diff options
Diffstat (limited to 'libbindgen/src')
-rw-r--r-- | libbindgen/src/codegen/mod.rs | 77 | ||||
-rw-r--r-- | libbindgen/src/ir/context.rs | 35 | ||||
-rw-r--r-- | libbindgen/src/ir/item.rs | 19 |
3 files changed, 57 insertions, 74 deletions
diff --git a/libbindgen/src/codegen/mod.rs b/libbindgen/src/codegen/mod.rs index a3fefcc7..0469a5be 100644 --- a/libbindgen/src/codegen/mod.rs +++ b/libbindgen/src/codegen/mod.rs @@ -242,11 +242,6 @@ impl CodeGenerator for Item { match *self.kind() { ItemKind::Module(ref module) => { - if !ctx.options().enable_cxx_namespaces && - self.id() == ctx.root_module() { - return; - } - module.codegen(ctx, result, whitelisted_items, self); } ItemKind::Function(ref fun) => { @@ -274,22 +269,28 @@ impl CodeGenerator for Module { item: &Item) { debug!("<Module as CodeGenerator>::codegen: item = {:?}", item); - if !ctx.options().enable_cxx_namespaces { - for child in self.children() { - ctx.resolve_item(*child) - .codegen(ctx, result, whitelisted_items, &()); + let codegen_self = |result: &mut CodegenResult| { + // FIXME: This could be less expensive, I guess. + for &whitelisted_item in whitelisted_items { + if whitelisted_item == item.id() { + continue; + } + + let child = ctx.resolve_item(whitelisted_item); + if child.parent_id() == item.id() { + child.codegen(ctx, result, whitelisted_items, &()); + } } + }; + + if !ctx.options().enable_cxx_namespaces { + codegen_self(result); return; } let inner_items = result.inner(|result| { result.push(root_import(ctx)); - for child in self.children() { - if whitelisted_items.contains(child) { - ctx.resolve_item(*child) - .codegen(ctx, result, whitelisted_items, &()); - } - } + codegen_self(result); }); let module = ast::ItemKind::Mod(ast::Mod { @@ -428,13 +429,12 @@ impl CodeGenerator for Type { TypeKind::Comp(ref ci) => { ci.codegen(ctx, result, whitelisted_items, item) } + // NB: The inner Alias will be generated and pick the correct + // applicable_template_args. TypeKind::TemplateAlias(inner, _) => { - // NB: The inner Alias will pick the correct - // applicable_template_args. - let inner_item = ctx.resolve_item(inner); - inner_item.expect_type() - .codegen(ctx, result, whitelisted_items, inner_item); - } + ctx.resolve_item(inner) + .codegen(ctx, result, whitelisted_items, &()) + }, TypeKind::Alias(ref spelling, inner) => { let inner_item = ctx.resolve_item(inner); let name = item.canonical_name(ctx); @@ -1964,27 +1964,6 @@ impl CodeGenerator for Function { } } -// Return true if any of the ancestors of `id` are in the whitelisted items set, -// false otherwise. -fn ancestor_is_whitelisted(ctx: &BindgenContext, - whitelisted_items: &ItemSet, - id: ItemId) - -> bool { - let item = ctx.resolve_item(id); - let mut last = id; - let mut current = item.parent_id(); - - while last != current { - if whitelisted_items.contains(¤t) { - return true; - } - last = current; - current = ctx.resolve_item(current).parent_id(); - } - - false -} - pub fn codegen(context: &mut BindgenContext) -> Vec<P<ast::Item>> { context.gen(|context| { let mut result = CodegenResult::new(); @@ -2000,18 +1979,8 @@ pub fn codegen(context: &mut BindgenContext) -> Vec<P<ast::Item>> { } } - for &id in whitelisted_items.iter() { - let item = context.resolve_item(id); - - // Non-toplevel items' parents are responsible one for generating - // their children. However, if we find an orphaned reference to a - // non-toplevel item whose parent is not in our whitelisted set, we - // need to take responsibility for generating it. - if item.is_toplevel(context) || - !ancestor_is_whitelisted(context, &whitelisted_items, id) { - item.codegen(context, &mut result, &whitelisted_items, &()); - } - } + context.resolve_item(context.root_module()) + .codegen(context, &mut result, &whitelisted_items, &()); let saw_union = result.saw_union; let mut result = result.items; diff --git a/libbindgen/src/ir/context.rs b/libbindgen/src/ir/context.rs index 76e27841..e599160e 100644 --- a/libbindgen/src/ir/context.rs +++ b/libbindgen/src/ir/context.rs @@ -10,7 +10,7 @@ use std::collections::{HashMap, hash_map}; use std::collections::btree_map::{self, BTreeMap}; use std::fmt; use super::int::IntKind; -use super::item::{Item, ItemCanonicalName}; +use super::item::Item; use super::item_kind::ItemKind; use super::module::Module; use super::ty::{FloatKind, Type, TypeKind}; @@ -938,11 +938,9 @@ impl<'ctx> BindgenContext<'ctx> { return true; } - let name = item.canonical_name(self); + let name = item.real_canonical_name(self, false, true); match *item.kind() { - ItemKind::Module(..) => { - self.options().enable_cxx_namespaces - } + ItemKind::Module(..) => true, ItemKind::Function(_) => { self.options().whitelisted_functions.matches(&name) } @@ -954,18 +952,21 @@ impl<'ctx> BindgenContext<'ctx> { return true; } - // Unnamed top-level enums are special and we whitelist - // them via the `whitelisted_vars` filter, since they're - // effectively top-level constants, and there's no way - // for them to be referenced consistently. - if let TypeKind::Enum(ref enum_) = *ty.kind() { - if ty.name().is_none() && - enum_.variants().iter().any(|variant| { - self.options() - .whitelisted_vars - .matches(&variant.name()) - }) { - return true; + if self.resolve_item(item.parent_id()).is_module() { + // Unnamed top-level enums are special and we + // whitelist them via the `whitelisted_vars` filter, + // since they're effectively top-level constants, + // and there's no way for them to be referenced + // consistently. + if let TypeKind::Enum(ref enum_) = *ty.kind() { + if ty.name().is_none() && + enum_.variants().iter().any(|variant| { + self.options() + .whitelisted_vars + .matches(&variant.name()) + }) { + return true; + } } } diff --git a/libbindgen/src/ir/item.rs b/libbindgen/src/ir/item.rs index b857acf9..1f15ff0f 100644 --- a/libbindgen/src/ir/item.rs +++ b/libbindgen/src/ir/item.rs @@ -532,6 +532,14 @@ impl Item { self.as_type().map_or(false, |ty| ty.is_type_ref()) } + /// Is this item a var type? + pub fn is_var(&self) -> bool { + match *self.kind() { + ItemKind::Var(..) => true, + _ => false, + } + } + /// Get the target item id for name generation. fn name_target(&self, ctx: &BindgenContext, @@ -664,6 +672,14 @@ impl Item { for_name_checking: bool) -> String { let target = ctx.resolve_item(self.name_target(ctx, for_name_checking)); + + // Short-circuit if the target has an override, and just use that. + if !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); // Named template type arguments are never namespaced, and never @@ -1135,9 +1151,6 @@ impl ItemCanonicalName for Item { fn canonical_name(&self, ctx: &BindgenContext) -> String { debug_assert!(ctx.in_codegen_phase(), "You're not supposed to call this yet"); - if let Some(other_canon_type) = self.annotations.use_instead_of() { - return other_canon_type.to_owned(); - } if self.canonical_name_cache.borrow().is_none() { *self.canonical_name_cache.borrow_mut() = Some(self.real_canonical_name(ctx, |