[clang] 1a0d0ae - [clang-format] Add `VariableTemplates` option (#121318)
via cfe-commits
cfe-commits at lists.llvm.org
Wed Jan 1 18:25:00 PST 2025
Author: Owen Pan
Date: 2025-01-01T18:24:56-08:00
New Revision: 1a0d0ae234544dc4978f1e12730408cb83f6b923
URL: https://github.com/llvm/llvm-project/commit/1a0d0ae234544dc4978f1e12730408cb83f6b923
DIFF: https://github.com/llvm/llvm-project/commit/1a0d0ae234544dc4978f1e12730408cb83f6b923.diff
LOG: [clang-format] Add `VariableTemplates` option (#121318)
Closes #120148.
Added:
Modified:
clang/docs/ClangFormatStyleOptions.rst
clang/docs/ReleaseNotes.rst
clang/include/clang/Format/Format.h
clang/lib/Format/Format.cpp
clang/lib/Format/FormatToken.h
clang/lib/Format/FormatTokenLexer.cpp
clang/lib/Format/FormatTokenLexer.h
clang/lib/Format/TokenAnnotator.cpp
clang/unittests/Format/TokenAnnotatorTest.cpp
Removed:
################################################################################
diff --git a/clang/docs/ClangFormatStyleOptions.rst b/clang/docs/ClangFormatStyleOptions.rst
index c175436a2817a9..d9b3f666df03c0 100644
--- a/clang/docs/ClangFormatStyleOptions.rst
+++ b/clang/docs/ClangFormatStyleOptions.rst
@@ -6798,6 +6798,15 @@ the configuration (without a prefix: ``Auto``).
+.. _VariableTemplates:
+
+**VariableTemplates** (``List of Strings``) :versionbadge:`clang-format 20` :ref:`¶ <VariableTemplates>`
+ A vector of non-keyword identifiers that should be interpreted as variable
+ template names.
+
+ A ``)`` after a variable template instantiation is **not** annotated as
+ the closing parenthesis of C-style cast operator.
+
.. _VerilogBreakBetweenInstancePorts:
**VerilogBreakBetweenInstancePorts** (``Boolean``) :versionbadge:`clang-format 17` :ref:`¶ <VerilogBreakBetweenInstancePorts>`
diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst
index 662c575bad3e8b..e0aef1af2135cd 100644
--- a/clang/docs/ReleaseNotes.rst
+++ b/clang/docs/ReleaseNotes.rst
@@ -1125,6 +1125,7 @@ clang-format
- Adds ``RemoveEmptyLinesInUnwrappedLines`` option.
- Adds ``KeepFormFeed`` option and set it to ``true`` for ``GNU`` style.
- Adds ``AllowShortNamespacesOnASingleLine`` option.
+- Adds ``VariableTemplates`` option.
- Adds support for bash globstar in ``.clang-format-ignore``.
libclang
diff --git a/clang/include/clang/Format/Format.h b/clang/include/clang/Format/Format.h
index eefaabf9392fd7..bb34f2d33ac15e 100644
--- a/clang/include/clang/Format/Format.h
+++ b/clang/include/clang/Format/Format.h
@@ -5103,6 +5103,15 @@ struct FormatStyle {
/// \version 3.7
UseTabStyle UseTab;
+ /// A vector of non-keyword identifiers that should be interpreted as variable
+ /// template names.
+ ///
+ /// A ``)`` after a variable template instantiation is **not** annotated as
+ /// the closing parenthesis of C-style cast operator.
+ ///
+ /// \version 20
+ std::vector<std::string> VariableTemplates;
+
/// For Verilog, put each port on its own line in module instantiations.
/// \code
/// true:
@@ -5314,7 +5323,7 @@ struct FormatStyle {
TableGenBreakInsideDAGArg == R.TableGenBreakInsideDAGArg &&
TabWidth == R.TabWidth && TemplateNames == R.TemplateNames &&
TypeNames == R.TypeNames && TypenameMacros == R.TypenameMacros &&
- UseTab == R.UseTab &&
+ UseTab == R.UseTab && VariableTemplates == R.VariableTemplates &&
VerilogBreakBetweenInstancePorts ==
R.VerilogBreakBetweenInstancePorts &&
WhitespaceSensitiveMacros == R.WhitespaceSensitiveMacros;
diff --git a/clang/lib/Format/Format.cpp b/clang/lib/Format/Format.cpp
index 8f44e9f00212cf..a5657f2d910f68 100644
--- a/clang/lib/Format/Format.cpp
+++ b/clang/lib/Format/Format.cpp
@@ -1166,6 +1166,7 @@ template <> struct MappingTraits<FormatStyle> {
IO.mapOptional("TypeNames", Style.TypeNames);
IO.mapOptional("TypenameMacros", Style.TypenameMacros);
IO.mapOptional("UseTab", Style.UseTab);
+ IO.mapOptional("VariableTemplates", Style.VariableTemplates);
IO.mapOptional("VerilogBreakBetweenInstancePorts",
Style.VerilogBreakBetweenInstancePorts);
IO.mapOptional("WhitespaceSensitiveMacros",
diff --git a/clang/lib/Format/FormatToken.h b/clang/lib/Format/FormatToken.h
index f6bb860a1fea31..8917049cefb865 100644
--- a/clang/lib/Format/FormatToken.h
+++ b/clang/lib/Format/FormatToken.h
@@ -186,6 +186,7 @@ namespace format {
TYPE(UnionLBrace) \
TYPE(UnionRBrace) \
TYPE(UntouchableMacroFunc) \
+ TYPE(VariableTemplate) \
/* Like in 'assign x = 0, y = 1;' . */ \
TYPE(VerilogAssignComma) \
/* like in begin : block */ \
diff --git a/clang/lib/Format/FormatTokenLexer.cpp b/clang/lib/Format/FormatTokenLexer.cpp
index 7a264bddcdfe19..0f8d4940d4369a 100644
--- a/clang/lib/Format/FormatTokenLexer.cpp
+++ b/clang/lib/Format/FormatTokenLexer.cpp
@@ -76,6 +76,8 @@ FormatTokenLexer::FormatTokenLexer(
TemplateNames.insert(&IdentTable.get(TemplateName));
for (const auto &TypeName : Style.TypeNames)
TypeNames.insert(&IdentTable.get(TypeName));
+ for (const auto &VariableTemplate : Style.VariableTemplates)
+ VariableTemplates.insert(&IdentTable.get(VariableTemplate));
}
ArrayRef<FormatToken *> FormatTokenLexer::lex() {
@@ -1382,6 +1384,8 @@ FormatToken *FormatTokenLexer::getNextToken() {
FormatTok->setFinalizedType(TT_TemplateName);
else if (TypeNames.contains(Identifier))
FormatTok->setFinalizedType(TT_TypeName);
+ else if (VariableTemplates.contains(Identifier))
+ FormatTok->setFinalizedType(TT_VariableTemplate);
}
}
diff --git a/clang/lib/Format/FormatTokenLexer.h b/clang/lib/Format/FormatTokenLexer.h
index 71389d2ade2b73..61474a3f9ada8c 100644
--- a/clang/lib/Format/FormatTokenLexer.h
+++ b/clang/lib/Format/FormatTokenLexer.h
@@ -129,7 +129,8 @@ class FormatTokenLexer {
llvm::SmallMapVector<IdentifierInfo *, TokenType, 8> Macros;
- llvm::SmallPtrSet<IdentifierInfo *, 8> TemplateNames, TypeNames;
+ llvm::SmallPtrSet<IdentifierInfo *, 8> TemplateNames, TypeNames,
+ VariableTemplates;
bool FormattingDisabled;
diff --git a/clang/lib/Format/TokenAnnotator.cpp b/clang/lib/Format/TokenAnnotator.cpp
index f2cfa7f49f62f9..b0f570966a63f3 100644
--- a/clang/lib/Format/TokenAnnotator.cpp
+++ b/clang/lib/Format/TokenAnnotator.cpp
@@ -2792,6 +2792,16 @@ class AnnotatingParser {
return true;
}
+ auto IsNonVariableTemplate = [](const FormatToken &Tok) {
+ if (Tok.isNot(TT_TemplateCloser))
+ return false;
+ const auto *Less = Tok.MatchingParen;
+ if (!Less)
+ return false;
+ const auto *BeforeLess = Less->getPreviousNonComment();
+ return BeforeLess && BeforeLess->isNot(TT_VariableTemplate);
+ };
+
// Heuristically try to determine whether the parentheses contain a type.
auto IsQualifiedPointerOrReference = [](const FormatToken *T,
const LangOptions &LangOpts) {
@@ -2825,10 +2835,11 @@ class AnnotatingParser {
}
return T && T->is(TT_PointerOrReference);
};
- bool ParensAreType =
- BeforeRParen->isOneOf(TT_TemplateCloser, TT_TypeDeclarationParen) ||
- BeforeRParen->isTypeName(LangOpts) ||
- IsQualifiedPointerOrReference(BeforeRParen, LangOpts);
+
+ bool ParensAreType = IsNonVariableTemplate(*BeforeRParen) ||
+ BeforeRParen->is(TT_TypeDeclarationParen) ||
+ BeforeRParen->isTypeName(LangOpts) ||
+ IsQualifiedPointerOrReference(BeforeRParen, LangOpts);
bool ParensCouldEndDecl =
AfterRParen->isOneOf(tok::equal, tok::semi, tok::l_brace, tok::greater);
if (ParensAreType && !ParensCouldEndDecl)
diff --git a/clang/unittests/Format/TokenAnnotatorTest.cpp b/clang/unittests/Format/TokenAnnotatorTest.cpp
index b2fb5227993c3f..d61b9adf4f58c6 100644
--- a/clang/unittests/Format/TokenAnnotatorTest.cpp
+++ b/clang/unittests/Format/TokenAnnotatorTest.cpp
@@ -3615,6 +3615,19 @@ TEST_F(TokenAnnotatorTest, TemplateInstantiation) {
EXPECT_TOKEN(Tokens[18], tok::greater, TT_TemplateCloser);
}
+TEST_F(TokenAnnotatorTest, VariableTemplate) {
+ auto Style = getLLVMStyle();
+ Style.VariableTemplates.push_back("a");
+
+ auto Tokens = annotate("auto t3 = (a<int>) + b;", Style);
+ ASSERT_EQ(Tokens.size(), 13u) << Tokens;
+ EXPECT_TOKEN(Tokens[4], tok::identifier, TT_VariableTemplate);
+ EXPECT_TOKEN(Tokens[5], tok::less, TT_TemplateOpener);
+ EXPECT_TOKEN(Tokens[7], tok::greater, TT_TemplateCloser);
+ EXPECT_TOKEN(Tokens[8], tok::r_paren, TT_Unknown); // Not TT_CastRParen
+ EXPECT_TOKEN(Tokens[9], tok::plus, TT_BinaryOperator);
+}
+
TEST_F(TokenAnnotatorTest, SwitchInMacroArgument) {
auto Tokens = annotate("FOOBAR(switch);\n"
"void f() {}");
More information about the cfe-commits
mailing list