forked from OSchip/llvm-project
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
This commit is contained in:
parent
a92e2311bb
commit
3a33f0292b
|
@ -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.
|
||||
|
|
|
@ -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 ||
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -185,6 +185,7 @@ private:
|
|||
std::stack<int> PPChainBranchIndex;
|
||||
|
||||
friend class ScopedLineState;
|
||||
friend class CompoundStatementIndenter;
|
||||
};
|
||||
|
||||
struct UnwrappedLineNode {
|
||||
|
|
|
@ -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,
|
||||
|
|
Loading…
Reference in New Issue