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