@@ -1020,6 +1020,108 @@ impl<'a> FieldCodegen<'a> for FieldData {
1020
1020
}
1021
1021
}
1022
1022
1023
+ impl BitfieldUnit {
1024
+ /// Get the constructor name for this bitfield unit.
1025
+ fn ctor_name ( & self , ctx : & BindgenContext ) -> ast:: Ident {
1026
+ let ctor_name = format ! ( "new_bitfield_{}" , self . nth( ) ) ;
1027
+ ctx. ext_cx ( ) . ident_of ( & ctor_name)
1028
+ }
1029
+
1030
+ /// Get the initial bitfield unit constructor that just returns 0. This will
1031
+ /// then be extended by each bitfield in the unit. See `extend_ctor_impl`
1032
+ /// below.
1033
+ fn initial_ctor_impl ( & self ,
1034
+ ctx : & BindgenContext ,
1035
+ unit_field_int_ty : & P < ast:: Ty > )
1036
+ -> P < ast:: Item > {
1037
+ let ctor_name = self . ctor_name ( ctx) ;
1038
+
1039
+ // If we're generating unstable Rust, add the const.
1040
+ let fn_prefix = if ctx. options ( ) . unstable_rust {
1041
+ quote_tokens ! ( ctx. ext_cx( ) , pub const fn )
1042
+ } else {
1043
+ quote_tokens ! ( ctx. ext_cx( ) , pub fn )
1044
+ } ;
1045
+
1046
+ quote_item ! (
1047
+ ctx. ext_cx( ) ,
1048
+ impl XxxUnused {
1049
+ #[ inline]
1050
+ $fn_prefix $ctor_name( ) -> $unit_field_int_ty {
1051
+ 0
1052
+ }
1053
+ }
1054
+ ) . unwrap ( )
1055
+ }
1056
+ }
1057
+
1058
+ impl Bitfield {
1059
+ /// Extend an under construction bitfield unit constructor with this
1060
+ /// bitfield. This involves two things:
1061
+ ///
1062
+ /// 1. Adding a parameter with this bitfield's name and its type.
1063
+ ///
1064
+ /// 2. Bitwise or'ing the parameter into the final value of the constructed
1065
+ /// bitfield unit.
1066
+ fn extend_ctor_impl ( & self ,
1067
+ ctx : & BindgenContext ,
1068
+ parent : & CompInfo ,
1069
+ ctor_impl : P < ast:: Item > ,
1070
+ ctor_name : & ast:: Ident ,
1071
+ unit_field_int_ty : & P < ast:: Ty > )
1072
+ -> P < ast:: Item > {
1073
+ match ctor_impl. unwrap ( ) . node {
1074
+ ast:: ItemKind :: Impl ( _, _, _, _, _, ref items) => {
1075
+ assert_eq ! ( items. len( ) , 1 ) ;
1076
+
1077
+ match items. get ( 0 ) . unwrap ( ) . node {
1078
+ ast:: ImplItemKind :: Method ( ref sig, ref body) => {
1079
+ let params = sig. decl . clone ( ) . unwrap ( ) . inputs ;
1080
+ let param_name = bitfield_getter_name ( ctx, parent, self . name ( ) ) ;
1081
+
1082
+ let bitfield_ty_item = ctx. resolve_item ( self . ty ( ) ) ;
1083
+ let bitfield_ty = bitfield_ty_item. expect_type ( ) ;
1084
+ let bitfield_ty_layout = bitfield_ty. layout ( ctx)
1085
+ . expect ( "Bitfield without layout? Gah!" ) ;
1086
+ let bitfield_int_ty = BlobTyBuilder :: new ( bitfield_ty_layout) . build ( ) ;
1087
+ let bitfield_ty = bitfield_ty
1088
+ . to_rust_ty_or_opaque ( ctx, bitfield_ty_item) ;
1089
+
1090
+ let offset = self . offset_into_unit ( ) ;
1091
+ let mask = self . mask ( ) ;
1092
+
1093
+ // If we're generating unstable Rust, add the const.
1094
+ let fn_prefix = if ctx. options ( ) . unstable_rust {
1095
+ quote_tokens ! ( ctx. ext_cx( ) , pub const fn )
1096
+ } else {
1097
+ quote_tokens ! ( ctx. ext_cx( ) , pub fn )
1098
+ } ;
1099
+
1100
+ quote_item ! (
1101
+ ctx. ext_cx( ) ,
1102
+ impl XxxUnused {
1103
+ #[ inline]
1104
+ $fn_prefix $ctor_name( $params $param_name : $bitfield_ty)
1105
+ -> $unit_field_int_ty {
1106
+ let bitfield_unit_val = $body;
1107
+ let $param_name = $param_name
1108
+ as $bitfield_int_ty
1109
+ as $unit_field_int_ty;
1110
+ let mask = $mask as $unit_field_int_ty;
1111
+ let $param_name = ( $param_name << $offset) & mask;
1112
+ bitfield_unit_val | $param_name
1113
+ }
1114
+ }
1115
+ ) . unwrap ( )
1116
+ }
1117
+ _ => unreachable ! ( ) ,
1118
+ }
1119
+ }
1120
+ _ => unreachable ! ( ) ,
1121
+ }
1122
+ }
1123
+ }
1124
+
1023
1125
impl < ' a > FieldCodegen < ' a > for BitfieldUnit {
1024
1126
type Extra = ( ) ;
1025
1127
@@ -1058,6 +1160,9 @@ impl<'a> FieldCodegen<'a> for BitfieldUnit {
1058
1160
}
1059
1161
} ;
1060
1162
1163
+ let ctor_name = self . ctor_name ( ctx) ;
1164
+ let mut ctor_impl = self . initial_ctor_impl ( ctx, & unit_field_int_ty) ;
1165
+
1061
1166
for bf in self . bitfields ( ) {
1062
1167
bf. codegen ( ctx,
1063
1168
fields_should_be_private,
@@ -1069,8 +1174,22 @@ impl<'a> FieldCodegen<'a> for BitfieldUnit {
1069
1174
fields,
1070
1175
methods,
1071
1176
( & unit_field_name, unit_field_int_ty. clone ( ) ) ) ;
1177
+
1178
+ ctor_impl = bf. extend_ctor_impl ( ctx,
1179
+ parent,
1180
+ ctor_impl,
1181
+ & ctor_name,
1182
+ & unit_field_int_ty) ;
1072
1183
}
1073
1184
1185
+ match ctor_impl. unwrap ( ) . node {
1186
+ ast:: ItemKind :: Impl ( _, _, _, _, _, items) => {
1187
+ assert_eq ! ( items. len( ) , 1 ) ;
1188
+ methods. extend ( items. into_iter ( ) ) ;
1189
+ } ,
1190
+ _ => unreachable ! ( ) ,
1191
+ } ;
1192
+
1074
1193
struct_layout. saw_bitfield_unit ( self . layout ( ) ) ;
1075
1194
}
1076
1195
}
@@ -1154,7 +1273,7 @@ impl<'a> FieldCodegen<'a> for Bitfield {
1154
1273
let bitfield_ty = bitfield_ty. to_rust_ty_or_opaque ( ctx, bitfield_ty_item) ;
1155
1274
1156
1275
let offset = self . offset_into_unit ( ) ;
1157
- let mask: usize = ( ( 1usize << self . width ( ) ) - 1usize ) << offset ;
1276
+ let mask: usize = self . mask ( ) ;
1158
1277
1159
1278
let impl_item = quote_item ! (
1160
1279
ctx. ext_cx( ) ,
0 commit comments