diff --git a/docs/LibASTMatchersReference.html b/docs/LibASTMatchersReference.html index 69c58e90b3df01787381dfca6bc85c34665989a6..2a8d864c3c5c1a36f584c0a0c3129eb16267f6df 100644 --- a/docs/LibASTMatchersReference.html +++ b/docs/LibASTMatchersReference.html @@ -5421,6 +5421,20 @@ sizeof. </pre></td></tr> +<tr><td>Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1SubstTemplateTypeParmType.html">SubstTemplateTypeParmType</a>></td><td class="name" onclick="toggle('hasReplacementType0')"><a name="hasReplacementType0Anchor">hasReplacementType</a></td><td>Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1Type.html">Type</a>></td></tr> +<tr><td colspan="4" class="doc" id="hasReplacementType0"><pre>Matches template type parameter substitutions that have a replacement +type that matches the provided matcher. + +Given + template <typename T> + double F(T t); + int i; + double j = F(i); + +substTemplateTypeParmType(hasReplacementType(type())) matches int +</pre></td></tr> + + <tr><td>Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1SwitchStmt.html">SwitchStmt</a>></td><td class="name" onclick="toggle('forEachSwitchCase0')"><a name="forEachSwitchCase0Anchor">forEachSwitchCase</a></td><td>Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1SwitchCase.html">SwitchCase</a>> InnerMatcher</td></tr> <tr><td colspan="4" class="doc" id="forEachSwitchCase0"><pre>Matches each case or default statement belonging to the given switch statement. This matcher may produce multiple matches. diff --git a/include/clang/ASTMatchers/ASTMatchers.h b/include/clang/ASTMatchers/ASTMatchers.h index 409786e8e9cd13c8d921ea0ee9155b281108d0fa..ce01f45333b85465b3352d88643ec478b3d47b06 100644 --- a/include/clang/ASTMatchers/ASTMatchers.h +++ b/include/clang/ASTMatchers/ASTMatchers.h @@ -5019,6 +5019,22 @@ AST_MATCHER_P(ElaboratedType, namesType, internal::Matcher<QualType>, /// \c substTemplateTypeParmType() matches the type of 't' but not '1' AST_TYPE_MATCHER(SubstTemplateTypeParmType, substTemplateTypeParmType); +/// \brief Matches template type parameter substitutions that have a replacement +/// type that matches the provided matcher. +/// +/// Given +/// \code +/// template <typename T> +/// double F(T t); +/// int i; +/// double j = F(i); +/// \endcode +/// +/// \c substTemplateTypeParmType(hasReplacementType(type())) matches int +AST_TYPE_TRAVERSE_MATCHER( + hasReplacementType, getReplacementType, + AST_POLYMORPHIC_SUPPORTED_TYPES(SubstTemplateTypeParmType)); + /// \brief Matches template type parameter types. /// /// Example matches T, but not int. diff --git a/lib/ASTMatchers/Dynamic/Registry.cpp b/lib/ASTMatchers/Dynamic/Registry.cpp index eca8a1a9d134bad7903fe80db3941a80e24d8814..b1309bcafe3a077cd68e04c525570f55f009687b 100644 --- a/lib/ASTMatchers/Dynamic/Registry.cpp +++ b/lib/ASTMatchers/Dynamic/Registry.cpp @@ -252,6 +252,7 @@ RegistryMaps::RegistryMaps() { REGISTER_MATCHER(hasQualifier); REGISTER_MATCHER(hasRangeInit); REGISTER_MATCHER(hasReceiverType); + REGISTER_MATCHER(hasReplacementType); REGISTER_MATCHER(hasReturnValue); REGISTER_MATCHER(hasRHS); REGISTER_MATCHER(hasSelector); diff --git a/unittests/ASTMatchers/ASTMatchersTraversalTest.cpp b/unittests/ASTMatchers/ASTMatchersTraversalTest.cpp index 27f0669ca70d43edd948289d5229191dd88ff1cb..789982972e0140fc56ae2404fd47ddbb569ecb9d 100644 --- a/unittests/ASTMatchers/ASTMatchersTraversalTest.cpp +++ b/unittests/ASTMatchers/ASTMatchersTraversalTest.cpp @@ -2204,5 +2204,22 @@ TEST(Matcher, HasAnyDeclaration) { functionDecl(hasName("bar")))))); } +TEST(SubstTemplateTypeParmType, HasReplacementType) +{ + std::string Fragment = "template<typename T>" + "double F(T t);" + "int i;" + "double j = F(i);"; + EXPECT_TRUE(matches(Fragment, substTemplateTypeParmType(hasReplacementType( + qualType(asString("int")))))); + EXPECT_TRUE(notMatches(Fragment, substTemplateTypeParmType(hasReplacementType( + qualType(asString("double")))))); + EXPECT_TRUE( + notMatches("template<int N>" + "double F();" + "double j = F<5>();", + substTemplateTypeParmType(hasReplacementType(qualType())))); +} + } // namespace ast_matchers } // namespace clang