//===- unittest/Tooling/RecursiveASTVisitorTests/CXXMemberCall.cpp --------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// #include "TestVisitor.h" using namespace clang; namespace { class CXXMemberCallVisitor : public ExpectedLocationVisitor { public: bool VisitCXXMemberCallExpr(CXXMemberCallExpr *Call) { Match(Call->getMethodDecl()->getQualifiedNameAsString(), Call->getBeginLoc()); return true; } }; TEST(RecursiveASTVisitor, VisitsCallInTemplateInstantiation) { CXXMemberCallVisitor Visitor; Visitor.ExpectMatch("Y::x", 3, 3); EXPECT_TRUE(Visitor.runOver( "struct Y { void x(); };\n" "template void y(T t) {\n" " t.x();\n" "}\n" "void foo() { y(Y()); }")); } TEST(RecursiveASTVisitor, VisitsCallInNestedFunctionTemplateInstantiation) { CXXMemberCallVisitor Visitor; Visitor.ExpectMatch("Y::x", 4, 5); EXPECT_TRUE(Visitor.runOver( "struct Y { void x(); };\n" "template struct Z {\n" " template static void f() {\n" " T().x();\n" " }\n" "};\n" "void foo() { Z::f(); }")); } TEST(RecursiveASTVisitor, VisitsCallInNestedClassTemplateInstantiation) { CXXMemberCallVisitor Visitor; Visitor.ExpectMatch("A::x", 5, 7); EXPECT_TRUE(Visitor.runOver( "template struct X {\n" " template struct Y {\n" " void f() {\n" " T2 y;\n" " y.x();\n" " }\n" " };\n" "};\n" "struct A { void x(); };\n" "int main() {\n" " (new X::Y())->f();\n" "}")); } TEST(RecursiveASTVisitor, VisitsCallInPartialTemplateSpecialization) { CXXMemberCallVisitor Visitor; Visitor.ExpectMatch("A::x", 6, 20); EXPECT_TRUE(Visitor.runOver( "template struct X {\n" " template struct Y { void g(); };\n" "};\n" "template template \n" "struct X::Y {\n" " void f() { T2 y; y.x(); }\n" "};\n" "struct A { void x(); };\n" "int main() {\n" " (new X::Y())->f();\n" "}\n")); } TEST(RecursiveASTVisitor, VisitsExplicitTemplateSpecialization) { CXXMemberCallVisitor Visitor; Visitor.ExpectMatch("A::f", 4, 5); EXPECT_TRUE(Visitor.runOver( "struct A {\n" " void f() const {}\n" " template void g(const T& t) const {\n" " t.f();\n" " }\n" "};\n" "template void A::g(const A& a) const;\n")); } } // end anonymous namespace