use std::fmt;
#[derive(Clone)]
#[allow(non_camel_case_types)]
pub struct Array<'dwarf, R: crate::gimli::Reader<Offset = usize>>
where
R: crate::gimli::Reader<Offset = usize>,
{
dwarf: &'dwarf crate::gimli::Dwarf<R>,
unit: &'dwarf crate::gimli::Unit<R, usize>,
entry: crate::gimli::DebuggingInformationEntry<'dwarf, 'dwarf, R>,
}
impl<'dwarf, R> Array<'dwarf, R>
where
R: crate::gimli::Reader<Offset = usize>,
{
pub(crate) fn from_dw_tag_array_type(
dwarf: &'dwarf crate::gimli::Dwarf<R>,
unit: &'dwarf crate::gimli::Unit<R, usize>,
entry: crate::gimli::DebuggingInformationEntry<'dwarf, 'dwarf, R>,
) -> Result<Self, crate::Error> {
crate::check_tag(&entry, crate::gimli::DW_TAG_array_type)?;
Ok(Self { dwarf, unit, entry })
}
#[allow(dead_code)]
pub(crate) fn dwarf(&self) -> &'dwarf crate::gimli::Dwarf<R> {
self.dwarf
}
#[allow(dead_code)]
pub(crate) fn unit(&self) -> &crate::gimli::Unit<R, usize> {
self.unit
}
#[allow(dead_code)]
pub(crate) fn entry(&self) -> &crate::gimli::DebuggingInformationEntry<'dwarf, 'dwarf, R> {
&self.entry
}
pub fn elt_type(&self) -> Result<super::Type<'dwarf, R>, crate::Error> {
super::Type::from_die(
self.dwarf,
self.unit,
self.unit.entry(crate::get_type(&self.entry)?)?,
)
}
pub fn len(&self) -> Result<u64, crate::Error> {
let mut tree = self.unit.entries_tree(Some(self.entry.offset()))?;
let root = tree.root()?;
let mut children = root.children();
let dw_tag_subrange_type = children
.next()?
.ok_or_else(|| crate::error::missing_child(crate::gimli::DW_TAG_subrange_type))?;
let dw_tag_subrange_type = dw_tag_subrange_type.entry();
crate::check_tag(dw_tag_subrange_type, crate::gimli::DW_TAG_subrange_type)?;
let dw_at_count = crate::get(dw_tag_subrange_type, crate::gimli::DW_AT_count)?;
let count = dw_at_count
.udata_value()
.ok_or_else(|| crate::error::invalid_attr(crate::gimli::DW_AT_count))?;
Ok(count)
}
pub fn bytes(&self) -> Result<u64, crate::Error> {
let len = self.len()?;
let elt_type = self.elt_type()?;
let elt_size = elt_type.size()?;
len.checked_mul(elt_size)
.ok_or_else(crate::error::arithmetic_overflow)
}
}
impl<'dwarf, R> fmt::Debug for Array<'dwarf, R>
where
R: crate::gimli::Reader<Offset = usize>,
{
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
let mut debug_tuple = f.debug_tuple("deflect::schema::array");
debug_tuple.field(&crate::debug::DebugEntry::new(
self.dwarf,
self.unit,
&self.entry,
));
debug_tuple.finish()
}
}
impl<'dwarf, R> fmt::Display for Array<'dwarf, R>
where
R: crate::gimli::Reader<Offset = usize>,
{
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
super::Name::from_die(self.dwarf(), self.unit(), self.entry())
.map_err(crate::fmt_err)?
.fmt(f)
}
}