When the compiler crashes, the compiler driver now produces diagnostic information 
including the fully preprocessed source file(s) and command line arguments.  The 
developer is asked to attach this diagnostic information to a bug report.

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@135614 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/lib/Driver/Compilation.cpp b/lib/Driver/Compilation.cpp
index 2657faa..b0e46ff 100644
--- a/lib/Driver/Compilation.cpp
+++ b/lib/Driver/Compilation.cpp
@@ -25,7 +25,7 @@
 Compilation::Compilation(const Driver &D, const ToolChain &_DefaultToolChain,
                          InputArgList *_Args, DerivedArgList *_TranslatedArgs)
   : TheDriver(D), DefaultToolChain(_DefaultToolChain), Args(_Args),
-    TranslatedArgs(_TranslatedArgs) {
+    TranslatedArgs(_TranslatedArgs), Redirects(0) {
 }
 
 Compilation::~Compilation() {
@@ -43,6 +43,13 @@
   for (ActionList::iterator it = Actions.begin(), ie = Actions.end();
        it != ie; ++it)
     delete *it;
+
+  // Free redirections of stdout/stderr.
+  if (Redirects) {
+    delete Redirects[1];
+    delete Redirects[2];
+    delete Redirects;
+  }
 }
 
 const DerivedArgList &Compilation::getArgsForToolChain(const ToolChain *TC,
@@ -135,8 +142,8 @@
   std::copy(C.getArguments().begin(), C.getArguments().end(), Argv+1);
   Argv[C.getArguments().size() + 1] = 0;
 
-  if (getDriver().CCCEcho || getDriver().CCPrintOptions ||
-      getArgs().hasArg(options::OPT_v)) {
+  if ((getDriver().CCCEcho || getDriver().CCPrintOptions ||
+       getArgs().hasArg(options::OPT_v)) && !getDriver().CCGenDiagnostics) {
     llvm::raw_ostream *OS = &llvm::errs();
 
     // Follow gcc implementation of CC_PRINT_OPTIONS; we could also cache the
@@ -167,7 +174,7 @@
   std::string Error;
   int Res =
     llvm::sys::Program::ExecuteAndWait(Prog, Argv,
-                                       /*env*/0, /*redirects*/0,
+                                       /*env*/0, Redirects,
                                        /*secondsToWait*/0, /*memoryLimit*/0,
                                        &Error);
   if (!Error.empty()) {
@@ -195,3 +202,27 @@
     return 0;
   }
 }
+
+void Compilation::initCompilationForDiagnostics(void) {
+  // Free actions and jobs, if built.
+  for (ActionList::iterator it = Actions.begin(), ie = Actions.end();
+       it != ie; ++it)
+    delete *it;
+  Actions.clear();
+  Jobs.clear();
+
+  // Clear temporary and results file lists.
+  TempFiles.clear();
+  ResultFiles.clear();
+
+  // Remove any user specified output.  Claim any unclaimed arguments, so as
+  // to avoid emitting warnings about unused args.
+  if (TranslatedArgs->hasArg(options::OPT_o))
+    TranslatedArgs->eraseArg(options::OPT_o);
+  TranslatedArgs->ClaimAllArgs();
+
+  // Redirect stdout/stderr to /dev/null.
+  Redirects = new const llvm::sys::Path*[3]();
+  Redirects[1] = new const llvm::sys::Path();
+  Redirects[2] = new const llvm::sys::Path();
+}