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 @@ -123,11 +123,9 @@ const_iterator begin() const { return Multilibs.begin(); } const_iterator end() const { return Multilibs.end(); } - /// Select compatible variants - multilib_list select(const Multilib::tag_set &Tags) const; - - /// Pick the best multilib in the set, \returns false if none are compatible - bool select(const Multilib::tag_set &Tags, Multilib &M) const; + /// Select compatible variants, \returns false if none are compatible + bool select(const Multilib::tag_set &Tags, + 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 tags 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 --- a/clang/lib/Driver/Driver.cpp +++ b/clang/lib/Driver/Driver.cpp @@ -2217,13 +2217,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 @@ -81,24 +81,16 @@ void MultilibSet::push_back(const Multilib &M) { Multilibs.push_back(M); } -std::vector MultilibSet::select(const Multilib::tag_set &Tags) const { +bool MultilibSet::select(const Multilib::tag_set &Tags, + llvm::SmallVector &Selected) const { Multilib::tag_set AllTags(expandTags(Tags)); - multilib_list Result; - llvm::copy_if(Multilibs, std::back_inserter(Result), + Selected.clear(); + llvm::copy_if(Multilibs, std::back_inserter(Selected), [&AllTags](const Multilib &M) { return std::includes(AllTags.begin(), AllTags.end(), M.tags().begin(), M.tags().end()); }); - return Result; -} - -bool MultilibSet::select(const Multilib::tag_set &Tags, - Multilib &Selected) const { - multilib_list Result = select(Tags); - if (Result.empty()) - return false; - Selected = Result.back(); - return true; + return !Selected.empty(); } Multilib::tag_set 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 @@ -615,7 +615,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 @@ -54,7 +54,7 @@ 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 @@ 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; } @@ -166,7 +166,7 @@ if (!Result.Multilibs.parse(*MB.get())) return false; Multilib::tag_set Tags(ArgsTags.begin(), ArgsTags.end()); - return Result.Multilibs.select(Tags, Result.SelectedMultilib); + return Result.Multilibs.select(Tags, Result.SelectedMultilibs); } #define MULTILIB_YAML_FILENAME "multilib.yaml" @@ -198,14 +198,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; } } @@ -220,8 +220,10 @@ } 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 @@ -313,12 +313,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. + 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.h b/clang/lib/Driver/ToolChains/Gnu.h --- a/clang/lib/Driver/ToolChains/Gnu.h +++ b/clang/lib/Driver/ToolChains/Gnu.h @@ -23,8 +23,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 @@ -1133,7 +1133,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; @@ -1182,7 +1182,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; } @@ -1216,7 +1216,7 @@ {"/../sysroot" + M.osSuffix() + "/usr/include"}); }); } - if (MuslMipsMultilibs.select(Flags, Result.SelectedMultilib)) { + if (MuslMipsMultilibs.select(Flags, Result.SelectedMultilibs)) { Result.Multilibs = MuslMipsMultilibs; return true; } @@ -1396,7 +1396,7 @@ }); } for (auto *Candidate : {&MtiMipsMultilibsV1, &MtiMipsMultilibsV2}) { - if (Candidate->select(Flags, Result.SelectedMultilib)) { + if (Candidate->select(Flags, Result.SelectedMultilibs)) { Result.Multilibs = *Candidate; return true; } @@ -1497,7 +1497,7 @@ }); } for (auto *Candidate : {&ImgMultilibsV1, &ImgMultilibsV2}) { - if (Candidate->select(Flags, Result.SelectedMultilib)) { + if (Candidate->select(Flags, Result.SelectedMultilibs)) { Result.Multilibs = *Candidate; return true; } @@ -1570,7 +1570,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; } @@ -1613,7 +1613,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; } @@ -1639,7 +1639,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; @@ -1705,7 +1705,7 @@ .makeMultilibSet() .FilterOut(NonExistent); - if (CSKYMultilibs.select(Flags, Result.SelectedMultilib)) + if (CSKYMultilibs.select(Flags, Result.SelectedMultilibs)) Result.Multilibs = CSKYMultilibs; } @@ -1760,7 +1760,7 @@ } } - if (RISCVMultilibs.select(Flags, Result.SelectedMultilib)) + if (RISCVMultilibs.select(Flags, Result.SelectedMultilibs)) Result.Multilibs = RISCVMultilibs; } @@ -1802,7 +1802,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; } @@ -1905,11 +1905,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; @@ -2693,7 +2694,9 @@ } Multilibs = Detected.Multilibs; - SelectedMultilib = Detected.SelectedMultilib; + SelectedMultilib = Detected.SelectedMultilibs.empty() + ? Multilib() + : Detected.SelectedMultilibs.back(); BiarchSibling = Detected.BiarchSibling; return true; @@ -2995,6 +2998,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()); @@ -3002,13 +3006,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. @@ -3035,7 +3040,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/MultilibBuilderTest.cpp b/clang/unittests/Driver/MultilibBuilderTest.cpp --- a/clang/unittests/Driver/MultilibBuilderTest.cpp +++ b/clang/unittests/Driver/MultilibBuilderTest.cpp @@ -158,18 +158,20 @@ .makeMultilibSet(); Multilib::tag_set 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::tag_set 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) { @@ -192,7 +194,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"); @@ -203,8 +205,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 @@ -154,18 +154,18 @@ Multilib("/bar", {}, {}, {"+bar"}), }); Multilib::tag_set Tags1 = {"+foo", "-bar"}; - Multilib Selection1; + llvm::SmallVector Selection1; ASSERT_TRUE(MS.select(Tags1, Selection1)) << "Tag 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::tag_set Tags2 = {"+foo", "+bar"}; - Multilib Selection2; + llvm::SmallVector Selection2; ASSERT_TRUE(MS.select(Tags2, Selection2)) << "Tag 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 @@ 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()); @@ -382,7 +382,7 @@ TEST(MultilibTest, SelectSoft) { MultilibSet MS; - Multilib Selected; + llvm::SmallVector Selected; ASSERT_TRUE(parse(MS, YAML_PREAMBLE R"( Variants: - Dir: s @@ -401,7 +401,7 @@ TEST(MultilibTest, SelectSoftFP) { MultilibSet MS; - Multilib Selected; + llvm::SmallVector Selected; ASSERT_TRUE(parse(MS, YAML_PREAMBLE R"( Variants: - Dir: f @@ -417,7 +417,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, YAML_PREAMBLE R"( Variants: - Dir: h @@ -431,7 +431,7 @@ TEST(MultilibTest, SelectFloatABI) { MultilibSet MS; - Multilib Selected; + llvm::SmallVector Selected; ASSERT_TRUE(parse(MS, YAML_PREAMBLE R"( Variants: - Dir: s @@ -452,18 +452,18 @@ NoMatchTags: [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, YAML_PREAMBLE R"( Variants: - Dir: h @@ -484,11 +484,11 @@ NoMatchTags: [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) { @@ -544,51 +544,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()); }