diff options
author | Nikhil Shagrithaya <nikhilshagri@gmail.com> | 2017-02-27 16:01:15 +0530 |
---|---|---|
committer | Emilio Cobos Álvarez <emilio@crisal.io> | 2017-04-04 01:05:34 +0200 |
commit | 1714f947e062a7b90ebda71d190daccba87ab32d (patch) | |
tree | 22b835655de2263098f7d4f5d08f9d8f90b96bcd | |
parent | 8f1e5f5ad4fff230b06cdfca868266a28ada3881 (diff) |
Add codegen for destructors.
-rw-r--r-- | src/codegen/mod.rs | 15 | ||||
-rw-r--r-- | src/ir/comp.rs | 21 | ||||
-rw-r--r-- | src/ir/function.rs | 18 | ||||
-rw-r--r-- | src/lib.rs | 4 | ||||
-rw-r--r-- | tests/expectations/tests/public-dtor.rs | 10 | ||||
-rw-r--r-- | tests/expectations/tests/union_dtor.rs | 10 | ||||
-rw-r--r-- | tests/expectations/tests/virtual_dtor.rs | 10 |
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); @@ -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) + } +} |