aboutsummaryrefslogtreecommitdiff
path: root/clang/lib/Format/ContinuationIndenter.cpp
diff options
context:
space:
mode:
authorleijurv <leijurv@gmail.com>2025-02-06 01:15:47 -0800
committerGitHub <noreply@github.com>2025-02-06 01:15:47 -0800
commitd2b45ce100d641a8f1690e30843bb9c5ea71ab86 (patch)
treece6d7d8789e85d82656f19a99116801a58dcc2ac /clang/lib/Format/ContinuationIndenter.cpp
parent7ef33e609c45515de9db1b5222fe6e05edd76c94 (diff)
downloadllvm-d2b45ce100d641a8f1690e30843bb9c5ea71ab86.zip
llvm-d2b45ce100d641a8f1690e30843bb9c5ea71ab86.tar.gz
llvm-d2b45ce100d641a8f1690e30843bb9c5ea71ab86.tar.bz2
[clang-format] Add BreakBeforeTemplateCloser option (#118046)
In clang-format, multiline templates have the `>` on the same line as the last parameter: ```c++ template < typename Foo, typename Bar> void foo() { ``` I would like to add an option to put the `>` on the next line, like this: ```c++ template < typename Foo, typename Bar > void foo() { ``` An example of a large project that uses this style is NVIDIA's CUTLASS, here is an example: https://github.com/NVIDIA/cutlass/blob/main/include/cutlass/epilogue/dispatch_policy.hpp#L149-L156 My reasoning is that it reminds me of this style of braces: ```c++ if (foo()) { bar(); baz();} ``` Most people agree this is better: ```c++ if (foo()) { bar(); baz(); } ``` --------- Co-authored-by: Owen Pan <owenpiano@gmail.com>
Diffstat (limited to 'clang/lib/Format/ContinuationIndenter.cpp')
-rw-r--r--clang/lib/Format/ContinuationIndenter.cpp24
1 files changed, 18 insertions, 6 deletions
diff --git a/clang/lib/Format/ContinuationIndenter.cpp b/clang/lib/Format/ContinuationIndenter.cpp
index 6f7d213..3e51b4aa 100644
--- a/clang/lib/Format/ContinuationIndenter.cpp
+++ b/clang/lib/Format/ContinuationIndenter.cpp
@@ -349,6 +349,13 @@ bool ContinuationIndenter::canBreak(const LineState &State) {
}
}
+ // Don't allow breaking before a closing brace of a block-indented braced list
+ // initializer if there isn't already a break.
+ if (Current.is(tok::r_brace) && Current.MatchingParen &&
+ Current.isBlockIndentedInitRBrace(Style)) {
+ return CurrentState.BreakBeforeClosingBrace;
+ }
+
// Allow breaking before the right parens with block indentation if there was
// a break after the left parens, which is tracked by BreakBeforeClosingParen.
if (Style.AlignAfterOpenBracket == FormatStyle::BAS_BlockIndent &&
@@ -356,12 +363,8 @@ bool ContinuationIndenter::canBreak(const LineState &State) {
return CurrentState.BreakBeforeClosingParen;
}
- // Don't allow breaking before a closing brace of a block-indented braced list
- // initializer if there isn't already a break.
- if (Current.is(tok::r_brace) && Current.MatchingParen &&
- Current.isBlockIndentedInitRBrace(Style)) {
- return CurrentState.BreakBeforeClosingBrace;
- }
+ if (Style.BreakBeforeTemplateCloser && Current.is(TT_TemplateCloser))
+ return CurrentState.BreakBeforeClosingAngle;
// If binary operators are moved to the next line (including commas for some
// styles of constructor initializers), that's always ok.
@@ -414,6 +417,8 @@ bool ContinuationIndenter::mustBreak(const LineState &State) {
}
if (CurrentState.BreakBeforeClosingParen && Current.is(tok::r_paren))
return true;
+ if (CurrentState.BreakBeforeClosingAngle && Current.is(TT_TemplateCloser))
+ return true;
if (Style.Language == FormatStyle::LK_ObjC &&
Style.ObjCBreakBeforeNestedBlockParam &&
Current.ObjCSelectorNameParts > 1 &&
@@ -1243,6 +1248,9 @@ unsigned ContinuationIndenter::addTokenOnNewLine(LineState &State,
Style.AlignAfterOpenBracket == FormatStyle::BAS_BlockIndent;
}
+ if (PreviousNonComment && PreviousNonComment->is(TT_TemplateOpener))
+ CurrentState.BreakBeforeClosingAngle = Style.BreakBeforeTemplateCloser;
+
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
@@ -1379,6 +1387,10 @@ unsigned ContinuationIndenter::getNewLineColumn(const LineState &State) {
State.Stack.size() > 1) {
return State.Stack[State.Stack.size() - 2].LastSpace;
}
+ if (Style.BreakBeforeTemplateCloser && Current.is(TT_TemplateCloser) &&
+ State.Stack.size() > 1) {
+ return State.Stack[State.Stack.size() - 2].LastSpace;
+ }
if (NextNonComment->is(TT_TemplateString) && NextNonComment->closesScope())
return State.Stack[State.Stack.size() - 2].LastSpace;
// Field labels in a nested type should be aligned to the brace. For example