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