Introduce CIndex API functions for displaying a diagnostic, with some
knobs to control formatting. Eventually, I'd like to merge the
implementation of this code with the TextDiagnosticPrinter, so that
it's easy for CIndex clients to produce beautiful diagnostics like the
clang compiler does.

Use this new function to display diagnostics within c-index-test.


git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@96603 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/tools/c-index-test/c-index-test.c b/tools/c-index-test/c-index-test.c
index b983d3a..99d8b5d 100644
--- a/tools/c-index-test/c-index-test.c
+++ b/tools/c-index-test/c-index-test.c
@@ -198,120 +198,73 @@
 void PrintDiagnostic(CXDiagnostic Diagnostic) {
   FILE *out = stderr;
   CXFile file;
-  unsigned line, column;
   CXString text;
-  enum CXDiagnosticSeverity severity = clang_getDiagnosticSeverity(Diagnostic);
+  unsigned display_opts = CXDiagnostic_DisplaySourceLocation
+    | CXDiagnostic_DisplayColumn | CXDiagnostic_DisplaySourceRanges;
+  unsigned i, num_fixits;
 
-  /* Ignore diagnostics that should be ignored. */
-  if (severity == CXDiagnostic_Ignored)
+  clang_displayDiagnostic(Diagnostic, out, display_opts);
+  if (clang_getDiagnosticSeverity(Diagnostic) == CXDiagnostic_Ignored)
     return;
 
-  /* Print file:line:column. */
   clang_getInstantiationLocation(clang_getDiagnosticLocation(Diagnostic),
-                                 &file, &line, &column, 0);
-  if (file) {
-    unsigned i, n;
-    unsigned printed_any_ranges = 0;
-    CXString fname;
+                                 &file, 0, 0, 0);
+  if (!file)
+    return;
 
-    fname = clang_getFileName(file);
-    fprintf(out, "%s:%d:%d:", clang_getCString(fname), line, column);
-    clang_disposeString(fname);
-
-    n = clang_getDiagnosticNumRanges(Diagnostic);
-    for (i = 0; i != n; ++i) {
-      CXFile start_file, end_file;
-      CXSourceRange range = clang_getDiagnosticRange(Diagnostic, i);
-
-      unsigned start_line, start_column, end_line, end_column;
-      clang_getInstantiationLocation(clang_getRangeStart(range),
-                                     &start_file, &start_line, &start_column,0);
-      clang_getInstantiationLocation(clang_getRangeEnd(range),
-                                     &end_file, &end_line, &end_column, 0);
-
-      if (start_file != end_file || start_file != file)
-        continue;
-
-      PrintExtent(out, start_line, start_column, end_line, end_column);
-      printed_any_ranges = 1;
+  num_fixits = clang_getDiagnosticNumFixIts(Diagnostic);
+  for (i = 0; i != num_fixits; ++i) {
+    switch (clang_getDiagnosticFixItKind(Diagnostic, i)) {
+    case CXFixIt_Insertion: {
+      CXSourceLocation insertion_loc;
+      CXFile insertion_file;
+      unsigned insertion_line, insertion_column;
+      text = clang_getDiagnosticFixItInsertion(Diagnostic, i, &insertion_loc);
+      clang_getInstantiationLocation(insertion_loc, &insertion_file,
+                                     &insertion_line, &insertion_column, 0);
+      if (insertion_file == file)
+        fprintf(out, "FIX-IT: Insert \"%s\" at %d:%d\n",
+                clang_getCString(text), insertion_line, insertion_column);
+      clang_disposeString(text);
+      break;
     }
-    if (printed_any_ranges)
-      fprintf(out, ":");
-
-    fprintf(out, " ");
-  }
-
-  /* Print warning/error/etc. */
-  switch (severity) {
-  case CXDiagnostic_Ignored: assert(0 && "impossible"); break;
-  case CXDiagnostic_Note: fprintf(out, "note: "); break;
-  case CXDiagnostic_Warning: fprintf(out, "warning: "); break;
-  case CXDiagnostic_Error: fprintf(out, "error: "); break;
-  case CXDiagnostic_Fatal: fprintf(out, "fatal error: "); break;
-  }
-
-  text = clang_getDiagnosticSpelling(Diagnostic);
-  if (clang_getCString(text))
-    fprintf(out, "%s\n", clang_getCString(text));
-  else
-    fprintf(out, "<no diagnostic text>\n");
-  clang_disposeString(text);
-
-  if (file) {
-    unsigned i, num_fixits = clang_getDiagnosticNumFixIts(Diagnostic);
-    for (i = 0; i != num_fixits; ++i) {
-      switch (clang_getDiagnosticFixItKind(Diagnostic, i)) {
-      case CXFixIt_Insertion: {
-        CXSourceLocation insertion_loc;
-        CXFile insertion_file;
-        unsigned insertion_line, insertion_column;
-        text = clang_getDiagnosticFixItInsertion(Diagnostic, i, &insertion_loc);
-        clang_getInstantiationLocation(insertion_loc, &insertion_file,
-                                       &insertion_line, &insertion_column, 0);
-        if (insertion_file == file)
-          fprintf(out, "FIX-IT: Insert \"%s\" at %d:%d\n",
-                  clang_getCString(text), insertion_line, insertion_column);
-        clang_disposeString(text);
-        break;
+      
+    case CXFixIt_Removal: {
+      CXFile start_file, end_file;
+      unsigned start_line, start_column, end_line, end_column;
+      CXSourceRange remove_range
+        = clang_getDiagnosticFixItRemoval(Diagnostic, i);
+      clang_getInstantiationLocation(clang_getRangeStart(remove_range),
+                                     &start_file, &start_line, &start_column,
+                                     0);
+      clang_getInstantiationLocation(clang_getRangeEnd(remove_range),
+                                     &end_file, &end_line, &end_column, 0);
+      if (start_file == file && end_file == file) {
+        fprintf(out, "FIX-IT: Remove ");
+        PrintExtent(out, start_line, start_column, end_line, end_column);
+        fprintf(out, "\n");
       }
-
-      case CXFixIt_Removal: {
-        CXFile start_file, end_file;
-        unsigned start_line, start_column, end_line, end_column;
-        CXSourceRange remove_range
-          = clang_getDiagnosticFixItRemoval(Diagnostic, i);
-        clang_getInstantiationLocation(clang_getRangeStart(remove_range),
-                                       &start_file, &start_line, &start_column,
-                                       0);
-        clang_getInstantiationLocation(clang_getRangeEnd(remove_range),
-                                       &end_file, &end_line, &end_column, 0);
-        if (start_file == file && end_file == file) {
-          fprintf(out, "FIX-IT: Remove ");
-          PrintExtent(out, start_line, start_column, end_line, end_column);
-          fprintf(out, "\n");
-        }
-        break;
+      break;
+    }
+      
+    case CXFixIt_Replacement: {
+      CXFile start_file, end_file;
+      unsigned start_line, start_column, end_line, end_column;
+      CXSourceRange remove_range;
+      text = clang_getDiagnosticFixItReplacement(Diagnostic, i,&remove_range);
+      clang_getInstantiationLocation(clang_getRangeStart(remove_range),
+                                     &start_file, &start_line, &start_column,
+                                     0);
+      clang_getInstantiationLocation(clang_getRangeEnd(remove_range),
+                                     &end_file, &end_line, &end_column, 0);
+      if (start_file == end_file) {
+        fprintf(out, "FIX-IT: Replace ");
+        PrintExtent(out, start_line, start_column, end_line, end_column);
+        fprintf(out, " with \"%s\"\n", clang_getCString(text));
       }
-
-      case CXFixIt_Replacement: {
-        CXFile start_file, end_file;
-        unsigned start_line, start_column, end_line, end_column;
-        CXSourceRange remove_range;
-        text = clang_getDiagnosticFixItReplacement(Diagnostic, i,&remove_range);
-        clang_getInstantiationLocation(clang_getRangeStart(remove_range),
-                                       &start_file, &start_line, &start_column,
-                                       0);
-        clang_getInstantiationLocation(clang_getRangeEnd(remove_range),
-                                       &end_file, &end_line, &end_column, 0);
-        if (start_file == end_file) {
-          fprintf(out, "FIX-IT: Replace ");
-          PrintExtent(out, start_line, start_column, end_line, end_column);
-          fprintf(out, " with \"%s\"\n", clang_getCString(text));
-        }
-        clang_disposeString(text);
-        break;
-      }
-      }
+      clang_disposeString(text);
+      break;
+    }
     }
   }
 }