Decl,
CXXRecordDecl> record;
+/// \brief Matches C++ class template declarations.
+///
+/// Example matches Z
+/// template<class T> class Z {};
+const internal::VariadicDynCastAllOfMatcher<
+ Decl,
+ ClassTemplateDecl> classTemplate;
+
/// \brief Matches C++ class template specializations.
///
/// Given
/// void f();
const internal::VariadicDynCastAllOfMatcher<Decl, FunctionDecl> function;
+/// \brief Matches C++ function template declarations.
+///
+/// Example matches f
+/// template<class T> void f(T t) {}
+const internal::VariadicDynCastAllOfMatcher<
+ Decl,
+ FunctionTemplateDecl> functionTemplate;
/// \brief Matches statements.
///
internal::IsTemplateInstantiationMatcher>();
}
+/// \brief Matches explicit template specializations of function, class, or
+/// static member variable template instantiations.
+///
+/// Given
+/// template<typename T> void A(T t) { }
+/// template<> void A(int N) { }
+/// function(isExplicitSpecialization())
+/// matches the specialization A<int>().
+inline internal::PolymorphicMatcherWithParam0<
+ internal::IsExplicitTemplateSpecializationMatcher>
+isExplicitTemplateSpecialization() {
+ return internal::PolymorphicMatcherWithParam0<
+ internal::IsExplicitTemplateSpecializationMatcher>();
+}
+
} // end namespace ast_matchers
} // end namespace clang
record(isDerivedFrom(record(hasName("X")).bind("test")))));
}
+TEST(ClassTemplate, DoesNotMatchClass) {
+ DeclarationMatcher ClassX = classTemplate(hasName("X"));
+ EXPECT_TRUE(notMatches("class X;", ClassX));
+ EXPECT_TRUE(notMatches("class X {};", ClassX));
+}
+
+TEST(ClassTemplate, MatchesClassTemplate) {
+ DeclarationMatcher ClassX = classTemplate(hasName("X"));
+ EXPECT_TRUE(matches("template<typename T> class X {};", ClassX));
+ EXPECT_TRUE(matches("class Z { template<class T> class X {}; };", ClassX));
+}
+
+TEST(ClassTemplate, DoesNotMatchClassTemplateExplicitSpecialization) {
+ EXPECT_TRUE(notMatches("template<typename T> class X { };"
+ "template<> class X<int> { int a; };",
+ classTemplate(hasName("X"),
+ hasDescendant(field(hasName("a"))))));
+}
+
+TEST(ClassTemplate, DoesNotMatchClassTemplatePartialSpecialization) {
+ EXPECT_TRUE(notMatches("template<typename T, typename U> class X { };"
+ "template<typename T> class X<T, int> { int a; };",
+ classTemplate(hasName("X"),
+ hasDescendant(field(hasName("a"))))));
+}
+
TEST(AllOf, AllOverloadsWork) {
const char Program[] =
"struct T { }; int f(int, T*); void g(int x) { T t; f(x, &t); }";
CallFunctionF));
}
+TEST(FunctionTemplate, MatchesFunctionTemplateDeclarations) {
+ EXPECT_TRUE(
+ matches("template <typename T> void f(T t) {}",
+ functionTemplate(hasName("f"))));
+}
+
+TEST(FunctionTemplate, DoesNotMatchFunctionDeclarations) {
+ EXPECT_TRUE(
+ notMatches("void f(double d); void f(int t) {}",
+ functionTemplate(hasName("f"))));
+}
+
+TEST(FunctionTemplate, DoesNotMatchFunctionTemplateSpecializations) {
+ EXPECT_TRUE(
+ notMatches("void g(); template <typename T> void f(T t) {}"
+ "template <> void f(int t) { g(); }",
+ functionTemplate(hasName("f"),
+ hasDescendant(declarationReference(
+ to(function(hasName("g"))))))));
+}
+
TEST(Matcher, Argument) {
StatementMatcher CallArgumentY = expression(call(
hasArgument(0, declarationReference(to(variable(hasName("y")))))));
record(isTemplateInstantiation())));
}
+TEST(IsExplicitTemplateSpecialization,
+ DoesNotMatchPrimaryTemplate) {
+ EXPECT_TRUE(notMatches(
+ "template <typename T> class X {};",
+ record(isExplicitTemplateSpecialization())));
+ EXPECT_TRUE(notMatches(
+ "template <typename T> void f(T t);",
+ function(isExplicitTemplateSpecialization())));
+}
+
+TEST(IsExplicitTemplateSpecialization,
+ DoesNotMatchExplicitTemplateInstantiations) {
+ EXPECT_TRUE(notMatches(
+ "template <typename T> class X {};"
+ "template class X<int>; extern template class X<long>;",
+ record(isExplicitTemplateSpecialization())));
+ EXPECT_TRUE(notMatches(
+ "template <typename T> void f(T t) {}"
+ "template void f(int t); extern template void f(long t);",
+ function(isExplicitTemplateSpecialization())));
+}
+
+TEST(IsExplicitTemplateSpecialization,
+ DoesNotMatchImplicitTemplateInstantiations) {
+ EXPECT_TRUE(notMatches(
+ "template <typename T> class X {}; X<int> x;",
+ record(isExplicitTemplateSpecialization())));
+ EXPECT_TRUE(notMatches(
+ "template <typename T> void f(T t); void g() { f(10); }",
+ function(isExplicitTemplateSpecialization())));
+}
+
+TEST(IsExplicitTemplateSpecialization,
+ MatchesExplicitTemplateSpecializations) {
+ EXPECT_TRUE(matches(
+ "template <typename T> class X {};"
+ "template<> class X<int> {};",
+ record(isExplicitTemplateSpecialization())));
+ EXPECT_TRUE(matches(
+ "template <typename T> void f(T t) {}"
+ "template<> void f(int t) {}",
+ function(isExplicitTemplateSpecialization())));
+}
+
} // end namespace ast_matchers
} // end namespace clang