https://github.com/gedare updated https://github.com/llvm/llvm-project/pull/108332
>From 5972376f719665225b04bf121cda6c769e3392d9 Mon Sep 17 00:00:00 2001 From: Gedare Bloom <ged...@rtems.org> Date: Thu, 20 Jun 2024 17:35:39 -0600 Subject: [PATCH 1/8] Format: add AlignAfterControlStatement Introduce new style option to allow overriding the breaking after the opening parenthesis for control statements (if/for/while/switch). Fixes #67738. Fixes #79176. Fixes #80123. --- clang/include/clang/Format/Format.h | 17 ++ clang/lib/Format/ContinuationIndenter.cpp | 69 +++-- clang/lib/Format/Format.cpp | 13 + clang/lib/Format/TokenAnnotator.cpp | 8 +- clang/unittests/Format/ConfigParseTest.cpp | 8 + clang/unittests/Format/FormatTest.cpp | 298 +++++++++++++++++++++ 6 files changed, 391 insertions(+), 22 deletions(-) diff --git a/clang/include/clang/Format/Format.h b/clang/include/clang/Format/Format.h index 3ac4318824ac0..2b2bcb6764e9b 100644 --- a/clang/include/clang/Format/Format.h +++ b/clang/include/clang/Format/Format.h @@ -62,6 +62,22 @@ struct FormatStyle { /// \version 3.3 int AccessModifierOffset; + /// Different styles for breaking the parenthesis after a control statement + /// (``if/switch/while/for ...``). + /// \version 21 + enum BreakAfterControlStatementStyle : int8_t { + /// Use the default behavior. + BACSS_Default, + /// Force break after the left parenthesis of a control statement only + /// when the expression exceeds the column limit, and align on the + /// ``ContinuationIndentWidth``. + BACSS_MultiLine, + /// Do not force a break after the control statment. + BACSS_No, + }; + + BreakAfterControlStatementStyle AlignAfterControlStatement; + /// Different styles for aligning after open brackets. enum BracketAlignmentStyle : int8_t { /// Align parameters on the open bracket, e.g.: @@ -5305,6 +5321,7 @@ struct FormatStyle { bool operator==(const FormatStyle &R) const { return AccessModifierOffset == R.AccessModifierOffset && + AlignAfterControlStatement == R.AlignAfterControlStatement && AlignAfterOpenBracket == R.AlignAfterOpenBracket && AlignArrayOfStructures == R.AlignArrayOfStructures && AlignConsecutiveAssignments == R.AlignConsecutiveAssignments && diff --git a/clang/lib/Format/ContinuationIndenter.cpp b/clang/lib/Format/ContinuationIndenter.cpp index 4e4e48f90a89f..f91da11cd2f44 100644 --- a/clang/lib/Format/ContinuationIndenter.cpp +++ b/clang/lib/Format/ContinuationIndenter.cpp @@ -814,6 +814,11 @@ void ContinuationIndenter::addTokenOnCurrentLine(LineState &State, bool DryRun, // parenthesis by disallowing any further line breaks if there is no line // break after the opening parenthesis. Don't break if it doesn't conserve // columns. + auto IsOtherConditional = [&](const FormatToken &Tok) { + return Tok.isOneOf(tok::kw_for, tok::kw_while, tok::kw_switch) || + (Style.isJavaScript() && Tok.is(Keywords.kw_await) && Tok.Previous && + Tok.Previous->is(tok::kw_for)); + }; auto IsOpeningBracket = [&](const FormatToken &Tok) { auto IsStartOfBracedList = [&]() { return Tok.is(tok::l_brace) && Tok.isNot(BK_Block) && @@ -825,26 +830,36 @@ void ContinuationIndenter::addTokenOnCurrentLine(LineState &State, bool DryRun, } if (!Tok.Previous) return true; - if (Tok.Previous->isIf()) - return Style.AlignAfterOpenBracket == FormatStyle::BAS_AlwaysBreak; - return !Tok.Previous->isOneOf(TT_CastRParen, tok::kw_for, tok::kw_while, - tok::kw_switch) && - !(Style.isJavaScript() && Tok.Previous->is(Keywords.kw_await)); + if (Tok.Previous->isIf()) { + /* For backward compatibility, use AlignAfterOpenBracket + * in case AlignAfterControlStatement is not initialized */ + return Style.AlignAfterControlStatement == FormatStyle::BACSS_MultiLine || + (Style.AlignAfterControlStatement == FormatStyle::BACSS_Default && + Style.AlignAfterOpenBracket == FormatStyle::BAS_AlwaysBreak); + } + if (IsOtherConditional(*Tok.Previous)) + return Style.AlignAfterControlStatement == FormatStyle::BACSS_MultiLine; + if (Style.AlignAfterOpenBracket == FormatStyle::BAS_AlwaysBreak || + Style.AlignAfterOpenBracket == FormatStyle::BAS_BlockIndent) { + return !Tok.Previous->is(TT_CastRParen) && + !(Style.isJavaScript() && Tok.is(Keywords.kw_await)); + } + return false; }; auto IsFunctionCallParen = [](const FormatToken &Tok) { return Tok.is(tok::l_paren) && Tok.ParameterCount > 0 && Tok.Previous && Tok.Previous->is(tok::identifier); }; - auto IsInTemplateString = [this](const FormatToken &Tok) { + auto IsInTemplateString = [this](const FormatToken &Tok, bool NestBlocks) { if (!Style.isJavaScript()) return false; for (const auto *Prev = &Tok; Prev; Prev = Prev->Previous) { if (Prev->is(TT_TemplateString) && Prev->opensScope()) return true; - if (Prev->opensScope() || - (Prev->is(TT_TemplateString) && Prev->closesScope())) { - break; - } + if (Prev->opensScope() && !NestBlocks) + return false; + if (Prev->is(TT_TemplateString) && Prev->closesScope()) + return false; } return false; }; @@ -866,21 +881,24 @@ void ContinuationIndenter::addTokenOnCurrentLine(LineState &State, bool DryRun, Tok.isOneOf(tok::ellipsis, Keywords.kw_await))) { return true; } - const auto *Previous = Tok.Previous; - if (!Previous || (!Previous->isOneOf(TT_FunctionDeclarationLParen, - TT_LambdaDefinitionLParen) && - !IsFunctionCallParen(*Previous))) { + const auto *Previous = TokAfterLParen.Previous; + assert(Previous); // IsOpeningBracket(Previous) + if (Previous->Previous && (Previous->Previous->isIf() || + IsOtherConditional(*Previous->Previous))) { + return false; + } + if (!Previous->isOneOf(TT_FunctionDeclarationLParen, + TT_LambdaDefinitionLParen) && + !IsFunctionCallParen(*Previous)) { return true; } - if (IsOpeningBracket(Tok) || IsInTemplateString(Tok)) + if (IsOpeningBracket(Tok) || IsInTemplateString(Tok, true)) return true; const auto *Next = Tok.Next; return !Next || Next->isMemberAccess() || Next->is(TT_FunctionDeclarationLParen) || IsFunctionCallParen(*Next); }; - if ((Style.AlignAfterOpenBracket == FormatStyle::BAS_AlwaysBreak || - Style.AlignAfterOpenBracket == FormatStyle::BAS_BlockIndent) && - IsOpeningBracket(Previous) && State.Column > getNewLineColumn(State) && + if (IsOpeningBracket(Previous) && State.Column > getNewLineColumn(State) && // Don't do this for simple (no expressions) one-argument function calls // as that feels like needlessly wasting whitespace, e.g.: // @@ -910,7 +928,7 @@ void ContinuationIndenter::addTokenOnCurrentLine(LineState &State, bool DryRun, !(Current.MacroParent && Previous.MacroParent) && (Current.isNot(TT_LineComment) || Previous.isOneOf(BK_BracedInit, TT_VerilogMultiLineListLParen)) && - !IsInTemplateString(Current)) { + !IsInTemplateString(Current, false)) { CurrentState.Indent = State.Column + Spaces; CurrentState.IsAligned = true; } @@ -1247,8 +1265,17 @@ unsigned ContinuationIndenter::addTokenOnNewLine(LineState &State, } if (PreviousNonComment && PreviousNonComment->is(tok::l_paren)) { - CurrentState.BreakBeforeClosingParen = - Style.AlignAfterOpenBracket == FormatStyle::BAS_BlockIndent; + auto Previous = PreviousNonComment->Previous; + if (Previous && + (Previous->isIf() || + Previous->isOneOf(tok::kw_for, tok::kw_while, tok::kw_switch))) { + CurrentState.BreakBeforeClosingParen = + Style.AlignAfterControlStatement == FormatStyle::BACSS_MultiLine && + Style.AlignAfterOpenBracket == FormatStyle::BAS_BlockIndent; + } else { + CurrentState.BreakBeforeClosingParen = + Style.AlignAfterOpenBracket == FormatStyle::BAS_BlockIndent; + } } if (PreviousNonComment && PreviousNonComment->is(TT_TemplateOpener)) diff --git a/clang/lib/Format/Format.cpp b/clang/lib/Format/Format.cpp index 0cfa061681053..5776d297fab24 100644 --- a/clang/lib/Format/Format.cpp +++ b/clang/lib/Format/Format.cpp @@ -202,6 +202,16 @@ template <> struct MappingTraits<FormatStyle::BraceWrappingFlags> { } }; +template <> +struct ScalarEnumerationTraits<FormatStyle::BreakAfterControlStatementStyle> { + static void enumeration(IO &IO, + FormatStyle::BreakAfterControlStatementStyle &Value) { + IO.enumCase(Value, "Default", FormatStyle::BACSS_Default); + IO.enumCase(Value, "MultiLine", FormatStyle::BACSS_MultiLine); + IO.enumCase(Value, "No", FormatStyle::BACSS_No); + } +}; + template <> struct ScalarEnumerationTraits<FormatStyle::BracketAlignmentStyle> { static void enumeration(IO &IO, FormatStyle::BracketAlignmentStyle &Value) { IO.enumCase(Value, "Align", FormatStyle::BAS_Align); @@ -965,6 +975,8 @@ template <> struct MappingTraits<FormatStyle> { IO.mapOptional("AccessModifierOffset", Style.AccessModifierOffset); IO.mapOptional("AlignAfterOpenBracket", Style.AlignAfterOpenBracket); + IO.mapOptional("AlignAfterControlStatement", + Style.AlignAfterControlStatement); IO.mapOptional("AlignArrayOfStructures", Style.AlignArrayOfStructures); IO.mapOptional("AlignConsecutiveAssignments", Style.AlignConsecutiveAssignments); @@ -1499,6 +1511,7 @@ static void expandPresetsSpacesInParens(FormatStyle &Expanded) { FormatStyle getLLVMStyle(FormatStyle::LanguageKind Language) { FormatStyle LLVMStyle; LLVMStyle.AccessModifierOffset = -2; + LLVMStyle.AlignAfterControlStatement = FormatStyle::BACSS_Default; LLVMStyle.AlignAfterOpenBracket = FormatStyle::BAS_Align; LLVMStyle.AlignArrayOfStructures = FormatStyle::AIAS_None; LLVMStyle.AlignConsecutiveAssignments = {}; diff --git a/clang/lib/Format/TokenAnnotator.cpp b/clang/lib/Format/TokenAnnotator.cpp index 542c362ccacae..c17a7c458bf42 100644 --- a/clang/lib/Format/TokenAnnotator.cpp +++ b/clang/lib/Format/TokenAnnotator.cpp @@ -6222,7 +6222,13 @@ bool TokenAnnotator::canBreakBefore(const AnnotatedLine &Line, if (Next && Next->is(tok::l_paren)) return false; const FormatToken *Previous = Right.MatchingParen->Previous; - return !(Previous && (Previous->is(tok::kw_for) || Previous->isIf())); + if (!Previous) + return true; + if (Previous->isIf() || + Previous->isOneOf(tok::kw_for, tok::kw_while, tok::kw_switch)) { + return Style.AlignAfterControlStatement == FormatStyle::BACSS_MultiLine; + } + return true; } if (Left.isOneOf(tok::r_paren, TT_TrailingAnnotation) && diff --git a/clang/unittests/Format/ConfigParseTest.cpp b/clang/unittests/Format/ConfigParseTest.cpp index 5b9055d0a80be..2c26df5298258 100644 --- a/clang/unittests/Format/ConfigParseTest.cpp +++ b/clang/unittests/Format/ConfigParseTest.cpp @@ -532,6 +532,14 @@ TEST(ConfigParseTest, ParsesConfiguration) { CHECK_PARSE("EnumTrailingComma: Remove", EnumTrailingComma, FormatStyle::ETC_Remove); + Style.AlignAfterControlStatement = FormatStyle::BACSS_Default; + CHECK_PARSE("AlignAfterControlStatement: MultiLine", + AlignAfterControlStatement, FormatStyle::BACSS_MultiLine); + CHECK_PARSE("AlignAfterControlStatement: No", AlignAfterControlStatement, + FormatStyle::BACSS_No); + CHECK_PARSE("AlignAfterControlStatement: Default", AlignAfterControlStatement, + FormatStyle::BACSS_Default); + Style.AlignAfterOpenBracket = FormatStyle::BAS_AlwaysBreak; CHECK_PARSE("AlignAfterOpenBracket: Align", AlignAfterOpenBracket, FormatStyle::BAS_Align); diff --git a/clang/unittests/Format/FormatTest.cpp b/clang/unittests/Format/FormatTest.cpp index c0633ba3c29b3..8cad1637c1d1d 100644 --- a/clang/unittests/Format/FormatTest.cpp +++ b/clang/unittests/Format/FormatTest.cpp @@ -9694,6 +9694,304 @@ TEST_F(FormatTest, ParenthesesAndOperandAlignment) { Style); } +TEST_F(FormatTest, AlignAfterConditionalStatements) { + FormatStyle Style = getLLVMStyle(); + + Style.AlignAfterOpenBracket = FormatStyle::BAS_DontAlign; + Style.AlignAfterControlStatement = FormatStyle::BACSS_MultiLine; + + verifyFormat("void foo() {\n" + " if constexpr (\n" + " (aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa |\n" + " bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb" + "bbb) == 0) {\n" + " return;\n" + " } else if (\n" + " (aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa &\n" + " bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb" + "bbb) == 0) {\n" + " return;\n" + " }\n" + "}", + Style); + + verifyFormat("void foo() {\n" + " switch (\n" + " aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa |\n" + " bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb) {\n" + " default:\n" + " break;\n" + " }\n" + "}", + Style); + + verifyFormat( + "void foo() {\n" + " for (\n" + " aaaaaaaaaaaaaaaaaaaaaa = 0;\n" + " (aaaaaaaaaaaaaaaaaaaaaa->bbbbbbbbbbbbbb |\n" + " aaaaaaaaaaaaaaaaaaaaaa->ccccccccccccccccccccccc) == 0;\n" + " aaaaaaaaaaaaaaaaaaaaa = aaaaaaaaaaaaaaaaaaaaaa->next) {\n" + " ;\n" + " }\n" + "}", + Style); + + verifyFormat( + "void foo() {\n" + " while (\n" + " (aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa |\n" + " bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb) == 0) " + "{\n" + " continue;\n" + " }\n" + "}", + Style); + + Style.AlignAfterOpenBracket = FormatStyle::BAS_AlwaysBreak; + Style.AlignAfterControlStatement = FormatStyle::BACSS_MultiLine; + + verifyFormat("void foo() {\n" + " if constexpr (\n" + " (aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa |\n" + " bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb" + ") == 0) {\n" + " return;\n" + " } else if (\n" + " (aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa &\n" + " bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb" + ") == 0) {\n" + " return;\n" + " }\n" + "}", + Style); + + verifyFormat("void foo() {\n" + " switch (\n" + " aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa |\n" + " bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb) {\n" + " default:\n" + " break;\n" + " }\n" + "}", + Style); + + verifyFormat("void foo() {\n" + " for (\n" + " aaaaaaaaaaaaaaaaaaaaaa = 0;\n" + " (aaaaaaaaaaaaaaaaaaaaaa->bbbbbbbbbbbbbb |\n" + " aaaaaaaaaaaaaaaaaaaaaa->ccccccccccccccccccccccc) == 0;\n" + " aaaaaaaaaaaaaaaaaaaaa = aaaaaaaaaaaaaaaaaaaaaa->next) {\n" + " ;\n" + " }\n" + "}", + Style); + + verifyFormat("void foo() {\n" + " while (\n" + " (aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa |\n" + " bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb) == 0) " + "{\n" + " continue;\n" + " }\n" + "}", + Style); + + Style.AlignAfterOpenBracket = FormatStyle::BAS_AlwaysBreak; + Style.AlignAfterControlStatement = FormatStyle::BACSS_MultiLine; + + verifyFormat("void foo() {\n" + " if constexpr (\n" + " (aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa |\n" + " bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb" + ") == 0) {\n" + " return;\n" + " } else if (\n" + " (aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa &\n" + " bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb" + ") == 0) {\n" + " return;\n" + " }\n" + "}", + Style); + + verifyFormat("void foo() {\n" + " switch (\n" + " aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa |\n" + " bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb) {\n" + " default:\n" + " break;\n" + " }\n" + "}", + Style); + + verifyFormat("void foo() {\n" + " for (\n" + " aaaaaaaaaaaaaaaaaaaaaa = 0;\n" + " (aaaaaaaaaaaaaaaaaaaaaa->bbbbbbbbbbbbbb |\n" + " aaaaaaaaaaaaaaaaaaaaaa->ccccccccccccccccccccccc) == 0;\n" + " aaaaaaaaaaaaaaaaaaaaa = aaaaaaaaaaaaaaaaaaaaaa->next) {\n" + " ;\n" + " }\n" + "}", + Style); + + verifyFormat("void foo() {\n" + " while (\n" + " (aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa |\n" + " bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb) == 0) " + "{\n" + " continue;\n" + " }\n" + "}", + Style); + + Style.AlignAfterOpenBracket = FormatStyle::BAS_AlwaysBreak; + Style.AlignAfterControlStatement = FormatStyle::BACSS_No; + + verifyFormat("void foo() {\n" + " if constexpr ((aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa |\n" + " bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb" + "bbbbbbbbbb) ==\n" + " 0) {\n" + " return;\n" + " } else if ((aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa &\n" + " bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb" + "bbbbbbb) == 0) {\n" + " return;\n" + " }\n" + "}", + Style); + + verifyFormat("void foo() {\n" + " switch (aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa |\n" + " bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb) {\n" + " default:\n" + " break;\n" + " }\n" + "}", + Style); + + verifyFormat( + "void foo() {\n" + " for (aaaaaaaaaaaaaaaaaaaaaa = 0;\n" + " (aaaaaaaaaaaaaaaaaaaaaa->bbbbbbbbbbbbbb |\n" + " aaaaaaaaaaaaaaaaaaaaaa->ccccccccccccccccccccccc) == 0;\n" + " aaaaaaaaaaaaaaaaaaaaa = aaaaaaaaaaaaaaaaaaaaaa->next) {\n" + " ;\n" + " }\n" + "}", + Style); + + verifyFormat( + "void foo() {\n" + " while ((aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa |\n" + " bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb) == 0) " + "{\n" + " continue;\n" + " }\n" + "}", + Style); + + Style.AlignAfterOpenBracket = FormatStyle::BAS_BlockIndent; + Style.AlignAfterControlStatement = FormatStyle::BACSS_MultiLine; + + verifyFormat( + "void foo() {\n" + " if constexpr (\n" + " (aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa |\n" + " bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb) == 0\n" + " ) {\n" + " return;\n" + " } else if (\n" + " (aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa &\n" + " bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb) == 0\n" + " ) {\n" + " return;\n" + " }\n" + "}", + Style); + + verifyFormat("void foo() {\n" + " switch (\n" + " aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa | " + "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb\n" + " ) {\n" + " default:\n" + " break;\n" + " }\n" + "}", + Style); + + verifyFormat("void foo() {\n" + " for (\n" + " aaaaaaaaaaaaaaaaaaaaaa = 0;\n" + " (aaaaaaaaaaaaaaaaaaaaaa->bbbbbbbbbbbbbb |\n" + " aaaaaaaaaaaaaaaaaaaaaa->ccccccccccccccccccccccc) == 0;\n" + " aaaaaaaaaaaaaaaaaaaaa = aaaaaaaaaaaaaaaaaaaaaa->next\n" + " ) {\n" + " ;\n" + " }\n" + "}", + Style); + + verifyFormat("void foo() {\n" + " while (\n" + " (aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa |\n" + " bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb) == 0\n" + " ) {\n" + " continue;\n" + " }\n" + "}", + Style); + + Style.AlignAfterOpenBracket = FormatStyle::BAS_BlockIndent; + Style.AlignAfterControlStatement = FormatStyle::BACSS_No; + + verifyFormat("void foo() {\n" + " if constexpr ((aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa |\n" + " bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb" + "bbbbbbbbbb) ==\n" + " 0) {\n" + " return;\n" + " } else if ((aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa &\n" + " bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb" + "bbbbbbb) == 0) {\n" + " return;\n" + " }\n" + "}", + Style); + + verifyFormat("void foo() {\n" + " switch (aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa |\n" + " bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb) {\n" + " default:\n" + " break;\n" + " }\n" + "}", + Style); + + verifyFormat( + "void foo() {\n" + " for (aaaaaaaaaaaaaaaaaaaaaa = 0;\n" + " (aaaaaaaaaaaaaaaaaaaaaa->bbbbbbbbbbbbbb |\n" + " aaaaaaaaaaaaaaaaaaaaaa->ccccccccccccccccccccccc) == 0;\n" + " aaaaaaaaaaaaaaaaaaaaa = aaaaaaaaaaaaaaaaaaaaaa->next) {\n" + " ;\n" + " }\n" + "}", + Style); + + verifyFormat( + "void foo() {\n" + " while ((aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa |\n" + " bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb) == 0) {\n" + " continue;\n" + " }\n" + "}", + Style); +} + TEST_F(FormatTest, BreaksConditionalExpressions) { verifyFormat( "aaaa(aaaaaaaaaaaaaaaaaaaa, aaaaaaaaaaaaaaaaaaaaaaaaaa\n" >From eafb17601c009ee04b68e65af627276df4a364ad Mon Sep 17 00:00:00 2001 From: Gedare Bloom <ged...@rtems.org> Date: Wed, 11 Sep 2024 22:48:12 -0600 Subject: [PATCH 2/8] Update release notes --- clang/docs/ReleaseNotes.rst | 3 +++ 1 file changed, 3 insertions(+) diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst index 648b32c659b4f..0ca0f13332951 100644 --- a/clang/docs/ReleaseNotes.rst +++ b/clang/docs/ReleaseNotes.rst @@ -911,6 +911,9 @@ clang-format ``enum`` enumerator lists. - Add ``OneLineFormatOffRegex`` option for turning formatting off for one line. - Add ``SpaceAfterOperatorKeyword`` option. +- Add ``BreakAfterOpenBracketIf``, ``BreakAfterOpenBracketLoop``, + ``BreakAfterOpenBracketSwitch``, ``BreakBeforeCloseBracketIf``, + ``BreakBeforeCloseBracketLoop``, ``BreakBeforeCloseBracketSwitch`` options. clang-refactor -------------- >From dd3af42dd2c214bb470fd93fbbb65434ce75b39e Mon Sep 17 00:00:00 2001 From: Gedare Bloom <ged...@rtems.org> Date: Wed, 21 May 2025 16:11:23 -0600 Subject: [PATCH 3/8] updates --- clang/include/clang/Format/Format.h | 178 +++++++++++++++++++-- clang/lib/Format/ContinuationIndenter.cpp | 59 ++++--- clang/lib/Format/Format.cpp | 91 +++++++++-- clang/lib/Format/TokenAnnotator.cpp | 37 ++++- clang/unittests/Format/ConfigParseTest.cpp | 56 ++++++- clang/unittests/Format/FormatTest.cpp | 30 +++- 6 files changed, 386 insertions(+), 65 deletions(-) diff --git a/clang/include/clang/Format/Format.h b/clang/include/clang/Format/Format.h index 2b2bcb6764e9b..7976929041db2 100644 --- a/clang/include/clang/Format/Format.h +++ b/clang/include/clang/Format/Format.h @@ -62,21 +62,86 @@ struct FormatStyle { /// \version 3.3 int AccessModifierOffset; - /// Different styles for breaking the parenthesis after a control statement - /// (``if/switch/while/for ...``). + /// Different styles for breaking the parenthesis after ``if/else if``. /// \version 21 - enum BreakAfterControlStatementStyle : int8_t { - /// Use the default behavior. - BACSS_Default, - /// Force break after the left parenthesis of a control statement only - /// when the expression exceeds the column limit, and align on the - /// ``ContinuationIndentWidth``. - BACSS_MultiLine, - /// Do not force a break after the control statment. - BACSS_No, + enum BreakAfterOpenBracketIfStyle : int8_t { + /// Always break the opening parenthesis of an if statement, e.g.: + /// \code + /// if constexpr ( + /// a) + /// \endcode + BAOBIS_Always, + /// Force break after the left parenthesis of an if statement only + /// when the expression exceeds the column limit, e.g..: + /// \code + /// if constexpr ( + /// a || + /// b) + /// \endcode + BAOBIS_MultiLine, + /// Do not force a break after the control statement. + /// \code + /// if constexpr (a || + /// b + /// \endcode + BAOBIS_No, + }; + + BreakAfterOpenBracketIfStyle BreakAfterOpenBracketIf; + + /// Different styles for breaking the parenthesis after loops ``(for/while)``. + /// \version 21 + enum BreakAfterOpenBracketLoopStyle : int8_t { + /// Always break the opening parenthesis of a loop statement, e.g.: + /// \code + /// while ( + /// a) { + /// \endcode + BAOBLS_Always, + /// Force break after the left parenthesis of a loop only + /// when the expression exceeds the column limit, e.g..: + /// \code + /// while ( + /// a && + /// b) { + /// \endcode + BAOBLS_MultiLine, + /// Do not force a break after the control statement. + /// \code + /// while (a && + /// b) { + /// \endcode + BAOBLS_No, + }; + + BreakAfterOpenBracketLoopStyle BreakAfterOpenBracketLoop; + + /// Different styles for breaking the parenthesis after ``switch``. + /// \version 21 + enum BreakAfterOpenBracketSwitchStyle : int8_t { + /// Always break the opening parenthesis of a switch statement, e.g.: + /// \code + /// switch ( + /// a) { + /// \endcode + BAOBSS_Always, + /// Force break after the left parenthesis of a switch only + /// when the expression exceeds the column limit, e.g..: + /// \code + /// switch ( + /// a && + /// b) { + /// \endcode + BAOBSS_MultiLine, + /// Do not force a break after the control statement. + /// \code + /// switch (a && + /// b) { + /// \endcode + BAOBSS_No, }; - BreakAfterControlStatementStyle AlignAfterControlStatement; + BreakAfterOpenBracketSwitchStyle BreakAfterOpenBracketSwitch; /// Different styles for aligning after open brackets. enum BracketAlignmentStyle : int8_t { @@ -2231,6 +2296,88 @@ struct FormatStyle { /// \version 3.7 BraceBreakingStyle BreakBeforeBraces; + /// Different styles for breaking before ``if/else if`` closing parenthesis. + /// \version 21 + enum BreakBeforeCloseBracketIfStyle : int8_t { + /// Always break the closing parenthesis of an if statement, e.g.: + /// \code + /// if constexpr (a + /// ) + /// \endcode + BBCBIS_Always, + /// Force break before the closing parenthesis of an if statement only + /// when the expression exceeds the column limit, e.g..: + /// \code + /// if constexpr (a || + /// b + /// ) + /// \endcode + BBCBIS_MultiLine, + /// Do not force a break before closing the if control statement. + /// \code + /// if constexpr (a || + /// b) + /// \endcode + BBCBIS_No, + }; + + BreakBeforeCloseBracketIfStyle BreakBeforeCloseBracketIf; + + /// Different styles for breaking before loop ``(for/while)`` closing + /// parenthesis. + /// \version 21 + enum BreakBeforeCloseBracketLoopStyle : int8_t { + /// Always break the closing parenthesis of a loop statement, e.g.: + /// \code + /// while (a + /// ) { + /// \endcode + BBCBLS_Always, + /// Force break before the closing parenthesis of a loop only + /// when the expression exceeds the column limit, e.g..: + /// \code + /// while (a && + /// b + /// ) { + /// \endcode + BBCBLS_MultiLine, + /// Do not force a break before closing the loop control statement. + /// \code + /// while (a && + /// b) { + /// \endcode + BBCBLS_No, + }; + + BreakBeforeCloseBracketLoopStyle BreakBeforeCloseBracketLoop; + + /// Different styles for breaking before ``switch`` closing parenthesis. + /// \version 21 + enum BreakBeforeCloseBracketSwitchStyle : int8_t { + /// Always break before the closing parenthesis of a switch statement, e.g.: + /// \code + /// switch (a + /// ) { + /// \endcode + BBCBSS_Always, + /// Force break before the closing parenthesis of a switch only + /// when the expression exceeds the column limit, e.g..: + /// \code + /// switch (a && + /// b + /// ) { + /// \endcode + BBCBSS_MultiLine, + /// Do not force a break before closing the switch control statement. + /// \code + /// switch (a && + /// b) { + /// \endcode + BBCBSS_No, + }; + + BreakBeforeCloseBracketSwitchStyle BreakBeforeCloseBracketSwitch; + /// Different ways to break before concept declarations. enum BreakBeforeConceptDeclarationsStyle : int8_t { /// Keep the template declaration line together with ``concept``. @@ -5321,7 +5468,6 @@ struct FormatStyle { bool operator==(const FormatStyle &R) const { return AccessModifierOffset == R.AccessModifierOffset && - AlignAfterControlStatement == R.AlignAfterControlStatement && AlignAfterOpenBracket == R.AlignAfterOpenBracket && AlignArrayOfStructures == R.AlignArrayOfStructures && AlignConsecutiveAssignments == R.AlignConsecutiveAssignments && @@ -5371,10 +5517,16 @@ struct FormatStyle { BreakAdjacentStringLiterals == R.BreakAdjacentStringLiterals && BreakAfterAttributes == R.BreakAfterAttributes && BreakAfterJavaFieldAnnotations == R.BreakAfterJavaFieldAnnotations && + BreakAfterOpenBracketIf == R.BreakAfterOpenBracketIf && + BreakAfterOpenBracketLoop == R.BreakAfterOpenBracketLoop && + BreakAfterOpenBracketSwitch == R.BreakAfterOpenBracketSwitch && BreakAfterReturnType == R.BreakAfterReturnType && BreakArrays == R.BreakArrays && BreakBeforeBinaryOperators == R.BreakBeforeBinaryOperators && BreakBeforeBraces == R.BreakBeforeBraces && + BreakBeforeCloseBracketIf == R.BreakBeforeCloseBracketIf && + BreakBeforeCloseBracketLoop == R.BreakBeforeCloseBracketLoop && + BreakBeforeCloseBracketSwitch == R.BreakBeforeCloseBracketSwitch && BreakBeforeConceptDeclarations == R.BreakBeforeConceptDeclarations && BreakBeforeInlineASMColon == R.BreakBeforeInlineASMColon && BreakBeforeTemplateCloser == R.BreakBeforeTemplateCloser && diff --git a/clang/lib/Format/ContinuationIndenter.cpp b/clang/lib/Format/ContinuationIndenter.cpp index f91da11cd2f44..0611a76c73692 100644 --- a/clang/lib/Format/ContinuationIndenter.cpp +++ b/clang/lib/Format/ContinuationIndenter.cpp @@ -814,8 +814,8 @@ void ContinuationIndenter::addTokenOnCurrentLine(LineState &State, bool DryRun, // parenthesis by disallowing any further line breaks if there is no line // break after the opening parenthesis. Don't break if it doesn't conserve // columns. - auto IsOtherConditional = [&](const FormatToken &Tok) { - return Tok.isOneOf(tok::kw_for, tok::kw_while, tok::kw_switch) || + auto IsLoopConditional = [&](const FormatToken &Tok) { + return Tok.isOneOf(tok::kw_for, tok::kw_while) || (Style.isJavaScript() && Tok.is(Keywords.kw_await) && Tok.Previous && Tok.Previous->is(tok::kw_for)); }; @@ -833,12 +833,18 @@ void ContinuationIndenter::addTokenOnCurrentLine(LineState &State, bool DryRun, if (Tok.Previous->isIf()) { /* For backward compatibility, use AlignAfterOpenBracket * in case AlignAfterControlStatement is not initialized */ - return Style.AlignAfterControlStatement == FormatStyle::BACSS_MultiLine || - (Style.AlignAfterControlStatement == FormatStyle::BACSS_Default && - Style.AlignAfterOpenBracket == FormatStyle::BAS_AlwaysBreak); + return Style.BreakAfterOpenBracketIf == FormatStyle::BAOBIS_MultiLine || + Style.BreakAfterOpenBracketIf == FormatStyle::BAOBIS_Always; + } + if (IsLoopConditional(*Tok.Previous)) { + return Style.BreakAfterOpenBracketLoop == FormatStyle::BAOBLS_MultiLine || + Style.BreakAfterOpenBracketLoop == FormatStyle::BAOBLS_Always; + } + if (Tok.Previous->is(tok::kw_switch)) { + return Style.BreakAfterOpenBracketSwitch == + FormatStyle::BAOBSS_MultiLine || + Style.BreakAfterOpenBracketSwitch == FormatStyle::BAOBSS_Always; } - if (IsOtherConditional(*Tok.Previous)) - return Style.AlignAfterControlStatement == FormatStyle::BACSS_MultiLine; if (Style.AlignAfterOpenBracket == FormatStyle::BAS_AlwaysBreak || Style.AlignAfterOpenBracket == FormatStyle::BAS_BlockIndent) { return !Tok.Previous->is(TT_CastRParen) && @@ -883,8 +889,9 @@ void ContinuationIndenter::addTokenOnCurrentLine(LineState &State, bool DryRun, } const auto *Previous = TokAfterLParen.Previous; assert(Previous); // IsOpeningBracket(Previous) - if (Previous->Previous && (Previous->Previous->isIf() || - IsOtherConditional(*Previous->Previous))) { + if (Previous->Previous && + (Previous->Previous->isIf() || IsLoopConditional(*Previous->Previous) || + Previous->Previous->is(tok::kw_switch))) { return false; } if (!Previous->isOneOf(TT_FunctionDeclarationLParen, @@ -1266,16 +1273,32 @@ unsigned ContinuationIndenter::addTokenOnNewLine(LineState &State, if (PreviousNonComment && PreviousNonComment->is(tok::l_paren)) { auto Previous = PreviousNonComment->Previous; - if (Previous && - (Previous->isIf() || - Previous->isOneOf(tok::kw_for, tok::kw_while, tok::kw_switch))) { - CurrentState.BreakBeforeClosingParen = - Style.AlignAfterControlStatement == FormatStyle::BACSS_MultiLine && - Style.AlignAfterOpenBracket == FormatStyle::BAS_BlockIndent; - } else { - CurrentState.BreakBeforeClosingParen = - Style.AlignAfterOpenBracket == FormatStyle::BAS_BlockIndent; + if (Previous) { + + auto IsLoopConditional = [&](const FormatToken &Tok) { + return Tok.isOneOf(tok::kw_for, tok::kw_while) || + (Style.isJavaScript() && Tok.is(Keywords.kw_await) && + Tok.Previous && Tok.Previous->is(tok::kw_for)); + }; + + if (Previous->isIf()) { + CurrentState.BreakBeforeClosingParen = + Style.BreakBeforeCloseBracketIf == FormatStyle::BBCBIS_MultiLine || + Style.BreakBeforeCloseBracketIf == FormatStyle::BBCBIS_Always; + } else if (IsLoopConditional(*Previous)) { + CurrentState.BreakBeforeClosingParen = + Style.BreakBeforeCloseBracketLoop == + FormatStyle::BBCBLS_MultiLine || + Style.BreakBeforeCloseBracketLoop == FormatStyle::BBCBLS_Always; + } else if (Previous->is(tok::kw_switch)) { + CurrentState.BreakBeforeClosingParen = + Style.BreakBeforeCloseBracketSwitch == + FormatStyle::BBCBSS_MultiLine || + Style.BreakBeforeCloseBracketSwitch == FormatStyle::BBCBSS_Always; + } } + CurrentState.BreakBeforeClosingParen = + Style.AlignAfterOpenBracket == FormatStyle::BAS_BlockIndent; } if (PreviousNonComment && PreviousNonComment->is(TT_TemplateOpener)) diff --git a/clang/lib/Format/Format.cpp b/clang/lib/Format/Format.cpp index 5776d297fab24..9177a5077b653 100644 --- a/clang/lib/Format/Format.cpp +++ b/clang/lib/Format/Format.cpp @@ -202,16 +202,6 @@ template <> struct MappingTraits<FormatStyle::BraceWrappingFlags> { } }; -template <> -struct ScalarEnumerationTraits<FormatStyle::BreakAfterControlStatementStyle> { - static void enumeration(IO &IO, - FormatStyle::BreakAfterControlStatementStyle &Value) { - IO.enumCase(Value, "Default", FormatStyle::BACSS_Default); - IO.enumCase(Value, "MultiLine", FormatStyle::BACSS_MultiLine); - IO.enumCase(Value, "No", FormatStyle::BACSS_No); - } -}; - template <> struct ScalarEnumerationTraits<FormatStyle::BracketAlignmentStyle> { static void enumeration(IO &IO, FormatStyle::BracketAlignmentStyle &Value) { IO.enumCase(Value, "Align", FormatStyle::BAS_Align); @@ -241,6 +231,67 @@ struct ScalarEnumerationTraits< } }; +template <> +struct ScalarEnumerationTraits<FormatStyle::BreakAfterOpenBracketIfStyle> { + static void enumeration(IO &IO, + FormatStyle::BreakAfterOpenBracketIfStyle &Value) { + IO.enumCase(Value, "Always", FormatStyle::BAOBIS_Always); + IO.enumCase(Value, "MultiLine", FormatStyle::BAOBIS_MultiLine); + IO.enumCase(Value, "No", FormatStyle::BAOBIS_No); + } +}; + +template <> +struct ScalarEnumerationTraits<FormatStyle::BreakAfterOpenBracketLoopStyle> { + static void enumeration(IO &IO, + FormatStyle::BreakAfterOpenBracketLoopStyle &Value) { + IO.enumCase(Value, "Always", FormatStyle::BAOBLS_Always); + IO.enumCase(Value, "MultiLine", FormatStyle::BAOBLS_MultiLine); + IO.enumCase(Value, "No", FormatStyle::BAOBLS_No); + } +}; + +template <> +struct ScalarEnumerationTraits<FormatStyle::BreakAfterOpenBracketSwitchStyle> { + static void + enumeration(IO &IO, FormatStyle::BreakAfterOpenBracketSwitchStyle &Value) { + IO.enumCase(Value, "Always", FormatStyle::BAOBSS_Always); + IO.enumCase(Value, "MultiLine", FormatStyle::BAOBSS_MultiLine); + IO.enumCase(Value, "No", FormatStyle::BAOBSS_No); + } +}; + +template <> +struct ScalarEnumerationTraits<FormatStyle::BreakBeforeCloseBracketIfStyle> { + static void enumeration(IO &IO, + FormatStyle::BreakBeforeCloseBracketIfStyle &Value) { + IO.enumCase(Value, "Always", FormatStyle::BBCBIS_Always); + IO.enumCase(Value, "MultiLine", FormatStyle::BBCBIS_MultiLine); + IO.enumCase(Value, "No", FormatStyle::BBCBIS_No); + } +}; + +template <> +struct ScalarEnumerationTraits<FormatStyle::BreakBeforeCloseBracketLoopStyle> { + static void + enumeration(IO &IO, FormatStyle::BreakBeforeCloseBracketLoopStyle &Value) { + IO.enumCase(Value, "Always", FormatStyle::BBCBLS_Always); + IO.enumCase(Value, "MultiLine", FormatStyle::BBCBLS_MultiLine); + IO.enumCase(Value, "No", FormatStyle::BBCBLS_No); + } +}; + +template <> +struct ScalarEnumerationTraits< + FormatStyle::BreakBeforeCloseBracketSwitchStyle> { + static void + enumeration(IO &IO, FormatStyle::BreakBeforeCloseBracketSwitchStyle &Value) { + IO.enumCase(Value, "Always", FormatStyle::BBCBSS_Always); + IO.enumCase(Value, "MultiLine", FormatStyle::BBCBSS_MultiLine); + IO.enumCase(Value, "No", FormatStyle::BBCBSS_No); + } +}; + template <> struct ScalarEnumerationTraits< FormatStyle::BreakBeforeConceptDeclarationsStyle> { @@ -975,8 +1026,6 @@ template <> struct MappingTraits<FormatStyle> { IO.mapOptional("AccessModifierOffset", Style.AccessModifierOffset); IO.mapOptional("AlignAfterOpenBracket", Style.AlignAfterOpenBracket); - IO.mapOptional("AlignAfterControlStatement", - Style.AlignAfterControlStatement); IO.mapOptional("AlignArrayOfStructures", Style.AlignArrayOfStructures); IO.mapOptional("AlignConsecutiveAssignments", Style.AlignConsecutiveAssignments); @@ -1039,10 +1088,21 @@ template <> struct MappingTraits<FormatStyle> { IO.mapOptional("BreakAfterAttributes", Style.BreakAfterAttributes); IO.mapOptional("BreakAfterJavaFieldAnnotations", Style.BreakAfterJavaFieldAnnotations); + IO.mapOptional("BreakAfterOpenBracketIf", Style.BreakAfterOpenBracketIf); + IO.mapOptional("BreakAfterOpenBracketLoop", + Style.BreakAfterOpenBracketLoop); + IO.mapOptional("BreakAfterOpenBracketSwitch", + Style.BreakAfterOpenBracketSwitch); IO.mapOptional("BreakAfterReturnType", Style.BreakAfterReturnType); IO.mapOptional("BreakArrays", Style.BreakArrays); IO.mapOptional("BreakBeforeBinaryOperators", Style.BreakBeforeBinaryOperators); + IO.mapOptional("BreakBeforeCloseBracketIf", + Style.BreakBeforeCloseBracketIf); + IO.mapOptional("BreakBeforeCloseBracketLoop", + Style.BreakBeforeCloseBracketLoop); + IO.mapOptional("BreakBeforeCloseBracketSwitch", + Style.BreakBeforeCloseBracketSwitch); IO.mapOptional("BreakBeforeConceptDeclarations", Style.BreakBeforeConceptDeclarations); IO.mapOptional("BreakBeforeBraces", Style.BreakBeforeBraces); @@ -1511,7 +1571,6 @@ static void expandPresetsSpacesInParens(FormatStyle &Expanded) { FormatStyle getLLVMStyle(FormatStyle::LanguageKind Language) { FormatStyle LLVMStyle; LLVMStyle.AccessModifierOffset = -2; - LLVMStyle.AlignAfterControlStatement = FormatStyle::BACSS_Default; LLVMStyle.AlignAfterOpenBracket = FormatStyle::BAS_Align; LLVMStyle.AlignArrayOfStructures = FormatStyle::AIAS_None; LLVMStyle.AlignConsecutiveAssignments = {}; @@ -1571,10 +1630,16 @@ FormatStyle getLLVMStyle(FormatStyle::LanguageKind Language) { LLVMStyle.BreakAdjacentStringLiterals = true; LLVMStyle.BreakAfterAttributes = FormatStyle::ABS_Leave; LLVMStyle.BreakAfterJavaFieldAnnotations = false; + LLVMStyle.BreakAfterOpenBracketIf = FormatStyle::BAOBIS_No; + LLVMStyle.BreakAfterOpenBracketLoop = FormatStyle::BAOBLS_No; + LLVMStyle.BreakAfterOpenBracketSwitch = FormatStyle::BAOBSS_No; LLVMStyle.BreakAfterReturnType = FormatStyle::RTBS_None; LLVMStyle.BreakArrays = true; LLVMStyle.BreakBeforeBinaryOperators = FormatStyle::BOS_None; LLVMStyle.BreakBeforeBraces = FormatStyle::BS_Attach; + LLVMStyle.BreakBeforeCloseBracketIf = FormatStyle::BBCBIS_No; + LLVMStyle.BreakBeforeCloseBracketLoop = FormatStyle::BBCBLS_No; + LLVMStyle.BreakBeforeCloseBracketSwitch = FormatStyle::BBCBSS_No; LLVMStyle.BreakBeforeConceptDeclarations = FormatStyle::BBCDS_Always; LLVMStyle.BreakBeforeInlineASMColon = FormatStyle::BBIAS_OnlyMultiline; LLVMStyle.BreakBeforeTemplateCloser = false; diff --git a/clang/lib/Format/TokenAnnotator.cpp b/clang/lib/Format/TokenAnnotator.cpp index c17a7c458bf42..b88600893d22d 100644 --- a/clang/lib/Format/TokenAnnotator.cpp +++ b/clang/lib/Format/TokenAnnotator.cpp @@ -6212,10 +6212,16 @@ bool TokenAnnotator::canBreakBefore(const AnnotatedLine &Line, // We only break before r_paren if we're in a block indented context. if (Right.is(tok::r_paren)) { - if (Style.AlignAfterOpenBracket != FormatStyle::BAS_BlockIndent || - !Right.MatchingParen) { + bool might_break = + Style.BreakBeforeCloseBracketIf == FormatStyle::BBCBIS_Always || + Style.BreakBeforeCloseBracketIf == FormatStyle::BBCBIS_MultiLine || + Style.BreakBeforeCloseBracketLoop == FormatStyle::BBCBLS_Always || + Style.BreakBeforeCloseBracketLoop == FormatStyle::BBCBLS_MultiLine || + Style.BreakBeforeCloseBracketSwitch == FormatStyle::BBCBSS_Always || + Style.BreakBeforeCloseBracketSwitch == FormatStyle::BBCBSS_MultiLine || + Style.AlignAfterOpenBracket == FormatStyle::BAS_BlockIndent; + if (!might_break || !Right.MatchingParen) return false; - } auto Next = Right.Next; if (Next && Next->is(tok::r_paren)) Next = Next->Next; @@ -6224,11 +6230,28 @@ bool TokenAnnotator::canBreakBefore(const AnnotatedLine &Line, const FormatToken *Previous = Right.MatchingParen->Previous; if (!Previous) return true; - if (Previous->isIf() || - Previous->isOneOf(tok::kw_for, tok::kw_while, tok::kw_switch)) { - return Style.AlignAfterControlStatement == FormatStyle::BACSS_MultiLine; + if (Previous->isIf()) { + return Style.BreakBeforeCloseBracketIf == FormatStyle::BBCBIS_Always || + Style.BreakBeforeCloseBracketIf == FormatStyle::BBCBIS_MultiLine; + } + auto IsLoopConditional = [&](const FormatToken &Tok) { + return Tok.isOneOf(tok::kw_for, tok::kw_while) || + (Style.isJavaScript() && Tok.is(Keywords.kw_await) && + Tok.Previous && Tok.Previous->is(tok::kw_for)); + }; + + if (IsLoopConditional(*Previous)) { + return Style.BreakBeforeCloseBracketLoop == FormatStyle::BBCBLS_Always || + Style.BreakBeforeCloseBracketLoop == FormatStyle::BBCBLS_MultiLine; } - return true; + + if (Previous->is(tok::kw_switch)) { + return Style.BreakBeforeCloseBracketSwitch == + FormatStyle::BBCBSS_Always || + Style.BreakBeforeCloseBracketSwitch == + FormatStyle::BBCBSS_MultiLine; + } + return Style.AlignAfterOpenBracket == FormatStyle::BAS_BlockIndent; } if (Left.isOneOf(tok::r_paren, TT_TrailingAnnotation) && diff --git a/clang/unittests/Format/ConfigParseTest.cpp b/clang/unittests/Format/ConfigParseTest.cpp index 2c26df5298258..da0df40955fab 100644 --- a/clang/unittests/Format/ConfigParseTest.cpp +++ b/clang/unittests/Format/ConfigParseTest.cpp @@ -532,14 +532,6 @@ TEST(ConfigParseTest, ParsesConfiguration) { CHECK_PARSE("EnumTrailingComma: Remove", EnumTrailingComma, FormatStyle::ETC_Remove); - Style.AlignAfterControlStatement = FormatStyle::BACSS_Default; - CHECK_PARSE("AlignAfterControlStatement: MultiLine", - AlignAfterControlStatement, FormatStyle::BACSS_MultiLine); - CHECK_PARSE("AlignAfterControlStatement: No", AlignAfterControlStatement, - FormatStyle::BACSS_No); - CHECK_PARSE("AlignAfterControlStatement: Default", AlignAfterControlStatement, - FormatStyle::BACSS_Default); - Style.AlignAfterOpenBracket = FormatStyle::BAS_AlwaysBreak; CHECK_PARSE("AlignAfterOpenBracket: Align", AlignAfterOpenBracket, FormatStyle::BAS_Align); @@ -765,6 +757,30 @@ TEST(ConfigParseTest, ParsesConfiguration) { " AfterControlStatement: false", BraceWrapping.AfterControlStatement, FormatStyle::BWACS_Never); + Style.BreakAfterOpenBracketIf = FormatStyle::BAOBIS_No; + CHECK_PARSE("BreakAfterOpenBracketIf: MultiLine", BreakAfterOpenBracketIf, + FormatStyle::BAOBIS_MultiLine); + CHECK_PARSE("BreakAfterOpenBracketIf: No", BreakAfterOpenBracketIf, + FormatStyle::BAOBIS_No); + CHECK_PARSE("BreakAfterOpenBracketIf: Always", BreakAfterOpenBracketIf, + FormatStyle::BAOBIS_Always); + + Style.BreakAfterOpenBracketLoop = FormatStyle::BAOBLS_No; + CHECK_PARSE("BreakAfterOpenBracketLoop: MultiLine", BreakAfterOpenBracketLoop, + FormatStyle::BAOBLS_MultiLine); + CHECK_PARSE("BreakAfterOpenBracketLoop: No", BreakAfterOpenBracketLoop, + FormatStyle::BAOBLS_No); + CHECK_PARSE("BreakAfterOpenBracketLoop: Always", BreakAfterOpenBracketLoop, + FormatStyle::BAOBLS_Always); + + Style.BreakAfterOpenBracketSwitch = FormatStyle::BAOBSS_No; + CHECK_PARSE("BreakAfterOpenBracketSwitch: MultiLine", + BreakAfterOpenBracketSwitch, FormatStyle::BAOBSS_MultiLine); + CHECK_PARSE("BreakAfterOpenBracketSwitch: No", BreakAfterOpenBracketSwitch, + FormatStyle::BAOBSS_No); + CHECK_PARSE("BreakAfterOpenBracketSwitch: Always", + BreakAfterOpenBracketSwitch, FormatStyle::BAOBSS_Always); + Style.BreakAfterReturnType = FormatStyle::RTBS_All; CHECK_PARSE("BreakAfterReturnType: None", BreakAfterReturnType, FormatStyle::RTBS_None); @@ -1075,6 +1091,30 @@ TEST(ConfigParseTest, ParsesConfiguration) { CHECK_PARSE("RequiresClausePosition: OwnLine", RequiresClausePosition, FormatStyle::RCPS_OwnLine); + Style.BreakBeforeCloseBracketIf = FormatStyle::BBCBIS_No; + CHECK_PARSE("BreakBeforeCloseBracketIf: MultiLine", BreakBeforeCloseBracketIf, + FormatStyle::BBCBIS_MultiLine); + CHECK_PARSE("BreakBeforeCloseBracketIf: No", BreakBeforeCloseBracketIf, + FormatStyle::BBCBIS_No); + CHECK_PARSE("BreakBeforeCloseBracketIf: Always", BreakBeforeCloseBracketIf, + FormatStyle::BBCBIS_Always); + + Style.BreakBeforeCloseBracketLoop = FormatStyle::BBCBLS_No; + CHECK_PARSE("BreakBeforeCloseBracketLoop: MultiLine", + BreakBeforeCloseBracketLoop, FormatStyle::BBCBLS_MultiLine); + CHECK_PARSE("BreakBeforeCloseBracketLoop: No", BreakBeforeCloseBracketLoop, + FormatStyle::BBCBLS_No); + CHECK_PARSE("BreakBeforeCloseBracketLoop: Always", + BreakBeforeCloseBracketLoop, FormatStyle::BBCBLS_Always); + + Style.BreakBeforeCloseBracketSwitch = FormatStyle::BBCBSS_No; + CHECK_PARSE("BreakBeforeCloseBracketSwitch: MultiLine", + BreakBeforeCloseBracketSwitch, FormatStyle::BBCBSS_MultiLine); + CHECK_PARSE("BreakBeforeCloseBracketSwitch: No", + BreakBeforeCloseBracketSwitch, FormatStyle::BBCBSS_No); + CHECK_PARSE("BreakBeforeCloseBracketSwitch: Always", + BreakBeforeCloseBracketSwitch, FormatStyle::BBCBSS_Always); + CHECK_PARSE("BreakBeforeConceptDeclarations: Never", BreakBeforeConceptDeclarations, FormatStyle::BBCDS_Never); CHECK_PARSE("BreakBeforeConceptDeclarations: Always", diff --git a/clang/unittests/Format/FormatTest.cpp b/clang/unittests/Format/FormatTest.cpp index 8cad1637c1d1d..c7e639b88c81e 100644 --- a/clang/unittests/Format/FormatTest.cpp +++ b/clang/unittests/Format/FormatTest.cpp @@ -9698,7 +9698,9 @@ TEST_F(FormatTest, AlignAfterConditionalStatements) { FormatStyle Style = getLLVMStyle(); Style.AlignAfterOpenBracket = FormatStyle::BAS_DontAlign; - Style.AlignAfterControlStatement = FormatStyle::BACSS_MultiLine; + Style.BreakAfterOpenBracketIf = FormatStyle::BAOBIS_MultiLine; + Style.BreakAfterOpenBracketLoop = FormatStyle::BAOBLS_MultiLine; + Style.BreakAfterOpenBracketSwitch = FormatStyle::BAOBSS_MultiLine; verifyFormat("void foo() {\n" " if constexpr (\n" @@ -9749,7 +9751,9 @@ TEST_F(FormatTest, AlignAfterConditionalStatements) { Style); Style.AlignAfterOpenBracket = FormatStyle::BAS_AlwaysBreak; - Style.AlignAfterControlStatement = FormatStyle::BACSS_MultiLine; + Style.BreakAfterOpenBracketIf = FormatStyle::BAOBIS_MultiLine; + Style.BreakAfterOpenBracketLoop = FormatStyle::BAOBLS_MultiLine; + Style.BreakAfterOpenBracketSwitch = FormatStyle::BAOBSS_MultiLine; verifyFormat("void foo() {\n" " if constexpr (\n" @@ -9798,7 +9802,9 @@ TEST_F(FormatTest, AlignAfterConditionalStatements) { Style); Style.AlignAfterOpenBracket = FormatStyle::BAS_AlwaysBreak; - Style.AlignAfterControlStatement = FormatStyle::BACSS_MultiLine; + Style.BreakAfterOpenBracketIf = FormatStyle::BAOBIS_MultiLine; + Style.BreakAfterOpenBracketLoop = FormatStyle::BAOBLS_MultiLine; + Style.BreakAfterOpenBracketSwitch = FormatStyle::BAOBSS_MultiLine; verifyFormat("void foo() {\n" " if constexpr (\n" @@ -9847,7 +9853,9 @@ TEST_F(FormatTest, AlignAfterConditionalStatements) { Style); Style.AlignAfterOpenBracket = FormatStyle::BAS_AlwaysBreak; - Style.AlignAfterControlStatement = FormatStyle::BACSS_No; + Style.BreakAfterOpenBracketIf = FormatStyle::BAOBIS_No; + Style.BreakAfterOpenBracketLoop = FormatStyle::BAOBLS_No; + Style.BreakAfterOpenBracketSwitch = FormatStyle::BAOBSS_No; verifyFormat("void foo() {\n" " if constexpr ((aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa |\n" @@ -9894,7 +9902,12 @@ TEST_F(FormatTest, AlignAfterConditionalStatements) { Style); Style.AlignAfterOpenBracket = FormatStyle::BAS_BlockIndent; - Style.AlignAfterControlStatement = FormatStyle::BACSS_MultiLine; + Style.BreakAfterOpenBracketIf = FormatStyle::BAOBIS_MultiLine; + Style.BreakAfterOpenBracketLoop = FormatStyle::BAOBLS_MultiLine; + Style.BreakAfterOpenBracketSwitch = FormatStyle::BAOBSS_MultiLine; + Style.BreakBeforeCloseBracketIf = FormatStyle::BBCBIS_MultiLine; + Style.BreakBeforeCloseBracketLoop = FormatStyle::BBCBLS_MultiLine; + Style.BreakBeforeCloseBracketSwitch = FormatStyle::BBCBSS_MultiLine; verifyFormat( "void foo() {\n" @@ -9946,7 +9959,12 @@ TEST_F(FormatTest, AlignAfterConditionalStatements) { Style); Style.AlignAfterOpenBracket = FormatStyle::BAS_BlockIndent; - Style.AlignAfterControlStatement = FormatStyle::BACSS_No; + Style.BreakAfterOpenBracketIf = FormatStyle::BAOBIS_No; + Style.BreakAfterOpenBracketLoop = FormatStyle::BAOBLS_No; + Style.BreakAfterOpenBracketSwitch = FormatStyle::BAOBSS_No; + Style.BreakBeforeCloseBracketIf = FormatStyle::BBCBIS_No; + Style.BreakBeforeCloseBracketLoop = FormatStyle::BBCBLS_No; + Style.BreakBeforeCloseBracketSwitch = FormatStyle::BBCBSS_No; verifyFormat("void foo() {\n" " if constexpr ((aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa |\n" >From 42f1cb61a5e4cd7cd328abcce20100f7c556ef1c Mon Sep 17 00:00:00 2001 From: Gedare Bloom <ged...@rtems.org> Date: Wed, 21 May 2025 16:44:48 -0600 Subject: [PATCH 4/8] Change to use bool options for each control statement --- clang/include/clang/Format/Format.h | 205 ++++++--------------- clang/lib/Format/ContinuationIndenter.cpp | 47 ++--- clang/lib/Format/Format.cpp | 76 +------- clang/lib/Format/TokenAnnotator.cpp | 37 +--- clang/unittests/Format/ConfigParseTest.cpp | 54 +----- clang/unittests/Format/FormatTest.cpp | 48 ++--- 6 files changed, 121 insertions(+), 346 deletions(-) diff --git a/clang/include/clang/Format/Format.h b/clang/include/clang/Format/Format.h index 7976929041db2..8387a6de8c329 100644 --- a/clang/include/clang/Format/Format.h +++ b/clang/include/clang/Format/Format.h @@ -62,86 +62,38 @@ struct FormatStyle { /// \version 3.3 int AccessModifierOffset; - /// Different styles for breaking the parenthesis after ``if/else if``. + /// Force break after the left parenthesis of an if control statement + /// when the expression exceeds the column limit. + /// \code + /// true: false: + /// if constexpr ( vs. if constexpr (a || + /// a || b) + /// b) + /// \endcode /// \version 21 - enum BreakAfterOpenBracketIfStyle : int8_t { - /// Always break the opening parenthesis of an if statement, e.g.: - /// \code - /// if constexpr ( - /// a) - /// \endcode - BAOBIS_Always, - /// Force break after the left parenthesis of an if statement only - /// when the expression exceeds the column limit, e.g..: - /// \code - /// if constexpr ( - /// a || - /// b) - /// \endcode - BAOBIS_MultiLine, - /// Do not force a break after the control statement. - /// \code - /// if constexpr (a || - /// b - /// \endcode - BAOBIS_No, - }; - - BreakAfterOpenBracketIfStyle BreakAfterOpenBracketIf; + bool BreakAfterOpenBracketIf; - /// Different styles for breaking the parenthesis after loops ``(for/while)``. + /// Force break after the left parenthesis of a loop control statement + /// when the expression exceeds the column limit. + /// \code + /// true: false: + /// while ( vs. while (a && + /// a && b) { + /// b) { + /// \endcode /// \version 21 - enum BreakAfterOpenBracketLoopStyle : int8_t { - /// Always break the opening parenthesis of a loop statement, e.g.: - /// \code - /// while ( - /// a) { - /// \endcode - BAOBLS_Always, - /// Force break after the left parenthesis of a loop only - /// when the expression exceeds the column limit, e.g..: - /// \code - /// while ( - /// a && - /// b) { - /// \endcode - BAOBLS_MultiLine, - /// Do not force a break after the control statement. - /// \code - /// while (a && - /// b) { - /// \endcode - BAOBLS_No, - }; + bool BreakAfterOpenBracketLoop; - BreakAfterOpenBracketLoopStyle BreakAfterOpenBracketLoop; - - /// Different styles for breaking the parenthesis after ``switch``. + /// Force break after the left parenthesis of a switch control statement + /// when the expression exceeds the column limit. + /// \code + /// true: false: + /// switch ( vs. switch (a && + /// a && b) { + /// b) { + /// \endcode /// \version 21 - enum BreakAfterOpenBracketSwitchStyle : int8_t { - /// Always break the opening parenthesis of a switch statement, e.g.: - /// \code - /// switch ( - /// a) { - /// \endcode - BAOBSS_Always, - /// Force break after the left parenthesis of a switch only - /// when the expression exceeds the column limit, e.g..: - /// \code - /// switch ( - /// a && - /// b) { - /// \endcode - BAOBSS_MultiLine, - /// Do not force a break after the control statement. - /// \code - /// switch (a && - /// b) { - /// \endcode - BAOBSS_No, - }; - - BreakAfterOpenBracketSwitchStyle BreakAfterOpenBracketSwitch; + bool BreakAfterOpenBracketSwitch; /// Different styles for aligning after open brackets. enum BracketAlignmentStyle : int8_t { @@ -2296,87 +2248,38 @@ struct FormatStyle { /// \version 3.7 BraceBreakingStyle BreakBeforeBraces; - /// Different styles for breaking before ``if/else if`` closing parenthesis. + /// Force break before the right parenthesis of an if control statement + /// when the expression exceeds the column limit. + /// \code + /// true: false: + /// if constexpr (a || vs. if constexpr (a || + /// b b) + /// ) + /// \endcode /// \version 21 - enum BreakBeforeCloseBracketIfStyle : int8_t { - /// Always break the closing parenthesis of an if statement, e.g.: - /// \code - /// if constexpr (a - /// ) - /// \endcode - BBCBIS_Always, - /// Force break before the closing parenthesis of an if statement only - /// when the expression exceeds the column limit, e.g..: - /// \code - /// if constexpr (a || - /// b - /// ) - /// \endcode - BBCBIS_MultiLine, - /// Do not force a break before closing the if control statement. - /// \code - /// if constexpr (a || - /// b) - /// \endcode - BBCBIS_No, - }; - - BreakBeforeCloseBracketIfStyle BreakBeforeCloseBracketIf; + bool BreakBeforeCloseBracketIf; - /// Different styles for breaking before loop ``(for/while)`` closing - /// parenthesis. + /// Force break before the right parenthesis of a loop control statement + /// when the expression exceeds the column limit. + /// \code + /// true: false: + /// while (a && vs. while (a && + /// b b) { + /// ) { + /// \endcode /// \version 21 - enum BreakBeforeCloseBracketLoopStyle : int8_t { - /// Always break the closing parenthesis of a loop statement, e.g.: - /// \code - /// while (a - /// ) { - /// \endcode - BBCBLS_Always, - /// Force break before the closing parenthesis of a loop only - /// when the expression exceeds the column limit, e.g..: - /// \code - /// while (a && - /// b - /// ) { - /// \endcode - BBCBLS_MultiLine, - /// Do not force a break before closing the loop control statement. - /// \code - /// while (a && - /// b) { - /// \endcode - BBCBLS_No, - }; + bool BreakBeforeCloseBracketLoop; - BreakBeforeCloseBracketLoopStyle BreakBeforeCloseBracketLoop; - - /// Different styles for breaking before ``switch`` closing parenthesis. + /// Force break before the right parenthesis of a switch control statement + /// when the expression exceeds the column limit. + /// \code + /// true: false: + /// switch (a && vs. switch (a && + /// b b) { + /// ) { + /// \endcode /// \version 21 - enum BreakBeforeCloseBracketSwitchStyle : int8_t { - /// Always break before the closing parenthesis of a switch statement, e.g.: - /// \code - /// switch (a - /// ) { - /// \endcode - BBCBSS_Always, - /// Force break before the closing parenthesis of a switch only - /// when the expression exceeds the column limit, e.g..: - /// \code - /// switch (a && - /// b - /// ) { - /// \endcode - BBCBSS_MultiLine, - /// Do not force a break before closing the switch control statement. - /// \code - /// switch (a && - /// b) { - /// \endcode - BBCBSS_No, - }; - - BreakBeforeCloseBracketSwitchStyle BreakBeforeCloseBracketSwitch; + bool BreakBeforeCloseBracketSwitch; /// Different ways to break before concept declarations. enum BreakBeforeConceptDeclarationsStyle : int8_t { diff --git a/clang/lib/Format/ContinuationIndenter.cpp b/clang/lib/Format/ContinuationIndenter.cpp index 0611a76c73692..1ccd484cac5cf 100644 --- a/clang/lib/Format/ContinuationIndenter.cpp +++ b/clang/lib/Format/ContinuationIndenter.cpp @@ -358,10 +358,13 @@ bool ContinuationIndenter::canBreak(const LineState &State) { // Allow breaking before the right parens with block indentation if there was // a break after the left parens, which is tracked by BreakBeforeClosingParen. - if (Style.AlignAfterOpenBracket == FormatStyle::BAS_BlockIndent && - Current.is(tok::r_paren)) { + bool might_break_before = + Style.BreakBeforeCloseBracketIf || Style.BreakBeforeCloseBracketLoop || + Style.BreakBeforeCloseBracketSwitch || + Style.AlignAfterOpenBracket == FormatStyle::BAS_BlockIndent; + + if (might_break_before && Current.is(tok::r_paren)) return CurrentState.BreakBeforeClosingParen; - } if (Style.BreakBeforeTemplateCloser && Current.is(TT_TemplateCloser)) return CurrentState.BreakBeforeClosingAngle; @@ -830,21 +833,12 @@ void ContinuationIndenter::addTokenOnCurrentLine(LineState &State, bool DryRun, } if (!Tok.Previous) return true; - if (Tok.Previous->isIf()) { - /* For backward compatibility, use AlignAfterOpenBracket - * in case AlignAfterControlStatement is not initialized */ - return Style.BreakAfterOpenBracketIf == FormatStyle::BAOBIS_MultiLine || - Style.BreakAfterOpenBracketIf == FormatStyle::BAOBIS_Always; - } - if (IsLoopConditional(*Tok.Previous)) { - return Style.BreakAfterOpenBracketLoop == FormatStyle::BAOBLS_MultiLine || - Style.BreakAfterOpenBracketLoop == FormatStyle::BAOBLS_Always; - } - if (Tok.Previous->is(tok::kw_switch)) { - return Style.BreakAfterOpenBracketSwitch == - FormatStyle::BAOBSS_MultiLine || - Style.BreakAfterOpenBracketSwitch == FormatStyle::BAOBSS_Always; - } + if (Tok.Previous->isIf()) + return Style.BreakAfterOpenBracketIf; + if (IsLoopConditional(*Tok.Previous)) + return Style.BreakAfterOpenBracketLoop; + if (Tok.Previous->is(tok::kw_switch)) + return Style.BreakAfterOpenBracketSwitch; if (Style.AlignAfterOpenBracket == FormatStyle::BAS_AlwaysBreak || Style.AlignAfterOpenBracket == FormatStyle::BAS_BlockIndent) { return !Tok.Previous->is(TT_CastRParen) && @@ -1282,23 +1276,18 @@ unsigned ContinuationIndenter::addTokenOnNewLine(LineState &State, }; if (Previous->isIf()) { - CurrentState.BreakBeforeClosingParen = - Style.BreakBeforeCloseBracketIf == FormatStyle::BBCBIS_MultiLine || - Style.BreakBeforeCloseBracketIf == FormatStyle::BBCBIS_Always; + CurrentState.BreakBeforeClosingParen = Style.BreakBeforeCloseBracketIf; } else if (IsLoopConditional(*Previous)) { CurrentState.BreakBeforeClosingParen = - Style.BreakBeforeCloseBracketLoop == - FormatStyle::BBCBLS_MultiLine || - Style.BreakBeforeCloseBracketLoop == FormatStyle::BBCBLS_Always; + Style.BreakBeforeCloseBracketLoop; } else if (Previous->is(tok::kw_switch)) { CurrentState.BreakBeforeClosingParen = - Style.BreakBeforeCloseBracketSwitch == - FormatStyle::BBCBSS_MultiLine || - Style.BreakBeforeCloseBracketSwitch == FormatStyle::BBCBSS_Always; + Style.BreakBeforeCloseBracketSwitch; + } else { + CurrentState.BreakBeforeClosingParen = + Style.AlignAfterOpenBracket == FormatStyle::BAS_BlockIndent; } } - CurrentState.BreakBeforeClosingParen = - Style.AlignAfterOpenBracket == FormatStyle::BAS_BlockIndent; } if (PreviousNonComment && PreviousNonComment->is(TT_TemplateOpener)) diff --git a/clang/lib/Format/Format.cpp b/clang/lib/Format/Format.cpp index 9177a5077b653..27dadbb1593b1 100644 --- a/clang/lib/Format/Format.cpp +++ b/clang/lib/Format/Format.cpp @@ -231,67 +231,6 @@ struct ScalarEnumerationTraits< } }; -template <> -struct ScalarEnumerationTraits<FormatStyle::BreakAfterOpenBracketIfStyle> { - static void enumeration(IO &IO, - FormatStyle::BreakAfterOpenBracketIfStyle &Value) { - IO.enumCase(Value, "Always", FormatStyle::BAOBIS_Always); - IO.enumCase(Value, "MultiLine", FormatStyle::BAOBIS_MultiLine); - IO.enumCase(Value, "No", FormatStyle::BAOBIS_No); - } -}; - -template <> -struct ScalarEnumerationTraits<FormatStyle::BreakAfterOpenBracketLoopStyle> { - static void enumeration(IO &IO, - FormatStyle::BreakAfterOpenBracketLoopStyle &Value) { - IO.enumCase(Value, "Always", FormatStyle::BAOBLS_Always); - IO.enumCase(Value, "MultiLine", FormatStyle::BAOBLS_MultiLine); - IO.enumCase(Value, "No", FormatStyle::BAOBLS_No); - } -}; - -template <> -struct ScalarEnumerationTraits<FormatStyle::BreakAfterOpenBracketSwitchStyle> { - static void - enumeration(IO &IO, FormatStyle::BreakAfterOpenBracketSwitchStyle &Value) { - IO.enumCase(Value, "Always", FormatStyle::BAOBSS_Always); - IO.enumCase(Value, "MultiLine", FormatStyle::BAOBSS_MultiLine); - IO.enumCase(Value, "No", FormatStyle::BAOBSS_No); - } -}; - -template <> -struct ScalarEnumerationTraits<FormatStyle::BreakBeforeCloseBracketIfStyle> { - static void enumeration(IO &IO, - FormatStyle::BreakBeforeCloseBracketIfStyle &Value) { - IO.enumCase(Value, "Always", FormatStyle::BBCBIS_Always); - IO.enumCase(Value, "MultiLine", FormatStyle::BBCBIS_MultiLine); - IO.enumCase(Value, "No", FormatStyle::BBCBIS_No); - } -}; - -template <> -struct ScalarEnumerationTraits<FormatStyle::BreakBeforeCloseBracketLoopStyle> { - static void - enumeration(IO &IO, FormatStyle::BreakBeforeCloseBracketLoopStyle &Value) { - IO.enumCase(Value, "Always", FormatStyle::BBCBLS_Always); - IO.enumCase(Value, "MultiLine", FormatStyle::BBCBLS_MultiLine); - IO.enumCase(Value, "No", FormatStyle::BBCBLS_No); - } -}; - -template <> -struct ScalarEnumerationTraits< - FormatStyle::BreakBeforeCloseBracketSwitchStyle> { - static void - enumeration(IO &IO, FormatStyle::BreakBeforeCloseBracketSwitchStyle &Value) { - IO.enumCase(Value, "Always", FormatStyle::BBCBSS_Always); - IO.enumCase(Value, "MultiLine", FormatStyle::BBCBSS_MultiLine); - IO.enumCase(Value, "No", FormatStyle::BBCBSS_No); - } -}; - template <> struct ScalarEnumerationTraits< FormatStyle::BreakBeforeConceptDeclarationsStyle> { @@ -1630,16 +1569,16 @@ FormatStyle getLLVMStyle(FormatStyle::LanguageKind Language) { LLVMStyle.BreakAdjacentStringLiterals = true; LLVMStyle.BreakAfterAttributes = FormatStyle::ABS_Leave; LLVMStyle.BreakAfterJavaFieldAnnotations = false; - LLVMStyle.BreakAfterOpenBracketIf = FormatStyle::BAOBIS_No; - LLVMStyle.BreakAfterOpenBracketLoop = FormatStyle::BAOBLS_No; - LLVMStyle.BreakAfterOpenBracketSwitch = FormatStyle::BAOBSS_No; + LLVMStyle.BreakAfterOpenBracketIf = false; + LLVMStyle.BreakAfterOpenBracketLoop = false; + LLVMStyle.BreakAfterOpenBracketSwitch = false; LLVMStyle.BreakAfterReturnType = FormatStyle::RTBS_None; LLVMStyle.BreakArrays = true; LLVMStyle.BreakBeforeBinaryOperators = FormatStyle::BOS_None; LLVMStyle.BreakBeforeBraces = FormatStyle::BS_Attach; - LLVMStyle.BreakBeforeCloseBracketIf = FormatStyle::BBCBIS_No; - LLVMStyle.BreakBeforeCloseBracketLoop = FormatStyle::BBCBLS_No; - LLVMStyle.BreakBeforeCloseBracketSwitch = FormatStyle::BBCBSS_No; + LLVMStyle.BreakBeforeCloseBracketIf = false; + LLVMStyle.BreakBeforeCloseBracketLoop = false; + LLVMStyle.BreakBeforeCloseBracketSwitch = false; LLVMStyle.BreakBeforeConceptDeclarations = FormatStyle::BBCDS_Always; LLVMStyle.BreakBeforeInlineASMColon = FormatStyle::BBIAS_OnlyMultiline; LLVMStyle.BreakBeforeTemplateCloser = false; @@ -1900,6 +1839,9 @@ FormatStyle getGoogleStyle(FormatStyle::LanguageKind Language) { GoogleStyle.SpacesBeforeTrailingComments = 1; } else if (Language == FormatStyle::LK_JavaScript) { GoogleStyle.AlignAfterOpenBracket = FormatStyle::BAS_AlwaysBreak; + GoogleStyle.BreakAfterOpenBracketIf = true; + GoogleStyle.BreakAfterOpenBracketLoop = false; + GoogleStyle.BreakAfterOpenBracketSwitch = false; GoogleStyle.AlignOperands = FormatStyle::OAS_DontAlign; GoogleStyle.AllowShortFunctionsOnASingleLine = FormatStyle::SFS_Empty; // TODO: still under discussion whether to switch to SLS_All. diff --git a/clang/lib/Format/TokenAnnotator.cpp b/clang/lib/Format/TokenAnnotator.cpp index b88600893d22d..17f4175affd14 100644 --- a/clang/lib/Format/TokenAnnotator.cpp +++ b/clang/lib/Format/TokenAnnotator.cpp @@ -6210,17 +6210,10 @@ bool TokenAnnotator::canBreakBefore(const AnnotatedLine &Line, (Right.isBlockIndentedInitRBrace(Style))); } - // We only break before r_paren if we're in a block indented context. + // We can break before r_paren if we're in a block indented context or + // a control statement with an explicit style option. if (Right.is(tok::r_paren)) { - bool might_break = - Style.BreakBeforeCloseBracketIf == FormatStyle::BBCBIS_Always || - Style.BreakBeforeCloseBracketIf == FormatStyle::BBCBIS_MultiLine || - Style.BreakBeforeCloseBracketLoop == FormatStyle::BBCBLS_Always || - Style.BreakBeforeCloseBracketLoop == FormatStyle::BBCBLS_MultiLine || - Style.BreakBeforeCloseBracketSwitch == FormatStyle::BBCBSS_Always || - Style.BreakBeforeCloseBracketSwitch == FormatStyle::BBCBSS_MultiLine || - Style.AlignAfterOpenBracket == FormatStyle::BAS_BlockIndent; - if (!might_break || !Right.MatchingParen) + if (!Right.MatchingParen) return false; auto Next = Right.Next; if (Next && Next->is(tok::r_paren)) @@ -6229,28 +6222,18 @@ bool TokenAnnotator::canBreakBefore(const AnnotatedLine &Line, return false; const FormatToken *Previous = Right.MatchingParen->Previous; if (!Previous) - return true; - if (Previous->isIf()) { - return Style.BreakBeforeCloseBracketIf == FormatStyle::BBCBIS_Always || - Style.BreakBeforeCloseBracketIf == FormatStyle::BBCBIS_MultiLine; - } + return false; + if (Previous->isIf()) + return Style.BreakBeforeCloseBracketIf; auto IsLoopConditional = [&](const FormatToken &Tok) { return Tok.isOneOf(tok::kw_for, tok::kw_while) || (Style.isJavaScript() && Tok.is(Keywords.kw_await) && Tok.Previous && Tok.Previous->is(tok::kw_for)); }; - - if (IsLoopConditional(*Previous)) { - return Style.BreakBeforeCloseBracketLoop == FormatStyle::BBCBLS_Always || - Style.BreakBeforeCloseBracketLoop == FormatStyle::BBCBLS_MultiLine; - } - - if (Previous->is(tok::kw_switch)) { - return Style.BreakBeforeCloseBracketSwitch == - FormatStyle::BBCBSS_Always || - Style.BreakBeforeCloseBracketSwitch == - FormatStyle::BBCBSS_MultiLine; - } + if (IsLoopConditional(*Previous)) + return Style.BreakBeforeCloseBracketLoop; + if (Previous->is(tok::kw_switch)) + return Style.BreakBeforeCloseBracketSwitch; return Style.AlignAfterOpenBracket == FormatStyle::BAS_BlockIndent; } diff --git a/clang/unittests/Format/ConfigParseTest.cpp b/clang/unittests/Format/ConfigParseTest.cpp index da0df40955fab..874fb0a309b5c 100644 --- a/clang/unittests/Format/ConfigParseTest.cpp +++ b/clang/unittests/Format/ConfigParseTest.cpp @@ -171,6 +171,12 @@ TEST(ConfigParseTest, ParsesConfigurationBools) { CHECK_PARSE_BOOL(BinPackLongBracedList); CHECK_PARSE_BOOL(BreakAdjacentStringLiterals); CHECK_PARSE_BOOL(BreakAfterJavaFieldAnnotations); + CHECK_PARSE_BOOL(BreakAfterOpenBracketIf); + CHECK_PARSE_BOOL(BreakAfterOpenBracketLoop); + CHECK_PARSE_BOOL(BreakAfterOpenBracketSwitch); + CHECK_PARSE_BOOL(BreakBeforeCloseBracketIf); + CHECK_PARSE_BOOL(BreakBeforeCloseBracketLoop); + CHECK_PARSE_BOOL(BreakBeforeCloseBracketSwitch); CHECK_PARSE_BOOL(BreakBeforeTemplateCloser); CHECK_PARSE_BOOL(BreakBeforeTernaryOperators); CHECK_PARSE_BOOL(BreakStringLiterals); @@ -757,30 +763,6 @@ TEST(ConfigParseTest, ParsesConfiguration) { " AfterControlStatement: false", BraceWrapping.AfterControlStatement, FormatStyle::BWACS_Never); - Style.BreakAfterOpenBracketIf = FormatStyle::BAOBIS_No; - CHECK_PARSE("BreakAfterOpenBracketIf: MultiLine", BreakAfterOpenBracketIf, - FormatStyle::BAOBIS_MultiLine); - CHECK_PARSE("BreakAfterOpenBracketIf: No", BreakAfterOpenBracketIf, - FormatStyle::BAOBIS_No); - CHECK_PARSE("BreakAfterOpenBracketIf: Always", BreakAfterOpenBracketIf, - FormatStyle::BAOBIS_Always); - - Style.BreakAfterOpenBracketLoop = FormatStyle::BAOBLS_No; - CHECK_PARSE("BreakAfterOpenBracketLoop: MultiLine", BreakAfterOpenBracketLoop, - FormatStyle::BAOBLS_MultiLine); - CHECK_PARSE("BreakAfterOpenBracketLoop: No", BreakAfterOpenBracketLoop, - FormatStyle::BAOBLS_No); - CHECK_PARSE("BreakAfterOpenBracketLoop: Always", BreakAfterOpenBracketLoop, - FormatStyle::BAOBLS_Always); - - Style.BreakAfterOpenBracketSwitch = FormatStyle::BAOBSS_No; - CHECK_PARSE("BreakAfterOpenBracketSwitch: MultiLine", - BreakAfterOpenBracketSwitch, FormatStyle::BAOBSS_MultiLine); - CHECK_PARSE("BreakAfterOpenBracketSwitch: No", BreakAfterOpenBracketSwitch, - FormatStyle::BAOBSS_No); - CHECK_PARSE("BreakAfterOpenBracketSwitch: Always", - BreakAfterOpenBracketSwitch, FormatStyle::BAOBSS_Always); - Style.BreakAfterReturnType = FormatStyle::RTBS_All; CHECK_PARSE("BreakAfterReturnType: None", BreakAfterReturnType, FormatStyle::RTBS_None); @@ -1091,30 +1073,6 @@ TEST(ConfigParseTest, ParsesConfiguration) { CHECK_PARSE("RequiresClausePosition: OwnLine", RequiresClausePosition, FormatStyle::RCPS_OwnLine); - Style.BreakBeforeCloseBracketIf = FormatStyle::BBCBIS_No; - CHECK_PARSE("BreakBeforeCloseBracketIf: MultiLine", BreakBeforeCloseBracketIf, - FormatStyle::BBCBIS_MultiLine); - CHECK_PARSE("BreakBeforeCloseBracketIf: No", BreakBeforeCloseBracketIf, - FormatStyle::BBCBIS_No); - CHECK_PARSE("BreakBeforeCloseBracketIf: Always", BreakBeforeCloseBracketIf, - FormatStyle::BBCBIS_Always); - - Style.BreakBeforeCloseBracketLoop = FormatStyle::BBCBLS_No; - CHECK_PARSE("BreakBeforeCloseBracketLoop: MultiLine", - BreakBeforeCloseBracketLoop, FormatStyle::BBCBLS_MultiLine); - CHECK_PARSE("BreakBeforeCloseBracketLoop: No", BreakBeforeCloseBracketLoop, - FormatStyle::BBCBLS_No); - CHECK_PARSE("BreakBeforeCloseBracketLoop: Always", - BreakBeforeCloseBracketLoop, FormatStyle::BBCBLS_Always); - - Style.BreakBeforeCloseBracketSwitch = FormatStyle::BBCBSS_No; - CHECK_PARSE("BreakBeforeCloseBracketSwitch: MultiLine", - BreakBeforeCloseBracketSwitch, FormatStyle::BBCBSS_MultiLine); - CHECK_PARSE("BreakBeforeCloseBracketSwitch: No", - BreakBeforeCloseBracketSwitch, FormatStyle::BBCBSS_No); - CHECK_PARSE("BreakBeforeCloseBracketSwitch: Always", - BreakBeforeCloseBracketSwitch, FormatStyle::BBCBSS_Always); - CHECK_PARSE("BreakBeforeConceptDeclarations: Never", BreakBeforeConceptDeclarations, FormatStyle::BBCDS_Never); CHECK_PARSE("BreakBeforeConceptDeclarations: Always", diff --git a/clang/unittests/Format/FormatTest.cpp b/clang/unittests/Format/FormatTest.cpp index c7e639b88c81e..28609b404ea33 100644 --- a/clang/unittests/Format/FormatTest.cpp +++ b/clang/unittests/Format/FormatTest.cpp @@ -9698,9 +9698,9 @@ TEST_F(FormatTest, AlignAfterConditionalStatements) { FormatStyle Style = getLLVMStyle(); Style.AlignAfterOpenBracket = FormatStyle::BAS_DontAlign; - Style.BreakAfterOpenBracketIf = FormatStyle::BAOBIS_MultiLine; - Style.BreakAfterOpenBracketLoop = FormatStyle::BAOBLS_MultiLine; - Style.BreakAfterOpenBracketSwitch = FormatStyle::BAOBSS_MultiLine; + Style.BreakAfterOpenBracketIf = true; + Style.BreakAfterOpenBracketLoop = true; + Style.BreakAfterOpenBracketSwitch = true; verifyFormat("void foo() {\n" " if constexpr (\n" @@ -9751,9 +9751,9 @@ TEST_F(FormatTest, AlignAfterConditionalStatements) { Style); Style.AlignAfterOpenBracket = FormatStyle::BAS_AlwaysBreak; - Style.BreakAfterOpenBracketIf = FormatStyle::BAOBIS_MultiLine; - Style.BreakAfterOpenBracketLoop = FormatStyle::BAOBLS_MultiLine; - Style.BreakAfterOpenBracketSwitch = FormatStyle::BAOBSS_MultiLine; + Style.BreakAfterOpenBracketIf = true; + Style.BreakAfterOpenBracketLoop = true; + Style.BreakAfterOpenBracketSwitch = true; verifyFormat("void foo() {\n" " if constexpr (\n" @@ -9802,9 +9802,9 @@ TEST_F(FormatTest, AlignAfterConditionalStatements) { Style); Style.AlignAfterOpenBracket = FormatStyle::BAS_AlwaysBreak; - Style.BreakAfterOpenBracketIf = FormatStyle::BAOBIS_MultiLine; - Style.BreakAfterOpenBracketLoop = FormatStyle::BAOBLS_MultiLine; - Style.BreakAfterOpenBracketSwitch = FormatStyle::BAOBSS_MultiLine; + Style.BreakAfterOpenBracketIf = true; + Style.BreakAfterOpenBracketLoop = true; + Style.BreakAfterOpenBracketSwitch = true; verifyFormat("void foo() {\n" " if constexpr (\n" @@ -9853,9 +9853,9 @@ TEST_F(FormatTest, AlignAfterConditionalStatements) { Style); Style.AlignAfterOpenBracket = FormatStyle::BAS_AlwaysBreak; - Style.BreakAfterOpenBracketIf = FormatStyle::BAOBIS_No; - Style.BreakAfterOpenBracketLoop = FormatStyle::BAOBLS_No; - Style.BreakAfterOpenBracketSwitch = FormatStyle::BAOBSS_No; + Style.BreakAfterOpenBracketIf = false; + Style.BreakAfterOpenBracketLoop = false; + Style.BreakAfterOpenBracketSwitch = false; verifyFormat("void foo() {\n" " if constexpr ((aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa |\n" @@ -9902,12 +9902,12 @@ TEST_F(FormatTest, AlignAfterConditionalStatements) { Style); Style.AlignAfterOpenBracket = FormatStyle::BAS_BlockIndent; - Style.BreakAfterOpenBracketIf = FormatStyle::BAOBIS_MultiLine; - Style.BreakAfterOpenBracketLoop = FormatStyle::BAOBLS_MultiLine; - Style.BreakAfterOpenBracketSwitch = FormatStyle::BAOBSS_MultiLine; - Style.BreakBeforeCloseBracketIf = FormatStyle::BBCBIS_MultiLine; - Style.BreakBeforeCloseBracketLoop = FormatStyle::BBCBLS_MultiLine; - Style.BreakBeforeCloseBracketSwitch = FormatStyle::BBCBSS_MultiLine; + Style.BreakAfterOpenBracketIf = true; + Style.BreakAfterOpenBracketLoop = true; + Style.BreakAfterOpenBracketSwitch = true; + Style.BreakBeforeCloseBracketIf = true; + Style.BreakBeforeCloseBracketLoop = true; + Style.BreakBeforeCloseBracketSwitch = true; verifyFormat( "void foo() {\n" @@ -9959,12 +9959,12 @@ TEST_F(FormatTest, AlignAfterConditionalStatements) { Style); Style.AlignAfterOpenBracket = FormatStyle::BAS_BlockIndent; - Style.BreakAfterOpenBracketIf = FormatStyle::BAOBIS_No; - Style.BreakAfterOpenBracketLoop = FormatStyle::BAOBLS_No; - Style.BreakAfterOpenBracketSwitch = FormatStyle::BAOBSS_No; - Style.BreakBeforeCloseBracketIf = FormatStyle::BBCBIS_No; - Style.BreakBeforeCloseBracketLoop = FormatStyle::BBCBLS_No; - Style.BreakBeforeCloseBracketSwitch = FormatStyle::BBCBSS_No; + Style.BreakAfterOpenBracketIf = false; + Style.BreakAfterOpenBracketLoop = false; + Style.BreakAfterOpenBracketSwitch = false; + Style.BreakBeforeCloseBracketIf = false; + Style.BreakBeforeCloseBracketLoop = false; + Style.BreakBeforeCloseBracketSwitch = false; verifyFormat("void foo() {\n" " if constexpr ((aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa |\n" >From ad3b18d07e36365785da2a49b91d828b270acb6b Mon Sep 17 00:00:00 2001 From: Gedare Bloom <ged...@rtems.org> Date: Wed, 21 May 2025 17:39:58 -0600 Subject: [PATCH 5/8] update clang-format-style --- clang/docs/ClangFormatStyleOptions.rst | 78 ++++++++++++++++++++++++++ 1 file changed, 78 insertions(+) diff --git a/clang/docs/ClangFormatStyleOptions.rst b/clang/docs/ClangFormatStyleOptions.rst index 83716cc049ee3..a6ca560d00db0 100644 --- a/clang/docs/ClangFormatStyleOptions.rst +++ b/clang/docs/ClangFormatStyleOptions.rst @@ -2736,6 +2736,45 @@ the configuration (without a prefix: ``Auto``). @Mock DataLoad loader; +.. _BreakAfterOpenBracketIf: + +**BreakAfterOpenBracketIf** (``Boolean``) :versionbadge:`clang-format 21` :ref:`¶ <BreakAfterOpenBracketIf>` + Force break after the left parenthesis of an if control statement + when the expression exceeds the column limit. + + .. code-block:: c++ + + true: false: + if constexpr ( vs. if constexpr (a || + a || b) + b) + +.. _BreakAfterOpenBracketLoop: + +**BreakAfterOpenBracketLoop** (``Boolean``) :versionbadge:`clang-format 21` :ref:`¶ <BreakAfterOpenBracketLoop>` + Force break after the left parenthesis of a loop control statement + when the expression exceeds the column limit. + + .. code-block:: c++ + + true: false: + while ( vs. while (a && + a && b) { + b) { + +.. _BreakAfterOpenBracketSwitch: + +**BreakAfterOpenBracketSwitch** (``Boolean``) :versionbadge:`clang-format 21` :ref:`¶ <BreakAfterOpenBracketSwitch>` + Force break after the left parenthesis of a switch control statement + when the expression exceeds the column limit. + + .. code-block:: c++ + + true: false: + switch ( vs. switch (a && + a && b) { + b) { + .. _BreakAfterReturnType: **BreakAfterReturnType** (``ReturnTypeBreakingStyle``) :versionbadge:`clang-format 19` :ref:`¶ <BreakAfterReturnType>` @@ -3373,6 +3412,45 @@ the configuration (without a prefix: ``Auto``). +.. _BreakBeforeCloseBracketIf: + +**BreakBeforeCloseBracketIf** (``Boolean``) :versionbadge:`clang-format 21` :ref:`¶ <BreakBeforeCloseBracketIf>` + Force break before the right parenthesis of an if control statement + when the expression exceeds the column limit. + + .. code-block:: c++ + + true: false: + if constexpr (a || vs. if constexpr (a || + b b) + ) + +.. _BreakBeforeCloseBracketLoop: + +**BreakBeforeCloseBracketLoop** (``Boolean``) :versionbadge:`clang-format 21` :ref:`¶ <BreakBeforeCloseBracketLoop>` + Force break before the right parenthesis of a loop control statement + when the expression exceeds the column limit. + + .. code-block:: c++ + + true: false: + while (a && vs. while (a && + b b) { + ) { + +.. _BreakBeforeCloseBracketSwitch: + +**BreakBeforeCloseBracketSwitch** (``Boolean``) :versionbadge:`clang-format 21` :ref:`¶ <BreakBeforeCloseBracketSwitch>` + Force break before the right parenthesis of a switch control statement + when the expression exceeds the column limit. + + .. code-block:: c++ + + true: false: + switch (a && vs. switch (a && + b b) { + ) { + .. _BreakBeforeConceptDeclarations: **BreakBeforeConceptDeclarations** (``BreakBeforeConceptDeclarationsStyle``) :versionbadge:`clang-format 12` :ref:`¶ <BreakBeforeConceptDeclarations>` >From c881f6bb1870e50425a6ac6b6809c25bfea82d09 Mon Sep 17 00:00:00 2001 From: Gedare Bloom <ged...@rtems.org> Date: Wed, 21 May 2025 17:47:09 -0600 Subject: [PATCH 6/8] update tests --- clang/unittests/Format/FormatTest.cpp | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-) diff --git a/clang/unittests/Format/FormatTest.cpp b/clang/unittests/Format/FormatTest.cpp index 28609b404ea33..74d62b5722694 100644 --- a/clang/unittests/Format/FormatTest.cpp +++ b/clang/unittests/Format/FormatTest.cpp @@ -9694,7 +9694,7 @@ TEST_F(FormatTest, ParenthesesAndOperandAlignment) { Style); } -TEST_F(FormatTest, AlignAfterConditionalStatements) { +TEST_F(FormatTest, AlignAndBreakControlStatements) { FormatStyle Style = getLLVMStyle(); Style.AlignAfterOpenBracket = FormatStyle::BAS_DontAlign; @@ -9769,6 +9769,20 @@ TEST_F(FormatTest, AlignAfterConditionalStatements) { " }\n" "}", Style); + Style.BreakAfterOpenBracketIf = false; + verifyFormat("void foo() {\n" + " if constexpr ((aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa |\n" + " bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb" + "bbbbbbbbbb) ==\n" + " 0) {\n" + " return;\n" + " } else if ((aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa &\n" + " bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb" + "bbbbbbb) == 0) {\n" + " return;\n" + " }\n" + "}", + Style); verifyFormat("void foo() {\n" " switch (\n" >From 879fd954a02ddbc7df31fb416e68d1c4a55d356a Mon Sep 17 00:00:00 2001 From: Gedare Bloom <ged...@rtems.org> Date: Wed, 21 May 2025 20:59:10 -0600 Subject: [PATCH 7/8] updates --- clang/include/clang/Format/Format.h | 39 ++++++++++++----------- clang/lib/Format/ContinuationIndenter.cpp | 5 +++ clang/unittests/Format/FormatTest.cpp | 3 ++ 3 files changed, 29 insertions(+), 18 deletions(-) diff --git a/clang/include/clang/Format/Format.h b/clang/include/clang/Format/Format.h index 8387a6de8c329..7dd6ba26da532 100644 --- a/clang/include/clang/Format/Format.h +++ b/clang/include/clang/Format/Format.h @@ -67,8 +67,7 @@ struct FormatStyle { /// \code /// true: false: /// if constexpr ( vs. if constexpr (a || - /// a || b) - /// b) + /// a || b) b) /// \endcode /// \version 21 bool BreakAfterOpenBracketIf; @@ -78,8 +77,7 @@ struct FormatStyle { /// \code /// true: false: /// while ( vs. while (a && - /// a && b) { - /// b) { + /// a && b) { b) { /// \endcode /// \version 21 bool BreakAfterOpenBracketLoop; @@ -89,8 +87,7 @@ struct FormatStyle { /// \code /// true: false: /// switch ( vs. switch (a && - /// a && b) { - /// b) { + /// a && b) { b) { /// \endcode /// \version 21 bool BreakAfterOpenBracketSwitch; @@ -2249,34 +2246,40 @@ struct FormatStyle { BraceBreakingStyle BreakBeforeBraces; /// Force break before the right parenthesis of an if control statement - /// when the expression exceeds the column limit. + /// when the expression exceeds the column limit. The break before the + /// closing parenthesis is only made if there is a break after the opening + /// parenthesis. /// \code /// true: false: - /// if constexpr (a || vs. if constexpr (a || - /// b b) - /// ) + /// if constexpr ( vs. if constexpr (a || + /// a || b b) + /// ) /// \endcode /// \version 21 bool BreakBeforeCloseBracketIf; /// Force break before the right parenthesis of a loop control statement - /// when the expression exceeds the column limit. + /// when the expression exceeds the column limit. The break before the + /// closing parenthesis is only made if there is a break after the opening + /// parenthesis. /// \code /// true: false: - /// while (a && vs. while (a && - /// b b) { - /// ) { + /// while ( vs. while (a && + /// a && b b) { + /// ) { /// \endcode /// \version 21 bool BreakBeforeCloseBracketLoop; /// Force break before the right parenthesis of a switch control statement - /// when the expression exceeds the column limit. + /// when the expression exceeds the column limit. The break before the + /// closing parenthesis is only made if there is a break after the opening + /// parenthesis. /// \code /// true: false: - /// switch (a && vs. switch (a && - /// b b) { - /// ) { + /// switch ( vs. switch (a && + /// a && b b) { + /// ) { /// \endcode /// \version 21 bool BreakBeforeCloseBracketSwitch; diff --git a/clang/lib/Format/ContinuationIndenter.cpp b/clang/lib/Format/ContinuationIndenter.cpp index 1ccd484cac5cf..5c83c419ef5c4 100644 --- a/clang/lib/Format/ContinuationIndenter.cpp +++ b/clang/lib/Format/ContinuationIndenter.cpp @@ -1437,6 +1437,11 @@ unsigned ContinuationIndenter::getNewLineColumn(const LineState &State) { State.Stack.size() > 1) { return State.Stack[State.Stack.size() - 2].LastSpace; } + if ((Style.BreakBeforeCloseBracketIf || Style.BreakBeforeCloseBracketLoop || + Style.BreakBeforeCloseBracketSwitch) && + Current.is(tok::r_paren) && State.Stack.size() > 1) { + return State.Stack[State.Stack.size() - 2].LastSpace; + } if (Style.BreakBeforeTemplateCloser && Current.is(TT_TemplateCloser) && State.Stack.size() > 1) { return State.Stack[State.Stack.size() - 2].LastSpace; diff --git a/clang/unittests/Format/FormatTest.cpp b/clang/unittests/Format/FormatTest.cpp index 74d62b5722694..39bcdcad85116 100644 --- a/clang/unittests/Format/FormatTest.cpp +++ b/clang/unittests/Format/FormatTest.cpp @@ -9754,6 +9754,9 @@ TEST_F(FormatTest, AlignAndBreakControlStatements) { Style.BreakAfterOpenBracketIf = true; Style.BreakAfterOpenBracketLoop = true; Style.BreakAfterOpenBracketSwitch = true; + Style.BreakBeforeCloseBracketIf = false; + Style.BreakBeforeCloseBracketLoop = false; + Style.BreakBeforeCloseBracketSwitch = false; verifyFormat("void foo() {\n" " if constexpr (\n" >From 4df294c3a221fa4306ad7e8987926865b150a597 Mon Sep 17 00:00:00 2001 From: Gedare Bloom <ged...@rtems.org> Date: Wed, 21 May 2025 20:59:31 -0600 Subject: [PATCH 8/8] dump format style --- clang/docs/ClangFormatStyleOptions.rst | 39 ++++++++++++++------------ 1 file changed, 21 insertions(+), 18 deletions(-) diff --git a/clang/docs/ClangFormatStyleOptions.rst b/clang/docs/ClangFormatStyleOptions.rst index a6ca560d00db0..c7dc01880d6bb 100644 --- a/clang/docs/ClangFormatStyleOptions.rst +++ b/clang/docs/ClangFormatStyleOptions.rst @@ -2746,8 +2746,7 @@ the configuration (without a prefix: ``Auto``). true: false: if constexpr ( vs. if constexpr (a || - a || b) - b) + a || b) b) .. _BreakAfterOpenBracketLoop: @@ -2759,8 +2758,7 @@ the configuration (without a prefix: ``Auto``). true: false: while ( vs. while (a && - a && b) { - b) { + a && b) { b) { .. _BreakAfterOpenBracketSwitch: @@ -2772,8 +2770,7 @@ the configuration (without a prefix: ``Auto``). true: false: switch ( vs. switch (a && - a && b) { - b) { + a && b) { b) { .. _BreakAfterReturnType: @@ -3416,40 +3413,46 @@ the configuration (without a prefix: ``Auto``). **BreakBeforeCloseBracketIf** (``Boolean``) :versionbadge:`clang-format 21` :ref:`¶ <BreakBeforeCloseBracketIf>` Force break before the right parenthesis of an if control statement - when the expression exceeds the column limit. + when the expression exceeds the column limit. The break before the + closing parenthesis is only made if there is a break after the opening + parenthesis. .. code-block:: c++ true: false: - if constexpr (a || vs. if constexpr (a || - b b) - ) + if constexpr ( vs. if constexpr (a || + a || b b) + ) .. _BreakBeforeCloseBracketLoop: **BreakBeforeCloseBracketLoop** (``Boolean``) :versionbadge:`clang-format 21` :ref:`¶ <BreakBeforeCloseBracketLoop>` Force break before the right parenthesis of a loop control statement - when the expression exceeds the column limit. + when the expression exceeds the column limit. The break before the + closing parenthesis is only made if there is a break after the opening + parenthesis. .. code-block:: c++ true: false: - while (a && vs. while (a && - b b) { - ) { + while ( vs. while (a && + a && b b) { + ) { .. _BreakBeforeCloseBracketSwitch: **BreakBeforeCloseBracketSwitch** (``Boolean``) :versionbadge:`clang-format 21` :ref:`¶ <BreakBeforeCloseBracketSwitch>` Force break before the right parenthesis of a switch control statement - when the expression exceeds the column limit. + when the expression exceeds the column limit. The break before the + closing parenthesis is only made if there is a break after the opening + parenthesis. .. code-block:: c++ true: false: - switch (a && vs. switch (a && - b b) { - ) { + switch ( vs. switch (a && + a && b b) { + ) { .. _BreakBeforeConceptDeclarations: _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits