forked from OSchip/llvm-project
clang-cl: Implement support for the /Fo option
This implements support for the /Fo option, which is used to set the filename or output dir for object files. Differential Revision: http://llvm-reviews.chandlerc.com/D1302 llvm-svn: 187820
This commit is contained in:
parent
95866fa7b2
commit
2b89a2692c
|
@ -33,6 +33,8 @@ def err_drv_use_of_Z_option : Error<
|
|||
"unsupported use of internal gcc -Z option '%0'">;
|
||||
def err_drv_output_argument_with_multiple_files : Error<
|
||||
"cannot specify -o when generating multiple output files">;
|
||||
def err_drv_obj_file_argument_with_multiple_sources : Error<
|
||||
"cannot specify '%0%1' when compiling multiple source files">;
|
||||
def err_no_external_windows_assembler : Error<
|
||||
"there is no external assembler we can use on windows">;
|
||||
def err_drv_unable_to_remove_file : Error<
|
||||
|
@ -133,6 +135,9 @@ def warn_drv_assuming_mfloat_abi_is : Warning<
|
|||
"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<
|
||||
"overriding '%0%1' option with '%2%3'">,
|
||||
InGroup<DiagGroup<"overriding-fo-option">>;
|
||||
def warn_drv_overriding_t_option : Warning<
|
||||
"overriding '%0' option with '%1'">,
|
||||
InGroup<DiagGroup<"overriding-t-option">>;
|
||||
|
|
|
@ -83,6 +83,9 @@ def _SLASH_Zs : CLFlag<"Zs">, HelpText<"Syntax-check only">,
|
|||
|
||||
// Non-aliases:
|
||||
|
||||
def _SLASH_Fo : CLJoined<"Fo">,
|
||||
HelpText<"Set output object file, or directory (ends in / or \\)">,
|
||||
MetaVarName<"<file or directory>">;
|
||||
def _SLASH_Tc : CLJoinedOrSeparate<"Tc">, HelpText<"Specify a C source file">,
|
||||
MetaVarName<"<filename>">;
|
||||
def _SLASH_TC : CLFlag<"TC">, HelpText<"Treat all source files as C">;
|
||||
|
@ -106,7 +109,6 @@ def _SLASH_Zc_wchar_t : CLIgnoredFlag<"Zc:wchar_t">;
|
|||
|
||||
def _SLASH_EH : CLJoined<"EH">;
|
||||
def _SLASH_Fd : CLJoined<"Fd">;
|
||||
def _SLASH_Fo : CLJoined<"Fo">;
|
||||
def _SLASH_fp : CLJoined<"fp">;
|
||||
def _SLASH_Gd : CLFlag<"Gd">;
|
||||
def _SLASH_GL : CLFlag<"GL">;
|
||||
|
|
|
@ -357,6 +357,30 @@ Compilation *Driver::BuildCompilation(ArrayRef<const char *> ArgList) {
|
|||
InputList Inputs;
|
||||
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();
|
||||
}
|
||||
}
|
||||
|
||||
StringRef V = A->getValue();
|
||||
if (V == "") {
|
||||
// It has to have a value.
|
||||
Diag(clang::diag::err_drv_missing_argument) << A->getSpelling() << 1;
|
||||
C->getArgs().eraseArg(options::OPT__SLASH_Fo);
|
||||
} else if (Inputs.size() > 1 && !llvm::sys::path::is_separator(V.back())) {
|
||||
// Check whether /Fo tries to name an output file for multiple inputs.
|
||||
Diag(clang::diag::err_drv_obj_file_argument_with_multiple_sources)
|
||||
<< A->getSpelling() << V;
|
||||
C->getArgs().eraseArg(options::OPT__SLASH_Fo);
|
||||
}
|
||||
}
|
||||
|
||||
// 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())
|
||||
|
@ -1559,7 +1583,8 @@ const char *Driver::GetNamedOutputPath(Compilation &C,
|
|||
return "-";
|
||||
|
||||
// Output to a temporary file?
|
||||
if ((!AtTopLevel && !C.getArgs().hasArg(options::OPT_save_temps)) ||
|
||||
if ((!AtTopLevel && !C.getArgs().hasArg(options::OPT_save_temps) &&
|
||||
!C.getArgs().hasArg(options::OPT__SLASH_Fo)) ||
|
||||
CCGenDiagnostics) {
|
||||
StringRef Name = llvm::sys::path::filename(BaseInput);
|
||||
std::pair<StringRef, StringRef> Split = Name.split('.');
|
||||
|
@ -1579,7 +1604,28 @@ const char *Driver::GetNamedOutputPath(Compilation &C,
|
|||
|
||||
// Determine what the derived output name should be.
|
||||
const char *NamedOutput;
|
||||
if (JA.getType() == types::TY_Image) {
|
||||
|
||||
if (JA.getType() == types::TY_Object &&
|
||||
C.getArgs().hasArg(options::OPT__SLASH_Fo)) {
|
||||
// The /Fo flag decides the object filename.
|
||||
StringRef Val = C.getArgs().getLastArg(options::OPT__SLASH_Fo)->getValue();
|
||||
SmallString<128> Filename = Val;
|
||||
|
||||
if (llvm::sys::path::is_separator(Val.back())) {
|
||||
// If /Fo names a dir, output to BaseName in that dir.
|
||||
llvm::sys::path::append(Filename, BaseName);
|
||||
}
|
||||
if (!llvm::sys::path::has_extension(Val)) {
|
||||
// If /Fo doesn't provide a filename with an extension, we set it.
|
||||
if (llvm::sys::path::has_extension(Filename.str()))
|
||||
Filename = Filename.substr(0, Filename.rfind("."));
|
||||
Filename.append(".");
|
||||
// FIXME: For clang-cl, we want .obj rather than .o for object files.
|
||||
Filename.append(types::getTypeTempSuffix(types::TY_Object));
|
||||
}
|
||||
|
||||
NamedOutput = C.getArgs().MakeArgString(Filename.c_str());
|
||||
} else if (JA.getType() == types::TY_Image) {
|
||||
if (MultipleArchs && BoundArch) {
|
||||
SmallString<128> Output(DefaultImageName.c_str());
|
||||
Output += "-";
|
||||
|
|
|
@ -0,0 +1,34 @@
|
|||
// 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 /Foa -### -- %s 2>&1 | FileCheck -check-prefix=CHECK-NAME %s
|
||||
// CHECK-NAME: "-o" "a.o"
|
||||
|
||||
// RUN: %clang_cl /Foa.ext /Fob.ext -### -- %s 2>&1 | FileCheck -check-prefix=CHECK-NAMEEXT %s
|
||||
// CHECK-NAMEEXT: warning: overriding '/Foa.ext' option with '/Fob.ext'
|
||||
// CHECK-NAMEEXT: "-o" "b.ext"
|
||||
|
||||
// RUN: %clang_cl /Fofoo.dir/ -### -- %s 2>&1 | FileCheck -check-prefix=CHECK-DIR %s
|
||||
// CHECK-DIR: "-o" "foo.dir{{[/\\]+}}cl-Fo.o"
|
||||
|
||||
// RUN: %clang_cl /Fofoo.dir/a -### -- %s 2>&1 | FileCheck -check-prefix=CHECK-DIRNAME %s
|
||||
// CHECK-DIRNAME: "-o" "foo.dir{{[/\\]+}}a.o"
|
||||
|
||||
// RUN: %clang_cl /Fofoo.dir/a.ext -### -- %s 2>&1 | FileCheck -check-prefix=CHECK-DIRNAMEEXT %s
|
||||
// CHECK-DIRNAMEEXT: "-o" "foo.dir{{[/\\]+}}a.ext"
|
||||
|
||||
// RUN: %clang_cl /Fo.. -### -- %s 2>&1 | FileCheck -check-prefix=CHECK-CRAZY %s
|
||||
// CHECK-CRAZY: "-o" "...o"
|
||||
|
||||
|
||||
// RUN: %clang_cl /Fo -### 2>&1 | FileCheck -check-prefix=CHECK-MISSINGARG %s
|
||||
// CHECK-MISSINGARG: error: argument to '/Fo' is missing (expected 1 value)
|
||||
|
||||
// RUN: %clang_cl /Foa.obj -### -- %s %s 2>&1 | FileCheck -check-prefix=CHECK-MULTIPLESOURCEERROR %s
|
||||
// CHECK-MULTIPLESOURCEERROR: error: cannot specify '/Foa.obj' when compiling multiple source files
|
||||
|
||||
// RUN: %clang_cl /Fomydir/ -### -- %s %s 2>&1 | FileCheck -check-prefix=CHECK-MULTIPLESOURCEOK %s
|
||||
// CHECK-MULTIPLESOURCEOK: "-o" "mydir{{[/\\]+}}cl-Fo.o"
|
|
@ -88,7 +88,7 @@
|
|||
|
||||
// Unsupported but parsed options. Check that we don't error on them.
|
||||
// (/Zs is for syntax-only)
|
||||
// RUN: %clang_cl /Zs /EHsc /Fdfoo /Fobar /fp:precise /Gd /GL /GL- -- %s 2>&1
|
||||
// RUN: %clang_cl /Zs /EHsc /Fdfoo /fp:precise /Gd /GL /GL- -- %s 2>&1
|
||||
// RUN: %clang_cl /Zs /Gm /Gm- /GS /Gy /Gy- /GZ /MD /MT /MDd /MTd /Oi -- %s 2>&1
|
||||
// RUN: %clang_cl /Zs /RTC1 /wfoo /Zc:wchar_t- -- %s 2>&1
|
||||
// RUN: %clang_cl /Zs /ZI /Zi /showIncludes -- %s 2>&1
|
||||
|
|
Loading…
Reference in New Issue