diff options
author | Alexander Kornienko <alexfh@google.com> | 2013-12-12 09:49:52 +0000 |
---|---|---|
committer | Alexander Kornienko <alexfh@google.com> | 2013-12-12 09:49:52 +0000 |
commit | 3a33f0292bcadc2eaf980ec7581dbe260f0e092b (patch) | |
tree | 05922d09cc643457235fb3203c2d84f3cd999fc2 | |
parent | a92e2311bb1345c60f6c90180028b8adf252897c (diff) | |
download | llvm-3a33f0292bcadc2eaf980ec7581dbe260f0e092b.tar.gz |
Implemented GNU-style formatting for compound statements.
Summary:
Added BraceBreakingStyle::BS_GNU. I'm not sure about the correctness of
static initializer formatting, but compound statements should be fine.
Reviewers: djasper
Reviewed By: djasper
CC: cfe-commits, klimek
Differential Revision: http://llvm-reviews.chandlerc.com/D2372
llvm-svn: 197138
-rw-r--r-- | clang/include/clang/Format/Format.h | 6 | ||||
-rw-r--r-- | clang/lib/Format/Format.cpp | 6 | ||||
-rw-r--r-- | clang/lib/Format/TokenAnnotator.cpp | 3 | ||||
-rw-r--r-- | clang/lib/Format/UnwrappedLineParser.cpp | 67 | ||||
-rw-r--r-- | clang/lib/Format/UnwrappedLineParser.h | 1 | ||||
-rw-r--r-- | clang/unittests/Format/FormatTest.cpp | 88 |
6 files changed, 145 insertions, 26 deletions
diff --git a/clang/include/clang/Format/Format.h b/clang/include/clang/Format/Format.h index 7af5a094511f..0b51a205021f 100644 --- a/clang/include/clang/Format/Format.h +++ b/clang/include/clang/Format/Format.h @@ -218,7 +218,11 @@ struct FormatStyle { /// Like \c Attach, but break before function definitions. BS_Stroustrup, /// Always break before braces. - BS_Allman + BS_Allman, + /// Always break before braces and add an extra level of indentation to + /// braces of control statements, not to those of class, function + /// or other definitions. + BS_GNU }; /// \brief The brace breaking style to use. diff --git a/clang/lib/Format/Format.cpp b/clang/lib/Format/Format.cpp index 808e64db9155..87c2fd70aeee 100644 --- a/clang/lib/Format/Format.cpp +++ b/clang/lib/Format/Format.cpp @@ -68,6 +68,7 @@ template <> struct ScalarEnumerationTraits<FormatStyle::BraceBreakingStyle> { IO.enumCase(Value, "Linux", FormatStyle::BS_Linux); IO.enumCase(Value, "Stroustrup", FormatStyle::BS_Stroustrup); IO.enumCase(Value, "Allman", FormatStyle::BS_Allman); + IO.enumCase(Value, "GNU", FormatStyle::BS_GNU); } }; @@ -359,7 +360,7 @@ FormatStyle getWebKitStyle() { FormatStyle getGNUStyle() { FormatStyle Style = getLLVMStyle(); Style.BreakBeforeBinaryOperators = true; - Style.BreakBeforeBraces = FormatStyle::BS_Allman; + Style.BreakBeforeBraces = FormatStyle::BS_GNU; Style.BreakBeforeTernaryOperators = true; Style.ColumnLimit = 79; Style.SpaceBeforeParens = FormatStyle::SBPO_Always; @@ -561,7 +562,8 @@ private: SmallVectorImpl<AnnotatedLine *>::const_iterator E, unsigned Limit) { if (Limit == 0) return 0; - if (Style.BreakBeforeBraces == FormatStyle::BS_Allman && + if ((Style.BreakBeforeBraces == FormatStyle::BS_Allman || + Style.BreakBeforeBraces == FormatStyle::BS_GNU) && I[1]->First->is(tok::l_brace)) return 0; if (I[1]->InPPDirective != (*I)->InPPDirective || diff --git a/clang/lib/Format/TokenAnnotator.cpp b/clang/lib/Format/TokenAnnotator.cpp index b8905a9bfd39..37ad7336513c 100644 --- a/clang/lib/Format/TokenAnnotator.cpp +++ b/clang/lib/Format/TokenAnnotator.cpp @@ -1410,7 +1410,8 @@ bool TokenAnnotator::mustBreakBefore(const AnnotatedLine &Line, Right.Previous->isNot(tok::r_brace) && Right.isNot(tok::r_brace)) { return true; } else if (Right.is(tok::l_brace) && (Right.BlockKind == BK_Block)) { - return Style.BreakBeforeBraces == FormatStyle::BS_Allman; + return Style.BreakBeforeBraces == FormatStyle::BS_Allman || + Style.BreakBeforeBraces == FormatStyle::BS_GNU; } return false; } diff --git a/clang/lib/Format/UnwrappedLineParser.cpp b/clang/lib/Format/UnwrappedLineParser.cpp index 1eb0ae170073..089bd570b5c5 100644 --- a/clang/lib/Format/UnwrappedLineParser.cpp +++ b/clang/lib/Format/UnwrappedLineParser.cpp @@ -152,6 +152,27 @@ private: SmallVectorImpl<UnwrappedLine> *OriginalLines; }; +class CompoundStatementIndenter { +public: + CompoundStatementIndenter(UnwrappedLineParser *Parser, + const FormatStyle &Style, unsigned &LineLevel) + : LineLevel(LineLevel), OldLineLevel(LineLevel) { + if (Style.BreakBeforeBraces == FormatStyle::BS_Allman) { + Parser->addUnwrappedLine(); + } else if (Style.BreakBeforeBraces == FormatStyle::BS_GNU) { + Parser->addUnwrappedLine(); + ++LineLevel; + } + } + ~CompoundStatementIndenter() { + LineLevel = OldLineLevel; + } + +private: + unsigned &LineLevel; + unsigned OldLineLevel; +}; + namespace { class IndexedTokenSource : public FormatTokenSource { @@ -677,9 +698,7 @@ void UnwrappedLineParser::parseStructuralElement() { // structural element. // FIXME: Figure out cases where this is not true, and add projections // for them (the one we know is missing are lambdas). - if (Style.BreakBeforeBraces == FormatStyle::BS_Linux || - Style.BreakBeforeBraces == FormatStyle::BS_Stroustrup || - Style.BreakBeforeBraces == FormatStyle::BS_Allman) + if (Style.BreakBeforeBraces != FormatStyle::BS_Attach) addUnwrappedLine(); FormatTok->Type = TT_FunctionLBrace; parseBlock(/*MustBeDeclaration=*/false); @@ -938,13 +957,14 @@ void UnwrappedLineParser::parseIfThenElse() { parseParens(); bool NeedsUnwrappedLine = false; if (FormatTok->Tok.is(tok::l_brace)) { - if (Style.BreakBeforeBraces == FormatStyle::BS_Allman) - addUnwrappedLine(); + CompoundStatementIndenter Indenter(this, Style, Line->Level); parseBlock(/*MustBeDeclaration=*/false); - if (Style.BreakBeforeBraces == FormatStyle::BS_Allman) + if (Style.BreakBeforeBraces == FormatStyle::BS_Allman || + Style.BreakBeforeBraces == FormatStyle::BS_GNU) { addUnwrappedLine(); - else + } else { NeedsUnwrappedLine = true; + } } else { addUnwrappedLine(); ++Line->Level; @@ -954,8 +974,7 @@ void UnwrappedLineParser::parseIfThenElse() { if (FormatTok->Tok.is(tok::kw_else)) { nextToken(); if (FormatTok->Tok.is(tok::l_brace)) { - if (Style.BreakBeforeBraces == FormatStyle::BS_Allman) - addUnwrappedLine(); + CompoundStatementIndenter Indenter(this, Style, Line->Level); parseBlock(/*MustBeDeclaration=*/false); addUnwrappedLine(); } else if (FormatTok->Tok.is(tok::kw_if)) { @@ -978,7 +997,8 @@ void UnwrappedLineParser::parseNamespace() { nextToken(); if (FormatTok->Tok.is(tok::l_brace)) { if (Style.BreakBeforeBraces == FormatStyle::BS_Linux || - Style.BreakBeforeBraces == FormatStyle::BS_Allman) + Style.BreakBeforeBraces == FormatStyle::BS_Allman || + Style.BreakBeforeBraces == FormatStyle::BS_GNU) addUnwrappedLine(); bool AddLevel = Style.NamespaceIndentation == FormatStyle::NI_All || @@ -1001,8 +1021,7 @@ void UnwrappedLineParser::parseForOrWhileLoop() { if (FormatTok->Tok.is(tok::l_paren)) parseParens(); if (FormatTok->Tok.is(tok::l_brace)) { - if (Style.BreakBeforeBraces == FormatStyle::BS_Allman) - addUnwrappedLine(); + CompoundStatementIndenter Indenter(this, Style, Line->Level); parseBlock(/*MustBeDeclaration=*/false); addUnwrappedLine(); } else { @@ -1017,9 +1036,10 @@ void UnwrappedLineParser::parseDoWhile() { assert(FormatTok->Tok.is(tok::kw_do) && "'do' expected"); nextToken(); if (FormatTok->Tok.is(tok::l_brace)) { - if (Style.BreakBeforeBraces == FormatStyle::BS_Allman) - addUnwrappedLine(); + CompoundStatementIndenter Indenter(this, Style, Line->Level); parseBlock(/*MustBeDeclaration=*/false); + if (Style.BreakBeforeBraces == FormatStyle::BS_GNU) + addUnwrappedLine(); } else { addUnwrappedLine(); ++Line->Level; @@ -1043,17 +1063,20 @@ void UnwrappedLineParser::parseLabel() { if (Line->Level > 1 || (!Line->InPPDirective && Line->Level > 0)) --Line->Level; if (CommentsBeforeNextToken.empty() && FormatTok->Tok.is(tok::l_brace)) { - if (Style.BreakBeforeBraces == FormatStyle::BS_Allman) - addUnwrappedLine(); + CompoundStatementIndenter Indenter(this, Style, Line->Level); parseBlock(/*MustBeDeclaration=*/false); if (FormatTok->Tok.is(tok::kw_break)) { - // "break;" after "}" on its own line only for BS_Allman - if (Style.BreakBeforeBraces == FormatStyle::BS_Allman) + // "break;" after "}" on its own line only for BS_Allman and BS_GNU + if (Style.BreakBeforeBraces == FormatStyle::BS_Allman || + Style.BreakBeforeBraces == FormatStyle::BS_GNU) { addUnwrappedLine(); + } parseStructuralElement(); } + addUnwrappedLine(); + } else { + addUnwrappedLine(); } - addUnwrappedLine(); Line->Level = OldLineLevel; } @@ -1072,8 +1095,7 @@ void UnwrappedLineParser::parseSwitch() { if (FormatTok->Tok.is(tok::l_paren)) parseParens(); if (FormatTok->Tok.is(tok::l_brace)) { - if (Style.BreakBeforeBraces == FormatStyle::BS_Allman) - addUnwrappedLine(); + CompoundStatementIndenter Indenter(this, Style, Line->Level); parseBlock(/*MustBeDeclaration=*/false); addUnwrappedLine(); } else { @@ -1164,7 +1186,8 @@ void UnwrappedLineParser::parseRecord() { } if (FormatTok->Tok.is(tok::l_brace)) { if (Style.BreakBeforeBraces == FormatStyle::BS_Linux || - Style.BreakBeforeBraces == FormatStyle::BS_Allman) + Style.BreakBeforeBraces == FormatStyle::BS_Allman || + Style.BreakBeforeBraces == FormatStyle::BS_GNU) addUnwrappedLine(); parseBlock(/*MustBeDeclaration=*/true, /*Addlevel=*/true, diff --git a/clang/lib/Format/UnwrappedLineParser.h b/clang/lib/Format/UnwrappedLineParser.h index f1f4e57a20b3..71caed8505c1 100644 --- a/clang/lib/Format/UnwrappedLineParser.h +++ b/clang/lib/Format/UnwrappedLineParser.h @@ -185,6 +185,7 @@ private: std::stack<int> PPChainBranchIndex; friend class ScopedLineState; + friend class CompoundStatementIndenter; }; struct UnwrappedLineNode { diff --git a/clang/unittests/Format/FormatTest.cpp b/clang/unittests/Format/FormatTest.cpp index 91519d8dad86..940f60df3c48 100644 --- a/clang/unittests/Format/FormatTest.cpp +++ b/clang/unittests/Format/FormatTest.cpp @@ -6935,6 +6935,91 @@ TEST_F(FormatTest, AllmanBraceBreaking) { BreakBeforeBraceShortIfs); } +TEST_F(FormatTest, GNUBraceBreaking) { + FormatStyle GNUBraceStyle = getLLVMStyle(); + GNUBraceStyle.BreakBeforeBraces = FormatStyle::BS_GNU; + verifyFormat("namespace a\n" + "{\n" + "class A\n" + "{\n" + " void f()\n" + " {\n" + " int a;\n" + " {\n" + " int b;\n" + " }\n" + " if (true)\n" + " {\n" + " a();\n" + " b();\n" + " }\n" + " }\n" + " void g() { return; }\n" + "}\n" + "}", + GNUBraceStyle); + + verifyFormat("void f()\n" + "{\n" + " if (true)\n" + " {\n" + " a();\n" + " }\n" + " else if (false)\n" + " {\n" + " b();\n" + " }\n" + " else\n" + " {\n" + " c();\n" + " }\n" + "}\n", + GNUBraceStyle); + + verifyFormat("void f()\n" + "{\n" + " for (int i = 0; i < 10; ++i)\n" + " {\n" + " a();\n" + " }\n" + " while (false)\n" + " {\n" + " b();\n" + " }\n" + " do\n" + " {\n" + " c();\n" + " }\n" + " while (false);\n" + "}\n", + GNUBraceStyle); + + verifyFormat("void f(int a)\n" + "{\n" + " switch (a)\n" + " {\n" + " case 0:\n" + " break;\n" + " case 1:\n" + " {\n" + " break;\n" + " }\n" + " case 2:\n" + " {\n" + " }\n" + " break;\n" + " default:\n" + " break;\n" + " }\n" + "}\n", + GNUBraceStyle); + + verifyFormat("enum X\n" + "{\n" + " Y = 0,\n" + "}\n", + GNUBraceStyle); +} TEST_F(FormatTest, CatchExceptionReferenceBinding) { verifyFormat("void f() {\n" " try {\n" @@ -7132,6 +7217,9 @@ TEST_F(FormatTest, ParsesConfiguration) { FormatStyle::BS_Linux); CHECK_PARSE("BreakBeforeBraces: Stroustrup", BreakBeforeBraces, FormatStyle::BS_Stroustrup); + CHECK_PARSE("BreakBeforeBraces: Allman", BreakBeforeBraces, + FormatStyle::BS_Allman); + CHECK_PARSE("BreakBeforeBraces: GNU", BreakBeforeBraces, FormatStyle::BS_GNU); Style.NamespaceIndentation = FormatStyle::NI_All; CHECK_PARSE("NamespaceIndentation: None", NamespaceIndentation, |