1 //===--- Compilation.cpp - Compilation Task Implementation --------------*-===//
3 // The LLVM Compiler Infrastructure
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
8 //===----------------------------------------------------------------------===//
10 #include "clang/Driver/Compilation.h"
12 #include "clang/Driver/Action.h"
13 #include "clang/Driver/ArgList.h"
14 #include "clang/Driver/Driver.h"
15 #include "clang/Driver/DriverDiagnostic.h"
16 #include "clang/Driver/ToolChain.h"
18 #include "llvm/Support/raw_ostream.h"
19 #include "llvm/System/Program.h"
22 using namespace clang::driver
;
24 Compilation::Compilation(const Driver
&D
,
25 const ToolChain
&_DefaultToolChain
,
27 : TheDriver(D
), DefaultToolChain(_DefaultToolChain
), Args(_Args
) {
30 Compilation::~Compilation() {
33 // Free any derived arg lists.
34 for (llvm::DenseMap
<const ToolChain
*, DerivedArgList
*>::iterator
35 it
= TCArgs
.begin(), ie
= TCArgs
.end(); it
!= ie
; ++it
)
38 // Free the actions, if built.
39 for (ActionList::iterator it
= Actions
.begin(), ie
= Actions
.end();
44 const DerivedArgList
&Compilation::getArgsForToolChain(const ToolChain
*TC
) {
46 TC
= &DefaultToolChain
;
48 DerivedArgList
*&Entry
= TCArgs
[TC
];
50 Entry
= TC
->TranslateArgs(*Args
);
55 void Compilation::PrintJob(llvm::raw_ostream
&OS
, const Job
&J
,
56 const char *Terminator
, bool Quote
) const {
57 if (const Command
*C
= dyn_cast
<Command
>(&J
)) {
58 OS
<< " \"" << C
->getExecutable() << '"';
59 for (ArgStringList::const_iterator it
= C
->getArguments().begin(),
60 ie
= C
->getArguments().end(); it
!= ie
; ++it
) {
62 OS
<< " \"" << *it
<< '"';
67 } else if (const PipedJob
*PJ
= dyn_cast
<PipedJob
>(&J
)) {
68 for (PipedJob::const_iterator
69 it
= PJ
->begin(), ie
= PJ
->end(); it
!= ie
; ++it
)
70 PrintJob(OS
, **it
, (it
+ 1 != PJ
->end()) ? " |\n" : "\n", Quote
);
72 const JobList
*Jobs
= cast
<JobList
>(&J
);
73 for (JobList::const_iterator
74 it
= Jobs
->begin(), ie
= Jobs
->end(); it
!= ie
; ++it
)
75 PrintJob(OS
, **it
, Terminator
, Quote
);
79 bool Compilation::CleanupFileList(const ArgStringList
&Files
,
80 bool IssueErrors
) const {
83 for (ArgStringList::const_iterator
84 it
= Files
.begin(), ie
= Files
.end(); it
!= ie
; ++it
) {
85 llvm::sys::Path
P(*it
);
88 if (P
.eraseFromDisk(false, &Error
)) {
89 // Failure is only failure if the file doesn't exist. There is a
90 // race condition here due to the limited interface of
91 // llvm::sys::Path, we want to know if the removal gave E_NOENT.
93 // FIXME: Grumble, P.exists() is broken. PR3837.
95 if (::stat(P
.c_str(), &buf
) == 0
98 getDriver().Diag(clang::diag::err_drv_unable_to_remove_file
)
108 int Compilation::ExecuteCommand(const Command
&C
,
109 const Command
*&FailingCommand
) const {
110 llvm::sys::Path
Prog(C
.getExecutable());
111 const char **Argv
= new const char*[C
.getArguments().size() + 2];
112 Argv
[0] = C
.getExecutable();
113 std::copy(C
.getArguments().begin(), C
.getArguments().end(), Argv
+1);
114 Argv
[C
.getArguments().size() + 1] = 0;
116 if (getDriver().CCCEcho
|| getArgs().hasArg(options::OPT_v
))
117 PrintJob(llvm::errs(), C
, "\n", false);
121 llvm::sys::Program::ExecuteAndWait(Prog
, Argv
,
122 /*env*/0, /*redirects*/0,
123 /*secondsToWait*/0, /*memoryLimit*/0,
125 if (!Error
.empty()) {
126 assert(Res
&& "Error string set with 0 result code!");
127 getDriver().Diag(clang::diag::err_drv_command_failure
) << Error
;
137 int Compilation::ExecuteJob(const Job
&J
,
138 const Command
*&FailingCommand
) const {
139 if (const Command
*C
= dyn_cast
<Command
>(&J
)) {
140 return ExecuteCommand(*C
, FailingCommand
);
141 } else if (const PipedJob
*PJ
= dyn_cast
<PipedJob
>(&J
)) {
142 // Piped commands with a single job are easy.
144 return ExecuteCommand(**PJ
->begin(), FailingCommand
);
146 FailingCommand
= *PJ
->begin();
147 getDriver().Diag(clang::diag::err_drv_unsupported_opt
) << "-pipe";
150 const JobList
*Jobs
= cast
<JobList
>(&J
);
151 for (JobList::const_iterator
152 it
= Jobs
->begin(), ie
= Jobs
->end(); it
!= ie
; ++it
)
153 if (int Res
= ExecuteJob(**it
, FailingCommand
))