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