-
Notifications
You must be signed in to change notification settings - Fork 14.3k
[clang-format] Fix a bug in BWACS_MultiLine #135906
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Merged
Merged
Conversation
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
@llvm/pr-subscribers-clang-format Author: Owen Pan (owenca) ChangesFix #51940 Full diff: https://github.com/llvm/llvm-project/pull/135906.diff 4 Files Affected:
diff --git a/clang/lib/Format/TokenAnnotator.cpp b/clang/lib/Format/TokenAnnotator.cpp
index ef5f07e2c62ee..05d83726091ac 100644
--- a/clang/lib/Format/TokenAnnotator.cpp
+++ b/clang/lib/Format/TokenAnnotator.cpp
@@ -4153,8 +4153,16 @@ void TokenAnnotator::calculateFormattingInformation(AnnotatedLine &Line) const {
ChildSize + Current->SpacesRequiredBefore;
}
- if (Current->is(TT_CtorInitializerColon))
+ if (Current->is(TT_ControlStatementLBrace) && 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 +5594,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 different 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..8f89d1cd06e22 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,
@@ -3090,6 +3091,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) {
|
HazardyKnusperkeks
approved these changes
Apr 16, 2025
var-const
pushed a commit
to ldionne/llvm-project
that referenced
this pull request
Apr 17, 2025
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Fix #51940