summaryrefslogtreecommitdiff
path: root/libbindgen/src
diff options
context:
space:
mode:
Diffstat (limited to 'libbindgen/src')
-rw-r--r--libbindgen/src/codegen/mod.rs77
-rw-r--r--libbindgen/src/ir/context.rs35
-rw-r--r--libbindgen/src/ir/item.rs19
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(&current) {
- 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,