r219649 - Revert "Frontend: Extract SerializedDiagnosticReader out of CXLoadedDiagnostic (NFC)"

Justin Bogner mail at justinbogner.com
Mon Oct 13 17:57:34 PDT 2014


Author: bogner
Date: Mon Oct 13 19:57:34 2014
New Revision: 219649

URL: http://llvm.org/viewvc/llvm-project?rev=219649&view=rev
Log:
Revert "Frontend: Extract SerializedDiagnosticReader out of CXLoadedDiagnostic (NFC)"

The bots can't seem to find an include file. Reverting for now and
I'll look into it in a bit.

This reverts commits r219647 and r219648.

Removed:
    cfe/trunk/include/clang/Frontend/SerializedDiagnosticReader.h
    cfe/trunk/include/clang/Frontend/SerializedDiagnostics.h
    cfe/trunk/lib/Frontend/SerializedDiagnosticReader.cpp
Modified:
    cfe/trunk/include/clang/Frontend/SerializedDiagnosticPrinter.h
    cfe/trunk/lib/Frontend/CMakeLists.txt
    cfe/trunk/lib/Frontend/SerializedDiagnosticPrinter.cpp
    cfe/trunk/tools/libclang/CXLoadedDiagnostic.cpp

Modified: cfe/trunk/include/clang/Frontend/SerializedDiagnosticPrinter.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Frontend/SerializedDiagnosticPrinter.h?rev=219649&r1=219648&r2=219649&view=diff
==============================================================================
--- cfe/trunk/include/clang/Frontend/SerializedDiagnosticPrinter.h (original)
+++ cfe/trunk/include/clang/Frontend/SerializedDiagnosticPrinter.h Mon Oct 13 19:57:34 2014
@@ -11,7 +11,6 @@
 #define LLVM_CLANG_FRONTEND_SERIALIZEDDIAGNOSTICPRINTER_H
 
 #include "clang/Basic/LLVM.h"
-#include "clang/Frontend/SerializedDiagnostics.h"
 #include "llvm/Bitcode/BitstreamWriter.h"
 
 namespace llvm {
@@ -24,6 +23,41 @@ class DiagnosticsEngine;
 class DiagnosticOptions;
 
 namespace serialized_diags {
+  
+enum BlockIDs {
+  /// \brief A top-level block which represents any meta data associated
+  /// with the diagostics, including versioning of the format.
+  BLOCK_META = llvm::bitc::FIRST_APPLICATION_BLOCKID,
+
+  /// \brief The this block acts as a container for all the information
+  /// for a specific diagnostic.
+  BLOCK_DIAG
+};
+
+enum RecordIDs {
+  RECORD_VERSION = 1,
+  RECORD_DIAG,
+  RECORD_SOURCE_RANGE,
+  RECORD_DIAG_FLAG,
+  RECORD_CATEGORY,
+  RECORD_FILENAME,
+  RECORD_FIXIT,
+  RECORD_FIRST = RECORD_VERSION,
+  RECORD_LAST = RECORD_FIXIT
+};
+
+/// A stable version of DiagnosticIDs::Level.
+///
+/// Do not change the order of values in this enum, and please increment the
+/// serialized diagnostics version number when you add to it.
+enum Level {
+  Ignored = 0,
+  Note,
+  Warning,
+  Error,
+  Fatal,
+  Remark
+};
 
 /// \brief Returns a DiagnosticConsumer that serializes diagnostics to
 ///  a bitcode file.

Removed: cfe/trunk/include/clang/Frontend/SerializedDiagnosticReader.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Frontend/SerializedDiagnosticReader.h?rev=219648&view=auto
==============================================================================
--- cfe/trunk/include/clang/Frontend/SerializedDiagnosticReader.h (original)
+++ cfe/trunk/include/clang/Frontend/SerializedDiagnosticReader.h (removed)
@@ -1,131 +0,0 @@
-//===--- SerializedDiagnosticReader.h - Reads diagnostics -------*- C++ -*-===//
-//
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef LLVM_CLANG_FRONTEND_SERIALIZED_DIAGNOSTIC_READER_H_
-#define LLVM_CLANG_FRONTEND_SERIALIZED_DIAGNOSTIC_READER_H_
-
-#include "clang/Basic/LLVM.h"
-#include "llvm/ADT/ArrayRef.h"
-#include "llvm/Bitcode/BitstreamReader.h"
-#include "llvm/Support/ErrorOr.h"
-
-namespace clang {
-namespace serialized_diags {
-
-enum class SDError {
-  CouldNotLoad = 1,
-  InvalidSignature,
-  InvalidDiagnostics,
-  MalformedTopLevelBlock,
-  MalformedSubBlock,
-  MalformedBlockInfoBlock,
-  MalformedMetadataBlock,
-  MalformedDiagnosticBlock,
-  MalformedDiagnosticRecord,
-  MissingVersion,
-  VersionMismatch,
-  UnsupportedConstruct,
-  /// A generic error for subclass handlers that don't want or need to define
-  /// their own error_category.
-  HandlerFailed
-};
-
-const std::error_category &SDErrorCategory();
-
-inline std::error_code make_error_code(SDError E) {
-  return std::error_code(static_cast<int>(E), SDErrorCategory());
-}
-
-/// \brief A location that is represented in the serialized diagnostics.
-struct Location {
-  unsigned FileID;
-  unsigned Line;
-  unsigned Col;
-  unsigned Offset;
-  Location(unsigned FileID, unsigned Line, unsigned Col, unsigned Offset)
-      : FileID(FileID), Line(Line), Col(Col), Offset(Offset) {}
-};
-
-/// \brief A base class that handles reading serialized diagnostics from a file.
-///
-/// Subclasses should override the visit* methods with their logic for handling
-/// the various constructs that are found in serialized diagnostics.
-class SerializedDiagnosticReader {
-public:
-  SerializedDiagnosticReader() {}
-  virtual ~SerializedDiagnosticReader() {}
-
-  /// \brief Read the diagnostics in \c File
-  std::error_code readDiagnostics(StringRef File);
-
-private:
-  enum class Cursor;
-
-  /// \brief Read to the next record or block to process.
-  llvm::ErrorOr<Cursor> skipUntilRecordOrBlock(llvm::BitstreamCursor &Stream,
-                                               unsigned &BlockOrRecordId);
-
-  /// \brief Read a metadata block from \c Stream.
-  std::error_code readMetaBlock(llvm::BitstreamCursor &Stream);
-
-  /// \brief Read a diagnostic block from \c Stream.
-  std::error_code readDiagnosticBlock(llvm::BitstreamCursor &Stream);
-
-protected:
-  /// \brief Visit the start of a diagnostic block.
-  virtual std::error_code visitStartOfDiagnostic() {
-    return std::error_code();
-  };
-  /// \brief Visit the end of a diagnostic block.
-  virtual std::error_code visitEndOfDiagnostic() { return std::error_code(); };
-  /// \brief Visit a category. This associates the category \c ID to a \c Name.
-  virtual std::error_code visitCategoryRecord(unsigned ID, StringRef Name) {
-    return std::error_code();
-  };
-  /// \brief Visit a flag. This associates the flag's \c ID to a \c Name.
-  virtual std::error_code visitDiagFlagRecord(unsigned ID, StringRef Name) {
-    return std::error_code();
-  };
-  /// \brief Visit a diagnostic.
-  virtual std::error_code
-  visitDiagnosticRecord(unsigned Severity, const Location &Location,
-                        unsigned Category, unsigned Flag, StringRef Message) {
-    return std::error_code();
-  };
-  /// \brief Visit a filename. This associates the file's \c ID to a \c Name.
-  virtual std::error_code visitFilenameRecord(unsigned ID, unsigned Size,
-                                              unsigned Timestamp,
-                                              StringRef Name) {
-    return std::error_code();
-  };
-  /// \brief Visit a fixit hint.
-  virtual std::error_code
-  visitFixitRecord(const Location &Start, const Location &End, StringRef Text) {
-    return std::error_code();
-  };
-  /// \brief Visit a source range.
-  virtual std::error_code visitSourceRangeRecord(const Location &Start,
-                                                 const Location &End) {
-    return std::error_code();
-  };
-  /// \brief Visit the version of the set of diagnostics.
-  virtual std::error_code visitVersionRecord(unsigned Version) {
-    return std::error_code();
-  };
-};
-
-} // end serialized_diags namespace
-} // end clang namespace
-
-namespace std {
-template <>
-struct is_error_code_enum<clang::serialized_diags::SDError> : std::true_type {};
-}
-
-#endif

Removed: cfe/trunk/include/clang/Frontend/SerializedDiagnostics.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Frontend/SerializedDiagnostics.h?rev=219648&view=auto
==============================================================================
--- cfe/trunk/include/clang/Frontend/SerializedDiagnostics.h (original)
+++ cfe/trunk/include/clang/Frontend/SerializedDiagnostics.h (removed)
@@ -1,59 +0,0 @@
-//===--- SerializedDiagnostics.h - Common data for serialized diagnostics -===//
-//
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef LLVM_CLANG_FRONTEND_SERIALIZE_DIAGNOSTICS_H_
-#define LLVM_CLANG_FRONTEND_SERIALIZE_DIAGNOSTICS_H_
-
-#include "llvm/BitCode/BitCodes.h"
-
-namespace clang {
-namespace serialized_diags {
-
-enum BlockIDs {
-  /// \brief A top-level block which represents any meta data associated
-  /// with the diagostics, including versioning of the format.
-  BLOCK_META = llvm::bitc::FIRST_APPLICATION_BLOCKID,
-
-  /// \brief The this block acts as a container for all the information
-  /// for a specific diagnostic.
-  BLOCK_DIAG
-};
-
-enum RecordIDs {
-  RECORD_VERSION = 1,
-  RECORD_DIAG,
-  RECORD_SOURCE_RANGE,
-  RECORD_DIAG_FLAG,
-  RECORD_CATEGORY,
-  RECORD_FILENAME,
-  RECORD_FIXIT,
-  RECORD_FIRST = RECORD_VERSION,
-  RECORD_LAST = RECORD_FIXIT
-};
-
-/// \brief A stable version of DiagnosticIDs::Level.
-///
-/// Do not change the order of values in this enum, and please increment the
-/// serialized diagnostics version number when you add to it.
-enum Level {
-  Ignored = 0,
-  Note,
-  Warning,
-  Error,
-  Fatal,
-  Remark
-};
-
-/// \brief The serialized diagnostics version number.
-enum { VersionNumber = 2 };
-
-} // end serialized_diags namespace
-} // end clang namespace
-
-#endif

Modified: cfe/trunk/lib/Frontend/CMakeLists.txt
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Frontend/CMakeLists.txt?rev=219649&r1=219648&r2=219649&view=diff
==============================================================================
--- cfe/trunk/lib/Frontend/CMakeLists.txt (original)
+++ cfe/trunk/lib/Frontend/CMakeLists.txt Mon Oct 13 19:57:34 2014
@@ -1,7 +1,6 @@
 add_subdirectory(Rewrite)
 
 set(LLVM_LINK_COMPONENTS
-  BitReader
   Option
   Support
   )
@@ -32,7 +31,6 @@ add_clang_library(clangFrontend
   MultiplexConsumer.cpp
   PrintPreprocessedOutput.cpp
   SerializedDiagnosticPrinter.cpp
-  SerializedDiagnosticReader.cpp
   TextDiagnostic.cpp
   TextDiagnosticBuffer.cpp
   TextDiagnosticPrinter.cpp

Modified: cfe/trunk/lib/Frontend/SerializedDiagnosticPrinter.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Frontend/SerializedDiagnosticPrinter.cpp?rev=219649&r1=219648&r2=219649&view=diff
==============================================================================
--- cfe/trunk/lib/Frontend/SerializedDiagnosticPrinter.cpp (original)
+++ cfe/trunk/lib/Frontend/SerializedDiagnosticPrinter.cpp Mon Oct 13 19:57:34 2014
@@ -8,7 +8,6 @@
 //===----------------------------------------------------------------------===//
 
 #include "clang/Frontend/SerializedDiagnosticPrinter.h"
-#include "clang/Frontend/SerializedDiagnostics.h"
 #include "clang/Basic/Diagnostic.h"
 #include "clang/Basic/DiagnosticOptions.h"
 #include "clang/Basic/FileManager.h"
@@ -173,6 +172,9 @@ private:
   void AddCharSourceRangeToRecord(CharSourceRange R, RecordDataImpl &Record,
                                   const SourceManager &SM);
 
+  /// \brief The version of the diagnostics file.
+  enum { Version = 2 };
+
   /// \brief Language options, which can differ from one clone of this client
   /// to another.
   const LangOptions *LangOpts;
@@ -464,7 +466,7 @@ void SDiagsWriter::EmitMetaBlock() {
   Stream.EnterSubblock(BLOCK_META, 3);
   Record.clear();
   Record.push_back(RECORD_VERSION);
-  Record.push_back(VersionNumber);
+  Record.push_back(Version);
   Stream.EmitRecordWithAbbrev(Abbrevs.get(RECORD_VERSION), Record);  
   Stream.ExitBlock();
 }

Removed: cfe/trunk/lib/Frontend/SerializedDiagnosticReader.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Frontend/SerializedDiagnosticReader.cpp?rev=219648&view=auto
==============================================================================
--- cfe/trunk/lib/Frontend/SerializedDiagnosticReader.cpp (original)
+++ cfe/trunk/lib/Frontend/SerializedDiagnosticReader.cpp (removed)
@@ -1,296 +0,0 @@
-//===--- SerializedDiagnosticReader.cpp - Reads diagnostics ---------------===//
-//
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-
-#include "clang/Frontend/SerializedDiagnosticReader.h"
-#include "clang/Frontend/SerializedDiagnostics.h"
-#include "clang/Basic/FileManager.h"
-#include "llvm/Support/ManagedStatic.h"
-#include "llvm/Support/MemoryBuffer.h"
-
-using namespace clang;
-using namespace clang::serialized_diags;
-
-std::error_code SerializedDiagnosticReader::readDiagnostics(StringRef File) {
-  // Open the diagnostics file.
-  FileSystemOptions FO;
-  FileManager FileMgr(FO);
-
-  std::unique_ptr<llvm::MemoryBuffer> Buffer = FileMgr.getBufferForFile(File);
-  if (!Buffer)
-    return SDError::CouldNotLoad;
-
-  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')
-    return SDError::InvalidSignature;
-
-  // Read the top level blocks.
-  while (!Stream.AtEndOfStream()) {
-    if (Stream.ReadCode() != llvm::bitc::ENTER_SUBBLOCK)
-      return SDError::InvalidDiagnostics;
-
-    std::error_code EC;
-    switch (Stream.ReadSubBlockID()) {
-    case llvm::bitc::BLOCKINFO_BLOCK_ID:
-      if (Stream.ReadBlockInfoBlock())
-        return SDError::MalformedBlockInfoBlock;
-      continue;
-    case BLOCK_META:
-      if ((EC = readMetaBlock(Stream)))
-        return EC;
-      continue;
-    case BLOCK_DIAG:
-      if ((EC = readDiagnosticBlock(Stream)))
-        return EC;
-      continue;
-    default:
-      if (!Stream.SkipBlock())
-        return SDError::MalformedTopLevelBlock;
-      continue;
-    }
-  }
-  return std::error_code();
-}
-
-enum class SerializedDiagnosticReader::Cursor {
-  Record = 1,
-  BlockEnd,
-  BlockBegin
-};
-
-llvm::ErrorOr<SerializedDiagnosticReader::Cursor>
-SerializedDiagnosticReader::skipUntilRecordOrBlock(
-    llvm::BitstreamCursor &Stream, unsigned &BlockOrRecordID) {
-  BlockOrRecordID = 0;
-
-  while (!Stream.AtEndOfStream()) {
-    unsigned Code = Stream.ReadCode();
-
-    switch ((llvm::bitc::FixedAbbrevIDs)Code) {
-    case llvm::bitc::ENTER_SUBBLOCK:
-      BlockOrRecordID = Stream.ReadSubBlockID();
-      return Cursor::BlockBegin;
-
-    case llvm::bitc::END_BLOCK:
-      if (Stream.ReadBlockEnd())
-        return SDError::InvalidDiagnostics;
-      return Cursor::BlockEnd;
-
-    case llvm::bitc::DEFINE_ABBREV:
-      Stream.ReadAbbrevRecord();
-      continue;
-
-    case llvm::bitc::UNABBREV_RECORD:
-      return SDError::UnsupportedConstruct;
-
-    default:
-      // We found a record.
-      BlockOrRecordID = Code;
-      return Cursor::Record;
-    }
-  }
-
-  return SDError::InvalidDiagnostics;
-}
-
-std::error_code
-SerializedDiagnosticReader::readMetaBlock(llvm::BitstreamCursor &Stream) {
-  if (Stream.EnterSubBlock(clang::serialized_diags::BLOCK_META))
-    return SDError::MalformedMetadataBlock;
-
-  bool VersionChecked = false;
-
-  while (true) {
-    unsigned BlockOrCode = 0;
-    llvm::ErrorOr<Cursor> Res = skipUntilRecordOrBlock(Stream, BlockOrCode);
-    if (!Res)
-      Res.getError();
-
-    switch (Res.get()) {
-    case Cursor::Record:
-      break;
-    case Cursor::BlockBegin:
-      if (Stream.SkipBlock())
-        return SDError::MalformedMetadataBlock;
-    case Cursor::BlockEnd:
-      if (!VersionChecked)
-        return SDError::MissingVersion;
-      return std::error_code();
-    }
-
-    SmallVector<uint64_t, 1> Record;
-    unsigned RecordID = Stream.readRecord(BlockOrCode, Record);
-
-    if (RecordID == RECORD_VERSION) {
-      if (Record.size() < 1)
-        return SDError::MissingVersion;
-      if (Record[0] > VersionNumber)
-        return SDError::VersionMismatch;
-      VersionChecked = true;
-    }
-  }
-}
-
-std::error_code
-SerializedDiagnosticReader::readDiagnosticBlock(llvm::BitstreamCursor &Stream) {
-  if (Stream.EnterSubBlock(clang::serialized_diags::BLOCK_DIAG))
-    return SDError::MalformedDiagnosticBlock;
-
-  std::error_code EC;
-  if ((EC = visitStartOfDiagnostic()))
-    return EC;
-
-  SmallVector<uint64_t, 16> Record;
-  while (true) {
-    unsigned BlockOrCode = 0;
-    llvm::ErrorOr<Cursor> Res = skipUntilRecordOrBlock(Stream, BlockOrCode);
-    if (!Res)
-      Res.getError();
-
-    switch (Res.get()) {
-    case Cursor::BlockBegin:
-      // The only blocks we care about are subdiagnostics.
-      if (BlockOrCode == serialized_diags::BLOCK_DIAG) {
-        if ((EC = readDiagnosticBlock(Stream)))
-          return EC;
-      } else if (!Stream.SkipBlock())
-        return SDError::MalformedSubBlock;
-      continue;
-    case Cursor::BlockEnd:
-      if ((EC = visitEndOfDiagnostic()))
-        return EC;
-      return std::error_code();
-    case Cursor::Record:
-      break;
-    }
-
-    // Read the record.
-    Record.clear();
-    StringRef Blob;
-    unsigned RecID = Stream.readRecord(BlockOrCode, Record, &Blob);
-
-    if (RecID < serialized_diags::RECORD_FIRST ||
-        RecID > serialized_diags::RECORD_LAST)
-      continue;
-
-    switch ((RecordIDs)RecID) {
-    case RECORD_CATEGORY:
-      // A category has ID and name size.
-      if (Record.size() != 2)
-        return SDError::MalformedDiagnosticRecord;
-      if ((EC = visitCategoryRecord(Record[0], Blob)))
-        return EC;
-      continue;
-    case RECORD_DIAG:
-      // A diagnostic has severity, location (4), category, flag, and message
-      // size.
-      if (Record.size() != 8)
-        return SDError::MalformedDiagnosticRecord;
-      if ((EC = visitDiagnosticRecord(
-               Record[0], Location(Record[1], Record[2], Record[3], Record[4]),
-               Record[5], Record[6], Blob)))
-        return EC;
-      continue;
-    case RECORD_DIAG_FLAG:
-      // A diagnostic flag has ID and name size.
-      if (Record.size() != 2)
-        return SDError::MalformedDiagnosticRecord;
-      if ((EC = visitDiagFlagRecord(Record[0], Blob)))
-        return EC;
-      continue;
-    case RECORD_FILENAME:
-      // A filename has ID, size, timestamp, and name size. The size and
-      // timestamp are legacy fields that are always zero these days.
-      if (Record.size() != 4)
-        return SDError::MalformedDiagnosticRecord;
-      if ((EC = visitFilenameRecord(Record[0], Record[1], Record[2], Blob)))
-        return EC;
-      continue;
-    case RECORD_FIXIT:
-      // A fixit has two locations (4 each) and message size.
-      if (Record.size() != 9)
-        return SDError::MalformedDiagnosticRecord;
-      if ((EC = visitFixitRecord(
-               Location(Record[0], Record[1], Record[2], Record[3]),
-               Location(Record[4], Record[5], Record[6], Record[7]), Blob)))
-        return EC;
-      continue;
-    case RECORD_SOURCE_RANGE:
-      // A source range is two locations (4 each).
-      if (Record.size() != 8)
-        return SDError::MalformedDiagnosticRecord;
-      if ((EC = visitSourceRangeRecord(
-               Location(Record[0], Record[1], Record[2], Record[3]),
-               Location(Record[4], Record[5], Record[6], Record[7]))))
-        return EC;
-      continue;
-    case RECORD_VERSION:
-      // A version is just a number.
-      if (Record.size() != 1)
-        return SDError::MalformedDiagnosticRecord;
-      if ((EC = visitVersionRecord(Record[0])))
-        return EC;
-      continue;
-    }
-  }
-}
-
-namespace {
-class SDErrorCategoryType final : public std::error_category {
-  const char *name() const LLVM_NOEXCEPT override {
-    return "clang.serialized_diags";
-  }
-  std::string message(int IE) const override {
-    SDError E = static_cast<SDError>(IE);
-    switch (E) {
-    case SDError::CouldNotLoad:
-      return "Failed to open diagnostics file";
-    case SDError::InvalidSignature:
-      return "Invalid diagnostics signature";
-    case SDError::InvalidDiagnostics:
-      return "Parse error reading diagnostics";
-    case SDError::MalformedTopLevelBlock:
-      return "Malformed block at top-level of diagnostics";
-    case SDError::MalformedSubBlock:
-      return "Malformed sub-block in a diagnostic";
-    case SDError::MalformedBlockInfoBlock:
-      return "Malformed BlockInfo block";
-    case SDError::MalformedMetadataBlock:
-      return "Malformed Metadata block";
-    case SDError::MalformedDiagnosticBlock:
-      return "Malformed Diagnostic block";
-    case SDError::MalformedDiagnosticRecord:
-      return "Malformed Diagnostic record";
-    case SDError::MissingVersion:
-      return "No version provided in diagnostics";
-    case SDError::VersionMismatch:
-      return "Unsupported diagnostics version";
-    case SDError::UnsupportedConstruct:
-      return "Bitcode constructs that are not supported in diagnostics appear";
-    case SDError::HandlerFailed:
-      return "Generic error occurred while handling a record";
-    }
-    llvm_unreachable("Unknown error type!");
-  }
-};
-}
-
-static llvm::ManagedStatic<SDErrorCategoryType> ErrorCategory;
-const std::error_category &clang::serialized_diags::SDErrorCategory() {
-  return *ErrorCategory;
-}

Modified: cfe/trunk/tools/libclang/CXLoadedDiagnostic.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/tools/libclang/CXLoadedDiagnostic.cpp?rev=219649&r1=219648&r2=219649&view=diff
==============================================================================
--- cfe/trunk/tools/libclang/CXLoadedDiagnostic.cpp (original)
+++ cfe/trunk/tools/libclang/CXLoadedDiagnostic.cpp Mon Oct 13 19:57:34 2014
@@ -16,8 +16,7 @@
 #include "clang/Basic/Diagnostic.h"
 #include "clang/Basic/FileManager.h"
 #include "clang/Basic/LLVM.h"
-#include "clang/Frontend/SerializedDiagnostics.h"
-#include "clang/Frontend/SerializedDiagnosticReader.h"
+#include "clang/Frontend/SerializedDiagnosticPrinter.h"
 #include "llvm/ADT/Optional.h"
 #include "llvm/ADT/StringRef.h"
 #include "llvm/ADT/Twine.h"
@@ -184,207 +183,475 @@ void CXLoadedDiagnostic::decodeLocation(
 // Deserialize diagnostics.
 //===----------------------------------------------------------------------===//
 
+enum { MaxSupportedVersion = 2 };
+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 : serialized_diags::SerializedDiagnosticReader {
+class DiagLoader {
   enum CXLoadDiag_Error *error;
   CXString *errorString;
-  std::unique_ptr<CXLoadedDiagnosticSetImpl> TopDiags;
-  SmallVector<std::unique_ptr<CXLoadedDiagnostic>, 8> CurrentDiags;
-
-  std::error_code reportBad(enum CXLoadDiag_Error code, llvm::StringRef err) {
+  
+  void reportBad(enum CXLoadDiag_Error code, llvm::StringRef err) {
     if (error)
       *error = code;
     if (errorString)
       *errorString = cxstring::createDup(err);
-    return serialized_diags::SDError::HandlerFailed;
   }
   
-  std::error_code reportInvalidFile(llvm::StringRef err) {
+  void reportInvalidFile(llvm::StringRef err) {
     return reportBad(CXLoadDiag_InvalidFile, err);
   }
 
-  std::error_code readRange(const serialized_diags::Location &SDStart,
-                            const serialized_diags::Location &SDEnd,
-                            CXSourceRange &SR);
+  LoadResult readMetaBlock(llvm::BitstreamCursor &Stream);
+  
+  LoadResult readDiagnosticBlock(llvm::BitstreamCursor &Stream,
+                                 CXDiagnosticSetImpl &Diags,
+                                 CXLoadedDiagnosticSetImpl &TopDiags);
+
+  StreamResult readToNextRecordOrBlock(llvm::BitstreamCursor &Stream,
+                                       llvm::StringRef errorContext,
+                                       unsigned &BlockOrRecordID,
+                                       bool atTopLevel = false);
+  
+  
+  LoadResult readString(CXLoadedDiagnosticSetImpl &TopDiags,
+                        Strings &strings, llvm::StringRef errorContext,
+                        RecordData &Record,
+                        StringRef Blob,
+                        bool allowEmptyString = false);
+
+  LoadResult readString(CXLoadedDiagnosticSetImpl &TopDiags,
+                        const char *&RetStr,
+                        llvm::StringRef errorContext,
+                        RecordData &Record,
+                        StringRef Blob,
+                        bool allowEmptyString = false);
+
+  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 = cxstring::createEmpty();
+    }
 
-  std::error_code readLocation(const serialized_diags::Location &SDLoc,
-                               CXLoadedDiagnostic::Location &LoadedLoc);
+  CXDiagnosticSet load(const char *file);
+};
+}
 
-protected:
-  std::error_code visitStartOfDiagnostic() override;
-  std::error_code visitEndOfDiagnostic() override;
+CXDiagnosticSet DiagLoader::load(const char *file) {
+  // Open the diagnostics file.
+  std::string ErrStr;
+  FileSystemOptions FO;
+  FileManager FileMgr(FO);
 
-  std::error_code visitCategoryRecord(unsigned ID, StringRef Name) override;
+  std::unique_ptr<llvm::MemoryBuffer> Buffer = FileMgr.getBufferForFile(file);
+  if (!Buffer) {
+    reportBad(CXLoadDiag_CannotLoad, ErrStr);
+    return nullptr;
+  }
 
-  std::error_code visitDiagFlagRecord(unsigned ID, StringRef Name) override;
+  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 nullptr;
+  }
 
-  std::error_code visitDiagnosticRecord(
-      unsigned Severity, const serialized_diags::Location &Location,
-      unsigned Category, unsigned Flag, StringRef Message) override;
+  std::unique_ptr<CXLoadedDiagnosticSetImpl> Diags(
+      new CXLoadedDiagnosticSetImpl());
 
-  std::error_code visitFilenameRecord(unsigned ID, unsigned Size,
-                                      unsigned Timestamp,
-                                      StringRef Name) override;
+  while (true) {
+    unsigned BlockID = 0;
+    StreamResult Res = readToNextRecordOrBlock(Stream, "Top-level", 
+                                               BlockID, true);
+    switch (Res) {
+      case Read_EndOfStream:
+        return (CXDiagnosticSet)Diags.release();
+      case Read_Failure:
+        return nullptr;
+      case Read_Record:
+        llvm_unreachable("Top-level does not have records");
+      case Read_BlockEnd:
+        continue;
+      case Read_BlockBegin:
+        break;
+    }
+    
+    switch (BlockID) {
+      case serialized_diags::BLOCK_META:
+        if (readMetaBlock(Stream))
+          return nullptr;
+        break;
+      case serialized_diags::BLOCK_DIAG:
+        if (readDiagnosticBlock(Stream, *Diags.get(), *Diags.get()))
+          return nullptr;
+        break;
+      default:
+        if (!Stream.SkipBlock()) {
+          reportInvalidFile("Malformed block at top-level of diagnostics file");
+          return nullptr;
+        }
+        break;
+    }
+  }
+}
 
-  std::error_code visitFixitRecord(const serialized_diags::Location &Start,
-                                   const serialized_diags::Location &End,
-                                   StringRef CodeToInsert) override;
+StreamResult DiagLoader::readToNextRecordOrBlock(llvm::BitstreamCursor &Stream,
+                                                 llvm::StringRef errorContext,
+                                                 unsigned &blockOrRecordID,
+                                                 bool atTopLevel) {
+  
+  blockOrRecordID = 0;
 
-  std::error_code
-  visitSourceRangeRecord(const serialized_diags::Location &Start,
-                         const serialized_diags::Location &End) override;
+  while (!Stream.AtEndOfStream()) {
+    unsigned Code = Stream.ReadCode();
 
-public:
-  DiagLoader(enum CXLoadDiag_Error *e, CXString *es)
-      : SerializedDiagnosticReader(), error(e), errorString(es) {
-    if (error)
-      *error = CXLoadDiag_None;
-    if (errorString)
-      *errorString = cxstring::createEmpty();
+    // 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;
+    }
   }
-
-  CXDiagnosticSet load(const char *file);
-};
+  
+  if (atTopLevel)
+    return Read_EndOfStream;
+  
+  reportInvalidFile(Twine("Premature end of diagnostics file within ").str() + 
+                    errorContext.str());
+  return Read_Failure;
 }
 
-CXDiagnosticSet DiagLoader::load(const char *file) {
-  TopDiags = llvm::make_unique<CXLoadedDiagnosticSetImpl>();
+LoadResult DiagLoader::readMetaBlock(llvm::BitstreamCursor &Stream) {
+  if (Stream.EnterSubBlock(clang::serialized_diags::BLOCK_META)) {
+    reportInvalidFile("Malformed metadata block");
+    return Failure;
+  }
 
-  std::error_code EC = readDiagnostics(file);
-  if (EC) {
-    switch (EC.value()) {
-    case static_cast<int>(serialized_diags::SDError::HandlerFailed):
-      // We've already reported the problem.
-      break;
-    case static_cast<int>(serialized_diags::SDError::CouldNotLoad):
-      reportBad(CXLoadDiag_CannotLoad, EC.message());
-      break;
-    default:
-      reportInvalidFile(EC.message());
-      break;
+  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;
+    unsigned recordID = Stream.readRecord(blockOrCode, Record);
+    
+    if (recordID == serialized_diags::RECORD_VERSION) {
+      if (Record.size() < 1) {
+        reportInvalidFile("malformed VERSION identifier in diagnostics file");
+        return Failure;
+      }
+      if (Record[0] > MaxSupportedVersion) {
+        reportInvalidFile("diagnostics file is a newer version than the one "
+                          "supported");
+        return Failure;
+      }
+      versionChecked = true;
     }
-    return 0;
+  }
+}
+
+LoadResult DiagLoader::readString(CXLoadedDiagnosticSetImpl &TopDiags,
+                                  const char *&RetStr,
+                                  llvm::StringRef errorContext,
+                                  RecordData &Record,
+                                  StringRef Blob,
+                                  bool allowEmptyString) {
+  
+  // Basic buffer overflow check.
+  if (Blob.size() > 65536) {
+    reportInvalidFile(std::string("Out-of-bounds string in ") +
+                      std::string(errorContext));
+    return Failure;
   }
 
-  return (CXDiagnosticSet)TopDiags.release();
+  if (allowEmptyString && Record.size() >= 1 && Blob.size() == 0) {
+    RetStr = "";
+    return Success;
+  }
+  
+  if (Record.size() < 1 || Blob.size() == 0) {
+    reportInvalidFile(std::string("Corrupted ") + std::string(errorContext)
+                      + std::string(" entry"));
+    return Failure;
+  }
+  
+  RetStr = TopDiags.copyString(Blob);
+  return Success;
 }
 
-std::error_code
-DiagLoader::readLocation(const serialized_diags::Location &SDLoc,
-                         CXLoadedDiagnostic::Location &LoadedLoc) {
-  unsigned FileID = SDLoc.FileID;
-  if (FileID == 0)
-    LoadedLoc.file = nullptr;
-  else {
-    LoadedLoc.file = const_cast<FileEntry *>(TopDiags->Files[FileID]);
-    if (!LoadedLoc.file)
-      return reportInvalidFile("Corrupted file entry in source location");
+LoadResult DiagLoader::readString(CXLoadedDiagnosticSetImpl &TopDiags,
+                                  Strings &strings,
+                                  llvm::StringRef errorContext,
+                                  RecordData &Record,
+                                  StringRef Blob,
+                                  bool allowEmptyString) {
+  const char *RetStr;
+  if (readString(TopDiags, RetStr, errorContext, Record, Blob,
+                 allowEmptyString))
+    return Failure;
+  strings[Record[0]] = RetStr;
+  return Success;
+}
+
+LoadResult DiagLoader::readLocation(CXLoadedDiagnosticSetImpl &TopDiags,
+                                    RecordData &Record, unsigned &offset,
+                                    CXLoadedDiagnostic::Location &Loc) {
+  if (Record.size() < offset + 4) {
+    reportInvalidFile("Corrupted source location");
+    return Failure;
+  }
+  auto Fields = makeArrayRef(Record).slice(offset);
+  offset += 4;
+  
+  unsigned fileID = Fields[0];
+  if (fileID == 0) {
+    // Sentinel value.
+    Loc.file = nullptr;
+    Loc.line = 0;
+    Loc.column = 0;
+    Loc.offset = 0;
+    return Success;
   }
-  LoadedLoc.line = SDLoc.Line;
-  LoadedLoc.column = SDLoc.Col;
-  LoadedLoc.offset = SDLoc.Offset;
-  return std::error_code();
+
+  const FileEntry *FE = TopDiags.Files[fileID];
+  if (!FE) {
+    reportInvalidFile("Corrupted file entry in source location");
+    return Failure;
+  }
+  Loc.file = const_cast<FileEntry *>(FE);
+  Loc.line = Fields[1];
+  Loc.column = Fields[2];
+  Loc.offset = Fields[3];
+  return Success;
 }
 
-std::error_code
-DiagLoader::readRange(const serialized_diags::Location &SDStart,
-                      const serialized_diags::Location &SDEnd,
-                      CXSourceRange &SR) {
+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>();
-
-  std::error_code EC;
-  if ((EC = readLocation(SDStart, *Start)))
-    return EC;
-  if ((EC = readLocation(SDEnd, *End)))
-    return EC;
+  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 std::error_code();
+  return Success;  
 }
 
-std::error_code DiagLoader::visitStartOfDiagnostic() {
-  CurrentDiags.push_back(llvm::make_unique<CXLoadedDiagnostic>());
-  return std::error_code();
-}
-
-std::error_code DiagLoader::visitEndOfDiagnostic() {
-  auto D = CurrentDiags.pop_back_val();
-  if (CurrentDiags.empty())
-    TopDiags->appendDiagnostic(std::move(D));
-  else
-    CurrentDiags.back()->getChildDiagnostics().appendDiagnostic(std::move(D));
-  return std::error_code();
-}
-
-std::error_code DiagLoader::visitCategoryRecord(unsigned ID, StringRef Name) {
-  // FIXME: Why do we care about long strings?
-  if (Name.size() > 65536)
-    return reportInvalidFile("Out-of-bounds string in category");
-  TopDiags->Categories[ID] = TopDiags->copyString(Name);
-  return std::error_code();
-}
-
-std::error_code DiagLoader::visitDiagFlagRecord(unsigned ID, StringRef Name) {
-  // FIXME: Why do we care about long strings?
-  if (Name.size() > 65536)
-    return reportInvalidFile("Out-of-bounds string in warning flag");
-  TopDiags->WarningFlags[ID] = TopDiags->copyString(Name);
-  return std::error_code();
-}
-
-std::error_code DiagLoader::visitFilenameRecord(unsigned ID, unsigned Size,
-                                                unsigned Timestamp,
-                                                StringRef Name) {
-  // FIXME: Why do we care about long strings?
-  if (Name.size() > 65536)
-    return reportInvalidFile("Out-of-bounds string in filename");
-  TopDiags->FileNames[ID] = TopDiags->copyString(Name);
-  TopDiags->Files[ID] =
-      TopDiags->FakeFiles.getVirtualFile(Name, Size, Timestamp);
-  return std::error_code();
-}
-
-std::error_code
-DiagLoader::visitSourceRangeRecord(const serialized_diags::Location &Start,
-                                   const serialized_diags::Location &End) {
-  CXSourceRange SR;
-  if (std::error_code EC = readRange(Start, End, SR))
-    return EC;
-  CurrentDiags.back()->Ranges.push_back(SR);
-  return std::error_code();
-}
-
-std::error_code
-DiagLoader::visitFixitRecord(const serialized_diags::Location &Start,
-                             const serialized_diags::Location &End,
-                             StringRef CodeToInsert) {
-  CXSourceRange SR;
-  if (std::error_code EC = readRange(Start, End, SR))
-    return EC;
-  // FIXME: Why do we care about long strings?
-  if (CodeToInsert.size() > 65536)
-    return reportInvalidFile("Out-of-bounds string in FIXIT");
-  CurrentDiags.back()->FixIts.push_back(
-      std::make_pair(SR, TopDiags->copyString(CodeToInsert)));
-  return std::error_code();
-}
-
-std::error_code DiagLoader::visitDiagnosticRecord(
-    unsigned Severity, const serialized_diags::Location &Location,
-    unsigned Category, unsigned Flag, StringRef Message) {
-  CXLoadedDiagnostic &D = *CurrentDiags.back();
-  D.severity = Severity;
-  if (std::error_code EC = readLocation(Location, D.DiagLoc))
-    return EC;
-  D.category = Category;
-  D.DiagOption = Flag ? TopDiags->WarningFlags[Flag] : "";
-  D.CategoryText = Category ? TopDiags->Categories[Category] : "";
-  D.Spelling = TopDiags->copyString(Message);
-  return std::error_code();
+LoadResult DiagLoader::readDiagnosticBlock(llvm::BitstreamCursor &Stream,
+                                           CXDiagnosticSetImpl &Diags,
+                                           CXLoadedDiagnosticSetImpl &TopDiags){
+
+  if (Stream.EnterSubBlock(clang::serialized_diags::BLOCK_DIAG)) {
+    reportInvalidFile("malformed diagnostic block");
+    return Failure;
+  }
+
+  std::unique_ptr<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");
+      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(std::move(D));
+        return Success;
+      case Read_Record:
+        break;
+    }
+    
+    // Read the record.
+    Record.clear();
+    StringRef Blob;
+    unsigned recID = Stream.readRecord(blockOrCode, Record, &Blob);
+    
+    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,
+                       Blob, /* allowEmptyString */ true))
+          return Failure;
+        continue;
+      
+      case serialized_diags::RECORD_DIAG_FLAG:
+        if (readString(TopDiags, TopDiags.WarningFlags, "warning flag", Record,
+                       Blob))
+          return Failure;
+        continue;
+        
+      case serialized_diags::RECORD_FILENAME: {
+        if (readString(TopDiags, TopDiags.FileNames, "filename", Record,
+                       Blob))
+          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;
+        const char *RetStr;
+        if (readString(TopDiags, RetStr, "FIXIT", Record, Blob,
+                       /* allowEmptyString */ true))
+          return Failure;
+        D->FixIts.push_back(std::make_pair(SR, RetStr));
+        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->CategoryText = D->category ? TopDiags.Categories[D->category] : "";
+        D->Spelling = TopDiags.copyString(Blob);
+        continue;
+      }
+    }
+  }
 }
 
 extern "C" {





More information about the cfe-commits mailing list