diff options
author | Travis Finkenauer <tmfinken@gmail.com> | 2017-06-20 22:05:34 -0700 |
---|---|---|
committer | Travis Finkenauer <tmfinken@gmail.com> | 2017-06-20 22:05:34 -0700 |
commit | 814d28e0f256a24865f633b5992ced6f035d6f4c (patch) | |
tree | 5969fecb13d112182d629a7461c9571d705fc1b9 | |
parent | 465e242752109591f6d8986c31761dda97ab43c7 (diff) |
Simplify is_constified_enum_module
Used suggested code from @emilio and also added a test for an alias to
an anonymous enum.
-rw-r--r-- | src/ir/item.rs | 58 | ||||
-rw-r--r-- | tests/expectations/tests/constify-module-enums-types.rs | 35 | ||||
-rw-r--r-- | tests/headers/constify-module-enums-types.hpp | 14 |
3 files changed, 70 insertions, 37 deletions
diff --git a/src/ir/item.rs b/src/ir/item.rs index 7d033210..de629e03 100644 --- a/src/ir/item.rs +++ b/src/ir/item.rs @@ -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; } } diff --git a/tests/expectations/tests/constify-module-enums-types.rs b/tests/expectations/tests/constify-module-enums-types.rs index db236d6f..4eb100c4 100644 --- a/tests/expectations/tests/constify-module-enums-types.rs +++ b/tests/expectations/tests/constify-module-enums-types.rs @@ -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; @@ -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 { @@ -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 ) )); @@ -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 } diff --git a/tests/headers/constify-module-enums-types.hpp b/tests/headers/constify-module-enums-types.hpp index 1618b269..2c652499 100644 --- a/tests/headers/constify-module-enums-types.hpp +++ b/tests/headers/constify-module-enums-types.hpp @@ -8,6 +8,12 @@ typedef enum foo { AND_ALSO_THIS = 42, } foo; + +typedef enum { + Variant1, Variant2, Variant3, +} anon_enum; + + namespace ns1 { typedef enum { THIS, @@ -28,6 +34,10 @@ 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; @@ -35,6 +45,10 @@ typedef struct bar { 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 { |