[clang] BreakBeforeTemplateClose (PR #118046)
https://github.com/leijurv updated https://github.com/llvm/llvm-project/pull/118046 >From de78cfbdefd90ce2427b552c941c613f93c9fd9a Mon Sep 17 00:00:00 2001 From: Leijurv Date: Fri, 29 Nov 2024 21:35:06 -0600 Subject: [PATCH] BreakBeforeTemplateClose --- clang/docs/ClangFormatStyleOptions.rst | 23 +++ clang/include/clang/Format/Format.h| 19 ++ clang/lib/Format/ContinuationIndenter.cpp | 18 + clang/lib/Format/Format.cpp| 1 + clang/unittests/Format/ConfigParseTest.cpp | 1 + clang/unittests/Format/FormatTest.cpp | 79 ++ 6 files changed, 141 insertions(+) diff --git a/clang/docs/ClangFormatStyleOptions.rst b/clang/docs/ClangFormatStyleOptions.rst index dc34094b5053a9..b40507b289049d 100644 --- a/clang/docs/ClangFormatStyleOptions.rst +++ b/clang/docs/ClangFormatStyleOptions.rst @@ -3416,6 +3416,29 @@ the configuration (without a prefix: ``Auto``). + +.. _BreakBeforeTemplateClose: + +**BreakBeforeTemplateClose** (``Boolean``) :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/include/clang/Format/Format.h b/clang/include/clang/Format/Format.h index 056fad2cc0ff8c..7a8b8ca72e494f 100644 --- a/clang/include/clang/Format/Format.h +++ b/clang/include/clang/Format/Format.h @@ -2248,6 +2248,24 @@ 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 + bool BreakBeforeTemplateClose{}; + /// If ``true``, ternary operators will be placed after line breaks. /// \code ///true: @@ -5184,6 +5202,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(); + if (Current.ClosesTemplateDeclaration && Style.BreakBeforeTemplateClose) +return CurrentState.Indent - Style.ContinuationIndentWidth; + if (CurrentState.IsCSharpGenericTypeConstraint && Current.isNot(TT_CSharpGenericTypeConstraint)) { return CurrentState.ColonPos + 2; diff --git a/clang/lib/Format/Format.cpp b/clang/lib/Format/Format.cpp index ee52972ce66f4a..3523f843d86b50 100644 --- a/clang/lib/Format/Format.cpp +++ b/clang/lib/Format/Format.cpp @@ -1000,6 +1000,7 @@ template <> struct MappingTraits { IO.mapOptional("Bre
[clang] BreakBeforeTemplateClose (PR #118046)
https://github.com/leijurv updated https://github.com/llvm/llvm-project/pull/118046 >From de78cfbdefd90ce2427b552c941c613f93c9fd9a Mon Sep 17 00:00:00 2001 From: Leijurv Date: Fri, 29 Nov 2024 21:35:06 -0600 Subject: [PATCH] BreakBeforeTemplateClose --- clang/docs/ClangFormatStyleOptions.rst | 23 +++ clang/include/clang/Format/Format.h| 19 ++ clang/lib/Format/ContinuationIndenter.cpp | 18 + clang/lib/Format/Format.cpp| 1 + clang/unittests/Format/ConfigParseTest.cpp | 1 + clang/unittests/Format/FormatTest.cpp | 79 ++ 6 files changed, 141 insertions(+) diff --git a/clang/docs/ClangFormatStyleOptions.rst b/clang/docs/ClangFormatStyleOptions.rst index dc34094b5053a9..b40507b289049d 100644 --- a/clang/docs/ClangFormatStyleOptions.rst +++ b/clang/docs/ClangFormatStyleOptions.rst @@ -3416,6 +3416,29 @@ the configuration (without a prefix: ``Auto``). + +.. _BreakBeforeTemplateClose: + +**BreakBeforeTemplateClose** (``Boolean``) :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/include/clang/Format/Format.h b/clang/include/clang/Format/Format.h index 056fad2cc0ff8c..7a8b8ca72e494f 100644 --- a/clang/include/clang/Format/Format.h +++ b/clang/include/clang/Format/Format.h @@ -2248,6 +2248,24 @@ 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 + bool BreakBeforeTemplateClose{}; + /// If ``true``, ternary operators will be placed after line breaks. /// \code ///true: @@ -5184,6 +5202,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(); + if (Current.ClosesTemplateDeclaration && Style.BreakBeforeTemplateClose) +return CurrentState.Indent - Style.ContinuationIndentWidth; + if (CurrentState.IsCSharpGenericTypeConstraint && Current.isNot(TT_CSharpGenericTypeConstraint)) { return CurrentState.ColonPos + 2; diff --git a/clang/lib/Format/Format.cpp b/clang/lib/Format/Format.cpp index ee52972ce66f4a..3523f843d86b50 100644 --- a/clang/lib/Format/Format.cpp +++ b/clang/lib/Format/Format.cpp @@ -1000,6 +1000,7 @@ template <> struct MappingTraits { IO.mapOptional("Bre
[clang] BreakBeforeTemplateClose (PR #118046)
https://github.com/leijurv updated https://github.com/llvm/llvm-project/pull/118046 >From b9886635c250fe765bf35c6b0e785f55b0749d52 Mon Sep 17 00:00:00 2001 From: Leijurv Date: Thu, 28 Nov 2024 21:44:50 -0600 Subject: [PATCH 01/10] BreakBeforeTemplateClose --- clang/docs/ClangFormatStyleOptions.rst | 23 ++ clang/include/clang/Format/Format.h| 4 clang/lib/Format/ContinuationIndenter.cpp | 22 + clang/lib/Format/Format.cpp| 2 ++ clang/unittests/Format/ConfigParseTest.cpp | 1 + clang/unittests/Format/FormatTest.cpp | 21 6 files changed, 73 insertions(+) diff --git a/clang/docs/ClangFormatStyleOptions.rst b/clang/docs/ClangFormatStyleOptions.rst index dc34094b5053a9..b40507b289049d 100644 --- a/clang/docs/ClangFormatStyleOptions.rst +++ b/clang/docs/ClangFormatStyleOptions.rst @@ -3416,6 +3416,29 @@ the configuration (without a prefix: ``Auto``). + +.. _BreakBeforeTemplateClose: + +**BreakBeforeTemplateClose** (``Boolean``) :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/include/clang/Format/Format.h b/clang/include/clang/Format/Format.h index 056fad2cc0ff8c..a8478060828072 100644 --- a/clang/include/clang/Format/Format.h +++ b/clang/include/clang/Format/Format.h @@ -2248,6 +2248,9 @@ struct FormatStyle { /// \version 16 BreakBeforeInlineASMColonStyle BreakBeforeInlineASMColon; + /// If ``true``, a line break will be placed before the ``>`` in a multiline template declaration. + bool BreakBeforeTemplateClose; + /// If ``true``, ternary operators will be placed after line breaks. /// \code ///true: @@ -5184,6 +5187,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..5887e9cef9011d 100644 --- a/clang/lib/Format/ContinuationIndenter.cpp +++ b/clang/lib/Format/ContinuationIndenter.cpp @@ -382,10 +382,28 @@ 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 +1297,10 @@ unsigned ContinuationIndenter::getNewLineColumn(const LineState &State) { FormatToken &Current = *State.NextToken; const auto &CurrentState = State.Stack.back(); + if (Current.ClosesTemplateDeclaration && Style.BreakBeforeTemplateClose) { +return 0; + } + if (CurrentState.IsCSharpGenericTypeConstraint && Current.isNot(TT_CSharpGenericTypeConstraint)) { return CurrentState.ColonPos + 2; diff --git a/clang/lib/Format/Format.cpp b/clang/lib/Format/Format.cpp index ee52972ce66f4a..a957129bbcf440 100644 --- a/clang/lib/Format/Format.cpp +++ b/clang/lib/Format/Format.cpp @@ -1000,6 +1000,8 @@ template <> struct MappingTraits { IO.mapOptional("BreakBeforeBraces", Style.BreakBeforeBraces); IO.mapOptional("BreakBeforeInlineASMColon", Style.BreakBeforeInlineASMColon); +IO.mapOptional("BreakBeforeTemplateClose", + Style.BreakBeforeTemplateClose); IO.mapOptional("BreakBeforeTernar
[clang] BreakBeforeTemplateClose (PR #118046)
https://github.com/leijurv updated https://github.com/llvm/llvm-project/pull/118046 >From b9886635c250fe765bf35c6b0e785f55b0749d52 Mon Sep 17 00:00:00 2001 From: Leijurv Date: Thu, 28 Nov 2024 21:44:50 -0600 Subject: [PATCH 1/9] BreakBeforeTemplateClose --- clang/docs/ClangFormatStyleOptions.rst | 23 ++ clang/include/clang/Format/Format.h| 4 clang/lib/Format/ContinuationIndenter.cpp | 22 + clang/lib/Format/Format.cpp| 2 ++ clang/unittests/Format/ConfigParseTest.cpp | 1 + clang/unittests/Format/FormatTest.cpp | 21 6 files changed, 73 insertions(+) diff --git a/clang/docs/ClangFormatStyleOptions.rst b/clang/docs/ClangFormatStyleOptions.rst index dc34094b5053a9..b40507b289049d 100644 --- a/clang/docs/ClangFormatStyleOptions.rst +++ b/clang/docs/ClangFormatStyleOptions.rst @@ -3416,6 +3416,29 @@ the configuration (without a prefix: ``Auto``). + +.. _BreakBeforeTemplateClose: + +**BreakBeforeTemplateClose** (``Boolean``) :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/include/clang/Format/Format.h b/clang/include/clang/Format/Format.h index 056fad2cc0ff8c..a8478060828072 100644 --- a/clang/include/clang/Format/Format.h +++ b/clang/include/clang/Format/Format.h @@ -2248,6 +2248,9 @@ struct FormatStyle { /// \version 16 BreakBeforeInlineASMColonStyle BreakBeforeInlineASMColon; + /// If ``true``, a line break will be placed before the ``>`` in a multiline template declaration. + bool BreakBeforeTemplateClose; + /// If ``true``, ternary operators will be placed after line breaks. /// \code ///true: @@ -5184,6 +5187,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..5887e9cef9011d 100644 --- a/clang/lib/Format/ContinuationIndenter.cpp +++ b/clang/lib/Format/ContinuationIndenter.cpp @@ -382,10 +382,28 @@ 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 +1297,10 @@ unsigned ContinuationIndenter::getNewLineColumn(const LineState &State) { FormatToken &Current = *State.NextToken; const auto &CurrentState = State.Stack.back(); + if (Current.ClosesTemplateDeclaration && Style.BreakBeforeTemplateClose) { +return 0; + } + if (CurrentState.IsCSharpGenericTypeConstraint && Current.isNot(TT_CSharpGenericTypeConstraint)) { return CurrentState.ColonPos + 2; diff --git a/clang/lib/Format/Format.cpp b/clang/lib/Format/Format.cpp index ee52972ce66f4a..a957129bbcf440 100644 --- a/clang/lib/Format/Format.cpp +++ b/clang/lib/Format/Format.cpp @@ -1000,6 +1000,8 @@ template <> struct MappingTraits { IO.mapOptional("BreakBeforeBraces", Style.BreakBeforeBraces); IO.mapOptional("BreakBeforeInlineASMColon", Style.BreakBeforeInlineASMColon); +IO.mapOptional("BreakBeforeTemplateClose", + Style.BreakBeforeTemplateClose); IO.mapOptional("BreakBeforeTernaryO
[clang] BreakBeforeTemplateClose (PR #118046)
https://github.com/leijurv updated https://github.com/llvm/llvm-project/pull/118046 >From b9886635c250fe765bf35c6b0e785f55b0749d52 Mon Sep 17 00:00:00 2001 From: Leijurv Date: Thu, 28 Nov 2024 21:44:50 -0600 Subject: [PATCH 1/8] BreakBeforeTemplateClose --- clang/docs/ClangFormatStyleOptions.rst | 23 ++ clang/include/clang/Format/Format.h| 4 clang/lib/Format/ContinuationIndenter.cpp | 22 + clang/lib/Format/Format.cpp| 2 ++ clang/unittests/Format/ConfigParseTest.cpp | 1 + clang/unittests/Format/FormatTest.cpp | 21 6 files changed, 73 insertions(+) diff --git a/clang/docs/ClangFormatStyleOptions.rst b/clang/docs/ClangFormatStyleOptions.rst index dc34094b5053a9..b40507b289049d 100644 --- a/clang/docs/ClangFormatStyleOptions.rst +++ b/clang/docs/ClangFormatStyleOptions.rst @@ -3416,6 +3416,29 @@ the configuration (without a prefix: ``Auto``). + +.. _BreakBeforeTemplateClose: + +**BreakBeforeTemplateClose** (``Boolean``) :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/include/clang/Format/Format.h b/clang/include/clang/Format/Format.h index 056fad2cc0ff8c..a8478060828072 100644 --- a/clang/include/clang/Format/Format.h +++ b/clang/include/clang/Format/Format.h @@ -2248,6 +2248,9 @@ struct FormatStyle { /// \version 16 BreakBeforeInlineASMColonStyle BreakBeforeInlineASMColon; + /// If ``true``, a line break will be placed before the ``>`` in a multiline template declaration. + bool BreakBeforeTemplateClose; + /// If ``true``, ternary operators will be placed after line breaks. /// \code ///true: @@ -5184,6 +5187,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..5887e9cef9011d 100644 --- a/clang/lib/Format/ContinuationIndenter.cpp +++ b/clang/lib/Format/ContinuationIndenter.cpp @@ -382,10 +382,28 @@ 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 +1297,10 @@ unsigned ContinuationIndenter::getNewLineColumn(const LineState &State) { FormatToken &Current = *State.NextToken; const auto &CurrentState = State.Stack.back(); + if (Current.ClosesTemplateDeclaration && Style.BreakBeforeTemplateClose) { +return 0; + } + if (CurrentState.IsCSharpGenericTypeConstraint && Current.isNot(TT_CSharpGenericTypeConstraint)) { return CurrentState.ColonPos + 2; diff --git a/clang/lib/Format/Format.cpp b/clang/lib/Format/Format.cpp index ee52972ce66f4a..a957129bbcf440 100644 --- a/clang/lib/Format/Format.cpp +++ b/clang/lib/Format/Format.cpp @@ -1000,6 +1000,8 @@ template <> struct MappingTraits { IO.mapOptional("BreakBeforeBraces", Style.BreakBeforeBraces); IO.mapOptional("BreakBeforeInlineASMColon", Style.BreakBeforeInlineASMColon); +IO.mapOptional("BreakBeforeTemplateClose", + Style.BreakBeforeTemplateClose); IO.mapOptional("BreakBeforeTernaryO
[clang] BreakBeforeTemplateClose (PR #118046)
https://github.com/leijurv updated https://github.com/llvm/llvm-project/pull/118046 >From b9886635c250fe765bf35c6b0e785f55b0749d52 Mon Sep 17 00:00:00 2001 From: Leijurv Date: Thu, 28 Nov 2024 21:44:50 -0600 Subject: [PATCH 1/7] BreakBeforeTemplateClose --- clang/docs/ClangFormatStyleOptions.rst | 23 ++ clang/include/clang/Format/Format.h| 4 clang/lib/Format/ContinuationIndenter.cpp | 22 + clang/lib/Format/Format.cpp| 2 ++ clang/unittests/Format/ConfigParseTest.cpp | 1 + clang/unittests/Format/FormatTest.cpp | 21 6 files changed, 73 insertions(+) diff --git a/clang/docs/ClangFormatStyleOptions.rst b/clang/docs/ClangFormatStyleOptions.rst index dc34094b5053a9..b40507b289049d 100644 --- a/clang/docs/ClangFormatStyleOptions.rst +++ b/clang/docs/ClangFormatStyleOptions.rst @@ -3416,6 +3416,29 @@ the configuration (without a prefix: ``Auto``). + +.. _BreakBeforeTemplateClose: + +**BreakBeforeTemplateClose** (``Boolean``) :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/include/clang/Format/Format.h b/clang/include/clang/Format/Format.h index 056fad2cc0ff8c..a8478060828072 100644 --- a/clang/include/clang/Format/Format.h +++ b/clang/include/clang/Format/Format.h @@ -2248,6 +2248,9 @@ struct FormatStyle { /// \version 16 BreakBeforeInlineASMColonStyle BreakBeforeInlineASMColon; + /// If ``true``, a line break will be placed before the ``>`` in a multiline template declaration. + bool BreakBeforeTemplateClose; + /// If ``true``, ternary operators will be placed after line breaks. /// \code ///true: @@ -5184,6 +5187,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..5887e9cef9011d 100644 --- a/clang/lib/Format/ContinuationIndenter.cpp +++ b/clang/lib/Format/ContinuationIndenter.cpp @@ -382,10 +382,28 @@ 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 +1297,10 @@ unsigned ContinuationIndenter::getNewLineColumn(const LineState &State) { FormatToken &Current = *State.NextToken; const auto &CurrentState = State.Stack.back(); + if (Current.ClosesTemplateDeclaration && Style.BreakBeforeTemplateClose) { +return 0; + } + if (CurrentState.IsCSharpGenericTypeConstraint && Current.isNot(TT_CSharpGenericTypeConstraint)) { return CurrentState.ColonPos + 2; diff --git a/clang/lib/Format/Format.cpp b/clang/lib/Format/Format.cpp index ee52972ce66f4a..a957129bbcf440 100644 --- a/clang/lib/Format/Format.cpp +++ b/clang/lib/Format/Format.cpp @@ -1000,6 +1000,8 @@ template <> struct MappingTraits { IO.mapOptional("BreakBeforeBraces", Style.BreakBeforeBraces); IO.mapOptional("BreakBeforeInlineASMColon", Style.BreakBeforeInlineASMColon); +IO.mapOptional("BreakBeforeTemplateClose", + Style.BreakBeforeTemplateClose); IO.mapOptional("BreakBeforeTernaryO
[clang] BreakBeforeTemplateClose (PR #118046)
https://github.com/leijurv updated https://github.com/llvm/llvm-project/pull/118046 >From b9886635c250fe765bf35c6b0e785f55b0749d52 Mon Sep 17 00:00:00 2001 From: Leijurv Date: Thu, 28 Nov 2024 21:44:50 -0600 Subject: [PATCH 1/6] BreakBeforeTemplateClose --- clang/docs/ClangFormatStyleOptions.rst | 23 ++ clang/include/clang/Format/Format.h| 4 clang/lib/Format/ContinuationIndenter.cpp | 22 + clang/lib/Format/Format.cpp| 2 ++ clang/unittests/Format/ConfigParseTest.cpp | 1 + clang/unittests/Format/FormatTest.cpp | 21 6 files changed, 73 insertions(+) diff --git a/clang/docs/ClangFormatStyleOptions.rst b/clang/docs/ClangFormatStyleOptions.rst index dc34094b5053a9..b40507b289049d 100644 --- a/clang/docs/ClangFormatStyleOptions.rst +++ b/clang/docs/ClangFormatStyleOptions.rst @@ -3416,6 +3416,29 @@ the configuration (without a prefix: ``Auto``). + +.. _BreakBeforeTemplateClose: + +**BreakBeforeTemplateClose** (``Boolean``) :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/include/clang/Format/Format.h b/clang/include/clang/Format/Format.h index 056fad2cc0ff8c..a8478060828072 100644 --- a/clang/include/clang/Format/Format.h +++ b/clang/include/clang/Format/Format.h @@ -2248,6 +2248,9 @@ struct FormatStyle { /// \version 16 BreakBeforeInlineASMColonStyle BreakBeforeInlineASMColon; + /// If ``true``, a line break will be placed before the ``>`` in a multiline template declaration. + bool BreakBeforeTemplateClose; + /// If ``true``, ternary operators will be placed after line breaks. /// \code ///true: @@ -5184,6 +5187,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..5887e9cef9011d 100644 --- a/clang/lib/Format/ContinuationIndenter.cpp +++ b/clang/lib/Format/ContinuationIndenter.cpp @@ -382,10 +382,28 @@ 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 +1297,10 @@ unsigned ContinuationIndenter::getNewLineColumn(const LineState &State) { FormatToken &Current = *State.NextToken; const auto &CurrentState = State.Stack.back(); + if (Current.ClosesTemplateDeclaration && Style.BreakBeforeTemplateClose) { +return 0; + } + if (CurrentState.IsCSharpGenericTypeConstraint && Current.isNot(TT_CSharpGenericTypeConstraint)) { return CurrentState.ColonPos + 2; diff --git a/clang/lib/Format/Format.cpp b/clang/lib/Format/Format.cpp index ee52972ce66f4a..a957129bbcf440 100644 --- a/clang/lib/Format/Format.cpp +++ b/clang/lib/Format/Format.cpp @@ -1000,6 +1000,8 @@ template <> struct MappingTraits { IO.mapOptional("BreakBeforeBraces", Style.BreakBeforeBraces); IO.mapOptional("BreakBeforeInlineASMColon", Style.BreakBeforeInlineASMColon); +IO.mapOptional("BreakBeforeTemplateClose", + Style.BreakBeforeTemplateClose); IO.mapOptional("BreakBeforeTernaryO
[clang] BreakBeforeTemplateClose (PR #118046)
https://github.com/leijurv updated https://github.com/llvm/llvm-project/pull/118046 >From b9886635c250fe765bf35c6b0e785f55b0749d52 Mon Sep 17 00:00:00 2001 From: Leijurv Date: Thu, 28 Nov 2024 21:44:50 -0600 Subject: [PATCH 1/5] BreakBeforeTemplateClose --- clang/docs/ClangFormatStyleOptions.rst | 23 ++ clang/include/clang/Format/Format.h| 4 clang/lib/Format/ContinuationIndenter.cpp | 22 + clang/lib/Format/Format.cpp| 2 ++ clang/unittests/Format/ConfigParseTest.cpp | 1 + clang/unittests/Format/FormatTest.cpp | 21 6 files changed, 73 insertions(+) diff --git a/clang/docs/ClangFormatStyleOptions.rst b/clang/docs/ClangFormatStyleOptions.rst index dc34094b5053a9..b40507b289049d 100644 --- a/clang/docs/ClangFormatStyleOptions.rst +++ b/clang/docs/ClangFormatStyleOptions.rst @@ -3416,6 +3416,29 @@ the configuration (without a prefix: ``Auto``). + +.. _BreakBeforeTemplateClose: + +**BreakBeforeTemplateClose** (``Boolean``) :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/include/clang/Format/Format.h b/clang/include/clang/Format/Format.h index 056fad2cc0ff8c..a8478060828072 100644 --- a/clang/include/clang/Format/Format.h +++ b/clang/include/clang/Format/Format.h @@ -2248,6 +2248,9 @@ struct FormatStyle { /// \version 16 BreakBeforeInlineASMColonStyle BreakBeforeInlineASMColon; + /// If ``true``, a line break will be placed before the ``>`` in a multiline template declaration. + bool BreakBeforeTemplateClose; + /// If ``true``, ternary operators will be placed after line breaks. /// \code ///true: @@ -5184,6 +5187,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..5887e9cef9011d 100644 --- a/clang/lib/Format/ContinuationIndenter.cpp +++ b/clang/lib/Format/ContinuationIndenter.cpp @@ -382,10 +382,28 @@ 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 +1297,10 @@ unsigned ContinuationIndenter::getNewLineColumn(const LineState &State) { FormatToken &Current = *State.NextToken; const auto &CurrentState = State.Stack.back(); + if (Current.ClosesTemplateDeclaration && Style.BreakBeforeTemplateClose) { +return 0; + } + if (CurrentState.IsCSharpGenericTypeConstraint && Current.isNot(TT_CSharpGenericTypeConstraint)) { return CurrentState.ColonPos + 2; diff --git a/clang/lib/Format/Format.cpp b/clang/lib/Format/Format.cpp index ee52972ce66f4a..a957129bbcf440 100644 --- a/clang/lib/Format/Format.cpp +++ b/clang/lib/Format/Format.cpp @@ -1000,6 +1000,8 @@ template <> struct MappingTraits { IO.mapOptional("BreakBeforeBraces", Style.BreakBeforeBraces); IO.mapOptional("BreakBeforeInlineASMColon", Style.BreakBeforeInlineASMColon); +IO.mapOptional("BreakBeforeTemplateClose", + Style.BreakBeforeTemplateClose); IO.mapOptional("BreakBeforeTernaryO
[clang] BreakBeforeTemplateClose (PR #118046)
https://github.com/leijurv updated https://github.com/llvm/llvm-project/pull/118046 >From b9886635c250fe765bf35c6b0e785f55b0749d52 Mon Sep 17 00:00:00 2001 From: Leijurv Date: Thu, 28 Nov 2024 21:44:50 -0600 Subject: [PATCH 1/4] BreakBeforeTemplateClose --- clang/docs/ClangFormatStyleOptions.rst | 23 ++ clang/include/clang/Format/Format.h| 4 clang/lib/Format/ContinuationIndenter.cpp | 22 + clang/lib/Format/Format.cpp| 2 ++ clang/unittests/Format/ConfigParseTest.cpp | 1 + clang/unittests/Format/FormatTest.cpp | 21 6 files changed, 73 insertions(+) diff --git a/clang/docs/ClangFormatStyleOptions.rst b/clang/docs/ClangFormatStyleOptions.rst index dc34094b5053a9..b40507b289049d 100644 --- a/clang/docs/ClangFormatStyleOptions.rst +++ b/clang/docs/ClangFormatStyleOptions.rst @@ -3416,6 +3416,29 @@ the configuration (without a prefix: ``Auto``). + +.. _BreakBeforeTemplateClose: + +**BreakBeforeTemplateClose** (``Boolean``) :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/include/clang/Format/Format.h b/clang/include/clang/Format/Format.h index 056fad2cc0ff8c..a8478060828072 100644 --- a/clang/include/clang/Format/Format.h +++ b/clang/include/clang/Format/Format.h @@ -2248,6 +2248,9 @@ struct FormatStyle { /// \version 16 BreakBeforeInlineASMColonStyle BreakBeforeInlineASMColon; + /// If ``true``, a line break will be placed before the ``>`` in a multiline template declaration. + bool BreakBeforeTemplateClose; + /// If ``true``, ternary operators will be placed after line breaks. /// \code ///true: @@ -5184,6 +5187,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..5887e9cef9011d 100644 --- a/clang/lib/Format/ContinuationIndenter.cpp +++ b/clang/lib/Format/ContinuationIndenter.cpp @@ -382,10 +382,28 @@ 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 +1297,10 @@ unsigned ContinuationIndenter::getNewLineColumn(const LineState &State) { FormatToken &Current = *State.NextToken; const auto &CurrentState = State.Stack.back(); + if (Current.ClosesTemplateDeclaration && Style.BreakBeforeTemplateClose) { +return 0; + } + if (CurrentState.IsCSharpGenericTypeConstraint && Current.isNot(TT_CSharpGenericTypeConstraint)) { return CurrentState.ColonPos + 2; diff --git a/clang/lib/Format/Format.cpp b/clang/lib/Format/Format.cpp index ee52972ce66f4a..a957129bbcf440 100644 --- a/clang/lib/Format/Format.cpp +++ b/clang/lib/Format/Format.cpp @@ -1000,6 +1000,8 @@ template <> struct MappingTraits { IO.mapOptional("BreakBeforeBraces", Style.BreakBeforeBraces); IO.mapOptional("BreakBeforeInlineASMColon", Style.BreakBeforeInlineASMColon); +IO.mapOptional("BreakBeforeTemplateClose", + Style.BreakBeforeTemplateClose); IO.mapOptional("BreakBeforeTernaryO
[clang] BreakBeforeTemplateClose (PR #118046)
https://github.com/leijurv updated https://github.com/llvm/llvm-project/pull/118046 >From b9886635c250fe765bf35c6b0e785f55b0749d52 Mon Sep 17 00:00:00 2001 From: Leijurv Date: Thu, 28 Nov 2024 21:44:50 -0600 Subject: [PATCH 1/3] BreakBeforeTemplateClose --- clang/docs/ClangFormatStyleOptions.rst | 23 ++ clang/include/clang/Format/Format.h| 4 clang/lib/Format/ContinuationIndenter.cpp | 22 + clang/lib/Format/Format.cpp| 2 ++ clang/unittests/Format/ConfigParseTest.cpp | 1 + clang/unittests/Format/FormatTest.cpp | 21 6 files changed, 73 insertions(+) diff --git a/clang/docs/ClangFormatStyleOptions.rst b/clang/docs/ClangFormatStyleOptions.rst index dc34094b5053a9..b40507b289049d 100644 --- a/clang/docs/ClangFormatStyleOptions.rst +++ b/clang/docs/ClangFormatStyleOptions.rst @@ -3416,6 +3416,29 @@ the configuration (without a prefix: ``Auto``). + +.. _BreakBeforeTemplateClose: + +**BreakBeforeTemplateClose** (``Boolean``) :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/include/clang/Format/Format.h b/clang/include/clang/Format/Format.h index 056fad2cc0ff8c..a8478060828072 100644 --- a/clang/include/clang/Format/Format.h +++ b/clang/include/clang/Format/Format.h @@ -2248,6 +2248,9 @@ struct FormatStyle { /// \version 16 BreakBeforeInlineASMColonStyle BreakBeforeInlineASMColon; + /// If ``true``, a line break will be placed before the ``>`` in a multiline template declaration. + bool BreakBeforeTemplateClose; + /// If ``true``, ternary operators will be placed after line breaks. /// \code ///true: @@ -5184,6 +5187,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..5887e9cef9011d 100644 --- a/clang/lib/Format/ContinuationIndenter.cpp +++ b/clang/lib/Format/ContinuationIndenter.cpp @@ -382,10 +382,28 @@ 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 +1297,10 @@ unsigned ContinuationIndenter::getNewLineColumn(const LineState &State) { FormatToken &Current = *State.NextToken; const auto &CurrentState = State.Stack.back(); + if (Current.ClosesTemplateDeclaration && Style.BreakBeforeTemplateClose) { +return 0; + } + if (CurrentState.IsCSharpGenericTypeConstraint && Current.isNot(TT_CSharpGenericTypeConstraint)) { return CurrentState.ColonPos + 2; diff --git a/clang/lib/Format/Format.cpp b/clang/lib/Format/Format.cpp index ee52972ce66f4a..a957129bbcf440 100644 --- a/clang/lib/Format/Format.cpp +++ b/clang/lib/Format/Format.cpp @@ -1000,6 +1000,8 @@ template <> struct MappingTraits { IO.mapOptional("BreakBeforeBraces", Style.BreakBeforeBraces); IO.mapOptional("BreakBeforeInlineASMColon", Style.BreakBeforeInlineASMColon); +IO.mapOptional("BreakBeforeTemplateClose", + Style.BreakBeforeTemplateClose); IO.mapOptional("BreakBeforeTernaryO
[clang] BreakBeforeTemplateClose (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] BreakBeforeTemplateClose (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] BreakBeforeTemplateClose (PR #118046)
https://github.com/leijurv updated https://github.com/llvm/llvm-project/pull/118046 >From b9886635c250fe765bf35c6b0e785f55b0749d52 Mon Sep 17 00:00:00 2001 From: Leijurv Date: Thu, 28 Nov 2024 21:44:50 -0600 Subject: [PATCH 1/2] BreakBeforeTemplateClose --- clang/docs/ClangFormatStyleOptions.rst | 23 ++ clang/include/clang/Format/Format.h| 4 clang/lib/Format/ContinuationIndenter.cpp | 22 + clang/lib/Format/Format.cpp| 2 ++ clang/unittests/Format/ConfigParseTest.cpp | 1 + clang/unittests/Format/FormatTest.cpp | 21 6 files changed, 73 insertions(+) diff --git a/clang/docs/ClangFormatStyleOptions.rst b/clang/docs/ClangFormatStyleOptions.rst index dc34094b5053a9..b40507b289049d 100644 --- a/clang/docs/ClangFormatStyleOptions.rst +++ b/clang/docs/ClangFormatStyleOptions.rst @@ -3416,6 +3416,29 @@ the configuration (without a prefix: ``Auto``). + +.. _BreakBeforeTemplateClose: + +**BreakBeforeTemplateClose** (``Boolean``) :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/include/clang/Format/Format.h b/clang/include/clang/Format/Format.h index 056fad2cc0ff8c..a8478060828072 100644 --- a/clang/include/clang/Format/Format.h +++ b/clang/include/clang/Format/Format.h @@ -2248,6 +2248,9 @@ struct FormatStyle { /// \version 16 BreakBeforeInlineASMColonStyle BreakBeforeInlineASMColon; + /// If ``true``, a line break will be placed before the ``>`` in a multiline template declaration. + bool BreakBeforeTemplateClose; + /// If ``true``, ternary operators will be placed after line breaks. /// \code ///true: @@ -5184,6 +5187,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..5887e9cef9011d 100644 --- a/clang/lib/Format/ContinuationIndenter.cpp +++ b/clang/lib/Format/ContinuationIndenter.cpp @@ -382,10 +382,28 @@ 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 +1297,10 @@ unsigned ContinuationIndenter::getNewLineColumn(const LineState &State) { FormatToken &Current = *State.NextToken; const auto &CurrentState = State.Stack.back(); + if (Current.ClosesTemplateDeclaration && Style.BreakBeforeTemplateClose) { +return 0; + } + if (CurrentState.IsCSharpGenericTypeConstraint && Current.isNot(TT_CSharpGenericTypeConstraint)) { return CurrentState.ColonPos + 2; diff --git a/clang/lib/Format/Format.cpp b/clang/lib/Format/Format.cpp index ee52972ce66f4a..a957129bbcf440 100644 --- a/clang/lib/Format/Format.cpp +++ b/clang/lib/Format/Format.cpp @@ -1000,6 +1000,8 @@ template <> struct MappingTraits { IO.mapOptional("BreakBeforeBraces", Style.BreakBeforeBraces); IO.mapOptional("BreakBeforeInlineASMColon", Style.BreakBeforeInlineASMColon); +IO.mapOptional("BreakBeforeTemplateClose", + Style.BreakBeforeTemplateClose); IO.mapOptional("BreakBeforeTernaryO
[clang] BreakBeforeTemplateClose (PR #118046)
github-actions[bot] wrote: Thank you for submitting a Pull Request (PR) to the LLVM Project! This PR will be automatically labeled and the relevant teams will be notified. If you wish to, you can add reviewers by using the "Reviewers" section on this page. If this is not working for you, it is probably because you do not have write permissions for the repository. In which case you can instead tag reviewers by name in a comment by using `@` followed by their GitHub username. If you have received no comments on your PR for a week, you can request a review by "ping"ing the PR by adding a comment “Ping”. The common courtesy "ping" rate is once a week. Please remember that you are asking for valuable time from other developers. If you have further questions, they may be answered by the [LLVM GitHub User Guide](https://llvm.org/docs/GitHub.html). You can also ask questions in a comment on this PR, on the [LLVM Discord](https://discord.com/invite/xS7Z362) or on the [forums](https://discourse.llvm.org/). 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] BreakBeforeTemplateClose (PR #118046)
https://github.com/leijurv created https://github.com/llvm/llvm-project/pull/118046 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 rubs me the wrong way and reminds me of this style of braces: ```c++ if (foo()) { bar();} ``` Most people agree this is better: ```c++ if (foo()) { bar(); } ``` >From b9886635c250fe765bf35c6b0e785f55b0749d52 Mon Sep 17 00:00:00 2001 From: Leijurv Date: Thu, 28 Nov 2024 21:44:50 -0600 Subject: [PATCH] BreakBeforeTemplateClose --- clang/docs/ClangFormatStyleOptions.rst | 23 ++ clang/include/clang/Format/Format.h| 4 clang/lib/Format/ContinuationIndenter.cpp | 22 + clang/lib/Format/Format.cpp| 2 ++ clang/unittests/Format/ConfigParseTest.cpp | 1 + clang/unittests/Format/FormatTest.cpp | 21 6 files changed, 73 insertions(+) diff --git a/clang/docs/ClangFormatStyleOptions.rst b/clang/docs/ClangFormatStyleOptions.rst index dc34094b5053a9..b40507b289049d 100644 --- a/clang/docs/ClangFormatStyleOptions.rst +++ b/clang/docs/ClangFormatStyleOptions.rst @@ -3416,6 +3416,29 @@ the configuration (without a prefix: ``Auto``). + +.. _BreakBeforeTemplateClose: + +**BreakBeforeTemplateClose** (``Boolean``) :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/include/clang/Format/Format.h b/clang/include/clang/Format/Format.h index 056fad2cc0ff8c..a8478060828072 100644 --- a/clang/include/clang/Format/Format.h +++ b/clang/include/clang/Format/Format.h @@ -2248,6 +2248,9 @@ struct FormatStyle { /// \version 16 BreakBeforeInlineASMColonStyle BreakBeforeInlineASMColon; + /// If ``true``, a line break will be placed before the ``>`` in a multiline template declaration. + bool BreakBeforeTemplateClose; + /// If ``true``, ternary operators will be placed after line breaks. /// \code ///true: @@ -5184,6 +5187,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..5887e9cef9011d 100644 --- a/clang/lib/Format/ContinuationIndenter.cpp +++ b/clang/lib/Format/ContinuationIndenter.cpp @@ -382,10 +382,28 @@ 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 +1297,10 @@ unsigned ContinuationIndenter::getNewLineColumn(const LineState &State) { FormatToken &Current = *State.NextToken; const auto &CurrentState = State.Stack.back(); + if (Current.ClosesTemplateDeclaration && Style.BreakBeforeTemplateClose) { +return 0; + } + if (CurrentState.IsCSharpGenericTypeConstraint && Current.isNot(TT_CSharpGenericTypeConstraint)) { return CurrentState.ColonPos + 2; diff --git