diff options
author | bors-servo <lbergstrom+bors@mozilla.com> | 2017-10-02 15:47:41 -0500 |
---|---|---|
committer | GitHub <noreply@github.com> | 2017-10-02 15:47:41 -0500 |
commit | c66598d28b7ffe8b8e30a58e9268db50dd109986 (patch) | |
tree | 246f534a435e0974032490ef67f74a16b45f825e | |
parent | 0c5f4e1ffa6da921ff07525fcd1a25623c782d0e (diff) | |
parent | 5f3bf1f0230d753edf198d9d4e1266b3c0756e2d (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.rs | 67 | ||||
-rw-r--r-- | src/ir/analysis/derive_copy.rs | 10 | ||||
-rw-r--r-- | src/ir/analysis/derive_debug.rs | 8 | ||||
-rw-r--r-- | src/ir/analysis/derive_default.rs | 12 | ||||
-rw-r--r-- | src/ir/analysis/derive_hash.rs | 23 | ||||
-rw-r--r-- | src/ir/analysis/derive_partial_eq_or_partial_ord.rs | 23 | ||||
-rw-r--r-- | src/ir/analysis/has_destructor.rs | 13 | ||||
-rw-r--r-- | src/ir/analysis/has_float.rs | 17 | ||||
-rw-r--r-- | src/ir/analysis/has_type_param_in_array.rs | 13 | ||||
-rw-r--r-- | src/ir/analysis/has_vtable.rs | 9 | ||||
-rw-r--r-- | src/ir/analysis/template_params.rs | 9 | ||||
-rw-r--r-- | src/ir/comp.rs | 101 | ||||
-rw-r--r-- | src/ir/context.rs | 422 | ||||
-rw-r--r-- | src/ir/enum_ty.rs | 8 | ||||
-rw-r--r-- | src/ir/function.rs | 32 | ||||
-rw-r--r-- | src/ir/item.rs | 169 | ||||
-rw-r--r-- | src/ir/module.rs | 4 | ||||
-rw-r--r-- | src/ir/template.rs | 28 | ||||
-rw-r--r-- | src/ir/ty.rs | 58 | ||||
-rw-r--r-- | src/ir/var.rs | 8 | ||||
-rw-r--r-- | src/parse.rs | 14 |
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(¶m.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; } |