@@ -1020,6 +1020,111 @@ 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
+ let items = match ctor_impl. unwrap ( ) . node {
1074
+ ast:: ItemKind :: Impl ( _, _, _, _, _, items) => {
1075
+ items
1076
+ }
1077
+ _ => unreachable ! ( ) ,
1078
+ } ;
1079
+
1080
+ assert_eq ! ( items. len( ) , 1 ) ;
1081
+ let ( sig, body) = match items[ 0 ] . node {
1082
+ ast:: ImplItemKind :: Method ( ref sig, ref body) => {
1083
+ ( sig, body)
1084
+ }
1085
+ _ => unreachable ! ( ) ,
1086
+ } ;
1087
+
1088
+ let params = sig. decl . clone ( ) . unwrap ( ) . inputs ;
1089
+ let param_name = bitfield_getter_name ( ctx, parent, self . name ( ) ) ;
1090
+
1091
+ let bitfield_ty_item = ctx. resolve_item ( self . ty ( ) ) ;
1092
+ let bitfield_ty = bitfield_ty_item. expect_type ( ) ;
1093
+ let bitfield_ty_layout = bitfield_ty. layout ( ctx)
1094
+ . expect ( "Bitfield without layout? Gah!" ) ;
1095
+ let bitfield_int_ty = BlobTyBuilder :: new ( bitfield_ty_layout) . build ( ) ;
1096
+ let bitfield_ty = bitfield_ty
1097
+ . to_rust_ty_or_opaque ( ctx, bitfield_ty_item) ;
1098
+
1099
+ let offset = self . offset_into_unit ( ) ;
1100
+ let mask = self . mask ( ) ;
1101
+
1102
+ // If we're generating unstable Rust, add the const.
1103
+ let fn_prefix = if ctx. options ( ) . unstable_rust {
1104
+ quote_tokens ! ( ctx. ext_cx( ) , pub const fn )
1105
+ } else {
1106
+ quote_tokens ! ( ctx. ext_cx( ) , pub fn )
1107
+ } ;
1108
+
1109
+ quote_item ! (
1110
+ ctx. ext_cx( ) ,
1111
+ impl XxxUnused {
1112
+ #[ inline]
1113
+ $fn_prefix $ctor_name( $params $param_name : $bitfield_ty)
1114
+ -> $unit_field_int_ty {
1115
+ let bitfield_unit_val = $body;
1116
+ let $param_name = $param_name
1117
+ as $bitfield_int_ty
1118
+ as $unit_field_int_ty;
1119
+ let mask = $mask as $unit_field_int_ty;
1120
+ let $param_name = ( $param_name << $offset) & mask;
1121
+ bitfield_unit_val | $param_name
1122
+ }
1123
+ }
1124
+ ) . unwrap ( )
1125
+ }
1126
+ }
1127
+
1023
1128
impl < ' a > FieldCodegen < ' a > for BitfieldUnit {
1024
1129
type Extra = ( ) ;
1025
1130
@@ -1058,6 +1163,9 @@ impl<'a> FieldCodegen<'a> for BitfieldUnit {
1058
1163
}
1059
1164
} ;
1060
1165
1166
+ let ctor_name = self . ctor_name ( ctx) ;
1167
+ let mut ctor_impl = self . initial_ctor_impl ( ctx, & unit_field_int_ty) ;
1168
+
1061
1169
for bf in self . bitfields ( ) {
1062
1170
bf. codegen ( ctx,
1063
1171
fields_should_be_private,
@@ -1069,8 +1177,22 @@ impl<'a> FieldCodegen<'a> for BitfieldUnit {
1069
1177
fields,
1070
1178
methods,
1071
1179
( & unit_field_name, unit_field_int_ty. clone ( ) ) ) ;
1180
+
1181
+ ctor_impl = bf. extend_ctor_impl ( ctx,
1182
+ parent,
1183
+ ctor_impl,
1184
+ & ctor_name,
1185
+ & unit_field_int_ty) ;
1072
1186
}
1073
1187
1188
+ match ctor_impl. unwrap ( ) . node {
1189
+ ast:: ItemKind :: Impl ( _, _, _, _, _, items) => {
1190
+ assert_eq ! ( items. len( ) , 1 ) ;
1191
+ methods. extend ( items. into_iter ( ) ) ;
1192
+ } ,
1193
+ _ => unreachable ! ( ) ,
1194
+ } ;
1195
+
1074
1196
struct_layout. saw_bitfield_unit ( self . layout ( ) ) ;
1075
1197
}
1076
1198
}
@@ -1154,7 +1276,7 @@ impl<'a> FieldCodegen<'a> for Bitfield {
1154
1276
let bitfield_ty = bitfield_ty. to_rust_ty_or_opaque ( ctx, bitfield_ty_item) ;
1155
1277
1156
1278
let offset = self . offset_into_unit ( ) ;
1157
- let mask: usize = ( ( 1usize << self . width ( ) ) - 1usize ) << offset ;
1279
+ let mask: usize = self . mask ( ) ;
1158
1280
1159
1281
let impl_item = quote_item ! (
1160
1282
ctx. ext_cx( ) ,
0 commit comments