ToolChains.cpp revision 255321
1218893Sdim//===--- ToolChains.cpp - ToolChain Implementations -----------------------===// 2193326Sed// 3193326Sed// The LLVM Compiler Infrastructure 4193326Sed// 5193326Sed// This file is distributed under the University of Illinois Open Source 6193326Sed// License. See LICENSE.TXT for details. 7193326Sed// 8193326Sed//===----------------------------------------------------------------------===// 9193326Sed 10193326Sed#include "ToolChains.h" 11249423Sdim#include "SanitizerArgs.h" 12249423Sdim#include "clang/Basic/ObjCRuntime.h" 13249423Sdim#include "clang/Basic/Version.h" 14193326Sed#include "clang/Driver/Arg.h" 15193326Sed#include "clang/Driver/ArgList.h" 16208600Srdivacky#include "clang/Driver/Compilation.h" 17193326Sed#include "clang/Driver/Driver.h" 18193326Sed#include "clang/Driver/DriverDiagnostic.h" 19199512Srdivacky#include "clang/Driver/OptTable.h" 20193326Sed#include "clang/Driver/Option.h" 21199512Srdivacky#include "clang/Driver/Options.h" 22249423Sdim#include "llvm/ADT/STLExtras.h" 23212904Sdim#include "llvm/ADT/SmallString.h" 24193326Sed#include "llvm/ADT/StringExtras.h" 25226633Sdim#include "llvm/ADT/StringSwitch.h" 26198092Srdivacky#include "llvm/Support/ErrorHandling.h" 27218893Sdim#include "llvm/Support/FileSystem.h" 28218893Sdim#include "llvm/Support/MemoryBuffer.h" 29249423Sdim#include "llvm/Support/Path.h" 30193326Sed#include "llvm/Support/raw_ostream.h" 31218893Sdim#include "llvm/Support/system_error.h" 32193326Sed 33249423Sdim// FIXME: This needs to be listed last until we fix the broken include guards 34249423Sdim// in these files and the LLVM config.h files. 35249423Sdim#include "clang/Config/config.h" // for GCC_INSTALL_PREFIX 36243830Sdim 37193326Sed#include <cstdlib> // ::getenv 38193326Sed 39193326Sedusing namespace clang::driver; 40193326Sedusing namespace clang::driver::toolchains; 41226633Sdimusing namespace clang; 42193326Sed 43198092Srdivacky/// Darwin - Darwin tool chain for i386 and x86_64. 44193326Sed 45249423SdimDarwin::Darwin(const Driver &D, const llvm::Triple& Triple, const ArgList &Args) 46249423Sdim : ToolChain(D, Triple, Args), TargetInitialized(false) 47198092Srdivacky{ 48234353Sdim // Compute the initial Darwin version from the triple 49234353Sdim unsigned Major, Minor, Micro; 50234353Sdim if (!Triple.getMacOSXVersion(Major, Minor, Micro)) 51234353Sdim getDriver().Diag(diag::err_drv_invalid_darwin_version) << 52234353Sdim Triple.getOSName(); 53234353Sdim llvm::raw_string_ostream(MacosxVersionMin) 54234353Sdim << Major << '.' << Minor << '.' << Micro; 55212904Sdim 56234353Sdim // FIXME: DarwinVersion is only used to find GCC's libexec directory. 57234353Sdim // It should be removed when we stop supporting that. 58234353Sdim DarwinVersion[0] = Minor + 4; 59234353Sdim DarwinVersion[1] = Micro; 60234353Sdim DarwinVersion[2] = 0; 61239462Sdim 62239462Sdim // Compute the initial iOS version from the triple 63239462Sdim Triple.getiOSVersion(Major, Minor, Micro); 64239462Sdim llvm::raw_string_ostream(iOSVersionMin) 65239462Sdim << Major << '.' << Minor << '.' << Micro; 66198092Srdivacky} 67198092Srdivacky 68212904Sdimtypes::ID Darwin::LookupTypeForExtension(const char *Ext) const { 69212904Sdim types::ID Ty = types::lookupTypeForExtension(Ext); 70212904Sdim 71212904Sdim // Darwin always preprocesses assembly files (unless -x is used explicitly). 72212904Sdim if (Ty == types::TY_PP_Asm) 73212904Sdim return types::TY_Asm; 74212904Sdim 75212904Sdim return Ty; 76212904Sdim} 77212904Sdim 78218893Sdimbool Darwin::HasNativeLLVMSupport() const { 79218893Sdim return true; 80218893Sdim} 81218893Sdim 82239462Sdim/// Darwin provides an ARC runtime starting in MacOS X 10.7 and iOS 5.0. 83239462SdimObjCRuntime Darwin::getDefaultObjCRuntime(bool isNonFragile) const { 84243830Sdim if (isTargetIPhoneOS()) 85239462Sdim return ObjCRuntime(ObjCRuntime::iOS, TargetVersion); 86243830Sdim if (isNonFragile) 87243830Sdim return ObjCRuntime(ObjCRuntime::MacOSX, TargetVersion); 88243830Sdim return ObjCRuntime(ObjCRuntime::FragileMacOSX, TargetVersion); 89224145Sdim} 90224145Sdim 91226633Sdim/// Darwin provides a blocks runtime starting in MacOS X 10.6 and iOS 3.2. 92226633Sdimbool Darwin::hasBlocksRuntime() const { 93226633Sdim if (isTargetIPhoneOS()) 94226633Sdim return !isIPhoneOSVersionLT(3, 2); 95226633Sdim else 96226633Sdim return !isMacosxVersionLT(10, 6); 97226633Sdim} 98202879Srdivacky 99226633Sdimstatic const char *GetArmArchForMArch(StringRef Value) { 100226633Sdim return llvm::StringSwitch<const char*>(Value) 101226633Sdim .Case("armv6k", "armv6") 102249423Sdim .Case("armv6m", "armv6m") 103226633Sdim .Case("armv5tej", "armv5") 104226633Sdim .Case("xscale", "xscale") 105226633Sdim .Case("armv4t", "armv4t") 106226633Sdim .Case("armv7", "armv7") 107226633Sdim .Cases("armv7a", "armv7-a", "armv7") 108226633Sdim .Cases("armv7r", "armv7-r", "armv7") 109249423Sdim .Cases("armv7em", "armv7e-m", "armv7em") 110243830Sdim .Cases("armv7f", "armv7-f", "armv7f") 111243830Sdim .Cases("armv7k", "armv7-k", "armv7k") 112249423Sdim .Cases("armv7m", "armv7-m", "armv7m") 113243830Sdim .Cases("armv7s", "armv7-s", "armv7s") 114226633Sdim .Default(0); 115202879Srdivacky} 116202879Srdivacky 117226633Sdimstatic const char *GetArmArchForMCpu(StringRef Value) { 118226633Sdim return llvm::StringSwitch<const char *>(Value) 119226633Sdim .Cases("arm9e", "arm946e-s", "arm966e-s", "arm968e-s", "arm926ej-s","armv5") 120226633Sdim .Cases("arm10e", "arm10tdmi", "armv5") 121226633Sdim .Cases("arm1020t", "arm1020e", "arm1022e", "arm1026ej-s", "armv5") 122226633Sdim .Case("xscale", "xscale") 123249423Sdim .Cases("arm1136j-s", "arm1136jf-s", "arm1176jz-s", "arm1176jzf-s", "armv6") 124249423Sdim .Case("cortex-m0", "armv6m") 125249423Sdim .Cases("cortex-a8", "cortex-r4", "cortex-a9", "cortex-a15", "armv7") 126243830Sdim .Case("cortex-a9-mp", "armv7f") 127249423Sdim .Case("cortex-m3", "armv7m") 128249423Sdim .Case("cortex-m4", "armv7em") 129243830Sdim .Case("swift", "armv7s") 130226633Sdim .Default(0); 131202879Srdivacky} 132202879Srdivacky 133226633SdimStringRef Darwin::getDarwinArchName(const ArgList &Args) const { 134202879Srdivacky switch (getTriple().getArch()) { 135202879Srdivacky default: 136202879Srdivacky return getArchName(); 137223017Sdim 138221345Sdim case llvm::Triple::thumb: 139202879Srdivacky case llvm::Triple::arm: { 140202879Srdivacky if (const Arg *A = Args.getLastArg(options::OPT_march_EQ)) 141243830Sdim if (const char *Arch = GetArmArchForMArch(A->getValue())) 142202879Srdivacky return Arch; 143202879Srdivacky 144202879Srdivacky if (const Arg *A = Args.getLastArg(options::OPT_mcpu_EQ)) 145243830Sdim if (const char *Arch = GetArmArchForMCpu(A->getValue())) 146202879Srdivacky return Arch; 147202879Srdivacky 148202879Srdivacky return "arm"; 149202879Srdivacky } 150202879Srdivacky } 151202879Srdivacky} 152202879Srdivacky 153198092SrdivackyDarwin::~Darwin() { 154193326Sed} 155193326Sed 156226633Sdimstd::string Darwin::ComputeEffectiveClangTriple(const ArgList &Args, 157226633Sdim types::ID InputType) const { 158226633Sdim llvm::Triple Triple(ComputeLLVMTriple(Args, InputType)); 159212904Sdim 160212904Sdim // If the target isn't initialized (e.g., an unknown Darwin platform, return 161212904Sdim // the default triple). 162212904Sdim if (!isTargetInitialized()) 163212904Sdim return Triple.getTriple(); 164223017Sdim 165234353Sdim SmallString<16> Str; 166234353Sdim Str += isTargetIPhoneOS() ? "ios" : "macosx"; 167234353Sdim Str += getTargetVersion().getAsString(); 168234353Sdim Triple.setOSName(Str); 169223017Sdim 170212904Sdim return Triple.getTriple(); 171212904Sdim} 172212904Sdim 173234353Sdimvoid Generic_ELF::anchor() {} 174234353Sdim 175249423SdimTool *Darwin::getTool(Action::ActionClass AC) const { 176249423Sdim switch (AC) { 177249423Sdim case Action::LipoJobClass: 178249423Sdim if (!Lipo) 179249423Sdim Lipo.reset(new tools::darwin::Lipo(*this)); 180249423Sdim return Lipo.get(); 181249423Sdim case Action::DsymutilJobClass: 182249423Sdim if (!Dsymutil) 183249423Sdim Dsymutil.reset(new tools::darwin::Dsymutil(*this)); 184249423Sdim return Dsymutil.get(); 185249423Sdim case Action::VerifyJobClass: 186249423Sdim if (!VerifyDebug) 187249423Sdim VerifyDebug.reset(new tools::darwin::VerifyDebug(*this)); 188249423Sdim return VerifyDebug.get(); 189249423Sdim default: 190249423Sdim return ToolChain::getTool(AC); 191239462Sdim } 192249423Sdim} 193193326Sed 194249423SdimTool *Darwin::buildLinker() const { 195249423Sdim return new tools::darwin::Link(*this); 196249423Sdim} 197208600Srdivacky 198249423SdimTool *Darwin::buildAssembler() const { 199249423Sdim return new tools::darwin::Assemble(*this); 200193326Sed} 201193326Sed 202249423SdimDarwinClang::DarwinClang(const Driver &D, const llvm::Triple& Triple, 203249423Sdim const ArgList &Args) 204249423Sdim : Darwin(D, Triple, Args) 205198092Srdivacky{ 206218893Sdim getProgramPaths().push_back(getDriver().getInstalledDir()); 207218893Sdim if (getDriver().getInstalledDir() != getDriver().Dir) 208218893Sdim getProgramPaths().push_back(getDriver().Dir); 209218893Sdim 210198092Srdivacky // We expect 'as', 'ld', etc. to be adjacent to our install dir. 211212904Sdim getProgramPaths().push_back(getDriver().getInstalledDir()); 212212904Sdim if (getDriver().getInstalledDir() != getDriver().Dir) 213212904Sdim getProgramPaths().push_back(getDriver().Dir); 214226633Sdim} 215226633Sdim 216224145Sdimvoid DarwinClang::AddLinkARCArgs(const ArgList &Args, 217224145Sdim ArgStringList &CmdArgs) const { 218226633Sdim 219226633Sdim CmdArgs.push_back("-force_load"); 220224145Sdim llvm::sys::Path P(getDriver().ClangExecutable); 221224145Sdim P.eraseComponent(); // 'clang' 222224145Sdim P.eraseComponent(); // 'bin' 223224145Sdim P.appendComponent("lib"); 224224145Sdim P.appendComponent("arc"); 225224145Sdim P.appendComponent("libarclite_"); 226224145Sdim std::string s = P.str(); 227224145Sdim // Mash in the platform. 228234353Sdim if (isTargetIOSSimulator()) 229234353Sdim s += "iphonesimulator"; 230234353Sdim else if (isTargetIPhoneOS()) 231224145Sdim s += "iphoneos"; 232224145Sdim else 233224145Sdim s += "macosx"; 234224145Sdim s += ".a"; 235224145Sdim 236224145Sdim CmdArgs.push_back(Args.MakeArgString(s)); 237224145Sdim} 238224145Sdim 239224145Sdimvoid DarwinClang::AddLinkRuntimeLib(const ArgList &Args, 240226633Sdim ArgStringList &CmdArgs, 241249423Sdim const char *DarwinStaticLib, 242249423Sdim bool AlwaysLink) const { 243224145Sdim llvm::sys::Path P(getDriver().ResourceDir); 244224145Sdim P.appendComponent("lib"); 245224145Sdim P.appendComponent("darwin"); 246224145Sdim P.appendComponent(DarwinStaticLib); 247226633Sdim 248224145Sdim // For now, allow missing resource libraries to support developers who may 249249423Sdim // not have compiler-rt checked out or integrated into their build (unless 250249423Sdim // we explicitly force linking with this library). 251224145Sdim bool Exists; 252249423Sdim if (AlwaysLink || (!llvm::sys::fs::exists(P.str(), Exists) && Exists)) 253224145Sdim CmdArgs.push_back(Args.MakeArgString(P.str())); 254224145Sdim} 255224145Sdim 256198092Srdivackyvoid DarwinClang::AddLinkRuntimeLibArgs(const ArgList &Args, 257198092Srdivacky ArgStringList &CmdArgs) const { 258234353Sdim // Darwin only supports the compiler-rt based runtime libraries. 259234353Sdim switch (GetRuntimeLibType(Args)) { 260234353Sdim case ToolChain::RLT_CompilerRT: 261234353Sdim break; 262234353Sdim default: 263234353Sdim getDriver().Diag(diag::err_drv_unsupported_rtlib_for_platform) 264243830Sdim << Args.getLastArg(options::OPT_rtlib_EQ)->getValue() << "darwin"; 265234353Sdim return; 266234353Sdim } 267234353Sdim 268202879Srdivacky // Darwin doesn't support real static executables, don't link any runtime 269202879Srdivacky // libraries with -static. 270243830Sdim if (Args.hasArg(options::OPT_static) || 271243830Sdim Args.hasArg(options::OPT_fapple_kext) || 272243830Sdim Args.hasArg(options::OPT_mkernel)) 273198092Srdivacky return; 274198092Srdivacky 275198092Srdivacky // Reject -static-libgcc for now, we can deal with this when and if someone 276198092Srdivacky // cares. This is useful in situations where someone wants to statically link 277198092Srdivacky // something like libstdc++, and needs its runtime support routines. 278198092Srdivacky if (const Arg *A = Args.getLastArg(options::OPT_static_libgcc)) { 279226633Sdim getDriver().Diag(diag::err_drv_unsupported_opt) 280198092Srdivacky << A->getAsString(Args); 281198092Srdivacky return; 282198092Srdivacky } 283198092Srdivacky 284234353Sdim // If we are building profile support, link that library in. 285234353Sdim if (Args.hasArg(options::OPT_fprofile_arcs) || 286234353Sdim Args.hasArg(options::OPT_fprofile_generate) || 287234353Sdim Args.hasArg(options::OPT_fcreate_profile) || 288234353Sdim Args.hasArg(options::OPT_coverage)) { 289234353Sdim // Select the appropriate runtime library for the target. 290234353Sdim if (isTargetIPhoneOS()) { 291234353Sdim AddLinkRuntimeLib(Args, CmdArgs, "libclang_rt.profile_ios.a"); 292234353Sdim } else { 293234353Sdim AddLinkRuntimeLib(Args, CmdArgs, "libclang_rt.profile_osx.a"); 294234353Sdim } 295234353Sdim } 296234353Sdim 297251662Sdim SanitizerArgs Sanitize(*this, Args); 298243830Sdim 299249423Sdim // Add Ubsan runtime library, if required. 300249423Sdim if (Sanitize.needsUbsanRt()) { 301249423Sdim if (isTargetIPhoneOS()) { 302249423Sdim getDriver().Diag(diag::err_drv_clang_unsupported_per_platform) 303249423Sdim << "-fsanitize=undefined"; 304249423Sdim } else { 305249423Sdim AddLinkRuntimeLib(Args, CmdArgs, "libclang_rt.ubsan_osx.a", true); 306249423Sdim 307249423Sdim // The Ubsan runtime library requires C++. 308249423Sdim AddCXXStdlibLibArgs(Args, CmdArgs); 309249423Sdim } 310249423Sdim } 311249423Sdim 312234353Sdim // Add ASAN runtime library, if required. Dynamic libraries and bundles 313234353Sdim // should not be linked with the runtime library. 314243830Sdim if (Sanitize.needsAsanRt()) { 315249423Sdim if (isTargetIPhoneOS() && !isTargetIOSSimulator()) { 316234353Sdim getDriver().Diag(diag::err_drv_clang_unsupported_per_platform) 317243830Sdim << "-fsanitize=address"; 318234353Sdim } else { 319249423Sdim if (Args.hasArg(options::OPT_dynamiclib) || 320249423Sdim Args.hasArg(options::OPT_bundle)) { 321249423Sdim // Assume the binary will provide the ASan runtime. 322249423Sdim } else { 323249423Sdim AddLinkRuntimeLib(Args, CmdArgs, 324249423Sdim "libclang_rt.asan_osx_dynamic.dylib", true); 325249423Sdim // The ASAN runtime library requires C++. 326249423Sdim AddCXXStdlibLibArgs(Args, CmdArgs); 327249423Sdim } 328234353Sdim } 329234353Sdim } 330234353Sdim 331202879Srdivacky // Otherwise link libSystem, then the dynamic runtime library, and finally any 332202879Srdivacky // target specific static runtime library. 333198092Srdivacky CmdArgs.push_back("-lSystem"); 334202879Srdivacky 335202879Srdivacky // Select the dynamic runtime library and the target specific static library. 336203955Srdivacky if (isTargetIPhoneOS()) { 337221345Sdim // If we are compiling as iOS / simulator, don't attempt to link libgcc_s.1, 338221345Sdim // it never went into the SDK. 339226633Sdim // Linking against libgcc_s.1 isn't needed for iOS 5.0+ 340226633Sdim if (isIPhoneOSVersionLT(5, 0) && !isTargetIOSSimulator()) 341226633Sdim CmdArgs.push_back("-lgcc_s.1"); 342202879Srdivacky 343221345Sdim // We currently always need a static runtime library for iOS. 344224145Sdim AddLinkRuntimeLib(Args, CmdArgs, "libclang_rt.ios.a"); 345202879Srdivacky } else { 346202879Srdivacky // The dynamic runtime library was merged with libSystem for 10.6 and 347202879Srdivacky // beyond; only 10.4 and 10.5 need an additional runtime library. 348203955Srdivacky if (isMacosxVersionLT(10, 5)) 349202879Srdivacky CmdArgs.push_back("-lgcc_s.10.4"); 350203955Srdivacky else if (isMacosxVersionLT(10, 6)) 351202879Srdivacky CmdArgs.push_back("-lgcc_s.10.5"); 352202879Srdivacky 353218893Sdim // For OS X, we thought we would only need a static runtime library when 354221345Sdim // targeting 10.4, to provide versions of the static functions which were 355218893Sdim // omitted from 10.4.dylib. 356218893Sdim // 357218893Sdim // Unfortunately, that turned out to not be true, because Darwin system 358218893Sdim // headers can still use eprintf on i386, and it is not exported from 359218893Sdim // libSystem. Therefore, we still must provide a runtime library just for 360218893Sdim // the tiny tiny handful of projects that *might* use that symbol. 361218893Sdim if (isMacosxVersionLT(10, 5)) { 362224145Sdim AddLinkRuntimeLib(Args, CmdArgs, "libclang_rt.10.4.a"); 363218893Sdim } else { 364218893Sdim if (getTriple().getArch() == llvm::Triple::x86) 365224145Sdim AddLinkRuntimeLib(Args, CmdArgs, "libclang_rt.eprintf.a"); 366224145Sdim AddLinkRuntimeLib(Args, CmdArgs, "libclang_rt.osx.a"); 367218893Sdim } 368202879Srdivacky } 369224145Sdim} 370202879Srdivacky 371212904Sdimvoid Darwin::AddDeploymentTarget(DerivedArgList &Args) const { 372201361Srdivacky const OptTable &Opts = getDriver().getOpts(); 373193326Sed 374243830Sdim // Support allowing the SDKROOT environment variable used by xcrun and other 375243830Sdim // Xcode tools to define the default sysroot, by making it the default for 376243830Sdim // isysroot. 377249423Sdim if (const Arg *A = Args.getLastArg(options::OPT_isysroot)) { 378249423Sdim // Warn if the path does not exist. 379249423Sdim bool Exists; 380249423Sdim if (llvm::sys::fs::exists(A->getValue(), Exists) || !Exists) 381249423Sdim getDriver().Diag(clang::diag::warn_missing_sysroot) << A->getValue(); 382249423Sdim } else { 383243830Sdim if (char *env = ::getenv("SDKROOT")) { 384249423Sdim // We only use this value as the default if it is an absolute path, 385249423Sdim // exists, and it is not the root path. 386249423Sdim if (llvm::sys::path::is_absolute(env) && llvm::sys::fs::exists(env) && 387249423Sdim StringRef(env) != "/") { 388243830Sdim Args.append(Args.MakeSeparateArg( 389243830Sdim 0, Opts.getOption(options::OPT_isysroot), env)); 390243830Sdim } 391243830Sdim } 392243830Sdim } 393243830Sdim 394203955Srdivacky Arg *OSXVersion = Args.getLastArg(options::OPT_mmacosx_version_min_EQ); 395221345Sdim Arg *iOSVersion = Args.getLastArg(options::OPT_miphoneos_version_min_EQ); 396221345Sdim Arg *iOSSimVersion = Args.getLastArg( 397221345Sdim options::OPT_mios_simulator_version_min_EQ); 398224145Sdim 399221345Sdim if (OSXVersion && (iOSVersion || iOSSimVersion)) { 400226633Sdim getDriver().Diag(diag::err_drv_argument_not_allowed_with) 401193326Sed << OSXVersion->getAsString(Args) 402221345Sdim << (iOSVersion ? iOSVersion : iOSSimVersion)->getAsString(Args); 403221345Sdim iOSVersion = iOSSimVersion = 0; 404221345Sdim } else if (iOSVersion && iOSSimVersion) { 405226633Sdim getDriver().Diag(diag::err_drv_argument_not_allowed_with) 406221345Sdim << iOSVersion->getAsString(Args) 407221345Sdim << iOSSimVersion->getAsString(Args); 408221345Sdim iOSSimVersion = 0; 409221345Sdim } else if (!OSXVersion && !iOSVersion && !iOSSimVersion) { 410226633Sdim // If no deployment target was specified on the command line, check for 411203955Srdivacky // environment defines. 412226633Sdim StringRef OSXTarget; 413226633Sdim StringRef iOSTarget; 414226633Sdim StringRef iOSSimTarget; 415226633Sdim if (char *env = ::getenv("MACOSX_DEPLOYMENT_TARGET")) 416226633Sdim OSXTarget = env; 417226633Sdim if (char *env = ::getenv("IPHONEOS_DEPLOYMENT_TARGET")) 418226633Sdim iOSTarget = env; 419226633Sdim if (char *env = ::getenv("IOS_SIMULATOR_DEPLOYMENT_TARGET")) 420226633Sdim iOSSimTarget = env; 421203955Srdivacky 422226633Sdim // If no '-miphoneos-version-min' specified on the command line and 423226633Sdim // IPHONEOS_DEPLOYMENT_TARGET is not defined, see if we can set the default 424234982Sdim // based on -isysroot. 425226633Sdim if (iOSTarget.empty()) { 426226633Sdim if (const Arg *A = Args.getLastArg(options::OPT_isysroot)) { 427226633Sdim StringRef first, second; 428243830Sdim StringRef isysroot = A->getValue(); 429226633Sdim llvm::tie(first, second) = isysroot.split(StringRef("SDKs/iPhoneOS")); 430226633Sdim if (second != "") 431226633Sdim iOSTarget = second.substr(0,3); 432226633Sdim } 433226633Sdim } 434203955Srdivacky 435226633Sdim // If no OSX or iOS target has been specified and we're compiling for armv7, 436226633Sdim // go ahead as assume we're targeting iOS. 437239462Sdim if (OSXTarget.empty() && iOSTarget.empty() && 438243830Sdim (getDarwinArchName(Args) == "armv7" || 439243830Sdim getDarwinArchName(Args) == "armv7s")) 440239462Sdim iOSTarget = iOSVersionMin; 441226633Sdim 442221345Sdim // Handle conflicting deployment targets 443193326Sed // 444203955Srdivacky // FIXME: Don't hardcode default here. 445221345Sdim 446221345Sdim // Do not allow conflicts with the iOS simulator target. 447226633Sdim if (!iOSSimTarget.empty() && (!OSXTarget.empty() || !iOSTarget.empty())) { 448226633Sdim getDriver().Diag(diag::err_drv_conflicting_deployment_targets) 449221345Sdim << "IOS_SIMULATOR_DEPLOYMENT_TARGET" 450226633Sdim << (!OSXTarget.empty() ? "MACOSX_DEPLOYMENT_TARGET" : 451221345Sdim "IPHONEOS_DEPLOYMENT_TARGET"); 452221345Sdim } 453221345Sdim 454221345Sdim // Allow conflicts among OSX and iOS for historical reasons, but choose the 455221345Sdim // default platform. 456226633Sdim if (!OSXTarget.empty() && !iOSTarget.empty()) { 457203955Srdivacky if (getTriple().getArch() == llvm::Triple::arm || 458203955Srdivacky getTriple().getArch() == llvm::Triple::thumb) 459226633Sdim OSXTarget = ""; 460203955Srdivacky else 461226633Sdim iOSTarget = ""; 462203955Srdivacky } 463193326Sed 464226633Sdim if (!OSXTarget.empty()) { 465243830Sdim const Option O = Opts.getOption(options::OPT_mmacosx_version_min_EQ); 466212904Sdim OSXVersion = Args.MakeJoinedArg(0, O, OSXTarget); 467212904Sdim Args.append(OSXVersion); 468226633Sdim } else if (!iOSTarget.empty()) { 469243830Sdim const Option O = Opts.getOption(options::OPT_miphoneos_version_min_EQ); 470221345Sdim iOSVersion = Args.MakeJoinedArg(0, O, iOSTarget); 471221345Sdim Args.append(iOSVersion); 472226633Sdim } else if (!iOSSimTarget.empty()) { 473243830Sdim const Option O = Opts.getOption( 474221345Sdim options::OPT_mios_simulator_version_min_EQ); 475221345Sdim iOSSimVersion = Args.MakeJoinedArg(0, O, iOSSimTarget); 476221345Sdim Args.append(iOSSimVersion); 477198092Srdivacky } else { 478210299Sed // Otherwise, assume we are targeting OS X. 479243830Sdim const Option O = Opts.getOption(options::OPT_mmacosx_version_min_EQ); 480212904Sdim OSXVersion = Args.MakeJoinedArg(0, O, MacosxVersionMin); 481212904Sdim Args.append(OSXVersion); 482198092Srdivacky } 483193326Sed } 484198092Srdivacky 485221345Sdim // Reject invalid architecture combinations. 486221345Sdim if (iOSSimVersion && (getTriple().getArch() != llvm::Triple::x86 && 487221345Sdim getTriple().getArch() != llvm::Triple::x86_64)) { 488226633Sdim getDriver().Diag(diag::err_drv_invalid_arch_for_deployment_target) 489221345Sdim << getTriple().getArchName() << iOSSimVersion->getAsString(Args); 490221345Sdim } 491221345Sdim 492203955Srdivacky // Set the tool chain target information. 493203955Srdivacky unsigned Major, Minor, Micro; 494203955Srdivacky bool HadExtra; 495203955Srdivacky if (OSXVersion) { 496221345Sdim assert((!iOSVersion && !iOSSimVersion) && "Unknown target platform!"); 497243830Sdim if (!Driver::GetReleaseVersion(OSXVersion->getValue(), Major, Minor, 498203955Srdivacky Micro, HadExtra) || HadExtra || 499221345Sdim Major != 10 || Minor >= 100 || Micro >= 100) 500226633Sdim getDriver().Diag(diag::err_drv_invalid_version_number) 501203955Srdivacky << OSXVersion->getAsString(Args); 502203955Srdivacky } else { 503221345Sdim const Arg *Version = iOSVersion ? iOSVersion : iOSSimVersion; 504221345Sdim assert(Version && "Unknown target platform!"); 505243830Sdim if (!Driver::GetReleaseVersion(Version->getValue(), Major, Minor, 506203955Srdivacky Micro, HadExtra) || HadExtra || 507203955Srdivacky Major >= 10 || Minor >= 100 || Micro >= 100) 508226633Sdim getDriver().Diag(diag::err_drv_invalid_version_number) 509221345Sdim << Version->getAsString(Args); 510203955Srdivacky } 511221345Sdim 512221345Sdim bool IsIOSSim = bool(iOSSimVersion); 513221345Sdim 514221345Sdim // In GCC, the simulator historically was treated as being OS X in some 515221345Sdim // contexts, like determining the link logic, despite generally being called 516221345Sdim // with an iOS deployment target. For compatibility, we detect the 517221345Sdim // simulator as iOS + x86, and treat it differently in a few contexts. 518221345Sdim if (iOSVersion && (getTriple().getArch() == llvm::Triple::x86 || 519221345Sdim getTriple().getArch() == llvm::Triple::x86_64)) 520221345Sdim IsIOSSim = true; 521221345Sdim 522221345Sdim setTarget(/*IsIPhoneOS=*/ !OSXVersion, Major, Minor, Micro, IsIOSSim); 523212904Sdim} 524203955Srdivacky 525218893Sdimvoid DarwinClang::AddCXXStdlibLibArgs(const ArgList &Args, 526218893Sdim ArgStringList &CmdArgs) const { 527218893Sdim CXXStdlibType Type = GetCXXStdlibType(Args); 528218893Sdim 529218893Sdim switch (Type) { 530218893Sdim case ToolChain::CST_Libcxx: 531218893Sdim CmdArgs.push_back("-lc++"); 532218893Sdim break; 533218893Sdim 534218893Sdim case ToolChain::CST_Libstdcxx: { 535218893Sdim // Unfortunately, -lstdc++ doesn't always exist in the standard search path; 536218893Sdim // it was previously found in the gcc lib dir. However, for all the Darwin 537218893Sdim // platforms we care about it was -lstdc++.6, so we search for that 538218893Sdim // explicitly if we can't see an obvious -lstdc++ candidate. 539218893Sdim 540218893Sdim // Check in the sysroot first. 541218893Sdim bool Exists; 542218893Sdim if (const Arg *A = Args.getLastArg(options::OPT_isysroot)) { 543243830Sdim llvm::sys::Path P(A->getValue()); 544218893Sdim P.appendComponent("usr"); 545218893Sdim P.appendComponent("lib"); 546218893Sdim P.appendComponent("libstdc++.dylib"); 547218893Sdim 548218893Sdim if (llvm::sys::fs::exists(P.str(), Exists) || !Exists) { 549218893Sdim P.eraseComponent(); 550218893Sdim P.appendComponent("libstdc++.6.dylib"); 551218893Sdim if (!llvm::sys::fs::exists(P.str(), Exists) && Exists) { 552218893Sdim CmdArgs.push_back(Args.MakeArgString(P.str())); 553218893Sdim return; 554218893Sdim } 555218893Sdim } 556218893Sdim } 557218893Sdim 558218893Sdim // Otherwise, look in the root. 559234353Sdim // FIXME: This should be removed someday when we don't have to care about 560234353Sdim // 10.6 and earlier, where /usr/lib/libstdc++.dylib does not exist. 561218893Sdim if ((llvm::sys::fs::exists("/usr/lib/libstdc++.dylib", Exists) || !Exists)&& 562218893Sdim (!llvm::sys::fs::exists("/usr/lib/libstdc++.6.dylib", Exists) && Exists)){ 563218893Sdim CmdArgs.push_back("/usr/lib/libstdc++.6.dylib"); 564218893Sdim return; 565218893Sdim } 566218893Sdim 567218893Sdim // Otherwise, let the linker search. 568218893Sdim CmdArgs.push_back("-lstdc++"); 569218893Sdim break; 570218893Sdim } 571218893Sdim } 572218893Sdim} 573218893Sdim 574218893Sdimvoid DarwinClang::AddCCKextLibArgs(const ArgList &Args, 575218893Sdim ArgStringList &CmdArgs) const { 576218893Sdim 577218893Sdim // For Darwin platforms, use the compiler-rt-based support library 578218893Sdim // instead of the gcc-provided one (which is also incidentally 579218893Sdim // only present in the gcc lib dir, which makes it hard to find). 580218893Sdim 581218893Sdim llvm::sys::Path P(getDriver().ResourceDir); 582218893Sdim P.appendComponent("lib"); 583218893Sdim P.appendComponent("darwin"); 584223017Sdim 585243830Sdim // Use the newer cc_kext for iOS ARM after 6.0. 586243830Sdim if (!isTargetIPhoneOS() || isTargetIOSSimulator() || 587243830Sdim !isIPhoneOSVersionLT(6, 0)) { 588243830Sdim P.appendComponent("libclang_rt.cc_kext.a"); 589243830Sdim } else { 590243830Sdim P.appendComponent("libclang_rt.cc_kext_ios5.a"); 591243830Sdim } 592243830Sdim 593218893Sdim // For now, allow missing resource libraries to support developers who may 594218893Sdim // not have compiler-rt checked out or integrated into their build. 595218893Sdim bool Exists; 596218893Sdim if (!llvm::sys::fs::exists(P.str(), Exists) && Exists) 597218893Sdim CmdArgs.push_back(Args.MakeArgString(P.str())); 598218893Sdim} 599218893Sdim 600212904SdimDerivedArgList *Darwin::TranslateArgs(const DerivedArgList &Args, 601212904Sdim const char *BoundArch) const { 602212904Sdim DerivedArgList *DAL = new DerivedArgList(Args.getBaseArgs()); 603212904Sdim const OptTable &Opts = getDriver().getOpts(); 604212904Sdim 605212904Sdim // FIXME: We really want to get out of the tool chain level argument 606212904Sdim // translation business, as it makes the driver functionality much 607212904Sdim // more opaque. For now, we follow gcc closely solely for the 608212904Sdim // purpose of easily achieving feature parity & testability. Once we 609212904Sdim // have something that works, we should reevaluate each translation 610212904Sdim // and try to push it down into tool specific logic. 611212904Sdim 612210299Sed for (ArgList::const_iterator it = Args.begin(), 613210299Sed ie = Args.end(); it != ie; ++it) { 614193326Sed Arg *A = *it; 615193326Sed 616193326Sed if (A->getOption().matches(options::OPT_Xarch__)) { 617224145Sdim // Skip this argument unless the architecture matches either the toolchain 618224145Sdim // triple arch, or the arch being bound. 619243830Sdim llvm::Triple::ArchType XarchArch = 620243830Sdim tools::darwin::getArchTypeForDarwinArchName(A->getValue(0)); 621243830Sdim if (!(XarchArch == getArch() || 622243830Sdim (BoundArch && XarchArch == 623243830Sdim tools::darwin::getArchTypeForDarwinArchName(BoundArch)))) 624193326Sed continue; 625193326Sed 626218893Sdim Arg *OriginalArg = A; 627243830Sdim unsigned Index = Args.getBaseArgs().MakeIndex(A->getValue(1)); 628210299Sed unsigned Prev = Index; 629193326Sed Arg *XarchArg = Opts.ParseOneArg(Args, Index); 630198092Srdivacky 631193326Sed // If the argument parsing failed or more than one argument was 632193326Sed // consumed, the -Xarch_ argument's parameter tried to consume 633193326Sed // extra arguments. Emit an error and ignore. 634193326Sed // 635193326Sed // We also want to disallow any options which would alter the 636193326Sed // driver behavior; that isn't going to work in our model. We 637193326Sed // use isDriverOption() as an approximation, although things 638193326Sed // like -O4 are going to slip through. 639221345Sdim if (!XarchArg || Index > Prev + 1) { 640226633Sdim getDriver().Diag(diag::err_drv_invalid_Xarch_argument_with_args) 641193326Sed << A->getAsString(Args); 642193326Sed continue; 643243830Sdim } else if (XarchArg->getOption().hasFlag(options::DriverOption)) { 644226633Sdim getDriver().Diag(diag::err_drv_invalid_Xarch_argument_isdriver) 645221345Sdim << A->getAsString(Args); 646221345Sdim continue; 647193326Sed } 648193326Sed 649193326Sed XarchArg->setBaseArg(A); 650193326Sed A = XarchArg; 651210299Sed 652210299Sed DAL->AddSynthesizedArg(A); 653218893Sdim 654218893Sdim // Linker input arguments require custom handling. The problem is that we 655218893Sdim // have already constructed the phase actions, so we can not treat them as 656218893Sdim // "input arguments". 657243830Sdim if (A->getOption().hasFlag(options::LinkerInput)) { 658218893Sdim // Convert the argument into individual Zlinker_input_args. 659218893Sdim for (unsigned i = 0, e = A->getNumValues(); i != e; ++i) { 660218893Sdim DAL->AddSeparateArg(OriginalArg, 661218893Sdim Opts.getOption(options::OPT_Zlinker_input), 662243830Sdim A->getValue(i)); 663223017Sdim 664218893Sdim } 665218893Sdim continue; 666218893Sdim } 667198092Srdivacky } 668193326Sed 669193326Sed // Sob. These is strictly gcc compatible for the time being. Apple 670193326Sed // gcc translates options twice, which means that self-expanding 671193326Sed // options add duplicates. 672199512Srdivacky switch ((options::ID) A->getOption().getID()) { 673193326Sed default: 674193326Sed DAL->append(A); 675193326Sed break; 676193326Sed 677193326Sed case options::OPT_mkernel: 678193326Sed case options::OPT_fapple_kext: 679193326Sed DAL->append(A); 680210299Sed DAL->AddFlagArg(A, Opts.getOption(options::OPT_static)); 681193326Sed break; 682198092Srdivacky 683193326Sed case options::OPT_dependency_file: 684210299Sed DAL->AddSeparateArg(A, Opts.getOption(options::OPT_MF), 685243830Sdim A->getValue()); 686193326Sed break; 687193326Sed 688193326Sed case options::OPT_gfull: 689210299Sed DAL->AddFlagArg(A, Opts.getOption(options::OPT_g_Flag)); 690210299Sed DAL->AddFlagArg(A, 691210299Sed Opts.getOption(options::OPT_fno_eliminate_unused_debug_symbols)); 692193326Sed break; 693193326Sed 694193326Sed case options::OPT_gused: 695210299Sed DAL->AddFlagArg(A, Opts.getOption(options::OPT_g_Flag)); 696210299Sed DAL->AddFlagArg(A, 697210299Sed Opts.getOption(options::OPT_feliminate_unused_debug_symbols)); 698193326Sed break; 699193326Sed 700193326Sed case options::OPT_shared: 701210299Sed DAL->AddFlagArg(A, Opts.getOption(options::OPT_dynamiclib)); 702193326Sed break; 703193326Sed 704193326Sed case options::OPT_fconstant_cfstrings: 705210299Sed DAL->AddFlagArg(A, Opts.getOption(options::OPT_mconstant_cfstrings)); 706193326Sed break; 707193326Sed 708193326Sed case options::OPT_fno_constant_cfstrings: 709210299Sed DAL->AddFlagArg(A, Opts.getOption(options::OPT_mno_constant_cfstrings)); 710193326Sed break; 711193326Sed 712193326Sed case options::OPT_Wnonportable_cfstrings: 713210299Sed DAL->AddFlagArg(A, 714210299Sed Opts.getOption(options::OPT_mwarn_nonportable_cfstrings)); 715193326Sed break; 716193326Sed 717193326Sed case options::OPT_Wno_nonportable_cfstrings: 718210299Sed DAL->AddFlagArg(A, 719210299Sed Opts.getOption(options::OPT_mno_warn_nonportable_cfstrings)); 720193326Sed break; 721193326Sed 722193326Sed case options::OPT_fpascal_strings: 723210299Sed DAL->AddFlagArg(A, Opts.getOption(options::OPT_mpascal_strings)); 724193326Sed break; 725193326Sed 726193326Sed case options::OPT_fno_pascal_strings: 727210299Sed DAL->AddFlagArg(A, Opts.getOption(options::OPT_mno_pascal_strings)); 728193326Sed break; 729193326Sed } 730193326Sed } 731193326Sed 732198092Srdivacky if (getTriple().getArch() == llvm::Triple::x86 || 733198092Srdivacky getTriple().getArch() == llvm::Triple::x86_64) 734199512Srdivacky if (!Args.hasArgNoClaim(options::OPT_mtune_EQ)) 735210299Sed DAL->AddJoinedArg(0, Opts.getOption(options::OPT_mtune_EQ), "core2"); 736198092Srdivacky 737198092Srdivacky // Add the arch options based on the particular spelling of -arch, to match 738198092Srdivacky // how the driver driver works. 739198092Srdivacky if (BoundArch) { 740226633Sdim StringRef Name = BoundArch; 741243830Sdim const Option MCpu = Opts.getOption(options::OPT_mcpu_EQ); 742243830Sdim const Option MArch = Opts.getOption(options::OPT_march_EQ); 743198092Srdivacky 744198092Srdivacky // This code must be kept in sync with LLVM's getArchTypeForDarwinArch, 745198092Srdivacky // which defines the list of which architectures we accept. 746198092Srdivacky if (Name == "ppc") 747198092Srdivacky ; 748198092Srdivacky else if (Name == "ppc601") 749210299Sed DAL->AddJoinedArg(0, MCpu, "601"); 750198092Srdivacky else if (Name == "ppc603") 751210299Sed DAL->AddJoinedArg(0, MCpu, "603"); 752198092Srdivacky else if (Name == "ppc604") 753210299Sed DAL->AddJoinedArg(0, MCpu, "604"); 754198092Srdivacky else if (Name == "ppc604e") 755210299Sed DAL->AddJoinedArg(0, MCpu, "604e"); 756198092Srdivacky else if (Name == "ppc750") 757210299Sed DAL->AddJoinedArg(0, MCpu, "750"); 758198092Srdivacky else if (Name == "ppc7400") 759210299Sed DAL->AddJoinedArg(0, MCpu, "7400"); 760198092Srdivacky else if (Name == "ppc7450") 761210299Sed DAL->AddJoinedArg(0, MCpu, "7450"); 762198092Srdivacky else if (Name == "ppc970") 763210299Sed DAL->AddJoinedArg(0, MCpu, "970"); 764198092Srdivacky 765198092Srdivacky else if (Name == "ppc64") 766210299Sed DAL->AddFlagArg(0, Opts.getOption(options::OPT_m64)); 767193326Sed 768198092Srdivacky else if (Name == "i386") 769198092Srdivacky ; 770198092Srdivacky else if (Name == "i486") 771210299Sed DAL->AddJoinedArg(0, MArch, "i486"); 772198092Srdivacky else if (Name == "i586") 773210299Sed DAL->AddJoinedArg(0, MArch, "i586"); 774198092Srdivacky else if (Name == "i686") 775210299Sed DAL->AddJoinedArg(0, MArch, "i686"); 776198092Srdivacky else if (Name == "pentium") 777210299Sed DAL->AddJoinedArg(0, MArch, "pentium"); 778198092Srdivacky else if (Name == "pentium2") 779210299Sed DAL->AddJoinedArg(0, MArch, "pentium2"); 780198092Srdivacky else if (Name == "pentpro") 781210299Sed DAL->AddJoinedArg(0, MArch, "pentiumpro"); 782198092Srdivacky else if (Name == "pentIIm3") 783210299Sed DAL->AddJoinedArg(0, MArch, "pentium2"); 784193326Sed 785198092Srdivacky else if (Name == "x86_64") 786210299Sed DAL->AddFlagArg(0, Opts.getOption(options::OPT_m64)); 787198092Srdivacky 788198092Srdivacky else if (Name == "arm") 789210299Sed DAL->AddJoinedArg(0, MArch, "armv4t"); 790198092Srdivacky else if (Name == "armv4t") 791210299Sed DAL->AddJoinedArg(0, MArch, "armv4t"); 792198092Srdivacky else if (Name == "armv5") 793210299Sed DAL->AddJoinedArg(0, MArch, "armv5tej"); 794198092Srdivacky else if (Name == "xscale") 795210299Sed DAL->AddJoinedArg(0, MArch, "xscale"); 796198092Srdivacky else if (Name == "armv6") 797210299Sed DAL->AddJoinedArg(0, MArch, "armv6k"); 798249423Sdim else if (Name == "armv6m") 799249423Sdim DAL->AddJoinedArg(0, MArch, "armv6m"); 800198092Srdivacky else if (Name == "armv7") 801210299Sed DAL->AddJoinedArg(0, MArch, "armv7a"); 802249423Sdim else if (Name == "armv7em") 803249423Sdim DAL->AddJoinedArg(0, MArch, "armv7em"); 804243830Sdim else if (Name == "armv7f") 805243830Sdim DAL->AddJoinedArg(0, MArch, "armv7f"); 806243830Sdim else if (Name == "armv7k") 807243830Sdim DAL->AddJoinedArg(0, MArch, "armv7k"); 808249423Sdim else if (Name == "armv7m") 809249423Sdim DAL->AddJoinedArg(0, MArch, "armv7m"); 810243830Sdim else if (Name == "armv7s") 811243830Sdim DAL->AddJoinedArg(0, MArch, "armv7s"); 812198092Srdivacky 813198092Srdivacky else 814200583Srdivacky llvm_unreachable("invalid Darwin arch"); 815198092Srdivacky } 816198092Srdivacky 817212904Sdim // Add an explicit version min argument for the deployment target. We do this 818212904Sdim // after argument translation because -Xarch_ arguments may add a version min 819212904Sdim // argument. 820239462Sdim if (BoundArch) 821239462Sdim AddDeploymentTarget(*DAL); 822212904Sdim 823243830Sdim // For iOS 6, undo the translation to add -static for -mkernel/-fapple-kext. 824243830Sdim // FIXME: It would be far better to avoid inserting those -static arguments, 825243830Sdim // but we can't check the deployment target in the translation code until 826243830Sdim // it is set here. 827243830Sdim if (isTargetIPhoneOS() && !isIPhoneOSVersionLT(6, 0)) { 828243830Sdim for (ArgList::iterator it = DAL->begin(), ie = DAL->end(); it != ie; ) { 829243830Sdim Arg *A = *it; 830243830Sdim ++it; 831243830Sdim if (A->getOption().getID() != options::OPT_mkernel && 832243830Sdim A->getOption().getID() != options::OPT_fapple_kext) 833243830Sdim continue; 834243830Sdim assert(it != ie && "unexpected argument translation"); 835243830Sdim A = *it; 836243830Sdim assert(A->getOption().getID() == options::OPT_static && 837243830Sdim "missing expected -static argument"); 838243830Sdim it = DAL->getArgs().erase(it); 839243830Sdim } 840243830Sdim } 841243830Sdim 842226633Sdim // Validate the C++ standard library choice. 843226633Sdim CXXStdlibType Type = GetCXXStdlibType(*DAL); 844226633Sdim if (Type == ToolChain::CST_Libcxx) { 845239462Sdim // Check whether the target provides libc++. 846239462Sdim StringRef where; 847239462Sdim 848239462Sdim // Complain about targetting iOS < 5.0 in any way. 849243830Sdim if (isTargetIPhoneOS() && isIPhoneOSVersionLT(5, 0)) 850243830Sdim where = "iOS 5.0"; 851239462Sdim 852239462Sdim if (where != StringRef()) { 853226633Sdim getDriver().Diag(clang::diag::err_drv_invalid_libcxx_deployment) 854239462Sdim << where; 855226633Sdim } 856226633Sdim } 857226633Sdim 858193326Sed return DAL; 859198092Srdivacky} 860193326Sed 861198092Srdivackybool Darwin::IsUnwindTablesDefault() const { 862243830Sdim return getArch() == llvm::Triple::x86_64; 863193326Sed} 864193326Sed 865201361Srdivackybool Darwin::UseDwarfDebugFlags() const { 866201361Srdivacky if (const char *S = ::getenv("RC_DEBUG_OPTIONS")) 867201361Srdivacky return S[0] != '\0'; 868201361Srdivacky return false; 869201361Srdivacky} 870201361Srdivacky 871203955Srdivackybool Darwin::UseSjLjExceptions() const { 872203955Srdivacky // Darwin uses SjLj exceptions on ARM. 873203955Srdivacky return (getTriple().getArch() == llvm::Triple::arm || 874203955Srdivacky getTriple().getArch() == llvm::Triple::thumb); 875203955Srdivacky} 876203955Srdivacky 877243830Sdimbool Darwin::isPICDefault() const { 878243830Sdim return true; 879193326Sed} 880193326Sed 881251662Sdimbool Darwin::isPIEDefault() const { 882251662Sdim return false; 883251662Sdim} 884251662Sdim 885243830Sdimbool Darwin::isPICDefaultForced() const { 886243830Sdim return getArch() == llvm::Triple::x86_64; 887193326Sed} 888193326Sed 889221345Sdimbool Darwin::SupportsProfiling() const { 890221345Sdim // Profiling instrumentation is only supported on x86. 891243830Sdim return getArch() == llvm::Triple::x86 || getArch() == llvm::Triple::x86_64; 892221345Sdim} 893221345Sdim 894207619Srdivackybool Darwin::SupportsObjCGC() const { 895207619Srdivacky // Garbage collection is supported everywhere except on iPhone OS. 896207619Srdivacky return !isTargetIPhoneOS(); 897207619Srdivacky} 898207619Srdivacky 899243830Sdimvoid Darwin::CheckObjCARC() const { 900243830Sdim if (isTargetIPhoneOS() || !isMacosxVersionLT(10, 6)) 901243830Sdim return; 902243830Sdim getDriver().Diag(diag::err_arc_unsupported_on_toolchain); 903234353Sdim} 904234353Sdim 905212904Sdimstd::string 906226633SdimDarwin_Generic_GCC::ComputeEffectiveClangTriple(const ArgList &Args, 907226633Sdim types::ID InputType) const { 908226633Sdim return ComputeLLVMTriple(Args, InputType); 909212904Sdim} 910212904Sdim 911193326Sed/// Generic_GCC - A tool chain using the 'gcc' command to perform 912193326Sed/// all subcommands; this relies on gcc translating the majority of 913193326Sed/// command line options. 914193326Sed 915234353Sdim/// \brief Parse a GCCVersion object out of a string of text. 916234353Sdim/// 917234353Sdim/// This is the primary means of forming GCCVersion objects. 918234353Sdim/*static*/ 919234353SdimGeneric_GCC::GCCVersion Linux::GCCVersion::Parse(StringRef VersionText) { 920234353Sdim const GCCVersion BadVersion = { VersionText.str(), -1, -1, -1, "" }; 921234353Sdim std::pair<StringRef, StringRef> First = VersionText.split('.'); 922234353Sdim std::pair<StringRef, StringRef> Second = First.second.split('.'); 923234353Sdim 924234353Sdim GCCVersion GoodVersion = { VersionText.str(), -1, -1, -1, "" }; 925234353Sdim if (First.first.getAsInteger(10, GoodVersion.Major) || 926234353Sdim GoodVersion.Major < 0) 927234353Sdim return BadVersion; 928234353Sdim if (Second.first.getAsInteger(10, GoodVersion.Minor) || 929234353Sdim GoodVersion.Minor < 0) 930234353Sdim return BadVersion; 931234353Sdim 932234353Sdim // First look for a number prefix and parse that if present. Otherwise just 933234353Sdim // stash the entire patch string in the suffix, and leave the number 934234353Sdim // unspecified. This covers versions strings such as: 935234353Sdim // 4.4 936234353Sdim // 4.4.0 937234353Sdim // 4.4.x 938234353Sdim // 4.4.2-rc4 939234353Sdim // 4.4.x-patched 940234353Sdim // And retains any patch number it finds. 941234353Sdim StringRef PatchText = GoodVersion.PatchSuffix = Second.second.str(); 942234353Sdim if (!PatchText.empty()) { 943249423Sdim if (size_t EndNumber = PatchText.find_first_not_of("0123456789")) { 944234353Sdim // Try to parse the number and any suffix. 945234353Sdim if (PatchText.slice(0, EndNumber).getAsInteger(10, GoodVersion.Patch) || 946234353Sdim GoodVersion.Patch < 0) 947234353Sdim return BadVersion; 948234353Sdim GoodVersion.PatchSuffix = PatchText.substr(EndNumber).str(); 949234353Sdim } 950234353Sdim } 951234353Sdim 952234353Sdim return GoodVersion; 953234353Sdim} 954234353Sdim 955234353Sdim/// \brief Less-than for GCCVersion, implementing a Strict Weak Ordering. 956234353Sdimbool Generic_GCC::GCCVersion::operator<(const GCCVersion &RHS) const { 957249423Sdim if (Major != RHS.Major) 958249423Sdim return Major < RHS.Major; 959249423Sdim if (Minor != RHS.Minor) 960249423Sdim return Minor < RHS.Minor; 961249423Sdim if (Patch != RHS.Patch) { 962249423Sdim // Note that versions without a specified patch sort higher than those with 963249423Sdim // a patch. 964249423Sdim if (RHS.Patch == -1) 965249423Sdim return true; 966249423Sdim if (Patch == -1) 967249423Sdim return false; 968234353Sdim 969249423Sdim // Otherwise just sort on the patch itself. 970249423Sdim return Patch < RHS.Patch; 971249423Sdim } 972249423Sdim if (PatchSuffix != RHS.PatchSuffix) { 973249423Sdim // Sort empty suffixes higher. 974249423Sdim if (RHS.PatchSuffix.empty()) 975249423Sdim return true; 976249423Sdim if (PatchSuffix.empty()) 977249423Sdim return false; 978234353Sdim 979249423Sdim // Provide a lexicographic sort to make this a total ordering. 980249423Sdim return PatchSuffix < RHS.PatchSuffix; 981249423Sdim } 982249423Sdim 983249423Sdim // The versions are equal. 984234353Sdim return false; 985234353Sdim} 986234353Sdim 987234353Sdimstatic StringRef getGCCToolchainDir(const ArgList &Args) { 988234353Sdim const Arg *A = Args.getLastArg(options::OPT_gcc_toolchain); 989234353Sdim if (A) 990243830Sdim return A->getValue(); 991234353Sdim return GCC_INSTALL_PREFIX; 992234353Sdim} 993234353Sdim 994234353Sdim/// \brief Construct a GCCInstallationDetector from the driver. 995234353Sdim/// 996234353Sdim/// This performs all of the autodetection and sets up the various paths. 997234982Sdim/// Once constructed, a GCCInstallationDetector is essentially immutable. 998234353Sdim/// 999234353Sdim/// FIXME: We shouldn't need an explicit TargetTriple parameter here, and 1000234353Sdim/// should instead pull the target out of the driver. This is currently 1001234353Sdim/// necessary because the driver doesn't store the final version of the target 1002234353Sdim/// triple. 1003234353SdimGeneric_GCC::GCCInstallationDetector::GCCInstallationDetector( 1004234353Sdim const Driver &D, 1005234353Sdim const llvm::Triple &TargetTriple, 1006234353Sdim const ArgList &Args) 1007234353Sdim : IsValid(false) { 1008234353Sdim llvm::Triple MultiarchTriple 1009234353Sdim = TargetTriple.isArch32Bit() ? TargetTriple.get64BitArchVariant() 1010234353Sdim : TargetTriple.get32BitArchVariant(); 1011234353Sdim llvm::Triple::ArchType TargetArch = TargetTriple.getArch(); 1012234353Sdim // The library directories which may contain GCC installations. 1013234353Sdim SmallVector<StringRef, 4> CandidateLibDirs, CandidateMultiarchLibDirs; 1014234353Sdim // The compatible GCC triples for this particular architecture. 1015234353Sdim SmallVector<StringRef, 10> CandidateTripleAliases; 1016234353Sdim SmallVector<StringRef, 10> CandidateMultiarchTripleAliases; 1017234353Sdim CollectLibDirsAndTriples(TargetTriple, MultiarchTriple, CandidateLibDirs, 1018234353Sdim CandidateTripleAliases, 1019234353Sdim CandidateMultiarchLibDirs, 1020234353Sdim CandidateMultiarchTripleAliases); 1021234353Sdim 1022234353Sdim // Compute the set of prefixes for our search. 1023234353Sdim SmallVector<std::string, 8> Prefixes(D.PrefixDirs.begin(), 1024234353Sdim D.PrefixDirs.end()); 1025234353Sdim 1026234353Sdim StringRef GCCToolchainDir = getGCCToolchainDir(Args); 1027234353Sdim if (GCCToolchainDir != "") { 1028234353Sdim if (GCCToolchainDir.back() == '/') 1029234353Sdim GCCToolchainDir = GCCToolchainDir.drop_back(); // remove the / 1030234353Sdim 1031234353Sdim Prefixes.push_back(GCCToolchainDir); 1032234353Sdim } else { 1033234353Sdim Prefixes.push_back(D.SysRoot); 1034234353Sdim Prefixes.push_back(D.SysRoot + "/usr"); 1035234353Sdim Prefixes.push_back(D.InstalledDir + "/.."); 1036234353Sdim } 1037234353Sdim 1038234353Sdim // Loop over the various components which exist and select the best GCC 1039234353Sdim // installation available. GCC installs are ranked by version number. 1040234353Sdim Version = GCCVersion::Parse("0.0.0"); 1041234353Sdim for (unsigned i = 0, ie = Prefixes.size(); i < ie; ++i) { 1042234353Sdim if (!llvm::sys::fs::exists(Prefixes[i])) 1043234353Sdim continue; 1044234353Sdim for (unsigned j = 0, je = CandidateLibDirs.size(); j < je; ++j) { 1045234353Sdim const std::string LibDir = Prefixes[i] + CandidateLibDirs[j].str(); 1046234353Sdim if (!llvm::sys::fs::exists(LibDir)) 1047234353Sdim continue; 1048234353Sdim for (unsigned k = 0, ke = CandidateTripleAliases.size(); k < ke; ++k) 1049243830Sdim ScanLibDirForGCCTriple(TargetArch, Args, LibDir, 1050243830Sdim CandidateTripleAliases[k]); 1051234353Sdim } 1052234353Sdim for (unsigned j = 0, je = CandidateMultiarchLibDirs.size(); j < je; ++j) { 1053234353Sdim const std::string LibDir 1054234353Sdim = Prefixes[i] + CandidateMultiarchLibDirs[j].str(); 1055234353Sdim if (!llvm::sys::fs::exists(LibDir)) 1056234353Sdim continue; 1057234353Sdim for (unsigned k = 0, ke = CandidateMultiarchTripleAliases.size(); k < ke; 1058234353Sdim ++k) 1059243830Sdim ScanLibDirForGCCTriple(TargetArch, Args, LibDir, 1060234353Sdim CandidateMultiarchTripleAliases[k], 1061234353Sdim /*NeedsMultiarchSuffix=*/true); 1062234353Sdim } 1063234353Sdim } 1064234353Sdim} 1065234353Sdim 1066234353Sdim/*static*/ void Generic_GCC::GCCInstallationDetector::CollectLibDirsAndTriples( 1067234353Sdim const llvm::Triple &TargetTriple, 1068234353Sdim const llvm::Triple &MultiarchTriple, 1069234353Sdim SmallVectorImpl<StringRef> &LibDirs, 1070234353Sdim SmallVectorImpl<StringRef> &TripleAliases, 1071234353Sdim SmallVectorImpl<StringRef> &MultiarchLibDirs, 1072234353Sdim SmallVectorImpl<StringRef> &MultiarchTripleAliases) { 1073234353Sdim // Declare a bunch of static data sets that we'll select between below. These 1074234353Sdim // are specifically designed to always refer to string literals to avoid any 1075234353Sdim // lifetime or initialization issues. 1076249423Sdim static const char *const AArch64LibDirs[] = { "/lib" }; 1077249423Sdim static const char *const AArch64Triples[] = { 1078249423Sdim "aarch64-none-linux-gnu", 1079249423Sdim "aarch64-linux-gnu" 1080249423Sdim }; 1081249423Sdim 1082234353Sdim static const char *const ARMLibDirs[] = { "/lib" }; 1083234353Sdim static const char *const ARMTriples[] = { 1084234353Sdim "arm-linux-gnueabi", 1085234353Sdim "arm-linux-androideabi" 1086234353Sdim }; 1087239462Sdim static const char *const ARMHFTriples[] = { 1088239462Sdim "arm-linux-gnueabihf", 1089251662Sdim "armv7hl-redhat-linux-gnueabi" 1090239462Sdim }; 1091234353Sdim 1092234353Sdim static const char *const X86_64LibDirs[] = { "/lib64", "/lib" }; 1093234353Sdim static const char *const X86_64Triples[] = { 1094234353Sdim "x86_64-linux-gnu", 1095234353Sdim "x86_64-unknown-linux-gnu", 1096234353Sdim "x86_64-pc-linux-gnu", 1097234353Sdim "x86_64-redhat-linux6E", 1098234353Sdim "x86_64-redhat-linux", 1099234353Sdim "x86_64-suse-linux", 1100234353Sdim "x86_64-manbo-linux-gnu", 1101234353Sdim "x86_64-linux-gnu", 1102234353Sdim "x86_64-slackware-linux" 1103234353Sdim }; 1104234353Sdim static const char *const X86LibDirs[] = { "/lib32", "/lib" }; 1105234353Sdim static const char *const X86Triples[] = { 1106234353Sdim "i686-linux-gnu", 1107234353Sdim "i686-pc-linux-gnu", 1108234353Sdim "i486-linux-gnu", 1109234353Sdim "i386-linux-gnu", 1110249423Sdim "i386-redhat-linux6E", 1111234353Sdim "i686-redhat-linux", 1112234353Sdim "i586-redhat-linux", 1113234353Sdim "i386-redhat-linux", 1114234353Sdim "i586-suse-linux", 1115239462Sdim "i486-slackware-linux", 1116239462Sdim "i686-montavista-linux" 1117234353Sdim }; 1118234353Sdim 1119234353Sdim static const char *const MIPSLibDirs[] = { "/lib" }; 1120234353Sdim static const char *const MIPSTriples[] = { "mips-linux-gnu" }; 1121234353Sdim static const char *const MIPSELLibDirs[] = { "/lib" }; 1122243830Sdim static const char *const MIPSELTriples[] = { 1123243830Sdim "mipsel-linux-gnu", 1124251662Sdim "mipsel-linux-android", 1125251662Sdim "mips-linux-gnu" 1126243830Sdim }; 1127234353Sdim 1128239462Sdim static const char *const MIPS64LibDirs[] = { "/lib64", "/lib" }; 1129239462Sdim static const char *const MIPS64Triples[] = { "mips64-linux-gnu" }; 1130239462Sdim static const char *const MIPS64ELLibDirs[] = { "/lib64", "/lib" }; 1131239462Sdim static const char *const MIPS64ELTriples[] = { "mips64el-linux-gnu" }; 1132239462Sdim 1133234353Sdim static const char *const PPCLibDirs[] = { "/lib32", "/lib" }; 1134234353Sdim static const char *const PPCTriples[] = { 1135234353Sdim "powerpc-linux-gnu", 1136234353Sdim "powerpc-unknown-linux-gnu", 1137249423Sdim "powerpc-linux-gnuspe", 1138239462Sdim "powerpc-suse-linux", 1139239462Sdim "powerpc-montavista-linuxspe" 1140234353Sdim }; 1141234353Sdim static const char *const PPC64LibDirs[] = { "/lib64", "/lib" }; 1142234353Sdim static const char *const PPC64Triples[] = { 1143234353Sdim "powerpc64-linux-gnu", 1144234353Sdim "powerpc64-unknown-linux-gnu", 1145234353Sdim "powerpc64-suse-linux", 1146234353Sdim "ppc64-redhat-linux" 1147234353Sdim }; 1148234353Sdim 1149251662Sdim static const char *const SystemZLibDirs[] = { "/lib64", "/lib" }; 1150251662Sdim static const char *const SystemZTriples[] = { 1151251662Sdim "s390x-linux-gnu", 1152251662Sdim "s390x-unknown-linux-gnu", 1153251662Sdim "s390x-ibm-linux-gnu", 1154251662Sdim "s390x-suse-linux", 1155251662Sdim "s390x-redhat-linux" 1156251662Sdim }; 1157251662Sdim 1158234353Sdim switch (TargetTriple.getArch()) { 1159249423Sdim case llvm::Triple::aarch64: 1160249423Sdim LibDirs.append(AArch64LibDirs, AArch64LibDirs 1161249423Sdim + llvm::array_lengthof(AArch64LibDirs)); 1162249423Sdim TripleAliases.append( 1163249423Sdim AArch64Triples, AArch64Triples + llvm::array_lengthof(AArch64Triples)); 1164249423Sdim MultiarchLibDirs.append( 1165249423Sdim AArch64LibDirs, AArch64LibDirs + llvm::array_lengthof(AArch64LibDirs)); 1166249423Sdim MultiarchTripleAliases.append( 1167249423Sdim AArch64Triples, AArch64Triples + llvm::array_lengthof(AArch64Triples)); 1168249423Sdim break; 1169234353Sdim case llvm::Triple::arm: 1170234353Sdim case llvm::Triple::thumb: 1171234353Sdim LibDirs.append(ARMLibDirs, ARMLibDirs + llvm::array_lengthof(ARMLibDirs)); 1172239462Sdim if (TargetTriple.getEnvironment() == llvm::Triple::GNUEABIHF) { 1173239462Sdim TripleAliases.append( 1174239462Sdim ARMHFTriples, ARMHFTriples + llvm::array_lengthof(ARMHFTriples)); 1175239462Sdim } else { 1176239462Sdim TripleAliases.append( 1177239462Sdim ARMTriples, ARMTriples + llvm::array_lengthof(ARMTriples)); 1178239462Sdim } 1179234353Sdim break; 1180234353Sdim case llvm::Triple::x86_64: 1181234353Sdim LibDirs.append( 1182234353Sdim X86_64LibDirs, X86_64LibDirs + llvm::array_lengthof(X86_64LibDirs)); 1183234353Sdim TripleAliases.append( 1184234353Sdim X86_64Triples, X86_64Triples + llvm::array_lengthof(X86_64Triples)); 1185234353Sdim MultiarchLibDirs.append( 1186234353Sdim X86LibDirs, X86LibDirs + llvm::array_lengthof(X86LibDirs)); 1187234353Sdim MultiarchTripleAliases.append( 1188234353Sdim X86Triples, X86Triples + llvm::array_lengthof(X86Triples)); 1189234353Sdim break; 1190234353Sdim case llvm::Triple::x86: 1191234353Sdim LibDirs.append(X86LibDirs, X86LibDirs + llvm::array_lengthof(X86LibDirs)); 1192234353Sdim TripleAliases.append( 1193234353Sdim X86Triples, X86Triples + llvm::array_lengthof(X86Triples)); 1194234353Sdim MultiarchLibDirs.append( 1195234353Sdim X86_64LibDirs, X86_64LibDirs + llvm::array_lengthof(X86_64LibDirs)); 1196234353Sdim MultiarchTripleAliases.append( 1197234353Sdim X86_64Triples, X86_64Triples + llvm::array_lengthof(X86_64Triples)); 1198234353Sdim break; 1199234353Sdim case llvm::Triple::mips: 1200234353Sdim LibDirs.append( 1201234353Sdim MIPSLibDirs, MIPSLibDirs + llvm::array_lengthof(MIPSLibDirs)); 1202234353Sdim TripleAliases.append( 1203234353Sdim MIPSTriples, MIPSTriples + llvm::array_lengthof(MIPSTriples)); 1204239462Sdim MultiarchLibDirs.append( 1205239462Sdim MIPS64LibDirs, MIPS64LibDirs + llvm::array_lengthof(MIPS64LibDirs)); 1206239462Sdim MultiarchTripleAliases.append( 1207239462Sdim MIPS64Triples, MIPS64Triples + llvm::array_lengthof(MIPS64Triples)); 1208234353Sdim break; 1209234353Sdim case llvm::Triple::mipsel: 1210234353Sdim LibDirs.append( 1211234353Sdim MIPSELLibDirs, MIPSELLibDirs + llvm::array_lengthof(MIPSELLibDirs)); 1212234353Sdim TripleAliases.append( 1213234353Sdim MIPSELTriples, MIPSELTriples + llvm::array_lengthof(MIPSELTriples)); 1214239462Sdim MultiarchLibDirs.append( 1215239462Sdim MIPS64ELLibDirs, MIPS64ELLibDirs + llvm::array_lengthof(MIPS64ELLibDirs)); 1216239462Sdim MultiarchTripleAliases.append( 1217239462Sdim MIPS64ELTriples, MIPS64ELTriples + llvm::array_lengthof(MIPS64ELTriples)); 1218234353Sdim break; 1219239462Sdim case llvm::Triple::mips64: 1220239462Sdim LibDirs.append( 1221239462Sdim MIPS64LibDirs, MIPS64LibDirs + llvm::array_lengthof(MIPS64LibDirs)); 1222239462Sdim TripleAliases.append( 1223239462Sdim MIPS64Triples, MIPS64Triples + llvm::array_lengthof(MIPS64Triples)); 1224239462Sdim MultiarchLibDirs.append( 1225239462Sdim MIPSLibDirs, MIPSLibDirs + llvm::array_lengthof(MIPSLibDirs)); 1226239462Sdim MultiarchTripleAliases.append( 1227239462Sdim MIPSTriples, MIPSTriples + llvm::array_lengthof(MIPSTriples)); 1228239462Sdim break; 1229239462Sdim case llvm::Triple::mips64el: 1230239462Sdim LibDirs.append( 1231239462Sdim MIPS64ELLibDirs, MIPS64ELLibDirs + llvm::array_lengthof(MIPS64ELLibDirs)); 1232239462Sdim TripleAliases.append( 1233239462Sdim MIPS64ELTriples, MIPS64ELTriples + llvm::array_lengthof(MIPS64ELTriples)); 1234239462Sdim MultiarchLibDirs.append( 1235239462Sdim MIPSELLibDirs, MIPSELLibDirs + llvm::array_lengthof(MIPSELLibDirs)); 1236239462Sdim MultiarchTripleAliases.append( 1237239462Sdim MIPSELTriples, MIPSELTriples + llvm::array_lengthof(MIPSELTriples)); 1238239462Sdim break; 1239234353Sdim case llvm::Triple::ppc: 1240234353Sdim LibDirs.append(PPCLibDirs, PPCLibDirs + llvm::array_lengthof(PPCLibDirs)); 1241234353Sdim TripleAliases.append( 1242234353Sdim PPCTriples, PPCTriples + llvm::array_lengthof(PPCTriples)); 1243234353Sdim MultiarchLibDirs.append( 1244234353Sdim PPC64LibDirs, PPC64LibDirs + llvm::array_lengthof(PPC64LibDirs)); 1245234353Sdim MultiarchTripleAliases.append( 1246234353Sdim PPC64Triples, PPC64Triples + llvm::array_lengthof(PPC64Triples)); 1247234353Sdim break; 1248234353Sdim case llvm::Triple::ppc64: 1249234353Sdim LibDirs.append( 1250234353Sdim PPC64LibDirs, PPC64LibDirs + llvm::array_lengthof(PPC64LibDirs)); 1251234353Sdim TripleAliases.append( 1252234353Sdim PPC64Triples, PPC64Triples + llvm::array_lengthof(PPC64Triples)); 1253234353Sdim MultiarchLibDirs.append( 1254234353Sdim PPCLibDirs, PPCLibDirs + llvm::array_lengthof(PPCLibDirs)); 1255234353Sdim MultiarchTripleAliases.append( 1256234353Sdim PPCTriples, PPCTriples + llvm::array_lengthof(PPCTriples)); 1257234353Sdim break; 1258251662Sdim case llvm::Triple::systemz: 1259251662Sdim LibDirs.append( 1260251662Sdim SystemZLibDirs, SystemZLibDirs + llvm::array_lengthof(SystemZLibDirs)); 1261251662Sdim TripleAliases.append( 1262251662Sdim SystemZTriples, SystemZTriples + llvm::array_lengthof(SystemZTriples)); 1263251662Sdim break; 1264234353Sdim 1265234353Sdim default: 1266234353Sdim // By default, just rely on the standard lib directories and the original 1267234353Sdim // triple. 1268234353Sdim break; 1269234353Sdim } 1270234353Sdim 1271234353Sdim // Always append the drivers target triple to the end, in case it doesn't 1272234353Sdim // match any of our aliases. 1273234353Sdim TripleAliases.push_back(TargetTriple.str()); 1274234353Sdim 1275234353Sdim // Also include the multiarch variant if it's different. 1276234353Sdim if (TargetTriple.str() != MultiarchTriple.str()) 1277234353Sdim MultiarchTripleAliases.push_back(MultiarchTriple.str()); 1278234353Sdim} 1279234353Sdim 1280251662Sdimstatic bool isSoftFloatABI(const ArgList &Args) { 1281251662Sdim Arg *A = Args.getLastArg(options::OPT_msoft_float, 1282251662Sdim options::OPT_mhard_float, 1283251662Sdim options::OPT_mfloat_abi_EQ); 1284251662Sdim if (!A) return false; 1285251662Sdim 1286251662Sdim return A->getOption().matches(options::OPT_msoft_float) || 1287251662Sdim (A->getOption().matches(options::OPT_mfloat_abi_EQ) && 1288251662Sdim A->getValue() == StringRef("soft")); 1289251662Sdim} 1290251662Sdim 1291251662Sdimstatic bool isMipsArch(llvm::Triple::ArchType Arch) { 1292251662Sdim return Arch == llvm::Triple::mips || 1293251662Sdim Arch == llvm::Triple::mipsel || 1294251662Sdim Arch == llvm::Triple::mips64 || 1295251662Sdim Arch == llvm::Triple::mips64el; 1296251662Sdim} 1297251662Sdim 1298251662Sdimstatic bool isMips16(const ArgList &Args) { 1299251662Sdim Arg *A = Args.getLastArg(options::OPT_mips16, 1300251662Sdim options::OPT_mno_mips16); 1301251662Sdim return A && A->getOption().matches(options::OPT_mips16); 1302251662Sdim} 1303251662Sdim 1304251662Sdimstatic bool isMicroMips(const ArgList &Args) { 1305251662Sdim Arg *A = Args.getLastArg(options::OPT_mmicromips, 1306251662Sdim options::OPT_mno_micromips); 1307251662Sdim return A && A->getOption().matches(options::OPT_mmicromips); 1308251662Sdim} 1309251662Sdim 1310243830Sdim// FIXME: There is the same routine in the Tools.cpp. 1311243830Sdimstatic bool hasMipsN32ABIArg(const ArgList &Args) { 1312243830Sdim Arg *A = Args.getLastArg(options::OPT_mabi_EQ); 1313243830Sdim return A && (A->getValue() == StringRef("n32")); 1314243830Sdim} 1315243830Sdim 1316251662Sdimstatic void appendMipsTargetSuffix(std::string &Path, 1317251662Sdim llvm::Triple::ArchType TargetArch, 1318251662Sdim const ArgList &Args) { 1319251662Sdim if (isMips16(Args)) 1320251662Sdim Path += "/mips16"; 1321251662Sdim else if (isMicroMips(Args)) 1322251662Sdim Path += "/micromips"; 1323243830Sdim 1324251662Sdim if (isSoftFloatABI(Args)) 1325251662Sdim Path += "/soft-float"; 1326251662Sdim 1327251662Sdim if (TargetArch == llvm::Triple::mipsel || 1328251662Sdim TargetArch == llvm::Triple::mips64el) 1329251662Sdim Path += "/el"; 1330251662Sdim} 1331251662Sdim 1332251662Sdimstatic StringRef getMipsTargetABISuffix(llvm::Triple::ArchType TargetArch, 1333251662Sdim const ArgList &Args) { 1334243830Sdim if (TargetArch == llvm::Triple::mips64 || 1335251662Sdim TargetArch == llvm::Triple::mips64el) 1336251662Sdim return hasMipsN32ABIArg(Args) ? "/n32" : "/64"; 1337243830Sdim 1338243830Sdim return "/32"; 1339243830Sdim} 1340243830Sdim 1341251662Sdimstatic bool findTargetMultiarchSuffix(std::string &Suffix, 1342251662Sdim StringRef Path, 1343251662Sdim llvm::Triple::ArchType TargetArch, 1344251662Sdim const ArgList &Args) { 1345251662Sdim if (isMipsArch(TargetArch)) { 1346251662Sdim StringRef ABISuffix = getMipsTargetABISuffix(TargetArch, Args); 1347251662Sdim 1348251662Sdim // First build and check a complex path to crtbegin.o 1349251662Sdim // depends on command line options (-mips16, -msoft-float, ...) 1350251662Sdim // like mips-linux-gnu/4.7/mips16/soft-float/el/crtbegin.o 1351251662Sdim appendMipsTargetSuffix(Suffix, TargetArch, Args); 1352251662Sdim 1353251662Sdim if (TargetArch == llvm::Triple::mips64 || 1354251662Sdim TargetArch == llvm::Triple::mips64el) 1355251662Sdim Suffix += ABISuffix; 1356251662Sdim 1357251662Sdim if (llvm::sys::fs::exists(Path + Suffix + "/crtbegin.o")) 1358251662Sdim return true; 1359251662Sdim 1360251662Sdim // Then fall back and probe a simple case like 1361251662Sdim // mips-linux-gnu/4.7/32/crtbegin.o 1362251662Sdim Suffix = ABISuffix; 1363251662Sdim return llvm::sys::fs::exists(Path + Suffix + "/crtbegin.o"); 1364251662Sdim } 1365251662Sdim 1366251662Sdim if (TargetArch == llvm::Triple::x86_64 || 1367251662Sdim TargetArch == llvm::Triple::ppc64 || 1368251662Sdim TargetArch == llvm::Triple::systemz) 1369251662Sdim Suffix = "/64"; 1370251662Sdim else 1371251662Sdim Suffix = "/32"; 1372251662Sdim 1373251662Sdim return llvm::sys::fs::exists(Path + Suffix + "/crtbegin.o"); 1374251662Sdim} 1375251662Sdim 1376234353Sdimvoid Generic_GCC::GCCInstallationDetector::ScanLibDirForGCCTriple( 1377243830Sdim llvm::Triple::ArchType TargetArch, const ArgList &Args, 1378243830Sdim const std::string &LibDir, 1379234353Sdim StringRef CandidateTriple, bool NeedsMultiarchSuffix) { 1380234353Sdim // There are various different suffixes involving the triple we 1381234353Sdim // check for. We also record what is necessary to walk from each back 1382234353Sdim // up to the lib directory. 1383234353Sdim const std::string LibSuffixes[] = { 1384234353Sdim "/gcc/" + CandidateTriple.str(), 1385234353Sdim "/" + CandidateTriple.str() + "/gcc/" + CandidateTriple.str(), 1386234353Sdim 1387243830Sdim // The Freescale PPC SDK has the gcc libraries in 1388243830Sdim // <sysroot>/usr/lib/<triple>/x.y.z so have a look there as well. 1389243830Sdim "/" + CandidateTriple.str(), 1390243830Sdim 1391234353Sdim // Ubuntu has a strange mis-matched pair of triples that this happens to 1392234353Sdim // match. 1393234353Sdim // FIXME: It may be worthwhile to generalize this and look for a second 1394234353Sdim // triple. 1395234353Sdim "/i386-linux-gnu/gcc/" + CandidateTriple.str() 1396234353Sdim }; 1397234353Sdim const std::string InstallSuffixes[] = { 1398234353Sdim "/../../..", 1399234353Sdim "/../../../..", 1400243830Sdim "/../..", 1401234353Sdim "/../../../.." 1402234353Sdim }; 1403234353Sdim // Only look at the final, weird Ubuntu suffix for i386-linux-gnu. 1404234353Sdim const unsigned NumLibSuffixes = (llvm::array_lengthof(LibSuffixes) - 1405234353Sdim (TargetArch != llvm::Triple::x86)); 1406234353Sdim for (unsigned i = 0; i < NumLibSuffixes; ++i) { 1407234353Sdim StringRef LibSuffix = LibSuffixes[i]; 1408234353Sdim llvm::error_code EC; 1409234353Sdim for (llvm::sys::fs::directory_iterator LI(LibDir + LibSuffix, EC), LE; 1410234353Sdim !EC && LI != LE; LI = LI.increment(EC)) { 1411234353Sdim StringRef VersionText = llvm::sys::path::filename(LI->path()); 1412234353Sdim GCCVersion CandidateVersion = GCCVersion::Parse(VersionText); 1413234353Sdim static const GCCVersion MinVersion = { "4.1.1", 4, 1, 1, "" }; 1414234353Sdim if (CandidateVersion < MinVersion) 1415234353Sdim continue; 1416234353Sdim if (CandidateVersion <= Version) 1417234353Sdim continue; 1418234353Sdim 1419234353Sdim // Some versions of SUSE and Fedora on ppc64 put 32-bit libs 1420234353Sdim // in what would normally be GCCInstallPath and put the 64-bit 1421234353Sdim // libs in a subdirectory named 64. The simple logic we follow is that 1422234353Sdim // *if* there is a subdirectory of the right name with crtbegin.o in it, 1423234353Sdim // we use that. If not, and if not a multiarch triple, we look for 1424234353Sdim // crtbegin.o without the subdirectory. 1425251662Sdim 1426251662Sdim std::string MultiarchSuffix; 1427251662Sdim if (findTargetMultiarchSuffix(MultiarchSuffix, 1428251662Sdim LI->path(), TargetArch, Args)) { 1429251662Sdim GCCMultiarchSuffix = MultiarchSuffix; 1430234353Sdim } else { 1431234353Sdim if (NeedsMultiarchSuffix || 1432234353Sdim !llvm::sys::fs::exists(LI->path() + "/crtbegin.o")) 1433234353Sdim continue; 1434234353Sdim GCCMultiarchSuffix.clear(); 1435234353Sdim } 1436234353Sdim 1437234353Sdim Version = CandidateVersion; 1438234353Sdim GCCTriple.setTriple(CandidateTriple); 1439234353Sdim // FIXME: We hack together the directory name here instead of 1440234353Sdim // using LI to ensure stable path separators across Windows and 1441234353Sdim // Linux. 1442234353Sdim GCCInstallPath = LibDir + LibSuffixes[i] + "/" + VersionText.str(); 1443234353Sdim GCCParentLibPath = GCCInstallPath + InstallSuffixes[i]; 1444234353Sdim IsValid = true; 1445234353Sdim } 1446234353Sdim } 1447234353Sdim} 1448234353Sdim 1449234353SdimGeneric_GCC::Generic_GCC(const Driver &D, const llvm::Triple& Triple, 1450234353Sdim const ArgList &Args) 1451249423Sdim : ToolChain(D, Triple, Args), GCCInstallation(getDriver(), Triple, Args) { 1452212904Sdim getProgramPaths().push_back(getDriver().getInstalledDir()); 1453221345Sdim if (getDriver().getInstalledDir() != getDriver().Dir) 1454212904Sdim getProgramPaths().push_back(getDriver().Dir); 1455193326Sed} 1456193326Sed 1457193326SedGeneric_GCC::~Generic_GCC() { 1458193326Sed} 1459193326Sed 1460249423SdimTool *Generic_GCC::getTool(Action::ActionClass AC) const { 1461249423Sdim switch (AC) { 1462249423Sdim case Action::PreprocessJobClass: 1463249423Sdim if (!Preprocess) 1464249423Sdim Preprocess.reset(new tools::gcc::Preprocess(*this)); 1465249423Sdim return Preprocess.get(); 1466249423Sdim case Action::PrecompileJobClass: 1467249423Sdim if (!Precompile) 1468249423Sdim Precompile.reset(new tools::gcc::Precompile(*this)); 1469249423Sdim return Precompile.get(); 1470249423Sdim case Action::CompileJobClass: 1471249423Sdim if (!Compile) 1472249423Sdim Compile.reset(new tools::gcc::Compile(*this)); 1473249423Sdim return Compile.get(); 1474249423Sdim default: 1475249423Sdim return ToolChain::getTool(AC); 1476193326Sed } 1477249423Sdim} 1478193326Sed 1479249423SdimTool *Generic_GCC::buildAssembler() const { 1480249423Sdim return new tools::gcc::Assemble(*this); 1481193326Sed} 1482193326Sed 1483249423SdimTool *Generic_GCC::buildLinker() const { 1484249423Sdim return new tools::gcc::Link(*this); 1485249423Sdim} 1486249423Sdim 1487193326Sedbool Generic_GCC::IsUnwindTablesDefault() const { 1488243830Sdim return getArch() == llvm::Triple::x86_64; 1489193326Sed} 1490193326Sed 1491243830Sdimbool Generic_GCC::isPICDefault() const { 1492243830Sdim return false; 1493193326Sed} 1494193326Sed 1495251662Sdimbool Generic_GCC::isPIEDefault() const { 1496251662Sdim return false; 1497251662Sdim} 1498251662Sdim 1499243830Sdimbool Generic_GCC::isPICDefaultForced() const { 1500243830Sdim return false; 1501193326Sed} 1502243830Sdim 1503234353Sdim/// Hexagon Toolchain 1504193326Sed 1505249423Sdimstd::string Hexagon_TC::GetGnuDir(const std::string &InstalledDir) { 1506249423Sdim 1507249423Sdim // Locate the rest of the toolchain ... 1508249423Sdim if (strlen(GCC_INSTALL_PREFIX)) 1509249423Sdim return std::string(GCC_INSTALL_PREFIX); 1510249423Sdim 1511249423Sdim std::string InstallRelDir = InstalledDir + "/../../gnu"; 1512249423Sdim if (llvm::sys::fs::exists(InstallRelDir)) 1513249423Sdim return InstallRelDir; 1514249423Sdim 1515249423Sdim std::string PrefixRelDir = std::string(LLVM_PREFIX) + "/../gnu"; 1516249423Sdim if (llvm::sys::fs::exists(PrefixRelDir)) 1517249423Sdim return PrefixRelDir; 1518249423Sdim 1519249423Sdim return InstallRelDir; 1520234353Sdim} 1521234353Sdim 1522249423Sdimstatic void GetHexagonLibraryPaths( 1523249423Sdim const ArgList &Args, 1524249423Sdim const std::string Ver, 1525249423Sdim const std::string MarchString, 1526249423Sdim const std::string &InstalledDir, 1527249423Sdim ToolChain::path_list *LibPaths) 1528249423Sdim{ 1529249423Sdim bool buildingLib = Args.hasArg(options::OPT_shared); 1530249423Sdim 1531249423Sdim //---------------------------------------------------------------------------- 1532249423Sdim // -L Args 1533249423Sdim //---------------------------------------------------------------------------- 1534249423Sdim for (arg_iterator 1535249423Sdim it = Args.filtered_begin(options::OPT_L), 1536249423Sdim ie = Args.filtered_end(); 1537249423Sdim it != ie; 1538249423Sdim ++it) { 1539249423Sdim for (unsigned i = 0, e = (*it)->getNumValues(); i != e; ++i) 1540249423Sdim LibPaths->push_back((*it)->getValue(i)); 1541249423Sdim } 1542249423Sdim 1543249423Sdim //---------------------------------------------------------------------------- 1544249423Sdim // Other standard paths 1545249423Sdim //---------------------------------------------------------------------------- 1546249423Sdim const std::string MarchSuffix = "/" + MarchString; 1547249423Sdim const std::string G0Suffix = "/G0"; 1548249423Sdim const std::string MarchG0Suffix = MarchSuffix + G0Suffix; 1549249423Sdim const std::string RootDir = Hexagon_TC::GetGnuDir(InstalledDir) + "/"; 1550249423Sdim 1551249423Sdim // lib/gcc/hexagon/... 1552249423Sdim std::string LibGCCHexagonDir = RootDir + "lib/gcc/hexagon/"; 1553249423Sdim if (buildingLib) { 1554249423Sdim LibPaths->push_back(LibGCCHexagonDir + Ver + MarchG0Suffix); 1555249423Sdim LibPaths->push_back(LibGCCHexagonDir + Ver + G0Suffix); 1556249423Sdim } 1557249423Sdim LibPaths->push_back(LibGCCHexagonDir + Ver + MarchSuffix); 1558249423Sdim LibPaths->push_back(LibGCCHexagonDir + Ver); 1559249423Sdim 1560249423Sdim // lib/gcc/... 1561249423Sdim LibPaths->push_back(RootDir + "lib/gcc"); 1562249423Sdim 1563249423Sdim // hexagon/lib/... 1564249423Sdim std::string HexagonLibDir = RootDir + "hexagon/lib"; 1565249423Sdim if (buildingLib) { 1566249423Sdim LibPaths->push_back(HexagonLibDir + MarchG0Suffix); 1567249423Sdim LibPaths->push_back(HexagonLibDir + G0Suffix); 1568249423Sdim } 1569249423Sdim LibPaths->push_back(HexagonLibDir + MarchSuffix); 1570249423Sdim LibPaths->push_back(HexagonLibDir); 1571249423Sdim} 1572249423Sdim 1573249423SdimHexagon_TC::Hexagon_TC(const Driver &D, const llvm::Triple &Triple, 1574249423Sdim const ArgList &Args) 1575249423Sdim : Linux(D, Triple, Args) { 1576249423Sdim const std::string InstalledDir(getDriver().getInstalledDir()); 1577249423Sdim const std::string GnuDir = Hexagon_TC::GetGnuDir(InstalledDir); 1578249423Sdim 1579249423Sdim // Note: Generic_GCC::Generic_GCC adds InstalledDir and getDriver().Dir to 1580249423Sdim // program paths 1581249423Sdim const std::string BinDir(GnuDir + "/bin"); 1582249423Sdim if (llvm::sys::fs::exists(BinDir)) 1583249423Sdim getProgramPaths().push_back(BinDir); 1584249423Sdim 1585249423Sdim // Determine version of GCC libraries and headers to use. 1586249423Sdim const std::string HexagonDir(GnuDir + "/lib/gcc/hexagon"); 1587249423Sdim llvm::error_code ec; 1588249423Sdim GCCVersion MaxVersion= GCCVersion::Parse("0.0.0"); 1589249423Sdim for (llvm::sys::fs::directory_iterator di(HexagonDir, ec), de; 1590249423Sdim !ec && di != de; di = di.increment(ec)) { 1591249423Sdim GCCVersion cv = GCCVersion::Parse(llvm::sys::path::filename(di->path())); 1592249423Sdim if (MaxVersion < cv) 1593249423Sdim MaxVersion = cv; 1594249423Sdim } 1595249423Sdim GCCLibAndIncVersion = MaxVersion; 1596249423Sdim 1597249423Sdim ToolChain::path_list *LibPaths= &getFilePaths(); 1598249423Sdim 1599249423Sdim // Remove paths added by Linux toolchain. Currently Hexagon_TC really targets 1600249423Sdim // 'elf' OS type, so the Linux paths are not appropriate. When we actually 1601249423Sdim // support 'linux' we'll need to fix this up 1602249423Sdim LibPaths->clear(); 1603249423Sdim 1604249423Sdim GetHexagonLibraryPaths( 1605249423Sdim Args, 1606249423Sdim GetGCCLibAndIncVersion(), 1607249423Sdim GetTargetCPU(Args), 1608249423Sdim InstalledDir, 1609249423Sdim LibPaths); 1610249423Sdim} 1611249423Sdim 1612234353SdimHexagon_TC::~Hexagon_TC() { 1613234353Sdim} 1614234353Sdim 1615249423SdimTool *Hexagon_TC::buildAssembler() const { 1616249423Sdim return new tools::hexagon::Assemble(*this); 1617249423Sdim} 1618234353Sdim 1619249423SdimTool *Hexagon_TC::buildLinker() const { 1620249423Sdim return new tools::hexagon::Link(*this); 1621249423Sdim} 1622234353Sdim 1623249423Sdimvoid Hexagon_TC::AddClangSystemIncludeArgs(const ArgList &DriverArgs, 1624249423Sdim ArgStringList &CC1Args) const { 1625249423Sdim const Driver &D = getDriver(); 1626249423Sdim 1627249423Sdim if (DriverArgs.hasArg(options::OPT_nostdinc) || 1628249423Sdim DriverArgs.hasArg(options::OPT_nostdlibinc)) 1629249423Sdim return; 1630249423Sdim 1631249423Sdim llvm::sys::Path InstallDir(D.InstalledDir); 1632249423Sdim std::string Ver(GetGCCLibAndIncVersion()); 1633249423Sdim std::string GnuDir = Hexagon_TC::GetGnuDir(D.InstalledDir); 1634249423Sdim std::string HexagonDir(GnuDir + "/lib/gcc/hexagon/" + Ver); 1635249423Sdim addExternCSystemInclude(DriverArgs, CC1Args, HexagonDir + "/include"); 1636249423Sdim addExternCSystemInclude(DriverArgs, CC1Args, HexagonDir + "/include-fixed"); 1637249423Sdim addExternCSystemInclude(DriverArgs, CC1Args, GnuDir + "/hexagon/include"); 1638249423Sdim} 1639249423Sdim 1640249423Sdimvoid Hexagon_TC::AddClangCXXStdlibIncludeArgs(const ArgList &DriverArgs, 1641249423Sdim ArgStringList &CC1Args) const { 1642249423Sdim 1643249423Sdim if (DriverArgs.hasArg(options::OPT_nostdlibinc) || 1644249423Sdim DriverArgs.hasArg(options::OPT_nostdincxx)) 1645249423Sdim return; 1646249423Sdim 1647249423Sdim const Driver &D = getDriver(); 1648249423Sdim std::string Ver(GetGCCLibAndIncVersion()); 1649249423Sdim llvm::sys::Path IncludeDir(Hexagon_TC::GetGnuDir(D.InstalledDir)); 1650249423Sdim 1651249423Sdim IncludeDir.appendComponent("hexagon/include/c++/"); 1652249423Sdim IncludeDir.appendComponent(Ver); 1653249423Sdim addSystemInclude(DriverArgs, CC1Args, IncludeDir.str()); 1654249423Sdim} 1655249423Sdim 1656249423SdimToolChain::CXXStdlibType 1657249423SdimHexagon_TC::GetCXXStdlibType(const ArgList &Args) const { 1658249423Sdim Arg *A = Args.getLastArg(options::OPT_stdlib_EQ); 1659249423Sdim if (!A) 1660249423Sdim return ToolChain::CST_Libstdcxx; 1661249423Sdim 1662249423Sdim StringRef Value = A->getValue(); 1663249423Sdim if (Value != "libstdc++") { 1664249423Sdim getDriver().Diag(diag::err_drv_invalid_stdlib_name) 1665249423Sdim << A->getAsString(Args); 1666234353Sdim } 1667234353Sdim 1668249423Sdim return ToolChain::CST_Libstdcxx; 1669234353Sdim} 1670234353Sdim 1671249423Sdimstatic Arg *GetLastHexagonArchArg(const ArgList &Args) 1672249423Sdim{ 1673249423Sdim Arg *A = NULL; 1674249423Sdim 1675249423Sdim for (ArgList::const_iterator it = Args.begin(), ie = Args.end(); 1676249423Sdim it != ie; ++it) { 1677249423Sdim if ((*it)->getOption().matches(options::OPT_march_EQ) || 1678249423Sdim (*it)->getOption().matches(options::OPT_mcpu_EQ)) { 1679249423Sdim A = *it; 1680249423Sdim A->claim(); 1681249423Sdim } else if ((*it)->getOption().matches(options::OPT_m_Joined)) { 1682249423Sdim StringRef Value = (*it)->getValue(0); 1683249423Sdim if (Value.startswith("v")) { 1684249423Sdim A = *it; 1685249423Sdim A->claim(); 1686249423Sdim } 1687249423Sdim } 1688249423Sdim } 1689249423Sdim return A; 1690234353Sdim} 1691234353Sdim 1692249423SdimStringRef Hexagon_TC::GetTargetCPU(const ArgList &Args) 1693249423Sdim{ 1694249423Sdim // Select the default CPU (v4) if none was given or detection failed. 1695249423Sdim Arg *A = GetLastHexagonArchArg (Args); 1696249423Sdim if (A) { 1697249423Sdim StringRef WhichHexagon = A->getValue(); 1698249423Sdim if (WhichHexagon.startswith("hexagon")) 1699249423Sdim return WhichHexagon.substr(sizeof("hexagon") - 1); 1700249423Sdim if (WhichHexagon != "") 1701249423Sdim return WhichHexagon; 1702249423Sdim } 1703249423Sdim 1704249423Sdim return "v4"; 1705234353Sdim} 1706249423Sdim// End Hexagon 1707234353Sdim 1708204793Srdivacky/// TCEToolChain - A tool chain using the llvm bitcode tools to perform 1709204793Srdivacky/// all subcommands. See http://tce.cs.tut.fi for our peculiar target. 1710204793Srdivacky/// Currently does not support anything else but compilation. 1711204793Srdivacky 1712249423SdimTCEToolChain::TCEToolChain(const Driver &D, const llvm::Triple& Triple, 1713249423Sdim const ArgList &Args) 1714249423Sdim : ToolChain(D, Triple, Args) { 1715204793Srdivacky // Path mangling to find libexec 1716204793Srdivacky std::string Path(getDriver().Dir); 1717204793Srdivacky 1718204793Srdivacky Path += "/../libexec"; 1719204793Srdivacky getProgramPaths().push_back(Path); 1720204793Srdivacky} 1721204793Srdivacky 1722204793SrdivackyTCEToolChain::~TCEToolChain() { 1723204793Srdivacky} 1724204793Srdivacky 1725223017Sdimbool TCEToolChain::IsMathErrnoDefault() const { 1726223017Sdim return true; 1727204793Srdivacky} 1728204793Srdivacky 1729243830Sdimbool TCEToolChain::isPICDefault() const { 1730204793Srdivacky return false; 1731204793Srdivacky} 1732204793Srdivacky 1733251662Sdimbool TCEToolChain::isPIEDefault() const { 1734251662Sdim return false; 1735251662Sdim} 1736251662Sdim 1737243830Sdimbool TCEToolChain::isPICDefaultForced() const { 1738243830Sdim return false; 1739204793Srdivacky} 1740204793Srdivacky 1741195341Sed/// OpenBSD - OpenBSD tool chain which can call as(1) and ld(1) directly. 1742195341Sed 1743234353SdimOpenBSD::OpenBSD(const Driver &D, const llvm::Triple& Triple, const ArgList &Args) 1744234353Sdim : Generic_ELF(D, Triple, Args) { 1745201361Srdivacky getFilePaths().push_back(getDriver().Dir + "/../lib"); 1746195341Sed getFilePaths().push_back("/usr/lib"); 1747195341Sed} 1748195341Sed 1749249423SdimTool *OpenBSD::buildAssembler() const { 1750249423Sdim return new tools::openbsd::Assemble(*this); 1751249423Sdim} 1752195341Sed 1753249423SdimTool *OpenBSD::buildLinker() const { 1754249423Sdim return new tools::openbsd::Link(*this); 1755195341Sed} 1756195341Sed 1757239462Sdim/// Bitrig - Bitrig tool chain which can call as(1) and ld(1) directly. 1758239462Sdim 1759239462SdimBitrig::Bitrig(const Driver &D, const llvm::Triple& Triple, const ArgList &Args) 1760239462Sdim : Generic_ELF(D, Triple, Args) { 1761239462Sdim getFilePaths().push_back(getDriver().Dir + "/../lib"); 1762239462Sdim getFilePaths().push_back("/usr/lib"); 1763239462Sdim} 1764239462Sdim 1765249423SdimTool *Bitrig::buildAssembler() const { 1766249423Sdim return new tools::bitrig::Assemble(*this); 1767249423Sdim} 1768239462Sdim 1769249423SdimTool *Bitrig::buildLinker() const { 1770249423Sdim return new tools::bitrig::Link(*this); 1771239462Sdim} 1772239462Sdim 1773239462Sdimvoid Bitrig::AddClangCXXStdlibIncludeArgs(const ArgList &DriverArgs, 1774239462Sdim ArgStringList &CC1Args) const { 1775239462Sdim if (DriverArgs.hasArg(options::OPT_nostdlibinc) || 1776239462Sdim DriverArgs.hasArg(options::OPT_nostdincxx)) 1777239462Sdim return; 1778239462Sdim 1779243830Sdim switch (GetCXXStdlibType(DriverArgs)) { 1780243830Sdim case ToolChain::CST_Libcxx: 1781243830Sdim addSystemInclude(DriverArgs, CC1Args, 1782243830Sdim getDriver().SysRoot + "/usr/include/c++/"); 1783243830Sdim break; 1784243830Sdim case ToolChain::CST_Libstdcxx: 1785243830Sdim addSystemInclude(DriverArgs, CC1Args, 1786243830Sdim getDriver().SysRoot + "/usr/include/c++/stdc++"); 1787243830Sdim addSystemInclude(DriverArgs, CC1Args, 1788243830Sdim getDriver().SysRoot + "/usr/include/c++/stdc++/backward"); 1789239462Sdim 1790243830Sdim StringRef Triple = getTriple().str(); 1791243830Sdim if (Triple.startswith("amd64")) 1792243830Sdim addSystemInclude(DriverArgs, CC1Args, 1793243830Sdim getDriver().SysRoot + "/usr/include/c++/stdc++/x86_64" + 1794243830Sdim Triple.substr(5)); 1795243830Sdim else 1796243830Sdim addSystemInclude(DriverArgs, CC1Args, 1797243830Sdim getDriver().SysRoot + "/usr/include/c++/stdc++/" + 1798243830Sdim Triple); 1799243830Sdim break; 1800243830Sdim } 1801239462Sdim} 1802239462Sdim 1803239462Sdimvoid Bitrig::AddCXXStdlibLibArgs(const ArgList &Args, 1804239462Sdim ArgStringList &CmdArgs) const { 1805243830Sdim switch (GetCXXStdlibType(Args)) { 1806243830Sdim case ToolChain::CST_Libcxx: 1807243830Sdim CmdArgs.push_back("-lc++"); 1808243830Sdim CmdArgs.push_back("-lcxxrt"); 1809243830Sdim // Include supc++ to provide Unwind until provided by libcxx. 1810243830Sdim CmdArgs.push_back("-lgcc"); 1811243830Sdim break; 1812243830Sdim case ToolChain::CST_Libstdcxx: 1813243830Sdim CmdArgs.push_back("-lstdc++"); 1814243830Sdim break; 1815243830Sdim } 1816239462Sdim} 1817239462Sdim 1818193326Sed/// FreeBSD - FreeBSD tool chain which can call as(1) and ld(1) directly. 1819193326Sed 1820234353SdimFreeBSD::FreeBSD(const Driver &D, const llvm::Triple& Triple, const ArgList &Args) 1821234353Sdim : Generic_ELF(D, Triple, Args) { 1822212904Sdim 1823234353Sdim // When targeting 32-bit platforms, look for '/usr/lib32/crt1.o' and fall 1824234353Sdim // back to '/usr/lib' if it doesn't exist. 1825234353Sdim if ((Triple.getArch() == llvm::Triple::x86 || 1826234353Sdim Triple.getArch() == llvm::Triple::ppc) && 1827234982Sdim llvm::sys::fs::exists(getDriver().SysRoot + "/usr/lib32/crt1.o")) 1828234982Sdim getFilePaths().push_back(getDriver().SysRoot + "/usr/lib32"); 1829234353Sdim else 1830234982Sdim getFilePaths().push_back(getDriver().SysRoot + "/usr/lib"); 1831193326Sed} 1832193326Sed 1833249423SdimTool *FreeBSD::buildAssembler() const { 1834249423Sdim return new tools::freebsd::Assemble(*this); 1835249423Sdim} 1836193326Sed 1837249423SdimTool *FreeBSD::buildLinker() const { 1838249423Sdim return new tools::freebsd::Link(*this); 1839193326Sed} 1840193326Sed 1841244640Sandrewbool FreeBSD::UseSjLjExceptions() const { 1842244640Sandrew // FreeBSD uses SjLj exceptions on ARM oabi. 1843244640Sandrew switch (getTriple().getEnvironment()) { 1844244640Sandrew case llvm::Triple::GNUEABI: 1845244640Sandrew case llvm::Triple::EABI: 1846244640Sandrew return false; 1847244640Sandrew 1848244640Sandrew default: 1849244640Sandrew return (getTriple().getArch() == llvm::Triple::arm || 1850244640Sandrew getTriple().getArch() == llvm::Triple::thumb); 1851244640Sandrew } 1852244640Sandrew} 1853244640Sandrew 1854255321StheravenToolChain::CXXStdlibType 1855255321StheravenFreeBSD::GetCXXStdlibType(const ArgList &Args) const { 1856255321Stheraven if (Arg *A = Args.getLastArg(options::OPT_stdlib_EQ)) { 1857255321Stheraven StringRef Value = A->getValue(); 1858255321Stheraven if (Value == "libc++") 1859255321Stheraven return ToolChain::CST_Libcxx; 1860255321Stheraven if (Value == "libstdc++") 1861255321Stheraven return ToolChain::CST_Libstdcxx; 1862255321Stheraven getDriver().Diag(diag::err_drv_invalid_stdlib_name) 1863255321Stheraven << A->getAsString(Args); 1864255321Stheraven } 1865255321Stheraven 1866255321Stheraven return getTriple().getOSMajorVersion() >= 10 ? ToolChain::CST_Libcxx : 1867255321Stheraven ToolChain::CST_Libstdcxx; 1868255321Stheraven} 1869255321Stheraven 1870255321Stheravenvoid FreeBSD::AddClangCXXStdlibIncludeArgs(const ArgList &DriverArgs, 1871255321Stheraven ArgStringList &CC1Args) const { 1872255321Stheraven if (DriverArgs.hasArg(options::OPT_nostdlibinc) || 1873255321Stheraven DriverArgs.hasArg(options::OPT_nostdincxx)) 1874255321Stheraven return; 1875255321Stheraven 1876255321Stheraven if (GetCXXStdlibType(DriverArgs) == ToolChain::CST_Libcxx) 1877255321Stheraven addSystemInclude(DriverArgs, CC1Args, 1878255321Stheraven getDriver().SysRoot + "/usr/include/c++/v1"); 1879255321Stheraven else 1880255321Stheraven addSystemInclude(DriverArgs, CC1Args, 1881255321Stheraven getDriver().SysRoot + "/usr/include/c++/4.2"); 1882255321Stheraven return; 1883255321Stheraven 1884255321Stheraven} 1885255321Stheraven 1886218893Sdim/// NetBSD - NetBSD tool chain which can call as(1) and ld(1) directly. 1887218893Sdim 1888234353SdimNetBSD::NetBSD(const Driver &D, const llvm::Triple& Triple, const ArgList &Args) 1889234353Sdim : Generic_ELF(D, Triple, Args) { 1890218893Sdim 1891221345Sdim if (getDriver().UseStdLib) { 1892234353Sdim // When targeting a 32-bit platform, try the special directory used on 1893234353Sdim // 64-bit hosts, and only fall back to the main library directory if that 1894234353Sdim // doesn't work. 1895234353Sdim // FIXME: It'd be nicer to test if this directory exists, but I'm not sure 1896234353Sdim // what all logic is needed to emulate the '=' prefix here. 1897234353Sdim if (Triple.getArch() == llvm::Triple::x86) 1898221345Sdim getFilePaths().push_back("=/usr/lib/i386"); 1899234353Sdim 1900234353Sdim getFilePaths().push_back("=/usr/lib"); 1901218893Sdim } 1902218893Sdim} 1903218893Sdim 1904249423SdimTool *NetBSD::buildAssembler() const { 1905249423Sdim return new tools::netbsd::Assemble(*this); 1906249423Sdim} 1907218893Sdim 1908249423SdimTool *NetBSD::buildLinker() const { 1909249423Sdim return new tools::netbsd::Link(*this); 1910218893Sdim} 1911218893Sdim 1912251662SdimToolChain::CXXStdlibType 1913251662SdimNetBSD::GetCXXStdlibType(const ArgList &Args) const { 1914251662Sdim if (Arg *A = Args.getLastArg(options::OPT_stdlib_EQ)) { 1915251662Sdim StringRef Value = A->getValue(); 1916251662Sdim if (Value == "libstdc++") 1917251662Sdim return ToolChain::CST_Libstdcxx; 1918251662Sdim if (Value == "libc++") 1919251662Sdim return ToolChain::CST_Libcxx; 1920251662Sdim 1921251662Sdim getDriver().Diag(diag::err_drv_invalid_stdlib_name) 1922251662Sdim << A->getAsString(Args); 1923251662Sdim } 1924251662Sdim 1925251662Sdim return ToolChain::CST_Libstdcxx; 1926251662Sdim} 1927251662Sdim 1928251662Sdimvoid NetBSD::AddClangCXXStdlibIncludeArgs(const ArgList &DriverArgs, 1929251662Sdim ArgStringList &CC1Args) const { 1930251662Sdim if (DriverArgs.hasArg(options::OPT_nostdlibinc) || 1931251662Sdim DriverArgs.hasArg(options::OPT_nostdincxx)) 1932251662Sdim return; 1933251662Sdim 1934251662Sdim switch (GetCXXStdlibType(DriverArgs)) { 1935251662Sdim case ToolChain::CST_Libcxx: 1936251662Sdim addSystemInclude(DriverArgs, CC1Args, 1937251662Sdim getDriver().SysRoot + "/usr/include/c++/"); 1938251662Sdim break; 1939251662Sdim case ToolChain::CST_Libstdcxx: 1940251662Sdim addSystemInclude(DriverArgs, CC1Args, 1941251662Sdim getDriver().SysRoot + "/usr/include/g++"); 1942251662Sdim addSystemInclude(DriverArgs, CC1Args, 1943251662Sdim getDriver().SysRoot + "/usr/include/g++/backward"); 1944251662Sdim break; 1945251662Sdim } 1946251662Sdim} 1947251662Sdim 1948210299Sed/// Minix - Minix tool chain which can call as(1) and ld(1) directly. 1949210299Sed 1950234353SdimMinix::Minix(const Driver &D, const llvm::Triple& Triple, const ArgList &Args) 1951234353Sdim : Generic_ELF(D, Triple, Args) { 1952210299Sed getFilePaths().push_back(getDriver().Dir + "/../lib"); 1953210299Sed getFilePaths().push_back("/usr/lib"); 1954210299Sed} 1955210299Sed 1956249423SdimTool *Minix::buildAssembler() const { 1957249423Sdim return new tools::minix::Assemble(*this); 1958249423Sdim} 1959210299Sed 1960249423SdimTool *Minix::buildLinker() const { 1961249423Sdim return new tools::minix::Link(*this); 1962210299Sed} 1963210299Sed 1964198092Srdivacky/// AuroraUX - AuroraUX tool chain which can call as(1) and ld(1) directly. 1965198092Srdivacky 1966234353SdimAuroraUX::AuroraUX(const Driver &D, const llvm::Triple& Triple, 1967234353Sdim const ArgList &Args) 1968234353Sdim : Generic_GCC(D, Triple, Args) { 1969198092Srdivacky 1970212904Sdim getProgramPaths().push_back(getDriver().getInstalledDir()); 1971221345Sdim if (getDriver().getInstalledDir() != getDriver().Dir) 1972212904Sdim getProgramPaths().push_back(getDriver().Dir); 1973198092Srdivacky 1974201361Srdivacky getFilePaths().push_back(getDriver().Dir + "/../lib"); 1975198092Srdivacky getFilePaths().push_back("/usr/lib"); 1976198092Srdivacky getFilePaths().push_back("/usr/sfw/lib"); 1977198092Srdivacky getFilePaths().push_back("/opt/gcc4/lib"); 1978198398Srdivacky getFilePaths().push_back("/opt/gcc4/lib/gcc/i386-pc-solaris2.11/4.2.4"); 1979198092Srdivacky 1980198092Srdivacky} 1981198092Srdivacky 1982249423SdimTool *AuroraUX::buildAssembler() const { 1983249423Sdim return new tools::auroraux::Assemble(*this); 1984249423Sdim} 1985198092Srdivacky 1986249423SdimTool *AuroraUX::buildLinker() const { 1987249423Sdim return new tools::auroraux::Link(*this); 1988198092Srdivacky} 1989198092Srdivacky 1990234353Sdim/// Solaris - Solaris tool chain which can call as(1) and ld(1) directly. 1991198092Srdivacky 1992234353SdimSolaris::Solaris(const Driver &D, const llvm::Triple& Triple, 1993234353Sdim const ArgList &Args) 1994234353Sdim : Generic_GCC(D, Triple, Args) { 1995234353Sdim 1996234353Sdim getProgramPaths().push_back(getDriver().getInstalledDir()); 1997234353Sdim if (getDriver().getInstalledDir() != getDriver().Dir) 1998234353Sdim getProgramPaths().push_back(getDriver().Dir); 1999234353Sdim 2000234353Sdim getFilePaths().push_back(getDriver().Dir + "/../lib"); 2001234353Sdim getFilePaths().push_back("/usr/lib"); 2002234353Sdim} 2003234353Sdim 2004249423SdimTool *Solaris::buildAssembler() const { 2005249423Sdim return new tools::solaris::Assemble(*this); 2006249423Sdim} 2007234353Sdim 2008249423SdimTool *Solaris::buildLinker() const { 2009249423Sdim return new tools::solaris::Link(*this); 2010234353Sdim} 2011234353Sdim 2012249423Sdim/// Distribution (very bare-bones at the moment). 2013193326Sed 2014249423Sdimenum Distro { 2015219077Sdim ArchLinux, 2016218893Sdim DebianLenny, 2017218893Sdim DebianSqueeze, 2018223017Sdim DebianWheezy, 2019249423Sdim DebianJessie, 2020218893Sdim Exherbo, 2021223017Sdim RHEL4, 2022223017Sdim RHEL5, 2023223017Sdim RHEL6, 2024218893Sdim Fedora13, 2025218893Sdim Fedora14, 2026221345Sdim Fedora15, 2027234353Sdim Fedora16, 2028221345Sdim FedoraRawhide, 2029218893Sdim OpenSuse11_3, 2030223017Sdim OpenSuse11_4, 2031223017Sdim OpenSuse12_1, 2032235864Sdim OpenSuse12_2, 2033221345Sdim UbuntuHardy, 2034221345Sdim UbuntuIntrepid, 2035218893Sdim UbuntuJaunty, 2036218893Sdim UbuntuKarmic, 2037218893Sdim UbuntuLucid, 2038218893Sdim UbuntuMaverick, 2039221345Sdim UbuntuNatty, 2040223017Sdim UbuntuOneiric, 2041234353Sdim UbuntuPrecise, 2042244628Sdim UbuntuQuantal, 2043244628Sdim UbuntuRaring, 2044218893Sdim UnknownDistro 2045218893Sdim}; 2046198092Srdivacky 2047249423Sdimstatic bool IsRedhat(enum Distro Distro) { 2048234353Sdim return (Distro >= Fedora13 && Distro <= FedoraRawhide) || 2049234353Sdim (Distro >= RHEL4 && Distro <= RHEL6); 2050218893Sdim} 2051198092Srdivacky 2052249423Sdimstatic bool IsOpenSuse(enum Distro Distro) { 2053235864Sdim return Distro >= OpenSuse11_3 && Distro <= OpenSuse12_2; 2054193326Sed} 2055193326Sed 2056249423Sdimstatic bool IsDebian(enum Distro Distro) { 2057249423Sdim return Distro >= DebianLenny && Distro <= DebianJessie; 2058218893Sdim} 2059218893Sdim 2060249423Sdimstatic bool IsUbuntu(enum Distro Distro) { 2061244628Sdim return Distro >= UbuntuHardy && Distro <= UbuntuRaring; 2062218893Sdim} 2063218893Sdim 2064249423Sdimstatic Distro DetectDistro(llvm::Triple::ArchType Arch) { 2065234353Sdim OwningPtr<llvm::MemoryBuffer> File; 2066218893Sdim if (!llvm::MemoryBuffer::getFile("/etc/lsb-release", File)) { 2067226633Sdim StringRef Data = File.get()->getBuffer(); 2068226633Sdim SmallVector<StringRef, 8> Lines; 2069218893Sdim Data.split(Lines, "\n"); 2070249423Sdim Distro Version = UnknownDistro; 2071234353Sdim for (unsigned i = 0, s = Lines.size(); i != s; ++i) 2072234353Sdim if (Version == UnknownDistro && Lines[i].startswith("DISTRIB_CODENAME=")) 2073249423Sdim Version = llvm::StringSwitch<Distro>(Lines[i].substr(17)) 2074234353Sdim .Case("hardy", UbuntuHardy) 2075234353Sdim .Case("intrepid", UbuntuIntrepid) 2076234353Sdim .Case("jaunty", UbuntuJaunty) 2077234353Sdim .Case("karmic", UbuntuKarmic) 2078234353Sdim .Case("lucid", UbuntuLucid) 2079234353Sdim .Case("maverick", UbuntuMaverick) 2080234353Sdim .Case("natty", UbuntuNatty) 2081234353Sdim .Case("oneiric", UbuntuOneiric) 2082234353Sdim .Case("precise", UbuntuPrecise) 2083244628Sdim .Case("quantal", UbuntuQuantal) 2084244628Sdim .Case("raring", UbuntuRaring) 2085234353Sdim .Default(UnknownDistro); 2086234353Sdim return Version; 2087218893Sdim } 2088218893Sdim 2089218893Sdim if (!llvm::MemoryBuffer::getFile("/etc/redhat-release", File)) { 2090226633Sdim StringRef Data = File.get()->getBuffer(); 2091234353Sdim if (Data.startswith("Fedora release 16")) 2092234353Sdim return Fedora16; 2093234353Sdim else if (Data.startswith("Fedora release 15")) 2094221345Sdim return Fedora15; 2095221345Sdim else if (Data.startswith("Fedora release 14")) 2096218893Sdim return Fedora14; 2097221345Sdim else if (Data.startswith("Fedora release 13")) 2098218893Sdim return Fedora13; 2099221345Sdim else if (Data.startswith("Fedora release") && 2100226633Sdim Data.find("Rawhide") != StringRef::npos) 2101221345Sdim return FedoraRawhide; 2102223017Sdim else if (Data.startswith("Red Hat Enterprise Linux") && 2103226633Sdim Data.find("release 6") != StringRef::npos) 2104223017Sdim return RHEL6; 2105223017Sdim else if ((Data.startswith("Red Hat Enterprise Linux") || 2106249423Sdim Data.startswith("CentOS")) && 2107226633Sdim Data.find("release 5") != StringRef::npos) 2108223017Sdim return RHEL5; 2109223017Sdim else if ((Data.startswith("Red Hat Enterprise Linux") || 2110249423Sdim Data.startswith("CentOS")) && 2111226633Sdim Data.find("release 4") != StringRef::npos) 2112223017Sdim return RHEL4; 2113218893Sdim return UnknownDistro; 2114218893Sdim } 2115218893Sdim 2116218893Sdim if (!llvm::MemoryBuffer::getFile("/etc/debian_version", File)) { 2117226633Sdim StringRef Data = File.get()->getBuffer(); 2118218893Sdim if (Data[0] == '5') 2119218893Sdim return DebianLenny; 2120234353Sdim else if (Data.startswith("squeeze/sid") || Data[0] == '6') 2121218893Sdim return DebianSqueeze; 2122234353Sdim else if (Data.startswith("wheezy/sid") || Data[0] == '7') 2123223017Sdim return DebianWheezy; 2124249423Sdim else if (Data.startswith("jessie/sid") || Data[0] == '8') 2125249423Sdim return DebianJessie; 2126218893Sdim return UnknownDistro; 2127218893Sdim } 2128218893Sdim 2129234353Sdim if (!llvm::MemoryBuffer::getFile("/etc/SuSE-release", File)) 2130249423Sdim return llvm::StringSwitch<Distro>(File.get()->getBuffer()) 2131234353Sdim .StartsWith("openSUSE 11.3", OpenSuse11_3) 2132234353Sdim .StartsWith("openSUSE 11.4", OpenSuse11_4) 2133234353Sdim .StartsWith("openSUSE 12.1", OpenSuse12_1) 2134235864Sdim .StartsWith("openSUSE 12.2", OpenSuse12_2) 2135234353Sdim .Default(UnknownDistro); 2136218893Sdim 2137218893Sdim bool Exists; 2138218893Sdim if (!llvm::sys::fs::exists("/etc/exherbo-release", Exists) && Exists) 2139218893Sdim return Exherbo; 2140218893Sdim 2141219077Sdim if (!llvm::sys::fs::exists("/etc/arch-release", Exists) && Exists) 2142219077Sdim return ArchLinux; 2143219077Sdim 2144218893Sdim return UnknownDistro; 2145218893Sdim} 2146218893Sdim 2147228379Sdim/// \brief Get our best guess at the multiarch triple for a target. 2148228379Sdim/// 2149228379Sdim/// Debian-based systems are starting to use a multiarch setup where they use 2150228379Sdim/// a target-triple directory in the library and header search paths. 2151228379Sdim/// Unfortunately, this triple does not align with the vanilla target triple, 2152228379Sdim/// so we provide a rough mapping here. 2153228379Sdimstatic std::string getMultiarchTriple(const llvm::Triple TargetTriple, 2154228379Sdim StringRef SysRoot) { 2155228379Sdim // For most architectures, just use whatever we have rather than trying to be 2156228379Sdim // clever. 2157228379Sdim switch (TargetTriple.getArch()) { 2158228379Sdim default: 2159228379Sdim return TargetTriple.str(); 2160226633Sdim 2161228379Sdim // We use the existence of '/lib/<triple>' as a directory to detect some 2162228379Sdim // common linux triples that don't quite match the Clang triple for both 2163234353Sdim // 32-bit and 64-bit targets. Multiarch fixes its install triples to these 2164234353Sdim // regardless of what the actual target triple is. 2165239462Sdim case llvm::Triple::arm: 2166239462Sdim case llvm::Triple::thumb: 2167239462Sdim if (TargetTriple.getEnvironment() == llvm::Triple::GNUEABIHF) { 2168239462Sdim if (llvm::sys::fs::exists(SysRoot + "/lib/arm-linux-gnueabihf")) 2169239462Sdim return "arm-linux-gnueabihf"; 2170239462Sdim } else { 2171239462Sdim if (llvm::sys::fs::exists(SysRoot + "/lib/arm-linux-gnueabi")) 2172239462Sdim return "arm-linux-gnueabi"; 2173239462Sdim } 2174239462Sdim return TargetTriple.str(); 2175228379Sdim case llvm::Triple::x86: 2176228379Sdim if (llvm::sys::fs::exists(SysRoot + "/lib/i386-linux-gnu")) 2177228379Sdim return "i386-linux-gnu"; 2178228379Sdim return TargetTriple.str(); 2179228379Sdim case llvm::Triple::x86_64: 2180228379Sdim if (llvm::sys::fs::exists(SysRoot + "/lib/x86_64-linux-gnu")) 2181228379Sdim return "x86_64-linux-gnu"; 2182228379Sdim return TargetTriple.str(); 2183249423Sdim case llvm::Triple::aarch64: 2184249423Sdim if (llvm::sys::fs::exists(SysRoot + "/lib/aarch64-linux-gnu")) 2185249423Sdim return "aarch64-linux-gnu"; 2186234353Sdim case llvm::Triple::mips: 2187234353Sdim if (llvm::sys::fs::exists(SysRoot + "/lib/mips-linux-gnu")) 2188234353Sdim return "mips-linux-gnu"; 2189234353Sdim return TargetTriple.str(); 2190234353Sdim case llvm::Triple::mipsel: 2191234353Sdim if (llvm::sys::fs::exists(SysRoot + "/lib/mipsel-linux-gnu")) 2192234353Sdim return "mipsel-linux-gnu"; 2193234353Sdim return TargetTriple.str(); 2194234353Sdim case llvm::Triple::ppc: 2195249423Sdim if (llvm::sys::fs::exists(SysRoot + "/lib/powerpc-linux-gnuspe")) 2196249423Sdim return "powerpc-linux-gnuspe"; 2197234353Sdim if (llvm::sys::fs::exists(SysRoot + "/lib/powerpc-linux-gnu")) 2198234353Sdim return "powerpc-linux-gnu"; 2199234353Sdim return TargetTriple.str(); 2200234353Sdim case llvm::Triple::ppc64: 2201234353Sdim if (llvm::sys::fs::exists(SysRoot + "/lib/powerpc64-linux-gnu")) 2202234353Sdim return "powerpc64-linux-gnu"; 2203234353Sdim return TargetTriple.str(); 2204226633Sdim } 2205226633Sdim} 2206226633Sdim 2207234353Sdimstatic void addPathIfExists(Twine Path, ToolChain::path_list &Paths) { 2208234353Sdim if (llvm::sys::fs::exists(Path)) Paths.push_back(Path.str()); 2209234353Sdim} 2210234353Sdim 2211243830Sdimstatic bool isMipsR2Arch(llvm::Triple::ArchType Arch, 2212243830Sdim const ArgList &Args) { 2213243830Sdim if (Arch != llvm::Triple::mips && 2214243830Sdim Arch != llvm::Triple::mipsel) 2215243830Sdim return false; 2216243830Sdim 2217243830Sdim Arg *A = Args.getLastArg(options::OPT_march_EQ, 2218243830Sdim options::OPT_mcpu_EQ, 2219243830Sdim options::OPT_mips_CPUs_Group); 2220243830Sdim 2221243830Sdim if (!A) 2222243830Sdim return false; 2223243830Sdim 2224243830Sdim if (A->getOption().matches(options::OPT_mips_CPUs_Group)) 2225243830Sdim return A->getOption().matches(options::OPT_mips32r2); 2226243830Sdim 2227243830Sdim return A->getValue() == StringRef("mips32r2"); 2228243830Sdim} 2229243830Sdim 2230243830Sdimstatic StringRef getMultilibDir(const llvm::Triple &Triple, 2231243830Sdim const ArgList &Args) { 2232243830Sdim if (!isMipsArch(Triple.getArch())) 2233243830Sdim return Triple.isArch32Bit() ? "lib32" : "lib64"; 2234243830Sdim 2235243830Sdim // lib32 directory has a special meaning on MIPS targets. 2236243830Sdim // It contains N32 ABI binaries. Use this folder if produce 2237243830Sdim // code for N32 ABI only. 2238243830Sdim if (hasMipsN32ABIArg(Args)) 2239243830Sdim return "lib32"; 2240243830Sdim 2241243830Sdim return Triple.isArch32Bit() ? "lib" : "lib64"; 2242243830Sdim} 2243243830Sdim 2244234353SdimLinux::Linux(const Driver &D, const llvm::Triple &Triple, const ArgList &Args) 2245234353Sdim : Generic_ELF(D, Triple, Args) { 2246234353Sdim llvm::Triple::ArchType Arch = Triple.getArch(); 2247251662Sdim std::string SysRoot = computeSysRoot(Args); 2248226633Sdim 2249226633Sdim // OpenSuse stores the linker with the compiler, add that to the search 2250226633Sdim // path. 2251226633Sdim ToolChain::path_list &PPaths = getProgramPaths(); 2252228379Sdim PPaths.push_back(Twine(GCCInstallation.getParentLibPath() + "/../" + 2253234353Sdim GCCInstallation.getTriple().str() + "/bin").str()); 2254226633Sdim 2255226633Sdim Linker = GetProgramPath("ld"); 2256226633Sdim 2257249423Sdim Distro Distro = DetectDistro(Arch); 2258218893Sdim 2259223017Sdim if (IsOpenSuse(Distro) || IsUbuntu(Distro)) { 2260218893Sdim ExtraOpts.push_back("-z"); 2261218893Sdim ExtraOpts.push_back("relro"); 2262218893Sdim } 2263218893Sdim 2264221345Sdim if (Arch == llvm::Triple::arm || Arch == llvm::Triple::thumb) 2265218893Sdim ExtraOpts.push_back("-X"); 2266218893Sdim 2267243830Sdim const bool IsAndroid = Triple.getEnvironment() == llvm::Triple::Android; 2268251662Sdim const bool IsMips = isMipsArch(Arch); 2269218893Sdim 2270251662Sdim if (IsMips && !SysRoot.empty()) 2271251662Sdim ExtraOpts.push_back("--sysroot=" + SysRoot); 2272251662Sdim 2273234353Sdim // Do not use 'gnu' hash style for Mips targets because .gnu.hash 2274234353Sdim // and the MIPS ABI require .dynsym to be sorted in different ways. 2275234353Sdim // .gnu.hash needs symbols to be grouped by hash code whereas the MIPS 2276234353Sdim // ABI requires a mapping between the GOT and the symbol table. 2277234353Sdim // Android loader does not support .gnu.hash. 2278251662Sdim if (!IsMips && !IsAndroid) { 2279234353Sdim if (IsRedhat(Distro) || IsOpenSuse(Distro) || 2280234353Sdim (IsUbuntu(Distro) && Distro >= UbuntuMaverick)) 2281234353Sdim ExtraOpts.push_back("--hash-style=gnu"); 2282234353Sdim 2283234353Sdim if (IsDebian(Distro) || IsOpenSuse(Distro) || Distro == UbuntuLucid || 2284234353Sdim Distro == UbuntuJaunty || Distro == UbuntuKarmic) 2285234353Sdim ExtraOpts.push_back("--hash-style=both"); 2286234353Sdim } 2287234353Sdim 2288223017Sdim if (IsRedhat(Distro)) 2289218893Sdim ExtraOpts.push_back("--no-add-needed"); 2290218893Sdim 2291223017Sdim if (Distro == DebianSqueeze || Distro == DebianWheezy || 2292249423Sdim Distro == DebianJessie || IsOpenSuse(Distro) || 2293223017Sdim (IsRedhat(Distro) && Distro != RHEL4 && Distro != RHEL5) || 2294234353Sdim (IsUbuntu(Distro) && Distro >= UbuntuKarmic)) 2295218893Sdim ExtraOpts.push_back("--build-id"); 2296218893Sdim 2297223017Sdim if (IsOpenSuse(Distro)) 2298223017Sdim ExtraOpts.push_back("--enable-new-dtags"); 2299223017Sdim 2300226633Sdim // The selection of paths to try here is designed to match the patterns which 2301226633Sdim // the GCC driver itself uses, as this is part of the GCC-compatible driver. 2302226633Sdim // This was determined by running GCC in a fake filesystem, creating all 2303226633Sdim // possible permutations of these directories, and seeing which ones it added 2304226633Sdim // to the link paths. 2305226633Sdim path_list &Paths = getFilePaths(); 2306219077Sdim 2307243830Sdim const std::string Multilib = getMultilibDir(Triple, Args); 2308228379Sdim const std::string MultiarchTriple = getMultiarchTriple(Triple, SysRoot); 2309226633Sdim 2310228379Sdim // Add the multilib suffixed paths where they are available. 2311228379Sdim if (GCCInstallation.isValid()) { 2312234353Sdim const llvm::Triple &GCCTriple = GCCInstallation.getTriple(); 2313228379Sdim const std::string &LibPath = GCCInstallation.getParentLibPath(); 2314234353Sdim 2315243830Sdim if (IsAndroid && isMipsR2Arch(Triple.getArch(), Args)) 2316243830Sdim addPathIfExists(GCCInstallation.getInstallPath() + 2317243830Sdim GCCInstallation.getMultiarchSuffix() + 2318243830Sdim "/mips-r2", 2319243830Sdim Paths); 2320243830Sdim else 2321243830Sdim addPathIfExists((GCCInstallation.getInstallPath() + 2322243830Sdim GCCInstallation.getMultiarchSuffix()), 2323243830Sdim Paths); 2324243830Sdim 2325234353Sdim // If the GCC installation we found is inside of the sysroot, we want to 2326234353Sdim // prefer libraries installed in the parent prefix of the GCC installation. 2327234353Sdim // It is important to *not* use these paths when the GCC installation is 2328234982Sdim // outside of the system root as that can pick up unintended libraries. 2329234353Sdim // This usually happens when there is an external cross compiler on the 2330234353Sdim // host system, and a more minimal sysroot available that is the target of 2331234353Sdim // the cross. 2332234353Sdim if (StringRef(LibPath).startswith(SysRoot)) { 2333234353Sdim addPathIfExists(LibPath + "/../" + GCCTriple.str() + "/lib/../" + Multilib, 2334234353Sdim Paths); 2335234353Sdim addPathIfExists(LibPath + "/" + MultiarchTriple, Paths); 2336234353Sdim addPathIfExists(LibPath + "/../" + Multilib, Paths); 2337234353Sdim } 2338243830Sdim // On Android, libraries in the parent prefix of the GCC installation are 2339243830Sdim // preferred to the ones under sysroot. 2340243830Sdim if (IsAndroid) { 2341243830Sdim addPathIfExists(LibPath + "/../" + GCCTriple.str() + "/lib", Paths); 2342243830Sdim } 2343251662Sdim // Sourcery CodeBench MIPS toolchain holds some libraries under 2344251662Sdim // the parent prefix of the GCC installation. 2345251662Sdim if (IsMips) { 2346251662Sdim std::string Suffix; 2347251662Sdim appendMipsTargetSuffix(Suffix, Arch, Args); 2348251662Sdim addPathIfExists(LibPath + "/../" + GCCTriple.str() + "/lib/../" + 2349251662Sdim Multilib + Suffix, 2350251662Sdim Paths); 2351251662Sdim } 2352228379Sdim } 2353228379Sdim addPathIfExists(SysRoot + "/lib/" + MultiarchTriple, Paths); 2354228379Sdim addPathIfExists(SysRoot + "/lib/../" + Multilib, Paths); 2355228379Sdim addPathIfExists(SysRoot + "/usr/lib/" + MultiarchTriple, Paths); 2356228379Sdim addPathIfExists(SysRoot + "/usr/lib/../" + Multilib, Paths); 2357226633Sdim 2358228379Sdim // Try walking via the GCC triple path in case of multiarch GCC 2359228379Sdim // installations with strange symlinks. 2360228379Sdim if (GCCInstallation.isValid()) 2361234353Sdim addPathIfExists(SysRoot + "/usr/lib/" + GCCInstallation.getTriple().str() + 2362228379Sdim "/../../" + Multilib, Paths); 2363226633Sdim 2364226633Sdim // Add the non-multilib suffixed paths (if potentially different). 2365226633Sdim if (GCCInstallation.isValid()) { 2366226633Sdim const std::string &LibPath = GCCInstallation.getParentLibPath(); 2367234353Sdim const llvm::Triple &GCCTriple = GCCInstallation.getTriple(); 2368234353Sdim if (!GCCInstallation.getMultiarchSuffix().empty()) 2369226633Sdim addPathIfExists(GCCInstallation.getInstallPath(), Paths); 2370234353Sdim 2371234353Sdim if (StringRef(LibPath).startswith(SysRoot)) { 2372234353Sdim addPathIfExists(LibPath + "/../" + GCCTriple.str() + "/lib", Paths); 2373234353Sdim addPathIfExists(LibPath, Paths); 2374234353Sdim } 2375226633Sdim } 2376226633Sdim addPathIfExists(SysRoot + "/lib", Paths); 2377226633Sdim addPathIfExists(SysRoot + "/usr/lib", Paths); 2378251662Sdim 2379251662Sdim IsPIEDefault = SanitizerArgs(*this, Args).hasZeroBaseShadow(); 2380218893Sdim} 2381218893Sdim 2382218893Sdimbool Linux::HasNativeLLVMSupport() const { 2383218893Sdim return true; 2384218893Sdim} 2385218893Sdim 2386249423SdimTool *Linux::buildLinker() const { 2387249423Sdim return new tools::gnutools::Link(*this); 2388249423Sdim} 2389212904Sdim 2390249423SdimTool *Linux::buildAssembler() const { 2391249423Sdim return new tools::gnutools::Assemble(*this); 2392212904Sdim} 2393212904Sdim 2394249423Sdimvoid Linux::addClangTargetOptions(const ArgList &DriverArgs, 2395249423Sdim ArgStringList &CC1Args) const { 2396239462Sdim const Generic_GCC::GCCVersion &V = GCCInstallation.getVersion(); 2397249423Sdim bool UseInitArrayDefault 2398249423Sdim = V >= Generic_GCC::GCCVersion::Parse("4.7.0") || 2399249423Sdim getTriple().getArch() == llvm::Triple::aarch64 || 2400249423Sdim getTriple().getEnvironment() == llvm::Triple::Android; 2401249423Sdim if (DriverArgs.hasFlag(options::OPT_fuse_init_array, 2402249423Sdim options::OPT_fno_use_init_array, 2403249423Sdim UseInitArrayDefault)) 2404239462Sdim CC1Args.push_back("-fuse-init-array"); 2405239462Sdim} 2406239462Sdim 2407251662Sdimstd::string Linux::computeSysRoot(const ArgList &Args) const { 2408251662Sdim if (!getDriver().SysRoot.empty()) 2409251662Sdim return getDriver().SysRoot; 2410251662Sdim 2411251662Sdim if (!GCCInstallation.isValid() || !isMipsArch(getTriple().getArch())) 2412251662Sdim return std::string(); 2413251662Sdim 2414251662Sdim std::string Path = 2415251662Sdim (GCCInstallation.getInstallPath() + 2416251662Sdim "/../../../../" + GCCInstallation.getTriple().str() + "/libc").str(); 2417251662Sdim appendMipsTargetSuffix(Path, getTriple().getArch(), Args); 2418251662Sdim 2419251662Sdim return llvm::sys::fs::exists(Path) ? Path : ""; 2420251662Sdim} 2421251662Sdim 2422228379Sdimvoid Linux::AddClangSystemIncludeArgs(const ArgList &DriverArgs, 2423228379Sdim ArgStringList &CC1Args) const { 2424228379Sdim const Driver &D = getDriver(); 2425251662Sdim std::string SysRoot = computeSysRoot(DriverArgs); 2426228379Sdim 2427228379Sdim if (DriverArgs.hasArg(options::OPT_nostdinc)) 2428228379Sdim return; 2429228379Sdim 2430228379Sdim if (!DriverArgs.hasArg(options::OPT_nostdlibinc)) 2431251662Sdim addSystemInclude(DriverArgs, CC1Args, SysRoot + "/usr/local/include"); 2432228379Sdim 2433228379Sdim if (!DriverArgs.hasArg(options::OPT_nobuiltininc)) { 2434228379Sdim llvm::sys::Path P(D.ResourceDir); 2435228379Sdim P.appendComponent("include"); 2436228379Sdim addSystemInclude(DriverArgs, CC1Args, P.str()); 2437228379Sdim } 2438228379Sdim 2439228379Sdim if (DriverArgs.hasArg(options::OPT_nostdlibinc)) 2440228379Sdim return; 2441228379Sdim 2442228379Sdim // Check for configure-time C include directories. 2443228379Sdim StringRef CIncludeDirs(C_INCLUDE_DIRS); 2444228379Sdim if (CIncludeDirs != "") { 2445228379Sdim SmallVector<StringRef, 5> dirs; 2446228379Sdim CIncludeDirs.split(dirs, ":"); 2447228379Sdim for (SmallVectorImpl<StringRef>::iterator I = dirs.begin(), E = dirs.end(); 2448228379Sdim I != E; ++I) { 2449251662Sdim StringRef Prefix = llvm::sys::path::is_absolute(*I) ? SysRoot : ""; 2450228379Sdim addExternCSystemInclude(DriverArgs, CC1Args, Prefix + *I); 2451228379Sdim } 2452228379Sdim return; 2453228379Sdim } 2454228379Sdim 2455228379Sdim // Lacking those, try to detect the correct set of system includes for the 2456228379Sdim // target triple. 2457228379Sdim 2458251662Sdim // Sourcery CodeBench and modern FSF Mips toolchains put extern C 2459251662Sdim // system includes under three additional directories. 2460251662Sdim if (GCCInstallation.isValid() && isMipsArch(getTriple().getArch())) { 2461251662Sdim addExternCSystemIncludeIfExists(DriverArgs, CC1Args, 2462251662Sdim GCCInstallation.getInstallPath() + 2463251662Sdim "/include"); 2464251662Sdim 2465251662Sdim addExternCSystemIncludeIfExists(DriverArgs, CC1Args, 2466251662Sdim GCCInstallation.getInstallPath() + 2467251662Sdim "/../../../../" + 2468251662Sdim GCCInstallation.getTriple().str() + 2469251662Sdim "/libc/usr/include"); 2470251662Sdim } 2471251662Sdim 2472228379Sdim // Implement generic Debian multiarch support. 2473228379Sdim const StringRef X86_64MultiarchIncludeDirs[] = { 2474228379Sdim "/usr/include/x86_64-linux-gnu", 2475228379Sdim 2476228379Sdim // FIXME: These are older forms of multiarch. It's not clear that they're 2477228379Sdim // in use in any released version of Debian, so we should consider 2478228379Sdim // removing them. 2479228379Sdim "/usr/include/i686-linux-gnu/64", 2480228379Sdim "/usr/include/i486-linux-gnu/64" 2481228379Sdim }; 2482228379Sdim const StringRef X86MultiarchIncludeDirs[] = { 2483228379Sdim "/usr/include/i386-linux-gnu", 2484228379Sdim 2485228379Sdim // FIXME: These are older forms of multiarch. It's not clear that they're 2486228379Sdim // in use in any released version of Debian, so we should consider 2487228379Sdim // removing them. 2488228379Sdim "/usr/include/x86_64-linux-gnu/32", 2489228379Sdim "/usr/include/i686-linux-gnu", 2490228379Sdim "/usr/include/i486-linux-gnu" 2491228379Sdim }; 2492249423Sdim const StringRef AArch64MultiarchIncludeDirs[] = { 2493249423Sdim "/usr/include/aarch64-linux-gnu" 2494249423Sdim }; 2495228379Sdim const StringRef ARMMultiarchIncludeDirs[] = { 2496228379Sdim "/usr/include/arm-linux-gnueabi" 2497228379Sdim }; 2498239462Sdim const StringRef ARMHFMultiarchIncludeDirs[] = { 2499239462Sdim "/usr/include/arm-linux-gnueabihf" 2500239462Sdim }; 2501234353Sdim const StringRef MIPSMultiarchIncludeDirs[] = { 2502234353Sdim "/usr/include/mips-linux-gnu" 2503234353Sdim }; 2504234353Sdim const StringRef MIPSELMultiarchIncludeDirs[] = { 2505234353Sdim "/usr/include/mipsel-linux-gnu" 2506234353Sdim }; 2507234353Sdim const StringRef PPCMultiarchIncludeDirs[] = { 2508234353Sdim "/usr/include/powerpc-linux-gnu" 2509234353Sdim }; 2510234353Sdim const StringRef PPC64MultiarchIncludeDirs[] = { 2511234353Sdim "/usr/include/powerpc64-linux-gnu" 2512234353Sdim }; 2513228379Sdim ArrayRef<StringRef> MultiarchIncludeDirs; 2514228379Sdim if (getTriple().getArch() == llvm::Triple::x86_64) { 2515228379Sdim MultiarchIncludeDirs = X86_64MultiarchIncludeDirs; 2516228379Sdim } else if (getTriple().getArch() == llvm::Triple::x86) { 2517228379Sdim MultiarchIncludeDirs = X86MultiarchIncludeDirs; 2518249423Sdim } else if (getTriple().getArch() == llvm::Triple::aarch64) { 2519249423Sdim MultiarchIncludeDirs = AArch64MultiarchIncludeDirs; 2520228379Sdim } else if (getTriple().getArch() == llvm::Triple::arm) { 2521239462Sdim if (getTriple().getEnvironment() == llvm::Triple::GNUEABIHF) 2522239462Sdim MultiarchIncludeDirs = ARMHFMultiarchIncludeDirs; 2523239462Sdim else 2524239462Sdim MultiarchIncludeDirs = ARMMultiarchIncludeDirs; 2525234353Sdim } else if (getTriple().getArch() == llvm::Triple::mips) { 2526234353Sdim MultiarchIncludeDirs = MIPSMultiarchIncludeDirs; 2527234353Sdim } else if (getTriple().getArch() == llvm::Triple::mipsel) { 2528234353Sdim MultiarchIncludeDirs = MIPSELMultiarchIncludeDirs; 2529234353Sdim } else if (getTriple().getArch() == llvm::Triple::ppc) { 2530234353Sdim MultiarchIncludeDirs = PPCMultiarchIncludeDirs; 2531234353Sdim } else if (getTriple().getArch() == llvm::Triple::ppc64) { 2532234353Sdim MultiarchIncludeDirs = PPC64MultiarchIncludeDirs; 2533228379Sdim } 2534228379Sdim for (ArrayRef<StringRef>::iterator I = MultiarchIncludeDirs.begin(), 2535228379Sdim E = MultiarchIncludeDirs.end(); 2536228379Sdim I != E; ++I) { 2537251662Sdim if (llvm::sys::fs::exists(SysRoot + *I)) { 2538251662Sdim addExternCSystemInclude(DriverArgs, CC1Args, SysRoot + *I); 2539228379Sdim break; 2540228379Sdim } 2541228379Sdim } 2542228379Sdim 2543228379Sdim if (getTriple().getOS() == llvm::Triple::RTEMS) 2544228379Sdim return; 2545228379Sdim 2546234353Sdim // Add an include of '/include' directly. This isn't provided by default by 2547234353Sdim // system GCCs, but is often used with cross-compiling GCCs, and harmless to 2548234353Sdim // add even when Clang is acting as-if it were a system compiler. 2549251662Sdim addExternCSystemInclude(DriverArgs, CC1Args, SysRoot + "/include"); 2550234353Sdim 2551251662Sdim addExternCSystemInclude(DriverArgs, CC1Args, SysRoot + "/usr/include"); 2552228379Sdim} 2553228379Sdim 2554249423Sdim/// \brief Helper to add the three variant paths for a libstdc++ installation. 2555234353Sdim/*static*/ bool Linux::addLibStdCXXIncludePaths(Twine Base, Twine TargetArchDir, 2556234353Sdim const ArgList &DriverArgs, 2557234353Sdim ArgStringList &CC1Args) { 2558228379Sdim if (!llvm::sys::fs::exists(Base)) 2559228379Sdim return false; 2560228379Sdim addSystemInclude(DriverArgs, CC1Args, Base); 2561228379Sdim addSystemInclude(DriverArgs, CC1Args, Base + "/" + TargetArchDir); 2562228379Sdim addSystemInclude(DriverArgs, CC1Args, Base + "/backward"); 2563228379Sdim return true; 2564228379Sdim} 2565228379Sdim 2566249423Sdim/// \brief Helper to add an extra variant path for an (Ubuntu) multilib 2567249423Sdim/// libstdc++ installation. 2568249423Sdim/*static*/ bool Linux::addLibStdCXXIncludePaths(Twine Base, Twine Suffix, 2569249423Sdim Twine TargetArchDir, 2570249423Sdim Twine MultiLibSuffix, 2571249423Sdim const ArgList &DriverArgs, 2572249423Sdim ArgStringList &CC1Args) { 2573249423Sdim if (!addLibStdCXXIncludePaths(Base+Suffix, TargetArchDir + MultiLibSuffix, 2574249423Sdim DriverArgs, CC1Args)) 2575249423Sdim return false; 2576249423Sdim 2577249423Sdim addSystemInclude(DriverArgs, CC1Args, Base + "/" + TargetArchDir + Suffix 2578249423Sdim + MultiLibSuffix); 2579249423Sdim return true; 2580249423Sdim} 2581249423Sdim 2582228379Sdimvoid Linux::AddClangCXXStdlibIncludeArgs(const ArgList &DriverArgs, 2583228379Sdim ArgStringList &CC1Args) const { 2584228379Sdim if (DriverArgs.hasArg(options::OPT_nostdlibinc) || 2585228379Sdim DriverArgs.hasArg(options::OPT_nostdincxx)) 2586228379Sdim return; 2587228379Sdim 2588228379Sdim // Check if libc++ has been enabled and provide its include paths if so. 2589228379Sdim if (GetCXXStdlibType(DriverArgs) == ToolChain::CST_Libcxx) { 2590228379Sdim // libc++ is always installed at a fixed path on Linux currently. 2591228379Sdim addSystemInclude(DriverArgs, CC1Args, 2592228379Sdim getDriver().SysRoot + "/usr/include/c++/v1"); 2593228379Sdim return; 2594228379Sdim } 2595228379Sdim 2596234353Sdim // We need a detected GCC installation on Linux to provide libstdc++'s 2597234353Sdim // headers. We handled the libc++ case above. 2598234353Sdim if (!GCCInstallation.isValid()) 2599228379Sdim return; 2600228379Sdim 2601228379Sdim // By default, look for the C++ headers in an include directory adjacent to 2602228379Sdim // the lib directory of the GCC installation. Note that this is expect to be 2603228379Sdim // equivalent to '/usr/include/c++/X.Y' in almost all cases. 2604228379Sdim StringRef LibDir = GCCInstallation.getParentLibPath(); 2605228379Sdim StringRef InstallDir = GCCInstallation.getInstallPath(); 2606239462Sdim StringRef Version = GCCInstallation.getVersion().Text; 2607243830Sdim StringRef TripleStr = GCCInstallation.getTriple().str(); 2608243830Sdim 2609249423Sdim if (addLibStdCXXIncludePaths(LibDir.str() + "/../include", 2610249423Sdim "/c++/" + Version.str(), 2611249423Sdim TripleStr, 2612249423Sdim GCCInstallation.getMultiarchSuffix(), 2613249423Sdim DriverArgs, CC1Args)) 2614249423Sdim return; 2615249423Sdim 2616243830Sdim const std::string IncludePathCandidates[] = { 2617228379Sdim // Gentoo is weird and places its headers inside the GCC install, so if the 2618228379Sdim // first attempt to find the headers fails, try this pattern. 2619243830Sdim InstallDir.str() + "/include/g++-v4", 2620243830Sdim // Android standalone toolchain has C++ headers in yet another place. 2621243830Sdim LibDir.str() + "/../" + TripleStr.str() + "/include/c++/" + Version.str(), 2622243830Sdim // Freescale SDK C++ headers are directly in <sysroot>/usr/include/c++, 2623243830Sdim // without a subdirectory corresponding to the gcc version. 2624243830Sdim LibDir.str() + "/../include/c++", 2625243830Sdim }; 2626243830Sdim 2627243830Sdim for (unsigned i = 0; i < llvm::array_lengthof(IncludePathCandidates); ++i) { 2628243830Sdim if (addLibStdCXXIncludePaths(IncludePathCandidates[i], (TripleStr + 2629243830Sdim GCCInstallation.getMultiarchSuffix()), 2630243830Sdim DriverArgs, CC1Args)) 2631243830Sdim break; 2632228379Sdim } 2633228379Sdim} 2634228379Sdim 2635251662Sdimbool Linux::isPIEDefault() const { 2636251662Sdim return IsPIEDefault; 2637251662Sdim} 2638251662Sdim 2639193326Sed/// DragonFly - DragonFly tool chain which can call as(1) and ld(1) directly. 2640193326Sed 2641234353SdimDragonFly::DragonFly(const Driver &D, const llvm::Triple& Triple, const ArgList &Args) 2642234353Sdim : Generic_ELF(D, Triple, Args) { 2643193326Sed 2644193326Sed // Path mangling to find libexec 2645212904Sdim getProgramPaths().push_back(getDriver().getInstalledDir()); 2646221345Sdim if (getDriver().getInstalledDir() != getDriver().Dir) 2647212904Sdim getProgramPaths().push_back(getDriver().Dir); 2648193326Sed 2649201361Srdivacky getFilePaths().push_back(getDriver().Dir + "/../lib"); 2650193326Sed getFilePaths().push_back("/usr/lib"); 2651251662Sdim if (llvm::sys::fs::exists("/usr/lib/gcc47")) 2652251662Sdim getFilePaths().push_back("/usr/lib/gcc47"); 2653251662Sdim else 2654251662Sdim getFilePaths().push_back("/usr/lib/gcc44"); 2655193326Sed} 2656193326Sed 2657249423SdimTool *DragonFly::buildAssembler() const { 2658249423Sdim return new tools::dragonfly::Assemble(*this); 2659249423Sdim} 2660193326Sed 2661249423SdimTool *DragonFly::buildLinker() const { 2662249423Sdim return new tools::dragonfly::Link(*this); 2663193326Sed} 2664