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
diff --git a/lib/CodeGen/CGExprAgg.cpp b/lib/CodeGen/CGExprAgg.cpp
index 4155738..f8e9c56 100644
--- a/lib/CodeGen/CGExprAgg.cpp
+++ b/lib/CodeGen/CGExprAgg.cpp
@@ -37,12 +37,13 @@
   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 @@
     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 @@
     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 @@
 /// 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));
 }