1 | //===- unittest/Tooling/RecursiveASTVisitorTests/DeclRefExpr.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 | class DeclRefExprVisitor : public ExpectedLocationVisitor { |
16 | public: |
17 | DeclRefExprVisitor() { ShouldVisitImplicitCode = false; } |
18 | |
19 | bool VisitDeclRefExpr(DeclRefExpr *Reference) override { |
20 | Match(Reference->getNameInfo().getAsString(), Reference->getLocation()); |
21 | return true; |
22 | } |
23 | }; |
24 | |
25 | TEST(RecursiveASTVisitor, VisitsBaseClassTemplateArguments) { |
26 | DeclRefExprVisitor Visitor; |
27 | Visitor.ExpectMatch("x" , 2, 3); |
28 | EXPECT_TRUE(Visitor.runOver( |
29 | "void x(); template <void (*T)()> class X {};\nX<x> y;" )); |
30 | } |
31 | |
32 | TEST(RecursiveASTVisitor, VisitsCXXForRangeStmtRange) { |
33 | DeclRefExprVisitor Visitor; |
34 | Visitor.ExpectMatch("x" , 2, 25); |
35 | Visitor.ExpectMatch("x" , 2, 30); |
36 | EXPECT_TRUE(Visitor.runOver( |
37 | "int x[5];\n" |
38 | "void f() { for (int i : x) { x[0] = 1; } }" , |
39 | DeclRefExprVisitor::Lang_CXX11)); |
40 | } |
41 | |
42 | TEST(RecursiveASTVisitor, VisitsCallExpr) { |
43 | DeclRefExprVisitor Visitor; |
44 | Visitor.ExpectMatch("x" , 1, 22); |
45 | EXPECT_TRUE(Visitor.runOver( |
46 | "void x(); void y() { x(); }" )); |
47 | } |
48 | |
49 | TEST(RecursiveASTVisitor, VisitsExplicitLambdaCaptureInit) { |
50 | DeclRefExprVisitor Visitor; |
51 | Visitor.ExpectMatch("i" , 1, 20); |
52 | EXPECT_TRUE(Visitor.runOver( |
53 | "void f() { int i; [i]{}; }" , |
54 | DeclRefExprVisitor::Lang_CXX11)); |
55 | } |
56 | |
57 | TEST(RecursiveASTVisitor, VisitsUseOfImplicitLambdaCapture) { |
58 | DeclRefExprVisitor Visitor; |
59 | Visitor.ExpectMatch("i" , 1, 24); |
60 | EXPECT_TRUE(Visitor.runOver( |
61 | "void f() { int i; [=]{ i; }; }" , |
62 | DeclRefExprVisitor::Lang_CXX11)); |
63 | } |
64 | |
65 | TEST(RecursiveASTVisitor, VisitsImplicitLambdaCaptureInit) { |
66 | DeclRefExprVisitor Visitor; |
67 | Visitor.ShouldVisitImplicitCode = true; |
68 | // We're expecting "i" to be visited twice: once for the initialization expr |
69 | // for the captured variable "i" outside of the lambda body, and again for |
70 | // the use of "i" inside the lambda. |
71 | Visitor.ExpectMatch("i" , 1, 20, /*Times=*/1); |
72 | Visitor.ExpectMatch("i" , 1, 24, /*Times=*/1); |
73 | EXPECT_TRUE(Visitor.runOver( |
74 | "void f() { int i; [=]{ i; }; }" , |
75 | DeclRefExprVisitor::Lang_CXX11)); |
76 | } |
77 | |
78 | TEST(RecursiveASTVisitor, VisitsLambdaInitCaptureInit) { |
79 | DeclRefExprVisitor Visitor; |
80 | Visitor.ExpectMatch("i" , 1, 24); |
81 | EXPECT_TRUE(Visitor.runOver( |
82 | "void f() { int i; [a = i + 1]{}; }" , |
83 | DeclRefExprVisitor::Lang_CXX14)); |
84 | } |
85 | |
86 | /* FIXME: According to Richard Smith this is a bug in the AST. |
87 | TEST(RecursiveASTVisitor, VisitsBaseClassTemplateArgumentsInInstantiation) { |
88 | DeclRefExprVisitor Visitor; |
89 | Visitor.ExpectMatch("x", 3, 43); |
90 | EXPECT_TRUE(Visitor.runOver( |
91 | "template <typename T> void x();\n" |
92 | "template <void (*T)()> class X {};\n" |
93 | "template <typename T> class Y : public X< x<T> > {};\n" |
94 | "Y<int> y;")); |
95 | } |
96 | */ |
97 | |
98 | TEST(RecursiveASTVisitor, VisitsExtension) { |
99 | DeclRefExprVisitor Visitor; |
100 | Visitor.ExpectMatch("s" , 1, 24); |
101 | EXPECT_TRUE(Visitor.runOver( |
102 | "int s = __extension__ (s);\n" )); |
103 | } |
104 | |
105 | TEST(RecursiveASTVisitor, VisitsCopyExprOfBlockDeclCapture) { |
106 | DeclRefExprVisitor Visitor; |
107 | Visitor.ExpectMatch("x" , 3, 24); |
108 | EXPECT_TRUE(Visitor.runOver("void f(int(^)(int)); \n" |
109 | "void g() { \n" |
110 | " f([&](int x){ return x; }); \n" |
111 | "}" , |
112 | DeclRefExprVisitor::Lang_OBJCXX11)); |
113 | } |
114 | |
115 | } // end anonymous namespace |
116 | |