@@ -2524,7 +2524,7 @@ impl<'a> EnumBuilder<'a> {
2524
2524
/// the representation, and which variation it should be generated as.
2525
2525
fn new (
2526
2526
name : & ' a str ,
2527
- attrs : Vec < proc_macro2:: TokenStream > ,
2527
+ mut attrs : Vec < proc_macro2:: TokenStream > ,
2528
2528
repr : proc_macro2:: TokenStream ,
2529
2529
enum_variation : EnumVariation ,
2530
2530
enum_codegen_depth : usize ,
@@ -2543,6 +2543,8 @@ impl<'a> EnumBuilder<'a> {
2543
2543
} ,
2544
2544
2545
2545
EnumVariation :: Rust { .. } => {
2546
+ // `repr` is guaranteed to be Rustified in Enum::codegen
2547
+ attrs. push ( quote ! { #[ repr( #repr ) ] } ) ;
2546
2548
let tokens = quote ! ( ) ;
2547
2549
EnumBuilder :: Rust {
2548
2550
codegen_depth : enum_codegen_depth + 1 ,
@@ -2820,51 +2822,64 @@ impl CodeGenerator for Enum {
2820
2822
let ident = ctx. rust_ident ( & name) ;
2821
2823
let enum_ty = item. expect_type ( ) ;
2822
2824
let layout = enum_ty. layout ( ctx) ;
2825
+ let variation = self . computed_enum_variation ( ctx, item) ;
2823
2826
2824
- let repr = self . repr ( ) . map ( |repr| ctx. resolve_type ( repr) ) ;
2825
- let repr = match repr {
2826
- Some ( repr) => match * repr. canonical_type ( ctx) . kind ( ) {
2827
- TypeKind :: Int ( int_kind) => int_kind,
2828
- _ => panic ! ( "Unexpected type as enum repr" ) ,
2829
- } ,
2830
- None => {
2831
- warn ! (
2832
- "Guessing type of enum! Forward declarations of enums \
2833
- shouldn't be legal!"
2834
- ) ;
2835
- IntKind :: Int
2836
- }
2837
- } ;
2827
+ let repr_translated;
2828
+ let repr = match self . repr ( ) . map ( |repr| ctx. resolve_type ( repr) ) {
2829
+ Some ( repr) if !ctx. options ( ) . translate_enum_integer_types && !variation. is_rust ( ) => repr,
2830
+ repr => {
2831
+ // An enum's integer type is translated to a native Rust
2832
+ // integer type in 3 cases:
2833
+ // * the enum is Rustified and we need a translated type for
2834
+ // the repr attribute
2835
+ // * the representation couldn't be determined from the C source
2836
+ // * it was explicitly requested as a bindgen option
2837
+
2838
+ let kind = match repr {
2839
+ Some ( repr) => match * repr. canonical_type ( ctx) . kind ( ) {
2840
+ TypeKind :: Int ( int_kind) => int_kind,
2841
+ _ => panic ! ( "Unexpected type as enum repr" ) ,
2842
+ } ,
2843
+ None => {
2844
+ warn ! (
2845
+ "Guessing type of enum! Forward declarations of enums \
2846
+ shouldn't be legal!"
2847
+ ) ;
2848
+ IntKind :: Int
2849
+ }
2850
+ } ;
2851
+
2852
+ let signed = kind. is_signed ( ) ;
2853
+ let size = layout
2854
+ . map ( |l| l. size )
2855
+ . or_else ( || kind. known_size ( ) )
2856
+ . unwrap_or ( 0 ) ;
2857
+
2858
+ let translated = match ( signed, size) {
2859
+ ( true , 1 ) => IntKind :: I8 ,
2860
+ ( false , 1 ) => IntKind :: U8 ,
2861
+ ( true , 2 ) => IntKind :: I16 ,
2862
+ ( false , 2 ) => IntKind :: U16 ,
2863
+ ( true , 4 ) => IntKind :: I32 ,
2864
+ ( false , 4 ) => IntKind :: U32 ,
2865
+ ( true , 8 ) => IntKind :: I64 ,
2866
+ ( false , 8 ) => IntKind :: U64 ,
2867
+ _ => {
2868
+ warn ! ( "invalid enum decl: signed: {}, size: {}" , signed, size) ;
2869
+ IntKind :: I32
2870
+ }
2871
+ } ;
2838
2872
2839
- let signed = repr. is_signed ( ) ;
2840
- let size = layout
2841
- . map ( |l| l. size )
2842
- . or_else ( || repr. known_size ( ) )
2843
- . unwrap_or ( 0 ) ;
2844
-
2845
- let repr_name = match ( signed, size) {
2846
- ( true , 1 ) => "i8" ,
2847
- ( false , 1 ) => "u8" ,
2848
- ( true , 2 ) => "i16" ,
2849
- ( false , 2 ) => "u16" ,
2850
- ( true , 4 ) => "i32" ,
2851
- ( false , 4 ) => "u32" ,
2852
- ( true , 8 ) => "i64" ,
2853
- ( false , 8 ) => "u64" ,
2854
- _ => {
2855
- warn ! ( "invalid enum decl: signed: {}, size: {}" , signed, size) ;
2856
- "i32"
2873
+ repr_translated = Type :: new ( None , None , TypeKind :: Int ( translated) , false ) ;
2874
+ & repr_translated
2857
2875
}
2858
2876
} ;
2859
2877
2860
2878
let mut attrs = vec ! [ ] ;
2861
2879
2862
- let variation = self . computed_enum_variation ( ctx, item) ;
2863
-
2864
2880
// TODO(emilio): Delegate this to the builders?
2865
2881
match variation {
2866
2882
EnumVariation :: Rust { non_exhaustive } => {
2867
- attrs. push ( attributes:: repr ( repr_name) ) ;
2868
2883
if non_exhaustive &&
2869
2884
ctx. options ( ) . rust_features ( ) . non_exhaustive
2870
2885
{
@@ -2934,13 +2949,7 @@ impl CodeGenerator for Enum {
2934
2949
} ) ;
2935
2950
}
2936
2951
2937
- let repr = match self . repr ( ) {
2938
- Some ( ty) => ty. to_rust_ty_or_opaque ( ctx, & ( ) ) ,
2939
- None => {
2940
- let repr_name = ctx. rust_ident_raw ( repr_name) ;
2941
- quote ! { #repr_name }
2942
- }
2943
- } ;
2952
+ let repr = repr. to_rust_ty_or_opaque ( ctx, item) ;
2944
2953
2945
2954
let mut builder = EnumBuilder :: new (
2946
2955
& name,
0 commit comments