https://github.com/owenca updated https://github.com/llvm/llvm-project/pull/135906
>From c4ccaf91a0f2c3f3ea8e45eb75d36c1464b6c3b8 Mon Sep 17 00:00:00 2001 From: Owen Pan <owenpi...@gmail.com> Date: Tue, 15 Apr 2025 21:21:28 -0700 Subject: [PATCH] [clang-format] Fix a bug in BWACS_MultiLine Fix #51940 --- clang/lib/Format/TokenAnnotator.cpp | 15 ++++++- clang/lib/Format/UnwrappedLineFormatter.cpp | 45 ++++----------------- clang/lib/Format/UnwrappedLineParser.cpp | 11 ++++- clang/unittests/Format/FormatTest.cpp | 11 +++++ 4 files changed, 41 insertions(+), 41 deletions(-) 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 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..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) { _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits