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 "clang/Basic/ObjCRuntime.h" 12249423Sdim#include "clang/Basic/Version.h" 13208600Srdivacky#include "clang/Driver/Compilation.h" 14193326Sed#include "clang/Driver/Driver.h" 15193326Sed#include "clang/Driver/DriverDiagnostic.h" 16199512Srdivacky#include "clang/Driver/Options.h" 17263508Sdim#include "clang/Driver/SanitizerArgs.h" 18249423Sdim#include "llvm/ADT/STLExtras.h" 19212904Sdim#include "llvm/ADT/SmallString.h" 20193326Sed#include "llvm/ADT/StringExtras.h" 21226633Sdim#include "llvm/ADT/StringSwitch.h" 22263508Sdim#include "llvm/Option/Arg.h" 23263508Sdim#include "llvm/Option/ArgList.h" 24263508Sdim#include "llvm/Option/OptTable.h" 25263508Sdim#include "llvm/Option/Option.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" 32263508Sdim#include "llvm/Support/Program.h" 33193326Sed 34249423Sdim// FIXME: This needs to be listed last until we fix the broken include guards 35249423Sdim// in these files and the LLVM config.h files. 36249423Sdim#include "clang/Config/config.h" // for GCC_INSTALL_PREFIX 37243830Sdim 38193326Sed#include <cstdlib> // ::getenv 39193326Sed 40193326Sedusing namespace clang::driver; 41193326Sedusing namespace clang::driver::toolchains; 42226633Sdimusing namespace clang; 43263508Sdimusing namespace llvm::opt; 44193326Sed 45198092Srdivacky/// Darwin - Darwin tool chain for i386 and x86_64. 46193326Sed 47249423SdimDarwin::Darwin(const Driver &D, const llvm::Triple& Triple, const ArgList &Args) 48249423Sdim : ToolChain(D, Triple, Args), TargetInitialized(false) 49198092Srdivacky{ 50234353Sdim // Compute the initial Darwin version from the triple 51234353Sdim unsigned Major, Minor, Micro; 52234353Sdim if (!Triple.getMacOSXVersion(Major, Minor, Micro)) 53234353Sdim getDriver().Diag(diag::err_drv_invalid_darwin_version) << 54234353Sdim Triple.getOSName(); 55234353Sdim llvm::raw_string_ostream(MacosxVersionMin) 56234353Sdim << Major << '.' << Minor << '.' << Micro; 57212904Sdim 58234353Sdim // FIXME: DarwinVersion is only used to find GCC's libexec directory. 59234353Sdim // It should be removed when we stop supporting that. 60234353Sdim DarwinVersion[0] = Minor + 4; 61234353Sdim DarwinVersion[1] = Micro; 62234353Sdim DarwinVersion[2] = 0; 63239462Sdim 64239462Sdim // Compute the initial iOS version from the triple 65239462Sdim Triple.getiOSVersion(Major, Minor, Micro); 66239462Sdim llvm::raw_string_ostream(iOSVersionMin) 67239462Sdim << Major << '.' << Minor << '.' << Micro; 68198092Srdivacky} 69198092Srdivacky 70212904Sdimtypes::ID Darwin::LookupTypeForExtension(const char *Ext) const { 71212904Sdim types::ID Ty = types::lookupTypeForExtension(Ext); 72212904Sdim 73212904Sdim // Darwin always preprocesses assembly files (unless -x is used explicitly). 74212904Sdim if (Ty == types::TY_PP_Asm) 75212904Sdim return types::TY_Asm; 76212904Sdim 77212904Sdim return Ty; 78212904Sdim} 79212904Sdim 80218893Sdimbool Darwin::HasNativeLLVMSupport() const { 81218893Sdim return true; 82218893Sdim} 83218893Sdim 84239462Sdim/// Darwin provides an ARC runtime starting in MacOS X 10.7 and iOS 5.0. 85239462SdimObjCRuntime Darwin::getDefaultObjCRuntime(bool isNonFragile) const { 86243830Sdim if (isTargetIPhoneOS()) 87239462Sdim return ObjCRuntime(ObjCRuntime::iOS, TargetVersion); 88243830Sdim if (isNonFragile) 89243830Sdim return ObjCRuntime(ObjCRuntime::MacOSX, TargetVersion); 90243830Sdim return ObjCRuntime(ObjCRuntime::FragileMacOSX, TargetVersion); 91224145Sdim} 92224145Sdim 93226633Sdim/// Darwin provides a blocks runtime starting in MacOS X 10.6 and iOS 3.2. 94226633Sdimbool Darwin::hasBlocksRuntime() const { 95226633Sdim if (isTargetIPhoneOS()) 96226633Sdim return !isIPhoneOSVersionLT(3, 2); 97226633Sdim else 98226633Sdim return !isMacosxVersionLT(10, 6); 99226633Sdim} 100202879Srdivacky 101226633Sdimstatic const char *GetArmArchForMArch(StringRef Value) { 102226633Sdim return llvm::StringSwitch<const char*>(Value) 103226633Sdim .Case("armv6k", "armv6") 104249423Sdim .Case("armv6m", "armv6m") 105226633Sdim .Case("armv5tej", "armv5") 106226633Sdim .Case("xscale", "xscale") 107226633Sdim .Case("armv4t", "armv4t") 108226633Sdim .Case("armv7", "armv7") 109226633Sdim .Cases("armv7a", "armv7-a", "armv7") 110226633Sdim .Cases("armv7r", "armv7-r", "armv7") 111249423Sdim .Cases("armv7em", "armv7e-m", "armv7em") 112243830Sdim .Cases("armv7f", "armv7-f", "armv7f") 113243830Sdim .Cases("armv7k", "armv7-k", "armv7k") 114249423Sdim .Cases("armv7m", "armv7-m", "armv7m") 115243830Sdim .Cases("armv7s", "armv7-s", "armv7s") 116226633Sdim .Default(0); 117202879Srdivacky} 118202879Srdivacky 119226633Sdimstatic const char *GetArmArchForMCpu(StringRef Value) { 120226633Sdim return llvm::StringSwitch<const char *>(Value) 121226633Sdim .Cases("arm9e", "arm946e-s", "arm966e-s", "arm968e-s", "arm926ej-s","armv5") 122226633Sdim .Cases("arm10e", "arm10tdmi", "armv5") 123226633Sdim .Cases("arm1020t", "arm1020e", "arm1022e", "arm1026ej-s", "armv5") 124226633Sdim .Case("xscale", "xscale") 125249423Sdim .Cases("arm1136j-s", "arm1136jf-s", "arm1176jz-s", "arm1176jzf-s", "armv6") 126249423Sdim .Case("cortex-m0", "armv6m") 127263508Sdim .Cases("cortex-a5", "cortex-a7", "cortex-a8", "armv7") 128263508Sdim .Cases("cortex-a9", "cortex-a12", "cortex-a15", "armv7") 129263508Sdim .Cases("cortex-r4", "cortex-r5", "armv7r") 130243830Sdim .Case("cortex-a9-mp", "armv7f") 131249423Sdim .Case("cortex-m3", "armv7m") 132249423Sdim .Case("cortex-m4", "armv7em") 133243830Sdim .Case("swift", "armv7s") 134226633Sdim .Default(0); 135202879Srdivacky} 136202879Srdivacky 137226633SdimStringRef Darwin::getDarwinArchName(const ArgList &Args) const { 138202879Srdivacky switch (getTriple().getArch()) { 139202879Srdivacky default: 140202879Srdivacky return getArchName(); 141223017Sdim 142221345Sdim case llvm::Triple::thumb: 143202879Srdivacky case llvm::Triple::arm: { 144202879Srdivacky if (const Arg *A = Args.getLastArg(options::OPT_march_EQ)) 145243830Sdim if (const char *Arch = GetArmArchForMArch(A->getValue())) 146202879Srdivacky return Arch; 147202879Srdivacky 148202879Srdivacky if (const Arg *A = Args.getLastArg(options::OPT_mcpu_EQ)) 149243830Sdim if (const char *Arch = GetArmArchForMCpu(A->getValue())) 150202879Srdivacky return Arch; 151202879Srdivacky 152202879Srdivacky return "arm"; 153202879Srdivacky } 154202879Srdivacky } 155202879Srdivacky} 156202879Srdivacky 157198092SrdivackyDarwin::~Darwin() { 158193326Sed} 159193326Sed 160226633Sdimstd::string Darwin::ComputeEffectiveClangTriple(const ArgList &Args, 161226633Sdim types::ID InputType) const { 162226633Sdim llvm::Triple Triple(ComputeLLVMTriple(Args, InputType)); 163212904Sdim 164212904Sdim // If the target isn't initialized (e.g., an unknown Darwin platform, return 165212904Sdim // the default triple). 166212904Sdim if (!isTargetInitialized()) 167212904Sdim return Triple.getTriple(); 168223017Sdim 169263508Sdim if (Triple.getArchName() == "thumbv6m" || 170263508Sdim Triple.getArchName() == "thumbv7m" || 171263508Sdim Triple.getArchName() == "thumbv7em") { 172263508Sdim // OS is ios or macosx unless it's the v6m or v7m. 173263508Sdim Triple.setOS(llvm::Triple::Darwin); 174263508Sdim Triple.setEnvironment(llvm::Triple::EABI); 175263508Sdim } else { 176263508Sdim SmallString<16> Str; 177263508Sdim Str += isTargetIPhoneOS() ? "ios" : "macosx"; 178263508Sdim Str += getTargetVersion().getAsString(); 179263508Sdim Triple.setOSName(Str); 180263508Sdim } 181223017Sdim 182212904Sdim return Triple.getTriple(); 183212904Sdim} 184212904Sdim 185234353Sdimvoid Generic_ELF::anchor() {} 186234353Sdim 187249423SdimTool *Darwin::getTool(Action::ActionClass AC) const { 188249423Sdim switch (AC) { 189249423Sdim case Action::LipoJobClass: 190249423Sdim if (!Lipo) 191249423Sdim Lipo.reset(new tools::darwin::Lipo(*this)); 192249423Sdim return Lipo.get(); 193249423Sdim case Action::DsymutilJobClass: 194249423Sdim if (!Dsymutil) 195249423Sdim Dsymutil.reset(new tools::darwin::Dsymutil(*this)); 196249423Sdim return Dsymutil.get(); 197249423Sdim case Action::VerifyJobClass: 198249423Sdim if (!VerifyDebug) 199249423Sdim VerifyDebug.reset(new tools::darwin::VerifyDebug(*this)); 200249423Sdim return VerifyDebug.get(); 201249423Sdim default: 202249423Sdim return ToolChain::getTool(AC); 203239462Sdim } 204249423Sdim} 205193326Sed 206249423SdimTool *Darwin::buildLinker() const { 207249423Sdim return new tools::darwin::Link(*this); 208249423Sdim} 209208600Srdivacky 210249423SdimTool *Darwin::buildAssembler() const { 211249423Sdim return new tools::darwin::Assemble(*this); 212193326Sed} 213193326Sed 214249423SdimDarwinClang::DarwinClang(const Driver &D, const llvm::Triple& Triple, 215249423Sdim const ArgList &Args) 216249423Sdim : Darwin(D, Triple, Args) 217198092Srdivacky{ 218218893Sdim getProgramPaths().push_back(getDriver().getInstalledDir()); 219218893Sdim if (getDriver().getInstalledDir() != getDriver().Dir) 220218893Sdim getProgramPaths().push_back(getDriver().Dir); 221218893Sdim 222198092Srdivacky // We expect 'as', 'ld', etc. to be adjacent to our install dir. 223212904Sdim getProgramPaths().push_back(getDriver().getInstalledDir()); 224212904Sdim if (getDriver().getInstalledDir() != getDriver().Dir) 225212904Sdim getProgramPaths().push_back(getDriver().Dir); 226226633Sdim} 227226633Sdim 228224145Sdimvoid DarwinClang::AddLinkARCArgs(const ArgList &Args, 229224145Sdim ArgStringList &CmdArgs) const { 230226633Sdim 231226633Sdim CmdArgs.push_back("-force_load"); 232263508Sdim SmallString<128> P(getDriver().ClangExecutable); 233263508Sdim llvm::sys::path::remove_filename(P); // 'clang' 234263508Sdim llvm::sys::path::remove_filename(P); // 'bin' 235263508Sdim llvm::sys::path::append(P, "lib", "arc", "libarclite_"); 236224145Sdim // Mash in the platform. 237234353Sdim if (isTargetIOSSimulator()) 238263508Sdim P += "iphonesimulator"; 239234353Sdim else if (isTargetIPhoneOS()) 240263508Sdim P += "iphoneos"; 241224145Sdim else 242263508Sdim P += "macosx"; 243263508Sdim P += ".a"; 244224145Sdim 245263508Sdim CmdArgs.push_back(Args.MakeArgString(P)); 246224145Sdim} 247224145Sdim 248224145Sdimvoid DarwinClang::AddLinkRuntimeLib(const ArgList &Args, 249226633Sdim ArgStringList &CmdArgs, 250249423Sdim const char *DarwinStaticLib, 251249423Sdim bool AlwaysLink) const { 252263508Sdim SmallString<128> P(getDriver().ResourceDir); 253263508Sdim llvm::sys::path::append(P, "lib", "darwin", DarwinStaticLib); 254226633Sdim 255224145Sdim // For now, allow missing resource libraries to support developers who may 256249423Sdim // not have compiler-rt checked out or integrated into their build (unless 257249423Sdim // we explicitly force linking with this library). 258263508Sdim if (AlwaysLink || llvm::sys::fs::exists(P.str())) 259224145Sdim CmdArgs.push_back(Args.MakeArgString(P.str())); 260224145Sdim} 261224145Sdim 262198092Srdivackyvoid DarwinClang::AddLinkRuntimeLibArgs(const ArgList &Args, 263198092Srdivacky ArgStringList &CmdArgs) const { 264234353Sdim // Darwin only supports the compiler-rt based runtime libraries. 265234353Sdim switch (GetRuntimeLibType(Args)) { 266234353Sdim case ToolChain::RLT_CompilerRT: 267234353Sdim break; 268234353Sdim default: 269234353Sdim getDriver().Diag(diag::err_drv_unsupported_rtlib_for_platform) 270243830Sdim << Args.getLastArg(options::OPT_rtlib_EQ)->getValue() << "darwin"; 271234353Sdim return; 272234353Sdim } 273234353Sdim 274202879Srdivacky // Darwin doesn't support real static executables, don't link any runtime 275202879Srdivacky // libraries with -static. 276243830Sdim if (Args.hasArg(options::OPT_static) || 277243830Sdim Args.hasArg(options::OPT_fapple_kext) || 278243830Sdim Args.hasArg(options::OPT_mkernel)) 279198092Srdivacky return; 280198092Srdivacky 281198092Srdivacky // Reject -static-libgcc for now, we can deal with this when and if someone 282198092Srdivacky // cares. This is useful in situations where someone wants to statically link 283198092Srdivacky // something like libstdc++, and needs its runtime support routines. 284198092Srdivacky if (const Arg *A = Args.getLastArg(options::OPT_static_libgcc)) { 285226633Sdim getDriver().Diag(diag::err_drv_unsupported_opt) 286198092Srdivacky << A->getAsString(Args); 287198092Srdivacky return; 288198092Srdivacky } 289198092Srdivacky 290234353Sdim // If we are building profile support, link that library in. 291234353Sdim if (Args.hasArg(options::OPT_fprofile_arcs) || 292234353Sdim Args.hasArg(options::OPT_fprofile_generate) || 293234353Sdim Args.hasArg(options::OPT_fcreate_profile) || 294234353Sdim Args.hasArg(options::OPT_coverage)) { 295234353Sdim // Select the appropriate runtime library for the target. 296234353Sdim if (isTargetIPhoneOS()) { 297234353Sdim AddLinkRuntimeLib(Args, CmdArgs, "libclang_rt.profile_ios.a"); 298234353Sdim } else { 299234353Sdim AddLinkRuntimeLib(Args, CmdArgs, "libclang_rt.profile_osx.a"); 300234353Sdim } 301234353Sdim } 302234353Sdim 303263508Sdim const SanitizerArgs &Sanitize = getSanitizerArgs(); 304243830Sdim 305249423Sdim // Add Ubsan runtime library, if required. 306249423Sdim if (Sanitize.needsUbsanRt()) { 307263508Sdim // FIXME: Move this check to SanitizerArgs::filterUnsupportedKinds. 308249423Sdim if (isTargetIPhoneOS()) { 309249423Sdim getDriver().Diag(diag::err_drv_clang_unsupported_per_platform) 310249423Sdim << "-fsanitize=undefined"; 311249423Sdim } else { 312249423Sdim AddLinkRuntimeLib(Args, CmdArgs, "libclang_rt.ubsan_osx.a", true); 313249423Sdim 314249423Sdim // The Ubsan runtime library requires C++. 315249423Sdim AddCXXStdlibLibArgs(Args, CmdArgs); 316249423Sdim } 317249423Sdim } 318249423Sdim 319234353Sdim // Add ASAN runtime library, if required. Dynamic libraries and bundles 320234353Sdim // should not be linked with the runtime library. 321243830Sdim if (Sanitize.needsAsanRt()) { 322263508Sdim // FIXME: Move this check to SanitizerArgs::filterUnsupportedKinds. 323249423Sdim if (isTargetIPhoneOS() && !isTargetIOSSimulator()) { 324234353Sdim getDriver().Diag(diag::err_drv_clang_unsupported_per_platform) 325243830Sdim << "-fsanitize=address"; 326234353Sdim } else { 327263508Sdim if (!Args.hasArg(options::OPT_dynamiclib) && 328263508Sdim !Args.hasArg(options::OPT_bundle)) { 329249423Sdim // The ASAN runtime library requires C++. 330249423Sdim AddCXXStdlibLibArgs(Args, CmdArgs); 331249423Sdim } 332263508Sdim if (isTargetMacOS()) { 333263508Sdim AddLinkRuntimeLib(Args, CmdArgs, 334263508Sdim "libclang_rt.asan_osx_dynamic.dylib", 335263508Sdim true); 336263508Sdim } else { 337263508Sdim if (isTargetIOSSimulator()) { 338263508Sdim AddLinkRuntimeLib(Args, CmdArgs, 339263508Sdim "libclang_rt.asan_iossim_dynamic.dylib", 340263508Sdim true); 341263508Sdim } 342263508Sdim } 343234353Sdim } 344234353Sdim } 345234353Sdim 346202879Srdivacky // Otherwise link libSystem, then the dynamic runtime library, and finally any 347202879Srdivacky // target specific static runtime library. 348198092Srdivacky CmdArgs.push_back("-lSystem"); 349202879Srdivacky 350202879Srdivacky // Select the dynamic runtime library and the target specific static library. 351203955Srdivacky if (isTargetIPhoneOS()) { 352221345Sdim // If we are compiling as iOS / simulator, don't attempt to link libgcc_s.1, 353221345Sdim // it never went into the SDK. 354226633Sdim // Linking against libgcc_s.1 isn't needed for iOS 5.0+ 355226633Sdim if (isIPhoneOSVersionLT(5, 0) && !isTargetIOSSimulator()) 356226633Sdim CmdArgs.push_back("-lgcc_s.1"); 357202879Srdivacky 358221345Sdim // We currently always need a static runtime library for iOS. 359224145Sdim AddLinkRuntimeLib(Args, CmdArgs, "libclang_rt.ios.a"); 360202879Srdivacky } else { 361202879Srdivacky // The dynamic runtime library was merged with libSystem for 10.6 and 362202879Srdivacky // beyond; only 10.4 and 10.5 need an additional runtime library. 363203955Srdivacky if (isMacosxVersionLT(10, 5)) 364202879Srdivacky CmdArgs.push_back("-lgcc_s.10.4"); 365203955Srdivacky else if (isMacosxVersionLT(10, 6)) 366202879Srdivacky CmdArgs.push_back("-lgcc_s.10.5"); 367202879Srdivacky 368218893Sdim // For OS X, we thought we would only need a static runtime library when 369221345Sdim // targeting 10.4, to provide versions of the static functions which were 370218893Sdim // omitted from 10.4.dylib. 371218893Sdim // 372218893Sdim // Unfortunately, that turned out to not be true, because Darwin system 373218893Sdim // headers can still use eprintf on i386, and it is not exported from 374218893Sdim // libSystem. Therefore, we still must provide a runtime library just for 375218893Sdim // the tiny tiny handful of projects that *might* use that symbol. 376218893Sdim if (isMacosxVersionLT(10, 5)) { 377224145Sdim AddLinkRuntimeLib(Args, CmdArgs, "libclang_rt.10.4.a"); 378218893Sdim } else { 379218893Sdim if (getTriple().getArch() == llvm::Triple::x86) 380224145Sdim AddLinkRuntimeLib(Args, CmdArgs, "libclang_rt.eprintf.a"); 381224145Sdim AddLinkRuntimeLib(Args, CmdArgs, "libclang_rt.osx.a"); 382218893Sdim } 383202879Srdivacky } 384224145Sdim} 385202879Srdivacky 386212904Sdimvoid Darwin::AddDeploymentTarget(DerivedArgList &Args) const { 387201361Srdivacky const OptTable &Opts = getDriver().getOpts(); 388193326Sed 389243830Sdim // Support allowing the SDKROOT environment variable used by xcrun and other 390243830Sdim // Xcode tools to define the default sysroot, by making it the default for 391243830Sdim // isysroot. 392249423Sdim if (const Arg *A = Args.getLastArg(options::OPT_isysroot)) { 393249423Sdim // Warn if the path does not exist. 394263508Sdim if (!llvm::sys::fs::exists(A->getValue())) 395249423Sdim getDriver().Diag(clang::diag::warn_missing_sysroot) << A->getValue(); 396249423Sdim } else { 397243830Sdim if (char *env = ::getenv("SDKROOT")) { 398249423Sdim // We only use this value as the default if it is an absolute path, 399249423Sdim // exists, and it is not the root path. 400249423Sdim if (llvm::sys::path::is_absolute(env) && llvm::sys::fs::exists(env) && 401249423Sdim StringRef(env) != "/") { 402243830Sdim Args.append(Args.MakeSeparateArg( 403243830Sdim 0, Opts.getOption(options::OPT_isysroot), env)); 404243830Sdim } 405243830Sdim } 406243830Sdim } 407243830Sdim 408203955Srdivacky Arg *OSXVersion = Args.getLastArg(options::OPT_mmacosx_version_min_EQ); 409221345Sdim Arg *iOSVersion = Args.getLastArg(options::OPT_miphoneos_version_min_EQ); 410221345Sdim Arg *iOSSimVersion = Args.getLastArg( 411221345Sdim options::OPT_mios_simulator_version_min_EQ); 412224145Sdim 413221345Sdim if (OSXVersion && (iOSVersion || iOSSimVersion)) { 414226633Sdim getDriver().Diag(diag::err_drv_argument_not_allowed_with) 415193326Sed << OSXVersion->getAsString(Args) 416221345Sdim << (iOSVersion ? iOSVersion : iOSSimVersion)->getAsString(Args); 417221345Sdim iOSVersion = iOSSimVersion = 0; 418221345Sdim } else if (iOSVersion && iOSSimVersion) { 419226633Sdim getDriver().Diag(diag::err_drv_argument_not_allowed_with) 420221345Sdim << iOSVersion->getAsString(Args) 421221345Sdim << iOSSimVersion->getAsString(Args); 422221345Sdim iOSSimVersion = 0; 423221345Sdim } else if (!OSXVersion && !iOSVersion && !iOSSimVersion) { 424226633Sdim // If no deployment target was specified on the command line, check for 425203955Srdivacky // environment defines. 426226633Sdim StringRef OSXTarget; 427226633Sdim StringRef iOSTarget; 428226633Sdim StringRef iOSSimTarget; 429226633Sdim if (char *env = ::getenv("MACOSX_DEPLOYMENT_TARGET")) 430226633Sdim OSXTarget = env; 431226633Sdim if (char *env = ::getenv("IPHONEOS_DEPLOYMENT_TARGET")) 432226633Sdim iOSTarget = env; 433226633Sdim if (char *env = ::getenv("IOS_SIMULATOR_DEPLOYMENT_TARGET")) 434226633Sdim iOSSimTarget = env; 435203955Srdivacky 436226633Sdim // If no '-miphoneos-version-min' specified on the command line and 437226633Sdim // IPHONEOS_DEPLOYMENT_TARGET is not defined, see if we can set the default 438234982Sdim // based on -isysroot. 439226633Sdim if (iOSTarget.empty()) { 440226633Sdim if (const Arg *A = Args.getLastArg(options::OPT_isysroot)) { 441226633Sdim StringRef first, second; 442243830Sdim StringRef isysroot = A->getValue(); 443226633Sdim llvm::tie(first, second) = isysroot.split(StringRef("SDKs/iPhoneOS")); 444226633Sdim if (second != "") 445226633Sdim iOSTarget = second.substr(0,3); 446226633Sdim } 447226633Sdim } 448203955Srdivacky 449226633Sdim // If no OSX or iOS target has been specified and we're compiling for armv7, 450226633Sdim // go ahead as assume we're targeting iOS. 451239462Sdim if (OSXTarget.empty() && iOSTarget.empty() && 452243830Sdim (getDarwinArchName(Args) == "armv7" || 453243830Sdim getDarwinArchName(Args) == "armv7s")) 454239462Sdim iOSTarget = iOSVersionMin; 455226633Sdim 456221345Sdim // Handle conflicting deployment targets 457193326Sed // 458203955Srdivacky // FIXME: Don't hardcode default here. 459221345Sdim 460221345Sdim // Do not allow conflicts with the iOS simulator target. 461226633Sdim if (!iOSSimTarget.empty() && (!OSXTarget.empty() || !iOSTarget.empty())) { 462226633Sdim getDriver().Diag(diag::err_drv_conflicting_deployment_targets) 463221345Sdim << "IOS_SIMULATOR_DEPLOYMENT_TARGET" 464226633Sdim << (!OSXTarget.empty() ? "MACOSX_DEPLOYMENT_TARGET" : 465221345Sdim "IPHONEOS_DEPLOYMENT_TARGET"); 466221345Sdim } 467221345Sdim 468221345Sdim // Allow conflicts among OSX and iOS for historical reasons, but choose the 469221345Sdim // default platform. 470226633Sdim if (!OSXTarget.empty() && !iOSTarget.empty()) { 471203955Srdivacky if (getTriple().getArch() == llvm::Triple::arm || 472203955Srdivacky getTriple().getArch() == llvm::Triple::thumb) 473226633Sdim OSXTarget = ""; 474203955Srdivacky else 475226633Sdim iOSTarget = ""; 476203955Srdivacky } 477193326Sed 478226633Sdim if (!OSXTarget.empty()) { 479243830Sdim const Option O = Opts.getOption(options::OPT_mmacosx_version_min_EQ); 480212904Sdim OSXVersion = Args.MakeJoinedArg(0, O, OSXTarget); 481212904Sdim Args.append(OSXVersion); 482226633Sdim } else if (!iOSTarget.empty()) { 483243830Sdim const Option O = Opts.getOption(options::OPT_miphoneos_version_min_EQ); 484221345Sdim iOSVersion = Args.MakeJoinedArg(0, O, iOSTarget); 485221345Sdim Args.append(iOSVersion); 486226633Sdim } else if (!iOSSimTarget.empty()) { 487243830Sdim const Option O = Opts.getOption( 488221345Sdim options::OPT_mios_simulator_version_min_EQ); 489221345Sdim iOSSimVersion = Args.MakeJoinedArg(0, O, iOSSimTarget); 490221345Sdim Args.append(iOSSimVersion); 491198092Srdivacky } else { 492210299Sed // Otherwise, assume we are targeting OS X. 493243830Sdim const Option O = Opts.getOption(options::OPT_mmacosx_version_min_EQ); 494212904Sdim OSXVersion = Args.MakeJoinedArg(0, O, MacosxVersionMin); 495212904Sdim Args.append(OSXVersion); 496198092Srdivacky } 497193326Sed } 498198092Srdivacky 499221345Sdim // Reject invalid architecture combinations. 500221345Sdim if (iOSSimVersion && (getTriple().getArch() != llvm::Triple::x86 && 501221345Sdim getTriple().getArch() != llvm::Triple::x86_64)) { 502226633Sdim getDriver().Diag(diag::err_drv_invalid_arch_for_deployment_target) 503221345Sdim << getTriple().getArchName() << iOSSimVersion->getAsString(Args); 504221345Sdim } 505221345Sdim 506203955Srdivacky // Set the tool chain target information. 507203955Srdivacky unsigned Major, Minor, Micro; 508203955Srdivacky bool HadExtra; 509203955Srdivacky if (OSXVersion) { 510221345Sdim assert((!iOSVersion && !iOSSimVersion) && "Unknown target platform!"); 511243830Sdim if (!Driver::GetReleaseVersion(OSXVersion->getValue(), Major, Minor, 512203955Srdivacky Micro, HadExtra) || HadExtra || 513221345Sdim Major != 10 || Minor >= 100 || Micro >= 100) 514226633Sdim getDriver().Diag(diag::err_drv_invalid_version_number) 515203955Srdivacky << OSXVersion->getAsString(Args); 516203955Srdivacky } else { 517221345Sdim const Arg *Version = iOSVersion ? iOSVersion : iOSSimVersion; 518221345Sdim assert(Version && "Unknown target platform!"); 519243830Sdim if (!Driver::GetReleaseVersion(Version->getValue(), Major, Minor, 520203955Srdivacky Micro, HadExtra) || HadExtra || 521203955Srdivacky Major >= 10 || Minor >= 100 || Micro >= 100) 522226633Sdim getDriver().Diag(diag::err_drv_invalid_version_number) 523221345Sdim << Version->getAsString(Args); 524203955Srdivacky } 525221345Sdim 526221345Sdim bool IsIOSSim = bool(iOSSimVersion); 527221345Sdim 528221345Sdim // In GCC, the simulator historically was treated as being OS X in some 529221345Sdim // contexts, like determining the link logic, despite generally being called 530221345Sdim // with an iOS deployment target. For compatibility, we detect the 531221345Sdim // simulator as iOS + x86, and treat it differently in a few contexts. 532221345Sdim if (iOSVersion && (getTriple().getArch() == llvm::Triple::x86 || 533221345Sdim getTriple().getArch() == llvm::Triple::x86_64)) 534221345Sdim IsIOSSim = true; 535221345Sdim 536221345Sdim setTarget(/*IsIPhoneOS=*/ !OSXVersion, Major, Minor, Micro, IsIOSSim); 537212904Sdim} 538203955Srdivacky 539218893Sdimvoid DarwinClang::AddCXXStdlibLibArgs(const ArgList &Args, 540218893Sdim ArgStringList &CmdArgs) const { 541218893Sdim CXXStdlibType Type = GetCXXStdlibType(Args); 542218893Sdim 543218893Sdim switch (Type) { 544218893Sdim case ToolChain::CST_Libcxx: 545218893Sdim CmdArgs.push_back("-lc++"); 546218893Sdim break; 547218893Sdim 548218893Sdim case ToolChain::CST_Libstdcxx: { 549218893Sdim // Unfortunately, -lstdc++ doesn't always exist in the standard search path; 550218893Sdim // it was previously found in the gcc lib dir. However, for all the Darwin 551218893Sdim // platforms we care about it was -lstdc++.6, so we search for that 552218893Sdim // explicitly if we can't see an obvious -lstdc++ candidate. 553218893Sdim 554218893Sdim // Check in the sysroot first. 555218893Sdim if (const Arg *A = Args.getLastArg(options::OPT_isysroot)) { 556263508Sdim SmallString<128> P(A->getValue()); 557263508Sdim llvm::sys::path::append(P, "usr", "lib", "libstdc++.dylib"); 558218893Sdim 559263508Sdim if (!llvm::sys::fs::exists(P.str())) { 560263508Sdim llvm::sys::path::remove_filename(P); 561263508Sdim llvm::sys::path::append(P, "libstdc++.6.dylib"); 562263508Sdim if (llvm::sys::fs::exists(P.str())) { 563218893Sdim CmdArgs.push_back(Args.MakeArgString(P.str())); 564218893Sdim return; 565218893Sdim } 566218893Sdim } 567218893Sdim } 568218893Sdim 569218893Sdim // Otherwise, look in the root. 570234353Sdim // FIXME: This should be removed someday when we don't have to care about 571234353Sdim // 10.6 and earlier, where /usr/lib/libstdc++.dylib does not exist. 572263508Sdim if (!llvm::sys::fs::exists("/usr/lib/libstdc++.dylib") && 573263508Sdim llvm::sys::fs::exists("/usr/lib/libstdc++.6.dylib")) { 574218893Sdim CmdArgs.push_back("/usr/lib/libstdc++.6.dylib"); 575218893Sdim return; 576218893Sdim } 577218893Sdim 578218893Sdim // Otherwise, let the linker search. 579218893Sdim CmdArgs.push_back("-lstdc++"); 580218893Sdim break; 581218893Sdim } 582218893Sdim } 583218893Sdim} 584218893Sdim 585218893Sdimvoid DarwinClang::AddCCKextLibArgs(const ArgList &Args, 586218893Sdim ArgStringList &CmdArgs) const { 587218893Sdim 588218893Sdim // For Darwin platforms, use the compiler-rt-based support library 589218893Sdim // instead of the gcc-provided one (which is also incidentally 590218893Sdim // only present in the gcc lib dir, which makes it hard to find). 591218893Sdim 592263508Sdim SmallString<128> P(getDriver().ResourceDir); 593263508Sdim llvm::sys::path::append(P, "lib", "darwin"); 594223017Sdim 595243830Sdim // Use the newer cc_kext for iOS ARM after 6.0. 596243830Sdim if (!isTargetIPhoneOS() || isTargetIOSSimulator() || 597243830Sdim !isIPhoneOSVersionLT(6, 0)) { 598263508Sdim llvm::sys::path::append(P, "libclang_rt.cc_kext.a"); 599243830Sdim } else { 600263508Sdim llvm::sys::path::append(P, "libclang_rt.cc_kext_ios5.a"); 601243830Sdim } 602243830Sdim 603218893Sdim // For now, allow missing resource libraries to support developers who may 604218893Sdim // not have compiler-rt checked out or integrated into their build. 605263508Sdim if (llvm::sys::fs::exists(P.str())) 606218893Sdim CmdArgs.push_back(Args.MakeArgString(P.str())); 607218893Sdim} 608218893Sdim 609212904SdimDerivedArgList *Darwin::TranslateArgs(const DerivedArgList &Args, 610212904Sdim const char *BoundArch) const { 611212904Sdim DerivedArgList *DAL = new DerivedArgList(Args.getBaseArgs()); 612212904Sdim const OptTable &Opts = getDriver().getOpts(); 613212904Sdim 614212904Sdim // FIXME: We really want to get out of the tool chain level argument 615212904Sdim // translation business, as it makes the driver functionality much 616212904Sdim // more opaque. For now, we follow gcc closely solely for the 617212904Sdim // purpose of easily achieving feature parity & testability. Once we 618212904Sdim // have something that works, we should reevaluate each translation 619212904Sdim // and try to push it down into tool specific logic. 620212904Sdim 621210299Sed for (ArgList::const_iterator it = Args.begin(), 622210299Sed ie = Args.end(); it != ie; ++it) { 623193326Sed Arg *A = *it; 624193326Sed 625193326Sed if (A->getOption().matches(options::OPT_Xarch__)) { 626224145Sdim // Skip this argument unless the architecture matches either the toolchain 627224145Sdim // triple arch, or the arch being bound. 628243830Sdim llvm::Triple::ArchType XarchArch = 629243830Sdim tools::darwin::getArchTypeForDarwinArchName(A->getValue(0)); 630243830Sdim if (!(XarchArch == getArch() || 631243830Sdim (BoundArch && XarchArch == 632243830Sdim tools::darwin::getArchTypeForDarwinArchName(BoundArch)))) 633193326Sed continue; 634193326Sed 635218893Sdim Arg *OriginalArg = A; 636243830Sdim unsigned Index = Args.getBaseArgs().MakeIndex(A->getValue(1)); 637210299Sed unsigned Prev = Index; 638193326Sed Arg *XarchArg = Opts.ParseOneArg(Args, Index); 639198092Srdivacky 640193326Sed // If the argument parsing failed or more than one argument was 641193326Sed // consumed, the -Xarch_ argument's parameter tried to consume 642193326Sed // extra arguments. Emit an error and ignore. 643193326Sed // 644193326Sed // We also want to disallow any options which would alter the 645193326Sed // driver behavior; that isn't going to work in our model. We 646193326Sed // use isDriverOption() as an approximation, although things 647193326Sed // like -O4 are going to slip through. 648221345Sdim if (!XarchArg || Index > Prev + 1) { 649226633Sdim getDriver().Diag(diag::err_drv_invalid_Xarch_argument_with_args) 650193326Sed << A->getAsString(Args); 651193326Sed continue; 652243830Sdim } else if (XarchArg->getOption().hasFlag(options::DriverOption)) { 653226633Sdim getDriver().Diag(diag::err_drv_invalid_Xarch_argument_isdriver) 654221345Sdim << A->getAsString(Args); 655221345Sdim continue; 656193326Sed } 657193326Sed 658193326Sed XarchArg->setBaseArg(A); 659193326Sed A = XarchArg; 660210299Sed 661210299Sed DAL->AddSynthesizedArg(A); 662218893Sdim 663218893Sdim // Linker input arguments require custom handling. The problem is that we 664218893Sdim // have already constructed the phase actions, so we can not treat them as 665218893Sdim // "input arguments". 666243830Sdim if (A->getOption().hasFlag(options::LinkerInput)) { 667218893Sdim // Convert the argument into individual Zlinker_input_args. 668218893Sdim for (unsigned i = 0, e = A->getNumValues(); i != e; ++i) { 669218893Sdim DAL->AddSeparateArg(OriginalArg, 670218893Sdim Opts.getOption(options::OPT_Zlinker_input), 671243830Sdim A->getValue(i)); 672223017Sdim 673218893Sdim } 674218893Sdim continue; 675218893Sdim } 676198092Srdivacky } 677193326Sed 678193326Sed // Sob. These is strictly gcc compatible for the time being. Apple 679193326Sed // gcc translates options twice, which means that self-expanding 680193326Sed // options add duplicates. 681199512Srdivacky switch ((options::ID) A->getOption().getID()) { 682193326Sed default: 683193326Sed DAL->append(A); 684193326Sed break; 685193326Sed 686193326Sed case options::OPT_mkernel: 687193326Sed case options::OPT_fapple_kext: 688193326Sed DAL->append(A); 689210299Sed DAL->AddFlagArg(A, Opts.getOption(options::OPT_static)); 690193326Sed break; 691198092Srdivacky 692193326Sed case options::OPT_dependency_file: 693210299Sed DAL->AddSeparateArg(A, Opts.getOption(options::OPT_MF), 694243830Sdim A->getValue()); 695193326Sed break; 696193326Sed 697193326Sed case options::OPT_gfull: 698210299Sed DAL->AddFlagArg(A, Opts.getOption(options::OPT_g_Flag)); 699210299Sed DAL->AddFlagArg(A, 700210299Sed Opts.getOption(options::OPT_fno_eliminate_unused_debug_symbols)); 701193326Sed break; 702193326Sed 703193326Sed case options::OPT_gused: 704210299Sed DAL->AddFlagArg(A, Opts.getOption(options::OPT_g_Flag)); 705210299Sed DAL->AddFlagArg(A, 706210299Sed Opts.getOption(options::OPT_feliminate_unused_debug_symbols)); 707193326Sed break; 708193326Sed 709193326Sed case options::OPT_shared: 710210299Sed DAL->AddFlagArg(A, Opts.getOption(options::OPT_dynamiclib)); 711193326Sed break; 712193326Sed 713193326Sed case options::OPT_fconstant_cfstrings: 714210299Sed DAL->AddFlagArg(A, Opts.getOption(options::OPT_mconstant_cfstrings)); 715193326Sed break; 716193326Sed 717193326Sed case options::OPT_fno_constant_cfstrings: 718210299Sed DAL->AddFlagArg(A, Opts.getOption(options::OPT_mno_constant_cfstrings)); 719193326Sed break; 720193326Sed 721193326Sed case options::OPT_Wnonportable_cfstrings: 722210299Sed DAL->AddFlagArg(A, 723210299Sed Opts.getOption(options::OPT_mwarn_nonportable_cfstrings)); 724193326Sed break; 725193326Sed 726193326Sed case options::OPT_Wno_nonportable_cfstrings: 727210299Sed DAL->AddFlagArg(A, 728210299Sed Opts.getOption(options::OPT_mno_warn_nonportable_cfstrings)); 729193326Sed break; 730193326Sed 731193326Sed case options::OPT_fpascal_strings: 732210299Sed DAL->AddFlagArg(A, Opts.getOption(options::OPT_mpascal_strings)); 733193326Sed break; 734193326Sed 735193326Sed case options::OPT_fno_pascal_strings: 736210299Sed DAL->AddFlagArg(A, Opts.getOption(options::OPT_mno_pascal_strings)); 737193326Sed break; 738193326Sed } 739193326Sed } 740193326Sed 741198092Srdivacky if (getTriple().getArch() == llvm::Triple::x86 || 742198092Srdivacky getTriple().getArch() == llvm::Triple::x86_64) 743199512Srdivacky if (!Args.hasArgNoClaim(options::OPT_mtune_EQ)) 744210299Sed DAL->AddJoinedArg(0, Opts.getOption(options::OPT_mtune_EQ), "core2"); 745198092Srdivacky 746198092Srdivacky // Add the arch options based on the particular spelling of -arch, to match 747198092Srdivacky // how the driver driver works. 748198092Srdivacky if (BoundArch) { 749226633Sdim StringRef Name = BoundArch; 750243830Sdim const Option MCpu = Opts.getOption(options::OPT_mcpu_EQ); 751243830Sdim const Option MArch = Opts.getOption(options::OPT_march_EQ); 752198092Srdivacky 753198092Srdivacky // This code must be kept in sync with LLVM's getArchTypeForDarwinArch, 754198092Srdivacky // which defines the list of which architectures we accept. 755198092Srdivacky if (Name == "ppc") 756198092Srdivacky ; 757198092Srdivacky else if (Name == "ppc601") 758210299Sed DAL->AddJoinedArg(0, MCpu, "601"); 759198092Srdivacky else if (Name == "ppc603") 760210299Sed DAL->AddJoinedArg(0, MCpu, "603"); 761198092Srdivacky else if (Name == "ppc604") 762210299Sed DAL->AddJoinedArg(0, MCpu, "604"); 763198092Srdivacky else if (Name == "ppc604e") 764210299Sed DAL->AddJoinedArg(0, MCpu, "604e"); 765198092Srdivacky else if (Name == "ppc750") 766210299Sed DAL->AddJoinedArg(0, MCpu, "750"); 767198092Srdivacky else if (Name == "ppc7400") 768210299Sed DAL->AddJoinedArg(0, MCpu, "7400"); 769198092Srdivacky else if (Name == "ppc7450") 770210299Sed DAL->AddJoinedArg(0, MCpu, "7450"); 771198092Srdivacky else if (Name == "ppc970") 772210299Sed DAL->AddJoinedArg(0, MCpu, "970"); 773198092Srdivacky 774263508Sdim else if (Name == "ppc64" || Name == "ppc64le") 775210299Sed DAL->AddFlagArg(0, Opts.getOption(options::OPT_m64)); 776193326Sed 777198092Srdivacky else if (Name == "i386") 778198092Srdivacky ; 779198092Srdivacky else if (Name == "i486") 780210299Sed DAL->AddJoinedArg(0, MArch, "i486"); 781198092Srdivacky else if (Name == "i586") 782210299Sed DAL->AddJoinedArg(0, MArch, "i586"); 783198092Srdivacky else if (Name == "i686") 784210299Sed DAL->AddJoinedArg(0, MArch, "i686"); 785198092Srdivacky else if (Name == "pentium") 786210299Sed DAL->AddJoinedArg(0, MArch, "pentium"); 787198092Srdivacky else if (Name == "pentium2") 788210299Sed DAL->AddJoinedArg(0, MArch, "pentium2"); 789198092Srdivacky else if (Name == "pentpro") 790210299Sed DAL->AddJoinedArg(0, MArch, "pentiumpro"); 791198092Srdivacky else if (Name == "pentIIm3") 792210299Sed DAL->AddJoinedArg(0, MArch, "pentium2"); 793193326Sed 794198092Srdivacky else if (Name == "x86_64") 795210299Sed DAL->AddFlagArg(0, Opts.getOption(options::OPT_m64)); 796263508Sdim else if (Name == "x86_64h") { 797263508Sdim DAL->AddFlagArg(0, Opts.getOption(options::OPT_m64)); 798263508Sdim DAL->AddJoinedArg(0, MArch, "x86_64h"); 799263508Sdim } 800198092Srdivacky 801198092Srdivacky else if (Name == "arm") 802210299Sed DAL->AddJoinedArg(0, MArch, "armv4t"); 803198092Srdivacky else if (Name == "armv4t") 804210299Sed DAL->AddJoinedArg(0, MArch, "armv4t"); 805198092Srdivacky else if (Name == "armv5") 806210299Sed DAL->AddJoinedArg(0, MArch, "armv5tej"); 807198092Srdivacky else if (Name == "xscale") 808210299Sed DAL->AddJoinedArg(0, MArch, "xscale"); 809198092Srdivacky else if (Name == "armv6") 810210299Sed DAL->AddJoinedArg(0, MArch, "armv6k"); 811249423Sdim else if (Name == "armv6m") 812249423Sdim DAL->AddJoinedArg(0, MArch, "armv6m"); 813198092Srdivacky else if (Name == "armv7") 814210299Sed DAL->AddJoinedArg(0, MArch, "armv7a"); 815249423Sdim else if (Name == "armv7em") 816249423Sdim DAL->AddJoinedArg(0, MArch, "armv7em"); 817243830Sdim else if (Name == "armv7f") 818243830Sdim DAL->AddJoinedArg(0, MArch, "armv7f"); 819243830Sdim else if (Name == "armv7k") 820243830Sdim DAL->AddJoinedArg(0, MArch, "armv7k"); 821249423Sdim else if (Name == "armv7m") 822249423Sdim DAL->AddJoinedArg(0, MArch, "armv7m"); 823243830Sdim else if (Name == "armv7s") 824243830Sdim DAL->AddJoinedArg(0, MArch, "armv7s"); 825198092Srdivacky 826198092Srdivacky else 827200583Srdivacky llvm_unreachable("invalid Darwin arch"); 828198092Srdivacky } 829198092Srdivacky 830212904Sdim // Add an explicit version min argument for the deployment target. We do this 831212904Sdim // after argument translation because -Xarch_ arguments may add a version min 832212904Sdim // argument. 833239462Sdim if (BoundArch) 834239462Sdim AddDeploymentTarget(*DAL); 835212904Sdim 836243830Sdim // For iOS 6, undo the translation to add -static for -mkernel/-fapple-kext. 837243830Sdim // FIXME: It would be far better to avoid inserting those -static arguments, 838243830Sdim // but we can't check the deployment target in the translation code until 839243830Sdim // it is set here. 840243830Sdim if (isTargetIPhoneOS() && !isIPhoneOSVersionLT(6, 0)) { 841243830Sdim for (ArgList::iterator it = DAL->begin(), ie = DAL->end(); it != ie; ) { 842243830Sdim Arg *A = *it; 843243830Sdim ++it; 844243830Sdim if (A->getOption().getID() != options::OPT_mkernel && 845243830Sdim A->getOption().getID() != options::OPT_fapple_kext) 846243830Sdim continue; 847243830Sdim assert(it != ie && "unexpected argument translation"); 848243830Sdim A = *it; 849243830Sdim assert(A->getOption().getID() == options::OPT_static && 850243830Sdim "missing expected -static argument"); 851243830Sdim it = DAL->getArgs().erase(it); 852243830Sdim } 853243830Sdim } 854243830Sdim 855263508Sdim // Default to use libc++ on OS X 10.9+ and iOS 7+. 856263508Sdim if (((isTargetMacOS() && !isMacosxVersionLT(10, 9)) || 857263508Sdim (isTargetIPhoneOS() && !isIPhoneOSVersionLT(7, 0))) && 858263508Sdim !Args.getLastArg(options::OPT_stdlib_EQ)) 859263508Sdim DAL->AddJoinedArg(0, Opts.getOption(options::OPT_stdlib_EQ), "libc++"); 860263508Sdim 861226633Sdim // Validate the C++ standard library choice. 862226633Sdim CXXStdlibType Type = GetCXXStdlibType(*DAL); 863226633Sdim if (Type == ToolChain::CST_Libcxx) { 864239462Sdim // Check whether the target provides libc++. 865239462Sdim StringRef where; 866239462Sdim 867239462Sdim // Complain about targetting iOS < 5.0 in any way. 868243830Sdim if (isTargetIPhoneOS() && isIPhoneOSVersionLT(5, 0)) 869243830Sdim where = "iOS 5.0"; 870239462Sdim 871239462Sdim if (where != StringRef()) { 872226633Sdim getDriver().Diag(clang::diag::err_drv_invalid_libcxx_deployment) 873239462Sdim << where; 874226633Sdim } 875226633Sdim } 876226633Sdim 877193326Sed return DAL; 878198092Srdivacky} 879193326Sed 880198092Srdivackybool Darwin::IsUnwindTablesDefault() const { 881243830Sdim return getArch() == llvm::Triple::x86_64; 882193326Sed} 883193326Sed 884201361Srdivackybool Darwin::UseDwarfDebugFlags() const { 885201361Srdivacky if (const char *S = ::getenv("RC_DEBUG_OPTIONS")) 886201361Srdivacky return S[0] != '\0'; 887201361Srdivacky return false; 888201361Srdivacky} 889201361Srdivacky 890203955Srdivackybool Darwin::UseSjLjExceptions() const { 891203955Srdivacky // Darwin uses SjLj exceptions on ARM. 892203955Srdivacky return (getTriple().getArch() == llvm::Triple::arm || 893203955Srdivacky getTriple().getArch() == llvm::Triple::thumb); 894203955Srdivacky} 895203955Srdivacky 896243830Sdimbool Darwin::isPICDefault() const { 897243830Sdim return true; 898193326Sed} 899193326Sed 900251662Sdimbool Darwin::isPIEDefault() const { 901251662Sdim return false; 902251662Sdim} 903251662Sdim 904243830Sdimbool Darwin::isPICDefaultForced() const { 905243830Sdim return getArch() == llvm::Triple::x86_64; 906193326Sed} 907193326Sed 908221345Sdimbool Darwin::SupportsProfiling() const { 909221345Sdim // Profiling instrumentation is only supported on x86. 910243830Sdim return getArch() == llvm::Triple::x86 || getArch() == llvm::Triple::x86_64; 911221345Sdim} 912221345Sdim 913207619Srdivackybool Darwin::SupportsObjCGC() const { 914207619Srdivacky // Garbage collection is supported everywhere except on iPhone OS. 915207619Srdivacky return !isTargetIPhoneOS(); 916207619Srdivacky} 917207619Srdivacky 918243830Sdimvoid Darwin::CheckObjCARC() const { 919243830Sdim if (isTargetIPhoneOS() || !isMacosxVersionLT(10, 6)) 920243830Sdim return; 921243830Sdim getDriver().Diag(diag::err_arc_unsupported_on_toolchain); 922234353Sdim} 923234353Sdim 924212904Sdimstd::string 925226633SdimDarwin_Generic_GCC::ComputeEffectiveClangTriple(const ArgList &Args, 926226633Sdim types::ID InputType) const { 927226633Sdim return ComputeLLVMTriple(Args, InputType); 928212904Sdim} 929212904Sdim 930193326Sed/// Generic_GCC - A tool chain using the 'gcc' command to perform 931193326Sed/// all subcommands; this relies on gcc translating the majority of 932193326Sed/// command line options. 933193326Sed 934234353Sdim/// \brief Parse a GCCVersion object out of a string of text. 935234353Sdim/// 936234353Sdim/// This is the primary means of forming GCCVersion objects. 937234353Sdim/*static*/ 938234353SdimGeneric_GCC::GCCVersion Linux::GCCVersion::Parse(StringRef VersionText) { 939263508Sdim const GCCVersion BadVersion = { VersionText.str(), -1, -1, -1, "", "", "" }; 940234353Sdim std::pair<StringRef, StringRef> First = VersionText.split('.'); 941234353Sdim std::pair<StringRef, StringRef> Second = First.second.split('.'); 942234353Sdim 943263508Sdim GCCVersion GoodVersion = { VersionText.str(), -1, -1, -1, "", "", "" }; 944234353Sdim if (First.first.getAsInteger(10, GoodVersion.Major) || 945234353Sdim GoodVersion.Major < 0) 946234353Sdim return BadVersion; 947263508Sdim GoodVersion.MajorStr = First.first.str(); 948234353Sdim if (Second.first.getAsInteger(10, GoodVersion.Minor) || 949234353Sdim GoodVersion.Minor < 0) 950234353Sdim return BadVersion; 951263508Sdim GoodVersion.MinorStr = Second.first.str(); 952234353Sdim 953234353Sdim // First look for a number prefix and parse that if present. Otherwise just 954234353Sdim // stash the entire patch string in the suffix, and leave the number 955234353Sdim // unspecified. This covers versions strings such as: 956234353Sdim // 4.4 957234353Sdim // 4.4.0 958234353Sdim // 4.4.x 959234353Sdim // 4.4.2-rc4 960234353Sdim // 4.4.x-patched 961234353Sdim // And retains any patch number it finds. 962234353Sdim StringRef PatchText = GoodVersion.PatchSuffix = Second.second.str(); 963234353Sdim if (!PatchText.empty()) { 964249423Sdim if (size_t EndNumber = PatchText.find_first_not_of("0123456789")) { 965234353Sdim // Try to parse the number and any suffix. 966234353Sdim if (PatchText.slice(0, EndNumber).getAsInteger(10, GoodVersion.Patch) || 967234353Sdim GoodVersion.Patch < 0) 968234353Sdim return BadVersion; 969263508Sdim GoodVersion.PatchSuffix = PatchText.substr(EndNumber); 970234353Sdim } 971234353Sdim } 972234353Sdim 973234353Sdim return GoodVersion; 974234353Sdim} 975234353Sdim 976234353Sdim/// \brief Less-than for GCCVersion, implementing a Strict Weak Ordering. 977263508Sdimbool Generic_GCC::GCCVersion::isOlderThan(int RHSMajor, int RHSMinor, 978263508Sdim int RHSPatch, 979263508Sdim StringRef RHSPatchSuffix) const { 980263508Sdim if (Major != RHSMajor) 981263508Sdim return Major < RHSMajor; 982263508Sdim if (Minor != RHSMinor) 983263508Sdim return Minor < RHSMinor; 984263508Sdim if (Patch != RHSPatch) { 985249423Sdim // Note that versions without a specified patch sort higher than those with 986249423Sdim // a patch. 987263508Sdim if (RHSPatch == -1) 988249423Sdim return true; 989249423Sdim if (Patch == -1) 990249423Sdim return false; 991234353Sdim 992249423Sdim // Otherwise just sort on the patch itself. 993263508Sdim return Patch < RHSPatch; 994249423Sdim } 995263508Sdim if (PatchSuffix != RHSPatchSuffix) { 996249423Sdim // Sort empty suffixes higher. 997263508Sdim if (RHSPatchSuffix.empty()) 998249423Sdim return true; 999249423Sdim if (PatchSuffix.empty()) 1000249423Sdim return false; 1001234353Sdim 1002249423Sdim // Provide a lexicographic sort to make this a total ordering. 1003263508Sdim return PatchSuffix < RHSPatchSuffix; 1004249423Sdim } 1005249423Sdim 1006249423Sdim // The versions are equal. 1007234353Sdim return false; 1008234353Sdim} 1009234353Sdim 1010234353Sdimstatic StringRef getGCCToolchainDir(const ArgList &Args) { 1011234353Sdim const Arg *A = Args.getLastArg(options::OPT_gcc_toolchain); 1012234353Sdim if (A) 1013243830Sdim return A->getValue(); 1014234353Sdim return GCC_INSTALL_PREFIX; 1015234353Sdim} 1016234353Sdim 1017259157Sdim/// \brief Initialize a GCCInstallationDetector from the driver. 1018234353Sdim/// 1019234353Sdim/// This performs all of the autodetection and sets up the various paths. 1020234982Sdim/// Once constructed, a GCCInstallationDetector is essentially immutable. 1021234353Sdim/// 1022234353Sdim/// FIXME: We shouldn't need an explicit TargetTriple parameter here, and 1023234353Sdim/// should instead pull the target out of the driver. This is currently 1024234353Sdim/// necessary because the driver doesn't store the final version of the target 1025234353Sdim/// triple. 1026259157Sdimvoid 1027259157SdimGeneric_GCC::GCCInstallationDetector::init( 1028263508Sdim const llvm::Triple &TargetTriple, const ArgList &Args) { 1029263508Sdim llvm::Triple BiarchVariantTriple = 1030263508Sdim TargetTriple.isArch32Bit() ? TargetTriple.get64BitArchVariant() 1031234353Sdim : TargetTriple.get32BitArchVariant(); 1032234353Sdim llvm::Triple::ArchType TargetArch = TargetTriple.getArch(); 1033234353Sdim // The library directories which may contain GCC installations. 1034263508Sdim SmallVector<StringRef, 4> CandidateLibDirs, CandidateBiarchLibDirs; 1035234353Sdim // The compatible GCC triples for this particular architecture. 1036234353Sdim SmallVector<StringRef, 10> CandidateTripleAliases; 1037263508Sdim SmallVector<StringRef, 10> CandidateBiarchTripleAliases; 1038263508Sdim CollectLibDirsAndTriples(TargetTriple, BiarchVariantTriple, CandidateLibDirs, 1039263508Sdim CandidateTripleAliases, CandidateBiarchLibDirs, 1040263508Sdim CandidateBiarchTripleAliases); 1041234353Sdim 1042234353Sdim // Compute the set of prefixes for our search. 1043234353Sdim SmallVector<std::string, 8> Prefixes(D.PrefixDirs.begin(), 1044234353Sdim D.PrefixDirs.end()); 1045234353Sdim 1046234353Sdim StringRef GCCToolchainDir = getGCCToolchainDir(Args); 1047234353Sdim if (GCCToolchainDir != "") { 1048234353Sdim if (GCCToolchainDir.back() == '/') 1049234353Sdim GCCToolchainDir = GCCToolchainDir.drop_back(); // remove the / 1050234353Sdim 1051234353Sdim Prefixes.push_back(GCCToolchainDir); 1052234353Sdim } else { 1053263508Sdim // If we have a SysRoot, try that first. 1054263508Sdim if (!D.SysRoot.empty()) { 1055263508Sdim Prefixes.push_back(D.SysRoot); 1056263508Sdim Prefixes.push_back(D.SysRoot + "/usr"); 1057263508Sdim } 1058263508Sdim 1059263508Sdim // Then look for gcc installed alongside clang. 1060234353Sdim Prefixes.push_back(D.InstalledDir + "/.."); 1061263508Sdim 1062263508Sdim // And finally in /usr. 1063263508Sdim if (D.SysRoot.empty()) 1064263508Sdim Prefixes.push_back("/usr"); 1065234353Sdim } 1066234353Sdim 1067234353Sdim // Loop over the various components which exist and select the best GCC 1068234353Sdim // installation available. GCC installs are ranked by version number. 1069234353Sdim Version = GCCVersion::Parse("0.0.0"); 1070234353Sdim for (unsigned i = 0, ie = Prefixes.size(); i < ie; ++i) { 1071234353Sdim if (!llvm::sys::fs::exists(Prefixes[i])) 1072234353Sdim continue; 1073234353Sdim for (unsigned j = 0, je = CandidateLibDirs.size(); j < je; ++j) { 1074234353Sdim const std::string LibDir = Prefixes[i] + CandidateLibDirs[j].str(); 1075234353Sdim if (!llvm::sys::fs::exists(LibDir)) 1076234353Sdim continue; 1077234353Sdim for (unsigned k = 0, ke = CandidateTripleAliases.size(); k < ke; ++k) 1078243830Sdim ScanLibDirForGCCTriple(TargetArch, Args, LibDir, 1079243830Sdim CandidateTripleAliases[k]); 1080234353Sdim } 1081263508Sdim for (unsigned j = 0, je = CandidateBiarchLibDirs.size(); j < je; ++j) { 1082263508Sdim const std::string LibDir = Prefixes[i] + CandidateBiarchLibDirs[j].str(); 1083234353Sdim if (!llvm::sys::fs::exists(LibDir)) 1084234353Sdim continue; 1085263508Sdim for (unsigned k = 0, ke = CandidateBiarchTripleAliases.size(); k < ke; 1086234353Sdim ++k) 1087243830Sdim ScanLibDirForGCCTriple(TargetArch, Args, LibDir, 1088263508Sdim CandidateBiarchTripleAliases[k], 1089263508Sdim /*NeedsBiarchSuffix=*/ true); 1090234353Sdim } 1091234353Sdim } 1092234353Sdim} 1093234353Sdim 1094263508Sdimvoid Generic_GCC::GCCInstallationDetector::print(raw_ostream &OS) const { 1095263508Sdim for (std::set<std::string>::const_iterator 1096263508Sdim I = CandidateGCCInstallPaths.begin(), 1097263508Sdim E = CandidateGCCInstallPaths.end(); 1098263508Sdim I != E; ++I) 1099263508Sdim OS << "Found candidate GCC installation: " << *I << "\n"; 1100263508Sdim 1101263508Sdim OS << "Selected GCC installation: " << GCCInstallPath << "\n"; 1102263508Sdim} 1103263508Sdim 1104234353Sdim/*static*/ void Generic_GCC::GCCInstallationDetector::CollectLibDirsAndTriples( 1105263508Sdim const llvm::Triple &TargetTriple, const llvm::Triple &BiarchTriple, 1106234353Sdim SmallVectorImpl<StringRef> &LibDirs, 1107234353Sdim SmallVectorImpl<StringRef> &TripleAliases, 1108263508Sdim SmallVectorImpl<StringRef> &BiarchLibDirs, 1109263508Sdim SmallVectorImpl<StringRef> &BiarchTripleAliases) { 1110234353Sdim // Declare a bunch of static data sets that we'll select between below. These 1111234353Sdim // are specifically designed to always refer to string literals to avoid any 1112234353Sdim // lifetime or initialization issues. 1113249423Sdim static const char *const AArch64LibDirs[] = { "/lib" }; 1114263508Sdim static const char *const AArch64Triples[] = { "aarch64-none-linux-gnu", 1115263508Sdim "aarch64-linux-gnu" }; 1116249423Sdim 1117234353Sdim static const char *const ARMLibDirs[] = { "/lib" }; 1118263508Sdim static const char *const ARMTriples[] = { "arm-linux-gnueabi", 1119263508Sdim "arm-linux-androideabi" }; 1120263508Sdim static const char *const ARMHFTriples[] = { "arm-linux-gnueabihf", 1121263508Sdim "armv7hl-redhat-linux-gnueabi" }; 1122234353Sdim 1123234353Sdim static const char *const X86_64LibDirs[] = { "/lib64", "/lib" }; 1124234353Sdim static const char *const X86_64Triples[] = { 1125263508Sdim "x86_64-linux-gnu", "x86_64-unknown-linux-gnu", "x86_64-pc-linux-gnu", 1126263508Sdim "x86_64-redhat-linux6E", "x86_64-redhat-linux", "x86_64-suse-linux", 1127263508Sdim "x86_64-manbo-linux-gnu", "x86_64-linux-gnu", "x86_64-slackware-linux" 1128234353Sdim }; 1129234353Sdim static const char *const X86LibDirs[] = { "/lib32", "/lib" }; 1130234353Sdim static const char *const X86Triples[] = { 1131263508Sdim "i686-linux-gnu", "i686-pc-linux-gnu", "i486-linux-gnu", "i386-linux-gnu", 1132263508Sdim "i386-redhat-linux6E", "i686-redhat-linux", "i586-redhat-linux", 1133263508Sdim "i386-redhat-linux", "i586-suse-linux", "i486-slackware-linux", 1134239462Sdim "i686-montavista-linux" 1135234353Sdim }; 1136234353Sdim 1137234353Sdim static const char *const MIPSLibDirs[] = { "/lib" }; 1138263508Sdim static const char *const MIPSTriples[] = { "mips-linux-gnu", 1139263508Sdim "mips-mti-linux-gnu" }; 1140234353Sdim static const char *const MIPSELLibDirs[] = { "/lib" }; 1141263508Sdim static const char *const MIPSELTriples[] = { "mipsel-linux-gnu", 1142263508Sdim "mipsel-linux-android" }; 1143234353Sdim 1144239462Sdim static const char *const MIPS64LibDirs[] = { "/lib64", "/lib" }; 1145263508Sdim static const char *const MIPS64Triples[] = { "mips64-linux-gnu", 1146263508Sdim "mips-mti-linux-gnu" }; 1147239462Sdim static const char *const MIPS64ELLibDirs[] = { "/lib64", "/lib" }; 1148263508Sdim static const char *const MIPS64ELTriples[] = { "mips64el-linux-gnu", 1149263508Sdim "mips-mti-linux-gnu" }; 1150239462Sdim 1151234353Sdim static const char *const PPCLibDirs[] = { "/lib32", "/lib" }; 1152234353Sdim static const char *const PPCTriples[] = { 1153263508Sdim "powerpc-linux-gnu", "powerpc-unknown-linux-gnu", "powerpc-linux-gnuspe", 1154263508Sdim "powerpc-suse-linux", "powerpc-montavista-linuxspe" 1155234353Sdim }; 1156234353Sdim static const char *const PPC64LibDirs[] = { "/lib64", "/lib" }; 1157263508Sdim static const char *const PPC64Triples[] = { "powerpc64-linux-gnu", 1158263508Sdim "powerpc64-unknown-linux-gnu", 1159263508Sdim "powerpc64-suse-linux", 1160263508Sdim "ppc64-redhat-linux" }; 1161263508Sdim static const char *const PPC64LELibDirs[] = { "/lib64", "/lib" }; 1162263508Sdim static const char *const PPC64LETriples[] = { "powerpc64le-linux-gnu", 1163263508Sdim "powerpc64le-unknown-linux-gnu", 1164263508Sdim "powerpc64le-suse-linux", 1165263508Sdim "ppc64le-redhat-linux" }; 1166234353Sdim 1167263763Sdim static const char *const SPARCv8LibDirs[] = { "/lib32", "/lib" }; 1168263763Sdim static const char *const SPARCv8Triples[] = { "sparc-linux-gnu", 1169263763Sdim "sparcv8-linux-gnu" }; 1170263763Sdim static const char *const SPARCv9LibDirs[] = { "/lib64", "/lib" }; 1171263763Sdim static const char *const SPARCv9Triples[] = { "sparc64-linux-gnu", 1172263763Sdim "sparcv9-linux-gnu" }; 1173263763Sdim 1174251662Sdim static const char *const SystemZLibDirs[] = { "/lib64", "/lib" }; 1175251662Sdim static const char *const SystemZTriples[] = { 1176263508Sdim "s390x-linux-gnu", "s390x-unknown-linux-gnu", "s390x-ibm-linux-gnu", 1177263508Sdim "s390x-suse-linux", "s390x-redhat-linux" 1178251662Sdim }; 1179251662Sdim 1180234353Sdim switch (TargetTriple.getArch()) { 1181249423Sdim case llvm::Triple::aarch64: 1182263508Sdim LibDirs.append(AArch64LibDirs, 1183263508Sdim AArch64LibDirs + llvm::array_lengthof(AArch64LibDirs)); 1184263508Sdim TripleAliases.append(AArch64Triples, 1185263508Sdim AArch64Triples + llvm::array_lengthof(AArch64Triples)); 1186263508Sdim BiarchLibDirs.append(AArch64LibDirs, 1187263508Sdim AArch64LibDirs + llvm::array_lengthof(AArch64LibDirs)); 1188263508Sdim BiarchTripleAliases.append( 1189263508Sdim AArch64Triples, AArch64Triples + llvm::array_lengthof(AArch64Triples)); 1190249423Sdim break; 1191234353Sdim case llvm::Triple::arm: 1192234353Sdim case llvm::Triple::thumb: 1193234353Sdim LibDirs.append(ARMLibDirs, ARMLibDirs + llvm::array_lengthof(ARMLibDirs)); 1194239462Sdim if (TargetTriple.getEnvironment() == llvm::Triple::GNUEABIHF) { 1195263508Sdim TripleAliases.append(ARMHFTriples, 1196263508Sdim ARMHFTriples + llvm::array_lengthof(ARMHFTriples)); 1197239462Sdim } else { 1198263508Sdim TripleAliases.append(ARMTriples, 1199263508Sdim ARMTriples + llvm::array_lengthof(ARMTriples)); 1200239462Sdim } 1201234353Sdim break; 1202234353Sdim case llvm::Triple::x86_64: 1203263508Sdim LibDirs.append(X86_64LibDirs, 1204263508Sdim X86_64LibDirs + llvm::array_lengthof(X86_64LibDirs)); 1205263508Sdim TripleAliases.append(X86_64Triples, 1206263508Sdim X86_64Triples + llvm::array_lengthof(X86_64Triples)); 1207263508Sdim BiarchLibDirs.append(X86LibDirs, 1208263508Sdim X86LibDirs + llvm::array_lengthof(X86LibDirs)); 1209263508Sdim BiarchTripleAliases.append(X86Triples, 1210263508Sdim X86Triples + llvm::array_lengthof(X86Triples)); 1211234353Sdim break; 1212234353Sdim case llvm::Triple::x86: 1213234353Sdim LibDirs.append(X86LibDirs, X86LibDirs + llvm::array_lengthof(X86LibDirs)); 1214263508Sdim TripleAliases.append(X86Triples, 1215263508Sdim X86Triples + llvm::array_lengthof(X86Triples)); 1216263508Sdim BiarchLibDirs.append(X86_64LibDirs, 1217263508Sdim X86_64LibDirs + llvm::array_lengthof(X86_64LibDirs)); 1218263508Sdim BiarchTripleAliases.append( 1219263508Sdim X86_64Triples, X86_64Triples + llvm::array_lengthof(X86_64Triples)); 1220234353Sdim break; 1221234353Sdim case llvm::Triple::mips: 1222263508Sdim LibDirs.append(MIPSLibDirs, 1223263508Sdim MIPSLibDirs + llvm::array_lengthof(MIPSLibDirs)); 1224263508Sdim TripleAliases.append(MIPSTriples, 1225263508Sdim MIPSTriples + llvm::array_lengthof(MIPSTriples)); 1226263508Sdim BiarchLibDirs.append(MIPS64LibDirs, 1227263508Sdim MIPS64LibDirs + llvm::array_lengthof(MIPS64LibDirs)); 1228263508Sdim BiarchTripleAliases.append( 1229263508Sdim MIPS64Triples, MIPS64Triples + llvm::array_lengthof(MIPS64Triples)); 1230234353Sdim break; 1231234353Sdim case llvm::Triple::mipsel: 1232263508Sdim LibDirs.append(MIPSELLibDirs, 1233263508Sdim MIPSELLibDirs + llvm::array_lengthof(MIPSELLibDirs)); 1234263508Sdim TripleAliases.append(MIPSELTriples, 1235263508Sdim MIPSELTriples + llvm::array_lengthof(MIPSELTriples)); 1236263508Sdim TripleAliases.append(MIPSTriples, 1237263508Sdim MIPSTriples + llvm::array_lengthof(MIPSTriples)); 1238263508Sdim BiarchLibDirs.append( 1239263508Sdim MIPS64ELLibDirs, 1240263508Sdim MIPS64ELLibDirs + llvm::array_lengthof(MIPS64ELLibDirs)); 1241263508Sdim BiarchTripleAliases.append( 1242263508Sdim MIPS64ELTriples, 1243263508Sdim MIPS64ELTriples + llvm::array_lengthof(MIPS64ELTriples)); 1244234353Sdim break; 1245239462Sdim case llvm::Triple::mips64: 1246263508Sdim LibDirs.append(MIPS64LibDirs, 1247263508Sdim MIPS64LibDirs + llvm::array_lengthof(MIPS64LibDirs)); 1248263508Sdim TripleAliases.append(MIPS64Triples, 1249263508Sdim MIPS64Triples + llvm::array_lengthof(MIPS64Triples)); 1250263508Sdim BiarchLibDirs.append(MIPSLibDirs, 1251263508Sdim MIPSLibDirs + llvm::array_lengthof(MIPSLibDirs)); 1252263508Sdim BiarchTripleAliases.append(MIPSTriples, 1253263508Sdim MIPSTriples + llvm::array_lengthof(MIPSTriples)); 1254239462Sdim break; 1255239462Sdim case llvm::Triple::mips64el: 1256263508Sdim LibDirs.append(MIPS64ELLibDirs, 1257263508Sdim MIPS64ELLibDirs + llvm::array_lengthof(MIPS64ELLibDirs)); 1258239462Sdim TripleAliases.append( 1259263508Sdim MIPS64ELTriples, 1260263508Sdim MIPS64ELTriples + llvm::array_lengthof(MIPS64ELTriples)); 1261263508Sdim BiarchLibDirs.append(MIPSELLibDirs, 1262263508Sdim MIPSELLibDirs + llvm::array_lengthof(MIPSELLibDirs)); 1263263508Sdim BiarchTripleAliases.append( 1264263508Sdim MIPSELTriples, MIPSELTriples + llvm::array_lengthof(MIPSELTriples)); 1265263508Sdim BiarchTripleAliases.append( 1266263508Sdim MIPSTriples, MIPSTriples + llvm::array_lengthof(MIPSTriples)); 1267239462Sdim break; 1268234353Sdim case llvm::Triple::ppc: 1269234353Sdim LibDirs.append(PPCLibDirs, PPCLibDirs + llvm::array_lengthof(PPCLibDirs)); 1270263508Sdim TripleAliases.append(PPCTriples, 1271263508Sdim PPCTriples + llvm::array_lengthof(PPCTriples)); 1272263508Sdim BiarchLibDirs.append(PPC64LibDirs, 1273263508Sdim PPC64LibDirs + llvm::array_lengthof(PPC64LibDirs)); 1274263508Sdim BiarchTripleAliases.append( 1275263508Sdim PPC64Triples, PPC64Triples + llvm::array_lengthof(PPC64Triples)); 1276234353Sdim break; 1277234353Sdim case llvm::Triple::ppc64: 1278263508Sdim LibDirs.append(PPC64LibDirs, 1279263508Sdim PPC64LibDirs + llvm::array_lengthof(PPC64LibDirs)); 1280263508Sdim TripleAliases.append(PPC64Triples, 1281263508Sdim PPC64Triples + llvm::array_lengthof(PPC64Triples)); 1282263508Sdim BiarchLibDirs.append(PPCLibDirs, 1283263508Sdim PPCLibDirs + llvm::array_lengthof(PPCLibDirs)); 1284263508Sdim BiarchTripleAliases.append(PPCTriples, 1285263508Sdim PPCTriples + llvm::array_lengthof(PPCTriples)); 1286234353Sdim break; 1287263508Sdim case llvm::Triple::ppc64le: 1288263508Sdim LibDirs.append(PPC64LELibDirs, 1289263508Sdim PPC64LELibDirs + llvm::array_lengthof(PPC64LELibDirs)); 1290263508Sdim TripleAliases.append(PPC64LETriples, 1291263508Sdim PPC64LETriples + llvm::array_lengthof(PPC64LETriples)); 1292263508Sdim break; 1293263763Sdim case llvm::Triple::sparc: 1294263763Sdim LibDirs.append(SPARCv8LibDirs, 1295263763Sdim SPARCv8LibDirs + llvm::array_lengthof(SPARCv8LibDirs)); 1296263763Sdim TripleAliases.append(SPARCv8Triples, 1297263763Sdim SPARCv8Triples + llvm::array_lengthof(SPARCv8Triples)); 1298263763Sdim BiarchLibDirs.append(SPARCv9LibDirs, 1299263763Sdim SPARCv9LibDirs + llvm::array_lengthof(SPARCv9LibDirs)); 1300263763Sdim BiarchTripleAliases.append( 1301263763Sdim SPARCv9Triples, SPARCv9Triples + llvm::array_lengthof(SPARCv9Triples)); 1302263763Sdim break; 1303263763Sdim case llvm::Triple::sparcv9: 1304263763Sdim LibDirs.append(SPARCv9LibDirs, 1305263763Sdim SPARCv9LibDirs + llvm::array_lengthof(SPARCv9LibDirs)); 1306263763Sdim TripleAliases.append(SPARCv9Triples, 1307263763Sdim SPARCv9Triples + llvm::array_lengthof(SPARCv9Triples)); 1308263763Sdim BiarchLibDirs.append(SPARCv8LibDirs, 1309263763Sdim SPARCv8LibDirs + llvm::array_lengthof(SPARCv8LibDirs)); 1310263763Sdim BiarchTripleAliases.append( 1311263763Sdim SPARCv8Triples, SPARCv8Triples + llvm::array_lengthof(SPARCv8Triples)); 1312263763Sdim break; 1313251662Sdim case llvm::Triple::systemz: 1314263508Sdim LibDirs.append(SystemZLibDirs, 1315263508Sdim SystemZLibDirs + llvm::array_lengthof(SystemZLibDirs)); 1316263508Sdim TripleAliases.append(SystemZTriples, 1317263508Sdim SystemZTriples + llvm::array_lengthof(SystemZTriples)); 1318251662Sdim break; 1319234353Sdim 1320234353Sdim default: 1321234353Sdim // By default, just rely on the standard lib directories and the original 1322234353Sdim // triple. 1323234353Sdim break; 1324234353Sdim } 1325234353Sdim 1326234353Sdim // Always append the drivers target triple to the end, in case it doesn't 1327234353Sdim // match any of our aliases. 1328234353Sdim TripleAliases.push_back(TargetTriple.str()); 1329234353Sdim 1330234353Sdim // Also include the multiarch variant if it's different. 1331263508Sdim if (TargetTriple.str() != BiarchTriple.str()) 1332263508Sdim BiarchTripleAliases.push_back(BiarchTriple.str()); 1333234353Sdim} 1334234353Sdim 1335251662Sdimstatic bool isSoftFloatABI(const ArgList &Args) { 1336251662Sdim Arg *A = Args.getLastArg(options::OPT_msoft_float, 1337251662Sdim options::OPT_mhard_float, 1338251662Sdim options::OPT_mfloat_abi_EQ); 1339251662Sdim if (!A) return false; 1340251662Sdim 1341251662Sdim return A->getOption().matches(options::OPT_msoft_float) || 1342251662Sdim (A->getOption().matches(options::OPT_mfloat_abi_EQ) && 1343251662Sdim A->getValue() == StringRef("soft")); 1344251662Sdim} 1345251662Sdim 1346251662Sdimstatic bool isMipsArch(llvm::Triple::ArchType Arch) { 1347251662Sdim return Arch == llvm::Triple::mips || 1348251662Sdim Arch == llvm::Triple::mipsel || 1349251662Sdim Arch == llvm::Triple::mips64 || 1350251662Sdim Arch == llvm::Triple::mips64el; 1351251662Sdim} 1352251662Sdim 1353251662Sdimstatic bool isMips16(const ArgList &Args) { 1354251662Sdim Arg *A = Args.getLastArg(options::OPT_mips16, 1355251662Sdim options::OPT_mno_mips16); 1356251662Sdim return A && A->getOption().matches(options::OPT_mips16); 1357251662Sdim} 1358251662Sdim 1359263508Sdimstatic bool isMips32r2(const ArgList &Args) { 1360263508Sdim Arg *A = Args.getLastArg(options::OPT_march_EQ, 1361263508Sdim options::OPT_mcpu_EQ); 1362263508Sdim 1363263508Sdim return A && A->getValue() == StringRef("mips32r2"); 1364263508Sdim} 1365263508Sdim 1366263508Sdimstatic bool isMips64r2(const ArgList &Args) { 1367263508Sdim Arg *A = Args.getLastArg(options::OPT_march_EQ, 1368263508Sdim options::OPT_mcpu_EQ); 1369263508Sdim 1370263508Sdim return A && A->getValue() == StringRef("mips64r2"); 1371263508Sdim} 1372263508Sdim 1373251662Sdimstatic bool isMicroMips(const ArgList &Args) { 1374251662Sdim Arg *A = Args.getLastArg(options::OPT_mmicromips, 1375251662Sdim options::OPT_mno_micromips); 1376251662Sdim return A && A->getOption().matches(options::OPT_mmicromips); 1377251662Sdim} 1378251662Sdim 1379263508Sdimstatic bool isMipsFP64(const ArgList &Args) { 1380263508Sdim Arg *A = Args.getLastArg(options::OPT_mfp64, options::OPT_mfp32); 1381263508Sdim return A && A->getOption().matches(options::OPT_mfp64); 1382263508Sdim} 1383263508Sdim 1384263508Sdimstatic bool isMipsNan2008(const ArgList &Args) { 1385263508Sdim Arg *A = Args.getLastArg(options::OPT_mnan_EQ); 1386263508Sdim return A && A->getValue() == StringRef("2008"); 1387263508Sdim} 1388263508Sdim 1389243830Sdim// FIXME: There is the same routine in the Tools.cpp. 1390243830Sdimstatic bool hasMipsN32ABIArg(const ArgList &Args) { 1391243830Sdim Arg *A = Args.getLastArg(options::OPT_mabi_EQ); 1392243830Sdim return A && (A->getValue() == StringRef("n32")); 1393243830Sdim} 1394243830Sdim 1395263508Sdimstatic bool hasCrtBeginObj(Twine Path) { 1396263508Sdim return llvm::sys::fs::exists(Path + "/crtbegin.o"); 1397263508Sdim} 1398263508Sdim 1399263508Sdimstatic bool findTargetBiarchSuffix(std::string &Suffix, StringRef Path, 1400251662Sdim llvm::Triple::ArchType TargetArch, 1401251662Sdim const ArgList &Args) { 1402263508Sdim // FIXME: This routine was only intended to model bi-arch toolchains which 1403263508Sdim // use -m32 and -m64 to swap between variants of a target. It shouldn't be 1404263508Sdim // doing ABI-based builtin location for MIPS. 1405263508Sdim if (hasMipsN32ABIArg(Args)) 1406263508Sdim Suffix = "/n32"; 1407263508Sdim else if (TargetArch == llvm::Triple::x86_64 || 1408263508Sdim TargetArch == llvm::Triple::ppc64 || 1409263763Sdim TargetArch == llvm::Triple::sparcv9 || 1410263508Sdim TargetArch == llvm::Triple::systemz || 1411263508Sdim TargetArch == llvm::Triple::mips64 || 1412263508Sdim TargetArch == llvm::Triple::mips64el) 1413263508Sdim Suffix = "/64"; 1414263508Sdim else 1415263508Sdim Suffix = "/32"; 1416243830Sdim 1417263508Sdim return hasCrtBeginObj(Path + Suffix); 1418251662Sdim} 1419251662Sdim 1420263508Sdimvoid Generic_GCC::GCCInstallationDetector::findMIPSABIDirSuffix( 1421263508Sdim std::string &Suffix, llvm::Triple::ArchType TargetArch, StringRef Path, 1422263508Sdim const llvm::opt::ArgList &Args) { 1423263508Sdim if (!isMipsArch(TargetArch)) 1424263508Sdim return; 1425243830Sdim 1426263508Sdim // Some MIPS toolchains put libraries and object files compiled 1427263508Sdim // using different options in to the sub-directoris which names 1428263508Sdim // reflects the flags used for compilation. For example sysroot 1429263508Sdim // directory might looks like the following examples: 1430263508Sdim // 1431263508Sdim // /usr 1432263508Sdim // /lib <= crt*.o files compiled with '-mips32' 1433263508Sdim // /mips16 1434263508Sdim // /usr 1435263508Sdim // /lib <= crt*.o files compiled with '-mips16' 1436263508Sdim // /el 1437263508Sdim // /usr 1438263508Sdim // /lib <= crt*.o files compiled with '-mips16 -EL' 1439263508Sdim // 1440263508Sdim // or 1441263508Sdim // 1442263508Sdim // /usr 1443263508Sdim // /lib <= crt*.o files compiled with '-mips32r2' 1444263508Sdim // /mips16 1445263508Sdim // /usr 1446263508Sdim // /lib <= crt*.o files compiled with '-mips32r2 -mips16' 1447263508Sdim // /mips32 1448263508Sdim // /usr 1449263508Sdim // /lib <= crt*.o files compiled with '-mips32' 1450263508Sdim // 1451263508Sdim // Unfortunately different toolchains use different and partially 1452263508Sdim // overlapped naming schemes. So we have to make a trick for detection 1453263508Sdim // of using toolchain. We lookup a path which unique for each toolchains. 1454243830Sdim 1455263508Sdim bool IsMentorToolChain = hasCrtBeginObj(Path + "/mips16/soft-float"); 1456263508Sdim bool IsFSFToolChain = hasCrtBeginObj(Path + "/mips32/mips16/sof"); 1457251662Sdim 1458263508Sdim if (IsMentorToolChain && IsFSFToolChain) 1459263508Sdim D.Diag(diag::err_drv_unknown_toolchain); 1460251662Sdim 1461263508Sdim if (IsMentorToolChain) { 1462263508Sdim if (isMips16(Args)) 1463263508Sdim Suffix += "/mips16"; 1464263508Sdim else if (isMicroMips(Args)) 1465263508Sdim Suffix += "/micromips"; 1466263508Sdim 1467263508Sdim if (isSoftFloatABI(Args)) 1468263508Sdim Suffix += "/soft-float"; 1469263508Sdim 1470263508Sdim if (TargetArch == llvm::Triple::mipsel || 1471251662Sdim TargetArch == llvm::Triple::mips64el) 1472263508Sdim Suffix += "/el"; 1473263508Sdim } else if (IsFSFToolChain) { 1474263508Sdim if (TargetArch == llvm::Triple::mips || 1475263508Sdim TargetArch == llvm::Triple::mipsel) { 1476263508Sdim if (isMicroMips(Args)) 1477263508Sdim Suffix += "/micromips"; 1478263508Sdim else if (isMips32r2(Args)) 1479263508Sdim Suffix += ""; 1480263508Sdim else 1481263508Sdim Suffix += "/mips32"; 1482251662Sdim 1483263508Sdim if (isMips16(Args)) 1484263508Sdim Suffix += "/mips16"; 1485263508Sdim } else { 1486263508Sdim if (isMips64r2(Args)) 1487263508Sdim Suffix += hasMipsN32ABIArg(Args) ? "/mips64r2" : "/mips64r2/64"; 1488263508Sdim else 1489263508Sdim Suffix += hasMipsN32ABIArg(Args) ? "/mips64" : "/mips64/64"; 1490263508Sdim } 1491251662Sdim 1492263508Sdim if (TargetArch == llvm::Triple::mipsel || 1493263508Sdim TargetArch == llvm::Triple::mips64el) 1494263508Sdim Suffix += "/el"; 1495263508Sdim 1496263508Sdim if (isSoftFloatABI(Args)) 1497263508Sdim Suffix += "/sof"; 1498263508Sdim else { 1499263508Sdim if (isMipsFP64(Args)) 1500263508Sdim Suffix += "/fp64"; 1501263508Sdim 1502263508Sdim if (isMipsNan2008(Args)) 1503263508Sdim Suffix += "/nan2008"; 1504263508Sdim } 1505251662Sdim } 1506251662Sdim 1507263508Sdim if (!hasCrtBeginObj(Path + Suffix)) 1508263508Sdim Suffix.clear(); 1509251662Sdim} 1510251662Sdim 1511234353Sdimvoid Generic_GCC::GCCInstallationDetector::ScanLibDirForGCCTriple( 1512243830Sdim llvm::Triple::ArchType TargetArch, const ArgList &Args, 1513263508Sdim const std::string &LibDir, StringRef CandidateTriple, 1514263508Sdim bool NeedsBiarchSuffix) { 1515234353Sdim // There are various different suffixes involving the triple we 1516234353Sdim // check for. We also record what is necessary to walk from each back 1517234353Sdim // up to the lib directory. 1518234353Sdim const std::string LibSuffixes[] = { 1519234353Sdim "/gcc/" + CandidateTriple.str(), 1520263508Sdim // Debian puts cross-compilers in gcc-cross 1521263508Sdim "/gcc-cross/" + CandidateTriple.str(), 1522234353Sdim "/" + CandidateTriple.str() + "/gcc/" + CandidateTriple.str(), 1523234353Sdim 1524243830Sdim // The Freescale PPC SDK has the gcc libraries in 1525243830Sdim // <sysroot>/usr/lib/<triple>/x.y.z so have a look there as well. 1526243830Sdim "/" + CandidateTriple.str(), 1527243830Sdim 1528234353Sdim // Ubuntu has a strange mis-matched pair of triples that this happens to 1529234353Sdim // match. 1530234353Sdim // FIXME: It may be worthwhile to generalize this and look for a second 1531234353Sdim // triple. 1532234353Sdim "/i386-linux-gnu/gcc/" + CandidateTriple.str() 1533234353Sdim }; 1534234353Sdim const std::string InstallSuffixes[] = { 1535263508Sdim "/../../..", // gcc/ 1536263508Sdim "/../../..", // gcc-cross/ 1537263508Sdim "/../../../..", // <triple>/gcc/ 1538263508Sdim "/../..", // <triple>/ 1539263508Sdim "/../../../.." // i386-linux-gnu/gcc/<triple>/ 1540234353Sdim }; 1541234353Sdim // Only look at the final, weird Ubuntu suffix for i386-linux-gnu. 1542263508Sdim const unsigned NumLibSuffixes = 1543263508Sdim (llvm::array_lengthof(LibSuffixes) - (TargetArch != llvm::Triple::x86)); 1544234353Sdim for (unsigned i = 0; i < NumLibSuffixes; ++i) { 1545234353Sdim StringRef LibSuffix = LibSuffixes[i]; 1546234353Sdim llvm::error_code EC; 1547234353Sdim for (llvm::sys::fs::directory_iterator LI(LibDir + LibSuffix, EC), LE; 1548234353Sdim !EC && LI != LE; LI = LI.increment(EC)) { 1549234353Sdim StringRef VersionText = llvm::sys::path::filename(LI->path()); 1550234353Sdim GCCVersion CandidateVersion = GCCVersion::Parse(VersionText); 1551263508Sdim if (CandidateVersion.Major != -1) // Filter obviously bad entries. 1552263508Sdim if (!CandidateGCCInstallPaths.insert(LI->path()).second) 1553263508Sdim continue; // Saw this path before; no need to look at it again. 1554263508Sdim if (CandidateVersion.isOlderThan(4, 1, 1)) 1555234353Sdim continue; 1556234353Sdim if (CandidateVersion <= Version) 1557234353Sdim continue; 1558234353Sdim 1559263508Sdim std::string MIPSABIDirSuffix; 1560263508Sdim findMIPSABIDirSuffix(MIPSABIDirSuffix, TargetArch, LI->path(), Args); 1561263508Sdim 1562234353Sdim // Some versions of SUSE and Fedora on ppc64 put 32-bit libs 1563234353Sdim // in what would normally be GCCInstallPath and put the 64-bit 1564234353Sdim // libs in a subdirectory named 64. The simple logic we follow is that 1565234353Sdim // *if* there is a subdirectory of the right name with crtbegin.o in it, 1566263508Sdim // we use that. If not, and if not a biarch triple alias, we look for 1567234353Sdim // crtbegin.o without the subdirectory. 1568251662Sdim 1569263508Sdim std::string BiarchSuffix; 1570263508Sdim if (findTargetBiarchSuffix(BiarchSuffix, 1571263508Sdim LI->path() + MIPSABIDirSuffix, 1572263508Sdim TargetArch, Args)) { 1573263508Sdim GCCBiarchSuffix = BiarchSuffix; 1574263508Sdim } else if (NeedsBiarchSuffix || 1575263508Sdim !hasCrtBeginObj(LI->path() + MIPSABIDirSuffix)) { 1576263508Sdim continue; 1577234353Sdim } else { 1578263508Sdim GCCBiarchSuffix.clear(); 1579234353Sdim } 1580234353Sdim 1581234353Sdim Version = CandidateVersion; 1582234353Sdim GCCTriple.setTriple(CandidateTriple); 1583234353Sdim // FIXME: We hack together the directory name here instead of 1584234353Sdim // using LI to ensure stable path separators across Windows and 1585234353Sdim // Linux. 1586234353Sdim GCCInstallPath = LibDir + LibSuffixes[i] + "/" + VersionText.str(); 1587234353Sdim GCCParentLibPath = GCCInstallPath + InstallSuffixes[i]; 1588263508Sdim GCCMIPSABIDirSuffix = MIPSABIDirSuffix; 1589234353Sdim IsValid = true; 1590234353Sdim } 1591234353Sdim } 1592234353Sdim} 1593234353Sdim 1594234353SdimGeneric_GCC::Generic_GCC(const Driver &D, const llvm::Triple& Triple, 1595234353Sdim const ArgList &Args) 1596263508Sdim : ToolChain(D, Triple, Args), GCCInstallation(getDriver()) { 1597212904Sdim getProgramPaths().push_back(getDriver().getInstalledDir()); 1598221345Sdim if (getDriver().getInstalledDir() != getDriver().Dir) 1599212904Sdim getProgramPaths().push_back(getDriver().Dir); 1600193326Sed} 1601193326Sed 1602193326SedGeneric_GCC::~Generic_GCC() { 1603193326Sed} 1604193326Sed 1605249423SdimTool *Generic_GCC::getTool(Action::ActionClass AC) const { 1606249423Sdim switch (AC) { 1607249423Sdim case Action::PreprocessJobClass: 1608249423Sdim if (!Preprocess) 1609249423Sdim Preprocess.reset(new tools::gcc::Preprocess(*this)); 1610249423Sdim return Preprocess.get(); 1611249423Sdim case Action::PrecompileJobClass: 1612249423Sdim if (!Precompile) 1613249423Sdim Precompile.reset(new tools::gcc::Precompile(*this)); 1614249423Sdim return Precompile.get(); 1615249423Sdim case Action::CompileJobClass: 1616249423Sdim if (!Compile) 1617249423Sdim Compile.reset(new tools::gcc::Compile(*this)); 1618249423Sdim return Compile.get(); 1619249423Sdim default: 1620249423Sdim return ToolChain::getTool(AC); 1621193326Sed } 1622249423Sdim} 1623193326Sed 1624249423SdimTool *Generic_GCC::buildAssembler() const { 1625249423Sdim return new tools::gcc::Assemble(*this); 1626193326Sed} 1627193326Sed 1628249423SdimTool *Generic_GCC::buildLinker() const { 1629249423Sdim return new tools::gcc::Link(*this); 1630249423Sdim} 1631249423Sdim 1632263508Sdimvoid Generic_GCC::printVerboseInfo(raw_ostream &OS) const { 1633263508Sdim // Print the information about how we detected the GCC installation. 1634263508Sdim GCCInstallation.print(OS); 1635263508Sdim} 1636263508Sdim 1637193326Sedbool Generic_GCC::IsUnwindTablesDefault() const { 1638243830Sdim return getArch() == llvm::Triple::x86_64; 1639193326Sed} 1640193326Sed 1641243830Sdimbool Generic_GCC::isPICDefault() const { 1642243830Sdim return false; 1643193326Sed} 1644193326Sed 1645251662Sdimbool Generic_GCC::isPIEDefault() const { 1646251662Sdim return false; 1647251662Sdim} 1648251662Sdim 1649243830Sdimbool Generic_GCC::isPICDefaultForced() const { 1650243830Sdim return false; 1651193326Sed} 1652243830Sdim 1653266715Sdimvoid Generic_GCC::addClangTargetOptions(const ArgList &DriverArgs, 1654266715Sdim ArgStringList &CC1Args) const { 1655266715Sdim const Generic_GCC::GCCVersion &V = GCCInstallation.getVersion(); 1656266715Sdim bool UseInitArrayDefault = 1657266715Sdim getTriple().getArch() == llvm::Triple::aarch64 || 1658266715Sdim (getTriple().getOS() == llvm::Triple::Linux && ( 1659266715Sdim !V.isOlderThan(4, 7, 0) || 1660266715Sdim getTriple().getEnvironment() == llvm::Triple::Android)); 1661266715Sdim 1662266715Sdim if (DriverArgs.hasFlag(options::OPT_fuse_init_array, 1663266715Sdim options::OPT_fno_use_init_array, 1664266715Sdim UseInitArrayDefault)) 1665266715Sdim CC1Args.push_back("-fuse-init-array"); 1666266715Sdim} 1667266715Sdim 1668234353Sdim/// Hexagon Toolchain 1669193326Sed 1670249423Sdimstd::string Hexagon_TC::GetGnuDir(const std::string &InstalledDir) { 1671249423Sdim 1672249423Sdim // Locate the rest of the toolchain ... 1673249423Sdim if (strlen(GCC_INSTALL_PREFIX)) 1674249423Sdim return std::string(GCC_INSTALL_PREFIX); 1675249423Sdim 1676249423Sdim std::string InstallRelDir = InstalledDir + "/../../gnu"; 1677249423Sdim if (llvm::sys::fs::exists(InstallRelDir)) 1678249423Sdim return InstallRelDir; 1679249423Sdim 1680249423Sdim std::string PrefixRelDir = std::string(LLVM_PREFIX) + "/../gnu"; 1681249423Sdim if (llvm::sys::fs::exists(PrefixRelDir)) 1682249423Sdim return PrefixRelDir; 1683249423Sdim 1684249423Sdim return InstallRelDir; 1685234353Sdim} 1686234353Sdim 1687249423Sdimstatic void GetHexagonLibraryPaths( 1688249423Sdim const ArgList &Args, 1689249423Sdim const std::string Ver, 1690249423Sdim const std::string MarchString, 1691249423Sdim const std::string &InstalledDir, 1692249423Sdim ToolChain::path_list *LibPaths) 1693249423Sdim{ 1694249423Sdim bool buildingLib = Args.hasArg(options::OPT_shared); 1695249423Sdim 1696249423Sdim //---------------------------------------------------------------------------- 1697249423Sdim // -L Args 1698249423Sdim //---------------------------------------------------------------------------- 1699249423Sdim for (arg_iterator 1700249423Sdim it = Args.filtered_begin(options::OPT_L), 1701249423Sdim ie = Args.filtered_end(); 1702249423Sdim it != ie; 1703249423Sdim ++it) { 1704249423Sdim for (unsigned i = 0, e = (*it)->getNumValues(); i != e; ++i) 1705249423Sdim LibPaths->push_back((*it)->getValue(i)); 1706249423Sdim } 1707249423Sdim 1708249423Sdim //---------------------------------------------------------------------------- 1709249423Sdim // Other standard paths 1710249423Sdim //---------------------------------------------------------------------------- 1711249423Sdim const std::string MarchSuffix = "/" + MarchString; 1712249423Sdim const std::string G0Suffix = "/G0"; 1713249423Sdim const std::string MarchG0Suffix = MarchSuffix + G0Suffix; 1714249423Sdim const std::string RootDir = Hexagon_TC::GetGnuDir(InstalledDir) + "/"; 1715249423Sdim 1716249423Sdim // lib/gcc/hexagon/... 1717249423Sdim std::string LibGCCHexagonDir = RootDir + "lib/gcc/hexagon/"; 1718249423Sdim if (buildingLib) { 1719249423Sdim LibPaths->push_back(LibGCCHexagonDir + Ver + MarchG0Suffix); 1720249423Sdim LibPaths->push_back(LibGCCHexagonDir + Ver + G0Suffix); 1721249423Sdim } 1722249423Sdim LibPaths->push_back(LibGCCHexagonDir + Ver + MarchSuffix); 1723249423Sdim LibPaths->push_back(LibGCCHexagonDir + Ver); 1724249423Sdim 1725249423Sdim // lib/gcc/... 1726249423Sdim LibPaths->push_back(RootDir + "lib/gcc"); 1727249423Sdim 1728249423Sdim // hexagon/lib/... 1729249423Sdim std::string HexagonLibDir = RootDir + "hexagon/lib"; 1730249423Sdim if (buildingLib) { 1731249423Sdim LibPaths->push_back(HexagonLibDir + MarchG0Suffix); 1732249423Sdim LibPaths->push_back(HexagonLibDir + G0Suffix); 1733249423Sdim } 1734249423Sdim LibPaths->push_back(HexagonLibDir + MarchSuffix); 1735249423Sdim LibPaths->push_back(HexagonLibDir); 1736249423Sdim} 1737249423Sdim 1738249423SdimHexagon_TC::Hexagon_TC(const Driver &D, const llvm::Triple &Triple, 1739249423Sdim const ArgList &Args) 1740249423Sdim : Linux(D, Triple, Args) { 1741249423Sdim const std::string InstalledDir(getDriver().getInstalledDir()); 1742249423Sdim const std::string GnuDir = Hexagon_TC::GetGnuDir(InstalledDir); 1743249423Sdim 1744249423Sdim // Note: Generic_GCC::Generic_GCC adds InstalledDir and getDriver().Dir to 1745249423Sdim // program paths 1746249423Sdim const std::string BinDir(GnuDir + "/bin"); 1747249423Sdim if (llvm::sys::fs::exists(BinDir)) 1748249423Sdim getProgramPaths().push_back(BinDir); 1749249423Sdim 1750249423Sdim // Determine version of GCC libraries and headers to use. 1751249423Sdim const std::string HexagonDir(GnuDir + "/lib/gcc/hexagon"); 1752249423Sdim llvm::error_code ec; 1753249423Sdim GCCVersion MaxVersion= GCCVersion::Parse("0.0.0"); 1754249423Sdim for (llvm::sys::fs::directory_iterator di(HexagonDir, ec), de; 1755249423Sdim !ec && di != de; di = di.increment(ec)) { 1756249423Sdim GCCVersion cv = GCCVersion::Parse(llvm::sys::path::filename(di->path())); 1757249423Sdim if (MaxVersion < cv) 1758249423Sdim MaxVersion = cv; 1759249423Sdim } 1760249423Sdim GCCLibAndIncVersion = MaxVersion; 1761249423Sdim 1762249423Sdim ToolChain::path_list *LibPaths= &getFilePaths(); 1763249423Sdim 1764249423Sdim // Remove paths added by Linux toolchain. Currently Hexagon_TC really targets 1765249423Sdim // 'elf' OS type, so the Linux paths are not appropriate. When we actually 1766249423Sdim // support 'linux' we'll need to fix this up 1767249423Sdim LibPaths->clear(); 1768249423Sdim 1769249423Sdim GetHexagonLibraryPaths( 1770249423Sdim Args, 1771249423Sdim GetGCCLibAndIncVersion(), 1772249423Sdim GetTargetCPU(Args), 1773249423Sdim InstalledDir, 1774249423Sdim LibPaths); 1775249423Sdim} 1776249423Sdim 1777234353SdimHexagon_TC::~Hexagon_TC() { 1778234353Sdim} 1779234353Sdim 1780249423SdimTool *Hexagon_TC::buildAssembler() const { 1781249423Sdim return new tools::hexagon::Assemble(*this); 1782249423Sdim} 1783234353Sdim 1784249423SdimTool *Hexagon_TC::buildLinker() const { 1785249423Sdim return new tools::hexagon::Link(*this); 1786249423Sdim} 1787234353Sdim 1788249423Sdimvoid Hexagon_TC::AddClangSystemIncludeArgs(const ArgList &DriverArgs, 1789249423Sdim ArgStringList &CC1Args) const { 1790249423Sdim const Driver &D = getDriver(); 1791249423Sdim 1792249423Sdim if (DriverArgs.hasArg(options::OPT_nostdinc) || 1793249423Sdim DriverArgs.hasArg(options::OPT_nostdlibinc)) 1794249423Sdim return; 1795249423Sdim 1796249423Sdim std::string Ver(GetGCCLibAndIncVersion()); 1797249423Sdim std::string GnuDir = Hexagon_TC::GetGnuDir(D.InstalledDir); 1798249423Sdim std::string HexagonDir(GnuDir + "/lib/gcc/hexagon/" + Ver); 1799249423Sdim addExternCSystemInclude(DriverArgs, CC1Args, HexagonDir + "/include"); 1800249423Sdim addExternCSystemInclude(DriverArgs, CC1Args, HexagonDir + "/include-fixed"); 1801249423Sdim addExternCSystemInclude(DriverArgs, CC1Args, GnuDir + "/hexagon/include"); 1802249423Sdim} 1803249423Sdim 1804249423Sdimvoid Hexagon_TC::AddClangCXXStdlibIncludeArgs(const ArgList &DriverArgs, 1805249423Sdim ArgStringList &CC1Args) const { 1806249423Sdim 1807249423Sdim if (DriverArgs.hasArg(options::OPT_nostdlibinc) || 1808249423Sdim DriverArgs.hasArg(options::OPT_nostdincxx)) 1809249423Sdim return; 1810249423Sdim 1811249423Sdim const Driver &D = getDriver(); 1812249423Sdim std::string Ver(GetGCCLibAndIncVersion()); 1813263508Sdim SmallString<128> IncludeDir(Hexagon_TC::GetGnuDir(D.InstalledDir)); 1814249423Sdim 1815263508Sdim llvm::sys::path::append(IncludeDir, "hexagon/include/c++/"); 1816263508Sdim llvm::sys::path::append(IncludeDir, Ver); 1817249423Sdim addSystemInclude(DriverArgs, CC1Args, IncludeDir.str()); 1818249423Sdim} 1819249423Sdim 1820249423SdimToolChain::CXXStdlibType 1821249423SdimHexagon_TC::GetCXXStdlibType(const ArgList &Args) const { 1822249423Sdim Arg *A = Args.getLastArg(options::OPT_stdlib_EQ); 1823249423Sdim if (!A) 1824249423Sdim return ToolChain::CST_Libstdcxx; 1825249423Sdim 1826249423Sdim StringRef Value = A->getValue(); 1827249423Sdim if (Value != "libstdc++") { 1828249423Sdim getDriver().Diag(diag::err_drv_invalid_stdlib_name) 1829249423Sdim << A->getAsString(Args); 1830234353Sdim } 1831234353Sdim 1832249423Sdim return ToolChain::CST_Libstdcxx; 1833234353Sdim} 1834234353Sdim 1835263508Sdimstatic int getHexagonVersion(const ArgList &Args) { 1836263508Sdim Arg *A = Args.getLastArg(options::OPT_march_EQ, options::OPT_mcpu_EQ); 1837263508Sdim // Select the default CPU (v4) if none was given. 1838263508Sdim if (!A) 1839263508Sdim return 4; 1840249423Sdim 1841263508Sdim // FIXME: produce errors if we cannot parse the version. 1842263508Sdim StringRef WhichHexagon = A->getValue(); 1843263508Sdim if (WhichHexagon.startswith("hexagonv")) { 1844263508Sdim int Val; 1845263508Sdim if (!WhichHexagon.substr(sizeof("hexagonv") - 1).getAsInteger(10, Val)) 1846263508Sdim return Val; 1847249423Sdim } 1848263508Sdim if (WhichHexagon.startswith("v")) { 1849263508Sdim int Val; 1850263508Sdim if (!WhichHexagon.substr(1).getAsInteger(10, Val)) 1851263508Sdim return Val; 1852263508Sdim } 1853263508Sdim 1854263508Sdim // FIXME: should probably be an error. 1855263508Sdim return 4; 1856234353Sdim} 1857234353Sdim 1858249423SdimStringRef Hexagon_TC::GetTargetCPU(const ArgList &Args) 1859249423Sdim{ 1860263508Sdim int V = getHexagonVersion(Args); 1861263508Sdim // FIXME: We don't support versions < 4. We should error on them. 1862263508Sdim switch (V) { 1863263508Sdim default: 1864263508Sdim llvm_unreachable("Unexpected version"); 1865263508Sdim case 5: 1866263508Sdim return "v5"; 1867263508Sdim case 4: 1868263508Sdim return "v4"; 1869263508Sdim case 3: 1870263508Sdim return "v3"; 1871263508Sdim case 2: 1872263508Sdim return "v2"; 1873263508Sdim case 1: 1874263508Sdim return "v1"; 1875249423Sdim } 1876234353Sdim} 1877249423Sdim// End Hexagon 1878234353Sdim 1879204793Srdivacky/// TCEToolChain - A tool chain using the llvm bitcode tools to perform 1880204793Srdivacky/// all subcommands. See http://tce.cs.tut.fi for our peculiar target. 1881204793Srdivacky/// Currently does not support anything else but compilation. 1882204793Srdivacky 1883249423SdimTCEToolChain::TCEToolChain(const Driver &D, const llvm::Triple& Triple, 1884249423Sdim const ArgList &Args) 1885249423Sdim : ToolChain(D, Triple, Args) { 1886204793Srdivacky // Path mangling to find libexec 1887204793Srdivacky std::string Path(getDriver().Dir); 1888204793Srdivacky 1889204793Srdivacky Path += "/../libexec"; 1890204793Srdivacky getProgramPaths().push_back(Path); 1891204793Srdivacky} 1892204793Srdivacky 1893204793SrdivackyTCEToolChain::~TCEToolChain() { 1894204793Srdivacky} 1895204793Srdivacky 1896223017Sdimbool TCEToolChain::IsMathErrnoDefault() const { 1897223017Sdim return true; 1898204793Srdivacky} 1899204793Srdivacky 1900243830Sdimbool TCEToolChain::isPICDefault() const { 1901204793Srdivacky return false; 1902204793Srdivacky} 1903204793Srdivacky 1904251662Sdimbool TCEToolChain::isPIEDefault() const { 1905251662Sdim return false; 1906251662Sdim} 1907251662Sdim 1908243830Sdimbool TCEToolChain::isPICDefaultForced() const { 1909243830Sdim return false; 1910204793Srdivacky} 1911204793Srdivacky 1912195341Sed/// OpenBSD - OpenBSD tool chain which can call as(1) and ld(1) directly. 1913195341Sed 1914234353SdimOpenBSD::OpenBSD(const Driver &D, const llvm::Triple& Triple, const ArgList &Args) 1915234353Sdim : Generic_ELF(D, Triple, Args) { 1916201361Srdivacky getFilePaths().push_back(getDriver().Dir + "/../lib"); 1917195341Sed getFilePaths().push_back("/usr/lib"); 1918195341Sed} 1919195341Sed 1920249423SdimTool *OpenBSD::buildAssembler() const { 1921249423Sdim return new tools::openbsd::Assemble(*this); 1922249423Sdim} 1923195341Sed 1924249423SdimTool *OpenBSD::buildLinker() const { 1925249423Sdim return new tools::openbsd::Link(*this); 1926195341Sed} 1927195341Sed 1928239462Sdim/// Bitrig - Bitrig tool chain which can call as(1) and ld(1) directly. 1929239462Sdim 1930239462SdimBitrig::Bitrig(const Driver &D, const llvm::Triple& Triple, const ArgList &Args) 1931239462Sdim : Generic_ELF(D, Triple, Args) { 1932239462Sdim getFilePaths().push_back(getDriver().Dir + "/../lib"); 1933239462Sdim getFilePaths().push_back("/usr/lib"); 1934239462Sdim} 1935239462Sdim 1936249423SdimTool *Bitrig::buildAssembler() const { 1937249423Sdim return new tools::bitrig::Assemble(*this); 1938249423Sdim} 1939239462Sdim 1940249423SdimTool *Bitrig::buildLinker() const { 1941249423Sdim return new tools::bitrig::Link(*this); 1942239462Sdim} 1943239462Sdim 1944239462Sdimvoid Bitrig::AddClangCXXStdlibIncludeArgs(const ArgList &DriverArgs, 1945239462Sdim ArgStringList &CC1Args) const { 1946239462Sdim if (DriverArgs.hasArg(options::OPT_nostdlibinc) || 1947239462Sdim DriverArgs.hasArg(options::OPT_nostdincxx)) 1948239462Sdim return; 1949239462Sdim 1950243830Sdim switch (GetCXXStdlibType(DriverArgs)) { 1951243830Sdim case ToolChain::CST_Libcxx: 1952243830Sdim addSystemInclude(DriverArgs, CC1Args, 1953243830Sdim getDriver().SysRoot + "/usr/include/c++/"); 1954243830Sdim break; 1955243830Sdim case ToolChain::CST_Libstdcxx: 1956243830Sdim addSystemInclude(DriverArgs, CC1Args, 1957243830Sdim getDriver().SysRoot + "/usr/include/c++/stdc++"); 1958243830Sdim addSystemInclude(DriverArgs, CC1Args, 1959243830Sdim getDriver().SysRoot + "/usr/include/c++/stdc++/backward"); 1960239462Sdim 1961243830Sdim StringRef Triple = getTriple().str(); 1962243830Sdim if (Triple.startswith("amd64")) 1963243830Sdim addSystemInclude(DriverArgs, CC1Args, 1964243830Sdim getDriver().SysRoot + "/usr/include/c++/stdc++/x86_64" + 1965243830Sdim Triple.substr(5)); 1966243830Sdim else 1967243830Sdim addSystemInclude(DriverArgs, CC1Args, 1968243830Sdim getDriver().SysRoot + "/usr/include/c++/stdc++/" + 1969243830Sdim Triple); 1970243830Sdim break; 1971243830Sdim } 1972239462Sdim} 1973239462Sdim 1974239462Sdimvoid Bitrig::AddCXXStdlibLibArgs(const ArgList &Args, 1975239462Sdim ArgStringList &CmdArgs) const { 1976243830Sdim switch (GetCXXStdlibType(Args)) { 1977243830Sdim case ToolChain::CST_Libcxx: 1978243830Sdim CmdArgs.push_back("-lc++"); 1979243830Sdim CmdArgs.push_back("-lcxxrt"); 1980243830Sdim // Include supc++ to provide Unwind until provided by libcxx. 1981243830Sdim CmdArgs.push_back("-lgcc"); 1982243830Sdim break; 1983243830Sdim case ToolChain::CST_Libstdcxx: 1984243830Sdim CmdArgs.push_back("-lstdc++"); 1985243830Sdim break; 1986243830Sdim } 1987239462Sdim} 1988239462Sdim 1989193326Sed/// FreeBSD - FreeBSD tool chain which can call as(1) and ld(1) directly. 1990193326Sed 1991234353SdimFreeBSD::FreeBSD(const Driver &D, const llvm::Triple& Triple, const ArgList &Args) 1992234353Sdim : Generic_ELF(D, Triple, Args) { 1993212904Sdim 1994234353Sdim // When targeting 32-bit platforms, look for '/usr/lib32/crt1.o' and fall 1995234353Sdim // back to '/usr/lib' if it doesn't exist. 1996234353Sdim if ((Triple.getArch() == llvm::Triple::x86 || 1997234353Sdim Triple.getArch() == llvm::Triple::ppc) && 1998234982Sdim llvm::sys::fs::exists(getDriver().SysRoot + "/usr/lib32/crt1.o")) 1999234982Sdim getFilePaths().push_back(getDriver().SysRoot + "/usr/lib32"); 2000234353Sdim else 2001234982Sdim getFilePaths().push_back(getDriver().SysRoot + "/usr/lib"); 2002193326Sed} 2003193326Sed 2004255321StheravenToolChain::CXXStdlibType 2005255321StheravenFreeBSD::GetCXXStdlibType(const ArgList &Args) const { 2006255321Stheraven if (Arg *A = Args.getLastArg(options::OPT_stdlib_EQ)) { 2007255321Stheraven StringRef Value = A->getValue(); 2008263508Sdim if (Value == "libstdc++") 2009263508Sdim return ToolChain::CST_Libstdcxx; 2010255321Stheraven if (Value == "libc++") 2011255321Stheraven return ToolChain::CST_Libcxx; 2012263508Sdim 2013255321Stheraven getDriver().Diag(diag::err_drv_invalid_stdlib_name) 2014255321Stheraven << A->getAsString(Args); 2015255321Stheraven } 2016263508Sdim if (getTriple().getOSMajorVersion() >= 10) 2017263508Sdim return ToolChain::CST_Libcxx; 2018263508Sdim return ToolChain::CST_Libstdcxx; 2019255321Stheraven} 2020255321Stheraven 2021255321Stheravenvoid FreeBSD::AddClangCXXStdlibIncludeArgs(const ArgList &DriverArgs, 2022263508Sdim ArgStringList &CC1Args) const { 2023255321Stheraven if (DriverArgs.hasArg(options::OPT_nostdlibinc) || 2024255321Stheraven DriverArgs.hasArg(options::OPT_nostdincxx)) 2025255321Stheraven return; 2026255321Stheraven 2027263508Sdim switch (GetCXXStdlibType(DriverArgs)) { 2028263508Sdim case ToolChain::CST_Libcxx: 2029255321Stheraven addSystemInclude(DriverArgs, CC1Args, 2030255321Stheraven getDriver().SysRoot + "/usr/include/c++/v1"); 2031263508Sdim break; 2032263508Sdim case ToolChain::CST_Libstdcxx: 2033255321Stheraven addSystemInclude(DriverArgs, CC1Args, 2034255321Stheraven getDriver().SysRoot + "/usr/include/c++/4.2"); 2035263508Sdim addSystemInclude(DriverArgs, CC1Args, 2036263508Sdim getDriver().SysRoot + "/usr/include/c++/4.2/backward"); 2037263508Sdim break; 2038263508Sdim } 2039263508Sdim} 2040255321Stheraven 2041263508SdimTool *FreeBSD::buildAssembler() const { 2042263508Sdim return new tools::freebsd::Assemble(*this); 2043255321Stheraven} 2044255321Stheraven 2045263508SdimTool *FreeBSD::buildLinker() const { 2046263508Sdim return new tools::freebsd::Link(*this); 2047263508Sdim} 2048263508Sdim 2049263508Sdimbool FreeBSD::UseSjLjExceptions() const { 2050263508Sdim // FreeBSD uses SjLj exceptions on ARM oabi. 2051263508Sdim switch (getTriple().getEnvironment()) { 2052263508Sdim case llvm::Triple::GNUEABI: 2053263508Sdim case llvm::Triple::EABI: 2054263508Sdim return false; 2055263508Sdim 2056263508Sdim default: 2057263508Sdim return (getTriple().getArch() == llvm::Triple::arm || 2058263508Sdim getTriple().getArch() == llvm::Triple::thumb); 2059263508Sdim } 2060263508Sdim} 2061263508Sdim 2062218893Sdim/// NetBSD - NetBSD tool chain which can call as(1) and ld(1) directly. 2063218893Sdim 2064234353SdimNetBSD::NetBSD(const Driver &D, const llvm::Triple& Triple, const ArgList &Args) 2065234353Sdim : Generic_ELF(D, Triple, Args) { 2066218893Sdim 2067221345Sdim if (getDriver().UseStdLib) { 2068234353Sdim // When targeting a 32-bit platform, try the special directory used on 2069234353Sdim // 64-bit hosts, and only fall back to the main library directory if that 2070234353Sdim // doesn't work. 2071234353Sdim // FIXME: It'd be nicer to test if this directory exists, but I'm not sure 2072234353Sdim // what all logic is needed to emulate the '=' prefix here. 2073234353Sdim if (Triple.getArch() == llvm::Triple::x86) 2074221345Sdim getFilePaths().push_back("=/usr/lib/i386"); 2075234353Sdim 2076234353Sdim getFilePaths().push_back("=/usr/lib"); 2077218893Sdim } 2078218893Sdim} 2079218893Sdim 2080249423SdimTool *NetBSD::buildAssembler() const { 2081249423Sdim return new tools::netbsd::Assemble(*this); 2082249423Sdim} 2083218893Sdim 2084249423SdimTool *NetBSD::buildLinker() const { 2085249423Sdim return new tools::netbsd::Link(*this); 2086218893Sdim} 2087218893Sdim 2088251662SdimToolChain::CXXStdlibType 2089251662SdimNetBSD::GetCXXStdlibType(const ArgList &Args) const { 2090251662Sdim if (Arg *A = Args.getLastArg(options::OPT_stdlib_EQ)) { 2091251662Sdim StringRef Value = A->getValue(); 2092251662Sdim if (Value == "libstdc++") 2093251662Sdim return ToolChain::CST_Libstdcxx; 2094251662Sdim if (Value == "libc++") 2095251662Sdim return ToolChain::CST_Libcxx; 2096251662Sdim 2097251662Sdim getDriver().Diag(diag::err_drv_invalid_stdlib_name) 2098251662Sdim << A->getAsString(Args); 2099251662Sdim } 2100251662Sdim 2101263508Sdim unsigned Major, Minor, Micro; 2102263508Sdim getTriple().getOSVersion(Major, Minor, Micro); 2103263508Sdim if (Major >= 7 || (Major == 6 && Minor == 99 && Micro >= 23) || Major == 0) { 2104263508Sdim if (getArch() == llvm::Triple::x86 || getArch() == llvm::Triple::x86_64) 2105263508Sdim return ToolChain::CST_Libcxx; 2106263508Sdim } 2107251662Sdim return ToolChain::CST_Libstdcxx; 2108251662Sdim} 2109251662Sdim 2110251662Sdimvoid NetBSD::AddClangCXXStdlibIncludeArgs(const ArgList &DriverArgs, 2111251662Sdim ArgStringList &CC1Args) const { 2112251662Sdim if (DriverArgs.hasArg(options::OPT_nostdlibinc) || 2113251662Sdim DriverArgs.hasArg(options::OPT_nostdincxx)) 2114251662Sdim return; 2115251662Sdim 2116251662Sdim switch (GetCXXStdlibType(DriverArgs)) { 2117251662Sdim case ToolChain::CST_Libcxx: 2118251662Sdim addSystemInclude(DriverArgs, CC1Args, 2119251662Sdim getDriver().SysRoot + "/usr/include/c++/"); 2120251662Sdim break; 2121251662Sdim case ToolChain::CST_Libstdcxx: 2122251662Sdim addSystemInclude(DriverArgs, CC1Args, 2123251662Sdim getDriver().SysRoot + "/usr/include/g++"); 2124251662Sdim addSystemInclude(DriverArgs, CC1Args, 2125251662Sdim getDriver().SysRoot + "/usr/include/g++/backward"); 2126251662Sdim break; 2127251662Sdim } 2128251662Sdim} 2129251662Sdim 2130210299Sed/// Minix - Minix tool chain which can call as(1) and ld(1) directly. 2131210299Sed 2132234353SdimMinix::Minix(const Driver &D, const llvm::Triple& Triple, const ArgList &Args) 2133234353Sdim : Generic_ELF(D, Triple, Args) { 2134210299Sed getFilePaths().push_back(getDriver().Dir + "/../lib"); 2135210299Sed getFilePaths().push_back("/usr/lib"); 2136210299Sed} 2137210299Sed 2138249423SdimTool *Minix::buildAssembler() const { 2139249423Sdim return new tools::minix::Assemble(*this); 2140249423Sdim} 2141210299Sed 2142249423SdimTool *Minix::buildLinker() const { 2143249423Sdim return new tools::minix::Link(*this); 2144210299Sed} 2145210299Sed 2146198092Srdivacky/// AuroraUX - AuroraUX tool chain which can call as(1) and ld(1) directly. 2147198092Srdivacky 2148234353SdimAuroraUX::AuroraUX(const Driver &D, const llvm::Triple& Triple, 2149234353Sdim const ArgList &Args) 2150234353Sdim : Generic_GCC(D, Triple, Args) { 2151198092Srdivacky 2152212904Sdim getProgramPaths().push_back(getDriver().getInstalledDir()); 2153221345Sdim if (getDriver().getInstalledDir() != getDriver().Dir) 2154212904Sdim getProgramPaths().push_back(getDriver().Dir); 2155198092Srdivacky 2156201361Srdivacky getFilePaths().push_back(getDriver().Dir + "/../lib"); 2157198092Srdivacky getFilePaths().push_back("/usr/lib"); 2158198092Srdivacky getFilePaths().push_back("/usr/sfw/lib"); 2159198092Srdivacky getFilePaths().push_back("/opt/gcc4/lib"); 2160198398Srdivacky getFilePaths().push_back("/opt/gcc4/lib/gcc/i386-pc-solaris2.11/4.2.4"); 2161198092Srdivacky 2162198092Srdivacky} 2163198092Srdivacky 2164249423SdimTool *AuroraUX::buildAssembler() const { 2165249423Sdim return new tools::auroraux::Assemble(*this); 2166249423Sdim} 2167198092Srdivacky 2168249423SdimTool *AuroraUX::buildLinker() const { 2169249423Sdim return new tools::auroraux::Link(*this); 2170198092Srdivacky} 2171198092Srdivacky 2172234353Sdim/// Solaris - Solaris tool chain which can call as(1) and ld(1) directly. 2173198092Srdivacky 2174234353SdimSolaris::Solaris(const Driver &D, const llvm::Triple& Triple, 2175234353Sdim const ArgList &Args) 2176234353Sdim : Generic_GCC(D, Triple, Args) { 2177234353Sdim 2178234353Sdim getProgramPaths().push_back(getDriver().getInstalledDir()); 2179234353Sdim if (getDriver().getInstalledDir() != getDriver().Dir) 2180234353Sdim getProgramPaths().push_back(getDriver().Dir); 2181234353Sdim 2182234353Sdim getFilePaths().push_back(getDriver().Dir + "/../lib"); 2183234353Sdim getFilePaths().push_back("/usr/lib"); 2184234353Sdim} 2185234353Sdim 2186249423SdimTool *Solaris::buildAssembler() const { 2187249423Sdim return new tools::solaris::Assemble(*this); 2188249423Sdim} 2189234353Sdim 2190249423SdimTool *Solaris::buildLinker() const { 2191249423Sdim return new tools::solaris::Link(*this); 2192234353Sdim} 2193234353Sdim 2194249423Sdim/// Distribution (very bare-bones at the moment). 2195193326Sed 2196249423Sdimenum Distro { 2197219077Sdim ArchLinux, 2198218893Sdim DebianLenny, 2199218893Sdim DebianSqueeze, 2200223017Sdim DebianWheezy, 2201249423Sdim DebianJessie, 2202218893Sdim Exherbo, 2203223017Sdim RHEL4, 2204223017Sdim RHEL5, 2205223017Sdim RHEL6, 2206263508Sdim Fedora, 2207263508Sdim OpenSUSE, 2208221345Sdim UbuntuHardy, 2209221345Sdim UbuntuIntrepid, 2210218893Sdim UbuntuJaunty, 2211218893Sdim UbuntuKarmic, 2212218893Sdim UbuntuLucid, 2213218893Sdim UbuntuMaverick, 2214221345Sdim UbuntuNatty, 2215223017Sdim UbuntuOneiric, 2216234353Sdim UbuntuPrecise, 2217244628Sdim UbuntuQuantal, 2218244628Sdim UbuntuRaring, 2219263508Sdim UbuntuSaucy, 2220263508Sdim UbuntuTrusty, 2221218893Sdim UnknownDistro 2222218893Sdim}; 2223198092Srdivacky 2224249423Sdimstatic bool IsRedhat(enum Distro Distro) { 2225263508Sdim return Distro == Fedora || (Distro >= RHEL4 && Distro <= RHEL6); 2226218893Sdim} 2227198092Srdivacky 2228263508Sdimstatic bool IsOpenSUSE(enum Distro Distro) { 2229263508Sdim return Distro == OpenSUSE; 2230193326Sed} 2231193326Sed 2232249423Sdimstatic bool IsDebian(enum Distro Distro) { 2233249423Sdim return Distro >= DebianLenny && Distro <= DebianJessie; 2234218893Sdim} 2235218893Sdim 2236249423Sdimstatic bool IsUbuntu(enum Distro Distro) { 2237263508Sdim return Distro >= UbuntuHardy && Distro <= UbuntuTrusty; 2238218893Sdim} 2239218893Sdim 2240249423Sdimstatic Distro DetectDistro(llvm::Triple::ArchType Arch) { 2241234353Sdim OwningPtr<llvm::MemoryBuffer> File; 2242218893Sdim if (!llvm::MemoryBuffer::getFile("/etc/lsb-release", File)) { 2243226633Sdim StringRef Data = File.get()->getBuffer(); 2244226633Sdim SmallVector<StringRef, 8> Lines; 2245218893Sdim Data.split(Lines, "\n"); 2246249423Sdim Distro Version = UnknownDistro; 2247234353Sdim for (unsigned i = 0, s = Lines.size(); i != s; ++i) 2248234353Sdim if (Version == UnknownDistro && Lines[i].startswith("DISTRIB_CODENAME=")) 2249249423Sdim Version = llvm::StringSwitch<Distro>(Lines[i].substr(17)) 2250234353Sdim .Case("hardy", UbuntuHardy) 2251234353Sdim .Case("intrepid", UbuntuIntrepid) 2252234353Sdim .Case("jaunty", UbuntuJaunty) 2253234353Sdim .Case("karmic", UbuntuKarmic) 2254234353Sdim .Case("lucid", UbuntuLucid) 2255234353Sdim .Case("maverick", UbuntuMaverick) 2256234353Sdim .Case("natty", UbuntuNatty) 2257234353Sdim .Case("oneiric", UbuntuOneiric) 2258234353Sdim .Case("precise", UbuntuPrecise) 2259244628Sdim .Case("quantal", UbuntuQuantal) 2260244628Sdim .Case("raring", UbuntuRaring) 2261263508Sdim .Case("saucy", UbuntuSaucy) 2262263508Sdim .Case("trusty", UbuntuTrusty) 2263234353Sdim .Default(UnknownDistro); 2264234353Sdim return Version; 2265218893Sdim } 2266218893Sdim 2267218893Sdim if (!llvm::MemoryBuffer::getFile("/etc/redhat-release", File)) { 2268226633Sdim StringRef Data = File.get()->getBuffer(); 2269263508Sdim if (Data.startswith("Fedora release")) 2270263508Sdim return Fedora; 2271223017Sdim else if (Data.startswith("Red Hat Enterprise Linux") && 2272226633Sdim Data.find("release 6") != StringRef::npos) 2273223017Sdim return RHEL6; 2274223017Sdim else if ((Data.startswith("Red Hat Enterprise Linux") || 2275249423Sdim Data.startswith("CentOS")) && 2276226633Sdim Data.find("release 5") != StringRef::npos) 2277223017Sdim return RHEL5; 2278223017Sdim else if ((Data.startswith("Red Hat Enterprise Linux") || 2279249423Sdim Data.startswith("CentOS")) && 2280226633Sdim Data.find("release 4") != StringRef::npos) 2281223017Sdim return RHEL4; 2282218893Sdim return UnknownDistro; 2283218893Sdim } 2284218893Sdim 2285218893Sdim if (!llvm::MemoryBuffer::getFile("/etc/debian_version", File)) { 2286226633Sdim StringRef Data = File.get()->getBuffer(); 2287218893Sdim if (Data[0] == '5') 2288218893Sdim return DebianLenny; 2289234353Sdim else if (Data.startswith("squeeze/sid") || Data[0] == '6') 2290218893Sdim return DebianSqueeze; 2291234353Sdim else if (Data.startswith("wheezy/sid") || Data[0] == '7') 2292223017Sdim return DebianWheezy; 2293249423Sdim else if (Data.startswith("jessie/sid") || Data[0] == '8') 2294249423Sdim return DebianJessie; 2295218893Sdim return UnknownDistro; 2296218893Sdim } 2297218893Sdim 2298263508Sdim if (llvm::sys::fs::exists("/etc/SuSE-release")) 2299263508Sdim return OpenSUSE; 2300218893Sdim 2301263508Sdim if (llvm::sys::fs::exists("/etc/exherbo-release")) 2302218893Sdim return Exherbo; 2303218893Sdim 2304263508Sdim if (llvm::sys::fs::exists("/etc/arch-release")) 2305219077Sdim return ArchLinux; 2306219077Sdim 2307218893Sdim return UnknownDistro; 2308218893Sdim} 2309218893Sdim 2310228379Sdim/// \brief Get our best guess at the multiarch triple for a target. 2311228379Sdim/// 2312228379Sdim/// Debian-based systems are starting to use a multiarch setup where they use 2313228379Sdim/// a target-triple directory in the library and header search paths. 2314228379Sdim/// Unfortunately, this triple does not align with the vanilla target triple, 2315228379Sdim/// so we provide a rough mapping here. 2316228379Sdimstatic std::string getMultiarchTriple(const llvm::Triple TargetTriple, 2317228379Sdim StringRef SysRoot) { 2318228379Sdim // For most architectures, just use whatever we have rather than trying to be 2319228379Sdim // clever. 2320228379Sdim switch (TargetTriple.getArch()) { 2321228379Sdim default: 2322228379Sdim return TargetTriple.str(); 2323226633Sdim 2324228379Sdim // We use the existence of '/lib/<triple>' as a directory to detect some 2325228379Sdim // common linux triples that don't quite match the Clang triple for both 2326234353Sdim // 32-bit and 64-bit targets. Multiarch fixes its install triples to these 2327234353Sdim // regardless of what the actual target triple is. 2328239462Sdim case llvm::Triple::arm: 2329239462Sdim case llvm::Triple::thumb: 2330239462Sdim if (TargetTriple.getEnvironment() == llvm::Triple::GNUEABIHF) { 2331239462Sdim if (llvm::sys::fs::exists(SysRoot + "/lib/arm-linux-gnueabihf")) 2332239462Sdim return "arm-linux-gnueabihf"; 2333239462Sdim } else { 2334239462Sdim if (llvm::sys::fs::exists(SysRoot + "/lib/arm-linux-gnueabi")) 2335239462Sdim return "arm-linux-gnueabi"; 2336239462Sdim } 2337239462Sdim return TargetTriple.str(); 2338228379Sdim case llvm::Triple::x86: 2339228379Sdim if (llvm::sys::fs::exists(SysRoot + "/lib/i386-linux-gnu")) 2340228379Sdim return "i386-linux-gnu"; 2341228379Sdim return TargetTriple.str(); 2342228379Sdim case llvm::Triple::x86_64: 2343228379Sdim if (llvm::sys::fs::exists(SysRoot + "/lib/x86_64-linux-gnu")) 2344228379Sdim return "x86_64-linux-gnu"; 2345228379Sdim return TargetTriple.str(); 2346249423Sdim case llvm::Triple::aarch64: 2347249423Sdim if (llvm::sys::fs::exists(SysRoot + "/lib/aarch64-linux-gnu")) 2348249423Sdim return "aarch64-linux-gnu"; 2349263508Sdim return TargetTriple.str(); 2350234353Sdim case llvm::Triple::mips: 2351234353Sdim if (llvm::sys::fs::exists(SysRoot + "/lib/mips-linux-gnu")) 2352234353Sdim return "mips-linux-gnu"; 2353234353Sdim return TargetTriple.str(); 2354234353Sdim case llvm::Triple::mipsel: 2355234353Sdim if (llvm::sys::fs::exists(SysRoot + "/lib/mipsel-linux-gnu")) 2356234353Sdim return "mipsel-linux-gnu"; 2357234353Sdim return TargetTriple.str(); 2358234353Sdim case llvm::Triple::ppc: 2359249423Sdim if (llvm::sys::fs::exists(SysRoot + "/lib/powerpc-linux-gnuspe")) 2360249423Sdim return "powerpc-linux-gnuspe"; 2361234353Sdim if (llvm::sys::fs::exists(SysRoot + "/lib/powerpc-linux-gnu")) 2362234353Sdim return "powerpc-linux-gnu"; 2363234353Sdim return TargetTriple.str(); 2364234353Sdim case llvm::Triple::ppc64: 2365234353Sdim if (llvm::sys::fs::exists(SysRoot + "/lib/powerpc64-linux-gnu")) 2366234353Sdim return "powerpc64-linux-gnu"; 2367263508Sdim case llvm::Triple::ppc64le: 2368263508Sdim if (llvm::sys::fs::exists(SysRoot + "/lib/powerpc64le-linux-gnu")) 2369263508Sdim return "powerpc64le-linux-gnu"; 2370234353Sdim return TargetTriple.str(); 2371226633Sdim } 2372226633Sdim} 2373226633Sdim 2374234353Sdimstatic void addPathIfExists(Twine Path, ToolChain::path_list &Paths) { 2375234353Sdim if (llvm::sys::fs::exists(Path)) Paths.push_back(Path.str()); 2376234353Sdim} 2377234353Sdim 2378243830Sdimstatic StringRef getMultilibDir(const llvm::Triple &Triple, 2379243830Sdim const ArgList &Args) { 2380263508Sdim if (isMipsArch(Triple.getArch())) { 2381263508Sdim // lib32 directory has a special meaning on MIPS targets. 2382263508Sdim // It contains N32 ABI binaries. Use this folder if produce 2383263508Sdim // code for N32 ABI only. 2384263508Sdim if (hasMipsN32ABIArg(Args)) 2385263508Sdim return "lib32"; 2386263508Sdim return Triple.isArch32Bit() ? "lib" : "lib64"; 2387263508Sdim } 2388243830Sdim 2389263508Sdim // It happens that only x86 and PPC use the 'lib32' variant of multilib, and 2390263508Sdim // using that variant while targeting other architectures causes problems 2391263508Sdim // because the libraries are laid out in shared system roots that can't cope 2392263508Sdim // with a 'lib32' multilib search path being considered. So we only enable 2393263508Sdim // them when we know we may need it. 2394263508Sdim // 2395263508Sdim // FIXME: This is a bit of a hack. We should really unify this code for 2396263508Sdim // reasoning about multilib spellings with the lib dir spellings in the 2397263508Sdim // GCCInstallationDetector, but that is a more significant refactoring. 2398263508Sdim if (Triple.getArch() == llvm::Triple::x86 || 2399263508Sdim Triple.getArch() == llvm::Triple::ppc) 2400243830Sdim return "lib32"; 2401243830Sdim 2402243830Sdim return Triple.isArch32Bit() ? "lib" : "lib64"; 2403243830Sdim} 2404243830Sdim 2405234353SdimLinux::Linux(const Driver &D, const llvm::Triple &Triple, const ArgList &Args) 2406234353Sdim : Generic_ELF(D, Triple, Args) { 2407263508Sdim GCCInstallation.init(Triple, Args); 2408234353Sdim llvm::Triple::ArchType Arch = Triple.getArch(); 2409263508Sdim std::string SysRoot = computeSysRoot(); 2410226633Sdim 2411263508Sdim // Cross-compiling binutils and GCC installations (vanilla and openSUSE at 2412263508Sdim // least) put various tools in a triple-prefixed directory off of the parent 2413263508Sdim // of the GCC installation. We use the GCC triple here to ensure that we end 2414263508Sdim // up with tools that support the same amount of cross compiling as the 2415263508Sdim // detected GCC installation. For example, if we find a GCC installation 2416263508Sdim // targeting x86_64, but it is a bi-arch GCC installation, it can also be 2417263508Sdim // used to target i386. 2418263508Sdim // FIXME: This seems unlikely to be Linux-specific. 2419226633Sdim ToolChain::path_list &PPaths = getProgramPaths(); 2420228379Sdim PPaths.push_back(Twine(GCCInstallation.getParentLibPath() + "/../" + 2421234353Sdim GCCInstallation.getTriple().str() + "/bin").str()); 2422226633Sdim 2423226633Sdim Linker = GetProgramPath("ld"); 2424226633Sdim 2425249423Sdim Distro Distro = DetectDistro(Arch); 2426218893Sdim 2427263508Sdim if (IsOpenSUSE(Distro) || IsUbuntu(Distro)) { 2428218893Sdim ExtraOpts.push_back("-z"); 2429218893Sdim ExtraOpts.push_back("relro"); 2430218893Sdim } 2431218893Sdim 2432221345Sdim if (Arch == llvm::Triple::arm || Arch == llvm::Triple::thumb) 2433218893Sdim ExtraOpts.push_back("-X"); 2434218893Sdim 2435243830Sdim const bool IsAndroid = Triple.getEnvironment() == llvm::Triple::Android; 2436251662Sdim const bool IsMips = isMipsArch(Arch); 2437218893Sdim 2438251662Sdim if (IsMips && !SysRoot.empty()) 2439251662Sdim ExtraOpts.push_back("--sysroot=" + SysRoot); 2440251662Sdim 2441234353Sdim // Do not use 'gnu' hash style for Mips targets because .gnu.hash 2442234353Sdim // and the MIPS ABI require .dynsym to be sorted in different ways. 2443234353Sdim // .gnu.hash needs symbols to be grouped by hash code whereas the MIPS 2444234353Sdim // ABI requires a mapping between the GOT and the symbol table. 2445234353Sdim // Android loader does not support .gnu.hash. 2446251662Sdim if (!IsMips && !IsAndroid) { 2447263508Sdim if (IsRedhat(Distro) || IsOpenSUSE(Distro) || 2448234353Sdim (IsUbuntu(Distro) && Distro >= UbuntuMaverick)) 2449234353Sdim ExtraOpts.push_back("--hash-style=gnu"); 2450234353Sdim 2451263508Sdim if (IsDebian(Distro) || IsOpenSUSE(Distro) || Distro == UbuntuLucid || 2452234353Sdim Distro == UbuntuJaunty || Distro == UbuntuKarmic) 2453234353Sdim ExtraOpts.push_back("--hash-style=both"); 2454234353Sdim } 2455234353Sdim 2456223017Sdim if (IsRedhat(Distro)) 2457218893Sdim ExtraOpts.push_back("--no-add-needed"); 2458218893Sdim 2459223017Sdim if (Distro == DebianSqueeze || Distro == DebianWheezy || 2460263508Sdim Distro == DebianJessie || IsOpenSUSE(Distro) || 2461223017Sdim (IsRedhat(Distro) && Distro != RHEL4 && Distro != RHEL5) || 2462234353Sdim (IsUbuntu(Distro) && Distro >= UbuntuKarmic)) 2463218893Sdim ExtraOpts.push_back("--build-id"); 2464218893Sdim 2465263508Sdim if (IsOpenSUSE(Distro)) 2466223017Sdim ExtraOpts.push_back("--enable-new-dtags"); 2467223017Sdim 2468226633Sdim // The selection of paths to try here is designed to match the patterns which 2469226633Sdim // the GCC driver itself uses, as this is part of the GCC-compatible driver. 2470226633Sdim // This was determined by running GCC in a fake filesystem, creating all 2471226633Sdim // possible permutations of these directories, and seeing which ones it added 2472226633Sdim // to the link paths. 2473226633Sdim path_list &Paths = getFilePaths(); 2474219077Sdim 2475243830Sdim const std::string Multilib = getMultilibDir(Triple, Args); 2476228379Sdim const std::string MultiarchTriple = getMultiarchTriple(Triple, SysRoot); 2477226633Sdim 2478228379Sdim // Add the multilib suffixed paths where they are available. 2479228379Sdim if (GCCInstallation.isValid()) { 2480234353Sdim const llvm::Triple &GCCTriple = GCCInstallation.getTriple(); 2481228379Sdim const std::string &LibPath = GCCInstallation.getParentLibPath(); 2482234353Sdim 2483263508Sdim // Sourcery CodeBench MIPS toolchain holds some libraries under 2484263508Sdim // a biarch-like suffix of the GCC installation. 2485263508Sdim // 2486263508Sdim // FIXME: It would be cleaner to model this as a variant of bi-arch. IE, 2487263508Sdim // instead of a '64' biarch suffix it would be 'el' or something. 2488263508Sdim if (IsAndroid && IsMips && isMips32r2(Args)) { 2489263508Sdim assert(GCCInstallation.getBiarchSuffix().empty() && 2490263508Sdim "Unexpected bi-arch suffix"); 2491263508Sdim addPathIfExists(GCCInstallation.getInstallPath() + "/mips-r2", Paths); 2492263508Sdim } else { 2493243830Sdim addPathIfExists((GCCInstallation.getInstallPath() + 2494263508Sdim GCCInstallation.getMIPSABIDirSuffix() + 2495263508Sdim GCCInstallation.getBiarchSuffix()), 2496243830Sdim Paths); 2497263508Sdim } 2498243830Sdim 2499263508Sdim // GCC cross compiling toolchains will install target libraries which ship 2500263508Sdim // as part of the toolchain under <prefix>/<triple>/<libdir> rather than as 2501263508Sdim // any part of the GCC installation in 2502263508Sdim // <prefix>/<libdir>/gcc/<triple>/<version>. This decision is somewhat 2503263508Sdim // debatable, but is the reality today. We need to search this tree even 2504263508Sdim // when we have a sysroot somewhere else. It is the responsibility of 2505263508Sdim // whomever is doing the cross build targetting a sysroot using a GCC 2506263508Sdim // installation that is *not* within the system root to ensure two things: 2507263508Sdim // 2508263508Sdim // 1) Any DSOs that are linked in from this tree or from the install path 2509263508Sdim // above must be preasant on the system root and found via an 2510263508Sdim // appropriate rpath. 2511263508Sdim // 2) There must not be libraries installed into 2512263508Sdim // <prefix>/<triple>/<libdir> unless they should be preferred over 2513263508Sdim // those within the system root. 2514263508Sdim // 2515263508Sdim // Note that this matches the GCC behavior. See the below comment for where 2516263508Sdim // Clang diverges from GCC's behavior. 2517263508Sdim addPathIfExists(LibPath + "/../" + GCCTriple.str() + "/lib/../" + Multilib + 2518263508Sdim GCCInstallation.getMIPSABIDirSuffix(), 2519263508Sdim Paths); 2520263508Sdim 2521234353Sdim // If the GCC installation we found is inside of the sysroot, we want to 2522234353Sdim // prefer libraries installed in the parent prefix of the GCC installation. 2523234353Sdim // It is important to *not* use these paths when the GCC installation is 2524234982Sdim // outside of the system root as that can pick up unintended libraries. 2525234353Sdim // This usually happens when there is an external cross compiler on the 2526234353Sdim // host system, and a more minimal sysroot available that is the target of 2527263508Sdim // the cross. Note that GCC does include some of these directories in some 2528263508Sdim // configurations but this seems somewhere between questionable and simply 2529263508Sdim // a bug. 2530234353Sdim if (StringRef(LibPath).startswith(SysRoot)) { 2531234353Sdim addPathIfExists(LibPath + "/" + MultiarchTriple, Paths); 2532234353Sdim addPathIfExists(LibPath + "/../" + Multilib, Paths); 2533234353Sdim } 2534228379Sdim } 2535228379Sdim addPathIfExists(SysRoot + "/lib/" + MultiarchTriple, Paths); 2536228379Sdim addPathIfExists(SysRoot + "/lib/../" + Multilib, Paths); 2537228379Sdim addPathIfExists(SysRoot + "/usr/lib/" + MultiarchTriple, Paths); 2538228379Sdim addPathIfExists(SysRoot + "/usr/lib/../" + Multilib, Paths); 2539226633Sdim 2540263508Sdim // Try walking via the GCC triple path in case of biarch or multiarch GCC 2541228379Sdim // installations with strange symlinks. 2542263508Sdim if (GCCInstallation.isValid()) { 2543234353Sdim addPathIfExists(SysRoot + "/usr/lib/" + GCCInstallation.getTriple().str() + 2544228379Sdim "/../../" + Multilib, Paths); 2545226633Sdim 2546263508Sdim // Add the non-multilib suffixed paths (if potentially different). 2547226633Sdim const std::string &LibPath = GCCInstallation.getParentLibPath(); 2548234353Sdim const llvm::Triple &GCCTriple = GCCInstallation.getTriple(); 2549263508Sdim if (!GCCInstallation.getBiarchSuffix().empty()) 2550263508Sdim addPathIfExists(GCCInstallation.getInstallPath() + 2551263508Sdim GCCInstallation.getMIPSABIDirSuffix(), Paths); 2552234353Sdim 2553263508Sdim // See comments above on the multilib variant for details of why this is 2554263508Sdim // included even from outside the sysroot. 2555263508Sdim addPathIfExists(LibPath + "/../" + GCCTriple.str() + 2556263508Sdim "/lib" + GCCInstallation.getMIPSABIDirSuffix(), Paths); 2557263508Sdim 2558263508Sdim // See comments above on the multilib variant for details of why this is 2559263508Sdim // only included from within the sysroot. 2560263508Sdim if (StringRef(LibPath).startswith(SysRoot)) 2561234353Sdim addPathIfExists(LibPath, Paths); 2562226633Sdim } 2563226633Sdim addPathIfExists(SysRoot + "/lib", Paths); 2564226633Sdim addPathIfExists(SysRoot + "/usr/lib", Paths); 2565263508Sdim} 2566251662Sdim 2567263508Sdimbool FreeBSD::HasNativeLLVMSupport() const { 2568263508Sdim return true; 2569218893Sdim} 2570218893Sdim 2571218893Sdimbool Linux::HasNativeLLVMSupport() const { 2572218893Sdim return true; 2573218893Sdim} 2574218893Sdim 2575249423SdimTool *Linux::buildLinker() const { 2576249423Sdim return new tools::gnutools::Link(*this); 2577249423Sdim} 2578212904Sdim 2579249423SdimTool *Linux::buildAssembler() const { 2580249423Sdim return new tools::gnutools::Assemble(*this); 2581212904Sdim} 2582212904Sdim 2583263508Sdimstd::string Linux::computeSysRoot() const { 2584251662Sdim if (!getDriver().SysRoot.empty()) 2585251662Sdim return getDriver().SysRoot; 2586251662Sdim 2587251662Sdim if (!GCCInstallation.isValid() || !isMipsArch(getTriple().getArch())) 2588251662Sdim return std::string(); 2589251662Sdim 2590263508Sdim // Standalone MIPS toolchains use different names for sysroot folder 2591263508Sdim // and put it into different places. Here we try to check some known 2592263508Sdim // variants. 2593251662Sdim 2594263508Sdim const StringRef InstallDir = GCCInstallation.getInstallPath(); 2595263508Sdim const StringRef TripleStr = GCCInstallation.getTriple().str(); 2596263508Sdim const StringRef MIPSABIDirSuffix = GCCInstallation.getMIPSABIDirSuffix(); 2597263508Sdim 2598263508Sdim std::string Path = (InstallDir + "/../../../../" + TripleStr + "/libc" + 2599263508Sdim MIPSABIDirSuffix).str(); 2600263508Sdim 2601263508Sdim if (llvm::sys::fs::exists(Path)) 2602263508Sdim return Path; 2603263508Sdim 2604263508Sdim Path = (InstallDir + "/../../../../sysroot" + MIPSABIDirSuffix).str(); 2605263508Sdim 2606263508Sdim if (llvm::sys::fs::exists(Path)) 2607263508Sdim return Path; 2608263508Sdim 2609263508Sdim return std::string(); 2610251662Sdim} 2611251662Sdim 2612228379Sdimvoid Linux::AddClangSystemIncludeArgs(const ArgList &DriverArgs, 2613228379Sdim ArgStringList &CC1Args) const { 2614228379Sdim const Driver &D = getDriver(); 2615263508Sdim std::string SysRoot = computeSysRoot(); 2616228379Sdim 2617228379Sdim if (DriverArgs.hasArg(options::OPT_nostdinc)) 2618228379Sdim return; 2619228379Sdim 2620228379Sdim if (!DriverArgs.hasArg(options::OPT_nostdlibinc)) 2621251662Sdim addSystemInclude(DriverArgs, CC1Args, SysRoot + "/usr/local/include"); 2622228379Sdim 2623228379Sdim if (!DriverArgs.hasArg(options::OPT_nobuiltininc)) { 2624263508Sdim SmallString<128> P(D.ResourceDir); 2625263508Sdim llvm::sys::path::append(P, "include"); 2626228379Sdim addSystemInclude(DriverArgs, CC1Args, P.str()); 2627228379Sdim } 2628228379Sdim 2629228379Sdim if (DriverArgs.hasArg(options::OPT_nostdlibinc)) 2630228379Sdim return; 2631228379Sdim 2632228379Sdim // Check for configure-time C include directories. 2633228379Sdim StringRef CIncludeDirs(C_INCLUDE_DIRS); 2634228379Sdim if (CIncludeDirs != "") { 2635228379Sdim SmallVector<StringRef, 5> dirs; 2636228379Sdim CIncludeDirs.split(dirs, ":"); 2637228379Sdim for (SmallVectorImpl<StringRef>::iterator I = dirs.begin(), E = dirs.end(); 2638228379Sdim I != E; ++I) { 2639251662Sdim StringRef Prefix = llvm::sys::path::is_absolute(*I) ? SysRoot : ""; 2640228379Sdim addExternCSystemInclude(DriverArgs, CC1Args, Prefix + *I); 2641228379Sdim } 2642228379Sdim return; 2643228379Sdim } 2644228379Sdim 2645228379Sdim // Lacking those, try to detect the correct set of system includes for the 2646228379Sdim // target triple. 2647228379Sdim 2648251662Sdim // Sourcery CodeBench and modern FSF Mips toolchains put extern C 2649251662Sdim // system includes under three additional directories. 2650251662Sdim if (GCCInstallation.isValid() && isMipsArch(getTriple().getArch())) { 2651263508Sdim addExternCSystemIncludeIfExists( 2652263508Sdim DriverArgs, CC1Args, GCCInstallation.getInstallPath() + "/include"); 2653251662Sdim 2654263508Sdim addExternCSystemIncludeIfExists( 2655263508Sdim DriverArgs, CC1Args, 2656263508Sdim GCCInstallation.getInstallPath() + "/../../../../" + 2657263508Sdim GCCInstallation.getTriple().str() + "/libc/usr/include"); 2658263508Sdim 2659263508Sdim addExternCSystemIncludeIfExists( 2660263508Sdim DriverArgs, CC1Args, 2661263508Sdim GCCInstallation.getInstallPath() + "/../../../../sysroot/usr/include"); 2662251662Sdim } 2663251662Sdim 2664228379Sdim // Implement generic Debian multiarch support. 2665228379Sdim const StringRef X86_64MultiarchIncludeDirs[] = { 2666228379Sdim "/usr/include/x86_64-linux-gnu", 2667228379Sdim 2668228379Sdim // FIXME: These are older forms of multiarch. It's not clear that they're 2669228379Sdim // in use in any released version of Debian, so we should consider 2670228379Sdim // removing them. 2671263508Sdim "/usr/include/i686-linux-gnu/64", "/usr/include/i486-linux-gnu/64" 2672228379Sdim }; 2673228379Sdim const StringRef X86MultiarchIncludeDirs[] = { 2674228379Sdim "/usr/include/i386-linux-gnu", 2675228379Sdim 2676228379Sdim // FIXME: These are older forms of multiarch. It's not clear that they're 2677228379Sdim // in use in any released version of Debian, so we should consider 2678228379Sdim // removing them. 2679263508Sdim "/usr/include/x86_64-linux-gnu/32", "/usr/include/i686-linux-gnu", 2680228379Sdim "/usr/include/i486-linux-gnu" 2681228379Sdim }; 2682249423Sdim const StringRef AArch64MultiarchIncludeDirs[] = { 2683249423Sdim "/usr/include/aarch64-linux-gnu" 2684249423Sdim }; 2685228379Sdim const StringRef ARMMultiarchIncludeDirs[] = { 2686228379Sdim "/usr/include/arm-linux-gnueabi" 2687228379Sdim }; 2688239462Sdim const StringRef ARMHFMultiarchIncludeDirs[] = { 2689239462Sdim "/usr/include/arm-linux-gnueabihf" 2690239462Sdim }; 2691234353Sdim const StringRef MIPSMultiarchIncludeDirs[] = { 2692234353Sdim "/usr/include/mips-linux-gnu" 2693234353Sdim }; 2694234353Sdim const StringRef MIPSELMultiarchIncludeDirs[] = { 2695234353Sdim "/usr/include/mipsel-linux-gnu" 2696234353Sdim }; 2697234353Sdim const StringRef PPCMultiarchIncludeDirs[] = { 2698234353Sdim "/usr/include/powerpc-linux-gnu" 2699234353Sdim }; 2700234353Sdim const StringRef PPC64MultiarchIncludeDirs[] = { 2701234353Sdim "/usr/include/powerpc64-linux-gnu" 2702234353Sdim }; 2703228379Sdim ArrayRef<StringRef> MultiarchIncludeDirs; 2704228379Sdim if (getTriple().getArch() == llvm::Triple::x86_64) { 2705228379Sdim MultiarchIncludeDirs = X86_64MultiarchIncludeDirs; 2706228379Sdim } else if (getTriple().getArch() == llvm::Triple::x86) { 2707228379Sdim MultiarchIncludeDirs = X86MultiarchIncludeDirs; 2708249423Sdim } else if (getTriple().getArch() == llvm::Triple::aarch64) { 2709249423Sdim MultiarchIncludeDirs = AArch64MultiarchIncludeDirs; 2710228379Sdim } else if (getTriple().getArch() == llvm::Triple::arm) { 2711239462Sdim if (getTriple().getEnvironment() == llvm::Triple::GNUEABIHF) 2712239462Sdim MultiarchIncludeDirs = ARMHFMultiarchIncludeDirs; 2713239462Sdim else 2714239462Sdim MultiarchIncludeDirs = ARMMultiarchIncludeDirs; 2715234353Sdim } else if (getTriple().getArch() == llvm::Triple::mips) { 2716234353Sdim MultiarchIncludeDirs = MIPSMultiarchIncludeDirs; 2717234353Sdim } else if (getTriple().getArch() == llvm::Triple::mipsel) { 2718234353Sdim MultiarchIncludeDirs = MIPSELMultiarchIncludeDirs; 2719234353Sdim } else if (getTriple().getArch() == llvm::Triple::ppc) { 2720234353Sdim MultiarchIncludeDirs = PPCMultiarchIncludeDirs; 2721234353Sdim } else if (getTriple().getArch() == llvm::Triple::ppc64) { 2722234353Sdim MultiarchIncludeDirs = PPC64MultiarchIncludeDirs; 2723228379Sdim } 2724228379Sdim for (ArrayRef<StringRef>::iterator I = MultiarchIncludeDirs.begin(), 2725228379Sdim E = MultiarchIncludeDirs.end(); 2726228379Sdim I != E; ++I) { 2727251662Sdim if (llvm::sys::fs::exists(SysRoot + *I)) { 2728251662Sdim addExternCSystemInclude(DriverArgs, CC1Args, SysRoot + *I); 2729228379Sdim break; 2730228379Sdim } 2731228379Sdim } 2732228379Sdim 2733228379Sdim if (getTriple().getOS() == llvm::Triple::RTEMS) 2734228379Sdim return; 2735228379Sdim 2736234353Sdim // Add an include of '/include' directly. This isn't provided by default by 2737234353Sdim // system GCCs, but is often used with cross-compiling GCCs, and harmless to 2738234353Sdim // add even when Clang is acting as-if it were a system compiler. 2739251662Sdim addExternCSystemInclude(DriverArgs, CC1Args, SysRoot + "/include"); 2740234353Sdim 2741251662Sdim addExternCSystemInclude(DriverArgs, CC1Args, SysRoot + "/usr/include"); 2742228379Sdim} 2743228379Sdim 2744249423Sdim/// \brief Helper to add the three variant paths for a libstdc++ installation. 2745234353Sdim/*static*/ bool Linux::addLibStdCXXIncludePaths(Twine Base, Twine TargetArchDir, 2746234353Sdim const ArgList &DriverArgs, 2747234353Sdim ArgStringList &CC1Args) { 2748228379Sdim if (!llvm::sys::fs::exists(Base)) 2749228379Sdim return false; 2750228379Sdim addSystemInclude(DriverArgs, CC1Args, Base); 2751228379Sdim addSystemInclude(DriverArgs, CC1Args, Base + "/" + TargetArchDir); 2752228379Sdim addSystemInclude(DriverArgs, CC1Args, Base + "/backward"); 2753228379Sdim return true; 2754228379Sdim} 2755228379Sdim 2756249423Sdim/// \brief Helper to add an extra variant path for an (Ubuntu) multilib 2757249423Sdim/// libstdc++ installation. 2758249423Sdim/*static*/ bool Linux::addLibStdCXXIncludePaths(Twine Base, Twine Suffix, 2759249423Sdim Twine TargetArchDir, 2760263508Sdim Twine BiarchSuffix, 2761263508Sdim Twine MIPSABIDirSuffix, 2762249423Sdim const ArgList &DriverArgs, 2763249423Sdim ArgStringList &CC1Args) { 2764263508Sdim if (!addLibStdCXXIncludePaths(Base + Suffix, 2765263508Sdim TargetArchDir + MIPSABIDirSuffix + BiarchSuffix, 2766249423Sdim DriverArgs, CC1Args)) 2767249423Sdim return false; 2768249423Sdim 2769249423Sdim addSystemInclude(DriverArgs, CC1Args, Base + "/" + TargetArchDir + Suffix 2770263508Sdim + MIPSABIDirSuffix + BiarchSuffix); 2771249423Sdim return true; 2772249423Sdim} 2773249423Sdim 2774228379Sdimvoid Linux::AddClangCXXStdlibIncludeArgs(const ArgList &DriverArgs, 2775228379Sdim ArgStringList &CC1Args) const { 2776228379Sdim if (DriverArgs.hasArg(options::OPT_nostdlibinc) || 2777228379Sdim DriverArgs.hasArg(options::OPT_nostdincxx)) 2778228379Sdim return; 2779228379Sdim 2780228379Sdim // Check if libc++ has been enabled and provide its include paths if so. 2781228379Sdim if (GetCXXStdlibType(DriverArgs) == ToolChain::CST_Libcxx) { 2782228379Sdim // libc++ is always installed at a fixed path on Linux currently. 2783228379Sdim addSystemInclude(DriverArgs, CC1Args, 2784228379Sdim getDriver().SysRoot + "/usr/include/c++/v1"); 2785228379Sdim return; 2786228379Sdim } 2787228379Sdim 2788234353Sdim // We need a detected GCC installation on Linux to provide libstdc++'s 2789234353Sdim // headers. We handled the libc++ case above. 2790234353Sdim if (!GCCInstallation.isValid()) 2791228379Sdim return; 2792228379Sdim 2793228379Sdim // By default, look for the C++ headers in an include directory adjacent to 2794228379Sdim // the lib directory of the GCC installation. Note that this is expect to be 2795228379Sdim // equivalent to '/usr/include/c++/X.Y' in almost all cases. 2796228379Sdim StringRef LibDir = GCCInstallation.getParentLibPath(); 2797228379Sdim StringRef InstallDir = GCCInstallation.getInstallPath(); 2798243830Sdim StringRef TripleStr = GCCInstallation.getTriple().str(); 2799263508Sdim StringRef MIPSABIDirSuffix = GCCInstallation.getMIPSABIDirSuffix(); 2800263508Sdim StringRef BiarchSuffix = GCCInstallation.getBiarchSuffix(); 2801263508Sdim const GCCVersion &Version = GCCInstallation.getVersion(); 2802243830Sdim 2803263508Sdim if (addLibStdCXXIncludePaths(LibDir.str() + "/../include", 2804263508Sdim "/c++/" + Version.Text, TripleStr, BiarchSuffix, 2805263508Sdim MIPSABIDirSuffix, DriverArgs, CC1Args)) 2806249423Sdim return; 2807249423Sdim 2808243830Sdim const std::string IncludePathCandidates[] = { 2809228379Sdim // Gentoo is weird and places its headers inside the GCC install, so if the 2810263508Sdim // first attempt to find the headers fails, try these patterns. 2811263508Sdim InstallDir.str() + "/include/g++-v" + Version.MajorStr + "." + 2812263508Sdim Version.MinorStr, 2813263508Sdim InstallDir.str() + "/include/g++-v" + Version.MajorStr, 2814243830Sdim // Android standalone toolchain has C++ headers in yet another place. 2815263508Sdim LibDir.str() + "/../" + TripleStr.str() + "/include/c++/" + Version.Text, 2816243830Sdim // Freescale SDK C++ headers are directly in <sysroot>/usr/include/c++, 2817243830Sdim // without a subdirectory corresponding to the gcc version. 2818243830Sdim LibDir.str() + "/../include/c++", 2819243830Sdim }; 2820243830Sdim 2821243830Sdim for (unsigned i = 0; i < llvm::array_lengthof(IncludePathCandidates); ++i) { 2822263508Sdim if (addLibStdCXXIncludePaths(IncludePathCandidates[i], 2823263508Sdim TripleStr + MIPSABIDirSuffix + BiarchSuffix, 2824263508Sdim DriverArgs, CC1Args)) 2825243830Sdim break; 2826228379Sdim } 2827228379Sdim} 2828228379Sdim 2829251662Sdimbool Linux::isPIEDefault() const { 2830263508Sdim return getSanitizerArgs().hasZeroBaseShadow(); 2831251662Sdim} 2832251662Sdim 2833193326Sed/// DragonFly - DragonFly tool chain which can call as(1) and ld(1) directly. 2834193326Sed 2835234353SdimDragonFly::DragonFly(const Driver &D, const llvm::Triple& Triple, const ArgList &Args) 2836234353Sdim : Generic_ELF(D, Triple, Args) { 2837193326Sed 2838193326Sed // Path mangling to find libexec 2839212904Sdim getProgramPaths().push_back(getDriver().getInstalledDir()); 2840221345Sdim if (getDriver().getInstalledDir() != getDriver().Dir) 2841212904Sdim getProgramPaths().push_back(getDriver().Dir); 2842193326Sed 2843201361Srdivacky getFilePaths().push_back(getDriver().Dir + "/../lib"); 2844193326Sed getFilePaths().push_back("/usr/lib"); 2845251662Sdim if (llvm::sys::fs::exists("/usr/lib/gcc47")) 2846251662Sdim getFilePaths().push_back("/usr/lib/gcc47"); 2847251662Sdim else 2848251662Sdim getFilePaths().push_back("/usr/lib/gcc44"); 2849193326Sed} 2850193326Sed 2851249423SdimTool *DragonFly::buildAssembler() const { 2852249423Sdim return new tools::dragonfly::Assemble(*this); 2853249423Sdim} 2854193326Sed 2855249423SdimTool *DragonFly::buildLinker() const { 2856249423Sdim return new tools::dragonfly::Link(*this); 2857193326Sed} 2858263508Sdim 2859263508Sdim 2860263508Sdim/// XCore tool chain 2861263508SdimXCore::XCore(const Driver &D, const llvm::Triple &Triple, 2862263508Sdim const ArgList &Args) : ToolChain(D, Triple, Args) { 2863263508Sdim // ProgramPaths are found via 'PATH' environment variable. 2864263508Sdim} 2865263508Sdim 2866263508SdimTool *XCore::buildAssembler() const { 2867263508Sdim return new tools::XCore::Assemble(*this); 2868263508Sdim} 2869263508Sdim 2870263508SdimTool *XCore::buildLinker() const { 2871263508Sdim return new tools::XCore::Link(*this); 2872263508Sdim} 2873263508Sdim 2874263508Sdimbool XCore::isPICDefault() const { 2875263508Sdim return false; 2876263508Sdim} 2877263508Sdim 2878263508Sdimbool XCore::isPIEDefault() const { 2879263508Sdim return false; 2880263508Sdim} 2881263508Sdim 2882263508Sdimbool XCore::isPICDefaultForced() const { 2883263508Sdim return false; 2884263508Sdim} 2885263508Sdim 2886263508Sdimbool XCore::SupportsProfiling() const { 2887263508Sdim return false; 2888263508Sdim} 2889263508Sdim 2890263508Sdimbool XCore::hasBlocksRuntime() const { 2891263508Sdim return false; 2892263508Sdim} 2893263508Sdim 2894263508Sdim 2895263508Sdimvoid XCore::AddClangSystemIncludeArgs(const ArgList &DriverArgs, 2896263508Sdim ArgStringList &CC1Args) const { 2897263508Sdim if (DriverArgs.hasArg(options::OPT_nostdinc) || 2898263508Sdim DriverArgs.hasArg(options::OPT_nostdlibinc)) 2899263508Sdim return; 2900263508Sdim if (const char *cl_include_dir = getenv("XCC_C_INCLUDE_PATH")) { 2901263508Sdim SmallVector<StringRef, 4> Dirs; 2902263508Sdim const char EnvPathSeparatorStr[] = {llvm::sys::EnvPathSeparator,'\0'}; 2903263508Sdim StringRef(cl_include_dir).split(Dirs, StringRef(EnvPathSeparatorStr)); 2904263508Sdim ArrayRef<StringRef> DirVec(Dirs); 2905263508Sdim addSystemIncludes(DriverArgs, CC1Args, DirVec); 2906263508Sdim } 2907263508Sdim} 2908263508Sdim 2909263508Sdimvoid XCore::addClangTargetOptions(const llvm::opt::ArgList &DriverArgs, 2910263508Sdim llvm::opt::ArgStringList &CC1Args) const { 2911263508Sdim CC1Args.push_back("-nostdsysteminc"); 2912263508Sdim} 2913263508Sdim 2914263508Sdimvoid XCore::AddClangCXXStdlibIncludeArgs(const ArgList &DriverArgs, 2915263508Sdim ArgStringList &CC1Args) const { 2916263508Sdim if (DriverArgs.hasArg(options::OPT_nostdinc) || 2917263508Sdim DriverArgs.hasArg(options::OPT_nostdlibinc)) 2918263508Sdim return; 2919263508Sdim if (const char *cl_include_dir = getenv("XCC_CPLUS_INCLUDE_PATH")) { 2920263508Sdim SmallVector<StringRef, 4> Dirs; 2921263508Sdim const char EnvPathSeparatorStr[] = {llvm::sys::EnvPathSeparator,'\0'}; 2922263508Sdim StringRef(cl_include_dir).split(Dirs, StringRef(EnvPathSeparatorStr)); 2923263508Sdim ArrayRef<StringRef> DirVec(Dirs); 2924263508Sdim addSystemIncludes(DriverArgs, CC1Args, DirVec); 2925263508Sdim } 2926263508Sdim} 2927263508Sdim 2928263508Sdimvoid XCore::AddCXXStdlibLibArgs(const ArgList &Args, 2929263508Sdim ArgStringList &CmdArgs) const { 2930263508Sdim // We don't output any lib args. This is handled by xcc. 2931263508Sdim} 2932