diff options
Diffstat (limited to 'libbindgen/src')
-rw-r--r-- | libbindgen/src/ir/context.rs | 13 | ||||
-rw-r--r-- | libbindgen/src/ir/item.rs | 93 |
2 files changed, 83 insertions, 23 deletions
diff --git a/libbindgen/src/ir/context.rs b/libbindgen/src/ir/context.rs index a0e57610..ebc7f10a 100644 --- a/libbindgen/src/ir/context.rs +++ b/libbindgen/src/ir/context.rs @@ -368,7 +368,16 @@ impl<'ctx> BindgenContext<'ctx> { } let in_namespace = self.options().enable_cxx_namespaces; - let name = item.real_canonical_name(self, in_namespace, true); + + let name = if in_namespace { + item.name(self) + .within_namespaces() + .get() + } else { + item.name(self) + .for_name_checking() + .get() + }; let replacement = self.replacements.get(&name); if let Some(replacement) = replacement { @@ -938,7 +947,7 @@ impl<'ctx> BindgenContext<'ctx> { return true; } - let name = item.real_canonical_name(self, false, true); + let name = item.name(self).for_name_checking().get(); match *item.kind() { ItemKind::Module(..) => true, ItemKind::Function(_) => { diff --git a/libbindgen/src/ir/item.rs b/libbindgen/src/ir/item.rs index 1d643a45..c0555bca 100644 --- a/libbindgen/src/ir/item.rs +++ b/libbindgen/src/ir/item.rs @@ -516,7 +516,7 @@ impl Item { debug_assert!(ctx.in_codegen_phase(), "You're not supposed to call this yet"); self.annotations.hide() || - ctx.hidden_by_name(&self.real_canonical_name(ctx, false, true), self.id) + ctx.hidden_by_name(&self.name(ctx).for_name_checking().get(), self.id) } /// Is this item opaque? @@ -524,7 +524,7 @@ impl Item { debug_assert!(ctx.in_codegen_phase(), "You're not supposed to call this yet"); self.annotations.opaque() || - ctx.opaque_by_name(&self.real_canonical_name(ctx, false, true)) + ctx.opaque_by_name(&self.name(ctx).for_name_checking().get()) } /// Is this a reference to another type? @@ -540,6 +540,13 @@ impl Item { } } + /// Take out item NameOptions + pub fn name<'item, 'ctx>(&'item self, + ctx: &'item BindgenContext<'ctx>) + -> NameOptions<'item, 'ctx> { + NameOptions::new(self, ctx) + } + /// Get the target item id for name generation. fn name_target(&self, ctx: &BindgenContext, @@ -628,9 +635,7 @@ impl Item { } ItemKind::Type(ref ty) => { let name = match *ty.kind() { - TypeKind::ResolvedTypeRef(..) => { - panic!("should have resolved this in name_target()") - } + TypeKind::ResolvedTypeRef(..) => panic!("should have resolved this in name_target()"), TypeKind::TemplateAlias(..) => { if for_name_checking { None } else { Some("") } } @@ -668,19 +673,19 @@ impl Item { /// type and the parent chain, since it should be consistent. pub fn real_canonical_name(&self, ctx: &BindgenContext, - within_namespace: bool, - for_name_checking: bool) + opt: &NameOptions) -> String { - let target = ctx.resolve_item(self.name_target(ctx, for_name_checking)); + let target = + ctx.resolve_item(self.name_target(ctx, opt.for_name_checking)); // Short-circuit if the target has an override, and just use that. - if !for_name_checking { + if !opt.for_name_checking { if let Some(other) = target.annotations.use_instead_of() { return other.to_owned(); } } - let base_name = target.base_name(ctx, for_name_checking); + let base_name = target.base_name(ctx, opt.for_name_checking); // Named template type arguments are never namespaced, and never // mangled. @@ -694,7 +699,7 @@ impl Item { .filter(|id| *id != ctx.root_module()) .take_while(|id| { // Stop iterating ancestors once we reach a namespace. - !within_namespace || !ctx.resolve_item(*id).is_module() + !opt.within_namespaces || !ctx.resolve_item(*id).is_module() }) .map(|id| { let item = ctx.resolve_item(id); @@ -940,9 +945,8 @@ impl ClangItemParser for Item { .expect("Unable to resolve type"); } - if let Some(ty) = ctx.builtin_or_resolved_ty(potential_id, - parent_id, &ty, - location) { + if let Some(ty) = + ctx.builtin_or_resolved_ty(potential_id, parent_id, &ty, location) { debug!("{:?} already resolved: {:?}", ty, location); return ty; } @@ -1008,7 +1012,7 @@ impl ClangItemParser for Item { } if let Some(ty) = - ctx.builtin_or_resolved_ty(id, parent_id, ty, location) { + ctx.builtin_or_resolved_ty(id, parent_id, ty, location) { return Ok(ty); } @@ -1026,9 +1030,10 @@ impl ClangItemParser for Item { }; if valid_decl { - if let Some(&(_, item_id)) = ctx.currently_parsed_types - .iter() - .find(|&&(d, _)| d == declaration_to_look_for) { + if let Some(&(_, item_id)) = + ctx.currently_parsed_types + .iter() + .find(|&&(d, _)| d == declaration_to_look_for) { debug!("Avoiding recursion parsing type: {:?}", ty); return Ok(item_id); } @@ -1160,8 +1165,11 @@ impl ItemCanonicalName for Item { let in_namespace = ctx.options().enable_cxx_namespaces || ctx.options().disable_name_namespacing; - *self.canonical_name_cache.borrow_mut() = - Some(self.real_canonical_name(ctx, in_namespace, false)); + *self.canonical_name_cache.borrow_mut() = if in_namespace { + Some(self.name(ctx).within_namespaces().get()) + } else { + Some(self.name(ctx).get()) + }; } return self.canonical_name_cache.borrow().as_ref().unwrap().clone(); } @@ -1214,8 +1222,51 @@ impl ItemCanonicalPath for Item { debug_assert!(is_alias, "How can this ever happen?"); parent_path.pop().unwrap(); } - parent_path.push(self.real_canonical_name(ctx, true, false)); + parent_path.push(self.name(ctx).within_namespaces().get()); parent_path } } + +/// Builder struct for naming variations, which hold inside different +/// flags for naming options. +#[derive(Debug)] +pub struct NameOptions<'item, 'ctx> + where 'ctx: 'item, +{ + item: &'item Item, + ctx: &'item BindgenContext<'ctx>, + for_name_checking: bool, + within_namespaces: bool, +} + +impl<'item, 'ctx> NameOptions<'item, 'ctx> { + /// Construct a new `NameOptions` + pub fn new(item: &'item Item, ctx: &'item BindgenContext<'ctx>) -> Self { + NameOptions { + item: item, + ctx: ctx, + for_name_checking: false, + within_namespaces: false, + } + } + + /// Construct a name that is suitable for replacements/whitelisting/opaque- + /// ness look ups. + pub fn for_name_checking(&mut self) -> &mut Self { + self.for_name_checking = true; + self + } + + /// Construct the name without the item's containing C++ namespaces mangled + /// into it. In other words, the item's name within the item's namespace. + pub fn within_namespaces(&mut self) -> &mut Self { + self.within_namespaces = true; + self + } + + /// Construct a name `String` + pub fn get(&self) -> String { + self.item.real_canonical_name(self.ctx, self) + } +} |