aboutsummaryrefslogtreecommitdiff
path: root/lib/Driver/Driver.cpp
diff options
context:
space:
mode:
authorChad Rosier <mcrosier@apple.com>2013-01-29 20:15:05 +0000
committerChad Rosier <mcrosier@apple.com>2013-01-29 20:15:05 +0000
commita16355c31878403443f99077cc8df8318457faf5 (patch)
treea09155eff30a4a409d7ef68e7386524c1925af41 /lib/Driver/Driver.cpp
parentd4f2c2e21addd8ed0a50b92f062d3229cde0506a (diff)
[driver] Refactor the driver so that a failing commands doesn't prevent
subsequent commands from being executed. The diagnostics generation isn't designed for this use case, so add a note to fix this in the very near future. For now, just generated the diagnostics for the first failing command. Part of rdar://12984531 git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@173825 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Driver/Driver.cpp')
-rw-r--r--lib/Driver/Driver.cpp75
1 files changed, 41 insertions, 34 deletions
diff --git a/lib/Driver/Driver.cpp b/lib/Driver/Driver.cpp
index c97b3786b3..0ba61a3de8 100644
--- a/lib/Driver/Driver.cpp
+++ b/lib/Driver/Driver.cpp
@@ -440,11 +440,11 @@ void Driver::generateCompilationDiagnostics(Compilation &C,
}
// Generate preprocessed output.
- FailingCommand = 0;
- int Res = C.ExecuteJob(C.getJobs(), FailingCommand);
+ SmallVector<std::pair<int, const Command *>, 4> FailingCommands;
+ C.ExecuteJob(C.getJobs(), FailingCommands);
// If the command succeeded, we are done.
- if (Res == 0) {
+ if (FailingCommands.empty()) {
Diag(clang::diag::note_drv_command_failed_diag_msg)
<< "\n********************\n\n"
"PLEASE ATTACH THE FOLLOWING FILES TO THE BUG REPORT:\n"
@@ -495,7 +495,7 @@ void Driver::generateCompilationDiagnostics(Compilation &C,
}
int Driver::ExecuteCompilation(const Compilation &C,
- const Command *&FailingCommand) const {
+ SmallVectorImpl< std::pair<int, const Command *> > &FailingCommands) const {
// Just print if -### was present.
if (C.getArgs().hasArg(options::OPT__HASH_HASH_HASH)) {
C.PrintJob(llvm::errs(), C.getJobs(), "\n", true);
@@ -506,45 +506,52 @@ int Driver::ExecuteCompilation(const Compilation &C,
if (Diags.hasErrorOccurred())
return 1;
- int Res = C.ExecuteJob(C.getJobs(), FailingCommand);
+ C.ExecuteJob(C.getJobs(), FailingCommands);
// Remove temp files.
C.CleanupFileList(C.getTempFiles());
// If the command succeeded, we are done.
- if (Res == 0)
- return Res;
+ if (FailingCommands.empty())
+ return 0;
- // Otherwise, remove result files as well.
- if (!C.getArgs().hasArg(options::OPT_save_temps)) {
- const JobAction *JA = cast<JobAction>(&FailingCommand->getSource());
- C.CleanupFileMap(C.getResultFiles(), JA, true);
+ // Otherwise, remove result files and print extra information about abnormal
+ // failures.
+ for (SmallVectorImpl< std::pair<int, const Command *> >::iterator it =
+ FailingCommands.begin(), ie = FailingCommands.end(); it != ie; ++it) {
+ int Res = it->first;
+ const Command *FailingCommand = it->second;
- // Failure result files are valid unless we crashed.
- if (Res < 0)
- C.CleanupFileMap(C.getFailureResultFiles(), JA, true);
- }
+ // Remove result files if we're not saving temps.
+ if (!C.getArgs().hasArg(options::OPT_save_temps)) {
+ const JobAction *JA = cast<JobAction>(&FailingCommand->getSource());
+ C.CleanupFileMap(C.getResultFiles(), JA, true);
- // Print extra information about abnormal failures, if possible.
- //
- // This is ad-hoc, but we don't want to be excessively noisy. If the result
- // status was 1, assume the command failed normally. In particular, if it was
- // the compiler then assume it gave a reasonable error code. Failures in other
- // tools are less common, and they generally have worse diagnostics, so always
- // print the diagnostic there.
- const Tool &FailingTool = FailingCommand->getCreator();
-
- if (!FailingCommand->getCreator().hasGoodDiagnostics() || Res != 1) {
- // FIXME: See FIXME above regarding result code interpretation.
- if (Res < 0)
- Diag(clang::diag::err_drv_command_signalled)
- << FailingTool.getShortName();
- else
- Diag(clang::diag::err_drv_command_failed)
- << FailingTool.getShortName() << Res;
- }
+ // Failure result files are valid unless we crashed.
+ if (Res < 0)
+ C.CleanupFileMap(C.getFailureResultFiles(), JA, true);
+ }
- return Res;
+ // Print extra information about abnormal failures, if possible.
+ //
+ // This is ad-hoc, but we don't want to be excessively noisy. If the result
+ // status was 1, assume the command failed normally. In particular, if it
+ // was the compiler then assume it gave a reasonable error code. Failures
+ // in other tools are less common, and they generally have worse
+ // diagnostics, so always print the diagnostic there.
+ const Tool &FailingTool = FailingCommand->getCreator();
+
+ if (!FailingCommand->getCreator().hasGoodDiagnostics() || Res != 1) {
+ // FIXME: See FIXME above regarding result code interpretation.
+ if (Res < 0)
+ Diag(clang::diag::err_drv_command_signalled)
+ << FailingTool.getShortName();
+ else
+ Diag(clang::diag::err_drv_command_failed)
+ << FailingTool.getShortName() << Res;
+ }
+ }
+ return 0;
}
void Driver::PrintOptions(const ArgList &Args) const {