diff options
| -rw-r--r-- | clang/include/clang-c/Index.h | 83 | ||||
| -rw-r--r-- | clang/lib/Basic/Diagnostic.cpp | 2 | ||||
| -rw-r--r-- | clang/test/Index/cindex-on-invalid.m | 1 | ||||
| -rw-r--r-- | clang/test/Index/code-complete-errors.c | 2 | ||||
| -rw-r--r-- | clang/tools/CIndex/CIndex.cpp | 47 | ||||
| -rw-r--r-- | clang/tools/CIndex/CIndex.exports | 3 | ||||
| -rw-r--r-- | clang/tools/CIndex/CIndexCodeCompletion.cpp | 22 | ||||
| -rw-r--r-- | clang/tools/CIndex/CIndexDiagnostic.cpp | 85 | ||||
| -rw-r--r-- | clang/tools/CIndex/CIndexer.h | 12 | ||||
| -rw-r--r-- | clang/tools/c-index-test/c-index-test.c | 175 | 
10 files changed, 296 insertions, 136 deletions
diff --git a/clang/include/clang-c/Index.h b/clang/include/clang-c/Index.h index 99c129b2208..0130b72b6fa 100644 --- a/clang/include/clang-c/Index.h +++ b/clang/include/clang-c/Index.h @@ -18,6 +18,7 @@  #include <sys/stat.h>  #include <time.h> +#include <stdio.h>  #ifdef __cplusplus  extern "C" { @@ -145,8 +146,8 @@ CINDEX_LINKAGE void clang_disposeString(CXString string);   *   * 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 @@ CINDEX_LINKAGE void clang_disposeString(CXString string);   * -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 CXDiagnostic clang_getDiagnostic(CXTranslationUnit Unit,  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 @@ CINDEX_LINKAGE void clang_getDefinitionSpellingAndExtent(CXCursor,                                            unsigned *startColumn,                                            unsigned *endLine,                                            unsigned *endColumn); - +CINDEX_LINKAGE void clang_enableStackTraces(void);  /**   * @}   */ diff --git a/clang/lib/Basic/Diagnostic.cpp b/clang/lib/Basic/Diagnostic.cpp index e92d1e56ca9..c5c9ca7484e 100644 --- a/clang/lib/Basic/Diagnostic.cpp +++ b/clang/lib/Basic/Diagnostic.cpp @@ -923,7 +923,7 @@ StoredDiagnostic::StoredDiagnostic() { }  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) diff --git a/clang/test/Index/cindex-on-invalid.m b/clang/test/Index/cindex-on-invalid.m index 0f6bdffe914..651c40a3353 100644 --- a/clang/test/Index/cindex-on-invalid.m +++ b/clang/test/Index/cindex-on-invalid.m @@ -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! diff --git a/clang/test/Index/code-complete-errors.c b/clang/test/Index/code-complete-errors.c index 520a8c87df2..29c2a861986 100644 --- a/clang/test/Index/code-complete-errors.c +++ b/clang/test/Index/code-complete-errors.c @@ -7,7 +7,7 @@ struct s {  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() {  } diff --git a/clang/tools/CIndex/CIndex.cpp b/clang/tools/CIndex/CIndex.cpp index 61e9210aa50..5eddee45b2c 100644 --- a/clang/tools/CIndex/CIndex.cpp +++ b/clang/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 @@ bool CursorVisitor::VisitAttributes(Decl *D) {  }  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 @@ clang_createTranslationUnitFromSourceFile(CXIndex CIdx,      // 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 @@ clang_createTranslationUnitFromSourceFile(CXIndex CIdx,                                            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 @@ void clang_getDefinitionSpellingAndExtent(CXCursor C,    *endColumn = SM.getSpellingColumnNumber(Body->getRBracLoc());  } +void clang_enableStackTraces(void) { +  llvm::sys::PrintStackTraceOnErrorSignal(); +} +  } // end: extern "C"  //===----------------------------------------------------------------------===// diff --git a/clang/tools/CIndex/CIndex.exports b/clang/tools/CIndex/CIndex.exports index 1c445b74aaa..449bb95a947 100644 --- a/clang/tools/CIndex/CIndex.exports +++ b/clang/tools/CIndex/CIndex.exports @@ -5,12 +5,15 @@ _clang_codeCompleteGetNumDiagnostics  _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 diff --git a/clang/tools/CIndex/CIndexCodeCompletion.cpp b/clang/tools/CIndex/CIndexCodeCompletion.cpp index 9e8946381ae..08510f2e557 100644 --- a/clang/tools/CIndex/CIndexCodeCompletion.cpp +++ b/clang/tools/CIndex/CIndexCodeCompletion.cpp @@ -177,6 +177,9 @@ static bool ReadUnsigned(const char *&Memory, const char *MemoryEnd,  /// \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 @@ struct AllocatedCXCodeCompleteResults : public CXCodeCompleteResults {    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 @@ void clang_disposeCodeCompleteResults(CXCodeCompleteResults *ResultsIn) {    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;  } diff --git a/clang/tools/CIndex/CIndexDiagnostic.cpp b/clang/tools/CIndex/CIndexDiagnostic.cpp index 70676f0e141..07c1983672d 100644 --- a/clang/tools/CIndex/CIndexDiagnostic.cpp +++ b/clang/tools/CIndex/CIndexDiagnostic.cpp @@ -47,6 +47,81 @@ void clang_disposeDiagnostic(CXDiagnostic Diagnostic) {    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 @@ void clang::LoadSerializedDiagnostics(const llvm::sys::Path &DiagnosticsPath,        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 @@ void clang::LoadSerializedDiagnostics(const llvm::sys::Path &DiagnosticsPath,      StoredDiagnostic Stored = StoredDiagnostic::Deserialize(FileMgr, SourceMgr,                                                              Memory, MemoryEnd);      if (!Stored) -      return; +      break;      Diags.push_back(Stored);    } +  delete F;  } diff --git a/clang/tools/CIndex/CIndexer.h b/clang/tools/CIndex/CIndexer.h index d559f138647..1fa3ca93876 100644 --- a/clang/tools/CIndex/CIndexer.h +++ b/clang/tools/CIndex/CIndexer.h @@ -34,11 +34,14 @@ namespace cxstring {  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 @@ public:    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; diff --git a/clang/tools/c-index-test/c-index-test.c b/clang/tools/c-index-test/c-index-test.c index b983d3a4de7..c5f8431c348 100644 --- a/clang/tools/c-index-test/c-index-test.c +++ b/clang/tools/c-index-test/c-index-test.c @@ -198,120 +198,73 @@ typedef void (*PostVisitTU)(CXTranslationUnit);  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 @@ int perform_test_load_tu(const char *file, const char *filter,    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 perform_test_load_source(int argc, const char **argv,    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 @@ static int perform_file_scan(const char *ast_file, const char *source_file,    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 @@ int perform_code_completion(int argc, const char **argv) {    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 @@ int inspect_cursor_at(int argc, const char **argv) {                             &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 @@ int perform_token_annotation(int argc, const char **argv) {    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 @@ static void print_usage(void) {  }  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])  | 

