summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorEmilio Cobos Álvarez <emilio@crisal.io>2017-01-26 17:26:02 +0100
committerEmilio Cobos Álvarez <emilio@crisal.io>2017-01-26 20:34:57 +0100
commit78e425f921085030585c93ed1eb0b96b5cb3b4b5 (patch)
treed74fddd91158b753aeb47a13bfc7e122b17b63f1
parent7d7c49aaa3b9b5c01d2afac70660575f1bb562b2 (diff)
ir: Allow whitelisting non-recursivelyv0.20.3
Fixes #429
-rw-r--r--src/ir/context.rs26
-rw-r--r--src/lib.rs14
-rw-r--r--src/options.rs7
-rw-r--r--tests/expectations/tests/no-recursive-whitelisting.rs20
-rw-r--r--tests/headers/no-recursive-whitelisting.h7
5 files changed, 62 insertions, 12 deletions
diff --git a/src/ir/context.rs b/src/ir/context.rs
index b0143bd5..50774a43 100644
--- a/src/ir/context.rs
+++ b/src/ir/context.rs
@@ -1155,15 +1155,15 @@ pub struct WhitelistedItemsIter<'ctx, 'gen>
{
ctx: &'ctx BindgenContext<'gen>,
- // The set of whitelisted items we have seen. If you think of traversing
- // whitelisted items like GC tracing, this is the mark bits, and contains
- // both black and gray items.
+ /// The set of whitelisted items we have seen. If you think of traversing
+ /// whitelisted items like GC tracing, this is the mark bits, and contains
+ /// both black and gray items.
seen: ItemSet,
- // The set of whitelisted items that we have seen but have yet to iterate
- // over and collect transitive references from. To return to the GC analogy,
- // this is the mark stack, containing the set of gray items which we have
- // not finished tracing yet.
+ /// The set of whitelisted items that we have seen but have yet to iterate
+ /// over and collect transitive references from. To return to the GC analogy,
+ /// this is the mark stack, containing the set of gray items which we have
+ /// not finished tracing yet.
to_iterate: Vec<ItemId>,
}
@@ -1181,12 +1181,14 @@ impl<'ctx, 'gen> Iterator for WhitelistedItemsIter<'ctx, 'gen>
debug_assert!(self.seen.contains(&id));
debug_assert!(self.ctx.items.contains_key(&id));
- let mut sub_types = ItemSet::new();
- id.collect_types(self.ctx, &mut sub_types, &());
+ if self.ctx.options().whitelist_recursively {
+ let mut sub_types = ItemSet::new();
+ id.collect_types(self.ctx, &mut sub_types, &());
- for id in sub_types {
- if self.seen.insert(id) {
- self.to_iterate.push(id);
+ for id in sub_types {
+ if self.seen.insert(id) {
+ self.to_iterate.push(id);
+ }
}
}
diff --git a/src/lib.rs b/src/lib.rs
index c28e3168..dabab152 100644
--- a/src/lib.rs
+++ b/src/lib.rs
@@ -188,6 +188,16 @@ impl Builder {
self
}
+ /// Whether to whitelist types recursively or not. Defaults to true.
+ ///
+ /// This can be used to get bindgen to generate _exactly_ the types you want
+ /// in your bindings, and then import other types manually via other means
+ /// (like `raw_line`).
+ pub fn whitelist_recursively(mut self, doit: bool) -> Self {
+ self.options.whitelist_recursively = doit;
+ self
+ }
+
/// Generate a C/C++ file that includes the header and has dummy uses of
/// every type defined in the header.
pub fn dummy_uses<T: Into<String>>(mut self, dummy_uses: T) -> Builder {
@@ -529,6 +539,9 @@ pub struct BindgenOptions {
/// Wether to keep documentation comments in the generated output. See the
/// documentation for more details.
pub generate_comments: bool,
+
+ /// Wether to whitelist types recursively. Defaults to true.
+ pub whitelist_recursively: bool,
}
impl BindgenOptions {
@@ -574,6 +587,7 @@ impl Default for BindgenOptions {
codegen_config: CodegenConfig::all(),
conservative_inline_namespaces: false,
generate_comments: true,
+ whitelist_recursively: true,
}
}
}
diff --git a/src/options.rs b/src/options.rs
index 7b18eb03..307ea6b0 100644
--- a/src/options.rs
+++ b/src/options.rs
@@ -46,6 +46,9 @@ pub fn builder_from_flags<I>(args: I)
.long("no-doc-comments")
.help("Avoid including doc comments in the output, see: \
https://github.com/servo/rust-bindgen/issues/426"),
+ Arg::with_name("no-recursive-whitelist")
+ .long("no-recursive-whitelist")
+ .help("Avoid whitelisting types recursively"),
Arg::with_name("builtins")
.long("builtins")
.help("Output bindings for builtin definitions, e.g. \
@@ -279,6 +282,10 @@ pub fn builder_from_flags<I>(args: I)
builder = builder.generate_comments(false);
}
+ if matches.is_present("no-recursive-whitelist") {
+ builder = builder.whitelist_recursively(false);
+ }
+
if let Some(opaque_types) = matches.values_of("opaque-type") {
for ty in opaque_types {
builder = builder.opaque_type(ty);
diff --git a/tests/expectations/tests/no-recursive-whitelisting.rs b/tests/expectations/tests/no-recursive-whitelisting.rs
new file mode 100644
index 00000000..5bc21665
--- /dev/null
+++ b/tests/expectations/tests/no-recursive-whitelisting.rs
@@ -0,0 +1,20 @@
+/* automatically generated by rust-bindgen */
+
+
+#![allow(non_snake_case)]
+
+pub enum Bar {}
+
+#[repr(C)]
+#[derive(Debug, Copy)]
+pub struct Foo {
+ pub baz: *mut Bar,
+}
+#[test]
+fn bindgen_test_layout_Foo() {
+ assert_eq!(::std::mem::size_of::<Foo>() , 8usize);
+ assert_eq!(::std::mem::align_of::<Foo>() , 8usize);
+}
+impl Clone for Foo {
+ fn clone(&self) -> Self { *self }
+}
diff --git a/tests/headers/no-recursive-whitelisting.h b/tests/headers/no-recursive-whitelisting.h
new file mode 100644
index 00000000..1d805d93
--- /dev/null
+++ b/tests/headers/no-recursive-whitelisting.h
@@ -0,0 +1,7 @@
+// bindgen-flags: --no-recursive-whitelist --whitelist-type "Foo" --raw-line "pub enum Bar {}"
+
+struct Bar;
+
+struct Foo {
+ struct Bar* baz;
+};