From 34e65770ad6142b033d6cec4f476ed20fb248bf3 Mon Sep 17 00:00:00 2001 From: Fariborz Jahanian Date: Fri, 22 May 2009 20:17:16 +0000 Subject: [PATCH] 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. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@72275 91177308-0d34-0410-b5e6-96231b3b80d8 --- include/clang/Basic/LangOptions.h | 2 ++ include/clang/Driver/Options.def | 1 + lib/CodeGen/CGObjCGNU.cpp | 33 +++++++++++++++++++++++++------ lib/Driver/Tools.cpp | 1 + lib/Frontend/InitPreprocessor.cpp | 3 +++ tools/clang-cc/clang-cc.cpp | 6 ++++++ 6 files changed, 40 insertions(+), 6 deletions(-) diff --git a/include/clang/Basic/LangOptions.h b/include/clang/Basic/LangOptions.h index 1214afacd0..74e70a6985 100644 --- a/include/clang/Basic/LangOptions.h +++ b/include/clang/Basic/LangOptions.h @@ -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 diff --git a/include/clang/Driver/Options.def b/include/clang/Driver/Options.def index 2ec2336c8d..cd046bc930 100644 --- a/include/clang/Driver/Options.def +++ b/include/clang/Driver/Options.def @@ -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) diff --git a/lib/CodeGen/CGObjCGNU.cpp b/lib/CodeGen/CGObjCGNU.cpp index 2cae9a0ea8..5e7eec9819 100644 --- a/lib/CodeGen/CGObjCGNU.cpp +++ b/lib/CodeGen/CGObjCGNU.cpp @@ -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 Params; Params.push_back(Receiver->getType()); Params.push_back(SelectorTy); - llvm::Constant *lookupFunction = - CGM.CreateRuntimeFunction(llvm::FunctionType::get( + // 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; + + if (isa(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"); + "objc_msg_lookup_sender"); - llvm::Value *imp = CGF.Builder.CreateCall2(lookupFunction, Receiver, cmd); + 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); } diff --git a/lib/Driver/Tools.cpp b/lib/Driver/Tools.cpp index fd071dfe28..abfabbb721 100644 --- a/lib/Driver/Tools.cpp +++ b/lib/Driver/Tools.cpp @@ -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); diff --git a/lib/Frontend/InitPreprocessor.cpp b/lib/Frontend/InitPreprocessor.cpp index 1ad9d5c8d3..8f4cdbc5f5 100644 --- a/lib/Frontend/InitPreprocessor.cpp +++ b/lib/Frontend/InitPreprocessor.cpp @@ -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__"); diff --git a/tools/clang-cc/clang-cc.cpp b/tools/clang-cc/clang-cc.cpp index f2f05237a2..5b0f864034 100644 --- a/tools/clang-cc/clang-cc.cpp +++ b/tools/clang-cc/clang-cc.cpp @@ -445,6 +445,10 @@ OverflowChecking("ftrapv", llvm::cl::desc("Trap on integer overflow"), llvm::cl::init(false)); +static llvm::cl::opt +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; -- 2.40.0