diff options
author | Emilio Cobos Álvarez <emilio@crisal.io> | 2017-01-26 17:26:02 +0100 |
---|---|---|
committer | Emilio Cobos Álvarez <emilio@crisal.io> | 2017-01-26 20:34:57 +0100 |
commit | 78e425f921085030585c93ed1eb0b96b5cb3b4b5 (patch) | |
tree | d74fddd91158b753aeb47a13bfc7e122b17b63f1 | |
parent | 7d7c49aaa3b9b5c01d2afac70660575f1bb562b2 (diff) |
ir: Allow whitelisting non-recursivelyv0.20.3
Fixes #429
-rw-r--r-- | src/ir/context.rs | 26 | ||||
-rw-r--r-- | src/lib.rs | 14 | ||||
-rw-r--r-- | src/options.rs | 7 | ||||
-rw-r--r-- | tests/expectations/tests/no-recursive-whitelisting.rs | 20 | ||||
-rw-r--r-- | tests/headers/no-recursive-whitelisting.h | 7 |
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); + } } } @@ -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; +}; |