RecursiveASTVisitorTest.cpp 4.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137
  1. //===- unittest/Tooling/RecursiveASTVisitorTest.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 LambdaExprVisitor : public ExpectedLocationVisitor<LambdaExprVisitor> {
  14. public:
  15. bool VisitLambdaExpr(LambdaExpr *Lambda) {
  16. PendingBodies.push(Lambda);
  17. Match("", Lambda->getIntroducerRange().getBegin());
  18. return true;
  19. }
  20. /// For each call to VisitLambdaExpr, we expect a subsequent call (with
  21. /// proper nesting) to TraverseLambdaBody.
  22. bool TraverseLambdaBody(LambdaExpr *Lambda) {
  23. EXPECT_FALSE(PendingBodies.empty());
  24. EXPECT_EQ(PendingBodies.top(), Lambda);
  25. PendingBodies.pop();
  26. return TraverseStmt(Lambda->getBody());
  27. }
  28. /// Determine whether TraverseLambdaBody has been called for every call to
  29. /// VisitLambdaExpr.
  30. bool allBodiesHaveBeenTraversed() const {
  31. return PendingBodies.empty();
  32. }
  33. private:
  34. std::stack<LambdaExpr *> PendingBodies;
  35. };
  36. TEST(RecursiveASTVisitor, VisitsLambdaExpr) {
  37. LambdaExprVisitor Visitor;
  38. Visitor.ExpectMatch("", 1, 12);
  39. EXPECT_TRUE(Visitor.runOver("void f() { []{ return; }(); }",
  40. LambdaExprVisitor::Lang_CXX11));
  41. }
  42. TEST(RecursiveASTVisitor, TraverseLambdaBodyCanBeOverridden) {
  43. LambdaExprVisitor Visitor;
  44. EXPECT_TRUE(Visitor.runOver("void f() { []{ return; }(); }",
  45. LambdaExprVisitor::Lang_CXX11));
  46. EXPECT_TRUE(Visitor.allBodiesHaveBeenTraversed());
  47. }
  48. // Matches the (optional) capture-default of a lambda-introducer.
  49. class LambdaDefaultCaptureVisitor
  50. : public ExpectedLocationVisitor<LambdaDefaultCaptureVisitor> {
  51. public:
  52. bool VisitLambdaExpr(LambdaExpr *Lambda) {
  53. if (Lambda->getCaptureDefault() != LCD_None) {
  54. Match("", Lambda->getCaptureDefaultLoc());
  55. }
  56. return true;
  57. }
  58. };
  59. TEST(RecursiveASTVisitor, HasCaptureDefaultLoc) {
  60. LambdaDefaultCaptureVisitor Visitor;
  61. Visitor.ExpectMatch("", 1, 20);
  62. EXPECT_TRUE(Visitor.runOver("void f() { int a; [=]{a;}; }",
  63. LambdaDefaultCaptureVisitor::Lang_CXX11));
  64. }
  65. // Checks for lambda classes that are not marked as implicitly-generated.
  66. // (There should be none.)
  67. class ClassVisitor : public ExpectedLocationVisitor<ClassVisitor> {
  68. public:
  69. ClassVisitor() : SawNonImplicitLambdaClass(false) {}
  70. bool VisitCXXRecordDecl(CXXRecordDecl* record) {
  71. if (record->isLambda() && !record->isImplicit())
  72. SawNonImplicitLambdaClass = true;
  73. return true;
  74. }
  75. bool sawOnlyImplicitLambdaClasses() const {
  76. return !SawNonImplicitLambdaClass;
  77. }
  78. private:
  79. bool SawNonImplicitLambdaClass;
  80. };
  81. TEST(RecursiveASTVisitor, LambdaClosureTypesAreImplicit) {
  82. ClassVisitor Visitor;
  83. EXPECT_TRUE(Visitor.runOver("auto lambda = []{};",
  84. ClassVisitor::Lang_CXX11));
  85. EXPECT_TRUE(Visitor.sawOnlyImplicitLambdaClasses());
  86. }
  87. // Check to ensure that attributes and expressions within them are being
  88. // visited.
  89. class AttrVisitor : public ExpectedLocationVisitor<AttrVisitor> {
  90. public:
  91. bool VisitMemberExpr(MemberExpr *ME) {
  92. Match(ME->getMemberDecl()->getNameAsString(), ME->getLocStart());
  93. return true;
  94. }
  95. bool VisitAttr(Attr *A) {
  96. Match("Attr", A->getLocation());
  97. return true;
  98. }
  99. bool VisitGuardedByAttr(GuardedByAttr *A) {
  100. Match("guarded_by", A->getLocation());
  101. return true;
  102. }
  103. };
  104. TEST(RecursiveASTVisitor, AttributesAreVisited) {
  105. AttrVisitor Visitor;
  106. Visitor.ExpectMatch("Attr", 4, 24);
  107. Visitor.ExpectMatch("guarded_by", 4, 24);
  108. Visitor.ExpectMatch("mu1", 4, 35);
  109. Visitor.ExpectMatch("Attr", 5, 29);
  110. Visitor.ExpectMatch("mu1", 5, 54);
  111. Visitor.ExpectMatch("mu2", 5, 59);
  112. EXPECT_TRUE(Visitor.runOver(
  113. "class Foo {\n"
  114. " int mu1;\n"
  115. " int mu2;\n"
  116. " int a __attribute__((guarded_by(mu1)));\n"
  117. " void bar() __attribute__((exclusive_locks_required(mu1, mu2)));\n"
  118. "};\n"));
  119. }
  120. } // end anonymous namespace