summaryrefslogtreecommitdiffstats
path: root/clang/unittests/Tooling/RecursiveASTVisitorTest.cpp
diff options
context:
space:
mode:
authorJames Dennett <jdennett@google.com>2013-07-10 18:29:15 +0000
committerJames Dennett <jdennett@google.com>2013-07-10 18:29:15 +0000
commit86e67a2fc40860f081f87537bcf55c2faaf1b942 (patch)
tree446eae63e83e06be4d6a0f12b5ef5c55536694b2 /clang/unittests/Tooling/RecursiveASTVisitorTest.cpp
parente602fe1e7f3ff443ee3529fca5872f69688a7f43 (diff)
downloadbcm5719-llvm-86e67a2fc40860f081f87537bcf55c2faaf1b942.tar.gz
bcm5719-llvm-86e67a2fc40860f081f87537bcf55c2faaf1b942.zip
Add a hook RecursiveASTVisitor::TraverseLambdaBody, to enable visitors to
use/maintain additional state from the LambdaExpr while visiting the body of a LambdaExpr. One use for this arises because Clang's AST currently holds lambda bodies in a form prior to their adjustment to refer to captured copies of local variables, and so some clients will need access to the lambda's closure type in order to query how to map VarDecl*s to the FieldDecls of their by-copy captures. This hook is sufficient for at least one such client; to do this without such a hook would require the client to re-implement the whole of TraverseLambdaExpr, which is non-trivial and would likely be more brittle. llvm-svn: 186024
Diffstat (limited to 'clang/unittests/Tooling/RecursiveASTVisitorTest.cpp')
-rw-r--r--clang/unittests/Tooling/RecursiveASTVisitorTest.cpp25
1 files changed, 25 insertions, 0 deletions
diff --git a/clang/unittests/Tooling/RecursiveASTVisitorTest.cpp b/clang/unittests/Tooling/RecursiveASTVisitorTest.cpp
index 2d226fddfc4..c97ee0c8c47 100644
--- a/clang/unittests/Tooling/RecursiveASTVisitorTest.cpp
+++ b/clang/unittests/Tooling/RecursiveASTVisitorTest.cpp
@@ -9,6 +9,8 @@
#include "TestVisitor.h"
+#include <stack>
+
namespace clang {
class TypeLocVisitor : public ExpectedLocationVisitor<TypeLocVisitor> {
@@ -82,9 +84,25 @@ public:
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;
};
class TemplateArgumentLocTraverser
@@ -478,4 +496,11 @@ TEST(RecursiveASTVisitor, VisitsLambdaExpr) {
LambdaExprVisitor::Lang_CXX11));
}
+TEST(RecursiveASTVisitor, TraverseLambdaBodyCanBeOverridden) {
+ LambdaExprVisitor Visitor;
+ EXPECT_TRUE(Visitor.runOver("void f() { []{ return; }(); }",
+ LambdaExprVisitor::Lang_CXX11));
+ EXPECT_TRUE(Visitor.allBodiesHaveBeenTraversed());
+}
+
} // end namespace clang
OpenPOWER on IntegriCloud