summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rwxr-xr-xsrc/codegen/mod.rs129
-rw-r--r--src/ir/comp.rs33
-rw-r--r--src/ir/context.rs2
-rw-r--r--src/ir/function.rs18
-rw-r--r--src/ir/item.rs39
-rw-r--r--src/ir/mod.rs1
-rw-r--r--src/ir/ty.rs36
-rw-r--r--src/ir/type_collector.rs23
8 files changed, 149 insertions, 132 deletions
diff --git a/src/codegen/mod.rs b/src/codegen/mod.rs
index 65900739..a656c2c1 100755
--- a/src/codegen/mod.rs
+++ b/src/codegen/mod.rs
@@ -14,11 +14,11 @@ use ir::item_kind::ItemKind;
use ir::comp::{CompKind, CompInfo, Field, Method};
use ir::layout::Layout;
use ir::annotations::FieldAccessorKind;
+use ir::type_collector::{ItemSet, TypeCollector};
use std::ops;
use std::borrow::Cow;
use std::mem;
-use std::collections::BTreeSet;
use std::collections::HashSet;
use std::collections::hash_map::{HashMap, Entry};
@@ -1584,133 +1584,6 @@ impl CodeGenerator for Function {
}
}
-type ItemSet = BTreeSet<ItemId>;
-
-trait TypeCollector {
- type Extra;
-
- fn collect_types(&self,
- context: &BindgenContext,
- types: &mut ItemSet,
- extra: &Self::Extra);
-}
-
-impl TypeCollector for ItemId {
- type Extra = ();
-
- fn collect_types(&self,
- context: &BindgenContext,
- types: &mut ItemSet,
- extra: &()) {
- context.resolve_item(*self).collect_types(context, types, extra);
- }
-}
-
-impl TypeCollector for Item {
- type Extra = ();
-
- fn collect_types(&self,
- context: &BindgenContext,
- types: &mut ItemSet,
- _extra: &()) {
- if self.is_hidden(context) || types.contains(&self.id()) {
- return;
- }
-
- match *self.kind() {
- ItemKind::Type(ref ty) => {
- types.insert(self.id());
- if !self.is_opaque(context) {
- ty.collect_types(context, types, self);
- }
- }
- _ => {}, // FIXME.
- }
- }
-}
-
-impl TypeCollector for Type {
- type Extra = Item;
-
- fn collect_types(&self,
- context: &BindgenContext,
- types: &mut ItemSet,
- item: &Item) {
- match *self.kind() {
- TypeKind::Pointer(inner) |
- TypeKind::Reference(inner) |
- TypeKind::Array(inner, _) |
- TypeKind::TemplateAlias(inner, _) |
- TypeKind::Alias(_, inner) |
- TypeKind::Named(_, Some(inner)) |
- TypeKind::ResolvedTypeRef(inner)
- => inner.collect_types(context, types, &()),
-
- TypeKind::TemplateRef(inner, ref template_args) => {
- inner.collect_types(context, types, &());
- for item in template_args {
- item.collect_types(context, types, &());
- }
- }
- TypeKind::Comp(ref ci) => ci.collect_types(context, types, item),
- TypeKind::Function(ref sig) => {
- sig.collect_types(context, types, item)
- }
- // FIXME: Pending types!
- ref other @ _ => {
- debug!("Ignoring: {:?}", other);
- },
- }
- }
-}
-
-impl TypeCollector for FunctionSig {
- type Extra = Item;
-
- fn collect_types(&self,
- context: &BindgenContext,
- types: &mut ItemSet,
- _item: &Item) {
- self.return_type().collect_types(context, types, &());
-
- for &(_, ty) in self.argument_types() {
- ty.collect_types(context, types, &());
- }
- }
-}
-
-impl TypeCollector for CompInfo {
- type Extra = Item;
-
- fn collect_types(&self,
- context: &BindgenContext,
- types: &mut ItemSet,
- item: &Item) {
- if let Some(template) = self.specialized_template() {
- template.collect_types(context, types, &());
- }
-
- let applicable_template_args = item.applicable_template_args(context);
- for arg in applicable_template_args {
- arg.collect_types(context, types, &());
- }
-
- for base in self.base_members() {
- base.collect_types(context, types, &());
- }
-
- for field in self.fields() {
- field.ty().collect_types(context, types, &());
- }
-
- for ty in self.inner_types() {
- ty.collect_types(context, types, &());
- }
-
- // FIXME(emilio): Methods, VTable?
- }
-}
-
pub fn codegen(context: &mut BindgenContext) -> Vec<P<ast::Item>> {
context.gen(|context| {
let mut result = CodegenResult::new();
diff --git a/src/ir/comp.rs b/src/ir/comp.rs
index b9e9ec8b..13eaa6db 100644
--- a/src/ir/comp.rs
+++ b/src/ir/comp.rs
@@ -5,6 +5,7 @@ use super::context::BindgenContext;
use super::layout::Layout;
use super::item::{Item, ItemId};
use super::ty::{Type, RUST_DERIVE_IN_ARRAY_LIMIT};
+use super::type_collector::{ItemSet, TypeCollector};
use std::cell::Cell;
use std::cmp;
use parse::{ClangItemParser, ParseError};
@@ -804,3 +805,35 @@ impl CompInfo {
})
}
}
+
+impl TypeCollector for CompInfo {
+ type Extra = Item;
+
+ fn collect_types(&self,
+ context: &BindgenContext,
+ types: &mut ItemSet,
+ item: &Item) {
+ if let Some(template) = self.specialized_template() {
+ template.collect_types(context, types, &());
+ }
+
+ let applicable_template_args = item.applicable_template_args(context);
+ for arg in applicable_template_args {
+ arg.collect_types(context, types, &());
+ }
+
+ for base in self.base_members() {
+ base.collect_types(context, types, &());
+ }
+
+ for field in self.fields() {
+ field.ty().collect_types(context, types, &());
+ }
+
+ for ty in self.inner_types() {
+ ty.collect_types(context, types, &());
+ }
+
+ // FIXME(emilio): Methods, VTable?
+ }
+}
diff --git a/src/ir/context.rs b/src/ir/context.rs
index 65c62817..729a1c02 100644
--- a/src/ir/context.rs
+++ b/src/ir/context.rs
@@ -32,7 +32,7 @@ enum TypeKey {
// context.
struct GenContext<'ctx>(ExtCtxt<'ctx>);
-impl<'ctx> fmt::Debug for GenContext <'ctx> {
+impl<'ctx> fmt::Debug for GenContext<'ctx> {
fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
write!(fmt, "GenContext {{ ... }}")
}
diff --git a/src/ir/function.rs b/src/ir/function.rs
index 0cf23f43..fc2a7110 100644
--- a/src/ir/function.rs
+++ b/src/ir/function.rs
@@ -1,8 +1,9 @@
//! Intermediate representation for C/C++ functions and methods.
+use super::context::BindgenContext;
use super::item::{Item, ItemId};
use super::ty::TypeKind;
-use super::context::BindgenContext;
+use super::type_collector::{ItemSet, TypeCollector};
use syntax::abi;
use clang;
use clangll::Enum_CXCallingConv;
@@ -246,3 +247,18 @@ impl ClangSubItemParser for Function {
Ok(ParseResult::New(function, Some(cursor)))
}
}
+
+impl TypeCollector for FunctionSig {
+ type Extra = Item;
+
+ fn collect_types(&self,
+ context: &BindgenContext,
+ types: &mut ItemSet,
+ _item: &Item) {
+ self.return_type().collect_types(context, types, &());
+
+ for &(_, ty) in self.argument_types() {
+ ty.collect_types(context, types, &());
+ }
+ }
+}
diff --git a/src/ir/item.rs b/src/ir/item.rs
index 0d409f04..b262b825 100644
--- a/src/ir/item.rs
+++ b/src/ir/item.rs
@@ -4,6 +4,7 @@ use regex::Regex;
use super::context::BindgenContext;
use super::item_kind::ItemKind;
use super::ty::{Type, TypeKind};
+use super::type_collector::{ItemSet, TypeCollector};
use super::function::Function;
use super::module::Module;
use super::annotations::Annotations;
@@ -76,6 +77,40 @@ impl ItemCanonicalPath for ItemId {
}
}
+impl TypeCollector for ItemId {
+ type Extra = ();
+
+ fn collect_types(&self,
+ context: &BindgenContext,
+ types: &mut ItemSet,
+ extra: &()) {
+ context.resolve_item(*self).collect_types(context, types, extra);
+ }
+}
+
+impl TypeCollector for Item {
+ type Extra = ();
+
+ fn collect_types(&self,
+ context: &BindgenContext,
+ types: &mut ItemSet,
+ _extra: &()) {
+ if self.is_hidden(context) || types.contains(&self.id()) {
+ return;
+ }
+
+ match *self.kind() {
+ ItemKind::Type(ref ty) => {
+ types.insert(self.id());
+ if !self.is_opaque(context) {
+ ty.collect_types(context, types, self);
+ }
+ }
+ _ => {}, // FIXME.
+ }
+ }
+}
+
/// An item is the base of the bindgen representation, it can be either a
/// module, a type, a function, or a variable (see `ItemKind` for more
/// information).
@@ -566,12 +601,12 @@ impl Item {
static ref RE_ENDS_WITH_BINDGEN_TY: Regex = Regex::new(r"_bindgen_ty(_\d+)+$").unwrap();
static ref RE_ENDS_WITH_BINDGEN_MOD: Regex = Regex::new(r"_bindgen_mod(_\d+)+$").unwrap();
}
-
+
let (re, kind) = match *self.kind() {
ItemKind::Module(..) => (&*RE_ENDS_WITH_BINDGEN_MOD, "mod"),
_ => (&*RE_ENDS_WITH_BINDGEN_TY, "ty"),
};
-
+
let parent_name = parent_name.and_then(|n| if n.is_empty() { None } else { Some(n) });
match (parent_name, base_name) {
(Some(parent), Some(base)) => format!("{}_{}", parent, base),
diff --git a/src/ir/mod.rs b/src/ir/mod.rs
index 01f388b8..3c658a4a 100644
--- a/src/ir/mod.rs
+++ b/src/ir/mod.rs
@@ -14,4 +14,5 @@ pub mod item_kind;
pub mod layout;
pub mod module;
pub mod ty;
+pub mod type_collector;
pub mod var;
diff --git a/src/ir/ty.rs b/src/ir/ty.rs
index b9816f6e..b2f20dde 100644
--- a/src/ir/ty.rs
+++ b/src/ir/ty.rs
@@ -7,6 +7,7 @@ use super::item::{Item, ItemId};
use super::int::IntKind;
use super::layout::Layout;
use super::context::BindgenContext;
+use super::type_collector::{ItemSet, TypeCollector};
use parse::{ClangItemParser, ParseResult, ParseError};
use clang::{self, Cursor};
@@ -709,3 +710,38 @@ impl Type {
Ok(ParseResult::New(ty, Some(cursor.canonical())))
}
}
+
+impl TypeCollector for Type {
+ type Extra = Item;
+
+ fn collect_types(&self,
+ context: &BindgenContext,
+ types: &mut ItemSet,
+ item: &Item) {
+ match *self.kind() {
+ TypeKind::Pointer(inner) |
+ TypeKind::Reference(inner) |
+ TypeKind::Array(inner, _) |
+ TypeKind::TemplateAlias(inner, _) |
+ TypeKind::Alias(_, inner) |
+ TypeKind::Named(_, Some(inner)) |
+ TypeKind::ResolvedTypeRef(inner)
+ => inner.collect_types(context, types, &()),
+
+ TypeKind::TemplateRef(inner, ref template_args) => {
+ inner.collect_types(context, types, &());
+ for item in template_args {
+ item.collect_types(context, types, &());
+ }
+ }
+ TypeKind::Comp(ref ci) => ci.collect_types(context, types, item),
+ TypeKind::Function(ref sig) => {
+ sig.collect_types(context, types, item)
+ }
+ // FIXME: Pending types!
+ ref other @ _ => {
+ debug!("Ignoring: {:?}", other);
+ },
+ }
+ }
+}
diff --git a/src/ir/type_collector.rs b/src/ir/type_collector.rs
new file mode 100644
index 00000000..a829b165
--- /dev/null
+++ b/src/ir/type_collector.rs
@@ -0,0 +1,23 @@
+//! Collecting type items.
+
+use std::collections::BTreeSet;
+use super::context::BindgenContext;
+use super::item::ItemId;
+
+/// A set of items.
+pub type ItemSet = BTreeSet<ItemId>;
+
+/// Collect all the type items referenced by this item.
+pub trait TypeCollector {
+ /// If a particular type needs extra information beyond what it has in
+ /// `self` and `context` to find its referenced type items, its
+ /// implementation can define this associated type, forcing callers to pass
+ /// the needed information through.
+ type Extra;
+
+ /// Add each type item referenced by `self` into the `types` set.
+ fn collect_types(&self,
+ context: &BindgenContext,
+ types: &mut ItemSet,
+ extra: &Self::Extra);
+}