Compilation.cpp revision 49b98e700e300b8a61b2f7fbb0bb22264e8ec27a
13ede8d0a7d1813f678ccc6011a99a0834b1b6116Daniel Dunbar//===--- Compilation.cpp - Compilation Task Implementation --------------*-===// 23ede8d0a7d1813f678ccc6011a99a0834b1b6116Daniel Dunbar// 33ede8d0a7d1813f678ccc6011a99a0834b1b6116Daniel Dunbar// The LLVM Compiler Infrastructure 43ede8d0a7d1813f678ccc6011a99a0834b1b6116Daniel Dunbar// 53ede8d0a7d1813f678ccc6011a99a0834b1b6116Daniel Dunbar// This file is distributed under the University of Illinois Open Source 63ede8d0a7d1813f678ccc6011a99a0834b1b6116Daniel Dunbar// License. See LICENSE.TXT for details. 73ede8d0a7d1813f678ccc6011a99a0834b1b6116Daniel Dunbar// 83ede8d0a7d1813f678ccc6011a99a0834b1b6116Daniel Dunbar//===----------------------------------------------------------------------===// 93ede8d0a7d1813f678ccc6011a99a0834b1b6116Daniel Dunbar 103ede8d0a7d1813f678ccc6011a99a0834b1b6116Daniel Dunbar#include "clang/Driver/Compilation.h" 11586dc233bb88f2920c9f3638f69cef0ccd55dcedDaniel Dunbar 1221549237f14505cfc2a18a06416372a36229d0ceDaniel Dunbar#include "clang/Driver/Action.h" 13586dc233bb88f2920c9f3638f69cef0ccd55dcedDaniel Dunbar#include "clang/Driver/ArgList.h" 14e530ad407af4a8904377592bfdb236acd320c6c2Daniel Dunbar#include "clang/Driver/Driver.h" 15e530ad407af4a8904377592bfdb236acd320c6c2Daniel Dunbar#include "clang/Driver/DriverDiagnostic.h" 16586dc233bb88f2920c9f3638f69cef0ccd55dcedDaniel Dunbar#include "clang/Driver/ToolChain.h" 17586dc233bb88f2920c9f3638f69cef0ccd55dcedDaniel Dunbar 1824b5560b6ea51b8a260194710468fa060775fc01Daniel Dunbar#include "llvm/Support/raw_ostream.h" 1949b98e700e300b8a61b2f7fbb0bb22264e8ec27aDaniel Dunbar#include "llvm/System/Program.h" 20e530ad407af4a8904377592bfdb236acd320c6c2Daniel Dunbar#include <sys/stat.h> 21e530ad407af4a8904377592bfdb236acd320c6c2Daniel Dunbar#include <errno.h> 221b3bb6efc59a21f794b534078f9ae7e95393f510Daniel Dunbarusing namespace clang::driver; 233ede8d0a7d1813f678ccc6011a99a0834b1b6116Daniel Dunbar 24e530ad407af4a8904377592bfdb236acd320c6c2Daniel DunbarCompilation::Compilation(Driver &D, 25e530ad407af4a8904377592bfdb236acd320c6c2Daniel Dunbar ToolChain &_DefaultToolChain, 26586dc233bb88f2920c9f3638f69cef0ccd55dcedDaniel Dunbar ArgList *_Args) 27e530ad407af4a8904377592bfdb236acd320c6c2Daniel Dunbar : TheDriver(D), DefaultToolChain(_DefaultToolChain), Args(_Args) { 28586dc233bb88f2920c9f3638f69cef0ccd55dcedDaniel Dunbar} 29586dc233bb88f2920c9f3638f69cef0ccd55dcedDaniel Dunbar 30586dc233bb88f2920c9f3638f69cef0ccd55dcedDaniel DunbarCompilation::~Compilation() { 31586dc233bb88f2920c9f3638f69cef0ccd55dcedDaniel Dunbar delete Args; 32586dc233bb88f2920c9f3638f69cef0ccd55dcedDaniel Dunbar 33586dc233bb88f2920c9f3638f69cef0ccd55dcedDaniel Dunbar // Free any derived arg lists. 34586dc233bb88f2920c9f3638f69cef0ccd55dcedDaniel Dunbar for (llvm::DenseMap<const ToolChain*, ArgList*>::iterator 35586dc233bb88f2920c9f3638f69cef0ccd55dcedDaniel Dunbar it = TCArgs.begin(), ie = TCArgs.end(); it != ie; ++it) { 36586dc233bb88f2920c9f3638f69cef0ccd55dcedDaniel Dunbar ArgList *A = it->second; 37586dc233bb88f2920c9f3638f69cef0ccd55dcedDaniel Dunbar if (A != Args) 38586dc233bb88f2920c9f3638f69cef0ccd55dcedDaniel Dunbar delete Args; 39586dc233bb88f2920c9f3638f69cef0ccd55dcedDaniel Dunbar } 4021549237f14505cfc2a18a06416372a36229d0ceDaniel Dunbar 4121549237f14505cfc2a18a06416372a36229d0ceDaniel Dunbar // Free the actions, if built. 4221549237f14505cfc2a18a06416372a36229d0ceDaniel Dunbar for (ActionList::iterator it = Actions.begin(), ie = Actions.end(); 4321549237f14505cfc2a18a06416372a36229d0ceDaniel Dunbar it != ie; ++it) 4421549237f14505cfc2a18a06416372a36229d0ceDaniel Dunbar delete *it; 453ede8d0a7d1813f678ccc6011a99a0834b1b6116Daniel Dunbar} 463ede8d0a7d1813f678ccc6011a99a0834b1b6116Daniel Dunbar 47586dc233bb88f2920c9f3638f69cef0ccd55dcedDaniel Dunbarconst ArgList &Compilation::getArgsForToolChain(const ToolChain *TC) { 48586dc233bb88f2920c9f3638f69cef0ccd55dcedDaniel Dunbar if (!TC) 49586dc233bb88f2920c9f3638f69cef0ccd55dcedDaniel Dunbar TC = &DefaultToolChain; 50586dc233bb88f2920c9f3638f69cef0ccd55dcedDaniel Dunbar 51aa3e0d292065fd50713b4c70647063c32d99a36aDaniel Dunbar ArgList *&Entry = TCArgs[TC]; 52aa3e0d292065fd50713b4c70647063c32d99a36aDaniel Dunbar if (!Entry) 53aa3e0d292065fd50713b4c70647063c32d99a36aDaniel Dunbar Entry = TC->TranslateArgs(*Args); 54586dc233bb88f2920c9f3638f69cef0ccd55dcedDaniel Dunbar 55aa3e0d292065fd50713b4c70647063c32d99a36aDaniel Dunbar return *Entry; 563ede8d0a7d1813f678ccc6011a99a0834b1b6116Daniel Dunbar} 573ede8d0a7d1813f678ccc6011a99a0834b1b6116Daniel Dunbar 5849b98e700e300b8a61b2f7fbb0bb22264e8ec27aDaniel Dunbarvoid Compilation::PrintJob(llvm::raw_ostream &OS, const Job &J, 5949b98e700e300b8a61b2f7fbb0bb22264e8ec27aDaniel Dunbar const char *Terminator, bool Quote) const { 6049b98e700e300b8a61b2f7fbb0bb22264e8ec27aDaniel Dunbar if (const Command *C = dyn_cast<Command>(&J)) { 6124b5560b6ea51b8a260194710468fa060775fc01Daniel Dunbar OS << " \"" << C->getExecutable() << '"'; 6224b5560b6ea51b8a260194710468fa060775fc01Daniel Dunbar for (ArgStringList::const_iterator it = C->getArguments().begin(), 6349b98e700e300b8a61b2f7fbb0bb22264e8ec27aDaniel Dunbar ie = C->getArguments().end(); it != ie; ++it) { 6449b98e700e300b8a61b2f7fbb0bb22264e8ec27aDaniel Dunbar if (Quote) 6549b98e700e300b8a61b2f7fbb0bb22264e8ec27aDaniel Dunbar OS << " \"" << *it << '"'; 6649b98e700e300b8a61b2f7fbb0bb22264e8ec27aDaniel Dunbar else 6749b98e700e300b8a61b2f7fbb0bb22264e8ec27aDaniel Dunbar OS << ' ' << *it; 6849b98e700e300b8a61b2f7fbb0bb22264e8ec27aDaniel Dunbar } 6924b5560b6ea51b8a260194710468fa060775fc01Daniel Dunbar OS << Terminator; 7049b98e700e300b8a61b2f7fbb0bb22264e8ec27aDaniel Dunbar } else if (const PipedJob *PJ = dyn_cast<PipedJob>(&J)) { 7124b5560b6ea51b8a260194710468fa060775fc01Daniel Dunbar for (PipedJob::const_iterator 7224b5560b6ea51b8a260194710468fa060775fc01Daniel Dunbar it = PJ->begin(), ie = PJ->end(); it != ie; ++it) 7349b98e700e300b8a61b2f7fbb0bb22264e8ec27aDaniel Dunbar PrintJob(OS, **it, (it + 1 != PJ->end()) ? " |\n" : "\n", Quote); 7424b5560b6ea51b8a260194710468fa060775fc01Daniel Dunbar } else { 7549b98e700e300b8a61b2f7fbb0bb22264e8ec27aDaniel Dunbar const JobList *Jobs = cast<JobList>(&J); 7624b5560b6ea51b8a260194710468fa060775fc01Daniel Dunbar for (JobList::const_iterator 7724b5560b6ea51b8a260194710468fa060775fc01Daniel Dunbar it = Jobs->begin(), ie = Jobs->end(); it != ie; ++it) 7849b98e700e300b8a61b2f7fbb0bb22264e8ec27aDaniel Dunbar PrintJob(OS, **it, Terminator, Quote); 7924b5560b6ea51b8a260194710468fa060775fc01Daniel Dunbar } 8024b5560b6ea51b8a260194710468fa060775fc01Daniel Dunbar} 8124b5560b6ea51b8a260194710468fa060775fc01Daniel Dunbar 82e530ad407af4a8904377592bfdb236acd320c6c2Daniel Dunbarbool Compilation::CleanupFileList(const ArgStringList &Files, 83e530ad407af4a8904377592bfdb236acd320c6c2Daniel Dunbar bool IssueErrors) const { 84e530ad407af4a8904377592bfdb236acd320c6c2Daniel Dunbar bool Success = true; 85e530ad407af4a8904377592bfdb236acd320c6c2Daniel Dunbar 86e530ad407af4a8904377592bfdb236acd320c6c2Daniel Dunbar for (ArgStringList::const_iterator 87e530ad407af4a8904377592bfdb236acd320c6c2Daniel Dunbar it = Files.begin(), ie = Files.end(); it != ie; ++it) { 88e530ad407af4a8904377592bfdb236acd320c6c2Daniel Dunbar llvm::sys::Path P(*it); 89e530ad407af4a8904377592bfdb236acd320c6c2Daniel Dunbar std::string Error; 90e530ad407af4a8904377592bfdb236acd320c6c2Daniel Dunbar 91e530ad407af4a8904377592bfdb236acd320c6c2Daniel Dunbar if (P.eraseFromDisk(false, &Error)) { 92e530ad407af4a8904377592bfdb236acd320c6c2Daniel Dunbar // Failure is only failure if the file doesn't exist. There is a 93e530ad407af4a8904377592bfdb236acd320c6c2Daniel Dunbar // race condition here due to the limited interface of 94e530ad407af4a8904377592bfdb236acd320c6c2Daniel Dunbar // llvm::sys::Path, we want to know if the removal gave E_NOENT. 95e530ad407af4a8904377592bfdb236acd320c6c2Daniel Dunbar 96e530ad407af4a8904377592bfdb236acd320c6c2Daniel Dunbar // FIXME: Grumble, P.exists() is broken. PR3837. 97e530ad407af4a8904377592bfdb236acd320c6c2Daniel Dunbar struct stat buf; 9849b98e700e300b8a61b2f7fbb0bb22264e8ec27aDaniel Dunbar if (::stat(P.c_str(), &buf) == 0 9949b98e700e300b8a61b2f7fbb0bb22264e8ec27aDaniel Dunbar || errno != ENOENT) { 100e530ad407af4a8904377592bfdb236acd320c6c2Daniel Dunbar if (IssueErrors) 101e530ad407af4a8904377592bfdb236acd320c6c2Daniel Dunbar getDriver().Diag(clang::diag::err_drv_unable_to_remove_file) 102e530ad407af4a8904377592bfdb236acd320c6c2Daniel Dunbar << Error; 103e530ad407af4a8904377592bfdb236acd320c6c2Daniel Dunbar Success = false; 104e530ad407af4a8904377592bfdb236acd320c6c2Daniel Dunbar } 105e530ad407af4a8904377592bfdb236acd320c6c2Daniel Dunbar } 106e530ad407af4a8904377592bfdb236acd320c6c2Daniel Dunbar } 107e530ad407af4a8904377592bfdb236acd320c6c2Daniel Dunbar 108e530ad407af4a8904377592bfdb236acd320c6c2Daniel Dunbar return Success; 109e530ad407af4a8904377592bfdb236acd320c6c2Daniel Dunbar} 110e530ad407af4a8904377592bfdb236acd320c6c2Daniel Dunbar 11149b98e700e300b8a61b2f7fbb0bb22264e8ec27aDaniel Dunbarint Compilation::ExecuteJob(const Job &J) const { 11249b98e700e300b8a61b2f7fbb0bb22264e8ec27aDaniel Dunbar if (const Command *C = dyn_cast<Command>(&J)) { 11349b98e700e300b8a61b2f7fbb0bb22264e8ec27aDaniel Dunbar llvm::sys::Path Prog(C->getExecutable()); 11449b98e700e300b8a61b2f7fbb0bb22264e8ec27aDaniel Dunbar const char **Argv = new const char*[C->getArguments().size() + 2]; 11549b98e700e300b8a61b2f7fbb0bb22264e8ec27aDaniel Dunbar Argv[0] = C->getExecutable(); 11649b98e700e300b8a61b2f7fbb0bb22264e8ec27aDaniel Dunbar std::copy(C->getArguments().begin(), C->getArguments().end(), Argv+1); 11749b98e700e300b8a61b2f7fbb0bb22264e8ec27aDaniel Dunbar Argv[C->getArguments().size() + 1] = 0; 11849b98e700e300b8a61b2f7fbb0bb22264e8ec27aDaniel Dunbar 11949b98e700e300b8a61b2f7fbb0bb22264e8ec27aDaniel Dunbar if (getDriver().CCCEcho || getArgs().hasArg(options::OPT_v)) 12049b98e700e300b8a61b2f7fbb0bb22264e8ec27aDaniel Dunbar PrintJob(llvm::errs(), J, "\n", false); 12149b98e700e300b8a61b2f7fbb0bb22264e8ec27aDaniel Dunbar 12249b98e700e300b8a61b2f7fbb0bb22264e8ec27aDaniel Dunbar std::string Error; 12349b98e700e300b8a61b2f7fbb0bb22264e8ec27aDaniel Dunbar int Res = 12449b98e700e300b8a61b2f7fbb0bb22264e8ec27aDaniel Dunbar llvm::sys::Program::ExecuteAndWait(Prog, Argv, 12549b98e700e300b8a61b2f7fbb0bb22264e8ec27aDaniel Dunbar /*env*/0, /*redirects*/0, 12649b98e700e300b8a61b2f7fbb0bb22264e8ec27aDaniel Dunbar /*secondsToWait*/0, /*memoryLimit*/0, 12749b98e700e300b8a61b2f7fbb0bb22264e8ec27aDaniel Dunbar &Error); 12849b98e700e300b8a61b2f7fbb0bb22264e8ec27aDaniel Dunbar if (!Error.empty()) { 12949b98e700e300b8a61b2f7fbb0bb22264e8ec27aDaniel Dunbar assert(Res && "Error string set with 0 result code!"); 13049b98e700e300b8a61b2f7fbb0bb22264e8ec27aDaniel Dunbar getDriver().Diag(clang::diag::err_drv_command_failure) << Error; 13149b98e700e300b8a61b2f7fbb0bb22264e8ec27aDaniel Dunbar } 13249b98e700e300b8a61b2f7fbb0bb22264e8ec27aDaniel Dunbar 13349b98e700e300b8a61b2f7fbb0bb22264e8ec27aDaniel Dunbar delete[] Argv; 13449b98e700e300b8a61b2f7fbb0bb22264e8ec27aDaniel Dunbar return Res; 13549b98e700e300b8a61b2f7fbb0bb22264e8ec27aDaniel Dunbar } else if (const PipedJob *PJ = dyn_cast<PipedJob>(&J)) { 13649b98e700e300b8a61b2f7fbb0bb22264e8ec27aDaniel Dunbar (void) PJ; 13749b98e700e300b8a61b2f7fbb0bb22264e8ec27aDaniel Dunbar getDriver().Diag(clang::diag::err_drv_unsupported_opt) << "-pipe"; 13849b98e700e300b8a61b2f7fbb0bb22264e8ec27aDaniel Dunbar return 1; 13949b98e700e300b8a61b2f7fbb0bb22264e8ec27aDaniel Dunbar } else { 14049b98e700e300b8a61b2f7fbb0bb22264e8ec27aDaniel Dunbar const JobList *Jobs = cast<JobList>(&J); 14149b98e700e300b8a61b2f7fbb0bb22264e8ec27aDaniel Dunbar for (JobList::const_iterator 14249b98e700e300b8a61b2f7fbb0bb22264e8ec27aDaniel Dunbar it = Jobs->begin(), ie = Jobs->end(); it != ie; ++it) 14349b98e700e300b8a61b2f7fbb0bb22264e8ec27aDaniel Dunbar if (int Res = ExecuteJob(**it)) 14449b98e700e300b8a61b2f7fbb0bb22264e8ec27aDaniel Dunbar return Res; 14549b98e700e300b8a61b2f7fbb0bb22264e8ec27aDaniel Dunbar return 0; 14649b98e700e300b8a61b2f7fbb0bb22264e8ec27aDaniel Dunbar } 14749b98e700e300b8a61b2f7fbb0bb22264e8ec27aDaniel Dunbar} 14849b98e700e300b8a61b2f7fbb0bb22264e8ec27aDaniel Dunbar 1493ede8d0a7d1813f678ccc6011a99a0834b1b6116Daniel Dunbarint Compilation::Execute() const { 15024b5560b6ea51b8a260194710468fa060775fc01Daniel Dunbar // Just print if -### was present. 15124b5560b6ea51b8a260194710468fa060775fc01Daniel Dunbar if (getArgs().hasArg(options::OPT__HASH_HASH_HASH)) { 15249b98e700e300b8a61b2f7fbb0bb22264e8ec27aDaniel Dunbar PrintJob(llvm::errs(), Jobs, "\n", true); 15324b5560b6ea51b8a260194710468fa060775fc01Daniel Dunbar return 0; 15424b5560b6ea51b8a260194710468fa060775fc01Daniel Dunbar } 155e530ad407af4a8904377592bfdb236acd320c6c2Daniel Dunbar 15649b98e700e300b8a61b2f7fbb0bb22264e8ec27aDaniel Dunbar int Res = ExecuteJob(Jobs); 15724b5560b6ea51b8a260194710468fa060775fc01Daniel Dunbar 158e530ad407af4a8904377592bfdb236acd320c6c2Daniel Dunbar // Remove temp files. 159e530ad407af4a8904377592bfdb236acd320c6c2Daniel Dunbar CleanupFileList(TempFiles); 160e530ad407af4a8904377592bfdb236acd320c6c2Daniel Dunbar 161e530ad407af4a8904377592bfdb236acd320c6c2Daniel Dunbar // If the compilation failed, remove result files as well. 162e530ad407af4a8904377592bfdb236acd320c6c2Daniel Dunbar if (Res != 0) 163e530ad407af4a8904377592bfdb236acd320c6c2Daniel Dunbar CleanupFileList(ResultFiles, true); 164e530ad407af4a8904377592bfdb236acd320c6c2Daniel Dunbar 1653ede8d0a7d1813f678ccc6011a99a0834b1b6116Daniel Dunbar return 0; 1663ede8d0a7d1813f678ccc6011a99a0834b1b6116Daniel Dunbar} 167