# 23701635 clang produces amd64 opcodes, but calls 32-bit assembler by default
# 23854357 clang should check for GNU ld
# 22778650 clang should support OpenMP because it can
# 24314745 clang should support PIE executables in Solaris
# 24378340 clang -fopenmp must include the path to the omp.h header file
# 24378393 clang -fopenmp must define _OPENMP to 201307
# 3.9.X for upstream.
--- tools/clang/include/clang/Driver/Options.td 2016-01-06 13:27:42.000000000 -0800
+++ tools/clang/include/clang/Driver/Options.td 2016-07-30 10:18:25.039779680 -0700
@@ -669,6 +669,9 @@
Flags<[CC1Option]>, HelpText<"Form fused FP ops (e.g. FMAs): fast (everywhere)"
" | on (according to FP_CONTRACT pragma, default) | off (never fuse)">;
+def fabi_version_EQ : Joined<["-"], "fabi-version=">, Group<f_Group>,
+ Flags<[CC1Option]>, HelpText<"Use specified GNU C++ ABI version">;
+
def ffor_scope : Flag<["-"], "ffor-scope">, Group<f_Group>;
def fno_for_scope : Flag<["-"], "fno-for-scope">, Group<f_Group>;
@@ -959,11 +962,17 @@
def fobjc_sender_dependent_dispatch : Flag<["-"], "fobjc-sender-dependent-dispatch">, Group<f_Group>;
def fomit_frame_pointer : Flag<["-"], "fomit-frame-pointer">, Group<f_Group>;
-def fopenmp : Flag<["-"], "fopenmp">, Group<f_Group>, Flags<[CC1Option, NoArgumentUnused]>;
-def fno_openmp : Flag<["-"], "fno-openmp">, Group<f_Group>, Flags<[NoArgumentUnused]>;
-def fopenmp_EQ : Joined<["-"], "fopenmp=">, Group<f_Group>;
-def fopenmp_use_tls : Flag<["-"], "fopenmp-use-tls">, Group<f_Group>, Flags<[NoArgumentUnused]>;
-def fnoopenmp_use_tls : Flag<["-"], "fnoopenmp-use-tls">, Group<f_Group>, Flags<[CC1Option, NoArgumentUnused]>;
+def fopenmp : Flag<["-"], "fopenmp">, Group<f_Group>,
+ Flags<[CC1Option]>, HelpText<"Enable OpenMP">;
+def fno_openmp : Flag<["-"], "fno-openmp">, Group<f_Group>,
+ Flags<[CC1Option]>, HelpText<"Disable OpenMP">;
+def fopenmp_EQ : Joined<["-"], "fopenmp=">, Group<f_Group>,
+ Flags<[CC1Option]>,
+ HelpText<"Use specified OpenMP Implementation">;
+def fopenmp_use_tls : Flag<["-"], "fopenmp-use-tls">, Group<f_Group>,
+ Flags<[CC1Option]>, HelpText<"Use OpenMP TLS">;
+def fnoopenmp_use_tls : Flag<["-"], "fnoopenmp-use-tls">, Group<f_Group>,
+ Flags<[CC1Option]>, HelpText<"Do not use OpenMP TLS">;
def fno_optimize_sibling_calls : Flag<["-"], "fno-optimize-sibling-calls">, Group<f_Group>;
def foptimize_sibling_calls : Flag<["-"], "foptimize-sibling-calls">, Group<f_Group>;
def force__cpusubtype__ALL : Flag<["-"], "force_cpusubtype_ALL">;
@@ -1312,6 +1321,12 @@
def meabi : Separate<["-"], "meabi">, Group<m_Group>, Flags<[CC1Option]>,
HelpText<"Set EABI type, e.g. 4, 5 or gnu (default depends on triple)">;
+// SPARC-only options.
+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>;
@@ -1954,6 +1969,7 @@
def fprofile_dir : Joined<["-"], "fprofile-dir=">, Group<clang_ignored_gcc_optimization_f_Group>;
+def fuse_as_EQ : Joined<["-"], "fuse-as=">, Group<f_Group>;
def fuse_ld_EQ : Joined<["-"], "fuse-ld=">, Group<f_Group>;
defm align_functions : BooleanFFlag<"align-functions">, Group<clang_ignored_gcc_optimization_f_Group>;
###
--- tools/clang/lib/Driver/Multilib.cpp 2015-10-12 10:32:57.000000000 -0400
+++ tools/clang/lib/Driver/Multilib.cpp 2016-05-08 23:19:20.569431652 -0400
@@ -171,11 +171,11 @@
}
static Multilib compose(const Multilib &Base, const Multilib &New) {
- SmallString<128> GCCSuffix;
+ SmallString<PATH_MAX> GCCSuffix;
llvm::sys::path::append(GCCSuffix, "/", Base.gccSuffix(), New.gccSuffix());
- SmallString<128> OSSuffix;
+ SmallString<PATH_MAX> OSSuffix;
llvm::sys::path::append(OSSuffix, "/", Base.osSuffix(), New.osSuffix());
- SmallString<128> IncludeSuffix;
+ SmallString<PATH_MAX> IncludeSuffix;
llvm::sys::path::append(IncludeSuffix, "/", Base.includeSuffix(),
New.includeSuffix());
###
--- tools/clang/lib/Driver/ToolChains.cpp 2016-02-16 11:56:48.000000000 -0800
+++ tools/clang/lib/Driver/ToolChains.cpp 2016-08-04 06:09:44.734198665 -0700
@@ -28,12 +28,15 @@
#include "llvm/ProfileData/InstrProf.h"
#include "llvm/Support/ErrorHandling.h"
#include "llvm/Support/FileSystem.h"
+#include "llvm/Support/Host.h"
#include "llvm/Support/MemoryBuffer.h"
#include "llvm/Support/Path.h"
#include "llvm/Support/Program.h"
#include "llvm/Support/TargetParser.h"
#include "llvm/Support/raw_ostream.h"
#include <cstdlib> // ::getenv
+#include <cstring>
+#include <cctype>
#include <system_error>
using namespace clang::driver;
@@ -41,6 +44,15 @@
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
+
MachO::MachO(const Driver &D, const llvm::Triple &Triple, const ArgList &Args)
: ToolChain(D, Triple, Args) {
// We expect 'as', 'ld', etc. to be adjacent to our install dir.
@@ -1347,6 +1359,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");
}
@@ -1434,14 +1451,17 @@
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-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[] = {
@@ -1449,7 +1469,8 @@
"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"};
+ "i586-linux-gnu", "i386-pc-solaris2.11", "i386-pc-solaris2.12",
+ "i386-pc-solaris2.13" };
static const char *const MIPSLibDirs[] = {"/lib"};
static const char *const MIPSTriples[] = {"mips-linux-gnu", "mips-mti-linux",
@@ -1483,30 +1504,28 @@
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[] = {
"s390x-linux-gnu", "s390x-unknown-linux-gnu", "s390x-ibm-linux-gnu",
"s390x-suse-linux", "s390x-redhat-linux"};
- // Solaris.
- static const char *const SolarisSPARCLibDirs[] = {"/gcc"};
- static const char *const SolarisSPARCTriples[] = {"sparc-sun-solaris2.11",
- "i386-pc-solaris2.11"};
-
using std::begin;
using std::end;
- if (TargetTriple.getOS() == llvm::Triple::Solaris) {
- LibDirs.append(begin(SolarisSPARCLibDirs), end(SolarisSPARCLibDirs));
- TripleAliases.append(begin(SolarisSPARCTriples), end(SolarisSPARCTriples));
- return;
- }
-
switch (TargetTriple.getArch()) {
case llvm::Triple::aarch64:
LibDirs.append(begin(AArch64LibDirs), end(AArch64LibDirs));
@@ -3302,69 +3321,828 @@
}
/// Solaris - Solaris tool chain which can call as(1) and ld(1) directly.
+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);
+
+ if (!UseSpecifiedGCCToolChainPath) {
+ D.Diag(diag::err_drv_unsupported_rtlib_for_platform)
+ << GCCInstallDir << Triple.getTriple();
+ } else {
+ findGCCIncludeDirs(Triple, Args);
+ findGCCInternalLibDir(Triple, Args);
+ }
+ }
+ } 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;
+ }
+ }
- GCCInstallation.init(Triple, Args);
+ 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);
+ }
- path_list &Paths = getFilePaths();
- if (GCCInstallation.isValid())
- addPathIfExists(D, GCCInstallation.getInstallPath(), Paths);
+ getProgramPaths().push_back(GCCInstallDir);
- addPathIfExists(D, getDriver().getInstalledDir(), Paths);
if (getDriver().getInstalledDir() != getDriver().Dir)
- addPathIfExists(D, getDriver().Dir, Paths);
+ getProgramPaths().push_back(getDriver().Dir);
- addPathIfExists(D, getDriver().SysRoot + getDriver().Dir + "/../lib", Paths);
+ llvm::Triple::ArchType Arch = Triple.getArch();
- std::string LibPath = "/usr/lib/";
- switch (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:
- LibPath += "amd64/";
+ getFilePaths().push_back(getDriver().Dir + "/../lib/amd64");
+ getFilePaths().push_back("/usr/lib/amd64");
+ march = mtune = "opteron";
break;
case llvm::Triple::sparcv9:
- LibPath += "sparcv9/";
+ getFilePaths().push_back(getDriver().Dir + "/../lib/sparcv9");
+ getFilePaths().push_back("/usr/lib/sparcv9");
+ mcpu = "ultrasparc";
+ mtune = "ultrasparc";
+ march = "v9a";
break;
default:
- llvm_unreachable("Unsupported architecture");
+ getFilePaths().push_back(getDriver().Dir + "/../lib");
+ getFilePaths().push_back("/usr/lib");
+ break;
}
- addPathIfExists(D, getDriver().SysRoot + LibPath, Paths);
+ validate();
+
+ if (Args.hasArg(options::OPT_v))
+ this->print(llvm::errs());
}
-Tool *Solaris::buildAssembler() const {
- return new tools::solaris::Assembler(*this);
+std::string Solaris::computeSysRoot() const {
+ if (!getDriver().SysRoot.empty())
+ return getDriver().SysRoot;
+
+ return std::string("/");
}
-Tool *Solaris::buildLinker() const { return new tools::solaris::Linker(*this); }
+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);
-void Solaris::AddClangCXXStdlibIncludeArgs(const ArgList &DriverArgs,
- ArgStringList &CC1Args) const {
+ 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);
+ }
+
+ if (DriverArgs.hasArg(options::OPT_fopenmp) ||
+ DriverArgs.hasArg(options::OPT_fopenmp_EQ)) {
+ addSystemInclude(DriverArgs, CC1Args, "/usr/include/iomp5");
+ }
+
+ 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;
- // Include the support directory for things like xlocale and fudged system
- // headers.
- addSystemInclude(DriverArgs, CC1Args, "/usr/include/c++/v1/support/solaris");
+ const Driver &D = getDriver();
- if (GCCInstallation.isValid()) {
- GCCVersion Version = GCCInstallation.getVersion();
- addSystemInclude(DriverArgs, CC1Args,
- getDriver().SysRoot + "/usr/gcc/" +
- Version.MajorStr + "." +
- Version.MinorStr +
- "/include/c++/" + Version.Text);
- addSystemInclude(DriverArgs, CC1Args,
- getDriver().SysRoot + "/usr/gcc/" + Version.MajorStr +
- "." + Version.MinorStr + "/include/c++/" +
- Version.Text + "/" +
- GCCInstallation.getTriple().str());
+ // 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);
+ }
+ }
+
+ if (DriverArgs.hasArg(options::OPT_fopenmp) ||
+ DriverArgs.hasArg(options::OPT_fopenmp_EQ))
+ addSystemInclude(DriverArgs, CC1Args, "/usr/include/iomp5");
+
+ 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_fuse_init_array))
+ DriverArgs.ClaimAllArgs(options::OPT_fuse_init_array);
+
+ // Always use .init_array/.fini_array on Solaris. The Solaris
+ // linker can't do .ctors/.dtors or .init/.fini for that matter.
+ CC1Args.push_back("-fuse-init-array");
+
+ if (Arg *A = DriverArgs.getLastArg(options::OPT_fabi_version_EQ)) {
+ StringRef V = A->getValue();
+ if (!V.empty()) {
+ std::string fabi_version = "-fabi-version=";
+ fabi_version += V.str();
+ CC1Args.push_back(DriverArgs.MakeArgString(fabi_version.c_str()));
+ } else {
+ std::string fabi_version = "-fabi-version=4";
+ CC1Args.push_back(DriverArgs.MakeArgString(fabi_version.c_str()));
+ }
+ } else {
+ CC1Args.push_back(DriverArgs.MakeArgString("-fabi-version=4"));
+ }
+
+ DriverArgs.ClaimAllArgs(options::OPT_fabi_version_EQ);
+
+ if (Arg *A = DriverArgs.getLastArg(options::OPT_fopenmp))
+ CC1Args.push_back(DriverArgs.MakeArgString("-fopenmp"));
+
+ if (Arg *A = DriverArgs.getLastArg(options::OPT_fno_openmp))
+ CC1Args.push_back(DriverArgs.MakeArgString("-fno-openmp"));
+
+ if (Arg *A = DriverArgs.getLastArg(options::OPT_fopenmp_EQ)) {
+ std::string V = A->getValue();
+ if (V != "libiomp5") {
+ const Driver &D = getDriver();
+ D.Diag(diag::err_drv_unsupported_opt) << V.c_str();
+ }
+
+ std::string fompeq="-fopenmp=";
+ fompeq += V;
+ CC1Args.push_back(DriverArgs.MakeArgString(fompeq.c_str()));
+ }
+
+ if (Arg *A = DriverArgs.getLastArg(options::OPT_fopenmp_use_tls))
+ CC1Args.push_back(DriverArgs.MakeArgString("-fopenmp-use-tls"));
+
+ if (Arg *A = DriverArgs.getLastArg(options::OPT_fnoopenmp_use_tls))
+ CC1Args.push_back(DriverArgs.MakeArgString("-fnoopenmp-use-tls"));
+
+ if (Arg *A = DriverArgs.getLastArg(options::OPT_fopenmp_is_device)) {
+ CC1Args.push_back(DriverArgs.MakeArgString("-fopenmp-is-device"));
+ }
+
+ if (Arch == llvm::Triple::sparc || Arch == llvm::Triple::sparcv9) {
+ CC1Args.push_back(DriverArgs.MakeArgString("-target-feature"));
+ CC1Args.push_back(DriverArgs.MakeArgString("+hwcap"));
+ }
+
+ if (Arch == llvm::Triple::x86 || Arch == llvm::Triple::x86_64) {
+ if (Arg *A = DriverArgs.getLastArg(options::OPT_fomit_frame_pointer))
+ CC1Args.push_back(DriverArgs.MakeArgString("-fomit-frame-pointer"));
+
+ if (Arg *A = DriverArgs.getLastArg(options::OPT_fno_omit_frame_pointer))
+ CC1Args.push_back(DriverArgs.MakeArgString("-fno-omit-frame-pointer"));
+ }
+
+ bool SeenVIS = false;
+ bool SeenVIS2 = false;
+ bool SeenVIS3 = false;
+
+ bool DoneVIS = false;
+ bool DoneVIS2 = false;
+ bool DoneVIS3 = false;
+
+ bool DoneMTune = false;
+
+ if (Arg *A = DriverArgs.getLastArg(options::OPT_mtune_EQ)) {
+ StringRef V = A->getValue();
+ if (!V.empty())
+ mtune = V.str();
+ else
+ mtune = "ultrasparc";
+
+ if (Arch == llvm::Triple::sparc || Arch == llvm::Triple::sparcv9) {
+ if ((mtune == "ultrasparc") || (mtune == "ultrasparc2") ||
+ (mtune == "vis")) {
+ SeenVIS = true;
+ } else if ((mtune == "ultrasparc3") || (mtune == "vis2")) {
+ SeenVIS = true;
+ SeenVIS2 = true;
+ } else {
+ SeenVIS = true;
+ SeenVIS2 = true;
+ SeenVIS3 = true;
+ }
+
+ if (!DoneMTune) {
+ if (SeenVIS3 && !DoneVIS3) {
+ CC1Args.push_back(DriverArgs.MakeArgString("-target-feature"));
+ CC1Args.push_back(DriverArgs.MakeArgString("+vis3"));
+ DoneVIS3 = true;
+ DoneVIS2 = true;
+ DoneVIS = true;
+ }
+
+ if (SeenVIS2 && !DoneVIS2) {
+ CC1Args.push_back(DriverArgs.MakeArgString("-target-feature"));
+ CC1Args.push_back(DriverArgs.MakeArgString("+vis2"));
+ DoneVIS2 = true;
+ DoneVIS = true;
+ }
+
+ if (SeenVIS && !DoneVIS) {
+ CC1Args.push_back(DriverArgs.MakeArgString("-target-feature"));
+ CC1Args.push_back(DriverArgs.MakeArgString("+vis"));
+ DoneVIS = true;
+ }
+
+ DoneMTune = true;
+ }
+ }
+ }
+
+ if (Arch == llvm::Triple::sparc || Arch == llvm::Triple::sparcv9) {
+ if (Arg *A = DriverArgs.getLastArg(options::OPT_mvis)) {
+ SeenVIS = !DoneVIS;
+ if (!DoneVIS) {
+ CC1Args.push_back(DriverArgs.MakeArgString("-target-feature"));
+ CC1Args.push_back(DriverArgs.MakeArgString("+vis"));
+ DoneVIS = true;
+ }
+ }
+
+ if (Arg *A = DriverArgs.getLastArg(options::OPT_mvis2)) {
+ SeenVIS2 = !DoneVIS2;
+ if (!DoneVIS2) {
+ CC1Args.push_back(DriverArgs.MakeArgString("-target-feature"));
+ CC1Args.push_back(DriverArgs.MakeArgString("+vis2"));
+ DoneVIS2 = true;
+ DoneVIS = true;
+ }
+ }
+
+ if (Arg *A = DriverArgs.getLastArg(options::OPT_mvis3)) {
+ SeenVIS3 = !DoneVIS3;
+ if (!DoneVIS3) {
+ CC1Args.push_back(DriverArgs.MakeArgString("-target-feature"));
+ CC1Args.push_back(DriverArgs.MakeArgString("+vis3"));
+ DoneVIS3 = true;
+ DoneVIS2 = true;
+ DoneVIS = true;
+ }
+ }
+ }
+}
+
+void
+Solaris::findGCCMajorMinor() const {
+ // FIXME: Add 5.X after testing the ABI.
+ static const char* const GCCMM[] = { "4.8", "4.9" };
+
+ const char* P;
+ std::string Path;
+
+ 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.X after testing the ABI.
+ static const char* const GCCMMM[] = { "4.8.2", "4.9.3", "4.9.4" };
+
+ const char* P;
+ std::string Path;
+ std::string TripleString = llvm::sys::getDefaultTargetTriple();
+ llvm::Triple::ArchType Arch = T.getArch();
+
+ // GCC4 on Solaris is multilib 32/64.
+ // GCC5 (not supported here yet) on Solaris is multilib 64/32.
+ if (GCCMajorMinor[0] == '4') {
+ if (TripleString.find("x86_64") != std::string::npos)
+ TripleString.replace(0U, 6U, std::string("i386"));
+ else if (TripleString.find("sparcv9") != std::string::npos)
+ TripleString.replace(0U, 7U, std::string("sparc"));
+ }
+
+ 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 = static_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 = static_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 = static_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 = static_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
+ 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
+ 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 << "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 {
+ return new tools::solaris::Assembler(*this);
+}
+
+Tool *Solaris::buildLinker() const {
+ return new tools::solaris::Linker(*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;
}
}
@@ -3404,6 +4182,27 @@
UbuntuVivid,
UbuntuWily,
UbuntuXenial,
+ 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
};
@@ -3421,6 +4220,10 @@
return Distro >= UbuntuHardy && Distro <= UbuntuXenial;
}
+static bool IsSolaris(enum Distro Distro) {
+ return Distro >= Solaris_11 && Distro <= Solaris_13;
+}
+
static Distro DetectDistro(const Driver &D, llvm::Triple::ArchType Arch) {
llvm::ErrorOr<std::unique_ptr<llvm::MemoryBuffer>> File =
llvm::MemoryBuffer::getFile("/etc/lsb-release");
@@ -3488,6 +4291,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 (D.getVFS().exists("/etc/SuSE-release"))
return OpenSUSE;
###
--- tools/clang/lib/Driver/ToolChains.h 2016-02-16 14:56:48.000000000 -0500
+++ tools/clang/lib/Driver/ToolChains.h 2016-05-08 23:19:20.571431701 -0400
@@ -615,24 +615,111 @@
Tool *buildLinker() 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; }
- void AddClangCXXStdlibIncludeArgs(
- const llvm::opt::ArgList &DriverArgs,
- llvm::opt::ArgStringList &CC1Args) const override;
+ std::string computeSysRoot() const;
- unsigned GetDefaultDwarfVersion() const override { return 2; }
+ 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;
+
+ unsigned GetDefaultDwarfVersion() const override { return 4; }
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 bool SupportsClangLibCPlusPlus;
};
+
class LLVM_LIBRARY_VISIBILITY MinGW : public ToolChain {
public:
MinGW(const Driver &D, const llvm::Triple &Triple,
###
--- tools/clang/lib/Driver/Tools.cpp 2016-02-12 14:51:41.000000000 -0800
+++ tools/clang/lib/Driver/Tools.cpp 2016-08-04 06:17:07.826616905 -0700
@@ -43,15 +43,22 @@
#include "llvm/Support/raw_ostream.h"
#include "llvm/Support/TargetParser.h"
-#ifdef LLVM_ON_UNIX
-#include <unistd.h> // For getuid().
-#endif
-
using namespace clang::driver;
using namespace clang::driver::tools;
using namespace clang;
using namespace llvm::opt;
+#ifdef LLVM_ON_UNIX
+#include <unistd.h> // For getuid().
+#endif
+
+#include <cstdlib>
+#include <climits>
+
+static std::tuple<llvm::Reloc::Model, unsigned, bool>
+ParsePICArgs(const ToolChain &ToolChain, const llvm::Triple &Triple,
+ const ArgList &Args);
+
static void handleTargetFeaturesGroup(const ArgList &Args,
std::vector<const char *> &Features,
OptSpecifier Group) {
@@ -74,11 +81,15 @@
const llvm::Triple &Triple) {
if (Triple.getArch() == llvm::Triple::sparcv9) {
return llvm::StringSwitch<const char *>(Name)
+ .Case("v9", "-Av9")
+ .Case("ultrasparc", "-Av9a")
+ .Case("ultrasparc2", "-Av9a")
+ .Case("ultrasparc3", "-Av9b")
.Case("niagara", "-Av9b")
.Case("niagara2", "-Av9b")
.Case("niagara3", "-Av9d")
.Case("niagara4", "-Av9d")
- .Default("-Av9");
+ .Default("-Av9a");
} else {
return llvm::StringSwitch<const char *>(Name)
.Case("v8", "-Av8")
@@ -89,17 +100,23 @@
.Case("sparclite86x", "-Asparclite")
.Case("sparclet", "-Asparclet")
.Case("tsc701", "-Asparclet")
- .Case("v9", "-Av8plus")
- .Case("ultrasparc", "-Av8plus")
- .Case("ultrasparc3", "-Av8plus")
+ .Case("ultrasparc", "-Av8plusa")
+ .Case("ultrasparc2", "-Av8plusa")
+ .Case("ultrasparc3", "-Av8plusb")
.Case("niagara", "-Av8plusb")
.Case("niagara2", "-Av8plusb")
.Case("niagara3", "-Av8plusd")
.Case("niagara4", "-Av8plusd")
- .Default("-Av8");
+ .Default("-Av8plusa");
}
}
+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) {
@@ -266,6 +283,27 @@
addDirectoryList(Args, CmdArgs, "-L", "LIBRARY_PATH");
}
+static void AddAssemblerKPIC(const ToolChain &ToolChain, const ArgList &Args,
+ ArgStringList &CmdArgs) {
+ llvm::Reloc::Model RelocationModel;
+ unsigned PICLevel = 1;
+ bool IsPIE = false;
+
+ std::tie(RelocationModel, PICLevel, IsPIE) =
+ ParsePICArgs(ToolChain, ToolChain.getTriple(), Args);
+
+ if (ToolChain.getTriple().getOS() == llvm::Triple::Solaris) {
+ if ((RelocationModel != llvm::Reloc::Static) &&
+ (RelocationModel != llvm::Reloc::DynamicNoPIC))
+ CmdArgs.push_back("-KPIC");
+
+ return;
+ }
+
+ if (RelocationModel != llvm::Reloc::Static)
+ CmdArgs.push_back("-KPIC");
+}
+
/// \brief Determine whether Objective-C automated reference counting is
/// enabled.
static bool isObjCAutoRefCount(const ArgList &Args) {
@@ -1601,8 +1639,127 @@
}
}
-static const char *getX86TargetCPU(const ArgList &Args,
- const llvm::Triple &Triple) {
+const char *sparc::getSparcTargetCPU(const llvm::opt::ArgList &Args,
+ const llvm::Triple &Triple) {
+ if (const Arg *A = Args.getLastArg(options::OPT_march_EQ)) {
+ StringRef AV = A->getValue();
+ if (AV == "native") {
+ std::string CPU = llvm::sys::getHostCPUName().str();
+ if (CPU.find("UltraSPARC-IV") != std::string::npos)
+ return Triple.getArch() == llvm::Triple::sparcv9 ? "v9c" : "v8plusc";
+ else if (CPU.find("UltraSPARC-III") != std::string::npos)
+ return Triple.getArch() == llvm::Triple::sparcv9 ? "v9b" : "v8plusb";
+ else if (CPU.find("UltraSPARC-II") != std::string::npos)
+ return Triple.getArch() == llvm::Triple::sparcv9 ? "v9a" : "v8plusa";
+ else if (CPU.find("UltraSPARC-I") != std::string::npos)
+ return Triple.getArch() == llvm::Triple::sparcv9 ? "v9" : "v8plus";
+ else if (CPU.find("SPARC-T4") != std::string::npos)
+ return Triple.getArch() == llvm::Triple::sparcv9 ? "v9v" : "v8plusv";
+ else if (CPU.find("SPARC-T5") != std::string::npos)
+ return Triple.getArch() == llvm::Triple::sparcv9 ? "v9v" : "v8plusv";
+ else if (CPU.find("SPARC-T6") != std::string::npos)
+ return Triple.getArch() == llvm::Triple::sparcv9 ? "v9v" : "v8plusv";
+ else if (CPU.find("SPARC-T7") != std::string::npos)
+ return Triple.getArch() == llvm::Triple::sparcv9 ? "v9v" : "v8plusv";
+ else if (CPU.find("SPARC-M4") != std::string::npos)
+ return Triple.getArch() == llvm::Triple::sparcv9 ? "v9v" : "v8plusv";
+ else if (CPU.find("SPARC-M5") != std::string::npos)
+ return Triple.getArch() == llvm::Triple::sparcv9 ? "v9m" : "v8plusm";
+ else if (CPU.find("SPARC-M6") != std::string::npos)
+ return Triple.getArch() == llvm::Triple::sparcv9 ? "v9m" : "v8plusm";
+ else if (CPU.find("SPARC-M7") != std::string::npos)
+ return Triple.getArch() == llvm::Triple::sparcv9 ? "v9m" : "v8plusm";
+ } else if (AV == "ultrasparc") {
+ return Triple.getArch() == llvm::Triple::sparcv9 ? "v9a" : "v8plusa";
+ } else if (AV == "ultrasparc2") {
+ return Triple.getArch() == llvm::Triple::sparcv9 ? "v9a" : "v8plusa";
+ } else if (AV == "ultrasparc3") {
+ return Triple.getArch() == llvm::Triple::sparcv9 ? "v9b" : "v8plusb";
+ } else if (AV == "ultrasparc4") {
+ return Triple.getArch() == llvm::Triple::sparcv9 ? "v9c" : "v8plusc";
+ } else if (AV == "niagara") {
+ return Triple.getArch() == llvm::Triple::sparcv9 ? "v9b" : "v8plusb";
+ } else if (AV == "niagara2") {
+ return Triple.getArch() == llvm::Triple::sparcv9 ? "v9b" : "v8plusb";
+ } else if (AV == "niagara3") {
+ return Triple.getArch() == llvm::Triple::sparcv9 ? "v9b" : "v8plusb";
+ } else if (AV == "niagara4") {
+ return Triple.getArch() == llvm::Triple::sparcv9 ? "v9b" : "v8plusb";
+ } else if (AV == "sparc4") {
+ return "sparc4";
+ } else if (AV == "sparc5") {
+ return "sparc5";
+ } else if (AV == "generic") {
+ return Triple.getArch() == llvm::Triple::sparcv9 ? "v9a" : "v8plusa";
+ } else if (AV == "generic32") {
+ return "v8plusa";
+ } else if (AV == "generic64") {
+ return "v9a";
+ }
+ }
+
+ if (const Arg *A = Args.getLastArg(options::OPT_mcpu_EQ)) {
+ StringRef AV = A->getValue();
+ if (AV == "native") {
+ std::string CPU = llvm::sys::getHostCPUName().str();
+ if (CPU.find("UltraSPARC-IV") != std::string::npos)
+ return Triple.getArch() == llvm::Triple::sparcv9 ? "v9c" : "v8plusc";
+ else if (CPU.find("UltraSPARC-III") != std::string::npos)
+ return Triple.getArch() == llvm::Triple::sparcv9 ? "v9b" : "v8plusb";
+ else if (CPU.find("UltraSPARC-II") != std::string::npos)
+ return Triple.getArch() == llvm::Triple::sparcv9 ? "v9a" : "v8plusa";
+ else if (CPU.find("UltraSPARC-I") != std::string::npos)
+ return Triple.getArch() == llvm::Triple::sparcv9 ? "v9" : "v8plus";
+ else if (CPU.find("SPARC-T4") != std::string::npos)
+ return Triple.getArch() == llvm::Triple::sparcv9 ? "v9v" : "v8plusv";
+ else if (CPU.find("SPARC-T5") != std::string::npos)
+ return Triple.getArch() == llvm::Triple::sparcv9 ? "v9m" : "v8plusm";
+ else if (CPU.find("SPARC-T6") != std::string::npos)
+ return Triple.getArch() == llvm::Triple::sparcv9 ? "v9m" : "v8plusm";
+ else if (CPU.find("SPARC-T7") != std::string::npos)
+ return Triple.getArch() == llvm::Triple::sparcv9 ? "v9m" : "v8plusm";
+ else if (CPU.find("SPARC-M4") != std::string::npos)
+ return Triple.getArch() == llvm::Triple::sparcv9 ? "v9v" : "v8plusv";
+ else if (CPU.find("SPARC-M5") != std::string::npos)
+ return Triple.getArch() == llvm::Triple::sparcv9 ? "v9m" : "v8plusm";
+ else if (CPU.find("SPARC-M6") != std::string::npos)
+ return Triple.getArch() == llvm::Triple::sparcv9 ? "v9m" : "v8plusm";
+ else if (CPU.find("SPARC-M7") != std::string::npos)
+ return Triple.getArch() == llvm::Triple::sparcv9 ? "v9m" : "v8plusm";
+ } else if (AV == "ultrasparc") {
+ return Triple.getArch() == llvm::Triple::sparcv9 ? "v9a" : "v8plusa";
+ } else if (AV == "ultrasparc2") {
+ return Triple.getArch() == llvm::Triple::sparcv9 ? "v9a" : "v8plusa";
+ } else if (AV == "ultrasparc3") {
+ return Triple.getArch() == llvm::Triple::sparcv9 ? "v9b" : "v8plusb";
+ } else if (AV == "ultrasparc4") {
+ return Triple.getArch() == llvm::Triple::sparcv9 ? "v9c" : "v8plusc";
+ } else if (AV == "niagara") {
+ return Triple.getArch() == llvm::Triple::sparcv9 ? "v9b" : "v8plusb";
+ } else if (AV == "niagara2") {
+ return Triple.getArch() == llvm::Triple::sparcv9 ? "v9b" : "v8plusb";
+ } else if (AV == "niagara3") {
+ return Triple.getArch() == llvm::Triple::sparcv9 ? "v9b" : "v8plusb";
+ } else if (AV == "niagara4") {
+ return Triple.getArch() == llvm::Triple::sparcv9 ? "v9b" : "v8plusb";
+ } else if (AV == "sparc4") {
+ return "sparc4";
+ } else if (AV == "sparc5") {
+ return "sparc5";
+ } else if (AV == "generic") {
+ return Triple.getArch() == llvm::Triple::sparcv9 ? "v9a" : "v8plusa";
+ } else if (AV == "generic32") {
+ return "v8plusa";
+ } else if (AV == "generic64") {
+ return "v9a";
+ }
+ }
+
+ return Triple.getArch() == llvm::Triple::sparcv9 ? "v9a" : "v8plusa";
+}
+
+const char *x86::getX86TargetCPU(const llvm::opt::ArgList &Args,
+ const llvm::Triple &Triple) {
if (const Arg *A = Args.getLastArg(options::OPT_march_EQ)) {
if (StringRef(A->getValue()) != "native") {
if (Triple.isOSDarwin() && Triple.getArchName() == "x86_64h")
@@ -1616,7 +1773,7 @@
//
// FIXME: We should also incorporate the detected target features for use
// with -native.
- std::string CPU = llvm::sys::getHostCPUName();
+ std::string CPU = llvm::sys::getHostCPUName().str();
if (!CPU.empty() && CPU != "generic")
return Args.MakeArgString(CPU);
}
@@ -1666,6 +1823,10 @@
if (Triple.isAndroid())
return Is64Bit ? "x86-64" : "i686";
+ // On Solaris return a target compatible with gas.
+ if (Triple.isOSSolaris())
+ return Is64Bit ? "opteron" : "pentium4";
+
// Everything else goes to x86-64 in 64-bit mode.
if (Is64Bit)
return "x86-64";
@@ -1757,15 +1918,17 @@
}
case llvm::Triple::sparc:
- case llvm::Triple::sparcel:
case llvm::Triple::sparcv9:
+ return sparc::getSparcTargetCPU(Args, T);
+
+ case llvm::Triple::sparcel:
if (const Arg *A = Args.getLastArg(options::OPT_mcpu_EQ))
return A->getValue();
return "";
case llvm::Triple::x86:
case llvm::Triple::x86_64:
- return getX86TargetCPU(Args, T);
+ return x86::getX86TargetCPU(Args, T);
case llvm::Triple::hexagon:
return "hexagon" +
@@ -3084,7 +3247,7 @@
// Fallback to user id.
#ifdef LLVM_ON_UNIX
- std::string UID = llvm::utostr(getuid());
+ std::string UID = std::to_string(static_cast<unsigned int>(getuid()));
#else
// FIXME: Windows seems to have an 'SID' that might work.
std::string UID = "9999";
@@ -3263,10 +3426,12 @@
// ToolChain.getTriple() and Triple?
bool PIE = ToolChain.isPIEDefault();
bool PIC = PIE || ToolChain.isPICDefault();
+
// The Darwin/MachO default to use PIC does not apply when using -static.
if (ToolChain.getTriple().isOSBinFormatMachO() &&
Args.hasArg(options::OPT_static))
PIE = PIC = false;
+
bool IsPICLevelTwo = PIC;
bool KernelOrKext =
@@ -3320,6 +3485,24 @@
}
}
+ // Solaris-specific defaults for PIE
+ if (ToolChain.getTriple().getOS() == llvm::Triple::Solaris) {
+ switch (ToolChain.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;
+ }
+ }
+
+
// The last argument relating to either PIC or PIE wins, and no
// other argument is used. If the last argument is any flavor of the
// '-fno-...' arguments, both PIC and PIE are disabled. Any PIE
@@ -3336,8 +3519,8 @@
if (O.matches(options::OPT_fPIC) || O.matches(options::OPT_fpic) ||
O.matches(options::OPT_fPIE) || O.matches(options::OPT_fpie)) {
PIE = O.matches(options::OPT_fPIE) || O.matches(options::OPT_fpie);
- PIC =
- PIE || O.matches(options::OPT_fPIC) || O.matches(options::OPT_fpic);
+ PIC = PIE || O.matches(options::OPT_fPIC) ||
+ O.matches(options::OPT_fpic);
IsPICLevelTwo =
O.matches(options::OPT_fPIE) || O.matches(options::OPT_fPIC);
} else {
@@ -3367,10 +3550,37 @@
!Triple.isWatchOS()))
PIC = PIE = false;
+ if (ToolChain.getTriple().getOS() == llvm::Triple::Solaris) {
+ unsigned PICLevel = IsPICLevelTwo ? 2 : 1;
+ if (Arg *A = Args.getLastArg(options::OPT_shared)) {
+ PIC = true;
+ PIE = false;
+ return std::make_tuple(llvm::Reloc::PIC_, PICLevel, PIE);
+ } else if (PIE) {
+ PIC = PIE = true;
+ return std::make_tuple(llvm::Reloc::PIC_, PICLevel, PIE);
+ } else if (PIC) {
+ PIC = true;
+ PIE = IsPICLevelTwo;
+ return std::make_tuple(llvm::Reloc::PIC_, PICLevel, PIE);
+ } else if (Args.hasArg(options::OPT_static)) {
+ // Solaris doesn't to static relocations.
+ PIC = PIE = false;
+ return std::make_tuple(llvm::Reloc::DynamicNoPIC, PICLevel, PIE);
+ } else {
+ // This is a Solaris non-PIE executable.
+ // Solaris doesn't to static relocations.
+ PIC = PIE = false;
+ PICLevel = 0;
+ return std::make_tuple(llvm::Reloc::DynamicNoPIC, PICLevel, PIE);
+ }
+ }
+
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.
- if (!ToolChain.getTriple().isOSDarwin())
+ if (!ToolChain.getTriple().isOSDarwin() &&
+ !ToolChain.getTriple().isOSSolaris())
ToolChain.getDriver().Diag(diag::err_drv_unsupported_opt_for_target)
<< A->getSpelling() << ToolChain.getTriple().str();
@@ -3404,18 +3614,6 @@
llvm_unreachable("Unknown Reloc::Model kind");
}
-static void AddAssemblerKPIC(const ToolChain &ToolChain, const ArgList &Args,
- ArgStringList &CmdArgs) {
- llvm::Reloc::Model RelocationModel;
- unsigned PICLevel;
- bool IsPIE;
- std::tie(RelocationModel, PICLevel, IsPIE) =
- ParsePICArgs(ToolChain, ToolChain.getTriple(), Args);
-
- if (RelocationModel != llvm::Reloc::Static)
- CmdArgs.push_back("-KPIC");
-}
-
void Clang::ConstructJob(Compilation &C, const JobAction &JA,
const InputInfo &Output, const InputInfoList &Inputs,
const ArgList &Args, const char *LinkingOutput) const {
@@ -3713,6 +3911,14 @@
CmdArgs.push_back(A->getValue());
}
+ if (Arg *A = Args.getLastArg(options::OPT_fabi_version_EQ)) {
+ StringRef V = A->getValue();
+ CmdArgs.push_back(Args.MakeArgString("-fabi-version=" + V));
+ A->claim();
+ } else {
+ CmdArgs.push_back(Args.MakeArgString("-fabi-version=4"));
+ }
+
if (Arg *A = Args.getLastArg(options::OPT_fpcc_struct_return,
options::OPT_freg_struct_return)) {
if (getToolChain().getArch() != llvm::Triple::x86) {
@@ -4522,6 +4728,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 == 0U) N = 72U;
CmdArgs.push_back(Args.MakeArgString(Twine(N)));
}
@@ -4707,6 +4914,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().getArch() == llvm::Triple::sparc) ||
+ (getToolChain().getArch() == llvm::Triple::sparcv9))
+ CmdArgs.push_back("-mstack-alignment=16");
}
if (Args.hasArg(options::OPT_mstack_probe_size)) {
@@ -4963,16 +5174,16 @@
}
// -fuse-cxa-atexit is default.
- if (!Args.hasFlag(
+ if ((!Args.hasFlag(
options::OPT_fuse_cxa_atexit, options::OPT_fno_use_cxa_atexit,
!IsWindowsCygnus && !IsWindowsGNU &&
- getToolChain().getTriple().getOS() != llvm::Triple::Solaris &&
getToolChain().getArch() != llvm::Triple::hexagon &&
getToolChain().getArch() != llvm::Triple::xcore &&
((getToolChain().getTriple().getVendor() !=
llvm::Triple::MipsTechnologies) ||
getToolChain().getTriple().hasEnvironment())) ||
- KernelOrKext)
+ KernelOrKext) &&
+ !getToolChain().getTriple().getOS() == llvm::Triple::Solaris)
CmdArgs.push_back("-fno-use-cxa-atexit");
// -fms-extensions=0 is default.
@@ -5425,8 +5636,10 @@
// nice to enable this when doing a crashdump for modules as well.
if (Args.hasFlag(options::OPT_frewrite_includes,
options::OPT_fno_rewrite_includes, false) ||
- (C.isForDiagnostics() && !HaveModules))
+ (C.isForDiagnostics() && !HaveModules)) {
+ if (getToolChain().getTriple().getOS() != llvm::Triple::Solaris)
CmdArgs.push_back("-frewrite-includes");
+ }
// Only allow -traditional or -traditional-cpp outside in preprocessing modes.
if (Arg *A = Args.getLastArg(options::OPT_traditional,
@@ -6155,7 +6368,10 @@
CmdArgs.push_back("-fsyntax-only");
}
- Args.AddAllArgValues(CmdArgs, options::OPT_Wa_COMMA, options::OPT_Xassembler);
+ Args.AddAllArgValues(CmdArgs, options::OPT_Wa_COMMA,
+ options::OPT_Xassembler);
+ Args.ClaimAllArgs(options::OPT_Wa_COMMA);
+ Args.ClaimAllArgs(options::OPT_Xassembler);
// Only pass -x if gcc will understand it; otherwise hope gcc
// understands the suffix correctly. The main use case this would go
@@ -7383,44 +7599,362 @@
claimNoWarnArgs(Args);
ArgStringList CmdArgs;
- Args.AddAllArgValues(CmdArgs, options::OPT_Wa_COMMA, options::OPT_Xassembler);
+ const toolchains::Solaris &TC =
+ static_cast<const toolchains::Solaris&>(getToolChain());
+
+ if (!TC.isValid()) {
+ llvm::errs() << "Invalid GCC installation!\n";
+ return;
+ }
+ std::string EffectiveTriple = TC.ComputeLLVMTriple(Args, types::ID(0));
+ llvm::Triple ET(EffectiveTriple);
+
+ const Driver &D = TC.getDriver();
+ llvm::Triple::ArchType Arch = ET.getArch();
+ StringRef AS = TC.getAssembler();
+ bool m32 = !!Args.getLastArg(options::OPT_m32);
+
+ std::string march;
+ std::string mtune;
+ std::string mcpu;
+
+ 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 (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");
+ if (march.empty())
+ march="v8plusa";
+ if (mcpu.empty())
+ mcpu="v8plusa";
+ } else {
+ CmdArgs.push_back("-64");
+ if (march.empty())
+ march="v9a";
+ if (mcpu.empty())
+ mcpu="v9a";
+ }
+ break;
+ default:
+ D.Diag(diag::err_target_unsupported_arch) << ET.getArchName()
+ << ET.getTriple();
+ break;
+ }
+
+ std::string xarch;
+
+ switch (Arch) {
+ case llvm::Triple::sparc:
+ case llvm::Triple::sparcv9:
+ xarch = "-xarch=";
+ xarch += clang::driver::tools::sparc::getSparcTargetCPU(Args, ET);
+ CmdArgs.push_back(Args.MakeArgString(xarch.c_str()));
+ AddAssemblerKPIC(TC, Args, CmdArgs);
+ CmdArgs.push_back("-no-undeclared-regs");
+ if (Args.hasArg(options::OPT_mstrict_align))
+ CmdArgs.push_back("--enforce-aligned-data");
+ break;
+ case llvm::Triple::x86:
+ case llvm::Triple::x86_64:
+ xarch = "-march=";
+ xarch += clang::driver::tools::x86::getX86TargetCPU(Args, ET);
+ CmdArgs.push_back(Args.MakeArgString(xarch.c_str()));
+ break;
+ default:
+ D.Diag(diag::err_target_unsupported_arch) << ET.getArchName()
+ << ET.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)
+ Args.AddAllArgValues(CmdArgs, options::OPT_Wa_COMMA,
+ options::OPT_Xassembler);
+
+ for (const auto &II : Inputs) {
+ if (II.isFilename())
CmdArgs.push_back(II.getFilename());
+ else
+ II.getInputArg().render(Args, CmdArgs);
+ }
- const char *Exec = Args.MakeArgString(getToolChain().GetProgramPath("as"));
+ const char *Exec = AS.data();
C.addCommand(llvm::make_unique<Command>(JA, *this, Exec, CmdArgs, Inputs));
}
+void
+solaris::Assembler::RenderExtraToolArgs(const JobAction &JA,
+ llvm::opt::ArgStringList &CmdArgs) const {
+ // FIXME: IMPLEMENT
+}
+
+bool solaris::Linker::checkGnuLd(StringRef Path) const {
+ if (Path.empty()) return false;
+
+ char Buf[_POSIX_PATH_MAX+1];
+ std::string CMD = Path.str();
+ CMD += " -v 2>&1";
+
+ std::FILE *FP = ::popen(CMD.c_str(), "r");
+ if (!FP) return false;
+
+ (void) std::memset(Buf, 0, sizeof(Buf));
+ (void) std::fgets(Buf, _POSIX_PATH_MAX, FP);
+ ::pclose(FP);
+
+ return !!std::strstr(Buf, "GNU");
+}
+
void solaris::Linker::ConstructJob(Compilation &C, const JobAction &JA,
const InputInfo &Output,
const InputInfoList &Inputs,
const ArgList &Args,
const char *LinkingOutput) const {
+ const toolchains::Solaris& TC =
+ static_cast<const toolchains::Solaris&>(getToolChain());
+
+ if (!TC.isValid()) {
+ llvm::errs() << "Invalid GCC installation!\n";
+ return;
+ }
+
+ llvm::Triple TT = TC.getTriple();
+ std::string EffectiveTriple = TC.ComputeLLVMTriple(Args, types::ID(0));
+ llvm::Triple ET(EffectiveTriple);
+
+ const Driver &D = TC.getDriver();
+ llvm::Triple::ArchType Arch = TT.getArch();
+ bool m32 = !!Args.getLastArg(options::OPT_m32);
+
+ StringRef LD = TC.getLinker();
+ bool UseGnuLd = checkGnuLd(LD);
+
+ std::string GCCLibPath;
+ std::string YPPath;
+ GCCLibPath += "/lib/gcc/";
+ std::string LibPath = "/usr/lib/";
+ std::string ShortLibPath = "/lib/";
+ std::string ClangLibPath;
+ const char* moption;
+ std::string gldm;
+
+ if (UseGnuLd) {
+ switch (Arch) {
+ case llvm::Triple::x86:
+ if (m32)
+ gldm = "elf_i386_sol2";
+ else
+ gldm = "elf_x86_64_sol2";
+ break;
+ case llvm::Triple::x86_64:
+ if (m32)
+ gldm = "elf_i386_sol2";
+ else
+ gldm = "elf_x86_64_sol2";
+ break;
+ case llvm::Triple::sparc:
+ if (m32)
+ gldm = "elf32_sparc_sol2";
+ else
+ gldm = "elf64_sparc_sol2";
+ break;
+ case llvm::Triple::sparcv9:
+ if (m32)
+ gldm = "elf32_sparc_sol2";
+ else
+ gldm = "elf64_sparc_sol2";
+ break;
+ default:
+ break;
+ }
+ }
+
+ switch (Arch) {
+ case llvm::Triple::x86:
+ 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/amd64/clang/";
+ }
+ 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/sparcv9/clang/";
+ }
+ break;
+ case llvm::Triple::x86_64:
+ 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/amd64/clang/";
+ }
+ 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/sparcv9/clang/";
+ }
+ break;
+ default:
+ D.Diag(diag::err_target_unsupported_arch) << ET.getArchName()
+ << ET.getTriple();
+ break;
+ }
+
ArgStringList CmdArgs;
- // Demangle C++ names in errors
- CmdArgs.push_back("-C");
+ // THe -m flag to GNU ld is positional dependent.
+ // Do not change this ordering of options for the GNU ld.
+ if (!gldm.empty()) {
+ CmdArgs.push_back(Args.MakeArgString("-m"));
+ CmdArgs.push_back(Args.MakeArgString(gldm.c_str()));
+ }
- if (!Args.hasArg(options::OPT_nostdlib, options::OPT_shared)) {
- CmdArgs.push_back("-e");
- CmdArgs.push_back("_start");
+ if (UseGnuLd) {
+ if (Args.hasArg(options::OPT_v))
+ CmdArgs.push_back(Args.MakeArgString("-v"));
+ CmdArgs.push_back(Args.MakeArgString("--as-needed"));
+ } else {
+ if (D.CCCIsCXX())
+ CmdArgs.push_back(Args.MakeArgString("-zrelax=comdat"));
}
+ 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"));
+
+ if (UseGnuLd) {
+ CmdArgs.push_back(Args.MakeArgString("--pic-executable"));
+ } else {
+ 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 'argument not used during compilation: -g' warning.
+ Args.ClaimAllArgs(options::OPT_g_Group);
+
+ // Silence 'argument unused during compilation: -pthread' warning.
+ Args.ClaimAllArgs(options::OPT_pthread);
+
+ // 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 (UseGnuLd)
+ CmdArgs.push_back("--demangle");
+ else
+ 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 {
CmdArgs.push_back("--dynamic-linker");
- CmdArgs.push_back(
- Args.MakeArgString(getToolChain().GetFilePath("ld.so.1")));
+ CmdArgs.push_back(Args.MakeArgString(LibPath + "ld.so.1"));
}
}
@@ -7431,48 +7965,268 @@
assert(Output.isNothing() && "Invalid output.");
}
- if (!Args.hasArg(options::OPT_nostdlib, options::OPT_nostartfiles)) {
- if (!Args.hasArg(options::OPT_shared))
- CmdArgs.push_back(
- Args.MakeArgString(getToolChain().GetFilePath("crt1.o")));
+ const char* Values = "values-Xa.o";
+ const char* Xpg = "values-xpg4.o";
- CmdArgs.push_back(Args.MakeArgString(getToolChain().GetFilePath("crti.o")));
- CmdArgs.push_back(
- Args.MakeArgString(getToolChain().GetFilePath("values-Xa.o")));
- CmdArgs.push_back(
- Args.MakeArgString(getToolChain().GetFilePath("crtbegin.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";
+ }
+ }
}
- getToolChain().AddFilePathLibArgs(Args, CmdArgs);
+ if (UseGnuLd) {
+ if (LD == "/usr/gnu/bin/ld.gold") {
+ if (Args.hasArg(options::OPT_O))
+ Args.AddAllArgs(CmdArgs, options::OPT_O);
+ } else
+ CmdArgs.push_back(Args.MakeArgString("-O"));
+ }
- Args.AddAllArgs(CmdArgs, {options::OPT_L, options::OPT_T_Group,
- options::OPT_e, options::OPT_r});
+ if (Args.hasArg(options::OPT_v))
+ CmdArgs.push_back(Args.MakeArgString(StringRef("-V")));
- AddLinkerInputs(getToolChain(), Inputs, Args, CmdArgs);
+ CmdArgs.push_back(Args.MakeArgString(StringRef("-Qy")));
- if (!Args.hasArg(options::OPT_nostdlib, options::OPT_nodefaultlibs)) {
- if (getToolChain().getDriver().CCCIsCXX())
- getToolChain().AddCXXStdlibLibArgs(Args, CmdArgs);
- CmdArgs.push_back("-lgcc_s");
- CmdArgs.push_back("-lc");
+ if (LD == "/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;
+ bool S12OrHigher = false;
+
+ // We're not backporting this to S10. Until we do, that is.
+ if (EffectiveTriple.find("solaris2.11") == std::string::npos)
+ S12OrHigher = true;
+
+ if (!Args.hasArg(options::OPT_nostdlib) &&
+ !Args.hasArg(options::OPT_nostartfiles)) {
if (!Args.hasArg(options::OPT_shared)) {
- CmdArgs.push_back("-lgcc");
+ switch (Arch) {
+ case llvm::Triple::sparc:
+ case llvm::Triple::sparcv9:
+ if (S12OrHigher)
+ crt1o = LibPath;
+ else
+ crt1o = GCCLibPath;
+ case llvm::Triple::x86:
+ case llvm::Triple::x86_64:
+ crt1o = LibPath;
+ break;
+ default:
+ D.Diag(diag::err_target_unsupported_arch) << ET.getArchName()
+ << ET.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));
+ 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));
+ 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 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"));
+ }
+ }
+
+ // Itanium C++ ABI.
+ std::string CXAFinalize;
+ bool HasSystemCXAFinalize = !S12OrHigher;
+
+ 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);
+
+ 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)) {
+ if (HasSystemCXAFinalize) {
+ const char* zfiniarray = "-zfiniarray=__cxa_finalize";
+ CmdArgs.push_back(Args.MakeArgString(zfiniarray));
+ }
+ }
+ }
+
+ if (LD == "/usr/gnu/bin/ld.gold") {
+ CmdArgs.push_back("-plugin");
+ std::string Plugin = D.Dir + "/../lib/LLVMgold.so";
+ CmdArgs.push_back(Args.MakeArgString(Plugin));
+ }
+
+ if (!UseGnuLd) {
+ CmdArgs.push_back(moption);
+ }
+
+ if (Arg *A = Args.getLastArg(options::OPT_rpath)) {
+ StringRef V = A->getValue();
+ if (UseGnuLd) {
+ 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, LD.str());
+
+ if (!Args.hasArg(options::OPT_nostdlib) &&
+ !Args.hasArg(options::OPT_nodefaultlibs)) {
+ if (Args.hasArg(options::OPT_fopenmp) ||
+ Args.hasArg(options::OPT_fopenmp_EQ)) {
+ addOpenMPRuntime(CmdArgs, TC, Args);
+ CmdArgs.push_back("-latomic");
+ }
+
+ 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, options::OPT_nostartfiles)) {
- CmdArgs.push_back(
- Args.MakeArgString(getToolChain().GetFilePath("crtend.o")));
+ if (!Args.hasArg(options::OPT_nostdlib) &&
+ !Args.hasArg(options::OPT_nostartfiles)) {
+ CmdArgs.push_back(Args.MakeArgString(GCCLibPath + "crtend.o"));
}
- CmdArgs.push_back(Args.MakeArgString(getToolChain().GetFilePath("crtn.o")));
- getToolChain().addProfileRTLibs(Args, CmdArgs);
+ CmdArgs.push_back(Args.MakeArgString(LibPath + "crtn.o"));
- const char *Exec = Args.MakeArgString(getToolChain().GetLinkerPath());
+ TC.addProfileRTLibs(Args, CmdArgs);
+
+ Args.ClaimAllArgs(options::OPT_Wl_COMMA);
+ Args.ClaimAllArgs(options::OPT_Xlinker);
+
+ const char *Exec = LD.data();
C.addCommand(llvm::make_unique<Command>(JA, *this, Exec, CmdArgs, Inputs));
}
+void
+solaris::Linker::RenderExtraToolArgs(const JobAction &JA,
+ llvm::opt::ArgStringList &CmdArgs) const {
+ // FIXME: IMPLEMENT
+}
+
void openbsd::Assembler::ConstructJob(Compilation &C, const JobAction &JA,
const InputInfo &Output,
const InputInfoList &Inputs,
@@ -8623,6 +9377,41 @@
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) {
const llvm::Triple::ArchType Arch = ToolChain.getArch();
###
--- tools/clang/lib/Driver/Tools.h 2016-01-08 06:14:31.000000000 -0900
+++ tools/clang/lib/Driver/Tools.h 2016-07-04 11:21:03.646553390 -0800
@@ -17,6 +17,8 @@
#include "clang/Frontend/CodeGenOptions.h"
#include "llvm/ADT/Triple.h"
#include "llvm/Option/Option.h"
+#include "llvm/Option/Arg.h"
+#include "llvm/Option/ArgList.h"
#include "llvm/Support/Compiler.h"
namespace clang {
@@ -38,9 +40,10 @@
using llvm::opt::ArgStringList;
-SmallString<128> getCompilerRT(const ToolChain &TC,
+SmallString<PATH_MAX> getCompilerRT(const ToolChain &TC,
const llvm::opt::ArgList &Args,
- StringRef Component, bool Shared = false);
+ StringRef Component,
+ bool Shared = false);
/// \brief Clang compiler tool.
class LLVM_LIBRARY_VISIBILITY Clang : public Tool {
@@ -308,6 +311,16 @@
bool hasPPCAbiArg(const llvm::opt::ArgList &Args, const char *Value);
} // end namespace ppc
+namespace sparc {
+ const char *getSparcTargetCPU(const llvm::opt::ArgList &Args,
+ const llvm::Triple &Triple);
+} // end namespace sparc
+
+namespace x86 {
+ const char *getX86TargetCPU(const llvm::opt::ArgList &Args,
+ const llvm::Triple &Triple);
+} // end namespace x86
+
/// cloudabi -- Directly call GNU Binutils linker
namespace cloudabi {
class LLVM_LIBRARY_VISIBILITY Linker : public GnuTool {
@@ -622,25 +635,32 @@
/// solaris -- Directly call Solaris assembler and linker
namespace solaris {
-class LLVM_LIBRARY_VISIBILITY Assembler : public Tool {
+class LLVM_LIBRARY_VISIBILITY Assembler : public GnuTool {
public:
Assembler(const ToolChain &TC)
- : Tool("solaris::Assembler", "assembler", TC) {}
+ : GnuTool("solaris::Assembler", "assembler", TC) {}
bool hasIntegratedCPP() const override { return false; }
+ virtual void RenderExtraToolArgs(const JobAction &JA,
+ llvm::opt::ArgStringList &CmdArgs) const;
+
void ConstructJob(Compilation &C, const JobAction &JA,
const InputInfo &Output, const InputInfoList &Inputs,
const llvm::opt::ArgList &TCArgs,
const char *LinkingOutput) const override;
};
-class LLVM_LIBRARY_VISIBILITY Linker : public Tool {
+class LLVM_LIBRARY_VISIBILITY Linker : public GnuTool {
public:
- Linker(const ToolChain &TC) : Tool("solaris::Linker", "linker", TC) {}
+ Linker(const ToolChain &TC)
+ : GnuTool("solaris::Linker", "linker", TC) {}
bool hasIntegratedCPP() const override { return false; }
bool isLinkJob() const override { return true; }
+ bool checkGnuLd(StringRef Path) const;
+ virtual void RenderExtraToolArgs(const JobAction &JA,
+ llvm::opt::ArgStringList &CmdArgs) const;
void ConstructJob(Compilation &C, const JobAction &JA,
const InputInfo &Output, const InputInfoList &Inputs,
###
--- tools/clang/lib/Driver/ToolChain.cpp 2015-11-25 16:02:07.000000000 -0900
+++ tools/clang/lib/Driver/ToolChain.cpp 2016-06-30 20:26:09.406980255 -0800
@@ -408,6 +408,34 @@
std::string ToolChain::ComputeLLVMTriple(const ArgList &Args,
types::ID InputType) const {
+ llvm::Triple T = getTriple();
+ if (T.isOSSolaris()) {
+ if ((!Args.getLastArg(options::OPT_m32)) &&
+ (!Args.getLastArg(options::OPT_m64))) {
+ StringRef ArchName;
+
+ switch (T.getArch()) {
+ case llvm::Triple::x86_64:
+ case llvm::Triple::sparcv9:
+ return getTripleString();
+ break;
+ case llvm::Triple::sparc:
+ ArchName = "sparcv9";
+ T.setArchName(ArchName);
+ return T.getTriple();
+ break;
+ case llvm::Triple::x86:
+ ArchName = "x86_64";
+ T.setArchName(ArchName);
+ return T.getTriple();
+ break;
+ default:
+ llvm_unreachable("Unknonwn Solaris Target Triple!");
+ break;
+ }
+ }
+ }
+
switch (getTriple().getArch()) {
default:
return getTripleString();
###