[ASTMatchers] isTemplateInstantiation: also match explicit instantiation declaration.

Summary:
Example:
template <typename T> class X {}; class A {};
// Explicit instantiation declaration.
extern template class X<A>;

Reviewers: bkramer

Subscribers: klimek, cfe-commits

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

llvm-svn: 325678
This commit is contained in:
Eric Liu 2018-02-21 13:51:27 +00:00
parent 770397f4cd
commit 500e126155
2 changed files with 15 additions and 1 deletions

View File

@ -4649,6 +4649,10 @@ AST_MATCHER_P(UsingShadowDecl, hasTargetDecl,
/// \code
/// template <typename T> class X {}; class A {}; template class X<A>;
/// \endcode
/// or
/// \code
/// template <typename T> class X {}; class A {}; extern template class X<A>;
/// \endcode
/// cxxRecordDecl(hasName("::X"), isTemplateInstantiation())
/// matches the template instantiation of X<A>.
///
@ -4666,7 +4670,9 @@ AST_POLYMORPHIC_MATCHER(isTemplateInstantiation,
CXXRecordDecl)) {
return (Node.getTemplateSpecializationKind() == TSK_ImplicitInstantiation ||
Node.getTemplateSpecializationKind() ==
TSK_ExplicitInstantiationDefinition);
TSK_ExplicitInstantiationDefinition ||
Node.getTemplateSpecializationKind() ==
TSK_ExplicitInstantiationDeclaration);
}
/// \brief Matches declarations that are template instantiations or are inside

View File

@ -1623,6 +1623,14 @@ TEST(IsTemplateInstantiation, MatchesExplicitClassTemplateInstantiation) {
"template class X<A>;",
cxxRecordDecl(isTemplateInstantiation(), hasDescendant(
fieldDecl(hasType(recordDecl(hasName("A"))))))));
// Make sure that we match the instantiation instead of the template
// definition by checking whether the member function is present.
EXPECT_TRUE(
matches("template <typename T> class X { void f() { T t; } };"
"extern template class X<int>;",
cxxRecordDecl(isTemplateInstantiation(),
unless(hasDescendant(varDecl(hasName("t")))))));
}
TEST(IsTemplateInstantiation,