aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorrmarker <37921131+rmarker@users.noreply.github.com>2024-02-05 06:56:32 +1030
committerGitHub <noreply@github.com>2024-02-04 12:26:32 -0800
commit256200732111afd03bb7437564f3a3d77c0ec3f5 (patch)
treeb4beee78935f7d40cb6e91123788d07232baa1f6
parent9ff83f12fe406f9c3c6b2cd0ee96660a7485f29f (diff)
downloadllvm-256200732111afd03bb7437564f3a3d77c0ec3f5.zip
llvm-256200732111afd03bb7437564f3a3d77c0ec3f5.tar.gz
llvm-256200732111afd03bb7437564f3a3d77c0ec3f5.tar.bz2
[clang-format] Add Automatic and ExceptShortType options for AlwaysBreakAfterReturnType. (#78011)
The RTBS_None option in Clang-format avoids breaking after a short return type. However, there was an issue with the behaviour in that it wouldn't take the leading indentation of the line into account. This meant that the behaviour wasn't applying when intended. In order to address this situation without breaking the existing formatting, RTBS_None has been deprecated. In its place are two new options for AlwaysBreakAfterReturnType. The option RTBS_Automatic will break after the return type based on PenaltyReturnTypeOnItsOwnLine. The option RTBS_ExceptShortType will take the leading indentation into account and prevent breaking after short return types. This allows the inconsistent behaviour of RTBS_None to be avoided and users to decide whether they want to allow breaking after short return types or not. Resolves #78010
-rw-r--r--clang/docs/ClangFormatStyleOptions.rst30
-rw-r--r--clang/include/clang/Format/Format.h29
-rw-r--r--clang/lib/Format/ContinuationIndenter.cpp14
-rw-r--r--clang/lib/Format/Format.cpp2
-rw-r--r--clang/lib/Format/TokenAnnotator.cpp2
-rw-r--r--clang/unittests/Format/ConfigParseTest.cpp4
-rw-r--r--clang/unittests/Format/FormatTest.cpp46
7 files changed, 116 insertions, 11 deletions
diff --git a/clang/docs/ClangFormatStyleOptions.rst b/clang/docs/ClangFormatStyleOptions.rst
index 0b88728..976d9e2 100644
--- a/clang/docs/ClangFormatStyleOptions.rst
+++ b/clang/docs/ClangFormatStyleOptions.rst
@@ -1537,8 +1537,10 @@ the configuration (without a prefix: ``Auto``).
Possible values:
* ``RTBS_None`` (in configuration: ``None``)
- Break after return type automatically.
- ``PenaltyReturnTypeOnItsOwnLine`` is taken into account.
+ This is **deprecated**. See ``Automatic`` below.
+
+ * ``RTBS_Automatic`` (in configuration: ``Automatic``)
+ Break after return type based on ``PenaltyReturnTypeOnItsOwnLine``.
.. code-block:: c++
@@ -1547,6 +1549,22 @@ the configuration (without a prefix: ``Auto``).
};
int f();
int f() { return 1; }
+ int
+ LongName::AnotherLongName();
+
+ * ``RTBS_ExceptShortType`` (in configuration: ``ExceptShortType``)
+ Same as ``Automatic`` above, except that there is no break after short
+ return types.
+
+ .. code-block:: c++
+
+ class A {
+ int f() { return 0; };
+ };
+ int f();
+ int f() { return 1; }
+ int LongName::
+ AnotherLongName();
* ``RTBS_All`` (in configuration: ``All``)
Always break after the return type.
@@ -1565,6 +1583,8 @@ the configuration (without a prefix: ``Auto``).
f() {
return 1;
}
+ int
+ LongName::AnotherLongName();
* ``RTBS_TopLevel`` (in configuration: ``TopLevel``)
Always break after the return types of top-level functions.
@@ -1580,6 +1600,8 @@ the configuration (without a prefix: ``Auto``).
f() {
return 1;
}
+ int
+ LongName::AnotherLongName();
* ``RTBS_AllDefinitions`` (in configuration: ``AllDefinitions``)
Always break after the return type of function definitions.
@@ -1597,6 +1619,8 @@ the configuration (without a prefix: ``Auto``).
f() {
return 1;
}
+ int
+ LongName::AnotherLongName();
* ``RTBS_TopLevelDefinitions`` (in configuration: ``TopLevelDefinitions``)
Always break after the return type of top-level definitions.
@@ -1611,6 +1635,8 @@ the configuration (without a prefix: ``Auto``).
f() {
return 1;
}
+ int
+ LongName::AnotherLongName();
diff --git a/clang/include/clang/Format/Format.h b/clang/include/clang/Format/Format.h
index efcb4e1..2ca80a7 100644
--- a/clang/include/clang/Format/Format.h
+++ b/clang/include/clang/Format/Format.h
@@ -914,16 +914,31 @@ struct FormatStyle {
/// Different ways to break after the function definition or
/// declaration return type.
enum ReturnTypeBreakingStyle : int8_t {
- /// Break after return type automatically.
- /// ``PenaltyReturnTypeOnItsOwnLine`` is taken into account.
+ /// This is **deprecated**. See ``Automatic`` below.
+ RTBS_None,
+ /// Break after return type based on ``PenaltyReturnTypeOnItsOwnLine``.
/// \code
/// class A {
/// int f() { return 0; };
/// };
/// int f();
/// int f() { return 1; }
+ /// int
+ /// LongName::AnotherLongName();
/// \endcode
- RTBS_None,
+ RTBS_Automatic,
+ /// Same as ``Automatic`` above, except that there is no break after short
+ /// return types.
+ /// \code
+ /// class A {
+ /// int f() { return 0; };
+ /// };
+ /// int f();
+ /// int f() { return 1; }
+ /// int LongName::
+ /// AnotherLongName();
+ /// \endcode
+ RTBS_ExceptShortType,
/// Always break after the return type.
/// \code
/// class A {
@@ -938,6 +953,8 @@ struct FormatStyle {
/// f() {
/// return 1;
/// }
+ /// int
+ /// LongName::AnotherLongName();
/// \endcode
RTBS_All,
/// Always break after the return types of top-level functions.
@@ -951,6 +968,8 @@ struct FormatStyle {
/// f() {
/// return 1;
/// }
+ /// int
+ /// LongName::AnotherLongName();
/// \endcode
RTBS_TopLevel,
/// Always break after the return type of function definitions.
@@ -966,6 +985,8 @@ struct FormatStyle {
/// f() {
/// return 1;
/// }
+ /// int
+ /// LongName::AnotherLongName();
/// \endcode
RTBS_AllDefinitions,
/// Always break after the return type of top-level definitions.
@@ -978,6 +999,8 @@ struct FormatStyle {
/// f() {
/// return 1;
/// }
+ /// int
+ /// LongName::AnotherLongName();
/// \endcode
RTBS_TopLevelDefinitions,
};
diff --git a/clang/lib/Format/ContinuationIndenter.cpp b/clang/lib/Format/ContinuationIndenter.cpp
index a3eb913..a3aca4a 100644
--- a/clang/lib/Format/ContinuationIndenter.cpp
+++ b/clang/lib/Format/ContinuationIndenter.cpp
@@ -328,9 +328,17 @@ bool ContinuationIndenter::canBreak(const LineState &State) {
// Don't break after very short return types (e.g. "void") as that is often
// unexpected.
- if (Current.is(TT_FunctionDeclarationName) && State.Column < 6) {
- if (Style.AlwaysBreakAfterReturnType == FormatStyle::RTBS_None)
+ if (Current.is(TT_FunctionDeclarationName)) {
+ if (Style.AlwaysBreakAfterReturnType == FormatStyle::RTBS_None &&
+ State.Column < 6) {
return false;
+ }
+
+ if (Style.AlwaysBreakAfterReturnType == FormatStyle::RTBS_ExceptShortType) {
+ assert(State.Column >= State.FirstIndent);
+ if (State.Column - State.FirstIndent < 6)
+ return false;
+ }
}
// If binary operators are moved to the next line (including commas for some
@@ -587,7 +595,7 @@ bool ContinuationIndenter::mustBreak(const LineState &State) {
!State.Line->ReturnTypeWrapped &&
// Don't break before a C# function when no break after return type.
(!Style.isCSharp() ||
- Style.AlwaysBreakAfterReturnType != FormatStyle::RTBS_None) &&
+ Style.AlwaysBreakAfterReturnType > FormatStyle::RTBS_ExceptShortType) &&
// Don't always break between a JavaScript `function` and the function
// name.
!Style.isJavaScript() && Previous.isNot(tok::kw_template) &&
diff --git a/clang/lib/Format/Format.cpp b/clang/lib/Format/Format.cpp
index 10fe35c..01d6e9a 100644
--- a/clang/lib/Format/Format.cpp
+++ b/clang/lib/Format/Format.cpp
@@ -558,6 +558,8 @@ template <>
struct ScalarEnumerationTraits<FormatStyle::ReturnTypeBreakingStyle> {
static void enumeration(IO &IO, FormatStyle::ReturnTypeBreakingStyle &Value) {
IO.enumCase(Value, "None", FormatStyle::RTBS_None);
+ IO.enumCase(Value, "Automatic", FormatStyle::RTBS_Automatic);
+ IO.enumCase(Value, "ExceptShortType", FormatStyle::RTBS_ExceptShortType);
IO.enumCase(Value, "All", FormatStyle::RTBS_All);
IO.enumCase(Value, "TopLevel", FormatStyle::RTBS_TopLevel);
IO.enumCase(Value, "TopLevelDefinitions",
diff --git a/clang/lib/Format/TokenAnnotator.cpp b/clang/lib/Format/TokenAnnotator.cpp
index d0c4273..7a62f5f 100644
--- a/clang/lib/Format/TokenAnnotator.cpp
+++ b/clang/lib/Format/TokenAnnotator.cpp
@@ -3434,6 +3434,8 @@ bool TokenAnnotator::mustBreakForReturnType(const AnnotatedLine &Line) const {
switch (Style.AlwaysBreakAfterReturnType) {
case FormatStyle::RTBS_None:
+ case FormatStyle::RTBS_Automatic:
+ case FormatStyle::RTBS_ExceptShortType:
return false;
case FormatStyle::RTBS_All:
case FormatStyle::RTBS_TopLevel:
diff --git a/clang/unittests/Format/ConfigParseTest.cpp b/clang/unittests/Format/ConfigParseTest.cpp
index 6436581..3f1fc893 100644
--- a/clang/unittests/Format/ConfigParseTest.cpp
+++ b/clang/unittests/Format/ConfigParseTest.cpp
@@ -680,6 +680,10 @@ TEST(ConfigParseTest, ParsesConfiguration) {
Style.AlwaysBreakAfterReturnType = FormatStyle::RTBS_All;
CHECK_PARSE("AlwaysBreakAfterReturnType: None", AlwaysBreakAfterReturnType,
FormatStyle::RTBS_None);
+ CHECK_PARSE("AlwaysBreakAfterReturnType: Automatic",
+ AlwaysBreakAfterReturnType, FormatStyle::RTBS_Automatic);
+ CHECK_PARSE("AlwaysBreakAfterReturnType: ExceptShortType",
+ AlwaysBreakAfterReturnType, FormatStyle::RTBS_ExceptShortType);
CHECK_PARSE("AlwaysBreakAfterReturnType: All", AlwaysBreakAfterReturnType,
FormatStyle::RTBS_All);
CHECK_PARSE("AlwaysBreakAfterReturnType: TopLevel",
diff --git a/clang/unittests/Format/FormatTest.cpp b/clang/unittests/Format/FormatTest.cpp
index a471e36..2f7febd 100644
--- a/clang/unittests/Format/FormatTest.cpp
+++ b/clang/unittests/Format/FormatTest.cpp
@@ -9867,14 +9867,48 @@ TEST_F(FormatTest, AlignsStringLiterals) {
TEST_F(FormatTest, ReturnTypeBreakingStyle) {
FormatStyle Style = getLLVMStyle();
+ Style.ColumnLimit = 60;
+
// No declarations or definitions should be moved to own line.
Style.AlwaysBreakAfterReturnType = FormatStyle::RTBS_None;
verifyFormat("class A {\n"
" int f() { return 1; }\n"
" int g();\n"
+ " long\n"
+ " foooooooooooooooooooooooooooo::baaaaaaaaaaaaaaaaaaaar();\n"
"};\n"
"int f() { return 1; }\n"
- "int g();",
+ "int g();\n"
+ "int foooooooooooooooooooooooooooo::\n"
+ " baaaaaaaaaaaaaaaaaaaaar();",
+ Style);
+
+ // It is now allowed to break after a short return type if necessary.
+ Style.AlwaysBreakAfterReturnType = FormatStyle::RTBS_Automatic;
+ verifyFormat("class A {\n"
+ " int f() { return 1; }\n"
+ " int g();\n"
+ " long\n"
+ " foooooooooooooooooooooooooooo::baaaaaaaaaaaaaaaaaaaar();\n"
+ "};\n"
+ "int f() { return 1; }\n"
+ "int g();\n"
+ "int\n"
+ "foooooooooooooooooooooooooooo::baaaaaaaaaaaaaaaaaaaaar();",
+ Style);
+
+ // It now must never break after a short return type.
+ Style.AlwaysBreakAfterReturnType = FormatStyle::RTBS_ExceptShortType;
+ verifyFormat("class A {\n"
+ " int f() { return 1; }\n"
+ " int g();\n"
+ " long foooooooooooooooooooooooooooo::\n"
+ " baaaaaaaaaaaaaaaaaaaar();\n"
+ "};\n"
+ "int f() { return 1; }\n"
+ "int g();\n"
+ "int foooooooooooooooooooooooooooo::\n"
+ " baaaaaaaaaaaaaaaaaaaaar();",
Style);
// All declarations and definitions should have the return type moved to its
@@ -9891,13 +9925,17 @@ TEST_F(FormatTest, ReturnTypeBreakingStyle) {
" }\n"
" int\n"
" g();\n"
+ " long\n"
+ " foooooooooooooooooooooooooooo::baaaaaaaaaaaaaaaaaaaar();\n"
"};\n"
"int\n"
"f() {\n"
" return 1;\n"
"}\n"
"int\n"
- "g();",
+ "g();\n"
+ "int\n"
+ "foooooooooooooooooooooooooooo::baaaaaaaaaaaaaaaaaaaaar();",
Style);
// Top-level definitions, and no kinds of declarations should have the
@@ -9926,7 +9964,9 @@ TEST_F(FormatTest, ReturnTypeBreakingStyle) {
" return 1;\n"
"}\n"
"int\n"
- "g();",
+ "g();\n"
+ "int\n"
+ "foooooooooooooooooooooooooooo::baaaaaaaaaaaaaaaaaaaaar();",
Style);
// All definitions should have the return type moved to its own line, but no