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