summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTravis Finkenauer <tmfinken@gmail.com>2017-06-20 22:05:34 -0700
committerTravis Finkenauer <tmfinken@gmail.com>2017-06-20 22:05:34 -0700
commit814d28e0f256a24865f633b5992ced6f035d6f4c (patch)
tree5969fecb13d112182d629a7461c9571d705fc1b9
parent465e242752109591f6d8986c31761dda97ab43c7 (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.rs58
-rw-r--r--tests/expectations/tests/constify-module-enums-types.rs35
-rw-r--r--tests/headers/constify-module-enums-types.hpp14
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 {