summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTaylor Foxhall <lxmachina@gmail.com>2017-10-19 13:48:16 -0400
committerTaylor Foxhall <lxmachina@gmail.com>2017-10-24 23:49:24 -0400
commita35ab85716eeae986d662a4cafd7896e6423321d (patch)
tree41e4d86f4874ee1efbf322d7edccdb01b95712ed
parentc30a8050e5def6a9fcb43e6a683f8446d15a3006 (diff)
Resolve #962 - implement --no-copy with tests
generated bindings from test headers
-rw-r--r--src/ir/analysis/derive_copy.rs4
-rw-r--r--src/ir/context.rs8
-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
10 files changed, 178 insertions, 0 deletions
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 1979e34d..b7332b8e 100644
--- a/src/ir/context.rs
+++ b/src/ir/context.rs
@@ -2455,8 +2455,16 @@ impl BindgenContext {
/// Check if `--no-partialeq` flag is enabled for this item.
pub fn no_partialeq_by_name(&self, item: &Item) -> bool {
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;
+};