1 //===- unittest/Tooling/RecursiveASTVisitorTests/CXXMemberCall.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->getBeginLoc()); 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 } // end anonymous namespace 99