use crate::{
error::TraceError,
gimli_extensions::{AttributeExt, DebuggingInformationEntryExt},
type_value_tree::{variable_type::Archetype, TypeValue, TypeValueTree},
variables::{build_type_value_tree, get_entry_name, get_entry_type_reference_tree},
DefaultReader,
};
use gimli::{Abbreviations, DebugInfoOffset, Dwarf, Unit};
use std::collections::HashMap;
pub fn build_pointer<W: funty::Integral>(
dwarf: &Dwarf<DefaultReader>,
unit: &Unit<DefaultReader, usize>,
abbreviations: &Abbreviations,
node: gimli::EntriesTreeNode<DefaultReader>,
type_cache: &mut HashMap<DebugInfoOffset, Result<TypeValueTree<W>, TraceError>>,
) -> Result<TypeValueTree<W>, TraceError> {
let mut type_value_tree = TypeValueTree::new(TypeValue::default());
let mut type_value = type_value_tree.root_mut();
let entry = node.entry();
let entry_die_offset = entry.offset().to_debug_info_offset(&unit.header).unwrap();
let (pointee_type_name, pointee_type_die_offset) =
get_entry_type_reference_tree(unit, abbreviations, entry).map(|mut type_tree| {
type_tree.root().map(|root| {
let die_offset = root
.entry()
.offset()
.to_debug_info_offset(&unit.header)
.unwrap();
let pointee_type_name = get_entry_name(dwarf, unit, root.entry());
pointee_type_name.map(|ptn| (ptn, die_offset))
})
})???;
let name =
get_entry_name(dwarf, unit, entry).unwrap_or_else(|_| format!("&{pointee_type_name}"));
let address_class = entry
.required_attr(unit, gimli::constants::DW_AT_address_class)?
.required_address_class()?;
if address_class != gimli::constants::DW_ADDR_none {
return Err(TraceError::UnexpectedPointerClass {
pointer_name: name,
class_value: address_class,
});
}
type_value.data_mut().variable_type.name = name;
type_value.data_mut().variable_type.archetype = Archetype::Pointer(pointee_type_die_offset);
type_value.data_mut().bit_range = 0..W::BITS as u64;
type_cache.insert(entry_die_offset, Ok(type_value_tree.clone()));
#[allow(clippy::map_entry)] if !type_cache.contains_key(&pointee_type_die_offset) {
let pointee_type_tree = get_entry_type_reference_tree(unit, abbreviations, entry).map(
|mut type_tree| {
type_tree
.root()
.map(|root| build_type_value_tree(dwarf, unit, abbreviations, root, type_cache))
},
)???;
type_cache.insert(pointee_type_die_offset, Ok(pointee_type_tree));
}
Ok(type_value_tree)
}