# 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 <mach/machine.h>
#endif
+#if defined(sun) || defined(__sun) || defined(__sun__)
+#include <cstring>
+#include <kstat.h>
+#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_named_t*>(kstat_data_lookup(KSP, "brand"));
+ Value = (const char *) KNP->value.str.addr.ptr;
+ (void) std::sprintf(Buffer, "%s (", Value);
+
+ KNP =
+ reinterpret_cast<kstat_named_t*>(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_named_t*>(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<m_Group>, Flags<[CC1Option]>,
HelpText<"The thread model to use, e.g. posix, single (posix by default)">;
+def mvis : Flag<["-"], "mvis">, Group<m_Group>;
+def mvis2 : Flag<["-"], "mvis2">, Group<m_Group>;
+def mvis3 : Flag<["-"], "mvis3">, Group<m_Group>;
+def mimpure_text: Flag<["-"], "mimpure-text">, Group<m_Group>;
+
def mmmx : Flag<["-"], "mmmx">, Group<m_x86_Features_Group>;
def mno_3dnowa : Flag<["-"], "mno-3dnowa">, Group<m_x86_Features_Group>;
def mno_3dnow : Flag<["-"], "mno-3dnow">, Group<m_x86_Features_Group>;
@@ -1690,6 +1695,7 @@
defm profile_use : BooleanFFlag<"profile-use">, Group<clang_ignored_gcc_optimization_f_Group>;
def fprofile_use_EQ : Joined<["-"], "fprofile-use=">, Group<clang_ignored_gcc_optimization_f_Group>;
def fuse_ld_EQ : Joined<["-"], "fuse-ld=">, Group<f_Group>;
+def fuse_as_EQ : Joined<["-"], "fuse-as=">, Group<f_Group>;
defm align_functions : BooleanFFlag<"align-functions">, Group<clang_ignored_gcc_optimization_f_Group>;
def falign_functions_EQ : Joined<["-"], "falign-functions=">, Group<clang_ignored_gcc_optimization_f_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<PATH_MAX> 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<PATH_MAX> 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<PATH_MAX> 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<const char *> &Features) {
- bool SoftFloatABI = true;
+ std::vector<const char *> &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<Command>(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<const toolchains::Solaris&>(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) << "<unspecified>";
+ 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<Command>(JA, *this, Exec, CmdArgs));
+ C.addCommand(llvm::make_unique<Command>(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<const toolchains::Solaris&>(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<std::string> &ExtraOpts = TC.getExtraOpts();
+
+ // Handle extra options
+ if (ExtraOpts.size()) {
+ for (std::vector<std::string>::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<std::string> zoptions = Args.getAllArgValues(options::OPT_z);
+ std::string zoption;
+ for (std::vector<std::string>::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<Command>(JA, *this, Exec, CmdArgs));
+ C.addCommand(llvm::make_unique<Command>(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<std::string> &getGCCIncludeDirs() const {
+ return GCCIncludeDirs;
+ }
+
+ const std::vector<std::string> &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<std::string> GCCIncludeDirs;
+
+ mutable std::string Assembler;
+ mutable std::string Linker;
+ mutable std::string mtune;
+ mutable std::string march;
+ mutable std::string mcpu;
+ mutable std::vector<std::string> 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 <cstdlib> // ::getenv
#include <system_error>
@@ -38,6 +40,19 @@
using namespace clang;
using namespace llvm::opt;
+#if defined(LLVM_ON_UNIX)
+#include <cstring>
+#include <cctype>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <dirent.h>
+#include <unistd.h>
+#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<std::string>::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<PATH_MAX> 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<StringRef, 5> dirs;
+ CIncludeDirs.split(dirs, ":");
+ for (SmallVectorImpl<StringRef>::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<const char*>(&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<const char*>(&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<const char*>(&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<const char*>(&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<std::string>::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<std::string>::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<std::string>::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<std::unique_ptr<llvm::MemoryBuffer>> 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<StringRef, 8> 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<typename Target>
class SolarisTargetInfo : public OSTargetInfo<Target> {
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<Target>(Triple) {
this->UserLabelPrefix = "";