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" 11252723Sdim#include "clang/Basic/ObjCRuntime.h" 12252723Sdim#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" 17263509Sdim#include "clang/Driver/SanitizerArgs.h" 18252723Sdim#include "llvm/ADT/STLExtras.h" 19212904Sdim#include "llvm/ADT/SmallString.h" 20193326Sed#include "llvm/ADT/StringExtras.h" 21226890Sdim#include "llvm/ADT/StringSwitch.h" 22263509Sdim#include "llvm/Option/Arg.h" 23263509Sdim#include "llvm/Option/ArgList.h" 24263509Sdim#include "llvm/Option/OptTable.h" 25263509Sdim#include "llvm/Option/Option.h" 26198092Srdivacky#include "llvm/Support/ErrorHandling.h" 27218893Sdim#include "llvm/Support/FileSystem.h" 28218893Sdim#include "llvm/Support/MemoryBuffer.h" 29252723Sdim#include "llvm/Support/Path.h" 30193326Sed#include "llvm/Support/raw_ostream.h" 31218893Sdim#include "llvm/Support/system_error.h" 32263509Sdim#include "llvm/Support/Program.h" 33193326Sed 34252723Sdim// FIXME: This needs to be listed last until we fix the broken include guards 35252723Sdim// in these files and the LLVM config.h files. 36252723Sdim#include "clang/Config/config.h" // for GCC_INSTALL_PREFIX 37245431Sdim 38193326Sed#include <cstdlib> // ::getenv 39193326Sed 40193326Sedusing namespace clang::driver; 41193326Sedusing namespace clang::driver::toolchains; 42226890Sdimusing namespace clang; 43263509Sdimusing namespace llvm::opt; 44193326Sed 45198092Srdivacky/// Darwin - Darwin tool chain for i386 and x86_64. 46193326Sed 47252723SdimDarwin::Darwin(const Driver &D, const llvm::Triple& Triple, const ArgList &Args) 48252723Sdim : ToolChain(D, Triple, Args), TargetInitialized(false) 49198092Srdivacky{ 50235633Sdim // Compute the initial Darwin version from the triple 51235633Sdim unsigned Major, Minor, Micro; 52235633Sdim if (!Triple.getMacOSXVersion(Major, Minor, Micro)) 53235633Sdim getDriver().Diag(diag::err_drv_invalid_darwin_version) << 54235633Sdim Triple.getOSName(); 55235633Sdim llvm::raw_string_ostream(MacosxVersionMin) 56235633Sdim << Major << '.' << Minor << '.' << Micro; 57212904Sdim 58235633Sdim // FIXME: DarwinVersion is only used to find GCC's libexec directory. 59235633Sdim // It should be removed when we stop supporting that. 60235633Sdim DarwinVersion[0] = Minor + 4; 61235633Sdim DarwinVersion[1] = Micro; 62235633Sdim DarwinVersion[2] = 0; 63245431Sdim 64245431Sdim // Compute the initial iOS version from the triple 65245431Sdim Triple.getiOSVersion(Major, Minor, Micro); 66245431Sdim llvm::raw_string_ostream(iOSVersionMin) 67245431Sdim << 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 84245431Sdim/// Darwin provides an ARC runtime starting in MacOS X 10.7 and iOS 5.0. 85245431SdimObjCRuntime Darwin::getDefaultObjCRuntime(bool isNonFragile) const { 86224145Sdim if (isTargetIPhoneOS()) 87245431Sdim return ObjCRuntime(ObjCRuntime::iOS, TargetVersion); 88245431Sdim if (isNonFragile) 89245431Sdim return ObjCRuntime(ObjCRuntime::MacOSX, TargetVersion); 90245431Sdim return ObjCRuntime(ObjCRuntime::FragileMacOSX, TargetVersion); 91224145Sdim} 92224145Sdim 93226890Sdim/// Darwin provides a blocks runtime starting in MacOS X 10.6 and iOS 3.2. 94226890Sdimbool Darwin::hasBlocksRuntime() const { 95226890Sdim if (isTargetIPhoneOS()) 96226890Sdim return !isIPhoneOSVersionLT(3, 2); 97226890Sdim else 98226890Sdim return !isMacosxVersionLT(10, 6); 99226890Sdim} 100202879Srdivacky 101226890Sdimstatic const char *GetArmArchForMArch(StringRef Value) { 102226890Sdim return llvm::StringSwitch<const char*>(Value) 103226890Sdim .Case("armv6k", "armv6") 104252723Sdim .Case("armv6m", "armv6m") 105226890Sdim .Case("armv5tej", "armv5") 106226890Sdim .Case("xscale", "xscale") 107226890Sdim .Case("armv4t", "armv4t") 108226890Sdim .Case("armv7", "armv7") 109226890Sdim .Cases("armv7a", "armv7-a", "armv7") 110226890Sdim .Cases("armv7r", "armv7-r", "armv7") 111252723Sdim .Cases("armv7em", "armv7e-m", "armv7em") 112245431Sdim .Cases("armv7f", "armv7-f", "armv7f") 113245431Sdim .Cases("armv7k", "armv7-k", "armv7k") 114252723Sdim .Cases("armv7m", "armv7-m", "armv7m") 115245431Sdim .Cases("armv7s", "armv7-s", "armv7s") 116226890Sdim .Default(0); 117202879Srdivacky} 118202879Srdivacky 119226890Sdimstatic const char *GetArmArchForMCpu(StringRef Value) { 120226890Sdim return llvm::StringSwitch<const char *>(Value) 121226890Sdim .Cases("arm9e", "arm946e-s", "arm966e-s", "arm968e-s", "arm926ej-s","armv5") 122226890Sdim .Cases("arm10e", "arm10tdmi", "armv5") 123226890Sdim .Cases("arm1020t", "arm1020e", "arm1022e", "arm1026ej-s", "armv5") 124226890Sdim .Case("xscale", "xscale") 125252723Sdim .Cases("arm1136j-s", "arm1136jf-s", "arm1176jz-s", "arm1176jzf-s", "armv6") 126252723Sdim .Case("cortex-m0", "armv6m") 127263509Sdim .Cases("cortex-a5", "cortex-a7", "cortex-a8", "armv7") 128263509Sdim .Cases("cortex-a9", "cortex-a12", "cortex-a15", "armv7") 129263509Sdim .Cases("cortex-r4", "cortex-r5", "armv7r") 130245431Sdim .Case("cortex-a9-mp", "armv7f") 131252723Sdim .Case("cortex-m3", "armv7m") 132252723Sdim .Case("cortex-m4", "armv7em") 133245431Sdim .Case("swift", "armv7s") 134226890Sdim .Default(0); 135202879Srdivacky} 136202879Srdivacky 137226890SdimStringRef 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)) 145245431Sdim if (const char *Arch = GetArmArchForMArch(A->getValue())) 146202879Srdivacky return Arch; 147202879Srdivacky 148202879Srdivacky if (const Arg *A = Args.getLastArg(options::OPT_mcpu_EQ)) 149245431Sdim if (const char *Arch = GetArmArchForMCpu(A->getValue())) 150202879Srdivacky return Arch; 151202879Srdivacky 152202879Srdivacky return "arm"; 153202879Srdivacky } 154202879Srdivacky } 155202879Srdivacky} 156202879Srdivacky 157198092SrdivackyDarwin::~Darwin() { 158193326Sed} 159193326Sed 160226890Sdimstd::string Darwin::ComputeEffectiveClangTriple(const ArgList &Args, 161226890Sdim types::ID InputType) const { 162226890Sdim 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 169263509Sdim if (Triple.getArchName() == "thumbv6m" || 170263509Sdim Triple.getArchName() == "thumbv7m" || 171263509Sdim Triple.getArchName() == "thumbv7em") { 172263509Sdim // OS is ios or macosx unless it's the v6m or v7m. 173263509Sdim Triple.setOS(llvm::Triple::Darwin); 174263509Sdim Triple.setEnvironment(llvm::Triple::EABI); 175263509Sdim } else { 176263509Sdim SmallString<16> Str; 177263509Sdim Str += isTargetIPhoneOS() ? "ios" : "macosx"; 178263509Sdim Str += getTargetVersion().getAsString(); 179263509Sdim Triple.setOSName(Str); 180263509Sdim } 181223017Sdim 182212904Sdim return Triple.getTriple(); 183212904Sdim} 184212904Sdim 185235633Sdimvoid Generic_ELF::anchor() {} 186235633Sdim 187252723SdimTool *Darwin::getTool(Action::ActionClass AC) const { 188252723Sdim switch (AC) { 189252723Sdim case Action::LipoJobClass: 190252723Sdim if (!Lipo) 191252723Sdim Lipo.reset(new tools::darwin::Lipo(*this)); 192252723Sdim return Lipo.get(); 193252723Sdim case Action::DsymutilJobClass: 194252723Sdim if (!Dsymutil) 195252723Sdim Dsymutil.reset(new tools::darwin::Dsymutil(*this)); 196252723Sdim return Dsymutil.get(); 197252723Sdim case Action::VerifyJobClass: 198252723Sdim if (!VerifyDebug) 199252723Sdim VerifyDebug.reset(new tools::darwin::VerifyDebug(*this)); 200252723Sdim return VerifyDebug.get(); 201252723Sdim default: 202252723Sdim return ToolChain::getTool(AC); 203245431Sdim } 204252723Sdim} 205193326Sed 206252723SdimTool *Darwin::buildLinker() const { 207252723Sdim return new tools::darwin::Link(*this); 208252723Sdim} 209208600Srdivacky 210252723SdimTool *Darwin::buildAssembler() const { 211252723Sdim return new tools::darwin::Assemble(*this); 212193326Sed} 213193326Sed 214252723SdimDarwinClang::DarwinClang(const Driver &D, const llvm::Triple& Triple, 215252723Sdim const ArgList &Args) 216252723Sdim : 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); 226226890Sdim} 227226890Sdim 228224145Sdimvoid DarwinClang::AddLinkARCArgs(const ArgList &Args, 229224145Sdim ArgStringList &CmdArgs) const { 230226890Sdim 231226890Sdim CmdArgs.push_back("-force_load"); 232263509Sdim SmallString<128> P(getDriver().ClangExecutable); 233263509Sdim llvm::sys::path::remove_filename(P); // 'clang' 234263509Sdim llvm::sys::path::remove_filename(P); // 'bin' 235263509Sdim llvm::sys::path::append(P, "lib", "arc", "libarclite_"); 236224145Sdim // Mash in the platform. 237235633Sdim if (isTargetIOSSimulator()) 238263509Sdim P += "iphonesimulator"; 239235633Sdim else if (isTargetIPhoneOS()) 240263509Sdim P += "iphoneos"; 241224145Sdim else 242263509Sdim P += "macosx"; 243263509Sdim P += ".a"; 244224145Sdim 245263509Sdim CmdArgs.push_back(Args.MakeArgString(P)); 246224145Sdim} 247224145Sdim 248224145Sdimvoid DarwinClang::AddLinkRuntimeLib(const ArgList &Args, 249226890Sdim ArgStringList &CmdArgs, 250252723Sdim const char *DarwinStaticLib, 251252723Sdim bool AlwaysLink) const { 252263509Sdim SmallString<128> P(getDriver().ResourceDir); 253263509Sdim llvm::sys::path::append(P, "lib", "darwin", DarwinStaticLib); 254226890Sdim 255224145Sdim // For now, allow missing resource libraries to support developers who may 256252723Sdim // not have compiler-rt checked out or integrated into their build (unless 257252723Sdim // we explicitly force linking with this library). 258263509Sdim 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 { 264235633Sdim // Darwin only supports the compiler-rt based runtime libraries. 265235633Sdim switch (GetRuntimeLibType(Args)) { 266235633Sdim case ToolChain::RLT_CompilerRT: 267235633Sdim break; 268235633Sdim default: 269235633Sdim getDriver().Diag(diag::err_drv_unsupported_rtlib_for_platform) 270245431Sdim << Args.getLastArg(options::OPT_rtlib_EQ)->getValue() << "darwin"; 271235633Sdim return; 272235633Sdim } 273235633Sdim 274202879Srdivacky // Darwin doesn't support real static executables, don't link any runtime 275202879Srdivacky // libraries with -static. 276245431Sdim if (Args.hasArg(options::OPT_static) || 277245431Sdim Args.hasArg(options::OPT_fapple_kext) || 278245431Sdim 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)) { 285226890Sdim getDriver().Diag(diag::err_drv_unsupported_opt) 286198092Srdivacky << A->getAsString(Args); 287198092Srdivacky return; 288198092Srdivacky } 289198092Srdivacky 290235633Sdim // If we are building profile support, link that library in. 291235633Sdim if (Args.hasArg(options::OPT_fprofile_arcs) || 292235633Sdim Args.hasArg(options::OPT_fprofile_generate) || 293235633Sdim Args.hasArg(options::OPT_fcreate_profile) || 294235633Sdim Args.hasArg(options::OPT_coverage)) { 295235633Sdim // Select the appropriate runtime library for the target. 296235633Sdim if (isTargetIPhoneOS()) { 297235633Sdim AddLinkRuntimeLib(Args, CmdArgs, "libclang_rt.profile_ios.a"); 298235633Sdim } else { 299235633Sdim AddLinkRuntimeLib(Args, CmdArgs, "libclang_rt.profile_osx.a"); 300235633Sdim } 301235633Sdim } 302235633Sdim 303263509Sdim const SanitizerArgs &Sanitize = getSanitizerArgs(); 304245431Sdim 305252723Sdim // Add Ubsan runtime library, if required. 306252723Sdim if (Sanitize.needsUbsanRt()) { 307263509Sdim // FIXME: Move this check to SanitizerArgs::filterUnsupportedKinds. 308252723Sdim if (isTargetIPhoneOS()) { 309252723Sdim getDriver().Diag(diag::err_drv_clang_unsupported_per_platform) 310252723Sdim << "-fsanitize=undefined"; 311252723Sdim } else { 312252723Sdim AddLinkRuntimeLib(Args, CmdArgs, "libclang_rt.ubsan_osx.a", true); 313252723Sdim 314252723Sdim // The Ubsan runtime library requires C++. 315252723Sdim AddCXXStdlibLibArgs(Args, CmdArgs); 316252723Sdim } 317252723Sdim } 318252723Sdim 319235633Sdim // Add ASAN runtime library, if required. Dynamic libraries and bundles 320235633Sdim // should not be linked with the runtime library. 321245431Sdim if (Sanitize.needsAsanRt()) { 322263509Sdim // FIXME: Move this check to SanitizerArgs::filterUnsupportedKinds. 323252723Sdim if (isTargetIPhoneOS() && !isTargetIOSSimulator()) { 324235633Sdim getDriver().Diag(diag::err_drv_clang_unsupported_per_platform) 325245431Sdim << "-fsanitize=address"; 326235633Sdim } else { 327263509Sdim if (!Args.hasArg(options::OPT_dynamiclib) && 328263509Sdim !Args.hasArg(options::OPT_bundle)) { 329252723Sdim // The ASAN runtime library requires C++. 330252723Sdim AddCXXStdlibLibArgs(Args, CmdArgs); 331252723Sdim } 332263509Sdim if (isTargetMacOS()) { 333263509Sdim AddLinkRuntimeLib(Args, CmdArgs, 334263509Sdim "libclang_rt.asan_osx_dynamic.dylib", 335263509Sdim true); 336263509Sdim } else { 337263509Sdim if (isTargetIOSSimulator()) { 338263509Sdim AddLinkRuntimeLib(Args, CmdArgs, 339263509Sdim "libclang_rt.asan_iossim_dynamic.dylib", 340263509Sdim true); 341263509Sdim } 342263509Sdim } 343235633Sdim } 344235633Sdim } 345235633Sdim 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. 354226890Sdim // Linking against libgcc_s.1 isn't needed for iOS 5.0+ 355226890Sdim if (isIPhoneOSVersionLT(5, 0) && !isTargetIOSSimulator()) 356226890Sdim 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 389245431Sdim // Support allowing the SDKROOT environment variable used by xcrun and other 390245431Sdim // Xcode tools to define the default sysroot, by making it the default for 391245431Sdim // isysroot. 392252723Sdim if (const Arg *A = Args.getLastArg(options::OPT_isysroot)) { 393252723Sdim // Warn if the path does not exist. 394263509Sdim if (!llvm::sys::fs::exists(A->getValue())) 395252723Sdim getDriver().Diag(clang::diag::warn_missing_sysroot) << A->getValue(); 396252723Sdim } else { 397245431Sdim if (char *env = ::getenv("SDKROOT")) { 398252723Sdim // We only use this value as the default if it is an absolute path, 399252723Sdim // exists, and it is not the root path. 400252723Sdim if (llvm::sys::path::is_absolute(env) && llvm::sys::fs::exists(env) && 401252723Sdim StringRef(env) != "/") { 402245431Sdim Args.append(Args.MakeSeparateArg( 403245431Sdim 0, Opts.getOption(options::OPT_isysroot), env)); 404245431Sdim } 405245431Sdim } 406245431Sdim } 407245431Sdim 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)) { 414226890Sdim 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) { 419226890Sdim 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) { 424226890Sdim // If no deployment target was specified on the command line, check for 425203955Srdivacky // environment defines. 426226890Sdim StringRef OSXTarget; 427226890Sdim StringRef iOSTarget; 428226890Sdim StringRef iOSSimTarget; 429226890Sdim if (char *env = ::getenv("MACOSX_DEPLOYMENT_TARGET")) 430226890Sdim OSXTarget = env; 431226890Sdim if (char *env = ::getenv("IPHONEOS_DEPLOYMENT_TARGET")) 432226890Sdim iOSTarget = env; 433226890Sdim if (char *env = ::getenv("IOS_SIMULATOR_DEPLOYMENT_TARGET")) 434226890Sdim iOSSimTarget = env; 435203955Srdivacky 436226890Sdim // If no '-miphoneos-version-min' specified on the command line and 437226890Sdim // IPHONEOS_DEPLOYMENT_TARGET is not defined, see if we can set the default 438235633Sdim // based on -isysroot. 439226890Sdim if (iOSTarget.empty()) { 440226890Sdim if (const Arg *A = Args.getLastArg(options::OPT_isysroot)) { 441226890Sdim StringRef first, second; 442245431Sdim StringRef isysroot = A->getValue(); 443226890Sdim llvm::tie(first, second) = isysroot.split(StringRef("SDKs/iPhoneOS")); 444226890Sdim if (second != "") 445226890Sdim iOSTarget = second.substr(0,3); 446226890Sdim } 447226890Sdim } 448203955Srdivacky 449226890Sdim // If no OSX or iOS target has been specified and we're compiling for armv7, 450226890Sdim // go ahead as assume we're targeting iOS. 451245431Sdim if (OSXTarget.empty() && iOSTarget.empty() && 452245431Sdim (getDarwinArchName(Args) == "armv7" || 453245431Sdim getDarwinArchName(Args) == "armv7s")) 454245431Sdim iOSTarget = iOSVersionMin; 455226890Sdim 456221345Sdim // Handle conflicting deployment targets 457193326Sed // 458203955Srdivacky // FIXME: Don't hardcode default here. 459221345Sdim 460221345Sdim // Do not allow conflicts with the iOS simulator target. 461226890Sdim if (!iOSSimTarget.empty() && (!OSXTarget.empty() || !iOSTarget.empty())) { 462226890Sdim getDriver().Diag(diag::err_drv_conflicting_deployment_targets) 463221345Sdim << "IOS_SIMULATOR_DEPLOYMENT_TARGET" 464226890Sdim << (!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. 470226890Sdim if (!OSXTarget.empty() && !iOSTarget.empty()) { 471203955Srdivacky if (getTriple().getArch() == llvm::Triple::arm || 472203955Srdivacky getTriple().getArch() == llvm::Triple::thumb) 473226890Sdim OSXTarget = ""; 474203955Srdivacky else 475226890Sdim iOSTarget = ""; 476203955Srdivacky } 477193326Sed 478226890Sdim if (!OSXTarget.empty()) { 479245431Sdim const Option O = Opts.getOption(options::OPT_mmacosx_version_min_EQ); 480212904Sdim OSXVersion = Args.MakeJoinedArg(0, O, OSXTarget); 481212904Sdim Args.append(OSXVersion); 482226890Sdim } else if (!iOSTarget.empty()) { 483245431Sdim const Option O = Opts.getOption(options::OPT_miphoneos_version_min_EQ); 484221345Sdim iOSVersion = Args.MakeJoinedArg(0, O, iOSTarget); 485221345Sdim Args.append(iOSVersion); 486226890Sdim } else if (!iOSSimTarget.empty()) { 487245431Sdim 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. 493245431Sdim 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)) { 502226890Sdim 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!"); 511245431Sdim if (!Driver::GetReleaseVersion(OSXVersion->getValue(), Major, Minor, 512203955Srdivacky Micro, HadExtra) || HadExtra || 513221345Sdim Major != 10 || Minor >= 100 || Micro >= 100) 514226890Sdim 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!"); 519245431Sdim if (!Driver::GetReleaseVersion(Version->getValue(), Major, Minor, 520203955Srdivacky Micro, HadExtra) || HadExtra || 521203955Srdivacky Major >= 10 || Minor >= 100 || Micro >= 100) 522226890Sdim 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)) { 556263509Sdim SmallString<128> P(A->getValue()); 557263509Sdim llvm::sys::path::append(P, "usr", "lib", "libstdc++.dylib"); 558218893Sdim 559263509Sdim if (!llvm::sys::fs::exists(P.str())) { 560263509Sdim llvm::sys::path::remove_filename(P); 561263509Sdim llvm::sys::path::append(P, "libstdc++.6.dylib"); 562263509Sdim 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. 570235633Sdim // FIXME: This should be removed someday when we don't have to care about 571235633Sdim // 10.6 and earlier, where /usr/lib/libstdc++.dylib does not exist. 572263509Sdim if (!llvm::sys::fs::exists("/usr/lib/libstdc++.dylib") && 573263509Sdim 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 592263509Sdim SmallString<128> P(getDriver().ResourceDir); 593263509Sdim llvm::sys::path::append(P, "lib", "darwin"); 594223017Sdim 595245431Sdim // Use the newer cc_kext for iOS ARM after 6.0. 596245431Sdim if (!isTargetIPhoneOS() || isTargetIOSSimulator() || 597245431Sdim !isIPhoneOSVersionLT(6, 0)) { 598263509Sdim llvm::sys::path::append(P, "libclang_rt.cc_kext.a"); 599245431Sdim } else { 600263509Sdim llvm::sys::path::append(P, "libclang_rt.cc_kext_ios5.a"); 601245431Sdim } 602245431Sdim 603218893Sdim // For now, allow missing resource libraries to support developers who may 604218893Sdim // not have compiler-rt checked out or integrated into their build. 605263509Sdim 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. 628245431Sdim llvm::Triple::ArchType XarchArch = 629245431Sdim tools::darwin::getArchTypeForDarwinArchName(A->getValue(0)); 630245431Sdim if (!(XarchArch == getArch() || 631245431Sdim (BoundArch && XarchArch == 632245431Sdim tools::darwin::getArchTypeForDarwinArchName(BoundArch)))) 633193326Sed continue; 634193326Sed 635218893Sdim Arg *OriginalArg = A; 636245431Sdim 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) { 649226890Sdim getDriver().Diag(diag::err_drv_invalid_Xarch_argument_with_args) 650193326Sed << A->getAsString(Args); 651193326Sed continue; 652245431Sdim } else if (XarchArg->getOption().hasFlag(options::DriverOption)) { 653226890Sdim 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". 666245431Sdim 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), 671245431Sdim 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), 694245431Sdim 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) { 749226890Sdim StringRef Name = BoundArch; 750245431Sdim const Option MCpu = Opts.getOption(options::OPT_mcpu_EQ); 751245431Sdim 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 774263509Sdim 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)); 796263509Sdim else if (Name == "x86_64h") { 797263509Sdim DAL->AddFlagArg(0, Opts.getOption(options::OPT_m64)); 798263509Sdim DAL->AddJoinedArg(0, MArch, "x86_64h"); 799263509Sdim } 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"); 811252723Sdim else if (Name == "armv6m") 812252723Sdim DAL->AddJoinedArg(0, MArch, "armv6m"); 813198092Srdivacky else if (Name == "armv7") 814210299Sed DAL->AddJoinedArg(0, MArch, "armv7a"); 815252723Sdim else if (Name == "armv7em") 816252723Sdim DAL->AddJoinedArg(0, MArch, "armv7em"); 817245431Sdim else if (Name == "armv7f") 818245431Sdim DAL->AddJoinedArg(0, MArch, "armv7f"); 819245431Sdim else if (Name == "armv7k") 820245431Sdim DAL->AddJoinedArg(0, MArch, "armv7k"); 821252723Sdim else if (Name == "armv7m") 822252723Sdim DAL->AddJoinedArg(0, MArch, "armv7m"); 823245431Sdim else if (Name == "armv7s") 824245431Sdim 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. 833245431Sdim if (BoundArch) 834245431Sdim AddDeploymentTarget(*DAL); 835212904Sdim 836245431Sdim // For iOS 6, undo the translation to add -static for -mkernel/-fapple-kext. 837245431Sdim // FIXME: It would be far better to avoid inserting those -static arguments, 838245431Sdim // but we can't check the deployment target in the translation code until 839245431Sdim // it is set here. 840245431Sdim if (isTargetIPhoneOS() && !isIPhoneOSVersionLT(6, 0)) { 841245431Sdim for (ArgList::iterator it = DAL->begin(), ie = DAL->end(); it != ie; ) { 842245431Sdim Arg *A = *it; 843245431Sdim ++it; 844245431Sdim if (A->getOption().getID() != options::OPT_mkernel && 845245431Sdim A->getOption().getID() != options::OPT_fapple_kext) 846245431Sdim continue; 847245431Sdim assert(it != ie && "unexpected argument translation"); 848245431Sdim A = *it; 849245431Sdim assert(A->getOption().getID() == options::OPT_static && 850245431Sdim "missing expected -static argument"); 851245431Sdim it = DAL->getArgs().erase(it); 852245431Sdim } 853245431Sdim } 854245431Sdim 855263509Sdim // Default to use libc++ on OS X 10.9+ and iOS 7+. 856263509Sdim if (((isTargetMacOS() && !isMacosxVersionLT(10, 9)) || 857263509Sdim (isTargetIPhoneOS() && !isIPhoneOSVersionLT(7, 0))) && 858263509Sdim !Args.getLastArg(options::OPT_stdlib_EQ)) 859263509Sdim DAL->AddJoinedArg(0, Opts.getOption(options::OPT_stdlib_EQ), "libc++"); 860263509Sdim 861226890Sdim // Validate the C++ standard library choice. 862226890Sdim CXXStdlibType Type = GetCXXStdlibType(*DAL); 863226890Sdim if (Type == ToolChain::CST_Libcxx) { 864245431Sdim // Check whether the target provides libc++. 865245431Sdim StringRef where; 866245431Sdim 867245431Sdim // Complain about targetting iOS < 5.0 in any way. 868245431Sdim if (isTargetIPhoneOS() && isIPhoneOSVersionLT(5, 0)) 869245431Sdim where = "iOS 5.0"; 870245431Sdim 871245431Sdim if (where != StringRef()) { 872226890Sdim getDriver().Diag(clang::diag::err_drv_invalid_libcxx_deployment) 873245431Sdim << where; 874226890Sdim } 875226890Sdim } 876226890Sdim 877193326Sed return DAL; 878198092Srdivacky} 879193326Sed 880198092Srdivackybool Darwin::IsUnwindTablesDefault() const { 881245431Sdim 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 896245431Sdimbool Darwin::isPICDefault() const { 897245431Sdim return true; 898193326Sed} 899193326Sed 900252723Sdimbool Darwin::isPIEDefault() const { 901252723Sdim return false; 902252723Sdim} 903252723Sdim 904245431Sdimbool Darwin::isPICDefaultForced() const { 905245431Sdim return getArch() == llvm::Triple::x86_64; 906193326Sed} 907193326Sed 908221345Sdimbool Darwin::SupportsProfiling() const { 909221345Sdim // Profiling instrumentation is only supported on x86. 910245431Sdim 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 918245431Sdimvoid Darwin::CheckObjCARC() const { 919245431Sdim if (isTargetIPhoneOS() || !isMacosxVersionLT(10, 6)) 920245431Sdim return; 921245431Sdim getDriver().Diag(diag::err_arc_unsupported_on_toolchain); 922235633Sdim} 923235633Sdim 924212904Sdimstd::string 925226890SdimDarwin_Generic_GCC::ComputeEffectiveClangTriple(const ArgList &Args, 926226890Sdim types::ID InputType) const { 927226890Sdim 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 934235633Sdim/// \brief Parse a GCCVersion object out of a string of text. 935235633Sdim/// 936235633Sdim/// This is the primary means of forming GCCVersion objects. 937235633Sdim/*static*/ 938235633SdimGeneric_GCC::GCCVersion Linux::GCCVersion::Parse(StringRef VersionText) { 939263509Sdim const GCCVersion BadVersion = { VersionText.str(), -1, -1, -1, "", "", "" }; 940235633Sdim std::pair<StringRef, StringRef> First = VersionText.split('.'); 941235633Sdim std::pair<StringRef, StringRef> Second = First.second.split('.'); 942235633Sdim 943263509Sdim GCCVersion GoodVersion = { VersionText.str(), -1, -1, -1, "", "", "" }; 944235633Sdim if (First.first.getAsInteger(10, GoodVersion.Major) || 945235633Sdim GoodVersion.Major < 0) 946235633Sdim return BadVersion; 947263509Sdim GoodVersion.MajorStr = First.first.str(); 948235633Sdim if (Second.first.getAsInteger(10, GoodVersion.Minor) || 949235633Sdim GoodVersion.Minor < 0) 950235633Sdim return BadVersion; 951263509Sdim GoodVersion.MinorStr = Second.first.str(); 952235633Sdim 953235633Sdim // First look for a number prefix and parse that if present. Otherwise just 954235633Sdim // stash the entire patch string in the suffix, and leave the number 955235633Sdim // unspecified. This covers versions strings such as: 956235633Sdim // 4.4 957235633Sdim // 4.4.0 958235633Sdim // 4.4.x 959235633Sdim // 4.4.2-rc4 960235633Sdim // 4.4.x-patched 961235633Sdim // And retains any patch number it finds. 962235633Sdim StringRef PatchText = GoodVersion.PatchSuffix = Second.second.str(); 963235633Sdim if (!PatchText.empty()) { 964252723Sdim if (size_t EndNumber = PatchText.find_first_not_of("0123456789")) { 965235633Sdim // Try to parse the number and any suffix. 966235633Sdim if (PatchText.slice(0, EndNumber).getAsInteger(10, GoodVersion.Patch) || 967235633Sdim GoodVersion.Patch < 0) 968235633Sdim return BadVersion; 969263509Sdim GoodVersion.PatchSuffix = PatchText.substr(EndNumber); 970235633Sdim } 971235633Sdim } 972235633Sdim 973235633Sdim return GoodVersion; 974235633Sdim} 975235633Sdim 976235633Sdim/// \brief Less-than for GCCVersion, implementing a Strict Weak Ordering. 977263509Sdimbool Generic_GCC::GCCVersion::isOlderThan(int RHSMajor, int RHSMinor, 978263509Sdim int RHSPatch, 979263509Sdim StringRef RHSPatchSuffix) const { 980263509Sdim if (Major != RHSMajor) 981263509Sdim return Major < RHSMajor; 982263509Sdim if (Minor != RHSMinor) 983263509Sdim return Minor < RHSMinor; 984263509Sdim if (Patch != RHSPatch) { 985252723Sdim // Note that versions without a specified patch sort higher than those with 986252723Sdim // a patch. 987263509Sdim if (RHSPatch == -1) 988252723Sdim return true; 989252723Sdim if (Patch == -1) 990252723Sdim return false; 991235633Sdim 992252723Sdim // Otherwise just sort on the patch itself. 993263509Sdim return Patch < RHSPatch; 994252723Sdim } 995263509Sdim if (PatchSuffix != RHSPatchSuffix) { 996252723Sdim // Sort empty suffixes higher. 997263509Sdim if (RHSPatchSuffix.empty()) 998252723Sdim return true; 999252723Sdim if (PatchSuffix.empty()) 1000252723Sdim return false; 1001235633Sdim 1002252723Sdim // Provide a lexicographic sort to make this a total ordering. 1003263509Sdim return PatchSuffix < RHSPatchSuffix; 1004252723Sdim } 1005252723Sdim 1006252723Sdim // The versions are equal. 1007235633Sdim return false; 1008235633Sdim} 1009235633Sdim 1010235633Sdimstatic StringRef getGCCToolchainDir(const ArgList &Args) { 1011235633Sdim const Arg *A = Args.getLastArg(options::OPT_gcc_toolchain); 1012235633Sdim if (A) 1013245431Sdim return A->getValue(); 1014235633Sdim return GCC_INSTALL_PREFIX; 1015235633Sdim} 1016235633Sdim 1017259157Sdim/// \brief Initialize a GCCInstallationDetector from the driver. 1018235633Sdim/// 1019235633Sdim/// This performs all of the autodetection and sets up the various paths. 1020235633Sdim/// Once constructed, a GCCInstallationDetector is essentially immutable. 1021235633Sdim/// 1022235633Sdim/// FIXME: We shouldn't need an explicit TargetTriple parameter here, and 1023235633Sdim/// should instead pull the target out of the driver. This is currently 1024235633Sdim/// necessary because the driver doesn't store the final version of the target 1025235633Sdim/// triple. 1026259157Sdimvoid 1027259157SdimGeneric_GCC::GCCInstallationDetector::init( 1028263509Sdim const llvm::Triple &TargetTriple, const ArgList &Args) { 1029263509Sdim llvm::Triple BiarchVariantTriple = 1030263509Sdim TargetTriple.isArch32Bit() ? TargetTriple.get64BitArchVariant() 1031235633Sdim : TargetTriple.get32BitArchVariant(); 1032235633Sdim llvm::Triple::ArchType TargetArch = TargetTriple.getArch(); 1033235633Sdim // The library directories which may contain GCC installations. 1034263509Sdim SmallVector<StringRef, 4> CandidateLibDirs, CandidateBiarchLibDirs; 1035235633Sdim // The compatible GCC triples for this particular architecture. 1036235633Sdim SmallVector<StringRef, 10> CandidateTripleAliases; 1037263509Sdim SmallVector<StringRef, 10> CandidateBiarchTripleAliases; 1038263509Sdim CollectLibDirsAndTriples(TargetTriple, BiarchVariantTriple, CandidateLibDirs, 1039263509Sdim CandidateTripleAliases, CandidateBiarchLibDirs, 1040263509Sdim CandidateBiarchTripleAliases); 1041235633Sdim 1042235633Sdim // Compute the set of prefixes for our search. 1043235633Sdim SmallVector<std::string, 8> Prefixes(D.PrefixDirs.begin(), 1044235633Sdim D.PrefixDirs.end()); 1045235633Sdim 1046235633Sdim StringRef GCCToolchainDir = getGCCToolchainDir(Args); 1047235633Sdim if (GCCToolchainDir != "") { 1048235633Sdim if (GCCToolchainDir.back() == '/') 1049235633Sdim GCCToolchainDir = GCCToolchainDir.drop_back(); // remove the / 1050235633Sdim 1051235633Sdim Prefixes.push_back(GCCToolchainDir); 1052235633Sdim } else { 1053263509Sdim // If we have a SysRoot, try that first. 1054263509Sdim if (!D.SysRoot.empty()) { 1055263509Sdim Prefixes.push_back(D.SysRoot); 1056263509Sdim Prefixes.push_back(D.SysRoot + "/usr"); 1057263509Sdim } 1058263509Sdim 1059263509Sdim // Then look for gcc installed alongside clang. 1060235633Sdim Prefixes.push_back(D.InstalledDir + "/.."); 1061263509Sdim 1062263509Sdim // And finally in /usr. 1063263509Sdim if (D.SysRoot.empty()) 1064263509Sdim Prefixes.push_back("/usr"); 1065235633Sdim } 1066235633Sdim 1067235633Sdim // Loop over the various components which exist and select the best GCC 1068235633Sdim // installation available. GCC installs are ranked by version number. 1069235633Sdim Version = GCCVersion::Parse("0.0.0"); 1070235633Sdim for (unsigned i = 0, ie = Prefixes.size(); i < ie; ++i) { 1071235633Sdim if (!llvm::sys::fs::exists(Prefixes[i])) 1072235633Sdim continue; 1073235633Sdim for (unsigned j = 0, je = CandidateLibDirs.size(); j < je; ++j) { 1074235633Sdim const std::string LibDir = Prefixes[i] + CandidateLibDirs[j].str(); 1075235633Sdim if (!llvm::sys::fs::exists(LibDir)) 1076235633Sdim continue; 1077235633Sdim for (unsigned k = 0, ke = CandidateTripleAliases.size(); k < ke; ++k) 1078245431Sdim ScanLibDirForGCCTriple(TargetArch, Args, LibDir, 1079245431Sdim CandidateTripleAliases[k]); 1080235633Sdim } 1081263509Sdim for (unsigned j = 0, je = CandidateBiarchLibDirs.size(); j < je; ++j) { 1082263509Sdim const std::string LibDir = Prefixes[i] + CandidateBiarchLibDirs[j].str(); 1083235633Sdim if (!llvm::sys::fs::exists(LibDir)) 1084235633Sdim continue; 1085263509Sdim for (unsigned k = 0, ke = CandidateBiarchTripleAliases.size(); k < ke; 1086235633Sdim ++k) 1087245431Sdim ScanLibDirForGCCTriple(TargetArch, Args, LibDir, 1088263509Sdim CandidateBiarchTripleAliases[k], 1089263509Sdim /*NeedsBiarchSuffix=*/ true); 1090235633Sdim } 1091235633Sdim } 1092235633Sdim} 1093235633Sdim 1094263509Sdimvoid Generic_GCC::GCCInstallationDetector::print(raw_ostream &OS) const { 1095263509Sdim for (std::set<std::string>::const_iterator 1096263509Sdim I = CandidateGCCInstallPaths.begin(), 1097263509Sdim E = CandidateGCCInstallPaths.end(); 1098263509Sdim I != E; ++I) 1099263509Sdim OS << "Found candidate GCC installation: " << *I << "\n"; 1100263509Sdim 1101263509Sdim OS << "Selected GCC installation: " << GCCInstallPath << "\n"; 1102263509Sdim} 1103263509Sdim 1104235633Sdim/*static*/ void Generic_GCC::GCCInstallationDetector::CollectLibDirsAndTriples( 1105263509Sdim const llvm::Triple &TargetTriple, const llvm::Triple &BiarchTriple, 1106235633Sdim SmallVectorImpl<StringRef> &LibDirs, 1107235633Sdim SmallVectorImpl<StringRef> &TripleAliases, 1108263509Sdim SmallVectorImpl<StringRef> &BiarchLibDirs, 1109263509Sdim SmallVectorImpl<StringRef> &BiarchTripleAliases) { 1110235633Sdim // Declare a bunch of static data sets that we'll select between below. These 1111235633Sdim // are specifically designed to always refer to string literals to avoid any 1112235633Sdim // lifetime or initialization issues. 1113252723Sdim static const char *const AArch64LibDirs[] = { "/lib" }; 1114263509Sdim static const char *const AArch64Triples[] = { "aarch64-none-linux-gnu", 1115263509Sdim "aarch64-linux-gnu" }; 1116252723Sdim 1117235633Sdim static const char *const ARMLibDirs[] = { "/lib" }; 1118263509Sdim static const char *const ARMTriples[] = { "arm-linux-gnueabi", 1119263509Sdim "arm-linux-androideabi" }; 1120263509Sdim static const char *const ARMHFTriples[] = { "arm-linux-gnueabihf", 1121263509Sdim "armv7hl-redhat-linux-gnueabi" }; 1122235633Sdim 1123235633Sdim static const char *const X86_64LibDirs[] = { "/lib64", "/lib" }; 1124235633Sdim static const char *const X86_64Triples[] = { 1125263509Sdim "x86_64-linux-gnu", "x86_64-unknown-linux-gnu", "x86_64-pc-linux-gnu", 1126263509Sdim "x86_64-redhat-linux6E", "x86_64-redhat-linux", "x86_64-suse-linux", 1127263509Sdim "x86_64-manbo-linux-gnu", "x86_64-linux-gnu", "x86_64-slackware-linux" 1128235633Sdim }; 1129235633Sdim static const char *const X86LibDirs[] = { "/lib32", "/lib" }; 1130235633Sdim static const char *const X86Triples[] = { 1131263509Sdim "i686-linux-gnu", "i686-pc-linux-gnu", "i486-linux-gnu", "i386-linux-gnu", 1132263509Sdim "i386-redhat-linux6E", "i686-redhat-linux", "i586-redhat-linux", 1133263509Sdim "i386-redhat-linux", "i586-suse-linux", "i486-slackware-linux", 1134245431Sdim "i686-montavista-linux" 1135235633Sdim }; 1136235633Sdim 1137235633Sdim static const char *const MIPSLibDirs[] = { "/lib" }; 1138263509Sdim static const char *const MIPSTriples[] = { "mips-linux-gnu", 1139263509Sdim "mips-mti-linux-gnu" }; 1140235633Sdim static const char *const MIPSELLibDirs[] = { "/lib" }; 1141263509Sdim static const char *const MIPSELTriples[] = { "mipsel-linux-gnu", 1142263509Sdim "mipsel-linux-android" }; 1143235633Sdim 1144245431Sdim static const char *const MIPS64LibDirs[] = { "/lib64", "/lib" }; 1145263509Sdim static const char *const MIPS64Triples[] = { "mips64-linux-gnu", 1146263509Sdim "mips-mti-linux-gnu" }; 1147245431Sdim static const char *const MIPS64ELLibDirs[] = { "/lib64", "/lib" }; 1148263509Sdim static const char *const MIPS64ELTriples[] = { "mips64el-linux-gnu", 1149263509Sdim "mips-mti-linux-gnu" }; 1150245431Sdim 1151235633Sdim static const char *const PPCLibDirs[] = { "/lib32", "/lib" }; 1152235633Sdim static const char *const PPCTriples[] = { 1153263509Sdim "powerpc-linux-gnu", "powerpc-unknown-linux-gnu", "powerpc-linux-gnuspe", 1154263509Sdim "powerpc-suse-linux", "powerpc-montavista-linuxspe" 1155235633Sdim }; 1156235633Sdim static const char *const PPC64LibDirs[] = { "/lib64", "/lib" }; 1157263509Sdim static const char *const PPC64Triples[] = { "powerpc64-linux-gnu", 1158263509Sdim "powerpc64-unknown-linux-gnu", 1159263509Sdim "powerpc64-suse-linux", 1160263509Sdim "ppc64-redhat-linux" }; 1161263509Sdim static const char *const PPC64LELibDirs[] = { "/lib64", "/lib" }; 1162263509Sdim static const char *const PPC64LETriples[] = { "powerpc64le-linux-gnu", 1163263509Sdim "powerpc64le-unknown-linux-gnu", 1164263509Sdim "powerpc64le-suse-linux", 1165263509Sdim "ppc64le-redhat-linux" }; 1166235633Sdim 1167263764Sdim static const char *const SPARCv8LibDirs[] = { "/lib32", "/lib" }; 1168263764Sdim static const char *const SPARCv8Triples[] = { "sparc-linux-gnu", 1169263764Sdim "sparcv8-linux-gnu" }; 1170263764Sdim static const char *const SPARCv9LibDirs[] = { "/lib64", "/lib" }; 1171263764Sdim static const char *const SPARCv9Triples[] = { "sparc64-linux-gnu", 1172263764Sdim "sparcv9-linux-gnu" }; 1173263764Sdim 1174252723Sdim static const char *const SystemZLibDirs[] = { "/lib64", "/lib" }; 1175252723Sdim static const char *const SystemZTriples[] = { 1176263509Sdim "s390x-linux-gnu", "s390x-unknown-linux-gnu", "s390x-ibm-linux-gnu", 1177263509Sdim "s390x-suse-linux", "s390x-redhat-linux" 1178252723Sdim }; 1179252723Sdim 1180235633Sdim switch (TargetTriple.getArch()) { 1181252723Sdim case llvm::Triple::aarch64: 1182263509Sdim LibDirs.append(AArch64LibDirs, 1183263509Sdim AArch64LibDirs + llvm::array_lengthof(AArch64LibDirs)); 1184263509Sdim TripleAliases.append(AArch64Triples, 1185263509Sdim AArch64Triples + llvm::array_lengthof(AArch64Triples)); 1186263509Sdim BiarchLibDirs.append(AArch64LibDirs, 1187263509Sdim AArch64LibDirs + llvm::array_lengthof(AArch64LibDirs)); 1188263509Sdim BiarchTripleAliases.append( 1189263509Sdim AArch64Triples, AArch64Triples + llvm::array_lengthof(AArch64Triples)); 1190252723Sdim break; 1191235633Sdim case llvm::Triple::arm: 1192235633Sdim case llvm::Triple::thumb: 1193235633Sdim LibDirs.append(ARMLibDirs, ARMLibDirs + llvm::array_lengthof(ARMLibDirs)); 1194245431Sdim if (TargetTriple.getEnvironment() == llvm::Triple::GNUEABIHF) { 1195263509Sdim TripleAliases.append(ARMHFTriples, 1196263509Sdim ARMHFTriples + llvm::array_lengthof(ARMHFTriples)); 1197245431Sdim } else { 1198263509Sdim TripleAliases.append(ARMTriples, 1199263509Sdim ARMTriples + llvm::array_lengthof(ARMTriples)); 1200245431Sdim } 1201235633Sdim break; 1202235633Sdim case llvm::Triple::x86_64: 1203263509Sdim LibDirs.append(X86_64LibDirs, 1204263509Sdim X86_64LibDirs + llvm::array_lengthof(X86_64LibDirs)); 1205263509Sdim TripleAliases.append(X86_64Triples, 1206263509Sdim X86_64Triples + llvm::array_lengthof(X86_64Triples)); 1207263509Sdim BiarchLibDirs.append(X86LibDirs, 1208263509Sdim X86LibDirs + llvm::array_lengthof(X86LibDirs)); 1209263509Sdim BiarchTripleAliases.append(X86Triples, 1210263509Sdim X86Triples + llvm::array_lengthof(X86Triples)); 1211235633Sdim break; 1212235633Sdim case llvm::Triple::x86: 1213235633Sdim LibDirs.append(X86LibDirs, X86LibDirs + llvm::array_lengthof(X86LibDirs)); 1214263509Sdim TripleAliases.append(X86Triples, 1215263509Sdim X86Triples + llvm::array_lengthof(X86Triples)); 1216263509Sdim BiarchLibDirs.append(X86_64LibDirs, 1217263509Sdim X86_64LibDirs + llvm::array_lengthof(X86_64LibDirs)); 1218263509Sdim BiarchTripleAliases.append( 1219263509Sdim X86_64Triples, X86_64Triples + llvm::array_lengthof(X86_64Triples)); 1220235633Sdim break; 1221235633Sdim case llvm::Triple::mips: 1222263509Sdim LibDirs.append(MIPSLibDirs, 1223263509Sdim MIPSLibDirs + llvm::array_lengthof(MIPSLibDirs)); 1224263509Sdim TripleAliases.append(MIPSTriples, 1225263509Sdim MIPSTriples + llvm::array_lengthof(MIPSTriples)); 1226263509Sdim BiarchLibDirs.append(MIPS64LibDirs, 1227263509Sdim MIPS64LibDirs + llvm::array_lengthof(MIPS64LibDirs)); 1228263509Sdim BiarchTripleAliases.append( 1229263509Sdim MIPS64Triples, MIPS64Triples + llvm::array_lengthof(MIPS64Triples)); 1230235633Sdim break; 1231235633Sdim case llvm::Triple::mipsel: 1232263509Sdim LibDirs.append(MIPSELLibDirs, 1233263509Sdim MIPSELLibDirs + llvm::array_lengthof(MIPSELLibDirs)); 1234263509Sdim TripleAliases.append(MIPSELTriples, 1235263509Sdim MIPSELTriples + llvm::array_lengthof(MIPSELTriples)); 1236263509Sdim TripleAliases.append(MIPSTriples, 1237263509Sdim MIPSTriples + llvm::array_lengthof(MIPSTriples)); 1238263509Sdim BiarchLibDirs.append( 1239263509Sdim MIPS64ELLibDirs, 1240263509Sdim MIPS64ELLibDirs + llvm::array_lengthof(MIPS64ELLibDirs)); 1241263509Sdim BiarchTripleAliases.append( 1242263509Sdim MIPS64ELTriples, 1243263509Sdim MIPS64ELTriples + llvm::array_lengthof(MIPS64ELTriples)); 1244235633Sdim break; 1245245431Sdim case llvm::Triple::mips64: 1246263509Sdim LibDirs.append(MIPS64LibDirs, 1247263509Sdim MIPS64LibDirs + llvm::array_lengthof(MIPS64LibDirs)); 1248263509Sdim TripleAliases.append(MIPS64Triples, 1249263509Sdim MIPS64Triples + llvm::array_lengthof(MIPS64Triples)); 1250263509Sdim BiarchLibDirs.append(MIPSLibDirs, 1251263509Sdim MIPSLibDirs + llvm::array_lengthof(MIPSLibDirs)); 1252263509Sdim BiarchTripleAliases.append(MIPSTriples, 1253263509Sdim MIPSTriples + llvm::array_lengthof(MIPSTriples)); 1254245431Sdim break; 1255245431Sdim case llvm::Triple::mips64el: 1256263509Sdim LibDirs.append(MIPS64ELLibDirs, 1257263509Sdim MIPS64ELLibDirs + llvm::array_lengthof(MIPS64ELLibDirs)); 1258245431Sdim TripleAliases.append( 1259263509Sdim MIPS64ELTriples, 1260263509Sdim MIPS64ELTriples + llvm::array_lengthof(MIPS64ELTriples)); 1261263509Sdim BiarchLibDirs.append(MIPSELLibDirs, 1262263509Sdim MIPSELLibDirs + llvm::array_lengthof(MIPSELLibDirs)); 1263263509Sdim BiarchTripleAliases.append( 1264263509Sdim MIPSELTriples, MIPSELTriples + llvm::array_lengthof(MIPSELTriples)); 1265263509Sdim BiarchTripleAliases.append( 1266263509Sdim MIPSTriples, MIPSTriples + llvm::array_lengthof(MIPSTriples)); 1267245431Sdim break; 1268235633Sdim case llvm::Triple::ppc: 1269235633Sdim LibDirs.append(PPCLibDirs, PPCLibDirs + llvm::array_lengthof(PPCLibDirs)); 1270263509Sdim TripleAliases.append(PPCTriples, 1271263509Sdim PPCTriples + llvm::array_lengthof(PPCTriples)); 1272263509Sdim BiarchLibDirs.append(PPC64LibDirs, 1273263509Sdim PPC64LibDirs + llvm::array_lengthof(PPC64LibDirs)); 1274263509Sdim BiarchTripleAliases.append( 1275263509Sdim PPC64Triples, PPC64Triples + llvm::array_lengthof(PPC64Triples)); 1276235633Sdim break; 1277235633Sdim case llvm::Triple::ppc64: 1278263509Sdim LibDirs.append(PPC64LibDirs, 1279263509Sdim PPC64LibDirs + llvm::array_lengthof(PPC64LibDirs)); 1280263509Sdim TripleAliases.append(PPC64Triples, 1281263509Sdim PPC64Triples + llvm::array_lengthof(PPC64Triples)); 1282263509Sdim BiarchLibDirs.append(PPCLibDirs, 1283263509Sdim PPCLibDirs + llvm::array_lengthof(PPCLibDirs)); 1284263509Sdim BiarchTripleAliases.append(PPCTriples, 1285263509Sdim PPCTriples + llvm::array_lengthof(PPCTriples)); 1286235633Sdim break; 1287263509Sdim case llvm::Triple::ppc64le: 1288263509Sdim LibDirs.append(PPC64LELibDirs, 1289263509Sdim PPC64LELibDirs + llvm::array_lengthof(PPC64LELibDirs)); 1290263509Sdim TripleAliases.append(PPC64LETriples, 1291263509Sdim PPC64LETriples + llvm::array_lengthof(PPC64LETriples)); 1292263509Sdim break; 1293263764Sdim case llvm::Triple::sparc: 1294263764Sdim LibDirs.append(SPARCv8LibDirs, 1295263764Sdim SPARCv8LibDirs + llvm::array_lengthof(SPARCv8LibDirs)); 1296263764Sdim TripleAliases.append(SPARCv8Triples, 1297263764Sdim SPARCv8Triples + llvm::array_lengthof(SPARCv8Triples)); 1298263764Sdim BiarchLibDirs.append(SPARCv9LibDirs, 1299263764Sdim SPARCv9LibDirs + llvm::array_lengthof(SPARCv9LibDirs)); 1300263764Sdim BiarchTripleAliases.append( 1301263764Sdim SPARCv9Triples, SPARCv9Triples + llvm::array_lengthof(SPARCv9Triples)); 1302263764Sdim break; 1303263764Sdim case llvm::Triple::sparcv9: 1304263764Sdim LibDirs.append(SPARCv9LibDirs, 1305263764Sdim SPARCv9LibDirs + llvm::array_lengthof(SPARCv9LibDirs)); 1306263764Sdim TripleAliases.append(SPARCv9Triples, 1307263764Sdim SPARCv9Triples + llvm::array_lengthof(SPARCv9Triples)); 1308263764Sdim BiarchLibDirs.append(SPARCv8LibDirs, 1309263764Sdim SPARCv8LibDirs + llvm::array_lengthof(SPARCv8LibDirs)); 1310263764Sdim BiarchTripleAliases.append( 1311263764Sdim SPARCv8Triples, SPARCv8Triples + llvm::array_lengthof(SPARCv8Triples)); 1312263764Sdim break; 1313252723Sdim case llvm::Triple::systemz: 1314263509Sdim LibDirs.append(SystemZLibDirs, 1315263509Sdim SystemZLibDirs + llvm::array_lengthof(SystemZLibDirs)); 1316263509Sdim TripleAliases.append(SystemZTriples, 1317263509Sdim SystemZTriples + llvm::array_lengthof(SystemZTriples)); 1318252723Sdim break; 1319235633Sdim 1320235633Sdim default: 1321235633Sdim // By default, just rely on the standard lib directories and the original 1322235633Sdim // triple. 1323235633Sdim break; 1324235633Sdim } 1325235633Sdim 1326235633Sdim // Always append the drivers target triple to the end, in case it doesn't 1327235633Sdim // match any of our aliases. 1328235633Sdim TripleAliases.push_back(TargetTriple.str()); 1329235633Sdim 1330235633Sdim // Also include the multiarch variant if it's different. 1331263509Sdim if (TargetTriple.str() != BiarchTriple.str()) 1332263509Sdim BiarchTripleAliases.push_back(BiarchTriple.str()); 1333235633Sdim} 1334235633Sdim 1335252723Sdimstatic bool isSoftFloatABI(const ArgList &Args) { 1336252723Sdim Arg *A = Args.getLastArg(options::OPT_msoft_float, 1337252723Sdim options::OPT_mhard_float, 1338252723Sdim options::OPT_mfloat_abi_EQ); 1339252723Sdim if (!A) return false; 1340252723Sdim 1341252723Sdim return A->getOption().matches(options::OPT_msoft_float) || 1342252723Sdim (A->getOption().matches(options::OPT_mfloat_abi_EQ) && 1343252723Sdim A->getValue() == StringRef("soft")); 1344252723Sdim} 1345252723Sdim 1346252723Sdimstatic bool isMipsArch(llvm::Triple::ArchType Arch) { 1347252723Sdim return Arch == llvm::Triple::mips || 1348252723Sdim Arch == llvm::Triple::mipsel || 1349252723Sdim Arch == llvm::Triple::mips64 || 1350252723Sdim Arch == llvm::Triple::mips64el; 1351252723Sdim} 1352252723Sdim 1353252723Sdimstatic bool isMips16(const ArgList &Args) { 1354252723Sdim Arg *A = Args.getLastArg(options::OPT_mips16, 1355252723Sdim options::OPT_mno_mips16); 1356252723Sdim return A && A->getOption().matches(options::OPT_mips16); 1357252723Sdim} 1358252723Sdim 1359263509Sdimstatic bool isMips32r2(const ArgList &Args) { 1360263509Sdim Arg *A = Args.getLastArg(options::OPT_march_EQ, 1361263509Sdim options::OPT_mcpu_EQ); 1362263509Sdim 1363263509Sdim return A && A->getValue() == StringRef("mips32r2"); 1364263509Sdim} 1365263509Sdim 1366263509Sdimstatic bool isMips64r2(const ArgList &Args) { 1367263509Sdim Arg *A = Args.getLastArg(options::OPT_march_EQ, 1368263509Sdim options::OPT_mcpu_EQ); 1369263509Sdim 1370263509Sdim return A && A->getValue() == StringRef("mips64r2"); 1371263509Sdim} 1372263509Sdim 1373252723Sdimstatic bool isMicroMips(const ArgList &Args) { 1374252723Sdim Arg *A = Args.getLastArg(options::OPT_mmicromips, 1375252723Sdim options::OPT_mno_micromips); 1376252723Sdim return A && A->getOption().matches(options::OPT_mmicromips); 1377252723Sdim} 1378252723Sdim 1379263509Sdimstatic bool isMipsFP64(const ArgList &Args) { 1380263509Sdim Arg *A = Args.getLastArg(options::OPT_mfp64, options::OPT_mfp32); 1381263509Sdim return A && A->getOption().matches(options::OPT_mfp64); 1382263509Sdim} 1383263509Sdim 1384263509Sdimstatic bool isMipsNan2008(const ArgList &Args) { 1385263509Sdim Arg *A = Args.getLastArg(options::OPT_mnan_EQ); 1386263509Sdim return A && A->getValue() == StringRef("2008"); 1387263509Sdim} 1388263509Sdim 1389245431Sdim// FIXME: There is the same routine in the Tools.cpp. 1390245431Sdimstatic bool hasMipsN32ABIArg(const ArgList &Args) { 1391245431Sdim Arg *A = Args.getLastArg(options::OPT_mabi_EQ); 1392245431Sdim return A && (A->getValue() == StringRef("n32")); 1393245431Sdim} 1394245431Sdim 1395263509Sdimstatic bool hasCrtBeginObj(Twine Path) { 1396263509Sdim return llvm::sys::fs::exists(Path + "/crtbegin.o"); 1397263509Sdim} 1398263509Sdim 1399263509Sdimstatic bool findTargetBiarchSuffix(std::string &Suffix, StringRef Path, 1400252723Sdim llvm::Triple::ArchType TargetArch, 1401252723Sdim const ArgList &Args) { 1402263509Sdim // FIXME: This routine was only intended to model bi-arch toolchains which 1403263509Sdim // use -m32 and -m64 to swap between variants of a target. It shouldn't be 1404263509Sdim // doing ABI-based builtin location for MIPS. 1405263509Sdim if (hasMipsN32ABIArg(Args)) 1406263509Sdim Suffix = "/n32"; 1407263509Sdim else if (TargetArch == llvm::Triple::x86_64 || 1408263509Sdim TargetArch == llvm::Triple::ppc64 || 1409263764Sdim TargetArch == llvm::Triple::sparcv9 || 1410263509Sdim TargetArch == llvm::Triple::systemz || 1411263509Sdim TargetArch == llvm::Triple::mips64 || 1412263509Sdim TargetArch == llvm::Triple::mips64el) 1413263509Sdim Suffix = "/64"; 1414263509Sdim else 1415263509Sdim Suffix = "/32"; 1416245431Sdim 1417263509Sdim return hasCrtBeginObj(Path + Suffix); 1418252723Sdim} 1419252723Sdim 1420263509Sdimvoid Generic_GCC::GCCInstallationDetector::findMIPSABIDirSuffix( 1421263509Sdim std::string &Suffix, llvm::Triple::ArchType TargetArch, StringRef Path, 1422263509Sdim const llvm::opt::ArgList &Args) { 1423263509Sdim if (!isMipsArch(TargetArch)) 1424263509Sdim return; 1425245431Sdim 1426263509Sdim // Some MIPS toolchains put libraries and object files compiled 1427263509Sdim // using different options in to the sub-directoris which names 1428263509Sdim // reflects the flags used for compilation. For example sysroot 1429263509Sdim // directory might looks like the following examples: 1430263509Sdim // 1431263509Sdim // /usr 1432263509Sdim // /lib <= crt*.o files compiled with '-mips32' 1433263509Sdim // /mips16 1434263509Sdim // /usr 1435263509Sdim // /lib <= crt*.o files compiled with '-mips16' 1436263509Sdim // /el 1437263509Sdim // /usr 1438263509Sdim // /lib <= crt*.o files compiled with '-mips16 -EL' 1439263509Sdim // 1440263509Sdim // or 1441263509Sdim // 1442263509Sdim // /usr 1443263509Sdim // /lib <= crt*.o files compiled with '-mips32r2' 1444263509Sdim // /mips16 1445263509Sdim // /usr 1446263509Sdim // /lib <= crt*.o files compiled with '-mips32r2 -mips16' 1447263509Sdim // /mips32 1448263509Sdim // /usr 1449263509Sdim // /lib <= crt*.o files compiled with '-mips32' 1450263509Sdim // 1451263509Sdim // Unfortunately different toolchains use different and partially 1452263509Sdim // overlapped naming schemes. So we have to make a trick for detection 1453263509Sdim // of using toolchain. We lookup a path which unique for each toolchains. 1454245431Sdim 1455263509Sdim bool IsMentorToolChain = hasCrtBeginObj(Path + "/mips16/soft-float"); 1456263509Sdim bool IsFSFToolChain = hasCrtBeginObj(Path + "/mips32/mips16/sof"); 1457252723Sdim 1458263509Sdim if (IsMentorToolChain && IsFSFToolChain) 1459263509Sdim D.Diag(diag::err_drv_unknown_toolchain); 1460252723Sdim 1461263509Sdim if (IsMentorToolChain) { 1462263509Sdim if (isMips16(Args)) 1463263509Sdim Suffix += "/mips16"; 1464263509Sdim else if (isMicroMips(Args)) 1465263509Sdim Suffix += "/micromips"; 1466263509Sdim 1467263509Sdim if (isSoftFloatABI(Args)) 1468263509Sdim Suffix += "/soft-float"; 1469263509Sdim 1470263509Sdim if (TargetArch == llvm::Triple::mipsel || 1471252723Sdim TargetArch == llvm::Triple::mips64el) 1472263509Sdim Suffix += "/el"; 1473263509Sdim } else if (IsFSFToolChain) { 1474263509Sdim if (TargetArch == llvm::Triple::mips || 1475263509Sdim TargetArch == llvm::Triple::mipsel) { 1476263509Sdim if (isMicroMips(Args)) 1477263509Sdim Suffix += "/micromips"; 1478263509Sdim else if (isMips32r2(Args)) 1479263509Sdim Suffix += ""; 1480263509Sdim else 1481263509Sdim Suffix += "/mips32"; 1482252723Sdim 1483263509Sdim if (isMips16(Args)) 1484263509Sdim Suffix += "/mips16"; 1485263509Sdim } else { 1486263509Sdim if (isMips64r2(Args)) 1487263509Sdim Suffix += hasMipsN32ABIArg(Args) ? "/mips64r2" : "/mips64r2/64"; 1488263509Sdim else 1489263509Sdim Suffix += hasMipsN32ABIArg(Args) ? "/mips64" : "/mips64/64"; 1490263509Sdim } 1491252723Sdim 1492263509Sdim if (TargetArch == llvm::Triple::mipsel || 1493263509Sdim TargetArch == llvm::Triple::mips64el) 1494263509Sdim Suffix += "/el"; 1495263509Sdim 1496263509Sdim if (isSoftFloatABI(Args)) 1497263509Sdim Suffix += "/sof"; 1498263509Sdim else { 1499263509Sdim if (isMipsFP64(Args)) 1500263509Sdim Suffix += "/fp64"; 1501263509Sdim 1502263509Sdim if (isMipsNan2008(Args)) 1503263509Sdim Suffix += "/nan2008"; 1504263509Sdim } 1505252723Sdim } 1506252723Sdim 1507263509Sdim if (!hasCrtBeginObj(Path + Suffix)) 1508263509Sdim Suffix.clear(); 1509252723Sdim} 1510252723Sdim 1511235633Sdimvoid Generic_GCC::GCCInstallationDetector::ScanLibDirForGCCTriple( 1512245431Sdim llvm::Triple::ArchType TargetArch, const ArgList &Args, 1513263509Sdim const std::string &LibDir, StringRef CandidateTriple, 1514263509Sdim bool NeedsBiarchSuffix) { 1515235633Sdim // There are various different suffixes involving the triple we 1516235633Sdim // check for. We also record what is necessary to walk from each back 1517235633Sdim // up to the lib directory. 1518235633Sdim const std::string LibSuffixes[] = { 1519235633Sdim "/gcc/" + CandidateTriple.str(), 1520263509Sdim // Debian puts cross-compilers in gcc-cross 1521263509Sdim "/gcc-cross/" + CandidateTriple.str(), 1522235633Sdim "/" + CandidateTriple.str() + "/gcc/" + CandidateTriple.str(), 1523235633Sdim 1524245431Sdim // The Freescale PPC SDK has the gcc libraries in 1525245431Sdim // <sysroot>/usr/lib/<triple>/x.y.z so have a look there as well. 1526245431Sdim "/" + CandidateTriple.str(), 1527245431Sdim 1528235633Sdim // Ubuntu has a strange mis-matched pair of triples that this happens to 1529235633Sdim // match. 1530235633Sdim // FIXME: It may be worthwhile to generalize this and look for a second 1531235633Sdim // triple. 1532235633Sdim "/i386-linux-gnu/gcc/" + CandidateTriple.str() 1533235633Sdim }; 1534235633Sdim const std::string InstallSuffixes[] = { 1535263509Sdim "/../../..", // gcc/ 1536263509Sdim "/../../..", // gcc-cross/ 1537263509Sdim "/../../../..", // <triple>/gcc/ 1538263509Sdim "/../..", // <triple>/ 1539263509Sdim "/../../../.." // i386-linux-gnu/gcc/<triple>/ 1540235633Sdim }; 1541235633Sdim // Only look at the final, weird Ubuntu suffix for i386-linux-gnu. 1542263509Sdim const unsigned NumLibSuffixes = 1543263509Sdim (llvm::array_lengthof(LibSuffixes) - (TargetArch != llvm::Triple::x86)); 1544235633Sdim for (unsigned i = 0; i < NumLibSuffixes; ++i) { 1545235633Sdim StringRef LibSuffix = LibSuffixes[i]; 1546235633Sdim llvm::error_code EC; 1547235633Sdim for (llvm::sys::fs::directory_iterator LI(LibDir + LibSuffix, EC), LE; 1548235633Sdim !EC && LI != LE; LI = LI.increment(EC)) { 1549235633Sdim StringRef VersionText = llvm::sys::path::filename(LI->path()); 1550235633Sdim GCCVersion CandidateVersion = GCCVersion::Parse(VersionText); 1551263509Sdim if (CandidateVersion.Major != -1) // Filter obviously bad entries. 1552263509Sdim if (!CandidateGCCInstallPaths.insert(LI->path()).second) 1553263509Sdim continue; // Saw this path before; no need to look at it again. 1554263509Sdim if (CandidateVersion.isOlderThan(4, 1, 1)) 1555235633Sdim continue; 1556235633Sdim if (CandidateVersion <= Version) 1557235633Sdim continue; 1558235633Sdim 1559263509Sdim std::string MIPSABIDirSuffix; 1560263509Sdim findMIPSABIDirSuffix(MIPSABIDirSuffix, TargetArch, LI->path(), Args); 1561263509Sdim 1562235633Sdim // Some versions of SUSE and Fedora on ppc64 put 32-bit libs 1563235633Sdim // in what would normally be GCCInstallPath and put the 64-bit 1564235633Sdim // libs in a subdirectory named 64. The simple logic we follow is that 1565235633Sdim // *if* there is a subdirectory of the right name with crtbegin.o in it, 1566263509Sdim // we use that. If not, and if not a biarch triple alias, we look for 1567235633Sdim // crtbegin.o without the subdirectory. 1568252723Sdim 1569263509Sdim std::string BiarchSuffix; 1570263509Sdim if (findTargetBiarchSuffix(BiarchSuffix, 1571263509Sdim LI->path() + MIPSABIDirSuffix, 1572263509Sdim TargetArch, Args)) { 1573263509Sdim GCCBiarchSuffix = BiarchSuffix; 1574263509Sdim } else if (NeedsBiarchSuffix || 1575263509Sdim !hasCrtBeginObj(LI->path() + MIPSABIDirSuffix)) { 1576263509Sdim continue; 1577235633Sdim } else { 1578263509Sdim GCCBiarchSuffix.clear(); 1579235633Sdim } 1580235633Sdim 1581235633Sdim Version = CandidateVersion; 1582235633Sdim GCCTriple.setTriple(CandidateTriple); 1583235633Sdim // FIXME: We hack together the directory name here instead of 1584235633Sdim // using LI to ensure stable path separators across Windows and 1585235633Sdim // Linux. 1586235633Sdim GCCInstallPath = LibDir + LibSuffixes[i] + "/" + VersionText.str(); 1587235633Sdim GCCParentLibPath = GCCInstallPath + InstallSuffixes[i]; 1588263509Sdim GCCMIPSABIDirSuffix = MIPSABIDirSuffix; 1589235633Sdim IsValid = true; 1590235633Sdim } 1591235633Sdim } 1592235633Sdim} 1593235633Sdim 1594235633SdimGeneric_GCC::Generic_GCC(const Driver &D, const llvm::Triple& Triple, 1595235633Sdim const ArgList &Args) 1596263509Sdim : 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 1605252723SdimTool *Generic_GCC::getTool(Action::ActionClass AC) const { 1606252723Sdim switch (AC) { 1607252723Sdim case Action::PreprocessJobClass: 1608252723Sdim if (!Preprocess) 1609252723Sdim Preprocess.reset(new tools::gcc::Preprocess(*this)); 1610252723Sdim return Preprocess.get(); 1611252723Sdim case Action::PrecompileJobClass: 1612252723Sdim if (!Precompile) 1613252723Sdim Precompile.reset(new tools::gcc::Precompile(*this)); 1614252723Sdim return Precompile.get(); 1615252723Sdim case Action::CompileJobClass: 1616252723Sdim if (!Compile) 1617252723Sdim Compile.reset(new tools::gcc::Compile(*this)); 1618252723Sdim return Compile.get(); 1619252723Sdim default: 1620252723Sdim return ToolChain::getTool(AC); 1621193326Sed } 1622252723Sdim} 1623193326Sed 1624252723SdimTool *Generic_GCC::buildAssembler() const { 1625252723Sdim return new tools::gcc::Assemble(*this); 1626193326Sed} 1627193326Sed 1628252723SdimTool *Generic_GCC::buildLinker() const { 1629252723Sdim return new tools::gcc::Link(*this); 1630252723Sdim} 1631252723Sdim 1632263509Sdimvoid Generic_GCC::printVerboseInfo(raw_ostream &OS) const { 1633263509Sdim // Print the information about how we detected the GCC installation. 1634263509Sdim GCCInstallation.print(OS); 1635263509Sdim} 1636263509Sdim 1637193326Sedbool Generic_GCC::IsUnwindTablesDefault() const { 1638245431Sdim return getArch() == llvm::Triple::x86_64; 1639193326Sed} 1640193326Sed 1641245431Sdimbool Generic_GCC::isPICDefault() const { 1642245431Sdim return false; 1643193326Sed} 1644193326Sed 1645252723Sdimbool Generic_GCC::isPIEDefault() const { 1646252723Sdim return false; 1647252723Sdim} 1648252723Sdim 1649245431Sdimbool Generic_GCC::isPICDefaultForced() const { 1650245431Sdim return false; 1651193326Sed} 1652245431Sdim 1653266759Sdimvoid Generic_GCC::addClangTargetOptions(const ArgList &DriverArgs, 1654266759Sdim ArgStringList &CC1Args) const { 1655266759Sdim const Generic_GCC::GCCVersion &V = GCCInstallation.getVersion(); 1656266759Sdim bool UseInitArrayDefault = 1657266759Sdim getTriple().getArch() == llvm::Triple::aarch64 || 1658266759Sdim (getTriple().getOS() == llvm::Triple::Linux && ( 1659266759Sdim !V.isOlderThan(4, 7, 0) || 1660266759Sdim getTriple().getEnvironment() == llvm::Triple::Android)); 1661266759Sdim 1662266759Sdim if (DriverArgs.hasFlag(options::OPT_fuse_init_array, 1663266759Sdim options::OPT_fno_use_init_array, 1664266759Sdim UseInitArrayDefault)) 1665266759Sdim CC1Args.push_back("-fuse-init-array"); 1666266759Sdim} 1667266759Sdim 1668235633Sdim/// Hexagon Toolchain 1669193326Sed 1670252723Sdimstd::string Hexagon_TC::GetGnuDir(const std::string &InstalledDir) { 1671252723Sdim 1672252723Sdim // Locate the rest of the toolchain ... 1673252723Sdim if (strlen(GCC_INSTALL_PREFIX)) 1674252723Sdim return std::string(GCC_INSTALL_PREFIX); 1675252723Sdim 1676252723Sdim std::string InstallRelDir = InstalledDir + "/../../gnu"; 1677252723Sdim if (llvm::sys::fs::exists(InstallRelDir)) 1678252723Sdim return InstallRelDir; 1679252723Sdim 1680252723Sdim std::string PrefixRelDir = std::string(LLVM_PREFIX) + "/../gnu"; 1681252723Sdim if (llvm::sys::fs::exists(PrefixRelDir)) 1682252723Sdim return PrefixRelDir; 1683252723Sdim 1684252723Sdim return InstallRelDir; 1685235633Sdim} 1686235633Sdim 1687252723Sdimstatic void GetHexagonLibraryPaths( 1688252723Sdim const ArgList &Args, 1689252723Sdim const std::string Ver, 1690252723Sdim const std::string MarchString, 1691252723Sdim const std::string &InstalledDir, 1692252723Sdim ToolChain::path_list *LibPaths) 1693252723Sdim{ 1694252723Sdim bool buildingLib = Args.hasArg(options::OPT_shared); 1695252723Sdim 1696252723Sdim //---------------------------------------------------------------------------- 1697252723Sdim // -L Args 1698252723Sdim //---------------------------------------------------------------------------- 1699252723Sdim for (arg_iterator 1700252723Sdim it = Args.filtered_begin(options::OPT_L), 1701252723Sdim ie = Args.filtered_end(); 1702252723Sdim it != ie; 1703252723Sdim ++it) { 1704252723Sdim for (unsigned i = 0, e = (*it)->getNumValues(); i != e; ++i) 1705252723Sdim LibPaths->push_back((*it)->getValue(i)); 1706252723Sdim } 1707252723Sdim 1708252723Sdim //---------------------------------------------------------------------------- 1709252723Sdim // Other standard paths 1710252723Sdim //---------------------------------------------------------------------------- 1711252723Sdim const std::string MarchSuffix = "/" + MarchString; 1712252723Sdim const std::string G0Suffix = "/G0"; 1713252723Sdim const std::string MarchG0Suffix = MarchSuffix + G0Suffix; 1714252723Sdim const std::string RootDir = Hexagon_TC::GetGnuDir(InstalledDir) + "/"; 1715252723Sdim 1716252723Sdim // lib/gcc/hexagon/... 1717252723Sdim std::string LibGCCHexagonDir = RootDir + "lib/gcc/hexagon/"; 1718252723Sdim if (buildingLib) { 1719252723Sdim LibPaths->push_back(LibGCCHexagonDir + Ver + MarchG0Suffix); 1720252723Sdim LibPaths->push_back(LibGCCHexagonDir + Ver + G0Suffix); 1721252723Sdim } 1722252723Sdim LibPaths->push_back(LibGCCHexagonDir + Ver + MarchSuffix); 1723252723Sdim LibPaths->push_back(LibGCCHexagonDir + Ver); 1724252723Sdim 1725252723Sdim // lib/gcc/... 1726252723Sdim LibPaths->push_back(RootDir + "lib/gcc"); 1727252723Sdim 1728252723Sdim // hexagon/lib/... 1729252723Sdim std::string HexagonLibDir = RootDir + "hexagon/lib"; 1730252723Sdim if (buildingLib) { 1731252723Sdim LibPaths->push_back(HexagonLibDir + MarchG0Suffix); 1732252723Sdim LibPaths->push_back(HexagonLibDir + G0Suffix); 1733252723Sdim } 1734252723Sdim LibPaths->push_back(HexagonLibDir + MarchSuffix); 1735252723Sdim LibPaths->push_back(HexagonLibDir); 1736252723Sdim} 1737252723Sdim 1738252723SdimHexagon_TC::Hexagon_TC(const Driver &D, const llvm::Triple &Triple, 1739252723Sdim const ArgList &Args) 1740252723Sdim : Linux(D, Triple, Args) { 1741252723Sdim const std::string InstalledDir(getDriver().getInstalledDir()); 1742252723Sdim const std::string GnuDir = Hexagon_TC::GetGnuDir(InstalledDir); 1743252723Sdim 1744252723Sdim // Note: Generic_GCC::Generic_GCC adds InstalledDir and getDriver().Dir to 1745252723Sdim // program paths 1746252723Sdim const std::string BinDir(GnuDir + "/bin"); 1747252723Sdim if (llvm::sys::fs::exists(BinDir)) 1748252723Sdim getProgramPaths().push_back(BinDir); 1749252723Sdim 1750252723Sdim // Determine version of GCC libraries and headers to use. 1751252723Sdim const std::string HexagonDir(GnuDir + "/lib/gcc/hexagon"); 1752252723Sdim llvm::error_code ec; 1753252723Sdim GCCVersion MaxVersion= GCCVersion::Parse("0.0.0"); 1754252723Sdim for (llvm::sys::fs::directory_iterator di(HexagonDir, ec), de; 1755252723Sdim !ec && di != de; di = di.increment(ec)) { 1756252723Sdim GCCVersion cv = GCCVersion::Parse(llvm::sys::path::filename(di->path())); 1757252723Sdim if (MaxVersion < cv) 1758252723Sdim MaxVersion = cv; 1759252723Sdim } 1760252723Sdim GCCLibAndIncVersion = MaxVersion; 1761252723Sdim 1762252723Sdim ToolChain::path_list *LibPaths= &getFilePaths(); 1763252723Sdim 1764252723Sdim // Remove paths added by Linux toolchain. Currently Hexagon_TC really targets 1765252723Sdim // 'elf' OS type, so the Linux paths are not appropriate. When we actually 1766252723Sdim // support 'linux' we'll need to fix this up 1767252723Sdim LibPaths->clear(); 1768252723Sdim 1769252723Sdim GetHexagonLibraryPaths( 1770252723Sdim Args, 1771252723Sdim GetGCCLibAndIncVersion(), 1772252723Sdim GetTargetCPU(Args), 1773252723Sdim InstalledDir, 1774252723Sdim LibPaths); 1775252723Sdim} 1776252723Sdim 1777235633SdimHexagon_TC::~Hexagon_TC() { 1778235633Sdim} 1779235633Sdim 1780252723SdimTool *Hexagon_TC::buildAssembler() const { 1781252723Sdim return new tools::hexagon::Assemble(*this); 1782252723Sdim} 1783235633Sdim 1784252723SdimTool *Hexagon_TC::buildLinker() const { 1785252723Sdim return new tools::hexagon::Link(*this); 1786252723Sdim} 1787235633Sdim 1788252723Sdimvoid Hexagon_TC::AddClangSystemIncludeArgs(const ArgList &DriverArgs, 1789252723Sdim ArgStringList &CC1Args) const { 1790252723Sdim const Driver &D = getDriver(); 1791252723Sdim 1792252723Sdim if (DriverArgs.hasArg(options::OPT_nostdinc) || 1793252723Sdim DriverArgs.hasArg(options::OPT_nostdlibinc)) 1794252723Sdim return; 1795252723Sdim 1796252723Sdim std::string Ver(GetGCCLibAndIncVersion()); 1797252723Sdim std::string GnuDir = Hexagon_TC::GetGnuDir(D.InstalledDir); 1798252723Sdim std::string HexagonDir(GnuDir + "/lib/gcc/hexagon/" + Ver); 1799252723Sdim addExternCSystemInclude(DriverArgs, CC1Args, HexagonDir + "/include"); 1800252723Sdim addExternCSystemInclude(DriverArgs, CC1Args, HexagonDir + "/include-fixed"); 1801252723Sdim addExternCSystemInclude(DriverArgs, CC1Args, GnuDir + "/hexagon/include"); 1802252723Sdim} 1803252723Sdim 1804252723Sdimvoid Hexagon_TC::AddClangCXXStdlibIncludeArgs(const ArgList &DriverArgs, 1805252723Sdim ArgStringList &CC1Args) const { 1806252723Sdim 1807252723Sdim if (DriverArgs.hasArg(options::OPT_nostdlibinc) || 1808252723Sdim DriverArgs.hasArg(options::OPT_nostdincxx)) 1809252723Sdim return; 1810252723Sdim 1811252723Sdim const Driver &D = getDriver(); 1812252723Sdim std::string Ver(GetGCCLibAndIncVersion()); 1813263509Sdim SmallString<128> IncludeDir(Hexagon_TC::GetGnuDir(D.InstalledDir)); 1814252723Sdim 1815263509Sdim llvm::sys::path::append(IncludeDir, "hexagon/include/c++/"); 1816263509Sdim llvm::sys::path::append(IncludeDir, Ver); 1817252723Sdim addSystemInclude(DriverArgs, CC1Args, IncludeDir.str()); 1818252723Sdim} 1819252723Sdim 1820252723SdimToolChain::CXXStdlibType 1821252723SdimHexagon_TC::GetCXXStdlibType(const ArgList &Args) const { 1822252723Sdim Arg *A = Args.getLastArg(options::OPT_stdlib_EQ); 1823252723Sdim if (!A) 1824252723Sdim return ToolChain::CST_Libstdcxx; 1825252723Sdim 1826252723Sdim StringRef Value = A->getValue(); 1827252723Sdim if (Value != "libstdc++") { 1828252723Sdim getDriver().Diag(diag::err_drv_invalid_stdlib_name) 1829252723Sdim << A->getAsString(Args); 1830235633Sdim } 1831235633Sdim 1832252723Sdim return ToolChain::CST_Libstdcxx; 1833235633Sdim} 1834235633Sdim 1835263509Sdimstatic int getHexagonVersion(const ArgList &Args) { 1836263509Sdim Arg *A = Args.getLastArg(options::OPT_march_EQ, options::OPT_mcpu_EQ); 1837263509Sdim // Select the default CPU (v4) if none was given. 1838263509Sdim if (!A) 1839263509Sdim return 4; 1840252723Sdim 1841263509Sdim // FIXME: produce errors if we cannot parse the version. 1842263509Sdim StringRef WhichHexagon = A->getValue(); 1843263509Sdim if (WhichHexagon.startswith("hexagonv")) { 1844263509Sdim int Val; 1845263509Sdim if (!WhichHexagon.substr(sizeof("hexagonv") - 1).getAsInteger(10, Val)) 1846263509Sdim return Val; 1847252723Sdim } 1848263509Sdim if (WhichHexagon.startswith("v")) { 1849263509Sdim int Val; 1850263509Sdim if (!WhichHexagon.substr(1).getAsInteger(10, Val)) 1851263509Sdim return Val; 1852263509Sdim } 1853263509Sdim 1854263509Sdim // FIXME: should probably be an error. 1855263509Sdim return 4; 1856235633Sdim} 1857235633Sdim 1858252723SdimStringRef Hexagon_TC::GetTargetCPU(const ArgList &Args) 1859252723Sdim{ 1860263509Sdim int V = getHexagonVersion(Args); 1861263509Sdim // FIXME: We don't support versions < 4. We should error on them. 1862263509Sdim switch (V) { 1863263509Sdim default: 1864263509Sdim llvm_unreachable("Unexpected version"); 1865263509Sdim case 5: 1866263509Sdim return "v5"; 1867263509Sdim case 4: 1868263509Sdim return "v4"; 1869263509Sdim case 3: 1870263509Sdim return "v3"; 1871263509Sdim case 2: 1872263509Sdim return "v2"; 1873263509Sdim case 1: 1874263509Sdim return "v1"; 1875252723Sdim } 1876235633Sdim} 1877252723Sdim// End Hexagon 1878235633Sdim 1879204793Srdivacky/// TCEToolChain - A tool chain using the llvm bitcode tools to perform 1880204793Srdivacky/// all subcommands. See http://tce.cs.tut.fi for our peculiar target. 1881204793Srdivacky/// Currently does not support anything else but compilation. 1882204793Srdivacky 1883252723SdimTCEToolChain::TCEToolChain(const Driver &D, const llvm::Triple& Triple, 1884252723Sdim const ArgList &Args) 1885252723Sdim : ToolChain(D, Triple, Args) { 1886204793Srdivacky // Path mangling to find libexec 1887204793Srdivacky std::string Path(getDriver().Dir); 1888204793Srdivacky 1889204793Srdivacky Path += "/../libexec"; 1890204793Srdivacky getProgramPaths().push_back(Path); 1891204793Srdivacky} 1892204793Srdivacky 1893204793SrdivackyTCEToolChain::~TCEToolChain() { 1894204793Srdivacky} 1895204793Srdivacky 1896223017Sdimbool TCEToolChain::IsMathErrnoDefault() const { 1897223017Sdim return true; 1898204793Srdivacky} 1899204793Srdivacky 1900245431Sdimbool TCEToolChain::isPICDefault() const { 1901204793Srdivacky return false; 1902204793Srdivacky} 1903204793Srdivacky 1904252723Sdimbool TCEToolChain::isPIEDefault() const { 1905245431Sdim return false; 1906204793Srdivacky} 1907204793Srdivacky 1908252723Sdimbool TCEToolChain::isPICDefaultForced() const { 1909252723Sdim return false; 1910204793Srdivacky} 1911204793Srdivacky 1912195341Sed/// OpenBSD - OpenBSD tool chain which can call as(1) and ld(1) directly. 1913195341Sed 1914235633SdimOpenBSD::OpenBSD(const Driver &D, const llvm::Triple& Triple, const ArgList &Args) 1915235633Sdim : Generic_ELF(D, Triple, Args) { 1916201361Srdivacky getFilePaths().push_back(getDriver().Dir + "/../lib"); 1917195341Sed getFilePaths().push_back("/usr/lib"); 1918195341Sed} 1919195341Sed 1920252723SdimTool *OpenBSD::buildAssembler() const { 1921252723Sdim return new tools::openbsd::Assemble(*this); 1922252723Sdim} 1923195341Sed 1924252723SdimTool *OpenBSD::buildLinker() const { 1925252723Sdim return new tools::openbsd::Link(*this); 1926195341Sed} 1927195341Sed 1928245431Sdim/// Bitrig - Bitrig tool chain which can call as(1) and ld(1) directly. 1929245431Sdim 1930245431SdimBitrig::Bitrig(const Driver &D, const llvm::Triple& Triple, const ArgList &Args) 1931245431Sdim : Generic_ELF(D, Triple, Args) { 1932245431Sdim getFilePaths().push_back(getDriver().Dir + "/../lib"); 1933245431Sdim getFilePaths().push_back("/usr/lib"); 1934245431Sdim} 1935245431Sdim 1936252723SdimTool *Bitrig::buildAssembler() const { 1937252723Sdim return new tools::bitrig::Assemble(*this); 1938252723Sdim} 1939245431Sdim 1940252723SdimTool *Bitrig::buildLinker() const { 1941252723Sdim return new tools::bitrig::Link(*this); 1942245431Sdim} 1943245431Sdim 1944245431Sdimvoid Bitrig::AddClangCXXStdlibIncludeArgs(const ArgList &DriverArgs, 1945245431Sdim ArgStringList &CC1Args) const { 1946245431Sdim if (DriverArgs.hasArg(options::OPT_nostdlibinc) || 1947245431Sdim DriverArgs.hasArg(options::OPT_nostdincxx)) 1948245431Sdim return; 1949245431Sdim 1950245431Sdim switch (GetCXXStdlibType(DriverArgs)) { 1951245431Sdim case ToolChain::CST_Libcxx: 1952245431Sdim addSystemInclude(DriverArgs, CC1Args, 1953245431Sdim getDriver().SysRoot + "/usr/include/c++/"); 1954245431Sdim break; 1955245431Sdim case ToolChain::CST_Libstdcxx: 1956245431Sdim addSystemInclude(DriverArgs, CC1Args, 1957245431Sdim getDriver().SysRoot + "/usr/include/c++/stdc++"); 1958245431Sdim addSystemInclude(DriverArgs, CC1Args, 1959245431Sdim getDriver().SysRoot + "/usr/include/c++/stdc++/backward"); 1960245431Sdim 1961245431Sdim StringRef Triple = getTriple().str(); 1962245431Sdim if (Triple.startswith("amd64")) 1963245431Sdim addSystemInclude(DriverArgs, CC1Args, 1964245431Sdim getDriver().SysRoot + "/usr/include/c++/stdc++/x86_64" + 1965245431Sdim Triple.substr(5)); 1966245431Sdim else 1967245431Sdim addSystemInclude(DriverArgs, CC1Args, 1968245431Sdim getDriver().SysRoot + "/usr/include/c++/stdc++/" + 1969245431Sdim Triple); 1970245431Sdim break; 1971245431Sdim } 1972245431Sdim} 1973245431Sdim 1974245431Sdimvoid Bitrig::AddCXXStdlibLibArgs(const ArgList &Args, 1975245431Sdim ArgStringList &CmdArgs) const { 1976245431Sdim switch (GetCXXStdlibType(Args)) { 1977245431Sdim case ToolChain::CST_Libcxx: 1978245431Sdim CmdArgs.push_back("-lc++"); 1979245431Sdim CmdArgs.push_back("-lcxxrt"); 1980245431Sdim // Include supc++ to provide Unwind until provided by libcxx. 1981245431Sdim CmdArgs.push_back("-lgcc"); 1982245431Sdim break; 1983245431Sdim case ToolChain::CST_Libstdcxx: 1984245431Sdim CmdArgs.push_back("-lstdc++"); 1985245431Sdim break; 1986245431Sdim } 1987245431Sdim} 1988245431Sdim 1989193326Sed/// FreeBSD - FreeBSD tool chain which can call as(1) and ld(1) directly. 1990193326Sed 1991235633SdimFreeBSD::FreeBSD(const Driver &D, const llvm::Triple& Triple, const ArgList &Args) 1992235633Sdim : Generic_ELF(D, Triple, Args) { 1993212904Sdim 1994235633Sdim // When targeting 32-bit platforms, look for '/usr/lib32/crt1.o' and fall 1995235633Sdim // back to '/usr/lib' if it doesn't exist. 1996235633Sdim if ((Triple.getArch() == llvm::Triple::x86 || 1997235633Sdim Triple.getArch() == llvm::Triple::ppc) && 1998235633Sdim llvm::sys::fs::exists(getDriver().SysRoot + "/usr/lib32/crt1.o")) 1999235633Sdim getFilePaths().push_back(getDriver().SysRoot + "/usr/lib32"); 2000235633Sdim else 2001235633Sdim getFilePaths().push_back(getDriver().SysRoot + "/usr/lib"); 2002193326Sed} 2003193326Sed 2004263509SdimToolChain::CXXStdlibType 2005263509SdimFreeBSD::GetCXXStdlibType(const ArgList &Args) const { 2006263509Sdim if (Arg *A = Args.getLastArg(options::OPT_stdlib_EQ)) { 2007263509Sdim StringRef Value = A->getValue(); 2008263509Sdim if (Value == "libstdc++") 2009263509Sdim return ToolChain::CST_Libstdcxx; 2010263509Sdim if (Value == "libc++") 2011263509Sdim return ToolChain::CST_Libcxx; 2012263509Sdim 2013263509Sdim getDriver().Diag(diag::err_drv_invalid_stdlib_name) 2014263509Sdim << A->getAsString(Args); 2015263509Sdim } 2016263509Sdim if (getTriple().getOSMajorVersion() >= 10) 2017263509Sdim return ToolChain::CST_Libcxx; 2018263509Sdim return ToolChain::CST_Libstdcxx; 2019263509Sdim} 2020263509Sdim 2021263509Sdimvoid FreeBSD::AddClangCXXStdlibIncludeArgs(const ArgList &DriverArgs, 2022263509Sdim ArgStringList &CC1Args) const { 2023263509Sdim if (DriverArgs.hasArg(options::OPT_nostdlibinc) || 2024263509Sdim DriverArgs.hasArg(options::OPT_nostdincxx)) 2025263509Sdim return; 2026263509Sdim 2027263509Sdim switch (GetCXXStdlibType(DriverArgs)) { 2028263509Sdim case ToolChain::CST_Libcxx: 2029263509Sdim addSystemInclude(DriverArgs, CC1Args, 2030263509Sdim getDriver().SysRoot + "/usr/include/c++/v1"); 2031263509Sdim break; 2032263509Sdim case ToolChain::CST_Libstdcxx: 2033263509Sdim addSystemInclude(DriverArgs, CC1Args, 2034263509Sdim getDriver().SysRoot + "/usr/include/c++/4.2"); 2035263509Sdim addSystemInclude(DriverArgs, CC1Args, 2036263509Sdim getDriver().SysRoot + "/usr/include/c++/4.2/backward"); 2037263509Sdim break; 2038263509Sdim } 2039263509Sdim} 2040263509Sdim 2041252723SdimTool *FreeBSD::buildAssembler() const { 2042252723Sdim return new tools::freebsd::Assemble(*this); 2043252723Sdim} 2044193326Sed 2045252723SdimTool *FreeBSD::buildLinker() const { 2046252723Sdim return new tools::freebsd::Link(*this); 2047193326Sed} 2048193326Sed 2049245431Sdimbool FreeBSD::UseSjLjExceptions() const { 2050245431Sdim // FreeBSD uses SjLj exceptions on ARM oabi. 2051245431Sdim switch (getTriple().getEnvironment()) { 2052245431Sdim case llvm::Triple::GNUEABI: 2053245431Sdim case llvm::Triple::EABI: 2054245431Sdim return false; 2055245431Sdim 2056245431Sdim default: 2057245431Sdim return (getTriple().getArch() == llvm::Triple::arm || 2058245431Sdim getTriple().getArch() == llvm::Triple::thumb); 2059245431Sdim } 2060245431Sdim} 2061245431Sdim 2062218893Sdim/// NetBSD - NetBSD tool chain which can call as(1) and ld(1) directly. 2063218893Sdim 2064235633SdimNetBSD::NetBSD(const Driver &D, const llvm::Triple& Triple, const ArgList &Args) 2065235633Sdim : Generic_ELF(D, Triple, Args) { 2066218893Sdim 2067221345Sdim if (getDriver().UseStdLib) { 2068235633Sdim // When targeting a 32-bit platform, try the special directory used on 2069235633Sdim // 64-bit hosts, and only fall back to the main library directory if that 2070235633Sdim // doesn't work. 2071235633Sdim // FIXME: It'd be nicer to test if this directory exists, but I'm not sure 2072235633Sdim // what all logic is needed to emulate the '=' prefix here. 2073235633Sdim if (Triple.getArch() == llvm::Triple::x86) 2074221345Sdim getFilePaths().push_back("=/usr/lib/i386"); 2075235633Sdim 2076235633Sdim getFilePaths().push_back("=/usr/lib"); 2077218893Sdim } 2078218893Sdim} 2079218893Sdim 2080252723SdimTool *NetBSD::buildAssembler() const { 2081252723Sdim return new tools::netbsd::Assemble(*this); 2082252723Sdim} 2083218893Sdim 2084252723SdimTool *NetBSD::buildLinker() const { 2085252723Sdim return new tools::netbsd::Link(*this); 2086252723Sdim} 2087218893Sdim 2088252723SdimToolChain::CXXStdlibType 2089252723SdimNetBSD::GetCXXStdlibType(const ArgList &Args) const { 2090252723Sdim if (Arg *A = Args.getLastArg(options::OPT_stdlib_EQ)) { 2091252723Sdim StringRef Value = A->getValue(); 2092252723Sdim if (Value == "libstdc++") 2093252723Sdim return ToolChain::CST_Libstdcxx; 2094252723Sdim if (Value == "libc++") 2095252723Sdim return ToolChain::CST_Libcxx; 2096252723Sdim 2097252723Sdim getDriver().Diag(diag::err_drv_invalid_stdlib_name) 2098252723Sdim << A->getAsString(Args); 2099218893Sdim } 2100218893Sdim 2101263509Sdim unsigned Major, Minor, Micro; 2102263509Sdim getTriple().getOSVersion(Major, Minor, Micro); 2103263509Sdim if (Major >= 7 || (Major == 6 && Minor == 99 && Micro >= 23) || Major == 0) { 2104263509Sdim if (getArch() == llvm::Triple::x86 || getArch() == llvm::Triple::x86_64) 2105263509Sdim return ToolChain::CST_Libcxx; 2106263509Sdim } 2107252723Sdim return ToolChain::CST_Libstdcxx; 2108218893Sdim} 2109218893Sdim 2110252723Sdimvoid NetBSD::AddClangCXXStdlibIncludeArgs(const ArgList &DriverArgs, 2111252723Sdim ArgStringList &CC1Args) const { 2112252723Sdim if (DriverArgs.hasArg(options::OPT_nostdlibinc) || 2113252723Sdim DriverArgs.hasArg(options::OPT_nostdincxx)) 2114252723Sdim return; 2115252723Sdim 2116252723Sdim switch (GetCXXStdlibType(DriverArgs)) { 2117252723Sdim case ToolChain::CST_Libcxx: 2118252723Sdim addSystemInclude(DriverArgs, CC1Args, 2119252723Sdim getDriver().SysRoot + "/usr/include/c++/"); 2120252723Sdim break; 2121252723Sdim case ToolChain::CST_Libstdcxx: 2122252723Sdim addSystemInclude(DriverArgs, CC1Args, 2123252723Sdim getDriver().SysRoot + "/usr/include/g++"); 2124252723Sdim addSystemInclude(DriverArgs, CC1Args, 2125252723Sdim getDriver().SysRoot + "/usr/include/g++/backward"); 2126252723Sdim break; 2127252723Sdim } 2128252723Sdim} 2129252723Sdim 2130210299Sed/// Minix - Minix tool chain which can call as(1) and ld(1) directly. 2131210299Sed 2132235633SdimMinix::Minix(const Driver &D, const llvm::Triple& Triple, const ArgList &Args) 2133235633Sdim : Generic_ELF(D, Triple, Args) { 2134210299Sed getFilePaths().push_back(getDriver().Dir + "/../lib"); 2135210299Sed getFilePaths().push_back("/usr/lib"); 2136210299Sed} 2137210299Sed 2138252723SdimTool *Minix::buildAssembler() const { 2139252723Sdim return new tools::minix::Assemble(*this); 2140252723Sdim} 2141210299Sed 2142252723SdimTool *Minix::buildLinker() const { 2143252723Sdim return new tools::minix::Link(*this); 2144210299Sed} 2145210299Sed 2146198092Srdivacky/// AuroraUX - AuroraUX tool chain which can call as(1) and ld(1) directly. 2147198092Srdivacky 2148235633SdimAuroraUX::AuroraUX(const Driver &D, const llvm::Triple& Triple, 2149235633Sdim const ArgList &Args) 2150235633Sdim : Generic_GCC(D, Triple, Args) { 2151198092Srdivacky 2152212904Sdim getProgramPaths().push_back(getDriver().getInstalledDir()); 2153221345Sdim if (getDriver().getInstalledDir() != getDriver().Dir) 2154212904Sdim getProgramPaths().push_back(getDriver().Dir); 2155198092Srdivacky 2156201361Srdivacky getFilePaths().push_back(getDriver().Dir + "/../lib"); 2157198092Srdivacky getFilePaths().push_back("/usr/lib"); 2158198092Srdivacky getFilePaths().push_back("/usr/sfw/lib"); 2159198092Srdivacky getFilePaths().push_back("/opt/gcc4/lib"); 2160198398Srdivacky getFilePaths().push_back("/opt/gcc4/lib/gcc/i386-pc-solaris2.11/4.2.4"); 2161198092Srdivacky 2162198092Srdivacky} 2163198092Srdivacky 2164252723SdimTool *AuroraUX::buildAssembler() const { 2165252723Sdim return new tools::auroraux::Assemble(*this); 2166252723Sdim} 2167198092Srdivacky 2168252723SdimTool *AuroraUX::buildLinker() const { 2169252723Sdim return new tools::auroraux::Link(*this); 2170198092Srdivacky} 2171198092Srdivacky 2172235633Sdim/// Solaris - Solaris tool chain which can call as(1) and ld(1) directly. 2173198092Srdivacky 2174235633SdimSolaris::Solaris(const Driver &D, const llvm::Triple& Triple, 2175235633Sdim const ArgList &Args) 2176235633Sdim : Generic_GCC(D, Triple, Args) { 2177235633Sdim 2178235633Sdim getProgramPaths().push_back(getDriver().getInstalledDir()); 2179235633Sdim if (getDriver().getInstalledDir() != getDriver().Dir) 2180235633Sdim getProgramPaths().push_back(getDriver().Dir); 2181235633Sdim 2182235633Sdim getFilePaths().push_back(getDriver().Dir + "/../lib"); 2183235633Sdim getFilePaths().push_back("/usr/lib"); 2184235633Sdim} 2185235633Sdim 2186252723SdimTool *Solaris::buildAssembler() const { 2187252723Sdim return new tools::solaris::Assemble(*this); 2188252723Sdim} 2189235633Sdim 2190252723SdimTool *Solaris::buildLinker() const { 2191252723Sdim return new tools::solaris::Link(*this); 2192235633Sdim} 2193235633Sdim 2194252723Sdim/// Distribution (very bare-bones at the moment). 2195193326Sed 2196252723Sdimenum Distro { 2197219077Sdim ArchLinux, 2198218893Sdim DebianLenny, 2199218893Sdim DebianSqueeze, 2200223017Sdim DebianWheezy, 2201252723Sdim DebianJessie, 2202218893Sdim Exherbo, 2203223017Sdim RHEL4, 2204223017Sdim RHEL5, 2205223017Sdim RHEL6, 2206263509Sdim Fedora, 2207263509Sdim OpenSUSE, 2208221345Sdim UbuntuHardy, 2209221345Sdim UbuntuIntrepid, 2210218893Sdim UbuntuJaunty, 2211218893Sdim UbuntuKarmic, 2212218893Sdim UbuntuLucid, 2213218893Sdim UbuntuMaverick, 2214221345Sdim UbuntuNatty, 2215223017Sdim UbuntuOneiric, 2216235633Sdim UbuntuPrecise, 2217245431Sdim UbuntuQuantal, 2218245431Sdim UbuntuRaring, 2219263509Sdim UbuntuSaucy, 2220263509Sdim UbuntuTrusty, 2221218893Sdim UnknownDistro 2222218893Sdim}; 2223198092Srdivacky 2224252723Sdimstatic bool IsRedhat(enum Distro Distro) { 2225263509Sdim return Distro == Fedora || (Distro >= RHEL4 && Distro <= RHEL6); 2226218893Sdim} 2227198092Srdivacky 2228263509Sdimstatic bool IsOpenSUSE(enum Distro Distro) { 2229263509Sdim return Distro == OpenSUSE; 2230193326Sed} 2231193326Sed 2232252723Sdimstatic bool IsDebian(enum Distro Distro) { 2233252723Sdim return Distro >= DebianLenny && Distro <= DebianJessie; 2234218893Sdim} 2235218893Sdim 2236252723Sdimstatic bool IsUbuntu(enum Distro Distro) { 2237263509Sdim return Distro >= UbuntuHardy && Distro <= UbuntuTrusty; 2238218893Sdim} 2239218893Sdim 2240252723Sdimstatic Distro DetectDistro(llvm::Triple::ArchType Arch) { 2241235633Sdim OwningPtr<llvm::MemoryBuffer> File; 2242218893Sdim if (!llvm::MemoryBuffer::getFile("/etc/lsb-release", File)) { 2243226890Sdim StringRef Data = File.get()->getBuffer(); 2244226890Sdim SmallVector<StringRef, 8> Lines; 2245218893Sdim Data.split(Lines, "\n"); 2246252723Sdim Distro Version = UnknownDistro; 2247235633Sdim for (unsigned i = 0, s = Lines.size(); i != s; ++i) 2248235633Sdim if (Version == UnknownDistro && Lines[i].startswith("DISTRIB_CODENAME=")) 2249252723Sdim Version = llvm::StringSwitch<Distro>(Lines[i].substr(17)) 2250235633Sdim .Case("hardy", UbuntuHardy) 2251235633Sdim .Case("intrepid", UbuntuIntrepid) 2252235633Sdim .Case("jaunty", UbuntuJaunty) 2253235633Sdim .Case("karmic", UbuntuKarmic) 2254235633Sdim .Case("lucid", UbuntuLucid) 2255235633Sdim .Case("maverick", UbuntuMaverick) 2256235633Sdim .Case("natty", UbuntuNatty) 2257235633Sdim .Case("oneiric", UbuntuOneiric) 2258235633Sdim .Case("precise", UbuntuPrecise) 2259245431Sdim .Case("quantal", UbuntuQuantal) 2260245431Sdim .Case("raring", UbuntuRaring) 2261263509Sdim .Case("saucy", UbuntuSaucy) 2262263509Sdim .Case("trusty", UbuntuTrusty) 2263235633Sdim .Default(UnknownDistro); 2264235633Sdim return Version; 2265218893Sdim } 2266218893Sdim 2267218893Sdim if (!llvm::MemoryBuffer::getFile("/etc/redhat-release", File)) { 2268226890Sdim StringRef Data = File.get()->getBuffer(); 2269263509Sdim if (Data.startswith("Fedora release")) 2270263509Sdim return Fedora; 2271223017Sdim else if (Data.startswith("Red Hat Enterprise Linux") && 2272226890Sdim Data.find("release 6") != StringRef::npos) 2273223017Sdim return RHEL6; 2274223017Sdim else if ((Data.startswith("Red Hat Enterprise Linux") || 2275252723Sdim Data.startswith("CentOS")) && 2276226890Sdim Data.find("release 5") != StringRef::npos) 2277223017Sdim return RHEL5; 2278223017Sdim else if ((Data.startswith("Red Hat Enterprise Linux") || 2279252723Sdim Data.startswith("CentOS")) && 2280226890Sdim Data.find("release 4") != StringRef::npos) 2281223017Sdim return RHEL4; 2282218893Sdim return UnknownDistro; 2283218893Sdim } 2284218893Sdim 2285218893Sdim if (!llvm::MemoryBuffer::getFile("/etc/debian_version", File)) { 2286226890Sdim StringRef Data = File.get()->getBuffer(); 2287218893Sdim if (Data[0] == '5') 2288218893Sdim return DebianLenny; 2289235633Sdim else if (Data.startswith("squeeze/sid") || Data[0] == '6') 2290218893Sdim return DebianSqueeze; 2291235633Sdim else if (Data.startswith("wheezy/sid") || Data[0] == '7') 2292223017Sdim return DebianWheezy; 2293252723Sdim else if (Data.startswith("jessie/sid") || Data[0] == '8') 2294252723Sdim return DebianJessie; 2295218893Sdim return UnknownDistro; 2296218893Sdim } 2297218893Sdim 2298263509Sdim if (llvm::sys::fs::exists("/etc/SuSE-release")) 2299263509Sdim return OpenSUSE; 2300218893Sdim 2301263509Sdim if (llvm::sys::fs::exists("/etc/exherbo-release")) 2302218893Sdim return Exherbo; 2303218893Sdim 2304263509Sdim if (llvm::sys::fs::exists("/etc/arch-release")) 2305219077Sdim return ArchLinux; 2306219077Sdim 2307218893Sdim return UnknownDistro; 2308218893Sdim} 2309218893Sdim 2310229042Sdim/// \brief Get our best guess at the multiarch triple for a target. 2311229042Sdim/// 2312229042Sdim/// Debian-based systems are starting to use a multiarch setup where they use 2313229042Sdim/// a target-triple directory in the library and header search paths. 2314229042Sdim/// Unfortunately, this triple does not align with the vanilla target triple, 2315229042Sdim/// so we provide a rough mapping here. 2316229042Sdimstatic std::string getMultiarchTriple(const llvm::Triple TargetTriple, 2317229042Sdim StringRef SysRoot) { 2318229042Sdim // For most architectures, just use whatever we have rather than trying to be 2319229042Sdim // clever. 2320229042Sdim switch (TargetTriple.getArch()) { 2321229042Sdim default: 2322229042Sdim return TargetTriple.str(); 2323226890Sdim 2324229042Sdim // We use the existence of '/lib/<triple>' as a directory to detect some 2325229042Sdim // common linux triples that don't quite match the Clang triple for both 2326235633Sdim // 32-bit and 64-bit targets. Multiarch fixes its install triples to these 2327235633Sdim // regardless of what the actual target triple is. 2328245431Sdim case llvm::Triple::arm: 2329245431Sdim case llvm::Triple::thumb: 2330245431Sdim if (TargetTriple.getEnvironment() == llvm::Triple::GNUEABIHF) { 2331245431Sdim if (llvm::sys::fs::exists(SysRoot + "/lib/arm-linux-gnueabihf")) 2332245431Sdim return "arm-linux-gnueabihf"; 2333245431Sdim } else { 2334245431Sdim if (llvm::sys::fs::exists(SysRoot + "/lib/arm-linux-gnueabi")) 2335245431Sdim return "arm-linux-gnueabi"; 2336245431Sdim } 2337245431Sdim return TargetTriple.str(); 2338229042Sdim case llvm::Triple::x86: 2339229042Sdim if (llvm::sys::fs::exists(SysRoot + "/lib/i386-linux-gnu")) 2340229042Sdim return "i386-linux-gnu"; 2341229042Sdim return TargetTriple.str(); 2342229042Sdim case llvm::Triple::x86_64: 2343229042Sdim if (llvm::sys::fs::exists(SysRoot + "/lib/x86_64-linux-gnu")) 2344229042Sdim return "x86_64-linux-gnu"; 2345229042Sdim return TargetTriple.str(); 2346252723Sdim case llvm::Triple::aarch64: 2347252723Sdim if (llvm::sys::fs::exists(SysRoot + "/lib/aarch64-linux-gnu")) 2348252723Sdim return "aarch64-linux-gnu"; 2349263509Sdim return TargetTriple.str(); 2350235633Sdim case llvm::Triple::mips: 2351235633Sdim if (llvm::sys::fs::exists(SysRoot + "/lib/mips-linux-gnu")) 2352235633Sdim return "mips-linux-gnu"; 2353235633Sdim return TargetTriple.str(); 2354235633Sdim case llvm::Triple::mipsel: 2355235633Sdim if (llvm::sys::fs::exists(SysRoot + "/lib/mipsel-linux-gnu")) 2356235633Sdim return "mipsel-linux-gnu"; 2357235633Sdim return TargetTriple.str(); 2358235633Sdim case llvm::Triple::ppc: 2359252723Sdim if (llvm::sys::fs::exists(SysRoot + "/lib/powerpc-linux-gnuspe")) 2360252723Sdim return "powerpc-linux-gnuspe"; 2361235633Sdim if (llvm::sys::fs::exists(SysRoot + "/lib/powerpc-linux-gnu")) 2362235633Sdim return "powerpc-linux-gnu"; 2363235633Sdim return TargetTriple.str(); 2364235633Sdim case llvm::Triple::ppc64: 2365235633Sdim if (llvm::sys::fs::exists(SysRoot + "/lib/powerpc64-linux-gnu")) 2366235633Sdim return "powerpc64-linux-gnu"; 2367263509Sdim case llvm::Triple::ppc64le: 2368263509Sdim if (llvm::sys::fs::exists(SysRoot + "/lib/powerpc64le-linux-gnu")) 2369263509Sdim return "powerpc64le-linux-gnu"; 2370235633Sdim return TargetTriple.str(); 2371226890Sdim } 2372226890Sdim} 2373226890Sdim 2374235633Sdimstatic void addPathIfExists(Twine Path, ToolChain::path_list &Paths) { 2375235633Sdim if (llvm::sys::fs::exists(Path)) Paths.push_back(Path.str()); 2376235633Sdim} 2377235633Sdim 2378245431Sdimstatic StringRef getMultilibDir(const llvm::Triple &Triple, 2379245431Sdim const ArgList &Args) { 2380263509Sdim if (isMipsArch(Triple.getArch())) { 2381263509Sdim // lib32 directory has a special meaning on MIPS targets. 2382263509Sdim // It contains N32 ABI binaries. Use this folder if produce 2383263509Sdim // code for N32 ABI only. 2384263509Sdim if (hasMipsN32ABIArg(Args)) 2385263509Sdim return "lib32"; 2386263509Sdim return Triple.isArch32Bit() ? "lib" : "lib64"; 2387263509Sdim } 2388245431Sdim 2389263509Sdim // It happens that only x86 and PPC use the 'lib32' variant of multilib, and 2390263509Sdim // using that variant while targeting other architectures causes problems 2391263509Sdim // because the libraries are laid out in shared system roots that can't cope 2392263509Sdim // with a 'lib32' multilib search path being considered. So we only enable 2393263509Sdim // them when we know we may need it. 2394263509Sdim // 2395263509Sdim // FIXME: This is a bit of a hack. We should really unify this code for 2396263509Sdim // reasoning about multilib spellings with the lib dir spellings in the 2397263509Sdim // GCCInstallationDetector, but that is a more significant refactoring. 2398263509Sdim if (Triple.getArch() == llvm::Triple::x86 || 2399263509Sdim Triple.getArch() == llvm::Triple::ppc) 2400245431Sdim return "lib32"; 2401245431Sdim 2402245431Sdim return Triple.isArch32Bit() ? "lib" : "lib64"; 2403245431Sdim} 2404245431Sdim 2405235633SdimLinux::Linux(const Driver &D, const llvm::Triple &Triple, const ArgList &Args) 2406235633Sdim : Generic_ELF(D, Triple, Args) { 2407263509Sdim GCCInstallation.init(Triple, Args); 2408235633Sdim llvm::Triple::ArchType Arch = Triple.getArch(); 2409263509Sdim std::string SysRoot = computeSysRoot(); 2410226890Sdim 2411263509Sdim // Cross-compiling binutils and GCC installations (vanilla and openSUSE at 2412263509Sdim // least) put various tools in a triple-prefixed directory off of the parent 2413263509Sdim // of the GCC installation. We use the GCC triple here to ensure that we end 2414263509Sdim // up with tools that support the same amount of cross compiling as the 2415263509Sdim // detected GCC installation. For example, if we find a GCC installation 2416263509Sdim // targeting x86_64, but it is a bi-arch GCC installation, it can also be 2417263509Sdim // used to target i386. 2418263509Sdim // FIXME: This seems unlikely to be Linux-specific. 2419226890Sdim ToolChain::path_list &PPaths = getProgramPaths(); 2420229042Sdim PPaths.push_back(Twine(GCCInstallation.getParentLibPath() + "/../" + 2421235633Sdim GCCInstallation.getTriple().str() + "/bin").str()); 2422226890Sdim 2423226890Sdim Linker = GetProgramPath("ld"); 2424226890Sdim 2425252723Sdim Distro Distro = DetectDistro(Arch); 2426218893Sdim 2427263509Sdim if (IsOpenSUSE(Distro) || IsUbuntu(Distro)) { 2428218893Sdim ExtraOpts.push_back("-z"); 2429218893Sdim ExtraOpts.push_back("relro"); 2430218893Sdim } 2431218893Sdim 2432221345Sdim if (Arch == llvm::Triple::arm || Arch == llvm::Triple::thumb) 2433218893Sdim ExtraOpts.push_back("-X"); 2434218893Sdim 2435245431Sdim const bool IsAndroid = Triple.getEnvironment() == llvm::Triple::Android; 2436252723Sdim const bool IsMips = isMipsArch(Arch); 2437218893Sdim 2438252723Sdim if (IsMips && !SysRoot.empty()) 2439252723Sdim ExtraOpts.push_back("--sysroot=" + SysRoot); 2440252723Sdim 2441235633Sdim // Do not use 'gnu' hash style for Mips targets because .gnu.hash 2442235633Sdim // and the MIPS ABI require .dynsym to be sorted in different ways. 2443235633Sdim // .gnu.hash needs symbols to be grouped by hash code whereas the MIPS 2444235633Sdim // ABI requires a mapping between the GOT and the symbol table. 2445235633Sdim // Android loader does not support .gnu.hash. 2446252723Sdim if (!IsMips && !IsAndroid) { 2447263509Sdim if (IsRedhat(Distro) || IsOpenSUSE(Distro) || 2448235633Sdim (IsUbuntu(Distro) && Distro >= UbuntuMaverick)) 2449235633Sdim ExtraOpts.push_back("--hash-style=gnu"); 2450235633Sdim 2451263509Sdim if (IsDebian(Distro) || IsOpenSUSE(Distro) || Distro == UbuntuLucid || 2452235633Sdim Distro == UbuntuJaunty || Distro == UbuntuKarmic) 2453235633Sdim ExtraOpts.push_back("--hash-style=both"); 2454235633Sdim } 2455235633Sdim 2456223017Sdim if (IsRedhat(Distro)) 2457218893Sdim ExtraOpts.push_back("--no-add-needed"); 2458218893Sdim 2459223017Sdim if (Distro == DebianSqueeze || Distro == DebianWheezy || 2460263509Sdim Distro == DebianJessie || IsOpenSUSE(Distro) || 2461223017Sdim (IsRedhat(Distro) && Distro != RHEL4 && Distro != RHEL5) || 2462235633Sdim (IsUbuntu(Distro) && Distro >= UbuntuKarmic)) 2463218893Sdim ExtraOpts.push_back("--build-id"); 2464218893Sdim 2465263509Sdim if (IsOpenSUSE(Distro)) 2466223017Sdim ExtraOpts.push_back("--enable-new-dtags"); 2467223017Sdim 2468226890Sdim // The selection of paths to try here is designed to match the patterns which 2469226890Sdim // the GCC driver itself uses, as this is part of the GCC-compatible driver. 2470226890Sdim // This was determined by running GCC in a fake filesystem, creating all 2471226890Sdim // possible permutations of these directories, and seeing which ones it added 2472226890Sdim // to the link paths. 2473226890Sdim path_list &Paths = getFilePaths(); 2474219077Sdim 2475245431Sdim const std::string Multilib = getMultilibDir(Triple, Args); 2476229042Sdim const std::string MultiarchTriple = getMultiarchTriple(Triple, SysRoot); 2477226890Sdim 2478229042Sdim // Add the multilib suffixed paths where they are available. 2479229042Sdim if (GCCInstallation.isValid()) { 2480235633Sdim const llvm::Triple &GCCTriple = GCCInstallation.getTriple(); 2481229042Sdim const std::string &LibPath = GCCInstallation.getParentLibPath(); 2482235633Sdim 2483263509Sdim // Sourcery CodeBench MIPS toolchain holds some libraries under 2484263509Sdim // a biarch-like suffix of the GCC installation. 2485263509Sdim // 2486263509Sdim // FIXME: It would be cleaner to model this as a variant of bi-arch. IE, 2487263509Sdim // instead of a '64' biarch suffix it would be 'el' or something. 2488263509Sdim if (IsAndroid && IsMips && isMips32r2(Args)) { 2489263509Sdim assert(GCCInstallation.getBiarchSuffix().empty() && 2490263509Sdim "Unexpected bi-arch suffix"); 2491263509Sdim addPathIfExists(GCCInstallation.getInstallPath() + "/mips-r2", Paths); 2492263509Sdim } else { 2493245431Sdim addPathIfExists((GCCInstallation.getInstallPath() + 2494263509Sdim GCCInstallation.getMIPSABIDirSuffix() + 2495263509Sdim GCCInstallation.getBiarchSuffix()), 2496245431Sdim Paths); 2497263509Sdim } 2498245431Sdim 2499263509Sdim // GCC cross compiling toolchains will install target libraries which ship 2500263509Sdim // as part of the toolchain under <prefix>/<triple>/<libdir> rather than as 2501263509Sdim // any part of the GCC installation in 2502263509Sdim // <prefix>/<libdir>/gcc/<triple>/<version>. This decision is somewhat 2503263509Sdim // debatable, but is the reality today. We need to search this tree even 2504263509Sdim // when we have a sysroot somewhere else. It is the responsibility of 2505263509Sdim // whomever is doing the cross build targetting a sysroot using a GCC 2506263509Sdim // installation that is *not* within the system root to ensure two things: 2507263509Sdim // 2508263509Sdim // 1) Any DSOs that are linked in from this tree or from the install path 2509263509Sdim // above must be preasant on the system root and found via an 2510263509Sdim // appropriate rpath. 2511263509Sdim // 2) There must not be libraries installed into 2512263509Sdim // <prefix>/<triple>/<libdir> unless they should be preferred over 2513263509Sdim // those within the system root. 2514263509Sdim // 2515263509Sdim // Note that this matches the GCC behavior. See the below comment for where 2516263509Sdim // Clang diverges from GCC's behavior. 2517263509Sdim addPathIfExists(LibPath + "/../" + GCCTriple.str() + "/lib/../" + Multilib + 2518263509Sdim GCCInstallation.getMIPSABIDirSuffix(), 2519263509Sdim Paths); 2520263509Sdim 2521235633Sdim // If the GCC installation we found is inside of the sysroot, we want to 2522235633Sdim // prefer libraries installed in the parent prefix of the GCC installation. 2523235633Sdim // It is important to *not* use these paths when the GCC installation is 2524235633Sdim // outside of the system root as that can pick up unintended libraries. 2525235633Sdim // This usually happens when there is an external cross compiler on the 2526235633Sdim // host system, and a more minimal sysroot available that is the target of 2527263509Sdim // the cross. Note that GCC does include some of these directories in some 2528263509Sdim // configurations but this seems somewhere between questionable and simply 2529263509Sdim // a bug. 2530235633Sdim if (StringRef(LibPath).startswith(SysRoot)) { 2531235633Sdim addPathIfExists(LibPath + "/" + MultiarchTriple, Paths); 2532235633Sdim addPathIfExists(LibPath + "/../" + Multilib, Paths); 2533235633Sdim } 2534229042Sdim } 2535229042Sdim addPathIfExists(SysRoot + "/lib/" + MultiarchTriple, Paths); 2536229042Sdim addPathIfExists(SysRoot + "/lib/../" + Multilib, Paths); 2537229042Sdim addPathIfExists(SysRoot + "/usr/lib/" + MultiarchTriple, Paths); 2538229042Sdim addPathIfExists(SysRoot + "/usr/lib/../" + Multilib, Paths); 2539226890Sdim 2540263509Sdim // Try walking via the GCC triple path in case of biarch or multiarch GCC 2541229042Sdim // installations with strange symlinks. 2542263509Sdim if (GCCInstallation.isValid()) { 2543235633Sdim addPathIfExists(SysRoot + "/usr/lib/" + GCCInstallation.getTriple().str() + 2544229042Sdim "/../../" + Multilib, Paths); 2545226890Sdim 2546263509Sdim // Add the non-multilib suffixed paths (if potentially different). 2547226890Sdim const std::string &LibPath = GCCInstallation.getParentLibPath(); 2548235633Sdim const llvm::Triple &GCCTriple = GCCInstallation.getTriple(); 2549263509Sdim if (!GCCInstallation.getBiarchSuffix().empty()) 2550263509Sdim addPathIfExists(GCCInstallation.getInstallPath() + 2551263509Sdim GCCInstallation.getMIPSABIDirSuffix(), Paths); 2552235633Sdim 2553263509Sdim // See comments above on the multilib variant for details of why this is 2554263509Sdim // included even from outside the sysroot. 2555263509Sdim addPathIfExists(LibPath + "/../" + GCCTriple.str() + 2556263509Sdim "/lib" + GCCInstallation.getMIPSABIDirSuffix(), Paths); 2557263509Sdim 2558263509Sdim // See comments above on the multilib variant for details of why this is 2559263509Sdim // only included from within the sysroot. 2560263509Sdim if (StringRef(LibPath).startswith(SysRoot)) 2561235633Sdim addPathIfExists(LibPath, Paths); 2562226890Sdim } 2563226890Sdim addPathIfExists(SysRoot + "/lib", Paths); 2564226890Sdim addPathIfExists(SysRoot + "/usr/lib", Paths); 2565263509Sdim} 2566252723Sdim 2567263509Sdimbool FreeBSD::HasNativeLLVMSupport() const { 2568263509Sdim return true; 2569218893Sdim} 2570218893Sdim 2571218893Sdimbool Linux::HasNativeLLVMSupport() const { 2572218893Sdim return true; 2573218893Sdim} 2574218893Sdim 2575252723SdimTool *Linux::buildLinker() const { 2576252723Sdim return new tools::gnutools::Link(*this); 2577252723Sdim} 2578212904Sdim 2579252723SdimTool *Linux::buildAssembler() const { 2580252723Sdim return new tools::gnutools::Assemble(*this); 2581212904Sdim} 2582212904Sdim 2583263509Sdimstd::string Linux::computeSysRoot() const { 2584252723Sdim if (!getDriver().SysRoot.empty()) 2585252723Sdim return getDriver().SysRoot; 2586252723Sdim 2587252723Sdim if (!GCCInstallation.isValid() || !isMipsArch(getTriple().getArch())) 2588252723Sdim return std::string(); 2589252723Sdim 2590263509Sdim // Standalone MIPS toolchains use different names for sysroot folder 2591263509Sdim // and put it into different places. Here we try to check some known 2592263509Sdim // variants. 2593252723Sdim 2594263509Sdim const StringRef InstallDir = GCCInstallation.getInstallPath(); 2595263509Sdim const StringRef TripleStr = GCCInstallation.getTriple().str(); 2596263509Sdim const StringRef MIPSABIDirSuffix = GCCInstallation.getMIPSABIDirSuffix(); 2597263509Sdim 2598263509Sdim std::string Path = (InstallDir + "/../../../../" + TripleStr + "/libc" + 2599263509Sdim MIPSABIDirSuffix).str(); 2600263509Sdim 2601263509Sdim if (llvm::sys::fs::exists(Path)) 2602263509Sdim return Path; 2603263509Sdim 2604263509Sdim Path = (InstallDir + "/../../../../sysroot" + MIPSABIDirSuffix).str(); 2605263509Sdim 2606263509Sdim if (llvm::sys::fs::exists(Path)) 2607263509Sdim return Path; 2608263509Sdim 2609263509Sdim return std::string(); 2610252723Sdim} 2611252723Sdim 2612229042Sdimvoid Linux::AddClangSystemIncludeArgs(const ArgList &DriverArgs, 2613229042Sdim ArgStringList &CC1Args) const { 2614229042Sdim const Driver &D = getDriver(); 2615263509Sdim std::string SysRoot = computeSysRoot(); 2616229042Sdim 2617229042Sdim if (DriverArgs.hasArg(options::OPT_nostdinc)) 2618229042Sdim return; 2619229042Sdim 2620229042Sdim if (!DriverArgs.hasArg(options::OPT_nostdlibinc)) 2621252723Sdim addSystemInclude(DriverArgs, CC1Args, SysRoot + "/usr/local/include"); 2622229042Sdim 2623229042Sdim if (!DriverArgs.hasArg(options::OPT_nobuiltininc)) { 2624263509Sdim SmallString<128> P(D.ResourceDir); 2625263509Sdim llvm::sys::path::append(P, "include"); 2626229042Sdim addSystemInclude(DriverArgs, CC1Args, P.str()); 2627229042Sdim } 2628229042Sdim 2629229042Sdim if (DriverArgs.hasArg(options::OPT_nostdlibinc)) 2630229042Sdim return; 2631229042Sdim 2632229042Sdim // Check for configure-time C include directories. 2633229042Sdim StringRef CIncludeDirs(C_INCLUDE_DIRS); 2634229042Sdim if (CIncludeDirs != "") { 2635229042Sdim SmallVector<StringRef, 5> dirs; 2636229042Sdim CIncludeDirs.split(dirs, ":"); 2637229042Sdim for (SmallVectorImpl<StringRef>::iterator I = dirs.begin(), E = dirs.end(); 2638229042Sdim I != E; ++I) { 2639252723Sdim StringRef Prefix = llvm::sys::path::is_absolute(*I) ? SysRoot : ""; 2640229042Sdim addExternCSystemInclude(DriverArgs, CC1Args, Prefix + *I); 2641229042Sdim } 2642229042Sdim return; 2643229042Sdim } 2644229042Sdim 2645229042Sdim // Lacking those, try to detect the correct set of system includes for the 2646229042Sdim // target triple. 2647229042Sdim 2648252723Sdim // Sourcery CodeBench and modern FSF Mips toolchains put extern C 2649252723Sdim // system includes under three additional directories. 2650252723Sdim if (GCCInstallation.isValid() && isMipsArch(getTriple().getArch())) { 2651263509Sdim addExternCSystemIncludeIfExists( 2652263509Sdim DriverArgs, CC1Args, GCCInstallation.getInstallPath() + "/include"); 2653252723Sdim 2654263509Sdim addExternCSystemIncludeIfExists( 2655263509Sdim DriverArgs, CC1Args, 2656263509Sdim GCCInstallation.getInstallPath() + "/../../../../" + 2657263509Sdim GCCInstallation.getTriple().str() + "/libc/usr/include"); 2658263509Sdim 2659263509Sdim addExternCSystemIncludeIfExists( 2660263509Sdim DriverArgs, CC1Args, 2661263509Sdim GCCInstallation.getInstallPath() + "/../../../../sysroot/usr/include"); 2662252723Sdim } 2663252723Sdim 2664229042Sdim // Implement generic Debian multiarch support. 2665229042Sdim const StringRef X86_64MultiarchIncludeDirs[] = { 2666229042Sdim "/usr/include/x86_64-linux-gnu", 2667229042Sdim 2668229042Sdim // FIXME: These are older forms of multiarch. It's not clear that they're 2669229042Sdim // in use in any released version of Debian, so we should consider 2670229042Sdim // removing them. 2671263509Sdim "/usr/include/i686-linux-gnu/64", "/usr/include/i486-linux-gnu/64" 2672229042Sdim }; 2673229042Sdim const StringRef X86MultiarchIncludeDirs[] = { 2674229042Sdim "/usr/include/i386-linux-gnu", 2675229042Sdim 2676229042Sdim // FIXME: These are older forms of multiarch. It's not clear that they're 2677229042Sdim // in use in any released version of Debian, so we should consider 2678229042Sdim // removing them. 2679263509Sdim "/usr/include/x86_64-linux-gnu/32", "/usr/include/i686-linux-gnu", 2680229042Sdim "/usr/include/i486-linux-gnu" 2681229042Sdim }; 2682252723Sdim const StringRef AArch64MultiarchIncludeDirs[] = { 2683252723Sdim "/usr/include/aarch64-linux-gnu" 2684252723Sdim }; 2685229042Sdim const StringRef ARMMultiarchIncludeDirs[] = { 2686229042Sdim "/usr/include/arm-linux-gnueabi" 2687229042Sdim }; 2688245431Sdim const StringRef ARMHFMultiarchIncludeDirs[] = { 2689245431Sdim "/usr/include/arm-linux-gnueabihf" 2690245431Sdim }; 2691235633Sdim const StringRef MIPSMultiarchIncludeDirs[] = { 2692235633Sdim "/usr/include/mips-linux-gnu" 2693235633Sdim }; 2694235633Sdim const StringRef MIPSELMultiarchIncludeDirs[] = { 2695235633Sdim "/usr/include/mipsel-linux-gnu" 2696235633Sdim }; 2697235633Sdim const StringRef PPCMultiarchIncludeDirs[] = { 2698235633Sdim "/usr/include/powerpc-linux-gnu" 2699235633Sdim }; 2700235633Sdim const StringRef PPC64MultiarchIncludeDirs[] = { 2701235633Sdim "/usr/include/powerpc64-linux-gnu" 2702235633Sdim }; 2703229042Sdim ArrayRef<StringRef> MultiarchIncludeDirs; 2704229042Sdim if (getTriple().getArch() == llvm::Triple::x86_64) { 2705229042Sdim MultiarchIncludeDirs = X86_64MultiarchIncludeDirs; 2706229042Sdim } else if (getTriple().getArch() == llvm::Triple::x86) { 2707229042Sdim MultiarchIncludeDirs = X86MultiarchIncludeDirs; 2708252723Sdim } else if (getTriple().getArch() == llvm::Triple::aarch64) { 2709252723Sdim MultiarchIncludeDirs = AArch64MultiarchIncludeDirs; 2710229042Sdim } else if (getTriple().getArch() == llvm::Triple::arm) { 2711245431Sdim if (getTriple().getEnvironment() == llvm::Triple::GNUEABIHF) 2712245431Sdim MultiarchIncludeDirs = ARMHFMultiarchIncludeDirs; 2713245431Sdim else 2714245431Sdim MultiarchIncludeDirs = ARMMultiarchIncludeDirs; 2715235633Sdim } else if (getTriple().getArch() == llvm::Triple::mips) { 2716235633Sdim MultiarchIncludeDirs = MIPSMultiarchIncludeDirs; 2717235633Sdim } else if (getTriple().getArch() == llvm::Triple::mipsel) { 2718235633Sdim MultiarchIncludeDirs = MIPSELMultiarchIncludeDirs; 2719235633Sdim } else if (getTriple().getArch() == llvm::Triple::ppc) { 2720235633Sdim MultiarchIncludeDirs = PPCMultiarchIncludeDirs; 2721235633Sdim } else if (getTriple().getArch() == llvm::Triple::ppc64) { 2722235633Sdim MultiarchIncludeDirs = PPC64MultiarchIncludeDirs; 2723229042Sdim } 2724229042Sdim for (ArrayRef<StringRef>::iterator I = MultiarchIncludeDirs.begin(), 2725229042Sdim E = MultiarchIncludeDirs.end(); 2726229042Sdim I != E; ++I) { 2727252723Sdim if (llvm::sys::fs::exists(SysRoot + *I)) { 2728252723Sdim addExternCSystemInclude(DriverArgs, CC1Args, SysRoot + *I); 2729229042Sdim break; 2730229042Sdim } 2731229042Sdim } 2732229042Sdim 2733229042Sdim if (getTriple().getOS() == llvm::Triple::RTEMS) 2734229042Sdim return; 2735229042Sdim 2736235633Sdim // Add an include of '/include' directly. This isn't provided by default by 2737235633Sdim // system GCCs, but is often used with cross-compiling GCCs, and harmless to 2738235633Sdim // add even when Clang is acting as-if it were a system compiler. 2739252723Sdim addExternCSystemInclude(DriverArgs, CC1Args, SysRoot + "/include"); 2740235633Sdim 2741252723Sdim addExternCSystemInclude(DriverArgs, CC1Args, SysRoot + "/usr/include"); 2742229042Sdim} 2743229042Sdim 2744252723Sdim/// \brief Helper to add the three variant paths for a libstdc++ installation. 2745235633Sdim/*static*/ bool Linux::addLibStdCXXIncludePaths(Twine Base, Twine TargetArchDir, 2746235633Sdim const ArgList &DriverArgs, 2747235633Sdim ArgStringList &CC1Args) { 2748229042Sdim if (!llvm::sys::fs::exists(Base)) 2749229042Sdim return false; 2750229042Sdim addSystemInclude(DriverArgs, CC1Args, Base); 2751229042Sdim addSystemInclude(DriverArgs, CC1Args, Base + "/" + TargetArchDir); 2752229042Sdim addSystemInclude(DriverArgs, CC1Args, Base + "/backward"); 2753229042Sdim return true; 2754229042Sdim} 2755229042Sdim 2756252723Sdim/// \brief Helper to add an extra variant path for an (Ubuntu) multilib 2757252723Sdim/// libstdc++ installation. 2758252723Sdim/*static*/ bool Linux::addLibStdCXXIncludePaths(Twine Base, Twine Suffix, 2759252723Sdim Twine TargetArchDir, 2760263509Sdim Twine BiarchSuffix, 2761263509Sdim Twine MIPSABIDirSuffix, 2762252723Sdim const ArgList &DriverArgs, 2763252723Sdim ArgStringList &CC1Args) { 2764263509Sdim if (!addLibStdCXXIncludePaths(Base + Suffix, 2765263509Sdim TargetArchDir + MIPSABIDirSuffix + BiarchSuffix, 2766252723Sdim DriverArgs, CC1Args)) 2767252723Sdim return false; 2768252723Sdim 2769252723Sdim addSystemInclude(DriverArgs, CC1Args, Base + "/" + TargetArchDir + Suffix 2770263509Sdim + MIPSABIDirSuffix + BiarchSuffix); 2771252723Sdim return true; 2772252723Sdim} 2773252723Sdim 2774229042Sdimvoid Linux::AddClangCXXStdlibIncludeArgs(const ArgList &DriverArgs, 2775229042Sdim ArgStringList &CC1Args) const { 2776229042Sdim if (DriverArgs.hasArg(options::OPT_nostdlibinc) || 2777229042Sdim DriverArgs.hasArg(options::OPT_nostdincxx)) 2778229042Sdim return; 2779229042Sdim 2780229042Sdim // Check if libc++ has been enabled and provide its include paths if so. 2781229042Sdim if (GetCXXStdlibType(DriverArgs) == ToolChain::CST_Libcxx) { 2782229042Sdim // libc++ is always installed at a fixed path on Linux currently. 2783229042Sdim addSystemInclude(DriverArgs, CC1Args, 2784229042Sdim getDriver().SysRoot + "/usr/include/c++/v1"); 2785229042Sdim return; 2786229042Sdim } 2787229042Sdim 2788235633Sdim // We need a detected GCC installation on Linux to provide libstdc++'s 2789235633Sdim // headers. We handled the libc++ case above. 2790235633Sdim if (!GCCInstallation.isValid()) 2791229042Sdim return; 2792229042Sdim 2793229042Sdim // By default, look for the C++ headers in an include directory adjacent to 2794229042Sdim // the lib directory of the GCC installation. Note that this is expect to be 2795229042Sdim // equivalent to '/usr/include/c++/X.Y' in almost all cases. 2796229042Sdim StringRef LibDir = GCCInstallation.getParentLibPath(); 2797229042Sdim StringRef InstallDir = GCCInstallation.getInstallPath(); 2798245431Sdim StringRef TripleStr = GCCInstallation.getTriple().str(); 2799263509Sdim StringRef MIPSABIDirSuffix = GCCInstallation.getMIPSABIDirSuffix(); 2800263509Sdim StringRef BiarchSuffix = GCCInstallation.getBiarchSuffix(); 2801263509Sdim const GCCVersion &Version = GCCInstallation.getVersion(); 2802245431Sdim 2803263509Sdim if (addLibStdCXXIncludePaths(LibDir.str() + "/../include", 2804263509Sdim "/c++/" + Version.Text, TripleStr, BiarchSuffix, 2805263509Sdim MIPSABIDirSuffix, DriverArgs, CC1Args)) 2806252723Sdim return; 2807252723Sdim 2808245431Sdim const std::string IncludePathCandidates[] = { 2809229042Sdim // Gentoo is weird and places its headers inside the GCC install, so if the 2810263509Sdim // first attempt to find the headers fails, try these patterns. 2811263509Sdim InstallDir.str() + "/include/g++-v" + Version.MajorStr + "." + 2812263509Sdim Version.MinorStr, 2813263509Sdim InstallDir.str() + "/include/g++-v" + Version.MajorStr, 2814245431Sdim // Android standalone toolchain has C++ headers in yet another place. 2815263509Sdim LibDir.str() + "/../" + TripleStr.str() + "/include/c++/" + Version.Text, 2816245431Sdim // Freescale SDK C++ headers are directly in <sysroot>/usr/include/c++, 2817245431Sdim // without a subdirectory corresponding to the gcc version. 2818245431Sdim LibDir.str() + "/../include/c++", 2819245431Sdim }; 2820245431Sdim 2821245431Sdim for (unsigned i = 0; i < llvm::array_lengthof(IncludePathCandidates); ++i) { 2822263509Sdim if (addLibStdCXXIncludePaths(IncludePathCandidates[i], 2823263509Sdim TripleStr + MIPSABIDirSuffix + BiarchSuffix, 2824263509Sdim DriverArgs, CC1Args)) 2825245431Sdim break; 2826229042Sdim } 2827229042Sdim} 2828229042Sdim 2829252723Sdimbool Linux::isPIEDefault() const { 2830263509Sdim return getSanitizerArgs().hasZeroBaseShadow(); 2831252723Sdim} 2832252723Sdim 2833193326Sed/// DragonFly - DragonFly tool chain which can call as(1) and ld(1) directly. 2834193326Sed 2835235633SdimDragonFly::DragonFly(const Driver &D, const llvm::Triple& Triple, const ArgList &Args) 2836235633Sdim : Generic_ELF(D, Triple, Args) { 2837193326Sed 2838193326Sed // Path mangling to find libexec 2839212904Sdim getProgramPaths().push_back(getDriver().getInstalledDir()); 2840221345Sdim if (getDriver().getInstalledDir() != getDriver().Dir) 2841212904Sdim getProgramPaths().push_back(getDriver().Dir); 2842193326Sed 2843201361Srdivacky getFilePaths().push_back(getDriver().Dir + "/../lib"); 2844193326Sed getFilePaths().push_back("/usr/lib"); 2845252723Sdim if (llvm::sys::fs::exists("/usr/lib/gcc47")) 2846252723Sdim getFilePaths().push_back("/usr/lib/gcc47"); 2847252723Sdim else 2848252723Sdim getFilePaths().push_back("/usr/lib/gcc44"); 2849193326Sed} 2850193326Sed 2851252723SdimTool *DragonFly::buildAssembler() const { 2852252723Sdim return new tools::dragonfly::Assemble(*this); 2853252723Sdim} 2854193326Sed 2855252723SdimTool *DragonFly::buildLinker() const { 2856252723Sdim return new tools::dragonfly::Link(*this); 2857193326Sed} 2858263509Sdim 2859263509Sdim 2860263509Sdim/// XCore tool chain 2861263509SdimXCore::XCore(const Driver &D, const llvm::Triple &Triple, 2862263509Sdim const ArgList &Args) : ToolChain(D, Triple, Args) { 2863263509Sdim // ProgramPaths are found via 'PATH' environment variable. 2864263509Sdim} 2865263509Sdim 2866263509SdimTool *XCore::buildAssembler() const { 2867263509Sdim return new tools::XCore::Assemble(*this); 2868263509Sdim} 2869263509Sdim 2870263509SdimTool *XCore::buildLinker() const { 2871263509Sdim return new tools::XCore::Link(*this); 2872263509Sdim} 2873263509Sdim 2874263509Sdimbool XCore::isPICDefault() const { 2875263509Sdim return false; 2876263509Sdim} 2877263509Sdim 2878263509Sdimbool XCore::isPIEDefault() const { 2879263509Sdim return false; 2880263509Sdim} 2881263509Sdim 2882263509Sdimbool XCore::isPICDefaultForced() const { 2883263509Sdim return false; 2884263509Sdim} 2885263509Sdim 2886263509Sdimbool XCore::SupportsProfiling() const { 2887263509Sdim return false; 2888263509Sdim} 2889263509Sdim 2890263509Sdimbool XCore::hasBlocksRuntime() const { 2891263509Sdim return false; 2892263509Sdim} 2893263509Sdim 2894263509Sdim 2895263509Sdimvoid XCore::AddClangSystemIncludeArgs(const ArgList &DriverArgs, 2896263509Sdim ArgStringList &CC1Args) const { 2897263509Sdim if (DriverArgs.hasArg(options::OPT_nostdinc) || 2898263509Sdim DriverArgs.hasArg(options::OPT_nostdlibinc)) 2899263509Sdim return; 2900263509Sdim if (const char *cl_include_dir = getenv("XCC_C_INCLUDE_PATH")) { 2901263509Sdim SmallVector<StringRef, 4> Dirs; 2902263509Sdim const char EnvPathSeparatorStr[] = {llvm::sys::EnvPathSeparator,'\0'}; 2903263509Sdim StringRef(cl_include_dir).split(Dirs, StringRef(EnvPathSeparatorStr)); 2904263509Sdim ArrayRef<StringRef> DirVec(Dirs); 2905263509Sdim addSystemIncludes(DriverArgs, CC1Args, DirVec); 2906263509Sdim } 2907263509Sdim} 2908263509Sdim 2909263509Sdimvoid XCore::addClangTargetOptions(const llvm::opt::ArgList &DriverArgs, 2910263509Sdim llvm::opt::ArgStringList &CC1Args) const { 2911263509Sdim CC1Args.push_back("-nostdsysteminc"); 2912263509Sdim} 2913263509Sdim 2914263509Sdimvoid XCore::AddClangCXXStdlibIncludeArgs(const ArgList &DriverArgs, 2915263509Sdim ArgStringList &CC1Args) const { 2916263509Sdim if (DriverArgs.hasArg(options::OPT_nostdinc) || 2917263509Sdim DriverArgs.hasArg(options::OPT_nostdlibinc)) 2918263509Sdim return; 2919263509Sdim if (const char *cl_include_dir = getenv("XCC_CPLUS_INCLUDE_PATH")) { 2920263509Sdim SmallVector<StringRef, 4> Dirs; 2921263509Sdim const char EnvPathSeparatorStr[] = {llvm::sys::EnvPathSeparator,'\0'}; 2922263509Sdim StringRef(cl_include_dir).split(Dirs, StringRef(EnvPathSeparatorStr)); 2923263509Sdim ArrayRef<StringRef> DirVec(Dirs); 2924263509Sdim addSystemIncludes(DriverArgs, CC1Args, DirVec); 2925263509Sdim } 2926263509Sdim} 2927263509Sdim 2928263509Sdimvoid XCore::AddCXXStdlibLibArgs(const ArgList &Args, 2929263509Sdim ArgStringList &CmdArgs) const { 2930263509Sdim // We don't output any lib args. This is handled by xcc. 2931263509Sdim} 2932