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