1 //===- unittest/Tooling/LookupTest.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 #include "clang/Tooling/Core/Lookup.h" 12 using namespace clang; 13 14 namespace { 15 struct GetDeclsVisitor : TestVisitor<GetDeclsVisitor> { 16 std::function<void(CallExpr *)> OnCall; 17 SmallVector<Decl *, 4> DeclStack; 18 19 bool VisitCallExpr(CallExpr *Expr) { 20 OnCall(Expr); 21 return true; 22 } 23 24 bool TraverseDecl(Decl *D) { 25 DeclStack.push_back(D); 26 bool Ret = TestVisitor::TraverseDecl(D); 27 DeclStack.pop_back(); 28 return Ret; 29 } 30 }; 31 32 TEST(LookupTest, replaceNestedName) { 33 GetDeclsVisitor Visitor; 34 35 auto replaceCallExpr = [&](const CallExpr *Expr, 36 StringRef ReplacementString) { 37 const auto *Callee = cast<DeclRefExpr>(Expr->getCallee()->IgnoreImplicit()); 38 const ValueDecl *FD = Callee->getDecl(); 39 return tooling::replaceNestedName( 40 Callee->getQualifier(), Visitor.DeclStack.back()->getDeclContext(), FD, 41 ReplacementString); 42 }; 43 44 Visitor.OnCall = [&](CallExpr *Expr) { 45 EXPECT_EQ("bar", replaceCallExpr(Expr, "::bar")); 46 }; 47 Visitor.runOver("namespace a { void foo(); }\n" 48 "namespace a { void f() { foo(); } }\n"); 49 50 Visitor.OnCall = [&](CallExpr *Expr) { 51 EXPECT_EQ("bar", replaceCallExpr(Expr, "::a::bar")); 52 }; 53 Visitor.runOver("namespace a { void foo(); }\n" 54 "namespace a { void f() { foo(); } }\n"); 55 56 Visitor.OnCall = [&](CallExpr *Expr) { 57 EXPECT_EQ("a::bar", replaceCallExpr(Expr, "::a::bar")); 58 }; 59 Visitor.runOver("namespace a { void foo(); }\n" 60 "namespace b { void f() { a::foo(); } }\n"); 61 62 Visitor.OnCall = [&](CallExpr *Expr) { 63 EXPECT_EQ("a::bar", replaceCallExpr(Expr, "::a::bar")); 64 }; 65 Visitor.runOver("namespace a { void foo(); }\n" 66 "namespace b { namespace a { void foo(); }\n" 67 "void f() { a::foo(); } }\n"); 68 69 Visitor.OnCall = [&](CallExpr *Expr) { 70 EXPECT_EQ("c::bar", replaceCallExpr(Expr, "::a::c::bar")); 71 }; 72 Visitor.runOver("namespace a { namespace b { void foo(); }\n" 73 "void f() { b::foo(); } }\n"); 74 75 Visitor.OnCall = [&](CallExpr *Expr) { 76 EXPECT_EQ("bar", replaceCallExpr(Expr, "::a::bar")); 77 }; 78 Visitor.runOver("namespace a { namespace b { void foo(); }\n" 79 "void f() { b::foo(); } }\n"); 80 81 Visitor.OnCall = [&](CallExpr *Expr) { 82 EXPECT_EQ("bar", replaceCallExpr(Expr, "::bar")); 83 }; 84 Visitor.runOver("void foo(); void f() { foo(); }\n"); 85 86 Visitor.OnCall = [&](CallExpr *Expr) { 87 EXPECT_EQ("::bar", replaceCallExpr(Expr, "::bar")); 88 }; 89 Visitor.runOver("void foo(); void f() { ::foo(); }\n"); 90 91 Visitor.OnCall = [&](CallExpr *Expr) { 92 EXPECT_EQ("a::bar", replaceCallExpr(Expr, "::a::bar")); 93 }; 94 Visitor.runOver("namespace a { void foo(); }\nvoid f() { a::foo(); }\n"); 95 96 Visitor.OnCall = [&](CallExpr *Expr) { 97 EXPECT_EQ("a::bar", replaceCallExpr(Expr, "::a::bar")); 98 }; 99 Visitor.runOver("namespace a { int foo(); }\nauto f = a::foo();\n"); 100 101 Visitor.OnCall = [&](CallExpr *Expr) { 102 EXPECT_EQ("bar", replaceCallExpr(Expr, "::a::bar")); 103 }; 104 Visitor.runOver( 105 "namespace a { int foo(); }\nusing a::foo;\nauto f = foo();\n"); 106 } 107 108 } // end anonymous namespace 109