@@ -17,6 +17,7 @@ use peeking_take_while::PeekableExt;
17
17
use std:: cmp;
18
18
use std:: io;
19
19
use std:: mem;
20
+ use std:: collections:: HashMap ;
20
21
21
22
/// The kind of compound type.
22
23
#[ derive( Debug , Copy , Clone , PartialEq ) ]
@@ -292,6 +293,16 @@ pub struct Bitfield {
292
293
293
294
/// The field data for this bitfield.
294
295
data : FieldData ,
296
+
297
+ /// Name of the generated Rust getter for this bitfield.
298
+ ///
299
+ /// Should be assigned before codegen.
300
+ getter_name : Option < String > ,
301
+
302
+ /// Name of the generated Rust setter for this bitfield.
303
+ ///
304
+ /// Should be assigned before codegen.
305
+ setter_name : Option < String > ,
295
306
}
296
307
297
308
impl Bitfield {
@@ -302,6 +313,8 @@ impl Bitfield {
302
313
Bitfield {
303
314
offset_into_unit : offset_into_unit,
304
315
data : raw. 0 ,
316
+ getter_name : None ,
317
+ setter_name : None ,
305
318
}
306
319
}
307
320
@@ -331,6 +344,30 @@ impl Bitfield {
331
344
pub fn width ( & self ) -> u32 {
332
345
self . data . bitfield ( ) . unwrap ( )
333
346
}
347
+
348
+ /// Name of the generated Rust getter for this bitfield.
349
+ ///
350
+ /// Panics if called before assigning bitfield accessor names or if
351
+ /// this bitfield have no name.
352
+ pub fn getter_name ( & self ) -> & str {
353
+ assert ! ( self . name( ) . is_some( ) , "`Bitfield::getter_name` called on anonymous field" ) ;
354
+ self . getter_name . as_ref ( ) . expect (
355
+ "`Bitfield::getter_name` should only be called after\
356
+ assigning bitfield accessor names",
357
+ )
358
+ }
359
+
360
+ /// Name of the generated Rust setter for this bitfield.
361
+ ///
362
+ /// Panics if called before assigning bitfield accessor names or if
363
+ /// this bitfield have no name.
364
+ pub fn setter_name ( & self ) -> & str {
365
+ assert ! ( self . name( ) . is_some( ) , "`Bitfield::setter_name` called on anonymous field" ) ;
366
+ self . setter_name . as_ref ( ) . expect (
367
+ "`Bitfield::setter_name` should only be called\
368
+ after assigning bitfield accessor names",
369
+ )
370
+ }
334
371
}
335
372
336
373
impl FieldMethods for Bitfield {
@@ -661,30 +698,79 @@ impl CompFields {
661
698
) ;
662
699
}
663
700
664
- fn deanonymize_fields ( & mut self ) {
701
+ fn deanonymize_fields ( & mut self , ctx : & BindgenContext , methods : & [ Method ] ) {
665
702
let fields = match * self {
666
- CompFields :: AfterComputingBitfieldUnits ( ref mut fields) => {
667
- fields
668
- }
703
+ CompFields :: AfterComputingBitfieldUnits ( ref mut fields) => fields,
669
704
CompFields :: BeforeComputingBitfieldUnits ( _) => {
670
705
panic ! ( "Not yet computed bitfield units." ) ;
671
706
}
672
707
} ;
673
708
709
+ fn has_method ( methods : & [ Method ] , ctx : & BindgenContext , name : & str ) -> bool {
710
+ methods. iter ( ) . any ( |method| {
711
+ let method_name = ctx. resolve_func ( method. signature ( ) ) . name ( ) ;
712
+ method_name == name || ctx. rust_mangle ( & method_name) == name
713
+ } )
714
+ }
715
+
716
+ struct AccessorNamesPair {
717
+ getter : String ,
718
+ setter : String ,
719
+ }
720
+
721
+ let mut accessor_names: HashMap < String , AccessorNamesPair > = fields
722
+ . iter ( )
723
+ . flat_map ( |field| match * field {
724
+ Field :: Bitfields ( ref bu) => & * bu. bitfields ,
725
+ Field :: DataMember ( _) => & [ ] ,
726
+ } )
727
+ . filter_map ( |bitfield| bitfield. name ( ) )
728
+ . map ( |bitfield_name| {
729
+ let bitfield_name = bitfield_name. to_string ( ) ;
730
+ let getter = {
731
+ let mut getter = ctx. rust_mangle ( & bitfield_name) . to_string ( ) ;
732
+ if has_method ( methods, ctx, & getter) {
733
+ getter. push_str ( "_bindgen_bitfield" ) ;
734
+ }
735
+ getter
736
+ } ;
737
+ let setter = {
738
+ let setter = format ! ( "set_{}" , bitfield_name) ;
739
+ let mut setter = ctx. rust_mangle ( & setter) . to_string ( ) ;
740
+ if has_method ( methods, ctx, & setter) {
741
+ setter. push_str ( "_bindgen_bitfield" ) ;
742
+ }
743
+ setter
744
+ } ;
745
+ ( bitfield_name, AccessorNamesPair { getter, setter } )
746
+ } )
747
+ . collect ( ) ;
748
+
674
749
let mut anon_field_counter = 0 ;
675
750
for field in fields. iter_mut ( ) {
676
- let field_data = match * field {
677
- Field :: DataMember ( ref mut fd) => fd,
678
- Field :: Bitfields ( _) => continue ,
679
- } ;
751
+ match * field {
752
+ Field :: DataMember ( FieldData { ref mut name, .. } ) => {
753
+ if let Some ( _) = * name {
754
+ continue ;
755
+ }
680
756
681
- if let Some ( _) = field_data. name {
682
- continue ;
683
- }
757
+ anon_field_counter += 1 ;
758
+ let generated_name = format ! ( "__bindgen_anon_{}" , anon_field_counter) ;
759
+ * name = Some ( generated_name) ;
760
+ }
761
+ Field :: Bitfields ( ref mut bu) => for bitfield in & mut bu. bitfields {
762
+ if bitfield. name ( ) . is_none ( ) {
763
+ continue ;
764
+ }
684
765
685
- anon_field_counter += 1 ;
686
- let name = format ! ( "__bindgen_anon_{}" , anon_field_counter) ;
687
- field_data. name = Some ( name) ;
766
+ if let Some ( AccessorNamesPair { getter, setter } ) =
767
+ accessor_names. remove ( bitfield. name ( ) . unwrap ( ) )
768
+ {
769
+ bitfield. getter_name = Some ( getter) ;
770
+ bitfield. setter_name = Some ( setter) ;
771
+ }
772
+ } ,
773
+ }
688
774
}
689
775
}
690
776
}
@@ -1397,8 +1483,8 @@ impl CompInfo {
1397
1483
}
1398
1484
1399
1485
/// Assign for each anonymous field a generated name.
1400
- pub fn deanonymize_fields ( & mut self ) {
1401
- self . fields . deanonymize_fields ( ) ;
1486
+ pub fn deanonymize_fields ( & mut self , ctx : & BindgenContext ) {
1487
+ self . fields . deanonymize_fields ( ctx , & self . methods ) ;
1402
1488
}
1403
1489
1404
1490
/// Returns whether the current union can be represented as a Rust `union`
@@ -1484,7 +1570,7 @@ impl IsOpaque for CompInfo {
1484
1570
false
1485
1571
} ,
1486
1572
Field :: Bitfields ( ref unit) => {
1487
- unit. bitfields ( ) . iter ( ) . any ( |bf| {
1573
+ unit. bitfields ( ) . iter ( ) . any ( |bf| {
1488
1574
let bitfield_layout = ctx. resolve_type ( bf. ty ( ) )
1489
1575
. layout ( ctx)
1490
1576
. expect ( "Bitfield without layout? Gah!" ) ;
0 commit comments