summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/codegen/mod.rs2
-rw-r--r--src/ir/context.rs90
-rw-r--r--src/ir/item.rs22
-rw-r--r--src/ir/module.rs4
-rw-r--r--src/ir/ty.rs6
5 files changed, 84 insertions, 40 deletions
diff --git a/src/codegen/mod.rs b/src/codegen/mod.rs
index ce5054c9..f2b3a17b 100644
--- a/src/codegen/mod.rs
+++ b/src/codegen/mod.rs
@@ -379,7 +379,7 @@ impl CodeGenerator for Module {
}
}
- if item.id() == ctx.root_module() {
+ if item.id() == ctx.root_module().into() {
if result.saw_bindgen_union {
utils::prepend_union_types(ctx, &mut *result);
}
diff --git a/src/ir/context.rs b/src/ir/context.rs
index cdc1dceb..24213ebc 100644
--- a/src/ir/context.rs
+++ b/src/ir/context.rs
@@ -30,7 +30,7 @@ use std::collections::btree_map::{self, BTreeMap};
use std::iter::IntoIterator;
use std::mem;
-/// A single identifier for an item.
+/// An identifier for some kind of IR item.
#[derive(Debug, Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
pub struct ItemId(usize);
@@ -39,6 +39,11 @@ pub struct ItemId(usize);
#[derive(Debug, Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
pub struct TypeId(ItemId);
+/// An identifier for an `Item` whose `ItemKind` is known to be
+/// `ItemKind::Module`.
+#[derive(Debug, Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
+pub struct ModuleId(ItemId);
+
impl From<TypeId> for ItemId {
fn from(tid: TypeId) -> ItemId {
tid.0
@@ -51,6 +56,18 @@ impl<'a> From<&'a TypeId> for ItemId {
}
}
+impl From<ModuleId> for ItemId {
+ fn from(mid: ModuleId) -> ItemId {
+ mid.0
+ }
+}
+
+impl<'a> From<&'a ModuleId> for ItemId {
+ fn from(mid: &'a ModuleId) -> ItemId {
+ mid.0
+ }
+}
+
impl From<ItemId> for usize {
fn from(id: ItemId) -> usize {
id.0
@@ -86,6 +103,30 @@ impl ItemId {
pub fn as_type_id_unchecked(&self) -> TypeId {
TypeId(*self)
}
+
+ /// Convert this `ItemId` into a `ModuleId` if its associated item is a module,
+ /// otherwise return `None`.
+ pub fn as_module_id(&self, ctx: &BindgenContext) -> Option<ModuleId> {
+ if ctx.resolve_item(*self).kind().is_module() {
+ Some(ModuleId(*self))
+ } else {
+ None
+ }
+ }
+
+ /// Convert this `ItemId` into a `ModuleId`.
+ ///
+ /// If this `ItemId` does not point to a module, then panic.
+ pub fn expect_module_id(&self, ctx: &BindgenContext) -> ModuleId {
+ self.as_module_id(ctx)
+ .expect("expect_module_id called with ItemId that doesn't point to a module")
+ }
+
+ /// Convert this `ItemId` into a `ModuleId` without actually checking whether
+ /// this id actually points to a `Module`.
+ pub fn as_module_id_unchecked(&self) -> ModuleId {
+ ModuleId(*self)
+ }
}
impl<T> CanDeriveDebug for T
@@ -200,13 +241,13 @@ pub struct BindgenContext {
type_params: HashMap<clang::Cursor, TypeId>,
/// A cursor to module map. Similar reason than above.
- modules: HashMap<Cursor, ItemId>,
+ modules: HashMap<Cursor, ModuleId>,
/// The root module, this is guaranteed to be an item of kind Module.
- root_module: ItemId,
+ root_module: ModuleId,
/// Current module being traversed.
- current_module: ItemId,
+ current_module: ModuleId,
/// A HashMap keyed on a type definition, and whose value is the parent id
/// of the declaration.
@@ -449,14 +490,16 @@ impl BindgenContext {
effective_target == "i686-pc-win32";
let root_module = Self::build_root_module(ItemId(0));
+ let root_module_id = root_module.id().as_module_id_unchecked();
+
let mut me = BindgenContext {
items: Default::default(),
types: Default::default(),
type_params: Default::default(),
modules: Default::default(),
next_item_id: ItemId(1),
- root_module: root_module.id(),
- current_module: root_module.id(),
+ root_module: root_module_id,
+ current_module: root_module_id,
semantic_parents: Default::default(),
currently_parsed_types: vec![],
parsed_macros: Default::default(),
@@ -551,7 +594,7 @@ impl BindgenContext {
let is_template_instantiation = is_type &&
item.expect_type().is_template_instantiation();
- if item.id() != self.root_module {
+ if item.id() != self.root_module.into() {
self.add_item_to_module(&item);
}
@@ -615,7 +658,7 @@ impl BindgenContext {
/// codegen'd, even if its parent is not whitelisted. See issue #769 for
/// details.
fn add_item_to_module(&mut self, item: &Item) {
- assert!(item.id() != self.root_module);
+ assert!(item.id() != self.root_module.into());
assert!(!self.items.contains_key(&item.id()));
if let Some(parent) = self.items.get_mut(&item.parent_id()) {
@@ -638,7 +681,7 @@ impl BindgenContext {
);
self.items
- .get_mut(&self.current_module)
+ .get_mut(&self.current_module.into())
.expect("Should always have an item for self.current_module")
.as_module_mut()
.expect("self.current_module should always be a module")
@@ -966,7 +1009,7 @@ impl BindgenContext {
let immut_self = &*self;
old_parent
.ancestors(immut_self)
- .chain(Some(immut_self.root_module))
+ .chain(Some(immut_self.root_module.into()))
.find(|id| {
let item = immut_self.resolve_item(*id);
item.as_module().map_or(false, |m| {
@@ -984,7 +1027,7 @@ impl BindgenContext {
immut_self.resolve_item(*id).is_module()
})
};
- let new_module = new_module.unwrap_or(self.root_module);
+ let new_module = new_module.unwrap_or(self.root_module.into());
if new_module == old_module {
// Already in the correct module.
@@ -1091,7 +1134,7 @@ impl BindgenContext {
assert!(self.current_module == self.root_module);
for (&id, _item) in self.items() {
- if id == self.root_module {
+ if id == self.root_module.into() {
continue;
}
@@ -1102,7 +1145,7 @@ impl BindgenContext {
.through_type_aliases()
.resolve(self)
.id();
- id.ancestors(self).chain(Some(self.root_module)).any(
+ id.ancestors(self).chain(Some(self.root_module.into())).any(
|ancestor| {
debug!(
"Checking if {:?} is a child of {:?}",
@@ -1271,7 +1314,7 @@ impl BindgenContext {
}
/// Get the root module.
- pub fn root_module(&self) -> ItemId {
+ pub fn root_module(&self) -> ModuleId {
self.root_module
}
@@ -1309,7 +1352,7 @@ impl BindgenContext {
}
/// Get the current module.
- pub fn current_module(&self) -> ItemId {
+ pub fn current_module(&self) -> ModuleId {
self.current_module
}
@@ -1561,7 +1604,7 @@ impl BindgenContext {
sub_id,
None,
None,
- self.current_module,
+ self.current_module.into(),
ItemKind::Type(sub_ty),
);
@@ -1625,7 +1668,7 @@ impl BindgenContext {
with_id,
None,
None,
- self.current_module,
+ self.current_module.into(),
ItemKind::Type(ty),
);
@@ -1745,7 +1788,7 @@ impl BindgenContext {
with_id,
None,
None,
- parent_id.unwrap_or(self.current_module),
+ parent_id.unwrap_or(self.current_module.into()),
ItemKind::Type(ty),
);
self.add_builtin_item(item);
@@ -1809,7 +1852,7 @@ impl BindgenContext {
let ty = Type::new(Some(spelling), layout, type_kind, is_const);
let id = self.next_item_id();
let item =
- Item::new(id, None, None, self.root_module, ItemKind::Type(ty));
+ Item::new(id, None, None, self.root_module.into(), ItemKind::Type(ty));
self.add_builtin_item(item);
Some(id.as_type_id_unchecked())
}
@@ -1970,7 +2013,7 @@ impl BindgenContext {
/// Given a CXCursor_Namespace cursor, return the item id of the
/// corresponding module, or create one on the fly.
- pub fn module(&mut self, cursor: clang::Cursor) -> ItemId {
+ pub fn module(&mut self, cursor: clang::Cursor) -> ModuleId {
use clang_sys::*;
assert_eq!(cursor.kind(), CXCursor_Namespace, "Be a nice person");
let cursor = cursor.canonical();
@@ -1986,11 +2029,12 @@ impl BindgenContext {
module_id,
None,
None,
- self.current_module,
+ self.current_module.into(),
ItemKind::Module(module),
);
- self.modules.insert(cursor, module.id());
+ let module_id = module.id().as_module_id_unchecked();
+ self.modules.insert(cursor, module_id);
self.add_item(module, None, None);
@@ -1999,7 +2043,7 @@ impl BindgenContext {
/// Start traversing the module with the given `module_id`, invoke the
/// callback `cb`, and then return to traversing the original module.
- pub fn with_module<F>(&mut self, module_id: ItemId, cb: F)
+ pub fn with_module<F>(&mut self, module_id: ModuleId, cb: F)
where
F: FnOnce(&mut Self),
{
diff --git a/src/ir/item.rs b/src/ir/item.rs
index 1e18cb73..2b137584 100644
--- a/src/ir/item.rs
+++ b/src/ir/item.rs
@@ -465,7 +465,7 @@ impl Item {
) -> TypeId {
let ty = Opaque::from_clang_ty(ty);
let kind = ItemKind::Type(ty);
- let parent = ctx.root_module();
+ let parent = ctx.root_module().into();
ctx.add_item(Item::new(with_id, None, None, parent, kind), None, None);
with_id.as_type_id_unchecked()
}
@@ -577,7 +577,7 @@ impl Item {
// FIXME: Workaround for some types falling behind when parsing weird
// stl classes, for example.
if ctx.options().enable_cxx_namespaces && self.kind().is_module() &&
- self.id() != ctx.root_module()
+ self.id() != ctx.root_module().into()
{
return false;
}
@@ -589,7 +589,7 @@ impl Item {
None => return false,
};
- if parent_item.id() == ctx.root_module() {
+ if parent_item.id() == ctx.root_module().into() {
return true;
} else if ctx.options().enable_cxx_namespaces ||
!parent_item.kind().is_module()
@@ -834,7 +834,7 @@ impl Item {
let mut names: Vec<_> = target
.parent_id()
.ancestors(ctx)
- .filter(|id| *id != ctx.root_module())
+ .filter(|id| *id != ctx.root_module().into())
.take_while(|id| {
// Stop iterating ancestors once we reach a non-inline namespace
// when opt.within_namespaces is set.
@@ -1162,7 +1162,7 @@ impl ClangItemParser for Item {
let ty = Type::new(None, None, kind, is_const);
let id = ctx.next_item_id();
- let module = ctx.root_module();
+ let module = ctx.root_module().into();
ctx.add_item(
Item::new(id, None, None, module, ItemKind::Type(ty)),
None,
@@ -1189,7 +1189,7 @@ impl ClangItemParser for Item {
let comment = cursor.raw_comment();
let annotations = Annotations::new(&cursor);
- let current_module = ctx.current_module();
+ let current_module = ctx.current_module().into();
let relevant_parent_id = parent_id.unwrap_or(current_module);
macro_rules! try_parse {
@@ -1246,7 +1246,7 @@ impl ClangItemParser for Item {
}
ctx.known_semantic_parent(definition)
.or(parent_id)
- .unwrap_or(ctx.current_module())
+ .unwrap_or(ctx.current_module().into())
}
None => relevant_parent_id,
};
@@ -1368,7 +1368,7 @@ impl ClangItemParser for Item {
potential_id,
None,
None,
- parent_id.unwrap_or(current_module),
+ parent_id.unwrap_or(current_module.into()),
ItemKind::Type(Type::new(None, None, kind, is_const)),
),
Some(clang::Cursor::null()),
@@ -1477,7 +1477,7 @@ impl ClangItemParser for Item {
}
}
- let current_module = ctx.current_module();
+ let current_module = ctx.current_module().into();
let partial_ty = PartialType::new(declaration_to_look_for, id);
if valid_decl {
ctx.begin_parsing(partial_ty);
@@ -1700,7 +1700,7 @@ impl ClangItemParser for Item {
// referenced with namespace prefixes, and they can't inherit anything
// from their parent either, so it is simplest to just hang them off
// something we know will always exist.
- let parent = ctx.root_module();
+ let parent = ctx.root_module().into();
if let Some(id) = ctx.get_type_param(&definition) {
if let Some(with_id) = with_id {
@@ -1786,7 +1786,7 @@ impl ItemCanonicalPath for Item {
let target = ctx.resolve_item(self.name_target(ctx));
let mut path: Vec<_> = target
.ancestors(ctx)
- .chain(iter::once(ctx.root_module()))
+ .chain(iter::once(ctx.root_module().into()))
.map(|id| ctx.resolve_item(id))
.filter(|item| {
item.id() == target.id() ||
diff --git a/src/ir/module.rs b/src/ir/module.rs
index c66623dd..af46d4ac 100644
--- a/src/ir/module.rs
+++ b/src/ir/module.rs
@@ -83,11 +83,11 @@ impl ClangSubItemParser for Module {
let module_id = ctx.module(cursor);
ctx.with_module(module_id, |ctx| {
cursor.visit(
- |cursor| parse_one(ctx, cursor, Some(module_id)),
+ |cursor| parse_one(ctx, cursor, Some(module_id.into())),
)
});
- Ok(ParseResult::AlreadyResolved(module_id))
+ Ok(ParseResult::AlreadyResolved(module_id.into()))
}
_ => Err(ParseError::Continue),
}
diff --git a/src/ir/ty.rs b/src/ir/ty.rs
index 601dce6c..5aef39a2 100644
--- a/src/ir/ty.rs
+++ b/src/ir/ty.rs
@@ -702,16 +702,16 @@ impl Type {
TypeKind::Comp(ref ci) => ci.is_unsized(ctx, id),
TypeKind::Opaque => self.layout.map_or(true, |l| l.size == 0),
TypeKind::Array(inner, size) => {
- size == 0 || ctx.resolve_type(inner).is_unsized(ctx, &inner.into())
+ size == 0 || ctx.resolve_type(inner).is_unsized(ctx, inner)
}
TypeKind::ResolvedTypeRef(inner) |
TypeKind::Alias(inner) |
TypeKind::TemplateAlias(inner, _) => {
- ctx.resolve_type(inner).is_unsized(ctx, &inner.into())
+ ctx.resolve_type(inner).is_unsized(ctx, inner)
}
TypeKind::TemplateInstantiation(ref inst) => {
let definition = inst.template_definition();
- ctx.resolve_type(definition).is_unsized(ctx, &definition.into())
+ ctx.resolve_type(definition).is_unsized(ctx, definition)
}
TypeKind::TypeParam |
TypeKind::Int(..) |