phosek created this revision.
phosek added reviewers: beanz, jroelofs, mcgrathr.
Herald added subscribers: cfe-commits, javed.absar.
Herald added a project: clang.

This introduces a support for multilibs to Fuchsia driver. Unlike the
existing multilibs that are used primarily for handling different
architecture variants, we use multilibs to handle different variants
of Clang runtime libraries: -fsanitize=address and -fno-exceptions
are the two we support initially. This replaces the existing support
for sanitized runtimes libraries that was only used by Fuchsia driver
and it also refactors some of the logic to allow sharing between GNU
and Fuchsia drivers.


Repository:
  rC Clang

https://reviews.llvm.org/D61040

Files:
  clang/lib/Driver/ToolChains/CommonArgs.cpp
  clang/lib/Driver/ToolChains/CommonArgs.h
  clang/lib/Driver/ToolChains/Fuchsia.cpp
  clang/lib/Driver/ToolChains/Gnu.cpp
  
clang/test/Driver/Inputs/resource_dir_with_per_target_subdir/aarch64-fuchsia/lib/noexcept/.keep
  
clang/test/Driver/Inputs/resource_dir_with_per_target_subdir/x86_64-fuchsia/lib/noexcept/.keep
  clang/test/Driver/fuchsia.cpp

Index: clang/test/Driver/fuchsia.cpp
===================================================================
--- clang/test/Driver/fuchsia.cpp
+++ clang/test/Driver/fuchsia.cpp
@@ -49,3 +49,19 @@
 // CHECK-NOSTDLIBXX-NOT: "-lc++"
 // CHECK-NOSTDLIBXX-NOT: "-lm"
 // CHECK-NOSTDLIBXX: "-lc"
+
+// RUN: %clang %s -### --target=x86_64-fuchsia -fno-exceptions \
+// RUN:     -resource-dir=%S/Inputs/resource_dir_with_per_target_subdir \
+// RUN:     -fuse-ld=lld 2>&1\
+// RUN:     | FileCheck %s -check-prefix=CHECK-NOEXCEPTIONS-X86
+// CHECK-NOEXCEPTIONS-X86: "-resource-dir" "[[RESOURCE_DIR:[^"]+]]"
+// CHECK-NOEXCEPTIONS-X86: "-L[[RESOURCE_DIR]]{{/|\\\\}}x86_64-fuchsia{{/|\\\\}}lib{{/|\\\\}}noexcept"
+// CHECK-NOEXCEPTIONS-X86: "-L[[RESOURCE_DIR]]{{/|\\\\}}x86_64-fuchsia{{/|\\\\}}lib"
+
+// RUN: %clang %s -### --target=aarch64-fuchsia -fno-exceptions \
+// RUN:     -resource-dir=%S/Inputs/resource_dir_with_per_target_subdir \
+// RUN:     -fuse-ld=lld 2>&1\
+// RUN:     | FileCheck %s -check-prefix=CHECK-NOEXCEPTIONS-AARCH64
+// CHECK-NOEXCEPTIONS-AARCH64: "-resource-dir" "[[RESOURCE_DIR:[^"]+]]"
+// CHECK-NOEXCEPTIONS-AARCH64: "-L[[RESOURCE_DIR]]{{/|\\\\}}aarch64-fuchsia{{/|\\\\}}lib{{/|\\\\}}noexcept"
+// CHECK-NOEXCEPTIONS-AARCH64: "-L[[RESOURCE_DIR]]{{/|\\\\}}aarch64-fuchsia{{/|\\\\}}lib"
Index: clang/lib/Driver/ToolChains/Gnu.cpp
===================================================================
--- clang/lib/Driver/ToolChains/Gnu.cpp
+++ clang/lib/Driver/ToolChains/Gnu.cpp
@@ -33,6 +33,8 @@
 using namespace clang;
 using namespace llvm::opt;
 
+using tools::addMultilibFlag;
+
 void tools::GnuTool::anchor() {}
 
 static bool forwardToGCC(const Option &O) {
@@ -871,16 +873,6 @@
           A->getValue() == StringRef("soft"));
 }
 
-/// \p Flag must be a flag accepted by the driver with its leading '-' removed,
-//     otherwise '-print-multi-lib' will not emit them correctly.
-static void addMultilibFlag(bool Enabled, const char *const Flag,
-                            std::vector<std::string> &Flags) {
-  if (Enabled)
-    Flags.push_back(std::string("+") + Flag);
-  else
-    Flags.push_back(std::string("-") + Flag);
-}
-
 static bool isArmOrThumbArch(llvm::Triple::ArchType Arch) {
   return Arch == llvm::Triple::arm || Arch == llvm::Triple::thumb;
 }
Index: clang/lib/Driver/ToolChains/Fuchsia.cpp
===================================================================
--- clang/lib/Driver/ToolChains/Fuchsia.cpp
+++ clang/lib/Driver/ToolChains/Fuchsia.cpp
@@ -15,7 +15,9 @@
 #include "clang/Driver/Options.h"
 #include "clang/Driver/SanitizerArgs.h"
 #include "llvm/Option/ArgList.h"
+#include "llvm/Support/FileSystem.h"
 #include "llvm/Support/Path.h"
+#include "llvm/Support/VirtualFileSystem.h"
 
 using namespace clang::driver;
 using namespace clang::driver::toolchains;
@@ -23,6 +25,8 @@
 using namespace clang;
 using namespace llvm::opt;
 
+using tools::addMultilibFlag;
+
 void fuchsia::Linker::ConstructJob(Compilation &C, const JobAction &JA,
                                    const InputInfo &Output,
                                    const InputInfoList &Inputs,
@@ -98,8 +102,6 @@
   Args.AddAllArgs(CmdArgs, options::OPT_L);
   Args.AddAllArgs(CmdArgs, options::OPT_u);
 
-  addSanitizerPathLibArgs(ToolChain, Args, CmdArgs);
-
   ToolChain.AddFilePathLibArgs(Args, CmdArgs);
 
   if (D.isUsingLTO()) {
@@ -169,6 +171,36 @@
     llvm::sys::path::append(P, "lib");
     getFilePaths().push_back(P.str());
   }
+
+  Multilib Default;
+  Multilib NoExcept = Multilib("/noexcept", "", "", 1)
+                          .flag("-fexceptions")
+                          .flag("+fno-exceptions");
+  Multilib ASan = Multilib("/asan", "", "", 2).flag("+fsanitize=address");
+  Multilibs.push_back(Default);
+  Multilibs.push_back(NoExcept);
+  Multilibs.push_back(ASan);
+  Multilibs.FilterOut([&](const Multilib &M) {
+    SmallString<128> P(D.ResourceDir);
+    llvm::sys::path::append(P, D.getTargetTriple(), "lib", M.gccSuffix());
+    return !getVFS().exists(P);
+  });
+
+  Multilib::flags_list Flags;
+  addMultilibFlag(
+      Args.hasFlag(options::OPT_fexceptions, options::OPT_fno_exceptions, true),
+      "fexceptions", Flags);
+  addMultilibFlag(getSanitizerArgs().needsAsanRt(), "fsanitize=address", Flags);
+  Multilibs.select(Flags, SelectedMultilib);
+  Multilibs.setFilePathsCallback([&](const Multilib &M) {
+    SmallString<128> P(D.ResourceDir);
+    llvm::sys::path::append(P, D.getTargetTriple(), "lib", M.gccSuffix());
+    return std::vector<std::string>({P.str()});
+  });
+
+  if (const auto &PathsCallback = Multilibs.filePathsCallback())
+    for (const auto &Path : PathsCallback(SelectedMultilib))
+      getLibraryPaths().insert(getLibraryPaths().begin(), Path);
 }
 
 std::string Fuchsia::ComputeEffectiveClangTriple(const ArgList &Args,
Index: clang/lib/Driver/ToolChains/CommonArgs.h
===================================================================
--- clang/lib/Driver/ToolChains/CommonArgs.h
+++ clang/lib/Driver/ToolChains/CommonArgs.h
@@ -11,6 +11,7 @@
 
 #include "InputInfo.h"
 #include "clang/Driver/Driver.h"
+#include "clang/Driver/Multilib.h"
 #include "clang/Driver/Tool.h"
 #include "clang/Driver/ToolChain.h"
 #include "llvm/Support/CodeGen.h"
@@ -31,10 +32,6 @@
 bool addSanitizerRuntimes(const ToolChain &TC, const llvm::opt::ArgList &Args,
                           llvm::opt::ArgStringList &CmdArgs);
 
-void addSanitizerPathLibArgs(const ToolChain &TC,
-                             const llvm::opt::ArgList &Args,
-                             llvm::opt::ArgStringList &CmdArgs);
-
 void linkSanitizerRuntimeDeps(const ToolChain &TC,
                               llvm::opt::ArgStringList &CmdArgs);
 
@@ -121,6 +118,12 @@
 SmallString<128> getStatsFileName(const llvm::opt::ArgList &Args,
                                   const InputInfo &Output,
                                   const InputInfo &Input, const Driver &D);
+
+/// \p Flag must be a flag accepted by the driver with its leading '-' removed,
+//     otherwise '-print-multi-lib' will not emit them correctly.
+void addMultilibFlag(bool Enabled, const char *const Flag,
+                     Multilib::flags_list &Flags);
+
 } // end namespace tools
 } // end namespace driver
 } // end namespace clang
Index: clang/lib/Driver/ToolChains/CommonArgs.cpp
===================================================================
--- clang/lib/Driver/ToolChains/CommonArgs.cpp
+++ clang/lib/Driver/ToolChains/CommonArgs.cpp
@@ -570,40 +570,6 @@
   return false;
 }
 
-static void addSanitizerLibPath(const ToolChain &TC, const ArgList &Args,
-                                ArgStringList &CmdArgs, StringRef Name) {
-  for (const auto &LibPath : TC.getLibraryPaths()) {
-    if (!LibPath.empty()) {
-      SmallString<128> P(LibPath);
-      llvm::sys::path::append(P, Name);
-      if (TC.getVFS().exists(P))
-        CmdArgs.push_back(Args.MakeArgString(StringRef("-L") + P));
-    }
-  }
-}
-
-void tools::addSanitizerPathLibArgs(const ToolChain &TC, const ArgList &Args,
-                                    ArgStringList &CmdArgs) {
-  const SanitizerArgs &SanArgs = TC.getSanitizerArgs();
-  if (SanArgs.needsAsanRt()) {
-    addSanitizerLibPath(TC, Args, CmdArgs, "asan");
-  }
-  if (SanArgs.needsHwasanRt()) {
-    addSanitizerLibPath(TC, Args, CmdArgs, "hwasan");
-  }
-  if (SanArgs.needsLsanRt()) {
-    addSanitizerLibPath(TC, Args, CmdArgs, "lsan");
-  }
-  if (SanArgs.needsMsanRt()) {
-    addSanitizerLibPath(TC, Args, CmdArgs, "msan");
-  }
-  if (SanArgs.needsTsanRt()) {
-    addSanitizerLibPath(TC, Args, CmdArgs, "tsan");
-  }
-}
-
-
-
 void tools::linkSanitizerRuntimeDeps(const ToolChain &TC,
                                      ArgStringList &CmdArgs) {
   // Force linking against the system libraries sanitizers depends on
@@ -1535,3 +1501,11 @@
   llvm::sys::path::replace_extension(StatsFile, "stats");
   return StatsFile;
 }
+
+void tools::addMultilibFlag(bool Enabled, const char *const Flag,
+                            Multilib::flags_list &Flags) {
+  if (Enabled)
+    Flags.push_back(std::string("+") + Flag);
+  else
+    Flags.push_back(std::string("-") + Flag);
+}
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to