[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