ToolChains.cpp revision 263508
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 1167251662Sdim static const char *const SystemZLibDirs[] = { "/lib64", "/lib" }; 1168251662Sdim static const char *const SystemZTriples[] = { 1169263508Sdim "s390x-linux-gnu", "s390x-unknown-linux-gnu", "s390x-ibm-linux-gnu", 1170263508Sdim "s390x-suse-linux", "s390x-redhat-linux" 1171251662Sdim }; 1172251662Sdim 1173234353Sdim switch (TargetTriple.getArch()) { 1174249423Sdim case llvm::Triple::aarch64: 1175263508Sdim LibDirs.append(AArch64LibDirs, 1176263508Sdim AArch64LibDirs + llvm::array_lengthof(AArch64LibDirs)); 1177263508Sdim TripleAliases.append(AArch64Triples, 1178263508Sdim AArch64Triples + llvm::array_lengthof(AArch64Triples)); 1179263508Sdim BiarchLibDirs.append(AArch64LibDirs, 1180263508Sdim AArch64LibDirs + llvm::array_lengthof(AArch64LibDirs)); 1181263508Sdim BiarchTripleAliases.append( 1182263508Sdim AArch64Triples, AArch64Triples + llvm::array_lengthof(AArch64Triples)); 1183249423Sdim break; 1184234353Sdim case llvm::Triple::arm: 1185234353Sdim case llvm::Triple::thumb: 1186234353Sdim LibDirs.append(ARMLibDirs, ARMLibDirs + llvm::array_lengthof(ARMLibDirs)); 1187239462Sdim if (TargetTriple.getEnvironment() == llvm::Triple::GNUEABIHF) { 1188263508Sdim TripleAliases.append(ARMHFTriples, 1189263508Sdim ARMHFTriples + llvm::array_lengthof(ARMHFTriples)); 1190239462Sdim } else { 1191263508Sdim TripleAliases.append(ARMTriples, 1192263508Sdim ARMTriples + llvm::array_lengthof(ARMTriples)); 1193239462Sdim } 1194234353Sdim break; 1195234353Sdim case llvm::Triple::x86_64: 1196263508Sdim LibDirs.append(X86_64LibDirs, 1197263508Sdim X86_64LibDirs + llvm::array_lengthof(X86_64LibDirs)); 1198263508Sdim TripleAliases.append(X86_64Triples, 1199263508Sdim X86_64Triples + llvm::array_lengthof(X86_64Triples)); 1200263508Sdim BiarchLibDirs.append(X86LibDirs, 1201263508Sdim X86LibDirs + llvm::array_lengthof(X86LibDirs)); 1202263508Sdim BiarchTripleAliases.append(X86Triples, 1203263508Sdim X86Triples + llvm::array_lengthof(X86Triples)); 1204234353Sdim break; 1205234353Sdim case llvm::Triple::x86: 1206234353Sdim LibDirs.append(X86LibDirs, X86LibDirs + llvm::array_lengthof(X86LibDirs)); 1207263508Sdim TripleAliases.append(X86Triples, 1208263508Sdim X86Triples + llvm::array_lengthof(X86Triples)); 1209263508Sdim BiarchLibDirs.append(X86_64LibDirs, 1210263508Sdim X86_64LibDirs + llvm::array_lengthof(X86_64LibDirs)); 1211263508Sdim BiarchTripleAliases.append( 1212263508Sdim X86_64Triples, X86_64Triples + llvm::array_lengthof(X86_64Triples)); 1213234353Sdim break; 1214234353Sdim case llvm::Triple::mips: 1215263508Sdim LibDirs.append(MIPSLibDirs, 1216263508Sdim MIPSLibDirs + llvm::array_lengthof(MIPSLibDirs)); 1217263508Sdim TripleAliases.append(MIPSTriples, 1218263508Sdim MIPSTriples + llvm::array_lengthof(MIPSTriples)); 1219263508Sdim BiarchLibDirs.append(MIPS64LibDirs, 1220263508Sdim MIPS64LibDirs + llvm::array_lengthof(MIPS64LibDirs)); 1221263508Sdim BiarchTripleAliases.append( 1222263508Sdim MIPS64Triples, MIPS64Triples + llvm::array_lengthof(MIPS64Triples)); 1223234353Sdim break; 1224234353Sdim case llvm::Triple::mipsel: 1225263508Sdim LibDirs.append(MIPSELLibDirs, 1226263508Sdim MIPSELLibDirs + llvm::array_lengthof(MIPSELLibDirs)); 1227263508Sdim TripleAliases.append(MIPSELTriples, 1228263508Sdim MIPSELTriples + llvm::array_lengthof(MIPSELTriples)); 1229263508Sdim TripleAliases.append(MIPSTriples, 1230263508Sdim MIPSTriples + llvm::array_lengthof(MIPSTriples)); 1231263508Sdim BiarchLibDirs.append( 1232263508Sdim MIPS64ELLibDirs, 1233263508Sdim MIPS64ELLibDirs + llvm::array_lengthof(MIPS64ELLibDirs)); 1234263508Sdim BiarchTripleAliases.append( 1235263508Sdim MIPS64ELTriples, 1236263508Sdim MIPS64ELTriples + llvm::array_lengthof(MIPS64ELTriples)); 1237234353Sdim break; 1238239462Sdim case llvm::Triple::mips64: 1239263508Sdim LibDirs.append(MIPS64LibDirs, 1240263508Sdim MIPS64LibDirs + llvm::array_lengthof(MIPS64LibDirs)); 1241263508Sdim TripleAliases.append(MIPS64Triples, 1242263508Sdim MIPS64Triples + llvm::array_lengthof(MIPS64Triples)); 1243263508Sdim BiarchLibDirs.append(MIPSLibDirs, 1244263508Sdim MIPSLibDirs + llvm::array_lengthof(MIPSLibDirs)); 1245263508Sdim BiarchTripleAliases.append(MIPSTriples, 1246263508Sdim MIPSTriples + llvm::array_lengthof(MIPSTriples)); 1247239462Sdim break; 1248239462Sdim case llvm::Triple::mips64el: 1249263508Sdim LibDirs.append(MIPS64ELLibDirs, 1250263508Sdim MIPS64ELLibDirs + llvm::array_lengthof(MIPS64ELLibDirs)); 1251239462Sdim TripleAliases.append( 1252263508Sdim MIPS64ELTriples, 1253263508Sdim MIPS64ELTriples + llvm::array_lengthof(MIPS64ELTriples)); 1254263508Sdim BiarchLibDirs.append(MIPSELLibDirs, 1255263508Sdim MIPSELLibDirs + llvm::array_lengthof(MIPSELLibDirs)); 1256263508Sdim BiarchTripleAliases.append( 1257263508Sdim MIPSELTriples, MIPSELTriples + llvm::array_lengthof(MIPSELTriples)); 1258263508Sdim BiarchTripleAliases.append( 1259263508Sdim MIPSTriples, MIPSTriples + llvm::array_lengthof(MIPSTriples)); 1260239462Sdim break; 1261234353Sdim case llvm::Triple::ppc: 1262234353Sdim LibDirs.append(PPCLibDirs, PPCLibDirs + llvm::array_lengthof(PPCLibDirs)); 1263263508Sdim TripleAliases.append(PPCTriples, 1264263508Sdim PPCTriples + llvm::array_lengthof(PPCTriples)); 1265263508Sdim BiarchLibDirs.append(PPC64LibDirs, 1266263508Sdim PPC64LibDirs + llvm::array_lengthof(PPC64LibDirs)); 1267263508Sdim BiarchTripleAliases.append( 1268263508Sdim PPC64Triples, PPC64Triples + llvm::array_lengthof(PPC64Triples)); 1269234353Sdim break; 1270234353Sdim case llvm::Triple::ppc64: 1271263508Sdim LibDirs.append(PPC64LibDirs, 1272263508Sdim PPC64LibDirs + llvm::array_lengthof(PPC64LibDirs)); 1273263508Sdim TripleAliases.append(PPC64Triples, 1274263508Sdim PPC64Triples + llvm::array_lengthof(PPC64Triples)); 1275263508Sdim BiarchLibDirs.append(PPCLibDirs, 1276263508Sdim PPCLibDirs + llvm::array_lengthof(PPCLibDirs)); 1277263508Sdim BiarchTripleAliases.append(PPCTriples, 1278263508Sdim PPCTriples + llvm::array_lengthof(PPCTriples)); 1279234353Sdim break; 1280263508Sdim case llvm::Triple::ppc64le: 1281263508Sdim LibDirs.append(PPC64LELibDirs, 1282263508Sdim PPC64LELibDirs + llvm::array_lengthof(PPC64LELibDirs)); 1283263508Sdim TripleAliases.append(PPC64LETriples, 1284263508Sdim PPC64LETriples + llvm::array_lengthof(PPC64LETriples)); 1285263508Sdim break; 1286251662Sdim case llvm::Triple::systemz: 1287263508Sdim LibDirs.append(SystemZLibDirs, 1288263508Sdim SystemZLibDirs + llvm::array_lengthof(SystemZLibDirs)); 1289263508Sdim TripleAliases.append(SystemZTriples, 1290263508Sdim SystemZTriples + llvm::array_lengthof(SystemZTriples)); 1291251662Sdim break; 1292234353Sdim 1293234353Sdim default: 1294234353Sdim // By default, just rely on the standard lib directories and the original 1295234353Sdim // triple. 1296234353Sdim break; 1297234353Sdim } 1298234353Sdim 1299234353Sdim // Always append the drivers target triple to the end, in case it doesn't 1300234353Sdim // match any of our aliases. 1301234353Sdim TripleAliases.push_back(TargetTriple.str()); 1302234353Sdim 1303234353Sdim // Also include the multiarch variant if it's different. 1304263508Sdim if (TargetTriple.str() != BiarchTriple.str()) 1305263508Sdim BiarchTripleAliases.push_back(BiarchTriple.str()); 1306234353Sdim} 1307234353Sdim 1308251662Sdimstatic bool isSoftFloatABI(const ArgList &Args) { 1309251662Sdim Arg *A = Args.getLastArg(options::OPT_msoft_float, 1310251662Sdim options::OPT_mhard_float, 1311251662Sdim options::OPT_mfloat_abi_EQ); 1312251662Sdim if (!A) return false; 1313251662Sdim 1314251662Sdim return A->getOption().matches(options::OPT_msoft_float) || 1315251662Sdim (A->getOption().matches(options::OPT_mfloat_abi_EQ) && 1316251662Sdim A->getValue() == StringRef("soft")); 1317251662Sdim} 1318251662Sdim 1319251662Sdimstatic bool isMipsArch(llvm::Triple::ArchType Arch) { 1320251662Sdim return Arch == llvm::Triple::mips || 1321251662Sdim Arch == llvm::Triple::mipsel || 1322251662Sdim Arch == llvm::Triple::mips64 || 1323251662Sdim Arch == llvm::Triple::mips64el; 1324251662Sdim} 1325251662Sdim 1326251662Sdimstatic bool isMips16(const ArgList &Args) { 1327251662Sdim Arg *A = Args.getLastArg(options::OPT_mips16, 1328251662Sdim options::OPT_mno_mips16); 1329251662Sdim return A && A->getOption().matches(options::OPT_mips16); 1330251662Sdim} 1331251662Sdim 1332263508Sdimstatic bool isMips32r2(const ArgList &Args) { 1333263508Sdim Arg *A = Args.getLastArg(options::OPT_march_EQ, 1334263508Sdim options::OPT_mcpu_EQ); 1335263508Sdim 1336263508Sdim return A && A->getValue() == StringRef("mips32r2"); 1337263508Sdim} 1338263508Sdim 1339263508Sdimstatic bool isMips64r2(const ArgList &Args) { 1340263508Sdim Arg *A = Args.getLastArg(options::OPT_march_EQ, 1341263508Sdim options::OPT_mcpu_EQ); 1342263508Sdim 1343263508Sdim return A && A->getValue() == StringRef("mips64r2"); 1344263508Sdim} 1345263508Sdim 1346251662Sdimstatic bool isMicroMips(const ArgList &Args) { 1347251662Sdim Arg *A = Args.getLastArg(options::OPT_mmicromips, 1348251662Sdim options::OPT_mno_micromips); 1349251662Sdim return A && A->getOption().matches(options::OPT_mmicromips); 1350251662Sdim} 1351251662Sdim 1352263508Sdimstatic bool isMipsFP64(const ArgList &Args) { 1353263508Sdim Arg *A = Args.getLastArg(options::OPT_mfp64, options::OPT_mfp32); 1354263508Sdim return A && A->getOption().matches(options::OPT_mfp64); 1355263508Sdim} 1356263508Sdim 1357263508Sdimstatic bool isMipsNan2008(const ArgList &Args) { 1358263508Sdim Arg *A = Args.getLastArg(options::OPT_mnan_EQ); 1359263508Sdim return A && A->getValue() == StringRef("2008"); 1360263508Sdim} 1361263508Sdim 1362243830Sdim// FIXME: There is the same routine in the Tools.cpp. 1363243830Sdimstatic bool hasMipsN32ABIArg(const ArgList &Args) { 1364243830Sdim Arg *A = Args.getLastArg(options::OPT_mabi_EQ); 1365243830Sdim return A && (A->getValue() == StringRef("n32")); 1366243830Sdim} 1367243830Sdim 1368263508Sdimstatic bool hasCrtBeginObj(Twine Path) { 1369263508Sdim return llvm::sys::fs::exists(Path + "/crtbegin.o"); 1370263508Sdim} 1371263508Sdim 1372263508Sdimstatic bool findTargetBiarchSuffix(std::string &Suffix, StringRef Path, 1373251662Sdim llvm::Triple::ArchType TargetArch, 1374251662Sdim const ArgList &Args) { 1375263508Sdim // FIXME: This routine was only intended to model bi-arch toolchains which 1376263508Sdim // use -m32 and -m64 to swap between variants of a target. It shouldn't be 1377263508Sdim // doing ABI-based builtin location for MIPS. 1378263508Sdim if (hasMipsN32ABIArg(Args)) 1379263508Sdim Suffix = "/n32"; 1380263508Sdim else if (TargetArch == llvm::Triple::x86_64 || 1381263508Sdim TargetArch == llvm::Triple::ppc64 || 1382263508Sdim TargetArch == llvm::Triple::systemz || 1383263508Sdim TargetArch == llvm::Triple::mips64 || 1384263508Sdim TargetArch == llvm::Triple::mips64el) 1385263508Sdim Suffix = "/64"; 1386263508Sdim else 1387263508Sdim Suffix = "/32"; 1388243830Sdim 1389263508Sdim return hasCrtBeginObj(Path + Suffix); 1390251662Sdim} 1391251662Sdim 1392263508Sdimvoid Generic_GCC::GCCInstallationDetector::findMIPSABIDirSuffix( 1393263508Sdim std::string &Suffix, llvm::Triple::ArchType TargetArch, StringRef Path, 1394263508Sdim const llvm::opt::ArgList &Args) { 1395263508Sdim if (!isMipsArch(TargetArch)) 1396263508Sdim return; 1397243830Sdim 1398263508Sdim // Some MIPS toolchains put libraries and object files compiled 1399263508Sdim // using different options in to the sub-directoris which names 1400263508Sdim // reflects the flags used for compilation. For example sysroot 1401263508Sdim // directory might looks like the following examples: 1402263508Sdim // 1403263508Sdim // /usr 1404263508Sdim // /lib <= crt*.o files compiled with '-mips32' 1405263508Sdim // /mips16 1406263508Sdim // /usr 1407263508Sdim // /lib <= crt*.o files compiled with '-mips16' 1408263508Sdim // /el 1409263508Sdim // /usr 1410263508Sdim // /lib <= crt*.o files compiled with '-mips16 -EL' 1411263508Sdim // 1412263508Sdim // or 1413263508Sdim // 1414263508Sdim // /usr 1415263508Sdim // /lib <= crt*.o files compiled with '-mips32r2' 1416263508Sdim // /mips16 1417263508Sdim // /usr 1418263508Sdim // /lib <= crt*.o files compiled with '-mips32r2 -mips16' 1419263508Sdim // /mips32 1420263508Sdim // /usr 1421263508Sdim // /lib <= crt*.o files compiled with '-mips32' 1422263508Sdim // 1423263508Sdim // Unfortunately different toolchains use different and partially 1424263508Sdim // overlapped naming schemes. So we have to make a trick for detection 1425263508Sdim // of using toolchain. We lookup a path which unique for each toolchains. 1426243830Sdim 1427263508Sdim bool IsMentorToolChain = hasCrtBeginObj(Path + "/mips16/soft-float"); 1428263508Sdim bool IsFSFToolChain = hasCrtBeginObj(Path + "/mips32/mips16/sof"); 1429251662Sdim 1430263508Sdim if (IsMentorToolChain && IsFSFToolChain) 1431263508Sdim D.Diag(diag::err_drv_unknown_toolchain); 1432251662Sdim 1433263508Sdim if (IsMentorToolChain) { 1434263508Sdim if (isMips16(Args)) 1435263508Sdim Suffix += "/mips16"; 1436263508Sdim else if (isMicroMips(Args)) 1437263508Sdim Suffix += "/micromips"; 1438263508Sdim 1439263508Sdim if (isSoftFloatABI(Args)) 1440263508Sdim Suffix += "/soft-float"; 1441263508Sdim 1442263508Sdim if (TargetArch == llvm::Triple::mipsel || 1443251662Sdim TargetArch == llvm::Triple::mips64el) 1444263508Sdim Suffix += "/el"; 1445263508Sdim } else if (IsFSFToolChain) { 1446263508Sdim if (TargetArch == llvm::Triple::mips || 1447263508Sdim TargetArch == llvm::Triple::mipsel) { 1448263508Sdim if (isMicroMips(Args)) 1449263508Sdim Suffix += "/micromips"; 1450263508Sdim else if (isMips32r2(Args)) 1451263508Sdim Suffix += ""; 1452263508Sdim else 1453263508Sdim Suffix += "/mips32"; 1454251662Sdim 1455263508Sdim if (isMips16(Args)) 1456263508Sdim Suffix += "/mips16"; 1457263508Sdim } else { 1458263508Sdim if (isMips64r2(Args)) 1459263508Sdim Suffix += hasMipsN32ABIArg(Args) ? "/mips64r2" : "/mips64r2/64"; 1460263508Sdim else 1461263508Sdim Suffix += hasMipsN32ABIArg(Args) ? "/mips64" : "/mips64/64"; 1462263508Sdim } 1463251662Sdim 1464263508Sdim if (TargetArch == llvm::Triple::mipsel || 1465263508Sdim TargetArch == llvm::Triple::mips64el) 1466263508Sdim Suffix += "/el"; 1467263508Sdim 1468263508Sdim if (isSoftFloatABI(Args)) 1469263508Sdim Suffix += "/sof"; 1470263508Sdim else { 1471263508Sdim if (isMipsFP64(Args)) 1472263508Sdim Suffix += "/fp64"; 1473263508Sdim 1474263508Sdim if (isMipsNan2008(Args)) 1475263508Sdim Suffix += "/nan2008"; 1476263508Sdim } 1477251662Sdim } 1478251662Sdim 1479263508Sdim if (!hasCrtBeginObj(Path + Suffix)) 1480263508Sdim Suffix.clear(); 1481251662Sdim} 1482251662Sdim 1483234353Sdimvoid Generic_GCC::GCCInstallationDetector::ScanLibDirForGCCTriple( 1484243830Sdim llvm::Triple::ArchType TargetArch, const ArgList &Args, 1485263508Sdim const std::string &LibDir, StringRef CandidateTriple, 1486263508Sdim bool NeedsBiarchSuffix) { 1487234353Sdim // There are various different suffixes involving the triple we 1488234353Sdim // check for. We also record what is necessary to walk from each back 1489234353Sdim // up to the lib directory. 1490234353Sdim const std::string LibSuffixes[] = { 1491234353Sdim "/gcc/" + CandidateTriple.str(), 1492263508Sdim // Debian puts cross-compilers in gcc-cross 1493263508Sdim "/gcc-cross/" + CandidateTriple.str(), 1494234353Sdim "/" + CandidateTriple.str() + "/gcc/" + CandidateTriple.str(), 1495234353Sdim 1496243830Sdim // The Freescale PPC SDK has the gcc libraries in 1497243830Sdim // <sysroot>/usr/lib/<triple>/x.y.z so have a look there as well. 1498243830Sdim "/" + CandidateTriple.str(), 1499243830Sdim 1500234353Sdim // Ubuntu has a strange mis-matched pair of triples that this happens to 1501234353Sdim // match. 1502234353Sdim // FIXME: It may be worthwhile to generalize this and look for a second 1503234353Sdim // triple. 1504234353Sdim "/i386-linux-gnu/gcc/" + CandidateTriple.str() 1505234353Sdim }; 1506234353Sdim const std::string InstallSuffixes[] = { 1507263508Sdim "/../../..", // gcc/ 1508263508Sdim "/../../..", // gcc-cross/ 1509263508Sdim "/../../../..", // <triple>/gcc/ 1510263508Sdim "/../..", // <triple>/ 1511263508Sdim "/../../../.." // i386-linux-gnu/gcc/<triple>/ 1512234353Sdim }; 1513234353Sdim // Only look at the final, weird Ubuntu suffix for i386-linux-gnu. 1514263508Sdim const unsigned NumLibSuffixes = 1515263508Sdim (llvm::array_lengthof(LibSuffixes) - (TargetArch != llvm::Triple::x86)); 1516234353Sdim for (unsigned i = 0; i < NumLibSuffixes; ++i) { 1517234353Sdim StringRef LibSuffix = LibSuffixes[i]; 1518234353Sdim llvm::error_code EC; 1519234353Sdim for (llvm::sys::fs::directory_iterator LI(LibDir + LibSuffix, EC), LE; 1520234353Sdim !EC && LI != LE; LI = LI.increment(EC)) { 1521234353Sdim StringRef VersionText = llvm::sys::path::filename(LI->path()); 1522234353Sdim GCCVersion CandidateVersion = GCCVersion::Parse(VersionText); 1523263508Sdim if (CandidateVersion.Major != -1) // Filter obviously bad entries. 1524263508Sdim if (!CandidateGCCInstallPaths.insert(LI->path()).second) 1525263508Sdim continue; // Saw this path before; no need to look at it again. 1526263508Sdim if (CandidateVersion.isOlderThan(4, 1, 1)) 1527234353Sdim continue; 1528234353Sdim if (CandidateVersion <= Version) 1529234353Sdim continue; 1530234353Sdim 1531263508Sdim std::string MIPSABIDirSuffix; 1532263508Sdim findMIPSABIDirSuffix(MIPSABIDirSuffix, TargetArch, LI->path(), Args); 1533263508Sdim 1534234353Sdim // Some versions of SUSE and Fedora on ppc64 put 32-bit libs 1535234353Sdim // in what would normally be GCCInstallPath and put the 64-bit 1536234353Sdim // libs in a subdirectory named 64. The simple logic we follow is that 1537234353Sdim // *if* there is a subdirectory of the right name with crtbegin.o in it, 1538263508Sdim // we use that. If not, and if not a biarch triple alias, we look for 1539234353Sdim // crtbegin.o without the subdirectory. 1540251662Sdim 1541263508Sdim std::string BiarchSuffix; 1542263508Sdim if (findTargetBiarchSuffix(BiarchSuffix, 1543263508Sdim LI->path() + MIPSABIDirSuffix, 1544263508Sdim TargetArch, Args)) { 1545263508Sdim GCCBiarchSuffix = BiarchSuffix; 1546263508Sdim } else if (NeedsBiarchSuffix || 1547263508Sdim !hasCrtBeginObj(LI->path() + MIPSABIDirSuffix)) { 1548263508Sdim continue; 1549234353Sdim } else { 1550263508Sdim GCCBiarchSuffix.clear(); 1551234353Sdim } 1552234353Sdim 1553234353Sdim Version = CandidateVersion; 1554234353Sdim GCCTriple.setTriple(CandidateTriple); 1555234353Sdim // FIXME: We hack together the directory name here instead of 1556234353Sdim // using LI to ensure stable path separators across Windows and 1557234353Sdim // Linux. 1558234353Sdim GCCInstallPath = LibDir + LibSuffixes[i] + "/" + VersionText.str(); 1559234353Sdim GCCParentLibPath = GCCInstallPath + InstallSuffixes[i]; 1560263508Sdim GCCMIPSABIDirSuffix = MIPSABIDirSuffix; 1561234353Sdim IsValid = true; 1562234353Sdim } 1563234353Sdim } 1564234353Sdim} 1565234353Sdim 1566234353SdimGeneric_GCC::Generic_GCC(const Driver &D, const llvm::Triple& Triple, 1567234353Sdim const ArgList &Args) 1568263508Sdim : ToolChain(D, Triple, Args), GCCInstallation(getDriver()) { 1569212904Sdim getProgramPaths().push_back(getDriver().getInstalledDir()); 1570221345Sdim if (getDriver().getInstalledDir() != getDriver().Dir) 1571212904Sdim getProgramPaths().push_back(getDriver().Dir); 1572193326Sed} 1573193326Sed 1574193326SedGeneric_GCC::~Generic_GCC() { 1575193326Sed} 1576193326Sed 1577249423SdimTool *Generic_GCC::getTool(Action::ActionClass AC) const { 1578249423Sdim switch (AC) { 1579249423Sdim case Action::PreprocessJobClass: 1580249423Sdim if (!Preprocess) 1581249423Sdim Preprocess.reset(new tools::gcc::Preprocess(*this)); 1582249423Sdim return Preprocess.get(); 1583249423Sdim case Action::PrecompileJobClass: 1584249423Sdim if (!Precompile) 1585249423Sdim Precompile.reset(new tools::gcc::Precompile(*this)); 1586249423Sdim return Precompile.get(); 1587249423Sdim case Action::CompileJobClass: 1588249423Sdim if (!Compile) 1589249423Sdim Compile.reset(new tools::gcc::Compile(*this)); 1590249423Sdim return Compile.get(); 1591249423Sdim default: 1592249423Sdim return ToolChain::getTool(AC); 1593193326Sed } 1594249423Sdim} 1595193326Sed 1596249423SdimTool *Generic_GCC::buildAssembler() const { 1597249423Sdim return new tools::gcc::Assemble(*this); 1598193326Sed} 1599193326Sed 1600249423SdimTool *Generic_GCC::buildLinker() const { 1601249423Sdim return new tools::gcc::Link(*this); 1602249423Sdim} 1603249423Sdim 1604263508Sdimvoid Generic_GCC::printVerboseInfo(raw_ostream &OS) const { 1605263508Sdim // Print the information about how we detected the GCC installation. 1606263508Sdim GCCInstallation.print(OS); 1607263508Sdim} 1608263508Sdim 1609193326Sedbool Generic_GCC::IsUnwindTablesDefault() const { 1610243830Sdim return getArch() == llvm::Triple::x86_64; 1611193326Sed} 1612193326Sed 1613243830Sdimbool Generic_GCC::isPICDefault() const { 1614243830Sdim return false; 1615193326Sed} 1616193326Sed 1617251662Sdimbool Generic_GCC::isPIEDefault() const { 1618251662Sdim return false; 1619251662Sdim} 1620251662Sdim 1621243830Sdimbool Generic_GCC::isPICDefaultForced() const { 1622243830Sdim return false; 1623193326Sed} 1624243830Sdim 1625234353Sdim/// Hexagon Toolchain 1626193326Sed 1627249423Sdimstd::string Hexagon_TC::GetGnuDir(const std::string &InstalledDir) { 1628249423Sdim 1629249423Sdim // Locate the rest of the toolchain ... 1630249423Sdim if (strlen(GCC_INSTALL_PREFIX)) 1631249423Sdim return std::string(GCC_INSTALL_PREFIX); 1632249423Sdim 1633249423Sdim std::string InstallRelDir = InstalledDir + "/../../gnu"; 1634249423Sdim if (llvm::sys::fs::exists(InstallRelDir)) 1635249423Sdim return InstallRelDir; 1636249423Sdim 1637249423Sdim std::string PrefixRelDir = std::string(LLVM_PREFIX) + "/../gnu"; 1638249423Sdim if (llvm::sys::fs::exists(PrefixRelDir)) 1639249423Sdim return PrefixRelDir; 1640249423Sdim 1641249423Sdim return InstallRelDir; 1642234353Sdim} 1643234353Sdim 1644249423Sdimstatic void GetHexagonLibraryPaths( 1645249423Sdim const ArgList &Args, 1646249423Sdim const std::string Ver, 1647249423Sdim const std::string MarchString, 1648249423Sdim const std::string &InstalledDir, 1649249423Sdim ToolChain::path_list *LibPaths) 1650249423Sdim{ 1651249423Sdim bool buildingLib = Args.hasArg(options::OPT_shared); 1652249423Sdim 1653249423Sdim //---------------------------------------------------------------------------- 1654249423Sdim // -L Args 1655249423Sdim //---------------------------------------------------------------------------- 1656249423Sdim for (arg_iterator 1657249423Sdim it = Args.filtered_begin(options::OPT_L), 1658249423Sdim ie = Args.filtered_end(); 1659249423Sdim it != ie; 1660249423Sdim ++it) { 1661249423Sdim for (unsigned i = 0, e = (*it)->getNumValues(); i != e; ++i) 1662249423Sdim LibPaths->push_back((*it)->getValue(i)); 1663249423Sdim } 1664249423Sdim 1665249423Sdim //---------------------------------------------------------------------------- 1666249423Sdim // Other standard paths 1667249423Sdim //---------------------------------------------------------------------------- 1668249423Sdim const std::string MarchSuffix = "/" + MarchString; 1669249423Sdim const std::string G0Suffix = "/G0"; 1670249423Sdim const std::string MarchG0Suffix = MarchSuffix + G0Suffix; 1671249423Sdim const std::string RootDir = Hexagon_TC::GetGnuDir(InstalledDir) + "/"; 1672249423Sdim 1673249423Sdim // lib/gcc/hexagon/... 1674249423Sdim std::string LibGCCHexagonDir = RootDir + "lib/gcc/hexagon/"; 1675249423Sdim if (buildingLib) { 1676249423Sdim LibPaths->push_back(LibGCCHexagonDir + Ver + MarchG0Suffix); 1677249423Sdim LibPaths->push_back(LibGCCHexagonDir + Ver + G0Suffix); 1678249423Sdim } 1679249423Sdim LibPaths->push_back(LibGCCHexagonDir + Ver + MarchSuffix); 1680249423Sdim LibPaths->push_back(LibGCCHexagonDir + Ver); 1681249423Sdim 1682249423Sdim // lib/gcc/... 1683249423Sdim LibPaths->push_back(RootDir + "lib/gcc"); 1684249423Sdim 1685249423Sdim // hexagon/lib/... 1686249423Sdim std::string HexagonLibDir = RootDir + "hexagon/lib"; 1687249423Sdim if (buildingLib) { 1688249423Sdim LibPaths->push_back(HexagonLibDir + MarchG0Suffix); 1689249423Sdim LibPaths->push_back(HexagonLibDir + G0Suffix); 1690249423Sdim } 1691249423Sdim LibPaths->push_back(HexagonLibDir + MarchSuffix); 1692249423Sdim LibPaths->push_back(HexagonLibDir); 1693249423Sdim} 1694249423Sdim 1695249423SdimHexagon_TC::Hexagon_TC(const Driver &D, const llvm::Triple &Triple, 1696249423Sdim const ArgList &Args) 1697249423Sdim : Linux(D, Triple, Args) { 1698249423Sdim const std::string InstalledDir(getDriver().getInstalledDir()); 1699249423Sdim const std::string GnuDir = Hexagon_TC::GetGnuDir(InstalledDir); 1700249423Sdim 1701249423Sdim // Note: Generic_GCC::Generic_GCC adds InstalledDir and getDriver().Dir to 1702249423Sdim // program paths 1703249423Sdim const std::string BinDir(GnuDir + "/bin"); 1704249423Sdim if (llvm::sys::fs::exists(BinDir)) 1705249423Sdim getProgramPaths().push_back(BinDir); 1706249423Sdim 1707249423Sdim // Determine version of GCC libraries and headers to use. 1708249423Sdim const std::string HexagonDir(GnuDir + "/lib/gcc/hexagon"); 1709249423Sdim llvm::error_code ec; 1710249423Sdim GCCVersion MaxVersion= GCCVersion::Parse("0.0.0"); 1711249423Sdim for (llvm::sys::fs::directory_iterator di(HexagonDir, ec), de; 1712249423Sdim !ec && di != de; di = di.increment(ec)) { 1713249423Sdim GCCVersion cv = GCCVersion::Parse(llvm::sys::path::filename(di->path())); 1714249423Sdim if (MaxVersion < cv) 1715249423Sdim MaxVersion = cv; 1716249423Sdim } 1717249423Sdim GCCLibAndIncVersion = MaxVersion; 1718249423Sdim 1719249423Sdim ToolChain::path_list *LibPaths= &getFilePaths(); 1720249423Sdim 1721249423Sdim // Remove paths added by Linux toolchain. Currently Hexagon_TC really targets 1722249423Sdim // 'elf' OS type, so the Linux paths are not appropriate. When we actually 1723249423Sdim // support 'linux' we'll need to fix this up 1724249423Sdim LibPaths->clear(); 1725249423Sdim 1726249423Sdim GetHexagonLibraryPaths( 1727249423Sdim Args, 1728249423Sdim GetGCCLibAndIncVersion(), 1729249423Sdim GetTargetCPU(Args), 1730249423Sdim InstalledDir, 1731249423Sdim LibPaths); 1732249423Sdim} 1733249423Sdim 1734234353SdimHexagon_TC::~Hexagon_TC() { 1735234353Sdim} 1736234353Sdim 1737249423SdimTool *Hexagon_TC::buildAssembler() const { 1738249423Sdim return new tools::hexagon::Assemble(*this); 1739249423Sdim} 1740234353Sdim 1741249423SdimTool *Hexagon_TC::buildLinker() const { 1742249423Sdim return new tools::hexagon::Link(*this); 1743249423Sdim} 1744234353Sdim 1745249423Sdimvoid Hexagon_TC::AddClangSystemIncludeArgs(const ArgList &DriverArgs, 1746249423Sdim ArgStringList &CC1Args) const { 1747249423Sdim const Driver &D = getDriver(); 1748249423Sdim 1749249423Sdim if (DriverArgs.hasArg(options::OPT_nostdinc) || 1750249423Sdim DriverArgs.hasArg(options::OPT_nostdlibinc)) 1751249423Sdim return; 1752249423Sdim 1753249423Sdim std::string Ver(GetGCCLibAndIncVersion()); 1754249423Sdim std::string GnuDir = Hexagon_TC::GetGnuDir(D.InstalledDir); 1755249423Sdim std::string HexagonDir(GnuDir + "/lib/gcc/hexagon/" + Ver); 1756249423Sdim addExternCSystemInclude(DriverArgs, CC1Args, HexagonDir + "/include"); 1757249423Sdim addExternCSystemInclude(DriverArgs, CC1Args, HexagonDir + "/include-fixed"); 1758249423Sdim addExternCSystemInclude(DriverArgs, CC1Args, GnuDir + "/hexagon/include"); 1759249423Sdim} 1760249423Sdim 1761249423Sdimvoid Hexagon_TC::AddClangCXXStdlibIncludeArgs(const ArgList &DriverArgs, 1762249423Sdim ArgStringList &CC1Args) const { 1763249423Sdim 1764249423Sdim if (DriverArgs.hasArg(options::OPT_nostdlibinc) || 1765249423Sdim DriverArgs.hasArg(options::OPT_nostdincxx)) 1766249423Sdim return; 1767249423Sdim 1768249423Sdim const Driver &D = getDriver(); 1769249423Sdim std::string Ver(GetGCCLibAndIncVersion()); 1770263508Sdim SmallString<128> IncludeDir(Hexagon_TC::GetGnuDir(D.InstalledDir)); 1771249423Sdim 1772263508Sdim llvm::sys::path::append(IncludeDir, "hexagon/include/c++/"); 1773263508Sdim llvm::sys::path::append(IncludeDir, Ver); 1774249423Sdim addSystemInclude(DriverArgs, CC1Args, IncludeDir.str()); 1775249423Sdim} 1776249423Sdim 1777249423SdimToolChain::CXXStdlibType 1778249423SdimHexagon_TC::GetCXXStdlibType(const ArgList &Args) const { 1779249423Sdim Arg *A = Args.getLastArg(options::OPT_stdlib_EQ); 1780249423Sdim if (!A) 1781249423Sdim return ToolChain::CST_Libstdcxx; 1782249423Sdim 1783249423Sdim StringRef Value = A->getValue(); 1784249423Sdim if (Value != "libstdc++") { 1785249423Sdim getDriver().Diag(diag::err_drv_invalid_stdlib_name) 1786249423Sdim << A->getAsString(Args); 1787234353Sdim } 1788234353Sdim 1789249423Sdim return ToolChain::CST_Libstdcxx; 1790234353Sdim} 1791234353Sdim 1792263508Sdimstatic int getHexagonVersion(const ArgList &Args) { 1793263508Sdim Arg *A = Args.getLastArg(options::OPT_march_EQ, options::OPT_mcpu_EQ); 1794263508Sdim // Select the default CPU (v4) if none was given. 1795263508Sdim if (!A) 1796263508Sdim return 4; 1797249423Sdim 1798263508Sdim // FIXME: produce errors if we cannot parse the version. 1799263508Sdim StringRef WhichHexagon = A->getValue(); 1800263508Sdim if (WhichHexagon.startswith("hexagonv")) { 1801263508Sdim int Val; 1802263508Sdim if (!WhichHexagon.substr(sizeof("hexagonv") - 1).getAsInteger(10, Val)) 1803263508Sdim return Val; 1804249423Sdim } 1805263508Sdim if (WhichHexagon.startswith("v")) { 1806263508Sdim int Val; 1807263508Sdim if (!WhichHexagon.substr(1).getAsInteger(10, Val)) 1808263508Sdim return Val; 1809263508Sdim } 1810263508Sdim 1811263508Sdim // FIXME: should probably be an error. 1812263508Sdim return 4; 1813234353Sdim} 1814234353Sdim 1815249423SdimStringRef Hexagon_TC::GetTargetCPU(const ArgList &Args) 1816249423Sdim{ 1817263508Sdim int V = getHexagonVersion(Args); 1818263508Sdim // FIXME: We don't support versions < 4. We should error on them. 1819263508Sdim switch (V) { 1820263508Sdim default: 1821263508Sdim llvm_unreachable("Unexpected version"); 1822263508Sdim case 5: 1823263508Sdim return "v5"; 1824263508Sdim case 4: 1825263508Sdim return "v4"; 1826263508Sdim case 3: 1827263508Sdim return "v3"; 1828263508Sdim case 2: 1829263508Sdim return "v2"; 1830263508Sdim case 1: 1831263508Sdim return "v1"; 1832249423Sdim } 1833234353Sdim} 1834249423Sdim// End Hexagon 1835234353Sdim 1836204793Srdivacky/// TCEToolChain - A tool chain using the llvm bitcode tools to perform 1837204793Srdivacky/// all subcommands. See http://tce.cs.tut.fi for our peculiar target. 1838204793Srdivacky/// Currently does not support anything else but compilation. 1839204793Srdivacky 1840249423SdimTCEToolChain::TCEToolChain(const Driver &D, const llvm::Triple& Triple, 1841249423Sdim const ArgList &Args) 1842249423Sdim : ToolChain(D, Triple, Args) { 1843204793Srdivacky // Path mangling to find libexec 1844204793Srdivacky std::string Path(getDriver().Dir); 1845204793Srdivacky 1846204793Srdivacky Path += "/../libexec"; 1847204793Srdivacky getProgramPaths().push_back(Path); 1848204793Srdivacky} 1849204793Srdivacky 1850204793SrdivackyTCEToolChain::~TCEToolChain() { 1851204793Srdivacky} 1852204793Srdivacky 1853223017Sdimbool TCEToolChain::IsMathErrnoDefault() const { 1854223017Sdim return true; 1855204793Srdivacky} 1856204793Srdivacky 1857243830Sdimbool TCEToolChain::isPICDefault() const { 1858204793Srdivacky return false; 1859204793Srdivacky} 1860204793Srdivacky 1861251662Sdimbool TCEToolChain::isPIEDefault() const { 1862251662Sdim return false; 1863251662Sdim} 1864251662Sdim 1865243830Sdimbool TCEToolChain::isPICDefaultForced() const { 1866243830Sdim return false; 1867204793Srdivacky} 1868204793Srdivacky 1869195341Sed/// OpenBSD - OpenBSD tool chain which can call as(1) and ld(1) directly. 1870195341Sed 1871234353SdimOpenBSD::OpenBSD(const Driver &D, const llvm::Triple& Triple, const ArgList &Args) 1872234353Sdim : Generic_ELF(D, Triple, Args) { 1873201361Srdivacky getFilePaths().push_back(getDriver().Dir + "/../lib"); 1874195341Sed getFilePaths().push_back("/usr/lib"); 1875195341Sed} 1876195341Sed 1877249423SdimTool *OpenBSD::buildAssembler() const { 1878249423Sdim return new tools::openbsd::Assemble(*this); 1879249423Sdim} 1880195341Sed 1881249423SdimTool *OpenBSD::buildLinker() const { 1882249423Sdim return new tools::openbsd::Link(*this); 1883195341Sed} 1884195341Sed 1885239462Sdim/// Bitrig - Bitrig tool chain which can call as(1) and ld(1) directly. 1886239462Sdim 1887239462SdimBitrig::Bitrig(const Driver &D, const llvm::Triple& Triple, const ArgList &Args) 1888239462Sdim : Generic_ELF(D, Triple, Args) { 1889239462Sdim getFilePaths().push_back(getDriver().Dir + "/../lib"); 1890239462Sdim getFilePaths().push_back("/usr/lib"); 1891239462Sdim} 1892239462Sdim 1893249423SdimTool *Bitrig::buildAssembler() const { 1894249423Sdim return new tools::bitrig::Assemble(*this); 1895249423Sdim} 1896239462Sdim 1897249423SdimTool *Bitrig::buildLinker() const { 1898249423Sdim return new tools::bitrig::Link(*this); 1899239462Sdim} 1900239462Sdim 1901239462Sdimvoid Bitrig::AddClangCXXStdlibIncludeArgs(const ArgList &DriverArgs, 1902239462Sdim ArgStringList &CC1Args) const { 1903239462Sdim if (DriverArgs.hasArg(options::OPT_nostdlibinc) || 1904239462Sdim DriverArgs.hasArg(options::OPT_nostdincxx)) 1905239462Sdim return; 1906239462Sdim 1907243830Sdim switch (GetCXXStdlibType(DriverArgs)) { 1908243830Sdim case ToolChain::CST_Libcxx: 1909243830Sdim addSystemInclude(DriverArgs, CC1Args, 1910243830Sdim getDriver().SysRoot + "/usr/include/c++/"); 1911243830Sdim break; 1912243830Sdim case ToolChain::CST_Libstdcxx: 1913243830Sdim addSystemInclude(DriverArgs, CC1Args, 1914243830Sdim getDriver().SysRoot + "/usr/include/c++/stdc++"); 1915243830Sdim addSystemInclude(DriverArgs, CC1Args, 1916243830Sdim getDriver().SysRoot + "/usr/include/c++/stdc++/backward"); 1917239462Sdim 1918243830Sdim StringRef Triple = getTriple().str(); 1919243830Sdim if (Triple.startswith("amd64")) 1920243830Sdim addSystemInclude(DriverArgs, CC1Args, 1921243830Sdim getDriver().SysRoot + "/usr/include/c++/stdc++/x86_64" + 1922243830Sdim Triple.substr(5)); 1923243830Sdim else 1924243830Sdim addSystemInclude(DriverArgs, CC1Args, 1925243830Sdim getDriver().SysRoot + "/usr/include/c++/stdc++/" + 1926243830Sdim Triple); 1927243830Sdim break; 1928243830Sdim } 1929239462Sdim} 1930239462Sdim 1931239462Sdimvoid Bitrig::AddCXXStdlibLibArgs(const ArgList &Args, 1932239462Sdim ArgStringList &CmdArgs) const { 1933243830Sdim switch (GetCXXStdlibType(Args)) { 1934243830Sdim case ToolChain::CST_Libcxx: 1935243830Sdim CmdArgs.push_back("-lc++"); 1936243830Sdim CmdArgs.push_back("-lcxxrt"); 1937243830Sdim // Include supc++ to provide Unwind until provided by libcxx. 1938243830Sdim CmdArgs.push_back("-lgcc"); 1939243830Sdim break; 1940243830Sdim case ToolChain::CST_Libstdcxx: 1941243830Sdim CmdArgs.push_back("-lstdc++"); 1942243830Sdim break; 1943243830Sdim } 1944239462Sdim} 1945239462Sdim 1946193326Sed/// FreeBSD - FreeBSD tool chain which can call as(1) and ld(1) directly. 1947193326Sed 1948234353SdimFreeBSD::FreeBSD(const Driver &D, const llvm::Triple& Triple, const ArgList &Args) 1949234353Sdim : Generic_ELF(D, Triple, Args) { 1950212904Sdim 1951234353Sdim // When targeting 32-bit platforms, look for '/usr/lib32/crt1.o' and fall 1952234353Sdim // back to '/usr/lib' if it doesn't exist. 1953234353Sdim if ((Triple.getArch() == llvm::Triple::x86 || 1954234353Sdim Triple.getArch() == llvm::Triple::ppc) && 1955234982Sdim llvm::sys::fs::exists(getDriver().SysRoot + "/usr/lib32/crt1.o")) 1956234982Sdim getFilePaths().push_back(getDriver().SysRoot + "/usr/lib32"); 1957234353Sdim else 1958234982Sdim getFilePaths().push_back(getDriver().SysRoot + "/usr/lib"); 1959193326Sed} 1960193326Sed 1961255321StheravenToolChain::CXXStdlibType 1962255321StheravenFreeBSD::GetCXXStdlibType(const ArgList &Args) const { 1963255321Stheraven if (Arg *A = Args.getLastArg(options::OPT_stdlib_EQ)) { 1964255321Stheraven StringRef Value = A->getValue(); 1965263508Sdim if (Value == "libstdc++") 1966263508Sdim return ToolChain::CST_Libstdcxx; 1967255321Stheraven if (Value == "libc++") 1968255321Stheraven return ToolChain::CST_Libcxx; 1969263508Sdim 1970255321Stheraven getDriver().Diag(diag::err_drv_invalid_stdlib_name) 1971255321Stheraven << A->getAsString(Args); 1972255321Stheraven } 1973263508Sdim if (getTriple().getOSMajorVersion() >= 10) 1974263508Sdim return ToolChain::CST_Libcxx; 1975263508Sdim return ToolChain::CST_Libstdcxx; 1976255321Stheraven} 1977255321Stheraven 1978255321Stheravenvoid FreeBSD::AddClangCXXStdlibIncludeArgs(const ArgList &DriverArgs, 1979263508Sdim ArgStringList &CC1Args) const { 1980255321Stheraven if (DriverArgs.hasArg(options::OPT_nostdlibinc) || 1981255321Stheraven DriverArgs.hasArg(options::OPT_nostdincxx)) 1982255321Stheraven return; 1983255321Stheraven 1984263508Sdim switch (GetCXXStdlibType(DriverArgs)) { 1985263508Sdim case ToolChain::CST_Libcxx: 1986255321Stheraven addSystemInclude(DriverArgs, CC1Args, 1987255321Stheraven getDriver().SysRoot + "/usr/include/c++/v1"); 1988263508Sdim break; 1989263508Sdim case ToolChain::CST_Libstdcxx: 1990255321Stheraven addSystemInclude(DriverArgs, CC1Args, 1991255321Stheraven getDriver().SysRoot + "/usr/include/c++/4.2"); 1992263508Sdim addSystemInclude(DriverArgs, CC1Args, 1993263508Sdim getDriver().SysRoot + "/usr/include/c++/4.2/backward"); 1994263508Sdim break; 1995263508Sdim } 1996263508Sdim} 1997255321Stheraven 1998263508SdimTool *FreeBSD::buildAssembler() const { 1999263508Sdim return new tools::freebsd::Assemble(*this); 2000255321Stheraven} 2001255321Stheraven 2002263508SdimTool *FreeBSD::buildLinker() const { 2003263508Sdim return new tools::freebsd::Link(*this); 2004263508Sdim} 2005263508Sdim 2006263508Sdimbool FreeBSD::UseSjLjExceptions() const { 2007263508Sdim // FreeBSD uses SjLj exceptions on ARM oabi. 2008263508Sdim switch (getTriple().getEnvironment()) { 2009263508Sdim case llvm::Triple::GNUEABI: 2010263508Sdim case llvm::Triple::EABI: 2011263508Sdim return false; 2012263508Sdim 2013263508Sdim default: 2014263508Sdim return (getTriple().getArch() == llvm::Triple::arm || 2015263508Sdim getTriple().getArch() == llvm::Triple::thumb); 2016263508Sdim } 2017263508Sdim} 2018263508Sdim 2019218893Sdim/// NetBSD - NetBSD tool chain which can call as(1) and ld(1) directly. 2020218893Sdim 2021234353SdimNetBSD::NetBSD(const Driver &D, const llvm::Triple& Triple, const ArgList &Args) 2022234353Sdim : Generic_ELF(D, Triple, Args) { 2023218893Sdim 2024221345Sdim if (getDriver().UseStdLib) { 2025234353Sdim // When targeting a 32-bit platform, try the special directory used on 2026234353Sdim // 64-bit hosts, and only fall back to the main library directory if that 2027234353Sdim // doesn't work. 2028234353Sdim // FIXME: It'd be nicer to test if this directory exists, but I'm not sure 2029234353Sdim // what all logic is needed to emulate the '=' prefix here. 2030234353Sdim if (Triple.getArch() == llvm::Triple::x86) 2031221345Sdim getFilePaths().push_back("=/usr/lib/i386"); 2032234353Sdim 2033234353Sdim getFilePaths().push_back("=/usr/lib"); 2034218893Sdim } 2035218893Sdim} 2036218893Sdim 2037249423SdimTool *NetBSD::buildAssembler() const { 2038249423Sdim return new tools::netbsd::Assemble(*this); 2039249423Sdim} 2040218893Sdim 2041249423SdimTool *NetBSD::buildLinker() const { 2042249423Sdim return new tools::netbsd::Link(*this); 2043218893Sdim} 2044218893Sdim 2045251662SdimToolChain::CXXStdlibType 2046251662SdimNetBSD::GetCXXStdlibType(const ArgList &Args) const { 2047251662Sdim if (Arg *A = Args.getLastArg(options::OPT_stdlib_EQ)) { 2048251662Sdim StringRef Value = A->getValue(); 2049251662Sdim if (Value == "libstdc++") 2050251662Sdim return ToolChain::CST_Libstdcxx; 2051251662Sdim if (Value == "libc++") 2052251662Sdim return ToolChain::CST_Libcxx; 2053251662Sdim 2054251662Sdim getDriver().Diag(diag::err_drv_invalid_stdlib_name) 2055251662Sdim << A->getAsString(Args); 2056251662Sdim } 2057251662Sdim 2058263508Sdim unsigned Major, Minor, Micro; 2059263508Sdim getTriple().getOSVersion(Major, Minor, Micro); 2060263508Sdim if (Major >= 7 || (Major == 6 && Minor == 99 && Micro >= 23) || Major == 0) { 2061263508Sdim if (getArch() == llvm::Triple::x86 || getArch() == llvm::Triple::x86_64) 2062263508Sdim return ToolChain::CST_Libcxx; 2063263508Sdim } 2064251662Sdim return ToolChain::CST_Libstdcxx; 2065251662Sdim} 2066251662Sdim 2067251662Sdimvoid NetBSD::AddClangCXXStdlibIncludeArgs(const ArgList &DriverArgs, 2068251662Sdim ArgStringList &CC1Args) const { 2069251662Sdim if (DriverArgs.hasArg(options::OPT_nostdlibinc) || 2070251662Sdim DriverArgs.hasArg(options::OPT_nostdincxx)) 2071251662Sdim return; 2072251662Sdim 2073251662Sdim switch (GetCXXStdlibType(DriverArgs)) { 2074251662Sdim case ToolChain::CST_Libcxx: 2075251662Sdim addSystemInclude(DriverArgs, CC1Args, 2076251662Sdim getDriver().SysRoot + "/usr/include/c++/"); 2077251662Sdim break; 2078251662Sdim case ToolChain::CST_Libstdcxx: 2079251662Sdim addSystemInclude(DriverArgs, CC1Args, 2080251662Sdim getDriver().SysRoot + "/usr/include/g++"); 2081251662Sdim addSystemInclude(DriverArgs, CC1Args, 2082251662Sdim getDriver().SysRoot + "/usr/include/g++/backward"); 2083251662Sdim break; 2084251662Sdim } 2085251662Sdim} 2086251662Sdim 2087210299Sed/// Minix - Minix tool chain which can call as(1) and ld(1) directly. 2088210299Sed 2089234353SdimMinix::Minix(const Driver &D, const llvm::Triple& Triple, const ArgList &Args) 2090234353Sdim : Generic_ELF(D, Triple, Args) { 2091210299Sed getFilePaths().push_back(getDriver().Dir + "/../lib"); 2092210299Sed getFilePaths().push_back("/usr/lib"); 2093210299Sed} 2094210299Sed 2095249423SdimTool *Minix::buildAssembler() const { 2096249423Sdim return new tools::minix::Assemble(*this); 2097249423Sdim} 2098210299Sed 2099249423SdimTool *Minix::buildLinker() const { 2100249423Sdim return new tools::minix::Link(*this); 2101210299Sed} 2102210299Sed 2103198092Srdivacky/// AuroraUX - AuroraUX tool chain which can call as(1) and ld(1) directly. 2104198092Srdivacky 2105234353SdimAuroraUX::AuroraUX(const Driver &D, const llvm::Triple& Triple, 2106234353Sdim const ArgList &Args) 2107234353Sdim : Generic_GCC(D, Triple, Args) { 2108198092Srdivacky 2109212904Sdim getProgramPaths().push_back(getDriver().getInstalledDir()); 2110221345Sdim if (getDriver().getInstalledDir() != getDriver().Dir) 2111212904Sdim getProgramPaths().push_back(getDriver().Dir); 2112198092Srdivacky 2113201361Srdivacky getFilePaths().push_back(getDriver().Dir + "/../lib"); 2114198092Srdivacky getFilePaths().push_back("/usr/lib"); 2115198092Srdivacky getFilePaths().push_back("/usr/sfw/lib"); 2116198092Srdivacky getFilePaths().push_back("/opt/gcc4/lib"); 2117198398Srdivacky getFilePaths().push_back("/opt/gcc4/lib/gcc/i386-pc-solaris2.11/4.2.4"); 2118198092Srdivacky 2119198092Srdivacky} 2120198092Srdivacky 2121249423SdimTool *AuroraUX::buildAssembler() const { 2122249423Sdim return new tools::auroraux::Assemble(*this); 2123249423Sdim} 2124198092Srdivacky 2125249423SdimTool *AuroraUX::buildLinker() const { 2126249423Sdim return new tools::auroraux::Link(*this); 2127198092Srdivacky} 2128198092Srdivacky 2129234353Sdim/// Solaris - Solaris tool chain which can call as(1) and ld(1) directly. 2130198092Srdivacky 2131234353SdimSolaris::Solaris(const Driver &D, const llvm::Triple& Triple, 2132234353Sdim const ArgList &Args) 2133234353Sdim : Generic_GCC(D, Triple, Args) { 2134234353Sdim 2135234353Sdim getProgramPaths().push_back(getDriver().getInstalledDir()); 2136234353Sdim if (getDriver().getInstalledDir() != getDriver().Dir) 2137234353Sdim getProgramPaths().push_back(getDriver().Dir); 2138234353Sdim 2139234353Sdim getFilePaths().push_back(getDriver().Dir + "/../lib"); 2140234353Sdim getFilePaths().push_back("/usr/lib"); 2141234353Sdim} 2142234353Sdim 2143249423SdimTool *Solaris::buildAssembler() const { 2144249423Sdim return new tools::solaris::Assemble(*this); 2145249423Sdim} 2146234353Sdim 2147249423SdimTool *Solaris::buildLinker() const { 2148249423Sdim return new tools::solaris::Link(*this); 2149234353Sdim} 2150234353Sdim 2151249423Sdim/// Distribution (very bare-bones at the moment). 2152193326Sed 2153249423Sdimenum Distro { 2154219077Sdim ArchLinux, 2155218893Sdim DebianLenny, 2156218893Sdim DebianSqueeze, 2157223017Sdim DebianWheezy, 2158249423Sdim DebianJessie, 2159218893Sdim Exherbo, 2160223017Sdim RHEL4, 2161223017Sdim RHEL5, 2162223017Sdim RHEL6, 2163263508Sdim Fedora, 2164263508Sdim OpenSUSE, 2165221345Sdim UbuntuHardy, 2166221345Sdim UbuntuIntrepid, 2167218893Sdim UbuntuJaunty, 2168218893Sdim UbuntuKarmic, 2169218893Sdim UbuntuLucid, 2170218893Sdim UbuntuMaverick, 2171221345Sdim UbuntuNatty, 2172223017Sdim UbuntuOneiric, 2173234353Sdim UbuntuPrecise, 2174244628Sdim UbuntuQuantal, 2175244628Sdim UbuntuRaring, 2176263508Sdim UbuntuSaucy, 2177263508Sdim UbuntuTrusty, 2178218893Sdim UnknownDistro 2179218893Sdim}; 2180198092Srdivacky 2181249423Sdimstatic bool IsRedhat(enum Distro Distro) { 2182263508Sdim return Distro == Fedora || (Distro >= RHEL4 && Distro <= RHEL6); 2183218893Sdim} 2184198092Srdivacky 2185263508Sdimstatic bool IsOpenSUSE(enum Distro Distro) { 2186263508Sdim return Distro == OpenSUSE; 2187193326Sed} 2188193326Sed 2189249423Sdimstatic bool IsDebian(enum Distro Distro) { 2190249423Sdim return Distro >= DebianLenny && Distro <= DebianJessie; 2191218893Sdim} 2192218893Sdim 2193249423Sdimstatic bool IsUbuntu(enum Distro Distro) { 2194263508Sdim return Distro >= UbuntuHardy && Distro <= UbuntuTrusty; 2195218893Sdim} 2196218893Sdim 2197249423Sdimstatic Distro DetectDistro(llvm::Triple::ArchType Arch) { 2198234353Sdim OwningPtr<llvm::MemoryBuffer> File; 2199218893Sdim if (!llvm::MemoryBuffer::getFile("/etc/lsb-release", File)) { 2200226633Sdim StringRef Data = File.get()->getBuffer(); 2201226633Sdim SmallVector<StringRef, 8> Lines; 2202218893Sdim Data.split(Lines, "\n"); 2203249423Sdim Distro Version = UnknownDistro; 2204234353Sdim for (unsigned i = 0, s = Lines.size(); i != s; ++i) 2205234353Sdim if (Version == UnknownDistro && Lines[i].startswith("DISTRIB_CODENAME=")) 2206249423Sdim Version = llvm::StringSwitch<Distro>(Lines[i].substr(17)) 2207234353Sdim .Case("hardy", UbuntuHardy) 2208234353Sdim .Case("intrepid", UbuntuIntrepid) 2209234353Sdim .Case("jaunty", UbuntuJaunty) 2210234353Sdim .Case("karmic", UbuntuKarmic) 2211234353Sdim .Case("lucid", UbuntuLucid) 2212234353Sdim .Case("maverick", UbuntuMaverick) 2213234353Sdim .Case("natty", UbuntuNatty) 2214234353Sdim .Case("oneiric", UbuntuOneiric) 2215234353Sdim .Case("precise", UbuntuPrecise) 2216244628Sdim .Case("quantal", UbuntuQuantal) 2217244628Sdim .Case("raring", UbuntuRaring) 2218263508Sdim .Case("saucy", UbuntuSaucy) 2219263508Sdim .Case("trusty", UbuntuTrusty) 2220234353Sdim .Default(UnknownDistro); 2221234353Sdim return Version; 2222218893Sdim } 2223218893Sdim 2224218893Sdim if (!llvm::MemoryBuffer::getFile("/etc/redhat-release", File)) { 2225226633Sdim StringRef Data = File.get()->getBuffer(); 2226263508Sdim if (Data.startswith("Fedora release")) 2227263508Sdim return Fedora; 2228223017Sdim else if (Data.startswith("Red Hat Enterprise Linux") && 2229226633Sdim Data.find("release 6") != StringRef::npos) 2230223017Sdim return RHEL6; 2231223017Sdim else if ((Data.startswith("Red Hat Enterprise Linux") || 2232249423Sdim Data.startswith("CentOS")) && 2233226633Sdim Data.find("release 5") != StringRef::npos) 2234223017Sdim return RHEL5; 2235223017Sdim else if ((Data.startswith("Red Hat Enterprise Linux") || 2236249423Sdim Data.startswith("CentOS")) && 2237226633Sdim Data.find("release 4") != StringRef::npos) 2238223017Sdim return RHEL4; 2239218893Sdim return UnknownDistro; 2240218893Sdim } 2241218893Sdim 2242218893Sdim if (!llvm::MemoryBuffer::getFile("/etc/debian_version", File)) { 2243226633Sdim StringRef Data = File.get()->getBuffer(); 2244218893Sdim if (Data[0] == '5') 2245218893Sdim return DebianLenny; 2246234353Sdim else if (Data.startswith("squeeze/sid") || Data[0] == '6') 2247218893Sdim return DebianSqueeze; 2248234353Sdim else if (Data.startswith("wheezy/sid") || Data[0] == '7') 2249223017Sdim return DebianWheezy; 2250249423Sdim else if (Data.startswith("jessie/sid") || Data[0] == '8') 2251249423Sdim return DebianJessie; 2252218893Sdim return UnknownDistro; 2253218893Sdim } 2254218893Sdim 2255263508Sdim if (llvm::sys::fs::exists("/etc/SuSE-release")) 2256263508Sdim return OpenSUSE; 2257218893Sdim 2258263508Sdim if (llvm::sys::fs::exists("/etc/exherbo-release")) 2259218893Sdim return Exherbo; 2260218893Sdim 2261263508Sdim if (llvm::sys::fs::exists("/etc/arch-release")) 2262219077Sdim return ArchLinux; 2263219077Sdim 2264218893Sdim return UnknownDistro; 2265218893Sdim} 2266218893Sdim 2267228379Sdim/// \brief Get our best guess at the multiarch triple for a target. 2268228379Sdim/// 2269228379Sdim/// Debian-based systems are starting to use a multiarch setup where they use 2270228379Sdim/// a target-triple directory in the library and header search paths. 2271228379Sdim/// Unfortunately, this triple does not align with the vanilla target triple, 2272228379Sdim/// so we provide a rough mapping here. 2273228379Sdimstatic std::string getMultiarchTriple(const llvm::Triple TargetTriple, 2274228379Sdim StringRef SysRoot) { 2275228379Sdim // For most architectures, just use whatever we have rather than trying to be 2276228379Sdim // clever. 2277228379Sdim switch (TargetTriple.getArch()) { 2278228379Sdim default: 2279228379Sdim return TargetTriple.str(); 2280226633Sdim 2281228379Sdim // We use the existence of '/lib/<triple>' as a directory to detect some 2282228379Sdim // common linux triples that don't quite match the Clang triple for both 2283234353Sdim // 32-bit and 64-bit targets. Multiarch fixes its install triples to these 2284234353Sdim // regardless of what the actual target triple is. 2285239462Sdim case llvm::Triple::arm: 2286239462Sdim case llvm::Triple::thumb: 2287239462Sdim if (TargetTriple.getEnvironment() == llvm::Triple::GNUEABIHF) { 2288239462Sdim if (llvm::sys::fs::exists(SysRoot + "/lib/arm-linux-gnueabihf")) 2289239462Sdim return "arm-linux-gnueabihf"; 2290239462Sdim } else { 2291239462Sdim if (llvm::sys::fs::exists(SysRoot + "/lib/arm-linux-gnueabi")) 2292239462Sdim return "arm-linux-gnueabi"; 2293239462Sdim } 2294239462Sdim return TargetTriple.str(); 2295228379Sdim case llvm::Triple::x86: 2296228379Sdim if (llvm::sys::fs::exists(SysRoot + "/lib/i386-linux-gnu")) 2297228379Sdim return "i386-linux-gnu"; 2298228379Sdim return TargetTriple.str(); 2299228379Sdim case llvm::Triple::x86_64: 2300228379Sdim if (llvm::sys::fs::exists(SysRoot + "/lib/x86_64-linux-gnu")) 2301228379Sdim return "x86_64-linux-gnu"; 2302228379Sdim return TargetTriple.str(); 2303249423Sdim case llvm::Triple::aarch64: 2304249423Sdim if (llvm::sys::fs::exists(SysRoot + "/lib/aarch64-linux-gnu")) 2305249423Sdim return "aarch64-linux-gnu"; 2306263508Sdim return TargetTriple.str(); 2307234353Sdim case llvm::Triple::mips: 2308234353Sdim if (llvm::sys::fs::exists(SysRoot + "/lib/mips-linux-gnu")) 2309234353Sdim return "mips-linux-gnu"; 2310234353Sdim return TargetTriple.str(); 2311234353Sdim case llvm::Triple::mipsel: 2312234353Sdim if (llvm::sys::fs::exists(SysRoot + "/lib/mipsel-linux-gnu")) 2313234353Sdim return "mipsel-linux-gnu"; 2314234353Sdim return TargetTriple.str(); 2315234353Sdim case llvm::Triple::ppc: 2316249423Sdim if (llvm::sys::fs::exists(SysRoot + "/lib/powerpc-linux-gnuspe")) 2317249423Sdim return "powerpc-linux-gnuspe"; 2318234353Sdim if (llvm::sys::fs::exists(SysRoot + "/lib/powerpc-linux-gnu")) 2319234353Sdim return "powerpc-linux-gnu"; 2320234353Sdim return TargetTriple.str(); 2321234353Sdim case llvm::Triple::ppc64: 2322234353Sdim if (llvm::sys::fs::exists(SysRoot + "/lib/powerpc64-linux-gnu")) 2323234353Sdim return "powerpc64-linux-gnu"; 2324263508Sdim case llvm::Triple::ppc64le: 2325263508Sdim if (llvm::sys::fs::exists(SysRoot + "/lib/powerpc64le-linux-gnu")) 2326263508Sdim return "powerpc64le-linux-gnu"; 2327234353Sdim return TargetTriple.str(); 2328226633Sdim } 2329226633Sdim} 2330226633Sdim 2331234353Sdimstatic void addPathIfExists(Twine Path, ToolChain::path_list &Paths) { 2332234353Sdim if (llvm::sys::fs::exists(Path)) Paths.push_back(Path.str()); 2333234353Sdim} 2334234353Sdim 2335243830Sdimstatic StringRef getMultilibDir(const llvm::Triple &Triple, 2336243830Sdim const ArgList &Args) { 2337263508Sdim if (isMipsArch(Triple.getArch())) { 2338263508Sdim // lib32 directory has a special meaning on MIPS targets. 2339263508Sdim // It contains N32 ABI binaries. Use this folder if produce 2340263508Sdim // code for N32 ABI only. 2341263508Sdim if (hasMipsN32ABIArg(Args)) 2342263508Sdim return "lib32"; 2343263508Sdim return Triple.isArch32Bit() ? "lib" : "lib64"; 2344263508Sdim } 2345243830Sdim 2346263508Sdim // It happens that only x86 and PPC use the 'lib32' variant of multilib, and 2347263508Sdim // using that variant while targeting other architectures causes problems 2348263508Sdim // because the libraries are laid out in shared system roots that can't cope 2349263508Sdim // with a 'lib32' multilib search path being considered. So we only enable 2350263508Sdim // them when we know we may need it. 2351263508Sdim // 2352263508Sdim // FIXME: This is a bit of a hack. We should really unify this code for 2353263508Sdim // reasoning about multilib spellings with the lib dir spellings in the 2354263508Sdim // GCCInstallationDetector, but that is a more significant refactoring. 2355263508Sdim if (Triple.getArch() == llvm::Triple::x86 || 2356263508Sdim Triple.getArch() == llvm::Triple::ppc) 2357243830Sdim return "lib32"; 2358243830Sdim 2359243830Sdim return Triple.isArch32Bit() ? "lib" : "lib64"; 2360243830Sdim} 2361243830Sdim 2362234353SdimLinux::Linux(const Driver &D, const llvm::Triple &Triple, const ArgList &Args) 2363234353Sdim : Generic_ELF(D, Triple, Args) { 2364263508Sdim GCCInstallation.init(Triple, Args); 2365234353Sdim llvm::Triple::ArchType Arch = Triple.getArch(); 2366263508Sdim std::string SysRoot = computeSysRoot(); 2367226633Sdim 2368263508Sdim // Cross-compiling binutils and GCC installations (vanilla and openSUSE at 2369263508Sdim // least) put various tools in a triple-prefixed directory off of the parent 2370263508Sdim // of the GCC installation. We use the GCC triple here to ensure that we end 2371263508Sdim // up with tools that support the same amount of cross compiling as the 2372263508Sdim // detected GCC installation. For example, if we find a GCC installation 2373263508Sdim // targeting x86_64, but it is a bi-arch GCC installation, it can also be 2374263508Sdim // used to target i386. 2375263508Sdim // FIXME: This seems unlikely to be Linux-specific. 2376226633Sdim ToolChain::path_list &PPaths = getProgramPaths(); 2377228379Sdim PPaths.push_back(Twine(GCCInstallation.getParentLibPath() + "/../" + 2378234353Sdim GCCInstallation.getTriple().str() + "/bin").str()); 2379226633Sdim 2380226633Sdim Linker = GetProgramPath("ld"); 2381226633Sdim 2382249423Sdim Distro Distro = DetectDistro(Arch); 2383218893Sdim 2384263508Sdim if (IsOpenSUSE(Distro) || IsUbuntu(Distro)) { 2385218893Sdim ExtraOpts.push_back("-z"); 2386218893Sdim ExtraOpts.push_back("relro"); 2387218893Sdim } 2388218893Sdim 2389221345Sdim if (Arch == llvm::Triple::arm || Arch == llvm::Triple::thumb) 2390218893Sdim ExtraOpts.push_back("-X"); 2391218893Sdim 2392243830Sdim const bool IsAndroid = Triple.getEnvironment() == llvm::Triple::Android; 2393251662Sdim const bool IsMips = isMipsArch(Arch); 2394218893Sdim 2395251662Sdim if (IsMips && !SysRoot.empty()) 2396251662Sdim ExtraOpts.push_back("--sysroot=" + SysRoot); 2397251662Sdim 2398234353Sdim // Do not use 'gnu' hash style for Mips targets because .gnu.hash 2399234353Sdim // and the MIPS ABI require .dynsym to be sorted in different ways. 2400234353Sdim // .gnu.hash needs symbols to be grouped by hash code whereas the MIPS 2401234353Sdim // ABI requires a mapping between the GOT and the symbol table. 2402234353Sdim // Android loader does not support .gnu.hash. 2403251662Sdim if (!IsMips && !IsAndroid) { 2404263508Sdim if (IsRedhat(Distro) || IsOpenSUSE(Distro) || 2405234353Sdim (IsUbuntu(Distro) && Distro >= UbuntuMaverick)) 2406234353Sdim ExtraOpts.push_back("--hash-style=gnu"); 2407234353Sdim 2408263508Sdim if (IsDebian(Distro) || IsOpenSUSE(Distro) || Distro == UbuntuLucid || 2409234353Sdim Distro == UbuntuJaunty || Distro == UbuntuKarmic) 2410234353Sdim ExtraOpts.push_back("--hash-style=both"); 2411234353Sdim } 2412234353Sdim 2413223017Sdim if (IsRedhat(Distro)) 2414218893Sdim ExtraOpts.push_back("--no-add-needed"); 2415218893Sdim 2416223017Sdim if (Distro == DebianSqueeze || Distro == DebianWheezy || 2417263508Sdim Distro == DebianJessie || IsOpenSUSE(Distro) || 2418223017Sdim (IsRedhat(Distro) && Distro != RHEL4 && Distro != RHEL5) || 2419234353Sdim (IsUbuntu(Distro) && Distro >= UbuntuKarmic)) 2420218893Sdim ExtraOpts.push_back("--build-id"); 2421218893Sdim 2422263508Sdim if (IsOpenSUSE(Distro)) 2423223017Sdim ExtraOpts.push_back("--enable-new-dtags"); 2424223017Sdim 2425226633Sdim // The selection of paths to try here is designed to match the patterns which 2426226633Sdim // the GCC driver itself uses, as this is part of the GCC-compatible driver. 2427226633Sdim // This was determined by running GCC in a fake filesystem, creating all 2428226633Sdim // possible permutations of these directories, and seeing which ones it added 2429226633Sdim // to the link paths. 2430226633Sdim path_list &Paths = getFilePaths(); 2431219077Sdim 2432243830Sdim const std::string Multilib = getMultilibDir(Triple, Args); 2433228379Sdim const std::string MultiarchTriple = getMultiarchTriple(Triple, SysRoot); 2434226633Sdim 2435228379Sdim // Add the multilib suffixed paths where they are available. 2436228379Sdim if (GCCInstallation.isValid()) { 2437234353Sdim const llvm::Triple &GCCTriple = GCCInstallation.getTriple(); 2438228379Sdim const std::string &LibPath = GCCInstallation.getParentLibPath(); 2439234353Sdim 2440263508Sdim // Sourcery CodeBench MIPS toolchain holds some libraries under 2441263508Sdim // a biarch-like suffix of the GCC installation. 2442263508Sdim // 2443263508Sdim // FIXME: It would be cleaner to model this as a variant of bi-arch. IE, 2444263508Sdim // instead of a '64' biarch suffix it would be 'el' or something. 2445263508Sdim if (IsAndroid && IsMips && isMips32r2(Args)) { 2446263508Sdim assert(GCCInstallation.getBiarchSuffix().empty() && 2447263508Sdim "Unexpected bi-arch suffix"); 2448263508Sdim addPathIfExists(GCCInstallation.getInstallPath() + "/mips-r2", Paths); 2449263508Sdim } else { 2450243830Sdim addPathIfExists((GCCInstallation.getInstallPath() + 2451263508Sdim GCCInstallation.getMIPSABIDirSuffix() + 2452263508Sdim GCCInstallation.getBiarchSuffix()), 2453243830Sdim Paths); 2454263508Sdim } 2455243830Sdim 2456263508Sdim // GCC cross compiling toolchains will install target libraries which ship 2457263508Sdim // as part of the toolchain under <prefix>/<triple>/<libdir> rather than as 2458263508Sdim // any part of the GCC installation in 2459263508Sdim // <prefix>/<libdir>/gcc/<triple>/<version>. This decision is somewhat 2460263508Sdim // debatable, but is the reality today. We need to search this tree even 2461263508Sdim // when we have a sysroot somewhere else. It is the responsibility of 2462263508Sdim // whomever is doing the cross build targetting a sysroot using a GCC 2463263508Sdim // installation that is *not* within the system root to ensure two things: 2464263508Sdim // 2465263508Sdim // 1) Any DSOs that are linked in from this tree or from the install path 2466263508Sdim // above must be preasant on the system root and found via an 2467263508Sdim // appropriate rpath. 2468263508Sdim // 2) There must not be libraries installed into 2469263508Sdim // <prefix>/<triple>/<libdir> unless they should be preferred over 2470263508Sdim // those within the system root. 2471263508Sdim // 2472263508Sdim // Note that this matches the GCC behavior. See the below comment for where 2473263508Sdim // Clang diverges from GCC's behavior. 2474263508Sdim addPathIfExists(LibPath + "/../" + GCCTriple.str() + "/lib/../" + Multilib + 2475263508Sdim GCCInstallation.getMIPSABIDirSuffix(), 2476263508Sdim Paths); 2477263508Sdim 2478234353Sdim // If the GCC installation we found is inside of the sysroot, we want to 2479234353Sdim // prefer libraries installed in the parent prefix of the GCC installation. 2480234353Sdim // It is important to *not* use these paths when the GCC installation is 2481234982Sdim // outside of the system root as that can pick up unintended libraries. 2482234353Sdim // This usually happens when there is an external cross compiler on the 2483234353Sdim // host system, and a more minimal sysroot available that is the target of 2484263508Sdim // the cross. Note that GCC does include some of these directories in some 2485263508Sdim // configurations but this seems somewhere between questionable and simply 2486263508Sdim // a bug. 2487234353Sdim if (StringRef(LibPath).startswith(SysRoot)) { 2488234353Sdim addPathIfExists(LibPath + "/" + MultiarchTriple, Paths); 2489234353Sdim addPathIfExists(LibPath + "/../" + Multilib, Paths); 2490234353Sdim } 2491228379Sdim } 2492228379Sdim addPathIfExists(SysRoot + "/lib/" + MultiarchTriple, Paths); 2493228379Sdim addPathIfExists(SysRoot + "/lib/../" + Multilib, Paths); 2494228379Sdim addPathIfExists(SysRoot + "/usr/lib/" + MultiarchTriple, Paths); 2495228379Sdim addPathIfExists(SysRoot + "/usr/lib/../" + Multilib, Paths); 2496226633Sdim 2497263508Sdim // Try walking via the GCC triple path in case of biarch or multiarch GCC 2498228379Sdim // installations with strange symlinks. 2499263508Sdim if (GCCInstallation.isValid()) { 2500234353Sdim addPathIfExists(SysRoot + "/usr/lib/" + GCCInstallation.getTriple().str() + 2501228379Sdim "/../../" + Multilib, Paths); 2502226633Sdim 2503263508Sdim // Add the non-multilib suffixed paths (if potentially different). 2504226633Sdim const std::string &LibPath = GCCInstallation.getParentLibPath(); 2505234353Sdim const llvm::Triple &GCCTriple = GCCInstallation.getTriple(); 2506263508Sdim if (!GCCInstallation.getBiarchSuffix().empty()) 2507263508Sdim addPathIfExists(GCCInstallation.getInstallPath() + 2508263508Sdim GCCInstallation.getMIPSABIDirSuffix(), Paths); 2509234353Sdim 2510263508Sdim // See comments above on the multilib variant for details of why this is 2511263508Sdim // included even from outside the sysroot. 2512263508Sdim addPathIfExists(LibPath + "/../" + GCCTriple.str() + 2513263508Sdim "/lib" + GCCInstallation.getMIPSABIDirSuffix(), Paths); 2514263508Sdim 2515263508Sdim // See comments above on the multilib variant for details of why this is 2516263508Sdim // only included from within the sysroot. 2517263508Sdim if (StringRef(LibPath).startswith(SysRoot)) 2518234353Sdim addPathIfExists(LibPath, Paths); 2519226633Sdim } 2520226633Sdim addPathIfExists(SysRoot + "/lib", Paths); 2521226633Sdim addPathIfExists(SysRoot + "/usr/lib", Paths); 2522263508Sdim} 2523251662Sdim 2524263508Sdimbool FreeBSD::HasNativeLLVMSupport() const { 2525263508Sdim return true; 2526218893Sdim} 2527218893Sdim 2528218893Sdimbool Linux::HasNativeLLVMSupport() const { 2529218893Sdim return true; 2530218893Sdim} 2531218893Sdim 2532249423SdimTool *Linux::buildLinker() const { 2533249423Sdim return new tools::gnutools::Link(*this); 2534249423Sdim} 2535212904Sdim 2536249423SdimTool *Linux::buildAssembler() const { 2537249423Sdim return new tools::gnutools::Assemble(*this); 2538212904Sdim} 2539212904Sdim 2540249423Sdimvoid Linux::addClangTargetOptions(const ArgList &DriverArgs, 2541249423Sdim ArgStringList &CC1Args) const { 2542239462Sdim const Generic_GCC::GCCVersion &V = GCCInstallation.getVersion(); 2543263508Sdim bool UseInitArrayDefault = 2544263508Sdim !V.isOlderThan(4, 7, 0) || 2545249423Sdim getTriple().getArch() == llvm::Triple::aarch64 || 2546249423Sdim getTriple().getEnvironment() == llvm::Triple::Android; 2547249423Sdim if (DriverArgs.hasFlag(options::OPT_fuse_init_array, 2548249423Sdim options::OPT_fno_use_init_array, 2549249423Sdim UseInitArrayDefault)) 2550239462Sdim CC1Args.push_back("-fuse-init-array"); 2551239462Sdim} 2552239462Sdim 2553263508Sdimstd::string Linux::computeSysRoot() const { 2554251662Sdim if (!getDriver().SysRoot.empty()) 2555251662Sdim return getDriver().SysRoot; 2556251662Sdim 2557251662Sdim if (!GCCInstallation.isValid() || !isMipsArch(getTriple().getArch())) 2558251662Sdim return std::string(); 2559251662Sdim 2560263508Sdim // Standalone MIPS toolchains use different names for sysroot folder 2561263508Sdim // and put it into different places. Here we try to check some known 2562263508Sdim // variants. 2563251662Sdim 2564263508Sdim const StringRef InstallDir = GCCInstallation.getInstallPath(); 2565263508Sdim const StringRef TripleStr = GCCInstallation.getTriple().str(); 2566263508Sdim const StringRef MIPSABIDirSuffix = GCCInstallation.getMIPSABIDirSuffix(); 2567263508Sdim 2568263508Sdim std::string Path = (InstallDir + "/../../../../" + TripleStr + "/libc" + 2569263508Sdim MIPSABIDirSuffix).str(); 2570263508Sdim 2571263508Sdim if (llvm::sys::fs::exists(Path)) 2572263508Sdim return Path; 2573263508Sdim 2574263508Sdim Path = (InstallDir + "/../../../../sysroot" + MIPSABIDirSuffix).str(); 2575263508Sdim 2576263508Sdim if (llvm::sys::fs::exists(Path)) 2577263508Sdim return Path; 2578263508Sdim 2579263508Sdim return std::string(); 2580251662Sdim} 2581251662Sdim 2582228379Sdimvoid Linux::AddClangSystemIncludeArgs(const ArgList &DriverArgs, 2583228379Sdim ArgStringList &CC1Args) const { 2584228379Sdim const Driver &D = getDriver(); 2585263508Sdim std::string SysRoot = computeSysRoot(); 2586228379Sdim 2587228379Sdim if (DriverArgs.hasArg(options::OPT_nostdinc)) 2588228379Sdim return; 2589228379Sdim 2590228379Sdim if (!DriverArgs.hasArg(options::OPT_nostdlibinc)) 2591251662Sdim addSystemInclude(DriverArgs, CC1Args, SysRoot + "/usr/local/include"); 2592228379Sdim 2593228379Sdim if (!DriverArgs.hasArg(options::OPT_nobuiltininc)) { 2594263508Sdim SmallString<128> P(D.ResourceDir); 2595263508Sdim llvm::sys::path::append(P, "include"); 2596228379Sdim addSystemInclude(DriverArgs, CC1Args, P.str()); 2597228379Sdim } 2598228379Sdim 2599228379Sdim if (DriverArgs.hasArg(options::OPT_nostdlibinc)) 2600228379Sdim return; 2601228379Sdim 2602228379Sdim // Check for configure-time C include directories. 2603228379Sdim StringRef CIncludeDirs(C_INCLUDE_DIRS); 2604228379Sdim if (CIncludeDirs != "") { 2605228379Sdim SmallVector<StringRef, 5> dirs; 2606228379Sdim CIncludeDirs.split(dirs, ":"); 2607228379Sdim for (SmallVectorImpl<StringRef>::iterator I = dirs.begin(), E = dirs.end(); 2608228379Sdim I != E; ++I) { 2609251662Sdim StringRef Prefix = llvm::sys::path::is_absolute(*I) ? SysRoot : ""; 2610228379Sdim addExternCSystemInclude(DriverArgs, CC1Args, Prefix + *I); 2611228379Sdim } 2612228379Sdim return; 2613228379Sdim } 2614228379Sdim 2615228379Sdim // Lacking those, try to detect the correct set of system includes for the 2616228379Sdim // target triple. 2617228379Sdim 2618251662Sdim // Sourcery CodeBench and modern FSF Mips toolchains put extern C 2619251662Sdim // system includes under three additional directories. 2620251662Sdim if (GCCInstallation.isValid() && isMipsArch(getTriple().getArch())) { 2621263508Sdim addExternCSystemIncludeIfExists( 2622263508Sdim DriverArgs, CC1Args, GCCInstallation.getInstallPath() + "/include"); 2623251662Sdim 2624263508Sdim addExternCSystemIncludeIfExists( 2625263508Sdim DriverArgs, CC1Args, 2626263508Sdim GCCInstallation.getInstallPath() + "/../../../../" + 2627263508Sdim GCCInstallation.getTriple().str() + "/libc/usr/include"); 2628263508Sdim 2629263508Sdim addExternCSystemIncludeIfExists( 2630263508Sdim DriverArgs, CC1Args, 2631263508Sdim GCCInstallation.getInstallPath() + "/../../../../sysroot/usr/include"); 2632251662Sdim } 2633251662Sdim 2634228379Sdim // Implement generic Debian multiarch support. 2635228379Sdim const StringRef X86_64MultiarchIncludeDirs[] = { 2636228379Sdim "/usr/include/x86_64-linux-gnu", 2637228379Sdim 2638228379Sdim // FIXME: These are older forms of multiarch. It's not clear that they're 2639228379Sdim // in use in any released version of Debian, so we should consider 2640228379Sdim // removing them. 2641263508Sdim "/usr/include/i686-linux-gnu/64", "/usr/include/i486-linux-gnu/64" 2642228379Sdim }; 2643228379Sdim const StringRef X86MultiarchIncludeDirs[] = { 2644228379Sdim "/usr/include/i386-linux-gnu", 2645228379Sdim 2646228379Sdim // FIXME: These are older forms of multiarch. It's not clear that they're 2647228379Sdim // in use in any released version of Debian, so we should consider 2648228379Sdim // removing them. 2649263508Sdim "/usr/include/x86_64-linux-gnu/32", "/usr/include/i686-linux-gnu", 2650228379Sdim "/usr/include/i486-linux-gnu" 2651228379Sdim }; 2652249423Sdim const StringRef AArch64MultiarchIncludeDirs[] = { 2653249423Sdim "/usr/include/aarch64-linux-gnu" 2654249423Sdim }; 2655228379Sdim const StringRef ARMMultiarchIncludeDirs[] = { 2656228379Sdim "/usr/include/arm-linux-gnueabi" 2657228379Sdim }; 2658239462Sdim const StringRef ARMHFMultiarchIncludeDirs[] = { 2659239462Sdim "/usr/include/arm-linux-gnueabihf" 2660239462Sdim }; 2661234353Sdim const StringRef MIPSMultiarchIncludeDirs[] = { 2662234353Sdim "/usr/include/mips-linux-gnu" 2663234353Sdim }; 2664234353Sdim const StringRef MIPSELMultiarchIncludeDirs[] = { 2665234353Sdim "/usr/include/mipsel-linux-gnu" 2666234353Sdim }; 2667234353Sdim const StringRef PPCMultiarchIncludeDirs[] = { 2668234353Sdim "/usr/include/powerpc-linux-gnu" 2669234353Sdim }; 2670234353Sdim const StringRef PPC64MultiarchIncludeDirs[] = { 2671234353Sdim "/usr/include/powerpc64-linux-gnu" 2672234353Sdim }; 2673228379Sdim ArrayRef<StringRef> MultiarchIncludeDirs; 2674228379Sdim if (getTriple().getArch() == llvm::Triple::x86_64) { 2675228379Sdim MultiarchIncludeDirs = X86_64MultiarchIncludeDirs; 2676228379Sdim } else if (getTriple().getArch() == llvm::Triple::x86) { 2677228379Sdim MultiarchIncludeDirs = X86MultiarchIncludeDirs; 2678249423Sdim } else if (getTriple().getArch() == llvm::Triple::aarch64) { 2679249423Sdim MultiarchIncludeDirs = AArch64MultiarchIncludeDirs; 2680228379Sdim } else if (getTriple().getArch() == llvm::Triple::arm) { 2681239462Sdim if (getTriple().getEnvironment() == llvm::Triple::GNUEABIHF) 2682239462Sdim MultiarchIncludeDirs = ARMHFMultiarchIncludeDirs; 2683239462Sdim else 2684239462Sdim MultiarchIncludeDirs = ARMMultiarchIncludeDirs; 2685234353Sdim } else if (getTriple().getArch() == llvm::Triple::mips) { 2686234353Sdim MultiarchIncludeDirs = MIPSMultiarchIncludeDirs; 2687234353Sdim } else if (getTriple().getArch() == llvm::Triple::mipsel) { 2688234353Sdim MultiarchIncludeDirs = MIPSELMultiarchIncludeDirs; 2689234353Sdim } else if (getTriple().getArch() == llvm::Triple::ppc) { 2690234353Sdim MultiarchIncludeDirs = PPCMultiarchIncludeDirs; 2691234353Sdim } else if (getTriple().getArch() == llvm::Triple::ppc64) { 2692234353Sdim MultiarchIncludeDirs = PPC64MultiarchIncludeDirs; 2693228379Sdim } 2694228379Sdim for (ArrayRef<StringRef>::iterator I = MultiarchIncludeDirs.begin(), 2695228379Sdim E = MultiarchIncludeDirs.end(); 2696228379Sdim I != E; ++I) { 2697251662Sdim if (llvm::sys::fs::exists(SysRoot + *I)) { 2698251662Sdim addExternCSystemInclude(DriverArgs, CC1Args, SysRoot + *I); 2699228379Sdim break; 2700228379Sdim } 2701228379Sdim } 2702228379Sdim 2703228379Sdim if (getTriple().getOS() == llvm::Triple::RTEMS) 2704228379Sdim return; 2705228379Sdim 2706234353Sdim // Add an include of '/include' directly. This isn't provided by default by 2707234353Sdim // system GCCs, but is often used with cross-compiling GCCs, and harmless to 2708234353Sdim // add even when Clang is acting as-if it were a system compiler. 2709251662Sdim addExternCSystemInclude(DriverArgs, CC1Args, SysRoot + "/include"); 2710234353Sdim 2711251662Sdim addExternCSystemInclude(DriverArgs, CC1Args, SysRoot + "/usr/include"); 2712228379Sdim} 2713228379Sdim 2714249423Sdim/// \brief Helper to add the three variant paths for a libstdc++ installation. 2715234353Sdim/*static*/ bool Linux::addLibStdCXXIncludePaths(Twine Base, Twine TargetArchDir, 2716234353Sdim const ArgList &DriverArgs, 2717234353Sdim ArgStringList &CC1Args) { 2718228379Sdim if (!llvm::sys::fs::exists(Base)) 2719228379Sdim return false; 2720228379Sdim addSystemInclude(DriverArgs, CC1Args, Base); 2721228379Sdim addSystemInclude(DriverArgs, CC1Args, Base + "/" + TargetArchDir); 2722228379Sdim addSystemInclude(DriverArgs, CC1Args, Base + "/backward"); 2723228379Sdim return true; 2724228379Sdim} 2725228379Sdim 2726249423Sdim/// \brief Helper to add an extra variant path for an (Ubuntu) multilib 2727249423Sdim/// libstdc++ installation. 2728249423Sdim/*static*/ bool Linux::addLibStdCXXIncludePaths(Twine Base, Twine Suffix, 2729249423Sdim Twine TargetArchDir, 2730263508Sdim Twine BiarchSuffix, 2731263508Sdim Twine MIPSABIDirSuffix, 2732249423Sdim const ArgList &DriverArgs, 2733249423Sdim ArgStringList &CC1Args) { 2734263508Sdim if (!addLibStdCXXIncludePaths(Base + Suffix, 2735263508Sdim TargetArchDir + MIPSABIDirSuffix + BiarchSuffix, 2736249423Sdim DriverArgs, CC1Args)) 2737249423Sdim return false; 2738249423Sdim 2739249423Sdim addSystemInclude(DriverArgs, CC1Args, Base + "/" + TargetArchDir + Suffix 2740263508Sdim + MIPSABIDirSuffix + BiarchSuffix); 2741249423Sdim return true; 2742249423Sdim} 2743249423Sdim 2744228379Sdimvoid Linux::AddClangCXXStdlibIncludeArgs(const ArgList &DriverArgs, 2745228379Sdim ArgStringList &CC1Args) const { 2746228379Sdim if (DriverArgs.hasArg(options::OPT_nostdlibinc) || 2747228379Sdim DriverArgs.hasArg(options::OPT_nostdincxx)) 2748228379Sdim return; 2749228379Sdim 2750228379Sdim // Check if libc++ has been enabled and provide its include paths if so. 2751228379Sdim if (GetCXXStdlibType(DriverArgs) == ToolChain::CST_Libcxx) { 2752228379Sdim // libc++ is always installed at a fixed path on Linux currently. 2753228379Sdim addSystemInclude(DriverArgs, CC1Args, 2754228379Sdim getDriver().SysRoot + "/usr/include/c++/v1"); 2755228379Sdim return; 2756228379Sdim } 2757228379Sdim 2758234353Sdim // We need a detected GCC installation on Linux to provide libstdc++'s 2759234353Sdim // headers. We handled the libc++ case above. 2760234353Sdim if (!GCCInstallation.isValid()) 2761228379Sdim return; 2762228379Sdim 2763228379Sdim // By default, look for the C++ headers in an include directory adjacent to 2764228379Sdim // the lib directory of the GCC installation. Note that this is expect to be 2765228379Sdim // equivalent to '/usr/include/c++/X.Y' in almost all cases. 2766228379Sdim StringRef LibDir = GCCInstallation.getParentLibPath(); 2767228379Sdim StringRef InstallDir = GCCInstallation.getInstallPath(); 2768243830Sdim StringRef TripleStr = GCCInstallation.getTriple().str(); 2769263508Sdim StringRef MIPSABIDirSuffix = GCCInstallation.getMIPSABIDirSuffix(); 2770263508Sdim StringRef BiarchSuffix = GCCInstallation.getBiarchSuffix(); 2771263508Sdim const GCCVersion &Version = GCCInstallation.getVersion(); 2772243830Sdim 2773263508Sdim if (addLibStdCXXIncludePaths(LibDir.str() + "/../include", 2774263508Sdim "/c++/" + Version.Text, TripleStr, BiarchSuffix, 2775263508Sdim MIPSABIDirSuffix, DriverArgs, CC1Args)) 2776249423Sdim return; 2777249423Sdim 2778243830Sdim const std::string IncludePathCandidates[] = { 2779228379Sdim // Gentoo is weird and places its headers inside the GCC install, so if the 2780263508Sdim // first attempt to find the headers fails, try these patterns. 2781263508Sdim InstallDir.str() + "/include/g++-v" + Version.MajorStr + "." + 2782263508Sdim Version.MinorStr, 2783263508Sdim InstallDir.str() + "/include/g++-v" + Version.MajorStr, 2784243830Sdim // Android standalone toolchain has C++ headers in yet another place. 2785263508Sdim LibDir.str() + "/../" + TripleStr.str() + "/include/c++/" + Version.Text, 2786243830Sdim // Freescale SDK C++ headers are directly in <sysroot>/usr/include/c++, 2787243830Sdim // without a subdirectory corresponding to the gcc version. 2788243830Sdim LibDir.str() + "/../include/c++", 2789243830Sdim }; 2790243830Sdim 2791243830Sdim for (unsigned i = 0; i < llvm::array_lengthof(IncludePathCandidates); ++i) { 2792263508Sdim if (addLibStdCXXIncludePaths(IncludePathCandidates[i], 2793263508Sdim TripleStr + MIPSABIDirSuffix + BiarchSuffix, 2794263508Sdim DriverArgs, CC1Args)) 2795243830Sdim break; 2796228379Sdim } 2797228379Sdim} 2798228379Sdim 2799251662Sdimbool Linux::isPIEDefault() const { 2800263508Sdim return getSanitizerArgs().hasZeroBaseShadow(); 2801251662Sdim} 2802251662Sdim 2803193326Sed/// DragonFly - DragonFly tool chain which can call as(1) and ld(1) directly. 2804193326Sed 2805234353SdimDragonFly::DragonFly(const Driver &D, const llvm::Triple& Triple, const ArgList &Args) 2806234353Sdim : Generic_ELF(D, Triple, Args) { 2807193326Sed 2808193326Sed // Path mangling to find libexec 2809212904Sdim getProgramPaths().push_back(getDriver().getInstalledDir()); 2810221345Sdim if (getDriver().getInstalledDir() != getDriver().Dir) 2811212904Sdim getProgramPaths().push_back(getDriver().Dir); 2812193326Sed 2813201361Srdivacky getFilePaths().push_back(getDriver().Dir + "/../lib"); 2814193326Sed getFilePaths().push_back("/usr/lib"); 2815251662Sdim if (llvm::sys::fs::exists("/usr/lib/gcc47")) 2816251662Sdim getFilePaths().push_back("/usr/lib/gcc47"); 2817251662Sdim else 2818251662Sdim getFilePaths().push_back("/usr/lib/gcc44"); 2819193326Sed} 2820193326Sed 2821249423SdimTool *DragonFly::buildAssembler() const { 2822249423Sdim return new tools::dragonfly::Assemble(*this); 2823249423Sdim} 2824193326Sed 2825249423SdimTool *DragonFly::buildLinker() const { 2826249423Sdim return new tools::dragonfly::Link(*this); 2827193326Sed} 2828263508Sdim 2829263508Sdim 2830263508Sdim/// XCore tool chain 2831263508SdimXCore::XCore(const Driver &D, const llvm::Triple &Triple, 2832263508Sdim const ArgList &Args) : ToolChain(D, Triple, Args) { 2833263508Sdim // ProgramPaths are found via 'PATH' environment variable. 2834263508Sdim} 2835263508Sdim 2836263508SdimTool *XCore::buildAssembler() const { 2837263508Sdim return new tools::XCore::Assemble(*this); 2838263508Sdim} 2839263508Sdim 2840263508SdimTool *XCore::buildLinker() const { 2841263508Sdim return new tools::XCore::Link(*this); 2842263508Sdim} 2843263508Sdim 2844263508Sdimbool XCore::isPICDefault() const { 2845263508Sdim return false; 2846263508Sdim} 2847263508Sdim 2848263508Sdimbool XCore::isPIEDefault() const { 2849263508Sdim return false; 2850263508Sdim} 2851263508Sdim 2852263508Sdimbool XCore::isPICDefaultForced() const { 2853263508Sdim return false; 2854263508Sdim} 2855263508Sdim 2856263508Sdimbool XCore::SupportsProfiling() const { 2857263508Sdim return false; 2858263508Sdim} 2859263508Sdim 2860263508Sdimbool XCore::hasBlocksRuntime() const { 2861263508Sdim return false; 2862263508Sdim} 2863263508Sdim 2864263508Sdim 2865263508Sdimvoid XCore::AddClangSystemIncludeArgs(const ArgList &DriverArgs, 2866263508Sdim ArgStringList &CC1Args) const { 2867263508Sdim if (DriverArgs.hasArg(options::OPT_nostdinc) || 2868263508Sdim DriverArgs.hasArg(options::OPT_nostdlibinc)) 2869263508Sdim return; 2870263508Sdim if (const char *cl_include_dir = getenv("XCC_C_INCLUDE_PATH")) { 2871263508Sdim SmallVector<StringRef, 4> Dirs; 2872263508Sdim const char EnvPathSeparatorStr[] = {llvm::sys::EnvPathSeparator,'\0'}; 2873263508Sdim StringRef(cl_include_dir).split(Dirs, StringRef(EnvPathSeparatorStr)); 2874263508Sdim ArrayRef<StringRef> DirVec(Dirs); 2875263508Sdim addSystemIncludes(DriverArgs, CC1Args, DirVec); 2876263508Sdim } 2877263508Sdim} 2878263508Sdim 2879263508Sdimvoid XCore::addClangTargetOptions(const llvm::opt::ArgList &DriverArgs, 2880263508Sdim llvm::opt::ArgStringList &CC1Args) const { 2881263508Sdim CC1Args.push_back("-nostdsysteminc"); 2882263508Sdim} 2883263508Sdim 2884263508Sdimvoid XCore::AddClangCXXStdlibIncludeArgs(const ArgList &DriverArgs, 2885263508Sdim ArgStringList &CC1Args) const { 2886263508Sdim if (DriverArgs.hasArg(options::OPT_nostdinc) || 2887263508Sdim DriverArgs.hasArg(options::OPT_nostdlibinc)) 2888263508Sdim return; 2889263508Sdim if (const char *cl_include_dir = getenv("XCC_CPLUS_INCLUDE_PATH")) { 2890263508Sdim SmallVector<StringRef, 4> Dirs; 2891263508Sdim const char EnvPathSeparatorStr[] = {llvm::sys::EnvPathSeparator,'\0'}; 2892263508Sdim StringRef(cl_include_dir).split(Dirs, StringRef(EnvPathSeparatorStr)); 2893263508Sdim ArrayRef<StringRef> DirVec(Dirs); 2894263508Sdim addSystemIncludes(DriverArgs, CC1Args, DirVec); 2895263508Sdim } 2896263508Sdim} 2897263508Sdim 2898263508Sdimvoid XCore::AddCXXStdlibLibArgs(const ArgList &Args, 2899263508Sdim ArgStringList &CmdArgs) const { 2900263508Sdim // We don't output any lib args. This is handled by xcc. 2901263508Sdim} 2902