[ASTMatcher] Add hasReplacementType matcher for SubstTemplateTypeParmType

Summary: Needed for https://reviews.llvm.org/D27166

Reviewers: sbenza, bkramer, klimek

Subscribers: aemerson, cfe-commits

Differential Revision: https://reviews.llvm.org/D27447

llvm-svn: 289042
This commit is contained in:
Malcolm Parsons 2016-12-08 11:46:22 +00:00
parent 82b95acfbe
commit 77f039bf58
4 changed files with 48 additions and 0 deletions

View File

@ -5421,6 +5421,20 @@ sizeof.
</pre></td></tr>
<tr><td>Matcher&lt;<a href="http://clang.llvm.org/doxygen/classclang_1_1SubstTemplateTypeParmType.html">SubstTemplateTypeParmType</a>&gt;</td><td class="name" onclick="toggle('hasReplacementType0')"><a name="hasReplacementType0Anchor">hasReplacementType</a></td><td>Matcher&lt;<a href="http://clang.llvm.org/doxygen/classclang_1_1Type.html">Type</a>&gt;</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 &lt;typename T&gt;
double F(T t);
int i;
double j = F(i);
substTemplateTypeParmType(hasReplacementType(type())) matches int
</pre></td></tr>
<tr><td>Matcher&lt;<a href="http://clang.llvm.org/doxygen/classclang_1_1SwitchStmt.html">SwitchStmt</a>&gt;</td><td class="name" onclick="toggle('forEachSwitchCase0')"><a name="forEachSwitchCase0Anchor">forEachSwitchCase</a></td><td>Matcher&lt;<a href="http://clang.llvm.org/doxygen/classclang_1_1SwitchCase.html">SwitchCase</a>&gt; 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.

View File

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

View File

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

View File

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