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