RecursiveASTVisitorTestDeclVisitor.cpp 4.5 KB

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