]> granicus.if.org Git - clang/commitdiff
Handle case of none gc'able objects regardless of their
authorFariborz Jahanian <fjahanian@apple.com>
Sat, 21 Feb 2009 00:30:43 +0000 (00:30 +0000)
committerFariborz Jahanian <fjahanian@apple.com>
Sat, 21 Feb 2009 00:30:43 +0000 (00:30 +0000)
type.

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@65205 91177308-0d34-0410-b5e6-96231b3b80d8

lib/CodeGen/CGExpr.cpp
lib/CodeGen/CGValue.h

index ea0fc5546412c89071f8198ffbf7972c16bd2d40..a9db6db0d9b6c6f72e2c58c2f96e30ee1064c936 100644 (file)
@@ -405,7 +405,7 @@ void CodeGenFunction::EmitStoreThroughLValue(RValue Src, LValue Dst,
     assert(0 && "Unknown LValue type");
   }
   
-  if (Dst.isObjCWeak()) {
+  if (Dst.isObjCWeak() && !Dst.isNonGC()) {
     // load of a __weak object. 
     llvm::Value *LvalueDst = Dst.getAddress();
     llvm::Value *src = Src.getScalarVal();
@@ -413,7 +413,7 @@ void CodeGenFunction::EmitStoreThroughLValue(RValue Src, LValue Dst,
     return;
   }
   
-  if (Dst.isObjCStrong()) {
+  if (Dst.isObjCStrong() && !Dst.isNonGC()) {
     // load of a __strong object. 
     llvm::Value *LvalueDst = Dst.getAddress();
     llvm::Value *src = Src.getScalarVal();
@@ -629,10 +629,11 @@ LValue CodeGenFunction::EmitDeclRefLValue(const DeclRefExpr *E) {
       // local variables do not get their gc attribute set.
       QualType::GCAttrTypes attr = QualType::GCNone;
       // local static?
-      if (VD->getStorageClass() == VarDecl::Static)
+      if (!VD->hasLocalStorage())
         attr = getContext().getObjCGCAttrKind(E->getType());
       LV = LValue::MakeAddr(V, E->getType().getCVRQualifiers(), attr);
     }
+    LValue::SetObjCNonGC(LV, VD->hasLocalStorage());
     return LV;
   } else if (VD && VD->isFileVarDecl()) {
     LValue LV = LValue::MakeAddr(CGM.GetAddrOfGlobalVar(VD),
@@ -834,6 +835,7 @@ EmitExtVectorElementExpr(const ExtVectorElementExpr *E) {
 LValue CodeGenFunction::EmitMemberExpr(const MemberExpr *E) {
   bool isUnion = false;
   bool isIvar = false;
+  bool isNonGC = false;
   Expr *BaseExpr = E->getBase();
   llvm::Value *BaseValue = NULL;
   unsigned CVRQualifiers=0;
@@ -857,6 +859,8 @@ LValue CodeGenFunction::EmitMemberExpr(const MemberExpr *E) {
     LValue BaseLV = EmitLValue(BaseExpr);
     if (BaseLV.isObjCIvar())
       isIvar = true;
+    if (BaseLV.isNonGC())
+      isNonGC = true;
     // FIXME: this isn't right for bitfields.
     BaseValue = BaseLV.getAddress();
     if (BaseExpr->getType()->isUnionType())
@@ -870,6 +874,7 @@ LValue CodeGenFunction::EmitMemberExpr(const MemberExpr *E) {
   LValue MemExpLV = EmitLValueForField(BaseValue, Field, isUnion,
                                        CVRQualifiers);
   LValue::SetObjCIvar(MemExpLV, isIvar);
+  LValue::SetObjCNonGC(MemExpLV, isNonGC);
   return MemExpLV;
 }
 
index 96e4224f6148cec6f641c3ce2004535e3cdeb748..66cb0037a1361ed9f870bfb190fbd6c791da151d 100644 (file)
@@ -144,6 +144,10 @@ class LValue {
 
   // objective-c's ivar
   bool Ivar:1;
+  
+  // LValue is non-gc'able for any reason, including being a parameter or local
+  // variable.
+  bool NonGC: 1;
 
   // objective-c's gc attributes
   unsigned ObjCType : 2;  
@@ -156,7 +160,7 @@ private:
     // FIXME: Convenient place to set objc flags to 0. This
     // should really be done in a user-defined constructor instead.
     R.ObjCType = None;
-    R.Ivar = false;
+    R.Ivar = R.NonGC = false;
   }
   
 public:
@@ -175,18 +179,24 @@ public:
   }
   
   bool isObjCIvar() const { return Ivar; }
+  bool isNonGC () const { return NonGC; }
   bool isObjCWeak() const { return ObjCType == Weak; }
   bool isObjCStrong() const { return ObjCType == Strong; }
   
   static void SetObjCIvar(LValue& R, bool iValue) {
     R.Ivar = iValue;
   }
-    
+  
+  static void SetObjCNonGC(LValue& R, bool iValue) {
+    R.NonGC = iValue;
+  }
   static void SetObjCType(QualType::GCAttrTypes GCAttrs, LValue& R) {
     if (GCAttrs == QualType::Weak)
       R.ObjCType = Weak;
     else if (GCAttrs == QualType::Strong)
       R.ObjCType = Strong;
+    else
+     R.ObjCType = None;
   }
   
   // simple lvalue