1 // Copyright 2018 The ChromiumOS Authors
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #![recursion_limit = "256"]
6
7 extern crate proc_macro;
8
9 use proc_macro2::Span;
10 use proc_macro2::TokenStream;
11 use quote::quote;
12 use quote::quote_spanned;
13 use syn::parse::Error;
14 use syn::parse::Result;
15 use syn::parse_macro_input;
16 use syn::Attribute;
17 use syn::Data;
18 use syn::DataEnum;
19 use syn::DeriveInput;
20 use syn::Fields;
21 use syn::FieldsNamed;
22 use syn::FieldsUnnamed;
23 use syn::Ident;
24 use syn::Lit;
25 use syn::LitInt;
26 use syn::Meta;
27 use syn::Type;
28 use syn::Visibility;
29
30 /// The function that derives the actual implementation.
31 #[proc_macro_attribute]
bitfield( _args: proc_macro::TokenStream, input: proc_macro::TokenStream, ) -> proc_macro::TokenStream32 pub fn bitfield(
33 _args: proc_macro::TokenStream,
34 input: proc_macro::TokenStream,
35 ) -> proc_macro::TokenStream {
36 let derive_input = parse_macro_input!(input as DeriveInput);
37
38 let expanded = bitfield_impl(&derive_input).unwrap_or_else(|err| {
39 let compile_error = err.to_compile_error();
40 quote! {
41 #compile_error
42
43 // Include the original input to avoid "use of undeclared type"
44 // errors elsewhere.
45 #derive_input
46 }
47 });
48
49 expanded.into()
50 }
51
bitfield_impl(ast: &DeriveInput) -> Result<TokenStream>52 fn bitfield_impl(ast: &DeriveInput) -> Result<TokenStream> {
53 if !ast.generics.params.is_empty() {
54 return Err(Error::new(
55 Span::call_site(),
56 "#[bitfield] does not support generic parameters",
57 ));
58 }
59
60 match &ast.data {
61 Data::Struct(data_struct) => match &data_struct.fields {
62 Fields::Named(fields_named) => bitfield_struct_impl(ast, fields_named),
63 Fields::Unnamed(fields_unnamed) => bitfield_tuple_struct_impl(ast, fields_unnamed),
64 Fields::Unit => Err(Error::new(
65 Span::call_site(),
66 "#[bitfield] does not work with unit struct",
67 )),
68 },
69 Data::Enum(data_enum) => bitfield_enum_impl(ast, data_enum),
70 Data::Union(_) => Err(Error::new(
71 Span::call_site(),
72 "#[bitfield] does not support unions",
73 )),
74 }
75 }
76
bitfield_tuple_struct_impl(ast: &DeriveInput, fields: &FieldsUnnamed) -> Result<TokenStream>77 fn bitfield_tuple_struct_impl(ast: &DeriveInput, fields: &FieldsUnnamed) -> Result<TokenStream> {
78 let mut ast = ast.clone();
79 let width = match parse_remove_bits_attr(&mut ast)? {
80 Some(w) => w,
81 None => {
82 return Err(Error::new(
83 Span::call_site(),
84 "tuple struct field must have bits attribute",
85 ));
86 }
87 };
88
89 let ident = &ast.ident;
90
91 if width > 64 {
92 return Err(Error::new(
93 Span::call_site(),
94 "max width of bitfield field is 64",
95 ));
96 }
97
98 let bits = width as u8;
99
100 if fields.unnamed.len() != 1 {
101 return Err(Error::new(
102 Span::call_site(),
103 "tuple struct field must have exactly 1 field",
104 ));
105 }
106
107 let field_type = match &fields.unnamed.first().unwrap().ty {
108 Type::Path(t) => t,
109 _ => {
110 return Err(Error::new(
111 Span::call_site(),
112 "tuple struct field must have primitive field",
113 ));
114 }
115 };
116 let span = field_type.path.segments.first().unwrap().ident.span();
117
118 let from_u64 = quote_spanned! {
119 span => val as #field_type
120 };
121
122 let into_u64 = quote_spanned! {
123 span => val.0 as u64
124 };
125
126 let expanded = quote! {
127 #ast
128
129 impl bit_field::BitFieldSpecifier for #ident {
130 const FIELD_WIDTH: u8 = #bits;
131 type SetterType = Self;
132 type GetterType = Self;
133
134 #[inline]
135 fn from_u64(val: u64) -> Self::GetterType {
136 Self(#from_u64)
137 }
138
139 #[inline]
140 fn into_u64(val: Self::SetterType) -> u64 {
141 #into_u64
142 }
143 }
144 };
145
146 Ok(expanded)
147 }
148
bitfield_enum_impl(ast: &DeriveInput, data: &DataEnum) -> Result<TokenStream>149 fn bitfield_enum_impl(ast: &DeriveInput, data: &DataEnum) -> Result<TokenStream> {
150 let mut ast = ast.clone();
151 let width = parse_remove_bits_attr(&mut ast)?;
152 match width {
153 None => bitfield_enum_without_width_impl(&ast, data),
154 Some(width) => bitfield_enum_with_width_impl(&ast, data, width),
155 }
156 }
157
bitfield_enum_with_width_impl( ast: &DeriveInput, data: &DataEnum, width: u64, ) -> Result<TokenStream>158 fn bitfield_enum_with_width_impl(
159 ast: &DeriveInput,
160 data: &DataEnum,
161 width: u64,
162 ) -> Result<TokenStream> {
163 if width > 64 {
164 return Err(Error::new(
165 Span::call_site(),
166 "max width of bitfield enum is 64",
167 ));
168 }
169 let bits = width as u8;
170 let declare_discriminants = get_declare_discriminants_for_enum(bits, ast, data);
171
172 let ident = &ast.ident;
173 let type_name = ident.to_string();
174 let variants = &data.variants;
175 let match_discriminants = variants.iter().map(|variant| {
176 let variant = &variant.ident;
177 quote! {
178 discriminant::#variant => Ok(#ident::#variant),
179 }
180 });
181
182 let expanded = quote! {
183 #ast
184
185 impl bit_field::BitFieldSpecifier for #ident {
186 const FIELD_WIDTH: u8 = #bits;
187 type SetterType = Self;
188 type GetterType = std::result::Result<Self, bit_field::Error>;
189
190 #[inline]
191 fn from_u64(val: u64) -> Self::GetterType {
192 struct discriminant;
193 impl discriminant {
194 #(#declare_discriminants)*
195 }
196 match val {
197 #(#match_discriminants)*
198 v => Err(bit_field::Error::new(#type_name, v)),
199 }
200 }
201
202 #[inline]
203 fn into_u64(val: Self::SetterType) -> u64 {
204 val as u64
205 }
206 }
207 };
208
209 Ok(expanded)
210 }
211 // Expand to an impl of BitFieldSpecifier for an enum like:
212 //
213 // #[bitfield]
214 // #[derive(Debug, PartialEq)]
215 // enum TwoBits {
216 // Zero = 0b00,
217 // One = 0b01,
218 // Two = 0b10,
219 // Three = 0b11,
220 // }
221 //
222 // Such enums may be used as a field of a bitfield struct.
223 //
224 // #[bitfield]
225 // struct Struct {
226 // prefix: BitField1,
227 // two_bits: TwoBits,
228 // suffix: BitField5,
229 // }
230 //
bitfield_enum_without_width_impl(ast: &DeriveInput, data: &DataEnum) -> Result<TokenStream>231 fn bitfield_enum_without_width_impl(ast: &DeriveInput, data: &DataEnum) -> Result<TokenStream> {
232 let ident = &ast.ident;
233 let variants = &data.variants;
234 let len = variants.len();
235 if len.count_ones() != 1 {
236 return Err(Error::new(
237 Span::call_site(),
238 "#[bitfield] expected a number of variants which is a power of 2 when bits is not \
239 specified for the enum",
240 ));
241 }
242
243 let bits = len.trailing_zeros() as u8;
244 let declare_discriminants = get_declare_discriminants_for_enum(bits, ast, data);
245
246 let match_discriminants = variants.iter().map(|variant| {
247 let variant = &variant.ident;
248 quote! {
249 discriminant::#variant => #ident::#variant,
250 }
251 });
252
253 let expanded = quote! {
254 #ast
255
256 impl bit_field::BitFieldSpecifier for #ident {
257 const FIELD_WIDTH: u8 = #bits;
258 type SetterType = Self;
259 type GetterType = Self;
260
261 #[inline]
262 fn from_u64(val: u64) -> Self::GetterType {
263 struct discriminant;
264 impl discriminant {
265 #(#declare_discriminants)*
266 }
267 match val {
268 #(#match_discriminants)*
269 _ => unreachable!(),
270 }
271 }
272
273 #[inline]
274 fn into_u64(val: Self::SetterType) -> u64 {
275 val as u64
276 }
277 }
278 };
279
280 Ok(expanded)
281 }
282
get_declare_discriminants_for_enum( bits: u8, ast: &DeriveInput, data: &DataEnum, ) -> Vec<TokenStream>283 fn get_declare_discriminants_for_enum(
284 bits: u8,
285 ast: &DeriveInput,
286 data: &DataEnum,
287 ) -> Vec<TokenStream> {
288 let variants = &data.variants;
289 let upper_bound = 2u64.pow(bits as u32);
290 let ident = &ast.ident;
291
292 variants
293 .iter()
294 .map(|variant| {
295 let variant = &variant.ident;
296 let span = variant.span();
297
298 let assertion = quote_spanned! {span=>
299 // If IS_IN_BOUNDS is true, this evaluates to 0.
300 //
301 // If IS_IN_BOUNDS is false, this evaluates to `0 - 1` which
302 // triggers a compile error on underflow when referenced below. The
303 // error is not beautiful but does carry the span of the problematic
304 // enum variant so at least it points to the right line.
305 //
306 // error: any use of this value will cause an error
307 // --> bit_field/test.rs:10:5
308 // |
309 // 10 | OutOfBounds = 0b111111,
310 // | ^^^^^^^^^^^ attempt to subtract with overflow
311 // |
312 //
313 // error[E0080]: erroneous constant used
314 // --> bit_field/test.rs:5:1
315 // |
316 // 5 | #[bitfield]
317 // | ^^^^^^^^^^^ referenced constant has errors
318 //
319 const ASSERT: u64 = 0 - !IS_IN_BOUNDS as u64;
320 };
321
322 quote! {
323 #[allow(non_upper_case_globals)]
324 const #variant: u64 = {
325 const IS_IN_BOUNDS: bool = (#ident::#variant as u64) < #upper_bound;
326
327 #assertion
328
329 #ident::#variant as u64 + ASSERT
330 };
331 }
332 })
333 .collect()
334 }
335
bitfield_struct_impl(ast: &DeriveInput, fields: &FieldsNamed) -> Result<TokenStream>336 fn bitfield_struct_impl(ast: &DeriveInput, fields: &FieldsNamed) -> Result<TokenStream> {
337 let name = &ast.ident;
338 let vis = &ast.vis;
339 let attrs = &ast.attrs;
340 let fields = get_struct_fields(fields)?;
341 let struct_def = get_struct_def(vis, name, &fields);
342 let bits_impl = get_bits_impl(name);
343 let fields_impl = get_fields_impl(&fields);
344 let debug_fmt_impl = get_debug_fmt_impl(name, &fields);
345
346 let expanded = quote! {
347 #(#attrs)*
348 #struct_def
349 #bits_impl
350 impl #name {
351 #(#fields_impl)*
352 }
353 #debug_fmt_impl
354 };
355
356 Ok(expanded)
357 }
358
359 struct FieldSpec<'a> {
360 ident: &'a Ident,
361 ty: &'a Type,
362 expected_bits: Option<LitInt>,
363 }
364
365 // Unwrap ast to get the named fields. We only care about field names and types:
366 // "myfield : BitField3" -> ("myfield", Token(BitField3))
get_struct_fields(fields: &FieldsNamed) -> Result<Vec<FieldSpec>>367 fn get_struct_fields(fields: &FieldsNamed) -> Result<Vec<FieldSpec>> {
368 let mut vec = Vec::new();
369
370 for field in &fields.named {
371 let ident = field
372 .ident
373 .as_ref()
374 .expect("Fields::Named has named fields");
375 let ty = &field.ty;
376 let expected_bits = parse_bits_attr(&field.attrs)?;
377 vec.push(FieldSpec {
378 ident,
379 ty,
380 expected_bits,
381 });
382 }
383
384 Ok(vec)
385 }
386
387 // For example: #[bits = 1]
parse_bits_attr(attrs: &[Attribute]) -> Result<Option<LitInt>>388 fn parse_bits_attr(attrs: &[Attribute]) -> Result<Option<LitInt>> {
389 let mut expected_bits = None;
390
391 for attr in attrs {
392 if attr.path.is_ident("doc") {
393 continue;
394 }
395 if let Some(v) = try_parse_bits_attr(attr)? {
396 expected_bits = Some(v);
397 continue;
398 }
399
400 return Err(Error::new_spanned(attr, "unrecognized attribute"));
401 }
402
403 Ok(expected_bits)
404 }
405
406 // This function will return None if the attribute is not #[bits = *].
try_parse_bits_attr(attr: &Attribute) -> Result<Option<LitInt>>407 fn try_parse_bits_attr(attr: &Attribute) -> Result<Option<LitInt>> {
408 if attr.path.is_ident("bits") {
409 if let Meta::NameValue(name_value) = attr.parse_meta()? {
410 if let Lit::Int(int) = name_value.lit {
411 return Ok(Some(int));
412 }
413 }
414 }
415 Ok(None)
416 }
417
parse_remove_bits_attr(ast: &mut DeriveInput) -> Result<Option<u64>>418 fn parse_remove_bits_attr(ast: &mut DeriveInput) -> Result<Option<u64>> {
419 let mut width = None;
420 let mut bits_idx = 0;
421
422 for (i, attr) in ast.attrs.iter().enumerate() {
423 if let Some(w) = try_parse_bits_attr(attr)? {
424 bits_idx = i;
425 width = Some(w.base10_parse()?);
426 }
427 }
428
429 if width.is_some() {
430 ast.attrs.remove(bits_idx);
431 }
432
433 Ok(width)
434 }
435
get_struct_def(vis: &Visibility, name: &Ident, fields: &[FieldSpec]) -> TokenStream436 fn get_struct_def(vis: &Visibility, name: &Ident, fields: &[FieldSpec]) -> TokenStream {
437 let mut field_types = Vec::new();
438 for spec in fields {
439 field_types.push(spec.ty);
440 }
441
442 // `(BitField1::FIELD_WIDTH + BitField3::FIELD_WIDTH + ...)`
443 let data_size_in_bits = quote! {
444 (
445 #(
446 <#field_types as ::bit_field::BitFieldSpecifier>::FIELD_WIDTH as usize
447 )+*
448 )
449 };
450
451 quote! {
452 #[repr(C)]
453 #vis struct #name {
454 data: [u8; #data_size_in_bits / 8],
455 }
456
457 impl #name {
458 pub fn new() -> #name {
459 let _: ::bit_field::Check<[u8; #data_size_in_bits % 8]>;
460
461 #name {
462 data: [0; #data_size_in_bits / 8],
463 }
464 }
465 }
466 }
467 }
468
469 // Implement setter and getter for all fields.
get_fields_impl(fields: &[FieldSpec]) -> Vec<TokenStream>470 fn get_fields_impl(fields: &[FieldSpec]) -> Vec<TokenStream> {
471 let mut impls = Vec::new();
472 // This vec keeps track of types before this field, used to generate the offset.
473 let current_types = &mut vec![quote!(::bit_field::BitField0)];
474
475 for spec in fields {
476 let ty = spec.ty;
477 let getter_ident = Ident::new(format!("get_{}", spec.ident).as_str(), Span::call_site());
478 let setter_ident = Ident::new(format!("set_{}", spec.ident).as_str(), Span::call_site());
479
480 // Optional #[bits = N] attribute to provide compile-time checked
481 // documentation of how many bits some field covers.
482 let check_expected_bits = spec.expected_bits.as_ref().map(|expected_bits| {
483 // If expected_bits does not match the actual number of bits in the
484 // bit field specifier, this will fail to compile with an error
485 // pointing into the #[bits = N] attribute.
486 let span = expected_bits.span();
487 quote_spanned! {span=>
488 #[allow(dead_code)]
489 const EXPECTED_BITS: [(); #expected_bits] =
490 [(); <#ty as ::bit_field::BitFieldSpecifier>::FIELD_WIDTH as usize];
491 }
492 });
493
494 impls.push(quote! {
495 pub fn #getter_ident(&self) -> <#ty as ::bit_field::BitFieldSpecifier>::GetterType {
496 #check_expected_bits
497 let offset = #(<#current_types as ::bit_field::BitFieldSpecifier>::FIELD_WIDTH as usize)+*;
498 let val = self.get(offset, <#ty as ::bit_field::BitFieldSpecifier>::FIELD_WIDTH);
499 <#ty as ::bit_field::BitFieldSpecifier>::from_u64(val)
500 }
501
502 pub fn #setter_ident(&mut self, val: <#ty as ::bit_field::BitFieldSpecifier>::SetterType) {
503 let val = <#ty as ::bit_field::BitFieldSpecifier>::into_u64(val);
504 debug_assert!(val <= ::bit_field::max::<#ty>());
505 let offset = #(<#current_types as ::bit_field::BitFieldSpecifier>::FIELD_WIDTH as usize)+*;
506 self.set(offset, <#ty as ::bit_field::BitFieldSpecifier>::FIELD_WIDTH, val)
507 }
508 });
509
510 current_types.push(quote!(#ty));
511 }
512
513 impls
514 }
515
516 // Implement setter and getter for all fields.
get_debug_fmt_impl(name: &Ident, fields: &[FieldSpec]) -> TokenStream517 fn get_debug_fmt_impl(name: &Ident, fields: &[FieldSpec]) -> TokenStream {
518 // print fields:
519 let mut impls = Vec::new();
520 for spec in fields {
521 let field_name = spec.ident.to_string();
522 let getter_ident = Ident::new(&format!("get_{}", spec.ident), Span::call_site());
523 impls.push(quote! {
524 .field(#field_name, &self.#getter_ident())
525 });
526 }
527
528 let name_str = format!("{}", name);
529 quote! {
530 impl std::fmt::Debug for #name {
531 fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
532 f.debug_struct(#name_str)
533 #(#impls)*
534 .finish()
535 }
536 }
537 }
538 }
539
get_bits_impl(name: &Ident) -> TokenStream540 fn get_bits_impl(name: &Ident) -> TokenStream {
541 quote! {
542 impl #name {
543 #[inline]
544 fn check_access(&self, offset: usize, width: u8) {
545 debug_assert!(width <= 64);
546 debug_assert!(offset / 8 < self.data.len());
547 debug_assert!((offset + (width as usize)) <= (self.data.len() * 8));
548 }
549
550 #[inline]
551 pub fn get_bit(&self, offset: usize) -> bool {
552 self.check_access(offset, 1);
553
554 let byte_index = offset / 8;
555 let bit_offset = offset % 8;
556
557 let byte = self.data[byte_index];
558 let mask = 1 << bit_offset;
559
560 byte & mask == mask
561 }
562
563 #[inline]
564 pub fn set_bit(&mut self, offset: usize, val: bool) {
565 self.check_access(offset, 1);
566
567 let byte_index = offset / 8;
568 let bit_offset = offset % 8;
569
570 let byte = &mut self.data[byte_index];
571 let mask = 1 << bit_offset;
572
573 if val {
574 *byte |= mask;
575 } else {
576 *byte &= !mask;
577 }
578 }
579
580 #[inline]
581 pub fn get(&self, offset: usize, width: u8) -> u64 {
582 self.check_access(offset, width);
583 let mut val = 0;
584
585 for i in 0..(width as usize) {
586 if self.get_bit(i + offset) {
587 val |= 1 << i;
588 }
589 }
590
591 val
592 }
593
594 #[inline]
595 pub fn set(&mut self, offset: usize, width: u8, val: u64) {
596 self.check_access(offset, width);
597
598 for i in 0..(width as usize) {
599 let mask = 1 << i;
600 let val_bit_is_set = val & mask == mask;
601 self.set_bit(i + offset, val_bit_is_set);
602 }
603 }
604 }
605 }
606 }
607
608 // Only intended to be used from the bit_field crate. This macro emits the
609 // marker types bit_field::BitField0 through bit_field::BitField64.
610 #[proc_macro]
611 #[doc(hidden)]
define_bit_field_specifiers(_input: proc_macro::TokenStream) -> proc_macro::TokenStream612 pub fn define_bit_field_specifiers(_input: proc_macro::TokenStream) -> proc_macro::TokenStream {
613 let mut code = TokenStream::new();
614
615 for width in 0u8..=64 {
616 let span = Span::call_site();
617 let long_name = Ident::new(&format!("BitField{}", width), span);
618 let short_name = Ident::new(&format!("B{}", width), span);
619
620 let default_field_type = if width <= 8 {
621 quote!(u8)
622 } else if width <= 16 {
623 quote!(u16)
624 } else if width <= 32 {
625 quote!(u32)
626 } else {
627 quote!(u64)
628 };
629
630 code.extend(quote! {
631 pub struct #long_name;
632 pub use self::#long_name as #short_name;
633
634 impl BitFieldSpecifier for #long_name {
635 const FIELD_WIDTH: u8 = #width;
636 type SetterType = #default_field_type;
637 type GetterType = #default_field_type;
638
639 #[inline]
640 fn from_u64(val: u64) -> Self::GetterType {
641 val as Self::GetterType
642 }
643
644 #[inline]
645 fn into_u64(val: Self::SetterType) -> u64 {
646 val as u64
647 }
648 }
649 });
650 }
651
652 code.into()
653 }
654
655 #[cfg(test)]
656 mod tests {
657 use syn::parse_quote;
658
659 use super::*;
660
661 #[test]
end_to_end()662 fn end_to_end() {
663 let input: DeriveInput = parse_quote! {
664 #[derive(Clone)]
665 struct MyBitField {
666 a: BitField1,
667 b: BitField2,
668 c: BitField5,
669 }
670 };
671
672 let expected = quote! {
673 #[derive(Clone)]
674 #[repr(C)]
675 struct MyBitField {
676 data: [u8; (<BitField1 as ::bit_field::BitFieldSpecifier>::FIELD_WIDTH as usize
677 + <BitField2 as ::bit_field::BitFieldSpecifier>::FIELD_WIDTH as usize
678 + <BitField5 as ::bit_field::BitFieldSpecifier>::FIELD_WIDTH as usize)
679 / 8],
680 }
681 impl MyBitField {
682 pub fn new() -> MyBitField {
683 let _: ::bit_field::Check<[
684 u8;
685 (<BitField1 as ::bit_field::BitFieldSpecifier>::FIELD_WIDTH as usize
686 + <BitField2 as ::bit_field::BitFieldSpecifier>::FIELD_WIDTH as usize
687 + <BitField5 as ::bit_field::BitFieldSpecifier>::FIELD_WIDTH as usize)
688 % 8
689 ]>;
690
691 MyBitField {
692 data: [0; (<BitField1 as ::bit_field::BitFieldSpecifier>::FIELD_WIDTH as usize
693 + <BitField2 as ::bit_field::BitFieldSpecifier>::FIELD_WIDTH as usize
694 + <BitField5 as ::bit_field::BitFieldSpecifier>::FIELD_WIDTH as usize)
695 / 8],
696 }
697 }
698 }
699 impl MyBitField {
700 #[inline]
701 fn check_access(&self, offset: usize, width: u8) {
702 debug_assert!(width <= 64);
703 debug_assert!(offset / 8 < self.data.len());
704 debug_assert!((offset + (width as usize)) <= (self.data.len() * 8));
705 }
706 #[inline]
707 pub fn get_bit(&self, offset: usize) -> bool {
708 self.check_access(offset, 1);
709 let byte_index = offset / 8;
710 let bit_offset = offset % 8;
711 let byte = self.data[byte_index];
712 let mask = 1 << bit_offset;
713 byte & mask == mask
714 }
715 #[inline]
716 pub fn set_bit(&mut self, offset: usize, val: bool) {
717 self.check_access(offset, 1);
718 let byte_index = offset / 8;
719 let bit_offset = offset % 8;
720 let byte = &mut self.data[byte_index];
721 let mask = 1 << bit_offset;
722 if val {
723 *byte |= mask;
724 } else {
725 *byte &= !mask;
726 }
727 }
728 #[inline]
729 pub fn get(&self, offset: usize, width: u8) -> u64 {
730 self.check_access(offset, width);
731 let mut val = 0;
732 for i in 0..(width as usize) {
733 if self.get_bit(i + offset) {
734 val |= 1 << i;
735 }
736 }
737 val
738 }
739 #[inline]
740 pub fn set(&mut self, offset: usize, width: u8, val: u64) {
741 self.check_access(offset, width);
742 for i in 0..(width as usize) {
743 let mask = 1 << i;
744 let val_bit_is_set = val & mask == mask;
745 self.set_bit(i + offset, val_bit_is_set);
746 }
747 }
748 }
749 impl MyBitField {
750 pub fn get_a(&self) -> <BitField1 as ::bit_field::BitFieldSpecifier>::GetterType {
751 let offset = <::bit_field::BitField0 as ::bit_field::BitFieldSpecifier>::FIELD_WIDTH as usize;
752 let val = self.get(offset, <BitField1 as ::bit_field::BitFieldSpecifier>::FIELD_WIDTH);
753 <BitField1 as ::bit_field::BitFieldSpecifier>::from_u64(val)
754 }
755 pub fn set_a(&mut self, val: <BitField1 as ::bit_field::BitFieldSpecifier>::SetterType) {
756 let val = <BitField1 as ::bit_field::BitFieldSpecifier>::into_u64(val);
757 debug_assert!(val <= ::bit_field::max::<BitField1>());
758 let offset = <::bit_field::BitField0 as ::bit_field::BitFieldSpecifier>::FIELD_WIDTH as usize;
759 self.set(offset, <BitField1 as ::bit_field::BitFieldSpecifier>::FIELD_WIDTH, val)
760 }
761 pub fn get_b(&self) -> <BitField2 as ::bit_field::BitFieldSpecifier>::GetterType {
762 let offset = <::bit_field::BitField0 as ::bit_field::BitFieldSpecifier>::FIELD_WIDTH as usize
763 + <BitField1 as ::bit_field::BitFieldSpecifier>::FIELD_WIDTH as usize;
764 let val = self.get(offset, <BitField2 as ::bit_field::BitFieldSpecifier>::FIELD_WIDTH);
765 <BitField2 as ::bit_field::BitFieldSpecifier>::from_u64(val)
766 }
767 pub fn set_b(&mut self, val: <BitField2 as ::bit_field::BitFieldSpecifier>::SetterType) {
768 let val = <BitField2 as ::bit_field::BitFieldSpecifier>::into_u64(val);
769 debug_assert!(val <= ::bit_field::max::<BitField2>());
770 let offset = <::bit_field::BitField0 as ::bit_field::BitFieldSpecifier>::FIELD_WIDTH as usize
771 + <BitField1 as ::bit_field::BitFieldSpecifier>::FIELD_WIDTH as usize;
772 self.set(offset, <BitField2 as ::bit_field::BitFieldSpecifier>::FIELD_WIDTH, val)
773 }
774 pub fn get_c(&self) -> <BitField5 as ::bit_field::BitFieldSpecifier>::GetterType {
775 let offset = <::bit_field::BitField0 as ::bit_field::BitFieldSpecifier>::FIELD_WIDTH as usize
776 + <BitField1 as ::bit_field::BitFieldSpecifier>::FIELD_WIDTH as usize
777 + <BitField2 as ::bit_field::BitFieldSpecifier>::FIELD_WIDTH as usize;
778 let val = self.get(offset, <BitField5 as ::bit_field::BitFieldSpecifier>::FIELD_WIDTH);
779 <BitField5 as ::bit_field::BitFieldSpecifier>::from_u64(val)
780 }
781 pub fn set_c(&mut self, val: <BitField5 as ::bit_field::BitFieldSpecifier>::SetterType) {
782 let val = <BitField5 as ::bit_field::BitFieldSpecifier>::into_u64(val);
783 debug_assert!(val <= ::bit_field::max::<BitField5>());
784 let offset = <::bit_field::BitField0 as ::bit_field::BitFieldSpecifier>::FIELD_WIDTH as usize
785 + <BitField1 as ::bit_field::BitFieldSpecifier>::FIELD_WIDTH as usize
786 + <BitField2 as ::bit_field::BitFieldSpecifier>::FIELD_WIDTH as usize;
787 self.set(offset, <BitField5 as ::bit_field::BitFieldSpecifier>::FIELD_WIDTH, val)
788 }
789 }
790 impl std::fmt::Debug for MyBitField {
791 fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
792 f.debug_struct("MyBitField")
793 .field("a", &self.get_a())
794 .field("b", &self.get_b())
795 .field("c", &self.get_c())
796 .finish()
797 }
798 }
799 };
800
801 assert_eq!(
802 bitfield_impl(&input).unwrap().to_string(),
803 expected.to_string()
804 );
805 }
806 }
807