diff options
author | Emilio Cobos Álvarez <emilio@crisal.io> | 2018-10-11 17:12:16 +0200 |
---|---|---|
committer | Emilio Cobos Álvarez <emilio@crisal.io> | 2018-10-11 17:16:41 +0200 |
commit | e0a052a3b181edd83894e0ade15de47e4b1e9b85 (patch) | |
tree | edfda64c339a560a788f1b0113e2805cc9438185 | |
parent | 988a9537800a23c045e045f19e02a1674d6a14ef (diff) |
ir: Ensure everything agrees in which kind of variation an enum generates.
-rw-r--r-- | src/codegen/mod.rs | 16 | ||||
-rw-r--r-- | src/ir/enum_ty.rs | 35 | ||||
-rw-r--r-- | src/ir/item.rs | 4 | ||||
-rw-r--r-- | tests/expectations/tests/default-enum-style-constified-module.rs | 18 | ||||
-rw-r--r-- | tests/headers/default-enum-style-constified-module.h | 4 |
5 files changed, 53 insertions, 24 deletions
diff --git a/src/codegen/mod.rs b/src/codegen/mod.rs index dc8271f9..f29a3bc0 100644 --- a/src/codegen/mod.rs +++ b/src/codegen/mod.rs @@ -2566,22 +2566,10 @@ impl CodeGenerator for Enum { } }; - // ModuleConsts has higher precedence before Rust in order to avoid problems with - // overlapping match patterns - let variation = if self.is_constified_enum_module(ctx, item) { - EnumVariation::ModuleConsts - } else if self.is_bitfield(ctx, item) { - EnumVariation::Bitfield - } else if self.is_rustified_enum(ctx, item) { - EnumVariation::Rust - } else if self.is_constified_enum(ctx, item) { - EnumVariation::Consts - } else { - ctx.options().default_enum_style - }; - let mut attrs = vec![]; + let variation = self.computed_enum_variation(ctx, item); + // TODO(emilio): Delegate this to the builders? if variation.is_rust() { attrs.push(attributes::repr(repr_name)); diff --git a/src/ir/enum_ty.rs b/src/ir/enum_ty.rs index ee705f16..6d1e7214 100644 --- a/src/ir/enum_ty.rs +++ b/src/ir/enum_ty.rs @@ -2,6 +2,7 @@ use super::context::{BindgenContext, TypeId}; use super::item::Item; +use super::super::codegen::EnumVariation; use super::ty::TypeKind; use clang; use ir::annotations::Annotations; @@ -150,25 +151,43 @@ impl Enum { path_matches || (enum_is_anon && a_variant_matches) } - /// Whether the enum should be a bitfield - pub fn is_bitfield(&self, ctx: &BindgenContext, item: &Item) -> bool { + /// Whether the enum was explicitly specified to be a bitfield. + fn is_bitfield(&self, ctx: &BindgenContext, item: &Item) -> bool { self.is_matching_enum(ctx, &ctx.options().bitfield_enums, item) } - /// Whether the enum should be an constified enum module - pub fn is_constified_enum_module(&self, ctx: &BindgenContext, item: &Item) -> bool { + /// Whether the enum was explicitly specified to be an constified enum + /// module. + fn is_constified_enum_module(&self, ctx: &BindgenContext, item: &Item) -> bool { self.is_matching_enum(ctx, &ctx.options().constified_enum_modules, item) } - /// Whether the enum should be an set of constants - pub fn is_constified_enum(&self, ctx: &BindgenContext, item: &Item) -> bool { + /// Whether the enum was explicitly specified to be an set of constants. + fn is_constified_enum(&self, ctx: &BindgenContext, item: &Item) -> bool { self.is_matching_enum(ctx, &ctx.options().constified_enums, item) } - /// Whether the enum should be a Rust enum - pub fn is_rustified_enum(&self, ctx: &BindgenContext, item: &Item) -> bool { + /// Whether the enum was explicitly specified to be a Rust enum. + fn is_rustified_enum(&self, ctx: &BindgenContext, item: &Item) -> bool { self.is_matching_enum(ctx, &ctx.options().rustified_enums, item) } + + /// Returns the final representation of the enum. + pub fn computed_enum_variation(&self, ctx: &BindgenContext, item: &Item) -> EnumVariation { + // ModuleConsts has higher precedence before Rust in order to avoid + // problems with overlapping match patterns. + if self.is_constified_enum_module(ctx, item) { + EnumVariation::ModuleConsts + } else if self.is_bitfield(ctx, item) { + EnumVariation::Bitfield + } else if self.is_rustified_enum(ctx, item) { + EnumVariation::Rust + } else if self.is_constified_enum(ctx, item) { + EnumVariation::Consts + } else { + ctx.options().default_enum_style + } + } } /// A single enum variant, to be contained only in an enum. diff --git a/src/ir/item.rs b/src/ir/item.rs index 27e3d2f8..92372031 100644 --- a/src/ir/item.rs +++ b/src/ir/item.rs @@ -13,7 +13,7 @@ use super::function::{Function, FunctionKind}; use super::item_kind::ItemKind; use super::layout::Opaque; use super::module::Module; -use super::super::codegen::CONSTIFIED_ENUM_MODULE_REPR_NAME; +use super::super::codegen::{CONSTIFIED_ENUM_MODULE_REPR_NAME, EnumVariation}; use super::template::{AsTemplateParam, TemplateParameters}; use super::traversal::{EdgeKind, Trace, Tracer}; use super::ty::{Type, TypeKind}; @@ -928,7 +928,7 @@ impl Item { match *type_.kind() { TypeKind::Enum(ref enum_) => { - enum_.is_constified_enum_module(ctx, self) + enum_.computed_enum_variation(ctx, self) == EnumVariation::ModuleConsts } TypeKind::Alias(inner_id) => { // TODO(emilio): Make this "hop through type aliases that aren't diff --git a/tests/expectations/tests/default-enum-style-constified-module.rs b/tests/expectations/tests/default-enum-style-constified-module.rs new file mode 100644 index 00000000..4b71efdd --- /dev/null +++ b/tests/expectations/tests/default-enum-style-constified-module.rs @@ -0,0 +1,18 @@ +/* automatically generated by rust-bindgen */ + +#![allow( + dead_code, + non_snake_case, + non_camel_case_types, + non_upper_case_globals +)] + +pub mod Foo { + pub type Type = u32; + pub const bar: Type = 0; + pub const baz: Type = 1; + pub const blap: Type = 2; +} +extern "C" { + pub fn func(x: Foo::Type); +} diff --git a/tests/headers/default-enum-style-constified-module.h b/tests/headers/default-enum-style-constified-module.h new file mode 100644 index 00000000..a5ba6531 --- /dev/null +++ b/tests/headers/default-enum-style-constified-module.h @@ -0,0 +1,4 @@ +// bindgen-flags: --default-enum-style moduleconsts + +typedef enum { bar, baz, blap } Foo; +void func(Foo x); |