llvm_mapper/block/
identification.rs

1//! Functionality for mapping the `IDENTIFICATION_BLOCK` block.
2
3use llvm_support::bitcodes::{IdentificationCode, IrBlockId};
4use thiserror::Error;
5
6use crate::block::IrBlock;
7use crate::map::{MapError, PartialMapCtx};
8use crate::unroll::UnrolledBlock;
9
10/// Errors that can occur while mapping the identification block.
11#[derive(Debug, Error)]
12pub enum IdentificationError {
13    /// The `IDENTIFICATION_CODE_PRODUCER` couldn't be found.
14    #[error("identification block has no producer")]
15    MissingProducer,
16
17    /// The producer string is malformed.
18    #[error("malformed producer string")]
19    BadProducer,
20
21    /// The `IDENTIFICATION_CODE_EPOCH` couldn't be found.
22    #[error("identification block has no epoch")]
23    MissingEpoch,
24
25    /// A generic mapping error occured.
26    #[error("mapping error in string table")]
27    Map(#[from] MapError),
28}
29
30/// Models the `IDENTIFICATION_BLOCK` block.
31#[non_exhaustive]
32#[derive(Debug)]
33pub struct Identification {
34    /// The name of the "producer" for this bitcode.
35    pub producer: String,
36    /// The compatibility epoch.
37    pub epoch: u64,
38}
39
40impl IrBlock for Identification {
41    type Error = IdentificationError;
42
43    const BLOCK_ID: IrBlockId = IrBlockId::Identification;
44
45    fn try_map_inner(block: &UnrolledBlock, _ctx: &mut PartialMapCtx) -> Result<Self, Self::Error> {
46        let producer = block
47            .records()
48            .one(IdentificationCode::ProducerString as u64)
49            .ok_or(IdentificationError::MissingProducer)
50            .and_then(|r| {
51                r.try_string(0)
52                    .map_err(|_| IdentificationError::BadProducer)
53            })?;
54
55        let epoch = *block
56            .records()
57            .one(IdentificationCode::Epoch as u64)
58            .ok_or(IdentificationError::MissingEpoch)
59            .and_then(|r| r.fields().get(0).ok_or(IdentificationError::MissingEpoch))?;
60
61        Ok(Self { producer, epoch })
62    }
63}