From 6bd37ee37aa8ffb7007e38735ce14f27e5784b40 Mon Sep 17 00:00:00 2001 From: Tim Northover Date: Thu, 16 Jan 2014 08:48:16 +0000 Subject: [PATCH] MachO: use *-*-*-macho for MachO embedded targets. Previously we had bodged together some hacks mapping MachO embedded targets (i.e. mainly ARM v6M and v7M) to the "*-*-darwin-eabi" triple. This is incorrect in both details (they don't run Darwin and they're not EABI in any real sense). This commit appropriates the existing "MachO" environment for the purpose instead. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@199367 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/Basic/Targets.cpp | 9 +- lib/Driver/Driver.cpp | 34 +-- lib/Driver/ToolChain.cpp | 6 +- lib/Driver/ToolChains.cpp | 269 +++++++++++++----- lib/Driver/ToolChains.h | 241 ++++++++++------ lib/Driver/Tools.cpp | 181 +++--------- lib/Driver/Tools.h | 41 +-- test/Driver/darwin-embedded.c | 7 +- .../{darwin-eabi.c => macho-embedded.c} | 10 +- test/Preprocessor/macho-embedded-predefines.c | 5 + 10 files changed, 457 insertions(+), 346 deletions(-) rename test/Driver/{darwin-eabi.c => macho-embedded.c} (68%) create mode 100644 test/Preprocessor/macho-embedded-predefines.c diff --git a/lib/Basic/Targets.cpp b/lib/Basic/Targets.cpp index bb844f13ef..629b540a14 100644 --- a/lib/Basic/Targets.cpp +++ b/lib/Basic/Targets.cpp @@ -90,7 +90,6 @@ static void getDarwinDefines(MacroBuilder &Builder, const LangOptions &Opts, VersionTuple &PlatformMinVersion) { Builder.defineMacro("__APPLE_CC__", "6000"); Builder.defineMacro("__APPLE__"); - Builder.defineMacro("__MACH__"); Builder.defineMacro("OBJC_NEW_PROPERTIES"); // AddressSanitizer doesn't play well with source fortification, which is on // by default on Darwin. @@ -154,7 +153,7 @@ static void getDarwinDefines(MacroBuilder &Builder, const LangOptions &Opts, Str[5] = '\0'; Builder.defineMacro("__ENVIRONMENT_IPHONE_OS_VERSION_MIN_REQUIRED__", Str); - } else { + } else if (Triple.isMacOSX()) { // Note that the Driver allows versions which aren't representable in the // define (because we only get a single digit for the minor and micro // revision numbers). So, we limit them to the maximum representable @@ -171,6 +170,10 @@ static void getDarwinDefines(MacroBuilder &Builder, const LangOptions &Opts, } } + // Tell users about the kernel if there is one. + if (Triple.isOSDarwin()) + Builder.defineMacro("__MACH__"); + PlatformMinVersion = VersionTuple(Maj, Min, Rev); } @@ -5535,7 +5538,7 @@ static TargetInfo *AllocateTarget(const llvm::Triple &Triple) { case llvm::Triple::arm: case llvm::Triple::thumb: - if (Triple.isOSDarwin()) + if (Triple.isOSBinFormatMachO()) return new DarwinARMTargetInfo(Triple); switch (os) { diff --git a/lib/Driver/Driver.cpp b/lib/Driver/Driver.cpp index 253a083109..65df188ea7 100644 --- a/lib/Driver/Driver.cpp +++ b/lib/Driver/Driver.cpp @@ -379,8 +379,8 @@ Compilation *Driver::BuildCompilation(ArrayRef ArgList) { BuildInputs(C->getDefaultToolChain(), *TranslatedArgs, Inputs); // Construct the list of abstract actions to perform for this compilation. On - // Darwin target OSes this uses the driver-driver and universal actions. - if (TC.getTriple().isOSDarwin()) + // MachO targets this uses the driver-driver and universal actions. + if (TC.getTriple().isOSBinFormatMachO()) BuildUniversalActions(C->getDefaultToolChain(), C->getArgs(), Inputs, C->getActions()); else @@ -492,7 +492,7 @@ void Driver::generateCompilationDiagnostics(Compilation &C, // Construct the list of abstract actions to perform for this compilation. On // Darwin OSes this uses the driver-driver and builds universal actions. const ToolChain &TC = C.getDefaultToolChain(); - if (TC.getTriple().isOSDarwin()) + if (TC.getTriple().isOSBinFormatMachO()) BuildUniversalActions(TC, C.getArgs(), Inputs, C.getActions()); else BuildActions(TC, C.getArgs(), Inputs, C.getActions()); @@ -868,7 +868,7 @@ void Driver::BuildUniversalActions(const ToolChain &TC, // Validate the option here; we don't save the type here because its // particular spelling may participate in other driver choices. llvm::Triple::ArchType Arch = - tools::darwin::getArchTypeForDarwinArchName(A->getValue()); + tools::darwin::getArchTypeForMachOArchName(A->getValue()); if (Arch == llvm::Triple::UnknownArch) { Diag(clang::diag::err_drv_invalid_arch_name) << A->getAsString(Args); @@ -1363,7 +1363,7 @@ void Driver::BuildJobs(Compilation &C) const { // Collect the list of architectures. llvm::StringSet<> ArchNames; - if (C.getDefaultToolChain().getTriple().isOSDarwin()) { + if (C.getDefaultToolChain().getTriple().isOSBinFormatMachO()) { for (ArgList::const_iterator it = C.getArgs().begin(), ie = C.getArgs().end(); it != ie; ++it) { Arg *A = *it; @@ -1864,28 +1864,18 @@ static llvm::Triple computeTargetTriple(StringRef DefaultTargetTriple, llvm::Triple Target(llvm::Triple::normalize(DefaultTargetTriple)); - // Handle Darwin-specific options available here. - if (Target.isOSDarwin()) { + // Handle Apple-specific options available here. + if (Target.isOSBinFormatMachO()) { // If an explict Darwin arch name is given, that trumps all. if (!DarwinArchName.empty()) { - if (DarwinArchName == "x86_64h") - Target.setArchName(DarwinArchName); - else - Target.setArch( - tools::darwin::getArchTypeForDarwinArchName(DarwinArchName)); + tools::darwin::setTripleTypeForMachOArchName(Target, DarwinArchName); return Target; } // Handle the Darwin '-arch' flag. if (Arg *A = Args.getLastArg(options::OPT_arch)) { - if (StringRef(A->getValue()) == "x86_64h") - Target.setArchName(A->getValue()); - else { - llvm::Triple::ArchType DarwinArch - = tools::darwin::getArchTypeForDarwinArchName(A->getValue()); - if (DarwinArch != llvm::Triple::UnknownArch) - Target.setArch(DarwinArch); - } + StringRef ArchName = A->getValue(); + tools::darwin::setTripleTypeForMachOArchName(Target, ArchName); } } @@ -1991,6 +1981,10 @@ const ToolChain &Driver::getToolChain(const ArgList &Args, TC = new toolchains::Generic_ELF(*this, Target, Args); break; } + if (Target.getEnvironment() == llvm::Triple::MachO) { + TC = new toolchains::MachO(*this, Target, Args); + break; + } TC = new toolchains::Generic_GCC(*this, Target, Args); break; } diff --git a/lib/Driver/ToolChain.cpp b/lib/Driver/ToolChain.cpp index 9f783e8f66..1cbf70ede9 100644 --- a/lib/Driver/ToolChain.cpp +++ b/lib/Driver/ToolChain.cpp @@ -180,7 +180,7 @@ std::string ToolChain::ComputeLLVMTriple(const ArgList &Args, case llvm::Triple::x86_64: { llvm::Triple Triple = getTriple(); - if (!Triple.isOSDarwin()) + if (!Triple.isOSBinFormatMachO()) return getTripleString(); if (Arg *A = Args.getLastArg(options::OPT_march_EQ)) { @@ -200,12 +200,12 @@ std::string ToolChain::ComputeLLVMTriple(const ArgList &Args, // Thumb2 is the default for V7 on Darwin. // // FIXME: Thumb should just be another -target-feaure, not in the triple. - StringRef Suffix = Triple.isOSDarwin() + StringRef Suffix = Triple.isOSBinFormatMachO() ? tools::arm::getLLVMArchSuffixForARM(tools::arm::getARMCPUForMArch(Args, Triple)) : tools::arm::getLLVMArchSuffixForARM(tools::arm::getARMTargetCPU(Args, Triple)); bool ThumbDefault = Suffix.startswith("v6m") || Suffix.startswith("v7m") || Suffix.startswith("v7em") || - (Suffix.startswith("v7") && getTriple().isOSDarwin()); + (Suffix.startswith("v7") && getTriple().isOSBinFormatMachO()); std::string ArchName = "arm"; // Assembly files should start in ARM mode. diff --git a/lib/Driver/ToolChains.cpp b/lib/Driver/ToolChains.cpp index b8e1d6f0f8..1d32c4586e 100644 --- a/lib/Driver/ToolChains.cpp +++ b/lib/Driver/ToolChains.cpp @@ -42,11 +42,15 @@ using namespace clang::driver::toolchains; using namespace clang; using namespace llvm::opt; -/// Darwin - Darwin tool chain for i386 and x86_64. +MachO::MachO(const Driver &D, const llvm::Triple &Triple, + const ArgList &Args) + : ToolChain(D, Triple, Args) { +} -Darwin::Darwin(const Driver &D, const llvm::Triple& Triple, const ArgList &Args) - : ToolChain(D, Triple, Args), TargetInitialized(false) -{ +/// Darwin - Darwin tool chain for i386 and x86_64. +Darwin::Darwin(const Driver & D, const llvm::Triple & Triple, + const ArgList & Args) + : MachO(D, Triple, Args), TargetInitialized(false) { // Compute the initial Darwin version from the triple unsigned Major, Minor, Micro; if (!Triple.getMacOSXVersion(Major, Minor, Micro)) @@ -67,7 +71,7 @@ Darwin::Darwin(const Driver &D, const llvm::Triple& Triple, const ArgList &Args) << Major << '.' << Minor << '.' << Micro; } -types::ID Darwin::LookupTypeForExtension(const char *Ext) const { +types::ID MachO::LookupTypeForExtension(const char *Ext) const { types::ID Ty = types::lookupTypeForExtension(Ext); // Darwin always preprocesses assembly files (unless -x is used explicitly). @@ -77,7 +81,7 @@ types::ID Darwin::LookupTypeForExtension(const char *Ext) const { return Ty; } -bool Darwin::HasNativeLLVMSupport() const { +bool MachO::HasNativeLLVMSupport() const { return true; } @@ -94,11 +98,9 @@ ObjCRuntime Darwin::getDefaultObjCRuntime(bool isNonFragile) const { bool Darwin::hasBlocksRuntime() const { if (isTargetIOSBased()) return !isIPhoneOSVersionLT(3, 2); - else if (isTargetMacOS()) - return !isMacosxVersionLT(10, 6); else { - assert(isTargetEmbedded() && "unexpected target platform"); - return false; + assert(isTargetMacOS() && "unexpected darwin target"); + return !isMacosxVersionLT(10, 6); } } @@ -147,7 +149,7 @@ static bool isSoftFloatABI(const ArgList &Args) { A->getValue() == StringRef("soft")); } -StringRef Darwin::getDarwinArchName(const ArgList &Args) const { +StringRef MachO::getMachOArchName(const ArgList &Args) const { switch (getTriple().getArch()) { default: return getArchName(); @@ -170,6 +172,17 @@ StringRef Darwin::getDarwinArchName(const ArgList &Args) const { Darwin::~Darwin() { } +MachO::~MachO() { +} + + +std::string MachO::ComputeEffectiveClangTriple(const ArgList &Args, + types::ID InputType) const { + llvm::Triple Triple(ComputeLLVMTriple(Args, InputType)); + + return Triple.getTriple(); +} + std::string Darwin::ComputeEffectiveClangTriple(const ArgList &Args, types::ID InputType) const { llvm::Triple Triple(ComputeLLVMTriple(Args, InputType)); @@ -179,25 +192,17 @@ std::string Darwin::ComputeEffectiveClangTriple(const ArgList &Args, if (!isTargetInitialized()) return Triple.getTriple(); - if (Triple.getArchName() == "thumbv6m" || - Triple.getArchName() == "thumbv7m" || - Triple.getArchName() == "thumbv7em") { - // OS is ios or macosx unless it's the v6m or v7m. - Triple.setOS(llvm::Triple::Darwin); - Triple.setEnvironment(llvm::Triple::EABI); - } else { - SmallString<16> Str; - Str += isTargetIOSBased() ? "ios" : "macosx"; - Str += getTargetVersion().getAsString(); - Triple.setOSName(Str); - } + SmallString<16> Str; + Str += isTargetIOSBased() ? "ios" : "macosx"; + Str += getTargetVersion().getAsString(); + Triple.setOSName(Str); return Triple.getTriple(); } void Generic_ELF::anchor() {} -Tool *Darwin::getTool(Action::ActionClass AC) const { +Tool *MachO::getTool(Action::ActionClass AC) const { switch (AC) { case Action::LipoJobClass: if (!Lipo) @@ -216,18 +221,17 @@ Tool *Darwin::getTool(Action::ActionClass AC) const { } } -Tool *Darwin::buildLinker() const { +Tool *MachO::buildLinker() const { return new tools::darwin::Link(*this); } -Tool *Darwin::buildAssembler() const { +Tool *MachO::buildAssembler() const { return new tools::darwin::Assemble(*this); } DarwinClang::DarwinClang(const Driver &D, const llvm::Triple& Triple, const ArgList &Args) - : Darwin(D, Triple, Args) -{ + : Darwin(D, Triple, Args) { getProgramPaths().push_back(getDriver().getInstalledDir()); if (getDriver().getInstalledDir() != getDriver().Dir) getProgramPaths().push_back(getDriver().Dir); @@ -238,8 +242,23 @@ DarwinClang::DarwinClang(const Driver &D, const llvm::Triple& Triple, getProgramPaths().push_back(getDriver().Dir); } +/// \brief Determine whether Objective-C automated reference counting is +/// enabled. +static bool isObjCAutoRefCount(const ArgList &Args) { + return Args.hasFlag(options::OPT_fobjc_arc, options::OPT_fno_objc_arc, false); +} + void DarwinClang::AddLinkARCArgs(const ArgList &Args, ArgStringList &CmdArgs) const { + // Avoid linking compatibility stubs on i386 mac. + if (isTargetMacOS() && getArch() == llvm::Triple::x86) + return; + + ObjCRuntime runtime = getDefaultObjCRuntime(/*nonfragile*/ true); + + if ((runtime.hasNativeARC() || !isObjCAutoRefCount(Args)) && + runtime.hasSubscripting()) + return; CmdArgs.push_back("-force_load"); SmallString<128> P(getDriver().ClangExecutable); @@ -258,11 +277,9 @@ void DarwinClang::AddLinkARCArgs(const ArgList &Args, CmdArgs.push_back(Args.MakeArgString(P)); } -void DarwinClang::AddLinkRuntimeLib(const ArgList &Args, - ArgStringList &CmdArgs, - StringRef DarwinStaticLib, - bool AlwaysLink, - bool IsEmbedded) const { +void MachO::AddLinkRuntimeLib(const ArgList &Args, ArgStringList &CmdArgs, + StringRef DarwinStaticLib, bool AlwaysLink, + bool IsEmbedded) const { SmallString<128> P(getDriver().ResourceDir); llvm::sys::path::append(P, "lib", IsEmbedded ? "darwin_embedded" : "darwin", DarwinStaticLib); @@ -286,21 +303,6 @@ void DarwinClang::AddLinkRuntimeLibArgs(const ArgList &Args, return; } - if (isTargetEmbedded()) { - // Embedded targets are simple at the moment, not supporting sanitizers and - // with different libraries for each member of the product { static, PIC } x - // { hard-float, soft-float } - llvm::SmallString<32> CompilerRT = StringRef("libclang_rt."); - CompilerRT += - tools::arm::getARMFloatABI(getDriver(), Args, getTriple()) == "hard" - ? "hard" - : "soft"; - CompilerRT += Args.hasArg(options::OPT_fPIC) ? "_pic.a" : "_static.a"; - - AddLinkRuntimeLib(Args, CmdArgs, CompilerRT, false, true); - return; - } - // Darwin doesn't support real static executables, don't link any runtime // libraries with -static. if (Args.hasArg(options::OPT_static) || @@ -481,9 +483,9 @@ void Darwin::AddDeploymentTarget(DerivedArgList &Args) const { // If no OSX or iOS target has been specified and we're compiling for armv7, // go ahead as assume we're targeting iOS. - StringRef DarwinArchName = getDarwinArchName(Args); + StringRef MachOArchName = getMachOArchName(Args); if (OSXTarget.empty() && iOSTarget.empty() && - (DarwinArchName == "armv7" || DarwinArchName == "armv7s")) + (MachOArchName == "armv7" || MachOArchName == "armv7s")) iOSTarget = iOSVersionMin; // Handle conflicting deployment targets @@ -521,8 +523,8 @@ void Darwin::AddDeploymentTarget(DerivedArgList &Args) const { options::OPT_mios_simulator_version_min_EQ); iOSSimVersion = Args.MakeJoinedArg(0, O, iOSSimTarget); Args.append(iOSSimVersion); - } else if (DarwinArchName != "armv6m" && DarwinArchName != "armv7m" && - DarwinArchName != "armv7em") { + } else if (MachOArchName != "armv6m" && MachOArchName != "armv7m" && + MachOArchName != "armv7em") { // Otherwise, assume we are targeting OS X. const Option O = Opts.getOption(options::OPT_mmacosx_version_min_EQ); OSXVersion = Args.MakeJoinedArg(0, O, MacosxVersionMin); @@ -538,7 +540,7 @@ void Darwin::AddDeploymentTarget(DerivedArgList &Args) const { else if (iOSSimVersion) Platform = IPhoneOSSimulator; else - Platform = Embedded; + llvm_unreachable("Unable to infer Darwin variant"); // Reject invalid architecture combinations. if (iOSSimVersion && (getTriple().getArch() != llvm::Triple::x86 && @@ -565,10 +567,8 @@ void Darwin::AddDeploymentTarget(DerivedArgList &Args) const { Major >= 10 || Minor >= 100 || Micro >= 100) getDriver().Diag(diag::err_drv_invalid_version_number) << Version->getAsString(Args); - } else { - assert(Platform == Embedded && "unexpected platform"); - Major = Minor = Micro = 0; - } + } else + llvm_unreachable("unknown kind of Darwin platform"); // In GCC, the simulator historically was treated as being OS X in some // contexts, like determining the link logic, despite generally being called @@ -651,8 +651,8 @@ void DarwinClang::AddCCKextLibArgs(const ArgList &Args, CmdArgs.push_back(Args.MakeArgString(P.str())); } -DerivedArgList *Darwin::TranslateArgs(const DerivedArgList &Args, - const char *BoundArch) const { +DerivedArgList *MachO::TranslateArgs(const DerivedArgList &Args, + const char *BoundArch) const { DerivedArgList *DAL = new DerivedArgList(Args.getBaseArgs()); const OptTable &Opts = getDriver().getOpts(); @@ -671,10 +671,10 @@ DerivedArgList *Darwin::TranslateArgs(const DerivedArgList &Args, // Skip this argument unless the architecture matches either the toolchain // triple arch, or the arch being bound. llvm::Triple::ArchType XarchArch = - tools::darwin::getArchTypeForDarwinArchName(A->getValue(0)); + tools::darwin::getArchTypeForMachOArchName(A->getValue(0)); if (!(XarchArch == getArch() || (BoundArch && XarchArch == - tools::darwin::getArchTypeForDarwinArchName(BoundArch)))) + tools::darwin::getArchTypeForMachOArchName(BoundArch)))) continue; Arg *OriginalArg = A; @@ -870,6 +870,31 @@ DerivedArgList *Darwin::TranslateArgs(const DerivedArgList &Args, llvm_unreachable("invalid Darwin arch"); } + return DAL; +} + +void MachO::AddLinkRuntimeLibArgs(const llvm::opt::ArgList &Args, + llvm::opt::ArgStringList &CmdArgs) const { + // Embedded targets are simple at the moment, not supporting sanitizers and + // with different libraries for each member of the product { static, PIC } x + // { hard-float, soft-float } + llvm::SmallString<32> CompilerRT = StringRef("libclang_rt."); + CompilerRT += + tools::arm::getARMFloatABI(getDriver(), Args, getTriple()) == "hard" + ? "hard" + : "soft"; + CompilerRT += Args.hasArg(options::OPT_fPIC) ? "_pic.a" : "_static.a"; + + AddLinkRuntimeLib(Args, CmdArgs, CompilerRT, false, true); +} + + +DerivedArgList *Darwin::TranslateArgs(const DerivedArgList &Args, + const char *BoundArch) const { + // First get the generic Apple args, before moving onto Darwin-specific ones. + DerivedArgList *DAL = MachO::TranslateArgs(Args, BoundArch); + const OptTable &Opts = getDriver().getOpts(); + // Add an explicit version min argument for the deployment target. We do this // after argument translation because -Xarch_ arguments may add a version min // argument. @@ -920,11 +945,11 @@ DerivedArgList *Darwin::TranslateArgs(const DerivedArgList &Args, return DAL; } -bool Darwin::IsUnwindTablesDefault() const { +bool MachO::IsUnwindTablesDefault() const { return getArch() == llvm::Triple::x86_64; } -bool Darwin::UseDwarfDebugFlags() const { +bool MachO::UseDwarfDebugFlags() const { if (const char *S = ::getenv("RC_DEBUG_OPTIONS")) return S[0] != '\0'; return false; @@ -936,23 +961,133 @@ bool Darwin::UseSjLjExceptions() const { getTriple().getArch() == llvm::Triple::thumb); } -bool Darwin::isPICDefault() const { +bool MachO::isPICDefault() const { return true; } -bool Darwin::isPIEDefault() const { +bool MachO::isPIEDefault() const { return false; } -bool Darwin::isPICDefaultForced() const { +bool MachO::isPICDefaultForced() const { return getArch() == llvm::Triple::x86_64; } -bool Darwin::SupportsProfiling() const { +bool MachO::SupportsProfiling() const { // Profiling instrumentation is only supported on x86. return getArch() == llvm::Triple::x86 || getArch() == llvm::Triple::x86_64; } +void Darwin::addMinVersionArgs(const llvm::opt::ArgList &Args, + llvm::opt::ArgStringList &CmdArgs) const { + VersionTuple TargetVersion = getTargetVersion(); + + // If we had an explicit -mios-simulator-version-min argument, honor that, + // otherwise use the traditional deployment targets. We can't just check the + // is-sim attribute because existing code follows this path, and the linker + // may not handle the argument. + // + // FIXME: We may be able to remove this, once we can verify no one depends on + // it. + if (Args.hasArg(options::OPT_mios_simulator_version_min_EQ)) + CmdArgs.push_back("-ios_simulator_version_min"); + else if (isTargetIPhoneOS()) + CmdArgs.push_back("-iphoneos_version_min"); + else { + assert(isTargetMacOS() && "unexpected target"); + CmdArgs.push_back("-macosx_version_min"); + } + + CmdArgs.push_back(Args.MakeArgString(TargetVersion.getAsString())); +} + +void Darwin::addStartObjectFileArgs(const llvm::opt::ArgList &Args, + llvm::opt::ArgStringList &CmdArgs) const { + // Derived from startfile spec. + if (Args.hasArg(options::OPT_dynamiclib)) { + // Derived from darwin_dylib1 spec. + if (isTargetIOSSimulator()) { + // The simulator doesn't have a versioned crt1 file. + CmdArgs.push_back("-ldylib1.o"); + } else if (isTargetIPhoneOS()) { + if (isIPhoneOSVersionLT(3, 1)) + CmdArgs.push_back("-ldylib1.o"); + } else { + if (isMacosxVersionLT(10, 5)) + CmdArgs.push_back("-ldylib1.o"); + else if (isMacosxVersionLT(10, 6)) + CmdArgs.push_back("-ldylib1.10.5.o"); + } + } else { + if (Args.hasArg(options::OPT_bundle)) { + if (!Args.hasArg(options::OPT_static)) { + // Derived from darwin_bundle1 spec. + if (isTargetIOSSimulator()) { + // The simulator doesn't have a versioned crt1 file. + CmdArgs.push_back("-lbundle1.o"); + } else if (isTargetIPhoneOS()) { + if (isIPhoneOSVersionLT(3, 1)) + CmdArgs.push_back("-lbundle1.o"); + } else { + if (isMacosxVersionLT(10, 6)) + CmdArgs.push_back("-lbundle1.o"); + } + } + } else { + if (Args.hasArg(options::OPT_pg) && SupportsProfiling()) { + if (Args.hasArg(options::OPT_static) || + Args.hasArg(options::OPT_object) || + Args.hasArg(options::OPT_preload)) { + CmdArgs.push_back("-lgcrt0.o"); + } else { + CmdArgs.push_back("-lgcrt1.o"); + + // darwin_crt2 spec is empty. + } + // By default on OS X 10.8 and later, we don't link with a crt1.o + // file and the linker knows to use _main as the entry point. But, + // when compiling with -pg, we need to link with the gcrt1.o file, + // so pass the -no_new_main option to tell the linker to use the + // "start" symbol as the entry point. + if (isTargetMacOS() && !isMacosxVersionLT(10, 8)) + CmdArgs.push_back("-no_new_main"); + } else { + if (Args.hasArg(options::OPT_static) || + Args.hasArg(options::OPT_object) || + Args.hasArg(options::OPT_preload)) { + CmdArgs.push_back("-lcrt0.o"); + } else { + // Derived from darwin_crt1 spec. + if (isTargetIOSSimulator()) { + // The simulator doesn't have a versioned crt1 file. + CmdArgs.push_back("-lcrt1.o"); + } else if (isTargetIPhoneOS()) { + if (isIPhoneOSVersionLT(3, 1)) + CmdArgs.push_back("-lcrt1.o"); + else if (isIPhoneOSVersionLT(6, 0)) + CmdArgs.push_back("-lcrt1.3.1.o"); + } else { + if (isMacosxVersionLT(10, 5)) + CmdArgs.push_back("-lcrt1.o"); + else if (isMacosxVersionLT(10, 6)) + CmdArgs.push_back("-lcrt1.10.5.o"); + else if (isMacosxVersionLT(10, 8)) + CmdArgs.push_back("-lcrt1.10.6.o"); + + // darwin_crt2 spec is empty. + } + } + } + } + } + + if (!isTargetIPhoneOS() && Args.hasArg(options::OPT_shared_libgcc) && + isMacosxVersionLT(10, 5)) { + const char *Str = Args.MakeArgString(GetFilePath("crt3.o")); + CmdArgs.push_back(Str); + } +} + bool Darwin::SupportsObjCGC() const { return isTargetMacOS(); } diff --git a/lib/Driver/ToolChains.h b/lib/Driver/ToolChains.h index d9edccac79..d5d058161f 100644 --- a/lib/Driver/ToolChains.h +++ b/lib/Driver/ToolChains.h @@ -187,22 +187,134 @@ private: mutable OwningPtr Compile; }; - /// Darwin - The base Darwin tool chain. -class LLVM_LIBRARY_VISIBILITY Darwin : public ToolChain { -public: - /// The host version. - unsigned DarwinVersion[3]; - +class LLVM_LIBRARY_VISIBILITY MachO : public ToolChain { protected: virtual Tool *buildAssembler() const; virtual Tool *buildLinker() const; virtual Tool *getTool(Action::ActionClass AC) const; - private: mutable OwningPtr Lipo; mutable OwningPtr Dsymutil; mutable OwningPtr VerifyDebug; +public: + MachO(const Driver &D, const llvm::Triple &Triple, + const llvm::opt::ArgList &Args); + ~MachO(); + + /// @name MachO specific toolchain API + /// { + + /// Get the "MachO" arch name for a particular compiler invocation. For + /// example, Apple treats different ARM variations as distinct architectures. + StringRef getMachOArchName(const llvm::opt::ArgList &Args) const; + + + /// Add the linker arguments to link the ARC runtime library. + virtual void AddLinkARCArgs(const llvm::opt::ArgList &Args, + llvm::opt::ArgStringList &CmdArgs) const {} + + /// Add the linker arguments to link the compiler runtime library. + virtual void AddLinkRuntimeLibArgs(const llvm::opt::ArgList &Args, + llvm::opt::ArgStringList &CmdArgs) const; + + virtual void + addStartObjectFileArgs(const llvm::opt::ArgList &Args, + llvm::opt::ArgStringList &CmdArgs) const {} + + virtual void addMinVersionArgs(const llvm::opt::ArgList &Args, + llvm::opt::ArgStringList &CmdArgs) const {} + + /// On some iOS platforms, kernel and kernel modules were built statically. Is + /// this such a target? + virtual bool isKernelStatic() const { + return false; + } + + /// Is the target either iOS or an iOS simulator? + bool isTargetIOSBased() const { + return false; + } + + void AddLinkRuntimeLib(const llvm::opt::ArgList &Args, + llvm::opt::ArgStringList &CmdArgs, + StringRef DarwinStaticLib, + bool AlwaysLink = false, + bool IsEmbedded = false) const; + + /// } + /// @name ToolChain Implementation + /// { + + std::string ComputeEffectiveClangTriple(const llvm::opt::ArgList &Args, + types::ID InputType) const; + + virtual types::ID LookupTypeForExtension(const char *Ext) const; + + virtual bool HasNativeLLVMSupport() const; + + virtual llvm::opt::DerivedArgList * + TranslateArgs(const llvm::opt::DerivedArgList &Args, + const char *BoundArch) const; + + virtual bool IsBlocksDefault() const { + // Always allow blocks on Apple; users interested in versioning are + // expected to use /usr/include/Blocks.h. + return true; + } + virtual bool IsIntegratedAssemblerDefault() const { + // Default integrated assembler to on for Apple's MachO targets. + return true; + } + + virtual bool IsMathErrnoDefault() const { + return false; + } + + virtual bool IsEncodeExtendedBlockSignatureDefault() const { + return true; + } + + virtual bool IsObjCNonFragileABIDefault() const { + // Non-fragile ABI is default for everything but i386. + return getTriple().getArch() != llvm::Triple::x86; + } + + virtual bool UseObjCMixedDispatch() const { + return true; + } + + virtual bool IsUnwindTablesDefault() const; + + virtual RuntimeLibType GetDefaultRuntimeLibType() const { + return ToolChain::RLT_CompilerRT; + } + + virtual bool isPICDefault() const; + virtual bool isPIEDefault() const; + virtual bool isPICDefaultForced() const; + + virtual bool SupportsProfiling() const; + + virtual bool SupportsObjCGC() const { + return false; + } + + virtual bool UseDwarfDebugFlags() const; + + virtual bool UseSjLjExceptions() const { + return false; + } + + /// } +}; + + /// Darwin - The base Darwin tool chain. +class LLVM_LIBRARY_VISIBILITY Darwin : public MachO { +public: + /// The host version. + unsigned DarwinVersion[3]; + /// Whether the information on the target has been initialized. // // FIXME: This should be eliminated. What we want to do is make this part of @@ -213,8 +325,7 @@ private: enum DarwinPlatformKind { MacOS, IPhoneOS, - IPhoneOSSimulator, - Embedded // FIXME: embedded isn't really a Darwin platform. + IPhoneOSSimulator }; mutable DarwinPlatformKind TargetPlatform; @@ -242,7 +353,24 @@ public: std::string ComputeEffectiveClangTriple(const llvm::opt::ArgList &Args, types::ID InputType) const; - /// @name Darwin Specific Toolchain API + /// @name Apple Specific Toolchain Implementation + /// { + + virtual void + addMinVersionArgs(const llvm::opt::ArgList &Args, + llvm::opt::ArgStringList &CmdArgs) const LLVM_OVERRIDE; + + virtual void + addStartObjectFileArgs(const llvm::opt::ArgList &Args, + llvm::opt::ArgStringList &CmdArgs) const LLVM_OVERRIDE; + + virtual bool isKernelStatic() const { + return !isTargetIPhoneOS() || isIPhoneOSVersionLT(6, 0); + } + +protected: + /// } + /// @name Darwin specific Toolchain functions /// { // FIXME: Eliminate these ...Target functions and derive separate tool chains @@ -280,11 +408,6 @@ public: return TargetPlatform == MacOS; } - bool isTargetEmbedded() const { - assert(TargetInitialized && "Target not initialized!"); - return TargetPlatform == Embedded; - } - bool isTargetInitialized() const { return TargetInitialized; } VersionTuple getTargetVersion() const { @@ -292,11 +415,6 @@ public: return TargetVersion; } - /// getDarwinArchName - Get the "Darwin" arch name for a particular compiler - /// invocation. For example, Darwin treats different ARM variations as - /// distinct architectures. - StringRef getDarwinArchName(const llvm::opt::ArgList &Args) const; - bool isIPhoneOSVersionLT(unsigned V0, unsigned V1=0, unsigned V2=0) const { assert(isTargetIOSBased() && "Unexpected call for non iOS target!"); return TargetVersion < VersionTuple(V0, V1, V2); @@ -307,53 +425,17 @@ public: return TargetVersion < VersionTuple(V0, V1, V2); } - /// AddLinkARCArgs - Add the linker arguments to link the ARC runtime library. - virtual void AddLinkARCArgs(const llvm::opt::ArgList &Args, - llvm::opt::ArgStringList &CmdArgs) const = 0; - - /// AddLinkRuntimeLibArgs - Add the linker arguments to link the compiler - /// runtime library. - virtual void - AddLinkRuntimeLibArgs(const llvm::opt::ArgList &Args, - llvm::opt::ArgStringList &CmdArgs) const = 0; - +public: /// } /// @name ToolChain Implementation /// { - virtual types::ID LookupTypeForExtension(const char *Ext) const; - - virtual bool HasNativeLLVMSupport() const; - - virtual ObjCRuntime getDefaultObjCRuntime(bool isNonFragile) const; - virtual bool hasBlocksRuntime() const; - virtual llvm::opt::DerivedArgList * TranslateArgs(const llvm::opt::DerivedArgList &Args, const char *BoundArch) const; - virtual bool IsBlocksDefault() const { - // Always allow blocks on Darwin; users interested in versioning are - // expected to use /usr/include/Blocks.h. - return true; - } - virtual bool IsIntegratedAssemblerDefault() const { - // Default integrated assembler to on for Darwin. - return true; - } - - virtual bool IsMathErrnoDefault() const { - return false; - } - - virtual bool IsEncodeExtendedBlockSignatureDefault() const { - return true; - } - - virtual bool IsObjCNonFragileABIDefault() const { - // Non-fragile ABI is default for everything but i386. - return getTriple().getArch() != llvm::Triple::x86; - } + virtual ObjCRuntime getDefaultObjCRuntime(bool isNonFragile) const; + virtual bool hasBlocksRuntime() const; virtual bool UseObjCMixedDispatch() const { // This is only used with the non-fragile ABI and non-legacy dispatch. @@ -361,7 +443,7 @@ public: // Mixed dispatch is used everywhere except OS X before 10.6. return !(isTargetMacOS() && isMacosxVersionLT(10, 6)); } - virtual bool IsUnwindTablesDefault() const; + virtual unsigned GetDefaultStackProtectorLevel(bool KernelOrKext) const { // Stack protectors default to on for user code on 10.5, // and for everything in 10.6 and beyond @@ -374,24 +456,12 @@ public: return 0; } - virtual RuntimeLibType GetDefaultRuntimeLibType() const { - return ToolChain::RLT_CompilerRT; - } - virtual bool isPICDefault() const; - virtual bool isPIEDefault() const; - virtual bool isPICDefaultForced() const; - - virtual bool SupportsProfiling() const; virtual bool SupportsObjCGC() const; virtual void CheckObjCARC() const; - virtual bool UseDwarfDebugFlags() const; - virtual bool UseSjLjExceptions() const; - - /// } }; /// DarwinClang - The Darwin toolchain used by Clang. @@ -400,25 +470,24 @@ public: DarwinClang(const Driver &D, const llvm::Triple &Triple, const llvm::opt::ArgList &Args); - /// @name Darwin ToolChain Implementation + /// @name Apple ToolChain Implementation /// { - virtual void AddLinkRuntimeLibArgs(const llvm::opt::ArgList &Args, - llvm::opt::ArgStringList &CmdArgs) const; - void AddLinkRuntimeLib(const llvm::opt::ArgList &Args, - llvm::opt::ArgStringList &CmdArgs, - StringRef DarwinStaticLib, - bool AlwaysLink = false, - bool IsEmbedded = false) const; + virtual void + AddLinkRuntimeLibArgs(const llvm::opt::ArgList &Args, + llvm::opt::ArgStringList &CmdArgs) const LLVM_OVERRIDE; - virtual void AddCXXStdlibLibArgs(const llvm::opt::ArgList &Args, - llvm::opt::ArgStringList &CmdArgs) const; + virtual void + AddCXXStdlibLibArgs(const llvm::opt::ArgList &Args, + llvm::opt::ArgStringList &CmdArgs) const LLVM_OVERRIDE; - virtual void AddCCKextLibArgs(const llvm::opt::ArgList &Args, - llvm::opt::ArgStringList &CmdArgs) const; + virtual void + AddCCKextLibArgs(const llvm::opt::ArgList &Args, + llvm::opt::ArgStringList &CmdArgs) const LLVM_OVERRIDE; - virtual void AddLinkARCArgs(const llvm::opt::ArgList &Args, - llvm::opt::ArgStringList &CmdArgs) const; + virtual void + AddLinkARCArgs(const llvm::opt::ArgList &Args, + llvm::opt::ArgStringList &CmdArgs) const LLVM_OVERRIDE; /// } }; diff --git a/lib/Driver/Tools.cpp b/lib/Driver/Tools.cpp index 5689d1cad5..16e396705c 100644 --- a/lib/Driver/Tools.cpp +++ b/lib/Driver/Tools.cpp @@ -475,7 +475,7 @@ static bool isSignedCharDefault(const llvm::Triple &Triple) { case llvm::Triple::arm: case llvm::Triple::ppc: case llvm::Triple::ppc64: - if (Triple.isOSDarwin()) + if (Triple.isOSBinFormatMachO()) return true; return false; @@ -746,10 +746,11 @@ void Clang::AddARMTargetArgs(const ArgList &Args, const char *ABIName = 0; if (Arg *A = Args.getLastArg(options::OPT_mabi_EQ)) { ABIName = A->getValue(); - } else if (Triple.isOSDarwin()) { + } else if (Triple.isOSBinFormatMachO()) { // The backend is hardwired to assume AAPCS for M-class processors, ensure // the frontend matches that. if (Triple.getEnvironment() == llvm::Triple::EABI || + Triple.getEnvironment() == llvm::Triple::MachO || StringRef(CPUName).startswith("cortex-m")) { ABIName = "aapcs"; } else { @@ -1191,7 +1192,7 @@ static const char *getX86TargetCPU(const ArgList &Args, const llvm::Triple &Triple) { if (const Arg *A = Args.getLastArg(options::OPT_march_EQ)) { if (StringRef(A->getValue()) != "native") { - if (Triple.isOSDarwin() && Triple.getArchName() == "x86_64h") + if (Triple.isOSBinFormatMachO() && Triple.getArchName() == "x86_64h") return "core-avx2"; return A->getValue(); @@ -1216,7 +1217,7 @@ static const char *getX86TargetCPU(const ArgList &Args, bool Is64Bit = Triple.getArch() == llvm::Triple::x86_64; // FIXME: Need target hooks. - if (Triple.isOSDarwin()) { + if (Triple.isOSBinFormatMachO()) { if (Triple.getArchName() == "x86_64h") return "core-avx2"; return Is64Bit ? "core2" : "yonah"; @@ -2556,7 +2557,7 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA, // -gline-tables-only. CmdArgs.push_back("-gline-tables-only"); // Default is dwarf-2 for darwin. - if (getToolChain().getTriple().isOSDarwin()) + if (getToolChain().getTriple().isOSBinFormatMachO()) CmdArgs.push_back("-gdwarf-2"); } else if (A->getOption().matches(options::OPT_gdwarf_2)) CmdArgs.push_back("-gdwarf-2"); @@ -2567,7 +2568,7 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA, else if (!A->getOption().matches(options::OPT_g0) && !A->getOption().matches(options::OPT_ggdb0)) { // Default is dwarf-2 for darwin. - if (getToolChain().getTriple().isOSDarwin()) + if (getToolChain().getTriple().isOSBinFormatMachO()) CmdArgs.push_back("-gdwarf-2"); else CmdArgs.push_back("-g"); @@ -3864,7 +3865,7 @@ ObjCRuntime Clang::AddObjCRuntimeArgs(const ArgList &args, // -fnext-runtime } else if (runtimeArg->getOption().matches(options::OPT_fnext_runtime)) { // On Darwin, make this use the default behavior for the toolchain. - if (getToolChain().getTriple().isOSDarwin()) { + if (getToolChain().getTriple().isOSBinFormatMachO()) { runtime = getToolChain().getDefaultObjCRuntime(isNonFragile); // Otherwise, build for a generic macosx port. @@ -4101,7 +4102,7 @@ void gcc::Common::ConstructJob(Compilation &C, const JobAction &JA, // If using a driver driver, force the arch. llvm::Triple::ArchType Arch = getToolChain().getArch(); - if (getToolChain().getTriple().isOSDarwin()) { + if (getToolChain().getTriple().isOSBinFormatMachO()) { CmdArgs.push_back("-arch"); // FIXME: Remove these special cases. @@ -4596,7 +4597,7 @@ const char *arm::getLLVMArchSuffixForARM(StringRef CPU) { .Default(""); } -llvm::Triple::ArchType darwin::getArchTypeForDarwinArchName(StringRef Str) { +llvm::Triple::ArchType darwin::getArchTypeForMachOArchName(StringRef Str) { // See arch(3) and llvm-gcc's driver-driver.c. We don't implement support for // archs which Darwin doesn't use. @@ -4629,6 +4630,18 @@ llvm::Triple::ArchType darwin::getArchTypeForDarwinArchName(StringRef Str) { .Default(llvm::Triple::UnknownArch); } +void darwin::setTripleTypeForMachOArchName(llvm::Triple &T, StringRef Str) { + llvm::Triple::ArchType Arch = getArchTypeForMachOArchName(Str); + T.setArch(Arch); + + if (Str == "x86_64h") + T.setArchName(Str); + else if (Str == "armv6m" || Str == "armv7m" || Str == "armv7em") { + T.setOS(llvm::Triple::UnknownOS); + T.setEnvironment(llvm::Triple::MachO); + } +} + const char *Clang::getBaseInputName(const ArgList &Args, const InputInfoList &Inputs) { return Args.MakeArgString( @@ -4697,7 +4710,7 @@ void darwin::Assemble::ConstructJob(Compilation &C, const JobAction &JA, } // Derived from asm spec. - AddDarwinArch(Args, CmdArgs); + AddMachOArch(Args, CmdArgs); // Use -force_cpusubtype_ALL on x86 by default. if (getToolChain().getArch() == llvm::Triple::x86 || @@ -4708,8 +4721,7 @@ void darwin::Assemble::ConstructJob(Compilation &C, const JobAction &JA, if (getToolChain().getArch() != llvm::Triple::x86_64 && (((Args.hasArg(options::OPT_mkernel) || Args.hasArg(options::OPT_fapple_kext)) && - (!getDarwinToolChain().isTargetIPhoneOS() || - getDarwinToolChain().isIPhoneOSVersionLT(6, 0))) || + getMachOToolChain().isKernelStatic()) || Args.hasArg(options::OPT_static))) CmdArgs.push_back("-static"); @@ -4730,11 +4742,11 @@ void darwin::Assemble::ConstructJob(Compilation &C, const JobAction &JA, C.addCommand(new Command(JA, *this, Exec, CmdArgs)); } -void darwin::DarwinTool::anchor() {} +void darwin::MachOTool::anchor() {} -void darwin::DarwinTool::AddDarwinArch(const ArgList &Args, - ArgStringList &CmdArgs) const { - StringRef ArchName = getDarwinToolChain().getDarwinArchName(Args); +void darwin::MachOTool::AddMachOArch(const ArgList &Args, + ArgStringList &CmdArgs) const { + StringRef ArchName = getMachOToolChain().getMachOArchName(Args); // Derived from darwin_arch spec. CmdArgs.push_back("-arch"); @@ -4762,7 +4774,7 @@ void darwin::Link::AddLinkArgs(Compilation &C, ArgStringList &CmdArgs, const InputInfoList &Inputs) const { const Driver &D = getToolChain().getDriver(); - const toolchains::Darwin &DarwinTC = getDarwinToolChain(); + const toolchains::MachO &MachOTC = getMachOToolChain(); unsigned Version[3] = { 0, 0, 0 }; if (Arg *A = Args.getLastArg(options::OPT_mlinker_version_EQ)) { @@ -4803,7 +4815,7 @@ void darwin::Link::AddLinkArgs(Compilation &C, } if (!Args.hasArg(options::OPT_dynamiclib)) { - AddDarwinArch(Args, CmdArgs); + AddMachOArch(Args, CmdArgs); // FIXME: Why do this only on this path? Args.AddLastArg(CmdArgs, options::OPT_force__cpusubtype__ALL); @@ -4839,7 +4851,7 @@ void darwin::Link::AddLinkArgs(Compilation &C, Args.AddAllArgsTranslated(CmdArgs, options::OPT_current__version, "-dylib_current_version"); - AddDarwinArch(Args, CmdArgs); + AddMachOArch(Args, CmdArgs); Args.AddAllArgsTranslated(CmdArgs, options::OPT_install__name, "-dylib_install_name"); @@ -4848,7 +4860,7 @@ void darwin::Link::AddLinkArgs(Compilation &C, Args.AddLastArg(CmdArgs, options::OPT_all__load); Args.AddAllArgs(CmdArgs, options::OPT_allowable__client); Args.AddLastArg(CmdArgs, options::OPT_bind__at__load); - if (DarwinTC.isTargetIOSBased()) + if (MachOTC.isTargetIOSBased()) Args.AddLastArg(CmdArgs, options::OPT_arch__errors__fatal); Args.AddLastArg(CmdArgs, options::OPT_dead__strip); Args.AddLastArg(CmdArgs, options::OPT_no__dead__strip__inits__and__terms); @@ -4862,25 +4874,7 @@ void darwin::Link::AddLinkArgs(Compilation &C, Args.AddAllArgs(CmdArgs, options::OPT_init); // Add the deployment target. - VersionTuple TargetVersion = DarwinTC.getTargetVersion(); - - // If we had an explicit -mios-simulator-version-min argument, honor that, - // otherwise use the traditional deployment targets. We can't just check the - // is-sim attribute because existing code follows this path, and the linker - // may not handle the argument. - // - // FIXME: We may be able to remove this, once we can verify no one depends on - // it. - if (Args.hasArg(options::OPT_mios_simulator_version_min_EQ)) { - CmdArgs.push_back("-ios_simulator_version_min"); - CmdArgs.push_back(Args.MakeArgString(TargetVersion.getAsString())); - } else if (DarwinTC.isTargetIOSBased()) { - CmdArgs.push_back("-iphoneos_version_min"); - CmdArgs.push_back(Args.MakeArgString(TargetVersion.getAsString())); - } else if (DarwinTC.isTargetMacOS()) { - CmdArgs.push_back("-macosx_version_min"); - CmdArgs.push_back(Args.MakeArgString(TargetVersion.getAsString())); - } + MachOTC.addMinVersionArgs(Args, CmdArgs); Args.AddLastArg(CmdArgs, options::OPT_nomultidefs); Args.AddLastArg(CmdArgs, options::OPT_multi__module); @@ -4995,95 +4989,8 @@ void darwin::Link::ConstructJob(Compilation &C, const JobAction &JA, CmdArgs.push_back(Output.getFilename()); if (!Args.hasArg(options::OPT_nostdlib) && - !Args.hasArg(options::OPT_nostartfiles)) { - // Derived from startfile spec. - if (Args.hasArg(options::OPT_dynamiclib)) { - // Derived from darwin_dylib1 spec. - if (getDarwinToolChain().isTargetIOSSimulator()) { - // The simulator doesn't have a versioned crt1 file. - CmdArgs.push_back("-ldylib1.o"); - } else if (getDarwinToolChain().isTargetIPhoneOS()) { - if (getDarwinToolChain().isIPhoneOSVersionLT(3, 1)) - CmdArgs.push_back("-ldylib1.o"); - } else if (getDarwinToolChain().isTargetMacOS()) { - if (getDarwinToolChain().isMacosxVersionLT(10, 5)) - CmdArgs.push_back("-ldylib1.o"); - else if (getDarwinToolChain().isMacosxVersionLT(10, 6)) - CmdArgs.push_back("-ldylib1.10.5.o"); - } - } else { - if (Args.hasArg(options::OPT_bundle)) { - if (!Args.hasArg(options::OPT_static)) { - // Derived from darwin_bundle1 spec. - if (getDarwinToolChain().isTargetIOSSimulator()) { - // The simulator doesn't have a versioned crt1 file. - CmdArgs.push_back("-lbundle1.o"); - } else if (getDarwinToolChain().isTargetIPhoneOS()) { - if (getDarwinToolChain().isIPhoneOSVersionLT(3, 1)) - CmdArgs.push_back("-lbundle1.o"); - } else if (getDarwinToolChain().isTargetMacOS()) { - if (getDarwinToolChain().isMacosxVersionLT(10, 6)) - CmdArgs.push_back("-lbundle1.o"); - } - } - } else { - if (Args.hasArg(options::OPT_pg) && - getToolChain().SupportsProfiling()) { - if (Args.hasArg(options::OPT_static) || - Args.hasArg(options::OPT_object) || - Args.hasArg(options::OPT_preload)) { - CmdArgs.push_back("-lgcrt0.o"); - } else { - CmdArgs.push_back("-lgcrt1.o"); - - // darwin_crt2 spec is empty. - } - // By default on OS X 10.8 and later, we don't link with a crt1.o - // file and the linker knows to use _main as the entry point. But, - // when compiling with -pg, we need to link with the gcrt1.o file, - // so pass the -no_new_main option to tell the linker to use the - // "start" symbol as the entry point. - if (getDarwinToolChain().isTargetMacOS() && - !getDarwinToolChain().isMacosxVersionLT(10, 8)) - CmdArgs.push_back("-no_new_main"); - } else { - if (Args.hasArg(options::OPT_static) || - Args.hasArg(options::OPT_object) || - Args.hasArg(options::OPT_preload)) { - CmdArgs.push_back("-lcrt0.o"); - } else { - // Derived from darwin_crt1 spec. - if (getDarwinToolChain().isTargetIOSSimulator()) { - // The simulator doesn't have a versioned crt1 file. - CmdArgs.push_back("-lcrt1.o"); - } else if (getDarwinToolChain().isTargetIPhoneOS()) { - if (getDarwinToolChain().isIPhoneOSVersionLT(3, 1)) - CmdArgs.push_back("-lcrt1.o"); - else if (getDarwinToolChain().isIPhoneOSVersionLT(6, 0)) - CmdArgs.push_back("-lcrt1.3.1.o"); - } else if (getDarwinToolChain().isTargetMacOS()) { - if (getDarwinToolChain().isMacosxVersionLT(10, 5)) - CmdArgs.push_back("-lcrt1.o"); - else if (getDarwinToolChain().isMacosxVersionLT(10, 6)) - CmdArgs.push_back("-lcrt1.10.5.o"); - else if (getDarwinToolChain().isMacosxVersionLT(10, 8)) - CmdArgs.push_back("-lcrt1.10.6.o"); - - // darwin_crt2 spec is empty. - } - } - } - } - } - - if (getDarwinToolChain().isTargetMacOS() && - Args.hasArg(options::OPT_shared_libgcc) && - getDarwinToolChain().isMacosxVersionLT(10, 5)) { - const char *Str = - Args.MakeArgString(getToolChain().GetFilePath("crt3.o")); - CmdArgs.push_back(Str); - } - } + !Args.hasArg(options::OPT_nostartfiles)) + getMachOToolChain().addStartObjectFileArgs(Args, CmdArgs); Args.AddAllArgs(CmdArgs, options::OPT_L); @@ -5096,19 +5003,9 @@ void darwin::Link::ConstructJob(Compilation &C, const JobAction &JA, if (isObjCRuntimeLinked(Args) && !Args.hasArg(options::OPT_nostdlib) && !Args.hasArg(options::OPT_nodefaultlibs)) { - // Avoid linking compatibility stubs on i386 mac. - if (!getDarwinToolChain().isTargetMacOS() || - getDarwinToolChain().getArch() != llvm::Triple::x86) { - // If we don't have ARC or subscripting runtime support, link in the - // runtime stubs. We have to do this *before* adding any of the normal - // linker inputs so that its initializer gets run first. - ObjCRuntime runtime = - getDarwinToolChain().getDefaultObjCRuntime(/*nonfragile*/ true); - // We use arclite library for both ARC and subscripting support. - if ((!runtime.hasNativeARC() && isObjCAutoRefCount(Args)) || - !runtime.hasSubscripting()) - getDarwinToolChain().AddLinkARCArgs(Args, CmdArgs); - } + // We use arclite library for both ARC and subscripting support. + getMachOToolChain().AddLinkARCArgs(Args, CmdArgs); + CmdArgs.push_back("-framework"); CmdArgs.push_back("Foundation"); // Link libobj. @@ -5132,7 +5029,7 @@ void darwin::Link::ConstructJob(Compilation &C, const JobAction &JA, // link_ssp spec is empty. // Let the tool chain choose which runtime library to link. - getDarwinToolChain().AddLinkRuntimeLibArgs(Args, CmdArgs); + getMachOToolChain().AddLinkRuntimeLibArgs(Args, CmdArgs); } if (!Args.hasArg(options::OPT_nostdlib) && diff --git a/lib/Driver/Tools.h b/lib/Driver/Tools.h index 2ede62e019..873969b4d7 100644 --- a/lib/Driver/Tools.h +++ b/lib/Driver/Tools.h @@ -25,7 +25,7 @@ namespace driver { class Driver; namespace toolchains { - class Darwin; + class MachO; } namespace tools { @@ -210,27 +210,28 @@ namespace arm { } namespace darwin { - llvm::Triple::ArchType getArchTypeForDarwinArchName(StringRef Str); + llvm::Triple::ArchType getArchTypeForMachOArchName(StringRef Str); + void setTripleTypeForMachOArchName(llvm::Triple &T, StringRef Str); - class LLVM_LIBRARY_VISIBILITY DarwinTool : public Tool { + class LLVM_LIBRARY_VISIBILITY MachOTool : public Tool { virtual void anchor(); protected: - void AddDarwinArch(const llvm::opt::ArgList &Args, + void AddMachOArch(const llvm::opt::ArgList &Args, llvm::opt::ArgStringList &CmdArgs) const; - const toolchains::Darwin &getDarwinToolChain() const { - return reinterpret_cast(getToolChain()); + const toolchains::MachO &getMachOToolChain() const { + return reinterpret_cast(getToolChain()); } public: - DarwinTool(const char *Name, const char *ShortName, + MachOTool(const char *Name, const char *ShortName, const ToolChain &TC) : Tool(Name, ShortName, TC) {} }; - class LLVM_LIBRARY_VISIBILITY Assemble : public DarwinTool { + class LLVM_LIBRARY_VISIBILITY Assemble : public MachOTool { public: - Assemble(const ToolChain &TC) : DarwinTool("darwin::Assemble", - "assembler", TC) {} + Assemble(const ToolChain &TC) : MachOTool("darwin::Assemble", + "assembler", TC) {} virtual bool hasIntegratedCPP() const { return false; } @@ -241,14 +242,14 @@ namespace darwin { const char *LinkingOutput) const; }; - class LLVM_LIBRARY_VISIBILITY Link : public DarwinTool { + class LLVM_LIBRARY_VISIBILITY Link : public MachOTool { bool NeedsTempPath(const InputInfoList &Inputs) const; void AddLinkArgs(Compilation &C, const llvm::opt::ArgList &Args, llvm::opt::ArgStringList &CmdArgs, const InputInfoList &Inputs) const; public: - Link(const ToolChain &TC) : DarwinTool("darwin::Link", "linker", TC) {} + Link(const ToolChain &TC) : MachOTool("darwin::Link", "linker", TC) {} virtual bool hasIntegratedCPP() const { return false; } virtual bool isLinkJob() const { return true; } @@ -260,9 +261,9 @@ namespace darwin { const char *LinkingOutput) const; }; - class LLVM_LIBRARY_VISIBILITY Lipo : public DarwinTool { + class LLVM_LIBRARY_VISIBILITY Lipo : public MachOTool { public: - Lipo(const ToolChain &TC) : DarwinTool("darwin::Lipo", "lipo", TC) {} + Lipo(const ToolChain &TC) : MachOTool("darwin::Lipo", "lipo", TC) {} virtual bool hasIntegratedCPP() const { return false; } @@ -273,10 +274,10 @@ namespace darwin { const char *LinkingOutput) const; }; - class LLVM_LIBRARY_VISIBILITY Dsymutil : public DarwinTool { + class LLVM_LIBRARY_VISIBILITY Dsymutil : public MachOTool { public: - Dsymutil(const ToolChain &TC) : DarwinTool("darwin::Dsymutil", - "dsymutil", TC) {} + Dsymutil(const ToolChain &TC) : MachOTool("darwin::Dsymutil", + "dsymutil", TC) {} virtual bool hasIntegratedCPP() const { return false; } virtual bool isDsymutilJob() const { return true; } @@ -288,10 +289,10 @@ namespace darwin { const char *LinkingOutput) const; }; - class LLVM_LIBRARY_VISIBILITY VerifyDebug : public DarwinTool { + class LLVM_LIBRARY_VISIBILITY VerifyDebug : public MachOTool { public: - VerifyDebug(const ToolChain &TC) : DarwinTool("darwin::VerifyDebug", - "dwarfdump", TC) {} + VerifyDebug(const ToolChain &TC) : MachOTool("darwin::VerifyDebug", + "dwarfdump", TC) {} virtual bool hasIntegratedCPP() const { return false; } diff --git a/test/Driver/darwin-embedded.c b/test/Driver/darwin-embedded.c index e0a0342f11..5f545d535f 100644 --- a/test/Driver/darwin-embedded.c +++ b/test/Driver/darwin-embedded.c @@ -5,6 +5,9 @@ // RUN: %clang -target x86_64-apple-darwin -arch armv7m -fPIC -resource-dir=%S/Inputs/resource_dir %s -### 2>> %t // RUN: %clang -target x86_64-apple-darwin -arch armv7em -fPIC -mfloat-abi=hard -resource-dir=%S/Inputs/resource_dir %s -### 2>> %t // RUN: %clang -target x86_64-apple-darwin -arch armv7em -fPIC -mfloat-abi=softfp -resource-dir=%S/Inputs/resource_dir %s -### 2>> %t +// RUN: %clang -target x86_64-apple-none-macho -arch armv7 -mhard-float -resource-dir=%S/Inputs/resource_dir %s -### 2>> %t +// RUN: %clang -target x86_64-apple-none-macho -arch armv7 -msoft-float -fPIC -resource-dir=%S/Inputs/resource_dir %s -### 2>> %t + // RUN: FileCheck %s < %t @@ -27,4 +30,6 @@ // callers we're compiling will expect. // CHECK: libclang_rt.soft_pic.a -// FIXME: test ARMv7a when we switch to -none-macho as the triple +// -arch "armv7" (== embedded v7a) can be used in a couple of variants: +// CHECK: libclang_rt.hard_static.a +// CHECK: libclang_rt.soft_pic.a diff --git a/test/Driver/darwin-eabi.c b/test/Driver/macho-embedded.c similarity index 68% rename from test/Driver/darwin-eabi.c rename to test/Driver/macho-embedded.c index 1288fa4060..e45547db9e 100644 --- a/test/Driver/darwin-eabi.c +++ b/test/Driver/macho-embedded.c @@ -1,12 +1,14 @@ // RUN: %clang -arch armv7 -target thumbv7-apple-darwin-eabi -### -c %s 2>&1 | FileCheck %s --check-prefix=CHECK-AAPCS // RUN: %clang -arch armv7s -target thumbv7-apple-ios -### -c %s 2>&1 | FileCheck %s --check-prefix=CHECK-APCS // RUN: %clang -arch armv7s -target thumbv7-apple-darwin -### -c %s 2>&1 | FileCheck %s --check-prefix=CHECK-APCS -// RUN: %clang -arch armv6m -target thumbv7-apple-darwin -### -c %s 2>&1 | FileCheck %s --check-prefix=CHECK-DARWIN-EABI -// RUN: %clang -arch armv7m -target thumbv7-apple-darwin -### -c %s 2>&1 | FileCheck %s --check-prefix=CHECK-DARWIN-EABI -// RUN: %clang -arch armv7em -target thumbv7-apple-darwin -### -c %s 2>&1 | FileCheck %s --check-prefix=CHECK-DARWIN-EABI +// RUN: %clang -arch armv6m -target thumbv7-apple-darwin -### -c %s 2>&1 | FileCheck %s --check-prefix=CHECK-MACHO-EMBEDDED +// RUN: %clang -arch armv7m -target thumbv7-apple-darwin -### -c %s 2>&1 | FileCheck %s --check-prefix=CHECK-MACHO-EMBEDDED +// RUN: %clang -arch armv7em -target thumbv7-apple-darwin -### -c %s 2>&1 | FileCheck %s --check-prefix=CHECK-MACHO-EMBEDDED -// CHECK-DARWIN-EABI: "-triple" "{{thumbv[67]e?m}}-apple-darwin-eabi" // CHECK-IOS: "-triple" "thumbv7" "thumbv7-apple-ios // CHECK-AAPCS: "-target-abi" "aapcs" // CHECK-APCS: "-target-abi" "apcs-gnu" + +// CHECK-MACHO-EMBEDDED: "-triple" "{{thumbv[67]e?m}}-apple-unknown-macho" +// CHECK-MACHO-EMBEDDED: "-mrelocation-model" "pic" diff --git a/test/Preprocessor/macho-embedded-predefines.c b/test/Preprocessor/macho-embedded-predefines.c new file mode 100644 index 0000000000..8356bc9924 --- /dev/null +++ b/test/Preprocessor/macho-embedded-predefines.c @@ -0,0 +1,5 @@ +// RUN: %clang_cc1 -E -dM -triple thumbv7m-apple-unknown-macho %s | FileCheck %s + +// CHECK: #define __APPLE_CC__ +// CHECK: #define __APPLE__ +// CHECK-NOT: #define __MACH__ -- 2.49.0