use lief_ffi as ffi;
use super::lexical_block::LexicalBlock;
use super::variable::Variables;
use super::{Parameters, Scope, Type};
use crate::Error;
use crate::Range;
use crate::assembly;
use crate::common::{FromFFI, into_optional, into_ranges};
use crate::to_result;
use crate::{DebugLocation, DeclOpt};
use crate::{declare_fwd_iterator, declare_lazy_iterator};
use std::marker::PhantomData;
pub struct Function<'a> {
ptr: cxx::UniquePtr<ffi::DWARF_Function>,
_owner: PhantomData<&'a ()>,
}
impl FromFFI<ffi::DWARF_Function> for Function<'_> {
fn from_ffi(ptr: cxx::UniquePtr<ffi::DWARF_Function>) -> Self {
Self {
ptr,
_owner: PhantomData,
}
}
}
impl Function<'_> {
pub fn name(&self) -> String {
self.ptr.name().to_string()
}
pub fn linkage_name(&self) -> String {
self.ptr.linkage_name().to_string()
}
pub fn address(&self) -> Result<u64, Error> {
to_result!(ffi::DWARF_Function::address, self);
}
pub fn variables(&self) -> Variables<'_> {
Variables::new(self.ptr.variables())
}
pub fn is_artificial(&self) -> bool {
self.ptr.is_artificial()
}
pub fn is_external(&self) -> bool {
self.ptr.is_external()
}
pub fn size(&self) -> u64 {
self.ptr.size()
}
pub fn ranges(&self) -> Vec<Range> {
into_ranges(self.ptr.ranges())
}
pub fn debug_location(&self) -> DebugLocation {
DebugLocation::from_ffi(self.ptr.debug_location())
}
pub fn return_type(&self) -> Option<Type<'_>> {
into_optional(self.ptr.get_type())
}
pub fn parameters(&self) -> ParametersIt<'_> {
ParametersIt::new(self.ptr.parameters())
}
pub fn thrown_types(&self) -> ThrownTypes<'_> {
ThrownTypes::new(self.ptr.thrown_types())
}
pub fn scope(&self) -> Option<Scope<'_>> {
into_optional(self.ptr.scope())
}
pub fn instructions(&self) -> Instructions<'_> {
Instructions::new(self.ptr.instructions())
}
pub fn description(&self) -> String {
self.ptr.description().to_string()
}
pub fn lexical_blocks(&self) -> LexicalBlocks<'_> {
LexicalBlocks::new(self.ptr.lexical_blocks())
}
pub fn to_decl(&self) -> String {
self.ptr.to_decl().to_string()
}
pub fn to_decl_with_opt(&self, opt: &DeclOpt) -> String {
self.ptr.to_decl_with_opt(&opt.to_ffi()).to_string()
}
}
declare_fwd_iterator!(
Functions,
Function<'a>,
ffi::DWARF_Function,
ffi::DWARF_CompilationUnit,
ffi::DWARF_CompilationUnit_it_functions
);
declare_fwd_iterator!(
ParametersIt,
Parameters<'a>,
ffi::DWARF_Parameter,
ffi::DWARF_Function,
ffi::DWARF_Function_it_parameters
);
declare_fwd_iterator!(
ThrownTypes,
Type<'a>,
ffi::DWARF_Type,
ffi::DWARF_Function,
ffi::DWARF_Function_it_thrown_types
);
declare_lazy_iterator!(
Instructions,
assembly::Instructions,
ffi::asm_Instruction,
ffi::DWARF_Function,
ffi::DWARF_Function_it_instructions
);
declare_fwd_iterator!(
LexicalBlocks,
LexicalBlock<'a>,
ffi::DWARF_LexicalBlock,
ffi::DWARF_Function,
ffi::DWARF_Function_it_lexical_blocks
);