Rework how CIndex handles diagnostics. Rather than using a callback,
we attach diagnostics to translation units and code-completion
results, so they can be queried at any time.

To facilitate this, the new StoredDiagnostic class stores a diagnostic
in a serializable/deserializable form, and ASTUnit knows how to
capture diagnostics in this stored form. CIndex's CXDiagnostic is a
thin wrapper around StoredDiagnostic, providing a C interface to
stored or de-serialized diagnostics.

I've XFAIL'd one test case temporarily, because currently we end up
storing diagnostics in an ASTUnit that's never returned to the user
(because it contains errors). I'll introduce a temporary fix for this
soon; the real fix will be to allow us to return and query invalid ASTs.



git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@96592 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/tools/CIndex/CIndex.cpp b/tools/CIndex/CIndex.cpp
index 0b08874..cb81988 100644
--- a/tools/CIndex/CIndex.cpp
+++ b/tools/CIndex/CIndex.cpp
@@ -933,9 +933,7 @@
 }
 
 CXTranslationUnit clang_createTranslationUnit(CXIndex CIdx,
-                                              const char *ast_filename,
-                                             CXDiagnosticCallback diag_callback,
-                                              CXClientData diag_client_data) {
+                                              const char *ast_filename) {
   if (!CIdx)
     return 0;
 
@@ -945,11 +943,9 @@
   DiagnosticOptions DiagOpts;
   llvm::OwningPtr<Diagnostic> Diags;
   Diags.reset(CompilerInstance::createDiagnostics(DiagOpts, 0, 0));
-  CIndexDiagnosticClient DiagClient(diag_callback, diag_client_data);
-  Diags->setClient(&DiagClient);
-
   return ASTUnit::LoadFromPCHFile(ast_filename, *Diags,
-                                  CXXIdx->getOnlyLocalDecls());
+                                  CXXIdx->getOnlyLocalDecls(),
+                                  0, 0, true);
 }
 
 CXTranslationUnit
@@ -958,9 +954,7 @@
                                           int num_command_line_args,
                                           const char **command_line_args,
                                           unsigned num_unsaved_files,
-                                          struct CXUnsavedFile *unsaved_files,
-                                          CXDiagnosticCallback diag_callback,
-                                          CXClientData diag_client_data) {
+                                          struct CXUnsavedFile *unsaved_files) {
   if (!CIdx)
     return 0;
 
@@ -970,8 +964,6 @@
   DiagnosticOptions DiagOpts;
   llvm::OwningPtr<Diagnostic> Diags;
   Diags.reset(CompilerInstance::createDiagnostics(DiagOpts, 0, 0));
-  CIndexDiagnosticClient DiagClient(diag_callback, diag_client_data);
-  Diags->setClient(&DiagClient);
 
   llvm::SmallVector<ASTUnit::RemappedFile, 4> RemappedFiles;
   for (unsigned I = 0; I != num_unsaved_files; ++I) {
@@ -1006,7 +998,8 @@
                                    CXXIdx->getClangResourcesPath(),
                                    CXXIdx->getOnlyLocalDecls(),
                                    RemappedFiles.data(),
-                                   RemappedFiles.size()));
+                                   RemappedFiles.size(),
+                                   /*CaptureDiagnostics=*/true));
 
     // FIXME: Until we have broader testing, just drop the entire AST if we
     // encountered an error.
@@ -1097,20 +1090,22 @@
     Diags->Report(diag::err_fe_clang) << AllArgs << ErrMsg;
   }
 
-  // FIXME: Parse the (redirected) standard error to emit diagnostics.
-
   ASTUnit *ATU = ASTUnit::LoadFromPCHFile(astTmpFile, *Diags,
                                           CXXIdx->getOnlyLocalDecls(),
                                           RemappedFiles.data(),
-                                          RemappedFiles.size());
+                                          RemappedFiles.size(),
+                                          /*CaptureDiagnostics=*/true);
   if (ATU)
     ATU->unlinkTemporaryFile();
 
   // FIXME: Currently we don't report diagnostics on invalid ASTs.
-  if (ATU)
-    ReportSerializedDiagnostics(DiagnosticsFile, *Diags,
-                                num_unsaved_files, unsaved_files,
-                                ATU->getASTContext().getLangOptions());
+  if (ATU) {
+    LoadSerializedDiagnostics(DiagnosticsFile, 
+                              num_unsaved_files, unsaved_files,
+                              ATU->getFileManager(),
+                              ATU->getSourceManager(),
+                              ATU->getDiagnostics());
+  }
 
   for (unsigned i = 0, e = TemporaryFiles.size(); i != e; ++i)
     TemporaryFiles[i].eraseFromDisk();