diff options
author | leijurv <leijurv@gmail.com> | 2025-02-06 01:15:47 -0800 |
---|---|---|
committer | GitHub <noreply@github.com> | 2025-02-06 01:15:47 -0800 |
commit | d2b45ce100d641a8f1690e30843bb9c5ea71ab86 (patch) | |
tree | ce6d7d8789e85d82656f19a99116801a58dcc2ac /clang/lib/Format/ContinuationIndenter.cpp | |
parent | 7ef33e609c45515de9db1b5222fe6e05edd76c94 (diff) | |
download | llvm-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.cpp | 24 |
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 |