forked from OSchip/llvm-project
This patch adds support for sender-aware dispatch in Objective-C for the GNU runtime, when
compiled with -fobjc-sender-dependent-dispatch. This is used in AOP, COP, implementing object planes, and a few other things. Patch by David Chisnall. llvm-svn: 72275
This commit is contained in:
parent
162af638a9
commit
a4404f21d1
|
@ -36,6 +36,8 @@ public:
|
|||
|
||||
unsigned ObjC1 : 1; // Objective-C 1 support enabled.
|
||||
unsigned ObjC2 : 1; // Objective-C 2 support enabled.
|
||||
unsigned ObjCSenderDispatch: 1; // Objective-C 2 three-dimensional dispatch
|
||||
// enabled.
|
||||
unsigned ObjCNonFragileABI : 1; // Objective-C modern abi enabled
|
||||
|
||||
unsigned PascalStrings : 1; // Allow Pascal strings
|
||||
|
|
|
@ -425,6 +425,7 @@ OPTION("-fobjc-gc-only", fobjc_gc_only, Flag, f_Group, INVALID, "", 0, 0, 0)
|
|||
OPTION("-fobjc-gc", fobjc_gc, Flag, f_Group, INVALID, "", 0, 0, 0)
|
||||
OPTION("-fobjc-new-property", fobjc_new_property, Flag, clang_ignored_f_Group, INVALID, "", 0, 0, 0)
|
||||
OPTION("-fobjc-nonfragile-abi", fobjc_nonfragile_abi, Flag, f_Group, INVALID, "", 0, 0, 0)
|
||||
OPTION("-fobjc-sender-dependent-dispatch", fobjc_sender_dependent_dispatch, Flag, f_Group, INVALID, "", 0, 0, 0)
|
||||
OPTION("-fobjc-tight-layout", fobjc_tight_layout, Flag, f_Group, INVALID, "", 0, 0, 0)
|
||||
OPTION("-fobjc", fobjc, Flag, f_Group, INVALID, "", 0, 0, 0)
|
||||
OPTION("-fomit-frame-pointer", fomit_frame_pointer, Flag, f_Group, INVALID, "", 0, 0, 0)
|
||||
|
|
|
@ -417,8 +417,8 @@ CGObjCGNU::GenerateMessageSend(CodeGen::CodeGenFunction &CGF,
|
|||
CallArgList ActualArgs;
|
||||
|
||||
ActualArgs.push_back(
|
||||
std::make_pair(RValue::get(CGF.Builder.CreateBitCast(Receiver, IdTy)),
|
||||
CGF.getContext().getObjCIdType()));
|
||||
std::make_pair(RValue::get(CGF.Builder.CreateBitCast(Receiver, IdTy)),
|
||||
CGF.getContext().getObjCIdType()));
|
||||
ActualArgs.push_back(std::make_pair(RValue::get(cmd),
|
||||
CGF.getContext().getObjCSelType()));
|
||||
ActualArgs.insert(ActualArgs.end(), CallArgs.begin(), CallArgs.end());
|
||||
|
@ -427,15 +427,36 @@ CGObjCGNU::GenerateMessageSend(CodeGen::CodeGenFunction &CGF,
|
|||
const CGFunctionInfo &FnInfo = Types.getFunctionInfo(ResultType, ActualArgs);
|
||||
const llvm::FunctionType *impType = Types.GetFunctionType(FnInfo, false);
|
||||
|
||||
llvm::Value *imp;
|
||||
std::vector<const llvm::Type*> Params;
|
||||
Params.push_back(Receiver->getType());
|
||||
Params.push_back(SelectorTy);
|
||||
llvm::Constant *lookupFunction =
|
||||
CGM.CreateRuntimeFunction(llvm::FunctionType::get(
|
||||
llvm::PointerType::getUnqual(impType), Params, true),
|
||||
"objc_msg_lookup");
|
||||
// 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);
|
||||
if (CGM.getContext().getLangOptions().ObjCSenderDispatch) {
|
||||
llvm::Value *self;
|
||||
|
||||
llvm::Value *imp = CGF.Builder.CreateCall2(lookupFunction, Receiver, cmd);
|
||||
if (isa<ObjCMethodDecl>(CGF.CurFuncDecl)) {
|
||||
self = CGF.LoadObjCSelf();
|
||||
} else {
|
||||
self = llvm::ConstantPointerNull::get(IdTy);
|
||||
}
|
||||
Params.push_back(self->getType());
|
||||
llvm::Constant *lookupFunction =
|
||||
CGM.CreateRuntimeFunction(llvm::FunctionType::get(
|
||||
llvm::PointerType::getUnqual(impType), Params, true),
|
||||
"objc_msg_lookup_sender");
|
||||
|
||||
imp = CGF.Builder.CreateCall3(lookupFunction, Receiver, cmd, self);
|
||||
} else {
|
||||
llvm::Constant *lookupFunction =
|
||||
CGM.CreateRuntimeFunction(llvm::FunctionType::get(
|
||||
llvm::PointerType::getUnqual(impType), Params, true),
|
||||
"objc_msg_lookup");
|
||||
|
||||
imp = CGF.Builder.CreateCall2(lookupFunction, Receiver, cmd);
|
||||
}
|
||||
|
||||
return CGF.EmitCall(FnInfo, imp, ActualArgs);
|
||||
}
|
||||
|
|
|
@ -479,6 +479,7 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA,
|
|||
Args.AddLastArg(CmdArgs, options::OPT_fno_show_column);
|
||||
Args.AddLastArg(CmdArgs, options::OPT_fobjc_gc_only);
|
||||
Args.AddLastArg(CmdArgs, options::OPT_fobjc_gc);
|
||||
Args.AddLastArg(CmdArgs, options::OPT_fobjc_sender_dependent_dispatch);
|
||||
// FIXME: Should we remove this?
|
||||
Args.AddLastArg(CmdArgs, options::OPT_fobjc_nonfragile_abi);
|
||||
Args.AddLastArg(CmdArgs, options::OPT_fobjc_tight_layout);
|
||||
|
|
|
@ -280,6 +280,9 @@ static void InitializePredefinedMacros(const TargetInfo &TI,
|
|||
if (LangOpts.ObjC2)
|
||||
DefineBuiltinMacro(Buf, "OBJC_NEW_PROPERTIES");
|
||||
|
||||
if (LangOpts.ObjCSenderDispatch)
|
||||
DefineBuiltinMacro(Buf, "__OBJC_SENDER_AWARE_DISPATCH__");
|
||||
|
||||
if (LangOpts.PascalStrings)
|
||||
DefineBuiltinMacro(Buf, "__PASCAL_STRINGS__");
|
||||
|
||||
|
|
|
@ -445,6 +445,10 @@ OverflowChecking("ftrapv",
|
|||
llvm::cl::desc("Trap on integer overflow"),
|
||||
llvm::cl::init(false));
|
||||
|
||||
static llvm::cl::opt<bool>
|
||||
ObjCSenderDispatch("fobjc-sender-dependent-dispatch",
|
||||
llvm::cl::desc("Enable sender-dependent dispatch for"
|
||||
"Objective-C messages"), llvm::cl::init(false));
|
||||
|
||||
/// InitializeBaseLanguage - Handle the -x foo options.
|
||||
static void InitializeBaseLanguage() {
|
||||
|
@ -827,6 +831,8 @@ static void InitializeLanguageStandard(LangOptions &Options, LangKind LK,
|
|||
|
||||
if (ObjCNonFragileABI)
|
||||
Options.ObjCNonFragileABI = 1;
|
||||
|
||||
Options.ObjCSenderDispatch = ObjCSenderDispatch;
|
||||
|
||||
if (EmitAllDecls)
|
||||
Options.EmitAllDecls = 1;
|
||||
|
|
Loading…
Reference in New Issue