michaelplatings updated this revision to Diff 511073.
michaelplatings marked 3 inline comments as done.
michaelplatings added a comment.

Expand constructor comment as suggested by @peter.smith


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D146757

Files:
  clang/include/clang/Driver/Multilib.h
  clang/lib/Driver/Multilib.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
@@ -187,3 +187,19 @@
   EXPECT_EQ("/a", Selection[0].gccSuffix());
   EXPECT_EQ("/b", Selection[1].gccSuffix());
 }
+
+TEST(MultilibBuilder, PrintOptions) {
+  ASSERT_EQ(Multilib::flags_list(), Multilib().getPrintOptions());
+  ASSERT_EQ(Multilib::flags_list({"-x"}),
+            Multilib({}, {}, {}, {"+x"}).getPrintOptions());
+  ASSERT_EQ(Multilib::flags_list({"-x"}),
+            Multilib({}, {}, {}, {"+x"}, Multilib::PrintOptionsType::PlusFlags)
+                .getPrintOptions());
+  ASSERT_EQ(
+      Multilib::flags_list({"-x", "-a", "-c"}),
+      Multilib({}, {}, {}, {"+x", "-y", "+a", "-b", "+c"}).getPrintOptions());
+  ASSERT_EQ(
+      Multilib::flags_list({"-y"}),
+      Multilib({}, {}, {}, {"+x"}, Multilib::PrintOptionsType::List, {"-y"})
+          .getPrintOptions());
+}
Index: clang/unittests/Driver/MultilibBuilderTest.cpp
===================================================================
--- clang/unittests/Driver/MultilibBuilderTest.cpp
+++ clang/unittests/Driver/MultilibBuilderTest.cpp
@@ -207,3 +207,14 @@
         << "Selection picked " << Selection << " which was not expected ";
   }
 }
+
+TEST(MultilibBuilderTest, PrintOptions) {
+  Multilib M = MultilibBuilder()
+                   .flag("+x")
+                   .flag("-y")
+                   .flag("+a")
+                   .flag("-b")
+                   .flag("+c")
+                   .makeMultilib();
+  ASSERT_EQ(Multilib::flags_list({"-x", "-a", "-c"}), M.getPrintOptions());
+}
Index: clang/lib/Driver/Multilib.cpp
===================================================================
--- clang/lib/Driver/Multilib.cpp
+++ clang/lib/Driver/Multilib.cpp
@@ -26,15 +26,43 @@
 using namespace llvm::sys;
 
 Multilib::Multilib(StringRef GCCSuffix, StringRef OSSuffix,
-                   StringRef IncludeSuffix, const flags_list &Flags)
+                   StringRef IncludeSuffix, const flags_list &Flags,
+                   PrintOptionsType PrintOptions,
+                   const flags_list &PrintOptionsList)
     : GCCSuffix(GCCSuffix), OSSuffix(OSSuffix), IncludeSuffix(IncludeSuffix),
-      Flags(Flags) {
+      Flags(Flags), PrintOptionsList(PrintOptionsList),
+      PrintOptions(PrintOptions) {
   assert(GCCSuffix.empty() ||
          (StringRef(GCCSuffix).front() == '/' && GCCSuffix.size() > 1));
   assert(OSSuffix.empty() ||
          (StringRef(OSSuffix).front() == '/' && OSSuffix.size() > 1));
   assert(IncludeSuffix.empty() ||
          (StringRef(IncludeSuffix).front() == '/' && IncludeSuffix.size() > 1));
+  // If PrintOptions is something other than List then PrintOptionsList must be
+  // empty.
+  assert(PrintOptions == PrintOptionsType::List || PrintOptionsList.empty());
+}
+
+static Multilib::flags_list
+getPrintOptionsFromPlusFlags(const Multilib::flags_list &Flags) {
+  // Derive print options from flags beginning '+', replacing the first
+  // character with '-'.
+  Multilib::flags_list PrintOptions;
+  for (StringRef Flag : Flags) {
+    if (Flag.front() == '+')
+      PrintOptions.push_back(("-" + Flag.substr(1)).str());
+  }
+  return PrintOptions;
+}
+
+Multilib::flags_list Multilib::getPrintOptions() const {
+  switch (PrintOptions) {
+  case PrintOptionsType::List:
+    return PrintOptionsList;
+  case PrintOptionsType::PlusFlags:
+    return getPrintOptionsFromPlusFlags(Flags);
+  }
+  llvm_unreachable("Unknown Multilib::PrintOptionsType");
 }
 
 LLVM_DUMP_METHOD void Multilib::dump() const {
@@ -44,14 +72,11 @@
 void Multilib::print(raw_ostream &OS) const {
   if (GCCSuffix.empty())
     OS << ".";
-  else {
+  else
     OS << StringRef(GCCSuffix).drop_front();
-  }
   OS << ";";
-  for (StringRef Flag : Flags) {
-    if (Flag.front() == '+')
-      OS << "@" << Flag.substr(1);
-  }
+  for (StringRef Option : getPrintOptions())
+    OS << "@" << Option.substr(1);
 }
 
 bool Multilib::operator==(const Multilib &Other) const {
Index: clang/include/clang/Driver/Multilib.h
===================================================================
--- clang/include/clang/Driver/Multilib.h
+++ clang/include/clang/Driver/Multilib.h
@@ -31,19 +31,39 @@
 public:
   using flags_list = std::vector<std::string>;
 
+  /// When -print-multi-lib is used, this defines how the printed options must
+  /// be calculated.
+  enum class PrintOptionsType {
+    /// Use the options stored in PrintOptionsList
+    List,
+    /// Print flags in the Flags list that begin with '+', but with the initial
+    /// '+' replaced with '-'. e.g. "+fno-rtti" becomes "-fno-rtti"
+    PlusFlags,
+  };
+
 private:
   std::string GCCSuffix;
   std::string OSSuffix;
   std::string IncludeSuffix;
   flags_list Flags;
+  flags_list PrintOptionsList;
+  PrintOptionsType PrintOptions;
 
 public:
   /// GCCSuffix, OSSuffix & IncludeSuffix will be appended directly to the
   /// sysroot string so they must either be empty or begin with a '/' character.
   /// This is enforced with an assert in the constructor.
+  /// Flags is the set of flags that indicate this multilib's use. See the
+  /// flags() method for more information.
+  /// If PrintOptions is something other than PrintOptionsType::List then
+  /// PrintOptionsList must be empty. This is enforced with an assert in the
+  /// constructor.
+  /// Each value in PrintOptionsList should be a complete valid Clang option,
+  /// for example "-fno-exceptions", but the constructor does not enforce this.
   Multilib(StringRef GCCSuffix = {}, StringRef OSSuffix = {},
-           StringRef IncludeSuffix = {},
-           const flags_list &Flags = flags_list());
+           StringRef IncludeSuffix = {}, const flags_list &Flags = flags_list(),
+           PrintOptionsType PrintOptions = PrintOptionsType::PlusFlags,
+           const flags_list &PrintOptionsList = flags_list());
 
   /// Get the detected GCC installation path suffix for the multi-arch
   /// target variant. Always starts with a '/', unless empty
@@ -57,10 +77,15 @@
   /// empty
   const std::string &includeSuffix() const { return IncludeSuffix; }
 
-  /// Get the flags that indicate or contraindicate this multilib's use
-  /// All elements begin with either '+' or '-'
+  /// Get the set of flags that indicate this multilib's use.
+  /// Flags are arbitrary strings although typically they will look similar to
+  /// command line options. A multilib is considered compatible if its flags are
+  /// a subset of the flags derived from the Clang command line options.
   const flags_list &flags() const { return Flags; }
 
+  /// Returns the options that should be used for clang -print-multi-lib
+  flags_list getPrintOptions() const;
+
   LLVM_DUMP_METHOD void dump() const;
   /// print summary of the Multilib
   void print(raw_ostream &OS) const;
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to