diff --git a/src/codegen/mod.rs b/src/codegen/mod.rs index 3f7c87e84d..8e04fd7c05 100755 --- a/src/codegen/mod.rs +++ b/src/codegen/mod.rs @@ -5,11 +5,11 @@ use aster; use ir::annotations::FieldAccessorKind; use ir::comp::{CompInfo, CompKind, Field, Method}; -use ir::context::BindgenContext; +use ir::context::{BindgenContext, ItemId}; use ir::enum_ty::{Enum, EnumVariant, EnumVariantValue}; use ir::function::{Function, FunctionSig}; use ir::int::IntKind; -use ir::item::{Item, ItemCanonicalName, ItemCanonicalPath, ItemId}; +use ir::item::{Item, ItemCanonicalName, ItemCanonicalPath}; use ir::item_kind::ItemKind; use ir::layout::Layout; use ir::module::Module; @@ -1919,8 +1919,8 @@ pub fn codegen(context: &mut BindgenContext) -> Vec> { mod utils { use aster; - use ir::context::BindgenContext; - use ir::item::{Item, ItemCanonicalPath, ItemId}; + use ir::context::{BindgenContext, ItemId}; + use ir::item::{Item, ItemCanonicalPath}; use ir::ty::TypeKind; use std::mem; use super::ItemToRustTy; diff --git a/src/ir/comp.rs b/src/ir/comp.rs index 1d823d0a90..d19d12092b 100644 --- a/src/ir/comp.rs +++ b/src/ir/comp.rs @@ -5,8 +5,8 @@ use parse::{ClangItemParser, ParseError}; use std::cell::Cell; use std::cmp; use super::annotations::Annotations; -use super::context::BindgenContext; -use super::item::{Item, ItemId}; +use super::context::{BindgenContext, ItemId}; +use super::item::Item; use super::layout::Layout; use super::ty::{RUST_DERIVE_IN_ARRAY_LIMIT, Type}; use super::type_collector::{ItemSet, TypeCollector}; diff --git a/src/ir/context.rs b/src/ir/context.rs index 8c84b328e6..857219780e 100644 --- a/src/ir/context.rs +++ b/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, ItemId}; +use super::item::{Item, ItemCanonicalName}; use super::item_kind::ItemKind; use super::module::Module; use super::ty::{FloatKind, Type, TypeKind}; @@ -19,6 +19,19 @@ use syntax::ast::Ident; use syntax::codemap::{DUMMY_SP, Span}; use syntax::ext::base::ExtCtxt; +/// A single identifier for an item. +/// +/// TODO: Build stronger abstractions on top of this, like TypeId(ItemId)? +#[derive(Debug, Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)] +pub struct ItemId(usize); + +impl ItemId { + /// Get a numeric representation of this id. + pub fn as_usize(&self) -> usize { + self.0 + } +} + /// A key used to index a resolved type, so we only process it once. /// /// This is almost always a USR string (an unique identifier generated by @@ -50,6 +63,9 @@ pub struct BindgenContext<'ctx> { /// output. items: BTreeMap, + /// The next item id to use during this bindings regeneration. + next_item_id: ItemId, + /// Clang USR to type map. This is needed to be able to associate types with /// item ids during parsing. types: HashMap, @@ -122,11 +138,12 @@ impl<'ctx> BindgenContext<'ctx> { parse_options) .expect("TranslationUnit::parse"); - let root_module = Self::build_root_module(); + let root_module = Self::build_root_module(ItemId(0)); let mut me = BindgenContext { items: Default::default(), types: Default::default(), modules: Default::default(), + next_item_id: ItemId(1), root_module: root_module.id(), current_module: root_module.id(), currently_parsed_types: vec![], @@ -422,9 +439,8 @@ impl<'ctx> BindgenContext<'ctx> { assert!(old_item.is_none(), "Inserted type twice?"); } - fn build_root_module() -> Item { + fn build_root_module(id: ItemId) -> Item { let module = Module::new(Some("root".into())); - let id = ItemId::next(); Item::new(id, None, None, id, ItemKind::Module(module)) } @@ -702,6 +718,13 @@ impl<'ctx> BindgenContext<'ctx> { with_id } + /// Returns the next item id to be used for an item. + pub fn next_item_id(&mut self) -> ItemId { + let ret = self.next_item_id; + self.next_item_id = ItemId(self.next_item_id.0 + 1); + ret + } + fn build_builtin_ty(&mut self, ty: &clang::Type, _declaration: Cursor) @@ -747,7 +770,7 @@ impl<'ctx> BindgenContext<'ctx> { let is_const = ty.is_const(); let layout = ty.fallible_layout().ok(); let ty = Type::new(Some(spelling), layout, type_kind, is_const); - let id = ItemId::next(); + let id = self.next_item_id(); let item = Item::new(id, None, None, self.root_module, ItemKind::Type(ty)); self.add_builtin_item(item); @@ -841,11 +864,11 @@ impl<'ctx> BindgenContext<'ctx> { use clangll::*; assert!(cursor.kind() == CXCursor_Namespace, "Be a nice person"); let cursor = cursor.canonical(); - let module_id = match self.modules.get(&cursor) { - Some(id) => return *id, - None => ItemId::next(), - }; + if let Some(id) = self.modules.get(&cursor) { + return *id; + } + let module_id = self.next_item_id(); let module_name = self.translation_unit .tokens(&cursor) .and_then(|tokens| { diff --git a/src/ir/enum_ty.rs b/src/ir/enum_ty.rs index 8efd9e3be1..6085833d18 100644 --- a/src/ir/enum_ty.rs +++ b/src/ir/enum_ty.rs @@ -2,8 +2,8 @@ use clang; use parse::{ClangItemParser, ParseError}; -use super::context::BindgenContext; -use super::item::{Item, ItemId}; +use super::context::{BindgenContext, ItemId}; +use super::item::Item; use super::ty::TypeKind; /// A C/C++ enumeration. diff --git a/src/ir/function.rs b/src/ir/function.rs index e45dcbe817..eacb6c0ea8 100644 --- a/src/ir/function.rs +++ b/src/ir/function.rs @@ -3,8 +3,8 @@ use clang; use clangll::Enum_CXCallingConv; use parse::{ClangItemParser, ClangSubItemParser, ParseError, ParseResult}; -use super::context::BindgenContext; -use super::item::{Item, ItemId}; +use super::context::{BindgenContext, ItemId}; +use super::item::Item; use super::ty::TypeKind; use super::type_collector::{ItemSet, TypeCollector}; use syntax::abi; diff --git a/src/ir/item.rs b/src/ir/item.rs index 17d249b560..1f05f92f39 100644 --- a/src/ir/item.rs +++ b/src/ir/item.rs @@ -4,9 +4,8 @@ use clang; use parse::{ClangItemParser, ClangSubItemParser, ParseError, ParseResult}; use regex::Regex; use std::cell::{Cell, RefCell}; -use std::sync::atomic::{ATOMIC_USIZE_INIT, AtomicUsize, Ordering}; use super::annotations::Annotations; -use super::context::BindgenContext; +use super::context::{BindgenContext, ItemId}; use super::function::Function; use super::item_kind::ItemKind; use super::module::Module; @@ -78,21 +77,6 @@ impl<'a, 'b> Iterator for ItemAncestorsIter<'a, 'b> } } -/// A single identifier for an item. -/// -/// TODO: Build stronger abstractions on top of this, like TypeId(ItemId)? -#[derive(Debug, Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)] -pub struct ItemId(usize); - -impl ItemId { - /// Allocate the next `ItemId`. - pub fn next() -> Self { - static NEXT_ITEM_ID: AtomicUsize = ATOMIC_USIZE_INIT; - let next_id = NEXT_ITEM_ID.fetch_add(1, Ordering::Relaxed); - ItemId(next_id) - } -} - // Pure convenience impl ItemCanonicalName for ItemId { fn canonical_name(&self, ctx: &BindgenContext) -> String { @@ -667,7 +651,7 @@ impl Item { // Note that this `id_` prefix prevents (really unlikely) collisions // between the global id and the local id of an item with the same // parent. - format!("id_{}", self.id().0) + format!("id_{}", self.id().as_usize()) } fn make_exposed_name(&self, @@ -747,7 +731,7 @@ impl ClangItemParser for Item { } let ty = Type::new(None, None, kind, is_const); - let id = ItemId::next(); + let id = ctx.next_item_id(); let module = ctx.root_module(); ctx.add_item(Item::new(id, None, None, module, ItemKind::Type(ty)), None, @@ -779,7 +763,7 @@ impl ClangItemParser for Item { ($what:ident) => { match $what::parse(cursor, ctx) { Ok(ParseResult::New(item, declaration)) => { - let id = ItemId::next(); + let id = ctx.next_item_id(); ctx.add_item(Item::new(id, comment, annotations, relevant_parent_id, @@ -855,7 +839,8 @@ impl ClangItemParser for Item { parent_id: Option, ctx: &mut BindgenContext) -> ItemId { - Self::from_ty_or_ref_with_id(ItemId::next(), + let id = ctx.next_item_id(); + Self::from_ty_or_ref_with_id(id, ty, location, parent_id, @@ -925,7 +910,8 @@ impl ClangItemParser for Item { parent_id: Option, ctx: &mut BindgenContext) -> Result { - Self::from_ty_with_id(ItemId::next(), ty, location, parent_id, ctx) + let id = ctx.next_item_id(); + Self::from_ty_with_id(id, ty, location, parent_id, ctx) } /// This is one of the trickiest methods you'll find (probably along with @@ -1109,7 +1095,8 @@ impl ClangItemParser for Item { -> ItemId where S: Into, { - Self::named_type_with_id(ItemId::next(), name, default, parent_id, ctx) + let id = ctx.next_item_id(); + Self::named_type_with_id(id, name, default, parent_id, ctx) } } diff --git a/src/ir/module.rs b/src/ir/module.rs index 42175b920e..c5d8cfa79e 100644 --- a/src/ir/module.rs +++ b/src/ir/module.rs @@ -3,8 +3,7 @@ use clang; use parse::{ClangSubItemParser, ParseError, ParseResult}; use parse_one; -use super::context::BindgenContext; -use super::item::ItemId; +use super::context::{BindgenContext, ItemId}; /// A module, as in, a C++ namespace. #[derive(Clone, Debug)] diff --git a/src/ir/ty.rs b/src/ir/ty.rs index ba69296b25..34af2db502 100644 --- a/src/ir/ty.rs +++ b/src/ir/ty.rs @@ -3,11 +3,11 @@ use clang::{self, Cursor}; use parse::{ClangItemParser, ParseError, ParseResult}; use super::comp::CompInfo; -use super::context::BindgenContext; +use super::context::{BindgenContext, ItemId}; use super::enum_ty::Enum; use super::function::FunctionSig; use super::int::IntKind; -use super::item::{Item, ItemId}; +use super::item::Item; use super::layout::Layout; use super::type_collector::{ItemSet, TypeCollector}; diff --git a/src/ir/type_collector.rs b/src/ir/type_collector.rs index a829b165ba..0f10152d4a 100644 --- a/src/ir/type_collector.rs +++ b/src/ir/type_collector.rs @@ -1,8 +1,7 @@ //! Collecting type items. use std::collections::BTreeSet; -use super::context::BindgenContext; -use super::item::ItemId; +use super::context::{BindgenContext, ItemId}; /// A set of items. pub type ItemSet = BTreeSet; diff --git a/src/ir/var.rs b/src/ir/var.rs index 1c7b20280e..d0c4d9cacd 100644 --- a/src/ir/var.rs +++ b/src/ir/var.rs @@ -4,10 +4,10 @@ use cexpr; use clang; use parse::{ClangItemParser, ClangSubItemParser, ParseError, ParseResult}; use std::num::Wrapping; -use super::context::BindgenContext; +use super::context::{BindgenContext, ItemId}; use super::function::cursor_mangling; use super::int::IntKind; -use super::item::{Item, ItemId}; +use super::item::Item; use super::ty::TypeKind; /// A `Var` is our intermediate representation of a variable. diff --git a/src/lib.rs b/src/lib.rs index db87eb228d..b56cb468e9 100755 --- a/src/lib.rs +++ b/src/lib.rs @@ -78,8 +78,8 @@ mod codegen { include!(concat!(env!("OUT_DIR"), "/codegen.rs")); } -use ir::context::BindgenContext; -use ir::item::{Item, ItemId}; +use ir::context::{BindgenContext, ItemId}; +use ir::item::Item; use parse::{ClangItemParser, ParseError}; use regex_set::RegexSet; diff --git a/src/parse.rs b/src/parse.rs index 98cf6b13e8..28e6575945 100644 --- a/src/parse.rs +++ b/src/parse.rs @@ -1,8 +1,7 @@ //! Common traits and types related to parsing our IR from Clang cursors. use clang; -use ir::context::BindgenContext; -use ir::item::ItemId; +use ir::context::{BindgenContext, ItemId}; use ir::ty::TypeKind; /// Not so much an error in the traditional sense, but a control flow message