witx_codegen/cpp/
union.rs1use super::*;
2use std::io::Write;
3
4impl CppGenerator {
5 fn define_union_member<T: Write>(
6 w: &mut PrettyWriter<T>,
7 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 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 Self::define_union_member(&mut w.new_block(), 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}