[ASTMatchers] Omit methods from explicit template instantations
authorStephen Kelly <steveire@gmail.com>
Mon, 28 Dec 2020 01:10:20 +0000 (01:10 +0000)
committerStephen Kelly <steveire@gmail.com>
Tue, 5 Jan 2021 17:42:33 +0000 (17:42 +0000)
Differential Revision: https://reviews.llvm.org/D94032

clang/lib/ASTMatchers/ASTMatchFinder.cpp
clang/unittests/ASTMatchers/ASTMatchersTraversalTest.cpp

index 54dc874..99d9583 100644 (file)
@@ -1158,6 +1158,8 @@ bool MatchASTVisitor::TraverseDecl(Decl *DeclNode) {
   } else if (const auto *FD = dyn_cast<FunctionDecl>(DeclNode)) {
     if (FD->isDefaulted())
       ScopedChildren = true;
+    if (FD->isTemplateInstantiation())
+      ScopedTraversal = true;
   }
 
   ASTNodeNotSpelledInSourceScope RAII1(this, ScopedTraversal);
index cde3e46..e706ea4 100644 (file)
@@ -2201,11 +2201,19 @@ struct TemplStruct {
   TemplStruct() {}
   ~TemplStruct() {}
 
+  void outOfLine(T);
+
 private:
   T m_t;
 };
 
 template<typename T>
+void TemplStruct<T>::outOfLine(T)
+{
+
+}
+
+template<typename T>
 T timesTwo(T input)
 {
   return input * 2;
@@ -2277,7 +2285,7 @@ template<> bool timesTwo<bool>(bool){
                      hasTemplateArgument(0, refersToType(asString("float"))));
     EXPECT_TRUE(matches(Code, traverse(TK_AsIs, MTempl)));
     // TODO: If we could match on explicit instantiations of function templates,
-    // this would be EXPECT_TRUE.
+    // this would be EXPECT_TRUE. See Sema::ActOnExplicitInstantiation.
     EXPECT_FALSE(
         matches(Code, traverse(TK_IgnoreUnlessSpelledInSource, MTempl)));
   }
@@ -2325,6 +2333,14 @@ template<> bool timesTwo<bool>(bool){
     EXPECT_FALSE(matches(Code, traverse(TK_IgnoreUnlessSpelledInSource, M)));
   }
   {
+    // Instantiated, out-of-line methods are not matchable.
+    auto M =
+        cxxMethodDecl(hasName("outOfLine"), isDefinition(),
+                      hasParameter(0, parmVarDecl(hasType(asString("float")))));
+    EXPECT_TRUE(matches(Code, traverse(TK_AsIs, M)));
+    EXPECT_FALSE(matches(Code, traverse(TK_IgnoreUnlessSpelledInSource, M)));
+  }
+  {
     // Explicit specialization is written in source and it matches:
     auto M = classTemplateSpecializationDecl(
         hasName("TemplStruct"),