13 #include "llvm/Support/ManagedStatic.h"
14 #include "llvm/Support/MemoryBuffer.h"
16 using namespace clang;
17 using namespace clang::serialized_diags;
28 llvm::BitstreamReader StreamFile;
29 StreamFile.init((
const unsigned char *)(*Buffer)->getBufferStart(),
30 (
const unsigned char *)(*Buffer)->getBufferEnd());
32 llvm::BitstreamCursor Stream(StreamFile);
35 if (Stream.Read(8) !=
'D' ||
36 Stream.Read(8) !=
'I' ||
37 Stream.Read(8) !=
'A' ||
38 Stream.Read(8) !=
'G')
42 while (!Stream.AtEndOfStream()) {
43 if (Stream.ReadCode() != llvm::bitc::ENTER_SUBBLOCK)
47 switch (Stream.ReadSubBlockID()) {
48 case llvm::bitc::BLOCKINFO_BLOCK_ID:
49 if (Stream.ReadBlockInfoBlock())
53 if ((EC = readMetaBlock(Stream)))
57 if ((EC = readDiagnosticBlock(Stream)))
61 if (!Stream.SkipBlock())
66 return std::error_code();
75 llvm::ErrorOr<SerializedDiagnosticReader::Cursor>
76 SerializedDiagnosticReader::skipUntilRecordOrBlock(
77 llvm::BitstreamCursor &Stream,
unsigned &BlockOrRecordID) {
80 while (!Stream.AtEndOfStream()) {
81 unsigned Code = Stream.ReadCode();
83 switch ((llvm::bitc::FixedAbbrevIDs)Code) {
84 case llvm::bitc::ENTER_SUBBLOCK:
85 BlockOrRecordID = Stream.ReadSubBlockID();
86 return Cursor::BlockBegin;
88 case llvm::bitc::END_BLOCK:
89 if (Stream.ReadBlockEnd())
91 return Cursor::BlockEnd;
93 case llvm::bitc::DEFINE_ABBREV:
94 Stream.ReadAbbrevRecord();
97 case llvm::bitc::UNABBREV_RECORD:
102 BlockOrRecordID = Code;
103 return Cursor::Record;
111 SerializedDiagnosticReader::readMetaBlock(llvm::BitstreamCursor &Stream) {
115 bool VersionChecked =
false;
118 unsigned BlockOrCode = 0;
119 llvm::ErrorOr<Cursor> Res = skipUntilRecordOrBlock(Stream, BlockOrCode);
126 case Cursor::BlockBegin:
127 if (Stream.SkipBlock())
129 case Cursor::BlockEnd:
132 return std::error_code();
136 unsigned RecordID = Stream.readRecord(BlockOrCode, Record);
139 if (Record.size() < 1)
143 VersionChecked =
true;
149 SerializedDiagnosticReader::readDiagnosticBlock(llvm::BitstreamCursor &Stream) {
159 unsigned BlockOrCode = 0;
160 llvm::ErrorOr<Cursor> Res = skipUntilRecordOrBlock(Stream, BlockOrCode);
165 case Cursor::BlockBegin:
168 if ((EC = readDiagnosticBlock(Stream)))
170 }
else if (!Stream.SkipBlock())
173 case Cursor::BlockEnd:
176 return std::error_code();
184 unsigned RecID = Stream.readRecord(BlockOrCode, Record, &Blob);
193 if (Record.size() != 2)
201 if (Record.size() != 8)
204 Record[0],
Location(Record[1], Record[2], Record[3], Record[4]),
205 Record[5], Record[6], Blob)))
210 if (Record.size() != 2)
218 if (Record.size() != 4)
225 if (Record.size() != 9)
228 Location(Record[0], Record[1], Record[2], Record[3]),
229 Location(Record[4], Record[5], Record[6], Record[7]), Blob)))
234 if (Record.size() != 8)
237 Location(Record[0], Record[1], Record[2], Record[3]),
238 Location(Record[4], Record[5], Record[6], Record[7]))))
243 if (Record.size() != 1)
253 class SDErrorCategoryType final :
public std::error_category {
254 const char *name() const LLVM_NOEXCEPT
override {
255 return "clang.serialized_diags";
257 std::string message(
int IE)
const override {
261 return "Failed to open diagnostics file";
263 return "Invalid diagnostics signature";
265 return "Parse error reading diagnostics";
267 return "Malformed block at top-level of diagnostics";
269 return "Malformed sub-block in a diagnostic";
271 return "Malformed BlockInfo block";
273 return "Malformed Metadata block";
275 return "Malformed Diagnostic block";
277 return "Malformed Diagnostic record";
279 return "No version provided in diagnostics";
281 return "Unsupported diagnostics version";
283 return "Bitcode constructs that are not supported in diagnostics appear";
285 return "Generic error occurred while handling a record";
287 llvm_unreachable(
"Unknown error type!");
Implements support for file system lookup, file system caching, and directory search management...
Defines the clang::FileManager interface and associated types.
virtual std::error_code visitStartOfDiagnostic()
Visit the start of a diagnostic block.
std::unique_ptr< llvm::MemoryBuffer > Buffer
A generic error for subclass handlers that don't want or need to define their own error_category...
virtual std::error_code visitSourceRangeRecord(const Location &Start, const Location &End)
Visit a source range.
std::error_code readDiagnostics(StringRef File)
Read the diagnostics in File.
virtual std::error_code visitDiagFlagRecord(unsigned ID, StringRef Name)
Visit a flag. This associates the flag's ID to a Name.
virtual std::error_code visitVersionRecord(unsigned Version)
Visit the version of the set of diagnostics.
virtual std::error_code visitFixitRecord(const Location &Start, const Location &End, StringRef Text)
Visit a fixit hint.
A location that is represented in the serialized diagnostics.
virtual std::error_code visitCategoryRecord(unsigned ID, StringRef Name)
Visit a category. This associates the category ID to a Name.
llvm::ErrorOr< std::unique_ptr< llvm::MemoryBuffer > > getBufferForFile(const FileEntry *Entry, bool isVolatile=false, bool ShouldCloseOpenFile=true)
Open the specified file as a MemoryBuffer, returning a new MemoryBuffer if successful, otherwise returning null.
static llvm::ManagedStatic< SDErrorCategoryType > ErrorCategory
detail::InMemoryDirectory::const_iterator E
Keeps track of options that affect how file operations are performed.
virtual std::error_code visitFilenameRecord(unsigned ID, unsigned Size, unsigned Timestamp, StringRef Name)
Visit a filename. This associates the file's ID to a Name.
const std::error_category & SDErrorCategory()
virtual std::error_code visitEndOfDiagnostic()
Visit the end of a diagnostic block.
The this block acts as a container for all the information for a specific diagnostic.
A top-level block which represents any meta data associated with the diagostics, including versioning...
virtual std::error_code visitDiagnosticRecord(unsigned Severity, const Location &Location, unsigned Category, unsigned Flag, StringRef Message)
Visit a diagnostic.