@@ -398,6 +398,22 @@ pub struct BindgenContext {
398
398
/// bitfield allocation units computed. Drained in `compute_bitfield_units`.
399
399
need_bitfield_allocation : Vec < ItemId > ,
400
400
401
+ /// The set of enums that are defined by a pair of `enum` and `typedef`,
402
+ /// which is legal in C (but not C++).
403
+ ///
404
+ /// ```c++
405
+ /// // in either order
406
+ /// enum Enum { Variants... };
407
+ /// typedef int16_t Enum;
408
+ /// ```
409
+ ///
410
+ /// The stored `ItemId` is that of the `TypeKind::Enum`, not of the
411
+ /// `TypeKind::Alias`.
412
+ ///
413
+ /// This is populated when we enter codegen by `compute_enum_typedef_combos`
414
+ /// and is always `None` before that and `Some` after.
415
+ enum_typedef_combos : Option < HashSet < ItemId > > ,
416
+
401
417
/// The set of (`ItemId`s of) types that can't derive debug.
402
418
///
403
419
/// This is populated when we enter codegen by `compute_cannot_derive_debug`
@@ -565,6 +581,7 @@ If you encounter an error missing from this list, please file an issue or a PR!"
565
581
codegen_items : None ,
566
582
used_template_parameters : None ,
567
583
need_bitfield_allocation : Default :: default ( ) ,
584
+ enum_typedef_combos : None ,
568
585
cannot_derive_debug : None ,
569
586
cannot_derive_default : None ,
570
587
cannot_derive_copy : None ,
@@ -1157,6 +1174,7 @@ If you encounter an error missing from this list, please file an issue or a PR!"
1157
1174
self . compute_sizedness ( ) ;
1158
1175
self . compute_has_destructor ( ) ;
1159
1176
self . find_used_template_parameters ( ) ;
1177
+ self . compute_enum_typedef_combos ( ) ;
1160
1178
self . compute_cannot_derive_debug ( ) ;
1161
1179
self . compute_cannot_derive_default ( ) ;
1162
1180
self . compute_cannot_derive_copy ( ) ;
@@ -2476,6 +2494,70 @@ If you encounter an error missing from this list, please file an issue or a PR!"
2476
2494
self . generated_bindgen_complex . get ( )
2477
2495
}
2478
2496
2497
+ /// Compute which `enum`s have an associated `typedef` definition.
2498
+ fn compute_enum_typedef_combos ( & mut self ) {
2499
+ let _t = self . timer ( "compute_enum_typedef_combos" ) ;
2500
+ assert ! ( self . enum_typedef_combos. is_none( ) ) ;
2501
+
2502
+ let mut enum_typedef_combos = HashSet :: default ( ) ;
2503
+ for item in & self . items {
2504
+ if let Some ( ItemKind :: Module ( module) ) =
2505
+ item. as_ref ( ) . map ( Item :: kind)
2506
+ {
2507
+ // Find typedefs in this module, and build set of their names.
2508
+ let mut names_of_typedefs = HashSet :: default ( ) ;
2509
+ for child_id in module. children ( ) {
2510
+ if let Some ( ItemKind :: Type ( ty) ) =
2511
+ self . items [ child_id. 0 ] . as_ref ( ) . map ( Item :: kind)
2512
+ {
2513
+ if let ( Some ( name) , TypeKind :: Alias ( type_id) ) =
2514
+ ( ty. name ( ) , ty. kind ( ) )
2515
+ {
2516
+ // We disregard aliases that refer to the enum
2517
+ // itself, such as in `typedef enum { ... } Enum;`.
2518
+ if type_id
2519
+ . into_resolver ( )
2520
+ . through_type_refs ( )
2521
+ . through_type_aliases ( )
2522
+ . resolve ( self )
2523
+ . expect_type ( )
2524
+ . is_int ( )
2525
+ {
2526
+ names_of_typedefs. insert ( name) ;
2527
+ }
2528
+ }
2529
+ }
2530
+ }
2531
+
2532
+ // Find enums in this module, and record the id of each one that
2533
+ // has a typedef.
2534
+ for child_id in module. children ( ) {
2535
+ if let Some ( ItemKind :: Type ( ty) ) =
2536
+ self . items [ child_id. 0 ] . as_ref ( ) . map ( Item :: kind)
2537
+ {
2538
+ if let ( Some ( name) , true ) = ( ty. name ( ) , ty. is_enum ( ) ) {
2539
+ if names_of_typedefs. contains ( name) {
2540
+ enum_typedef_combos. insert ( * child_id) ;
2541
+ }
2542
+ }
2543
+ }
2544
+ }
2545
+ }
2546
+ }
2547
+
2548
+ self . enum_typedef_combos = Some ( enum_typedef_combos) ;
2549
+ }
2550
+
2551
+ /// Look up whether `id` refers to an `enum` whose underlying type is
2552
+ /// defined by a `typedef`.
2553
+ pub fn is_enum_typedef_combo ( & self , id : ItemId ) -> bool {
2554
+ assert ! (
2555
+ self . in_codegen_phase( ) ,
2556
+ "We only compute enum_typedef_combos when we enter codegen" ,
2557
+ ) ;
2558
+ self . enum_typedef_combos . as_ref ( ) . unwrap ( ) . contains ( & id)
2559
+ }
2560
+
2479
2561
/// Compute whether we can derive debug.
2480
2562
fn compute_cannot_derive_debug ( & mut self ) {
2481
2563
let _t = self . timer ( "compute_cannot_derive_debug" ) ;
0 commit comments