diff options
author | Fariborz Jahanian <fjahanian@apple.com> | 2009-08-31 19:33:16 +0000 |
---|---|---|
committer | Fariborz Jahanian <fjahanian@apple.com> | 2009-08-31 19:33:16 +0000 |
commit | 08c321380fff07d476a19daab6d29522c046cd49 (patch) | |
tree | 859787972fc3b6ec946d50d5e5579c59d7d09483 /lib/CodeGen/CGExprAgg.cpp | |
parent | e32ecce8a181640c2f3d3939f9a9bfe8927df767 (diff) |
Re-implemented generation of objc_memmove_collectable
API for copying GC'able aggregates (Next runtime only).
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@80607 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/CodeGen/CGExprAgg.cpp')
-rw-r--r-- | lib/CodeGen/CGExprAgg.cpp | 29 |
1 files changed, 17 insertions, 12 deletions
diff --git a/lib/CodeGen/CGExprAgg.cpp b/lib/CodeGen/CGExprAgg.cpp index 4155738a22..f8e9c56b18 100644 --- a/lib/CodeGen/CGExprAgg.cpp +++ b/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)); } |