diff options
author | Alexey Bataev <a.bataev@hotmail.com> | 2014-08-28 04:28:19 +0000 |
---|---|---|
committer | Alexey Bataev <a.bataev@hotmail.com> | 2014-08-28 04:28:19 +0000 |
commit | 39c81e281629886bfa491434e31516b2056d0985 (patch) | |
tree | b0b1ff5b7d83d851e804aad3c20379024760bb7b /clang/lib/Sema/SemaExpr.cpp | |
parent | c5cafbb074d216d6fa6bc5beb05f236e736490d2 (diff) | |
download | bcm5719-llvm-39c81e281629886bfa491434e31516b2056d0985.tar.gz bcm5719-llvm-39c81e281629886bfa491434e31516b2056d0985.zip |
[C++11] Support for capturing of variable length arrays in lambda expression.
Differential Revision: http://reviews.llvm.org/D4368
llvm-svn: 216649
Diffstat (limited to 'clang/lib/Sema/SemaExpr.cpp')
-rw-r--r-- | clang/lib/Sema/SemaExpr.cpp | 41 |
1 files changed, 30 insertions, 11 deletions
diff --git a/clang/lib/Sema/SemaExpr.cpp b/clang/lib/Sema/SemaExpr.cpp index 6a530c71ec2..d9278863534 100644 --- a/clang/lib/Sema/SemaExpr.cpp +++ b/clang/lib/Sema/SemaExpr.cpp @@ -11681,13 +11681,10 @@ static bool isVariableCapturable(CapturingScopeInfo *CSI, VarDecl *Var, return false; } - // Prohibit variably-modified types; they're difficult to deal with. - if (Var->getType()->isVariablyModifiedType() && (IsBlock || IsLambda)) { + // Prohibit variably-modified types in blocks; they're difficult to deal with. + if (Var->getType()->isVariablyModifiedType() && IsBlock) { if (Diagnose) { - if (IsBlock) - S.Diag(Loc, diag::err_ref_vm_type); - else - S.Diag(Loc, diag::err_lambda_capture_vm_type) << Var->getDeclName(); + S.Diag(Loc, diag::err_ref_vm_type); S.Diag(Var->getLocation(), diag::note_previous_decl) << Var->getDeclName(); } @@ -12091,7 +12088,6 @@ static bool captureInLambda(LambdaScopeInfo *LSI, return true; } - bool Sema::tryCaptureVariable(VarDecl *Var, SourceLocation ExprLoc, TryCaptureKind Kind, SourceLocation EllipsisLoc, bool BuildAndDiagnose, @@ -12228,14 +12224,37 @@ bool Sema::tryCaptureVariable(VarDecl *Var, SourceLocation ExprLoc, break; case Type::VariableArray: { // Losing element qualification here is fine. - const VariableArrayType *Vat = cast<VariableArrayType>(Ty); + const VariableArrayType *VAT = cast<VariableArrayType>(Ty); // Unknown size indication requires no size computation. // Otherwise, evaluate and record it. - if (Expr *Size = Vat->getSizeExpr()) { - MarkDeclarationsReferencedInExpr(Size); + if (auto Size = VAT->getSizeExpr()) { + if (auto LSI = dyn_cast<LambdaScopeInfo>(CSI)) { + if (!LSI->isVLATypeCaptured(VAT)) { + auto ExprLoc = Size->getExprLoc(); + auto SizeType = Context.getSizeType(); + auto Lambda = LSI->Lambda; + + // Build the non-static data member. + auto Field = FieldDecl::Create( + Context, Lambda, ExprLoc, ExprLoc, + /*Id*/ nullptr, SizeType, /*TInfo*/ nullptr, + /*BW*/ nullptr, /*Mutable*/ false, + /*InitStyle*/ ICIS_NoInit); + Field->setImplicit(true); + Field->setAccess(AS_private); + Field->setCapturedVLAType(VAT); + Lambda->addDecl(Field); + + LSI->addVLATypeCapture(ExprLoc, SizeType); + } + } else { + // Immediately mark all referenced vars for CapturedStatements, + // they all are captured by reference. + MarkDeclarationsReferencedInExpr(Size); + } } - QTy = Vat->getElementType(); + QTy = VAT->getElementType(); break; } case Type::FunctionProto: |