Index: docs/LibASTMatchersReference.html =================================================================== --- docs/LibASTMatchersReference.html +++ docs/LibASTMatchersReference.html @@ -1318,6 +1318,17 @@ +
Matches template name.
+
+Given
+ template <typename T> class X { };
+ X<int> xi;
+templateName()
+ matches 'X' in X<int>.
+Matches TypeLocs in the clang AST.
Matches a TemplateArgument that refers to a certain template.
+
+Given
+ template<template <typename> class S> class X {};
+ template<typename T> class Y {};"
+ X<Y> xi;
+classTemplateSpecializationDecl(hasAnyTemplateArgument(
+ refersToTemplate(templateName())))
+ matches the specialization X<Y>
+Matches a TemplateArgument that refers to a certain type.
Index: include/clang/AST/ASTTypeTraits.h
===================================================================
--- include/clang/AST/ASTTypeTraits.h
+++ include/clang/AST/ASTTypeTraits.h
@@ -121,6 +121,7 @@
enum NodeKindId {
NKI_None,
NKI_TemplateArgument,
+ NKI_TemplateName,
NKI_NestedNameSpecifierLoc,
NKI_QualType,
NKI_TypeLoc,
@@ -175,6 +176,7 @@
};
KIND_TO_KIND_ID(CXXCtorInitializer)
KIND_TO_KIND_ID(TemplateArgument)
+KIND_TO_KIND_ID(TemplateName)
KIND_TO_KIND_ID(NestedNameSpecifier)
KIND_TO_KIND_ID(NestedNameSpecifierLoc)
KIND_TO_KIND_ID(QualType)
@@ -472,6 +474,10 @@
template <>
struct DynTypedNode::BaseConverter<
+ TemplateName, void> : public ValueConverter {};
+
+template <>
+struct DynTypedNode::BaseConverter<
NestedNameSpecifierLoc,
void> : public ValueConverter {};
Index: include/clang/ASTMatchers/ASTMatchers.h
===================================================================
--- include/clang/ASTMatchers/ASTMatchers.h
+++ include/clang/ASTMatchers/ASTMatchers.h
@@ -446,6 +446,17 @@
/// matches 'int' in C.
const internal::VariadicAllOfMatcher templateArgument;
+/// \brief Matches template name.
+///
+/// Given
+/// \code
+/// template class X { };
+/// X xi;
+/// \endcode
+/// templateName()
+/// matches 'X' in X.
+const internal::VariadicAllOfMatcher templateName;
+
/// \brief Matches non-type template parameter declarations.
///
/// Given
@@ -774,6 +785,24 @@
return InnerMatcher.matches(Node.getAsType(), Finder, Builder);
}
+/// \brief Matches a TemplateArgument that refers to a certain template.
+///
+/// Given
+/// \code
+/// template class S> class X {};
+/// template class Y {};"
+/// X xi;
+/// \endcode
+/// classTemplateSpecializationDecl(hasAnyTemplateArgument(
+/// refersToTemplate(templateName())))
+/// matches the specialization \c X
+AST_MATCHER_P(TemplateArgument, refersToTemplate,
+ internal::Matcher, InnerMatcher) {
+ if (Node.getKind() != TemplateArgument::Template)
+ return false;
+ return InnerMatcher.matches(Node.getAsTemplate(), Finder, Builder);
+}
+
/// \brief Matches a canonical TemplateArgument that refers to a certain
/// declaration.
///
Index: lib/AST/ASTTypeTraits.cpp
===================================================================
--- lib/AST/ASTTypeTraits.cpp
+++ lib/AST/ASTTypeTraits.cpp
@@ -23,6 +23,7 @@
const ASTNodeKind::KindInfo ASTNodeKind::AllKindInfo[] = {
{ NKI_None, "" },
{ NKI_None, "TemplateArgument" },
+ { NKI_None, "TemplateName" },
{ NKI_None, "NestedNameSpecifierLoc" },
{ NKI_None, "QualType" },
{ NKI_None, "TypeLoc" },
@@ -109,6 +110,8 @@
const PrintingPolicy &PP) const {
if (const TemplateArgument *TA = get())
TA->print(PP, OS);
+ else if (const TemplateName *TN = get())
+ TN->print(OS, PP);
else if (const NestedNameSpecifier *NNS = get())
NNS->print(OS, PP);
else if (const NestedNameSpecifierLoc *NNSL = get())
Index: lib/ASTMatchers/Dynamic/Registry.cpp
===================================================================
--- lib/ASTMatchers/Dynamic/Registry.cpp
+++ lib/ASTMatchers/Dynamic/Registry.cpp
@@ -391,6 +391,7 @@
REGISTER_MATCHER(switchCase);
REGISTER_MATCHER(switchStmt);
REGISTER_MATCHER(templateArgument);
+ REGISTER_MATCHER(templateName);
REGISTER_MATCHER(templateArgumentCountIs);
REGISTER_MATCHER(templateSpecializationType);
REGISTER_MATCHER(templateTypeParmType);
Index: unittests/ASTMatchers/ASTMatchersTraversalTest.cpp
===================================================================
--- unittests/ASTMatchers/ASTMatchersTraversalTest.cpp
+++ unittests/ASTMatchers/ASTMatchersTraversalTest.cpp
@@ -543,6 +543,15 @@
asString("int"))))));
}
+TEST(Matcher, MatchesTemplateTemplateArgument) {
+ EXPECT_TRUE(matches(
+ "template class S> class X {};"
+ "template class Y {};"
+ "X xi;",
+ classTemplateSpecializationDecl(hasAnyTemplateArgument(
+ refersToTemplate(templateName())))));
+}
+
TEST(Matcher, MatchesDeclarationReferenceTemplateArgument) {
EXPECT_TRUE(matches(
"struct B { int next; };"