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