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