diff options
author | Daniel Dunbar <daniel@zuster.org> | 2009-03-18 22:44:24 +0000 |
---|---|---|
committer | Daniel Dunbar <daniel@zuster.org> | 2009-03-18 22:44:24 +0000 |
commit | 49b98e700e300b8a61b2f7fbb0bb22264e8ec27a (patch) | |
tree | 745e768b6312615212b3dd4ab2a7e236293a6097 | |
parent | 38e24c782c17b6058bf61d635747bbde19fb1bc7 (diff) |
Driver: Execute jobs; no pipe support yet.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@67250 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r-- | include/clang/Basic/DiagnosticDriverKinds.def | 2 | ||||
-rw-r--r-- | include/clang/Basic/DiagnosticDriverKinds.td | 2 | ||||
-rw-r--r-- | include/clang/Driver/Compilation.h | 10 | ||||
-rw-r--r-- | lib/Driver/Compilation.cpp | 70 |
4 files changed, 68 insertions, 16 deletions
diff --git a/include/clang/Basic/DiagnosticDriverKinds.def b/include/clang/Basic/DiagnosticDriverKinds.def index 9a5567fd91..778fdf3186 100644 --- a/include/clang/Basic/DiagnosticDriverKinds.def +++ b/include/clang/Basic/DiagnosticDriverKinds.def @@ -34,6 +34,8 @@ 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(err_drv_command_failure, ERROR, + "unable to execute command: %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 1bd3047f5a..1422cfaac9 100644 --- a/include/clang/Basic/DiagnosticDriverKinds.td +++ b/include/clang/Basic/DiagnosticDriverKinds.td @@ -27,6 +27,8 @@ 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 err_drv_command_failure : Error< + "unable to execute command: %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 ec47d030e7..eaa57914b8 100644 --- a/include/clang/Driver/Compilation.h +++ b/include/clang/Driver/Compilation.h @@ -105,8 +105,14 @@ private: /// OS - The stream to print on. /// J - The job to print. /// Terminator - A string to print at the end of the line. - void PrintJob(llvm::raw_ostream &OS, const Job *J, - const char *Terminator) const; + /// Quote - Should separate arguments be quoted. + void PrintJob(llvm::raw_ostream &OS, const Job &J, + const char *Terminator, bool Quote) const; + + /// ExecuteJob - Execute a single job. + /// + /// \return The accumulated result code of the job. + int ExecuteJob(const Job &J) const; }; } // end namespace driver diff --git a/lib/Driver/Compilation.cpp b/lib/Driver/Compilation.cpp index 0bd573856e..5234165ab5 100644 --- a/lib/Driver/Compilation.cpp +++ b/lib/Driver/Compilation.cpp @@ -16,6 +16,7 @@ #include "clang/Driver/ToolChain.h" #include "llvm/Support/raw_ostream.h" +#include "llvm/System/Program.h" #include <sys/stat.h> #include <errno.h> using namespace clang::driver; @@ -54,23 +55,27 @@ const ArgList &Compilation::getArgsForToolChain(const ToolChain *TC) { return *Entry; } -void Compilation::PrintJob(llvm::raw_ostream &OS, const Job *J, - const char *Terminator) const { - if (const Command *C = dyn_cast<Command>(J)) { +void Compilation::PrintJob(llvm::raw_ostream &OS, const Job &J, + const char *Terminator, bool Quote) const { + if (const Command *C = dyn_cast<Command>(&J)) { OS << " \"" << C->getExecutable() << '"'; for (ArgStringList::const_iterator it = C->getArguments().begin(), - ie = C->getArguments().end(); it != ie; ++it) - OS << " \"" << *it << '"'; + ie = C->getArguments().end(); it != ie; ++it) { + if (Quote) + OS << " \"" << *it << '"'; + else + OS << ' ' << *it; + } OS << Terminator; - } else if (const PipedJob *PJ = dyn_cast<PipedJob>(J)) { + } else if (const PipedJob *PJ = dyn_cast<PipedJob>(&J)) { for (PipedJob::const_iterator it = PJ->begin(), ie = PJ->end(); it != ie; ++it) - PrintJob(OS, *it, (it + 1 != PJ->end()) ? " |\n" : "\n"); + PrintJob(OS, **it, (it + 1 != PJ->end()) ? " |\n" : "\n", Quote); } else { - const JobList *Jobs = cast<JobList>(J); + const JobList *Jobs = cast<JobList>(&J); for (JobList::const_iterator it = Jobs->begin(), ie = Jobs->end(); it != ie; ++it) - PrintJob(OS, *it, Terminator); + PrintJob(OS, **it, Terminator, Quote); } } @@ -90,7 +95,8 @@ bool Compilation::CleanupFileList(const ArgStringList &Files, // FIXME: Grumble, P.exists() is broken. PR3837. struct stat buf; - if (::stat(P.c_str(), &buf) || errno != ENOENT) { + if (::stat(P.c_str(), &buf) == 0 + || errno != ENOENT) { if (IssueErrors) getDriver().Diag(clang::diag::err_drv_unable_to_remove_file) << Error; @@ -102,16 +108,52 @@ bool Compilation::CleanupFileList(const ArgStringList &Files, return Success; } +int Compilation::ExecuteJob(const Job &J) const { + if (const Command *C = dyn_cast<Command>(&J)) { + llvm::sys::Path Prog(C->getExecutable()); + const char **Argv = new const char*[C->getArguments().size() + 2]; + Argv[0] = C->getExecutable(); + std::copy(C->getArguments().begin(), C->getArguments().end(), Argv+1); + Argv[C->getArguments().size() + 1] = 0; + + if (getDriver().CCCEcho || getArgs().hasArg(options::OPT_v)) + PrintJob(llvm::errs(), J, "\n", false); + + std::string Error; + int Res = + llvm::sys::Program::ExecuteAndWait(Prog, Argv, + /*env*/0, /*redirects*/0, + /*secondsToWait*/0, /*memoryLimit*/0, + &Error); + if (!Error.empty()) { + assert(Res && "Error string set with 0 result code!"); + getDriver().Diag(clang::diag::err_drv_command_failure) << Error; + } + + delete[] Argv; + return Res; + } else if (const PipedJob *PJ = dyn_cast<PipedJob>(&J)) { + (void) PJ; + getDriver().Diag(clang::diag::err_drv_unsupported_opt) << "-pipe"; + return 1; + } else { + const JobList *Jobs = cast<JobList>(&J); + for (JobList::const_iterator + it = Jobs->begin(), ie = Jobs->end(); it != ie; ++it) + if (int Res = ExecuteJob(**it)) + return Res; + return 0; + } +} + int Compilation::Execute() const { // Just print if -### was present. if (getArgs().hasArg(options::OPT__HASH_HASH_HASH)) { - PrintJob(llvm::errs(), &Jobs, "\n"); + PrintJob(llvm::errs(), Jobs, "\n", true); return 0; } - // FIXME: Execute. - - int Res = 0; + int Res = ExecuteJob(Jobs); // Remove temp files. CleanupFileList(TempFiles); |