diff options
author | Hans Wennborg <hans@hanshq.net> | 2013-08-06 22:11:28 +0000 |
---|---|---|
committer | Hans Wennborg <hans@hanshq.net> | 2013-08-06 22:11:28 +0000 |
commit | 2b89a2692cc2862362dbb83e68c46a3e357b0915 (patch) | |
tree | ccd202f41791ad3d701185b5d328493d28f84882 /clang/lib/Driver/Driver.cpp | |
parent | 95866fa7b208b8bff68bc6c2d0f5d0bcbd3a2816 (diff) | |
download | bcm5719-llvm-2b89a2692cc2862362dbb83e68c46a3e357b0915.tar.gz bcm5719-llvm-2b89a2692cc2862362dbb83e68c46a3e357b0915.zip |
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
Diffstat (limited to 'clang/lib/Driver/Driver.cpp')
-rw-r--r-- | clang/lib/Driver/Driver.cpp | 50 |
1 files changed, 48 insertions, 2 deletions
diff --git a/clang/lib/Driver/Driver.cpp b/clang/lib/Driver/Driver.cpp index 84e5fe2cfbb..729b9afe62e 100644 --- a/clang/lib/Driver/Driver.cpp +++ b/clang/lib/Driver/Driver.cpp @@ -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 += "-"; |