diff --git a/bindgen-tests/tests/expectations/tests/enum-default-bitfield.rs b/bindgen-tests/tests/expectations/tests/enum-default-bitfield.rs
index dda688617c..bf21cc2340 100644
--- a/bindgen-tests/tests/expectations/tests/enum-default-bitfield.rs
+++ b/bindgen-tests/tests/expectations/tests/enum-default-bitfield.rs
@@ -158,3 +158,102 @@ impl ::std::ops::BitAndAssign for Debug {
///
#[derive(Debug, Copy, Clone, Hash, PartialEq, Eq)]
pub struct Debug(pub ::std::os::raw::c_uint);
+impl should_be_u8 {
+ pub const FirstU8: should_be_u8 = should_be_u8(0);
+ pub const SecondU8: should_be_u8 = should_be_u8(1);
+}
+impl ::std::ops::BitOr for should_be_u8 {
+ type Output = Self;
+ #[inline]
+ fn bitor(self, other: Self) -> Self {
+ should_be_u8(self.0 | other.0)
+ }
+}
+impl ::std::ops::BitOrAssign for should_be_u8 {
+ #[inline]
+ fn bitor_assign(&mut self, rhs: should_be_u8) {
+ self.0 |= rhs.0;
+ }
+}
+impl ::std::ops::BitAnd for should_be_u8 {
+ type Output = Self;
+ #[inline]
+ fn bitand(self, other: Self) -> Self {
+ should_be_u8(self.0 & other.0)
+ }
+}
+impl ::std::ops::BitAndAssign for should_be_u8 {
+ #[inline]
+ fn bitand_assign(&mut self, rhs: should_be_u8) {
+ self.0 &= rhs.0;
+ }
+}
+#[repr(transparent)]
+#[derive(Debug, Copy, Clone, Hash, PartialEq, Eq)]
+pub struct should_be_u8(pub u8);
+impl should_be_u16 {
+ pub const FirstU16: should_be_u16 = should_be_u16(0);
+ pub const SecondU16: should_be_u16 = should_be_u16(1);
+}
+impl ::std::ops::BitOr for should_be_u16 {
+ type Output = Self;
+ #[inline]
+ fn bitor(self, other: Self) -> Self {
+ should_be_u16(self.0 | other.0)
+ }
+}
+impl ::std::ops::BitOrAssign for should_be_u16 {
+ #[inline]
+ fn bitor_assign(&mut self, rhs: should_be_u16) {
+ self.0 |= rhs.0;
+ }
+}
+impl ::std::ops::BitAnd for should_be_u16 {
+ type Output = Self;
+ #[inline]
+ fn bitand(self, other: Self) -> Self {
+ should_be_u16(self.0 & other.0)
+ }
+}
+impl ::std::ops::BitAndAssign for should_be_u16 {
+ #[inline]
+ fn bitand_assign(&mut self, rhs: should_be_u16) {
+ self.0 &= rhs.0;
+ }
+}
+#[repr(transparent)]
+#[derive(Debug, Copy, Clone, Hash, PartialEq, Eq)]
+pub struct should_be_u16(pub u16);
+impl should_be_i32 {
+ pub const FirstI32: should_be_i32 = should_be_i32(0);
+ pub const SecondI32: should_be_i32 = should_be_i32(1);
+}
+impl ::std::ops::BitOr for should_be_i32 {
+ type Output = Self;
+ #[inline]
+ fn bitor(self, other: Self) -> Self {
+ should_be_i32(self.0 | other.0)
+ }
+}
+impl ::std::ops::BitOrAssign for should_be_i32 {
+ #[inline]
+ fn bitor_assign(&mut self, rhs: should_be_i32) {
+ self.0 |= rhs.0;
+ }
+}
+impl ::std::ops::BitAnd for should_be_i32 {
+ type Output = Self;
+ #[inline]
+ fn bitand(self, other: Self) -> Self {
+ should_be_i32(self.0 & other.0)
+ }
+}
+impl ::std::ops::BitAndAssign for should_be_i32 {
+ #[inline]
+ fn bitand_assign(&mut self, rhs: should_be_i32) {
+ self.0 &= rhs.0;
+ }
+}
+#[repr(transparent)]
+#[derive(Debug, Copy, Clone, Hash, PartialEq, Eq)]
+pub struct should_be_i32(pub i32);
diff --git a/bindgen-tests/tests/expectations/tests/enum-default-consts.rs b/bindgen-tests/tests/expectations/tests/enum-default-consts.rs
index 1432182310..b47703d964 100644
--- a/bindgen-tests/tests/expectations/tests/enum-default-consts.rs
+++ b/bindgen-tests/tests/expectations/tests/enum-default-consts.rs
@@ -40,3 +40,12 @@ pub const Debug_Debug1: Debug = 0;
pub const Debug_Debug2: Debug = 1;
///
pub type Debug = ::std::os::raw::c_uint;
+pub const should_be_u8_FirstU8: should_be_u8 = 0;
+pub const should_be_u8_SecondU8: should_be_u8 = 1;
+pub type should_be_u8 = u8;
+pub const should_be_u16_FirstU16: should_be_u16 = 0;
+pub const should_be_u16_SecondU16: should_be_u16 = 1;
+pub type should_be_u16 = u16;
+pub const should_be_i32_FirstI32: should_be_i32 = 0;
+pub const should_be_i32_SecondI32: should_be_i32 = 1;
+pub type should_be_i32 = i32;
diff --git a/bindgen-tests/tests/expectations/tests/enum-default-module.rs b/bindgen-tests/tests/expectations/tests/enum-default-module.rs
index 23fbd22c6e..82c2c72eb3 100644
--- a/bindgen-tests/tests/expectations/tests/enum-default-module.rs
+++ b/bindgen-tests/tests/expectations/tests/enum-default-module.rs
@@ -56,3 +56,24 @@ pub mod Debug {
pub const Debug1: Type = 0;
pub const Debug2: Type = 1;
}
+pub mod should_be_u8 {
+ #[allow(unused_imports)]
+ use super::*;
+ pub type Type = u8;
+ pub const FirstU8: Type = 0;
+ pub const SecondU8: Type = 1;
+}
+pub mod should_be_u16 {
+ #[allow(unused_imports)]
+ use super::*;
+ pub type Type = u16;
+ pub const FirstU16: Type = 0;
+ pub const SecondU16: Type = 1;
+}
+pub mod should_be_i32 {
+ #[allow(unused_imports)]
+ use super::*;
+ pub type Type = i32;
+ pub const FirstI32: Type = 0;
+ pub const SecondI32: Type = 1;
+}
diff --git a/bindgen-tests/tests/expectations/tests/enum-default-rust.rs b/bindgen-tests/tests/expectations/tests/enum-default-rust.rs
index 59901a78ac..a9d62b7400 100644
--- a/bindgen-tests/tests/expectations/tests/enum-default-rust.rs
+++ b/bindgen-tests/tests/expectations/tests/enum-default-rust.rs
@@ -54,3 +54,21 @@ pub enum Debug {
Debug1 = 0,
Debug2 = 1,
}
+#[repr(u8)]
+#[derive(Debug, Copy, Clone, Hash, PartialEq, Eq)]
+pub enum should_be_u8 {
+ FirstU8 = 0,
+ SecondU8 = 1,
+}
+#[repr(u16)]
+#[derive(Debug, Copy, Clone, Hash, PartialEq, Eq)]
+pub enum should_be_u16 {
+ FirstU16 = 0,
+ SecondU16 = 1,
+}
+#[repr(i32)]
+#[derive(Debug, Copy, Clone, Hash, PartialEq, Eq)]
+pub enum should_be_i32 {
+ FirstI32 = 0,
+ SecondI32 = 1,
+}
diff --git a/bindgen-tests/tests/expectations/tests/enum-no-debug-rust.rs b/bindgen-tests/tests/expectations/tests/enum-no-debug-rust.rs
index 643577e1e3..202a04e74e 100644
--- a/bindgen-tests/tests/expectations/tests/enum-no-debug-rust.rs
+++ b/bindgen-tests/tests/expectations/tests/enum-no-debug-rust.rs
@@ -54,3 +54,21 @@ pub enum Debug {
Debug1 = 0,
Debug2 = 1,
}
+#[repr(u8)]
+#[derive(Copy, Clone, Hash, PartialEq, Eq)]
+pub enum should_be_u8 {
+ FirstU8 = 0,
+ SecondU8 = 1,
+}
+#[repr(u16)]
+#[derive(Copy, Clone, Hash, PartialEq, Eq)]
+pub enum should_be_u16 {
+ FirstU16 = 0,
+ SecondU16 = 1,
+}
+#[repr(i32)]
+#[derive(Copy, Clone, Hash, PartialEq, Eq)]
+pub enum should_be_i32 {
+ FirstI32 = 0,
+ SecondI32 = 1,
+}
diff --git a/bindgen-tests/tests/expectations/tests/enum.rs b/bindgen-tests/tests/expectations/tests/enum.rs
index 820182125a..b0e549f05c 100644
--- a/bindgen-tests/tests/expectations/tests/enum.rs
+++ b/bindgen-tests/tests/expectations/tests/enum.rs
@@ -36,3 +36,12 @@ pub const Debug_Debug1: Debug = 0;
pub const Debug_Debug2: Debug = 1;
///
pub type Debug = ::std::os::raw::c_uint;
+pub const should_be_u8_FirstU8: should_be_u8 = 0;
+pub const should_be_u8_SecondU8: should_be_u8 = 1;
+pub type should_be_u8 = ::std::os::raw::c_uint;
+pub const should_be_u16_FirstU16: should_be_u16 = 0;
+pub const should_be_u16_SecondU16: should_be_u16 = 1;
+pub type should_be_u16 = ::std::os::raw::c_uint;
+pub const should_be_i32_FirstI32: should_be_i32 = 0;
+pub const should_be_i32_SecondI32: should_be_i32 = 1;
+pub type should_be_i32 = ::std::os::raw::c_uint;
diff --git a/bindgen-tests/tests/headers/enum-default-bitfield.h b/bindgen-tests/tests/headers/enum-default-bitfield.h
index 5f3cb95468..8250563fa8 100644
--- a/bindgen-tests/tests/headers/enum-default-bitfield.h
+++ b/bindgen-tests/tests/headers/enum-default-bitfield.h
@@ -1,3 +1,4 @@
// bindgen-flags: --default-enum-style=bitfield --constified-enum-module=Neg
+// bindgen-parse-callbacks: enum-type-changer
#include "enum.h"
diff --git a/bindgen-tests/tests/headers/enum-default-consts.h b/bindgen-tests/tests/headers/enum-default-consts.h
index 233d2718a4..5228ca7aa5 100644
--- a/bindgen-tests/tests/headers/enum-default-consts.h
+++ b/bindgen-tests/tests/headers/enum-default-consts.h
@@ -1,3 +1,4 @@
// bindgen-flags: --default-enum-style=consts --constified-enum-module=Neg
+// bindgen-parse-callbacks: enum-type-changer
#include "enum.h"
diff --git a/bindgen-tests/tests/headers/enum-default-module.h b/bindgen-tests/tests/headers/enum-default-module.h
index 8c2ec1bca4..eae2d69a54 100644
--- a/bindgen-tests/tests/headers/enum-default-module.h
+++ b/bindgen-tests/tests/headers/enum-default-module.h
@@ -1,3 +1,4 @@
// bindgen-flags: --default-enum-style=moduleconsts --constified-enum-module=Neg
+// bindgen-parse-callbacks: enum-type-changer
#include "enum.h"
diff --git a/bindgen-tests/tests/headers/enum-default-rust.h b/bindgen-tests/tests/headers/enum-default-rust.h
index 7fd2999fe0..4e95166d18 100644
--- a/bindgen-tests/tests/headers/enum-default-rust.h
+++ b/bindgen-tests/tests/headers/enum-default-rust.h
@@ -1,3 +1,4 @@
// bindgen-flags: --default-enum-style=rust --constified-enum-module=Neg
+// bindgen-parse-callbacks: enum-type-changer
#include "enum.h"
diff --git a/bindgen-tests/tests/headers/enum-no-debug-rust.h b/bindgen-tests/tests/headers/enum-no-debug-rust.h
index 7cb7398029..c5e3e0d48b 100644
--- a/bindgen-tests/tests/headers/enum-no-debug-rust.h
+++ b/bindgen-tests/tests/headers/enum-no-debug-rust.h
@@ -1,3 +1,4 @@
// bindgen-flags: --no-derive-debug --default-enum-style=rust --constified-enum-module=Neg
+// bindgen-parse-callbacks: enum-type-changer
#include "enum.h"
diff --git a/bindgen-tests/tests/headers/enum.h b/bindgen-tests/tests/headers/enum.h
index 0147433ee9..2acd6adbdf 100644
--- a/bindgen-tests/tests/headers/enum.h
+++ b/bindgen-tests/tests/headers/enum.h
@@ -28,4 +28,19 @@ enum NoDebug {
enum Debug {
Debug1,
Debug2,
-};
\ No newline at end of file
+};
+
+enum should_be_u8 {
+ FirstU8,
+ SecondU8,
+};
+
+enum should_be_u16 {
+ FirstU16,
+ SecondU16,
+};
+
+enum should_be_i32 {
+ FirstI32,
+ SecondI32,
+};
diff --git a/bindgen-tests/tests/parse_callbacks/mod.rs b/bindgen-tests/tests/parse_callbacks/mod.rs
index 7e9f011812..ca22b7cb9a 100644
--- a/bindgen-tests/tests/parse_callbacks/mod.rs
+++ b/bindgen-tests/tests/parse_callbacks/mod.rs
@@ -94,6 +94,20 @@ impl ParseCallbacks for StructFieldRename {
}
}
+#[derive(Debug)]
+struct EnumTypeChanger;
+
+impl ParseCallbacks for EnumTypeChanger {
+ fn enum_type_override(&self, enum_name: &str) -> Option {
+ match enum_name {
+ "should_be_u8" => Some(IntKind::U8),
+ "should_be_u16" => Some(IntKind::U16),
+ "should_be_i32" => Some(IntKind::I32),
+ _ => None,
+ }
+ }
+}
+
#[derive(Debug)]
struct BlocklistedTypeImplementsTrait;
@@ -191,6 +205,7 @@ pub fn lookup(cb: &str) -> Box {
"wrap-as-variadic-fn" => Box::new(WrapAsVariadicFn),
"type-visibility" => Box::new(TypeVisibility),
"operator-rename" => Box::new(OperatorRename),
+ "enum-type-changer" => Box::new(EnumTypeChanger),
call_back => {
if let Some(prefix) =
call_back.strip_prefix("remove-function-prefix-")
diff --git a/bindgen/callbacks.rs b/bindgen/callbacks.rs
index 4df316b9d1..3df6a8c63b 100644
--- a/bindgen/callbacks.rs
+++ b/bindgen/callbacks.rs
@@ -73,6 +73,12 @@ pub trait ParseCallbacks: fmt::Debug {
/// the expansion of the macro as a sequence of tokens.
fn func_macro(&self, _name: &str, _value: &[&[u8]]) {}
+ /// The integer kind an enum should have, given the name of the enum type,
+ /// or `None` if you want the default to be chosen.
+ fn enum_type_override(&self, _enum_name: &str) -> Option {
+ None
+ }
+
/// This function should return whether, given an enum variant
/// name, and value, this enum variant will forcibly be a constant.
fn enum_variant_behavior(
diff --git a/bindgen/codegen/mod.rs b/bindgen/codegen/mod.rs
index 6034b0e6ba..87faaf1042 100644
--- a/bindgen/codegen/mod.rs
+++ b/bindgen/codegen/mod.rs
@@ -3759,7 +3759,7 @@ impl CodeGenerator for Enum {
let variation = self.computed_enum_variation(ctx, item);
let repr_translated;
- let repr = match self.repr().map(|repr| ctx.resolve_type(repr)) {
+ let mut repr = match self.repr().map(|repr| ctx.resolve_type(repr)) {
Some(repr)
if !ctx.options().translate_enum_integer_types &&
!variation.is_rust() =>
@@ -3906,6 +3906,18 @@ impl CodeGenerator for Enum {
});
}
+ let repr_from_callback;
+ if !ctx.options().parse_callbacks.is_empty() {
+ if let Some(callback_type) = ctx
+ .options()
+ .last_callback(|cb| cb.enum_type_override(&name))
+ {
+ repr_from_callback =
+ Type::new(None, None, TypeKind::Int(callback_type), false);
+ repr = &repr_from_callback;
+ }
+ }
+
let repr = repr.to_rust_ty_or_opaque(ctx, item);
let has_typedef = ctx.is_enum_typedef_combo(item.id());