summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--clang/docs/LibASTMatchersReference.html86
-rw-r--r--clang/include/clang/ASTMatchers/ASTMatchers.h29
-rw-r--r--clang/include/clang/ASTMatchers/ASTMatchersInternal.h7
-rw-r--r--clang/unittests/ASTMatchers/ASTMatchersTraversalTest.cpp13
4 files changed, 121 insertions, 14 deletions
diff --git a/clang/docs/LibASTMatchersReference.html b/clang/docs/LibASTMatchersReference.html
index 70c83ea5cca..222b39fcf5c 100644
--- a/clang/docs/LibASTMatchersReference.html
+++ b/clang/docs/LibASTMatchersReference.html
@@ -4240,30 +4240,44 @@ caseStmt(hasCaseConstant(integerLiteral()))
<tr><td>Matcher&lt;<a href="http://clang.llvm.org/doxygen/classclang_1_1ClassTemplateSpecializationDecl.html">ClassTemplateSpecializationDecl</a>&gt;</td><td class="name" onclick="toggle('hasAnyTemplateArgument0')"><a name="hasAnyTemplateArgument0Anchor">hasAnyTemplateArgument</a></td><td>Matcher&lt;<a href="http://clang.llvm.org/doxygen/classclang_1_1TemplateArgument.html">TemplateArgument</a>&gt; InnerMatcher</td></tr>
-<tr><td colspan="4" class="doc" id="hasAnyTemplateArgument0"><pre>Matches classTemplateSpecializations that have at least one
-TemplateArgument matching the given InnerMatcher.
+<tr><td colspan="4" class="doc" id="hasAnyTemplateArgument0"><pre>Matches classTemplateSpecializations, templateSpecializationType and
+functionDecl that have at least one TemplateArgument matching the given
+InnerMatcher.
Given
template&lt;typename T&gt; class A {};
template&lt;&gt; class A&lt;double&gt; {};
A&lt;int&gt; a;
+
+ template&lt;typenmae T&gt; f() {};
+ void func() { f&lt;int&gt;(); };
+
classTemplateSpecializationDecl(hasAnyTemplateArgument(
refersToType(asString("int"))))
matches the specialization A&lt;int&gt;
+
+functionDecl(hasAnyTemplateArgument(refersToType(asString("int"))))
+ matches the specialization f&lt;int&gt;
</pre></td></tr>
<tr><td>Matcher&lt;<a href="http://clang.llvm.org/doxygen/classclang_1_1ClassTemplateSpecializationDecl.html">ClassTemplateSpecializationDecl</a>&gt;</td><td class="name" onclick="toggle('hasTemplateArgument0')"><a name="hasTemplateArgument0Anchor">hasTemplateArgument</a></td><td>unsigned N, Matcher&lt;<a href="http://clang.llvm.org/doxygen/classclang_1_1TemplateArgument.html">TemplateArgument</a>&gt; InnerMatcher</td></tr>
-<tr><td colspan="4" class="doc" id="hasTemplateArgument0"><pre>Matches classTemplateSpecializations where the n'th TemplateArgument
-matches the given InnerMatcher.
+<tr><td colspan="4" class="doc" id="hasTemplateArgument0"><pre>Matches classTemplateSpecializations, templateSpecializationType and
+functionDecl where the n'th TemplateArgument matches the given InnerMatcher.
Given
template&lt;typename T, typename U&gt; class A {};
A&lt;bool, int&gt; b;
A&lt;int, bool&gt; c;
+
+ template&lt;typenmae T&gt; f() {};
+ void func() { f&lt;int&gt;(); };
classTemplateSpecializationDecl(hasTemplateArgument(
1, refersToType(asString("int"))))
matches the specialization A&lt;bool, int&gt;
+
+functionDecl(hasTemplateArgument(0, refersToType(asString("int"))))
+ matches the specialization f&lt;int&gt;
</pre></td></tr>
@@ -4679,6 +4693,28 @@ with hasAnyParameter(...)
</pre></td></tr>
+<tr><td>Matcher&lt;<a href="http://clang.llvm.org/doxygen/classclang_1_1FunctionDecl.html">FunctionDecl</a>&gt;</td><td class="name" onclick="toggle('hasAnyTemplateArgument2')"><a name="hasAnyTemplateArgument2Anchor">hasAnyTemplateArgument</a></td><td>Matcher&lt;<a href="http://clang.llvm.org/doxygen/classclang_1_1TemplateArgument.html">TemplateArgument</a>&gt; InnerMatcher</td></tr>
+<tr><td colspan="4" class="doc" id="hasAnyTemplateArgument2"><pre>Matches classTemplateSpecializations, templateSpecializationType and
+functionDecl that have at least one TemplateArgument matching the given
+InnerMatcher.
+
+Given
+ template&lt;typename T&gt; class A {};
+ template&lt;&gt; class A&lt;double&gt; {};
+ A&lt;int&gt; a;
+
+ template&lt;typenmae T&gt; f() {};
+ void func() { f&lt;int&gt;(); };
+
+classTemplateSpecializationDecl(hasAnyTemplateArgument(
+ refersToType(asString("int"))))
+ matches the specialization A&lt;int&gt;
+
+functionDecl(hasAnyTemplateArgument(refersToType(asString("int"))))
+ matches the specialization f&lt;int&gt;
+</pre></td></tr>
+
+
<tr><td>Matcher&lt;<a href="http://clang.llvm.org/doxygen/classclang_1_1FunctionDecl.html">FunctionDecl</a>&gt;</td><td class="name" onclick="toggle('hasBody4')"><a name="hasBody4Anchor">hasBody</a></td><td>Matcher&lt;<a href="http://clang.llvm.org/doxygen/classclang_1_1Stmt.html">Stmt</a>&gt; InnerMatcher</td></tr>
<tr><td colspan="4" class="doc" id="hasBody4"><pre>Matches a 'for', 'while', 'do while' statement or a function
definition that has a given body.
@@ -4704,6 +4740,26 @@ with hasParameter(...)
</pre></td></tr>
+<tr><td>Matcher&lt;<a href="http://clang.llvm.org/doxygen/classclang_1_1FunctionDecl.html">FunctionDecl</a>&gt;</td><td class="name" onclick="toggle('hasTemplateArgument2')"><a name="hasTemplateArgument2Anchor">hasTemplateArgument</a></td><td>unsigned N, Matcher&lt;<a href="http://clang.llvm.org/doxygen/classclang_1_1TemplateArgument.html">TemplateArgument</a>&gt; InnerMatcher</td></tr>
+<tr><td colspan="4" class="doc" id="hasTemplateArgument2"><pre>Matches classTemplateSpecializations, templateSpecializationType and
+functionDecl where the n'th TemplateArgument matches the given InnerMatcher.
+
+Given
+ template&lt;typename T, typename U&gt; class A {};
+ A&lt;bool, int&gt; b;
+ A&lt;int, bool&gt; c;
+
+ template&lt;typenmae T&gt; f() {};
+ void func() { f&lt;int&gt;(); };
+classTemplateSpecializationDecl(hasTemplateArgument(
+ 1, refersToType(asString("int"))))
+ matches the specialization A&lt;bool, int&gt;
+
+functionDecl(hasTemplateArgument(0, refersToType(asString("int"))))
+ matches the specialization f&lt;int&gt;
+</pre></td></tr>
+
+
<tr><td>Matcher&lt;<a href="http://clang.llvm.org/doxygen/classclang_1_1FunctionDecl.html">FunctionDecl</a>&gt;</td><td class="name" onclick="toggle('returns0')"><a name="returns0Anchor">returns</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="returns0"><pre>Matches the return type of a function declaration.
@@ -5311,16 +5367,24 @@ classTemplateSpecializationDecl(hasAnyTemplateArgument(
<tr><td>Matcher&lt;<a href="http://clang.llvm.org/doxygen/classclang_1_1TemplateSpecializationType.html">TemplateSpecializationType</a>&gt;</td><td class="name" onclick="toggle('hasAnyTemplateArgument1')"><a name="hasAnyTemplateArgument1Anchor">hasAnyTemplateArgument</a></td><td>Matcher&lt;<a href="http://clang.llvm.org/doxygen/classclang_1_1TemplateArgument.html">TemplateArgument</a>&gt; InnerMatcher</td></tr>
-<tr><td colspan="4" class="doc" id="hasAnyTemplateArgument1"><pre>Matches classTemplateSpecializations that have at least one
-TemplateArgument matching the given InnerMatcher.
+<tr><td colspan="4" class="doc" id="hasAnyTemplateArgument1"><pre>Matches classTemplateSpecializations, templateSpecializationType and
+functionDecl that have at least one TemplateArgument matching the given
+InnerMatcher.
Given
template&lt;typename T&gt; class A {};
template&lt;&gt; class A&lt;double&gt; {};
A&lt;int&gt; a;
+
+ template&lt;typenmae T&gt; f() {};
+ void func() { f&lt;int&gt;(); };
+
classTemplateSpecializationDecl(hasAnyTemplateArgument(
refersToType(asString("int"))))
matches the specialization A&lt;int&gt;
+
+functionDecl(hasAnyTemplateArgument(refersToType(asString("int"))))
+ matches the specialization f&lt;int&gt;
</pre></td></tr>
@@ -5347,16 +5411,22 @@ Usable as: Matcher&lt;<a href="http://clang.llvm.org/doxygen/classclang_1_1CallE
<tr><td>Matcher&lt;<a href="http://clang.llvm.org/doxygen/classclang_1_1TemplateSpecializationType.html">TemplateSpecializationType</a>&gt;</td><td class="name" onclick="toggle('hasTemplateArgument1')"><a name="hasTemplateArgument1Anchor">hasTemplateArgument</a></td><td>unsigned N, Matcher&lt;<a href="http://clang.llvm.org/doxygen/classclang_1_1TemplateArgument.html">TemplateArgument</a>&gt; InnerMatcher</td></tr>
-<tr><td colspan="4" class="doc" id="hasTemplateArgument1"><pre>Matches classTemplateSpecializations where the n'th TemplateArgument
-matches the given InnerMatcher.
+<tr><td colspan="4" class="doc" id="hasTemplateArgument1"><pre>Matches classTemplateSpecializations, templateSpecializationType and
+functionDecl where the n'th TemplateArgument matches the given InnerMatcher.
Given
template&lt;typename T, typename U&gt; class A {};
A&lt;bool, int&gt; b;
A&lt;int, bool&gt; c;
+
+ template&lt;typenmae T&gt; f() {};
+ void func() { f&lt;int&gt;(); };
classTemplateSpecializationDecl(hasTemplateArgument(
1, refersToType(asString("int"))))
matches the specialization A&lt;bool, int&gt;
+
+functionDecl(hasTemplateArgument(0, refersToType(asString("int"))))
+ matches the specialization f&lt;int&gt;
</pre></td></tr>
diff --git a/clang/include/clang/ASTMatchers/ASTMatchers.h b/clang/include/clang/ASTMatchers/ASTMatchers.h
index 8c079bae418..6f59b825202 100644
--- a/clang/include/clang/ASTMatchers/ASTMatchers.h
+++ b/clang/include/clang/ASTMatchers/ASTMatchers.h
@@ -556,22 +556,32 @@ AST_MATCHER(Decl, isImplicit) {
return Node.isImplicit();
}
-/// \brief Matches classTemplateSpecializations that have at least one
-/// TemplateArgument matching the given InnerMatcher.
+/// \brief Matches classTemplateSpecializations, templateSpecializationType and
+/// functionDecl that have at least one TemplateArgument matching the given
+/// InnerMatcher.
///
/// Given
/// \code
/// template<typename T> class A {};
/// template<> class A<double> {};
/// A<int> a;
+///
+/// template<typenmae T> f() {};
+/// void func() { f<int>(); };
+/// \endcode
+///
/// \endcode
/// classTemplateSpecializationDecl(hasAnyTemplateArgument(
/// refersToType(asString("int"))))
/// matches the specialization \c A<int>
+///
+/// functionDecl(hasAnyTemplateArgument(refersToType(asString("int"))))
+/// matches the specialization \c f<int>
AST_POLYMORPHIC_MATCHER_P(
hasAnyTemplateArgument,
AST_POLYMORPHIC_SUPPORTED_TYPES(ClassTemplateSpecializationDecl,
- TemplateSpecializationType),
+ TemplateSpecializationType,
+ FunctionDecl),
internal::Matcher<TemplateArgument>, InnerMatcher) {
ArrayRef<TemplateArgument> List =
internal::getTemplateSpecializationArgs(Node);
@@ -698,22 +708,29 @@ AST_MATCHER_P(QualType, ignoringParens,
return InnerMatcher.matches(Node.IgnoreParens(), Finder, Builder);
}
-/// \brief Matches classTemplateSpecializations where the n'th TemplateArgument
-/// matches the given InnerMatcher.
+/// \brief Matches classTemplateSpecializations, templateSpecializationType and
+/// functionDecl where the n'th TemplateArgument matches the given InnerMatcher.
///
/// Given
/// \code
/// template<typename T, typename U> class A {};
/// A<bool, int> b;
/// A<int, bool> c;
+///
+/// template<typenmae T> f() {};
+/// void func() { f<int>(); };
/// \endcode
/// classTemplateSpecializationDecl(hasTemplateArgument(
/// 1, refersToType(asString("int"))))
/// matches the specialization \c A<bool, int>
+///
+/// functionDecl(hasTemplateArgument(0, refersToType(asString("int"))))
+/// matches the specialization \c f<int>
AST_POLYMORPHIC_MATCHER_P2(
hasTemplateArgument,
AST_POLYMORPHIC_SUPPORTED_TYPES(ClassTemplateSpecializationDecl,
- TemplateSpecializationType),
+ TemplateSpecializationType,
+ FunctionDecl),
unsigned, N, internal::Matcher<TemplateArgument>, InnerMatcher) {
ArrayRef<TemplateArgument> List =
internal::getTemplateSpecializationArgs(Node);
diff --git a/clang/include/clang/ASTMatchers/ASTMatchersInternal.h b/clang/include/clang/ASTMatchers/ASTMatchersInternal.h
index c2c01fbd78e..b9e31577071 100644
--- a/clang/include/clang/ASTMatchers/ASTMatchersInternal.h
+++ b/clang/include/clang/ASTMatchers/ASTMatchersInternal.h
@@ -1638,6 +1638,13 @@ getTemplateSpecializationArgs(const TemplateSpecializationType &T) {
return llvm::makeArrayRef(T.getArgs(), T.getNumArgs());
}
+inline ArrayRef<TemplateArgument>
+getTemplateSpecializationArgs(const FunctionDecl &FD) {
+ if (const auto* TemplateArgs = FD.getTemplateSpecializationArgs())
+ return TemplateArgs->asArray();
+ return ArrayRef<TemplateArgument>();
+}
+
struct NotEqualsBoundNodePredicate {
bool operator()(const internal::BoundNodesMap &Nodes) const {
return Nodes.getNode(ID) != Node;
diff --git a/clang/unittests/ASTMatchers/ASTMatchersTraversalTest.cpp b/clang/unittests/ASTMatchers/ASTMatchersTraversalTest.cpp
index 4149d4fd0b1..7c496647b4c 100644
--- a/clang/unittests/ASTMatchers/ASTMatchersTraversalTest.cpp
+++ b/clang/unittests/ASTMatchers/ASTMatchersTraversalTest.cpp
@@ -594,6 +594,14 @@ TEST(Matcher, MatchesSpecificArgument) {
"A<int, bool> a;",
templateSpecializationType(hasTemplateArgument(
1, refersToType(asString("int"))))));
+
+ EXPECT_TRUE(matches(
+ "template<typename T> void f() {};"
+ "void func() { f<int>(); }",
+ functionDecl(hasTemplateArgument(0, refersToType(asString("int"))))));
+ EXPECT_TRUE(notMatches(
+ "template<typename T> void f() {};",
+ functionDecl(hasTemplateArgument(0, refersToType(asString("int"))))));
}
TEST(TemplateArgument, Matches) {
@@ -603,6 +611,11 @@ TEST(TemplateArgument, Matches) {
EXPECT_TRUE(matches(
"template<typename T> struct C {}; C<int> c;",
templateSpecializationType(hasAnyTemplateArgument(templateArgument()))));
+
+ EXPECT_TRUE(matches(
+ "template<typename T> void f() {};"
+ "void func() { f<int>(); }",
+ functionDecl(hasAnyTemplateArgument(templateArgument()))));
}
TEST(RefersToIntegralType, Matches) {
OpenPOWER on IntegriCloud