Clang Project

clang_source_code/unittests/Tooling/RecursiveASTVisitorTests/CXXMemberCall.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-exception
6//
7//===----------------------------------------------------------------------===//
8
9#include "TestVisitor.h"
10
11using namespace clang;
12
13namespace {
14
15class CXXMemberCallVisitor
16  : public ExpectedLocationVisitor<CXXMemberCallVisitor> {
17public:
18  bool VisitCXXMemberCallExpr(CXXMemberCallExpr *Call) {
19    Match(Call->getMethodDecl()->getQualifiedNameAsString(),
20          Call->getBeginLoc());
21    return true;
22  }
23};
24
25TEST(RecursiveASTVisitor, VisitsCallInTemplateInstantiation) {
26  CXXMemberCallVisitor Visitor;
27  Visitor.ExpectMatch("Y::x"33);
28  EXPECT_TRUE(Visitor.runOver(
29    "struct Y { void x(); };\n"
30    "template<typename T> void y(T t) {\n"
31    "  t.x();\n"
32    "}\n"
33    "void foo() { y<Y>(Y()); }"));
34}
35
36TEST(RecursiveASTVisitor, VisitsCallInNestedFunctionTemplateInstantiation) {
37  CXXMemberCallVisitor Visitor;
38  Visitor.ExpectMatch("Y::x"45);
39  EXPECT_TRUE(Visitor.runOver(
40    "struct Y { void x(); };\n"
41    "template<typename T> struct Z {\n"
42    "  template<typename U> static void f() {\n"
43    "    T().x();\n"
44    "  }\n"
45    "};\n"
46    "void foo() { Z<Y>::f<int>(); }"));
47}
48
49TEST(RecursiveASTVisitor, VisitsCallInNestedClassTemplateInstantiation) {
50  CXXMemberCallVisitor Visitor;
51  Visitor.ExpectMatch("A::x"57);
52  EXPECT_TRUE(Visitor.runOver(
53    "template <typename T1> struct X {\n"
54    "  template <typename T2> struct Y {\n"
55    "    void f() {\n"
56    "      T2 y;\n"
57    "      y.x();\n"
58    "    }\n"
59    "  };\n"
60    "};\n"
61    "struct A { void x(); };\n"
62    "int main() {\n"
63    "  (new X<A>::Y<A>())->f();\n"
64    "}"));
65}
66
67TEST(RecursiveASTVisitor, VisitsCallInPartialTemplateSpecialization) {
68  CXXMemberCallVisitor Visitor;
69  Visitor.ExpectMatch("A::x"620);
70  EXPECT_TRUE(Visitor.runOver(
71    "template <typename T1> struct X {\n"
72    "  template <typename T2, bool B> struct Y { void g(); };\n"
73    "};\n"
74    "template <typename T1> template <typename T2>\n"
75    "struct X<T1>::Y<T2, true> {\n"
76    "  void f() { T2 y; y.x(); }\n"
77    "};\n"
78    "struct A { void x(); };\n"
79    "int main() {\n"
80    "  (new X<A>::Y<A, true>())->f();\n"
81    "}\n"));
82}
83
84TEST(RecursiveASTVisitor, VisitsExplicitTemplateSpecialization) {
85  CXXMemberCallVisitor Visitor;
86  Visitor.ExpectMatch("A::f"45);
87  EXPECT_TRUE(Visitor.runOver(
88    "struct A {\n"
89    "  void f() const {}\n"
90    "  template<class T> void g(const T& t) const {\n"
91    "    t.f();\n"
92    "  }\n"
93    "};\n"
94    "template void A::g(const A& a) const;\n"));
95}
96
97// end anonymous namespace
98