[clang] [clang-format] Add BreakBeforeTemplateClose option (PR #118046)
@@ -11224,6 +11224,254 @@ TEST_F(FormatTest, WrapsTemplateDeclarationsWithComments) { Style); } +TEST_F(FormatTest, BreakBeforeTemplateCloser) { + FormatStyle Style = getLLVMStyle(); + // Begin with tests covering the case where there is no constraint on the + // column limit. + Style.ColumnLimit = 0; + Style.BreakBeforeTemplateCloser = true; + // BreakBeforeTemplateCloser should NOT force template declarations onto + // multiple lines. + verifyFormat("template \n" + "void foo() {}", + Style); + verifyFormat("template \n" + "void foo() {}", + Style); + // It should add a line break before > if not already present: + verifyFormat("template <\n" + "typename Foo\n" + ">\n" + "void foo() {}", + "template <\n" + "typename Foo>\n" + "void foo() {}", + Style); + verifyFormat("template <\n" + "typename Foo,\n" + "typename Bar\n" + ">\n" + "void foo() {}", + "template <\n" + "typename Foo,\n" + "typename Bar>\n" + "void foo() {}", + Style); + // When within an indent scope, the > should be placed accordingly: + verifyFormat("struct Baz {\n" + " template <\n" + " typename Foo,\n" + " typename Bar\n" + " >\n" + " void foo() {}\n" + "};", + "struct Baz {\n" + " template <\n" + " typename Foo,\n" + " typename Bar>\n" + " void foo() {}\n" + "};", + Style); + + // Test from https://github.com/llvm/llvm-project/issues/80049: + verifyFormat( + "using type = std::remove_cv_t<\n" + "add_common_cv_reference<\n" + "std::common_type_t, std::decay_t>,\n" + "T0,\n" + "T1\n" + ">\n" + ">;", + "using type = std::remove_cv_t<\n" + "add_common_cv_reference<\n" + "std::common_type_t, std::decay_t>,\n" + "T0,\n" + "T1>>;", + Style); + + // Test lambda goes to next line: + verifyFormat("void foo() {\n" + " auto lambda = []<\n" + "typename T\n" + ">(T t) {\n" + " };\n" + "}", + "void foo() {\n" + " auto lambda = []<\n" + " typename T>(T t){\n" + " };\n" + "}", + Style); + // With no column limit, two parameters can go on the same line: + verifyFormat("void foo() {\n" + " auto lambda = []<\n" + "typename T, typename Foo\n" + ">(T t) {\n" + " };\n" + "}", + "void foo() {\n" + " auto lambda = []<\n" + " typename T, typename Foo>(T t){\n" + " };\n" + "}", + Style); + // Or on different lines: + verifyFormat("void foo() {\n" + " auto lambda = []<\n" + "typename T,\n" + "typename Foo\n" + ">(T t) {\n" + " };\n" + "}", + "void foo() {\n" + " auto lambda = []<\n" + " typename T,\n" + " typename Foo>(T t){\n" + " };\n" + "}", + Style); + + // Test template usage goes to next line too: + verifyFormat("void foo() {\n" + " myFunc<\n" + " T\n" + " >();\n" + "}", + "void foo() {\n" + " myFunc<\n" + " T>();\n" + "}", + Style); + + // Now test that it handles the cases when the column limit forces wrapping. + Style.ColumnLimit = 40; + // Breaks when the name is looong. Note that these names are exactly 1 + // character too long for the ColumnLimit. + verifyFormat("template <\n" + "typename Foo,\n" + "typename Barrr\n" + ">\n" + "void foo() {}", + Style); + // BlockIndent style is used when the ColumnLimit allows it: + verifyFormat("template \n" + "void foo() {}", + Style); + verifyFormat("template \n" + "void foo() {}", + Style); owenca wrote: > However, these other two I don't think are tested anymore? > > ```c++ > verifyFormat("template " typename Barr>\n" >"void foo() {}", >
[clang] [clang-format] Add BreakBeforeTemplateClose option (PR #118046)
@@ -11224,6 +11224,254 @@ TEST_F(FormatTest, WrapsTemplateDeclarationsWithComments) { Style); } +TEST_F(FormatTest, BreakBeforeTemplateCloser) { + FormatStyle Style = getLLVMStyle(); + // Begin with tests covering the case where there is no constraint on the + // column limit. + Style.ColumnLimit = 0; + Style.BreakBeforeTemplateCloser = true; + // BreakBeforeTemplateCloser should NOT force template declarations onto + // multiple lines. + verifyFormat("template \n" + "void foo() {}", + Style); + verifyFormat("template \n" + "void foo() {}", + Style); + // It should add a line break before > if not already present: + verifyFormat("template <\n" + "typename Foo\n" + ">\n" + "void foo() {}", + "template <\n" + "typename Foo>\n" + "void foo() {}", + Style); + verifyFormat("template <\n" + "typename Foo,\n" + "typename Bar\n" + ">\n" + "void foo() {}", + "template <\n" + "typename Foo,\n" + "typename Bar>\n" + "void foo() {}", + Style); + // When within an indent scope, the > should be placed accordingly: + verifyFormat("struct Baz {\n" + " template <\n" + " typename Foo,\n" + " typename Bar\n" + " >\n" + " void foo() {}\n" + "};", + "struct Baz {\n" + " template <\n" + " typename Foo,\n" + " typename Bar>\n" + " void foo() {}\n" + "};", + Style); + + // Test from https://github.com/llvm/llvm-project/issues/80049: + verifyFormat( + "using type = std::remove_cv_t<\n" + "add_common_cv_reference<\n" + "std::common_type_t, std::decay_t>,\n" + "T0,\n" + "T1\n" + ">\n" + ">;", + "using type = std::remove_cv_t<\n" + "add_common_cv_reference<\n" + "std::common_type_t, std::decay_t>,\n" + "T0,\n" + "T1>>;", + Style); + + // Test lambda goes to next line: + verifyFormat("void foo() {\n" + " auto lambda = []<\n" + "typename T\n" + ">(T t) {\n" + " };\n" + "}", + "void foo() {\n" + " auto lambda = []<\n" + " typename T>(T t){\n" + " };\n" + "}", + Style); + // With no column limit, two parameters can go on the same line: + verifyFormat("void foo() {\n" + " auto lambda = []<\n" + "typename T, typename Foo\n" + ">(T t) {\n" + " };\n" + "}", + "void foo() {\n" + " auto lambda = []<\n" + " typename T, typename Foo>(T t){\n" + " };\n" + "}", + Style); + // Or on different lines: + verifyFormat("void foo() {\n" + " auto lambda = []<\n" + "typename T,\n" + "typename Foo\n" + ">(T t) {\n" + " };\n" + "}", + "void foo() {\n" + " auto lambda = []<\n" + " typename T,\n" + " typename Foo>(T t){\n" + " };\n" + "}", + Style); + + // Test template usage goes to next line too: + verifyFormat("void foo() {\n" + " myFunc<\n" + " T\n" + " >();\n" + "}", + "void foo() {\n" + " myFunc<\n" + " T>();\n" + "}", + Style); + + // Now test that it handles the cases when the column limit forces wrapping. + Style.ColumnLimit = 40; + // Breaks when the name is looong. Note that these names are exactly 1 + // character too long for the ColumnLimit. + verifyFormat("template <\n" + "typename Foo,\n" + "typename Barrr\n" + ">\n" + "void foo() {}", + Style); + // BlockIndent style is used when the ColumnLimit allows it: + verifyFormat("template \n" + "void foo() {}", + Style); + verifyFormat("template \n" + "void foo() {}", + Style); owenca wrote: IIRC we agreed that these 3 test cases are redundant? https://github.com/llvm/llvm-project/pull/118046 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https:
[clang] [clang-format] Add BreakBeforeTemplateClose option (PR #118046)
@@ -11224,6 +11224,254 @@ TEST_F(FormatTest, WrapsTemplateDeclarationsWithComments) { Style); } +TEST_F(FormatTest, BreakBeforeTemplateCloser) { + FormatStyle Style = getLLVMStyle(); + // Begin with tests covering the case where there is no constraint on the + // column limit. + Style.ColumnLimit = 0; + Style.BreakBeforeTemplateCloser = true; + // BreakBeforeTemplateCloser should NOT force template declarations onto + // multiple lines. + verifyFormat("template \n" + "void foo() {}", + Style); + verifyFormat("template \n" + "void foo() {}", + Style); + // It should add a line break before > if not already present: + verifyFormat("template <\n" + "typename Foo\n" + ">\n" + "void foo() {}", + "template <\n" + "typename Foo>\n" + "void foo() {}", + Style); + verifyFormat("template <\n" + "typename Foo,\n" + "typename Bar\n" + ">\n" + "void foo() {}", + "template <\n" + "typename Foo,\n" + "typename Bar>\n" + "void foo() {}", + Style); + // When within an indent scope, the > should be placed accordingly: + verifyFormat("struct Baz {\n" + " template <\n" + " typename Foo,\n" + " typename Bar\n" + " >\n" + " void foo() {}\n" + "};", + "struct Baz {\n" + " template <\n" + " typename Foo,\n" + " typename Bar>\n" + " void foo() {}\n" + "};", + Style); + + // Test from https://github.com/llvm/llvm-project/issues/80049: + verifyFormat( + "using type = std::remove_cv_t<\n" + "add_common_cv_reference<\n" + "std::common_type_t, std::decay_t>,\n" + "T0,\n" + "T1\n" + ">\n" + ">;", + "using type = std::remove_cv_t<\n" + "add_common_cv_reference<\n" + "std::common_type_t, std::decay_t>,\n" + "T0,\n" + "T1>>;", + Style); + + // Test lambda goes to next line: + verifyFormat("void foo() {\n" + " auto lambda = []<\n" + "typename T\n" + ">(T t) {\n" + " };\n" + "}", + "void foo() {\n" + " auto lambda = []<\n" + " typename T>(T t){\n" + " };\n" + "}", + Style); + // With no column limit, two parameters can go on the same line: + verifyFormat("void foo() {\n" + " auto lambda = []<\n" + "typename T, typename Foo\n" + ">(T t) {\n" + " };\n" + "}", + "void foo() {\n" + " auto lambda = []<\n" + " typename T, typename Foo>(T t){\n" + " };\n" + "}", + Style); + // Or on different lines: + verifyFormat("void foo() {\n" + " auto lambda = []<\n" + "typename T,\n" + "typename Foo\n" + ">(T t) {\n" + " };\n" + "}", + "void foo() {\n" + " auto lambda = []<\n" + " typename T,\n" + " typename Foo>(T t){\n" + " };\n" + "}", + Style); + + // Test template usage goes to next line too: + verifyFormat("void foo() {\n" + " myFunc<\n" + " T\n" + " >();\n" + "}", + "void foo() {\n" + " myFunc<\n" + " T>();\n" + "}", + Style); + + // Now test that it handles the cases when the column limit forces wrapping. + Style.ColumnLimit = 40; + // Breaks when the name is looong. Note that these names are exactly 1 + // character too long for the ColumnLimit. + verifyFormat("template <\n" + "typename Foo,\n" + "typename Barrr\n" + ">\n" + "void foo() {}", + Style); + // BlockIndent style is used when the ColumnLimit allows it: + verifyFormat("template \n" + "void foo() {}", + Style); + verifyFormat("template \n" + "void foo() {}", + Style); + // Additionally, long names should be split in one step: + verifyFormat("template <\n" + "typename Foo,\n" + "typename Barrr\n" + ">\n" + "void foo() {}", +
[clang] [clang-format] Add BreakBeforeTemplateClose option (PR #118046)
@@ -304,6 +304,10 @@ bool ContinuationIndenter::canBreak(const LineState &State) { Current.closesBlockOrBlockTypeList(Style))) { return false; } + if (Style.BreakBeforeTemplateCloser && Current.is(TT_TemplateCloser) && + !CurrentState.BreakBeforeClosingAngle) { +return false; + } owenca wrote: ```suggestion if (Style.BreakBeforeTemplateCloser && Current.is(TT_TemplateCloser)) return CurrentState.BreakBeforeClosingAngle; ``` And move this to line 362 below for ease of maintenance. https://github.com/llvm/llvm-project/pull/118046 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang-format] Add BreakBeforeTemplateClose option (PR #118046)
@@ -11224,6 +11224,328 @@ TEST_F(FormatTest, WrapsTemplateDeclarationsWithComments) { Style); } +TEST_F(FormatTest, BreakBeforeTemplateCloser) { + FormatStyle Style = getLLVMStyle(); + // Begin with tests covering the case where there is no constraint on the + // column limit. + Style.ColumnLimit = 0; + // When BreakBeforeTemplateCloser is turned off, the line break that it adds + // shall be removed: + verifyFormat("template <\n" + "typename Foo,\n" + "typename Bar>\n" + "void foo() {}", + "template <\n" + "typename Foo,\n" + "typename Bar\n" + ">\n" + "void foo() {}", + Style); + + Style.BreakBeforeTemplateCloser = true; + // BreakBeforeTemplateCloser should NOT force template declarations onto + // multiple lines. + verifyFormat("template \n" + "void foo() {}", + Style); + verifyFormat("template \n" + "void foo() {}", + Style); + // It should allow a line break, even when the typename is short. + // verifyNoChange is needed because the default behavior is one line. + verifyNoChange("template <\n" + "typename Foo\n" + ">\n" + "void foo() {}", + Style); + verifyNoChange("template <\n" + "typename Foo,\n" + "typename Bar\n" + ">\n" + "void foo() {}", + Style); + verifyNoChange("template \n" + "void foo() {}", + Style); + // It should add a line break before > if not already present: + verifyFormat("template <\n" + "typename Foo\n" + ">\n" + "void foo() {}", + "template <\n" + "typename Foo>\n" + "void foo() {}", + Style); + verifyFormat("template <\n" + "typename Foo,\n" + "typename Bar\n" + ">\n" + "void foo() {}", + "template <\n" + "typename Foo,\n" + "typename Bar>\n" + "void foo() {}", + Style); + // When within an indent scope, the > should be placed accordingly: + verifyFormat("struct Baz {\n" + " template <\n" + " typename Foo,\n" + " typename Bar\n" + " >\n" + " void foo() {}\n" + "};", + "struct Baz {\n" + " template <\n" + " typename Foo,\n" + " typename Bar>\n" + " void foo() {}\n" + "};", + Style); + + // Test from https://github.com/llvm/llvm-project/issues/80049: + verifyFormat( + "using type = std::remove_cv_t<\n" + "add_common_cv_reference<\n" + "std::common_type_t, std::decay_t>,\n" + "T0,\n" + "T1\n" + ">\n" + ">;\n", + "using type = std::remove_cv_t<\n" + "add_common_cv_reference<\n" + "std::common_type_t, std::decay_t>,\n" + "T0,\n" + "T1>>;\n", + Style); + + // Test lambda goes to next line: + verifyFormat("void foo() {\n" + " auto lambda = []<\n" + "typename T\n" + ">(T t) {\n" + " };\n" + "}", + "void foo() {\n" + " auto lambda = []<\n" + " typename T>(T t){\n" + " };\n" + "}", + Style); + // With no column limit, two parameters can go on the same line: + verifyFormat("void foo() {\n" + " auto lambda = []<\n" + "typename T, typename Foo\n" + ">(T t) {\n" + " };\n" + "}", + "void foo() {\n" + " auto lambda = []<\n" + " typename T, typename Foo>(T t){\n" + " };\n" + "}", + Style); + // Or on different lines: + verifyFormat("void foo() {\n" + " auto lambda = []<\n" + "typename T,\n" + "typename Foo\n" + ">(T t) {\n" + " };\n" + "}", + "void foo() {\n" + " auto lambda = []<\n" + " typename T,\n" + " typename Foo>(T t){\n" + " };\n" + "}", + Style); + + // Note that this is the same line (no \n): + verifyFormat("void foo() {\n" + " auto lambda = [](T t) {};\n" + "}", + Style); + leijurv wrote: Gotch
[clang] [clang-format] Add BreakBeforeTemplateClose option (PR #118046)
@@ -11224,6 +11224,328 @@ TEST_F(FormatTest, WrapsTemplateDeclarationsWithComments) { Style); } +TEST_F(FormatTest, BreakBeforeTemplateCloser) { + FormatStyle Style = getLLVMStyle(); + // Begin with tests covering the case where there is no constraint on the + // column limit. + Style.ColumnLimit = 0; + // When BreakBeforeTemplateCloser is turned off, the line break that it adds + // shall be removed: + verifyFormat("template <\n" + "typename Foo,\n" + "typename Bar>\n" + "void foo() {}", + "template <\n" + "typename Foo,\n" + "typename Bar\n" + ">\n" + "void foo() {}", + Style); + + Style.BreakBeforeTemplateCloser = true; + // BreakBeforeTemplateCloser should NOT force template declarations onto + // multiple lines. + verifyFormat("template \n" + "void foo() {}", + Style); + verifyFormat("template \n" + "void foo() {}", + Style); + // It should allow a line break, even when the typename is short. + // verifyNoChange is needed because the default behavior is one line. + verifyNoChange("template <\n" + "typename Foo\n" + ">\n" + "void foo() {}", + Style); + verifyNoChange("template <\n" + "typename Foo,\n" + "typename Bar\n" + ">\n" + "void foo() {}", + Style); + verifyNoChange("template \n" + "void foo() {}", + Style); + // It should add a line break before > if not already present: + verifyFormat("template <\n" + "typename Foo\n" + ">\n" + "void foo() {}", + "template <\n" + "typename Foo>\n" + "void foo() {}", + Style); + verifyFormat("template <\n" + "typename Foo,\n" + "typename Bar\n" + ">\n" + "void foo() {}", + "template <\n" + "typename Foo,\n" + "typename Bar>\n" + "void foo() {}", + Style); + // When within an indent scope, the > should be placed accordingly: + verifyFormat("struct Baz {\n" + " template <\n" + " typename Foo,\n" + " typename Bar\n" + " >\n" + " void foo() {}\n" + "};", + "struct Baz {\n" + " template <\n" + " typename Foo,\n" + " typename Bar>\n" + " void foo() {}\n" + "};", + Style); + + // Test from https://github.com/llvm/llvm-project/issues/80049: + verifyFormat( + "using type = std::remove_cv_t<\n" + "add_common_cv_reference<\n" + "std::common_type_t, std::decay_t>,\n" + "T0,\n" + "T1\n" + ">\n" + ">;\n", + "using type = std::remove_cv_t<\n" + "add_common_cv_reference<\n" + "std::common_type_t, std::decay_t>,\n" + "T0,\n" + "T1>>;\n", + Style); + + // Test lambda goes to next line: + verifyFormat("void foo() {\n" + " auto lambda = []<\n" + "typename T\n" + ">(T t) {\n" + " };\n" + "}", + "void foo() {\n" + " auto lambda = []<\n" + " typename T>(T t){\n" + " };\n" + "}", + Style); + // With no column limit, two parameters can go on the same line: + verifyFormat("void foo() {\n" + " auto lambda = []<\n" + "typename T, typename Foo\n" + ">(T t) {\n" + " };\n" + "}", + "void foo() {\n" + " auto lambda = []<\n" + " typename T, typename Foo>(T t){\n" + " };\n" + "}", + Style); + // Or on different lines: + verifyFormat("void foo() {\n" + " auto lambda = []<\n" + "typename T,\n" + "typename Foo\n" + ">(T t) {\n" + " };\n" + "}", + "void foo() {\n" + " auto lambda = []<\n" + " typename T,\n" + " typename Foo>(T t){\n" + " };\n" + "}", + Style); + + // Note that this is the same line (no \n): + verifyFormat("void foo() {\n" + " auto lambda = [](T t) {};\n" + "}", + Style); + owenca wrote: That s
[clang] [clang-format] Add BreakBeforeTemplateClose option (PR #118046)
leijurv wrote: Ah, it resolved itself as of https://github.com/leijurv/llvm-project/commit/b6219e250b80114c9b93a7762db7c3e0cbd84260 https://github.com/llvm/llvm-project/pull/118046 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang-format] Add BreakBeforeTemplateClose option (PR #118046)
https://github.com/leijurv edited https://github.com/llvm/llvm-project/pull/118046 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang-format] Add BreakBeforeTemplateClose option (PR #118046)
@@ -11224,6 +11224,328 @@ TEST_F(FormatTest, WrapsTemplateDeclarationsWithComments) { Style); } +TEST_F(FormatTest, BreakBeforeTemplateCloser) { + FormatStyle Style = getLLVMStyle(); + // Begin with tests covering the case where there is no constraint on the + // column limit. + Style.ColumnLimit = 0; + // When BreakBeforeTemplateCloser is turned off, the line break that it adds + // shall be removed: + verifyFormat("template <\n" + "typename Foo,\n" + "typename Bar>\n" + "void foo() {}", + "template <\n" + "typename Foo,\n" + "typename Bar\n" + ">\n" + "void foo() {}", + Style); + + Style.BreakBeforeTemplateCloser = true; + // BreakBeforeTemplateCloser should NOT force template declarations onto + // multiple lines. + verifyFormat("template \n" + "void foo() {}", + Style); + verifyFormat("template \n" + "void foo() {}", + Style); + // It should allow a line break, even when the typename is short. + // verifyNoChange is needed because the default behavior is one line. + verifyNoChange("template <\n" + "typename Foo\n" + ">\n" + "void foo() {}", + Style); + verifyNoChange("template <\n" + "typename Foo,\n" + "typename Bar\n" + ">\n" + "void foo() {}", + Style); leijurv wrote: I was unaware of that! That explains a lot of redundancies that I now agree with you about. Removed: https://github.com/leijurv/llvm-project/commit/b6219e250b80114c9b93a7762db7c3e0cbd84260 https://github.com/llvm/llvm-project/pull/118046 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang-format] Add BreakBeforeTemplateClose option (PR #118046)
https://github.com/leijurv updated https://github.com/llvm/llvm-project/pull/118046 >From 1caf823165b16f6701993d586df51d5cdbf0885e Mon Sep 17 00:00:00 2001 From: Leijurv Date: Fri, 29 Nov 2024 21:54:36 -0600 Subject: [PATCH 01/19] [clang-format] Add BreakBeforeTemplateClose option --- clang/docs/ClangFormatStyleOptions.rst | 21 clang/docs/ReleaseNotes.rst| 1 + clang/include/clang/Format/Format.h| 20 clang/lib/Format/ContinuationIndenter.cpp | 11 ++ clang/lib/Format/ContinuationIndenter.h| 26 ++-- clang/lib/Format/Format.cpp| 2 + clang/lib/Format/TokenAnnotator.cpp| 2 +- clang/unittests/Format/ConfigParseTest.cpp | 1 + clang/unittests/Format/FormatTest.cpp | 131 + 9 files changed, 206 insertions(+), 9 deletions(-) diff --git a/clang/docs/ClangFormatStyleOptions.rst b/clang/docs/ClangFormatStyleOptions.rst index 4be448171699ca..84ab1b0a2eff61 100644 --- a/clang/docs/ClangFormatStyleOptions.rst +++ b/clang/docs/ClangFormatStyleOptions.rst @@ -3416,6 +3416,27 @@ the configuration (without a prefix: ``Auto``). +.. _BreakBeforeTemplateClose: + +**BreakBeforeTemplateClose** (``Boolean``) :versionbadge:`clang-format 20` :ref:`¶ ` + If ``true``, a line break will be placed before the ``>`` in a multiline + template declaration. + + .. code-block:: c++ + + true: + template < + typename Foo, + typename Bar, + typename Baz + > + + false: + template < + typename Foo, + typename Bar, + typename Baz> + .. _BreakBeforeTernaryOperators: **BreakBeforeTernaryOperators** (``Boolean``) :versionbadge:`clang-format 3.7` :ref:`¶ ` diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst index e44aefa90ab386..867d4b5d8c3f18 100644 --- a/clang/docs/ReleaseNotes.rst +++ b/clang/docs/ReleaseNotes.rst @@ -976,6 +976,7 @@ clang-format ``Never``, and ``true`` to ``Always``. - Adds ``RemoveEmptyLinesInUnwrappedLines`` option. - Adds ``KeepFormFeed`` option and set it to ``true`` for ``GNU`` style. +- Adds ``BreakBeforeTemplateClose`` option. libclang diff --git a/clang/include/clang/Format/Format.h b/clang/include/clang/Format/Format.h index 6383934afa2c40..bffd964f6aa8aa 100644 --- a/clang/include/clang/Format/Format.h +++ b/clang/include/clang/Format/Format.h @@ -2248,6 +2248,25 @@ struct FormatStyle { /// \version 16 BreakBeforeInlineASMColonStyle BreakBeforeInlineASMColon; + /// If ``true``, a line break will be placed before the ``>`` in a multiline + /// template declaration. + /// \code + ///true: + ///template < + ///typename Foo, + ///typename Bar, + ///typename Baz + ///> + /// + ///false: + ///template < + ///typename Foo, + ///typename Bar, + ///typename Baz> + /// \endcode + /// \version 20 + bool BreakBeforeTemplateClose; + /// If ``true``, ternary operators will be placed after line breaks. /// \code ///true: @@ -5184,6 +5203,7 @@ struct FormatStyle { BreakBeforeBraces == R.BreakBeforeBraces && BreakBeforeConceptDeclarations == R.BreakBeforeConceptDeclarations && BreakBeforeInlineASMColon == R.BreakBeforeInlineASMColon && + BreakBeforeTemplateClose == R.BreakBeforeTemplateClose && BreakBeforeTernaryOperators == R.BreakBeforeTernaryOperators && BreakBinaryOperations == R.BreakBinaryOperations && BreakConstructorInitializers == R.BreakConstructorInitializers && diff --git a/clang/lib/Format/ContinuationIndenter.cpp b/clang/lib/Format/ContinuationIndenter.cpp index aed86c1fb99551..4c783623afc535 100644 --- a/clang/lib/Format/ContinuationIndenter.cpp +++ b/clang/lib/Format/ContinuationIndenter.cpp @@ -406,6 +406,10 @@ bool ContinuationIndenter::mustBreak(const LineState &State) { } if (CurrentState.BreakBeforeClosingParen && Current.is(tok::r_paren)) return true; + if (CurrentState.BreakBeforeClosingAngle && + Current.ClosesTemplateDeclaration && Style.BreakBeforeTemplateClose) { +return true; + } if (Style.Language == FormatStyle::LK_ObjC && Style.ObjCBreakBeforeNestedBlockParam && Current.ObjCSelectorNameParts > 1 && @@ -1234,6 +1238,9 @@ unsigned ContinuationIndenter::addTokenOnNewLine(LineState &State, Style.AlignAfterOpenBracket == FormatStyle::BAS_BlockIndent; } + if (PreviousNonComment && PreviousNonComment->is(tok::less)) +CurrentState.BreakBeforeClosingAngle = true; + if (CurrentState.AvoidBinPacking) { // If we are breaking after '(', '{', '<', or this is the break after a ':' // to start a member initializer list in a constructor, this should not @@ -1370,6 +1377,10 @@ unsigned ContinuationIndenter::getNewLineColumn(const LineState &State) { State.Stack.size() > 1) { return State.Stack[State.Stack.size() - 2].La
[clang] [clang-format] Add BreakBeforeTemplateClose option (PR #118046)
leijurv wrote: GitHub is having issues it appears - the commit https://github.com/leijurv/llvm-project/commit/e1eaba9b05b00adf44628e2ceb1b3374fec902cb is certainly pushed, and I even tried pushing an empty commit on top to kick github into working, https://github.com/leijurv/llvm-project/commit/7d456ca2457dc7d7d2403562386097880bedaa34 but still this PR is in a glitched state that doesn't show those commits... https://github.com/user-attachments/assets/9b48ee20-9da8-434c-8986-9445f143f2b9"; /> https://github.com/llvm/llvm-project/pull/118046 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang-format] Add BreakBeforeTemplateClose option (PR #118046)
@@ -11224,6 +11224,328 @@ TEST_F(FormatTest, WrapsTemplateDeclarationsWithComments) { Style); } +TEST_F(FormatTest, BreakBeforeTemplateCloser) { + FormatStyle Style = getLLVMStyle(); + // Begin with tests covering the case where there is no constraint on the + // column limit. + Style.ColumnLimit = 0; + // When BreakBeforeTemplateCloser is turned off, the line break that it adds + // shall be removed: + verifyFormat("template <\n" + "typename Foo,\n" + "typename Bar>\n" + "void foo() {}", + "template <\n" + "typename Foo,\n" + "typename Bar\n" + ">\n" + "void foo() {}", + Style); + + Style.BreakBeforeTemplateCloser = true; + // BreakBeforeTemplateCloser should NOT force template declarations onto + // multiple lines. + verifyFormat("template \n" + "void foo() {}", + Style); + verifyFormat("template \n" + "void foo() {}", + Style); leijurv wrote: I apologize, it appears that in my commit https://github.com/leijurv/llvm-project/commit/e1eaba9b05b00adf44628e2ceb1b3374fec902cb I missed removing this one, bit of a coincidence (I swear it wasn't on purpose). I have just now triple checked to ensure that all your other comments were indeed addressed, I believe I only missed this one. https://github.com/llvm/llvm-project/pull/118046 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang-format] Add BreakBeforeTemplateClose option (PR #118046)
@@ -11224,6 +11224,328 @@ TEST_F(FormatTest, WrapsTemplateDeclarationsWithComments) { Style); } +TEST_F(FormatTest, BreakBeforeTemplateCloser) { + FormatStyle Style = getLLVMStyle(); + // Begin with tests covering the case where there is no constraint on the + // column limit. + Style.ColumnLimit = 0; + // When BreakBeforeTemplateCloser is turned off, the line break that it adds + // shall be removed: + verifyFormat("template <\n" + "typename Foo,\n" + "typename Bar>\n" + "void foo() {}", + "template <\n" + "typename Foo,\n" + "typename Bar\n" + ">\n" + "void foo() {}", + Style); + + Style.BreakBeforeTemplateCloser = true; + // BreakBeforeTemplateCloser should NOT force template declarations onto + // multiple lines. + verifyFormat("template \n" + "void foo() {}", + Style); + verifyFormat("template \n" + "void foo() {}", + Style); + // It should allow a line break, even when the typename is short. + // verifyNoChange is needed because the default behavior is one line. + verifyNoChange("template <\n" + "typename Foo\n" + ">\n" + "void foo() {}", + Style); + verifyNoChange("template <\n" + "typename Foo,\n" + "typename Bar\n" + ">\n" + "void foo() {}", + Style); owenca wrote: As I explained, they are already tested by "the test cases at lines 11272 and 11280 below" as the two-argument version of `verifyFormat()` first checks that the input is formatted to the expected output and then ensures that the expected output doesn't change when being formatted. In other words, `verifyFormat(Output, Input)` also does `verifyNoChange(Output)`. https://github.com/llvm/llvm-project/pull/118046 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang-format] Add BreakBeforeTemplateClose option (PR #118046)
@@ -11224,6 +11224,328 @@ TEST_F(FormatTest, WrapsTemplateDeclarationsWithComments) { Style); } +TEST_F(FormatTest, BreakBeforeTemplateCloser) { + FormatStyle Style = getLLVMStyle(); + // Begin with tests covering the case where there is no constraint on the + // column limit. + Style.ColumnLimit = 0; + // When BreakBeforeTemplateCloser is turned off, the line break that it adds + // shall be removed: + verifyFormat("template <\n" + "typename Foo,\n" + "typename Bar>\n" + "void foo() {}", + "template <\n" + "typename Foo,\n" + "typename Bar\n" + ">\n" + "void foo() {}", + Style); + + Style.BreakBeforeTemplateCloser = true; + // BreakBeforeTemplateCloser should NOT force template declarations onto + // multiple lines. + verifyFormat("template \n" + "void foo() {}", + Style); + verifyFormat("template \n" + "void foo() {}", + Style); owenca wrote: You can add them back if you prefer. https://github.com/llvm/llvm-project/pull/118046 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang-format] Add BreakBeforeTemplateClose option (PR #118046)
@@ -11224,6 +11224,328 @@ TEST_F(FormatTest, WrapsTemplateDeclarationsWithComments) { Style); } +TEST_F(FormatTest, BreakBeforeTemplateCloser) { + FormatStyle Style = getLLVMStyle(); + // Begin with tests covering the case where there is no constraint on the + // column limit. + Style.ColumnLimit = 0; + // When BreakBeforeTemplateCloser is turned off, the line break that it adds + // shall be removed: + verifyFormat("template <\n" + "typename Foo,\n" + "typename Bar>\n" + "void foo() {}", + "template <\n" + "typename Foo,\n" + "typename Bar\n" + ">\n" + "void foo() {}", + Style); + + Style.BreakBeforeTemplateCloser = true; + // BreakBeforeTemplateCloser should NOT force template declarations onto + // multiple lines. + verifyFormat("template \n" + "void foo() {}", + Style); + verifyFormat("template \n" + "void foo() {}", + Style); + // It should allow a line break, even when the typename is short. + // verifyNoChange is needed because the default behavior is one line. + verifyNoChange("template <\n" + "typename Foo\n" + ">\n" + "void foo() {}", + Style); + verifyNoChange("template <\n" + "typename Foo,\n" + "typename Bar\n" + ">\n" + "void foo() {}", + Style); + verifyNoChange("template \n" + "void foo() {}", + Style); + // It should add a line break before > if not already present: + verifyFormat("template <\n" + "typename Foo\n" + ">\n" + "void foo() {}", + "template <\n" + "typename Foo>\n" + "void foo() {}", + Style); + verifyFormat("template <\n" + "typename Foo,\n" + "typename Bar\n" + ">\n" + "void foo() {}", + "template <\n" + "typename Foo,\n" + "typename Bar>\n" + "void foo() {}", + Style); + // When within an indent scope, the > should be placed accordingly: + verifyFormat("struct Baz {\n" + " template <\n" + " typename Foo,\n" + " typename Bar\n" + " >\n" + " void foo() {}\n" + "};", + "struct Baz {\n" + " template <\n" + " typename Foo,\n" + " typename Bar>\n" + " void foo() {}\n" + "};", + Style); + + // Test from https://github.com/llvm/llvm-project/issues/80049: + verifyFormat( + "using type = std::remove_cv_t<\n" + "add_common_cv_reference<\n" + "std::common_type_t, std::decay_t>,\n" + "T0,\n" + "T1\n" + ">\n" + ">;\n", + "using type = std::remove_cv_t<\n" + "add_common_cv_reference<\n" + "std::common_type_t, std::decay_t>,\n" + "T0,\n" + "T1>>;\n", + Style); + + // Test lambda goes to next line: + verifyFormat("void foo() {\n" + " auto lambda = []<\n" + "typename T\n" + ">(T t) {\n" + " };\n" + "}", + "void foo() {\n" + " auto lambda = []<\n" + " typename T>(T t){\n" + " };\n" + "}", + Style); + // With no column limit, two parameters can go on the same line: + verifyFormat("void foo() {\n" + " auto lambda = []<\n" + "typename T, typename Foo\n" + ">(T t) {\n" + " };\n" + "}", + "void foo() {\n" + " auto lambda = []<\n" + " typename T, typename Foo>(T t){\n" + " };\n" + "}", + Style); + // Or on different lines: + verifyFormat("void foo() {\n" + " auto lambda = []<\n" + "typename T,\n" + "typename Foo\n" + ">(T t) {\n" + " };\n" + "}", + "void foo() {\n" + " auto lambda = []<\n" + " typename T,\n" + " typename Foo>(T t){\n" + " };\n" + "}", + Style); + + // Note that this is the same line (no \n): + verifyFormat("void foo() {\n" + " auto lambda = [](T t) {};\n" + "}", + Style); + + // Test template usage goes to next
[clang] [clang-format] Add BreakBeforeTemplateClose option (PR #118046)
@@ -11224,6 +11224,328 @@ TEST_F(FormatTest, WrapsTemplateDeclarationsWithComments) { Style); } +TEST_F(FormatTest, BreakBeforeTemplateCloser) { + FormatStyle Style = getLLVMStyle(); + // Begin with tests covering the case where there is no constraint on the + // column limit. + Style.ColumnLimit = 0; + // When BreakBeforeTemplateCloser is turned off, the line break that it adds + // shall be removed: + verifyFormat("template <\n" + "typename Foo,\n" + "typename Bar>\n" + "void foo() {}", + "template <\n" + "typename Foo,\n" + "typename Bar\n" + ">\n" + "void foo() {}", + Style); + + Style.BreakBeforeTemplateCloser = true; + // BreakBeforeTemplateCloser should NOT force template declarations onto + // multiple lines. + verifyFormat("template \n" + "void foo() {}", + Style); + verifyFormat("template \n" + "void foo() {}", + Style); + // It should allow a line break, even when the typename is short. + // verifyNoChange is needed because the default behavior is one line. + verifyNoChange("template <\n" + "typename Foo\n" + ">\n" + "void foo() {}", + Style); + verifyNoChange("template <\n" + "typename Foo,\n" + "typename Bar\n" + ">\n" + "void foo() {}", + Style); + verifyNoChange("template \n" + "void foo() {}", + Style); + // It should add a line break before > if not already present: + verifyFormat("template <\n" + "typename Foo\n" + ">\n" + "void foo() {}", + "template <\n" + "typename Foo>\n" + "void foo() {}", + Style); + verifyFormat("template <\n" + "typename Foo,\n" + "typename Bar\n" + ">\n" + "void foo() {}", + "template <\n" + "typename Foo,\n" + "typename Bar>\n" + "void foo() {}", + Style); + // When within an indent scope, the > should be placed accordingly: + verifyFormat("struct Baz {\n" + " template <\n" + " typename Foo,\n" + " typename Bar\n" + " >\n" + " void foo() {}\n" + "};", + "struct Baz {\n" + " template <\n" + " typename Foo,\n" + " typename Bar>\n" + " void foo() {}\n" + "};", + Style); + + // Test from https://github.com/llvm/llvm-project/issues/80049: + verifyFormat( + "using type = std::remove_cv_t<\n" + "add_common_cv_reference<\n" + "std::common_type_t, std::decay_t>,\n" + "T0,\n" + "T1\n" + ">\n" + ">;\n", + "using type = std::remove_cv_t<\n" + "add_common_cv_reference<\n" + "std::common_type_t, std::decay_t>,\n" + "T0,\n" + "T1>>;\n", + Style); + + // Test lambda goes to next line: + verifyFormat("void foo() {\n" + " auto lambda = []<\n" + "typename T\n" + ">(T t) {\n" + " };\n" + "}", + "void foo() {\n" + " auto lambda = []<\n" + " typename T>(T t){\n" + " };\n" + "}", + Style); + // With no column limit, two parameters can go on the same line: + verifyFormat("void foo() {\n" + " auto lambda = []<\n" + "typename T, typename Foo\n" + ">(T t) {\n" + " };\n" + "}", + "void foo() {\n" + " auto lambda = []<\n" + " typename T, typename Foo>(T t){\n" + " };\n" + "}", + Style); + // Or on different lines: + verifyFormat("void foo() {\n" + " auto lambda = []<\n" + "typename T,\n" + "typename Foo\n" + ">(T t) {\n" + " };\n" + "}", + "void foo() {\n" + " auto lambda = []<\n" + " typename T,\n" + " typename Foo>(T t){\n" + " };\n" + "}", + Style); + + // Note that this is the same line (no \n): + verifyFormat("void foo() {\n" + " auto lambda = [](T t) {};\n" + "}", + Style); + + // Test template usage goes to next
[clang] [clang-format] Add BreakBeforeTemplateClose option (PR #118046)
@@ -11224,6 +11224,328 @@ TEST_F(FormatTest, WrapsTemplateDeclarationsWithComments) { Style); } +TEST_F(FormatTest, BreakBeforeTemplateCloser) { + FormatStyle Style = getLLVMStyle(); + // Begin with tests covering the case where there is no constraint on the + // column limit. + Style.ColumnLimit = 0; + // When BreakBeforeTemplateCloser is turned off, the line break that it adds + // shall be removed: + verifyFormat("template <\n" + "typename Foo,\n" + "typename Bar>\n" + "void foo() {}", + "template <\n" + "typename Foo,\n" + "typename Bar\n" + ">\n" + "void foo() {}", + Style); + + Style.BreakBeforeTemplateCloser = true; + // BreakBeforeTemplateCloser should NOT force template declarations onto + // multiple lines. + verifyFormat("template \n" + "void foo() {}", + Style); + verifyFormat("template \n" + "void foo() {}", + Style); + // It should allow a line break, even when the typename is short. + // verifyNoChange is needed because the default behavior is one line. + verifyNoChange("template <\n" + "typename Foo\n" + ">\n" + "void foo() {}", + Style); + verifyNoChange("template <\n" + "typename Foo,\n" + "typename Bar\n" + ">\n" + "void foo() {}", + Style); + verifyNoChange("template \n" + "void foo() {}", + Style); + // It should add a line break before > if not already present: + verifyFormat("template <\n" + "typename Foo\n" + ">\n" + "void foo() {}", + "template <\n" + "typename Foo>\n" + "void foo() {}", + Style); + verifyFormat("template <\n" + "typename Foo,\n" + "typename Bar\n" + ">\n" + "void foo() {}", + "template <\n" + "typename Foo,\n" + "typename Bar>\n" + "void foo() {}", + Style); + // When within an indent scope, the > should be placed accordingly: + verifyFormat("struct Baz {\n" + " template <\n" + " typename Foo,\n" + " typename Bar\n" + " >\n" + " void foo() {}\n" + "};", + "struct Baz {\n" + " template <\n" + " typename Foo,\n" + " typename Bar>\n" + " void foo() {}\n" + "};", + Style); + + // Test from https://github.com/llvm/llvm-project/issues/80049: + verifyFormat( + "using type = std::remove_cv_t<\n" + "add_common_cv_reference<\n" + "std::common_type_t, std::decay_t>,\n" + "T0,\n" + "T1\n" + ">\n" + ">;\n", + "using type = std::remove_cv_t<\n" + "add_common_cv_reference<\n" + "std::common_type_t, std::decay_t>,\n" + "T0,\n" + "T1>>;\n", + Style); + + // Test lambda goes to next line: + verifyFormat("void foo() {\n" + " auto lambda = []<\n" + "typename T\n" + ">(T t) {\n" + " };\n" + "}", + "void foo() {\n" + " auto lambda = []<\n" + " typename T>(T t){\n" + " };\n" + "}", + Style); + // With no column limit, two parameters can go on the same line: + verifyFormat("void foo() {\n" + " auto lambda = []<\n" + "typename T, typename Foo\n" + ">(T t) {\n" + " };\n" + "}", + "void foo() {\n" + " auto lambda = []<\n" + " typename T, typename Foo>(T t){\n" + " };\n" + "}", + Style); + // Or on different lines: + verifyFormat("void foo() {\n" + " auto lambda = []<\n" + "typename T,\n" + "typename Foo\n" + ">(T t) {\n" + " };\n" + "}", + "void foo() {\n" + " auto lambda = []<\n" + " typename T,\n" + " typename Foo>(T t){\n" + " };\n" + "}", + Style); + + // Note that this is the same line (no \n): + verifyFormat("void foo() {\n" + " auto lambda = [](T t) {};\n" + "}", + Style); + + // Test template usage goes to next
[clang] [clang-format] Add BreakBeforeTemplateClose option (PR #118046)
@@ -11224,6 +11224,328 @@ TEST_F(FormatTest, WrapsTemplateDeclarationsWithComments) { Style); } +TEST_F(FormatTest, BreakBeforeTemplateCloser) { + FormatStyle Style = getLLVMStyle(); + // Begin with tests covering the case where there is no constraint on the + // column limit. + Style.ColumnLimit = 0; + // When BreakBeforeTemplateCloser is turned off, the line break that it adds + // shall be removed: + verifyFormat("template <\n" + "typename Foo,\n" + "typename Bar>\n" + "void foo() {}", + "template <\n" + "typename Foo,\n" + "typename Bar\n" + ">\n" + "void foo() {}", + Style); + + Style.BreakBeforeTemplateCloser = true; + // BreakBeforeTemplateCloser should NOT force template declarations onto + // multiple lines. + verifyFormat("template \n" + "void foo() {}", + Style); + verifyFormat("template \n" + "void foo() {}", + Style); + // It should allow a line break, even when the typename is short. + // verifyNoChange is needed because the default behavior is one line. + verifyNoChange("template <\n" + "typename Foo\n" + ">\n" + "void foo() {}", + Style); + verifyNoChange("template <\n" + "typename Foo,\n" + "typename Bar\n" + ">\n" + "void foo() {}", + Style); + verifyNoChange("template \n" + "void foo() {}", + Style); + // It should add a line break before > if not already present: + verifyFormat("template <\n" + "typename Foo\n" + ">\n" + "void foo() {}", + "template <\n" + "typename Foo>\n" + "void foo() {}", + Style); + verifyFormat("template <\n" + "typename Foo,\n" + "typename Bar\n" + ">\n" + "void foo() {}", + "template <\n" + "typename Foo,\n" + "typename Bar>\n" + "void foo() {}", + Style); + // When within an indent scope, the > should be placed accordingly: + verifyFormat("struct Baz {\n" + " template <\n" + " typename Foo,\n" + " typename Bar\n" + " >\n" + " void foo() {}\n" + "};", + "struct Baz {\n" + " template <\n" + " typename Foo,\n" + " typename Bar>\n" + " void foo() {}\n" + "};", + Style); + + // Test from https://github.com/llvm/llvm-project/issues/80049: + verifyFormat( + "using type = std::remove_cv_t<\n" + "add_common_cv_reference<\n" + "std::common_type_t, std::decay_t>,\n" + "T0,\n" + "T1\n" + ">\n" + ">;\n", + "using type = std::remove_cv_t<\n" + "add_common_cv_reference<\n" + "std::common_type_t, std::decay_t>,\n" + "T0,\n" + "T1>>;\n", + Style); + + // Test lambda goes to next line: + verifyFormat("void foo() {\n" + " auto lambda = []<\n" + "typename T\n" + ">(T t) {\n" + " };\n" + "}", + "void foo() {\n" + " auto lambda = []<\n" + " typename T>(T t){\n" + " };\n" + "}", + Style); + // With no column limit, two parameters can go on the same line: + verifyFormat("void foo() {\n" + " auto lambda = []<\n" + "typename T, typename Foo\n" + ">(T t) {\n" + " };\n" + "}", + "void foo() {\n" + " auto lambda = []<\n" + " typename T, typename Foo>(T t){\n" + " };\n" + "}", + Style); + // Or on different lines: + verifyFormat("void foo() {\n" + " auto lambda = []<\n" + "typename T,\n" + "typename Foo\n" + ">(T t) {\n" + " };\n" + "}", + "void foo() {\n" + " auto lambda = []<\n" + " typename T,\n" + " typename Foo>(T t){\n" + " };\n" + "}", + Style); + + // Note that this is the same line (no \n): + verifyFormat("void foo() {\n" + " auto lambda = [](T t) {};\n" + "}", + Style); + owenca wrote: Delete
[clang] [clang-format] Add BreakBeforeTemplateClose option (PR #118046)
@@ -11224,6 +11224,328 @@ TEST_F(FormatTest, WrapsTemplateDeclarationsWithComments) { Style); } +TEST_F(FormatTest, BreakBeforeTemplateCloser) { + FormatStyle Style = getLLVMStyle(); + // Begin with tests covering the case where there is no constraint on the + // column limit. + Style.ColumnLimit = 0; + // When BreakBeforeTemplateCloser is turned off, the line break that it adds + // shall be removed: + verifyFormat("template <\n" + "typename Foo,\n" + "typename Bar>\n" + "void foo() {}", + "template <\n" + "typename Foo,\n" + "typename Bar\n" + ">\n" + "void foo() {}", + Style); + + Style.BreakBeforeTemplateCloser = true; + // BreakBeforeTemplateCloser should NOT force template declarations onto + // multiple lines. + verifyFormat("template \n" + "void foo() {}", + Style); + verifyFormat("template \n" + "void foo() {}", + Style); + // It should allow a line break, even when the typename is short. + // verifyNoChange is needed because the default behavior is one line. + verifyNoChange("template <\n" + "typename Foo\n" + ">\n" + "void foo() {}", + Style); + verifyNoChange("template <\n" + "typename Foo,\n" + "typename Bar\n" + ">\n" + "void foo() {}", + Style); + verifyNoChange("template \n" + "void foo() {}", + Style); + // It should add a line break before > if not already present: + verifyFormat("template <\n" + "typename Foo\n" + ">\n" + "void foo() {}", + "template <\n" + "typename Foo>\n" + "void foo() {}", + Style); + verifyFormat("template <\n" + "typename Foo,\n" + "typename Bar\n" + ">\n" + "void foo() {}", + "template <\n" + "typename Foo,\n" + "typename Bar>\n" + "void foo() {}", + Style); + // When within an indent scope, the > should be placed accordingly: + verifyFormat("struct Baz {\n" + " template <\n" + " typename Foo,\n" + " typename Bar\n" + " >\n" + " void foo() {}\n" + "};", + "struct Baz {\n" + " template <\n" + " typename Foo,\n" + " typename Bar>\n" + " void foo() {}\n" + "};", + Style); + + // Test from https://github.com/llvm/llvm-project/issues/80049: + verifyFormat( + "using type = std::remove_cv_t<\n" + "add_common_cv_reference<\n" + "std::common_type_t, std::decay_t>,\n" + "T0,\n" + "T1\n" + ">\n" + ">;\n", + "using type = std::remove_cv_t<\n" + "add_common_cv_reference<\n" + "std::common_type_t, std::decay_t>,\n" + "T0,\n" + "T1>>;\n", + Style); + + // Test lambda goes to next line: + verifyFormat("void foo() {\n" + " auto lambda = []<\n" + "typename T\n" + ">(T t) {\n" + " };\n" + "}", + "void foo() {\n" + " auto lambda = []<\n" + " typename T>(T t){\n" + " };\n" + "}", + Style); + // With no column limit, two parameters can go on the same line: + verifyFormat("void foo() {\n" + " auto lambda = []<\n" + "typename T, typename Foo\n" + ">(T t) {\n" + " };\n" + "}", + "void foo() {\n" + " auto lambda = []<\n" + " typename T, typename Foo>(T t){\n" + " };\n" + "}", + Style); + // Or on different lines: + verifyFormat("void foo() {\n" + " auto lambda = []<\n" + "typename T,\n" + "typename Foo\n" + ">(T t) {\n" + " };\n" + "}", + "void foo() {\n" + " auto lambda = []<\n" + " typename T,\n" + " typename Foo>(T t){\n" + " };\n" + "}", + Style); + + // Note that this is the same line (no \n): + verifyFormat("void foo() {\n" + " auto lambda = [](T t) {};\n" + "}", + Style); + + // Test template usage goes to next
[clang] [clang-format] Add BreakBeforeTemplateClose option (PR #118046)
@@ -11224,6 +11224,328 @@ TEST_F(FormatTest, WrapsTemplateDeclarationsWithComments) { Style); } +TEST_F(FormatTest, BreakBeforeTemplateCloser) { + FormatStyle Style = getLLVMStyle(); + // Begin with tests covering the case where there is no constraint on the + // column limit. + Style.ColumnLimit = 0; + // When BreakBeforeTemplateCloser is turned off, the line break that it adds + // shall be removed: + verifyFormat("template <\n" + "typename Foo,\n" + "typename Bar>\n" + "void foo() {}", + "template <\n" + "typename Foo,\n" + "typename Bar\n" + ">\n" + "void foo() {}", + Style); + + Style.BreakBeforeTemplateCloser = true; + // BreakBeforeTemplateCloser should NOT force template declarations onto + // multiple lines. + verifyFormat("template \n" + "void foo() {}", + Style); + verifyFormat("template \n" + "void foo() {}", + Style); + // It should allow a line break, even when the typename is short. + // verifyNoChange is needed because the default behavior is one line. + verifyNoChange("template <\n" + "typename Foo\n" + ">\n" + "void foo() {}", + Style); + verifyNoChange("template <\n" + "typename Foo,\n" + "typename Bar\n" + ">\n" + "void foo() {}", + Style); + verifyNoChange("template \n" + "void foo() {}", + Style); + // It should add a line break before > if not already present: + verifyFormat("template <\n" + "typename Foo\n" + ">\n" + "void foo() {}", + "template <\n" + "typename Foo>\n" + "void foo() {}", + Style); + verifyFormat("template <\n" + "typename Foo,\n" + "typename Bar\n" + ">\n" + "void foo() {}", + "template <\n" + "typename Foo,\n" + "typename Bar>\n" + "void foo() {}", + Style); + // When within an indent scope, the > should be placed accordingly: + verifyFormat("struct Baz {\n" + " template <\n" + " typename Foo,\n" + " typename Bar\n" + " >\n" + " void foo() {}\n" + "};", + "struct Baz {\n" + " template <\n" + " typename Foo,\n" + " typename Bar>\n" + " void foo() {}\n" + "};", + Style); + + // Test from https://github.com/llvm/llvm-project/issues/80049: + verifyFormat( + "using type = std::remove_cv_t<\n" + "add_common_cv_reference<\n" + "std::common_type_t, std::decay_t>,\n" + "T0,\n" + "T1\n" + ">\n" + ">;\n", + "using type = std::remove_cv_t<\n" + "add_common_cv_reference<\n" + "std::common_type_t, std::decay_t>,\n" + "T0,\n" + "T1>>;\n", + Style); + + // Test lambda goes to next line: + verifyFormat("void foo() {\n" + " auto lambda = []<\n" + "typename T\n" + ">(T t) {\n" + " };\n" + "}", + "void foo() {\n" + " auto lambda = []<\n" + " typename T>(T t){\n" + " };\n" + "}", + Style); + // With no column limit, two parameters can go on the same line: + verifyFormat("void foo() {\n" + " auto lambda = []<\n" + "typename T, typename Foo\n" + ">(T t) {\n" + " };\n" + "}", + "void foo() {\n" + " auto lambda = []<\n" + " typename T, typename Foo>(T t){\n" + " };\n" + "}", + Style); + // Or on different lines: + verifyFormat("void foo() {\n" + " auto lambda = []<\n" + "typename T,\n" + "typename Foo\n" + ">(T t) {\n" + " };\n" + "}", + "void foo() {\n" + " auto lambda = []<\n" + " typename T,\n" + " typename Foo>(T t){\n" + " };\n" + "}", + Style); + + // Note that this is the same line (no \n): + verifyFormat("void foo() {\n" + " auto lambda = [](T t) {};\n" + "}", + Style); + + // Test template usage goes to next
[clang] [clang-format] Add BreakBeforeTemplateClose option (PR #118046)
@@ -11224,6 +11224,328 @@ TEST_F(FormatTest, WrapsTemplateDeclarationsWithComments) { Style); } +TEST_F(FormatTest, BreakBeforeTemplateCloser) { + FormatStyle Style = getLLVMStyle(); + // Begin with tests covering the case where there is no constraint on the + // column limit. + Style.ColumnLimit = 0; + // When BreakBeforeTemplateCloser is turned off, the line break that it adds + // shall be removed: + verifyFormat("template <\n" + "typename Foo,\n" + "typename Bar>\n" + "void foo() {}", + "template <\n" + "typename Foo,\n" + "typename Bar\n" + ">\n" + "void foo() {}", + Style); + + Style.BreakBeforeTemplateCloser = true; + // BreakBeforeTemplateCloser should NOT force template declarations onto + // multiple lines. + verifyFormat("template \n" + "void foo() {}", + Style); + verifyFormat("template \n" + "void foo() {}", + Style); + // It should allow a line break, even when the typename is short. + // verifyNoChange is needed because the default behavior is one line. + verifyNoChange("template <\n" + "typename Foo\n" + ">\n" + "void foo() {}", + Style); + verifyNoChange("template <\n" + "typename Foo,\n" + "typename Bar\n" + ">\n" + "void foo() {}", + Style); + verifyNoChange("template \n" + "void foo() {}", + Style); + // It should add a line break before > if not already present: + verifyFormat("template <\n" + "typename Foo\n" + ">\n" + "void foo() {}", + "template <\n" + "typename Foo>\n" + "void foo() {}", + Style); + verifyFormat("template <\n" + "typename Foo,\n" + "typename Bar\n" + ">\n" + "void foo() {}", + "template <\n" + "typename Foo,\n" + "typename Bar>\n" + "void foo() {}", + Style); + // When within an indent scope, the > should be placed accordingly: + verifyFormat("struct Baz {\n" + " template <\n" + " typename Foo,\n" + " typename Bar\n" + " >\n" + " void foo() {}\n" + "};", + "struct Baz {\n" + " template <\n" + " typename Foo,\n" + " typename Bar>\n" + " void foo() {}\n" + "};", + Style); + + // Test from https://github.com/llvm/llvm-project/issues/80049: + verifyFormat( + "using type = std::remove_cv_t<\n" + "add_common_cv_reference<\n" + "std::common_type_t, std::decay_t>,\n" + "T0,\n" + "T1\n" + ">\n" + ">;\n", + "using type = std::remove_cv_t<\n" + "add_common_cv_reference<\n" + "std::common_type_t, std::decay_t>,\n" + "T0,\n" + "T1>>;\n", owenca wrote: ```suggestion "T1>>;", ``` https://github.com/llvm/llvm-project/pull/118046 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang-format] Add BreakBeforeTemplateClose option (PR #118046)
@@ -11224,6 +11224,328 @@ TEST_F(FormatTest, WrapsTemplateDeclarationsWithComments) { Style); } +TEST_F(FormatTest, BreakBeforeTemplateCloser) { + FormatStyle Style = getLLVMStyle(); + // Begin with tests covering the case where there is no constraint on the + // column limit. + Style.ColumnLimit = 0; + // When BreakBeforeTemplateCloser is turned off, the line break that it adds + // shall be removed: + verifyFormat("template <\n" + "typename Foo,\n" + "typename Bar>\n" + "void foo() {}", + "template <\n" + "typename Foo,\n" + "typename Bar\n" + ">\n" + "void foo() {}", + Style); + + Style.BreakBeforeTemplateCloser = true; + // BreakBeforeTemplateCloser should NOT force template declarations onto + // multiple lines. + verifyFormat("template \n" + "void foo() {}", + Style); + verifyFormat("template \n" + "void foo() {}", + Style); + // It should allow a line break, even when the typename is short. + // verifyNoChange is needed because the default behavior is one line. + verifyNoChange("template <\n" + "typename Foo\n" + ">\n" + "void foo() {}", + Style); + verifyNoChange("template <\n" + "typename Foo,\n" + "typename Bar\n" + ">\n" + "void foo() {}", + Style); + verifyNoChange("template \n" + "void foo() {}", + Style); + // It should add a line break before > if not already present: + verifyFormat("template <\n" + "typename Foo\n" + ">\n" + "void foo() {}", + "template <\n" + "typename Foo>\n" + "void foo() {}", + Style); + verifyFormat("template <\n" + "typename Foo,\n" + "typename Bar\n" + ">\n" + "void foo() {}", + "template <\n" + "typename Foo,\n" + "typename Bar>\n" + "void foo() {}", + Style); + // When within an indent scope, the > should be placed accordingly: + verifyFormat("struct Baz {\n" + " template <\n" + " typename Foo,\n" + " typename Bar\n" + " >\n" + " void foo() {}\n" + "};", + "struct Baz {\n" + " template <\n" + " typename Foo,\n" + " typename Bar>\n" + " void foo() {}\n" + "};", + Style); + + // Test from https://github.com/llvm/llvm-project/issues/80049: + verifyFormat( + "using type = std::remove_cv_t<\n" + "add_common_cv_reference<\n" + "std::common_type_t, std::decay_t>,\n" + "T0,\n" + "T1\n" + ">\n" + ">;\n", + "using type = std::remove_cv_t<\n" + "add_common_cv_reference<\n" + "std::common_type_t, std::decay_t>,\n" + "T0,\n" + "T1>>;\n", + Style); + + // Test lambda goes to next line: + verifyFormat("void foo() {\n" + " auto lambda = []<\n" + "typename T\n" + ">(T t) {\n" + " };\n" + "}", + "void foo() {\n" + " auto lambda = []<\n" + " typename T>(T t){\n" + " };\n" + "}", + Style); + // With no column limit, two parameters can go on the same line: + verifyFormat("void foo() {\n" + " auto lambda = []<\n" + "typename T, typename Foo\n" + ">(T t) {\n" + " };\n" + "}", + "void foo() {\n" + " auto lambda = []<\n" + " typename T, typename Foo>(T t){\n" + " };\n" + "}", + Style); + // Or on different lines: + verifyFormat("void foo() {\n" + " auto lambda = []<\n" + "typename T,\n" + "typename Foo\n" + ">(T t) {\n" + " };\n" + "}", + "void foo() {\n" + " auto lambda = []<\n" + " typename T,\n" + " typename Foo>(T t){\n" + " };\n" + "}", + Style); + + // Note that this is the same line (no \n): + verifyFormat("void foo() {\n" + " auto lambda = [](T t) {};\n" + "}", + Style); + + // Test template usage goes to next
[clang] [clang-format] Add BreakBeforeTemplateClose option (PR #118046)
@@ -11224,6 +11224,328 @@ TEST_F(FormatTest, WrapsTemplateDeclarationsWithComments) { Style); } +TEST_F(FormatTest, BreakBeforeTemplateCloser) { + FormatStyle Style = getLLVMStyle(); + // Begin with tests covering the case where there is no constraint on the + // column limit. + Style.ColumnLimit = 0; + // When BreakBeforeTemplateCloser is turned off, the line break that it adds + // shall be removed: + verifyFormat("template <\n" + "typename Foo,\n" + "typename Bar>\n" + "void foo() {}", + "template <\n" + "typename Foo,\n" + "typename Bar\n" + ">\n" + "void foo() {}", + Style); + + Style.BreakBeforeTemplateCloser = true; + // BreakBeforeTemplateCloser should NOT force template declarations onto + // multiple lines. + verifyFormat("template \n" + "void foo() {}", + Style); + verifyFormat("template \n" + "void foo() {}", + Style); owenca wrote: Delete. Current behavior. https://github.com/llvm/llvm-project/pull/118046 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang-format] Add BreakBeforeTemplateClose option (PR #118046)
@@ -11224,6 +11224,328 @@ TEST_F(FormatTest, WrapsTemplateDeclarationsWithComments) { Style); } +TEST_F(FormatTest, BreakBeforeTemplateCloser) { + FormatStyle Style = getLLVMStyle(); + // Begin with tests covering the case where there is no constraint on the + // column limit. + Style.ColumnLimit = 0; + // When BreakBeforeTemplateCloser is turned off, the line break that it adds + // shall be removed: + verifyFormat("template <\n" + "typename Foo,\n" + "typename Bar>\n" + "void foo() {}", + "template <\n" + "typename Foo,\n" + "typename Bar\n" + ">\n" + "void foo() {}", + Style); + + Style.BreakBeforeTemplateCloser = true; + // BreakBeforeTemplateCloser should NOT force template declarations onto + // multiple lines. + verifyFormat("template \n" + "void foo() {}", + Style); + verifyFormat("template \n" + "void foo() {}", + Style); + // It should allow a line break, even when the typename is short. + // verifyNoChange is needed because the default behavior is one line. + verifyNoChange("template <\n" + "typename Foo\n" + ">\n" + "void foo() {}", + Style); + verifyNoChange("template <\n" + "typename Foo,\n" + "typename Bar\n" + ">\n" + "void foo() {}", + Style); + verifyNoChange("template \n" + "void foo() {}", + Style); + // It should add a line break before > if not already present: + verifyFormat("template <\n" + "typename Foo\n" + ">\n" + "void foo() {}", + "template <\n" + "typename Foo>\n" + "void foo() {}", + Style); + verifyFormat("template <\n" + "typename Foo,\n" + "typename Bar\n" + ">\n" + "void foo() {}", + "template <\n" + "typename Foo,\n" + "typename Bar>\n" + "void foo() {}", + Style); + // When within an indent scope, the > should be placed accordingly: + verifyFormat("struct Baz {\n" + " template <\n" + " typename Foo,\n" + " typename Bar\n" + " >\n" + " void foo() {}\n" + "};", + "struct Baz {\n" + " template <\n" + " typename Foo,\n" + " typename Bar>\n" + " void foo() {}\n" + "};", + Style); + + // Test from https://github.com/llvm/llvm-project/issues/80049: + verifyFormat( + "using type = std::remove_cv_t<\n" + "add_common_cv_reference<\n" + "std::common_type_t, std::decay_t>,\n" + "T0,\n" + "T1\n" + ">\n" + ">;\n", + "using type = std::remove_cv_t<\n" + "add_common_cv_reference<\n" + "std::common_type_t, std::decay_t>,\n" + "T0,\n" + "T1>>;\n", + Style); + + // Test lambda goes to next line: + verifyFormat("void foo() {\n" + " auto lambda = []<\n" + "typename T\n" + ">(T t) {\n" + " };\n" + "}", + "void foo() {\n" + " auto lambda = []<\n" + " typename T>(T t){\n" + " };\n" + "}", + Style); + // With no column limit, two parameters can go on the same line: + verifyFormat("void foo() {\n" + " auto lambda = []<\n" + "typename T, typename Foo\n" + ">(T t) {\n" + " };\n" + "}", + "void foo() {\n" + " auto lambda = []<\n" + " typename T, typename Foo>(T t){\n" + " };\n" + "}", + Style); + // Or on different lines: + verifyFormat("void foo() {\n" + " auto lambda = []<\n" + "typename T,\n" + "typename Foo\n" + ">(T t) {\n" + " };\n" + "}", + "void foo() {\n" + " auto lambda = []<\n" + " typename T,\n" + " typename Foo>(T t){\n" + " };\n" + "}", + Style); + + // Note that this is the same line (no \n): + verifyFormat("void foo() {\n" + " auto lambda = [](T t) {};\n" + "}", + Style); + + // Test template usage goes to next
[clang] [clang-format] Add BreakBeforeTemplateClose option (PR #118046)
@@ -11224,6 +11224,328 @@ TEST_F(FormatTest, WrapsTemplateDeclarationsWithComments) { Style); } +TEST_F(FormatTest, BreakBeforeTemplateCloser) { + FormatStyle Style = getLLVMStyle(); + // Begin with tests covering the case where there is no constraint on the + // column limit. + Style.ColumnLimit = 0; + // When BreakBeforeTemplateCloser is turned off, the line break that it adds + // shall be removed: + verifyFormat("template <\n" + "typename Foo,\n" + "typename Bar>\n" + "void foo() {}", + "template <\n" + "typename Foo,\n" + "typename Bar\n" + ">\n" + "void foo() {}", + Style); + + Style.BreakBeforeTemplateCloser = true; + // BreakBeforeTemplateCloser should NOT force template declarations onto + // multiple lines. + verifyFormat("template \n" + "void foo() {}", + Style); + verifyFormat("template \n" + "void foo() {}", + Style); + // It should allow a line break, even when the typename is short. + // verifyNoChange is needed because the default behavior is one line. + verifyNoChange("template <\n" + "typename Foo\n" + ">\n" + "void foo() {}", + Style); + verifyNoChange("template <\n" + "typename Foo,\n" + "typename Bar\n" + ">\n" + "void foo() {}", + Style); + verifyNoChange("template \n" + "void foo() {}", + Style); + // It should add a line break before > if not already present: + verifyFormat("template <\n" + "typename Foo\n" + ">\n" + "void foo() {}", + "template <\n" + "typename Foo>\n" + "void foo() {}", + Style); + verifyFormat("template <\n" + "typename Foo,\n" + "typename Bar\n" + ">\n" + "void foo() {}", + "template <\n" + "typename Foo,\n" + "typename Bar>\n" + "void foo() {}", + Style); + // When within an indent scope, the > should be placed accordingly: + verifyFormat("struct Baz {\n" + " template <\n" + " typename Foo,\n" + " typename Bar\n" + " >\n" + " void foo() {}\n" + "};", + "struct Baz {\n" + " template <\n" + " typename Foo,\n" + " typename Bar>\n" + " void foo() {}\n" + "};", + Style); + + // Test from https://github.com/llvm/llvm-project/issues/80049: + verifyFormat( + "using type = std::remove_cv_t<\n" + "add_common_cv_reference<\n" + "std::common_type_t, std::decay_t>,\n" + "T0,\n" + "T1\n" + ">\n" + ">;\n", + "using type = std::remove_cv_t<\n" + "add_common_cv_reference<\n" + "std::common_type_t, std::decay_t>,\n" + "T0,\n" + "T1>>;\n", + Style); + + // Test lambda goes to next line: + verifyFormat("void foo() {\n" + " auto lambda = []<\n" + "typename T\n" + ">(T t) {\n" + " };\n" + "}", + "void foo() {\n" + " auto lambda = []<\n" + " typename T>(T t){\n" + " };\n" + "}", + Style); + // With no column limit, two parameters can go on the same line: + verifyFormat("void foo() {\n" + " auto lambda = []<\n" + "typename T, typename Foo\n" + ">(T t) {\n" + " };\n" + "}", + "void foo() {\n" + " auto lambda = []<\n" + " typename T, typename Foo>(T t){\n" + " };\n" + "}", + Style); + // Or on different lines: + verifyFormat("void foo() {\n" + " auto lambda = []<\n" + "typename T,\n" + "typename Foo\n" + ">(T t) {\n" + " };\n" + "}", + "void foo() {\n" + " auto lambda = []<\n" + " typename T,\n" + " typename Foo>(T t){\n" + " };\n" + "}", + Style); + + // Note that this is the same line (no \n): + verifyFormat("void foo() {\n" + " auto lambda = [](T t) {};\n" + "}", + Style); + + // Test template usage goes to next
[clang] [clang-format] Add BreakBeforeTemplateClose option (PR #118046)
@@ -11224,6 +11224,328 @@ TEST_F(FormatTest, WrapsTemplateDeclarationsWithComments) { Style); } +TEST_F(FormatTest, BreakBeforeTemplateCloser) { + FormatStyle Style = getLLVMStyle(); + // Begin with tests covering the case where there is no constraint on the + // column limit. + Style.ColumnLimit = 0; + // When BreakBeforeTemplateCloser is turned off, the line break that it adds + // shall be removed: + verifyFormat("template <\n" + "typename Foo,\n" + "typename Bar>\n" + "void foo() {}", + "template <\n" + "typename Foo,\n" + "typename Bar\n" + ">\n" + "void foo() {}", + Style); + + Style.BreakBeforeTemplateCloser = true; + // BreakBeforeTemplateCloser should NOT force template declarations onto + // multiple lines. + verifyFormat("template \n" + "void foo() {}", + Style); + verifyFormat("template \n" + "void foo() {}", + Style); + // It should allow a line break, even when the typename is short. + // verifyNoChange is needed because the default behavior is one line. + verifyNoChange("template <\n" + "typename Foo\n" + ">\n" + "void foo() {}", + Style); + verifyNoChange("template <\n" + "typename Foo,\n" + "typename Bar\n" + ">\n" + "void foo() {}", + Style); + verifyNoChange("template \n" + "void foo() {}", + Style); + // It should add a line break before > if not already present: + verifyFormat("template <\n" + "typename Foo\n" + ">\n" + "void foo() {}", + "template <\n" + "typename Foo>\n" + "void foo() {}", + Style); + verifyFormat("template <\n" + "typename Foo,\n" + "typename Bar\n" + ">\n" + "void foo() {}", + "template <\n" + "typename Foo,\n" + "typename Bar>\n" + "void foo() {}", + Style); + // When within an indent scope, the > should be placed accordingly: + verifyFormat("struct Baz {\n" + " template <\n" + " typename Foo,\n" + " typename Bar\n" + " >\n" + " void foo() {}\n" + "};", + "struct Baz {\n" + " template <\n" + " typename Foo,\n" + " typename Bar>\n" + " void foo() {}\n" + "};", + Style); + + // Test from https://github.com/llvm/llvm-project/issues/80049: + verifyFormat( + "using type = std::remove_cv_t<\n" + "add_common_cv_reference<\n" + "std::common_type_t, std::decay_t>,\n" + "T0,\n" + "T1\n" + ">\n" + ">;\n", + "using type = std::remove_cv_t<\n" + "add_common_cv_reference<\n" + "std::common_type_t, std::decay_t>,\n" + "T0,\n" + "T1>>;\n", + Style); + + // Test lambda goes to next line: + verifyFormat("void foo() {\n" + " auto lambda = []<\n" + "typename T\n" + ">(T t) {\n" + " };\n" + "}", + "void foo() {\n" + " auto lambda = []<\n" + " typename T>(T t){\n" + " };\n" + "}", + Style); + // With no column limit, two parameters can go on the same line: + verifyFormat("void foo() {\n" + " auto lambda = []<\n" + "typename T, typename Foo\n" + ">(T t) {\n" + " };\n" + "}", + "void foo() {\n" + " auto lambda = []<\n" + " typename T, typename Foo>(T t){\n" + " };\n" + "}", + Style); + // Or on different lines: + verifyFormat("void foo() {\n" + " auto lambda = []<\n" + "typename T,\n" + "typename Foo\n" + ">(T t) {\n" + " };\n" + "}", + "void foo() {\n" + " auto lambda = []<\n" + " typename T,\n" + " typename Foo>(T t){\n" + " };\n" + "}", + Style); + + // Note that this is the same line (no \n): + verifyFormat("void foo() {\n" + " auto lambda = [](T t) {};\n" + "}", + Style); + + // Test template usage goes to next
[clang] [clang-format] Add BreakBeforeTemplateClose option (PR #118046)
@@ -11224,6 +11224,328 @@ TEST_F(FormatTest, WrapsTemplateDeclarationsWithComments) { Style); } +TEST_F(FormatTest, BreakBeforeTemplateCloser) { + FormatStyle Style = getLLVMStyle(); + // Begin with tests covering the case where there is no constraint on the + // column limit. + Style.ColumnLimit = 0; + // When BreakBeforeTemplateCloser is turned off, the line break that it adds + // shall be removed: + verifyFormat("template <\n" + "typename Foo,\n" + "typename Bar>\n" + "void foo() {}", + "template <\n" + "typename Foo,\n" + "typename Bar\n" + ">\n" + "void foo() {}", + Style); + + Style.BreakBeforeTemplateCloser = true; + // BreakBeforeTemplateCloser should NOT force template declarations onto + // multiple lines. + verifyFormat("template \n" + "void foo() {}", + Style); + verifyFormat("template \n" + "void foo() {}", + Style); + // It should allow a line break, even when the typename is short. + // verifyNoChange is needed because the default behavior is one line. + verifyNoChange("template <\n" + "typename Foo\n" + ">\n" + "void foo() {}", + Style); + verifyNoChange("template <\n" + "typename Foo,\n" + "typename Bar\n" + ">\n" + "void foo() {}", + Style); owenca wrote: Delete. Redundant to the test cases at lines 11272 and 11280 below as `verifyFormat(Output, Input)` also checks the stability of `Output`. https://github.com/llvm/llvm-project/pull/118046 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang-format] Add BreakBeforeTemplateClose option (PR #118046)
@@ -11224,6 +11224,328 @@ TEST_F(FormatTest, WrapsTemplateDeclarationsWithComments) { Style); } +TEST_F(FormatTest, BreakBeforeTemplateCloser) { + FormatStyle Style = getLLVMStyle(); + // Begin with tests covering the case where there is no constraint on the + // column limit. + Style.ColumnLimit = 0; + // When BreakBeforeTemplateCloser is turned off, the line break that it adds + // shall be removed: + verifyFormat("template <\n" + "typename Foo,\n" + "typename Bar>\n" + "void foo() {}", + "template <\n" + "typename Foo,\n" + "typename Bar\n" + ">\n" + "void foo() {}", + Style); + + Style.BreakBeforeTemplateCloser = true; + // BreakBeforeTemplateCloser should NOT force template declarations onto + // multiple lines. + verifyFormat("template \n" + "void foo() {}", + Style); + verifyFormat("template \n" + "void foo() {}", + Style); + // It should allow a line break, even when the typename is short. + // verifyNoChange is needed because the default behavior is one line. + verifyNoChange("template <\n" + "typename Foo\n" + ">\n" + "void foo() {}", + Style); + verifyNoChange("template <\n" + "typename Foo,\n" + "typename Bar\n" + ">\n" + "void foo() {}", + Style); + verifyNoChange("template \n" + "void foo() {}", + Style); owenca wrote: Delete. Current behavior. https://github.com/llvm/llvm-project/pull/118046 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang-format] Add BreakBeforeTemplateClose option (PR #118046)
@@ -11224,6 +11224,328 @@ TEST_F(FormatTest, WrapsTemplateDeclarationsWithComments) { Style); } +TEST_F(FormatTest, BreakBeforeTemplateCloser) { + FormatStyle Style = getLLVMStyle(); + // Begin with tests covering the case where there is no constraint on the + // column limit. + Style.ColumnLimit = 0; + // When BreakBeforeTemplateCloser is turned off, the line break that it adds + // shall be removed: + verifyFormat("template <\n" + "typename Foo,\n" + "typename Bar>\n" + "void foo() {}", + "template <\n" + "typename Foo,\n" + "typename Bar\n" + ">\n" + "void foo() {}", + Style); + + Style.BreakBeforeTemplateCloser = true; + // BreakBeforeTemplateCloser should NOT force template declarations onto + // multiple lines. + verifyFormat("template \n" + "void foo() {}", + Style); + verifyFormat("template \n" + "void foo() {}", + Style); + // It should allow a line break, even when the typename is short. + // verifyNoChange is needed because the default behavior is one line. + verifyNoChange("template <\n" + "typename Foo\n" + ">\n" + "void foo() {}", + Style); + verifyNoChange("template <\n" + "typename Foo,\n" + "typename Bar\n" + ">\n" + "void foo() {}", + Style); + verifyNoChange("template \n" + "void foo() {}", + Style); + // It should add a line break before > if not already present: + verifyFormat("template <\n" + "typename Foo\n" + ">\n" + "void foo() {}", + "template <\n" + "typename Foo>\n" + "void foo() {}", + Style); + verifyFormat("template <\n" + "typename Foo,\n" + "typename Bar\n" + ">\n" + "void foo() {}", + "template <\n" + "typename Foo,\n" + "typename Bar>\n" + "void foo() {}", + Style); + // When within an indent scope, the > should be placed accordingly: + verifyFormat("struct Baz {\n" + " template <\n" + " typename Foo,\n" + " typename Bar\n" + " >\n" + " void foo() {}\n" + "};", + "struct Baz {\n" + " template <\n" + " typename Foo,\n" + " typename Bar>\n" + " void foo() {}\n" + "};", + Style); + + // Test from https://github.com/llvm/llvm-project/issues/80049: + verifyFormat( + "using type = std::remove_cv_t<\n" + "add_common_cv_reference<\n" + "std::common_type_t, std::decay_t>,\n" + "T0,\n" + "T1\n" + ">\n" + ">;\n", owenca wrote: ```suggestion ">;", ``` https://github.com/llvm/llvm-project/pull/118046 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang-format] Add BreakBeforeTemplateClose option (PR #118046)
@@ -11220,6 +11220,333 @@ TEST_F(FormatTest, WrapsTemplateDeclarationsWithComments) { Style); } +TEST_F(FormatTest, BreakBeforeTemplateCloser) { + FormatStyle Style = getGoogleStyle(FormatStyle::LK_Cpp); + // Begin with tests covering the case where there is no constraint on the + // column limit. + Style.ColumnLimit = 0; + // When BreakBeforeTemplateCloser is turned off, the line break that it adds + // shall be removed: + verifyFormat("template <\n" + "typename Foo,\n" + "typename Bar>\n" + "void foo() {}", + "template <\n" + "typename Foo,\n" + "typename Bar\n" + ">\n" + "void foo() {}", + Style); + + Style.BreakBeforeTemplateCloser = FormatStyle::BBTCS_BlockIndent; + // BreakBeforeTemplateCloser should NOT force template declarations onto + // multiple lines. + verifyFormat("template \n" + "void foo() {}", + Style); + verifyFormat("template \n" + "void foo() {}", + Style); + // It should allow a line break, even when the typename is short. + // verifyNoChange is needed because the default behavior is one line. + verifyNoChange("template <\n" + "typename Foo\n" + ">\n" + "void foo() {}", + Style); + verifyNoChange("template <\n" + "typename Foo,\n" + "typename Bar\n" + ">\n" + "void foo() {}", + Style); + verifyNoChange("template \n" + "void foo() {}", + Style); + // It should add a line break before > if not already present: + verifyFormat("template <\n" + "typename Foo\n" + ">\n" + "void foo() {}", + "template <\n" + "typename Foo>\n" + "void foo() {}", + Style); + verifyFormat("template <\n" + "typename Foo,\n" + "typename Bar\n" + ">\n" + "void foo() {}", + "template <\n" + "typename Foo,\n" + "typename Bar>\n" + "void foo() {}", + Style); + // When within an indent scope, the > should be placed accordingly: + verifyFormat("struct Baz {\n" + " template <\n" + " typename Foo,\n" + " typename Bar\n" + " >\n" + " void foo() {}\n" + "};", + "struct Baz {\n" + " template <\n" + " typename Foo,\n" + " typename Bar>\n" + " void foo() {}\n" + "};", + Style); + + // Test from issue #80049: + verifyFormat( + "void foo() {\n" + " using type = std::remove_cv_t<\n" + " add_common_cv_reference<\n" + " std::common_type_t, std::decay_t>,\n" + " T0,\n" + " T1\n" + " >\n" + " >;\n" + "}", + "void foo() {\n" + " using type = std::remove_cv_t<\n" + " add_common_cv_reference<\n" + " std::common_type_t, std::decay_t>,\n" + " T0,\n" + " T1>>;\n" + "}", + Style); + + // Test lambda goes to next line: + verifyFormat("void foo() {\n" + " auto lambda = []<\n" + "typename T\n" + ">(T t) {\n" + " };\n" + "}", + "void foo() {\n" + " auto lambda = []<\n" + " typename T>(T t){\n" + " };\n" + "}", + Style); + // With no column limit, two parameters can go on the same line: + verifyFormat("void foo() {\n" + " auto lambda = []<\n" + "typename T, typename Foo\n" + ">(T t) {\n" + " };\n" + "}", + "void foo() {\n" + " auto lambda = []<\n" + " typename T, typename Foo>(T t){\n" + " };\n" + "}", + Style); + // Or on different lines: + verifyFormat("void foo() {\n" + " auto lambda = []<\n" + "typename T,\n" + "typename Foo\n" + ">(T t) {\n" + " };\n" + "}", + "void foo() {\n" + " auto lambda = []<\n" + " typename T,\n" + " typename Foo>(T t){\n" + " };\n" + "}", + Style); + + // Note that this is the same line (no \n): + verifyFormat("void foo() {\n" + " auto lambd
[clang] [clang-format] Add BreakBeforeTemplateClose option (PR #118046)
https://github.com/leijurv updated https://github.com/llvm/llvm-project/pull/118046 >From 1caf823165b16f6701993d586df51d5cdbf0885e Mon Sep 17 00:00:00 2001 From: Leijurv Date: Fri, 29 Nov 2024 21:54:36 -0600 Subject: [PATCH 01/16] [clang-format] Add BreakBeforeTemplateClose option --- clang/docs/ClangFormatStyleOptions.rst | 21 clang/docs/ReleaseNotes.rst| 1 + clang/include/clang/Format/Format.h| 20 clang/lib/Format/ContinuationIndenter.cpp | 11 ++ clang/lib/Format/ContinuationIndenter.h| 26 ++-- clang/lib/Format/Format.cpp| 2 + clang/lib/Format/TokenAnnotator.cpp| 2 +- clang/unittests/Format/ConfigParseTest.cpp | 1 + clang/unittests/Format/FormatTest.cpp | 131 + 9 files changed, 206 insertions(+), 9 deletions(-) diff --git a/clang/docs/ClangFormatStyleOptions.rst b/clang/docs/ClangFormatStyleOptions.rst index 4be448171699ca1..84ab1b0a2eff615 100644 --- a/clang/docs/ClangFormatStyleOptions.rst +++ b/clang/docs/ClangFormatStyleOptions.rst @@ -3416,6 +3416,27 @@ the configuration (without a prefix: ``Auto``). +.. _BreakBeforeTemplateClose: + +**BreakBeforeTemplateClose** (``Boolean``) :versionbadge:`clang-format 20` :ref:`¶ ` + If ``true``, a line break will be placed before the ``>`` in a multiline + template declaration. + + .. code-block:: c++ + + true: + template < + typename Foo, + typename Bar, + typename Baz + > + + false: + template < + typename Foo, + typename Bar, + typename Baz> + .. _BreakBeforeTernaryOperators: **BreakBeforeTernaryOperators** (``Boolean``) :versionbadge:`clang-format 3.7` :ref:`¶ ` diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst index e44aefa90ab386f..867d4b5d8c3f184 100644 --- a/clang/docs/ReleaseNotes.rst +++ b/clang/docs/ReleaseNotes.rst @@ -976,6 +976,7 @@ clang-format ``Never``, and ``true`` to ``Always``. - Adds ``RemoveEmptyLinesInUnwrappedLines`` option. - Adds ``KeepFormFeed`` option and set it to ``true`` for ``GNU`` style. +- Adds ``BreakBeforeTemplateClose`` option. libclang diff --git a/clang/include/clang/Format/Format.h b/clang/include/clang/Format/Format.h index 6383934afa2c404..bffd964f6aa8aa0 100644 --- a/clang/include/clang/Format/Format.h +++ b/clang/include/clang/Format/Format.h @@ -2248,6 +2248,25 @@ struct FormatStyle { /// \version 16 BreakBeforeInlineASMColonStyle BreakBeforeInlineASMColon; + /// If ``true``, a line break will be placed before the ``>`` in a multiline + /// template declaration. + /// \code + ///true: + ///template < + ///typename Foo, + ///typename Bar, + ///typename Baz + ///> + /// + ///false: + ///template < + ///typename Foo, + ///typename Bar, + ///typename Baz> + /// \endcode + /// \version 20 + bool BreakBeforeTemplateClose; + /// If ``true``, ternary operators will be placed after line breaks. /// \code ///true: @@ -5184,6 +5203,7 @@ struct FormatStyle { BreakBeforeBraces == R.BreakBeforeBraces && BreakBeforeConceptDeclarations == R.BreakBeforeConceptDeclarations && BreakBeforeInlineASMColon == R.BreakBeforeInlineASMColon && + BreakBeforeTemplateClose == R.BreakBeforeTemplateClose && BreakBeforeTernaryOperators == R.BreakBeforeTernaryOperators && BreakBinaryOperations == R.BreakBinaryOperations && BreakConstructorInitializers == R.BreakConstructorInitializers && diff --git a/clang/lib/Format/ContinuationIndenter.cpp b/clang/lib/Format/ContinuationIndenter.cpp index aed86c1fb99551c..4c783623afc535e 100644 --- a/clang/lib/Format/ContinuationIndenter.cpp +++ b/clang/lib/Format/ContinuationIndenter.cpp @@ -406,6 +406,10 @@ bool ContinuationIndenter::mustBreak(const LineState &State) { } if (CurrentState.BreakBeforeClosingParen && Current.is(tok::r_paren)) return true; + if (CurrentState.BreakBeforeClosingAngle && + Current.ClosesTemplateDeclaration && Style.BreakBeforeTemplateClose) { +return true; + } if (Style.Language == FormatStyle::LK_ObjC && Style.ObjCBreakBeforeNestedBlockParam && Current.ObjCSelectorNameParts > 1 && @@ -1234,6 +1238,9 @@ unsigned ContinuationIndenter::addTokenOnNewLine(LineState &State, Style.AlignAfterOpenBracket == FormatStyle::BAS_BlockIndent; } + if (PreviousNonComment && PreviousNonComment->is(tok::less)) +CurrentState.BreakBeforeClosingAngle = true; + if (CurrentState.AvoidBinPacking) { // If we are breaking after '(', '{', '<', or this is the break after a ':' // to start a member initializer list in a constructor, this should not @@ -1370,6 +1377,10 @@ unsigned ContinuationIndenter::getNewLineColumn(const LineState &State) { State.Stack.size() > 1) { return State.Stack[State.Stack.size()
[clang] [clang-format] Add BreakBeforeTemplateClose option (PR #118046)
@@ -11220,6 +11220,333 @@ TEST_F(FormatTest, WrapsTemplateDeclarationsWithComments) { Style); } +TEST_F(FormatTest, BreakBeforeTemplateCloser) { + FormatStyle Style = getGoogleStyle(FormatStyle::LK_Cpp); + // Begin with tests covering the case where there is no constraint on the + // column limit. + Style.ColumnLimit = 0; + // When BreakBeforeTemplateCloser is turned off, the line break that it adds + // shall be removed: + verifyFormat("template <\n" + "typename Foo,\n" + "typename Bar>\n" + "void foo() {}", + "template <\n" + "typename Foo,\n" + "typename Bar\n" + ">\n" + "void foo() {}", + Style); + + Style.BreakBeforeTemplateCloser = FormatStyle::BBTCS_BlockIndent; + // BreakBeforeTemplateCloser should NOT force template declarations onto + // multiple lines. + verifyFormat("template \n" + "void foo() {}", + Style); + verifyFormat("template \n" + "void foo() {}", + Style); + // It should allow a line break, even when the typename is short. + // verifyNoChange is needed because the default behavior is one line. + verifyNoChange("template <\n" + "typename Foo\n" + ">\n" + "void foo() {}", + Style); + verifyNoChange("template <\n" + "typename Foo,\n" + "typename Bar\n" + ">\n" + "void foo() {}", + Style); + verifyNoChange("template \n" + "void foo() {}", + Style); + // It should add a line break before > if not already present: + verifyFormat("template <\n" + "typename Foo\n" + ">\n" + "void foo() {}", + "template <\n" + "typename Foo>\n" + "void foo() {}", + Style); + verifyFormat("template <\n" + "typename Foo,\n" + "typename Bar\n" + ">\n" + "void foo() {}", + "template <\n" + "typename Foo,\n" + "typename Bar>\n" + "void foo() {}", + Style); + // When within an indent scope, the > should be placed accordingly: + verifyFormat("struct Baz {\n" + " template <\n" + " typename Foo,\n" + " typename Bar\n" + " >\n" + " void foo() {}\n" + "};", + "struct Baz {\n" + " template <\n" + " typename Foo,\n" + " typename Bar>\n" + " void foo() {}\n" + "};", + Style); + + // Test from issue #80049: + verifyFormat( + "void foo() {\n" + " using type = std::remove_cv_t<\n" + " add_common_cv_reference<\n" + " std::common_type_t, std::decay_t>,\n" + " T0,\n" + " T1\n" + " >\n" + " >;\n" + "}", + "void foo() {\n" + " using type = std::remove_cv_t<\n" + " add_common_cv_reference<\n" + " std::common_type_t, std::decay_t>,\n" + " T0,\n" + " T1>>;\n" + "}", + Style); + + // Test lambda goes to next line: + verifyFormat("void foo() {\n" + " auto lambda = []<\n" + "typename T\n" + ">(T t) {\n" + " };\n" + "}", + "void foo() {\n" + " auto lambda = []<\n" + " typename T>(T t){\n" + " };\n" + "}", + Style); + // With no column limit, two parameters can go on the same line: + verifyFormat("void foo() {\n" + " auto lambda = []<\n" + "typename T, typename Foo\n" + ">(T t) {\n" + " };\n" + "}", + "void foo() {\n" + " auto lambda = []<\n" + " typename T, typename Foo>(T t){\n" + " };\n" + "}", + Style); + // Or on different lines: + verifyFormat("void foo() {\n" + " auto lambda = []<\n" + "typename T,\n" + "typename Foo\n" + ">(T t) {\n" + " };\n" + "}", + "void foo() {\n" + " auto lambda = []<\n" + " typename T,\n" + " typename Foo>(T t){\n" + " };\n" + "}", + Style); + + // Note that this is the same line (no \n): + verifyFormat("void foo() {\n" + " auto lambd
[clang] [clang-format] Add BreakBeforeTemplateClose option (PR #118046)
@@ -11220,6 +11220,333 @@ TEST_F(FormatTest, WrapsTemplateDeclarationsWithComments) { Style); } +TEST_F(FormatTest, BreakBeforeTemplateCloser) { + FormatStyle Style = getGoogleStyle(FormatStyle::LK_Cpp); + // Begin with tests covering the case where there is no constraint on the + // column limit. + Style.ColumnLimit = 0; + // When BreakBeforeTemplateCloser is turned off, the line break that it adds + // shall be removed: + verifyFormat("template <\n" + "typename Foo,\n" + "typename Bar>\n" + "void foo() {}", + "template <\n" + "typename Foo,\n" + "typename Bar\n" + ">\n" + "void foo() {}", + Style); + + Style.BreakBeforeTemplateCloser = FormatStyle::BBTCS_BlockIndent; + // BreakBeforeTemplateCloser should NOT force template declarations onto + // multiple lines. + verifyFormat("template \n" + "void foo() {}", + Style); + verifyFormat("template \n" + "void foo() {}", + Style); + // It should allow a line break, even when the typename is short. + // verifyNoChange is needed because the default behavior is one line. + verifyNoChange("template <\n" + "typename Foo\n" + ">\n" + "void foo() {}", + Style); + verifyNoChange("template <\n" + "typename Foo,\n" + "typename Bar\n" + ">\n" + "void foo() {}", + Style); + verifyNoChange("template \n" + "void foo() {}", + Style); + // It should add a line break before > if not already present: + verifyFormat("template <\n" + "typename Foo\n" + ">\n" + "void foo() {}", + "template <\n" + "typename Foo>\n" + "void foo() {}", + Style); + verifyFormat("template <\n" + "typename Foo,\n" + "typename Bar\n" + ">\n" + "void foo() {}", + "template <\n" + "typename Foo,\n" + "typename Bar>\n" + "void foo() {}", + Style); + // When within an indent scope, the > should be placed accordingly: + verifyFormat("struct Baz {\n" + " template <\n" + " typename Foo,\n" + " typename Bar\n" + " >\n" + " void foo() {}\n" + "};", + "struct Baz {\n" + " template <\n" + " typename Foo,\n" + " typename Bar>\n" + " void foo() {}\n" + "};", + Style); + + // Test from issue #80049: + verifyFormat( + "void foo() {\n" + " using type = std::remove_cv_t<\n" + " add_common_cv_reference<\n" + " std::common_type_t, std::decay_t>,\n" + " T0,\n" + " T1\n" + " >\n" + " >;\n" + "}", + "void foo() {\n" + " using type = std::remove_cv_t<\n" + " add_common_cv_reference<\n" + " std::common_type_t, std::decay_t>,\n" + " T0,\n" + " T1>>;\n" + "}", + Style); + + // Test lambda goes to next line: + verifyFormat("void foo() {\n" + " auto lambda = []<\n" + "typename T\n" + ">(T t) {\n" + " };\n" + "}", + "void foo() {\n" + " auto lambda = []<\n" + " typename T>(T t){\n" + " };\n" + "}", + Style); + // With no column limit, two parameters can go on the same line: + verifyFormat("void foo() {\n" + " auto lambda = []<\n" + "typename T, typename Foo\n" + ">(T t) {\n" + " };\n" + "}", + "void foo() {\n" + " auto lambda = []<\n" + " typename T, typename Foo>(T t){\n" + " };\n" + "}", + Style); + // Or on different lines: + verifyFormat("void foo() {\n" + " auto lambda = []<\n" + "typename T,\n" + "typename Foo\n" + ">(T t) {\n" + " };\n" + "}", + "void foo() {\n" + " auto lambda = []<\n" + " typename T,\n" + " typename Foo>(T t){\n" + " };\n" + "}", + Style); + + // Note that this is the same line (no \n): + verifyFormat("void foo() {\n" + " auto lambd
[clang] [clang-format] Add BreakBeforeTemplateClose option (PR #118046)
@@ -11220,6 +11220,333 @@ TEST_F(FormatTest, WrapsTemplateDeclarationsWithComments) { Style); } +TEST_F(FormatTest, BreakBeforeTemplateCloser) { + FormatStyle Style = getGoogleStyle(FormatStyle::LK_Cpp); + // Begin with tests covering the case where there is no constraint on the + // column limit. + Style.ColumnLimit = 0; + // When BreakBeforeTemplateCloser is turned off, the line break that it adds + // shall be removed: + verifyFormat("template <\n" + "typename Foo,\n" + "typename Bar>\n" + "void foo() {}", + "template <\n" + "typename Foo,\n" + "typename Bar\n" + ">\n" + "void foo() {}", + Style); + + Style.BreakBeforeTemplateCloser = FormatStyle::BBTCS_BlockIndent; + // BreakBeforeTemplateCloser should NOT force template declarations onto + // multiple lines. + verifyFormat("template \n" + "void foo() {}", + Style); + verifyFormat("template \n" + "void foo() {}", + Style); + // It should allow a line break, even when the typename is short. + // verifyNoChange is needed because the default behavior is one line. + verifyNoChange("template <\n" + "typename Foo\n" + ">\n" + "void foo() {}", + Style); + verifyNoChange("template <\n" + "typename Foo,\n" + "typename Bar\n" + ">\n" + "void foo() {}", + Style); + verifyNoChange("template \n" + "void foo() {}", + Style); + // It should add a line break before > if not already present: + verifyFormat("template <\n" + "typename Foo\n" + ">\n" + "void foo() {}", + "template <\n" + "typename Foo>\n" + "void foo() {}", + Style); + verifyFormat("template <\n" + "typename Foo,\n" + "typename Bar\n" + ">\n" + "void foo() {}", + "template <\n" + "typename Foo,\n" + "typename Bar>\n" + "void foo() {}", + Style); + // When within an indent scope, the > should be placed accordingly: + verifyFormat("struct Baz {\n" + " template <\n" + " typename Foo,\n" + " typename Bar\n" + " >\n" + " void foo() {}\n" + "};", + "struct Baz {\n" + " template <\n" + " typename Foo,\n" + " typename Bar>\n" + " void foo() {}\n" + "};", + Style); + + // Test from issue #80049: + verifyFormat( + "void foo() {\n" + " using type = std::remove_cv_t<\n" + " add_common_cv_reference<\n" + " std::common_type_t, std::decay_t>,\n" + " T0,\n" + " T1\n" + " >\n" + " >;\n" + "}", + "void foo() {\n" + " using type = std::remove_cv_t<\n" + " add_common_cv_reference<\n" + " std::common_type_t, std::decay_t>,\n" + " T0,\n" + " T1>>;\n" + "}", + Style); + + // Test lambda goes to next line: + verifyFormat("void foo() {\n" + " auto lambda = []<\n" + "typename T\n" + ">(T t) {\n" + " };\n" + "}", + "void foo() {\n" + " auto lambda = []<\n" + " typename T>(T t){\n" + " };\n" + "}", + Style); + // With no column limit, two parameters can go on the same line: + verifyFormat("void foo() {\n" + " auto lambda = []<\n" + "typename T, typename Foo\n" + ">(T t) {\n" + " };\n" + "}", + "void foo() {\n" + " auto lambda = []<\n" + " typename T, typename Foo>(T t){\n" + " };\n" + "}", + Style); + // Or on different lines: + verifyFormat("void foo() {\n" + " auto lambda = []<\n" + "typename T,\n" + "typename Foo\n" + ">(T t) {\n" + " };\n" + "}", + "void foo() {\n" + " auto lambda = []<\n" + " typename T,\n" + " typename Foo>(T t){\n" + " };\n" + "}", + Style); + + // Note that this is the same line (no \n): + verifyFormat("void foo() {\n" + " auto lambd
[clang] [clang-format] Add BreakBeforeTemplateClose option (PR #118046)
@@ -11220,6 +11220,333 @@ TEST_F(FormatTest, WrapsTemplateDeclarationsWithComments) { Style); } +TEST_F(FormatTest, BreakBeforeTemplateCloser) { + FormatStyle Style = getGoogleStyle(FormatStyle::LK_Cpp); + // Begin with tests covering the case where there is no constraint on the + // column limit. + Style.ColumnLimit = 0; + // When BreakBeforeTemplateCloser is turned off, the line break that it adds + // shall be removed: + verifyFormat("template <\n" + "typename Foo,\n" + "typename Bar>\n" + "void foo() {}", + "template <\n" + "typename Foo,\n" + "typename Bar\n" + ">\n" + "void foo() {}", + Style); + + Style.BreakBeforeTemplateCloser = FormatStyle::BBTCS_BlockIndent; + // BreakBeforeTemplateCloser should NOT force template declarations onto + // multiple lines. + verifyFormat("template \n" + "void foo() {}", + Style); + verifyFormat("template \n" + "void foo() {}", + Style); + // It should allow a line break, even when the typename is short. + // verifyNoChange is needed because the default behavior is one line. + verifyNoChange("template <\n" + "typename Foo\n" + ">\n" + "void foo() {}", + Style); + verifyNoChange("template <\n" + "typename Foo,\n" + "typename Bar\n" + ">\n" + "void foo() {}", + Style); + verifyNoChange("template \n" + "void foo() {}", + Style); + // It should add a line break before > if not already present: + verifyFormat("template <\n" + "typename Foo\n" + ">\n" + "void foo() {}", + "template <\n" + "typename Foo>\n" + "void foo() {}", + Style); + verifyFormat("template <\n" + "typename Foo,\n" + "typename Bar\n" + ">\n" + "void foo() {}", + "template <\n" + "typename Foo,\n" + "typename Bar>\n" + "void foo() {}", + Style); + // When within an indent scope, the > should be placed accordingly: + verifyFormat("struct Baz {\n" + " template <\n" + " typename Foo,\n" + " typename Bar\n" + " >\n" + " void foo() {}\n" + "};", + "struct Baz {\n" + " template <\n" + " typename Foo,\n" + " typename Bar>\n" + " void foo() {}\n" + "};", + Style); + + // Test from issue #80049: + verifyFormat( + "void foo() {\n" + " using type = std::remove_cv_t<\n" + " add_common_cv_reference<\n" + " std::common_type_t, std::decay_t>,\n" + " T0,\n" + " T1\n" + " >\n" + " >;\n" + "}", + "void foo() {\n" + " using type = std::remove_cv_t<\n" + " add_common_cv_reference<\n" + " std::common_type_t, std::decay_t>,\n" + " T0,\n" + " T1>>;\n" + "}", + Style); + + // Test lambda goes to next line: + verifyFormat("void foo() {\n" + " auto lambda = []<\n" + "typename T\n" + ">(T t) {\n" + " };\n" + "}", + "void foo() {\n" + " auto lambda = []<\n" + " typename T>(T t){\n" + " };\n" + "}", + Style); + // With no column limit, two parameters can go on the same line: + verifyFormat("void foo() {\n" + " auto lambda = []<\n" + "typename T, typename Foo\n" + ">(T t) {\n" + " };\n" + "}", + "void foo() {\n" + " auto lambda = []<\n" + " typename T, typename Foo>(T t){\n" + " };\n" + "}", + Style); + // Or on different lines: + verifyFormat("void foo() {\n" + " auto lambda = []<\n" + "typename T,\n" + "typename Foo\n" + ">(T t) {\n" + " };\n" + "}", + "void foo() {\n" + " auto lambda = []<\n" + " typename T,\n" + " typename Foo>(T t){\n" + " };\n" + "}", + Style); + + // Note that this is the same line (no \n): + verifyFormat("void foo() {\n" + " auto lambd
[clang] [clang-format] Add BreakBeforeTemplateClose option (PR #118046)
https://github.com/leijurv updated https://github.com/llvm/llvm-project/pull/118046 >From 1caf823165b16f6701993d586df51d5cdbf0885e Mon Sep 17 00:00:00 2001 From: Leijurv Date: Fri, 29 Nov 2024 21:54:36 -0600 Subject: [PATCH 01/15] [clang-format] Add BreakBeforeTemplateClose option --- clang/docs/ClangFormatStyleOptions.rst | 21 clang/docs/ReleaseNotes.rst| 1 + clang/include/clang/Format/Format.h| 20 clang/lib/Format/ContinuationIndenter.cpp | 11 ++ clang/lib/Format/ContinuationIndenter.h| 26 ++-- clang/lib/Format/Format.cpp| 2 + clang/lib/Format/TokenAnnotator.cpp| 2 +- clang/unittests/Format/ConfigParseTest.cpp | 1 + clang/unittests/Format/FormatTest.cpp | 131 + 9 files changed, 206 insertions(+), 9 deletions(-) diff --git a/clang/docs/ClangFormatStyleOptions.rst b/clang/docs/ClangFormatStyleOptions.rst index 4be448171699ca..84ab1b0a2eff61 100644 --- a/clang/docs/ClangFormatStyleOptions.rst +++ b/clang/docs/ClangFormatStyleOptions.rst @@ -3416,6 +3416,27 @@ the configuration (without a prefix: ``Auto``). +.. _BreakBeforeTemplateClose: + +**BreakBeforeTemplateClose** (``Boolean``) :versionbadge:`clang-format 20` :ref:`¶ ` + If ``true``, a line break will be placed before the ``>`` in a multiline + template declaration. + + .. code-block:: c++ + + true: + template < + typename Foo, + typename Bar, + typename Baz + > + + false: + template < + typename Foo, + typename Bar, + typename Baz> + .. _BreakBeforeTernaryOperators: **BreakBeforeTernaryOperators** (``Boolean``) :versionbadge:`clang-format 3.7` :ref:`¶ ` diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst index e44aefa90ab386..867d4b5d8c3f18 100644 --- a/clang/docs/ReleaseNotes.rst +++ b/clang/docs/ReleaseNotes.rst @@ -976,6 +976,7 @@ clang-format ``Never``, and ``true`` to ``Always``. - Adds ``RemoveEmptyLinesInUnwrappedLines`` option. - Adds ``KeepFormFeed`` option and set it to ``true`` for ``GNU`` style. +- Adds ``BreakBeforeTemplateClose`` option. libclang diff --git a/clang/include/clang/Format/Format.h b/clang/include/clang/Format/Format.h index 6383934afa2c40..bffd964f6aa8aa 100644 --- a/clang/include/clang/Format/Format.h +++ b/clang/include/clang/Format/Format.h @@ -2248,6 +2248,25 @@ struct FormatStyle { /// \version 16 BreakBeforeInlineASMColonStyle BreakBeforeInlineASMColon; + /// If ``true``, a line break will be placed before the ``>`` in a multiline + /// template declaration. + /// \code + ///true: + ///template < + ///typename Foo, + ///typename Bar, + ///typename Baz + ///> + /// + ///false: + ///template < + ///typename Foo, + ///typename Bar, + ///typename Baz> + /// \endcode + /// \version 20 + bool BreakBeforeTemplateClose; + /// If ``true``, ternary operators will be placed after line breaks. /// \code ///true: @@ -5184,6 +5203,7 @@ struct FormatStyle { BreakBeforeBraces == R.BreakBeforeBraces && BreakBeforeConceptDeclarations == R.BreakBeforeConceptDeclarations && BreakBeforeInlineASMColon == R.BreakBeforeInlineASMColon && + BreakBeforeTemplateClose == R.BreakBeforeTemplateClose && BreakBeforeTernaryOperators == R.BreakBeforeTernaryOperators && BreakBinaryOperations == R.BreakBinaryOperations && BreakConstructorInitializers == R.BreakConstructorInitializers && diff --git a/clang/lib/Format/ContinuationIndenter.cpp b/clang/lib/Format/ContinuationIndenter.cpp index aed86c1fb99551..4c783623afc535 100644 --- a/clang/lib/Format/ContinuationIndenter.cpp +++ b/clang/lib/Format/ContinuationIndenter.cpp @@ -406,6 +406,10 @@ bool ContinuationIndenter::mustBreak(const LineState &State) { } if (CurrentState.BreakBeforeClosingParen && Current.is(tok::r_paren)) return true; + if (CurrentState.BreakBeforeClosingAngle && + Current.ClosesTemplateDeclaration && Style.BreakBeforeTemplateClose) { +return true; + } if (Style.Language == FormatStyle::LK_ObjC && Style.ObjCBreakBeforeNestedBlockParam && Current.ObjCSelectorNameParts > 1 && @@ -1234,6 +1238,9 @@ unsigned ContinuationIndenter::addTokenOnNewLine(LineState &State, Style.AlignAfterOpenBracket == FormatStyle::BAS_BlockIndent; } + if (PreviousNonComment && PreviousNonComment->is(tok::less)) +CurrentState.BreakBeforeClosingAngle = true; + if (CurrentState.AvoidBinPacking) { // If we are breaking after '(', '{', '<', or this is the break after a ':' // to start a member initializer list in a constructor, this should not @@ -1370,6 +1377,10 @@ unsigned ContinuationIndenter::getNewLineColumn(const LineState &State) { State.Stack.size() > 1) { return State.Stack[State.Stack.size() - 2].La
[clang] [clang-format] Add BreakBeforeTemplateClose option (PR #118046)
https://github.com/leijurv updated https://github.com/llvm/llvm-project/pull/118046 >From 1caf823165b16f6701993d586df51d5cdbf0885e Mon Sep 17 00:00:00 2001 From: Leijurv Date: Fri, 29 Nov 2024 21:54:36 -0600 Subject: [PATCH 01/14] [clang-format] Add BreakBeforeTemplateClose option --- clang/docs/ClangFormatStyleOptions.rst | 21 clang/docs/ReleaseNotes.rst| 1 + clang/include/clang/Format/Format.h| 20 clang/lib/Format/ContinuationIndenter.cpp | 11 ++ clang/lib/Format/ContinuationIndenter.h| 26 ++-- clang/lib/Format/Format.cpp| 2 + clang/lib/Format/TokenAnnotator.cpp| 2 +- clang/unittests/Format/ConfigParseTest.cpp | 1 + clang/unittests/Format/FormatTest.cpp | 131 + 9 files changed, 206 insertions(+), 9 deletions(-) diff --git a/clang/docs/ClangFormatStyleOptions.rst b/clang/docs/ClangFormatStyleOptions.rst index 4be448171699ca..84ab1b0a2eff61 100644 --- a/clang/docs/ClangFormatStyleOptions.rst +++ b/clang/docs/ClangFormatStyleOptions.rst @@ -3416,6 +3416,27 @@ the configuration (without a prefix: ``Auto``). +.. _BreakBeforeTemplateClose: + +**BreakBeforeTemplateClose** (``Boolean``) :versionbadge:`clang-format 20` :ref:`¶ ` + If ``true``, a line break will be placed before the ``>`` in a multiline + template declaration. + + .. code-block:: c++ + + true: + template < + typename Foo, + typename Bar, + typename Baz + > + + false: + template < + typename Foo, + typename Bar, + typename Baz> + .. _BreakBeforeTernaryOperators: **BreakBeforeTernaryOperators** (``Boolean``) :versionbadge:`clang-format 3.7` :ref:`¶ ` diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst index e44aefa90ab386..867d4b5d8c3f18 100644 --- a/clang/docs/ReleaseNotes.rst +++ b/clang/docs/ReleaseNotes.rst @@ -976,6 +976,7 @@ clang-format ``Never``, and ``true`` to ``Always``. - Adds ``RemoveEmptyLinesInUnwrappedLines`` option. - Adds ``KeepFormFeed`` option and set it to ``true`` for ``GNU`` style. +- Adds ``BreakBeforeTemplateClose`` option. libclang diff --git a/clang/include/clang/Format/Format.h b/clang/include/clang/Format/Format.h index 6383934afa2c40..bffd964f6aa8aa 100644 --- a/clang/include/clang/Format/Format.h +++ b/clang/include/clang/Format/Format.h @@ -2248,6 +2248,25 @@ struct FormatStyle { /// \version 16 BreakBeforeInlineASMColonStyle BreakBeforeInlineASMColon; + /// If ``true``, a line break will be placed before the ``>`` in a multiline + /// template declaration. + /// \code + ///true: + ///template < + ///typename Foo, + ///typename Bar, + ///typename Baz + ///> + /// + ///false: + ///template < + ///typename Foo, + ///typename Bar, + ///typename Baz> + /// \endcode + /// \version 20 + bool BreakBeforeTemplateClose; + /// If ``true``, ternary operators will be placed after line breaks. /// \code ///true: @@ -5184,6 +5203,7 @@ struct FormatStyle { BreakBeforeBraces == R.BreakBeforeBraces && BreakBeforeConceptDeclarations == R.BreakBeforeConceptDeclarations && BreakBeforeInlineASMColon == R.BreakBeforeInlineASMColon && + BreakBeforeTemplateClose == R.BreakBeforeTemplateClose && BreakBeforeTernaryOperators == R.BreakBeforeTernaryOperators && BreakBinaryOperations == R.BreakBinaryOperations && BreakConstructorInitializers == R.BreakConstructorInitializers && diff --git a/clang/lib/Format/ContinuationIndenter.cpp b/clang/lib/Format/ContinuationIndenter.cpp index aed86c1fb99551..4c783623afc535 100644 --- a/clang/lib/Format/ContinuationIndenter.cpp +++ b/clang/lib/Format/ContinuationIndenter.cpp @@ -406,6 +406,10 @@ bool ContinuationIndenter::mustBreak(const LineState &State) { } if (CurrentState.BreakBeforeClosingParen && Current.is(tok::r_paren)) return true; + if (CurrentState.BreakBeforeClosingAngle && + Current.ClosesTemplateDeclaration && Style.BreakBeforeTemplateClose) { +return true; + } if (Style.Language == FormatStyle::LK_ObjC && Style.ObjCBreakBeforeNestedBlockParam && Current.ObjCSelectorNameParts > 1 && @@ -1234,6 +1238,9 @@ unsigned ContinuationIndenter::addTokenOnNewLine(LineState &State, Style.AlignAfterOpenBracket == FormatStyle::BAS_BlockIndent; } + if (PreviousNonComment && PreviousNonComment->is(tok::less)) +CurrentState.BreakBeforeClosingAngle = true; + if (CurrentState.AvoidBinPacking) { // If we are breaking after '(', '{', '<', or this is the break after a ':' // to start a member initializer list in a constructor, this should not @@ -1370,6 +1377,10 @@ unsigned ContinuationIndenter::getNewLineColumn(const LineState &State) { State.Stack.size() > 1) { return State.Stack[State.Stack.size() - 2].La
[clang] [clang-format] Add BreakBeforeTemplateClose option (PR #118046)
https://github.com/leijurv updated https://github.com/llvm/llvm-project/pull/118046 >From 1caf823165b16f6701993d586df51d5cdbf0885e Mon Sep 17 00:00:00 2001 From: Leijurv Date: Fri, 29 Nov 2024 21:54:36 -0600 Subject: [PATCH 01/13] [clang-format] Add BreakBeforeTemplateClose option --- clang/docs/ClangFormatStyleOptions.rst | 21 clang/docs/ReleaseNotes.rst| 1 + clang/include/clang/Format/Format.h| 20 clang/lib/Format/ContinuationIndenter.cpp | 11 ++ clang/lib/Format/ContinuationIndenter.h| 26 ++-- clang/lib/Format/Format.cpp| 2 + clang/lib/Format/TokenAnnotator.cpp| 2 +- clang/unittests/Format/ConfigParseTest.cpp | 1 + clang/unittests/Format/FormatTest.cpp | 131 + 9 files changed, 206 insertions(+), 9 deletions(-) diff --git a/clang/docs/ClangFormatStyleOptions.rst b/clang/docs/ClangFormatStyleOptions.rst index 4be448171699ca..84ab1b0a2eff61 100644 --- a/clang/docs/ClangFormatStyleOptions.rst +++ b/clang/docs/ClangFormatStyleOptions.rst @@ -3416,6 +3416,27 @@ the configuration (without a prefix: ``Auto``). +.. _BreakBeforeTemplateClose: + +**BreakBeforeTemplateClose** (``Boolean``) :versionbadge:`clang-format 20` :ref:`¶ ` + If ``true``, a line break will be placed before the ``>`` in a multiline + template declaration. + + .. code-block:: c++ + + true: + template < + typename Foo, + typename Bar, + typename Baz + > + + false: + template < + typename Foo, + typename Bar, + typename Baz> + .. _BreakBeforeTernaryOperators: **BreakBeforeTernaryOperators** (``Boolean``) :versionbadge:`clang-format 3.7` :ref:`¶ ` diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst index e44aefa90ab386..867d4b5d8c3f18 100644 --- a/clang/docs/ReleaseNotes.rst +++ b/clang/docs/ReleaseNotes.rst @@ -976,6 +976,7 @@ clang-format ``Never``, and ``true`` to ``Always``. - Adds ``RemoveEmptyLinesInUnwrappedLines`` option. - Adds ``KeepFormFeed`` option and set it to ``true`` for ``GNU`` style. +- Adds ``BreakBeforeTemplateClose`` option. libclang diff --git a/clang/include/clang/Format/Format.h b/clang/include/clang/Format/Format.h index 6383934afa2c40..bffd964f6aa8aa 100644 --- a/clang/include/clang/Format/Format.h +++ b/clang/include/clang/Format/Format.h @@ -2248,6 +2248,25 @@ struct FormatStyle { /// \version 16 BreakBeforeInlineASMColonStyle BreakBeforeInlineASMColon; + /// If ``true``, a line break will be placed before the ``>`` in a multiline + /// template declaration. + /// \code + ///true: + ///template < + ///typename Foo, + ///typename Bar, + ///typename Baz + ///> + /// + ///false: + ///template < + ///typename Foo, + ///typename Bar, + ///typename Baz> + /// \endcode + /// \version 20 + bool BreakBeforeTemplateClose; + /// If ``true``, ternary operators will be placed after line breaks. /// \code ///true: @@ -5184,6 +5203,7 @@ struct FormatStyle { BreakBeforeBraces == R.BreakBeforeBraces && BreakBeforeConceptDeclarations == R.BreakBeforeConceptDeclarations && BreakBeforeInlineASMColon == R.BreakBeforeInlineASMColon && + BreakBeforeTemplateClose == R.BreakBeforeTemplateClose && BreakBeforeTernaryOperators == R.BreakBeforeTernaryOperators && BreakBinaryOperations == R.BreakBinaryOperations && BreakConstructorInitializers == R.BreakConstructorInitializers && diff --git a/clang/lib/Format/ContinuationIndenter.cpp b/clang/lib/Format/ContinuationIndenter.cpp index aed86c1fb99551..4c783623afc535 100644 --- a/clang/lib/Format/ContinuationIndenter.cpp +++ b/clang/lib/Format/ContinuationIndenter.cpp @@ -406,6 +406,10 @@ bool ContinuationIndenter::mustBreak(const LineState &State) { } if (CurrentState.BreakBeforeClosingParen && Current.is(tok::r_paren)) return true; + if (CurrentState.BreakBeforeClosingAngle && + Current.ClosesTemplateDeclaration && Style.BreakBeforeTemplateClose) { +return true; + } if (Style.Language == FormatStyle::LK_ObjC && Style.ObjCBreakBeforeNestedBlockParam && Current.ObjCSelectorNameParts > 1 && @@ -1234,6 +1238,9 @@ unsigned ContinuationIndenter::addTokenOnNewLine(LineState &State, Style.AlignAfterOpenBracket == FormatStyle::BAS_BlockIndent; } + if (PreviousNonComment && PreviousNonComment->is(tok::less)) +CurrentState.BreakBeforeClosingAngle = true; + if (CurrentState.AvoidBinPacking) { // If we are breaking after '(', '{', '<', or this is the break after a ':' // to start a member initializer list in a constructor, this should not @@ -1370,6 +1377,10 @@ unsigned ContinuationIndenter::getNewLineColumn(const LineState &State) { State.Stack.size() > 1) { return State.Stack[State.Stack.size() - 2].La
[clang] [clang-format] Add BreakBeforeTemplateClose option (PR #118046)
@@ -11220,6 +11220,333 @@ TEST_F(FormatTest, WrapsTemplateDeclarationsWithComments) { Style); } +TEST_F(FormatTest, BreakBeforeTemplateCloser) { + FormatStyle Style = getGoogleStyle(FormatStyle::LK_Cpp); + // Begin with tests covering the case where there is no constraint on the + // column limit. + Style.ColumnLimit = 0; + // When BreakBeforeTemplateCloser is turned off, the line break that it adds + // shall be removed: + verifyFormat("template <\n" + "typename Foo,\n" + "typename Bar>\n" + "void foo() {}", + "template <\n" + "typename Foo,\n" + "typename Bar\n" + ">\n" + "void foo() {}", + Style); + + Style.BreakBeforeTemplateCloser = FormatStyle::BBTCS_BlockIndent; + // BreakBeforeTemplateCloser should NOT force template declarations onto + // multiple lines. + verifyFormat("template \n" + "void foo() {}", + Style); + verifyFormat("template \n" + "void foo() {}", + Style); + // It should allow a line break, even when the typename is short. + // verifyNoChange is needed because the default behavior is one line. + verifyNoChange("template <\n" + "typename Foo\n" + ">\n" + "void foo() {}", + Style); + verifyNoChange("template <\n" + "typename Foo,\n" + "typename Bar\n" + ">\n" + "void foo() {}", + Style); + verifyNoChange("template \n" + "void foo() {}", + Style); + // It should add a line break before > if not already present: + verifyFormat("template <\n" + "typename Foo\n" + ">\n" + "void foo() {}", + "template <\n" + "typename Foo>\n" + "void foo() {}", + Style); + verifyFormat("template <\n" + "typename Foo,\n" + "typename Bar\n" + ">\n" + "void foo() {}", + "template <\n" + "typename Foo,\n" + "typename Bar>\n" + "void foo() {}", + Style); + // When within an indent scope, the > should be placed accordingly: + verifyFormat("struct Baz {\n" + " template <\n" + " typename Foo,\n" + " typename Bar\n" + " >\n" + " void foo() {}\n" + "};", + "struct Baz {\n" + " template <\n" + " typename Foo,\n" + " typename Bar>\n" + " void foo() {}\n" + "};", + Style); + + // Test from issue #80049: + verifyFormat( + "void foo() {\n" + " using type = std::remove_cv_t<\n" + " add_common_cv_reference<\n" + " std::common_type_t, std::decay_t>,\n" + " T0,\n" + " T1\n" + " >\n" + " >;\n" + "}", + "void foo() {\n" + " using type = std::remove_cv_t<\n" + " add_common_cv_reference<\n" + " std::common_type_t, std::decay_t>,\n" + " T0,\n" + " T1>>;\n" + "}", + Style); + + // Test lambda goes to next line: + verifyFormat("void foo() {\n" + " auto lambda = []<\n" + "typename T\n" + ">(T t) {\n" + " };\n" + "}", + "void foo() {\n" + " auto lambda = []<\n" + " typename T>(T t){\n" + " };\n" + "}", + Style); + // With no column limit, two parameters can go on the same line: + verifyFormat("void foo() {\n" + " auto lambda = []<\n" + "typename T, typename Foo\n" + ">(T t) {\n" + " };\n" + "}", + "void foo() {\n" + " auto lambda = []<\n" + " typename T, typename Foo>(T t){\n" + " };\n" + "}", + Style); + // Or on different lines: + verifyFormat("void foo() {\n" + " auto lambda = []<\n" + "typename T,\n" + "typename Foo\n" + ">(T t) {\n" + " };\n" + "}", + "void foo() {\n" + " auto lambda = []<\n" + " typename T,\n" + " typename Foo>(T t){\n" + " };\n" + "}", + Style); + + // Note that this is the same line (no \n): + verifyFormat("void foo() {\n" + " auto lambd
[clang] [clang-format] Add BreakBeforeTemplateClose option (PR #118046)
@@ -11220,6 +11220,333 @@ TEST_F(FormatTest, WrapsTemplateDeclarationsWithComments) { Style); } +TEST_F(FormatTest, BreakBeforeTemplateCloser) { + FormatStyle Style = getGoogleStyle(FormatStyle::LK_Cpp); + // Begin with tests covering the case where there is no constraint on the + // column limit. + Style.ColumnLimit = 0; + // When BreakBeforeTemplateCloser is turned off, the line break that it adds + // shall be removed: + verifyFormat("template <\n" + "typename Foo,\n" + "typename Bar>\n" + "void foo() {}", + "template <\n" + "typename Foo,\n" + "typename Bar\n" + ">\n" + "void foo() {}", + Style); + + Style.BreakBeforeTemplateCloser = FormatStyle::BBTCS_BlockIndent; + // BreakBeforeTemplateCloser should NOT force template declarations onto + // multiple lines. + verifyFormat("template \n" + "void foo() {}", + Style); + verifyFormat("template \n" + "void foo() {}", + Style); + // It should allow a line break, even when the typename is short. + // verifyNoChange is needed because the default behavior is one line. + verifyNoChange("template <\n" + "typename Foo\n" + ">\n" + "void foo() {}", + Style); + verifyNoChange("template <\n" + "typename Foo,\n" + "typename Bar\n" + ">\n" + "void foo() {}", + Style); + verifyNoChange("template \n" + "void foo() {}", + Style); + // It should add a line break before > if not already present: + verifyFormat("template <\n" + "typename Foo\n" + ">\n" + "void foo() {}", + "template <\n" + "typename Foo>\n" + "void foo() {}", + Style); + verifyFormat("template <\n" + "typename Foo,\n" + "typename Bar\n" + ">\n" + "void foo() {}", + "template <\n" + "typename Foo,\n" + "typename Bar>\n" + "void foo() {}", + Style); + // When within an indent scope, the > should be placed accordingly: + verifyFormat("struct Baz {\n" + " template <\n" + " typename Foo,\n" + " typename Bar\n" + " >\n" + " void foo() {}\n" + "};", + "struct Baz {\n" + " template <\n" + " typename Foo,\n" + " typename Bar>\n" + " void foo() {}\n" + "};", + Style); + + // Test from issue #80049: + verifyFormat( + "void foo() {\n" + " using type = std::remove_cv_t<\n" + " add_common_cv_reference<\n" + " std::common_type_t, std::decay_t>,\n" + " T0,\n" + " T1\n" + " >\n" + " >;\n" + "}", + "void foo() {\n" + " using type = std::remove_cv_t<\n" + " add_common_cv_reference<\n" + " std::common_type_t, std::decay_t>,\n" + " T0,\n" + " T1>>;\n" + "}", + Style); + + // Test lambda goes to next line: + verifyFormat("void foo() {\n" + " auto lambda = []<\n" + "typename T\n" + ">(T t) {\n" + " };\n" + "}", + "void foo() {\n" + " auto lambda = []<\n" + " typename T>(T t){\n" + " };\n" + "}", + Style); + // With no column limit, two parameters can go on the same line: + verifyFormat("void foo() {\n" + " auto lambda = []<\n" + "typename T, typename Foo\n" + ">(T t) {\n" + " };\n" + "}", + "void foo() {\n" + " auto lambda = []<\n" + " typename T, typename Foo>(T t){\n" + " };\n" + "}", + Style); + // Or on different lines: + verifyFormat("void foo() {\n" + " auto lambda = []<\n" + "typename T,\n" + "typename Foo\n" + ">(T t) {\n" + " };\n" + "}", + "void foo() {\n" + " auto lambda = []<\n" + " typename T,\n" + " typename Foo>(T t){\n" + " };\n" + "}", + Style); + + // Note that this is the same line (no \n): + verifyFormat("void foo() {\n" + " auto lambd
[clang] [clang-format] Add BreakBeforeTemplateClose option (PR #118046)
@@ -11220,6 +11220,333 @@ TEST_F(FormatTest, WrapsTemplateDeclarationsWithComments) { Style); } +TEST_F(FormatTest, BreakBeforeTemplateCloser) { + FormatStyle Style = getGoogleStyle(FormatStyle::LK_Cpp); + // Begin with tests covering the case where there is no constraint on the + // column limit. + Style.ColumnLimit = 0; + // When BreakBeforeTemplateCloser is turned off, the line break that it adds + // shall be removed: + verifyFormat("template <\n" + "typename Foo,\n" + "typename Bar>\n" + "void foo() {}", + "template <\n" + "typename Foo,\n" + "typename Bar\n" + ">\n" + "void foo() {}", + Style); + + Style.BreakBeforeTemplateCloser = FormatStyle::BBTCS_BlockIndent; + // BreakBeforeTemplateCloser should NOT force template declarations onto + // multiple lines. + verifyFormat("template \n" + "void foo() {}", + Style); + verifyFormat("template \n" + "void foo() {}", + Style); + // It should allow a line break, even when the typename is short. + // verifyNoChange is needed because the default behavior is one line. + verifyNoChange("template <\n" + "typename Foo\n" + ">\n" + "void foo() {}", + Style); + verifyNoChange("template <\n" + "typename Foo,\n" + "typename Bar\n" + ">\n" + "void foo() {}", + Style); + verifyNoChange("template \n" + "void foo() {}", + Style); + // It should add a line break before > if not already present: + verifyFormat("template <\n" + "typename Foo\n" + ">\n" + "void foo() {}", + "template <\n" + "typename Foo>\n" + "void foo() {}", + Style); + verifyFormat("template <\n" + "typename Foo,\n" + "typename Bar\n" + ">\n" + "void foo() {}", + "template <\n" + "typename Foo,\n" + "typename Bar>\n" + "void foo() {}", + Style); + // When within an indent scope, the > should be placed accordingly: + verifyFormat("struct Baz {\n" + " template <\n" + " typename Foo,\n" + " typename Bar\n" + " >\n" + " void foo() {}\n" + "};", + "struct Baz {\n" + " template <\n" + " typename Foo,\n" + " typename Bar>\n" + " void foo() {}\n" + "};", + Style); + + // Test from issue #80049: + verifyFormat( + "void foo() {\n" + " using type = std::remove_cv_t<\n" + " add_common_cv_reference<\n" + " std::common_type_t, std::decay_t>,\n" + " T0,\n" + " T1\n" + " >\n" + " >;\n" + "}", + "void foo() {\n" + " using type = std::remove_cv_t<\n" + " add_common_cv_reference<\n" + " std::common_type_t, std::decay_t>,\n" + " T0,\n" + " T1>>;\n" + "}", + Style); + + // Test lambda goes to next line: + verifyFormat("void foo() {\n" + " auto lambda = []<\n" + "typename T\n" + ">(T t) {\n" + " };\n" + "}", + "void foo() {\n" + " auto lambda = []<\n" + " typename T>(T t){\n" + " };\n" + "}", + Style); + // With no column limit, two parameters can go on the same line: + verifyFormat("void foo() {\n" + " auto lambda = []<\n" + "typename T, typename Foo\n" + ">(T t) {\n" + " };\n" + "}", + "void foo() {\n" + " auto lambda = []<\n" + " typename T, typename Foo>(T t){\n" + " };\n" + "}", + Style); + // Or on different lines: + verifyFormat("void foo() {\n" + " auto lambda = []<\n" + "typename T,\n" + "typename Foo\n" + ">(T t) {\n" + " };\n" + "}", + "void foo() {\n" + " auto lambda = []<\n" + " typename T,\n" + " typename Foo>(T t){\n" + " };\n" + "}", + Style); + + // Note that this is the same line (no \n): + verifyFormat("void foo() {\n" + " auto lambd
[clang] [clang-format] Add BreakBeforeTemplateClose option (PR #118046)
https://github.com/leijurv updated https://github.com/llvm/llvm-project/pull/118046 >From 1caf823165b16f6701993d586df51d5cdbf0885e Mon Sep 17 00:00:00 2001 From: Leijurv Date: Fri, 29 Nov 2024 21:54:36 -0600 Subject: [PATCH 01/13] [clang-format] Add BreakBeforeTemplateClose option --- clang/docs/ClangFormatStyleOptions.rst | 21 clang/docs/ReleaseNotes.rst| 1 + clang/include/clang/Format/Format.h| 20 clang/lib/Format/ContinuationIndenter.cpp | 11 ++ clang/lib/Format/ContinuationIndenter.h| 26 ++-- clang/lib/Format/Format.cpp| 2 + clang/lib/Format/TokenAnnotator.cpp| 2 +- clang/unittests/Format/ConfigParseTest.cpp | 1 + clang/unittests/Format/FormatTest.cpp | 131 + 9 files changed, 206 insertions(+), 9 deletions(-) diff --git a/clang/docs/ClangFormatStyleOptions.rst b/clang/docs/ClangFormatStyleOptions.rst index 4be448171699ca..84ab1b0a2eff61 100644 --- a/clang/docs/ClangFormatStyleOptions.rst +++ b/clang/docs/ClangFormatStyleOptions.rst @@ -3416,6 +3416,27 @@ the configuration (without a prefix: ``Auto``). +.. _BreakBeforeTemplateClose: + +**BreakBeforeTemplateClose** (``Boolean``) :versionbadge:`clang-format 20` :ref:`¶ ` + If ``true``, a line break will be placed before the ``>`` in a multiline + template declaration. + + .. code-block:: c++ + + true: + template < + typename Foo, + typename Bar, + typename Baz + > + + false: + template < + typename Foo, + typename Bar, + typename Baz> + .. _BreakBeforeTernaryOperators: **BreakBeforeTernaryOperators** (``Boolean``) :versionbadge:`clang-format 3.7` :ref:`¶ ` diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst index e44aefa90ab386..867d4b5d8c3f18 100644 --- a/clang/docs/ReleaseNotes.rst +++ b/clang/docs/ReleaseNotes.rst @@ -976,6 +976,7 @@ clang-format ``Never``, and ``true`` to ``Always``. - Adds ``RemoveEmptyLinesInUnwrappedLines`` option. - Adds ``KeepFormFeed`` option and set it to ``true`` for ``GNU`` style. +- Adds ``BreakBeforeTemplateClose`` option. libclang diff --git a/clang/include/clang/Format/Format.h b/clang/include/clang/Format/Format.h index 6383934afa2c40..bffd964f6aa8aa 100644 --- a/clang/include/clang/Format/Format.h +++ b/clang/include/clang/Format/Format.h @@ -2248,6 +2248,25 @@ struct FormatStyle { /// \version 16 BreakBeforeInlineASMColonStyle BreakBeforeInlineASMColon; + /// If ``true``, a line break will be placed before the ``>`` in a multiline + /// template declaration. + /// \code + ///true: + ///template < + ///typename Foo, + ///typename Bar, + ///typename Baz + ///> + /// + ///false: + ///template < + ///typename Foo, + ///typename Bar, + ///typename Baz> + /// \endcode + /// \version 20 + bool BreakBeforeTemplateClose; + /// If ``true``, ternary operators will be placed after line breaks. /// \code ///true: @@ -5184,6 +5203,7 @@ struct FormatStyle { BreakBeforeBraces == R.BreakBeforeBraces && BreakBeforeConceptDeclarations == R.BreakBeforeConceptDeclarations && BreakBeforeInlineASMColon == R.BreakBeforeInlineASMColon && + BreakBeforeTemplateClose == R.BreakBeforeTemplateClose && BreakBeforeTernaryOperators == R.BreakBeforeTernaryOperators && BreakBinaryOperations == R.BreakBinaryOperations && BreakConstructorInitializers == R.BreakConstructorInitializers && diff --git a/clang/lib/Format/ContinuationIndenter.cpp b/clang/lib/Format/ContinuationIndenter.cpp index aed86c1fb99551..4c783623afc535 100644 --- a/clang/lib/Format/ContinuationIndenter.cpp +++ b/clang/lib/Format/ContinuationIndenter.cpp @@ -406,6 +406,10 @@ bool ContinuationIndenter::mustBreak(const LineState &State) { } if (CurrentState.BreakBeforeClosingParen && Current.is(tok::r_paren)) return true; + if (CurrentState.BreakBeforeClosingAngle && + Current.ClosesTemplateDeclaration && Style.BreakBeforeTemplateClose) { +return true; + } if (Style.Language == FormatStyle::LK_ObjC && Style.ObjCBreakBeforeNestedBlockParam && Current.ObjCSelectorNameParts > 1 && @@ -1234,6 +1238,9 @@ unsigned ContinuationIndenter::addTokenOnNewLine(LineState &State, Style.AlignAfterOpenBracket == FormatStyle::BAS_BlockIndent; } + if (PreviousNonComment && PreviousNonComment->is(tok::less)) +CurrentState.BreakBeforeClosingAngle = true; + if (CurrentState.AvoidBinPacking) { // If we are breaking after '(', '{', '<', or this is the break after a ':' // to start a member initializer list in a constructor, this should not @@ -1370,6 +1377,10 @@ unsigned ContinuationIndenter::getNewLineColumn(const LineState &State) { State.Stack.size() > 1) { return State.Stack[State.Stack.size() - 2].La
[clang] [clang-format] Add BreakBeforeTemplateClose option (PR #118046)
https://github.com/leijurv edited https://github.com/llvm/llvm-project/pull/118046 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang-format] Add BreakBeforeTemplateClose option (PR #118046)
https://github.com/leijurv edited https://github.com/llvm/llvm-project/pull/118046 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang-format] Add BreakBeforeTemplateClose option (PR #118046)
https://github.com/leijurv updated https://github.com/llvm/llvm-project/pull/118046 >From 1caf823165b16f6701993d586df51d5cdbf0885e Mon Sep 17 00:00:00 2001 From: Leijurv Date: Fri, 29 Nov 2024 21:54:36 -0600 Subject: [PATCH 01/13] [clang-format] Add BreakBeforeTemplateClose option --- clang/docs/ClangFormatStyleOptions.rst | 21 clang/docs/ReleaseNotes.rst| 1 + clang/include/clang/Format/Format.h| 20 clang/lib/Format/ContinuationIndenter.cpp | 11 ++ clang/lib/Format/ContinuationIndenter.h| 26 ++-- clang/lib/Format/Format.cpp| 2 + clang/lib/Format/TokenAnnotator.cpp| 2 +- clang/unittests/Format/ConfigParseTest.cpp | 1 + clang/unittests/Format/FormatTest.cpp | 131 + 9 files changed, 206 insertions(+), 9 deletions(-) diff --git a/clang/docs/ClangFormatStyleOptions.rst b/clang/docs/ClangFormatStyleOptions.rst index 4be448171699ca..84ab1b0a2eff61 100644 --- a/clang/docs/ClangFormatStyleOptions.rst +++ b/clang/docs/ClangFormatStyleOptions.rst @@ -3416,6 +3416,27 @@ the configuration (without a prefix: ``Auto``). +.. _BreakBeforeTemplateClose: + +**BreakBeforeTemplateClose** (``Boolean``) :versionbadge:`clang-format 20` :ref:`¶ ` + If ``true``, a line break will be placed before the ``>`` in a multiline + template declaration. + + .. code-block:: c++ + + true: + template < + typename Foo, + typename Bar, + typename Baz + > + + false: + template < + typename Foo, + typename Bar, + typename Baz> + .. _BreakBeforeTernaryOperators: **BreakBeforeTernaryOperators** (``Boolean``) :versionbadge:`clang-format 3.7` :ref:`¶ ` diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst index e44aefa90ab386..867d4b5d8c3f18 100644 --- a/clang/docs/ReleaseNotes.rst +++ b/clang/docs/ReleaseNotes.rst @@ -976,6 +976,7 @@ clang-format ``Never``, and ``true`` to ``Always``. - Adds ``RemoveEmptyLinesInUnwrappedLines`` option. - Adds ``KeepFormFeed`` option and set it to ``true`` for ``GNU`` style. +- Adds ``BreakBeforeTemplateClose`` option. libclang diff --git a/clang/include/clang/Format/Format.h b/clang/include/clang/Format/Format.h index 6383934afa2c40..bffd964f6aa8aa 100644 --- a/clang/include/clang/Format/Format.h +++ b/clang/include/clang/Format/Format.h @@ -2248,6 +2248,25 @@ struct FormatStyle { /// \version 16 BreakBeforeInlineASMColonStyle BreakBeforeInlineASMColon; + /// If ``true``, a line break will be placed before the ``>`` in a multiline + /// template declaration. + /// \code + ///true: + ///template < + ///typename Foo, + ///typename Bar, + ///typename Baz + ///> + /// + ///false: + ///template < + ///typename Foo, + ///typename Bar, + ///typename Baz> + /// \endcode + /// \version 20 + bool BreakBeforeTemplateClose; + /// If ``true``, ternary operators will be placed after line breaks. /// \code ///true: @@ -5184,6 +5203,7 @@ struct FormatStyle { BreakBeforeBraces == R.BreakBeforeBraces && BreakBeforeConceptDeclarations == R.BreakBeforeConceptDeclarations && BreakBeforeInlineASMColon == R.BreakBeforeInlineASMColon && + BreakBeforeTemplateClose == R.BreakBeforeTemplateClose && BreakBeforeTernaryOperators == R.BreakBeforeTernaryOperators && BreakBinaryOperations == R.BreakBinaryOperations && BreakConstructorInitializers == R.BreakConstructorInitializers && diff --git a/clang/lib/Format/ContinuationIndenter.cpp b/clang/lib/Format/ContinuationIndenter.cpp index aed86c1fb99551..4c783623afc535 100644 --- a/clang/lib/Format/ContinuationIndenter.cpp +++ b/clang/lib/Format/ContinuationIndenter.cpp @@ -406,6 +406,10 @@ bool ContinuationIndenter::mustBreak(const LineState &State) { } if (CurrentState.BreakBeforeClosingParen && Current.is(tok::r_paren)) return true; + if (CurrentState.BreakBeforeClosingAngle && + Current.ClosesTemplateDeclaration && Style.BreakBeforeTemplateClose) { +return true; + } if (Style.Language == FormatStyle::LK_ObjC && Style.ObjCBreakBeforeNestedBlockParam && Current.ObjCSelectorNameParts > 1 && @@ -1234,6 +1238,9 @@ unsigned ContinuationIndenter::addTokenOnNewLine(LineState &State, Style.AlignAfterOpenBracket == FormatStyle::BAS_BlockIndent; } + if (PreviousNonComment && PreviousNonComment->is(tok::less)) +CurrentState.BreakBeforeClosingAngle = true; + if (CurrentState.AvoidBinPacking) { // If we are breaking after '(', '{', '<', or this is the break after a ':' // to start a member initializer list in a constructor, this should not @@ -1370,6 +1377,10 @@ unsigned ContinuationIndenter::getNewLineColumn(const LineState &State) { State.Stack.size() > 1) { return State.Stack[State.Stack.size() - 2].La
[clang] [clang-format] Add BreakBeforeTemplateClose option (PR #118046)
@@ -11220,6 +11220,333 @@ TEST_F(FormatTest, WrapsTemplateDeclarationsWithComments) { Style); } +TEST_F(FormatTest, BreakBeforeTemplateCloser) { + FormatStyle Style = getGoogleStyle(FormatStyle::LK_Cpp); + // Begin with tests covering the case where there is no constraint on the + // column limit. + Style.ColumnLimit = 0; + // When BreakBeforeTemplateCloser is turned off, the line break that it adds + // shall be removed: + verifyFormat("template <\n" + "typename Foo,\n" + "typename Bar>\n" + "void foo() {}", + "template <\n" + "typename Foo,\n" + "typename Bar\n" + ">\n" + "void foo() {}", + Style); + + Style.BreakBeforeTemplateCloser = FormatStyle::BBTCS_BlockIndent; + // BreakBeforeTemplateCloser should NOT force template declarations onto + // multiple lines. + verifyFormat("template \n" + "void foo() {}", + Style); + verifyFormat("template \n" + "void foo() {}", + Style); + // It should allow a line break, even when the typename is short. + // verifyNoChange is needed because the default behavior is one line. + verifyNoChange("template <\n" + "typename Foo\n" + ">\n" + "void foo() {}", + Style); + verifyNoChange("template <\n" + "typename Foo,\n" + "typename Bar\n" + ">\n" + "void foo() {}", + Style); + verifyNoChange("template \n" + "void foo() {}", + Style); + // It should add a line break before > if not already present: + verifyFormat("template <\n" + "typename Foo\n" + ">\n" + "void foo() {}", + "template <\n" + "typename Foo>\n" + "void foo() {}", + Style); + verifyFormat("template <\n" + "typename Foo,\n" + "typename Bar\n" + ">\n" + "void foo() {}", + "template <\n" + "typename Foo,\n" + "typename Bar>\n" + "void foo() {}", + Style); + // When within an indent scope, the > should be placed accordingly: + verifyFormat("struct Baz {\n" + " template <\n" + " typename Foo,\n" + " typename Bar\n" + " >\n" + " void foo() {}\n" + "};", + "struct Baz {\n" + " template <\n" + " typename Foo,\n" + " typename Bar>\n" + " void foo() {}\n" + "};", + Style); + + // Test from issue #80049: + verifyFormat( + "void foo() {\n" + " using type = std::remove_cv_t<\n" + " add_common_cv_reference<\n" + " std::common_type_t, std::decay_t>,\n" + " T0,\n" + " T1\n" + " >\n" + " >;\n" + "}", + "void foo() {\n" + " using type = std::remove_cv_t<\n" + " add_common_cv_reference<\n" + " std::common_type_t, std::decay_t>,\n" + " T0,\n" + " T1>>;\n" + "}", + Style); + + // Test lambda goes to next line: + verifyFormat("void foo() {\n" + " auto lambda = []<\n" + "typename T\n" + ">(T t) {\n" + " };\n" + "}", + "void foo() {\n" + " auto lambda = []<\n" + " typename T>(T t){\n" + " };\n" + "}", + Style); + // With no column limit, two parameters can go on the same line: + verifyFormat("void foo() {\n" + " auto lambda = []<\n" + "typename T, typename Foo\n" + ">(T t) {\n" + " };\n" + "}", + "void foo() {\n" + " auto lambda = []<\n" + " typename T, typename Foo>(T t){\n" + " };\n" + "}", + Style); + // Or on different lines: + verifyFormat("void foo() {\n" + " auto lambda = []<\n" + "typename T,\n" + "typename Foo\n" + ">(T t) {\n" + " };\n" + "}", + "void foo() {\n" + " auto lambda = []<\n" + " typename T,\n" + " typename Foo>(T t){\n" + " };\n" + "}", + Style); + + // Note that this is the same line (no \n): + verifyFormat("void foo() {\n" + " auto lambd
[clang] [clang-format] Add BreakBeforeTemplateClose option (PR #118046)
@@ -11220,6 +11220,333 @@ TEST_F(FormatTest, WrapsTemplateDeclarationsWithComments) { Style); } +TEST_F(FormatTest, BreakBeforeTemplateCloser) { + FormatStyle Style = getGoogleStyle(FormatStyle::LK_Cpp); + // Begin with tests covering the case where there is no constraint on the + // column limit. + Style.ColumnLimit = 0; + // When BreakBeforeTemplateCloser is turned off, the line break that it adds + // shall be removed: + verifyFormat("template <\n" + "typename Foo,\n" + "typename Bar>\n" + "void foo() {}", + "template <\n" + "typename Foo,\n" + "typename Bar\n" + ">\n" + "void foo() {}", + Style); + + Style.BreakBeforeTemplateCloser = FormatStyle::BBTCS_BlockIndent; + // BreakBeforeTemplateCloser should NOT force template declarations onto + // multiple lines. + verifyFormat("template \n" + "void foo() {}", + Style); + verifyFormat("template \n" + "void foo() {}", + Style); + // It should allow a line break, even when the typename is short. + // verifyNoChange is needed because the default behavior is one line. + verifyNoChange("template <\n" + "typename Foo\n" + ">\n" + "void foo() {}", + Style); + verifyNoChange("template <\n" + "typename Foo,\n" + "typename Bar\n" + ">\n" + "void foo() {}", + Style); + verifyNoChange("template \n" + "void foo() {}", + Style); + // It should add a line break before > if not already present: + verifyFormat("template <\n" + "typename Foo\n" + ">\n" + "void foo() {}", + "template <\n" + "typename Foo>\n" + "void foo() {}", + Style); + verifyFormat("template <\n" + "typename Foo,\n" + "typename Bar\n" + ">\n" + "void foo() {}", + "template <\n" + "typename Foo,\n" + "typename Bar>\n" + "void foo() {}", + Style); + // When within an indent scope, the > should be placed accordingly: + verifyFormat("struct Baz {\n" + " template <\n" + " typename Foo,\n" + " typename Bar\n" + " >\n" + " void foo() {}\n" + "};", + "struct Baz {\n" + " template <\n" + " typename Foo,\n" + " typename Bar>\n" + " void foo() {}\n" + "};", + Style); + + // Test from issue #80049: + verifyFormat( + "void foo() {\n" + " using type = std::remove_cv_t<\n" + " add_common_cv_reference<\n" + " std::common_type_t, std::decay_t>,\n" + " T0,\n" + " T1\n" + " >\n" + " >;\n" + "}", + "void foo() {\n" + " using type = std::remove_cv_t<\n" + " add_common_cv_reference<\n" + " std::common_type_t, std::decay_t>,\n" + " T0,\n" + " T1>>;\n" + "}", + Style); + + // Test lambda goes to next line: + verifyFormat("void foo() {\n" + " auto lambda = []<\n" + "typename T\n" + ">(T t) {\n" + " };\n" + "}", + "void foo() {\n" + " auto lambda = []<\n" + " typename T>(T t){\n" + " };\n" + "}", + Style); + // With no column limit, two parameters can go on the same line: + verifyFormat("void foo() {\n" + " auto lambda = []<\n" + "typename T, typename Foo\n" + ">(T t) {\n" + " };\n" + "}", + "void foo() {\n" + " auto lambda = []<\n" + " typename T, typename Foo>(T t){\n" + " };\n" + "}", + Style); + // Or on different lines: + verifyFormat("void foo() {\n" + " auto lambda = []<\n" + "typename T,\n" + "typename Foo\n" + ">(T t) {\n" + " };\n" + "}", + "void foo() {\n" + " auto lambda = []<\n" + " typename T,\n" + " typename Foo>(T t){\n" + " };\n" + "}", + Style); + + // Note that this is the same line (no \n): + verifyFormat("void foo() {\n" + " auto lambd
[clang] [clang-format] Add BreakBeforeTemplateClose option (PR #118046)
https://github.com/leijurv updated https://github.com/llvm/llvm-project/pull/118046 >From 1caf823165b16f6701993d586df51d5cdbf0885e Mon Sep 17 00:00:00 2001 From: Leijurv Date: Fri, 29 Nov 2024 21:54:36 -0600 Subject: [PATCH 01/13] [clang-format] Add BreakBeforeTemplateClose option --- clang/docs/ClangFormatStyleOptions.rst | 21 clang/docs/ReleaseNotes.rst| 1 + clang/include/clang/Format/Format.h| 20 clang/lib/Format/ContinuationIndenter.cpp | 11 ++ clang/lib/Format/ContinuationIndenter.h| 26 ++-- clang/lib/Format/Format.cpp| 2 + clang/lib/Format/TokenAnnotator.cpp| 2 +- clang/unittests/Format/ConfigParseTest.cpp | 1 + clang/unittests/Format/FormatTest.cpp | 131 + 9 files changed, 206 insertions(+), 9 deletions(-) diff --git a/clang/docs/ClangFormatStyleOptions.rst b/clang/docs/ClangFormatStyleOptions.rst index 4be448171699ca..84ab1b0a2eff61 100644 --- a/clang/docs/ClangFormatStyleOptions.rst +++ b/clang/docs/ClangFormatStyleOptions.rst @@ -3416,6 +3416,27 @@ the configuration (without a prefix: ``Auto``). +.. _BreakBeforeTemplateClose: + +**BreakBeforeTemplateClose** (``Boolean``) :versionbadge:`clang-format 20` :ref:`¶ ` + If ``true``, a line break will be placed before the ``>`` in a multiline + template declaration. + + .. code-block:: c++ + + true: + template < + typename Foo, + typename Bar, + typename Baz + > + + false: + template < + typename Foo, + typename Bar, + typename Baz> + .. _BreakBeforeTernaryOperators: **BreakBeforeTernaryOperators** (``Boolean``) :versionbadge:`clang-format 3.7` :ref:`¶ ` diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst index e44aefa90ab386..867d4b5d8c3f18 100644 --- a/clang/docs/ReleaseNotes.rst +++ b/clang/docs/ReleaseNotes.rst @@ -976,6 +976,7 @@ clang-format ``Never``, and ``true`` to ``Always``. - Adds ``RemoveEmptyLinesInUnwrappedLines`` option. - Adds ``KeepFormFeed`` option and set it to ``true`` for ``GNU`` style. +- Adds ``BreakBeforeTemplateClose`` option. libclang diff --git a/clang/include/clang/Format/Format.h b/clang/include/clang/Format/Format.h index 6383934afa2c40..bffd964f6aa8aa 100644 --- a/clang/include/clang/Format/Format.h +++ b/clang/include/clang/Format/Format.h @@ -2248,6 +2248,25 @@ struct FormatStyle { /// \version 16 BreakBeforeInlineASMColonStyle BreakBeforeInlineASMColon; + /// If ``true``, a line break will be placed before the ``>`` in a multiline + /// template declaration. + /// \code + ///true: + ///template < + ///typename Foo, + ///typename Bar, + ///typename Baz + ///> + /// + ///false: + ///template < + ///typename Foo, + ///typename Bar, + ///typename Baz> + /// \endcode + /// \version 20 + bool BreakBeforeTemplateClose; + /// If ``true``, ternary operators will be placed after line breaks. /// \code ///true: @@ -5184,6 +5203,7 @@ struct FormatStyle { BreakBeforeBraces == R.BreakBeforeBraces && BreakBeforeConceptDeclarations == R.BreakBeforeConceptDeclarations && BreakBeforeInlineASMColon == R.BreakBeforeInlineASMColon && + BreakBeforeTemplateClose == R.BreakBeforeTemplateClose && BreakBeforeTernaryOperators == R.BreakBeforeTernaryOperators && BreakBinaryOperations == R.BreakBinaryOperations && BreakConstructorInitializers == R.BreakConstructorInitializers && diff --git a/clang/lib/Format/ContinuationIndenter.cpp b/clang/lib/Format/ContinuationIndenter.cpp index aed86c1fb99551..4c783623afc535 100644 --- a/clang/lib/Format/ContinuationIndenter.cpp +++ b/clang/lib/Format/ContinuationIndenter.cpp @@ -406,6 +406,10 @@ bool ContinuationIndenter::mustBreak(const LineState &State) { } if (CurrentState.BreakBeforeClosingParen && Current.is(tok::r_paren)) return true; + if (CurrentState.BreakBeforeClosingAngle && + Current.ClosesTemplateDeclaration && Style.BreakBeforeTemplateClose) { +return true; + } if (Style.Language == FormatStyle::LK_ObjC && Style.ObjCBreakBeforeNestedBlockParam && Current.ObjCSelectorNameParts > 1 && @@ -1234,6 +1238,9 @@ unsigned ContinuationIndenter::addTokenOnNewLine(LineState &State, Style.AlignAfterOpenBracket == FormatStyle::BAS_BlockIndent; } + if (PreviousNonComment && PreviousNonComment->is(tok::less)) +CurrentState.BreakBeforeClosingAngle = true; + if (CurrentState.AvoidBinPacking) { // If we are breaking after '(', '{', '<', or this is the break after a ':' // to start a member initializer list in a constructor, this should not @@ -1370,6 +1377,10 @@ unsigned ContinuationIndenter::getNewLineColumn(const LineState &State) { State.Stack.size() > 1) { return State.Stack[State.Stack.size() - 2].La
[clang] [clang-format] Add BreakBeforeTemplateClose option (PR #118046)
@@ -11220,6 +11220,333 @@ TEST_F(FormatTest, WrapsTemplateDeclarationsWithComments) { Style); } +TEST_F(FormatTest, BreakBeforeTemplateCloser) { + FormatStyle Style = getGoogleStyle(FormatStyle::LK_Cpp); + // Begin with tests covering the case where there is no constraint on the + // column limit. + Style.ColumnLimit = 0; + // When BreakBeforeTemplateCloser is turned off, the line break that it adds + // shall be removed: + verifyFormat("template <\n" + "typename Foo,\n" + "typename Bar>\n" + "void foo() {}", + "template <\n" + "typename Foo,\n" + "typename Bar\n" + ">\n" + "void foo() {}", + Style); + + Style.BreakBeforeTemplateCloser = FormatStyle::BBTCS_BlockIndent; + // BreakBeforeTemplateCloser should NOT force template declarations onto + // multiple lines. + verifyFormat("template \n" + "void foo() {}", + Style); + verifyFormat("template \n" + "void foo() {}", + Style); + // It should allow a line break, even when the typename is short. + // verifyNoChange is needed because the default behavior is one line. + verifyNoChange("template <\n" + "typename Foo\n" + ">\n" + "void foo() {}", + Style); + verifyNoChange("template <\n" + "typename Foo,\n" + "typename Bar\n" + ">\n" + "void foo() {}", + Style); + verifyNoChange("template \n" + "void foo() {}", + Style); + // It should add a line break before > if not already present: + verifyFormat("template <\n" + "typename Foo\n" + ">\n" + "void foo() {}", + "template <\n" + "typename Foo>\n" + "void foo() {}", + Style); + verifyFormat("template <\n" + "typename Foo,\n" + "typename Bar\n" + ">\n" + "void foo() {}", + "template <\n" + "typename Foo,\n" + "typename Bar>\n" + "void foo() {}", + Style); + // When within an indent scope, the > should be placed accordingly: + verifyFormat("struct Baz {\n" + " template <\n" + " typename Foo,\n" + " typename Bar\n" + " >\n" + " void foo() {}\n" + "};", + "struct Baz {\n" + " template <\n" + " typename Foo,\n" + " typename Bar>\n" + " void foo() {}\n" + "};", + Style); + + // Test from issue #80049: + verifyFormat( + "void foo() {\n" + " using type = std::remove_cv_t<\n" + " add_common_cv_reference<\n" + " std::common_type_t, std::decay_t>,\n" + " T0,\n" + " T1\n" + " >\n" + " >;\n" + "}", + "void foo() {\n" + " using type = std::remove_cv_t<\n" + " add_common_cv_reference<\n" + " std::common_type_t, std::decay_t>,\n" + " T0,\n" + " T1>>;\n" + "}", owenca wrote: ```suggestion // Test from https://github.com/llvm/llvm-project/issues/80049: verifyFormat( "using type = std::remove_cv_t<\n" "add_common_cv_reference<\n" "std::common_type_t, std::decay_t>,\n" "T0,\n" "T1\n" ">\n" ">;", "using type = std::remove_cv_t<\n" "add_common_cv_reference<\n" "std::common_type_t, std::decay_t>,\n" "T0,\n" "T1>>;", ``` https://github.com/llvm/llvm-project/pull/118046 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang-format] Add BreakBeforeTemplateClose option (PR #118046)
@@ -11220,6 +11220,333 @@ TEST_F(FormatTest, WrapsTemplateDeclarationsWithComments) { Style); } +TEST_F(FormatTest, BreakBeforeTemplateCloser) { + FormatStyle Style = getGoogleStyle(FormatStyle::LK_Cpp); + // Begin with tests covering the case where there is no constraint on the + // column limit. + Style.ColumnLimit = 0; + // When BreakBeforeTemplateCloser is turned off, the line break that it adds + // shall be removed: + verifyFormat("template <\n" + "typename Foo,\n" + "typename Bar>\n" + "void foo() {}", + "template <\n" + "typename Foo,\n" + "typename Bar\n" + ">\n" + "void foo() {}", + Style); + + Style.BreakBeforeTemplateCloser = FormatStyle::BBTCS_BlockIndent; + // BreakBeforeTemplateCloser should NOT force template declarations onto + // multiple lines. + verifyFormat("template \n" + "void foo() {}", + Style); + verifyFormat("template \n" + "void foo() {}", + Style); + // It should allow a line break, even when the typename is short. + // verifyNoChange is needed because the default behavior is one line. + verifyNoChange("template <\n" + "typename Foo\n" + ">\n" + "void foo() {}", + Style); + verifyNoChange("template <\n" + "typename Foo,\n" + "typename Bar\n" + ">\n" + "void foo() {}", + Style); + verifyNoChange("template \n" + "void foo() {}", + Style); + // It should add a line break before > if not already present: + verifyFormat("template <\n" + "typename Foo\n" + ">\n" + "void foo() {}", + "template <\n" + "typename Foo>\n" + "void foo() {}", + Style); + verifyFormat("template <\n" + "typename Foo,\n" + "typename Bar\n" + ">\n" + "void foo() {}", + "template <\n" + "typename Foo,\n" + "typename Bar>\n" + "void foo() {}", + Style); + // When within an indent scope, the > should be placed accordingly: + verifyFormat("struct Baz {\n" + " template <\n" + " typename Foo,\n" + " typename Bar\n" + " >\n" + " void foo() {}\n" + "};", + "struct Baz {\n" + " template <\n" + " typename Foo,\n" + " typename Bar>\n" + " void foo() {}\n" + "};", + Style); + + // Test from issue #80049: + verifyFormat( + "void foo() {\n" + " using type = std::remove_cv_t<\n" + " add_common_cv_reference<\n" + " std::common_type_t, std::decay_t>,\n" + " T0,\n" + " T1\n" + " >\n" + " >;\n" + "}", + "void foo() {\n" + " using type = std::remove_cv_t<\n" + " add_common_cv_reference<\n" + " std::common_type_t, std::decay_t>,\n" + " T0,\n" + " T1>>;\n" + "}", + Style); + + // Test lambda goes to next line: + verifyFormat("void foo() {\n" + " auto lambda = []<\n" + "typename T\n" + ">(T t) {\n" + " };\n" + "}", + "void foo() {\n" + " auto lambda = []<\n" + " typename T>(T t){\n" + " };\n" + "}", + Style); + // With no column limit, two parameters can go on the same line: + verifyFormat("void foo() {\n" + " auto lambda = []<\n" + "typename T, typename Foo\n" + ">(T t) {\n" + " };\n" + "}", + "void foo() {\n" + " auto lambda = []<\n" + " typename T, typename Foo>(T t){\n" + " };\n" + "}", + Style); + // Or on different lines: + verifyFormat("void foo() {\n" + " auto lambda = []<\n" + "typename T,\n" + "typename Foo\n" + ">(T t) {\n" + " };\n" + "}", + "void foo() {\n" + " auto lambda = []<\n" + " typename T,\n" + " typename Foo>(T t){\n" + " };\n" + "}", + Style); + + // Note that this is the same line (no \n): + verifyFormat("void foo() {\n" + " auto lambd
[clang] [clang-format] Add BreakBeforeTemplateClose option (PR #118046)
@@ -11220,6 +11220,333 @@ TEST_F(FormatTest, WrapsTemplateDeclarationsWithComments) { Style); } +TEST_F(FormatTest, BreakBeforeTemplateCloser) { + FormatStyle Style = getGoogleStyle(FormatStyle::LK_Cpp); + // Begin with tests covering the case where there is no constraint on the + // column limit. + Style.ColumnLimit = 0; + // When BreakBeforeTemplateCloser is turned off, the line break that it adds + // shall be removed: + verifyFormat("template <\n" + "typename Foo,\n" + "typename Bar>\n" + "void foo() {}", + "template <\n" + "typename Foo,\n" + "typename Bar\n" + ">\n" + "void foo() {}", + Style); + + Style.BreakBeforeTemplateCloser = FormatStyle::BBTCS_BlockIndent; + // BreakBeforeTemplateCloser should NOT force template declarations onto + // multiple lines. + verifyFormat("template \n" + "void foo() {}", + Style); + verifyFormat("template \n" + "void foo() {}", + Style); + // It should allow a line break, even when the typename is short. + // verifyNoChange is needed because the default behavior is one line. + verifyNoChange("template <\n" + "typename Foo\n" + ">\n" + "void foo() {}", + Style); + verifyNoChange("template <\n" + "typename Foo,\n" + "typename Bar\n" + ">\n" + "void foo() {}", + Style); + verifyNoChange("template \n" + "void foo() {}", + Style); + // It should add a line break before > if not already present: + verifyFormat("template <\n" + "typename Foo\n" + ">\n" + "void foo() {}", + "template <\n" + "typename Foo>\n" + "void foo() {}", + Style); + verifyFormat("template <\n" + "typename Foo,\n" + "typename Bar\n" + ">\n" + "void foo() {}", + "template <\n" + "typename Foo,\n" + "typename Bar>\n" + "void foo() {}", + Style); + // When within an indent scope, the > should be placed accordingly: + verifyFormat("struct Baz {\n" + " template <\n" + " typename Foo,\n" + " typename Bar\n" + " >\n" + " void foo() {}\n" + "};", + "struct Baz {\n" + " template <\n" + " typename Foo,\n" + " typename Bar>\n" + " void foo() {}\n" + "};", + Style); + + // Test from issue #80049: + verifyFormat( + "void foo() {\n" + " using type = std::remove_cv_t<\n" + " add_common_cv_reference<\n" + " std::common_type_t, std::decay_t>,\n" + " T0,\n" + " T1\n" + " >\n" + " >;\n" + "}", + "void foo() {\n" + " using type = std::remove_cv_t<\n" + " add_common_cv_reference<\n" + " std::common_type_t, std::decay_t>,\n" + " T0,\n" + " T1>>;\n" + "}", + Style); + + // Test lambda goes to next line: + verifyFormat("void foo() {\n" + " auto lambda = []<\n" + "typename T\n" + ">(T t) {\n" + " };\n" + "}", + "void foo() {\n" + " auto lambda = []<\n" + " typename T>(T t){\n" + " };\n" + "}", + Style); + // With no column limit, two parameters can go on the same line: + verifyFormat("void foo() {\n" + " auto lambda = []<\n" + "typename T, typename Foo\n" + ">(T t) {\n" + " };\n" + "}", + "void foo() {\n" + " auto lambda = []<\n" + " typename T, typename Foo>(T t){\n" + " };\n" + "}", + Style); + // Or on different lines: + verifyFormat("void foo() {\n" + " auto lambda = []<\n" + "typename T,\n" + "typename Foo\n" + ">(T t) {\n" + " };\n" + "}", + "void foo() {\n" + " auto lambda = []<\n" + " typename T,\n" + " typename Foo>(T t){\n" + " };\n" + "}", + Style); + + // Note that this is the same line (no \n): + verifyFormat("void foo() {\n" + " auto lambd
[clang] [clang-format] Add BreakBeforeTemplateClose option (PR #118046)
@@ -11220,6 +11220,333 @@ TEST_F(FormatTest, WrapsTemplateDeclarationsWithComments) { Style); } +TEST_F(FormatTest, BreakBeforeTemplateCloser) { + FormatStyle Style = getGoogleStyle(FormatStyle::LK_Cpp); owenca wrote: ```suggestion FormatStyle Style = getLLVMStyle(); EXPECT_EQ(Style.BreakBeforeTemplateCloser, FormatStyle::BBTCS_Never); ``` https://github.com/llvm/llvm-project/pull/118046 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang-format] Add BreakBeforeTemplateClose option (PR #118046)
leijurv wrote: Thank you for the review owenca, those are very reasonable changes, particularly on the conditions where the BreakBeforeClosingAngle gets set/used! https://github.com/llvm/llvm-project/pull/118046 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang-format] Add BreakBeforeTemplateClose option (PR #118046)
https://github.com/leijurv updated https://github.com/llvm/llvm-project/pull/118046 >From 1caf823165b16f6701993d586df51d5cdbf0885e Mon Sep 17 00:00:00 2001 From: Leijurv Date: Fri, 29 Nov 2024 21:54:36 -0600 Subject: [PATCH 01/12] [clang-format] Add BreakBeforeTemplateClose option --- clang/docs/ClangFormatStyleOptions.rst | 21 clang/docs/ReleaseNotes.rst| 1 + clang/include/clang/Format/Format.h| 20 clang/lib/Format/ContinuationIndenter.cpp | 11 ++ clang/lib/Format/ContinuationIndenter.h| 26 ++-- clang/lib/Format/Format.cpp| 2 + clang/lib/Format/TokenAnnotator.cpp| 2 +- clang/unittests/Format/ConfigParseTest.cpp | 1 + clang/unittests/Format/FormatTest.cpp | 131 + 9 files changed, 206 insertions(+), 9 deletions(-) diff --git a/clang/docs/ClangFormatStyleOptions.rst b/clang/docs/ClangFormatStyleOptions.rst index 4be448171699ca..84ab1b0a2eff61 100644 --- a/clang/docs/ClangFormatStyleOptions.rst +++ b/clang/docs/ClangFormatStyleOptions.rst @@ -3416,6 +3416,27 @@ the configuration (without a prefix: ``Auto``). +.. _BreakBeforeTemplateClose: + +**BreakBeforeTemplateClose** (``Boolean``) :versionbadge:`clang-format 20` :ref:`¶ ` + If ``true``, a line break will be placed before the ``>`` in a multiline + template declaration. + + .. code-block:: c++ + + true: + template < + typename Foo, + typename Bar, + typename Baz + > + + false: + template < + typename Foo, + typename Bar, + typename Baz> + .. _BreakBeforeTernaryOperators: **BreakBeforeTernaryOperators** (``Boolean``) :versionbadge:`clang-format 3.7` :ref:`¶ ` diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst index e44aefa90ab386..867d4b5d8c3f18 100644 --- a/clang/docs/ReleaseNotes.rst +++ b/clang/docs/ReleaseNotes.rst @@ -976,6 +976,7 @@ clang-format ``Never``, and ``true`` to ``Always``. - Adds ``RemoveEmptyLinesInUnwrappedLines`` option. - Adds ``KeepFormFeed`` option and set it to ``true`` for ``GNU`` style. +- Adds ``BreakBeforeTemplateClose`` option. libclang diff --git a/clang/include/clang/Format/Format.h b/clang/include/clang/Format/Format.h index 6383934afa2c40..bffd964f6aa8aa 100644 --- a/clang/include/clang/Format/Format.h +++ b/clang/include/clang/Format/Format.h @@ -2248,6 +2248,25 @@ struct FormatStyle { /// \version 16 BreakBeforeInlineASMColonStyle BreakBeforeInlineASMColon; + /// If ``true``, a line break will be placed before the ``>`` in a multiline + /// template declaration. + /// \code + ///true: + ///template < + ///typename Foo, + ///typename Bar, + ///typename Baz + ///> + /// + ///false: + ///template < + ///typename Foo, + ///typename Bar, + ///typename Baz> + /// \endcode + /// \version 20 + bool BreakBeforeTemplateClose; + /// If ``true``, ternary operators will be placed after line breaks. /// \code ///true: @@ -5184,6 +5203,7 @@ struct FormatStyle { BreakBeforeBraces == R.BreakBeforeBraces && BreakBeforeConceptDeclarations == R.BreakBeforeConceptDeclarations && BreakBeforeInlineASMColon == R.BreakBeforeInlineASMColon && + BreakBeforeTemplateClose == R.BreakBeforeTemplateClose && BreakBeforeTernaryOperators == R.BreakBeforeTernaryOperators && BreakBinaryOperations == R.BreakBinaryOperations && BreakConstructorInitializers == R.BreakConstructorInitializers && diff --git a/clang/lib/Format/ContinuationIndenter.cpp b/clang/lib/Format/ContinuationIndenter.cpp index aed86c1fb99551..4c783623afc535 100644 --- a/clang/lib/Format/ContinuationIndenter.cpp +++ b/clang/lib/Format/ContinuationIndenter.cpp @@ -406,6 +406,10 @@ bool ContinuationIndenter::mustBreak(const LineState &State) { } if (CurrentState.BreakBeforeClosingParen && Current.is(tok::r_paren)) return true; + if (CurrentState.BreakBeforeClosingAngle && + Current.ClosesTemplateDeclaration && Style.BreakBeforeTemplateClose) { +return true; + } if (Style.Language == FormatStyle::LK_ObjC && Style.ObjCBreakBeforeNestedBlockParam && Current.ObjCSelectorNameParts > 1 && @@ -1234,6 +1238,9 @@ unsigned ContinuationIndenter::addTokenOnNewLine(LineState &State, Style.AlignAfterOpenBracket == FormatStyle::BAS_BlockIndent; } + if (PreviousNonComment && PreviousNonComment->is(tok::less)) +CurrentState.BreakBeforeClosingAngle = true; + if (CurrentState.AvoidBinPacking) { // If we are breaking after '(', '{', '<', or this is the break after a ':' // to start a member initializer list in a constructor, this should not @@ -1370,6 +1377,10 @@ unsigned ContinuationIndenter::getNewLineColumn(const LineState &State) { State.Stack.size() > 1) { return State.Stack[State.Stack.size() - 2].La
[clang] [clang-format] Add BreakBeforeTemplateClose option (PR #118046)
https://github.com/leijurv updated https://github.com/llvm/llvm-project/pull/118046 >From 1caf823165b16f6701993d586df51d5cdbf0885e Mon Sep 17 00:00:00 2001 From: Leijurv Date: Fri, 29 Nov 2024 21:54:36 -0600 Subject: [PATCH 01/11] [clang-format] Add BreakBeforeTemplateClose option --- clang/docs/ClangFormatStyleOptions.rst | 21 clang/docs/ReleaseNotes.rst| 1 + clang/include/clang/Format/Format.h| 20 clang/lib/Format/ContinuationIndenter.cpp | 11 ++ clang/lib/Format/ContinuationIndenter.h| 26 ++-- clang/lib/Format/Format.cpp| 2 + clang/lib/Format/TokenAnnotator.cpp| 2 +- clang/unittests/Format/ConfigParseTest.cpp | 1 + clang/unittests/Format/FormatTest.cpp | 131 + 9 files changed, 206 insertions(+), 9 deletions(-) diff --git a/clang/docs/ClangFormatStyleOptions.rst b/clang/docs/ClangFormatStyleOptions.rst index 4be448171699ca..84ab1b0a2eff61 100644 --- a/clang/docs/ClangFormatStyleOptions.rst +++ b/clang/docs/ClangFormatStyleOptions.rst @@ -3416,6 +3416,27 @@ the configuration (without a prefix: ``Auto``). +.. _BreakBeforeTemplateClose: + +**BreakBeforeTemplateClose** (``Boolean``) :versionbadge:`clang-format 20` :ref:`¶ ` + If ``true``, a line break will be placed before the ``>`` in a multiline + template declaration. + + .. code-block:: c++ + + true: + template < + typename Foo, + typename Bar, + typename Baz + > + + false: + template < + typename Foo, + typename Bar, + typename Baz> + .. _BreakBeforeTernaryOperators: **BreakBeforeTernaryOperators** (``Boolean``) :versionbadge:`clang-format 3.7` :ref:`¶ ` diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst index e44aefa90ab386..867d4b5d8c3f18 100644 --- a/clang/docs/ReleaseNotes.rst +++ b/clang/docs/ReleaseNotes.rst @@ -976,6 +976,7 @@ clang-format ``Never``, and ``true`` to ``Always``. - Adds ``RemoveEmptyLinesInUnwrappedLines`` option. - Adds ``KeepFormFeed`` option and set it to ``true`` for ``GNU`` style. +- Adds ``BreakBeforeTemplateClose`` option. libclang diff --git a/clang/include/clang/Format/Format.h b/clang/include/clang/Format/Format.h index 6383934afa2c40..bffd964f6aa8aa 100644 --- a/clang/include/clang/Format/Format.h +++ b/clang/include/clang/Format/Format.h @@ -2248,6 +2248,25 @@ struct FormatStyle { /// \version 16 BreakBeforeInlineASMColonStyle BreakBeforeInlineASMColon; + /// If ``true``, a line break will be placed before the ``>`` in a multiline + /// template declaration. + /// \code + ///true: + ///template < + ///typename Foo, + ///typename Bar, + ///typename Baz + ///> + /// + ///false: + ///template < + ///typename Foo, + ///typename Bar, + ///typename Baz> + /// \endcode + /// \version 20 + bool BreakBeforeTemplateClose; + /// If ``true``, ternary operators will be placed after line breaks. /// \code ///true: @@ -5184,6 +5203,7 @@ struct FormatStyle { BreakBeforeBraces == R.BreakBeforeBraces && BreakBeforeConceptDeclarations == R.BreakBeforeConceptDeclarations && BreakBeforeInlineASMColon == R.BreakBeforeInlineASMColon && + BreakBeforeTemplateClose == R.BreakBeforeTemplateClose && BreakBeforeTernaryOperators == R.BreakBeforeTernaryOperators && BreakBinaryOperations == R.BreakBinaryOperations && BreakConstructorInitializers == R.BreakConstructorInitializers && diff --git a/clang/lib/Format/ContinuationIndenter.cpp b/clang/lib/Format/ContinuationIndenter.cpp index aed86c1fb99551..4c783623afc535 100644 --- a/clang/lib/Format/ContinuationIndenter.cpp +++ b/clang/lib/Format/ContinuationIndenter.cpp @@ -406,6 +406,10 @@ bool ContinuationIndenter::mustBreak(const LineState &State) { } if (CurrentState.BreakBeforeClosingParen && Current.is(tok::r_paren)) return true; + if (CurrentState.BreakBeforeClosingAngle && + Current.ClosesTemplateDeclaration && Style.BreakBeforeTemplateClose) { +return true; + } if (Style.Language == FormatStyle::LK_ObjC && Style.ObjCBreakBeforeNestedBlockParam && Current.ObjCSelectorNameParts > 1 && @@ -1234,6 +1238,9 @@ unsigned ContinuationIndenter::addTokenOnNewLine(LineState &State, Style.AlignAfterOpenBracket == FormatStyle::BAS_BlockIndent; } + if (PreviousNonComment && PreviousNonComment->is(tok::less)) +CurrentState.BreakBeforeClosingAngle = true; + if (CurrentState.AvoidBinPacking) { // If we are breaking after '(', '{', '<', or this is the break after a ':' // to start a member initializer list in a constructor, this should not @@ -1370,6 +1377,10 @@ unsigned ContinuationIndenter::getNewLineColumn(const LineState &State) { State.Stack.size() > 1) { return State.Stack[State.Stack.size() - 2].La
[clang] [clang-format] Add BreakBeforeTemplateClose option (PR #118046)
@@ -280,6 +281,13 @@ struct ParenState { /// was a newline after the beginning left paren. bool BreakBeforeClosingParen : 1; + /// Whether a newline needs to be inserted before the block's closing + /// angle < >. + /// + /// We only want to insert a newline before the closing angle if there also + /// was a newline after the beginning left angle. owenca wrote: ```suggestion /// Whether a newline needs to be inserted before a closing angle `>`. ``` https://github.com/llvm/llvm-project/pull/118046 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang-format] Add BreakBeforeTemplateClose option (PR #118046)
@@ -1371,6 +1378,11 @@ unsigned ContinuationIndenter::getNewLineColumn(const LineState &State) { State.Stack.size() > 1) { return State.Stack[State.Stack.size() - 2].LastSpace; } + if (Current.is(TT_TemplateCloser) && + Style.BreakBeforeTemplateCloser != FormatStyle::BBTCS_Never && + State.Stack.size() > 1) { owenca wrote: ```suggestion if (Style.BreakBeforeTemplateCloser == FormatStyle::BBTCS_BlockIndent && Current.is(TT_TemplateCloser) && State.Stack.size() > 1) { ``` https://github.com/llvm/llvm-project/pull/118046 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang-format] Add BreakBeforeTemplateClose option (PR #118046)
@@ -1235,6 +1239,9 @@ unsigned ContinuationIndenter::addTokenOnNewLine(LineState &State, Style.AlignAfterOpenBracket == FormatStyle::BAS_BlockIndent; } + if (PreviousNonComment && PreviousNonComment->is(tok::less)) +CurrentState.BreakBeforeClosingAngle = true; owenca wrote: ```suggestion if (PreviousNonComment && PreviousNonComment->is(TT_TemplateOpener)) { CurrentState.BreakBeforeClosingAngle = Style.BreakBeforeTemplateCloser == FormatStyle::BBTCS_BlockIndent; } ``` https://github.com/llvm/llvm-project/pull/118046 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang-format] Add BreakBeforeTemplateClose option (PR #118046)
@@ -406,6 +406,10 @@ bool ContinuationIndenter::mustBreak(const LineState &State) { } if (CurrentState.BreakBeforeClosingParen && Current.is(tok::r_paren)) return true; + if (CurrentState.BreakBeforeClosingAngle && Current.is(TT_TemplateCloser) && + Style.BreakBeforeTemplateCloser == FormatStyle::BBTCS_BlockIndent) { +return true; + } owenca wrote: ```suggestion if (CurrentState.BreakBeforeClosingAngle && Current.is(TT_TemplateCloser)) return true; ``` See below. https://github.com/llvm/llvm-project/pull/118046 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang-format] Add BreakBeforeTemplateClose option (PR #118046)
https://github.com/leijurv updated https://github.com/llvm/llvm-project/pull/118046 >From 1caf823165b16f6701993d586df51d5cdbf0885e Mon Sep 17 00:00:00 2001 From: Leijurv Date: Fri, 29 Nov 2024 21:54:36 -0600 Subject: [PATCH 01/11] [clang-format] Add BreakBeforeTemplateClose option --- clang/docs/ClangFormatStyleOptions.rst | 21 clang/docs/ReleaseNotes.rst| 1 + clang/include/clang/Format/Format.h| 20 clang/lib/Format/ContinuationIndenter.cpp | 11 ++ clang/lib/Format/ContinuationIndenter.h| 26 ++-- clang/lib/Format/Format.cpp| 2 + clang/lib/Format/TokenAnnotator.cpp| 2 +- clang/unittests/Format/ConfigParseTest.cpp | 1 + clang/unittests/Format/FormatTest.cpp | 131 + 9 files changed, 206 insertions(+), 9 deletions(-) diff --git a/clang/docs/ClangFormatStyleOptions.rst b/clang/docs/ClangFormatStyleOptions.rst index 4be448171699ca..84ab1b0a2eff61 100644 --- a/clang/docs/ClangFormatStyleOptions.rst +++ b/clang/docs/ClangFormatStyleOptions.rst @@ -3416,6 +3416,27 @@ the configuration (without a prefix: ``Auto``). +.. _BreakBeforeTemplateClose: + +**BreakBeforeTemplateClose** (``Boolean``) :versionbadge:`clang-format 20` :ref:`¶ ` + If ``true``, a line break will be placed before the ``>`` in a multiline + template declaration. + + .. code-block:: c++ + + true: + template < + typename Foo, + typename Bar, + typename Baz + > + + false: + template < + typename Foo, + typename Bar, + typename Baz> + .. _BreakBeforeTernaryOperators: **BreakBeforeTernaryOperators** (``Boolean``) :versionbadge:`clang-format 3.7` :ref:`¶ ` diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst index e44aefa90ab386..867d4b5d8c3f18 100644 --- a/clang/docs/ReleaseNotes.rst +++ b/clang/docs/ReleaseNotes.rst @@ -976,6 +976,7 @@ clang-format ``Never``, and ``true`` to ``Always``. - Adds ``RemoveEmptyLinesInUnwrappedLines`` option. - Adds ``KeepFormFeed`` option and set it to ``true`` for ``GNU`` style. +- Adds ``BreakBeforeTemplateClose`` option. libclang diff --git a/clang/include/clang/Format/Format.h b/clang/include/clang/Format/Format.h index 6383934afa2c40..bffd964f6aa8aa 100644 --- a/clang/include/clang/Format/Format.h +++ b/clang/include/clang/Format/Format.h @@ -2248,6 +2248,25 @@ struct FormatStyle { /// \version 16 BreakBeforeInlineASMColonStyle BreakBeforeInlineASMColon; + /// If ``true``, a line break will be placed before the ``>`` in a multiline + /// template declaration. + /// \code + ///true: + ///template < + ///typename Foo, + ///typename Bar, + ///typename Baz + ///> + /// + ///false: + ///template < + ///typename Foo, + ///typename Bar, + ///typename Baz> + /// \endcode + /// \version 20 + bool BreakBeforeTemplateClose; + /// If ``true``, ternary operators will be placed after line breaks. /// \code ///true: @@ -5184,6 +5203,7 @@ struct FormatStyle { BreakBeforeBraces == R.BreakBeforeBraces && BreakBeforeConceptDeclarations == R.BreakBeforeConceptDeclarations && BreakBeforeInlineASMColon == R.BreakBeforeInlineASMColon && + BreakBeforeTemplateClose == R.BreakBeforeTemplateClose && BreakBeforeTernaryOperators == R.BreakBeforeTernaryOperators && BreakBinaryOperations == R.BreakBinaryOperations && BreakConstructorInitializers == R.BreakConstructorInitializers && diff --git a/clang/lib/Format/ContinuationIndenter.cpp b/clang/lib/Format/ContinuationIndenter.cpp index aed86c1fb99551..4c783623afc535 100644 --- a/clang/lib/Format/ContinuationIndenter.cpp +++ b/clang/lib/Format/ContinuationIndenter.cpp @@ -406,6 +406,10 @@ bool ContinuationIndenter::mustBreak(const LineState &State) { } if (CurrentState.BreakBeforeClosingParen && Current.is(tok::r_paren)) return true; + if (CurrentState.BreakBeforeClosingAngle && + Current.ClosesTemplateDeclaration && Style.BreakBeforeTemplateClose) { +return true; + } if (Style.Language == FormatStyle::LK_ObjC && Style.ObjCBreakBeforeNestedBlockParam && Current.ObjCSelectorNameParts > 1 && @@ -1234,6 +1238,9 @@ unsigned ContinuationIndenter::addTokenOnNewLine(LineState &State, Style.AlignAfterOpenBracket == FormatStyle::BAS_BlockIndent; } + if (PreviousNonComment && PreviousNonComment->is(tok::less)) +CurrentState.BreakBeforeClosingAngle = true; + if (CurrentState.AvoidBinPacking) { // If we are breaking after '(', '{', '<', or this is the break after a ':' // to start a member initializer list in a constructor, this should not @@ -1370,6 +1377,10 @@ unsigned ContinuationIndenter::getNewLineColumn(const LineState &State) { State.Stack.size() > 1) { return State.Stack[State.Stack.size() - 2].La
[clang] [clang-format] Add BreakBeforeTemplateClose option (PR #118046)
https://github.com/leijurv edited https://github.com/llvm/llvm-project/pull/118046 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang-format] Add BreakBeforeTemplateClose option (PR #118046)
@@ -2252,6 +2252,25 @@ struct FormatStyle { /// \version 16 BreakBeforeInlineASMColonStyle BreakBeforeInlineASMColon; + /// If ``true``, a line break will be placed before the ``>`` in a multiline + /// template declaration. + /// \code + ///true: + ///template < + ///typename Foo, + ///typename Bar, + ///typename Baz + ///> + /// + ///false: + ///template < + ///typename Foo, + ///typename Bar, + ///typename Baz> leijurv wrote: No, I don't intend the `>` to be forced onto its own line. For instance, see this test case: ``` verifyFormat("void foo() {\n" " myFunc<\n" " Lng\n" " >();\n" "}", Style); ``` https://github.com/llvm/llvm-project/pull/118046 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang-format] Add BreakBeforeTemplateClose option (PR #118046)
https://github.com/leijurv updated https://github.com/llvm/llvm-project/pull/118046 >From 1caf823165b16f6701993d586df51d5cdbf0885e Mon Sep 17 00:00:00 2001 From: Leijurv Date: Fri, 29 Nov 2024 21:54:36 -0600 Subject: [PATCH 01/10] [clang-format] Add BreakBeforeTemplateClose option --- clang/docs/ClangFormatStyleOptions.rst | 21 clang/docs/ReleaseNotes.rst| 1 + clang/include/clang/Format/Format.h| 20 clang/lib/Format/ContinuationIndenter.cpp | 11 ++ clang/lib/Format/ContinuationIndenter.h| 26 ++-- clang/lib/Format/Format.cpp| 2 + clang/lib/Format/TokenAnnotator.cpp| 2 +- clang/unittests/Format/ConfigParseTest.cpp | 1 + clang/unittests/Format/FormatTest.cpp | 131 + 9 files changed, 206 insertions(+), 9 deletions(-) diff --git a/clang/docs/ClangFormatStyleOptions.rst b/clang/docs/ClangFormatStyleOptions.rst index 4be448171699ca..84ab1b0a2eff61 100644 --- a/clang/docs/ClangFormatStyleOptions.rst +++ b/clang/docs/ClangFormatStyleOptions.rst @@ -3416,6 +3416,27 @@ the configuration (without a prefix: ``Auto``). +.. _BreakBeforeTemplateClose: + +**BreakBeforeTemplateClose** (``Boolean``) :versionbadge:`clang-format 20` :ref:`¶ ` + If ``true``, a line break will be placed before the ``>`` in a multiline + template declaration. + + .. code-block:: c++ + + true: + template < + typename Foo, + typename Bar, + typename Baz + > + + false: + template < + typename Foo, + typename Bar, + typename Baz> + .. _BreakBeforeTernaryOperators: **BreakBeforeTernaryOperators** (``Boolean``) :versionbadge:`clang-format 3.7` :ref:`¶ ` diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst index e44aefa90ab386..867d4b5d8c3f18 100644 --- a/clang/docs/ReleaseNotes.rst +++ b/clang/docs/ReleaseNotes.rst @@ -976,6 +976,7 @@ clang-format ``Never``, and ``true`` to ``Always``. - Adds ``RemoveEmptyLinesInUnwrappedLines`` option. - Adds ``KeepFormFeed`` option and set it to ``true`` for ``GNU`` style. +- Adds ``BreakBeforeTemplateClose`` option. libclang diff --git a/clang/include/clang/Format/Format.h b/clang/include/clang/Format/Format.h index 6383934afa2c40..bffd964f6aa8aa 100644 --- a/clang/include/clang/Format/Format.h +++ b/clang/include/clang/Format/Format.h @@ -2248,6 +2248,25 @@ struct FormatStyle { /// \version 16 BreakBeforeInlineASMColonStyle BreakBeforeInlineASMColon; + /// If ``true``, a line break will be placed before the ``>`` in a multiline + /// template declaration. + /// \code + ///true: + ///template < + ///typename Foo, + ///typename Bar, + ///typename Baz + ///> + /// + ///false: + ///template < + ///typename Foo, + ///typename Bar, + ///typename Baz> + /// \endcode + /// \version 20 + bool BreakBeforeTemplateClose; + /// If ``true``, ternary operators will be placed after line breaks. /// \code ///true: @@ -5184,6 +5203,7 @@ struct FormatStyle { BreakBeforeBraces == R.BreakBeforeBraces && BreakBeforeConceptDeclarations == R.BreakBeforeConceptDeclarations && BreakBeforeInlineASMColon == R.BreakBeforeInlineASMColon && + BreakBeforeTemplateClose == R.BreakBeforeTemplateClose && BreakBeforeTernaryOperators == R.BreakBeforeTernaryOperators && BreakBinaryOperations == R.BreakBinaryOperations && BreakConstructorInitializers == R.BreakConstructorInitializers && diff --git a/clang/lib/Format/ContinuationIndenter.cpp b/clang/lib/Format/ContinuationIndenter.cpp index aed86c1fb99551..4c783623afc535 100644 --- a/clang/lib/Format/ContinuationIndenter.cpp +++ b/clang/lib/Format/ContinuationIndenter.cpp @@ -406,6 +406,10 @@ bool ContinuationIndenter::mustBreak(const LineState &State) { } if (CurrentState.BreakBeforeClosingParen && Current.is(tok::r_paren)) return true; + if (CurrentState.BreakBeforeClosingAngle && + Current.ClosesTemplateDeclaration && Style.BreakBeforeTemplateClose) { +return true; + } if (Style.Language == FormatStyle::LK_ObjC && Style.ObjCBreakBeforeNestedBlockParam && Current.ObjCSelectorNameParts > 1 && @@ -1234,6 +1238,9 @@ unsigned ContinuationIndenter::addTokenOnNewLine(LineState &State, Style.AlignAfterOpenBracket == FormatStyle::BAS_BlockIndent; } + if (PreviousNonComment && PreviousNonComment->is(tok::less)) +CurrentState.BreakBeforeClosingAngle = true; + if (CurrentState.AvoidBinPacking) { // If we are breaking after '(', '{', '<', or this is the break after a ':' // to start a member initializer list in a constructor, this should not @@ -1370,6 +1377,10 @@ unsigned ContinuationIndenter::getNewLineColumn(const LineState &State) { State.Stack.size() > 1) { return State.Stack[State.Stack.size() - 2].La
[clang] [clang-format] Add BreakBeforeTemplateClose option (PR #118046)
leijurv wrote: Oh gosh, that's embarrassing. It looks like I was so focused on the column limit that I didn't cover cases where the column limit doesn't break the template fully. In other words, I would just type "Fooo" and force it onto the next line, without noticing that a slightly shorter Foo would have different behavior, I apologize. In your example, I see that `BreakBeforeTemplateCloser: Multiline, ColumnLimit: 17` gives me: ``` template < class A, class B > class C { void f() {} }; ``` But `BreakBeforeTemplateCloser: Multiline, ColumnLimit: 18` gives me: ``` template class C { void f() {} }; ``` It looks to me like the problem is that when writing this code originally, I searched through the codebase for `FormatStyle::BAS_BlockIndent` and tried to replicate it. This causes the behavior here, where the `>` only goes onto the next line if there was a break after the matching `<`. In other words, it seems **I was wrong** when I said `I didn't really have an intent in mind between your described options of BlockIndent vs Multiline but yes, I suppose what I have here is Multiline.` Actually, it seems like what I have here is BlockIndent. So, thankfully I think I can fix this just by **renaming my option from Multiline to BlockIndent**, per your comment [here](https://github.com/llvm/llvm-project/pull/118046#discussion_r1912382882). Additionally I have **added more tests** to cover this case where the first parameter can fit within the ColumnLimit on the same line as the `template <`. https://github.com/llvm/llvm-project/pull/118046/commits/09528826ffc9f7b783d043c4447419cfd9a6ff38 https://github.com/llvm/llvm-project/pull/118046 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang-format] Add BreakBeforeTemplateClose option (PR #118046)
https://github.com/leijurv updated https://github.com/llvm/llvm-project/pull/118046 >From 1caf823165b16f6701993d586df51d5cdbf0885e Mon Sep 17 00:00:00 2001 From: Leijurv Date: Fri, 29 Nov 2024 21:54:36 -0600 Subject: [PATCH 1/9] [clang-format] Add BreakBeforeTemplateClose option --- clang/docs/ClangFormatStyleOptions.rst | 21 clang/docs/ReleaseNotes.rst| 1 + clang/include/clang/Format/Format.h| 20 clang/lib/Format/ContinuationIndenter.cpp | 11 ++ clang/lib/Format/ContinuationIndenter.h| 26 ++-- clang/lib/Format/Format.cpp| 2 + clang/lib/Format/TokenAnnotator.cpp| 2 +- clang/unittests/Format/ConfigParseTest.cpp | 1 + clang/unittests/Format/FormatTest.cpp | 131 + 9 files changed, 206 insertions(+), 9 deletions(-) diff --git a/clang/docs/ClangFormatStyleOptions.rst b/clang/docs/ClangFormatStyleOptions.rst index 4be448171699ca..84ab1b0a2eff61 100644 --- a/clang/docs/ClangFormatStyleOptions.rst +++ b/clang/docs/ClangFormatStyleOptions.rst @@ -3416,6 +3416,27 @@ the configuration (without a prefix: ``Auto``). +.. _BreakBeforeTemplateClose: + +**BreakBeforeTemplateClose** (``Boolean``) :versionbadge:`clang-format 20` :ref:`¶ ` + If ``true``, a line break will be placed before the ``>`` in a multiline + template declaration. + + .. code-block:: c++ + + true: + template < + typename Foo, + typename Bar, + typename Baz + > + + false: + template < + typename Foo, + typename Bar, + typename Baz> + .. _BreakBeforeTernaryOperators: **BreakBeforeTernaryOperators** (``Boolean``) :versionbadge:`clang-format 3.7` :ref:`¶ ` diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst index e44aefa90ab386..867d4b5d8c3f18 100644 --- a/clang/docs/ReleaseNotes.rst +++ b/clang/docs/ReleaseNotes.rst @@ -976,6 +976,7 @@ clang-format ``Never``, and ``true`` to ``Always``. - Adds ``RemoveEmptyLinesInUnwrappedLines`` option. - Adds ``KeepFormFeed`` option and set it to ``true`` for ``GNU`` style. +- Adds ``BreakBeforeTemplateClose`` option. libclang diff --git a/clang/include/clang/Format/Format.h b/clang/include/clang/Format/Format.h index 6383934afa2c40..bffd964f6aa8aa 100644 --- a/clang/include/clang/Format/Format.h +++ b/clang/include/clang/Format/Format.h @@ -2248,6 +2248,25 @@ struct FormatStyle { /// \version 16 BreakBeforeInlineASMColonStyle BreakBeforeInlineASMColon; + /// If ``true``, a line break will be placed before the ``>`` in a multiline + /// template declaration. + /// \code + ///true: + ///template < + ///typename Foo, + ///typename Bar, + ///typename Baz + ///> + /// + ///false: + ///template < + ///typename Foo, + ///typename Bar, + ///typename Baz> + /// \endcode + /// \version 20 + bool BreakBeforeTemplateClose; + /// If ``true``, ternary operators will be placed after line breaks. /// \code ///true: @@ -5184,6 +5203,7 @@ struct FormatStyle { BreakBeforeBraces == R.BreakBeforeBraces && BreakBeforeConceptDeclarations == R.BreakBeforeConceptDeclarations && BreakBeforeInlineASMColon == R.BreakBeforeInlineASMColon && + BreakBeforeTemplateClose == R.BreakBeforeTemplateClose && BreakBeforeTernaryOperators == R.BreakBeforeTernaryOperators && BreakBinaryOperations == R.BreakBinaryOperations && BreakConstructorInitializers == R.BreakConstructorInitializers && diff --git a/clang/lib/Format/ContinuationIndenter.cpp b/clang/lib/Format/ContinuationIndenter.cpp index aed86c1fb99551..4c783623afc535 100644 --- a/clang/lib/Format/ContinuationIndenter.cpp +++ b/clang/lib/Format/ContinuationIndenter.cpp @@ -406,6 +406,10 @@ bool ContinuationIndenter::mustBreak(const LineState &State) { } if (CurrentState.BreakBeforeClosingParen && Current.is(tok::r_paren)) return true; + if (CurrentState.BreakBeforeClosingAngle && + Current.ClosesTemplateDeclaration && Style.BreakBeforeTemplateClose) { +return true; + } if (Style.Language == FormatStyle::LK_ObjC && Style.ObjCBreakBeforeNestedBlockParam && Current.ObjCSelectorNameParts > 1 && @@ -1234,6 +1238,9 @@ unsigned ContinuationIndenter::addTokenOnNewLine(LineState &State, Style.AlignAfterOpenBracket == FormatStyle::BAS_BlockIndent; } + if (PreviousNonComment && PreviousNonComment->is(tok::less)) +CurrentState.BreakBeforeClosingAngle = true; + if (CurrentState.AvoidBinPacking) { // If we are breaking after '(', '{', '<', or this is the break after a ':' // to start a member initializer list in a constructor, this should not @@ -1370,6 +1377,10 @@ unsigned ContinuationIndenter::getNewLineColumn(const LineState &State) { State.Stack.size() > 1) { return State.Stack[State.Stack.size() - 2].Last
[clang] [clang-format] Add BreakBeforeTemplateClose option (PR #118046)
https://github.com/mydeveloperday approved this pull request. This looks good to me but please wait for @owenca to approve https://github.com/llvm/llvm-project/pull/118046 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang-format] Add BreakBeforeTemplateClose option (PR #118046)
@@ -2252,6 +2252,25 @@ struct FormatStyle { /// \version 16 BreakBeforeInlineASMColonStyle BreakBeforeInlineASMColon; + /// If ``true``, a line break will be placed before the ``>`` in a multiline + /// template declaration. + /// \code + ///true: + ///template < + ///typename Foo, + ///typename Bar, + ///typename Baz + ///> + /// + ///false: + ///template < + ///typename Foo, + ///typename Bar, + ///typename Baz> owenca wrote: I was asking whether you intended to also break _after_ the `>`, effectively forcing it to be on its own line. https://github.com/llvm/llvm-project/pull/118046 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang-format] Add BreakBeforeTemplateClose option (PR #118046)
owenca wrote: Why doesn't it break before the `>` for the example (a.cc) below? ```cpp template class C { void f() {} }; ``` Command line: ``` clang-format -style='{BreakBeforeTemplateCloser: Multiline, ColumnLimit: 26}' a.cc ``` https://github.com/llvm/llvm-project/pull/118046 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang-format] Add BreakBeforeTemplateClose option (PR #118046)
@@ -2252,6 +2252,25 @@ struct FormatStyle { /// \version 16 BreakBeforeInlineASMColonStyle BreakBeforeInlineASMColon; + /// If ``true``, a line break will be placed before the ``>`` in a multiline + /// template declaration. + /// \code + ///true: + ///template < + ///typename Foo, + ///typename Bar, + ///typename Baz + ///> + /// + ///false: + ///template < + ///typename Foo, + ///typename Bar, + ///typename Baz> leijurv wrote: I'm doing `BreakBeforeTemplateCloser` because of [your comment here](https://github.com/llvm/llvm-project/pull/118046#discussion_r1912369946) I've changed it to an enum in this commit: https://github.com/llvm/llvm-project/pull/118046/commits/9277a685c7a0199fff20677759d663254de9189f 👍 https://github.com/llvm/llvm-project/pull/118046 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang-format] Add BreakBeforeTemplateClose option (PR #118046)
https://github.com/leijurv updated https://github.com/llvm/llvm-project/pull/118046 >From 1caf823165b16f6701993d586df51d5cdbf0885e Mon Sep 17 00:00:00 2001 From: Leijurv Date: Fri, 29 Nov 2024 21:54:36 -0600 Subject: [PATCH 1/8] [clang-format] Add BreakBeforeTemplateClose option --- clang/docs/ClangFormatStyleOptions.rst | 21 clang/docs/ReleaseNotes.rst| 1 + clang/include/clang/Format/Format.h| 20 clang/lib/Format/ContinuationIndenter.cpp | 11 ++ clang/lib/Format/ContinuationIndenter.h| 26 ++-- clang/lib/Format/Format.cpp| 2 + clang/lib/Format/TokenAnnotator.cpp| 2 +- clang/unittests/Format/ConfigParseTest.cpp | 1 + clang/unittests/Format/FormatTest.cpp | 131 + 9 files changed, 206 insertions(+), 9 deletions(-) diff --git a/clang/docs/ClangFormatStyleOptions.rst b/clang/docs/ClangFormatStyleOptions.rst index 4be448171699ca..84ab1b0a2eff61 100644 --- a/clang/docs/ClangFormatStyleOptions.rst +++ b/clang/docs/ClangFormatStyleOptions.rst @@ -3416,6 +3416,27 @@ the configuration (without a prefix: ``Auto``). +.. _BreakBeforeTemplateClose: + +**BreakBeforeTemplateClose** (``Boolean``) :versionbadge:`clang-format 20` :ref:`¶ ` + If ``true``, a line break will be placed before the ``>`` in a multiline + template declaration. + + .. code-block:: c++ + + true: + template < + typename Foo, + typename Bar, + typename Baz + > + + false: + template < + typename Foo, + typename Bar, + typename Baz> + .. _BreakBeforeTernaryOperators: **BreakBeforeTernaryOperators** (``Boolean``) :versionbadge:`clang-format 3.7` :ref:`¶ ` diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst index e44aefa90ab386..867d4b5d8c3f18 100644 --- a/clang/docs/ReleaseNotes.rst +++ b/clang/docs/ReleaseNotes.rst @@ -976,6 +976,7 @@ clang-format ``Never``, and ``true`` to ``Always``. - Adds ``RemoveEmptyLinesInUnwrappedLines`` option. - Adds ``KeepFormFeed`` option and set it to ``true`` for ``GNU`` style. +- Adds ``BreakBeforeTemplateClose`` option. libclang diff --git a/clang/include/clang/Format/Format.h b/clang/include/clang/Format/Format.h index 6383934afa2c40..bffd964f6aa8aa 100644 --- a/clang/include/clang/Format/Format.h +++ b/clang/include/clang/Format/Format.h @@ -2248,6 +2248,25 @@ struct FormatStyle { /// \version 16 BreakBeforeInlineASMColonStyle BreakBeforeInlineASMColon; + /// If ``true``, a line break will be placed before the ``>`` in a multiline + /// template declaration. + /// \code + ///true: + ///template < + ///typename Foo, + ///typename Bar, + ///typename Baz + ///> + /// + ///false: + ///template < + ///typename Foo, + ///typename Bar, + ///typename Baz> + /// \endcode + /// \version 20 + bool BreakBeforeTemplateClose; + /// If ``true``, ternary operators will be placed after line breaks. /// \code ///true: @@ -5184,6 +5203,7 @@ struct FormatStyle { BreakBeforeBraces == R.BreakBeforeBraces && BreakBeforeConceptDeclarations == R.BreakBeforeConceptDeclarations && BreakBeforeInlineASMColon == R.BreakBeforeInlineASMColon && + BreakBeforeTemplateClose == R.BreakBeforeTemplateClose && BreakBeforeTernaryOperators == R.BreakBeforeTernaryOperators && BreakBinaryOperations == R.BreakBinaryOperations && BreakConstructorInitializers == R.BreakConstructorInitializers && diff --git a/clang/lib/Format/ContinuationIndenter.cpp b/clang/lib/Format/ContinuationIndenter.cpp index aed86c1fb99551..4c783623afc535 100644 --- a/clang/lib/Format/ContinuationIndenter.cpp +++ b/clang/lib/Format/ContinuationIndenter.cpp @@ -406,6 +406,10 @@ bool ContinuationIndenter::mustBreak(const LineState &State) { } if (CurrentState.BreakBeforeClosingParen && Current.is(tok::r_paren)) return true; + if (CurrentState.BreakBeforeClosingAngle && + Current.ClosesTemplateDeclaration && Style.BreakBeforeTemplateClose) { +return true; + } if (Style.Language == FormatStyle::LK_ObjC && Style.ObjCBreakBeforeNestedBlockParam && Current.ObjCSelectorNameParts > 1 && @@ -1234,6 +1238,9 @@ unsigned ContinuationIndenter::addTokenOnNewLine(LineState &State, Style.AlignAfterOpenBracket == FormatStyle::BAS_BlockIndent; } + if (PreviousNonComment && PreviousNonComment->is(tok::less)) +CurrentState.BreakBeforeClosingAngle = true; + if (CurrentState.AvoidBinPacking) { // If we are breaking after '(', '{', '<', or this is the break after a ':' // to start a member initializer list in a constructor, this should not @@ -1370,6 +1377,10 @@ unsigned ContinuationIndenter::getNewLineColumn(const LineState &State) { State.Stack.size() > 1) { return State.Stack[State.Stack.size() - 2].Last
[clang] [clang-format] Add BreakBeforeTemplateClose option (PR #118046)
@@ -2252,6 +2252,25 @@ struct FormatStyle { /// \version 16 BreakBeforeInlineASMColonStyle BreakBeforeInlineASMColon; + /// If ``true``, a line break will be placed before the ``>`` in a multiline + /// template declaration. + /// \code + ///true: + ///template < + ///typename Foo, + ///typename Bar, + ///typename Baz + ///> + /// + ///false: + ///template < + ///typename Foo, + ///typename Bar, + ///typename Baz> owenca wrote: > Would `Always` look like: > > ``` > template > > ``` Yes, except that there is a space between `template` and `<` by `LLVM` default. > So, should I change this from a true/false to an enum of Multiline/Never? Yes. I haven't looked at your implementation yet, but are you doing `BreakBeforeTemplateCloser` or `TemplateCloserOnItsOwnLine`? https://github.com/llvm/llvm-project/pull/118046 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang-format] Add BreakBeforeTemplateClose option (PR #118046)
https://github.com/leijurv edited https://github.com/llvm/llvm-project/pull/118046 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang-format] Add BreakBeforeTemplateClose option (PR #118046)
https://github.com/leijurv edited https://github.com/llvm/llvm-project/pull/118046 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang-format] Add BreakBeforeTemplateClose option (PR #118046)
@@ -2252,6 +2252,25 @@ struct FormatStyle { /// \version 16 BreakBeforeInlineASMColonStyle BreakBeforeInlineASMColon; + /// If ``true``, a line break will be placed before the ``>`` in a multiline + /// template declaration. + /// \code + ///true: + ///template < + ///typename Foo, + ///typename Bar, + ///typename Baz + ///> + /// + ///false: + ///template < + ///typename Foo, + ///typename Bar, + ///typename Baz> leijurv wrote: Would `Always` look like: ``` template ``` For the overall indentation / line breaking of the various typenames, I left that untouched. All that stuff went way above my head. I didn't really have an intent in mind between your described options of BlockIndent vs Multiline but yes, I suppose what I have here is Multiline. So, should I change this from a true/false to an enum of Multiline/Never? https://github.com/llvm/llvm-project/pull/118046 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang-format] Add BreakBeforeTemplateClose option (PR #118046)
@@ -2252,6 +2252,25 @@ struct FormatStyle { /// \version 16 BreakBeforeInlineASMColonStyle BreakBeforeInlineASMColon; + /// If ``true``, a line break will be placed before the ``>`` in a multiline + /// template declaration. + /// \code + ///true: + ///template < + ///typename Foo, + ///typename Bar, + ///typename Baz + ///> + /// + ///false: + ///template < + ///typename Foo, + ///typename Bar, + ///typename Baz> owenca wrote: > In my mind that's a bit of a different option. You can see in your examples > that you're assuming that the `>` goes on the next line, but that's what this > PR is trying to add support for. `Always` would break before a template closer unconditionally. > Like, your enum (which is totally reasonable) would switch between: > > ``` > template < > typename Foo, typename Bar, > typename Baz > > > ``` > > versus > > ``` > templatetypename Baz > > > ``` > > But what I'm currently trying to add support for is: > > ``` > template < > typename Foo, typename Bar, > typename Baz > > > > templatetypename Baz > > > ``` > > versus > > ``` > template < > typename Foo, typename Bar, > typename Baz> > > templatetypename Baz> > ``` I don't recall that you had a test case for the last pattern, but it seems that your current implementation is `Multiline`, which would break before the template closer if the template doesn't fit on one line regardless whether there is a break after the template opener (`BlockIndent`). To clarify: - BlockIndent ``` template < typename Foo, typename Bar, typename Baz > template ``` - Multiline ``` template < typename Foo, typename Bar, typename Baz > template ``` > So I believe that should be another patch. Like I said, I'm ok with some of the enumerated values being implemented in another patch. https://github.com/llvm/llvm-project/pull/118046 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang-format] Add BreakBeforeTemplateClose option (PR #118046)
leijurv wrote: I apologize for forgetting `clang-format-check-format` You're right that I had still missed some more cases of `verifyNoChange`. I've changed those now in https://github.com/llvm/llvm-project/pull/118046/commits/130428887e534cc3bfdfeec5846df2fd1e939667. The last two remaining `verifyNoChange` can't be changed to `verifyFormat`. https://github.com/llvm/llvm-project/pull/118046 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang-format] Add BreakBeforeTemplateClose option (PR #118046)
https://github.com/leijurv updated https://github.com/llvm/llvm-project/pull/118046 >From 1caf823165b16f6701993d586df51d5cdbf0885e Mon Sep 17 00:00:00 2001 From: Leijurv Date: Fri, 29 Nov 2024 21:54:36 -0600 Subject: [PATCH 1/7] [clang-format] Add BreakBeforeTemplateClose option --- clang/docs/ClangFormatStyleOptions.rst | 21 clang/docs/ReleaseNotes.rst| 1 + clang/include/clang/Format/Format.h| 20 clang/lib/Format/ContinuationIndenter.cpp | 11 ++ clang/lib/Format/ContinuationIndenter.h| 26 ++-- clang/lib/Format/Format.cpp| 2 + clang/lib/Format/TokenAnnotator.cpp| 2 +- clang/unittests/Format/ConfigParseTest.cpp | 1 + clang/unittests/Format/FormatTest.cpp | 131 + 9 files changed, 206 insertions(+), 9 deletions(-) diff --git a/clang/docs/ClangFormatStyleOptions.rst b/clang/docs/ClangFormatStyleOptions.rst index 4be448171699ca..84ab1b0a2eff61 100644 --- a/clang/docs/ClangFormatStyleOptions.rst +++ b/clang/docs/ClangFormatStyleOptions.rst @@ -3416,6 +3416,27 @@ the configuration (without a prefix: ``Auto``). +.. _BreakBeforeTemplateClose: + +**BreakBeforeTemplateClose** (``Boolean``) :versionbadge:`clang-format 20` :ref:`¶ ` + If ``true``, a line break will be placed before the ``>`` in a multiline + template declaration. + + .. code-block:: c++ + + true: + template < + typename Foo, + typename Bar, + typename Baz + > + + false: + template < + typename Foo, + typename Bar, + typename Baz> + .. _BreakBeforeTernaryOperators: **BreakBeforeTernaryOperators** (``Boolean``) :versionbadge:`clang-format 3.7` :ref:`¶ ` diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst index e44aefa90ab386..867d4b5d8c3f18 100644 --- a/clang/docs/ReleaseNotes.rst +++ b/clang/docs/ReleaseNotes.rst @@ -976,6 +976,7 @@ clang-format ``Never``, and ``true`` to ``Always``. - Adds ``RemoveEmptyLinesInUnwrappedLines`` option. - Adds ``KeepFormFeed`` option and set it to ``true`` for ``GNU`` style. +- Adds ``BreakBeforeTemplateClose`` option. libclang diff --git a/clang/include/clang/Format/Format.h b/clang/include/clang/Format/Format.h index 6383934afa2c40..bffd964f6aa8aa 100644 --- a/clang/include/clang/Format/Format.h +++ b/clang/include/clang/Format/Format.h @@ -2248,6 +2248,25 @@ struct FormatStyle { /// \version 16 BreakBeforeInlineASMColonStyle BreakBeforeInlineASMColon; + /// If ``true``, a line break will be placed before the ``>`` in a multiline + /// template declaration. + /// \code + ///true: + ///template < + ///typename Foo, + ///typename Bar, + ///typename Baz + ///> + /// + ///false: + ///template < + ///typename Foo, + ///typename Bar, + ///typename Baz> + /// \endcode + /// \version 20 + bool BreakBeforeTemplateClose; + /// If ``true``, ternary operators will be placed after line breaks. /// \code ///true: @@ -5184,6 +5203,7 @@ struct FormatStyle { BreakBeforeBraces == R.BreakBeforeBraces && BreakBeforeConceptDeclarations == R.BreakBeforeConceptDeclarations && BreakBeforeInlineASMColon == R.BreakBeforeInlineASMColon && + BreakBeforeTemplateClose == R.BreakBeforeTemplateClose && BreakBeforeTernaryOperators == R.BreakBeforeTernaryOperators && BreakBinaryOperations == R.BreakBinaryOperations && BreakConstructorInitializers == R.BreakConstructorInitializers && diff --git a/clang/lib/Format/ContinuationIndenter.cpp b/clang/lib/Format/ContinuationIndenter.cpp index aed86c1fb99551..4c783623afc535 100644 --- a/clang/lib/Format/ContinuationIndenter.cpp +++ b/clang/lib/Format/ContinuationIndenter.cpp @@ -406,6 +406,10 @@ bool ContinuationIndenter::mustBreak(const LineState &State) { } if (CurrentState.BreakBeforeClosingParen && Current.is(tok::r_paren)) return true; + if (CurrentState.BreakBeforeClosingAngle && + Current.ClosesTemplateDeclaration && Style.BreakBeforeTemplateClose) { +return true; + } if (Style.Language == FormatStyle::LK_ObjC && Style.ObjCBreakBeforeNestedBlockParam && Current.ObjCSelectorNameParts > 1 && @@ -1234,6 +1238,9 @@ unsigned ContinuationIndenter::addTokenOnNewLine(LineState &State, Style.AlignAfterOpenBracket == FormatStyle::BAS_BlockIndent; } + if (PreviousNonComment && PreviousNonComment->is(tok::less)) +CurrentState.BreakBeforeClosingAngle = true; + if (CurrentState.AvoidBinPacking) { // If we are breaking after '(', '{', '<', or this is the break after a ':' // to start a member initializer list in a constructor, this should not @@ -1370,6 +1377,10 @@ unsigned ContinuationIndenter::getNewLineColumn(const LineState &State) { State.Stack.size() > 1) { return State.Stack[State.Stack.size() - 2].Last
[clang] [clang-format] Add BreakBeforeTemplateClose option (PR #118046)
https://github.com/leijurv updated https://github.com/llvm/llvm-project/pull/118046 >From 1caf823165b16f6701993d586df51d5cdbf0885e Mon Sep 17 00:00:00 2001 From: Leijurv Date: Fri, 29 Nov 2024 21:54:36 -0600 Subject: [PATCH 1/6] [clang-format] Add BreakBeforeTemplateClose option --- clang/docs/ClangFormatStyleOptions.rst | 21 clang/docs/ReleaseNotes.rst| 1 + clang/include/clang/Format/Format.h| 20 clang/lib/Format/ContinuationIndenter.cpp | 11 ++ clang/lib/Format/ContinuationIndenter.h| 26 ++-- clang/lib/Format/Format.cpp| 2 + clang/lib/Format/TokenAnnotator.cpp| 2 +- clang/unittests/Format/ConfigParseTest.cpp | 1 + clang/unittests/Format/FormatTest.cpp | 131 + 9 files changed, 206 insertions(+), 9 deletions(-) diff --git a/clang/docs/ClangFormatStyleOptions.rst b/clang/docs/ClangFormatStyleOptions.rst index 4be448171699ca..84ab1b0a2eff61 100644 --- a/clang/docs/ClangFormatStyleOptions.rst +++ b/clang/docs/ClangFormatStyleOptions.rst @@ -3416,6 +3416,27 @@ the configuration (without a prefix: ``Auto``). +.. _BreakBeforeTemplateClose: + +**BreakBeforeTemplateClose** (``Boolean``) :versionbadge:`clang-format 20` :ref:`¶ ` + If ``true``, a line break will be placed before the ``>`` in a multiline + template declaration. + + .. code-block:: c++ + + true: + template < + typename Foo, + typename Bar, + typename Baz + > + + false: + template < + typename Foo, + typename Bar, + typename Baz> + .. _BreakBeforeTernaryOperators: **BreakBeforeTernaryOperators** (``Boolean``) :versionbadge:`clang-format 3.7` :ref:`¶ ` diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst index e44aefa90ab386..867d4b5d8c3f18 100644 --- a/clang/docs/ReleaseNotes.rst +++ b/clang/docs/ReleaseNotes.rst @@ -976,6 +976,7 @@ clang-format ``Never``, and ``true`` to ``Always``. - Adds ``RemoveEmptyLinesInUnwrappedLines`` option. - Adds ``KeepFormFeed`` option and set it to ``true`` for ``GNU`` style. +- Adds ``BreakBeforeTemplateClose`` option. libclang diff --git a/clang/include/clang/Format/Format.h b/clang/include/clang/Format/Format.h index 6383934afa2c40..bffd964f6aa8aa 100644 --- a/clang/include/clang/Format/Format.h +++ b/clang/include/clang/Format/Format.h @@ -2248,6 +2248,25 @@ struct FormatStyle { /// \version 16 BreakBeforeInlineASMColonStyle BreakBeforeInlineASMColon; + /// If ``true``, a line break will be placed before the ``>`` in a multiline + /// template declaration. + /// \code + ///true: + ///template < + ///typename Foo, + ///typename Bar, + ///typename Baz + ///> + /// + ///false: + ///template < + ///typename Foo, + ///typename Bar, + ///typename Baz> + /// \endcode + /// \version 20 + bool BreakBeforeTemplateClose; + /// If ``true``, ternary operators will be placed after line breaks. /// \code ///true: @@ -5184,6 +5203,7 @@ struct FormatStyle { BreakBeforeBraces == R.BreakBeforeBraces && BreakBeforeConceptDeclarations == R.BreakBeforeConceptDeclarations && BreakBeforeInlineASMColon == R.BreakBeforeInlineASMColon && + BreakBeforeTemplateClose == R.BreakBeforeTemplateClose && BreakBeforeTernaryOperators == R.BreakBeforeTernaryOperators && BreakBinaryOperations == R.BreakBinaryOperations && BreakConstructorInitializers == R.BreakConstructorInitializers && diff --git a/clang/lib/Format/ContinuationIndenter.cpp b/clang/lib/Format/ContinuationIndenter.cpp index aed86c1fb99551..4c783623afc535 100644 --- a/clang/lib/Format/ContinuationIndenter.cpp +++ b/clang/lib/Format/ContinuationIndenter.cpp @@ -406,6 +406,10 @@ bool ContinuationIndenter::mustBreak(const LineState &State) { } if (CurrentState.BreakBeforeClosingParen && Current.is(tok::r_paren)) return true; + if (CurrentState.BreakBeforeClosingAngle && + Current.ClosesTemplateDeclaration && Style.BreakBeforeTemplateClose) { +return true; + } if (Style.Language == FormatStyle::LK_ObjC && Style.ObjCBreakBeforeNestedBlockParam && Current.ObjCSelectorNameParts > 1 && @@ -1234,6 +1238,9 @@ unsigned ContinuationIndenter::addTokenOnNewLine(LineState &State, Style.AlignAfterOpenBracket == FormatStyle::BAS_BlockIndent; } + if (PreviousNonComment && PreviousNonComment->is(tok::less)) +CurrentState.BreakBeforeClosingAngle = true; + if (CurrentState.AvoidBinPacking) { // If we are breaking after '(', '{', '<', or this is the break after a ':' // to start a member initializer list in a constructor, this should not @@ -1370,6 +1377,10 @@ unsigned ContinuationIndenter::getNewLineColumn(const LineState &State) { State.Stack.size() > 1) { return State.Stack[State.Stack.size() - 2].Last
[clang] [clang-format] Add BreakBeforeTemplateClose option (PR #118046)
@@ -2252,6 +2252,25 @@ struct FormatStyle { /// \version 16 BreakBeforeInlineASMColonStyle BreakBeforeInlineASMColon; + /// If ``true``, a line break will be placed before the ``>`` in a multiline + /// template declaration. + /// \code + ///true: + ///template < + ///typename Foo, + ///typename Bar, + ///typename Baz + ///> + /// + ///false: + ///template < + ///typename Foo, + ///typename Bar, + ///typename Baz> leijurv wrote: In my mind that's a bit of a different option. You can see in your examples that you're assuming that the `>` goes on the next line, but that's what this PR is trying to add support for. Like, your enum (which is totally reasonable) would switch between: ``` template < typename Foo, typename Bar, typename Baz > ``` versus ``` template ``` But what I'm currently trying to add support for is: ``` template < typename Foo, typename Bar, typename Baz > template ``` versus ``` template < typename Foo, typename Bar, typename Baz> template ``` So I believe that should be another patch. https://github.com/llvm/llvm-project/pull/118046 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang-format] Add BreakBeforeTemplateClose option (PR #118046)
https://github.com/owenca edited https://github.com/llvm/llvm-project/pull/118046 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang-format] Add BreakBeforeTemplateClose option (PR #118046)
@@ -6,6 +6,275 @@ TEST_F(FormatTest, WrapsTemplateDeclarationsWithComments) { Style); } +TEST_F(FormatTest, BreakBeforeTemplateClose) { + FormatStyle Style = getGoogleStyle(FormatStyle::LK_Cpp); + // Begin with tests covering the case where there is no constraint on the column limit. + Style.ColumnLimit = 0; + // When BreakBeforeTemplateClose is turned off, the line break that it adds shall be removed: + verifyFormat("template <\n" + "typename Foo,\n" + "typename Bar>\n" + "void foo() {}", + "template <\n" + "typename Foo,\n" + "typename Bar\n" + ">\n" + "void foo() {}", + Style); + Style.BreakBeforeTemplateClose = true; + // BreakBeforeTemplateClose should NOT force template declarations onto multiple lines. + // Use verifyNoChange since ColumnLimit = 0. + verifyNoChange("template \n" + "void foo() {}", + Style); + verifyNoChange("template \n" + "void foo() {}", + Style); + // It should allow a line break, even when the typename is short: + verifyNoChange("template <\n" + "typename Foo\n" + ">\n" + "void foo() {}", + Style); + verifyNoChange("template <\n" + "typename Foo,\n" + "typename Bar\n" + ">\n" + "void foo() {}", + Style); + // It should add a line break before > if not already present: + verifyFormat("template <\n" + "typename Foo\n" + ">\n" + "void foo() {}", + "template <\n" + "typename Foo>\n" + "void foo() {}", + Style); + verifyFormat("template <\n" + "typename Foo,\n" + "typename Bar\n" + ">\n" + "void foo() {}", + "template <\n" + "typename Foo,\n" + "typename Bar>\n" + "void foo() {}", + Style); + // When within an indent scope, the > should be placed accordingly: + verifyFormat("struct Baz {\n" + " template <\n" + " typename Foo,\n" + " typename Bar\n" + " >\n" + " void foo() {}\n" + "};", + "struct Baz {\n" + " template <\n" + " typename Foo,\n" + " typename Bar>\n" + " void foo() {}\n" + "};", + Style); + + // Test from issue #80049: + verifyFormat( + "void foo() {\n" + " using type = std::remove_cv_t<\n" + " add_common_cv_reference<\n" + " std::common_type_t, std::decay_t>,\n" + " T0,\n" + " T1\n" + " >\n" + " >;\n" + "}", + "void foo() {\n" + " using type = std::remove_cv_t<\n" + " add_common_cv_reference<\n" + " std::common_type_t, std::decay_t>,\n" + " T0,\n" + " T1>>;\n" + "}", + Style); + + // Test lambda goes to next line: + verifyFormat("void foo() {\n" + " auto lambda = []<\n" + "typename T\n" + ">(T t) {\n" + " };\n" + "}", + "void foo() {\n" + " auto lambda = []<\n" + " typename T>(T t){\n" + " };\n" + "}", + Style); + // With no column limit, two parameters can go on the same line: + verifyFormat("void foo() {\n" + " auto lambda = []<\n" + "typename T, typename Foo\n" + ">(T t) {\n" + " };\n" + "}", + "void foo() {\n" + " auto lambda = []<\n" + " typename T, typename Foo>(T t){\n" + " };\n" + "}", + Style); + // Or on different lines: + verifyFormat("void foo() {\n" + " auto lambda = []<\n" + "typename T,\n" + "typename Foo\n" + ">(T t) {\n" + " };\n" + "}", + "void foo() {\n" + " auto lambda = []<\n" + " typename T,\n" + " typename Foo>(T t){\n" + " };\n" + "}", + Style); + + // Note that this is the same line (no \n): + verifyFormat("void foo() {\n" + " auto lambda = [](" + "Long t) {};\n" + "}", + Style); + + // Test template usage goes to nex
[clang] [clang-format] Add BreakBeforeTemplateClose option (PR #118046)
@@ -2252,6 +2252,25 @@ struct FormatStyle { /// \version 16 BreakBeforeInlineASMColonStyle BreakBeforeInlineASMColon; + /// If ``true``, a line break will be placed before the ``>`` in a multiline + /// template declaration. + /// \code + ///true: + ///template < + ///typename Foo, + ///typename Bar, + ///typename Baz + ///> + /// + ///false: + ///template < + ///typename Foo, + ///typename Bar, + ///typename Baz> + /// \endcode + /// \version 20 + bool BreakBeforeTemplateClose; owenca wrote: ```suggestion bool BreakBeforeTemplateCloser; ``` https://github.com/llvm/llvm-project/pull/118046 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang-format] Add BreakBeforeTemplateClose option (PR #118046)
@@ -2252,6 +2252,25 @@ struct FormatStyle { /// \version 16 BreakBeforeInlineASMColonStyle BreakBeforeInlineASMColon; + /// If ``true``, a line break will be placed before the ``>`` in a multiline + /// template declaration. + /// \code + ///true: + ///template < + ///typename Foo, + ///typename Bar, + ///typename Baz + ///> + /// + ///false: + ///template < + ///typename Foo, + ///typename Bar, + ///typename Baz> owenca wrote: We should make it an `enum` in order to handle more cases (now or in another patch), e.g.: - Always - BlockIndent ``` template < typename Foo, typename Bar, typename Baz > ``` - Leave - Multiline ``` template ``` - Never https://github.com/llvm/llvm-project/pull/118046 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang-format] Add BreakBeforeTemplateClose option (PR #118046)
https://github.com/owenca commented: You can run `ninja clang-format-check-format` to make sure your patch is correctly formatted before pushing. https://github.com/llvm/llvm-project/pull/118046 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang-format] Add BreakBeforeTemplateClose option (PR #118046)
owenca wrote: > > I think this should be covered by BlockIndent > > My understanding from looking at past PRs to clang-format was that backwards > compatibility was a top requirement. If I changed the behavior of BlockIndent > to put the `>` on the next line, that would change a lot of existing > behavior/codebases/tests. The default behavior of `AlignAfterOpenBracket` is `Align` for `LLVM` style, and the breaking for template angles seems to have the same default behavior. Unfortunately, `WebKit` style has `DontAlign` as its default. So let's keep this new option separate. > > Call verifyFormat instead of verifyNoChange whenever possible. > > I understand, but, I am testing the case where ColumnLimit = 0. When I call > `verifyFormat` it removes all the newlines. So I was unable to test the > behavior in the unconstrained column limit case. Note how I test that you can > have a `\n` after the `template<`, or not, and this option doesn't force it > either way. > > In the later part of the tests, starting when I change the ColumnLimit to 40, > note that all of the tests are `verifyFormat` and I don't use > `verifyNoChange` anymore. I got that as I said "whenever possible". > I have removed a few `verifyNoChange` in my last commit. There are still a couple of `verifyNoChange` that can be replaced with `verifyFormat` for your `ColumnLimit = 0` test cases, though. https://github.com/llvm/llvm-project/pull/118046 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang-format] Add BreakBeforeTemplateClose option (PR #118046)
github-actions[bot] wrote: :warning: C/C++ code formatter, clang-format found issues in your code. :warning: You can test this locally with the following command: ``bash git-clang-format --diff db88071a8b24ad9302659ee88383eea69a732f11 19bc40e7d824804ebcd9839cb2155a704d368e36 --extensions cpp,h -- clang/include/clang/Format/Format.h clang/lib/Format/ContinuationIndenter.cpp clang/lib/Format/ContinuationIndenter.h clang/lib/Format/Format.cpp clang/lib/Format/TokenAnnotator.cpp clang/unittests/Format/ConfigParseTest.cpp clang/unittests/Format/FormatTest.cpp `` View the diff from clang-format here. ``diff diff --git a/clang/unittests/Format/FormatTest.cpp b/clang/unittests/Format/FormatTest.cpp index cd968fc719..03581fde1c 100644 --- a/clang/unittests/Format/FormatTest.cpp +++ b/clang/unittests/Format/FormatTest.cpp @@ -8,9 +8,11 @@ TEST_F(FormatTest, WrapsTemplateDeclarationsWithComments) { TEST_F(FormatTest, BreakBeforeTemplateClose) { FormatStyle Style = getGoogleStyle(FormatStyle::LK_Cpp); - // Begin with tests covering the case where there is no constraint on the column limit. + // Begin with tests covering the case where there is no constraint on the + // column limit. Style.ColumnLimit = 0; - // When BreakBeforeTemplateClose is turned off, the line break that it adds shall be removed: + // When BreakBeforeTemplateClose is turned off, the line break that it adds + // shall be removed: verifyFormat("template <\n" "typename Foo,\n" "typename Bar>\n" @@ -11132,8 +11134,8 @@ TEST_F(FormatTest, BreakBeforeTemplateClose) { "void foo() {}", Style); Style.BreakBeforeTemplateClose = true; - // BreakBeforeTemplateClose should NOT force template declarations onto multiple lines. - // Use verifyNoChange since ColumnLimit = 0. + // BreakBeforeTemplateClose should NOT force template declarations onto + // multiple lines. Use verifyNoChange since ColumnLimit = 0. verifyNoChange("template \n" "void foo() {}", Style); `` https://github.com/llvm/llvm-project/pull/118046 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang-format] Add BreakBeforeTemplateClose option (PR #118046)
leijurv wrote: Thank you for the review @owenca > I think this should be covered by BlockIndent My understanding from looking at past PRs to clang-format was that backwards compatibility was a top requirement. If I changed the behavior of BlockIndent to put the `>` on the next line, that would change a lot of existing behavior/codebases/tests. > Call verifyFormat instead of verifyNoChange whenever possible. I understand, but, I am testing the case where ColumnLimit = 0. When I call `verifyFormat` it removes all the newlines. So I was unable to test the behavior in the unconstrained column limit case. Note how I test that you can have a `\n` after the `template<`, or not, and this option doesn't force it either way. In the later part of the tests, starting when I change the ColumnLimit to 40, note that all of the tests are `verifyFormat` and I don't use `verifyNoChange` anymore. I have removed a few `verifyNoChange` in my last commit. > Don't end a test case with a newline. > Capitalize the first word of a comment and end the comment with a . (or : if > appropriate). Sure! Did so in this commit https://github.com/llvm/llvm-project/pull/118046/commits/19bc40e7d824804ebcd9839cb2155a704d368e36 https://github.com/llvm/llvm-project/pull/118046 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang-format] Add BreakBeforeTemplateClose option (PR #118046)
https://github.com/leijurv updated https://github.com/llvm/llvm-project/pull/118046 >From 1caf823165b16f6701993d586df51d5cdbf0885e Mon Sep 17 00:00:00 2001 From: Leijurv Date: Fri, 29 Nov 2024 21:54:36 -0600 Subject: [PATCH 1/5] [clang-format] Add BreakBeforeTemplateClose option --- clang/docs/ClangFormatStyleOptions.rst | 21 clang/docs/ReleaseNotes.rst| 1 + clang/include/clang/Format/Format.h| 20 clang/lib/Format/ContinuationIndenter.cpp | 11 ++ clang/lib/Format/ContinuationIndenter.h| 26 ++-- clang/lib/Format/Format.cpp| 2 + clang/lib/Format/TokenAnnotator.cpp| 2 +- clang/unittests/Format/ConfigParseTest.cpp | 1 + clang/unittests/Format/FormatTest.cpp | 131 + 9 files changed, 206 insertions(+), 9 deletions(-) diff --git a/clang/docs/ClangFormatStyleOptions.rst b/clang/docs/ClangFormatStyleOptions.rst index 4be448171699ca..84ab1b0a2eff61 100644 --- a/clang/docs/ClangFormatStyleOptions.rst +++ b/clang/docs/ClangFormatStyleOptions.rst @@ -3416,6 +3416,27 @@ the configuration (without a prefix: ``Auto``). +.. _BreakBeforeTemplateClose: + +**BreakBeforeTemplateClose** (``Boolean``) :versionbadge:`clang-format 20` :ref:`¶ ` + If ``true``, a line break will be placed before the ``>`` in a multiline + template declaration. + + .. code-block:: c++ + + true: + template < + typename Foo, + typename Bar, + typename Baz + > + + false: + template < + typename Foo, + typename Bar, + typename Baz> + .. _BreakBeforeTernaryOperators: **BreakBeforeTernaryOperators** (``Boolean``) :versionbadge:`clang-format 3.7` :ref:`¶ ` diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst index e44aefa90ab386..867d4b5d8c3f18 100644 --- a/clang/docs/ReleaseNotes.rst +++ b/clang/docs/ReleaseNotes.rst @@ -976,6 +976,7 @@ clang-format ``Never``, and ``true`` to ``Always``. - Adds ``RemoveEmptyLinesInUnwrappedLines`` option. - Adds ``KeepFormFeed`` option and set it to ``true`` for ``GNU`` style. +- Adds ``BreakBeforeTemplateClose`` option. libclang diff --git a/clang/include/clang/Format/Format.h b/clang/include/clang/Format/Format.h index 6383934afa2c40..bffd964f6aa8aa 100644 --- a/clang/include/clang/Format/Format.h +++ b/clang/include/clang/Format/Format.h @@ -2248,6 +2248,25 @@ struct FormatStyle { /// \version 16 BreakBeforeInlineASMColonStyle BreakBeforeInlineASMColon; + /// If ``true``, a line break will be placed before the ``>`` in a multiline + /// template declaration. + /// \code + ///true: + ///template < + ///typename Foo, + ///typename Bar, + ///typename Baz + ///> + /// + ///false: + ///template < + ///typename Foo, + ///typename Bar, + ///typename Baz> + /// \endcode + /// \version 20 + bool BreakBeforeTemplateClose; + /// If ``true``, ternary operators will be placed after line breaks. /// \code ///true: @@ -5184,6 +5203,7 @@ struct FormatStyle { BreakBeforeBraces == R.BreakBeforeBraces && BreakBeforeConceptDeclarations == R.BreakBeforeConceptDeclarations && BreakBeforeInlineASMColon == R.BreakBeforeInlineASMColon && + BreakBeforeTemplateClose == R.BreakBeforeTemplateClose && BreakBeforeTernaryOperators == R.BreakBeforeTernaryOperators && BreakBinaryOperations == R.BreakBinaryOperations && BreakConstructorInitializers == R.BreakConstructorInitializers && diff --git a/clang/lib/Format/ContinuationIndenter.cpp b/clang/lib/Format/ContinuationIndenter.cpp index aed86c1fb99551..4c783623afc535 100644 --- a/clang/lib/Format/ContinuationIndenter.cpp +++ b/clang/lib/Format/ContinuationIndenter.cpp @@ -406,6 +406,10 @@ bool ContinuationIndenter::mustBreak(const LineState &State) { } if (CurrentState.BreakBeforeClosingParen && Current.is(tok::r_paren)) return true; + if (CurrentState.BreakBeforeClosingAngle && + Current.ClosesTemplateDeclaration && Style.BreakBeforeTemplateClose) { +return true; + } if (Style.Language == FormatStyle::LK_ObjC && Style.ObjCBreakBeforeNestedBlockParam && Current.ObjCSelectorNameParts > 1 && @@ -1234,6 +1238,9 @@ unsigned ContinuationIndenter::addTokenOnNewLine(LineState &State, Style.AlignAfterOpenBracket == FormatStyle::BAS_BlockIndent; } + if (PreviousNonComment && PreviousNonComment->is(tok::less)) +CurrentState.BreakBeforeClosingAngle = true; + if (CurrentState.AvoidBinPacking) { // If we are breaking after '(', '{', '<', or this is the break after a ':' // to start a member initializer list in a constructor, this should not @@ -1370,6 +1377,10 @@ unsigned ContinuationIndenter::getNewLineColumn(const LineState &State) { State.Stack.size() > 1) { return State.Stack[State.Stack.size() - 2].Last
[clang] [clang-format] Add BreakBeforeTemplateClose option (PR #118046)
https://github.com/owenca commented: About the test cases: - Call `verifyFormat` instead of `verifyNoChange` whenever possible. - Don't end a test case with a newline. (Search for `\n",` and `\n")`.) - Capitalize the first word of a comment and end the comment with a `.` (or `:` if appropriate). https://github.com/llvm/llvm-project/pull/118046 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang-format] Add BreakBeforeTemplateClose option (PR #118046)
owenca wrote: > > Maybe we should make it a sub-option for `BlockIndent`. I'm seeing a > > possible need for having control over other kinds of block indented > > structures such as Lambdas. I suspect the way this option has been > > implemented it interacts with the alignment options anyway. This would be a > > question probably for @owenca > > I thought about it some more and I don't think it would be a good idea. > Having a separate option seems a bit easier to handle, and allows mixing and > matching by users. I think this should be covered by [`BlockIndent`](https://clang.llvm.org/docs/ClangFormatStyleOptions.html#alignafteropenbracket), which already covers both parentheses and braces. Let's hear what @mydeveloperday has to say. https://github.com/llvm/llvm-project/pull/118046 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang-format] Add BreakBeforeTemplateClose option (PR #118046)
leijurv wrote: Thank you! It looks like I don't have permissions to merge, if you have them, could you? https://github.com/llvm/llvm-project/pull/118046 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang-format] Add BreakBeforeTemplateClose option (PR #118046)
https://github.com/HazardyKnusperkeks approved this pull request. https://github.com/llvm/llvm-project/pull/118046 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang-format] Add BreakBeforeTemplateClose option (PR #118046)
https://github.com/leijurv updated https://github.com/llvm/llvm-project/pull/118046 >From 1caf823165b16f6701993d586df51d5cdbf0885e Mon Sep 17 00:00:00 2001 From: Leijurv Date: Fri, 29 Nov 2024 21:54:36 -0600 Subject: [PATCH 1/4] [clang-format] Add BreakBeforeTemplateClose option --- clang/docs/ClangFormatStyleOptions.rst | 21 clang/docs/ReleaseNotes.rst| 1 + clang/include/clang/Format/Format.h| 20 clang/lib/Format/ContinuationIndenter.cpp | 11 ++ clang/lib/Format/ContinuationIndenter.h| 26 ++-- clang/lib/Format/Format.cpp| 2 + clang/lib/Format/TokenAnnotator.cpp| 2 +- clang/unittests/Format/ConfigParseTest.cpp | 1 + clang/unittests/Format/FormatTest.cpp | 131 + 9 files changed, 206 insertions(+), 9 deletions(-) diff --git a/clang/docs/ClangFormatStyleOptions.rst b/clang/docs/ClangFormatStyleOptions.rst index 4be448171699ca..84ab1b0a2eff61 100644 --- a/clang/docs/ClangFormatStyleOptions.rst +++ b/clang/docs/ClangFormatStyleOptions.rst @@ -3416,6 +3416,27 @@ the configuration (without a prefix: ``Auto``). +.. _BreakBeforeTemplateClose: + +**BreakBeforeTemplateClose** (``Boolean``) :versionbadge:`clang-format 20` :ref:`¶ ` + If ``true``, a line break will be placed before the ``>`` in a multiline + template declaration. + + .. code-block:: c++ + + true: + template < + typename Foo, + typename Bar, + typename Baz + > + + false: + template < + typename Foo, + typename Bar, + typename Baz> + .. _BreakBeforeTernaryOperators: **BreakBeforeTernaryOperators** (``Boolean``) :versionbadge:`clang-format 3.7` :ref:`¶ ` diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst index e44aefa90ab386..867d4b5d8c3f18 100644 --- a/clang/docs/ReleaseNotes.rst +++ b/clang/docs/ReleaseNotes.rst @@ -976,6 +976,7 @@ clang-format ``Never``, and ``true`` to ``Always``. - Adds ``RemoveEmptyLinesInUnwrappedLines`` option. - Adds ``KeepFormFeed`` option and set it to ``true`` for ``GNU`` style. +- Adds ``BreakBeforeTemplateClose`` option. libclang diff --git a/clang/include/clang/Format/Format.h b/clang/include/clang/Format/Format.h index 6383934afa2c40..bffd964f6aa8aa 100644 --- a/clang/include/clang/Format/Format.h +++ b/clang/include/clang/Format/Format.h @@ -2248,6 +2248,25 @@ struct FormatStyle { /// \version 16 BreakBeforeInlineASMColonStyle BreakBeforeInlineASMColon; + /// If ``true``, a line break will be placed before the ``>`` in a multiline + /// template declaration. + /// \code + ///true: + ///template < + ///typename Foo, + ///typename Bar, + ///typename Baz + ///> + /// + ///false: + ///template < + ///typename Foo, + ///typename Bar, + ///typename Baz> + /// \endcode + /// \version 20 + bool BreakBeforeTemplateClose; + /// If ``true``, ternary operators will be placed after line breaks. /// \code ///true: @@ -5184,6 +5203,7 @@ struct FormatStyle { BreakBeforeBraces == R.BreakBeforeBraces && BreakBeforeConceptDeclarations == R.BreakBeforeConceptDeclarations && BreakBeforeInlineASMColon == R.BreakBeforeInlineASMColon && + BreakBeforeTemplateClose == R.BreakBeforeTemplateClose && BreakBeforeTernaryOperators == R.BreakBeforeTernaryOperators && BreakBinaryOperations == R.BreakBinaryOperations && BreakConstructorInitializers == R.BreakConstructorInitializers && diff --git a/clang/lib/Format/ContinuationIndenter.cpp b/clang/lib/Format/ContinuationIndenter.cpp index aed86c1fb99551..4c783623afc535 100644 --- a/clang/lib/Format/ContinuationIndenter.cpp +++ b/clang/lib/Format/ContinuationIndenter.cpp @@ -406,6 +406,10 @@ bool ContinuationIndenter::mustBreak(const LineState &State) { } if (CurrentState.BreakBeforeClosingParen && Current.is(tok::r_paren)) return true; + if (CurrentState.BreakBeforeClosingAngle && + Current.ClosesTemplateDeclaration && Style.BreakBeforeTemplateClose) { +return true; + } if (Style.Language == FormatStyle::LK_ObjC && Style.ObjCBreakBeforeNestedBlockParam && Current.ObjCSelectorNameParts > 1 && @@ -1234,6 +1238,9 @@ unsigned ContinuationIndenter::addTokenOnNewLine(LineState &State, Style.AlignAfterOpenBracket == FormatStyle::BAS_BlockIndent; } + if (PreviousNonComment && PreviousNonComment->is(tok::less)) +CurrentState.BreakBeforeClosingAngle = true; + if (CurrentState.AvoidBinPacking) { // If we are breaking after '(', '{', '<', or this is the break after a ':' // to start a member initializer list in a constructor, this should not @@ -1370,6 +1377,10 @@ unsigned ContinuationIndenter::getNewLineColumn(const LineState &State) { State.Stack.size() > 1) { return State.Stack[State.Stack.size() - 2].Last
[clang] [clang-format] Add BreakBeforeTemplateClose option (PR #118046)
leijurv wrote: Ping :pray: https://github.com/llvm/llvm-project/pull/118046 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang-format] Add BreakBeforeTemplateClose option (PR #118046)
https://github.com/leijurv updated https://github.com/llvm/llvm-project/pull/118046 >From 1caf823165b16f6701993d586df51d5cdbf0885e Mon Sep 17 00:00:00 2001 From: Leijurv Date: Fri, 29 Nov 2024 21:54:36 -0600 Subject: [PATCH 1/4] [clang-format] Add BreakBeforeTemplateClose option --- clang/docs/ClangFormatStyleOptions.rst | 21 clang/docs/ReleaseNotes.rst| 1 + clang/include/clang/Format/Format.h| 20 clang/lib/Format/ContinuationIndenter.cpp | 11 ++ clang/lib/Format/ContinuationIndenter.h| 26 ++-- clang/lib/Format/Format.cpp| 2 + clang/lib/Format/TokenAnnotator.cpp| 2 +- clang/unittests/Format/ConfigParseTest.cpp | 1 + clang/unittests/Format/FormatTest.cpp | 131 + 9 files changed, 206 insertions(+), 9 deletions(-) diff --git a/clang/docs/ClangFormatStyleOptions.rst b/clang/docs/ClangFormatStyleOptions.rst index 4be448171699ca..84ab1b0a2eff61 100644 --- a/clang/docs/ClangFormatStyleOptions.rst +++ b/clang/docs/ClangFormatStyleOptions.rst @@ -3416,6 +3416,27 @@ the configuration (without a prefix: ``Auto``). +.. _BreakBeforeTemplateClose: + +**BreakBeforeTemplateClose** (``Boolean``) :versionbadge:`clang-format 20` :ref:`¶ ` + If ``true``, a line break will be placed before the ``>`` in a multiline + template declaration. + + .. code-block:: c++ + + true: + template < + typename Foo, + typename Bar, + typename Baz + > + + false: + template < + typename Foo, + typename Bar, + typename Baz> + .. _BreakBeforeTernaryOperators: **BreakBeforeTernaryOperators** (``Boolean``) :versionbadge:`clang-format 3.7` :ref:`¶ ` diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst index e44aefa90ab386..867d4b5d8c3f18 100644 --- a/clang/docs/ReleaseNotes.rst +++ b/clang/docs/ReleaseNotes.rst @@ -976,6 +976,7 @@ clang-format ``Never``, and ``true`` to ``Always``. - Adds ``RemoveEmptyLinesInUnwrappedLines`` option. - Adds ``KeepFormFeed`` option and set it to ``true`` for ``GNU`` style. +- Adds ``BreakBeforeTemplateClose`` option. libclang diff --git a/clang/include/clang/Format/Format.h b/clang/include/clang/Format/Format.h index 6383934afa2c40..bffd964f6aa8aa 100644 --- a/clang/include/clang/Format/Format.h +++ b/clang/include/clang/Format/Format.h @@ -2248,6 +2248,25 @@ struct FormatStyle { /// \version 16 BreakBeforeInlineASMColonStyle BreakBeforeInlineASMColon; + /// If ``true``, a line break will be placed before the ``>`` in a multiline + /// template declaration. + /// \code + ///true: + ///template < + ///typename Foo, + ///typename Bar, + ///typename Baz + ///> + /// + ///false: + ///template < + ///typename Foo, + ///typename Bar, + ///typename Baz> + /// \endcode + /// \version 20 + bool BreakBeforeTemplateClose; + /// If ``true``, ternary operators will be placed after line breaks. /// \code ///true: @@ -5184,6 +5203,7 @@ struct FormatStyle { BreakBeforeBraces == R.BreakBeforeBraces && BreakBeforeConceptDeclarations == R.BreakBeforeConceptDeclarations && BreakBeforeInlineASMColon == R.BreakBeforeInlineASMColon && + BreakBeforeTemplateClose == R.BreakBeforeTemplateClose && BreakBeforeTernaryOperators == R.BreakBeforeTernaryOperators && BreakBinaryOperations == R.BreakBinaryOperations && BreakConstructorInitializers == R.BreakConstructorInitializers && diff --git a/clang/lib/Format/ContinuationIndenter.cpp b/clang/lib/Format/ContinuationIndenter.cpp index aed86c1fb99551..4c783623afc535 100644 --- a/clang/lib/Format/ContinuationIndenter.cpp +++ b/clang/lib/Format/ContinuationIndenter.cpp @@ -406,6 +406,10 @@ bool ContinuationIndenter::mustBreak(const LineState &State) { } if (CurrentState.BreakBeforeClosingParen && Current.is(tok::r_paren)) return true; + if (CurrentState.BreakBeforeClosingAngle && + Current.ClosesTemplateDeclaration && Style.BreakBeforeTemplateClose) { +return true; + } if (Style.Language == FormatStyle::LK_ObjC && Style.ObjCBreakBeforeNestedBlockParam && Current.ObjCSelectorNameParts > 1 && @@ -1234,6 +1238,9 @@ unsigned ContinuationIndenter::addTokenOnNewLine(LineState &State, Style.AlignAfterOpenBracket == FormatStyle::BAS_BlockIndent; } + if (PreviousNonComment && PreviousNonComment->is(tok::less)) +CurrentState.BreakBeforeClosingAngle = true; + if (CurrentState.AvoidBinPacking) { // If we are breaking after '(', '{', '<', or this is the break after a ':' // to start a member initializer list in a constructor, this should not @@ -1370,6 +1377,10 @@ unsigned ContinuationIndenter::getNewLineColumn(const LineState &State) { State.Stack.size() > 1) { return State.Stack[State.Stack.size() - 2].Last
[clang] [clang-format] Add BreakBeforeTemplateClose option (PR #118046)
https://github.com/leijurv updated https://github.com/llvm/llvm-project/pull/118046 >From 1caf823165b16f6701993d586df51d5cdbf0885e Mon Sep 17 00:00:00 2001 From: Leijurv Date: Fri, 29 Nov 2024 21:54:36 -0600 Subject: [PATCH 1/4] [clang-format] Add BreakBeforeTemplateClose option --- clang/docs/ClangFormatStyleOptions.rst | 21 clang/docs/ReleaseNotes.rst| 1 + clang/include/clang/Format/Format.h| 20 clang/lib/Format/ContinuationIndenter.cpp | 11 ++ clang/lib/Format/ContinuationIndenter.h| 26 ++-- clang/lib/Format/Format.cpp| 2 + clang/lib/Format/TokenAnnotator.cpp| 2 +- clang/unittests/Format/ConfigParseTest.cpp | 1 + clang/unittests/Format/FormatTest.cpp | 131 + 9 files changed, 206 insertions(+), 9 deletions(-) diff --git a/clang/docs/ClangFormatStyleOptions.rst b/clang/docs/ClangFormatStyleOptions.rst index 4be448171699ca..84ab1b0a2eff61 100644 --- a/clang/docs/ClangFormatStyleOptions.rst +++ b/clang/docs/ClangFormatStyleOptions.rst @@ -3416,6 +3416,27 @@ the configuration (without a prefix: ``Auto``). +.. _BreakBeforeTemplateClose: + +**BreakBeforeTemplateClose** (``Boolean``) :versionbadge:`clang-format 20` :ref:`¶ ` + If ``true``, a line break will be placed before the ``>`` in a multiline + template declaration. + + .. code-block:: c++ + + true: + template < + typename Foo, + typename Bar, + typename Baz + > + + false: + template < + typename Foo, + typename Bar, + typename Baz> + .. _BreakBeforeTernaryOperators: **BreakBeforeTernaryOperators** (``Boolean``) :versionbadge:`clang-format 3.7` :ref:`¶ ` diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst index e44aefa90ab386..867d4b5d8c3f18 100644 --- a/clang/docs/ReleaseNotes.rst +++ b/clang/docs/ReleaseNotes.rst @@ -976,6 +976,7 @@ clang-format ``Never``, and ``true`` to ``Always``. - Adds ``RemoveEmptyLinesInUnwrappedLines`` option. - Adds ``KeepFormFeed`` option and set it to ``true`` for ``GNU`` style. +- Adds ``BreakBeforeTemplateClose`` option. libclang diff --git a/clang/include/clang/Format/Format.h b/clang/include/clang/Format/Format.h index 6383934afa2c40..bffd964f6aa8aa 100644 --- a/clang/include/clang/Format/Format.h +++ b/clang/include/clang/Format/Format.h @@ -2248,6 +2248,25 @@ struct FormatStyle { /// \version 16 BreakBeforeInlineASMColonStyle BreakBeforeInlineASMColon; + /// If ``true``, a line break will be placed before the ``>`` in a multiline + /// template declaration. + /// \code + ///true: + ///template < + ///typename Foo, + ///typename Bar, + ///typename Baz + ///> + /// + ///false: + ///template < + ///typename Foo, + ///typename Bar, + ///typename Baz> + /// \endcode + /// \version 20 + bool BreakBeforeTemplateClose; + /// If ``true``, ternary operators will be placed after line breaks. /// \code ///true: @@ -5184,6 +5203,7 @@ struct FormatStyle { BreakBeforeBraces == R.BreakBeforeBraces && BreakBeforeConceptDeclarations == R.BreakBeforeConceptDeclarations && BreakBeforeInlineASMColon == R.BreakBeforeInlineASMColon && + BreakBeforeTemplateClose == R.BreakBeforeTemplateClose && BreakBeforeTernaryOperators == R.BreakBeforeTernaryOperators && BreakBinaryOperations == R.BreakBinaryOperations && BreakConstructorInitializers == R.BreakConstructorInitializers && diff --git a/clang/lib/Format/ContinuationIndenter.cpp b/clang/lib/Format/ContinuationIndenter.cpp index aed86c1fb99551..4c783623afc535 100644 --- a/clang/lib/Format/ContinuationIndenter.cpp +++ b/clang/lib/Format/ContinuationIndenter.cpp @@ -406,6 +406,10 @@ bool ContinuationIndenter::mustBreak(const LineState &State) { } if (CurrentState.BreakBeforeClosingParen && Current.is(tok::r_paren)) return true; + if (CurrentState.BreakBeforeClosingAngle && + Current.ClosesTemplateDeclaration && Style.BreakBeforeTemplateClose) { +return true; + } if (Style.Language == FormatStyle::LK_ObjC && Style.ObjCBreakBeforeNestedBlockParam && Current.ObjCSelectorNameParts > 1 && @@ -1234,6 +1238,9 @@ unsigned ContinuationIndenter::addTokenOnNewLine(LineState &State, Style.AlignAfterOpenBracket == FormatStyle::BAS_BlockIndent; } + if (PreviousNonComment && PreviousNonComment->is(tok::less)) +CurrentState.BreakBeforeClosingAngle = true; + if (CurrentState.AvoidBinPacking) { // If we are breaking after '(', '{', '<', or this is the break after a ':' // to start a member initializer list in a constructor, this should not @@ -1370,6 +1377,10 @@ unsigned ContinuationIndenter::getNewLineColumn(const LineState &State) { State.Stack.size() > 1) { return State.Stack[State.Stack.size() - 2].Last
[clang] [clang-format] Add BreakBeforeTemplateClose option (PR #118046)
@@ -11077,6 +11077,281 @@ TEST_F(FormatTest, WrapsTemplateDeclarationsWithComments) { Style); } +TEST_F(FormatTest, BreakBeforeTemplateClose) { + FormatStyle Style = getGoogleStyle(FormatStyle::LK_Cpp); + Style.ColumnLimit = 0; + verifyNoChange("template \n" + "void foo() {}", + Style); + verifyNoChange("template <\n" + "typename Foo,\n" + "typename Bar>\n" + "void foo() {}", + Style); + // when BreakBeforeTemplateClose is off, this line break is removed: + verifyFormat("template <\n" + "typename Foo,\n" + "typename Bar>\n" + "void foo() {}", + "template <\n" + "typename Foo,\n" + "typename Bar\n" + ">\n" + "void foo() {}", + Style); + Style.BreakBeforeTemplateClose = true; + // BreakBeforeTemplateClose should NOT force multiline templates + verifyNoChange("template \n" + "void foo() {}", + Style); + verifyNoChange("template \n" + "void foo() {}", + Style); + // it should allow a line break: + verifyNoChange("template <\n" + "typename Foo\n" + ">\n" + "void foo() {}", + Style); + verifyNoChange("template <\n" + "typename Foo,\n" + "typename Bar\n" + ">\n" + "void foo() {}", + Style); + // it should add a line break if not already present: + verifyFormat("template <\n" + "typename Foo\n" + ">\n" + "void foo() {}", + "template <\n" + "typename Foo>\n" + "void foo() {}", + Style); + verifyFormat("template <\n" + "typename Foo,\n" + "typename Bar\n" + ">\n" + "void foo() {}", + "template <\n" + "typename Foo,\n" + "typename Bar>\n" + "void foo() {}", + Style); + // when within an indent scope, the > should be placed appropriately: + verifyFormat("struct Baz {\n" + " template <\n" + " typename Foo,\n" + " typename Bar\n" + " >\n" + " void foo() {}\n" + "};", + "struct Baz {\n" + " template <\n" + " typename Foo,\n" + " typename Bar>\n" + " void foo() {}\n" + "};", + Style); + + // test from issue #80049 + verifyFormat( + "void foo() {\n" + " using type = std::remove_cv_t<\n" + " add_common_cv_reference<\n" + " std::common_type_t, std::decay_t>,\n" + " T0,\n" + " T1\n" + " >\n" + " >;\n" + "}\n", + "void foo() {\n" + " using type = std::remove_cv_t<\n" + " add_common_cv_reference<\n" + " std::common_type_t, std::decay_t>,\n" + " T0,\n" + " T1>>;\n" + "}\n", + Style); + + // test lambda goes to next line: + verifyFormat("void foo() {\n" + " auto lambda = []<\n" + "typename T\n" + ">(T t) {\n" + " };\n" + "}\n", + "void foo() {\n" + " auto lambda = []<\n" + " typename T>(T t){\n" + " };\n" + "}\n", + Style); + // with no column limit, two parameters can go on the same line: + verifyFormat("void foo() {\n" + " auto lambda = []<\n" + "typename T, typename Foo\n" + ">(T t) {\n" + " };\n" + "}\n", + "void foo() {\n" + " auto lambda = []<\n" + " typename T, typename Foo>(T t){\n" + " };\n" + "}\n", + Style); + // or on different lines: + verifyFormat("void foo() {\n" + " auto lambda = []<\n" + "typename T,\n" + "typename Foo\n" + ">(T t) {\n" + " };\n" + "}\n", + "void foo() {\n" + " auto lambda = []<\n" + " typename T,\n" + " typename Foo>(T t){\n" + " };\n" + "}\n", + Style); + + // same line with no column limit + verifyFormat("void foo() {\n" + " auto lambda = [](" + "Long t) {};\n" + "}\n", + Sty
[clang] [clang-format] Add BreakBeforeTemplateClose option (PR #118046)
@@ -11077,6 +11077,281 @@ TEST_F(FormatTest, WrapsTemplateDeclarationsWithComments) { Style); } +TEST_F(FormatTest, BreakBeforeTemplateClose) { + FormatStyle Style = getGoogleStyle(FormatStyle::LK_Cpp); + Style.ColumnLimit = 0; + verifyNoChange("template \n" + "void foo() {}", + Style); + verifyNoChange("template <\n" + "typename Foo,\n" + "typename Bar>\n" + "void foo() {}", + Style); + // when BreakBeforeTemplateClose is off, this line break is removed: + verifyFormat("template <\n" + "typename Foo,\n" + "typename Bar>\n" + "void foo() {}", + "template <\n" + "typename Foo,\n" + "typename Bar\n" + ">\n" + "void foo() {}", + Style); + Style.BreakBeforeTemplateClose = true; + // BreakBeforeTemplateClose should NOT force multiline templates + verifyNoChange("template \n" + "void foo() {}", + Style); + verifyNoChange("template \n" + "void foo() {}", + Style); + // it should allow a line break: + verifyNoChange("template <\n" + "typename Foo\n" + ">\n" + "void foo() {}", + Style); + verifyNoChange("template <\n" + "typename Foo,\n" + "typename Bar\n" + ">\n" + "void foo() {}", + Style); + // it should add a line break if not already present: + verifyFormat("template <\n" + "typename Foo\n" + ">\n" + "void foo() {}", + "template <\n" + "typename Foo>\n" + "void foo() {}", + Style); + verifyFormat("template <\n" + "typename Foo,\n" + "typename Bar\n" + ">\n" + "void foo() {}", + "template <\n" + "typename Foo,\n" + "typename Bar>\n" + "void foo() {}", + Style); + // when within an indent scope, the > should be placed appropriately: + verifyFormat("struct Baz {\n" + " template <\n" + " typename Foo,\n" + " typename Bar\n" + " >\n" + " void foo() {}\n" + "};", + "struct Baz {\n" + " template <\n" + " typename Foo,\n" + " typename Bar>\n" + " void foo() {}\n" + "};", + Style); + + // test from issue #80049 + verifyFormat( + "void foo() {\n" + " using type = std::remove_cv_t<\n" + " add_common_cv_reference<\n" + " std::common_type_t, std::decay_t>,\n" + " T0,\n" + " T1\n" + " >\n" + " >;\n" + "}\n", + "void foo() {\n" + " using type = std::remove_cv_t<\n" + " add_common_cv_reference<\n" + " std::common_type_t, std::decay_t>,\n" + " T0,\n" + " T1>>;\n" + "}\n", + Style); + + // test lambda goes to next line: + verifyFormat("void foo() {\n" + " auto lambda = []<\n" + "typename T\n" + ">(T t) {\n" + " };\n" + "}\n", + "void foo() {\n" + " auto lambda = []<\n" + " typename T>(T t){\n" + " };\n" + "}\n", + Style); + // with no column limit, two parameters can go on the same line: + verifyFormat("void foo() {\n" + " auto lambda = []<\n" + "typename T, typename Foo\n" + ">(T t) {\n" + " };\n" + "}\n", + "void foo() {\n" + " auto lambda = []<\n" + " typename T, typename Foo>(T t){\n" + " };\n" + "}\n", + Style); + // or on different lines: + verifyFormat("void foo() {\n" + " auto lambda = []<\n" + "typename T,\n" + "typename Foo\n" + ">(T t) {\n" + " };\n" + "}\n", + "void foo() {\n" + " auto lambda = []<\n" + " typename T,\n" + " typename Foo>(T t){\n" + " };\n" + "}\n", + Style); + + // same line with no column limit + verifyFormat("void foo() {\n" + " auto lambda = [](" + "Long t) {};\n" + "}\n", + Sty
[clang] [clang-format] Add BreakBeforeTemplateClose option (PR #118046)
@@ -11077,6 +11077,221 @@ TEST_F(FormatTest, WrapsTemplateDeclarationsWithComments) { Style); } +TEST_F(FormatTest, BreakBeforeTemplateClose) { HazardyKnusperkeks wrote: Sorry missed that, didn't look for the lambda case. https://github.com/llvm/llvm-project/pull/118046 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang-format] Add BreakBeforeTemplateClose option (PR #118046)
@@ -11077,6 +11077,281 @@ TEST_F(FormatTest, WrapsTemplateDeclarationsWithComments) { Style); } +TEST_F(FormatTest, BreakBeforeTemplateClose) { + FormatStyle Style = getGoogleStyle(FormatStyle::LK_Cpp); + Style.ColumnLimit = 0; + verifyNoChange("template \n" + "void foo() {}", + Style); + verifyNoChange("template <\n" + "typename Foo,\n" + "typename Bar>\n" + "void foo() {}", + Style); + // when BreakBeforeTemplateClose is off, this line break is removed: + verifyFormat("template <\n" + "typename Foo,\n" + "typename Bar>\n" + "void foo() {}", + "template <\n" + "typename Foo,\n" + "typename Bar\n" + ">\n" + "void foo() {}", + Style); + Style.BreakBeforeTemplateClose = true; + // BreakBeforeTemplateClose should NOT force multiline templates + verifyNoChange("template \n" + "void foo() {}", + Style); + verifyNoChange("template \n" + "void foo() {}", + Style); + // it should allow a line break: + verifyNoChange("template <\n" + "typename Foo\n" + ">\n" + "void foo() {}", + Style); + verifyNoChange("template <\n" + "typename Foo,\n" + "typename Bar\n" + ">\n" + "void foo() {}", + Style); + // it should add a line break if not already present: + verifyFormat("template <\n" + "typename Foo\n" + ">\n" + "void foo() {}", + "template <\n" + "typename Foo>\n" + "void foo() {}", + Style); + verifyFormat("template <\n" + "typename Foo,\n" + "typename Bar\n" + ">\n" + "void foo() {}", + "template <\n" + "typename Foo,\n" + "typename Bar>\n" + "void foo() {}", + Style); + // when within an indent scope, the > should be placed appropriately: + verifyFormat("struct Baz {\n" + " template <\n" + " typename Foo,\n" + " typename Bar\n" + " >\n" + " void foo() {}\n" + "};", + "struct Baz {\n" + " template <\n" + " typename Foo,\n" + " typename Bar>\n" + " void foo() {}\n" + "};", + Style); + + // test from issue #80049 + verifyFormat( + "void foo() {\n" + " using type = std::remove_cv_t<\n" + " add_common_cv_reference<\n" + " std::common_type_t, std::decay_t>,\n" + " T0,\n" + " T1\n" + " >\n" + " >;\n" + "}\n", + "void foo() {\n" + " using type = std::remove_cv_t<\n" + " add_common_cv_reference<\n" + " std::common_type_t, std::decay_t>,\n" + " T0,\n" + " T1>>;\n" + "}\n", + Style); + + // test lambda goes to next line: + verifyFormat("void foo() {\n" + " auto lambda = []<\n" + "typename T\n" + ">(T t) {\n" + " };\n" + "}\n", + "void foo() {\n" + " auto lambda = []<\n" + " typename T>(T t){\n" + " };\n" + "}\n", + Style); + // with no column limit, two parameters can go on the same line: + verifyFormat("void foo() {\n" + " auto lambda = []<\n" + "typename T, typename Foo\n" + ">(T t) {\n" + " };\n" + "}\n", + "void foo() {\n" + " auto lambda = []<\n" + " typename T, typename Foo>(T t){\n" + " };\n" + "}\n", + Style); + // or on different lines: + verifyFormat("void foo() {\n" + " auto lambda = []<\n" + "typename T,\n" + "typename Foo\n" + ">(T t) {\n" + " };\n" + "}\n", + "void foo() {\n" + " auto lambda = []<\n" + " typename T,\n" + " typename Foo>(T t){\n" + " };\n" + "}\n", + Style); + + // same line with no column limit + verifyFormat("void foo() {\n" + " auto lambda = [](" + "Long t) {};\n" + "}\n", + Sty