summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorEmilio Cobos Álvarez <emilio@crisal.io>2018-10-11 17:12:16 +0200
committerEmilio Cobos Álvarez <emilio@crisal.io>2018-10-11 17:16:41 +0200
commite0a052a3b181edd83894e0ade15de47e4b1e9b85 (patch)
treeedfda64c339a560a788f1b0113e2805cc9438185
parent988a9537800a23c045e045f19e02a1674d6a14ef (diff)
ir: Ensure everything agrees in which kind of variation an enum generates.
-rw-r--r--src/codegen/mod.rs16
-rw-r--r--src/ir/enum_ty.rs35
-rw-r--r--src/ir/item.rs4
-rw-r--r--tests/expectations/tests/default-enum-style-constified-module.rs18
-rw-r--r--tests/headers/default-enum-style-constified-module.h4
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);