diff -r d283aa33e131 -r 92717ce71105 components/llvm/patches/014-clang-gcc-toolchain.patch --- a/components/llvm/patches/014-clang-gcc-toolchain.patch Thu Jul 28 16:15:45 2016 -0700 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,2323 +0,0 @@ -# Solaris GCC Toolchain discovery. -# https://llvm.org/bugs/show_bug.cgi?id=24606 ---- lib/Support/Host.cpp 2014-12-16 19:38:04.000000000 -0800 -+++ lib/Support/Host.cpp 2016-02-09 09:59:19.281147309 -0800 -@@ -39,6 +39,11 @@ - #include - #endif - -+#if defined(sun) || defined(__sun) || defined(__sun__) -+#include -+#include -+#endif -+ - #define DEBUG_TYPE "host-detection" - - //===----------------------------------------------------------------------===// -@@ -674,6 +679,43 @@ - - return "generic"; - } -+#elif ((defined(sun) || defined(__sun) || defined(__sun__)) && \ -+ (defined(sparc) || defined(__sparc) || defined(__sparc__))) -+StringRef sys::getHostCPUName() { -+ kstat_ctl_t *KC = 0; -+ kstat_t *KSP = 0; -+ kstat_named_t *KNP = 0; -+ static char Buffer[256]; -+ static bool Init = false; -+ const char *Value; -+ -+ if (!Init) { -+ KC = kstat_open(); -+ if (KC) { -+ KSP = kstat_lookup(KC, "cpu_info", -1, "cpu_info0"); -+ kstat_read(KC, KSP, NULL); -+ KNP = reinterpret_cast(kstat_data_lookup(KSP, "brand")); -+ Value = (const char *) KNP->value.str.addr.ptr; -+ (void) std::sprintf(Buffer, "%s (", Value); -+ -+ KNP = -+ reinterpret_cast(kstat_data_lookup(KSP, "cpu_type")); -+ Value = (const char*) KNP->value.c; -+ (void) std::strcat(Buffer, Value); -+ (void) std::strcat(Buffer, ") "); -+ -+ KNP = -+ reinterpret_cast(kstat_data_lookup(KSP, -+ "implementation")); -+ Value = (const char*) KNP->value.str.addr.ptr; -+ (void) std::strcat(Buffer, Value); -+ Init = true; -+ kstat_close(KC); -+ } -+ } -+ -+ return Buffer; -+} - #else - StringRef sys::getHostCPUName() { - return "generic"; ---- tools/clang/include/clang/Driver/Options.td Sat Jul 18 11:44:46 2015 -+++ tools/clang/include/clang/Driver/Options.td Thu Aug 20 22:46:37 2015 -@@ -1129,6 +1129,11 @@ - def mthread_model : Separate<["-"], "mthread-model">, Group, Flags<[CC1Option]>, - HelpText<"The thread model to use, e.g. posix, single (posix by default)">; - -+def mvis : Flag<["-"], "mvis">, Group; -+def mvis2 : Flag<["-"], "mvis2">, Group; -+def mvis3 : Flag<["-"], "mvis3">, Group; -+def mimpure_text: Flag<["-"], "mimpure-text">, Group; -+ - def mmmx : Flag<["-"], "mmmx">, Group; - def mno_3dnowa : Flag<["-"], "mno-3dnowa">, Group; - def mno_3dnow : Flag<["-"], "mno-3dnow">, Group; -@@ -1690,6 +1695,7 @@ - defm profile_use : BooleanFFlag<"profile-use">, Group; - def fprofile_use_EQ : Joined<["-"], "fprofile-use=">, Group; - def fuse_ld_EQ : Joined<["-"], "fuse-ld=">, Group; -+def fuse_as_EQ : Joined<["-"], "fuse-as=">, Group; - - defm align_functions : BooleanFFlag<"align-functions">, Group; - def falign_functions_EQ : Joined<["-"], "falign-functions=">, Group; ---- tools/clang/lib/Frontend/InitHeaderSearch.cpp Thu Dec 4 16:22:48 2014 -+++ tools/clang/lib/Frontend/InitHeaderSearch.cpp Fri Aug 21 23:23:27 2015 -@@ -122,7 +122,7 @@ - // Add the path with sysroot prepended, if desired and this is a system header - // group. - if (HasSysroot) { -- SmallString<256> MappedPathStorage; -+ SmallString MappedPathStorage; - StringRef MappedPathStr = Path.toStringRef(MappedPathStorage); - if (CanPrefixSysroot(MappedPathStr)) { - AddUnmappedPath(IncludeSysroot + Path, Group, isFramework); -@@ -138,7 +138,7 @@ - assert(!Path.isTriviallyEmpty() && "can't handle empty path here"); - - FileManager &FM = Headers.getFileMgr(); -- SmallString<256> MappedPathStorage; -+ SmallString MappedPathStorage; - StringRef MappedPathStr = Path.toStringRef(MappedPathStorage); - - // Compute the DirectoryLookup type. -@@ -187,12 +187,16 @@ - - // Add the multilib dirs - llvm::Triple::ArchType arch = triple.getArch(); -- bool is64bit = arch == llvm::Triple::ppc64 || arch == llvm::Triple::x86_64; -+ bool is64bit = arch == llvm::Triple::ppc64 || arch == llvm::Triple::x86_64 || -+ arch == llvm::Triple::sparcv9; - if (is64bit) - AddPath(Base + "/" + ArchDir + "/" + Dir64, CXXSystem, false); - else - AddPath(Base + "/" + ArchDir + "/" + Dir32, CXXSystem, false); - -+ // Add GCC's "C" include dir -+ AddPath(Base + "/include", CXXSystem, false); -+ - // Add the backward dir - AddPath(Base + "/backward", CXXSystem, false); - } -@@ -442,8 +446,7 @@ - "", "", "", triple); - break; - case llvm::Triple::Solaris: -- AddGnuCPlusPlusIncludePaths("/usr/gcc/4.5/include/c++/4.5.2/", -- "i386-pc-solaris2.11", "", "", triple); -+ // All of this is handled in the driver. - break; - default: - break; -@@ -462,6 +465,7 @@ - break; // Everything else continues to use this routine's logic. - - case llvm::Triple::Linux: -+ case llvm::Triple::Solaris: - return; - - case llvm::Triple::Win32: -@@ -484,7 +488,7 @@ - // Remove clang from foo/lib/clang - StringRef Lib = llvm::sys::path::parent_path(NoVer); - // Remove lib from foo/lib -- SmallString<128> P = llvm::sys::path::parent_path(Lib); -+ SmallString P = llvm::sys::path::parent_path(Lib); - - // Get foo/include/c++/v1 - llvm::sys::path::append(P, "include", "c++", "v1"); -@@ -491,10 +495,6 @@ - AddUnmappedPath(P.str(), CXXSystem, false); - } - } -- // On Solaris, include the support directory for things like xlocale and -- // fudged system headers. -- if (triple.getOS() == llvm::Triple::Solaris) -- AddPath("/usr/include/c++/v1/support/solaris", CXXSystem, false); - - AddPath("/usr/include/c++/v1", CXXSystem, false); - } else { ---- tools/clang/lib/Driver/Tools.h Wed Jan 28 15:52:21 2015 -+++ tools/clang/lib/Driver/Tools.h Thu Aug 20 22:46:37 2015 -@@ -529,6 +529,9 @@ - - bool hasIntegratedCPP() const override { return false; } - -+ void RenderExtraToolArgs(const JobAction &JA, -+ ArgStringList &CmdArgs) const; -+ - void ConstructJob(Compilation &C, const JobAction &JA, - const InputInfo &Output, const InputInfoList &Inputs, - const llvm::opt::ArgList &TCArgs, -@@ -541,6 +544,9 @@ - bool hasIntegratedCPP() const override { return false; } - bool isLinkJob() const override { return true; } - -+ void RenderExtraToolArgs(const JobAction &JA, -+ ArgStringList &CmdArgs) const; -+ - void ConstructJob(Compilation &C, const JobAction &JA, - const InputInfo &Output, const InputInfoList &Inputs, - const llvm::opt::ArgList &TCArgs, ---- tools/clang/lib/Driver/Tools.cpp Sat Jul 18 11:44:46 2015 -+++ tools/clang/lib/Driver/Tools.cpp Sat Aug 22 17:26:16 2015 -@@ -60,6 +60,12 @@ - } - } - -+static void AddLibgcc(const llvm::Triple &Triple, const Driver &D, -+ ArgStringList &CmdArgs, const ArgList &Args); -+ -+static void AddLibgcc(const Driver &D, ArgStringList &CmdArgs, -+ const ArgList &Args, const std::string& Exec); -+ - /// CheckPreprocessingOptions - Perform some validation of preprocessing - /// arguments that is shared with gcc. - static void CheckPreprocessingOptions(const Driver &D, const ArgList &Args) { -@@ -1360,14 +1366,30 @@ - return ""; - } - -+static const char *getSparcTargetCPU(const ArgList &Args, -+ const llvm::Triple &Triple); -+ -+static const char *getSparcTargetCPUFeature(const char* CPU, -+ const ArgList &Args, -+ const llvm::Triple &Triple); -+ - static void getSparcTargetFeatures(const ArgList &Args, -- std::vector &Features) { -- bool SoftFloatABI = true; -+ std::vector &Features, -+ const llvm::Triple &Triple) { -+ bool SoftFloatABI; -+ -+ if ((Triple.getOS() == llvm::Triple::Solaris) || -+ (Triple.getOS() == llvm::Triple::Linux)) -+ SoftFloatABI = false; -+ else -+ SoftFloatABI = true; -+ - if (Arg *A = - Args.getLastArg(options::OPT_msoft_float, options::OPT_mhard_float)) { - if (A->getOption().matches(options::OPT_mhard_float)) - SoftFloatABI = false; - } -+ - if (SoftFloatABI) - Features.push_back("+soft-float"); - } -@@ -1375,17 +1397,31 @@ - void Clang::AddSparcTargetArgs(const ArgList &Args, - ArgStringList &CmdArgs) const { - const Driver &D = getToolChain().getDriver(); -+ const llvm::Triple &T = getToolChain().getTriple(); - - // Select the float ABI as determined by -msoft-float and -mhard-float. -+ // There is no support for soft-float ABI in Solaris. - StringRef FloatABI; - if (Arg *A = Args.getLastArg(options::OPT_msoft_float, - options::OPT_mhard_float)) { -- if (A->getOption().matches(options::OPT_msoft_float)) -+ if (A->getOption().matches(options::OPT_msoft_float)) { -+ if ((T.getOS() == llvm::Triple::Solaris) || -+ (T.getOS() == llvm::Triple::Linux)) { -+ D.Diag(diag::warn_drv_clang_unsupported) << "-msoft-float"; -+ D.Diag(diag::warn_drv_overriding_flag_option) << -+ "-msoft-float" << "-mhard-float"; -+ FloatABI = "hard"; -+ } else { - FloatABI = "soft"; -- else if (A->getOption().matches(options::OPT_mhard_float)) -+ } -+ } else if (A->getOption().matches(options::OPT_mhard_float)) - FloatABI = "hard"; - } - -+ if (((T.getOS() == llvm::Triple::Solaris) || -+ (T.getOS() == llvm::Triple::Linux)) && FloatABI.empty()) -+ FloatABI = "hard"; -+ - // If unspecified, choose the default based on the platform. - if (FloatABI.empty()) { - // Assume "soft", but warn the user we are guessing. -@@ -1400,10 +1436,93 @@ - CmdArgs.push_back("-msoft-float"); - } else { - assert(FloatABI == "hard" && "Invalid float abi!"); -- CmdArgs.push_back("-mhard-float"); - } -+ -+ std::string Feature; -+ if (Arg *A = Args.getLastArg(options::OPT_march_EQ)) { -+ Feature = "-march="; -+ Feature += A->getValue(); -+ CmdArgs.push_back(Args.MakeArgString("-target-feature")); -+ CmdArgs.push_back(Args.MakeArgString(Feature.c_str())); - } - -+ if (Arg *A = Args.getLastArg(options::OPT_mtune_EQ)) { -+ Feature = "-mtune="; -+ Feature += A->getValue(); -+ CmdArgs.push_back(Args.MakeArgString("-target-feature")); -+ CmdArgs.push_back(Args.MakeArgString(Feature.c_str())); -+ } -+ -+ if (Arg *A = Args.getLastArg(options::OPT_mcpu_EQ)) { -+ Feature = "-mcpu="; -+ Feature += A->getValue(); -+ CmdArgs.push_back(Args.MakeArgString("-target-feature")); -+ CmdArgs.push_back(Args.MakeArgString(Feature.c_str())); -+ } -+} -+ -+static const char *getSparcTargetCPU(const ArgList &Args, -+ const llvm::Triple &Triple) { -+ StringRef V; -+ -+ if (Arg *A = Args.getLastArg(options::OPT_march_EQ)) { -+ V = A->getValue(); -+ switch (Triple.getOS()) { -+ case llvm::Triple::Solaris: -+ case llvm::Triple::Linux: -+ if (V == "v8plus" || V == "v8plusa" || -+ V == "v8plusb" || V == "v9" || -+ V == "v9a" || V == "v9b" || -+ V == "sparcmaf" || V == "sparc4" ) -+ return Args.MakeArgString(V); -+ break; -+ default: -+ return Args.MakeArgString("v8plusa"); -+ break; -+ } -+ } -+ -+ if (Arg *AA = Args.getLastArg(options::OPT_m64)) -+ return "v9a"; -+ -+ return "v8plusa"; -+} -+ -+static const char *getSparcTargetCPUFeature(const char* CPU, -+ const ArgList &Args, -+ const llvm::Triple &Triple) { -+ StringRef V; -+ if (Arg *A = Args.getLastArg(options::OPT_mtune_EQ)) { -+ V = A->getValue(); -+ -+ if (V.empty()) -+ if (Arg *AA = Args.getLastArg(options::OPT_m64)) -+ return "vis"; -+ -+ if (V == "ultrasparc" || V == "ultrasparc2" || -+ V == "ultrasparc3" || V == "sparcmaf" || V == "sparc4" ) -+ return Args.MakeArgString(A->getValue()); -+ } -+ -+ if (!CPU) -+ return 0; -+ -+ std::string C = CPU; -+ -+ if (C == "v8plus" || C == "v9") -+ return ""; -+ -+ if (C == "v8plusa" || C == "v9a") -+ return "vis1"; -+ else if (C == "v8plusb" || C == "v9b") -+ return "vis2"; -+ else if (C == "sparcmaf" || C == "sparc4") -+ return "vis3"; -+ -+ return 0; -+} -+ -+ - static const char *getSystemZTargetCPU(const ArgList &Args) { - if (const Arg *A = Args.getLastArg(options::OPT_march_EQ)) - return A->getValue(); -@@ -1872,7 +1991,7 @@ - break; - case llvm::Triple::sparc: - case llvm::Triple::sparcv9: -- getSparcTargetFeatures(Args, Features); -+ getSparcTargetFeatures(Args, Features, Triple); - break; - case llvm::Triple::aarch64: - case llvm::Triple::aarch64_be: -@@ -2695,6 +2814,23 @@ - } - } - -+ // Solaris-specific defaults for PIE -+ if (getToolChain().getTriple().getOS() == llvm::Triple::Solaris) { -+ switch (getToolChain().getTriple().getArch()) { -+ case llvm::Triple::x86: -+ IsPICLevelTwo = false; // "-fpie" -+ break; -+ case llvm::Triple::sparc: -+ case llvm::Triple::x86_64: -+ case llvm::Triple::sparcv9: -+ IsPICLevelTwo = true; // "-fPIE" -+ break; -+ -+ default: -+ break; -+ } -+ } -+ - // For the PIC and PIE flag options, this logic is different from the - // legacy logic in very old versions of GCC, as that logic was just - // a bug no one had ever fixed. This logic is both more rational and -@@ -2740,6 +2876,47 @@ - if (Args.hasArg(options::OPT_static)) - PIC = PIE = false; - -+ if (Triple.getOS() == llvm::Triple::Solaris) { -+ if (Arg *A = Args.getLastArg(options::OPT_shared)) { -+ PIC = true; -+ PIE = false; -+ CmdArgs.push_back("-mrelocation-model"); -+ CmdArgs.push_back("pic"); -+ if (IsPICLevelTwo) { -+ CmdArgs.push_back("-pic-level"); -+ CmdArgs.push_back("2"); -+ } -+ } else if (PIC) { -+ PIC = true; -+ PIE = false; -+ CmdArgs.push_back("-mrelocation-model"); -+ CmdArgs.push_back("pic"); -+ if (IsPICLevelTwo) { -+ CmdArgs.push_back("-pic-level"); -+ CmdArgs.push_back("2"); -+ } -+ } else if (PIE) { -+ PIC = PIE = true; -+ CmdArgs.push_back("-mrelocation-model"); -+ CmdArgs.push_back("pic"); -+ if (IsPICLevelTwo) { -+ CmdArgs.push_back("-pie-level"); -+ CmdArgs.push_back("2"); -+ } -+ } else if (Args.hasArg(options::OPT_static)) { -+ // Solaris doesn't to static relocations. -+ PIC = PIE = false; -+ CmdArgs.push_back("-mrelocation-model"); -+ CmdArgs.push_back("dynamic-no-pic"); -+ } else { -+ // This is a Solaris non-PIE executable. -+ // Solaris doesn't to static relocations. -+ PIC = PIE = false; -+ CmdArgs.push_back("-mrelocation-model"); -+ CmdArgs.push_back("dynamic-no-pic"); -+ } -+ } -+ - if (Arg *A = Args.getLastArg(options::OPT_mdynamic_no_pic)) { - // This is a very special mode. It trumps the other modes, almost no one - // uses it, and it isn't even valid on any OS but Darwin. -@@ -2762,6 +2939,8 @@ - } else { - // Currently, LLVM only knows about PIC vs. static; the PIE differences are - // handled in Clang's IRGen by the -pie-level flag. -+ // Solaris already took care of PIC/PIE/non-PIC above. -+ if (Triple.getOS() != llvm::Triple::Solaris) { - CmdArgs.push_back("-mrelocation-model"); - CmdArgs.push_back(PIC ? "pic" : "static"); - -@@ -2774,6 +2953,7 @@ - } - } - } -+ } - - CmdArgs.push_back("-mthread-model"); - if (Arg *A = Args.getLastArg(options::OPT_mthread_model)) -@@ -3180,12 +3360,13 @@ - // FIXME: we should support specifying dwarf version with - // -gline-tables-only. - CmdArgs.push_back("-gline-tables-only"); -- // Default is dwarf-2 for Darwin, OpenBSD, FreeBSD and Solaris. -+ // Default is dwarf-2 for Darwin, OpenBSD and FreeBSD. - const llvm::Triple &Triple = getToolChain().getTriple(); - if (Triple.isOSDarwin() || Triple.getOS() == llvm::Triple::OpenBSD || -- Triple.getOS() == llvm::Triple::FreeBSD || -- Triple.getOS() == llvm::Triple::Solaris) -+ Triple.getOS() == llvm::Triple::FreeBSD) - CmdArgs.push_back("-gdwarf-2"); -+ else if (Triple.getOS() == llvm::Triple::Solaris) -+ CmdArgs.push_back("-gdwarf-4"); - } else if (A->getOption().matches(options::OPT_gdwarf_2)) - CmdArgs.push_back("-gdwarf-2"); - else if (A->getOption().matches(options::OPT_gdwarf_3)) -@@ -3194,12 +3375,13 @@ - CmdArgs.push_back("-gdwarf-4"); - else if (!A->getOption().matches(options::OPT_g0) && - !A->getOption().matches(options::OPT_ggdb0)) { -- // Default is dwarf-2 for Darwin, OpenBSD, FreeBSD and Solaris. -+ // Default is dwarf-2 for Darwin, OpenBSD and FreeBSD. - const llvm::Triple &Triple = getToolChain().getTriple(); - if (Triple.isOSDarwin() || Triple.getOS() == llvm::Triple::OpenBSD || -- Triple.getOS() == llvm::Triple::FreeBSD || -- Triple.getOS() == llvm::Triple::Solaris) -+ Triple.getOS() == llvm::Triple::FreeBSD) - CmdArgs.push_back("-gdwarf-2"); -+ else if (Triple.getOS() == llvm::Triple::Solaris) -+ CmdArgs.push_back("-gdwarf-4"); - else - CmdArgs.push_back("-g"); - } -@@ -3594,6 +3776,7 @@ - // If -fmessage-length=N was not specified, determine whether this is a - // terminal and, if so, implicitly define -fmessage-length appropriately. - unsigned N = llvm::sys::Process::StandardErrColumns(); -+ if (N == 0) N = 72U; - CmdArgs.push_back(Args.MakeArgString(Twine(N))); - } - -@@ -3735,6 +3918,7 @@ - CmdArgs.push_back("-backend-option"); - CmdArgs.push_back("-force-align-stack"); - } -+ - if (!Args.hasFlag(options::OPT_mno_stackrealign, options::OPT_mstackrealign, - false)) { - CmdArgs.push_back(Args.MakeArgString("-mstackrealign")); -@@ -3743,6 +3927,10 @@ - if (Args.hasArg(options::OPT_mstack_alignment)) { - StringRef alignment = Args.getLastArgValue(options::OPT_mstack_alignment); - CmdArgs.push_back(Args.MakeArgString("-mstack-alignment=" + alignment)); -+ } else { -+ if ((getToolChain().getTriple().getArch() == llvm::Triple::sparc) || -+ (getToolChain().getTriple().getArch() == llvm::Triple::sparcv9)) -+ CmdArgs.push_back("-mstack-alignment=16"); - } - - if (getToolChain().getTriple().getArch() == llvm::Triple::aarch64 || -@@ -6049,6 +6237,10 @@ - C.addCommand(llvm::make_unique(JA, *this, Exec, CmdArgs)); - } - -+void solaris::Assemble::RenderExtraToolArgs(const JobAction &JA, -+ ArgStringList &CmdArgs) const { -+} -+ - void solaris::Assemble::ConstructJob(Compilation &C, const JobAction &JA, - const InputInfo &Output, - const InputInfoList &Inputs, -@@ -6055,61 +6247,321 @@ - const ArgList &Args, - const char *LinkingOutput) const { - claimNoWarnArgs(Args); -+ -+ const toolchains::Solaris &TC = -+ static_cast(getToolChain()); -+ -+ if (!TC.isValid()) { -+ llvm::errs() << "Invalid GCC installation!\n"; -+ return; -+ } -+ -+ const llvm::Triple &TT = TC.getTriple(); -+ const Driver &D = TC.getDriver(); -+ llvm::Triple::ArchType Arch = TT.getArch(); -+ StringRef Assembler = TC.getAssembler(); -+ bool m32 = true; -+ -+ std::string march; -+ std::string mtune; -+ std::string mcpu; -+ - ArgStringList CmdArgs; - -- Args.AddAllArgValues(CmdArgs, options::OPT_Wa_COMMA, -- options::OPT_Xassembler); -+ if (Arg *A = Args.getLastArg(options::OPT_march_EQ)) -+ march = A->getValue(); -+ else -+ march = TC.getMArch(); - -+ if (Arg *A = Args.getLastArg(options::OPT_mtune_EQ)) -+ mtune = A->getValue(); -+ else -+ mtune = TC.getMTune(); -+ -+ if (Arg *A = Args.getLastArg(options::OPT_mcpu_EQ)) -+ mcpu = A->getValue(); -+ else -+ mcpu = TC.getMCpu(); -+ -+ if (Arg *A = Args.getLastArg(options::OPT_m64)) -+ m32 = false; -+ -+ if (Args.hasArg(options::OPT_v)) -+ CmdArgs.push_back("-V"); -+ -+ switch (Arch) { -+ case llvm::Triple::x86: -+ case llvm::Triple::x86_64: -+ if (m32) -+ CmdArgs.push_back("--32"); -+ else -+ CmdArgs.push_back("--64"); -+ break; -+ case llvm::Triple::sparc: -+ case llvm::Triple::sparcv9: -+ if (m32) { -+ CmdArgs.push_back("-32"); -+ march="v8plusa"; -+ mcpu="v8plusa"; -+ } else { -+ CmdArgs.push_back("-64"); -+ march="v9a"; -+ mcpu="v9a"; -+ } -+ break; -+ default: -+ D.Diag(diag::err_target_unsupported_arch) << TT.getArchName() -+ << TT.getTriple(); -+ break; -+ } -+ -+ std::string xarch; -+ -+ switch (Arch) { -+ case llvm::Triple::sparc: -+ case llvm::Triple::sparcv9: -+ if (!march.empty()) { -+ xarch = "-xarch="; -+ xarch += march; -+ CmdArgs.push_back(Args.MakeArgString(xarch.c_str())); -+ } else if (!mtune.empty()) { -+ xarch = "-xarch="; -+ xarch += mtune; -+ CmdArgs.push_back(Args.MakeArgString(xarch.c_str())); -+ } else if (!mcpu.empty()) { -+ xarch = "-xarch="; -+ xarch += mcpu; -+ CmdArgs.push_back(Args.MakeArgString(xarch.c_str())); -+ } -+ -+ addAssemblerKPIC(Args, CmdArgs); -+ -+ if (Args.hasArg(options::OPT_mstrict_align)) -+ CmdArgs.push_back("--enforce-aligned-data"); -+ break; -+ case llvm::Triple::x86: -+ case llvm::Triple::x86_64: -+ if (!march.empty()) { -+ xarch = "-mtune="; -+ xarch += march; -+ CmdArgs.push_back(Args.MakeArgString(xarch.c_str())); -+ } else if (!mtune.empty()) { -+ xarch = "-mtune="; -+ xarch += mtune; -+ CmdArgs.push_back(Args.MakeArgString(xarch.c_str())); -+ } -+ if (!mcpu.empty()) { -+ xarch = "-march="; -+ xarch += mcpu; -+ CmdArgs.push_back(Args.MakeArgString(xarch.c_str())); -+ } -+ break; -+ default: -+ D.Diag(diag::err_target_unsupported_arch) << TT.getArchName() -+ << TT.getTriple(); -+ break; -+ } -+ -+ if (Args.hasArg(options::OPT_g_Flag) || Args.hasArg(options::OPT_g0) || -+ Args.hasArg(options::OPT_g1) || Args.hasArg(options::OPT_g2) || -+ Args.hasArg(options::OPT_g3)) -+ CmdArgs.push_back("--gen-debug"); -+ -+ if (Output.isFilename()) { - CmdArgs.push_back("-o"); - CmdArgs.push_back(Output.getFilename()); -+ } else { -+ D.Diag(diag::err_drv_invalid_gcc_output_type) << ""; -+ CmdArgs.push_back("-fsyntax-only"); -+ } - -- for (const auto &II : Inputs) -+ RenderExtraToolArgs(JA, CmdArgs); -+ -+ Args.AddAllArgValues(CmdArgs, options::OPT_Wa_COMMA, -+ options::OPT_Xassembler); -+ -+ for (const auto &II : Inputs) { -+ if (II.getType() == types::TY_LLVM_IR || -+ II.getType() == types::TY_LTO_IR || -+ II.getType() == types::TY_LLVM_BC || II.getType() == types::TY_LTO_BC) -+ D.Diag(clang::diag::err_drv_no_linker_llvm_support) -+ << getToolChain().getTripleString(); -+ else if (II.getType() == types::TY_AST) -+ D.Diag(clang::diag::err_drv_no_ast_support) -+ << getToolChain().getTripleString(); -+ else if (II.getType() == types::TY_ModuleFile) -+ D.Diag(diag::err_drv_no_module_support) -+ << getToolChain().getTripleString(); -+ -+ if (II.isFilename()) - CmdArgs.push_back(II.getFilename()); -+ else -+ II.getInputArg().render(Args, CmdArgs); -+ } - -- const char *Exec = Args.MakeArgString(getToolChain().GetProgramPath("as")); -- C.addCommand(llvm::make_unique(JA, *this, Exec, CmdArgs)); -+ C.addCommand(llvm::make_unique(JA, *this, -+ Args.MakeArgString(Assembler), -+ CmdArgs)); - } - -+ -+void solaris::Link::RenderExtraToolArgs(const JobAction &JA, -+ ArgStringList &CmdArgs) const { -+} -+ - void solaris::Link::ConstructJob(Compilation &C, const JobAction &JA, - const InputInfo &Output, - const InputInfoList &Inputs, - const ArgList &Args, - const char *LinkingOutput) const { -- // FIXME: Find a real GCC, don't hard-code versions here -- std::string GCCLibPath = "/usr/gcc/4.5/lib/gcc/"; -- const llvm::Triple &T = getToolChain().getTriple(); -- std::string LibPath = "/usr/lib/"; -+ const toolchains::Solaris& TC = -+ static_cast(getToolChain()); -+ -+ if (!TC.isValid()) { -+ llvm::errs() << "Invalid GCC installation!\n"; -+ return; -+ } -+ -+ const llvm::Triple &T = TC.getTriple(); -+ const Driver &D = TC.getDriver(); - llvm::Triple::ArchType Arch = T.getArch(); -+ bool m32 = true; -+ StringRef Linker = TC.getLinker(); -+ -+ if (Arg *A = Args.getLastArg(options::OPT_m64)) -+ m32 = false; -+ -+ std::string GCCLibPath; -+ std::string YPPath; -+ GCCLibPath += "/lib/gcc/"; -+ std::string LibPath = "/usr/lib/"; -+ std::string ShortLibPath = "/lib/"; -+ std::string ClangLibPath; -+ const char* moption; -+ - switch (Arch) { - case llvm::Triple::x86: -- GCCLibPath += -- ("i386-" + T.getVendorName() + "-" + T.getOSName()).str() + "/4.5.2/"; -+ if (m32) { -+ GCCLibPath = TC.getGCCInternalLibDir().str(); -+ GCCLibPath += "/"; -+ moption = "-32"; -+ YPPath = "/lib:/usr/lib"; -+ ClangLibPath = "/usr/lib/clang/"; -+ } else { -+ GCCLibPath = TC.getGCCInternalMultiLibDir().str(); -+ GCCLibPath += "/"; -+ LibPath += "amd64/"; -+ ShortLibPath += "amd64/"; -+ moption = "-64"; -+ YPPath = "/lib/amd64:/usr/lib/amd64"; -+ ClangLibPath = "/usr/lib/clang/amd64/"; -+ } - break; -+ case llvm::Triple::sparc: -+ if (m32) { -+ GCCLibPath = TC.getGCCInternalLibDir().str(); -+ GCCLibPath += "/"; -+ moption = "-32"; -+ YPPath = "/lib:/usr/lib"; -+ ClangLibPath = "/usr/lib/clang/"; -+ } else { -+ GCCLibPath = TC.getGCCInternalMultiLibDir().str(); -+ GCCLibPath += "/"; -+ LibPath += "sparcv9/"; -+ ShortLibPath += "sparcv9/"; -+ moption = "-64"; -+ YPPath = "/lib/sparcv9:/usr/lib/sparcv9"; -+ ClangLibPath = "/usr/lib/clang/sparcv9/"; -+ } -+ break; - case llvm::Triple::x86_64: -- GCCLibPath += ("i386-" + T.getVendorName() + "-" + T.getOSName()).str(); -- GCCLibPath += "/4.5.2/amd64/"; -+ if (m32) { -+ GCCLibPath = TC.getGCCInternalMultiLibDir().str(); -+ GCCLibPath += "/"; -+ moption = "-32"; -+ YPPath = "/lib:/usr/lib"; -+ ClangLibPath = "/usr/lib/clang/"; -+ } else { -+ GCCLibPath = TC.getGCCInternalLibDir().str(); -+ GCCLibPath += "/"; - LibPath += "amd64/"; -+ ShortLibPath += "amd64/"; -+ moption = "-64"; -+ YPPath = "/lib/amd64:/usr/lib/amd64"; -+ ClangLibPath = "/usr/lib/clang/amd64/"; -+ } - break; -+ case llvm::Triple::sparcv9: -+ if (m32) { -+ GCCLibPath = TC.getGCCInternalMultiLibDir().str(); -+ GCCLibPath += "/"; -+ moption = "-32"; -+ YPPath = "/lib:/usr/lib"; -+ ClangLibPath = "/usr/lib/clang/"; -+ } else { -+ GCCLibPath = TC.getGCCInternalLibDir().str(); -+ GCCLibPath += "/"; -+ LibPath += "sparcv9/"; -+ ShortLibPath += "sparcv9/"; -+ moption = "-64"; -+ YPPath = "/lib/sparcv9:/usr/lib/sparcv9"; -+ ClangLibPath = "/usr/lib/clang/sparcv9/"; -+ } -+ break; - default: -- llvm_unreachable("Unsupported architecture"); -+ D.Diag(diag::err_target_unsupported_arch) << T.getArchName() -+ << T.getTriple(); -+ break; - } - - ArgStringList CmdArgs; - -- // Demangle C++ names in errors -- CmdArgs.push_back("-C"); -+ CmdArgs.push_back(Args.MakeArgString("-zignore")); - -- if ((!Args.hasArg(options::OPT_nostdlib)) && -- (!Args.hasArg(options::OPT_shared))) { -- CmdArgs.push_back("-e"); -- CmdArgs.push_back("_start"); -+ Arg *PIEArg = Args.getLastArg(options::OPT_fPIE, options::OPT_fpie); -+ if (PIEArg) { -+ if (PIEArg->getOption().matches(options::OPT_fPIE) || -+ PIEArg->getOption().matches(options::OPT_fpie)) { -+ CmdArgs.push_back(Args.MakeArgString("-Qy")); -+ CmdArgs.push_back(Args.MakeArgString("-zdirect")); -+ CmdArgs.push_back(Args.MakeArgString("-ztextwarn")); -+ CmdArgs.push_back(Args.MakeArgString("-ztype=pie")); -+ CmdArgs.push_back(Args.MakeArgString("-zaslr=enable")); - } -+ } - -+ // Silence warning for "-g: argument not used during compilation -+ Args.ClaimAllArgs(options::OPT_g_Group); -+ -+ // Language options -+ Args.ClaimAllArgs(options::OPT_emit_llvm); -+ Args.ClaimAllArgs(options::OPT_w); -+ -+ if (Args.hasArg(options::OPT_s)) -+ CmdArgs.push_back("-s"); -+ -+ const std::vector &ExtraOpts = TC.getExtraOpts(); -+ -+ // Handle extra options -+ if (ExtraOpts.size()) { -+ for (std::vector::const_iterator I = ExtraOpts.begin(), -+ E = ExtraOpts.end(); I != E; ++I) -+ CmdArgs.push_back((*I).c_str()); -+ } -+ -+ // Demangle C++ names -+ if (Linker == "/usr/gnu/bin/ld.bfd" || Linker == "/usr/gnu/bin/ld.gold" || -+ Linker == "/usr/gnu/bin/ld" || Linker == "/usr/bin/gld") -+ CmdArgs.push_back("--demangle"); -+ else if (Linker == "/usr/bin/ld") -+ CmdArgs.push_back("-C"); -+ - if (Args.hasArg(options::OPT_static)) { - CmdArgs.push_back("-Bstatic"); - CmdArgs.push_back("-dn"); - } else { - CmdArgs.push_back("-Bdynamic"); -+ CmdArgs.push_back("-dy"); - if (Args.hasArg(options::OPT_shared)) { - CmdArgs.push_back("-shared"); - } else { -@@ -6125,41 +6577,261 @@ - assert(Output.isNothing() && "Invalid output."); - } - -+ const char* Values = "values-Xa.o"; -+ const char* Xpg = "values-xpg4.o"; -+ -+ Arg *STDArg = Args.getLastArg(options::OPT_std_EQ); -+ if (STDArg) { -+ if (STDArg->getOption().matches(options::OPT_std_EQ)) { -+ std::string Lang = STDArg->getValue(); -+ if ((Lang == "c99") || (Lang == "c11") || -+ (Lang == "c++11") || (Lang == "c++14")) { -+ Values = "values-Xc.o"; -+ Xpg = "values-xpg6.o"; -+ } -+ } -+ } -+ -+ const char *gldm = 0; -+ if (Linker == "/usr/gnu/bin/ld.bfd" || Linker == "/usr/gnu/bin/ld.gold" || -+ Linker == "/usr/gnu/bin/ld" || Linker == "/usr/bin/gld") { -+ switch (Arch) { -+ case llvm::Triple::x86: -+ if (m32) -+ gldm = "-m elf_i386"; -+ else -+ gldm = "-m elf_x86_64"; -+ break; -+ case llvm::Triple::x86_64: -+ if (m32) -+ gldm = "-m elf_i386"; -+ else -+ gldm = "-m elf_x86_64"; -+ break; -+ case llvm::Triple::sparc: -+ if (m32) -+ gldm = "-m elf32_sparc"; -+ else -+ gldm = "-m elf64_sparc"; -+ break; -+ case llvm::Triple::sparcv9: -+ if (m32) -+ gldm = "-m elf32_sparc"; -+ else -+ gldm = "-m elf64_sparc"; -+ break; -+ default: -+ break; -+ } -+ -+ if (gldm) -+ CmdArgs.push_back(Args.MakeArgString(StringRef(gldm))); -+ -+ if (Linker == "/usr/gnu/bin/ld.gold") { -+ if (Args.hasArg(options::OPT_O)) -+ Args.AddAllArgs(CmdArgs, options::OPT_O); -+ } -+ } -+ -+ if (Args.hasArg(options::OPT_v)) -+ CmdArgs.push_back(Args.MakeArgString(StringRef("-V"))); -+ -+ CmdArgs.push_back(Args.MakeArgString(StringRef("-Qy"))); -+ if (Linker == "/usr/bin/ld") { -+ CmdArgs.push_back(Args.MakeArgString(StringRef("-Y"))); -+ CmdArgs.push_back(Args.MakeArgString(StringRef("P," + YPPath))); -+ } else { -+ CmdArgs.push_back(Args.MakeArgString(StringRef("-Y"))); -+ CmdArgs.push_back(Args.MakeArgString(StringRef(YPPath))); -+ } -+ -+ CmdArgs.push_back(Args.MakeArgString(StringRef("-L") + LibPath)); -+ -+ std::string P = GCCLibPath; -+ P += "../../.."; -+ CmdArgs.push_back(Args.MakeArgString(StringRef("-L") + P)); -+ -+ std::string crt1o; -+ - if (!Args.hasArg(options::OPT_nostdlib) && - !Args.hasArg(options::OPT_nostartfiles)) { - if (!Args.hasArg(options::OPT_shared)) { -- CmdArgs.push_back(Args.MakeArgString(LibPath + "crt1.o")); -+ switch (Arch) { -+ case llvm::Triple::sparc: -+ case llvm::Triple::sparcv9: -+ crt1o = GCCLibPath; -+ break; -+ case llvm::Triple::x86: -+ case llvm::Triple::x86_64: -+ crt1o = LibPath; -+ break; -+ default: -+ D.Diag(diag::err_target_unsupported_arch) << T.getArchName() -+ << T.getTriple(); -+ break; -+ } -+ -+ crt1o += "/crt1.o"; -+ -+ CmdArgs.push_back(Args.MakeArgString(crt1o.c_str())); - CmdArgs.push_back(Args.MakeArgString(LibPath + "crti.o")); -- CmdArgs.push_back(Args.MakeArgString(LibPath + "values-Xa.o")); -+ CmdArgs.push_back(Args.MakeArgString(LibPath + Values)); -+ CmdArgs.push_back(Args.MakeArgString(LibPath + Xpg)); -+ CmdArgs.push_back(Args.MakeArgString(StringRef("-L") + GCCLibPath)); -+ CmdArgs.push_back(Args.MakeArgString("-L" + P)); - CmdArgs.push_back(Args.MakeArgString(GCCLibPath + "crtbegin.o")); - } else { - CmdArgs.push_back(Args.MakeArgString(LibPath + "crti.o")); -- CmdArgs.push_back(Args.MakeArgString(LibPath + "values-Xa.o")); -+ CmdArgs.push_back(Args.MakeArgString(LibPath + Values)); -+ CmdArgs.push_back(Args.MakeArgString(LibPath + Xpg)); -+ CmdArgs.push_back(Args.MakeArgString(StringRef("-L") + GCCLibPath)); -+ CmdArgs.push_back(Args.MakeArgString(StringRef("-L") + P)); - CmdArgs.push_back(Args.MakeArgString(GCCLibPath + "crtbegin.o")); - } -- if (getToolChain().getDriver().CCCIsCXX()) -- CmdArgs.push_back(Args.MakeArgString(LibPath + "cxa_finalize.o")); -+ } else if (Args.hasArg(options::OPT_nostdlib) && -+ !Args.hasArg(options::OPT_nostartfiles)) { -+ if (Args.hasArg(options::OPT_shared)) { -+ CmdArgs.push_back(Args.MakeArgString(LibPath + "crti.o")); -+ CmdArgs.push_back(Args.MakeArgString(LibPath + Values)); -+ CmdArgs.push_back(Args.MakeArgString(LibPath + Xpg)); -+ CmdArgs.push_back(Args.MakeArgString(StringRef("-L") + GCCLibPath)); -+ CmdArgs.push_back(Args.MakeArgString(StringRef("-L") + P)); -+ CmdArgs.push_back(Args.MakeArgString(GCCLibPath + "crtbegin.o")); -+ } else { -+ CmdArgs.push_back(Args.MakeArgString(crt1o.c_str())); -+ CmdArgs.push_back(Args.MakeArgString(LibPath + "crti.o")); -+ CmdArgs.push_back(Args.MakeArgString(LibPath + Values)); -+ CmdArgs.push_back(Args.MakeArgString(LibPath + Xpg)); -+ CmdArgs.push_back(Args.MakeArgString(StringRef("-L") + GCCLibPath)); -+ CmdArgs.push_back(Args.MakeArgString("-L" + P)); - } -+ } else if (!Args.hasArg(options::OPT_nostdlib) && -+ Args.hasArg(options::OPT_nostartfiles)) { -+ if (Args.hasArg(options::OPT_shared)) { -+ CmdArgs.push_back(Args.MakeArgString(GCCLibPath + "crtend.o")); -+ } -+ } - -- CmdArgs.push_back(Args.MakeArgString("-L" + GCCLibPath)); -+ // Itanium C++ ABI. -+ std::string CXAFinalize; -+ bool HasSystemCXAFinalize = false; - -+ if (!Args.hasArg(options::OPT_shared)) { -+ if (PIEArg) { -+ if (PIEArg->getOption().matches(options::OPT_fPIE) || -+ PIEArg->getOption().matches(options::OPT_fpie)) { -+ CXAFinalize = ClangLibPath + "cxa_finalize_pic.o"; -+ } -+ } else { -+ CXAFinalize = ClangLibPath + "cxa_finalize.o"; -+ } -+ -+ HasSystemCXAFinalize = llvm::sys::fs::exists(CXAFinalize.c_str()); -+ -+ if (D.CCCIsCXX() && HasSystemCXAFinalize) -+ CmdArgs.push_back(Args.MakeArgString(CXAFinalize.c_str())); -+ } -+ -+ CmdArgs.push_back(Args.MakeArgString(StringRef("-L" + GCCLibPath))); -+ CmdArgs.push_back(Args.MakeArgString(StringRef("-L") + LibPath)); -+ CmdArgs.push_back(Args.MakeArgString(StringRef("-L") + ShortLibPath)); -+ - Args.AddAllArgs(CmdArgs, options::OPT_L); -+ const ToolChain::path_list Paths = TC.getFilePaths(); -+ for (ToolChain::path_list::const_iterator B = Paths.begin(), E = Paths.end(); -+ B != E; ++B) { -+ CmdArgs.push_back(Args.MakeArgString(StringRef("-L") + *B)); -+ -+ // Itanium C++ ABI. -+ if (!Args.hasArg(options::OPT_shared)) { -+ if (D.CCCIsCXX() && !HasSystemCXAFinalize) { -+ if (PIEArg) { -+ if (PIEArg->getOption().matches(options::OPT_fPIE) || -+ PIEArg->getOption().matches(options::OPT_fpie)) { -+ CXAFinalize = *B + "/cxa_finalize_pic.o"; -+ } -+ } else { -+ CXAFinalize = *B + "/cxa_finalize.o"; -+ } -+ -+ if (llvm::sys::fs::exists(CXAFinalize.c_str())) -+ CmdArgs.push_back(Args.MakeArgString(CXAFinalize.c_str())); -+ } -+ } -+ } -+ - Args.AddAllArgs(CmdArgs, options::OPT_T_Group); - Args.AddAllArgs(CmdArgs, options::OPT_e); -+ Args.AddAllArgs(CmdArgs, options::OPT_s); -+ Args.AddAllArgs(CmdArgs, options::OPT_t); - Args.AddAllArgs(CmdArgs, options::OPT_r); - -- AddLinkerInputs(getToolChain(), Inputs, Args, CmdArgs); -+ std::vector zoptions = Args.getAllArgValues(options::OPT_z); -+ std::string zoption; - -+ for (std::vector::const_iterator B = zoptions.begin(), -+ E = zoptions.end(); B != E; ++B) { -+ zoption = "-z"; -+ zoption += *B; -+ CmdArgs.push_back(Args.MakeArgString(StringRef(zoption))); -+ } -+ -+ if (!Args.hasArg(options::OPT_mimpure_text) && -+ !Args.hasArg(options::OPT_fpie) && -+ !Args.hasArg(options::OPT_fPIE)) -+ CmdArgs.push_back(Args.MakeArgString(StringRef("-ztext"))); -+ -+ // Itanium C++ ABI. -+ if (D.CCCIsCXX()) { -+ if (!Args.hasArg(options::OPT_shared)) { -+ const char* zfiniarray = "-zfiniarray=__cxa_finalize"; -+ CmdArgs.push_back(Args.MakeArgString(zfiniarray)); -+ } -+ } -+ -+ if (Linker == "/usr/gnu/bin/ld.gold" || Linker == "/usr/gnu/bin/ld" || -+ Linker == "/usr/gnu/bin/ld.bfd") { -+ CmdArgs.push_back("-plugin"); -+ std::string Plugin = D.Dir + "/../lib/LLVMgold.so"; -+ CmdArgs.push_back(Args.MakeArgString(Plugin)); -+ } else { -+ CmdArgs.push_back(moption); -+ } -+ -+ if (Arg *A = Args.getLastArg(options::OPT_rpath)) { -+ StringRef V = A->getValue(); -+ if (Linker == "/usr/gnu/bin/ld.gold" || Linker == "/usr/gnu/bin/ld" || -+ Linker == "/usr/gnu/bin/ld.bfd") { -+ CmdArgs.push_back(Args.MakeArgString("-rpath")); -+ CmdArgs.push_back(Args.MakeArgString(V)); -+ } else { -+ CmdArgs.push_back(Args.MakeArgString("-R")); -+ CmdArgs.push_back(Args.MakeArgString(V)); -+ } -+ } -+ -+ AddLinkerInputs(TC, Inputs, Args, CmdArgs); -+ AddLibgcc(D, CmdArgs, Args, Linker.str()); -+ - if (!Args.hasArg(options::OPT_nostdlib) && - !Args.hasArg(options::OPT_nodefaultlibs)) { -- if (getToolChain().getDriver().CCCIsCXX()) -- getToolChain().AddCXXStdlibLibArgs(Args, CmdArgs); -- CmdArgs.push_back("-lgcc_s"); -- if (!Args.hasArg(options::OPT_shared)) { -- CmdArgs.push_back("-lgcc"); -+ if (D.CCCIsCXX()) -+ TC.AddCXXStdlibLibArgs(Args, CmdArgs); -+ - CmdArgs.push_back("-lc"); - CmdArgs.push_back("-lm"); -+ CmdArgs.push_back("-lgcc_s"); -+ -+ if (Args.hasArg(options::OPT_static)) { -+ CmdArgs.push_back("-lgcc"); -+ CmdArgs.push_back("-lgcc_eh"); - } -+ } else if (Args.hasArg(options::OPT_nostdlib) && -+ (!Args.hasArg(options::OPT_nodefaultlibs))) { -+ CmdArgs.push_back("-lgcc_s"); -+ -+ if (Args.hasArg(options::OPT_static)) -+ CmdArgs.push_back("-lgcc_eh"); - } - - if (!Args.hasArg(options::OPT_nostdlib) && -@@ -6166,15 +6838,17 @@ - !Args.hasArg(options::OPT_nostartfiles)) { - CmdArgs.push_back(Args.MakeArgString(GCCLibPath + "crtend.o")); - } -+ - CmdArgs.push_back(Args.MakeArgString(LibPath + "crtn.o")); - -- addProfileRT(getToolChain(), Args, CmdArgs); -+ addProfileRT(TC, Args, CmdArgs); - -- const char *Exec = -- Args.MakeArgString(getToolChain().GetLinkerPath()); -- C.addCommand(llvm::make_unique(JA, *this, Exec, CmdArgs)); -+ C.addCommand(llvm::make_unique(JA, *this, -+ Args.MakeArgString(Linker), -+ CmdArgs)); - } - -+ - void openbsd::Assemble::ConstructJob(Compilation &C, const JobAction &JA, - const InputInfo &Output, - const InputInfoList &Inputs, -@@ -7280,6 +7954,40 @@ - if (isAndroid && !StaticLibgcc) - CmdArgs.push_back("-ldl"); - } -+ -+static void AddLibgcc(const Driver &D, ArgStringList &CmdArgs, -+ const ArgList &Args, const std::string& Exec) { -+ bool StaticLibgcc = Args.hasArg(options::OPT_static) || -+ Args.hasArg(options::OPT_static_libgcc); -+ if (!D.CCCIsCXX()) -+ CmdArgs.push_back("-lgcc"); -+ -+ if (StaticLibgcc) { -+ if (D.CCCIsCXX()) -+ CmdArgs.push_back("-lgcc"); -+ } else { -+ if ((!D.CCCIsCXX()) && ((Exec == "/usr/bin/gld") || -+ (Exec == "/usr/gnu/bin/ld") || -+ (Exec == "/usr/gnu/bin/ld.bfd") || -+ (Exec == "/usr/gnu/bin/ld.gold"))) -+ CmdArgs.push_back("--as-needed"); -+ -+ CmdArgs.push_back("-lgcc_s"); -+ if ((!D.CCCIsCXX()) && ((Exec == "/usr/bin/gld") || -+ (Exec == "/usr/gnu/bin/ld") || -+ (Exec == "/usr/gnu/bin/ld.bfd") || -+ (Exec == "/usr/gnu/bin/ld.gold"))) -+ CmdArgs.push_back("--no-as-needed"); -+ } -+ -+ if (StaticLibgcc) -+ CmdArgs.push_back("-lgcc_eh"); -+ else if (!Args.hasArg(options::OPT_shared) && D.CCCIsCXX()) -+ CmdArgs.push_back("-lgcc"); -+ -+ if (!StaticLibgcc) -+ CmdArgs.push_back("-ldl"); -+} - - static std::string getLinuxDynamicLinker(const ArgList &Args, - const toolchains::Linux &ToolChain) { ---- tools/clang/lib/Driver/ToolChains.h 2015-08-29 19:24:32.064113013 -0700 -+++ tools/clang/lib/Driver/ToolChains.h 2015-08-30 12:42:03.657485673 -0700 -@@ -508,16 +508,106 @@ - llvm::opt::ArgStringList &CC1Args) const override; - }; - --class LLVM_LIBRARY_VISIBILITY Solaris : public Generic_GCC { -+class LLVM_LIBRARY_VISIBILITY Solaris : public Generic_ELF { - public: - Solaris(const Driver &D, const llvm::Triple &Triple, - const llvm::opt::ArgList &Args); - -- bool IsIntegratedAssemblerDefault() const override { return true; } -+ bool IsIntegratedAssemblerDefault() const override { return !UseGnuAs; } -+ -+ std::string computeSysRoot() const; -+ -+ bool addLibStdCXXIncludePaths(Twine Base, Twine Suffix, -+ StringRef GCCTriple, -+ StringRef GCCMultiarchTriple, -+ StringRef TargetMultiarchTriple, -+ Twine IncludeSuffix, -+ const llvm::opt::ArgList &DriverArgs, -+ llvm::opt::ArgStringList &CC1Args) const; -+ -+ void addLibStdCXXIncludePaths(Twine Base, Twine TargetArchDir, -+ const llvm::opt::ArgList &DriverArgs, -+ llvm::opt::ArgStringList &CC1Args) const; -+ -+ void AddClangCXXStdlibIncludeArgs(const llvm::opt::ArgList &DriverArgs, -+ llvm::opt::ArgStringList &CC1Args) const override; -+ -+ void AddClangSystemIncludeArgs(const llvm::opt::ArgList &DriverArgs, -+ llvm::opt::ArgStringList &CC1Args) const override; -+ -+ void addClangTargetOptions(const llvm::opt::ArgList &DriverArgs, -+ llvm::opt::ArgStringList &CC1Args) const override; -+ -+ void findGCCMajorMinor() const; -+ void findGCCMajorMinorMicro(const llvm::Triple &Triple) const; -+ void findGCCIncludeDirs(const llvm::Triple &Triple, -+ const llvm::opt::ArgList &Args) const; -+ void findGCCInternalLibDir(const llvm::Triple &Triple, -+ const llvm::opt::ArgList &Args) const; -+ void findSpecifiedGCCToolchain(const char *StartingPath, -+ const llvm::Triple &Triple, -+ const llvm::opt::ArgList &Args) const; -+ -+ StringRef getAssembler() const { return Assembler.c_str(); } -+ StringRef getLinker() const { return Linker.c_str(); } -+ StringRef getGCCInstallDir() const { return GCCInstallDir.c_str(); } -+ StringRef getGCCMajorMinor() const { return GCCMajorMinor.c_str(); } -+ StringRef getMArch() const { return march.c_str(); } -+ StringRef getMTune() const { return mtune.c_str(); } -+ StringRef getMCpu() const { return mcpu.c_str(); } -+ StringRef getGCCInternalLibDir() const { return GCCInternalLibDir; } -+ -+ StringRef getGCCInternalMultiLibDir() const { -+ return GCCInternalMultiLibDir; -+ } -+ -+ StringRef getGCCMajorMinorMicro() const { -+ return GCCMajorMinorMicro.c_str(); -+ } -+ -+ const std::vector &getGCCIncludeDirs() const { -+ return GCCIncludeDirs; -+ } -+ -+ const std::vector &getExtraOpts() const { -+ return ExtraOpts; -+ } -+ -+ bool isValid() const { return IsValid; } -+ -+ void print(raw_ostream &OS) const; -+ - protected: - Tool *buildAssembler() const override; - Tool *buildLinker() const override; -+ void validate(); -+ -+private: -+ bool UseGnuAs; -+ bool UseGnuLd; -+ bool UseGoldLd; -+ bool UseSunLd; -+ mutable bool UseMediatedGCCToolChainPath; -+ mutable bool UseSpecifiedGCCToolChainPath; -+ bool IsValid; -+ -+protected: -+ mutable std::string GCCInstallDir; -+ mutable std::string GCCMajorMinor; -+ mutable std::string GCCMajorMinorMicro; -+ mutable std::string GCCInternalLibDir; -+ mutable std::string GCCInternalMultiLibDir; -+ mutable std::vector GCCIncludeDirs; -+ -+ mutable std::string Assembler; -+ mutable std::string Linker; -+ mutable std::string mtune; -+ mutable std::string march; -+ mutable std::string mcpu; - -+ mutable std::vector ExtraOpts; -+ static const char *MediatedGCCToolChainPath; -+ static const bool SupportsClangLibCPlusPlus; - }; - - ---- tools/clang/lib/Driver/ToolChains.cpp 2015-04-27 01:13:25.000000000 -0700 -+++ tools/clang/lib/Driver/ToolChains.cpp 2015-08-30 13:11:52.217344511 -0700 -@@ -28,8 +28,10 @@ - #include "llvm/Support/FileSystem.h" - #include "llvm/Support/MemoryBuffer.h" - #include "llvm/Support/Path.h" -+#include "llvm/Support/Host.h" - #include "llvm/Support/Program.h" - #include "llvm/Support/raw_ostream.h" -+ - #include // ::getenv - #include - -@@ -38,6 +40,19 @@ - using namespace clang; - using namespace llvm::opt; - -+#if defined(LLVM_ON_UNIX) -+#include -+#include -+#include -+#include -+#include -+#include -+#endif -+ -+/// \brief Get our best guess at the multiarch triple for a target. -+static std::string getMultiarchTriple(const llvm::Triple &TargetTriple, -+ StringRef SysRoot); -+ - MachO::MachO(const Driver &D, const llvm::Triple &Triple, - const ArgList &Args) - : ToolChain(D, Triple, Args) { -@@ -1214,6 +1229,11 @@ - // If we have a SysRoot, try that first. - if (!D.SysRoot.empty()) { - Prefixes.push_back(D.SysRoot); -+ -+ // Add Solaris-specific GCC locations. -+ if (TargetTriple.getOS() == llvm::Triple::Solaris) -+ Prefixes.push_back("/usr/gcc"); -+ - Prefixes.push_back(D.SysRoot + "/usr"); - } - -@@ -1303,20 +1323,24 @@ - static const char *const ARMebHFTriples[] = { "armeb-linux-gnueabihf", - "armebv7hl-redhat-linux-gnueabi" }; - -- static const char *const X86_64LibDirs[] = { "/lib64", "/lib" }; -+ static const char *const X86_64LibDirs[] = { "/lib64", "/lib/amd64", -+ "/lib/64", "/lib" }; - static const char *const X86_64Triples[] = { - "x86_64-linux-gnu", "x86_64-unknown-linux-gnu", "x86_64-pc-linux-gnu", - "x86_64-redhat-linux6E", "x86_64-redhat-linux", "x86_64-suse-linux", - "x86_64-manbo-linux-gnu", "x86_64-linux-gnu", "x86_64-slackware-linux", -- "x86_64-linux-android", "x86_64-unknown-linux" -+ "x86_64-linux-android", "x86_64-unknown-linux", "x86_64-pc-solaris2.11", -+ "x86_64-pc-solaris2.12", "x86_64-pc-solaris2.13" - }; -+ - static const char *const X32LibDirs[] = { "/libx32" }; - static const char *const X86LibDirs[] = { "/lib32", "/lib" }; - static const char *const X86Triples[] = { - "i686-linux-gnu", "i686-pc-linux-gnu", "i486-linux-gnu", "i386-linux-gnu", - "i386-redhat-linux6E", "i686-redhat-linux", "i586-redhat-linux", - "i386-redhat-linux", "i586-suse-linux", "i486-slackware-linux", -- "i686-montavista-linux", "i686-linux-android", "i586-linux-gnu" -+ "i686-montavista-linux", "i686-linux-android", "i586-linux-gnu", -+ "i386-pc-solaris2.11", "i386-pc-solaris2.12", "i386-pc-solaris2.13" - }; - - static const char *const MIPSLibDirs[] = { "/lib" }; -@@ -1358,10 +1382,18 @@ - - static const char *const SPARCv8LibDirs[] = { "/lib32", "/lib" }; - static const char *const SPARCv8Triples[] = { "sparc-linux-gnu", -- "sparcv8-linux-gnu" }; -- static const char *const SPARCv9LibDirs[] = { "/lib64", "/lib" }; -+ "sparcv8-linux-gnu", -+ "sparc-sun-solaris2.11", -+ "sparc-sun-solaris2.12", -+ "sparc-sun-solaris2.13" }; -+ -+ static const char *const SPARCv9LibDirs[] = { "/lib64", "/lib/sparcv9", -+ "/lib/64", "/lib" }; - static const char *const SPARCv9Triples[] = { "sparc64-linux-gnu", -- "sparcv9-linux-gnu" }; -+ "sparcv9-linux-gnu", -+ "sparcv9-sun-solaris2.11", -+ "sparcv9-sun-solaris2.12", -+ "sparcv9-sun-solaris2.13" }; - - static const char *const SystemZLibDirs[] = { "/lib64", "/lib" }; - static const char *const SystemZTriples[] = { -@@ -2649,16 +2681,703 @@ - - /// Solaris - Solaris tool chain which can call as(1) and ld(1) directly. - -+const char *Solaris::MediatedGCCToolChainPath = -+"/path/to/mediated/gcc/toolchain"; -+const bool Solaris::SupportsClangLibCPlusPlus = false; -+ - Solaris::Solaris(const Driver &D, const llvm::Triple& Triple, -- const ArgList &Args) -- : Generic_GCC(D, Triple, Args) { -+ const llvm::opt::ArgList &Args) -+ : Generic_ELF(D, Triple, Args), -+ UseGnuAs(true), -+ UseGnuLd(false), -+ UseGoldLd(false), -+ UseSunLd(true), -+ UseMediatedGCCToolChainPath(false), -+ UseSpecifiedGCCToolChainPath(false), -+ IsValid(false), -+ GCCInstallDir("/usr/gcc/"), -+ GCCMajorMinor(""), -+ GCCMajorMinorMicro(""), -+ GCCInternalLibDir(""), -+ GCCInternalMultiLibDir(""), -+ GCCIncludeDirs(), -+ Assembler("/usr/gnu/bin/as"), -+ Linker("/usr/bin/ld"), -+ mtune(""), -+ march(""), -+ mcpu(""), -+ ExtraOpts() { -+ if (Arg *A = Args.getLastArg(options::OPT_gcc_toolchain)) { -+ GCCInstallDir = A->getValue(); -+ if (!llvm::sys::fs::exists(GCCInstallDir)) -+ D.Diag(diag::err_drv_no_such_file) << GCCInstallDir; -+ else { -+ findSpecifiedGCCToolchain(GCCInstallDir.c_str(), Triple, Args); - -- getProgramPaths().push_back(getDriver().getInstalledDir()); -+ if (!UseSpecifiedGCCToolChainPath) { -+ D.Diag(diag::err_drv_unsupported_rtlib_for_platform) -+ << GCCInstallDir << Triple.getTriple(); -+ } else { -+ findGCCIncludeDirs(Triple, Args); -+ findGCCInternalLibDir(Triple, Args); -+ } -+ } -+ } else if (llvm::sys::fs::exists(Solaris::MediatedGCCToolChainPath)) { -+ GCCInstallDir = Solaris::MediatedGCCToolChainPath; -+ UseMediatedGCCToolChainPath = true; -+ } else { -+ findGCCMajorMinor(); -+ findGCCMajorMinorMicro(Triple); -+ findGCCIncludeDirs(Triple, Args); -+ findGCCInternalLibDir(Triple, Args); -+ } -+ -+ if (Arg *A = Args.getLastArg(options::OPT_fuse_ld_EQ)) { -+ Linker = A->getValue(); -+ if (Linker == "bfd") -+ Linker = "/usr/gnu/bin/ld"; -+ else if (Linker == "gold") -+ Linker = "/usr/gnu/bin/ld.gold"; -+ -+ if ((Linker == "/usr/gnu/bin/ld") || (Linker == "/usr/gnu/bin/ld.bfd") || -+ (Linker == "/usr/bin/gld") || (Linker == "/usr/bin/gld.bfd")) { -+ UseGnuLd = true; -+ UseGoldLd = false; -+ UseSunLd = false; -+ } else if ((Linker == "/usr/gnu/bin/ld.gold") || -+ (Linker == "/usr/bin/gld.gold") || -+ (Linker == "/usr/bin/ld.gold")) { -+ UseGnuLd = false; -+ UseSunLd = false; -+ UseGoldLd = true; -+ } -+ } -+ -+ if (Arg *A = Args.getLastArg(options::OPT_fuse_as_EQ)) { -+ Assembler = A->getValue(); -+ if (Assembler == "llvm") -+ UseGnuAs = false; -+ else if ((Assembler == "/usr/gnu/bin/as") || -+ (Assembler == "/usr/bin/gas")) -+ UseGnuAs = true; -+ else if (Assembler == "gas") { -+ Assembler = "/usr/gnu/bin/as"; -+ UseGnuAs = true; -+ } else if ((Assembler == "/usr/bin/as") || (Assembler == "sun") || -+ (Assembler == "solaris")) -+ D.Diag(diag::err_drv_clang_unsupported) << A->getAsString(Args); -+ } -+ -+ getProgramPaths().push_back(GCCInstallDir); - if (getDriver().getInstalledDir() != getDriver().Dir) - getProgramPaths().push_back(getDriver().Dir); - -+ llvm::Triple::ArchType Arch = Triple.getArch(); -+ -+ switch (Arch) { -+ case llvm::Triple::x86: -+ getFilePaths().push_back(getDriver().Dir + "/../lib"); -+ getFilePaths().push_back("/usr/lib"); -+ march = mtune = "i686"; -+ break; -+ case llvm::Triple::sparc: -+ getFilePaths().push_back(getDriver().Dir + "/../lib"); -+ getFilePaths().push_back("/usr/lib"); -+ mcpu = "ultrasparc"; -+ mtune = "ultrasparc"; -+ march = "v8plusa"; -+ break; -+ case llvm::Triple::x86_64: -+ getFilePaths().push_back(getDriver().Dir + "/../lib/amd64"); -+ getFilePaths().push_back("/usr/lib/amd64"); -+ march = mtune = "opteron"; -+ break; -+ case llvm::Triple::sparcv9: -+ getFilePaths().push_back(getDriver().Dir + "/../lib/sparcv9"); -+ getFilePaths().push_back("/usr/lib/sparcv9"); -+ mcpu = "ultrasparc"; -+ mtune = "ultrasparc"; -+ march = "v9a"; -+ break; -+ default: - getFilePaths().push_back(getDriver().Dir + "/../lib"); - getFilePaths().push_back("/usr/lib"); -+ break; -+ } -+ -+ validate(); -+ -+ if (Args.hasArg(options::OPT_v)) -+ this->print(llvm::errs()); -+} -+ -+std::string Solaris::computeSysRoot() const { -+ if (!getDriver().SysRoot.empty()) -+ return getDriver().SysRoot; -+ -+ return std::string("/"); -+} -+ -+bool Solaris::addLibStdCXXIncludePaths(Twine Base, Twine Suffix, -+ StringRef GCCTriple, -+ StringRef GCCMultiarchTriple, -+ StringRef TargetMultiarchTriple, -+ Twine IncludeSuffix, -+ const llvm::opt::ArgList &DriverArgs, -+ llvm::opt::ArgStringList &CC1Args) const { -+ if (!llvm::sys::fs::exists(Base + Suffix)) -+ return false; -+ -+ addSystemInclude(DriverArgs, CC1Args, Base); -+ addSystemInclude(DriverArgs, CC1Args, Base + Suffix); -+ -+ if ((GCCMultiarchTriple.empty() && TargetMultiarchTriple.empty()) || -+ llvm::sys::fs::exists(Base + Suffix + "/" + GCCTriple + IncludeSuffix)) { -+ addSystemInclude(DriverArgs, -+ CC1Args, Base + Suffix + "/" + GCCTriple + IncludeSuffix); -+ } else { -+ addSystemInclude(DriverArgs, CC1Args, -+ Base + "/" + GCCMultiarchTriple + Suffix + IncludeSuffix); -+ addSystemInclude(DriverArgs, CC1Args, -+ Base + "/" + TargetMultiarchTriple + Suffix); -+ } -+ -+ addSystemInclude(DriverArgs, CC1Args, Base + "/backward"); -+ addSystemInclude(DriverArgs, CC1Args, Base + Suffix + "/backward"); -+ return true; -+} -+ -+void Solaris::AddClangCXXStdlibIncludeArgs(const llvm::opt::ArgList &DriverArgs, -+ llvm::opt::ArgStringList &CC1Args) const { -+ if (DriverArgs.hasArg(options::OPT_nostdlibinc) || -+ DriverArgs.hasArg(options::OPT_nostdincxx)) -+ return; -+ -+ const Driver &D = getDriver(); -+ -+ // Check for Clang libc++ -+ if (GetCXXStdlibType(DriverArgs) == ToolChain::CST_Libcxx) { -+ if (!Solaris::SupportsClangLibCPlusPlus) { -+ D.Diag(diag::err_drv_invalid_stdlib_name) << "libc++"; -+ return; -+ } -+ -+ StringRef IncludePath = "/usr/include/libc++/v1"; -+ if (!llvm::sys::fs::exists(IncludePath)) { -+ D.Diag(diag::err_drv_no_such_file) << IncludePath; -+ return; -+ } -+ -+ addSystemInclude(DriverArgs, CC1Args, IncludePath); -+ return; -+ } -+ -+ for (std::vector::const_iterator B = -+ getGCCIncludeDirs().begin(), E = getGCCIncludeDirs().end(); -+ B != E; ++B) { -+ llvm::Twine IncludePath((*B)); -+ addSystemInclude(DriverArgs, CC1Args, IncludePath); -+ } -+} -+ -+void Solaris::AddClangSystemIncludeArgs(const ArgList &DriverArgs, -+ ArgStringList &CC1Args) const { -+ const Driver &D = getDriver(); -+ -+ if (DriverArgs.hasArg(options::OPT_nostdinc)) -+ return; -+ -+ std::string SysRoot = computeSysRoot(); -+ -+ if (!DriverArgs.hasArg(options::OPT_nobuiltininc)) { -+ SmallString P(D.ResourceDir); -+ llvm::sys::path::append(P, "/include"); -+ addSystemInclude(DriverArgs, CC1Args, P.str()); -+ } -+ -+ if (DriverArgs.hasArg(options::OPT_nostdlibinc)) -+ return; -+ -+ StringRef CIncludeDirs(C_INCLUDE_DIRS); -+ if (CIncludeDirs != "") { -+ SmallVector dirs; -+ CIncludeDirs.split(dirs, ":"); -+ for (SmallVectorImpl::iterator I = dirs.begin(), E = dirs.end(); -+ I != E; ++I) { -+ StringRef Prefix = -+ llvm::sys::path::is_absolute(*I) ? StringRef(SysRoot) : ""; -+ addExternCSystemInclude(DriverArgs, CC1Args, Prefix + *I); -+ } -+ } -+ -+ addExternCSystemInclude(DriverArgs, CC1Args, "/usr/include"); -+} -+ -+void Solaris::addClangTargetOptions(const ArgList &DriverArgs, -+ ArgStringList &CC1Args) const { -+ const llvm::Triple& TT = getTriple(); -+ llvm::Triple::ArchType Arch = TT.getArch(); -+ -+ if (Arg *A = DriverArgs.getLastArg(options::OPT_mtune_EQ)) { -+ StringRef V = A->getValue(); -+ if (!V.empty()) -+ mtune = V.str(); -+ -+ // FIXME: Impplement SPARC target features. -+ CC1Args.push_back(DriverArgs.MakeArgString("-target-feature")); -+ if (Arch == llvm::Triple::sparc || Arch == llvm::Triple::sparcv9) { -+ std::string S = "mtune="; -+ S += mtune; -+ CC1Args.push_back(DriverArgs.MakeArgString(S.c_str())); -+ } else { -+ CC1Args.push_back(DriverArgs.MakeArgString(mtune.c_str())); -+ } -+ } -+ -+ if (Arg *A = DriverArgs.getLastArg(options::OPT_march_EQ)) { -+ StringRef V = A->getValue(); -+ if (!V.empty()) -+ march = V.str(); -+ -+ CC1Args.push_back(DriverArgs.MakeArgString("-target-feature")); -+ -+ if ((Arch == llvm::Triple::sparc) || (Arch == llvm::Triple::sparcv9)) { -+ std::string S = "march="; -+ S += mtune; -+ CC1Args.push_back(DriverArgs.MakeArgString(S.c_str())); -+ } else { -+ CC1Args.push_back(DriverArgs.MakeArgString(march.c_str())); -+ } -+ } -+ -+ if (Arch == llvm::Triple::sparc || Arch == llvm::Triple::sparcv9) { -+ if (Arg *A = DriverArgs.getLastArg(options::OPT_mcpu_EQ)) { -+ StringRef V = A->getValue(); -+ if (!V.empty()) -+ mcpu = V.str(); -+ else -+ mcpu = "ultrasparc"; -+ } -+ -+ CC1Args.push_back(DriverArgs.MakeArgString("-target-feature")); -+ std::string S = "mcpu="; -+ S += mcpu; -+ CC1Args.push_back(DriverArgs.MakeArgString(S.c_str())); -+ -+ if (Arg *A = DriverArgs.getLastArg(options::OPT_mvis)) { -+ CC1Args.push_back(DriverArgs.MakeArgString("-target-feature")); -+ CC1Args.push_back(DriverArgs.MakeArgString("vis")); -+ } else if (Arg *A = DriverArgs.getLastArg(options::OPT_mvis2)) { -+ CC1Args.push_back(DriverArgs.MakeArgString("-target-feature")); -+ CC1Args.push_back(DriverArgs.MakeArgString("vis2")); -+ } else if (Arg *A = DriverArgs.getLastArg(options::OPT_mvis3)) { -+ CC1Args.push_back(DriverArgs.MakeArgString("-target-feature")); -+ CC1Args.push_back(DriverArgs.MakeArgString("vis3")); -+ } -+ } -+} -+ -+void Solaris::findGCCMajorMinor() const { -+ // FIXME: Add 5.2 after testing the ABI. -+ static const char* const GCCMM[] = { "4.8", "4.9" }; -+ -+ const char* P; -+ std::string Path; -+ -+ if (UseMediatedGCCToolChainPath) { -+ // FIXME: IMPLEMENT. -+ // Needs spec. -+ } -+ -+ Path.reserve(std::string::size_type(PATH_MAX)); -+ -+ for (int I = (llvm::array_lengthof(GCCMM) - 1); I >= 0; --I) { -+ if ((P = GCCMM[I]) != NULL) { -+ Path = GCCInstallDir; -+ Path.append(P); -+ Path.append("/"); -+ -+ if (llvm::sys::fs::exists(Path.c_str())) { -+ GCCMajorMinor = P; -+ break; -+ } -+ } -+ } -+} -+ -+void Solaris::findGCCMajorMinorMicro(const llvm::Triple& T) const { -+ // FIXME: Add 5.2.0 after testing the ABI. -+ static const char* const GCCMMM[] = { "4.8.2", "4.8.5", "4.9.3" }; -+ -+ const char* P; -+ std::string Path; -+ std::string TripleString = llvm::sys::getDefaultTargetTriple(); -+ llvm::Triple::ArchType Arch = T.getArch(); -+ -+ if (UseMediatedGCCToolChainPath) { -+ // FIXME: IMPLEMENT. -+ // Needs spec. -+ } -+ -+ Path.reserve(std::string::size_type(PATH_MAX)); -+ -+ for (int I = (llvm::array_lengthof(GCCMMM) - 1); I >= 0; --I) { -+ if ((P = GCCMMM[I]) != NULL) { -+ if ((P[0] == GCCMajorMinor[0]) && (P[2] == GCCMajorMinor[2])) { -+ Path = GCCInstallDir; -+ Path.append("/"); -+ Path.append(GCCMajorMinor); -+ Path.append("/lib/gcc/"); -+ Path.append(TripleString); -+ Path.append("/"); -+ Path.append(P); -+ -+ if (llvm::sys::fs::exists(Path.c_str())) { -+ std::string Test; -+ // Check if this is a real GCC installation and not just -+ // an empty directory tree -+ switch (Arch) { -+ case llvm::Triple::x86: -+ case llvm::Triple::sparc: -+ Test = Path + "/crtbegin.o"; -+ break; -+ case llvm::Triple::x86_64: -+ Test = Path + "/amd64/crtbegin.o"; -+ break; -+ case llvm::Triple::sparcv9: -+ Test = Path + "/sparcv9/crtbegin.o"; -+ break; -+ default: -+ break; -+ } -+ -+ if (llvm::sys::fs::exists(Test.c_str())) { -+ GCCMajorMinorMicro = P; -+ break; -+ } -+ } -+ } -+ } -+ } -+} -+ -+void Solaris::findSpecifiedGCCToolchain(const char *StartingPath, -+ const llvm::Triple &Triple, -+ const llvm::opt::ArgList &Args) const { -+ DIR *TopLD = 0; -+ DIR *LibLD = 0; -+ DIR *GccLD = 0; -+ DIR *TripleLD = 0; -+ struct dirent *TopDE = 0; -+ struct dirent *LibDE = 0; -+ struct dirent *GccDE = 0; -+ struct dirent *TripleDE = 0; -+ std::string LibDir; -+ std::string GccDir; -+ std::string TripleDir; -+ std::string TripleVersionDir; -+ const char *DName; -+ -+ assert(StartingPath && "Invalid GCC Toolchain starting search path!"); -+ -+ GCCMajorMinor = ""; -+ GCCMajorMinorMicro = ""; -+ UseSpecifiedGCCToolChainPath = false; -+ -+ LibDir.reserve(std::string::size_type(PATH_MAX)); -+ GccDir.reserve(std::string::size_type(PATH_MAX)); -+ TripleDir.reserve(std::string::size_type(PATH_MAX)); -+ TripleVersionDir.reserve(std::string::size_type(PATH_MAX)); -+ -+ if (llvm::sys::fs::exists(StartingPath) && -+ llvm::sys::fs::is_directory(StartingPath)) { -+ TopLD = opendir(StartingPath); -+ assert(TopLD && "Cannot obtain a valid toplevel DIR handle!"); -+ -+ while ((TopDE = readdir(TopLD)) != NULL) { -+ if (TopDE->d_name[0] == '.') -+ continue; -+ -+ DName = reinterpret_cast(&TopDE->d_name[0]); -+ if (std::strcmp(DName, "lib") == 0) { -+ LibDir = StartingPath; -+ LibDir.append("/"); -+ LibDir.append(DName); -+ -+ if (!llvm::sys::fs::is_directory(LibDir.c_str())) -+ continue; -+ -+ LibLD = opendir(LibDir.c_str()); -+ assert(LibLD && "Could not obtain a valid lib DIR handle!"); -+ -+ while ((LibDE = readdir(LibLD)) != NULL) { -+ if (LibDE->d_name[0] == '.') -+ continue; -+ -+ DName = reinterpret_cast(&LibDE->d_name[0]); -+ if (std::strcmp(DName, "gcc") == 0) { -+ GccDir = LibDir; -+ GccDir.append("/"); -+ GccDir.append(DName); -+ -+ if (!llvm::sys::fs::is_directory(GccDir.c_str())) -+ continue; -+ -+ GccLD = opendir(GccDir.c_str()); -+ assert(GccLD && "Could not obtain a valid gcc DIR handle!"); -+ -+ while ((GccDE = readdir(GccLD)) != NULL) { -+ if (GccDE->d_name[0] == '.') -+ continue; -+ -+ DName = reinterpret_cast(&GccDE->d_name[0]); -+ TripleDir = GccDir; -+ TripleDir.append("/"); -+ TripleDir.append(DName); -+ -+ if (!llvm::sys::fs::is_directory(TripleDir.c_str())) -+ continue; -+ -+ if ((std::strncmp(DName, "sparc", 5) == 0) || -+ (std::strncmp(DName, "i386", 4) == 0) || -+ (std::strncmp(DName, "sparcv9", 7) == 0) || -+ (std::strncmp(DName, "x86_64", 6) == 0)) { -+ TripleLD = opendir(TripleDir.c_str()); -+ assert(TripleLD && -+ "Could not obtain a valid Triple DIR handle!"); -+ -+ while ((TripleDE = readdir(TripleLD)) != NULL) { -+ if (TripleDE->d_name[0] == '.') -+ continue; -+ -+ DName = reinterpret_cast(&TripleDE->d_name[0]); -+ TripleVersionDir = TripleDir; -+ TripleVersionDir.append("/"); -+ TripleVersionDir.append(DName); -+ -+ if (!llvm::sys::fs::is_directory(TripleVersionDir.c_str())) -+ continue; -+ -+ if ((std::isdigit(DName[0])) && (DName[1] == '.') && -+ (std::isdigit(DName[2])) && (DName[3] == '.') && -+ (std::isdigit(DName[4])) && (DName[5] == '\0')) { -+ GCCMajorMinorMicro = DName; -+ GCCMajorMinor = GCCMajorMinorMicro.substr(0, 3); -+ UseSpecifiedGCCToolChainPath = true; -+ goto done; -+ } -+ } -+ } -+ } -+ } -+ } -+ } -+ } -+ } -+ -+done: -+ if (TripleLD) { -+ rewinddir(TripleLD); -+ closedir(TripleLD); -+ } -+ -+ if (GccLD) { -+ rewinddir(GccLD); -+ closedir(GccLD); -+ } -+ -+ if (LibLD) { -+ rewinddir(LibLD); -+ closedir(LibLD); -+ } -+ -+ if (TopLD) { -+ rewinddir(TopLD); -+ closedir(TopLD); -+ } -+} -+ -+ -+ -+void Solaris::findGCCIncludeDirs(const llvm::Triple &Triple, -+ const llvm::opt::ArgList &Args) const { -+ std::string GCCInstallPath; -+ if (UseSpecifiedGCCToolChainPath) -+ GCCInstallPath = GCCInstallDir; -+ else if (UseMediatedGCCToolChainPath) -+ GCCInstallPath = Solaris::MediatedGCCToolChainPath; -+ else -+ GCCInstallPath = GCCInstallDir + GCCMajorMinor; -+ -+ std::string GCCIncludeDir = -+ GCCInstallPath + "/include/c++/" + GCCMajorMinorMicro; -+ GCCIncludeDirs.push_back(GCCIncludeDir); -+ -+ llvm::Triple::ArchType Arch = Triple.getArch(); -+ GCCIncludeDir += "/"; -+ -+ switch (Arch) { -+ case llvm::Triple::x86: -+ GCCIncludeDir += Triple.getTriple(); -+ if (Arg *A = Args.getLastArg(options::OPT_m64)) -+ GCCIncludeDir += "/amd64"; -+ break; -+ case llvm::Triple::sparc: -+ GCCIncludeDir += Triple.getTriple(); -+ if (Arg *A = Args.getLastArg(options::OPT_m64)) -+ GCCIncludeDir += "/sparcv9"; -+ break; -+ case llvm::Triple::x86_64: -+ GCCIncludeDir += "i386-pc-"; -+ GCCIncludeDir += Triple.getOSName(); -+ if (Arg *A = Args.getLastArg(options::OPT_m64)) -+ GCCIncludeDir += "/amd64"; -+ break; -+ case llvm::Triple::sparcv9: -+ GCCIncludeDir += "sparc-sun-"; -+ GCCIncludeDir += Triple.getOSName(); -+ if (Arg *A = Args.getLastArg(options::OPT_m64)) -+ GCCIncludeDir += "/sparcv9"; -+ break; -+ default: -+ getDriver().Diag(diag::err_target_unsupported_arch) -+ << Triple.getArchName() << Triple.getTriple(); -+ break; -+ } -+ -+ GCCIncludeDirs.push_back(GCCIncludeDir); -+ -+ GCCIncludeDir = GCCInstallPath + "/include/c++/" + -+ GCCMajorMinorMicro + "/backward"; -+ -+ GCCIncludeDirs.push_back(GCCIncludeDir); -+} -+ -+void Solaris::findGCCInternalLibDir(const llvm::Triple &Triple, -+ const llvm::opt::ArgList &Args) const { -+ std::string GCCInstallPath; -+ if (UseSpecifiedGCCToolChainPath) -+ GCCInstallPath = GCCInstallDir; -+ else if (UseMediatedGCCToolChainPath) -+ GCCInstallPath = Solaris::MediatedGCCToolChainPath; -+ else -+ GCCInstallPath = GCCInstallDir + GCCMajorMinor; -+ -+ GCCInternalLibDir = GCCInstallPath + "/lib/gcc/"; -+ -+ llvm::Triple::ArchType Arch = Triple.getArch(); -+ -+ switch (Arch) { -+ case llvm::Triple::x86: -+ GCCInternalLibDir += Triple.getTriple(); -+ GCCInternalLibDir += "/"; -+ GCCInternalLibDir += GCCMajorMinorMicro; -+ if (Arg *A = Args.getLastArg(options::OPT_m64)) { -+ GCCInternalMultiLibDir = GCCInternalLibDir; -+ GCCInternalLibDir += "/amd64"; -+ } else if (Arg *A = Args.getLastArg(options::OPT_m32)) { -+ GCCInternalMultiLibDir = GCCInternalLibDir; -+ GCCInternalMultiLibDir += "/amd64"; -+ } else { -+ GCCInternalMultiLibDir = GCCInternalLibDir; -+ GCCInternalMultiLibDir += "/amd64"; -+ } -+ -+ break; -+ case llvm::Triple::sparc: -+ GCCInternalLibDir += Triple.getTriple(); -+ GCCInternalLibDir += "/"; -+ GCCInternalLibDir += GCCMajorMinorMicro; -+ if (Arg *A = Args.getLastArg(options::OPT_m64)) { -+ GCCInternalMultiLibDir = GCCInternalLibDir; -+ GCCInternalLibDir += "/sparcv9"; -+ } else if (Arg *A = Args.getLastArg(options::OPT_m32)) { -+ GCCInternalMultiLibDir = GCCInternalLibDir; -+ GCCInternalMultiLibDir += "/sparcv9"; -+ } else { -+ GCCInternalMultiLibDir = GCCInternalLibDir; -+ GCCInternalMultiLibDir += "/sparcv9"; -+ } -+ break; -+ case llvm::Triple::x86_64: -+ GCCInternalLibDir += "i386-pc-"; -+ GCCInternalLibDir += Triple.getOSName(); -+ GCCInternalLibDir += "/"; -+ GCCInternalLibDir += GCCMajorMinorMicro; -+ GCCInternalMultiLibDir = GCCInternalLibDir; -+ if (Arg *A = Args.getLastArg(options::OPT_m64)) -+ GCCInternalLibDir += "/amd64"; -+ else if (Arg *A = Args.getLastArg(options::OPT_m32)) -+ GCCInternalMultiLibDir += "/amd64"; -+ else -+ GCCInternalLibDir += "/amd64"; -+ break; -+ case llvm::Triple::sparcv9: -+ GCCInternalLibDir += "sparc-sun-"; -+ GCCInternalLibDir += Triple.getOSName(); -+ GCCInternalLibDir += "/"; -+ GCCInternalLibDir += GCCMajorMinorMicro; -+ GCCInternalMultiLibDir = GCCInternalLibDir; -+ if (Arg *A = Args.getLastArg(options::OPT_m64)) -+ GCCInternalLibDir += "/sparcv9"; -+ else if (Arg *A = Args.getLastArg(options::OPT_m32)) -+ GCCInternalMultiLibDir += "/sparcv9"; -+ else -+ GCCInternalLibDir += "/sparcv9"; -+ break; -+ default: -+ getDriver().Diag(diag::err_target_unsupported_arch) -+ << Triple.getArchName() << Triple.getTriple(); -+ break; -+ } -+} -+ -+void Solaris::print(raw_ostream &OS) const { -+ OS << "UseGnuAs: " << (UseGnuAs ? "true" : "false") << "\n"; -+ OS << "UseGnuLd: " << (UseGnuLd ? "true" : "false") << "\n"; -+ OS << "UseGoldLd: " << (UseGoldLd ? "true" : "false") << "\n"; -+ OS << "UseSunLd: " << (UseSunLd ? "true" : "false") << "\n"; -+ OS << "UseMediatedGCCToolChainPath: " -+ << (UseMediatedGCCToolChainPath ? "true" : "false") << "\n"; -+ OS << "UseSpecifiedGCCToolChainPath: " -+ << (UseSpecifiedGCCToolChainPath ? "true" : "false") << "\n"; -+ OS << "GCCInstallDir: " << GCCInstallDir.c_str() << "\n"; -+ OS << "GCCMajorMinor: " << GCCMajorMinor.c_str() << "\n"; -+ OS << "GCCMajorMinorMicro: " << GCCMajorMinorMicro.c_str() << "\n"; -+ OS << "GCCInternalLibDir: " << GCCInternalLibDir.c_str() << "\n"; -+ OS << "GCCInternalMultiLibDir: " << GCCInternalMultiLibDir.c_str() << "\n"; -+ OS << "MediatedGCCToolChainPath: " << MediatedGCCToolChainPath << "\n"; -+ OS << "GCCIncludeDirs: "; -+ -+ if (GCCIncludeDirs.size()) { -+ std::string IncludePath; -+ for (std::vector::const_iterator B = GCCIncludeDirs.begin(), -+ E = GCCIncludeDirs.end(); B != E; ++B) { -+ IncludePath = "-I"; -+ IncludePath += (*B); -+ OS << IncludePath.c_str() << " "; -+ } -+ -+ OS << "\n"; -+ } -+ -+ OS << "Assembler: " << Assembler.c_str() << "\n"; -+ OS << "Linker: " << Linker.c_str() << "\n"; -+ OS << "mtune: " << mtune.c_str() << "\n"; -+ OS << "march: " << march.c_str() << "\n"; -+ OS << "mcpu: " << mcpu.c_str() << "\n"; -+ -+ if (ExtraOpts.size()) { -+ OS << "ExtraOpts: "; -+ for (std::vector::const_iterator B = ExtraOpts.begin(), -+ E = ExtraOpts.end(); B != E; ++B) { -+ OS << (*B).c_str() << " "; -+ } -+ -+ OS << "\n"; -+ } -+ -+ OS << "Valid: " << (IsValid ? "true" : "false") << "\n"; - } - - Tool *Solaris::buildAssembler() const { -@@ -2669,6 +3388,21 @@ - return new tools::solaris::Link(*this); - } - -+void Solaris::validate() { -+ IsValid = llvm::sys::fs::exists(GCCInstallDir.c_str()); -+ if (!IsValid) return; -+ IsValid = llvm::sys::fs::exists(GCCInternalLibDir.c_str()); -+ if (!IsValid) return; -+ IsValid = llvm::sys::fs::exists(GCCInternalMultiLibDir.c_str()); -+ if (!IsValid) return; -+ -+ for (std::vector::const_iterator B = GCCIncludeDirs.begin(), -+ E = GCCIncludeDirs.end(); B != E; ++B) { -+ IsValid = llvm::sys::fs::exists((*B).c_str()); -+ if (!IsValid) return; -+ } -+} -+ - /// Distribution (very bare-bones at the moment). - - enum Distro { -@@ -2696,6 +3430,27 @@ - UbuntuRaring, - UbuntuSaucy, - UbuntuTrusty, -+ Solaris_11, -+ Solaris_11_1, -+ Solaris_11_2, -+ Solaris_11_3, -+ Solaris_11_4, -+ Solaris_11_5, -+ Solaris_11_6, -+ Solaris_11_7, -+ Solaris_11_8, -+ Solaris_11_9, -+ Solaris_12, -+ Solaris_12_1, -+ Solaris_12_2, -+ Solaris_12_3, -+ Solaris_12_4, -+ Solaris_12_5, -+ Solaris_12_6, -+ Solaris_12_7, -+ Solaris_12_8, -+ Solaris_12_9, -+ Solaris_13, - UnknownDistro - }; - -@@ -2715,6 +3470,10 @@ - return Distro >= UbuntuHardy && Distro <= UbuntuTrusty; - } - -+static bool IsSolaris(enum Distro Distro) { -+ return Distro >= Solaris_11 && Distro <= Solaris_13; -+} -+ - static Distro DetectDistro(llvm::Triple::ArchType Arch) { - llvm::ErrorOr> File = - llvm::MemoryBuffer::getFile("/etc/lsb-release"); -@@ -2774,6 +3533,59 @@ - return UnknownDistro; - } - -+ File = llvm::MemoryBuffer::getFile("/etc/release"); -+ if (File) { -+ StringRef Data = File.get()->getBuffer(); -+ SmallVector Lines; -+ Data.split(Lines, "\n"); -+ for (unsigned I = 0, S = Lines.size(); I != S; ++I) { -+ if (Lines[I].find("Oracle Solaris") != std::string::npos) { -+ if (Lines[I].find("Solaris 11.0") != std::string::npos) -+ return Solaris_11; -+ else if (Lines[I].find("Solaris 11.1") != std::string::npos) -+ return Solaris_11_1; -+ else if (Lines[I].find("Solaris 11.2") != std::string::npos) -+ return Solaris_11_2; -+ else if (Lines[I].find("Solaris 11.3") != std::string::npos) -+ return Solaris_11_3; -+ else if (Lines[I].find("Solaris 11.4") != std::string::npos) -+ return Solaris_11_4; -+ else if (Lines[I].find("Solaris 11.5") != std::string::npos) -+ return Solaris_11_5; -+ else if (Lines[I].find("Solaris 11.6") != std::string::npos) -+ return Solaris_11_6; -+ else if (Lines[I].find("Solaris 11.7") != std::string::npos) -+ return Solaris_11_7; -+ else if (Lines[I].find("Solaris 11.8") != std::string::npos) -+ return Solaris_11_8; -+ else if (Lines[I].find("Solaris 11.9") != std::string::npos) -+ return Solaris_11_9; -+ else if (Lines[I].find("Solaris 12.0") != std::string::npos) -+ return Solaris_12; -+ else if (Lines[I].find("Solaris 12.1") != std::string::npos) -+ return Solaris_12_1; -+ else if (Lines[I].find("Solaris 12.2") != std::string::npos) -+ return Solaris_12_2; -+ else if (Lines[I].find("Solaris 12.3") != std::string::npos) -+ return Solaris_12_3; -+ else if (Lines[I].find("Solaris 12.4") != std::string::npos) -+ return Solaris_12_4; -+ else if (Lines[I].find("Solaris 12.5") != std::string::npos) -+ return Solaris_12_5; -+ else if (Lines[I].find("Solaris 12.6") != std::string::npos) -+ return Solaris_12_6; -+ else if (Lines[I].find("Solaris 12.7") != std::string::npos) -+ return Solaris_12_7; -+ else if (Lines[I].find("Solaris 12.8") != std::string::npos) -+ return Solaris_12_8; -+ else if (Lines[I].find("Solaris 12.9") != std::string::npos) -+ return Solaris_12_9; -+ } -+ } -+ -+ return UnknownDistro; -+ } -+ - if (llvm::sys::fs::exists("/etc/SuSE-release")) - return OpenSUSE; - ---- tools/llvm-shlib/Makefile Sat Jul 18 11:44:45 2015 -+++ tools/llvm-shlib/Makefile Thu Aug 20 23:40:28 2015 -@@ -74,6 +74,7 @@ - LLVMLibsOptions := -Wl,-z -Wl,rescan -Wl,-z -Wl,allextract $(LLVMLibsOptions) - LLVMLibsOptions += -Wl,-h -Wl,lib$(LIBRARYNAME)$(SHLIBEXT) - LLVMLibsOptions += -Wl,-z -Wl,defaultextract -Wl,-z -Wl,defs -+ LLVMLibsOptions += -lkstat - endif - - ifeq ($(HOST_OS), $(filter $(HOST_OS), Cygwin MingW)) ---- tools/clang/lib/Basic/Targets.cpp 2015-08-26 11:44:48.659904739 -0700 -+++ tools/clang/lib/Basic/Targets.cpp 2015-08-26 11:47:36.318310023 -0700 -@@ -530,28 +530,60 @@ - template - class SolarisTargetInfo : public OSTargetInfo { - protected: -- void getOSDefines(const LangOptions &Opts, const llvm::Triple &Triple, -+ virtual void getOSDefines(const LangOptions &Opts, const llvm::Triple &Triple, - MacroBuilder &Builder) const override { - DefineStd(Builder, "sun", Opts); - DefineStd(Builder, "unix", Opts); - Builder.defineMacro("__ELF__"); - Builder.defineMacro("__svr4__"); - Builder.defineMacro("__SVR4"); -- // Solaris headers require _XOPEN_SOURCE to be set to 600 for C99 and -- // newer, but to 500 for everything else. feature_test.h has a check to -- // ensure that you are not using C99 with an old version of X/Open or C89 -- // with a new version. -- if (Opts.C99) -+ -+ if (Opts.C99 || Opts.CPlusPlus11) { -+ if (Opts.C99) { - Builder.defineMacro("_XOPEN_SOURCE", "600"); -- else -+ Builder.defineMacro("_XPG6", "1"); -+ } -+ -+ Builder.defineMacro("__STDC_VERSION__", "199901L"); -+ Builder.defineMacro("_STDC_C99", "1"); -+ Builder.defineMacro("__C99FEATURES__", "1"); -+ } -+ -+ if (Opts.CPlusPlus11) -+ Builder.defineMacro("__cplusplus", "201103L"); -+ else if (Opts.CPlusPlus14) -+ Builder.defineMacro("__cplusplus", "201402L"); -+ -+ if (Opts.CPlusPlus11) { -+ Builder.defineMacro("_STDC_C11", "1"); -+ Builder.defineMacro("_STDC_C11_BCI", "1"); -+ Builder.defineMacro("__XPG7_THREAD_MODEL__", "1"); -+ Builder.defineMacro("_XPG7", "1"); -+ Builder.defineMacro("_XOPEN_SOURCE", "700"); -+ } else if (Opts.C11 || Opts.CPlusPlus14) { -+ Builder.defineMacro("__STDC_VERSION__", "201112L"); -+ Builder.defineMacro("_STDC_C11", "1"); -+ Builder.defineMacro("_STDC_C11_BCI", "1"); -+ Builder.defineMacro("__XPG7_THREAD_MODEL__", "1"); -+ Builder.defineMacro("_XPG7", "1"); -+ Builder.defineMacro("_XOPEN_SOURCE", "700"); -+ } else { - Builder.defineMacro("_XOPEN_SOURCE", "500"); -- if (Opts.CPlusPlus) -- Builder.defineMacro("__C99FEATURES__"); -+ Builder.defineMacro("__STDC_VERSION__", "199409L"); -+ if (Opts.CPlusPlus && !Opts.CPlusPlus11 && !Opts.CPlusPlus14) -+ Builder.defineMacro("__cplusplus", "199711L"); -+ } -+ -+ if ((Triple.getArchName() == "i386") || (Triple.getArchName() == "sparc")) - Builder.defineMacro("_LARGEFILE_SOURCE"); -+ else if ((Triple.getArchName() == "x86_64") || -+ (Triple.getArchName() == "sparcv9")) - Builder.defineMacro("_LARGEFILE64_SOURCE"); -- Builder.defineMacro("__EXTENSIONS__"); -+ -+ Builder.defineMacro("__EXTENSIONS__", "1"); - Builder.defineMacro("_REENTRANT"); - } -+ - public: - SolarisTargetInfo(const llvm::Triple &Triple) : OSTargetInfo(Triple) { - this->UserLabelPrefix = "";