5 changed files with 446 additions and 161 deletions
@ -1,24 +1,172 @@
|
||||
#![allow(dead_code)] |
||||
|
||||
use super::*; |
||||
|
||||
macro_rules! ctx_type { |
||||
( typ , $id:ident , $fn:ident $( , $arg:expr )? ) => { |
||||
pub(super) unsafe fn $id(context: LLVMContextRef) -> LLVMTypeRef { |
||||
$fn(context $(, $arg)?) |
||||
#[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 |
||||
} |
||||
|
||||
( int , $id:ident , $bits:expr ) => { |
||||
ctx_type!(typ, $id, LLVMIntTypeInContext, $bits); |
||||
}; |
||||
pub fn memb(&self) -> &ComplType { |
||||
&self.memb |
||||
} |
||||
} |
||||
|
||||
ctx_type!(int, i64, 64); |
||||
ctx_type!(int, i32, 32); |
||||
ctx_type!(int, i16, 16); |
||||
ctx_type!(int, i8, 8); |
||||
ctx_type!(int, i1, 1); |
||||
ctx_type!(typ, void, LLVMVoidTypeInContext); |
||||
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
|
||||
|
Loading…
Reference in new issue