1 //===-- BitstreamRemarkParser.h - Bitstream parser --------------*- 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 // This file provides an implementation of the remark parser using the LLVM
10 // Bitstream format.
11 //
12 //===----------------------------------------------------------------------===//
13 
14 #ifndef LLVM_REMARKS_BITSTREAMREMARKPARSER_H
15 #define LLVM_REMARKS_BITSTREAMREMARKPARSER_H
16 
17 #include "llvm/ADT/ArrayRef.h"
18 #include "llvm/ADT/Optional.h"
19 #include "llvm/ADT/StringRef.h"
20 #include "llvm/Bitstream/BitstreamReader.h"
21 #include "llvm/Support/Error.h"
22 #include <array>
23 #include <cstdint>
24 
25 namespace llvm {
26 namespace remarks {
27 
28 /// Helper to parse a META_BLOCK for a bitstream remark container.
29 struct BitstreamMetaParserHelper {
30   /// The Bitstream reader.
31   BitstreamCursor &Stream;
32   /// Reference to the storage for the block info.
33   BitstreamBlockInfo &BlockInfo;
34   /// The parsed content: depending on the container type, some fields might be
35   /// empty.
36   Optional<uint64_t> ContainerVersion;
37   Optional<uint8_t> ContainerType;
38   Optional<StringRef> StrTabBuf;
39   Optional<StringRef> ExternalFilePath;
40   Optional<uint64_t> RemarkVersion;
41 
42   /// Continue parsing with \p Stream. \p Stream is expected to contain a
43   /// ENTER_SUBBLOCK to the META_BLOCK at the current position.
44   /// \p Stream is expected to have a BLOCKINFO_BLOCK set.
45   BitstreamMetaParserHelper(BitstreamCursor &Stream,
46                             BitstreamBlockInfo &BlockInfo);
47 
48   /// Parse the META_BLOCK and fill the available entries.
49   /// This helper does not check for the validity of the fields.
50   Error parse();
51 };
52 
53 /// Helper to parse a REMARK_BLOCK for a bitstream remark container.
54 struct BitstreamRemarkParserHelper {
55   /// The Bitstream reader.
56   BitstreamCursor &Stream;
57   /// The parsed content: depending on the remark, some fields might be empty.
58   Optional<uint8_t> Type;
59   Optional<uint64_t> RemarkNameIdx;
60   Optional<uint64_t> PassNameIdx;
61   Optional<uint64_t> FunctionNameIdx;
62   Optional<uint64_t> SourceFileNameIdx;
63   Optional<uint32_t> SourceLine;
64   Optional<uint32_t> SourceColumn;
65   Optional<uint64_t> Hotness;
66   struct Argument {
67     Optional<uint64_t> KeyIdx;
68     Optional<uint64_t> ValueIdx;
69     Optional<uint64_t> SourceFileNameIdx;
70     Optional<uint32_t> SourceLine;
71     Optional<uint32_t> SourceColumn;
72   };
73   Optional<ArrayRef<Argument>> Args;
74   /// Avoid re-allocating a vector every time.
75   SmallVector<Argument, 8> TmpArgs;
76 
77   /// Continue parsing with \p Stream. \p Stream is expected to contain a
78   /// ENTER_SUBBLOCK to the REMARK_BLOCK at the current position.
79   /// \p Stream is expected to have a BLOCKINFO_BLOCK set and to have already
80   /// parsed the META_BLOCK.
81   BitstreamRemarkParserHelper(BitstreamCursor &Stream);
82 
83   /// Parse the REMARK_BLOCK and fill the available entries.
84   /// This helper does not check for the validity of the fields.
85   Error parse();
86 };
87 
88 /// Helper to parse any bitstream remark container.
89 struct BitstreamParserHelper {
90   /// The Bitstream reader.
91   BitstreamCursor Stream;
92   /// The block info block.
93   BitstreamBlockInfo BlockInfo;
94   /// Start parsing at \p Buffer.
95   BitstreamParserHelper(StringRef Buffer);
96   /// Parse the magic number.
97   Expected<std::array<char, 4>> parseMagic();
98   /// Parse the block info block containing all the abbrevs.
99   /// This needs to be called before calling any other parsing function.
100   Error parseBlockInfoBlock();
101   /// Return true if the next block is a META_BLOCK. This function does not move
102   /// the cursor.
103   Expected<bool> isMetaBlock();
104   /// Return true if the next block is a REMARK_BLOCK. This function does not
105   /// move the cursor.
106   Expected<bool> isRemarkBlock();
107   /// Return true if the parser reached the end of the stream.
108   bool atEndOfStream() { return Stream.AtEndOfStream(); }
109   /// Jump to the end of the stream, skipping everything.
110   void skipToEnd() { return Stream.skipToEnd(); }
111 };
112 
113 } // end namespace remarks
114 } // end namespace llvm
115 
116 #endif // LLVM_REMARKS_BITSTREAMREMARKPARSER_H
117