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(Name: RTL.getDecl()->getName(), Location: 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(Name: ND->getName(), Location: 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 | |