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; };"