$OpenBSD: patch-tools_clang_lib_Driver_ToolChains_OpenBSD_cpp,v 1.8 2019/01/28 15:34:22 jca Exp $

Some improvements to the OpenBSD driver.

Index: tools/clang/lib/Driver/ToolChains/OpenBSD.cpp
--- tools/clang/lib/Driver/ToolChains/OpenBSD.cpp.orig
+++ tools/clang/lib/Driver/ToolChains/OpenBSD.cpp
@@ -12,6 +12,8 @@
 #include "Arch/Sparc.h"
 #include "CommonArgs.h"
 #include "clang/Driver/Compilation.h"
+#include "clang/Driver/Driver.h"
+#include "clang/Driver/DriverDiagnostic.h"
 #include "clang/Driver/Options.h"
 #include "clang/Driver/SanitizerArgs.h"
 #include "llvm/Option/ArgList.h"
@@ -111,9 +113,9 @@ void openbsd::Linker::ConstructJob(Compilation &C, con
   // handled somewhere else.
   Args.ClaimAllArgs(options::OPT_w);
 
-  if (getToolChain().getArch() == llvm::Triple::mips64)
+  if (ToolChain.getArch() == llvm::Triple::mips64)
     CmdArgs.push_back("-EB");
-  else if (getToolChain().getArch() == llvm::Triple::mips64el)
+  else if (ToolChain.getArch() == llvm::Triple::mips64el)
     CmdArgs.push_back("-EL");
 
   if (!Args.hasArg(options::OPT_nostdlib, options::OPT_shared)) {
@@ -149,44 +151,50 @@ void openbsd::Linker::ConstructJob(Compilation &C, con
   }
 
   if (!Args.hasArg(options::OPT_nostdlib, options::OPT_nostartfiles)) {
+    const char *crt0 = nullptr;
+    const char *crtbegin = nullptr;
     if (!Args.hasArg(options::OPT_shared)) {
       if (Args.hasArg(options::OPT_pg))
-        CmdArgs.push_back(
-            Args.MakeArgString(getToolChain().GetFilePath("gcrt0.o")));
+        crt0 = "gcrt0.o";
       else if (Args.hasArg(options::OPT_static) &&
                !Args.hasArg(options::OPT_nopie))
-        CmdArgs.push_back(
-            Args.MakeArgString(getToolChain().GetFilePath("rcrt0.o")));
+        crt0 = "rcrt0.o";
       else
-        CmdArgs.push_back(
-            Args.MakeArgString(getToolChain().GetFilePath("crt0.o")));
-      CmdArgs.push_back(
-          Args.MakeArgString(getToolChain().GetFilePath("crtbegin.o")));
+        crt0 = "crt0.o";
+      crtbegin = "crtbegin.o";
     } else {
-      CmdArgs.push_back(
-          Args.MakeArgString(getToolChain().GetFilePath("crtbeginS.o")));
+      crtbegin = "crtbeginS.o";
     }
+
+    if (crt0)
+      CmdArgs.push_back(Args.MakeArgString(ToolChain.GetFilePath(crt0)));
+    CmdArgs.push_back(Args.MakeArgString(ToolChain.GetFilePath(crtbegin)));
   }
 
-  std::string Triple = getToolChain().getTripleString();
-  if (Triple.substr(0, 6) == "x86_64")
-    Triple.replace(0, 6, "amd64");
-  CmdArgs.push_back(
-      Args.MakeArgString("-L/usr/lib/gcc-lib/" + Triple + "/4.2.1"));
-  CmdArgs.push_back(Args.MakeArgString("-L/usr/lib"));
+  if (ToolChain.GetCXXStdlibType(Args) == ToolChain::CST_Libstdcxx) {
+    std::string Triple = ToolChain.getTripleString();
+    if (Triple.substr(0, 6) == "x86_64")
+      Triple.replace(0, 6, "amd64");
+    CmdArgs.push_back(
+        Args.MakeArgString("-L${LOCALBASE}/lib/gcc/" + Triple + "/${GCC_VER}"));
+    CmdArgs.push_back(
+        Args.MakeArgString("-L${LOCALBASE}/lib"));
+  }
 
-  Args.AddAllArgs(CmdArgs, {options::OPT_L, options::OPT_T_Group,
-                            options::OPT_e, options::OPT_s, options::OPT_t,
+  Args.AddAllArgs(CmdArgs, options::OPT_L);
+  ToolChain.AddFilePathLibArgs(Args, CmdArgs);
+  Args.AddAllArgs(CmdArgs, {options::OPT_T_Group, options::OPT_e,
+                            options::OPT_s, options::OPT_t,
                             options::OPT_Z_Flag, options::OPT_r});
 
   bool NeedsSanitizerDeps = addSanitizerRuntimes(ToolChain, Args, CmdArgs);
   bool NeedsXRayDeps = addXRayRuntime(ToolChain, Args, CmdArgs);
-  AddLinkerInputs(getToolChain(), Inputs, Args, CmdArgs, JA);
+  AddLinkerInputs(ToolChain, Inputs, Args, CmdArgs, JA);
 
   if (!Args.hasArg(options::OPT_nostdlib, options::OPT_nodefaultlibs)) {
     if (D.CCCIsCXX()) {
-      if (getToolChain().ShouldLinkCXXStdlib(Args))
-        getToolChain().AddCXXStdlibLibArgs(Args, CmdArgs);
+      if (ToolChain.ShouldLinkCXXStdlib(Args))
+        ToolChain.AddCXXStdlibLibArgs(Args, CmdArgs);
       if (Args.hasArg(options::OPT_pg))
         CmdArgs.push_back("-lm_p");
       else
@@ -202,7 +210,10 @@ void openbsd::Linker::ConstructJob(Compilation &C, con
     }
     // FIXME: For some reason GCC passes -lgcc before adding
     // the default system libraries. Just mimic this for now.
-    CmdArgs.push_back("-lgcc");
+    if (ToolChain.GetCXXStdlibType(Args) == ToolChain::CST_Libcxx)
+      CmdArgs.push_back("-lcompiler_rt");
+    else
+      CmdArgs.push_back("-lgcc");
 
     if (Args.hasArg(options::OPT_pthread)) {
       if (!Args.hasArg(options::OPT_shared) && Args.hasArg(options::OPT_pg))
@@ -218,21 +229,25 @@ void openbsd::Linker::ConstructJob(Compilation &C, con
         CmdArgs.push_back("-lc");
     }
 
-    CmdArgs.push_back("-lgcc");
+    if (ToolChain.GetCXXStdlibType(Args) == ToolChain::CST_Libcxx)
+      CmdArgs.push_back("-lcompiler_rt");
+    else
+      CmdArgs.push_back("-lgcc");
   }
 
   if (!Args.hasArg(options::OPT_nostdlib, options::OPT_nostartfiles)) {
+    const char *crtend = nullptr;
     if (!Args.hasArg(options::OPT_shared))
-      CmdArgs.push_back(
-          Args.MakeArgString(getToolChain().GetFilePath("crtend.o")));
+      crtend = "crtend.o";
     else
-      CmdArgs.push_back(
-          Args.MakeArgString(getToolChain().GetFilePath("crtendS.o")));
+      crtend = "crtendS.o";
+
+    CmdArgs.push_back(Args.MakeArgString(ToolChain.GetFilePath(crtend)));
   }
 
   const char *Exec = Args.MakeArgString(
-      !NeedsSanitizerDeps ? getToolChain().GetLinkerPath()
-                          : getToolChain().GetProgramPath("ld.lld"));
+      !NeedsSanitizerDeps ? ToolChain.GetLinkerPath()
+                          : ToolChain.GetProgramPath("ld.lld"));
   C.addCommand(llvm::make_unique<Command>(JA, *this, Exec, CmdArgs, Inputs));
 }
 
@@ -257,16 +272,60 @@ SanitizerMask OpenBSD::getSupportedSanitizers() const 
 OpenBSD::OpenBSD(const Driver &D, const llvm::Triple &Triple,
                  const ArgList &Args)
     : Generic_ELF(D, Triple, Args) {
-  getFilePaths().push_back(getDriver().Dir + "/../lib");
-  getFilePaths().push_back("/usr/lib");
+  getFilePaths().push_back(getDriver().SysRoot + "/usr/lib");
 }
 
 void OpenBSD::AddCXXStdlibLibArgs(const ArgList &Args,
                                   ArgStringList &CmdArgs) const {
   bool Profiling = Args.hasArg(options::OPT_pg);
 
-  CmdArgs.push_back(Profiling ? "-lc++_p" : "-lc++");
-  CmdArgs.push_back(Profiling ? "-lc++abi_p" : "-lc++abi");
+  switch (GetCXXStdlibType(Args)) {
+  case ToolChain::CST_Libcxx:
+    CmdArgs.push_back(Profiling ? "-lc++_p" : "-lc++");
+    CmdArgs.push_back(Profiling ? "-lc++abi_p" : "-lc++abi");
+    CmdArgs.push_back(Profiling ? "-lpthread_p" : "-lpthread");
+    break;
+  case ToolChain::CST_Libstdcxx:
+    CmdArgs.push_back("-lestdc++");
+    break;
+  }
+}
+
+ToolChain::CXXStdlibType OpenBSD::GetCXXStdlibType(const ArgList &Args) const {
+  if (Arg *A = Args.getLastArg(options::OPT_stdlib_EQ)) {
+    StringRef Value = A->getValue();
+    if (Value == "libstdc++")
+      return ToolChain::CST_Libstdcxx;
+    if (Value == "libc++")
+      return ToolChain::CST_Libcxx;
+
+    getDriver().Diag(diag::err_drv_invalid_stdlib_name) << A->getAsString(Args);
+  }
+
+  switch (getArch()) {
+  case llvm::Triple::arm:
+  case llvm::Triple::aarch64:
+  case llvm::Triple::x86:
+  case llvm::Triple::x86_64:
+    return ToolChain::CST_Libcxx;
+    break;
+  default:
+    return ToolChain::CST_Libstdcxx;
+    break;
+  }
+}
+
+void OpenBSD::addLibStdCxxIncludePaths(const llvm::opt::ArgList &DriverArgs,
+                                       llvm::opt::ArgStringList &CC1Args) const {
+  addLibStdCXXIncludePaths(getDriver().SysRoot,
+      "${LOCALBASE}/include/c++/${GCC_VER}",
+      "", "", "", "", DriverArgs, CC1Args);
+  addLibStdCXXIncludePaths(getDriver().SysRoot,
+      "${LOCALBASE}/include/c++/${GCC_VER}/${GCC_CONFIG}",
+      "", "", "", "", DriverArgs, CC1Args);
+  addLibStdCXXIncludePaths(getDriver().SysRoot,
+      "${LOCALBASE}/include/c++/${GCC_VER}/backward",
+      "", "", "", "", DriverArgs, CC1Args);
 }
 
 Tool *OpenBSD::buildAssembler() const {
