r277142 - [ASTMatcher] Add hasTemplateArgument/hasAnyTemplateArgument support in functionDecl.

Benjamin Kramer via cfe-commits cfe-commits at lists.llvm.org
Fri Jul 29 09:32:51 PDT 2016


Sorry for being overly dense, you misspelled 'typename' in the docs.

On Fri, Jul 29, 2016 at 5:59 PM, Haojian Wu <hokein at google.com> wrote:
> No, this is not templateName patch. The templateName one is in r277155.
>
> On Fri, Jul 29, 2016 at 4:45 PM, Benjamin Kramer <benny.kra at gmail.com>
> wrote:
>>
>> On Fri, Jul 29, 2016 at 3:57 PM, Haojian Wu via cfe-commits
>> <cfe-commits at 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<<a
>> > href="http://clang.llvm.org/doxygen/classclang_1_1ClassTemplateSpecializationDecl.html">ClassTemplateSpecializationDecl</a>></td><td
>> > class="name" onclick="toggle('hasAnyTemplateArgument0')"><a
>> > name="hasAnyTemplateArgument0Anchor">hasAnyTemplateArgument</a></td><td>Matcher<<a
>> > href="http://clang.llvm.org/doxygen/classclang_1_1TemplateArgument.html">TemplateArgument</a>>
>> > 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<typename T> class A {};
>> >    template<> class A<double> {};
>> >    A<int> a;
>> > +
>> > +  template<typenmae T> f() {};
>> > +  void func() { f<int>(); };
>> > +
>> >  classTemplateSpecializationDecl(hasAnyTemplateArgument(
>> >      refersToType(asString("int"))))
>> >    matches the specialization A<int>
>> > +
>> > +functionDecl(hasAnyTemplateArgument(refersToType(asString("int"))))
>> > +  matches the specialization f<int>
>> >  </pre></td></tr>
>> >
>> >
>> >  <tr><td>Matcher<<a
>> > href="http://clang.llvm.org/doxygen/classclang_1_1ClassTemplateSpecializationDecl.html">ClassTemplateSpecializationDecl</a>></td><td
>> > class="name" onclick="toggle('hasTemplateArgument0')"><a
>> > name="hasTemplateArgument0Anchor">hasTemplateArgument</a></td><td>unsigned
>> > N, Matcher<<a
>> > href="http://clang.llvm.org/doxygen/classclang_1_1TemplateArgument.html">TemplateArgument</a>>
>> > 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<typename T, typename U> class A {};
>> >    A<bool, int> b;
>> >    A<int, bool> c;
>> > +
>> > +  template<typenmae T> f() {};
>> > +  void func() { f<int>(); };
>> >  classTemplateSpecializationDecl(hasTemplateArgument(
>> >      1, refersToType(asString("int"))))
>> >    matches the specialization A<bool, int>
>> > +
>> > +functionDecl(hasTemplateArgument(0, refersToType(asString("int"))))
>> > +  matches the specialization f<int>
>> >  </pre></td></tr>
>> >
>> >
>> > @@ -4679,6 +4693,28 @@ with hasAnyParameter(...)
>> >  </pre></td></tr>
>> >
>> >
>> > +<tr><td>Matcher<<a
>> > href="http://clang.llvm.org/doxygen/classclang_1_1FunctionDecl.html">FunctionDecl</a>></td><td
>> > class="name" onclick="toggle('hasAnyTemplateArgument2')"><a
>> > name="hasAnyTemplateArgument2Anchor">hasAnyTemplateArgument</a></td><td>Matcher<<a
>> > href="http://clang.llvm.org/doxygen/classclang_1_1TemplateArgument.html">TemplateArgument</a>>
>> > 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<typename T> class A {};
>> > +  template<> class A<double> {};
>> > +  A<int> a;
>> > +
>> > +  template<typenmae T> f() {};
>> > +  void func() { f<int>(); };
>> > +
>> > +classTemplateSpecializationDecl(hasAnyTemplateArgument(
>> > +    refersToType(asString("int"))))
>> > +  matches the specialization A<int>
>> > +
>> > +functionDecl(hasAnyTemplateArgument(refersToType(asString("int"))))
>> > +  matches the specialization f<int>
>> > +</pre></td></tr>
>> > +
>> > +
>> >  <tr><td>Matcher<<a
>> > href="http://clang.llvm.org/doxygen/classclang_1_1FunctionDecl.html">FunctionDecl</a>></td><td
>> > class="name" onclick="toggle('hasBody4')"><a
>> > name="hasBody4Anchor">hasBody</a></td><td>Matcher<<a
>> > href="http://clang.llvm.org/doxygen/classclang_1_1Stmt.html">Stmt</a>>
>> > 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<<a
>> > href="http://clang.llvm.org/doxygen/classclang_1_1FunctionDecl.html">FunctionDecl</a>></td><td
>> > class="name" onclick="toggle('hasTemplateArgument2')"><a
>> > name="hasTemplateArgument2Anchor">hasTemplateArgument</a></td><td>unsigned
>> > N, Matcher<<a
>> > href="http://clang.llvm.org/doxygen/classclang_1_1TemplateArgument.html">TemplateArgument</a>>
>> > 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<typename T, typename U> class A {};
>> > +  A<bool, int> b;
>> > +  A<int, bool> c;
>> > +
>> > +  template<typenmae T> f() {};
>> > +  void func() { f<int>(); };
>> > +classTemplateSpecializationDecl(hasTemplateArgument(
>> > +    1, refersToType(asString("int"))))
>> > +  matches the specialization A<bool, int>
>> > +
>> > +functionDecl(hasTemplateArgument(0, refersToType(asString("int"))))
>> > +  matches the specialization f<int>
>> > +</pre></td></tr>
>> > +
>> > +
>> >  <tr><td>Matcher<<a
>> > href="http://clang.llvm.org/doxygen/classclang_1_1FunctionDecl.html">FunctionDecl</a>></td><td
>> > class="name" onclick="toggle('returns0')"><a
>> > name="returns0Anchor">returns</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="returns0"><pre>Matches the return
>> > type of a function declaration.
>> >
>> > @@ -5311,16 +5367,24 @@ classTemplateSpecializationDecl(hasAnyTe
>> >
>> >
>> >  <tr><td>Matcher<<a
>> > href="http://clang.llvm.org/doxygen/classclang_1_1TemplateSpecializationType.html">TemplateSpecializationType</a>></td><td
>> > class="name" onclick="toggle('hasAnyTemplateArgument1')"><a
>> > name="hasAnyTemplateArgument1Anchor">hasAnyTemplateArgument</a></td><td>Matcher<<a
>> > href="http://clang.llvm.org/doxygen/classclang_1_1TemplateArgument.html">TemplateArgument</a>>
>> > 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<typename T> class A {};
>> >    template<> class A<double> {};
>> >    A<int> a;
>> > +
>> > +  template<typenmae T> f() {};
>> > +  void func() { f<int>(); };
>> > +
>> >  classTemplateSpecializationDecl(hasAnyTemplateArgument(
>> >      refersToType(asString("int"))))
>> >    matches the specialization A<int>
>> > +
>> > +functionDecl(hasAnyTemplateArgument(refersToType(asString("int"))))
>> > +  matches the specialization f<int>
>> >  </pre></td></tr>
>> >
>> >
>> > @@ -5347,16 +5411,22 @@ Usable as: Matcher<<a href="http://cl
>> >
>> >
>> >  <tr><td>Matcher<<a
>> > href="http://clang.llvm.org/doxygen/classclang_1_1TemplateSpecializationType.html">TemplateSpecializationType</a>></td><td
>> > class="name" onclick="toggle('hasTemplateArgument1')"><a
>> > name="hasTemplateArgument1Anchor">hasTemplateArgument</a></td><td>unsigned
>> > N, Matcher<<a
>> > href="http://clang.llvm.org/doxygen/classclang_1_1TemplateArgument.html">TemplateArgument</a>>
>> > 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<typename T, typename U> class A {};
>> >    A<bool, int> b;
>> >    A<int, bool> c;
>> > +
>> > +  template<typenmae T> f() {};
>> > +  void func() { f<int>(); };
>> >  classTemplateSpecializationDecl(hasTemplateArgument(
>> >      1, refersToType(asString("int"))))
>> >    matches the specialization A<bool, int>
>> > +
>> > +functionDecl(hasTemplateArgument(0, refersToType(asString("int"))))
>> > +  matches the specialization f<int>
>> >  </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 at lists.llvm.org
>> > http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
>
>


More information about the cfe-commits mailing list