First pass of semantic analysis for init-captures: check the initializer, build
a FieldDecl from it, and propagate both into the closure type and the
LambdaExpr.
You can't do much useful with them yet -- you can't use them within the body
of the lambda, because we don't have a representation for "the this of the
lambda, not the this of the enclosing context". We also don't have support or a
representation for a nested capture of an init-capture yet, which was intended
to work despite not being allowed by the current standard wording.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@181985 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/lib/Sema/TreeTransform.h b/lib/Sema/TreeTransform.h
index 253135f..95ea9bc 100644
--- a/lib/Sema/TreeTransform.h
+++ b/lib/Sema/TreeTransform.h
@@ -8074,6 +8074,22 @@
ExprResult
TreeTransform<Derived>::TransformLambdaScope(LambdaExpr *E,
CXXMethodDecl *CallOperator) {
+ bool Invalid = false;
+
+ // Transform any init-capture expressions before entering the scope of the
+ // lambda.
+ llvm::SmallVector<ExprResult, 8> InitCaptureExprs;
+ InitCaptureExprs.resize(E->explicit_capture_end() -
+ E->explicit_capture_begin());
+ for (LambdaExpr::capture_iterator C = E->capture_begin(),
+ CEnd = E->capture_end();
+ C != CEnd; ++C) {
+ if (!C->isInitCapture())
+ continue;
+ InitCaptureExprs[C - E->capture_begin()] =
+ getDerived().TransformExpr(E->getInitCaptureInit(C));
+ }
+
// Introduce the context of the call operator.
Sema::ContextRAII SavedContext(getSema(), CallOperator);
@@ -8086,7 +8102,6 @@
E->isMutable());
// Transform captures.
- bool Invalid = false;
bool FinishedExplicitCaptures = false;
for (LambdaExpr::capture_iterator C = E->capture_begin(),
CEnd = E->capture_end();
@@ -8104,6 +8119,26 @@
continue;
}
+ // Rebuild init-captures, including the implied field declaration.
+ if (C->isInitCapture()) {
+ ExprResult Init = InitCaptureExprs[C - E->capture_begin()];
+ if (Init.isInvalid()) {
+ Invalid = true;
+ continue;
+ }
+ FieldDecl *OldFD = C->getInitCaptureField();
+ FieldDecl *NewFD = getSema().checkInitCapture(
+ C->getLocation(), OldFD->getType()->isReferenceType(),
+ OldFD->getIdentifier(), Init.take());
+ if (!NewFD)
+ Invalid = true;
+ else
+ getDerived().transformedLocalDecl(OldFD, NewFD);
+ continue;
+ }
+
+ assert(C->capturesVariable() && "unexpected kind of lambda capture");
+
// Determine the capture kind for Sema.
Sema::TryCaptureKind Kind
= C->isImplicit()? Sema::TryCapture_Implicit
@@ -8120,8 +8155,10 @@
C->getLocation(),
Unexpanded,
ShouldExpand, RetainExpansion,
- NumExpansions))
- return ExprError();
+ NumExpansions)) {
+ Invalid = true;
+ continue;
+ }
if (ShouldExpand) {
// The transform has determined that we should perform an expansion;