diff options
Diffstat (limited to 'unittests/Tooling/RecursiveASTVisitorTests')
9 files changed, 110 insertions, 25 deletions
diff --git a/unittests/Tooling/RecursiveASTVisitorTests/Attr.cpp b/unittests/Tooling/RecursiveASTVisitorTests/Attr.cpp index a6ba92ea03b5..33163c30e5d0 100644 --- a/unittests/Tooling/RecursiveASTVisitorTests/Attr.cpp +++ b/unittests/Tooling/RecursiveASTVisitorTests/Attr.cpp @@ -18,7 +18,7 @@ namespace { class AttrVisitor : public ExpectedLocationVisitor<AttrVisitor> { public: bool VisitMemberExpr(MemberExpr *ME) { - Match(ME->getMemberDecl()->getNameAsString(), ME->getLocStart()); + Match(ME->getMemberDecl()->getNameAsString(), ME->getBeginLoc()); return true; } bool VisitAttr(Attr *A) { diff --git a/unittests/Tooling/RecursiveASTVisitorTests/CXXMemberCall.cpp b/unittests/Tooling/RecursiveASTVisitorTests/CXXMemberCall.cpp index 8a979204b847..a83e55137ad7 100644 --- a/unittests/Tooling/RecursiveASTVisitorTests/CXXMemberCall.cpp +++ b/unittests/Tooling/RecursiveASTVisitorTests/CXXMemberCall.cpp @@ -18,7 +18,7 @@ class CXXMemberCallVisitor public: bool VisitCXXMemberCallExpr(CXXMemberCallExpr *Call) { Match(Call->getMethodDecl()->getQualifiedNameAsString(), - Call->getLocStart()); + Call->getBeginLoc()); return true; } }; diff --git a/unittests/Tooling/RecursiveASTVisitorTests/DeclRefExpr.cpp b/unittests/Tooling/RecursiveASTVisitorTests/DeclRefExpr.cpp index 67640486efb6..cd0e4260a8bc 100644 --- a/unittests/Tooling/RecursiveASTVisitorTests/DeclRefExpr.cpp +++ b/unittests/Tooling/RecursiveASTVisitorTests/DeclRefExpr.cpp @@ -75,11 +75,11 @@ TEST(RecursiveASTVisitor, VisitsUseOfImplicitLambdaCapture) { TEST(RecursiveASTVisitor, VisitsImplicitLambdaCaptureInit) { DeclRefExprVisitor Visitor; Visitor.setShouldVisitImplicitCode(true); - // We're expecting the "i" in the lambda to be visited twice: - // - Once for the DeclRefExpr in the lambda capture initialization (whose - // source code location is set to the first use of the variable). - // - Once for the DeclRefExpr for the use of "i" inside the lambda. - Visitor.ExpectMatch("i", 1, 24, /*Times=*/2); + // We're expecting "i" to be visited twice: once for the initialization expr + // for the captured variable "i" outside of the lambda body, and again for + // the use of "i" inside the lambda. + Visitor.ExpectMatch("i", 1, 20, /*Times=*/1); + Visitor.ExpectMatch("i", 1, 24, /*Times=*/1); EXPECT_TRUE(Visitor.runOver( "void f() { int i; [=]{ i; }; }", DeclRefExprVisitor::Lang_CXX11)); diff --git a/unittests/Tooling/RecursiveASTVisitorTests/InitListExprPostOrder.cpp b/unittests/Tooling/RecursiveASTVisitorTests/InitListExprPostOrder.cpp index 420b49aa1b14..396f25de5c5d 100644 --- a/unittests/Tooling/RecursiveASTVisitorTests/InitListExprPostOrder.cpp +++ b/unittests/Tooling/RecursiveASTVisitorTests/InitListExprPostOrder.cpp @@ -19,7 +19,7 @@ public: bool shouldTraversePostOrder() const { return true; } bool VisitInitListExpr(InitListExpr *ILE) { - Match(ILE->isSemanticForm() ? "semantic" : "syntactic", ILE->getLocStart()); + Match(ILE->isSemanticForm() ? "semantic" : "syntactic", ILE->getBeginLoc()); return true; } }; diff --git a/unittests/Tooling/RecursiveASTVisitorTests/InitListExprPostOrderNoQueue.cpp b/unittests/Tooling/RecursiveASTVisitorTests/InitListExprPostOrderNoQueue.cpp index f9d5ef69e098..587f84bb430a 100644 --- a/unittests/Tooling/RecursiveASTVisitorTests/InitListExprPostOrderNoQueue.cpp +++ b/unittests/Tooling/RecursiveASTVisitorTests/InitListExprPostOrderNoQueue.cpp @@ -23,7 +23,7 @@ public: } bool VisitInitListExpr(InitListExpr *ILE) { - Match(ILE->isSemanticForm() ? "semantic" : "syntactic", ILE->getLocStart()); + Match(ILE->isSemanticForm() ? "semantic" : "syntactic", ILE->getBeginLoc()); return true; } }; diff --git a/unittests/Tooling/RecursiveASTVisitorTests/InitListExprPreOrder.cpp b/unittests/Tooling/RecursiveASTVisitorTests/InitListExprPreOrder.cpp index f2036e232c01..01f6e1902916 100644 --- a/unittests/Tooling/RecursiveASTVisitorTests/InitListExprPreOrder.cpp +++ b/unittests/Tooling/RecursiveASTVisitorTests/InitListExprPreOrder.cpp @@ -19,7 +19,7 @@ class InitListExprPreOrderVisitor : public ExpectedLocationVisitor<InitListExprPreOrderVisitor> { public: bool VisitInitListExpr(InitListExpr *ILE) { - Match(ILE->isSemanticForm() ? "semantic" : "syntactic", ILE->getLocStart()); + Match(ILE->isSemanticForm() ? "semantic" : "syntactic", ILE->getBeginLoc()); return true; } }; diff --git a/unittests/Tooling/RecursiveASTVisitorTests/InitListExprPreOrderNoQueue.cpp b/unittests/Tooling/RecursiveASTVisitorTests/InitListExprPreOrderNoQueue.cpp index 064cd74390b4..d48b5a89c824 100644 --- a/unittests/Tooling/RecursiveASTVisitorTests/InitListExprPreOrderNoQueue.cpp +++ b/unittests/Tooling/RecursiveASTVisitorTests/InitListExprPreOrderNoQueue.cpp @@ -21,7 +21,7 @@ public: } bool VisitInitListExpr(InitListExpr *ILE) { - Match(ILE->isSemanticForm() ? "semantic" : "syntactic", ILE->getLocStart()); + Match(ILE->isSemanticForm() ? "semantic" : "syntactic", ILE->getBeginLoc()); return true; } }; diff --git a/unittests/Tooling/RecursiveASTVisitorTests/LambdaExpr.cpp b/unittests/Tooling/RecursiveASTVisitorTests/LambdaExpr.cpp index 80aeb43528c4..d3a3eba15d16 100644 --- a/unittests/Tooling/RecursiveASTVisitorTests/LambdaExpr.cpp +++ b/unittests/Tooling/RecursiveASTVisitorTests/LambdaExpr.cpp @@ -17,25 +17,33 @@ namespace { class LambdaExprVisitor : public ExpectedLocationVisitor<LambdaExprVisitor> { public: bool VisitLambdaExpr(LambdaExpr *Lambda) { - PendingBodies.push(Lambda); + PendingBodies.push(Lambda->getBody()); + PendingClasses.push(Lambda->getLambdaClass()); 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()); + /// For each call to VisitLambdaExpr, we expect a subsequent call to visit + /// the body (and maybe the lambda class, which is implicit). + bool VisitStmt(Stmt *S) { + if (!PendingBodies.empty() && S == PendingBodies.top()) + PendingBodies.pop(); + return true; } - /// Determine whether TraverseLambdaBody has been called for every call to - /// VisitLambdaExpr. - bool allBodiesHaveBeenTraversed() const { - return PendingBodies.empty(); + bool VisitDecl(Decl *D) { + if (!PendingClasses.empty() && D == PendingClasses.top()) + PendingClasses.pop(); + return true; } + /// Determine whether parts of lambdas (VisitLambdaExpr) were later traversed. + bool allBodiesHaveBeenTraversed() const { return PendingBodies.empty(); } + bool allClassesHaveBeenTraversed() const { return PendingClasses.empty(); } + + bool VisitImplicitCode = false; + bool shouldVisitImplicitCode() const { return VisitImplicitCode; } + private: - std::stack<LambdaExpr *> PendingBodies; + std::stack<Stmt *> PendingBodies; + std::stack<Decl *> PendingClasses; }; TEST(RecursiveASTVisitor, VisitsLambdaExpr) { @@ -43,13 +51,39 @@ TEST(RecursiveASTVisitor, VisitsLambdaExpr) { Visitor.ExpectMatch("", 1, 12); EXPECT_TRUE(Visitor.runOver("void f() { []{ return; }(); }", LambdaExprVisitor::Lang_CXX11)); + EXPECT_TRUE(Visitor.allBodiesHaveBeenTraversed()); + EXPECT_FALSE(Visitor.allClassesHaveBeenTraversed()); } -TEST(RecursiveASTVisitor, TraverseLambdaBodyCanBeOverridden) { +TEST(RecursiveASTVisitor, LambdaInLambda) { LambdaExprVisitor Visitor; + Visitor.ExpectMatch("", 1, 12); + Visitor.ExpectMatch("", 1, 16); + EXPECT_TRUE(Visitor.runOver("void f() { []{ []{ return; }; }(); }", + LambdaExprVisitor::Lang_CXX11)); + EXPECT_TRUE(Visitor.allBodiesHaveBeenTraversed()); + EXPECT_FALSE(Visitor.allClassesHaveBeenTraversed()); +} + +TEST(RecursiveASTVisitor, TopLevelLambda) { + LambdaExprVisitor Visitor; + Visitor.VisitImplicitCode = true; + Visitor.ExpectMatch("", 1, 10); + Visitor.ExpectMatch("", 1, 14); + EXPECT_TRUE(Visitor.runOver("auto x = []{ [] {}; };", + LambdaExprVisitor::Lang_CXX11)); + EXPECT_TRUE(Visitor.allBodiesHaveBeenTraversed()); + EXPECT_TRUE(Visitor.allClassesHaveBeenTraversed()); +} + +TEST(RecursiveASTVisitor, VisitsLambdaExprAndImplicitClass) { + LambdaExprVisitor Visitor; + Visitor.VisitImplicitCode = true; + Visitor.ExpectMatch("", 1, 12); EXPECT_TRUE(Visitor.runOver("void f() { []{ return; }(); }", LambdaExprVisitor::Lang_CXX11)); EXPECT_TRUE(Visitor.allBodiesHaveBeenTraversed()); + EXPECT_TRUE(Visitor.allClassesHaveBeenTraversed()); } TEST(RecursiveASTVisitor, VisitsAttributedLambdaExpr) { diff --git a/unittests/Tooling/RecursiveASTVisitorTests/TraversalScope.cpp b/unittests/Tooling/RecursiveASTVisitorTests/TraversalScope.cpp new file mode 100644 index 000000000000..72f6c644b388 --- /dev/null +++ b/unittests/Tooling/RecursiveASTVisitorTests/TraversalScope.cpp @@ -0,0 +1,51 @@ +//===- unittest/Tooling/RecursiveASTVisitorTests/TraversalScope.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" + +using namespace clang; + +namespace { + +class Visitor : public ExpectedLocationVisitor<Visitor, clang::TestVisitor> { +public: + Visitor(ASTContext *Context) { this->Context = Context; } + + bool VisitNamedDecl(NamedDecl *D) { + if (!D->isImplicit()) + Match(D->getName(), D->getLocation()); + return true; + } +}; + +TEST(RecursiveASTVisitor, RespectsTraversalScope) { + auto AST = tooling::buildASTFromCode( + R"cpp( +struct foo { + struct bar { + struct baz {}; + }; +}; + )cpp", + "foo.cpp", std::make_shared<PCHContainerOperations>()); + auto &Ctx = AST->getASTContext(); + auto &TU = *Ctx.getTranslationUnitDecl(); + auto &Foo = *TU.lookup(&Ctx.Idents.get("foo")).front(); + auto &Bar = *cast<DeclContext>(Foo).lookup(&Ctx.Idents.get("bar")).front(); + + Ctx.setTraversalScope({&Bar}); + + Visitor V(&Ctx); + V.DisallowMatch("foo", 2, 8); + V.ExpectMatch("bar", 3, 10); + V.ExpectMatch("baz", 4, 12); + V.TraverseAST(Ctx); +} + +} // end anonymous namespace |
