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()); } _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits