[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