mboehme created this revision.
mboehme added a reviewer: klimek.
mboehme added a subscriber: cfe-commits.
Herald added a subscriber: klimek.

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.

https://reviews.llvm.org/D22566

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

Index: unittests/Tooling/RecursiveASTVisitorTestExprVisitor.cpp
===================================================================
--- unittests/Tooling/RecursiveASTVisitorTestExprVisitor.cpp
+++ unittests/Tooling/RecursiveASTVisitorTestExprVisitor.cpp
@@ -191,6 +191,14 @@
     "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;
Index: include/clang/AST/RecursiveASTVisitor.h
===================================================================
--- include/clang/AST/RecursiveASTVisitor.h
+++ include/clang/AST/RecursiveASTVisitor.h
@@ -2254,6 +2254,9 @@
        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: unittests/Tooling/RecursiveASTVisitorTestExprVisitor.cpp
===================================================================
--- unittests/Tooling/RecursiveASTVisitorTestExprVisitor.cpp
+++ unittests/Tooling/RecursiveASTVisitorTestExprVisitor.cpp
@@ -191,6 +191,14 @@
     "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;
Index: include/clang/AST/RecursiveASTVisitor.h
===================================================================
--- include/clang/AST/RecursiveASTVisitor.h
+++ include/clang/AST/RecursiveASTVisitor.h
@@ -2254,6 +2254,9 @@
        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>();
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to