From de7685487c5d628dd9fe64c4f861cd1888f50fc7 Mon Sep 17 00:00:00 2001 From: Manuel Klimek Date: Mon, 7 Jan 2013 18:10:23 +0000 Subject: [PATCH] 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 --- lib/Format/UnwrappedLineParser.cpp | 29 ++++++++++++++++--- lib/Format/UnwrappedLineParser.h | 1 + test/Index/comment-cplus-decls.cpp | 2 +- test/Index/comment-to-html-xml-conversion.cpp | 2 +- unittests/Format/FormatTest.cpp | 21 +++++++++----- 5 files changed, 42 insertions(+), 13 deletions(-) diff --git a/lib/Format/UnwrappedLineParser.cpp b/lib/Format/UnwrappedLineParser.cpp index 00ca3a5334..d7220259b7 100644 --- a/lib/Format/UnwrappedLineParser.cpp +++ b/lib/Format/UnwrappedLineParser.cpp @@ -129,13 +129,10 @@ bool UnwrappedLineParser::parseBlock(unsigned AddLevels) { parseLevel(/*HasOpeningBrace=*/true); Line.Level -= AddLevels; - // FIXME: Add error handling. if (!FormatTok.Tok.is(tok::r_brace)) return true; - nextToken(); - if (FormatTok.Tok.is(tok::semi)) - nextToken(); + nextToken(); // Munch the closing brace. return false; } @@ -246,6 +243,10 @@ void UnwrappedLineParser::parseStructuralElement() { case tok::kw_enum: parseEnum(); return; + case tok::kw_struct: // fallthrough + case tok::kw_class: + parseStructOrClass(); + return; case tok::semi: nextToken(); addUnwrappedLine(); @@ -459,6 +460,26 @@ void UnwrappedLineParser::parseEnum() { } 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() { // Consume trailing comments. while (!eof() && FormatTok.NewlinesBefore == 0 && diff --git a/lib/Format/UnwrappedLineParser.h b/lib/Format/UnwrappedLineParser.h index 27c1102055..a9f0475e32 100644 --- a/lib/Format/UnwrappedLineParser.h +++ b/lib/Format/UnwrappedLineParser.h @@ -128,6 +128,7 @@ private: void parseNamespace(); void parseAccessSpecifier(); void parseEnum(); + void parseStructOrClass(); void addUnwrappedLine(); bool eof() const; void nextToken(); diff --git a/test/Index/comment-cplus-decls.cpp b/test/Index/comment-cplus-decls.cpp index 29af712e1c..ed851d84fc 100644 --- a/test/Index/comment-cplus-decls.cpp +++ b/test/Index/comment-cplus-decls.cpp @@ -162,7 +162,7 @@ private: */ template friend class valarray; }; -// CHECK: template <class T = unsigned int> class valarray {\n}\ntemplate <class T> class valarray +// CHECK: template <class T = unsigned int> class valarray {\n} template <class T> class valarray // CHECK: friend template <class T> class valarray class gslice diff --git a/test/Index/comment-to-html-xml-conversion.cpp b/test/Index/comment-to-html-xml-conversion.cpp index 1ab49d6fc0..139120ec05 100644 --- a/test/Index/comment-to-html-xml-conversion.cpp +++ b/test/Index/comment-to-html-xml-conversion.cpp @@ -670,7 +670,7 @@ void comment_to_xml_conversion_10(int aaa, int bbb); template class comment_to_xml_conversion_11 { }; -// CHECK: comment-to-html-xml-conversion.cpp:[[@LINE-2]]:7: ClassTemplate=comment_to_xml_conversion_11:{{.*}} FullCommentAsXML=[comment_to_xml_conversion_11c:@CT>2#T#T@comment_to_xml_conversion_11template <typename T = int, typename U = int>\nclass comment_to_xml_conversion_11 {\n}\ntemplate <typename T, typename U> class comment_to_xml_conversion_11 {\n} Aaa.] +// CHECK: comment-to-html-xml-conversion.cpp:[[@LINE-2]]:7: ClassTemplate=comment_to_xml_conversion_11:{{.*}} FullCommentAsXML=[comment_to_xml_conversion_11c:@CT>2#T#T@comment_to_xml_conversion_11template <typename T = int, typename U = int>\nclass comment_to_xml_conversion_11 {\n} template <typename T, typename U> class comment_to_xml_conversion_11 {\n} Aaa.] /// Aaa. template diff --git a/unittests/Format/FormatTest.cpp b/unittests/Format/FormatTest.cpp index d4490dddfc..2ba4765cc7 100644 --- a/unittests/Format/FormatTest.cpp +++ b/unittests/Format/FormatTest.cpp @@ -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) { verifyFormat("enum {\n" " Zero,\n" @@ -624,7 +631,7 @@ TEST_F(FormatTest, BreaksAsHighAsPossible) { TEST_F(FormatTest, BreaksDesireably) { verifyFormat("if (aaaaaaaaaaaaaaaaaaa(aaaaaaaaaaaaaaa) ||\n" " aaaaaaaaaaaaaaaaaaa(aaaaaaaaaaaaaaa) ||\n" - " aaaaaaaaaaaaaaaaaaa(aaaaaaaaaaaaaaa)) {\n};"); + " aaaaaaaaaaaaaaaaaaa(aaaaaaaaaaaaaaa)) {\n}"); verifyFormat( "aaaaaaaaaaaaaaaaaaaaa(aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa,\n" @@ -974,14 +981,14 @@ TEST_F(FormatTest, IncorrectAccessSpecifier) { "int qwerty;"); verifyFormat("public\n" "B {\n" - "};"); + "}"); verifyFormat("public\n" "{\n" - "};"); + "}"); verifyFormat("public\n" "B {\n" " int x;\n" - "};"); + "}"); } TEST_F(FormatTest, IncorrectCodeUnbalancedBraces) { @@ -990,16 +997,16 @@ TEST_F(FormatTest, IncorrectCodeUnbalancedBraces) { TEST_F(FormatTest, IncorrectCodeDoNoWhile) { verifyFormat("do {\n" - "};"); + "}"); verifyFormat("do {\n" - "};\n" + "}\n" "f();"); verifyFormat("do {\n" "}\n" "wheeee(fun);"); verifyFormat("do {\n" " f();\n" - "};"); + "}"); } TEST_F(FormatTest, DoesNotTouchUnwrappedLinesWithErrors) { -- 2.40.0