#[derive(Debug, Clone, Default, PartialEq)]
pub struct Header {
pub items: Vec<Item>,
}
#[derive(Debug, Clone, PartialEq)]
#[non_exhaustive]
pub enum Item {
Function(Function),
Var(Var),
Record(Record),
Enum(Enum),
Typedef(Typedef),
Const(Const),
MacroFn(MacroFn),
}
impl Item {
pub fn type_name(&self) -> Option<&str> {
match self {
Item::Record(r) => Some(&r.name),
Item::Enum(e) => e.name.as_deref(),
Item::Typedef(t) => Some(&t.name),
_ => None,
}
}
}
#[derive(Debug, Clone, PartialEq)]
pub struct MacroFn {
pub name: String,
pub params: Vec<String>,
pub target: String,
pub args: Vec<MacroArg>,
}
#[derive(Debug, Clone, PartialEq)]
#[non_exhaustive]
pub enum MacroArg {
Param(usize),
Int(i128),
Str(Vec<u8>),
Const(String),
SizeOf(String),
}
#[derive(Debug, Clone, Copy, Default, PartialEq, Eq, Hash, PartialOrd, Ord)]
#[non_exhaustive]
pub enum Abi {
#[default]
C,
CUnwind,
Stdcall,
Fastcall,
Thiscall,
ThiscallUnwind,
Vectorcall,
}
impl Abi {
pub fn as_str(self) -> &'static str {
match self {
Abi::C => "C",
Abi::CUnwind => "C-unwind",
Abi::Stdcall => "stdcall",
Abi::Fastcall => "fastcall",
Abi::Thiscall => "thiscall",
Abi::ThiscallUnwind => "thiscall-unwind",
Abi::Vectorcall => "vectorcall",
}
}
}
#[derive(Debug, Clone, PartialEq)]
pub struct Function {
pub name: String,
pub link_name: Option<String>,
pub params: Vec<Param>,
pub ret: Type,
pub variadic: bool,
pub abi: Abi,
pub doc: Option<String>,
pub member: Option<Member>,
}
#[derive(Debug, Clone, PartialEq, Eq)]
pub struct Member {
pub class: String,
pub kind: MemberKind,
}
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum MemberKind {
Method,
Constructor,
Destructor,
}
#[derive(Debug, Clone, PartialEq)]
pub struct Param {
pub name: Option<String>,
pub ty: Type,
}
#[derive(Debug, Clone, PartialEq)]
pub struct Var {
pub name: String,
pub link_name: Option<String>,
pub ty: Type,
pub is_const: bool,
pub doc: Option<String>,
}
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum RecordKind {
Struct,
Union,
}
#[derive(Debug, Clone, PartialEq)]
pub struct Record {
pub name: String,
pub kind: RecordKind,
pub body: Option<RecordBody>,
pub opaque_layout: Option<(u64, u64)>,
pub doc: Option<String>,
}
#[derive(Debug, Clone, PartialEq)]
pub struct RecordBody {
pub size: u64,
pub align: u64,
pub fields: Vec<Field>,
}
#[derive(Debug, Clone, PartialEq)]
pub struct Field {
pub name: String,
pub ty: Type,
pub offset_bits: u64,
pub bit_width: Option<u32>,
pub layout: (u64, u64),
pub is_private: bool,
pub doc: Option<String>,
}
#[derive(Debug, Clone, PartialEq)]
pub struct Enum {
pub name: Option<String>,
pub repr: Type,
pub variants: Vec<Variant>,
pub doc: Option<String>,
}
#[derive(Debug, Clone, PartialEq)]
pub struct Variant {
pub name: String,
pub value: i128,
pub doc: Option<String>,
}
#[derive(Debug, Clone, PartialEq)]
pub struct Typedef {
pub name: String,
pub ty: Type,
pub doc: Option<String>,
}
#[derive(Debug, Clone, PartialEq)]
pub struct Const {
pub name: String,
pub value: ConstValue,
pub doc: Option<String>,
}
#[derive(Debug, Clone, PartialEq)]
pub enum ConstValue {
Int(i128, Type),
Float(f64, Type),
Str(Vec<u8>),
}
#[derive(Debug, Clone, PartialEq)]
#[non_exhaustive]
pub enum Type {
Void,
Bool,
Char,
SChar,
UChar,
Short,
UShort,
Int,
UInt,
Long,
ULong,
LongLong,
ULongLong,
Float,
Double,
Fixed(u32, bool),
USize,
ISize,
Pointer {
pointee: Box<Type>,
is_const: bool,
},
Array {
elem: Box<Type>,
len: u64,
},
FnPtr {
params: Vec<Type>,
ret: Box<Type>,
variadic: bool,
abi: Abi,
},
Named(String),
Unsupported(String),
}
impl Function {
pub fn symbol(&self) -> &str {
self.link_name.as_deref().unwrap_or(&self.name)
}
}
impl Var {
pub fn symbol(&self) -> &str {
self.link_name.as_deref().unwrap_or(&self.name)
}
}
impl Type {
pub fn ptr(pointee: Type) -> Self {
Type::Pointer {
pointee: Box::new(pointee),
is_const: false,
}
}
pub fn const_ptr(pointee: Type) -> Self {
Type::Pointer {
pointee: Box::new(pointee),
is_const: true,
}
}
pub fn unsupported(&self) -> Option<&str> {
match self {
Type::Unsupported(what) => Some(what),
Type::Pointer { pointee, .. } => pointee.unsupported(),
Type::Array { elem, .. } => elem.unsupported(),
Type::FnPtr { params, ret, .. } => params
.iter()
.chain(std::iter::once(&**ret))
.find_map(Type::unsupported),
_ => None,
}
}
}