diff options
Diffstat (limited to 'clang/lib/Driver/ToolChains.cpp')
-rw-r--r-- | clang/lib/Driver/ToolChains.cpp | 269 |
1 files changed, 202 insertions, 67 deletions
diff --git a/clang/lib/Driver/ToolChains.cpp b/clang/lib/Driver/ToolChains.cpp index b8e1d6f0f88..1d32c4586e4 100644 --- a/clang/lib/Driver/ToolChains.cpp +++ b/clang/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(); } |