bitflags_attr_macros/
typed.rs

1use syn::{
2    parse::Parse, punctuated::Punctuated, spanned::Spanned, token::Paren, Attribute, DeriveInput,
3    Error, Expr, Ident, ItemConst, ItemEnum, LitInt, LitStr, Meta, MetaNameValue, Path, Visibility,
4};
5
6use proc_macro2::TokenStream;
7
8use quote::{quote, ToTokens, TokenStreamExt};
9
10pub struct Bitflag {
11    vis: Visibility,
12    attrs: Vec<Attribute>,
13    name: Ident,
14    inner_ty: Path,
15    repr_attr: Option<ReprAttr>,
16    derived_traits: Vec<Path>,
17    impl_flags: ImplFlags,
18    all_attrs: Vec<Vec<Attribute>>,
19    all_flags: Vec<TokenStream>,
20    all_flags_names: Vec<LitStr>,
21    flags: Vec<ItemConst>,
22    default_value: Option<Expr>,
23    custom_known_bits: Option<Expr>,
24    orig_enum: ItemEnum,
25}
26
27impl Bitflag {
28    pub fn parse(args: Args, item: proc_macro::TokenStream) -> syn::Result<Self> {
29        let ty = args.ty;
30
31        let item: DeriveInput = syn::parse(item)?;
32        let item_span = item.span();
33        let ident_span = item.ident.span();
34        let og_attrs = item.attrs.iter().filter(|att| {
35            !att.path().is_ident("derive")
36                && !att.path().is_ident("reserved_bits")
37                && !att.path().is_ident("repr")
38                && !att.path().is_ident("serde")
39        });
40
41        let vis = item.vis;
42        let name = item.ident;
43
44        let has_non_exhaustive = item
45            .attrs
46            .iter()
47            .any(|att| att.path().is_ident("non_exhaustive"));
48
49        let serde_helper = item.attrs.iter().find(|att| att.path().is_ident("serde"));
50
51        if let Some(serde) = serde_helper {
52            return Err(Error::new(
53                serde.span(),
54                "`serde` helper attribute is not compatible with `bitflag` attribute: in this case, manual implementation of serde traits should be considered",
55            ));
56        }
57
58        // Attributes
59        let attrs = item
60            .attrs
61            .iter()
62            .filter(|att| {
63                !att.path().is_ident("derive")
64                    && !att.path().is_ident("reserved_bits")
65                    && !att.path().is_ident("repr")
66            })
67            .cloned()
68            .collect();
69
70        let repr_attr = item
71            .attrs
72            .iter()
73            .find(|att| att.path().is_ident("repr"))
74            .map(|att| syn::parse2::<ReprAttr>(att.meta.to_token_stream()));
75
76        let repr_attr = match repr_attr {
77            Some(repr) => {
78                use ReprKind::*;
79                let repr = repr?;
80
81                // Cause errors on invalid ones since Rust will cause worse errors
82                match repr.kinds() {
83                    // ignore case | impossible case
84                    (None, None) | (None, Some(_)) => {}
85                    // Simplest cases
86                    (Some(Rust(_) | C(_) | Transparent(_)), None) => {}
87                    // Definitely wrong cases
88                    (Some(kind), None)
89                    | (Some(Rust(_) | C(_)), Some(kind))
90                    | (Some(kind), Some(Rust(_) | C(_))) => {
91                        return Err(Error::new(
92                            kind.span(),
93                            "`bitflag` unsupported repr: Supported repr are `C`, `Rust` and `transparent`",
94                        ));
95                    }
96                    // TODO: Theoretically, `packed(N)` and `align(N)` is allowed if N is the same
97                    // or bigger than size_of the inner type. We can only prove it by this time
98                    // if the inner type is one of the integers of specific type (i<BITS>|u<BITS>).
99                    // We could allow and generate a static assert (a.k.a. a const that panics under
100                    // condition) like we do with the `Pod` trait.
101                    _ => {}
102                }
103                Some(repr)
104            }
105            None => None,
106        };
107
108        let valid_bits_attr = item
109            .attrs
110            .iter()
111            .find(|att| att.path().is_ident("reserved_bits"));
112
113        let derives = item
114            .attrs
115            .iter()
116            .filter(|att| att.path().is_ident("derive"));
117
118        let mut derived_traits = Vec::new();
119        let mut impl_flags = ImplFlags::empty();
120        let mut clone_found = false;
121        let mut copy_found = false;
122
123        for derive in derives {
124            derive.parse_nested_meta(|meta| {
125                let s = meta.path.to_token_stream().to_string().replace(" ", "");
126                match s.as_str() {
127                    "Debug" => {
128                        impl_flags |= ImplFlags::DEBUG;
129                        return Ok(());
130                    }
131                    "Default" => {
132                        impl_flags |= ImplFlags::DEFAULT;
133                        return Ok(());
134                    }
135                    "Serialize" | "serde::Serialize" | "::serde::Serialize"
136                        if cfg!(feature = "serde") =>
137                    {
138                        impl_flags |= ImplFlags::SERIALIZE;
139                        return Ok(());
140                    }
141                    "Deserialize" | "serde::Deserialize" | "::serde::Deserialize"
142                        if cfg!(feature = "serde") =>
143                    {
144                        impl_flags |= ImplFlags::DESERIALIZE;
145                        return Ok(());
146                    }
147                    "Arbitrary" | "arbitrary::Arbitrary" | "::arbitrary::Arbitrary"
148                        if cfg!(feature = "arbitrary") =>
149                    {
150                        impl_flags |= ImplFlags::ARBITRARY;
151                        return Ok(());
152                    }
153                    "Pod" | "bytemuck::Pod" | "::bytemuck::Pod" if cfg!(feature = "bytemuck") => {
154                        // Our types are repr(transparent) by default, and that is compatible with
155                        // the constrains required by `Pod` trait.
156                        if repr_attr.is_none() {
157                            impl_flags |= ImplFlags::POD;
158                            return Ok(());
159                        }
160
161                        if let Some(repr_attr) = &repr_attr {
162                            match repr_attr.kinds() {
163                                // Pod requires either `repr(transparent)` or `repr(C)` without
164                                // padding (I think it's always safe for one field struct) or
165                                // `repr(C, packed|align)`
166                                // We should generate static checks to make sure though
167                                (Some(ReprKind::Transparent(_) | ReprKind::C(_)), None)
168                                | (
169                                    Some(ReprKind::C(_)),
170                                    Some(ReprKind::Packed(_, _) | ReprKind::Align(_, _)),
171                                ) => {
172                                    impl_flags |= ImplFlags::POD;
173                                    return Ok(());
174                                }
175                                _ => {
176                                    return Err(Error::new(
177                                        meta.path.span(),
178                                        format!(
179                                            "bitflag: deriving `Pod` for `{}` is not compatible",
180                                            repr_attr.to_token_stream()
181                                        ),
182                                    ))
183                                }
184                            }
185                        }
186                    }
187                    "Zeroable" | "bytemuck::Zeroable" | "::bytemuck::Zeroable"
188                        if cfg!(feature = "bytemuck") =>
189                    {
190                        impl_flags |= ImplFlags::ZEROABLE;
191                        return Ok(());
192                    }
193                    path => {
194                        if path == "Clone" {
195                            clone_found = true;
196                        }
197
198                        if path == "Copy" {
199                            copy_found = true;
200                        }
201
202                        derived_traits.push(meta.path);
203                    }
204                }
205                Ok(())
206            })?;
207        }
208
209        if !clone_found || !copy_found {
210            return Err(syn::Error::new(
211                item_span,
212                "`bitflags` attribute requires the type to derive `Clone` and `Copy`",
213            ));
214        }
215
216        let enun = if let syn::Data::Enum(e) = item.data {
217            e
218        } else {
219            return Err(syn::Error::new(
220                ident_span,
221                "the type for `bitflag` must be a `enum` (that will be turned into a `struct`)",
222            ));
223        };
224        let number_flags = enun.variants.len();
225
226        let mut all_attrs = Vec::with_capacity(number_flags);
227        let mut all_flags = Vec::with_capacity(number_flags);
228        let mut all_flags_names = Vec::with_capacity(number_flags);
229        let mut all_variants = Vec::with_capacity(number_flags);
230        let mut all_non_doc_attrs = Vec::with_capacity(number_flags);
231        let mut default_value = None;
232
233        // The raw flags as private itens to allow defining flags referencing other flag definitions
234        let mut raw_flags = Vec::with_capacity(number_flags);
235
236        let mut flags = Vec::with_capacity(number_flags); // Associated constants
237
238        // First generate the raw_flags
239        for variant in enun.variants.iter() {
240            let var_attrs = &variant.attrs;
241            let var_name = &variant.ident;
242
243            if !variant.fields.is_empty() {
244                let span = variant.fields.span();
245                return Err(Error::new(
246                    span,
247                    "an enum with `bitflag` attribute can not have a field",
248                ));
249            }
250
251            let expr = match variant.discriminant.as_ref() {
252                Some((_, expr)) => expr,
253                None => {
254                    return Err(Error::new_spanned(
255                        variant,
256                        "a discriminant must be defined",
257                    ))
258                }
259            };
260
261            let serde_helper = var_attrs.iter().find(|attr| attr.path().is_ident("serde"));
262
263            if let Some(serde) = serde_helper {
264                return Err(Error::new(
265                    serde.span(),
266                    "`serde` helper attribute is not compatible with `bitflag` attribute: in this case, manual implementation of serde traits should be considered",
267                ));
268            }
269
270            let default_attr = var_attrs
271                .iter()
272                .find(|attr| attr.path().is_ident("default"));
273
274            if let Some(default) = default_attr {
275                if !impl_flags.contains(ImplFlags::DEFAULT) {
276                    return Err(Error::new(
277                        default.span(),
278                        "`default` attribute without `#[derive(Default)]`",
279                    ));
280                }
281
282                default_value = Some(syn::parse2(quote!(Self::#var_name))?);
283            }
284
285            let non_doc_attrs: Vec<Attribute> = var_attrs
286                .iter()
287                .filter(|attr| !attr.path().is_ident("doc"))
288                .cloned()
289                .collect();
290
291            let filtered_attrs = var_attrs
292                .iter()
293                .filter(|attr| !attr.path().is_ident("doc") && !attr.path().is_ident("default"));
294
295            all_flags.push(quote!(#name::#var_name));
296            all_flags_names.push(syn::LitStr::new(&var_name.to_string(), var_name.span()));
297            all_variants.push(var_name.clone());
298            all_attrs.push(filtered_attrs.clone().cloned().collect::<Vec<_>>());
299            all_non_doc_attrs.push(non_doc_attrs.clone());
300            raw_flags.push(quote! {
301                #(#filtered_attrs)*
302                #[allow(non_upper_case_globals, dead_code, unused)]
303                const #var_name: #ty = #expr;
304            });
305        }
306
307        for variant in enun.variants.iter() {
308            let var_attrs = &variant.attrs;
309            let var_name = &variant.ident;
310
311            let expr = match variant.discriminant.as_ref() {
312                Some((_, expr)) => expr,
313                None => {
314                    return Err(Error::new_spanned(
315                        variant,
316                        "a discriminant must be defined",
317                    ))
318                }
319            };
320
321            let all_attr = var_attrs
322                .iter()
323                .filter(|attr| !attr.path().is_ident("default"));
324
325            let generated = if can_simplify(expr, &all_variants) {
326                quote! {
327                    #(#all_attr)*
328                    #vis const #var_name: Self = Self(#expr);
329                }
330            } else {
331                quote! {
332                    #(#all_attr)*
333                    #vis const #var_name: Self = {
334                        #(#raw_flags)*
335
336                        Self(#expr)
337                    };
338                }
339            };
340
341            flags.push(syn::parse2(generated)?);
342        }
343
344        let og_derive = (impl_flags.contains(ImplFlags::DEFAULT) && default_value.is_some())
345            .then(|| quote!(#[derive(Default)]));
346        let orig_enum = syn::parse2(quote! {
347            #[allow(dead_code)]
348            #(#og_attrs)*
349            #og_derive
350            enum #name {
351                #(
352                    #(#all_non_doc_attrs)*
353                    #all_variants,
354                )*
355            }
356        })?;
357
358        let custom_known_bits: Option<Expr> = if let Some(attr) = valid_bits_attr {
359            let parsed = ExtraValidBits::from_meta(&attr.meta)?;
360
361            Some(parsed.0)
362        } else if has_non_exhaustive {
363            Some(syn::parse2(quote! {!0})?)
364        } else {
365            None
366        };
367
368        Ok(Self {
369            vis,
370            attrs,
371            name,
372            inner_ty: ty,
373            derived_traits,
374            repr_attr,
375            impl_flags,
376            all_attrs,
377            all_flags,
378            all_flags_names,
379            default_value,
380            flags,
381            custom_known_bits,
382            orig_enum,
383        })
384    }
385}
386
387impl ToTokens for Bitflag {
388    fn to_tokens(&self, tokens: &mut TokenStream) {
389        let Self {
390            vis,
391            attrs,
392            name,
393            inner_ty,
394            repr_attr,
395            derived_traits,
396            impl_flags,
397            all_attrs,
398            all_flags,
399            all_flags_names,
400            default_value,
401            flags,
402            custom_known_bits,
403            orig_enum,
404        } = self;
405
406        let reserved_bits = custom_known_bits
407            .as_ref()
408            .map(|expr| quote! {all |= #expr;});
409
410        let reserved_bits_value = if let Some(expr) = custom_known_bits {
411            quote! {#expr}
412        } else {
413            quote! {
414                {
415                    let mut all = 0;
416
417                    #(
418                        #(#all_attrs)*{
419                            all |= #all_flags.0;
420                        }
421                    )*
422
423                    all
424                }
425            }
426        };
427
428        let repr_attr = match repr_attr {
429            Some(repr) => {
430                quote! {#repr}
431            }
432            None => quote! {#[repr(transparent)]},
433        };
434
435        let const_mut = cfg!(feature = "const-mut-ref").then(|| quote!(const));
436
437        let debug_impl = impl_flags.contains(ImplFlags::DEBUG).then(|| {
438            quote! {
439                #[automatically_derived]
440                impl ::core::fmt::Debug for #name {
441                    fn fmt(&self, f: &mut ::core::fmt::Formatter<'_>) -> ::core::fmt::Result {
442                        struct HumanReadable<'a>(&'a #name);
443
444                        impl<'a> ::core::fmt::Debug for HumanReadable<'a> {
445                            fn fmt(&self, f: &mut ::core::fmt::Formatter<'_>) -> ::core::fmt::Result {
446                                if self.0.is_empty() {
447                                    ::core::write!(f, "{:#X}", self.0.0)
448                                } else {
449                                    ::bitflag_attr::parser::to_writer(self.0, f)
450                                }
451                            }
452                        }
453
454                        #[inline]
455                        pub const fn octal_width() -> usize {
456                            match #inner_ty::BITS as usize {
457                                8 => 3,
458                                16 => 6,
459                                32 => 11,
460                                64 => 22,
461                                128 => 43,
462                                // Not probable to happens, but if it does, do an approximation
463                                x =>  x/3 + x%3
464                            }
465                        }
466
467                        let name = ::core::stringify!(#name);
468
469                        f.debug_struct(name)
470                            .field("flags", &HumanReadable(self))
471                            // The width `2 +` is to account for the 0b printed before the binary number
472                            .field("bits", &::core::format_args!("{:#0width$b}", self.0, width = 2 + #inner_ty::BITS as usize))
473                            .field("octal", &::core::format_args!("{:#0width$o}", self.0, width = 2 + const { octal_width() }))
474                            .field("hex", &::core::format_args!("{:#0width$X}", self.0, width = 2 + const {#inner_ty::BITS as usize/4}))
475                            .finish()
476                    }
477                }
478            }
479        });
480
481        let default_impl = impl_flags.contains(ImplFlags::DEFAULT).then(|| {
482            if let Some(expr) = default_value {
483                quote! {
484                    #[automatically_derived]
485                    impl ::core::default::Default for #name {
486                        #[inline]
487                        fn default() -> Self {
488                            #expr
489                        }
490                    }
491                }
492            } else {
493                quote! {
494                    #[automatically_derived]
495                    impl ::core::default::Default for #name {
496                        #[inline]
497                        fn default() -> Self {
498                            Self(<#inner_ty as ::core::default::Default>::default())
499                        }
500                    }
501                }
502            }
503        });
504
505        let serialize_impl = (cfg!(feature = "serde") && impl_flags.contains(ImplFlags::SERIALIZE)).then(|| {
506            quote! {
507                #[automatically_derived]
508                impl ::serde::Serialize for #name {
509                    fn serialize<S>(&self, serializer: S) -> ::core::result::Result<S::Ok, S::Error>
510                    where
511                        S: ::serde::Serializer
512                    {
513                        struct AsDisplay<'a>(&'a #name);
514
515                        impl<'a> ::core::fmt::Display for AsDisplay<'a> {
516                            fn fmt(&self, f: &mut ::core::fmt::Formatter<'_>) -> ::core::fmt::Result {
517                                ::bitflag_attr::parser::to_writer(self.0, f)
518                            }
519                        }
520
521                        // Serialize human-readable flags as a string like `"A | B"`
522                        if serializer.is_human_readable() {
523                            serializer.collect_str(&AsDisplay(self))
524                        }
525                        // Serialize non-human-readable flags directly as the underlying bits
526                        else {
527                            self.bits().serialize(serializer)
528                        }
529                    }
530                }
531            }
532        });
533
534        let deserialize_impl = (cfg!(feature = "serde") && impl_flags.contains(ImplFlags::DESERIALIZE)).then(|| {
535            quote! {
536                #[automatically_derived]
537                impl<'de> ::serde::Deserialize<'de> for #name {
538                    fn deserialize<D>(deserializer: D) -> ::core::result::Result<Self, D::Error>
539                    where
540                        D: ::serde::Deserializer<'de>
541                    {
542                        if deserializer.is_human_readable() {
543                            struct HelperVisitor(::core::marker::PhantomData<#name>);
544
545                            impl<'de> ::serde::de::Visitor<'de> for HelperVisitor {
546                                type Value = #name;
547
548                                fn expecting(&self,  f: &mut ::core::fmt::Formatter<'_>) -> ::core::fmt::Result {
549                                    f.write_str("a string value of `|` separated flags")
550                                }
551
552                                fn visit_str<E>(self, flags: &str) -> ::core::result::Result<Self::Value, E>
553                                where
554                                    E: ::serde::de::Error,
555                                {
556                                    ::bitflag_attr::parser::from_text(flags).map_err(|e| E::custom(e))
557                                }
558                            }
559
560                            deserializer.deserialize_str(HelperVisitor(::core::marker::PhantomData))
561                        } else {
562                            let bits = #inner_ty::deserialize(deserializer)?;
563
564                            ::core::result::Result::Ok(#name::from_bits_retain(bits))
565                        }
566                    }
567                }
568            }
569        });
570
571        let arbitrary_impl = (cfg!(feature = "arbitrary") && impl_flags.contains(ImplFlags::ARBITRARY)).then(|| {
572            quote! {
573                #[automatically_derived]
574                impl<'a> ::arbitrary::Arbitrary<'a> for #name {
575                    fn arbitrary(u: &mut ::arbitrary::Unstructured<'a>) -> ::arbitrary::Result<Self> {
576                        #name::from_bits(u.arbitrary()?).ok_or(::arbitrary::Error::IncorrectFormat)
577                    }
578                }
579            }
580        });
581
582        let pod_impl =
583            (cfg!(feature = "bytemuck") && impl_flags.contains(ImplFlags::POD)).then(|| {
584                let error_str = LitStr::new(
585                    &format!(
586                    "`bitflag` error: type `{name}` not compatible with the `bytemuck::Pod` trait."
587                ),
588                    name.span(),
589                );
590                quote! {
591                    /// Extra static check for the Pod implementation
592                    #[doc(hidden)]
593                    const _: () = {
594                        if ::core::mem::size_of::<#name>() != ::core::mem::size_of::<#inner_ty>() {
595                            ::core::panic!(#error_str);
596                        }
597                    };
598                    #[automatically_derived]
599                    unsafe impl ::bytemuck::Pod for #name {}
600                }
601            });
602
603        let zeroable_impl =
604            (cfg!(feature = "bytemuck") && impl_flags.contains(ImplFlags::ZEROABLE)).then(|| {
605                quote! {
606                    #[automatically_derived]
607                    unsafe impl ::bytemuck::Zeroable for #name {}
608                }
609            });
610
611        let doc_from_iter = format!("Create a `{name}` from a iterator of flags.");
612        let generated = quote! {
613            #repr_attr
614            #(#attrs)*
615            #[derive(#(#derived_traits,)*)]
616            #vis struct #name(#inner_ty)
617            where
618                #inner_ty: ::bitflag_attr::BitsPrimitive;
619
620            #[doc(hidden)]
621            #[allow(clippy::unused_unit)]
622            const _: () = {
623                {
624                    // Original enum
625                    // This is a hack to make LSP coloring to still sees the original enum variant as a Enum variant token.
626                    #orig_enum
627                }
628                ()
629            };
630
631            #[allow(non_upper_case_globals)]
632            impl #name {
633                #(#flags)*
634            }
635
636            #[allow(non_upper_case_globals)]
637            impl #name {
638                /// Return the underlying bits value.
639                #[inline]
640                pub const fn bits(&self) -> #inner_ty {
641                    self.0
642                }
643
644                /// Converts from a `bits` value. Returning [`None`] is any unknown bits are set.
645                #[inline]
646                pub const fn from_bits(bits: #inner_ty) -> ::core::option::Option<Self> {
647                    let truncated = Self::from_bits_truncate(bits).0;
648
649                    if truncated == bits {
650                        ::core::option::Option::Some(Self(bits))
651                    } else {
652                        ::core::option::Option::None
653                    }
654                }
655
656                /// Convert from `bits` value, unsetting any unknown bits.
657                #[inline]
658                pub const fn from_bits_truncate(bits: #inner_ty) -> Self {
659                    Self(bits & Self::all().0)
660                }
661
662                /// Convert from `bits` value exactly.
663                #[inline]
664                pub const fn from_bits_retain(bits: #inner_ty) -> Self {
665                    Self(bits)
666                }
667
668                /// Convert from a flag `name`.
669                #[inline]
670                pub fn from_flag_name(name: &str) -> ::core::option::Option<Self> {
671                    match name {
672                        #(
673                            #(#all_attrs)*
674                            #all_flags_names => ::core::option::Option::Some(#all_flags),
675                        )*
676                        _ => ::core::option::Option::None
677                    }
678                }
679
680                /// Construct a flags value with all bits unset.
681                #[inline]
682                pub const fn empty() -> Self {
683                    Self(0)
684                }
685
686                /// Returns `true` if the flags value has all bits unset.
687                #[inline]
688                pub const fn is_empty(&self) -> bool {
689                    self.0 == 0
690                }
691
692                /// Returns a flags value that contains all value.
693                ///
694                /// This will include bits that do not have any flags/meaning.
695                /// Use [`all`](Self::all) if you want only the specified flags set.
696                #[inline]
697                pub const fn all_bits() -> Self {
698                    Self(!0)
699                }
700
701                /// Returns `true` if the flags value contains all value bits set.
702                ///
703                /// This will check for all bits.
704                /// Use [`is_all`](Self::is_all) if you want to check for all specified flags.
705                #[inline]
706                pub const fn is_all_bits(&self) -> bool {
707                    self.0 == !0
708                }
709
710                /// Construct a flags value with all known flags set.
711                ///
712                /// This will only set the flags specified as associated constant and the defined
713                /// extra valid bits.
714                #[inline]
715                pub const fn all() -> Self {
716                    let mut all = 0;
717
718                    #(
719                        #(#all_attrs)*{
720                            all |= #all_flags.0;
721                        }
722                    )*
723
724                    #reserved_bits
725
726                    Self(all)
727                }
728
729                /// Returns `true` if the flags value contais all known flags.
730                #[inline]
731                pub const fn is_all(&self) -> bool {
732                    Self::all().0 | self.0 == self.0
733                }
734
735                /// Construct a flags value with all known named flags set.
736                ///
737                /// This will only set the flags specified as associated constant **without** the
738                /// defined extra valid bits.
739                #[inline]
740                pub const fn all_named() -> Self {
741                    let mut all = 0;
742
743                    #(
744                        #(#all_attrs)*{
745                            all |= #all_flags.0;
746                        }
747                    )*
748
749                    Self(all)
750                }
751
752                /// Returns `true` if the flags value contais all known named flags.
753                #[inline]
754                pub const fn is_all_named(&self) -> bool {
755                    Self::all_named().0 | self.0 == self.0
756                }
757
758                /// Returns `true` if there are any unknown bits set in the flags value.
759                #[inline]
760                pub const fn contains_unknown_bits(&self) -> bool {
761                    Self::all().0 & self.0 != self.0
762                }
763
764                /// Returns `true` if there are any unnamed known bits set in the flags value.
765                #[inline]
766                pub const fn contains_unnamed_bits(&self) -> bool {
767                    Self::all_named().0 & self.0 != self.0
768                }
769
770                /// Returns a flags value with unknown bits removed from the original flags value.
771                #[inline]
772                pub const fn truncated(&self) -> Self {
773                    Self(self.0 & Self::all().0)
774                }
775
776                /// Removes unknown bits from the flags value.
777                #[inline]
778                pub #const_mut fn truncate(&mut self) {
779                    *self = Self::from_bits_truncate(self.0);
780                }
781
782                /// Returns `true` if this flags value intersects with any value in `other`.
783                ///
784                /// This is equivalent to `(self & other) != Self::empty()`
785                #[inline]
786                pub const fn intersects(&self, other: Self) -> bool {
787                    (self.0 & other.0) != Self::empty().0
788                }
789
790                /// Returns `true` if this flags value contains all values of `other`.
791                ///
792                /// This is equivalent to `(self & other) == other`
793                #[inline]
794                pub const fn contains(&self, other: Self) -> bool {
795                    (self.0 & other.0) == other.0
796                }
797
798                /// Returns the bitwise NOT of the flags value.
799                ///
800                /// This function does not truncate unused bits (bits that do not have any flags/meaning).
801                /// Use [`complement`](Self::complement) if you want that the result to be truncated in one call.
802                #[inline]
803                #[doc(alias = "complement")]
804                pub const fn not(self) -> Self {
805                    Self(!self.0)
806                }
807
808                /// Returns the bitwise AND of the flags value with `other`.
809                #[inline]
810                #[doc(alias = "intersection")]
811                pub const fn and(self, other: Self) -> Self {
812                    Self(self.0 & other.0)
813                }
814
815                /// Returns the bitwise OR of the flags value with `other`.
816                #[inline]
817                #[doc(alias = "union")]
818                pub const fn or(self, other: Self) -> Self {
819                    Self(self.0 | other.0)
820                }
821
822                /// Returns the bitwise XOR of the flags value with `other`.
823                #[inline]
824                #[doc(alias = "symmetric_difference")]
825                pub const fn xor(self, other: Self) -> Self {
826                    Self(self.0 ^ other.0)
827                }
828
829                /// Returns the intersection from this flags value with `other`.
830                #[inline]
831                #[doc(alias = "and")]
832                pub const fn intersection(self, other: Self) -> Self {
833                    self.and(other)
834                }
835
836                /// Returns the union from this flags value with `other`.
837                #[inline]
838                #[doc(alias = "or")]
839                pub const fn union(self, other: Self) -> Self {
840                    self.or(other)
841                }
842
843                /// Returns the difference from this flags value with `other`.
844                ///
845                /// In other words, returns the intersection of this flags value with the negation of `other`.
846                ///
847                /// This method is not equivalent to `self & !other` when `other` has unknown bits set.
848                /// `difference` won't truncate `other`, but the `!` operator will.
849                #[inline]
850                pub const fn difference(self, other: Self) -> Self {
851                    self.and(other.not())
852                }
853
854                /// Returns the symmetric difference from this flags value with `other`.
855                #[inline]
856                #[doc(alias = "xor")]
857                pub const fn symmetric_difference(self, other: Self) -> Self {
858                    self.xor(other)
859                }
860
861                /// Returns the complement of the flags value.
862                ///
863                /// This is very similar to the [`not`](Self::not), but truncates non used bits.
864                #[inline]
865                #[doc(alias = "not")]
866                pub const fn complement(self) -> Self {
867                    self.not().truncated()
868                }
869
870                /// Set the flags in `other` in the flags value.
871                #[inline]
872                #[doc(alias = "insert")]
873                pub #const_mut fn set(&mut self, other: Self) {
874                    self.0 = self.or(other).0
875                }
876
877                /// Unset the flags bits in `other` in the flags value.
878                #[inline]
879                #[doc(alias = "remove")]
880                pub #const_mut fn unset(&mut self, other: Self) {
881                    self.0 = self.difference(other).0
882                }
883
884                /// Toggle the flags in `other` in the flags value.
885                #[inline]
886                pub #const_mut fn toggle(&mut self, other: Self) {
887                    self.0 = self.xor(other).0
888                }
889
890                /// Resets the flags value to a empty state.
891                #[inline]
892                pub #const_mut fn clear(&mut self) {
893                    self.0 = 0
894                }
895            }
896
897            #[automatically_derived]
898            impl ::core::ops::Not for #name {
899                type Output = Self;
900
901                #[inline]
902                fn not(self) -> Self::Output {
903                    self.complement()
904                }
905            }
906
907            #[automatically_derived]
908            impl ::core::ops::BitAnd for #name {
909                type Output = Self;
910
911                #[inline]
912                fn bitand(self, rhs: Self) -> Self::Output {
913                    self.and(rhs)
914                }
915            }
916
917            #[automatically_derived]
918            impl ::core::ops::BitOr for #name {
919                type Output = Self;
920
921                #[inline]
922                fn bitor(self, rhs: Self) -> Self::Output {
923                    self.or(rhs)
924                }
925            }
926
927            #[automatically_derived]
928            impl ::core::ops::BitXor for #name {
929                type Output = Self;
930
931                #[inline]
932                fn bitxor(self, rhs: Self) -> Self::Output {
933                    self.xor(rhs)
934                }
935            }
936
937            #[automatically_derived]
938            impl ::core::ops::BitAndAssign for #name {
939                #[inline]
940                fn bitand_assign(&mut self, rhs: Self) {
941                    *self = self.and(rhs)
942                }
943            }
944
945            #[automatically_derived]
946            impl ::core::ops::BitOrAssign for #name {
947                #[inline]
948                fn bitor_assign(&mut self, rhs: Self) {
949                    *self = self.or(rhs)
950                }
951            }
952
953            #[automatically_derived]
954            impl ::core::ops::BitXorAssign for #name {
955                #[inline]
956                fn bitxor_assign(&mut self, rhs: Self) {
957                    *self = self.xor(rhs)
958                }
959            }
960
961            #[automatically_derived]
962            impl ::core::ops::Sub for #name {
963                type Output = Self;
964
965                /// The intersection of a source flag with the complement of a target flags value
966                #[inline]
967                fn sub(self, rhs: Self) -> Self::Output {
968                    self.difference(rhs)
969                }
970            }
971
972            #[automatically_derived]
973            impl ::core::ops::SubAssign for #name {
974                /// The intersection of a source flag with the complement of a target flags value
975                #[inline]
976                fn sub_assign(&mut self, rhs: Self) {
977                    self.unset(rhs)
978                }
979            }
980
981            #[automatically_derived]
982            impl ::core::convert::From<#inner_ty> for #name {
983                #[inline]
984                fn from(val: #inner_ty) -> Self {
985                    Self::from_bits_truncate(val)
986                }
987            }
988
989            #[automatically_derived]
990            impl ::core::convert::From<#name> for #inner_ty {
991                #[inline]
992                fn from(val: #name) -> Self {
993                    val.0
994                }
995            }
996
997            #[automatically_derived]
998            impl ::core::fmt::Binary for #name {
999                #[inline]
1000                fn fmt(&self, f: &mut ::core::fmt::Formatter<'_>) -> ::core::fmt::Result {
1001                    ::core::fmt::Binary::fmt(&self.0, f)
1002                }
1003            }
1004
1005            #[automatically_derived]
1006            impl ::core::fmt::LowerHex for #name {
1007                #[inline]
1008                fn fmt(&self, f: &mut ::core::fmt::Formatter<'_>) -> ::core::fmt::Result {
1009                    ::core::fmt::LowerHex::fmt(&self.0, f)
1010                }
1011            }
1012
1013            #[automatically_derived]
1014            impl ::core::fmt::UpperHex for #name {
1015                #[inline]
1016                fn fmt(&self, f: &mut ::core::fmt::Formatter<'_>) -> ::core::fmt::Result {
1017                    ::core::fmt::UpperHex::fmt(&self.0, f)
1018                }
1019            }
1020
1021            #[automatically_derived]
1022            impl ::core::fmt::Octal for #name {
1023                #[inline]
1024                fn fmt(&self, f: &mut ::core::fmt::Formatter<'_>) -> ::core::fmt::Result {
1025                    ::core::fmt::Octal::fmt(&self.0, f)
1026                }
1027            }
1028
1029            #[automatically_derived]
1030            impl ::core::str::FromStr for #name {
1031                type Err = ::bitflag_attr::parser::ParseError;
1032
1033                #[inline]
1034                fn from_str(input: &str) -> ::core::result::Result<Self, Self::Err> {
1035                    ::bitflag_attr::parser::from_text(input)
1036                }
1037            }
1038
1039            #debug_impl
1040
1041            #default_impl
1042
1043            #[automatically_derived]
1044            impl ::bitflag_attr::Flags for #name {
1045                const NAMED_FLAGS: &'static [(&'static str, #name)] = &[#(
1046                    #(#all_attrs)*
1047                    (#all_flags_names , #all_flags) ,
1048                )*];
1049
1050                const RESERVED_BITS: #inner_ty = #reserved_bits_value;
1051
1052                type Bits = #inner_ty;
1053
1054                #[inline]
1055                fn bits(&self) -> Self::Bits {
1056                    self.0
1057                }
1058
1059                #[inline]
1060                fn from_bits_retain(bits: Self::Bits) -> Self {
1061                    Self(bits)
1062                }
1063            }
1064
1065            impl #name {
1066                const NAMED_FLAGS: &'static [(&'static str, #name)] = &[#(
1067                    #(#all_attrs)*
1068                    (#all_flags_names , #all_flags) ,
1069                )*];
1070
1071                /// Yield a set of contained flags values.
1072                ///
1073                /// Each yielded flags value will correspond to a defined named flag. Any unknown bits
1074                /// will be yielded together as a final flags value.
1075                #[inline]
1076                pub const fn iter(&self) -> ::bitflag_attr::iter::Iter<Self> {
1077                    ::bitflag_attr::iter::Iter::__private_const_new(Self::NAMED_FLAGS, *self, *self)
1078                }
1079
1080                /// Yield a set of contained named flags values.
1081                ///
1082                /// This method is like [`iter`](#method.iter), except only yields bits in contained named flags.
1083                /// Any unknown bits, or bits not corresponding to a contained flag will not be yielded.
1084                #[inline]
1085                pub const fn iter_names(&self) -> ::bitflag_attr::iter::IterNames<Self> {
1086                    ::bitflag_attr::iter::IterNames::__private_const_new(Self::NAMED_FLAGS, *self, *self)
1087                }
1088            }
1089
1090            #[automatically_derived]
1091            impl ::core::iter::Extend<#name> for #name {
1092                /// Set all flags of `iter` to self
1093                fn extend<T: ::core::iter::IntoIterator<Item = Self>>(&mut self, iter: T) {
1094                    for item in iter {
1095                        self.set(item);
1096                    }
1097                }
1098            }
1099
1100            #[automatically_derived]
1101            impl ::core::iter::FromIterator<#name> for #name {
1102                #[doc = #doc_from_iter]
1103                fn from_iter<T: ::core::iter::IntoIterator<Item = Self>>(iter: T) -> Self {
1104                    use ::core::iter::Extend;
1105
1106                    let mut res = Self::empty();
1107                    res.extend(iter);
1108                    res
1109                }
1110            }
1111
1112            #[automatically_derived]
1113            impl ::core::iter::IntoIterator for #name {
1114                type Item = Self;
1115                type IntoIter = ::bitflag_attr::iter::Iter<Self>;
1116
1117                #[inline]
1118                fn into_iter(self) -> Self::IntoIter {
1119                    self.iter()
1120                }
1121            }
1122
1123            #[automatically_derived]
1124            impl ::core::iter::IntoIterator for &#name {
1125                type Item = #name;
1126                type IntoIter = ::bitflag_attr::iter::Iter<#name>;
1127
1128                #[inline]
1129                fn into_iter(self) -> Self::IntoIter {
1130                    self.iter()
1131                }
1132            }
1133
1134            #serialize_impl
1135            #deserialize_impl
1136            #arbitrary_impl
1137            #pod_impl
1138            #zeroable_impl
1139        };
1140
1141        tokens.append_all(generated);
1142    }
1143}
1144
1145pub struct Args {
1146    ty: Path,
1147}
1148
1149impl Parse for Args {
1150    fn parse(input: syn::parse::ParseStream) -> syn::Result<Self> {
1151        let ty: Path = input.parse().map_err(|err| {
1152            Error::new(err.span(), "unexpected token: expected a `{integer}` type")
1153        })?;
1154
1155        if !cfg!(feature = "custom-types") {
1156            let path_s = ty.to_token_stream().to_string().replace(" ", "");
1157            if !VALID_TYPES.contains(&path_s.as_str()) {
1158                return Err(Error::new_spanned(ty, "type must be a `{integer}` type"));
1159            }
1160        }
1161
1162        Ok(Args { ty })
1163    }
1164}
1165
1166struct ExtraValidBits(Expr);
1167
1168impl ExtraValidBits {
1169    fn from_meta(meta: &Meta) -> syn::Result<Self> {
1170        match meta {
1171            Meta::NameValue(m) => {
1172                if !m.path.is_ident("reserved_bits") {
1173                    return Err(Error::new(
1174                        m.span(),
1175                        "not a valid `reserved_bits` attribute",
1176                    ));
1177                }
1178
1179                Ok(Self(m.value.clone()))
1180            }
1181            _ => Err(Error::new(
1182                meta.span(),
1183                "reserved_bits must follow the syntax `reserved_bits = <expr>`",
1184            )),
1185        }
1186    }
1187}
1188
1189impl Parse for ExtraValidBits {
1190    fn parse(input: syn::parse::ParseStream) -> syn::Result<Self> {
1191        let meta: MetaNameValue = input.parse()?;
1192
1193        if !meta.path.is_ident("reserved_bits") {
1194            return Err(Error::new(meta.span(), "not a `reserved_bits` attribute"));
1195        }
1196
1197        Ok(Self(meta.value))
1198    }
1199}
1200
1201struct ReprAttr {
1202    path: Path,
1203    _paren_token: Paren,
1204    kinds: Punctuated<ReprKind, syn::Token![,]>,
1205}
1206
1207impl ReprAttr {
1208    pub fn kinds(&self) -> (Option<ReprKind>, Option<ReprKind>) {
1209        (self.kinds.get(0).cloned(), self.kinds.get(1).cloned())
1210    }
1211}
1212
1213impl Parse for ReprAttr {
1214    fn parse(input: syn::parse::ParseStream) -> syn::Result<Self> {
1215        let path: Path = input.parse()?;
1216
1217        let content;
1218        let _paren_token = syn::parenthesized!(content in input);
1219
1220        if !path.is_ident("repr") {
1221            return Err(Error::new(path.span(), "not a `#[repr]` attribute"));
1222        }
1223
1224        let mut kinds = Punctuated::new();
1225
1226        while !content.is_empty() {
1227            let first: ReprKind = content.parse()?;
1228            kinds.push_value(first);
1229            if content.is_empty() {
1230                break;
1231            }
1232            let punct = content.parse()?;
1233            kinds.push_punct(punct);
1234        }
1235
1236        Ok(Self {
1237            path,
1238            _paren_token,
1239            kinds,
1240        })
1241    }
1242}
1243
1244impl ToTokens for ReprAttr {
1245    fn to_tokens(&self, tokens: &mut TokenStream) {
1246        let Self { path, kinds, .. } = self;
1247        tokens.append_all(quote! {#[#path(#kinds)]});
1248    }
1249}
1250
1251/// Supported repr
1252#[derive(Clone)]
1253enum ReprKind {
1254    C(Path),
1255    Rust(Path),
1256    Transparent(Path),
1257    Integer(Path),
1258    Packed(Path, Option<LitInt>),
1259    Align(Path, LitInt),
1260}
1261
1262impl Parse for ReprKind {
1263    fn parse(input: syn::parse::ParseStream) -> syn::Result<Self> {
1264        let meta: Meta = input.parse()?;
1265
1266        match meta {
1267            Meta::Path(path) => {
1268                let text = path
1269                    .get_ident()
1270                    .map(|p| p.to_string())
1271                    .unwrap_or("".to_string());
1272
1273                match text.as_str() {
1274                    "C" => Ok(Self::C(path)),
1275                    "Rust" => Ok(Self::Rust(path)),
1276                    "transparent" => Ok(Self::Transparent(path)),
1277                    "packed" => Ok(Self::Packed(path, None)),
1278                    x if VALID_REPR_INT.contains(&x) => Ok(Self::Integer(path)),
1279                    _ => Err(Error::new(path.span(), "invalid `repr` kind")),
1280                }
1281            }
1282            Meta::List(list) => {
1283                let text = list
1284                    .path
1285                    .get_ident()
1286                    .map(|p| p.to_string())
1287                    .unwrap_or("".to_string());
1288
1289                match text.as_str() {
1290                    "packed" => {
1291                        let lit = syn::parse2(list.tokens)?;
1292                        Ok(Self::Packed(list.path, Some(lit)))
1293                    }
1294                    "align" => {
1295                        let lit = syn::parse2(list.tokens)?;
1296                        Ok(Self::Align(list.path, lit))
1297                    }
1298                    _ => Err(Error::new(list.span(), "invalid `repr` kind")),
1299                }
1300            }
1301            _ => Err(Error::new(meta.span(), "invalid `repr` kind")),
1302        }
1303    }
1304}
1305
1306impl ToTokens for ReprKind {
1307    fn to_tokens(&self, tokens: &mut TokenStream) {
1308        match self {
1309            ReprKind::C(path)
1310            | ReprKind::Rust(path)
1311            | ReprKind::Transparent(path)
1312            | ReprKind::Integer(path)
1313            | ReprKind::Packed(path, None) => tokens.append_all(quote!(#path)),
1314
1315            ReprKind::Packed(path, Some(lit_int)) | ReprKind::Align(path, lit_int) => {
1316                tokens.append_all(quote!(#path(#lit_int)))
1317            }
1318        }
1319    }
1320}
1321
1322const VALID_REPR_INT: &[&str] = &[
1323    "i8", "u8", "i16", "u16", "i32", "u32", "i64", "u64", "i128", "u128",
1324];
1325
1326/// Flags of found derives that is handled specially by the macro.
1327#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord)]
1328struct ImplFlags(u8);
1329
1330impl ImplFlags {
1331    pub const DEBUG: Self = Self(1);
1332    pub const DEFAULT: Self = Self(1 << 1);
1333    pub const SERIALIZE: Self = Self(1 << 2);
1334    pub const DESERIALIZE: Self = Self(1 << 3);
1335    pub const ARBITRARY: Self = Self(1 << 4);
1336    pub const ZEROABLE: Self = Self(1 << 5);
1337    pub const POD: Self = Self(1 << 6);
1338
1339    pub const fn empty() -> Self {
1340        Self(0)
1341    }
1342
1343    pub const fn contains(&self, other: Self) -> bool {
1344        (self.0 & other.0) == other.0
1345    }
1346}
1347
1348impl core::ops::Not for ImplFlags {
1349    type Output = Self;
1350
1351    #[inline]
1352    fn not(self) -> Self::Output {
1353        Self(!self.0)
1354    }
1355}
1356
1357impl core::ops::BitAnd for ImplFlags {
1358    type Output = Self;
1359
1360    #[inline]
1361    fn bitand(self, rhs: Self) -> Self::Output {
1362        Self(self.0 & rhs.0)
1363    }
1364}
1365
1366impl core::ops::BitOr for ImplFlags {
1367    type Output = Self;
1368
1369    #[inline]
1370    fn bitor(self, rhs: Self) -> Self::Output {
1371        Self(self.0 | rhs.0)
1372    }
1373}
1374
1375impl core::ops::BitXor for ImplFlags {
1376    type Output = Self;
1377
1378    #[inline]
1379    fn bitxor(self, rhs: Self) -> Self::Output {
1380        Self(self.0 ^ rhs.0)
1381    }
1382}
1383
1384impl core::ops::BitAndAssign for ImplFlags {
1385    #[inline]
1386    fn bitand_assign(&mut self, rhs: Self) {
1387        *self = Self(self.0 & rhs.0)
1388    }
1389}
1390
1391impl core::ops::BitOrAssign for ImplFlags {
1392    #[inline]
1393    fn bitor_assign(&mut self, rhs: Self) {
1394        *self = Self(self.0 | rhs.0)
1395    }
1396}
1397
1398impl core::ops::BitXorAssign for ImplFlags {
1399    #[inline]
1400    fn bitxor_assign(&mut self, rhs: Self) {
1401        *self = Self(self.0 ^ rhs.0)
1402    }
1403}
1404
1405/// Recursively check if a expression can be simplified to a simple wrap of `Self(<expr>)`.
1406///
1407/// Logic behind this:
1408/// A literal and a path where it is not fancy and is not one of the variants names are always able to be simplified.
1409///
1410/// A unary expression can be simplified if it's underlying expression is also able to be simplified.
1411///
1412/// A binary expression can be simplified if both expression that compose it also are able to be simplified.
1413///
1414/// A parenthesized expression can be simplified if it's underlying expression is also able to be simplified.
1415///
1416/// A "as" cast can be simplified if it's underlying expression is also able to be simplified.
1417///
1418/// To-Do:
1419/// In theory, something like `FlagTypeName::FlagKind.bits()` could be simplified, but demands a more complicated analysis of method call expression
1420fn can_simplify(expr: &syn::Expr, variants: &[Ident]) -> bool {
1421    match expr {
1422        syn::Expr::Lit(_) => true,
1423        syn::Expr::Path(expr_path) if is_simple_path(expr_path, variants) => true,
1424        syn::Expr::Unary(expr_unary) => can_simplify(&expr_unary.expr, variants),
1425        syn::Expr::Binary(expr_binary) => {
1426            can_simplify(&expr_binary.left, variants) && can_simplify(&expr_binary.right, variants)
1427        }
1428        syn::Expr::Paren(expr_paren) => can_simplify(&expr_paren.expr, variants),
1429        syn::Expr::Cast(expr_cast) => can_simplify(&expr_cast.expr, variants),
1430        _ => false,
1431    }
1432}
1433
1434fn is_simple_path(expr: &syn::ExprPath, variants: &[Ident]) -> bool {
1435    if expr.qself.is_some() {
1436        return false;
1437    }
1438
1439    // simplest path
1440    if let Some(ident) = expr.path.get_ident() {
1441        // if the ident is in variants, it is not a simple path
1442        if !variants.contains(ident) {
1443            return true;
1444        }
1445    }
1446
1447    // compound path
1448    // All real usages I had it could be simplified, after simplification, even cases where type
1449    // don't match, the resulting native error is very good.
1450    if expr.path.segments.iter().count() >= 2 {
1451        return true;
1452    }
1453
1454    false
1455}
1456
1457static VALID_TYPES: &[&str] = &[
1458    "i8",
1459    "u8",
1460    "i16",
1461    "u16",
1462    "i32",
1463    "u32",
1464    "i64",
1465    "u64",
1466    "i128",
1467    "u128",
1468    "isize",
1469    "usize",
1470    "c_char",
1471    "c_schar",
1472    "c_uchar",
1473    "c_short",
1474    "c_ushort",
1475    "c_int",
1476    "c_uint",
1477    "c_long",
1478    "c_ulong",
1479    "c_longlong",
1480    "c_ulonglong",
1481    "ffi::c_char",
1482    "ffi::c_schar",
1483    "ffi::c_uchar",
1484    "ffi::c_short",
1485    "ffi::c_ushort",
1486    "ffi::c_int",
1487    "ffi::c_uint",
1488    "ffi::c_long",
1489    "ffi::c_ulong",
1490    "ffi::c_longlong",
1491    "ffi::c_ulonglong",
1492    "core::ffi::c_char",
1493    "core::ffi::c_schar",
1494    "core::ffi::c_uchar",
1495    "core::ffi::c_short",
1496    "core::ffi::c_ushort",
1497    "core::ffi::c_int",
1498    "core::ffi::c_uint",
1499    "core::ffi::c_long",
1500    "core::ffi::c_ulong",
1501    "core::ffi::c_longlong",
1502    "core::ffi::c_ulonglong",
1503    "::core::ffi::c_char",
1504    "::core::ffi::c_schar",
1505    "::core::ffi::c_uchar",
1506    "::core::ffi::c_short",
1507    "::core::ffi::c_ushort",
1508    "::core::ffi::c_int",
1509    "::core::ffi::c_uint",
1510    "::core::ffi::c_long",
1511    "::core::ffi::c_ulong",
1512    "::core::ffi::c_longlong",
1513    "::core::ffi::c_ulonglong",
1514    "libc::c_char",
1515    "libc::c_schar",
1516    "libc::c_uchar",
1517    "libc::c_short",
1518    "libc::c_ushort",
1519    "libc::c_int",
1520    "libc::c_uint",
1521    "libc::c_long",
1522    "libc::c_ulong",
1523    "libc::c_longlong",
1524    "libc::c_ulonglong",
1525    "::libc::c_char",
1526    "::libc::c_schar",
1527    "::libc::c_uchar",
1528    "::libc::c_short",
1529    "::libc::c_ushort",
1530    "::libc::c_int",
1531    "::libc::c_uint",
1532    "::libc::c_long",
1533    "::libc::c_ulong",
1534    "::libc::c_longlong",
1535    "::libc::c_ulonglong",
1536    "blkcnt_t",
1537    "blksize_t",
1538    "clock_t",
1539    "clockid_t",
1540    "dev_t",
1541    "fsblkcnt_t",
1542    "fsfilcnt_t",
1543    "gid_t",
1544    "id_t",
1545    "ino_t",
1546    "key_t",
1547    "mode_t",
1548    "nlink_t",
1549    "off_t",
1550    "pid_t",
1551    "size_t",
1552    "ssize_t",
1553    "suseconds_t",
1554    "time_t",
1555    "uid_t",
1556    "libc::blkcnt_t",
1557    "libc::blksize_t",
1558    "libc::clock_t",
1559    "libc::clockid_t",
1560    "libc::dev_t",
1561    "libc::fsblkcnt_t",
1562    "libc::fsfilcnt_t",
1563    "libc::gid_t",
1564    "libc::id_t",
1565    "libc::ino_t",
1566    "libc::key_t",
1567    "libc::mode_t",
1568    "libc::nlink_t",
1569    "libc::off_t",
1570    "libc::pid_t",
1571    "libc::size_t",
1572    "libc::ssize_t",
1573    "libc::suseconds_t",
1574    "libc::time_t",
1575    "libc::uid_t",
1576    "::libc::blkcnt_t",
1577    "::libc::blksize_t",
1578    "::libc::clock_t",
1579    "::libc::clockid_t",
1580    "::libc::dev_t",
1581    "::libc::fsblkcnt_t",
1582    "::libc::fsfilcnt_t",
1583    "::libc::gid_t",
1584    "::libc::id_t",
1585    "::libc::ino_t",
1586    "::libc::key_t",
1587    "::libc::mode_t",
1588    "::libc::nlink_t",
1589    "::libc::off_t",
1590    "::libc::pid_t",
1591    "::libc::size_t",
1592    "::libc::ssize_t",
1593    "::libc::suseconds_t",
1594    "::libc::time_t",
1595    "::libc::uid_t",
1596];