use lief_ffi as ffi;
use super::Type;
use crate::Error;
use crate::common::{FromFFI, into_optional};
use crate::declare_fwd_iterator;
use crate::dwarf::Function;
use crate::dwarf::types::DwarfType;
use crate::to_result;
use std::marker::PhantomData;
pub trait ClassLike {
#[doc(hidden)]
fn get_classlike(&self) -> &ffi::DWARF_types_ClassLike;
fn members(&self) -> Members<'_> {
Members::new(self.get_classlike().members())
}
fn functions(&self) -> Functions<'_> {
Functions::new(self.get_classlike().functions())
}
}
pub struct Member<'a> {
ptr: cxx::UniquePtr<ffi::DWARF_types_ClassLike_Member>,
_owner: PhantomData<&'a ()>,
}
impl Member<'_> {
pub fn name(&self) -> String {
self.ptr.name().to_string()
}
pub fn offset(&self) -> Result<u64, Error> {
to_result!(ffi::DWARF_types_ClassLike_Member::offset, self);
}
pub fn bit_offset(&self) -> Result<u64, Error> {
to_result!(ffi::DWARF_types_ClassLike_Member::bit_offset, self);
}
pub fn bit_size(&self) -> Result<u64, Error> {
to_result!(ffi::DWARF_types_ClassLike_Member::bit_size, self);
}
pub fn get_type(&self) -> Option<Type<'_>> {
into_optional(self.ptr.get_type())
}
pub fn is_external(&self) -> bool {
self.ptr.is_external()
}
pub fn is_declaration(&self) -> bool {
self.ptr.is_declaration()
}
}
impl FromFFI<ffi::DWARF_types_ClassLike_Member> for Member<'_> {
fn from_ffi(cmd: cxx::UniquePtr<ffi::DWARF_types_ClassLike_Member>) -> Self {
Self {
ptr: cmd,
_owner: PhantomData,
}
}
}
pub struct Structure<'a> {
ptr: cxx::UniquePtr<ffi::DWARF_types_Structure>,
_owner: PhantomData<&'a ()>,
}
impl FromFFI<ffi::DWARF_types_Structure> for Structure<'_> {
fn from_ffi(cmd: cxx::UniquePtr<ffi::DWARF_types_Structure>) -> Self {
Self {
ptr: cmd,
_owner: PhantomData,
}
}
}
impl DwarfType for Structure<'_> {
fn get_base(&self) -> &ffi::DWARF_Type {
self.ptr.as_ref().unwrap().as_ref().as_ref()
}
}
impl ClassLike for Structure<'_> {
fn get_classlike(&self) -> &ffi::DWARF_types_ClassLike {
self.ptr.as_ref().unwrap().as_ref()
}
}
pub struct Union<'a> {
ptr: cxx::UniquePtr<ffi::DWARF_types_Union>,
_owner: PhantomData<&'a ()>,
}
impl FromFFI<ffi::DWARF_types_Union> for Union<'_> {
fn from_ffi(cmd: cxx::UniquePtr<ffi::DWARF_types_Union>) -> Self {
Self {
ptr: cmd,
_owner: PhantomData,
}
}
}
impl DwarfType for Union<'_> {
fn get_base(&self) -> &ffi::DWARF_Type {
self.ptr.as_ref().unwrap().as_ref().as_ref()
}
}
impl ClassLike for Union<'_> {
fn get_classlike(&self) -> &ffi::DWARF_types_ClassLike {
self.ptr.as_ref().unwrap().as_ref()
}
}
pub struct Packed<'a> {
ptr: cxx::UniquePtr<ffi::DWARF_types_Packed>,
_owner: PhantomData<&'a ()>,
}
impl FromFFI<ffi::DWARF_types_Packed> for Packed<'_> {
fn from_ffi(cmd: cxx::UniquePtr<ffi::DWARF_types_Packed>) -> Self {
Self {
ptr: cmd,
_owner: PhantomData,
}
}
}
impl DwarfType for Packed<'_> {
fn get_base(&self) -> &ffi::DWARF_Type {
self.ptr.as_ref().unwrap().as_ref().as_ref()
}
}
impl ClassLike for Packed<'_> {
fn get_classlike(&self) -> &ffi::DWARF_types_ClassLike {
self.ptr.as_ref().unwrap().as_ref()
}
}
pub struct Class<'a> {
ptr: cxx::UniquePtr<ffi::DWARF_types_Class>,
_owner: PhantomData<&'a ()>,
}
impl FromFFI<ffi::DWARF_types_Class> for Class<'_> {
fn from_ffi(cmd: cxx::UniquePtr<ffi::DWARF_types_Class>) -> Self {
Self {
ptr: cmd,
_owner: PhantomData,
}
}
}
impl DwarfType for Class<'_> {
fn get_base(&self) -> &ffi::DWARF_Type {
self.ptr.as_ref().unwrap().as_ref().as_ref()
}
}
impl ClassLike for Class<'_> {
fn get_classlike(&self) -> &ffi::DWARF_types_ClassLike {
self.ptr.as_ref().unwrap().as_ref()
}
}
declare_fwd_iterator!(
Members,
Member<'a>,
ffi::DWARF_types_ClassLike_Member,
ffi::DWARF_types_ClassLike,
ffi::DWARF_types_ClassLike_it_members
);
declare_fwd_iterator!(
Functions,
Function<'a>,
ffi::DWARF_Function,
ffi::DWARF_types_ClassLike,
ffi::DWARF_types_ClassLike_it_functions
);