Re-apply my diagnostics-capture patch for CIndex, with some tweaks to
try to address the msvc failures.


git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@96624 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/tools/CIndex/CIndex.cpp b/tools/CIndex/CIndex.cpp
index 61e9210..5eddee4 100644
--- a/tools/CIndex/CIndex.cpp
+++ b/tools/CIndex/CIndex.cpp
@@ -27,6 +27,7 @@
 #include "clang/Lex/Preprocessor.h"
 #include "llvm/Support/MemoryBuffer.h"
 #include "llvm/System/Program.h"
+#include "llvm/System/Signals.h"
 
 // Needed to define L_TMPNAM on some systems.
 #include <cstdio>
@@ -907,10 +908,13 @@
 }
 
 extern "C" {
-CXIndex clang_createIndex(int excludeDeclarationsFromPCH) {
+CXIndex clang_createIndex(int excludeDeclarationsFromPCH,
+                          int displayDiagnostics) {
   CIndexer *CIdxr = new CIndexer();
   if (excludeDeclarationsFromPCH)
     CIdxr->setOnlyLocalDecls();
+  if (displayDiagnostics)
+    CIdxr->setDisplayDiagnostics();
   return CIdxr;
 }
 
@@ -997,8 +1001,18 @@
 
     // FIXME: Until we have broader testing, just drop the entire AST if we
     // encountered an error.
-    if (NumErrors != Diags->getNumErrors())
+    if (NumErrors != Diags->getNumErrors()) {
+      if (CXXIdx->getDisplayDiagnostics()) {
+        for (ASTUnit::diag_iterator D = Unit->diag_begin(), 
+                                 DEnd = Unit->diag_end();
+             D != DEnd; ++D) {
+          CXStoredDiagnostic Diag(*D, Unit->getASTContext().getLangOptions());
+          clang_displayDiagnostic(&Diag, stderr,
+                                  clang_defaultDiagnosticDisplayOptions());
+        }
+      }
       return 0;
+    }
 
     return Unit.take();
   }
@@ -1089,18 +1103,35 @@
                                           RemappedFiles.data(),
                                           RemappedFiles.size(),
                                           /*CaptureDiagnostics=*/true);
-  if (ATU)
-    ATU->unlinkTemporaryFile();
-
-  // FIXME: Currently we don't report diagnostics on invalid ASTs.
   if (ATU) {
     LoadSerializedDiagnostics(DiagnosticsFile, 
                               num_unsaved_files, unsaved_files,
                               ATU->getFileManager(),
                               ATU->getSourceManager(),
                               ATU->getDiagnostics());
+  } else if (CXXIdx->getDisplayDiagnostics()) {
+    // We failed to load the ASTUnit, but we can still deserialize the
+    // diagnostics and emit them.
+    FileManager FileMgr;
+    SourceManager SourceMgr;
+    // FIXME: Faked LangOpts!
+    LangOptions LangOpts;
+    llvm::SmallVector<StoredDiagnostic, 4> Diags;
+    LoadSerializedDiagnostics(DiagnosticsFile, 
+                              num_unsaved_files, unsaved_files,
+                              FileMgr, SourceMgr, Diags);
+    for (llvm::SmallVector<StoredDiagnostic, 4>::iterator D = Diags.begin(), 
+                                                       DEnd = Diags.end();
+         D != DEnd; ++D) {
+      CXStoredDiagnostic Diag(*D, LangOpts);
+      clang_displayDiagnostic(&Diag, stderr,
+                              clang_defaultDiagnosticDisplayOptions());
+    }
   }
 
+  if (ATU)
+    ATU->unlinkTemporaryFile();
+
   for (unsigned i = 0, e = TemporaryFiles.size(); i != e; ++i)
     TemporaryFiles[i].eraseFromDisk();
 
@@ -1909,6 +1940,10 @@
   *endColumn = SM.getSpellingColumnNumber(Body->getRBracLoc());
 }
 
+void clang_enableStackTraces(void) {
+  llvm::sys::PrintStackTraceOnErrorSignal();
+}
+
 } // end: extern "C"
 
 //===----------------------------------------------------------------------===//