| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137 |
- //===- unittest/Tooling/RecursiveASTVisitorTest.cpp -----------------------===//
- //
- // The LLVM Compiler Infrastructure
- //
- // This file is distributed under the University of Illinois Open Source
- // License. See LICENSE.TXT for details.
- //
- //===----------------------------------------------------------------------===//
- #include "TestVisitor.h"
- #include <stack>
- using namespace clang;
- namespace {
- class LambdaExprVisitor : public ExpectedLocationVisitor<LambdaExprVisitor> {
- public:
- bool VisitLambdaExpr(LambdaExpr *Lambda) {
- PendingBodies.push(Lambda);
- Match("", Lambda->getIntroducerRange().getBegin());
- return true;
- }
- /// For each call to VisitLambdaExpr, we expect a subsequent call (with
- /// proper nesting) to TraverseLambdaBody.
- bool TraverseLambdaBody(LambdaExpr *Lambda) {
- EXPECT_FALSE(PendingBodies.empty());
- EXPECT_EQ(PendingBodies.top(), Lambda);
- PendingBodies.pop();
- return TraverseStmt(Lambda->getBody());
- }
- /// Determine whether TraverseLambdaBody has been called for every call to
- /// VisitLambdaExpr.
- bool allBodiesHaveBeenTraversed() const {
- return PendingBodies.empty();
- }
- private:
- std::stack<LambdaExpr *> PendingBodies;
- };
- TEST(RecursiveASTVisitor, VisitsLambdaExpr) {
- LambdaExprVisitor Visitor;
- Visitor.ExpectMatch("", 1, 12);
- EXPECT_TRUE(Visitor.runOver("void f() { []{ return; }(); }",
- LambdaExprVisitor::Lang_CXX11));
- }
- TEST(RecursiveASTVisitor, TraverseLambdaBodyCanBeOverridden) {
- LambdaExprVisitor Visitor;
- EXPECT_TRUE(Visitor.runOver("void f() { []{ return; }(); }",
- LambdaExprVisitor::Lang_CXX11));
- EXPECT_TRUE(Visitor.allBodiesHaveBeenTraversed());
- }
- // Matches the (optional) capture-default of a lambda-introducer.
- class LambdaDefaultCaptureVisitor
- : public ExpectedLocationVisitor<LambdaDefaultCaptureVisitor> {
- public:
- bool VisitLambdaExpr(LambdaExpr *Lambda) {
- if (Lambda->getCaptureDefault() != LCD_None) {
- Match("", Lambda->getCaptureDefaultLoc());
- }
- return true;
- }
- };
- TEST(RecursiveASTVisitor, HasCaptureDefaultLoc) {
- LambdaDefaultCaptureVisitor Visitor;
- Visitor.ExpectMatch("", 1, 20);
- EXPECT_TRUE(Visitor.runOver("void f() { int a; [=]{a;}; }",
- LambdaDefaultCaptureVisitor::Lang_CXX11));
- }
- // Checks for lambda classes that are not marked as implicitly-generated.
- // (There should be none.)
- class ClassVisitor : public ExpectedLocationVisitor<ClassVisitor> {
- public:
- ClassVisitor() : SawNonImplicitLambdaClass(false) {}
- bool VisitCXXRecordDecl(CXXRecordDecl* record) {
- if (record->isLambda() && !record->isImplicit())
- SawNonImplicitLambdaClass = true;
- return true;
- }
- bool sawOnlyImplicitLambdaClasses() const {
- return !SawNonImplicitLambdaClass;
- }
- private:
- bool SawNonImplicitLambdaClass;
- };
- TEST(RecursiveASTVisitor, LambdaClosureTypesAreImplicit) {
- ClassVisitor Visitor;
- EXPECT_TRUE(Visitor.runOver("auto lambda = []{};",
- ClassVisitor::Lang_CXX11));
- EXPECT_TRUE(Visitor.sawOnlyImplicitLambdaClasses());
- }
- // Check to ensure that attributes and expressions within them are being
- // visited.
- class AttrVisitor : public ExpectedLocationVisitor<AttrVisitor> {
- public:
- bool VisitMemberExpr(MemberExpr *ME) {
- Match(ME->getMemberDecl()->getNameAsString(), ME->getLocStart());
- return true;
- }
- bool VisitAttr(Attr *A) {
- Match("Attr", A->getLocation());
- return true;
- }
- bool VisitGuardedByAttr(GuardedByAttr *A) {
- Match("guarded_by", A->getLocation());
- return true;
- }
- };
- TEST(RecursiveASTVisitor, AttributesAreVisited) {
- AttrVisitor Visitor;
- Visitor.ExpectMatch("Attr", 4, 24);
- Visitor.ExpectMatch("guarded_by", 4, 24);
- Visitor.ExpectMatch("mu1", 4, 35);
- Visitor.ExpectMatch("Attr", 5, 29);
- Visitor.ExpectMatch("mu1", 5, 54);
- Visitor.ExpectMatch("mu2", 5, 59);
- EXPECT_TRUE(Visitor.runOver(
- "class Foo {\n"
- " int mu1;\n"
- " int mu2;\n"
- " int a __attribute__((guarded_by(mu1)));\n"
- " void bar() __attribute__((exclusive_locks_required(mu1, mu2)));\n"
- "};\n"));
- }
- } // end anonymous namespace
|