witx_codegen/cpp/
union.rs

1use super::*;
2use std::io::Write;
3
4impl CppGenerator {
5    fn define_union_member<T: Write>(
6        w: &mut PrettyWriter<T>,
7        // union_name: &str,
8        i: usize,
9        member: &ASUnionMember,
10    ) -> Result<(), Error> {
11        let member_type = member.type_.as_ref();
12        match member_type {
13            ASType::Void => {
14                w.write_line(format!(
15                    "// {}: (no associated content) if tag={}",
16                    member.name.as_var(),
17                    i
18                ))?;
19            }
20            _ => {
21                w.write_line(format!(
22                    "{} {}; // if tag={}",
23                    member_type.as_lang(),
24                    member.name.as_var(),
25                    i
26                ))?;
27            }
28        }
29        // Self::define_union_member_accessors(w, union_name, i, member)?;
30        Ok(())
31    }
32
33    pub fn define_as_union<T: Write>(
34        w: &mut PrettyWriter<T>,
35        name: &str,
36        union_: &ASUnion,
37    ) -> Result<(), Error> {
38        let tag_repr = union_.tag_repr.as_ref();
39        let inner_name = format!("{}_member", name);
40        w.write_line(format!("union {} {{", inner_name.as_type()))?;
41        for (i, member) in union_.members.iter().enumerate() {
42            // w.eob()?;
43            Self::define_union_member(&mut w.new_block(), /* name, */ i, member)?;
44        }
45        w.write_line("};")?.eob()?;
46
47        w.write_line(format!(
48            "struct __attribute__((packed)) {} {{",
49            name.as_type()
50        ))?;
51        {
52            let mut w = w.new_block();
53            w.write_line(format!("{} tag;", tag_repr.as_lang()))?;
54            let pad_len = union_.padding_after_tag;
55            for i in 0..(pad_len & 1) {
56                w.write_line(format!("uint8_t __pad8_{};", i))?;
57            }
58            for i in 0..(pad_len & 3) / 2 {
59                w.write_line(format!("uint16_t __pad16_{};", i))?;
60            }
61            for i in 0..(pad_len & 7) / 4 {
62                w.write_line(format!("uint32_t __pad32_{};", i))?;
63            }
64            for i in 0..pad_len / 8 {
65                w.write_line(format!("uint64_t __pad64_{};", i))?;
66            }
67
68            w.write_line(format!("{} member;", inner_name.as_type()))?;
69        }
70
71        w.write_line("};")?.eob()?;
72        Ok(())
73    }
74}