const FormatToken &Previous = *Current.Previous;
if (Current.MustBreakBefore || Current.Type == TT_InlineASMColon)
return true;
- if (!Style.Cpp11BracedListStyle && Current.is(tok::r_brace) &&
- State.Stack.back().BreakBeforeClosingBrace)
+ if ((!Style.Cpp11BracedListStyle ||
+ (Current.MatchingParen &&
+ Current.MatchingParen->BlockKind == BK_Block)) &&
+ Current.is(tok::r_brace) && State.Stack.back().BreakBeforeClosingBrace)
return true;
if (Previous.is(tok::semi) && State.LineContainsContinuedForLoopSection)
return true;
State.Column <= Style.ColumnLimit / 2)
Penalty += Style.PenaltyBreakFirstLessLess;
- if (Current.is(tok::r_brace)) {
+ if (Current.is(tok::l_brace) && Current.BlockKind == BK_Block) {
+ State.Column = State.FirstIndent;
+ } else if (Current.is(tok::r_brace)) {
if (Current.MatchingParen &&
(Current.MatchingParen->BlockKind == BK_BracedInit ||
!Current.MatchingParen->Children.empty()))
// });
for (unsigned i = 0; i != Current.MatchingParen->FakeRParens; ++i)
State.Stack.pop_back();
- NewIndent = State.Stack.back().LastSpace;
+ NewIndent = State.Stack.back().LastSpace + Style.IndentWidth;
} else {
NewIndent = State.Stack.back().LastSpace +
(Style.Cpp11BracedListStyle ? 4 : Style.IndentWidth);
}
const FormatToken *NextNoComment = Current.getNextNonComment();
- AvoidBinPacking = NextNoComment &&
- NextNoComment->Type == TT_DesignatedInitializerPeriod;
+ AvoidBinPacking = Current.BlockKind == BK_Block ||
+ (NextNoComment &&
+ NextNoComment->Type == TT_DesignatedInitializerPeriod);
} else {
NewIndent = 4 + std::max(State.Stack.back().LastSpace,
State.Stack.back().StartOfFunctionCall);
State.Stack.push_back(ParenState(NewIndent, State.Stack.back().LastSpace,
AvoidBinPacking,
State.Stack.back().NoLineBreak));
+ State.Stack.back().BreakBeforeParameter = Current.BlockKind == BK_Block;
++State.ParenLevel;
}
E = LBrace.Children.end();
I != E; ++I) {
unsigned Indent =
- ParentIndent + ((*I)->Level - Line.Level) * Style.IndentWidth;
+ ParentIndent + ((*I)->Level - Line.Level - 1) * Style.IndentWidth;
if (!DryRun) {
unsigned Newlines = std::min((*I)->First->NewlinesBefore,
Style.MaxEmptyLinesToKeep + 1);
// Ensure that we start on the opening brace.
const FormatToken *LBrace = State.NextToken->Previous->Previous;
if (LBrace->isNot(tok::l_brace) ||
+ LBrace->BlockKind == BK_Block ||
LBrace->Next->Type == TT_DesignatedInitializerPeriod)
return 0;
} else if (Current->Type == TT_CtorInitializerComma &&
Style.BreakConstructorInitializersBeforeComma) {
Current->MustBreakBefore = true;
+ } else if (Current->Previous->BlockKind == BK_Block &&
+ Current->isNot(tok::r_brace)) {
+ Current->MustBreakBefore = true;
+ } else if (Current->is(tok::l_brace) && (Current->BlockKind == BK_Block)) {
+ Current->MustBreakBefore =
+ Style.BreakBeforeBraces == FormatStyle::BS_Allman;
}
Current->CanBreakBefore =
Current->MustBreakBefore || canBreakBefore(Line, *Current);
return true;
}
-void UnwrappedLineParser::parseBracedList() {
+bool UnwrappedLineParser::parseBracedList(bool ContinueOnSemicolons) {
+ bool HasError = false;
nextToken();
// FIXME: Once we have an expression parser in the UnwrappedLineParser,
break;
case tok::r_brace:
nextToken();
- return;
+ return !HasError;
case tok::semi:
- // Probably a missing closing brace. Bail out.
- return;
+ HasError = true;
+ if (!ContinueOnSemicolons)
+ return !HasError;
+ nextToken();
+ break;
case tok::comma:
nextToken();
break;
break;
}
} while (!eof());
+ return false;
}
void UnwrappedLineParser::parseReturn() {
if (FormatTok->Tok.is(tok::identifier))
nextToken();
}
- bool HasError = false;
if (FormatTok->Tok.is(tok::l_brace)) {
- if (Style.BreakBeforeBraces == FormatStyle::BS_Allman)
- addUnwrappedLine();
- nextToken();
- addUnwrappedLine();
- ++Line->Level;
- do {
- switch (FormatTok->Tok.getKind()) {
- case tok::l_paren:
- parseParens();
- break;
- case tok::r_brace:
- addUnwrappedLine();
- nextToken();
- --Line->Level;
- if (HasError) {
- if (FormatTok->is(tok::semi))
- nextToken();
- addUnwrappedLine();
- }
- return;
- case tok::semi:
- HasError = true;
- nextToken();
- addUnwrappedLine();
- break;
- case tok::comma:
- nextToken();
- addUnwrappedLine();
- break;
- default:
+ FormatTok->BlockKind = BK_Block;
+ bool HasError = !parseBracedList(/*ContinueOnSemicolons=*/true);
+ if (HasError) {
+ if (FormatTok->is(tok::semi))
nextToken();
- break;
- }
- } while (!eof());
+ addUnwrappedLine();
+ }
}
// We fall through to parsing a structural element afterwards, so that in
// enum A {} n, m;
void parsePPUnknown();
void parseStructuralElement();
bool tryToParseBracedList();
- void parseBracedList();
+ bool parseBracedList(bool ContinueOnSemicolons = false);
void parseReturn();
void parseParens();
void parseIfThenElse();
" Four = (Zero && (One ^ Two)) | (One << Two),\n"
" Five = (One, Two, Three, Four, 5)\n"
"};");
+ verifyGoogleFormat("enum {\n"
+ " Zero,\n"
+ " One = 1,\n"
+ " Two = One + 1,\n"
+ " Three = (One + Two),\n"
+ " Four = (Zero && (One ^ Two)) | (One << Two),\n"
+ " Five = (One, Two, Three, Four, 5)\n"
+ "};");
verifyFormat("enum Enum {};");
verifyFormat("enum {};");
- verifyFormat("enum X E {\n} d;");
- verifyFormat("enum __attribute__((...)) E {\n} d;");
- verifyFormat("enum __declspec__((...)) E {\n} d;");
+ verifyFormat("enum X E {} d;");
+ verifyFormat("enum __attribute__((...)) E {} d;");
+ verifyFormat("enum __declspec__((...)) E {} d;");
verifyFormat("enum X f() {\n a();\n return 42;\n}");
+ verifyFormat("enum {\n"
+ " Bar = Foo<int, int>::value\n"
+ "};");
}
TEST_F(FormatTest, FormatsEnumsWithErrors) {
"};");
verifyFormat("enum struct Enum {};");
verifyFormat("enum struct {};");
- verifyFormat("enum struct X E {\n} d;");
- verifyFormat("enum struct __attribute__((...)) E {\n} d;");
- verifyFormat("enum struct __declspec__((...)) E {\n} d;");
+ verifyFormat("enum struct X E {} d;");
+ verifyFormat("enum struct __attribute__((...)) E {} d;");
+ verifyFormat("enum struct __declspec__((...)) E {} d;");
verifyFormat("enum struct X f() {\n a();\n return 42;\n}");
}
"};");
verifyFormat("enum class Enum {};");
verifyFormat("enum class {};");
- verifyFormat("enum class X E {\n} d;");
- verifyFormat("enum class __attribute__((...)) E {\n} d;");
- verifyFormat("enum class __declspec__((...)) E {\n} d;");
+ verifyFormat("enum class X E {} d;");
+ verifyFormat("enum class __attribute__((...)) E {} d;");
+ verifyFormat("enum class __declspec__((...)) E {} d;");
verifyFormat("enum class X f() {\n a();\n return 42;\n}");
}