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