summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/codegen/mod.rs48
-rw-r--r--src/ir/analysis/derive_copy.rs7
-rw-r--r--src/ir/analysis/derive_default.rs5
-rw-r--r--src/ir/analysis/derive_hash.rs5
-rw-r--r--src/ir/analysis/derive_partialeq_or_partialord.rs5
-rw-r--r--src/ir/comp.rs21
-rw-r--r--src/ir/context.rs6
7 files changed, 52 insertions, 45 deletions
diff --git a/src/codegen/mod.rs b/src/codegen/mod.rs
index f9e5e77c..0ddcdc0a 100644
--- a/src/codegen/mod.rs
+++ b/src/codegen/mod.rs
@@ -1425,23 +1425,6 @@ impl CodeGenerator for CompInfo {
let layout = ty.layout(ctx);
let mut packed = self.is_packed(ctx, &layout);
- // generate tuple struct if struct or union is a forward declaration,
- // skip for now if template parameters are needed.
- //
- // NB: We generate a proper struct to avoid struct/function name
- // collisions.
- if self.is_forward_declaration() && used_template_params.is_none() {
- let struct_name = item.canonical_name(ctx);
- let struct_name = ctx.rust_ident_raw(struct_name);
- let tuple_struct = quote! {
- #[repr(C)]
- #[derive(Debug, Copy, Clone)]
- pub struct #struct_name { _unused: [u8; 0] }
- };
- result.push(tuple_struct);
- return;
- }
-
let canonical_name = item.canonical_name(ctx);
let canonical_ident = ctx.rust_ident(&canonical_name);
@@ -1497,14 +1480,6 @@ impl CodeGenerator for CompInfo {
}
}
- let is_union = self.kind() == CompKind::Union;
- if is_union {
- result.saw_union();
- if !self.can_be_rust_union(ctx) {
- result.saw_bindgen_union();
- }
- }
-
let mut methods = vec![];
if !is_opaque {
let codegen_depth = item.codegen_depth(ctx);
@@ -1529,8 +1504,14 @@ impl CodeGenerator for CompInfo {
}
}
+ let is_union = self.kind() == CompKind::Union;
let layout = item.kind().expect_type().layout(ctx);
- if is_union && !is_opaque {
+ 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(layout);
@@ -1594,7 +1575,11 @@ impl CodeGenerator for CompInfo {
//
// NOTE: This check is conveniently here to avoid the dummy fields we
// may add for unused template parameters.
- if item.is_zero_sized(ctx) {
+ if self.is_forward_declaration() {
+ fields.push(quote! {
+ _unused: [u8; 0],
+ });
+ } else if item.is_zero_sized(ctx) {
let has_address = if is_opaque {
// Generate the address field if it's an opaque type and
// couldn't determine the layout of the blob.
@@ -1664,12 +1649,11 @@ impl CodeGenerator for CompInfo {
if item.can_derive_default(ctx) {
derives.push("Default");
} else {
- needs_default_impl = ctx.options().derive_default;
+ needs_default_impl =
+ ctx.options().derive_default && !self.is_forward_declaration();
}
- if item.can_derive_copy(ctx) && !item.annotations().disallow_copy() &&
- ctx.options().derive_copy
- {
+ if item.can_derive_copy(ctx) && !item.annotations().disallow_copy() {
derives.push("Copy");
if ctx.options().rust_features().builtin_clone_impls() ||
@@ -1762,7 +1746,7 @@ impl CodeGenerator for CompInfo {
}
}
- if ctx.options().layout_tests {
+ if ctx.options().layout_tests && !self.is_forward_declaration() {
if let Some(layout) = layout {
let fn_name =
format!("bindgen_test_layout_{}", canonical_ident.as_str());
diff --git a/src/ir/analysis/derive_copy.rs b/src/ir/analysis/derive_copy.rs
index 8da47a7f..94d457d5 100644
--- a/src/ir/analysis/derive_copy.rs
+++ b/src/ir/analysis/derive_copy.rs
@@ -235,9 +235,10 @@ impl<'ctx> MonotoneFramework for CannotDeriveCopy<'ctx> {
if info.kind() == CompKind::Union {
if !self.ctx.options().rust_features().untagged_union() {
- // NOTE: If there's no template parameters we can derive copy
- // unconditionally, since arrays are magical for rustc, and
- // __BindgenUnionField always implements copy.
+ // NOTE: If there's no template parameters we can derive
+ // copy unconditionally, since arrays are magical for
+ // rustc, and __BindgenUnionField always implements
+ // copy.
trace!(
" comp can always derive debug if it's a Union and no template parameters"
);
diff --git a/src/ir/analysis/derive_default.rs b/src/ir/analysis/derive_default.rs
index f8f02df7..2c79a437 100644
--- a/src/ir/analysis/derive_default.rs
+++ b/src/ir/analysis/derive_default.rs
@@ -265,6 +265,11 @@ impl<'ctx> MonotoneFramework for CannotDeriveDefault<'ctx> {
"The early ty.is_opaque check should have handled this case"
);
+ if info.is_forward_declaration() {
+ trace!(" cannot derive Default for forward decls");
+ return self.insert(id);
+ }
+
if info.kind() == CompKind::Union {
if self.ctx.options().rust_features().untagged_union() {
trace!(" cannot derive Default for Rust unions");
diff --git a/src/ir/analysis/derive_hash.rs b/src/ir/analysis/derive_hash.rs
index 46790232..3fc31b39 100644
--- a/src/ir/analysis/derive_hash.rs
+++ b/src/ir/analysis/derive_hash.rs
@@ -251,6 +251,11 @@ impl<'ctx> MonotoneFramework for CannotDeriveHash<'ctx> {
"The early ty.is_opaque check should have handled this case"
);
+ if info.is_forward_declaration() {
+ trace!(" cannot derive Hash for forward decls");
+ return self.insert(id);
+ }
+
if info.kind() == CompKind::Union {
if self.ctx.options().rust_features().untagged_union() {
trace!(" cannot derive Hash for Rust unions");
diff --git a/src/ir/analysis/derive_partialeq_or_partialord.rs b/src/ir/analysis/derive_partialeq_or_partialord.rs
index 92861341..2641d2b3 100644
--- a/src/ir/analysis/derive_partialeq_or_partialord.rs
+++ b/src/ir/analysis/derive_partialeq_or_partialord.rs
@@ -236,6 +236,11 @@ impl<'ctx> CannotDerivePartialEqOrPartialOrd<'ctx> {
"The early ty.is_opaque check should have handled this case"
);
+ if info.is_forward_declaration() {
+ trace!(" cannot derive for forward decls");
+ return CanDerive::No;
+ }
+
if info.kind() == CompKind::Union {
if self.ctx.options().rust_features().untagged_union() {
trace!(
diff --git a/src/ir/comp.rs b/src/ir/comp.rs
index 5008dcfd..50d0ddb1 100644
--- a/src/ir/comp.rs
+++ b/src/ir/comp.rs
@@ -1543,13 +1543,20 @@ impl CompInfo {
/// 1. Current RustTarget allows for `untagged_union`
/// 2. Each field can derive `Copy`
pub fn can_be_rust_union(&self, ctx: &BindgenContext) -> bool {
- ctx.options().rust_features().untagged_union() &&
- self.fields().iter().all(|f| match *f {
- Field::DataMember(ref field_data) => {
- field_data.ty().can_derive_copy(ctx)
- }
- Field::Bitfields(_) => true,
- })
+ if !ctx.options().rust_features().untagged_union() {
+ return false;
+ }
+
+ if self.is_forward_declaration() {
+ return false;
+ }
+
+ self.fields().iter().all(|f| match *f {
+ Field::DataMember(ref field_data) => {
+ field_data.ty().can_derive_copy(ctx)
+ }
+ Field::Bitfields(_) => true,
+ })
}
}
diff --git a/src/ir/context.rs b/src/ir/context.rs
index cddbeb2d..21801c9f 100644
--- a/src/ir/context.rs
+++ b/src/ir/context.rs
@@ -222,8 +222,7 @@ where
T: Copy + Into<ItemId>
{
fn can_derive_default(&self, ctx: &BindgenContext) -> bool {
- ctx.options().derive_default &&
- ctx.lookup_can_derive_default(*self)
+ ctx.options().derive_default && ctx.lookup_can_derive_default(*self)
}
}
@@ -232,7 +231,7 @@ where
T: Copy + Into<ItemId>
{
fn can_derive_copy(&self, ctx: &BindgenContext) -> bool {
- ctx.lookup_can_derive_copy(*self)
+ ctx.options().derive_copy && ctx.lookup_can_derive_copy(*self)
}
}
@@ -2452,6 +2451,7 @@ impl BindgenContext {
// Look up the computed value for whether the item with `id` can
// derive `Copy` or not.
let id = id.into();
+
!self.lookup_has_type_param_in_array(id) &&
!self.cannot_derive_copy.as_ref().unwrap().contains(&id)
}