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