Make RecursiveASTVisitor visit lambda capture initialization expressions
authorMartin Bohme <mboehme@google.com>
Mon, 1 Aug 2016 12:15:46 +0000 (12:15 +0000)
committerMartin Bohme <mboehme@google.com>
Mon, 1 Aug 2016 12:15:46 +0000 (12:15 +0000)
Summary:
Lambda capture initializations are part of the explicit source code and
therefore should be visited by default but, so far, RecursiveASTVisitor does not
visit them.

This appears to be an oversight. Because the lambda body needs custom handling
(calling TraverseLambdaBody()), the DEF_TRAVERSE_STMT for LambdaExpr sets
ShouldVisitChildren to false but then neglects to visit the lambda capture
initializations. This patch adds code to visit the expressions associated with
lambda capture initializations.

Reviewers: klimek

Subscribers: cfe-commits

Differential Revision: https://reviews.llvm.org/D22566

llvm-svn: 277342

clang/include/clang/AST/RecursiveASTVisitor.h
clang/unittests/Tooling/RecursiveASTVisitorTestExprVisitor.cpp

index 71d7d19..8c49785 100644 (file)
@@ -2266,6 +2266,9 @@ DEF_TRAVERSE_STMT(LambdaExpr, {
        C != CEnd; ++C) {
     TRY_TO(TraverseLambdaCapture(S, C));
   }
+  for (Expr *Init : S->capture_inits()) {
+    TRY_TO_TRAVERSE_OR_ENQUEUE_STMT(Init);
+  }
 
   TypeLoc TL = S->getCallOperator()->getTypeSourceInfo()->getTypeLoc();
   FunctionProtoTypeLoc Proto = TL.castAs<FunctionProtoTypeLoc>();
index 7b62fc1..d39ca4b 100644 (file)
@@ -191,6 +191,14 @@ TEST(RecursiveASTVisitor, VisitsCallExpr) {
     "void x(); void y() { x(); }"));
 }
 
+TEST(RecursiveASTVisitor, VisitsLambdaCaptureInit) {
+  DeclRefExprVisitor Visitor;
+  Visitor.ExpectMatch("i", 1, 20);
+  EXPECT_TRUE(Visitor.runOver(
+    "void f() { int i; [i]{}; };",
+    DeclRefExprVisitor::Lang_CXX11));
+}
+
 /* FIXME: According to Richard Smith this is a bug in the AST.
 TEST(RecursiveASTVisitor, VisitsBaseClassTemplateArgumentsInInstantiation) {
   DeclRefExprVisitor Visitor;