diff --git a/clang/lib/CodeGen/CGBlocks.cpp b/clang/lib/CodeGen/CGBlocks.cpp index 2206e8a1cd7b..e21664607cf5 100644 --- a/clang/lib/CodeGen/CGBlocks.cpp +++ b/clang/lib/CodeGen/CGBlocks.cpp @@ -1006,14 +1006,36 @@ GenerateCopyHelperFunction(const llvm::StructType *T, || NoteForHelper[i].RequiresCopying) { llvm::Value *Srcv = SrcObj; Srcv = Builder.CreateStructGEP(Srcv, index); - Srcv = Builder.CreateBitCast(Srcv, - llvm::PointerType::get(PtrToInt8Ty, 0)); - llvm::Value *Dstv = Builder.CreateStructGEP(DstObj, index); + llvm::Value *Dstv; if (NoteForHelper[i].cxxvar_import) { - CGF.EmitSynthesizedCXXCopyCtor(Dstv, Srcv, - NoteForHelper[i].cxxvar_import); + if (NoteForHelper[i].flag & BLOCK_FIELD_IS_BYREF) { + const ValueDecl *VD = NoteForHelper[i].cxxvar_import->getDecl(); + const llvm::Type *PtrStructTy + = llvm::PointerType::get(CGF.BuildByRefType(VD), 0); + Srcv = Builder.CreateLoad(Srcv); + Srcv = Builder.CreateBitCast(Srcv, PtrStructTy); + Srcv = Builder.CreateStructGEP(Srcv, CGF.getByRefValueLLVMField(VD), + VD->getNameAsString()); + Dstv = Builder.CreateStructGEP(DstObj, index); + Dstv = Builder.CreateLoad(Dstv); + Dstv = Builder.CreateBitCast(Dstv, PtrStructTy); + Dstv = Builder.CreateStructGEP(Dstv, CGF.getByRefValueLLVMField(VD), + VD->getNameAsString()); + CGF.EmitSynthesizedCXXCopyCtor(Dstv, Srcv, + NoteForHelper[i].cxxvar_import); + } + else { + Srcv = Builder.CreateBitCast(Srcv, + llvm::PointerType::get(PtrToInt8Ty, 0)); + Dstv = Builder.CreateStructGEP(DstObj, index); + CGF.EmitSynthesizedCXXCopyCtor(Dstv, Srcv, + NoteForHelper[i].cxxvar_import); + } } else { + Srcv = Builder.CreateBitCast(Srcv, + llvm::PointerType::get(PtrToInt8Ty, 0)); + Dstv = Builder.CreateStructGEP(DstObj, index); Srcv = Builder.CreateLoad(Srcv); Dstv = Builder.CreateBitCast(Dstv, PtrToInt8Ty); llvm::Value *N = llvm::ConstantInt::get(CGF.Int32Ty, flag); @@ -1091,6 +1113,17 @@ GenerateDestroyHelperFunction(const llvm::StructType* T, QualType ClassTy = E->getType(); QualType PtrClassTy = getContext().getPointerType(ClassTy); const llvm::Type *t = CGM.getTypes().ConvertType(PtrClassTy); + + if (NoteForHelper[i].flag & BLOCK_FIELD_IS_BYREF) { + const ValueDecl *VD = NoteForHelper[i].cxxvar_import->getDecl(); + const llvm::Type *PtrStructTy + = llvm::PointerType::get(CGF.BuildByRefType(VD), 0); + Srcv = Builder.CreateLoad(Srcv); + Srcv = Builder.CreateBitCast(Srcv, PtrStructTy); + Srcv = Builder.CreateStructGEP(Srcv, CGF.getByRefValueLLVMField(VD), + VD->getNameAsString()); + + } Srcv = Builder.CreateBitCast(Srcv, t); CGF.PushDestructorCleanup(ClassTy, Srcv); } diff --git a/clang/lib/CodeGen/CodeGenFunction.h b/clang/lib/CodeGen/CodeGenFunction.h index 86a46deddd37..a3e1eac550fe 100644 --- a/clang/lib/CodeGen/CodeGenFunction.h +++ b/clang/lib/CodeGen/CodeGenFunction.h @@ -683,7 +683,11 @@ public: /// isInConditionalBranch - Return true if we're currently emitting /// one branch or the other of a conditional expression. bool isInConditionalBranch() const { return ConditionalBranchLevel != 0; } - + + /// getByrefValueFieldNumber - Given a declaration, returns the LLVM field + /// number that holds the value. + unsigned getByRefValueLLVMField(const ValueDecl *VD) const; + private: CGDebugInfo *DebugInfo; @@ -757,10 +761,6 @@ private: llvm::DenseMap > ByRefValueInfo; - /// getByrefValueFieldNumber - Given a declaration, returns the LLVM field - /// number that holds the value. - unsigned getByRefValueLLVMField(const ValueDecl *VD) const; - llvm::BasicBlock *TerminateLandingPad; llvm::BasicBlock *TerminateHandler; llvm::BasicBlock *TrapBB; diff --git a/clang/lib/Sema/SemaExpr.cpp b/clang/lib/Sema/SemaExpr.cpp index 0d065145a1f6..7555af375f7a 100644 --- a/clang/lib/Sema/SemaExpr.cpp +++ b/clang/lib/Sema/SemaExpr.cpp @@ -2145,17 +2145,21 @@ Sema::BuildDeclarationNameExpr(const CXXScopeSpec &SS, MarkDeclarationReferenced(Loc, VD); QualType ExprTy = VD->getType().getNonReferenceType(); // The BlocksAttr indicates the variable is bound by-reference. - if (VD->getAttr()) - return Owned(new (Context) BlockDeclRefExpr(VD, ExprTy, Loc, true)); - // This is to record that a 'const' was actually synthesize and added. - bool constAdded = !ExprTy.isConstQualified(); - // Variable will be bound by-copy, make it const within the closure. - - ExprTy.addConst(); + bool byrefVar = (VD->getAttr() != 0); QualType T = VD->getType(); - BlockDeclRefExpr *BDRE = new (Context) BlockDeclRefExpr(VD, - ExprTy, Loc, false, - constAdded); + BlockDeclRefExpr *BDRE; + + if (!byrefVar) { + // This is to record that a 'const' was actually synthesize and added. + bool constAdded = !ExprTy.isConstQualified(); + // Variable will be bound by-copy, make it const within the closure. + ExprTy.addConst(); + BDRE = new (Context) BlockDeclRefExpr(VD, ExprTy, Loc, false, + constAdded); + } + else + BDRE = new (Context) BlockDeclRefExpr(VD, ExprTy, Loc, true); + if (getLangOptions().CPlusPlus) { if (!T->isDependentType() && !T->isReferenceType()) { Expr *E = new (Context)