1 //===- 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 12 using namespace clang; 13 14 namespace { 15 16 class DeclRefExprVisitor : public ExpectedLocationVisitor<DeclRefExprVisitor> { 17 public: 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 31 private: 32 bool ShouldVisitImplicitCode; 33 }; 34 35 TEST(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 42 TEST(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 52 TEST(RecursiveASTVisitor, VisitsCallExpr) { 53 DeclRefExprVisitor Visitor; 54 Visitor.ExpectMatch("x", 1, 22); 55 EXPECT_TRUE(Visitor.runOver( 56 "void x(); void y() { x(); }")); 57 } 58 59 TEST(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 67 TEST(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 75 TEST(RecursiveASTVisitor, VisitsImplicitLambdaCaptureInit) { 76 DeclRefExprVisitor Visitor; 77 Visitor.setShouldVisitImplicitCode(true); 78 // We're expecting "i" to be visited twice: once for the initialization expr 79 // for the captured variable "i" outside of the lambda body, and again for 80 // the use of "i" inside the lambda. 81 Visitor.ExpectMatch("i", 1, 20, /*Times=*/1); 82 Visitor.ExpectMatch("i", 1, 24, /*Times=*/1); 83 EXPECT_TRUE(Visitor.runOver( 84 "void f() { int i; [=]{ i; }; }", 85 DeclRefExprVisitor::Lang_CXX11)); 86 } 87 88 TEST(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. 97 TEST(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 108 TEST(RecursiveASTVisitor, VisitsExtension) { 109 DeclRefExprVisitor Visitor; 110 Visitor.ExpectMatch("s", 1, 24); 111 EXPECT_TRUE(Visitor.runOver( 112 "int s = __extension__ (s);\n")); 113 } 114 115 TEST(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 126