phosek created this revision.
phosek added reviewers: jroelofs, bkramer.
Herald added subscribers: cfe-commits, mgrang.
Herald added a project: clang.

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.


Repository:
  rC Clang

https://reviews.llvm.org/D60990

Files:
  clang/include/clang/Driver/Multilib.h
  clang/lib/Driver/Multilib.cpp


Index: clang/lib/Driver/Multilib.cpp
===================================================================
--- clang/lib/Driver/Multilib.cpp
+++ clang/lib/Driver/Multilib.cpp
@@ -19,6 +19,7 @@
 #include "llvm/Support/raw_ostream.h"
 #include <algorithm>
 #include <cassert>
+#include <map>
 #include <string>
 
 using namespace clang;
@@ -51,8 +52,9 @@
 }
 
 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 +267,19 @@
     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.
+  std::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;
 }
 
Index: clang/include/clang/Driver/Multilib.h
===================================================================
--- clang/include/clang/Driver/Multilib.h
+++ clang/include/clang/Driver/Multilib.h
@@ -34,10 +34,11 @@
   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,9 @@
   const flags_list &flags() const { return Flags; }
   flags_list &flags() { return Flags; }
 
+  /// Returns the multilib priority.
+  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:


Index: clang/lib/Driver/Multilib.cpp
===================================================================
--- clang/lib/Driver/Multilib.cpp
+++ clang/lib/Driver/Multilib.cpp
@@ -19,6 +19,7 @@
 #include "llvm/Support/raw_ostream.h"
 #include <algorithm>
 #include <cassert>
+#include <map>
 #include <string>
 
 using namespace clang;
@@ -51,8 +52,9 @@
 }
 
 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 +267,19 @@
     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.
+  std::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;
 }
 
Index: clang/include/clang/Driver/Multilib.h
===================================================================
--- clang/include/clang/Driver/Multilib.h
+++ clang/include/clang/Driver/Multilib.h
@@ -34,10 +34,11 @@
   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,9 @@
   const flags_list &flags() const { return Flags; }
   flags_list &flags() { return Flags; }
 
+  /// Returns the multilib priority.
+  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:
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to