-
Notifications
You must be signed in to change notification settings - Fork 14.8k
release/21.x: [clang-format] Fix a bug in wrapping { after else (#161048) #162958
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
@HazardyKnusperkeks @HazardyKnusperkeks What do you think about merging this PR to the release branch? |
@llvm/pr-subscribers-clang-format Author: None (llvmbot) ChangesRequested by: @owenca Full diff: https://github.com/llvm/llvm-project/pull/162958.diff 4 Files Affected:
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 580996e870f54..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) {
- 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"
" ;");
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>>;");
|
Fixes llvm#155746 (cherry picked from commit c62a5bf)
Fixes llvm#160775 (cherry picked from commit 56d920d)
@owenca (or anyone else). If you would like to add a note about this fix in the release notes (completely optional). Please reply to this comment with a one or two sentence description of the fix. When you are done, please add the release:note label to this PR. |
Backport c62a5bf 56d920d
Requested by: @owenca