diff options
Diffstat (limited to 'lib')
-rw-r--r-- | lib/CodeGen/CGObjCMac.cpp | 17 | ||||
-rw-r--r-- | lib/Driver/ToolChains.h | 6 | ||||
-rw-r--r-- | lib/Driver/Tools.cpp | 18 | ||||
-rw-r--r-- | lib/Frontend/CompilerInvocation.cpp | 26 |
4 files changed, 52 insertions, 15 deletions
diff --git a/lib/CodeGen/CGObjCMac.cpp b/lib/CodeGen/CGObjCMac.cpp index e000bd22aa..098a0f8221 100644 --- a/lib/CodeGen/CGObjCMac.cpp +++ b/lib/CodeGen/CGObjCMac.cpp @@ -4275,13 +4275,19 @@ void CGObjCNonFragileABIMac::FinishNonFragileABIModule() { /// message dispatch call for all the rest. /// bool CGObjCNonFragileABIMac::LegacyDispatchedSelector(Selector Sel) { - if (CGM.getCodeGenOpts().ObjCLegacyDispatch) + switch (CGM.getCodeGenOpts().getObjCDispatchMethod()) { + default: + assert(0 && "Invalid dispatch method!"); + case CodeGenOptions::Legacy: return true; - /* Leopard */ - if (CGM.getContext().Target.getTriple().getOS() == llvm::Triple::Darwin && - CGM.getContext().Target.getTriple().getDarwinMajorNumber() <= 9) + case CodeGenOptions::NonLegacy: return false; - + case CodeGenOptions::Mixed: + break; + } + + // If so, see whether this selector is in the white-list of things which must + // use the new dispatch convention. We lazily build a dense set for this. if (NonLegacyDispatchMethods.empty()) { NonLegacyDispatchMethods.insert(GetNullarySelector("alloc")); NonLegacyDispatchMethods.insert(GetNullarySelector("class")); @@ -4311,6 +4317,7 @@ bool CGObjCNonFragileABIMac::LegacyDispatchedSelector(Selector Sel) { NonLegacyDispatchMethods.insert( CGM.getContext().Selectors.getSelector(3, KeyIdents)); } + return (NonLegacyDispatchMethods.count(Sel) == 0); } diff --git a/lib/Driver/ToolChains.h b/lib/Driver/ToolChains.h index 9e61b8972f..a307b2bdac 100644 --- a/lib/Driver/ToolChains.h +++ b/lib/Driver/ToolChains.h @@ -168,6 +168,12 @@ public: return (getTriple().getArch() == llvm::Triple::arm || getTriple().getArch() == llvm::Triple::thumb); } + virtual bool UseObjCMixedDispatch() const { + // Mixed dispatch is only used on x86_64 for 10.6 and later. + return (!isTargetIPhoneOS() && + getTriple().getArch() == llvm::Triple::x86_64 && + !isMacosxVersionLT(10, 6)); + } virtual bool IsUnwindTablesDefault() const; virtual unsigned GetDefaultStackProtectorLevel() const { // Stack protectors default to on for 10.6 and beyond. diff --git a/lib/Driver/Tools.cpp b/lib/Driver/Tools.cpp index 2e8db0062d..8ad04aa508 100644 --- a/lib/Driver/Tools.cpp +++ b/lib/Driver/Tools.cpp @@ -1230,13 +1230,17 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA, if (Args.hasArg(options::OPT_fobjc_nonfragile_abi) || getToolChain().IsObjCNonFragileABIDefault()) { CmdArgs.push_back("-fobjc-nonfragile-abi"); - - // -fobjc-legacy-dispatch is only relevant with the nonfragile-abi, and - // defaults to off. - if (Args.hasFlag(options::OPT_fobjc_legacy_dispatch, - options::OPT_fno_objc_legacy_dispatch, - getToolChain().IsObjCLegacyDispatchDefault())) - CmdArgs.push_back("-fobjc-legacy-dispatch"); + + // -fobjc-dispatch-method is only relevant with the nonfragile-abi, and + // legacy is the default. + if (!Args.hasFlag(options::OPT_fobjc_legacy_dispatch, + options::OPT_fno_objc_legacy_dispatch, + getToolChain().IsObjCLegacyDispatchDefault())) { + if (getToolChain().UseObjCMixedDispatch()) + CmdArgs.push_back("-fobjc-dispatch-method=mixed"); + else + CmdArgs.push_back("-fobjc-dispatch-method=non-legacy"); + } } } diff --git a/lib/Frontend/CompilerInvocation.cpp b/lib/Frontend/CompilerInvocation.cpp index db937bc4c7..68842a4015 100644 --- a/lib/Frontend/CompilerInvocation.cpp +++ b/lib/Frontend/CompilerInvocation.cpp @@ -178,8 +178,16 @@ static void CodeGenOptsToArgs(const CodeGenOptions &Opts, } if (Opts.NoZeroInitializedInBSS) Res.push_back("-mno-zero-initialized-bss"); - if (Opts.ObjCLegacyDispatch) - Res.push_back("-fobjc-legacy-dispatch"); + switch (Opts.getObjCDispatchMethod()) { + case CodeGenOptions::Legacy: + break; + case CodeGenOptions::Mixed: + Res.push_back("-fobjc-dispatch-method=mixed"); + break; + case CodeGenOptions::NonLegacy: + Res.push_back("-fobjc-dispatch-method=non-legacy"); + break; + } if (Opts.SoftFloat) Res.push_back("-msoft-float"); if (Opts.UnwindTables) @@ -820,7 +828,6 @@ static void ParseCodeGenArgs(CodeGenOptions &Opts, ArgList &Args, Opts.FloatABI = getLastArgValue(Args, OPT_mfloat_abi); Opts.LimitFloatPrecision = getLastArgValue(Args, OPT_mlimit_float_precision); Opts.NoZeroInitializedInBSS = Args.hasArg(OPT_mno_zero_initialized_in_bss); - Opts.ObjCLegacyDispatch = Args.hasArg(OPT_fobjc_legacy_dispatch); Opts.SoftFloat = Args.hasArg(OPT_msoft_float); Opts.UnwindTables = Args.hasArg(OPT_munwind_tables); Opts.RelocationModel = getLastArgValue(Args, OPT_mrelocation_model, "pic"); @@ -830,6 +837,19 @@ static void ParseCodeGenArgs(CodeGenOptions &Opts, ArgList &Args, Opts.MainFileName = getLastArgValue(Args, OPT_main_file_name); Opts.VerifyModule = !Args.hasArg(OPT_disable_llvm_verifier); + + if (Arg *A = Args.getLastArg(OPT_fobjc_dispatch_method_EQ)) { + llvm::StringRef Name = A->getValue(Args); + unsigned Method = llvm::StringSwitch<unsigned>(Name) + .Case("legacy", CodeGenOptions::Legacy) + .Case("non-legacy", CodeGenOptions::NonLegacy) + .Case("mixed", CodeGenOptions::Mixed) + .Default(~0U); + if (Method == ~0U) + Diags.Report(diag::err_drv_invalid_value) << A->getAsString(Args) << Name; + else + Opts.ObjCDispatchMethod = Method; + } } static void ParseDependencyOutputArgs(DependencyOutputOptions &Opts, |