diff options
Diffstat (limited to 'clang/lib')
-rw-r--r-- | clang/lib/CodeGen/CGObjCGNU.cpp | 33 | ||||
-rw-r--r-- | clang/lib/Driver/Tools.cpp | 1 | ||||
-rw-r--r-- | clang/lib/Frontend/InitPreprocessor.cpp | 3 |
3 files changed, 31 insertions, 6 deletions
diff --git a/clang/lib/CodeGen/CGObjCGNU.cpp b/clang/lib/CodeGen/CGObjCGNU.cpp index 2cae9a0ea87..5e7eec9819c 100644 --- a/clang/lib/CodeGen/CGObjCGNU.cpp +++ b/clang/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/clang/lib/Driver/Tools.cpp b/clang/lib/Driver/Tools.cpp index fd071dfe282..abfabbb721a 100644 --- a/clang/lib/Driver/Tools.cpp +++ b/clang/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/clang/lib/Frontend/InitPreprocessor.cpp b/clang/lib/Frontend/InitPreprocessor.cpp index 1ad9d5c8d3b..8f4cdbc5f5d 100644 --- a/clang/lib/Frontend/InitPreprocessor.cpp +++ b/clang/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__"); |