Skip to content

Commit 9bd0c87

Browse files
authored
[clang-format] Fix a bug in BWACS_MultiLine (#135906)
Fix #51940
1 parent 53eae22 commit 9bd0c87

File tree

4 files changed

+41
-41
lines changed

4 files changed

+41
-41
lines changed

clang/lib/Format/TokenAnnotator.cpp

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

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

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

55875597
bool TokenAnnotator::mustBreakBefore(const AnnotatedLine &Line,
55885598
const FormatToken &Right) const {
5589-
const FormatToken &Left = *Right.Previous;
55905599
if (Right.NewlinesBefore > 1 && Style.MaxEmptyLinesToKeep > 0 &&
55915600
(!Style.RemoveEmptyLinesInUnwrappedLines || &Right == Line.First)) {
55925601
return true;
55935602
}
55945603

5604+
const FormatToken &Left = *Right.Previous;
5605+
55955606
if (Style.BreakFunctionDefinitionParameters && Line.MightBeFunctionDecl &&
55965607
Line.mightBeFunctionDefinition() && Left.MightBeFunctionDeclParen &&
55975608
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: 9 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,
@@ -3077,6 +3078,8 @@ void UnwrappedLineParser::parseTryCatch() {
30773078
FormatTok->is(Keywords.kw_finally)))) {
30783079
break;
30793080
}
3081+
if (FormatTok->is(tok::kw_catch))
3082+
SeenCatch = true;
30803083
nextToken();
30813084
while (FormatTok->isNot(tok::l_brace)) {
30823085
if (FormatTok->is(tok::l_paren)) {
@@ -3090,6 +3093,10 @@ void UnwrappedLineParser::parseTryCatch() {
30903093
}
30913094
nextToken();
30923095
}
3096+
if (SeenCatch) {
3097+
FormatTok->setFinalizedType(TT_ControlStatementLBrace);
3098+
SeenCatch = false;
3099+
}
30933100
NeedsUnwrappedLine = false;
30943101
Line->MustBeDeclaration = false;
30953102
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)