]> granicus.if.org Git - clang/commitdiff
Enable experimental support for objc_msgSend with GNUstep ObjC runtime.
authorDavid Chisnall <csdavec@swan.ac.uk>
Mon, 24 Oct 2011 14:07:03 +0000 (14:07 +0000)
committerDavid Chisnall <csdavec@swan.ac.uk>
Mon, 24 Oct 2011 14:07:03 +0000 (14:07 +0000)
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@142795 91177308-0d34-0410-b5e6-96231b3b80d8

include/clang/Driver/ToolChain.h
lib/CodeGen/CGObjCGNU.cpp

index a5d51ca9d7c9172e64ac24cddab5363bfb8f2afd..b05869693b8c2efc9173cbeab640ff4b2521533d 100644 (file)
@@ -131,7 +131,7 @@ public:
   /// IsObjCLegacyDispatchDefault - Does this tool chain set
   /// -fobjc-legacy-dispatch by default (this is only used with the non-fragile
   /// ABI).
-  virtual bool IsObjCLegacyDispatchDefault() const { return false; }
+  virtual bool IsObjCLegacyDispatchDefault() const { return true; }
 
   /// UseObjCMixedDispatchDefault - When using non-legacy dispatch, should the
   /// mixed dispatch method be used?
index d3da649fbbf3d5656e1a06a8d5c335e5a934b2e5..57dfd28e9e0a12a24ac3240bbad74437923076ed 100644 (file)
@@ -1159,25 +1159,48 @@ CGObjCGNU::GenerateMessageSend(CodeGenFunction &CGF,
    };
   llvm::MDNode *node = llvm::MDNode::get(VMContext, impMD);
 
-  // Get the IMP to call
-  llvm::Value *imp = LookupIMP(CGF, Receiver, cmd, node);
-
+  CodeGenTypes &Types = CGM.getTypes();
   CallArgList ActualArgs;
   ActualArgs.add(RValue::get(Receiver), ASTIdTy);
   ActualArgs.add(RValue::get(cmd), CGF.getContext().getObjCSelType());
   ActualArgs.addFrom(CallArgs);
-
-  CodeGenTypes &Types = CGM.getTypes();
   const CGFunctionInfo &FnInfo = Types.getFunctionInfo(ResultType, ActualArgs,
                                                        FunctionType::ExtInfo());
+  // Get the IMP to call
+  llvm::Value *imp;
+
+  // If we have non-legacy dispatch specified, we try using the objc_msgSend()
+  // functions.  These are not supported on all platforms (or all runtimes on a
+  // given platform), so we 
+  switch (CGM.getCodeGenOpts().getObjCDispatchMethod()) {
+    default:
+      llvm_unreachable("Invalid dispatch method!");
+    case CodeGenOptions::Legacy:
+      fprintf(stderr, "Legacy\n");
+      imp = LookupIMP(CGF, Receiver, cmd, node);
+      break;
+    case CodeGenOptions::Mixed:
+      fprintf(stderr, "Mixed\n");
+    case CodeGenOptions::NonLegacy:
+      fprintf(stderr, "NonLegacy\n");
+      if (CGM.ReturnTypeUsesFPRet(ResultType) || (Method && Method->isVariadic())) {
+        imp = LookupIMP(CGF, Receiver, cmd, node);
+      } else if (CGM.ReturnTypeUsesSRet(FnInfo)) {
+        // The actual types here don't matter - we're going to bitcast the
+        // function anyway
+        imp = CGM.CreateRuntimeFunction(llvm::FunctionType::get(IdTy, IdTy, true),
+                                  "objc_msgSend_stret");
+      } else {
+        imp = CGM.CreateRuntimeFunction(llvm::FunctionType::get(IdTy, IdTy, true),
+                                  "objc_msgSend");
+      }
+  }
+
+
   llvm::FunctionType *impType =
     Types.GetFunctionType(FnInfo, Method ? Method->isVariadic() : false);
   imp = EnforceType(Builder, imp, llvm::PointerType::getUnqual(impType));
 
-
-  // For sender-aware dispatch, we pass the sender as the third argument to a
-  // lookup function.  When sending messages from C code, the sender is nil.
-  // objc_msg_lookup_sender(id *receiver, SEL selector, id sender);
   llvm::Instruction *call;
   RValue msgRet = CGF.EmitCall(FnInfo, imp, Return, ActualArgs,
       0, &call);