diff --git a/src/ir/context.rs b/src/ir/context.rs index 30c45dcc7c..ee15bcf544 100644 --- a/src/ir/context.rs +++ b/src/ir/context.rs @@ -2113,21 +2113,9 @@ If you encounter an error missing from this list, please file an issue or a PR!" } } - /// Is the item with the given `name` blacklisted? Or is the item with the given - /// `name` and `id` replaced by another type, and effectively blacklisted? - pub fn blacklisted_by_name>(&self, path: &[String], id: Id) -> bool { - let id = id.into(); - debug_assert!( - self.in_codegen_phase(), - "You're not supposed to call this yet" - ); - self.options.blacklisted_types.matches(&path[1..].join("::")) || - self.is_replaced_type(path, id) - } - /// Has the item with the given `name` and `id` been replaced by another /// type? - fn is_replaced_type>(&self, path: &[String], id: Id) -> bool { + pub fn is_replaced_type>(&self, path: &[String], id: Id) -> bool { let id = id.into(); match self.replacements.get(path) { Some(replaced_by) if *replaced_by != id => true, diff --git a/src/ir/item.rs b/src/ir/item.rs index 91ec22b34b..927322eb52 100644 --- a/src/ir/item.rs +++ b/src/ir/item.rs @@ -631,8 +631,24 @@ impl Item { ctx.in_codegen_phase(), "You're not supposed to call this yet" ); - self.annotations.hide() || - ctx.blacklisted_by_name(&self.canonical_path(ctx), self.id) + if self.annotations.hide() { + return true; + } + + let path = self.canonical_path(ctx); + let name = path[1..].join("::"); + match self.kind { + ItemKind::Type(..) => { + ctx.options().blacklisted_types.matches(&name) || + ctx.is_replaced_type(&path, self.id) + } + ItemKind::Function(..) => { + ctx.options().blacklisted_functions.matches(&name) + } + // TODO: Add constant / namespace blacklisting? + ItemKind::Var(..) | + ItemKind::Module(..) => false, + } } /// Is this a reference to another type? diff --git a/src/lib.rs b/src/lib.rs index 606671a237..f12b3db521 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -290,6 +290,20 @@ impl Builder { }) .count(); + self.options + .blacklisted_functions + .get_items() + .iter() + .map(|item| { + output_vector.push("--blacklist-function".into()); + output_vector.push( + item.trim_left_matches("^") + .trim_right_matches("$") + .into(), + ); + }) + .count(); + if !self.options.layout_tests { output_vector.push("--no-layout-tests".into()); } @@ -705,6 +719,13 @@ impl Builder { self } + /// Hide the given function from the generated bindings. Regular expressions + /// are supported. + pub fn blacklist_function>(mut self, arg: T) -> Builder { + self.options.blacklisted_functions.insert(arg); + self + } + /// Treat the given type as opaque in the generated bindings. Regular /// expressions are supported. pub fn opaque_type>(mut self, arg: T) -> Builder { @@ -1260,6 +1281,10 @@ struct BindgenOptions { /// anywhere in the generated code. blacklisted_types: RegexSet, + /// The set of functions that have been blacklisted and should not appear + /// in the generated code. + blacklisted_functions: RegexSet, + /// The set of types that should be treated as opaque structures in the /// generated code. opaque_types: RegexSet, @@ -1469,6 +1494,7 @@ impl BindgenOptions { self.whitelisted_types.build(); self.whitelisted_functions.build(); self.blacklisted_types.build(); + self.blacklisted_functions.build(); self.opaque_types.build(); self.bitfield_enums.build(); self.constified_enums.build(); @@ -1498,9 +1524,10 @@ impl Default for BindgenOptions { let rust_target = RustTarget::default(); BindgenOptions { - rust_target: rust_target, + rust_target, rust_features: rust_target.into(), blacklisted_types: Default::default(), + blacklisted_functions: Default::default(), opaque_types: Default::default(), rustfmt_path: Default::default(), whitelisted_types: Default::default(), diff --git a/src/options.rs b/src/options.rs index 5169fb9a28..c65a80fc50 100644 --- a/src/options.rs +++ b/src/options.rs @@ -71,6 +71,13 @@ where .takes_value(true) .multiple(true) .number_of_values(1), + Arg::with_name("blacklist-function") + .long("blacklist-function") + .help("Mark as hidden.") + .value_name("function") + .takes_value(true) + .multiple(true) + .number_of_values(1), Arg::with_name("no-layout-tests") .long("no-layout-tests") .help("Avoid generating layout tests for any type."), @@ -350,6 +357,12 @@ where } } + if let Some(hidden_functions) = matches.values_of("blacklist-function") { + for fun in hidden_functions { + builder = builder.blacklist_function(fun); + } + } + if matches.is_present("builtins") { builder = builder.emit_builtins(); } diff --git a/tests/expectations/tests/blacklist-function.rs b/tests/expectations/tests/blacklist-function.rs new file mode 100644 index 0000000000..b1d5564339 --- /dev/null +++ b/tests/expectations/tests/blacklist-function.rs @@ -0,0 +1,26 @@ +/* automatically generated by rust-bindgen */ + +#![allow( + dead_code, + non_snake_case, + non_camel_case_types, + non_upper_case_globals +)] + +#[allow(non_snake_case, non_camel_case_types, non_upper_case_globals)] +pub mod root { + #[allow(unused_imports)] + use self::super::root; + pub mod foo { + #[allow(unused_imports)] + use self::super::super::root; + } + pub mod bar { + #[allow(unused_imports)] + use self::super::super::root; + extern "C" { + #[link_name = "\u{1}_ZN3bar18NamespacedFunctionEv"] + pub fn NamespacedFunction(); + } + } +} diff --git a/tests/expectations/tests/layout_mbuf.rs b/tests/expectations/tests/layout_mbuf.rs index 0dbc362fcf..af58ca1c99 100644 --- a/tests/expectations/tests/layout_mbuf.rs +++ b/tests/expectations/tests/layout_mbuf.rs @@ -1,6 +1,11 @@ /* automatically generated by rust-bindgen */ -#![allow(dead_code, non_snake_case, non_camel_case_types, non_upper_case_globals)] +#![allow( + dead_code, + non_snake_case, + non_camel_case_types, + non_upper_case_globals +)] #[repr(C)] #[derive(Copy, Clone, Debug, Default, Eq, Hash, Ord, PartialEq, PartialOrd)] @@ -474,10 +479,7 @@ fn bindgen_test_layout_rte_mbuf__bindgen_ty_3__bindgen_ty_1__bindgen_ty_1__bindg ); assert_eq!( unsafe { - &(*(::std::ptr::null::< - rte_mbuf__bindgen_ty_3__bindgen_ty_1__bindgen_ty_1__bindgen_ty_1, - >())) - .hash as *const _ as usize + & ( * ( :: std :: ptr :: null :: < rte_mbuf__bindgen_ty_3__bindgen_ty_1__bindgen_ty_1__bindgen_ty_1 > ( ) ) ) . hash as * const _ as usize }, 0usize, concat!( @@ -489,10 +491,7 @@ fn bindgen_test_layout_rte_mbuf__bindgen_ty_3__bindgen_ty_1__bindgen_ty_1__bindg ); assert_eq!( unsafe { - &(*(::std::ptr::null::< - rte_mbuf__bindgen_ty_3__bindgen_ty_1__bindgen_ty_1__bindgen_ty_1, - >())) - .id as *const _ as usize + & ( * ( :: std :: ptr :: null :: < rte_mbuf__bindgen_ty_3__bindgen_ty_1__bindgen_ty_1__bindgen_ty_1 > ( ) ) ) . id as * const _ as usize }, 2usize, concat!( diff --git a/tests/expectations/tests/layout_mbuf_1_0.rs b/tests/expectations/tests/layout_mbuf_1_0.rs index 0bfcc13e56..da9d84b821 100644 --- a/tests/expectations/tests/layout_mbuf_1_0.rs +++ b/tests/expectations/tests/layout_mbuf_1_0.rs @@ -1,6 +1,11 @@ /* automatically generated by rust-bindgen */ -#![allow(dead_code, non_snake_case, non_camel_case_types, non_upper_case_globals)] +#![allow( + dead_code, + non_snake_case, + non_camel_case_types, + non_upper_case_globals +)] #[repr(C)] #[derive(Copy, Clone, Debug, Default, Eq, Hash, Ord, PartialEq, PartialOrd)] @@ -528,10 +533,7 @@ fn bindgen_test_layout_rte_mbuf__bindgen_ty_3__bindgen_ty_1__bindgen_ty_1__bindg ); assert_eq!( unsafe { - &(*(::std::ptr::null::< - rte_mbuf__bindgen_ty_3__bindgen_ty_1__bindgen_ty_1__bindgen_ty_1, - >())) - .hash as *const _ as usize + & ( * ( :: std :: ptr :: null :: < rte_mbuf__bindgen_ty_3__bindgen_ty_1__bindgen_ty_1__bindgen_ty_1 > ( ) ) ) . hash as * const _ as usize }, 0usize, concat!( @@ -543,10 +545,7 @@ fn bindgen_test_layout_rte_mbuf__bindgen_ty_3__bindgen_ty_1__bindgen_ty_1__bindg ); assert_eq!( unsafe { - &(*(::std::ptr::null::< - rte_mbuf__bindgen_ty_3__bindgen_ty_1__bindgen_ty_1__bindgen_ty_1, - >())) - .id as *const _ as usize + & ( * ( :: std :: ptr :: null :: < rte_mbuf__bindgen_ty_3__bindgen_ty_1__bindgen_ty_1__bindgen_ty_1 > ( ) ) ) . id as * const _ as usize }, 2usize, concat!( diff --git a/tests/expectations/tests/sentry-defined-multiple-times.rs b/tests/expectations/tests/sentry-defined-multiple-times.rs index 887d84bb10..7f96b45023 100644 --- a/tests/expectations/tests/sentry-defined-multiple-times.rs +++ b/tests/expectations/tests/sentry-defined-multiple-times.rs @@ -1,8 +1,11 @@ /* automatically generated by rust-bindgen */ - -#![allow(dead_code, non_snake_case, non_camel_case_types, non_upper_case_globals)] - +#![allow( + dead_code, + non_snake_case, + non_camel_case_types, + non_upper_case_globals +)] #[allow(non_snake_case, non_camel_case_types, non_upper_case_globals)] pub mod root { @@ -274,10 +277,7 @@ pub mod root { ); assert_eq!( unsafe { - &(*(::std::ptr::null::< - OuterDoubleInlineWrapper_InnerDoubleInlineWrapper_sentry, - >())) - .i_am_double_wrapper_inline_sentry as *const _ as usize + & ( * ( :: std :: ptr :: null :: < OuterDoubleInlineWrapper_InnerDoubleInlineWrapper_sentry > ( ) ) ) . i_am_double_wrapper_inline_sentry as * const _ as usize }, 0usize, concat!( diff --git a/tests/headers/blacklist-function.hpp b/tests/headers/blacklist-function.hpp new file mode 100644 index 0000000000..c4a923fcea --- /dev/null +++ b/tests/headers/blacklist-function.hpp @@ -0,0 +1,11 @@ +// bindgen-flags: --blacklist-function "ExternFunction" --blacklist-function "foo::NamespacedFunction" --enable-cxx-namespaces + +extern "C" void ExternFunction(); + +namespace foo { + void NamespacedFunction(); +} + +namespace bar { + void NamespacedFunction(); +} diff --git a/tests/headers/dupe-enum-variant-in-namespace.h b/tests/headers/dupe-enum-variant-in-namespace.h index 6d72437dd2..2b6fb93a8e 100644 --- a/tests/headers/dupe-enum-variant-in-namespace.h +++ b/tests/headers/dupe-enum-variant-in-namespace.h @@ -1,4 +1,4 @@ -// bindgen-flags: --rustified-enum ".*" --enable-cxx-namespaces -- -x c++ +// bindgen-flags: --rustified-enum ".*" --enable-cxx-namespaces -- -x c++ -std=c++11 namespace foo { enum class Bar : unsigned {