Skip to content

Commit 11ffbd1

Browse files
committed
Refactor a bit and do not generate virtual destructors.
1 parent 43df048 commit 11ffbd1

File tree

4 files changed

+37
-32
lines changed

4 files changed

+37
-32
lines changed

src/codegen/mod.rs

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1599,10 +1599,14 @@ impl CodeGenerator for CompInfo {
15991599
}
16001600

16011601
if ctx.options().codegen_config.destructor {
1602-
if let Some(destructor) = *self.destructor() {
1603-
Method::new(MethodKind::Destructor,
1604-
destructor,
1605-
false)
1602+
if let Some((is_virtual, destructor)) = self.destructor() {
1603+
let kind = if is_virtual {
1604+
MethodKind::VirtualDestructor
1605+
} else {
1606+
MethodKind::Destructor
1607+
};
1608+
1609+
Method::new(kind, destructor, false)
16061610
.codegen_method(ctx,
16071611
&mut methods,
16081612
&mut method_names,
@@ -1707,6 +1711,7 @@ impl MethodCodegen for Method {
17071711
if self.is_virtual() {
17081712
return; // FIXME
17091713
}
1714+
17101715
// First of all, output the actual function.
17111716
let function_item = ctx.resolve_item(self.signature());
17121717
function_item.codegen(ctx, result, whitelisted_items, &());

src/ir/comp.rs

Lines changed: 13 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -26,8 +26,10 @@ pub enum MethodKind {
2626
/// A constructor. We represent it as method for convenience, to avoid code
2727
/// duplication.
2828
Constructor,
29-
/// A destructor method
29+
/// A destructor.
3030
Destructor,
31+
/// A virtual destructor.
32+
VirtualDestructor,
3133
/// A static method.
3234
Static,
3335
/// A normal method.
@@ -65,7 +67,8 @@ impl Method {
6567

6668
/// Is this a destructor method?
6769
pub fn is_destructor(&self) -> bool {
68-
self.kind == MethodKind::Destructor
70+
self.kind == MethodKind::Destructor ||
71+
self.kind == MethodKind::VirtualDestructor
6972
}
7073

7174
/// Is this a constructor?
@@ -75,7 +78,8 @@ impl Method {
7578

7679
/// Is this a virtual method?
7780
pub fn is_virtual(&self) -> bool {
78-
self.kind == MethodKind::Virtual
81+
self.kind == MethodKind::Virtual ||
82+
self.kind == MethodKind::VirtualDestructor
7983
}
8084

8185
/// Is this a static method?
@@ -257,8 +261,9 @@ pub struct CompInfo {
257261
/// The different constructors this struct or class contains.
258262
constructors: Vec<ItemId>,
259263

260-
/// The destructor of this type
261-
destructor: Option<ItemId>,
264+
/// The destructor of this type. The bool represents whether this destructor
265+
/// is virtual.
266+
destructor: Option<(bool, ItemId)>,
262267

263268
/// Vector of classes this one inherits from.
264269
base_members: Vec<Base>,
@@ -446,8 +451,8 @@ impl CompInfo {
446451
}
447452

448453
/// Get this type's destructor.
449-
pub fn destructor(&self) -> &Option<ItemId> {
450-
&self.destructor
454+
pub fn destructor(&self) -> Option<(bool, ItemId)> {
455+
self.destructor
451456
}
452457

453458
/// What kind of compound type is this?
@@ -674,7 +679,7 @@ impl CompInfo {
674679
ci.constructors.push(signature);
675680
}
676681
CXCursor_Destructor => {
677-
ci.destructor = Some(signature);
682+
ci.destructor = Some((is_virtual, signature));
678683
}
679684
CXCursor_CXXMethod => {
680685
let is_const = cur.method_is_const();

src/ir/function.rs

Lines changed: 15 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -326,18 +326,23 @@ impl ClangSubItemParser for Function {
326326
let sig =
327327
try!(Item::from_ty(&cursor.cur_type(), cursor, None, context));
328328

329-
let name = match cursor.kind() {
330-
CXCursor_Destructor => {
331-
let mut name_ = cursor.spelling();
332-
// remove the `~`
333-
name_.remove(0);
334-
name_ + "_destructor"
335-
},
336-
_ => cursor.spelling(),
337-
};
338-
329+
let mut name = cursor.spelling();
339330
assert!(!name.is_empty(), "Empty function name?");
340331

332+
if cursor.kind() == CXCursor_Destructor {
333+
// Remove the leading `~`. The alternative to this is special-casing
334+
// code-generation for destructor functions, which seems less than
335+
// ideal.
336+
if name.starts_with('~') {
337+
name.remove(0);
338+
}
339+
340+
// Add a suffix to avoid colliding with constructors. This would be
341+
// technically fine (since we handle duplicated functions/methods),
342+
// but seems easy enough to handle it here.
343+
name.push_str("_destructor");
344+
}
345+
341346
let mut mangled_name = cursor_mangling(context, &cursor);
342347
if mangled_name.as_ref() == Some(&name) {
343348
mangled_name = None;

tests/expectations/tests/virtual_dtor.rs

Lines changed: 0 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -18,16 +18,6 @@ fn bindgen_test_layout_nsSlots() {
1818
assert_eq! (::std::mem::align_of::<nsSlots>() , 8usize , concat ! (
1919
"Alignment of " , stringify ! ( nsSlots ) ));
2020
}
21-
extern "C" {
22-
#[link_name = "_ZN7nsSlotsD1Ev"]
23-
pub fn nsSlots_nsSlots_destructor(this: *mut nsSlots);
24-
}
2521
impl Default for nsSlots {
2622
fn default() -> Self { unsafe { ::std::mem::zeroed() } }
2723
}
28-
impl nsSlots {
29-
#[inline]
30-
pub unsafe fn __bindgen_destructor__(&mut self) {
31-
nsSlots_nsSlots_destructor(&mut *self)
32-
}
33-
}

0 commit comments

Comments
 (0)