summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorbors-servo <lbergstrom+bors@mozilla.com>2017-10-26 20:50:36 -0500
committerGitHub <noreply@github.com>2017-10-26 20:50:36 -0500
commitf315d2c99e9566401193c125ac71bc8cf56443f6 (patch)
tree95c88c1f3ffebdf1c11b307811dbc5a16b1ffeba
parent208b98a55f23b92d874219ec6546f06c3bea5cd5 (diff)
parent5d271568e07522503ddc361152633385a537cc2d (diff)
Auto merge of #1105 - seemyvest:issue-964, r=seemyvest
Add --no-hash <regex> flag Issue #964 - [x] Adding a new RegexSet member to bindgen::Builder (similar to the whitelisted_types set). - [x] A Builder method to add strings to that RegexSet. - [x] Plumbing in src/options.rs to convert --no-hash <regex> CLI flags into invocations of the builder method. - [x] Making the MonotoneFramework::constrain function in src/ir/analysis/derive_hash.rs check if the given item is explicitly marked not to be Hash, and if so, inserting it into the self.cannot_derive_hash set via return self.insert(id). - [x] Tests! - [x] When the no-hash type is transitively referenced by a whitelisted item - [x] When the no-hash type is explicitly whitelisted - [x] When the no-hash type is marked opaque r? @fitzgen
-rw-r--r--src/ir/analysis/derive_hash.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-hash-opaque.rs24
-rw-r--r--tests/expectations/tests/no-hash-whitelisted.rs34
-rw-r--r--tests/expectations/tests/whitelisted-item-references-no-hash.rs52
-rw-r--r--tests/headers/no-hash-opaque.hpp5
-rw-r--r--tests/headers/no-hash-whitelisted.hpp5
-rw-r--r--tests/headers/whitelisted-item-references-no-hash.hpp7
10 files changed, 176 insertions, 0 deletions
diff --git a/src/ir/analysis/derive_hash.rs b/src/ir/analysis/derive_hash.rs
index d2eac677..46790232 100644
--- a/src/ir/analysis/derive_hash.rs
+++ b/src/ir/analysis/derive_hash.rs
@@ -127,6 +127,10 @@ impl<'ctx> MonotoneFramework for CannotDeriveHash<'ctx> {
}
};
+ if self.ctx.no_hash_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_hash()
diff --git a/src/ir/context.rs b/src/ir/context.rs
index 0acf8d41..138a69b9 100644
--- a/src/ir/context.rs
+++ b/src/ir/context.rs
@@ -2495,6 +2495,12 @@ impl BindgenContext {
let name = item.canonical_path(self)[1..].join("::");
self.options().no_copy_types.matches(&name)
}
+
+ /// Chech if `--no-hash` flag is enabled for this item.
+ pub fn no_hash_by_name(&self, item: &Item) -> bool {
+ let name = item.canonical_path(self)[1..].join("::");
+ self.options().no_hash_types.matches(&name)
+ }
}
/// A builder struct for configuring item resolution options.
diff --git a/src/lib.rs b/src/lib.rs
index 86af0550..deadf478 100644
--- a/src/lib.rs
+++ b/src/lib.rs
@@ -536,6 +536,20 @@ impl Builder {
})
.count();
+ self.options
+ .no_hash_types
+ .get_items()
+ .iter()
+ .map(|item| {
+ output_vector.push("--no-hash".into());
+ output_vector.push(
+ item.trim_left_matches("^")
+ .trim_right_matches("$")
+ .into(),
+ );
+ })
+ .count();
+
output_vector
}
@@ -1179,6 +1193,13 @@ impl Builder {
self.options.no_copy_types.insert(arg);
self
}
+
+ /// Don't derive `Hash` for a given type. Regular
+ /// expressions are supported.
+ pub fn no_hash(mut self, arg: String) -> Builder {
+ self.options.no_hash_types.insert(arg);
+ self
+ }
}
/// Configuration options for generated bindings.
@@ -1369,6 +1390,9 @@ struct BindgenOptions {
/// The set of types that we should not derive `Copy` for.
no_copy_types: RegexSet,
+
+ /// The set of types that we should not derive `Hash` for.
+ no_hash_types: RegexSet,
}
/// TODO(emilio): This is sort of a lie (see the error message that results from
@@ -1388,6 +1412,7 @@ impl BindgenOptions {
self.rustified_enums.build();
self.no_partialeq_types.build();
self.no_copy_types.build();
+ self.no_hash_types.build();
}
/// Update rust target version
@@ -1460,6 +1485,7 @@ impl Default for BindgenOptions {
rustfmt_configuration_file: None,
no_partialeq_types: Default::default(),
no_copy_types: Default::default(),
+ no_hash_types: Default::default(),
}
}
}
diff --git a/src/options.rs b/src/options.rs
index 38b47b6a..d06fb6a2 100644
--- a/src/options.rs
+++ b/src/options.rs
@@ -292,6 +292,13 @@ where
.takes_value(true)
.multiple(true)
.number_of_values(1),
+ Arg::with_name("no-hash")
+ .long("no-hash")
+ .help("Avoid deriving Hash for types matching <regex>.")
+ .value_name("regex")
+ .takes_value(true)
+ .multiple(true)
+ .number_of_values(1),
]) // .args()
.get_matches_from(args);
@@ -592,6 +599,12 @@ where
}
}
+ if let Some(no_hash) = matches.values_of("no-hash") {
+ for regex in no_hash {
+ builder = builder.no_hash(String::from(regex));
+ }
+ }
+
let verbose = matches.is_present("verbose");
Ok((builder, output, verbose))
diff --git a/tests/expectations/tests/no-hash-opaque.rs b/tests/expectations/tests/no-hash-opaque.rs
new file mode 100644
index 00000000..c4211c71
--- /dev/null
+++ b/tests/expectations/tests/no-hash-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, Copy, Clone)]
+pub struct NoHash {
+ pub _bindgen_opaque_blob: u32,
+}
+#[test]
+fn bindgen_test_layout_NoHash() {
+ assert_eq!(
+ ::std::mem::size_of::<NoHash>(),
+ 4usize,
+ concat!("Size of: ", stringify!(NoHash))
+ );
+ assert_eq!(
+ ::std::mem::align_of::<NoHash>(),
+ 4usize,
+ concat!("Alignment of ", stringify!(NoHash))
+ );
+}
diff --git a/tests/expectations/tests/no-hash-whitelisted.rs b/tests/expectations/tests/no-hash-whitelisted.rs
new file mode 100644
index 00000000..9997d062
--- /dev/null
+++ b/tests/expectations/tests/no-hash-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, Copy, Clone)]
+pub struct NoHash {
+ pub i: ::std::os::raw::c_int,
+}
+#[test]
+fn bindgen_test_layout_NoHash() {
+ assert_eq!(
+ ::std::mem::size_of::<NoHash>(),
+ 4usize,
+ concat!("Size of: ", stringify!(NoHash))
+ );
+ assert_eq!(
+ ::std::mem::align_of::<NoHash>(),
+ 4usize,
+ concat!("Alignment of ", stringify!(NoHash))
+ );
+ assert_eq!(
+ unsafe { &(*(0 as *const NoHash)).i as *const _ as usize },
+ 0usize,
+ concat!(
+ "Alignment of field: ",
+ stringify!(NoHash),
+ "::",
+ stringify!(i)
+ )
+ );
+}
diff --git a/tests/expectations/tests/whitelisted-item-references-no-hash.rs b/tests/expectations/tests/whitelisted-item-references-no-hash.rs
new file mode 100644
index 00000000..5a77ff75
--- /dev/null
+++ b/tests/expectations/tests/whitelisted-item-references-no-hash.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, Copy, Clone)]
+pub struct NoHash {
+ pub _address: u8,
+}
+#[test]
+fn bindgen_test_layout_NoHash() {
+ assert_eq!(
+ ::std::mem::size_of::<NoHash>(),
+ 1usize,
+ concat!("Size of: ", stringify!(NoHash))
+ );
+ assert_eq!(
+ ::std::mem::align_of::<NoHash>(),
+ 1usize,
+ concat!("Alignment of ", stringify!(NoHash))
+ );
+}
+#[repr(C)]
+#[derive(Debug, Default, Copy, Clone)]
+pub struct WhitelistMe {
+ pub a: NoHash,
+}
+#[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-hash-opaque.hpp b/tests/headers/no-hash-opaque.hpp
new file mode 100644
index 00000000..c1db2cd1
--- /dev/null
+++ b/tests/headers/no-hash-opaque.hpp
@@ -0,0 +1,5 @@
+// bindgen-flags: --with-derive-hash --opaque-type "NoHash" --no-hash "NoHash"
+
+class NoHash {
+ int i;
+};
diff --git a/tests/headers/no-hash-whitelisted.hpp b/tests/headers/no-hash-whitelisted.hpp
new file mode 100644
index 00000000..77c90864
--- /dev/null
+++ b/tests/headers/no-hash-whitelisted.hpp
@@ -0,0 +1,5 @@
+// bindgen-flags: --with-derive-hash --whitelist-type "NoHash" --no-hash "NoHash"
+
+class NoHash {
+ int i;
+};
diff --git a/tests/headers/whitelisted-item-references-no-hash.hpp b/tests/headers/whitelisted-item-references-no-hash.hpp
new file mode 100644
index 00000000..e656d32d
--- /dev/null
+++ b/tests/headers/whitelisted-item-references-no-hash.hpp
@@ -0,0 +1,7 @@
+// bindgen-flags: --with-derive-hash --whitelist-type "WhitelistMe" --no-hash "NoHash"
+
+struct NoHash {};
+
+class WhitelistMe {
+ NoHash a;
+};