michaelplatings updated this revision to Diff 505051.
michaelplatings added a comment.

tags->flags


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D143059/new/

https://reviews.llvm.org/D143059

Files:
  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/RISCVToolchain.cpp
  clang/test/Driver/fuchsia.cpp
  clang/unittests/Driver/MultilibBuilderTest.cpp
  clang/unittests/Driver/MultilibTest.cpp

Index: clang/unittests/Driver/MultilibTest.cpp
===================================================================
--- clang/unittests/Driver/MultilibTest.cpp
+++ clang/unittests/Driver/MultilibTest.cpp
@@ -154,18 +154,18 @@
       Multilib("/bar", {}, {}, {"+bar"}),
   });
   Multilib::flag_set 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::flag_set 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 @@
       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());
@@ -384,7 +384,7 @@
 
 TEST(MultilibTest, SelectSoft) {
   MultilibSet MS;
-  Multilib Selected;
+  llvm::SmallVector<Multilib> Selected;
   ASSERT_TRUE(parseYaml(MS, YAML_PREAMBLE R"(
 Variants:
 - Dir: s
@@ -403,7 +403,7 @@
 
 TEST(MultilibTest, SelectSoftFP) {
   MultilibSet MS;
-  Multilib Selected;
+  llvm::SmallVector<Multilib> Selected;
   ASSERT_TRUE(parseYaml(MS, YAML_PREAMBLE R"(
 Variants:
 - Dir: f
@@ -419,7 +419,7 @@
   // 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
@@ -433,7 +433,7 @@
 
 TEST(MultilibTest, SelectFloatABI) {
   MultilibSet MS;
-  Multilib Selected;
+  llvm::SmallVector<Multilib> Selected;
   ASSERT_TRUE(parseYaml(MS, YAML_PREAMBLE R"(
 Variants:
 - Dir: s
@@ -454,18 +454,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<Multilib> Selected;
   ASSERT_TRUE(parseYaml(MS, YAML_PREAMBLE R"(
 Variants:
 - Dir: h
@@ -486,11 +486,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) {
@@ -546,51 +546,51 @@
 )";
 
   MultilibSet MS;
-  Multilib Selected;
+  llvm::SmallVector<Multilib> Selected;
   ASSERT_TRUE(parseYaml(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());
 }
Index: clang/unittests/Driver/MultilibBuilderTest.cpp
===================================================================
--- clang/unittests/Driver/MultilibBuilderTest.cpp
+++ clang/unittests/Driver/MultilibBuilderTest.cpp
@@ -158,18 +158,20 @@
                         .makeMultilibSet();
 
   Multilib::flag_set 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::flag_set 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) {
@@ -192,7 +194,7 @@
     else
       Flags.insert("-SF");
 
-    Multilib Selection;
+    llvm::SmallVector<Multilib> 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 ";
   }
 }
 
Index: clang/test/Driver/fuchsia.cpp
===================================================================
--- clang/test/Driver/fuchsia.cpp
+++ 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
Index: clang/lib/Driver/ToolChains/RISCVToolchain.cpp
===================================================================
--- clang/lib/Driver/ToolChains/RISCVToolchain.cpp
+++ 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();
Index: clang/lib/Driver/ToolChains/MipsLinux.cpp
===================================================================
--- clang/lib/Driver/ToolChains/MipsLinux.cpp
+++ 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);
Index: clang/lib/Driver/ToolChains/Linux.cpp
===================================================================
--- clang/lib/Driver/ToolChains/Linux.cpp
+++ 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);
Index: clang/lib/Driver/ToolChains/Hurd.cpp
===================================================================
--- clang/lib/Driver/ToolChains/Hurd.cpp
+++ 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();
 
Index: clang/lib/Driver/ToolChains/Hexagon.cpp
===================================================================
--- clang/lib/Driver/ToolChains/Hexagon.cpp
+++ 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());
 }
 
Index: clang/lib/Driver/ToolChains/Gnu.h
===================================================================
--- clang/lib/Driver/ToolChains/Gnu.h
+++ 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<Multilib> SelectedMultilibs;
 
   /// On Biarch systems, this corresponds to the default multilib when
   /// targeting the non-default multilib. Otherwise, it is empty.
Index: clang/lib/Driver/ToolChains/Gnu.cpp
===================================================================
--- clang/lib/Driver/ToolChains/Gnu.cpp
+++ 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
Index: clang/lib/Driver/ToolChains/Fuchsia.cpp
===================================================================
--- clang/lib/Driver/ToolChains/Fuchsia.cpp
+++ 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,
Index: clang/lib/Driver/ToolChains/CSKYToolChain.cpp
===================================================================
--- clang/lib/Driver/ToolChains/CSKYToolChain.cpp
+++ 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 {
Index: clang/lib/Driver/ToolChains/BareMetal.cpp
===================================================================
--- clang/lib/Driver/ToolChains/BareMetal.cpp
+++ 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.parseYaml(*MB.get()))
     return false;
   Multilib::flag_set 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"
@@ -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,
Index: clang/lib/Driver/ToolChain.cpp
===================================================================
--- clang/lib/Driver/ToolChain.cpp
+++ 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 {
Index: clang/lib/Driver/Multilib.cpp
===================================================================
--- clang/lib/Driver/Multilib.cpp
+++ clang/lib/Driver/Multilib.cpp
@@ -81,25 +81,16 @@
 
 void MultilibSet::push_back(const Multilib &M) { Multilibs.push_back(M); }
 
-std::vector<Multilib>
-MultilibSet::select(const Multilib::flag_set &Flags) const {
+bool MultilibSet::select(const Multilib::flag_set &Flags,
+                         llvm::SmallVector<Multilib> &Selected) const {
   Multilib::flag_set 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::flag_set &Flags,
-                         Multilib &Selected) const {
-  multilib_list Result = select(Flags);
-  if (Result.empty())
-    return false;
-  Selected = Result.back();
-  return true;
+  return !Selected.empty();
 }
 
 Multilib::flag_set
Index: clang/lib/Driver/Driver.cpp
===================================================================
--- clang/lib/Driver/Driver.cpp
+++ 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;
   }
Index: clang/include/clang/Driver/ToolChain.h
===================================================================
--- clang/include/clang/Driver/ToolChain.h
+++ clang/include/clang/Driver/ToolChain.h
@@ -187,7 +187,7 @@
 
 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 @@
 
   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
Index: clang/include/clang/Driver/Multilib.h
===================================================================
--- clang/include/clang/Driver/Multilib.h
+++ clang/include/clang/Driver/Multilib.h
@@ -124,11 +124,9 @@
   const_iterator begin() const { return Multilibs.begin(); }
   const_iterator end() const { return Multilibs.end(); }
 
-  /// Select compatible variants
-  multilib_list select(const Multilib::flag_set &Flags) const;
-
-  /// Pick the best multilib in the set, \returns false if none are compatible
-  bool select(const Multilib::flag_set &Flags, Multilib &M) const;
+  /// Select compatible variants, \returns false if none are compatible
+  bool select(const Multilib::flag_set &Flags,
+              llvm::SmallVector<Multilib> &) const;
 
   unsigned size() const { return Multilibs.size(); }
 
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to