RecursiveASTVisitorTestDeclVisitor.cpp 4.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139
  1. //===- unittest/Tooling/RecursiveASTVisitorTestDeclVisitor.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 VarDeclVisitor : public ExpectedLocationVisitor<VarDeclVisitor> {
  12. public:
  13. bool VisitVarDecl(VarDecl *Variable) {
  14. Match(Variable->getNameAsString(), Variable->getBeginLoc());
  15. return true;
  16. }
  17. };
  18. TEST(RecursiveASTVisitor, VisitsCXXForRangeStmtLoopVariable) {
  19. VarDeclVisitor Visitor;
  20. Visitor.ExpectMatch("i", 2, 17);
  21. EXPECT_TRUE(Visitor.runOver(
  22. "int x[5];\n"
  23. "void f() { for (int i : x) {} }",
  24. VarDeclVisitor::Lang_CXX11));
  25. }
  26. class ParmVarDeclVisitorForImplicitCode :
  27. public ExpectedLocationVisitor<ParmVarDeclVisitorForImplicitCode> {
  28. public:
  29. bool shouldVisitImplicitCode() const { return true; }
  30. bool VisitParmVarDecl(ParmVarDecl *ParamVar) {
  31. Match(ParamVar->getNameAsString(), ParamVar->getBeginLoc());
  32. return true;
  33. }
  34. };
  35. // Test RAV visits parameter variable declaration of the implicit
  36. // copy assignment operator and implicit copy constructor.
  37. TEST(RecursiveASTVisitor, VisitsParmVarDeclForImplicitCode) {
  38. ParmVarDeclVisitorForImplicitCode Visitor;
  39. // Match parameter variable name of implicit copy assignment operator and
  40. // implicit copy constructor.
  41. // This parameter name does not have a valid IdentifierInfo, and shares
  42. // same SourceLocation with its class declaration, so we match an empty name
  43. // with the class' source location.
  44. Visitor.ExpectMatch("", 1, 7);
  45. Visitor.ExpectMatch("", 3, 7);
  46. EXPECT_TRUE(Visitor.runOver(
  47. "class X {};\n"
  48. "void foo(X a, X b) {a = b;}\n"
  49. "class Y {};\n"
  50. "void bar(Y a) {Y b = a;}"));
  51. }
  52. class NamedDeclVisitor
  53. : public ExpectedLocationVisitor<NamedDeclVisitor> {
  54. public:
  55. bool VisitNamedDecl(NamedDecl *Decl) {
  56. std::string NameWithTemplateArgs;
  57. llvm::raw_string_ostream OS(NameWithTemplateArgs);
  58. Decl->getNameForDiagnostic(OS,
  59. Decl->getASTContext().getPrintingPolicy(),
  60. true);
  61. Match(OS.str(), Decl->getLocation());
  62. return true;
  63. }
  64. };
  65. TEST(RecursiveASTVisitor, VisitsPartialTemplateSpecialization) {
  66. // From cfe-commits/Week-of-Mon-20100830/033998.html
  67. // Contrary to the approach suggested in that email, we visit all
  68. // specializations when we visit the primary template. Visiting them when we
  69. // visit the associated specialization is problematic for specializations of
  70. // template members of class templates.
  71. NamedDeclVisitor Visitor;
  72. Visitor.ExpectMatch("A<bool>", 1, 26);
  73. Visitor.ExpectMatch("A<char *>", 2, 26);
  74. EXPECT_TRUE(Visitor.runOver(
  75. "template <class T> class A {};\n"
  76. "template <class T> class A<T*> {};\n"
  77. "A<bool> ab;\n"
  78. "A<char*> acp;\n"));
  79. }
  80. TEST(RecursiveASTVisitor, VisitsUndefinedClassTemplateSpecialization) {
  81. NamedDeclVisitor Visitor;
  82. Visitor.ExpectMatch("A<int>", 1, 29);
  83. EXPECT_TRUE(Visitor.runOver(
  84. "template<typename T> struct A;\n"
  85. "A<int> *p;\n"));
  86. }
  87. TEST(RecursiveASTVisitor, VisitsNestedUndefinedClassTemplateSpecialization) {
  88. NamedDeclVisitor Visitor;
  89. Visitor.ExpectMatch("A<int>::B<char>", 2, 31);
  90. EXPECT_TRUE(Visitor.runOver(
  91. "template<typename T> struct A {\n"
  92. " template<typename U> struct B;\n"
  93. "};\n"
  94. "A<int>::B<char> *p;\n"));
  95. }
  96. TEST(RecursiveASTVisitor, VisitsUndefinedFunctionTemplateSpecialization) {
  97. NamedDeclVisitor Visitor;
  98. Visitor.ExpectMatch("A<int>", 1, 26);
  99. EXPECT_TRUE(Visitor.runOver(
  100. "template<typename T> int A();\n"
  101. "int k = A<int>();\n"));
  102. }
  103. TEST(RecursiveASTVisitor, VisitsNestedUndefinedFunctionTemplateSpecialization) {
  104. NamedDeclVisitor Visitor;
  105. Visitor.ExpectMatch("A<int>::B<char>", 2, 35);
  106. EXPECT_TRUE(Visitor.runOver(
  107. "template<typename T> struct A {\n"
  108. " template<typename U> static int B();\n"
  109. "};\n"
  110. "int k = A<int>::B<char>();\n"));
  111. }
  112. TEST(RecursiveASTVisitor, NoRecursionInSelfFriend) {
  113. // From cfe-commits/Week-of-Mon-20100830/033977.html
  114. NamedDeclVisitor Visitor;
  115. Visitor.ExpectMatch("vector_iterator<int>", 2, 7);
  116. EXPECT_TRUE(Visitor.runOver(
  117. "template<typename Container>\n"
  118. "class vector_iterator {\n"
  119. " template <typename C> friend class vector_iterator;\n"
  120. "};\n"
  121. "vector_iterator<int> it_int;\n"));
  122. }
  123. } // end anonymous namespace