diff options
45 files changed, 485 insertions, 83 deletions
diff --git a/bindgen-integration/cpp/Test.cc b/bindgen-integration/cpp/Test.cc index 1d962406..7b0ec4ad 100644 --- a/bindgen-integration/cpp/Test.cc +++ b/bindgen-integration/cpp/Test.cc @@ -21,6 +21,15 @@ Test::Test(double foo) , m_double(foo) {} +AutoRestoreBool::AutoRestoreBool(bool* ptr) + : m_ptr(ptr) + , m_value(*ptr) +{} + +AutoRestoreBool::~AutoRestoreBool() { + *m_ptr = m_value; +} + namespace bitfields { bool @@ -47,4 +56,4 @@ Third::assert(int first, bool second, ItemKind third) kind == third; } -} +} // namespace bitfields diff --git a/bindgen-integration/cpp/Test.h b/bindgen-integration/cpp/Test.h index 310478bb..01c7aea1 100644 --- a/bindgen-integration/cpp/Test.h +++ b/bindgen-integration/cpp/Test.h @@ -64,3 +64,11 @@ struct Third { }; } // namespace bitfields + +struct AutoRestoreBool { + bool* m_ptr; + bool m_value; + + AutoRestoreBool(bool*); + ~AutoRestoreBool(); +}; diff --git a/bindgen-integration/src/lib.rs b/bindgen-integration/src/lib.rs index 8d7eb753..be3c8451 100755 --- a/bindgen-integration/src/lib.rs +++ b/bindgen-integration/src/lib.rs @@ -101,3 +101,21 @@ fn test_bitfields_third() { bindings::bitfields::ItemKind::ITEM_KIND_TRES) }); } + +impl Drop for bindings::AutoRestoreBool { + fn drop(&mut self) { + unsafe { bindings::AutoRestoreBool::destruct(self) } + } +} + +#[test] +fn test_destructors() { + let mut v = true; + + { + let auto_restore = unsafe { bindings::AutoRestoreBool::new(&mut v) }; + v = false; + } + + assert!(v, "Should've been restored when going out of scope"); +} diff --git a/src/codegen/mod.rs b/src/codegen/mod.rs index fb6c839d..ee4a9d4e 100644 --- a/src/codegen/mod.rs +++ b/src/codegen/mod.rs @@ -1597,6 +1597,24 @@ impl CodeGenerator for CompInfo { self); } } + + if ctx.options().codegen_config.destructors { + if let Some((is_virtual, destructor)) = self.destructor() { + let kind = if is_virtual { + MethodKind::VirtualDestructor + } else { + MethodKind::Destructor + }; + + Method::new(kind, 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 @@ -1693,6 +1711,7 @@ impl MethodCodegen for Method { if self.is_virtual() { return; // FIXME } + // First of all, output the actual function. let function_item = ctx.resolve_item(self.signature()); function_item.codegen(ctx, result, whitelisted_items, &()); @@ -1701,6 +1720,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 => "destruct".into(), _ => function.name().to_owned(), }; @@ -1801,11 +1821,7 @@ impl MethodCodegen for Method { exprs[0] = quote_expr!(ctx.ext_cx(), &mut __bindgen_tmp); } else if !self.is_static() { assert!(!exprs.is_empty()); - exprs[0] = if self.is_const() { - quote_expr!(ctx.ext_cx(), &*self) - } else { - quote_expr!(ctx.ext_cx(), &mut *self) - }; + exprs[0] = quote_expr!(ctx.ext_cx(), self); }; let call = aster::expr::ExprBuilder::new() @@ -2455,7 +2471,8 @@ impl TryToRustTy for Type { TypeKind::Int(ik) => { match ik { IntKind::Bool => Ok(aster::ty::TyBuilder::new().bool()), - IntKind::Char => Ok(raw_type(ctx, "c_schar")), + IntKind::Char { .. } => Ok(raw_type(ctx, "c_char")), + IntKind::SChar => Ok(raw_type(ctx, "c_schar")), IntKind::UChar => Ok(raw_type(ctx, "c_uchar")), IntKind::Short => Ok(raw_type(ctx, "c_short")), IntKind::UShort => Ok(raw_type(ctx, "c_ushort")), diff --git a/src/ir/comp.rs b/src/ir/comp.rs index 9a6548a7..2c7b6de2 100644 --- a/src/ir/comp.rs +++ b/src/ir/comp.rs @@ -26,6 +26,10 @@ pub enum MethodKind { /// A constructor. We represent it as method for convenience, to avoid code /// duplication. Constructor, + /// A destructor. + Destructor, + /// A virtual destructor. + VirtualDestructor, /// A static method. Static, /// A normal method. @@ -61,6 +65,12 @@ impl Method { self.kind } + /// Is this a destructor method? + pub fn is_destructor(&self) -> bool { + self.kind == MethodKind::Destructor || + self.kind == MethodKind::VirtualDestructor + } + /// Is this a constructor? pub fn is_constructor(&self) -> bool { self.kind == MethodKind::Constructor @@ -68,7 +78,8 @@ impl Method { /// Is this a virtual method? pub fn is_virtual(&self) -> bool { - self.kind == MethodKind::Virtual + self.kind == MethodKind::Virtual || + self.kind == MethodKind::VirtualDestructor } /// Is this a static method? @@ -250,6 +261,10 @@ pub struct CompInfo { /// The different constructors this struct or class contains. constructors: Vec<ItemId>, + /// The destructor of this type. The bool represents whether this destructor + /// is virtual. + destructor: Option<(bool, ItemId)>, + /// Vector of classes this one inherits from. base_members: Vec<Base>, @@ -321,6 +336,7 @@ impl CompInfo { template_params: vec![], methods: vec![], constructors: vec![], + destructor: None, base_members: vec![], inner_types: vec![], inner_vars: vec![], @@ -434,6 +450,11 @@ impl CompInfo { &self.constructors } + /// Get this type's destructor. + pub fn destructor(&self) -> Option<(bool, ItemId)> { + self.destructor + } + /// What kind of compound type is this? pub fn kind(&self) -> CompKind { self.kind @@ -657,8 +678,9 @@ impl CompInfo { CXCursor_Constructor => { ci.constructors.push(signature); } - // TODO(emilio): Bind the destructor? - CXCursor_Destructor => {} + CXCursor_Destructor => { + ci.destructor = Some((is_virtual, signature)); + } CXCursor_CXXMethod => { let is_const = cur.method_is_const(); let method_kind = if is_static { diff --git a/src/ir/context.rs b/src/ir/context.rs index 6c11f7f9..32ee5bd0 100644 --- a/src/ir/context.rs +++ b/src/ir/context.rs @@ -1094,8 +1094,10 @@ impl<'ctx> BindgenContext<'ctx> { CXType_Bool => TypeKind::Int(IntKind::Bool), CXType_Int => TypeKind::Int(IntKind::Int), CXType_UInt => TypeKind::Int(IntKind::UInt), - CXType_SChar | CXType_Char_S => TypeKind::Int(IntKind::Char), - CXType_UChar | CXType_Char_U => TypeKind::Int(IntKind::UChar), + CXType_Char_S => TypeKind::Int(IntKind::Char { is_signed: true }), + CXType_Char_U => TypeKind::Int(IntKind::Char { is_signed: false }), + CXType_SChar => TypeKind::Int(IntKind::SChar), + CXType_UChar => TypeKind::Int(IntKind::UChar), CXType_Short => TypeKind::Int(IntKind::Short), CXType_UShort => TypeKind::Int(IntKind::UShort), CXType_WChar | CXType_Char16 => TypeKind::Int(IntKind::U16), diff --git a/src/ir/function.rs b/src/ir/function.rs index fd88b657..0809b3c2 100644 --- a/src/ir/function.rs +++ b/src/ir/function.rs @@ -114,6 +114,7 @@ fn get_abi(cc: CXCallingConv) -> Option<abi::Abi> { pub fn cursor_mangling(ctx: &BindgenContext, cursor: &clang::Cursor) -> Option<String> { + use clang_sys; if !ctx.options().enable_mangling { return None; } @@ -131,10 +132,40 @@ pub fn cursor_mangling(ctx: &BindgenContext, } // Try to undo backend linkage munging (prepended _, generally) + // + // TODO(emilio): This is wrong when the target system is not the host + // system. See https://github.com/servo/rust-bindgen/issues/593 if cfg!(target_os = "macos") { mangling.remove(0); } + if cursor.kind() == clang_sys::CXCursor_Destructor { + // With old (3.8-) libclang versions, and the Itanium ABI, clang returns + // the "destructor group 0" symbol, which means that it'll try to free + // memory, which definitely isn't what we want. + // + // Explicitly force the destructor group 1 symbol. + // + // See http://refspecs.linuxbase.org/cxxabi-1.83.html#mangling-special + // for the reference, and http://stackoverflow.com/a/6614369/1091587 for + // a more friendly explanation. + // + // We don't need to do this for constructors since clang seems to always + // have returned the C1 constructor. + // + // FIXME(emilio): Can a legit symbol in other ABIs end with this string? + // I don't think so, but if it can this would become a linker error + // anyway, not an invalid free at runtime. + // + // TODO(emilio, #611): Use cpp_demangle if this becomes nastier with + // time. + if mangling.ends_with("D0Ev") { + let new_len = mangling.len() - 4; + mangling.truncate(new_len); + mangling.push_str("D1Ev"); + } + } + Some(mangling) } @@ -220,13 +251,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(); @@ -292,9 +324,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), }; @@ -325,9 +357,23 @@ impl ClangSubItemParser for Function { let sig = try!(Item::from_ty(&cursor.cur_type(), cursor, None, context)); - let name = cursor.spelling(); + let mut name = cursor.spelling(); assert!(!name.is_empty(), "Empty function name?"); + if cursor.kind() == CXCursor_Destructor { + // Remove the leading `~`. The alternative to this is special-casing + // code-generation for destructor functions, which seems less than + // ideal. + if name.starts_with('~') { + name.remove(0); + } + + // Add a suffix to avoid colliding with constructors. This would be + // technically fine (since we handle duplicated functions/methods), + // but seems easy enough to handle it here. + name.push_str("_destructor"); + } + let mut mangled_name = cursor_mangling(context, &cursor); if mangled_name.as_ref() == Some(&name) { mangled_name = None; diff --git a/src/ir/int.rs b/src/ir/int.rs index 89068e0f..a4cb8bc7 100644 --- a/src/ir/int.rs +++ b/src/ir/int.rs @@ -6,12 +6,18 @@ pub enum IntKind { /// A `bool`. Bool, - /// A `char`. - Char, + /// A `signed char`. + SChar, /// An `unsigned char`. UChar, + /// A platform-dependent `char` type, with the signedness support. + Char { + /// Whether the char is signed for the target platform. + is_signed: bool, + }, + /// A `short`. Short, @@ -84,9 +90,11 @@ impl IntKind { Bool | UChar | UShort | UInt | ULong | ULongLong | U8 | U16 | U32 | U64 | U128 => false, - Char | Short | Int | Long | LongLong | I8 | I16 | I32 | I64 | + SChar | Short | Int | Long | LongLong | I8 | I16 | I32 | I64 | I128 => true, + Char { is_signed } => is_signed, + Custom { is_signed, .. } => is_signed, } } @@ -97,7 +105,7 @@ impl IntKind { pub fn known_size(&self) -> Option<usize> { use self::IntKind::*; Some(match *self { - Bool | UChar | Char | U8 | I8 => 1, + Bool | UChar | SChar | U8 | I8 | Char { .. } => 1, U16 | I16 => 2, U32 | I32 => 4, U64 | I64 => 8, @@ -109,6 +109,8 @@ pub struct CodegenConfig { pub methods: bool, /// Whether to generate constructors. pub constructors: bool, + /// Whether to generate destructors. + pub destructors: bool, } impl CodegenConfig { @@ -120,6 +122,7 @@ impl CodegenConfig { vars: true, methods: true, constructors: true, + destructors: true, } } @@ -131,6 +134,7 @@ impl CodegenConfig { vars: false, methods: false, constructors: false, + destructors: false, } } } diff --git a/src/options.rs b/src/options.rs index f1c8479a..6d06ad3b 100644 --- a/src/options.rs +++ b/src/options.rs @@ -111,8 +111,8 @@ pub fn builder_from_flags<I> Arg::with_name("generate") .long("generate") .help("Generate a given kind of items, split by commas. \ - Valid values are \"functions\",\"types\", \"vars\" and \ - \"methods\".") + Valid values are \"functions\",\"types\", \"vars\", \ + \"methods\", \"constructors\" and \"destructors\".") .takes_value(true), Arg::with_name("ignore-methods") .long("ignore-methods") @@ -271,6 +271,8 @@ pub fn builder_from_flags<I> "types" => config.types = true, "vars" => config.vars = true, "methods" => config.methods = true, + "constructors" => config.constructors = true, + "destructors" => config.destructors = true, _ => { return Err(Error::new(ErrorKind::Other, "Unknown generate item")); diff --git a/tests/expectations/tests/anonymous-template-types.rs b/tests/expectations/tests/anonymous-template-types.rs index bb4be105..c225b69d 100644 --- a/tests/expectations/tests/anonymous-template-types.rs +++ b/tests/expectations/tests/anonymous-template-types.rs @@ -15,7 +15,7 @@ impl <T> Default for Foo<T> { #[repr(C)] #[derive(Debug, Default, Copy, Clone)] pub struct Bar { - pub member: ::std::os::raw::c_schar, + pub member: ::std::os::raw::c_char, } #[repr(C)] #[derive(Debug, Copy, Clone)] @@ -28,6 +28,6 @@ impl <V> Default for Quux<V> { #[repr(C)] #[derive(Debug, Default, Copy, Clone)] pub struct Lobo { - pub also_member: ::std::os::raw::c_schar, + pub also_member: ::std::os::raw::c_char, } -pub type AliasWithAnonType = ::std::os::raw::c_schar; +pub type AliasWithAnonType = ::std::os::raw::c_char; diff --git a/tests/expectations/tests/arg_keyword.rs b/tests/expectations/tests/arg_keyword.rs index 23818328..cb1cc432 100644 --- a/tests/expectations/tests/arg_keyword.rs +++ b/tests/expectations/tests/arg_keyword.rs @@ -6,5 +6,5 @@ extern "C" { #[link_name = "_Z3fooPKc"] - pub fn foo(type_: *const ::std::os::raw::c_schar); + pub fn foo(type_: *const ::std::os::raw::c_char); } diff --git a/tests/expectations/tests/bitfield-method-same-name.rs b/tests/expectations/tests/bitfield-method-same-name.rs index 9222f74d..ab74b1e5 100644 --- a/tests/expectations/tests/bitfield-method-same-name.rs +++ b/tests/expectations/tests/bitfield-method-same-name.rs @@ -19,22 +19,22 @@ fn bindgen_test_layout_Foo() { } extern "C" { #[link_name = "_ZN3Foo4typeEv"] - pub fn Foo_type(this: *mut Foo) -> ::std::os::raw::c_schar; + pub fn Foo_type(this: *mut Foo) -> ::std::os::raw::c_char; } extern "C" { #[link_name = "_ZN3Foo9set_type_Ec"] - pub fn Foo_set_type_(this: *mut Foo, c: ::std::os::raw::c_schar); + pub fn Foo_set_type_(this: *mut Foo, c: ::std::os::raw::c_char); } extern "C" { #[link_name = "_ZN3Foo8set_typeEc"] - pub fn Foo_set_type(this: *mut Foo, c: ::std::os::raw::c_schar); + pub fn Foo_set_type(this: *mut Foo, c: ::std::os::raw::c_char); } impl Clone for Foo { fn clone(&self) -> Self { *self } } impl Foo { #[inline] - pub fn type__bindgen_bitfield(&self) -> ::std::os::raw::c_schar { + pub fn type__bindgen_bitfield(&self) -> ::std::os::raw::c_char { let mask = 7usize as u8; let field_val: u8 = unsafe { ::std::mem::transmute(self._bitfield_1) }; @@ -43,7 +43,7 @@ impl Foo { } #[inline] pub fn set_type__bindgen_bitfield(&mut self, - val: ::std::os::raw::c_schar) { + val: ::std::os::raw::c_char) { let mask = 7usize as u8; let val = val as u8 as u8; let mut field_val: u8 = @@ -53,15 +53,15 @@ impl Foo { self._bitfield_1 = unsafe { ::std::mem::transmute(field_val) }; } #[inline] - pub unsafe fn type_(&mut self) -> ::std::os::raw::c_schar { - Foo_type(&mut *self) + pub unsafe fn type_(&mut self) -> ::std::os::raw::c_char { + Foo_type(self) } #[inline] - pub unsafe fn set_type_(&mut self, c: ::std::os::raw::c_schar) { - Foo_set_type_(&mut *self, c) + pub unsafe fn set_type_(&mut self, c: ::std::os::raw::c_char) { + Foo_set_type_(self, c) } #[inline] - pub unsafe fn set_type(&mut self, c: ::std::os::raw::c_schar) { - Foo_set_type(&mut *self, c) + pub unsafe fn set_type(&mut self, c: ::std::os::raw::c_char) { + Foo_set_type(self, c) } } diff --git a/tests/expectations/tests/char.rs b/tests/expectations/tests/char.rs new file mode 100644 index 00000000..5541d492 --- /dev/null +++ b/tests/expectations/tests/char.rs @@ -0,0 +1,95 @@ +/* automatically generated by rust-bindgen */ + + +#![allow(non_snake_case)] + + +pub type Char = ::std::os::raw::c_char; +pub type SChar = ::std::os::raw::c_schar; +pub type UChar = ::std::os::raw::c_uchar; +#[repr(C)] +#[derive(Debug, Default, Copy)] +pub struct Test { + pub ch: ::std::os::raw::c_char, + pub u: ::std::os::raw::c_uchar, + pub d: ::std::os::raw::c_schar, + pub cch: ::std::os::raw::c_char, + pub cu: ::std::os::raw::c_uchar, + pub cd: ::std::os::raw::c_schar, + pub Cch: Char, + pub Cu: UChar, + pub Cd: SChar, + pub Ccch: Char, + pub Ccu: UChar, + pub Ccd: SChar, +} +#[test] +fn bindgen_test_layout_Test() { + assert_eq!(::std::mem::size_of::<Test>() , 12usize , concat ! ( + "Size of: " , stringify ! ( Test ) )); + assert_eq! (::std::mem::align_of::<Test>() , 1usize , concat ! ( + "Alignment of " , stringify ! ( Test ) )); + assert_eq! (unsafe { + & ( * ( 0 as * const Test ) ) . ch as * const _ as usize } , + 0usize , concat ! ( + "Alignment of field: " , stringify ! ( Test ) , "::" , + stringify ! ( ch ) )); + assert_eq! (unsafe { + & ( * ( 0 as * const Test ) ) . u as * const _ as usize } , + 1usize , concat ! ( + "Alignment of field: " , stringify ! ( Test ) , "::" , + stringify ! ( u ) )); + assert_eq! (unsafe { + & ( * ( 0 as * const Test ) ) . d as * const _ as usize } , + 2usize , concat ! ( + "Alignment of field: " , stringify ! ( Test ) , "::" , + stringify ! ( d ) )); + assert_eq! (unsafe { + & ( * ( 0 as * const Test ) ) . cch as * const _ as usize } , + 3usize , concat ! ( + "Alignment of field: " , stringify ! ( Test ) , "::" , + stringify ! ( cch ) )); + assert_eq! (unsafe { + & ( * ( 0 as * const Test ) ) . cu as * const _ as usize } , + 4usize , concat ! ( + "Alignment of field: " , stringify ! ( Test ) , "::" , + stringify ! ( cu ) )); + assert_eq! (unsafe { + & ( * ( 0 as * const Test ) ) . cd as * const _ as usize } , + 5usize , concat ! ( + "Alignment of field: " , stringify ! ( Test ) , "::" , + stringify ! ( cd ) )); + assert_eq! (unsafe { + & ( * ( 0 as * const Test ) ) . Cch as * const _ as usize } , + 6usize , concat ! ( + "Alignment of field: " , stringify ! ( Test ) , "::" , + stringify ! ( Cch ) )); + assert_eq! (unsafe { + & ( * ( 0 as * const Test ) ) . Cu as * const _ as usize } , + 7usize , concat ! ( + "Alignment of field: " , stringify ! ( Test ) , "::" , + stringify ! ( Cu ) )); + assert_eq! (unsafe { + & ( * ( 0 as * const Test ) ) . Cd as * const _ as usize } , + 8usize , concat ! ( + "Alignment of field: " , stringify ! ( Test ) , "::" , + stringify ! ( Cd ) )); + assert_eq! (unsafe { + & ( * ( 0 as * const Test ) ) . Ccch as * const _ as usize } , + 9usize , concat ! ( + "Alignment of field: " , stringify ! ( Test ) , "::" , + stringify ! ( Ccch ) )); + assert_eq! (unsafe { + & ( * ( 0 as * const Test ) ) . Ccu as * const _ as usize } , + 10usize , concat ! ( + "Alignment of field: " , stringify ! ( Test ) , "::" , + stringify ! ( Ccu ) )); + assert_eq! (unsafe { + & ( * ( 0 as * const Test ) ) . Ccd as * const _ as usize } , + 11usize , concat ! ( + "Alignment of field: " , stringify ! ( Test ) , "::" , + stringify ! ( Ccd ) )); +} +impl Clone for Test { + fn clone(&self) -> Self { *self } +} diff --git a/tests/expectations/tests/class.rs b/tests/expectations/tests/class.rs index 3ed5edd2..56353a5e 100644 --- a/tests/expectations/tests/class.rs +++ b/tests/expectations/tests/class.rs @@ -64,7 +64,7 @@ impl <T> ::std::fmt::Debug for __BindgenUnionField<T> { #[repr(C)] pub struct C { pub a: ::std::os::raw::c_int, - pub big_array: [::std::os::raw::c_schar; 33usize], + pub big_array: [::std::os::raw::c_char; 33usize], } #[test] fn bindgen_test_layout_C() { @@ -88,8 +88,8 @@ impl Default for C { #[repr(C)] pub struct C_with_zero_length_array { pub a: ::std::os::raw::c_int, - pub big_array: [::std::os::raw::c_schar; 33usize], - pub zero_length_array: __IncompleteArrayField<::std::os::raw::c_schar>, + pub big_array: [::std::os::raw::c_char; 33usize], + pub zero_length_array: __IncompleteArrayField<::std::os::raw::c_char>, } #[test] fn bindgen_test_layout_C_with_zero_length_array() { @@ -124,8 +124,8 @@ impl Default for C_with_zero_length_array { #[repr(C)] pub struct C_with_incomplete_array { pub a: ::std::os::raw::c_int, - pub big_array: [::std::os::raw::c_schar; 33usize], - pub incomplete_array: __IncompleteArrayField<::std::os::raw::c_schar>, + pub big_array: [::std::os::raw::c_char; 33usize], + pub incomplete_array: __IncompleteArrayField<::std::os::raw::c_char>, } #[test] fn bindgen_test_layout_C_with_incomplete_array() { @@ -142,9 +142,9 @@ impl Default for C_with_incomplete_array { #[repr(C)] pub struct C_with_zero_length_array_and_incomplete_array { pub a: ::std::os::raw::c_int, - pub big_array: [::std::os::raw::c_schar; 33usize], - pub zero_length_array: __IncompleteArrayField<::std::os::raw::c_schar>, - pub incomplete_array: __IncompleteArrayField<::std::os::raw::c_schar>, + pub big_array: [::std::os::raw::c_char; 33usize], + pub zero_length_array: __IncompleteArrayField<::std::os::raw::c_char>, + pub incomplete_array: __IncompleteArrayField<::std::os::raw::c_char>, } #[test] fn bindgen_test_layout_C_with_zero_length_array_and_incomplete_array() { @@ -283,14 +283,14 @@ impl Clone for RealAbstractionWithTonsOfMethods { } impl RealAbstractionWithTonsOfMethods { #[inline] - pub unsafe fn bar(&self) { RealAbstractionWithTonsOfMethods_bar(&*self) } + pub unsafe fn bar(&self) { RealAbstractionWithTonsOfMethods_bar(self) } #[inline] pub unsafe fn bar1(&mut self) { - RealAbstractionWithTonsOfMethods_bar1(&mut *self) + RealAbstractionWithTonsOfMethods_bar1(self) } #[inline] pub unsafe fn bar2(&mut self, foo: ::std::os::raw::c_int) { - RealAbstractionWithTonsOfMethods_bar2(&mut *self, foo) + RealAbstractionWithTonsOfMethods_bar2(self, foo) } #[inline] pub unsafe fn sta() { RealAbstractionWithTonsOfMethods_sta() } diff --git a/tests/expectations/tests/class_with_typedef.rs b/tests/expectations/tests/class_with_typedef.rs index 03822233..642a7287 100644 --- a/tests/expectations/tests/class_with_typedef.rs +++ b/tests/expectations/tests/class_with_typedef.rs @@ -15,7 +15,7 @@ pub struct C { pub other_ptr: *mut AnotherInt, } pub type C_MyInt = ::std::os::raw::c_int; -pub type C_Lookup = *const ::std::os::raw::c_schar; +pub type C_Lookup = *const ::std::os::raw::c_char; #[test] fn bindgen_test_layout_C() { assert_eq!(::std::mem::size_of::<C>() , 72usize , concat ! ( @@ -70,18 +70,18 @@ impl Default for C { } impl C { #[inline] - pub unsafe fn method(&mut self, c: C_MyInt) { C_method(&mut *self, c) } + pub unsafe fn method(&mut self, c: C_MyInt) { C_method(self, c) } #[inline] pub unsafe fn methodRef(&mut self, c: *mut C_MyInt) { - C_methodRef(&mut *self, c) + C_methodRef(self, c) } #[inline] pub unsafe fn complexMethodRef(&mut self, c: *mut C_Lookup) { - C_complexMethodRef(&mut *self, c) + C_complexMethodRef(self, c) } #[inline] pub unsafe fn anotherMethod(&mut self, c: AnotherInt) { - C_anotherMethod(&mut *self, c) + C_anotherMethod(self, c) } } #[repr(C)] diff --git a/tests/expectations/tests/constant-evaluate.rs b/tests/expectations/tests/constant-evaluate.rs index ae0570ea..cdf097a2 100644 --- a/tests/expectations/tests/constant-evaluate.rs +++ b/tests/expectations/tests/constant-evaluate.rs @@ -14,7 +14,7 @@ pub const k: EasyToOverflow = 2147483648; pub const k_expr: EasyToOverflow = 0; pub const BAZ: ::std::os::raw::c_longlong = 24; pub const fuzz: f64 = 51.; -pub const BAZZ: ::std::os::raw::c_schar = 53; -pub const WAT: ::std::os::raw::c_schar = 0; +pub const BAZZ: ::std::os::raw::c_char = 53; +pub const WAT: ::std::os::raw::c_char = 0; pub const bytestring: &'static [u8; 4usize] = b"Foo\x00"; pub const NOT_UTF8: [u8; 5usize] = [240, 40, 140, 40, 0]; diff --git a/tests/expectations/tests/gen-constructors-neg.rs b/tests/expectations/tests/gen-constructors-neg.rs new file mode 100644 index 00000000..fbeb3d5e --- /dev/null +++ b/tests/expectations/tests/gen-constructors-neg.rs @@ -0,0 +1,21 @@ +/* automatically generated by rust-bindgen */ + + +#![allow(non_snake_case)] + + +#[repr(C)] +#[derive(Debug, Default, Copy)] +pub struct Foo { + pub _address: u8, +} +#[test] +fn bindgen_test_layout_Foo() { + assert_eq!(::std::mem::size_of::<Foo>() , 1usize , concat ! ( + "Size of: " , stringify ! ( Foo ) )); + assert_eq! (::std::mem::align_of::<Foo>() , 1usize , concat ! ( + "Alignment of " , stringify ! ( Foo ) )); +} +impl Clone for Foo { + fn clone(&self) -> Self { *self } +} diff --git a/tests/expectations/tests/gen-constructors.rs b/tests/expectations/tests/gen-constructors.rs new file mode 100644 index 00000000..72c2fc53 --- /dev/null +++ b/tests/expectations/tests/gen-constructors.rs @@ -0,0 +1,33 @@ +/* automatically generated by rust-bindgen */ + + +#![allow(non_snake_case)] + + +#[repr(C)] +#[derive(Debug, Default, Copy)] +pub struct Foo { + pub _address: u8, +} +#[test] +fn bindgen_test_layout_Foo() { + assert_eq!(::std::mem::size_of::<Foo>() , 1usize , concat ! ( + "Size of: " , stringify ! ( Foo ) )); + assert_eq! (::std::mem::align_of::<Foo>() , 1usize , concat ! ( + "Alignment of " , stringify ! ( Foo ) )); +} +extern "C" { + #[link_name = "_ZN3FooC1Ei"] + pub fn Foo_Foo(this: *mut Foo, a: ::std::os::raw::c_int); +} +impl Clone for Foo { + fn clone(&self) -> Self { *self } +} +impl Foo { + #[inline] + pub unsafe fn new(a: ::std::os::raw::c_int) -> Self { + let mut __bindgen_tmp = ::std::mem::uninitialized(); + Foo_Foo(&mut __bindgen_tmp, a); + __bindgen_tmp + } +} diff --git a/tests/expectations/tests/gen-destructors-neg.rs b/tests/expectations/tests/gen-destructors-neg.rs new file mode 100644 index 00000000..4aaec83a --- /dev/null +++ b/tests/expectations/tests/gen-destructors-neg.rs @@ -0,0 +1,23 @@ +/* automatically generated by rust-bindgen */ + + +#![allow(non_snake_case)] + + +#[repr(C)] +#[derive(Debug, Default)] +pub struct Foo { + pub bar: ::std::os::raw::c_int, +} +#[test] +fn bindgen_test_layout_Foo() { + assert_eq!(::std::mem::size_of::<Foo>() , 4usize , concat ! ( + "Size of: " , stringify ! ( Foo ) )); + assert_eq! (::std::mem::align_of::<Foo>() , 4usize , concat ! ( + "Alignment of " , stringify ! ( Foo ) )); + assert_eq! (unsafe { + & ( * ( 0 as * const Foo ) ) . bar as * const _ as usize } , + 0usize , concat ! ( + "Alignment of field: " , stringify ! ( Foo ) , "::" , + stringify ! ( bar ) )); +} diff --git a/tests/expectations/tests/gen-destructors.rs b/tests/expectations/tests/gen-destructors.rs new file mode 100644 index 00000000..7ec13b03 --- /dev/null +++ b/tests/expectations/tests/gen-destructors.rs @@ -0,0 +1,31 @@ +/* automatically generated by rust-bindgen */ + + +#![allow(non_snake_case)] + + +#[repr(C)] +#[derive(Debug, Default)] +pub struct Foo { + pub bar: ::std::os::raw::c_int, +} +#[test] +fn bindgen_test_layout_Foo() { + assert_eq!(::std::mem::size_of::<Foo>() , 4usize , concat ! ( + "Size of: " , stringify ! ( Foo ) )); + assert_eq! (::std::mem::align_of::<Foo>() , 4usize , concat ! ( + "Alignment of " , stringify ! ( Foo ) )); + assert_eq! (unsafe { + & ( * ( 0 as * const Foo ) ) . bar as * const _ as usize } , + 0usize , concat ! ( + "Alignment of field: " , stringify ! ( Foo ) , "::" , + stringify ! ( bar ) )); +} +extern "C" { + #[link_name = "_ZN3FooD1Ev"] + pub fn Foo_Foo_destructor(this: *mut Foo); +} +impl Foo { + #[inline] + pub unsafe fn destruct(&mut self) { Foo_Foo_destructor(self) } +} diff --git a/tests/expectations/tests/inline_namespace_whitelist.rs b/tests/expectations/tests/inline_namespace_whitelist.rs index d4a5aaff..96012684 100644 --- a/tests/expectations/tests/inline_namespace_whitelist.rs +++ b/tests/expectations/tests/inline_namespace_whitelist.rs @@ -11,6 +11,6 @@ pub mod root { pub mod std { #[allow(unused_imports)] use self::super::super::root; - pub type string = *const ::std::os::raw::c_schar; + pub type string = *const ::std::os::raw::c_char; } } diff --git a/tests/expectations/tests/issue-410.rs b/tests/expectations/tests/issue-410.rs index 1f624fec..8833ef4e 100644 --- a/tests/expectations/tests/issue-410.rs +++ b/tests/expectations/tests/issue-410.rs @@ -34,7 +34,7 @@ pub mod root { impl Value { #[inline] pub unsafe fn a(&mut self, arg1: root::JSWhyMagic) { - Value_a(&mut *self, arg1) + Value_a(self, arg1) } } } diff --git a/tests/expectations/tests/issue-493.rs b/tests/expectations/tests/issue-493.rs index 155834a3..04fa1d8c 100644 --- a/tests/expectations/tests/issue-493.rs +++ b/tests/expectations/tests/issue-493.rs @@ -34,7 +34,7 @@ pub struct basic_string { pub _address: u8, } pub type basic_string_size_type = ::std::os::raw::c_ulonglong; -pub type basic_string_value_type = ::std::os::raw::c_schar; +pub type basic_string_value_type = ::std::os::raw::c_char; pub type basic_string_pointer = *mut basic_string_value_type; #[repr(C)] #[derive(Debug, Copy, Clone)] diff --git a/tests/expectations/tests/layout.rs b/tests/expectations/tests/layout.rs index d0748672..115a108a 100644 --- a/tests/expectations/tests/layout.rs +++ b/tests/expectations/tests/layout.rs @@ -40,7 +40,7 @@ impl <T> ::std::marker::Copy for __IncompleteArrayField<T> { } #[repr(C, packed)] #[derive(Debug, Default, Copy)] pub struct header { - pub proto: ::std::os::raw::c_schar, + pub proto: ::std::os::raw::c_char, pub size: ::std::os::raw::c_uint, pub data: __IncompleteArrayField<::std::os::raw::c_uchar>, pub __bindgen_padding_0: [u8; 11usize], diff --git a/tests/expectations/tests/layout_array.rs b/tests/expectations/tests/layout_array.rs index eedc32b2..2cc85785 100644 --- a/tests/expectations/tests/layout_array.rs +++ b/tests/expectations/tests/layout_array.rs @@ -58,7 +58,7 @@ pub type rte_mempool_get_count = #[derive(Debug, Copy)] pub struct rte_mempool_ops { /**< Name of mempool ops struct. */ - pub name: [::std::os::raw::c_schar; 32usize], + pub name: [::std::os::raw::c_char; 32usize], /**< Allocate private data. */ pub alloc: rte_mempool_alloc_t, /**< Free the external pool. */ diff --git a/tests/expectations/tests/layout_cmdline_token.rs b/tests/expectations/tests/layout_cmdline_token.rs index c2b10455..791ea9b3 100644 --- a/tests/expectations/tests/layout_cmdline_token.rs +++ b/tests/expectations/tests/layout_cmdline_token.rs @@ -64,7 +64,7 @@ pub struct cmdline_token_ops { pub parse: ::std::option::Option<unsafe extern "C" fn(arg1: *mut cmdline_parse_token_hdr_t, arg2: - *const ::std::os::raw::c_schar, + *const ::std::os::raw::c_char, arg3: *mut ::std::os::raw::c_void, arg4: @@ -80,7 +80,7 @@ pub struct cmdline_token_ops { arg2: ::std::os::raw::c_int, arg3: - *mut ::std::os::raw::c_schar, + *mut ::std::os::raw::c_char, arg4: ::std::os::raw::c_uint) -> ::std::os::raw::c_int>, @@ -88,7 +88,7 @@ pub struct cmdline_token_ops { pub get_help: ::std::option::Option<unsafe extern "C" fn(arg1: *mut cmdline_parse_token_hdr_t, arg2: - *mut ::std::os::raw::c_schar, + *mut ::std::os::raw::c_char, arg3: ::std::os::raw::c_uint) -> ::std::os::raw::c_int>, diff --git a/tests/expectations/tests/layout_kni_mbuf.rs b/tests/expectations/tests/layout_kni_mbuf.rs index 209be0f1..d704267d 100644 --- a/tests/expectations/tests/layout_kni_mbuf.rs +++ b/tests/expectations/tests/layout_kni_mbuf.rs @@ -11,22 +11,22 @@ pub const RTE_CACHE_LINE_SIZE: ::std::os::raw::c_uint = 64; pub struct rte_kni_mbuf { pub buf_addr: *mut ::std::os::raw::c_void, pub buf_physaddr: u64, - pub pad0: [::std::os::raw::c_schar; 2usize], + pub pad0: [::std::os::raw::c_char; 2usize], /**< Start address of data in segment buffer. */ pub data_off: u16, - pub pad1: [::std::os::raw::c_schar; 2usize], + pub pad1: [::std::os::raw::c_char; 2usize], /**< Number of segments. */ pub nb_segs: u8, - pub pad4: [::std::os::raw::c_schar; 1usize], + pub pad4: [::std::os::raw::c_char; 1usize], /**< Offload features. */ pub ol_flags: u64, - pub pad2: [::std::os::raw::c_schar; 4usize], + pub pad2: [::std::os::raw::c_char; 4usize], /**< Total pkt len: sum of all segment data_len. */ pub pkt_len: u32, /**< Amount of data in segment buffer. */ pub data_len: u16, pub __bindgen_padding_0: [u8; 22usize], - pub pad3: [::std::os::raw::c_schar; 8usize], + pub pad3: [::std::os::raw::c_char; 8usize], pub pool: *mut ::std::os::raw::c_void, pub next: *mut ::std::os::raw::c_void, pub __bindgen_padding_1: [u64; 5usize], diff --git a/tests/expectations/tests/method-mangling.rs b/tests/expectations/tests/method-mangling.rs index 23f12280..360f0ea7 100644 --- a/tests/expectations/tests/method-mangling.rs +++ b/tests/expectations/tests/method-mangling.rs @@ -25,7 +25,5 @@ impl Clone for Foo { } impl Foo { #[inline] - pub unsafe fn type_(&mut self) -> ::std::os::raw::c_int { - Foo_type(&mut *self) - } + pub unsafe fn type_(&mut self) -> ::std::os::raw::c_int { Foo_type(self) } } diff --git a/tests/expectations/tests/namespace.rs b/tests/expectations/tests/namespace.rs index 21b5a58b..8e64fa22 100644 --- a/tests/expectations/tests/namespace.rs +++ b/tests/expectations/tests/namespace.rs @@ -58,7 +58,7 @@ pub mod root { #[inline] pub unsafe fn lets_hope_this_works(&mut self) -> ::std::os::raw::c_int { - A_lets_hope_this_works(&mut *self) + A_lets_hope_this_works(self) } } } diff --git a/tests/expectations/tests/objc_class_method.rs b/tests/expectations/tests/objc_class_method.rs index 768abe10..699f5619 100644 --- a/tests/expectations/tests/objc_class_method.rs +++ b/tests/expectations/tests/objc_class_method.rs @@ -19,7 +19,7 @@ pub trait Foo { -> *mut id; unsafe fn methodWithArg1_andArg2_andArg3_(intvalue: ::std::os::raw::c_int, ptr: - *mut ::std::os::raw::c_schar, + *mut ::std::os::raw::c_char, floatvalue: f32); } impl Foo for id { @@ -45,7 +45,7 @@ impl Foo for id { } unsafe fn methodWithArg1_andArg2_andArg3_(intvalue: ::std::os::raw::c_int, ptr: - *mut ::std::os::raw::c_schar, + *mut ::std::os::raw::c_char, floatvalue: f32) { msg_send!(objc :: runtime :: Class :: get ( "Foo" ) . expect ( "Couldn\'t find Foo" ) , diff --git a/tests/expectations/tests/objc_method.rs b/tests/expectations/tests/objc_method.rs index c9b9504f..d0342a21 100644 --- a/tests/expectations/tests/objc_method.rs +++ b/tests/expectations/tests/objc_method.rs @@ -20,7 +20,7 @@ pub trait Foo { unsafe fn methodWithArg1_andArg2_andArg3_(self, intvalue: ::std::os::raw::c_int, ptr: - *mut ::std::os::raw::c_schar, + *mut ::std::os::raw::c_char, floatvalue: f32); } impl Foo for id { @@ -40,7 +40,7 @@ impl Foo for id { unsafe fn methodWithArg1_andArg2_andArg3_(self, intvalue: ::std::os::raw::c_int, ptr: - *mut ::std::os::raw::c_schar, + *mut ::std::os::raw::c_char, floatvalue: f32) { msg_send!(self , methodWithArg1:intvalue andArg2:ptr andArg3:floatvalue ) diff --git a/tests/expectations/tests/overloading.rs b/tests/expectations/tests/overloading.rs index 99efe496..71002e23 100644 --- a/tests/expectations/tests/overloading.rs +++ b/tests/expectations/tests/overloading.rs @@ -6,7 +6,7 @@ extern "C" { #[link_name = "_Z8Evaluatec"] - pub fn Evaluate(r: ::std::os::raw::c_schar) -> bool; + pub fn Evaluate(r: ::std::os::raw::c_char) -> bool; } extern "C" { #[link_name = "_Z8Evaluateii"] diff --git a/tests/expectations/tests/public-dtor.rs b/tests/expectations/tests/public-dtor.rs index 1accf49c..d24e863e 100644 --- a/tests/expectations/tests/public-dtor.rs +++ b/tests/expectations/tests/public-dtor.rs @@ -16,3 +16,11 @@ 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 destruct(&mut self) { cv_String_String_destructor(self) } +} diff --git a/tests/expectations/tests/struct_with_packing.rs b/tests/expectations/tests/struct_with_packing.rs index 293cc534..cba3d475 100644 --- a/tests/expectations/tests/struct_with_packing.rs +++ b/tests/expectations/tests/struct_with_packing.rs @@ -7,7 +7,7 @@ #[repr(C, packed)] #[derive(Debug, Default, Copy)] pub struct a { - pub b: ::std::os::raw::c_schar, + pub b: ::std::os::raw::c_char, pub c: ::std::os::raw::c_short, } #[test] diff --git a/tests/expectations/tests/template-param-usage-7.rs b/tests/expectations/tests/template-param-usage-7.rs index b0584479..2544ffd0 100644 --- a/tests/expectations/tests/template-param-usage-7.rs +++ b/tests/expectations/tests/template-param-usage-7.rs @@ -13,4 +13,4 @@ pub struct DoesNotUseU<T, V> { impl <T, V> Default for DoesNotUseU<T, V> { fn default() -> Self { unsafe { ::std::mem::zeroed() } } } -pub type Alias = DoesNotUseU<::std::os::raw::c_int, ::std::os::raw::c_schar>; +pub type Alias = DoesNotUseU<::std::os::raw::c_int, ::std::os::raw::c_char>; diff --git a/tests/expectations/tests/union_dtor.rs b/tests/expectations/tests/union_dtor.rs index bfd573e0..61fb0380 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 destruct(&mut self) { + UnionWithDtor_UnionWithDtor_destructor(self) + } +} diff --git a/tests/expectations/tests/union_with_big_member.rs b/tests/expectations/tests/union_with_big_member.rs index 0a11b8bc..2b7a8eef 100644 --- a/tests/expectations/tests/union_with_big_member.rs +++ b/tests/expectations/tests/union_with_big_member.rs @@ -62,7 +62,7 @@ impl Default for WithBigArray { #[derive(Debug, Default, Copy)] pub struct WithBigArray2 { pub a: __BindgenUnionField<::std::os::raw::c_int>, - pub b: __BindgenUnionField<[::std::os::raw::c_schar; 33usize]>, + pub b: __BindgenUnionField<[::std::os::raw::c_char; 33usize]>, pub bindgen_union_field: [u32; 9usize], } #[test] diff --git a/tests/expectations/tests/variadic-method.rs b/tests/expectations/tests/variadic-method.rs index 6241c2cb..542e1e75 100644 --- a/tests/expectations/tests/variadic-method.rs +++ b/tests/expectations/tests/variadic-method.rs @@ -6,7 +6,7 @@ extern "C" { #[link_name = "_Z3fooPKcz"] - pub fn foo(fmt: *const ::std::os::raw::c_schar, ...); + pub fn foo(fmt: *const ::std::os::raw::c_char, ...); } #[repr(C)] #[derive(Debug, Default, Copy)] @@ -22,7 +22,7 @@ fn bindgen_test_layout_Bar() { } extern "C" { #[link_name = "_ZN3Bar3fooEPKcz"] - pub fn Bar_foo(this: *mut Bar, fmt: *const ::std::os::raw::c_schar, ...); + pub fn Bar_foo(this: *mut Bar, fmt: *const ::std::os::raw::c_char, ...); } impl Clone for Bar { fn clone(&self) -> Self { *self } diff --git a/tests/headers/char.h b/tests/headers/char.h new file mode 100644 index 00000000..ae38653e --- /dev/null +++ b/tests/headers/char.h @@ -0,0 +1,19 @@ +typedef char Char; +typedef signed char SChar; +typedef unsigned char UChar; + +struct Test { + char ch; + unsigned char u; + signed char d; + const char cch; + const unsigned char cu; + const signed char cd; + + Char Cch; + UChar Cu; + SChar Cd; + const Char Ccch; + const UChar Ccu; + const SChar Ccd; +}; diff --git a/tests/headers/gen-constructors-neg.hpp b/tests/headers/gen-constructors-neg.hpp new file mode 100644 index 00000000..2dd491c4 --- /dev/null +++ b/tests/headers/gen-constructors-neg.hpp @@ -0,0 +1,6 @@ +// bindgen-flags: --generate types,functions + +class Foo { + public: + Foo(int a); +}; diff --git a/tests/headers/gen-constructors.hpp b/tests/headers/gen-constructors.hpp new file mode 100644 index 00000000..809d6ef9 --- /dev/null +++ b/tests/headers/gen-constructors.hpp @@ -0,0 +1,6 @@ +// bindgen-flags: --generate types,constructors,functions + +class Foo { + public: + Foo(int a); +}; diff --git a/tests/headers/gen-destructors-neg.hpp b/tests/headers/gen-destructors-neg.hpp new file mode 100644 index 00000000..5ede3ba3 --- /dev/null +++ b/tests/headers/gen-destructors-neg.hpp @@ -0,0 +1,9 @@ +// bindgen-flags: --generate types,functions +// +// NB: This is intended to _not_ generate destructors. + +class Foo { + int bar; + public: + ~Foo(); +}; diff --git a/tests/headers/gen-destructors.hpp b/tests/headers/gen-destructors.hpp new file mode 100644 index 00000000..719eb248 --- /dev/null +++ b/tests/headers/gen-destructors.hpp @@ -0,0 +1,7 @@ +// bindgen-flags: --generate types,destructors,functions + +class Foo { + int bar; + public: + ~Foo(); +}; diff --git a/tests/tests.rs b/tests/tests.rs index 84b5e076..bb965bd7 100644 --- a/tests/tests.rs +++ b/tests/tests.rs @@ -156,7 +156,7 @@ fn test_header_contents() { assert_eq!(bindings, "/* automatically generated by rust-bindgen */ extern \"C\" { - pub fn foo(a: *const ::std::os::raw::c_schar) -> ::std::os::raw::c_int; + pub fn foo(a: *const ::std::os::raw::c_char) -> ::std::os::raw::c_int; } "); } |