[PATCH] D34981: RecursiveASTVisitor should visit the nested name qualifiers in a template specialisation
This revision was automatically updated to reflect the committed changes. arphaman marked an inline comment as done. Closed by commit rL307638: RecursiveASTVisitor should visit the nested name qualifiers in (authored by arphaman). Changed prior to commit: https://reviews.llvm.org/D34981?vs=105167=105982#toc Repository: rL LLVM https://reviews.llvm.org/D34981 Files: cfe/trunk/include/clang/AST/RecursiveASTVisitor.h cfe/trunk/unittests/Tooling/RecursiveASTVisitorTest.cpp Index: cfe/trunk/unittests/Tooling/RecursiveASTVisitorTest.cpp === --- cfe/trunk/unittests/Tooling/RecursiveASTVisitorTest.cpp +++ cfe/trunk/unittests/Tooling/RecursiveASTVisitorTest.cpp @@ -244,4 +244,62 @@ InitListExprPostOrderNoQueueVisitor::Lang_C)); } +// Check to ensure that nested name specifiers are visited. +class NestedNameSpecifiersVisitor +: public ExpectedLocationVisitor { +public: + bool VisitRecordTypeLoc(RecordTypeLoc RTL) { +if (!RTL) + return true; +Match(RTL.getDecl()->getName(), RTL.getNameLoc()); +return true; + } + + bool TraverseNestedNameSpecifierLoc(NestedNameSpecifierLoc NNS) { +if (!NNS) + return true; +if (const NamespaceDecl *ND = +NNS.getNestedNameSpecifier()->getAsNamespace()) + Match(ND->getName(), NNS.getLocalBeginLoc()); +return ExpectedLocationVisitor::TraverseNestedNameSpecifierLoc(NNS); + } +}; + +TEST(RecursiveASTVisitor, + NestedNameSpecifiersForTemplateSpecializationsAreVisited) { + StringRef Source = R"( +namespace ns { +struct Outer { +template +struct Nested { }; + +template +static T x; +}; +} + +template<> +struct ns::Outer::Nested; + +template<> +struct ns::Outer::Nested { }; + +template +struct ns::Outer::Nested { }; + +template<> +int ns::Outer::x = 0; +)"; + NestedNameSpecifiersVisitor Visitor; + Visitor.ExpectMatch("ns", 13, 8); + Visitor.ExpectMatch("ns", 16, 8); + Visitor.ExpectMatch("ns", 19, 8); + Visitor.ExpectMatch("ns", 22, 5); + Visitor.ExpectMatch("Outer", 13, 12); + Visitor.ExpectMatch("Outer", 16, 12); + Visitor.ExpectMatch("Outer", 19, 12); + Visitor.ExpectMatch("Outer", 22, 9); + EXPECT_TRUE(Visitor.runOver(Source, NestedNameSpecifiersVisitor::Lang_CXX14)); +} + } // end anonymous namespace Index: cfe/trunk/include/clang/AST/RecursiveASTVisitor.h === --- cfe/trunk/include/clang/AST/RecursiveASTVisitor.h +++ cfe/trunk/include/clang/AST/RecursiveASTVisitor.h @@ -1799,6 +1799,7 @@ if (TypeSourceInfo *TSI = D->getTypeAsWritten()) \ TRY_TO(TraverseTypeLoc(TSI->getTypeLoc())); \ \ +TRY_TO(TraverseNestedNameSpecifierLoc(D->getQualifierLoc())); \ if (!getDerived().shouldVisitTemplateInstantiations() && \ D->getTemplateSpecializationKind() != TSK_ExplicitSpecialization) \ /* Returning from here skips traversing the \ Index: cfe/trunk/unittests/Tooling/RecursiveASTVisitorTest.cpp === --- cfe/trunk/unittests/Tooling/RecursiveASTVisitorTest.cpp +++ cfe/trunk/unittests/Tooling/RecursiveASTVisitorTest.cpp @@ -244,4 +244,62 @@ InitListExprPostOrderNoQueueVisitor::Lang_C)); } +// Check to ensure that nested name specifiers are visited. +class NestedNameSpecifiersVisitor +: public ExpectedLocationVisitor { +public: + bool VisitRecordTypeLoc(RecordTypeLoc RTL) { +if (!RTL) + return true; +Match(RTL.getDecl()->getName(), RTL.getNameLoc()); +return true; + } + + bool TraverseNestedNameSpecifierLoc(NestedNameSpecifierLoc NNS) { +if (!NNS) + return true; +if (const NamespaceDecl *ND = +NNS.getNestedNameSpecifier()->getAsNamespace()) + Match(ND->getName(), NNS.getLocalBeginLoc()); +return ExpectedLocationVisitor::TraverseNestedNameSpecifierLoc(NNS); + } +}; + +TEST(RecursiveASTVisitor, + NestedNameSpecifiersForTemplateSpecializationsAreVisited) { + StringRef Source = R"( +namespace ns { +struct Outer { +template +struct Nested { }; + +template +static T x; +}; +} + +template<> +struct ns::Outer::Nested ; + +template<> +struct ns::Outer::Nested { }; + +template +struct ns::Outer::Nested { }; + +template<> +int ns::Outer::x = 0; +)"; + NestedNameSpecifiersVisitor Visitor; + Visitor.ExpectMatch("ns", 13, 8); + Visitor.ExpectMatch("ns", 16, 8); + Visitor.ExpectMatch("ns", 19, 8); + Visitor.ExpectMatch("ns", 22, 5); + Visitor.ExpectMatch("Outer", 13, 12); + Visitor.ExpectMatch("Outer", 16, 12); + Visitor.ExpectMatch("Outer", 19, 12); + Visitor.ExpectMatch("Outer",
[PATCH] D34981: RecursiveASTVisitor should visit the nested name qualifiers in a template specialisation
vsk accepted this revision. vsk added a comment. This revision is now accepted and ready to land. I haven't touched any AST code but this looks good to me: it's in line with what's done in TraverseRecordHelper and the test case is comprehensive. Comment at: unittests/Tooling/RecursiveASTVisitorTest.cpp:269 +TEST(RecursiveASTVisitor, + NestedNameSpecifiersForTemplateSpecializatoinsAreVisited) { + StringRef Source = R"( Nit, 'specializations' Repository: rL LLVM https://reviews.llvm.org/D34981 ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[PATCH] D34981: RecursiveASTVisitor should visit the nested name qualifiers in a template specialisation
arphaman created this revision. Right now because of this issue rename cannot be initiated at name qualifiers in a template specialisation, e.g.: struct Outer { template struct Nested { }; }; template<> struct Outer::Nested; // Rename cannot be initiated at 'Outer' because the NNSL is not visited by the RecursiveASTVisitor Repository: rL LLVM https://reviews.llvm.org/D34981 Files: include/clang/AST/RecursiveASTVisitor.h unittests/Tooling/RecursiveASTVisitorTest.cpp Index: unittests/Tooling/RecursiveASTVisitorTest.cpp === --- unittests/Tooling/RecursiveASTVisitorTest.cpp +++ unittests/Tooling/RecursiveASTVisitorTest.cpp @@ -244,4 +244,62 @@ InitListExprPostOrderNoQueueVisitor::Lang_C)); } +// Check to ensure that nested name specifiers are visited. +class NestedNameSpecifiersVisitor +: public ExpectedLocationVisitor { +public: + bool VisitRecordTypeLoc(RecordTypeLoc RTL) { +if (!RTL) + return true; +Match(RTL.getDecl()->getName(), RTL.getNameLoc()); +return true; + } + + bool TraverseNestedNameSpecifierLoc(NestedNameSpecifierLoc NNS) { +if (!NNS) + return true; +if (const NamespaceDecl *ND = +NNS.getNestedNameSpecifier()->getAsNamespace()) + Match(ND->getName(), NNS.getLocalBeginLoc()); +return ExpectedLocationVisitor::TraverseNestedNameSpecifierLoc(NNS); + } +}; + +TEST(RecursiveASTVisitor, + NestedNameSpecifiersForTemplateSpecializatoinsAreVisited) { + StringRef Source = R"( +namespace ns { +struct Outer { +template +struct Nested { }; + +template +static T x; +}; +} + +template<> +struct ns::Outer::Nested; + +template<> +struct ns::Outer::Nested { }; + +template +struct ns::Outer::Nested { }; + +template<> +int ns::Outer::x = 0; +)"; + NestedNameSpecifiersVisitor Visitor; + Visitor.ExpectMatch("ns", 13, 8); + Visitor.ExpectMatch("ns", 16, 8); + Visitor.ExpectMatch("ns", 19, 8); + Visitor.ExpectMatch("ns", 22, 5); + Visitor.ExpectMatch("Outer", 13, 12); + Visitor.ExpectMatch("Outer", 16, 12); + Visitor.ExpectMatch("Outer", 19, 12); + Visitor.ExpectMatch("Outer", 22, 9); + EXPECT_TRUE(Visitor.runOver(Source, NestedNameSpecifiersVisitor::Lang_CXX14)); +} + } // end anonymous namespace Index: include/clang/AST/RecursiveASTVisitor.h === --- include/clang/AST/RecursiveASTVisitor.h +++ include/clang/AST/RecursiveASTVisitor.h @@ -1799,6 +1799,7 @@ if (TypeSourceInfo *TSI = D->getTypeAsWritten()) \ TRY_TO(TraverseTypeLoc(TSI->getTypeLoc())); \ \ +TRY_TO(TraverseNestedNameSpecifierLoc(D->getQualifierLoc())); \ if (!getDerived().shouldVisitTemplateInstantiations() && \ D->getTemplateSpecializationKind() != TSK_ExplicitSpecialization) \ /* Returning from here skips traversing the \ Index: unittests/Tooling/RecursiveASTVisitorTest.cpp === --- unittests/Tooling/RecursiveASTVisitorTest.cpp +++ unittests/Tooling/RecursiveASTVisitorTest.cpp @@ -244,4 +244,62 @@ InitListExprPostOrderNoQueueVisitor::Lang_C)); } +// Check to ensure that nested name specifiers are visited. +class NestedNameSpecifiersVisitor +: public ExpectedLocationVisitor { +public: + bool VisitRecordTypeLoc(RecordTypeLoc RTL) { +if (!RTL) + return true; +Match(RTL.getDecl()->getName(), RTL.getNameLoc()); +return true; + } + + bool TraverseNestedNameSpecifierLoc(NestedNameSpecifierLoc NNS) { +if (!NNS) + return true; +if (const NamespaceDecl *ND = +NNS.getNestedNameSpecifier()->getAsNamespace()) + Match(ND->getName(), NNS.getLocalBeginLoc()); +return ExpectedLocationVisitor::TraverseNestedNameSpecifierLoc(NNS); + } +}; + +TEST(RecursiveASTVisitor, + NestedNameSpecifiersForTemplateSpecializatoinsAreVisited) { + StringRef Source = R"( +namespace ns { +struct Outer { +template +struct Nested { }; + +template +static T x; +}; +} + +template<> +struct ns::Outer::Nested ; + +template<> +struct ns::Outer::Nested { }; + +template +struct ns::Outer::Nested { }; + +template<> +int ns::Outer::x = 0; +)"; + NestedNameSpecifiersVisitor Visitor; + Visitor.ExpectMatch("ns", 13, 8); + Visitor.ExpectMatch("ns", 16, 8); + Visitor.ExpectMatch("ns", 19, 8); + Visitor.ExpectMatch("ns", 22, 5); + Visitor.ExpectMatch("Outer", 13, 12); + Visitor.ExpectMatch("Outer", 16, 12); + Visitor.ExpectMatch("Outer", 19, 12); + Visitor.ExpectMatch("Outer", 22, 9); + EXPECT_TRUE(Visitor.runOver(Source,