summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorbors-servo <lbergstrom+bors@mozilla.com>2017-10-02 15:47:41 -0500
committerGitHub <noreply@github.com>2017-10-02 15:47:41 -0500
commitc66598d28b7ffe8b8e30a58e9268db50dd109986 (patch)
tree246f534a435e0974032490ef67f74a16b45f825e
parent0c5f4e1ffa6da921ff07525fcd1a25623c782d0e (diff)
parent5f3bf1f0230d753edf198d9d4e1266b3c0756e2d (diff)
Auto merge of #1050 - fitzgen:strongly-type-ids, r=pepyakin
Strongly type ids * [X] `TypeId` * [X] `ModuleId` * [x] `VarId` * [x] `FunctionId`
-rw-r--r--src/codegen/mod.rs67
-rw-r--r--src/ir/analysis/derive_copy.rs10
-rw-r--r--src/ir/analysis/derive_debug.rs8
-rw-r--r--src/ir/analysis/derive_default.rs12
-rw-r--r--src/ir/analysis/derive_hash.rs23
-rw-r--r--src/ir/analysis/derive_partial_eq_or_partial_ord.rs23
-rw-r--r--src/ir/analysis/has_destructor.rs13
-rw-r--r--src/ir/analysis/has_float.rs17
-rw-r--r--src/ir/analysis/has_type_param_in_array.rs13
-rw-r--r--src/ir/analysis/has_vtable.rs9
-rw-r--r--src/ir/analysis/template_params.rs9
-rw-r--r--src/ir/comp.rs101
-rw-r--r--src/ir/context.rs422
-rw-r--r--src/ir/enum_ty.rs8
-rw-r--r--src/ir/function.rs32
-rw-r--r--src/ir/item.rs169
-rw-r--r--src/ir/module.rs4
-rw-r--r--src/ir/template.rs28
-rw-r--r--src/ir/ty.rs58
-rw-r--r--src/ir/var.rs8
-rw-r--r--src/parse.rs14
21 files changed, 648 insertions, 400 deletions
diff --git a/src/codegen/mod.rs b/src/codegen/mod.rs
index 895422b0..264b701b 100644
--- a/src/codegen/mod.rs
+++ b/src/codegen/mod.rs
@@ -6,6 +6,7 @@ pub mod struct_layout;
use self::helpers::attributes;
use self::struct_layout::StructLayoutTracker;
+use ir::analysis::HasVtable;
use ir::annotations::FieldAccessorKind;
use ir::comment;
use ir::comp::{Base, Bitfield, BitfieldUnit, CompInfo, CompKind, Field,
@@ -151,12 +152,12 @@ impl<'a> CodegenResult<'a> {
self.saw_objc = true;
}
- fn seen(&self, item: ItemId) -> bool {
- self.items_seen.contains(&item)
+ fn seen<Id: Into<ItemId>>(&self, item: Id) -> bool {
+ self.items_seen.contains(&item.into())
}
- fn set_seen(&mut self, item: ItemId) {
- self.items_seen.insert(item);
+ fn set_seen<Id: Into<ItemId>>(&mut self, item: Id) {
+ self.items_seen.insert(item.into());
}
fn seen_function(&self, name: &str) -> bool {
@@ -599,7 +600,7 @@ impl CodeGenerator for Type {
// If this is a known named type, disallow generating anything
// for it too.
let spelling = self.name().expect("Unnamed alias?");
- if utils::type_from_named(ctx, spelling, inner).is_some() {
+ if utils::type_from_named(ctx, spelling).is_some() {
return;
}
@@ -1546,7 +1547,7 @@ impl CodeGenerator for CompInfo {
// NB: We won't include unsized types in our base chain because they
// would contribute to our size given the dummy field we insert for
// unsized types.
- if base_ty.is_unsized(ctx, &base.ty) {
+ if base_ty.is_unsized(ctx, base.ty) {
continue;
}
@@ -1625,7 +1626,7 @@ impl CodeGenerator for CompInfo {
warn!("Opaque type without layout! Expect dragons!");
}
}
- } else if !is_union && !self.is_unsized(ctx, &item.id()) {
+ } else if !is_union && !self.is_unsized(ctx, item.id().expect_type_id(ctx)) {
if let Some(padding_field) =
layout.and_then(|layout| struct_layout.pad_struct(layout))
{
@@ -1649,7 +1650,7 @@ impl CodeGenerator for CompInfo {
//
// NOTE: This check is conveniently here to avoid the dummy fields we
// may add for unused template parameters.
- if self.is_unsized(ctx, &item.id()) {
+ if self.is_unsized(ctx, item.id().expect_type_id(ctx)) {
let has_address = if is_opaque {
// Generate the address field if it's an opaque type and
// couldn't determine the layout of the blob.
@@ -1758,9 +1759,8 @@ impl CodeGenerator for CompInfo {
// FIXME when [issue #465](https://github.com/rust-lang-nursery/rust-bindgen/issues/465) ready
let too_many_base_vtables = self.base_members()
.iter()
- .filter(|base| ctx.lookup_item_id_has_vtable(&base.ty))
- .count() >
- 1;
+ .filter(|base| base.ty.has_vtable(ctx))
+ .count() > 1;
let should_skip_field_offset_checks = is_opaque ||
too_many_base_vtables;
@@ -2728,7 +2728,10 @@ where
}
}
-impl TryToOpaque for ItemId {
+impl<T> TryToOpaque for T
+where
+ T: Copy + Into<ItemId>
+{
type Extra = ();
fn try_get_layout(
@@ -2736,11 +2739,14 @@ impl TryToOpaque for ItemId {
ctx: &BindgenContext,
_: &(),
) -> error::Result<Layout> {
- ctx.resolve_item(*self).try_get_layout(ctx, &())
+ ctx.resolve_item((*self).into()).try_get_layout(ctx, &())
}
}
-impl TryToRustTy for ItemId {
+impl<T> TryToRustTy for T
+where
+ T: Copy + Into<ItemId>
+{
type Extra = ();
fn try_to_rust_ty(
@@ -2748,7 +2754,7 @@ impl TryToRustTy for ItemId {
ctx: &BindgenContext,
_: &(),
) -> error::Result<quote::Tokens> {
- ctx.resolve_item(*self).try_to_rust_ty(ctx, &())
+ ctx.resolve_item((*self).into()).try_to_rust_ty(ctx, &())
}
}
@@ -2889,8 +2895,8 @@ impl TryToRustTy for Type {
inst.try_to_rust_ty(ctx, item)
}
TypeKind::ResolvedTypeRef(inner) => inner.try_to_rust_ty(ctx, &()),
- TypeKind::TemplateAlias(inner, _) |
- TypeKind::Alias(inner) => {
+ TypeKind::TemplateAlias(..) |
+ TypeKind::Alias(..) => {
let template_params = item.used_template_params(ctx)
.unwrap_or(vec![])
.into_iter()
@@ -2903,12 +2909,11 @@ impl TryToRustTy for Type {
} else if let Some(ty) = utils::type_from_named(
ctx,
spelling,
- inner,
)
{
Ok(ty)
} else {
- utils::build_templated_path(item, ctx, vec![]) //template_params)
+ utils::build_path(item, ctx)
}
}
TypeKind::Comp(ref info) => {
@@ -2919,8 +2924,7 @@ impl TryToRustTy for Type {
return self.try_to_opaque(ctx, item);
}
- // let template_params = template_params.unwrap_or(vec![]);
- utils::build_templated_path(item, ctx, vec![])
+ utils::build_path(item, ctx)
}
TypeKind::Opaque => self.try_to_opaque(ctx, item),
TypeKind::BlockPointer => {
@@ -3326,8 +3330,8 @@ pub fn codegen(context: &mut BindgenContext) -> Vec<quote::Tokens> {
}
mod utils {
- use super::{ToRustTyOrOpaque, TryToRustTy, error};
- use ir::context::{BindgenContext, ItemId};
+ use super::{ToRustTyOrOpaque, error};
+ use ir::context::BindgenContext;
use ir::function::FunctionSig;
use ir::item::{Item, ItemCanonicalPath};
use ir::ty::TypeKind;
@@ -3549,28 +3553,16 @@ mod utils {
result.extend(old_items.into_iter());
}
- pub fn build_templated_path(
+ pub fn build_path(
item: &Item,
ctx: &BindgenContext,
- template_params: Vec<ItemId>,
) -> error::Result<quote::Tokens> {
let path = item.namespace_aware_canonical_path(ctx);
- let template_params = template_params
- .iter()
- .map(|param| param.try_to_rust_ty(ctx, &()))
- .collect::<error::Result<Vec<_>>>()?;
-
let mut tokens = quote! {};
tokens.append_separated(path.into_iter().map(quote::Ident::new), "::");
- if template_params.is_empty() {
- Ok(tokens)
- } else {
- Ok(quote! {
- #tokens < #( #template_params ),* >
- })
- }
+ Ok(tokens)
}
fn primitive_ty(ctx: &BindgenContext, name: &str) -> quote::Tokens {
@@ -3583,7 +3575,6 @@ mod utils {
pub fn type_from_named(
ctx: &BindgenContext,
name: &str,
- _inner: ItemId,
) -> Option<quote::Tokens> {
// FIXME: We could use the inner item to check this is really a
// primitive type but, who the heck overrides these anyway?
diff --git a/src/ir/analysis/derive_copy.rs b/src/ir/analysis/derive_copy.rs
index 264d227a..ba40141e 100644
--- a/src/ir/analysis/derive_copy.rs
+++ b/src/ir/analysis/derive_copy.rs
@@ -73,7 +73,8 @@ impl<'ctx> CannotDeriveCopy<'ctx> {
}
}
- fn insert(&mut self, id: ItemId) -> ConstrainResult {
+ fn insert<Id: Into<ItemId>>(&mut self, id: Id) -> ConstrainResult {
+ let id = id.into();
trace!("inserting {:?} into the cannot_derive_copy set", id);
let was_not_already_in_set = self.cannot_derive_copy.insert(id);
@@ -89,7 +90,8 @@ impl<'ctx> CannotDeriveCopy<'ctx> {
/// A type is not `Copy` if we've determined it is not copy, or if it is
/// blacklisted.
- fn is_not_copy(&self, id: ItemId) -> bool {
+ fn is_not_copy<Id: Into<ItemId>>(&self, id: Id) -> bool {
+ let id = id.into();
self.cannot_derive_copy.contains(&id) ||
!self.ctx.whitelisted_items().contains(&id)
}
@@ -222,7 +224,7 @@ impl<'ctx> MonotoneFramework for CannotDeriveCopy<'ctx> {
// NOTE: Take into account that while unions in C and C++ are copied by
// default, the may have an explicit destructor in C++, so we can't
// defer this check just for the union case.
- if self.ctx.lookup_item_id_has_destructor(&id) {
+ if self.ctx.lookup_has_destructor(id.expect_type_id(self.ctx)) {
trace!(" comp has destructor which cannot derive copy");
return self.insert(id);
}
@@ -307,7 +309,7 @@ impl<'ctx> MonotoneFramework for CannotDeriveCopy<'ctx> {
"The early ty.is_opaque check should have handled this case"
);
let def_cannot_derive = self.is_not_copy(
- template.template_definition(),
+ template.template_definition()
);
if def_cannot_derive {
trace!(
diff --git a/src/ir/analysis/derive_debug.rs b/src/ir/analysis/derive_debug.rs
index 7df745c9..a1743ae9 100644
--- a/src/ir/analysis/derive_debug.rs
+++ b/src/ir/analysis/derive_debug.rs
@@ -74,7 +74,8 @@ impl<'ctx> CannotDeriveDebug<'ctx> {
}
}
- fn insert(&mut self, id: ItemId) -> ConstrainResult {
+ fn insert<Id: Into<ItemId>>(&mut self, id: Id) -> ConstrainResult {
+ let id = id.into();
trace!("inserting {:?} into the cannot_derive_debug set", id);
let was_not_already_in_set = self.cannot_derive_debug.insert(id);
@@ -90,7 +91,8 @@ impl<'ctx> CannotDeriveDebug<'ctx> {
/// A type is not `Debug` if we've determined it is not debug, or if it is
/// blacklisted.
- fn is_not_debug(&self, id: ItemId) -> bool {
+ fn is_not_debug<Id: Into<ItemId>>(&self, id: Id) -> bool {
+ let id = id.into();
self.cannot_derive_debug.contains(&id) ||
!self.ctx.whitelisted_items().contains(&id)
}
@@ -325,7 +327,7 @@ impl<'ctx> MonotoneFramework for CannotDeriveDebug<'ctx> {
"The early ty.is_opaque check should have handled this case"
);
let def_cannot_derive = self.is_not_debug(
- template.template_definition(),
+ template.template_definition()
);
if def_cannot_derive {
trace!(
diff --git a/src/ir/analysis/derive_default.rs b/src/ir/analysis/derive_default.rs
index 7acbe04a..f8f02df7 100644
--- a/src/ir/analysis/derive_default.rs
+++ b/src/ir/analysis/derive_default.rs
@@ -71,7 +71,8 @@ impl<'ctx> CannotDeriveDefault<'ctx> {
}
}
- fn insert(&mut self, id: ItemId) -> ConstrainResult {
+ fn insert<Id: Into<ItemId>>(&mut self, id: Id) -> ConstrainResult {
+ let id = id.into();
trace!("inserting {:?} into the cannot_derive_default set", id);
let was_not_already_in_set = self.cannot_derive_default.insert(id);
@@ -85,7 +86,8 @@ impl<'ctx> CannotDeriveDefault<'ctx> {
ConstrainResult::Changed
}
- fn is_not_default(&self, id: ItemId) -> bool {
+ fn is_not_default<Id: Into<ItemId>>(&self, id: Id) -> bool {
+ let id = id.into();
self.cannot_derive_default.contains(&id) ||
!self.ctx.whitelisted_items().contains(&id)
}
@@ -288,7 +290,7 @@ impl<'ctx> MonotoneFramework for CannotDeriveDefault<'ctx> {
let bases_cannot_derive =
info.base_members().iter().any(|base| {
- !self.ctx.whitelisted_items().contains(&base.ty) ||
+ !self.ctx.whitelisted_items().contains(&base.ty.into()) ||
self.is_not_default(base.ty)
});
if bases_cannot_derive {
@@ -303,7 +305,7 @@ impl<'ctx> MonotoneFramework for CannotDeriveDefault<'ctx> {
info.fields().iter().any(|f| match *f {
Field::DataMember(ref data) => {
!self.ctx.whitelisted_items().contains(
- &data.ty(),
+ &data.ty().into(),
) ||
self.is_not_default(data.ty())
}
@@ -318,7 +320,7 @@ impl<'ctx> MonotoneFramework for CannotDeriveDefault<'ctx> {
bfu.bitfields().iter().any(|b| {
!self.ctx.whitelisted_items().contains(
- &b.ty(),
+ &b.ty().into(),
) ||
self.is_not_default(b.ty())
})
diff --git a/src/ir/analysis/derive_hash.rs b/src/ir/analysis/derive_hash.rs
index 5313cae3..569c7246 100644
--- a/src/ir/analysis/derive_hash.rs
+++ b/src/ir/analysis/derive_hash.rs
@@ -74,7 +74,8 @@ impl<'ctx> CannotDeriveHash<'ctx> {
}
}
- fn insert(&mut self, id: ItemId) -> ConstrainResult {
+ fn insert<Id: Into<ItemId>>(&mut self, id: Id) -> ConstrainResult {
+ let id = id.into();
trace!("inserting {:?} into the cannot_derive_hash set", id);
let was_not_already_in_set = self.cannot_derive_hash.insert(id);
@@ -178,7 +179,7 @@ impl<'ctx> MonotoneFramework for CannotDeriveHash<'ctx> {
}
TypeKind::Array(t, len) => {
- if self.cannot_derive_hash.contains(&t) {
+ if self.cannot_derive_hash.contains(&t.into()) {
trace!(
" arrays of T for which we cannot derive Hash \
also cannot derive Hash"
@@ -222,7 +223,7 @@ impl<'ctx> MonotoneFramework for CannotDeriveHash<'ctx> {
TypeKind::ResolvedTypeRef(t) |
TypeKind::TemplateAlias(t, _) |
TypeKind::Alias(t) => {
- if self.cannot_derive_hash.contains(&t) {
+ if self.cannot_derive_hash.contains(&t.into()) {
trace!(
" aliases and type refs to T which cannot derive \
Hash also cannot derive Hash"
@@ -263,8 +264,8 @@ impl<'ctx> MonotoneFramework for CannotDeriveHash<'ctx> {
let bases_cannot_derive =
info.base_members().iter().any(|base| {
- !self.ctx.whitelisted_items().contains(&base.ty) ||
- self.cannot_derive_hash.contains(&base.ty)
+ !self.ctx.whitelisted_items().contains(&base.ty.into()) ||
+ self.cannot_derive_hash.contains(&base.ty.into())
});
if bases_cannot_derive {
trace!(
@@ -278,9 +279,9 @@ impl<'ctx> MonotoneFramework for CannotDeriveHash<'ctx> {
info.fields().iter().any(|f| match *f {
Field::DataMember(ref data) => {
!self.ctx.whitelisted_items().contains(
- &data.ty(),
+ &data.ty().into(),
) ||
- self.cannot_derive_hash.contains(&data.ty())
+ self.cannot_derive_hash.contains(&data.ty().into())
}
Field::Bitfields(ref bfu) => {
if bfu.layout().align > RUST_DERIVE_IN_ARRAY_LIMIT {
@@ -293,9 +294,9 @@ impl<'ctx> MonotoneFramework for CannotDeriveHash<'ctx> {
bfu.bitfields().iter().any(|b| {
!self.ctx.whitelisted_items().contains(
- &b.ty(),
+ &b.ty().into(),
) ||
- self.cannot_derive_hash.contains(&b.ty())
+ self.cannot_derive_hash.contains(&b.ty().into())
})
}
});
@@ -311,7 +312,7 @@ impl<'ctx> MonotoneFramework for CannotDeriveHash<'ctx> {
TypeKind::TemplateInstantiation(ref template) => {
let args_cannot_derive =
template.template_arguments().iter().any(|arg| {
- self.cannot_derive_hash.contains(&arg)
+ self.cannot_derive_hash.contains(&arg.into())
});
if args_cannot_derive {
trace!(
@@ -326,7 +327,7 @@ impl<'ctx> MonotoneFramework for CannotDeriveHash<'ctx> {
"The early ty.is_opaque check should have handled this case"
);
let def_cannot_derive = self.cannot_derive_hash.contains(
- &template.template_definition(),
+ &template.template_definition().into(),
);
if def_cannot_derive {
trace!(
diff --git a/src/ir/analysis/derive_partial_eq_or_partial_ord.rs b/src/ir/analysis/derive_partial_eq_or_partial_ord.rs
index f34a256a..7efce6e5 100644
--- a/src/ir/analysis/derive_partial_eq_or_partial_ord.rs
+++ b/src/ir/analysis/derive_partial_eq_or_partial_ord.rs
@@ -83,7 +83,8 @@ impl<'ctx> CannotDerivePartialEqOrPartialOrd<'ctx> {
}
}
- fn insert(&mut self, id: ItemId) -> ConstrainResult {
+ fn insert<Id: Into<ItemId>>(&mut self, id: Id) -> ConstrainResult {
+ let id = id.into();
trace!("inserting {:?} into the cannot_derive_partialeq_or_partialord set", id);
let was_not_already_in_set = self.cannot_derive_partialeq_or_partialord.insert(id);
@@ -190,7 +191,7 @@ impl<'ctx> MonotoneFramework for CannotDerivePartialEqOrPartialOrd<'ctx> {
}
TypeKind::Array(t, len) => {
- if self.cannot_derive_partialeq_or_partialord.contains(&t) {
+ if self.cannot_derive_partialeq_or_partialord.contains(&t.into()) {
trace!(
" arrays of T for which we cannot derive `PartialEq`/`PartialOrd` \
also cannot derive `PartialEq`/`PartialOrd`"
@@ -236,7 +237,7 @@ impl<'ctx> MonotoneFramework for CannotDerivePartialEqOrPartialOrd<'ctx> {
TypeKind::ResolvedTypeRef(t) |
TypeKind::TemplateAlias(t, _) |
TypeKind::Alias(t) => {
- if self.cannot_derive_partialeq_or_partialord.contains(&t) {
+ if self.cannot_derive_partialeq_or_partialord.contains(&t.into()) {
trace!(
" aliases and type refs to T which cannot derive \
`PartialEq`/`PartialOrd` also cannot derive `PartialEq`/`PartialOrd`"
@@ -279,8 +280,8 @@ impl<'ctx> MonotoneFramework for CannotDerivePartialEqOrPartialOrd<'ctx> {
let bases_cannot_derive =
info.base_members().iter().any(|base| {
- !self.ctx.whitelisted_items().contains(&base.ty) ||
- self.cannot_derive_partialeq_or_partialord.contains(&base.ty)
+ !self.ctx.whitelisted_items().contains(&base.ty.into()) ||
+ self.cannot_derive_partialeq_or_partialord.contains(&base.ty.into())
});
if bases_cannot_derive {
trace!(
@@ -294,10 +295,10 @@ impl<'ctx> MonotoneFramework for CannotDerivePartialEqOrPartialOrd<'ctx> {
info.fields().iter().any(|f| match *f {
Field::DataMember(ref data) => {
!self.ctx.whitelisted_items().contains(
- &data.ty(),
+ &data.ty().into(),
) ||
self.cannot_derive_partialeq_or_partialord.contains(
- &data.ty(),
+ &data.ty().into(),
)
}
Field::Bitfields(ref bfu) => {
@@ -311,10 +312,10 @@ impl<'ctx> MonotoneFramework for CannotDerivePartialEqOrPartialOrd<'ctx> {
bfu.bitfields().iter().any(|b| {
!self.ctx.whitelisted_items().contains(
- &b.ty(),
+ &b.ty().into(),
) ||
self.cannot_derive_partialeq_or_partialord.contains(
- &b.ty(),
+ &b.ty().into(),
)
})
}
@@ -333,7 +334,7 @@ impl<'ctx> MonotoneFramework for CannotDerivePartialEqOrPartialOrd<'ctx> {
TypeKind::TemplateInstantiation(ref template) => {
let args_cannot_derive =
template.template_arguments().iter().any(|arg| {
- self.cannot_derive_partialeq_or_partialord.contains(&arg)
+ self.cannot_derive_partialeq_or_partialord.contains(&arg.into())
});
if args_cannot_derive {
trace!(
@@ -348,7 +349,7 @@ impl<'ctx> MonotoneFramework for CannotDerivePartialEqOrPartialOrd<'ctx> {
"The early ty.is_opaque check should have handled this case"
);
let def_cannot_derive = self.cannot_derive_partialeq_or_partialord.contains(
- &template.template_definition(),
+ &template.template_definition().into(),
);
if def_cannot_derive {
trace!(
diff --git a/src/ir/analysis/has_destructor.rs b/src/ir/analysis/has_destructor.rs
index f6400d7d..c87b7e25 100644
--- a/src/ir/analysis/has_destructor.rs
+++ b/src/ir/analysis/has_destructor.rs
@@ -54,7 +54,8 @@ impl<'ctx> HasDestructorAnalysis<'ctx> {
}
}
- fn insert(&mut self, id: ItemId) -> ConstrainResult {
+ fn insert<Id: Into<ItemId>>(&mut self, id: Id) -> ConstrainResult {
+ let id = id.into();
let was_not_already_in_set = self.have_destructor.insert(id);
assert!(
was_not_already_in_set,
@@ -103,7 +104,7 @@ impl<'ctx> MonotoneFramework for HasDestructorAnalysis<'ctx> {
TypeKind::TemplateAlias(t, _) |
TypeKind::Alias(t) |
TypeKind::ResolvedTypeRef(t) => {
- if self.have_destructor.contains(&t) {
+ if self.have_destructor.contains(&t.into()) {
self.insert(id)
} else {
ConstrainResult::Same
@@ -120,12 +121,12 @@ impl<'ctx> MonotoneFramework for HasDestructorAnalysis<'ctx> {
CompKind::Struct => {
let base_or_field_destructor =
info.base_members().iter().any(|base| {
- self.have_destructor.contains(&base.ty)
+ self.have_destructor.contains(&base.ty.into())
}) ||
info.fields().iter().any(|field| {
match *field {
Field::DataMember(ref data) =>
- self.have_destructor.contains(&data.ty()),
+ self.have_destructor.contains(&data.ty().into()),
Field::Bitfields(_) => false
}
});
@@ -140,10 +141,10 @@ impl<'ctx> MonotoneFramework for HasDestructorAnalysis<'ctx> {
TypeKind::TemplateInstantiation(ref inst) => {
let definition_or_arg_destructor =
- self.have_destructor.contains(&inst.template_definition())
+ self.have_destructor.contains(&inst.template_definition().into())
||
inst.template_arguments().iter().any(|arg| {
- self.have_destructor.contains(arg)
+ self.have_destructor.contains(&arg.into())
});
if definition_or_arg_destructor {
self.insert(id)
diff --git a/src/ir/analysis/has_float.rs b/src/ir/analysis/has_float.rs
index 959a411b..193862c0 100644
--- a/src/ir/analysis/has_float.rs
+++ b/src/ir/analysis/has_float.rs
@@ -62,7 +62,8 @@ impl<'ctx> HasFloat<'ctx> {
}
}
- fn insert(&mut self, id: ItemId) -> ConstrainResult {
+ fn insert<Id: Into<ItemId>>(&mut self, id: Id) -> ConstrainResult {
+ let id = id.into();
trace!("inserting {:?} into the has_float set", id);
let was_not_already_in_set = self.has_float.insert(id);
@@ -140,7 +141,7 @@ impl<'ctx> MonotoneFramework for HasFloat<'ctx> {
}
TypeKind::Array(t, _) => {
- if self.has_float.contains(&t) {
+ if self.has_float.contains(&t.into()) {
trace!(" Array with type T that has float also has float");
return self.insert(id)
}
@@ -151,7 +152,7 @@ impl<'ctx> MonotoneFramework for HasFloat<'ctx> {
TypeKind::ResolvedTypeRef(t) |
TypeKind::TemplateAlias(t, _) |
TypeKind::Alias(t) => {
- if self.has_float.contains(&t) {
+ if self.has_float.contains(&t.into()) {
trace!(" aliases and type refs to T which have float \
also have float");
self.insert(id)
@@ -165,7 +166,7 @@ impl<'ctx> MonotoneFramework for HasFloat<'ctx> {
TypeKind::Comp(ref info) => {
let bases_have = info.base_members()
.iter()
- .any(|base| self.has_float.contains(&base.ty));
+ .any(|base| self.has_float.contains(&base.ty.into()));
if bases_have {
trace!(" bases have float, so we also have");
return self.insert(id);
@@ -175,12 +176,12 @@ impl<'ctx> MonotoneFramework for HasFloat<'ctx> {
.any(|f| {
match *f {
Field::DataMember(ref data) => {
- self.has_float.contains(&data.ty())
+ self.has_float.contains(&data.ty().into())
}
Field::Bitfields(ref bfu) => {
bfu.bitfields()
.iter().any(|b| {
- self.has_float.contains(&b.ty())
+ self.has_float.contains(&b.ty().into())
})
},
}
@@ -197,7 +198,7 @@ impl<'ctx> MonotoneFramework for HasFloat<'ctx> {
TypeKind::TemplateInstantiation(ref template) => {
let args_have = template.template_arguments()
.iter()
- .any(|arg| self.has_float.contains(&arg));
+ .any(|arg| self.has_float.contains(&arg.into()));
if args_have {
trace!(" template args have float, so \
insantiation also has float");
@@ -205,7 +206,7 @@ impl<'ctx> MonotoneFramework for HasFloat<'ctx> {
}
let def_has = self.has_float
- .contains(&template.template_definition());
+ .contains(&template.template_definition().into());
if def_has {
trace!(" template definition has float, so \
insantiation also has");
diff --git a/src/ir/analysis/has_type_param_in_array.rs b/src/ir/analysis/has_type_param_in_array.rs
index f21bae14..aa8d34be 100644
--- a/src/ir/analysis/has_type_param_in_array.rs
+++ b/src/ir/analysis/has_type_param_in_array.rs
@@ -64,7 +64,8 @@ impl<'ctx> HasTypeParameterInArray<'ctx> {
}
}
- fn insert(&mut self, id: ItemId) -> ConstrainResult {
+ fn insert<Id: Into<ItemId>>(&mut self, id: Id) -> ConstrainResult {
+ let id = id.into();
trace!(
"inserting {:?} into the has_type_parameter_in_array set",
id
@@ -165,7 +166,7 @@ impl<'ctx> MonotoneFramework for HasTypeParameterInArray<'ctx> {
TypeKind::ResolvedTypeRef(t) |
TypeKind::TemplateAlias(t, _) |
TypeKind::Alias(t) => {
- if self.has_type_parameter_in_array.contains(&t) {
+ if self.has_type_parameter_in_array.contains(&t.into()) {
trace!(
" aliases and type refs to T which have array \
also have array"
@@ -182,7 +183,7 @@ impl<'ctx> MonotoneFramework for HasTypeParameterInArray<'ctx> {
TypeKind::Comp(ref info) => {
let bases_have = info.base_members().iter().any(|base| {
- self.has_type_parameter_in_array.contains(&base.ty)
+ self.has_type_parameter_in_array.contains(&base.ty.into())
});
if bases_have {
trace!(" bases have array, so we also have");
@@ -190,7 +191,7 @@ impl<'ctx> MonotoneFramework for HasTypeParameterInArray<'ctx> {
}
let fields_have = info.fields().iter().any(|f| match *f {
Field::DataMember(ref data) => {
- self.has_type_parameter_in_array.contains(&data.ty())
+ self.has_type_parameter_in_array.contains(&data.ty().into())
}
Field::Bitfields(..) => false,
});
@@ -206,7 +207,7 @@ impl<'ctx> MonotoneFramework for HasTypeParameterInArray<'ctx> {
TypeKind::TemplateInstantiation(ref template) => {
let args_have =
template.template_arguments().iter().any(|arg| {
- self.has_type_parameter_in_array.contains(&arg)
+ self.has_type_parameter_in_array.contains(&arg.into())
});
if args_have {
trace!(
@@ -217,7 +218,7 @@ impl<'ctx> MonotoneFramework for HasTypeParameterInArray<'ctx> {
}
let def_has = self.has_type_parameter_in_array.contains(
- &template.template_definition(),
+ &template.template_definition().into(),
);
if def_has {
trace!(
diff --git a/src/ir/analysis/has_vtable.rs b/src/ir/analysis/has_vtable.rs
index b0d48738..92d6a38f 100644
--- a/src/ir/analysis/has_vtable.rs
+++ b/src/ir/analysis/has_vtable.rs
@@ -47,7 +47,8 @@ impl<'ctx> HasVtableAnalysis<'ctx> {
}
}
- fn insert(&mut self, id: ItemId) -> ConstrainResult {
+ fn insert<Id: Into<ItemId>>(&mut self, id: Id) -> ConstrainResult {
+ let id = id.into();
let was_not_already_in_set = self.have_vtable.insert(id);
assert!(
was_not_already_in_set,
@@ -98,7 +99,7 @@ impl<'ctx> MonotoneFramework for HasVtableAnalysis<'ctx> {
TypeKind::Alias(t) |
TypeKind::ResolvedTypeRef(t) |
TypeKind::Reference(t) => {
- if self.have_vtable.contains(&t) {
+ if self.have_vtable.contains(&t.into()) {
self.insert(id)
} else {
ConstrainResult::Same
@@ -110,7 +111,7 @@ impl<'ctx> MonotoneFramework for HasVtableAnalysis<'ctx> {
return self.insert(id);
}
let bases_has_vtable = info.base_members().iter().any(|base| {
- self.have_vtable.contains(&base.ty)
+ self.have_vtable.contains(&base.ty.into())
});
if bases_has_vtable {
self.insert(id)
@@ -120,7 +121,7 @@ impl<'ctx> MonotoneFramework for HasVtableAnalysis<'ctx> {
}
TypeKind::TemplateInstantiation(ref inst) => {
- if self.have_vtable.contains(&inst.template_definition()) {
+ if self.have_vtable.contains(&inst.template_definition().into()) {
self.insert(id)
} else {
ConstrainResult::Same
diff --git a/src/ir/analysis/template_params.rs b/src/ir/analysis/template_params.rs
index 7699a0c2..00504aa4 100644
--- a/src/ir/analysis/template_params.rs
+++ b/src/ir/analysis/template_params.rs
@@ -203,7 +203,8 @@ impl<'ctx> UsedTemplateParameters<'ctx> {
}
}
- fn take_this_id_usage_set(&mut self, this_id: ItemId) -> ItemSet {
+ fn take_this_id_usage_set<Id: Into<ItemId>>(&mut self, this_id: Id) -> ItemSet {
+ let this_id = this_id.into();
self.used
.get_mut(&this_id)
.expect(
@@ -278,7 +279,7 @@ impl<'ctx> UsedTemplateParameters<'ctx> {
debug_assert!(this_id != instantiation.template_definition());
let used_by_def = self.used
- .get(&instantiation.template_definition())
+ .get(&instantiation.template_definition().into())
.expect("Should have a used entry for instantiation's template definition")
.as_ref()
.expect("And it should be Some because only this_id's set is None, and an \
@@ -293,7 +294,7 @@ impl<'ctx> UsedTemplateParameters<'ctx> {
param
);
- if used_by_def.contains(param) {
+ if used_by_def.contains(&param.into()) {
trace!(" param is used by template definition");
let arg = arg.into_resolver()
@@ -520,7 +521,7 @@ impl<'ctx> MonotoneFramework for UsedTemplateParameters<'ctx> {
// template definition uses the corresponding template parameter.
Some(&TypeKind::TemplateInstantiation(ref inst)) => {
if self.whitelisted_items.contains(
- &inst.template_definition(),
+ &inst.template_definition().into(),
)
{
self.constrain_instantiation(
diff --git a/src/ir/comp.rs b/src/ir/comp.rs
index e1b2a1f0..c1dd369b 100644
--- a/src/ir/comp.rs
+++ b/src/ir/comp.rs
@@ -1,7 +1,8 @@
//! Compound types (unions and structs) in our intermediate representation.
+use super::analysis::HasVtable;
use super::annotations::Annotations;
-use super::context::{BindgenContext, ItemId};
+use super::context::{BindgenContext, FunctionId, ItemId, TypeId, VarId};
use super::dot::DotAttributes;
use super::item::{IsOpaque, Item};
use super::layout::Layout;
@@ -52,13 +53,13 @@ pub struct Method {
/// item, but a `Function` one.
///
/// This is tricky and probably this field should be renamed.
- signature: ItemId,
+ signature: FunctionId,
is_const: bool,
}
impl Method {
/// Construct a new `Method`.
- pub fn new(kind: MethodKind, signature: ItemId, is_const: bool) -> Self {
+ pub fn new(kind: MethodKind, signature: FunctionId, is_const: bool) -> Self {
Method {
kind: kind,
signature: signature,
@@ -93,8 +94,8 @@ impl Method {
self.kind == MethodKind::Static
}
- /// Get the `ItemId` for the `Function` signature for this method.
- pub fn signature(&self) -> ItemId {
+ /// Get the id for the `Function` signature for this method.
+ pub fn signature(&self) -> FunctionId {
self.signature
}
@@ -110,7 +111,7 @@ pub trait FieldMethods {
fn name(&self) -> Option<&str>;
/// Get the type of this field.
- fn ty(&self) -> ItemId;
+ fn ty(&self) -> TypeId;
/// Get the comment for this field.
fn comment(&self) -> Option<&str>;
@@ -191,13 +192,13 @@ impl Trace for Field {
{
match *self {
Field::DataMember(ref data) => {
- tracer.visit_kind(data.ty, EdgeKind::Field);
+ tracer.visit_kind(data.ty.into(), EdgeKind::Field);
}
Field::Bitfields(BitfieldUnit {
ref bitfields, ..
}) => {
for bf in bitfields {
- tracer.visit_kind(bf.ty(), EdgeKind::Field);
+ tracer.visit_kind(bf.ty().into(), EdgeKind::Field);
}
}
}
@@ -343,7 +344,7 @@ impl FieldMethods for Bitfield {
self.data.name()
}
- fn ty(&self) -> ItemId {
+ fn ty(&self) -> TypeId {
self.data.ty()
}
@@ -380,7 +381,7 @@ impl RawField {
/// Construct a new `RawField`.
fn new(
name: Option<String>,
- ty: ItemId,
+ ty: TypeId,
comment: Option<String>,
annotations: Option<Annotations>,
bitfield: Option<u32>,
@@ -404,7 +405,7 @@ impl FieldMethods for RawField {
self.0.name()
}
- fn ty(&self) -> ItemId {
+ fn ty(&self) -> TypeId {
self.0.ty()
}
@@ -705,7 +706,7 @@ impl Trace for CompFields {
match *self {
CompFields::BeforeComputingBitfieldUnits(ref fields) => {
for f in fields {
- tracer.visit_kind(f.ty(), EdgeKind::Field);
+ tracer.visit_kind(f.ty().into(), EdgeKind::Field);
}
}
CompFields::AfterComputingBitfieldUnits(ref fields) => {
@@ -724,7 +725,7 @@ pub struct FieldData {
name: Option<String>,
/// The inner type.
- ty: ItemId,
+ ty: TypeId,
/// The doc comment on the field if any.
comment: Option<String>,
@@ -747,7 +748,7 @@ impl FieldMethods for FieldData {
self.name.as_ref().map(|n| &**n)
}
- fn ty(&self) -> ItemId {
+ fn ty(&self) -> TypeId {
self.ty
}
@@ -793,7 +794,7 @@ pub enum BaseKind {
#[derive(Clone, Debug)]
pub struct Base {
/// The type of this base class.
- pub ty: ItemId,
+ pub ty: TypeId,
/// The kind of inheritance we're doing.
pub kind: BaseKind,
/// Name of the field in which this base should be stored.
@@ -824,17 +825,17 @@ pub struct CompInfo {
/// concrete template arguments, and should always be a
/// `Type(TypeKind::TypeParam(name))`. For concrete template arguments, see
/// `TypeKind::TemplateInstantiation`.
- template_params: Vec<ItemId>,
+ template_params: Vec<TypeId>,
/// The method declarations inside this class, if in C++ mode.
methods: Vec<Method>,
/// The different constructors this struct or class contains.
- constructors: Vec<ItemId>,
+ constructors: Vec<FunctionId>,
/// The destructor of this type. The bool represents whether this destructor
/// is virtual.
- destructor: Option<(bool, ItemId)>,
+ destructor: Option<(bool, FunctionId)>,
/// Vector of classes this one inherits from.
base_members: Vec<Base>,
@@ -849,10 +850,10 @@ pub struct CompInfo {
/// }
///
/// static Foo::Bar const = {3};
- inner_types: Vec<ItemId>,
+ inner_types: Vec<TypeId>,
/// Set of static constants declared inside this class.
- inner_vars: Vec<ItemId>,
+ inner_vars: Vec<VarId>,
/// Whether this type should generate an vtable (TODO: Should be able to
/// look at the virtual methods and ditch this field).
@@ -910,12 +911,12 @@ impl CompInfo {
}
/// Is this compound type unsized?
- pub fn is_unsized(&self, ctx: &BindgenContext, itemid: &ItemId) -> bool {
- !ctx.lookup_item_id_has_vtable(itemid) && self.fields().is_empty() &&
+ pub fn is_unsized(&self, ctx: &BindgenContext, id: TypeId) -> bool {
+ !ctx.lookup_has_vtable(id) && self.fields().is_empty() &&
self.base_members.iter().all(|base| {
ctx.resolve_type(base.ty).canonical_type(ctx).is_unsized(
ctx,
- &base.ty,
+ base.ty,
)
})
}
@@ -983,12 +984,12 @@ impl CompInfo {
}
/// Get this type's set of constructors.
- pub fn constructors(&self) -> &[ItemId] {
+ pub fn constructors(&self) -> &[FunctionId] {
&self.constructors
}
/// Get this type's destructor.
- pub fn destructor(&self) -> Option<(bool, ItemId)> {
+ pub fn destructor(&self) -> Option<(bool, FunctionId)> {
self.destructor
}
@@ -1104,12 +1105,12 @@ impl CompInfo {
let name = if name.is_empty() { None } else { Some(name) };
let field = RawField::new(name,
- field_type,
- comment,
- annotations,
- bit_width,
- is_mutable,
- offset);
+ field_type,
+ comment,
+ annotations,
+ bit_width,
+ is_mutable,
+ offset);
ci.fields.append_raw_field(field);
// No we look for things like attributes and stuff.
@@ -1154,6 +1155,8 @@ impl CompInfo {
.expect("Inner ClassDecl");
assert_eq!(ctx.resolve_item(inner).parent_id(), potential_id);
+ let inner = inner.expect_type_id(ctx);
+
ci.inner_types.push(inner);
// A declaration of an union or a struct without name could
@@ -1162,8 +1165,7 @@ impl CompInfo {
cur.kind() != CXCursor_EnumDecl {
let ty = cur.cur_type();
let offset = cur.offset_of_field().ok();
- maybe_anonymous_struct_field =
- Some((inner, ty, offset));
+ maybe_anonymous_struct_field = Some((inner, ty, offset));
}
}
CXCursor_PackedAttr => {
@@ -1231,6 +1233,8 @@ impl CompInfo {
_ => return CXChildVisit_Continue,
};
+ let signature = signature.expect_function_id(ctx);
+
match cur.kind() {
CXCursor_Constructor => {
ci.constructors.push(signature);
@@ -1274,7 +1278,7 @@ impl CompInfo {
if let Ok(item) = Item::parse(cur,
Some(potential_id),
ctx) {
- ci.inner_vars.push(item);
+ ci.inner_vars.push(item.as_var_id_unchecked());
}
}
// Intentionally not handled
@@ -1327,12 +1331,12 @@ impl CompInfo {
/// Get the set of types that were declared within this compound type
/// (e.g. nested class definitions).
- pub fn inner_types(&self) -> &[ItemId] {
+ pub fn inner_types(&self) -> &[TypeId] {
&self.inner_types
}
/// Get the set of static variables declared within this compound type.
- pub fn inner_vars(&self) -> &[ItemId] {
+ pub fn inner_vars(&self) -> &[VarId] {
&self.inner_vars
}
@@ -1354,8 +1358,7 @@ impl CompInfo {
ctx: &BindgenContext,
item: &Item,
) -> bool {
- ctx.lookup_item_id_has_vtable(&item.id()) &&
- !self.base_members.iter().any(|base| {
+ item.has_vtable(ctx) && !self.base_members.iter().any(|base| {
// NB: Ideally, we could rely in all these types being `comp`, and
// life would be beautiful.
//
@@ -1365,7 +1368,7 @@ impl CompInfo {
ctx.resolve_type(base.ty)
.canonical_type(ctx)
.as_comp()
- .map_or(false, |_| ctx.lookup_item_id_has_vtable(&base.ty))
+ .map_or(false, |_| base.ty.has_vtable(ctx))
})
}
@@ -1465,7 +1468,7 @@ impl TemplateParameters for CompInfo {
fn self_template_params(
&self,
_ctx: &BindgenContext,
- ) -> Option<Vec<ItemId>> {
+ ) -> Option<Vec<TypeId>> {
if self.template_params.is_empty() {
None
} else {
@@ -1483,27 +1486,27 @@ impl Trace for CompInfo {
{
let params = item.all_template_params(context).unwrap_or(vec![]);
for p in params {
- tracer.visit_kind(p, EdgeKind::TemplateParameterDefinition);
+ tracer.visit_kind(p.into(), EdgeKind::TemplateParameterDefinition);
}
- for &ty in self.inner_types() {
- tracer.visit_kind(ty, EdgeKind::InnerType);
+ for ty in self.inner_types() {
+ tracer.visit_kind(ty.into(), EdgeKind::InnerType);
}
for &var in self.inner_vars() {
- tracer.visit_kind(var, EdgeKind::InnerVar);
+ tracer.visit_kind(var.into(), EdgeKind::InnerVar);
}
for method in self.methods() {
if method.is_destructor() {
- tracer.visit_kind(method.signature, EdgeKind::Destructor);
+ tracer.visit_kind(method.signature.into(), EdgeKind::Destructor);
} else {
- tracer.visit_kind(method.signature, EdgeKind::Method);
+ tracer.visit_kind(method.signature.into(), EdgeKind::Method);
}
}
- for &ctor in self.constructors() {
- tracer.visit_kind(ctor, EdgeKind::Constructor);
+ for ctor in self.constructors() {
+ tracer.visit_kind(ctor.into(), EdgeKind::Constructor);
}
// Base members and fields are not generated for opaque types (but all
@@ -1513,7 +1516,7 @@ impl Trace for CompInfo {
}
for base in self.base_members() {
- tracer.visit_kind(base.ty, EdgeKind::BaseMember);
+ tracer.visit_kind(base.ty.into(), EdgeKind::BaseMember);
}
self.fields.trace(context, tracer, &());
diff --git a/src/ir/context.rs b/src/ir/context.rs
index 5b6b46ef..37b71ba1 100644
--- a/src/ir/context.rs
+++ b/src/ir/context.rs
@@ -9,8 +9,7 @@ use super::derive::{CanDeriveCopy, CanDeriveDebug, CanDeriveDefault,
CanDeriveHash, CanDerivePartialOrd, CanDeriveOrd,
CanDerivePartialEq, CanDeriveEq};
use super::int::IntKind;
-use super::item::{HasTypeParamInArray, IsOpaque, Item, ItemAncestors,
- ItemCanonicalPath, ItemSet};
+use super::item::{IsOpaque, Item, ItemAncestors, ItemCanonicalPath, ItemSet};
use super::item_kind::ItemKind;
use super::module::{Module, ModuleKind};
use super::template::{TemplateInstantiation, TemplateParameters};
@@ -31,71 +30,258 @@ use std::collections::btree_map::{self, BTreeMap};
use std::iter::IntoIterator;
use std::mem;
-/// 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)]
+/// An identifier for some kind of IR item.
+#[derive(Debug, Copy, Clone, Eq, PartialOrd, Ord, Hash)]
pub struct ItemId(usize);
+macro_rules! item_id_newtype {
+ (
+ $( #[$attr:meta] )*
+ pub struct $name:ident(ItemId)
+ where
+ $( #[$checked_attr:meta] )*
+ checked = $checked:ident with $check_method:ident,
+ $( #[$expected_attr:meta] )*
+ expected = $expected:ident,
+ $( #[$unchecked_attr:meta] )*
+ unchecked = $unchecked:ident;
+ ) => {
+ $( #[$attr] )*
+ #[derive(Debug, Copy, Clone, Eq, PartialOrd, Ord, Hash)]
+ pub struct $name(ItemId);
+
+ impl $name {
+ /// Create an `ItemResolver` from this id.
+ pub fn into_resolver(self) -> ItemResolver {
+ let id: ItemId = self.into();
+ id.into()
+ }
+ }
+
+ impl<T> ::std::cmp::PartialEq<T> for $name
+ where
+ T: Copy + Into<ItemId>
+ {
+ fn eq(&self, rhs: &T) -> bool {
+ let rhs: ItemId = (*rhs).into();
+ self.0 == rhs
+ }
+ }
+
+ impl From<$name> for ItemId {
+ fn from(id: $name) -> ItemId {
+ id.0
+ }
+ }
+
+ impl<'a> From<&'a $name> for ItemId {
+ fn from(id: &'a $name) -> ItemId {
+ id.0
+ }
+ }
+
+ impl ItemId {
+ $( #[$checked_attr] )*
+ pub fn $checked(&self, ctx: &BindgenContext) -> Option<$name> {
+ if ctx.resolve_item(*self).kind().$check_method() {
+ Some($name(*self))
+ } else {
+ None
+ }
+ }
+
+ $( #[$expected_attr] )*
+ pub fn $expected(&self, ctx: &BindgenContext) -> $name {
+ self.$checked(ctx)
+ .expect(concat!(
+ stringify!($expected),
+ " called with ItemId that points to the wrong ItemKind"
+ ))
+ }
+
+ $( #[$unchecked_attr] )*
+ pub fn $unchecked(&self) -> $name {
+ $name(*self)
+ }
+ }
+ }
+}
+
+item_id_newtype! {
+ /// An identifier for an `Item` whose `ItemKind` is known to be
+ /// `ItemKind::Type`.
+ pub struct TypeId(ItemId)
+ where
+ /// Convert this `ItemId` into a `TypeId` if its associated item is a type,
+ /// otherwise return `None`.
+ checked = as_type_id with is_type,
+
+ /// Convert this `ItemId` into a `TypeId`.
+ ///
+ /// If this `ItemId` does not point to a type, then panic.
+ expected = expect_type_id,
+
+ /// Convert this `ItemId` into a `TypeId` without actually checking whether
+ /// this id actually points to a `Type`.
+ unchecked = as_type_id_unchecked;
+}
+
+item_id_newtype! {
+ /// An identifier for an `Item` whose `ItemKind` is known to be
+ /// `ItemKind::Module`.
+ pub struct ModuleId(ItemId)
+ where
+ /// Convert this `ItemId` into a `ModuleId` if its associated item is a
+ /// module, otherwise return `None`.
+ checked = as_module_id with is_module,
+
+ /// Convert this `ItemId` into a `ModuleId`.
+ ///
+ /// If this `ItemId` does not point to a module, then panic.
+ expected = expect_module_id,
+
+ /// Convert this `ItemId` into a `ModuleId` without actually checking
+ /// whether this id actually points to a `Module`.
+ unchecked = as_module_id_unchecked;
+}
+
+item_id_newtype! {
+ /// An identifier for an `Item` whose `ItemKind` is known to be
+ /// `ItemKind::Var`.
+ pub struct VarId(ItemId)
+ where
+ /// Convert this `ItemId` into a `VarId` if its associated item is a var,
+ /// otherwise return `None`.
+ checked = as_var_id with is_var,
+
+ /// Convert this `ItemId` into a `VarId`.
+ ///
+ /// If this `ItemId` does not point to a var, then panic.
+ expected = expect_var_id,
+
+ /// Convert this `ItemId` into a `VarId` without actually checking whether
+ /// this id actually points to a `Var`.
+ unchecked = as_var_id_unchecked;
+}
+
+item_id_newtype! {
+ /// An identifier for an `Item` whose `ItemKind` is known to be
+ /// `ItemKind::Function`.
+ pub struct FunctionId(ItemId)
+ where
+ /// Convert this `ItemId` into a `FunctionId` if its associated item is a function,
+ /// otherwise return `None`.
+ checked = as_function_id with is_function,
+
+ /// Convert this `ItemId` into a `FunctionId`.
+ ///
+ /// If this `ItemId` does not point to a function, then panic.
+ expected = expect_function_id,
+
+ /// Convert this `ItemId` into a `FunctionId` without actually checking whether
+ /// this id actually points to a `Function`.
+ unchecked = as_function_id_unchecked;
+}
+
+impl From<ItemId> for usize {
+ fn from(id: ItemId) -> usize {
+ id.0
+ }
+}
+
impl ItemId {
/// Get a numeric representation of this id.
pub fn as_usize(&self) -> usize {
- self.0
+ (*self).into()
+ }
+}
+
+impl<T> ::std::cmp::PartialEq<T> for ItemId
+where
+ T: Copy + Into<ItemId>
+{
+ fn eq(&self, rhs: &T) -> bool {
+ let rhs: ItemId = (*rhs).into();
+ self.0 == rhs.0
}
}
-impl CanDeriveDebug for ItemId {
+impl<T> CanDeriveDebug for T
+where
+ T: Copy + Into<ItemId>
+{
fn can_derive_debug(&self, ctx: &BindgenContext) -> bool {
- ctx.options().derive_debug && ctx.lookup_item_id_can_derive_debug(*self)
+ ctx.options().derive_debug && ctx.lookup_can_derive_debug(*self)
}
}
-impl CanDeriveDefault for ItemId {
+impl<T> CanDeriveDefault for T
+where
+ T: Copy + Into<ItemId>
+{
fn can_derive_default(&self, ctx: &BindgenContext) -> bool {
ctx.options().derive_default &&
- ctx.lookup_item_id_can_derive_default(*self)
+ ctx.lookup_can_derive_default(*self)
}
}
-impl<'a> CanDeriveCopy<'a> for ItemId {
+impl<'a, T> CanDeriveCopy<'a> for T
+where
+ T: Copy + Into<ItemId>
+{
fn can_derive_copy(&self, ctx: &BindgenContext) -> bool {
- ctx.lookup_item_id_can_derive_copy(*self)
+ ctx.lookup_can_derive_copy(*self)
}
}
-impl CanDeriveHash for ItemId {
+impl<T> CanDeriveHash for T
+where
+ T: Copy + Into<ItemId>
+{
fn can_derive_hash(&self, ctx: &BindgenContext) -> bool {
- ctx.options().derive_hash && ctx.lookup_item_id_can_derive_hash(*self)
+ ctx.options().derive_hash && ctx.lookup_can_derive_hash(*self)
}
}
-impl CanDerivePartialOrd for ItemId {
+impl<T> CanDerivePartialOrd for T
+where
+ T: Copy + Into<ItemId>
+{
fn can_derive_partialord(&self, ctx: &BindgenContext) -> bool {
ctx.options().derive_partialord &&
- ctx.lookup_item_id_can_derive_partialeq_or_partialord(*self)
+ ctx.lookup_can_derive_partialeq_or_partialord(*self)
}
}
-impl CanDerivePartialEq for ItemId {
+impl<T> CanDerivePartialEq for T
+where
+ T: Copy + Into<ItemId>
+{
fn can_derive_partialeq(&self, ctx: &BindgenContext) -> bool {
ctx.options().derive_partialeq &&
- ctx.lookup_item_id_can_derive_partialeq_or_partialord(*self)
+ ctx.lookup_can_derive_partialeq_or_partialord(*self)
}
}
-impl CanDeriveEq for ItemId {
+impl<T> CanDeriveEq for T
+where
+ T: Copy + Into<ItemId>
+{
fn can_derive_eq(&self, ctx: &BindgenContext) -> bool {
ctx.options().derive_eq &&
- ctx.lookup_item_id_can_derive_partialeq_or_partialord(*self) &&
- !ctx.lookup_item_id_has_float(&self)
+ ctx.lookup_can_derive_partialeq_or_partialord(*self) &&
+ !ctx.lookup_has_float(*self)
}
}
-impl CanDeriveOrd for ItemId {
+impl<T> CanDeriveOrd for T
+where
+ T: Copy + Into<ItemId>
+{
fn can_derive_ord(&self, ctx: &BindgenContext) -> bool {
ctx.options().derive_ord &&
- ctx.lookup_item_id_can_derive_partialeq_or_partialord(*self) &&
- !ctx.lookup_item_id_has_float(&self)
+ ctx.lookup_can_derive_partialeq_or_partialord(*self) &&
+ !ctx.lookup_has_float(*self)
}
}
@@ -125,20 +311,20 @@ pub struct BindgenContext {
/// Clang USR to type map. This is needed to be able to associate types with
/// item ids during parsing.
- types: HashMap<TypeKey, ItemId>,
+ types: HashMap<TypeKey, TypeId>,
/// Maps from a cursor to the item id of the named template type parameter
/// for that cursor.
- type_params: HashMap<clang::Cursor, ItemId>,
+ 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.
@@ -381,14 +567,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(),
@@ -537,7 +725,7 @@ impl BindgenContext {
TypeKey::Declaration(declaration)
};
- let old = self.types.insert(key, id);
+ let old = self.types.insert(key, id.as_type_id_unchecked());
debug_assert_eq!(old, None);
}
}
@@ -570,7 +758,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")
@@ -604,7 +792,7 @@ impl BindgenContext {
"should not have already associated an item with the given id"
);
- let old_named_ty = self.type_params.insert(definition, id);
+ let old_named_ty = self.type_params.insert(definition, id.as_type_id_unchecked());
assert!(
old_named_ty.is_none(),
"should not have already associated a named type with this id"
@@ -613,7 +801,7 @@ impl BindgenContext {
/// Get the named type defined at the given cursor location, if we've
/// already added one.
- pub fn get_type_param(&self, definition: &clang::Cursor) -> Option<ItemId> {
+ pub fn get_type_param(&self, definition: &clang::Cursor) -> Option<TypeId> {
assert_eq!(
definition.kind(),
clang_sys::CXCursor_TemplateTypeParameter
@@ -762,7 +950,6 @@ impl BindgenContext {
let item = self.items.get_mut(&id).unwrap();
*item.kind_mut().as_type_mut().unwrap().kind_mut() =
TypeKind::ResolvedTypeRef(resolved);
-
resolved
};
@@ -859,19 +1046,19 @@ impl BindgenContext {
// We set this just after parsing the annotation. It's
// very unlikely, but this can happen.
if self.items.get(replacement).is_some() {
- replacements.push((*id, *replacement));
+ replacements.push((id.expect_type_id(self), replacement.expect_type_id(self)));
}
}
}
}
- for (id, replacement) in replacements {
- debug!("Replacing {:?} with {:?}", id, replacement);
+ for (id, replacement_id) in replacements {
+ debug!("Replacing {:?} with {:?}", id, replacement_id);
let new_parent = {
- let item = self.items.get_mut(&id).unwrap();
+ let item = self.items.get_mut(&id.into()).unwrap();
*item.kind_mut().as_type_mut().unwrap().kind_mut() =
- TypeKind::ResolvedTypeRef(replacement);
+ TypeKind::ResolvedTypeRef(replacement_id);
item.parent_id()
};
@@ -880,7 +1067,7 @@ impl BindgenContext {
//
// First, we'll make sure that its parent id is correct.
- let old_parent = self.resolve_item(replacement).parent_id();
+ let old_parent = self.resolve_item(replacement_id).parent_id();
if new_parent == old_parent {
// Same parent and therefore also same containing
// module. Nothing to do here.
@@ -888,7 +1075,7 @@ impl BindgenContext {
}
self.items
- .get_mut(&replacement)
+ .get_mut(&replacement_id.into())
.unwrap()
.set_parent_for_replacement(new_parent);
@@ -899,11 +1086,11 @@ 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| {
- m.children().contains(&replacement)
+ m.children().contains(&replacement_id.into())
})
})
};
@@ -917,7 +1104,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.
@@ -930,7 +1117,7 @@ impl BindgenContext {
.as_module_mut()
.unwrap()
.children_mut()
- .remove(&replacement);
+ .remove(&replacement_id.into());
self.items
.get_mut(&new_module)
@@ -938,7 +1125,7 @@ impl BindgenContext {
.as_module_mut()
.unwrap()
.children_mut()
- .insert(replacement);
+ .insert(replacement_id.into());
}
}
@@ -1035,7 +1222,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 {:?}",
@@ -1066,7 +1253,7 @@ impl BindgenContext {
}
/// Look up whether the item with `id` has vtable or not.
- pub fn lookup_item_id_has_vtable(&self, id: &ItemId) -> bool {
+ pub fn lookup_has_vtable(&self, id: TypeId) -> bool {
assert!(
self.in_codegen_phase(),
"We only compute vtables when we enter codegen"
@@ -1074,7 +1261,7 @@ impl BindgenContext {
// Look up the computed value for whether the item with `id` has a
// vtable or not.
- self.have_vtable.as_ref().unwrap().contains(id)
+ self.have_vtable.as_ref().unwrap().contains(&id.into())
}
/// Compute whether the type has a destructor.
@@ -1085,13 +1272,13 @@ impl BindgenContext {
}
/// Look up whether the item with `id` has a destructor.
- pub fn lookup_item_id_has_destructor(&self, id: &ItemId) -> bool {
+ pub fn lookup_has_destructor(&self, id: TypeId) -> bool {
assert!(
self.in_codegen_phase(),
"We only compute destructors when we enter codegen"
);
- self.have_destructor.as_ref().unwrap().contains(id)
+ self.have_destructor.as_ref().unwrap().contains(&id.into())
}
fn find_used_template_parameters(&mut self) {
@@ -1107,7 +1294,7 @@ impl BindgenContext {
used_params.entry(id).or_insert(
id.self_template_params(self).map_or(
Default::default(),
- |params| params.into_iter().collect(),
+ |params| params.into_iter().map(|p| p.into()).collect(),
),
);
}
@@ -1132,7 +1319,7 @@ impl BindgenContext {
pub fn uses_template_parameter(
&self,
item: ItemId,
- template_param: ItemId,
+ template_param: TypeId,
) -> bool {
assert!(
self.in_codegen_phase(),
@@ -1204,7 +1391,7 @@ impl BindgenContext {
}
/// Get the root module.
- pub fn root_module(&self) -> ItemId {
+ pub fn root_module(&self) -> ModuleId {
self.root_module
}
@@ -1212,28 +1399,29 @@ impl BindgenContext {
///
/// Panics if there is no item for the given `ItemId` or if the resolved
/// item is not a `Type`.
- pub fn resolve_type(&self, type_id: ItemId) -> &Type {
- self.items.get(&type_id).unwrap().kind().expect_type()
+ pub fn resolve_type(&self, type_id: TypeId) -> &Type {
+ self.items.get(&type_id.into()).unwrap().kind().expect_type()
}
/// Resolve the given `ItemId` as a type, or `None` if there is no item with
/// the given id.
///
/// Panics if the id resolves to an item that is not a type.
- pub fn safe_resolve_type(&self, type_id: ItemId) -> Option<&Type> {
- self.items.get(&type_id).map(|t| t.kind().expect_type())
+ pub fn safe_resolve_type(&self, type_id: TypeId) -> Option<&Type> {
+ self.items.get(&type_id.into()).map(|t| t.kind().expect_type())
}
/// Resolve the given `ItemId` into an `Item`, or `None` if no such item
/// exists.
- pub fn resolve_item_fallible(&self, item_id: ItemId) -> Option<&Item> {
- self.items.get(&item_id)
+ pub fn resolve_item_fallible<Id: Into<ItemId>>(&self, id: Id) -> Option<&Item> {
+ self.items.get(&id.into())
}
/// Resolve the given `ItemId` into an `Item`.
///
/// Panics if the given id does not resolve to any item.
- pub fn resolve_item(&self, item_id: ItemId) -> &Item {
+ pub fn resolve_item<Id: Into<ItemId>>(&self, item_id: Id) -> &Item {
+ let item_id = item_id.into();
match self.items.get(&item_id) {
Some(item) => item,
None => panic!("Not an item: {:?}", item_id),
@@ -1241,7 +1429,7 @@ impl BindgenContext {
}
/// Get the current module.
- pub fn current_module(&self) -> ItemId {
+ pub fn current_module(&self) -> ModuleId {
self.current_module
}
@@ -1291,7 +1479,7 @@ impl BindgenContext {
|num_params| {
(
*canon_decl.cursor(),
- template_decl_id,
+ template_decl_id.into(),
num_params,
)
},
@@ -1365,10 +1553,10 @@ impl BindgenContext {
fn instantiate_template(
&mut self,
with_id: ItemId,
- template: ItemId,
+ template: TypeId,
ty: &clang::Type,
location: clang::Cursor,
- ) -> Option<ItemId> {
+ ) -> Option<TypeId> {
use clang_sys;
let num_expected_args = match self.resolve_type(template)
@@ -1425,7 +1613,7 @@ impl BindgenContext {
let ty = Item::from_ty_or_ref(
child.cur_type(),
*child,
- Some(template),
+ Some(template.into()),
self,
);
args.push(ty);
@@ -1447,7 +1635,7 @@ impl BindgenContext {
let ty = Item::from_ty_or_ref(
child.cur_type(),
*child,
- Some(template),
+ Some(template.into()),
self,
);
args.push(ty);
@@ -1465,14 +1653,16 @@ impl BindgenContext {
return None;
}
- let mut sub_args: Vec<_> = args.drain(
- args_len - num_expected_template_args..,
- ).collect();
+ let mut sub_args: Vec<_> = args
+ .drain(args_len - num_expected_template_args..)
+ .collect();
sub_args.reverse();
let sub_name = Some(template_decl_cursor.spelling());
let sub_inst = TemplateInstantiation::new(
- template_decl_id,
+ // This isn't guaranteed to be a type that we've
+ // already finished parsing yet.
+ template_decl_id.as_type_id_unchecked(),
sub_args,
);
let sub_kind =
@@ -1491,7 +1681,7 @@ impl BindgenContext {
sub_id,
None,
None,
- self.current_module,
+ self.current_module.into(),
ItemKind::Type(sub_ty),
);
@@ -1504,7 +1694,7 @@ impl BindgenContext {
self.add_item_to_module(&sub_item);
debug_assert!(sub_id == sub_item.id());
self.items.insert(sub_id, sub_item);
- args.push(sub_id);
+ args.push(sub_id.as_type_id_unchecked());
}
}
_ => {
@@ -1555,7 +1745,7 @@ impl BindgenContext {
with_id,
None,
None,
- self.current_module,
+ self.current_module.into(),
ItemKind::Type(ty),
);
@@ -1564,7 +1754,7 @@ impl BindgenContext {
self.add_item_to_module(&item);
debug_assert!(with_id == item.id());
self.items.insert(with_id, item);
- Some(with_id)
+ Some(with_id.as_type_id_unchecked())
}
/// If we have already resolved the type for the given type declaration,
@@ -1572,7 +1762,7 @@ impl BindgenContext {
pub fn get_resolved_type(
&self,
decl: &clang::CanonicalTypeDeclaration,
- ) -> Option<ItemId> {
+ ) -> Option<TypeId> {
self.types
.get(&TypeKey::Declaration(*decl.cursor()))
.or_else(|| {
@@ -1591,7 +1781,7 @@ impl BindgenContext {
parent_id: Option<ItemId>,
ty: &clang::Type,
location: Option<clang::Cursor>,
- ) -> Option<ItemId> {
+ ) -> Option<TypeId> {
use clang_sys::{CXCursor_TypeAliasTemplateDecl, CXCursor_TypeRef};
debug!(
"builtin_or_resolved_ty: {:?}, {:?}, {:?}",
@@ -1662,10 +1852,10 @@ impl BindgenContext {
pub fn build_ty_wrapper(
&mut self,
with_id: ItemId,
- wrapped_id: ItemId,
+ wrapped_id: TypeId,
parent_id: Option<ItemId>,
ty: &clang::Type,
- ) -> ItemId {
+ ) -> TypeId {
let spelling = ty.spelling();
let is_const = ty.is_const();
let layout = ty.fallible_layout().ok();
@@ -1675,11 +1865,11 @@ 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);
- with_id
+ with_id.as_type_id_unchecked()
}
/// Returns the next item id to be used for an item.
@@ -1689,7 +1879,7 @@ impl BindgenContext {
ret
}
- fn build_builtin_ty(&mut self, ty: &clang::Type) -> Option<ItemId> {
+ fn build_builtin_ty(&mut self, ty: &clang::Type) -> Option<TypeId> {
use clang_sys::*;
let type_kind = match ty.kind() {
CXType_NullPtr => TypeKind::NullPtr,
@@ -1739,9 +1929,9 @@ 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)
+ Some(id.as_type_id_unchecked())
}
/// Get the current Clang translation unit that is being processed.
@@ -1803,7 +1993,8 @@ impl BindgenContext {
/// Is the item with the given `name` blacklisted? Or is the item with the given
/// `name` and `id` replaced by another type, and effectively blacklisted?
- pub fn blacklisted_by_name(&self, path: &[String], id: ItemId) -> bool {
+ pub fn blacklisted_by_name<Id: Into<ItemId>>(&self, path: &[String], id: Id) -> bool {
+ let id = id.into();
debug_assert!(
self.in_codegen_phase(),
"You're not supposed to call this yet"
@@ -1814,7 +2005,8 @@ impl BindgenContext {
/// Has the item with the given `name` and `id` been replaced by another
/// type?
- pub fn is_replaced_type(&self, path: &[String], id: ItemId) -> bool {
+ pub fn is_replaced_type<Id: Into<ItemId>>(&self, path: &[String], id: Id) -> bool {
+ let id = id.into();
match self.replacements.get(path) {
Some(replaced_by) if *replaced_by != id => true,
_ => false,
@@ -1898,7 +2090,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();
@@ -1914,11 +2106,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);
@@ -1927,7 +2120,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),
{
@@ -2096,7 +2289,8 @@ impl BindgenContext {
/// Look up whether the item with `id` can
/// derive debug or not.
- pub fn lookup_item_id_can_derive_debug(&self, id: ItemId) -> bool {
+ pub fn lookup_can_derive_debug<Id: Into<ItemId>>(&self, id: Id) -> bool {
+ let id = id.into();
assert!(
self.in_codegen_phase(),
"We only compute can_derive_debug when we enter codegen"
@@ -2119,7 +2313,8 @@ impl BindgenContext {
/// Look up whether the item with `id` can
/// derive default or not.
- pub fn lookup_item_id_can_derive_default(&self, id: ItemId) -> bool {
+ pub fn lookup_can_derive_default<Id: Into<ItemId>>(&self, id: Id) -> bool {
+ let id = id.into();
assert!(
self.in_codegen_phase(),
"We only compute can_derive_default when we enter codegen"
@@ -2148,7 +2343,8 @@ impl BindgenContext {
/// Look up whether the item with `id` can
/// derive hash or not.
- pub fn lookup_item_id_can_derive_hash(&self, id: ItemId) -> bool {
+ pub fn lookup_can_derive_hash<Id: Into<ItemId>>(&self, id: Id) -> bool {
+ let id = id.into();
assert!(
self.in_codegen_phase(),
"We only compute can_derive_debug when we enter codegen"
@@ -2169,7 +2365,8 @@ impl BindgenContext {
}
/// Look up whether the item with `id` can derive `Partial{Eq,Ord}`.
- pub fn lookup_item_id_can_derive_partialeq_or_partialord(&self, id: ItemId) -> bool {
+ pub fn lookup_can_derive_partialeq_or_partialord<Id: Into<ItemId>>(&self, id: Id) -> bool {
+ let id = id.into();
assert!(
self.in_codegen_phase(),
"We only compute can_derive_partialeq_or_partialord when we enter codegen"
@@ -2181,7 +2378,7 @@ impl BindgenContext {
}
/// Look up whether the item with `id` can derive `Copy` or not.
- pub fn lookup_item_id_can_derive_copy(&self, id: ItemId) -> bool {
+ pub fn lookup_can_derive_copy<Id: Into<ItemId>>(&self, id: Id) -> bool {
assert!(
self.in_codegen_phase(),
"We only compute can_derive_debug when we enter codegen"
@@ -2189,7 +2386,8 @@ impl BindgenContext {
// Look up the computed value for whether the item with `id` can
// derive `Copy` or not.
- !id.has_type_param_in_array(self) &&
+ let id = id.into();
+ !self.lookup_has_type_param_in_array(id) &&
!self.cannot_derive_copy.as_ref().unwrap().contains(&id)
}
@@ -2202,7 +2400,7 @@ impl BindgenContext {
}
/// Look up whether the item with `id` has type parameter in array or not.
- pub fn lookup_item_id_has_type_param_in_array(&self, id: &ItemId) -> bool {
+ pub fn lookup_has_type_param_in_array<Id: Into<ItemId>>(&self, id: Id) -> bool {
assert!(
self.in_codegen_phase(),
"We only compute has array when we enter codegen"
@@ -2210,7 +2408,7 @@ impl BindgenContext {
// Look up the computed value for whether the item with `id` has
// type parameter in array or not.
- self.has_type_param_in_array.as_ref().unwrap().contains(id)
+ self.has_type_param_in_array.as_ref().unwrap().contains(&id.into())
}
/// Compute whether the type has float.
@@ -2223,13 +2421,13 @@ impl BindgenContext {
}
/// Look up whether the item with `id` has array or not.
- pub fn lookup_item_id_has_float(&self, id: &ItemId) -> bool {
+ pub fn lookup_has_float<Id: Into<ItemId>>(&self, id: Id) -> bool {
assert!(self.in_codegen_phase(),
"We only compute has float when we enter codegen");
// Look up the computed value for whether the item with `id` has
// float or not.
- self.has_float.as_ref().unwrap().contains(id)
+ self.has_float.as_ref().unwrap().contains(&id.into())
}
/// Check if `--no-partialeq` flag is enabled for this item.
@@ -2254,15 +2452,19 @@ impl ItemId {
}
}
-impl From<ItemId> for ItemResolver {
- fn from(id: ItemId) -> ItemResolver {
+impl<T> From<T> for ItemResolver
+where
+ T: Into<ItemId>
+{
+ fn from(id: T) -> ItemResolver {
ItemResolver::new(id)
}
}
impl ItemResolver {
/// Construct a new `ItemResolver` from the given id.
- pub fn new(id: ItemId) -> ItemResolver {
+ pub fn new<Id: Into<ItemId>>(id: Id) -> ItemResolver {
+ let id = id.into();
ItemResolver {
id: id,
through_type_refs: false,
@@ -2293,14 +2495,14 @@ impl ItemResolver {
match ty_kind {
Some(&TypeKind::ResolvedTypeRef(next_id))
if self.through_type_refs => {
- id = next_id;
+ id = next_id.into();
}
// We intentionally ignore template aliases here, as they are
// more complicated, and don't represent a simple renaming of
// some type.
Some(&TypeKind::Alias(next_id))
if self.through_type_aliases => {
- id = next_id;
+ id = next_id.into();
}
_ => return item,
}
@@ -2312,6 +2514,8 @@ impl ItemResolver {
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
pub struct PartialType {
decl: Cursor,
+ // Just an ItemId, and not a TypeId, because we haven't finished this type
+ // yet, so there's still time for things to go wrong.
id: ItemId,
}
@@ -2341,7 +2545,7 @@ impl TemplateParameters for PartialType {
fn self_template_params(
&self,
_ctx: &BindgenContext,
- ) -> Option<Vec<ItemId>> {
+ ) -> Option<Vec<TypeId>> {
// Maybe at some point we will eagerly parse named types, but for now we
// don't and this information is unavailable.
None
diff --git a/src/ir/enum_ty.rs b/src/ir/enum_ty.rs
index dc56f64a..3006ec7f 100644
--- a/src/ir/enum_ty.rs
+++ b/src/ir/enum_ty.rs
@@ -1,6 +1,6 @@
//! Intermediate representation for C/C++ enumerations.
-use super::context::{BindgenContext, ItemId};
+use super::context::{BindgenContext, TypeId};
use super::item::Item;
use super::ty::TypeKind;
use clang;
@@ -27,7 +27,7 @@ pub struct Enum {
///
/// It's `None` if the enum is a forward declaration and isn't defined
/// anywhere else, see `tests/headers/func_ptr_in_struct.h`.
- repr: Option<ItemId>,
+ repr: Option<TypeId>,
/// The different variants, with explicit values.
variants: Vec<EnumVariant>,
@@ -35,7 +35,7 @@ pub struct Enum {
impl Enum {
/// Construct a new `Enum` with the given representation and variants.
- pub fn new(repr: Option<ItemId>, variants: Vec<EnumVariant>) -> Self {
+ pub fn new(repr: Option<TypeId>, variants: Vec<EnumVariant>) -> Self {
Enum {
repr: repr,
variants: variants,
@@ -43,7 +43,7 @@ impl Enum {
}
/// Get this enumeration's representation.
- pub fn repr(&self) -> Option<ItemId> {
+ pub fn repr(&self) -> Option<TypeId> {
self.repr
}
diff --git a/src/ir/function.rs b/src/ir/function.rs
index 402a0230..ccdfc4f3 100644
--- a/src/ir/function.rs
+++ b/src/ir/function.rs
@@ -1,7 +1,7 @@
//! Intermediate representation for C/C++ functions and methods.
use super::comp::MethodKind;
-use super::context::{BindgenContext, ItemId};
+use super::context::{BindgenContext, TypeId};
use super::dot::DotAttributes;
use super::item::Item;
use super::traversal::{EdgeKind, Trace, Tracer};
@@ -62,7 +62,7 @@ pub struct Function {
mangled_name: Option<String>,
/// The id pointing to the current function signature.
- signature: ItemId,
+ signature: TypeId,
/// The doc comment on the function, if any.
comment: Option<String>,
@@ -76,7 +76,7 @@ impl Function {
pub fn new(
name: String,
mangled_name: Option<String>,
- sig: ItemId,
+ sig: TypeId,
comment: Option<String>,
kind: FunctionKind,
) -> Self {
@@ -99,8 +99,8 @@ impl Function {
self.mangled_name.as_ref().map(|n| &**n)
}
- /// Get this function's signature.
- pub fn signature(&self) -> ItemId {
+ /// Get this function's signature type.
+ pub fn signature(&self) -> TypeId {
self.signature
}
@@ -180,11 +180,11 @@ impl quote::ToTokens for Abi {
#[derive(Debug)]
pub struct FunctionSig {
/// The return type of the function.
- return_type: ItemId,
+ return_type: TypeId,
/// The type of the arguments, optionally with the name of the argument when
/// declared.
- argument_types: Vec<(Option<String>, ItemId)>,
+ argument_types: Vec<(Option<String>, TypeId)>,
/// Whether this function is variadic.
is_variadic: bool,
@@ -287,8 +287,8 @@ pub fn cursor_mangling(
impl FunctionSig {
/// Construct a new function signature.
pub fn new(
- return_type: ItemId,
- arguments: Vec<(Option<String>, ItemId)>,
+ return_type: TypeId,
+ arguments: Vec<(Option<String>, TypeId)>,
is_variadic: bool,
abi: Abi,
) -> Self {
@@ -384,6 +384,10 @@ impl FunctionSig {
if !is_static && !is_virtual {
let class = Item::parse(cursor.semantic_parent(), None, ctx)
.expect("Expected to parse the class");
+ // The `class` most likely is not finished parsing yet, so use
+ // the unchecked variant.
+ let class = class.as_type_id_unchecked();
+
let ptr =
Item::builtin_type(TypeKind::Pointer(class), is_const, ctx);
args.insert(0, (Some("this".into()), ptr));
@@ -412,16 +416,16 @@ impl FunctionSig {
warn!("Unknown calling convention: {:?}", call_conv);
}
- Ok(Self::new(ret, args, ty.is_variadic(), abi))
+ Ok(Self::new(ret.into(), args, ty.is_variadic(), abi))
}
/// Get this function signature's return type.
- pub fn return_type(&self) -> ItemId {
+ pub fn return_type(&self) -> TypeId {
self.return_type
}
/// Get this function signature's argument (name, type) pairs.
- pub fn argument_types(&self) -> &[(Option<String>, ItemId)] {
+ pub fn argument_types(&self) -> &[(Option<String>, TypeId)] {
&self.argument_types
}
@@ -535,10 +539,10 @@ impl Trace for FunctionSig {
where
T: Tracer,
{
- tracer.visit_kind(self.return_type(), EdgeKind::FunctionReturn);
+ tracer.visit_kind(self.return_type().into(), EdgeKind::FunctionReturn);
for &(_, ty) in self.argument_types() {
- tracer.visit_kind(ty, EdgeKind::FunctionParameter);
+ tracer.visit_kind(ty.into(), EdgeKind::FunctionParameter);
}
}
}
diff --git a/src/ir/item.rs b/src/ir/item.rs
index 955793c1..010528b6 100644
--- a/src/ir/item.rs
+++ b/src/ir/item.rs
@@ -4,7 +4,7 @@ use super::analysis::HasVtable;
use super::annotations::Annotations;
use super::comment;
use super::comp::MethodKind;
-use super::context::{BindgenContext, ItemId, PartialType};
+use super::context::{BindgenContext, ItemId, PartialType, TypeId};
use super::derive::{CanDeriveCopy, CanDeriveDebug, CanDeriveDefault,
CanDeriveHash, CanDerivePartialOrd, CanDeriveOrd,
CanDerivePartialEq, CanDeriveEq};
@@ -111,7 +111,7 @@ cfg_if! {
DebugOnlyItemSet
}
- fn contains(&self,_id: &ItemId) -> bool {
+ fn contains(&self, _id: &ItemId) -> bool {
false
}
@@ -128,9 +128,9 @@ pub struct ItemAncestorsIter<'a> {
}
impl<'a> ItemAncestorsIter<'a> {
- fn new(ctx: &'a BindgenContext, item: ItemId) -> Self {
+ fn new<Id: Into<ItemId>>(ctx: &'a BindgenContext, id: Id) -> Self {
ItemAncestorsIter {
- item: item,
+ item: id.into(),
ctx: ctx,
seen: DebugOnlyItemSet::new(),
}
@@ -156,15 +156,17 @@ impl<'a> Iterator for ItemAncestorsIter<'a> {
}
}
-impl AsTemplateParam for ItemId {
+impl<T> AsTemplateParam for T
+where
+ T: Copy + Into<ItemId> {
type Extra = ();
fn as_template_param(
&self,
ctx: &BindgenContext,
_: &(),
- ) -> Option<ItemId> {
- ctx.resolve_item(*self).as_template_param(ctx, &())
+ ) -> Option<TypeId> {
+ ctx.resolve_item((*self).into()).as_template_param(ctx, &())
}
}
@@ -175,7 +177,7 @@ impl AsTemplateParam for Item {
&self,
ctx: &BindgenContext,
_: &(),
- ) -> Option<ItemId> {
+ ) -> Option<TypeId> {
self.kind.as_template_param(ctx, self)
}
}
@@ -187,7 +189,7 @@ impl AsTemplateParam for ItemKind {
&self,
ctx: &BindgenContext,
item: &Item,
- ) -> Option<ItemId> {
+ ) -> Option<TypeId> {
match *self {
ItemKind::Type(ref ty) => ty.as_template_param(ctx, item),
ItemKind::Module(..) |
@@ -197,8 +199,10 @@ impl AsTemplateParam for ItemKind {
}
}
-// Pure convenience
-impl ItemCanonicalName for ItemId {
+impl<T> ItemCanonicalName for T
+where
+ T: Copy + Into<ItemId>
+{
fn canonical_name(&self, ctx: &BindgenContext) -> String {
debug_assert!(
ctx.in_codegen_phase(),
@@ -208,7 +212,10 @@ impl ItemCanonicalName for ItemId {
}
}
-impl ItemCanonicalPath for ItemId {
+impl<T> ItemCanonicalPath for T
+ where
+ T: Copy + Into<ItemId>
+{
fn namespace_aware_canonical_path(
&self,
ctx: &BindgenContext,
@@ -229,7 +236,10 @@ impl ItemCanonicalPath for ItemId {
}
}
-impl ItemAncestors for ItemId {
+impl<T> ItemAncestors for T
+where
+ T: Copy + Into<ItemId>
+{
fn ancestors<'a>(
&self,
ctx: &'a BindgenContext,
@@ -247,7 +257,10 @@ impl ItemAncestors for Item {
}
}
-impl Trace for ItemId {
+impl<Id> Trace for Id
+where
+ Id: Copy + Into<ItemId>
+{
type Extra = ();
fn trace<T>(&self, ctx: &BindgenContext, tracer: &mut T, extra: &())
@@ -286,10 +299,10 @@ impl Trace for Item {
ItemKind::Function(ref fun) => {
// Just the same way, it has not real meaning for a function to
// be opaque, so we trace across it.
- tracer.visit(fun.signature());
+ tracer.visit(fun.signature().into());
}
ItemKind::Var(ref var) => {
- tracer.visit_kind(var.ty(), EdgeKind::VarType);
+ tracer.visit_kind(var.ty().into(), EdgeKind::VarType);
}
ItemKind::Module(_) => {
// Module -> children edges are "weak", and we do not want to
@@ -307,57 +320,57 @@ impl Trace for Item {
impl CanDeriveDebug for Item {
fn can_derive_debug(&self, ctx: &BindgenContext) -> bool {
ctx.options().derive_debug &&
- ctx.lookup_item_id_can_derive_debug(self.id())
+ ctx.lookup_can_derive_debug(self.id())
}
}
impl CanDeriveDefault for Item {
fn can_derive_default(&self, ctx: &BindgenContext) -> bool {
ctx.options().derive_default &&
- ctx.lookup_item_id_can_derive_default(self.id())
+ ctx.lookup_can_derive_default(self.id())
}
}
impl<'a> CanDeriveCopy<'a> for Item {
fn can_derive_copy(&self, ctx: &BindgenContext) -> bool {
- ctx.lookup_item_id_can_derive_copy(self.id())
+ ctx.lookup_can_derive_copy(self.id())
}
}
impl CanDeriveHash for Item {
fn can_derive_hash(&self, ctx: &BindgenContext) -> bool {
ctx.options().derive_hash &&
- ctx.lookup_item_id_can_derive_hash(self.id())
+ ctx.lookup_can_derive_hash(self.id())
}
}
impl CanDerivePartialOrd for Item {
fn can_derive_partialord(&self, ctx: &BindgenContext) -> bool {
ctx.options().derive_partialord &&
- ctx.lookup_item_id_can_derive_partialeq_or_partialord(self.id())
+ ctx.lookup_can_derive_partialeq_or_partialord(self.id())
}
}
impl CanDerivePartialEq for Item {
fn can_derive_partialeq(&self, ctx: &BindgenContext) -> bool {
ctx.options().derive_partialeq &&
- ctx.lookup_item_id_can_derive_partialeq_or_partialord(self.id())
+ ctx.lookup_can_derive_partialeq_or_partialord(self.id())
}
}
impl CanDeriveEq for Item {
fn can_derive_eq(&self, ctx: &BindgenContext) -> bool {
ctx.options().derive_eq &&
- ctx.lookup_item_id_can_derive_partialeq_or_partialord(self.id()) &&
- !ctx.lookup_item_id_has_float(&self.id())
+ ctx.lookup_can_derive_partialeq_or_partialord(self.id()) &&
+ !ctx.lookup_has_float(self.id())
}
}
impl CanDeriveOrd for Item {
fn can_derive_ord(&self, ctx: &BindgenContext) -> bool {
ctx.options().derive_ord &&
- ctx.lookup_item_id_can_derive_partialeq_or_partialord(self.id()) &&
- !ctx.lookup_item_id_has_float(&self.id())
+ ctx.lookup_can_derive_partialeq_or_partialord(self.id()) &&
+ !ctx.lookup_has_float(self.id())
}
}
@@ -449,12 +462,12 @@ impl Item {
with_id: ItemId,
ty: &clang::Type,
ctx: &mut BindgenContext,
- ) -> ItemId {
+ ) -> 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
+ with_id.as_type_id_unchecked()
}
/// Get this `Item`'s identifier.
@@ -472,8 +485,8 @@ impl Item {
/// Set this item's parent id.
///
/// This is only used so replacements get generated in the proper module.
- pub fn set_parent_for_replacement(&mut self, id: ItemId) {
- self.parent_id = id;
+ pub fn set_parent_for_replacement<Id: Into<ItemId>>(&mut self, id: Id) {
+ self.parent_id = id.into();
}
/// Returns the depth this item is indented to.
@@ -952,7 +965,10 @@ impl Item {
}
}
-impl IsOpaque for ItemId {
+impl<T> IsOpaque for T
+where
+ T: Copy + Into<ItemId>
+{
type Extra = ();
fn is_opaque(&self, ctx: &BindgenContext, _: &()) -> bool {
@@ -960,7 +976,7 @@ impl IsOpaque for ItemId {
ctx.in_codegen_phase(),
"You're not supposed to call this yet"
);
- ctx.resolve_item(*self).is_opaque(ctx, &())
+ ctx.resolve_item((*self).into()).is_opaque(ctx, &())
}
}
@@ -978,25 +994,35 @@ impl IsOpaque for Item {
}
}
-impl HasVtable for ItemId {
+impl<T> HasVtable for T
+where
+ T: Copy + Into<ItemId>
+{
fn has_vtable(&self, ctx: &BindgenContext) -> bool {
- ctx.lookup_item_id_has_vtable(self)
+ let id: ItemId = (*self).into();
+ id.as_type_id(ctx)
+ .map_or(false, |id| ctx.lookup_has_vtable(id))
}
}
impl HasVtable for Item {
fn has_vtable(&self, ctx: &BindgenContext) -> bool {
- ctx.lookup_item_id_has_vtable(&self.id())
+ self.id()
+ .as_type_id(ctx)
+ .map_or(false, |id| ctx.lookup_has_vtable(id))
}
}
-impl HasTypeParamInArray for ItemId {
+impl<T> HasTypeParamInArray for T
+where
+ T: Copy + Into<ItemId>
+{
fn has_type_param_in_array(&self, ctx: &BindgenContext) -> bool {
debug_assert!(
ctx.in_codegen_phase(),
"You're not supposed to call this yet"
);
- ctx.lookup_item_id_has_type_param_in_array(self)
+ ctx.lookup_has_type_param_in_array(*self)
}
}
@@ -1006,15 +1032,18 @@ impl HasTypeParamInArray for Item {
ctx.in_codegen_phase(),
"You're not supposed to call this yet"
);
- ctx.lookup_item_id_has_type_param_in_array(&self.id())
+ ctx.lookup_has_type_param_in_array(self.id())
}
}
-impl HasFloat for ItemId {
+impl<T> HasFloat for T
+where
+ T: Copy + Into<ItemId>
+{
fn has_float(&self, ctx: &BindgenContext) -> bool {
debug_assert!(ctx.in_codegen_phase(),
"You're not supposed to call this yet");
- ctx.lookup_item_id_has_float(self)
+ ctx.lookup_has_float(*self)
}
}
@@ -1022,7 +1051,7 @@ impl HasFloat for Item {
fn has_float(&self, ctx: &BindgenContext) -> bool {
debug_assert!(ctx.in_codegen_phase(),
"You're not supposed to call this yet");
- ctx.lookup_item_id_has_float(&self.id())
+ ctx.lookup_has_float(self.id())
}
}
@@ -1054,11 +1083,14 @@ impl DotAttributes for Item {
}
}
-impl TemplateParameters for ItemId {
+impl<T> TemplateParameters for T
+where
+ T: Copy + Into<ItemId>
+{
fn self_template_params(
&self,
ctx: &BindgenContext,
- ) -> Option<Vec<ItemId>> {
+ ) -> Option<Vec<TypeId>> {
ctx.resolve_item_fallible(*self).and_then(|item| {
item.self_template_params(ctx)
})
@@ -1069,7 +1101,7 @@ impl TemplateParameters for Item {
fn self_template_params(
&self,
ctx: &BindgenContext,
- ) -> Option<Vec<ItemId>> {
+ ) -> Option<Vec<TypeId>> {
self.kind.self_template_params(ctx)
}
}
@@ -1078,7 +1110,7 @@ impl TemplateParameters for ItemKind {
fn self_template_params(
&self,
ctx: &BindgenContext,
- ) -> Option<Vec<ItemId>> {
+ ) -> Option<Vec<TypeId>> {
match *self {
ItemKind::Type(ref ty) => ty.self_template_params(ctx),
// If we start emitting bindings to explicitly instantiated
@@ -1098,7 +1130,7 @@ fn visit_child(
ty: &clang::Type,
parent_id: Option<ItemId>,
ctx: &mut BindgenContext,
- result: &mut Result<ItemId, ParseError>,
+ result: &mut Result<TypeId, ParseError>,
) -> clang_sys::CXChildVisitResult {
use clang_sys::*;
if result.is_ok() {
@@ -1122,7 +1154,7 @@ impl ClangItemParser for Item {
kind: TypeKind,
is_const: bool,
ctx: &mut BindgenContext,
- ) -> ItemId {
+ ) -> TypeId {
// Feel free to add more here, I'm just lazy.
match kind {
TypeKind::Void |
@@ -1134,13 +1166,13 @@ 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,
None,
);
- id
+ id.as_type_id_unchecked()
}
@@ -1161,7 +1193,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 {
@@ -1214,11 +1246,11 @@ impl ClangItemParser for Item {
cursor,
parent_id,
ctx,
- ));
+ ).into());
}
ctx.known_semantic_parent(definition)
.or(parent_id)
- .unwrap_or(ctx.current_module())
+ .unwrap_or(ctx.current_module().into())
}
None => relevant_parent_id,
};
@@ -1229,7 +1261,7 @@ impl ClangItemParser for Item {
Some(relevant_parent_id),
ctx,
) {
- Ok(ty) => return Ok(ty),
+ Ok(ty) => return Ok(ty.into()),
Err(ParseError::Recurse) => return Err(ParseError::Recurse),
Err(ParseError::Continue) => {}
}
@@ -1276,7 +1308,7 @@ impl ClangItemParser for Item {
location: clang::Cursor,
parent_id: Option<ItemId>,
ctx: &mut BindgenContext,
- ) -> ItemId {
+ ) -> TypeId {
let id = ctx.next_item_id();
Self::from_ty_or_ref_with_id(id, ty, location, parent_id, ctx)
}
@@ -1297,7 +1329,7 @@ impl ClangItemParser for Item {
location: clang::Cursor,
parent_id: Option<ItemId>,
ctx: &mut BindgenContext,
- ) -> ItemId {
+ ) -> TypeId {
debug!(
"from_ty_or_ref_with_id: {:?} {:?}, {:?}, {:?}",
potential_id,
@@ -1340,13 +1372,13 @@ 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()),
None,
);
- potential_id
+ potential_id.as_type_id_unchecked()
}
fn from_ty(
@@ -1354,7 +1386,7 @@ impl ClangItemParser for Item {
location: clang::Cursor,
parent_id: Option<ItemId>,
ctx: &mut BindgenContext,
- ) -> Result<ItemId, ParseError> {
+ ) -> Result<TypeId, ParseError> {
let id = ctx.next_item_id();
Item::from_ty_with_id(id, ty, location, parent_id, ctx)
}
@@ -1373,7 +1405,7 @@ impl ClangItemParser for Item {
location: clang::Cursor,
parent_id: Option<ItemId>,
ctx: &mut BindgenContext,
- ) -> Result<ItemId, ParseError> {
+ ) -> Result<TypeId, ParseError> {
use clang_sys::*;
debug!(
@@ -1444,11 +1476,12 @@ impl ClangItemParser for Item {
)
{
debug!("Avoiding recursion parsing type: {:?}", ty);
- return Ok(partial.id());
+ // Unchecked because we haven't finished this type yet.
+ return Ok(partial.id().as_type_id_unchecked());
}
}
- 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);
@@ -1457,7 +1490,7 @@ impl ClangItemParser for Item {
let result = Type::from_clang_ty(id, ty, location, parent_id, ctx);
let relevant_parent_id = parent_id.unwrap_or(current_module);
let ret = match result {
- Ok(ParseResult::AlreadyResolved(ty)) => Ok(ty),
+ Ok(ParseResult::AlreadyResolved(ty)) => Ok(ty.expect_type_id(ctx)),
Ok(ParseResult::New(item, declaration)) => {
ctx.add_item(
Item::new(
@@ -1470,7 +1503,7 @@ impl ClangItemParser for Item {
declaration,
Some(location),
);
- Ok(id)
+ Ok(id.as_type_id_unchecked())
}
Err(ParseError::Continue) => Err(ParseError::Continue),
Err(ParseError::Recurse) => {
@@ -1533,7 +1566,7 @@ impl ClangItemParser for Item {
with_id: Option<ItemId>,
location: clang::Cursor,
ctx: &mut BindgenContext,
- ) -> Option<ItemId> {
+ ) -> Option<TypeId> {
let ty = location.cur_type();
debug!(
@@ -1671,7 +1704,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 {
@@ -1696,7 +1729,7 @@ impl ClangItemParser for Item {
ItemKind::Type(Type::named(name)),
);
ctx.add_type_param(item, definition);
- Some(id)
+ Some(id.as_type_id_unchecked())
}
}
@@ -1757,7 +1790,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/template.rs b/src/ir/template.rs
index c1650abc..f5cc0152 100644
--- a/src/ir/template.rs
+++ b/src/ir/template.rs
@@ -27,7 +27,7 @@
//! };
//! ```
-use super::context::{BindgenContext, ItemId};
+use super::context::{BindgenContext, ItemId, TypeId};
use super::item::{IsOpaque, Item, ItemAncestors, ItemCanonicalPath};
use super::traversal::{EdgeKind, Trace, Tracer};
use clang;
@@ -109,7 +109,7 @@ pub trait TemplateParameters {
/// anything but types, so we must treat them as opaque, and avoid
/// instantiating them.
fn self_template_params(&self, ctx: &BindgenContext)
- -> Option<Vec<ItemId>>;
+ -> Option<Vec<TypeId>>;
/// Get the number of free template parameters this template declaration
/// has.
@@ -136,7 +136,7 @@ pub trait TemplateParameters {
/// how we would fully reference such a member type in C++:
/// `Foo<int,char>::Inner`. `Foo` *must* be instantiated with template
/// arguments before we can gain access to the `Inner` member type.
- fn all_template_params(&self, ctx: &BindgenContext) -> Option<Vec<ItemId>>
+ fn all_template_params(&self, ctx: &BindgenContext) -> Option<Vec<TypeId>>
where
Self: ItemAncestors,
{
@@ -159,7 +159,7 @@ pub trait TemplateParameters {
/// Get only the set of template parameters that this item uses. This is a
/// subset of `all_template_params` and does not necessarily contain any of
/// `self_template_params`.
- fn used_template_params(&self, ctx: &BindgenContext) -> Option<Vec<ItemId>>
+ fn used_template_params(&self, ctx: &BindgenContext) -> Option<Vec<TypeId>>
where
Self: AsRef<ItemId>,
{
@@ -190,7 +190,7 @@ pub trait AsTemplateParam {
&self,
ctx: &BindgenContext,
extra: &Self::Extra,
- ) -> Option<ItemId>;
+ ) -> Option<TypeId>;
/// Is this a named template type parameter?
fn is_template_param(
@@ -206,20 +206,20 @@ pub trait AsTemplateParam {
#[derive(Clone, Debug)]
pub struct TemplateInstantiation {
/// The template definition which this is instantiating.
- definition: ItemId,
+ definition: TypeId,
/// The concrete template arguments, which will be substituted in the
/// definition for the generic template parameters.
- args: Vec<ItemId>,
+ args: Vec<TypeId>,
}
impl TemplateInstantiation {
/// Construct a new template instantiation from the given parts.
pub fn new<I>(
- template_definition: ItemId,
+ template_definition: TypeId,
template_args: I,
) -> TemplateInstantiation
where
- I: IntoIterator<Item = ItemId>,
+ I: IntoIterator<Item = TypeId>,
{
TemplateInstantiation {
definition: template_definition,
@@ -228,12 +228,12 @@ impl TemplateInstantiation {
}
/// Get the template definition for this instantiation.
- pub fn template_definition(&self) -> ItemId {
+ pub fn template_definition(&self) -> TypeId {
self.definition
}
/// Get the concrete template arguments used in this instantiation.
- pub fn template_arguments(&self) -> &[ItemId] {
+ pub fn template_arguments(&self) -> &[TypeId] {
&self.args[..]
}
@@ -353,9 +353,9 @@ impl Trace for TemplateInstantiation {
where
T: Tracer,
{
- tracer.visit_kind(self.definition, EdgeKind::TemplateDeclaration);
- for &item in self.template_arguments() {
- tracer.visit_kind(item, EdgeKind::TemplateArgument);
+ tracer.visit_kind(self.definition.into(), EdgeKind::TemplateDeclaration);
+ for arg in self.template_arguments() {
+ tracer.visit_kind(arg.into(), EdgeKind::TemplateArgument);
}
}
}
diff --git a/src/ir/ty.rs b/src/ir/ty.rs
index 8cfbde10..45555344 100644
--- a/src/ir/ty.rs
+++ b/src/ir/ty.rs
@@ -1,7 +1,7 @@
//! Everything related to types in our intermediate representation.
use super::comp::CompInfo;
-use super::context::{BindgenContext, ItemId};
+use super::context::{BindgenContext, ItemId, TypeId};
use super::dot::DotAttributes;
use super::enum_ty::Enum;
use super::function::FunctionSig;
@@ -212,7 +212,7 @@ impl Type {
pub fn is_incomplete_array(&self, ctx: &BindgenContext) -> Option<ItemId> {
match self.kind {
TypeKind::Array(item, len) => {
- if len == 0 { Some(item) } else { None }
+ if len == 0 { Some(item.into()) } else { None }
}
TypeKind::ResolvedTypeRef(inner) => {
ctx.resolve_type(inner).is_incomplete_array(ctx)
@@ -275,8 +275,8 @@ impl Type {
ctx: &BindgenContext,
) -> Option<Cow<'a, str>> {
let name_info = match *self.kind() {
- TypeKind::Pointer(inner) => Some((inner, Cow::Borrowed("ptr"))),
- TypeKind::Reference(inner) => Some((inner, Cow::Borrowed("ref"))),
+ TypeKind::Pointer(inner) => Some((inner.into(), Cow::Borrowed("ptr"))),
+ TypeKind::Reference(inner) => Some((inner.into(), Cow::Borrowed("ref"))),
TypeKind::Array(inner, length) => {
Some((inner, format!("array{}", length).into()))
}
@@ -383,7 +383,7 @@ impl AsTemplateParam for Type {
&self,
ctx: &BindgenContext,
item: &Item,
- ) -> Option<ItemId> {
+ ) -> Option<TypeId> {
self.kind.as_template_param(ctx, item)
}
}
@@ -395,9 +395,9 @@ impl AsTemplateParam for TypeKind {
&self,
ctx: &BindgenContext,
item: &Item,
- ) -> Option<ItemId> {
+ ) -> Option<TypeId> {
match *self {
- TypeKind::TypeParam => Some(item.id()),
+ TypeKind::TypeParam => Some(item.id().expect_type_id(ctx)),
TypeKind::ResolvedTypeRef(id) => id.as_template_param(ctx, &()),
_ => None,
}
@@ -534,7 +534,7 @@ impl TemplateParameters for Type {
fn self_template_params(
&self,
ctx: &BindgenContext,
- ) -> Option<Vec<ItemId>> {
+ ) -> Option<Vec<TypeId>> {
self.kind.self_template_params(ctx)
}
}
@@ -543,7 +543,7 @@ impl TemplateParameters for TypeKind {
fn self_template_params(
&self,
ctx: &BindgenContext,
- ) -> Option<Vec<ItemId>> {
+ ) -> Option<Vec<TypeId>> {
match *self {
TypeKind::ResolvedTypeRef(id) => {
ctx.resolve_type(id).self_template_params(ctx)
@@ -626,14 +626,14 @@ pub enum TypeKind {
Complex(FloatKind),
/// A type alias, with a name, that points to another type.
- Alias(ItemId),
+ Alias(TypeId),
/// A templated alias, pointing to an inner type, just as `Alias`, but with
/// template parameters.
- TemplateAlias(ItemId, Vec<ItemId>),
+ TemplateAlias(TypeId, Vec<TypeId>),
- /// An array of a type and a lenght.
- Array(ItemId, usize),
+ /// An array of a type and a length.
+ Array(TypeId, usize),
/// A function type, with a given signature.
Function(FunctionSig),
@@ -643,13 +643,13 @@ pub enum TypeKind {
/// A pointer to a type. The bool field represents whether it's const or
/// not.
- Pointer(ItemId),
+ Pointer(TypeId),
/// A pointer to an Apple block.
BlockPointer,
/// A reference to a type, as in: int& foo().
- Reference(ItemId),
+ Reference(TypeId),
/// An instantiation of an abstract template definition with a set of
/// concrete template arguments.
@@ -673,7 +673,7 @@ pub enum TypeKind {
///
/// These are generated after we resolve a forward declaration, or when we
/// replace one type with another.
- ResolvedTypeRef(ItemId),
+ ResolvedTypeRef(TypeId),
/// A named type, that is, a template parameter.
TypeParam,
@@ -693,24 +693,24 @@ impl Type {
/// derive whether we should generate a dummy `_address` field for structs,
/// to comply to the C and C++ layouts, that specify that every type needs
/// to be addressable.
- pub fn is_unsized(&self, ctx: &BindgenContext, itemid: &ItemId) -> bool {
+ pub fn is_unsized(&self, ctx: &BindgenContext, id: TypeId) -> bool {
debug_assert!(ctx.in_codegen_phase(), "Not yet");
match self.kind {
TypeKind::Void => true,
- TypeKind::Comp(ref ci) => ci.is_unsized(ctx, itemid),
+ 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)
+ 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)
+ 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)
+ ctx.resolve_type(definition).is_unsized(ctx, definition)
}
TypeKind::TypeParam |
TypeKind::Int(..) |
@@ -755,7 +755,7 @@ impl Type {
);
if let Some(ty) = already_resolved {
debug!("{:?} already resolved: {:?}", ty, location);
- return Ok(ParseResult::AlreadyResolved(ty));
+ return Ok(ParseResult::AlreadyResolved(ty.into()));
}
}
@@ -1035,14 +1035,14 @@ impl Type {
referenced_ty
);
- let item = Item::from_ty_or_ref_with_id(
+ let id = Item::from_ty_or_ref_with_id(
potential_id,
referenced_ty,
declaration,
parent_id,
ctx,
);
- return Ok(ParseResult::AlreadyResolved(item));
+ return Ok(ParseResult::AlreadyResolved(id.into()));
}
CXCursor_NamespaceRef => {
return Err(ParseError::Continue);
@@ -1261,13 +1261,13 @@ impl Trace for Type {
TypeKind::Array(inner, _) |
TypeKind::Alias(inner) |
TypeKind::ResolvedTypeRef(inner) => {
- tracer.visit_kind(inner, EdgeKind::TypeReference);
+ tracer.visit_kind(inner.into(), EdgeKind::TypeReference);
}
TypeKind::TemplateAlias(inner, ref template_params) => {
- tracer.visit_kind(inner, EdgeKind::TypeReference);
- for &item in template_params {
+ tracer.visit_kind(inner.into(), EdgeKind::TypeReference);
+ for param in template_params {
tracer.visit_kind(
- item,
+ param.into(),
EdgeKind::TemplateParameterDefinition,
);
}
@@ -1279,7 +1279,7 @@ impl Trace for Type {
TypeKind::Function(ref sig) => sig.trace(context, tracer, &()),
TypeKind::Enum(ref en) => {
if let Some(repr) = en.repr() {
- tracer.visit(repr);
+ tracer.visit(repr.into());
}
}
TypeKind::UnresolvedTypeRef(_, _, Some(id)) => {
diff --git a/src/ir/var.rs b/src/ir/var.rs
index 987bfd50..3abc44cf 100644
--- a/src/ir/var.rs
+++ b/src/ir/var.rs
@@ -1,6 +1,6 @@
//! Intermediate representation of variables.
-use super::context::{BindgenContext, ItemId};
+use super::context::{BindgenContext, TypeId};
use super::dot::DotAttributes;
use super::function::cursor_mangling;
use super::int::IntKind;
@@ -35,7 +35,7 @@ pub struct Var {
/// The mangled name of the variable.
mangled_name: Option<String>,
/// The type of the variable.
- ty: ItemId,
+ ty: TypeId,
/// The value of the variable, that needs to be suitable for `ty`.
val: Option<VarType>,
/// Whether this variable is const.
@@ -47,7 +47,7 @@ impl Var {
pub fn new(
name: String,
mangled: Option<String>,
- ty: ItemId,
+ ty: TypeId,
val: Option<VarType>,
is_const: bool,
) -> Var {
@@ -72,7 +72,7 @@ impl Var {
}
/// Get this variable's type.
- pub fn ty(&self) -> ItemId {
+ pub fn ty(&self) -> TypeId {
self.ty
}
diff --git a/src/parse.rs b/src/parse.rs
index 5869f302..1a9278b3 100644
--- a/src/parse.rs
+++ b/src/parse.rs
@@ -1,7 +1,7 @@
//! Common traits and types related to parsing our IR from Clang cursors.
use clang;
-use ir::context::{BindgenContext, ItemId};
+use ir::context::{BindgenContext, ItemId, TypeId};
use ir::ty::TypeKind;
/// Not so much an error in the traditional sense, but a control flow message
@@ -55,7 +55,7 @@ pub trait ClangItemParser: Sized {
location: clang::Cursor,
parent: Option<ItemId>,
ctx: &mut BindgenContext,
- ) -> Result<ItemId, ParseError>;
+ ) -> Result<TypeId, ParseError>;
/// Identical to `from_ty`, but use the given `id` as the `ItemId` for the
/// newly parsed item.
@@ -65,7 +65,7 @@ pub trait ClangItemParser: Sized {
location: clang::Cursor,
parent: Option<ItemId>,
ctx: &mut BindgenContext,
- ) -> Result<ItemId, ParseError>;
+ ) -> Result<TypeId, ParseError>;
/// Parse this item from the given Clang type, or if we haven't resolved all
/// the other items this one depends on, an unresolved reference.
@@ -74,7 +74,7 @@ pub trait ClangItemParser: Sized {
location: clang::Cursor,
parent_id: Option<ItemId>,
context: &mut BindgenContext,
- ) -> ItemId;
+ ) -> TypeId;
/// Identical to `from_ty_or_ref`, but use the given `potential_id` as the
/// `ItemId` for the newly parsed item.
@@ -84,19 +84,19 @@ pub trait ClangItemParser: Sized {
location: clang::Cursor,
parent_id: Option<ItemId>,
context: &mut BindgenContext,
- ) -> ItemId;
+ ) -> TypeId;
/// Create a named template type.
fn type_param(
with_id: Option<ItemId>,
location: clang::Cursor,
ctx: &mut BindgenContext,
- ) -> Option<ItemId>;
+ ) -> Option<TypeId>;
/// Create a builtin type.
fn builtin_type(
kind: TypeKind,
is_const: bool,
context: &mut BindgenContext,
- ) -> ItemId;
+ ) -> TypeId;
}