[llvm-branch-commits] [clang] release/21.x: [clang-format] Fix a bug in wrapping { after else (#161048) (PR #162958)
via llvm-branch-commits
llvm-branch-commits at lists.llvm.org
Fri Oct 10 19:06:53 PDT 2025
https://github.com/llvmbot created https://github.com/llvm/llvm-project/pull/162958
Backport c62a5bf52de2953cbfb73e1df64092f37d3fc192 56d920d5868596f48a3a779dc88825594a646af3
Requested by: @owenca
>From e81eac0359cc907c2843572a840e72ca869fb8dd Mon Sep 17 00:00:00 2001
From: owenca <owenpiano at gmail.com>
Date: Thu, 28 Aug 2025 07:40:42 -0700
Subject: [PATCH 1/2] [clang-format] Correctly annotate
RequiresExpressionLBrace (#155773)
Fixes #155746
(cherry picked from commit c62a5bf52de2953cbfb73e1df64092f37d3fc192)
---
clang/lib/Format/TokenAnnotator.cpp | 2 +-
clang/unittests/Format/TokenAnnotatorTest.cpp | 8 ++++++++
2 files changed, 9 insertions(+), 1 deletion(-)
diff --git a/clang/lib/Format/TokenAnnotator.cpp b/clang/lib/Format/TokenAnnotator.cpp
index 580996e870f54..3ab3c45bbb052 100644
--- a/clang/lib/Format/TokenAnnotator.cpp
+++ b/clang/lib/Format/TokenAnnotator.cpp
@@ -4007,7 +4007,7 @@ void TokenAnnotator::calculateFormattingInformation(AnnotatedLine &Line) const {
auto *Tok = Line.Last->Previous;
while (Tok->isNot(tok::r_brace))
Tok = Tok->Previous;
- if (auto *LBrace = Tok->MatchingParen; LBrace) {
+ if (auto *LBrace = Tok->MatchingParen; LBrace && LBrace->is(TT_Unknown)) {
assert(LBrace->is(tok::l_brace));
Tok->setBlockKind(BK_Block);
LBrace->setBlockKind(BK_Block);
diff --git a/clang/unittests/Format/TokenAnnotatorTest.cpp b/clang/unittests/Format/TokenAnnotatorTest.cpp
index 259d7e54133a1..5ef7f5ba25a12 100644
--- a/clang/unittests/Format/TokenAnnotatorTest.cpp
+++ b/clang/unittests/Format/TokenAnnotatorTest.cpp
@@ -1349,6 +1349,14 @@ TEST_F(TokenAnnotatorTest, UnderstandsRequiresClausesAndConcepts) {
EXPECT_EQ(Tokens[21]->MatchingParen, Tokens[15]);
EXPECT_TRUE(Tokens[21]->ClosesRequiresClause);
+ Tokens = annotate("template <typename Foo>\n"
+ "void Fun(const Foo &F)\n"
+ " requires requires(Foo F) {\n"
+ " { F.Bar() } -> std::same_as<int>;\n"
+ " };");
+ ASSERT_EQ(Tokens.size(), 38u) << Tokens;
+ EXPECT_TOKEN(Tokens[19], tok::l_brace, TT_RequiresExpressionLBrace);
+
Tokens =
annotate("template <class A, class B> concept C ="
"std::same_as<std::iter_value_t<A>, std::iter_value_t<B>>;");
>From 24effb16dc3e7f0a312d832880ff61598d4c566e Mon Sep 17 00:00:00 2001
From: owenca <owenpiano at gmail.com>
Date: Mon, 29 Sep 2025 21:11:20 -0700
Subject: [PATCH 2/2] [clang-format] Fix a bug in wrapping { after else
(#161048)
Fixes #160775
(cherry picked from commit 56d920d5868596f48a3a779dc88825594a646af3)
---
clang/lib/Format/FormatToken.h | 2 +-
clang/lib/Format/TokenAnnotator.cpp | 44 +++++++++++++++------------
clang/unittests/Format/FormatTest.cpp | 21 +++++++++++++
3 files changed, 46 insertions(+), 21 deletions(-)
diff --git a/clang/lib/Format/FormatToken.h b/clang/lib/Format/FormatToken.h
index 9252a795a0b5e..c2000a971c898 100644
--- a/clang/lib/Format/FormatToken.h
+++ b/clang/lib/Format/FormatToken.h
@@ -55,7 +55,7 @@ namespace format {
TYPE(ConflictAlternative) \
TYPE(ConflictEnd) \
TYPE(ConflictStart) \
- /* l_brace of if/for/while */ \
+ /* l_brace of if/for/while/switch/catch */ \
TYPE(ControlStatementLBrace) \
TYPE(ControlStatementRBrace) \
TYPE(CppCastLParen) \
diff --git a/clang/lib/Format/TokenAnnotator.cpp b/clang/lib/Format/TokenAnnotator.cpp
index 3ab3c45bbb052..ed8aa514aaf31 100644
--- a/clang/lib/Format/TokenAnnotator.cpp
+++ b/clang/lib/Format/TokenAnnotator.cpp
@@ -4000,29 +4000,28 @@ void TokenAnnotator::calculateFormattingInformation(AnnotatedLine &Line) const {
}
}
- if (IsCpp &&
- (LineIsFunctionDeclaration ||
- (FirstNonComment && FirstNonComment->is(TT_CtorDtorDeclName))) &&
- Line.endsWith(tok::semi, tok::r_brace)) {
- auto *Tok = Line.Last->Previous;
- while (Tok->isNot(tok::r_brace))
- Tok = Tok->Previous;
- if (auto *LBrace = Tok->MatchingParen; LBrace && LBrace->is(TT_Unknown)) {
- assert(LBrace->is(tok::l_brace));
- Tok->setBlockKind(BK_Block);
- LBrace->setBlockKind(BK_Block);
- LBrace->setFinalizedType(TT_FunctionLBrace);
+ if (IsCpp) {
+ if ((LineIsFunctionDeclaration ||
+ (FirstNonComment && FirstNonComment->is(TT_CtorDtorDeclName))) &&
+ Line.endsWith(tok::semi, tok::r_brace)) {
+ auto *Tok = Line.Last->Previous;
+ while (Tok->isNot(tok::r_brace))
+ Tok = Tok->Previous;
+ if (auto *LBrace = Tok->MatchingParen; LBrace && LBrace->is(TT_Unknown)) {
+ assert(LBrace->is(tok::l_brace));
+ Tok->setBlockKind(BK_Block);
+ LBrace->setBlockKind(BK_Block);
+ LBrace->setFinalizedType(TT_FunctionLBrace);
+ }
}
- }
- if (IsCpp && SeenName && AfterLastAttribute &&
- mustBreakAfterAttributes(*AfterLastAttribute, Style)) {
- AfterLastAttribute->MustBreakBefore = true;
- if (LineIsFunctionDeclaration)
- Line.ReturnTypeWrapped = true;
- }
+ if (SeenName && AfterLastAttribute &&
+ mustBreakAfterAttributes(*AfterLastAttribute, Style)) {
+ AfterLastAttribute->MustBreakBefore = true;
+ if (LineIsFunctionDeclaration)
+ Line.ReturnTypeWrapped = true;
+ }
- if (IsCpp) {
if (!LineIsFunctionDeclaration) {
// Annotate */&/&& in `operator` function calls as binary operators.
for (const auto *Tok = FirstNonComment; Tok; Tok = Tok->Next) {
@@ -4068,6 +4067,11 @@ void TokenAnnotator::calculateFormattingInformation(AnnotatedLine &Line) const {
}
}
+ if (First->is(TT_ElseLBrace)) {
+ First->CanBreakBefore = true;
+ First->MustBreakBefore = true;
+ }
+
bool InFunctionDecl = Line.MightBeFunctionDecl;
bool InParameterList = false;
for (auto *Current = First->Next; Current; Current = Current->Next) {
diff --git a/clang/unittests/Format/FormatTest.cpp b/clang/unittests/Format/FormatTest.cpp
index 95682f2d8cfd4..bece239319912 100644
--- a/clang/unittests/Format/FormatTest.cpp
+++ b/clang/unittests/Format/FormatTest.cpp
@@ -1364,6 +1364,27 @@ TEST_F(FormatTest, FormatIfWithoutCompoundStatementButElseWith) {
AllowsMergedIf);
}
+TEST_F(FormatTest, WrapMultipleStatementIfAndElseBraces) {
+ auto Style = getLLVMStyle();
+ Style.AllowShortBlocksOnASingleLine = FormatStyle::SBS_Always;
+ Style.AllowShortIfStatementsOnASingleLine = FormatStyle::SIS_AllIfsAndElse;
+ Style.BreakBeforeBraces = FormatStyle::BS_Custom;
+ Style.BraceWrapping.AfterControlStatement = FormatStyle::BWACS_Always;
+ Style.BraceWrapping.BeforeElse = true;
+
+ verifyFormat("if (x)\n"
+ "{\n"
+ " ++x;\n"
+ " --y;\n"
+ "}\n"
+ "else\n"
+ "{\n"
+ " --x;\n"
+ " ++y;\n"
+ "}",
+ Style);
+}
+
TEST_F(FormatTest, FormatLoopsWithoutCompoundStatement) {
verifyFormat("while (true)\n"
" ;");
More information about the llvm-branch-commits
mailing list