[clang] [clang-format] Don't count template template parameter as declaration (PR #95025)
via cfe-commits
cfe-commits at lists.llvm.org
Mon Jun 10 12:20:30 PDT 2024
llvmbot wrote:
<!--LLVM PR SUMMARY COMMENT-->
@llvm/pr-subscribers-clang-format
Author: Emilia Kond (rymiel)
<details>
<summary>Changes</summary>
In ContinuationIndenter::mustBreak, a break is required between a template declaration and the function/class declaration it applies to, if the template declaration spans multiple lines.
However, this also includes template template parameters, which can cause extra erroneous line breaks in some declarations.
This patch makes template template parameters not be counted as template declarations.
Fixes https://github.com/llvm/llvm-project/issues/93793
---
Full diff: https://github.com/llvm/llvm-project/pull/95025.diff
2 Files Affected:
- (modified) clang/lib/Format/TokenAnnotator.cpp (+12-3)
- (modified) clang/unittests/Format/TokenAnnotatorTest.cpp (+17)
``````````diff
diff --git a/clang/lib/Format/TokenAnnotator.cpp b/clang/lib/Format/TokenAnnotator.cpp
index 1fe3b61a5a81f..9ed25d3e4c7ee 100644
--- a/clang/lib/Format/TokenAnnotator.cpp
+++ b/clang/lib/Format/TokenAnnotator.cpp
@@ -127,7 +127,7 @@ class AnnotatingParser {
SmallVector<ScopeType> &Scopes)
: Style(Style), Line(Line), CurrentToken(Line.First), AutoFound(false),
IsCpp(Style.isCpp()), LangOpts(getFormattingLangOpts(Style)),
- Keywords(Keywords), Scopes(Scopes) {
+ Keywords(Keywords), Scopes(Scopes), TemplateDeclarationDepth(0) {
assert(IsCpp == LangOpts.CXXOperatorNames);
Contexts.push_back(Context(tok::unknown, 1, /*IsExpression=*/false));
resetTokenMetadata();
@@ -1269,10 +1269,17 @@ class AnnotatingParser {
if (CurrentToken && CurrentToken->is(tok::less)) {
CurrentToken->setType(TT_TemplateOpener);
next();
- if (!parseAngle())
+ TemplateDeclarationDepth++;
+ if (!parseAngle()) {
+ TemplateDeclarationDepth--;
return false;
- if (CurrentToken)
+ }
+ TemplateDeclarationDepth--;
+ if (CurrentToken &&
+ !(TemplateDeclarationDepth > 0 &&
+ CurrentToken->isOneOf(tok::kw_typename, tok::kw_class))) {
CurrentToken->Previous->ClosesTemplateDeclaration = true;
+ }
return true;
}
return false;
@@ -3073,6 +3080,8 @@ class AnnotatingParser {
// same decision irrespective of the decisions for tokens leading up to it.
// Store this information to prevent this from causing exponential runtime.
llvm::SmallPtrSet<FormatToken *, 16> NonTemplateLess;
+
+ int TemplateDeclarationDepth;
};
static const int PrecedenceUnaryOperator = prec::PointerToMember + 1;
diff --git a/clang/unittests/Format/TokenAnnotatorTest.cpp b/clang/unittests/Format/TokenAnnotatorTest.cpp
index 8cc5c239d30a1..82de72ddeeaa1 100644
--- a/clang/unittests/Format/TokenAnnotatorTest.cpp
+++ b/clang/unittests/Format/TokenAnnotatorTest.cpp
@@ -584,6 +584,23 @@ TEST_F(TokenAnnotatorTest, UnderstandsNonTemplateAngleBrackets) {
EXPECT_TOKEN(Tokens[20], tok::greater, TT_BinaryOperator);
}
+TEST_F(TokenAnnotatorTest, UnderstandsTemplateTemplateParameters) {
+ auto Tokens = annotate("template <template <typename...> typename X,\n"
+ " template <typename...> typename Y,\n"
+ " typename... T>\n"
+ "class A {};");
+ ASSERT_EQ(Tokens.size(), 28u) << Tokens;
+ EXPECT_TOKEN(Tokens[1], tok::less, TT_TemplateOpener);
+ EXPECT_TOKEN(Tokens[3], tok::less, TT_TemplateOpener);
+ EXPECT_TOKEN(Tokens[6], tok::greater, TT_TemplateCloser);
+ EXPECT_EQ(Tokens[6]->ClosesTemplateDeclaration, 0u);
+ EXPECT_TOKEN(Tokens[11], tok::less, TT_TemplateOpener);
+ EXPECT_TOKEN(Tokens[14], tok::greater, TT_TemplateCloser);
+ EXPECT_EQ(Tokens[14]->ClosesTemplateDeclaration, 0u);
+ EXPECT_TOKEN(Tokens[21], tok::greater, TT_TemplateCloser);
+ EXPECT_EQ(Tokens[21]->ClosesTemplateDeclaration, 1u);
+}
+
TEST_F(TokenAnnotatorTest, UnderstandsWhitespaceSensitiveMacros) {
FormatStyle Style = getLLVMStyle();
Style.WhitespaceSensitiveMacros.push_back("FOO");
``````````
</details>
https://github.com/llvm/llvm-project/pull/95025
More information about the cfe-commits
mailing list