diff options
-rw-r--r-- | src/ir/context.rs | 14 | ||||
-rw-r--r-- | src/ir/item.rs | 100 |
2 files changed, 73 insertions, 41 deletions
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) |