diff options
author | Fariborz Jahanian <fjahanian@apple.com> | 2010-06-04 21:35:44 +0000 |
---|---|---|
committer | Fariborz Jahanian <fjahanian@apple.com> | 2010-06-04 21:35:44 +0000 |
commit | 59da45a1fc10a3af4f3b3152f45504b4c5ca7385 (patch) | |
tree | a6b2a72476a4b3954503e55e4593cdcb22d701ae | |
parent | 83a230c83a54190366138c1a4f4310ef838b88fc (diff) |
Build AST for copy-construction of copied-in
class object in blocks and carry it to IRGen.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@105487 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r-- | lib/CodeGen/CGBlocks.cpp | 32 | ||||
-rw-r--r-- | lib/Sema/SemaExpr.cpp | 24 | ||||
-rw-r--r-- | test/CodeGenCXX/copy-in-cplus-object.cpp | 4 |
3 files changed, 34 insertions, 26 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. diff --git a/test/CodeGenCXX/copy-in-cplus-object.cpp b/test/CodeGenCXX/copy-in-cplus-object.cpp index 6dcb1285fa..819879806d 100644 --- a/test/CodeGenCXX/copy-in-cplus-object.cpp +++ b/test/CodeGenCXX/copy-in-cplus-object.cpp @@ -2,7 +2,7 @@ struct TestObject { - TestObject(const TestObject& inObj); + TestObject(const TestObject& inObj, int def = 100); TestObject(); TestObject& operator=(const TestObject& inObj); int version() const; @@ -14,5 +14,5 @@ void testRoutine() { int (^V)() = ^{ return one.version(); }; } -// CHECK: call void @_ZN10TestObjectC1ERKS_ +// CHECK: call void @_ZN10TestObjectC1ERKS_i |