summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--README.md2
-rw-r--r--src/clang.rs24
-rw-r--r--src/codegen/struct_layout.rs5
-rw-r--r--src/ir/comp.rs5
-rw-r--r--tests/expectations/tests/issue-493.rs152
-rw-r--r--tests/headers/issue-493.hpp47
6 files changed, 219 insertions, 16 deletions
diff --git a/README.md b/README.md
index f0104fc9..f1a85cec 100644
--- a/README.md
+++ b/README.md
@@ -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