ToolChains.cpp revision 263763
1218893Sdim//===--- ToolChains.cpp - ToolChain Implementations -----------------------===// 2193326Sed// 3193326Sed// The LLVM Compiler Infrastructure 4193326Sed// 5193326Sed// This file is distributed under the University of Illinois Open Source 6193326Sed// License. See LICENSE.TXT for details. 7193326Sed// 8193326Sed//===----------------------------------------------------------------------===// 9193326Sed 10193326Sed#include "ToolChains.h" 11249423Sdim#include "clang/Basic/ObjCRuntime.h" 12249423Sdim#include "clang/Basic/Version.h" 13208600Srdivacky#include "clang/Driver/Compilation.h" 14193326Sed#include "clang/Driver/Driver.h" 15193326Sed#include "clang/Driver/DriverDiagnostic.h" 16199512Srdivacky#include "clang/Driver/Options.h" 17263508Sdim#include "clang/Driver/SanitizerArgs.h" 18249423Sdim#include "llvm/ADT/STLExtras.h" 19212904Sdim#include "llvm/ADT/SmallString.h" 20193326Sed#include "llvm/ADT/StringExtras.h" 21226633Sdim#include "llvm/ADT/StringSwitch.h" 22263508Sdim#include "llvm/Option/Arg.h" 23263508Sdim#include "llvm/Option/ArgList.h" 24263508Sdim#include "llvm/Option/OptTable.h" 25263508Sdim#include "llvm/Option/Option.h" 26198092Srdivacky#include "llvm/Support/ErrorHandling.h" 27218893Sdim#include "llvm/Support/FileSystem.h" 28218893Sdim#include "llvm/Support/MemoryBuffer.h" 29249423Sdim#include "llvm/Support/Path.h" 30193326Sed#include "llvm/Support/raw_ostream.h" 31218893Sdim#include "llvm/Support/system_error.h" 32263508Sdim#include "llvm/Support/Program.h" 33193326Sed 34249423Sdim// FIXME: This needs to be listed last until we fix the broken include guards 35249423Sdim// in these files and the LLVM config.h files. 36249423Sdim#include "clang/Config/config.h" // for GCC_INSTALL_PREFIX 37243830Sdim 38193326Sed#include <cstdlib> // ::getenv 39193326Sed 40193326Sedusing namespace clang::driver; 41193326Sedusing namespace clang::driver::toolchains; 42226633Sdimusing namespace clang; 43263508Sdimusing namespace llvm::opt; 44193326Sed 45198092Srdivacky/// Darwin - Darwin tool chain for i386 and x86_64. 46193326Sed 47249423SdimDarwin::Darwin(const Driver &D, const llvm::Triple& Triple, const ArgList &Args) 48249423Sdim : ToolChain(D, Triple, Args), TargetInitialized(false) 49198092Srdivacky{ 50234353Sdim // Compute the initial Darwin version from the triple 51234353Sdim unsigned Major, Minor, Micro; 52234353Sdim if (!Triple.getMacOSXVersion(Major, Minor, Micro)) 53234353Sdim getDriver().Diag(diag::err_drv_invalid_darwin_version) << 54234353Sdim Triple.getOSName(); 55234353Sdim llvm::raw_string_ostream(MacosxVersionMin) 56234353Sdim << Major << '.' << Minor << '.' << Micro; 57212904Sdim 58234353Sdim // FIXME: DarwinVersion is only used to find GCC's libexec directory. 59234353Sdim // It should be removed when we stop supporting that. 60234353Sdim DarwinVersion[0] = Minor + 4; 61234353Sdim DarwinVersion[1] = Micro; 62234353Sdim DarwinVersion[2] = 0; 63239462Sdim 64239462Sdim // Compute the initial iOS version from the triple 65239462Sdim Triple.getiOSVersion(Major, Minor, Micro); 66239462Sdim llvm::raw_string_ostream(iOSVersionMin) 67239462Sdim << Major << '.' << Minor << '.' << Micro; 68198092Srdivacky} 69198092Srdivacky 70212904Sdimtypes::ID Darwin::LookupTypeForExtension(const char *Ext) const { 71212904Sdim types::ID Ty = types::lookupTypeForExtension(Ext); 72212904Sdim 73212904Sdim // Darwin always preprocesses assembly files (unless -x is used explicitly). 74212904Sdim if (Ty == types::TY_PP_Asm) 75212904Sdim return types::TY_Asm; 76212904Sdim 77212904Sdim return Ty; 78212904Sdim} 79212904Sdim 80218893Sdimbool Darwin::HasNativeLLVMSupport() const { 81218893Sdim return true; 82218893Sdim} 83218893Sdim 84239462Sdim/// Darwin provides an ARC runtime starting in MacOS X 10.7 and iOS 5.0. 85239462SdimObjCRuntime Darwin::getDefaultObjCRuntime(bool isNonFragile) const { 86243830Sdim if (isTargetIPhoneOS()) 87239462Sdim return ObjCRuntime(ObjCRuntime::iOS, TargetVersion); 88243830Sdim if (isNonFragile) 89243830Sdim return ObjCRuntime(ObjCRuntime::MacOSX, TargetVersion); 90243830Sdim return ObjCRuntime(ObjCRuntime::FragileMacOSX, TargetVersion); 91224145Sdim} 92224145Sdim 93226633Sdim/// Darwin provides a blocks runtime starting in MacOS X 10.6 and iOS 3.2. 94226633Sdimbool Darwin::hasBlocksRuntime() const { 95226633Sdim if (isTargetIPhoneOS()) 96226633Sdim return !isIPhoneOSVersionLT(3, 2); 97226633Sdim else 98226633Sdim return !isMacosxVersionLT(10, 6); 99226633Sdim} 100202879Srdivacky 101226633Sdimstatic const char *GetArmArchForMArch(StringRef Value) { 102226633Sdim return llvm::StringSwitch<const char*>(Value) 103226633Sdim .Case("armv6k", "armv6") 104249423Sdim .Case("armv6m", "armv6m") 105226633Sdim .Case("armv5tej", "armv5") 106226633Sdim .Case("xscale", "xscale") 107226633Sdim .Case("armv4t", "armv4t") 108226633Sdim .Case("armv7", "armv7") 109226633Sdim .Cases("armv7a", "armv7-a", "armv7") 110226633Sdim .Cases("armv7r", "armv7-r", "armv7") 111249423Sdim .Cases("armv7em", "armv7e-m", "armv7em") 112243830Sdim .Cases("armv7f", "armv7-f", "armv7f") 113243830Sdim .Cases("armv7k", "armv7-k", "armv7k") 114249423Sdim .Cases("armv7m", "armv7-m", "armv7m") 115243830Sdim .Cases("armv7s", "armv7-s", "armv7s") 116226633Sdim .Default(0); 117202879Srdivacky} 118202879Srdivacky 119226633Sdimstatic const char *GetArmArchForMCpu(StringRef Value) { 120226633Sdim return llvm::StringSwitch<const char *>(Value) 121226633Sdim .Cases("arm9e", "arm946e-s", "arm966e-s", "arm968e-s", "arm926ej-s","armv5") 122226633Sdim .Cases("arm10e", "arm10tdmi", "armv5") 123226633Sdim .Cases("arm1020t", "arm1020e", "arm1022e", "arm1026ej-s", "armv5") 124226633Sdim .Case("xscale", "xscale") 125249423Sdim .Cases("arm1136j-s", "arm1136jf-s", "arm1176jz-s", "arm1176jzf-s", "armv6") 126249423Sdim .Case("cortex-m0", "armv6m") 127263508Sdim .Cases("cortex-a5", "cortex-a7", "cortex-a8", "armv7") 128263508Sdim .Cases("cortex-a9", "cortex-a12", "cortex-a15", "armv7") 129263508Sdim .Cases("cortex-r4", "cortex-r5", "armv7r") 130243830Sdim .Case("cortex-a9-mp", "armv7f") 131249423Sdim .Case("cortex-m3", "armv7m") 132249423Sdim .Case("cortex-m4", "armv7em") 133243830Sdim .Case("swift", "armv7s") 134226633Sdim .Default(0); 135202879Srdivacky} 136202879Srdivacky 137226633SdimStringRef Darwin::getDarwinArchName(const ArgList &Args) const { 138202879Srdivacky switch (getTriple().getArch()) { 139202879Srdivacky default: 140202879Srdivacky return getArchName(); 141223017Sdim 142221345Sdim case llvm::Triple::thumb: 143202879Srdivacky case llvm::Triple::arm: { 144202879Srdivacky if (const Arg *A = Args.getLastArg(options::OPT_march_EQ)) 145243830Sdim if (const char *Arch = GetArmArchForMArch(A->getValue())) 146202879Srdivacky return Arch; 147202879Srdivacky 148202879Srdivacky if (const Arg *A = Args.getLastArg(options::OPT_mcpu_EQ)) 149243830Sdim if (const char *Arch = GetArmArchForMCpu(A->getValue())) 150202879Srdivacky return Arch; 151202879Srdivacky 152202879Srdivacky return "arm"; 153202879Srdivacky } 154202879Srdivacky } 155202879Srdivacky} 156202879Srdivacky 157198092SrdivackyDarwin::~Darwin() { 158193326Sed} 159193326Sed 160226633Sdimstd::string Darwin::ComputeEffectiveClangTriple(const ArgList &Args, 161226633Sdim types::ID InputType) const { 162226633Sdim llvm::Triple Triple(ComputeLLVMTriple(Args, InputType)); 163212904Sdim 164212904Sdim // If the target isn't initialized (e.g., an unknown Darwin platform, return 165212904Sdim // the default triple). 166212904Sdim if (!isTargetInitialized()) 167212904Sdim return Triple.getTriple(); 168223017Sdim 169263508Sdim if (Triple.getArchName() == "thumbv6m" || 170263508Sdim Triple.getArchName() == "thumbv7m" || 171263508Sdim Triple.getArchName() == "thumbv7em") { 172263508Sdim // OS is ios or macosx unless it's the v6m or v7m. 173263508Sdim Triple.setOS(llvm::Triple::Darwin); 174263508Sdim Triple.setEnvironment(llvm::Triple::EABI); 175263508Sdim } else { 176263508Sdim SmallString<16> Str; 177263508Sdim Str += isTargetIPhoneOS() ? "ios" : "macosx"; 178263508Sdim Str += getTargetVersion().getAsString(); 179263508Sdim Triple.setOSName(Str); 180263508Sdim } 181223017Sdim 182212904Sdim return Triple.getTriple(); 183212904Sdim} 184212904Sdim 185234353Sdimvoid Generic_ELF::anchor() {} 186234353Sdim 187249423SdimTool *Darwin::getTool(Action::ActionClass AC) const { 188249423Sdim switch (AC) { 189249423Sdim case Action::LipoJobClass: 190249423Sdim if (!Lipo) 191249423Sdim Lipo.reset(new tools::darwin::Lipo(*this)); 192249423Sdim return Lipo.get(); 193249423Sdim case Action::DsymutilJobClass: 194249423Sdim if (!Dsymutil) 195249423Sdim Dsymutil.reset(new tools::darwin::Dsymutil(*this)); 196249423Sdim return Dsymutil.get(); 197249423Sdim case Action::VerifyJobClass: 198249423Sdim if (!VerifyDebug) 199249423Sdim VerifyDebug.reset(new tools::darwin::VerifyDebug(*this)); 200249423Sdim return VerifyDebug.get(); 201249423Sdim default: 202249423Sdim return ToolChain::getTool(AC); 203239462Sdim } 204249423Sdim} 205193326Sed 206249423SdimTool *Darwin::buildLinker() const { 207249423Sdim return new tools::darwin::Link(*this); 208249423Sdim} 209208600Srdivacky 210249423SdimTool *Darwin::buildAssembler() const { 211249423Sdim return new tools::darwin::Assemble(*this); 212193326Sed} 213193326Sed 214249423SdimDarwinClang::DarwinClang(const Driver &D, const llvm::Triple& Triple, 215249423Sdim const ArgList &Args) 216249423Sdim : Darwin(D, Triple, Args) 217198092Srdivacky{ 218218893Sdim getProgramPaths().push_back(getDriver().getInstalledDir()); 219218893Sdim if (getDriver().getInstalledDir() != getDriver().Dir) 220218893Sdim getProgramPaths().push_back(getDriver().Dir); 221218893Sdim 222198092Srdivacky // We expect 'as', 'ld', etc. to be adjacent to our install dir. 223212904Sdim getProgramPaths().push_back(getDriver().getInstalledDir()); 224212904Sdim if (getDriver().getInstalledDir() != getDriver().Dir) 225212904Sdim getProgramPaths().push_back(getDriver().Dir); 226226633Sdim} 227226633Sdim 228224145Sdimvoid DarwinClang::AddLinkARCArgs(const ArgList &Args, 229224145Sdim ArgStringList &CmdArgs) const { 230226633Sdim 231226633Sdim CmdArgs.push_back("-force_load"); 232263508Sdim SmallString<128> P(getDriver().ClangExecutable); 233263508Sdim llvm::sys::path::remove_filename(P); // 'clang' 234263508Sdim llvm::sys::path::remove_filename(P); // 'bin' 235263508Sdim llvm::sys::path::append(P, "lib", "arc", "libarclite_"); 236224145Sdim // Mash in the platform. 237234353Sdim if (isTargetIOSSimulator()) 238263508Sdim P += "iphonesimulator"; 239234353Sdim else if (isTargetIPhoneOS()) 240263508Sdim P += "iphoneos"; 241224145Sdim else 242263508Sdim P += "macosx"; 243263508Sdim P += ".a"; 244224145Sdim 245263508Sdim CmdArgs.push_back(Args.MakeArgString(P)); 246224145Sdim} 247224145Sdim 248224145Sdimvoid DarwinClang::AddLinkRuntimeLib(const ArgList &Args, 249226633Sdim ArgStringList &CmdArgs, 250249423Sdim const char *DarwinStaticLib, 251249423Sdim bool AlwaysLink) const { 252263508Sdim SmallString<128> P(getDriver().ResourceDir); 253263508Sdim llvm::sys::path::append(P, "lib", "darwin", DarwinStaticLib); 254226633Sdim 255224145Sdim // For now, allow missing resource libraries to support developers who may 256249423Sdim // not have compiler-rt checked out or integrated into their build (unless 257249423Sdim // we explicitly force linking with this library). 258263508Sdim if (AlwaysLink || llvm::sys::fs::exists(P.str())) 259224145Sdim CmdArgs.push_back(Args.MakeArgString(P.str())); 260224145Sdim} 261224145Sdim 262198092Srdivackyvoid DarwinClang::AddLinkRuntimeLibArgs(const ArgList &Args, 263198092Srdivacky ArgStringList &CmdArgs) const { 264234353Sdim // Darwin only supports the compiler-rt based runtime libraries. 265234353Sdim switch (GetRuntimeLibType(Args)) { 266234353Sdim case ToolChain::RLT_CompilerRT: 267234353Sdim break; 268234353Sdim default: 269234353Sdim getDriver().Diag(diag::err_drv_unsupported_rtlib_for_platform) 270243830Sdim << Args.getLastArg(options::OPT_rtlib_EQ)->getValue() << "darwin"; 271234353Sdim return; 272234353Sdim } 273234353Sdim 274202879Srdivacky // Darwin doesn't support real static executables, don't link any runtime 275202879Srdivacky // libraries with -static. 276243830Sdim if (Args.hasArg(options::OPT_static) || 277243830Sdim Args.hasArg(options::OPT_fapple_kext) || 278243830Sdim Args.hasArg(options::OPT_mkernel)) 279198092Srdivacky return; 280198092Srdivacky 281198092Srdivacky // Reject -static-libgcc for now, we can deal with this when and if someone 282198092Srdivacky // cares. This is useful in situations where someone wants to statically link 283198092Srdivacky // something like libstdc++, and needs its runtime support routines. 284198092Srdivacky if (const Arg *A = Args.getLastArg(options::OPT_static_libgcc)) { 285226633Sdim getDriver().Diag(diag::err_drv_unsupported_opt) 286198092Srdivacky << A->getAsString(Args); 287198092Srdivacky return; 288198092Srdivacky } 289198092Srdivacky 290234353Sdim // If we are building profile support, link that library in. 291234353Sdim if (Args.hasArg(options::OPT_fprofile_arcs) || 292234353Sdim Args.hasArg(options::OPT_fprofile_generate) || 293234353Sdim Args.hasArg(options::OPT_fcreate_profile) || 294234353Sdim Args.hasArg(options::OPT_coverage)) { 295234353Sdim // Select the appropriate runtime library for the target. 296234353Sdim if (isTargetIPhoneOS()) { 297234353Sdim AddLinkRuntimeLib(Args, CmdArgs, "libclang_rt.profile_ios.a"); 298234353Sdim } else { 299234353Sdim AddLinkRuntimeLib(Args, CmdArgs, "libclang_rt.profile_osx.a"); 300234353Sdim } 301234353Sdim } 302234353Sdim 303263508Sdim const SanitizerArgs &Sanitize = getSanitizerArgs(); 304243830Sdim 305249423Sdim // Add Ubsan runtime library, if required. 306249423Sdim if (Sanitize.needsUbsanRt()) { 307263508Sdim // FIXME: Move this check to SanitizerArgs::filterUnsupportedKinds. 308249423Sdim if (isTargetIPhoneOS()) { 309249423Sdim getDriver().Diag(diag::err_drv_clang_unsupported_per_platform) 310249423Sdim << "-fsanitize=undefined"; 311249423Sdim } else { 312249423Sdim AddLinkRuntimeLib(Args, CmdArgs, "libclang_rt.ubsan_osx.a", true); 313249423Sdim 314249423Sdim // The Ubsan runtime library requires C++. 315249423Sdim AddCXXStdlibLibArgs(Args, CmdArgs); 316249423Sdim } 317249423Sdim } 318249423Sdim 319234353Sdim // Add ASAN runtime library, if required. Dynamic libraries and bundles 320234353Sdim // should not be linked with the runtime library. 321243830Sdim if (Sanitize.needsAsanRt()) { 322263508Sdim // FIXME: Move this check to SanitizerArgs::filterUnsupportedKinds. 323249423Sdim if (isTargetIPhoneOS() && !isTargetIOSSimulator()) { 324234353Sdim getDriver().Diag(diag::err_drv_clang_unsupported_per_platform) 325243830Sdim << "-fsanitize=address"; 326234353Sdim } else { 327263508Sdim if (!Args.hasArg(options::OPT_dynamiclib) && 328263508Sdim !Args.hasArg(options::OPT_bundle)) { 329249423Sdim // The ASAN runtime library requires C++. 330249423Sdim AddCXXStdlibLibArgs(Args, CmdArgs); 331249423Sdim } 332263508Sdim if (isTargetMacOS()) { 333263508Sdim AddLinkRuntimeLib(Args, CmdArgs, 334263508Sdim "libclang_rt.asan_osx_dynamic.dylib", 335263508Sdim true); 336263508Sdim } else { 337263508Sdim if (isTargetIOSSimulator()) { 338263508Sdim AddLinkRuntimeLib(Args, CmdArgs, 339263508Sdim "libclang_rt.asan_iossim_dynamic.dylib", 340263508Sdim true); 341263508Sdim } 342263508Sdim } 343234353Sdim } 344234353Sdim } 345234353Sdim 346202879Srdivacky // Otherwise link libSystem, then the dynamic runtime library, and finally any 347202879Srdivacky // target specific static runtime library. 348198092Srdivacky CmdArgs.push_back("-lSystem"); 349202879Srdivacky 350202879Srdivacky // Select the dynamic runtime library and the target specific static library. 351203955Srdivacky if (isTargetIPhoneOS()) { 352221345Sdim // If we are compiling as iOS / simulator, don't attempt to link libgcc_s.1, 353221345Sdim // it never went into the SDK. 354226633Sdim // Linking against libgcc_s.1 isn't needed for iOS 5.0+ 355226633Sdim if (isIPhoneOSVersionLT(5, 0) && !isTargetIOSSimulator()) 356226633Sdim CmdArgs.push_back("-lgcc_s.1"); 357202879Srdivacky 358221345Sdim // We currently always need a static runtime library for iOS. 359224145Sdim AddLinkRuntimeLib(Args, CmdArgs, "libclang_rt.ios.a"); 360202879Srdivacky } else { 361202879Srdivacky // The dynamic runtime library was merged with libSystem for 10.6 and 362202879Srdivacky // beyond; only 10.4 and 10.5 need an additional runtime library. 363203955Srdivacky if (isMacosxVersionLT(10, 5)) 364202879Srdivacky CmdArgs.push_back("-lgcc_s.10.4"); 365203955Srdivacky else if (isMacosxVersionLT(10, 6)) 366202879Srdivacky CmdArgs.push_back("-lgcc_s.10.5"); 367202879Srdivacky 368218893Sdim // For OS X, we thought we would only need a static runtime library when 369221345Sdim // targeting 10.4, to provide versions of the static functions which were 370218893Sdim // omitted from 10.4.dylib. 371218893Sdim // 372218893Sdim // Unfortunately, that turned out to not be true, because Darwin system 373218893Sdim // headers can still use eprintf on i386, and it is not exported from 374218893Sdim // libSystem. Therefore, we still must provide a runtime library just for 375218893Sdim // the tiny tiny handful of projects that *might* use that symbol. 376218893Sdim if (isMacosxVersionLT(10, 5)) { 377224145Sdim AddLinkRuntimeLib(Args, CmdArgs, "libclang_rt.10.4.a"); 378218893Sdim } else { 379218893Sdim if (getTriple().getArch() == llvm::Triple::x86) 380224145Sdim AddLinkRuntimeLib(Args, CmdArgs, "libclang_rt.eprintf.a"); 381224145Sdim AddLinkRuntimeLib(Args, CmdArgs, "libclang_rt.osx.a"); 382218893Sdim } 383202879Srdivacky } 384224145Sdim} 385202879Srdivacky 386212904Sdimvoid Darwin::AddDeploymentTarget(DerivedArgList &Args) const { 387201361Srdivacky const OptTable &Opts = getDriver().getOpts(); 388193326Sed 389243830Sdim // Support allowing the SDKROOT environment variable used by xcrun and other 390243830Sdim // Xcode tools to define the default sysroot, by making it the default for 391243830Sdim // isysroot. 392249423Sdim if (const Arg *A = Args.getLastArg(options::OPT_isysroot)) { 393249423Sdim // Warn if the path does not exist. 394263508Sdim if (!llvm::sys::fs::exists(A->getValue())) 395249423Sdim getDriver().Diag(clang::diag::warn_missing_sysroot) << A->getValue(); 396249423Sdim } else { 397243830Sdim if (char *env = ::getenv("SDKROOT")) { 398249423Sdim // We only use this value as the default if it is an absolute path, 399249423Sdim // exists, and it is not the root path. 400249423Sdim if (llvm::sys::path::is_absolute(env) && llvm::sys::fs::exists(env) && 401249423Sdim StringRef(env) != "/") { 402243830Sdim Args.append(Args.MakeSeparateArg( 403243830Sdim 0, Opts.getOption(options::OPT_isysroot), env)); 404243830Sdim } 405243830Sdim } 406243830Sdim } 407243830Sdim 408203955Srdivacky Arg *OSXVersion = Args.getLastArg(options::OPT_mmacosx_version_min_EQ); 409221345Sdim Arg *iOSVersion = Args.getLastArg(options::OPT_miphoneos_version_min_EQ); 410221345Sdim Arg *iOSSimVersion = Args.getLastArg( 411221345Sdim options::OPT_mios_simulator_version_min_EQ); 412224145Sdim 413221345Sdim if (OSXVersion && (iOSVersion || iOSSimVersion)) { 414226633Sdim getDriver().Diag(diag::err_drv_argument_not_allowed_with) 415193326Sed << OSXVersion->getAsString(Args) 416221345Sdim << (iOSVersion ? iOSVersion : iOSSimVersion)->getAsString(Args); 417221345Sdim iOSVersion = iOSSimVersion = 0; 418221345Sdim } else if (iOSVersion && iOSSimVersion) { 419226633Sdim getDriver().Diag(diag::err_drv_argument_not_allowed_with) 420221345Sdim << iOSVersion->getAsString(Args) 421221345Sdim << iOSSimVersion->getAsString(Args); 422221345Sdim iOSSimVersion = 0; 423221345Sdim } else if (!OSXVersion && !iOSVersion && !iOSSimVersion) { 424226633Sdim // If no deployment target was specified on the command line, check for 425203955Srdivacky // environment defines. 426226633Sdim StringRef OSXTarget; 427226633Sdim StringRef iOSTarget; 428226633Sdim StringRef iOSSimTarget; 429226633Sdim if (char *env = ::getenv("MACOSX_DEPLOYMENT_TARGET")) 430226633Sdim OSXTarget = env; 431226633Sdim if (char *env = ::getenv("IPHONEOS_DEPLOYMENT_TARGET")) 432226633Sdim iOSTarget = env; 433226633Sdim if (char *env = ::getenv("IOS_SIMULATOR_DEPLOYMENT_TARGET")) 434226633Sdim iOSSimTarget = env; 435203955Srdivacky 436226633Sdim // If no '-miphoneos-version-min' specified on the command line and 437226633Sdim // IPHONEOS_DEPLOYMENT_TARGET is not defined, see if we can set the default 438234982Sdim // based on -isysroot. 439226633Sdim if (iOSTarget.empty()) { 440226633Sdim if (const Arg *A = Args.getLastArg(options::OPT_isysroot)) { 441226633Sdim StringRef first, second; 442243830Sdim StringRef isysroot = A->getValue(); 443226633Sdim llvm::tie(first, second) = isysroot.split(StringRef("SDKs/iPhoneOS")); 444226633Sdim if (second != "") 445226633Sdim iOSTarget = second.substr(0,3); 446226633Sdim } 447226633Sdim } 448203955Srdivacky 449226633Sdim // If no OSX or iOS target has been specified and we're compiling for armv7, 450226633Sdim // go ahead as assume we're targeting iOS. 451239462Sdim if (OSXTarget.empty() && iOSTarget.empty() && 452243830Sdim (getDarwinArchName(Args) == "armv7" || 453243830Sdim getDarwinArchName(Args) == "armv7s")) 454239462Sdim iOSTarget = iOSVersionMin; 455226633Sdim 456221345Sdim // Handle conflicting deployment targets 457193326Sed // 458203955Srdivacky // FIXME: Don't hardcode default here. 459221345Sdim 460221345Sdim // Do not allow conflicts with the iOS simulator target. 461226633Sdim if (!iOSSimTarget.empty() && (!OSXTarget.empty() || !iOSTarget.empty())) { 462226633Sdim getDriver().Diag(diag::err_drv_conflicting_deployment_targets) 463221345Sdim << "IOS_SIMULATOR_DEPLOYMENT_TARGET" 464226633Sdim << (!OSXTarget.empty() ? "MACOSX_DEPLOYMENT_TARGET" : 465221345Sdim "IPHONEOS_DEPLOYMENT_TARGET"); 466221345Sdim } 467221345Sdim 468221345Sdim // Allow conflicts among OSX and iOS for historical reasons, but choose the 469221345Sdim // default platform. 470226633Sdim if (!OSXTarget.empty() && !iOSTarget.empty()) { 471203955Srdivacky if (getTriple().getArch() == llvm::Triple::arm || 472203955Srdivacky getTriple().getArch() == llvm::Triple::thumb) 473226633Sdim OSXTarget = ""; 474203955Srdivacky else 475226633Sdim iOSTarget = ""; 476203955Srdivacky } 477193326Sed 478226633Sdim if (!OSXTarget.empty()) { 479243830Sdim const Option O = Opts.getOption(options::OPT_mmacosx_version_min_EQ); 480212904Sdim OSXVersion = Args.MakeJoinedArg(0, O, OSXTarget); 481212904Sdim Args.append(OSXVersion); 482226633Sdim } else if (!iOSTarget.empty()) { 483243830Sdim const Option O = Opts.getOption(options::OPT_miphoneos_version_min_EQ); 484221345Sdim iOSVersion = Args.MakeJoinedArg(0, O, iOSTarget); 485221345Sdim Args.append(iOSVersion); 486226633Sdim } else if (!iOSSimTarget.empty()) { 487243830Sdim const Option O = Opts.getOption( 488221345Sdim options::OPT_mios_simulator_version_min_EQ); 489221345Sdim iOSSimVersion = Args.MakeJoinedArg(0, O, iOSSimTarget); 490221345Sdim Args.append(iOSSimVersion); 491198092Srdivacky } else { 492210299Sed // Otherwise, assume we are targeting OS X. 493243830Sdim const Option O = Opts.getOption(options::OPT_mmacosx_version_min_EQ); 494212904Sdim OSXVersion = Args.MakeJoinedArg(0, O, MacosxVersionMin); 495212904Sdim Args.append(OSXVersion); 496198092Srdivacky } 497193326Sed } 498198092Srdivacky 499221345Sdim // Reject invalid architecture combinations. 500221345Sdim if (iOSSimVersion && (getTriple().getArch() != llvm::Triple::x86 && 501221345Sdim getTriple().getArch() != llvm::Triple::x86_64)) { 502226633Sdim getDriver().Diag(diag::err_drv_invalid_arch_for_deployment_target) 503221345Sdim << getTriple().getArchName() << iOSSimVersion->getAsString(Args); 504221345Sdim } 505221345Sdim 506203955Srdivacky // Set the tool chain target information. 507203955Srdivacky unsigned Major, Minor, Micro; 508203955Srdivacky bool HadExtra; 509203955Srdivacky if (OSXVersion) { 510221345Sdim assert((!iOSVersion && !iOSSimVersion) && "Unknown target platform!"); 511243830Sdim if (!Driver::GetReleaseVersion(OSXVersion->getValue(), Major, Minor, 512203955Srdivacky Micro, HadExtra) || HadExtra || 513221345Sdim Major != 10 || Minor >= 100 || Micro >= 100) 514226633Sdim getDriver().Diag(diag::err_drv_invalid_version_number) 515203955Srdivacky << OSXVersion->getAsString(Args); 516203955Srdivacky } else { 517221345Sdim const Arg *Version = iOSVersion ? iOSVersion : iOSSimVersion; 518221345Sdim assert(Version && "Unknown target platform!"); 519243830Sdim if (!Driver::GetReleaseVersion(Version->getValue(), Major, Minor, 520203955Srdivacky Micro, HadExtra) || HadExtra || 521203955Srdivacky Major >= 10 || Minor >= 100 || Micro >= 100) 522226633Sdim getDriver().Diag(diag::err_drv_invalid_version_number) 523221345Sdim << Version->getAsString(Args); 524203955Srdivacky } 525221345Sdim 526221345Sdim bool IsIOSSim = bool(iOSSimVersion); 527221345Sdim 528221345Sdim // In GCC, the simulator historically was treated as being OS X in some 529221345Sdim // contexts, like determining the link logic, despite generally being called 530221345Sdim // with an iOS deployment target. For compatibility, we detect the 531221345Sdim // simulator as iOS + x86, and treat it differently in a few contexts. 532221345Sdim if (iOSVersion && (getTriple().getArch() == llvm::Triple::x86 || 533221345Sdim getTriple().getArch() == llvm::Triple::x86_64)) 534221345Sdim IsIOSSim = true; 535221345Sdim 536221345Sdim setTarget(/*IsIPhoneOS=*/ !OSXVersion, Major, Minor, Micro, IsIOSSim); 537212904Sdim} 538203955Srdivacky 539218893Sdimvoid DarwinClang::AddCXXStdlibLibArgs(const ArgList &Args, 540218893Sdim ArgStringList &CmdArgs) const { 541218893Sdim CXXStdlibType Type = GetCXXStdlibType(Args); 542218893Sdim 543218893Sdim switch (Type) { 544218893Sdim case ToolChain::CST_Libcxx: 545218893Sdim CmdArgs.push_back("-lc++"); 546218893Sdim break; 547218893Sdim 548218893Sdim case ToolChain::CST_Libstdcxx: { 549218893Sdim // Unfortunately, -lstdc++ doesn't always exist in the standard search path; 550218893Sdim // it was previously found in the gcc lib dir. However, for all the Darwin 551218893Sdim // platforms we care about it was -lstdc++.6, so we search for that 552218893Sdim // explicitly if we can't see an obvious -lstdc++ candidate. 553218893Sdim 554218893Sdim // Check in the sysroot first. 555218893Sdim if (const Arg *A = Args.getLastArg(options::OPT_isysroot)) { 556263508Sdim SmallString<128> P(A->getValue()); 557263508Sdim llvm::sys::path::append(P, "usr", "lib", "libstdc++.dylib"); 558218893Sdim 559263508Sdim if (!llvm::sys::fs::exists(P.str())) { 560263508Sdim llvm::sys::path::remove_filename(P); 561263508Sdim llvm::sys::path::append(P, "libstdc++.6.dylib"); 562263508Sdim if (llvm::sys::fs::exists(P.str())) { 563218893Sdim CmdArgs.push_back(Args.MakeArgString(P.str())); 564218893Sdim return; 565218893Sdim } 566218893Sdim } 567218893Sdim } 568218893Sdim 569218893Sdim // Otherwise, look in the root. 570234353Sdim // FIXME: This should be removed someday when we don't have to care about 571234353Sdim // 10.6 and earlier, where /usr/lib/libstdc++.dylib does not exist. 572263508Sdim if (!llvm::sys::fs::exists("/usr/lib/libstdc++.dylib") && 573263508Sdim llvm::sys::fs::exists("/usr/lib/libstdc++.6.dylib")) { 574218893Sdim CmdArgs.push_back("/usr/lib/libstdc++.6.dylib"); 575218893Sdim return; 576218893Sdim } 577218893Sdim 578218893Sdim // Otherwise, let the linker search. 579218893Sdim CmdArgs.push_back("-lstdc++"); 580218893Sdim break; 581218893Sdim } 582218893Sdim } 583218893Sdim} 584218893Sdim 585218893Sdimvoid DarwinClang::AddCCKextLibArgs(const ArgList &Args, 586218893Sdim ArgStringList &CmdArgs) const { 587218893Sdim 588218893Sdim // For Darwin platforms, use the compiler-rt-based support library 589218893Sdim // instead of the gcc-provided one (which is also incidentally 590218893Sdim // only present in the gcc lib dir, which makes it hard to find). 591218893Sdim 592263508Sdim SmallString<128> P(getDriver().ResourceDir); 593263508Sdim llvm::sys::path::append(P, "lib", "darwin"); 594223017Sdim 595243830Sdim // Use the newer cc_kext for iOS ARM after 6.0. 596243830Sdim if (!isTargetIPhoneOS() || isTargetIOSSimulator() || 597243830Sdim !isIPhoneOSVersionLT(6, 0)) { 598263508Sdim llvm::sys::path::append(P, "libclang_rt.cc_kext.a"); 599243830Sdim } else { 600263508Sdim llvm::sys::path::append(P, "libclang_rt.cc_kext_ios5.a"); 601243830Sdim } 602243830Sdim 603218893Sdim // For now, allow missing resource libraries to support developers who may 604218893Sdim // not have compiler-rt checked out or integrated into their build. 605263508Sdim if (llvm::sys::fs::exists(P.str())) 606218893Sdim CmdArgs.push_back(Args.MakeArgString(P.str())); 607218893Sdim} 608218893Sdim 609212904SdimDerivedArgList *Darwin::TranslateArgs(const DerivedArgList &Args, 610212904Sdim const char *BoundArch) const { 611212904Sdim DerivedArgList *DAL = new DerivedArgList(Args.getBaseArgs()); 612212904Sdim const OptTable &Opts = getDriver().getOpts(); 613212904Sdim 614212904Sdim // FIXME: We really want to get out of the tool chain level argument 615212904Sdim // translation business, as it makes the driver functionality much 616212904Sdim // more opaque. For now, we follow gcc closely solely for the 617212904Sdim // purpose of easily achieving feature parity & testability. Once we 618212904Sdim // have something that works, we should reevaluate each translation 619212904Sdim // and try to push it down into tool specific logic. 620212904Sdim 621210299Sed for (ArgList::const_iterator it = Args.begin(), 622210299Sed ie = Args.end(); it != ie; ++it) { 623193326Sed Arg *A = *it; 624193326Sed 625193326Sed if (A->getOption().matches(options::OPT_Xarch__)) { 626224145Sdim // Skip this argument unless the architecture matches either the toolchain 627224145Sdim // triple arch, or the arch being bound. 628243830Sdim llvm::Triple::ArchType XarchArch = 629243830Sdim tools::darwin::getArchTypeForDarwinArchName(A->getValue(0)); 630243830Sdim if (!(XarchArch == getArch() || 631243830Sdim (BoundArch && XarchArch == 632243830Sdim tools::darwin::getArchTypeForDarwinArchName(BoundArch)))) 633193326Sed continue; 634193326Sed 635218893Sdim Arg *OriginalArg = A; 636243830Sdim unsigned Index = Args.getBaseArgs().MakeIndex(A->getValue(1)); 637210299Sed unsigned Prev = Index; 638193326Sed Arg *XarchArg = Opts.ParseOneArg(Args, Index); 639198092Srdivacky 640193326Sed // If the argument parsing failed or more than one argument was 641193326Sed // consumed, the -Xarch_ argument's parameter tried to consume 642193326Sed // extra arguments. Emit an error and ignore. 643193326Sed // 644193326Sed // We also want to disallow any options which would alter the 645193326Sed // driver behavior; that isn't going to work in our model. We 646193326Sed // use isDriverOption() as an approximation, although things 647193326Sed // like -O4 are going to slip through. 648221345Sdim if (!XarchArg || Index > Prev + 1) { 649226633Sdim getDriver().Diag(diag::err_drv_invalid_Xarch_argument_with_args) 650193326Sed << A->getAsString(Args); 651193326Sed continue; 652243830Sdim } else if (XarchArg->getOption().hasFlag(options::DriverOption)) { 653226633Sdim getDriver().Diag(diag::err_drv_invalid_Xarch_argument_isdriver) 654221345Sdim << A->getAsString(Args); 655221345Sdim continue; 656193326Sed } 657193326Sed 658193326Sed XarchArg->setBaseArg(A); 659193326Sed A = XarchArg; 660210299Sed 661210299Sed DAL->AddSynthesizedArg(A); 662218893Sdim 663218893Sdim // Linker input arguments require custom handling. The problem is that we 664218893Sdim // have already constructed the phase actions, so we can not treat them as 665218893Sdim // "input arguments". 666243830Sdim if (A->getOption().hasFlag(options::LinkerInput)) { 667218893Sdim // Convert the argument into individual Zlinker_input_args. 668218893Sdim for (unsigned i = 0, e = A->getNumValues(); i != e; ++i) { 669218893Sdim DAL->AddSeparateArg(OriginalArg, 670218893Sdim Opts.getOption(options::OPT_Zlinker_input), 671243830Sdim A->getValue(i)); 672223017Sdim 673218893Sdim } 674218893Sdim continue; 675218893Sdim } 676198092Srdivacky } 677193326Sed 678193326Sed // Sob. These is strictly gcc compatible for the time being. Apple 679193326Sed // gcc translates options twice, which means that self-expanding 680193326Sed // options add duplicates. 681199512Srdivacky switch ((options::ID) A->getOption().getID()) { 682193326Sed default: 683193326Sed DAL->append(A); 684193326Sed break; 685193326Sed 686193326Sed case options::OPT_mkernel: 687193326Sed case options::OPT_fapple_kext: 688193326Sed DAL->append(A); 689210299Sed DAL->AddFlagArg(A, Opts.getOption(options::OPT_static)); 690193326Sed break; 691198092Srdivacky 692193326Sed case options::OPT_dependency_file: 693210299Sed DAL->AddSeparateArg(A, Opts.getOption(options::OPT_MF), 694243830Sdim A->getValue()); 695193326Sed break; 696193326Sed 697193326Sed case options::OPT_gfull: 698210299Sed DAL->AddFlagArg(A, Opts.getOption(options::OPT_g_Flag)); 699210299Sed DAL->AddFlagArg(A, 700210299Sed Opts.getOption(options::OPT_fno_eliminate_unused_debug_symbols)); 701193326Sed break; 702193326Sed 703193326Sed case options::OPT_gused: 704210299Sed DAL->AddFlagArg(A, Opts.getOption(options::OPT_g_Flag)); 705210299Sed DAL->AddFlagArg(A, 706210299Sed Opts.getOption(options::OPT_feliminate_unused_debug_symbols)); 707193326Sed break; 708193326Sed 709193326Sed case options::OPT_shared: 710210299Sed DAL->AddFlagArg(A, Opts.getOption(options::OPT_dynamiclib)); 711193326Sed break; 712193326Sed 713193326Sed case options::OPT_fconstant_cfstrings: 714210299Sed DAL->AddFlagArg(A, Opts.getOption(options::OPT_mconstant_cfstrings)); 715193326Sed break; 716193326Sed 717193326Sed case options::OPT_fno_constant_cfstrings: 718210299Sed DAL->AddFlagArg(A, Opts.getOption(options::OPT_mno_constant_cfstrings)); 719193326Sed break; 720193326Sed 721193326Sed case options::OPT_Wnonportable_cfstrings: 722210299Sed DAL->AddFlagArg(A, 723210299Sed Opts.getOption(options::OPT_mwarn_nonportable_cfstrings)); 724193326Sed break; 725193326Sed 726193326Sed case options::OPT_Wno_nonportable_cfstrings: 727210299Sed DAL->AddFlagArg(A, 728210299Sed Opts.getOption(options::OPT_mno_warn_nonportable_cfstrings)); 729193326Sed break; 730193326Sed 731193326Sed case options::OPT_fpascal_strings: 732210299Sed DAL->AddFlagArg(A, Opts.getOption(options::OPT_mpascal_strings)); 733193326Sed break; 734193326Sed 735193326Sed case options::OPT_fno_pascal_strings: 736210299Sed DAL->AddFlagArg(A, Opts.getOption(options::OPT_mno_pascal_strings)); 737193326Sed break; 738193326Sed } 739193326Sed } 740193326Sed 741198092Srdivacky if (getTriple().getArch() == llvm::Triple::x86 || 742198092Srdivacky getTriple().getArch() == llvm::Triple::x86_64) 743199512Srdivacky if (!Args.hasArgNoClaim(options::OPT_mtune_EQ)) 744210299Sed DAL->AddJoinedArg(0, Opts.getOption(options::OPT_mtune_EQ), "core2"); 745198092Srdivacky 746198092Srdivacky // Add the arch options based on the particular spelling of -arch, to match 747198092Srdivacky // how the driver driver works. 748198092Srdivacky if (BoundArch) { 749226633Sdim StringRef Name = BoundArch; 750243830Sdim const Option MCpu = Opts.getOption(options::OPT_mcpu_EQ); 751243830Sdim const Option MArch = Opts.getOption(options::OPT_march_EQ); 752198092Srdivacky 753198092Srdivacky // This code must be kept in sync with LLVM's getArchTypeForDarwinArch, 754198092Srdivacky // which defines the list of which architectures we accept. 755198092Srdivacky if (Name == "ppc") 756198092Srdivacky ; 757198092Srdivacky else if (Name == "ppc601") 758210299Sed DAL->AddJoinedArg(0, MCpu, "601"); 759198092Srdivacky else if (Name == "ppc603") 760210299Sed DAL->AddJoinedArg(0, MCpu, "603"); 761198092Srdivacky else if (Name == "ppc604") 762210299Sed DAL->AddJoinedArg(0, MCpu, "604"); 763198092Srdivacky else if (Name == "ppc604e") 764210299Sed DAL->AddJoinedArg(0, MCpu, "604e"); 765198092Srdivacky else if (Name == "ppc750") 766210299Sed DAL->AddJoinedArg(0, MCpu, "750"); 767198092Srdivacky else if (Name == "ppc7400") 768210299Sed DAL->AddJoinedArg(0, MCpu, "7400"); 769198092Srdivacky else if (Name == "ppc7450") 770210299Sed DAL->AddJoinedArg(0, MCpu, "7450"); 771198092Srdivacky else if (Name == "ppc970") 772210299Sed DAL->AddJoinedArg(0, MCpu, "970"); 773198092Srdivacky 774263508Sdim else if (Name == "ppc64" || Name == "ppc64le") 775210299Sed DAL->AddFlagArg(0, Opts.getOption(options::OPT_m64)); 776193326Sed 777198092Srdivacky else if (Name == "i386") 778198092Srdivacky ; 779198092Srdivacky else if (Name == "i486") 780210299Sed DAL->AddJoinedArg(0, MArch, "i486"); 781198092Srdivacky else if (Name == "i586") 782210299Sed DAL->AddJoinedArg(0, MArch, "i586"); 783198092Srdivacky else if (Name == "i686") 784210299Sed DAL->AddJoinedArg(0, MArch, "i686"); 785198092Srdivacky else if (Name == "pentium") 786210299Sed DAL->AddJoinedArg(0, MArch, "pentium"); 787198092Srdivacky else if (Name == "pentium2") 788210299Sed DAL->AddJoinedArg(0, MArch, "pentium2"); 789198092Srdivacky else if (Name == "pentpro") 790210299Sed DAL->AddJoinedArg(0, MArch, "pentiumpro"); 791198092Srdivacky else if (Name == "pentIIm3") 792210299Sed DAL->AddJoinedArg(0, MArch, "pentium2"); 793193326Sed 794198092Srdivacky else if (Name == "x86_64") 795210299Sed DAL->AddFlagArg(0, Opts.getOption(options::OPT_m64)); 796263508Sdim else if (Name == "x86_64h") { 797263508Sdim DAL->AddFlagArg(0, Opts.getOption(options::OPT_m64)); 798263508Sdim DAL->AddJoinedArg(0, MArch, "x86_64h"); 799263508Sdim } 800198092Srdivacky 801198092Srdivacky else if (Name == "arm") 802210299Sed DAL->AddJoinedArg(0, MArch, "armv4t"); 803198092Srdivacky else if (Name == "armv4t") 804210299Sed DAL->AddJoinedArg(0, MArch, "armv4t"); 805198092Srdivacky else if (Name == "armv5") 806210299Sed DAL->AddJoinedArg(0, MArch, "armv5tej"); 807198092Srdivacky else if (Name == "xscale") 808210299Sed DAL->AddJoinedArg(0, MArch, "xscale"); 809198092Srdivacky else if (Name == "armv6") 810210299Sed DAL->AddJoinedArg(0, MArch, "armv6k"); 811249423Sdim else if (Name == "armv6m") 812249423Sdim DAL->AddJoinedArg(0, MArch, "armv6m"); 813198092Srdivacky else if (Name == "armv7") 814210299Sed DAL->AddJoinedArg(0, MArch, "armv7a"); 815249423Sdim else if (Name == "armv7em") 816249423Sdim DAL->AddJoinedArg(0, MArch, "armv7em"); 817243830Sdim else if (Name == "armv7f") 818243830Sdim DAL->AddJoinedArg(0, MArch, "armv7f"); 819243830Sdim else if (Name == "armv7k") 820243830Sdim DAL->AddJoinedArg(0, MArch, "armv7k"); 821249423Sdim else if (Name == "armv7m") 822249423Sdim DAL->AddJoinedArg(0, MArch, "armv7m"); 823243830Sdim else if (Name == "armv7s") 824243830Sdim DAL->AddJoinedArg(0, MArch, "armv7s"); 825198092Srdivacky 826198092Srdivacky else 827200583Srdivacky llvm_unreachable("invalid Darwin arch"); 828198092Srdivacky } 829198092Srdivacky 830212904Sdim // Add an explicit version min argument for the deployment target. We do this 831212904Sdim // after argument translation because -Xarch_ arguments may add a version min 832212904Sdim // argument. 833239462Sdim if (BoundArch) 834239462Sdim AddDeploymentTarget(*DAL); 835212904Sdim 836243830Sdim // For iOS 6, undo the translation to add -static for -mkernel/-fapple-kext. 837243830Sdim // FIXME: It would be far better to avoid inserting those -static arguments, 838243830Sdim // but we can't check the deployment target in the translation code until 839243830Sdim // it is set here. 840243830Sdim if (isTargetIPhoneOS() && !isIPhoneOSVersionLT(6, 0)) { 841243830Sdim for (ArgList::iterator it = DAL->begin(), ie = DAL->end(); it != ie; ) { 842243830Sdim Arg *A = *it; 843243830Sdim ++it; 844243830Sdim if (A->getOption().getID() != options::OPT_mkernel && 845243830Sdim A->getOption().getID() != options::OPT_fapple_kext) 846243830Sdim continue; 847243830Sdim assert(it != ie && "unexpected argument translation"); 848243830Sdim A = *it; 849243830Sdim assert(A->getOption().getID() == options::OPT_static && 850243830Sdim "missing expected -static argument"); 851243830Sdim it = DAL->getArgs().erase(it); 852243830Sdim } 853243830Sdim } 854243830Sdim 855263508Sdim // Default to use libc++ on OS X 10.9+ and iOS 7+. 856263508Sdim if (((isTargetMacOS() && !isMacosxVersionLT(10, 9)) || 857263508Sdim (isTargetIPhoneOS() && !isIPhoneOSVersionLT(7, 0))) && 858263508Sdim !Args.getLastArg(options::OPT_stdlib_EQ)) 859263508Sdim DAL->AddJoinedArg(0, Opts.getOption(options::OPT_stdlib_EQ), "libc++"); 860263508Sdim 861226633Sdim // Validate the C++ standard library choice. 862226633Sdim CXXStdlibType Type = GetCXXStdlibType(*DAL); 863226633Sdim if (Type == ToolChain::CST_Libcxx) { 864239462Sdim // Check whether the target provides libc++. 865239462Sdim StringRef where; 866239462Sdim 867239462Sdim // Complain about targetting iOS < 5.0 in any way. 868243830Sdim if (isTargetIPhoneOS() && isIPhoneOSVersionLT(5, 0)) 869243830Sdim where = "iOS 5.0"; 870239462Sdim 871239462Sdim if (where != StringRef()) { 872226633Sdim getDriver().Diag(clang::diag::err_drv_invalid_libcxx_deployment) 873239462Sdim << where; 874226633Sdim } 875226633Sdim } 876226633Sdim 877193326Sed return DAL; 878198092Srdivacky} 879193326Sed 880198092Srdivackybool Darwin::IsUnwindTablesDefault() const { 881243830Sdim return getArch() == llvm::Triple::x86_64; 882193326Sed} 883193326Sed 884201361Srdivackybool Darwin::UseDwarfDebugFlags() const { 885201361Srdivacky if (const char *S = ::getenv("RC_DEBUG_OPTIONS")) 886201361Srdivacky return S[0] != '\0'; 887201361Srdivacky return false; 888201361Srdivacky} 889201361Srdivacky 890203955Srdivackybool Darwin::UseSjLjExceptions() const { 891203955Srdivacky // Darwin uses SjLj exceptions on ARM. 892203955Srdivacky return (getTriple().getArch() == llvm::Triple::arm || 893203955Srdivacky getTriple().getArch() == llvm::Triple::thumb); 894203955Srdivacky} 895203955Srdivacky 896243830Sdimbool Darwin::isPICDefault() const { 897243830Sdim return true; 898193326Sed} 899193326Sed 900251662Sdimbool Darwin::isPIEDefault() const { 901251662Sdim return false; 902251662Sdim} 903251662Sdim 904243830Sdimbool Darwin::isPICDefaultForced() const { 905243830Sdim return getArch() == llvm::Triple::x86_64; 906193326Sed} 907193326Sed 908221345Sdimbool Darwin::SupportsProfiling() const { 909221345Sdim // Profiling instrumentation is only supported on x86. 910243830Sdim return getArch() == llvm::Triple::x86 || getArch() == llvm::Triple::x86_64; 911221345Sdim} 912221345Sdim 913207619Srdivackybool Darwin::SupportsObjCGC() const { 914207619Srdivacky // Garbage collection is supported everywhere except on iPhone OS. 915207619Srdivacky return !isTargetIPhoneOS(); 916207619Srdivacky} 917207619Srdivacky 918243830Sdimvoid Darwin::CheckObjCARC() const { 919243830Sdim if (isTargetIPhoneOS() || !isMacosxVersionLT(10, 6)) 920243830Sdim return; 921243830Sdim getDriver().Diag(diag::err_arc_unsupported_on_toolchain); 922234353Sdim} 923234353Sdim 924212904Sdimstd::string 925226633SdimDarwin_Generic_GCC::ComputeEffectiveClangTriple(const ArgList &Args, 926226633Sdim types::ID InputType) const { 927226633Sdim return ComputeLLVMTriple(Args, InputType); 928212904Sdim} 929212904Sdim 930193326Sed/// Generic_GCC - A tool chain using the 'gcc' command to perform 931193326Sed/// all subcommands; this relies on gcc translating the majority of 932193326Sed/// command line options. 933193326Sed 934234353Sdim/// \brief Parse a GCCVersion object out of a string of text. 935234353Sdim/// 936234353Sdim/// This is the primary means of forming GCCVersion objects. 937234353Sdim/*static*/ 938234353SdimGeneric_GCC::GCCVersion Linux::GCCVersion::Parse(StringRef VersionText) { 939263508Sdim const GCCVersion BadVersion = { VersionText.str(), -1, -1, -1, "", "", "" }; 940234353Sdim std::pair<StringRef, StringRef> First = VersionText.split('.'); 941234353Sdim std::pair<StringRef, StringRef> Second = First.second.split('.'); 942234353Sdim 943263508Sdim GCCVersion GoodVersion = { VersionText.str(), -1, -1, -1, "", "", "" }; 944234353Sdim if (First.first.getAsInteger(10, GoodVersion.Major) || 945234353Sdim GoodVersion.Major < 0) 946234353Sdim return BadVersion; 947263508Sdim GoodVersion.MajorStr = First.first.str(); 948234353Sdim if (Second.first.getAsInteger(10, GoodVersion.Minor) || 949234353Sdim GoodVersion.Minor < 0) 950234353Sdim return BadVersion; 951263508Sdim GoodVersion.MinorStr = Second.first.str(); 952234353Sdim 953234353Sdim // First look for a number prefix and parse that if present. Otherwise just 954234353Sdim // stash the entire patch string in the suffix, and leave the number 955234353Sdim // unspecified. This covers versions strings such as: 956234353Sdim // 4.4 957234353Sdim // 4.4.0 958234353Sdim // 4.4.x 959234353Sdim // 4.4.2-rc4 960234353Sdim // 4.4.x-patched 961234353Sdim // And retains any patch number it finds. 962234353Sdim StringRef PatchText = GoodVersion.PatchSuffix = Second.second.str(); 963234353Sdim if (!PatchText.empty()) { 964249423Sdim if (size_t EndNumber = PatchText.find_first_not_of("0123456789")) { 965234353Sdim // Try to parse the number and any suffix. 966234353Sdim if (PatchText.slice(0, EndNumber).getAsInteger(10, GoodVersion.Patch) || 967234353Sdim GoodVersion.Patch < 0) 968234353Sdim return BadVersion; 969263508Sdim GoodVersion.PatchSuffix = PatchText.substr(EndNumber); 970234353Sdim } 971234353Sdim } 972234353Sdim 973234353Sdim return GoodVersion; 974234353Sdim} 975234353Sdim 976234353Sdim/// \brief Less-than for GCCVersion, implementing a Strict Weak Ordering. 977263508Sdimbool Generic_GCC::GCCVersion::isOlderThan(int RHSMajor, int RHSMinor, 978263508Sdim int RHSPatch, 979263508Sdim StringRef RHSPatchSuffix) const { 980263508Sdim if (Major != RHSMajor) 981263508Sdim return Major < RHSMajor; 982263508Sdim if (Minor != RHSMinor) 983263508Sdim return Minor < RHSMinor; 984263508Sdim if (Patch != RHSPatch) { 985249423Sdim // Note that versions without a specified patch sort higher than those with 986249423Sdim // a patch. 987263508Sdim if (RHSPatch == -1) 988249423Sdim return true; 989249423Sdim if (Patch == -1) 990249423Sdim return false; 991234353Sdim 992249423Sdim // Otherwise just sort on the patch itself. 993263508Sdim return Patch < RHSPatch; 994249423Sdim } 995263508Sdim if (PatchSuffix != RHSPatchSuffix) { 996249423Sdim // Sort empty suffixes higher. 997263508Sdim if (RHSPatchSuffix.empty()) 998249423Sdim return true; 999249423Sdim if (PatchSuffix.empty()) 1000249423Sdim return false; 1001234353Sdim 1002249423Sdim // Provide a lexicographic sort to make this a total ordering. 1003263508Sdim return PatchSuffix < RHSPatchSuffix; 1004249423Sdim } 1005249423Sdim 1006249423Sdim // The versions are equal. 1007234353Sdim return false; 1008234353Sdim} 1009234353Sdim 1010234353Sdimstatic StringRef getGCCToolchainDir(const ArgList &Args) { 1011234353Sdim const Arg *A = Args.getLastArg(options::OPT_gcc_toolchain); 1012234353Sdim if (A) 1013243830Sdim return A->getValue(); 1014234353Sdim return GCC_INSTALL_PREFIX; 1015234353Sdim} 1016234353Sdim 1017259157Sdim/// \brief Initialize a GCCInstallationDetector from the driver. 1018234353Sdim/// 1019234353Sdim/// This performs all of the autodetection and sets up the various paths. 1020234982Sdim/// Once constructed, a GCCInstallationDetector is essentially immutable. 1021234353Sdim/// 1022234353Sdim/// FIXME: We shouldn't need an explicit TargetTriple parameter here, and 1023234353Sdim/// should instead pull the target out of the driver. This is currently 1024234353Sdim/// necessary because the driver doesn't store the final version of the target 1025234353Sdim/// triple. 1026259157Sdimvoid 1027259157SdimGeneric_GCC::GCCInstallationDetector::init( 1028263508Sdim const llvm::Triple &TargetTriple, const ArgList &Args) { 1029263508Sdim llvm::Triple BiarchVariantTriple = 1030263508Sdim TargetTriple.isArch32Bit() ? TargetTriple.get64BitArchVariant() 1031234353Sdim : TargetTriple.get32BitArchVariant(); 1032234353Sdim llvm::Triple::ArchType TargetArch = TargetTriple.getArch(); 1033234353Sdim // The library directories which may contain GCC installations. 1034263508Sdim SmallVector<StringRef, 4> CandidateLibDirs, CandidateBiarchLibDirs; 1035234353Sdim // The compatible GCC triples for this particular architecture. 1036234353Sdim SmallVector<StringRef, 10> CandidateTripleAliases; 1037263508Sdim SmallVector<StringRef, 10> CandidateBiarchTripleAliases; 1038263508Sdim CollectLibDirsAndTriples(TargetTriple, BiarchVariantTriple, CandidateLibDirs, 1039263508Sdim CandidateTripleAliases, CandidateBiarchLibDirs, 1040263508Sdim CandidateBiarchTripleAliases); 1041234353Sdim 1042234353Sdim // Compute the set of prefixes for our search. 1043234353Sdim SmallVector<std::string, 8> Prefixes(D.PrefixDirs.begin(), 1044234353Sdim D.PrefixDirs.end()); 1045234353Sdim 1046234353Sdim StringRef GCCToolchainDir = getGCCToolchainDir(Args); 1047234353Sdim if (GCCToolchainDir != "") { 1048234353Sdim if (GCCToolchainDir.back() == '/') 1049234353Sdim GCCToolchainDir = GCCToolchainDir.drop_back(); // remove the / 1050234353Sdim 1051234353Sdim Prefixes.push_back(GCCToolchainDir); 1052234353Sdim } else { 1053263508Sdim // If we have a SysRoot, try that first. 1054263508Sdim if (!D.SysRoot.empty()) { 1055263508Sdim Prefixes.push_back(D.SysRoot); 1056263508Sdim Prefixes.push_back(D.SysRoot + "/usr"); 1057263508Sdim } 1058263508Sdim 1059263508Sdim // Then look for gcc installed alongside clang. 1060234353Sdim Prefixes.push_back(D.InstalledDir + "/.."); 1061263508Sdim 1062263508Sdim // And finally in /usr. 1063263508Sdim if (D.SysRoot.empty()) 1064263508Sdim Prefixes.push_back("/usr"); 1065234353Sdim } 1066234353Sdim 1067234353Sdim // Loop over the various components which exist and select the best GCC 1068234353Sdim // installation available. GCC installs are ranked by version number. 1069234353Sdim Version = GCCVersion::Parse("0.0.0"); 1070234353Sdim for (unsigned i = 0, ie = Prefixes.size(); i < ie; ++i) { 1071234353Sdim if (!llvm::sys::fs::exists(Prefixes[i])) 1072234353Sdim continue; 1073234353Sdim for (unsigned j = 0, je = CandidateLibDirs.size(); j < je; ++j) { 1074234353Sdim const std::string LibDir = Prefixes[i] + CandidateLibDirs[j].str(); 1075234353Sdim if (!llvm::sys::fs::exists(LibDir)) 1076234353Sdim continue; 1077234353Sdim for (unsigned k = 0, ke = CandidateTripleAliases.size(); k < ke; ++k) 1078243830Sdim ScanLibDirForGCCTriple(TargetArch, Args, LibDir, 1079243830Sdim CandidateTripleAliases[k]); 1080234353Sdim } 1081263508Sdim for (unsigned j = 0, je = CandidateBiarchLibDirs.size(); j < je; ++j) { 1082263508Sdim const std::string LibDir = Prefixes[i] + CandidateBiarchLibDirs[j].str(); 1083234353Sdim if (!llvm::sys::fs::exists(LibDir)) 1084234353Sdim continue; 1085263508Sdim for (unsigned k = 0, ke = CandidateBiarchTripleAliases.size(); k < ke; 1086234353Sdim ++k) 1087243830Sdim ScanLibDirForGCCTriple(TargetArch, Args, LibDir, 1088263508Sdim CandidateBiarchTripleAliases[k], 1089263508Sdim /*NeedsBiarchSuffix=*/ true); 1090234353Sdim } 1091234353Sdim } 1092234353Sdim} 1093234353Sdim 1094263508Sdimvoid Generic_GCC::GCCInstallationDetector::print(raw_ostream &OS) const { 1095263508Sdim for (std::set<std::string>::const_iterator 1096263508Sdim I = CandidateGCCInstallPaths.begin(), 1097263508Sdim E = CandidateGCCInstallPaths.end(); 1098263508Sdim I != E; ++I) 1099263508Sdim OS << "Found candidate GCC installation: " << *I << "\n"; 1100263508Sdim 1101263508Sdim OS << "Selected GCC installation: " << GCCInstallPath << "\n"; 1102263508Sdim} 1103263508Sdim 1104234353Sdim/*static*/ void Generic_GCC::GCCInstallationDetector::CollectLibDirsAndTriples( 1105263508Sdim const llvm::Triple &TargetTriple, const llvm::Triple &BiarchTriple, 1106234353Sdim SmallVectorImpl<StringRef> &LibDirs, 1107234353Sdim SmallVectorImpl<StringRef> &TripleAliases, 1108263508Sdim SmallVectorImpl<StringRef> &BiarchLibDirs, 1109263508Sdim SmallVectorImpl<StringRef> &BiarchTripleAliases) { 1110234353Sdim // Declare a bunch of static data sets that we'll select between below. These 1111234353Sdim // are specifically designed to always refer to string literals to avoid any 1112234353Sdim // lifetime or initialization issues. 1113249423Sdim static const char *const AArch64LibDirs[] = { "/lib" }; 1114263508Sdim static const char *const AArch64Triples[] = { "aarch64-none-linux-gnu", 1115263508Sdim "aarch64-linux-gnu" }; 1116249423Sdim 1117234353Sdim static const char *const ARMLibDirs[] = { "/lib" }; 1118263508Sdim static const char *const ARMTriples[] = { "arm-linux-gnueabi", 1119263508Sdim "arm-linux-androideabi" }; 1120263508Sdim static const char *const ARMHFTriples[] = { "arm-linux-gnueabihf", 1121263508Sdim "armv7hl-redhat-linux-gnueabi" }; 1122234353Sdim 1123234353Sdim static const char *const X86_64LibDirs[] = { "/lib64", "/lib" }; 1124234353Sdim static const char *const X86_64Triples[] = { 1125263508Sdim "x86_64-linux-gnu", "x86_64-unknown-linux-gnu", "x86_64-pc-linux-gnu", 1126263508Sdim "x86_64-redhat-linux6E", "x86_64-redhat-linux", "x86_64-suse-linux", 1127263508Sdim "x86_64-manbo-linux-gnu", "x86_64-linux-gnu", "x86_64-slackware-linux" 1128234353Sdim }; 1129234353Sdim static const char *const X86LibDirs[] = { "/lib32", "/lib" }; 1130234353Sdim static const char *const X86Triples[] = { 1131263508Sdim "i686-linux-gnu", "i686-pc-linux-gnu", "i486-linux-gnu", "i386-linux-gnu", 1132263508Sdim "i386-redhat-linux6E", "i686-redhat-linux", "i586-redhat-linux", 1133263508Sdim "i386-redhat-linux", "i586-suse-linux", "i486-slackware-linux", 1134239462Sdim "i686-montavista-linux" 1135234353Sdim }; 1136234353Sdim 1137234353Sdim static const char *const MIPSLibDirs[] = { "/lib" }; 1138263508Sdim static const char *const MIPSTriples[] = { "mips-linux-gnu", 1139263508Sdim "mips-mti-linux-gnu" }; 1140234353Sdim static const char *const MIPSELLibDirs[] = { "/lib" }; 1141263508Sdim static const char *const MIPSELTriples[] = { "mipsel-linux-gnu", 1142263508Sdim "mipsel-linux-android" }; 1143234353Sdim 1144239462Sdim static const char *const MIPS64LibDirs[] = { "/lib64", "/lib" }; 1145263508Sdim static const char *const MIPS64Triples[] = { "mips64-linux-gnu", 1146263508Sdim "mips-mti-linux-gnu" }; 1147239462Sdim static const char *const MIPS64ELLibDirs[] = { "/lib64", "/lib" }; 1148263508Sdim static const char *const MIPS64ELTriples[] = { "mips64el-linux-gnu", 1149263508Sdim "mips-mti-linux-gnu" }; 1150239462Sdim 1151234353Sdim static const char *const PPCLibDirs[] = { "/lib32", "/lib" }; 1152234353Sdim static const char *const PPCTriples[] = { 1153263508Sdim "powerpc-linux-gnu", "powerpc-unknown-linux-gnu", "powerpc-linux-gnuspe", 1154263508Sdim "powerpc-suse-linux", "powerpc-montavista-linuxspe" 1155234353Sdim }; 1156234353Sdim static const char *const PPC64LibDirs[] = { "/lib64", "/lib" }; 1157263508Sdim static const char *const PPC64Triples[] = { "powerpc64-linux-gnu", 1158263508Sdim "powerpc64-unknown-linux-gnu", 1159263508Sdim "powerpc64-suse-linux", 1160263508Sdim "ppc64-redhat-linux" }; 1161263508Sdim static const char *const PPC64LELibDirs[] = { "/lib64", "/lib" }; 1162263508Sdim static const char *const PPC64LETriples[] = { "powerpc64le-linux-gnu", 1163263508Sdim "powerpc64le-unknown-linux-gnu", 1164263508Sdim "powerpc64le-suse-linux", 1165263508Sdim "ppc64le-redhat-linux" }; 1166234353Sdim 1167263763Sdim static const char *const SPARCv8LibDirs[] = { "/lib32", "/lib" }; 1168263763Sdim static const char *const SPARCv8Triples[] = { "sparc-linux-gnu", 1169263763Sdim "sparcv8-linux-gnu" }; 1170263763Sdim static const char *const SPARCv9LibDirs[] = { "/lib64", "/lib" }; 1171263763Sdim static const char *const SPARCv9Triples[] = { "sparc64-linux-gnu", 1172263763Sdim "sparcv9-linux-gnu" }; 1173263763Sdim 1174251662Sdim static const char *const SystemZLibDirs[] = { "/lib64", "/lib" }; 1175251662Sdim static const char *const SystemZTriples[] = { 1176263508Sdim "s390x-linux-gnu", "s390x-unknown-linux-gnu", "s390x-ibm-linux-gnu", 1177263508Sdim "s390x-suse-linux", "s390x-redhat-linux" 1178251662Sdim }; 1179251662Sdim 1180234353Sdim switch (TargetTriple.getArch()) { 1181249423Sdim case llvm::Triple::aarch64: 1182263508Sdim LibDirs.append(AArch64LibDirs, 1183263508Sdim AArch64LibDirs + llvm::array_lengthof(AArch64LibDirs)); 1184263508Sdim TripleAliases.append(AArch64Triples, 1185263508Sdim AArch64Triples + llvm::array_lengthof(AArch64Triples)); 1186263508Sdim BiarchLibDirs.append(AArch64LibDirs, 1187263508Sdim AArch64LibDirs + llvm::array_lengthof(AArch64LibDirs)); 1188263508Sdim BiarchTripleAliases.append( 1189263508Sdim AArch64Triples, AArch64Triples + llvm::array_lengthof(AArch64Triples)); 1190249423Sdim break; 1191234353Sdim case llvm::Triple::arm: 1192234353Sdim case llvm::Triple::thumb: 1193234353Sdim LibDirs.append(ARMLibDirs, ARMLibDirs + llvm::array_lengthof(ARMLibDirs)); 1194239462Sdim if (TargetTriple.getEnvironment() == llvm::Triple::GNUEABIHF) { 1195263508Sdim TripleAliases.append(ARMHFTriples, 1196263508Sdim ARMHFTriples + llvm::array_lengthof(ARMHFTriples)); 1197239462Sdim } else { 1198263508Sdim TripleAliases.append(ARMTriples, 1199263508Sdim ARMTriples + llvm::array_lengthof(ARMTriples)); 1200239462Sdim } 1201234353Sdim break; 1202234353Sdim case llvm::Triple::x86_64: 1203263508Sdim LibDirs.append(X86_64LibDirs, 1204263508Sdim X86_64LibDirs + llvm::array_lengthof(X86_64LibDirs)); 1205263508Sdim TripleAliases.append(X86_64Triples, 1206263508Sdim X86_64Triples + llvm::array_lengthof(X86_64Triples)); 1207263508Sdim BiarchLibDirs.append(X86LibDirs, 1208263508Sdim X86LibDirs + llvm::array_lengthof(X86LibDirs)); 1209263508Sdim BiarchTripleAliases.append(X86Triples, 1210263508Sdim X86Triples + llvm::array_lengthof(X86Triples)); 1211234353Sdim break; 1212234353Sdim case llvm::Triple::x86: 1213234353Sdim LibDirs.append(X86LibDirs, X86LibDirs + llvm::array_lengthof(X86LibDirs)); 1214263508Sdim TripleAliases.append(X86Triples, 1215263508Sdim X86Triples + llvm::array_lengthof(X86Triples)); 1216263508Sdim BiarchLibDirs.append(X86_64LibDirs, 1217263508Sdim X86_64LibDirs + llvm::array_lengthof(X86_64LibDirs)); 1218263508Sdim BiarchTripleAliases.append( 1219263508Sdim X86_64Triples, X86_64Triples + llvm::array_lengthof(X86_64Triples)); 1220234353Sdim break; 1221234353Sdim case llvm::Triple::mips: 1222263508Sdim LibDirs.append(MIPSLibDirs, 1223263508Sdim MIPSLibDirs + llvm::array_lengthof(MIPSLibDirs)); 1224263508Sdim TripleAliases.append(MIPSTriples, 1225263508Sdim MIPSTriples + llvm::array_lengthof(MIPSTriples)); 1226263508Sdim BiarchLibDirs.append(MIPS64LibDirs, 1227263508Sdim MIPS64LibDirs + llvm::array_lengthof(MIPS64LibDirs)); 1228263508Sdim BiarchTripleAliases.append( 1229263508Sdim MIPS64Triples, MIPS64Triples + llvm::array_lengthof(MIPS64Triples)); 1230234353Sdim break; 1231234353Sdim case llvm::Triple::mipsel: 1232263508Sdim LibDirs.append(MIPSELLibDirs, 1233263508Sdim MIPSELLibDirs + llvm::array_lengthof(MIPSELLibDirs)); 1234263508Sdim TripleAliases.append(MIPSELTriples, 1235263508Sdim MIPSELTriples + llvm::array_lengthof(MIPSELTriples)); 1236263508Sdim TripleAliases.append(MIPSTriples, 1237263508Sdim MIPSTriples + llvm::array_lengthof(MIPSTriples)); 1238263508Sdim BiarchLibDirs.append( 1239263508Sdim MIPS64ELLibDirs, 1240263508Sdim MIPS64ELLibDirs + llvm::array_lengthof(MIPS64ELLibDirs)); 1241263508Sdim BiarchTripleAliases.append( 1242263508Sdim MIPS64ELTriples, 1243263508Sdim MIPS64ELTriples + llvm::array_lengthof(MIPS64ELTriples)); 1244234353Sdim break; 1245239462Sdim case llvm::Triple::mips64: 1246263508Sdim LibDirs.append(MIPS64LibDirs, 1247263508Sdim MIPS64LibDirs + llvm::array_lengthof(MIPS64LibDirs)); 1248263508Sdim TripleAliases.append(MIPS64Triples, 1249263508Sdim MIPS64Triples + llvm::array_lengthof(MIPS64Triples)); 1250263508Sdim BiarchLibDirs.append(MIPSLibDirs, 1251263508Sdim MIPSLibDirs + llvm::array_lengthof(MIPSLibDirs)); 1252263508Sdim BiarchTripleAliases.append(MIPSTriples, 1253263508Sdim MIPSTriples + llvm::array_lengthof(MIPSTriples)); 1254239462Sdim break; 1255239462Sdim case llvm::Triple::mips64el: 1256263508Sdim LibDirs.append(MIPS64ELLibDirs, 1257263508Sdim MIPS64ELLibDirs + llvm::array_lengthof(MIPS64ELLibDirs)); 1258239462Sdim TripleAliases.append( 1259263508Sdim MIPS64ELTriples, 1260263508Sdim MIPS64ELTriples + llvm::array_lengthof(MIPS64ELTriples)); 1261263508Sdim BiarchLibDirs.append(MIPSELLibDirs, 1262263508Sdim MIPSELLibDirs + llvm::array_lengthof(MIPSELLibDirs)); 1263263508Sdim BiarchTripleAliases.append( 1264263508Sdim MIPSELTriples, MIPSELTriples + llvm::array_lengthof(MIPSELTriples)); 1265263508Sdim BiarchTripleAliases.append( 1266263508Sdim MIPSTriples, MIPSTriples + llvm::array_lengthof(MIPSTriples)); 1267239462Sdim break; 1268234353Sdim case llvm::Triple::ppc: 1269234353Sdim LibDirs.append(PPCLibDirs, PPCLibDirs + llvm::array_lengthof(PPCLibDirs)); 1270263508Sdim TripleAliases.append(PPCTriples, 1271263508Sdim PPCTriples + llvm::array_lengthof(PPCTriples)); 1272263508Sdim BiarchLibDirs.append(PPC64LibDirs, 1273263508Sdim PPC64LibDirs + llvm::array_lengthof(PPC64LibDirs)); 1274263508Sdim BiarchTripleAliases.append( 1275263508Sdim PPC64Triples, PPC64Triples + llvm::array_lengthof(PPC64Triples)); 1276234353Sdim break; 1277234353Sdim case llvm::Triple::ppc64: 1278263508Sdim LibDirs.append(PPC64LibDirs, 1279263508Sdim PPC64LibDirs + llvm::array_lengthof(PPC64LibDirs)); 1280263508Sdim TripleAliases.append(PPC64Triples, 1281263508Sdim PPC64Triples + llvm::array_lengthof(PPC64Triples)); 1282263508Sdim BiarchLibDirs.append(PPCLibDirs, 1283263508Sdim PPCLibDirs + llvm::array_lengthof(PPCLibDirs)); 1284263508Sdim BiarchTripleAliases.append(PPCTriples, 1285263508Sdim PPCTriples + llvm::array_lengthof(PPCTriples)); 1286234353Sdim break; 1287263508Sdim case llvm::Triple::ppc64le: 1288263508Sdim LibDirs.append(PPC64LELibDirs, 1289263508Sdim PPC64LELibDirs + llvm::array_lengthof(PPC64LELibDirs)); 1290263508Sdim TripleAliases.append(PPC64LETriples, 1291263508Sdim PPC64LETriples + llvm::array_lengthof(PPC64LETriples)); 1292263508Sdim break; 1293263763Sdim case llvm::Triple::sparc: 1294263763Sdim LibDirs.append(SPARCv8LibDirs, 1295263763Sdim SPARCv8LibDirs + llvm::array_lengthof(SPARCv8LibDirs)); 1296263763Sdim TripleAliases.append(SPARCv8Triples, 1297263763Sdim SPARCv8Triples + llvm::array_lengthof(SPARCv8Triples)); 1298263763Sdim BiarchLibDirs.append(SPARCv9LibDirs, 1299263763Sdim SPARCv9LibDirs + llvm::array_lengthof(SPARCv9LibDirs)); 1300263763Sdim BiarchTripleAliases.append( 1301263763Sdim SPARCv9Triples, SPARCv9Triples + llvm::array_lengthof(SPARCv9Triples)); 1302263763Sdim break; 1303263763Sdim case llvm::Triple::sparcv9: 1304263763Sdim LibDirs.append(SPARCv9LibDirs, 1305263763Sdim SPARCv9LibDirs + llvm::array_lengthof(SPARCv9LibDirs)); 1306263763Sdim TripleAliases.append(SPARCv9Triples, 1307263763Sdim SPARCv9Triples + llvm::array_lengthof(SPARCv9Triples)); 1308263763Sdim BiarchLibDirs.append(SPARCv8LibDirs, 1309263763Sdim SPARCv8LibDirs + llvm::array_lengthof(SPARCv8LibDirs)); 1310263763Sdim BiarchTripleAliases.append( 1311263763Sdim SPARCv8Triples, SPARCv8Triples + llvm::array_lengthof(SPARCv8Triples)); 1312263763Sdim break; 1313251662Sdim case llvm::Triple::systemz: 1314263508Sdim LibDirs.append(SystemZLibDirs, 1315263508Sdim SystemZLibDirs + llvm::array_lengthof(SystemZLibDirs)); 1316263508Sdim TripleAliases.append(SystemZTriples, 1317263508Sdim SystemZTriples + llvm::array_lengthof(SystemZTriples)); 1318251662Sdim break; 1319234353Sdim 1320234353Sdim default: 1321234353Sdim // By default, just rely on the standard lib directories and the original 1322234353Sdim // triple. 1323234353Sdim break; 1324234353Sdim } 1325234353Sdim 1326234353Sdim // Always append the drivers target triple to the end, in case it doesn't 1327234353Sdim // match any of our aliases. 1328234353Sdim TripleAliases.push_back(TargetTriple.str()); 1329234353Sdim 1330234353Sdim // Also include the multiarch variant if it's different. 1331263508Sdim if (TargetTriple.str() != BiarchTriple.str()) 1332263508Sdim BiarchTripleAliases.push_back(BiarchTriple.str()); 1333234353Sdim} 1334234353Sdim 1335251662Sdimstatic bool isSoftFloatABI(const ArgList &Args) { 1336251662Sdim Arg *A = Args.getLastArg(options::OPT_msoft_float, 1337251662Sdim options::OPT_mhard_float, 1338251662Sdim options::OPT_mfloat_abi_EQ); 1339251662Sdim if (!A) return false; 1340251662Sdim 1341251662Sdim return A->getOption().matches(options::OPT_msoft_float) || 1342251662Sdim (A->getOption().matches(options::OPT_mfloat_abi_EQ) && 1343251662Sdim A->getValue() == StringRef("soft")); 1344251662Sdim} 1345251662Sdim 1346251662Sdimstatic bool isMipsArch(llvm::Triple::ArchType Arch) { 1347251662Sdim return Arch == llvm::Triple::mips || 1348251662Sdim Arch == llvm::Triple::mipsel || 1349251662Sdim Arch == llvm::Triple::mips64 || 1350251662Sdim Arch == llvm::Triple::mips64el; 1351251662Sdim} 1352251662Sdim 1353251662Sdimstatic bool isMips16(const ArgList &Args) { 1354251662Sdim Arg *A = Args.getLastArg(options::OPT_mips16, 1355251662Sdim options::OPT_mno_mips16); 1356251662Sdim return A && A->getOption().matches(options::OPT_mips16); 1357251662Sdim} 1358251662Sdim 1359263508Sdimstatic bool isMips32r2(const ArgList &Args) { 1360263508Sdim Arg *A = Args.getLastArg(options::OPT_march_EQ, 1361263508Sdim options::OPT_mcpu_EQ); 1362263508Sdim 1363263508Sdim return A && A->getValue() == StringRef("mips32r2"); 1364263508Sdim} 1365263508Sdim 1366263508Sdimstatic bool isMips64r2(const ArgList &Args) { 1367263508Sdim Arg *A = Args.getLastArg(options::OPT_march_EQ, 1368263508Sdim options::OPT_mcpu_EQ); 1369263508Sdim 1370263508Sdim return A && A->getValue() == StringRef("mips64r2"); 1371263508Sdim} 1372263508Sdim 1373251662Sdimstatic bool isMicroMips(const ArgList &Args) { 1374251662Sdim Arg *A = Args.getLastArg(options::OPT_mmicromips, 1375251662Sdim options::OPT_mno_micromips); 1376251662Sdim return A && A->getOption().matches(options::OPT_mmicromips); 1377251662Sdim} 1378251662Sdim 1379263508Sdimstatic bool isMipsFP64(const ArgList &Args) { 1380263508Sdim Arg *A = Args.getLastArg(options::OPT_mfp64, options::OPT_mfp32); 1381263508Sdim return A && A->getOption().matches(options::OPT_mfp64); 1382263508Sdim} 1383263508Sdim 1384263508Sdimstatic bool isMipsNan2008(const ArgList &Args) { 1385263508Sdim Arg *A = Args.getLastArg(options::OPT_mnan_EQ); 1386263508Sdim return A && A->getValue() == StringRef("2008"); 1387263508Sdim} 1388263508Sdim 1389243830Sdim// FIXME: There is the same routine in the Tools.cpp. 1390243830Sdimstatic bool hasMipsN32ABIArg(const ArgList &Args) { 1391243830Sdim Arg *A = Args.getLastArg(options::OPT_mabi_EQ); 1392243830Sdim return A && (A->getValue() == StringRef("n32")); 1393243830Sdim} 1394243830Sdim 1395263508Sdimstatic bool hasCrtBeginObj(Twine Path) { 1396263508Sdim return llvm::sys::fs::exists(Path + "/crtbegin.o"); 1397263508Sdim} 1398263508Sdim 1399263508Sdimstatic bool findTargetBiarchSuffix(std::string &Suffix, StringRef Path, 1400251662Sdim llvm::Triple::ArchType TargetArch, 1401251662Sdim const ArgList &Args) { 1402263508Sdim // FIXME: This routine was only intended to model bi-arch toolchains which 1403263508Sdim // use -m32 and -m64 to swap between variants of a target. It shouldn't be 1404263508Sdim // doing ABI-based builtin location for MIPS. 1405263508Sdim if (hasMipsN32ABIArg(Args)) 1406263508Sdim Suffix = "/n32"; 1407263508Sdim else if (TargetArch == llvm::Triple::x86_64 || 1408263508Sdim TargetArch == llvm::Triple::ppc64 || 1409263763Sdim TargetArch == llvm::Triple::sparcv9 || 1410263508Sdim TargetArch == llvm::Triple::systemz || 1411263508Sdim TargetArch == llvm::Triple::mips64 || 1412263508Sdim TargetArch == llvm::Triple::mips64el) 1413263508Sdim Suffix = "/64"; 1414263508Sdim else 1415263508Sdim Suffix = "/32"; 1416243830Sdim 1417263508Sdim return hasCrtBeginObj(Path + Suffix); 1418251662Sdim} 1419251662Sdim 1420263508Sdimvoid Generic_GCC::GCCInstallationDetector::findMIPSABIDirSuffix( 1421263508Sdim std::string &Suffix, llvm::Triple::ArchType TargetArch, StringRef Path, 1422263508Sdim const llvm::opt::ArgList &Args) { 1423263508Sdim if (!isMipsArch(TargetArch)) 1424263508Sdim return; 1425243830Sdim 1426263508Sdim // Some MIPS toolchains put libraries and object files compiled 1427263508Sdim // using different options in to the sub-directoris which names 1428263508Sdim // reflects the flags used for compilation. For example sysroot 1429263508Sdim // directory might looks like the following examples: 1430263508Sdim // 1431263508Sdim // /usr 1432263508Sdim // /lib <= crt*.o files compiled with '-mips32' 1433263508Sdim // /mips16 1434263508Sdim // /usr 1435263508Sdim // /lib <= crt*.o files compiled with '-mips16' 1436263508Sdim // /el 1437263508Sdim // /usr 1438263508Sdim // /lib <= crt*.o files compiled with '-mips16 -EL' 1439263508Sdim // 1440263508Sdim // or 1441263508Sdim // 1442263508Sdim // /usr 1443263508Sdim // /lib <= crt*.o files compiled with '-mips32r2' 1444263508Sdim // /mips16 1445263508Sdim // /usr 1446263508Sdim // /lib <= crt*.o files compiled with '-mips32r2 -mips16' 1447263508Sdim // /mips32 1448263508Sdim // /usr 1449263508Sdim // /lib <= crt*.o files compiled with '-mips32' 1450263508Sdim // 1451263508Sdim // Unfortunately different toolchains use different and partially 1452263508Sdim // overlapped naming schemes. So we have to make a trick for detection 1453263508Sdim // of using toolchain. We lookup a path which unique for each toolchains. 1454243830Sdim 1455263508Sdim bool IsMentorToolChain = hasCrtBeginObj(Path + "/mips16/soft-float"); 1456263508Sdim bool IsFSFToolChain = hasCrtBeginObj(Path + "/mips32/mips16/sof"); 1457251662Sdim 1458263508Sdim if (IsMentorToolChain && IsFSFToolChain) 1459263508Sdim D.Diag(diag::err_drv_unknown_toolchain); 1460251662Sdim 1461263508Sdim if (IsMentorToolChain) { 1462263508Sdim if (isMips16(Args)) 1463263508Sdim Suffix += "/mips16"; 1464263508Sdim else if (isMicroMips(Args)) 1465263508Sdim Suffix += "/micromips"; 1466263508Sdim 1467263508Sdim if (isSoftFloatABI(Args)) 1468263508Sdim Suffix += "/soft-float"; 1469263508Sdim 1470263508Sdim if (TargetArch == llvm::Triple::mipsel || 1471251662Sdim TargetArch == llvm::Triple::mips64el) 1472263508Sdim Suffix += "/el"; 1473263508Sdim } else if (IsFSFToolChain) { 1474263508Sdim if (TargetArch == llvm::Triple::mips || 1475263508Sdim TargetArch == llvm::Triple::mipsel) { 1476263508Sdim if (isMicroMips(Args)) 1477263508Sdim Suffix += "/micromips"; 1478263508Sdim else if (isMips32r2(Args)) 1479263508Sdim Suffix += ""; 1480263508Sdim else 1481263508Sdim Suffix += "/mips32"; 1482251662Sdim 1483263508Sdim if (isMips16(Args)) 1484263508Sdim Suffix += "/mips16"; 1485263508Sdim } else { 1486263508Sdim if (isMips64r2(Args)) 1487263508Sdim Suffix += hasMipsN32ABIArg(Args) ? "/mips64r2" : "/mips64r2/64"; 1488263508Sdim else 1489263508Sdim Suffix += hasMipsN32ABIArg(Args) ? "/mips64" : "/mips64/64"; 1490263508Sdim } 1491251662Sdim 1492263508Sdim if (TargetArch == llvm::Triple::mipsel || 1493263508Sdim TargetArch == llvm::Triple::mips64el) 1494263508Sdim Suffix += "/el"; 1495263508Sdim 1496263508Sdim if (isSoftFloatABI(Args)) 1497263508Sdim Suffix += "/sof"; 1498263508Sdim else { 1499263508Sdim if (isMipsFP64(Args)) 1500263508Sdim Suffix += "/fp64"; 1501263508Sdim 1502263508Sdim if (isMipsNan2008(Args)) 1503263508Sdim Suffix += "/nan2008"; 1504263508Sdim } 1505251662Sdim } 1506251662Sdim 1507263508Sdim if (!hasCrtBeginObj(Path + Suffix)) 1508263508Sdim Suffix.clear(); 1509251662Sdim} 1510251662Sdim 1511234353Sdimvoid Generic_GCC::GCCInstallationDetector::ScanLibDirForGCCTriple( 1512243830Sdim llvm::Triple::ArchType TargetArch, const ArgList &Args, 1513263508Sdim const std::string &LibDir, StringRef CandidateTriple, 1514263508Sdim bool NeedsBiarchSuffix) { 1515234353Sdim // There are various different suffixes involving the triple we 1516234353Sdim // check for. We also record what is necessary to walk from each back 1517234353Sdim // up to the lib directory. 1518234353Sdim const std::string LibSuffixes[] = { 1519234353Sdim "/gcc/" + CandidateTriple.str(), 1520263508Sdim // Debian puts cross-compilers in gcc-cross 1521263508Sdim "/gcc-cross/" + CandidateTriple.str(), 1522234353Sdim "/" + CandidateTriple.str() + "/gcc/" + CandidateTriple.str(), 1523234353Sdim 1524243830Sdim // The Freescale PPC SDK has the gcc libraries in 1525243830Sdim // <sysroot>/usr/lib/<triple>/x.y.z so have a look there as well. 1526243830Sdim "/" + CandidateTriple.str(), 1527243830Sdim 1528234353Sdim // Ubuntu has a strange mis-matched pair of triples that this happens to 1529234353Sdim // match. 1530234353Sdim // FIXME: It may be worthwhile to generalize this and look for a second 1531234353Sdim // triple. 1532234353Sdim "/i386-linux-gnu/gcc/" + CandidateTriple.str() 1533234353Sdim }; 1534234353Sdim const std::string InstallSuffixes[] = { 1535263508Sdim "/../../..", // gcc/ 1536263508Sdim "/../../..", // gcc-cross/ 1537263508Sdim "/../../../..", // <triple>/gcc/ 1538263508Sdim "/../..", // <triple>/ 1539263508Sdim "/../../../.." // i386-linux-gnu/gcc/<triple>/ 1540234353Sdim }; 1541234353Sdim // Only look at the final, weird Ubuntu suffix for i386-linux-gnu. 1542263508Sdim const unsigned NumLibSuffixes = 1543263508Sdim (llvm::array_lengthof(LibSuffixes) - (TargetArch != llvm::Triple::x86)); 1544234353Sdim for (unsigned i = 0; i < NumLibSuffixes; ++i) { 1545234353Sdim StringRef LibSuffix = LibSuffixes[i]; 1546234353Sdim llvm::error_code EC; 1547234353Sdim for (llvm::sys::fs::directory_iterator LI(LibDir + LibSuffix, EC), LE; 1548234353Sdim !EC && LI != LE; LI = LI.increment(EC)) { 1549234353Sdim StringRef VersionText = llvm::sys::path::filename(LI->path()); 1550234353Sdim GCCVersion CandidateVersion = GCCVersion::Parse(VersionText); 1551263508Sdim if (CandidateVersion.Major != -1) // Filter obviously bad entries. 1552263508Sdim if (!CandidateGCCInstallPaths.insert(LI->path()).second) 1553263508Sdim continue; // Saw this path before; no need to look at it again. 1554263508Sdim if (CandidateVersion.isOlderThan(4, 1, 1)) 1555234353Sdim continue; 1556234353Sdim if (CandidateVersion <= Version) 1557234353Sdim continue; 1558234353Sdim 1559263508Sdim std::string MIPSABIDirSuffix; 1560263508Sdim findMIPSABIDirSuffix(MIPSABIDirSuffix, TargetArch, LI->path(), Args); 1561263508Sdim 1562234353Sdim // Some versions of SUSE and Fedora on ppc64 put 32-bit libs 1563234353Sdim // in what would normally be GCCInstallPath and put the 64-bit 1564234353Sdim // libs in a subdirectory named 64. The simple logic we follow is that 1565234353Sdim // *if* there is a subdirectory of the right name with crtbegin.o in it, 1566263508Sdim // we use that. If not, and if not a biarch triple alias, we look for 1567234353Sdim // crtbegin.o without the subdirectory. 1568251662Sdim 1569263508Sdim std::string BiarchSuffix; 1570263508Sdim if (findTargetBiarchSuffix(BiarchSuffix, 1571263508Sdim LI->path() + MIPSABIDirSuffix, 1572263508Sdim TargetArch, Args)) { 1573263508Sdim GCCBiarchSuffix = BiarchSuffix; 1574263508Sdim } else if (NeedsBiarchSuffix || 1575263508Sdim !hasCrtBeginObj(LI->path() + MIPSABIDirSuffix)) { 1576263508Sdim continue; 1577234353Sdim } else { 1578263508Sdim GCCBiarchSuffix.clear(); 1579234353Sdim } 1580234353Sdim 1581234353Sdim Version = CandidateVersion; 1582234353Sdim GCCTriple.setTriple(CandidateTriple); 1583234353Sdim // FIXME: We hack together the directory name here instead of 1584234353Sdim // using LI to ensure stable path separators across Windows and 1585234353Sdim // Linux. 1586234353Sdim GCCInstallPath = LibDir + LibSuffixes[i] + "/" + VersionText.str(); 1587234353Sdim GCCParentLibPath = GCCInstallPath + InstallSuffixes[i]; 1588263508Sdim GCCMIPSABIDirSuffix = MIPSABIDirSuffix; 1589234353Sdim IsValid = true; 1590234353Sdim } 1591234353Sdim } 1592234353Sdim} 1593234353Sdim 1594234353SdimGeneric_GCC::Generic_GCC(const Driver &D, const llvm::Triple& Triple, 1595234353Sdim const ArgList &Args) 1596263508Sdim : ToolChain(D, Triple, Args), GCCInstallation(getDriver()) { 1597212904Sdim getProgramPaths().push_back(getDriver().getInstalledDir()); 1598221345Sdim if (getDriver().getInstalledDir() != getDriver().Dir) 1599212904Sdim getProgramPaths().push_back(getDriver().Dir); 1600193326Sed} 1601193326Sed 1602193326SedGeneric_GCC::~Generic_GCC() { 1603193326Sed} 1604193326Sed 1605249423SdimTool *Generic_GCC::getTool(Action::ActionClass AC) const { 1606249423Sdim switch (AC) { 1607249423Sdim case Action::PreprocessJobClass: 1608249423Sdim if (!Preprocess) 1609249423Sdim Preprocess.reset(new tools::gcc::Preprocess(*this)); 1610249423Sdim return Preprocess.get(); 1611249423Sdim case Action::PrecompileJobClass: 1612249423Sdim if (!Precompile) 1613249423Sdim Precompile.reset(new tools::gcc::Precompile(*this)); 1614249423Sdim return Precompile.get(); 1615249423Sdim case Action::CompileJobClass: 1616249423Sdim if (!Compile) 1617249423Sdim Compile.reset(new tools::gcc::Compile(*this)); 1618249423Sdim return Compile.get(); 1619249423Sdim default: 1620249423Sdim return ToolChain::getTool(AC); 1621193326Sed } 1622249423Sdim} 1623193326Sed 1624249423SdimTool *Generic_GCC::buildAssembler() const { 1625249423Sdim return new tools::gcc::Assemble(*this); 1626193326Sed} 1627193326Sed 1628249423SdimTool *Generic_GCC::buildLinker() const { 1629249423Sdim return new tools::gcc::Link(*this); 1630249423Sdim} 1631249423Sdim 1632263508Sdimvoid Generic_GCC::printVerboseInfo(raw_ostream &OS) const { 1633263508Sdim // Print the information about how we detected the GCC installation. 1634263508Sdim GCCInstallation.print(OS); 1635263508Sdim} 1636263508Sdim 1637193326Sedbool Generic_GCC::IsUnwindTablesDefault() const { 1638243830Sdim return getArch() == llvm::Triple::x86_64; 1639193326Sed} 1640193326Sed 1641243830Sdimbool Generic_GCC::isPICDefault() const { 1642243830Sdim return false; 1643193326Sed} 1644193326Sed 1645251662Sdimbool Generic_GCC::isPIEDefault() const { 1646251662Sdim return false; 1647251662Sdim} 1648251662Sdim 1649243830Sdimbool Generic_GCC::isPICDefaultForced() const { 1650243830Sdim return false; 1651193326Sed} 1652243830Sdim 1653234353Sdim/// Hexagon Toolchain 1654193326Sed 1655249423Sdimstd::string Hexagon_TC::GetGnuDir(const std::string &InstalledDir) { 1656249423Sdim 1657249423Sdim // Locate the rest of the toolchain ... 1658249423Sdim if (strlen(GCC_INSTALL_PREFIX)) 1659249423Sdim return std::string(GCC_INSTALL_PREFIX); 1660249423Sdim 1661249423Sdim std::string InstallRelDir = InstalledDir + "/../../gnu"; 1662249423Sdim if (llvm::sys::fs::exists(InstallRelDir)) 1663249423Sdim return InstallRelDir; 1664249423Sdim 1665249423Sdim std::string PrefixRelDir = std::string(LLVM_PREFIX) + "/../gnu"; 1666249423Sdim if (llvm::sys::fs::exists(PrefixRelDir)) 1667249423Sdim return PrefixRelDir; 1668249423Sdim 1669249423Sdim return InstallRelDir; 1670234353Sdim} 1671234353Sdim 1672249423Sdimstatic void GetHexagonLibraryPaths( 1673249423Sdim const ArgList &Args, 1674249423Sdim const std::string Ver, 1675249423Sdim const std::string MarchString, 1676249423Sdim const std::string &InstalledDir, 1677249423Sdim ToolChain::path_list *LibPaths) 1678249423Sdim{ 1679249423Sdim bool buildingLib = Args.hasArg(options::OPT_shared); 1680249423Sdim 1681249423Sdim //---------------------------------------------------------------------------- 1682249423Sdim // -L Args 1683249423Sdim //---------------------------------------------------------------------------- 1684249423Sdim for (arg_iterator 1685249423Sdim it = Args.filtered_begin(options::OPT_L), 1686249423Sdim ie = Args.filtered_end(); 1687249423Sdim it != ie; 1688249423Sdim ++it) { 1689249423Sdim for (unsigned i = 0, e = (*it)->getNumValues(); i != e; ++i) 1690249423Sdim LibPaths->push_back((*it)->getValue(i)); 1691249423Sdim } 1692249423Sdim 1693249423Sdim //---------------------------------------------------------------------------- 1694249423Sdim // Other standard paths 1695249423Sdim //---------------------------------------------------------------------------- 1696249423Sdim const std::string MarchSuffix = "/" + MarchString; 1697249423Sdim const std::string G0Suffix = "/G0"; 1698249423Sdim const std::string MarchG0Suffix = MarchSuffix + G0Suffix; 1699249423Sdim const std::string RootDir = Hexagon_TC::GetGnuDir(InstalledDir) + "/"; 1700249423Sdim 1701249423Sdim // lib/gcc/hexagon/... 1702249423Sdim std::string LibGCCHexagonDir = RootDir + "lib/gcc/hexagon/"; 1703249423Sdim if (buildingLib) { 1704249423Sdim LibPaths->push_back(LibGCCHexagonDir + Ver + MarchG0Suffix); 1705249423Sdim LibPaths->push_back(LibGCCHexagonDir + Ver + G0Suffix); 1706249423Sdim } 1707249423Sdim LibPaths->push_back(LibGCCHexagonDir + Ver + MarchSuffix); 1708249423Sdim LibPaths->push_back(LibGCCHexagonDir + Ver); 1709249423Sdim 1710249423Sdim // lib/gcc/... 1711249423Sdim LibPaths->push_back(RootDir + "lib/gcc"); 1712249423Sdim 1713249423Sdim // hexagon/lib/... 1714249423Sdim std::string HexagonLibDir = RootDir + "hexagon/lib"; 1715249423Sdim if (buildingLib) { 1716249423Sdim LibPaths->push_back(HexagonLibDir + MarchG0Suffix); 1717249423Sdim LibPaths->push_back(HexagonLibDir + G0Suffix); 1718249423Sdim } 1719249423Sdim LibPaths->push_back(HexagonLibDir + MarchSuffix); 1720249423Sdim LibPaths->push_back(HexagonLibDir); 1721249423Sdim} 1722249423Sdim 1723249423SdimHexagon_TC::Hexagon_TC(const Driver &D, const llvm::Triple &Triple, 1724249423Sdim const ArgList &Args) 1725249423Sdim : Linux(D, Triple, Args) { 1726249423Sdim const std::string InstalledDir(getDriver().getInstalledDir()); 1727249423Sdim const std::string GnuDir = Hexagon_TC::GetGnuDir(InstalledDir); 1728249423Sdim 1729249423Sdim // Note: Generic_GCC::Generic_GCC adds InstalledDir and getDriver().Dir to 1730249423Sdim // program paths 1731249423Sdim const std::string BinDir(GnuDir + "/bin"); 1732249423Sdim if (llvm::sys::fs::exists(BinDir)) 1733249423Sdim getProgramPaths().push_back(BinDir); 1734249423Sdim 1735249423Sdim // Determine version of GCC libraries and headers to use. 1736249423Sdim const std::string HexagonDir(GnuDir + "/lib/gcc/hexagon"); 1737249423Sdim llvm::error_code ec; 1738249423Sdim GCCVersion MaxVersion= GCCVersion::Parse("0.0.0"); 1739249423Sdim for (llvm::sys::fs::directory_iterator di(HexagonDir, ec), de; 1740249423Sdim !ec && di != de; di = di.increment(ec)) { 1741249423Sdim GCCVersion cv = GCCVersion::Parse(llvm::sys::path::filename(di->path())); 1742249423Sdim if (MaxVersion < cv) 1743249423Sdim MaxVersion = cv; 1744249423Sdim } 1745249423Sdim GCCLibAndIncVersion = MaxVersion; 1746249423Sdim 1747249423Sdim ToolChain::path_list *LibPaths= &getFilePaths(); 1748249423Sdim 1749249423Sdim // Remove paths added by Linux toolchain. Currently Hexagon_TC really targets 1750249423Sdim // 'elf' OS type, so the Linux paths are not appropriate. When we actually 1751249423Sdim // support 'linux' we'll need to fix this up 1752249423Sdim LibPaths->clear(); 1753249423Sdim 1754249423Sdim GetHexagonLibraryPaths( 1755249423Sdim Args, 1756249423Sdim GetGCCLibAndIncVersion(), 1757249423Sdim GetTargetCPU(Args), 1758249423Sdim InstalledDir, 1759249423Sdim LibPaths); 1760249423Sdim} 1761249423Sdim 1762234353SdimHexagon_TC::~Hexagon_TC() { 1763234353Sdim} 1764234353Sdim 1765249423SdimTool *Hexagon_TC::buildAssembler() const { 1766249423Sdim return new tools::hexagon::Assemble(*this); 1767249423Sdim} 1768234353Sdim 1769249423SdimTool *Hexagon_TC::buildLinker() const { 1770249423Sdim return new tools::hexagon::Link(*this); 1771249423Sdim} 1772234353Sdim 1773249423Sdimvoid Hexagon_TC::AddClangSystemIncludeArgs(const ArgList &DriverArgs, 1774249423Sdim ArgStringList &CC1Args) const { 1775249423Sdim const Driver &D = getDriver(); 1776249423Sdim 1777249423Sdim if (DriverArgs.hasArg(options::OPT_nostdinc) || 1778249423Sdim DriverArgs.hasArg(options::OPT_nostdlibinc)) 1779249423Sdim return; 1780249423Sdim 1781249423Sdim std::string Ver(GetGCCLibAndIncVersion()); 1782249423Sdim std::string GnuDir = Hexagon_TC::GetGnuDir(D.InstalledDir); 1783249423Sdim std::string HexagonDir(GnuDir + "/lib/gcc/hexagon/" + Ver); 1784249423Sdim addExternCSystemInclude(DriverArgs, CC1Args, HexagonDir + "/include"); 1785249423Sdim addExternCSystemInclude(DriverArgs, CC1Args, HexagonDir + "/include-fixed"); 1786249423Sdim addExternCSystemInclude(DriverArgs, CC1Args, GnuDir + "/hexagon/include"); 1787249423Sdim} 1788249423Sdim 1789249423Sdimvoid Hexagon_TC::AddClangCXXStdlibIncludeArgs(const ArgList &DriverArgs, 1790249423Sdim ArgStringList &CC1Args) const { 1791249423Sdim 1792249423Sdim if (DriverArgs.hasArg(options::OPT_nostdlibinc) || 1793249423Sdim DriverArgs.hasArg(options::OPT_nostdincxx)) 1794249423Sdim return; 1795249423Sdim 1796249423Sdim const Driver &D = getDriver(); 1797249423Sdim std::string Ver(GetGCCLibAndIncVersion()); 1798263508Sdim SmallString<128> IncludeDir(Hexagon_TC::GetGnuDir(D.InstalledDir)); 1799249423Sdim 1800263508Sdim llvm::sys::path::append(IncludeDir, "hexagon/include/c++/"); 1801263508Sdim llvm::sys::path::append(IncludeDir, Ver); 1802249423Sdim addSystemInclude(DriverArgs, CC1Args, IncludeDir.str()); 1803249423Sdim} 1804249423Sdim 1805249423SdimToolChain::CXXStdlibType 1806249423SdimHexagon_TC::GetCXXStdlibType(const ArgList &Args) const { 1807249423Sdim Arg *A = Args.getLastArg(options::OPT_stdlib_EQ); 1808249423Sdim if (!A) 1809249423Sdim return ToolChain::CST_Libstdcxx; 1810249423Sdim 1811249423Sdim StringRef Value = A->getValue(); 1812249423Sdim if (Value != "libstdc++") { 1813249423Sdim getDriver().Diag(diag::err_drv_invalid_stdlib_name) 1814249423Sdim << A->getAsString(Args); 1815234353Sdim } 1816234353Sdim 1817249423Sdim return ToolChain::CST_Libstdcxx; 1818234353Sdim} 1819234353Sdim 1820263508Sdimstatic int getHexagonVersion(const ArgList &Args) { 1821263508Sdim Arg *A = Args.getLastArg(options::OPT_march_EQ, options::OPT_mcpu_EQ); 1822263508Sdim // Select the default CPU (v4) if none was given. 1823263508Sdim if (!A) 1824263508Sdim return 4; 1825249423Sdim 1826263508Sdim // FIXME: produce errors if we cannot parse the version. 1827263508Sdim StringRef WhichHexagon = A->getValue(); 1828263508Sdim if (WhichHexagon.startswith("hexagonv")) { 1829263508Sdim int Val; 1830263508Sdim if (!WhichHexagon.substr(sizeof("hexagonv") - 1).getAsInteger(10, Val)) 1831263508Sdim return Val; 1832249423Sdim } 1833263508Sdim if (WhichHexagon.startswith("v")) { 1834263508Sdim int Val; 1835263508Sdim if (!WhichHexagon.substr(1).getAsInteger(10, Val)) 1836263508Sdim return Val; 1837263508Sdim } 1838263508Sdim 1839263508Sdim // FIXME: should probably be an error. 1840263508Sdim return 4; 1841234353Sdim} 1842234353Sdim 1843249423SdimStringRef Hexagon_TC::GetTargetCPU(const ArgList &Args) 1844249423Sdim{ 1845263508Sdim int V = getHexagonVersion(Args); 1846263508Sdim // FIXME: We don't support versions < 4. We should error on them. 1847263508Sdim switch (V) { 1848263508Sdim default: 1849263508Sdim llvm_unreachable("Unexpected version"); 1850263508Sdim case 5: 1851263508Sdim return "v5"; 1852263508Sdim case 4: 1853263508Sdim return "v4"; 1854263508Sdim case 3: 1855263508Sdim return "v3"; 1856263508Sdim case 2: 1857263508Sdim return "v2"; 1858263508Sdim case 1: 1859263508Sdim return "v1"; 1860249423Sdim } 1861234353Sdim} 1862249423Sdim// End Hexagon 1863234353Sdim 1864204793Srdivacky/// TCEToolChain - A tool chain using the llvm bitcode tools to perform 1865204793Srdivacky/// all subcommands. See http://tce.cs.tut.fi for our peculiar target. 1866204793Srdivacky/// Currently does not support anything else but compilation. 1867204793Srdivacky 1868249423SdimTCEToolChain::TCEToolChain(const Driver &D, const llvm::Triple& Triple, 1869249423Sdim const ArgList &Args) 1870249423Sdim : ToolChain(D, Triple, Args) { 1871204793Srdivacky // Path mangling to find libexec 1872204793Srdivacky std::string Path(getDriver().Dir); 1873204793Srdivacky 1874204793Srdivacky Path += "/../libexec"; 1875204793Srdivacky getProgramPaths().push_back(Path); 1876204793Srdivacky} 1877204793Srdivacky 1878204793SrdivackyTCEToolChain::~TCEToolChain() { 1879204793Srdivacky} 1880204793Srdivacky 1881223017Sdimbool TCEToolChain::IsMathErrnoDefault() const { 1882223017Sdim return true; 1883204793Srdivacky} 1884204793Srdivacky 1885243830Sdimbool TCEToolChain::isPICDefault() const { 1886204793Srdivacky return false; 1887204793Srdivacky} 1888204793Srdivacky 1889251662Sdimbool TCEToolChain::isPIEDefault() const { 1890251662Sdim return false; 1891251662Sdim} 1892251662Sdim 1893243830Sdimbool TCEToolChain::isPICDefaultForced() const { 1894243830Sdim return false; 1895204793Srdivacky} 1896204793Srdivacky 1897195341Sed/// OpenBSD - OpenBSD tool chain which can call as(1) and ld(1) directly. 1898195341Sed 1899234353SdimOpenBSD::OpenBSD(const Driver &D, const llvm::Triple& Triple, const ArgList &Args) 1900234353Sdim : Generic_ELF(D, Triple, Args) { 1901201361Srdivacky getFilePaths().push_back(getDriver().Dir + "/../lib"); 1902195341Sed getFilePaths().push_back("/usr/lib"); 1903195341Sed} 1904195341Sed 1905249423SdimTool *OpenBSD::buildAssembler() const { 1906249423Sdim return new tools::openbsd::Assemble(*this); 1907249423Sdim} 1908195341Sed 1909249423SdimTool *OpenBSD::buildLinker() const { 1910249423Sdim return new tools::openbsd::Link(*this); 1911195341Sed} 1912195341Sed 1913239462Sdim/// Bitrig - Bitrig tool chain which can call as(1) and ld(1) directly. 1914239462Sdim 1915239462SdimBitrig::Bitrig(const Driver &D, const llvm::Triple& Triple, const ArgList &Args) 1916239462Sdim : Generic_ELF(D, Triple, Args) { 1917239462Sdim getFilePaths().push_back(getDriver().Dir + "/../lib"); 1918239462Sdim getFilePaths().push_back("/usr/lib"); 1919239462Sdim} 1920239462Sdim 1921249423SdimTool *Bitrig::buildAssembler() const { 1922249423Sdim return new tools::bitrig::Assemble(*this); 1923249423Sdim} 1924239462Sdim 1925249423SdimTool *Bitrig::buildLinker() const { 1926249423Sdim return new tools::bitrig::Link(*this); 1927239462Sdim} 1928239462Sdim 1929239462Sdimvoid Bitrig::AddClangCXXStdlibIncludeArgs(const ArgList &DriverArgs, 1930239462Sdim ArgStringList &CC1Args) const { 1931239462Sdim if (DriverArgs.hasArg(options::OPT_nostdlibinc) || 1932239462Sdim DriverArgs.hasArg(options::OPT_nostdincxx)) 1933239462Sdim return; 1934239462Sdim 1935243830Sdim switch (GetCXXStdlibType(DriverArgs)) { 1936243830Sdim case ToolChain::CST_Libcxx: 1937243830Sdim addSystemInclude(DriverArgs, CC1Args, 1938243830Sdim getDriver().SysRoot + "/usr/include/c++/"); 1939243830Sdim break; 1940243830Sdim case ToolChain::CST_Libstdcxx: 1941243830Sdim addSystemInclude(DriverArgs, CC1Args, 1942243830Sdim getDriver().SysRoot + "/usr/include/c++/stdc++"); 1943243830Sdim addSystemInclude(DriverArgs, CC1Args, 1944243830Sdim getDriver().SysRoot + "/usr/include/c++/stdc++/backward"); 1945239462Sdim 1946243830Sdim StringRef Triple = getTriple().str(); 1947243830Sdim if (Triple.startswith("amd64")) 1948243830Sdim addSystemInclude(DriverArgs, CC1Args, 1949243830Sdim getDriver().SysRoot + "/usr/include/c++/stdc++/x86_64" + 1950243830Sdim Triple.substr(5)); 1951243830Sdim else 1952243830Sdim addSystemInclude(DriverArgs, CC1Args, 1953243830Sdim getDriver().SysRoot + "/usr/include/c++/stdc++/" + 1954243830Sdim Triple); 1955243830Sdim break; 1956243830Sdim } 1957239462Sdim} 1958239462Sdim 1959239462Sdimvoid Bitrig::AddCXXStdlibLibArgs(const ArgList &Args, 1960239462Sdim ArgStringList &CmdArgs) const { 1961243830Sdim switch (GetCXXStdlibType(Args)) { 1962243830Sdim case ToolChain::CST_Libcxx: 1963243830Sdim CmdArgs.push_back("-lc++"); 1964243830Sdim CmdArgs.push_back("-lcxxrt"); 1965243830Sdim // Include supc++ to provide Unwind until provided by libcxx. 1966243830Sdim CmdArgs.push_back("-lgcc"); 1967243830Sdim break; 1968243830Sdim case ToolChain::CST_Libstdcxx: 1969243830Sdim CmdArgs.push_back("-lstdc++"); 1970243830Sdim break; 1971243830Sdim } 1972239462Sdim} 1973239462Sdim 1974193326Sed/// FreeBSD - FreeBSD tool chain which can call as(1) and ld(1) directly. 1975193326Sed 1976234353SdimFreeBSD::FreeBSD(const Driver &D, const llvm::Triple& Triple, const ArgList &Args) 1977234353Sdim : Generic_ELF(D, Triple, Args) { 1978212904Sdim 1979234353Sdim // When targeting 32-bit platforms, look for '/usr/lib32/crt1.o' and fall 1980234353Sdim // back to '/usr/lib' if it doesn't exist. 1981234353Sdim if ((Triple.getArch() == llvm::Triple::x86 || 1982234353Sdim Triple.getArch() == llvm::Triple::ppc) && 1983234982Sdim llvm::sys::fs::exists(getDriver().SysRoot + "/usr/lib32/crt1.o")) 1984234982Sdim getFilePaths().push_back(getDriver().SysRoot + "/usr/lib32"); 1985234353Sdim else 1986234982Sdim getFilePaths().push_back(getDriver().SysRoot + "/usr/lib"); 1987193326Sed} 1988193326Sed 1989255321StheravenToolChain::CXXStdlibType 1990255321StheravenFreeBSD::GetCXXStdlibType(const ArgList &Args) const { 1991255321Stheraven if (Arg *A = Args.getLastArg(options::OPT_stdlib_EQ)) { 1992255321Stheraven StringRef Value = A->getValue(); 1993263508Sdim if (Value == "libstdc++") 1994263508Sdim return ToolChain::CST_Libstdcxx; 1995255321Stheraven if (Value == "libc++") 1996255321Stheraven return ToolChain::CST_Libcxx; 1997263508Sdim 1998255321Stheraven getDriver().Diag(diag::err_drv_invalid_stdlib_name) 1999255321Stheraven << A->getAsString(Args); 2000255321Stheraven } 2001263508Sdim if (getTriple().getOSMajorVersion() >= 10) 2002263508Sdim return ToolChain::CST_Libcxx; 2003263508Sdim return ToolChain::CST_Libstdcxx; 2004255321Stheraven} 2005255321Stheraven 2006255321Stheravenvoid FreeBSD::AddClangCXXStdlibIncludeArgs(const ArgList &DriverArgs, 2007263508Sdim ArgStringList &CC1Args) const { 2008255321Stheraven if (DriverArgs.hasArg(options::OPT_nostdlibinc) || 2009255321Stheraven DriverArgs.hasArg(options::OPT_nostdincxx)) 2010255321Stheraven return; 2011255321Stheraven 2012263508Sdim switch (GetCXXStdlibType(DriverArgs)) { 2013263508Sdim case ToolChain::CST_Libcxx: 2014255321Stheraven addSystemInclude(DriverArgs, CC1Args, 2015255321Stheraven getDriver().SysRoot + "/usr/include/c++/v1"); 2016263508Sdim break; 2017263508Sdim case ToolChain::CST_Libstdcxx: 2018255321Stheraven addSystemInclude(DriverArgs, CC1Args, 2019255321Stheraven getDriver().SysRoot + "/usr/include/c++/4.2"); 2020263508Sdim addSystemInclude(DriverArgs, CC1Args, 2021263508Sdim getDriver().SysRoot + "/usr/include/c++/4.2/backward"); 2022263508Sdim break; 2023263508Sdim } 2024263508Sdim} 2025255321Stheraven 2026263508SdimTool *FreeBSD::buildAssembler() const { 2027263508Sdim return new tools::freebsd::Assemble(*this); 2028255321Stheraven} 2029255321Stheraven 2030263508SdimTool *FreeBSD::buildLinker() const { 2031263508Sdim return new tools::freebsd::Link(*this); 2032263508Sdim} 2033263508Sdim 2034263508Sdimbool FreeBSD::UseSjLjExceptions() const { 2035263508Sdim // FreeBSD uses SjLj exceptions on ARM oabi. 2036263508Sdim switch (getTriple().getEnvironment()) { 2037263508Sdim case llvm::Triple::GNUEABI: 2038263508Sdim case llvm::Triple::EABI: 2039263508Sdim return false; 2040263508Sdim 2041263508Sdim default: 2042263508Sdim return (getTriple().getArch() == llvm::Triple::arm || 2043263508Sdim getTriple().getArch() == llvm::Triple::thumb); 2044263508Sdim } 2045263508Sdim} 2046263508Sdim 2047218893Sdim/// NetBSD - NetBSD tool chain which can call as(1) and ld(1) directly. 2048218893Sdim 2049234353SdimNetBSD::NetBSD(const Driver &D, const llvm::Triple& Triple, const ArgList &Args) 2050234353Sdim : Generic_ELF(D, Triple, Args) { 2051218893Sdim 2052221345Sdim if (getDriver().UseStdLib) { 2053234353Sdim // When targeting a 32-bit platform, try the special directory used on 2054234353Sdim // 64-bit hosts, and only fall back to the main library directory if that 2055234353Sdim // doesn't work. 2056234353Sdim // FIXME: It'd be nicer to test if this directory exists, but I'm not sure 2057234353Sdim // what all logic is needed to emulate the '=' prefix here. 2058234353Sdim if (Triple.getArch() == llvm::Triple::x86) 2059221345Sdim getFilePaths().push_back("=/usr/lib/i386"); 2060234353Sdim 2061234353Sdim getFilePaths().push_back("=/usr/lib"); 2062218893Sdim } 2063218893Sdim} 2064218893Sdim 2065249423SdimTool *NetBSD::buildAssembler() const { 2066249423Sdim return new tools::netbsd::Assemble(*this); 2067249423Sdim} 2068218893Sdim 2069249423SdimTool *NetBSD::buildLinker() const { 2070249423Sdim return new tools::netbsd::Link(*this); 2071218893Sdim} 2072218893Sdim 2073251662SdimToolChain::CXXStdlibType 2074251662SdimNetBSD::GetCXXStdlibType(const ArgList &Args) const { 2075251662Sdim if (Arg *A = Args.getLastArg(options::OPT_stdlib_EQ)) { 2076251662Sdim StringRef Value = A->getValue(); 2077251662Sdim if (Value == "libstdc++") 2078251662Sdim return ToolChain::CST_Libstdcxx; 2079251662Sdim if (Value == "libc++") 2080251662Sdim return ToolChain::CST_Libcxx; 2081251662Sdim 2082251662Sdim getDriver().Diag(diag::err_drv_invalid_stdlib_name) 2083251662Sdim << A->getAsString(Args); 2084251662Sdim } 2085251662Sdim 2086263508Sdim unsigned Major, Minor, Micro; 2087263508Sdim getTriple().getOSVersion(Major, Minor, Micro); 2088263508Sdim if (Major >= 7 || (Major == 6 && Minor == 99 && Micro >= 23) || Major == 0) { 2089263508Sdim if (getArch() == llvm::Triple::x86 || getArch() == llvm::Triple::x86_64) 2090263508Sdim return ToolChain::CST_Libcxx; 2091263508Sdim } 2092251662Sdim return ToolChain::CST_Libstdcxx; 2093251662Sdim} 2094251662Sdim 2095251662Sdimvoid NetBSD::AddClangCXXStdlibIncludeArgs(const ArgList &DriverArgs, 2096251662Sdim ArgStringList &CC1Args) const { 2097251662Sdim if (DriverArgs.hasArg(options::OPT_nostdlibinc) || 2098251662Sdim DriverArgs.hasArg(options::OPT_nostdincxx)) 2099251662Sdim return; 2100251662Sdim 2101251662Sdim switch (GetCXXStdlibType(DriverArgs)) { 2102251662Sdim case ToolChain::CST_Libcxx: 2103251662Sdim addSystemInclude(DriverArgs, CC1Args, 2104251662Sdim getDriver().SysRoot + "/usr/include/c++/"); 2105251662Sdim break; 2106251662Sdim case ToolChain::CST_Libstdcxx: 2107251662Sdim addSystemInclude(DriverArgs, CC1Args, 2108251662Sdim getDriver().SysRoot + "/usr/include/g++"); 2109251662Sdim addSystemInclude(DriverArgs, CC1Args, 2110251662Sdim getDriver().SysRoot + "/usr/include/g++/backward"); 2111251662Sdim break; 2112251662Sdim } 2113251662Sdim} 2114251662Sdim 2115210299Sed/// Minix - Minix tool chain which can call as(1) and ld(1) directly. 2116210299Sed 2117234353SdimMinix::Minix(const Driver &D, const llvm::Triple& Triple, const ArgList &Args) 2118234353Sdim : Generic_ELF(D, Triple, Args) { 2119210299Sed getFilePaths().push_back(getDriver().Dir + "/../lib"); 2120210299Sed getFilePaths().push_back("/usr/lib"); 2121210299Sed} 2122210299Sed 2123249423SdimTool *Minix::buildAssembler() const { 2124249423Sdim return new tools::minix::Assemble(*this); 2125249423Sdim} 2126210299Sed 2127249423SdimTool *Minix::buildLinker() const { 2128249423Sdim return new tools::minix::Link(*this); 2129210299Sed} 2130210299Sed 2131198092Srdivacky/// AuroraUX - AuroraUX tool chain which can call as(1) and ld(1) directly. 2132198092Srdivacky 2133234353SdimAuroraUX::AuroraUX(const Driver &D, const llvm::Triple& Triple, 2134234353Sdim const ArgList &Args) 2135234353Sdim : Generic_GCC(D, Triple, Args) { 2136198092Srdivacky 2137212904Sdim getProgramPaths().push_back(getDriver().getInstalledDir()); 2138221345Sdim if (getDriver().getInstalledDir() != getDriver().Dir) 2139212904Sdim getProgramPaths().push_back(getDriver().Dir); 2140198092Srdivacky 2141201361Srdivacky getFilePaths().push_back(getDriver().Dir + "/../lib"); 2142198092Srdivacky getFilePaths().push_back("/usr/lib"); 2143198092Srdivacky getFilePaths().push_back("/usr/sfw/lib"); 2144198092Srdivacky getFilePaths().push_back("/opt/gcc4/lib"); 2145198398Srdivacky getFilePaths().push_back("/opt/gcc4/lib/gcc/i386-pc-solaris2.11/4.2.4"); 2146198092Srdivacky 2147198092Srdivacky} 2148198092Srdivacky 2149249423SdimTool *AuroraUX::buildAssembler() const { 2150249423Sdim return new tools::auroraux::Assemble(*this); 2151249423Sdim} 2152198092Srdivacky 2153249423SdimTool *AuroraUX::buildLinker() const { 2154249423Sdim return new tools::auroraux::Link(*this); 2155198092Srdivacky} 2156198092Srdivacky 2157234353Sdim/// Solaris - Solaris tool chain which can call as(1) and ld(1) directly. 2158198092Srdivacky 2159234353SdimSolaris::Solaris(const Driver &D, const llvm::Triple& Triple, 2160234353Sdim const ArgList &Args) 2161234353Sdim : Generic_GCC(D, Triple, Args) { 2162234353Sdim 2163234353Sdim getProgramPaths().push_back(getDriver().getInstalledDir()); 2164234353Sdim if (getDriver().getInstalledDir() != getDriver().Dir) 2165234353Sdim getProgramPaths().push_back(getDriver().Dir); 2166234353Sdim 2167234353Sdim getFilePaths().push_back(getDriver().Dir + "/../lib"); 2168234353Sdim getFilePaths().push_back("/usr/lib"); 2169234353Sdim} 2170234353Sdim 2171249423SdimTool *Solaris::buildAssembler() const { 2172249423Sdim return new tools::solaris::Assemble(*this); 2173249423Sdim} 2174234353Sdim 2175249423SdimTool *Solaris::buildLinker() const { 2176249423Sdim return new tools::solaris::Link(*this); 2177234353Sdim} 2178234353Sdim 2179249423Sdim/// Distribution (very bare-bones at the moment). 2180193326Sed 2181249423Sdimenum Distro { 2182219077Sdim ArchLinux, 2183218893Sdim DebianLenny, 2184218893Sdim DebianSqueeze, 2185223017Sdim DebianWheezy, 2186249423Sdim DebianJessie, 2187218893Sdim Exherbo, 2188223017Sdim RHEL4, 2189223017Sdim RHEL5, 2190223017Sdim RHEL6, 2191263508Sdim Fedora, 2192263508Sdim OpenSUSE, 2193221345Sdim UbuntuHardy, 2194221345Sdim UbuntuIntrepid, 2195218893Sdim UbuntuJaunty, 2196218893Sdim UbuntuKarmic, 2197218893Sdim UbuntuLucid, 2198218893Sdim UbuntuMaverick, 2199221345Sdim UbuntuNatty, 2200223017Sdim UbuntuOneiric, 2201234353Sdim UbuntuPrecise, 2202244628Sdim UbuntuQuantal, 2203244628Sdim UbuntuRaring, 2204263508Sdim UbuntuSaucy, 2205263508Sdim UbuntuTrusty, 2206218893Sdim UnknownDistro 2207218893Sdim}; 2208198092Srdivacky 2209249423Sdimstatic bool IsRedhat(enum Distro Distro) { 2210263508Sdim return Distro == Fedora || (Distro >= RHEL4 && Distro <= RHEL6); 2211218893Sdim} 2212198092Srdivacky 2213263508Sdimstatic bool IsOpenSUSE(enum Distro Distro) { 2214263508Sdim return Distro == OpenSUSE; 2215193326Sed} 2216193326Sed 2217249423Sdimstatic bool IsDebian(enum Distro Distro) { 2218249423Sdim return Distro >= DebianLenny && Distro <= DebianJessie; 2219218893Sdim} 2220218893Sdim 2221249423Sdimstatic bool IsUbuntu(enum Distro Distro) { 2222263508Sdim return Distro >= UbuntuHardy && Distro <= UbuntuTrusty; 2223218893Sdim} 2224218893Sdim 2225249423Sdimstatic Distro DetectDistro(llvm::Triple::ArchType Arch) { 2226234353Sdim OwningPtr<llvm::MemoryBuffer> File; 2227218893Sdim if (!llvm::MemoryBuffer::getFile("/etc/lsb-release", File)) { 2228226633Sdim StringRef Data = File.get()->getBuffer(); 2229226633Sdim SmallVector<StringRef, 8> Lines; 2230218893Sdim Data.split(Lines, "\n"); 2231249423Sdim Distro Version = UnknownDistro; 2232234353Sdim for (unsigned i = 0, s = Lines.size(); i != s; ++i) 2233234353Sdim if (Version == UnknownDistro && Lines[i].startswith("DISTRIB_CODENAME=")) 2234249423Sdim Version = llvm::StringSwitch<Distro>(Lines[i].substr(17)) 2235234353Sdim .Case("hardy", UbuntuHardy) 2236234353Sdim .Case("intrepid", UbuntuIntrepid) 2237234353Sdim .Case("jaunty", UbuntuJaunty) 2238234353Sdim .Case("karmic", UbuntuKarmic) 2239234353Sdim .Case("lucid", UbuntuLucid) 2240234353Sdim .Case("maverick", UbuntuMaverick) 2241234353Sdim .Case("natty", UbuntuNatty) 2242234353Sdim .Case("oneiric", UbuntuOneiric) 2243234353Sdim .Case("precise", UbuntuPrecise) 2244244628Sdim .Case("quantal", UbuntuQuantal) 2245244628Sdim .Case("raring", UbuntuRaring) 2246263508Sdim .Case("saucy", UbuntuSaucy) 2247263508Sdim .Case("trusty", UbuntuTrusty) 2248234353Sdim .Default(UnknownDistro); 2249234353Sdim return Version; 2250218893Sdim } 2251218893Sdim 2252218893Sdim if (!llvm::MemoryBuffer::getFile("/etc/redhat-release", File)) { 2253226633Sdim StringRef Data = File.get()->getBuffer(); 2254263508Sdim if (Data.startswith("Fedora release")) 2255263508Sdim return Fedora; 2256223017Sdim else if (Data.startswith("Red Hat Enterprise Linux") && 2257226633Sdim Data.find("release 6") != StringRef::npos) 2258223017Sdim return RHEL6; 2259223017Sdim else if ((Data.startswith("Red Hat Enterprise Linux") || 2260249423Sdim Data.startswith("CentOS")) && 2261226633Sdim Data.find("release 5") != StringRef::npos) 2262223017Sdim return RHEL5; 2263223017Sdim else if ((Data.startswith("Red Hat Enterprise Linux") || 2264249423Sdim Data.startswith("CentOS")) && 2265226633Sdim Data.find("release 4") != StringRef::npos) 2266223017Sdim return RHEL4; 2267218893Sdim return UnknownDistro; 2268218893Sdim } 2269218893Sdim 2270218893Sdim if (!llvm::MemoryBuffer::getFile("/etc/debian_version", File)) { 2271226633Sdim StringRef Data = File.get()->getBuffer(); 2272218893Sdim if (Data[0] == '5') 2273218893Sdim return DebianLenny; 2274234353Sdim else if (Data.startswith("squeeze/sid") || Data[0] == '6') 2275218893Sdim return DebianSqueeze; 2276234353Sdim else if (Data.startswith("wheezy/sid") || Data[0] == '7') 2277223017Sdim return DebianWheezy; 2278249423Sdim else if (Data.startswith("jessie/sid") || Data[0] == '8') 2279249423Sdim return DebianJessie; 2280218893Sdim return UnknownDistro; 2281218893Sdim } 2282218893Sdim 2283263508Sdim if (llvm::sys::fs::exists("/etc/SuSE-release")) 2284263508Sdim return OpenSUSE; 2285218893Sdim 2286263508Sdim if (llvm::sys::fs::exists("/etc/exherbo-release")) 2287218893Sdim return Exherbo; 2288218893Sdim 2289263508Sdim if (llvm::sys::fs::exists("/etc/arch-release")) 2290219077Sdim return ArchLinux; 2291219077Sdim 2292218893Sdim return UnknownDistro; 2293218893Sdim} 2294218893Sdim 2295228379Sdim/// \brief Get our best guess at the multiarch triple for a target. 2296228379Sdim/// 2297228379Sdim/// Debian-based systems are starting to use a multiarch setup where they use 2298228379Sdim/// a target-triple directory in the library and header search paths. 2299228379Sdim/// Unfortunately, this triple does not align with the vanilla target triple, 2300228379Sdim/// so we provide a rough mapping here. 2301228379Sdimstatic std::string getMultiarchTriple(const llvm::Triple TargetTriple, 2302228379Sdim StringRef SysRoot) { 2303228379Sdim // For most architectures, just use whatever we have rather than trying to be 2304228379Sdim // clever. 2305228379Sdim switch (TargetTriple.getArch()) { 2306228379Sdim default: 2307228379Sdim return TargetTriple.str(); 2308226633Sdim 2309228379Sdim // We use the existence of '/lib/<triple>' as a directory to detect some 2310228379Sdim // common linux triples that don't quite match the Clang triple for both 2311234353Sdim // 32-bit and 64-bit targets. Multiarch fixes its install triples to these 2312234353Sdim // regardless of what the actual target triple is. 2313239462Sdim case llvm::Triple::arm: 2314239462Sdim case llvm::Triple::thumb: 2315239462Sdim if (TargetTriple.getEnvironment() == llvm::Triple::GNUEABIHF) { 2316239462Sdim if (llvm::sys::fs::exists(SysRoot + "/lib/arm-linux-gnueabihf")) 2317239462Sdim return "arm-linux-gnueabihf"; 2318239462Sdim } else { 2319239462Sdim if (llvm::sys::fs::exists(SysRoot + "/lib/arm-linux-gnueabi")) 2320239462Sdim return "arm-linux-gnueabi"; 2321239462Sdim } 2322239462Sdim return TargetTriple.str(); 2323228379Sdim case llvm::Triple::x86: 2324228379Sdim if (llvm::sys::fs::exists(SysRoot + "/lib/i386-linux-gnu")) 2325228379Sdim return "i386-linux-gnu"; 2326228379Sdim return TargetTriple.str(); 2327228379Sdim case llvm::Triple::x86_64: 2328228379Sdim if (llvm::sys::fs::exists(SysRoot + "/lib/x86_64-linux-gnu")) 2329228379Sdim return "x86_64-linux-gnu"; 2330228379Sdim return TargetTriple.str(); 2331249423Sdim case llvm::Triple::aarch64: 2332249423Sdim if (llvm::sys::fs::exists(SysRoot + "/lib/aarch64-linux-gnu")) 2333249423Sdim return "aarch64-linux-gnu"; 2334263508Sdim return TargetTriple.str(); 2335234353Sdim case llvm::Triple::mips: 2336234353Sdim if (llvm::sys::fs::exists(SysRoot + "/lib/mips-linux-gnu")) 2337234353Sdim return "mips-linux-gnu"; 2338234353Sdim return TargetTriple.str(); 2339234353Sdim case llvm::Triple::mipsel: 2340234353Sdim if (llvm::sys::fs::exists(SysRoot + "/lib/mipsel-linux-gnu")) 2341234353Sdim return "mipsel-linux-gnu"; 2342234353Sdim return TargetTriple.str(); 2343234353Sdim case llvm::Triple::ppc: 2344249423Sdim if (llvm::sys::fs::exists(SysRoot + "/lib/powerpc-linux-gnuspe")) 2345249423Sdim return "powerpc-linux-gnuspe"; 2346234353Sdim if (llvm::sys::fs::exists(SysRoot + "/lib/powerpc-linux-gnu")) 2347234353Sdim return "powerpc-linux-gnu"; 2348234353Sdim return TargetTriple.str(); 2349234353Sdim case llvm::Triple::ppc64: 2350234353Sdim if (llvm::sys::fs::exists(SysRoot + "/lib/powerpc64-linux-gnu")) 2351234353Sdim return "powerpc64-linux-gnu"; 2352263508Sdim case llvm::Triple::ppc64le: 2353263508Sdim if (llvm::sys::fs::exists(SysRoot + "/lib/powerpc64le-linux-gnu")) 2354263508Sdim return "powerpc64le-linux-gnu"; 2355234353Sdim return TargetTriple.str(); 2356226633Sdim } 2357226633Sdim} 2358226633Sdim 2359234353Sdimstatic void addPathIfExists(Twine Path, ToolChain::path_list &Paths) { 2360234353Sdim if (llvm::sys::fs::exists(Path)) Paths.push_back(Path.str()); 2361234353Sdim} 2362234353Sdim 2363243830Sdimstatic StringRef getMultilibDir(const llvm::Triple &Triple, 2364243830Sdim const ArgList &Args) { 2365263508Sdim if (isMipsArch(Triple.getArch())) { 2366263508Sdim // lib32 directory has a special meaning on MIPS targets. 2367263508Sdim // It contains N32 ABI binaries. Use this folder if produce 2368263508Sdim // code for N32 ABI only. 2369263508Sdim if (hasMipsN32ABIArg(Args)) 2370263508Sdim return "lib32"; 2371263508Sdim return Triple.isArch32Bit() ? "lib" : "lib64"; 2372263508Sdim } 2373243830Sdim 2374263508Sdim // It happens that only x86 and PPC use the 'lib32' variant of multilib, and 2375263508Sdim // using that variant while targeting other architectures causes problems 2376263508Sdim // because the libraries are laid out in shared system roots that can't cope 2377263508Sdim // with a 'lib32' multilib search path being considered. So we only enable 2378263508Sdim // them when we know we may need it. 2379263508Sdim // 2380263508Sdim // FIXME: This is a bit of a hack. We should really unify this code for 2381263508Sdim // reasoning about multilib spellings with the lib dir spellings in the 2382263508Sdim // GCCInstallationDetector, but that is a more significant refactoring. 2383263508Sdim if (Triple.getArch() == llvm::Triple::x86 || 2384263508Sdim Triple.getArch() == llvm::Triple::ppc) 2385243830Sdim return "lib32"; 2386243830Sdim 2387243830Sdim return Triple.isArch32Bit() ? "lib" : "lib64"; 2388243830Sdim} 2389243830Sdim 2390234353SdimLinux::Linux(const Driver &D, const llvm::Triple &Triple, const ArgList &Args) 2391234353Sdim : Generic_ELF(D, Triple, Args) { 2392263508Sdim GCCInstallation.init(Triple, Args); 2393234353Sdim llvm::Triple::ArchType Arch = Triple.getArch(); 2394263508Sdim std::string SysRoot = computeSysRoot(); 2395226633Sdim 2396263508Sdim // Cross-compiling binutils and GCC installations (vanilla and openSUSE at 2397263508Sdim // least) put various tools in a triple-prefixed directory off of the parent 2398263508Sdim // of the GCC installation. We use the GCC triple here to ensure that we end 2399263508Sdim // up with tools that support the same amount of cross compiling as the 2400263508Sdim // detected GCC installation. For example, if we find a GCC installation 2401263508Sdim // targeting x86_64, but it is a bi-arch GCC installation, it can also be 2402263508Sdim // used to target i386. 2403263508Sdim // FIXME: This seems unlikely to be Linux-specific. 2404226633Sdim ToolChain::path_list &PPaths = getProgramPaths(); 2405228379Sdim PPaths.push_back(Twine(GCCInstallation.getParentLibPath() + "/../" + 2406234353Sdim GCCInstallation.getTriple().str() + "/bin").str()); 2407226633Sdim 2408226633Sdim Linker = GetProgramPath("ld"); 2409226633Sdim 2410249423Sdim Distro Distro = DetectDistro(Arch); 2411218893Sdim 2412263508Sdim if (IsOpenSUSE(Distro) || IsUbuntu(Distro)) { 2413218893Sdim ExtraOpts.push_back("-z"); 2414218893Sdim ExtraOpts.push_back("relro"); 2415218893Sdim } 2416218893Sdim 2417221345Sdim if (Arch == llvm::Triple::arm || Arch == llvm::Triple::thumb) 2418218893Sdim ExtraOpts.push_back("-X"); 2419218893Sdim 2420243830Sdim const bool IsAndroid = Triple.getEnvironment() == llvm::Triple::Android; 2421251662Sdim const bool IsMips = isMipsArch(Arch); 2422218893Sdim 2423251662Sdim if (IsMips && !SysRoot.empty()) 2424251662Sdim ExtraOpts.push_back("--sysroot=" + SysRoot); 2425251662Sdim 2426234353Sdim // Do not use 'gnu' hash style for Mips targets because .gnu.hash 2427234353Sdim // and the MIPS ABI require .dynsym to be sorted in different ways. 2428234353Sdim // .gnu.hash needs symbols to be grouped by hash code whereas the MIPS 2429234353Sdim // ABI requires a mapping between the GOT and the symbol table. 2430234353Sdim // Android loader does not support .gnu.hash. 2431251662Sdim if (!IsMips && !IsAndroid) { 2432263508Sdim if (IsRedhat(Distro) || IsOpenSUSE(Distro) || 2433234353Sdim (IsUbuntu(Distro) && Distro >= UbuntuMaverick)) 2434234353Sdim ExtraOpts.push_back("--hash-style=gnu"); 2435234353Sdim 2436263508Sdim if (IsDebian(Distro) || IsOpenSUSE(Distro) || Distro == UbuntuLucid || 2437234353Sdim Distro == UbuntuJaunty || Distro == UbuntuKarmic) 2438234353Sdim ExtraOpts.push_back("--hash-style=both"); 2439234353Sdim } 2440234353Sdim 2441223017Sdim if (IsRedhat(Distro)) 2442218893Sdim ExtraOpts.push_back("--no-add-needed"); 2443218893Sdim 2444223017Sdim if (Distro == DebianSqueeze || Distro == DebianWheezy || 2445263508Sdim Distro == DebianJessie || IsOpenSUSE(Distro) || 2446223017Sdim (IsRedhat(Distro) && Distro != RHEL4 && Distro != RHEL5) || 2447234353Sdim (IsUbuntu(Distro) && Distro >= UbuntuKarmic)) 2448218893Sdim ExtraOpts.push_back("--build-id"); 2449218893Sdim 2450263508Sdim if (IsOpenSUSE(Distro)) 2451223017Sdim ExtraOpts.push_back("--enable-new-dtags"); 2452223017Sdim 2453226633Sdim // The selection of paths to try here is designed to match the patterns which 2454226633Sdim // the GCC driver itself uses, as this is part of the GCC-compatible driver. 2455226633Sdim // This was determined by running GCC in a fake filesystem, creating all 2456226633Sdim // possible permutations of these directories, and seeing which ones it added 2457226633Sdim // to the link paths. 2458226633Sdim path_list &Paths = getFilePaths(); 2459219077Sdim 2460243830Sdim const std::string Multilib = getMultilibDir(Triple, Args); 2461228379Sdim const std::string MultiarchTriple = getMultiarchTriple(Triple, SysRoot); 2462226633Sdim 2463228379Sdim // Add the multilib suffixed paths where they are available. 2464228379Sdim if (GCCInstallation.isValid()) { 2465234353Sdim const llvm::Triple &GCCTriple = GCCInstallation.getTriple(); 2466228379Sdim const std::string &LibPath = GCCInstallation.getParentLibPath(); 2467234353Sdim 2468263508Sdim // Sourcery CodeBench MIPS toolchain holds some libraries under 2469263508Sdim // a biarch-like suffix of the GCC installation. 2470263508Sdim // 2471263508Sdim // FIXME: It would be cleaner to model this as a variant of bi-arch. IE, 2472263508Sdim // instead of a '64' biarch suffix it would be 'el' or something. 2473263508Sdim if (IsAndroid && IsMips && isMips32r2(Args)) { 2474263508Sdim assert(GCCInstallation.getBiarchSuffix().empty() && 2475263508Sdim "Unexpected bi-arch suffix"); 2476263508Sdim addPathIfExists(GCCInstallation.getInstallPath() + "/mips-r2", Paths); 2477263508Sdim } else { 2478243830Sdim addPathIfExists((GCCInstallation.getInstallPath() + 2479263508Sdim GCCInstallation.getMIPSABIDirSuffix() + 2480263508Sdim GCCInstallation.getBiarchSuffix()), 2481243830Sdim Paths); 2482263508Sdim } 2483243830Sdim 2484263508Sdim // GCC cross compiling toolchains will install target libraries which ship 2485263508Sdim // as part of the toolchain under <prefix>/<triple>/<libdir> rather than as 2486263508Sdim // any part of the GCC installation in 2487263508Sdim // <prefix>/<libdir>/gcc/<triple>/<version>. This decision is somewhat 2488263508Sdim // debatable, but is the reality today. We need to search this tree even 2489263508Sdim // when we have a sysroot somewhere else. It is the responsibility of 2490263508Sdim // whomever is doing the cross build targetting a sysroot using a GCC 2491263508Sdim // installation that is *not* within the system root to ensure two things: 2492263508Sdim // 2493263508Sdim // 1) Any DSOs that are linked in from this tree or from the install path 2494263508Sdim // above must be preasant on the system root and found via an 2495263508Sdim // appropriate rpath. 2496263508Sdim // 2) There must not be libraries installed into 2497263508Sdim // <prefix>/<triple>/<libdir> unless they should be preferred over 2498263508Sdim // those within the system root. 2499263508Sdim // 2500263508Sdim // Note that this matches the GCC behavior. See the below comment for where 2501263508Sdim // Clang diverges from GCC's behavior. 2502263508Sdim addPathIfExists(LibPath + "/../" + GCCTriple.str() + "/lib/../" + Multilib + 2503263508Sdim GCCInstallation.getMIPSABIDirSuffix(), 2504263508Sdim Paths); 2505263508Sdim 2506234353Sdim // If the GCC installation we found is inside of the sysroot, we want to 2507234353Sdim // prefer libraries installed in the parent prefix of the GCC installation. 2508234353Sdim // It is important to *not* use these paths when the GCC installation is 2509234982Sdim // outside of the system root as that can pick up unintended libraries. 2510234353Sdim // This usually happens when there is an external cross compiler on the 2511234353Sdim // host system, and a more minimal sysroot available that is the target of 2512263508Sdim // the cross. Note that GCC does include some of these directories in some 2513263508Sdim // configurations but this seems somewhere between questionable and simply 2514263508Sdim // a bug. 2515234353Sdim if (StringRef(LibPath).startswith(SysRoot)) { 2516234353Sdim addPathIfExists(LibPath + "/" + MultiarchTriple, Paths); 2517234353Sdim addPathIfExists(LibPath + "/../" + Multilib, Paths); 2518234353Sdim } 2519228379Sdim } 2520228379Sdim addPathIfExists(SysRoot + "/lib/" + MultiarchTriple, Paths); 2521228379Sdim addPathIfExists(SysRoot + "/lib/../" + Multilib, Paths); 2522228379Sdim addPathIfExists(SysRoot + "/usr/lib/" + MultiarchTriple, Paths); 2523228379Sdim addPathIfExists(SysRoot + "/usr/lib/../" + Multilib, Paths); 2524226633Sdim 2525263508Sdim // Try walking via the GCC triple path in case of biarch or multiarch GCC 2526228379Sdim // installations with strange symlinks. 2527263508Sdim if (GCCInstallation.isValid()) { 2528234353Sdim addPathIfExists(SysRoot + "/usr/lib/" + GCCInstallation.getTriple().str() + 2529228379Sdim "/../../" + Multilib, Paths); 2530226633Sdim 2531263508Sdim // Add the non-multilib suffixed paths (if potentially different). 2532226633Sdim const std::string &LibPath = GCCInstallation.getParentLibPath(); 2533234353Sdim const llvm::Triple &GCCTriple = GCCInstallation.getTriple(); 2534263508Sdim if (!GCCInstallation.getBiarchSuffix().empty()) 2535263508Sdim addPathIfExists(GCCInstallation.getInstallPath() + 2536263508Sdim GCCInstallation.getMIPSABIDirSuffix(), Paths); 2537234353Sdim 2538263508Sdim // See comments above on the multilib variant for details of why this is 2539263508Sdim // included even from outside the sysroot. 2540263508Sdim addPathIfExists(LibPath + "/../" + GCCTriple.str() + 2541263508Sdim "/lib" + GCCInstallation.getMIPSABIDirSuffix(), Paths); 2542263508Sdim 2543263508Sdim // See comments above on the multilib variant for details of why this is 2544263508Sdim // only included from within the sysroot. 2545263508Sdim if (StringRef(LibPath).startswith(SysRoot)) 2546234353Sdim addPathIfExists(LibPath, Paths); 2547226633Sdim } 2548226633Sdim addPathIfExists(SysRoot + "/lib", Paths); 2549226633Sdim addPathIfExists(SysRoot + "/usr/lib", Paths); 2550263508Sdim} 2551251662Sdim 2552263508Sdimbool FreeBSD::HasNativeLLVMSupport() const { 2553263508Sdim return true; 2554218893Sdim} 2555218893Sdim 2556218893Sdimbool Linux::HasNativeLLVMSupport() const { 2557218893Sdim return true; 2558218893Sdim} 2559218893Sdim 2560249423SdimTool *Linux::buildLinker() const { 2561249423Sdim return new tools::gnutools::Link(*this); 2562249423Sdim} 2563212904Sdim 2564249423SdimTool *Linux::buildAssembler() const { 2565249423Sdim return new tools::gnutools::Assemble(*this); 2566212904Sdim} 2567212904Sdim 2568249423Sdimvoid Linux::addClangTargetOptions(const ArgList &DriverArgs, 2569249423Sdim ArgStringList &CC1Args) const { 2570239462Sdim const Generic_GCC::GCCVersion &V = GCCInstallation.getVersion(); 2571263508Sdim bool UseInitArrayDefault = 2572263508Sdim !V.isOlderThan(4, 7, 0) || 2573249423Sdim getTriple().getArch() == llvm::Triple::aarch64 || 2574249423Sdim getTriple().getEnvironment() == llvm::Triple::Android; 2575249423Sdim if (DriverArgs.hasFlag(options::OPT_fuse_init_array, 2576249423Sdim options::OPT_fno_use_init_array, 2577249423Sdim UseInitArrayDefault)) 2578239462Sdim CC1Args.push_back("-fuse-init-array"); 2579239462Sdim} 2580239462Sdim 2581263508Sdimstd::string Linux::computeSysRoot() const { 2582251662Sdim if (!getDriver().SysRoot.empty()) 2583251662Sdim return getDriver().SysRoot; 2584251662Sdim 2585251662Sdim if (!GCCInstallation.isValid() || !isMipsArch(getTriple().getArch())) 2586251662Sdim return std::string(); 2587251662Sdim 2588263508Sdim // Standalone MIPS toolchains use different names for sysroot folder 2589263508Sdim // and put it into different places. Here we try to check some known 2590263508Sdim // variants. 2591251662Sdim 2592263508Sdim const StringRef InstallDir = GCCInstallation.getInstallPath(); 2593263508Sdim const StringRef TripleStr = GCCInstallation.getTriple().str(); 2594263508Sdim const StringRef MIPSABIDirSuffix = GCCInstallation.getMIPSABIDirSuffix(); 2595263508Sdim 2596263508Sdim std::string Path = (InstallDir + "/../../../../" + TripleStr + "/libc" + 2597263508Sdim MIPSABIDirSuffix).str(); 2598263508Sdim 2599263508Sdim if (llvm::sys::fs::exists(Path)) 2600263508Sdim return Path; 2601263508Sdim 2602263508Sdim Path = (InstallDir + "/../../../../sysroot" + MIPSABIDirSuffix).str(); 2603263508Sdim 2604263508Sdim if (llvm::sys::fs::exists(Path)) 2605263508Sdim return Path; 2606263508Sdim 2607263508Sdim return std::string(); 2608251662Sdim} 2609251662Sdim 2610228379Sdimvoid Linux::AddClangSystemIncludeArgs(const ArgList &DriverArgs, 2611228379Sdim ArgStringList &CC1Args) const { 2612228379Sdim const Driver &D = getDriver(); 2613263508Sdim std::string SysRoot = computeSysRoot(); 2614228379Sdim 2615228379Sdim if (DriverArgs.hasArg(options::OPT_nostdinc)) 2616228379Sdim return; 2617228379Sdim 2618228379Sdim if (!DriverArgs.hasArg(options::OPT_nostdlibinc)) 2619251662Sdim addSystemInclude(DriverArgs, CC1Args, SysRoot + "/usr/local/include"); 2620228379Sdim 2621228379Sdim if (!DriverArgs.hasArg(options::OPT_nobuiltininc)) { 2622263508Sdim SmallString<128> P(D.ResourceDir); 2623263508Sdim llvm::sys::path::append(P, "include"); 2624228379Sdim addSystemInclude(DriverArgs, CC1Args, P.str()); 2625228379Sdim } 2626228379Sdim 2627228379Sdim if (DriverArgs.hasArg(options::OPT_nostdlibinc)) 2628228379Sdim return; 2629228379Sdim 2630228379Sdim // Check for configure-time C include directories. 2631228379Sdim StringRef CIncludeDirs(C_INCLUDE_DIRS); 2632228379Sdim if (CIncludeDirs != "") { 2633228379Sdim SmallVector<StringRef, 5> dirs; 2634228379Sdim CIncludeDirs.split(dirs, ":"); 2635228379Sdim for (SmallVectorImpl<StringRef>::iterator I = dirs.begin(), E = dirs.end(); 2636228379Sdim I != E; ++I) { 2637251662Sdim StringRef Prefix = llvm::sys::path::is_absolute(*I) ? SysRoot : ""; 2638228379Sdim addExternCSystemInclude(DriverArgs, CC1Args, Prefix + *I); 2639228379Sdim } 2640228379Sdim return; 2641228379Sdim } 2642228379Sdim 2643228379Sdim // Lacking those, try to detect the correct set of system includes for the 2644228379Sdim // target triple. 2645228379Sdim 2646251662Sdim // Sourcery CodeBench and modern FSF Mips toolchains put extern C 2647251662Sdim // system includes under three additional directories. 2648251662Sdim if (GCCInstallation.isValid() && isMipsArch(getTriple().getArch())) { 2649263508Sdim addExternCSystemIncludeIfExists( 2650263508Sdim DriverArgs, CC1Args, GCCInstallation.getInstallPath() + "/include"); 2651251662Sdim 2652263508Sdim addExternCSystemIncludeIfExists( 2653263508Sdim DriverArgs, CC1Args, 2654263508Sdim GCCInstallation.getInstallPath() + "/../../../../" + 2655263508Sdim GCCInstallation.getTriple().str() + "/libc/usr/include"); 2656263508Sdim 2657263508Sdim addExternCSystemIncludeIfExists( 2658263508Sdim DriverArgs, CC1Args, 2659263508Sdim GCCInstallation.getInstallPath() + "/../../../../sysroot/usr/include"); 2660251662Sdim } 2661251662Sdim 2662228379Sdim // Implement generic Debian multiarch support. 2663228379Sdim const StringRef X86_64MultiarchIncludeDirs[] = { 2664228379Sdim "/usr/include/x86_64-linux-gnu", 2665228379Sdim 2666228379Sdim // FIXME: These are older forms of multiarch. It's not clear that they're 2667228379Sdim // in use in any released version of Debian, so we should consider 2668228379Sdim // removing them. 2669263508Sdim "/usr/include/i686-linux-gnu/64", "/usr/include/i486-linux-gnu/64" 2670228379Sdim }; 2671228379Sdim const StringRef X86MultiarchIncludeDirs[] = { 2672228379Sdim "/usr/include/i386-linux-gnu", 2673228379Sdim 2674228379Sdim // FIXME: These are older forms of multiarch. It's not clear that they're 2675228379Sdim // in use in any released version of Debian, so we should consider 2676228379Sdim // removing them. 2677263508Sdim "/usr/include/x86_64-linux-gnu/32", "/usr/include/i686-linux-gnu", 2678228379Sdim "/usr/include/i486-linux-gnu" 2679228379Sdim }; 2680249423Sdim const StringRef AArch64MultiarchIncludeDirs[] = { 2681249423Sdim "/usr/include/aarch64-linux-gnu" 2682249423Sdim }; 2683228379Sdim const StringRef ARMMultiarchIncludeDirs[] = { 2684228379Sdim "/usr/include/arm-linux-gnueabi" 2685228379Sdim }; 2686239462Sdim const StringRef ARMHFMultiarchIncludeDirs[] = { 2687239462Sdim "/usr/include/arm-linux-gnueabihf" 2688239462Sdim }; 2689234353Sdim const StringRef MIPSMultiarchIncludeDirs[] = { 2690234353Sdim "/usr/include/mips-linux-gnu" 2691234353Sdim }; 2692234353Sdim const StringRef MIPSELMultiarchIncludeDirs[] = { 2693234353Sdim "/usr/include/mipsel-linux-gnu" 2694234353Sdim }; 2695234353Sdim const StringRef PPCMultiarchIncludeDirs[] = { 2696234353Sdim "/usr/include/powerpc-linux-gnu" 2697234353Sdim }; 2698234353Sdim const StringRef PPC64MultiarchIncludeDirs[] = { 2699234353Sdim "/usr/include/powerpc64-linux-gnu" 2700234353Sdim }; 2701228379Sdim ArrayRef<StringRef> MultiarchIncludeDirs; 2702228379Sdim if (getTriple().getArch() == llvm::Triple::x86_64) { 2703228379Sdim MultiarchIncludeDirs = X86_64MultiarchIncludeDirs; 2704228379Sdim } else if (getTriple().getArch() == llvm::Triple::x86) { 2705228379Sdim MultiarchIncludeDirs = X86MultiarchIncludeDirs; 2706249423Sdim } else if (getTriple().getArch() == llvm::Triple::aarch64) { 2707249423Sdim MultiarchIncludeDirs = AArch64MultiarchIncludeDirs; 2708228379Sdim } else if (getTriple().getArch() == llvm::Triple::arm) { 2709239462Sdim if (getTriple().getEnvironment() == llvm::Triple::GNUEABIHF) 2710239462Sdim MultiarchIncludeDirs = ARMHFMultiarchIncludeDirs; 2711239462Sdim else 2712239462Sdim MultiarchIncludeDirs = ARMMultiarchIncludeDirs; 2713234353Sdim } else if (getTriple().getArch() == llvm::Triple::mips) { 2714234353Sdim MultiarchIncludeDirs = MIPSMultiarchIncludeDirs; 2715234353Sdim } else if (getTriple().getArch() == llvm::Triple::mipsel) { 2716234353Sdim MultiarchIncludeDirs = MIPSELMultiarchIncludeDirs; 2717234353Sdim } else if (getTriple().getArch() == llvm::Triple::ppc) { 2718234353Sdim MultiarchIncludeDirs = PPCMultiarchIncludeDirs; 2719234353Sdim } else if (getTriple().getArch() == llvm::Triple::ppc64) { 2720234353Sdim MultiarchIncludeDirs = PPC64MultiarchIncludeDirs; 2721228379Sdim } 2722228379Sdim for (ArrayRef<StringRef>::iterator I = MultiarchIncludeDirs.begin(), 2723228379Sdim E = MultiarchIncludeDirs.end(); 2724228379Sdim I != E; ++I) { 2725251662Sdim if (llvm::sys::fs::exists(SysRoot + *I)) { 2726251662Sdim addExternCSystemInclude(DriverArgs, CC1Args, SysRoot + *I); 2727228379Sdim break; 2728228379Sdim } 2729228379Sdim } 2730228379Sdim 2731228379Sdim if (getTriple().getOS() == llvm::Triple::RTEMS) 2732228379Sdim return; 2733228379Sdim 2734234353Sdim // Add an include of '/include' directly. This isn't provided by default by 2735234353Sdim // system GCCs, but is often used with cross-compiling GCCs, and harmless to 2736234353Sdim // add even when Clang is acting as-if it were a system compiler. 2737251662Sdim addExternCSystemInclude(DriverArgs, CC1Args, SysRoot + "/include"); 2738234353Sdim 2739251662Sdim addExternCSystemInclude(DriverArgs, CC1Args, SysRoot + "/usr/include"); 2740228379Sdim} 2741228379Sdim 2742249423Sdim/// \brief Helper to add the three variant paths for a libstdc++ installation. 2743234353Sdim/*static*/ bool Linux::addLibStdCXXIncludePaths(Twine Base, Twine TargetArchDir, 2744234353Sdim const ArgList &DriverArgs, 2745234353Sdim ArgStringList &CC1Args) { 2746228379Sdim if (!llvm::sys::fs::exists(Base)) 2747228379Sdim return false; 2748228379Sdim addSystemInclude(DriverArgs, CC1Args, Base); 2749228379Sdim addSystemInclude(DriverArgs, CC1Args, Base + "/" + TargetArchDir); 2750228379Sdim addSystemInclude(DriverArgs, CC1Args, Base + "/backward"); 2751228379Sdim return true; 2752228379Sdim} 2753228379Sdim 2754249423Sdim/// \brief Helper to add an extra variant path for an (Ubuntu) multilib 2755249423Sdim/// libstdc++ installation. 2756249423Sdim/*static*/ bool Linux::addLibStdCXXIncludePaths(Twine Base, Twine Suffix, 2757249423Sdim Twine TargetArchDir, 2758263508Sdim Twine BiarchSuffix, 2759263508Sdim Twine MIPSABIDirSuffix, 2760249423Sdim const ArgList &DriverArgs, 2761249423Sdim ArgStringList &CC1Args) { 2762263508Sdim if (!addLibStdCXXIncludePaths(Base + Suffix, 2763263508Sdim TargetArchDir + MIPSABIDirSuffix + BiarchSuffix, 2764249423Sdim DriverArgs, CC1Args)) 2765249423Sdim return false; 2766249423Sdim 2767249423Sdim addSystemInclude(DriverArgs, CC1Args, Base + "/" + TargetArchDir + Suffix 2768263508Sdim + MIPSABIDirSuffix + BiarchSuffix); 2769249423Sdim return true; 2770249423Sdim} 2771249423Sdim 2772228379Sdimvoid Linux::AddClangCXXStdlibIncludeArgs(const ArgList &DriverArgs, 2773228379Sdim ArgStringList &CC1Args) const { 2774228379Sdim if (DriverArgs.hasArg(options::OPT_nostdlibinc) || 2775228379Sdim DriverArgs.hasArg(options::OPT_nostdincxx)) 2776228379Sdim return; 2777228379Sdim 2778228379Sdim // Check if libc++ has been enabled and provide its include paths if so. 2779228379Sdim if (GetCXXStdlibType(DriverArgs) == ToolChain::CST_Libcxx) { 2780228379Sdim // libc++ is always installed at a fixed path on Linux currently. 2781228379Sdim addSystemInclude(DriverArgs, CC1Args, 2782228379Sdim getDriver().SysRoot + "/usr/include/c++/v1"); 2783228379Sdim return; 2784228379Sdim } 2785228379Sdim 2786234353Sdim // We need a detected GCC installation on Linux to provide libstdc++'s 2787234353Sdim // headers. We handled the libc++ case above. 2788234353Sdim if (!GCCInstallation.isValid()) 2789228379Sdim return; 2790228379Sdim 2791228379Sdim // By default, look for the C++ headers in an include directory adjacent to 2792228379Sdim // the lib directory of the GCC installation. Note that this is expect to be 2793228379Sdim // equivalent to '/usr/include/c++/X.Y' in almost all cases. 2794228379Sdim StringRef LibDir = GCCInstallation.getParentLibPath(); 2795228379Sdim StringRef InstallDir = GCCInstallation.getInstallPath(); 2796243830Sdim StringRef TripleStr = GCCInstallation.getTriple().str(); 2797263508Sdim StringRef MIPSABIDirSuffix = GCCInstallation.getMIPSABIDirSuffix(); 2798263508Sdim StringRef BiarchSuffix = GCCInstallation.getBiarchSuffix(); 2799263508Sdim const GCCVersion &Version = GCCInstallation.getVersion(); 2800243830Sdim 2801263508Sdim if (addLibStdCXXIncludePaths(LibDir.str() + "/../include", 2802263508Sdim "/c++/" + Version.Text, TripleStr, BiarchSuffix, 2803263508Sdim MIPSABIDirSuffix, DriverArgs, CC1Args)) 2804249423Sdim return; 2805249423Sdim 2806243830Sdim const std::string IncludePathCandidates[] = { 2807228379Sdim // Gentoo is weird and places its headers inside the GCC install, so if the 2808263508Sdim // first attempt to find the headers fails, try these patterns. 2809263508Sdim InstallDir.str() + "/include/g++-v" + Version.MajorStr + "." + 2810263508Sdim Version.MinorStr, 2811263508Sdim InstallDir.str() + "/include/g++-v" + Version.MajorStr, 2812243830Sdim // Android standalone toolchain has C++ headers in yet another place. 2813263508Sdim LibDir.str() + "/../" + TripleStr.str() + "/include/c++/" + Version.Text, 2814243830Sdim // Freescale SDK C++ headers are directly in <sysroot>/usr/include/c++, 2815243830Sdim // without a subdirectory corresponding to the gcc version. 2816243830Sdim LibDir.str() + "/../include/c++", 2817243830Sdim }; 2818243830Sdim 2819243830Sdim for (unsigned i = 0; i < llvm::array_lengthof(IncludePathCandidates); ++i) { 2820263508Sdim if (addLibStdCXXIncludePaths(IncludePathCandidates[i], 2821263508Sdim TripleStr + MIPSABIDirSuffix + BiarchSuffix, 2822263508Sdim DriverArgs, CC1Args)) 2823243830Sdim break; 2824228379Sdim } 2825228379Sdim} 2826228379Sdim 2827251662Sdimbool Linux::isPIEDefault() const { 2828263508Sdim return getSanitizerArgs().hasZeroBaseShadow(); 2829251662Sdim} 2830251662Sdim 2831193326Sed/// DragonFly - DragonFly tool chain which can call as(1) and ld(1) directly. 2832193326Sed 2833234353SdimDragonFly::DragonFly(const Driver &D, const llvm::Triple& Triple, const ArgList &Args) 2834234353Sdim : Generic_ELF(D, Triple, Args) { 2835193326Sed 2836193326Sed // Path mangling to find libexec 2837212904Sdim getProgramPaths().push_back(getDriver().getInstalledDir()); 2838221345Sdim if (getDriver().getInstalledDir() != getDriver().Dir) 2839212904Sdim getProgramPaths().push_back(getDriver().Dir); 2840193326Sed 2841201361Srdivacky getFilePaths().push_back(getDriver().Dir + "/../lib"); 2842193326Sed getFilePaths().push_back("/usr/lib"); 2843251662Sdim if (llvm::sys::fs::exists("/usr/lib/gcc47")) 2844251662Sdim getFilePaths().push_back("/usr/lib/gcc47"); 2845251662Sdim else 2846251662Sdim getFilePaths().push_back("/usr/lib/gcc44"); 2847193326Sed} 2848193326Sed 2849249423SdimTool *DragonFly::buildAssembler() const { 2850249423Sdim return new tools::dragonfly::Assemble(*this); 2851249423Sdim} 2852193326Sed 2853249423SdimTool *DragonFly::buildLinker() const { 2854249423Sdim return new tools::dragonfly::Link(*this); 2855193326Sed} 2856263508Sdim 2857263508Sdim 2858263508Sdim/// XCore tool chain 2859263508SdimXCore::XCore(const Driver &D, const llvm::Triple &Triple, 2860263508Sdim const ArgList &Args) : ToolChain(D, Triple, Args) { 2861263508Sdim // ProgramPaths are found via 'PATH' environment variable. 2862263508Sdim} 2863263508Sdim 2864263508SdimTool *XCore::buildAssembler() const { 2865263508Sdim return new tools::XCore::Assemble(*this); 2866263508Sdim} 2867263508Sdim 2868263508SdimTool *XCore::buildLinker() const { 2869263508Sdim return new tools::XCore::Link(*this); 2870263508Sdim} 2871263508Sdim 2872263508Sdimbool XCore::isPICDefault() const { 2873263508Sdim return false; 2874263508Sdim} 2875263508Sdim 2876263508Sdimbool XCore::isPIEDefault() const { 2877263508Sdim return false; 2878263508Sdim} 2879263508Sdim 2880263508Sdimbool XCore::isPICDefaultForced() const { 2881263508Sdim return false; 2882263508Sdim} 2883263508Sdim 2884263508Sdimbool XCore::SupportsProfiling() const { 2885263508Sdim return false; 2886263508Sdim} 2887263508Sdim 2888263508Sdimbool XCore::hasBlocksRuntime() const { 2889263508Sdim return false; 2890263508Sdim} 2891263508Sdim 2892263508Sdim 2893263508Sdimvoid XCore::AddClangSystemIncludeArgs(const ArgList &DriverArgs, 2894263508Sdim ArgStringList &CC1Args) const { 2895263508Sdim if (DriverArgs.hasArg(options::OPT_nostdinc) || 2896263508Sdim DriverArgs.hasArg(options::OPT_nostdlibinc)) 2897263508Sdim return; 2898263508Sdim if (const char *cl_include_dir = getenv("XCC_C_INCLUDE_PATH")) { 2899263508Sdim SmallVector<StringRef, 4> Dirs; 2900263508Sdim const char EnvPathSeparatorStr[] = {llvm::sys::EnvPathSeparator,'\0'}; 2901263508Sdim StringRef(cl_include_dir).split(Dirs, StringRef(EnvPathSeparatorStr)); 2902263508Sdim ArrayRef<StringRef> DirVec(Dirs); 2903263508Sdim addSystemIncludes(DriverArgs, CC1Args, DirVec); 2904263508Sdim } 2905263508Sdim} 2906263508Sdim 2907263508Sdimvoid XCore::addClangTargetOptions(const llvm::opt::ArgList &DriverArgs, 2908263508Sdim llvm::opt::ArgStringList &CC1Args) const { 2909263508Sdim CC1Args.push_back("-nostdsysteminc"); 2910263508Sdim} 2911263508Sdim 2912263508Sdimvoid XCore::AddClangCXXStdlibIncludeArgs(const ArgList &DriverArgs, 2913263508Sdim ArgStringList &CC1Args) const { 2914263508Sdim if (DriverArgs.hasArg(options::OPT_nostdinc) || 2915263508Sdim DriverArgs.hasArg(options::OPT_nostdlibinc)) 2916263508Sdim return; 2917263508Sdim if (const char *cl_include_dir = getenv("XCC_CPLUS_INCLUDE_PATH")) { 2918263508Sdim SmallVector<StringRef, 4> Dirs; 2919263508Sdim const char EnvPathSeparatorStr[] = {llvm::sys::EnvPathSeparator,'\0'}; 2920263508Sdim StringRef(cl_include_dir).split(Dirs, StringRef(EnvPathSeparatorStr)); 2921263508Sdim ArrayRef<StringRef> DirVec(Dirs); 2922263508Sdim addSystemIncludes(DriverArgs, CC1Args, DirVec); 2923263508Sdim } 2924263508Sdim} 2925263508Sdim 2926263508Sdimvoid XCore::AddCXXStdlibLibArgs(const ArgList &Args, 2927263508Sdim ArgStringList &CmdArgs) const { 2928263508Sdim // We don't output any lib args. This is handled by xcc. 2929263508Sdim} 2930