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 : public ExpectedLocationVisitor { 17 public: 18 bool VisitRecordTypeLoc(RecordTypeLoc RTL) override { 19 if (!RTL) 20 return true; 21 Match(RTL.getDecl()->getName(), RTL.getNameLoc()); 22 return true; 23 } 24 25 bool TraverseNestedNameSpecifierLoc(NestedNameSpecifierLoc NNS) override { 26 if (!NNS) 27 return true; 28 if (const NamespaceDecl *ND = 29 NNS.getNestedNameSpecifier()->getAsNamespace()) 30 Match(ND->getName(), NNS.getLocalBeginLoc()); 31 return ExpectedLocationVisitor::TraverseNestedNameSpecifierLoc(NNS); 32 } 33 }; 34 35 TEST(RecursiveASTVisitor, 36 NestedNameSpecifiersForTemplateSpecializationsAreVisited) { 37 StringRef Source = R"( 38 namespace ns { 39 struct Outer { 40 template<typename T, typename U> 41 struct Nested { }; 42 43 template<typename T> 44 static T x; 45 }; 46 } 47 48 template<> 49 struct ns::Outer::Nested<int, int>; 50 51 template<> 52 struct ns::Outer::Nested<int, int> { }; 53 54 template<typename T> 55 struct ns::Outer::Nested<int, T> { }; 56 57 template<> 58 int ns::Outer::x<int> = 0; 59 )"; 60 NestedNameSpecifiersVisitor Visitor; 61 Visitor.ExpectMatch("ns", 13, 8); 62 Visitor.ExpectMatch("ns", 16, 8); 63 Visitor.ExpectMatch("ns", 19, 8); 64 Visitor.ExpectMatch("ns", 22, 5); 65 Visitor.ExpectMatch("Outer", 13, 12); 66 Visitor.ExpectMatch("Outer", 16, 12); 67 Visitor.ExpectMatch("Outer", 19, 12); 68 Visitor.ExpectMatch("Outer", 22, 9); 69 EXPECT_TRUE(Visitor.runOver(Source, NestedNameSpecifiersVisitor::Lang_CXX14)); 70 } 71 72 } // end anonymous namespace 73