[clang] [clang-format] Add BreakFunctionDefinitionParameters option (PR #84988)
Ameer J via cfe-commits
cfe-commits at lists.llvm.org
Tue Mar 26 16:11:30 PDT 2024
https://github.com/ameerj updated https://github.com/llvm/llvm-project/pull/84988
>From 0d0868ddffe1b0668a57c10cc89614ab7c840634 Mon Sep 17 00:00:00 2001
From: ameerj <ameerj99 at outlook.com>
Date: Sat, 16 Mar 2024 17:03:47 -0400
Subject: [PATCH 1/3] [clang-format] Add BreakFunctionDefinitionParameters
option
---
clang/docs/ClangFormatStyleOptions.rst | 6 ++++++
clang/include/clang/Format/Format.h | 7 +++++++
clang/lib/Format/Format.cpp | 3 +++
clang/lib/Format/FormatToken.h | 3 +++
clang/lib/Format/TokenAnnotator.cpp | 7 +++++++
clang/unittests/Format/FormatTest.cpp | 18 ++++++++++++++++++
6 files changed, 44 insertions(+)
diff --git a/clang/docs/ClangFormatStyleOptions.rst b/clang/docs/ClangFormatStyleOptions.rst
index 5b00a8f4c00fb8..a5e710e21c8338 100644
--- a/clang/docs/ClangFormatStyleOptions.rst
+++ b/clang/docs/ClangFormatStyleOptions.rst
@@ -3150,6 +3150,12 @@ the configuration (without a prefix: ``Auto``).
+.. _BreakFunctionDefinitionParameters:
+
+**BreakFunctionDefinitionParameters** (``Boolean``) :versionbadge:`clang-format 19` :ref:`¶ <BreakFunctionDefinitionParameters>`
+ If ``true``, clang-format will always break before function definition
+ parameters
+
.. _BreakInheritanceList:
**BreakInheritanceList** (``BreakInheritanceListStyle``) :versionbadge:`clang-format 7` :ref:`¶ <BreakInheritanceList>`
diff --git a/clang/include/clang/Format/Format.h b/clang/include/clang/Format/Format.h
index a72c1b171c3e18..8bf3fac6176205 100644
--- a/clang/include/clang/Format/Format.h
+++ b/clang/include/clang/Format/Format.h
@@ -2218,6 +2218,11 @@ struct FormatStyle {
/// \version 3.8
bool BreakAfterJavaFieldAnnotations;
+ /// If ``true``, clang-format will always break before function definition
+ /// parameters
+ /// \version 19
+ bool BreakFunctionDefinitionParameters;
+
/// Allow breaking string literals when formatting.
///
/// In C, C++, and Objective-C:
@@ -4867,6 +4872,8 @@ struct FormatStyle {
BreakBeforeInlineASMColon == R.BreakBeforeInlineASMColon &&
BreakBeforeTernaryOperators == R.BreakBeforeTernaryOperators &&
BreakConstructorInitializers == R.BreakConstructorInitializers &&
+ BreakFunctionDefinitionParameters ==
+ R.BreakFunctionDefinitionParameters &&
BreakInheritanceList == R.BreakInheritanceList &&
BreakStringLiterals == R.BreakStringLiterals &&
BreakTemplateDeclarations == R.BreakTemplateDeclarations &&
diff --git a/clang/lib/Format/Format.cpp b/clang/lib/Format/Format.cpp
index d5d115a3c8db85..635f8123c402c7 100644
--- a/clang/lib/Format/Format.cpp
+++ b/clang/lib/Format/Format.cpp
@@ -933,6 +933,8 @@ template <> struct MappingTraits<FormatStyle> {
IO.mapOptional("BreakAfterJavaFieldAnnotations",
Style.BreakAfterJavaFieldAnnotations);
IO.mapOptional("BreakAfterReturnType", Style.BreakAfterReturnType);
+ IO.mapOptional("BreakFunctionDefinitionParameters",
+ Style.BreakFunctionDefinitionParameters);
IO.mapOptional("BreakArrays", Style.BreakArrays);
IO.mapOptional("BreakBeforeBinaryOperators",
Style.BreakBeforeBinaryOperators);
@@ -1443,6 +1445,7 @@ FormatStyle getLLVMStyle(FormatStyle::LanguageKind Language) {
LLVMStyle.BreakAfterAttributes = FormatStyle::ABS_Leave;
LLVMStyle.BreakAfterJavaFieldAnnotations = false;
LLVMStyle.BreakAfterReturnType = FormatStyle::RTBS_None;
+ LLVMStyle.BreakFunctionDefinitionParameters = false;
LLVMStyle.BreakArrays = true;
LLVMStyle.BreakBeforeBinaryOperators = FormatStyle::BOS_None;
LLVMStyle.BreakBeforeBraces = FormatStyle::BS_Attach;
diff --git a/clang/lib/Format/FormatToken.h b/clang/lib/Format/FormatToken.h
index c9022aba287187..d7cad8cec38948 100644
--- a/clang/lib/Format/FormatToken.h
+++ b/clang/lib/Format/FormatToken.h
@@ -569,6 +569,9 @@ struct FormatToken {
/// Is optional and can be removed.
bool Optional = false;
+ /// Might be function declaration open/closing paren.
+ bool MightBeFunctionDeclParen = false;
+
/// Number of optional braces to be inserted after this token:
/// -1: a single left brace
/// 0: no braces
diff --git a/clang/lib/Format/TokenAnnotator.cpp b/clang/lib/Format/TokenAnnotator.cpp
index 1342d37a147915..352b2fac149b29 100644
--- a/clang/lib/Format/TokenAnnotator.cpp
+++ b/clang/lib/Format/TokenAnnotator.cpp
@@ -1502,6 +1502,7 @@ class AnnotatingParser {
(!Previous->isAttribute() &&
!Previous->isOneOf(TT_RequiresClause, TT_LeadingJavaAnnotation))) {
Line.MightBeFunctionDecl = true;
+ Tok->MightBeFunctionDeclParen = true;
}
}
break;
@@ -5317,6 +5318,12 @@ bool TokenAnnotator::mustBreakBefore(const AnnotatedLine &Line,
if (Right.NewlinesBefore > 1 && Style.MaxEmptyLinesToKeep > 0)
return true;
+ if (Style.BreakFunctionDefinitionParameters && Line.MightBeFunctionDecl &&
+ Line.mightBeFunctionDefinition() && Left.is(tok::l_paren) &&
+ Left.MightBeFunctionDeclParen && Left.ParameterCount > 0) {
+ return true;
+ }
+
if (Style.isCSharp()) {
if (Left.is(TT_FatArrow) && Right.is(tok::l_brace) &&
Style.BraceWrapping.AfterFunction) {
diff --git a/clang/unittests/Format/FormatTest.cpp b/clang/unittests/Format/FormatTest.cpp
index fc367a7a5a8981..d70a3c916a2d75 100644
--- a/clang/unittests/Format/FormatTest.cpp
+++ b/clang/unittests/Format/FormatTest.cpp
@@ -7951,6 +7951,24 @@ TEST_F(FormatTest, AllowAllArgumentsOnNextLineDontAlign) {
Input, Style);
}
+TEST_F(FormatTest, BreakFunctionDefinitionParameters) {
+ FormatStyle Style = getLLVMStyleWithColumns(80);
+ StringRef Input = "void functionDecl(paramA, paramB, paramC);\n"
+ "void emptyFunctionDefinition() {}\n"
+ "void functionDefinition(int A, int B, int C) {}";
+ Style.BreakFunctionDefinitionParameters = false;
+ verifyFormat(StringRef("void functionDecl(paramA, paramB, paramC);\n"
+ "void emptyFunctionDefinition() {}\n"
+ "void functionDefinition(int A, int B, int C) {}"),
+ Input, Style);
+ Style.BreakFunctionDefinitionParameters = true;
+ verifyFormat(StringRef("void functionDecl(paramA, paramB, paramC);\n"
+ "void emptyFunctionDefinition() {}\n"
+ "void functionDefinition(\n"
+ " int A, int B, int C) {}"),
+ Input, Style);
+}
+
TEST_F(FormatTest, BreakBeforeInlineASMColon) {
FormatStyle Style = getLLVMStyle();
Style.BreakBeforeInlineASMColon = FormatStyle::BBIAS_Never;
>From e856cccf8459bee06013c4dea496a62f9a8183b6 Mon Sep 17 00:00:00 2001
From: ameerj <ameerj99 at outlook.com>
Date: Tue, 26 Mar 2024 11:00:56 -0400
Subject: [PATCH 2/3] Address feedback
---
clang/docs/ClangFormatStyleOptions.rst | 11 ++++++++++-
clang/include/clang/Format/Format.h | 19 ++++++++++++++-----
clang/lib/Format/TokenAnnotator.cpp | 4 ++--
clang/unittests/Format/FormatTest.cpp | 4 ++--
4 files changed, 28 insertions(+), 10 deletions(-)
diff --git a/clang/docs/ClangFormatStyleOptions.rst b/clang/docs/ClangFormatStyleOptions.rst
index a5e710e21c8338..8c827919058744 100644
--- a/clang/docs/ClangFormatStyleOptions.rst
+++ b/clang/docs/ClangFormatStyleOptions.rst
@@ -3154,7 +3154,16 @@ the configuration (without a prefix: ``Auto``).
**BreakFunctionDefinitionParameters** (``Boolean``) :versionbadge:`clang-format 19` :ref:`¶ <BreakFunctionDefinitionParameters>`
If ``true``, clang-format will always break before function definition
- parameters
+ parameters.
+
+ .. code-block:: c++
+
+ true:
+ void functionDefinition(
+ int A, int B) {}
+
+ false:
+ void functionDefinition(int A, int B) {}
.. _BreakInheritanceList:
diff --git a/clang/include/clang/Format/Format.h b/clang/include/clang/Format/Format.h
index 8bf3fac6176205..6567d039a1641b 100644
--- a/clang/include/clang/Format/Format.h
+++ b/clang/include/clang/Format/Format.h
@@ -2208,6 +2208,20 @@ struct FormatStyle {
/// \version 5
BreakConstructorInitializersStyle BreakConstructorInitializers;
+ /// If ``true``, clang-format will always break before function definition
+ /// parameters.
+ /// \code
+ /// true:
+ /// void functionDefinition(
+ /// int A, int B) {}
+ ///
+ /// false:
+ /// void functionDefinition(int A, int B) {}
+ ///
+ /// \endcode
+ /// \version 19
+ bool BreakFunctionDefinitionParameters;
+
/// Break after each annotation on a field in Java files.
/// \code{.java}
/// true: false:
@@ -2218,11 +2232,6 @@ struct FormatStyle {
/// \version 3.8
bool BreakAfterJavaFieldAnnotations;
- /// If ``true``, clang-format will always break before function definition
- /// parameters
- /// \version 19
- bool BreakFunctionDefinitionParameters;
-
/// Allow breaking string literals when formatting.
///
/// In C, C++, and Objective-C:
diff --git a/clang/lib/Format/TokenAnnotator.cpp b/clang/lib/Format/TokenAnnotator.cpp
index 352b2fac149b29..1557386869e127 100644
--- a/clang/lib/Format/TokenAnnotator.cpp
+++ b/clang/lib/Format/TokenAnnotator.cpp
@@ -5319,8 +5319,8 @@ bool TokenAnnotator::mustBreakBefore(const AnnotatedLine &Line,
return true;
if (Style.BreakFunctionDefinitionParameters && Line.MightBeFunctionDecl &&
- Line.mightBeFunctionDefinition() && Left.is(tok::l_paren) &&
- Left.MightBeFunctionDeclParen && Left.ParameterCount > 0) {
+ Line.mightBeFunctionDefinition() && Left.MightBeFunctionDeclParen &&
+ Left.ParameterCount > 0) {
return true;
}
diff --git a/clang/unittests/Format/FormatTest.cpp b/clang/unittests/Format/FormatTest.cpp
index d70a3c916a2d75..fcfb06c02be682 100644
--- a/clang/unittests/Format/FormatTest.cpp
+++ b/clang/unittests/Format/FormatTest.cpp
@@ -7952,11 +7952,11 @@ TEST_F(FormatTest, AllowAllArgumentsOnNextLineDontAlign) {
}
TEST_F(FormatTest, BreakFunctionDefinitionParameters) {
- FormatStyle Style = getLLVMStyleWithColumns(80);
+ FormatStyle Style = getLLVMStyle();
+ EXPECT_FALSE(Style.BreakFunctionDefinitionParameters);
StringRef Input = "void functionDecl(paramA, paramB, paramC);\n"
"void emptyFunctionDefinition() {}\n"
"void functionDefinition(int A, int B, int C) {}";
- Style.BreakFunctionDefinitionParameters = false;
verifyFormat(StringRef("void functionDecl(paramA, paramB, paramC);\n"
"void emptyFunctionDefinition() {}\n"
"void functionDefinition(int A, int B, int C) {}"),
>From 5376e83fe824d28657a7c5b1623a22b7a760410b Mon Sep 17 00:00:00 2001
From: ameerj <ameerj99 at outlook.com>
Date: Tue, 26 Mar 2024 19:11:03 -0400
Subject: [PATCH 3/3] Fix sorting, add Class and single line param tests
---
clang/lib/Format/Format.cpp | 6 +++---
clang/unittests/Format/FormatTest.cpp | 25 ++++++++++++++++++++++---
2 files changed, 25 insertions(+), 6 deletions(-)
diff --git a/clang/lib/Format/Format.cpp b/clang/lib/Format/Format.cpp
index 635f8123c402c7..d8152b2d22c808 100644
--- a/clang/lib/Format/Format.cpp
+++ b/clang/lib/Format/Format.cpp
@@ -933,8 +933,6 @@ template <> struct MappingTraits<FormatStyle> {
IO.mapOptional("BreakAfterJavaFieldAnnotations",
Style.BreakAfterJavaFieldAnnotations);
IO.mapOptional("BreakAfterReturnType", Style.BreakAfterReturnType);
- IO.mapOptional("BreakFunctionDefinitionParameters",
- Style.BreakFunctionDefinitionParameters);
IO.mapOptional("BreakArrays", Style.BreakArrays);
IO.mapOptional("BreakBeforeBinaryOperators",
Style.BreakBeforeBinaryOperators);
@@ -947,6 +945,8 @@ template <> struct MappingTraits<FormatStyle> {
Style.BreakBeforeTernaryOperators);
IO.mapOptional("BreakConstructorInitializers",
Style.BreakConstructorInitializers);
+ IO.mapOptional("BreakFunctionDefinitionParameters",
+ Style.BreakFunctionDefinitionParameters);
IO.mapOptional("BreakInheritanceList", Style.BreakInheritanceList);
IO.mapOptional("BreakStringLiterals", Style.BreakStringLiterals);
IO.mapOptional("BreakTemplateDeclarations",
@@ -1445,7 +1445,6 @@ FormatStyle getLLVMStyle(FormatStyle::LanguageKind Language) {
LLVMStyle.BreakAfterAttributes = FormatStyle::ABS_Leave;
LLVMStyle.BreakAfterJavaFieldAnnotations = false;
LLVMStyle.BreakAfterReturnType = FormatStyle::RTBS_None;
- LLVMStyle.BreakFunctionDefinitionParameters = false;
LLVMStyle.BreakArrays = true;
LLVMStyle.BreakBeforeBinaryOperators = FormatStyle::BOS_None;
LLVMStyle.BreakBeforeBraces = FormatStyle::BS_Attach;
@@ -1453,6 +1452,7 @@ FormatStyle getLLVMStyle(FormatStyle::LanguageKind Language) {
LLVMStyle.BreakBeforeInlineASMColon = FormatStyle::BBIAS_OnlyMultiline;
LLVMStyle.BreakBeforeTernaryOperators = true;
LLVMStyle.BreakConstructorInitializers = FormatStyle::BCIS_BeforeColon;
+ LLVMStyle.BreakFunctionDefinitionParameters = false;
LLVMStyle.BreakInheritanceList = FormatStyle::BILS_BeforeColon;
LLVMStyle.BreakStringLiterals = true;
LLVMStyle.BreakTemplateDeclarations = FormatStyle::BTDS_MultiLine;
diff --git a/clang/unittests/Format/FormatTest.cpp b/clang/unittests/Format/FormatTest.cpp
index fcfb06c02be682..d5f8b43ce91a29 100644
--- a/clang/unittests/Format/FormatTest.cpp
+++ b/clang/unittests/Format/FormatTest.cpp
@@ -7956,16 +7956,35 @@ TEST_F(FormatTest, BreakFunctionDefinitionParameters) {
EXPECT_FALSE(Style.BreakFunctionDefinitionParameters);
StringRef Input = "void functionDecl(paramA, paramB, paramC);\n"
"void emptyFunctionDefinition() {}\n"
- "void functionDefinition(int A, int B, int C) {}";
+ "void functionDefinition(int A, int B, int C) {}\n"
+ "Class::Class(int A, int B) : m_A(A), m_B(B) {}\n";
verifyFormat(StringRef("void functionDecl(paramA, paramB, paramC);\n"
"void emptyFunctionDefinition() {}\n"
- "void functionDefinition(int A, int B, int C) {}"),
+ "void functionDefinition(int A, int B, int C) {}\n"
+ "Class::Class(int A, int B) : m_A(A), m_B(B) {}\n"),
Input, Style);
Style.BreakFunctionDefinitionParameters = true;
verifyFormat(StringRef("void functionDecl(paramA, paramB, paramC);\n"
"void emptyFunctionDefinition() {}\n"
"void functionDefinition(\n"
- " int A, int B, int C) {}"),
+ " int A, int B, int C) {}\n"
+ "Class::Class(\n"
+ " int A, int B)\n"
+ " : m_A(A), m_B(B) {}\n"),
+ Input, Style);
+ // Test the style where all parameters are on their own lines
+ Style.AllowAllParametersOfDeclarationOnNextLine = false;
+ Style.BinPackParameters = false;
+ verifyFormat(StringRef("void functionDecl(paramA, paramB, paramC);\n"
+ "void emptyFunctionDefinition() {}\n"
+ "void functionDefinition(\n"
+ " int A,\n"
+ " int B,\n"
+ " int C) {}\n"
+ "Class::Class(\n"
+ " int A,\n"
+ " int B)\n"
+ " : m_A(A), m_B(B) {}\n"),
Input, Style);
}
More information about the cfe-commits
mailing list