Skip to content

Commit

Permalink
Simplify is_constified_enum_module
Browse files Browse the repository at this point in the history
Used suggested code from @emilio and also added a test for an alias to
an anonymous enum.
  • Loading branch information
tmfink committed Jun 21, 2017
1 parent 465e242 commit 814d28e
Show file tree
Hide file tree
Showing 3 changed files with 70 additions and 37 deletions.
58 changes: 22 additions & 36 deletions src/ir/item.rs
Original file line number Diff line number Diff line change
Expand Up @@ -829,46 +829,32 @@ impl Item {

/// Returns whether the item is a constified module enum
fn is_constified_enum_module(&self, ctx: &BindgenContext) -> bool {
if let ItemKind::Type(ref type_) = self.kind {
// Do not count an "alias of an alias" as a constified module enum;
// otherwise, we will get:
// pub mod foo {
// pub type Type = ::std::os::raw::c_uint;
// ...
// }
// pub use foo::Type as foo_alias1;
// pub use foo_alias1::Type as foo_alias2;
// pub use foo_alias2::Type as foo_alias3;
// ...
//
// (We do not want the '::Type' appended to the alias types; only the base type)
if let TypeKind::Alias(inner_id) = *type_.kind() {
let inner_item = ctx.resolve_item(inner_id);
if let ItemKind::Type(ref inner_type) = *inner_item.kind() {
match *inner_type.kind() {
TypeKind::Alias(..) => { return false; }
TypeKind::ResolvedTypeRef(resolved_id) => {
// We need to handle:
// Alias -> ResolvedTypeRef -> Alias
let resolved_item = ctx.resolve_item(resolved_id);
if let ItemKind::Type(ref resolved_type) = *resolved_item.kind() {
if let TypeKind::Alias(..) = *resolved_type.kind() {
return false;
}
}
}
_ => (),
}
}
// Do not jump through aliases, except for aliases that point to a type
// with the same name, since we dont generate coe for them.
let item = self.id.into_resolver().through_type_refs().resolve(ctx);
let type_ = match *item.kind() {
ItemKind::Type(ref type_) => type_,
_ => return false,
};

match *type_.kind() {
TypeKind::Enum(ref enum_) => {
enum_.is_constified_enum_module(ctx, self)
}
if let Some(ref type_) = type_.safe_canonical_type(ctx) {
if let TypeKind::Enum(ref enum_) = *type_.kind() {
return enum_.is_constified_enum_module(ctx, self);
TypeKind::Alias(inner_id) => {
// TODO(emilio): Make this "hop through type aliases that aren't
// really generated" an option in `ItemResolver`?
let inner_item = ctx.resolve_item(inner_id);
let name = item.canonical_name(ctx);

if inner_item.canonical_name(ctx) == name {
inner_item.is_constified_enum_module(ctx)
} else {
false
}
}
_ => false,
}

return false;
}
}

Expand Down
35 changes: 34 additions & 1 deletion tests/expectations/tests/constify-module-enums-types.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,12 @@ pub mod foo {
pub const ALSO_THIS: Type = 42;
pub const AND_ALSO_THIS: Type = 42;
}
pub mod anon_enum {
pub type Type = ::std::os::raw::c_uint;
pub const Variant1: Type = 0;
pub const Variant2: Type = 1;
pub const Variant3: Type = 2;
}
pub mod ns1_foo {
pub type Type = ::std::os::raw::c_uint;
pub const THIS: Type = 0;
Expand All @@ -27,6 +33,9 @@ pub mod ns2_Foo {
pub use self::foo::Type as foo_alias1;
pub use self::foo_alias1 as foo_alias2;
pub use self::foo_alias2 as foo_alias3;
pub use self::anon_enum::Type as anon_enum_alias1;
pub use self::anon_enum_alias1 as anon_enum_alias2;
pub use self::anon_enum_alias2 as anon_enum_alias3;
#[repr(C)]
#[derive(Debug, Copy)]
pub struct bar {
Expand All @@ -36,10 +45,14 @@ pub struct bar {
pub member4: foo_alias3,
pub member5: ns1_foo::Type,
pub member6: *mut ns2_Foo::Type,
pub member7: anon_enum::Type,
pub member8: anon_enum_alias1,
pub member9: anon_enum_alias2,
pub member10: anon_enum_alias3,
}
#[test]
fn bindgen_test_layout_bar() {
assert_eq!(::std::mem::size_of::<bar>() , 32usize , concat ! (
assert_eq!(::std::mem::size_of::<bar>() , 48usize , concat ! (
"Size of: " , stringify ! ( bar ) ));
assert_eq! (::std::mem::align_of::<bar>() , 8usize , concat ! (
"Alignment of " , stringify ! ( bar ) ));
Expand Down Expand Up @@ -73,6 +86,26 @@ fn bindgen_test_layout_bar() {
, 24usize , concat ! (
"Alignment of field: " , stringify ! ( bar ) , "::" ,
stringify ! ( member6 ) ));
assert_eq! (unsafe {
& ( * ( 0 as * const bar ) ) . member7 as * const _ as usize }
, 32usize , concat ! (
"Alignment of field: " , stringify ! ( bar ) , "::" ,
stringify ! ( member7 ) ));
assert_eq! (unsafe {
& ( * ( 0 as * const bar ) ) . member8 as * const _ as usize }
, 36usize , concat ! (
"Alignment of field: " , stringify ! ( bar ) , "::" ,
stringify ! ( member8 ) ));
assert_eq! (unsafe {
& ( * ( 0 as * const bar ) ) . member9 as * const _ as usize }
, 40usize , concat ! (
"Alignment of field: " , stringify ! ( bar ) , "::" ,
stringify ! ( member9 ) ));
assert_eq! (unsafe {
& ( * ( 0 as * const bar ) ) . member10 as * const _ as usize
} , 44usize , concat ! (
"Alignment of field: " , stringify ! ( bar ) , "::" ,
stringify ! ( member10 ) ));
}
impl Clone for bar {
fn clone(&self) -> Self { *self }
Expand Down
14 changes: 14 additions & 0 deletions tests/headers/constify-module-enums-types.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,12 @@ typedef enum foo {
AND_ALSO_THIS = 42,
} foo;


typedef enum {
Variant1, Variant2, Variant3,
} anon_enum;


namespace ns1 {
typedef enum {
THIS,
Expand All @@ -28,13 +34,21 @@ typedef foo foo_alias1;
typedef foo_alias1 foo_alias2;
typedef foo_alias2 foo_alias3;

typedef anon_enum anon_enum_alias1;
typedef anon_enum_alias1 anon_enum_alias2;
typedef anon_enum_alias2 anon_enum_alias3;

typedef struct bar {
foo member1;
foo_alias1 member2;
foo_alias2 member3;
foo_alias3 member4;
ns1::foo member5;
ns2::Foo *member6;
anon_enum member7;
anon_enum_alias1 member8;
anon_enum_alias2 member9;
anon_enum_alias3 member10;
} bar;

class Baz {
Expand Down

0 comments on commit 814d28e

Please sign in to comment.