aboutsummaryrefslogtreecommitdiff
path: root/clang/lib/Driver/Compilation.cpp
diff options
context:
space:
mode:
authorSteven Wu <stevenwu@apple.com>2017-11-10 01:32:47 +0000
committerSteven Wu <stevenwu@apple.com>2017-11-10 01:32:47 +0000
commit9278019eb34f787b92b26d44e1b1a1458b29a29b (patch)
treef2db7de034328acb2bd454714ed5407f559692a8 /clang/lib/Driver/Compilation.cpp
parent07d9f10374332d945011e7f7643823d8de88a0cd (diff)
downloadllvm-9278019eb34f787b92b26d44e1b1a1458b29a29b.zip
llvm-9278019eb34f787b92b26d44e1b1a1458b29a29b.tar.gz
llvm-9278019eb34f787b92b26d44e1b1a1458b29a29b.tar.bz2
[Driver] Make clang/cc conforms to UNIX standard
Summary: This is basically reverting r261774 with a tweak for clang-cl. UNIX standard states: When c99 encounters a compilation error that causes an object file not to be created, it shall write a diagnostic to standard error and continue to compile other source code operands, but it shall not perform the link phase and it shall return a non-zero exit status The same goes for c89 or cc. And they are all alias or shims pointing to clang on Darwin. The original commit was intended for CUDA so the error message doesn't get emit twice for both host and device. It seems that the clang driver has been changed to model the CUDA dependency differently. Now the driver behaves the same without this commit. rdar://problem/32223263 Reviewers: thakis, dexonsmith, tra Reviewed By: tra Subscribers: jlebar, cfe-commits Differential Revision: https://reviews.llvm.org/D39502 llvm-svn: 317860
Diffstat (limited to 'clang/lib/Driver/Compilation.cpp')
-rw-r--r--clang/lib/Driver/Compilation.cpp47
1 files changed, 41 insertions, 6 deletions
diff --git a/clang/lib/Driver/Compilation.cpp b/clang/lib/Driver/Compilation.cpp
index c27ea51..645da50 100644
--- a/clang/lib/Driver/Compilation.cpp
+++ b/clang/lib/Driver/Compilation.cpp
@@ -182,16 +182,51 @@ int Compilation::ExecuteCommand(const Command &C,
return ExecutionFailed ? 1 : Res;
}
-void Compilation::ExecuteJobs(
- const JobList &Jobs,
- SmallVectorImpl<std::pair<int, const Command *>> &FailingCommands) const {
+using FailingCommandList = SmallVectorImpl<std::pair<int, const Command *>>;
+
+static bool ActionFailed(const Action *A,
+ const FailingCommandList &FailingCommands) {
+
+ if (FailingCommands.empty())
+ return false;
+
+ // CUDA can have the same input source code compiled multiple times so do not
+ // compiled again if there are already failures. It is OK to abort the CUDA
+ // pipeline on errors.
+ if (A->isOffloading(Action::OFK_Cuda))
+ return true;
+
+ for (const auto &CI : FailingCommands)
+ if (A == &(CI.second->getSource()))
+ return true;
+
+ for (const Action *AI : A->inputs())
+ 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 {
+ // According to UNIX standard, driver need to continue compiling all the
+ // inputs on the command line even one of them failed.
+ // In all but CLMode, execute all the jobs unless the necessary inputs for the
+ // job is missing due to previous failures.
for (const auto &Job : Jobs) {
+ if (!InputsOk(Job, FailingCommands))
+ continue;
const Command *FailingCommand = nullptr;
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;
+ // Bail as soon as one command fails in cl driver mode.
+ if (TheDriver.IsCLMode())
+ return;
}
}
}