use crate::{
error::TraceError,
gimli_extensions::{AttributeExt, DebuggingInformationEntryExt},
type_value_tree::{
value::Value,
variable_type::{Archetype, VariableType},
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_enumeration<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 name = get_entry_name(dwarf, unit, entry)?;
let mut underlying_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))
})???;
underlying_type_tree.root_mut().data_mut().name = "base".into();
let underlying_type_bitrange = underlying_type_tree.root().data().bit_range.clone();
type_value.data_mut().variable_type.name = name;
type_value.data_mut().variable_type.archetype = Archetype::Enumeration;
type_value.data_mut().bit_range = underlying_type_bitrange.clone();
type_value.push_back(underlying_type_tree);
let mut children = node.children();
while let Ok(Some(child)) = children.next() {
let enumerator_entry = child.entry();
if enumerator_entry.tag() != gimli::constants::DW_TAG_enumerator {
continue;
}
let enumerator_name = get_entry_name(dwarf, unit, enumerator_entry)?;
let const_value = enumerator_entry
.required_attr(unit, gimli::constants::DW_AT_const_value)?
.required_sdata_value()?;
type_value.push_back(TypeValueTree::new(TypeValue {
name: enumerator_name,
variable_type: VariableType {
name: "".into(),
archetype: Archetype::Enumerator,
},
bit_range: underlying_type_bitrange.clone(),
variable_value: Ok(Value::Int(const_value as i128)),
}));
}
Ok(type_value_tree)
}