r359359 - [Driver] Support priority for multilibs

Petr Hosek via cfe-commits cfe-commits at lists.llvm.org
Fri Apr 26 17:25:11 PDT 2019


Author: phosek
Date: Fri Apr 26 17:25:11 2019
New Revision: 359359

URL: http://llvm.org/viewvc/llvm-project?rev=359359&view=rev
Log:
[Driver] Support priority for multilibs

When more than one multilib flag matches, try to select the best
possible match based on priority. When two different multilibs with
the same same priority match, we still throw an error matching the
existing behavior.

Differential Revision: https://reviews.llvm.org/D60990

Modified:
    cfe/trunk/include/clang/Driver/Multilib.h
    cfe/trunk/lib/Driver/Multilib.cpp
    cfe/trunk/unittests/Driver/MultilibTest.cpp

Modified: cfe/trunk/include/clang/Driver/Multilib.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Driver/Multilib.h?rev=359359&r1=359358&r2=359359&view=diff
==============================================================================
--- cfe/trunk/include/clang/Driver/Multilib.h (original)
+++ cfe/trunk/include/clang/Driver/Multilib.h Fri Apr 26 17:25:11 2019
@@ -34,10 +34,11 @@ private:
   std::string OSSuffix;
   std::string IncludeSuffix;
   flags_list Flags;
+  int Priority;
 
 public:
   Multilib(StringRef GCCSuffix = {}, StringRef OSSuffix = {},
-           StringRef IncludeSuffix = {});
+           StringRef IncludeSuffix = {}, int Priority = 0);
 
   /// Get the detected GCC installation path suffix for the multi-arch
   /// target variant. Always starts with a '/', unless empty
@@ -77,6 +78,10 @@ public:
   const flags_list &flags() const { return Flags; }
   flags_list &flags() { return Flags; }
 
+  /// Returns the multilib priority. When more than one multilib matches flags,
+  /// the one with the highest priority is selected, with 0 being the default.
+  int priority() const { return Priority; }
+
   /// Add a flag to the flags list
   /// \p Flag must be a flag accepted by the driver with its leading '-' removed,
   ///     and replaced with either:

Modified: cfe/trunk/lib/Driver/Multilib.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Driver/Multilib.cpp?rev=359359&r1=359358&r2=359359&view=diff
==============================================================================
--- cfe/trunk/lib/Driver/Multilib.cpp (original)
+++ cfe/trunk/lib/Driver/Multilib.cpp Fri Apr 26 17:25:11 2019
@@ -51,8 +51,9 @@ static void normalizePathSegment(std::st
 }
 
 Multilib::Multilib(StringRef GCCSuffix, StringRef OSSuffix,
-                   StringRef IncludeSuffix)
-    : GCCSuffix(GCCSuffix), OSSuffix(OSSuffix), IncludeSuffix(IncludeSuffix) {
+                   StringRef IncludeSuffix, int Priority)
+    : GCCSuffix(GCCSuffix), OSSuffix(OSSuffix), IncludeSuffix(IncludeSuffix),
+      Priority(Priority) {
   normalizePathSegment(this->GCCSuffix);
   normalizePathSegment(this->OSSuffix);
   normalizePathSegment(this->IncludeSuffix);
@@ -265,8 +266,19 @@ bool MultilibSet::select(const Multilib:
     return true;
   }
 
-  // TODO: pick the "best" multlib when more than one is suitable
-  assert(false);
+  // Sort multilibs by priority and select the one with the highest priority.
+  llvm::sort(Filtered.begin(), Filtered.end(),
+             [](const Multilib &a, const Multilib &b) -> bool {
+               return a.priority() > b.priority();
+             });
+
+  if (Filtered[0].priority() > Filtered[1].priority()) {
+    M = Filtered[0];
+    return true;
+  }
+
+  // TODO: We should consider returning llvm::Error rather than aborting.
+  assert(false && "More than one multilib with the same priority");
   return false;
 }
 

Modified: cfe/trunk/unittests/Driver/MultilibTest.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/unittests/Driver/MultilibTest.cpp?rev=359359&r1=359358&r2=359359&view=diff
==============================================================================
--- cfe/trunk/unittests/Driver/MultilibTest.cpp (original)
+++ cfe/trunk/unittests/Driver/MultilibTest.cpp Fri Apr 26 17:25:11 2019
@@ -349,3 +349,27 @@ TEST(MultilibTest, SetCombineWith) {
   Latte.combineWith(Milk);
   ASSERT_EQ(Latte.size(), (unsigned)2);
 }
+
+TEST(MultilibTest, SetPriority) {
+  MultilibSet MS;
+  MS.push_back(Multilib("foo", {}, {}, 1).flag("+foo"));
+  MS.push_back(Multilib("bar", {}, {}, 2).flag("+bar"));
+
+  Multilib::flags_list Flags1;
+  Flags1.push_back("+foo");
+  Flags1.push_back("-bar");
+  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";
+
+  Multilib::flags_list Flags2;
+  Flags2.push_back("+foo");
+  Flags2.push_back("+bar");
+  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";
+}




More information about the cfe-commits mailing list