[cfe-commits] r96603 - in /cfe/trunk: include/clang-c/Index.h test/Index/code-complete-errors.c tools/CIndex/CIndex.exports tools/CIndex/CIndexDiagnostic.cpp tools/c-index-test/c-index-test.c

Douglas Gregor dgregor at apple.com
Thu Feb 18 11:08:21 PST 2010


Author: dgregor
Date: Thu Feb 18 13:08:21 2010
New Revision: 96603

URL: http://llvm.org/viewvc/llvm-project?rev=96603&view=rev
Log:
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.

Modified:
    cfe/trunk/include/clang-c/Index.h
    cfe/trunk/test/Index/code-complete-errors.c
    cfe/trunk/tools/CIndex/CIndex.exports
    cfe/trunk/tools/CIndex/CIndexDiagnostic.cpp
    cfe/trunk/tools/c-index-test/c-index-test.c

Modified: cfe/trunk/include/clang-c/Index.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang-c/Index.h?rev=96603&r1=96602&r2=96603&view=diff

==============================================================================
--- cfe/trunk/include/clang-c/Index.h (original)
+++ cfe/trunk/include/clang-c/Index.h Thu Feb 18 13:08:21 2010
@@ -18,6 +18,7 @@
 
 #include <sys/stat.h>
 #include <time.h>
+#include <stdio.h>
 
 #ifdef __cplusplus
 extern "C" {
@@ -439,6 +440,79 @@
 CINDEX_LINKAGE void clang_disposeDiagnostic(CXDiagnostic Diagnostic);
 
 /**
+ * \brief Options to control the display of diagnostics.
+ *
+ * The values in this enum are meant to be combined to customize the
+ * behavior of \c clang_displayDiagnostic().
+ */
+enum CXDiagnosticDisplayOptions {
+  /**
+   * \brief Display the source-location information where the
+   * diagnostic was located.
+   *
+   * When set, diagnostics will be prefixed by the file, line, and
+   * (optionally) column to which the diagnostic refers. For example,
+   *
+   * \code
+   * test.c:28: warning: extra tokens at end of #endif directive
+   * \endcode
+   *
+   * This option corresponds to the clang flag \c -fshow-source-location.
+   */
+  CXDiagnostic_DisplaySourceLocation = 0x01,
+
+  /**
+   * \brief If displaying the source-location information of the
+   * diagnostic, also include the column number.
+   *
+   * This option corresponds to the clang flag \c -fshow-column.
+   */
+  CXDiagnostic_DisplayColumn = 0x02,
+
+  /**
+   * \brief If displaying the source-location information of the
+   * diagnostic, also include information about source ranges in a
+   * machine-parsable format.
+   *
+   * This option corresponds to the clang flag 
+   * \c -fdiagnostics-print-source-range-info.
+   */
+  CXDiagnostic_DisplaySourceRanges = 0x04
+};
+
+/**
+ * \brief Display the given diagnostic by printing it to the given file.
+ *
+ * This routine will display the given diagnostic to a file, rendering
+ * the diagnostic according to the various options given. The 
+ * \c clang_defaultDiagnosticDisplayOptions() function returns the set of 
+ * options that most closely mimics the behavior of the clang compiler.
+ *
+ * \param Diagnostic The diagnostic to print.
+ *
+ * \param File The file to print to (e.g., \c stderr).
+ *
+ * \param Options A set of options that control the diagnostic display, 
+ * created by combining \c CXDiagnosticDisplayOptions values.
+ */
+CINDEX_LINKAGE void clang_displayDiagnostic(CXDiagnostic Diagnostic,
+                                            FILE *File,
+                                            unsigned Options);
+
+/**
+ * \brief Retrieve the set of display options most similar to the
+ * default behavior of the clang compiler.
+ *
+ * \returns A set of display options suitable for use with \c
+ * clang_displayDiagnostic().
+ */
+CINDEX_LINKAGE unsigned clang_defaultDiagnosticDisplayOptions();
+
+/**
+ * \brief Print a diagnostic to the given file.
+ */
+
+/**
  * \brief Determine the severity of the given diagnostic.
  */
 CINDEX_LINKAGE enum CXDiagnosticSeverity 

Modified: cfe/trunk/test/Index/code-complete-errors.c
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Index/code-complete-errors.c?rev=96603&r1=96602&r2=96603&view=diff

==============================================================================
--- cfe/trunk/test/Index/code-complete-errors.c (original)
+++ cfe/trunk/test/Index/code-complete-errors.c Thu Feb 18 13:08:21 2010
@@ -7,7 +7,7 @@
 struct s s0 = { y: 5 }; // CHECK: code-complete-errors.c:7:20: warning: use of GNU old-style field designator extension
 // CHECK: FIX-IT: Replace [7:17 - 7:19] with ".y = "
 int f(int *ptr1, float *ptr2) {
-  return ptr1 != ptr2; // CHECK: code-complete-errors.c:10:15:[10:10 - 10:14][10:18 - 10:22]: warning: comparison of distinct pointer types ('int *' and 'float *')
+  return ptr1 != ptr2; // CHECK: code-complete-errors.c:10:15:{10:10-10:14}{10:18-10:22}: warning: comparison of distinct pointer types ('int *' and 'float *')
 }
 
 void g() {  }

Modified: cfe/trunk/tools/CIndex/CIndex.exports
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/tools/CIndex/CIndex.exports?rev=96603&r1=96602&r2=96603&view=diff

==============================================================================
--- cfe/trunk/tools/CIndex/CIndex.exports (original)
+++ cfe/trunk/tools/CIndex/CIndex.exports Thu Feb 18 13:08:21 2010
@@ -5,6 +5,8 @@
 _clang_createIndex
 _clang_createTranslationUnit
 _clang_createTranslationUnitFromSourceFile
+_clang_defaultDiagnosticDisplayOptions
+_clang_displayDiagnostic
 _clang_disposeCodeCompleteResults
 _clang_disposeDiagnostic
 _clang_disposeIndex

Modified: cfe/trunk/tools/CIndex/CIndexDiagnostic.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/tools/CIndex/CIndexDiagnostic.cpp?rev=96603&r1=96602&r2=96603&view=diff

==============================================================================
--- cfe/trunk/tools/CIndex/CIndexDiagnostic.cpp (original)
+++ cfe/trunk/tools/CIndex/CIndexDiagnostic.cpp Thu Feb 18 13:08:21 2010
@@ -47,6 +47,81 @@
   delete Stored;
 }
 
+void clang_displayDiagnostic(CXDiagnostic Diagnostic, FILE *Out, 
+                             unsigned Options) {
+  if (!Diagnostic || !Out)
+    return;
+
+  CXDiagnosticSeverity Severity = clang_getDiagnosticSeverity(Diagnostic);
+
+  // Ignore diagnostics that should be ignored.
+  if (Severity == CXDiagnostic_Ignored)
+    return;
+
+  if (Options & CXDiagnostic_DisplaySourceLocation) {
+    // Print source location (file:line), along with optional column
+    // and source ranges.
+    CXFile File;
+    unsigned Line, Column;
+    clang_getInstantiationLocation(clang_getDiagnosticLocation(Diagnostic),
+                                   &File, &Line, &Column, 0);
+    if (File) {
+      CXString FName = clang_getFileName(File);
+      fprintf(Out, "%s:%d:", clang_getCString(FName), Line);
+      clang_disposeString(FName);
+      if (Options & CXDiagnostic_DisplayColumn)
+        fprintf(Out, "%d:", Column);
+
+      if (Options & CXDiagnostic_DisplaySourceRanges) {
+        unsigned N = clang_getDiagnosticNumRanges(Diagnostic);
+        bool PrintedRange = false;
+        for (unsigned I = 0; I != N; ++I) {
+          CXFile StartFile, EndFile;
+          CXSourceRange Range = clang_getDiagnosticRange(Diagnostic, I);
+          
+          unsigned StartLine, StartColumn, EndLine, EndColumn;
+          clang_getInstantiationLocation(clang_getRangeStart(Range),
+                                         &StartFile, &StartLine, &StartColumn,
+                                         0);
+          clang_getInstantiationLocation(clang_getRangeEnd(Range),
+                                         &EndFile, &EndLine, &EndColumn, 0);
+          
+          if (StartFile != EndFile || StartFile != File)
+            continue;
+          
+          fprintf(Out, "{%d:%d-%d:%d}", StartLine, StartColumn, 
+                  EndLine, EndColumn);
+          PrintedRange = true;
+        }
+        if (PrintedRange)
+          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;
+  }
+
+  CXString 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);
+}
+
+unsigned clang_defaultDiagnosticDisplayOptions() {
+  return CXDiagnostic_DisplaySourceLocation | CXDiagnostic_DisplayColumn;
+}
+
 enum CXDiagnosticSeverity clang_getDiagnosticSeverity(CXDiagnostic Diag) {
   CXStoredDiagnostic *StoredDiag = static_cast<CXStoredDiagnostic *>(Diag);
   if (!StoredDiag)

Modified: cfe/trunk/tools/c-index-test/c-index-test.c
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/tools/c-index-test/c-index-test.c?rev=96603&r1=96602&r2=96603&view=diff

==============================================================================
--- cfe/trunk/tools/c-index-test/c-index-test.c (original)
+++ cfe/trunk/tools/c-index-test/c-index-test.c Thu Feb 18 13:08:21 2010
@@ -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;
-
-    fname = clang_getFileName(file);
-    fprintf(out, "%s:%d:%d:", clang_getCString(fname), line, column);
-    clang_disposeString(fname);
+                                 &file, 0, 0, 0);
+  if (!file)
+    return;
 
-    n = clang_getDiagnosticNumRanges(Diagnostic);
-    for (i = 0; i != n; ++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;
-      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),
+      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 != end_file || start_file != file)
-        continue;
-
-      PrintExtent(out, start_line, start_column, end_line, end_column);
-      printed_any_ranges = 1;
-    }
-    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");
-        }
-        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));
-        }
-        clang_disposeString(text);
-        break;
+      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;
+    }
+      
+    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;
+    }
     }
   }
 }





More information about the cfe-commits mailing list