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); +} 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({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/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 &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/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"