diff options
author | Emilio Cobos Álvarez <emilio@crisal.io> | 2018-09-20 15:45:08 +0200 |
---|---|---|
committer | Emilio Cobos Álvarez <emilio@crisal.io> | 2018-09-22 01:38:53 +0200 |
commit | dcb9921446ddd38cdd2bc5d02911b65ca3dcf93b (patch) | |
tree | 33f37ba8ca299abc164117b4e9c078c2b19f7350 /src/codegen/mod.rs | |
parent | 6fc0a31febb63d77da1a38aa2eea9d10fbea0d0d (diff) |
codegen: Explicitly align unions if needed.
Also adds a test header I missed from the previous PR.
Fixes #1393
Diffstat (limited to 'src/codegen/mod.rs')
-rw-r--r-- | src/codegen/mod.rs | 47 |
1 files changed, 26 insertions, 21 deletions
diff --git a/src/codegen/mod.rs b/src/codegen/mod.rs index 67d6b6d5..1bff1e26 100644 --- a/src/codegen/mod.rs +++ b/src/codegen/mod.rs @@ -1540,27 +1540,6 @@ impl CodeGenerator for CompInfo { let is_union = self.kind() == CompKind::Union; let layout = item.kind().expect_type().layout(ctx); - if is_union && !is_opaque && !self.is_forward_declaration() { - result.saw_union(); - if !self.can_be_rust_union(ctx) { - result.saw_bindgen_union(); - } - - let layout = layout.expect("Unable to get layout information?"); - let ty = helpers::blob(ctx, layout); - - fields.push(if self.can_be_rust_union(ctx) { - quote! { - _bindgen_union_align: #ty , - } - } else { - struct_layout.saw_union(layout); - - quote! { - pub bindgen_union_field: #ty , - } - }); - } let mut explicit_align = None; if is_opaque { @@ -1603,6 +1582,32 @@ impl CodeGenerator for CompInfo { } } } + } else if is_union && !self.is_forward_declaration() { + result.saw_union(); + if !self.can_be_rust_union(ctx) { + result.saw_bindgen_union(); + } + + // TODO(emilio): It'd be nice to unify this with the struct path + // above somehow. + let layout = layout.expect("Unable to get layout information?"); + + if struct_layout.requires_explicit_align(layout) { + explicit_align = Some(layout.align); + } + + let ty = helpers::blob(ctx, layout); + fields.push(if self.can_be_rust_union(ctx) { + quote! { + _bindgen_union_align: #ty , + } + } else { + struct_layout.saw_union(layout); + + quote! { + pub bindgen_union_field: #ty , + } + }); } // C++ requires every struct to be addressable, so what C++ compilers do |