diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/ir/analysis/has_vtable.rs | 4 | ||||
-rw-r--r-- | src/ir/comp.rs | 2 | ||||
-rw-r--r-- | src/ir/context.rs | 9 | ||||
-rw-r--r-- | src/ir/item.rs | 24 |
4 files changed, 31 insertions, 8 deletions
diff --git a/src/ir/analysis/has_vtable.rs b/src/ir/analysis/has_vtable.rs index 014d38b5..f3f2a695 100644 --- a/src/ir/analysis/has_vtable.rs +++ b/src/ir/analysis/has_vtable.rs @@ -242,4 +242,8 @@ impl<'ctx> From<HasVtableAnalysis<'ctx>> for HashMap<ItemId, HasVtableResult> { pub trait HasVtable { /// Return `true` if this thing has vtable, `false` otherwise. fn has_vtable(&self, ctx: &BindgenContext) -> bool; + + /// Return `true` if this thing has an actual vtable pointer in itself, as + /// opposed to transitively in a base member. + fn has_vtable_ptr(&self, ctx: &BindgenContext) -> bool; } diff --git a/src/ir/comp.rs b/src/ir/comp.rs index c77834ee..1227da1d 100644 --- a/src/ir/comp.rs +++ b/src/ir/comp.rs @@ -1012,7 +1012,7 @@ impl CompInfo { /// Is this compound type unsized? pub fn is_unsized(&self, ctx: &BindgenContext, id: TypeId) -> bool { - !ctx.lookup_has_vtable(id) && self.fields().is_empty() && + !id.has_vtable(ctx) && self.fields().is_empty() && self.base_members.iter().all(|base| { ctx.resolve_type(base.ty).canonical_type(ctx).is_unsized( ctx, diff --git a/src/ir/context.rs b/src/ir/context.rs index 112c4b5d..da692866 100644 --- a/src/ir/context.rs +++ b/src/ir/context.rs @@ -1267,7 +1267,7 @@ impl BindgenContext { } /// Look up whether the item with `id` has vtable or not. - pub fn lookup_has_vtable(&self, id: TypeId) -> bool { + pub fn lookup_has_vtable(&self, id: TypeId) -> HasVtableResult { assert!( self.in_codegen_phase(), "We only compute vtables when we enter codegen" @@ -1275,7 +1275,12 @@ 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_key(&id.into()) + self.have_vtable + .as_ref() + .unwrap() + .get(&id.into()) + .cloned() + .unwrap_or(HasVtableResult::No) } /// Compute whether the type has a destructor. diff --git a/src/ir/item.rs b/src/ir/item.rs index dbc352eb..ac50ef3b 100644 --- a/src/ir/item.rs +++ b/src/ir/item.rs @@ -1,6 +1,6 @@ //! Bindgen's core intermediate representation type. -use super::analysis::HasVtable; +use super::analysis::{HasVtable, HasVtableResult}; use super::annotations::Annotations; use super::comment; use super::comp::MethodKind; @@ -1001,15 +1001,29 @@ where fn has_vtable(&self, ctx: &BindgenContext) -> bool { let id: ItemId = (*self).into(); id.as_type_id(ctx) - .map_or(false, |id| ctx.lookup_has_vtable(id)) + .map_or(false, |id| match ctx.lookup_has_vtable(id) { + HasVtableResult::No => false, + _ => true, + }) + } + + fn has_vtable_ptr(&self, ctx: &BindgenContext) -> bool { + let id: ItemId = (*self).into(); + id.as_type_id(ctx) + .map_or(false, |id| match ctx.lookup_has_vtable(id) { + HasVtableResult::SelfHasVtable => true, + _ => false, + }) } } impl HasVtable for Item { fn has_vtable(&self, ctx: &BindgenContext) -> bool { - self.id() - .as_type_id(ctx) - .map_or(false, |id| ctx.lookup_has_vtable(id)) + self.id().has_vtable(ctx) + } + + fn has_vtable_ptr(&self, ctx: &BindgenContext) -> bool { + self.id().has_vtable_ptr(ctx) } } |