================
@@ -13,81 +13,171 @@
#ifndef LLVM_LIB_REMARKS_BITSTREAM_REMARK_PARSER_H
#define LLVM_LIB_REMARKS_BITSTREAM_REMARK_PARSER_H
-#include "llvm/ADT/ArrayRef.h"
#include "llvm/ADT/StringRef.h"
#include "llvm/Bitstream/BitstreamReader.h"
#include "llvm/Remarks/BitstreamRemarkContainer.h"
+#include "llvm/Remarks/Remark.h"
#include "llvm/Remarks/RemarkFormat.h"
#include "llvm/Remarks/RemarkParser.h"
+#include "llvm/Remarks/RemarkStringTable.h"
#include "llvm/Support/Error.h"
-#include <array>
+#include "llvm/Support/FormatVariadic.h"
#include <cstdint>
#include <memory>
#include <optional>
namespace llvm {
namespace remarks {
-struct Remark;
+class BitstreamBlockParserHelperBase {
+protected:
+ BitstreamCursor &Stream;
+
+ unsigned BlockID;
+ StringRef BlockName;
+
+public:
+ BitstreamBlockParserHelperBase(BitstreamCursor &Stream, unsigned BlockID,
+ StringRef BlockName)
+ : Stream(Stream), BlockID(BlockID), BlockName(BlockName) {}
+
+ template <typename... Ts> Error error(char const *Fmt, const Ts &...Vals) {
+ std::string Buffer;
+ raw_string_ostream OS(Buffer);
+ OS << "Error while parsing " << BlockName << " block: ";
+ OS << formatv(Fmt, Vals...);
+ return make_error<StringError>(
+ std::move(Buffer),
+ std::make_error_code(std::errc::illegal_byte_sequence));
+ }
+
+ Error expectBlock();
+
+protected:
+ Error enterBlock();
+
+ Error unknownRecord(unsigned AbbrevID);
+ Error unexpectedRecord(StringRef RecordName);
+ Error malformedRecord(StringRef RecordName);
+ Error unexpectedBlock(unsigned Code);
+};
+
+template <typename Derived>
+class BitstreamBlockParserHelper : public BitstreamBlockParserHelperBase {
+protected:
+ using BitstreamBlockParserHelperBase::BitstreamBlockParserHelperBase;
+ Derived &derived() { return *static_cast<Derived *>(this); }
+
+ /// Parse a record and fill in the fields in the parser.
+ /// The subclass can statically override this method.
+ Error parseRecord(unsigned Code) { return unexpectedRecord(Code); }
+
+ /// Parse a subblock and fill in the fields in the parser.
+ /// The subclass can statically override this method.
+ Error parseSubBlock(unsigned Code) { return unexpectedBlock(Code); }
+
+public:
+ /// Enter, parse, and leave this bitstream block. This expects the
+ /// BitstreamCursor to be right after the SubBlock entry (i.e. after calling
+ /// expectBlock).
+ Error parseBlock() {
+ if (Error E = enterBlock())
+ return E;
+
+ // Stop when there is nothing to read anymore or when we encounter an
+ // END_BLOCK.
+ while (true) {
+ Expected<BitstreamEntry> Next = Stream.advance();
+ if (!Next)
+ return Next.takeError();
+ switch (Next->Kind) {
+ case BitstreamEntry::SubBlock:
+ if (Error E = derived().parseSubBlock(Next->ID))
+ return E;
+ continue;
+ case BitstreamEntry::EndBlock:
+ return Error::success();
+ case BitstreamEntry::Record:
+ if (Error E = derived().parseRecord(Next->ID))
+ return E;
+ continue;
+ case BitstreamEntry::Error:
+ return error("Unexpected end of bitstream.");
+ }
+ }
+ }
+};
/// Helper to parse a META_BLOCK for a bitstream remark container.
-struct BitstreamMetaParserHelper {
- /// The Bitstream reader.
- BitstreamCursor &Stream;
- /// Reference to the storage for the block info.
- BitstreamBlockInfo &BlockInfo;
- /// The parsed content: depending on the container type, some fields might be
- /// empty.
- std::optional<uint64_t> ContainerVersion;
- std::optional<uint8_t> ContainerType;
- std::optional<StringRef> StrTabBuf;
- std::optional<StringRef> ExternalFilePath;
+class BitstreamMetaParserHelper
+ : public BitstreamBlockParserHelper<BitstreamMetaParserHelper> {
+ friend class BitstreamBlockParserHelper;
+
+public:
+ struct ContainerInfo {
+ uint64_t Version;
+ uint64_t Type;
+ };
+
+ /// The parsed content: depending on the container type, some fields might
+ /// be empty.
+ std::optional<ContainerInfo> Container;
std::optional<uint64_t> RemarkVersion;
+ std::optional<StringRef> ExternalFilePath;
+ std::optional<StringRef> StrTabBuf;
- /// Continue parsing with \p Stream. \p Stream is expected to contain a
- /// ENTER_SUBBLOCK to the META_BLOCK at the current position.
- /// \p Stream is expected to have a BLOCKINFO_BLOCK set.
- BitstreamMetaParserHelper(BitstreamCursor &Stream,
- BitstreamBlockInfo &BlockInfo);
+ BitstreamMetaParserHelper(BitstreamCursor &Stream)
+ : BitstreamBlockParserHelper(Stream, META_BLOCK_ID, MetaBlockName) {}
- /// Parse the META_BLOCK and fill the available entries.
- /// This helper does not check for the validity of the fields.
- Error parse();
+protected:
+ Error parseRecord(unsigned Code);
};
/// Helper to parse a REMARK_BLOCK for a bitstream remark container.
-struct BitstreamRemarkParserHelper {
- /// The Bitstream reader.
- BitstreamCursor &Stream;
+class BitstreamRemarkParserHelper
+ : public BitstreamBlockParserHelper<BitstreamRemarkParserHelper> {
+ friend class BitstreamBlockParserHelper;
+
+protected:
+ unsigned RecordID;
+ SmallVector<uint64_t, 5> Record;
+ StringRef RecordBlob;
----------------
jroelofs wrote:
```suggestion
SmallVector<uint64_t, 5> Record;
StringRef RecordBlob;
unsigned RecordID;
```
https://github.com/llvm/llvm-project/pull/156511
_______________________________________________
llvm-branch-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits