Skip to content

Commit e73dda4

Browse files
committed
Added codegen for destructors
1 parent 31c9132 commit e73dda4

File tree

7 files changed

+68
-5
lines changed

7 files changed

+68
-5
lines changed

src/codegen/mod.rs

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1453,6 +1453,20 @@ impl CodeGenerator for CompInfo {
14531453
self);
14541454
}
14551455
}
1456+
1457+
if ctx.options().codegen_config.destructor {
1458+
if let Some(destructor) = *self.destructor() {
1459+
Method::new(MethodKind::Destructor,
1460+
destructor,
1461+
false)
1462+
.codegen_method(ctx,
1463+
&mut methods,
1464+
&mut method_names,
1465+
result,
1466+
whitelisted_items,
1467+
self);
1468+
}
1469+
}
14561470
}
14571471

14581472
// NB: We can't use to_rust_ty here since for opaque types this tries to
@@ -1557,6 +1571,7 @@ impl MethodCodegen for Method {
15571571
let signature_item = ctx.resolve_item(function.signature());
15581572
let mut name = match self.kind() {
15591573
MethodKind::Constructor => "new".into(),
1574+
MethodKind::Destructor => "destruct".into(),
15601575
_ => function.name().to_owned(),
15611576
};
15621577

src/ir/comp.rs

Lines changed: 19 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,8 @@ pub enum MethodKind {
2626
/// A constructor. We represent it as method for convenience, to avoid code
2727
/// duplication.
2828
Constructor,
29+
/// A destructor method
30+
Destructor,
2931
/// A static method.
3032
Static,
3133
/// A normal method.
@@ -61,6 +63,11 @@ impl Method {
6163
self.kind
6264
}
6365

66+
/// Is this a destructor method?
67+
pub fn is_destructor(&self) -> bool {
68+
self.kind == MethodKind::Destructor
69+
}
70+
6471
/// Is this a constructor?
6572
pub fn is_constructor(&self) -> bool {
6673
self.kind == MethodKind::Constructor
@@ -249,6 +256,9 @@ pub struct CompInfo {
249256
/// The different constructors this struct or class contains.
250257
constructors: Vec<ItemId>,
251258

259+
/// The destructor of this type
260+
destructor: Option<ItemId>,
261+
252262
/// Vector of classes this one inherits from.
253263
base_members: Vec<Base>,
254264

@@ -323,6 +333,7 @@ impl CompInfo {
323333
template_args: vec![],
324334
methods: vec![],
325335
constructors: vec![],
336+
destructor: None,
326337
base_members: vec![],
327338
ref_template: None,
328339
inner_types: vec![],
@@ -468,6 +479,11 @@ impl CompInfo {
468479
&self.constructors
469480
}
470481

482+
/// Get this type's destructor.
483+
pub fn destructor(&self) -> &Option<ItemId> {
484+
&self.destructor
485+
}
486+
471487
/// What kind of compound type is this?
472488
pub fn kind(&self) -> CompKind {
473489
self.kind
@@ -718,8 +734,9 @@ impl CompInfo {
718734
CXCursor_Constructor => {
719735
ci.constructors.push(signature);
720736
}
721-
// TODO(emilio): Bind the destructor?
722-
CXCursor_Destructor => {}
737+
CXCursor_Destructor => {
738+
ci.destructor = Some(signature);
739+
}
723740
CXCursor_CXXMethod => {
724741
let is_const = cur.method_is_const();
725742
let method_kind = if is_static {

src/ir/function.rs

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -210,13 +210,14 @@ impl FunctionSig {
210210

211211
let is_method = cursor.kind() == CXCursor_CXXMethod;
212212
let is_constructor = cursor.kind() == CXCursor_Constructor;
213-
if (is_constructor || is_method) &&
213+
let is_destructor = cursor.kind() == CXCursor_Destructor;
214+
if (is_constructor || is_destructor || is_method) &&
214215
cursor.lexical_parent() != cursor.semantic_parent() {
215216
// Only parse constructors once.
216217
return Err(ParseError::Continue);
217218
}
218219

219-
if is_method || is_constructor {
220+
if is_method || is_constructor || is_destructor {
220221
let is_const = is_method && cursor.method_is_const();
221222
let is_virtual = is_method && cursor.method_is_virtual();
222223
let is_static = is_method && cursor.method_is_static();
@@ -281,9 +282,9 @@ impl ClangSubItemParser for Function {
281282
-> Result<ParseResult<Self>, ParseError> {
282283
use clang_sys::*;
283284
match cursor.kind() {
284-
// FIXME(emilio): Generate destructors properly.
285285
CXCursor_FunctionDecl |
286286
CXCursor_Constructor |
287+
CXCursor_Destructor |
287288
CXCursor_CXXMethod => {}
288289
_ => return Err(ParseError::Continue),
289290
};

src/lib.rs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -109,6 +109,8 @@ pub struct CodegenConfig {
109109
pub methods: bool,
110110
/// Whether to generate constructors.
111111
pub constructors: bool,
112+
/// Whether to generate a destructor.
113+
pub destructor: bool,
112114
}
113115

114116
impl CodegenConfig {
@@ -120,6 +122,7 @@ impl CodegenConfig {
120122
vars: true,
121123
methods: true,
122124
constructors: true,
125+
destructor: true,
123126
}
124127
}
125128

@@ -131,6 +134,7 @@ impl CodegenConfig {
131134
vars: false,
132135
methods: false,
133136
constructors: false,
137+
destructor: false,
134138
}
135139
}
136140
}

tests/expectations/tests/public-dtor.rs

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,3 +16,11 @@ fn bindgen_test_layout_cv_String() {
1616
assert_eq! (::std::mem::align_of::<cv_String>() , 1usize , concat ! (
1717
"Alignment of " , stringify ! ( cv_String ) ));
1818
}
19+
extern "C" {
20+
#[link_name = "_ZN2cv6StringD1Ev"]
21+
pub fn cv_String_~String(this: *mut cv_String);
22+
}
23+
impl cv_String {
24+
#[inline]
25+
pub unsafe fn destruct(&mut self) { cv_String_~String(&mut *self) }
26+
}

tests/expectations/tests/union_dtor.rs

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -52,3 +52,13 @@ fn bindgen_test_layout_UnionWithDtor() {
5252
"Alignment of field: " , stringify ! ( UnionWithDtor ) , "::"
5353
, stringify ! ( mBar ) ));
5454
}
55+
extern "C" {
56+
#[link_name = "_ZN13UnionWithDtorD1Ev"]
57+
pub fn UnionWithDtor_~UnionWithDtor(this: *mut UnionWithDtor);
58+
}
59+
impl UnionWithDtor {
60+
#[inline]
61+
pub unsafe fn destruct(&mut self) {
62+
UnionWithDtor_~UnionWithDtor(&mut *self)
63+
}
64+
}

tests/expectations/tests/virtual_dtor.rs

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,14 @@ fn bindgen_test_layout_nsSlots() {
2020
assert_eq! (::std::mem::align_of::<nsSlots>() , 8usize , concat ! (
2121
"Alignment of " , stringify ! ( nsSlots ) ));
2222
}
23+
extern "C" {
24+
#[link_name = "_ZN7nsSlotsD1Ev"]
25+
pub fn nsSlots_~nsSlots(this: *mut nsSlots);
26+
}
2327
impl Default for nsSlots {
2428
fn default() -> Self { unsafe { ::std::mem::zeroed() } }
2529
}
30+
impl nsSlots {
31+
#[inline]
32+
pub unsafe fn destruct(&mut self) { nsSlots_~nsSlots(&mut *self) }
33+
}

0 commit comments

Comments
 (0)