diff options
| -rw-r--r-- | clang/include/clang/AST/RecursiveASTVisitor.h | 6 | ||||
| -rw-r--r-- | clang/unittests/Tooling/RecursiveASTVisitorTest.cpp | 23 | 
2 files changed, 23 insertions, 6 deletions
diff --git a/clang/include/clang/AST/RecursiveASTVisitor.h b/clang/include/clang/AST/RecursiveASTVisitor.h index 465ed12dae4..e91b68cd421 100644 --- a/clang/include/clang/AST/RecursiveASTVisitor.h +++ b/clang/include/clang/AST/RecursiveASTVisitor.h @@ -1436,7 +1436,8 @@ DEF_TRAVERSE_DECL(ClassTemplateDecl, {      if (getDerived().shouldVisitTemplateInstantiations()) {        // If this is the definition of the primary template, visit        // instantiations which were formed from this pattern. -      if (D->isThisDeclarationADefinition()) +      if (D->isThisDeclarationADefinition() || +          D->getInstantiatedFromMemberTemplate())          TRY_TO(TraverseClassInstantiations(D, D));      } @@ -1489,7 +1490,8 @@ DEF_TRAVERSE_DECL(FunctionTemplateDecl, {        //        // In addition, we only traverse the function instantiations when        // the function template is a function template definition. -      if (D->isThisDeclarationADefinition()) { +      if (D->isThisDeclarationADefinition() || +          D->getInstantiatedFromMemberTemplate()) {          TRY_TO(TraverseFunctionInstantiations(D));        }      } diff --git a/clang/unittests/Tooling/RecursiveASTVisitorTest.cpp b/clang/unittests/Tooling/RecursiveASTVisitorTest.cpp index 8ddae504a0a..6ef2786210f 100644 --- a/clang/unittests/Tooling/RecursiveASTVisitorTest.cpp +++ b/clang/unittests/Tooling/RecursiveASTVisitorTest.cpp @@ -208,8 +208,7 @@ TEST(RecursiveASTVisitor, VisitsCallInTemplateInstantiation) {      "void foo() { y<Y>(Y()); }"));  } -/* FIXME: -TEST(RecursiveASTVisitor, VisitsCallInNestedTemplateInstantiation) { +TEST(RecursiveASTVisitor, VisitsCallInNestedFunctionTemplateInstantiation) {    CXXMemberCallVisitor Visitor;    Visitor.ExpectMatch("Y::x", 4, 5);    EXPECT_TRUE(Visitor.runOver( @@ -221,7 +220,24 @@ TEST(RecursiveASTVisitor, VisitsCallInNestedTemplateInstantiation) {      "};\n"      "void foo() { Z<Y>::f<int>(); }"));  } -*/ + +TEST(RecursiveASTVisitor, VisitsCallInNestedClassTemplateInstantiation) { +  CXXMemberCallVisitor Visitor; +  Visitor.ExpectMatch("A::x", 5, 7); +  EXPECT_TRUE(Visitor.runOver( +    "template <typename T1> struct X {\n" +    "  template <typename T2> struct Y {\n" +    "    void f() {\n" +    "      T2 y;\n" +    "      y.x();\n" +    "    }\n" +    "  };\n" +    "};\n" +    "struct A { void x(); };\n" +    "int main() {\n" +    "  (new X<A>::Y<A>())->f();\n" +    "}")); +}  /* FIXME: According to Richard Smith this is a bug in the AST.  TEST(RecursiveASTVisitor, VisitsBaseClassTemplateArgumentsInInstantiation) { @@ -236,4 +252,3 @@ TEST(RecursiveASTVisitor, VisitsBaseClassTemplateArgumentsInInstantiation) {  */  } // end namespace clang -  | 

