[clang] [clang-format] Add AlignAfterOpenBracketOptions (PR #108332)
Gedare Bloom via cfe-commits
cfe-commits at lists.llvm.org
Thu May 22 07:08:30 PDT 2025
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 <gedare at rtems.org>
Date: Thu, 20 Jun 2024 17:35:39 -0600
Subject: [PATCH 01/11] 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 <gedare at rtems.org>
Date: Wed, 11 Sep 2024 22:48:12 -0600
Subject: [PATCH 02/11] 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 <gedare at rtems.org>
Date: Wed, 21 May 2025 16:11:23 -0600
Subject: [PATCH 03/11] 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 <gedare at rtems.org>
Date: Wed, 21 May 2025 16:44:48 -0600
Subject: [PATCH 04/11] 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 <gedare at rtems.org>
Date: Wed, 21 May 2025 17:39:58 -0600
Subject: [PATCH 05/11] 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 <gedare at rtems.org>
Date: Wed, 21 May 2025 17:47:09 -0600
Subject: [PATCH 06/11] 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 <gedare at rtems.org>
Date: Wed, 21 May 2025 20:59:10 -0600
Subject: [PATCH 07/11] 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 <gedare at rtems.org>
Date: Wed, 21 May 2025 20:59:31 -0600
Subject: [PATCH 08/11] 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:
>From 028557f1382cea53c97f29334f2e664c853739bd Mon Sep 17 00:00:00 2001
From: Gedare Bloom <gedare at rtems.org>
Date: Thu, 22 May 2025 07:57:03 -0600
Subject: [PATCH 09/11] fix format
---
clang/include/clang/Format/Format.h | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/clang/include/clang/Format/Format.h b/clang/include/clang/Format/Format.h
index 7dd6ba26da532..3201cf6fa1afd 100644
--- a/clang/include/clang/Format/Format.h
+++ b/clang/include/clang/Format/Format.h
@@ -2253,7 +2253,7 @@ struct FormatStyle {
/// true: false:
/// if constexpr ( vs. if constexpr (a ||
/// a || b b)
- /// )
+ /// )
/// \endcode
/// \version 21
bool BreakBeforeCloseBracketIf;
@@ -2266,7 +2266,7 @@ struct FormatStyle {
/// true: false:
/// while ( vs. while (a &&
/// a && b b) {
- /// ) {
+ /// ) {
/// \endcode
/// \version 21
bool BreakBeforeCloseBracketLoop;
@@ -2279,7 +2279,7 @@ struct FormatStyle {
/// true: false:
/// switch ( vs. switch (a &&
/// a && b b) {
- /// ) {
+ /// ) {
/// \endcode
/// \version 21
bool BreakBeforeCloseBracketSwitch;
>From d5a484f9394b25f7ea6cf54913126ef5785b0b59 Mon Sep 17 00:00:00 2001
From: Gedare Bloom <gedare at rtems.org>
Date: Thu, 22 May 2025 08:07:59 -0600
Subject: [PATCH 10/11] Fix false case examples
---
clang/include/clang/Format/Format.h | 12 ++++++------
1 file changed, 6 insertions(+), 6 deletions(-)
diff --git a/clang/include/clang/Format/Format.h b/clang/include/clang/Format/Format.h
index 3201cf6fa1afd..38b15d1e54c45 100644
--- a/clang/include/clang/Format/Format.h
+++ b/clang/include/clang/Format/Format.h
@@ -2251,8 +2251,8 @@ struct FormatStyle {
/// parenthesis.
/// \code
/// true: false:
- /// if constexpr ( vs. if constexpr (a ||
- /// a || b b)
+ /// if constexpr ( vs. if constexpr (
+ /// a || b a || b )
/// )
/// \endcode
/// \version 21
@@ -2264,8 +2264,8 @@ struct FormatStyle {
/// parenthesis.
/// \code
/// true: false:
- /// while ( vs. while (a &&
- /// a && b b) {
+ /// while ( vs. while (
+ /// a && b a && b) {
/// ) {
/// \endcode
/// \version 21
@@ -2277,8 +2277,8 @@ struct FormatStyle {
/// parenthesis.
/// \code
/// true: false:
- /// switch ( vs. switch (a &&
- /// a && b b) {
+ /// switch ( vs. switch (
+ /// a && b a && b) {
/// ) {
/// \endcode
/// \version 21
>From 34ac03b9edcc1f360bec9b5478f29a07b93654a1 Mon Sep 17 00:00:00 2001
From: Gedare Bloom <gedare at rtems.org>
Date: Thu, 22 May 2025 08:08:12 -0600
Subject: [PATCH 11/11] dump style
---
clang/docs/ClangFormatStyleOptions.rst | 12 ++++++------
1 file changed, 6 insertions(+), 6 deletions(-)
diff --git a/clang/docs/ClangFormatStyleOptions.rst b/clang/docs/ClangFormatStyleOptions.rst
index c7dc01880d6bb..a8a2c1453f649 100644
--- a/clang/docs/ClangFormatStyleOptions.rst
+++ b/clang/docs/ClangFormatStyleOptions.rst
@@ -3420,8 +3420,8 @@ the configuration (without a prefix: ``Auto``).
.. code-block:: c++
true: false:
- if constexpr ( vs. if constexpr (a ||
- a || b b)
+ if constexpr ( vs. if constexpr (
+ a || b a || b )
)
.. _BreakBeforeCloseBracketLoop:
@@ -3435,8 +3435,8 @@ the configuration (without a prefix: ``Auto``).
.. code-block:: c++
true: false:
- while ( vs. while (a &&
- a && b b) {
+ while ( vs. while (
+ a && b a && b) {
) {
.. _BreakBeforeCloseBracketSwitch:
@@ -3450,8 +3450,8 @@ the configuration (without a prefix: ``Auto``).
.. code-block:: c++
true: false:
- switch ( vs. switch (a &&
- a && b b) {
+ switch ( vs. switch (
+ a && b a && b) {
) {
.. _BreakBeforeConceptDeclarations:
More information about the cfe-commits
mailing list