[clang] [clang-format] Don't count template template parameter as declaration (PR #95025)
Emilia Kond via cfe-commits
cfe-commits at lists.llvm.org
Mon Jun 10 12:20:07 PDT 2024
https://github.com/rymiel created https://github.com/llvm/llvm-project/pull/95025
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
>From 6fc09d022a0e4e395a1b8e17166641dffc7c12eb Mon Sep 17 00:00:00 2001
From: Emilia Kond <emilia at rymiel.space>
Date: Mon, 10 Jun 2024 22:17:29 +0300
Subject: [PATCH] [clang-format] Don't count template template parameter as
declaration
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
---
clang/lib/Format/TokenAnnotator.cpp | 15 ++++++++++++---
clang/unittests/Format/TokenAnnotatorTest.cpp | 17 +++++++++++++++++
2 files changed, 29 insertions(+), 3 deletions(-)
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");
More information about the cfe-commits
mailing list