diff options
Diffstat (limited to 'clang/lib/CodeGen')
-rw-r--r-- | clang/lib/CodeGen/CGExprAgg.cpp | 29 | ||||
-rw-r--r-- | clang/lib/CodeGen/CGObjCGNU.cpp | 4 | ||||
-rw-r--r-- | clang/lib/CodeGen/CGObjCMac.cpp | 14 | ||||
-rw-r--r-- | clang/lib/CodeGen/CGObjCRuntime.h | 2 | ||||
-rw-r--r-- | clang/lib/CodeGen/CodeGenFunction.h | 5 |
5 files changed, 33 insertions, 21 deletions
diff --git a/clang/lib/CodeGen/CGExprAgg.cpp b/clang/lib/CodeGen/CGExprAgg.cpp index 4155738a22f..f8e9c56b182 100644 --- a/clang/lib/CodeGen/CGExprAgg.cpp +++ b/clang/lib/CodeGen/CGExprAgg.cpp @@ -37,12 +37,13 @@ class VISIBILITY_HIDDEN AggExprEmitter : public StmtVisitor<AggExprEmitter> { bool VolatileDest; bool IgnoreResult; bool IsInitializer; + bool RequiresGCollection; public: AggExprEmitter(CodeGenFunction &cgf, llvm::Value *destPtr, bool v, - bool ignore, bool isinit) + bool ignore, bool isinit, bool requiresGCollection) : CGF(cgf), Builder(CGF.Builder), DestPtr(destPtr), VolatileDest(v), IgnoreResult(ignore), - IsInitializer(isinit) { + IsInitializer(isinit), RequiresGCollection(requiresGCollection) { } //===--------------------------------------------------------------------===// @@ -145,6 +146,12 @@ void AggExprEmitter::EmitFinalDestCopy(const Expr *E, RValue Src, bool Ignore) { DestPtr = CGF.CreateTempAlloca(CGF.ConvertType(E->getType()), "agg.tmp"); } + if (RequiresGCollection) { + CGF.CGM.getObjCRuntime().EmitGCMemmoveCollectable(CGF, + DestPtr, Src.getAggregateAddr(), + E->getType()); + return; + } // If the result of the assignment is used, copy the LHS there also. // FIXME: Pass VolatileDest as well. I think we also need to merge volatile // from the source as well, as we can't eliminate it if either operand @@ -262,19 +269,15 @@ void AggExprEmitter::VisitBinAssign(const BinaryOperator *E) { CGF.EmitObjCPropertySet(LHS.getKVCRefExpr(), RValue::getAggregate(AggLoc, VolatileDest)); } else { + bool RequiresGCollection = false; if (CGF.getContext().getLangOptions().NeXTRuntime) { QualType LHSTy = E->getLHS()->getType(); if (const RecordType *FDTTy = LHSTy.getTypePtr()->getAs<RecordType>()) - if (FDTTy->getDecl()->hasObjectMember()) { - LValue RHS = CGF.EmitLValue(E->getRHS()); - CGF.CGM.getObjCRuntime().EmitGCMemmoveCollectable(CGF, LHS.getAddress(), - RHS.getAddress(), - CGF.getContext().getTypeSize(LHSTy) / 8); - return; - } + RequiresGCollection = FDTTy->getDecl()->hasObjectMember(); } // Codegen the RHS so that it stores directly into the LHS. - CGF.EmitAggExpr(E->getRHS(), LHS.getAddress(), LHS.isVolatileQualified()); + CGF.EmitAggExpr(E->getRHS(), LHS.getAddress(), LHS.isVolatileQualified(), + false, false, RequiresGCollection); EmitFinalDestCopy(E, LHS, true); } } @@ -525,13 +528,15 @@ void AggExprEmitter::VisitInitListExpr(InitListExpr *E) { /// true, DestPtr cannot be 0. void CodeGenFunction::EmitAggExpr(const Expr *E, llvm::Value *DestPtr, bool VolatileDest, bool IgnoreResult, - bool IsInitializer) { + bool IsInitializer, + bool RequiresGCollection) { assert(E && hasAggregateLLVMType(E->getType()) && "Invalid aggregate expression to emit"); assert ((DestPtr != 0 || VolatileDest == false) && "volatile aggregate can't be 0"); - AggExprEmitter(*this, DestPtr, VolatileDest, IgnoreResult, IsInitializer) + AggExprEmitter(*this, DestPtr, VolatileDest, IgnoreResult, IsInitializer, + RequiresGCollection) .Visit(const_cast<Expr*>(E)); } diff --git a/clang/lib/CodeGen/CGObjCGNU.cpp b/clang/lib/CodeGen/CGObjCGNU.cpp index 6ed13a444f8..63d45e9bd7b 100644 --- a/clang/lib/CodeGen/CGObjCGNU.cpp +++ b/clang/lib/CodeGen/CGObjCGNU.cpp @@ -162,7 +162,7 @@ public: virtual void EmitGCMemmoveCollectable(CodeGen::CodeGenFunction &CGF, llvm::Value *DestPtr, llvm::Value *SrcPtr, - unsigned long size); + QualType Ty); virtual LValue EmitObjCValueForIvar(CodeGen::CodeGenFunction &CGF, QualType ObjectTy, llvm::Value *BaseValue, @@ -1598,7 +1598,7 @@ void CGObjCGNU::EmitObjCStrongCastAssign(CodeGen::CodeGenFunction &CGF, void CGObjCGNU::EmitGCMemmoveCollectable(CodeGen::CodeGenFunction &CGF, llvm::Value *DestPtr, llvm::Value *SrcPtr, - unsigned long size) { + QualType Ty) { return; } diff --git a/clang/lib/CodeGen/CGObjCMac.cpp b/clang/lib/CodeGen/CGObjCMac.cpp index e16c3ee2582..26bc976a86c 100644 --- a/clang/lib/CodeGen/CGObjCMac.cpp +++ b/clang/lib/CodeGen/CGObjCMac.cpp @@ -1130,7 +1130,7 @@ public: llvm::Value *src, llvm::Value *dest); virtual void EmitGCMemmoveCollectable(CodeGen::CodeGenFunction &CGF, llvm::Value *dest, llvm::Value *src, - unsigned long size); + QualType Ty); virtual LValue EmitObjCValueForIvar(CodeGen::CodeGenFunction &CGF, QualType ObjectTy, @@ -1359,7 +1359,7 @@ public: llvm::Value *src, llvm::Value *dest); virtual void EmitGCMemmoveCollectable(CodeGen::CodeGenFunction &CGF, llvm::Value *dest, llvm::Value *src, - unsigned long size); + QualType Ty); virtual LValue EmitObjCValueForIvar(CodeGen::CodeGenFunction &CGF, QualType ObjectTy, llvm::Value *BaseValue, @@ -2786,7 +2786,10 @@ void CGObjCMac::EmitObjCStrongCastAssign(CodeGen::CodeGenFunction &CGF, void CGObjCMac::EmitGCMemmoveCollectable(CodeGen::CodeGenFunction &CGF, llvm::Value *DestPtr, llvm::Value *SrcPtr, - unsigned long size) { + QualType Ty) { + // Get size info for this aggregate. + std::pair<uint64_t, unsigned> TypeInfo = CGM.getContext().getTypeInfo(Ty); + unsigned long size = TypeInfo.second/8; SrcPtr = CGF.Builder.CreateBitCast(SrcPtr, ObjCTypes.Int8PtrTy); DestPtr = CGF.Builder.CreateBitCast(DestPtr, ObjCTypes.Int8PtrTy); llvm::Value *N = llvm::ConstantInt::get(ObjCTypes.LongTy, size); @@ -5315,7 +5318,10 @@ void CGObjCNonFragileABIMac::EmitGCMemmoveCollectable( CodeGen::CodeGenFunction &CGF, llvm::Value *DestPtr, llvm::Value *SrcPtr, - unsigned long size) { + QualType Ty) { + // Get size info for this aggregate. + std::pair<uint64_t, unsigned> TypeInfo = CGM.getContext().getTypeInfo(Ty); + unsigned long size = TypeInfo.second/8; SrcPtr = CGF.Builder.CreateBitCast(SrcPtr, ObjCTypes.Int8PtrTy); DestPtr = CGF.Builder.CreateBitCast(DestPtr, ObjCTypes.Int8PtrTy); llvm::Value *N = llvm::ConstantInt::get(ObjCTypes.LongTy, size); diff --git a/clang/lib/CodeGen/CGObjCRuntime.h b/clang/lib/CodeGen/CGObjCRuntime.h index ec72bcd5999..d82df9d881d 100644 --- a/clang/lib/CodeGen/CGObjCRuntime.h +++ b/clang/lib/CodeGen/CGObjCRuntime.h @@ -197,7 +197,7 @@ public: virtual void EmitGCMemmoveCollectable(CodeGen::CodeGenFunction &CGF, llvm::Value *DestPtr, llvm::Value *SrcPtr, - unsigned long) = 0; + QualType Ty) = 0; }; /// Creates an instance of an Objective-C runtime class. diff --git a/clang/lib/CodeGen/CodeGenFunction.h b/clang/lib/CodeGen/CodeGenFunction.h index 2815939517b..046a619e8a7 100644 --- a/clang/lib/CodeGen/CodeGenFunction.h +++ b/clang/lib/CodeGen/CodeGenFunction.h @@ -897,12 +897,13 @@ public: /// aggregate type. The result is computed into DestPtr. Note that if /// DestPtr is null, the value of the aggregate expression is not needed. void EmitAggExpr(const Expr *E, llvm::Value *DestPtr, bool VolatileDest, - bool IgnoreResult = false, bool IsInitializer = false); + bool IgnoreResult = false, bool IsInitializer = false, + bool RequiresGCollection = false); /// EmitGCMemmoveCollectable - Emit special API for structs with object /// pointers. void EmitGCMemmoveCollectable(llvm::Value *DestPtr, llvm::Value *SrcPtr, - unsigned long); + QualType Ty); /// EmitComplexExpr - Emit the computation of the specified expression of /// complex type, returning the result. |