llvmbot wrote:
<!--LLVM PR SUMMARY COMMENT--> @llvm/pr-subscribers-clang-format Author: None (Ezlanding1) <details> <summary>Changes</summary> Adds the `BreakParametersAfter` option based on the feature request. Resolves #<!-- -->54220. --- Full diff: https://github.com/llvm/llvm-project/pull/181281.diff 6 Files Affected: - (modified) clang/docs/ClangFormatStyleOptions.rst (+31) - (modified) clang/include/clang/Format/Format.h (+30) - (modified) clang/lib/Format/Format.cpp (+2) - (modified) clang/lib/Format/TokenAnnotator.cpp (+17) - (modified) clang/unittests/Format/ConfigParseTest.cpp (+1) - (modified) clang/unittests/Format/FormatTest.cpp (+89) ``````````diff diff --git a/clang/docs/ClangFormatStyleOptions.rst b/clang/docs/ClangFormatStyleOptions.rst index 5ba117c231ad5..a0673cb8dcbc2 100644 --- a/clang/docs/ClangFormatStyleOptions.rst +++ b/clang/docs/ClangFormatStyleOptions.rst @@ -3752,6 +3752,37 @@ the configuration (without a prefix: ``Auto``). +.. _BreakParametersAfter: + +**BreakParametersAfter** (``Unsigned``) :versionbadge:`clang-format 23` :ref:`¶ <BreakParametersAfter>` + If set to a value greater than 0, any parenthesized parameter or argument + list with more parameters than the specified number will be formatted with + one parameter per line. This applies to all parameter-like lists enclosed + in parentheses, including function declarations, function definitions, + function calls, and comma expressions. + + .. code-block:: c++ + + BreakParametersAfter: 3 + + void foo(int a); + + void bar(int a, int b, int c); + + void baz(int a, + int b, + int c, + int d); + + foo(1); + + bar(1, 2, 3); + + baz(1, + 2, + 3, + 4); + .. _BreakStringLiterals: **BreakStringLiterals** (``Boolean``) :versionbadge:`clang-format 3.9` :ref:`¶ <BreakStringLiterals>` diff --git a/clang/include/clang/Format/Format.h b/clang/include/clang/Format/Format.h index 43bea4b80cb8a..25ad43d588485 100644 --- a/clang/include/clang/Format/Format.h +++ b/clang/include/clang/Format/Format.h @@ -2609,6 +2609,35 @@ struct FormatStyle { /// \version 7 BreakInheritanceListStyle BreakInheritanceList; + /// If set to a value greater than 0, any parenthesized parameter or argument + /// list with more parameters than the specified number will be formatted with + /// one parameter per line. This applies to all parameter-like lists enclosed + /// in parentheses, including function declarations, function definitions, + /// function calls, and comma expressions. + /// \code + /// BreakParametersAfter: 3 + /// + /// void foo(int a); + /// + /// void bar(int a, int b, int c); + /// + /// void baz(int a, + /// int b, + /// int c, + /// int d); + /// + /// foo(1); + /// + /// bar(1, 2, 3); + /// + /// baz(1, + /// 2, + /// 3, + /// 4); + /// \endcode + /// \version 23 + unsigned BreakParametersAfter; + /// The template declaration breaking style to use. /// \version 19 BreakTemplateDeclarationsStyle BreakTemplateDeclarations; @@ -5725,6 +5754,7 @@ struct FormatStyle { BreakFunctionDefinitionParameters == R.BreakFunctionDefinitionParameters && BreakInheritanceList == R.BreakInheritanceList && + BreakParametersAfter == R.BreakParametersAfter && BreakStringLiterals == R.BreakStringLiterals && BreakTemplateDeclarations == R.BreakTemplateDeclarations && ColumnLimit == R.ColumnLimit && CommentPragmas == R.CommentPragmas && diff --git a/clang/lib/Format/Format.cpp b/clang/lib/Format/Format.cpp index 1e68de531791f..e0388a17f2ef0 100644 --- a/clang/lib/Format/Format.cpp +++ b/clang/lib/Format/Format.cpp @@ -1355,6 +1355,7 @@ template <> struct MappingTraits<FormatStyle> { Style.WhitespaceSensitiveMacros); IO.mapOptional("WrapNamespaceBodyWithEmptyLines", Style.WrapNamespaceBodyWithEmptyLines); + IO.mapOptional("BreakParametersAfter", Style.BreakParametersAfter); // If AlwaysBreakAfterDefinitionReturnType was specified but // BreakAfterReturnType was not, initialize the latter from the former for @@ -1728,6 +1729,7 @@ FormatStyle getLLVMStyle(FormatStyle::LanguageKind Language) { LLVMStyle.BreakConstructorInitializers = FormatStyle::BCIS_BeforeColon; LLVMStyle.BreakFunctionDefinitionParameters = false; LLVMStyle.BreakInheritanceList = FormatStyle::BILS_BeforeColon; + LLVMStyle.BreakParametersAfter = 0; LLVMStyle.BreakStringLiterals = true; LLVMStyle.BreakTemplateDeclarations = FormatStyle::BTDS_MultiLine; LLVMStyle.ColumnLimit = 80; diff --git a/clang/lib/Format/TokenAnnotator.cpp b/clang/lib/Format/TokenAnnotator.cpp index b1c1afbf8684d..44be5ead41e39 100644 --- a/clang/lib/Format/TokenAnnotator.cpp +++ b/clang/lib/Format/TokenAnnotator.cpp @@ -4246,6 +4246,23 @@ void TokenAnnotator::calculateFormattingInformation(AnnotatedLine &Line) const { ChildSize + Current->SpacesRequiredBefore; } + if (Style.BreakParametersAfter > 0 && Prev->is(tok::l_paren) && + Prev->ParameterCount > Style.BreakParametersAfter) { + const auto *RParen = Prev->MatchingParen; + for (auto *ParamTok = Current; ParamTok && ParamTok != RParen; + ParamTok = ParamTok->Next) { + if (ParamTok->opensScope()) { + ParamTok = ParamTok->MatchingParen; + continue; + } + + if (startsNextParameter(*ParamTok, Style)) { + ParamTok->MustBreakBefore = true; + ParamTok->CanBreakBefore = true; + } + } + } + if (Current->is(TT_ControlStatementLBrace)) { if (Style.ColumnLimit > 0 && Style.BraceWrapping.AfterControlStatement == diff --git a/clang/unittests/Format/ConfigParseTest.cpp b/clang/unittests/Format/ConfigParseTest.cpp index 0a116b770f52a..ef442a17a7a8f 100644 --- a/clang/unittests/Format/ConfigParseTest.cpp +++ b/clang/unittests/Format/ConfigParseTest.cpp @@ -283,6 +283,7 @@ TEST(ConfigParseTest, ParsesConfigurationIntegers) { CHECK_PARSE_INT(BracedInitializerIndentWidth); CHECK_PARSE_INT(PPIndentWidth); + CHECK_PARSE_UNSIGNED(BreakParametersAfter); CHECK_PARSE_UNSIGNED(ColumnLimit); CHECK_PARSE_UNSIGNED(ConstructorInitializerIndentWidth); CHECK_PARSE_UNSIGNED(ContinuationIndentWidth); diff --git a/clang/unittests/Format/FormatTest.cpp b/clang/unittests/Format/FormatTest.cpp index 33836e28289b4..b9a07d960e67c 100644 --- a/clang/unittests/Format/FormatTest.cpp +++ b/clang/unittests/Format/FormatTest.cpp @@ -8164,6 +8164,95 @@ TEST_F(FormatTest, BreakFunctionDefinitionParameters) { " int B)\n" " : m_A(A), m_B(B) {}", Input, Style); + + Style.BinPackParameters = FormatStyle::BPPS_BinPack; + Style.BreakFunctionDefinitionParameters = false; + Style.BreakParametersAfter = 2; + verifyFormat("void functionDecl(paramA, paramB);\n" + "void functionDecl(paramA,\n" + " paramB,\n" + " paramC);\n" + "void functionDecl(paramA,\n" + " paramB,\n" + " paramC,\n" + " paramD,\n" + " paramE);\n" + "void functionDefinition(int A, int B) {}\n" + "void functionDefinition(int A,\n" + " int B,\n" + " int C) {}\n" + "Class::Class(int A, int B) {}\n" + "Class::Class(int A,\n" + " int B,\n" + " int C) {}\n" + "call(a, b);\n" + "call(a,\n" + " b,\n" + " c);\n" + "new Class(a, b);\n" + "new Class(a,\n" + " b,\n" + " c);\n" + "int x = (a, b);\n" + "int y = (a,\n" + " b,\n" + " c);\n" + "(a, b);\n" + "(a,\n" + " b,\n" + " c);", + Style); + Style.BreakParametersAfter = 4; + verifyFormat("void functionDecl(paramA);\n" + "void functionDecl(paramA, paramB);\n" + "void functionDecl(paramA, paramB, paramC);\n" + "void functionDecl(paramA, paramB, paramC, paramD);\n" + "void functionDecl(paramA,\n" + " paramB,\n" + " paramC,\n" + " paramD,\n" + " paramE);\n" + "void functionDecl(paramA,\n" + " paramB,\n" + " paramC,\n" + " paramD,\n" + " paramE,\n" + " paramF);\n" + "void functionDefinition(int A, int B, int C, int D) {}\n" + "void functionDefinition(int A,\n" + " int B,\n" + " int C,\n" + " int D,\n" + " int E) {}\n" + "Class::Class(int A, int B) {}\n" + "Class::Class(int A, int B, int C, int D) {}\n" + "Class::Class(int A,\n" + " int B,\n" + " int C,\n" + " int D,\n" + " int E) {}\n" + "call(a,\n" + " b,\n" + " c,\n" + " d,\n" + " e);\n" + "new Class(a,\n" + " b,\n" + " c,\n" + " d,\n" + " e);\n" + "int y = (a,\n" + " b,\n" + " c,\n" + " d,\n" + " e);\n" + "(a,\n" + " b,\n" + " c,\n" + " d,\n" + " e);", + Style); + Style.BreakParametersAfter = 0; } TEST_F(FormatTest, BreakBeforeInlineASMColon) { `````````` </details> https://github.com/llvm/llvm-project/pull/181281 _______________________________________________ cfe-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
