Skip to content

Commit 1ee4a87

Browse files
committed
[clang-format] Fix a bug in BWACS_MultiLine
Fix #51940
1 parent c41ef75 commit 1ee4a87

File tree

4 files changed

+37
-41
lines changed

4 files changed

+37
-41
lines changed

clang/lib/Format/TokenAnnotator.cpp

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4153,8 +4153,16 @@ void TokenAnnotator::calculateFormattingInformation(AnnotatedLine &Line) const {
41534153
ChildSize + Current->SpacesRequiredBefore;
41544154
}
41554155

4156-
if (Current->is(TT_CtorInitializerColon))
4156+
if (Current->is(TT_ControlStatementLBrace) && Style.ColumnLimit > 0 &&
4157+
Style.BraceWrapping.AfterControlStatement ==
4158+
FormatStyle::BWACS_MultiLine &&
4159+
Line.Level * Style.IndentWidth + Line.Last->TotalLength >
4160+
Style.ColumnLimit) {
4161+
Current->CanBreakBefore = true;
4162+
Current->MustBreakBefore = true;
4163+
} else if (Current->is(TT_CtorInitializerColon)) {
41574164
InFunctionDecl = false;
4165+
}
41584166

41594167
// FIXME: Only calculate this if CanBreakBefore is true once static
41604168
// initializers etc. are sorted out.
@@ -5586,12 +5594,13 @@ static bool isAllmanLambdaBrace(const FormatToken &Tok) {
55865594

55875595
bool TokenAnnotator::mustBreakBefore(const AnnotatedLine &Line,
55885596
const FormatToken &Right) const {
5589-
const FormatToken &Left = *Right.Previous;
55905597
if (Right.NewlinesBefore > 1 && Style.MaxEmptyLinesToKeep > 0 &&
55915598
(!Style.RemoveEmptyLinesInUnwrappedLines || &Right == Line.First)) {
55925599
return true;
55935600
}
55945601

5602+
const FormatToken &Left = *Right.Previous;
5603+
55955604
if (Style.BreakFunctionDefinitionParameters && Line.MightBeFunctionDecl &&
55965605
Line.mightBeFunctionDefinition() && Left.MightBeFunctionDeclParen &&
55975606
Left.ParameterCount > 0) {

clang/lib/Format/UnwrappedLineFormatter.cpp

Lines changed: 8 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -424,43 +424,14 @@ class LineJoiner {
424424
: 0;
425425
}
426426
// Try to merge a control statement block with left brace wrapped.
427-
if (NextLine.First->is(tok::l_brace)) {
428-
if ((TheLine->First->isOneOf(tok::kw_if, tok::kw_else, tok::kw_while,
429-
tok::kw_for, tok::kw_switch, tok::kw_try,
430-
tok::kw_do, TT_ForEachMacro) ||
431-
(TheLine->First->is(tok::r_brace) && TheLine->First->Next &&
432-
TheLine->First->Next->isOneOf(tok::kw_else, tok::kw_catch))) &&
433-
Style.BraceWrapping.AfterControlStatement ==
434-
FormatStyle::BWACS_MultiLine) {
435-
// If possible, merge the next line's wrapped left brace with the
436-
// current line. Otherwise, leave it on the next line, as this is a
437-
// multi-line control statement.
438-
return (Style.ColumnLimit == 0 || TheLine->Level * Style.IndentWidth +
439-
TheLine->Last->TotalLength <=
440-
Style.ColumnLimit)
441-
? 1
442-
: 0;
443-
}
444-
if (TheLine->First->isOneOf(tok::kw_if, tok::kw_else, tok::kw_while,
445-
tok::kw_for, TT_ForEachMacro)) {
446-
return (Style.BraceWrapping.AfterControlStatement ==
447-
FormatStyle::BWACS_Always)
448-
? tryMergeSimpleBlock(I, E, Limit)
449-
: 0;
450-
}
451-
if (TheLine->First->isOneOf(tok::kw_else, tok::kw_catch) &&
452-
Style.BraceWrapping.AfterControlStatement ==
453-
FormatStyle::BWACS_MultiLine) {
454-
// This case if different from the upper BWACS_MultiLine processing
455-
// in that a preceding r_brace is not on the same line as else/catch
456-
// most likely because of BeforeElse/BeforeCatch set to true.
457-
// If the line length doesn't fit ColumnLimit, leave l_brace on the
458-
// next line to respect the BWACS_MultiLine.
459-
return (Style.ColumnLimit == 0 ||
460-
TheLine->Last->TotalLength <= Style.ColumnLimit)
461-
? 1
462-
: 0;
463-
}
427+
if (NextLine.First->is(TT_ControlStatementLBrace)) {
428+
// If possible, merge the next line's wrapped left brace with the
429+
// current line. Otherwise, leave it on the next line, as this is a
430+
// multi-line control statement.
431+
return Style.BraceWrapping.AfterControlStatement ==
432+
FormatStyle::BWACS_Always
433+
? tryMergeSimpleBlock(I, E, Limit)
434+
: 0;
464435
}
465436
if (PreviousLine && TheLine->First->is(tok::l_brace)) {
466437
switch (PreviousLine->First->Tok.getKind()) {

clang/lib/Format/UnwrappedLineParser.cpp

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -135,7 +135,8 @@ class CompoundStatementIndenter {
135135
CompoundStatementIndenter(UnwrappedLineParser *Parser,
136136
const FormatStyle &Style, unsigned &LineLevel)
137137
: CompoundStatementIndenter(Parser, LineLevel,
138-
Style.BraceWrapping.AfterControlStatement,
138+
Style.BraceWrapping.AfterControlStatement ==
139+
FormatStyle::BWACS_Always,
139140
Style.BraceWrapping.IndentBraces) {}
140141
CompoundStatementIndenter(UnwrappedLineParser *Parser, unsigned &LineLevel,
141142
bool WrapBrace, bool IndentBrace)
@@ -3067,7 +3068,7 @@ void UnwrappedLineParser::parseTryCatch() {
30673068
parseStructuralElement();
30683069
--Line->Level;
30693070
}
3070-
while (true) {
3071+
for (bool SeenCatch = false;;) {
30713072
if (FormatTok->is(tok::at))
30723073
nextToken();
30733074
if (!(FormatTok->isOneOf(tok::kw_catch, Keywords.kw___except,
@@ -3090,6 +3091,10 @@ void UnwrappedLineParser::parseTryCatch() {
30903091
}
30913092
nextToken();
30923093
}
3094+
if (SeenCatch) {
3095+
FormatTok->setFinalizedType(TT_ControlStatementLBrace);
3096+
SeenCatch = false;
3097+
}
30933098
NeedsUnwrappedLine = false;
30943099
Line->MustBeDeclaration = false;
30953100
CompoundStatementIndenter Indenter(this, Style, Line->Level);

clang/unittests/Format/FormatTest.cpp

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3419,6 +3419,17 @@ TEST_F(FormatTest, MultiLineControlStatements) {
34193419
"{\n"
34203420
"};",
34213421
Style);
3422+
3423+
Style = getLLVMStyle();
3424+
Style.AllowShortBlocksOnASingleLine = FormatStyle::SBS_Always;
3425+
Style.AllowShortIfStatementsOnASingleLine = FormatStyle::SIS_WithoutElse;
3426+
Style.AllowShortLoopsOnASingleLine = true;
3427+
Style.BreakBeforeBraces = FormatStyle::BS_Custom;
3428+
Style.BraceWrapping.AfterControlStatement = FormatStyle::BWACS_MultiLine;
3429+
verifyFormat("if (true) { return; }", Style);
3430+
verifyFormat("while (true) { return; }", Style);
3431+
// Failing test in https://reviews.llvm.org/D114521#3151727
3432+
verifyFormat("for (;;) { bar(); }", Style);
34223433
}
34233434

34243435
TEST_F(FormatTest, BeforeWhile) {

0 commit comments

Comments
 (0)