diff options
author | Chad Rosier <mcrosier@apple.com> | 2013-01-29 20:15:05 +0000 |
---|---|---|
committer | Chad Rosier <mcrosier@apple.com> | 2013-01-29 20:15:05 +0000 |
commit | a16355c31878403443f99077cc8df8318457faf5 (patch) | |
tree | a09155eff30a4a409d7ef68e7386524c1925af41 /lib/Driver/Driver.cpp | |
parent | d4f2c2e21addd8ed0a50b92f062d3229cde0506a (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.cpp | 75 |
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 { |