Author: hokein
Date: Fri Jul 29 08:57:27 2016
New Revision: 277142

URL: http://llvm.org/viewvc/llvm-project?rev=277142&view=rev
Log:
[ASTMatcher] Add hasTemplateArgument/hasAnyTemplateArgument support in 
functionDecl.

Reviewers: klimek

Subscribers: klimek, cfe-commits

Differential Revision: https://reviews.llvm.org/D22957

Modified:
    cfe/trunk/docs/LibASTMatchersReference.html
    cfe/trunk/include/clang/ASTMatchers/ASTMatchers.h
    cfe/trunk/include/clang/ASTMatchers/ASTMatchersInternal.h
    cfe/trunk/unittests/ASTMatchers/ASTMatchersTraversalTest.cpp

Modified: cfe/trunk/docs/LibASTMatchersReference.html
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/docs/LibASTMatchersReference.html?rev=277142&r1=277141&r2=277142&view=diff
==============================================================================
--- cfe/trunk/docs/LibASTMatchersReference.html (original)
+++ cfe/trunk/docs/LibASTMatchersReference.html Fri Jul 29 08:57:27 2016
@@ -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(hasAnyTe
 
 
 <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://cl
 
 
 <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>
 
 

Modified: cfe/trunk/include/clang/ASTMatchers/ASTMatchers.h
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/ASTMatchers/ASTMatchers.h?rev=277142&r1=277141&r2=277142&view=diff
==============================================================================
--- cfe/trunk/include/clang/ASTMatchers/ASTMatchers.h (original)
+++ cfe/trunk/include/clang/ASTMatchers/ASTMatchers.h Fri Jul 29 08:57:27 2016
@@ -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);

Modified: cfe/trunk/include/clang/ASTMatchers/ASTMatchersInternal.h
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/ASTMatchers/ASTMatchersInternal.h?rev=277142&r1=277141&r2=277142&view=diff
==============================================================================
--- cfe/trunk/include/clang/ASTMatchers/ASTMatchersInternal.h (original)
+++ cfe/trunk/include/clang/ASTMatchers/ASTMatchersInternal.h Fri Jul 29 
08:57:27 2016
@@ -1638,6 +1638,13 @@ getTemplateSpecializationArgs(const Temp
   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;

Modified: cfe/trunk/unittests/ASTMatchers/ASTMatchersTraversalTest.cpp
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/unittests/ASTMatchers/ASTMatchersTraversalTest.cpp?rev=277142&r1=277141&r2=277142&view=diff
==============================================================================
--- cfe/trunk/unittests/ASTMatchers/ASTMatchersTraversalTest.cpp (original)
+++ cfe/trunk/unittests/ASTMatchers/ASTMatchersTraversalTest.cpp Fri Jul 29 
08:57:27 2016
@@ -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) {


_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to