diff options
author | Fariborz Jahanian <fjahanian@apple.com> | 2010-06-15 22:44:06 +0000 |
---|---|---|
committer | Fariborz Jahanian <fjahanian@apple.com> | 2010-06-15 22:44:06 +0000 |
commit | 55bcace250e1ff366e4482714b344b8cbc8be5f3 (patch) | |
tree | 40128a261e5ae0668dadb5382f2e33884f6b2adc /lib/CodeGen/CGExprAgg.cpp | |
parent | 6e5122c8ce152e19355b707d952ab53fe58bd7ad (diff) |
Patch adds support for copying of those
objective-c++ class objects which have GC'able objc object
pointers and need to use ObjC's objc_memmove_collectable
API (radar 8070772).
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@106061 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/CodeGen/CGExprAgg.cpp')
-rw-r--r-- | lib/CodeGen/CGExprAgg.cpp | 44 |
1 files changed, 39 insertions, 5 deletions
diff --git a/lib/CodeGen/CGExprAgg.cpp b/lib/CodeGen/CGExprAgg.cpp index 6c8a60e981..1a644f37a3 100644 --- a/lib/CodeGen/CGExprAgg.cpp +++ b/lib/CodeGen/CGExprAgg.cpp @@ -177,11 +177,16 @@ bool AggExprEmitter::TypeRequiresGCollection(QualType T) { /// directly into the return value slot. If GC does interfere, a final /// move will be performed. void AggExprEmitter::EmitGCMove(const Expr *E, RValue Src) { - if (!RequiresGCollection) return; - - CGF.CGM.getObjCRuntime().EmitGCMemmoveCollectable(CGF, DestPtr, + if (RequiresGCollection) { + std::pair<uint64_t, unsigned> TypeInfo = + CGF.getContext().getTypeInfo(E->getType()); + unsigned long size = TypeInfo.first/8; + const llvm::Type *SizeTy = CGF.ConvertType(CGF.getContext().getSizeType()); + llvm::Value *SizeVal = llvm::ConstantInt::get(SizeTy, size); + CGF.CGM.getObjCRuntime().EmitGCMemmoveCollectable(CGF, DestPtr, Src.getAggregateAddr(), - E->getType()); + SizeVal); + } } /// EmitFinalDestCopy - Perform the final copy to DestPtr, if desired. @@ -198,9 +203,14 @@ void AggExprEmitter::EmitFinalDestCopy(const Expr *E, RValue Src, bool Ignore) { } if (RequiresGCollection) { + std::pair<uint64_t, unsigned> TypeInfo = + CGF.getContext().getTypeInfo(E->getType()); + unsigned long size = TypeInfo.first/8; + const llvm::Type *SizeTy = CGF.ConvertType(CGF.getContext().getSizeType()); + llvm::Value *SizeVal = llvm::ConstantInt::get(SizeTy, size); CGF.CGM.getObjCRuntime().EmitGCMemmoveCollectable(CGF, DestPtr, Src.getAggregateAddr(), - E->getType()); + SizeVal); return; } // If the result of the assignment is used, copy the LHS there also. @@ -837,6 +847,30 @@ void CodeGenFunction::EmitAggregateCopy(llvm::Value *DestPtr, if (SrcPtr->getType() != SBP) SrcPtr = Builder.CreateBitCast(SrcPtr, SBP, "tmp"); + if (const RecordType *RecordTy = Ty->getAs<RecordType>()) { + RecordDecl *Record = RecordTy->getDecl(); + if (Record->hasObjectMember()) { + unsigned long size = TypeInfo.first/8; + const llvm::Type *SizeTy = ConvertType(getContext().getSizeType()); + llvm::Value *SizeVal = llvm::ConstantInt::get(SizeTy, size); + CGM.getObjCRuntime().EmitGCMemmoveCollectable(*this, DestPtr, SrcPtr, + SizeVal); + return; + } + } else if (getContext().getAsArrayType(Ty)) { + QualType BaseType = getContext().getBaseElementType(Ty); + if (const RecordType *RecordTy = BaseType->getAs<RecordType>()) { + if (RecordTy->getDecl()->hasObjectMember()) { + unsigned long size = TypeInfo.first/8; + const llvm::Type *SizeTy = ConvertType(getContext().getSizeType()); + llvm::Value *SizeVal = llvm::ConstantInt::get(SizeTy, size); + CGM.getObjCRuntime().EmitGCMemmoveCollectable(*this, DestPtr, SrcPtr, + SizeVal); + return; + } + } + } + Builder.CreateCall5(CGM.getMemCpyFn(DestPtr->getType(), SrcPtr->getType(), IntPtr), DestPtr, SrcPtr, |