aboutsummaryrefslogtreecommitdiff
path: root/clang/lib/Driver/Compilation.cpp
diff options
context:
space:
mode:
authorJustin Lebar <jlebar@google.com>2016-02-10 22:17:00 +0000
committerJustin Lebar <jlebar@google.com>2016-02-10 22:17:00 +0000
commit4022d529594dea28ef11ae78c214cf37f139f053 (patch)
tree0e5582c51581d1767d0b4d902159024b4857158d /clang/lib/Driver/Compilation.cpp
parent936db8fa2f20a99596c16e209df37f1c29041844 (diff)
downloadllvm-4022d529594dea28ef11ae78c214cf37f139f053.zip
llvm-4022d529594dea28ef11ae78c214cf37f139f053.tar.gz
llvm-4022d529594dea28ef11ae78c214cf37f139f053.tar.bz2
Bail on compilation as soon as a job fails.
Previously we attempted to be smart; if one job failed, we'd run all jobs that didn't depend on the failing job. Problem is, this doesn't work well for e.g. CUDA compilation without -save-temps. In this case, the device-side and host-side Assemble actions (which actually are responsible for preprocess, compile, backend, and assemble, since we're not saving temps) are necessarily distinct. So our clever heuristic doesn't help us, and we repeat every error message once for host and once for each device arch. The main effect of this change, other than fixing CUDA, is that if you pass multiple cc files to one instance of clang and you get a compile error, we'll stop when the first cc1 job fails. Reviewers: tra, echristo Subscribers: jhen, cfe-commits Differential Revision: http://reviews.llvm.org/D16514 llvm-svn: 260448
Diffstat (limited to 'clang/lib/Driver/Compilation.cpp')
-rw-r--r--clang/lib/Driver/Compilation.cpp38
1 files changed, 8 insertions, 30 deletions
diff --git a/clang/lib/Driver/Compilation.cpp b/clang/lib/Driver/Compilation.cpp
index 1c2eecd..b24d381 100644
--- a/clang/lib/Driver/Compilation.cpp
+++ b/clang/lib/Driver/Compilation.cpp
@@ -163,39 +163,17 @@ int Compilation::ExecuteCommand(const Command &C,
return ExecutionFailed ? 1 : Res;
}
-typedef SmallVectorImpl< std::pair<int, const Command *> > FailingCommandList;
-
-static bool ActionFailed(const Action *A,
- const FailingCommandList &FailingCommands) {
-
- if (FailingCommands.empty())
- return false;
-
- for (FailingCommandList::const_iterator CI = FailingCommands.begin(),
- CE = FailingCommands.end(); CI != CE; ++CI)
- if (A == &(CI->second->getSource()))
- return true;
-
- for (Action::const_iterator AI = A->begin(), AE = A->end(); AI != AE; ++AI)
- if (ActionFailed(*AI, FailingCommands))
- return true;
-
- return false;
-}
-
-static bool InputsOk(const Command &C,
- const FailingCommandList &FailingCommands) {
- return !ActionFailed(&C.getSource(), FailingCommands);
-}
-
-void Compilation::ExecuteJobs(const JobList &Jobs,
- FailingCommandList &FailingCommands) const {
+void Compilation::ExecuteJobs(
+ const JobList &Jobs,
+ SmallVectorImpl<std::pair<int, const Command *>> &FailingCommands) const {
for (const auto &Job : Jobs) {
- if (!InputsOk(Job, FailingCommands))
- continue;
const Command *FailingCommand = nullptr;
- if (int Res = ExecuteCommand(Job, FailingCommand))
+ if (int Res = ExecuteCommand(Job, FailingCommand)) {
FailingCommands.push_back(std::make_pair(Res, FailingCommand));
+ // Bail as soon as one command fails, so we don't output duplicate error
+ // messages if we die on e.g. the same file.
+ return;
+ }
}
}