summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/codegen/mod.rs3
-rw-r--r--src/ir/comp.rs4
-rw-r--r--src/ir/context.rs69
-rw-r--r--src/ir/function.rs4
-rw-r--r--src/ir/item.rs6
-rw-r--r--src/ir/mod.rs1
-rw-r--r--src/ir/traversal.rs78
-rw-r--r--src/ir/ty.rs4
-rw-r--r--src/ir/type_collector.rs7
9 files changed, 98 insertions, 78 deletions
diff --git a/src/codegen/mod.rs b/src/codegen/mod.rs
index 99400f7a..6f9291f7 100644
--- a/src/codegen/mod.rs
+++ b/src/codegen/mod.rs
@@ -12,13 +12,12 @@ use ir::derive::{CanDeriveCopy, CanDeriveDebug, CanDeriveDefault};
use ir::enum_ty::{Enum, EnumVariant, EnumVariantValue};
use ir::function::{Function, FunctionSig};
use ir::int::IntKind;
-use ir::item::{Item, ItemAncestors, ItemCanonicalName, ItemCanonicalPath};
+use ir::item::{Item, ItemSet, ItemAncestors, ItemCanonicalName, ItemCanonicalPath};
use ir::item_kind::ItemKind;
use ir::layout::Layout;
use ir::module::Module;
use ir::objc::ObjCInterface;
use ir::ty::{Type, TypeKind};
-use ir::type_collector::ItemSet;
use ir::var::Var;
use std::borrow::Cow;
diff --git a/src/ir/comp.rs b/src/ir/comp.rs
index 7c58e233..2ca25479 100644
--- a/src/ir/comp.rs
+++ b/src/ir/comp.rs
@@ -3,10 +3,10 @@
use super::annotations::Annotations;
use super::context::{BindgenContext, ItemId};
use super::derive::{CanDeriveCopy, CanDeriveDebug, CanDeriveDefault};
-use super::item::Item;
+use super::item::{Item, ItemSet};
use super::layout::Layout;
use super::ty::{TemplateDeclaration, Type};
-use super::type_collector::{ItemSet, TypeCollector};
+use super::type_collector::TypeCollector;
use clang;
use parse::{ClangItemParser, ParseError};
use std::cell::Cell;
diff --git a/src/ir/context.rs b/src/ir/context.rs
index 91ce579c..e251f0c3 100644
--- a/src/ir/context.rs
+++ b/src/ir/context.rs
@@ -2,11 +2,12 @@
use super::derive::{CanDeriveCopy, CanDeriveDebug, CanDeriveDefault};
use super::int::IntKind;
-use super::item::{Item, ItemCanonicalPath};
+use super::item::{Item, ItemSet, ItemCanonicalPath};
use super::item_kind::ItemKind;
use super::module::{Module, ModuleKind};
+use super::traversal::ItemTraversal;
use super::ty::{FloatKind, TemplateDeclaration, Type, TypeKind};
-use super::type_collector::{ItemSet, TypeCollector};
+use super::type_collector::TypeCollector;
use BindgenOptions;
use cexpr;
use chooser::TypeChooser;
@@ -1203,7 +1204,7 @@ impl<'ctx> BindgenContext<'ctx> {
/// If no items are explicitly whitelisted, then all items are considered
/// whitelisted.
pub fn whitelisted_items<'me>(&'me self)
- -> WhitelistedItemsIter<'me, 'ctx> {
+ -> ItemTraversal<'me, 'ctx> {
assert!(self.in_codegen_phase());
assert!(self.current_module == self.root_module);
@@ -1268,18 +1269,7 @@ impl<'ctx> BindgenContext<'ctx> {
})
.map(|(&id, _)| id);
- let seen: ItemSet = roots.collect();
-
- // The .rev() preserves the expected ordering traversal, resulting in
- // more stable-ish bindgen-generated names for anonymous types (like
- // unions).
- let to_iterate = seen.iter().cloned().rev().collect();
-
- WhitelistedItemsIter {
- ctx: self,
- seen: seen,
- to_iterate: to_iterate,
- }
+ ItemTraversal::new(self, roots)
}
/// Convenient method for getting the prefix to use for most traits in
@@ -1365,55 +1355,6 @@ impl TemplateDeclaration for PartialType {
}
}
-/// An iterator over whitelisted items.
-///
-/// See `BindgenContext::whitelisted_items` for more information.
-pub struct WhitelistedItemsIter<'ctx, 'gen>
- where 'gen: 'ctx,
-{
- ctx: &'ctx BindgenContext<'gen>,
-
- /// The set of whitelisted items we have seen. If you think of traversing
- /// whitelisted items like GC tracing, this is the mark bits, and contains
- /// both black and gray items.
- seen: ItemSet,
-
- /// The set of whitelisted items that we have seen but have yet to iterate
- /// over and collect transitive references from. To return to the GC analogy,
- /// this is the mark stack, containing the set of gray items which we have
- /// not finished tracing yet.
- to_iterate: Vec<ItemId>,
-}
-
-impl<'ctx, 'gen> Iterator for WhitelistedItemsIter<'ctx, 'gen>
- where 'gen: 'ctx,
-{
- type Item = ItemId;
-
- fn next(&mut self) -> Option<Self::Item> {
- let id = match self.to_iterate.pop() {
- None => return None,
- Some(id) => id,
- };
-
- debug_assert!(self.seen.contains(&id));
- debug_assert!(self.ctx.items.contains_key(&id));
-
- if self.ctx.options().whitelist_recursively {
- let mut sub_types = ItemSet::new();
- id.collect_types(self.ctx, &mut sub_types, &());
-
- for id in sub_types {
- if self.seen.insert(id) {
- self.to_iterate.push(id);
- }
- }
- }
-
- Some(id)
- }
-}
-
/// An iterator to find any dangling items.
///
/// See `BindgenContext::assert_no_dangling_item_traversal` for more
diff --git a/src/ir/function.rs b/src/ir/function.rs
index 6273de28..be8c49d5 100644
--- a/src/ir/function.rs
+++ b/src/ir/function.rs
@@ -1,9 +1,9 @@
//! Intermediate representation for C/C++ functions and methods.
use super::context::{BindgenContext, ItemId};
-use super::item::Item;
+use super::item::{Item, ItemSet};
use super::ty::TypeKind;
-use super::type_collector::{ItemSet, TypeCollector};
+use super::type_collector::TypeCollector;
use clang;
use clang_sys::CXCallingConv;
use parse::{ClangItemParser, ClangSubItemParser, ParseError, ParseResult};
diff --git a/src/ir/item.rs b/src/ir/item.rs
index 83e2a41f..2717c792 100644
--- a/src/ir/item.rs
+++ b/src/ir/item.rs
@@ -7,11 +7,12 @@ use super::function::Function;
use super::item_kind::ItemKind;
use super::module::Module;
use super::ty::{TemplateDeclaration, Type, TypeKind};
-use super::type_collector::{ItemSet, TypeCollector};
+use super::type_collector::TypeCollector;
use clang;
use clang_sys;
use parse::{ClangItemParser, ClangSubItemParser, ParseError, ParseResult};
use std::cell::{Cell, RefCell};
+use std::collections::BTreeSet;
use std::fmt::Write;
use std::iter;
@@ -902,6 +903,9 @@ impl Item {
}
}
+/// A set of items.
+pub type ItemSet = BTreeSet<ItemId>;
+
impl TemplateDeclaration for ItemId {
fn template_params(&self, ctx: &BindgenContext) -> Option<Vec<ItemId>> {
ctx.resolve_item_fallible(*self)
diff --git a/src/ir/mod.rs b/src/ir/mod.rs
index d424fcdf..9e53c184 100644
--- a/src/ir/mod.rs
+++ b/src/ir/mod.rs
@@ -14,6 +14,7 @@ pub mod item;
pub mod item_kind;
pub mod layout;
pub mod module;
+pub mod traversal;
pub mod ty;
pub mod type_collector;
pub mod var;
diff --git a/src/ir/traversal.rs b/src/ir/traversal.rs
new file mode 100644
index 00000000..d8e9a6e2
--- /dev/null
+++ b/src/ir/traversal.rs
@@ -0,0 +1,78 @@
+//! Traversal of the graph of IR items and types.
+
+use super::context::{BindgenContext, ItemId};
+use super::item::ItemSet;
+use super::type_collector::TypeCollector;
+
+/// An graph traversal of the transitive closure of references between items.
+///
+/// See `BindgenContext::whitelisted_items` for more information.
+pub struct ItemTraversal<'ctx, 'gen>
+ where 'gen: 'ctx,
+{
+ ctx: &'ctx BindgenContext<'gen>,
+
+ /// The set of whitelisted items we have seen. If you think of traversing
+ /// whitelisted items like GC tracing, this is the mark bits, and contains
+ /// both black and gray items.
+ seen: ItemSet,
+
+ /// The set of whitelisted items that we have seen but have yet to iterate
+ /// over and collect transitive references from. To return to the GC analogy,
+ /// this is the mark stack, containing the set of gray items which we have
+ /// not finished tracing yet.
+ to_iterate: Vec<ItemId>,
+}
+
+impl<'ctx, 'gen> ItemTraversal<'ctx, 'gen>
+ where 'gen: 'ctx,
+{
+ /// Begin a new traversal, starting from the given roots.
+ pub fn new<R>(ctx: &'ctx BindgenContext<'gen>,
+ roots: R)
+ -> ItemTraversal<'ctx, 'gen>
+ where R: IntoIterator<Item = ItemId>,
+ {
+ // Construct the ItemSet first. Because its underlying storage is a
+ // BTreeSet, its iteration over its entries is ordered, and the roots
+ // end up ordered as well. This contributes enables stable,
+ // deterministic generated names in the bindings.
+ let seen: ItemSet = roots.into_iter().collect();
+ let roots: Vec<_> = seen.iter().cloned().collect();
+
+ ItemTraversal {
+ ctx: ctx,
+ seen: seen,
+ to_iterate: roots,
+ }
+ }
+}
+
+impl<'ctx, 'gen> Iterator for ItemTraversal<'ctx, 'gen>
+ where 'gen: 'ctx,
+{
+ type Item = ItemId;
+
+ fn next(&mut self) -> Option<Self::Item> {
+ let id = match self.to_iterate.pop() {
+ None => return None,
+ Some(id) => id,
+ };
+
+ debug_assert!(self.seen.contains(&id));
+ debug_assert!(self.ctx.resolve_item_fallible(id).is_some());
+
+ if self.ctx.options().whitelist_recursively {
+ let mut sub_types = ItemSet::new();
+ id.collect_types(self.ctx, &mut sub_types, &());
+
+ for id in sub_types {
+ if self.seen.insert(id) {
+ self.to_iterate.push(id);
+ }
+ }
+ }
+
+ Some(id)
+ }
+}
diff --git a/src/ir/ty.rs b/src/ir/ty.rs
index a47c1470..b51054b7 100644
--- a/src/ir/ty.rs
+++ b/src/ir/ty.rs
@@ -6,10 +6,10 @@ use super::derive::{CanDeriveCopy, CanDeriveDebug, CanDeriveDefault};
use super::enum_ty::Enum;
use super::function::FunctionSig;
use super::int::IntKind;
-use super::item::Item;
+use super::item::{Item, ItemSet};
use super::layout::Layout;
use super::objc::ObjCInterface;
-use super::type_collector::{ItemSet, TypeCollector};
+use super::type_collector::TypeCollector;
use clang::{self, Cursor};
use parse::{ClangItemParser, ParseError, ParseResult};
use std::mem;
diff --git a/src/ir/type_collector.rs b/src/ir/type_collector.rs
index 25285b23..424007a1 100644
--- a/src/ir/type_collector.rs
+++ b/src/ir/type_collector.rs
@@ -1,10 +1,7 @@
//! Collecting type items.
-use super::context::{BindgenContext, ItemId};
-use std::collections::BTreeSet;
-
-/// A set of items.
-pub type ItemSet = BTreeSet<ItemId>;
+use super::context::BindgenContext;
+use super::item::ItemSet;
/// Collect all the type items referenced by this item.
pub trait TypeCollector {