use llvm_constants::{IrBlockId, ModuleCode, TARGET_TRIPLE};
use crate::block::attributes::{AttributeGroups, Attributes};
use crate::block::type_table::TypeTable;
use crate::block::{BlockId, BlockMapError, IrBlock};
use crate::map::{MapCtx, Mappable};
use crate::record::{Comdat, DataLayout};
use crate::unroll::UnrolledBlock;
#[non_exhaustive]
#[derive(Debug)]
pub struct Module {
version: u64,
pub triple: String,
pub datalayout: DataLayout,
pub asm: Vec<String>,
pub deplibs: Vec<String>,
pub type_table: TypeTable,
}
impl IrBlock for Module {
const BLOCK_ID: IrBlockId = IrBlockId::Module;
fn try_map_inner(block: &UnrolledBlock, ctx: &mut MapCtx) -> Result<Self, BlockMapError> {
let version = {
let version = block.one_record(ModuleCode::Version as u64)?;
version.get_field(0)?
};
ctx.version = Some(version);
let triple = if let Some(record) = block.maybe_one_record(ModuleCode::Triple as u64)? {
record.try_string(0)?
} else {
TARGET_TRIPLE.into()
};
let datalayout =
if let Some(record) = block.maybe_one_record(ModuleCode::DataLayout as u64)? {
DataLayout::try_map(record, ctx)?
} else {
DataLayout::default()
};
let asm = match block.maybe_one_record(ModuleCode::Asm as u64)? {
Some(rec) => rec
.try_string(0)?
.split('\n')
.map(String::from)
.collect::<Vec<_>>(),
None => Vec::new(),
};
let deplibs = block
.records(ModuleCode::DepLib as u64)
.map(|rec| rec.try_string(0))
.collect::<Result<Vec<_>, _>>()?;
let _section_table = block
.records(ModuleCode::SectionName as u64)
.map(|rec| rec.try_string(0))
.collect::<Result<Vec<_>, _>>()?;
let _gc_table = block
.records(ModuleCode::GcName as u64)
.map(|rec| rec.try_string(0))
.collect::<Result<Vec<_>, _>>()?;
let _comdats = block
.records(ModuleCode::Comdat as u64)
.map(|rec| Comdat::try_map(rec, ctx))
.collect::<Result<Vec<_>, _>>()?;
let type_table = TypeTable::try_map(block.one_block(BlockId::Ir(IrBlockId::Type))?, ctx)?;
ctx.attribute_groups = block
.maybe_one_block(BlockId::Ir(IrBlockId::ParamAttrGroup))?
.map(|b| AttributeGroups::try_map(b, ctx))
.transpose()?;
ctx.attributes = block
.maybe_one_block(BlockId::Ir(IrBlockId::ParamAttr))?
.map(|b| Attributes::try_map(b, ctx))
.transpose()?;
log::debug!("attributes: {:?}", ctx.attributes);
Ok(Self {
version,
triple,
datalayout,
asm,
deplibs,
type_table,
})
}
}