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 | 021510e96fdd46fb1fed1cefd6dabf472656e71c (patch) | |
| tree | e964a3c3d3c4ae154166fd95a14b58f198d2aafd /clang/lib/CodeGen/CGExprAgg.cpp | |
| parent | 438c35b5d160179b1b90f2b30724bc6a4e08428e (diff) | |
| download | bcm5719-llvm-021510e96fdd46fb1fed1cefd6dabf472656e71c.tar.gz bcm5719-llvm-021510e96fdd46fb1fed1cefd6dabf472656e71c.zip | |
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).
llvm-svn: 106061
Diffstat (limited to 'clang/lib/CodeGen/CGExprAgg.cpp')
| -rw-r--r-- | clang/lib/CodeGen/CGExprAgg.cpp | 44 |
1 files changed, 39 insertions, 5 deletions
diff --git a/clang/lib/CodeGen/CGExprAgg.cpp b/clang/lib/CodeGen/CGExprAgg.cpp index 6c8a60e9811..1a644f37a3d 100644 --- a/clang/lib/CodeGen/CGExprAgg.cpp +++ b/clang/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, |

