csmulhern updated this revision to Diff 387025.
Repository:
rG LLVM Github Monorepo
CHANGES SINCE LAST ACTION
https://reviews.llvm.org/D109557/new/
https://reviews.llvm.org/D109557
Files:
clang/docs/ClangFormatStyleOptions.rst
clang/docs/ReleaseNotes.rst
clang/include/clang/Format/Format.h
clang/lib/Format/ContinuationIndenter.cpp
clang/lib/Format/ContinuationIndenter.h
clang/lib/Format/Format.cpp
clang/lib/Format/TokenAnnotator.cpp
clang/unittests/Format/FormatTest.cpp
Index: clang/unittests/Format/FormatTest.cpp
===================================================================
--- clang/unittests/Format/FormatTest.cpp
+++ clang/unittests/Format/FormatTest.cpp
@@ -18706,6 +18706,8 @@
FormatStyle::BAS_DontAlign);
CHECK_PARSE("AlignAfterOpenBracket: AlwaysBreak", AlignAfterOpenBracket,
FormatStyle::BAS_AlwaysBreak);
+ CHECK_PARSE("AlignAfterOpenBracket: BlockIndent", AlignAfterOpenBracket,
+ FormatStyle::BAS_BlockIndent);
// For backward compatibility:
CHECK_PARSE("AlignAfterOpenBracket: false", AlignAfterOpenBracket,
FormatStyle::BAS_DontAlign);
@@ -22566,6 +22568,224 @@
EXPECT_EQ(Code, format(Code, Style));
}
+TEST_F(FormatTest, AlignAfterOpenBracketBlockIndent) {
+ auto Style = getLLVMStyle();
+
+ StringRef Short = "functionCall(paramA, paramB, paramC);\n"
+ "void functionDecl(int a, int b, int c);";
+
+ StringRef Medium = "functionCall(paramA, paramB, paramC, paramD, paramE, "
+ "paramF, paramG, paramH, paramI);\n"
+ "void functionDecl(int argumentA, int argumentB, int "
+ "argumentC, int argumentD, int argumentE);";
+
+ verifyFormat(Short, Style);
+
+ StringRef NoBreak = "functionCall(paramA, paramB, paramC, paramD, paramE, "
+ "paramF, paramG, paramH,\n"
+ " paramI);\n"
+ "void functionDecl(int argumentA, int argumentB, int "
+ "argumentC, int argumentD,\n"
+ " int argumentE);";
+
+ verifyFormat(NoBreak, Medium, Style);
+ verifyFormat(NoBreak,
+ "functionCall(\n"
+ " paramA,\n"
+ " paramB,\n"
+ " paramC,\n"
+ " paramD,\n"
+ " paramE,\n"
+ " paramF,\n"
+ " paramG,\n"
+ " paramH,\n"
+ " paramI\n"
+ ");\n"
+ "void functionDecl(\n"
+ " int argumentA,\n"
+ " int argumentB,\n"
+ " int argumentC,\n"
+ " int argumentD,\n"
+ " int argumentE\n"
+ ");",
+ Style);
+
+ verifyFormat("outerFunctionCall(nestedFunctionCall(argument1),\n"
+ " nestedLongFunctionCall(argument1, "
+ "argument2, argument3,\n"
+ " argument4, "
+ "argument5));",
+ Style);
+
+ Style.AlignAfterOpenBracket = FormatStyle::BAS_BlockIndent;
+
+ verifyFormat(Short, Style);
+ verifyFormat(
+ "functionCall(\n"
+ " paramA, paramB, paramC, paramD, paramE, paramF, paramG, paramH, "
+ "paramI\n"
+ ");\n"
+ "void functionDecl(\n"
+ " int argumentA, int argumentB, int argumentC, int argumentD, int "
+ "argumentE\n"
+ ");",
+ Medium, Style);
+
+ Style.AllowAllArgumentsOnNextLine = false;
+ Style.AllowAllParametersOfDeclarationOnNextLine = false;
+
+ verifyFormat(Short, Style);
+ verifyFormat(
+ "functionCall(\n"
+ " paramA, paramB, paramC, paramD, paramE, paramF, paramG, paramH, "
+ "paramI\n"
+ ");\n"
+ "void functionDecl(\n"
+ " int argumentA, int argumentB, int argumentC, int argumentD, int "
+ "argumentE\n"
+ ");",
+ Medium, Style);
+
+ Style.BinPackArguments = false;
+ Style.BinPackParameters = false;
+
+ verifyFormat(Short, Style);
+
+ verifyFormat("functionCall(\n"
+ " paramA,\n"
+ " paramB,\n"
+ " paramC,\n"
+ " paramD,\n"
+ " paramE,\n"
+ " paramF,\n"
+ " paramG,\n"
+ " paramH,\n"
+ " paramI\n"
+ ");\n"
+ "void functionDecl(\n"
+ " int argumentA,\n"
+ " int argumentB,\n"
+ " int argumentC,\n"
+ " int argumentD,\n"
+ " int argumentE\n"
+ ");",
+ Medium, Style);
+
+ verifyFormat("outerFunctionCall(\n"
+ " nestedFunctionCall(argument1),\n"
+ " nestedLongFunctionCall(\n"
+ " argument1,\n"
+ " argument2,\n"
+ " argument3,\n"
+ " argument4,\n"
+ " argument5\n"
+ " )\n"
+ ");",
+ Style);
+
+ verifyFormat("int a = (int)b;", Style);
+ verifyFormat("int a = (int)b;",
+ "int a = (\n"
+ " int\n"
+ ") b;",
+ Style);
+
+ verifyFormat("return (true);", Style);
+ verifyFormat("return (true);",
+ "return (\n"
+ " true\n"
+ ");",
+ Style);
+
+ verifyFormat("void foo();", Style);
+ verifyFormat("void foo();",
+ "void foo(\n"
+ ");",
+ Style);
+
+ verifyFormat("void foo() {}", Style);
+ verifyFormat("void foo() {}",
+ "void foo(\n"
+ ") {\n"
+ "}",
+ Style);
+
+ verifyFormat("auto string = std::string();", Style);
+ verifyFormat("auto string = std::string();",
+ "auto string = std::string(\n"
+ ");",
+ Style);
+
+ verifyFormat("void (*functionPointer)() = nullptr;", Style);
+ verifyFormat("void (*functionPointer)() = nullptr;",
+ "void (\n"
+ " *functionPointer\n"
+ ")\n"
+ "(\n"
+ ") = nullptr;",
+ Style);
+}
+
+TEST_F(FormatTest, AlignAfterOpenBracketBlockIndentIfStatement) {
+ auto Style = getLLVMStyle();
+
+ verifyFormat("if (foo()) {\n"
+ " return;\n"
+ "}",
+ Style);
+
+ verifyFormat("if (quitelongarg !=\n"
+ " (alsolongarg - 1)) { // ABC is a very longgggggggggggg "
+ "comment\n"
+ " return;\n"
+ "}",
+ Style);
+
+ Style.AlignAfterOpenBracket = FormatStyle::BAS_BlockIndent;
+
+ verifyFormat("if (foo()) {\n"
+ " return;\n"
+ "}",
+ Style);
+
+ verifyFormat("if (quitelongarg !=\n"
+ " (alsolongarg - 1)) { // ABC is a very longgggggggggggg "
+ "comment\n"
+ " return;\n"
+ "}",
+ Style);
+}
+
+TEST_F(FormatTest, AlignAfterOpenBracketBlockIndentForStatement) {
+ auto Style = getLLVMStyle();
+
+ verifyFormat("for (int i = 0; i < 5; ++i) {\n"
+ " doSomething();\n"
+ "}",
+ Style);
+
+ verifyFormat("for (int myReallyLongCountVariable = 0; "
+ "myReallyLongCountVariable < count;\n"
+ " myReallyLongCountVariable++) {\n"
+ " doSomething();\n"
+ "}",
+ Style);
+
+ Style.AlignAfterOpenBracket = FormatStyle::BAS_BlockIndent;
+
+ verifyFormat("for (int i = 0; i < 5; ++i) {\n"
+ " doSomething();\n"
+ "}",
+ Style);
+
+ verifyFormat("for (int myReallyLongCountVariable = 0; "
+ "myReallyLongCountVariable < count;\n"
+ " myReallyLongCountVariable++) {\n"
+ " doSomething();\n"
+ "}",
+ Style);
+}
+
} // namespace
} // namespace format
} // namespace clang
Index: clang/lib/Format/TokenAnnotator.cpp
===================================================================
--- clang/lib/Format/TokenAnnotator.cpp
+++ clang/lib/Format/TokenAnnotator.cpp
@@ -4213,7 +4213,7 @@
if (Right.is(TT_ImplicitStringLiteral))
return false;
- if (Right.is(tok::r_paren) || Right.is(TT_TemplateCloser))
+ if (Right.is(TT_TemplateCloser))
return false;
if (Right.is(tok::r_square) && Right.MatchingParen &&
Right.MatchingParen->is(TT_LambdaLSquare))
@@ -4224,6 +4224,18 @@
if (Right.is(tok::r_brace))
return Right.MatchingParen && Right.MatchingParen->is(BK_Block);
+ // 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) {
+ return Right.MatchingParen &&
+ !(Right.MatchingParen->Previous &&
+ (Right.MatchingParen->Previous->is(tok::kw_for) ||
+ Right.MatchingParen->Previous->isIf()));
+ }
+
+ return false;
+ }
+
// Allow breaking after a trailing annotation, e.g. after a method
// declaration.
if (Left.is(TT_TrailingAnnotation))
Index: clang/lib/Format/Format.cpp
===================================================================
--- clang/lib/Format/Format.cpp
+++ clang/lib/Format/Format.cpp
@@ -383,6 +383,7 @@
IO.enumCase(Value, "Align", FormatStyle::BAS_Align);
IO.enumCase(Value, "DontAlign", FormatStyle::BAS_DontAlign);
IO.enumCase(Value, "AlwaysBreak", FormatStyle::BAS_AlwaysBreak);
+ IO.enumCase(Value, "BlockIndent", FormatStyle::BAS_BlockIndent);
// For backward compatibility.
IO.enumCase(Value, "true", FormatStyle::BAS_Align);
Index: clang/lib/Format/ContinuationIndenter.h
===================================================================
--- clang/lib/Format/ContinuationIndenter.h
+++ clang/lib/Format/ContinuationIndenter.h
@@ -203,15 +203,15 @@
bool AvoidBinPacking, bool NoLineBreak)
: Tok(Tok), Indent(Indent), LastSpace(LastSpace),
NestedBlockIndent(Indent), IsAligned(false),
- BreakBeforeClosingBrace(false), AvoidBinPacking(AvoidBinPacking),
- BreakBeforeParameter(false), NoLineBreak(NoLineBreak),
- NoLineBreakInOperand(false), LastOperatorWrapped(true),
- ContainsLineBreak(false), ContainsUnwrappedBuilder(false),
- AlignColons(true), ObjCSelectorNameFound(false),
- HasMultipleNestedBlocks(false), NestedBlockInlined(false),
- IsInsideObjCArrayLiteral(false), IsCSharpGenericTypeConstraint(false),
- IsChainedConditional(false), IsWrappedConditional(false),
- UnindentOperator(false) {}
+ BreakBeforeClosingBrace(false), BreakBeforeClosingParen(false),
+ AvoidBinPacking(AvoidBinPacking), BreakBeforeParameter(false),
+ NoLineBreak(NoLineBreak), NoLineBreakInOperand(false),
+ LastOperatorWrapped(true), ContainsLineBreak(false),
+ ContainsUnwrappedBuilder(false), AlignColons(true),
+ ObjCSelectorNameFound(false), HasMultipleNestedBlocks(false),
+ NestedBlockInlined(false), IsInsideObjCArrayLiteral(false),
+ IsCSharpGenericTypeConstraint(false), IsChainedConditional(false),
+ IsWrappedConditional(false), UnindentOperator(false) {}
/// \brief The token opening this parenthesis level, or nullptr if this level
/// is opened by fake parenthesis.
@@ -277,6 +277,13 @@
/// was a newline after the beginning left brace.
bool BreakBeforeClosingBrace : 1;
+ /// Whether a newline needs to be inserted before the block's closing
+ /// paren.
+ ///
+ /// We only want to insert a newline before the closing paren if there also
+ /// was a newline after the beginning left paren.
+ bool BreakBeforeClosingParen : 1;
+
/// Avoid bin packing, i.e. multiple parameters/elements on multiple
/// lines, in this context.
bool AvoidBinPacking : 1;
@@ -362,6 +369,8 @@
return IsAligned;
if (BreakBeforeClosingBrace != Other.BreakBeforeClosingBrace)
return BreakBeforeClosingBrace;
+ if (BreakBeforeClosingParen != Other.BreakBeforeClosingParen)
+ return BreakBeforeClosingParen;
if (QuestionColumn != Other.QuestionColumn)
return QuestionColumn < Other.QuestionColumn;
if (AvoidBinPacking != Other.AvoidBinPacking)
Index: clang/lib/Format/ContinuationIndenter.cpp
===================================================================
--- clang/lib/Format/ContinuationIndenter.cpp
+++ clang/lib/Format/ContinuationIndenter.cpp
@@ -341,6 +341,8 @@
if (State.Stack.back().BreakBeforeClosingBrace &&
Current.closesBlockOrBlockTypeList(Style))
return true;
+ if (State.Stack.back().BreakBeforeClosingParen && Current.is(tok::r_paren))
+ return true;
if (Previous.is(tok::semi) && State.LineContainsContinuedForLoopSection)
return true;
if (Style.Language == FormatStyle::LK_ObjC &&
@@ -639,10 +641,12 @@
State.Stack.back().ColonPos = FirstColonPos;
}
- // In "AlwaysBreak" mode, enforce wrapping directly after the 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.
- if (Style.AlignAfterOpenBracket == FormatStyle::BAS_AlwaysBreak &&
+ // In "AlwaysBreak" or "BlockIndent" mode, enforce wrapping directly after the
+ // 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.
+ 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)) &&
@@ -944,6 +948,10 @@
opensProtoMessageField(*PreviousNonComment, Style)))
State.Stack.back().BreakBeforeClosingBrace = true;
+ if (PreviousNonComment && PreviousNonComment->is(tok::l_paren))
+ State.Stack.back().BreakBeforeClosingParen =
+ Style.AlignAfterOpenBracket == FormatStyle::BAS_BlockIndent;
+
if (State.Stack.back().AvoidBinPacking) {
// If we are breaking after '(', '{', '<', or this is the break after a ':'
// to start a member initializater list in a constructor, this should not
@@ -1038,6 +1046,9 @@
(!Current.Next ||
Current.Next->isOneOf(tok::semi, tok::kw_const, tok::l_brace)))
return State.Stack[State.Stack.size() - 2].LastSpace;
+ if (Style.AlignAfterOpenBracket == FormatStyle::BAS_BlockIndent &&
+ Current.is(tok::r_paren) && State.Stack.size() > 1)
+ return State.Stack[State.Stack.size() - 2].LastSpace;
if (NextNonComment->is(TT_TemplateString) && NextNonComment->closesScope())
return State.Stack[State.Stack.size() - 2].LastSpace;
if (Current.is(tok::identifier) && Current.Next &&
Index: clang/include/clang/Format/Format.h
===================================================================
--- clang/include/clang/Format/Format.h
+++ clang/include/clang/Format/Format.h
@@ -87,6 +87,20 @@
/// argument1, argument2);
/// \endcode
BAS_AlwaysBreak,
+ /// Always break after an open bracket, if the parameters don't fit
+ /// on a single line. Closing brackets will be placed on a new line.
+ /// E.g.:
+ /// \code
+ /// true:
+ /// someLongFunction(
+ /// argument1, argument2
+ /// )
+ /// \endcode
+ ///
+ /// \warning
+ /// Note: This currently only applies to parentheses.
+ /// \endwarning
+ BAS_BlockIndent,
};
/// If ``true``, horizontally aligns arguments after an open bracket.
Index: clang/docs/ReleaseNotes.rst
===================================================================
--- clang/docs/ReleaseNotes.rst
+++ clang/docs/ReleaseNotes.rst
@@ -244,6 +244,10 @@
- Option ``AllowShortEnumsOnASingleLine: false`` has been improved, it now
correctly places the opening brace according to ``BraceWrapping.AfterEnum``.
+- Option ``AlignAfterOpenBracket: BlockIndent`` has been added. If set, it will
+ always break after an open bracket, if the parameters don't fit on a single
+ line. Closing brackets will be placed on a new line.
+
- Option ``QualifierAligment`` has been added in order to auto-arrange the
positioning of specifiers/qualifiers
`const` `volatile` `static` `inline` `constexpr` `restrict`
Index: clang/docs/ClangFormatStyleOptions.rst
===================================================================
--- clang/docs/ClangFormatStyleOptions.rst
+++ clang/docs/ClangFormatStyleOptions.rst
@@ -210,6 +210,18 @@
someLongFunction(
argument1, argument2);
+ * ``BAS_BlockIndent`` (in configuration: ``BlockIndent``)
+ Always break after an open bracket, if the parameters don't fit
+ on a single line. Closing brackets will be placed on a new line.
+ Note: This currently only applies to parentheses.
+ E.g.:
+
+ .. code-block:: c++
+
+ someLongFunction(
+ argument1, argument2
+ );
+
**AlignArrayOfStructures** (``ArrayInitializerAlignmentStyle``) :versionbadge:`clang-format 13`
_______________________________________________
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits