diff options
Diffstat (limited to 'lib')
-rw-r--r-- | lib/CodeGen/CGBlocks.cpp | 32 | ||||
-rw-r--r-- | lib/Sema/SemaExpr.cpp | 24 |
2 files changed, 32 insertions, 24 deletions
diff --git a/lib/CodeGen/CGBlocks.cpp b/lib/CodeGen/CGBlocks.cpp index 5a3e1002c6..f789787b61 100644 --- a/lib/CodeGen/CGBlocks.cpp +++ b/lib/CodeGen/CGBlocks.cpp @@ -361,33 +361,21 @@ llvm::Value *CodeGenFunction::BuildBlockLiteralTmp(const BlockExpr *BE) { Builder.CreateStore(Loc, Addr); continue; } else { - E = new (getContext()) DeclRefExpr(const_cast<ValueDecl*>(VD), + if (BDRE->getCopyConstructorExpr()) + E = BDRE->getCopyConstructorExpr(); + else { + E = new (getContext()) DeclRefExpr(const_cast<ValueDecl*>(VD), VD->getType().getNonReferenceType(), SourceLocation()); - if (getContext().getLangOptions().CPlusPlus) { - if (VD->getType()->isReferenceType()) { - E = new (getContext()) - UnaryOperator(const_cast<Expr*>(E), UnaryOperator::AddrOf, - getContext().getPointerType(E->getType()), - SourceLocation()); - } - else { - QualType T = E->getType(); - if (const RecordType *RT = T->getAs<RecordType>()) { - CXXRecordDecl *Record = cast<CXXRecordDecl>(RT->getDecl()); - if (!Record->hasTrivialCopyConstructor()) { - CXXConstructorDecl *D = Record->getCopyConstructor(getContext(), - 0); - Expr *Arg = const_cast<Expr*>(E); - E = CXXConstructExpr::Create(getContext(), T, D->getLocation(), - D, false, &Arg, 1, false, - CXXConstructExpr::CK_Complete); - } - } + if (VD->getType()->isReferenceType()) { + E = new (getContext()) + UnaryOperator(const_cast<Expr*>(E), UnaryOperator::AddrOf, + getContext().getPointerType(E->getType()), + SourceLocation()); + } } } } - } if (BDRE->isByRef()) { E = new (getContext()) diff --git a/lib/Sema/SemaExpr.cpp b/lib/Sema/SemaExpr.cpp index e1a6a04bfd..5655a25b1f 100644 --- a/lib/Sema/SemaExpr.cpp +++ b/lib/Sema/SemaExpr.cpp @@ -1746,8 +1746,28 @@ Sema::BuildDeclarationNameExpr(const CXXScopeSpec &SS, // Variable will be bound by-copy, make it const within the closure. ExprTy.addConst(); - return Owned(new (Context) BlockDeclRefExpr(VD, ExprTy, Loc, false, - constAdded)); + BlockDeclRefExpr *BDRE = new (Context) BlockDeclRefExpr(VD, + ExprTy, Loc, false, + constAdded); + QualType T = VD->getType(); + if (getLangOptions().CPlusPlus && !T->isDependentType() && + !T->isReferenceType()) { + Expr *E = new (Context) + DeclRefExpr(const_cast<ValueDecl*>(BDRE->getDecl()), T, + SourceLocation()); + + OwningExprResult Res = PerformCopyInitialization( + InitializedEntity::InitializeResult(SourceLocation(), + T, false), + SourceLocation(), + Owned(E)); + if (!Res.isInvalid()) { + Expr *Init = Res.takeAs<Expr>(); + if (isa<CXXConstructExpr>(Init)) + BDRE->setCopyConstructorExpr(Init); + } + } + return Owned(BDRE); } // If this reference is not in a block or if the referenced variable is // within the block, create a normal DeclRefExpr. |