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/AST/ExprCXX.cpp b/lib/AST/ExprCXX.cpp
index 402d7b5..59e780a 100644
--- a/lib/AST/ExprCXX.cpp
+++ b/lib/AST/ExprCXX.cpp
@@ -811,7 +811,7 @@
LambdaExpr::Capture::Capture(SourceLocation Loc, bool Implicit,
LambdaCaptureKind Kind, VarDecl *Var,
SourceLocation EllipsisLoc)
- : VarAndBits(Var, 0), Loc(Loc), EllipsisLoc(EllipsisLoc)
+ : DeclAndBits(Var, 0), Loc(Loc), EllipsisLoc(EllipsisLoc)
{
unsigned Bits = 0;
if (Implicit)
@@ -828,15 +828,27 @@
case LCK_ByRef:
assert(Var && "capture must have a variable!");
break;
+
+ case LCK_Init:
+ llvm_unreachable("don't use this constructor for an init-capture");
}
- VarAndBits.setInt(Bits);
+ DeclAndBits.setInt(Bits);
}
+LambdaExpr::Capture::Capture(FieldDecl *Field)
+ : DeclAndBits(Field,
+ Field->getType()->isReferenceType() ? 0 : Capture_ByCopy),
+ Loc(Field->getLocation()), EllipsisLoc() {}
+
LambdaCaptureKind LambdaExpr::Capture::getCaptureKind() const {
- if (capturesThis())
+ Decl *D = DeclAndBits.getPointer();
+ if (!D)
return LCK_This;
- return (VarAndBits.getInt() & Capture_ByCopy)? LCK_ByCopy : LCK_ByRef;
+ if (isa<FieldDecl>(D))
+ return LCK_Init;
+
+ return (DeclAndBits.getInt() & Capture_ByCopy) ? LCK_ByCopy : LCK_ByRef;
}
LambdaExpr::LambdaExpr(QualType T,