summaryrefslogtreecommitdiffstats
path: root/clang
diff options
context:
space:
mode:
Diffstat (limited to 'clang')
-rw-r--r--clang/docs/LibASTMatchersReference.html24
-rw-r--r--clang/include/clang/AST/ASTTypeTraits.h6
-rw-r--r--clang/include/clang/ASTMatchers/ASTMatchers.h29
-rw-r--r--clang/lib/AST/ASTTypeTraits.cpp3
-rw-r--r--clang/lib/ASTMatchers/Dynamic/Registry.cpp1
-rw-r--r--clang/unittests/ASTMatchers/ASTMatchersTraversalTest.cpp8
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&lt;<a href="http://clang.llvm.org/doxygen/classclang_1_1TemplateName.html">TemplateName</a>&gt;</td><td class="name" onclick="toggle('templateName0')"><a name="templateName0Anchor">templateName</a></td><td>Matcher&lt;<a href="http://clang.llvm.org/doxygen/classclang_1_1TemplateName.html">TemplateName</a>&gt;...</td></tr>
+<tr><td colspan="4" class="doc" id="templateName0"><pre>Matches template name.
+
+Given
+ template &lt;typename T&gt; class X { };
+ X&lt;int&gt; xi;
+templateName()
+ matches 'X' in X&lt;int&gt;.
+</pre></td></tr>
+
+
<tr><td>Matcher&lt;<a href="http://clang.llvm.org/doxygen/classclang_1_1TypeLoc.html">TypeLoc</a>&gt;</td><td class="name" onclick="toggle('typeLoc0')"><a name="typeLoc0Anchor">typeLoc</a></td><td>Matcher&lt;<a href="http://clang.llvm.org/doxygen/classclang_1_1TypeLoc.html">TypeLoc</a>&gt;...</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&lt;<a href="http://clang.llvm.org/doxygen/classclang_1_1TemplateArgument.html">TemplateArgument</a>&gt;</td><td class="name" onclick="toggle('refersToTemplate0')"><a name="refersToTemplate0Anchor">refersToTemplate</a></td><td>Matcher&lt;<a href="http://clang.llvm.org/doxygen/classclang_1_1TemplateName.html">TemplateName</a>&gt; InnerMatcher</td></tr>
+<tr><td colspan="4" class="doc" id="refersToTemplate0"><pre>Matches a TemplateArgument that refers to a certain template.
+
+Given
+ template&lt;template &lt;typename&gt; class S&gt; class X {};
+ template&lt;typename T&gt; class Y {};"
+ X&lt;Y&gt; xi;
+classTemplateSpecializationDecl(hasAnyTemplateArgument(
+ refersToTemplate(templateName())))
+ matches the specialization X&lt;Y&gt;
+</pre></td></tr>
+
+
<tr><td>Matcher&lt;<a href="http://clang.llvm.org/doxygen/classclang_1_1TemplateArgument.html">TemplateArgument</a>&gt;</td><td class="name" onclick="toggle('refersToType0')"><a name="refersToType0Anchor">refersToType</a></td><td>Matcher&lt;<a href="http://clang.llvm.org/doxygen/classclang_1_1QualType.html">QualType</a>&gt; 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; };"
OpenPOWER on IntegriCloud