1 //===- unittest/Tooling/RecursiveASTVisitorTests/NestedNameSpecifiers.cpp -===// 2 // 3 // The LLVM Compiler Infrastructure 4 // 5 // This file is distributed under the University of Illinois Open Source 6 // License. See LICENSE.TXT for details. 7 // 8 //===----------------------------------------------------------------------===// 9 10 #include "TestVisitor.h" 11 12 using namespace clang; 13 14 namespace { 15 16 // Check to ensure that nested name specifiers are visited. 17 class NestedNameSpecifiersVisitor 18 : public ExpectedLocationVisitor<NestedNameSpecifiersVisitor> { 19 public: 20 bool VisitRecordTypeLoc(RecordTypeLoc RTL) { 21 if (!RTL) 22 return true; 23 Match(RTL.getDecl()->getName(), RTL.getNameLoc()); 24 return true; 25 } 26 27 bool TraverseNestedNameSpecifierLoc(NestedNameSpecifierLoc NNS) { 28 if (!NNS) 29 return true; 30 if (const NamespaceDecl *ND = 31 NNS.getNestedNameSpecifier()->getAsNamespace()) 32 Match(ND->getName(), NNS.getLocalBeginLoc()); 33 return ExpectedLocationVisitor::TraverseNestedNameSpecifierLoc(NNS); 34 } 35 }; 36 37 TEST(RecursiveASTVisitor, 38 NestedNameSpecifiersForTemplateSpecializationsAreVisited) { 39 StringRef Source = R"( 40 namespace ns { 41 struct Outer { 42 template<typename T, typename U> 43 struct Nested { }; 44 45 template<typename T> 46 static T x; 47 }; 48 } 49 50 template<> 51 struct ns::Outer::Nested<int, int>; 52 53 template<> 54 struct ns::Outer::Nested<int, int> { }; 55 56 template<typename T> 57 struct ns::Outer::Nested<int, T> { }; 58 59 template<> 60 int ns::Outer::x<int> = 0; 61 )"; 62 NestedNameSpecifiersVisitor Visitor; 63 Visitor.ExpectMatch("ns", 13, 8); 64 Visitor.ExpectMatch("ns", 16, 8); 65 Visitor.ExpectMatch("ns", 19, 8); 66 Visitor.ExpectMatch("ns", 22, 5); 67 Visitor.ExpectMatch("Outer", 13, 12); 68 Visitor.ExpectMatch("Outer", 16, 12); 69 Visitor.ExpectMatch("Outer", 19, 12); 70 Visitor.ExpectMatch("Outer", 22, 9); 71 EXPECT_TRUE(Visitor.runOver(Source, NestedNameSpecifiersVisitor::Lang_CXX14)); 72 } 73 74 } // end anonymous namespace 75