Enable experimental support for objc_msgSend with GNUstep ObjC runtime.

llvm-svn: 142795
This commit is contained in:
David Chisnall 2011-10-24 14:07:03 +00:00
parent 812da49172
commit 8c93cf2a27
2 changed files with 33 additions and 10 deletions

View 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?

View 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);