Patch to move RequiresGCollection bit to
AggValueSlot slot.


git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@114045 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/lib/CodeGen/CGExprAgg.cpp b/lib/CodeGen/CGExprAgg.cpp
index 9ed20f3..d280711 100644
--- a/lib/CodeGen/CGExprAgg.cpp
+++ b/lib/CodeGen/CGExprAgg.cpp
@@ -34,13 +34,12 @@
   CGBuilderTy &Builder;
   AggValueSlot Dest;
   bool IgnoreResult;
-  bool RequiresGCollection;
 
   ReturnValueSlot getReturnValueSlot() const {
     // If the destination slot requires garbage collection, we can't
     // use the real return value slot, because we have to use the GC
     // API.
-    if (RequiresGCollection) return ReturnValueSlot();
+    if (Dest.isRequiresGCollection()) return ReturnValueSlot();
 
     return ReturnValueSlot(Dest.getAddr(), Dest.isVolatile());
   }
@@ -52,9 +51,9 @@
 
 public:
   AggExprEmitter(CodeGenFunction &cgf, AggValueSlot Dest,
-                 bool ignore, bool requiresGCollection)
+                 bool ignore)
     : CGF(cgf), Builder(CGF.Builder), Dest(Dest),
-      IgnoreResult(ignore), RequiresGCollection(requiresGCollection) {
+      IgnoreResult(ignore) {
   }
 
   //===--------------------------------------------------------------------===//
@@ -178,7 +177,7 @@
 /// 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) {
+  if (Dest.isRequiresGCollection()) {
     std::pair<uint64_t, unsigned> TypeInfo = 
       CGF.getContext().getTypeInfo(E->getType());
     unsigned long size = TypeInfo.first/8;
@@ -211,7 +210,7 @@
     Dest = CGF.CreateAggTemp(E->getType(), "agg.tmp");
   }
 
-  if (RequiresGCollection) {
+  if (Dest.isRequiresGCollection()) {
     std::pair<uint64_t, unsigned> TypeInfo = 
     CGF.getContext().getTypeInfo(E->getType());
     unsigned long size = TypeInfo.first/8;
@@ -370,13 +369,14 @@
     CGF.EmitAggExpr(E->getRHS(), Slot);
     CGF.EmitObjCPropertySet(LHS.getKVCRefExpr(), Slot.asRValue());
   } else {
-    bool RequiresGCollection = false;
+    bool GCollection = false;
     if (CGF.getContext().getLangOptions().getGCMode())
-      RequiresGCollection = TypeRequiresGCollection(E->getLHS()->getType());
+      GCollection = TypeRequiresGCollection(E->getLHS()->getType());
 
     // Codegen the RHS so that it stores directly into the LHS.
-    AggValueSlot LHSSlot = AggValueSlot::forLValue(LHS, true);
-    CGF.EmitAggExpr(E->getRHS(), LHSSlot, false, RequiresGCollection);
+    AggValueSlot LHSSlot = AggValueSlot::forLValue(LHS, true, 
+                                                   GCollection);
+    CGF.EmitAggExpr(E->getRHS(), LHSSlot, false);
     EmitFinalDestCopy(E, LHS, true);
   }
 }
@@ -646,14 +646,13 @@
 //
 // FIXME: Take Qualifiers object.
 void CodeGenFunction::EmitAggExpr(const Expr *E, AggValueSlot Slot,
-                                  bool IgnoreResult,
-                                  bool RequiresGCollection) {
+                                  bool IgnoreResult) {
   assert(E && hasAggregateLLVMType(E->getType()) &&
          "Invalid aggregate expression to emit");
   assert((Slot.getAddr() != 0 || Slot.isIgnored())
          && "slot has bits but no address");
 
-  AggExprEmitter(*this, Slot, IgnoreResult, RequiresGCollection)
+  AggExprEmitter(*this, Slot, IgnoreResult)
     .Visit(const_cast<Expr*>(E));
 }
 
diff --git a/lib/CodeGen/CGValue.h b/lib/CodeGen/CGValue.h
index 42b8335..fa4cb3d 100644
--- a/lib/CodeGen/CGValue.h
+++ b/lib/CodeGen/CGValue.h
@@ -323,12 +323,13 @@
 
 /// An aggregate value slot.
 class AggValueSlot {
-  /// The address and associated flags.
+  /// The address.
   uintptr_t AddrAndFlags;
-
-  static const uintptr_t VolatileFlag = 0x1;
-  static const uintptr_t LifetimeFlag = 0x2;
-  static const uintptr_t AddrMask = ~(VolatileFlag | LifetimeFlag);
+  
+  // Associated flags.
+  bool VolatileFlag : 1;
+  bool LifetimeFlag : 1;
+  bool RequiresGCollection : 1;
 
 public:
   /// ignored - Returns an aggregate value slot indicating that the
@@ -336,6 +337,7 @@
   static AggValueSlot ignored() {
     AggValueSlot AV;
     AV.AddrAndFlags = 0;
+    AV.VolatileFlag = AV.LifetimeFlag = AV.RequiresGCollection = 0;
     return AV;
   }
 
@@ -346,32 +348,42 @@
   ///   is being externally managed; false if a destructor should be
   ///   registered for any temporaries evaluated into the slot
   static AggValueSlot forAddr(llvm::Value *Addr, bool Volatile,
-                              bool LifetimeExternallyManaged) {
+                              bool LifetimeExternallyManaged,
+                              bool RequiresGCollection=false) {
     AggValueSlot AV;
     AV.AddrAndFlags = reinterpret_cast<uintptr_t>(Addr);
-    if (Volatile) AV.AddrAndFlags |= VolatileFlag;
-    if (LifetimeExternallyManaged) AV.AddrAndFlags |= LifetimeFlag;
+    if (Volatile) AV.VolatileFlag = 1;
+    if (LifetimeExternallyManaged) AV.LifetimeFlag = 1;
+    if (RequiresGCollection) AV.RequiresGCollection = 1;
     return AV;
   }
 
-  static AggValueSlot forLValue(LValue LV, bool LifetimeExternallyManaged) {
+  static AggValueSlot forLValue(LValue LV, bool LifetimeExternallyManaged,
+                                bool RequiresGCollection=false) {
     return forAddr(LV.getAddress(), LV.isVolatileQualified(),
-                   LifetimeExternallyManaged);
+                   LifetimeExternallyManaged, RequiresGCollection);
   }
 
   bool isLifetimeExternallyManaged() const {
-    return AddrAndFlags & LifetimeFlag;
+    return LifetimeFlag;
   }
   void setLifetimeExternallyManaged() {
-    AddrAndFlags |= LifetimeFlag;
+    LifetimeFlag = 1;
   }
 
   bool isVolatile() const {
-    return AddrAndFlags & VolatileFlag;
+    return VolatileFlag;
   }
 
+  bool isRequiresGCollection() const {
+    return RequiresGCollection;
+  }
+  void setRequiresGCollection() {
+    RequiresGCollection = 1;
+  }
+  
   llvm::Value *getAddr() const {
-    return reinterpret_cast<llvm::Value*>(AddrAndFlags & AddrMask);
+    return reinterpret_cast<llvm::Value*>(AddrAndFlags);
   }
 
   bool isIgnored() const {
diff --git a/lib/CodeGen/CodeGenFunction.h b/lib/CodeGen/CodeGenFunction.h
index d19827b..26b262c 100644
--- a/lib/CodeGen/CodeGenFunction.h
+++ b/lib/CodeGen/CodeGenFunction.h
@@ -1551,8 +1551,7 @@
   /// EmitAggExpr - Emit the computation of the specified expression
   /// of aggregate type.  The result is computed into the given slot,
   /// which may be null to indicate that the value is not needed.
-  void EmitAggExpr(const Expr *E, AggValueSlot AS, bool IgnoreResult = false,
-                   bool RequiresGCollection = false);
+  void EmitAggExpr(const Expr *E, AggValueSlot AS, bool IgnoreResult = false);
 
   /// EmitAggExprToLValue - Emit the computation of the specified expression of
   /// aggregate type into a temporary LValue.