components/llvm/patches/012-solaris-clang-libclangDriver.patch
changeset 6512 92717ce71105
child 6637 22d5f6c97e6f
equal deleted inserted replaced
6511:d283aa33e131 6512:92717ce71105
       
     1 # 23701635 clang produces amd64 opcodes, but calls 32-bit assembler by default
       
     2 # 23854357 clang should check for GNU ld
       
     3 # 22778650 clang should support OpenMP because it can
       
     4 # 24314745 clang should support PIE executables in Solaris
       
     5 # 3.9.X for upstream.
       
     6 --- tools/clang/include/clang/Driver/Options.td	2016-01-06 16:27:42.000000000 -0500
       
     7 +++ tools/clang/include/clang/Driver/Options.td	2016-05-08 23:19:20.553431263 -0400
       
     8 @@ -669,6 +669,9 @@
       
     9    Flags<[CC1Option]>, HelpText<"Form fused FP ops (e.g. FMAs): fast (everywhere)"
       
    10    " | on (according to FP_CONTRACT pragma, default) | off (never fuse)">;
       
    11  
       
    12 +def fabi_version_EQ : Joined<["-"], "fabi-version=">, Group<f_Group>,
       
    13 +  Flags<[CC1Option]>, HelpText<"Use specified GNU C++ ABI version">;
       
    14 +
       
    15  def ffor_scope : Flag<["-"], "ffor-scope">, Group<f_Group>;
       
    16  def fno_for_scope : Flag<["-"], "fno-for-scope">, Group<f_Group>;
       
    17  
       
    18 @@ -1312,6 +1315,12 @@
       
    19  def meabi : Separate<["-"], "meabi">, Group<m_Group>, Flags<[CC1Option]>,
       
    20    HelpText<"Set EABI type, e.g. 4, 5 or gnu (default depends on triple)">;
       
    21  
       
    22 +// SPARC-only options.
       
    23 +def mvis : Flag<["-"], "mvis">, Group<m_Group>;
       
    24 +def mvis2 : Flag<["-"], "mvis2">, Group<m_Group>;
       
    25 +def mvis3 : Flag<["-"], "mvis3">, Group<m_Group>;
       
    26 +def mimpure_text: Flag<["-"], "mimpure-text">, Group<m_Group>;
       
    27 +
       
    28  def mmmx : Flag<["-"], "mmmx">, Group<m_x86_Features_Group>;
       
    29  def mno_3dnowa : Flag<["-"], "mno-3dnowa">, Group<m_x86_Features_Group>;
       
    30  def mno_3dnow : Flag<["-"], "mno-3dnow">, Group<m_x86_Features_Group>;
       
    31 @@ -1954,6 +1963,7 @@
       
    32  
       
    33  def fprofile_dir : Joined<["-"], "fprofile-dir=">, Group<clang_ignored_gcc_optimization_f_Group>;
       
    34  
       
    35 +def fuse_as_EQ : Joined<["-"], "fuse-as=">, Group<f_Group>;
       
    36  def fuse_ld_EQ : Joined<["-"], "fuse-ld=">, Group<f_Group>;
       
    37  
       
    38  defm align_functions : BooleanFFlag<"align-functions">, Group<clang_ignored_gcc_optimization_f_Group>;
       
    39 ###
       
    40 --- tools/clang/lib/Driver/Multilib.cpp	2015-10-12 10:32:57.000000000 -0400
       
    41 +++ tools/clang/lib/Driver/Multilib.cpp	2016-05-08 23:19:20.569431652 -0400
       
    42 @@ -171,11 +171,11 @@
       
    43  }
       
    44  
       
    45  static Multilib compose(const Multilib &Base, const Multilib &New) {
       
    46 -  SmallString<128> GCCSuffix;
       
    47 +  SmallString<PATH_MAX> GCCSuffix;
       
    48    llvm::sys::path::append(GCCSuffix, "/", Base.gccSuffix(), New.gccSuffix());
       
    49 -  SmallString<128> OSSuffix;
       
    50 +  SmallString<PATH_MAX> OSSuffix;
       
    51    llvm::sys::path::append(OSSuffix, "/", Base.osSuffix(), New.osSuffix());
       
    52 -  SmallString<128> IncludeSuffix;
       
    53 +  SmallString<PATH_MAX> IncludeSuffix;
       
    54    llvm::sys::path::append(IncludeSuffix, "/", Base.includeSuffix(),
       
    55                            New.includeSuffix());
       
    56  
       
    57 ###
       
    58 --- tools/clang/lib/Driver/ToolChains.cpp	2016-02-16 10:56:48.000000000 -0900
       
    59 +++ tools/clang/lib/Driver/ToolChains.cpp	2016-06-30 09:27:01.031173505 -0800
       
    60 @@ -28,12 +28,15 @@
       
    61  #include "llvm/ProfileData/InstrProf.h"
       
    62  #include "llvm/Support/ErrorHandling.h"
       
    63  #include "llvm/Support/FileSystem.h"
       
    64 +#include "llvm/Support/Host.h"
       
    65  #include "llvm/Support/MemoryBuffer.h"
       
    66  #include "llvm/Support/Path.h"
       
    67  #include "llvm/Support/Program.h"
       
    68  #include "llvm/Support/TargetParser.h"
       
    69  #include "llvm/Support/raw_ostream.h"
       
    70  #include <cstdlib> // ::getenv
       
    71 +#include <cstring>
       
    72 +#include <cctype>
       
    73  #include <system_error>
       
    74  
       
    75  using namespace clang::driver;
       
    76 @@ -41,6 +44,15 @@
       
    77  using namespace clang;
       
    78  using namespace llvm::opt;
       
    79  
       
    80 +#if defined(LLVM_ON_UNIX)
       
    81 +#include <cstring>
       
    82 +#include <cctype>
       
    83 +#include <sys/types.h>
       
    84 +#include <sys/stat.h>
       
    85 +#include <dirent.h>
       
    86 +#include <unistd.h>
       
    87 +#endif
       
    88 +
       
    89  MachO::MachO(const Driver &D, const llvm::Triple &Triple, const ArgList &Args)
       
    90      : ToolChain(D, Triple, Args) {
       
    91    // We expect 'as', 'ld', etc. to be adjacent to our install dir.
       
    92 @@ -1347,6 +1359,11 @@
       
    93      // If we have a SysRoot, try that first.
       
    94      if (!D.SysRoot.empty()) {
       
    95        Prefixes.push_back(D.SysRoot);
       
    96 +
       
    97 +      // Add Solaris-specific GCC locations.
       
    98 +      if (TargetTriple.getOS() == llvm::Triple::Solaris)
       
    99 +        Prefixes.push_back("/usr/gcc");
       
   100 +
       
   101        Prefixes.push_back(D.SysRoot + "/usr");
       
   102      }
       
   103  
       
   104 @@ -1434,14 +1451,17 @@
       
   105    static const char *const ARMebHFTriples[] = {
       
   106        "armeb-linux-gnueabihf", "armebv7hl-redhat-linux-gnueabi"};
       
   107  
       
   108 -  static const char *const X86_64LibDirs[] = {"/lib64", "/lib"};
       
   109 +  static const char *const X86_64LibDirs[] = {"/lib64", "/lib/amd64",
       
   110 +                                               "/lib/64", "/lib"};
       
   111    static const char *const X86_64Triples[] = {
       
   112        "x86_64-linux-gnu",       "x86_64-unknown-linux-gnu",
       
   113        "x86_64-pc-linux-gnu",    "x86_64-redhat-linux6E",
       
   114        "x86_64-redhat-linux",    "x86_64-suse-linux",
       
   115        "x86_64-manbo-linux-gnu", "x86_64-linux-gnu",
       
   116        "x86_64-slackware-linux", "x86_64-linux-android",
       
   117 -      "x86_64-unknown-linux"};
       
   118 +      "x86_64-unknown-linux", "x86_64-pc-solaris2.11",
       
   119 +      "x86_64-pc-solaris2.12", "x86_64-pc-solaris2.13" };
       
   120 +
       
   121    static const char *const X32LibDirs[] = {"/libx32"};
       
   122    static const char *const X86LibDirs[] = {"/lib32", "/lib"};
       
   123    static const char *const X86Triples[] = {
       
   124 @@ -1449,7 +1469,8 @@
       
   125        "i386-linux-gnu",       "i386-redhat-linux6E",   "i686-redhat-linux",
       
   126        "i586-redhat-linux",    "i386-redhat-linux",     "i586-suse-linux",
       
   127        "i486-slackware-linux", "i686-montavista-linux", "i686-linux-android",
       
   128 -      "i586-linux-gnu"};
       
   129 +      "i586-linux-gnu", "i386-pc-solaris2.11", "i386-pc-solaris2.12",
       
   130 +      "i386-pc-solaris2.13" };
       
   131  
       
   132    static const char *const MIPSLibDirs[] = {"/lib"};
       
   133    static const char *const MIPSTriples[] = {"mips-linux-gnu", "mips-mti-linux",
       
   134 @@ -1483,30 +1504,28 @@
       
   135  
       
   136    static const char *const SPARCv8LibDirs[] = {"/lib32", "/lib"};
       
   137    static const char *const SPARCv8Triples[] = {"sparc-linux-gnu",
       
   138 -                                               "sparcv8-linux-gnu"};
       
   139 -  static const char *const SPARCv9LibDirs[] = {"/lib64", "/lib"};
       
   140 +                                               "sparcv8-linux-gnu",
       
   141 +                                               "sparc-sun-solaris2.11",
       
   142 +                                               "sparc-sun-solaris2.12",
       
   143 +                                               "sparc-sun-solaris2.13" };
       
   144 +
       
   145 +  static const char *const SPARCv9LibDirs[] = {"/lib64", "/lib/sparcv9",
       
   146 +                                                "/lib/64", "/lib" };
       
   147 +
       
   148    static const char *const SPARCv9Triples[] = {"sparc64-linux-gnu",
       
   149 -                                               "sparcv9-linux-gnu"};
       
   150 +                                               "sparcv9-linux-gnu",
       
   151 +                                               "sparcv9-sun-solaris2.11",
       
   152 +                                               "sparcv9-sun-solaris2.12",
       
   153 +                                               "sparcv9-sun-solaris2.13"  };
       
   154  
       
   155    static const char *const SystemZLibDirs[] = {"/lib64", "/lib"};
       
   156    static const char *const SystemZTriples[] = {
       
   157        "s390x-linux-gnu", "s390x-unknown-linux-gnu", "s390x-ibm-linux-gnu",
       
   158        "s390x-suse-linux", "s390x-redhat-linux"};
       
   159  
       
   160 -  // Solaris.
       
   161 -  static const char *const SolarisSPARCLibDirs[] = {"/gcc"};
       
   162 -  static const char *const SolarisSPARCTriples[] = {"sparc-sun-solaris2.11",
       
   163 -                                                    "i386-pc-solaris2.11"};
       
   164 -
       
   165    using std::begin;
       
   166    using std::end;
       
   167  
       
   168 -  if (TargetTriple.getOS() == llvm::Triple::Solaris) {
       
   169 -    LibDirs.append(begin(SolarisSPARCLibDirs), end(SolarisSPARCLibDirs));
       
   170 -    TripleAliases.append(begin(SolarisSPARCTriples), end(SolarisSPARCTriples));
       
   171 -    return;
       
   172 -  }
       
   173 -
       
   174    switch (TargetTriple.getArch()) {
       
   175    case llvm::Triple::aarch64:
       
   176      LibDirs.append(begin(AArch64LibDirs), end(AArch64LibDirs));
       
   177 @@ -3302,69 +3321,783 @@
       
   178  }
       
   179  
       
   180  /// Solaris - Solaris tool chain which can call as(1) and ld(1) directly.
       
   181 +bool Solaris::SupportsClangLibCPlusPlus = false;
       
   182  
       
   183  Solaris::Solaris(const Driver &D, const llvm::Triple &Triple,
       
   184 -                 const ArgList &Args)
       
   185 -    : Generic_GCC(D, Triple, Args) {
       
   186 +                 const llvm::opt::ArgList &Args)
       
   187 +  : Generic_ELF(D, Triple, Args),
       
   188 +  UseGnuAs(true),
       
   189 +  UseGnuLd(false),
       
   190 +  UseGoldLd(false),
       
   191 +  UseSunLd(true),
       
   192 +  UseMediatedGCCToolChainPath(false),
       
   193 +  UseSpecifiedGCCToolChainPath(false),
       
   194 +  IsValid(false),
       
   195 +  GCCInstallDir("/usr/gcc/"),
       
   196 +  GCCMajorMinor(""),
       
   197 +  GCCMajorMinorMicro(""),
       
   198 +  GCCInternalLibDir(""),
       
   199 +  GCCInternalMultiLibDir(""),
       
   200 +  GCCIncludeDirs(),
       
   201 +  Assembler("/usr/gnu/bin/as"),
       
   202 +  Linker("/usr/bin/ld"),
       
   203 +  mtune(""),
       
   204 +  march(""),
       
   205 +  mcpu(""),
       
   206 +  ExtraOpts() {
       
   207 +    if (Arg *A = Args.getLastArg(options::OPT_gcc_toolchain)) {
       
   208 +      GCCInstallDir = A->getValue();
       
   209 +      if (!llvm::sys::fs::exists(GCCInstallDir))
       
   210 +        D.Diag(diag::err_drv_no_such_file) << GCCInstallDir;
       
   211 +      else {
       
   212 +        findSpecifiedGCCToolchain(GCCInstallDir.c_str(), Triple, Args);
       
   213 +
       
   214 +        if (!UseSpecifiedGCCToolChainPath) {
       
   215 +          D.Diag(diag::err_drv_unsupported_rtlib_for_platform)
       
   216 +            << GCCInstallDir << Triple.getTriple();
       
   217 +        } else {
       
   218 +          findGCCIncludeDirs(Triple, Args);
       
   219 +          findGCCInternalLibDir(Triple, Args);
       
   220 +        }
       
   221 +      }
       
   222 +    } else {
       
   223 +      findGCCMajorMinor();
       
   224 +      findGCCMajorMinorMicro(Triple);
       
   225 +      findGCCIncludeDirs(Triple, Args);
       
   226 +      findGCCInternalLibDir(Triple, Args);
       
   227 +    }
       
   228  
       
   229 -  GCCInstallation.init(Triple, Args);
       
   230 +    if (Arg *A = Args.getLastArg(options::OPT_fuse_ld_EQ)) {
       
   231 +      Linker = A->getValue();
       
   232 +      if (Linker == "bfd")
       
   233 +        Linker = "/usr/gnu/bin/ld";
       
   234 +      else if (Linker == "gold")
       
   235 +        Linker = "/usr/gnu/bin/ld.gold";
       
   236 +
       
   237 +      if ((Linker == "/usr/gnu/bin/ld") || (Linker == "/usr/gnu/bin/ld.bfd") ||
       
   238 +          (Linker == "/usr/bin/gld") || (Linker == "/usr/bin/gld.bfd")) {
       
   239 +        UseGnuLd = true;
       
   240 +        UseGoldLd = false;
       
   241 +        UseSunLd = false;
       
   242 +      } else if ((Linker == "/usr/gnu/bin/ld.gold") ||
       
   243 +                 (Linker == "/usr/bin/gld.gold") ||
       
   244 +                 (Linker == "/usr/bin/ld.gold")) {
       
   245 +        UseGnuLd = false;
       
   246 +        UseSunLd = false;
       
   247 +        UseGoldLd = true;
       
   248 +      }
       
   249 +    }
       
   250  
       
   251 -  path_list &Paths = getFilePaths();
       
   252 -  if (GCCInstallation.isValid())
       
   253 -    addPathIfExists(D, GCCInstallation.getInstallPath(), Paths);
       
   254 +    if (Arg *A = Args.getLastArg(options::OPT_fuse_as_EQ)) {
       
   255 +      Assembler = A->getValue();
       
   256 +      if (Assembler == "llvm")
       
   257 +        UseGnuAs = false;
       
   258 +      else if ((Assembler == "/usr/gnu/bin/as") ||
       
   259 +               (Assembler == "/usr/bin/gas"))
       
   260 +        UseGnuAs = true;
       
   261 +      else if (Assembler == "gas") {
       
   262 +        Assembler = "/usr/gnu/bin/as";
       
   263 +        UseGnuAs = true;
       
   264 +      } else if ((Assembler == "/usr/bin/as") || (Assembler == "sun") ||
       
   265 +                 (Assembler == "solaris"))
       
   266 +        D.Diag(diag::err_drv_clang_unsupported) << A->getAsString(Args);
       
   267 +    }
       
   268 +
       
   269 +    getProgramPaths().push_back(GCCInstallDir);
       
   270  
       
   271 -  addPathIfExists(D, getDriver().getInstalledDir(), Paths);
       
   272    if (getDriver().getInstalledDir() != getDriver().Dir)
       
   273 -    addPathIfExists(D, getDriver().Dir, Paths);
       
   274 +      getProgramPaths().push_back(getDriver().Dir);
       
   275  
       
   276 -  addPathIfExists(D, getDriver().SysRoot + getDriver().Dir + "/../lib", Paths);
       
   277 +    llvm::Triple::ArchType Arch = Triple.getArch();
       
   278  
       
   279 -  std::string LibPath = "/usr/lib/";
       
   280 -  switch (Triple.getArch()) {
       
   281 +    switch (Arch) {
       
   282    case llvm::Triple::x86:
       
   283 +      getFilePaths().push_back(getDriver().Dir + "/../lib");
       
   284 +      getFilePaths().push_back("/usr/lib");
       
   285 +      march = mtune = "i686";
       
   286 +      break;
       
   287    case llvm::Triple::sparc:
       
   288 +      getFilePaths().push_back(getDriver().Dir + "/../lib");
       
   289 +      getFilePaths().push_back("/usr/lib");
       
   290 +      mcpu = "ultrasparc";
       
   291 +      mtune = "ultrasparc";
       
   292 +      march = "v8plusa";
       
   293      break;
       
   294    case llvm::Triple::x86_64:
       
   295 -    LibPath += "amd64/";
       
   296 +      getFilePaths().push_back(getDriver().Dir + "/../lib/amd64");
       
   297 +      getFilePaths().push_back("/usr/lib/amd64");
       
   298 +      march = mtune = "opteron";
       
   299      break;
       
   300    case llvm::Triple::sparcv9:
       
   301 -    LibPath += "sparcv9/";
       
   302 +      getFilePaths().push_back(getDriver().Dir + "/../lib/sparcv9");
       
   303 +      getFilePaths().push_back("/usr/lib/sparcv9");
       
   304 +      mcpu = "ultrasparc";
       
   305 +      mtune = "ultrasparc";
       
   306 +      march = "v9a";
       
   307      break;
       
   308    default:
       
   309 -    llvm_unreachable("Unsupported architecture");
       
   310 +      getFilePaths().push_back(getDriver().Dir + "/../lib");
       
   311 +      getFilePaths().push_back("/usr/lib");
       
   312 +      break;
       
   313    }
       
   314  
       
   315 -  addPathIfExists(D, getDriver().SysRoot + LibPath, Paths);
       
   316 +    validate();
       
   317 +
       
   318 +    if (Args.hasArg(options::OPT_v))
       
   319 +      this->print(llvm::errs());
       
   320  }
       
   321  
       
   322 -Tool *Solaris::buildAssembler() const {
       
   323 -  return new tools::solaris::Assembler(*this);
       
   324 +std::string Solaris::computeSysRoot() const {
       
   325 +  if (!getDriver().SysRoot.empty())
       
   326 +    return getDriver().SysRoot;
       
   327 +
       
   328 +  return std::string("/");
       
   329  }
       
   330  
       
   331 -Tool *Solaris::buildLinker() const { return new tools::solaris::Linker(*this); }
       
   332 +bool
       
   333 +Solaris::addLibStdCXXIncludePaths(Twine Base, Twine Suffix,
       
   334 +                                  StringRef GCCTriple,
       
   335 +                                  StringRef GCCMultiarchTriple,
       
   336 +                                  StringRef TargetMultiarchTriple,
       
   337 +                                  Twine IncludeSuffix,
       
   338 +                                  const llvm::opt::ArgList &DriverArgs,
       
   339 +                                  llvm::opt::ArgStringList &CC1Args) const {
       
   340 +  if (!llvm::sys::fs::exists(Base + Suffix))
       
   341 +    return false;
       
   342  
       
   343 -void Solaris::AddClangCXXStdlibIncludeArgs(const ArgList &DriverArgs,
       
   344 -                                           ArgStringList &CC1Args) const {
       
   345 +  addSystemInclude(DriverArgs, CC1Args, Base);
       
   346 +  addSystemInclude(DriverArgs, CC1Args, Base + Suffix);
       
   347 +
       
   348 +  if ((GCCMultiarchTriple.empty() && TargetMultiarchTriple.empty()) ||
       
   349 +      llvm::sys::fs::exists(Base + Suffix + "/" + GCCTriple + IncludeSuffix)) {
       
   350 +    addSystemInclude(DriverArgs,
       
   351 +                     CC1Args, Base + Suffix + "/" + GCCTriple + IncludeSuffix);
       
   352 +  } else {
       
   353 +    addSystemInclude(DriverArgs, CC1Args,
       
   354 +                     Base + "/" + GCCMultiarchTriple + Suffix + IncludeSuffix);
       
   355 +    addSystemInclude(DriverArgs, CC1Args,
       
   356 +                     Base + "/" + TargetMultiarchTriple + Suffix);
       
   357 +  }
       
   358 +
       
   359 +  addSystemInclude(DriverArgs, CC1Args, Base + "/backward");
       
   360 +  addSystemInclude(DriverArgs, CC1Args, Base + Suffix + "/backward");
       
   361 +  return true;
       
   362 +}
       
   363 +
       
   364 +void
       
   365 +Solaris::AddClangCXXStdlibIncludeArgs(const llvm::opt::ArgList &DriverArgs,
       
   366 +                                      llvm::opt::ArgStringList &CC1Args) const {
       
   367    if (DriverArgs.hasArg(options::OPT_nostdlibinc) ||
       
   368        DriverArgs.hasArg(options::OPT_nostdincxx))
       
   369      return;
       
   370  
       
   371 -  // Include the support directory for things like xlocale and fudged system
       
   372 -  // headers.
       
   373 -  addSystemInclude(DriverArgs, CC1Args, "/usr/include/c++/v1/support/solaris");
       
   374 +  const Driver &D = getDriver();
       
   375  
       
   376 -  if (GCCInstallation.isValid()) {
       
   377 -    GCCVersion Version = GCCInstallation.getVersion();
       
   378 -    addSystemInclude(DriverArgs, CC1Args,
       
   379 -                     getDriver().SysRoot + "/usr/gcc/" +
       
   380 -                     Version.MajorStr + "." +
       
   381 -                     Version.MinorStr +
       
   382 -                     "/include/c++/" + Version.Text);
       
   383 -    addSystemInclude(DriverArgs, CC1Args,
       
   384 -                     getDriver().SysRoot + "/usr/gcc/" + Version.MajorStr +
       
   385 -                     "." + Version.MinorStr + "/include/c++/" +
       
   386 -                     Version.Text + "/" +
       
   387 -                     GCCInstallation.getTriple().str());
       
   388 +  // Check for Clang libc++
       
   389 +  if (GetCXXStdlibType(DriverArgs) == ToolChain::CST_Libcxx) {
       
   390 +    if (!Solaris::SupportsClangLibCPlusPlus) {
       
   391 +      D.Diag(diag::err_drv_invalid_stdlib_name) << "libc++";
       
   392 +      return;
       
   393 +    }
       
   394 +
       
   395 +    StringRef IncludePath = "/usr/include/libc++/v1";
       
   396 +    if (!llvm::sys::fs::exists(IncludePath)) {
       
   397 +      D.Diag(diag::err_drv_no_such_file) << IncludePath;
       
   398 +      return;
       
   399 +    }
       
   400 +
       
   401 +    addSystemInclude(DriverArgs, CC1Args, IncludePath);
       
   402 +    return;
       
   403 +  }
       
   404 +
       
   405 +  for (std::vector<std::string>::const_iterator B =
       
   406 +       getGCCIncludeDirs().begin(), E = getGCCIncludeDirs().end();
       
   407 +       B != E; ++B) {
       
   408 +    llvm::Twine IncludePath((*B));
       
   409 +    addSystemInclude(DriverArgs, CC1Args, IncludePath);
       
   410 +  }
       
   411 +}
       
   412 +
       
   413 +void
       
   414 +Solaris::AddClangSystemIncludeArgs(const ArgList &DriverArgs,
       
   415 +                                   ArgStringList &CC1Args) const {
       
   416 +  const Driver &D = getDriver();
       
   417 +
       
   418 +  if (DriverArgs.hasArg(options::OPT_nostdinc))
       
   419 +    return;
       
   420 +
       
   421 +  std::string SysRoot = computeSysRoot();
       
   422 +
       
   423 +  if (!DriverArgs.hasArg(options::OPT_nobuiltininc)) {
       
   424 +    SmallString<PATH_MAX> P(D.ResourceDir);
       
   425 +    llvm::sys::path::append(P, "/include");
       
   426 +    addSystemInclude(DriverArgs, CC1Args, P.str());
       
   427 +  }
       
   428 +
       
   429 +  if (DriverArgs.hasArg(options::OPT_nostdlibinc))
       
   430 +    return;
       
   431 +
       
   432 +  StringRef CIncludeDirs(C_INCLUDE_DIRS);
       
   433 +  if (CIncludeDirs != "") {
       
   434 +    SmallVector<StringRef, 5> dirs;
       
   435 +    CIncludeDirs.split(dirs, ":");
       
   436 +    for (SmallVectorImpl<StringRef>::iterator I = dirs.begin(), E = dirs.end();
       
   437 +         I != E; ++I) {
       
   438 +      StringRef Prefix =
       
   439 +        llvm::sys::path::is_absolute(*I) ? StringRef(SysRoot) : "";
       
   440 +      addExternCSystemInclude(DriverArgs, CC1Args, Prefix + *I);
       
   441 +    }
       
   442 +  }
       
   443 +
       
   444 +  addExternCSystemInclude(DriverArgs, CC1Args, "/usr/include");
       
   445 +}
       
   446 +
       
   447 +void
       
   448 +Solaris::addClangTargetOptions(const ArgList &DriverArgs,
       
   449 +                               ArgStringList &CC1Args) const {
       
   450 +  const llvm::Triple& TT = getTriple();
       
   451 +  llvm::Triple::ArchType Arch = TT.getArch();
       
   452 +
       
   453 +  if (Arg *A = DriverArgs.getLastArg(options::OPT_fuse_init_array))
       
   454 +    DriverArgs.ClaimAllArgs(options::OPT_fuse_init_array);
       
   455 +
       
   456 +  // Always use .init_array/.fini_array on Solaris. The Solaris
       
   457 +  // linker can't do .ctors/.dtors or .init/.fini for that matter.
       
   458 +  CC1Args.push_back("-fuse-init-array");
       
   459 +
       
   460 +  if (Arg *A = DriverArgs.getLastArg(options::OPT_fabi_version_EQ)) {
       
   461 +    StringRef V = A->getValue();
       
   462 +    if (!V.empty()) {
       
   463 +      std::string fabi_version = "-fabi-version=";
       
   464 +      fabi_version += V.str();
       
   465 +      CC1Args.push_back(DriverArgs.MakeArgString(fabi_version.c_str()));
       
   466 +    } else {
       
   467 +      std::string fabi_version = "-fabi-version=4";
       
   468 +      CC1Args.push_back(DriverArgs.MakeArgString(fabi_version.c_str()));
       
   469 +    }
       
   470 +  } else {
       
   471 +    CC1Args.push_back(DriverArgs.MakeArgString("-fabi-version=4"));
       
   472 +  }
       
   473 +
       
   474 +  DriverArgs.ClaimAllArgs(options::OPT_fabi_version_EQ);
       
   475 +
       
   476 +  if (Arch == llvm::Triple::sparc || Arch == llvm::Triple::sparcv9) {
       
   477 +    CC1Args.push_back(DriverArgs.MakeArgString("-target-feature"));
       
   478 +    CC1Args.push_back(DriverArgs.MakeArgString("+hwcap"));
       
   479 +  }
       
   480 +
       
   481 +  bool SeenVIS = false;
       
   482 +  bool SeenVIS2 = false;
       
   483 +  bool SeenVIS3 = false;
       
   484 +
       
   485 +  bool DoneVIS = false;
       
   486 +  bool DoneVIS2 = false;
       
   487 +  bool DoneVIS3 = false;
       
   488 +
       
   489 +  bool DoneMTune = false;
       
   490 +
       
   491 +  if (Arg *A = DriverArgs.getLastArg(options::OPT_mtune_EQ)) {
       
   492 +    StringRef V = A->getValue();
       
   493 +    if (!V.empty())
       
   494 +      mtune = V.str();
       
   495 +    else
       
   496 +      mtune = "ultrasparc";
       
   497 +
       
   498 +    if (Arch == llvm::Triple::sparc || Arch == llvm::Triple::sparcv9) {
       
   499 +      if ((mtune == "ultrasparc") || (mtune == "ultrasparc2") ||
       
   500 +          (mtune == "vis")) {
       
   501 +        SeenVIS = true;
       
   502 +      } else if ((mtune == "ultrasparc3") || (mtune == "vis2")) {
       
   503 +        SeenVIS = true;
       
   504 +        SeenVIS2 = true;
       
   505 +      } else {
       
   506 +        SeenVIS = true;
       
   507 +        SeenVIS2 = true;
       
   508 +        SeenVIS3 = true;
       
   509 +      }
       
   510 +
       
   511 +      if (!DoneMTune) {
       
   512 +        if (SeenVIS3 && !DoneVIS3) {
       
   513 +          CC1Args.push_back(DriverArgs.MakeArgString("-target-feature"));
       
   514 +          CC1Args.push_back(DriverArgs.MakeArgString("+vis3"));
       
   515 +          DoneVIS3 = true;
       
   516 +          DoneVIS2 = true;
       
   517 +          DoneVIS = true;
       
   518 +        }
       
   519 +
       
   520 +        if (SeenVIS2 && !DoneVIS2) {
       
   521 +          CC1Args.push_back(DriverArgs.MakeArgString("-target-feature"));
       
   522 +          CC1Args.push_back(DriverArgs.MakeArgString("+vis2"));
       
   523 +          DoneVIS2 = true;
       
   524 +          DoneVIS = true;
       
   525 +        }
       
   526 +
       
   527 +        if (SeenVIS && !DoneVIS) {
       
   528 +          CC1Args.push_back(DriverArgs.MakeArgString("-target-feature"));
       
   529 +          CC1Args.push_back(DriverArgs.MakeArgString("+vis"));
       
   530 +          DoneVIS = true;
       
   531 +        }
       
   532 +
       
   533 +        DoneMTune = true;
       
   534 +      }
       
   535 +    }
       
   536 +  }
       
   537 +
       
   538 +  if (Arch == llvm::Triple::sparc || Arch == llvm::Triple::sparcv9) {
       
   539 +    if (Arg *A = DriverArgs.getLastArg(options::OPT_mvis)) {
       
   540 +      SeenVIS = !DoneVIS;
       
   541 +      if (!DoneVIS) {
       
   542 +        CC1Args.push_back(DriverArgs.MakeArgString("-target-feature"));
       
   543 +        CC1Args.push_back(DriverArgs.MakeArgString("+vis"));
       
   544 +        DoneVIS = true;
       
   545 +      }
       
   546 +    }
       
   547 +
       
   548 +    if (Arg *A = DriverArgs.getLastArg(options::OPT_mvis2)) {
       
   549 +      SeenVIS2 = !DoneVIS2;
       
   550 +      if (!DoneVIS2) {
       
   551 +        CC1Args.push_back(DriverArgs.MakeArgString("-target-feature"));
       
   552 +        CC1Args.push_back(DriverArgs.MakeArgString("+vis2"));
       
   553 +        DoneVIS2 = true;
       
   554 +        DoneVIS = true;
       
   555 +      }
       
   556 +    }
       
   557 +
       
   558 +    if (Arg *A = DriverArgs.getLastArg(options::OPT_mvis3)) {
       
   559 +      SeenVIS3 = !DoneVIS3;
       
   560 +      if (!DoneVIS3) {
       
   561 +        CC1Args.push_back(DriverArgs.MakeArgString("-target-feature"));
       
   562 +        CC1Args.push_back(DriverArgs.MakeArgString("+vis3"));
       
   563 +        DoneVIS3 = true;
       
   564 +        DoneVIS2 = true;
       
   565 +        DoneVIS = true;
       
   566 +      }
       
   567 +    }
       
   568 +  }
       
   569 +}
       
   570 +
       
   571 +void
       
   572 +Solaris::findGCCMajorMinor() const {
       
   573 +  // FIXME: Add 5.X after testing the ABI.
       
   574 +  static const char* const GCCMM[] = { "4.8", "4.9" };
       
   575 +
       
   576 +  const char* P;
       
   577 +  std::string Path;
       
   578 +
       
   579 +  Path.reserve(std::string::size_type(PATH_MAX));
       
   580 +
       
   581 +  for (int I = (llvm::array_lengthof(GCCMM) - 1); I >= 0; --I) {
       
   582 +    if ((P = GCCMM[I]) != NULL) {
       
   583 +      Path = GCCInstallDir;
       
   584 +      Path.append(P);
       
   585 +      Path.append("/");
       
   586 +
       
   587 +      if (llvm::sys::fs::exists(Path.c_str())) {
       
   588 +        GCCMajorMinor = P;
       
   589 +        break;
       
   590 +      }
       
   591 +    }
       
   592 +  }
       
   593 +}
       
   594 +
       
   595 +void
       
   596 +Solaris::findGCCMajorMinorMicro(const llvm::Triple& T) const {
       
   597 +  // FIXME: Add 5.X after testing the ABI.
       
   598 +  static const char* const GCCMMM[] = { "4.8.2", "4.9.3", "4.9.4" };
       
   599 +
       
   600 +  const char* P;
       
   601 +  std::string Path;
       
   602 +  std::string TripleString = llvm::sys::getDefaultTargetTriple();
       
   603 +  llvm::Triple::ArchType Arch = T.getArch();
       
   604 +
       
   605 +  // GCC4 on Solaris is multilib 32/64.
       
   606 +  // GCC5 (not supported here yet) on Solaris is multilib 64/32.
       
   607 +  if (GCCMajorMinor[0] == '4') {
       
   608 +    if (TripleString.find("x86_64") != std::string::npos)
       
   609 +      TripleString.replace(0U, 6U, std::string("i386"));
       
   610 +    else if (TripleString.find("sparcv9") != std::string::npos)
       
   611 +      TripleString.replace(0U, 7U, std::string("sparc"));
       
   612 +  }
       
   613 +
       
   614 +  Path.reserve(std::string::size_type(PATH_MAX));
       
   615 +
       
   616 +  for (int I = (llvm::array_lengthof(GCCMMM) - 1); I >= 0; --I) {
       
   617 +    if ((P = GCCMMM[I]) != NULL) {
       
   618 +      if ((P[0] == GCCMajorMinor[0]) && (P[2] == GCCMajorMinor[2])) {
       
   619 +        Path = GCCInstallDir;
       
   620 +        Path.append("/");
       
   621 +        Path.append(GCCMajorMinor);
       
   622 +        Path.append("/lib/gcc/");
       
   623 +        Path.append(TripleString);
       
   624 +        Path.append("/");
       
   625 +        Path.append(P);
       
   626 +
       
   627 +        if (llvm::sys::fs::exists(Path.c_str())) {
       
   628 +          std::string Test;
       
   629 +          // Check if this is a real GCC installation and not just
       
   630 +          // an empty directory tree
       
   631 +          switch (Arch) {
       
   632 +          case llvm::Triple::x86:
       
   633 +          case llvm::Triple::sparc:
       
   634 +            Test = Path + "/crtbegin.o";
       
   635 +            break;
       
   636 +          case llvm::Triple::x86_64:
       
   637 +            Test = Path + "/amd64/crtbegin.o";
       
   638 +            break;
       
   639 +          case llvm::Triple::sparcv9:
       
   640 +            Test = Path + "/sparcv9/crtbegin.o";
       
   641 +            break;
       
   642 +          default:
       
   643 +            break;
       
   644 +          }
       
   645 +
       
   646 +          if (llvm::sys::fs::exists(Test.c_str())) {
       
   647 +            GCCMajorMinorMicro = P;
       
   648 +            break;
       
   649 +          }
       
   650 +        }
       
   651 +      }
       
   652 +    }
       
   653 +  }
       
   654 +}
       
   655 +
       
   656 +void
       
   657 +Solaris::findSpecifiedGCCToolchain(const char *StartingPath,
       
   658 +                                   const llvm::Triple &Triple,
       
   659 +                                   const llvm::opt::ArgList &Args) const {
       
   660 +  DIR *TopLD = 0;
       
   661 +  DIR *LibLD = 0;
       
   662 +  DIR *GccLD = 0;
       
   663 +  DIR *TripleLD = 0;
       
   664 +  struct dirent *TopDE = 0;
       
   665 +  struct dirent *LibDE = 0;
       
   666 +  struct dirent *GccDE = 0;
       
   667 +  struct dirent *TripleDE = 0;
       
   668 +  std::string LibDir;
       
   669 +  std::string GccDir;
       
   670 +  std::string TripleDir;
       
   671 +  std::string TripleVersionDir;
       
   672 +  const char *DName;
       
   673 +
       
   674 +  assert(StartingPath && "Invalid GCC Toolchain starting search path!");
       
   675 +
       
   676 +  GCCMajorMinor = "";
       
   677 +  GCCMajorMinorMicro = "";
       
   678 +  UseSpecifiedGCCToolChainPath = false;
       
   679 +
       
   680 +  LibDir.reserve(std::string::size_type(PATH_MAX));
       
   681 +  GccDir.reserve(std::string::size_type(PATH_MAX));
       
   682 +  TripleDir.reserve(std::string::size_type(PATH_MAX));
       
   683 +  TripleVersionDir.reserve(std::string::size_type(PATH_MAX));
       
   684 +
       
   685 +  if (llvm::sys::fs::exists(StartingPath) &&
       
   686 +      llvm::sys::fs::is_directory(StartingPath)) {
       
   687 +    TopLD = opendir(StartingPath);
       
   688 +    assert(TopLD && "Cannot obtain a valid toplevel DIR handle!");
       
   689 +
       
   690 +    while ((TopDE = readdir(TopLD)) != NULL) {
       
   691 +      if (TopDE->d_name[0] == '.')
       
   692 +        continue;
       
   693 +
       
   694 +      DName = static_cast<const char*>(&TopDE->d_name[0]);
       
   695 +      if (std::strcmp(DName, "lib") == 0) {
       
   696 +        LibDir = StartingPath;
       
   697 +        LibDir.append("/");
       
   698 +        LibDir.append(DName);
       
   699 +
       
   700 +        if (!llvm::sys::fs::is_directory(LibDir.c_str()))
       
   701 +          continue;
       
   702 +
       
   703 +        LibLD = opendir(LibDir.c_str());
       
   704 +        assert(LibLD && "Could not obtain a valid lib DIR handle!");
       
   705 +
       
   706 +        while ((LibDE = readdir(LibLD)) != NULL) {
       
   707 +          if (LibDE->d_name[0] == '.')
       
   708 +            continue;
       
   709 +
       
   710 +          DName = static_cast<const char*>(&LibDE->d_name[0]);
       
   711 +          if (std::strcmp(DName, "gcc") == 0) {
       
   712 +            GccDir = LibDir;
       
   713 +            GccDir.append("/");
       
   714 +            GccDir.append(DName);
       
   715 +
       
   716 +            if (!llvm::sys::fs::is_directory(GccDir.c_str()))
       
   717 +              continue;
       
   718 +
       
   719 +            GccLD = opendir(GccDir.c_str());
       
   720 +            assert(GccLD && "Could not obtain a valid gcc DIR handle!");
       
   721 +
       
   722 +            while ((GccDE = readdir(GccLD)) != NULL) {
       
   723 +              if (GccDE->d_name[0] == '.')
       
   724 +                continue;
       
   725 +
       
   726 +              DName = static_cast<const char*>(&GccDE->d_name[0]);
       
   727 +              TripleDir = GccDir;
       
   728 +              TripleDir.append("/");
       
   729 +              TripleDir.append(DName);
       
   730 +
       
   731 +              if (!llvm::sys::fs::is_directory(TripleDir.c_str()))
       
   732 +                continue;
       
   733 +
       
   734 +              if ((std::strncmp(DName, "sparc", 5) == 0) ||
       
   735 +                  (std::strncmp(DName, "i386", 4) == 0) ||
       
   736 +                  (std::strncmp(DName, "sparcv9", 7) == 0) ||
       
   737 +                  (std::strncmp(DName, "x86_64", 6) == 0)) {
       
   738 +                TripleLD = opendir(TripleDir.c_str());
       
   739 +                assert(TripleLD &&
       
   740 +                       "Could not obtain a valid Triple DIR handle!");
       
   741 +
       
   742 +                while ((TripleDE = readdir(TripleLD)) != NULL) {
       
   743 +                  if (TripleDE->d_name[0] == '.')
       
   744 +                    continue;
       
   745 +
       
   746 +                  DName = static_cast<const char*>(&TripleDE->d_name[0]);
       
   747 +                  TripleVersionDir = TripleDir;
       
   748 +                  TripleVersionDir.append("/");
       
   749 +                  TripleVersionDir.append(DName);
       
   750 +
       
   751 +                  if (!llvm::sys::fs::is_directory(TripleVersionDir.c_str()))
       
   752 +                    continue;
       
   753 +
       
   754 +                  if ((std::isdigit(DName[0])) && (DName[1] == '.') &&
       
   755 +                      (std::isdigit(DName[2])) && (DName[3] == '.') &&
       
   756 +                      (std::isdigit(DName[4])) && (DName[5] == '\0')) {
       
   757 +                    GCCMajorMinorMicro = DName;
       
   758 +                    GCCMajorMinor = GCCMajorMinorMicro.substr(0, 3);
       
   759 +                    UseSpecifiedGCCToolChainPath = true;
       
   760 +                    goto done;
       
   761 +                  }
       
   762 +                }
       
   763 +              }
       
   764 +            }
       
   765 +          }
       
   766 +        }
       
   767 +      }
       
   768 +    }
       
   769 +  }
       
   770 +
       
   771 +done:
       
   772 +  if (TripleLD) {
       
   773 +    rewinddir(TripleLD);
       
   774 +    closedir(TripleLD);
       
   775 +  }
       
   776 +
       
   777 +  if (GccLD) {
       
   778 +    rewinddir(GccLD);
       
   779 +    closedir(GccLD);
       
   780 +  }
       
   781 +
       
   782 +  if (LibLD) {
       
   783 +    rewinddir(LibLD);
       
   784 +    closedir(LibLD);
       
   785 +  }
       
   786 +
       
   787 +  if (TopLD) {
       
   788 +    rewinddir(TopLD);
       
   789 +    closedir(TopLD);
       
   790 +  }
       
   791 +}
       
   792 +
       
   793 +void
       
   794 +Solaris::findGCCIncludeDirs(const llvm::Triple &Triple,
       
   795 +                            const llvm::opt::ArgList &Args) const {
       
   796 +  std::string GCCInstallPath;
       
   797 +  if (UseSpecifiedGCCToolChainPath)
       
   798 +    GCCInstallPath = GCCInstallDir;
       
   799 +  else
       
   800 +    GCCInstallPath = GCCInstallDir + GCCMajorMinor;
       
   801 +
       
   802 +  std::string GCCIncludeDir =
       
   803 +    GCCInstallPath + "/include/c++/" + GCCMajorMinorMicro;
       
   804 +  GCCIncludeDirs.push_back(GCCIncludeDir);
       
   805 +
       
   806 +  llvm::Triple::ArchType Arch = Triple.getArch();
       
   807 +  GCCIncludeDir += "/";
       
   808 +
       
   809 +  switch (Arch) {
       
   810 +  case llvm::Triple::x86:
       
   811 +    GCCIncludeDir += Triple.getTriple();
       
   812 +    if (Arg *A = Args.getLastArg(options::OPT_m64))
       
   813 +      GCCIncludeDir += "/amd64";
       
   814 +    break;
       
   815 +  case llvm::Triple::sparc:
       
   816 +    GCCIncludeDir += Triple.getTriple();
       
   817 +    if (Arg *A = Args.getLastArg(options::OPT_m64))
       
   818 +      GCCIncludeDir += "/sparcv9";
       
   819 +    break;
       
   820 +  case llvm::Triple::x86_64:
       
   821 +    GCCIncludeDir += "i386-pc-";
       
   822 +    GCCIncludeDir += Triple.getOSName();
       
   823 +    if (Arg *A = Args.getLastArg(options::OPT_m64))
       
   824 +      GCCIncludeDir += "/amd64";
       
   825 +    break;
       
   826 +  case llvm::Triple::sparcv9:
       
   827 +    GCCIncludeDir += "sparc-sun-";
       
   828 +    GCCIncludeDir += Triple.getOSName();
       
   829 +    if (Arg *A = Args.getLastArg(options::OPT_m64))
       
   830 +      GCCIncludeDir += "/sparcv9";
       
   831 +    break;
       
   832 +  default:
       
   833 +    getDriver().Diag(diag::err_target_unsupported_arch)
       
   834 +      << Triple.getArchName() << Triple.getTriple();
       
   835 +    break;
       
   836 +  }
       
   837 +
       
   838 +  GCCIncludeDirs.push_back(GCCIncludeDir);
       
   839 +
       
   840 +  GCCIncludeDir = GCCInstallPath + "/include/c++/" +
       
   841 +    GCCMajorMinorMicro + "/backward";
       
   842 +
       
   843 +  GCCIncludeDirs.push_back(GCCIncludeDir);
       
   844 +}
       
   845 +
       
   846 +void
       
   847 +Solaris::findGCCInternalLibDir(const llvm::Triple &Triple,
       
   848 +                               const llvm::opt::ArgList &Args) const {
       
   849 +  std::string GCCInstallPath;
       
   850 +  if (UseSpecifiedGCCToolChainPath)
       
   851 +    GCCInstallPath = GCCInstallDir;
       
   852 +  else
       
   853 +    GCCInstallPath = GCCInstallDir + GCCMajorMinor;
       
   854 +
       
   855 +  GCCInternalLibDir = GCCInstallPath + "/lib/gcc/";
       
   856 +
       
   857 +  llvm::Triple::ArchType Arch = Triple.getArch();
       
   858 +
       
   859 +  switch (Arch) {
       
   860 +  case llvm::Triple::x86:
       
   861 +    GCCInternalLibDir += Triple.getTriple();
       
   862 +    GCCInternalLibDir += "/";
       
   863 +    GCCInternalLibDir += GCCMajorMinorMicro;
       
   864 +    if (Arg *A = Args.getLastArg(options::OPT_m64)) {
       
   865 +      GCCInternalMultiLibDir = GCCInternalLibDir;
       
   866 +      GCCInternalLibDir += "/amd64";
       
   867 +    } else if (Arg *A = Args.getLastArg(options::OPT_m32)) {
       
   868 +      GCCInternalMultiLibDir = GCCInternalLibDir;
       
   869 +      GCCInternalMultiLibDir += "/amd64";
       
   870 +    } else {
       
   871 +      GCCInternalMultiLibDir = GCCInternalLibDir;
       
   872 +      GCCInternalMultiLibDir += "/amd64";
       
   873 +    }
       
   874 +
       
   875 +    break;
       
   876 +  case llvm::Triple::sparc:
       
   877 +    GCCInternalLibDir += Triple.getTriple();
       
   878 +    GCCInternalLibDir += "/";
       
   879 +    GCCInternalLibDir += GCCMajorMinorMicro;
       
   880 +    if (Arg *A = Args.getLastArg(options::OPT_m64)) {
       
   881 +      GCCInternalMultiLibDir = GCCInternalLibDir;
       
   882 +      GCCInternalLibDir += "/sparcv9";
       
   883 +    } else if (Arg *A = Args.getLastArg(options::OPT_m32)) {
       
   884 +      GCCInternalMultiLibDir = GCCInternalLibDir;
       
   885 +      GCCInternalMultiLibDir += "/sparcv9";
       
   886 +    } else {
       
   887 +      GCCInternalMultiLibDir = GCCInternalLibDir;
       
   888 +      GCCInternalMultiLibDir += "/sparcv9";
       
   889 +    }
       
   890 +    break;
       
   891 +  case llvm::Triple::x86_64:
       
   892 +    GCCInternalLibDir += "i386-pc-";
       
   893 +    GCCInternalLibDir += Triple.getOSName();
       
   894 +    GCCInternalLibDir += "/";
       
   895 +    GCCInternalLibDir += GCCMajorMinorMicro;
       
   896 +    GCCInternalMultiLibDir = GCCInternalLibDir;
       
   897 +    if (Arg *A = Args.getLastArg(options::OPT_m64))
       
   898 +      GCCInternalLibDir += "/amd64";
       
   899 +    else if (Arg *A = Args.getLastArg(options::OPT_m32))
       
   900 +      GCCInternalMultiLibDir += "/amd64";
       
   901 +    else
       
   902 +      GCCInternalLibDir += "/amd64";
       
   903 +    break;
       
   904 +  case llvm::Triple::sparcv9:
       
   905 +    GCCInternalLibDir += "sparc-sun-";
       
   906 +    GCCInternalLibDir += Triple.getOSName();
       
   907 +    GCCInternalLibDir += "/";
       
   908 +    GCCInternalLibDir += GCCMajorMinorMicro;
       
   909 +    GCCInternalMultiLibDir = GCCInternalLibDir;
       
   910 +    if (Arg *A = Args.getLastArg(options::OPT_m64))
       
   911 +      GCCInternalLibDir += "/sparcv9";
       
   912 +    else if (Arg *A = Args.getLastArg(options::OPT_m32))
       
   913 +      GCCInternalMultiLibDir += "/sparcv9";
       
   914 +    else
       
   915 +      GCCInternalLibDir += "/sparcv9";
       
   916 +    break;
       
   917 +  default:
       
   918 +    getDriver().Diag(diag::err_target_unsupported_arch)
       
   919 +      << Triple.getArchName() << Triple.getTriple();
       
   920 +    break;
       
   921 +  }
       
   922 +}
       
   923 +
       
   924 +
       
   925 +void
       
   926 +Solaris::print(raw_ostream &OS) const {
       
   927 +  OS << "UseGnuAs: " << (UseGnuAs ? "true" : "false") << "\n";
       
   928 +  OS << "UseGnuLd: " << (UseGnuLd ? "true" : "false") << "\n";
       
   929 +  OS << "UseGoldLd: " << (UseGoldLd ? "true" : "false") << "\n";
       
   930 +  OS << "UseSunLd: " << (UseSunLd ? "true" : "false") << "\n";
       
   931 +  OS << "UseMediatedGCCToolChainPath: "
       
   932 +    << (UseMediatedGCCToolChainPath ? "true" : "false") << "\n";
       
   933 +  OS << "UseSpecifiedGCCToolChainPath: "
       
   934 +    << (UseSpecifiedGCCToolChainPath ? "true" : "false") << "\n";
       
   935 +  OS << "GCCInstallDir: " << GCCInstallDir.c_str() << "\n";
       
   936 +  OS << "GCCMajorMinor: " << GCCMajorMinor.c_str() << "\n";
       
   937 +  OS << "GCCMajorMinorMicro: " << GCCMajorMinorMicro.c_str() << "\n";
       
   938 +  OS << "GCCInternalLibDir: " << GCCInternalLibDir.c_str() << "\n";
       
   939 +  OS << "GCCInternalMultiLibDir: " << GCCInternalMultiLibDir.c_str() << "\n";
       
   940 +  OS << "GCCIncludeDirs: ";
       
   941 +
       
   942 +  if (GCCIncludeDirs.size()) {
       
   943 +    std::string IncludePath;
       
   944 +    for (std::vector<std::string>::const_iterator B = GCCIncludeDirs.begin(),
       
   945 +         E = GCCIncludeDirs.end(); B != E; ++B) {
       
   946 +      IncludePath = "-I";
       
   947 +      IncludePath += (*B);
       
   948 +      OS << IncludePath.c_str() << " ";
       
   949 +    }
       
   950 +
       
   951 +    OS << "\n";
       
   952 +  }
       
   953 +
       
   954 +  OS << "Assembler: " << Assembler.c_str() << "\n";
       
   955 +  OS << "Linker: " << Linker.c_str() << "\n";
       
   956 +  OS << "mtune: " << mtune.c_str() << "\n";
       
   957 +  OS << "march: " << march.c_str() << "\n";
       
   958 +  OS << "mcpu: " << mcpu.c_str() << "\n";
       
   959 +
       
   960 +  if (ExtraOpts.size()) {
       
   961 +    OS << "ExtraOpts: ";
       
   962 +    for (std::vector<std::string>::const_iterator B = ExtraOpts.begin(),
       
   963 +         E = ExtraOpts.end(); B != E; ++B) {
       
   964 +      OS << (*B).c_str() << " ";
       
   965 +    }
       
   966 +
       
   967 +    OS << "\n";
       
   968 +  }
       
   969 +
       
   970 +  OS << "Valid: " << (IsValid ? "true" : "false") << "\n";
       
   971 +}
       
   972 +
       
   973 +Tool *Solaris::buildAssembler() const {
       
   974 +  return new tools::solaris::Assembler(*this);
       
   975 +}
       
   976 +
       
   977 +Tool *Solaris::buildLinker() const {
       
   978 +  return new tools::solaris::Linker(*this);
       
   979 +}
       
   980 +
       
   981 +void Solaris::validate() {
       
   982 +  IsValid = llvm::sys::fs::exists(GCCInstallDir.c_str());
       
   983 +  if (!IsValid) return;
       
   984 +  IsValid = llvm::sys::fs::exists(GCCInternalLibDir.c_str());
       
   985 +  if (!IsValid) return;
       
   986 +  IsValid = llvm::sys::fs::exists(GCCInternalMultiLibDir.c_str());
       
   987 +  if (!IsValid) return;
       
   988 +
       
   989 +  for (std::vector<std::string>::const_iterator B = GCCIncludeDirs.begin(),
       
   990 +       E = GCCIncludeDirs.end(); B != E; ++B) {
       
   991 +    IsValid = llvm::sys::fs::exists((*B).c_str());
       
   992 +    if (!IsValid) return;
       
   993    }
       
   994  }
       
   995  
       
   996 @@ -3404,6 +4137,27 @@
       
   997    UbuntuVivid,
       
   998    UbuntuWily,
       
   999    UbuntuXenial,
       
  1000 +  Solaris_11,
       
  1001 +  Solaris_11_1,
       
  1002 +  Solaris_11_2,
       
  1003 +  Solaris_11_3,
       
  1004 +  Solaris_11_4,
       
  1005 +  Solaris_11_5,
       
  1006 +  Solaris_11_6,
       
  1007 +  Solaris_11_7,
       
  1008 +  Solaris_11_8,
       
  1009 +  Solaris_11_9,
       
  1010 +  Solaris_12,
       
  1011 +  Solaris_12_1,
       
  1012 +  Solaris_12_2,
       
  1013 +  Solaris_12_3,
       
  1014 +  Solaris_12_4,
       
  1015 +  Solaris_12_5,
       
  1016 +  Solaris_12_6,
       
  1017 +  Solaris_12_7,
       
  1018 +  Solaris_12_8,
       
  1019 +  Solaris_12_9,
       
  1020 +  Solaris_13,
       
  1021    UnknownDistro
       
  1022  };
       
  1023  
       
  1024 @@ -3421,6 +4175,10 @@
       
  1025    return Distro >= UbuntuHardy && Distro <= UbuntuXenial;
       
  1026  }
       
  1027  
       
  1028 +static bool IsSolaris(enum Distro Distro) {
       
  1029 +  return Distro >= Solaris_11 && Distro <= Solaris_13;
       
  1030 +}
       
  1031 +
       
  1032  static Distro DetectDistro(const Driver &D, llvm::Triple::ArchType Arch) {
       
  1033    llvm::ErrorOr<std::unique_ptr<llvm::MemoryBuffer>> File =
       
  1034        llvm::MemoryBuffer::getFile("/etc/lsb-release");
       
  1035 @@ -3488,6 +4246,59 @@
       
  1036      return UnknownDistro;
       
  1037    }
       
  1038  
       
  1039 +  File = llvm::MemoryBuffer::getFile("/etc/release");
       
  1040 +  if (File) {
       
  1041 +    StringRef Data = File.get()->getBuffer();
       
  1042 +    SmallVector<StringRef, 8> Lines;
       
  1043 +    Data.split(Lines, "\n");
       
  1044 +    for (unsigned I = 0, S = Lines.size(); I != S; ++I) {
       
  1045 +      if (Lines[I].find("Oracle Solaris") != std::string::npos) {
       
  1046 +        if (Lines[I].find("Solaris 11.0") != std::string::npos)
       
  1047 +          return Solaris_11;
       
  1048 +        else if (Lines[I].find("Solaris 11.1") != std::string::npos)
       
  1049 +          return Solaris_11_1;
       
  1050 +        else if (Lines[I].find("Solaris 11.2") != std::string::npos)
       
  1051 +          return Solaris_11_2;
       
  1052 +        else if (Lines[I].find("Solaris 11.3") != std::string::npos)
       
  1053 +          return Solaris_11_3;
       
  1054 +        else if (Lines[I].find("Solaris 11.4") != std::string::npos)
       
  1055 +          return Solaris_11_4;
       
  1056 +        else if (Lines[I].find("Solaris 11.5") != std::string::npos)
       
  1057 +          return Solaris_11_5;
       
  1058 +        else if (Lines[I].find("Solaris 11.6") != std::string::npos)
       
  1059 +          return Solaris_11_6;
       
  1060 +        else if (Lines[I].find("Solaris 11.7") != std::string::npos)
       
  1061 +          return Solaris_11_7;
       
  1062 +        else if (Lines[I].find("Solaris 11.8") != std::string::npos)
       
  1063 +          return Solaris_11_8;
       
  1064 +        else if (Lines[I].find("Solaris 11.9") != std::string::npos)
       
  1065 +          return Solaris_11_9;
       
  1066 +        else if (Lines[I].find("Solaris 12.0") != std::string::npos)
       
  1067 +          return Solaris_12;
       
  1068 +        else if (Lines[I].find("Solaris 12.1") != std::string::npos)
       
  1069 +          return Solaris_12_1;
       
  1070 +        else if (Lines[I].find("Solaris 12.2") != std::string::npos)
       
  1071 +          return Solaris_12_2;
       
  1072 +        else if (Lines[I].find("Solaris 12.3") != std::string::npos)
       
  1073 +          return Solaris_12_3;
       
  1074 +        else if (Lines[I].find("Solaris 12.4") != std::string::npos)
       
  1075 +          return Solaris_12_4;
       
  1076 +        else if (Lines[I].find("Solaris 12.5") != std::string::npos)
       
  1077 +          return Solaris_12_5;
       
  1078 +        else if (Lines[I].find("Solaris 12.6") != std::string::npos)
       
  1079 +          return Solaris_12_6;
       
  1080 +        else if (Lines[I].find("Solaris 12.7") != std::string::npos)
       
  1081 +          return Solaris_12_7;
       
  1082 +        else if (Lines[I].find("Solaris 12.8") != std::string::npos)
       
  1083 +          return Solaris_12_8;
       
  1084 +        else if (Lines[I].find("Solaris 12.9") != std::string::npos)
       
  1085 +          return Solaris_12_9;
       
  1086 +      }
       
  1087 +    }
       
  1088 +
       
  1089 +    return UnknownDistro;
       
  1090 +  }
       
  1091 +
       
  1092    if (D.getVFS().exists("/etc/SuSE-release"))
       
  1093      return OpenSUSE;
       
  1094  
       
  1095 ###
       
  1096 --- tools/clang/lib/Driver/ToolChains.h	2016-02-16 14:56:48.000000000 -0500
       
  1097 +++ tools/clang/lib/Driver/ToolChains.h	2016-05-08 23:19:20.571431701 -0400
       
  1098 @@ -615,24 +615,111 @@
       
  1099    Tool *buildLinker() const override;
       
  1100  };
       
  1101  
       
  1102 -class LLVM_LIBRARY_VISIBILITY Solaris : public Generic_GCC {
       
  1103 +class LLVM_LIBRARY_VISIBILITY Solaris : public Generic_ELF {
       
  1104  public:
       
  1105    Solaris(const Driver &D, const llvm::Triple &Triple,
       
  1106            const llvm::opt::ArgList &Args);
       
  1107  
       
  1108 -  bool IsIntegratedAssemblerDefault() const override { return true; }
       
  1109 +  bool IsIntegratedAssemblerDefault() const override { return !UseGnuAs; }
       
  1110  
       
  1111 -  void AddClangCXXStdlibIncludeArgs(
       
  1112 -      const llvm::opt::ArgList &DriverArgs,
       
  1113 -      llvm::opt::ArgStringList &CC1Args) const override;
       
  1114 +  std::string computeSysRoot() const;
       
  1115  
       
  1116 -  unsigned GetDefaultDwarfVersion() const override { return 2; }
       
  1117 +  bool addLibStdCXXIncludePaths(Twine Base, Twine Suffix,
       
  1118 +                                StringRef GCCTriple,
       
  1119 +                                StringRef GCCMultiarchTriple,
       
  1120 +                                StringRef TargetMultiarchTriple,
       
  1121 +                                Twine IncludeSuffix,
       
  1122 +                                const llvm::opt::ArgList &DriverArgs,
       
  1123 +                                llvm::opt::ArgStringList &CC1Args) const;
       
  1124 +
       
  1125 +  void addLibStdCXXIncludePaths(Twine Base, Twine TargetArchDir,
       
  1126 +                                const llvm::opt::ArgList &DriverArgs,
       
  1127 +                                llvm::opt::ArgStringList &CC1Args) const;
       
  1128 +
       
  1129 +  void AddClangCXXStdlibIncludeArgs(const llvm::opt::ArgList &DriverArgs,
       
  1130 +                                    llvm::opt::ArgStringList &CC1Args) const override;
       
  1131 +
       
  1132 +  void AddClangSystemIncludeArgs(const llvm::opt::ArgList &DriverArgs,
       
  1133 +                                 llvm::opt::ArgStringList &CC1Args) const override;
       
  1134 +
       
  1135 +  void addClangTargetOptions(const llvm::opt::ArgList &DriverArgs,
       
  1136 +                             llvm::opt::ArgStringList &CC1Args) const override;
       
  1137 +
       
  1138 +  void findGCCMajorMinor() const;
       
  1139 +  void findGCCMajorMinorMicro(const llvm::Triple &Triple) const;
       
  1140 +  void findGCCIncludeDirs(const llvm::Triple &Triple,
       
  1141 +                          const llvm::opt::ArgList &Args) const;
       
  1142 +  void findGCCInternalLibDir(const llvm::Triple &Triple,
       
  1143 +                             const llvm::opt::ArgList &Args) const;
       
  1144 +  void findSpecifiedGCCToolchain(const char *StartingPath,
       
  1145 +                                 const llvm::Triple &Triple,
       
  1146 +                                 const llvm::opt::ArgList &Args) const;
       
  1147 +
       
  1148 +  StringRef getAssembler() const { return Assembler.c_str(); }
       
  1149 +  StringRef getLinker() const { return Linker.c_str(); }
       
  1150 +  StringRef getGCCInstallDir() const { return GCCInstallDir.c_str(); }
       
  1151 +  StringRef getGCCMajorMinor() const { return GCCMajorMinor.c_str(); }
       
  1152 +  StringRef getMArch() const { return march.c_str(); }
       
  1153 +  StringRef getMTune() const { return mtune.c_str(); }
       
  1154 +  StringRef getMCpu() const { return mcpu.c_str(); }
       
  1155 +  StringRef getGCCInternalLibDir() const { return GCCInternalLibDir; }
       
  1156 +
       
  1157 +  StringRef getGCCInternalMultiLibDir() const {
       
  1158 +    return GCCInternalMultiLibDir;
       
  1159 +  }
       
  1160 +
       
  1161 +  StringRef getGCCMajorMinorMicro() const {
       
  1162 +    return GCCMajorMinorMicro.c_str();
       
  1163 +  }
       
  1164 +
       
  1165 +  const std::vector<std::string> &getGCCIncludeDirs() const {
       
  1166 +    return GCCIncludeDirs;
       
  1167 +  }
       
  1168 +
       
  1169 +  const std::vector<std::string> &getExtraOpts() const {
       
  1170 +    return ExtraOpts;
       
  1171 +  }
       
  1172 +
       
  1173 +  bool isValid() const { return IsValid; }
       
  1174 +
       
  1175 +  void print(raw_ostream &OS) const;
       
  1176 +
       
  1177 +  unsigned GetDefaultDwarfVersion() const override { return 4; }
       
  1178  
       
  1179  protected:
       
  1180    Tool *buildAssembler() const override;
       
  1181    Tool *buildLinker() const override;
       
  1182 +  void validate();
       
  1183 +
       
  1184 +private:
       
  1185 +  bool UseGnuAs;
       
  1186 +  bool UseGnuLd;
       
  1187 +  bool UseGoldLd;
       
  1188 +  bool UseSunLd;
       
  1189 +  mutable bool UseMediatedGCCToolChainPath;
       
  1190 +  mutable bool UseSpecifiedGCCToolChainPath;
       
  1191 +  bool IsValid;
       
  1192 +
       
  1193 +protected:
       
  1194 +  mutable std::string GCCInstallDir;
       
  1195 +  mutable std::string GCCMajorMinor;
       
  1196 +  mutable std::string GCCMajorMinorMicro;
       
  1197 +  mutable std::string GCCInternalLibDir;
       
  1198 +  mutable std::string GCCInternalMultiLibDir;
       
  1199 +  mutable std::vector<std::string> GCCIncludeDirs;
       
  1200 +
       
  1201 +  mutable std::string Assembler;
       
  1202 +  mutable std::string Linker;
       
  1203 +  mutable std::string mtune;
       
  1204 +  mutable std::string march;
       
  1205 +  mutable std::string mcpu;
       
  1206 +
       
  1207 +  mutable std::vector<std::string> ExtraOpts;
       
  1208 +  static const char *MediatedGCCToolChainPath;
       
  1209 +  static bool SupportsClangLibCPlusPlus;
       
  1210  };
       
  1211  
       
  1212 +
       
  1213  class LLVM_LIBRARY_VISIBILITY MinGW : public ToolChain {
       
  1214  public:
       
  1215    MinGW(const Driver &D, const llvm::Triple &Triple,
       
  1216 ###
       
  1217 --- tools/clang/lib/Driver/Tools.cpp	2016-02-12 14:51:41.000000000 -0800
       
  1218 +++ tools/clang/lib/Driver/Tools.cpp	2016-07-18 19:13:48.364415520 -0700
       
  1219 @@ -43,15 +43,22 @@
       
  1220  #include "llvm/Support/raw_ostream.h"
       
  1221  #include "llvm/Support/TargetParser.h"
       
  1222  
       
  1223 -#ifdef LLVM_ON_UNIX
       
  1224 -#include <unistd.h> // For getuid().
       
  1225 -#endif
       
  1226 -
       
  1227  using namespace clang::driver;
       
  1228  using namespace clang::driver::tools;
       
  1229  using namespace clang;
       
  1230  using namespace llvm::opt;
       
  1231  
       
  1232 +#ifdef LLVM_ON_UNIX
       
  1233 +#include <unistd.h> // For getuid().
       
  1234 +#endif
       
  1235 +
       
  1236 +#include <cstdlib>
       
  1237 +#include <climits>
       
  1238 +
       
  1239 +static std::tuple<llvm::Reloc::Model, unsigned, bool>
       
  1240 +ParsePICArgs(const ToolChain &ToolChain, const llvm::Triple &Triple,
       
  1241 +             const ArgList &Args);
       
  1242 +
       
  1243  static void handleTargetFeaturesGroup(const ArgList &Args,
       
  1244                                        std::vector<const char *> &Features,
       
  1245                                        OptSpecifier Group) {
       
  1246 @@ -74,11 +81,15 @@
       
  1247                                           const llvm::Triple &Triple) {
       
  1248    if (Triple.getArch() == llvm::Triple::sparcv9) {
       
  1249      return llvm::StringSwitch<const char *>(Name)
       
  1250 +          .Case("v9", "-Av9")
       
  1251 +          .Case("ultrasparc", "-Av9a")
       
  1252 +          .Case("ultrasparc2", "-Av9a")
       
  1253 +          .Case("ultrasparc3", "-Av9b")
       
  1254            .Case("niagara", "-Av9b")
       
  1255            .Case("niagara2", "-Av9b")
       
  1256            .Case("niagara3", "-Av9d")
       
  1257            .Case("niagara4", "-Av9d")
       
  1258 -          .Default("-Av9");
       
  1259 +          .Default("-Av9a");
       
  1260    } else {
       
  1261      return llvm::StringSwitch<const char *>(Name)
       
  1262            .Case("v8", "-Av8")
       
  1263 @@ -89,17 +100,23 @@
       
  1264            .Case("sparclite86x", "-Asparclite")
       
  1265            .Case("sparclet", "-Asparclet")
       
  1266            .Case("tsc701", "-Asparclet")
       
  1267 -          .Case("v9", "-Av8plus")
       
  1268 -          .Case("ultrasparc", "-Av8plus")
       
  1269 -          .Case("ultrasparc3", "-Av8plus")
       
  1270 +          .Case("ultrasparc", "-Av8plusa")
       
  1271 +          .Case("ultrasparc2", "-Av8plusa")
       
  1272 +          .Case("ultrasparc3", "-Av8plusb")
       
  1273            .Case("niagara", "-Av8plusb")
       
  1274            .Case("niagara2", "-Av8plusb")
       
  1275            .Case("niagara3", "-Av8plusd")
       
  1276            .Case("niagara4", "-Av8plusd")
       
  1277 -          .Default("-Av8");
       
  1278 +          .Default("-Av8plusa");
       
  1279    }
       
  1280  }
       
  1281  
       
  1282 +static void AddLibgcc(const llvm::Triple &Triple, const Driver &D,
       
  1283 +                      ArgStringList &CmdArgs, const ArgList &Args);
       
  1284 +
       
  1285 +static void AddLibgcc(const Driver &D, ArgStringList &CmdArgs,
       
  1286 +                      const ArgList &Args, const std::string& Exec);
       
  1287 +
       
  1288  /// CheckPreprocessingOptions - Perform some validation of preprocessing
       
  1289  /// arguments that is shared with gcc.
       
  1290  static void CheckPreprocessingOptions(const Driver &D, const ArgList &Args) {
       
  1291 @@ -266,6 +283,27 @@
       
  1292      addDirectoryList(Args, CmdArgs, "-L", "LIBRARY_PATH");
       
  1293  }
       
  1294  
       
  1295 +static void AddAssemblerKPIC(const ToolChain &ToolChain, const ArgList &Args,
       
  1296 +                             ArgStringList &CmdArgs) {
       
  1297 +  llvm::Reloc::Model RelocationModel;
       
  1298 +  unsigned PICLevel = 1;
       
  1299 +  bool IsPIE = false;
       
  1300 +
       
  1301 +  std::tie(RelocationModel, PICLevel, IsPIE) =
       
  1302 +    ParsePICArgs(ToolChain, ToolChain.getTriple(), Args);
       
  1303 +
       
  1304 +  if (ToolChain.getTriple().getOS() == llvm::Triple::Solaris) {
       
  1305 +    if ((RelocationModel != llvm::Reloc::Static) &&
       
  1306 +        (RelocationModel != llvm::Reloc::DynamicNoPIC))
       
  1307 +      CmdArgs.push_back("-KPIC");
       
  1308 +
       
  1309 +    return;
       
  1310 +  }
       
  1311 +
       
  1312 +  if (RelocationModel != llvm::Reloc::Static)
       
  1313 +    CmdArgs.push_back("-KPIC");
       
  1314 +}
       
  1315 +
       
  1316  /// \brief Determine whether Objective-C automated reference counting is
       
  1317  /// enabled.
       
  1318  static bool isObjCAutoRefCount(const ArgList &Args) {
       
  1319 @@ -1601,8 +1639,127 @@
       
  1320    }
       
  1321  }
       
  1322  
       
  1323 -static const char *getX86TargetCPU(const ArgList &Args,
       
  1324 -                                   const llvm::Triple &Triple) {
       
  1325 +const char *sparc::getSparcTargetCPU(const llvm::opt::ArgList &Args,
       
  1326 +                                     const llvm::Triple &Triple) {
       
  1327 +  if (const Arg *A = Args.getLastArg(options::OPT_march_EQ)) {
       
  1328 +    StringRef AV = A->getValue();
       
  1329 +    if (AV == "native") {
       
  1330 +      std::string CPU = llvm::sys::getHostCPUName().str();
       
  1331 +      if (CPU.find("UltraSPARC-IV") != std::string::npos)
       
  1332 +        return Triple.getArch() == llvm::Triple::sparcv9 ?  "v9c" : "v8plusc";
       
  1333 +      else if (CPU.find("UltraSPARC-III") != std::string::npos)
       
  1334 +        return Triple.getArch() == llvm::Triple::sparcv9 ?  "v9b" : "v8plusb";
       
  1335 +      else if (CPU.find("UltraSPARC-II") != std::string::npos)
       
  1336 +        return Triple.getArch() == llvm::Triple::sparcv9 ?  "v9a" : "v8plusa";
       
  1337 +      else if (CPU.find("UltraSPARC-I") != std::string::npos)
       
  1338 +        return Triple.getArch() == llvm::Triple::sparcv9 ?  "v9" : "v8plus";
       
  1339 +      else if (CPU.find("SPARC-T4") != std::string::npos)
       
  1340 +        return Triple.getArch() == llvm::Triple::sparcv9 ?  "v9v" : "v8plusv";
       
  1341 +      else if (CPU.find("SPARC-T5") != std::string::npos)
       
  1342 +        return Triple.getArch() == llvm::Triple::sparcv9 ?  "v9v" : "v8plusv";
       
  1343 +      else if (CPU.find("SPARC-T6") != std::string::npos)
       
  1344 +        return Triple.getArch() == llvm::Triple::sparcv9 ?  "v9v" : "v8plusv";
       
  1345 +      else if (CPU.find("SPARC-T7") != std::string::npos)
       
  1346 +        return Triple.getArch() == llvm::Triple::sparcv9 ?  "v9v" : "v8plusv";
       
  1347 +      else if (CPU.find("SPARC-M4") != std::string::npos)
       
  1348 +        return Triple.getArch() == llvm::Triple::sparcv9 ?  "v9v" : "v8plusv";
       
  1349 +      else if (CPU.find("SPARC-M5") != std::string::npos)
       
  1350 +        return Triple.getArch() == llvm::Triple::sparcv9 ?  "v9m" : "v8plusm";
       
  1351 +      else if (CPU.find("SPARC-M6") != std::string::npos)
       
  1352 +        return Triple.getArch() == llvm::Triple::sparcv9 ?  "v9m" : "v8plusm";
       
  1353 +      else if (CPU.find("SPARC-M7") != std::string::npos)
       
  1354 +        return Triple.getArch() == llvm::Triple::sparcv9 ?  "v9m" : "v8plusm";
       
  1355 +    } else if (AV == "ultrasparc") {
       
  1356 +      return Triple.getArch() == llvm::Triple::sparcv9 ?  "v9a" : "v8plusa";
       
  1357 +    } else if (AV == "ultrasparc2") {
       
  1358 +      return Triple.getArch() == llvm::Triple::sparcv9 ?  "v9a" : "v8plusa";
       
  1359 +    } else if (AV == "ultrasparc3") {
       
  1360 +      return Triple.getArch() == llvm::Triple::sparcv9 ?  "v9b" : "v8plusb";
       
  1361 +    } else if (AV == "ultrasparc4") {
       
  1362 +      return Triple.getArch() == llvm::Triple::sparcv9 ?  "v9c" : "v8plusc";
       
  1363 +    } else if (AV == "niagara") {
       
  1364 +      return Triple.getArch() == llvm::Triple::sparcv9 ?  "v9b" : "v8plusb";
       
  1365 +    } else if (AV == "niagara2") {
       
  1366 +      return Triple.getArch() == llvm::Triple::sparcv9 ?  "v9b" : "v8plusb";
       
  1367 +    } else if (AV == "niagara3") {
       
  1368 +      return Triple.getArch() == llvm::Triple::sparcv9 ?  "v9b" : "v8plusb";
       
  1369 +    } else if (AV == "niagara4") {
       
  1370 +      return Triple.getArch() == llvm::Triple::sparcv9 ?  "v9b" : "v8plusb";
       
  1371 +    } else if (AV == "sparc4") {
       
  1372 +      return "sparc4";
       
  1373 +    } else if (AV == "sparc5") {
       
  1374 +      return "sparc5";
       
  1375 +    } else if (AV == "generic") {
       
  1376 +      return Triple.getArch() == llvm::Triple::sparcv9 ?  "v9a" : "v8plusa";
       
  1377 +    } else if (AV == "generic32") {
       
  1378 +      return "v8plusa";
       
  1379 +    } else if (AV == "generic64") {
       
  1380 +      return "v9a";
       
  1381 +    }
       
  1382 +  }
       
  1383 +
       
  1384 +  if (const Arg *A = Args.getLastArg(options::OPT_mcpu_EQ)) {
       
  1385 +    StringRef AV = A->getValue();
       
  1386 +    if (AV == "native") {
       
  1387 +      std::string CPU = llvm::sys::getHostCPUName().str();
       
  1388 +      if (CPU.find("UltraSPARC-IV") != std::string::npos)
       
  1389 +        return Triple.getArch() == llvm::Triple::sparcv9 ?  "v9c" : "v8plusc";
       
  1390 +      else if (CPU.find("UltraSPARC-III") != std::string::npos)
       
  1391 +        return Triple.getArch() == llvm::Triple::sparcv9 ?  "v9b" : "v8plusb";
       
  1392 +      else if (CPU.find("UltraSPARC-II") != std::string::npos)
       
  1393 +        return Triple.getArch() == llvm::Triple::sparcv9 ?  "v9a" : "v8plusa";
       
  1394 +      else if (CPU.find("UltraSPARC-I") != std::string::npos)
       
  1395 +        return Triple.getArch() == llvm::Triple::sparcv9 ?  "v9" : "v8plus";
       
  1396 +      else if (CPU.find("SPARC-T4") != std::string::npos)
       
  1397 +        return Triple.getArch() == llvm::Triple::sparcv9 ?  "v9v" : "v8plusv";
       
  1398 +      else if (CPU.find("SPARC-T5") != std::string::npos)
       
  1399 +        return Triple.getArch() == llvm::Triple::sparcv9 ?  "v9m" : "v8plusm";
       
  1400 +      else if (CPU.find("SPARC-T6") != std::string::npos)
       
  1401 +        return Triple.getArch() == llvm::Triple::sparcv9 ?  "v9m" : "v8plusm";
       
  1402 +      else if (CPU.find("SPARC-T7") != std::string::npos)
       
  1403 +        return Triple.getArch() == llvm::Triple::sparcv9 ?  "v9m" : "v8plusm";
       
  1404 +      else if (CPU.find("SPARC-M4") != std::string::npos)
       
  1405 +        return Triple.getArch() == llvm::Triple::sparcv9 ?  "v9v" : "v8plusv";
       
  1406 +      else if (CPU.find("SPARC-M5") != std::string::npos)
       
  1407 +        return Triple.getArch() == llvm::Triple::sparcv9 ?  "v9m" : "v8plusm";
       
  1408 +      else if (CPU.find("SPARC-M6") != std::string::npos)
       
  1409 +        return Triple.getArch() == llvm::Triple::sparcv9 ?  "v9m" : "v8plusm";
       
  1410 +      else if (CPU.find("SPARC-M7") != std::string::npos)
       
  1411 +        return Triple.getArch() == llvm::Triple::sparcv9 ?  "v9m" : "v8plusm";
       
  1412 +    } else if (AV == "ultrasparc") {
       
  1413 +      return Triple.getArch() == llvm::Triple::sparcv9 ?  "v9a" : "v8plusa";
       
  1414 +    } else if (AV == "ultrasparc2") {
       
  1415 +      return Triple.getArch() == llvm::Triple::sparcv9 ?  "v9a" : "v8plusa";
       
  1416 +    } else if (AV == "ultrasparc3") {
       
  1417 +      return Triple.getArch() == llvm::Triple::sparcv9 ?  "v9b" : "v8plusb";
       
  1418 +    } else if (AV == "ultrasparc4") {
       
  1419 +      return Triple.getArch() == llvm::Triple::sparcv9 ?  "v9c" : "v8plusc";
       
  1420 +    } else if (AV == "niagara") {
       
  1421 +      return Triple.getArch() == llvm::Triple::sparcv9 ?  "v9b" : "v8plusb";
       
  1422 +    } else if (AV == "niagara2") {
       
  1423 +      return Triple.getArch() == llvm::Triple::sparcv9 ?  "v9b" : "v8plusb";
       
  1424 +    } else if (AV == "niagara3") {
       
  1425 +      return Triple.getArch() == llvm::Triple::sparcv9 ?  "v9b" : "v8plusb";
       
  1426 +    } else if (AV == "niagara4") {
       
  1427 +      return Triple.getArch() == llvm::Triple::sparcv9 ?  "v9b" : "v8plusb";
       
  1428 +    } else if (AV == "sparc4") {
       
  1429 +      return "sparc4";
       
  1430 +    } else if (AV == "sparc5") {
       
  1431 +      return "sparc5";
       
  1432 +    } else if (AV == "generic") {
       
  1433 +      return Triple.getArch() == llvm::Triple::sparcv9 ?  "v9a" : "v8plusa";
       
  1434 +    } else if (AV == "generic32") {
       
  1435 +      return "v8plusa";
       
  1436 +    } else if (AV == "generic64") {
       
  1437 +      return "v9a";
       
  1438 +    }
       
  1439 +  }
       
  1440 +
       
  1441 +  return Triple.getArch() == llvm::Triple::sparcv9 ?  "v9a" : "v8plusa";
       
  1442 +}
       
  1443 +
       
  1444 +const char *x86::getX86TargetCPU(const llvm::opt::ArgList &Args,
       
  1445 +                                 const llvm::Triple &Triple) {
       
  1446    if (const Arg *A = Args.getLastArg(options::OPT_march_EQ)) {
       
  1447      if (StringRef(A->getValue()) != "native") {
       
  1448        if (Triple.isOSDarwin() && Triple.getArchName() == "x86_64h")
       
  1449 @@ -1616,7 +1773,7 @@
       
  1450      //
       
  1451      // FIXME: We should also incorporate the detected target features for use
       
  1452      // with -native.
       
  1453 -    std::string CPU = llvm::sys::getHostCPUName();
       
  1454 +    std::string CPU = llvm::sys::getHostCPUName().str();
       
  1455      if (!CPU.empty() && CPU != "generic")
       
  1456        return Args.MakeArgString(CPU);
       
  1457    }
       
  1458 @@ -1666,6 +1823,10 @@
       
  1459    if (Triple.isAndroid())
       
  1460      return Is64Bit ? "x86-64" : "i686";
       
  1461  
       
  1462 +  // On Solaris return a target compatible with gas.
       
  1463 +  if (Triple.isOSSolaris())
       
  1464 +    return Is64Bit ? "opteron" : "pentium4";
       
  1465 +
       
  1466    // Everything else goes to x86-64 in 64-bit mode.
       
  1467    if (Is64Bit)
       
  1468      return "x86-64";
       
  1469 @@ -1757,15 +1918,17 @@
       
  1470    }
       
  1471  
       
  1472    case llvm::Triple::sparc:
       
  1473 -  case llvm::Triple::sparcel:
       
  1474    case llvm::Triple::sparcv9:
       
  1475 +    return sparc::getSparcTargetCPU(Args, T);
       
  1476 +
       
  1477 +  case llvm::Triple::sparcel:
       
  1478      if (const Arg *A = Args.getLastArg(options::OPT_mcpu_EQ))
       
  1479        return A->getValue();
       
  1480      return "";
       
  1481  
       
  1482    case llvm::Triple::x86:
       
  1483    case llvm::Triple::x86_64:
       
  1484 -    return getX86TargetCPU(Args, T);
       
  1485 +    return x86::getX86TargetCPU(Args, T);
       
  1486  
       
  1487    case llvm::Triple::hexagon:
       
  1488      return "hexagon" +
       
  1489 @@ -3084,7 +3247,7 @@
       
  1490  
       
  1491  // Fallback to user id.
       
  1492  #ifdef LLVM_ON_UNIX
       
  1493 -  std::string UID = llvm::utostr(getuid());
       
  1494 +  std::string UID = std::to_string(static_cast<unsigned int>(getuid()));
       
  1495  #else
       
  1496    // FIXME: Windows seems to have an 'SID' that might work.
       
  1497    std::string UID = "9999";
       
  1498 @@ -3263,10 +3426,12 @@
       
  1499    // ToolChain.getTriple() and Triple?
       
  1500    bool PIE = ToolChain.isPIEDefault();
       
  1501    bool PIC = PIE || ToolChain.isPICDefault();
       
  1502 +
       
  1503    // The Darwin/MachO default to use PIC does not apply when using -static.
       
  1504    if (ToolChain.getTriple().isOSBinFormatMachO() &&
       
  1505        Args.hasArg(options::OPT_static))
       
  1506      PIE = PIC = false;
       
  1507 +
       
  1508    bool IsPICLevelTwo = PIC;
       
  1509  
       
  1510    bool KernelOrKext =
       
  1511 @@ -3320,6 +3485,24 @@
       
  1512      }
       
  1513    }
       
  1514  
       
  1515 +  // Solaris-specific defaults for PIE
       
  1516 +  if (ToolChain.getTriple().getOS() == llvm::Triple::Solaris) {
       
  1517 +    switch (ToolChain.getTriple().getArch()) {
       
  1518 +    case llvm::Triple::x86:
       
  1519 +      IsPICLevelTwo = false; // "-fpie"
       
  1520 +      break;
       
  1521 +    case llvm::Triple::sparc:
       
  1522 +    case llvm::Triple::x86_64:
       
  1523 +    case llvm::Triple::sparcv9:
       
  1524 +      IsPICLevelTwo = true; // "-fPIE"
       
  1525 +      break;
       
  1526 +
       
  1527 +    default:
       
  1528 +      break;
       
  1529 +    }
       
  1530 +  }
       
  1531 +
       
  1532 +
       
  1533    // The last argument relating to either PIC or PIE wins, and no
       
  1534    // other argument is used. If the last argument is any flavor of the
       
  1535    // '-fno-...' arguments, both PIC and PIE are disabled. Any PIE
       
  1536 @@ -3336,8 +3519,8 @@
       
  1537        if (O.matches(options::OPT_fPIC) || O.matches(options::OPT_fpic) ||
       
  1538            O.matches(options::OPT_fPIE) || O.matches(options::OPT_fpie)) {
       
  1539          PIE = O.matches(options::OPT_fPIE) || O.matches(options::OPT_fpie);
       
  1540 -        PIC =
       
  1541 -            PIE || O.matches(options::OPT_fPIC) || O.matches(options::OPT_fpic);
       
  1542 +        PIC = PIE || O.matches(options::OPT_fPIC) ||
       
  1543 +          O.matches(options::OPT_fpic);
       
  1544          IsPICLevelTwo =
       
  1545              O.matches(options::OPT_fPIE) || O.matches(options::OPT_fPIC);
       
  1546        } else {
       
  1547 @@ -3367,10 +3550,37 @@
       
  1548                         !Triple.isWatchOS()))
       
  1549      PIC = PIE = false;
       
  1550  
       
  1551 +  if (ToolChain.getTriple().getOS() == llvm::Triple::Solaris) {
       
  1552 +    unsigned PICLevel = IsPICLevelTwo ? 2 : 1;
       
  1553 +    if (Arg *A = Args.getLastArg(options::OPT_shared)) {
       
  1554 +      PIC = true;
       
  1555 +      PIE = false;
       
  1556 +      return std::make_tuple(llvm::Reloc::PIC_, PICLevel, PIE);
       
  1557 +    } else if (PIE) {
       
  1558 +      PIC = PIE = true;
       
  1559 +      return std::make_tuple(llvm::Reloc::PIC_, PICLevel, PIE);
       
  1560 +    } else if (PIC) {
       
  1561 +      PIC = true;
       
  1562 +      PIE = IsPICLevelTwo;
       
  1563 +      return std::make_tuple(llvm::Reloc::PIC_, PICLevel, PIE);
       
  1564 +    } else if (Args.hasArg(options::OPT_static)) {
       
  1565 +      // Solaris doesn't to static relocations.
       
  1566 +      PIC = PIE = false;
       
  1567 +      return std::make_tuple(llvm::Reloc::DynamicNoPIC, PICLevel, PIE);
       
  1568 +    } else {
       
  1569 +      // This is a Solaris non-PIE executable.
       
  1570 +      // Solaris doesn't to static relocations.
       
  1571 +      PIC = PIE = false;
       
  1572 +      PICLevel = 0;
       
  1573 +      return std::make_tuple(llvm::Reloc::DynamicNoPIC, PICLevel, PIE);
       
  1574 +    }
       
  1575 +  }
       
  1576 +
       
  1577    if (Arg *A = Args.getLastArg(options::OPT_mdynamic_no_pic)) {
       
  1578      // This is a very special mode. It trumps the other modes, almost no one
       
  1579      // uses it, and it isn't even valid on any OS but Darwin.
       
  1580 -    if (!ToolChain.getTriple().isOSDarwin())
       
  1581 +    if (!ToolChain.getTriple().isOSDarwin() &&
       
  1582 +        !ToolChain.getTriple().isOSSolaris())
       
  1583        ToolChain.getDriver().Diag(diag::err_drv_unsupported_opt_for_target)
       
  1584            << A->getSpelling() << ToolChain.getTriple().str();
       
  1585  
       
  1586 @@ -3404,18 +3614,6 @@
       
  1587    llvm_unreachable("Unknown Reloc::Model kind");
       
  1588  }
       
  1589  
       
  1590 -static void AddAssemblerKPIC(const ToolChain &ToolChain, const ArgList &Args,
       
  1591 -                             ArgStringList &CmdArgs) {
       
  1592 -  llvm::Reloc::Model RelocationModel;
       
  1593 -  unsigned PICLevel;
       
  1594 -  bool IsPIE;
       
  1595 -  std::tie(RelocationModel, PICLevel, IsPIE) =
       
  1596 -      ParsePICArgs(ToolChain, ToolChain.getTriple(), Args);
       
  1597 -
       
  1598 -  if (RelocationModel != llvm::Reloc::Static)
       
  1599 -    CmdArgs.push_back("-KPIC");
       
  1600 -}
       
  1601 -
       
  1602  void Clang::ConstructJob(Compilation &C, const JobAction &JA,
       
  1603                           const InputInfo &Output, const InputInfoList &Inputs,
       
  1604                           const ArgList &Args, const char *LinkingOutput) const {
       
  1605 @@ -3713,6 +3911,14 @@
       
  1606      CmdArgs.push_back(A->getValue());
       
  1607    }
       
  1608  
       
  1609 +  if (Arg *A = Args.getLastArg(options::OPT_fabi_version_EQ)) {
       
  1610 +    StringRef V = A->getValue();
       
  1611 +    CmdArgs.push_back(Args.MakeArgString("-fabi-version=" + V));
       
  1612 +    A->claim();
       
  1613 +  } else {
       
  1614 +    CmdArgs.push_back(Args.MakeArgString("-fabi-version=4"));
       
  1615 +  }
       
  1616 +
       
  1617    if (Arg *A = Args.getLastArg(options::OPT_fpcc_struct_return,
       
  1618                                 options::OPT_freg_struct_return)) {
       
  1619      if (getToolChain().getArch() != llvm::Triple::x86) {
       
  1620 @@ -4522,6 +4728,7 @@
       
  1621      // If -fmessage-length=N was not specified, determine whether this is a
       
  1622      // terminal and, if so, implicitly define -fmessage-length appropriately.
       
  1623      unsigned N = llvm::sys::Process::StandardErrColumns();
       
  1624 +    if (N == 0U) N = 72U;
       
  1625      CmdArgs.push_back(Args.MakeArgString(Twine(N)));
       
  1626    }
       
  1627  
       
  1628 @@ -4707,6 +4914,10 @@
       
  1629    if (Args.hasArg(options::OPT_mstack_alignment)) {
       
  1630      StringRef alignment = Args.getLastArgValue(options::OPT_mstack_alignment);
       
  1631      CmdArgs.push_back(Args.MakeArgString("-mstack-alignment=" + alignment));
       
  1632 +  } else {
       
  1633 +    if ((getToolChain().getArch() == llvm::Triple::sparc) ||
       
  1634 +        (getToolChain().getArch() == llvm::Triple::sparcv9))
       
  1635 +      CmdArgs.push_back("-mstack-alignment=16");
       
  1636    }
       
  1637  
       
  1638    if (Args.hasArg(options::OPT_mstack_probe_size)) {
       
  1639 @@ -4963,16 +5174,16 @@
       
  1640    }
       
  1641  
       
  1642    // -fuse-cxa-atexit is default.
       
  1643 -  if (!Args.hasFlag(
       
  1644 +  if ((!Args.hasFlag(
       
  1645            options::OPT_fuse_cxa_atexit, options::OPT_fno_use_cxa_atexit,
       
  1646            !IsWindowsCygnus && !IsWindowsGNU &&
       
  1647 -              getToolChain().getTriple().getOS() != llvm::Triple::Solaris &&
       
  1648                getToolChain().getArch() != llvm::Triple::hexagon &&
       
  1649                getToolChain().getArch() != llvm::Triple::xcore &&
       
  1650                ((getToolChain().getTriple().getVendor() !=
       
  1651                  llvm::Triple::MipsTechnologies) ||
       
  1652                 getToolChain().getTriple().hasEnvironment())) ||
       
  1653 -      KernelOrKext)
       
  1654 +      KernelOrKext) &&
       
  1655 +      !getToolChain().getTriple().getOS() == llvm::Triple::Solaris)
       
  1656      CmdArgs.push_back("-fno-use-cxa-atexit");
       
  1657  
       
  1658    // -fms-extensions=0 is default.
       
  1659 @@ -5425,8 +5636,10 @@
       
  1660    // nice to enable this when doing a crashdump for modules as well.
       
  1661    if (Args.hasFlag(options::OPT_frewrite_includes,
       
  1662                     options::OPT_fno_rewrite_includes, false) ||
       
  1663 -      (C.isForDiagnostics() && !HaveModules))
       
  1664 +      (C.isForDiagnostics() && !HaveModules)) {
       
  1665 +    if (getToolChain().getTriple().getOS() != llvm::Triple::Solaris)
       
  1666      CmdArgs.push_back("-frewrite-includes");
       
  1667 +  }
       
  1668  
       
  1669    // Only allow -traditional or -traditional-cpp outside in preprocessing modes.
       
  1670    if (Arg *A = Args.getLastArg(options::OPT_traditional,
       
  1671 @@ -6155,7 +6368,10 @@
       
  1672      CmdArgs.push_back("-fsyntax-only");
       
  1673    }
       
  1674  
       
  1675 -  Args.AddAllArgValues(CmdArgs, options::OPT_Wa_COMMA, options::OPT_Xassembler);
       
  1676 +  Args.AddAllArgValues(CmdArgs, options::OPT_Wa_COMMA,
       
  1677 +                       options::OPT_Xassembler);
       
  1678 +  Args.ClaimAllArgs(options::OPT_Wa_COMMA);
       
  1679 +  Args.ClaimAllArgs(options::OPT_Xassembler);
       
  1680  
       
  1681    // Only pass -x if gcc will understand it; otherwise hope gcc
       
  1682    // understands the suffix correctly. The main use case this would go
       
  1683 @@ -7383,44 +7599,362 @@
       
  1684    claimNoWarnArgs(Args);
       
  1685    ArgStringList CmdArgs;
       
  1686  
       
  1687 -  Args.AddAllArgValues(CmdArgs, options::OPT_Wa_COMMA, options::OPT_Xassembler);
       
  1688 +  const toolchains::Solaris &TC =
       
  1689 +    static_cast<const toolchains::Solaris&>(getToolChain());
       
  1690 +
       
  1691 +  if (!TC.isValid()) {
       
  1692 +    llvm::errs() << "Invalid GCC installation!\n";
       
  1693 +    return;
       
  1694 +  }
       
  1695  
       
  1696 +  std::string EffectiveTriple = TC.ComputeLLVMTriple(Args, types::ID(0));
       
  1697 +  llvm::Triple ET(EffectiveTriple);
       
  1698 +
       
  1699 +  const Driver &D = TC.getDriver();
       
  1700 +  llvm::Triple::ArchType Arch = ET.getArch();
       
  1701 +  StringRef AS = TC.getAssembler();
       
  1702 +  bool m32 = !!Args.getLastArg(options::OPT_m32);
       
  1703 +
       
  1704 +  std::string march;
       
  1705 +  std::string mtune;
       
  1706 +  std::string mcpu;
       
  1707 +
       
  1708 +  if (Arg *A = Args.getLastArg(options::OPT_march_EQ))
       
  1709 +    march = A->getValue();
       
  1710 +  else
       
  1711 +    march = TC.getMArch();
       
  1712 +
       
  1713 +  if (Arg *A = Args.getLastArg(options::OPT_mtune_EQ))
       
  1714 +    mtune = A->getValue();
       
  1715 +  else
       
  1716 +    mtune = TC.getMTune();
       
  1717 +
       
  1718 +  if (Arg *A = Args.getLastArg(options::OPT_mcpu_EQ))
       
  1719 +    mcpu = A->getValue();
       
  1720 +  else
       
  1721 +    mcpu = TC.getMCpu();
       
  1722 +
       
  1723 +  if (Args.hasArg(options::OPT_v))
       
  1724 +    CmdArgs.push_back("-V");
       
  1725 +
       
  1726 +  switch (Arch) {
       
  1727 +  case llvm::Triple::x86:
       
  1728 +  case llvm::Triple::x86_64:
       
  1729 +    if (m32)
       
  1730 +      CmdArgs.push_back("--32");
       
  1731 +    else
       
  1732 +      CmdArgs.push_back("--64");
       
  1733 +    break;
       
  1734 +  case llvm::Triple::sparc:
       
  1735 +  case llvm::Triple::sparcv9:
       
  1736 +    if (m32) {
       
  1737 +      CmdArgs.push_back("-32");
       
  1738 +      if (march.empty())
       
  1739 +        march="v8plusa";
       
  1740 +      if (mcpu.empty())
       
  1741 +        mcpu="v8plusa";
       
  1742 +    } else {
       
  1743 +      CmdArgs.push_back("-64");
       
  1744 +      if (march.empty())
       
  1745 +        march="v9a";
       
  1746 +      if (mcpu.empty())
       
  1747 +        mcpu="v9a";
       
  1748 +    }
       
  1749 +    break;
       
  1750 +  default:
       
  1751 +    D.Diag(diag::err_target_unsupported_arch) << ET.getArchName()
       
  1752 +      << ET.getTriple();
       
  1753 +    break;
       
  1754 +  }
       
  1755 +
       
  1756 +  std::string xarch;
       
  1757 +
       
  1758 +  switch (Arch) {
       
  1759 +  case llvm::Triple::sparc:
       
  1760 +  case llvm::Triple::sparcv9:
       
  1761 +    xarch = "-xarch=";
       
  1762 +    xarch += clang::driver::tools::sparc::getSparcTargetCPU(Args, ET);
       
  1763 +    CmdArgs.push_back(Args.MakeArgString(xarch.c_str()));
       
  1764 +    AddAssemblerKPIC(TC, Args, CmdArgs);
       
  1765 +    CmdArgs.push_back("-no-undeclared-regs");
       
  1766 +    if (Args.hasArg(options::OPT_mstrict_align))
       
  1767 +      CmdArgs.push_back("--enforce-aligned-data");
       
  1768 +    break;
       
  1769 +  case llvm::Triple::x86:
       
  1770 +  case llvm::Triple::x86_64:
       
  1771 +    xarch = "-march=";
       
  1772 +    xarch += clang::driver::tools::x86::getX86TargetCPU(Args, ET);
       
  1773 +    CmdArgs.push_back(Args.MakeArgString(xarch.c_str()));
       
  1774 +    break;
       
  1775 +  default:
       
  1776 +    D.Diag(diag::err_target_unsupported_arch) << ET.getArchName()
       
  1777 +      << ET.getTriple();
       
  1778 +    break;
       
  1779 +  }
       
  1780 +
       
  1781 +  if (Args.hasArg(options::OPT_g_Flag) || Args.hasArg(options::OPT_g0) ||
       
  1782 +      Args.hasArg(options::OPT_g1) || Args.hasArg(options::OPT_g2) ||
       
  1783 +      Args.hasArg(options::OPT_g3))
       
  1784 +    CmdArgs.push_back("--gen-debug");
       
  1785 +
       
  1786 +  if (Output.isFilename()) {
       
  1787    CmdArgs.push_back("-o");
       
  1788    CmdArgs.push_back(Output.getFilename());
       
  1789 +  } else {
       
  1790 +    D.Diag(diag::err_drv_invalid_gcc_output_type) << "<unspecified>";
       
  1791 +    CmdArgs.push_back("-fsyntax-only");
       
  1792 +  }
       
  1793  
       
  1794 -  for (const auto &II : Inputs)
       
  1795 +  Args.AddAllArgValues(CmdArgs, options::OPT_Wa_COMMA,
       
  1796 +                       options::OPT_Xassembler);
       
  1797 +
       
  1798 +  for (const auto &II : Inputs) {
       
  1799 +    if (II.isFilename())
       
  1800      CmdArgs.push_back(II.getFilename());
       
  1801 +    else
       
  1802 +      II.getInputArg().render(Args, CmdArgs);
       
  1803 +  }
       
  1804  
       
  1805 -  const char *Exec = Args.MakeArgString(getToolChain().GetProgramPath("as"));
       
  1806 +  const char *Exec = AS.data();
       
  1807    C.addCommand(llvm::make_unique<Command>(JA, *this, Exec, CmdArgs, Inputs));
       
  1808  }
       
  1809  
       
  1810 +void
       
  1811 +solaris::Assembler::RenderExtraToolArgs(const JobAction &JA,
       
  1812 +                                        llvm::opt::ArgStringList &CmdArgs) const {
       
  1813 +  // FIXME: IMPLEMENT
       
  1814 +}
       
  1815 +
       
  1816 +bool solaris::Linker::checkGnuLd(StringRef Path) const {
       
  1817 +  if (Path.empty()) return false;
       
  1818 +
       
  1819 +  char Buf[_POSIX_PATH_MAX+1];
       
  1820 +  std::string CMD = Path.str();
       
  1821 +  CMD += " -v 2>&1";
       
  1822 +
       
  1823 +  std::FILE *FP = ::popen(CMD.c_str(), "r");
       
  1824 +  if (!FP) return false;
       
  1825 +
       
  1826 +  (void) std::memset(Buf, 0, sizeof(Buf));
       
  1827 +  (void) std::fgets(Buf, _POSIX_PATH_MAX, FP);
       
  1828 +  ::pclose(FP);
       
  1829 +
       
  1830 +  return !!std::strstr(Buf, "GNU");
       
  1831 +}
       
  1832 +
       
  1833  void solaris::Linker::ConstructJob(Compilation &C, const JobAction &JA,
       
  1834                                     const InputInfo &Output,
       
  1835                                     const InputInfoList &Inputs,
       
  1836                                     const ArgList &Args,
       
  1837                                     const char *LinkingOutput) const {
       
  1838 +  const toolchains::Solaris& TC =
       
  1839 +    static_cast<const toolchains::Solaris&>(getToolChain());
       
  1840 +
       
  1841 +  if (!TC.isValid()) {
       
  1842 +    llvm::errs() << "Invalid GCC installation!\n";
       
  1843 +    return;
       
  1844 +  }
       
  1845 +
       
  1846 +  llvm::Triple TT = TC.getTriple();
       
  1847 +  std::string EffectiveTriple = TC.ComputeLLVMTriple(Args, types::ID(0));
       
  1848 +  llvm::Triple ET(EffectiveTriple);
       
  1849 +
       
  1850 +  const Driver &D = TC.getDriver();
       
  1851 +  llvm::Triple::ArchType Arch = TT.getArch();
       
  1852 +  bool m32 = !!Args.getLastArg(options::OPT_m32);
       
  1853 +
       
  1854 +  StringRef LD = TC.getLinker();
       
  1855 +  bool UseGnuLd = checkGnuLd(LD);
       
  1856 +
       
  1857 +  std::string GCCLibPath;
       
  1858 +  std::string YPPath;
       
  1859 +  GCCLibPath += "/lib/gcc/";
       
  1860 +  std::string LibPath = "/usr/lib/";
       
  1861 +  std::string ShortLibPath = "/lib/";
       
  1862 +  std::string ClangLibPath;
       
  1863 +  const char* moption;
       
  1864 +  std::string gldm;
       
  1865 +
       
  1866 +  if (UseGnuLd) {
       
  1867 +    switch (Arch) {
       
  1868 +    case llvm::Triple::x86:
       
  1869 +      if (m32)
       
  1870 +        gldm = "elf_i386_sol2";
       
  1871 +      else
       
  1872 +        gldm = "elf_x86_64_sol2";
       
  1873 +      break;
       
  1874 +    case llvm::Triple::x86_64:
       
  1875 +      if (m32)
       
  1876 +        gldm = "elf_i386_sol2";
       
  1877 +      else
       
  1878 +        gldm = "elf_x86_64_sol2";
       
  1879 +      break;
       
  1880 +    case llvm::Triple::sparc:
       
  1881 +      if (m32)
       
  1882 +        gldm = "elf32_sparc_sol2";
       
  1883 +      else
       
  1884 +        gldm = "elf64_sparc_sol2";
       
  1885 +      break;
       
  1886 +    case llvm::Triple::sparcv9:
       
  1887 +      if (m32)
       
  1888 +        gldm = "elf32_sparc_sol2";
       
  1889 +      else
       
  1890 +        gldm = "elf64_sparc_sol2";
       
  1891 +      break;
       
  1892 +    default:
       
  1893 +      break;
       
  1894 +    }
       
  1895 +  }
       
  1896 +
       
  1897 +  switch (Arch) {
       
  1898 +  case llvm::Triple::x86:
       
  1899 +    if (m32) {
       
  1900 +      GCCLibPath = TC.getGCCInternalLibDir().str();
       
  1901 +      GCCLibPath += "/";
       
  1902 +      moption = "-32";
       
  1903 +      YPPath = "/lib:/usr/lib";
       
  1904 +      ClangLibPath = "/usr/lib/clang/";
       
  1905 +    } else {
       
  1906 +      GCCLibPath = TC.getGCCInternalMultiLibDir().str();
       
  1907 +      GCCLibPath += "/";
       
  1908 +      LibPath += "amd64/";
       
  1909 +      ShortLibPath += "amd64/";
       
  1910 +      moption = "-64";
       
  1911 +      YPPath = "/lib/amd64:/usr/lib/amd64";
       
  1912 +      ClangLibPath = "/usr/lib/amd64/clang/";
       
  1913 +    }
       
  1914 +    break;
       
  1915 +  case llvm::Triple::sparc:
       
  1916 +    if (m32) {
       
  1917 +      GCCLibPath = TC.getGCCInternalLibDir().str();
       
  1918 +      GCCLibPath += "/";
       
  1919 +      moption = "-32";
       
  1920 +      YPPath = "/lib:/usr/lib";
       
  1921 +      ClangLibPath = "/usr/lib/clang/";
       
  1922 +    } else {
       
  1923 +      GCCLibPath = TC.getGCCInternalMultiLibDir().str();
       
  1924 +      GCCLibPath += "/";
       
  1925 +      LibPath += "sparcv9/";
       
  1926 +      ShortLibPath += "sparcv9/";
       
  1927 +      moption = "-64";
       
  1928 +      YPPath = "/lib/sparcv9:/usr/lib/sparcv9";
       
  1929 +      ClangLibPath = "/usr/lib/sparcv9/clang/";
       
  1930 +    }
       
  1931 +    break;
       
  1932 +  case llvm::Triple::x86_64:
       
  1933 +    if (m32) {
       
  1934 +      GCCLibPath = TC.getGCCInternalMultiLibDir().str();
       
  1935 +      GCCLibPath += "/";
       
  1936 +      moption = "-32";
       
  1937 +      YPPath = "/lib:/usr/lib";
       
  1938 +      ClangLibPath = "/usr/lib/clang/";
       
  1939 +    } else {
       
  1940 +      GCCLibPath = TC.getGCCInternalLibDir().str();
       
  1941 +      GCCLibPath += "/";
       
  1942 +    LibPath += "amd64/";
       
  1943 +      ShortLibPath += "amd64/";
       
  1944 +      moption = "-64";
       
  1945 +      YPPath = "/lib/amd64:/usr/lib/amd64";
       
  1946 +      ClangLibPath = "/usr/lib/amd64/clang/";
       
  1947 +    }
       
  1948 +    break;
       
  1949 +  case llvm::Triple::sparcv9:
       
  1950 +    if (m32) {
       
  1951 +      GCCLibPath = TC.getGCCInternalMultiLibDir().str();
       
  1952 +      GCCLibPath += "/";
       
  1953 +      moption = "-32";
       
  1954 +      YPPath = "/lib:/usr/lib";
       
  1955 +      ClangLibPath = "/usr/lib/clang/";
       
  1956 +    } else {
       
  1957 +      GCCLibPath = TC.getGCCInternalLibDir().str();
       
  1958 +      GCCLibPath += "/";
       
  1959 +      LibPath += "sparcv9/";
       
  1960 +      ShortLibPath += "sparcv9/";
       
  1961 +      moption = "-64";
       
  1962 +      YPPath = "/lib/sparcv9:/usr/lib/sparcv9";
       
  1963 +      ClangLibPath = "/usr/lib/sparcv9/clang/";
       
  1964 +    }
       
  1965 +    break;
       
  1966 +  default:
       
  1967 +    D.Diag(diag::err_target_unsupported_arch) << ET.getArchName()
       
  1968 +      << ET.getTriple();
       
  1969 +    break;
       
  1970 +  }
       
  1971 +
       
  1972    ArgStringList CmdArgs;
       
  1973  
       
  1974 -  // Demangle C++ names in errors
       
  1975 -  CmdArgs.push_back("-C");
       
  1976 +  // THe -m flag to GNU ld is positional dependent.
       
  1977 +  // Do not change this ordering of options for the GNU ld.
       
  1978 +  if (!gldm.empty()) {
       
  1979 +    CmdArgs.push_back(Args.MakeArgString("-m"));
       
  1980 +    CmdArgs.push_back(Args.MakeArgString(gldm.c_str()));
       
  1981 +  }
       
  1982  
       
  1983 -  if (!Args.hasArg(options::OPT_nostdlib, options::OPT_shared)) {
       
  1984 -    CmdArgs.push_back("-e");
       
  1985 -    CmdArgs.push_back("_start");
       
  1986 +  if (UseGnuLd) {
       
  1987 +    if (Args.hasArg(options::OPT_v))
       
  1988 +      CmdArgs.push_back(Args.MakeArgString("-v"));
       
  1989 +    CmdArgs.push_back(Args.MakeArgString("--as-needed"));
       
  1990 +  } else {
       
  1991 +    if (D.CCCIsCXX())
       
  1992 +      CmdArgs.push_back(Args.MakeArgString("-zrelax=comdat"));
       
  1993    }
       
  1994  
       
  1995 +  Arg *PIEArg = Args.getLastArg(options::OPT_fPIE, options::OPT_fpie);
       
  1996 +  if (PIEArg) {
       
  1997 +    if (PIEArg->getOption().matches(options::OPT_fPIE) ||
       
  1998 +        PIEArg->getOption().matches(options::OPT_fpie)) {
       
  1999 +      CmdArgs.push_back(Args.MakeArgString("-Qy"));
       
  2000 +
       
  2001 +      if (UseGnuLd) {
       
  2002 +        CmdArgs.push_back(Args.MakeArgString("--pic-executable"));
       
  2003 +      } else {
       
  2004 +        CmdArgs.push_back(Args.MakeArgString("-zdirect"));
       
  2005 +        CmdArgs.push_back(Args.MakeArgString("-ztextwarn"));
       
  2006 +        CmdArgs.push_back(Args.MakeArgString("-ztype=pie"));
       
  2007 +        CmdArgs.push_back(Args.MakeArgString("-zaslr=enable"));
       
  2008 +      }
       
  2009 +    }
       
  2010 +  }
       
  2011 +
       
  2012 +  // Silence 'argument not used during compilation: -g' warning.
       
  2013 +  Args.ClaimAllArgs(options::OPT_g_Group);
       
  2014 +
       
  2015 +  // Silence 'argument unused during compilation: -pthread' warning.
       
  2016 +  Args.ClaimAllArgs(options::OPT_pthread);
       
  2017 +
       
  2018 +  // Language options
       
  2019 +  Args.ClaimAllArgs(options::OPT_emit_llvm);
       
  2020 +  Args.ClaimAllArgs(options::OPT_w);
       
  2021 +
       
  2022 +  if (Args.hasArg(options::OPT_s))
       
  2023 +    CmdArgs.push_back("-s");
       
  2024 +
       
  2025 +  const std::vector<std::string> &ExtraOpts = TC.getExtraOpts();
       
  2026 +
       
  2027 +  // Handle extra options
       
  2028 +  if (ExtraOpts.size()) {
       
  2029 +    for (std::vector<std::string>::const_iterator I = ExtraOpts.begin(),
       
  2030 +         E = ExtraOpts.end(); I != E; ++I)
       
  2031 +      CmdArgs.push_back((*I).c_str());
       
  2032 +  }
       
  2033 +
       
  2034 +  // Demangle C++ names
       
  2035 +  if (UseGnuLd)
       
  2036 +    CmdArgs.push_back("--demangle");
       
  2037 +  else
       
  2038 +    CmdArgs.push_back("-C");
       
  2039 +
       
  2040    if (Args.hasArg(options::OPT_static)) {
       
  2041      CmdArgs.push_back("-Bstatic");
       
  2042      CmdArgs.push_back("-dn");
       
  2043    } else {
       
  2044      CmdArgs.push_back("-Bdynamic");
       
  2045 +    CmdArgs.push_back("-dy");
       
  2046      if (Args.hasArg(options::OPT_shared)) {
       
  2047        CmdArgs.push_back("-shared");
       
  2048      } else {
       
  2049        CmdArgs.push_back("--dynamic-linker");
       
  2050 -      CmdArgs.push_back(
       
  2051 -          Args.MakeArgString(getToolChain().GetFilePath("ld.so.1")));
       
  2052 +      CmdArgs.push_back(Args.MakeArgString(LibPath + "ld.so.1"));
       
  2053      }
       
  2054    }
       
  2055  
       
  2056 @@ -7431,48 +7965,264 @@
       
  2057      assert(Output.isNothing() && "Invalid output.");
       
  2058    }
       
  2059  
       
  2060 -  if (!Args.hasArg(options::OPT_nostdlib, options::OPT_nostartfiles)) {
       
  2061 -    if (!Args.hasArg(options::OPT_shared))
       
  2062 -      CmdArgs.push_back(
       
  2063 -          Args.MakeArgString(getToolChain().GetFilePath("crt1.o")));
       
  2064 +  const char* Values = "values-Xa.o";
       
  2065 +  const char* Xpg = "values-xpg4.o";
       
  2066  
       
  2067 -    CmdArgs.push_back(Args.MakeArgString(getToolChain().GetFilePath("crti.o")));
       
  2068 -    CmdArgs.push_back(
       
  2069 -        Args.MakeArgString(getToolChain().GetFilePath("values-Xa.o")));
       
  2070 -    CmdArgs.push_back(
       
  2071 -        Args.MakeArgString(getToolChain().GetFilePath("crtbegin.o")));
       
  2072 +  Arg *STDArg = Args.getLastArg(options::OPT_std_EQ);
       
  2073 +  if (STDArg) {
       
  2074 +    if (STDArg->getOption().matches(options::OPT_std_EQ)) {
       
  2075 +      std::string Lang = STDArg->getValue();
       
  2076 +      if ((Lang == "c99") || (Lang == "c11") ||
       
  2077 +          (Lang == "c++11") || (Lang == "c++14")) {
       
  2078 +        Values = "values-Xc.o";
       
  2079 +        Xpg = "values-xpg6.o";
       
  2080 +      }
       
  2081 +    }
       
  2082    }
       
  2083  
       
  2084 -  getToolChain().AddFilePathLibArgs(Args, CmdArgs);
       
  2085 +  if (UseGnuLd) {
       
  2086 +    if (LD == "/usr/gnu/bin/ld.gold") {
       
  2087 +      if (Args.hasArg(options::OPT_O))
       
  2088 +        Args.AddAllArgs(CmdArgs, options::OPT_O);
       
  2089 +    } else
       
  2090 +      CmdArgs.push_back(Args.MakeArgString("-O"));
       
  2091 +  }
       
  2092  
       
  2093 -  Args.AddAllArgs(CmdArgs, {options::OPT_L, options::OPT_T_Group,
       
  2094 -                            options::OPT_e, options::OPT_r});
       
  2095 +  if (Args.hasArg(options::OPT_v))
       
  2096 +    CmdArgs.push_back(Args.MakeArgString(StringRef("-V")));
       
  2097  
       
  2098 -  AddLinkerInputs(getToolChain(), Inputs, Args, CmdArgs);
       
  2099 +  CmdArgs.push_back(Args.MakeArgString(StringRef("-Qy")));
       
  2100  
       
  2101 -  if (!Args.hasArg(options::OPT_nostdlib, options::OPT_nodefaultlibs)) {
       
  2102 -    if (getToolChain().getDriver().CCCIsCXX())
       
  2103 -      getToolChain().AddCXXStdlibLibArgs(Args, CmdArgs);
       
  2104 -    CmdArgs.push_back("-lgcc_s");
       
  2105 -    CmdArgs.push_back("-lc");
       
  2106 +  if (LD == "/usr/bin/ld") {
       
  2107 +    CmdArgs.push_back(Args.MakeArgString(StringRef("-Y")));
       
  2108 +    CmdArgs.push_back(Args.MakeArgString(StringRef("P," + YPPath)));
       
  2109 +  } else {
       
  2110 +    CmdArgs.push_back(Args.MakeArgString(StringRef("-Y")));
       
  2111 +    CmdArgs.push_back(Args.MakeArgString(StringRef(YPPath)));
       
  2112 +  }
       
  2113 +
       
  2114 +  CmdArgs.push_back(Args.MakeArgString(StringRef("-L") + LibPath));
       
  2115 +
       
  2116 +  std::string P = GCCLibPath;
       
  2117 +  P += "../../..";
       
  2118 +  CmdArgs.push_back(Args.MakeArgString(StringRef("-L") + P));
       
  2119 +
       
  2120 +  std::string crt1o;
       
  2121 +  bool S12OrHigher = false;
       
  2122 +
       
  2123 +  // We're not backporting this to S10. Until we do, that is.
       
  2124 +  if (EffectiveTriple.find("solaris2.11") == std::string::npos)
       
  2125 +    S12OrHigher = true;
       
  2126 +
       
  2127 +  if (!Args.hasArg(options::OPT_nostdlib) &&
       
  2128 +      !Args.hasArg(options::OPT_nostartfiles)) {
       
  2129      if (!Args.hasArg(options::OPT_shared)) {
       
  2130 -      CmdArgs.push_back("-lgcc");
       
  2131 +      switch (Arch) {
       
  2132 +      case llvm::Triple::sparc:
       
  2133 +      case llvm::Triple::sparcv9:
       
  2134 +        if (S12OrHigher)
       
  2135 +          crt1o = LibPath;
       
  2136 +        else
       
  2137 +          crt1o = GCCLibPath;
       
  2138 +      case llvm::Triple::x86:
       
  2139 +      case llvm::Triple::x86_64:
       
  2140 +        crt1o = LibPath;
       
  2141 +        break;
       
  2142 +      default:
       
  2143 +        D.Diag(diag::err_target_unsupported_arch) << ET.getArchName()
       
  2144 +          << ET.getTriple();
       
  2145 +        break;
       
  2146 +      }
       
  2147 +
       
  2148 +      crt1o += "/crt1.o";
       
  2149 +
       
  2150 +      CmdArgs.push_back(Args.MakeArgString(crt1o.c_str()));
       
  2151 +      CmdArgs.push_back(Args.MakeArgString(LibPath + "crti.o"));
       
  2152 +      CmdArgs.push_back(Args.MakeArgString(LibPath + Values));
       
  2153 +      CmdArgs.push_back(Args.MakeArgString(LibPath + Xpg));
       
  2154 +      CmdArgs.push_back(Args.MakeArgString(StringRef("-L") + GCCLibPath));
       
  2155 +      CmdArgs.push_back(Args.MakeArgString("-L" + P));
       
  2156 +      CmdArgs.push_back(Args.MakeArgString(GCCLibPath + "crtbegin.o"));
       
  2157 +    } else {
       
  2158 +      CmdArgs.push_back(Args.MakeArgString(LibPath + "crti.o"));
       
  2159 +      CmdArgs.push_back(Args.MakeArgString(LibPath + Values));
       
  2160 +      CmdArgs.push_back(Args.MakeArgString(LibPath + Xpg));
       
  2161 +      CmdArgs.push_back(Args.MakeArgString(StringRef("-L") + GCCLibPath));
       
  2162 +      CmdArgs.push_back(Args.MakeArgString(StringRef("-L") + P));
       
  2163 +      CmdArgs.push_back(Args.MakeArgString(GCCLibPath + "crtbegin.o"));
       
  2164 +    }
       
  2165 +  } else if (Args.hasArg(options::OPT_nostdlib) &&
       
  2166 +             !Args.hasArg(options::OPT_nostartfiles)) {
       
  2167 +    if (Args.hasArg(options::OPT_shared)) {
       
  2168 +      CmdArgs.push_back(Args.MakeArgString(LibPath + "crti.o"));
       
  2169 +      CmdArgs.push_back(Args.MakeArgString(LibPath + Values));
       
  2170 +      CmdArgs.push_back(Args.MakeArgString(LibPath + Xpg));
       
  2171 +      CmdArgs.push_back(Args.MakeArgString(StringRef("-L") + GCCLibPath));
       
  2172 +      CmdArgs.push_back(Args.MakeArgString(StringRef("-L") + P));
       
  2173 +      CmdArgs.push_back(Args.MakeArgString(GCCLibPath + "crtbegin.o"));
       
  2174 +    } else {
       
  2175 +      CmdArgs.push_back(Args.MakeArgString(crt1o.c_str()));
       
  2176 +      CmdArgs.push_back(Args.MakeArgString(LibPath + "crti.o"));
       
  2177 +      CmdArgs.push_back(Args.MakeArgString(LibPath + Values));
       
  2178 +      CmdArgs.push_back(Args.MakeArgString(LibPath + Xpg));
       
  2179 +      CmdArgs.push_back(Args.MakeArgString(StringRef("-L") + GCCLibPath));
       
  2180 +      CmdArgs.push_back(Args.MakeArgString("-L" + P));
       
  2181 +    }
       
  2182 +  } else if (!Args.hasArg(options::OPT_nostdlib) &&
       
  2183 +             Args.hasArg(options::OPT_nostartfiles)) {
       
  2184 +    if (Args.hasArg(options::OPT_shared)) {
       
  2185 +      CmdArgs.push_back(Args.MakeArgString(GCCLibPath + "crtend.o"));
       
  2186 +    }
       
  2187 +  }
       
  2188 +
       
  2189 +  // Itanium C++ ABI.
       
  2190 +  std::string CXAFinalize;
       
  2191 +  bool HasSystemCXAFinalize = !S12OrHigher;
       
  2192 +
       
  2193 +  if (!Args.hasArg(options::OPT_shared)) {
       
  2194 +    if (PIEArg) {
       
  2195 +      if (PIEArg->getOption().matches(options::OPT_fPIE) ||
       
  2196 +          PIEArg->getOption().matches(options::OPT_fpie)) {
       
  2197 +        CXAFinalize = ClangLibPath + "cxa_finalize_pic.o";
       
  2198 +      }
       
  2199 +    } else {
       
  2200 +      CXAFinalize = ClangLibPath + "cxa_finalize.o";
       
  2201 +    }
       
  2202 +
       
  2203 +    HasSystemCXAFinalize = llvm::sys::fs::exists(CXAFinalize.c_str());
       
  2204 +
       
  2205 +    if (D.CCCIsCXX() && HasSystemCXAFinalize)
       
  2206 +      CmdArgs.push_back(Args.MakeArgString(CXAFinalize.c_str()));
       
  2207 +  }
       
  2208 +
       
  2209 +  CmdArgs.push_back(Args.MakeArgString(StringRef("-L" + GCCLibPath)));
       
  2210 +  CmdArgs.push_back(Args.MakeArgString(StringRef("-L") + LibPath));
       
  2211 +  CmdArgs.push_back(Args.MakeArgString(StringRef("-L") + ShortLibPath));
       
  2212 +
       
  2213 +  Args.AddAllArgs(CmdArgs, options::OPT_L);
       
  2214 +  const ToolChain::path_list Paths = TC.getFilePaths();
       
  2215 +  for (ToolChain::path_list::const_iterator B = Paths.begin(), E = Paths.end();
       
  2216 +       B != E; ++B) {
       
  2217 +    CmdArgs.push_back(Args.MakeArgString(StringRef("-L") + *B));
       
  2218 +
       
  2219 +    // Itanium C++ ABI.
       
  2220 +    if (!Args.hasArg(options::OPT_shared)) {
       
  2221 +      if (D.CCCIsCXX() && !HasSystemCXAFinalize) {
       
  2222 +        if (PIEArg) {
       
  2223 +          if (PIEArg->getOption().matches(options::OPT_fPIE) ||
       
  2224 +              PIEArg->getOption().matches(options::OPT_fpie)) {
       
  2225 +            CXAFinalize = *B + "/cxa_finalize_pic.o";
       
  2226 +          }
       
  2227 +        } else {
       
  2228 +          CXAFinalize = *B + "/cxa_finalize.o";
       
  2229 +        }
       
  2230 +
       
  2231 +        if (llvm::sys::fs::exists(CXAFinalize.c_str()))
       
  2232 +          CmdArgs.push_back(Args.MakeArgString(CXAFinalize.c_str()));
       
  2233 +      }
       
  2234 +    }
       
  2235 +  }
       
  2236 +
       
  2237 +  Args.AddAllArgs(CmdArgs, options::OPT_T_Group);
       
  2238 +  Args.AddAllArgs(CmdArgs, options::OPT_e);
       
  2239 +  Args.AddAllArgs(CmdArgs, options::OPT_s);
       
  2240 +  Args.AddAllArgs(CmdArgs, options::OPT_t);
       
  2241 +  Args.AddAllArgs(CmdArgs, options::OPT_r);
       
  2242 +
       
  2243 +  std::vector<std::string>  zoptions = Args.getAllArgValues(options::OPT_z);
       
  2244 +  std::string zoption;
       
  2245 +
       
  2246 +  for (std::vector<std::string>::const_iterator B = zoptions.begin(),
       
  2247 +       E = zoptions.end(); B != E; ++B) {
       
  2248 +    zoption = "-z";
       
  2249 +    zoption += *B;
       
  2250 +    CmdArgs.push_back(Args.MakeArgString(StringRef(zoption)));
       
  2251 +  }
       
  2252 +
       
  2253 +  if (!Args.hasArg(options::OPT_mimpure_text) &&
       
  2254 +      !Args.hasArg(options::OPT_fpie) &&
       
  2255 +      !Args.hasArg(options::OPT_fPIE))
       
  2256 +    CmdArgs.push_back(Args.MakeArgString(StringRef("-ztext")));
       
  2257 +
       
  2258 +  // Itanium C++ ABI.
       
  2259 +  if (D.CCCIsCXX()) {
       
  2260 +    if (!Args.hasArg(options::OPT_shared)) {
       
  2261 +      if (HasSystemCXAFinalize) {
       
  2262 +        const char* zfiniarray = "-zfiniarray=__cxa_finalize";
       
  2263 +        CmdArgs.push_back(Args.MakeArgString(zfiniarray));
       
  2264 +      }
       
  2265 +    }
       
  2266 +  }
       
  2267 +
       
  2268 +  if (LD == "/usr/gnu/bin/ld.gold") {
       
  2269 +    CmdArgs.push_back("-plugin");
       
  2270 +    std::string Plugin = D.Dir + "/../lib/LLVMgold.so";
       
  2271 +    CmdArgs.push_back(Args.MakeArgString(Plugin));
       
  2272 +  }
       
  2273 +
       
  2274 +  if (!UseGnuLd) {
       
  2275 +    CmdArgs.push_back(moption);
       
  2276 +  }
       
  2277 +
       
  2278 +  if (Arg *A = Args.getLastArg(options::OPT_rpath)) {
       
  2279 +    StringRef V = A->getValue();
       
  2280 +    if (UseGnuLd) {
       
  2281 +      CmdArgs.push_back(Args.MakeArgString("-rpath"));
       
  2282 +      CmdArgs.push_back(Args.MakeArgString(V));
       
  2283 +    } else {
       
  2284 +      CmdArgs.push_back(Args.MakeArgString("-R"));
       
  2285 +      CmdArgs.push_back(Args.MakeArgString(V));
       
  2286 +    }
       
  2287 +  }
       
  2288 +
       
  2289 +  AddLinkerInputs(TC, Inputs, Args, CmdArgs);
       
  2290 +  AddLibgcc(D, CmdArgs, Args, LD.str());
       
  2291 +
       
  2292 +  if (!Args.hasArg(options::OPT_nostdlib) &&
       
  2293 +      !Args.hasArg(options::OPT_nodefaultlibs)) {
       
  2294 +    addOpenMPRuntime(CmdArgs, TC, Args);
       
  2295 +
       
  2296 +    if (D.CCCIsCXX())
       
  2297 +      TC.AddCXXStdlibLibArgs(Args, CmdArgs);
       
  2298 +
       
  2299 +    CmdArgs.push_back("-lc");
       
  2300        CmdArgs.push_back("-lm");
       
  2301 +    CmdArgs.push_back("-lgcc_s");
       
  2302 +
       
  2303 +    if (Args.hasArg(options::OPT_static)) {
       
  2304 +      CmdArgs.push_back("-lgcc");
       
  2305 +      CmdArgs.push_back("-lgcc_eh");
       
  2306      }
       
  2307 +  } else if (Args.hasArg(options::OPT_nostdlib) &&
       
  2308 +             (!Args.hasArg(options::OPT_nodefaultlibs))) {
       
  2309 +    CmdArgs.push_back("-lgcc_s");
       
  2310 +
       
  2311 +    if (Args.hasArg(options::OPT_static))
       
  2312 +      CmdArgs.push_back("-lgcc_eh");
       
  2313    }
       
  2314  
       
  2315 -  if (!Args.hasArg(options::OPT_nostdlib, options::OPT_nostartfiles)) {
       
  2316 -    CmdArgs.push_back(
       
  2317 -        Args.MakeArgString(getToolChain().GetFilePath("crtend.o")));
       
  2318 +  if (!Args.hasArg(options::OPT_nostdlib) &&
       
  2319 +      !Args.hasArg(options::OPT_nostartfiles)) {
       
  2320 +    CmdArgs.push_back(Args.MakeArgString(GCCLibPath + "crtend.o"));
       
  2321    }
       
  2322 -  CmdArgs.push_back(Args.MakeArgString(getToolChain().GetFilePath("crtn.o")));
       
  2323  
       
  2324 -  getToolChain().addProfileRTLibs(Args, CmdArgs);
       
  2325 +  CmdArgs.push_back(Args.MakeArgString(LibPath + "crtn.o"));
       
  2326  
       
  2327 -  const char *Exec = Args.MakeArgString(getToolChain().GetLinkerPath());
       
  2328 +  TC.addProfileRTLibs(Args, CmdArgs);
       
  2329 +
       
  2330 +  Args.ClaimAllArgs(options::OPT_Wl_COMMA);
       
  2331 +  Args.ClaimAllArgs(options::OPT_Xlinker);
       
  2332 +
       
  2333 +  const char *Exec = LD.data();
       
  2334    C.addCommand(llvm::make_unique<Command>(JA, *this, Exec, CmdArgs, Inputs));
       
  2335  }
       
  2336  
       
  2337 +void
       
  2338 +solaris::Linker::RenderExtraToolArgs(const JobAction &JA,
       
  2339 +                                     llvm::opt::ArgStringList &CmdArgs) const {
       
  2340 +  // FIXME: IMPLEMENT
       
  2341 +}
       
  2342 +
       
  2343  void openbsd::Assembler::ConstructJob(Compilation &C, const JobAction &JA,
       
  2344                                        const InputInfo &Output,
       
  2345                                        const InputInfoList &Inputs,
       
  2346 @@ -8623,6 +9373,41 @@
       
  2347      CmdArgs.push_back("-ldl");
       
  2348  }
       
  2349  
       
  2350 +static void AddLibgcc(const Driver &D, ArgStringList &CmdArgs,
       
  2351 +                      const ArgList &Args, const std::string& Exec) {
       
  2352 +  bool StaticLibgcc = Args.hasArg(options::OPT_static) ||
       
  2353 +    Args.hasArg(options::OPT_static_libgcc);
       
  2354 +  if (!D.CCCIsCXX())
       
  2355 +    CmdArgs.push_back("-lgcc");
       
  2356 +
       
  2357 +  if (StaticLibgcc) {
       
  2358 +    if (D.CCCIsCXX())
       
  2359 +      CmdArgs.push_back("-lgcc");
       
  2360 +  } else {
       
  2361 +    if ((!D.CCCIsCXX()) && ((Exec == "/usr/bin/gld") ||
       
  2362 +                            (Exec == "/usr/gnu/bin/ld") ||
       
  2363 +                            (Exec == "/usr/gnu/bin/ld.bfd") ||
       
  2364 +                            (Exec == "/usr/gnu/bin/ld.gold")))
       
  2365 +      CmdArgs.push_back("--as-needed");
       
  2366 +
       
  2367 +    CmdArgs.push_back("-lgcc_s");
       
  2368 +    if ((!D.CCCIsCXX()) && ((Exec == "/usr/bin/gld") ||
       
  2369 +                            (Exec == "/usr/gnu/bin/ld") ||
       
  2370 +                            (Exec == "/usr/gnu/bin/ld.bfd") ||
       
  2371 +                            (Exec == "/usr/gnu/bin/ld.gold")))
       
  2372 +      CmdArgs.push_back("--no-as-needed");
       
  2373 +  }
       
  2374 +
       
  2375 +  if (StaticLibgcc)
       
  2376 +    CmdArgs.push_back("-lgcc_eh");
       
  2377 +  else if (!Args.hasArg(options::OPT_shared) && D.CCCIsCXX())
       
  2378 +    CmdArgs.push_back("-lgcc");
       
  2379 +
       
  2380 +  if (!StaticLibgcc)
       
  2381 +    CmdArgs.push_back("-ldl");
       
  2382 +}
       
  2383 +
       
  2384 +
       
  2385  static std::string getLinuxDynamicLinker(const ArgList &Args,
       
  2386                                           const toolchains::Linux &ToolChain) {
       
  2387    const llvm::Triple::ArchType Arch = ToolChain.getArch();
       
  2388 ###
       
  2389 --- tools/clang/lib/Driver/Tools.h	2016-01-08 06:14:31.000000000 -0900
       
  2390 +++ tools/clang/lib/Driver/Tools.h	2016-07-04 11:21:03.646553390 -0800
       
  2391 @@ -17,6 +17,8 @@
       
  2392  #include "clang/Frontend/CodeGenOptions.h"
       
  2393  #include "llvm/ADT/Triple.h"
       
  2394  #include "llvm/Option/Option.h"
       
  2395 +#include "llvm/Option/Arg.h"
       
  2396 +#include "llvm/Option/ArgList.h"
       
  2397  #include "llvm/Support/Compiler.h"
       
  2398  
       
  2399  namespace clang {
       
  2400 @@ -38,9 +40,10 @@
       
  2401  
       
  2402  using llvm::opt::ArgStringList;
       
  2403  
       
  2404 -SmallString<128> getCompilerRT(const ToolChain &TC,
       
  2405 +SmallString<PATH_MAX> getCompilerRT(const ToolChain &TC,
       
  2406                                 const llvm::opt::ArgList &Args,
       
  2407 -                               StringRef Component, bool Shared = false);
       
  2408 +                                    StringRef Component,
       
  2409 +                                    bool Shared = false);
       
  2410  
       
  2411  /// \brief Clang compiler tool.
       
  2412  class LLVM_LIBRARY_VISIBILITY Clang : public Tool {
       
  2413 @@ -308,6 +311,16 @@
       
  2414  bool hasPPCAbiArg(const llvm::opt::ArgList &Args, const char *Value);
       
  2415  } // end namespace ppc
       
  2416  
       
  2417 +namespace sparc {
       
  2418 +  const char *getSparcTargetCPU(const llvm::opt::ArgList &Args,
       
  2419 +                                const llvm::Triple &Triple);
       
  2420 +} // end namespace sparc
       
  2421 +
       
  2422 +namespace x86 {
       
  2423 +  const char *getX86TargetCPU(const llvm::opt::ArgList &Args,
       
  2424 +                              const llvm::Triple &Triple);
       
  2425 +} // end namespace x86
       
  2426 +
       
  2427  /// cloudabi -- Directly call GNU Binutils linker
       
  2428  namespace cloudabi {
       
  2429  class LLVM_LIBRARY_VISIBILITY Linker : public GnuTool {
       
  2430 @@ -622,25 +635,32 @@
       
  2431  
       
  2432  /// solaris -- Directly call Solaris assembler and linker
       
  2433  namespace solaris {
       
  2434 -class LLVM_LIBRARY_VISIBILITY Assembler : public Tool {
       
  2435 +class LLVM_LIBRARY_VISIBILITY Assembler : public GnuTool {
       
  2436  public:
       
  2437    Assembler(const ToolChain &TC)
       
  2438 -      : Tool("solaris::Assembler", "assembler", TC) {}
       
  2439 +    : GnuTool("solaris::Assembler", "assembler", TC) {}
       
  2440  
       
  2441    bool hasIntegratedCPP() const override { return false; }
       
  2442  
       
  2443 +  virtual void RenderExtraToolArgs(const JobAction &JA,
       
  2444 +                                   llvm::opt::ArgStringList &CmdArgs) const;
       
  2445 +
       
  2446    void ConstructJob(Compilation &C, const JobAction &JA,
       
  2447                      const InputInfo &Output, const InputInfoList &Inputs,
       
  2448                      const llvm::opt::ArgList &TCArgs,
       
  2449                      const char *LinkingOutput) const override;
       
  2450  };
       
  2451  
       
  2452 -class LLVM_LIBRARY_VISIBILITY Linker : public Tool {
       
  2453 +class LLVM_LIBRARY_VISIBILITY Linker : public GnuTool {
       
  2454  public:
       
  2455 -  Linker(const ToolChain &TC) : Tool("solaris::Linker", "linker", TC) {}
       
  2456 +  Linker(const ToolChain &TC)
       
  2457 +    : GnuTool("solaris::Linker", "linker", TC) {}
       
  2458  
       
  2459    bool hasIntegratedCPP() const override { return false; }
       
  2460    bool isLinkJob() const override { return true; }
       
  2461 +  bool checkGnuLd(StringRef Path) const;
       
  2462 +  virtual void RenderExtraToolArgs(const JobAction &JA,
       
  2463 +                                   llvm::opt::ArgStringList &CmdArgs) const;
       
  2464  
       
  2465    void ConstructJob(Compilation &C, const JobAction &JA,
       
  2466                      const InputInfo &Output, const InputInfoList &Inputs,
       
  2467 ###
       
  2468 --- tools/clang/lib/Driver/ToolChain.cpp	2015-11-25 16:02:07.000000000 -0900
       
  2469 +++ tools/clang/lib/Driver/ToolChain.cpp	2016-06-30 20:26:09.406980255 -0800
       
  2470 @@ -408,6 +408,34 @@
       
  2471  
       
  2472  std::string ToolChain::ComputeLLVMTriple(const ArgList &Args,
       
  2473                                           types::ID InputType) const {
       
  2474 +  llvm::Triple T = getTriple();
       
  2475 +  if (T.isOSSolaris()) {
       
  2476 +    if ((!Args.getLastArg(options::OPT_m32)) &&
       
  2477 +        (!Args.getLastArg(options::OPT_m64))) {
       
  2478 +      StringRef ArchName;
       
  2479 +
       
  2480 +      switch (T.getArch()) {
       
  2481 +      case llvm::Triple::x86_64:
       
  2482 +      case llvm::Triple::sparcv9:
       
  2483 +        return getTripleString();
       
  2484 +        break;
       
  2485 +      case llvm::Triple::sparc:
       
  2486 +        ArchName = "sparcv9";
       
  2487 +        T.setArchName(ArchName);
       
  2488 +        return T.getTriple();
       
  2489 +        break;
       
  2490 +      case llvm::Triple::x86:
       
  2491 +        ArchName = "x86_64";
       
  2492 +        T.setArchName(ArchName);
       
  2493 +        return T.getTriple();
       
  2494 +        break;
       
  2495 +      default:
       
  2496 +        llvm_unreachable("Unknonwn Solaris Target Triple!");
       
  2497 +        break;
       
  2498 +      }
       
  2499 +    }
       
  2500 +  }
       
  2501 +
       
  2502    switch (getTriple().getArch()) {
       
  2503    default:
       
  2504      return getTripleString();
       
  2505 ###
       
  2506