From: Daniel Dunbar Date: Wed, 18 Mar 2009 22:16:03 +0000 (+0000) Subject: Driver: Cleanup temporary/result files. X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=e530ad407af4a8904377592bfdb236acd320c6c2;p=clang Driver: Cleanup temporary/result files. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@67248 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/include/clang/Basic/DiagnosticDriverKinds.def b/include/clang/Basic/DiagnosticDriverKinds.def index 135b0e1695..9a5567fd91 100644 --- a/include/clang/Basic/DiagnosticDriverKinds.def +++ b/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/include/clang/Basic/DiagnosticDriverKinds.td b/include/clang/Basic/DiagnosticDriverKinds.td index fecae53ad8..1bd3047f5a 100644 --- a/include/clang/Basic/DiagnosticDriverKinds.td +++ b/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/include/clang/Driver/Compilation.h b/include/clang/Driver/Compilation.h index 566bc5e0ca..ec47d030e7 100644 --- a/include/clang/Driver/Compilation.h +++ b/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 TCArgs; /// Temporary files which should be removed on exit. - llvm::SmallVector TempFiles; + ArgStringList TempFiles; /// Result files which should be removed on failure. - llvm::SmallVector 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/lib/Driver/Compilation.cpp b/lib/Driver/Compilation.cpp index 364f328157..0bd573856e 100644 --- a/lib/Driver/Compilation.cpp +++ b/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 +#include 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/lib/Driver/Driver.cpp b/lib/Driver/Driver.cpp index 85debe8bb7..e9e751178d 100644 --- a/lib/Driver/Driver.cpp +++ b/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) {