diff options
-rw-r--r-- | README.md | 2 | ||||
-rw-r--r-- | src/clang.rs | 24 | ||||
-rw-r--r-- | src/codegen/struct_layout.rs | 5 | ||||
-rw-r--r-- | src/ir/comp.rs | 5 | ||||
-rw-r--r-- | tests/expectations/tests/issue-493.rs | 152 | ||||
-rw-r--r-- | tests/headers/issue-493.hpp | 47 |
6 files changed, 219 insertions, 16 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 15cd60fc..bcb22e06 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. @@ -212,11 +216,6 @@ impl Cursor { unsafe { clang_isCursorDefinition(self.x) != 0 } } - /// Is the referent an anonymous record definition? - pub fn is_anonymous(&self) -> bool { - unsafe { clang_Cursor_isAnonymous(self.x) != 0 } - } - /// Is the referent a template specialization? pub fn is_template_specialization(&self) -> bool { self.specialized().is_some() @@ -483,7 +482,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 @@ -531,11 +534,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 { @@ -1420,8 +1428,6 @@ pub fn ast_dump(c: &Cursor, depth: isize) -> CXChildVisitResult { prefix, c.is_declaration())); print_indent(depth, - format!(" {}is-anonymous? {}", prefix, c.is_anonymous())); - print_indent(depth, format!(" {}is-inlined-function? {}", prefix, c.is_inlined_function())); 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/src/ir/comp.rs b/src/ir/comp.rs index 80372cab..b02cd342 100644 --- a/src/ir/comp.rs +++ b/src/ir/comp.rs @@ -289,9 +289,6 @@ pub struct CompInfo { /// Whether this struct layout is packed. packed: bool, - /// Whether this struct is anonymous. - is_anonymous: bool, - /// Used to know if we've found an opaque attribute that could cause us to /// generate a type with invalid layout. This is explicitly used to avoid us /// generating bad alignments when parsing types like max_align_t. @@ -335,7 +332,6 @@ impl CompInfo { has_nonempty_base: false, has_non_type_template_params: false, packed: false, - is_anonymous: false, found_unknown_attr: false, detect_derive_debug_cycle: Cell::new(false), detect_derive_default_cycle: Cell::new(false), @@ -562,7 +558,6 @@ impl CompInfo { CXCursor_ClassDecl => !cur.is_definition(), _ => false, }); - ci.is_anonymous = cursor.is_anonymous(); ci.template_args = match ty.template_args() { // In forward declarations and not specializations, etc, they are in // the ast, we'll meet them in CXCursor_TemplateTypeParameter 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 |