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<<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@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