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() {}; +/// 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