diff --git a/clang/include/clang/Driver/Multilib.h b/clang/include/clang/Driver/Multilib.h --- a/clang/include/clang/Driver/Multilib.h +++ b/clang/include/clang/Driver/Multilib.h @@ -114,11 +114,9 @@ const_iterator begin() const { return Multilibs.begin(); } const_iterator end() const { return Multilibs.end(); } - /// Select compatible variants - std::vector 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 &) const; unsigned size() const { return Multilibs.size(); } diff --git a/clang/include/clang/Driver/ToolChain.h b/clang/include/clang/Driver/ToolChain.h --- a/clang/include/clang/Driver/ToolChain.h +++ b/clang/include/clang/Driver/ToolChain.h @@ -187,7 +187,7 @@ protected: MultilibSet Multilibs; - Multilib SelectedMultilib; + llvm::SmallVector SelectedMultilibs; ToolChain(const Driver &D, const llvm::Triple &T, const llvm::opt::ArgList &Args); @@ -283,7 +283,9 @@ const MultilibSet &getMultilibs() const { return Multilibs; } - const Multilib &getMultilib() const { return SelectedMultilib; } + const llvm::SmallVector &getSelectedMultilibs() const { + return SelectedMultilibs; + } /// Get flags suitable for multilib selection, based on the provided clang /// command line arguments. The arguments aren't suitable to be used directly diff --git a/clang/lib/Driver/Driver.cpp b/clang/lib/Driver/Driver.cpp --- a/clang/lib/Driver/Driver.cpp +++ b/clang/lib/Driver/Driver.cpp @@ -2216,13 +2216,14 @@ } 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 --- a/clang/lib/Driver/Multilib.cpp +++ b/clang/lib/Driver/Multilib.cpp @@ -82,26 +82,16 @@ void MultilibSet::push_back(const Multilib &M) { Multilibs.push_back(M); } -std::vector -MultilibSet::select(const Multilib::flags_list &Flags) const { +bool MultilibSet::select(const Multilib::flags_list &Flags, + llvm::SmallVector &Selected) const { Multilib::flags_list AllFlags(expandFlags(Flags)); - multilib_list Result; - llvm::copy_if(Multilibs, std::back_inserter(Result), + Selected.clear(); + llvm::copy_if(Multilibs, std::back_inserter(Selected), [&AllFlags](const Multilib &M) { return std::includes(AllFlags.begin(), AllFlags.end(), M.flags().begin(), M.flags().end()); }); - return Result; -} - -bool MultilibSet::select(const Multilib::flags_list &Flags, - Multilib &Selected) const { - std::vector Result = select(Flags); - if (Result.empty()) { - return false; - } - Selected = Result.back(); - return true; + return !Selected.empty(); } Multilib::flags_list diff --git a/clang/lib/Driver/ToolChain.cpp b/clang/lib/Driver/ToolChain.cpp --- a/clang/lib/Driver/ToolChain.cpp +++ b/clang/lib/Driver/ToolChain.cpp @@ -596,7 +596,9 @@ 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 --- a/clang/lib/Driver/ToolChains/BareMetal.cpp +++ b/clang/lib/Driver/ToolChains/BareMetal.cpp @@ -56,7 +56,7 @@ addMultilibFlag(Abi == "lp64d", "mabi=lp64d", Flags); Result.Multilibs = MultilibBuilder().Either(Imac, Imafdc).makeMultilibSet(); - return Result.Multilibs.select(Flags, Result.SelectedMultilib); + return Result.Multilibs.select(Flags, Result.SelectedMultilibs); } if (TargetTriple.isRISCV32()) { auto Imac = makeMultilib("").flag("+march=rv32imac").flag("+mabi=ilp32"); @@ -87,7 +87,7 @@ Result.Multilibs = MultilibBuilder().Either(I, Im, Iac, Imac, Imafc).makeMultilibSet(); - return Result.Multilibs.select(Flags, Result.SelectedMultilib); + return Result.Multilibs.select(Flags, Result.SelectedMultilibs); } return false; } @@ -169,7 +169,7 @@ } Multilib::flags_list Flags(ArgsFlags.begin(), ArgsFlags.end()); - return Result.Multilibs.select(Flags, Result.SelectedMultilib); + return Result.Multilibs.select(Flags, Result.SelectedMultilibs); } #define MULTILIB_YAML_FILENAME "multilib.yaml" @@ -202,14 +202,14 @@ 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, MULTILIB_YAML_FILENAME); findMultilibsFromYAML(*this, D, MultilibPath, Args, Result); - SelectedMultilib = Result.SelectedMultilib; + SelectedMultilibs = Result.SelectedMultilibs; Multilibs = Result.Multilibs; } } @@ -224,8 +224,11 @@ } 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 --- a/clang/lib/Driver/ToolChains/CSKYToolChain.cpp +++ b/clang/lib/Driver/ToolChains/CSKYToolChain.cpp @@ -38,13 +38,13 @@ 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 @@ 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 --- a/clang/lib/Driver/ToolChains/Fuchsia.cpp +++ b/clang/lib/Driver/ToolChains/Fuchsia.cpp @@ -278,12 +278,17 @@ 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. + SelectedMultilibs.erase(SelectedMultilibs.begin(), + SelectedMultilibs.end() - 1); + + 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); + } } void Fuchsia::configureMultilibs(MultilibSet &Multilibs) { diff --git a/clang/lib/Driver/ToolChains/Gnu.h b/clang/lib/Driver/ToolChains/Gnu.h --- a/clang/lib/Driver/ToolChains/Gnu.h +++ b/clang/lib/Driver/ToolChains/Gnu.h @@ -22,8 +22,8 @@ /// 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 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/Gnu.cpp b/clang/lib/Driver/ToolChains/Gnu.cpp --- a/clang/lib/Driver/ToolChains/Gnu.cpp +++ b/clang/lib/Driver/ToolChains/Gnu.cpp @@ -1139,7 +1139,7 @@ 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; @@ -1188,7 +1188,7 @@ 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; } @@ -1221,7 +1221,7 @@ {"/../sysroot" + M.osSuffix() + "/usr/include"}); }); } - if (MuslMipsMultilibs.select(Flags, Result.SelectedMultilib)) { + if (MuslMipsMultilibs.select(Flags, Result.SelectedMultilibs)) { Result.Multilibs = MuslMipsMultilibs; return true; } @@ -1394,7 +1394,7 @@ }); } for (auto *Candidate : {&MtiMipsMultilibsV1, &MtiMipsMultilibsV2}) { - if (Candidate->select(Flags, Result.SelectedMultilib)) { + if (Candidate->select(Flags, Result.SelectedMultilibs)) { Result.Multilibs = *Candidate; return true; } @@ -1489,7 +1489,7 @@ }); } for (auto *Candidate : {&ImgMultilibsV1, &ImgMultilibsV2}) { - if (Candidate->select(Flags, Result.SelectedMultilib)) { + if (Candidate->select(Flags, Result.SelectedMultilibs)) { Result.Multilibs = *Candidate; return true; } @@ -1562,7 +1562,7 @@ 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; } @@ -1605,7 +1605,7 @@ 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; } @@ -1629,7 +1629,7 @@ 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; @@ -1695,7 +1695,7 @@ .makeMultilibSet() .FilterOut(NonExistent); - if (CSKYMultilibs.select(Flags, Result.SelectedMultilib)) + if (CSKYMultilibs.select(Flags, Result.SelectedMultilibs)) Result.Multilibs = CSKYMultilibs; } @@ -1749,7 +1749,7 @@ } } - if (RISCVMultilibs.select(Flags, Result.SelectedMultilib)) + if (RISCVMultilibs.select(Flags, Result.SelectedMultilibs)) Result.Multilibs = RISCVMultilibs; } @@ -1785,7 +1785,7 @@ 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; } @@ -1889,11 +1889,12 @@ 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; @@ -2677,7 +2678,9 @@ } Multilibs = Detected.Multilibs; - SelectedMultilib = Detected.SelectedMultilib; + SelectedMultilib = Detected.SelectedMultilibs.empty() + ? Multilib() + : Detected.SelectedMultilibs.back(); BiarchSibling = Detected.BiarchSibling; return true; @@ -2977,6 +2980,7 @@ 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()); @@ -2984,13 +2988,14 @@ // 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. @@ -3017,7 +3022,7 @@ // 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/Hexagon.cpp b/clang/lib/Driver/ToolChains/Hexagon.cpp --- a/clang/lib/Driver/ToolChains/Hexagon.cpp +++ b/clang/lib/Driver/ToolChains/Hexagon.cpp @@ -540,7 +540,9 @@ 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 --- a/clang/lib/Driver/ToolChains/Hurd.cpp +++ b/clang/lib/Driver/ToolChains/Hurd.cpp @@ -65,7 +65,7 @@ : 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 --- a/clang/lib/Driver/ToolChains/Linux.cpp +++ b/clang/lib/Driver/ToolChains/Linux.cpp @@ -182,7 +182,7 @@ : 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(); @@ -226,8 +226,8 @@ 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 --- a/clang/lib/Driver/ToolChains/MipsLinux.cpp +++ b/clang/lib/Driver/ToolChains/MipsLinux.cpp @@ -30,7 +30,7 @@ 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/RISCVToolchain.cpp b/clang/lib/Driver/ToolChains/RISCVToolchain.cpp --- a/clang/lib/Driver/ToolChains/RISCVToolchain.cpp +++ b/clang/lib/Driver/ToolChains/RISCVToolchain.cpp @@ -53,10 +53,10 @@ 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 --- 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/FuchsiaTest.cpp b/clang/unittests/Driver/FuchsiaTest.cpp --- a/clang/unittests/Driver/FuchsiaTest.cpp +++ b/clang/unittests/Driver/FuchsiaTest.cpp @@ -34,9 +34,9 @@ Multilib::flags_list Flags; toolchains::Fuchsia::configureMultilibFlags(Flags, Exceptions, Asan, Hwasan, Itanium); - Multilib Selected; - EXPECT_TRUE(Multilibs.select(Flags, Selected)); - Actual += Selected.gccSuffix() + "\n"; + llvm::SmallVector Selected; + ASSERT_TRUE(Multilibs.select(Flags, Selected)); + Actual += Selected.back().gccSuffix() + "\n"; } } } diff --git a/clang/unittests/Driver/MultilibBuilderTest.cpp b/clang/unittests/Driver/MultilibBuilderTest.cpp --- a/clang/unittests/Driver/MultilibBuilderTest.cpp +++ b/clang/unittests/Driver/MultilibBuilderTest.cpp @@ -160,18 +160,20 @@ .makeMultilibSet(); Multilib::flags_list FlagM64 = {"+m64"}; - Multilib SelectionM64; + llvm::SmallVector 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 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) { @@ -194,7 +196,7 @@ else Flags.insert("-SF"); - Multilib Selection; + llvm::SmallVector Selection; ASSERT_TRUE(MS2.select(Flags, Selection)) << "Selection failed for " << (IsEL ? "+EL" : "-EL") << " " << (IsSF ? "+SF" : "-SF"); @@ -205,8 +207,9 @@ 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 --- a/clang/unittests/Driver/MultilibTest.cpp +++ b/clang/unittests/Driver/MultilibTest.cpp @@ -153,18 +153,18 @@ Multilib("/bar", {}, {}, {"+bar"}), }); Multilib::flags_list Flags1 = {"+foo", "-bar"}; - Multilib Selection1; + llvm::SmallVector 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 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) { @@ -172,17 +172,17 @@ Multilib("/a", {}, {}, {"x"}), Multilib("/b", {}, {}, {"y"}), }); - std::vector Selection; + llvm::SmallVector 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()); @@ -314,7 +314,7 @@ TEST(MultilibTest, SelectSoft) { MultilibSet MS; - Multilib Selected; + llvm::SmallVector Selected; ASSERT_TRUE(parse(MS, R"( variants: - dir: s @@ -333,7 +333,7 @@ TEST(MultilibTest, SelectSoftFP) { MultilibSet MS; - Multilib Selected; + llvm::SmallVector Selected; ASSERT_TRUE(parse(MS, R"( variants: - dir: f @@ -349,7 +349,7 @@ // If hard float is all that's available then select that only if compiling // with hard float. MultilibSet MS; - Multilib Selected; + llvm::SmallVector Selected; ASSERT_TRUE(parse(MS, R"( variants: - dir: h @@ -363,7 +363,7 @@ TEST(MultilibTest, SelectFloatABI) { MultilibSet MS; - Multilib Selected; + llvm::SmallVector Selected; ASSERT_TRUE(parse(MS, R"( variants: - dir: s @@ -384,18 +384,18 @@ noMatchFlags: [hasfp] )")); 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 Selected; ASSERT_TRUE(parse(MS, R"( variants: - dir: h @@ -416,11 +416,11 @@ noMatchFlags: [hasfp] )")); 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) { @@ -476,51 +476,51 @@ )"; MultilibSet MS; - Multilib Selected; + llvm::SmallVector Selected; ASSERT_TRUE(parse(MS, MultilibSpec)); EXPECT_TRUE( MS.select({"target=thumbv6m-none-eabi", "mfloat-abi=soft"}, Selected)); - EXPECT_EQ("/thumb/v6-m/nofp", Selected.gccSuffix()); + EXPECT_EQ("/thumb/v6-m/nofp", Selected.back().gccSuffix()); EXPECT_TRUE( MS.select({"target=thumbv7m-none-eabi", "mfloat-abi=soft"}, Selected)); - EXPECT_EQ("/thumb/v7-m/nofp", Selected.gccSuffix()); + EXPECT_EQ("/thumb/v7-m/nofp", Selected.back().gccSuffix()); EXPECT_TRUE( MS.select({"target=thumbv7em-none-eabi", "mfloat-abi=soft", "mfpu=none"}, Selected)); - EXPECT_EQ("/thumb/v7e-m/nofp", Selected.gccSuffix()); + EXPECT_EQ("/thumb/v7e-m/nofp", Selected.back().gccSuffix()); EXPECT_TRUE(MS.select({"target=thumbv8m.main-none-eabi", "mfloat-abi=soft"}, Selected)); - EXPECT_EQ("/thumb/v8-m.main/nofp", Selected.gccSuffix()); + EXPECT_EQ("/thumb/v8-m.main/nofp", Selected.back().gccSuffix()); EXPECT_TRUE(MS.select( {"target=thumbv8.1m.main-none-eabi", "mfloat-abi=soft", "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()); EXPECT_TRUE(MS.select( {"target=thumbv7em-none-eabihf", "mfloat-abi=hard", "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()); EXPECT_TRUE(MS.select( {"target=thumbv7em-none-eabihf", "mfloat-abi=hard", "mfpu=fpv5-d16"}, Selected)); - EXPECT_EQ("/thumb/v7e-m/fpv5_d16", Selected.gccSuffix()); + EXPECT_EQ("/thumb/v7e-m/fpv5_d16", Selected.back().gccSuffix()); EXPECT_TRUE(MS.select({"target=thumbv8m.main-none-eabihf", "mfloat-abi=hard"}, Selected)); - EXPECT_EQ("/thumb/v8-m.main/fp", Selected.gccSuffix()); + EXPECT_EQ("/thumb/v8-m.main/fp", Selected.back().gccSuffix()); EXPECT_TRUE(MS.select( {"target=thumbv8.1m.main-none-eabihf", "mfloat-abi=hard"}, Selected)); - EXPECT_EQ("/thumb/v8.1-m.main/fp", Selected.gccSuffix()); + EXPECT_EQ("/thumb/v8.1-m.main/fp", Selected.back().gccSuffix()); EXPECT_TRUE(MS.select({"target=thumbv8.1m.main-none-eabihf", "mfloat-abi=hard", "mfpu=none", "march=+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()); }