llvm_bitcode/
bitstream.rs

1use num_enum::TryFromPrimitive;
2
3/// An `Abbreviation` represents the encoding definition for a user-defined
4/// record. An `Abbreviation` is the primary form of compression available in
5/// a bitstream file.
6#[derive(Debug, Clone)]
7pub struct Abbreviation {
8    /// All operands except the last that may be an array/string/blob
9    pub fields: Vec<ScalarOperand>,
10    pub payload: Option<PayloadOperand>,
11    pub id: u32,
12}
13
14/// Abbreviation operand
15#[derive(Debug, Copy, Clone)]
16pub enum ScalarOperand {
17    /// A literal value (emitted as a VBR8 field)
18    Literal(u64),
19    /// A fixed-width field
20    Fixed(u8),
21    /// A VBR-encoded value with the provided chunk width
22    Vbr(u8),
23    /// A char6-encoded ASCII character
24    Char6,
25}
26
27/// Abbreviation operand
28#[derive(Debug, Copy, Clone)]
29pub enum PayloadOperand {
30    /// Emitted as a vbr6 value, padded to a 32-bit boundary and then
31    /// an array of 8-bit objects
32    Blob,
33    /// An array of values. This expects another operand encoded
34    /// directly after indicating the element type.
35    /// The array will begin with a vbr6 value indicating the length of
36    /// the following array.
37    Array(ScalarOperand),
38}
39
40#[derive(Debug, Copy, Clone)]
41pub enum Operand {
42    Scalar(ScalarOperand),
43    Payload(PayloadOperand),
44}
45
46impl Operand {
47    /// Whether this case is payload
48    #[must_use]
49    pub fn is_payload(&self) -> bool {
50        matches!(self, Self::Payload(_))
51    }
52
53    /// Whether this case is the `literal` case
54    #[must_use]
55    pub fn is_literal(&self) -> bool {
56        matches!(self, Self::Scalar(ScalarOperand::Literal(_)))
57    }
58
59    #[must_use]
60    pub fn is_array(&self) -> bool {
61        matches!(self, Self::Payload(PayloadOperand::Array(_)))
62    }
63
64    #[must_use]
65    pub fn is_blob(&self) -> bool {
66        matches!(self, Self::Payload(PayloadOperand::Blob))
67    }
68
69    /// The `llvm::BitCodeAbbrevOp::Encoding` value this
70    /// enum case represents.
71    /// - note: Must match the encoding in
72    ///   <http://llvm.org/docs/BitCodeFormat.html#define-abbrev-encoding>
73    #[must_use]
74    pub fn encoded_kind(&self) -> u8 {
75        match self {
76            Self::Scalar(ScalarOperand::Literal(_)) => 0,
77            Self::Scalar(ScalarOperand::Fixed(_)) => 1,
78            Self::Scalar(ScalarOperand::Vbr(_)) => 2,
79            Self::Payload(PayloadOperand::Array(_)) => 3,
80            Self::Scalar(ScalarOperand::Char6) => 4,
81            Self::Payload(PayloadOperand::Blob) => 5,
82        }
83    }
84}
85
86/// A `BlockInfoCode` enumerates the bits that occur in the metadata for
87/// a block or record. Of these bits, only `SetBid` is required. If
88/// a name is given to a block or record with `BlockName` or
89/// `SetRecordName`, debugging tools like `llvm-bcanalyzer` can be used to
90/// introspect the structure of blocks and records in the bitstream file.
91#[derive(Debug, Clone, Copy, TryFromPrimitive)]
92#[repr(u8)]
93pub enum BlockInfoCode {
94    /// Indicates which block ID is being described.
95    SetBid = 1,
96    /// An optional element that records which bytes of the record are the
97    /// name of the block.
98    BlockName = 2,
99    /// An optional element that records the record ID number and the bytes
100    /// for the name of the corresponding record.
101    SetRecordName = 3,
102}
103
104/// An abbreviation id is a fixed-width field that occurs at the start of
105/// abbreviated data records and inside block definitions.
106///
107/// Bitstream reserves 4 special abbreviation IDs for its own bookkeeping.
108#[derive(Debug, Clone, Copy, TryFromPrimitive)]
109#[repr(u32)]
110pub enum BuiltinAbbreviationId {
111    /// Marks the end of the current block.
112    EndBlock = 0,
113    /// Marks the beginning of a new block.
114    EnterSubBlock = 1,
115    /// Marks the definition of a new abbreviation.
116    DefineAbbreviation = 2,
117    /// Marks the definition of a new unabbreviated record.
118    UnabbreviatedRecord = 3,
119}