14 #include "llvm/ADT/Optional.h" 15 #include "llvm/ADT/SmallVector.h" 16 #include "llvm/ADT/StringRef.h" 17 #include "llvm/Bitcode/BitCodes.h" 18 #include "llvm/Bitcode/BitstreamReader.h" 19 #include "llvm/Support/Compiler.h" 20 #include "llvm/Support/ErrorHandling.h" 21 #include "llvm/Support/ErrorOr.h" 22 #include "llvm/Support/ManagedStatic.h" 24 #include <system_error> 26 using namespace clang;
27 using namespace serialized_diags;
38 llvm::BitstreamCursor Stream(**Buffer);
41 if (Stream.AtEndOfStream())
45 if (Stream.Read(8) !=
'D' ||
46 Stream.Read(8) !=
'I' ||
47 Stream.Read(8) !=
'A' ||
48 Stream.Read(8) !=
'G')
52 while (!Stream.AtEndOfStream()) {
53 if (Stream.ReadCode() != llvm::bitc::ENTER_SUBBLOCK)
57 switch (Stream.ReadSubBlockID()) {
58 case llvm::bitc::BLOCKINFO_BLOCK_ID:
59 BlockInfo = Stream.ReadBlockInfoBlock();
62 Stream.setBlockInfo(&*BlockInfo);
65 if ((EC = readMetaBlock(Stream)))
69 if ((EC = readDiagnosticBlock(Stream)))
73 if (!Stream.SkipBlock())
87 llvm::ErrorOr<SerializedDiagnosticReader::Cursor>
88 SerializedDiagnosticReader::skipUntilRecordOrBlock(
89 llvm::BitstreamCursor &Stream,
unsigned &BlockOrRecordID) {
92 while (!Stream.AtEndOfStream()) {
93 unsigned Code = Stream.ReadCode();
95 switch ((llvm::bitc::FixedAbbrevIDs)Code) {
96 case llvm::bitc::ENTER_SUBBLOCK:
97 BlockOrRecordID = Stream.ReadSubBlockID();
98 return Cursor::BlockBegin;
100 case llvm::bitc::END_BLOCK:
101 if (Stream.ReadBlockEnd())
103 return Cursor::BlockEnd;
105 case llvm::bitc::DEFINE_ABBREV:
106 Stream.ReadAbbrevRecord();
109 case llvm::bitc::UNABBREV_RECORD:
114 BlockOrRecordID = Code;
115 return Cursor::Record;
123 SerializedDiagnosticReader::readMetaBlock(llvm::BitstreamCursor &Stream) {
127 bool VersionChecked =
false;
130 unsigned BlockOrCode = 0;
131 llvm::ErrorOr<Cursor> Res = skipUntilRecordOrBlock(Stream, BlockOrCode);
138 case Cursor::BlockBegin:
139 if (Stream.SkipBlock())
142 case Cursor::BlockEnd:
149 unsigned RecordID = Stream.readRecord(BlockOrCode, Record);
152 if (Record.size() < 1)
156 VersionChecked =
true;
162 SerializedDiagnosticReader::readDiagnosticBlock(llvm::BitstreamCursor &Stream) {
172 unsigned BlockOrCode = 0;
173 llvm::ErrorOr<Cursor> Res = skipUntilRecordOrBlock(Stream, BlockOrCode);
178 case Cursor::BlockBegin:
181 if ((EC = readDiagnosticBlock(Stream)))
183 }
else if (!Stream.SkipBlock())
186 case Cursor::BlockEnd:
197 unsigned RecID = Stream.readRecord(BlockOrCode, Record, &Blob);
206 if (Record.size() != 2)
214 if (Record.size() != 8)
217 Record[0],
Location(Record[1], Record[2], Record[3], Record[4]),
218 Record[5], Record[6], Blob)))
223 if (Record.size() != 2)
231 if (Record.size() != 4)
238 if (Record.size() != 9)
241 Location(Record[0], Record[1], Record[2], Record[3]),
242 Location(Record[4], Record[5], Record[6], Record[7]), Blob)))
247 if (Record.size() != 8)
250 Location(Record[0], Record[1], Record[2], Record[3]),
251 Location(Record[4], Record[5], Record[6], Record[7]))))
256 if (Record.size() != 1)
267 class SDErrorCategoryType final :
public std::error_category {
268 const char *name()
const noexcept
override {
269 return "clang.serialized_diags";
272 std::string message(
int IE)
const override {
273 auto E =
static_cast<SDError>(IE);
276 return "Failed to open diagnostics file";
278 return "Invalid diagnostics signature";
280 return "Parse error reading diagnostics";
282 return "Malformed block at top-level of diagnostics";
284 return "Malformed sub-block in a diagnostic";
286 return "Malformed BlockInfo block";
288 return "Malformed Metadata block";
290 return "Malformed Diagnostic block";
292 return "Malformed Diagnostic record";
294 return "No version provided in diagnostics";
296 return "Unsupported diagnostics version";
298 return "Bitcode constructs that are not supported in diagnostics appear";
300 return "Generic error occurred while handling a record";
302 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
Defines the clang::FileSystemOptions interface.
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.