[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
[clang] [clang-format] Add BreakBeforeTemplateClose option (PR #118046)
@@ -11077,6 +11077,221 @@ TEST_F(FormatTest, WrapsTemplateDeclarationsWithComments) { Style); } +TEST_F(FormatTest, BreakBeforeTemplateClose) { leijurv wrote: Sorry if I misunderstood, but, I thought I added that here: ![Screenshot_20241224-154618](https://github.com/user-attachments/assets/ce0a3af9-421e-48a9-a8ec-9b443f26b324) 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,221 @@ TEST_F(FormatTest, WrapsTemplateDeclarationsWithComments) { Style); } +TEST_F(FormatTest, BreakBeforeTemplateClose) { HazardyKnusperkeks wrote: This one is still missing. 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,221 @@ TEST_F(FormatTest, WrapsTemplateDeclarationsWithComments) { Style); } +TEST_F(FormatTest, BreakBeforeTemplateClose) { leijurv wrote: Sure! https://github.com/llvm/llvm-project/pull/118046/commits/2c3a64c8f32a5c43887db4d107a4142490898c20 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,221 @@ 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: leijurv wrote: Sure! https://github.com/llvm/llvm-project/pull/118046/commits/2c3a64c8f32a5c43887db4d107a4142490898c20 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)
@@ -11077,6 +11077,221 @@ 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: HazardyKnusperkeks wrote: Can you also add a lambda where the template is not on a new line? And multiple template parameters? 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,221 @@ TEST_F(FormatTest, WrapsTemplateDeclarationsWithComments) { Style); } +TEST_F(FormatTest, BreakBeforeTemplateClose) { HazardyKnusperkeks wrote: One additional test: How about nested templates? `template typename T>` for example. 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: Ping 🙏 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,157 @@ TEST_F(FormatTest, WrapsTemplateDeclarationsWithComments) { Style); } +TEST_F(FormatTest, BreakBeforeTemplateClose) { leijurv wrote: Good suggestion! I have added tests in this commit: https://github.com/llvm/llvm-project/pull/118046/commits/3927d411eeece27521e1a4034d01012c84beaf4b 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/3] [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/3] [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,157 @@ TEST_F(FormatTest, WrapsTemplateDeclarationsWithComments) { Style); } +TEST_F(FormatTest, BreakBeforeTemplateClose) { HazardyKnusperkeks wrote: I want to see some lambdas and template usages (not declarations). 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 think you should add test cases with multiple `>>` closing, see > `UnderstandsTemplateParameters` for example. > > Consider trying the code snippet mentioned in #80049 as well. Thank you for the suggestion! I have integrated that test case. It indicated that I was being too narrow - `ClosesTemplateDeclaration` only applies before functions, but, as you demonstrate, there are several other cases where templates are closed, so I have switched to `TT_TemplateCloser`. https://github.com/llvm/llvm-project/pull/118046/commits/212e26a2d194df996909a40ad0e0fc681d98 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/2] [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)
gedare wrote: I think you should add test cases with multiple `>>` closing, see `UnderstandsTemplateParameters` for example. Consider trying the code snippet mentioned in https://github.com/llvm/llvm-project/issues/80049 as well. 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)
gedare wrote: > > Yes. I followed the code that implements `AlignAfterOpenBracket: > > BlockIndent`, except applying to ClosesTemplateDeclaration. I made it a new > > setting for backwards compatibility. 👍 > > 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. 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)
gedare wrote: > Yes. I followed the code that implements `AlignAfterOpenBracket: > BlockIndent`, except applying to ClosesTemplateDeclaration. I made it a new > setting for backwards compatibility. 👍 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 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: Yes. I followed the code that implements `AlignAfterOpenBracket: BlockIndent`, except applying to ClosesTemplateDeclaration. I made it a new setting for backwards compatibility. 👍 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)
gedare wrote: Would this also be equivalent to supporting `AlignAfterOpenBracket: BlockIndent` for angle brackets? 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: 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] [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].LastSpac
[clang] [clang-format] Add BreakBeforeTemplateClose option (PR #118046)
https://github.com/leijurv updated https://github.com/llvm/llvm-project/pull/118046 >From b254c9311fb91374a21ba6ac5d44e087e4a55e98 Mon Sep 17 00:00:00 2001 From: Leijurv Date: Fri, 29 Nov 2024 21:54:36 -0600 Subject: [PATCH] [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].LastSpac
[clang] [clang-format] Add BreakBeforeTemplateClose option (PR #118046)
https://github.com/leijurv updated https://github.com/llvm/llvm-project/pull/118046 >From efb5b98de8817ce02a226353d9f5e36095874b27 Mon Sep 17 00:00:00 2001 From: Leijurv Date: Fri, 29 Nov 2024 21:54:36 -0600 Subject: [PATCH] [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 | 19 ++ clang/lib/Format/Format.cpp| 2 + clang/unittests/Format/ConfigParseTest.cpp | 1 + clang/unittests/Format/FormatTest.cpp | 78 ++ 7 files changed, 142 insertions(+) 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..f42574e135c91c 100644 --- a/clang/lib/Format/ContinuationIndenter.cpp +++ b/clang/lib/Format/ContinuationIndenter.cpp @@ -382,10 +382,25 @@ bool ContinuationIndenter::canBreak(const LineState &State) { return !State.NoLineBreak && !CurrentState.NoLineBreak; } +bool isMatchingBraceOnSameLine(const FormatToken *Token) { + if (!Token->MatchingParen) +return false; + const FormatToken *Matching = Token->MatchingParen; + const FormatToken *Current = Token; + while (Current && Current != Matching) { +if (Current->NewlinesBefore > 0) + return false; +Current = Current->Previous; + } + return true; +} + bool ContinuationIndenter::mustBreak(const LineState &State) { const FormatToken &Current = *State.NextToken; const FormatToken &Previous = *Current.Previous; const auto &CurrentState = State.Stack.back(); + if (Current.ClosesTemplateDeclaration && Style.BreakBeforeTemplateClose) +return !isMatchingBraceOnSameLine(State.NextToken); if (Style.BraceWrapping.BeforeLambdaBody && Current.CanBreakBefore && Current.is(TT_LambdaLBrace) && Previous.isNot(TT_LineComment)) { auto LambdaBodyLength = getLengthToMatchingParen(Current, State.Stack); @@ -1370,6 +1385,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)
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 4df01e5c4b5a5b4872c9d4f28c5bdce60ad79b84 Mon Sep 17 00:00:00 2001 From: Leijurv Date: Fri, 29 Nov 2024 21:54:36 -0600 Subject: [PATCH] [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 | 18 + clang/lib/Format/Format.cpp| 2 + clang/unittests/Format/ConfigParseTest.cpp | 1 + clang/unittests/Format/FormatTest.cpp | 79 ++ 7 files changed, 142 insertions(+) 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..0c77c18b3e7f48 100644 --- a/clang/lib/Format/ContinuationIndenter.cpp +++ b/clang/lib/Format/ContinuationIndenter.cpp @@ -382,10 +382,25 @@ bool ContinuationIndenter::canBreak(const LineState &State) { return !State.NoLineBreak && !CurrentState.NoLineBreak; } +bool isMatchingBraceOnSameLine(const FormatToken *Token) { + if (!Token->MatchingParen) +return false; + const FormatToken *Matching = Token->MatchingParen; + const FormatToken *Current = Token; + while (Current && Current != Matching) { +if (Current->NewlinesBefore > 0) + return false; +Current = Current->Previous; + } + return true; +} + bool ContinuationIndenter::mustBreak(const LineState &State) { const FormatToken &Current = *State.NextToken; const FormatToken &Previous = *Current.Previous; const auto &CurrentState = State.Stack.back(); + if (Current.ClosesTemplateDeclaration && Style.BreakBeforeTemplateClose) +return !isMatchingBraceOnSameLine(State.NextToken); if (Style.BraceWrapping.BeforeLambdaBody && Current.CanBreakBefore && Current.is(TT_LambdaLBrace) && Previous.isNot(TT_LineComment)) { auto LambdaBodyLength = getLengthToMatchingParen(Current, State.Stack); @@ -1279,6 +1294,9 @@ unsigned ContinuationIndenter::getNewLineColumn(const LineState &State) { FormatToken &Current = *State.NextToken; const auto &CurrentState = Sta
[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 79b3767b39d6d5d5c21bb461fb619651fb2443c5 Mon Sep 17 00:00:00 2001 From: Leijurv Date: Fri, 29 Nov 2024 21:54:36 -0600 Subject: [PATCH] [clang-format] Add BreakBeforeTemplateClose option --- clang/docs/ClangFormatStyleOptions.rst | 23 +++ clang/docs/ReleaseNotes.rst| 1 + clang/include/clang/Format/Format.h| 20 ++ clang/lib/Format/ContinuationIndenter.cpp | 18 + clang/lib/Format/Format.cpp| 2 + clang/unittests/Format/ConfigParseTest.cpp | 1 + clang/unittests/Format/FormatTest.cpp | 79 ++ 7 files changed, 144 insertions(+) diff --git a/clang/docs/ClangFormatStyleOptions.rst b/clang/docs/ClangFormatStyleOptions.rst index 4be448171699ca..31ed9a10d7153d 100644 --- a/clang/docs/ClangFormatStyleOptions.rst +++ b/clang/docs/ClangFormatStyleOptions.rst @@ -3416,6 +3416,29 @@ 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..0c77c18b3e7f48 100644 --- a/clang/lib/Format/ContinuationIndenter.cpp +++ b/clang/lib/Format/ContinuationIndenter.cpp @@ -382,10 +382,25 @@ bool ContinuationIndenter::canBreak(const LineState &State) { return !State.NoLineBreak && !CurrentState.NoLineBreak; } +bool isMatchingBraceOnSameLine(const FormatToken *Token) { + if (!Token->MatchingParen) +return false; + const FormatToken *Matching = Token->MatchingParen; + const FormatToken *Current = Token; + while (Current && Current != Matching) { +if (Current->NewlinesBefore > 0) + return false; +Current = Current->Previous; + } + return true; +} + bool ContinuationIndenter::mustBreak(const LineState &State) { const FormatToken &Current = *State.NextToken; const FormatToken &Previous = *Current.Previous; const auto &CurrentState = State.Stack.back(); + if (Current.ClosesTemplateDeclaration && Style.BreakBeforeTemplateClose) +return !isMatchingBraceOnSameLine(State.NextToken); if (Style.BraceWrapping.BeforeLambdaBody && Current.CanBreakBefore && Current.is(TT_LambdaLBrace) && Previous.isNot(TT_LineComment)) { auto LambdaBodyLength = getLengthToMatchingParen(Current, State.Stack); @@ -1279,6 +1294,9 @@ unsigned ContinuationIndenter::getNewLineColumn(const LineState &State) { FormatToken &Current = *State.NextToken; const auto &CurrentState
[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 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 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)
llvmbot wrote: @llvm/pr-subscribers-clang-format Author: leijurv (leijurv) Changes In clang-format, multiline templates have the `>` on the same line as the last parameter: ```c++ template< typename Foo, typename Bar, typename Baz> void foo() { ``` I would like to add an option to put the `>` on the next line, like this: ```c++ template< typename Foo, typename Bar, typename Baz > void foo() { ``` My reasoning is that it reminds me of this style of braces: ```c++ if (foo()) { bar();} ``` Most people agree this is better: ```c++ if (foo()) { bar(); } ``` --- Full diff: https://github.com/llvm/llvm-project/pull/118046.diff 7 Files Affected: - (modified) clang/docs/ClangFormatStyleOptions.rst (+23) - (modified) clang/docs/ReleaseNotes.rst (+1) - (modified) clang/include/clang/Format/Format.h (+20) - (modified) clang/lib/Format/ContinuationIndenter.cpp (+18) - (modified) clang/lib/Format/Format.cpp (+2) - (modified) clang/unittests/Format/ConfigParseTest.cpp (+1) - (modified) clang/unittests/Format/FormatTest.cpp (+79) ``diff diff --git a/clang/docs/ClangFormatStyleOptions.rst b/clang/docs/ClangFormatStyleOptions.rst index 4be448171699ca..31ed9a10d7153d 100644 --- a/clang/docs/ClangFormatStyleOptions.rst +++ b/clang/docs/ClangFormatStyleOptions.rst @@ -3416,6 +3416,29 @@ 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..0c77c18b3e7f48 100644 --- a/clang/lib/Format/ContinuationIndenter.cpp +++ b/clang/lib/Format/ContinuationIndenter.cpp @@ -382,10 +382,25 @@ bool ContinuationIndenter::canBreak(const LineState &State) { return !State.NoLineBreak && !CurrentState.NoLineBreak; } +bool isMatchingBraceOnSameLine(const FormatToken *Token) { + if (!Token->MatchingParen) +return false; + const FormatToken *Matching = Token->MatchingParen; + const FormatToken *Current = Token; + while (Current && Current != Matching) { +if (Current->NewlinesBefore > 0) + return false; +Current = Current->Previous; + } + return true; +} + bool ContinuationIndenter::mustBreak(const LineState &State) { const FormatToken &Current = *State.NextToken; const FormatToken &Previous = *Current.Previous; const auto &CurrentState = State.Stack.back(); + if (Current.ClosesTemplateDeclaration && Style.BreakBeforeTemplateClose) +return !isMatchingBraceOnSameLine(State.NextToken);
[clang] [clang-format] Add BreakBeforeTemplateClose option (PR #118046)
https://github.com/leijurv ready_for_review 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 217f80766d1eeeab4195f5d79cfed79c06657166 Mon Sep 17 00:00:00 2001 From: Leijurv Date: Fri, 29 Nov 2024 21:54:36 -0600 Subject: [PATCH] BreakBeforeTemplateClose --- clang/docs/ClangFormatStyleOptions.rst | 23 +++ clang/docs/ReleaseNotes.rst| 1 + clang/include/clang/Format/Format.h| 20 ++ clang/lib/Format/ContinuationIndenter.cpp | 18 + clang/lib/Format/Format.cpp| 2 + clang/unittests/Format/ConfigParseTest.cpp | 1 + clang/unittests/Format/FormatTest.cpp | 79 ++ 7 files changed, 144 insertions(+) diff --git a/clang/docs/ClangFormatStyleOptions.rst b/clang/docs/ClangFormatStyleOptions.rst index 4be448171699ca..31ed9a10d7153d 100644 --- a/clang/docs/ClangFormatStyleOptions.rst +++ b/clang/docs/ClangFormatStyleOptions.rst @@ -3416,6 +3416,29 @@ 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..0c77c18b3e7f48 100644 --- a/clang/lib/Format/ContinuationIndenter.cpp +++ b/clang/lib/Format/ContinuationIndenter.cpp @@ -382,10 +382,25 @@ bool ContinuationIndenter::canBreak(const LineState &State) { return !State.NoLineBreak && !CurrentState.NoLineBreak; } +bool isMatchingBraceOnSameLine(const FormatToken *Token) { + if (!Token->MatchingParen) +return false; + const FormatToken *Matching = Token->MatchingParen; + const FormatToken *Current = Token; + while (Current && Current != Matching) { +if (Current->NewlinesBefore > 0) + return false; +Current = Current->Previous; + } + return true; +} + bool ContinuationIndenter::mustBreak(const LineState &State) { const FormatToken &Current = *State.NextToken; const FormatToken &Previous = *Current.Previous; const auto &CurrentState = State.Stack.back(); + if (Current.ClosesTemplateDeclaration && Style.BreakBeforeTemplateClose) +return !isMatchingBraceOnSameLine(State.NextToken); if (Style.BraceWrapping.BeforeLambdaBody && Current.CanBreakBefore && Current.is(TT_LambdaLBrace) && Previous.isNot(TT_LineComment)) { auto LambdaBodyLength = getLengthToMatchingParen(Current, State.Stack); @@ -1279,6 +1294,9 @@ unsigned ContinuationIndenter::getNewLineColumn(const LineState &State) { FormatToken &Current = *State.NextToken; const auto &CurrentState = State.Stack.back(); +
[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