[clang] edc1130 - [Driver] Enable selecting multiple multilibs
Michael Platings via cfe-commits
cfe-commits at lists.llvm.org
Tue Jun 13 22:47:24 PDT 2023
Author: Michael Platings
Date: 2023-06-14T06:46:41+01:00
New Revision: edc1130c0ac0e52ac5e347127972313ba928fe9a
URL: https://github.com/llvm/llvm-project/commit/edc1130c0ac0e52ac5e347127972313ba928fe9a
DIFF: https://github.com/llvm/llvm-project/commit/edc1130c0ac0e52ac5e347127972313ba928fe9a.diff
LOG: [Driver] Enable selecting multiple multilibs
This will enable layering multilibs on top of each other.
For example a multilib containing only a no-exceptions libc++ could be
layered on top of a multilib containing C libs. This avoids the need
to duplicate the C library for every libc++ variant.
This change doesn't expose the functionality externally, it only opens
the functionality up to be potentially used by ToolChain classes.
Differential Revision: https://reviews.llvm.org/D143059
Added:
Modified:
clang/include/clang/Driver/Multilib.h
clang/include/clang/Driver/ToolChain.h
clang/lib/Driver/Driver.cpp
clang/lib/Driver/Multilib.cpp
clang/lib/Driver/ToolChain.cpp
clang/lib/Driver/ToolChains/BareMetal.cpp
clang/lib/Driver/ToolChains/CSKYToolChain.cpp
clang/lib/Driver/ToolChains/Fuchsia.cpp
clang/lib/Driver/ToolChains/Gnu.cpp
clang/lib/Driver/ToolChains/Gnu.h
clang/lib/Driver/ToolChains/Hexagon.cpp
clang/lib/Driver/ToolChains/Hurd.cpp
clang/lib/Driver/ToolChains/Linux.cpp
clang/lib/Driver/ToolChains/MipsLinux.cpp
clang/lib/Driver/ToolChains/OHOS.cpp
clang/lib/Driver/ToolChains/RISCVToolchain.cpp
clang/test/Driver/fuchsia.cpp
clang/unittests/Driver/MultilibBuilderTest.cpp
clang/unittests/Driver/MultilibTest.cpp
Removed:
################################################################################
diff --git a/clang/include/clang/Driver/Multilib.h b/clang/include/clang/Driver/Multilib.h
index 493be70cfc35b..1416559414f89 100644
--- a/clang/include/clang/Driver/Multilib.h
+++ b/clang/include/clang/Driver/Multilib.h
@@ -116,11 +116,9 @@ class MultilibSet {
const_iterator begin() const { return Multilibs.begin(); }
const_iterator end() const { return Multilibs.end(); }
- /// Select compatible variants
- multilib_list select(const Multilib::flags_list &Flags) const;
-
- /// Pick the best multilib in the set, \returns false if none are compatible
- bool select(const Multilib::flags_list &Flags, Multilib &M) const;
+ /// Select compatible variants, \returns false if none are compatible
+ bool select(const Multilib::flags_list &Flags,
+ llvm::SmallVector<Multilib> &) const;
unsigned size() const { return Multilibs.size(); }
diff --git a/clang/include/clang/Driver/ToolChain.h b/clang/include/clang/Driver/ToolChain.h
index 3b3932f1e3432..7b5c430aacc7e 100644
--- a/clang/include/clang/Driver/ToolChain.h
+++ b/clang/include/clang/Driver/ToolChain.h
@@ -187,7 +187,7 @@ class ToolChain {
protected:
MultilibSet Multilibs;
- Multilib SelectedMultilib;
+ llvm::SmallVector<Multilib> SelectedMultilibs;
ToolChain(const Driver &D, const llvm::Triple &T,
const llvm::opt::ArgList &Args);
@@ -283,7 +283,9 @@ class ToolChain {
const MultilibSet &getMultilibs() const { return Multilibs; }
- const Multilib &getMultilib() const { return SelectedMultilib; }
+ const llvm::SmallVector<Multilib> &getSelectedMultilibs() const {
+ return SelectedMultilibs;
+ }
/// Get flags suitable for multilib selection, based on the provided clang
/// command line arguments. The command line arguments aren't suitable to be
diff --git a/clang/lib/Driver/Driver.cpp b/clang/lib/Driver/Driver.cpp
index 87c31f993d758..8f92606960b3a 100644
--- a/clang/lib/Driver/Driver.cpp
+++ b/clang/lib/Driver/Driver.cpp
@@ -2229,13 +2229,14 @@ bool Driver::HandleImmediateArgs(const Compilation &C) {
}
if (C.getArgs().hasArg(options::OPT_print_multi_directory)) {
- const Multilib &Multilib = TC.getMultilib();
- if (Multilib.gccSuffix().empty())
- llvm::outs() << ".\n";
- else {
- StringRef Suffix(Multilib.gccSuffix());
- assert(Suffix.front() == '/');
- llvm::outs() << Suffix.substr(1) << "\n";
+ for (const Multilib &Multilib : TC.getSelectedMultilibs()) {
+ if (Multilib.gccSuffix().empty())
+ llvm::outs() << ".\n";
+ else {
+ StringRef Suffix(Multilib.gccSuffix());
+ assert(Suffix.front() == '/');
+ llvm::outs() << Suffix.substr(1) << "\n";
+ }
}
return false;
}
diff --git a/clang/lib/Driver/Multilib.cpp b/clang/lib/Driver/Multilib.cpp
index 0e988d040a4e3..a37dffc8a6f1d 100644
--- a/clang/lib/Driver/Multilib.cpp
+++ b/clang/lib/Driver/Multilib.cpp
@@ -93,27 +93,18 @@ MultilibSet &MultilibSet::FilterOut(FilterCallback F) {
void MultilibSet::push_back(const Multilib &M) { Multilibs.push_back(M); }
-MultilibSet::multilib_list
-MultilibSet::select(const Multilib::flags_list &Flags) const {
+bool MultilibSet::select(const Multilib::flags_list &Flags,
+ llvm::SmallVector<Multilib> &Selected) const {
llvm::StringSet<> FlagSet(expandFlags(Flags));
- multilib_list Result;
- llvm::copy_if(Multilibs, std::back_inserter(Result),
+ Selected.clear();
+ llvm::copy_if(Multilibs, std::back_inserter(Selected),
[&FlagSet](const Multilib &M) {
for (const std::string &F : M.flags())
if (!FlagSet.contains(F))
return false;
return true;
});
- return Result;
-}
-
-bool MultilibSet::select(const Multilib::flags_list &Flags,
- Multilib &Selected) const {
- multilib_list Result = select(Flags);
- if (Result.empty())
- return false;
- Selected = Result.back();
- return true;
+ return !Selected.empty();
}
llvm::StringSet<>
diff --git a/clang/lib/Driver/ToolChain.cpp b/clang/lib/Driver/ToolChain.cpp
index 44b2a3d8f9d0b..0903b0ad7eb89 100644
--- a/clang/lib/Driver/ToolChain.cpp
+++ b/clang/lib/Driver/ToolChain.cpp
@@ -591,7 +591,9 @@ std::string ToolChain::getCompilerRTPath() const {
SmallString<128> Path(getDriver().ResourceDir);
if (isBareMetal()) {
llvm::sys::path::append(Path, "lib", getOSLibName());
- Path += SelectedMultilib.gccSuffix();
+ if (!SelectedMultilibs.empty()) {
+ Path += SelectedMultilibs.back().gccSuffix();
+ }
} else if (Triple.isOSUnknown()) {
llvm::sys::path::append(Path, "lib");
} else {
diff --git a/clang/lib/Driver/ToolChains/BareMetal.cpp b/clang/lib/Driver/ToolChains/BareMetal.cpp
index c167f8608945e..748f24e151aa5 100644
--- a/clang/lib/Driver/ToolChains/BareMetal.cpp
+++ b/clang/lib/Driver/ToolChains/BareMetal.cpp
@@ -54,7 +54,7 @@ static bool findRISCVMultilibs(const Driver &D,
Result.Multilibs =
MultilibSetBuilder().Either(Imac, Imafdc).makeMultilibSet();
- return Result.Multilibs.select(Flags, Result.SelectedMultilib);
+ return Result.Multilibs.select(Flags, Result.SelectedMultilibs);
}
if (TargetTriple.isRISCV32()) {
MultilibBuilder Imac =
@@ -88,7 +88,7 @@ static bool findRISCVMultilibs(const Driver &D,
Result.Multilibs =
MultilibSetBuilder().Either(I, Im, Iac, Imac, Imafc).makeMultilibSet();
- return Result.Multilibs.select(Flags, Result.SelectedMultilib);
+ return Result.Multilibs.select(Flags, Result.SelectedMultilibs);
}
return false;
}
@@ -168,7 +168,7 @@ static bool findMultilibsFromYAML(const ToolChain &TC, const Driver &D,
if (ErrorOrMultilibSet.getError())
return false;
Result.Multilibs = ErrorOrMultilibSet.get();
- return Result.Multilibs.select(Flags, Result.SelectedMultilib);
+ return Result.Multilibs.select(Flags, Result.SelectedMultilibs);
}
static constexpr llvm::StringLiteral MultilibFilename = "multilib.yaml";
@@ -200,14 +200,14 @@ void BareMetal::findMultilibs(const Driver &D, const llvm::Triple &Triple,
DetectedMultilibs Result;
if (isRISCVBareMetal(Triple)) {
if (findRISCVMultilibs(D, Triple, Args, Result)) {
- SelectedMultilib = Result.SelectedMultilib;
+ SelectedMultilibs = Result.SelectedMultilibs;
Multilibs = Result.Multilibs;
}
} else {
llvm::SmallString<128> MultilibPath(computeBaseSysRoot(D, Triple));
llvm::sys::path::append(MultilibPath, MultilibFilename);
findMultilibsFromYAML(*this, D, MultilibPath, Args, Result);
- SelectedMultilib = Result.SelectedMultilib;
+ SelectedMultilibs = Result.SelectedMultilibs;
Multilibs = Result.Multilibs;
}
}
@@ -222,8 +222,10 @@ Tool *BareMetal::buildLinker() const {
}
std::string BareMetal::computeSysRoot() const {
- return computeBaseSysRoot(getDriver(), getTriple()) +
- SelectedMultilib.osSuffix();
+ std::string Result = computeBaseSysRoot(getDriver(), getTriple());
+ if (!SelectedMultilibs.empty())
+ Result += SelectedMultilibs.back().osSuffix();
+ return Result;
}
void BareMetal::AddClangSystemIncludeArgs(const ArgList &DriverArgs,
diff --git a/clang/lib/Driver/ToolChains/CSKYToolChain.cpp b/clang/lib/Driver/ToolChains/CSKYToolChain.cpp
index de286faaca6d8..0728ad14129a9 100644
--- a/clang/lib/Driver/ToolChains/CSKYToolChain.cpp
+++ b/clang/lib/Driver/ToolChains/CSKYToolChain.cpp
@@ -38,13 +38,13 @@ CSKYToolChain::CSKYToolChain(const Driver &D, const llvm::Triple &Triple,
GCCInstallation.init(Triple, Args);
if (GCCInstallation.isValid()) {
Multilibs = GCCInstallation.getMultilibs();
- SelectedMultilib = GCCInstallation.getMultilib();
+ SelectedMultilibs.assign({GCCInstallation.getMultilib()});
path_list &Paths = getFilePaths();
// Add toolchain/multilib specific file paths.
- addMultilibsFilePaths(D, Multilibs, SelectedMultilib,
+ addMultilibsFilePaths(D, Multilibs, SelectedMultilibs.back(),
GCCInstallation.getInstallPath(), Paths);
getFilePaths().push_back(GCCInstallation.getInstallPath().str() +
- SelectedMultilib.osSuffix());
+ SelectedMultilibs.back().osSuffix());
ToolChain::path_list &PPaths = getProgramPaths();
// Multilib cross-compiler GCC installations put ld in a triple-prefixed
// directory off of the parent of the GCC installation.
@@ -52,11 +52,12 @@ CSKYToolChain::CSKYToolChain(const Driver &D, const llvm::Triple &Triple,
GCCInstallation.getTriple().str() + "/bin")
.str());
PPaths.push_back((GCCInstallation.getParentLibPath() + "/../bin").str());
+ getFilePaths().push_back(computeSysRoot() + "/lib" +
+ SelectedMultilibs.back().osSuffix());
} else {
getProgramPaths().push_back(D.Dir);
+ getFilePaths().push_back(computeSysRoot() + "/lib");
}
- getFilePaths().push_back(computeSysRoot() + "/lib" +
- SelectedMultilib.osSuffix());
}
Tool *CSKYToolChain::buildLinker() const {
diff --git a/clang/lib/Driver/ToolChains/Fuchsia.cpp b/clang/lib/Driver/ToolChains/Fuchsia.cpp
index 5a540a3c5d57d..65692cc7f954c 100644
--- a/clang/lib/Driver/ToolChains/Fuchsia.cpp
+++ b/clang/lib/Driver/ToolChains/Fuchsia.cpp
@@ -314,12 +314,17 @@ Fuchsia::Fuchsia(const Driver &D, const llvm::Triple &Triple,
Multilibs.setFilePathsCallback(FilePaths);
- if (Multilibs.select(Flags, SelectedMultilib))
- if (!SelectedMultilib.isDefault())
+ if (Multilibs.select(Flags, SelectedMultilibs)) {
+ // Ensure that -print-multi-directory only outputs one multilib directory.
+ Multilib LastSelected = SelectedMultilibs.back();
+ SelectedMultilibs = {LastSelected};
+
+ if (!SelectedMultilibs.back().isDefault())
if (const auto &PathsCallback = Multilibs.filePathsCallback())
- for (const auto &Path : PathsCallback(SelectedMultilib))
+ for (const auto &Path : PathsCallback(SelectedMultilibs.back()))
// Prepend the multilib path to ensure it takes the precedence.
getFilePaths().insert(getFilePaths().begin(), Path);
+ }
}
std::string Fuchsia::ComputeEffectiveClangTriple(const ArgList &Args,
diff --git a/clang/lib/Driver/ToolChains/Gnu.cpp b/clang/lib/Driver/ToolChains/Gnu.cpp
index 80e3c0f570a28..7d4d8e054b0a2 100644
--- a/clang/lib/Driver/ToolChains/Gnu.cpp
+++ b/clang/lib/Driver/ToolChains/Gnu.cpp
@@ -1151,7 +1151,7 @@ static bool findMipsCsMultilibs(const Multilib::flags_list &Flags,
if (CSMipsMultilibs.size() < DebianMipsMultilibs.size())
std::iter_swap(Candidates, Candidates + 1);
for (const MultilibSet *Candidate : Candidates) {
- if (Candidate->select(Flags, Result.SelectedMultilib)) {
+ if (Candidate->select(Flags, Result.SelectedMultilibs)) {
if (Candidate == &DebianMipsMultilibs)
Result.BiarchSibling = Multilib();
Result.Multilibs = *Candidate;
@@ -1200,7 +1200,7 @@ static bool findMipsAndroidMultilibs(llvm::vfs::FileSystem &VFS, StringRef Path,
MS = &AndroidMipselMultilibs;
else if (VFS.exists(Path + "/32"))
MS = &AndroidMips64elMultilibs;
- if (MS->select(Flags, Result.SelectedMultilib)) {
+ if (MS->select(Flags, Result.SelectedMultilibs)) {
Result.Multilibs = *MS;
return true;
}
@@ -1234,7 +1234,7 @@ static bool findMipsMuslMultilibs(const Multilib::flags_list &Flags,
{"/../sysroot" + M.osSuffix() + "/usr/include"});
});
}
- if (MuslMipsMultilibs.select(Flags, Result.SelectedMultilib)) {
+ if (MuslMipsMultilibs.select(Flags, Result.SelectedMultilibs)) {
Result.Multilibs = MuslMipsMultilibs;
return true;
}
@@ -1419,7 +1419,7 @@ static bool findMipsMtiMultilibs(const Multilib::flags_list &Flags,
});
}
for (auto *Candidate : {&MtiMipsMultilibsV1, &MtiMipsMultilibsV2}) {
- if (Candidate->select(Flags, Result.SelectedMultilib)) {
+ if (Candidate->select(Flags, Result.SelectedMultilibs)) {
Result.Multilibs = *Candidate;
return true;
}
@@ -1525,7 +1525,7 @@ static bool findMipsImgMultilibs(const Multilib::flags_list &Flags,
});
}
for (auto *Candidate : {&ImgMultilibsV1, &ImgMultilibsV2}) {
- if (Candidate->select(Flags, Result.SelectedMultilib)) {
+ if (Candidate->select(Flags, Result.SelectedMultilibs)) {
Result.Multilibs = *Candidate;
return true;
}
@@ -1598,7 +1598,7 @@ bool clang::driver::findMIPSMultilibs(const Driver &D,
Result.Multilibs.push_back(Default);
Result.Multilibs.FilterOut(NonExistent);
- if (Result.Multilibs.select(Flags, Result.SelectedMultilib)) {
+ if (Result.Multilibs.select(Flags, Result.SelectedMultilibs)) {
Result.BiarchSibling = Multilib();
return true;
}
@@ -1645,7 +1645,7 @@ static void findAndroidArmMultilibs(const Driver &D,
addMultilibFlag(IsArmV7Mode, "-march=armv7-a", Flags);
addMultilibFlag(IsThumbMode, "-mthumb", Flags);
- if (AndroidArmMultilibs.select(Flags, Result.SelectedMultilib))
+ if (AndroidArmMultilibs.select(Flags, Result.SelectedMultilibs))
Result.Multilibs = AndroidArmMultilibs;
}
@@ -1671,7 +1671,7 @@ static bool findMSP430Multilibs(const Driver &D,
addMultilibFlag(Args.hasFlag(options::OPT_fexceptions,
options::OPT_fno_exceptions, false),
"-exceptions", Flags);
- if (Result.Multilibs.select(Flags, Result.SelectedMultilib))
+ if (Result.Multilibs.select(Flags, Result.SelectedMultilibs))
return true;
return false;
@@ -1738,7 +1738,7 @@ static void findCSKYMultilibs(const Driver &D, const llvm::Triple &TargetTriple,
.makeMultilibSet()
.FilterOut(NonExistent);
- if (CSKYMultilibs.select(Flags, Result.SelectedMultilib))
+ if (CSKYMultilibs.select(Flags, Result.SelectedMultilibs))
Result.Multilibs = CSKYMultilibs;
}
@@ -1793,7 +1793,7 @@ static void findRISCVBareMetalMultilibs(const Driver &D,
}
}
- if (RISCVMultilibs.select(Flags, Result.SelectedMultilib))
+ if (RISCVMultilibs.select(Flags, Result.SelectedMultilibs))
Result.Multilibs = RISCVMultilibs;
}
@@ -1835,7 +1835,7 @@ static void findRISCVMultilibs(const Driver &D,
addMultilibFlag(ABIName == "lp64f", "-mabi=lp64f", Flags);
addMultilibFlag(ABIName == "lp64d", "-mabi=lp64d", Flags);
- if (RISCVMultilibs.select(Flags, Result.SelectedMultilib))
+ if (RISCVMultilibs.select(Flags, Result.SelectedMultilibs))
Result.Multilibs = RISCVMultilibs;
}
@@ -1944,11 +1944,12 @@ static bool findBiarchMultilibs(const Driver &D,
addMultilibFlag(TargetTriple.isArch32Bit(), "-m32", Flags);
addMultilibFlag(TargetTriple.isArch64Bit() && IsX32, "-mx32", Flags);
- if (!Result.Multilibs.select(Flags, Result.SelectedMultilib))
+ if (!Result.Multilibs.select(Flags, Result.SelectedMultilibs))
return false;
- if (Result.SelectedMultilib == Alt64 || Result.SelectedMultilib == Alt32 ||
- Result.SelectedMultilib == Altx32)
+ if (Result.SelectedMultilibs.back() == Alt64 ||
+ Result.SelectedMultilibs.back() == Alt32 ||
+ Result.SelectedMultilibs.back() == Altx32)
Result.BiarchSibling = Default;
return true;
@@ -2713,7 +2714,9 @@ bool Generic_GCC::GCCInstallationDetector::ScanGCCForMultilibs(
}
Multilibs = Detected.Multilibs;
- SelectedMultilib = Detected.SelectedMultilib;
+ SelectedMultilib = Detected.SelectedMultilibs.empty()
+ ? Multilib()
+ : Detected.SelectedMultilibs.back();
BiarchSibling = Detected.BiarchSibling;
return true;
@@ -2983,6 +2986,7 @@ void Generic_GCC::AddMultilibPaths(const Driver &D,
path_list &Paths) {
// Add the multilib suffixed paths where they are available.
if (GCCInstallation.isValid()) {
+ assert(!SelectedMultilibs.empty());
const llvm::Triple &GCCTriple = GCCInstallation.getTriple();
const std::string &LibPath =
std::string(GCCInstallation.getParentLibPath());
@@ -2990,13 +2994,14 @@ void Generic_GCC::AddMultilibPaths(const Driver &D,
// Sourcery CodeBench MIPS toolchain holds some libraries under
// a biarch-like suffix of the GCC installation.
if (const auto &PathsCallback = Multilibs.filePathsCallback())
- for (const auto &Path : PathsCallback(SelectedMultilib))
+ for (const auto &Path : PathsCallback(SelectedMultilibs.back()))
addPathIfExists(D, GCCInstallation.getInstallPath() + Path, Paths);
// Add lib/gcc/$triple/$version, with an optional /multilib suffix.
- addPathIfExists(
- D, GCCInstallation.getInstallPath() + SelectedMultilib.gccSuffix(),
- Paths);
+ addPathIfExists(D,
+ GCCInstallation.getInstallPath() +
+ SelectedMultilibs.back().gccSuffix(),
+ Paths);
// Add lib/gcc/$triple/$libdir
// For GCC built with --enable-version-specific-runtime-libs.
@@ -3023,7 +3028,7 @@ void Generic_GCC::AddMultilibPaths(const Driver &D,
// Clang diverges from GCC's behavior.
addPathIfExists(D,
LibPath + "/../" + GCCTriple.str() + "/lib/../" + OSLibDir +
- SelectedMultilib.osSuffix(),
+ SelectedMultilibs.back().osSuffix(),
Paths);
// If the GCC installation we found is inside of the sysroot, we want to
diff --git a/clang/lib/Driver/ToolChains/Gnu.h b/clang/lib/Driver/ToolChains/Gnu.h
index c7975c9c60394..6d335c9edb225 100644
--- a/clang/lib/Driver/ToolChains/Gnu.h
+++ b/clang/lib/Driver/ToolChains/Gnu.h
@@ -23,8 +23,8 @@ struct DetectedMultilibs {
/// The set of multilibs that the detected installation supports.
MultilibSet Multilibs;
- /// The primary multilib appropriate for the given flags.
- Multilib SelectedMultilib;
+ /// The multilibs appropriate for the given flags.
+ llvm::SmallVector<Multilib> SelectedMultilibs;
/// On Biarch systems, this corresponds to the default multilib when
/// targeting the non-default multilib. Otherwise, it is empty.
diff --git a/clang/lib/Driver/ToolChains/Hexagon.cpp b/clang/lib/Driver/ToolChains/Hexagon.cpp
index c21cff21680a4..b06297435fcfc 100644
--- a/clang/lib/Driver/ToolChains/Hexagon.cpp
+++ b/clang/lib/Driver/ToolChains/Hexagon.cpp
@@ -542,7 +542,9 @@ HexagonToolChain::getSmallDataThreshold(const ArgList &Args) {
std::string HexagonToolChain::getCompilerRTPath() const {
SmallString<128> Dir(getDriver().SysRoot);
llvm::sys::path::append(Dir, "usr", "lib");
- Dir += SelectedMultilib.gccSuffix();
+ if (!SelectedMultilibs.empty()) {
+ Dir += SelectedMultilibs.back().gccSuffix();
+ }
return std::string(Dir.str());
}
diff --git a/clang/lib/Driver/ToolChains/Hurd.cpp b/clang/lib/Driver/ToolChains/Hurd.cpp
index 48b9ccadf36f2..2dfc90ef37f75 100644
--- a/clang/lib/Driver/ToolChains/Hurd.cpp
+++ b/clang/lib/Driver/ToolChains/Hurd.cpp
@@ -65,7 +65,7 @@ Hurd::Hurd(const Driver &D, const llvm::Triple &Triple, const ArgList &Args)
: Generic_ELF(D, Triple, Args) {
GCCInstallation.init(Triple, Args);
Multilibs = GCCInstallation.getMultilibs();
- SelectedMultilib = GCCInstallation.getMultilib();
+ SelectedMultilibs.assign({GCCInstallation.getMultilib()});
std::string SysRoot = computeSysRoot();
ToolChain::path_list &PPaths = getProgramPaths();
diff --git a/clang/lib/Driver/ToolChains/Linux.cpp b/clang/lib/Driver/ToolChains/Linux.cpp
index 920da6e4bfd49..33a431a54da67 100644
--- a/clang/lib/Driver/ToolChains/Linux.cpp
+++ b/clang/lib/Driver/ToolChains/Linux.cpp
@@ -213,7 +213,7 @@ Linux::Linux(const Driver &D, const llvm::Triple &Triple, const ArgList &Args)
: Generic_ELF(D, Triple, Args) {
GCCInstallation.init(Triple, Args);
Multilibs = GCCInstallation.getMultilibs();
- SelectedMultilib = GCCInstallation.getMultilib();
+ SelectedMultilibs.assign({GCCInstallation.getMultilib()});
llvm::Triple::ArchType Arch = Triple.getArch();
std::string SysRoot = computeSysRoot();
ToolChain::path_list &PPaths = getProgramPaths();
@@ -257,8 +257,8 @@ Linux::Linux(const Driver &D, const llvm::Triple &Triple, const ArgList &Args)
const bool IsRISCV = Triple.isRISCV();
const bool IsCSKY = Triple.isCSKY();
- if (IsCSKY)
- SysRoot = SysRoot + SelectedMultilib.osSuffix();
+ if (IsCSKY && !SelectedMultilibs.empty())
+ SysRoot = SysRoot + SelectedMultilibs.back().osSuffix();
if ((IsMips || IsCSKY) && !SysRoot.empty())
ExtraOpts.push_back("--sysroot=" + SysRoot);
diff --git a/clang/lib/Driver/ToolChains/MipsLinux.cpp b/clang/lib/Driver/ToolChains/MipsLinux.cpp
index 9c58583bca770..6157970233ae5 100644
--- a/clang/lib/Driver/ToolChains/MipsLinux.cpp
+++ b/clang/lib/Driver/ToolChains/MipsLinux.cpp
@@ -30,7 +30,7 @@ MipsLLVMToolChain::MipsLLVMToolChain(const Driver &D,
DetectedMultilibs Result;
findMIPSMultilibs(D, Triple, "", Args, Result);
Multilibs = Result.Multilibs;
- SelectedMultilib = Result.SelectedMultilib;
+ SelectedMultilibs = Result.SelectedMultilibs;
// Find out the library suffix based on the ABI.
LibSuffix = tools::mips::getMipsABILibSuffix(Args, Triple);
diff --git a/clang/lib/Driver/ToolChains/OHOS.cpp b/clang/lib/Driver/ToolChains/OHOS.cpp
index 0fdcafe898d70..1e50c9d71d59c 100644
--- a/clang/lib/Driver/ToolChains/OHOS.cpp
+++ b/clang/lib/Driver/ToolChains/OHOS.cpp
@@ -50,7 +50,7 @@ static bool findOHOSMuslMultilibs(const Multilib::flags_list &Flags,
Multilib("/a7_hard_neon-vfpv4", {}, {},
{"-mcpu=cortex-a7", "-mfloat-abi=hard", "-mfpu=neon-vfpv4"}));
- if (Multilibs.select(Flags, Result.SelectedMultilib)) {
+ if (Multilibs.select(Flags, Result.SelectedMultilibs)) {
Result.Multilibs = Multilibs;
return true;
}
@@ -136,7 +136,10 @@ OHOS::OHOS(const Driver &D, const llvm::Triple &Triple, const ArgList &Args)
DetectedMultilibs Result;
findOHOSMultilibs(D, *this, Triple, "", Args, Result);
Multilibs = Result.Multilibs;
- SelectedMultilib = Result.SelectedMultilib;
+ SelectedMultilibs = Result.SelectedMultilibs;
+ if (!SelectedMultilibs.empty()) {
+ SelectedMultilib = SelectedMultilibs.back();
+ }
getFilePaths().clear();
for (const auto &CandidateLibPath : getArchSpecificLibPaths())
diff --git a/clang/lib/Driver/ToolChains/RISCVToolchain.cpp b/clang/lib/Driver/ToolChains/RISCVToolchain.cpp
index a3cd9b2bfa90d..e2e5dea2da2b7 100644
--- a/clang/lib/Driver/ToolChains/RISCVToolchain.cpp
+++ b/clang/lib/Driver/ToolChains/RISCVToolchain.cpp
@@ -53,10 +53,10 @@ RISCVToolChain::RISCVToolChain(const Driver &D, const llvm::Triple &Triple,
GCCInstallation.init(Triple, Args);
if (GCCInstallation.isValid()) {
Multilibs = GCCInstallation.getMultilibs();
- SelectedMultilib = GCCInstallation.getMultilib();
+ SelectedMultilibs.assign({GCCInstallation.getMultilib()});
path_list &Paths = getFilePaths();
// Add toolchain/multilib specific file paths.
- addMultilibsFilePaths(D, Multilibs, SelectedMultilib,
+ addMultilibsFilePaths(D, Multilibs, SelectedMultilibs.back(),
GCCInstallation.getInstallPath(), Paths);
getFilePaths().push_back(GCCInstallation.getInstallPath().str());
ToolChain::path_list &PPaths = getProgramPaths();
diff --git a/clang/test/Driver/fuchsia.cpp b/clang/test/Driver/fuchsia.cpp
index 01ebcb146ca60..caccca19b80e2 100644
--- a/clang/test/Driver/fuchsia.cpp
+++ b/clang/test/Driver/fuchsia.cpp
@@ -139,3 +139,14 @@
// CHECK-MULTILIB-HWASAN-NOEXCEPT-X86: "-L{{.*}}{{/|\\\\}}..{{/|\\\\}}lib{{/|\\\\}}x86_64-unknown-fuchsia{{/|\\\\}}hwasan+noexcept"
// CHECK-MULTILIB-COMPAT-X86: "-L{{.*}}{{/|\\\\}}..{{/|\\\\}}lib{{/|\\\\}}x86_64-unknown-fuchsia{{/|\\\\}}compat"
// CHECK-MULTILIB-X86: "-L{{.*}}{{/|\\\\}}..{{/|\\\\}}lib{{/|\\\\}}x86_64-unknown-fuchsia"
+
+// Check that -print-multi-directory only outputs one multilib directory.
+// This may be relaxed later but for now preserve existing behaviour.
+// RUN: %clangxx -print-multi-directory --target=x86_64-unknown-fuchsia -fsanitize=address -fno-exceptions \
+// RUN: -ccc-install-dir %S/Inputs/basic_fuchsia_tree/bin \
+// RUN: -resource-dir=%S/Inputs/resource_dir_with_per_target_subdir \
+// RUN: | FileCheck %s -check-prefixes=CHECK-PRINT-MULTI-LIB
+// CHECK-PRINT-MULTI-LIB-NOT: .
+// CHECK-PRINT-MULTI-LIB-NOT: noexcept
+// CHECK-PRINT-MULTI-LIB-NOT: asan
+// CHECK-PRINT-MULTI-LIB: asan+noexcept
diff --git a/clang/unittests/Driver/MultilibBuilderTest.cpp b/clang/unittests/Driver/MultilibBuilderTest.cpp
index 6958f01f73a2f..60fe10ac3ba55 100644
--- a/clang/unittests/Driver/MultilibBuilderTest.cpp
+++ b/clang/unittests/Driver/MultilibBuilderTest.cpp
@@ -163,18 +163,20 @@ TEST(MultilibBuilderTest, SetSelection1) {
.makeMultilibSet();
Multilib::flags_list FlagM64 = {"-m64"};
- Multilib SelectionM64;
+ llvm::SmallVector<Multilib> SelectionM64;
ASSERT_TRUE(MS1.select(FlagM64, SelectionM64))
<< "Flag set was {\"-m64\"}, but selection not found";
- ASSERT_TRUE(SelectionM64.gccSuffix() == "/64")
- << "Selection picked " << SelectionM64 << " which was not expected";
+ ASSERT_TRUE(SelectionM64.back().gccSuffix() == "/64")
+ << "Selection picked " << SelectionM64.back()
+ << " which was not expected";
Multilib::flags_list FlagNoM64 = {"!m64"};
- Multilib SelectionNoM64;
+ llvm::SmallVector<Multilib> SelectionNoM64;
ASSERT_TRUE(MS1.select(FlagNoM64, SelectionNoM64))
<< "Flag set was {\"!m64\"}, but selection not found";
- ASSERT_TRUE(SelectionNoM64.gccSuffix() == "")
- << "Selection picked " << SelectionNoM64 << " which was not expected";
+ ASSERT_TRUE(SelectionNoM64.back().gccSuffix() == "")
+ << "Selection picked " << SelectionNoM64.back()
+ << " which was not expected";
}
TEST(MultilibBuilderTest, SetSelection2) {
@@ -197,7 +199,7 @@ TEST(MultilibBuilderTest, SetSelection2) {
else
Flags.push_back("!SF");
- Multilib Selection;
+ llvm::SmallVector<Multilib> Selection;
ASSERT_TRUE(MS2.select(Flags, Selection))
<< "Selection failed for " << (IsEL ? "-EL" : "!EL") << " "
<< (IsSF ? "-SF" : "!SF");
@@ -208,7 +210,8 @@ TEST(MultilibBuilderTest, SetSelection2) {
if (IsSF)
Suffix += "/sf";
- ASSERT_EQ(Selection.gccSuffix(), Suffix)
- << "Selection picked " << Selection << " which was not expected ";
+ ASSERT_EQ(Selection.back().gccSuffix(), Suffix)
+ << "Selection picked " << Selection.back()
+ << " which was not expected ";
}
}
diff --git a/clang/unittests/Driver/MultilibTest.cpp b/clang/unittests/Driver/MultilibTest.cpp
index 087ec35e48149..ed9ac58cecd7b 100644
--- a/clang/unittests/Driver/MultilibTest.cpp
+++ b/clang/unittests/Driver/MultilibTest.cpp
@@ -154,18 +154,18 @@ TEST(MultilibTest, SetPriority) {
Multilib("/bar", {}, {}, {"+bar"}),
});
Multilib::flags_list Flags1 = {"+foo", "-bar"};
- Multilib Selection1;
+ llvm::SmallVector<Multilib> Selection1;
ASSERT_TRUE(MS.select(Flags1, Selection1))
<< "Flag set was {\"+foo\"}, but selection not found";
- ASSERT_TRUE(Selection1.gccSuffix() == "/foo")
- << "Selection picked " << Selection1 << " which was not expected";
+ ASSERT_TRUE(Selection1.back().gccSuffix() == "/foo")
+ << "Selection picked " << Selection1.back() << " which was not expected";
Multilib::flags_list Flags2 = {"+foo", "+bar"};
- Multilib Selection2;
+ llvm::SmallVector<Multilib> Selection2;
ASSERT_TRUE(MS.select(Flags2, Selection2))
<< "Flag set was {\"+bar\"}, but selection not found";
- ASSERT_TRUE(Selection2.gccSuffix() == "/bar")
- << "Selection picked " << Selection2 << " which was not expected";
+ ASSERT_TRUE(Selection2.back().gccSuffix() == "/bar")
+ << "Selection picked " << Selection2.back() << " which was not expected";
}
TEST(MultilibTest, SelectMultiple) {
@@ -173,17 +173,17 @@ TEST(MultilibTest, SelectMultiple) {
Multilib("/a", {}, {}, {"x"}),
Multilib("/b", {}, {}, {"y"}),
});
- std::vector<Multilib> Selection;
+ llvm::SmallVector<Multilib> Selection;
- Selection = MS.select({"x"});
+ ASSERT_TRUE(MS.select({"x"}, Selection));
ASSERT_EQ(1u, Selection.size());
EXPECT_EQ("/a", Selection[0].gccSuffix());
- Selection = MS.select({"y"});
+ ASSERT_TRUE(MS.select({"y"}, Selection));
ASSERT_EQ(1u, Selection.size());
EXPECT_EQ("/b", Selection[0].gccSuffix());
- Selection = MS.select({"y", "x"});
+ ASSERT_TRUE(MS.select({"y", "x"}, Selection));
ASSERT_EQ(2u, Selection.size());
EXPECT_EQ("/a", Selection[0].gccSuffix());
EXPECT_EQ("/b", Selection[1].gccSuffix());
@@ -355,7 +355,7 @@ TEST(MultilibTest, Parse) {
TEST(MultilibTest, SelectSoft) {
MultilibSet MS;
- Multilib Selected;
+ llvm::SmallVector<Multilib> Selected;
ASSERT_TRUE(parseYaml(MS, YAML_PREAMBLE R"(
Variants:
- Dir: s
@@ -371,7 +371,7 @@ TEST(MultilibTest, SelectSoft) {
TEST(MultilibTest, SelectSoftFP) {
MultilibSet MS;
- Multilib Selected;
+ llvm::SmallVector<Multilib> Selected;
ASSERT_TRUE(parseYaml(MS, YAML_PREAMBLE R"(
Variants:
- Dir: f
@@ -386,7 +386,7 @@ TEST(MultilibTest, SelectHard) {
// If hard float is all that's available then select that only if compiling
// with hard float.
MultilibSet MS;
- Multilib Selected;
+ llvm::SmallVector<Multilib> Selected;
ASSERT_TRUE(parseYaml(MS, YAML_PREAMBLE R"(
Variants:
- Dir: h
@@ -399,7 +399,7 @@ TEST(MultilibTest, SelectHard) {
TEST(MultilibTest, SelectFloatABI) {
MultilibSet MS;
- Multilib Selected;
+ llvm::SmallVector<Multilib> Selected;
ASSERT_TRUE(parseYaml(MS, YAML_PREAMBLE R"(
Variants:
- Dir: s
@@ -413,18 +413,18 @@ TEST(MultilibTest, SelectFloatABI) {
Flags: [-mfloat-abi=soft]
)"));
MS.select({"-mfloat-abi=soft"}, Selected);
- EXPECT_EQ("/s", Selected.gccSuffix());
+ EXPECT_EQ("/s", Selected.back().gccSuffix());
MS.select({"-mfloat-abi=softfp"}, Selected);
- EXPECT_EQ("/f", Selected.gccSuffix());
+ EXPECT_EQ("/f", Selected.back().gccSuffix());
MS.select({"-mfloat-abi=hard"}, Selected);
- EXPECT_EQ("/h", Selected.gccSuffix());
+ EXPECT_EQ("/h", Selected.back().gccSuffix());
}
TEST(MultilibTest, SelectFloatABIReversed) {
// If soft is specified after softfp then softfp will never be
// selected because soft is compatible with softfp and last wins.
MultilibSet MS;
- Multilib Selected;
+ llvm::SmallVector<Multilib> Selected;
ASSERT_TRUE(parseYaml(MS, YAML_PREAMBLE R"(
Variants:
- Dir: h
@@ -438,11 +438,11 @@ TEST(MultilibTest, SelectFloatABIReversed) {
Flags: [-mfloat-abi=soft]
)"));
MS.select({"-mfloat-abi=soft"}, Selected);
- EXPECT_EQ("/s", Selected.gccSuffix());
+ EXPECT_EQ("/s", Selected.back().gccSuffix());
MS.select({"-mfloat-abi=softfp"}, Selected);
- EXPECT_EQ("/s", Selected.gccSuffix());
+ EXPECT_EQ("/s", Selected.back().gccSuffix());
MS.select({"-mfloat-abi=hard"}, Selected);
- EXPECT_EQ("/h", Selected.gccSuffix());
+ EXPECT_EQ("/h", Selected.back().gccSuffix());
}
TEST(MultilibTest, SelectMClass) {
@@ -490,48 +490,48 @@ TEST(MultilibTest, SelectMClass) {
)";
MultilibSet MS;
- Multilib Selected;
+ llvm::SmallVector<Multilib> Selected;
ASSERT_TRUE(parseYaml(MS, MultilibSpec));
ASSERT_TRUE(MS.select({"--target=thumbv6m-none-unknown-eabi", "-mfpu=none"},
Selected));
- EXPECT_EQ("/thumb/v6-m/nofp", Selected.gccSuffix());
+ EXPECT_EQ("/thumb/v6-m/nofp", Selected.back().gccSuffix());
ASSERT_TRUE(MS.select({"--target=thumbv7m-none-unknown-eabi", "-mfpu=none"},
Selected));
- EXPECT_EQ("/thumb/v7-m/nofp", Selected.gccSuffix());
+ EXPECT_EQ("/thumb/v7-m/nofp", Selected.back().gccSuffix());
ASSERT_TRUE(MS.select({"--target=thumbv7em-none-unknown-eabi", "-mfpu=none"},
Selected));
- EXPECT_EQ("/thumb/v7e-m/nofp", Selected.gccSuffix());
+ EXPECT_EQ("/thumb/v7e-m/nofp", Selected.back().gccSuffix());
ASSERT_TRUE(MS.select(
{"--target=thumbv8m.main-none-unknown-eabi", "-mfpu=none"}, Selected));
- EXPECT_EQ("/thumb/v8-m.main/nofp", Selected.gccSuffix());
+ EXPECT_EQ("/thumb/v8-m.main/nofp", Selected.back().gccSuffix());
ASSERT_TRUE(MS.select(
{"--target=thumbv8.1m.main-none-unknown-eabi", "-mfpu=none"}, Selected));
- EXPECT_EQ("/thumb/v8.1-m.main/nofp/nomve", Selected.gccSuffix());
+ EXPECT_EQ("/thumb/v8.1-m.main/nofp/nomve", Selected.back().gccSuffix());
ASSERT_TRUE(
MS.select({"--target=thumbv7em-none-unknown-eabihf", "-mfpu=fpv4-sp-d16"},
Selected));
- EXPECT_EQ("/thumb/v7e-m/fpv4_sp_d16", Selected.gccSuffix());
+ EXPECT_EQ("/thumb/v7e-m/fpv4_sp_d16", Selected.back().gccSuffix());
ASSERT_TRUE(MS.select(
{"--target=thumbv7em-none-unknown-eabihf", "-mfpu=fpv5-d16"}, Selected));
- EXPECT_EQ("/thumb/v7e-m/fpv5_d16", Selected.gccSuffix());
+ EXPECT_EQ("/thumb/v7e-m/fpv5_d16", Selected.back().gccSuffix());
ASSERT_TRUE(
MS.select({"--target=thumbv8m.main-none-unknown-eabihf"}, Selected));
- EXPECT_EQ("/thumb/v8-m.main/fp", Selected.gccSuffix());
+ EXPECT_EQ("/thumb/v8-m.main/fp", Selected.back().gccSuffix());
ASSERT_TRUE(
MS.select({"--target=thumbv8.1m.main-none-unknown-eabihf"}, Selected));
- EXPECT_EQ("/thumb/v8.1-m.main/fp", Selected.gccSuffix());
+ EXPECT_EQ("/thumb/v8.1-m.main/fp", Selected.back().gccSuffix());
ASSERT_TRUE(MS.select({"--target=thumbv8.1m.main-none-unknown-eabihf",
"-mfpu=none", "-march=thumbv8.1m.main+dsp+mve"},
Selected));
- EXPECT_EQ("/thumb/v8.1-m.main/nofp/mve", Selected.gccSuffix());
+ EXPECT_EQ("/thumb/v8.1-m.main/nofp/mve", Selected.back().gccSuffix());
}
More information about the cfe-commits
mailing list