diff options
-rw-r--r-- | README.md | 2 | ||||
-rw-r--r-- | src/clang.rs | 17 | ||||
-rw-r--r-- | src/codegen/struct_layout.rs | 5 | ||||
-rw-r--r-- | tests/expectations/tests/issue-493.rs | 152 | ||||
-rw-r--r-- | tests/headers/issue-493.hpp | 47 |
5 files changed, 219 insertions, 4 deletions
@@ -151,7 +151,7 @@ include!(concat!(env!("OUT_DIR"), "/example.rs")); $ cargo install bindgen ``` -There are a few options documented when running `./bindgen --help`. +There are a few options documented when running `bindgen --help`. Bindgen is installed to `~/.cargo/bin`. You have to add that directory to your path to use `bindgen`. ### C++ diff --git a/src/clang.rs b/src/clang.rs index 1a346898..e74f1a61 100644 --- a/src/clang.rs +++ b/src/clang.rs @@ -69,7 +69,11 @@ impl Cursor { /// Get the mangled name of this cursor's referent. pub fn mangling(&self) -> String { - unsafe { cxstring_into_string(clang_Cursor_getMangling(self.x)) } + if clang_Cursor_getMangling::is_loaded() { + unsafe { cxstring_into_string(clang_Cursor_getMangling(self.x)) } + } else { + self.spelling() + } } /// Get the `Cursor` for this cursor's referent's lexical parent. @@ -443,7 +447,11 @@ impl Cursor { /// Get the visibility of this cursor's referent. pub fn visibility(&self) -> CXVisibilityKind { - unsafe { clang_getCursorVisibility(self.x) } + if clang_getCursorVisibility::is_loaded() { + unsafe { clang_getCursorVisibility(self.x) } + } else { + CXVisibility_Default + } } /// Given that this cursor's referent is a function, return cursors to its @@ -491,11 +499,16 @@ impl Cursor { /// Is this cursor's referent a field declaration that is marked as /// `mutable`? pub fn is_mutable_field(&self) -> bool { + clang_CXXField_isMutable::is_loaded() && unsafe { clang_CXXField_isMutable(self.x) != 0 } } /// Get the offset of the field represented by the Cursor. pub fn offset_of_field(&self) -> Result<usize, LayoutError> { + if !clang_Cursor_getOffsetOfField::is_loaded() { + return Err(LayoutError::from(-1)); + } + let offset = unsafe { clang_Cursor_getOffsetOfField(self.x) }; if offset < 0 { diff --git a/src/codegen/struct_layout.rs b/src/codegen/struct_layout.rs index 98640570..f8a88bc2 100644 --- a/src/codegen/struct_layout.rs +++ b/src/codegen/struct_layout.rs @@ -89,9 +89,12 @@ impl<'a, 'ctx> StructLayoutTracker<'a, 'ctx> { Some(offset) if offset / 8 > self.latest_offset => { (offset / 8 - self.latest_offset, true) } - _ => { + _ if field_layout.align != 0 => { (self.padding_bytes(field_layout), (self.latest_offset % field_layout.align) != 0) } + _ => { + (0, false) + } }; self.latest_offset += padding_bytes; diff --git a/tests/expectations/tests/issue-493.rs b/tests/expectations/tests/issue-493.rs new file mode 100644 index 00000000..f8814bd3 --- /dev/null +++ b/tests/expectations/tests/issue-493.rs @@ -0,0 +1,152 @@ +/* automatically generated by rust-bindgen */ + + +#![allow(non_snake_case)] + + +#[repr(C)] +pub struct __BindgenUnionField<T>(::std::marker::PhantomData<T>); +impl <T> __BindgenUnionField<T> { + #[inline] + pub fn new() -> Self { __BindgenUnionField(::std::marker::PhantomData) } + #[inline] + pub unsafe fn as_ref(&self) -> &T { ::std::mem::transmute(self) } + #[inline] + pub unsafe fn as_mut(&mut self) -> &mut T { ::std::mem::transmute(self) } +} +impl <T> ::std::default::Default for __BindgenUnionField<T> { + #[inline] + fn default() -> Self { Self::new() } +} +impl <T> ::std::clone::Clone for __BindgenUnionField<T> { + #[inline] + fn clone(&self) -> Self { Self::new() } +} +impl <T> ::std::marker::Copy for __BindgenUnionField<T> { } +impl <T> ::std::fmt::Debug for __BindgenUnionField<T> { + fn fmt(&self, fmt: &mut ::std::fmt::Formatter) -> ::std::fmt::Result { + fmt.write_str("__BindgenUnionField") + } +} +#[repr(C)] +#[derive(Debug, Copy, Clone)] +pub struct basic_string<_CharT, _Traits, _Allocator> { + pub _address: u8, + pub _phantom_0: ::std::marker::PhantomData<_CharT>, + pub _phantom_1: ::std::marker::PhantomData<_Traits>, + pub _phantom_2: ::std::marker::PhantomData<_Allocator>, +} +pub type basic_string_size_type = ::std::os::raw::c_ulonglong; +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)] +pub struct basic_string___long<_CharT, _Traits, _Allocator> { + pub __cap_: basic_string_size_type, + pub __size_: basic_string_size_type, + pub __data_: basic_string_pointer, + pub _phantom_0: ::std::marker::PhantomData<_CharT>, + pub _phantom_1: ::std::marker::PhantomData<_Traits>, + pub _phantom_2: ::std::marker::PhantomData<_Allocator>, +} +impl <_CharT, _Traits, _Allocator> Default for + basic_string___long<_CharT, _Traits, _Allocator> { + fn default() -> Self { unsafe { ::std::mem::zeroed() } } +} +pub const basic_string___min_cap: basic_string__bindgen_ty_1 = + basic_string__bindgen_ty_1::__min_cap; +#[repr(i32)] +#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)] +pub enum basic_string__bindgen_ty_1 { __min_cap = 0, } +#[repr(C)] +#[derive(Debug, Copy, Clone)] +pub struct basic_string___short<_CharT, _Traits, _Allocator> { + pub __bindgen_anon_1: basic_string___short__bindgen_ty_1<_CharT, _Traits, + _Allocator>, + pub __data_: *mut basic_string_value_type, + pub _phantom_0: ::std::marker::PhantomData<_CharT>, + pub _phantom_1: ::std::marker::PhantomData<_Traits>, + pub _phantom_2: ::std::marker::PhantomData<_Allocator>, +} +#[repr(C)] +#[derive(Debug, Default, Copy, Clone)] +pub struct basic_string___short__bindgen_ty_1<_CharT, _Traits, _Allocator> { + pub __size_: __BindgenUnionField<::std::os::raw::c_uchar>, + pub __lx: __BindgenUnionField<basic_string_value_type>, + pub bindgen_union_field: u8, + pub _phantom_0: ::std::marker::PhantomData<_CharT>, + pub _phantom_1: ::std::marker::PhantomData<_Traits>, + pub _phantom_2: ::std::marker::PhantomData<_Allocator>, +} +impl <_CharT, _Traits, _Allocator> Default for + basic_string___short<_CharT, _Traits, _Allocator> { + fn default() -> Self { unsafe { ::std::mem::zeroed() } } +} +#[repr(C)] +#[derive(Copy, Clone)] +pub struct basic_string___ulx<_CharT, _Traits, _Allocator> { + pub __lx: __BindgenUnionField<basic_string___long<_CharT, _Traits, + _Allocator>>, + pub __lxx: __BindgenUnionField<basic_string___short<_CharT, _Traits, + _Allocator>>, + pub bindgen_union_field: [u8; 0usize], + pub _phantom_0: ::std::marker::PhantomData<_CharT>, + pub _phantom_1: ::std::marker::PhantomData<_Traits>, + pub _phantom_2: ::std::marker::PhantomData<_Allocator>, +} +impl <_CharT, _Traits, _Allocator> Default for + basic_string___ulx<_CharT, _Traits, _Allocator> { + fn default() -> Self { unsafe { ::std::mem::zeroed() } } +} +pub const basic_string___n_words: basic_string__bindgen_ty_2 = + basic_string__bindgen_ty_2::__n_words; +#[repr(i32)] +#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)] +pub enum basic_string__bindgen_ty_2 { __n_words = 0, } +#[repr(C)] +#[derive(Debug, Copy, Clone)] +pub struct basic_string___raw<_CharT, _Traits, _Allocator> { + pub __words: *mut basic_string_size_type, + pub _phantom_0: ::std::marker::PhantomData<_CharT>, + pub _phantom_1: ::std::marker::PhantomData<_Traits>, + pub _phantom_2: ::std::marker::PhantomData<_Allocator>, +} +impl <_CharT, _Traits, _Allocator> Default for + basic_string___raw<_CharT, _Traits, _Allocator> { + fn default() -> Self { unsafe { ::std::mem::zeroed() } } +} +#[repr(C)] +#[derive(Copy, Clone)] +pub struct basic_string___rep<_CharT, _Traits, _Allocator> { + pub __bindgen_anon_1: basic_string___rep__bindgen_ty_1<_CharT, _Traits, + _Allocator>, + pub _phantom_0: ::std::marker::PhantomData<_CharT>, + pub _phantom_1: ::std::marker::PhantomData<_Traits>, + pub _phantom_2: ::std::marker::PhantomData<_Allocator>, +} +#[repr(C)] +#[derive(Copy, Clone)] +pub struct basic_string___rep__bindgen_ty_1<_CharT, _Traits, _Allocator> { + pub __l: __BindgenUnionField<basic_string___long<_CharT, _Traits, + _Allocator>>, + pub __s: __BindgenUnionField<basic_string___short<_CharT, _Traits, + _Allocator>>, + pub __r: __BindgenUnionField<basic_string___raw<_CharT, _Traits, + _Allocator>>, + pub bindgen_union_field: [u8; 0usize], + pub _phantom_0: ::std::marker::PhantomData<_CharT>, + pub _phantom_1: ::std::marker::PhantomData<_Traits>, + pub _phantom_2: ::std::marker::PhantomData<_Allocator>, +} +impl <_CharT, _Traits, _Allocator> Default for + basic_string___rep__bindgen_ty_1<_CharT, _Traits, _Allocator> { + fn default() -> Self { unsafe { ::std::mem::zeroed() } } +} +impl <_CharT, _Traits, _Allocator> Default for + basic_string___rep<_CharT, _Traits, _Allocator> { + fn default() -> Self { unsafe { ::std::mem::zeroed() } } +} +impl <_CharT, _Traits, _Allocator> Default for + basic_string<_CharT, _Traits, _Allocator> { + fn default() -> Self { unsafe { ::std::mem::zeroed() } } +} diff --git a/tests/headers/issue-493.hpp b/tests/headers/issue-493.hpp new file mode 100644 index 00000000..975ef5ce --- /dev/null +++ b/tests/headers/issue-493.hpp @@ -0,0 +1,47 @@ +template<class _CharT, class _Traits, class _Allocator> +class basic_string +{ +public: + typedef unsigned long long size_type; + typedef char value_type; + typedef value_type * pointer; + + struct __long + { + size_type __cap_; + size_type __size_; + pointer __data_; + }; + + enum {__min_cap = (sizeof(__long) - 1)/sizeof(value_type) > 2 ? + (sizeof(__long) - 1)/sizeof(value_type) : 2}; + + struct __short + { + union + { + unsigned char __size_; + value_type __lx; + }; + value_type __data_[__min_cap]; + }; + + union __ulx{__long __lx; __short __lxx;}; + + enum {__n_words = sizeof(__ulx) / sizeof(size_type)}; + + struct __raw + { + size_type __words[__n_words]; + }; + + struct __rep + { + union + { + __long __l; + __short __s; + __raw __r; + }; + }; +};
\ No newline at end of file |