[clang] 9bd0c87 - [clang-format] Fix a bug in BWACS_MultiLine (#135906)
via cfe-commits
cfe-commits at lists.llvm.org
Wed Apr 16 18:48:14 PDT 2025
Author: Owen Pan
Date: 2025-04-16T18:48:10-07:00
New Revision: 9bd0c8726a5e3fd4f76e84692bd920dfca7a8d7f
URL: https://github.com/llvm/llvm-project/commit/9bd0c8726a5e3fd4f76e84692bd920dfca7a8d7f
DIFF: https://github.com/llvm/llvm-project/commit/9bd0c8726a5e3fd4f76e84692bd920dfca7a8d7f.diff
LOG: [clang-format] Fix a bug in BWACS_MultiLine (#135906)
Fix #51940
Added:
Modified:
clang/lib/Format/TokenAnnotator.cpp
clang/lib/Format/UnwrappedLineFormatter.cpp
clang/lib/Format/UnwrappedLineParser.cpp
clang/unittests/Format/FormatTest.cpp
Removed:
################################################################################
diff --git a/clang/lib/Format/TokenAnnotator.cpp b/clang/lib/Format/TokenAnnotator.cpp
index ef5f07e2c62ee..144983f675828 100644
--- a/clang/lib/Format/TokenAnnotator.cpp
+++ b/clang/lib/Format/TokenAnnotator.cpp
@@ -4153,8 +4153,18 @@ void TokenAnnotator::calculateFormattingInformation(AnnotatedLine &Line) const {
ChildSize + Current->SpacesRequiredBefore;
}
- if (Current->is(TT_CtorInitializerColon))
+ if (Current->is(TT_ControlStatementLBrace)) {
+ if (Style.ColumnLimit > 0 &&
+ Style.BraceWrapping.AfterControlStatement ==
+ FormatStyle::BWACS_MultiLine &&
+ Line.Level * Style.IndentWidth + Line.Last->TotalLength >
+ Style.ColumnLimit) {
+ Current->CanBreakBefore = true;
+ Current->MustBreakBefore = true;
+ }
+ } else if (Current->is(TT_CtorInitializerColon)) {
InFunctionDecl = false;
+ }
// FIXME: Only calculate this if CanBreakBefore is true once static
// initializers etc. are sorted out.
@@ -5586,12 +5596,13 @@ static bool isAllmanLambdaBrace(const FormatToken &Tok) {
bool TokenAnnotator::mustBreakBefore(const AnnotatedLine &Line,
const FormatToken &Right) const {
- const FormatToken &Left = *Right.Previous;
if (Right.NewlinesBefore > 1 && Style.MaxEmptyLinesToKeep > 0 &&
(!Style.RemoveEmptyLinesInUnwrappedLines || &Right == Line.First)) {
return true;
}
+ const FormatToken &Left = *Right.Previous;
+
if (Style.BreakFunctionDefinitionParameters && Line.MightBeFunctionDecl &&
Line.mightBeFunctionDefinition() && Left.MightBeFunctionDeclParen &&
Left.ParameterCount > 0) {
diff --git a/clang/lib/Format/UnwrappedLineFormatter.cpp b/clang/lib/Format/UnwrappedLineFormatter.cpp
index 617d46ad281d5..6806ab18312ea 100644
--- a/clang/lib/Format/UnwrappedLineFormatter.cpp
+++ b/clang/lib/Format/UnwrappedLineFormatter.cpp
@@ -424,43 +424,14 @@ class LineJoiner {
: 0;
}
// Try to merge a control statement block with left brace wrapped.
- if (NextLine.First->is(tok::l_brace)) {
- if ((TheLine->First->isOneOf(tok::kw_if, tok::kw_else, tok::kw_while,
- tok::kw_for, tok::kw_switch, tok::kw_try,
- tok::kw_do, TT_ForEachMacro) ||
- (TheLine->First->is(tok::r_brace) && TheLine->First->Next &&
- TheLine->First->Next->isOneOf(tok::kw_else, tok::kw_catch))) &&
- Style.BraceWrapping.AfterControlStatement ==
- FormatStyle::BWACS_MultiLine) {
- // If possible, merge the next line's wrapped left brace with the
- // current line. Otherwise, leave it on the next line, as this is a
- // multi-line control statement.
- return (Style.ColumnLimit == 0 || TheLine->Level * Style.IndentWidth +
- TheLine->Last->TotalLength <=
- Style.ColumnLimit)
- ? 1
- : 0;
- }
- if (TheLine->First->isOneOf(tok::kw_if, tok::kw_else, tok::kw_while,
- tok::kw_for, TT_ForEachMacro)) {
- return (Style.BraceWrapping.AfterControlStatement ==
- FormatStyle::BWACS_Always)
- ? tryMergeSimpleBlock(I, E, Limit)
- : 0;
- }
- if (TheLine->First->isOneOf(tok::kw_else, tok::kw_catch) &&
- Style.BraceWrapping.AfterControlStatement ==
- FormatStyle::BWACS_MultiLine) {
- // This case if
diff erent from the upper BWACS_MultiLine processing
- // in that a preceding r_brace is not on the same line as else/catch
- // most likely because of BeforeElse/BeforeCatch set to true.
- // If the line length doesn't fit ColumnLimit, leave l_brace on the
- // next line to respect the BWACS_MultiLine.
- return (Style.ColumnLimit == 0 ||
- TheLine->Last->TotalLength <= Style.ColumnLimit)
- ? 1
- : 0;
- }
+ if (NextLine.First->is(TT_ControlStatementLBrace)) {
+ // If possible, merge the next line's wrapped left brace with the
+ // current line. Otherwise, leave it on the next line, as this is a
+ // multi-line control statement.
+ return Style.BraceWrapping.AfterControlStatement ==
+ FormatStyle::BWACS_Always
+ ? tryMergeSimpleBlock(I, E, Limit)
+ : 0;
}
if (PreviousLine && TheLine->First->is(tok::l_brace)) {
switch (PreviousLine->First->Tok.getKind()) {
diff --git a/clang/lib/Format/UnwrappedLineParser.cpp b/clang/lib/Format/UnwrappedLineParser.cpp
index 5fe65cb9a47e7..b9430d4389feb 100644
--- a/clang/lib/Format/UnwrappedLineParser.cpp
+++ b/clang/lib/Format/UnwrappedLineParser.cpp
@@ -135,7 +135,8 @@ class CompoundStatementIndenter {
CompoundStatementIndenter(UnwrappedLineParser *Parser,
const FormatStyle &Style, unsigned &LineLevel)
: CompoundStatementIndenter(Parser, LineLevel,
- Style.BraceWrapping.AfterControlStatement,
+ Style.BraceWrapping.AfterControlStatement ==
+ FormatStyle::BWACS_Always,
Style.BraceWrapping.IndentBraces) {}
CompoundStatementIndenter(UnwrappedLineParser *Parser, unsigned &LineLevel,
bool WrapBrace, bool IndentBrace)
@@ -3067,7 +3068,7 @@ void UnwrappedLineParser::parseTryCatch() {
parseStructuralElement();
--Line->Level;
}
- while (true) {
+ for (bool SeenCatch = false;;) {
if (FormatTok->is(tok::at))
nextToken();
if (!(FormatTok->isOneOf(tok::kw_catch, Keywords.kw___except,
@@ -3077,6 +3078,8 @@ void UnwrappedLineParser::parseTryCatch() {
FormatTok->is(Keywords.kw_finally)))) {
break;
}
+ if (FormatTok->is(tok::kw_catch))
+ SeenCatch = true;
nextToken();
while (FormatTok->isNot(tok::l_brace)) {
if (FormatTok->is(tok::l_paren)) {
@@ -3090,6 +3093,10 @@ void UnwrappedLineParser::parseTryCatch() {
}
nextToken();
}
+ if (SeenCatch) {
+ FormatTok->setFinalizedType(TT_ControlStatementLBrace);
+ SeenCatch = false;
+ }
NeedsUnwrappedLine = false;
Line->MustBeDeclaration = false;
CompoundStatementIndenter Indenter(this, Style, Line->Level);
diff --git a/clang/unittests/Format/FormatTest.cpp b/clang/unittests/Format/FormatTest.cpp
index b62d49e17c83f..49284c7f51e27 100644
--- a/clang/unittests/Format/FormatTest.cpp
+++ b/clang/unittests/Format/FormatTest.cpp
@@ -3419,6 +3419,17 @@ TEST_F(FormatTest, MultiLineControlStatements) {
"{\n"
"};",
Style);
+
+ Style = getLLVMStyle();
+ Style.AllowShortBlocksOnASingleLine = FormatStyle::SBS_Always;
+ Style.AllowShortIfStatementsOnASingleLine = FormatStyle::SIS_WithoutElse;
+ Style.AllowShortLoopsOnASingleLine = true;
+ Style.BreakBeforeBraces = FormatStyle::BS_Custom;
+ Style.BraceWrapping.AfterControlStatement = FormatStyle::BWACS_MultiLine;
+ verifyFormat("if (true) { return; }", Style);
+ verifyFormat("while (true) { return; }", Style);
+ // Failing test in https://reviews.llvm.org/D114521#3151727
+ verifyFormat("for (;;) { bar(); }", Style);
}
TEST_F(FormatTest, BeforeWhile) {
More information about the cfe-commits
mailing list