[cfe-commits] r144269 - in /cfe/trunk: include/clang-c/ include/clang/Frontend/ lib/Frontend/ tools/c-index-test/ tools/libclang/

Nico Weber thakis at chromium.org
Fri Apr 25 12:41:58 PDT 2014


(Search for "clang_codeCompleteGetDiagnostic" to find it.)

On Fri, Apr 25, 2014 at 12:41 PM, Nico Weber <thakis at chromium.org> wrote:
> Zombie review! (below)
>
> On Thu, Nov 10, 2011 at 12:43 AM, Ted Kremenek <kremenek at apple.com> wrote:
>> Author: kremenek
>> Date: Thu Nov 10 02:43:12 2011
>> New Revision: 144269
>>
>> URL: http://llvm.org/viewvc/llvm-project?rev=144269&view=rev
>> Log:
>> serialized diagnostics: implement full deserialization of clang diagnostics via the libclang API.
>>
>> I've tested it on simple cases and it works.  Test cases to follow as well as a few tweaks.
>>
>> Added:
>>     cfe/trunk/tools/libclang/CXLoadedDiagnostic.cpp
>>     cfe/trunk/tools/libclang/CXLoadedDiagnostic.h
>> Modified:
>>     cfe/trunk/include/clang-c/Index.h
>>     cfe/trunk/include/clang/Frontend/SerializedDiagnosticPrinter.h
>>     cfe/trunk/lib/Frontend/SerializedDiagnosticPrinter.cpp
>>     cfe/trunk/tools/c-index-test/c-index-test.c
>>     cfe/trunk/tools/libclang/CIndex.cpp
>>     cfe/trunk/tools/libclang/CIndexDiagnostic.cpp
>>     cfe/trunk/tools/libclang/CIndexDiagnostic.h
>>     cfe/trunk/tools/libclang/CMakeLists.txt
>>     cfe/trunk/tools/libclang/CXSourceLocation.cpp
>>     cfe/trunk/tools/libclang/CXStoredDiagnostic.cpp
>>     cfe/trunk/tools/libclang/CXTranslationUnit.h
>>     cfe/trunk/tools/libclang/libclang.exports
>>
>> Modified: cfe/trunk/include/clang-c/Index.h
>> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang-c/Index.h?rev=144269&r1=144268&r2=144269&view=diff
>> ==============================================================================
>> --- cfe/trunk/include/clang-c/Index.h (original)
>> +++ cfe/trunk/include/clang-c/Index.h Thu Nov 10 02:43:12 2011
>> @@ -522,6 +522,86 @@
>>  typedef void *CXDiagnostic;
>>
>>  /**
>> + * \brief A group of CXDiagnostics.
>> + */
>> +typedef void *CXDiagnosticSet;
>> +
>> +/**
>> + * \brief Determine the number of diagnostics in a CXDiagnosticSet.
>> + */
>> +CINDEX_LINKAGE unsigned clang_getNumDiagnosticsInSet(CXDiagnosticSet Diags);
>> +
>> +/**
>> + * \brief Retrieve a diagnostic associated with the given CXDiagnosticSet.
>> + *
>> + * \param Unit the CXDiagnosticSet to query.
>> + * \param Index the zero-based diagnostic number to retrieve.
>> + *
>> + * \returns the requested diagnostic. This diagnostic must be freed
>> + * via a call to \c clang_disposeDiagnostic().
>> + */
>> +CINDEX_LINKAGE CXDiagnostic clang_getDiagnosticInSet(CXDiagnosticSet Diags,
>> +                                                     unsigned Index);
>> +
>> +
>> +/**
>> + * \brief Describes the kind of error that occurred (if any) in a call to
>> + * \c clang_loadDiagnostics.
>> + */
>> +enum CXLoadDiag_Error {
>> +  /**
>> +   * \brief Indicates that no error occurred.
>> +   */
>> +  CXLoadDiag_None = 0,
>> +
>> +  /**
>> +   * \brief Indicates that an unknown error occurred while attempting to
>> +   * deserialize diagnostics.
>> +   */
>> +  CXLoadDiag_Unknown = 1,
>> +
>> +  /**
>> +   * \brief Indicates that the file containing the serialized diagnostics
>> +   * could not be opened.
>> +   */
>> +  CXLoadDiag_CannotLoad = 2,
>> +
>> +  /**
>> +   * \brief Indicates that the serialized diagnostics file is invalid or
>> +   *  corrupt.
>> +   */
>> +  CXLoadDiag_InvalidFile = 3
>> +};
>> +
>> +/**
>> + * \brief Deserialize a set of diagnostics from a Clang diagnostics bitcode
>> + *  file.
>> + *
>> + * \param The name of the file to deserialize.
>> + * \param A pointer to a enum value recording if there was a problem
>> + *        deserializing the diagnostics.
>> + * \param A pointer to a CXString for recording the error string
>> + *        if the file was not successfully loaded.
>> + *
>> + * \returns A loaded CXDiagnosticSet if successful, and NULL otherwise.  These
>> + *  diagnostics should be released using clang_disposeDiagnosticSet().
>> + */
>> +CINDEX_LINKAGE CXDiagnosticSet clang_loadDiagnostics(const char *file,
>> +                                                  enum CXLoadDiag_Error *error,
>> +                                                  CXString *errorString);
>> +
>> +/**
>> + * \brief Release a CXDiagnosticSet and all of its contained diagnostics.
>> + */
>> +CINDEX_LINKAGE void clang_disposeDiagnosticSet(CXDiagnosticSet Diags);
>> +
>> +/**
>> + * \brief Retrieve the child diagnostics of a CXDiagnostic.  This
>> + *  CXDiagnosticSet does not need to be released by clang_diposeDiagnosticSet.
>> + */
>> +CINDEX_LINKAGE CXDiagnosticSet clang_getChildDiagnostics(CXDiagnostic D);
>> +
>> +/**
>>   * \brief Determine the number of diagnostics produced for the given
>>   * translation unit.
>>   */
>>
>> Modified: cfe/trunk/include/clang/Frontend/SerializedDiagnosticPrinter.h
>> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Frontend/SerializedDiagnosticPrinter.h?rev=144269&r1=144268&r2=144269&view=diff
>> ==============================================================================
>> --- cfe/trunk/include/clang/Frontend/SerializedDiagnosticPrinter.h (original)
>> +++ cfe/trunk/include/clang/Frontend/SerializedDiagnosticPrinter.h Thu Nov 10 02:43:12 2011
>> @@ -39,7 +39,9 @@
>>    RECORD_DIAG_FLAG,
>>    RECORD_CATEGORY,
>>    RECORD_FILENAME,
>> -  RECORD_FIXIT
>> +  RECORD_FIXIT,
>> +  RECORD_FIRST = RECORD_VERSION,
>> +  RECORD_LAST = RECORD_FIXIT
>>  };
>>
>>  /// \brief Returns a DiagnosticConsumer that serializes diagnostics to
>>
>> Modified: cfe/trunk/lib/Frontend/SerializedDiagnosticPrinter.cpp
>> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Frontend/SerializedDiagnosticPrinter.cpp?rev=144269&r1=144268&r2=144269&view=diff
>> ==============================================================================
>> --- cfe/trunk/lib/Frontend/SerializedDiagnosticPrinter.cpp (original)
>> +++ cfe/trunk/lib/Frontend/SerializedDiagnosticPrinter.cpp Thu Nov 10 02:43:12 2011
>> @@ -16,6 +16,7 @@
>>  #include "clang/Basic/FileManager.h"
>>  #include "clang/Basic/Diagnostic.h"
>>  #include "clang/Basic/Version.h"
>> +#include "clang/Lex/Lexer.h"
>>  #include "clang/Frontend/SerializedDiagnosticPrinter.h"
>>
>>  using namespace clang;
>> @@ -47,7 +48,8 @@
>>  class SDiagsWriter : public DiagnosticConsumer {
>>  public:
>>    SDiagsWriter(DiagnosticsEngine &diags, llvm::raw_ostream *os)
>> -    : Stream(Buffer), OS(os), Diags(diags), inNonNoteDiagnostic(false)
>> +    : LangOpts(0), Stream(Buffer), OS(os), Diags(diags),
>> +      inNonNoteDiagnostic(false)
>>    {
>>      EmitPreamble();
>>    };
>> @@ -59,6 +61,11 @@
>>
>>    void EndSourceFile();
>>
>> +  void BeginSourceFile(const LangOptions &LO,
>> +                       const Preprocessor *PP) {
>> +    LangOpts = &LO;
>> +  }
>> +
>>    DiagnosticConsumer *clone(DiagnosticsEngine &Diags) const {
>>      // It makes no sense to clone this.
>>      return 0;
>> @@ -88,7 +95,8 @@
>>    unsigned getEmitFile(SourceLocation Loc);
>>
>>    /// \brief Add SourceLocation information the specified record.
>> -  void AddLocToRecord(SourceLocation Loc, RecordDataImpl &Record);
>> +  void AddLocToRecord(SourceLocation Loc, RecordDataImpl &Record,
>> +                      unsigned TokSize = 0);
>>
>>    /// \brief Add CharSourceRange information the specified record.
>>    void AddCharSourceRangeToRecord(CharSourceRange R, RecordDataImpl &Record);
>> @@ -96,6 +104,8 @@
>>    /// \brief The version of the diagnostics file.
>>    enum { Version = 1 };
>>
>> +  const LangOptions *LangOpts;
>> +
>>    /// \brief The byte buffer for the serialized content.
>>    std::vector<unsigned char> Buffer;
>>
>> @@ -181,13 +191,14 @@
>>  }
>>
>>  void SDiagsWriter::AddLocToRecord(SourceLocation Loc,
>> -                                  RecordDataImpl &Record) {
>> +                                  RecordDataImpl &Record,
>> +                                  unsigned TokSize) {
>>    if (Loc.isInvalid()) {
>>      // Emit a "sentinel" location.
>> -    Record.push_back((unsigned) 0); // File.
>> -    Record.push_back(~(unsigned)0); // Line.
>> -    Record.push_back(~(unsigned)0); // Column.
>> -    Record.push_back(~(unsigned)0); // Offset.
>> +    Record.push_back((unsigned)0); // File.
>> +    Record.push_back((unsigned)0); // Line.
>> +    Record.push_back((unsigned)0); // Column.
>> +    Record.push_back((unsigned)0); // Offset.
>>      return;
>>    }
>>
>> @@ -195,7 +206,7 @@
>>    Loc = SM.getSpellingLoc(Loc);
>>    Record.push_back(getEmitFile(Loc));
>>    Record.push_back(SM.getSpellingLineNumber(Loc));
>> -  Record.push_back(SM.getSpellingColumnNumber(Loc));
>> +  Record.push_back(SM.getSpellingColumnNumber(Loc)+TokSize);
>>
>>    std::pair<FileID, unsigned> LocInfo = SM.getDecomposedLoc(Loc);
>>    FileID FID = LocInfo.first;
>> @@ -206,7 +217,13 @@
>>  void SDiagsWriter::AddCharSourceRangeToRecord(CharSourceRange Range,
>>                                                RecordDataImpl &Record) {
>>    AddLocToRecord(Range.getBegin(), Record);
>> -  AddLocToRecord(Range.getEnd(), Record);
>> +  unsigned TokSize = 0;
>> +  if (Range.isTokenRange())
>> +    TokSize = Lexer::MeasureTokenLength(Range.getEnd(),
>> +                                        Diags.getSourceManager(),
>> +                                        *LangOpts);
>> +
>> +  AddLocToRecord(Range.getEnd(), Record, TokSize);
>>  }
>>
>>  unsigned SDiagsWriter::getEmitFile(SourceLocation Loc) {
>>
>> 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=144269&r1=144268&r2=144269&view=diff
>> ==============================================================================
>> --- cfe/trunk/tools/c-index-test/c-index-test.c (original)
>> +++ cfe/trunk/tools/c-index-test/c-index-test.c Thu Nov 10 02:43:12 2011
>> @@ -2431,6 +2431,155 @@
>>  }
>>
>>  /******************************************************************************/
>> +/* Serialized diagnostics.                                                    */
>> +/******************************************************************************/
>> +
>> +static const char *getDiagnosticCodeStr(enum CXLoadDiag_Error error) {
>> +  switch (error) {
>> +    case CXLoadDiag_CannotLoad: return "Cannot Load File";
>> +    case CXLoadDiag_None: break;
>> +    case CXLoadDiag_Unknown: return "Unknown";
>> +    case CXLoadDiag_InvalidFile: return "Invalid File";
>> +  }
>> +  return "None";
>> +}
>> +
>> +static const char *getSeverityString(enum CXDiagnosticSeverity severity) {
>> +  switch (severity) {
>> +    case CXDiagnostic_Note: return "note";
>> +    case CXDiagnostic_Error: return "error";
>> +    case CXDiagnostic_Fatal: return "fatal";
>> +    case CXDiagnostic_Ignored: return "ignored";
>> +    case CXDiagnostic_Warning: return "warning";
>> +  }
>> +  return "unknown";
>> +}
>> +
>> +static void printIndent(unsigned indent) {
>> +  while (indent > 0) {
>> +    fprintf(stderr, " ");
>> +    --indent;
>> +  }
>> +}
>> +
>> +static void printLocation(CXSourceLocation L) {
>> +  CXFile File;
>> +  CXString FileName;
>> +  unsigned line, column, offset;
>> +
>> +  clang_getExpansionLocation(L, &File, &line, &column, &offset);
>> +  FileName = clang_getFileName(File);
>> +
>> +  fprintf(stderr, "%s:%d:%d", clang_getCString(FileName), line, column);
>> +  clang_disposeString(FileName);
>> +}
>> +
>> +static void printRanges(CXDiagnostic D, unsigned indent) {
>> +  unsigned i, n = clang_getDiagnosticNumRanges(D);
>> +
>> +  for (i = 0; i < n; ++i) {
>> +    CXSourceLocation Start, End;
>> +    CXSourceRange SR = clang_getDiagnosticRange(D, i);
>> +    Start = clang_getRangeStart(SR);
>> +    End = clang_getRangeEnd(SR);
>> +
>> +    printIndent(indent);
>> +    fprintf(stderr, "Range: ");
>> +    printLocation(Start);
>> +    fprintf(stderr, " ");
>> +    printLocation(End);
>> +    fprintf(stderr, "\n");
>> +  }
>> +}
>> +
>> +static void printFixIts(CXDiagnostic D, unsigned indent) {
>> +  unsigned i, n = clang_getDiagnosticNumFixIts(D);
>> +  for (i = 0 ; i < n; ++i) {
>> +    CXSourceRange ReplacementRange;
>> +    CXString text;
>> +    text = clang_getDiagnosticFixIt(D, i, &ReplacementRange);
>> +
>> +    printIndent(indent);
>> +    fprintf(stderr, "FIXIT: (");
>> +    printLocation(clang_getRangeStart(ReplacementRange));
>> +    fprintf(stderr, " - ");
>> +    printLocation(clang_getRangeEnd(ReplacementRange));
>> +    fprintf(stderr, "): \"%s\"\n", clang_getCString(text));
>> +    clang_disposeString(text);
>> +  }
>> +}
>> +
>> +static void printDiagnosticSet(CXDiagnosticSet Diags, unsigned indent) {
>> +  if (!Diags)
>> +    return;
>> +
>> +  fprintf(stderr, "\n");
>> +
>> +  unsigned i = 0;
>> +  unsigned n = clang_getNumDiagnosticsInSet(Diags);
>> +  for (i = 0; i < n; ++i) {
>> +    CXSourceLocation DiagLoc;
>> +    CXDiagnostic D;
>> +    CXFile File;
>> +    CXString FileName, DiagSpelling, DiagOption;
>> +    unsigned line, column, offset;
>> +    const char *DiagOptionStr = 0;
>> +
>> +    D = clang_getDiagnosticInSet(Diags, i);
>> +    DiagLoc = clang_getDiagnosticLocation(D);
>> +    clang_getExpansionLocation(DiagLoc, &File, &line, &column, &offset);
>> +    FileName = clang_getFileName(File);
>> +    DiagSpelling = clang_getDiagnosticSpelling(D);
>> +
>> +    printIndent(indent);
>> +
>> +    fprintf(stderr, "%s:%d:%d: %s: %s",
>> +            clang_getCString(FileName),
>> +            line,
>> +            column,
>> +            getSeverityString(clang_getDiagnosticSeverity(D)),
>> +            clang_getCString(DiagSpelling));
>> +
>> +    DiagOption = clang_getDiagnosticOption(D, 0);
>> +    DiagOptionStr = clang_getCString(DiagOption);
>> +    if (DiagOptionStr) {
>> +      fprintf(stderr, " [%s]", DiagOptionStr);
>> +    }
>> +
>> +    fprintf(stderr, "\n");
>> +
>> +    printRanges(D, indent);
>> +    printFixIts(D, indent);
>> +
>> +    // Print subdiagnostics.
>> +    printDiagnosticSet(clang_getChildDiagnostics(D), indent+2);
>> +
>> +    clang_disposeString(FileName);
>> +    clang_disposeString(DiagSpelling);
>> +    clang_disposeString(DiagOption);
>> +  }
>> +}
>> +
>> +static int read_diagnostics(const char *filename) {
>> +  enum CXLoadDiag_Error error;
>> +  CXString errorString;
>> +  CXDiagnosticSet Diags = 0;
>> +
>> +  Diags = clang_loadDiagnostics(filename, &error, &errorString);
>> +  if (!Diags) {
>> +    fprintf(stderr, "Trouble deserializing file (%s): %s\n",
>> +            getDiagnosticCodeStr(error),
>> +            clang_getCString(errorString));
>> +    clang_disposeString(errorString);
>> +    return 1;
>> +  }
>> +
>> +  printDiagnosticSet(Diags, 0);
>> +  clang_disposeDiagnosticSet(Diags);
>> +  return 0;
>> +}
>> +
>> +/******************************************************************************/
>>  /* Command line processing.                                                   */
>>  /******************************************************************************/
>>
>> @@ -2475,7 +2624,9 @@
>>      "       c-index-test -test-print-typekind {<args>}*\n"
>>      "       c-index-test -print-usr [<CursorKind> {<args>}]*\n"
>>      "       c-index-test -print-usr-file <file>\n"
>> -    "       c-index-test -write-pch <file> <compiler arguments>\n\n");
>> +    "       c-index-test -write-pch <file> <compiler arguments>\n");
>> +  fprintf(stderr,
>> +    "       c-index-test -read-diagnostics <file>\n\n");
>>    fprintf(stderr,
>>      " <symbol filter> values:\n%s",
>>      "   all - load all symbols, including those from PCH\n"
>> @@ -2492,6 +2643,8 @@
>>
>>  int cindextest_main(int argc, const char **argv) {
>>    clang_enableStackTraces();
>> +  if (argc > 2 && strcmp(argv[1], "-read-diagnostics") == 0)
>> +      return read_diagnostics(argv[2]);
>>    if (argc > 2 && strstr(argv[1], "-code-completion-at=") == argv[1])
>>      return perform_code_completion(argc, argv, 0);
>>    if (argc > 2 && strstr(argv[1], "-code-completion-timing=") == argv[1])
>>
>> Modified: cfe/trunk/tools/libclang/CIndex.cpp
>> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/tools/libclang/CIndex.cpp?rev=144269&r1=144268&r2=144269&view=diff
>> ==============================================================================
>> --- cfe/trunk/tools/libclang/CIndex.cpp (original)
>> +++ cfe/trunk/tools/libclang/CIndex.cpp Thu Nov 10 02:43:12 2011
>> @@ -58,6 +58,7 @@
>>    CXTranslationUnit D = new CXTranslationUnitImpl();
>>    D->TUData = TU;
>>    D->StringPool = createCXStringPool();
>> +  D->Diagnostics = 0;
>>    return D;
>>  }
>>
>> @@ -2562,6 +2563,7 @@
>>
>>      delete static_cast<ASTUnit *>(CTUnit->TUData);
>>      disposeCXStringPool(CTUnit->StringPool);
>> +    delete static_cast<CXDiagnosticSetImpl *>(CTUnit->Diagnostics);
>>      delete CTUnit;
>>    }
>>  }
>> @@ -2582,6 +2584,11 @@
>>    ReparseTranslationUnitInfo *RTUI =
>>      static_cast<ReparseTranslationUnitInfo*>(UserData);
>>    CXTranslationUnit TU = RTUI->TU;
>> +
>> +  // Reset the associated diagnostics.
>> +  delete static_cast<CXDiagnosticSetImpl*>(TU->Diagnostics);
>> +  TU->Diagnostics = 0;
>> +
>>    unsigned num_unsaved_files = RTUI->num_unsaved_files;
>>    struct CXUnsavedFile *unsaved_files = RTUI->unsaved_files;
>>    unsigned options = RTUI->options;
>>
>> Modified: cfe/trunk/tools/libclang/CIndexDiagnostic.cpp
>> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/tools/libclang/CIndexDiagnostic.cpp?rev=144269&r1=144268&r2=144269&view=diff
>> ==============================================================================
>> --- cfe/trunk/tools/libclang/CIndexDiagnostic.cpp (original)
>> +++ cfe/trunk/tools/libclang/CIndexDiagnostic.cpp Thu Nov 10 02:43:12 2011
>> @@ -28,27 +28,58 @@
>>  using namespace clang::cxstring;
>>  using namespace llvm;
>>
>> +
>> +CXDiagnosticSetImpl::~CXDiagnosticSetImpl() {
>> +  for (std::vector<CXDiagnosticImpl *>::iterator it = Diagnostics.begin(),
>> +       et = Diagnostics.end();
>> +       it != et; ++it) {
>> +    delete *it;
>> +  }
>> +}
>> +
>> +CXDiagnosticImpl::~CXDiagnosticImpl() {}
>> +
>> +static CXDiagnosticSetImpl *lazyCreateDiags(CXTranslationUnit TU) {
>> +  if (!TU->Diagnostics) {
>> +    ASTUnit *AU = static_cast<ASTUnit *>(TU->TUData);
>> +    CXDiagnosticSetImpl *Set = new CXDiagnosticSetImpl();
>> +    TU->Diagnostics = Set;
>> +
>> +    for (ASTUnit::stored_diag_iterator it = AU->stored_diag_begin(),
>> +         ei = AU->stored_diag_end(); it != ei; ++it) {
>> +      CXStoredDiagnostic *D =
>> +        new CXStoredDiagnostic(*it, AU->getASTContext().getLangOptions());
>> +      Set->appendDiagnostic(D);
>> +    }
>> +  }
>> +  return static_cast<CXDiagnosticSetImpl*>(TU->Diagnostics);
>> +}
>> +
>>  //-----------------------------------------------------------------------------
>>  // C Interface Routines
>>  //-----------------------------------------------------------------------------
>>  extern "C" {
>>
>>  unsigned clang_getNumDiagnostics(CXTranslationUnit Unit) {
>> -  ASTUnit *CXXUnit = static_cast<ASTUnit *>(Unit->TUData);
>> -  return CXXUnit? CXXUnit->stored_diag_size() : 0;
>> +  if (!Unit->TUData)
>> +    return 0;
>> +  return lazyCreateDiags(Unit)->getNumDiagnostics();
>>  }
>>
>>  CXDiagnostic clang_getDiagnostic(CXTranslationUnit Unit, unsigned Index) {
>> -  ASTUnit *CXXUnit = static_cast<ASTUnit *>(Unit->TUData);
>> -  if (!CXXUnit || Index >= CXXUnit->stored_diag_size())
>> +  if (!Unit->TUData)
>> +    return 0;
>> +
>> +  CXDiagnosticSetImpl *Diags = lazyCreateDiags(Unit);
>> +  if (Index >= Diags->getNumDiagnostics())
>>      return 0;
>>
>> -  return new CXStoredDiagnostic(CXXUnit->stored_diag_begin()[Index],
>> -                                CXXUnit->getASTContext().getLangOptions());
>> +  return Diags->getDiagnostic(Index);
>>  }
>>
>>  void clang_disposeDiagnostic(CXDiagnostic Diagnostic) {
>> -  delete static_cast<CXDiagnosticImpl *>(Diagnostic);
>> +  // No-op.  Kept as a legacy API.  CXDiagnostics are now managed
>> +  // by the enclosing CXDiagnosticSet.
>
> clang_codeCompleteGetDiagnostic() also needed this function to delete
> the argument (see the call to clang_codeCompleteGetDiagnostic()
> c-index-test.c and the dispose call two lines below – that's now a
> leak).
>
> Do you have an opinion on how to fix this? Should the result of
> clang_codeCompleteAt() own diagnostics associated with the completion?
>
>>  }
>>
>>  CXString clang_formatDiagnostic(CXDiagnostic Diagnostic, unsigned Options) {
>> @@ -243,4 +274,32 @@
>>    return D->getFixIt(FixIt, ReplacementRange);
>>  }
>>
>> +void clang_disposeDiagnosticSet(CXDiagnosticSet Diags) {
>> +  CXDiagnosticSetImpl *D = static_cast<CXDiagnosticSetImpl*>(Diags);
>> +  if (D->isExternallyManaged())
>> +    delete D;
>> +}
>> +
>> +CXDiagnostic clang_getDiagnosticInSet(CXDiagnosticSet Diags,
>> +                                      unsigned Index) {
>> +  if (CXDiagnosticSetImpl *D = static_cast<CXDiagnosticSetImpl*>(Diags))
>> +    if (Index < D->getNumDiagnostics())
>> +      return D->getDiagnostic(Index);
>> +  return 0;
>> +}
>> +
>> +CXDiagnosticSet clang_getChildDiagnostics(CXDiagnostic Diag) {
>> +  if (CXDiagnosticImpl *D = static_cast<CXDiagnosticImpl *>(Diag)) {
>> +    CXDiagnosticSetImpl &ChildDiags = D->getChildDiagnostics();
>> +    return ChildDiags.empty() ? 0 : (CXDiagnosticSet) &ChildDiags;
>> +  }
>> +  return 0;
>> +}
>> +
>> +unsigned clang_getNumDiagnosticsInSet(CXDiagnosticSet Diags) {
>> +  if (CXDiagnosticSetImpl *D = static_cast<CXDiagnosticSetImpl*>(Diags))
>> +    return D->getNumDiagnostics();
>> +  return 0;
>> +}
>> +
>>  } // end extern "C"
>>
>> Modified: cfe/trunk/tools/libclang/CIndexDiagnostic.h
>> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/tools/libclang/CIndexDiagnostic.h?rev=144269&r1=144268&r2=144269&view=diff
>> ==============================================================================
>> --- cfe/trunk/tools/libclang/CIndexDiagnostic.h (original)
>> +++ cfe/trunk/tools/libclang/CIndexDiagnostic.h Thu Nov 10 02:43:12 2011
>> @@ -14,15 +14,47 @@
>>  #define LLVM_CLANG_CINDEX_DIAGNOSTIC_H
>>
>>  #include "clang-c/Index.h"
>> +#include <vector>
>> +#include <assert.h>
>>
>>  namespace clang {
>>
>>  class LangOptions;
>>  class StoredDiagnostic;
>> +class CXDiagnosticImpl;
>> +
>> +class CXDiagnosticSetImpl {
>> +  std::vector<CXDiagnosticImpl *> Diagnostics;
>> +  const bool IsExternallyManaged;
>> +public:
>> +  CXDiagnosticSetImpl(bool isManaged = false)
>> +    : IsExternallyManaged(isManaged) {}
>> +
>> +  virtual ~CXDiagnosticSetImpl();
>> +
>> +  size_t getNumDiagnostics() const {
>> +    return Diagnostics.size();
>> +  }
>> +
>> +  CXDiagnosticImpl *getDiagnostic(unsigned i) const {
>> +    assert(i < getNumDiagnostics());
>> +    return Diagnostics[i];
>> +  }
>> +
>> +  void appendDiagnostic(CXDiagnosticImpl *D) {
>> +    Diagnostics.push_back(D);
>> +  }
>> +
>> +  bool empty() const {
>> +    return Diagnostics.empty();
>> +  }
>> +
>> +  bool isExternallyManaged() const { return IsExternallyManaged; }
>> +};
>>
>>  class CXDiagnosticImpl {
>>  public:
>> -  enum Kind { StoredDiagnosticKind, SerializedDiagnosticKind };
>> +  enum Kind { StoredDiagnosticKind, LoadedDiagnosticKind };
>>
>>    virtual ~CXDiagnosticImpl();
>>
>> @@ -55,9 +87,18 @@
>>                              CXSourceRange *ReplacementRange) const = 0;
>>
>>    Kind getKind() const { return K; }
>> -
>> +
>> +  CXDiagnosticSetImpl &getChildDiagnostics() {
>> +    return ChildDiags;
>> +  }
>> +
>>  protected:
>>    CXDiagnosticImpl(Kind k) : K(k) {}
>> +  CXDiagnosticSetImpl ChildDiags;
>> +
>> +  void append(CXDiagnosticImpl *D) {
>> +    ChildDiags.appendDiagnostic(D);
>> +  }
>>
>>  private:
>>    Kind K;
>>
>> Modified: cfe/trunk/tools/libclang/CMakeLists.txt
>> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/tools/libclang/CMakeLists.txt?rev=144269&r1=144268&r2=144269&view=diff
>> ==============================================================================
>> --- cfe/trunk/tools/libclang/CMakeLists.txt (original)
>> +++ cfe/trunk/tools/libclang/CMakeLists.txt Thu Nov 10 02:43:12 2011
>> @@ -29,6 +29,8 @@
>>    CIndexer.h
>>    CXCursor.cpp
>>    CXCursor.h
>> +  CXLoadedDiagnostic.cpp
>> +  CXLoadedDiagnostic.h
>>    CXSourceLocation.cpp
>>    CXSourceLocation.h
>>    CXStoredDiagnostic.cpp
>>
>> Added: cfe/trunk/tools/libclang/CXLoadedDiagnostic.cpp
>> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/tools/libclang/CXLoadedDiagnostic.cpp?rev=144269&view=auto
>> ==============================================================================
>> --- cfe/trunk/tools/libclang/CXLoadedDiagnostic.cpp (added)
>> +++ cfe/trunk/tools/libclang/CXLoadedDiagnostic.cpp Thu Nov 10 02:43:12 2011
>> @@ -0,0 +1,655 @@
>> +/*===-- CXLoadedDiagnostic.cpp - Handling of persisent diags -*- C++ -*-===*\
>> +|*                                                                            *|
>> +|*                     The LLVM Compiler Infrastructure                       *|
>> +|*                                                                            *|
>> +|* This file is distributed under the University of Illinois Open Source      *|
>> +|* License. See LICENSE.TXT for details.                                      *|
>> +|*                                                                            *|
>> +|*===----------------------------------------------------------------------===*|
>> +|*                                                                            *|
>> +|* Implements handling of persisent diagnostics.                              *|
>> +|*                                                                            *|
>> +\*===----------------------------------------------------------------------===*/
>> +
>> +#include "CXLoadedDiagnostic.h"
>> +#include "CXString.h"
>> +#include "clang/Basic/Diagnostic.h"
>> +#include "clang/Basic/FileManager.h"
>> +#include "clang/Frontend/SerializedDiagnosticPrinter.h"
>> +#include "llvm/ADT/StringRef.h"
>> +#include "llvm/ADT/Twine.h"
>> +#include "llvm/ADT/Optional.h"
>> +#include "clang/Basic/LLVM.h"
>> +#include "llvm/Support/ErrorHandling.h"
>> +#include "llvm/Bitcode/BitstreamReader.h"
>> +#include "llvm/Support/MemoryBuffer.h"
>> +#include <assert.h>
>> +
>> +using namespace clang;
>> +using namespace clang::cxstring;
>> +
>> +//===----------------------------------------------------------------------===//
>> +// Extend CXDiagnosticSetImpl which contains strings for diagnostics.
>> +//===----------------------------------------------------------------------===//
>> +
>> +typedef llvm::DenseMap<unsigned, llvm::StringRef> Strings;
>> +
>> +namespace {
>> +class CXLoadedDiagnosticSetImpl : public CXDiagnosticSetImpl {
>> +public:
>> +  CXLoadedDiagnosticSetImpl() : CXDiagnosticSetImpl(true), FakeFiles(FO) {}
>> +  virtual ~CXLoadedDiagnosticSetImpl() {}
>> +
>> +  llvm::StringRef makeString(const char *blob, unsigned blobLen);
>> +
>> +  llvm::BumpPtrAllocator Alloc;
>> +  Strings Categories;
>> +  Strings WarningFlags;
>> +  Strings FileNames;
>> +
>> +  FileSystemOptions FO;
>> +  FileManager FakeFiles;
>> +  llvm::DenseMap<unsigned, const FileEntry *> Files;
>> +};
>> +}
>> +
>> +llvm::StringRef CXLoadedDiagnosticSetImpl::makeString(const char *blob,
>> +                                                      unsigned bloblen) {
>> +  char *mem = Alloc.Allocate<char>(bloblen);
>> +  memcpy(mem, blob, bloblen);
>> +  return llvm::StringRef(mem, bloblen);
>> +}
>> +
>> +//===----------------------------------------------------------------------===//
>> +// Cleanup.
>> +//===----------------------------------------------------------------------===//
>> +
>> +CXLoadedDiagnostic::~CXLoadedDiagnostic() {}
>> +
>> +//===----------------------------------------------------------------------===//
>> +// Public CXLoadedDiagnostic methods.
>> +//===----------------------------------------------------------------------===//
>> +
>> +CXDiagnosticSeverity CXLoadedDiagnostic::getSeverity() const {
>> +  // FIXME: possibly refactor with logic in CXStoredDiagnostic.
>> +  switch (severity) {
>> +    case DiagnosticsEngine::Ignored: return CXDiagnostic_Ignored;
>> +    case DiagnosticsEngine::Note:    return CXDiagnostic_Note;
>> +    case DiagnosticsEngine::Warning: return CXDiagnostic_Warning;
>> +    case DiagnosticsEngine::Error:   return CXDiagnostic_Error;
>> +    case DiagnosticsEngine::Fatal:   return CXDiagnostic_Fatal;
>> +  }
>> +
>> +  llvm_unreachable("Invalid diagnostic level");
>> +  return CXDiagnostic_Ignored;
>> +}
>> +
>> +static CXSourceLocation makeLocation(const CXLoadedDiagnostic::Location *DLoc) {
>> +  // The lowest bit of ptr_data[0] is always set to 1 to indicate this
>> +  // is a persistent diagnostic.
>> +  uintptr_t V = (uintptr_t) DLoc;
>> +  V |= 0x1;
>> +  CXSourceLocation Loc = { {  (void*) V, 0 }, 0 };
>> +  return Loc;
>> +}
>> +
>> +CXSourceLocation CXLoadedDiagnostic::getLocation() const {
>> +  // The lowest bit of ptr_data[0] is always set to 1 to indicate this
>> +  // is a persistent diagnostic.
>> +  return makeLocation(&DiagLoc);
>> +}
>> +
>> +CXString CXLoadedDiagnostic::getSpelling() const {
>> +  return cxstring::createCXString(Spelling, false);
>> +}
>> +
>> +CXString CXLoadedDiagnostic::getDiagnosticOption(CXString *Disable) const {
>> +  if (DiagOption.empty())
>> +    return createCXString("");
>> +
>> +  // FIXME: possibly refactor with logic in CXStoredDiagnostic.
>> +  if (Disable)
>> +    *Disable = createCXString((Twine("-Wno-") + DiagOption).str());
>> +  return createCXString((Twine("-W") + DiagOption).str());
>> +}
>> +
>> +unsigned CXLoadedDiagnostic::getCategory() const {
>> +  return category;
>> +}
>> +
>> +unsigned CXLoadedDiagnostic::getNumRanges() const {
>> +  return Ranges.size();
>> +}
>> +
>> +CXSourceRange CXLoadedDiagnostic::getRange(unsigned Range) const {
>> +  assert(Range < Ranges.size());
>> +  return Ranges[Range];
>> +}
>> +
>> +unsigned CXLoadedDiagnostic::getNumFixIts() const {
>> +  return FixIts.size();
>> +}
>> +
>> +CXString CXLoadedDiagnostic::getFixIt(unsigned FixIt,
>> +                                      CXSourceRange *ReplacementRange) const {
>> +  assert(FixIt < FixIts.size());
>> +  if (ReplacementRange)
>> +    *ReplacementRange = FixIts[FixIt].first;
>> +  return FixIts[FixIt].second;
>> +}
>> +
>> +void CXLoadedDiagnostic::decodeLocation(CXSourceLocation location,
>> +                                        CXFile *file,
>> +                                        unsigned int *line,
>> +                                        unsigned int *column,
>> +                                        unsigned int *offset) {
>> +
>> +
>> +  // CXSourceLocation consists of the following fields:
>> +  //
>> +  //   void *ptr_data[2];
>> +  //   unsigned int_data;
>> +  //
>> +  // The lowest bit of ptr_data[0] is always set to 1 to indicate this
>> +  // is a persistent diagnostic.
>> +  //
>> +  // For now, do the unoptimized approach and store the data in a side
>> +  // data structure.  We can optimize this case later.
>> +
>> +  uintptr_t V = (uintptr_t) location.ptr_data[0];
>> +  assert((V & 0x1) == 1);
>> +  V &= ~(uintptr_t)1;
>> +
>> +  const Location &Loc = *((Location*)V);
>> +
>> +  if (file)
>> +    *file = Loc.file;
>> +  if (line)
>> +    *line = Loc.line;
>> +  if (column)
>> +    *column = Loc.column;
>> +  if (offset)
>> +    *offset = Loc.offset;
>> +}
>> +
>> +//===----------------------------------------------------------------------===//
>> +// Deserialize diagnostics.
>> +//===----------------------------------------------------------------------===//
>> +
>> +enum { MaxSupportedVersion = 1 };
>> +typedef SmallVector<uint64_t, 64> RecordData;
>> +enum LoadResult { Failure = 1, Success = 0 };
>> +enum StreamResult { Read_EndOfStream,
>> +                    Read_BlockBegin,
>> +                    Read_Failure,
>> +                    Read_Record,
>> +                    Read_BlockEnd };
>> +
>> +namespace {
>> +class DiagLoader {
>> +  enum CXLoadDiag_Error *error;
>> +  CXString *errorString;
>> +
>> +  void reportBad(enum CXLoadDiag_Error code, llvm::StringRef err) {
>> +    if (error)
>> +      *error = code;
>> +    if (errorString)
>> +      *errorString = createCXString(err);
>> +  }
>> +
>> +  void reportInvalidFile(llvm::StringRef err) {
>> +    return reportBad(CXLoadDiag_InvalidFile, err);
>> +  }
>> +
>> +  LoadResult readMetaBlock(llvm::BitstreamCursor &Stream);
>> +
>> +  LoadResult readDiagnosticBlock(llvm::BitstreamCursor &Stream,
>> +                                 CXDiagnosticSetImpl &Diags,
>> +                                 CXLoadedDiagnosticSetImpl &TopDiags);
>> +
>> +  StreamResult readToNextRecordOrBlock(llvm::BitstreamCursor &Stream,
>> +                                       llvm::StringRef errorContext,
>> +                                       unsigned &BlockOrRecordID,
>> +                                       const bool atTopLevel = false);
>> +
>> +
>> +  LoadResult readString(CXLoadedDiagnosticSetImpl &TopDiags,
>> +                        Strings &strings, llvm::StringRef errorContext,
>> +                        RecordData &Record,
>> +                        const char *BlobStart,
>> +                        unsigned BlobLen);
>> +
>> +  LoadResult readString(CXLoadedDiagnosticSetImpl &TopDiags,
>> +                        llvm::StringRef &RetStr,
>> +                        llvm::StringRef errorContext,
>> +                        RecordData &Record,
>> +                        const char *BlobStart,
>> +                        unsigned BlobLen);
>> +
>> +  LoadResult readRange(CXLoadedDiagnosticSetImpl &TopDiags,
>> +                       RecordData &Record, unsigned RecStartIdx,
>> +                       CXSourceRange &SR);
>> +
>> +  LoadResult readLocation(CXLoadedDiagnosticSetImpl &TopDiags,
>> +                          RecordData &Record, unsigned &offset,
>> +                          CXLoadedDiagnostic::Location &Loc);
>> +
>> +public:
>> +  DiagLoader(enum CXLoadDiag_Error *e, CXString *es)
>> +    : error(e), errorString(es) {
>> +      if (error)
>> +        *error = CXLoadDiag_None;
>> +      if (errorString)
>> +        *errorString = createCXString("");
>> +    }
>> +
>> +  CXDiagnosticSet load(const char *file);
>> +};
>> +}
>> +
>> +CXDiagnosticSet DiagLoader::load(const char *file) {
>> +  // Open the diagnostics file.
>> +  std::string ErrStr;
>> +  FileSystemOptions FO;
>> +  FileManager FileMgr(FO);
>> +
>> +  llvm::OwningPtr<llvm::MemoryBuffer> Buffer;
>> +  Buffer.reset(FileMgr.getBufferForFile(file));
>> +
>> +  if (!Buffer) {
>> +    reportBad(CXLoadDiag_CannotLoad, ErrStr);
>> +    return 0;
>> +  }
>> +
>> +  llvm::BitstreamReader StreamFile;
>> +  StreamFile.init((const unsigned char *)Buffer->getBufferStart(),
>> +                  (const unsigned char *)Buffer->getBufferEnd());
>> +
>> +  llvm::BitstreamCursor Stream;
>> +  Stream.init(StreamFile);
>> +
>> +  // Sniff for the signature.
>> +  if (Stream.Read(8) != 'D' ||
>> +      Stream.Read(8) != 'I' ||
>> +      Stream.Read(8) != 'A' ||
>> +      Stream.Read(8) != 'G') {
>> +    reportBad(CXLoadDiag_InvalidFile,
>> +              "Bad header in diagnostics file");
>> +    return 0;
>> +  }
>> +
>> +  llvm::OwningPtr<CXLoadedDiagnosticSetImpl>
>> +    Diags(new CXLoadedDiagnosticSetImpl());
>> +
>> +  while (true) {
>> +    unsigned BlockID = 0;
>> +    StreamResult Res = readToNextRecordOrBlock(Stream, "Top-level",
>> +                                               BlockID, true);
>> +    switch (Res) {
>> +      case Read_EndOfStream:
>> +        return (CXDiagnosticSet) Diags.take();
>> +      case Read_Failure:
>> +        return 0;
>> +      case Read_Record:
>> +        llvm_unreachable("Top-level does not have records");
>> +        return 0;
>> +      case Read_BlockEnd:
>> +        continue;
>> +      case Read_BlockBegin:
>> +        break;
>> +    }
>> +
>> +    switch (BlockID) {
>> +      case serialized_diags::BLOCK_META:
>> +        if (readMetaBlock(Stream))
>> +          return 0;
>> +        break;
>> +      case serialized_diags::BLOCK_DIAG:
>> +        if (readDiagnosticBlock(Stream, *Diags.get(), *Diags.get()))
>> +          return 0;
>> +        break;
>> +      default:
>> +        if (!Stream.SkipBlock()) {
>> +          reportInvalidFile("Malformed block at top-level of diagnostics file");
>> +          return 0;
>> +        }
>> +        break;
>> +    }
>> +  }
>> +}
>> +
>> +StreamResult DiagLoader::readToNextRecordOrBlock(llvm::BitstreamCursor &Stream,
>> +                                                 llvm::StringRef errorContext,
>> +                                                 unsigned &blockOrRecordID,
>> +                                                 const bool atTopLevel) {
>> +
>> +  blockOrRecordID = 0;
>> +
>> +  while (!Stream.AtEndOfStream()) {
>> +    unsigned Code = Stream.ReadCode();
>> +
>> +    // Handle the top-level specially.
>> +    if (atTopLevel) {
>> +      if (Code == llvm::bitc::ENTER_SUBBLOCK) {
>> +        unsigned BlockID = Stream.ReadSubBlockID();
>> +        if (BlockID == llvm::bitc::BLOCKINFO_BLOCK_ID) {
>> +          if (Stream.ReadBlockInfoBlock()) {
>> +            reportInvalidFile("Malformed BlockInfoBlock in diagnostics file");
>> +            return Read_Failure;
>> +          }
>> +          continue;
>> +        }
>> +        blockOrRecordID = BlockID;
>> +        return Read_BlockBegin;
>> +      }
>> +      reportInvalidFile("Only blocks can appear at the top of a "
>> +                        "diagnostic file");
>> +      return Read_Failure;
>> +    }
>> +
>> +    switch ((llvm::bitc::FixedAbbrevIDs)Code) {
>> +      case llvm::bitc::ENTER_SUBBLOCK:
>> +        blockOrRecordID = Stream.ReadSubBlockID();
>> +        return Read_BlockBegin;
>> +
>> +      case llvm::bitc::END_BLOCK:
>> +        if (Stream.ReadBlockEnd()) {
>> +          reportInvalidFile("Cannot read end of block");
>> +          return Read_Failure;
>> +        }
>> +        return Read_BlockEnd;
>> +
>> +      case llvm::bitc::DEFINE_ABBREV:
>> +        Stream.ReadAbbrevRecord();
>> +        continue;
>> +
>> +      case llvm::bitc::UNABBREV_RECORD:
>> +        reportInvalidFile("Diagnostics file should have no unabbreviated "
>> +                          "records");
>> +        return Read_Failure;
>> +
>> +      default:
>> +        // We found a record.
>> +        blockOrRecordID = Code;
>> +        return Read_Record;
>> +    }
>> +  }
>> +
>> +  if (atTopLevel)
>> +    return Read_EndOfStream;
>> +
>> +  reportInvalidFile(Twine("Premature end of diagnostics file within ").str() +
>> +                    errorContext.str());
>> +  return Read_Failure;
>> +}
>> +
>> +LoadResult DiagLoader::readMetaBlock(llvm::BitstreamCursor &Stream) {
>> +  if (Stream.EnterSubBlock(clang::serialized_diags::BLOCK_META)) {
>> +    reportInvalidFile("Malformed metadata block");
>> +    return Failure;
>> +  }
>> +
>> +  bool versionChecked = false;
>> +
>> +  while (true) {
>> +    unsigned blockOrCode = 0;
>> +    StreamResult Res = readToNextRecordOrBlock(Stream, "Metadata Block",
>> +                                               blockOrCode);
>> +
>> +    switch(Res) {
>> +      case Read_EndOfStream:
>> +        llvm_unreachable("EndOfStream handled by readToNextRecordOrBlock");
>> +      case Read_Failure:
>> +        return Failure;
>> +      case Read_Record:
>> +        break;
>> +      case Read_BlockBegin:
>> +        if (Stream.SkipBlock()) {
>> +          reportInvalidFile("Malformed metadata block");
>> +          return Failure;
>> +        }
>> +      case Read_BlockEnd:
>> +        if (!versionChecked) {
>> +          reportInvalidFile("Diagnostics file does not contain version"
>> +                            " information");
>> +          return Failure;
>> +        }
>> +        return Success;
>> +    }
>> +
>> +    RecordData Record;
>> +    const char *Blob;
>> +    unsigned BlobLen;
>> +    unsigned recordID = Stream.ReadRecord(blockOrCode, Record, &Blob, &BlobLen);
>> +
>> +    if (recordID == serialized_diags::RECORD_VERSION) {
>> +      if (Record.size() < 1) {
>> +        reportInvalidFile("malformed VERSION identifier in diagnostics file");
>> +        return Failure;
>> +      }
>> +      if (Record[0] > MaxSupportedVersion) {
>> +        reportInvalidFile("diagnosics file is a newer version than the one "
>> +                          "supported");
>> +        return Failure;
>> +      }
>> +      versionChecked = true;
>> +    }
>> +  }
>> +}
>> +
>> +LoadResult DiagLoader::readString(CXLoadedDiagnosticSetImpl &TopDiags,
>> +                                  llvm::StringRef &RetStr,
>> +                                  llvm::StringRef errorContext,
>> +                                  RecordData &Record,
>> +                                  const char *BlobStart,
>> +                                  unsigned BlobLen) {
>> +
>> +  // Basic buffer overflow check.
>> +  if (BlobLen > 65536) {
>> +    reportInvalidFile(std::string("Out-of-bounds string in ") +
>> +                      std::string(errorContext));
>> +    return Failure;
>> +  }
>> +
>> +  if (Record.size() < 1 || BlobLen == 0) {
>> +    reportInvalidFile(std::string("Corrupted ") + std::string(errorContext)
>> +                      + std::string(" entry"));
>> +    return Failure;
>> +  }
>> +
>> +  RetStr = TopDiags.makeString(BlobStart, BlobLen);
>> +  return Success;
>> +}
>> +
>> +LoadResult DiagLoader::readString(CXLoadedDiagnosticSetImpl &TopDiags,
>> +                                  Strings &strings,
>> +                                  llvm::StringRef errorContext,
>> +                                  RecordData &Record,
>> +                                  const char *BlobStart,
>> +                                  unsigned BlobLen) {
>> +  llvm::StringRef RetStr;
>> +  if (readString(TopDiags, RetStr, errorContext, Record, BlobStart, BlobLen))
>> +    return Failure;
>> +  strings[Record[0]] = RetStr;
>> +  return Success;
>> +}
>> +
>> +LoadResult DiagLoader::readLocation(CXLoadedDiagnosticSetImpl &TopDiags,
>> +                                    RecordData &Record, unsigned &offset,
>> +                                    CXLoadedDiagnostic::Location &Loc) {
>> +  if (Record.size() < offset + 3) {
>> +    reportInvalidFile("Corrupted source location");
>> +    return Failure;
>> +  }
>> +
>> +  unsigned fileID = Record[offset++];
>> +  if (fileID == 0) {
>> +    // Sentinel value.
>> +    Loc.file = 0;
>> +    Loc.line = 0;
>> +    Loc.column = 0;
>> +    Loc.offset = 0;
>> +    return Success;
>> +  }
>> +
>> +  const FileEntry *FE = TopDiags.Files[fileID];
>> +  if (!FE) {
>> +    reportInvalidFile("Corrupted file entry in source location");
>> +    return Failure;
>> +  }
>> +  Loc.file = (void*) FE;
>> +  Loc.line = Record[offset++];
>> +  Loc.column = Record[offset++];
>> +  Loc.offset = Record[offset++];
>> +  return Success;
>> +}
>> +
>> +LoadResult DiagLoader::readRange(CXLoadedDiagnosticSetImpl &TopDiags,
>> +                                 RecordData &Record,
>> +                                 unsigned int RecStartIdx,
>> +                                 CXSourceRange &SR) {
>> +  CXLoadedDiagnostic::Location *Start, *End;
>> +  Start = TopDiags.Alloc.Allocate<CXLoadedDiagnostic::Location>();
>> +  End = TopDiags.Alloc.Allocate<CXLoadedDiagnostic::Location>();
>> +
>> +  if (readLocation(TopDiags, Record, RecStartIdx, *Start))
>> +    return Failure;
>> +  if (readLocation(TopDiags, Record, RecStartIdx, *End))
>> +    return Failure;
>> +
>> +  CXSourceLocation startLoc = makeLocation(Start);
>> +  CXSourceLocation endLoc = makeLocation(End);
>> +  SR = clang_getRange(startLoc, endLoc);
>> +  return Success;
>> +}
>> +
>> +LoadResult DiagLoader::readDiagnosticBlock(llvm::BitstreamCursor &Stream,
>> +                                           CXDiagnosticSetImpl &Diags,
>> +                                           CXLoadedDiagnosticSetImpl &TopDiags){
>> +
>> +  if (Stream.EnterSubBlock(clang::serialized_diags::BLOCK_DIAG)) {
>> +    reportInvalidFile("malformed diagnostic block");
>> +    return Failure;
>> +  }
>> +
>> +  llvm::OwningPtr<CXLoadedDiagnostic> D(new CXLoadedDiagnostic());
>> +  RecordData Record;
>> +
>> +  while (true) {
>> +    unsigned blockOrCode = 0;
>> +    StreamResult Res = readToNextRecordOrBlock(Stream, "Diagnostic Block",
>> +                                               blockOrCode);
>> +    switch (Res) {
>> +      case Read_EndOfStream:
>> +        llvm_unreachable("EndOfStream handled in readToNextRecordOrBlock");
>> +        return Failure;
>> +      case Read_Failure:
>> +        return Failure;
>> +      case Read_BlockBegin: {
>> +        // The only blocks we care about are subdiagnostics.
>> +        if (blockOrCode != serialized_diags::BLOCK_DIAG) {
>> +          if (!Stream.SkipBlock()) {
>> +            reportInvalidFile("Invalid subblock in Diagnostics block");
>> +            return Failure;
>> +          }
>> +        } else if (readDiagnosticBlock(Stream, D->getChildDiagnostics(),
>> +                                       TopDiags)) {
>> +          return Failure;
>> +        }
>> +
>> +        continue;
>> +      }
>> +      case Read_BlockEnd:
>> +        Diags.appendDiagnostic(D.take());
>> +        return Success;
>> +      case Read_Record:
>> +        break;
>> +    }
>> +
>> +    // Read the record.
>> +    Record.clear();
>> +    const char *BlobStart = 0;
>> +    unsigned BlobLen = 0;
>> +    unsigned recID = Stream.ReadRecord(blockOrCode, Record,
>> +                                       BlobStart, BlobLen);
>> +
>> +    if (recID < serialized_diags::RECORD_FIRST ||
>> +        recID > serialized_diags::RECORD_LAST)
>> +      continue;
>> +
>> +    switch ((serialized_diags::RecordIDs)recID) {
>> +      case serialized_diags::RECORD_VERSION:
>> +        continue;
>> +      case serialized_diags::RECORD_CATEGORY:
>> +        if (readString(TopDiags, TopDiags.Categories, "category", Record,
>> +                       BlobStart, BlobLen))
>> +          return Failure;
>> +        continue;
>> +
>> +      case serialized_diags::RECORD_DIAG_FLAG:
>> +        if (readString(TopDiags, TopDiags.WarningFlags, "warning flag", Record,
>> +                       BlobStart, BlobLen))
>> +          return Failure;
>> +        continue;
>> +
>> +      case serialized_diags::RECORD_FILENAME: {
>> +        if (readString(TopDiags, TopDiags.FileNames, "filename", Record,
>> +                       BlobStart, BlobLen))
>> +          return Failure;
>> +
>> +        if (Record.size() < 3) {
>> +          reportInvalidFile("Invalid file entry");
>> +          return Failure;
>> +        }
>> +
>> +        const FileEntry *FE =
>> +          TopDiags.FakeFiles.getVirtualFile(TopDiags.FileNames[Record[0]],
>> +                                            /* size */ Record[1],
>> +                                            /* time */ Record[2]);
>> +
>> +        TopDiags.Files[Record[0]] = FE;
>> +        continue;
>> +      }
>> +
>> +      case serialized_diags::RECORD_SOURCE_RANGE: {
>> +        CXSourceRange SR;
>> +        if (readRange(TopDiags, Record, 0, SR))
>> +          return Failure;
>> +        D->Ranges.push_back(SR);
>> +        continue;
>> +      }
>> +
>> +      case serialized_diags::RECORD_FIXIT: {
>> +        CXSourceRange SR;
>> +        if (readRange(TopDiags, Record, 0, SR))
>> +          return Failure;
>> +        llvm::StringRef RetStr;
>> +        if (readString(TopDiags, RetStr, "FIXIT", Record, BlobStart, BlobLen))
>> +          return Failure;
>> +        D->FixIts.push_back(std::make_pair(SR, createCXString(RetStr, false)));
>> +        continue;
>> +      }
>> +
>> +      case serialized_diags::RECORD_DIAG: {
>> +        D->severity = Record[0];
>> +        unsigned offset = 1;
>> +        if (readLocation(TopDiags, Record, offset, D->DiagLoc))
>> +          return Failure;
>> +        D->category = Record[offset++];
>> +        unsigned diagFlag = Record[offset++];
>> +        D->DiagOption = diagFlag ? TopDiags.WarningFlags[diagFlag] : "";
>> +        D->Spelling = TopDiags.makeString(BlobStart, BlobLen);
>> +        continue;
>> +      }
>> +    }
>> +  }
>> +}
>> +
>> +extern "C" {
>> +CXDiagnosticSet clang_loadDiagnostics(const char *file,
>> +                                      enum CXLoadDiag_Error *error,
>> +                                      CXString *errorString) {
>> +  DiagLoader L(error, errorString);
>> +  return L.load(file);
>> +}
>> +} // end extern 'C'.
>>
>> Added: cfe/trunk/tools/libclang/CXLoadedDiagnostic.h
>> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/tools/libclang/CXLoadedDiagnostic.h?rev=144269&view=auto
>> ==============================================================================
>> --- cfe/trunk/tools/libclang/CXLoadedDiagnostic.h (added)
>> +++ cfe/trunk/tools/libclang/CXLoadedDiagnostic.h Thu Nov 10 02:43:12 2011
>> @@ -0,0 +1,90 @@
>> +/*===-- CXLoadedDiagnostic.h - Handling of persisent diags ------*- C++ -*-===*\
>> +|*                                                                            *|
>> +|*                     The LLVM Compiler Infrastructure                       *|
>> +|*                                                                            *|
>> +|* This file is distributed under the University of Illinois Open Source      *|
>> +|* License. See LICENSE.TXT for details.                                      *|
>> +|*                                                                            *|
>> +|*===----------------------------------------------------------------------===*|
>> +|*                                                                            *|
>> +|* Implements handling of persisent diagnostics.                              *|
>> +|*                                                                            *|
>> +\*===----------------------------------------------------------------------===*/
>> +
>> +#ifndef LLVM_CLANG_CINDEX_LOADED_DIAGNOSTIC_H
>> +#define LLVM_CLANG_CINDEX_LOADED_DIAGNOSTIC_H
>> +
>> +#include "CIndexDiagnostic.h"
>> +#include "llvm/ADT/StringRef.h"
>> +#include "clang/Basic/LLVM.h"
>> +#include <string>
>> +#include <vector>
>> +
>> +namespace clang {
>> +class CXLoadedDiagnostic : public CXDiagnosticImpl {
>> +public:
>> +  CXLoadedDiagnostic() : CXDiagnosticImpl(LoadedDiagnosticKind),
>> +    severity(0), category(0) {}
>> +
>> +  virtual ~CXLoadedDiagnostic();
>> +
>> +  /// \brief Return the severity of the diagnostic.
>> +  virtual CXDiagnosticSeverity getSeverity() const;
>> +
>> +  /// \brief Return the location of the diagnostic.
>> +  virtual CXSourceLocation getLocation() const;
>> +
>> +  /// \brief Return the spelling of the diagnostic.
>> +  virtual CXString getSpelling() const;
>> +
>> +  /// \brief Return the text for the diagnostic option.
>> +  virtual CXString getDiagnosticOption(CXString *Disable) const;
>> +
>> +  /// \brief Return the category of the diagnostic.
>> +  virtual unsigned getCategory() const;
>> +
>> +  /// \brief Return the number of source ranges for the diagnostic.
>> +  virtual unsigned getNumRanges() const;
>> +
>> +  /// \brief Return the source ranges for the diagnostic.
>> +  virtual CXSourceRange getRange(unsigned Range) const;
>> +
>> +  /// \brief Return the number of FixIts.
>> +  virtual unsigned getNumFixIts() const;
>> +
>> +  /// \brief Return the FixIt information (source range and inserted text).
>> +  virtual CXString getFixIt(unsigned FixIt,
>> +                            CXSourceRange *ReplacementRange) const;
>> +
>> +  static bool classof(const CXDiagnosticImpl *D) {
>> +    return D->getKind() == LoadedDiagnosticKind;
>> +  }
>> +
>> +  /// \brief Decode the CXSourceLocation into file, line, column, and offset.
>> +  static void decodeLocation(CXSourceLocation location,
>> +                             CXFile *file,
>> +                             unsigned *line,
>> +                             unsigned *column,
>> +                             unsigned *offset);
>> +
>> +  struct Location {
>> +    CXFile file;
>> +    unsigned line;
>> +    unsigned column;
>> +    unsigned offset;
>> +
>> +    Location() : line(0), column(0), offset(0) {}
>> +  };
>> +
>> +  Location DiagLoc;
>> +
>> +  std::vector<CXSourceRange> Ranges;
>> +  std::vector<std::pair<CXSourceRange, CXString> > FixIts;
>> +  llvm::StringRef Spelling;
>> +  llvm::StringRef DiagOption;
>> +  unsigned severity;
>> +  unsigned category;
>> +};
>> +}
>> +
>> +#endif
>>
>> Modified: cfe/trunk/tools/libclang/CXSourceLocation.cpp
>> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/tools/libclang/CXSourceLocation.cpp?rev=144269&r1=144268&r2=144269&view=diff
>> ==============================================================================
>> --- cfe/trunk/tools/libclang/CXSourceLocation.cpp (original)
>> +++ cfe/trunk/tools/libclang/CXSourceLocation.cpp Thu Nov 10 02:43:12 2011
>> @@ -17,6 +17,7 @@
>>  #include "CXString.h"
>>  #include "CXSourceLocation.h"
>>  #include "CXTranslationUnit.h"
>> +#include "CXLoadedDiagnostic.h"
>>
>>  using namespace clang;
>>  using namespace clang::cxstring;
>> @@ -54,6 +55,13 @@
>>  }
>>
>>  CXSourceRange clang_getRange(CXSourceLocation begin, CXSourceLocation end) {
>> +  if (!isASTUnitSourceLocation(begin)) {
>> +    if (isASTUnitSourceLocation(end))
>> +      return clang_getNullRange();
>> +    CXSourceRange Result = { { begin.ptr_data[0], end.ptr_data[0] }, 0, 0 };
>> +    return Result;
>> +  }
>> +
>>    if (begin.ptr_data[0] != end.ptr_data[0] ||
>>        begin.ptr_data[1] != end.ptr_data[1])
>>      return clang_getNullRange();
>> @@ -64,7 +72,6 @@
>>    return Result;
>>  }
>>
>> -
>>  unsigned clang_equalRanges(CXSourceRange range1, CXSourceRange range2) {
>>    return range1.ptr_data[0] == range2.ptr_data[0]
>>      && range1.ptr_data[1] == range2.ptr_data[1]
>> @@ -78,12 +85,24 @@
>>
>>
>>  CXSourceLocation clang_getRangeStart(CXSourceRange range) {
>> +  // Special decoding for CXSourceLocations for CXLoadedDiagnostics.
>> +  if ((uintptr_t)range.ptr_data[0] & 0x1) {
>> +    CXSourceLocation Result = { { range.ptr_data[0], 0 }, 0 };
>> +    return Result;
>> +  }
>> +
>>    CXSourceLocation Result = { { range.ptr_data[0], range.ptr_data[1] },
>>      range.begin_int_data };
>>    return Result;
>>  }
>>
>>  CXSourceLocation clang_getRangeEnd(CXSourceRange range) {
>> +  // Special decoding for CXSourceLocations for CXLoadedDiagnostics.
>> +  if ((uintptr_t)range.ptr_data[0] & 0x1) {
>> +    CXSourceLocation Result = { { range.ptr_data[1], 0 }, 0 };
>> +    return Result;
>> +  }
>> +
>>    CXSourceLocation Result = { { range.ptr_data[0], range.ptr_data[1] },
>>      range.end_int_data };
>>    return Result;
>> @@ -182,41 +201,40 @@
>>                                  unsigned *column,
>>                                  unsigned *offset) {
>>
>> -  if (isASTUnitSourceLocation(location)) {
>> -    SourceLocation Loc = SourceLocation::getFromRawEncoding(location.int_data);
>> -
>> -    if (!location.ptr_data[0] || Loc.isInvalid()) {
>> -      createNullLocation(file, line, column, offset);
>> -      return;
>> -    }
>> -
>> -    const SourceManager &SM =
>> -    *static_cast<const SourceManager*>(location.ptr_data[0]);
>> -    SourceLocation ExpansionLoc = SM.getExpansionLoc(Loc);
>> -
>> -    // Check that the FileID is invalid on the expansion location.
>> -    // This can manifest in invalid code.
>> -    FileID fileID = SM.getFileID(ExpansionLoc);
>> -    bool Invalid = false;
>> -    const SrcMgr::SLocEntry &sloc = SM.getSLocEntry(fileID, &Invalid);
>> -    if (Invalid || !sloc.isFile()) {
>> -      createNullLocation(file, line, column, offset);
>> -      return;
>> -    }
>> -
>> -    if (file)
>> -      *file = (void *)SM.getFileEntryForSLocEntry(sloc);
>> -    if (line)
>> -      *line = SM.getExpansionLineNumber(ExpansionLoc);
>> -    if (column)
>> -      *column = SM.getExpansionColumnNumber(ExpansionLoc);
>> -    if (offset)
>> -      *offset = SM.getDecomposedLoc(ExpansionLoc).second;
>> +  if (!isASTUnitSourceLocation(location)) {
>> +    CXLoadedDiagnostic::decodeLocation(location, file, line, column, offset);
>> +    return;
>> +  }
>> +
>> +  SourceLocation Loc = SourceLocation::getFromRawEncoding(location.int_data);
>> +
>> +  if (!location.ptr_data[0] || Loc.isInvalid()) {
>> +    createNullLocation(file, line, column, offset);
>> +    return;
>> +  }
>> +
>> +  const SourceManager &SM =
>> +  *static_cast<const SourceManager*>(location.ptr_data[0]);
>> +  SourceLocation ExpansionLoc = SM.getExpansionLoc(Loc);
>> +
>> +  // Check that the FileID is invalid on the expansion location.
>> +  // This can manifest in invalid code.
>> +  FileID fileID = SM.getFileID(ExpansionLoc);
>> +  bool Invalid = false;
>> +  const SrcMgr::SLocEntry &sloc = SM.getSLocEntry(fileID, &Invalid);
>> +  if (Invalid || !sloc.isFile()) {
>> +    createNullLocation(file, line, column, offset);
>>      return;
>>    }
>>
>> -  // FIXME:
>> -  createNullLocation(file, line, column, offset);
>> +  if (file)
>> +    *file = (void *)SM.getFileEntryForSLocEntry(sloc);
>> +  if (line)
>> +    *line = SM.getExpansionLineNumber(ExpansionLoc);
>> +  if (column)
>> +    *column = SM.getExpansionColumnNumber(ExpansionLoc);
>> +  if (offset)
>> +    *offset = SM.getDecomposedLoc(ExpansionLoc).second;
>>  }
>>
>>  void clang_getPresumedLocation(CXSourceLocation location,
>> @@ -224,28 +242,29 @@
>>                                 unsigned *line,
>>                                 unsigned *column) {
>>
>> -  if (isASTUnitSourceLocation(location)) {
>> -    SourceLocation Loc = SourceLocation::getFromRawEncoding(location.int_data);
>> -
>> -    if (!location.ptr_data[0] || Loc.isInvalid())
>> -      createNullLocation(filename, line, column);
>> -    else {
>> -      const SourceManager &SM =
>> -      *static_cast<const SourceManager*>(location.ptr_data[0]);
>> -      PresumedLoc PreLoc = SM.getPresumedLoc(Loc);
>> -
>> -      if (filename)
>> -        *filename = createCXString(PreLoc.getFilename());
>> -      if (line)
>> -        *line = PreLoc.getLine();
>> -      if (column)
>> -        *column = PreLoc.getColumn();
>> -    }
>> +  if (!isASTUnitSourceLocation(location)) {
>> +    // Other SourceLocation implementations do not support presumed locations
>> +    // at this time.
>> +    createNullLocation(filename, line, column);
>>      return;
>>    }
>> -
>> -  // FIXME:
>> -  createNullLocation(filename, line, column);
>> +
>> +  SourceLocation Loc = SourceLocation::getFromRawEncoding(location.int_data);
>> +
>> +  if (!location.ptr_data[0] || Loc.isInvalid())
>> +    createNullLocation(filename, line, column);
>> +  else {
>> +    const SourceManager &SM =
>> +    *static_cast<const SourceManager*>(location.ptr_data[0]);
>> +    PresumedLoc PreLoc = SM.getPresumedLoc(Loc);
>> +
>> +    if (filename)
>> +      *filename = createCXString(PreLoc.getFilename());
>> +    if (line)
>> +      *line = PreLoc.getLine();
>> +    if (column)
>> +      *column = PreLoc.getColumn();
>> +  }
>>  }
>>
>>  void clang_getInstantiationLocation(CXSourceLocation location,
>> @@ -263,44 +282,44 @@
>>                                 unsigned *column,
>>                                 unsigned *offset) {
>>
>> -  if (isASTUnitSourceLocation(location)) {
>> -    SourceLocation Loc = SourceLocation::getFromRawEncoding(location.int_data);
>> -
>> -    if (!location.ptr_data[0] || Loc.isInvalid())
>> -      return createNullLocation(file, line, column, offset);
>> -
>> -    const SourceManager &SM =
>> -    *static_cast<const SourceManager*>(location.ptr_data[0]);
>> -    SourceLocation SpellLoc = Loc;
>> -    if (SpellLoc.isMacroID()) {
>> -      SourceLocation SimpleSpellingLoc = SM.getImmediateSpellingLoc(SpellLoc);
>> -      if (SimpleSpellingLoc.isFileID() &&
>> -          SM.getFileEntryForID(SM.getDecomposedLoc(SimpleSpellingLoc).first))
>> -        SpellLoc = SimpleSpellingLoc;
>> -      else
>> -        SpellLoc = SM.getExpansionLoc(SpellLoc);
>> -    }
>> -
>> -    std::pair<FileID, unsigned> LocInfo = SM.getDecomposedLoc(SpellLoc);
>> -    FileID FID = LocInfo.first;
>> -    unsigned FileOffset = LocInfo.second;
>> -
>> -    if (FID.isInvalid())
>> -      return createNullLocation(file, line, column, offset);
>> -
>> -    if (file)
>> -      *file = (void *)SM.getFileEntryForID(FID);
>> -    if (line)
>> -      *line = SM.getLineNumber(FID, FileOffset);
>> -    if (column)
>> -      *column = SM.getColumnNumber(FID, FileOffset);
>> -    if (offset)
>> -      *offset = FileOffset;
>> +  if (!isASTUnitSourceLocation(location)) {
>> +    CXLoadedDiagnostic::decodeLocation(location, file, line,
>> +                                           column, offset);
>>      return;
>>    }
>> -
>> -  // FIXME:
>> -  createNullLocation(file, line, column, offset);
>> +
>> +  SourceLocation Loc = SourceLocation::getFromRawEncoding(location.int_data);
>> +
>> +  if (!location.ptr_data[0] || Loc.isInvalid())
>> +    return createNullLocation(file, line, column, offset);
>> +
>> +  const SourceManager &SM =
>> +  *static_cast<const SourceManager*>(location.ptr_data[0]);
>> +  SourceLocation SpellLoc = Loc;
>> +  if (SpellLoc.isMacroID()) {
>> +    SourceLocation SimpleSpellingLoc = SM.getImmediateSpellingLoc(SpellLoc);
>> +    if (SimpleSpellingLoc.isFileID() &&
>> +        SM.getFileEntryForID(SM.getDecomposedLoc(SimpleSpellingLoc).first))
>> +      SpellLoc = SimpleSpellingLoc;
>> +    else
>> +      SpellLoc = SM.getExpansionLoc(SpellLoc);
>> +  }
>> +
>> +  std::pair<FileID, unsigned> LocInfo = SM.getDecomposedLoc(SpellLoc);
>> +  FileID FID = LocInfo.first;
>> +  unsigned FileOffset = LocInfo.second;
>> +
>> +  if (FID.isInvalid())
>> +    return createNullLocation(file, line, column, offset);
>> +
>> +  if (file)
>> +    *file = (void *)SM.getFileEntryForID(FID);
>> +  if (line)
>> +    *line = SM.getLineNumber(FID, FileOffset);
>> +  if (column)
>> +    *column = SM.getColumnNumber(FID, FileOffset);
>> +  if (offset)
>> +    *offset = FileOffset;
>>  }
>>
>>  } // end extern "C"
>>
>> Modified: cfe/trunk/tools/libclang/CXStoredDiagnostic.cpp
>> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/tools/libclang/CXStoredDiagnostic.cpp?rev=144269&r1=144268&r2=144269&view=diff
>> ==============================================================================
>> --- cfe/trunk/tools/libclang/CXStoredDiagnostic.cpp (original)
>> +++ cfe/trunk/tools/libclang/CXStoredDiagnostic.cpp Thu Nov 10 02:43:12 2011
>> @@ -28,9 +28,6 @@
>>  using namespace clang::cxloc;
>>  using namespace clang::cxstring;
>>
>> -// Needed for vtable of CXPersisetntDiagnostic.
>> -CXDiagnosticImpl::~CXDiagnosticImpl() {}
>> -
>>  CXDiagnosticSeverity CXStoredDiagnostic::getSeverity() const {
>>    switch (Diag.getLevel()) {
>>      case DiagnosticsEngine::Ignored: return CXDiagnostic_Ignored;
>>
>> Modified: cfe/trunk/tools/libclang/CXTranslationUnit.h
>> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/tools/libclang/CXTranslationUnit.h?rev=144269&r1=144268&r2=144269&view=diff
>> ==============================================================================
>> --- cfe/trunk/tools/libclang/CXTranslationUnit.h (original)
>> +++ cfe/trunk/tools/libclang/CXTranslationUnit.h Thu Nov 10 02:43:12 2011
>> @@ -18,6 +18,7 @@
>>  struct CXTranslationUnitImpl {
>>    void *TUData;
>>    void *StringPool;
>> +  void *Diagnostics;
>>  };
>>  }
>>
>> @@ -27,7 +28,7 @@
>>  namespace cxtu {
>>
>>  CXTranslationUnitImpl *MakeCXTranslationUnit(ASTUnit *TU);
>> -
>> +
>>  class CXTUOwner {
>>    CXTranslationUnitImpl *TU;
>>
>>
>> Modified: cfe/trunk/tools/libclang/libclang.exports
>> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/tools/libclang/libclang.exports?rev=144269&r1=144268&r2=144269&view=diff
>> ==============================================================================
>> --- cfe/trunk/tools/libclang/libclang.exports (original)
>> +++ cfe/trunk/tools/libclang/libclang.exports Thu Nov 10 02:43:12 2011
>> @@ -32,6 +32,7 @@
>>  clang_disposeCXTUResourceUsage
>>  clang_disposeCodeCompleteResults
>>  clang_disposeDiagnostic
>> +clang_disposeDiagnosticSet
>>  clang_disposeIndex
>>  clang_disposeOverriddenCursors
>>  clang_disposeString
>> @@ -53,6 +54,7 @@
>>  clang_getCXXAccessSpecifier
>>  clang_getCanonicalCursor
>>  clang_getCanonicalType
>> +clang_getChildDiagnostics
>>  clang_getClangVersion
>>  clang_getCompletionAnnotation
>>  clang_getCompletionAvailability
>> @@ -86,6 +88,7 @@
>>  clang_getDiagnosticCategory
>>  clang_getDiagnosticCategoryName
>>  clang_getDiagnosticFixIt
>> +clang_getDiagnosticInSet
>>  clang_getDiagnosticLocation
>>  clang_getDiagnosticNumFixIts
>>  clang_getDiagnosticNumRanges
>> @@ -108,6 +111,7 @@
>>  clang_getNullRange
>>  clang_getNumCompletionChunks
>>  clang_getNumDiagnostics
>> +clang_getNumDiagnosticsInSet
>>  clang_getNumOverloadedDecls
>>  clang_getOverloadedDecl
>>  clang_getOverriddenCursors
>> @@ -150,6 +154,7 @@
>>  clang_isUnexposed
>>  clang_isVirtualBase
>>  clang_isVolatileQualifiedType
>> +clang_loadDiagnostics
>>  clang_parseTranslationUnit
>>  clang_remap_dispose
>>  clang_remap_getFilenames
>>
>>
>> _______________________________________________
>> cfe-commits mailing list
>> cfe-commits at cs.uiuc.edu
>> http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits




More information about the cfe-commits mailing list