summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-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
-rw-r--r--tests/expectations/tests/anon_union.rs8
-rw-r--r--tests/expectations/tests/anon_union_1_0.rs8
-rw-r--r--tests/expectations/tests/forward-declaration-autoptr.rs2
-rw-r--r--tests/expectations/tests/forward_declared_complex_types.rs4
-rw-r--r--tests/expectations/tests/forward_declared_complex_types_1_0.rs23
-rw-r--r--tests/expectations/tests/issue-1238-fwd-no-copy.rs10
-rw-r--r--tests/expectations/tests/issue-654-struct-fn-collision.rs2
-rw-r--r--tests/expectations/tests/issue-801-opaque-sloppiness.rs2
-rw-r--r--tests/expectations/tests/layout_array.rs13
-rw-r--r--tests/expectations/tests/same_struct_name_in_different_namespaces.rs2
-rw-r--r--tests/expectations/tests/template.rs2
-rw-r--r--tests/headers/issue-1238-fwd-no-copy.h3
19 files changed, 96 insertions, 80 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)
}
diff --git a/tests/expectations/tests/anon_union.rs b/tests/expectations/tests/anon_union.rs
index 68927914..446cd589 100644
--- a/tests/expectations/tests/anon_union.rs
+++ b/tests/expectations/tests/anon_union.rs
@@ -17,14 +17,14 @@ pub enum TErrorResult_UnionState {
HasMessage = 0,
}
#[repr(C)]
-#[derive(Debug, Default, Copy, Clone, Hash, PartialEq, Eq)]
+#[derive(Debug, Copy, Clone)]
pub struct TErrorResult_Message {
- pub _address: u8,
+ _unused: [u8; 0],
}
#[repr(C)]
-#[derive(Debug, Default, Copy, Clone, Hash, PartialEq, Eq)]
+#[derive(Debug, Copy, Clone)]
pub struct TErrorResult_DOMExceptionInfo {
- pub _address: u8,
+ _unused: [u8; 0],
}
#[repr(C)]
pub union TErrorResult__bindgen_ty_1 {
diff --git a/tests/expectations/tests/anon_union_1_0.rs b/tests/expectations/tests/anon_union_1_0.rs
index 80111b90..60e2e0c5 100644
--- a/tests/expectations/tests/anon_union_1_0.rs
+++ b/tests/expectations/tests/anon_union_1_0.rs
@@ -61,14 +61,14 @@ pub enum TErrorResult_UnionState {
HasMessage = 0,
}
#[repr(C)]
-#[derive(Debug, Default, Copy, Clone, Hash, PartialEq, Eq)]
+#[derive(Debug, Copy, Clone)]
pub struct TErrorResult_Message {
- pub _address: u8,
+ _unused: [u8; 0],
}
#[repr(C)]
-#[derive(Debug, Default, Copy, Clone, Hash, PartialEq, Eq)]
+#[derive(Debug, Copy, Clone)]
pub struct TErrorResult_DOMExceptionInfo {
- pub _address: u8,
+ _unused: [u8; 0],
}
#[repr(C)]
#[derive(Debug, Default, Copy, Clone, Hash, PartialEq, Eq)]
diff --git a/tests/expectations/tests/forward-declaration-autoptr.rs b/tests/expectations/tests/forward-declaration-autoptr.rs
index b465836d..5d3c3eaa 100644
--- a/tests/expectations/tests/forward-declaration-autoptr.rs
+++ b/tests/expectations/tests/forward-declaration-autoptr.rs
@@ -1,9 +1,7 @@
/* automatically generated by rust-bindgen */
-
#![allow(dead_code, non_snake_case, non_camel_case_types, non_upper_case_globals)]
-
#[repr(C)]
#[derive(Debug, Copy, Clone)]
pub struct Foo {
diff --git a/tests/expectations/tests/forward_declared_complex_types.rs b/tests/expectations/tests/forward_declared_complex_types.rs
index 970d6d59..1132bfbe 100644
--- a/tests/expectations/tests/forward_declared_complex_types.rs
+++ b/tests/expectations/tests/forward_declared_complex_types.rs
@@ -1,9 +1,7 @@
/* automatically generated by rust-bindgen */
-
#![allow(dead_code, non_snake_case, non_camel_case_types, non_upper_case_globals)]
-
#[repr(C)]
#[derive(Debug, Default, Copy, Clone)]
pub struct Foo_empty {
@@ -60,7 +58,7 @@ extern "C" {
pub fn baz_struct(f: *mut Foo);
}
#[repr(C)]
-#[derive(Debug, Copy, Clone)]
+#[derive(Copy, Clone)]
pub struct Union {
_unused: [u8; 0],
}
diff --git a/tests/expectations/tests/forward_declared_complex_types_1_0.rs b/tests/expectations/tests/forward_declared_complex_types_1_0.rs
index 04fe9a3c..0a6a32be 100644
--- a/tests/expectations/tests/forward_declared_complex_types_1_0.rs
+++ b/tests/expectations/tests/forward_declared_complex_types_1_0.rs
@@ -1,9 +1,7 @@
/* automatically generated by rust-bindgen */
-
#![allow(dead_code, non_snake_case, non_camel_case_types, non_upper_case_globals)]
-
#[repr(C)]
#[derive(Debug, Default, Copy)]
pub struct Foo_empty {
@@ -28,10 +26,15 @@ impl Clone for Foo_empty {
}
}
#[repr(C)]
-#[derive(Debug, Copy, Clone)]
+#[derive(Debug, Copy)]
pub struct Foo {
_unused: [u8; 0],
}
+impl Clone for Foo {
+ fn clone(&self) -> Self {
+ *self
+ }
+}
#[repr(C)]
#[derive(Debug, Copy)]
pub struct Bar {
@@ -70,19 +73,29 @@ extern "C" {
pub fn baz_struct(f: *mut Foo);
}
#[repr(C)]
-#[derive(Debug, Copy, Clone)]
+#[derive(Copy)]
pub struct Union {
_unused: [u8; 0],
}
+impl Clone for Union {
+ fn clone(&self) -> Self {
+ *self
+ }
+}
extern "C" {
#[link_name = "\u{1}_Z9baz_unionP5Union"]
pub fn baz_union(u: *mut Union);
}
#[repr(C)]
-#[derive(Debug, Copy, Clone)]
+#[derive(Debug, Copy)]
pub struct Quux {
_unused: [u8; 0],
}
+impl Clone for Quux {
+ fn clone(&self) -> Self {
+ *self
+ }
+}
extern "C" {
#[link_name = "\u{1}_Z9baz_classP4Quux"]
pub fn baz_class(q: *mut Quux);
diff --git a/tests/expectations/tests/issue-1238-fwd-no-copy.rs b/tests/expectations/tests/issue-1238-fwd-no-copy.rs
new file mode 100644
index 00000000..f2156dfb
--- /dev/null
+++ b/tests/expectations/tests/issue-1238-fwd-no-copy.rs
@@ -0,0 +1,10 @@
+/* automatically generated by rust-bindgen */
+
+#![allow(dead_code, non_snake_case, non_camel_case_types, non_upper_case_globals)]
+
+#[repr(C)]
+#[derive(Debug)]
+pub struct MyType {
+ _unused: [u8; 0],
+}
+pub type MyTypeT = MyType;
diff --git a/tests/expectations/tests/issue-654-struct-fn-collision.rs b/tests/expectations/tests/issue-654-struct-fn-collision.rs
index 8b2bb533..fbd8cca3 100644
--- a/tests/expectations/tests/issue-654-struct-fn-collision.rs
+++ b/tests/expectations/tests/issue-654-struct-fn-collision.rs
@@ -1,9 +1,7 @@
/* automatically generated by rust-bindgen */
-
#![allow(dead_code, non_snake_case, non_camel_case_types, non_upper_case_globals)]
-
#[repr(C)]
#[derive(Debug, Copy, Clone)]
pub struct foo {
diff --git a/tests/expectations/tests/issue-801-opaque-sloppiness.rs b/tests/expectations/tests/issue-801-opaque-sloppiness.rs
index b3ad9d05..76deebba 100644
--- a/tests/expectations/tests/issue-801-opaque-sloppiness.rs
+++ b/tests/expectations/tests/issue-801-opaque-sloppiness.rs
@@ -1,9 +1,7 @@
/* automatically generated by rust-bindgen */
-
#![allow(dead_code, non_snake_case, non_camel_case_types, non_upper_case_globals)]
-
#[repr(C)]
#[derive(Debug, Copy, Clone)]
pub struct A {
diff --git a/tests/expectations/tests/layout_array.rs b/tests/expectations/tests/layout_array.rs
index 51676999..8429c4d4 100644
--- a/tests/expectations/tests/layout_array.rs
+++ b/tests/expectations/tests/layout_array.rs
@@ -1,9 +1,7 @@
/* automatically generated by rust-bindgen */
-
#![allow(dead_code, non_snake_case, non_camel_case_types, non_upper_case_globals)]
-
pub const RTE_CACHE_LINE_SIZE: ::std::os::raw::c_uint = 64;
pub const RTE_MEMPOOL_OPS_NAMESIZE: ::std::os::raw::c_uint = 32;
pub const RTE_MEMPOOL_MAX_OPS_IDX: ::std::os::raw::c_uint = 16;
@@ -21,9 +19,8 @@ pub struct rte_mempool {
/// it will most likely point to a different type of data structure, and
/// will be transparent to the application programmer.
/// This function should set mp->pool_data.
-pub type rte_mempool_alloc_t = ::std::option::Option<
- unsafe extern "C" fn(mp: *mut rte_mempool) -> ::std::os::raw::c_int,
->;
+pub type rte_mempool_alloc_t =
+ ::std::option::Option<unsafe extern "C" fn(mp: *mut rte_mempool) -> ::std::os::raw::c_int>;
/// Free the opaque private data pointed to by mp->pool_data pointer.
pub type rte_mempool_free_t = ::std::option::Option<unsafe extern "C" fn(mp: *mut rte_mempool)>;
/// Enqueue an object into the external pool.
@@ -43,10 +40,8 @@ pub type rte_mempool_dequeue_t = ::std::option::Option<
) -> ::std::os::raw::c_int,
>;
/// Return the number of available objects in the external pool.
-pub type rte_mempool_get_count = ::std::option::Option<
- unsafe extern "C" fn(mp: *const rte_mempool)
- -> ::std::os::raw::c_uint,
->;
+pub type rte_mempool_get_count =
+ ::std::option::Option<unsafe extern "C" fn(mp: *const rte_mempool) -> ::std::os::raw::c_uint>;
/// Structure defining mempool operations structure
#[repr(C)]
#[derive(Copy, Clone)]
diff --git a/tests/expectations/tests/same_struct_name_in_different_namespaces.rs b/tests/expectations/tests/same_struct_name_in_different_namespaces.rs
index 03ac70b8..9a8c1efa 100644
--- a/tests/expectations/tests/same_struct_name_in_different_namespaces.rs
+++ b/tests/expectations/tests/same_struct_name_in_different_namespaces.rs
@@ -1,9 +1,7 @@
/* automatically generated by rust-bindgen */
-
#![allow(dead_code, non_snake_case, non_camel_case_types, non_upper_case_globals)]
-
#[repr(C)]
#[derive(Debug, Copy, Clone)]
pub struct JS_Zone {
diff --git a/tests/expectations/tests/template.rs b/tests/expectations/tests/template.rs
index 70c1cdcb..6083265c 100644
--- a/tests/expectations/tests/template.rs
+++ b/tests/expectations/tests/template.rs
@@ -1,9 +1,7 @@
/* automatically generated by rust-bindgen */
-
#![allow(dead_code, non_snake_case, non_camel_case_types, non_upper_case_globals)]
-
#[repr(C)]
#[derive(Debug, Hash, PartialEq, Eq)]
pub struct Foo<T> {
diff --git a/tests/headers/issue-1238-fwd-no-copy.h b/tests/headers/issue-1238-fwd-no-copy.h
new file mode 100644
index 00000000..150bbbeb
--- /dev/null
+++ b/tests/headers/issue-1238-fwd-no-copy.h
@@ -0,0 +1,3 @@
+// bindgen-flags: --no-copy MyType
+
+typedef struct MyType MyTypeT;