aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--include/clang/Basic/LangOptions.h2
-rw-r--r--include/clang/Driver/Options.def1
-rw-r--r--lib/CodeGen/CGObjCGNU.cpp33
-rw-r--r--lib/Driver/Tools.cpp1
-rw-r--r--lib/Frontend/InitPreprocessor.cpp3
-rw-r--r--tools/clang-cc/clang-cc.cpp6
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<const llvm::Type*> 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<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");
+ "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<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;