]> granicus.if.org Git - clang/commitdiff
Patch fixes a code gen. bug in generation of objc_assign_ivar
authorFariborz Jahanian <fjahanian@apple.com>
Thu, 24 Sep 2009 22:25:38 +0000 (22:25 +0000)
committerFariborz Jahanian <fjahanian@apple.com>
Thu, 24 Sep 2009 22:25:38 +0000 (22:25 +0000)
(objc GC's API).

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@82724 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 309f38e080a56b83099b7c39b97305c8377deb97..332d47c1dd924ea5a0d71b2a385bd2d5784dc54f 100644 (file)
@@ -490,8 +490,17 @@ void CodeGenFunction::EmitStoreThroughLValue(RValue Src, LValue Dst,
     // load of a __strong object.
     llvm::Value *LvalueDst = Dst.getAddress();
     llvm::Value *src = Src.getScalarVal();
-    if (Dst.isObjCIvar())
-      CGM.getObjCRuntime().EmitObjCIvarAssign(*this, src, LvalueDst);
+    if (Dst.isObjCIvar()) {
+      assert(Dst.getBaseIvarExp() && "BaseIvarExp is NULL");
+      const llvm::Type *ResultType = ConvertType(getContext().LongTy);
+      llvm::Value *RHS = EmitScalarExpr(Dst.getBaseIvarExp());
+      RHS = Builder.CreatePtrToInt(RHS, ResultType, "sub.ptr.rhs.cast");
+      llvm::Value *LHS = 
+        Builder.CreatePtrToInt(LvalueDst, ResultType, "sub.ptr.lhs.cast");
+      llvm::Value *BytesBetween = Builder.CreateSub(LHS, RHS, "ivar.offset");
+      CGM.getObjCRuntime().EmitObjCIvarAssign(*this, src, LvalueDst,
+                                              BytesBetween);
+    }
     else if (Dst.isGlobalObjCRef())
       CGM.getObjCRuntime().EmitObjCGlobalAssign(*this, src, LvalueDst);
     else
@@ -694,6 +703,8 @@ void setObjCGCLValueClass(const ASTContext &Ctx, const Expr *E, LValue &LV) {
   
   if (isa<ObjCIvarRefExpr>(E)) {
     LV.SetObjCIvar(LV, true);
+    ObjCIvarRefExpr *Exp = cast<ObjCIvarRefExpr>(const_cast<Expr*>(E));
+    LV.setBaseIvarExp(Exp->getBase());
     LV.SetObjCArray(LV, E->getType()->isArrayType());
     return;
   }
index e19debc97f8e76efe197247e3c0a40cad296c1a7..a08ec472e97f3494e83125c4f7e1de4c25265d5a 100644 (file)
@@ -170,7 +170,8 @@ public:
   virtual void EmitObjCGlobalAssign(CodeGen::CodeGenFunction &CGF,
                                     llvm::Value *src, llvm::Value *dest);
   virtual void EmitObjCIvarAssign(CodeGen::CodeGenFunction &CGF,
-                                    llvm::Value *src, llvm::Value *dest);
+                                    llvm::Value *src, llvm::Value *dest,
+                                    llvm::Value *ivarOffset);
   virtual void EmitObjCStrongCastAssign(CodeGen::CodeGenFunction &CGF,
                                         llvm::Value *src, llvm::Value *dest);
   virtual void EmitGCMemmoveCollectable(CodeGen::CodeGenFunction &CGF,
@@ -1873,7 +1874,8 @@ void CGObjCGNU::EmitObjCGlobalAssign(CodeGen::CodeGenFunction &CGF,
 }
 
 void CGObjCGNU::EmitObjCIvarAssign(CodeGen::CodeGenFunction &CGF,
-                                   llvm::Value *src, llvm::Value *dst) {
+                                   llvm::Value *src, llvm::Value *dst,
+                                   llvm::Value *ivarOffset) {
   return;
 }
 
index b9f4f3471c9142ab36925a65896786bca6eed79e..bc4e7f9378b3a0b7d577fa41ee80b61be5908717 100644 (file)
@@ -369,9 +369,10 @@ public:
 
   /// GcAssignIvarFn -- LLVM objc_assign_ivar function.
   llvm::Constant *getGcAssignIvarFn() {
-    // id objc_assign_ivar(id, id *)
+    // id objc_assign_ivar(id, id *, ptrdiff_t)
     std::vector<const llvm::Type*> Args(1, ObjectPtrTy);
     Args.push_back(ObjectPtrTy->getPointerTo());
+    Args.push_back(LongTy);
     llvm::FunctionType *FTy =
       llvm::FunctionType::get(ObjectPtrTy, Args, false);
     return CGM.CreateRuntimeFunction(FTy, "objc_assign_ivar");
@@ -1130,7 +1131,8 @@ public:
   virtual void EmitObjCGlobalAssign(CodeGen::CodeGenFunction &CGF,
                                     llvm::Value *src, llvm::Value *dest);
   virtual void EmitObjCIvarAssign(CodeGen::CodeGenFunction &CGF,
-                                  llvm::Value *src, llvm::Value *dest);
+                                  llvm::Value *src, llvm::Value *dest,
+                                  llvm::Value *ivarOffset);
   virtual void EmitObjCStrongCastAssign(CodeGen::CodeGenFunction &CGF,
                                         llvm::Value *src, llvm::Value *dest);
   virtual void EmitGCMemmoveCollectable(CodeGen::CodeGenFunction &CGF,
@@ -1360,7 +1362,8 @@ public:
   virtual void EmitObjCGlobalAssign(CodeGen::CodeGenFunction &CGF,
                                     llvm::Value *src, llvm::Value *dest);
   virtual void EmitObjCIvarAssign(CodeGen::CodeGenFunction &CGF,
-                                  llvm::Value *src, llvm::Value *dest);
+                                  llvm::Value *src, llvm::Value *dest,
+                                  llvm::Value *ivarOffset);
   virtual void EmitObjCStrongCastAssign(CodeGen::CodeGenFunction &CGF,
                                         llvm::Value *src, llvm::Value *dest);
   virtual void EmitGCMemmoveCollectable(CodeGen::CodeGenFunction &CGF,
@@ -2745,10 +2748,12 @@ void CGObjCMac::EmitObjCGlobalAssign(CodeGen::CodeGenFunction &CGF,
 }
 
 /// EmitObjCIvarAssign - Code gen for assigning to a __strong object.
-/// objc_assign_ivar (id src, id *dst)
+/// objc_assign_ivar (id src, id *dst, ptrdiff_t ivaroffset)
 ///
 void CGObjCMac::EmitObjCIvarAssign(CodeGen::CodeGenFunction &CGF,
-                                   llvm::Value *src, llvm::Value *dst) {
+                                   llvm::Value *src, llvm::Value *dst,
+                                   llvm::Value *ivarOffset) {
+  assert(ivarOffset && "EmitObjCIvarAssign - ivarOffset is NULL");
   const llvm::Type * SrcTy = src->getType();
   if (!isa<llvm::PointerType>(SrcTy)) {
     unsigned Size = CGM.getTargetData().getTypeAllocSize(SrcTy);
@@ -2759,8 +2764,8 @@ void CGObjCMac::EmitObjCIvarAssign(CodeGen::CodeGenFunction &CGF,
   }
   src = CGF.Builder.CreateBitCast(src, ObjCTypes.ObjectPtrTy);
   dst = CGF.Builder.CreateBitCast(dst, ObjCTypes.PtrObjectPtrTy);
-  CGF.Builder.CreateCall2(ObjCTypes.getGcAssignIvarFn(),
-                          src, dst, "assignivar");
+  CGF.Builder.CreateCall3(ObjCTypes.getGcAssignIvarFn(),
+                          src, dst, ivarOffset);
   return;
 }
 
@@ -5268,11 +5273,12 @@ llvm::Value *CGObjCNonFragileABIMac::EmitSelector(CGBuilderTy &Builder,
   return Builder.CreateLoad(Entry, false, "tmp");
 }
 /// EmitObjCIvarAssign - Code gen for assigning to a __strong object.
-/// objc_assign_ivar (id src, id *dst)
+/// objc_assign_ivar (id src, id *dst, ptrdiff_t)
 ///
 void CGObjCNonFragileABIMac::EmitObjCIvarAssign(CodeGen::CodeGenFunction &CGF,
                                                 llvm::Value *src,
-                                                llvm::Value *dst) {
+                                                llvm::Value *dst,
+                                                llvm::Value *ivarOffset) {
   const llvm::Type * SrcTy = src->getType();
   if (!isa<llvm::PointerType>(SrcTy)) {
     unsigned Size = CGM.getTargetData().getTypeAllocSize(SrcTy);
@@ -5283,8 +5289,8 @@ void CGObjCNonFragileABIMac::EmitObjCIvarAssign(CodeGen::CodeGenFunction &CGF,
   }
   src = CGF.Builder.CreateBitCast(src, ObjCTypes.ObjectPtrTy);
   dst = CGF.Builder.CreateBitCast(dst, ObjCTypes.PtrObjectPtrTy);
-  CGF.Builder.CreateCall2(ObjCTypes.getGcAssignIvarFn(),
-                          src, dst, "assignivar");
+  CGF.Builder.CreateCall3(ObjCTypes.getGcAssignIvarFn(),
+                          src, dst, ivarOffset);
   return;
 }
 
index a903ac39464996505dfd4b0d3b0892c34b222c12..6b4556239723da0d39f8931abfb519326dbcf847 100644 (file)
@@ -189,7 +189,8 @@ public:
   virtual void EmitObjCGlobalAssign(CodeGen::CodeGenFunction &CGF,
                                     llvm::Value *src, llvm::Value *dest) = 0;
   virtual void EmitObjCIvarAssign(CodeGen::CodeGenFunction &CGF,
-                                  llvm::Value *src, llvm::Value *dest) = 0;
+                                  llvm::Value *src, llvm::Value *dest,
+                                  llvm::Value *ivarOffset) = 0;
   virtual void EmitObjCStrongCastAssign(CodeGen::CodeGenFunction &CGF,
                                         llvm::Value *src, llvm::Value *dest) = 0;
 
index ee9dc524c6ec8c3d814e7ec0a3b6e4d1a1e11266..2a06f51f6685de9c4d768d00ac51ea0b3a961e1f 100644 (file)
@@ -156,6 +156,7 @@ class LValue {
   // Lvalue is a global reference of an objective-c object
   bool GlobalObjCRef : 1;
 
+  Expr *BaseIvarExp;
 private:
   void SetQualifiers(Qualifiers Quals) {
     this->Quals = Quals;
@@ -163,6 +164,7 @@ private:
     // FIXME: Convenient place to set objc flags to 0. This should really be
     // done in a user-defined constructor instead.
     this->Ivar = this->ObjIsArray = this->NonGC = this->GlobalObjCRef = false;
+    this->BaseIvarExp = 0;
   }
 
 public:
@@ -185,6 +187,9 @@ public:
   bool isGlobalObjCRef() const { return GlobalObjCRef; }
   bool isObjCWeak() const { return Quals.getObjCGCAttr() == Qualifiers::Weak; }
   bool isObjCStrong() const { return Quals.getObjCGCAttr() == Qualifiers::Strong; }
+  
+  Expr *getBaseIvarExp() const { return BaseIvarExp; }
+  void setBaseIvarExp(Expr *V) { BaseIvarExp = V; }
 
   unsigned getAddressSpace() const { return Quals.getAddressSpace(); }