Skip to content
This repository has been archived by the owner on Apr 23, 2020. It is now read-only.

Commit

Permalink
[ASTMatchers] isTemplateInstantiation: also match explicit instantiat…
Browse files Browse the repository at this point in the history
…ion 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

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@325678 91177308-0d34-0410-b5e6-96231b3b80d8
  • Loading branch information
Eric Liu committed Feb 21, 2018
1 parent ab78fd5 commit bdb4755
Show file tree
Hide file tree
Showing 2 changed files with 15 additions and 1 deletion.
8 changes: 7 additions & 1 deletion include/clang/ASTMatchers/ASTMatchers.h
Original file line number Diff line number Diff line change
Expand Up @@ -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>.
///
Expand All @@ -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
Expand Down
8 changes: 8 additions & 0 deletions unittests/ASTMatchers/ASTMatchersNarrowingTest.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down

0 comments on commit bdb4755

Please sign in to comment.