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

Reply via email to