You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 

172 lines
3.0 KiB

use super::*;
#[repr(u8)]
#[derive(Clone, Copy, Debug, Eq, Hash, PartialEq)]
pub enum Basic {
Void,
Bool,
Q8_0,
Q16_0,
Q32_0,
Q64_0,
Q8_0U,
Q16_0U,
Q32_0U,
Q64_0U,
Q24_8,
Q24_8U,
Q16,
Q16U,
}
impl From<Basic> for u8 {
fn from(ty: Basic) -> Self {
ty as Self
}
}
impl Basic {
pub fn iter() -> impl DoubleEndedIterator<Item = Self> {
(0..14).map(|it| unsafe { std::mem::transmute(it as u8) })
}
}
#[derive(Clone, Copy)]
pub struct BasicType {
btyp: Basic,
handle: LLVMTypeRef,
}
#[derive(Clone)]
pub struct ArrayType {
size: usize,
memb: Box<ComplType>,
handle: LLVMTypeRef,
}
#[derive(Clone)]
pub struct StrucType {
memb: Vec<ComplType>,
handle: LLVMTypeRef,
}
#[derive(Clone)]
pub struct FunctType {
args: Vec<ComplType>,
retn: Box<ComplType>,
handle: LLVMTypeRef,
}
#[derive(Clone)]
pub enum ComplType {
Basic(BasicType),
Array(ArrayType),
Struc(StrucType),
Funct(FunctType),
}
pub trait TypeHandle {
fn handle(&self) -> LLVMTypeRef;
}
impl std::fmt::Debug for dyn TypeHandle {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
unsafe {
let ptr = LLVMPrintTypeToString(self.handle());
let res = std::ffi::CStr::from_ptr(ptr).fmt(f);
LLVMDisposeMessage(ptr);
res
}
}
}
impl BasicType {
pub fn new(btyp: Basic) -> Self {
let handle = unsafe {
match btyp {
Basic::Void => LLVMVoidType(),
Basic::Bool => LLVMInt1Type(),
Basic::Q8_0 | Basic::Q8_0U => LLVMInt8Type(),
Basic::Q16_0 | Basic::Q16_0U | Basic::Q16 | Basic::Q16U => {
LLVMInt16Type()
}
Basic::Q32_0 | Basic::Q32_0U | Basic::Q24_8 | Basic::Q24_8U => {
LLVMInt32Type()
}
Basic::Q64_0 | Basic::Q64_0U => LLVMInt64Type(),
}
};
Self { btyp, handle }
}
pub fn btyp(&self) -> Basic {
self.btyp
}
}
impl ArrayType {
pub fn new(size: usize, memb: &ComplType) -> Self {
let memb = Box::new(memb.clone());
let handle = unsafe { LLVMArrayType(memb.handle(), size as _) };
Self { size, memb, handle }
}
pub fn size(&self) -> usize {
self.size
}
pub fn memb(&self) -> &ComplType {
&self.memb
}
}
impl FunctType {
pub fn new(args: &[&ComplType], retn: &ComplType) -> Self {
let mut arg_handles =
args.iter().map(|arg| arg.handle()).collect::<Vec<_>>();
let args = args.iter().map(|&arg| arg.clone()).collect();
let retn = Box::new(retn.clone());
let handle = unsafe {
LLVMFunctionType(
retn.handle(),
arg_handles.as_mut_ptr(),
arg_handles.len() as _,
0,
)
};
Self { args, retn, handle }
}
}
impl TypeHandle for BasicType {
fn handle(&self) -> LLVMTypeRef {
self.handle
}
}
impl TypeHandle for ArrayType {
fn handle(&self) -> LLVMTypeRef {
self.handle
}
}
impl TypeHandle for StrucType {
fn handle(&self) -> LLVMTypeRef {
self.handle
}
}
impl TypeHandle for FunctType {
fn handle(&self) -> LLVMTypeRef {
self.handle
}
}
impl TypeHandle for ComplType {
fn handle(&self) -> LLVMTypeRef {
match self {
Self::Basic(t) => t.handle(),
Self::Array(t) => t.handle(),
Self::Struc(t) => t.handle(),
Self::Funct(t) => t.handle(),
}
}
}
// EOF