[cfe-commits] r56547 - in /cfe/trunk/lib/CodeGen: CGObjC.cpp CGObjCMac.cpp

Daniel Dunbar daniel at zuster.org
Tue Sep 23 23:32:09 PDT 2008


Author: ddunbar
Date: Wed Sep 24 01:32:09 2008
New Revision: 56547

URL: http://llvm.org/viewvc/llvm-project?rev=56547&view=rev
Log:
Implement Obj-C synthesized setters for copy / retain.

Modified:
    cfe/trunk/lib/CodeGen/CGObjC.cpp
    cfe/trunk/lib/CodeGen/CGObjCMac.cpp

Modified: cfe/trunk/lib/CodeGen/CGObjC.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGObjC.cpp?rev=56547&r1=56546&r2=56547&view=diff

==============================================================================
--- cfe/trunk/lib/CodeGen/CGObjC.cpp (original)
+++ cfe/trunk/lib/CodeGen/CGObjC.cpp Wed Sep 24 01:32:09 2008
@@ -206,6 +206,7 @@
 /// function. The given Decl must be either an ObjCCategoryImplDecl
 /// or an ObjCImplementationDecl.
 void CodeGenFunction::GenerateObjCSetter(const ObjCPropertyImplDecl *PID) {
+  ObjCIvarDecl *Ivar = PID->getPropertyIvarDecl();
   const ObjCPropertyDecl *PD = PID->getPropertyDecl();
   ObjCMethodDecl *OMD = PD->getSetterMethodDecl();
   assert(OMD && "Invalid call to generate setter (empty method)");
@@ -213,29 +214,69 @@
   // not have been created by Sema for us.  
   OMD->createImplicitParams(getContext());
   StartObjCMethod(OMD);
-  
-  switch (PD->getSetterKind()) {
-  case ObjCPropertyDecl::Assign: break;
-  case ObjCPropertyDecl::Copy:
-      CGM.ErrorUnsupported(PID, "Obj-C setter with 'copy'");
-      break;
-  case ObjCPropertyDecl::Retain:
-      CGM.ErrorUnsupported(PID, "Obj-C setter with 'retain'");
-      break;
-  }
 
-  // FIXME: What about nonatomic?
-  SourceLocation Loc = PD->getLocation();
-  ValueDecl *Self = OMD->getSelfDecl();
-  ObjCIvarDecl *Ivar = PID->getPropertyIvarDecl();
-  DeclRefExpr Base(Self, Self->getType(), Loc);
-  ParmVarDecl *ArgDecl = OMD->getParamDecl(0);
-  DeclRefExpr Arg(ArgDecl, ArgDecl->getType(), Loc);
-  ObjCIvarRefExpr IvarRef(Ivar, Ivar->getType(), Loc, &Base,
-                          true, true);
-  BinaryOperator Assign(&IvarRef, &Arg, BinaryOperator::Assign,
-                        Ivar->getType(), Loc);
-  EmitStmt(&Assign);
+  bool IsCopy = PD->getSetterKind() == ObjCPropertyDecl::Copy;
+  bool IsAtomic = 
+    !(PD->getPropertyAttributes() & ObjCPropertyDecl::OBJC_PR_nonatomic);
+
+  // Determine if we should use an objc_setProperty call for
+  // this. Properties with 'copy' semantics always use it, as do
+  // non-atomic properties with 'release' semantics as long as we are
+  // not in gc-only mode.
+  if (IsCopy ||
+      (CGM.getLangOptions().getGCMode() != LangOptions::GCOnly &&
+       PD->getSetterKind() == ObjCPropertyDecl::Retain)) {
+    llvm::Value *SetPropertyFn = 
+      CGM.getObjCRuntime().GetPropertySetFunction();
+    
+    if (!SetPropertyFn) {
+      CGM.ErrorUnsupported(PID, "Obj-C getter requiring atomic copy");
+      FinishFunction();
+      return;
+    }
+    
+    // Emit objc_setProperty((id) self, _cmd, offset, arg, 
+    //                       <is-atomic>, <is-copy>).
+    // FIXME: Can't this be simpler? This might even be worse than the
+    // corresponding gcc code.
+    CodeGenTypes &Types = CGM.getTypes();
+    ValueDecl *Cmd = OMD->getCmdDecl();
+    llvm::Value *CmdVal = Builder.CreateLoad(LocalDeclMap[Cmd], "cmd");
+    QualType IdTy = getContext().getObjCIdType();
+    llvm::Value *SelfAsId = 
+      Builder.CreateBitCast(LoadObjCSelf(), Types.ConvertType(IdTy));
+    llvm::Value *Offset = EmitIvarOffset(OMD->getClassInterface(), Ivar);
+    llvm::Value *Arg = LocalDeclMap[OMD->getParamDecl(0)];
+    llvm::Value *ArgAsId = 
+      Builder.CreateBitCast(Builder.CreateLoad(Arg, "arg"),
+                            Types.ConvertType(IdTy));
+    llvm::Value *True =
+      llvm::ConstantInt::get(Types.ConvertTypeForMem(getContext().BoolTy), 1);
+    llvm::Value *False =
+      llvm::ConstantInt::get(Types.ConvertTypeForMem(getContext().BoolTy), 0);
+    CallArgList Args;
+    Args.push_back(std::make_pair(RValue::get(SelfAsId), IdTy));
+    Args.push_back(std::make_pair(RValue::get(CmdVal), Cmd->getType()));
+    Args.push_back(std::make_pair(RValue::get(Offset), getContext().LongTy));
+    Args.push_back(std::make_pair(RValue::get(ArgAsId), IdTy));
+    Args.push_back(std::make_pair(RValue::get(IsAtomic ? True : False), 
+                                  getContext().BoolTy));
+    Args.push_back(std::make_pair(RValue::get(IsCopy ? True : False), 
+                                  getContext().BoolTy));
+    EmitCall(SetPropertyFn, PD->getType(), Args);
+  } else {
+    SourceLocation Loc = PD->getLocation();
+    ValueDecl *Self = OMD->getSelfDecl();
+    ObjCIvarDecl *Ivar = PID->getPropertyIvarDecl();
+    DeclRefExpr Base(Self, Self->getType(), Loc);
+    ParmVarDecl *ArgDecl = OMD->getParamDecl(0);
+    DeclRefExpr Arg(ArgDecl, ArgDecl->getType(), Loc);
+    ObjCIvarRefExpr IvarRef(Ivar, Ivar->getType(), Loc, &Base,
+                            true, true);
+    BinaryOperator Assign(&IvarRef, &Arg, BinaryOperator::Assign,
+                          Ivar->getType(), Loc);
+    EmitStmt(&Assign);
+  }
 
   FinishFunction();
 }

Modified: cfe/trunk/lib/CodeGen/CGObjCMac.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGObjCMac.cpp?rev=56547&r1=56546&r2=56547&view=diff

==============================================================================
--- cfe/trunk/lib/CodeGen/CGObjCMac.cpp (original)
+++ cfe/trunk/lib/CodeGen/CGObjCMac.cpp Wed Sep 24 01:32:09 2008
@@ -2164,10 +2164,11 @@
   Params.push_back(ObjectPtrTy);
   Params.push_back(SelectorPtrTy);
   Params.push_back(LongTy);
+  Params.push_back(ObjectPtrTy);
   Params.push_back(Types.ConvertTypeForMem(Ctx.BoolTy));
   Params.push_back(Types.ConvertTypeForMem(Ctx.BoolTy));
   SetPropertyFn =
-    llvm::Function::Create(llvm::FunctionType::get(ObjectPtrTy,
+    llvm::Function::Create(llvm::FunctionType::get(llvm::Type::VoidTy,
                                                    Params,
                                                    false),
                            llvm::Function::ExternalLinkage,





More information about the cfe-commits mailing list