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