diff options
-rw-r--r-- | src/codegen/mod.rs | 13 | ||||
-rw-r--r-- | src/ir/comp.rs | 21 | ||||
-rw-r--r-- | src/ir/function.rs | 25 | ||||
-rw-r--r-- | tests/expectations/tests/virtual_dtor.rs | 10 |
4 files changed, 37 insertions, 32 deletions
diff --git a/src/codegen/mod.rs b/src/codegen/mod.rs index d1523273..78b2e02a 100644 --- a/src/codegen/mod.rs +++ b/src/codegen/mod.rs @@ -1599,10 +1599,14 @@ impl CodeGenerator for CompInfo { } if ctx.options().codegen_config.destructor { - if let Some(destructor) = *self.destructor() { - Method::new(MethodKind::Destructor, - destructor, - false) + if let Some((is_virtual, destructor)) = self.destructor() { + let kind = if is_virtual { + MethodKind::VirtualDestructor + } else { + MethodKind::Destructor + }; + + Method::new(kind, destructor, false) .codegen_method(ctx, &mut methods, &mut method_names, @@ -1707,6 +1711,7 @@ impl MethodCodegen for Method { if self.is_virtual() { return; // FIXME } + // First of all, output the actual function. let function_item = ctx.resolve_item(self.signature()); function_item.codegen(ctx, result, whitelisted_items, &()); diff --git a/src/ir/comp.rs b/src/ir/comp.rs index 44e70058..2c7b6de2 100644 --- a/src/ir/comp.rs +++ b/src/ir/comp.rs @@ -26,8 +26,10 @@ pub enum MethodKind { /// A constructor. We represent it as method for convenience, to avoid code /// duplication. Constructor, - /// A destructor method + /// A destructor. Destructor, + /// A virtual destructor. + VirtualDestructor, /// A static method. Static, /// A normal method. @@ -65,7 +67,8 @@ impl Method { /// Is this a destructor method? pub fn is_destructor(&self) -> bool { - self.kind == MethodKind::Destructor + self.kind == MethodKind::Destructor || + self.kind == MethodKind::VirtualDestructor } /// Is this a constructor? @@ -75,7 +78,8 @@ impl Method { /// Is this a virtual method? pub fn is_virtual(&self) -> bool { - self.kind == MethodKind::Virtual + self.kind == MethodKind::Virtual || + self.kind == MethodKind::VirtualDestructor } /// Is this a static method? @@ -257,8 +261,9 @@ pub struct CompInfo { /// The different constructors this struct or class contains. constructors: Vec<ItemId>, - /// The destructor of this type - destructor: Option<ItemId>, + /// The destructor of this type. The bool represents whether this destructor + /// is virtual. + destructor: Option<(bool, ItemId)>, /// Vector of classes this one inherits from. base_members: Vec<Base>, @@ -446,8 +451,8 @@ impl CompInfo { } /// Get this type's destructor. - pub fn destructor(&self) -> &Option<ItemId> { - &self.destructor + pub fn destructor(&self) -> Option<(bool, ItemId)> { + self.destructor } /// What kind of compound type is this? @@ -674,7 +679,7 @@ impl CompInfo { ci.constructors.push(signature); } CXCursor_Destructor => { - ci.destructor = Some(signature); + ci.destructor = Some((is_virtual, signature)); } CXCursor_CXXMethod => { let is_const = cur.method_is_const(); diff --git a/src/ir/function.rs b/src/ir/function.rs index 163226e3..f80a5736 100644 --- a/src/ir/function.rs +++ b/src/ir/function.rs @@ -354,18 +354,23 @@ impl ClangSubItemParser for Function { let sig = try!(Item::from_ty(&cursor.cur_type(), cursor, None, context)); - let name = match cursor.kind() { - CXCursor_Destructor => { - let mut name_ = cursor.spelling(); - // remove the `~` - name_.remove(0); - name_ + "_destructor" - }, - _ => cursor.spelling(), - }; - + let mut name = cursor.spelling(); assert!(!name.is_empty(), "Empty function name?"); + if cursor.kind() == CXCursor_Destructor { + // Remove the leading `~`. The alternative to this is special-casing + // code-generation for destructor functions, which seems less than + // ideal. + if name.starts_with('~') { + name.remove(0); + } + + // Add a suffix to avoid colliding with constructors. This would be + // technically fine (since we handle duplicated functions/methods), + // but seems easy enough to handle it here. + name.push_str("_destructor"); + } + let mut mangled_name = cursor_mangling(context, &cursor); if mangled_name.as_ref() == Some(&name) { mangled_name = None; diff --git a/tests/expectations/tests/virtual_dtor.rs b/tests/expectations/tests/virtual_dtor.rs index a84da693..e5d3ace2 100644 --- a/tests/expectations/tests/virtual_dtor.rs +++ b/tests/expectations/tests/virtual_dtor.rs @@ -18,16 +18,6 @@ fn bindgen_test_layout_nsSlots() { assert_eq! (::std::mem::align_of::<nsSlots>() , 8usize , concat ! ( "Alignment of " , stringify ! ( nsSlots ) )); } -extern "C" { - #[link_name = "_ZN7nsSlotsD1Ev"] - pub fn nsSlots_nsSlots_destructor(this: *mut nsSlots); -} impl Default for nsSlots { fn default() -> Self { unsafe { ::std::mem::zeroed() } } } -impl nsSlots { - #[inline] - pub unsafe fn __bindgen_destructor__(&mut self) { - nsSlots_nsSlots_destructor(&mut *self) - } -} |