diff options
-rw-r--r-- | src/codegen/mod.rs | 2 | ||||
-rw-r--r-- | src/ir/context.rs | 90 | ||||
-rw-r--r-- | src/ir/item.rs | 22 | ||||
-rw-r--r-- | src/ir/module.rs | 4 | ||||
-rw-r--r-- | src/ir/ty.rs | 6 |
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(..) | |