summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNikhil Shagrithaya <nikhilshagri@gmail.com>2017-02-27 16:01:15 +0530
committerEmilio Cobos Álvarez <emilio@crisal.io>2017-04-04 01:05:34 +0200
commit1714f947e062a7b90ebda71d190daccba87ab32d (patch)
tree22b835655de2263098f7d4f5d08f9d8f90b96bcd
parent8f1e5f5ad4fff230b06cdfca868266a28ada3881 (diff)
Add codegen for destructors.
-rw-r--r--src/codegen/mod.rs15
-rw-r--r--src/ir/comp.rs21
-rw-r--r--src/ir/function.rs18
-rw-r--r--src/lib.rs4
-rw-r--r--tests/expectations/tests/public-dtor.rs10
-rw-r--r--tests/expectations/tests/union_dtor.rs10
-rw-r--r--tests/expectations/tests/virtual_dtor.rs10
7 files changed, 82 insertions, 6 deletions
diff --git a/src/codegen/mod.rs b/src/codegen/mod.rs
index fb6c839d..d1523273 100644
--- a/src/codegen/mod.rs
+++ b/src/codegen/mod.rs
@@ -1597,6 +1597,20 @@ impl CodeGenerator for CompInfo {
self);
}
}
+
+ if ctx.options().codegen_config.destructor {
+ if let Some(destructor) = *self.destructor() {
+ Method::new(MethodKind::Destructor,
+ destructor,
+ false)
+ .codegen_method(ctx,
+ &mut methods,
+ &mut method_names,
+ result,
+ whitelisted_items,
+ self);
+ }
+ }
}
// NB: We can't use to_rust_ty here since for opaque types this tries to
@@ -1701,6 +1715,7 @@ impl MethodCodegen for Method {
let signature_item = ctx.resolve_item(function.signature());
let mut name = match self.kind() {
MethodKind::Constructor => "new".into(),
+ MethodKind::Destructor => "__bindgen_destructor__".into(),
_ => function.name().to_owned(),
};
diff --git a/src/ir/comp.rs b/src/ir/comp.rs
index 9a6548a7..44e70058 100644
--- a/src/ir/comp.rs
+++ b/src/ir/comp.rs
@@ -26,6 +26,8 @@ pub enum MethodKind {
/// A constructor. We represent it as method for convenience, to avoid code
/// duplication.
Constructor,
+ /// A destructor method
+ Destructor,
/// A static method.
Static,
/// A normal method.
@@ -61,6 +63,11 @@ impl Method {
self.kind
}
+ /// Is this a destructor method?
+ pub fn is_destructor(&self) -> bool {
+ self.kind == MethodKind::Destructor
+ }
+
/// Is this a constructor?
pub fn is_constructor(&self) -> bool {
self.kind == MethodKind::Constructor
@@ -250,6 +257,9 @@ pub struct CompInfo {
/// The different constructors this struct or class contains.
constructors: Vec<ItemId>,
+ /// The destructor of this type
+ destructor: Option<ItemId>,
+
/// Vector of classes this one inherits from.
base_members: Vec<Base>,
@@ -321,6 +331,7 @@ impl CompInfo {
template_params: vec![],
methods: vec![],
constructors: vec![],
+ destructor: None,
base_members: vec![],
inner_types: vec![],
inner_vars: vec![],
@@ -434,6 +445,11 @@ impl CompInfo {
&self.constructors
}
+ /// Get this type's destructor.
+ pub fn destructor(&self) -> &Option<ItemId> {
+ &self.destructor
+ }
+
/// What kind of compound type is this?
pub fn kind(&self) -> CompKind {
self.kind
@@ -657,8 +673,9 @@ impl CompInfo {
CXCursor_Constructor => {
ci.constructors.push(signature);
}
- // TODO(emilio): Bind the destructor?
- CXCursor_Destructor => {}
+ CXCursor_Destructor => {
+ ci.destructor = Some(signature);
+ }
CXCursor_CXXMethod => {
let is_const = cur.method_is_const();
let method_kind = if is_static {
diff --git a/src/ir/function.rs b/src/ir/function.rs
index 2c588fdd..163226e3 100644
--- a/src/ir/function.rs
+++ b/src/ir/function.rs
@@ -248,13 +248,14 @@ impl FunctionSig {
let is_method = cursor.kind() == CXCursor_CXXMethod;
let is_constructor = cursor.kind() == CXCursor_Constructor;
- if (is_constructor || is_method) &&
+ let is_destructor = cursor.kind() == CXCursor_Destructor;
+ if (is_constructor || is_destructor || is_method) &&
cursor.lexical_parent() != cursor.semantic_parent() {
// Only parse constructors once.
return Err(ParseError::Continue);
}
- if is_method || is_constructor {
+ if is_method || is_constructor || is_destructor {
let is_const = is_method && cursor.method_is_const();
let is_virtual = is_method && cursor.method_is_virtual();
let is_static = is_method && cursor.method_is_static();
@@ -320,9 +321,9 @@ impl ClangSubItemParser for Function {
-> Result<ParseResult<Self>, ParseError> {
use clang_sys::*;
match cursor.kind() {
- // FIXME(emilio): Generate destructors properly.
CXCursor_FunctionDecl |
CXCursor_Constructor |
+ CXCursor_Destructor |
CXCursor_CXXMethod => {}
_ => return Err(ParseError::Continue),
};
@@ -353,7 +354,16 @@ impl ClangSubItemParser for Function {
let sig =
try!(Item::from_ty(&cursor.cur_type(), cursor, None, context));
- let name = cursor.spelling();
+ let name = match cursor.kind() {
+ CXCursor_Destructor => {
+ let mut name_ = cursor.spelling();
+ // remove the `~`
+ name_.remove(0);
+ name_ + "_destructor"
+ },
+ _ => cursor.spelling(),
+ };
+
assert!(!name.is_empty(), "Empty function name?");
let mut mangled_name = cursor_mangling(context, &cursor);
diff --git a/src/lib.rs b/src/lib.rs
index eccf80e3..8ee16534 100644
--- a/src/lib.rs
+++ b/src/lib.rs
@@ -109,6 +109,8 @@ pub struct CodegenConfig {
pub methods: bool,
/// Whether to generate constructors.
pub constructors: bool,
+ /// Whether to generate a destructor.
+ pub destructor: bool,
}
impl CodegenConfig {
@@ -120,6 +122,7 @@ impl CodegenConfig {
vars: true,
methods: true,
constructors: true,
+ destructor: true,
}
}
@@ -131,6 +134,7 @@ impl CodegenConfig {
vars: false,
methods: false,
constructors: false,
+ destructor: false,
}
}
}
diff --git a/tests/expectations/tests/public-dtor.rs b/tests/expectations/tests/public-dtor.rs
index 1accf49c..0412b9f4 100644
--- a/tests/expectations/tests/public-dtor.rs
+++ b/tests/expectations/tests/public-dtor.rs
@@ -16,3 +16,13 @@ fn bindgen_test_layout_cv_String() {
assert_eq! (::std::mem::align_of::<cv_String>() , 1usize , concat ! (
"Alignment of " , stringify ! ( cv_String ) ));
}
+extern "C" {
+ #[link_name = "_ZN2cv6StringD1Ev"]
+ pub fn cv_String_String_destructor(this: *mut cv_String);
+}
+impl cv_String {
+ #[inline]
+ pub unsafe fn __bindgen_destructor__(&mut self) {
+ cv_String_String_destructor(&mut *self)
+ }
+}
diff --git a/tests/expectations/tests/union_dtor.rs b/tests/expectations/tests/union_dtor.rs
index bfd573e0..1bcb45b6 100644
--- a/tests/expectations/tests/union_dtor.rs
+++ b/tests/expectations/tests/union_dtor.rs
@@ -52,3 +52,13 @@ fn bindgen_test_layout_UnionWithDtor() {
"Alignment of field: " , stringify ! ( UnionWithDtor ) , "::"
, stringify ! ( mBar ) ));
}
+extern "C" {
+ #[link_name = "_ZN13UnionWithDtorD1Ev"]
+ pub fn UnionWithDtor_UnionWithDtor_destructor(this: *mut UnionWithDtor);
+}
+impl UnionWithDtor {
+ #[inline]
+ pub unsafe fn __bindgen_destructor__(&mut self) {
+ UnionWithDtor_UnionWithDtor_destructor(&mut *self)
+ }
+}
diff --git a/tests/expectations/tests/virtual_dtor.rs b/tests/expectations/tests/virtual_dtor.rs
index e5d3ace2..a84da693 100644
--- a/tests/expectations/tests/virtual_dtor.rs
+++ b/tests/expectations/tests/virtual_dtor.rs
@@ -18,6 +18,16 @@ 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)
+ }
+}