in src/bindgen/language_backend/clike.rs [468:540]
fn write_enum<W: Write>(&mut self, out: &mut SourceWriter<W>, e: &Enum) {
let size = e.repr.ty.map(|ty| ty.to_primitive().to_repr_c(self.config));
let has_data = e.tag.is_some();
let inline_tag_field = Enum::inline_tag_field(&e.repr);
let tag_name = e.tag_name();
let condition = e.cfg.to_condition(self.config);
condition.write_before(self.config, out);
self.write_documentation(out, &e.documentation);
self.write_generic_param(out, &e.generic_params);
// If the enum has data, we need to emit a struct or union for the data
// and enum for the tag. C++ supports nested type definitions, so we open
// the struct or union here and define the tag enum inside it (*).
if has_data && self.config.language == Language::Cxx {
e.open_struct_or_union(self.config, out, inline_tag_field);
}
// Emit the tag enum and everything related to it.
e.write_tag_enum(self.config, self, out, size, Self::write_enum_variant);
// If the enum has data, we need to emit structs for the variants and gather them together.
if has_data {
e.write_variant_defs(self.config, self, out);
out.new_line();
out.new_line();
// Open the struct or union for the data (**), gathering all the variants with data
// together, unless it's C++, then we have already opened that struct/union at (*) and
// are currently inside it.
if self.config.language != Language::Cxx {
e.open_struct_or_union(self.config, out, inline_tag_field);
}
// Emit tag field that is separate from all variants.
e.write_tag_field(self.config, out, size, inline_tag_field, tag_name);
out.new_line();
// Open union of all variants with data, only in the non-inline tag scenario.
if !inline_tag_field {
out.write("union");
out.open_brace();
}
// Emit fields for all variants with data.
e.write_variant_fields(self.config, self, out, inline_tag_field, Self::write_field);
// Close union of all variants with data, only in the non-inline tag scenario.
if !inline_tag_field {
out.close_brace(true);
}
// Emit convenience methods for the struct or enum for the data.
e.write_derived_functions_data(self.config, self, out, tag_name, Self::write_field);
// Emit the post_body section, if relevant.
if let Some(body) = self.config.export.post_body(&e.path) {
out.new_line();
out.write_raw_block(body);
}
// Close the struct or union opened either at (*) or at (**).
if self.generate_typedef() {
out.close_brace(false);
write!(out, " {};", e.export_name);
} else {
out.close_brace(true);
}
}
condition.write_after(self.config, out);
}