CXXMemberCall.cpp 2.7 KB

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