-
Notifications
You must be signed in to change notification settings - Fork 10.8k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[clang-format] Add Leave to AlwaysBreakTemplateDeclarations #80569
Merged
Conversation
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
llvmbot
added
clang
Clang issues not falling into any other category
clang-format
labels
Feb 4, 2024
@llvm/pr-subscribers-clang @llvm/pr-subscribers-clang-format Author: Owen Pan (owenca) ChangesNow with a8279a8, we can make the update. Full diff: https://github.com/llvm/llvm-project/pull/80569.diff 7 Files Affected:
diff --git a/clang/docs/ClangFormatStyleOptions.rst b/clang/docs/ClangFormatStyleOptions.rst
index 0b887288fe2cb..5e23b16fa5910 100644
--- a/clang/docs/ClangFormatStyleOptions.rst
+++ b/clang/docs/ClangFormatStyleOptions.rst
@@ -1638,6 +1638,18 @@ the configuration (without a prefix: ``Auto``).
Possible values:
+ * ``BTDS_Leave`` (in configuration: ``Leave``)
+ Do not change the line breaking before the declaration.
+
+ .. code-block:: c++
+
+ template <typename T>
+ T foo() {
+ }
+ template <typename T> T foo(int aaaaaaaaaaaaaaaaaaaaa,
+ int bbbbbbbbbbbbbbbbbbbbb) {
+ }
+
* ``BTDS_No`` (in configuration: ``No``)
Do not force break before declaration.
``PenaltyBreakTemplateDeclaration`` is taken into account.
diff --git a/clang/include/clang/Format/Format.h b/clang/include/clang/Format/Format.h
index efcb4e1d87ea4..0328854d83165 100644
--- a/clang/include/clang/Format/Format.h
+++ b/clang/include/clang/Format/Format.h
@@ -1008,6 +1008,16 @@ struct FormatStyle {
/// Different ways to break after the template declaration.
enum BreakTemplateDeclarationsStyle : int8_t {
+ /// Do not change the line breaking before the declaration.
+ /// \code
+ /// template <typename T>
+ /// T foo() {
+ /// }
+ /// template <typename T> T foo(int aaaaaaaaaaaaaaaaaaaaa,
+ /// int bbbbbbbbbbbbbbbbbbbbb) {
+ /// }
+ /// \endcode
+ BTDS_Leave,
/// Do not force break before declaration.
/// ``PenaltyBreakTemplateDeclaration`` is taken into account.
/// \code
diff --git a/clang/lib/Format/ContinuationIndenter.cpp b/clang/lib/Format/ContinuationIndenter.cpp
index a3eb9138b2183..a4e4b7ace684d 100644
--- a/clang/lib/Format/ContinuationIndenter.cpp
+++ b/clang/lib/Format/ContinuationIndenter.cpp
@@ -561,7 +561,10 @@ bool ContinuationIndenter::mustBreak(const LineState &State) {
return true;
}
}
- return Style.AlwaysBreakTemplateDeclarations != FormatStyle::BTDS_No;
+ return Style.AlwaysBreakTemplateDeclarations != FormatStyle::BTDS_No &&
+ (Style.AlwaysBreakTemplateDeclarations !=
+ FormatStyle::BTDS_Leave ||
+ Current.NewlinesBefore > 0);
}
if (Previous.is(TT_FunctionAnnotationRParen) &&
State.Line->Type != LT_PreprocessorDirective) {
diff --git a/clang/lib/Format/Format.cpp b/clang/lib/Format/Format.cpp
index 10fe35c79a4f2..7ffc73ca6629e 100644
--- a/clang/lib/Format/Format.cpp
+++ b/clang/lib/Format/Format.cpp
@@ -296,6 +296,7 @@ template <>
struct ScalarEnumerationTraits<FormatStyle::BreakTemplateDeclarationsStyle> {
static void enumeration(IO &IO,
FormatStyle::BreakTemplateDeclarationsStyle &Value) {
+ IO.enumCase(Value, "Leave", FormatStyle::BTDS_Leave);
IO.enumCase(Value, "No", FormatStyle::BTDS_No);
IO.enumCase(Value, "MultiLine", FormatStyle::BTDS_MultiLine);
IO.enumCase(Value, "Yes", FormatStyle::BTDS_Yes);
diff --git a/clang/lib/Format/TokenAnnotator.cpp b/clang/lib/Format/TokenAnnotator.cpp
index d0c4273cfc7e5..fd02faf85fede 100644
--- a/clang/lib/Format/TokenAnnotator.cpp
+++ b/clang/lib/Format/TokenAnnotator.cpp
@@ -5182,7 +5182,9 @@ bool TokenAnnotator::mustBreakBefore(const AnnotatedLine &Line,
// concept ...
if (Right.is(tok::kw_concept))
return Style.BreakBeforeConceptDeclarations == FormatStyle::BBCDS_Always;
- return Style.AlwaysBreakTemplateDeclarations == FormatStyle::BTDS_Yes;
+ return Style.AlwaysBreakTemplateDeclarations == FormatStyle::BTDS_Yes ||
+ (Style.AlwaysBreakTemplateDeclarations == FormatStyle::BTDS_Leave &&
+ Right.NewlinesBefore > 0);
}
if (Left.ClosesRequiresClause && Right.isNot(tok::semi)) {
switch (Style.RequiresClausePosition) {
diff --git a/clang/unittests/Format/ConfigParseTest.cpp b/clang/unittests/Format/ConfigParseTest.cpp
index 6436581ddae5a..d32acd2bd32dc 100644
--- a/clang/unittests/Format/ConfigParseTest.cpp
+++ b/clang/unittests/Format/ConfigParseTest.cpp
@@ -691,6 +691,8 @@ TEST(ConfigParseTest, ParsesConfiguration) {
FormatStyle::RTBS_TopLevelDefinitions);
Style.AlwaysBreakTemplateDeclarations = FormatStyle::BTDS_Yes;
+ CHECK_PARSE("AlwaysBreakTemplateDeclarations: Leave",
+ AlwaysBreakTemplateDeclarations, FormatStyle::BTDS_Leave);
CHECK_PARSE("AlwaysBreakTemplateDeclarations: No",
AlwaysBreakTemplateDeclarations, FormatStyle::BTDS_No);
CHECK_PARSE("AlwaysBreakTemplateDeclarations: MultiLine",
diff --git a/clang/unittests/Format/FormatTest.cpp b/clang/unittests/Format/FormatTest.cpp
index a471e36f8d682..50d0da4dff33e 100644
--- a/clang/unittests/Format/FormatTest.cpp
+++ b/clang/unittests/Format/FormatTest.cpp
@@ -10657,6 +10657,84 @@ TEST_F(FormatTest, WrapsTemplateDeclarations) {
verifyFormat("template <typename T> void\nfoo(aaaaaaaaaaaaaaaaaaaaaaaaaa "
"bbbbbbbbbbbbbbbbbbbb) {}",
NeverBreak);
+
+ auto Style = getLLVMStyle();
+ Style.AlwaysBreakTemplateDeclarations = FormatStyle::BTDS_Leave;
+
+ verifyNoChange("template <typename T>\n"
+ "class C {};",
+ Style);
+ verifyFormat("template <typename T> class C {};", Style);
+
+ verifyNoChange("template <typename T>\n"
+ "void f();",
+ Style);
+ verifyFormat("template <typename T> void f();", Style);
+
+ verifyNoChange("template <typename T>\n"
+ "void f() {}",
+ Style);
+ verifyFormat("template <typename T> void f() {}", Style);
+
+ verifyNoChange("template <typename T>\n"
+ "// T can be A, B or C.\n"
+ "struct C {};",
+ Style);
+ verifyFormat("template <typename T> // T can be A, B or C.\n"
+ "struct C {};",
+ Style);
+
+ verifyNoChange("template <typename T>\n"
+ "C(T) noexcept;",
+ Style);
+ verifyFormat("template <typename T> C(T) noexcept;", Style);
+
+ verifyNoChange("template <typename T>\n"
+ "ClassName(T) noexcept;",
+ Style);
+ verifyFormat("template <typename T> ClassName(T) noexcept;", Style);
+
+ verifyNoChange("template <typename T>\n"
+ "POOR_NAME(T) noexcept;",
+ Style);
+ verifyFormat("template <typename T> POOR_NAME(T) noexcept;", Style);
+
+ verifyNoChange("template <enum E>\n"
+ "class A {\n"
+ "public:\n"
+ " E *f();\n"
+ "};",
+ Style);
+ verifyFormat("template <enum E> class A {\n"
+ "public:\n"
+ " E *f();\n"
+ "};",
+ Style);
+
+ verifyNoChange("template <auto x>\n"
+ "constexpr int simple(int) {\n"
+ " char c;\n"
+ " return 1;\n"
+ "}",
+ Style);
+ verifyFormat("template <auto x> constexpr int simple(int) {\n"
+ " char c;\n"
+ " return 1;\n"
+ "}",
+ Style);
+
+ Style.RequiresClausePosition = FormatStyle::RCPS_WithPreceding;
+ verifyNoChange("template <auto x>\n"
+ "requires(x > 1)\n"
+ "constexpr int with_req(int) {\n"
+ " return 1;\n"
+ "}",
+ Style);
+ verifyFormat("template <auto x> requires(x > 1)\n"
+ "constexpr int with_req(int) {\n"
+ " return 1;\n"
+ "}",
+ Style);
}
TEST_F(FormatTest, WrapsTemplateDeclarationsWithComments) {
|
owenca
requested review from
HazardyKnusperkeks,
mydeveloperday and
rymiel
and removed request for
HazardyKnusperkeks
February 7, 2024 04:47
HazardyKnusperkeks
approved these changes
Feb 7, 2024
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Closes #78067.