[clang] 47b431d - [NFC][Driver] Change MultilibBuilder interface

Michael Platings via cfe-commits cfe-commits at lists.llvm.org
Tue Jun 6 21:53:36 PDT 2023


Author: Michael Platings
Date: 2023-06-07T05:53:04+01:00
New Revision: 47b431d6617d5029e30370ec988e5087f65e2d6b

URL: https://github.com/llvm/llvm-project/commit/47b431d6617d5029e30370ec988e5087f65e2d6b
DIFF: https://github.com/llvm/llvm-project/commit/47b431d6617d5029e30370ec988e5087f65e2d6b.diff

LOG: [NFC][Driver] Change MultilibBuilder interface

Decouple the interface of the MultilibBuilder flag method from how flags
are stored internally. Likewise change the addMultilibFlag function.

Currently a multilib flag like "-fexceptions" means a multilib is
*incompatible* with the -fexceptions command line option, which is
counter-intuitive. This change is a step towards changing this scheme.

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

Added: 
    

Modified: 
    clang/include/clang/Driver/MultilibBuilder.h
    clang/lib/Driver/MultilibBuilder.cpp
    clang/lib/Driver/ToolChains/BareMetal.cpp
    clang/lib/Driver/ToolChains/CommonArgs.cpp
    clang/lib/Driver/ToolChains/CommonArgs.h
    clang/lib/Driver/ToolChains/Fuchsia.cpp
    clang/lib/Driver/ToolChains/Gnu.cpp
    clang/lib/Driver/ToolChains/OHOS.cpp
    clang/unittests/Driver/MultilibBuilderTest.cpp

Removed: 
    


################################################################################
diff  --git a/clang/include/clang/Driver/MultilibBuilder.h b/clang/include/clang/Driver/MultilibBuilder.h
index f4875f2e03f8a..177c8104f917b 100644
--- a/clang/include/clang/Driver/MultilibBuilder.h
+++ b/clang/include/clang/Driver/MultilibBuilder.h
@@ -75,18 +75,9 @@ class MultilibBuilder {
   flags_list &flags() { return Flags; }
 
   /// 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:
-  ///       '-' which contraindicates using this multilib with that flag
-  ///     or:
-  ///       '+' which promotes using this multilib in the presence of that flag
-  ///     otherwise '-print-multi-lib' will not emit them correctly.
-  MultilibBuilder &flag(StringRef F) {
-    assert(F.front() == '+' || F.front() == '-');
-    Flags.push_back(std::string(F));
-    return *this;
-  }
+  /// \p Required defines whether the flag is required or disallowed.
+  /// \p Flag must be a flag accepted by the driver.
+  MultilibBuilder &flag(bool Required, StringRef Flag);
 
   Multilib makeMultilib() const;
 

diff  --git a/clang/lib/Driver/MultilibBuilder.cpp b/clang/lib/Driver/MultilibBuilder.cpp
index f6351ae4b5278..213f971f262f7 100644
--- a/clang/lib/Driver/MultilibBuilder.cpp
+++ b/clang/lib/Driver/MultilibBuilder.cpp
@@ -7,6 +7,7 @@
 //===----------------------------------------------------------------------===//
 
 #include "clang/Driver/MultilibBuilder.h"
+#include "ToolChains/CommonArgs.h"
 #include "llvm/ADT/SmallString.h"
 #include "llvm/ADT/StringMap.h"
 #include "llvm/Support/Path.h"
@@ -85,6 +86,11 @@ bool MultilibBuilder::isValid() const {
   return true;
 }
 
+MultilibBuilder &MultilibBuilder::flag(bool Required, StringRef Flag) {
+  tools::addMultilibFlag(Required, Flag, Flags);
+  return *this;
+}
+
 Multilib MultilibBuilder::makeMultilib() const {
   return Multilib(GCCSuffix, OSSuffix, IncludeSuffix, Flags);
 }

diff  --git a/clang/lib/Driver/ToolChains/BareMetal.cpp b/clang/lib/Driver/ToolChains/BareMetal.cpp
index 3232394007bc3..6726ec1c9b22e 100644
--- a/clang/lib/Driver/ToolChains/BareMetal.cpp
+++ b/clang/lib/Driver/ToolChains/BareMetal.cpp
@@ -37,40 +37,42 @@ static bool findRISCVMultilibs(const Driver &D,
   StringRef Abi = tools::riscv::getRISCVABI(Args, TargetTriple);
 
   if (TargetTriple.isRISCV64()) {
-    MultilibBuilder Imac =
-        MultilibBuilder().flag("+march=rv64imac").flag("+mabi=lp64");
+    MultilibBuilder Imac = MultilibBuilder()
+                               .flag(true, "-march=rv64imac")
+                               .flag(true, "-mabi=lp64");
     MultilibBuilder Imafdc = MultilibBuilder("/rv64imafdc/lp64d")
-                                 .flag("+march=rv64imafdc")
-                                 .flag("+mabi=lp64d");
+                                 .flag(true, "-march=rv64imafdc")
+                                 .flag(true, "-mabi=lp64d");
 
     // Multilib reuse
     bool UseImafdc =
         (Arch == "rv64imafdc") || (Arch == "rv64gc"); // gc => imafdc
 
-    addMultilibFlag((Arch == "rv64imac"), "march=rv64imac", Flags);
-    addMultilibFlag(UseImafdc, "march=rv64imafdc", Flags);
-    addMultilibFlag(Abi == "lp64", "mabi=lp64", Flags);
-    addMultilibFlag(Abi == "lp64d", "mabi=lp64d", Flags);
+    addMultilibFlag((Arch == "rv64imac"), "-march=rv64imac", Flags);
+    addMultilibFlag(UseImafdc, "-march=rv64imafdc", Flags);
+    addMultilibFlag(Abi == "lp64", "-mabi=lp64", Flags);
+    addMultilibFlag(Abi == "lp64d", "-mabi=lp64d", Flags);
 
     Result.Multilibs =
         MultilibSetBuilder().Either(Imac, Imafdc).makeMultilibSet();
     return Result.Multilibs.select(Flags, Result.SelectedMultilib);
   }
   if (TargetTriple.isRISCV32()) {
-    MultilibBuilder Imac =
-        MultilibBuilder().flag("+march=rv32imac").flag("+mabi=ilp32");
+    MultilibBuilder Imac = MultilibBuilder()
+                               .flag(true, "-march=rv32imac")
+                               .flag(true, "-mabi=ilp32");
     MultilibBuilder I = MultilibBuilder("/rv32i/ilp32")
-                            .flag("+march=rv32i")
-                            .flag("+mabi=ilp32");
+                            .flag(true, "-march=rv32i")
+                            .flag(true, "-mabi=ilp32");
     MultilibBuilder Im = MultilibBuilder("/rv32im/ilp32")
-                             .flag("+march=rv32im")
-                             .flag("+mabi=ilp32");
+                             .flag(true, "-march=rv32im")
+                             .flag(true, "-mabi=ilp32");
     MultilibBuilder Iac = MultilibBuilder("/rv32iac/ilp32")
-                              .flag("+march=rv32iac")
-                              .flag("+mabi=ilp32");
+                              .flag(true, "-march=rv32iac")
+                              .flag(true, "-mabi=ilp32");
     MultilibBuilder Imafc = MultilibBuilder("/rv32imafc/ilp32f")
-                                .flag("+march=rv32imafc")
-                                .flag("+mabi=ilp32f");
+                                .flag(true, "-march=rv32imafc")
+                                .flag(true, "-mabi=ilp32f");
 
     // Multilib reuse
     bool UseI = (Arch == "rv32i") || (Arch == "rv32ic");    // ic => i
@@ -78,13 +80,13 @@ static bool findRISCVMultilibs(const Driver &D,
     bool UseImafc = (Arch == "rv32imafc") || (Arch == "rv32imafdc") ||
                     (Arch == "rv32gc"); // imafdc,gc => imafc
 
-    addMultilibFlag(UseI, "march=rv32i", Flags);
-    addMultilibFlag(UseIm, "march=rv32im", Flags);
-    addMultilibFlag((Arch == "rv32iac"), "march=rv32iac", Flags);
-    addMultilibFlag((Arch == "rv32imac"), "march=rv32imac", Flags);
-    addMultilibFlag(UseImafc, "march=rv32imafc", Flags);
-    addMultilibFlag(Abi == "ilp32", "mabi=ilp32", Flags);
-    addMultilibFlag(Abi == "ilp32f", "mabi=ilp32f", Flags);
+    addMultilibFlag(UseI, "-march=rv32i", Flags);
+    addMultilibFlag(UseIm, "-march=rv32im", Flags);
+    addMultilibFlag((Arch == "rv32iac"), "-march=rv32iac", Flags);
+    addMultilibFlag((Arch == "rv32imac"), "-march=rv32imac", Flags);
+    addMultilibFlag(UseImafc, "-march=rv32imafc", Flags);
+    addMultilibFlag(Abi == "ilp32", "-mabi=ilp32", Flags);
+    addMultilibFlag(Abi == "ilp32f", "-mabi=ilp32f", Flags);
 
     Result.Multilibs =
         MultilibSetBuilder().Either(I, Im, Iac, Imac, Imafc).makeMultilibSet();

diff  --git a/clang/lib/Driver/ToolChains/CommonArgs.cpp b/clang/lib/Driver/ToolChains/CommonArgs.cpp
index a952fdbacb386..403b17d1b2d62 100644
--- a/clang/lib/Driver/ToolChains/CommonArgs.cpp
+++ b/clang/lib/Driver/ToolChains/CommonArgs.cpp
@@ -1905,9 +1905,14 @@ SmallString<128> tools::getStatsFileName(const llvm::opt::ArgList &Args,
   return StatsFile;
 }
 
-void tools::addMultilibFlag(bool Enabled, const char *const Flag,
+void tools::addMultilibFlag(bool Enabled, const StringRef Flag,
                             Multilib::flags_list &Flags) {
-  Flags.push_back(std::string(Enabled ? "+" : "-") + Flag);
+  assert(Flag.front() == '-');
+  if (Enabled) {
+    Flags.push_back(("+" + Flag.substr(1)).str());
+  } else {
+    Flags.push_back(Flag.str());
+  }
 }
 
 void tools::addX86AlignBranchArgs(const Driver &D, const ArgList &Args,

diff  --git a/clang/lib/Driver/ToolChains/CommonArgs.h b/clang/lib/Driver/ToolChains/CommonArgs.h
index 66948f3f586ba..6a8de0f1c36d1 100644
--- a/clang/lib/Driver/ToolChains/CommonArgs.h
+++ b/clang/lib/Driver/ToolChains/CommonArgs.h
@@ -198,9 +198,8 @@ SmallString<128> getStatsFileName(const llvm::opt::ArgList &Args,
                                   const InputInfo &Output,
                                   const InputInfo &Input, const Driver &D);
 
-/// \p Flag must be a flag accepted by the driver with its leading '-' removed,
-//     otherwise '-print-multi-lib' will not emit them correctly.
-void addMultilibFlag(bool Enabled, const char *const Flag,
+/// \p Flag must be a flag accepted by the driver.
+void addMultilibFlag(bool Enabled, const StringRef Flag,
                      Multilib::flags_list &Flags);
 
 void addX86AlignBranchArgs(const Driver &D, const llvm::opt::ArgList &Args,

diff  --git a/clang/lib/Driver/ToolChains/Fuchsia.cpp b/clang/lib/Driver/ToolChains/Fuchsia.cpp
index 0b74e6aa38e93..a9b73bf432a31 100644
--- a/clang/lib/Driver/ToolChains/Fuchsia.cpp
+++ b/clang/lib/Driver/ToolChains/Fuchsia.cpp
@@ -265,33 +265,33 @@ Fuchsia::Fuchsia(const Driver &D, const llvm::Triple &Triple,
   Multilibs.push_back(Multilib());
   // Use the noexcept variant with -fno-exceptions to avoid the extra overhead.
   Multilibs.push_back(MultilibBuilder("noexcept", {}, {})
-                          .flag("-fexceptions")
-                          .flag("+fno-exceptions")
+                          .flag(false, "-fexceptions")
+                          .flag(true, "-fno-exceptions")
                           .makeMultilib());
   // ASan has higher priority because we always want the instrumentated version.
   Multilibs.push_back(MultilibBuilder("asan", {}, {})
-                          .flag("+fsanitize=address")
+                          .flag(true, "-fsanitize=address")
                           .makeMultilib());
   // Use the asan+noexcept variant with ASan and -fno-exceptions.
   Multilibs.push_back(MultilibBuilder("asan+noexcept", {}, {})
-                          .flag("+fsanitize=address")
-                          .flag("-fexceptions")
-                          .flag("+fno-exceptions")
+                          .flag(true, "-fsanitize=address")
+                          .flag(false, "-fexceptions")
+                          .flag(true, "-fno-exceptions")
                           .makeMultilib());
   // HWASan has higher priority because we always want the instrumentated
   // version.
   Multilibs.push_back(MultilibBuilder("hwasan", {}, {})
-                          .flag("+fsanitize=hwaddress")
+                          .flag(true, "-fsanitize=hwaddress")
                           .makeMultilib());
   // Use the hwasan+noexcept variant with HWASan and -fno-exceptions.
   Multilibs.push_back(MultilibBuilder("hwasan+noexcept", {}, {})
-                          .flag("+fsanitize=hwaddress")
-                          .flag("-fexceptions")
-                          .flag("+fno-exceptions")
+                          .flag(true, "-fsanitize=hwaddress")
+                          .flag(false, "-fexceptions")
+                          .flag(true, "-fno-exceptions")
                           .makeMultilib());
   // Use Itanium C++ ABI for the compat multilib.
   Multilibs.push_back(MultilibBuilder("compat", {}, {})
-                          .flag("+fc++-abi=itanium")
+                          .flag(true, "-fc++-abi=itanium")
                           .makeMultilib());
 
   Multilibs.FilterOut([&](const Multilib &M) {
@@ -302,15 +302,15 @@ Fuchsia::Fuchsia(const Driver &D, const llvm::Triple &Triple,
   Multilib::flags_list Flags;
   bool Exceptions =
       Args.hasFlag(options::OPT_fexceptions, options::OPT_fno_exceptions, true);
-  addMultilibFlag(Exceptions, "fexceptions", Flags);
-  addMultilibFlag(!Exceptions, "fno-exceptions", Flags);
-  addMultilibFlag(getSanitizerArgs(Args).needsAsanRt(), "fsanitize=address",
-                  Flags);
-  addMultilibFlag(getSanitizerArgs(Args).needsHwasanRt(), "fsanitize=hwaddress",
+  addMultilibFlag(Exceptions, "-fexceptions", Flags);
+  addMultilibFlag(!Exceptions, "-fno-exceptions", Flags);
+  addMultilibFlag(getSanitizerArgs(Args).needsAsanRt(), "-fsanitize=address",
                   Flags);
+  addMultilibFlag(getSanitizerArgs(Args).needsHwasanRt(),
+                  "-fsanitize=hwaddress", Flags);
 
   addMultilibFlag(Args.getLastArgValue(options::OPT_fcxx_abi_EQ) == "itanium",
-                  "fc++-abi=itanium", Flags);
+                  "-fc++-abi=itanium", Flags);
 
   Multilibs.setFilePathsCallback(FilePaths);
 

diff  --git a/clang/lib/Driver/ToolChains/Gnu.cpp b/clang/lib/Driver/ToolChains/Gnu.cpp
index 3be65bae81a3d..bd8fb8c09badb 100644
--- a/clang/lib/Driver/ToolChains/Gnu.cpp
+++ b/clang/lib/Driver/ToolChains/Gnu.cpp
@@ -1063,33 +1063,38 @@ static bool findMipsCsMultilibs(const Multilib::flags_list &Flags,
   // Check for Code Sourcery toolchain multilibs
   MultilibSet CSMipsMultilibs;
   {
-    auto MArchMips16 = MultilibBuilder("/mips16").flag("+m32").flag("+mips16");
+    auto MArchMips16 =
+        MultilibBuilder("/mips16").flag(true, "-m32").flag(true, "-mips16");
 
-    auto MArchMicroMips =
-        MultilibBuilder("/micromips").flag("+m32").flag("+mmicromips");
+    auto MArchMicroMips = MultilibBuilder("/micromips")
+                              .flag(true, "-m32")
+                              .flag(true, "-mmicromips");
 
-    auto MArchDefault = MultilibBuilder("").flag("-mips16").flag("-mmicromips");
+    auto MArchDefault =
+        MultilibBuilder("").flag(false, "-mips16").flag(false, "-mmicromips");
 
-    auto UCLibc = MultilibBuilder("/uclibc").flag("+muclibc");
+    auto UCLibc = MultilibBuilder("/uclibc").flag(true, "-muclibc");
 
-    auto SoftFloat = MultilibBuilder("/soft-float").flag("+msoft-float");
+    auto SoftFloat = MultilibBuilder("/soft-float").flag(true, "-msoft-float");
 
-    auto Nan2008 = MultilibBuilder("/nan2008").flag("+mnan=2008");
+    auto Nan2008 = MultilibBuilder("/nan2008").flag(true, "-mnan=2008");
 
-    auto DefaultFloat =
-        MultilibBuilder("").flag("-msoft-float").flag("-mnan=2008");
+    auto DefaultFloat = MultilibBuilder("")
+                            .flag(false, "-msoft-float")
+                            .flag(false, "-mnan=2008");
 
-    auto BigEndian = MultilibBuilder("").flag("+EB").flag("-EL");
+    auto BigEndian = MultilibBuilder("").flag(true, "-EB").flag(false, "-EL");
 
-    auto LittleEndian = MultilibBuilder("/el").flag("+EL").flag("-EB");
+    auto LittleEndian =
+        MultilibBuilder("/el").flag(true, "-EL").flag(false, "-EB");
 
     // Note that this one's osSuffix is ""
     auto MAbi64 = MultilibBuilder("")
                       .gccSuffix("/64")
                       .includeSuffix("/64")
-                      .flag("+mabi=n64")
-                      .flag("-mabi=n32")
-                      .flag("-m32");
+                      .flag(true, "-mabi=n64")
+                      .flag(false, "-mabi=n32")
+                      .flag(false, "-m32");
 
     CSMipsMultilibs =
         MultilibSetBuilder()
@@ -1119,18 +1124,20 @@ static bool findMipsCsMultilibs(const Multilib::flags_list &Flags,
   {
     MultilibBuilder MAbiN32 =
         MultilibBuilder().gccSuffix("/n32").includeSuffix("/n32").flag(
-            "+mabi=n32");
+            true, "-mabi=n32");
 
     MultilibBuilder M64 = MultilibBuilder()
                               .gccSuffix("/64")
                               .includeSuffix("/64")
-                              .flag("+m64")
-                              .flag("-m32")
-                              .flag("-mabi=n32");
+                              .flag(true, "-m64")
+                              .flag(false, "-m32")
+                              .flag(false, "-mabi=n32");
 
-    MultilibBuilder M32 =
-        MultilibBuilder().gccSuffix("/32").flag("-m64").flag("+m32").flag(
-            "-mabi=n32");
+    MultilibBuilder M32 = MultilibBuilder()
+                              .gccSuffix("/32")
+                              .flag(false, "-m64")
+                              .flag(true, "-m32")
+                              .flag(false, "-mabi=n32");
 
     DebianMipsMultilibs = MultilibSetBuilder()
                               .Either(M32, M64, MAbiN32)
@@ -1161,30 +1168,32 @@ static bool findMipsAndroidMultilibs(llvm::vfs::FileSystem &VFS, StringRef Path,
 
   MultilibSet AndroidMipsMultilibs =
       MultilibSetBuilder()
-          .Maybe(MultilibBuilder("/mips-r2", {}, {}).flag("+march=mips32r2"))
-          .Maybe(MultilibBuilder("/mips-r6", {}, {}).flag("+march=mips32r6"))
+          .Maybe(
+              MultilibBuilder("/mips-r2", {}, {}).flag(true, "-march=mips32r2"))
+          .Maybe(
+              MultilibBuilder("/mips-r6", {}, {}).flag(true, "-march=mips32r6"))
           .makeMultilibSet()
           .FilterOut(NonExistent);
 
   MultilibSet AndroidMipselMultilibs =
       MultilibSetBuilder()
-          .Either(MultilibBuilder().flag("+march=mips32"),
+          .Either(MultilibBuilder().flag(true, "-march=mips32"),
                   MultilibBuilder("/mips-r2", "", "/mips-r2")
-                      .flag("+march=mips32r2"),
+                      .flag(true, "-march=mips32r2"),
                   MultilibBuilder("/mips-r6", "", "/mips-r6")
-                      .flag("+march=mips32r6"))
+                      .flag(true, "-march=mips32r6"))
           .makeMultilibSet()
           .FilterOut(NonExistent);
 
   MultilibSet AndroidMips64elMultilibs =
       MultilibSetBuilder()
-          .Either(MultilibBuilder().flag("+march=mips64r6"),
+          .Either(MultilibBuilder().flag(true, "-march=mips64r6"),
                   MultilibBuilder("/32/mips-r1", "", "/mips-r1")
-                      .flag("+march=mips32"),
+                      .flag(true, "-march=mips32"),
                   MultilibBuilder("/32/mips-r2", "", "/mips-r2")
-                      .flag("+march=mips32r2"),
+                      .flag(true, "-march=mips32r2"),
                   MultilibBuilder("/32/mips-r6", "", "/mips-r6")
-                      .flag("+march=mips32r6"))
+                      .flag(true, "-march=mips32r6"))
           .makeMultilibSet()
           .FilterOut(NonExistent);
 
@@ -1208,14 +1217,14 @@ static bool findMipsMuslMultilibs(const Multilib::flags_list &Flags,
   {
     auto MArchMipsR2 = MultilibBuilder("")
                            .osSuffix("/mips-r2-hard-musl")
-                           .flag("+EB")
-                           .flag("-EL")
-                           .flag("+march=mips32r2");
+                           .flag(true, "-EB")
+                           .flag(false, "-EL")
+                           .flag(true, "-march=mips32r2");
 
     auto MArchMipselR2 = MultilibBuilder("/mipsel-r2-hard-musl")
-                             .flag("-EB")
-                             .flag("+EL")
-                             .flag("+march=mips32r2");
+                             .flag(false, "-EB")
+                             .flag(true, "-EL")
+                             .flag(true, "-march=mips32r2");
 
     MuslMipsMultilibs = MultilibSetBuilder()
                             .Either(MArchMipsR2, MArchMipselR2)
@@ -1241,45 +1250,49 @@ static bool findMipsMtiMultilibs(const Multilib::flags_list &Flags,
   MultilibSet MtiMipsMultilibsV1;
   {
     auto MArchMips32 = MultilibBuilder("/mips32")
-                           .flag("+m32")
-                           .flag("-m64")
-                           .flag("-mmicromips")
-                           .flag("+march=mips32");
+                           .flag(true, "-m32")
+                           .flag(false, "-m64")
+                           .flag(false, "-mmicromips")
+                           .flag(true, "-march=mips32");
 
     auto MArchMicroMips = MultilibBuilder("/micromips")
-                              .flag("+m32")
-                              .flag("-m64")
-                              .flag("+mmicromips");
+                              .flag(true, "-m32")
+                              .flag(false, "-m64")
+                              .flag(true, "-mmicromips");
 
     auto MArchMips64r2 = MultilibBuilder("/mips64r2")
-                             .flag("-m32")
-                             .flag("+m64")
-                             .flag("+march=mips64r2");
+                             .flag(false, "-m32")
+                             .flag(true, "-m64")
+                             .flag(true, "-march=mips64r2");
 
-    auto MArchMips64 =
-        MultilibBuilder("/mips64").flag("-m32").flag("+m64").flag(
-            "-march=mips64r2");
+    auto MArchMips64 = MultilibBuilder("/mips64")
+                           .flag(false, "-m32")
+                           .flag(true, "-m64")
+                           .flag(false, "-march=mips64r2");
 
     auto MArchDefault = MultilibBuilder("")
-                            .flag("+m32")
-                            .flag("-m64")
-                            .flag("-mmicromips")
-                            .flag("+march=mips32r2");
+                            .flag(true, "-m32")
+                            .flag(false, "-m64")
+                            .flag(false, "-mmicromips")
+                            .flag(true, "-march=mips32r2");
 
-    auto Mips16 = MultilibBuilder("/mips16").flag("+mips16");
+    auto Mips16 = MultilibBuilder("/mips16").flag(true, "-mips16");
 
-    auto UCLibc = MultilibBuilder("/uclibc").flag("+muclibc");
+    auto UCLibc = MultilibBuilder("/uclibc").flag(true, "-muclibc");
 
-    auto MAbi64 =
-        MultilibBuilder("/64").flag("+mabi=n64").flag("-mabi=n32").flag("-m32");
+    auto MAbi64 = MultilibBuilder("/64")
+                      .flag(true, "-mabi=n64")
+                      .flag(false, "-mabi=n32")
+                      .flag(false, "-m32");
 
-    auto BigEndian = MultilibBuilder("").flag("+EB").flag("-EL");
+    auto BigEndian = MultilibBuilder("").flag(true, "-EB").flag(false, "-EL");
 
-    auto LittleEndian = MultilibBuilder("/el").flag("+EL").flag("-EB");
+    auto LittleEndian =
+        MultilibBuilder("/el").flag(true, "-EL").flag(false, "-EB");
 
-    auto SoftFloat = MultilibBuilder("/sof").flag("+msoft-float");
+    auto SoftFloat = MultilibBuilder("/sof").flag(true, "-msoft-float");
 
-    auto Nan2008 = MultilibBuilder("/nan2008").flag("+mnan=2008");
+    auto Nan2008 = MultilibBuilder("/nan2008").flag(true, "-mnan=2008");
 
     MtiMipsMultilibsV1 =
         MultilibSetBuilder()
@@ -1315,78 +1328,78 @@ static bool findMipsMtiMultilibs(const Multilib::flags_list &Flags,
   MultilibSet MtiMipsMultilibsV2;
   {
     auto BeHard = MultilibBuilder("/mips-r2-hard")
-                      .flag("+EB")
-                      .flag("-msoft-float")
-                      .flag("-mnan=2008")
-                      .flag("-muclibc");
+                      .flag(true, "-EB")
+                      .flag(false, "-msoft-float")
+                      .flag(false, "-mnan=2008")
+                      .flag(false, "-muclibc");
     auto BeSoft = MultilibBuilder("/mips-r2-soft")
-                      .flag("+EB")
-                      .flag("+msoft-float")
-                      .flag("-mnan=2008");
+                      .flag(true, "-EB")
+                      .flag(true, "-msoft-float")
+                      .flag(false, "-mnan=2008");
     auto ElHard = MultilibBuilder("/mipsel-r2-hard")
-                      .flag("+EL")
-                      .flag("-msoft-float")
-                      .flag("-mnan=2008")
-                      .flag("-muclibc");
+                      .flag(true, "-EL")
+                      .flag(false, "-msoft-float")
+                      .flag(false, "-mnan=2008")
+                      .flag(false, "-muclibc");
     auto ElSoft = MultilibBuilder("/mipsel-r2-soft")
-                      .flag("+EL")
-                      .flag("+msoft-float")
-                      .flag("-mnan=2008")
-                      .flag("-mmicromips");
+                      .flag(true, "-EL")
+                      .flag(true, "-msoft-float")
+                      .flag(false, "-mnan=2008")
+                      .flag(false, "-mmicromips");
     auto BeHardNan = MultilibBuilder("/mips-r2-hard-nan2008")
-                         .flag("+EB")
-                         .flag("-msoft-float")
-                         .flag("+mnan=2008")
-                         .flag("-muclibc");
+                         .flag(true, "-EB")
+                         .flag(false, "-msoft-float")
+                         .flag(true, "-mnan=2008")
+                         .flag(false, "-muclibc");
     auto ElHardNan = MultilibBuilder("/mipsel-r2-hard-nan2008")
-                         .flag("+EL")
-                         .flag("-msoft-float")
-                         .flag("+mnan=2008")
-                         .flag("-muclibc")
-                         .flag("-mmicromips");
+                         .flag(true, "-EL")
+                         .flag(false, "-msoft-float")
+                         .flag(true, "-mnan=2008")
+                         .flag(false, "-muclibc")
+                         .flag(false, "-mmicromips");
     auto BeHardNanUclibc = MultilibBuilder("/mips-r2-hard-nan2008-uclibc")
-                               .flag("+EB")
-                               .flag("-msoft-float")
-                               .flag("+mnan=2008")
-                               .flag("+muclibc");
+                               .flag(true, "-EB")
+                               .flag(false, "-msoft-float")
+                               .flag(true, "-mnan=2008")
+                               .flag(true, "-muclibc");
     auto ElHardNanUclibc = MultilibBuilder("/mipsel-r2-hard-nan2008-uclibc")
-                               .flag("+EL")
-                               .flag("-msoft-float")
-                               .flag("+mnan=2008")
-                               .flag("+muclibc");
+                               .flag(true, "-EL")
+                               .flag(false, "-msoft-float")
+                               .flag(true, "-mnan=2008")
+                               .flag(true, "-muclibc");
     auto BeHardUclibc = MultilibBuilder("/mips-r2-hard-uclibc")
-                            .flag("+EB")
-                            .flag("-msoft-float")
-                            .flag("-mnan=2008")
-                            .flag("+muclibc");
+                            .flag(true, "-EB")
+                            .flag(false, "-msoft-float")
+                            .flag(false, "-mnan=2008")
+                            .flag(true, "-muclibc");
     auto ElHardUclibc = MultilibBuilder("/mipsel-r2-hard-uclibc")
-                            .flag("+EL")
-                            .flag("-msoft-float")
-                            .flag("-mnan=2008")
-                            .flag("+muclibc");
+                            .flag(true, "-EL")
+                            .flag(false, "-msoft-float")
+                            .flag(false, "-mnan=2008")
+                            .flag(true, "-muclibc");
     auto ElMicroHardNan = MultilibBuilder("/micromipsel-r2-hard-nan2008")
-                              .flag("+EL")
-                              .flag("-msoft-float")
-                              .flag("+mnan=2008")
-                              .flag("+mmicromips");
+                              .flag(true, "-EL")
+                              .flag(false, "-msoft-float")
+                              .flag(true, "-mnan=2008")
+                              .flag(true, "-mmicromips");
     auto ElMicroSoft = MultilibBuilder("/micromipsel-r2-soft")
-                           .flag("+EL")
-                           .flag("+msoft-float")
-                           .flag("-mnan=2008")
-                           .flag("+mmicromips");
+                           .flag(true, "-EL")
+                           .flag(true, "-msoft-float")
+                           .flag(false, "-mnan=2008")
+                           .flag(true, "-mmicromips");
 
     auto O32 = MultilibBuilder("/lib")
                    .osSuffix("")
-                   .flag("-mabi=n32")
-                   .flag("-mabi=n64");
+                   .flag(false, "-mabi=n32")
+                   .flag(false, "-mabi=n64");
     auto N32 = MultilibBuilder("/lib32")
                    .osSuffix("")
-                   .flag("+mabi=n32")
-                   .flag("-mabi=n64");
+                   .flag(true, "-mabi=n32")
+                   .flag(false, "-mabi=n64");
     auto N64 = MultilibBuilder("/lib64")
                    .osSuffix("")
-                   .flag("-mabi=n32")
-                   .flag("+mabi=n64");
+                   .flag(false, "-mabi=n32")
+                   .flag(true, "-mabi=n64");
 
     MtiMipsMultilibsV2 =
         MultilibSetBuilder()
@@ -1421,12 +1434,16 @@ static bool findMipsImgMultilibs(const Multilib::flags_list &Flags,
   // CodeScape IMG toolchain v1.2 and early.
   MultilibSet ImgMultilibsV1;
   {
-    auto Mips64r6 = MultilibBuilder("/mips64r6").flag("+m64").flag("-m32");
+    auto Mips64r6 =
+        MultilibBuilder("/mips64r6").flag(true, "-m64").flag(false, "-m32");
 
-    auto LittleEndian = MultilibBuilder("/el").flag("+EL").flag("-EB");
+    auto LittleEndian =
+        MultilibBuilder("/el").flag(true, "-EL").flag(false, "-EB");
 
-    auto MAbi64 =
-        MultilibBuilder("/64").flag("+mabi=n64").flag("-mabi=n32").flag("-m32");
+    auto MAbi64 = MultilibBuilder("/64")
+                      .flag(true, "-mabi=n64")
+                      .flag(false, "-mabi=n32")
+                      .flag(false, "-m32");
 
     ImgMultilibsV1 =
         MultilibSetBuilder()
@@ -1445,50 +1462,50 @@ static bool findMipsImgMultilibs(const Multilib::flags_list &Flags,
   MultilibSet ImgMultilibsV2;
   {
     auto BeHard = MultilibBuilder("/mips-r6-hard")
-                      .flag("+EB")
-                      .flag("-msoft-float")
-                      .flag("-mmicromips");
+                      .flag(true, "-EB")
+                      .flag(false, "-msoft-float")
+                      .flag(false, "-mmicromips");
     auto BeSoft = MultilibBuilder("/mips-r6-soft")
-                      .flag("+EB")
-                      .flag("+msoft-float")
-                      .flag("-mmicromips");
+                      .flag(true, "-EB")
+                      .flag(true, "-msoft-float")
+                      .flag(false, "-mmicromips");
     auto ElHard = MultilibBuilder("/mipsel-r6-hard")
-                      .flag("+EL")
-                      .flag("-msoft-float")
-                      .flag("-mmicromips");
+                      .flag(true, "-EL")
+                      .flag(false, "-msoft-float")
+                      .flag(false, "-mmicromips");
     auto ElSoft = MultilibBuilder("/mipsel-r6-soft")
-                      .flag("+EL")
-                      .flag("+msoft-float")
-                      .flag("-mmicromips");
+                      .flag(true, "-EL")
+                      .flag(true, "-msoft-float")
+                      .flag(false, "-mmicromips");
     auto BeMicroHard = MultilibBuilder("/micromips-r6-hard")
-                           .flag("+EB")
-                           .flag("-msoft-float")
-                           .flag("+mmicromips");
+                           .flag(true, "-EB")
+                           .flag(false, "-msoft-float")
+                           .flag(true, "-mmicromips");
     auto BeMicroSoft = MultilibBuilder("/micromips-r6-soft")
-                           .flag("+EB")
-                           .flag("+msoft-float")
-                           .flag("+mmicromips");
+                           .flag(true, "-EB")
+                           .flag(true, "-msoft-float")
+                           .flag(true, "-mmicromips");
     auto ElMicroHard = MultilibBuilder("/micromipsel-r6-hard")
-                           .flag("+EL")
-                           .flag("-msoft-float")
-                           .flag("+mmicromips");
+                           .flag(true, "-EL")
+                           .flag(false, "-msoft-float")
+                           .flag(true, "-mmicromips");
     auto ElMicroSoft = MultilibBuilder("/micromipsel-r6-soft")
-                           .flag("+EL")
-                           .flag("+msoft-float")
-                           .flag("+mmicromips");
+                           .flag(true, "-EL")
+                           .flag(true, "-msoft-float")
+                           .flag(true, "-mmicromips");
 
     auto O32 = MultilibBuilder("/lib")
                    .osSuffix("")
-                   .flag("-mabi=n32")
-                   .flag("-mabi=n64");
+                   .flag(false, "-mabi=n32")
+                   .flag(false, "-mabi=n64");
     auto N32 = MultilibBuilder("/lib32")
                    .osSuffix("")
-                   .flag("+mabi=n32")
-                   .flag("-mabi=n64");
+                   .flag(true, "-mabi=n32")
+                   .flag(false, "-mabi=n64");
     auto N64 = MultilibBuilder("/lib64")
                    .osSuffix("")
-                   .flag("-mabi=n32")
-                   .flag("+mabi=n64");
+                   .flag(false, "-mabi=n32")
+                   .flag(true, "-mabi=n64");
 
     ImgMultilibsV2 =
         MultilibSetBuilder()
@@ -1529,30 +1546,30 @@ bool clang::driver::findMIPSMultilibs(const Driver &D,
   llvm::Triple::ArchType TargetArch = TargetTriple.getArch();
 
   Multilib::flags_list Flags;
-  addMultilibFlag(TargetTriple.isMIPS32(), "m32", Flags);
-  addMultilibFlag(TargetTriple.isMIPS64(), "m64", Flags);
-  addMultilibFlag(isMips16(Args), "mips16", Flags);
-  addMultilibFlag(CPUName == "mips32", "march=mips32", Flags);
+  addMultilibFlag(TargetTriple.isMIPS32(), "-m32", Flags);
+  addMultilibFlag(TargetTriple.isMIPS64(), "-m64", Flags);
+  addMultilibFlag(isMips16(Args), "-mips16", Flags);
+  addMultilibFlag(CPUName == "mips32", "-march=mips32", Flags);
   addMultilibFlag(CPUName == "mips32r2" || CPUName == "mips32r3" ||
                       CPUName == "mips32r5" || CPUName == "p5600",
-                  "march=mips32r2", Flags);
-  addMultilibFlag(CPUName == "mips32r6", "march=mips32r6", Flags);
-  addMultilibFlag(CPUName == "mips64", "march=mips64", Flags);
+                  "-march=mips32r2", Flags);
+  addMultilibFlag(CPUName == "mips32r6", "-march=mips32r6", Flags);
+  addMultilibFlag(CPUName == "mips64", "-march=mips64", Flags);
   addMultilibFlag(CPUName == "mips64r2" || CPUName == "mips64r3" ||
                       CPUName == "mips64r5" || CPUName == "octeon" ||
                       CPUName == "octeon+",
-                  "march=mips64r2", Flags);
-  addMultilibFlag(CPUName == "mips64r6", "march=mips64r6", Flags);
-  addMultilibFlag(isMicroMips(Args), "mmicromips", Flags);
-  addMultilibFlag(tools::mips::isUCLibc(Args), "muclibc", Flags);
-  addMultilibFlag(tools::mips::isNaN2008(D, Args, TargetTriple), "mnan=2008",
+                  "-march=mips64r2", Flags);
+  addMultilibFlag(CPUName == "mips64r6", "-march=mips64r6", Flags);
+  addMultilibFlag(isMicroMips(Args), "-mmicromips", Flags);
+  addMultilibFlag(tools::mips::isUCLibc(Args), "-muclibc", Flags);
+  addMultilibFlag(tools::mips::isNaN2008(D, Args, TargetTriple), "-mnan=2008",
                   Flags);
-  addMultilibFlag(ABIName == "n32", "mabi=n32", Flags);
-  addMultilibFlag(ABIName == "n64", "mabi=n64", Flags);
-  addMultilibFlag(isSoftFloatABI(Args), "msoft-float", Flags);
-  addMultilibFlag(!isSoftFloatABI(Args), "mhard-float", Flags);
-  addMultilibFlag(isMipsEL(TargetArch), "EL", Flags);
-  addMultilibFlag(!isMipsEL(TargetArch), "EB", Flags);
+  addMultilibFlag(ABIName == "n32", "-mabi=n32", Flags);
+  addMultilibFlag(ABIName == "n64", "-mabi=n64", Flags);
+  addMultilibFlag(isSoftFloatABI(Args), "-msoft-float", Flags);
+  addMultilibFlag(!isSoftFloatABI(Args), "-mhard-float", Flags);
+  addMultilibFlag(isMipsEL(TargetArch), "-EL", Flags);
+  addMultilibFlag(!isMipsEL(TargetArch), "-EB", Flags);
 
   if (TargetTriple.isAndroid())
     return findMipsAndroidMultilibs(D.getVFS(), Path, Flags, NonExistent,
@@ -1595,14 +1612,17 @@ static void findAndroidArmMultilibs(const Driver &D,
                                     DetectedMultilibs &Result) {
   // Find multilibs with subdirectories like armv7-a, thumb, armv7-a/thumb.
   FilterNonExistent NonExistent(Path, "/crtbegin.o", D.getVFS());
-  MultilibBuilder ArmV7Multilib =
-      MultilibBuilder("/armv7-a").flag("+march=armv7-a").flag("-mthumb");
-  MultilibBuilder ThumbMultilib =
-      MultilibBuilder("/thumb").flag("-march=armv7-a").flag("+mthumb");
-  MultilibBuilder ArmV7ThumbMultilib =
-      MultilibBuilder("/armv7-a/thumb").flag("+march=armv7-a").flag("+mthumb");
+  MultilibBuilder ArmV7Multilib = MultilibBuilder("/armv7-a")
+                                      .flag(true, "-march=armv7-a")
+                                      .flag(false, "-mthumb");
+  MultilibBuilder ThumbMultilib = MultilibBuilder("/thumb")
+                                      .flag(false, "-march=armv7-a")
+                                      .flag(true, "-mthumb");
+  MultilibBuilder ArmV7ThumbMultilib = MultilibBuilder("/armv7-a/thumb")
+                                           .flag(true, "-march=armv7-a")
+                                           .flag(true, "-mthumb");
   MultilibBuilder DefaultMultilib =
-      MultilibBuilder("").flag("-march=armv7-a").flag("-mthumb");
+      MultilibBuilder("").flag(false, "-march=armv7-a").flag(false, "-mthumb");
   MultilibSet AndroidArmMultilibs =
       MultilibSetBuilder()
           .Either(ThumbMultilib, ArmV7Multilib, ArmV7ThumbMultilib,
@@ -1621,8 +1641,8 @@ static void findAndroidArmMultilibs(const Driver &D,
   bool IsArmV7Mode = (IsArmArch || IsThumbArch) &&
       (llvm::ARM::parseArchVersion(Arch) == 7 ||
        (IsArmArch && Arch == "" && IsV7SubArch));
-  addMultilibFlag(IsArmV7Mode, "march=armv7-a", Flags);
-  addMultilibFlag(IsThumbMode, "mthumb", Flags);
+  addMultilibFlag(IsArmV7Mode, "-march=armv7-a", Flags);
+  addMultilibFlag(IsThumbMode, "-mthumb", Flags);
 
   if (AndroidArmMultilibs.select(Flags, Result.SelectedMultilib))
     Result.Multilibs = AndroidArmMultilibs;
@@ -1634,9 +1654,9 @@ static bool findMSP430Multilibs(const Driver &D,
                                 DetectedMultilibs &Result) {
   FilterNonExistent NonExistent(Path, "/crtbegin.o", D.getVFS());
   MultilibBuilder WithoutExceptions =
-      MultilibBuilder("/430").flag("-exceptions");
+      MultilibBuilder("/430").flag(false, "-exceptions");
   MultilibBuilder WithExceptions =
-      MultilibBuilder("/430/exceptions").flag("+exceptions");
+      MultilibBuilder("/430/exceptions").flag(true, "-exceptions");
 
   // FIXME: when clang starts to support msp430x ISA additional logic
   // to select between multilib must be implemented
@@ -1649,7 +1669,7 @@ static bool findMSP430Multilibs(const Driver &D,
   Multilib::flags_list Flags;
   addMultilibFlag(Args.hasFlag(options::OPT_fexceptions,
                                options::OPT_fno_exceptions, false),
-                  "exceptions", Flags);
+                  "-exceptions", Flags);
   if (Result.Multilibs.select(Flags, Result.SelectedMultilib))
     return true;
 
@@ -1670,42 +1690,43 @@ static void findCSKYMultilibs(const Driver &D, const llvm::Triple &TargetTriple,
   auto ARCHName = *Res;
 
   Multilib::flags_list Flags;
-  addMultilibFlag(TheFloatABI == tools::csky::FloatABI::Hard, "hard-fp", Flags);
-  addMultilibFlag(TheFloatABI == tools::csky::FloatABI::SoftFP, "soft-fp",
+  addMultilibFlag(TheFloatABI == tools::csky::FloatABI::Hard, "-hard-fp",
+                  Flags);
+  addMultilibFlag(TheFloatABI == tools::csky::FloatABI::SoftFP, "-soft-fp",
                   Flags);
-  addMultilibFlag(TheFloatABI == tools::csky::FloatABI::Soft, "soft", Flags);
-  addMultilibFlag(ARCHName == "ck801", "march=ck801", Flags);
-  addMultilibFlag(ARCHName == "ck802", "march=ck802", Flags);
-  addMultilibFlag(ARCHName == "ck803", "march=ck803", Flags);
-  addMultilibFlag(ARCHName == "ck804", "march=ck804", Flags);
-  addMultilibFlag(ARCHName == "ck805", "march=ck805", Flags);
-  addMultilibFlag(ARCHName == "ck807", "march=ck807", Flags);
-  addMultilibFlag(ARCHName == "ck810", "march=ck810", Flags);
-  addMultilibFlag(ARCHName == "ck810v", "march=ck810v", Flags);
-  addMultilibFlag(ARCHName == "ck860", "march=ck860", Flags);
-  addMultilibFlag(ARCHName == "ck860v", "march=ck860v", Flags);
+  addMultilibFlag(TheFloatABI == tools::csky::FloatABI::Soft, "-soft", Flags);
+  addMultilibFlag(ARCHName == "ck801", "-march=ck801", Flags);
+  addMultilibFlag(ARCHName == "ck802", "-march=ck802", Flags);
+  addMultilibFlag(ARCHName == "ck803", "-march=ck803", Flags);
+  addMultilibFlag(ARCHName == "ck804", "-march=ck804", Flags);
+  addMultilibFlag(ARCHName == "ck805", "-march=ck805", Flags);
+  addMultilibFlag(ARCHName == "ck807", "-march=ck807", Flags);
+  addMultilibFlag(ARCHName == "ck810", "-march=ck810", Flags);
+  addMultilibFlag(ARCHName == "ck810v", "-march=ck810v", Flags);
+  addMultilibFlag(ARCHName == "ck860", "-march=ck860", Flags);
+  addMultilibFlag(ARCHName == "ck860v", "-march=ck860v", Flags);
 
   bool isBigEndian = false;
   if (Arg *A = Args.getLastArg(options::OPT_mlittle_endian,
                                options::OPT_mbig_endian))
     isBigEndian = !A->getOption().matches(options::OPT_mlittle_endian);
-  addMultilibFlag(isBigEndian, "EB", Flags);
-
-  auto HardFloat = MultilibBuilder("/hard-fp").flag("+hard-fp");
-  auto SoftFpFloat = MultilibBuilder("/soft-fp").flag("+soft-fp");
-  auto SoftFloat = MultilibBuilder("").flag("+soft");
-  auto Arch801 = MultilibBuilder("/ck801").flag("+march=ck801");
-  auto Arch802 = MultilibBuilder("/ck802").flag("+march=ck802");
-  auto Arch803 = MultilibBuilder("/ck803").flag("+march=ck803");
+  addMultilibFlag(isBigEndian, "-EB", Flags);
+
+  auto HardFloat = MultilibBuilder("/hard-fp").flag(true, "-hard-fp");
+  auto SoftFpFloat = MultilibBuilder("/soft-fp").flag(true, "-soft-fp");
+  auto SoftFloat = MultilibBuilder("").flag(true, "-soft");
+  auto Arch801 = MultilibBuilder("/ck801").flag(true, "-march=ck801");
+  auto Arch802 = MultilibBuilder("/ck802").flag(true, "-march=ck802");
+  auto Arch803 = MultilibBuilder("/ck803").flag(true, "-march=ck803");
   // CK804 use the same library as CK803
-  auto Arch804 = MultilibBuilder("/ck803").flag("+march=ck804");
-  auto Arch805 = MultilibBuilder("/ck805").flag("+march=ck805");
-  auto Arch807 = MultilibBuilder("/ck807").flag("+march=ck807");
-  auto Arch810 = MultilibBuilder("").flag("+march=ck810");
-  auto Arch810v = MultilibBuilder("/ck810v").flag("+march=ck810v");
-  auto Arch860 = MultilibBuilder("/ck860").flag("+march=ck860");
-  auto Arch860v = MultilibBuilder("/ck860v").flag("+march=ck860v");
-  auto BigEndian = MultilibBuilder("/big").flag("+EB");
+  auto Arch804 = MultilibBuilder("/ck803").flag(true, "-march=ck804");
+  auto Arch805 = MultilibBuilder("/ck805").flag(true, "-march=ck805");
+  auto Arch807 = MultilibBuilder("/ck807").flag(true, "-march=ck807");
+  auto Arch810 = MultilibBuilder("").flag(true, "-march=ck810");
+  auto Arch810v = MultilibBuilder("/ck810v").flag(true, "-march=ck810v");
+  auto Arch860 = MultilibBuilder("/ck860").flag(true, "-march=ck860");
+  auto Arch860v = MultilibBuilder("/ck860v").flag(true, "-march=ck860v");
+  auto BigEndian = MultilibBuilder("/big").flag(true, "-EB");
 
   MultilibSet CSKYMultilibs =
       MultilibSetBuilder()
@@ -1742,8 +1763,8 @@ static void findRISCVBareMetalMultilibs(const Driver &D,
     Ms.emplace_back(
         MultilibBuilder(
             (Twine(Element.march) + "/" + Twine(Element.mabi)).str())
-            .flag(Twine("+march=", Element.march).str())
-            .flag(Twine("+mabi=", Element.mabi).str()));
+            .flag(true, Twine("-march=", Element.march).str())
+            .flag(true, Twine("-mabi=", Element.mabi).str()));
   }
   MultilibSet RISCVMultilibs =
       MultilibSetBuilder()
@@ -1763,11 +1784,11 @@ static void findRISCVBareMetalMultilibs(const Driver &D,
   StringRef MArch = tools::riscv::getRISCVArch(Args, TargetTriple);
   for (auto Element : RISCVMultilibSet) {
     addMultilibFlag(MArch == Element.march,
-                    Twine("march=", Element.march).str().c_str(), Flags);
+                    Twine("-march=", Element.march).str().c_str(), Flags);
     if (!Added_ABIs.count(Element.mabi)) {
       Added_ABIs.insert(Element.mabi);
       addMultilibFlag(ABIName == Element.mabi,
-                      Twine("mabi=", Element.mabi).str().c_str(), Flags);
+                      Twine("-mabi=", Element.mabi).str().c_str(), Flags);
     }
   }
 
@@ -1782,18 +1803,23 @@ static void findRISCVMultilibs(const Driver &D,
     return findRISCVBareMetalMultilibs(D, TargetTriple, Path, Args, Result);
 
   FilterNonExistent NonExistent(Path, "/crtbegin.o", D.getVFS());
-  MultilibBuilder Ilp32 =
-      MultilibBuilder("lib32/ilp32").flag("+m32").flag("+mabi=ilp32");
-  MultilibBuilder Ilp32f =
-      MultilibBuilder("lib32/ilp32f").flag("+m32").flag("+mabi=ilp32f");
-  MultilibBuilder Ilp32d =
-      MultilibBuilder("lib32/ilp32d").flag("+m32").flag("+mabi=ilp32d");
+  MultilibBuilder Ilp32 = MultilibBuilder("lib32/ilp32")
+                              .flag(true, "-m32")
+                              .flag(true, "-mabi=ilp32");
+  MultilibBuilder Ilp32f = MultilibBuilder("lib32/ilp32f")
+                               .flag(true, "-m32")
+                               .flag(true, "-mabi=ilp32f");
+  MultilibBuilder Ilp32d = MultilibBuilder("lib32/ilp32d")
+                               .flag(true, "-m32")
+                               .flag(true, "-mabi=ilp32d");
   MultilibBuilder Lp64 =
-      MultilibBuilder("lib64/lp64").flag("+m64").flag("+mabi=lp64");
-  MultilibBuilder Lp64f =
-      MultilibBuilder("lib64/lp64f").flag("+m64").flag("+mabi=lp64f");
-  MultilibBuilder Lp64d =
-      MultilibBuilder("lib64/lp64d").flag("+m64").flag("+mabi=lp64d");
+      MultilibBuilder("lib64/lp64").flag(true, "-m64").flag(true, "-mabi=lp64");
+  MultilibBuilder Lp64f = MultilibBuilder("lib64/lp64f")
+                              .flag(true, "-m64")
+                              .flag(true, "-mabi=lp64f");
+  MultilibBuilder Lp64d = MultilibBuilder("lib64/lp64d")
+                              .flag(true, "-m64")
+                              .flag(true, "-mabi=lp64d");
   MultilibSet RISCVMultilibs =
       MultilibSetBuilder()
           .Either({Ilp32, Ilp32f, Ilp32d, Lp64, Lp64f, Lp64d})
@@ -1804,14 +1830,14 @@ static void findRISCVMultilibs(const Driver &D,
   bool IsRV64 = TargetTriple.getArch() == llvm::Triple::riscv64;
   StringRef ABIName = tools::riscv::getRISCVABI(Args, TargetTriple);
 
-  addMultilibFlag(!IsRV64, "m32", Flags);
-  addMultilibFlag(IsRV64, "m64", Flags);
-  addMultilibFlag(ABIName == "ilp32", "mabi=ilp32", Flags);
-  addMultilibFlag(ABIName == "ilp32f", "mabi=ilp32f", Flags);
-  addMultilibFlag(ABIName == "ilp32d", "mabi=ilp32d", Flags);
-  addMultilibFlag(ABIName == "lp64", "mabi=lp64", Flags);
-  addMultilibFlag(ABIName == "lp64f", "mabi=lp64f", Flags);
-  addMultilibFlag(ABIName == "lp64d", "mabi=lp64d", Flags);
+  addMultilibFlag(!IsRV64, "-m32", Flags);
+  addMultilibFlag(IsRV64, "-m64", Flags);
+  addMultilibFlag(ABIName == "ilp32", "-mabi=ilp32", Flags);
+  addMultilibFlag(ABIName == "ilp32f", "-mabi=ilp32f", Flags);
+  addMultilibFlag(ABIName == "ilp32d", "-mabi=ilp32d", Flags);
+  addMultilibFlag(ABIName == "lp64", "-mabi=lp64", Flags);
+  addMultilibFlag(ABIName == "lp64f", "-mabi=lp64f", Flags);
+  addMultilibFlag(ABIName == "lp64d", "-mabi=lp64d", Flags);
 
   if (RISCVMultilibs.select(Flags, Result.SelectedMultilib))
     Result.Multilibs = RISCVMultilibs;
@@ -1851,23 +1877,23 @@ static bool findBiarchMultilibs(const Driver &D,
   Multilib Alt64 = MultilibBuilder()
                        .gccSuffix(Suff64)
                        .includeSuffix(Suff64)
-                       .flag("-m32")
-                       .flag("+m64")
-                       .flag("-mx32")
+                       .flag(false, "-m32")
+                       .flag(true, "-m64")
+                       .flag(false, "-mx32")
                        .makeMultilib();
   Multilib Alt32 = MultilibBuilder()
                        .gccSuffix("/32")
                        .includeSuffix("/32")
-                       .flag("+m32")
-                       .flag("-m64")
-                       .flag("-mx32")
+                       .flag(true, "-m32")
+                       .flag(false, "-m64")
+                       .flag(false, "-mx32")
                        .makeMultilib();
   Multilib Altx32 = MultilibBuilder()
                         .gccSuffix("/x32")
                         .includeSuffix("/x32")
-                        .flag("-m32")
-                        .flag("-m64")
-                        .flag("+mx32")
+                        .flag(false, "-m32")
+                        .flag(false, "-m64")
+                        .flag(true, "-mx32")
                         .makeMultilib();
 
   // GCC toolchain for IAMCU doesn't have crtbegin.o, so look for libgcc.a.
@@ -1894,11 +1920,11 @@ static bool findBiarchMultilibs(const Driver &D,
   }
 
   if (Want == WANT32)
-    DefaultBuilder.flag("+m32").flag("-m64").flag("-mx32");
+    DefaultBuilder.flag(true, "-m32").flag(false, "-m64").flag(false, "-mx32");
   else if (Want == WANT64)
-    DefaultBuilder.flag("-m32").flag("+m64").flag("-mx32");
+    DefaultBuilder.flag(false, "-m32").flag(true, "-m64").flag(false, "-mx32");
   else if (Want == WANTX32)
-    DefaultBuilder.flag("-m32").flag("-m64").flag("+mx32");
+    DefaultBuilder.flag(false, "-m32").flag(false, "-m64").flag(true, "-mx32");
   else
     return false;
 
@@ -1912,9 +1938,9 @@ static bool findBiarchMultilibs(const Driver &D,
   Result.Multilibs.FilterOut(NonExistent);
 
   Multilib::flags_list Flags;
-  addMultilibFlag(TargetTriple.isArch64Bit() && !IsX32, "m64", Flags);
-  addMultilibFlag(TargetTriple.isArch32Bit(), "m32", Flags);
-  addMultilibFlag(TargetTriple.isArch64Bit() && IsX32, "mx32", Flags);
+  addMultilibFlag(TargetTriple.isArch64Bit() && !IsX32, "-m64", Flags);
+  addMultilibFlag(TargetTriple.isArch32Bit(), "-m32", Flags);
+  addMultilibFlag(TargetTriple.isArch64Bit() && IsX32, "-mx32", Flags);
 
   if (!Result.Multilibs.select(Flags, Result.SelectedMultilib))
     return false;

diff  --git a/clang/lib/Driver/ToolChains/OHOS.cpp b/clang/lib/Driver/ToolChains/OHOS.cpp
index ea0c1c12541ca..833204e1dc535 100644
--- a/clang/lib/Driver/ToolChains/OHOS.cpp
+++ b/clang/lib/Driver/ToolChains/OHOS.cpp
@@ -66,20 +66,20 @@ static bool findOHOSMultilibs(const Driver &D,
   bool IsA7 = false;
   if (const Arg *A = Args.getLastArg(options::OPT_mcpu_EQ))
     IsA7 = A->getValue() == StringRef("cortex-a7");
-  addMultilibFlag(IsA7, "mcpu=cortex-a7", Flags);
+  addMultilibFlag(IsA7, "-mcpu=cortex-a7", Flags);
 
   bool IsMFPU = false;
   if (const Arg *A = Args.getLastArg(options::OPT_mfpu_EQ))
     IsMFPU = A->getValue() == StringRef("neon-vfpv4");
-  addMultilibFlag(IsMFPU, "mfpu=neon-vfpv4", Flags);
+  addMultilibFlag(IsMFPU, "-mfpu=neon-vfpv4", Flags);
 
   tools::arm::FloatABI ARMFloatABI = getARMFloatABI(D, TargetTriple, Args);
   addMultilibFlag((ARMFloatABI == tools::arm::FloatABI::Soft),
-      "mfloat-abi=soft", Flags);
+                  "-mfloat-abi=soft", Flags);
   addMultilibFlag((ARMFloatABI == tools::arm::FloatABI::SoftFP),
-      "mfloat-abi=softfp", Flags);
+                  "-mfloat-abi=softfp", Flags);
   addMultilibFlag((ARMFloatABI == tools::arm::FloatABI::Hard),
-      "mfloat-abi=hard", Flags);
+                  "-mfloat-abi=hard", Flags);
 
   return findOHOSMuslMultilibs(Flags, Result);
 }

diff  --git a/clang/unittests/Driver/MultilibBuilderTest.cpp b/clang/unittests/Driver/MultilibBuilderTest.cpp
index 45ef4992d3f78..d88011cbb794e 100644
--- a/clang/unittests/Driver/MultilibBuilderTest.cpp
+++ b/clang/unittests/Driver/MultilibBuilderTest.cpp
@@ -27,20 +27,22 @@ TEST(MultilibBuilderTest, MultilibValidity) {
 
   ASSERT_TRUE(MultilibBuilder().isValid()) << "Empty multilib is not valid";
 
-  ASSERT_TRUE(MultilibBuilder().flag("+foo").isValid())
+  ASSERT_TRUE(MultilibBuilder().flag(true, "-foo").isValid())
       << "Single indicative flag is not valid";
 
-  ASSERT_TRUE(MultilibBuilder().flag("-foo").isValid())
+  ASSERT_TRUE(MultilibBuilder().flag(false, "-foo").isValid())
       << "Single contraindicative flag is not valid";
 
-  ASSERT_FALSE(MultilibBuilder().flag("+foo").flag("-foo").isValid())
+  ASSERT_FALSE(
+      MultilibBuilder().flag(true, "-foo").flag(false, "-foo").isValid())
       << "Conflicting flags should invalidate the Multilib";
 
-  ASSERT_TRUE(MultilibBuilder().flag("+foo").flag("+foo").isValid())
+  ASSERT_TRUE(MultilibBuilder().flag(true, "-foo").flag(true, "-foo").isValid())
       << "Multilib should be valid even if it has the same flag "
          "twice";
 
-  ASSERT_TRUE(MultilibBuilder().flag("+foo").flag("-foobar").isValid())
+  ASSERT_TRUE(
+      MultilibBuilder().flag(true, "-foo").flag(false, "-foobar").isValid())
       << "Seemingly conflicting prefixes shouldn't actually conflict";
 }
 
@@ -52,7 +54,8 @@ TEST(MultilibBuilderTest, Construction1) {
 }
 
 TEST(MultilibBuilderTest, Construction3) {
-  MultilibBuilder M = MultilibBuilder().flag("+f1").flag("+f2").flag("-f3");
+  MultilibBuilder M =
+      MultilibBuilder().flag(true, "-f1").flag(true, "-f2").flag(false, "-f3");
   for (const std::string &A : M.flags()) {
     ASSERT_TRUE(llvm::StringSwitch<bool>(A)
                     .Cases("+f1", "+f2", "-f3", true)
@@ -63,7 +66,7 @@ TEST(MultilibBuilderTest, Construction3) {
 TEST(MultilibBuilderTest, SetConstruction1) {
   // Single maybe
   MultilibSet MS = MultilibSetBuilder()
-                       .Maybe(MultilibBuilder("64").flag("+m64"))
+                       .Maybe(MultilibBuilder("64").flag(true, "-m64"))
                        .makeMultilibSet();
   ASSERT_TRUE(MS.size() == 2);
   for (MultilibSet::const_iterator I = MS.begin(), E = MS.end(); I != E; ++I) {
@@ -79,8 +82,8 @@ TEST(MultilibBuilderTest, SetConstruction1) {
 TEST(MultilibBuilderTest, SetConstruction2) {
   // Double maybe
   MultilibSet MS = MultilibSetBuilder()
-                       .Maybe(MultilibBuilder("sof").flag("+sof"))
-                       .Maybe(MultilibBuilder("el").flag("+EL"))
+                       .Maybe(MultilibBuilder("sof").flag(true, "-sof"))
+                       .Maybe(MultilibBuilder("el").flag(true, "-EL"))
                        .makeMultilibSet();
   ASSERT_TRUE(MS.size() == 4);
   for (MultilibSet::const_iterator I = MS.begin(), E = MS.end(); I != E; ++I) {
@@ -154,7 +157,7 @@ TEST(MultilibBuilderTest, SetFilterObject) {
 
 TEST(MultilibBuilderTest, SetSelection1) {
   MultilibSet MS1 = MultilibSetBuilder()
-                        .Maybe(MultilibBuilder("64").flag("+m64"))
+                        .Maybe(MultilibBuilder("64").flag(true, "-m64"))
                         .makeMultilibSet();
 
   Multilib::flags_list FlagM64 = {"+m64"};
@@ -174,8 +177,8 @@ TEST(MultilibBuilderTest, SetSelection1) {
 
 TEST(MultilibBuilderTest, SetSelection2) {
   MultilibSet MS2 = MultilibSetBuilder()
-                        .Maybe(MultilibBuilder("el").flag("+EL"))
-                        .Maybe(MultilibBuilder("sf").flag("+SF"))
+                        .Maybe(MultilibBuilder("el").flag(true, "-EL"))
+                        .Maybe(MultilibBuilder("sf").flag(true, "-SF"))
                         .makeMultilibSet();
 
   for (unsigned I = 0; I < 4; ++I) {


        


More information about the cfe-commits mailing list