xref: /freebsd-src/contrib/llvm-project/clang/include/clang/Frontend/SerializedDiagnosticReader.h (revision 0fca6ea1d4eea4c934cfff25ac9ee8ad6fe95583)
10b57cec5SDimitry Andric //===- SerializedDiagnosticReader.h - Reads diagnostics ---------*- C++ -*-===//
20b57cec5SDimitry Andric //
30b57cec5SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
40b57cec5SDimitry Andric // See https://llvm.org/LICENSE.txt for license information.
50b57cec5SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
60b57cec5SDimitry Andric //
70b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
80b57cec5SDimitry Andric 
90b57cec5SDimitry Andric #ifndef LLVM_CLANG_FRONTEND_SERIALIZEDDIAGNOSTICREADER_H
100b57cec5SDimitry Andric #define LLVM_CLANG_FRONTEND_SERIALIZEDDIAGNOSTICREADER_H
110b57cec5SDimitry Andric 
120b57cec5SDimitry Andric #include "clang/Basic/LLVM.h"
130b57cec5SDimitry Andric #include "llvm/Bitstream/BitstreamReader.h"
140b57cec5SDimitry Andric #include "llvm/ADT/StringRef.h"
150b57cec5SDimitry Andric #include "llvm/Support/ErrorOr.h"
160b57cec5SDimitry Andric #include <system_error>
170b57cec5SDimitry Andric 
180b57cec5SDimitry Andric namespace clang {
190b57cec5SDimitry Andric namespace serialized_diags {
200b57cec5SDimitry Andric 
210b57cec5SDimitry Andric enum class SDError {
220b57cec5SDimitry Andric   CouldNotLoad = 1,
230b57cec5SDimitry Andric   InvalidSignature,
240b57cec5SDimitry Andric   InvalidDiagnostics,
250b57cec5SDimitry Andric   MalformedTopLevelBlock,
260b57cec5SDimitry Andric   MalformedSubBlock,
270b57cec5SDimitry Andric   MalformedBlockInfoBlock,
280b57cec5SDimitry Andric   MalformedMetadataBlock,
290b57cec5SDimitry Andric   MalformedDiagnosticBlock,
300b57cec5SDimitry Andric   MalformedDiagnosticRecord,
310b57cec5SDimitry Andric   MissingVersion,
320b57cec5SDimitry Andric   VersionMismatch,
330b57cec5SDimitry Andric   UnsupportedConstruct,
340b57cec5SDimitry Andric   /// A generic error for subclass handlers that don't want or need to define
350b57cec5SDimitry Andric   /// their own error_category.
360b57cec5SDimitry Andric   HandlerFailed
370b57cec5SDimitry Andric };
380b57cec5SDimitry Andric 
390b57cec5SDimitry Andric const std::error_category &SDErrorCategory();
400b57cec5SDimitry Andric 
410b57cec5SDimitry Andric inline std::error_code make_error_code(SDError E) {
420b57cec5SDimitry Andric   return std::error_code(static_cast<int>(E), SDErrorCategory());
430b57cec5SDimitry Andric }
440b57cec5SDimitry Andric 
450b57cec5SDimitry Andric /// A location that is represented in the serialized diagnostics.
460b57cec5SDimitry Andric struct Location {
470b57cec5SDimitry Andric   unsigned FileID;
480b57cec5SDimitry Andric   unsigned Line;
490b57cec5SDimitry Andric   unsigned Col;
500b57cec5SDimitry Andric   unsigned Offset;
510b57cec5SDimitry Andric 
520b57cec5SDimitry Andric   Location(unsigned FileID, unsigned Line, unsigned Col, unsigned Offset)
530b57cec5SDimitry Andric       : FileID(FileID), Line(Line), Col(Col), Offset(Offset) {}
540b57cec5SDimitry Andric };
550b57cec5SDimitry Andric 
560b57cec5SDimitry Andric /// A base class that handles reading serialized diagnostics from a file.
570b57cec5SDimitry Andric ///
580b57cec5SDimitry Andric /// Subclasses should override the visit* methods with their logic for handling
590b57cec5SDimitry Andric /// the various constructs that are found in serialized diagnostics.
600b57cec5SDimitry Andric class SerializedDiagnosticReader {
610b57cec5SDimitry Andric public:
620b57cec5SDimitry Andric   SerializedDiagnosticReader() = default;
630b57cec5SDimitry Andric   virtual ~SerializedDiagnosticReader() = default;
640b57cec5SDimitry Andric 
650b57cec5SDimitry Andric   /// Read the diagnostics in \c File
660b57cec5SDimitry Andric   std::error_code readDiagnostics(StringRef File);
670b57cec5SDimitry Andric 
680b57cec5SDimitry Andric private:
690b57cec5SDimitry Andric   enum class Cursor;
700b57cec5SDimitry Andric 
710b57cec5SDimitry Andric   /// Read to the next record or block to process.
720b57cec5SDimitry Andric   llvm::ErrorOr<Cursor> skipUntilRecordOrBlock(llvm::BitstreamCursor &Stream,
730b57cec5SDimitry Andric                                                unsigned &BlockOrRecordId);
740b57cec5SDimitry Andric 
750b57cec5SDimitry Andric   /// Read a metadata block from \c Stream.
760b57cec5SDimitry Andric   std::error_code readMetaBlock(llvm::BitstreamCursor &Stream);
770b57cec5SDimitry Andric 
780b57cec5SDimitry Andric   /// Read a diagnostic block from \c Stream.
790b57cec5SDimitry Andric   std::error_code readDiagnosticBlock(llvm::BitstreamCursor &Stream);
800b57cec5SDimitry Andric 
810b57cec5SDimitry Andric protected:
820b57cec5SDimitry Andric   /// Visit the start of a diagnostic block.
830b57cec5SDimitry Andric   virtual std::error_code visitStartOfDiagnostic() { return {}; }
840b57cec5SDimitry Andric 
850b57cec5SDimitry Andric   /// Visit the end of a diagnostic block.
860b57cec5SDimitry Andric   virtual std::error_code visitEndOfDiagnostic() { return {}; }
870b57cec5SDimitry Andric 
880b57cec5SDimitry Andric   /// Visit a category. This associates the category \c ID to a \c Name.
890b57cec5SDimitry Andric   virtual std::error_code visitCategoryRecord(unsigned ID, StringRef Name) {
900b57cec5SDimitry Andric     return {};
910b57cec5SDimitry Andric   }
920b57cec5SDimitry Andric 
930b57cec5SDimitry Andric   /// Visit a flag. This associates the flag's \c ID to a \c Name.
940b57cec5SDimitry Andric   virtual std::error_code visitDiagFlagRecord(unsigned ID, StringRef Name) {
950b57cec5SDimitry Andric     return {};
960b57cec5SDimitry Andric   }
970b57cec5SDimitry Andric 
980b57cec5SDimitry Andric   /// Visit a diagnostic.
990b57cec5SDimitry Andric   virtual std::error_code
1000b57cec5SDimitry Andric   visitDiagnosticRecord(unsigned Severity, const Location &Location,
1010b57cec5SDimitry Andric                         unsigned Category, unsigned Flag, StringRef Message) {
1020b57cec5SDimitry Andric     return {};
1030b57cec5SDimitry Andric   }
1040b57cec5SDimitry Andric 
1050b57cec5SDimitry Andric   /// Visit a filename. This associates the file's \c ID to a \c Name.
1060b57cec5SDimitry Andric   virtual std::error_code visitFilenameRecord(unsigned ID, unsigned Size,
1070b57cec5SDimitry Andric                                               unsigned Timestamp,
1080b57cec5SDimitry Andric                                               StringRef Name) {
1090b57cec5SDimitry Andric     return {};
1100b57cec5SDimitry Andric   }
1110b57cec5SDimitry Andric 
1120b57cec5SDimitry Andric   /// Visit a fixit hint.
1130b57cec5SDimitry Andric   virtual std::error_code
1140b57cec5SDimitry Andric   visitFixitRecord(const Location &Start, const Location &End, StringRef Text) {
1150b57cec5SDimitry Andric     return {};
1160b57cec5SDimitry Andric   }
1170b57cec5SDimitry Andric 
1180b57cec5SDimitry Andric   /// Visit a source range.
1190b57cec5SDimitry Andric   virtual std::error_code visitSourceRangeRecord(const Location &Start,
1200b57cec5SDimitry Andric                                                  const Location &End) {
1210b57cec5SDimitry Andric     return {};
1220b57cec5SDimitry Andric   }
1230b57cec5SDimitry Andric 
1240b57cec5SDimitry Andric   /// Visit the version of the set of diagnostics.
1250b57cec5SDimitry Andric   virtual std::error_code visitVersionRecord(unsigned Version) { return {}; }
1260b57cec5SDimitry Andric };
1270b57cec5SDimitry Andric 
1280b57cec5SDimitry Andric } // namespace serialized_diags
1290b57cec5SDimitry Andric } // namespace clang
1300b57cec5SDimitry Andric 
1310b57cec5SDimitry Andric template <>
132*0fca6ea1SDimitry Andric struct std::is_error_code_enum<clang::serialized_diags::SDError>
133*0fca6ea1SDimitry Andric     : std::true_type {};
1340b57cec5SDimitry Andric 
1350b57cec5SDimitry Andric #endif // LLVM_CLANG_FRONTEND_SERIALIZEDDIAGNOSTICREADER_H
136