116 lines · cpp
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-exception6//7//===----------------------------------------------------------------------===//8 9#include "TestVisitor.h"10 11using namespace clang;12 13namespace {14 15class DeclRefExprVisitor : public ExpectedLocationVisitor {16public:17 DeclRefExprVisitor() { ShouldVisitImplicitCode = false; }18 19 bool VisitDeclRefExpr(DeclRefExpr *Reference) override {20 Match(Reference->getNameInfo().getAsString(), Reference->getLocation());21 return true;22 }23};24 25TEST(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 32TEST(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 42TEST(RecursiveASTVisitor, VisitsCallExpr) {43 DeclRefExprVisitor Visitor;44 Visitor.ExpectMatch("x", 1, 22);45 EXPECT_TRUE(Visitor.runOver(46 "void x(); void y() { x(); }"));47}48 49TEST(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 57TEST(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 65TEST(RecursiveASTVisitor, VisitsImplicitLambdaCaptureInit) {66 DeclRefExprVisitor Visitor;67 Visitor.ShouldVisitImplicitCode = true;68 // We're expecting "i" to be visited twice: once for the initialization expr69 // for the captured variable "i" outside of the lambda body, and again for70 // 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 78TEST(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.87TEST(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 98TEST(RecursiveASTVisitor, VisitsExtension) {99 DeclRefExprVisitor Visitor;100 Visitor.ExpectMatch("s", 1, 24);101 EXPECT_TRUE(Visitor.runOver(102 "int s = __extension__ (s);\n"));103}104 105TEST(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 namespace116