1 //===- SerializedDiagnosticReader.h - Reads diagnostics ---------*- C++ -*-===// 2 // 3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4 // See https://llvm.org/LICENSE.txt for license information. 5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6 // 7 //===----------------------------------------------------------------------===// 8 9 #ifndef LLVM_CLANG_FRONTEND_SERIALIZEDDIAGNOSTICREADER_H 10 #define LLVM_CLANG_FRONTEND_SERIALIZEDDIAGNOSTICREADER_H 11 12 #include "clang/Basic/LLVM.h" 13 #include "llvm/Bitstream/BitstreamReader.h" 14 #include "llvm/ADT/StringRef.h" 15 #include "llvm/Support/ErrorOr.h" 16 #include <system_error> 17 18 namespace clang { 19 namespace serialized_diags { 20 21 enum class SDError { 22 CouldNotLoad = 1, 23 InvalidSignature, 24 InvalidDiagnostics, 25 MalformedTopLevelBlock, 26 MalformedSubBlock, 27 MalformedBlockInfoBlock, 28 MalformedMetadataBlock, 29 MalformedDiagnosticBlock, 30 MalformedDiagnosticRecord, 31 MissingVersion, 32 VersionMismatch, 33 UnsupportedConstruct, 34 /// A generic error for subclass handlers that don't want or need to define 35 /// their own error_category. 36 HandlerFailed 37 }; 38 39 const std::error_category &SDErrorCategory(); 40 41 inline std::error_code make_error_code(SDError E) { 42 return std::error_code(static_cast<int>(E), SDErrorCategory()); 43 } 44 45 /// A location that is represented in the serialized diagnostics. 46 struct Location { 47 unsigned FileID; 48 unsigned Line; 49 unsigned Col; 50 unsigned Offset; 51 52 Location(unsigned FileID, unsigned Line, unsigned Col, unsigned Offset) 53 : FileID(FileID), Line(Line), Col(Col), Offset(Offset) {} 54 }; 55 56 /// A base class that handles reading serialized diagnostics from a file. 57 /// 58 /// Subclasses should override the visit* methods with their logic for handling 59 /// the various constructs that are found in serialized diagnostics. 60 class SerializedDiagnosticReader { 61 public: 62 SerializedDiagnosticReader() = default; 63 virtual ~SerializedDiagnosticReader() = default; 64 65 /// Read the diagnostics in \c File 66 std::error_code readDiagnostics(StringRef File); 67 68 private: 69 enum class Cursor; 70 71 /// Read to the next record or block to process. 72 llvm::ErrorOr<Cursor> skipUntilRecordOrBlock(llvm::BitstreamCursor &Stream, 73 unsigned &BlockOrRecordId); 74 75 /// Read a metadata block from \c Stream. 76 std::error_code readMetaBlock(llvm::BitstreamCursor &Stream); 77 78 /// Read a diagnostic block from \c Stream. 79 std::error_code readDiagnosticBlock(llvm::BitstreamCursor &Stream); 80 81 protected: 82 /// Visit the start of a diagnostic block. 83 virtual std::error_code visitStartOfDiagnostic() { return {}; } 84 85 /// Visit the end of a diagnostic block. 86 virtual std::error_code visitEndOfDiagnostic() { return {}; } 87 88 /// Visit a category. This associates the category \c ID to a \c Name. 89 virtual std::error_code visitCategoryRecord(unsigned ID, StringRef Name) { 90 return {}; 91 } 92 93 /// Visit a flag. This associates the flag's \c ID to a \c Name. 94 virtual std::error_code visitDiagFlagRecord(unsigned ID, StringRef Name) { 95 return {}; 96 } 97 98 /// Visit a diagnostic. 99 virtual std::error_code 100 visitDiagnosticRecord(unsigned Severity, const Location &Location, 101 unsigned Category, unsigned Flag, StringRef Message) { 102 return {}; 103 } 104 105 /// Visit a filename. This associates the file's \c ID to a \c Name. 106 virtual std::error_code visitFilenameRecord(unsigned ID, unsigned Size, 107 unsigned Timestamp, 108 StringRef Name) { 109 return {}; 110 } 111 112 /// Visit a fixit hint. 113 virtual std::error_code 114 visitFixitRecord(const Location &Start, const Location &End, StringRef Text) { 115 return {}; 116 } 117 118 /// Visit a source range. 119 virtual std::error_code visitSourceRangeRecord(const Location &Start, 120 const Location &End) { 121 return {}; 122 } 123 124 /// Visit the version of the set of diagnostics. 125 virtual std::error_code visitVersionRecord(unsigned Version) { return {}; } 126 }; 127 128 } // namespace serialized_diags 129 } // namespace clang 130 131 namespace std { 132 133 template <> 134 struct is_error_code_enum<clang::serialized_diags::SDError> : std::true_type {}; 135 136 } // namespace std 137 138 #endif // LLVM_CLANG_FRONTEND_SERIALIZEDDIAGNOSTICREADER_H 139