https://github.com/Fanteria created https://github.com/llvm/llvm-project/pull/158745
Add a new clang-format option `BreakFunctionDeclarationParameters` to control whether parameters in function declarations can be broken onto new lines, similar to the existing `BreakFunctionDefinitionParameters` option. Closes #158742 >From 6b45167ba1fda24ea6bee26ffb5463e6fa15955c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ji=C5=99=C3=AD=20Alexandrovi=C4=8D?= <jiri.alexandro...@gmail.com> Date: Mon, 15 Sep 2025 23:56:45 +0200 Subject: [PATCH] [clang-format] Add BreakFunctionDeclarationParameters option --- clang/docs/ClangFormatStyleOptions.rst | 15 ++++++++++++ clang/include/clang/Format/Format.h | 16 +++++++++++++ clang/lib/Format/Format.cpp | 3 +++ clang/lib/Format/TokenAnnotator.cpp | 6 +++++ clang/unittests/Format/FormatTest.cpp | 33 ++++++++++++++++++++++++++ 5 files changed, 73 insertions(+) diff --git a/clang/docs/ClangFormatStyleOptions.rst b/clang/docs/ClangFormatStyleOptions.rst index 9413b9a348b76..ab1afb8e9697a 100644 --- a/clang/docs/ClangFormatStyleOptions.rst +++ b/clang/docs/ClangFormatStyleOptions.rst @@ -3565,6 +3565,21 @@ the configuration (without a prefix: ``Auto``). +.. _BreakFunctionDeclarationParameters: + +**BreakFunctionDeclarationParameters** (``Boolean``) :versionbadge:`clang-format 22` :ref:`¶ <BreakFunctionDeclarationParameters>` + If ``true``, clang-format will always break before function declaration + parameters. + + .. code-block:: c++ + + true: + void functionDeclaration( + int A, int B); + + false: + void functionDeclaration(int A, int B); + .. _BreakFunctionDefinitionParameters: **BreakFunctionDefinitionParameters** (``Boolean``) :versionbadge:`clang-format 19` :ref:`¶ <BreakFunctionDefinitionParameters>` diff --git a/clang/include/clang/Format/Format.h b/clang/include/clang/Format/Format.h index 342fefcfc408c..22f60b3db6770 100644 --- a/clang/include/clang/Format/Format.h +++ b/clang/include/clang/Format/Format.h @@ -2389,6 +2389,20 @@ struct FormatStyle { /// \version 19 bool BreakFunctionDefinitionParameters; + /// If ``true``, clang-format will always break before function declaration + /// parameters. + /// \code + /// true: + /// void functionDeclaration( + /// int A, int B); + /// + /// false: + /// void functionDeclaration(int A, int B); + /// + /// \endcode + /// \version 22 + bool BreakFunctionDeclarationParameters; + /// Break after each annotation on a field in Java files. /// \code{.java} /// true: false: @@ -5497,6 +5511,8 @@ struct FormatStyle { BreakConstructorInitializers == R.BreakConstructorInitializers && BreakFunctionDefinitionParameters == R.BreakFunctionDefinitionParameters && + BreakFunctionDeclarationParameters == + R.BreakFunctionDeclarationParameters && BreakInheritanceList == R.BreakInheritanceList && BreakStringLiterals == R.BreakStringLiterals && BreakTemplateDeclarations == R.BreakTemplateDeclarations && diff --git a/clang/lib/Format/Format.cpp b/clang/lib/Format/Format.cpp index 68e9618432035..83d2f645df0f8 100644 --- a/clang/lib/Format/Format.cpp +++ b/clang/lib/Format/Format.cpp @@ -1083,6 +1083,8 @@ template <> struct MappingTraits<FormatStyle> { Style.BreakConstructorInitializers); IO.mapOptional("BreakFunctionDefinitionParameters", Style.BreakFunctionDefinitionParameters); + IO.mapOptional("BreakFunctionDeclarationParameters", + Style.BreakFunctionDeclarationParameters); IO.mapOptional("BreakInheritanceList", Style.BreakInheritanceList); IO.mapOptional("BreakStringLiterals", Style.BreakStringLiterals); IO.mapOptional("BreakTemplateDeclarations", @@ -1617,6 +1619,7 @@ FormatStyle getLLVMStyle(FormatStyle::LanguageKind Language) { LLVMStyle.BreakBinaryOperations = FormatStyle::BBO_Never; LLVMStyle.BreakConstructorInitializers = FormatStyle::BCIS_BeforeColon; LLVMStyle.BreakFunctionDefinitionParameters = false; + LLVMStyle.BreakFunctionDeclarationParameters = false; LLVMStyle.BreakInheritanceList = FormatStyle::BILS_BeforeColon; LLVMStyle.BreakStringLiterals = true; LLVMStyle.BreakTemplateDeclarations = FormatStyle::BTDS_MultiLine; diff --git a/clang/lib/Format/TokenAnnotator.cpp b/clang/lib/Format/TokenAnnotator.cpp index d97f56751ea69..8420b29628b62 100644 --- a/clang/lib/Format/TokenAnnotator.cpp +++ b/clang/lib/Format/TokenAnnotator.cpp @@ -5626,6 +5626,12 @@ bool TokenAnnotator::mustBreakBefore(const AnnotatedLine &Line, return true; } + if (Style.BreakFunctionDeclarationParameters && Line.MightBeFunctionDecl && + !Line.mightBeFunctionDefinition() && Left.MightBeFunctionDeclParen && + Left.ParameterCount > 0) { + return true; + } + // Ignores the first parameter as this will be handled separately by // BreakFunctionDefinitionParameters or AlignAfterOpenBracket. if (Style.BinPackParameters == FormatStyle::BPPS_AlwaysOnePerLine && diff --git a/clang/unittests/Format/FormatTest.cpp b/clang/unittests/Format/FormatTest.cpp index d9db06667d802..5d7e6e423e153 100644 --- a/clang/unittests/Format/FormatTest.cpp +++ b/clang/unittests/Format/FormatTest.cpp @@ -8143,6 +8143,39 @@ TEST_F(FormatTest, BreakFunctionDefinitionParameters) { Input, Style); } +TEST_F(FormatTest, BreakFunctionDeclarationParameters) { + StringRef Input = "void functionDecl(paramA, paramB, paramC);\n" + "void emptyFunctionDefinition() {}\n" + "void functionDefinition(int A, int B, int C) {}\n" + "Class::Class(int A, int B) : m_A(A), m_B(B) {}"; + verifyFormat(Input); + + FormatStyle Style = getLLVMStyle(); + EXPECT_FALSE(Style.BreakFunctionDeclarationParameters); + Style.BreakFunctionDeclarationParameters = true; + verifyFormat("void functionDecl(\n" + " paramA, paramB, paramC);\n" + "void emptyFunctionDefinition() {}\n" + "void functionDefinition(int A, int B, int C) {}\n" + "class Class {\n" + " Class(\n" + " int A, int B);\n" + "};\n", + Input, Style); + + // Test the style where all parameters are on their own lines. + Style.AllowAllParametersOfDeclarationOnNextLine = false; + Style.BinPackParameters = FormatStyle::BPPS_OnePerLine; + verifyFormat("void functionDecl(\n" + " paramA,\n" + " paramB,\n" + " paramC);\n" + "void emptyFunctionDefinition() {}\n" + "void functionDefinition(int A, int B, int C) {}\n" + "Class::Class(int A, int B) : m_A(A), m_B(B) {}", + Input, Style); +} + TEST_F(FormatTest, BreakBeforeInlineASMColon) { FormatStyle Style = getLLVMStyle(); Style.BreakBeforeInlineASMColon = FormatStyle::BBIAS_Never; _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits