summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/codegen/mod.rs13
-rw-r--r--src/ir/comp.rs21
-rw-r--r--src/ir/function.rs25
-rw-r--r--tests/expectations/tests/virtual_dtor.rs10
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)
- }
-}