Home | History | Annotate | Download | only in Tooling
      1 //===- unittest/Tooling/RecursiveASTVisitorTestCallVisitor.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 <stack>
     12 
     13 using namespace clang;
     14 
     15 namespace {
     16 
     17 class CXXMemberCallVisitor
     18   : public ExpectedLocationVisitor<CXXMemberCallVisitor> {
     19 public:
     20   bool VisitCXXMemberCallExpr(CXXMemberCallExpr *Call) {
     21     Match(Call->getMethodDecl()->getQualifiedNameAsString(),
     22           Call->getLocStart());
     23     return true;
     24   }
     25 };
     26 
     27 TEST(RecursiveASTVisitor, VisitsCallInTemplateInstantiation) {
     28   CXXMemberCallVisitor Visitor;
     29   Visitor.ExpectMatch("Y::x", 3, 3);
     30   EXPECT_TRUE(Visitor.runOver(
     31     "struct Y { void x(); };\n"
     32     "template<typename T> void y(T t) {\n"
     33     "  t.x();\n"
     34     "}\n"
     35     "void foo() { y<Y>(Y()); }"));
     36 }
     37 
     38 TEST(RecursiveASTVisitor, VisitsCallInNestedFunctionTemplateInstantiation) {
     39   CXXMemberCallVisitor Visitor;
     40   Visitor.ExpectMatch("Y::x", 4, 5);
     41   EXPECT_TRUE(Visitor.runOver(
     42     "struct Y { void x(); };\n"
     43     "template<typename T> struct Z {\n"
     44     "  template<typename U> static void f() {\n"
     45     "    T().x();\n"
     46     "  }\n"
     47     "};\n"
     48     "void foo() { Z<Y>::f<int>(); }"));
     49 }
     50 
     51 TEST(RecursiveASTVisitor, VisitsCallInNestedClassTemplateInstantiation) {
     52   CXXMemberCallVisitor Visitor;
     53   Visitor.ExpectMatch("A::x", 5, 7);
     54   EXPECT_TRUE(Visitor.runOver(
     55     "template <typename T1> struct X {\n"
     56     "  template <typename T2> struct Y {\n"
     57     "    void f() {\n"
     58     "      T2 y;\n"
     59     "      y.x();\n"
     60     "    }\n"
     61     "  };\n"
     62     "};\n"
     63     "struct A { void x(); };\n"
     64     "int main() {\n"
     65     "  (new X<A>::Y<A>())->f();\n"
     66     "}"));
     67 }
     68 
     69 TEST(RecursiveASTVisitor, VisitsCallInPartialTemplateSpecialization) {
     70   CXXMemberCallVisitor Visitor;
     71   Visitor.ExpectMatch("A::x", 6, 20);
     72   EXPECT_TRUE(Visitor.runOver(
     73     "template <typename T1> struct X {\n"
     74     "  template <typename T2, bool B> struct Y { void g(); };\n"
     75     "};\n"
     76     "template <typename T1> template <typename T2>\n"
     77     "struct X<T1>::Y<T2, true> {\n"
     78     "  void f() { T2 y; y.x(); }\n"
     79     "};\n"
     80     "struct A { void x(); };\n"
     81     "int main() {\n"
     82     "  (new X<A>::Y<A, true>())->f();\n"
     83     "}\n"));
     84 }
     85 
     86 TEST(RecursiveASTVisitor, VisitsExplicitTemplateSpecialization) {
     87   CXXMemberCallVisitor Visitor;
     88   Visitor.ExpectMatch("A::f", 4, 5);
     89   EXPECT_TRUE(Visitor.runOver(
     90     "struct A {\n"
     91     "  void f() const {}\n"
     92     "  template<class T> void g(const T& t) const {\n"
     93     "    t.f();\n"
     94     "  }\n"
     95     "};\n"
     96     "template void A::g(const A& a) const;\n"));
     97 }
     98 
     99 class CXXOperatorCallExprTraverser
    100   : public ExpectedLocationVisitor<CXXOperatorCallExprTraverser> {
    101 public:
    102   // Use Traverse, not Visit, to check that data recursion optimization isn't
    103   // bypassing the call of this function.
    104   bool TraverseCXXOperatorCallExpr(CXXOperatorCallExpr *CE) {
    105     Match(getOperatorSpelling(CE->getOperator()), CE->getExprLoc());
    106     return ExpectedLocationVisitor<CXXOperatorCallExprTraverser>::
    107         TraverseCXXOperatorCallExpr(CE);
    108   }
    109 };
    110 
    111 TEST(RecursiveASTVisitor, TraversesOverloadedOperator) {
    112   CXXOperatorCallExprTraverser Visitor;
    113   Visitor.ExpectMatch("()", 4, 9);
    114   EXPECT_TRUE(Visitor.runOver(
    115     "struct A {\n"
    116     "  int operator()();\n"
    117     "} a;\n"
    118     "int k = a();\n"));
    119 }
    120 
    121 } // end anonymous namespace
    122