kito-cheng updated this revision to Diff 331024.
kito-cheng added a comment.

Address jrtc27's and luismarques comment

ChangeLogs

- Move all new test to clang/test/Driver/riscv-toolchain-gcc-multilib.c
  - I don't found good way to test that on windows, since ExecuteAndWait only 
allow to execute .exe file on windows , upload a prebuilt *.exe file and 
execute that sounds like not reasonable.
- Add error message output when execute GCC with non-zero return code, it come 
with a new test.


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D97916

Files:
  clang/include/clang/Basic/DiagnosticDriverKinds.td
  clang/include/clang/Basic/DiagnosticGroups.td
  clang/lib/Driver/ToolChains/Arch/RISCV.cpp
  clang/lib/Driver/ToolChains/Arch/RISCV.h
  clang/lib/Driver/ToolChains/Gnu.cpp
  clang/lib/Driver/ToolChains/Gnu.h
  clang/test/Driver/Inputs/multilib_riscv32_elf_sdk/bin/riscv32-unknown-elf-gcc
  
clang/test/Driver/Inputs/multilib_riscv32_elf_sdk/lib/gcc/riscv32-unknown-elf/8.2.0/crtbegin.o
  
clang/test/Driver/Inputs/multilib_riscv32_elf_sdk/lib/gcc/riscv32-unknown-elf/8.2.0/crtend.o
  
clang/test/Driver/Inputs/multilib_riscv32_elf_sdk/lib/gcc/riscv32-unknown-elf/8.2.0/rv32iac/ilp32/crtbegin.o
  
clang/test/Driver/Inputs/multilib_riscv32_elf_sdk/lib/gcc/riscv32-unknown-elf/8.2.0/rv32iac/ilp32/crtend.o
  
clang/test/Driver/Inputs/multilib_riscv32_elf_sdk/lib/gcc/riscv32-unknown-elf/8.2.0/rv32imafc/ilp32f/crtbegin.o
  
clang/test/Driver/Inputs/multilib_riscv32_elf_sdk/lib/gcc/riscv32-unknown-elf/8.2.0/rv32imafc/ilp32f/crtend.o
  
clang/test/Driver/Inputs/multilib_riscv32_elf_sdk/lib/gcc/riscv32-unknown-elf/8.2.0/rv64imafdc/lp64d/crtbegin.o
  
clang/test/Driver/Inputs/multilib_riscv32_elf_sdk/lib/gcc/riscv32-unknown-elf/8.2.0/rv64imafdc/lp64d/crtend.o
  
clang/test/Driver/Inputs/multilib_riscv32_elf_sdk/riscv32-unknown-elf/lib/crt0.o
  
clang/test/Driver/Inputs/multilib_riscv32_elf_sdk/riscv32-unknown-elf/lib/rv32iac/ilp32/crt0.o
  
clang/test/Driver/Inputs/multilib_riscv32_elf_sdk/riscv32-unknown-elf/lib/rv32imafc/ilp32f/crt0.o
  
clang/test/Driver/Inputs/multilib_riscv32_elf_sdk/riscv32-unknown-elf/lib/rv64imac/lp64/crt0.o
  clang/test/Driver/Inputs/multilib_riscv64_elf_sdk/bin/riscv64-unknown-elf-gcc
  
clang/test/Driver/Inputs/multilib_riscv64_elf_sdk/lib/gcc/riscv64-unknown-elf/8.2.0/crtbegin.o
  
clang/test/Driver/Inputs/multilib_riscv64_elf_sdk/lib/gcc/riscv64-unknown-elf/8.2.0/crtend.o
  
clang/test/Driver/Inputs/multilib_riscv64_elf_sdk/lib/gcc/riscv64-unknown-elf/8.2.0/rv32iac/ilp32/crtbegin.o
  
clang/test/Driver/Inputs/multilib_riscv64_elf_sdk/lib/gcc/riscv64-unknown-elf/8.2.0/rv32iac/ilp32/crtend.o
  
clang/test/Driver/Inputs/multilib_riscv64_elf_sdk/lib/gcc/riscv64-unknown-elf/8.2.0/rv32imafc/ilp32f/crtbegin.o
  
clang/test/Driver/Inputs/multilib_riscv64_elf_sdk/lib/gcc/riscv64-unknown-elf/8.2.0/rv32imafc/ilp32f/crtend.o
  
clang/test/Driver/Inputs/multilib_riscv64_elf_sdk/lib/gcc/riscv64-unknown-elf/8.2.0/rv64imafdc/lp64d/crtbegin.o
  
clang/test/Driver/Inputs/multilib_riscv64_elf_sdk/lib/gcc/riscv64-unknown-elf/8.2.0/rv64imafdc/lp64d/crtend.o
  
clang/test/Driver/Inputs/multilib_riscv64_elf_sdk/riscv64-unknown-elf/lib/crt0.o
  
clang/test/Driver/Inputs/multilib_riscv64_elf_sdk/riscv64-unknown-elf/lib/rv32iac/ilp32/crt0.o
  
clang/test/Driver/Inputs/multilib_riscv64_elf_sdk/riscv64-unknown-elf/lib/rv32imafc/ilp32f/crt0.o
  
clang/test/Driver/Inputs/multilib_riscv64_elf_sdk/riscv64-unknown-elf/lib/rv64imac/lp64/crt0.o
  
clang/test/Driver/Inputs/multilib_riscv64_elf_sdk_bad/bin/riscv64-unknown-elf-gcc
  
clang/test/Driver/Inputs/multilib_riscv64_elf_sdk_bad/lib/gcc/riscv64-unknown-elf/8.2.0/crtbegin.o
  
clang/test/Driver/Inputs/multilib_riscv64_elf_sdk_bad/riscv64-unknown-elf/lib/crt0.o
  
clang/test/Driver/Inputs/multilib_riscv64_elf_sdk_bad2/bin/riscv64-unknown-elf-gcc
  
clang/test/Driver/Inputs/multilib_riscv64_elf_sdk_bad2/lib/gcc/riscv64-unknown-elf/8.2.0/crtbegin.o
  
clang/test/Driver/Inputs/multilib_riscv64_elf_sdk_bad2/riscv64-unknown-elf/lib/crt0.o
  clang/test/Driver/riscv-toolchain-gcc-multilib.c

Index: clang/test/Driver/riscv-toolchain-gcc-multilib.c
===================================================================
--- /dev/null
+++ clang/test/Driver/riscv-toolchain-gcc-multilib.c
@@ -0,0 +1,56 @@
+// Test case for scanning input of GCC output as multilib config
+// Skip this test on Windows, we can't create a dummy GCC to output
+// multilib config, ExecuteAndWait only execute *.exe file.
+// UNSUPPORTED: system-windows
+
+// RUN: %clang %s \
+// RUN:   -target riscv32-unknown-elf \
+// RUN:   --gcc-toolchain=%S/Inputs/multilib_riscv32_elf_sdk \
+// RUN:   --print-multi-lib \
+// RUN:   | FileCheck -check-prefix=C-RV32-GCC-MULTI-LIB %s
+// C-RV32-GCC-MULTI-LIB: rv32iac/ilp32;@march=rv32iac@mabi=ilp32
+// C-RV32-GCC-MULTI-LIB-NEXT: rv32imafc/ilp32f;@march=rv32iac@mabi=ilp32f
+// C-RV32-GCC-MULTI-LIB-NEXT: rv64imafdc/lp64d;@march=rv64imafdc@mabi=lp64d
+// C-RV32-GCC-MULTI-LIB-NOT:  {{^.+$}}
+
+// RUN: %clang %s \
+// RUN:   -### -v \
+// RUN:   -target riscv32-unknown-elf \
+// RUN:   --gcc-toolchain=%S/Inputs/multilib_riscv32_elf_sdk 2>&1 \
+// RUN:   | FileCheck -check-prefix=C-RV32-GCC-MULTI-LIB-V %s
+// C-RV32-GCC-MULTI-LIB-V: Candidate multilib: rv32iac/ilp32;@march=rv32iac@mabi=ilp32
+// C-RV32-GCC-MULTI-LIB-V-NEXT: Candidate multilib: rv32imafc/ilp32f;@march=rv32iac@mabi=ilp32f
+// C-RV32-GCC-MULTI-LIB-V-NEXT: Candidate multilib: rv64imafdc/lp64d;@march=rv64imafdc@mabi=lp64d
+
+// RUN: %clang %s \
+// RUN:   -target riscv64-unknown-elf \
+// RUN:   --gcc-toolchain=%S/Inputs/multilib_riscv64_elf_sdk \
+// RUN:   --print-multi-lib \
+// RUN:   | FileCheck -check-prefix=C-RV64-GCC-MULTI-LIB %s
+// C-RV64-GCC-MULTI-LIB: rv32iac/ilp32;@march=rv32iac@mabi=ilp32
+// C-RV64-GCC-MULTI-LIB-NEXT: rv32imafc/ilp32f;@march=rv32iac@mabi=ilp32f
+// C-RV64-GCC-MULTI-LIB-NEXT: rv64imafdc/lp64d;@march=rv64imafdc@mabi=lp64d
+// C-RV64-GCC-MULTI-LIB-NOT:  {{^.+$}}
+
+// RUN: %clang %s \
+// RUN:   -### -v \
+// RUN:   -target riscv64-unknown-elf \
+// RUN:   --gcc-toolchain=%S/Inputs/multilib_riscv64_elf_sdk 2>&1 \
+// RUN:   | FileCheck -check-prefix=C-RV64-GCC-MULTI-LIB-V %s
+// C-RV64-GCC-MULTI-LIB-V: Candidate multilib: rv32iac/ilp32;@march=rv32iac@mabi=ilp32
+// C-RV64-GCC-MULTI-LIB-V-NEXT: Candidate multilib: rv32imafc/ilp32f;@march=rv32iac@mabi=ilp32f
+// C-RV64-GCC-MULTI-LIB-V-NEXT: Candidate multilib: rv64imafdc/lp64d;@march=rv64imafdc@mabi=lp64d
+
+// RUN: %clang %s \
+// RUN:   -target riscv64-unknown-elf \
+// RUN:   --gcc-toolchain=%S/Inputs/multilib_riscv64_elf_sdk_bad \
+// RUN:   --print-multi-lib 2>&1 \
+// RUN:   | FileCheck -check-prefix=C-RV64-GCC-MULTI-LIB-BAD %s
+// C-RV64-GCC-MULTI-LIB-BAD: warning: xxx option unrecognized in multi-lib configuration when parsing config from GCC, falling back to built-in multi-lib configuration. [-Wmultilib-fallback]
+
+// RUN: %clang %s \
+// RUN:   -### -v \
+// RUN:   -target riscv64-unknown-elf \
+// RUN:   --gcc-toolchain=%S/Inputs/multilib_riscv64_elf_sdk_bad2 2>&1 \
+// RUN:   | FileCheck -check-prefix=C-RV64-GCC-MULTI-LIB-BAD-V %s
+// C-RV64-GCC-MULTI-LIB-BAD-V: Read GCC multilib configureation failed due to non-zero return code
Index: clang/test/Driver/Inputs/multilib_riscv64_elf_sdk_bad2/bin/riscv64-unknown-elf-gcc
===================================================================
--- /dev/null
+++ clang/test/Driver/Inputs/multilib_riscv64_elf_sdk_bad2/bin/riscv64-unknown-elf-gcc
@@ -0,0 +1,4 @@
+#!/usr/bin/env python3
+import sys
+
+sys.exit(1)
Index: clang/test/Driver/Inputs/multilib_riscv64_elf_sdk_bad/bin/riscv64-unknown-elf-gcc
===================================================================
--- /dev/null
+++ clang/test/Driver/Inputs/multilib_riscv64_elf_sdk_bad/bin/riscv64-unknown-elf-gcc
@@ -0,0 +1,5 @@
+#!/usr/bin/env python3
+
+print("rv32iac/ilp32;@march=rv32iac@mabi=ilp32")
+print("rv32imafc/ilp32f;@march=rv32iac@mabi=ilp32f")
+print("rv64imafdc/lp64d;@march=rv64imafdc@mabi=lp64d@xxx")
Index: clang/test/Driver/Inputs/multilib_riscv64_elf_sdk/bin/riscv64-unknown-elf-gcc
===================================================================
--- /dev/null
+++ clang/test/Driver/Inputs/multilib_riscv64_elf_sdk/bin/riscv64-unknown-elf-gcc
@@ -0,0 +1,5 @@
+#!/usr/bin/env python3
+
+print("rv32iac/ilp32;@march=rv32iac@mabi=ilp32")
+print("rv32imafc/ilp32f;@march=rv32iac@mabi=ilp32f")
+print("rv64imafdc/lp64d;@march=rv64imafdc@mabi=lp64d")
Index: clang/test/Driver/Inputs/multilib_riscv32_elf_sdk/bin/riscv32-unknown-elf-gcc
===================================================================
--- /dev/null
+++ clang/test/Driver/Inputs/multilib_riscv32_elf_sdk/bin/riscv32-unknown-elf-gcc
@@ -0,0 +1,5 @@
+#!/usr/bin/env python3
+
+print("rv32iac/ilp32;@march=rv32iac@mabi=ilp32")
+print("rv32imafc/ilp32f;@march=rv32iac@mabi=ilp32f")
+print("rv64imafdc/lp64d;@march=rv64imafdc@mabi=lp64d")
Index: clang/lib/Driver/ToolChains/Gnu.h
===================================================================
--- clang/lib/Driver/ToolChains/Gnu.h
+++ clang/lib/Driver/ToolChains/Gnu.h
@@ -215,6 +215,9 @@
     // Gentoo-specific toolchain configurations are stored here.
     const std::string GentooConfigDir = "/etc/env.d/gcc";
 
+    /// Error message during detect multilib
+    std::string MultilibErrorMessages;
+
   public:
     explicit GCCInstallationDetector(const Driver &D) : IsValid(false), D(D) {}
     void init(const llvm::Triple &TargetTriple, const llvm::opt::ArgList &Args,
Index: clang/lib/Driver/ToolChains/Gnu.cpp
===================================================================
--- clang/lib/Driver/ToolChains/Gnu.cpp
+++ clang/lib/Driver/ToolChains/Gnu.cpp
@@ -25,6 +25,7 @@
 #include "llvm/Option/ArgList.h"
 #include "llvm/Support/CodeGen.h"
 #include "llvm/Support/Path.h"
+#include "llvm/Support/Program.h"
 #include "llvm/Support/TargetParser.h"
 #include "llvm/Support/VirtualFileSystem.h"
 #include <system_error>
@@ -1585,10 +1586,180 @@
   return false;
 }
 
+static std::string findGCCPath(const Driver &D, llvm::StringRef BasePath) {
+  SmallString<128> GCCPath;
+  llvm::sys::path::append(GCCPath, BasePath, "bin",
+                          D.getTargetTriple() + "-gcc");
+
+  if (llvm::sys::fs::exists(GCCPath))
+    return GCCPath.str().str();
+
+  return "";
+}
+
+static std::string getGCCPath(const Driver &D, const ArgList &Args) {
+
+  // Find GCC from -gcc-toolchain if given.
+  if (const Arg *A =
+          Args.getLastArg(clang::driver::options::OPT_gcc_toolchain)) {
+    return findGCCPath(D, A->getValue());
+  } else {
+    // Try to find GCC from GCC_INSTALL_PREFIX if define.
+    llvm::StringRef GCCInstallPrefix = GCC_INSTALL_PREFIX;
+    std::string GCCPath;
+    if (!GCCInstallPrefix.empty())
+      GCCPath = findGCCPath(D, GCCInstallPrefix);
+    else {
+      // Try to find GCC from the same folder as driver.
+      SmallString<128> GCCBasePath;
+      llvm::sys::path::append(GCCBasePath, D.Dir, "..");
+      GCCPath = findGCCPath(D, GCCBasePath);
+    }
+    return GCCPath;
+  }
+}
+
+static bool scanRISCVGCCMultilibConfig(const Driver &D,
+                                       const llvm::Triple &TargetTriple,
+                                       StringRef Path, const ArgList &Args,
+                                       StringRef MultilibOutput,
+                                       DetectedMultilibs &Result) {
+  llvm::StringSet<> AllABI;
+  llvm::StringSet<> AllArch;
+  llvm::StringSet<> AllMCmodel;
+  Multilib::flags_list Flags;
+
+  FilterNonExistent NonExistent(Path, "/crtbegin.o", D.getVFS());
+
+  // Get current ABI, Arch, and code model.
+  StringRef ABIName = tools::riscv::getRISCVABI(Args, TargetTriple);
+  StringRef MArch = tools::riscv::getRISCVArch(Args, TargetTriple);
+  StringRef CodeModel = tools::riscv::getRISCVCodeModel(Args);
+
+  // Turns it into option style, to make it able to compare
+  // to multi-lib option list.
+  std::string CurrentABIOpt = Twine("mabi=", ABIName).str();
+  std::string CurrentArchOpt = Twine("march=", MArch).str();
+  std::string CurrentMCmodelOpt = llvm::StringSwitch<const char *>(CodeModel)
+                                      .Case("medium", "mcmodel=medany")
+                                      .Default("mcmodel=medlow");
+
+  llvm::ErrorOr<std::unique_ptr<llvm::MemoryBuffer>> File =
+      D.getVFS().getBufferForFile(MultilibOutput);
+  std::vector<Multilib> Ms;
+
+  if (!File) {
+    // Ooops, some thing wrong during open file, let's fallback.
+    return false;
+  }
+
+  SmallVector<StringRef, 128> Lines;
+  File.get()->getBuffer().split(Lines, "\n");
+  for (StringRef Line : Lines) {
+    if (Line.trim().empty())
+      continue;
+    // Format for multi-lib:
+    // <path>;@opt1@opt2
+    // For example:
+    // rv32ec/ilp32e;@march=rv32ec@mabi=ilp32e
+    // -march=rv32ec and -mabi=ilp32e using rv32ec/ilp32e.
+    auto MultilibInfo = Line.split(';');
+    StringRef Path = MultilibInfo.first;
+
+    // Skip default multi-lib path.
+    // Clang has implied a default multi-lib rule there,
+    // so we don't need to add it manually.
+    if (Path == ".")
+      continue;
+
+    StringRef Options = MultilibInfo.second.substr(1);
+    SmallVector<StringRef, 2> OptionList;
+    Options.split(OptionList, '@');
+    // multilib path rule is ${march}/${mabi}
+    auto Multilib = makeMultilib(Path);
+    for (StringRef Option : OptionList) {
+      Multilib.flag(Twine("+", Option).str());
+
+      // Gather all used option from multi-lib config.
+      if (Option.startswith("march=")) {
+        if (!AllArch.contains(Option)) {
+          // Make sure every option we only process once
+          AllArch.insert(Option);
+          addMultilibFlag(CurrentArchOpt == Option, Option.str().c_str(),
+                          Flags);
+        }
+      } else if (Option.startswith("mabi=")) {
+        if (!AllABI.contains(Option)) {
+          AllABI.insert(Option);
+          addMultilibFlag(CurrentABIOpt == Option, Option.str().c_str(), Flags);
+        }
+      } else if (Option.startswith("mcmodel=")) {
+        if (!AllMCmodel.contains(Option)) {
+          AllMCmodel.insert(Option);
+          addMultilibFlag(CurrentMCmodelOpt == Option, Option.str().c_str(),
+                          Flags);
+        }
+      } else {
+        // Got unrecognized option in multi-lib config, fallback.
+        D.Diag(diag::warn_drv_multilib_fallback) << Option;
+        return false;
+      }
+    }
+    Ms.emplace_back(Multilib);
+  }
+
+  MultilibSet RISCVMultilibs =
+      MultilibSet().FilterOut(NonExistent).Either(ArrayRef<Multilib>(Ms));
+
+  RISCVMultilibs.select(Flags, Result.SelectedMultilib);
+
+  Result.Multilibs = RISCVMultilibs;
+
+  return true;
+}
+
+static bool getRISCVMultilibFromGCC(const Driver &D,
+                                    const llvm::Triple &TargetTriple,
+                                    StringRef Path, const ArgList &Args,
+                                    DetectedMultilibs &Result,
+                                    std::string &MultilibErrorMessages) {
+  // Try to find where is GCC.
+  std::string GCCPath = getGCCPath(D, Args);
+
+  // Not found? fallback to built-in multi-lib.
+  if (GCCPath.empty())
+    return false;
+
+  // Ask GCC's multi-lib config via --print-multi-lib.
+  StringRef GCCArgs[] = {{GCCPath}, {"--print-multi-lib"}};
+  std::string MultilibOutput = D.GetTemporaryPath("gcc-output-", "");
+  Optional<StringRef> Redirects[] = {None, {MultilibOutput}, {""}};
+
+  int RC = llvm::sys::ExecuteAndWait(GCCPath, GCCArgs, None, Redirects);
+
+  // Any failed happen? let fallback to built-in multi-lib.
+  if (RC != 0) {
+    MultilibErrorMessages = "Read GCC multilib configureation failed due to "
+                            "non-zero return code";
+    return false;
+  }
+
+  // Parsing output of --print-multi-lib, and use that info to determine
+  // which multi-lib should be used.
+  return scanRISCVGCCMultilibConfig(D, TargetTriple, Path, Args, MultilibOutput,
+                                    Result);
+}
+
 static void findRISCVBareMetalMultilibs(const Driver &D,
                                         const llvm::Triple &TargetTriple,
                                         StringRef Path, const ArgList &Args,
-                                        DetectedMultilibs &Result) {
+                                        DetectedMultilibs &Result,
+                                        std::string &MultilibErrorMessages) {
+  // Try to get multilib from GCC first.
+  if (getRISCVMultilibFromGCC(D, TargetTriple, Path, Args, Result,
+                              MultilibErrorMessages))
+    return;
+
   FilterNonExistent NonExistent(Path, "/crtbegin.o", D.getVFS());
   struct RiscvMultilib {
     StringRef march;
@@ -1641,9 +1812,11 @@
 
 static void findRISCVMultilibs(const Driver &D,
                                const llvm::Triple &TargetTriple, StringRef Path,
-                               const ArgList &Args, DetectedMultilibs &Result) {
+                               const ArgList &Args, DetectedMultilibs &Result,
+                               std::string &MultilibErrorMessages) {
   if (TargetTriple.getOS() == llvm::Triple::UnknownOS)
-    return findRISCVBareMetalMultilibs(D, TargetTriple, Path, Args, Result);
+    return findRISCVBareMetalMultilibs(D, TargetTriple, Path, Args, Result,
+                                       MultilibErrorMessages);
 
   FilterNonExistent NonExistent(Path, "/crtbegin.o", D.getVFS());
   Multilib Ilp32 = makeMultilib("lib32/ilp32").flag("+m32").flag("+mabi=ilp32");
@@ -2000,6 +2173,9 @@
   if (!GCCInstallPath.empty())
     OS << "Selected GCC installation: " << GCCInstallPath << "\n";
 
+  if (!MultilibErrorMessages.empty())
+    OS << MultilibErrorMessages << "\n";
+
   for (const auto &Multilib : Multilibs)
     OS << "Candidate multilib: " << Multilib << "\n";
 
@@ -2482,7 +2658,8 @@
     if (!findMIPSMultilibs(D, TargetTriple, Path, Args, Detected))
       return false;
   } else if (TargetTriple.isRISCV()) {
-    findRISCVMultilibs(D, TargetTriple, Path, Args, Detected);
+    findRISCVMultilibs(D, TargetTriple, Path, Args, Detected,
+                       MultilibErrorMessages);
   } else if (isMSP430(TargetArch)) {
     findMSP430Multilibs(D, TargetTriple, Path, Args, Detected);
   } else if (TargetArch == llvm::Triple::avr) {
Index: clang/lib/Driver/ToolChains/Arch/RISCV.h
===================================================================
--- clang/lib/Driver/ToolChains/Arch/RISCV.h
+++ clang/lib/Driver/ToolChains/Arch/RISCV.h
@@ -26,6 +26,7 @@
                       const llvm::Triple &Triple);
 StringRef getRISCVArch(const llvm::opt::ArgList &Args,
                        const llvm::Triple &Triple);
+StringRef getRISCVCodeModel(const llvm::opt::ArgList &Args);
 } // end namespace riscv
 } // namespace tools
 } // end namespace driver
Index: clang/lib/Driver/ToolChains/Arch/RISCV.cpp
===================================================================
--- clang/lib/Driver/ToolChains/Arch/RISCV.cpp
+++ clang/lib/Driver/ToolChains/Arch/RISCV.cpp
@@ -735,3 +735,14 @@
       return "rv64imafdc";
   }
 }
+
+StringRef riscv::getRISCVCodeModel(const llvm::opt::ArgList &Args) {
+  // Default code model is 'small' (what GCC calls 'medlow').
+  StringRef CodeModel;
+  if (const Arg *A = Args.getLastArg(options::OPT_march_EQ))
+    CodeModel = A->getValue();
+  else
+    CodeModel = "small";
+
+  return CodeModel;
+}
Index: clang/include/clang/Basic/DiagnosticGroups.td
===================================================================
--- clang/include/clang/Basic/DiagnosticGroups.td
+++ clang/include/clang/Basic/DiagnosticGroups.td
@@ -767,6 +767,7 @@
 def GNUZeroLineDirective : DiagGroup<"gnu-zero-line-directive">;
 def GNUZeroVariadicMacroArguments : DiagGroup<"gnu-zero-variadic-macro-arguments">;
 def MisleadingIndentation : DiagGroup<"misleading-indentation">;
+def MultilibFallback : DiagGroup<"multilib-fallback">;
 
 // This covers both the deprecated case (in C++98)
 // and the extension case (in C++11 onwards).
Index: clang/include/clang/Basic/DiagnosticDriverKinds.td
===================================================================
--- clang/include/clang/Basic/DiagnosticDriverKinds.td
+++ clang/include/clang/Basic/DiagnosticDriverKinds.td
@@ -390,6 +390,11 @@
   "-ftest-module-file-extension argument '%0' is not of the required form "
   "'blockname:major:minor:hashed:user info'">;
 
+def warn_drv_multilib_fallback : Warning<
+  "%0 option unrecognized in multi-lib configuration when parsing config "
+  "from GCC, falling back to built-in multi-lib configuration.">,
+  InGroup<MultilibFallback>;
+
 def warn_slash_u_filename : Warning<"'/U%0' treated as the '/U' option">,
   InGroup<DiagGroup<"slash-u-filename">>;
 def note_use_dashdash : Note<"Use '--' to treat subsequent arguments as filenames">;
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to