Home | History | Annotate | Download | only in Tooling
      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