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