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