[cfe-commits] r96624 - in /cfe/trunk: include/clang-c/Index.h lib/Basic/Diagnostic.cpp test/Index/cindex-on-invalid.m test/Index/code-complete-errors.c tools/CIndex/CIndex.cpp tools/CIndex/CIndex.exports tools/CIndex/CIndexCodeCompletion.cpp tools/CIndex/CIndexDiagnostic.cpp tools/CIndex/CIndexer.h tools/c-index-test/c-index-test.c

Douglas Gregor dgregor at apple.com
Thu Feb 18 15:07:20 PST 2010


Author: dgregor
Date: Thu Feb 18 17:07:20 2010
New Revision: 96624

URL: http://llvm.org/viewvc/llvm-project?rev=96624&view=rev
Log:
Re-apply my diagnostics-capture patch for CIndex, with some tweaks to
try to address the msvc failures.

Modified:
    cfe/trunk/include/clang-c/Index.h
    cfe/trunk/lib/Basic/Diagnostic.cpp
    cfe/trunk/test/Index/cindex-on-invalid.m
    cfe/trunk/test/Index/code-complete-errors.c
    cfe/trunk/tools/CIndex/CIndex.cpp
    cfe/trunk/tools/CIndex/CIndex.exports
    cfe/trunk/tools/CIndex/CIndexCodeCompletion.cpp
    cfe/trunk/tools/CIndex/CIndexDiagnostic.cpp
    cfe/trunk/tools/CIndex/CIndexer.h
    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=96624&r1=96623&r2=96624&view=diff

==============================================================================
--- cfe/trunk/include/clang-c/Index.h (original)
+++ cfe/trunk/include/clang-c/Index.h Thu Feb 18 17:07:20 2010
@@ -18,6 +18,7 @@
 
 #include <sys/stat.h>
 #include <time.h>
+#include <stdio.h>
 
 #ifdef __cplusplus
 extern "C" {
@@ -145,8 +146,8 @@
  *
  * Here is an example:
  *
- *   // excludeDeclsFromPCH = 1
- *   Idx = clang_createIndex(1);
+ *   // excludeDeclsFromPCH = 1, displayDiagnostics=1
+ *   Idx = clang_createIndex(1, 1);
  *
  *   // IndexTest.pch was produced with the following command:
  *   // "clang -x c IndexTest.h -emit-ast -o IndexTest.pch"
@@ -170,7 +171,8 @@
  * -include-pch) allows 'excludeDeclsFromPCH' to remove redundant callbacks
  * (which gives the indexer the same performance benefit as the compiler).
  */
-CINDEX_LINKAGE CXIndex clang_createIndex(int excludeDeclarationsFromPCH);
+CINDEX_LINKAGE CXIndex clang_createIndex(int excludeDeclarationsFromPCH,
+                                         int displayDiagnostics);
   
 /**
  * \brief Destroy the given index.
@@ -439,6 +441,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(void);
+
+/**
+ * \brief Print a diagnostic to the given file.
+ */
+
+/**
  * \brief Determine the severity of the given diagnostic.
  */
 CINDEX_LINKAGE enum CXDiagnosticSeverity 
@@ -1247,7 +1322,7 @@
                                           unsigned *startColumn,
                                           unsigned *endLine,
                                           unsigned *endColumn);
-
+CINDEX_LINKAGE void clang_enableStackTraces(void);
 /**
  * @}
  */

Modified: cfe/trunk/lib/Basic/Diagnostic.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Basic/Diagnostic.cpp?rev=96624&r1=96623&r2=96624&view=diff

==============================================================================
--- cfe/trunk/lib/Basic/Diagnostic.cpp (original)
+++ cfe/trunk/lib/Basic/Diagnostic.cpp Thu Feb 18 17:07:20 2010
@@ -923,7 +923,7 @@
 
 StoredDiagnostic::StoredDiagnostic(Diagnostic::Level Level, 
                                    llvm::StringRef Message)
-  : Level(Level), Message(Message) { }
+  : Level(Level), Loc(), Message(Message) { }
 
 StoredDiagnostic::StoredDiagnostic(Diagnostic::Level Level, 
                                    const DiagnosticInfo &Info)

Modified: cfe/trunk/test/Index/cindex-on-invalid.m
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Index/cindex-on-invalid.m?rev=96624&r1=96623&r2=96624&view=diff

==============================================================================
--- cfe/trunk/test/Index/cindex-on-invalid.m (original)
+++ cfe/trunk/test/Index/cindex-on-invalid.m Thu Feb 18 17:07:20 2010
@@ -1,6 +1,5 @@
 // RUN: not c-index-test -test-load-source local %s > %t 2> %t.err
 // RUN: FileCheck %s < %t.err
-// XFAIL: *
 
 // CHECK: error: expected identifier or '('
 // CHECK: Unable to load translation unit!

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=96624&r1=96623&r2=96624&view=diff

==============================================================================
--- cfe/trunk/test/Index/code-complete-errors.c (original)
+++ cfe/trunk/test/Index/code-complete-errors.c Thu Feb 18 17:07:20 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.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/tools/CIndex/CIndex.cpp?rev=96624&r1=96623&r2=96624&view=diff

==============================================================================
--- cfe/trunk/tools/CIndex/CIndex.cpp (original)
+++ cfe/trunk/tools/CIndex/CIndex.cpp Thu Feb 18 17:07:20 2010
@@ -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"
 
 //===----------------------------------------------------------------------===//

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

==============================================================================
--- cfe/trunk/tools/CIndex/CIndex.exports (original)
+++ cfe/trunk/tools/CIndex/CIndex.exports Thu Feb 18 17:07:20 2010
@@ -5,12 +5,15 @@
 _clang_createIndex
 _clang_createTranslationUnit
 _clang_createTranslationUnitFromSourceFile
+_clang_defaultDiagnosticDisplayOptions
+_clang_displayDiagnostic
 _clang_disposeCodeCompleteResults
 _clang_disposeDiagnostic
 _clang_disposeIndex
 _clang_disposeString
 _clang_disposeTokens
 _clang_disposeTranslationUnit
+_clang_enableStackTraces
 _clang_equalCursors
 _clang_equalLocations
 _clang_getClangVersion

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

==============================================================================
--- cfe/trunk/tools/CIndex/CIndexCodeCompletion.cpp (original)
+++ cfe/trunk/tools/CIndex/CIndexCodeCompletion.cpp Thu Feb 18 17:07:20 2010
@@ -177,6 +177,9 @@
 /// \brief The CXCodeCompleteResults structure we allocate internally;
 /// the client only sees the initial CXCodeCompleteResults structure.
 struct AllocatedCXCodeCompleteResults : public CXCodeCompleteResults {
+  AllocatedCXCodeCompleteResults();
+  ~AllocatedCXCodeCompleteResults();
+  
   /// \brief The memory buffer from which we parsed the results. We
   /// retain this buffer because the completion strings point into it.
   llvm::MemoryBuffer *Buffer;
@@ -194,6 +197,16 @@
   FileManager FileMgr;
 };
 
+AllocatedCXCodeCompleteResults::AllocatedCXCodeCompleteResults() 
+  : CXCodeCompleteResults(), Buffer(0) { }
+  
+AllocatedCXCodeCompleteResults::~AllocatedCXCodeCompleteResults() {
+  for (unsigned I = 0, N = NumResults; I != N; ++I)
+    delete (CodeCompletionString *)Results[I].CompletionString;
+  delete [] Results;
+  delete Buffer;
+}
+  
 CXCodeCompleteResults *clang_codeComplete(CXIndex CIdx,
                                           const char *source_filename,
                                           int num_command_line_args,
@@ -368,15 +381,6 @@
 
   AllocatedCXCodeCompleteResults *Results
     = static_cast<AllocatedCXCodeCompleteResults*>(ResultsIn);
-
-  for (unsigned I = 0, N = Results->NumResults; I != N; ++I)
-    delete (CXCompletionString *)Results->Results[I].CompletionString;
-  delete [] Results->Results;
-
-  Results->Results = 0;
-  Results->NumResults = 0;
-  delete Results->Buffer;
-  Results->Buffer = 0;
   delete Results;
 }
 

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

==============================================================================
--- cfe/trunk/tools/CIndex/CIndexDiagnostic.cpp (original)
+++ cfe/trunk/tools/CIndex/CIndexDiagnostic.cpp Thu Feb 18 17:07:20 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)
@@ -204,15 +279,18 @@
       Diags.push_back(StoredDiagnostic(Diagnostic::Fatal,
                             (Twine("could not remap from missing file ") +
                                    unsaved_files[I].Filename).str()));
+      delete F;
       return;
     }
 
     MemoryBuffer *Buffer
       = MemoryBuffer::getMemBuffer(unsaved_files[I].Contents,
                            unsaved_files[I].Contents + unsaved_files[I].Length);
-    if (!Buffer)
+    if (!Buffer) {
+      delete F;
       return;
-
+    }
+    
     SourceMgr.overrideFileContents(File, Buffer);
   }
 
@@ -224,8 +302,9 @@
     StoredDiagnostic Stored = StoredDiagnostic::Deserialize(FileMgr, SourceMgr,
                                                             Memory, MemoryEnd);
     if (!Stored)
-      return;
+      break;
 
     Diags.push_back(Stored);
   }
+  delete F;
 }

Modified: cfe/trunk/tools/CIndex/CIndexer.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/tools/CIndex/CIndexer.h?rev=96624&r1=96623&r2=96624&view=diff

==============================================================================
--- cfe/trunk/tools/CIndex/CIndexer.h (original)
+++ cfe/trunk/tools/CIndex/CIndexer.h Thu Feb 18 17:07:20 2010
@@ -34,11 +34,14 @@
 class CIndexer {
   bool UseExternalASTGeneration;
   bool OnlyLocalDecls;
-  
+  bool DisplayDiagnostics;
+
   llvm::sys::Path ClangPath;
   
 public:
-  CIndexer() : UseExternalASTGeneration(false), OnlyLocalDecls(false) { }
+ CIndexer() 
+   : UseExternalASTGeneration(false), OnlyLocalDecls(false),
+     DisplayDiagnostics(false) { }
   
   /// \brief Whether we only want to see "local" declarations (that did not
   /// come from a previous precompiled header). If false, we want to see all
@@ -46,6 +49,11 @@
   bool getOnlyLocalDecls() const { return OnlyLocalDecls; }
   void setOnlyLocalDecls(bool Local = true) { OnlyLocalDecls = Local; }
   
+  bool getDisplayDiagnostics() const { return DisplayDiagnostics; }
+  void setDisplayDiagnostics(bool Display = true) {
+    DisplayDiagnostics = Display;
+  }
+
   bool getUseExternalASTGeneration() const { return UseExternalASTGeneration; }
   void setUseExternalASTGeneration(bool Value) {
     UseExternalASTGeneration = Value;

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=96624&r1=96623&r2=96624&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 17:07:20 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;
+    }
     }
   }
 }
@@ -534,7 +487,8 @@
   CXTranslationUnit TU;
   int result;
   Idx = clang_createIndex(/* excludeDeclsFromPCH */
-                          !strcmp(filter, "local") ? 1 : 0);
+                          !strcmp(filter, "local") ? 1 : 0,
+                          /* displayDiagnosics=*/1);
 
   if (!CreateTranslationUnit(Idx, file, &TU)) {
     clang_disposeIndex(Idx);
@@ -558,7 +512,8 @@
   int result;
 
   Idx = clang_createIndex(/* excludeDeclsFromPCH */
-                          !strcmp(filter, "local") ? 1 : 0);
+                          !strcmp(filter, "local") ? 1 : 0,
+                          /* displayDiagnosics=*/1);
 
   if (UseExternalASTs && strlen(UseExternalASTs))
     clang_setUseExternalASTGeneration(Idx, 1);
@@ -612,7 +567,8 @@
   unsigned line = 1, col = 1;
   unsigned start_line = 1, start_col = 1;
 
-  if (!(Idx = clang_createIndex(/* excludeDeclsFromPCH */ 1))) {
+  if (!(Idx = clang_createIndex(/* excludeDeclsFromPCH */ 1,
+                                /* displayDiagnosics=*/1))) {
     fprintf(stderr, "Could not create Index\n");
     return 1;
   }
@@ -813,7 +769,7 @@
   if (parse_remapped_files(argc, argv, 2, &unsaved_files, &num_unsaved_files))
     return -1;
 
-  CIdx = clang_createIndex(0);
+  CIdx = clang_createIndex(0, 1);
   results = clang_codeComplete(CIdx,
                                argv[argc - 1], argc - num_unsaved_files - 3,
                                argv + num_unsaved_files + 2,
@@ -877,7 +833,7 @@
                            &num_unsaved_files))
     return -1;
 
-  CIdx = clang_createIndex(0);
+  CIdx = clang_createIndex(0, 1);
   TU = clang_createTranslationUnitFromSourceFile(CIdx, argv[argc - 1],
                                   argc - num_unsaved_files - 2 - NumLocations,
                                    argv + num_unsaved_files + 1 + NumLocations,
@@ -935,7 +891,7 @@
   if (parse_remapped_files(argc, argv, 2, &unsaved_files, &num_unsaved_files))
     return -1;
 
-  CIdx = clang_createIndex(0);
+  CIdx = clang_createIndex(0, 1);
   TU = clang_createTranslationUnitFromSourceFile(CIdx, argv[argc - 1],
                                                  argc - num_unsaved_files - 3,
                                                  argv + num_unsaved_files + 2,
@@ -1053,6 +1009,7 @@
 }
 
 int main(int argc, const char **argv) {
+  clang_enableStackTraces();
   if (argc > 2 && strstr(argv[1], "-code-completion-at=") == argv[1])
     return perform_code_completion(argc, argv);
   if (argc > 2 && strstr(argv[1], "-cursor-at=") == argv[1])





More information about the cfe-commits mailing list