13 #include "llvm/Support/ManagedStatic.h" 15 using namespace clang;
27 llvm::BitstreamCursor Stream(**Buffer);
30 if (Stream.AtEndOfStream())
34 if (Stream.Read(8) !=
'D' ||
35 Stream.Read(8) !=
'I' ||
36 Stream.Read(8) !=
'A' ||
37 Stream.Read(8) !=
'G')
41 while (!Stream.AtEndOfStream()) {
42 if (Stream.ReadCode() != llvm::bitc::ENTER_SUBBLOCK)
46 switch (Stream.ReadSubBlockID()) {
47 case llvm::bitc::BLOCKINFO_BLOCK_ID: {
48 BlockInfo = Stream.ReadBlockInfoBlock();
51 Stream.setBlockInfo(&*BlockInfo);
55 if ((EC = readMetaBlock(Stream)))
59 if ((EC = readDiagnosticBlock(Stream)))
63 if (!Stream.SkipBlock())
68 return std::error_code();
77 llvm::ErrorOr<SerializedDiagnosticReader::Cursor>
78 SerializedDiagnosticReader::skipUntilRecordOrBlock(
79 llvm::BitstreamCursor &Stream,
unsigned &BlockOrRecordID) {
82 while (!Stream.AtEndOfStream()) {
83 unsigned Code = Stream.ReadCode();
85 switch ((llvm::bitc::FixedAbbrevIDs)Code) {
86 case llvm::bitc::ENTER_SUBBLOCK:
87 BlockOrRecordID = Stream.ReadSubBlockID();
88 return Cursor::BlockBegin;
90 case llvm::bitc::END_BLOCK:
91 if (Stream.ReadBlockEnd())
93 return Cursor::BlockEnd;
95 case llvm::bitc::DEFINE_ABBREV:
96 Stream.ReadAbbrevRecord();
99 case llvm::bitc::UNABBREV_RECORD:
104 BlockOrRecordID = Code;
105 return Cursor::Record;
113 SerializedDiagnosticReader::readMetaBlock(llvm::BitstreamCursor &Stream) {
117 bool VersionChecked =
false;
120 unsigned BlockOrCode = 0;
121 llvm::ErrorOr<Cursor> Res = skipUntilRecordOrBlock(Stream, BlockOrCode);
128 case Cursor::BlockBegin:
129 if (Stream.SkipBlock())
132 case Cursor::BlockEnd:
135 return std::error_code();
139 unsigned RecordID = Stream.readRecord(BlockOrCode, Record);
142 if (Record.size() < 1)
146 VersionChecked =
true;
152 SerializedDiagnosticReader::readDiagnosticBlock(llvm::BitstreamCursor &Stream) {
162 unsigned BlockOrCode = 0;
163 llvm::ErrorOr<Cursor> Res = skipUntilRecordOrBlock(Stream, BlockOrCode);
168 case Cursor::BlockBegin:
171 if ((EC = readDiagnosticBlock(Stream)))
173 }
else if (!Stream.SkipBlock())
176 case Cursor::BlockEnd:
179 return std::error_code();
187 unsigned RecID = Stream.readRecord(BlockOrCode, Record, &Blob);
196 if (Record.size() != 2)
204 if (Record.size() != 8)
207 Record[0],
Location(Record[1], Record[2], Record[3], Record[4]),
208 Record[5], Record[6], Blob)))
213 if (Record.size() != 2)
221 if (Record.size() != 4)
228 if (Record.size() != 9)
231 Location(Record[0], Record[1], Record[2], Record[3]),
232 Location(Record[4], Record[5], Record[6], Record[7]), Blob)))
237 if (Record.size() != 8)
240 Location(Record[0], Record[1], Record[2], Record[3]),
241 Location(Record[4], Record[5], Record[6], Record[7]))))
246 if (Record.size() != 1)
256 class SDErrorCategoryType final :
public std::error_category {
257 const char *name()
const noexcept
override {
258 return "clang.serialized_diags";
260 std::string message(
int IE)
const override {
264 return "Failed to open diagnostics file";
266 return "Invalid diagnostics signature";
268 return "Parse error reading diagnostics";
270 return "Malformed block at top-level of diagnostics";
272 return "Malformed sub-block in a diagnostic";
274 return "Malformed BlockInfo block";
276 return "Malformed Metadata block";
278 return "Malformed Diagnostic block";
280 return "Malformed Diagnostic record";
282 return "No version provided in diagnostics";
284 return "Unsupported diagnostics version";
286 return "Bitcode constructs that are not supported in diagnostics appear";
288 return "Generic error occurred while handling a record";
290 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.
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.
Dataflow Directional Tag Classes.
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
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.