r307638 - RecursiveASTVisitor should visit the nested name qualifiers in

Alex Lorenz via cfe-commits cfe-commits at lists.llvm.org
Tue Jul 11 02:39:23 PDT 2017


Author: arphaman
Date: Tue Jul 11 02:39:23 2017
New Revision: 307638

URL: http://llvm.org/viewvc/llvm-project?rev=307638&view=rev
Log:
RecursiveASTVisitor should visit the nested name qualifiers in
a template specialisation

rdar://33123354

Differential Revision: https://reviews.llvm.org/D34981

Modified:
    cfe/trunk/include/clang/AST/RecursiveASTVisitor.h
    cfe/trunk/unittests/Tooling/RecursiveASTVisitorTest.cpp

Modified: cfe/trunk/include/clang/AST/RecursiveASTVisitor.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/RecursiveASTVisitor.h?rev=307638&r1=307637&r2=307638&view=diff
==============================================================================
--- cfe/trunk/include/clang/AST/RecursiveASTVisitor.h (original)
+++ cfe/trunk/include/clang/AST/RecursiveASTVisitor.h Tue Jul 11 02:39:23 2017
@@ -1799,6 +1799,7 @@ DEF_TRAVERSE_DECL(CXXRecordDecl, { TRY_T
     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                              \

Modified: cfe/trunk/unittests/Tooling/RecursiveASTVisitorTest.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/unittests/Tooling/RecursiveASTVisitorTest.cpp?rev=307638&r1=307637&r2=307638&view=diff
==============================================================================
--- cfe/trunk/unittests/Tooling/RecursiveASTVisitorTest.cpp (original)
+++ cfe/trunk/unittests/Tooling/RecursiveASTVisitorTest.cpp Tue Jul 11 02:39:23 2017
@@ -244,4 +244,62 @@ TEST(RecursiveASTVisitor, InitListExprIs
                               InitListExprPostOrderNoQueueVisitor::Lang_C));
 }
 
+// Check to ensure that nested name specifiers are visited.
+class NestedNameSpecifiersVisitor
+    : public ExpectedLocationVisitor<NestedNameSpecifiersVisitor> {
+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<typename T, typename U>
+    struct Nested { };
+
+    template<typename T>
+    static T x;
+};
+}
+
+template<>
+struct ns::Outer::Nested<int, int>;
+
+template<>
+struct ns::Outer::Nested<int, int> { };
+
+template<typename T>
+struct ns::Outer::Nested<int, T> { };
+
+template<>
+int ns::Outer::x<int> = 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




More information about the cfe-commits mailing list