ASTMatchers: Add a matcher to detect whether a decl or stmt is inside a template instantiation.
This is hoisted from clang-tidy where it's used everywhere. The implementation
is not particularly efficient right now, but there is no easy fix for that.
Differential Revision: http://reviews.llvm.org/D5085
llvm-svn: 217029
diff --git a/clang/unittests/ASTMatchers/ASTMatchersTest.cpp b/clang/unittests/ASTMatchers/ASTMatchersTest.cpp
index 9263736..3fbe896 100644
--- a/clang/unittests/ASTMatchers/ASTMatchersTest.cpp
+++ b/clang/unittests/ASTMatchers/ASTMatchersTest.cpp
@@ -3504,6 +3504,62 @@
recordDecl(isTemplateInstantiation())));
}
+TEST(IsInstantiated, MatchesInstantiation) {
+ EXPECT_TRUE(
+ matches("template<typename T> class A { T i; }; class Y { A<int> a; };",
+ recordDecl(isInstantiated())));
+}
+
+TEST(IsInstantiated, NotMatchesDefinition) {
+ EXPECT_TRUE(notMatches("template<typename T> class A { T i; };",
+ recordDecl(isInstantiated())));
+}
+
+TEST(IsInTemplateInstantiation, MatchesInstantiationStmt) {
+ EXPECT_TRUE(matches("template<typename T> struct A { A() { T i; } };"
+ "class Y { A<int> a; }; Y y;",
+ declStmt(isInTemplateInstantiation())));
+}
+
+TEST(IsInTemplateInstantiation, NotMatchesDefinitionStmt) {
+ EXPECT_TRUE(notMatches("template<typename T> struct A { void x() { T i; } };",
+ declStmt(isInTemplateInstantiation())));
+}
+
+TEST(IsInstantiated, MatchesFunctionInstantiation) {
+ EXPECT_TRUE(
+ matches("template<typename T> void A(T t) { T i; } void x() { A(0); }",
+ functionDecl(isInstantiated())));
+}
+
+TEST(IsInstantiated, NotMatchesFunctionDefinition) {
+ EXPECT_TRUE(notMatches("template<typename T> void A(T t) { T i; }",
+ varDecl(isInstantiated())));
+}
+
+TEST(IsInTemplateInstantiation, MatchesFunctionInstantiationStmt) {
+ EXPECT_TRUE(
+ matches("template<typename T> void A(T t) { T i; } void x() { A(0); }",
+ declStmt(isInTemplateInstantiation())));
+}
+
+TEST(IsInTemplateInstantiation, NotMatchesFunctionDefinitionStmt) {
+ EXPECT_TRUE(notMatches("template<typename T> void A(T t) { T i; }",
+ declStmt(isInTemplateInstantiation())));
+}
+
+TEST(IsInTemplateInstantiation, Sharing) {
+ auto Matcher = binaryOperator(unless(isInTemplateInstantiation()));
+ // FIXME: Node sharing is an implementation detail, exposing it is ugly
+ // and makes the matcher behave in non-obvious ways.
+ EXPECT_TRUE(notMatches(
+ "int j; template<typename T> void A(T t) { j += 42; } void x() { A(0); }",
+ Matcher));
+ EXPECT_TRUE(matches(
+ "int j; template<typename T> void A(T t) { j += t; } void x() { A(0); }",
+ Matcher));
+}
+
TEST(IsExplicitTemplateSpecialization,
DoesNotMatchPrimaryTemplate) {
EXPECT_TRUE(notMatches(