blob: d847a298fff23dd8590ba225ca3a19be4ddc4083 [file] [log] [blame]
Benjamin Kramer9bccaa12015-10-22 15:04:10 +00001//===- 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"
12using namespace clang;
13
14namespace {
15struct 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
32TEST(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