[PATCH] clang-cl: Choose executable name base on input name or /Fe

Hans Wennborg hans at chromium.org
Fri Aug 9 15:27:23 PDT 2013


Hi rnk,

This implements support for the /Fe option, and otherwise decides the name for the linked exe file based on the first input filename. Please take a look!

http://llvm-reviews.chandlerc.com/D1344

Files:
  include/clang/Basic/DiagnosticDriverKinds.td
  include/clang/Driver/CLCompatOptions.td
  lib/Driver/Driver.cpp
  test/Driver/cl-Fe.c

Index: include/clang/Basic/DiagnosticDriverKinds.td
===================================================================
--- include/clang/Basic/DiagnosticDriverKinds.td
+++ include/clang/Basic/DiagnosticDriverKinds.td
@@ -135,7 +135,7 @@
   "unknown platform, assuming -mfloat-abi=%0">;
 def warn_ignoring_ftabstop_value : Warning<
   "ignoring invalid -ftabstop value '%0', using default value %1">;
-def warn_drv_overriding_fo_option : Warning<
+def warn_drv_overriding_joined_option : Warning<
   "overriding '%0%1' option with '%2%3'">,
   InGroup<DiagGroup<"overriding-fo-option">>;
 def warn_drv_overriding_t_option : Warning<
Index: include/clang/Driver/CLCompatOptions.td
===================================================================
--- include/clang/Driver/CLCompatOptions.td
+++ include/clang/Driver/CLCompatOptions.td
@@ -90,6 +90,9 @@
 
 // Non-aliases:
 
+def _SLASH_Fe : CLJoined<"Fe">,
+  HelpText<"Set output executable file">,
+  MetaVarName<"<file>">;
 def _SLASH_Fo : CLJoined<"Fo">,
   HelpText<"Set output object file, or directory (ends in / or \\)">,
   MetaVarName<"<file or directory>">;
Index: lib/Driver/Driver.cpp
===================================================================
--- lib/Driver/Driver.cpp
+++ lib/Driver/Driver.cpp
@@ -267,6 +267,26 @@
   return DAL;
 }
 
+/// \brief Check whether there are multiple instances of OptionID in Args, and
+/// if so, issue a diagnostics about it.
+static void DiagnoseOptionOverride(const Driver &D, const DerivedArgList &Args,
+                                   unsigned OptionID) {
+  assert(Args.hasArg(OptionID));
+
+  arg_iterator it = Args.filtered_begin(OptionID);
+  arg_iterator ie = Args.filtered_end();
+  Arg *Previous = *it;
+  ++it;
+
+  while (it != ie) {
+    D.Diag(clang::diag::warn_drv_overriding_joined_option)
+        << Previous->getSpelling() << Previous->getValue()
+        << (*it)->getSpelling() << (*it)->getValue();
+    Previous = *it;
+    ++it;
+  }
+}
+
 Compilation *Driver::BuildCompilation(ArrayRef<const char *> ArgList) {
   llvm::PrettyStackTraceString CrashInfo("Compilation construction");
 
@@ -358,16 +378,7 @@
   BuildInputs(C->getDefaultToolChain(), C->getArgs(), Inputs);
 
   if (Arg *A = C->getArgs().getLastArg(options::OPT__SLASH_Fo)) {
-    // Check for multiple /Fo arguments.
-    for (arg_iterator it = C->getArgs().filtered_begin(options::OPT__SLASH_Fo),
-        ie = C->getArgs().filtered_end(); it != ie; ++it) {
-      if (*it != A) {
-        Diag(clang::diag::warn_drv_overriding_fo_option)
-          << (*it)->getSpelling() << (*it)->getValue()
-          << A->getSpelling() << A->getValue();
-      }
-    }
-
+    DiagnoseOptionOverride(*this, C->getArgs(), options::OPT__SLASH_Fo);
     StringRef V = A->getValue();
     if (V == "") {
       // It has to have a value.
@@ -381,6 +392,16 @@
     }
   }
 
+  if (Arg *A = C->getArgs().getLastArg(options::OPT__SLASH_Fe)) {
+    DiagnoseOptionOverride(*this, C->getArgs(), options::OPT__SLASH_Fe);
+
+    if (A->getValue()[0] == '\0') {
+      // It has to have a value.
+      Diag(clang::diag::err_drv_missing_argument) << A->getSpelling() << 1;
+      C->getArgs().eraseArg(options::OPT__SLASH_Fe);
+    }
+  }
+
   // Construct the list of abstract actions to perform for this compilation. On
   // Darwin target OSes this uses the driver-driver and universal actions.
   if (TC.getTriple().isOSDarwin())
@@ -1625,8 +1646,22 @@
     }
 
     NamedOutput = C.getArgs().MakeArgString(Filename.c_str());
+  } else if (JA.getType() == types::TY_Image &&
+      C.getArgs().hasArg(options::OPT__SLASH_Fe)) {
+    // The /Fe flag names the linked file.
+    const char *V = C.getArgs().getLastArg(options::OPT__SLASH_Fe)->getValue();
+    if (!llvm::sys::path::has_extension(V))
+      V = C.getArgs().MakeArgString(std::string(V) + ".exe");
+    NamedOutput = V;
   } else if (JA.getType() == types::TY_Image) {    
-    if (MultipleArchs && BoundArch) {
+    if (IsCLMode()) {
+      // clang-cl uses BaseName for the executable name.
+      SmallString<128> Filename = BaseName;
+      if (llvm::sys::path::has_extension(Filename.str()))
+        Filename = Filename.substr(0, Filename.rfind("."));
+      Filename.append(".exe");
+      NamedOutput = C.getArgs().MakeArgString(Filename.c_str());
+    } else if (MultipleArchs && BoundArch) {
       SmallString<128> Output(DefaultImageName.c_str());
       Output += "-";
       Output.append(BoundArch);
Index: test/Driver/cl-Fe.c
===================================================================
--- /dev/null
+++ test/Driver/cl-Fe.c
@@ -0,0 +1,22 @@
+// Don't attempt slash switches on msys bash.
+// REQUIRES: shell-preserves-root
+
+// Note: %s must be preceded by --, otherwise it may be interpreted as a
+// command-line option, e.g. on Mac where %s is commonly under /Users.
+
+
+// RUN: %clang_cl -### -- %s 2>&1 | FileCheck -check-prefix=BASENAME %s
+// BASENAME:  cl-Fe.exe
+
+// RUN: %clang_cl /Fefoo -### -- %s 2>&1 | FileCheck -check-prefix=Fe %s
+// Fe: foo.exe
+
+// RUN: %clang_cl /Fefoo /Febar -### -- %s 2>&1 | FileCheck -check-prefix=OVERRIDE %s
+// OVERRIDE:  warning: overriding '/Fefoo' option with '/Febar'
+// OVERRIDE:  bar.exe
+
+// RUN: %clang_cl /Fefoo.ext -### -- %s 2>&1 | FileCheck -check-prefix=FeExt %s
+// FeExt: foo.ext
+
+// RUN: %clang_cl /Fe -### 2>&1 | FileCheck -check-prefix=MISSINGARG %s
+// MISSINGARG: error: argument to '/Fe' is missing (expected 1 value)
-------------- next part --------------
A non-text attachment was scrubbed...
Name: D1344.1.patch
Type: text/x-patch
Size: 5458 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/cfe-commits/attachments/20130809/4124458e/attachment.bin>


More information about the cfe-commits mailing list