diff options
-rw-r--r-- | clang/include/clang/Basic/DiagnosticDriverKinds.def | 2 | ||||
-rw-r--r-- | clang/include/clang/Basic/DiagnosticDriverKinds.td | 2 | ||||
-rw-r--r-- | clang/include/clang/Driver/Compilation.h | 20 | ||||
-rw-r--r-- | clang/lib/Driver/Compilation.cpp | 48 | ||||
-rw-r--r-- | clang/lib/Driver/Driver.cpp | 2 |
5 files changed, 68 insertions, 6 deletions
diff --git a/clang/include/clang/Basic/DiagnosticDriverKinds.def b/clang/include/clang/Basic/DiagnosticDriverKinds.def index 135b0e1695b..9a5567fd91b 100644 --- a/clang/include/clang/Basic/DiagnosticDriverKinds.def +++ b/clang/include/clang/Basic/DiagnosticDriverKinds.def @@ -32,6 +32,8 @@ DIAG(err_drv_output_argument_with_multiple_files, ERROR, "cannot specify -o when generating multiple output files") DIAG(err_drv_unable_to_make_temp, ERROR, "unable to make temporary file: %0") +DIAG(err_drv_unable_to_remove_file, ERROR, + "unable to remove file: %0") DIAG(warn_drv_input_file_unused, WARNING, "%0: '%1' input file unused when '%2' is present") diff --git a/clang/include/clang/Basic/DiagnosticDriverKinds.td b/clang/include/clang/Basic/DiagnosticDriverKinds.td index fecae53ad83..1bd3047f5ad 100644 --- a/clang/include/clang/Basic/DiagnosticDriverKinds.td +++ b/clang/include/clang/Basic/DiagnosticDriverKinds.td @@ -25,6 +25,8 @@ def err_drv_output_argument_with_multiple_files : Error< "cannot specify -o when generating multiple output files">; def err_drv_unable_to_make_temp : Error< "unable to make temporary file: %0">; +def err_drv_unable_to_remove_file : Error< + "unable to remove file: %0">; def warn_drv_input_file_unused : Warning< "%0: '%1' input file unused when '%2' is present">; diff --git a/clang/include/clang/Driver/Compilation.h b/clang/include/clang/Driver/Compilation.h index 566bc5e0ca5..ec47d030e71 100644 --- a/clang/include/clang/Driver/Compilation.h +++ b/clang/include/clang/Driver/Compilation.h @@ -11,6 +11,7 @@ #define CLANG_DRIVER_COMPILATION_H_ #include "clang/Driver/Job.h" +#include "clang/Driver/Util.h" #include "llvm/ADT/DenseMap.h" #include "llvm/ADT/SmallVector.h" @@ -22,12 +23,16 @@ namespace llvm { namespace clang { namespace driver { class ArgList; + class Driver; class JobList; class ToolChain; /// Compilation - A set of tasks to perform for a single driver /// invocation. class Compilation { + /// The driver we were created by. + Driver &TheDriver; + /// The default tool chain. ToolChain &DefaultToolChain; @@ -44,15 +49,17 @@ class Compilation { llvm::DenseMap<const ToolChain*, ArgList*> TCArgs; /// Temporary files which should be removed on exit. - llvm::SmallVector<const char*, 4> TempFiles; + ArgStringList TempFiles; /// Result files which should be removed on failure. - llvm::SmallVector<const char*, 4> ResultFiles; + ArgStringList ResultFiles; public: - Compilation(ToolChain &DefaultToolChain, ArgList *Args); + Compilation(Driver &D, ToolChain &DefaultToolChain, ArgList *Args); ~Compilation(); + const Driver &getDriver() const { return TheDriver; } + const ToolChain &getDefaultToolChain() const { return DefaultToolChain; } const ArgList &getArgs() const { return *Args; } @@ -86,6 +93,13 @@ public: int Execute() const; private: + /// CleanupFileList - Remove the files in the given list. + /// + /// \param IssueErrors - Report failures as errors. + /// \return Whether all files were removed successfully. + bool CleanupFileList(const ArgStringList &Files, + bool IssueErrors=false) const; + /// PrintJob - Print one job in -### format. /// /// OS - The stream to print on. diff --git a/clang/lib/Driver/Compilation.cpp b/clang/lib/Driver/Compilation.cpp index 364f3281572..0bd573856ea 100644 --- a/clang/lib/Driver/Compilation.cpp +++ b/clang/lib/Driver/Compilation.cpp @@ -11,14 +11,19 @@ #include "clang/Driver/Action.h" #include "clang/Driver/ArgList.h" +#include "clang/Driver/Driver.h" +#include "clang/Driver/DriverDiagnostic.h" #include "clang/Driver/ToolChain.h" #include "llvm/Support/raw_ostream.h" +#include <sys/stat.h> +#include <errno.h> using namespace clang::driver; -Compilation::Compilation(ToolChain &_DefaultToolChain, +Compilation::Compilation(Driver &D, + ToolChain &_DefaultToolChain, ArgList *_Args) - : DefaultToolChain(_DefaultToolChain), Args(_Args) { + : TheDriver(D), DefaultToolChain(_DefaultToolChain), Args(_Args) { } Compilation::~Compilation() { @@ -69,12 +74,51 @@ void Compilation::PrintJob(llvm::raw_ostream &OS, const Job *J, } } +bool Compilation::CleanupFileList(const ArgStringList &Files, + bool IssueErrors) const { + bool Success = true; + + for (ArgStringList::const_iterator + it = Files.begin(), ie = Files.end(); it != ie; ++it) { + llvm::sys::Path P(*it); + std::string Error; + + if (P.eraseFromDisk(false, &Error)) { + // Failure is only failure if the file doesn't exist. There is a + // race condition here due to the limited interface of + // llvm::sys::Path, we want to know if the removal gave E_NOENT. + + // FIXME: Grumble, P.exists() is broken. PR3837. + struct stat buf; + if (::stat(P.c_str(), &buf) || errno != ENOENT) { + if (IssueErrors) + getDriver().Diag(clang::diag::err_drv_unable_to_remove_file) + << Error; + Success = false; + } + } + } + + return Success; +} + int Compilation::Execute() const { // Just print if -### was present. if (getArgs().hasArg(options::OPT__HASH_HASH_HASH)) { PrintJob(llvm::errs(), &Jobs, "\n"); return 0; } + + // FIXME: Execute. + + int Res = 0; + // Remove temp files. + CleanupFileList(TempFiles); + + // If the compilation failed, remove result files as well. + if (Res != 0) + CleanupFileList(ResultFiles, true); + return 0; } diff --git a/clang/lib/Driver/Driver.cpp b/clang/lib/Driver/Driver.cpp index 85debe8bb73..e9e751178da 100644 --- a/clang/lib/Driver/Driver.cpp +++ b/clang/lib/Driver/Driver.cpp @@ -165,7 +165,7 @@ Compilation *Driver::BuildCompilation(int argc, const char **argv) { Host = GetHostInfo(HostTriple); // The compilation takes ownership of Args. - Compilation *C = new Compilation(*Host->getToolChain(*Args), Args); + Compilation *C = new Compilation(*this, *Host->getToolChain(*Args), Args); // FIXME: This behavior shouldn't be here. if (CCCPrintOptions) { |