Skip to content

Commit 29f199c

Browse files
committed
Added codegen for destructors
1 parent d57616c commit 29f199c

File tree

7 files changed

+76
-5
lines changed

7 files changed

+76
-5
lines changed

src/codegen/mod.rs

+19
Original file line numberDiff line numberDiff line change
@@ -1456,6 +1456,20 @@ impl CodeGenerator for CompInfo {
14561456
self);
14571457
}
14581458
}
1459+
1460+
if ctx.options().codegen_config.destructor {
1461+
if let Some(destructor) = *self.destructor() {
1462+
Method::new(MethodKind::Destructor,
1463+
destructor,
1464+
false)
1465+
.codegen_method(ctx,
1466+
&mut methods,
1467+
&mut method_names,
1468+
result,
1469+
whitelisted_items,
1470+
self);
1471+
}
1472+
}
14591473
}
14601474

14611475
// NB: We can't use to_rust_ty here since for opaque types this tries to
@@ -1560,6 +1574,11 @@ impl MethodCodegen for Method {
15601574
let signature_item = ctx.resolve_item(function.signature());
15611575
let mut name = match self.kind() {
15621576
MethodKind::Constructor => "new".into(),
1577+
MethodKind::Destructor => {
1578+
let mut prefix = "_bindgen_destructor_".to_owned();
1579+
prefix.push_str(function.name().trim_left_matches('~'));
1580+
prefix
1581+
},
15631582
_ => function.name().to_owned(),
15641583
};
15651584

src/ir/comp.rs

+19-2
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
@@ -729,8 +745,9 @@ impl CompInfo {
729745
CXCursor_Constructor => {
730746
ci.constructors.push(signature);
731747
}
732-
// TODO(emilio): Bind the destructor?
733-
CXCursor_Destructor => {}
748+
CXCursor_Destructor => {
749+
ci.destructor = Some(signature);
750+
}
734751
CXCursor_CXXMethod => {
735752
let is_const = cur.method_is_const();
736753
let method_kind = if is_static {

src/ir/function.rs

+4-3
Original file line numberDiff line numberDiff line change
@@ -217,13 +217,14 @@ impl FunctionSig {
217217

218218
let is_method = cursor.kind() == CXCursor_CXXMethod;
219219
let is_constructor = cursor.kind() == CXCursor_Constructor;
220-
if (is_constructor || is_method) &&
220+
let is_destructor = cursor.kind() == CXCursor_Destructor;
221+
if (is_constructor || is_destructor || is_method) &&
221222
cursor.lexical_parent() != cursor.semantic_parent() {
222223
// Only parse constructors once.
223224
return Err(ParseError::Continue);
224225
}
225226

226-
if is_method || is_constructor {
227+
if is_method || is_constructor || is_destructor {
227228
let is_const = is_method && cursor.method_is_const();
228229
let is_virtual = is_method && cursor.method_is_virtual();
229230
let is_static = is_method && cursor.method_is_static();
@@ -288,9 +289,9 @@ impl ClangSubItemParser for Function {
288289
-> Result<ParseResult<Self>, ParseError> {
289290
use clang_sys::*;
290291
match cursor.kind() {
291-
// FIXME(emilio): Generate destructors properly.
292292
CXCursor_FunctionDecl |
293293
CXCursor_Constructor |
294+
CXCursor_Destructor |
294295
CXCursor_CXXMethod => {}
295296
_ => return Err(ParseError::Continue),
296297
};

src/lib.rs

+4
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

+10
Original file line numberDiff line numberDiff line change
@@ -16,3 +16,13 @@ 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 _bindgen_destructor_String(&mut self) {
26+
cv_String_~String(&mut *self)
27+
}
28+
}

tests/expectations/tests/union_dtor.rs

+10
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 _bindgen_destructor_UnionWithDtor(&mut self) {
62+
UnionWithDtor_~UnionWithDtor(&mut *self)
63+
}
64+
}

tests/expectations/tests/virtual_dtor.rs

+10
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,16 @@ 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 _bindgen_destructor_nsSlots(&mut self) {
33+
nsSlots_~nsSlots(&mut *self)
34+
}
35+
}

0 commit comments

Comments
 (0)