97 lines · cpp
1//===- unittest/Tooling/RecursiveASTVisitorTests/CXXMemberCall.cpp --------===//2//3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.4// See https://llvm.org/LICENSE.txt for license information.5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception6//7//===----------------------------------------------------------------------===//8 9#include "TestVisitor.h"10 11using namespace clang;12 13namespace {14 15class CXXMemberCallVisitor : public ExpectedLocationVisitor {16public:17 bool VisitCXXMemberCallExpr(CXXMemberCallExpr *Call) override {18 Match(Call->getMethodDecl()->getQualifiedNameAsString(),19 Call->getBeginLoc());20 return true;21 }22};23 24TEST(RecursiveASTVisitor, VisitsCallInTemplateInstantiation) {25 CXXMemberCallVisitor Visitor;26 Visitor.ExpectMatch("Y::x", 3, 3);27 EXPECT_TRUE(Visitor.runOver(28 "struct Y { void x(); };\n"29 "template<typename T> void y(T t) {\n"30 " t.x();\n"31 "}\n"32 "void foo() { y<Y>(Y()); }"));33}34 35TEST(RecursiveASTVisitor, VisitsCallInNestedFunctionTemplateInstantiation) {36 CXXMemberCallVisitor Visitor;37 Visitor.ExpectMatch("Y::x", 4, 5);38 EXPECT_TRUE(Visitor.runOver(39 "struct Y { void x(); };\n"40 "template<typename T> struct Z {\n"41 " template<typename U> static void f() {\n"42 " T().x();\n"43 " }\n"44 "};\n"45 "void foo() { Z<Y>::f<int>(); }"));46}47 48TEST(RecursiveASTVisitor, VisitsCallInNestedClassTemplateInstantiation) {49 CXXMemberCallVisitor Visitor;50 Visitor.ExpectMatch("A::x", 5, 7);51 EXPECT_TRUE(Visitor.runOver(52 "template <typename T1> struct X {\n"53 " template <typename T2> struct Y {\n"54 " void f() {\n"55 " T2 y;\n"56 " y.x();\n"57 " }\n"58 " };\n"59 "};\n"60 "struct A { void x(); };\n"61 "int main() {\n"62 " (new X<A>::Y<A>())->f();\n"63 "}"));64}65 66TEST(RecursiveASTVisitor, VisitsCallInPartialTemplateSpecialization) {67 CXXMemberCallVisitor Visitor;68 Visitor.ExpectMatch("A::x", 6, 20);69 EXPECT_TRUE(Visitor.runOver(70 "template <typename T1> struct X {\n"71 " template <typename T2, bool B> struct Y { void g(); };\n"72 "};\n"73 "template <typename T1> template <typename T2>\n"74 "struct X<T1>::Y<T2, true> {\n"75 " void f() { T2 y; y.x(); }\n"76 "};\n"77 "struct A { void x(); };\n"78 "int main() {\n"79 " (new X<A>::Y<A, true>())->f();\n"80 "}\n"));81}82 83TEST(RecursiveASTVisitor, VisitsExplicitTemplateSpecialization) {84 CXXMemberCallVisitor Visitor;85 Visitor.ExpectMatch("A::f", 4, 5);86 EXPECT_TRUE(Visitor.runOver(87 "struct A {\n"88 " void f() const {}\n"89 " template<class T> void g(const T& t) const {\n"90 " t.f();\n"91 " }\n"92 "};\n"93 "template void A::g(const A& a) const;\n"));94}95 96} // end anonymous namespace97