[clang] [clang-format]: Fix formatting of if statements with BlockIndent (PR #77699)
Gedare Bloom via cfe-commits
cfe-commits at lists.llvm.org
Thu Jan 11 12:36:20 PST 2024
https://github.com/gedare updated https://github.com/llvm/llvm-project/pull/77699
>From ff055d9c064d1fb359d59eeb47cb5f8c6c422bec Mon Sep 17 00:00:00 2001
From: Gedare Bloom <gedare at rtems.org>
Date: Fri, 7 Jul 2023 17:28:47 -0600
Subject: [PATCH 1/4] Fix formatting of if statements with BlockIndent
A bug with BlockIndent prevents line breaks within if (and else if) clauses.
While fixing this bug, it appears that AlignAfterOpenBracket is not designed
to work with loop and if statements, but AlwaysBreak works on if clauses.
The documentation and tests are not clear on whether or not this is intended.
This patch preserves the AlwaysBreak behavior and supports BlockIndent on if
clauses while fixing the bug.
It may be reasonable to go the other way and create an explicit option for
alignment of if (and loop) clauses intentionally.
Fixes #54663.
Differential Revision: https://reviews.llvm.org/D154755
---
clang/lib/Format/ContinuationIndenter.cpp | 6 ++--
clang/unittests/Format/FormatTest.cpp | 40 ++++++++++++++++++++---
2 files changed, 40 insertions(+), 6 deletions(-)
diff --git a/clang/lib/Format/ContinuationIndenter.cpp b/clang/lib/Format/ContinuationIndenter.cpp
index 102504182c4505..8b288c62473db9 100644
--- a/clang/lib/Format/ContinuationIndenter.cpp
+++ b/clang/lib/Format/ContinuationIndenter.cpp
@@ -775,8 +775,10 @@ void ContinuationIndenter::addTokenOnCurrentLine(LineState &State, bool DryRun,
Style.Cpp11BracedListStyle)) &&
State.Column > getNewLineColumn(State) &&
(!Previous.Previous ||
- !Previous.Previous->isOneOf(TT_CastRParen, tok::kw_for, tok::kw_while,
- tok::kw_switch)) &&
+ !(Previous.Previous->isOneOf(TT_CastRParen, tok::kw_for, tok::kw_while,
+ tok::kw_switch) ||
+ (Style.AlignAfterOpenBracket == FormatStyle::BAS_BlockIndent &&
+ Previous.Previous->isIf()))) &&
// Don't do this for simple (no expressions) one-argument function calls
// as that feels like needlessly wasting whitespace, e.g.:
//
diff --git a/clang/unittests/Format/FormatTest.cpp b/clang/unittests/Format/FormatTest.cpp
index 25ef5c680af862..8d55e62e2558d3 100644
--- a/clang/unittests/Format/FormatTest.cpp
+++ b/clang/unittests/Format/FormatTest.cpp
@@ -25889,8 +25889,8 @@ TEST_F(FormatTest, AlignAfterOpenBracketBlockIndentIfStatement) {
"}",
Style);
- verifyFormat("if (quitelongarg !=\n"
- " (alsolongarg - 1)) { // ABC is a very longgggggggggggg "
+ verifyFormat("if (quiteLongArg !=\n"
+ " (alsoLongArg - 1)) { // ABC is a very longgggggggggggg "
"comment\n"
" return;\n"
"}",
@@ -25903,12 +25903,44 @@ TEST_F(FormatTest, AlignAfterOpenBracketBlockIndentIfStatement) {
"}",
Style);
- verifyFormat("if (quitelongarg !=\n"
- " (alsolongarg - 1)) { // ABC is a very longgggggggggggg "
+ verifyFormat("if (quiteLongArg !=\n"
+ " (alsoLongArg - 1)) { // ABC is a very longgggggggggggg "
"comment\n"
" return;\n"
"}",
Style);
+
+ verifyFormat("void foo() {\n"
+ " if (camelCaseName < alsoLongName ||\n"
+ " anotherEvenLongerName <=\n"
+ " thisReallyReallyReallyReallyReallyReallyLongerName ||"
+ "\n"
+ " otherName < thisLastName) {\n"
+ " return;\n"
+ " } else if (quiteLongName < alsoLongName ||\n"
+ " anotherEvenLongerName <=\n"
+ " thisReallyReallyReallyReallyReallyReallyLonger"
+ "Name ||\n"
+ " otherName < thisLastName) {\n"
+ " return;\n"
+ " }\n"
+ "}",
+ Style);
+
+ Style.ContinuationIndentWidth = 2;
+ verifyFormat("void foo() {\n"
+ " if (ThisIsRatherALongIfClause && thatIExpectToBeBroken ||\n"
+ " ontoMultipleLines && whenFormattedCorrectly) {\n"
+ " if (false) {\n"
+ " return;\n"
+ " } else if (thisIsRatherALongIfClause && "
+ "thatIExpectToBeBroken ||\n"
+ " ontoMultipleLines && whenFormattedCorrectly) {\n"
+ " return;\n"
+ " }\n"
+ " }\n"
+ "}",
+ Style);
}
TEST_F(FormatTest, AlignAfterOpenBracketBlockIndentForStatement) {
>From 55cfce78dbfc87af455e6bf822b8f0a6a5f9f3d6 Mon Sep 17 00:00:00 2001
From: Gedare Bloom <gedare at rtems.org>
Date: Wed, 10 Jan 2024 14:44:41 -0700
Subject: [PATCH 2/4] Refactor complex conditional logic as a lambda
---
clang/lib/Format/ContinuationIndenter.cpp | 25 +++++++++++++++--------
1 file changed, 16 insertions(+), 9 deletions(-)
diff --git a/clang/lib/Format/ContinuationIndenter.cpp b/clang/lib/Format/ContinuationIndenter.cpp
index 8b288c62473db9..29426c225fec9e 100644
--- a/clang/lib/Format/ContinuationIndenter.cpp
+++ b/clang/lib/Format/ContinuationIndenter.cpp
@@ -768,17 +768,24 @@ 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 isOpeningBracket = [&](const FormatToken &Tok) {
+ auto isStartOfBracedList = [&](const FormatToken &Tok) {
+ return Tok.is(tok::l_brace) && Tok.isNot(BK_Block) &&
+ Style.Cpp11BracedListStyle;
+ };
+ if (Tok.isOneOf(tok::l_paren, TT_TemplateOpener, tok::l_square) ||
+ isStartOfBracedList(Tok)) {
+ 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);
+ }
+ };
if ((Style.AlignAfterOpenBracket == FormatStyle::BAS_AlwaysBreak ||
Style.AlignAfterOpenBracket == FormatStyle::BAS_BlockIndent) &&
- (Previous.isOneOf(tok::l_paren, TT_TemplateOpener, tok::l_square) ||
- (Previous.is(tok::l_brace) && Previous.isNot(BK_Block) &&
- Style.Cpp11BracedListStyle)) &&
- State.Column > getNewLineColumn(State) &&
- (!Previous.Previous ||
- !(Previous.Previous->isOneOf(TT_CastRParen, tok::kw_for, tok::kw_while,
- tok::kw_switch) ||
- (Style.AlignAfterOpenBracket == FormatStyle::BAS_BlockIndent &&
- Previous.Previous->isIf()))) &&
+ 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.:
//
>From a08d90f09861554da844a2e3864a79cc2c4c50c4 Mon Sep 17 00:00:00 2001
From: Gedare Bloom <gedare at rtems.org>
Date: Thu, 11 Jan 2024 07:57:24 -0700
Subject: [PATCH 3/4] add misssing return
---
clang/lib/Format/ContinuationIndenter.cpp | 1 +
1 file changed, 1 insertion(+)
diff --git a/clang/lib/Format/ContinuationIndenter.cpp b/clang/lib/Format/ContinuationIndenter.cpp
index 29426c225fec9e..f6f7689bf37a3e 100644
--- a/clang/lib/Format/ContinuationIndenter.cpp
+++ b/clang/lib/Format/ContinuationIndenter.cpp
@@ -782,6 +782,7 @@ void ContinuationIndenter::addTokenOnCurrentLine(LineState &State, bool DryRun,
return !Tok.Previous->isOneOf(TT_CastRParen, tok::kw_for, tok::kw_while,
tok::kw_switch);
}
+ return false;
};
if ((Style.AlignAfterOpenBracket == FormatStyle::BAS_AlwaysBreak ||
Style.AlignAfterOpenBracket == FormatStyle::BAS_BlockIndent) &&
>From 14f76702e6ad9960e743990f777ba4f0a6771ae4 Mon Sep 17 00:00:00 2001
From: Gedare Bloom <gedare at rtems.org>
Date: Thu, 11 Jan 2024 13:36:07 -0700
Subject: [PATCH 4/4] Fix CamelCase lambda names
---
clang/lib/Format/ContinuationIndenter.cpp | 8 ++++----
1 file changed, 4 insertions(+), 4 deletions(-)
diff --git a/clang/lib/Format/ContinuationIndenter.cpp b/clang/lib/Format/ContinuationIndenter.cpp
index f6f7689bf37a3e..e50093fd9f42b8 100644
--- a/clang/lib/Format/ContinuationIndenter.cpp
+++ b/clang/lib/Format/ContinuationIndenter.cpp
@@ -768,13 +768,13 @@ 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 isOpeningBracket = [&](const FormatToken &Tok) {
- auto isStartOfBracedList = [&](const FormatToken &Tok) {
+ const auto IsOpeningBracket = [&](const FormatToken &Tok) {
+ const auto IsStartOfBracedList = [&]() {
return Tok.is(tok::l_brace) && Tok.isNot(BK_Block) &&
Style.Cpp11BracedListStyle;
};
if (Tok.isOneOf(tok::l_paren, TT_TemplateOpener, tok::l_square) ||
- isStartOfBracedList(Tok)) {
+ IsStartOfBracedList()) {
if (!Tok.Previous)
return true;
if (Tok.Previous->isIf())
@@ -786,7 +786,7 @@ void ContinuationIndenter::addTokenOnCurrentLine(LineState &State, bool DryRun,
};
if ((Style.AlignAfterOpenBracket == FormatStyle::BAS_AlwaysBreak ||
Style.AlignAfterOpenBracket == FormatStyle::BAS_BlockIndent) &&
- isOpeningBracket(Previous) && State.Column > getNewLineColumn(State) &&
+ 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.:
//
More information about the cfe-commits
mailing list