Skip to content

ir: consider all nested definitions inside structs to be inner types. #644

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Apr 19, 2017
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
18 changes: 8 additions & 10 deletions src/ir/comp.rs
Original file line number Diff line number Diff line change
Expand Up @@ -588,21 +588,19 @@ impl CompInfo {
CXCursor_ClassTemplate |
CXCursor_ClassDecl => {
// We can find non-semantic children here, clang uses a
// StructDecl to note incomplete structs that hasn't been
// forward-declared before, see:
// StructDecl to note incomplete structs that haven't been
// forward-declared before, see [1].
//
// Also, clang seems to scope struct definitions inside
// unions to the whole translation unit. Since those are
// anonymous, let's just assume that if the cursor we've
// found is a definition it's a valid inner type.
// unions, and other named struct definitions inside other
// structs to the whole translation unit.
//
// Note that doing this could be always ok, but let's just
// keep the union check for now.
// Let's just assume that if the cursor we've found is a
// definition, it's a valid inner type.
//
// https://github.com/servo/rust-bindgen/issues/482
// [1]: https://github.com/servo/rust-bindgen/issues/482
let is_inner_struct = cur.semantic_parent() == cursor ||
(kind == CompKind::Union &&
cur.is_definition());
cur.is_definition();
if !is_inner_struct {
return CXChildVisit_Continue;
}
Expand Down
108 changes: 108 additions & 0 deletions tests/expectations/tests/issue-643-inner-struct.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,108 @@
/* automatically generated by rust-bindgen */


#![allow(non_snake_case)]


#[repr(C)]
#[derive(Default)]
pub struct __IncompleteArrayField<T>(::std::marker::PhantomData<T>);
impl <T> __IncompleteArrayField<T> {
#[inline]
pub fn new() -> Self {
__IncompleteArrayField(::std::marker::PhantomData)
}
#[inline]
pub unsafe fn as_ptr(&self) -> *const T { ::std::mem::transmute(self) }
#[inline]
pub unsafe fn as_mut_ptr(&mut self) -> *mut T {
::std::mem::transmute(self)
}
#[inline]
pub unsafe fn as_slice(&self, len: usize) -> &[T] {
::std::slice::from_raw_parts(self.as_ptr(), len)
}
#[inline]
pub unsafe fn as_mut_slice(&mut self, len: usize) -> &mut [T] {
::std::slice::from_raw_parts_mut(self.as_mut_ptr(), len)
}
}
impl <T> ::std::fmt::Debug for __IncompleteArrayField<T> {
fn fmt(&self, fmt: &mut ::std::fmt::Formatter) -> ::std::fmt::Result {
fmt.write_str("__IncompleteArrayField")
}
}
impl <T> ::std::clone::Clone for __IncompleteArrayField<T> {
#[inline]
fn clone(&self) -> Self { Self::new() }
}
impl <T> ::std::marker::Copy for __IncompleteArrayField<T> { }
#[repr(C)]
#[derive(Debug, Copy)]
pub struct rte_ring {
pub memzone: *mut rte_memzone,
pub prod: rte_ring_prod,
pub cons: rte_ring_cons,
pub ring: __IncompleteArrayField<*mut ::std::os::raw::c_void>,
}
#[repr(C)]
#[derive(Debug, Default, Copy)]
pub struct rte_ring_prod {
pub watermark: ::std::os::raw::c_uint,
}
#[test]
fn bindgen_test_layout_rte_ring_prod() {
assert_eq!(::std::mem::size_of::<rte_ring_prod>() , 4usize , concat ! (
"Size of: " , stringify ! ( rte_ring_prod ) ));
assert_eq! (::std::mem::align_of::<rte_ring_prod>() , 4usize , concat ! (
"Alignment of " , stringify ! ( rte_ring_prod ) ));
assert_eq! (unsafe {
& ( * ( 0 as * const rte_ring_prod ) ) . watermark as * const
_ as usize } , 0usize , concat ! (
"Alignment of field: " , stringify ! ( rte_ring_prod ) , "::"
, stringify ! ( watermark ) ));
}
impl Clone for rte_ring_prod {
fn clone(&self) -> Self { *self }
}
#[repr(C)]
#[derive(Debug, Default, Copy)]
pub struct rte_ring_cons {
pub sc_dequeue: ::std::os::raw::c_uint,
}
#[test]
fn bindgen_test_layout_rte_ring_cons() {
assert_eq!(::std::mem::size_of::<rte_ring_cons>() , 4usize , concat ! (
"Size of: " , stringify ! ( rte_ring_cons ) ));
assert_eq! (::std::mem::align_of::<rte_ring_cons>() , 4usize , concat ! (
"Alignment of " , stringify ! ( rte_ring_cons ) ));
assert_eq! (unsafe {
& ( * ( 0 as * const rte_ring_cons ) ) . sc_dequeue as * const
_ as usize } , 0usize , concat ! (
"Alignment of field: " , stringify ! ( rte_ring_cons ) , "::"
, stringify ! ( sc_dequeue ) ));
}
impl Clone for rte_ring_cons {
fn clone(&self) -> Self { *self }
}
#[test]
fn bindgen_test_layout_rte_ring() {
assert_eq!(::std::mem::size_of::<rte_ring>() , 16usize , concat ! (
"Size of: " , stringify ! ( rte_ring ) ));
assert_eq! (::std::mem::align_of::<rte_ring>() , 8usize , concat ! (
"Alignment of " , stringify ! ( rte_ring ) ));
}
impl Clone for rte_ring {
fn clone(&self) -> Self { *self }
}
impl Default for rte_ring {
fn default() -> Self { unsafe { ::std::mem::zeroed() } }
}
#[repr(C)]
#[derive(Debug, Default, Copy)]
pub struct rte_memzone {
pub _address: u8,
}
impl Clone for rte_memzone {
fn clone(&self) -> Self { *self }
}
13 changes: 13 additions & 0 deletions tests/headers/issue-643-inner-struct.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
struct rte_ring {
struct rte_memzone *memzone;

struct prod {
unsigned watermark;
} prod;

struct cons {
unsigned sc_dequeue;
} cons;

void *ring[];
};