diff options
-rw-r--r-- | bindgen-integration/build.rs | 46 | ||||
-rw-r--r-- | bindgen-integration/cpp/Test.h | 2 | ||||
-rwxr-xr-x | bindgen-integration/src/lib.rs | 120 | ||||
-rw-r--r-- | src/ir/context.rs | 14 | ||||
-rw-r--r-- | src/ir/item.rs | 100 |
5 files changed, 144 insertions, 138 deletions
diff --git a/bindgen-integration/build.rs b/bindgen-integration/build.rs index cadec267..61580175 100644 --- a/bindgen-integration/build.rs +++ b/bindgen-integration/build.rs @@ -1,12 +1,12 @@ extern crate bindgen; extern crate gcc; +use bindgen::callbacks::{MacroParsingBehavior, ParseCallbacks}; +use bindgen::Builder; use std::collections::HashSet; use std::env; use std::path::PathBuf; -use std::sync::{Arc, RwLock, Mutex}; -use bindgen::Builder; -use bindgen::callbacks::{MacroParsingBehavior, ParseCallbacks}; +use std::sync::{Arc, Mutex, RwLock}; #[derive(Debug)] struct MacroCallback { @@ -19,7 +19,7 @@ impl ParseCallbacks for MacroCallback { self.macros.write().unwrap().insert(name.into()); if name == "MY_ANNOYING_MACRO" { - return MacroParsingBehavior::Ignore + return MacroParsingBehavior::Ignore; } MacroParsingBehavior::Default @@ -27,9 +27,17 @@ impl ParseCallbacks for MacroCallback { fn item_name(&self, original_item_name: &str) -> Option<String> { if original_item_name.starts_with("my_prefixed_") { - Some(original_item_name.trim_start_matches("my_prefixed_").to_string()) + Some( + original_item_name + .trim_start_matches("my_prefixed_") + .to_string(), + ) } else if original_item_name.starts_with("MY_PREFIXED_") { - Some(original_item_name.trim_start_matches("MY_PREFIXED_").to_string()) + Some( + original_item_name + .trim_start_matches("MY_PREFIXED_") + .to_string(), + ) } else { None } @@ -37,14 +45,17 @@ impl ParseCallbacks for MacroCallback { fn str_macro(&self, name: &str, value: &[u8]) { match &name { - &"TESTMACRO_STRING_EXPANDED" | - &"TESTMACRO_STRING" | - &"TESTMACRO_INTEGER" => { + &"TESTMACRO_STRING_EXPANDED" + | &"TESTMACRO_STRING" + | &"TESTMACRO_INTEGER" => { // The integer test macro is, actually, not expected to show up here at all -- but // should produce an error if it does. - assert_eq!(value, b"Hello Preprocessor!", "str_macro handle received unexpected value"); + assert_eq!( + value, b"Hello Preprocessor!", + "str_macro handle received unexpected value" + ); *self.seen_hellos.lock().unwrap() += 1; - }, + } _ => {} } } @@ -52,7 +63,11 @@ impl ParseCallbacks for MacroCallback { impl Drop for MacroCallback { fn drop(&mut self) { - assert_eq!(*self.seen_hellos.lock().unwrap(), 2, "str_macro handle was not called once for all relevant macros") + assert_eq!( + *self.seen_hellos.lock().unwrap(), + 2, + "str_macro handle was not called once for all relevant macros" + ) } } @@ -69,10 +84,15 @@ fn main() { .enable_cxx_namespaces() .rustified_enum(".*") .raw_line("pub use self::root::*;") + .raw_line("extern { fn my_prefixed_function_to_remove(i: i32); }") .module_raw_line("root::testing", "pub type Bar = i32;") .header("cpp/Test.h") .clang_args(&["-x", "c++", "-std=c++11"]) - .parse_callbacks(Box::new(MacroCallback {macros: macros.clone(), seen_hellos: Mutex::new(0)})) + .parse_callbacks(Box::new(MacroCallback { + macros: macros.clone(), + seen_hellos: Mutex::new(0), + })) + .blacklist_function("my_prefixed_function_to_remove") .generate() .expect("Unable to generate bindings"); diff --git a/bindgen-integration/cpp/Test.h b/bindgen-integration/cpp/Test.h index 03a55b88..1299337b 100644 --- a/bindgen-integration/cpp/Test.h +++ b/bindgen-integration/cpp/Test.h @@ -195,3 +195,5 @@ struct my_prefixed_bar { struct my_prefixed_foo { my_prefixed_bar member; }; + +void my_prefixed_function_to_remove(); diff --git a/bindgen-integration/src/lib.rs b/bindgen-integration/src/lib.rs index 0e051df3..04617ff3 100755 --- a/bindgen-integration/src/lib.rs +++ b/bindgen-integration/src/lib.rs @@ -5,8 +5,8 @@ mod bindings { } use std::ffi::CStr; -use std::os::raw::c_int; use std::mem; +use std::os::raw::c_int; #[allow(unused)] use bindings::testing::Bar; // This type is generated from module_raw_line. @@ -14,7 +14,7 @@ use bindings::testing::Bar; // This type is generated from module_raw_line. #[test] fn test_static_array() { let mut test = unsafe { bindings::Test_COUNTDOWN.as_ptr() }; - let expected = unsafe { bindings::Test_countdown()}; + let expected = unsafe { bindings::Test_countdown() }; let also_expected = unsafe { bindings::Test_COUNTDOWN_PTR }; assert!(!test.is_null()); assert_eq!(also_expected, expected); @@ -56,63 +56,41 @@ fn test_overload() { #[test] fn test_bitfields_first() { - let mut first: bindings::bitfields::First = unsafe { - mem::zeroed() - }; - assert!(unsafe { - first.assert(0, 0, 0) - }); + let mut first: bindings::bitfields::First = unsafe { mem::zeroed() }; + assert!(unsafe { first.assert(0, 0, 0) }); first.set_three_bits_byte_one(2); first.set_six_bits_byte_two(42); first.set_two_bits_byte_two(1); - assert!(unsafe { - first.assert(2, 42, 1) - }); + assert!(unsafe { first.assert(2, 42, 1) }); } #[test] fn test_bitfields_second() { - let mut second: bindings::bitfields::Second = unsafe { - mem::zeroed() - }; - assert!(unsafe { - second.assert(0, false) - }); + let mut second: bindings::bitfields::Second = unsafe { mem::zeroed() }; + assert!(unsafe { second.assert(0, false) }); second.set_thirty_one_bits(1337); second.set_one_bit(true); - assert!(unsafe { - second.assert(1337, true) - }); + assert!(unsafe { second.assert(1337, true) }); } #[test] fn test_bitfields_third() { - let mut third: bindings::bitfields::Third = unsafe { - mem::zeroed() - }; + let mut third: bindings::bitfields::Third = unsafe { mem::zeroed() }; assert!(unsafe { - third.assert(0, - false, - bindings::bitfields::ItemKind::ITEM_KIND_UNO) + third.assert(0, false, bindings::bitfields::ItemKind::ITEM_KIND_UNO) }); third.set_flags(12345); third.set_is_whatever(true); third.set_kind(bindings::bitfields::ItemKind::ITEM_KIND_TRES); assert!(unsafe { - third.assert(12345, - true, - bindings::bitfields::ItemKind::ITEM_KIND_TRES) + third.assert(12345, true, bindings::bitfields::ItemKind::ITEM_KIND_TRES) }); } #[test] fn test_bitfields_fourth() { - let mut fourth: bindings::bitfields::Fourth = unsafe { - mem::zeroed() - }; - assert!(unsafe { - fourth.assert(bindings::bitfields::MyEnum::ONE, 0) - }); + let mut fourth: bindings::bitfields::Fourth = unsafe { mem::zeroed() }; + assert!(unsafe { fourth.assert(bindings::bitfields::MyEnum::ONE, 0) }); fourth.set_tag(bindings::bitfields::MyEnum::THREE); fourth.set_ptr(0xdeadbeef); @@ -123,32 +101,22 @@ fn test_bitfields_fourth() { #[test] fn test_bitfields_date2() { - let mut date: bindings::bitfields::Date2 = unsafe { - mem::zeroed() - }; - assert!(unsafe { - date.assert(0, 0, 0, 0, 0) - }); + let mut date: bindings::bitfields::Date2 = unsafe { mem::zeroed() }; + assert!(unsafe { date.assert(0, 0, 0, 0, 0) }); date.set_nWeekDay(6); // saturdays are the best date.set_nMonthDay(20); date.set_nMonth(11); date.set_nYear(95); date.set_byte(255); - assert!(unsafe { - date.assert(6, 20, 11, 95, 255) - }); + assert!(unsafe { date.assert(6, 20, 11, 95, 255) }); } #[test] fn test_bitfields_fifth() { - let mut date: bindings::bitfields::Fifth = unsafe { - mem::zeroed() - }; + let mut date: bindings::bitfields::Fifth = unsafe { mem::zeroed() }; - assert!(unsafe { - date.assert(0, 0, 0, 0, 0) - }); + assert!(unsafe { date.assert(0, 0, 0, 0, 0) }); date.byte = 255; // Set this first, to ensure we don't override it. @@ -157,40 +125,28 @@ fn test_bitfields_fifth() { date.set_nMonth(11); date.set_nYear(95); - assert!(unsafe { - date.assert(6, 20, 11, 95, 255) - }); + assert!(unsafe { date.assert(6, 20, 11, 95, 255) }); } #[test] fn test_bitfields_sixth() { - let mut date: bindings::bitfields::Sixth = unsafe { - mem::zeroed() - }; + let mut date: bindings::bitfields::Sixth = unsafe { mem::zeroed() }; - assert!(unsafe { - date.assert(0, 0, 0, 0) - }); + assert!(unsafe { date.assert(0, 0, 0, 0) }); date.byte = 255; date.set_nWeekDay(6); // saturdays are the best date.set_nMonthDay(20); date.set_nMonth(11); - assert!(unsafe { - date.assert(255, 6, 11, 20) - }); + assert!(unsafe { date.assert(255, 6, 11, 20) }); } #[test] fn test_bitfields_seventh() { - let mut large: bindings::bitfields::Seventh = unsafe { - mem::zeroed() - }; + let mut large: bindings::bitfields::Seventh = unsafe { mem::zeroed() }; - assert!(unsafe { - large.assert(false, 0, 0, 0, 0, false, 0) - }); + assert!(unsafe { large.assert(false, 0, 0, 0, 0, false, 0) }); large.set_first_one_bit(true); large.set_second_thirty_bits(375028802); @@ -217,32 +173,26 @@ fn test_bitfields_seventh() { fn test_bitfield_constructors() { use std::mem; let mut first = bindings::bitfields::First { - _bitfield_1: bindings::bitfields::First::new_bitfield_1(1, 2, 3) + _bitfield_1: bindings::bitfields::First::new_bitfield_1(1, 2, 3), }; - assert!(unsafe { - first.assert(1, 2, 3) - }); + assert!(unsafe { first.assert(1, 2, 3) }); let mut second = bindings::bitfields::Second { _bitfield_1: bindings::bitfields::Second::new_bitfield_1(1337, true), __bindgen_align: [], }; - assert!(unsafe { - second.assert(1337, true) - }); + assert!(unsafe { second.assert(1337, true) }); let mut third = bindings::bitfields::Third { _bitfield_1: bindings::bitfields::Third::new_bitfield_1( 42, false, - bindings::bitfields::ItemKind::ITEM_KIND_TRES + bindings::bitfields::ItemKind::ITEM_KIND_TRES, ), __bindgen_align: [], }; assert!(unsafe { - third.assert(42, - false, - bindings::bitfields::ItemKind::ITEM_KIND_TRES) + third.assert(42, false, bindings::bitfields::ItemKind::ITEM_KIND_TRES) }); } @@ -266,7 +216,9 @@ fn test_destructors() { impl Drop for bindings::InheritsFromVirtualDestructor { fn drop(&mut self) { - unsafe { bindings::InheritsFromVirtualDestructor_InheritsFromVirtualDestructor_destructor(self) } + unsafe { + bindings::InheritsFromVirtualDestructor_InheritsFromVirtualDestructor_destructor(self) + } } } @@ -286,9 +238,9 @@ fn test_virtual_dtor() { #[test] fn test_item_rename() { assert_eq!(bindings::CONST_VALUE, 3); - assert_eq!(unsafe{ bindings::function_name() }, 4); + assert_eq!(unsafe { bindings::function_name() }, 4); - let _foo = bindings::foo{ - member: bindings::bar{foo: 2} + let _foo = bindings::foo { + member: bindings::bar { foo: 2 }, }; -}
\ No newline at end of file +} diff --git a/src/ir/context.rs b/src/ir/context.rs index c0f92464..3f49f8a0 100644 --- a/src/ir/context.rs +++ b/src/ir/context.rs @@ -10,7 +10,7 @@ use super::derive::{CanDeriveCopy, CanDeriveDebug, CanDeriveDefault, CanDeriveHash, CanDerivePartialOrd, CanDeriveOrd, CanDerivePartialEq, CanDeriveEq, CanDerive}; use super::int::IntKind; -use super::item::{IsOpaque, Item, ItemAncestors, ItemCanonicalPath, ItemSet}; +use super::item::{IsOpaque, Item, ItemAncestors, ItemSet}; use super::item_kind::ItemKind; use super::module::{Module, ModuleKind}; use super::template::{TemplateInstantiation, TemplateParameters}; @@ -1107,7 +1107,7 @@ If you encounter an error missing from this list, please file an issue or a PR!" _ => continue, } - let path = item.canonical_path(self); + let path = item.path_for_whitelisting(self); let replacement = self.replacements.get(&path[1..]); if let Some(replacement) = replacement { @@ -2307,7 +2307,7 @@ If you encounter an error missing from this list, please file an issue or a PR!" return true; } - let name = item.canonical_path(self)[1..].join("::"); + let name = item.path_for_whitelisting(self)[1..].join("::"); debug!("whitelisted_items: testing {:?}", name); match *item.kind() { ItemKind::Module(..) => true, @@ -2324,7 +2324,7 @@ If you encounter an error missing from this list, please file an issue or a PR!" let parent = self.resolve_item(item.parent_id()); if parent.is_module() { - let mut prefix_path = parent.canonical_path(self); + let mut prefix_path = parent.path_for_whitelisting(self); // Unnamed top-level enums are special and we // whitelist them via the `whitelisted_vars` filter, @@ -2570,19 +2570,19 @@ If you encounter an error missing from this list, please file an issue or a PR!" /// 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("::"); + let name = item.path_for_whitelisting(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("::"); + let name = item.path_for_whitelisting(self)[1..].join("::"); self.options().no_copy_types.matches(&name) } /// Check 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("::"); + let name = item.path_for_whitelisting(self)[1..].join("::"); self.options().no_hash_types.matches(&name) } } diff --git a/src/ir/item.rs b/src/ir/item.rs index 380313e7..a54cbb82 100644 --- a/src/ir/item.rs +++ b/src/ir/item.rs @@ -635,7 +635,7 @@ impl Item { return true; } - let path = self.canonical_path(ctx); + let path = self.path_for_whitelisting(ctx); let name = path[1..].join("::"); ctx.options().blacklisted_items.matches(&name) || match self.kind { @@ -875,10 +875,13 @@ impl Item { let name = names.join("_"); - let name = ctx - .parse_callbacks() - .and_then(|callbacks| callbacks.item_name(&name)) - .unwrap_or(name); + let name = if opt.user_mangled == UserMangled::Yes { + ctx.parse_callbacks() + .and_then(|callbacks| callbacks.item_name(&name)) + .unwrap_or(name) + } else { + name + }; ctx.rust_mangle(&name).into_owned() } @@ -972,6 +975,44 @@ impl Item { } } } + + /// Returns the path we should use for whitelisting / blacklisting, which + /// doesn't include user-mangling. + pub fn path_for_whitelisting(&self, ctx: &BindgenContext) -> Vec<String> { + self.compute_path(ctx, UserMangled::No) + } + + fn compute_path(&self, ctx: &BindgenContext, mangled: UserMangled) -> Vec<String> { + if let Some(path) = self.annotations().use_instead_of() { + let mut ret = + vec![ctx.resolve_item(ctx.root_module()).name(ctx).get()]; + ret.extend_from_slice(path); + return ret; + } + + let target = ctx.resolve_item(self.name_target(ctx)); + let mut path: Vec<_> = target + .ancestors(ctx) + .chain(iter::once(ctx.root_module().into())) + .map(|id| ctx.resolve_item(id)) + .filter(|item| { + item.id() == target.id() || + item.as_module().map_or(false, |module| { + !module.is_inline() || + ctx.options().conservative_inline_namespaces + }) + }) + .map(|item| { + ctx.resolve_item(item.name_target(ctx)) + .name(ctx) + .within_namespaces() + .user_mangled(mangled) + .get() + }) + .collect(); + path.reverse(); + path + } } impl<T> IsOpaque for T @@ -999,7 +1040,7 @@ impl IsOpaque for Item { ); self.annotations.opaque() || self.as_type().map_or(false, |ty| ty.is_opaque(ctx, self)) || - ctx.opaque_by_name(&self.canonical_path(ctx)) + ctx.opaque_by_name(&self.path_for_whitelisting(ctx)) } } @@ -1821,37 +1862,21 @@ impl ItemCanonicalPath for Item { } fn canonical_path(&self, ctx: &BindgenContext) -> Vec<String> { - if let Some(path) = self.annotations().use_instead_of() { - let mut ret = - vec![ctx.resolve_item(ctx.root_module()).name(ctx).get()]; - ret.extend_from_slice(path); - return ret; - } - - let target = ctx.resolve_item(self.name_target(ctx)); - let mut path: Vec<_> = target - .ancestors(ctx) - .chain(iter::once(ctx.root_module().into())) - .map(|id| ctx.resolve_item(id)) - .filter(|item| { - item.id() == target.id() || - item.as_module().map_or(false, |module| { - !module.is_inline() || - ctx.options().conservative_inline_namespaces - }) - }) - .map(|item| { - ctx.resolve_item(item.name_target(ctx)) - .name(ctx) - .within_namespaces() - .get() - }) - .collect(); - path.reverse(); - path + self.compute_path(ctx, UserMangled::Yes) } } +/// Whether to use the user-mangled name (mangled by the `item_name` callback or +/// not. +/// +/// Most of the callers probably want just yes, but the ones dealing with +/// whitelisting and blacklisting don't. +#[derive(Copy, Clone, Debug, PartialEq)] +enum UserMangled { + No, + Yes, +} + /// Builder struct for naming variations, which hold inside different /// flags for naming options. #[derive(Debug)] @@ -1859,6 +1884,7 @@ pub struct NameOptions<'a> { item: &'a Item, ctx: &'a BindgenContext, within_namespaces: bool, + user_mangled: UserMangled, } impl<'a> NameOptions<'a> { @@ -1868,6 +1894,7 @@ impl<'a> NameOptions<'a> { item: item, ctx: ctx, within_namespaces: false, + user_mangled: UserMangled::Yes, } } @@ -1878,6 +1905,11 @@ impl<'a> NameOptions<'a> { self } + fn user_mangled(&mut self, user_mangled: UserMangled) -> &mut Self { + self.user_mangled = user_mangled; + self + } + /// Construct a name `String` pub fn get(&self) -> String { self.item.real_canonical_name(self.ctx, self) |