]> granicus.if.org Git - clang/commitdiff
Generate strong write barriers for __strong objects.
authorFariborz Jahanian <fjahanian@apple.com>
Wed, 19 Nov 2008 00:59:10 +0000 (00:59 +0000)
committerFariborz Jahanian <fjahanian@apple.com>
Wed, 19 Nov 2008 00:59:10 +0000 (00:59 +0000)
Also, took care of Daniel's commments.

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

lib/CodeGen/CGExpr.cpp
lib/CodeGen/CGObjCGNU.cpp
lib/CodeGen/CGObjCMac.cpp
lib/CodeGen/CGObjCRuntime.h
lib/CodeGen/CGValue.h

index 98a54c6863f59a5d305b3a3452511fb346eda366..95733abbab4fe9e4335768107b7069efd5346b3a 100644 (file)
@@ -151,7 +151,7 @@ LValue CodeGenFunction::EmitLValue(const Expr *E) {
 /// this method emits the address of the lvalue, then loads the result as an
 /// rvalue, returning the rvalue.
 RValue CodeGenFunction::EmitLoadOfLValue(LValue LV, QualType ExprType) {
-  if (LV.isObjcWeak()) {
+  if (LV.ObjcWeak()) {
     // load of a __weak object. 
     llvm::Value *AddrWeakObj = LV.getAddress();
     llvm::Value *read_weak = CGM.getObjCRuntime().EmitObjCWeakRead(*this, 
@@ -335,7 +335,7 @@ RValue CodeGenFunction::EmitLoadOfExtVectorElementLValue(LValue LV,
 /// is 'Ty'.
 void CodeGenFunction::EmitStoreThroughLValue(RValue Src, LValue Dst, 
                                              QualType Ty) {
-  if (Dst.isObjcWeak()) {
+  if (Dst.ObjcWeak()) {
     // load of a __weak object. 
     llvm::Value *LvalueDst = Dst.getAddress();
     llvm::Value *src = Src.getScalarVal();
@@ -343,6 +343,14 @@ void CodeGenFunction::EmitStoreThroughLValue(RValue Src, LValue Dst,
     return;
   }
   
+  if (Dst.ObjcStrong()) {
+    // load of a __strong object. 
+    llvm::Value *LvalueDst = Dst.getAddress();
+    llvm::Value *src = Src.getScalarVal();
+    CGM.getObjCRuntime().EmitObjCGlobalAssign(*this, src, LvalueDst);
+    return;
+  }
+  
   if (!Dst.isSimple()) {
     if (Dst.isVectorElt()) {
       // Read/modify/write the vector, inserting the new element.
@@ -510,10 +518,9 @@ LValue CodeGenFunction::EmitDeclRefLValue(const DeclRefExpr *E) {
   } else if (VD && VD->isFileVarDecl()) {
     LValue LV = LValue::MakeAddr(CGM.GetAddrOfGlobalVar(VD),
                                  E->getType().getCVRQualifiers());
-    if (VD->getAttr<ObjCGCAttr>())
-    {
-      ObjCGCAttr::GCAttrTypes attrType = (VD->getAttr<ObjCGCAttr>())->getType();
-      LValue::SetObjCGCAttrs(attrType == ObjCGCAttr::Weak, attrType == ObjCGCAttr::Strong, LV);
+    if (const ObjCGCAttr *A = VD->getAttr<ObjCGCAttr>()) {
+      ObjCGCAttr::GCAttrTypes attrType = A->getType();
+      LValue::SetObjCType(attrType == ObjCGCAttr::Weak, attrType == ObjCGCAttr::Strong, LV);
     }
     return LV;
   } else if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(E->getDecl())) {
index 91b8587e1afd1596d47ac13eae00bc42c7e54936..7adbd4a8e752247c1fa9e27d07235cc4519ef862 100644 (file)
@@ -134,6 +134,10 @@ public:
                                          llvm::Value *AddrWeakObj);
   virtual void EmitObjCWeakAssign(CodeGen::CodeGenFunction &CGF,
                                   llvm::Value *src, llvm::Value *dst);
+  virtual void EmitObjCGlobalAssign(CodeGen::CodeGenFunction &CGF,
+                                    llvm::Value *src, llvm::Value *dest);
+  virtual void EmitObjCStrongCastAssign(CodeGen::CodeGenFunction &CGF,
+                                        llvm::Value *src, llvm::Value *dest);
 };
 } // end anonymous namespace
 
@@ -984,6 +988,18 @@ void CGObjCGNU::EmitObjCWeakAssign(CodeGen::CodeGenFunction &CGF,
   return;
 }
 
+void CGObjCGNU::EmitObjCGlobalAssign(CodeGen::CodeGenFunction &CGF,
+                                     llvm::Value *src, llvm::Value *dst)
+{
+  return;
+}
+
+void CGObjCGNU::EmitObjCStrongCastAssign(CodeGen::CodeGenFunction &CGF,
+                                         llvm::Value *src, llvm::Value *dst)
+{
+  return;
+}
+
 CodeGen::CGObjCRuntime *CodeGen::CreateGNUObjCRuntime(CodeGen::CodeGenModule &CGM){
   return new CGObjCGNU(CGM);
 }
index e6c2650a2e82aa79cbac3970ca17d4520c87550c..ccfd465c35e3b5b45b7b0c86b3c66f1022a1e1a3 100644 (file)
@@ -458,6 +458,10 @@ public:
                                          llvm::Value *AddrWeakObj); 
   virtual void EmitObjCWeakAssign(CodeGen::CodeGenFunction &CGF,
                                   llvm::Value *src, llvm::Value *dst); 
+  virtual void EmitObjCGlobalAssign(CodeGen::CodeGenFunction &CGF,
+                                    llvm::Value *src, llvm::Value *dest);
+  virtual void EmitObjCStrongCastAssign(CodeGen::CodeGenFunction &CGF,
+                                        llvm::Value *src, llvm::Value *dest);
 };
 } // end anonymous namespace
 
@@ -1800,6 +1804,28 @@ void CGObjCMac::EmitObjCWeakAssign(CodeGen::CodeGenFunction &CGF,
   return;
 }
 
+/// EmitObjCGlobalAssign - Code gen for assigning to a __strong object.
+/// objc_assign_global (id src, id *dst)
+///
+void CGObjCMac::EmitObjCGlobalAssign(CodeGen::CodeGenFunction &CGF,
+                                     llvm::Value *src, llvm::Value *dst)
+{
+  CGF.Builder.CreateCall2(ObjCTypes.GcAssignGlobalFn,
+                          src, dst, "globalassign");
+  return;
+}
+
+/// EmitObjCStrongCastAssign - Code gen for assigning to a __strong cast object.
+/// objc_assign_strongCast (id src, id *dst)
+///
+void CGObjCMac::EmitObjCStrongCastAssign(CodeGen::CodeGenFunction &CGF,
+                                         llvm::Value *src, llvm::Value *dst)
+{
+  CGF.Builder.CreateCall2(ObjCTypes.GcAssignStrongCastFn,
+                          src, dst, "weakassign");
+  return;
+}
+
 /// EmitSynchronizedStmt - Code gen for @synchronized(expr) stmt;
 /// Effectively generating code for:
 /// objc_sync_enter(expr);
index 24288b1e4439eb3d0d14e3991d2c7ce2725806f6..675ff340b64727896a8e5ca0e327db8d6c119cbc 100644 (file)
@@ -149,6 +149,10 @@ public:
                                         llvm::Value *AddrWeakObj) = 0;
   virtual void EmitObjCWeakAssign(CodeGen::CodeGenFunction &CGF,
                                   llvm::Value *src, llvm::Value *dest) = 0;
+  virtual void EmitObjCGlobalAssign(CodeGen::CodeGenFunction &CGF,
+                                    llvm::Value *src, llvm::Value *dest) = 0;
+  virtual void EmitObjCStrongCastAssign(CodeGen::CodeGenFunction &CGF,
+                                        llvm::Value *src, llvm::Value *dest) = 0;
 };
 
 /// Creates an instance of an Objective-C runtime class.  
index ef2cb033c95a96f631272379e52f707e019a3253..c328e35931d4081b6f76e144a8143f4491775cff 100644 (file)
@@ -106,6 +106,12 @@ class LValue {
     PropertyRef   // This is an Objective-C property reference, use
                   // getPropertyRefExpr
   } LVType;
+
+  enum ObjCType {
+    None = 0,  // object with no gc attribute.
+    Weak,      // __weak object expression
+    Strong      // __strong object expression
+  };
   
   llvm::Value *V;
   
@@ -130,9 +136,9 @@ class LValue {
   bool Volatile:1;
   // FIXME: set but never used, what effect should it have?
   bool Restrict:1;
-  
-  bool ObjcWeak:1;
-  bool ObjcStrong:1;
+
+  // objective-c's gc attributes
+  unsigned ObjCType : 2;  
 
 private:
   static void SetQualifiers(unsigned Qualifiers, LValue& R) {
@@ -140,8 +146,7 @@ private:
     R.Restrict = (Qualifiers&QualType::Restrict)!=0;
     // FIXME: Convenient place to set objc flags to 0. This
     // should really be done in a user-defined constructor instead.
-    R.ObjcWeak = 0;
-    R.ObjcStrong = 0;
+    R.ObjCType = None;
   }
   
 public:
@@ -154,12 +159,14 @@ public:
   bool isVolatileQualified() const { return Volatile; }
   bool isRestrictQualified() const { return Restrict; }
   
-  bool isObjcWeak() const { return ObjcWeak; }
-  bool isObjcStrong() const { return ObjcStrong; }
+  bool ObjcWeak() const { return ObjCType == Weak; }
+  bool ObjcStrong() const { return ObjCType == Strong; }
   
-  static void SetObjCGCAttrs(unsigned Weak, unsigned Strong, LValue& R) {
-    R.ObjcWeak = Weak;
-    R.ObjcStrong = Strong;
+  static void SetObjCType(unsigned WeakVal, unsigned StrongVal, LValue& R) {
+    if (WeakVal)
+      R.ObjCType = Weak;
+    else if (StrongVal)
+      R.ObjCType = Strong;
   }
   
   // simple lvalue