From 821252d070d6bc8fca462890d52426ffbe2d6d91 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Emilio=20Cobos=20=C3=81lvarez?= Date: Wed, 21 Sep 2016 20:11:46 +0200 Subject: [PATCH 1/5] Some fixes for function pointers, typedefs, and OSX's stdlib.h. --- src/clang.rs | 13 +++- src/codegen/mod.rs | 11 +++- src/ir/context.rs | 57 ++++++++++------- src/ir/item.rs | 30 ++++++--- src/ir/ty.rs | 39 +++++++++--- src/parse.rs | 5 ++ tests/expectations/anon_enum.rs | 2 +- tests/expectations/anon_union.rs | 4 +- tests/expectations/blocks.rs | 9 +++ tests/expectations/class_with_inner_struct.rs | 61 ++++++++++--------- tests/expectations/func_ptr.rs | 7 ++- tests/expectations/func_ptr_in_struct.rs | 6 +- tests/expectations/func_with_func_ptr_arg.rs | 2 +- tests/expectations/jsval_layout_opaque.rs | 38 ++++++------ tests/expectations/namespace.rs | 6 +- .../struct_with_anon_struct_array.rs | 12 ++-- tests/expectations/struct_with_nesting.rs | 44 ++++--------- tests/expectations/template_typedefs.rs | 22 +++++++ tests/expectations/typeref.rs | 4 +- tests/expectations/union_template.rs | 8 +-- .../union_with_anon_struct_bitfield.rs | 14 ++--- .../union_with_anon_unnamed_struct.rs | 12 ++-- .../union_with_anon_unnamed_union.rs | 12 ++-- tests/expectations/union_with_nesting.rs | 43 ++++--------- tests/expectations/what_is_going_on.rs | 5 +- tests/headers/blocks.h | 3 + tests/headers/template_typedefs.hpp | 8 +++ 27 files changed, 280 insertions(+), 197 deletions(-) create mode 100644 tests/expectations/blocks.rs create mode 100644 tests/expectations/template_typedefs.rs create mode 100644 tests/headers/blocks.h create mode 100644 tests/headers/template_typedefs.hpp diff --git a/src/clang.rs b/src/clang.rs index 5618007bd6..defdf54700 100644 --- a/src/clang.rs +++ b/src/clang.rs @@ -17,14 +17,23 @@ pub struct Cursor { impl fmt::Debug for Cursor { fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result { - write!(fmt, "Cursor({} kind: {}, loc: {})", - self.spelling(), kind_to_str(self.kind()), self.location()) + write!(fmt, "Cursor({} kind: {}, loc: {}, usr: {:?})", + self.spelling(), kind_to_str(self.kind()), self.location(), self.usr()) } } pub type CursorVisitor<'s> = for<'a, 'b> FnMut(&'a Cursor, &'b Cursor) -> Enum_CXChildVisitResult + 's; impl Cursor { + pub fn usr(&self) -> Option { + let s = String_ { x: unsafe { clang_getCursorUSR(self.x) } }.to_string(); + if s.is_empty() { + None + } else { + Some(s) + } + } + pub fn is_declaration(&self) -> bool { unsafe { clang_isDeclaration(self.kind()) != 0 } } diff --git a/src/codegen/mod.rs b/src/codegen/mod.rs index 62cebf460a..8d5f453fed 100644 --- a/src/codegen/mod.rs +++ b/src/codegen/mod.rs @@ -1380,7 +1380,16 @@ impl ToRustTy for Type { TypeKind::Pointer(inner) | TypeKind::Reference(inner) => { let inner = ctx.resolve_item(inner); - inner.to_rust_ty(ctx).to_ptr(inner.expect_type().is_const(), ctx.span()) + let inner_ty = inner.expect_type(); + let ty = inner.to_rust_ty(ctx); + + // Avoid the first function pointer level, since it's already + // represented in Rust. + if inner_ty.canonical_type(ctx).is_function() { + ty + } else { + ty.to_ptr(inner.expect_type().is_const(), ctx.span()) + } } TypeKind::Named(..) => { let name = item.canonical_name(ctx); diff --git a/src/ir/context.rs b/src/ir/context.rs index 5ddedda067..4d5d88e4b7 100644 --- a/src/ir/context.rs +++ b/src/ir/context.rs @@ -33,11 +33,9 @@ pub struct BindgenContext<'ctx> { /// output. items: BTreeMap, - /// Clang cursor to type map. This is needed to be able to associate types - /// with item ids during parsing. - /// - /// The cursor used for storage is the definition cursor. - types: HashMap, + /// Clang USR to type map. This is needed to be able to associate types with + /// item ids during parsing. + types: HashMap, /// A cursor to module map. Similar reason than above. modules: HashMap, @@ -135,17 +133,19 @@ impl<'ctx> BindgenContext<'ctx> { assert!(old_item.is_none(), "Inserted type twice?"); if is_type && declaration.is_some() { - let declaration = declaration.unwrap(); - debug_assert_eq!(declaration, declaration.canonical()); - if declaration.is_valid() { - let old = self.types.insert(declaration, id); - debug_assert_eq!(old, None); - } else if location.is_some() && - (location.unwrap().kind() == CXCursor_ClassTemplate || - location.unwrap().kind() == CXCursor_ClassTemplatePartialSpecialization) { - let old = self.types.insert(location.unwrap().canonical(), id); - debug_assert_eq!(old, None); - } else { + let mut declaration = declaration.unwrap(); + if !declaration.is_valid() { + if let Some(location) = location { + if location.kind() == CXCursor_ClassTemplate || + location.kind() == CXCursor_ClassTemplatePartialSpecialization { + declaration = location; + } + } + } + declaration = declaration.canonical(); + + + if !declaration.is_valid() { // This could happen, for example, with types like `int*` or // similar. // @@ -153,6 +153,14 @@ impl<'ctx> BindgenContext<'ctx> { // duplicated, so we can just ignore them. debug!("Invalid declaration {:?} found for type {:?}", declaration, self.items.get(&id).unwrap().kind().expect_type()); + return; + } + + if let Some(usr) = declaration.usr() { + let old = self.types.insert(usr, id); + debug_assert_eq!(old, None); + } else { + error!("Valid declaration with no USR: {:?}, {:?}", declaration, location); } } } @@ -206,7 +214,7 @@ impl<'ctx> BindgenContext<'ctx> { self.collected_typerefs } - fn collect_typerefs(&mut self) -> Vec<(ItemId, clang::Type, Option)> { + fn collect_typerefs(&mut self) -> Vec<(ItemId, clang::Type, Option, Option)> { debug_assert!(!self.collected_typerefs); self.collected_typerefs = true; let mut typerefs = vec![]; @@ -218,8 +226,8 @@ impl<'ctx> BindgenContext<'ctx> { }; match *ty.kind() { - TypeKind::UnresolvedTypeRef(ref ty, loc) => { - typerefs.push((*id, ty.clone(), loc)); + TypeKind::UnresolvedTypeRef(ref ty, loc, parent_id) => { + typerefs.push((*id, ty.clone(), loc, parent_id)); } _ => {}, }; @@ -230,9 +238,9 @@ impl<'ctx> BindgenContext<'ctx> { fn resolve_typerefs(&mut self) { let typerefs = self.collect_typerefs(); - for (id, ty, loc) in typerefs { + for (id, ty, loc, parent_id) in typerefs { let _resolved = { - let resolved = Item::from_ty(&ty, loc, None, self) + let resolved = Item::from_ty(&ty, loc, parent_id, self) .expect("What happened?"); let mut item = self.items.get_mut(&id).unwrap(); @@ -494,8 +502,11 @@ impl<'ctx> BindgenContext<'ctx> { } let canonical_declaration = declaration.canonical(); if canonical_declaration.is_valid() { - // First lookup to see if we already have it resolved. - let id = self.types.get(&canonical_declaration).map(|id| *id); + let id = + canonical_declaration + .usr() + .and_then(|usr| self.types.get(&usr)) + .map(|id| *id); if let Some(id) = id { debug!("Already resolved ty {:?}, {:?}, {:?} {:?}", id, declaration, ty, location); diff --git a/src/ir/item.rs b/src/ir/item.rs index c9ac71a4d9..75c3b857e5 100644 --- a/src/ir/item.rs +++ b/src/ir/item.rs @@ -191,10 +191,19 @@ impl Item { TypeKind::Array(inner, _) | TypeKind::Pointer(inner) | TypeKind::Reference(inner) | - TypeKind::Alias(_, inner) | TypeKind::ResolvedTypeRef(inner) => { ctx.resolve_item(inner).applicable_template_args(ctx) } + TypeKind::Alias(_, inner) => { + let parent_args = ctx.resolve_item(self.parent_id()) + .applicable_template_args(ctx); + let inner = ctx.resolve_type(inner); + // Avoid unused type parameters, sigh. + parent_args.iter().cloned().filter(|arg| { + let arg = ctx.resolve_type(*arg); + arg.is_named() && inner.signature_contains_named_type(ctx, arg) + }).collect() + } // XXX Is this completely correct? Partial template specialization // is hard anyways, sigh... TypeKind::TemplateRef(_, ref args) => { @@ -436,11 +445,19 @@ impl ClangItemParser for Item { location: Option, parent_id: Option, context: &mut BindgenContext) -> ItemId { - debug!("from_ty_or_ref: {:?}, {:?}, {:?}", ty, location, parent_id); + Self::from_ty_or_ref_with_id(ItemId::next(), ty, location, parent_id, context) + } + + fn from_ty_or_ref_with_id(potential_id: ItemId, + ty: clang::Type, + location: Option, + parent_id: Option, + context: &mut BindgenContext) -> ItemId { + debug!("from_ty_or_ref_with_id: {:?} {:?}, {:?}, {:?}", potential_id, ty, location, parent_id); if context.collected_typerefs() { debug!("refs already collected, resolving directly"); - return Self::from_ty(&ty, location, parent_id, context) + return Self::from_ty_with_id(potential_id, &ty, location, parent_id, context) .expect("Unable to resolve type"); } @@ -452,15 +469,14 @@ impl ClangItemParser for Item { debug!("New unresolved type reference: {:?}, {:?}", ty, location); let is_const = ty.is_const(); - let kind = TypeKind::UnresolvedTypeRef(ty, location); - let id = ItemId::next(); + let kind = TypeKind::UnresolvedTypeRef(ty, location, parent_id); let current_module = context.current_module(); - context.add_item(Item::new(id, None, None, + context.add_item(Item::new(potential_id, None, None, parent_id.unwrap_or(current_module), ItemKind::Type(Type::new(None, None, kind, is_const))), Some(clang::Cursor::null()), None); - id + potential_id } diff --git a/src/ir/ty.rs b/src/ir/ty.rs index b044843703..b0bf9bf634 100644 --- a/src/ir/ty.rs +++ b/src/ir/ty.rs @@ -75,6 +75,13 @@ impl Type { } } + pub fn is_function(&self) -> bool { + match self.kind { + TypeKind::Function(..) => true, + _ => false, + } + } + pub fn is_builtin_or_named(&self) -> bool { match self.kind { TypeKind::Void | @@ -243,9 +250,18 @@ impl Type { => this_name == name, TypeKind::ResolvedTypeRef(t) | TypeKind::Array(t, _) | - TypeKind::Pointer(t) + TypeKind::Pointer(t) | + TypeKind::Alias(_, t) => type_resolver.resolve_type(t) .signature_contains_named_type(type_resolver, ty), + TypeKind::Function(ref sig) => { + sig.argument_types().iter().any(|&(_, arg)| { + type_resolver.resolve_type(arg) + .signature_contains_named_type(type_resolver, ty) + }) || + type_resolver.resolve_type(sig.return_type()) + .signature_contains_named_type(type_resolver, ty) + }, TypeKind::TemplateRef(_inner, ref template_args) => { template_args.iter().any(|arg| { type_resolver.resolve_type(*arg) @@ -332,7 +348,7 @@ pub enum TypeKind { /// already known types, and are converted to ResolvedTypeRef. /// /// see tests/headers/typeref.hpp to see somewhere where this is a problem. - UnresolvedTypeRef(clang::Type, Option), + UnresolvedTypeRef(clang::Type, Option, /* parent_id */ Option), ResolvedTypeRef(ItemId), /// A named type, that is, a template parameter, with an optional default @@ -427,18 +443,18 @@ impl Type { let referenced = location.referenced(); return Self::from_clang_ty(potential_id, &referenced.cur_type(), - Some(referenced), + Some(referenced.cur_type().declaration()), parent_id, ctx); } CXCursor_TypeRef => { let referenced = location.referenced(); - // FIXME: use potential id? return Ok(ParseResult::AlreadyResolved( - Item::from_ty_or_ref(referenced.cur_type(), - Some(referenced), - parent_id, - ctx))); + Item::from_ty_or_ref_with_id(potential_id, + referenced.cur_type(), + Some(referenced.cur_type().declaration()), + parent_id, + ctx))); } _ => { if ty.kind() == CXType_Unexposed { @@ -469,9 +485,11 @@ impl Type { // We might need to, though, if the context is already in the // process of resolving them. CXType_MemberPointer | + CXType_BlockPointer | CXType_Pointer => { let inner = - Item::from_ty_or_ref(ty.pointee_type(), Some(ty.pointee_type().declaration()), parent_id, ctx); + Item::from_ty_or_ref(ty.pointee_type(), location, + parent_id, ctx); TypeKind::Pointer(inner) } // XXX: RValueReference is most likely wrong, but I don't think we @@ -479,7 +497,8 @@ impl Type { CXType_RValueReference | CXType_LValueReference => { let inner = - Item::from_ty_or_ref(ty.pointee_type(), Some(ty.pointee_type().declaration()), parent_id, ctx); + Item::from_ty_or_ref(ty.pointee_type(), location, + parent_id, ctx); TypeKind::Reference(inner) } // XXX DependentSizedArray is wrong diff --git a/src/parse.rs b/src/parse.rs index 39d2644a85..d6c36aa456 100644 --- a/src/parse.rs +++ b/src/parse.rs @@ -29,6 +29,11 @@ pub trait ClangItemParser: Sized { location: Option, parent_id: Option, context: &mut BindgenContext) -> ItemId; + fn from_ty_or_ref_with_id(potential_id: ItemId, + ty: clang::Type, + location: Option, + parent_id: Option, + context: &mut BindgenContext) -> ItemId; fn from_ty_with_id(id: ItemId, ty: &clang::Type, location: Option, diff --git a/tests/expectations/anon_enum.rs b/tests/expectations/anon_enum.rs index 6b8688e135..b06585b120 100644 --- a/tests/expectations/anon_enum.rs +++ b/tests/expectations/anon_enum.rs @@ -12,7 +12,7 @@ pub struct Test { } #[repr(u32)] #[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)] -pub enum Test__bindgen_ty_bindgen_id_4 { T_NONE = 0, } +pub enum Test__bindgen_ty_bindgen_id_6 { T_NONE = 0, } #[test] fn bindgen_test_layout_Test() { assert_eq!(::std::mem::size_of::() , 8usize); diff --git a/tests/expectations/anon_union.rs b/tests/expectations/anon_union.rs index 66963f40f9..731d1dd990 100644 --- a/tests/expectations/anon_union.rs +++ b/tests/expectations/anon_union.rs @@ -28,7 +28,7 @@ impl ::std::marker::Copy for __BindgenUnionField { } #[derive(Debug, Copy, Clone)] pub struct TErrorResult { pub mResult: ::std::os::raw::c_int, - pub __bindgen_anon_1: TErrorResult__bindgen_ty_bindgen_id_9, + pub __bindgen_anon_1: TErrorResult__bindgen_ty_bindgen_id_10, pub mMightHaveUnreported: bool, pub mUnionState: TErrorResult_UnionState, pub _phantom_0: ::std::marker::PhantomData, @@ -52,7 +52,7 @@ pub struct TErrorResult_DOMExceptionInfo { } #[repr(C)] #[derive(Debug, Copy, Clone)] -pub struct TErrorResult__bindgen_ty_bindgen_id_9 { +pub struct TErrorResult__bindgen_ty_bindgen_id_10 { pub mMessage: __BindgenUnionField<*mut TErrorResult_Message>, pub mDOMExceptionInfo: __BindgenUnionField<*mut TErrorResult_DOMExceptionInfo>, pub bindgen_union_field: u64, diff --git a/tests/expectations/blocks.rs b/tests/expectations/blocks.rs new file mode 100644 index 0000000000..88a797e224 --- /dev/null +++ b/tests/expectations/blocks.rs @@ -0,0 +1,9 @@ +/* automatically generated by rust-bindgen */ + + +#![allow(non_snake_case)] + + +extern "C" { + pub fn atexit_b(arg1: ::std::option::Option); +} diff --git a/tests/expectations/class_with_inner_struct.rs b/tests/expectations/class_with_inner_struct.rs index 464c622df0..98c0505ab7 100644 --- a/tests/expectations/class_with_inner_struct.rs +++ b/tests/expectations/class_with_inner_struct.rs @@ -28,8 +28,8 @@ impl ::std::marker::Copy for __BindgenUnionField { } #[derive(Debug, Copy)] pub struct A { pub c: ::std::os::raw::c_uint, - pub named_union: A__bindgen_ty_bindgen_id_6, - pub __bindgen_anon_1: A__bindgen_ty_bindgen_id_9, + pub named_union: A__bindgen_ty_bindgen_id_9, + pub __bindgen_anon_1: A__bindgen_ty_bindgen_id_14, } #[repr(C)] #[derive(Debug, Copy)] @@ -47,30 +47,31 @@ impl Clone for A_Segment { } #[repr(C)] #[derive(Debug, Copy)] -pub struct A__bindgen_ty_bindgen_id_6 { +pub struct A__bindgen_ty_bindgen_id_9 { pub f: __BindgenUnionField<::std::os::raw::c_int>, pub bindgen_union_field: u32, } #[test] -fn bindgen_test_layout_A__bindgen_ty_bindgen_id_6() { - assert_eq!(::std::mem::size_of::() , 4usize); - assert_eq!(::std::mem::align_of::() , 4usize); +fn bindgen_test_layout_A__bindgen_ty_bindgen_id_9() { + assert_eq!(::std::mem::size_of::() , 4usize); + assert_eq!(::std::mem::align_of::() , 4usize); } -impl Clone for A__bindgen_ty_bindgen_id_6 { +impl Clone for A__bindgen_ty_bindgen_id_9 { fn clone(&self) -> Self { *self } } #[repr(C)] #[derive(Debug, Copy)] -pub struct A__bindgen_ty_bindgen_id_9 { +pub struct A__bindgen_ty_bindgen_id_14 { pub d: __BindgenUnionField<::std::os::raw::c_int>, pub bindgen_union_field: u32, } #[test] -fn bindgen_test_layout_A__bindgen_ty_bindgen_id_9() { - assert_eq!(::std::mem::size_of::() , 4usize); - assert_eq!(::std::mem::align_of::() , 4usize); +fn bindgen_test_layout_A__bindgen_ty_bindgen_id_14() { + assert_eq!(::std::mem::size_of::() , 4usize); + assert_eq!(::std::mem::align_of::() , + 4usize); } -impl Clone for A__bindgen_ty_bindgen_id_9 { +impl Clone for A__bindgen_ty_bindgen_id_14 { fn clone(&self) -> Self { *self } } #[test] @@ -120,57 +121,57 @@ pub enum StepSyntax { #[derive(Debug, Copy)] pub struct C { pub d: ::std::os::raw::c_uint, - pub __bindgen_anon_1: C__bindgen_ty_bindgen_id_21, + pub __bindgen_anon_1: C__bindgen_ty_bindgen_id_31, } #[repr(C)] #[derive(Debug, Copy)] -pub struct C__bindgen_ty_bindgen_id_21 { - pub mFunc: __BindgenUnionField, - pub __bindgen_anon_1: __BindgenUnionField, +pub struct C__bindgen_ty_bindgen_id_31 { + pub mFunc: __BindgenUnionField, + pub __bindgen_anon_1: __BindgenUnionField, pub bindgen_union_field: [u32; 4usize], } #[repr(C)] #[derive(Debug, Copy)] -pub struct C__bindgen_ty_bindgen_id_21__bindgen_ty_bindgen_id_22 { +pub struct C__bindgen_ty_bindgen_id_31__bindgen_ty_bindgen_id_32 { pub mX1: f32, pub mY1: f32, pub mX2: f32, pub mY2: f32, } #[test] -fn bindgen_test_layout_C__bindgen_ty_bindgen_id_21__bindgen_ty_bindgen_id_22() { - assert_eq!(::std::mem::size_of::() +fn bindgen_test_layout_C__bindgen_ty_bindgen_id_31__bindgen_ty_bindgen_id_32() { + assert_eq!(::std::mem::size_of::() , 16usize); - assert_eq!(::std::mem::align_of::() + assert_eq!(::std::mem::align_of::() , 4usize); } -impl Clone for C__bindgen_ty_bindgen_id_21__bindgen_ty_bindgen_id_22 { +impl Clone for C__bindgen_ty_bindgen_id_31__bindgen_ty_bindgen_id_32 { fn clone(&self) -> Self { *self } } #[repr(C)] #[derive(Debug, Copy)] -pub struct C__bindgen_ty_bindgen_id_21__bindgen_ty_bindgen_id_28 { +pub struct C__bindgen_ty_bindgen_id_31__bindgen_ty_bindgen_id_43 { pub mStepSyntax: StepSyntax, pub mSteps: ::std::os::raw::c_uint, } #[test] -fn bindgen_test_layout_C__bindgen_ty_bindgen_id_21__bindgen_ty_bindgen_id_28() { - assert_eq!(::std::mem::size_of::() +fn bindgen_test_layout_C__bindgen_ty_bindgen_id_31__bindgen_ty_bindgen_id_43() { + assert_eq!(::std::mem::size_of::() , 8usize); - assert_eq!(::std::mem::align_of::() + assert_eq!(::std::mem::align_of::() , 4usize); } -impl Clone for C__bindgen_ty_bindgen_id_21__bindgen_ty_bindgen_id_28 { +impl Clone for C__bindgen_ty_bindgen_id_31__bindgen_ty_bindgen_id_43 { fn clone(&self) -> Self { *self } } #[test] -fn bindgen_test_layout_C__bindgen_ty_bindgen_id_21() { - assert_eq!(::std::mem::size_of::() , +fn bindgen_test_layout_C__bindgen_ty_bindgen_id_31() { + assert_eq!(::std::mem::size_of::() , 16usize); - assert_eq!(::std::mem::align_of::() , + assert_eq!(::std::mem::align_of::() , 4usize); } -impl Clone for C__bindgen_ty_bindgen_id_21 { +impl Clone for C__bindgen_ty_bindgen_id_31 { fn clone(&self) -> Self { *self } } #[repr(C)] diff --git a/tests/expectations/func_ptr.rs b/tests/expectations/func_ptr.rs index c62e532d7e..87ec3e3dcf 100644 --- a/tests/expectations/func_ptr.rs +++ b/tests/expectations/func_ptr.rs @@ -7,6 +7,9 @@ extern "C" { #[link_name = "foo"] pub static mut foo: - *mut ::std::option::Option ::std::os::raw::c_int>; + ::std::option::Option ::std::os::raw::c_int>; } diff --git a/tests/expectations/func_ptr_in_struct.rs b/tests/expectations/func_ptr_in_struct.rs index 0d4ccdbf73..dcae771b06 100644 --- a/tests/expectations/func_ptr_in_struct.rs +++ b/tests/expectations/func_ptr_in_struct.rs @@ -9,7 +9,11 @@ pub enum baz { } #[repr(C)] #[derive(Debug, Copy)] pub struct Foo { - pub bar: *mut ::std::option::Option baz>, + pub bar: ::std::option::Option baz>, } #[test] fn bindgen_test_layout_Foo() { diff --git a/tests/expectations/func_with_func_ptr_arg.rs b/tests/expectations/func_with_func_ptr_arg.rs index b6e345f6d4..4ac2528674 100644 --- a/tests/expectations/func_with_func_ptr_arg.rs +++ b/tests/expectations/func_with_func_ptr_arg.rs @@ -5,5 +5,5 @@ extern "C" { - pub fn foo(bar: *mut ::std::option::Option); + pub fn foo(bar: ::std::option::Option); } diff --git a/tests/expectations/jsval_layout_opaque.rs b/tests/expectations/jsval_layout_opaque.rs index 69fe54dc0e..dd432232d3 100644 --- a/tests/expectations/jsval_layout_opaque.rs +++ b/tests/expectations/jsval_layout_opaque.rs @@ -93,8 +93,8 @@ pub enum JSWhyMagic { #[derive(Debug, Copy)] pub struct jsval_layout { pub asBits: __BindgenUnionField, - pub debugView: __BindgenUnionField, - pub s: __BindgenUnionField, + pub debugView: __BindgenUnionField, + pub s: __BindgenUnionField, pub asDouble: __BindgenUnionField, pub asPtr: __BindgenUnionField<*mut ::std::os::raw::c_void>, pub asWord: __BindgenUnionField, @@ -103,20 +103,20 @@ pub struct jsval_layout { } #[repr(C)] #[derive(Debug, Copy)] -pub struct jsval_layout__bindgen_ty_bindgen_id_81 { +pub struct jsval_layout__bindgen_ty_bindgen_id_89 { pub _bitfield_1: u64, } #[test] -fn bindgen_test_layout_jsval_layout__bindgen_ty_bindgen_id_81() { - assert_eq!(::std::mem::size_of::() +fn bindgen_test_layout_jsval_layout__bindgen_ty_bindgen_id_89() { + assert_eq!(::std::mem::size_of::() , 8usize); - assert_eq!(::std::mem::align_of::() + assert_eq!(::std::mem::align_of::() , 8usize); } -impl Clone for jsval_layout__bindgen_ty_bindgen_id_81 { +impl Clone for jsval_layout__bindgen_ty_bindgen_id_89 { fn clone(&self) -> Self { *self } } -impl jsval_layout__bindgen_ty_bindgen_id_81 { +impl jsval_layout__bindgen_ty_bindgen_id_89 { #[inline] pub fn payload47(&self) -> u64 { unsafe { @@ -149,36 +149,36 @@ impl jsval_layout__bindgen_ty_bindgen_id_81 { } #[repr(C)] #[derive(Debug, Copy)] -pub struct jsval_layout__bindgen_ty_bindgen_id_85 { - pub payload: jsval_layout__bindgen_ty_bindgen_id_85__bindgen_ty_bindgen_id_86, +pub struct jsval_layout__bindgen_ty_bindgen_id_96 { + pub payload: jsval_layout__bindgen_ty_bindgen_id_96__bindgen_ty_bindgen_id_97, } #[repr(C)] #[derive(Debug, Copy)] -pub struct jsval_layout__bindgen_ty_bindgen_id_85__bindgen_ty_bindgen_id_86 { +pub struct jsval_layout__bindgen_ty_bindgen_id_96__bindgen_ty_bindgen_id_97 { pub i32: __BindgenUnionField, pub u32: __BindgenUnionField, pub why: __BindgenUnionField, pub bindgen_union_field: u32, } #[test] -fn bindgen_test_layout_jsval_layout__bindgen_ty_bindgen_id_85__bindgen_ty_bindgen_id_86() { - assert_eq!(::std::mem::size_of::() +fn bindgen_test_layout_jsval_layout__bindgen_ty_bindgen_id_96__bindgen_ty_bindgen_id_97() { + assert_eq!(::std::mem::size_of::() , 4usize); - assert_eq!(::std::mem::align_of::() + assert_eq!(::std::mem::align_of::() , 4usize); } impl Clone for - jsval_layout__bindgen_ty_bindgen_id_85__bindgen_ty_bindgen_id_86 { + jsval_layout__bindgen_ty_bindgen_id_96__bindgen_ty_bindgen_id_97 { fn clone(&self) -> Self { *self } } #[test] -fn bindgen_test_layout_jsval_layout__bindgen_ty_bindgen_id_85() { - assert_eq!(::std::mem::size_of::() +fn bindgen_test_layout_jsval_layout__bindgen_ty_bindgen_id_96() { + assert_eq!(::std::mem::size_of::() , 4usize); - assert_eq!(::std::mem::align_of::() + assert_eq!(::std::mem::align_of::() , 4usize); } -impl Clone for jsval_layout__bindgen_ty_bindgen_id_85 { +impl Clone for jsval_layout__bindgen_ty_bindgen_id_96 { fn clone(&self) -> Self { *self } } impl Clone for jsval_layout { diff --git a/tests/expectations/namespace.rs b/tests/expectations/namespace.rs index 0bd6e8e07b..ed0ca603e2 100644 --- a/tests/expectations/namespace.rs +++ b/tests/expectations/namespace.rs @@ -18,7 +18,7 @@ pub mod root { pub fn in_whatever(); } } - pub mod _bindgen_mod_bindgen_id_12 { + pub mod _bindgen_mod_bindgen_id_13 { use root; pub mod empty { use root; @@ -44,7 +44,7 @@ pub mod root { #[repr(C)] #[derive(Debug)] pub struct C { - pub _base: root::_bindgen_mod_bindgen_id_12::A, + pub _base: root::_bindgen_mod_bindgen_id_13::A, pub m_c: T, pub m_c_ptr: *mut T, pub m_c_arr: [T; 10usize], @@ -78,7 +78,7 @@ extern "C" { #[repr(C)] #[derive(Debug)] pub struct C { - pub _base: root::_bindgen_mod_bindgen_id_12::A, + pub _base: root::_bindgen_mod_bindgen_id_13::A, pub m_c: T, pub m_c_ptr: *mut T, pub m_c_arr: [T; 10usize], diff --git a/tests/expectations/struct_with_anon_struct_array.rs b/tests/expectations/struct_with_anon_struct_array.rs index 48cc71d25f..c87605de11 100644 --- a/tests/expectations/struct_with_anon_struct_array.rs +++ b/tests/expectations/struct_with_anon_struct_array.rs @@ -8,7 +8,7 @@ #[derive(Debug, Copy)] pub struct foo { pub bar: [foo__bindgen_ty_bindgen_id_2; 2usize], - pub baz: [[[foo__bindgen_ty_bindgen_id_6; 4usize]; 3usize]; 2usize], + pub baz: [[[foo__bindgen_ty_bindgen_id_8; 4usize]; 3usize]; 2usize], } #[repr(C)] #[derive(Debug, Copy)] @@ -28,18 +28,18 @@ impl Clone for foo__bindgen_ty_bindgen_id_2 { } #[repr(C)] #[derive(Debug, Copy)] -pub struct foo__bindgen_ty_bindgen_id_6 { +pub struct foo__bindgen_ty_bindgen_id_8 { pub a: ::std::os::raw::c_int, pub b: ::std::os::raw::c_int, } #[test] -fn bindgen_test_layout_foo__bindgen_ty_bindgen_id_6() { - assert_eq!(::std::mem::size_of::() , +fn bindgen_test_layout_foo__bindgen_ty_bindgen_id_8() { + assert_eq!(::std::mem::size_of::() , 8usize); - assert_eq!(::std::mem::align_of::() , + assert_eq!(::std::mem::align_of::() , 4usize); } -impl Clone for foo__bindgen_ty_bindgen_id_6 { +impl Clone for foo__bindgen_ty_bindgen_id_8 { fn clone(&self) -> Self { *self } } #[test] diff --git a/tests/expectations/struct_with_nesting.rs b/tests/expectations/struct_with_nesting.rs index ca5ec09e68..75cfececd2 100644 --- a/tests/expectations/struct_with_nesting.rs +++ b/tests/expectations/struct_with_nesting.rs @@ -28,58 +28,40 @@ impl ::std::marker::Copy for __BindgenUnionField { } #[derive(Debug, Copy)] pub struct foo { pub a: ::std::os::raw::c_uint, - pub __bindgen_anon_1: foo__bindgen_ty_bindgen_id_3, + pub __bindgen_anon_1: foo__bindgen_ty_bindgen_id_4, } #[repr(C)] #[derive(Debug, Copy)] -pub struct foo__bindgen_ty_bindgen_id_3 { +pub struct foo__bindgen_ty_bindgen_id_4 { pub b: __BindgenUnionField<::std::os::raw::c_uint>, - pub __bindgen_anon_1: __BindgenUnionField, - pub __bindgen_anon_2: __BindgenUnionField, + pub __bindgen_anon_1: __BindgenUnionField, + pub __bindgen_anon_2: __BindgenUnionField, pub bindgen_union_field: u32, } #[repr(C)] #[derive(Debug, Copy)] -pub struct foo__bindgen_ty_bindgen_id_3__bindgen_ty_bindgen_id_5 { +pub struct foo__bindgen_ty_bindgen_id_4__bindgen_ty_bindgen_id_7 { pub c1: ::std::os::raw::c_ushort, pub c2: ::std::os::raw::c_ushort, } #[test] -fn bindgen_test_layout_foo__bindgen_ty_bindgen_id_3__bindgen_ty_bindgen_id_5() { - assert_eq!(::std::mem::size_of::() +fn bindgen_test_layout_foo__bindgen_ty_bindgen_id_4__bindgen_ty_bindgen_id_7() { + assert_eq!(::std::mem::size_of::() , 4usize); - assert_eq!(::std::mem::align_of::() + assert_eq!(::std::mem::align_of::() , 2usize); } -impl Clone for foo__bindgen_ty_bindgen_id_3__bindgen_ty_bindgen_id_5 { - fn clone(&self) -> Self { *self } -} -#[repr(C)] -#[derive(Debug, Copy)] -pub struct foo__bindgen_ty_bindgen_id_3__bindgen_ty_bindgen_id_8 { - pub d1: ::std::os::raw::c_uchar, - pub d2: ::std::os::raw::c_uchar, - pub d3: ::std::os::raw::c_uchar, - pub d4: ::std::os::raw::c_uchar, -} -#[test] -fn bindgen_test_layout_foo__bindgen_ty_bindgen_id_3__bindgen_ty_bindgen_id_8() { - assert_eq!(::std::mem::size_of::() - , 4usize); - assert_eq!(::std::mem::align_of::() - , 1usize); -} -impl Clone for foo__bindgen_ty_bindgen_id_3__bindgen_ty_bindgen_id_8 { +impl Clone for foo__bindgen_ty_bindgen_id_4__bindgen_ty_bindgen_id_7 { fn clone(&self) -> Self { *self } } #[test] -fn bindgen_test_layout_foo__bindgen_ty_bindgen_id_3() { - assert_eq!(::std::mem::size_of::() , +fn bindgen_test_layout_foo__bindgen_ty_bindgen_id_4() { + assert_eq!(::std::mem::size_of::() , 4usize); - assert_eq!(::std::mem::align_of::() , + assert_eq!(::std::mem::align_of::() , 4usize); } -impl Clone for foo__bindgen_ty_bindgen_id_3 { +impl Clone for foo__bindgen_ty_bindgen_id_4 { fn clone(&self) -> Self { *self } } #[test] diff --git a/tests/expectations/template_typedefs.rs b/tests/expectations/template_typedefs.rs new file mode 100644 index 0000000000..5f0d80b901 --- /dev/null +++ b/tests/expectations/template_typedefs.rs @@ -0,0 +1,22 @@ +/* automatically generated by rust-bindgen */ + + +#![allow(non_snake_case)] + + +pub type foo = + ::std::option::Option; +#[repr(C)] +#[derive(Debug, Copy, Clone)] +pub struct Foo { + pub _address: u8, + pub _phantom_0: ::std::marker::PhantomData, + pub _phantom_1: ::std::marker::PhantomData, +} +pub type Foo_Char = T; +pub type Foo_FooPtrTypedef = *mut Foo_Char; +pub type Foo_nsCOMArrayEnumFunc = + ::std::option::Option bool>; diff --git a/tests/expectations/typeref.rs b/tests/expectations/typeref.rs index 35a873c9e3..50795077c8 100644 --- a/tests/expectations/typeref.rs +++ b/tests/expectations/typeref.rs @@ -79,12 +79,12 @@ impl Clone for Bar { #[repr(C)] #[derive(Debug, Copy, Clone)] pub struct StyleShapeSource { - pub __bindgen_anon_1: StyleShapeSource__bindgen_ty_bindgen_id_13, + pub __bindgen_anon_1: StyleShapeSource__bindgen_ty_bindgen_id_14, pub _phantom_0: ::std::marker::PhantomData, } #[repr(C)] #[derive(Debug, Copy, Clone)] -pub struct StyleShapeSource__bindgen_ty_bindgen_id_13 { +pub struct StyleShapeSource__bindgen_ty_bindgen_id_14 { pub mPosition: __BindgenUnionField<*mut Position>, pub mFragmentOrURL: __BindgenUnionField<*mut FragmentOrURL>, pub bindgen_union_field: u64, diff --git a/tests/expectations/union_template.rs b/tests/expectations/union_template.rs index f07087de6a..1e3cf17ecb 100644 --- a/tests/expectations/union_template.rs +++ b/tests/expectations/union_template.rs @@ -28,13 +28,13 @@ impl ::std::marker::Copy for __BindgenUnionField { } #[derive(Debug, Copy, Clone)] pub struct NastyStruct { pub mIsSome: bool, - pub mStorage: NastyStruct__bindgen_ty_bindgen_id_5, - pub __bindgen_anon_1: NastyStruct__bindgen_ty_bindgen_id_9, + pub mStorage: NastyStruct__bindgen_ty_bindgen_id_6, + pub __bindgen_anon_1: NastyStruct__bindgen_ty_bindgen_id_12, pub _phantom_0: ::std::marker::PhantomData, } #[repr(C)] #[derive(Debug, Copy, Clone)] -pub struct NastyStruct__bindgen_ty_bindgen_id_5 { +pub struct NastyStruct__bindgen_ty_bindgen_id_6 { pub mFoo: __BindgenUnionField<*mut ::std::os::raw::c_void>, pub mDummy: __BindgenUnionField<::std::os::raw::c_ulong>, pub bindgen_union_field: u64, @@ -42,7 +42,7 @@ pub struct NastyStruct__bindgen_ty_bindgen_id_5 { } #[repr(C)] #[derive(Debug, Copy, Clone)] -pub struct NastyStruct__bindgen_ty_bindgen_id_9 { +pub struct NastyStruct__bindgen_ty_bindgen_id_12 { pub wat: __BindgenUnionField<::std::os::raw::c_short>, pub wut: __BindgenUnionField<*mut ::std::os::raw::c_int>, pub bindgen_union_field: u64, diff --git a/tests/expectations/union_with_anon_struct_bitfield.rs b/tests/expectations/union_with_anon_struct_bitfield.rs index 80be0e55e3..1332d92e44 100644 --- a/tests/expectations/union_with_anon_struct_bitfield.rs +++ b/tests/expectations/union_with_anon_struct_bitfield.rs @@ -28,25 +28,25 @@ impl ::std::marker::Copy for __BindgenUnionField { } #[derive(Debug, Copy)] pub struct foo { pub a: __BindgenUnionField<::std::os::raw::c_int>, - pub __bindgen_anon_1: __BindgenUnionField, + pub __bindgen_anon_1: __BindgenUnionField, pub bindgen_union_field: u32, } #[repr(C)] #[derive(Debug, Copy)] -pub struct foo__bindgen_ty_bindgen_id_3 { +pub struct foo__bindgen_ty_bindgen_id_4 { pub _bitfield_1: u32, } #[test] -fn bindgen_test_layout_foo__bindgen_ty_bindgen_id_3() { - assert_eq!(::std::mem::size_of::() , +fn bindgen_test_layout_foo__bindgen_ty_bindgen_id_4() { + assert_eq!(::std::mem::size_of::() , 4usize); - assert_eq!(::std::mem::align_of::() , + assert_eq!(::std::mem::align_of::() , 4usize); } -impl Clone for foo__bindgen_ty_bindgen_id_3 { +impl Clone for foo__bindgen_ty_bindgen_id_4 { fn clone(&self) -> Self { *self } } -impl foo__bindgen_ty_bindgen_id_3 { +impl foo__bindgen_ty_bindgen_id_4 { #[inline] pub fn b(&self) -> ::std::os::raw::c_int { unsafe { diff --git a/tests/expectations/union_with_anon_unnamed_struct.rs b/tests/expectations/union_with_anon_unnamed_struct.rs index 80b3e97af3..defbe66bc6 100644 --- a/tests/expectations/union_with_anon_unnamed_struct.rs +++ b/tests/expectations/union_with_anon_unnamed_struct.rs @@ -28,25 +28,25 @@ impl ::std::marker::Copy for __BindgenUnionField { } #[derive(Debug, Copy)] pub struct pixel { pub rgba: __BindgenUnionField<::std::os::raw::c_uint>, - pub __bindgen_anon_1: __BindgenUnionField, + pub __bindgen_anon_1: __BindgenUnionField, pub bindgen_union_field: u32, } #[repr(C)] #[derive(Debug, Copy)] -pub struct pixel__bindgen_ty_bindgen_id_3 { +pub struct pixel__bindgen_ty_bindgen_id_4 { pub r: ::std::os::raw::c_uchar, pub g: ::std::os::raw::c_uchar, pub b: ::std::os::raw::c_uchar, pub a: ::std::os::raw::c_uchar, } #[test] -fn bindgen_test_layout_pixel__bindgen_ty_bindgen_id_3() { - assert_eq!(::std::mem::size_of::() , +fn bindgen_test_layout_pixel__bindgen_ty_bindgen_id_4() { + assert_eq!(::std::mem::size_of::() , 4usize); - assert_eq!(::std::mem::align_of::() , + assert_eq!(::std::mem::align_of::() , 1usize); } -impl Clone for pixel__bindgen_ty_bindgen_id_3 { +impl Clone for pixel__bindgen_ty_bindgen_id_4 { fn clone(&self) -> Self { *self } } #[test] diff --git a/tests/expectations/union_with_anon_unnamed_union.rs b/tests/expectations/union_with_anon_unnamed_union.rs index 3ddea69e38..519bf61964 100644 --- a/tests/expectations/union_with_anon_unnamed_union.rs +++ b/tests/expectations/union_with_anon_unnamed_union.rs @@ -28,24 +28,24 @@ impl ::std::marker::Copy for __BindgenUnionField { } #[derive(Debug, Copy)] pub struct foo { pub a: __BindgenUnionField<::std::os::raw::c_uint>, - pub __bindgen_anon_1: __BindgenUnionField, + pub __bindgen_anon_1: __BindgenUnionField, pub bindgen_union_field: u32, } #[repr(C)] #[derive(Debug, Copy)] -pub struct foo__bindgen_ty_bindgen_id_3 { +pub struct foo__bindgen_ty_bindgen_id_4 { pub b: __BindgenUnionField<::std::os::raw::c_ushort>, pub c: __BindgenUnionField<::std::os::raw::c_uchar>, pub bindgen_union_field: u16, } #[test] -fn bindgen_test_layout_foo__bindgen_ty_bindgen_id_3() { - assert_eq!(::std::mem::size_of::() , +fn bindgen_test_layout_foo__bindgen_ty_bindgen_id_4() { + assert_eq!(::std::mem::size_of::() , 2usize); - assert_eq!(::std::mem::align_of::() , + assert_eq!(::std::mem::align_of::() , 2usize); } -impl Clone for foo__bindgen_ty_bindgen_id_3 { +impl Clone for foo__bindgen_ty_bindgen_id_4 { fn clone(&self) -> Self { *self } } #[test] diff --git a/tests/expectations/union_with_nesting.rs b/tests/expectations/union_with_nesting.rs index 6b8d318dd3..7534cf8188 100644 --- a/tests/expectations/union_with_nesting.rs +++ b/tests/expectations/union_with_nesting.rs @@ -28,57 +28,40 @@ impl ::std::marker::Copy for __BindgenUnionField { } #[derive(Debug, Copy)] pub struct foo { pub a: __BindgenUnionField<::std::os::raw::c_uint>, - pub __bindgen_anon_1: __BindgenUnionField, + pub __bindgen_anon_1: __BindgenUnionField, pub bindgen_union_field: u32, } #[repr(C)] #[derive(Debug, Copy)] -pub struct foo__bindgen_ty_bindgen_id_3 { - pub __bindgen_anon_1: foo__bindgen_ty_bindgen_id_3__bindgen_ty_bindgen_id_4, - pub __bindgen_anon_2: foo__bindgen_ty_bindgen_id_3__bindgen_ty_bindgen_id_7, +pub struct foo__bindgen_ty_bindgen_id_4 { + pub __bindgen_anon_1: foo__bindgen_ty_bindgen_id_4__bindgen_ty_bindgen_id_5, + pub __bindgen_anon_2: foo__bindgen_ty_bindgen_id_4__bindgen_ty_bindgen_id_5, } #[repr(C)] #[derive(Debug, Copy)] -pub struct foo__bindgen_ty_bindgen_id_3__bindgen_ty_bindgen_id_4 { +pub struct foo__bindgen_ty_bindgen_id_4__bindgen_ty_bindgen_id_5 { pub b1: __BindgenUnionField<::std::os::raw::c_ushort>, pub b2: __BindgenUnionField<::std::os::raw::c_ushort>, pub bindgen_union_field: u16, } #[test] -fn bindgen_test_layout_foo__bindgen_ty_bindgen_id_3__bindgen_ty_bindgen_id_4() { - assert_eq!(::std::mem::size_of::() +fn bindgen_test_layout_foo__bindgen_ty_bindgen_id_4__bindgen_ty_bindgen_id_5() { + assert_eq!(::std::mem::size_of::() , 2usize); - assert_eq!(::std::mem::align_of::() + assert_eq!(::std::mem::align_of::() , 2usize); } -impl Clone for foo__bindgen_ty_bindgen_id_3__bindgen_ty_bindgen_id_4 { - fn clone(&self) -> Self { *self } -} -#[repr(C)] -#[derive(Debug, Copy)] -pub struct foo__bindgen_ty_bindgen_id_3__bindgen_ty_bindgen_id_7 { - pub c1: __BindgenUnionField<::std::os::raw::c_ushort>, - pub c2: __BindgenUnionField<::std::os::raw::c_ushort>, - pub bindgen_union_field: u16, -} -#[test] -fn bindgen_test_layout_foo__bindgen_ty_bindgen_id_3__bindgen_ty_bindgen_id_7() { - assert_eq!(::std::mem::size_of::() - , 2usize); - assert_eq!(::std::mem::align_of::() - , 2usize); -} -impl Clone for foo__bindgen_ty_bindgen_id_3__bindgen_ty_bindgen_id_7 { +impl Clone for foo__bindgen_ty_bindgen_id_4__bindgen_ty_bindgen_id_5 { fn clone(&self) -> Self { *self } } #[test] -fn bindgen_test_layout_foo__bindgen_ty_bindgen_id_3() { - assert_eq!(::std::mem::size_of::() , +fn bindgen_test_layout_foo__bindgen_ty_bindgen_id_4() { + assert_eq!(::std::mem::size_of::() , 4usize); - assert_eq!(::std::mem::align_of::() , + assert_eq!(::std::mem::align_of::() , 2usize); } -impl Clone for foo__bindgen_ty_bindgen_id_3 { +impl Clone for foo__bindgen_ty_bindgen_id_4 { fn clone(&self) -> Self { *self } } #[test] diff --git a/tests/expectations/what_is_going_on.rs b/tests/expectations/what_is_going_on.rs index b6a5c86a00..6f1998d198 100644 --- a/tests/expectations/what_is_going_on.rs +++ b/tests/expectations/what_is_going_on.rs @@ -21,9 +21,8 @@ pub type Float = f32; #[repr(C)] #[derive(Debug, Copy, Clone)] pub struct PointTyped { - pub x: Float, - pub y: Float, + pub x: F, + pub y: F, pub _phantom_0: ::std::marker::PhantomData, - pub _phantom_1: ::std::marker::PhantomData, } pub type IntPoint = PointTyped; diff --git a/tests/headers/blocks.h b/tests/headers/blocks.h new file mode 100644 index 0000000000..80420e6e45 --- /dev/null +++ b/tests/headers/blocks.h @@ -0,0 +1,3 @@ +// bindgen-flags: -- -fblocks + +void atexit_b(void (^)(void)); diff --git a/tests/headers/template_typedefs.hpp b/tests/headers/template_typedefs.hpp new file mode 100644 index 0000000000..5e13dcd837 --- /dev/null +++ b/tests/headers/template_typedefs.hpp @@ -0,0 +1,8 @@ +typedef void (*foo)(int); + +template +class Foo { + typedef T Char; + typedef Char* FooPtrTypedef; + typedef bool (*nsCOMArrayEnumFunc)(T* aElement, void* aData); +}; From 506531522c5910717d89fc3bfdf07d0cdf65485a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Emilio=20Cobos=20=C3=81lvarez?= Date: Wed, 21 Sep 2016 22:24:29 +0200 Subject: [PATCH 2/5] Add Int128 types. --- src/codegen/mod.rs | 5 +++++ src/ir/context.rs | 2 ++ src/ir/int.rs | 6 ++++-- tests/expectations/int128_t.rs | 7 +++++++ tests/headers/int128_t.h | 7 +++++++ 5 files changed, 25 insertions(+), 2 deletions(-) create mode 100644 tests/expectations/int128_t.rs create mode 100644 tests/headers/int128_t.h diff --git a/src/codegen/mod.rs b/src/codegen/mod.rs index 8d5f453fed..7de416a8bf 100644 --- a/src/codegen/mod.rs +++ b/src/codegen/mod.rs @@ -1306,6 +1306,11 @@ impl ToRustTy for Type { IntKind::ULongLong => raw!(c_ulonglong), IntKind::U16 => aster::ty::TyBuilder::new().u16(), IntKind::U32 => aster::ty::TyBuilder::new().u32(), + // FIXME: This doesn't generate the proper alignment, but we + // can't do better right now. We should be able to use + // i128/u128 when they're available. + IntKind::U128 | + IntKind::I128 => ArrayTyBuilder::new().with_len(2).build(aster::ty::TyBuilder::new().u64()), } } TypeKind::Float(fk) => { diff --git a/src/ir/context.rs b/src/ir/context.rs index 4d5d88e4b7..f3c24db28d 100644 --- a/src/ir/context.rs +++ b/src/ir/context.rs @@ -583,6 +583,8 @@ impl<'ctx> BindgenContext<'ctx> { CXType_ULong => TypeKind::Int(IntKind::ULong), CXType_LongLong => TypeKind::Int(IntKind::LongLong), CXType_ULongLong => TypeKind::Int(IntKind::ULongLong), + CXType_Int128 => TypeKind::Int(IntKind::I128), + CXType_UInt128 => TypeKind::Int(IntKind::U128), CXType_Float => TypeKind::Float(FloatKind::Float), CXType_Double => TypeKind::Float(FloatKind::Double), CXType_LongDouble => TypeKind::Float(FloatKind::LongDouble), diff --git a/src/ir/int.rs b/src/ir/int.rs index d2769b772a..75e576d48a 100644 --- a/src/ir/int.rs +++ b/src/ir/int.rs @@ -13,6 +13,8 @@ pub enum IntKind { ULongLong, U16, // For Char16 and Wchar U32, // For Char32 + I128, + U128, // Though now we're at it we could add equivalents for the rust types... } @@ -21,10 +23,10 @@ impl IntKind { use self::IntKind::*; match *self { Bool | UChar | UShort | - UInt | ULong | ULongLong | U16 | U32 => false, + UInt | ULong | ULongLong | U16 | U32 | U128 => false, Char | Short | Int | - Long | LongLong => true, + Long | LongLong | I128 => true, } } } diff --git a/tests/expectations/int128_t.rs b/tests/expectations/int128_t.rs new file mode 100644 index 0000000000..b4b7b2bcee --- /dev/null +++ b/tests/expectations/int128_t.rs @@ -0,0 +1,7 @@ +/* automatically generated by rust-bindgen */ + + +#![allow(non_snake_case)] + + + diff --git a/tests/headers/int128_t.h b/tests/headers/int128_t.h new file mode 100644 index 0000000000..eece252c93 --- /dev/null +++ b/tests/headers/int128_t.h @@ -0,0 +1,7 @@ +/** + * FIXME: Uncomment this once we can generate the proper alignment for the type, + * i.e., when we use u128/i128. +struct Foo { + __int128 foo; +}; + */ From 6ed0253913afc0c0258eaedfb27d87322250f2b2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Emilio=20Cobos=20=C3=81lvarez?= Date: Wed, 21 Sep 2016 23:16:05 +0200 Subject: [PATCH 3/5] Index unnamed types by canonical declaration. This fixes union_with_nesting.h --- src/ir/context.rs | 45 +++++++++++++++++------ tests/expectations/struct_with_nesting.rs | 20 +++++++++- tests/expectations/union_with_nesting.rs | 19 +++++++++- 3 files changed, 71 insertions(+), 13 deletions(-) diff --git a/src/ir/context.rs b/src/ir/context.rs index f3c24db28d..559dd2bacc 100644 --- a/src/ir/context.rs +++ b/src/ir/context.rs @@ -14,6 +14,18 @@ use syntax::ext::base::ExtCtxt; use parse::ClangItemParser; use BindgenOptions; +/// A key used to index a resolved type, so we only process it once. +/// +/// This is almost always a USR string (an unique identifier generated by +/// clang), but it can also be the canonical declaration if the type is unnamed, +/// in which case clang may generate the same USR for multiple nested unnamed +/// types. +#[derive(Eq, PartialEq, Hash, Debug)] +enum TypeKey { + USR(String), + Declaration(Cursor), +} + // This is just convenience to avoid creating a manual debug impl for the // context. struct GenContext<'ctx>(ExtCtxt<'ctx>); @@ -35,7 +47,7 @@ pub struct BindgenContext<'ctx> { /// Clang USR to type map. This is needed to be able to associate types with /// item ids during parsing. - types: HashMap, + types: HashMap, /// A cursor to module map. Similar reason than above. modules: HashMap, @@ -129,9 +141,13 @@ impl<'ctx> BindgenContext<'ctx> { let id = item.id(); let is_type = item.kind().is_type(); + let is_unnamed = is_type && item.expect_type().name().is_none(); let old_item = self.items.insert(id, item); assert!(old_item.is_none(), "Inserted type twice?"); + // Unnamed items can have an USR, but they can't be referenced from + // other sites explicitly and the USR can match if the unnamed items are + // nested, so don't bother tracking them. if is_type && declaration.is_some() { let mut declaration = declaration.unwrap(); if !declaration.is_valid() { @@ -143,8 +159,6 @@ impl<'ctx> BindgenContext<'ctx> { } } declaration = declaration.canonical(); - - if !declaration.is_valid() { // This could happen, for example, with types like `int*` or // similar. @@ -156,12 +170,17 @@ impl<'ctx> BindgenContext<'ctx> { return; } - if let Some(usr) = declaration.usr() { - let old = self.types.insert(usr, id); - debug_assert_eq!(old, None); + let key = if is_unnamed { + TypeKey::Declaration(declaration) + } else if let Some(usr) = declaration.usr() { + TypeKey::USR(usr) } else { error!("Valid declaration with no USR: {:?}, {:?}", declaration, location); - } + return; + }; + + let old = self.types.insert(key, id); + debug_assert_eq!(old, None); } } @@ -503,10 +522,14 @@ impl<'ctx> BindgenContext<'ctx> { let canonical_declaration = declaration.canonical(); if canonical_declaration.is_valid() { let id = - canonical_declaration - .usr() - .and_then(|usr| self.types.get(&usr)) - .map(|id| *id); + self.types.get(&TypeKey::Declaration(canonical_declaration)) + .map(|id| *id) + .or_else(|| { + canonical_declaration.usr().and_then(|usr| { + self.types.get(&TypeKey::USR(usr)) + }) + .map(|id| *id) + }); if let Some(id) = id { debug!("Already resolved ty {:?}, {:?}, {:?} {:?}", id, declaration, ty, location); diff --git a/tests/expectations/struct_with_nesting.rs b/tests/expectations/struct_with_nesting.rs index 75cfececd2..9eeeb56ef4 100644 --- a/tests/expectations/struct_with_nesting.rs +++ b/tests/expectations/struct_with_nesting.rs @@ -35,7 +35,7 @@ pub struct foo { pub struct foo__bindgen_ty_bindgen_id_4 { pub b: __BindgenUnionField<::std::os::raw::c_uint>, pub __bindgen_anon_1: __BindgenUnionField, - pub __bindgen_anon_2: __BindgenUnionField, + pub __bindgen_anon_2: __BindgenUnionField, pub bindgen_union_field: u32, } #[repr(C)] @@ -54,6 +54,24 @@ fn bindgen_test_layout_foo__bindgen_ty_bindgen_id_4__bindgen_ty_bindgen_id_7() { impl Clone for foo__bindgen_ty_bindgen_id_4__bindgen_ty_bindgen_id_7 { fn clone(&self) -> Self { *self } } +#[repr(C)] +#[derive(Debug, Copy)] +pub struct foo__bindgen_ty_bindgen_id_4__bindgen_ty_bindgen_id_12 { + pub d1: ::std::os::raw::c_uchar, + pub d2: ::std::os::raw::c_uchar, + pub d3: ::std::os::raw::c_uchar, + pub d4: ::std::os::raw::c_uchar, +} +#[test] +fn bindgen_test_layout_foo__bindgen_ty_bindgen_id_4__bindgen_ty_bindgen_id_12() { + assert_eq!(::std::mem::size_of::() + , 4usize); + assert_eq!(::std::mem::align_of::() + , 1usize); +} +impl Clone for foo__bindgen_ty_bindgen_id_4__bindgen_ty_bindgen_id_12 { + fn clone(&self) -> Self { *self } +} #[test] fn bindgen_test_layout_foo__bindgen_ty_bindgen_id_4() { assert_eq!(::std::mem::size_of::() , diff --git a/tests/expectations/union_with_nesting.rs b/tests/expectations/union_with_nesting.rs index 7534cf8188..d7fc780a5b 100644 --- a/tests/expectations/union_with_nesting.rs +++ b/tests/expectations/union_with_nesting.rs @@ -35,7 +35,7 @@ pub struct foo { #[derive(Debug, Copy)] pub struct foo__bindgen_ty_bindgen_id_4 { pub __bindgen_anon_1: foo__bindgen_ty_bindgen_id_4__bindgen_ty_bindgen_id_5, - pub __bindgen_anon_2: foo__bindgen_ty_bindgen_id_4__bindgen_ty_bindgen_id_5, + pub __bindgen_anon_2: foo__bindgen_ty_bindgen_id_4__bindgen_ty_bindgen_id_10, } #[repr(C)] #[derive(Debug, Copy)] @@ -54,6 +54,23 @@ fn bindgen_test_layout_foo__bindgen_ty_bindgen_id_4__bindgen_ty_bindgen_id_5() { impl Clone for foo__bindgen_ty_bindgen_id_4__bindgen_ty_bindgen_id_5 { fn clone(&self) -> Self { *self } } +#[repr(C)] +#[derive(Debug, Copy)] +pub struct foo__bindgen_ty_bindgen_id_4__bindgen_ty_bindgen_id_10 { + pub c1: __BindgenUnionField<::std::os::raw::c_ushort>, + pub c2: __BindgenUnionField<::std::os::raw::c_ushort>, + pub bindgen_union_field: u16, +} +#[test] +fn bindgen_test_layout_foo__bindgen_ty_bindgen_id_4__bindgen_ty_bindgen_id_10() { + assert_eq!(::std::mem::size_of::() + , 2usize); + assert_eq!(::std::mem::align_of::() + , 2usize); +} +impl Clone for foo__bindgen_ty_bindgen_id_4__bindgen_ty_bindgen_id_10 { + fn clone(&self) -> Self { *self } +} #[test] fn bindgen_test_layout_foo__bindgen_ty_bindgen_id_4() { assert_eq!(::std::mem::size_of::() , From dd45e455fa7e6f1877091a584c7872e750678bb9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Emilio=20Cobos=20=C3=81lvarez?= Date: Thu, 22 Sep 2016 02:45:20 +0200 Subject: [PATCH 4/5] Test weird edge cases with template params and stuff. --- .../struct_with_typedef_template_arg.rs | 15 +++++++++++++++ .../headers/struct_with_typedef_template_arg.hpp | 4 ++++ 2 files changed, 19 insertions(+) create mode 100644 tests/expectations/struct_with_typedef_template_arg.rs create mode 100644 tests/headers/struct_with_typedef_template_arg.hpp diff --git a/tests/expectations/struct_with_typedef_template_arg.rs b/tests/expectations/struct_with_typedef_template_arg.rs new file mode 100644 index 0000000000..6f8d71f183 --- /dev/null +++ b/tests/expectations/struct_with_typedef_template_arg.rs @@ -0,0 +1,15 @@ +/* automatically generated by rust-bindgen */ + + +#![allow(non_snake_case)] + + +#[repr(C)] +#[derive(Debug, Copy, Clone)] +pub struct Proxy { + pub _address: u8, + pub _phantom_0: ::std::marker::PhantomData, + pub _phantom_1: ::std::marker::PhantomData, +} +pub type Proxy_foo = + ::std::option::Option; diff --git a/tests/headers/struct_with_typedef_template_arg.hpp b/tests/headers/struct_with_typedef_template_arg.hpp new file mode 100644 index 0000000000..7fed21ab18 --- /dev/null +++ b/tests/headers/struct_with_typedef_template_arg.hpp @@ -0,0 +1,4 @@ +template +struct Proxy { + typedef void (*foo)(T* bar); +}; From cc8ed879bc99449146539ed41042b5c8f07545f6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Emilio=20Cobos=20=C3=81lvarez?= Date: Thu, 22 Sep 2016 12:29:39 +0200 Subject: [PATCH 5/5] Represent block pointers as *mut c_void instead. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Emilio Cobos Álvarez --- src/codegen/mod.rs | 5 +++++ src/ir/ty.rs | 14 +++++++++++--- tests/expectations/blocks.rs | 2 +- 3 files changed, 17 insertions(+), 4 deletions(-) diff --git a/src/codegen/mod.rs b/src/codegen/mod.rs index 7de416a8bf..36f20689ec 100644 --- a/src/codegen/mod.rs +++ b/src/codegen/mod.rs @@ -311,6 +311,7 @@ impl CodeGenerator for Type { TypeKind::Float(..) | TypeKind::Array(..) | TypeKind::Pointer(..) | + TypeKind::BlockPointer | TypeKind::Reference(..) | TypeKind::TemplateRef(..) | TypeKind::Function(..) | @@ -1382,6 +1383,10 @@ impl ToRustTy for Type { utils::build_templated_path(item, ctx, false) } + TypeKind::BlockPointer => { + let void = raw!(c_void); + void.to_ptr(/* is_const = */ false, ctx.span()) + } TypeKind::Pointer(inner) | TypeKind::Reference(inner) => { let inner = ctx.resolve_item(inner); diff --git a/src/ir/ty.rs b/src/ir/ty.rs index b0bf9bf634..97cdf9255d 100644 --- a/src/ir/ty.rs +++ b/src/ir/ty.rs @@ -90,6 +90,7 @@ impl Type { TypeKind::Array(..) | TypeKind::Reference(..) | TypeKind::Pointer(..) | + TypeKind::BlockPointer | TypeKind::Int(..) | TypeKind::Float(..) | TypeKind::Named(..) => true, @@ -124,8 +125,9 @@ impl Type { TypeKind::Comp(ref ci) => ci.layout(type_resolver), // FIXME(emilio): This is a hack for anonymous union templates. - // Use the actual pointer size! - TypeKind::Pointer(..) + // Use the actual pointer size! + TypeKind::Pointer(..) | + TypeKind::BlockPointer => Some(Layout::new(mem::size_of::<*mut ()>(), mem::align_of::<*mut ()>())), TypeKind::ResolvedTypeRef(inner) => type_resolver.resolve_type(inner).layout(type_resolver), @@ -286,6 +288,7 @@ impl Type { TypeKind::Reference(..) | TypeKind::Void | TypeKind::NullPtr | + TypeKind::BlockPointer | TypeKind::Pointer(..) => self, TypeKind::ResolvedTypeRef(inner) | @@ -334,6 +337,8 @@ pub enum TypeKind { /// A pointer to a type. The bool field represents whether it's const or /// not. Pointer(ItemId), + /// A pointer to an Apple block. + BlockPointer, /// A reference to a type, as in: int& foo(). Reference(ItemId), /// A reference to a template, with different template parameter names. To @@ -376,6 +381,7 @@ impl Type { TypeKind::Enum(..) | TypeKind::Reference(..) | TypeKind::NullPtr | + TypeKind::BlockPointer | TypeKind::Pointer(..) => false, TypeKind::UnresolvedTypeRef(..) @@ -485,13 +491,15 @@ impl Type { // We might need to, though, if the context is already in the // process of resolving them. CXType_MemberPointer | - CXType_BlockPointer | CXType_Pointer => { let inner = Item::from_ty_or_ref(ty.pointee_type(), location, parent_id, ctx); TypeKind::Pointer(inner) } + CXType_BlockPointer => { + TypeKind::BlockPointer + } // XXX: RValueReference is most likely wrong, but I don't think we // can even add bindings for that, so huh. CXType_RValueReference | diff --git a/tests/expectations/blocks.rs b/tests/expectations/blocks.rs index 88a797e224..528ea5182a 100644 --- a/tests/expectations/blocks.rs +++ b/tests/expectations/blocks.rs @@ -5,5 +5,5 @@ extern "C" { - pub fn atexit_b(arg1: ::std::option::Option); + pub fn atexit_b(arg1: *mut ::std::os::raw::c_void); }