On Fri, Jul 29, 2016 at 3:57 PM, Haojian Wu via cfe-commits
<cfe-commits@lists.llvm.org> wrote:
> 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() {};

typenmae?

> +///   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
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to