summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--book/src/nocopy.md10
-rw-r--r--src/ir/analysis/derive_copy.rs4
-rw-r--r--src/ir/context.rs6
-rw-r--r--src/lib.rs26
-rw-r--r--src/options.rs13
-rw-r--r--tests/expectations/tests/no_copy_opaque.rs24
-rw-r--r--tests/expectations/tests/no_copy_whitelisted.rs34
-rw-r--r--tests/expectations/tests/whitelisted_item_references_no_copy.rs52
-rw-r--r--tests/headers/no_copy_opaque.hpp5
-rw-r--r--tests/headers/no_copy_whitelisted.hpp5
-rw-r--r--tests/headers/whitelisted_item_references_no_copy.hpp7
11 files changed, 186 insertions, 0 deletions
diff --git a/book/src/nocopy.md b/book/src/nocopy.md
index 893f0932..06879ed1 100644
--- a/book/src/nocopy.md
+++ b/book/src/nocopy.md
@@ -6,6 +6,16 @@ Clone)]` to a translated type definition will compile, it still shouldn't do
that for reasons it can't know. In these cases, the `nocopy` annotation can be
used to prevent bindgen to autoderive the `Copy` and `Clone` traits for a type.
+###Library
+
+* [`bindgen::Builder::no_copy`](https://docs.rs/bindgen/0.23.1/bindgen/struct.Builder.html#method.no_copy)
+
+### Command Line
+
+* `--no-copy <regex>`
+
+### Annotations
+
```c
/**
* Although bindgen can't know, this struct is not safe to move because pthread
diff --git a/src/ir/analysis/derive_copy.rs b/src/ir/analysis/derive_copy.rs
index ba40141e..8da47a7f 100644
--- a/src/ir/analysis/derive_copy.rs
+++ b/src/ir/analysis/derive_copy.rs
@@ -143,6 +143,10 @@ impl<'ctx> MonotoneFramework for CannotDeriveCopy<'ctx> {
}
};
+ if self.ctx.no_copy_by_name(&item) {
+ return self.insert(id);
+ }
+
if item.is_opaque(self.ctx, &()) {
let layout_can_derive = ty.layout(self.ctx).map_or(true, |l| {
l.opaque().can_trivially_derive_copy()
diff --git a/src/ir/context.rs b/src/ir/context.rs
index e8f82b3d..0acf8d41 100644
--- a/src/ir/context.rs
+++ b/src/ir/context.rs
@@ -2489,6 +2489,12 @@ impl BindgenContext {
let name = item.canonical_path(self)[1..].join("::");
self.options().no_partialeq_types.matches(&name)
}
+
+ /// Check if `--no-copy` flag is enabled for this item.
+ pub fn no_copy_by_name(&self, item: &Item) -> bool {
+ let name = item.canonical_path(self)[1..].join("::");
+ self.options().no_copy_types.matches(&name)
+ }
}
/// A builder struct for configuring item resolution options.
diff --git a/src/lib.rs b/src/lib.rs
index 7e2db0d5..86af0550 100644
--- a/src/lib.rs
+++ b/src/lib.rs
@@ -522,6 +522,20 @@ impl Builder {
})
.count();
+ self.options
+ .no_copy_types
+ .get_items()
+ .iter()
+ .map(|item| {
+ output_vector.push("--no-copy".into());
+ output_vector.push(
+ item.trim_left_matches("^")
+ .trim_right_matches("$")
+ .into(),
+ );
+ })
+ .count();
+
output_vector
}
@@ -1158,6 +1172,13 @@ impl Builder {
self.options.no_partialeq_types.insert(arg);
self
}
+
+ /// Don't derive `Copy` for a given type. Regular
+ /// expressions are supported.
+ pub fn no_copy(mut self, arg: String) -> Self {
+ self.options.no_copy_types.insert(arg);
+ self
+ }
}
/// Configuration options for generated bindings.
@@ -1345,6 +1366,9 @@ struct BindgenOptions {
/// The set of types that we should not derive `PartialEq` for.
no_partialeq_types: RegexSet,
+
+ /// The set of types that we should not derive `Copy` for.
+ no_copy_types: RegexSet,
}
/// TODO(emilio): This is sort of a lie (see the error message that results from
@@ -1363,6 +1387,7 @@ impl BindgenOptions {
self.constified_enum_modules.build();
self.rustified_enums.build();
self.no_partialeq_types.build();
+ self.no_copy_types.build();
}
/// Update rust target version
@@ -1434,6 +1459,7 @@ impl Default for BindgenOptions {
rustfmt_bindings: true,
rustfmt_configuration_file: None,
no_partialeq_types: Default::default(),
+ no_copy_types: Default::default(),
}
}
}
diff --git a/src/options.rs b/src/options.rs
index 64ee249e..38b47b6a 100644
--- a/src/options.rs
+++ b/src/options.rs
@@ -285,6 +285,13 @@ where
.takes_value(true)
.multiple(true)
.number_of_values(1),
+ Arg::with_name("no-copy")
+ .long("no-copy")
+ .help("Avoid deriving Copy for types matching <regex>.")
+ .value_name("regex")
+ .takes_value(true)
+ .multiple(true)
+ .number_of_values(1),
]) // .args()
.get_matches_from(args);
@@ -579,6 +586,12 @@ where
}
}
+ if let Some(no_partialeq) = matches.values_of("no-copy") {
+ for regex in no_partialeq {
+ builder = builder.no_copy(String::from(regex));
+ }
+ }
+
let verbose = matches.is_present("verbose");
Ok((builder, output, verbose))
diff --git a/tests/expectations/tests/no_copy_opaque.rs b/tests/expectations/tests/no_copy_opaque.rs
new file mode 100644
index 00000000..8de90cd4
--- /dev/null
+++ b/tests/expectations/tests/no_copy_opaque.rs
@@ -0,0 +1,24 @@
+/* automatically generated by rust-bindgen */
+
+
+#![allow(dead_code, non_snake_case, non_camel_case_types, non_upper_case_globals)]
+
+
+#[repr(C)]
+#[derive(Debug, Default)]
+pub struct NoCopy {
+ pub _bindgen_opaque_blob: u32,
+}
+#[test]
+fn bindgen_test_layout_NoCopy() {
+ assert_eq!(
+ ::std::mem::size_of::<NoCopy>(),
+ 4usize,
+ concat!("Size of: ", stringify!(NoCopy))
+ );
+ assert_eq!(
+ ::std::mem::align_of::<NoCopy>(),
+ 4usize,
+ concat!("Alignment of ", stringify!(NoCopy))
+ );
+}
diff --git a/tests/expectations/tests/no_copy_whitelisted.rs b/tests/expectations/tests/no_copy_whitelisted.rs
new file mode 100644
index 00000000..79219625
--- /dev/null
+++ b/tests/expectations/tests/no_copy_whitelisted.rs
@@ -0,0 +1,34 @@
+/* automatically generated by rust-bindgen */
+
+
+#![allow(dead_code, non_snake_case, non_camel_case_types, non_upper_case_globals)]
+
+
+#[repr(C)]
+#[derive(Debug, Default)]
+pub struct NoCopy {
+ pub i: ::std::os::raw::c_int,
+}
+#[test]
+fn bindgen_test_layout_NoCopy() {
+ assert_eq!(
+ ::std::mem::size_of::<NoCopy>(),
+ 4usize,
+ concat!("Size of: ", stringify!(NoCopy))
+ );
+ assert_eq!(
+ ::std::mem::align_of::<NoCopy>(),
+ 4usize,
+ concat!("Alignment of ", stringify!(NoCopy))
+ );
+ assert_eq!(
+ unsafe { &(*(0 as *const NoCopy)).i as *const _ as usize },
+ 0usize,
+ concat!(
+ "Alignment of field: ",
+ stringify!(NoCopy),
+ "::",
+ stringify!(i)
+ )
+ );
+}
diff --git a/tests/expectations/tests/whitelisted_item_references_no_copy.rs b/tests/expectations/tests/whitelisted_item_references_no_copy.rs
new file mode 100644
index 00000000..91b6d46a
--- /dev/null
+++ b/tests/expectations/tests/whitelisted_item_references_no_copy.rs
@@ -0,0 +1,52 @@
+/* automatically generated by rust-bindgen */
+
+
+#![allow(dead_code, non_snake_case, non_camel_case_types, non_upper_case_globals)]
+
+
+#[repr(C)]
+#[derive(Debug, Default)]
+pub struct NoCopy {
+ pub _address: u8,
+}
+#[test]
+fn bindgen_test_layout_NoCopy() {
+ assert_eq!(
+ ::std::mem::size_of::<NoCopy>(),
+ 1usize,
+ concat!("Size of: ", stringify!(NoCopy))
+ );
+ assert_eq!(
+ ::std::mem::align_of::<NoCopy>(),
+ 1usize,
+ concat!("Alignment of ", stringify!(NoCopy))
+ );
+}
+#[repr(C)]
+#[derive(Debug, Default)]
+pub struct WhitelistMe {
+ pub a: NoCopy,
+}
+#[test]
+fn bindgen_test_layout_WhitelistMe() {
+ assert_eq!(
+ ::std::mem::size_of::<WhitelistMe>(),
+ 1usize,
+ concat!("Size of: ", stringify!(WhitelistMe))
+ );
+ assert_eq!(
+ ::std::mem::align_of::<WhitelistMe>(),
+ 1usize,
+ concat!("Alignment of ", stringify!(WhitelistMe))
+ );
+ assert_eq!(
+ unsafe { &(*(0 as *const WhitelistMe)).a as *const _ as usize },
+ 0usize,
+ concat!(
+ "Alignment of field: ",
+ stringify!(WhitelistMe),
+ "::",
+ stringify!(a)
+ )
+ );
+}
diff --git a/tests/headers/no_copy_opaque.hpp b/tests/headers/no_copy_opaque.hpp
new file mode 100644
index 00000000..c21f213a
--- /dev/null
+++ b/tests/headers/no_copy_opaque.hpp
@@ -0,0 +1,5 @@
+// bindgen-flags: --opaque-type "NoCopy" --no-copy "NoCopy"
+
+class NoCopy {
+ int i;
+};
diff --git a/tests/headers/no_copy_whitelisted.hpp b/tests/headers/no_copy_whitelisted.hpp
new file mode 100644
index 00000000..db44a8a7
--- /dev/null
+++ b/tests/headers/no_copy_whitelisted.hpp
@@ -0,0 +1,5 @@
+// bindgen-flags: --whitelist-type "NoCopy" --no-copy "NoCopy"
+
+class NoCopy {
+ int i;
+};
diff --git a/tests/headers/whitelisted_item_references_no_copy.hpp b/tests/headers/whitelisted_item_references_no_copy.hpp
new file mode 100644
index 00000000..755bbbdd
--- /dev/null
+++ b/tests/headers/whitelisted_item_references_no_copy.hpp
@@ -0,0 +1,7 @@
+// bindgen-flags: --whitelist-type "WhitelistMe" --no-copy "NoCopy"
+
+struct NoCopy {};
+
+class WhitelistMe {
+ NoCopy a;
+};