return InnerMatcher.matches(Node.getNamedType(), Finder, Builder);
}
+/// \brief Matches types that represent the result of substituting a type for a
+/// template type parameter.
+///
+/// Given
+/// \code
+/// template <typename T>
+/// void F(T t) {
+/// int i = 1 + t;
+/// }
+/// \code
+///
+/// \c substTemplateTypeParmType() matches the type of 't' but not '1'
+AST_TYPE_MATCHER(SubstTemplateTypeParmType, substTemplateTypeParmType);
+
/// \brief Matches declarations whose declaration context, interpreted as a
/// Decl, matches \c InnerMatcher.
///
REGISTER_MATCHER(stmt);
REGISTER_MATCHER(stringLiteral);
REGISTER_MATCHER(substNonTypeTemplateParmExpr);
+ REGISTER_MATCHER(substTemplateTypeParmType);
REGISTER_MATCHER(switchCase);
REGISTER_MATCHER(switchStmt);
REGISTER_MATCHER(templateArgument);
elaboratedType(elaboratedType(namesType(typedefType())))));
}
+TEST(TypeMatching, MatchesSubstTemplateTypeParmType) {
+ const std::string code = "template <typename T>"
+ "int F() {"
+ " return 1 + T();"
+ "}"
+ "int i = F<int>();";
+ EXPECT_FALSE(matches(code, binaryOperator(hasLHS(
+ expr(hasType(substTemplateTypeParmType()))))));
+ EXPECT_TRUE(matches(code, binaryOperator(hasRHS(
+ expr(hasType(substTemplateTypeParmType()))))));
+}
+
TEST(NNS, MatchesNestedNameSpecifiers) {
EXPECT_TRUE(matches("namespace ns { struct A {}; } ns::A a;",
nestedNameSpecifier()));