[PATCH] Tune capturing of init-captures in non-generic lambdas

Richard Smith richard at metafoo.co.uk
Wed Nov 20 15:13:11 PST 2013



================
Comment at: lib/Parse/ParseExprCXX.cpp:690-693
@@ +689,6 @@
+  {
+    // Each lambda init-capture forms its own full expression, which clears
+    // MaybeODRUseExprs. So create an expression evaluation context to save
+    // the necessary state, and restore it later.
+    EnterExpressionEvaluationContext EC(Actions, Sema::PotentiallyEvaluated);
+    DiagID = ParseLambdaIntroducer(Intro);
----------------
Can you put this in `ParseLambdaIntroducer` instead of in all its callers?

================
Comment at: lib/Parse/ParseExprCXX.cpp:747
@@ +746,3 @@
+    if (TryParseLambdaIntroducer(Intro)) {
+      performLambdaInitCaptureInitializations(Intro, Actions);
+      return ExprEmpty();
----------------
We shouldn't do this if `TryParseLambdaIntroducer` failed. It's not actually a lambda, so we don't have any init-captures.

================
Comment at: lib/Parse/ParseExprCXX.cpp:638-643
@@ +637,8 @@
+    // out argument.
+    Expr *Init = C->Init.get();
+    // This performs any lvalue-to-rvalue conversions if necessary, which 
+    // can affect what gets captured in the containing decl-context.
+    C->InitCaptureType.set(Actions.performLambdaInitCaptureInitialization(
+        C->Loc, C->Kind == LCK_ByRef, C->Id, Init));
+    C->Init = Init;  
+  }
----------------
Why do we need to defer this, rather than doing it in `ParseLambdaIntroducer`?

================
Comment at: lib/Sema/SemaExprCXX.cpp:5947-5948
@@ -5939,1 +5946,4 @@
+  // }
+  if (!IsLambdaInitCaptureInitializer && 
+      DiagnoseUnexpandedParameterPack(FullExpr.get()))
     return ExprError();
----------------
This feels like a hack: I'd be happier if we pushed the lambda scope when we parse the lambda introducer, and teach capturing (but not unexpanded pack detection) to walk over LambdaScopeInfos which don't have a corresponding class yet (that is, have LambdaScopeInfo either represent a lambda where we've entered the introducer but not the body, or represent a lambda where we've entered the body, depending on where the parser/instantiation has got to).

That said, we can revisit this post-3.4. Please add a FIXME.

================
Comment at: lib/Sema/SemaLambda.cpp:660-673
@@ +659,16 @@
+  QualType DeducedType;
+  if (DeduceAutoType(TSI, DeduceInit, DeducedType) ==
+        DAR_Failed) {
+    if (isa<InitListExpr>(Init))
+      Diag(Loc, diag::err_init_capture_deduction_failure_from_init_list)
+      << DeclarationName(Id) << (DeduceInit->getType().isNull() 
+          ? TSI->getType() : DeduceInit->getType())
+          << DeduceInit->getSourceRange();
+    else
+      Diag(Loc, diag::err_init_capture_deduction_failure) 
+          << DeclarationName(Id) << TSI->getType() << 
+          (DeduceInit->getType().isNull() 
+              ? TSI->getType() : DeduceInit->getType())
+          << DeduceInit->getSourceRange();
+  }
+  if (DeducedType.isNull()) 
----------------
Please clang-format this.

================
Comment at: lib/Sema/SemaLambda.cpp:713
@@ +712,3 @@
+
+VarDecl *Sema::createLambdaInitCaptureDummyVariable(SourceLocation Loc, 
+    QualType InitCaptureType, IdentifierInfo *Id, Expr *Init) {
----------------
Maybe just `createLambdaInitCaptureVarDecl`?

================
Comment at: lib/Sema/TreeTransform.h:596
@@ -595,3 +595,3 @@
   ExprResult TransformCXXNamedCastExpr(CXXNamedCastExpr *E);
-
+  typedef std::pair<ExprResult, QualType> ExprAndQualTypePairTy;
   /// \brief Transform the captures and body of a lambda expression.
----------------
Please give this a more meaningful name, maybe `InitCaptureInfo`.

================
Comment at: lib/Sema/TreeTransform.h:8279-8281
@@ -8277,2 +8278,5 @@
 TreeTransform<Derived>::TransformLambdaExpr(LambdaExpr *E) {
  
+  // Transform any init-capture expressions before entering the scope of the
+  // lambda to avoid confusing tryCaptureVar during the transformation.
+  SmallVector<ExprAndQualTypePairTy, 8> InitCaptureExprsAndTypes;
----------------
Please use a more semantic-level comment (rather than explaining what particular bug you're avoiding). Something like, "Transform any init-capture expressions before entering the scope of the lambda body, because they are not semantically within that scope."


http://llvm-reviews.chandlerc.com/D2092



More information about the cfe-commits mailing list