Skip to content
Snippets Groups Projects
Commit de768548 authored by Manuel Klimek's avatar Manuel Klimek
Browse files

Fix parsing of variable declarations directly after a class / struct.

Previous indent:
class A {
}
a;
void f() {
};

With this patch:
class A {
} a;
void f() {
}
;

The patch introduces a production for classes and structs, and parses
the rest of the line to the semicolon after the class scope.
This allowed us to remove a long-standing wart in the parser that would
just much the semicolon after any block.
Due to this suboptimal formating some tests were broken.

Some unrelated formatting tests broke; those hit a bug in the ast
printing, and need to be fixed separately.

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@171761 91177308-0d34-0410-b5e6-96231b3b80d8
parent c3cd2b0d
No related branches found
No related tags found
No related merge requests found
...@@ -129,13 +129,10 @@ bool UnwrappedLineParser::parseBlock(unsigned AddLevels) { ...@@ -129,13 +129,10 @@ bool UnwrappedLineParser::parseBlock(unsigned AddLevels) {
parseLevel(/*HasOpeningBrace=*/true); parseLevel(/*HasOpeningBrace=*/true);
Line.Level -= AddLevels; Line.Level -= AddLevels;
// FIXME: Add error handling.
if (!FormatTok.Tok.is(tok::r_brace)) if (!FormatTok.Tok.is(tok::r_brace))
return true; return true;
nextToken(); nextToken(); // Munch the closing brace.
if (FormatTok.Tok.is(tok::semi))
nextToken();
return false; return false;
} }
...@@ -246,6 +243,10 @@ void UnwrappedLineParser::parseStructuralElement() { ...@@ -246,6 +243,10 @@ void UnwrappedLineParser::parseStructuralElement() {
case tok::kw_enum: case tok::kw_enum:
parseEnum(); parseEnum();
return; return;
case tok::kw_struct: // fallthrough
case tok::kw_class:
parseStructOrClass();
return;
case tok::semi: case tok::semi:
nextToken(); nextToken();
addUnwrappedLine(); addUnwrappedLine();
...@@ -459,6 +460,26 @@ void UnwrappedLineParser::parseEnum() { ...@@ -459,6 +460,26 @@ void UnwrappedLineParser::parseEnum() {
} while (!eof()); } while (!eof());
} }
void UnwrappedLineParser::parseStructOrClass() {
nextToken();
do {
switch (FormatTok.Tok.getKind()) {
case tok::l_brace:
// FIXME: Think about how to resolve the error handling here.
parseBlock();
parseStructuralElement();
return;
case tok::semi:
nextToken();
addUnwrappedLine();
return;
default:
nextToken();
break;
}
} while (!eof());
}
void UnwrappedLineParser::addUnwrappedLine() { void UnwrappedLineParser::addUnwrappedLine() {
// Consume trailing comments. // Consume trailing comments.
while (!eof() && FormatTok.NewlinesBefore == 0 && while (!eof() && FormatTok.NewlinesBefore == 0 &&
......
...@@ -128,6 +128,7 @@ private: ...@@ -128,6 +128,7 @@ private:
void parseNamespace(); void parseNamespace();
void parseAccessSpecifier(); void parseAccessSpecifier();
void parseEnum(); void parseEnum();
void parseStructOrClass();
void addUnwrappedLine(); void addUnwrappedLine();
bool eof() const; bool eof() const;
void nextToken(); void nextToken();
......
...@@ -162,7 +162,7 @@ private: ...@@ -162,7 +162,7 @@ private:
*/ */
template <class T> friend class valarray; template <class T> friend class valarray;
}; };
// CHECK: <Declaration>template &lt;class T = unsigned int&gt; class valarray {\n}\ntemplate &lt;class T&gt; class valarray</Declaration> // CHECK: <Declaration>template &lt;class T = unsigned int&gt; class valarray {\n} template &lt;class T&gt; class valarray</Declaration>
// CHECK: <Declaration>friend template &lt;class T&gt; class valarray</Declaration> // CHECK: <Declaration>friend template &lt;class T&gt; class valarray</Declaration>
class gslice class gslice
......
...@@ -670,7 +670,7 @@ void comment_to_xml_conversion_10(int aaa, int bbb); ...@@ -670,7 +670,7 @@ void comment_to_xml_conversion_10(int aaa, int bbb);
template<typename T, typename U> template<typename T, typename U>
class comment_to_xml_conversion_11 { }; class comment_to_xml_conversion_11 { };
// CHECK: comment-to-html-xml-conversion.cpp:[[@LINE-2]]:7: ClassTemplate=comment_to_xml_conversion_11:{{.*}} FullCommentAsXML=[<Class templateKind="template" file="{{[^"]+}}comment-to-html-xml-conversion.cpp" line="[[@LINE-2]]" column="7"><Name>comment_to_xml_conversion_11</Name><USR>c:@CT&gt;2#T#T@comment_to_xml_conversion_11</USR><Declaration>template &lt;typename T = int, typename U = int&gt;\nclass comment_to_xml_conversion_11 {\n}\ntemplate &lt;typename T, typename U&gt; class comment_to_xml_conversion_11 {\n}</Declaration><Abstract><Para> Aaa.</Para></Abstract></Class>] // CHECK: comment-to-html-xml-conversion.cpp:[[@LINE-2]]:7: ClassTemplate=comment_to_xml_conversion_11:{{.*}} FullCommentAsXML=[<Class templateKind="template" file="{{[^"]+}}comment-to-html-xml-conversion.cpp" line="[[@LINE-2]]" column="7"><Name>comment_to_xml_conversion_11</Name><USR>c:@CT&gt;2#T#T@comment_to_xml_conversion_11</USR><Declaration>template &lt;typename T = int, typename U = int&gt;\nclass comment_to_xml_conversion_11 {\n} template &lt;typename T, typename U&gt; class comment_to_xml_conversion_11 {\n}</Declaration><Abstract><Para> Aaa.</Para></Abstract></Class>]
/// Aaa. /// Aaa.
template<typename T> template<typename T>
......
...@@ -332,6 +332,13 @@ TEST_F(FormatTest, FormatsDerivedClass) { ...@@ -332,6 +332,13 @@ TEST_F(FormatTest, FormatsDerivedClass) {
"};"); "};");
} }
TEST_F(FormatTest, FormatsVariableDeclarationsAfterStructOrClass) {
verifyFormat("class A {\n"
"} a, b;");
verifyFormat("struct A {\n"
"} a, b;");
}
TEST_F(FormatTest, FormatsEnum) { TEST_F(FormatTest, FormatsEnum) {
verifyFormat("enum {\n" verifyFormat("enum {\n"
" Zero,\n" " Zero,\n"
...@@ -624,7 +631,7 @@ TEST_F(FormatTest, BreaksAsHighAsPossible) { ...@@ -624,7 +631,7 @@ TEST_F(FormatTest, BreaksAsHighAsPossible) {
TEST_F(FormatTest, BreaksDesireably) { TEST_F(FormatTest, BreaksDesireably) {
verifyFormat("if (aaaaaaaaaaaaaaaaaaa(aaaaaaaaaaaaaaa) ||\n" verifyFormat("if (aaaaaaaaaaaaaaaaaaa(aaaaaaaaaaaaaaa) ||\n"
" aaaaaaaaaaaaaaaaaaa(aaaaaaaaaaaaaaa) ||\n" " aaaaaaaaaaaaaaaaaaa(aaaaaaaaaaaaaaa) ||\n"
" aaaaaaaaaaaaaaaaaaa(aaaaaaaaaaaaaaa)) {\n};"); " aaaaaaaaaaaaaaaaaaa(aaaaaaaaaaaaaaa)) {\n}");
verifyFormat( verifyFormat(
"aaaaaaaaaaaaaaaaaaaaa(aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa,\n" "aaaaaaaaaaaaaaaaaaaaa(aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa,\n"
...@@ -974,14 +981,14 @@ TEST_F(FormatTest, IncorrectAccessSpecifier) { ...@@ -974,14 +981,14 @@ TEST_F(FormatTest, IncorrectAccessSpecifier) {
"int qwerty;"); "int qwerty;");
verifyFormat("public\n" verifyFormat("public\n"
"B {\n" "B {\n"
"};"); "}");
verifyFormat("public\n" verifyFormat("public\n"
"{\n" "{\n"
"};"); "}");
verifyFormat("public\n" verifyFormat("public\n"
"B {\n" "B {\n"
" int x;\n" " int x;\n"
"};"); "}");
} }
TEST_F(FormatTest, IncorrectCodeUnbalancedBraces) { TEST_F(FormatTest, IncorrectCodeUnbalancedBraces) {
...@@ -990,16 +997,16 @@ TEST_F(FormatTest, IncorrectCodeUnbalancedBraces) { ...@@ -990,16 +997,16 @@ TEST_F(FormatTest, IncorrectCodeUnbalancedBraces) {
TEST_F(FormatTest, IncorrectCodeDoNoWhile) { TEST_F(FormatTest, IncorrectCodeDoNoWhile) {
verifyFormat("do {\n" verifyFormat("do {\n"
"};"); "}");
verifyFormat("do {\n" verifyFormat("do {\n"
"};\n" "}\n"
"f();"); "f();");
verifyFormat("do {\n" verifyFormat("do {\n"
"}\n" "}\n"
"wheeee(fun);"); "wheeee(fun);");
verifyFormat("do {\n" verifyFormat("do {\n"
" f();\n" " f();\n"
"};"); "}");
} }
TEST_F(FormatTest, DoesNotTouchUnwrappedLinesWithErrors) { TEST_F(FormatTest, DoesNotTouchUnwrappedLinesWithErrors) {
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment