rudy_dwarf/parser/
option.rs1use anyhow::Result;
4use rudy_types::{Discriminant, OptionLayout};
5
6use super::Parser;
7use crate::{
8 parser::{
9 children::child,
10 combinators::all,
11 enums::{enum_discriminant, enum_named_tuple_variant, PartiallyParsedEnumVariant},
12 primitives::{attr, identity, member_by_tag, resolve_type_shallow},
13 },
14 Die, DwarfDb,
15};
16
17pub struct OptionDefParser;
18
19pub fn option_def() -> OptionDefParser {
23 OptionDefParser
24}
25
26pub(super) fn parse_option_entry(
27) -> impl Parser<(String, usize, Discriminant, PartiallyParsedEnumVariant)> {
28 all((
29 attr::<String>(gimli::DW_AT_name),
30 attr::<usize>(gimli::DW_AT_byte_size),
31 member_by_tag(gimli::DW_TAG_variant_part).then(
32 enum_discriminant().and(
33 child(enum_named_tuple_variant("Some", (identity(),)).map(
36 |(discriminant, ((some_offset, some_type_entry),))| {
37 PartiallyParsedEnumVariant {
38 discriminant,
39 layout: some_type_entry,
40 offset: some_offset,
41 }
42 },
43 ))
44 .context("expected Some variant in Option type"),
45 ),
46 ),
47 ))
48 .map(|(name, size, (discriminant, some_variant))| (name, size, discriminant, some_variant))
49}
50
51impl Parser<OptionLayout<Die>> for OptionDefParser {
52 fn parse(&self, db: &dyn DwarfDb, entry: Die) -> Result<OptionLayout<Die>> {
53 tracing::debug!("resolving option type: {}", entry.print(db));
54 let (name, size, discriminant, some_variant) = parse_option_entry().parse(db, entry)?;
55
56 let some_type = resolve_type_shallow().parse(db, some_variant.layout)?;
58
59 Ok(OptionLayout {
60 name,
61 some_type,
62 some_offset: some_variant.offset,
63 size,
64 discriminant,
65 })
66 }
67}