use lief_ffi as ffi;
use super::Type;
use crate::common::FromFFI;
use crate::common::into_optional;
use crate::dwarf::Scope;
use crate::{DebugLocation, DeclOpt};
use crate::{Error, declare_fwd_iterator, to_result};
use std::marker::PhantomData;
pub struct Variable<'a> {
ptr: cxx::UniquePtr<ffi::DWARF_Variable>,
_owner: PhantomData<&'a ()>,
}
impl FromFFI<ffi::DWARF_Variable> for Variable<'_> {
fn from_ffi(ptr: cxx::UniquePtr<ffi::DWARF_Variable>) -> Self {
Self {
ptr,
_owner: PhantomData,
}
}
}
impl Variable<'_> {
pub fn name(&self) -> String {
self.ptr.name().to_string()
}
pub fn linkage_name(&self) -> Option<String> {
let name = self.ptr.name().to_string();
if !name.is_empty() {
return Some(name);
}
None
}
pub fn address(&self) -> Result<i64, Error> {
to_result!(ffi::DWARF_Variable::address, self);
}
pub fn size(&self) -> Result<u64, Error> {
to_result!(ffi::DWARF_Variable::size, self);
}
pub fn is_constexpr(&self) -> bool {
self.ptr.is_constexpr()
}
pub fn is_stack_based(&self) -> bool {
self.ptr.is_stack_based()
}
pub fn debug_location(&self) -> DebugLocation {
DebugLocation::from_ffi(self.ptr.debug_location())
}
pub fn get_type(&self) -> Option<Type<'_>> {
into_optional(self.ptr.get_type())
}
pub fn scope(&self) -> Option<Scope<'_>> {
into_optional(self.ptr.scope())
}
pub fn description(&self) -> String {
self.ptr.description().to_string()
}
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!(
Variables,
Variable<'a>,
ffi::DWARF_Variable,
ffi::DWARF_Function,
ffi::DWARF_Function_it_variables
);
declare_fwd_iterator!(
CompilationUnitVariables,
Variable<'a>,
ffi::DWARF_Variable,
ffi::DWARF_CompilationUnit,
ffi::DWARF_CompilationUnit_it_variables
);