diff options
Diffstat (limited to 'clang')
-rw-r--r-- | clang/docs/LibASTMatchersReference.html | 24 | ||||
-rw-r--r-- | clang/include/clang/AST/ASTTypeTraits.h | 6 | ||||
-rw-r--r-- | clang/include/clang/ASTMatchers/ASTMatchers.h | 29 | ||||
-rw-r--r-- | clang/lib/AST/ASTTypeTraits.cpp | 3 | ||||
-rw-r--r-- | clang/lib/ASTMatchers/Dynamic/Registry.cpp | 1 | ||||
-rw-r--r-- | clang/unittests/ASTMatchers/ASTMatchersTraversalTest.cpp | 8 |
6 files changed, 71 insertions, 0 deletions
diff --git a/clang/docs/LibASTMatchersReference.html b/clang/docs/LibASTMatchersReference.html index 222b39fcf5c..cb6a05e3e91 100644 --- a/clang/docs/LibASTMatchersReference.html +++ b/clang/docs/LibASTMatchersReference.html @@ -1318,6 +1318,17 @@ templateArgument() </pre></td></tr> +<tr><td>Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1TemplateName.html">TemplateName</a>></td><td class="name" onclick="toggle('templateName0')"><a name="templateName0Anchor">templateName</a></td><td>Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1TemplateName.html">TemplateName</a>>...</td></tr> +<tr><td colspan="4" class="doc" id="templateName0"><pre>Matches template name. + +Given + template <typename T> class X { }; + X<int> xi; +templateName() + matches 'X' in X<int>. +</pre></td></tr> + + <tr><td>Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1TypeLoc.html">TypeLoc</a>></td><td class="name" onclick="toggle('typeLoc0')"><a name="typeLoc0Anchor">typeLoc</a></td><td>Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1TypeLoc.html">TypeLoc</a>>...</td></tr> <tr><td colspan="4" class="doc" id="typeLoc0"><pre>Matches TypeLocs in the clang AST. </pre></td></tr> @@ -5353,6 +5364,19 @@ classTemplateSpecializationDecl( </pre></td></tr> +<tr><td>Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1TemplateArgument.html">TemplateArgument</a>></td><td class="name" onclick="toggle('refersToTemplate0')"><a name="refersToTemplate0Anchor">refersToTemplate</a></td><td>Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1TemplateName.html">TemplateName</a>> InnerMatcher</td></tr> +<tr><td colspan="4" class="doc" id="refersToTemplate0"><pre>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> +</pre></td></tr> + + <tr><td>Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1TemplateArgument.html">TemplateArgument</a>></td><td class="name" onclick="toggle('refersToType0')"><a name="refersToType0Anchor">refersToType</a></td><td>Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1QualType.html">QualType</a>> InnerMatcher</td></tr> <tr><td colspan="4" class="doc" id="refersToType0"><pre>Matches a TemplateArgument that refers to a certain type. diff --git a/clang/include/clang/AST/ASTTypeTraits.h b/clang/include/clang/AST/ASTTypeTraits.h index ad301b14829..51d60a90a14 100644 --- a/clang/include/clang/AST/ASTTypeTraits.h +++ b/clang/include/clang/AST/ASTTypeTraits.h @@ -121,6 +121,7 @@ private: enum NodeKindId { NKI_None, NKI_TemplateArgument, + NKI_TemplateName, NKI_NestedNameSpecifierLoc, NKI_QualType, NKI_TypeLoc, @@ -175,6 +176,7 @@ private: }; 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 @@ struct DynTypedNode::BaseConverter< template <> struct DynTypedNode::BaseConverter< + TemplateName, void> : public ValueConverter<TemplateName> {}; + +template <> +struct DynTypedNode::BaseConverter< NestedNameSpecifierLoc, void> : public ValueConverter<NestedNameSpecifierLoc> {}; diff --git a/clang/include/clang/ASTMatchers/ASTMatchers.h b/clang/include/clang/ASTMatchers/ASTMatchers.h index 6f59b825202..4e7e721c91a 100644 --- a/clang/include/clang/ASTMatchers/ASTMatchers.h +++ b/clang/include/clang/ASTMatchers/ASTMatchers.h @@ -446,6 +446,17 @@ const internal::VariadicAllOfMatcher<CXXCtorInitializer> cxxCtorInitializer; /// matches 'int' in C<int>. const internal::VariadicAllOfMatcher<TemplateArgument> templateArgument; +/// \brief Matches template name. +/// +/// Given +/// \code +/// template <typename T> class X { }; +/// X<int> xi; +/// \endcode +/// templateName() +/// matches 'X' in X<int>. +const internal::VariadicAllOfMatcher<TemplateName> templateName; + /// \brief Matches non-type template parameter declarations. /// /// Given @@ -774,6 +785,24 @@ AST_MATCHER_P(TemplateArgument, refersToType, return InnerMatcher.matches(Node.getAsType(), Finder, Builder); } +/// \brief Matches a TemplateArgument that refers to a certain template. +/// +/// Given +/// \code +/// template<template <typename> class S> class X {}; +/// template<typename T> class Y {};" +/// X<Y> xi; +/// \endcode +/// classTemplateSpecializationDecl(hasAnyTemplateArgument( +/// refersToTemplate(templateName()))) +/// matches the specialization \c X<Y> +AST_MATCHER_P(TemplateArgument, refersToTemplate, + internal::Matcher<TemplateName>, 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. /// diff --git a/clang/lib/AST/ASTTypeTraits.cpp b/clang/lib/AST/ASTTypeTraits.cpp index 2336c98fe04..680f526f00d 100644 --- a/clang/lib/AST/ASTTypeTraits.cpp +++ b/clang/lib/AST/ASTTypeTraits.cpp @@ -23,6 +23,7 @@ namespace ast_type_traits { const ASTNodeKind::KindInfo ASTNodeKind::AllKindInfo[] = { { NKI_None, "<None>" }, { NKI_None, "TemplateArgument" }, + { NKI_None, "TemplateName" }, { NKI_None, "NestedNameSpecifierLoc" }, { NKI_None, "QualType" }, { NKI_None, "TypeLoc" }, @@ -109,6 +110,8 @@ void DynTypedNode::print(llvm::raw_ostream &OS, const PrintingPolicy &PP) const { if (const TemplateArgument *TA = get<TemplateArgument>()) TA->print(PP, OS); + else if (const TemplateName *TN = get<TemplateName>()) + TN->print(OS, PP); else if (const NestedNameSpecifier *NNS = get<NestedNameSpecifier>()) NNS->print(OS, PP); else if (const NestedNameSpecifierLoc *NNSL = get<NestedNameSpecifierLoc>()) diff --git a/clang/lib/ASTMatchers/Dynamic/Registry.cpp b/clang/lib/ASTMatchers/Dynamic/Registry.cpp index a8d4b88d858..24ff30cd7bc 100644 --- a/clang/lib/ASTMatchers/Dynamic/Registry.cpp +++ b/clang/lib/ASTMatchers/Dynamic/Registry.cpp @@ -391,6 +391,7 @@ RegistryMaps::RegistryMaps() { REGISTER_MATCHER(switchCase); REGISTER_MATCHER(switchStmt); REGISTER_MATCHER(templateArgument); + REGISTER_MATCHER(templateName); REGISTER_MATCHER(templateArgumentCountIs); REGISTER_MATCHER(templateSpecializationType); REGISTER_MATCHER(templateTypeParmType); diff --git a/clang/unittests/ASTMatchers/ASTMatchersTraversalTest.cpp b/clang/unittests/ASTMatchers/ASTMatchersTraversalTest.cpp index 7c496647b4c..41d588f122b 100644 --- a/clang/unittests/ASTMatchers/ASTMatchersTraversalTest.cpp +++ b/clang/unittests/ASTMatchers/ASTMatchersTraversalTest.cpp @@ -543,6 +543,14 @@ TEST(Matcher, MatchesTypeTemplateArgument) { asString("int")))))); } +TEST(Matcher, MatchesTemplateTemplateArgument) { + EXPECT_TRUE(matches("template<template <typename> class S> class X {};" + "template<typename T> class Y {};" + "X<Y> xi;", + classTemplateSpecializationDecl(hasAnyTemplateArgument( + refersToTemplate(templateName()))))); +} + TEST(Matcher, MatchesDeclarationReferenceTemplateArgument) { EXPECT_TRUE(matches( "struct B { int next; };" |