• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 mod dyngen;
2 pub(crate) mod error;
3 
4 mod helpers;
5 mod impl_debug;
6 mod impl_partialeq;
7 mod postprocessing;
8 mod serialize;
9 pub(crate) mod struct_layout;
10 
11 #[cfg(test)]
12 #[allow(warnings)]
13 pub(crate) mod bitfield_unit;
14 #[cfg(all(test, target_endian = "little"))]
15 mod bitfield_unit_tests;
16 
17 use self::dyngen::DynamicItems;
18 use self::helpers::attributes;
19 use self::struct_layout::StructLayoutTracker;
20 
21 use super::BindgenOptions;
22 
23 use crate::callbacks::{DeriveInfo, FieldInfo, TypeKind as DeriveTypeKind};
24 use crate::codegen::error::Error;
25 use crate::ir::analysis::{HasVtable, Sizedness};
26 use crate::ir::annotations::{
27     Annotations, FieldAccessorKind, FieldVisibilityKind,
28 };
29 use crate::ir::comp::{
30     Bitfield, BitfieldUnit, CompInfo, CompKind, Field, FieldData, FieldMethods,
31     Method, MethodKind,
32 };
33 use crate::ir::context::{BindgenContext, ItemId};
34 use crate::ir::derive::{
35     CanDerive, CanDeriveCopy, CanDeriveDebug, CanDeriveDefault, CanDeriveEq,
36     CanDeriveHash, CanDeriveOrd, CanDerivePartialEq, CanDerivePartialOrd,
37 };
38 use crate::ir::dot;
39 use crate::ir::enum_ty::{Enum, EnumVariant, EnumVariantValue};
40 use crate::ir::function::{
41     ClangAbi, Function, FunctionKind, FunctionSig, Linkage,
42 };
43 use crate::ir::int::IntKind;
44 use crate::ir::item::{IsOpaque, Item, ItemCanonicalName, ItemCanonicalPath};
45 use crate::ir::item_kind::ItemKind;
46 use crate::ir::layout::Layout;
47 use crate::ir::module::Module;
48 use crate::ir::objc::{ObjCInterface, ObjCMethod};
49 use crate::ir::template::{
50     AsTemplateParam, TemplateInstantiation, TemplateParameters,
51 };
52 use crate::ir::ty::{Type, TypeKind};
53 use crate::ir::var::Var;
54 
55 use proc_macro2::{Ident, Span};
56 use quote::{ToTokens, TokenStreamExt};
57 
58 use crate::{Entry, HashMap, HashSet};
59 use std::borrow::Cow;
60 use std::cell::Cell;
61 use std::collections::VecDeque;
62 use std::ffi::CStr;
63 use std::fmt::{self, Write};
64 use std::ops;
65 use std::str::{self, FromStr};
66 
67 #[derive(Debug, Clone, PartialEq, Eq, Hash)]
68 pub enum CodegenError {
69     Serialize { msg: String, loc: String },
70     Io(String),
71 }
72 
73 impl From<std::io::Error> for CodegenError {
from(err: std::io::Error) -> Self74     fn from(err: std::io::Error) -> Self {
75         Self::Io(err.to_string())
76     }
77 }
78 
79 impl fmt::Display for CodegenError {
fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result80     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
81         match self {
82             Self::Serialize { msg, loc } => {
83                 write!(f, "serialization error at {}: {}", loc, msg)
84             }
85             Self::Io(err) => err.fmt(f),
86         }
87     }
88 }
89 
90 // Name of type defined in constified enum module
91 pub(crate) static CONSTIFIED_ENUM_MODULE_REPR_NAME: &str = "Type";
92 
top_level_path( ctx: &BindgenContext, item: &Item, ) -> Vec<proc_macro2::TokenStream>93 fn top_level_path(
94     ctx: &BindgenContext,
95     item: &Item,
96 ) -> Vec<proc_macro2::TokenStream> {
97     let mut path = vec![quote! { self }];
98 
99     if ctx.options().enable_cxx_namespaces {
100         for _ in 0..item.codegen_depth(ctx) {
101             path.push(quote! { super });
102         }
103     }
104 
105     path
106 }
107 
root_import( ctx: &BindgenContext, module: &Item, ) -> proc_macro2::TokenStream108 fn root_import(
109     ctx: &BindgenContext,
110     module: &Item,
111 ) -> proc_macro2::TokenStream {
112     assert!(ctx.options().enable_cxx_namespaces, "Somebody messed it up");
113     assert!(module.is_module());
114 
115     let mut path = top_level_path(ctx, module);
116 
117     let root = ctx.root_module().canonical_name(ctx);
118     let root_ident = ctx.rust_ident(root);
119     path.push(quote! { #root_ident });
120 
121     let mut tokens = quote! {};
122     tokens.append_separated(path, quote!(::));
123 
124     quote! {
125         #[allow(unused_imports)]
126         use #tokens ;
127     }
128 }
129 
130 bitflags! {
131     struct DerivableTraits: u16 {
132         const DEBUG       = 1 << 0;
133         const DEFAULT     = 1 << 1;
134         const COPY        = 1 << 2;
135         const CLONE       = 1 << 3;
136         const HASH        = 1 << 4;
137         const PARTIAL_ORD = 1 << 5;
138         const ORD         = 1 << 6;
139         const PARTIAL_EQ  = 1 << 7;
140         const EQ          = 1 << 8;
141     }
142 }
143 
derives_of_item( item: &Item, ctx: &BindgenContext, packed: bool, ) -> DerivableTraits144 fn derives_of_item(
145     item: &Item,
146     ctx: &BindgenContext,
147     packed: bool,
148 ) -> DerivableTraits {
149     let mut derivable_traits = DerivableTraits::empty();
150 
151     let all_template_params = item.all_template_params(ctx);
152 
153     if item.can_derive_copy(ctx) && !item.annotations().disallow_copy() {
154         derivable_traits |= DerivableTraits::COPY;
155 
156         if ctx.options().rust_features().builtin_clone_impls ||
157             !all_template_params.is_empty()
158         {
159             // FIXME: This requires extra logic if you have a big array in a
160             // templated struct. The reason for this is that the magic:
161             //     fn clone(&self) -> Self { *self }
162             // doesn't work for templates.
163             //
164             // It's not hard to fix though.
165             derivable_traits |= DerivableTraits::CLONE;
166         }
167     } else if packed {
168         // If the struct or union is packed, deriving from Copy is required for
169         // deriving from any other trait.
170         return derivable_traits;
171     }
172 
173     if item.can_derive_debug(ctx) && !item.annotations().disallow_debug() {
174         derivable_traits |= DerivableTraits::DEBUG;
175     }
176 
177     if item.can_derive_default(ctx) && !item.annotations().disallow_default() {
178         derivable_traits |= DerivableTraits::DEFAULT;
179     }
180 
181     if item.can_derive_hash(ctx) {
182         derivable_traits |= DerivableTraits::HASH;
183     }
184 
185     if item.can_derive_partialord(ctx) {
186         derivable_traits |= DerivableTraits::PARTIAL_ORD;
187     }
188 
189     if item.can_derive_ord(ctx) {
190         derivable_traits |= DerivableTraits::ORD;
191     }
192 
193     if item.can_derive_partialeq(ctx) {
194         derivable_traits |= DerivableTraits::PARTIAL_EQ;
195     }
196 
197     if item.can_derive_eq(ctx) {
198         derivable_traits |= DerivableTraits::EQ;
199     }
200 
201     derivable_traits
202 }
203 
204 impl From<DerivableTraits> for Vec<&'static str> {
from(derivable_traits: DerivableTraits) -> Vec<&'static str>205     fn from(derivable_traits: DerivableTraits) -> Vec<&'static str> {
206         [
207             (DerivableTraits::DEBUG, "Debug"),
208             (DerivableTraits::DEFAULT, "Default"),
209             (DerivableTraits::COPY, "Copy"),
210             (DerivableTraits::CLONE, "Clone"),
211             (DerivableTraits::HASH, "Hash"),
212             (DerivableTraits::PARTIAL_ORD, "PartialOrd"),
213             (DerivableTraits::ORD, "Ord"),
214             (DerivableTraits::PARTIAL_EQ, "PartialEq"),
215             (DerivableTraits::EQ, "Eq"),
216         ]
217         .iter()
218         .filter_map(|&(flag, derive)| {
219             Some(derive).filter(|_| derivable_traits.contains(flag))
220         })
221         .collect()
222     }
223 }
224 
225 struct WrapAsVariadic {
226     new_name: String,
227     idx_of_va_list_arg: usize,
228 }
229 
230 struct CodegenResult<'a> {
231     items: Vec<proc_macro2::TokenStream>,
232     dynamic_items: DynamicItems,
233 
234     /// A monotonic counter used to add stable unique ID's to stuff that doesn't
235     /// need to be referenced by anything.
236     codegen_id: &'a Cell<usize>,
237 
238     /// Whether a bindgen union has been generated at least once.
239     saw_bindgen_union: bool,
240 
241     /// Whether an incomplete array has been generated at least once.
242     saw_incomplete_array: bool,
243 
244     /// Whether Objective C types have been seen at least once.
245     saw_objc: bool,
246 
247     /// Whether Apple block types have been seen at least once.
248     saw_block: bool,
249 
250     /// Whether a bitfield allocation unit has been seen at least once.
251     saw_bitfield_unit: bool,
252 
253     items_seen: HashSet<ItemId>,
254     /// The set of generated function/var names, needed because in C/C++ is
255     /// legal to do something like:
256     ///
257     /// ```c++
258     /// extern "C" {
259     ///   void foo();
260     ///   extern int bar;
261     /// }
262     ///
263     /// extern "C" {
264     ///   void foo();
265     ///   extern int bar;
266     /// }
267     /// ```
268     ///
269     /// Being these two different declarations.
270     functions_seen: HashSet<String>,
271     vars_seen: HashSet<String>,
272 
273     /// Used for making bindings to overloaded functions. Maps from a canonical
274     /// function name to the number of overloads we have already codegen'd for
275     /// that name. This lets us give each overload a unique suffix.
276     overload_counters: HashMap<String, u32>,
277 
278     /// List of items to serialize. With optionally the argument for the wrap as
279     /// variadic transformation to be applied.
280     items_to_serialize: Vec<(ItemId, Option<WrapAsVariadic>)>,
281 }
282 
283 impl<'a> CodegenResult<'a> {
new(codegen_id: &'a Cell<usize>) -> Self284     fn new(codegen_id: &'a Cell<usize>) -> Self {
285         CodegenResult {
286             items: vec![],
287             dynamic_items: DynamicItems::new(),
288             saw_bindgen_union: false,
289             saw_incomplete_array: false,
290             saw_objc: false,
291             saw_block: false,
292             saw_bitfield_unit: false,
293             codegen_id,
294             items_seen: Default::default(),
295             functions_seen: Default::default(),
296             vars_seen: Default::default(),
297             overload_counters: Default::default(),
298             items_to_serialize: Default::default(),
299         }
300     }
301 
dynamic_items(&mut self) -> &mut DynamicItems302     fn dynamic_items(&mut self) -> &mut DynamicItems {
303         &mut self.dynamic_items
304     }
305 
saw_bindgen_union(&mut self)306     fn saw_bindgen_union(&mut self) {
307         self.saw_bindgen_union = true;
308     }
309 
saw_incomplete_array(&mut self)310     fn saw_incomplete_array(&mut self) {
311         self.saw_incomplete_array = true;
312     }
313 
saw_objc(&mut self)314     fn saw_objc(&mut self) {
315         self.saw_objc = true;
316     }
317 
saw_block(&mut self)318     fn saw_block(&mut self) {
319         self.saw_block = true;
320     }
321 
saw_bitfield_unit(&mut self)322     fn saw_bitfield_unit(&mut self) {
323         self.saw_bitfield_unit = true;
324     }
325 
seen<Id: Into<ItemId>>(&self, item: Id) -> bool326     fn seen<Id: Into<ItemId>>(&self, item: Id) -> bool {
327         self.items_seen.contains(&item.into())
328     }
329 
set_seen<Id: Into<ItemId>>(&mut self, item: Id)330     fn set_seen<Id: Into<ItemId>>(&mut self, item: Id) {
331         self.items_seen.insert(item.into());
332     }
333 
seen_function(&self, name: &str) -> bool334     fn seen_function(&self, name: &str) -> bool {
335         self.functions_seen.contains(name)
336     }
337 
saw_function(&mut self, name: &str)338     fn saw_function(&mut self, name: &str) {
339         self.functions_seen.insert(name.into());
340     }
341 
342     /// Get the overload number for the given function name. Increments the
343     /// counter internally so the next time we ask for the overload for this
344     /// name, we get the incremented value, and so on.
overload_number(&mut self, name: &str) -> u32345     fn overload_number(&mut self, name: &str) -> u32 {
346         let counter = self.overload_counters.entry(name.into()).or_insert(0);
347         let number = *counter;
348         *counter += 1;
349         number
350     }
351 
seen_var(&self, name: &str) -> bool352     fn seen_var(&self, name: &str) -> bool {
353         self.vars_seen.contains(name)
354     }
355 
saw_var(&mut self, name: &str)356     fn saw_var(&mut self, name: &str) {
357         self.vars_seen.insert(name.into());
358     }
359 
inner<F>(&mut self, cb: F) -> Vec<proc_macro2::TokenStream> where F: FnOnce(&mut Self),360     fn inner<F>(&mut self, cb: F) -> Vec<proc_macro2::TokenStream>
361     where
362         F: FnOnce(&mut Self),
363     {
364         let mut new = Self::new(self.codegen_id);
365 
366         cb(&mut new);
367 
368         self.saw_incomplete_array |= new.saw_incomplete_array;
369         self.saw_objc |= new.saw_objc;
370         self.saw_block |= new.saw_block;
371         self.saw_bitfield_unit |= new.saw_bitfield_unit;
372         self.saw_bindgen_union |= new.saw_bindgen_union;
373 
374         new.items
375     }
376 }
377 
378 impl<'a> ops::Deref for CodegenResult<'a> {
379     type Target = Vec<proc_macro2::TokenStream>;
380 
deref(&self) -> &Self::Target381     fn deref(&self) -> &Self::Target {
382         &self.items
383     }
384 }
385 
386 impl<'a> ops::DerefMut for CodegenResult<'a> {
deref_mut(&mut self) -> &mut Self::Target387     fn deref_mut(&mut self) -> &mut Self::Target {
388         &mut self.items
389     }
390 }
391 
392 /// A trait to convert a rust type into a pointer, optionally const, to the same
393 /// type.
394 trait ToPtr {
to_ptr(self, is_const: bool) -> syn::Type395     fn to_ptr(self, is_const: bool) -> syn::Type;
396 }
397 
398 impl ToPtr for syn::Type {
to_ptr(self, is_const: bool) -> syn::Type399     fn to_ptr(self, is_const: bool) -> syn::Type {
400         if is_const {
401             syn::parse_quote! { *const #self }
402         } else {
403             syn::parse_quote! { *mut #self }
404         }
405     }
406 }
407 
408 /// An extension trait for `syn::Type` that lets us append any implicit
409 /// template parameters that exist for some type, if necessary.
410 trait WithImplicitTemplateParams {
with_implicit_template_params( self, ctx: &BindgenContext, item: &Item, ) -> Self411     fn with_implicit_template_params(
412         self,
413         ctx: &BindgenContext,
414         item: &Item,
415     ) -> Self;
416 }
417 
418 impl WithImplicitTemplateParams for syn::Type {
with_implicit_template_params( self, ctx: &BindgenContext, item: &Item, ) -> Self419     fn with_implicit_template_params(
420         self,
421         ctx: &BindgenContext,
422         item: &Item,
423     ) -> Self {
424         let item = item.id().into_resolver().through_type_refs().resolve(ctx);
425 
426         let params = match *item.expect_type().kind() {
427             TypeKind::UnresolvedTypeRef(..) => {
428                 unreachable!("already resolved unresolved type refs")
429             }
430             TypeKind::ResolvedTypeRef(..) => {
431                 unreachable!("we resolved item through type refs")
432             }
433             // None of these types ever have implicit template parameters.
434             TypeKind::Void |
435             TypeKind::NullPtr |
436             TypeKind::Pointer(..) |
437             TypeKind::Reference(..) |
438             TypeKind::Int(..) |
439             TypeKind::Float(..) |
440             TypeKind::Complex(..) |
441             TypeKind::Array(..) |
442             TypeKind::TypeParam |
443             TypeKind::Opaque |
444             TypeKind::Function(..) |
445             TypeKind::Enum(..) |
446             TypeKind::ObjCId |
447             TypeKind::ObjCSel |
448             TypeKind::TemplateInstantiation(..) => None,
449             _ => {
450                 let params = item.used_template_params(ctx);
451                 if params.is_empty() {
452                     None
453                 } else {
454                     Some(params.into_iter().map(|p| {
455                         p.try_to_rust_ty(ctx, &()).expect(
456                             "template params cannot fail to be a rust type",
457                         )
458                     }))
459                 }
460             }
461         };
462 
463         if let Some(params) = params {
464             syn::parse_quote! { #self<#(#params),*> }
465         } else {
466             self
467         }
468     }
469 }
470 
471 trait CodeGenerator {
472     /// Extra information from the caller.
473     type Extra;
474 
475     /// Extra information returned to the caller.
476     type Return;
477 
codegen( &self, ctx: &BindgenContext, result: &mut CodegenResult<'_>, extra: &Self::Extra, ) -> Self::Return478     fn codegen(
479         &self,
480         ctx: &BindgenContext,
481         result: &mut CodegenResult<'_>,
482         extra: &Self::Extra,
483     ) -> Self::Return;
484 }
485 
486 impl Item {
process_before_codegen( &self, ctx: &BindgenContext, result: &mut CodegenResult, ) -> bool487     fn process_before_codegen(
488         &self,
489         ctx: &BindgenContext,
490         result: &mut CodegenResult,
491     ) -> bool {
492         if !self.is_enabled_for_codegen(ctx) {
493             return false;
494         }
495 
496         if self.is_blocklisted(ctx) || result.seen(self.id()) {
497             debug!(
498                 "<Item as CodeGenerator>::process_before_codegen: Ignoring hidden or seen: \
499                  self = {:?}",
500                 self
501             );
502             return false;
503         }
504 
505         if !ctx.codegen_items().contains(&self.id()) {
506             // TODO(emilio, #453): Figure out what to do when this happens
507             // legitimately, we could track the opaque stuff and disable the
508             // assertion there I guess.
509             warn!("Found non-allowlisted item in code generation: {:?}", self);
510         }
511 
512         result.set_seen(self.id());
513         true
514     }
515 }
516 
517 impl CodeGenerator for Item {
518     type Extra = ();
519     type Return = ();
520 
codegen( &self, ctx: &BindgenContext, result: &mut CodegenResult<'_>, _extra: &(), )521     fn codegen(
522         &self,
523         ctx: &BindgenContext,
524         result: &mut CodegenResult<'_>,
525         _extra: &(),
526     ) {
527         debug!("<Item as CodeGenerator>::codegen: self = {:?}", self);
528         if !self.process_before_codegen(ctx, result) {
529             return;
530         }
531 
532         match *self.kind() {
533             ItemKind::Module(ref module) => {
534                 module.codegen(ctx, result, self);
535             }
536             ItemKind::Function(ref fun) => {
537                 fun.codegen(ctx, result, self);
538             }
539             ItemKind::Var(ref var) => {
540                 var.codegen(ctx, result, self);
541             }
542             ItemKind::Type(ref ty) => {
543                 ty.codegen(ctx, result, self);
544             }
545         }
546     }
547 }
548 
549 impl CodeGenerator for Module {
550     type Extra = Item;
551     type Return = ();
552 
codegen( &self, ctx: &BindgenContext, result: &mut CodegenResult<'_>, item: &Item, )553     fn codegen(
554         &self,
555         ctx: &BindgenContext,
556         result: &mut CodegenResult<'_>,
557         item: &Item,
558     ) {
559         debug!("<Module as CodeGenerator>::codegen: item = {:?}", item);
560 
561         let codegen_self = |result: &mut CodegenResult,
562                             found_any: &mut bool| {
563             for child in self.children() {
564                 if ctx.codegen_items().contains(child) {
565                     *found_any = true;
566                     ctx.resolve_item(*child).codegen(ctx, result, &());
567                 }
568             }
569 
570             if item.id() == ctx.root_module() {
571                 if result.saw_block {
572                     utils::prepend_block_header(ctx, &mut *result);
573                 }
574                 if result.saw_bindgen_union {
575                     utils::prepend_union_types(ctx, &mut *result);
576                 }
577                 if result.saw_incomplete_array {
578                     utils::prepend_incomplete_array_types(ctx, &mut *result);
579                 }
580                 if ctx.need_bindgen_float16_type() {
581                     utils::prepend_float16_type(&mut *result);
582                 }
583                 if ctx.need_bindgen_complex_type() {
584                     utils::prepend_complex_type(&mut *result);
585                 }
586                 if result.saw_objc {
587                     utils::prepend_objc_header(ctx, &mut *result);
588                 }
589                 if result.saw_bitfield_unit {
590                     utils::prepend_bitfield_unit_type(ctx, &mut *result);
591                 }
592             }
593         };
594 
595         if !ctx.options().enable_cxx_namespaces ||
596             (self.is_inline() &&
597                 !ctx.options().conservative_inline_namespaces)
598         {
599             codegen_self(result, &mut false);
600             return;
601         }
602 
603         let mut found_any = false;
604         let inner_items = result.inner(|result| {
605             result.push(root_import(ctx, item));
606 
607             let path = item
608                 .namespace_aware_canonical_path(ctx)
609                 .join("::")
610                 .into_boxed_str();
611             if let Some(raw_lines) = ctx.options().module_lines.get(&path) {
612                 for raw_line in raw_lines {
613                     found_any = true;
614                     result.push(
615                         proc_macro2::TokenStream::from_str(raw_line).unwrap(),
616                     );
617                 }
618             }
619 
620             codegen_self(result, &mut found_any);
621         });
622 
623         // Don't bother creating an empty module.
624         if !found_any {
625             return;
626         }
627 
628         let name = item.canonical_name(ctx);
629         let ident = ctx.rust_ident(name);
630         result.push(if item.id() == ctx.root_module() {
631             quote! {
632                 #[allow(non_snake_case, non_camel_case_types, non_upper_case_globals)]
633                 pub mod #ident {
634                     #( #inner_items )*
635                 }
636             }
637         } else {
638             quote! {
639                 pub mod #ident {
640                     #( #inner_items )*
641                 }
642             }
643         });
644     }
645 }
646 
647 impl CodeGenerator for Var {
648     type Extra = Item;
649     type Return = ();
650 
codegen( &self, ctx: &BindgenContext, result: &mut CodegenResult<'_>, item: &Item, )651     fn codegen(
652         &self,
653         ctx: &BindgenContext,
654         result: &mut CodegenResult<'_>,
655         item: &Item,
656     ) {
657         use crate::ir::var::VarType;
658         debug!("<Var as CodeGenerator>::codegen: item = {:?}", item);
659         debug_assert!(item.is_enabled_for_codegen(ctx));
660 
661         let canonical_name = item.canonical_name(ctx);
662 
663         if result.seen_var(&canonical_name) {
664             return;
665         }
666         result.saw_var(&canonical_name);
667 
668         let canonical_ident = ctx.rust_ident(&canonical_name);
669 
670         // We can't generate bindings to static variables of templates. The
671         // number of actual variables for a single declaration are open ended
672         // and we don't know what instantiations do or don't exist.
673         if !item.all_template_params(ctx).is_empty() {
674             return;
675         }
676 
677         let mut attrs = vec![];
678         if let Some(comment) = item.comment(ctx) {
679             attrs.push(attributes::doc(comment));
680         }
681 
682         let var_ty = self.ty();
683         let ty = var_ty.to_rust_ty_or_opaque(ctx, &());
684 
685         if let Some(val) = self.val() {
686             match *val {
687                 VarType::Bool(val) => {
688                     result.push(quote! {
689                         #(#attrs)*
690                         pub const #canonical_ident : #ty = #val ;
691                     });
692                 }
693                 VarType::Int(val) => {
694                     let int_kind = var_ty
695                         .into_resolver()
696                         .through_type_aliases()
697                         .through_type_refs()
698                         .resolve(ctx)
699                         .expect_type()
700                         .as_integer()
701                         .unwrap();
702                     let val = if int_kind.is_signed() {
703                         helpers::ast_ty::int_expr(val)
704                     } else {
705                         helpers::ast_ty::uint_expr(val as _)
706                     };
707                     result.push(quote! {
708                         #(#attrs)*
709                         pub const #canonical_ident : #ty = #val ;
710                     });
711                 }
712                 VarType::String(ref bytes) => {
713                     let prefix = ctx.trait_prefix();
714 
715                     let options = ctx.options();
716                     let rust_features = options.rust_features;
717 
718                     let mut cstr_bytes = bytes.clone();
719                     cstr_bytes.push(0);
720                     let len = proc_macro2::Literal::usize_unsuffixed(
721                         cstr_bytes.len(),
722                     );
723 
724                     // TODO: Here we ignore the type we just made up, probably
725                     // we should refactor how the variable type and ty ID work.
726                     let array_ty = quote! { [u8; #len] };
727                     let cstr_ty = quote! { ::#prefix::ffi::CStr };
728 
729                     let bytes = proc_macro2::Literal::byte_string(&cstr_bytes);
730 
731                     if options.generate_cstr &&
732                         rust_features.const_cstr &&
733                         CStr::from_bytes_with_nul(&cstr_bytes).is_ok()
734                     {
735                         result.push(quote! {
736                             #(#attrs)*
737                             #[allow(unsafe_code)]
738                             pub const #canonical_ident: &#cstr_ty = unsafe {
739                                 #cstr_ty::from_bytes_with_nul_unchecked(#bytes)
740                             };
741                         });
742                     } else {
743                         let lifetime = if rust_features.static_lifetime_elision
744                         {
745                             None
746                         } else {
747                             Some(quote! { 'static })
748                         }
749                         .into_iter();
750 
751                         result.push(quote! {
752                             #(#attrs)*
753                             pub const #canonical_ident: &#(#lifetime )*#array_ty = #bytes ;
754                         });
755                     }
756                 }
757                 VarType::Float(f) => {
758                     if let Ok(expr) = helpers::ast_ty::float_expr(ctx, f) {
759                         result.push(quote! {
760                             #(#attrs)*
761                             pub const #canonical_ident : #ty = #expr ;
762                         });
763                     }
764                 }
765                 VarType::Char(c) => {
766                     result.push(quote! {
767                         #(#attrs)*
768                         pub const #canonical_ident : #ty = #c ;
769                     });
770                 }
771             }
772         } else {
773             // If necessary, apply a `#[link_name]` attribute
774             if let Some(link_name) = self.link_name() {
775                 attrs.push(attributes::link_name::<false>(link_name));
776             } else {
777                 let link_name =
778                     self.mangled_name().unwrap_or_else(|| self.name());
779                 if !utils::names_will_be_identical_after_mangling(
780                     &canonical_name,
781                     link_name,
782                     None,
783                 ) {
784                     attrs.push(attributes::link_name::<false>(link_name));
785                 }
786             }
787 
788             let maybe_mut = if self.is_const() {
789                 quote! {}
790             } else {
791                 quote! { mut }
792             };
793 
794             let tokens = quote!(
795                 extern "C" {
796                     #(#attrs)*
797                     pub static #maybe_mut #canonical_ident: #ty;
798                 }
799             );
800 
801             if ctx.options().dynamic_library_name.is_some() {
802                 result.dynamic_items().push_var(
803                     canonical_ident,
804                     self.ty()
805                         .to_rust_ty_or_opaque(ctx, &())
806                         .into_token_stream(),
807                     ctx.options().dynamic_link_require_all,
808                 );
809             } else {
810                 result.push(tokens);
811             }
812         }
813     }
814 }
815 
816 impl CodeGenerator for Type {
817     type Extra = Item;
818     type Return = ();
819 
codegen( &self, ctx: &BindgenContext, result: &mut CodegenResult<'_>, item: &Item, )820     fn codegen(
821         &self,
822         ctx: &BindgenContext,
823         result: &mut CodegenResult<'_>,
824         item: &Item,
825     ) {
826         debug!("<Type as CodeGenerator>::codegen: item = {:?}", item);
827         debug_assert!(item.is_enabled_for_codegen(ctx));
828 
829         match *self.kind() {
830             TypeKind::Void |
831             TypeKind::NullPtr |
832             TypeKind::Int(..) |
833             TypeKind::Float(..) |
834             TypeKind::Complex(..) |
835             TypeKind::Array(..) |
836             TypeKind::Vector(..) |
837             TypeKind::Pointer(..) |
838             TypeKind::Reference(..) |
839             TypeKind::Function(..) |
840             TypeKind::ResolvedTypeRef(..) |
841             TypeKind::Opaque |
842             TypeKind::TypeParam => {
843                 // These items don't need code generation, they only need to be
844                 // converted to rust types in fields, arguments, and such.
845                 // NOTE(emilio): If you add to this list, make sure to also add
846                 // it to BindgenContext::compute_allowlisted_and_codegen_items.
847             }
848             TypeKind::TemplateInstantiation(ref inst) => {
849                 inst.codegen(ctx, result, item)
850             }
851             TypeKind::BlockPointer(inner) => {
852                 if !ctx.options().generate_block {
853                     return;
854                 }
855 
856                 let inner_item =
857                     inner.into_resolver().through_type_refs().resolve(ctx);
858                 let name = item.canonical_name(ctx);
859 
860                 let inner_rust_type = {
861                     if let TypeKind::Function(fnsig) =
862                         inner_item.kind().expect_type().kind()
863                     {
864                         utils::fnsig_block(ctx, fnsig)
865                     } else {
866                         panic!("invalid block typedef: {:?}", inner_item)
867                     }
868                 };
869 
870                 let rust_name = ctx.rust_ident(name);
871 
872                 let mut tokens = if let Some(comment) = item.comment(ctx) {
873                     attributes::doc(comment)
874                 } else {
875                     quote! {}
876                 };
877 
878                 tokens.append_all(quote! {
879                     pub type #rust_name = #inner_rust_type ;
880                 });
881 
882                 result.push(tokens);
883                 result.saw_block();
884             }
885             TypeKind::Comp(ref ci) => ci.codegen(ctx, result, item),
886             TypeKind::TemplateAlias(inner, _) | TypeKind::Alias(inner) => {
887                 let inner_item =
888                     inner.into_resolver().through_type_refs().resolve(ctx);
889                 let name = item.canonical_name(ctx);
890                 let path = item.canonical_path(ctx);
891 
892                 {
893                     let through_type_aliases = inner
894                         .into_resolver()
895                         .through_type_refs()
896                         .through_type_aliases()
897                         .resolve(ctx);
898 
899                     // Try to catch the common pattern:
900                     //
901                     // typedef struct foo { ... } foo;
902                     //
903                     // here, and also other more complex cases like #946.
904                     if through_type_aliases.canonical_path(ctx) == path {
905                         return;
906                     }
907                 }
908 
909                 // If this is a known named type, disallow generating anything
910                 // for it too. If size_t -> usize conversions are enabled, we
911                 // need to check that these conversions are permissible, but
912                 // nothing needs to be generated, still.
913                 let spelling = self.name().expect("Unnamed alias?");
914                 if utils::type_from_named(ctx, spelling).is_some() {
915                     if let "size_t" | "ssize_t" = spelling {
916                         let layout = inner_item
917                             .kind()
918                             .expect_type()
919                             .layout(ctx)
920                             .expect("No layout?");
921                         assert_eq!(
922                             layout.size,
923                             ctx.target_pointer_size(),
924                             "Target platform requires `--no-size_t-is-usize`. The size of `{}` ({}) does not match the target pointer size ({})",
925                             spelling,
926                             layout.size,
927                             ctx.target_pointer_size(),
928                             );
929                         assert_eq!(
930                             layout.align,
931                             ctx.target_pointer_size(),
932                             "Target platform requires `--no-size_t-is-usize`. The alignment of `{}` ({}) does not match the target pointer size ({})",
933                             spelling,
934                             layout.align,
935                             ctx.target_pointer_size(),
936                         );
937                     }
938                     return;
939                 }
940 
941                 let mut outer_params = item.used_template_params(ctx);
942 
943                 let is_opaque = item.is_opaque(ctx, &());
944                 let inner_rust_type = if is_opaque {
945                     outer_params = vec![];
946                     self.to_opaque(ctx, item)
947                 } else {
948                     // Its possible that we have better layout information than
949                     // the inner type does, so fall back to an opaque blob based
950                     // on our layout if converting the inner item fails.
951                     inner_item
952                         .try_to_rust_ty_or_opaque(ctx, &())
953                         .unwrap_or_else(|_| self.to_opaque(ctx, item))
954                         .with_implicit_template_params(ctx, inner_item)
955                 };
956 
957                 {
958                     // FIXME(emilio): This is a workaround to avoid generating
959                     // incorrect type aliases because of types that we haven't
960                     // been able to resolve (because, eg, they depend on a
961                     // template parameter).
962                     //
963                     // It's kind of a shame not generating them even when they
964                     // could be referenced, but we already do the same for items
965                     // with invalid template parameters, and at least this way
966                     // they can be replaced, instead of generating plain invalid
967                     // code.
968                     let inner_canon_type =
969                         inner_item.expect_type().canonical_type(ctx);
970                     if inner_canon_type.is_invalid_type_param() {
971                         warn!(
972                             "Item contained invalid named type, skipping: \
973                              {:?}, {:?}",
974                             item, inner_item
975                         );
976                         return;
977                     }
978                 }
979 
980                 let rust_name = ctx.rust_ident(&name);
981 
982                 let mut tokens = if let Some(comment) = item.comment(ctx) {
983                     attributes::doc(comment)
984                 } else {
985                     quote! {}
986                 };
987 
988                 let alias_style = if ctx.options().type_alias.matches(&name) {
989                     AliasVariation::TypeAlias
990                 } else if ctx.options().new_type_alias.matches(&name) {
991                     AliasVariation::NewType
992                 } else if ctx.options().new_type_alias_deref.matches(&name) {
993                     AliasVariation::NewTypeDeref
994                 } else {
995                     ctx.options().default_alias_style
996                 };
997 
998                 // We prefer using `pub use` over `pub type` because of:
999                 // https://github.com/rust-lang/rust/issues/26264
1000                 if matches!(inner_rust_type, syn::Type::Path(_)) &&
1001                     outer_params.is_empty() &&
1002                     !is_opaque &&
1003                     alias_style == AliasVariation::TypeAlias &&
1004                     inner_item.expect_type().canonical_type(ctx).is_enum()
1005                 {
1006                     tokens.append_all(quote! {
1007                         pub use
1008                     });
1009                     let path = top_level_path(ctx, item);
1010                     tokens.append_separated(path, quote!(::));
1011                     tokens.append_all(quote! {
1012                         :: #inner_rust_type  as #rust_name ;
1013                     });
1014                     result.push(tokens);
1015                     return;
1016                 }
1017 
1018                 tokens.append_all(match alias_style {
1019                     AliasVariation::TypeAlias => quote! {
1020                         pub type #rust_name
1021                     },
1022                     AliasVariation::NewType | AliasVariation::NewTypeDeref => {
1023                         assert!(
1024                             ctx.options().rust_features().repr_transparent,
1025                             "repr_transparent feature is required to use {:?}",
1026                             alias_style
1027                         );
1028 
1029                         let mut attributes =
1030                             vec![attributes::repr("transparent")];
1031                         let packed = false; // Types can't be packed in Rust.
1032                         let derivable_traits =
1033                             derives_of_item(item, ctx, packed);
1034                         let mut derives: Vec<_> = derivable_traits.into();
1035                         // The custom derives callback may return a list of derive attributes;
1036                         // add them to the end of the list.
1037                         let custom_derives =
1038                             ctx.options().all_callbacks(|cb| {
1039                                 cb.add_derives(&DeriveInfo {
1040                                     name: &name,
1041                                     kind: DeriveTypeKind::Struct,
1042                                 })
1043                             });
1044                         // In most cases this will be a no-op, since custom_derives will be empty.
1045                         derives
1046                             .extend(custom_derives.iter().map(|s| s.as_str()));
1047                         attributes.push(attributes::derives(&derives));
1048 
1049                         quote! {
1050                             #( #attributes )*
1051                             pub struct #rust_name
1052                         }
1053                     }
1054                 });
1055 
1056                 let params: Vec<_> = outer_params
1057                     .into_iter()
1058                     .filter_map(|p| p.as_template_param(ctx, &()))
1059                     .collect();
1060                 if params
1061                     .iter()
1062                     .any(|p| ctx.resolve_type(*p).is_invalid_type_param())
1063                 {
1064                     warn!(
1065                         "Item contained invalid template \
1066                          parameter: {:?}",
1067                         item
1068                     );
1069                     return;
1070                 }
1071                 let params: Vec<_> = params
1072                     .iter()
1073                     .map(|p| {
1074                         p.try_to_rust_ty(ctx, &()).expect(
1075                             "type parameters can always convert to rust ty OK",
1076                         )
1077                     })
1078                     .collect();
1079 
1080                 if !params.is_empty() {
1081                     tokens.append_all(quote! {
1082                         < #( #params ),* >
1083                     });
1084                 }
1085 
1086                 let access_spec =
1087                     access_specifier(ctx.options().default_visibility);
1088                 tokens.append_all(match alias_style {
1089                     AliasVariation::TypeAlias => quote! {
1090                         = #inner_rust_type ;
1091                     },
1092                     AliasVariation::NewType | AliasVariation::NewTypeDeref => {
1093                         quote! {
1094                             (#access_spec #inner_rust_type) ;
1095                         }
1096                     }
1097                 });
1098 
1099                 if alias_style == AliasVariation::NewTypeDeref {
1100                     let prefix = ctx.trait_prefix();
1101                     tokens.append_all(quote! {
1102                         impl ::#prefix::ops::Deref for #rust_name {
1103                             type Target = #inner_rust_type;
1104                             #[inline]
1105                             fn deref(&self) -> &Self::Target {
1106                                 &self.0
1107                             }
1108                         }
1109                         impl ::#prefix::ops::DerefMut for #rust_name {
1110                             #[inline]
1111                             fn deref_mut(&mut self) -> &mut Self::Target {
1112                                 &mut self.0
1113                             }
1114                         }
1115                     });
1116                 }
1117 
1118                 result.push(tokens);
1119             }
1120             TypeKind::Enum(ref ei) => ei.codegen(ctx, result, item),
1121             TypeKind::ObjCId | TypeKind::ObjCSel => {
1122                 result.saw_objc();
1123             }
1124             TypeKind::ObjCInterface(ref interface) => {
1125                 interface.codegen(ctx, result, item)
1126             }
1127             ref u @ TypeKind::UnresolvedTypeRef(..) => {
1128                 unreachable!("Should have been resolved after parsing {:?}!", u)
1129             }
1130         }
1131     }
1132 }
1133 
1134 struct Vtable<'a> {
1135     item_id: ItemId,
1136     /// A reference to the originating compound object.
1137     #[allow(dead_code)]
1138     comp_info: &'a CompInfo,
1139 }
1140 
1141 impl<'a> Vtable<'a> {
new(item_id: ItemId, comp_info: &'a CompInfo) -> Self1142     fn new(item_id: ItemId, comp_info: &'a CompInfo) -> Self {
1143         Vtable { item_id, comp_info }
1144     }
1145 }
1146 
1147 impl<'a> CodeGenerator for Vtable<'a> {
1148     type Extra = Item;
1149     type Return = ();
1150 
codegen( &self, ctx: &BindgenContext, result: &mut CodegenResult<'_>, item: &Item, )1151     fn codegen(
1152         &self,
1153         ctx: &BindgenContext,
1154         result: &mut CodegenResult<'_>,
1155         item: &Item,
1156     ) {
1157         assert_eq!(item.id(), self.item_id);
1158         debug_assert!(item.is_enabled_for_codegen(ctx));
1159         let name = ctx.rust_ident(self.canonical_name(ctx));
1160 
1161         // For now, we will only generate vtables for classes that:
1162         // - do not inherit from others (compilers merge VTable from primary parent class).
1163         // - do not contain a virtual destructor (requires ordering; platforms generate different vtables).
1164         if ctx.options().vtable_generation &&
1165             self.comp_info.base_members().is_empty() &&
1166             self.comp_info.destructor().is_none()
1167         {
1168             let class_ident = ctx.rust_ident(self.item_id.canonical_name(ctx));
1169 
1170             let methods = self
1171                 .comp_info
1172                 .methods()
1173                 .iter()
1174                 .filter_map(|m| {
1175                     if !m.is_virtual() {
1176                         return None;
1177                     }
1178 
1179                     let function_item = ctx.resolve_item(m.signature());
1180                     let function = function_item.expect_function();
1181                     let signature_item = ctx.resolve_item(function.signature());
1182                     let signature = match signature_item.expect_type().kind() {
1183                         TypeKind::Function(ref sig) => sig,
1184                         _ => panic!("Function signature type mismatch"),
1185                     };
1186 
1187                     // FIXME: Is there a canonical name without the class prepended?
1188                     let function_name = function_item.canonical_name(ctx);
1189 
1190                     // FIXME: Need to account for overloading with times_seen (separately from regular function path).
1191                     let function_name = ctx.rust_ident(function_name);
1192                     let mut args = utils::fnsig_arguments(ctx, signature);
1193                     let ret = utils::fnsig_return_ty(ctx, signature);
1194 
1195                     args[0] = if m.is_const() {
1196                         quote! { this: *const #class_ident }
1197                     } else {
1198                         quote! { this: *mut #class_ident }
1199                     };
1200 
1201                     Some(quote! {
1202                         pub #function_name : unsafe extern "C" fn( #( #args ),* ) #ret
1203                     })
1204                 })
1205                 .collect::<Vec<_>>();
1206 
1207             result.push(quote! {
1208                 #[repr(C)]
1209                 pub struct #name {
1210                     #( #methods ),*
1211                 }
1212             })
1213         } else {
1214             // For the cases we don't support, simply generate an empty struct.
1215             let void = helpers::ast_ty::c_void(ctx);
1216 
1217             result.push(quote! {
1218                 #[repr(C)]
1219                 pub struct #name ( #void );
1220             });
1221         }
1222     }
1223 }
1224 
1225 impl<'a> ItemCanonicalName for Vtable<'a> {
canonical_name(&self, ctx: &BindgenContext) -> String1226     fn canonical_name(&self, ctx: &BindgenContext) -> String {
1227         format!("{}__bindgen_vtable", self.item_id.canonical_name(ctx))
1228     }
1229 }
1230 
1231 impl<'a> TryToRustTy for Vtable<'a> {
1232     type Extra = ();
1233 
try_to_rust_ty( &self, ctx: &BindgenContext, _: &(), ) -> error::Result<syn::Type>1234     fn try_to_rust_ty(
1235         &self,
1236         ctx: &BindgenContext,
1237         _: &(),
1238     ) -> error::Result<syn::Type> {
1239         let name = ctx.rust_ident(self.canonical_name(ctx));
1240         Ok(syn::parse_quote! { #name })
1241     }
1242 }
1243 
1244 impl CodeGenerator for TemplateInstantiation {
1245     type Extra = Item;
1246     type Return = ();
1247 
codegen( &self, ctx: &BindgenContext, result: &mut CodegenResult<'_>, item: &Item, )1248     fn codegen(
1249         &self,
1250         ctx: &BindgenContext,
1251         result: &mut CodegenResult<'_>,
1252         item: &Item,
1253     ) {
1254         debug_assert!(item.is_enabled_for_codegen(ctx));
1255 
1256         // Although uses of instantiations don't need code generation, and are
1257         // just converted to rust types in fields, vars, etc, we take this
1258         // opportunity to generate tests for their layout here. If the
1259         // instantiation is opaque, then its presumably because we don't
1260         // properly understand it (maybe because of specializations), and so we
1261         // shouldn't emit layout tests either.
1262         if !ctx.options().layout_tests || self.is_opaque(ctx, item) {
1263             return;
1264         }
1265 
1266         // For consistency with other layout tests, gate this on offset_of.
1267         let compile_time = ctx.options().rust_features().offset_of;
1268 
1269         // If there are any unbound type parameters, then we can't generate a
1270         // layout test because we aren't dealing with a concrete type with a
1271         // concrete size and alignment.
1272         if ctx.uses_any_template_parameters(item.id()) {
1273             return;
1274         }
1275 
1276         let layout = item.kind().expect_type().layout(ctx);
1277 
1278         if let Some(layout) = layout {
1279             let size = layout.size;
1280             let align = layout.align;
1281 
1282             let name = item.full_disambiguated_name(ctx);
1283             let fn_name = if compile_time {
1284                 None
1285             } else {
1286                 let mut fn_name =
1287                     format!("__bindgen_test_layout_{name}_instantiation");
1288                 let times_seen = result.overload_number(&fn_name);
1289                 if times_seen > 0 {
1290                     write!(&mut fn_name, "_{times_seen}").unwrap();
1291                 }
1292                 Some(ctx.rust_ident_raw(fn_name))
1293             };
1294 
1295             let prefix = ctx.trait_prefix();
1296             let ident = item.to_rust_ty_or_opaque(ctx, &());
1297             let size_of_expr = quote! {
1298                 ::#prefix::mem::size_of::<#ident>()
1299             };
1300             let align_of_expr = quote! {
1301                 ::#prefix::mem::align_of::<#ident>()
1302             };
1303             let size_of_err =
1304                 format!("Size of template specialization: {name}");
1305             let align_of_err =
1306                 format!("Align of template specialization: {name}");
1307 
1308             if compile_time {
1309                 // In an ideal world this would be assert_eq!, but that is not
1310                 // supported in const fn due to the need for string formatting.
1311                 // If #size_of_expr > #size, this will index OOB, and if
1312                 // #size_of_expr < #size, the subtraction will overflow, both
1313                 // of which print enough information to see what has gone wrong.
1314                 result.push(quote! {
1315                     #[allow(clippy::unnecessary_operation, clippy::identity_op)]
1316                     const _: () = {
1317                         [#size_of_err][#size_of_expr - #size];
1318                         [#align_of_err][#align_of_expr - #align];
1319                     };
1320                 });
1321             } else {
1322                 result.push(quote! {
1323                     #[test]
1324                     fn #fn_name() {
1325                         assert_eq!(#size_of_expr, #size, #size_of_err);
1326                         assert_eq!(#align_of_expr, #align, #align_of_err);
1327                     }
1328                 });
1329             }
1330         }
1331     }
1332 }
1333 
1334 /// Trait for implementing the code generation of a struct or union field.
1335 trait FieldCodegen<'a> {
1336     type Extra;
1337 
1338     #[allow(clippy::too_many_arguments)]
codegen<F, M>( &self, ctx: &BindgenContext, visibility_kind: FieldVisibilityKind, accessor_kind: FieldAccessorKind, parent: &CompInfo, parent_item: &Item, last_field: bool, result: &mut CodegenResult, struct_layout: &mut StructLayoutTracker, fields: &mut F, methods: &mut M, extra: Self::Extra, ) where F: Extend<proc_macro2::TokenStream>, M: Extend<proc_macro2::TokenStream>1339     fn codegen<F, M>(
1340         &self,
1341         ctx: &BindgenContext,
1342         visibility_kind: FieldVisibilityKind,
1343         accessor_kind: FieldAccessorKind,
1344         parent: &CompInfo,
1345         parent_item: &Item,
1346         last_field: bool,
1347         result: &mut CodegenResult,
1348         struct_layout: &mut StructLayoutTracker,
1349         fields: &mut F,
1350         methods: &mut M,
1351         extra: Self::Extra,
1352     ) where
1353         F: Extend<proc_macro2::TokenStream>,
1354         M: Extend<proc_macro2::TokenStream>;
1355 }
1356 
1357 impl<'a> FieldCodegen<'a> for Field {
1358     type Extra = ();
1359 
codegen<F, M>( &self, ctx: &BindgenContext, visibility_kind: FieldVisibilityKind, accessor_kind: FieldAccessorKind, parent: &CompInfo, parent_item: &Item, last_field: bool, result: &mut CodegenResult, struct_layout: &mut StructLayoutTracker, fields: &mut F, methods: &mut M, _: (), ) where F: Extend<proc_macro2::TokenStream>, M: Extend<proc_macro2::TokenStream>,1360     fn codegen<F, M>(
1361         &self,
1362         ctx: &BindgenContext,
1363         visibility_kind: FieldVisibilityKind,
1364         accessor_kind: FieldAccessorKind,
1365         parent: &CompInfo,
1366         parent_item: &Item,
1367         last_field: bool,
1368         result: &mut CodegenResult,
1369         struct_layout: &mut StructLayoutTracker,
1370         fields: &mut F,
1371         methods: &mut M,
1372         _: (),
1373     ) where
1374         F: Extend<proc_macro2::TokenStream>,
1375         M: Extend<proc_macro2::TokenStream>,
1376     {
1377         match *self {
1378             Field::DataMember(ref data) => {
1379                 data.codegen(
1380                     ctx,
1381                     visibility_kind,
1382                     accessor_kind,
1383                     parent,
1384                     parent_item,
1385                     last_field,
1386                     result,
1387                     struct_layout,
1388                     fields,
1389                     methods,
1390                     (),
1391                 );
1392             }
1393             Field::Bitfields(ref unit) => {
1394                 unit.codegen(
1395                     ctx,
1396                     visibility_kind,
1397                     accessor_kind,
1398                     parent,
1399                     parent_item,
1400                     last_field,
1401                     result,
1402                     struct_layout,
1403                     fields,
1404                     methods,
1405                     (),
1406                 );
1407             }
1408         }
1409     }
1410 }
1411 
wrap_union_field_if_needed( ctx: &BindgenContext, struct_layout: &StructLayoutTracker, ty: syn::Type, result: &mut CodegenResult, ) -> syn::Type1412 fn wrap_union_field_if_needed(
1413     ctx: &BindgenContext,
1414     struct_layout: &StructLayoutTracker,
1415     ty: syn::Type,
1416     result: &mut CodegenResult,
1417 ) -> syn::Type {
1418     if struct_layout.is_rust_union() {
1419         if struct_layout.can_copy_union_fields() {
1420             ty
1421         } else {
1422             let prefix = ctx.trait_prefix();
1423             syn::parse_quote! { ::#prefix::mem::ManuallyDrop<#ty> }
1424         }
1425     } else {
1426         result.saw_bindgen_union();
1427         if ctx.options().enable_cxx_namespaces {
1428             syn::parse_quote! { root::__BindgenUnionField<#ty> }
1429         } else {
1430             syn::parse_quote! { __BindgenUnionField<#ty> }
1431         }
1432     }
1433 }
1434 
1435 impl<'a> FieldCodegen<'a> for FieldData {
1436     type Extra = ();
1437 
codegen<F, M>( &self, ctx: &BindgenContext, parent_visibility_kind: FieldVisibilityKind, accessor_kind: FieldAccessorKind, parent: &CompInfo, parent_item: &Item, last_field: bool, result: &mut CodegenResult, struct_layout: &mut StructLayoutTracker, fields: &mut F, methods: &mut M, _: (), ) where F: Extend<proc_macro2::TokenStream>, M: Extend<proc_macro2::TokenStream>,1438     fn codegen<F, M>(
1439         &self,
1440         ctx: &BindgenContext,
1441         parent_visibility_kind: FieldVisibilityKind,
1442         accessor_kind: FieldAccessorKind,
1443         parent: &CompInfo,
1444         parent_item: &Item,
1445         last_field: bool,
1446         result: &mut CodegenResult,
1447         struct_layout: &mut StructLayoutTracker,
1448         fields: &mut F,
1449         methods: &mut M,
1450         _: (),
1451     ) where
1452         F: Extend<proc_macro2::TokenStream>,
1453         M: Extend<proc_macro2::TokenStream>,
1454     {
1455         // Bitfields are handled by `FieldCodegen` implementations for
1456         // `BitfieldUnit` and `Bitfield`.
1457         assert!(self.bitfield_width().is_none());
1458 
1459         let field_item =
1460             self.ty().into_resolver().through_type_refs().resolve(ctx);
1461         let field_ty = field_item.expect_type();
1462         let ty = self
1463             .ty()
1464             .to_rust_ty_or_opaque(ctx, &())
1465             .with_implicit_template_params(ctx, field_item);
1466 
1467         // NB: If supported, we use proper `union` types.
1468         let ty = if parent.is_union() {
1469             wrap_union_field_if_needed(ctx, struct_layout, ty, result)
1470         } else if let Some(item) = field_ty.is_incomplete_array(ctx) {
1471             // Only FAM if its the last field
1472             if ctx.options().flexarray_dst && last_field {
1473                 struct_layout.saw_flexible_array();
1474                 syn::parse_quote! { FAM }
1475             } else {
1476                 result.saw_incomplete_array();
1477 
1478                 let inner = item.to_rust_ty_or_opaque(ctx, &());
1479 
1480                 if ctx.options().enable_cxx_namespaces {
1481                     syn::parse_quote! { root::__IncompleteArrayField<#inner> }
1482                 } else {
1483                     syn::parse_quote! { __IncompleteArrayField<#inner> }
1484                 }
1485             }
1486         } else {
1487             ty
1488         };
1489 
1490         let mut field = quote! {};
1491         if ctx.options().generate_comments {
1492             if let Some(raw_comment) = self.comment() {
1493                 let comment = ctx.options().process_comment(raw_comment);
1494                 field = attributes::doc(comment);
1495             }
1496         }
1497 
1498         let field_name = self
1499             .name()
1500             .map(|name| ctx.rust_mangle(name).into_owned())
1501             .expect("Each field should have a name in codegen!");
1502         let field_name = field_name.as_str();
1503         let field_ident = ctx.rust_ident_raw(field_name);
1504 
1505         if let Some(padding_field) =
1506             struct_layout.saw_field(field_name, field_ty, self.offset())
1507         {
1508             fields.extend(Some(padding_field));
1509         }
1510 
1511         let visibility = compute_visibility(
1512             ctx,
1513             self.is_public(),
1514             ctx.options().last_callback(|cb| {
1515                 cb.field_visibility(FieldInfo {
1516                     type_name: &parent_item.canonical_name(ctx),
1517                     field_name,
1518                 })
1519             }),
1520             self.annotations(),
1521             parent_visibility_kind,
1522         );
1523         let accessor_kind =
1524             self.annotations().accessor_kind().unwrap_or(accessor_kind);
1525 
1526         match visibility {
1527             FieldVisibilityKind::Private => {
1528                 field.append_all(quote! {
1529                     #field_ident : #ty ,
1530                 });
1531             }
1532             FieldVisibilityKind::PublicCrate => {
1533                 field.append_all(quote! {
1534                     pub(crate) #field_ident : #ty ,
1535                 });
1536             }
1537             FieldVisibilityKind::Public => {
1538                 field.append_all(quote! {
1539                     pub #field_ident : #ty ,
1540                 });
1541             }
1542         }
1543 
1544         fields.extend(Some(field));
1545 
1546         // TODO: Factor the following code out, please!
1547         if accessor_kind == FieldAccessorKind::None {
1548             return;
1549         }
1550 
1551         let getter_name = ctx.rust_ident_raw(format!("get_{}", field_name));
1552         let mutable_getter_name =
1553             ctx.rust_ident_raw(format!("get_{}_mut", field_name));
1554 
1555         methods.extend(Some(match accessor_kind {
1556             FieldAccessorKind::None => unreachable!(),
1557             FieldAccessorKind::Regular => {
1558                 quote! {
1559                     #[inline]
1560                     pub fn #getter_name(&self) -> & #ty {
1561                         &self.#field_ident
1562                     }
1563 
1564                     #[inline]
1565                     pub fn #mutable_getter_name(&mut self) -> &mut #ty {
1566                         &mut self.#field_ident
1567                     }
1568                 }
1569             }
1570             FieldAccessorKind::Unsafe => {
1571                 quote! {
1572                     #[inline]
1573                     pub unsafe fn #getter_name(&self) -> & #ty {
1574                         &self.#field_ident
1575                     }
1576 
1577                     #[inline]
1578                     pub unsafe fn #mutable_getter_name(&mut self) -> &mut #ty {
1579                         &mut self.#field_ident
1580                     }
1581                 }
1582             }
1583             FieldAccessorKind::Immutable => {
1584                 quote! {
1585                     #[inline]
1586                     pub fn #getter_name(&self) -> & #ty {
1587                         &self.#field_ident
1588                     }
1589                 }
1590             }
1591         }));
1592     }
1593 }
1594 
1595 impl BitfieldUnit {
1596     /// Get the constructor name for this bitfield unit.
ctor_name(&self) -> proc_macro2::TokenStream1597     fn ctor_name(&self) -> proc_macro2::TokenStream {
1598         let ctor_name = Ident::new(
1599             &format!("new_bitfield_{}", self.nth()),
1600             Span::call_site(),
1601         );
1602         quote! {
1603             #ctor_name
1604         }
1605     }
1606 }
1607 
1608 impl Bitfield {
1609     /// Extend an under construction bitfield unit constructor with this
1610     /// bitfield. This sets the relevant bits on the `__bindgen_bitfield_unit`
1611     /// variable that's being constructed.
extend_ctor_impl( &self, ctx: &BindgenContext, param_name: proc_macro2::TokenStream, mut ctor_impl: proc_macro2::TokenStream, ) -> proc_macro2::TokenStream1612     fn extend_ctor_impl(
1613         &self,
1614         ctx: &BindgenContext,
1615         param_name: proc_macro2::TokenStream,
1616         mut ctor_impl: proc_macro2::TokenStream,
1617     ) -> proc_macro2::TokenStream {
1618         let bitfield_ty = ctx.resolve_type(self.ty());
1619         let bitfield_ty_layout = bitfield_ty
1620             .layout(ctx)
1621             .expect("Bitfield without layout? Gah!");
1622         let bitfield_int_ty = helpers::integer_type(ctx, bitfield_ty_layout)
1623             .expect(
1624                 "Should already have verified that the bitfield is \
1625                  representable as an int",
1626             );
1627 
1628         let offset = self.offset_into_unit();
1629         let width = self.width() as u8;
1630         let prefix = ctx.trait_prefix();
1631 
1632         ctor_impl.append_all(quote! {
1633             __bindgen_bitfield_unit.set(
1634                 #offset,
1635                 #width,
1636                 {
1637                     let #param_name: #bitfield_int_ty = unsafe {
1638                         ::#prefix::mem::transmute(#param_name)
1639                     };
1640                     #param_name as u64
1641                 }
1642             );
1643         });
1644 
1645         ctor_impl
1646     }
1647 }
1648 
access_specifier( visibility: FieldVisibilityKind, ) -> proc_macro2::TokenStream1649 fn access_specifier(
1650     visibility: FieldVisibilityKind,
1651 ) -> proc_macro2::TokenStream {
1652     match visibility {
1653         FieldVisibilityKind::Private => quote! {},
1654         FieldVisibilityKind::PublicCrate => quote! { pub(crate) },
1655         FieldVisibilityKind::Public => quote! { pub },
1656     }
1657 }
1658 
1659 /// Compute a fields or structs visibility based on multiple conditions.
1660 /// 1. If the element was declared public, and we respect such CXX accesses specs
1661 ///    (context option) => By default Public, but this can be overruled by an `annotation`.
1662 ///
1663 /// 2. If the element was declared private, and we respect such CXX accesses specs
1664 ///    (context option) => By default Private, but this can be overruled by an `annotation`.
1665 ///
1666 /// 3. If we do not respect visibility modifiers, the result depends on the `annotation`,
1667 ///    if any, or the passed `default_kind`.
1668 ///
compute_visibility( ctx: &BindgenContext, is_declared_public: bool, callback_override: Option<FieldVisibilityKind>, annotations: &Annotations, default_kind: FieldVisibilityKind, ) -> FieldVisibilityKind1669 fn compute_visibility(
1670     ctx: &BindgenContext,
1671     is_declared_public: bool,
1672     callback_override: Option<FieldVisibilityKind>,
1673     annotations: &Annotations,
1674     default_kind: FieldVisibilityKind,
1675 ) -> FieldVisibilityKind {
1676     callback_override
1677         .or_else(|| annotations.visibility_kind())
1678         .unwrap_or_else(|| {
1679             match (is_declared_public, ctx.options().respect_cxx_access_specs) {
1680                 (true, true) => {
1681                     // declared as public, cxx specs are respected
1682                     FieldVisibilityKind::Public
1683                 }
1684                 (false, true) => {
1685                     // declared as private, cxx specs are respected
1686                     FieldVisibilityKind::Private
1687                 }
1688                 (_, false) => {
1689                     // cxx specs are not respected, declaration does not matter.
1690                     default_kind
1691                 }
1692             }
1693         })
1694 }
1695 
1696 impl<'a> FieldCodegen<'a> for BitfieldUnit {
1697     type Extra = ();
1698 
codegen<F, M>( &self, ctx: &BindgenContext, visibility_kind: FieldVisibilityKind, accessor_kind: FieldAccessorKind, parent: &CompInfo, parent_item: &Item, last_field: bool, result: &mut CodegenResult, struct_layout: &mut StructLayoutTracker, fields: &mut F, methods: &mut M, _: (), ) where F: Extend<proc_macro2::TokenStream>, M: Extend<proc_macro2::TokenStream>,1699     fn codegen<F, M>(
1700         &self,
1701         ctx: &BindgenContext,
1702         visibility_kind: FieldVisibilityKind,
1703         accessor_kind: FieldAccessorKind,
1704         parent: &CompInfo,
1705         parent_item: &Item,
1706         last_field: bool,
1707         result: &mut CodegenResult,
1708         struct_layout: &mut StructLayoutTracker,
1709         fields: &mut F,
1710         methods: &mut M,
1711         _: (),
1712     ) where
1713         F: Extend<proc_macro2::TokenStream>,
1714         M: Extend<proc_macro2::TokenStream>,
1715     {
1716         use crate::ir::ty::RUST_DERIVE_IN_ARRAY_LIMIT;
1717 
1718         result.saw_bitfield_unit();
1719 
1720         let layout = self.layout();
1721         let unit_field_ty = helpers::bitfield_unit(ctx, layout);
1722         let field_ty = {
1723             let unit_field_ty = unit_field_ty.clone();
1724             if parent.is_union() {
1725                 wrap_union_field_if_needed(
1726                     ctx,
1727                     struct_layout,
1728                     unit_field_ty,
1729                     result,
1730                 )
1731             } else {
1732                 unit_field_ty
1733             }
1734         };
1735 
1736         {
1737             let align_field_name = format!("_bitfield_align_{}", self.nth());
1738             let align_field_ident = ctx.rust_ident(align_field_name);
1739             let align_ty = match self.layout().align {
1740                 n if n >= 8 => quote! { u64 },
1741                 4 => quote! { u32 },
1742                 2 => quote! { u16 },
1743                 _ => quote! { u8  },
1744             };
1745             let access_spec = access_specifier(visibility_kind);
1746             let align_field = quote! {
1747                 #access_spec #align_field_ident: [#align_ty; 0],
1748             };
1749             fields.extend(Some(align_field));
1750         }
1751 
1752         let unit_field_name = format!("_bitfield_{}", self.nth());
1753         let unit_field_ident = ctx.rust_ident(&unit_field_name);
1754 
1755         let ctor_name = self.ctor_name();
1756         let mut ctor_params = vec![];
1757         let mut ctor_impl = quote! {};
1758 
1759         // We cannot generate any constructor if the underlying storage can't
1760         // implement AsRef<[u8]> / AsMut<[u8]> / etc, or can't derive Default.
1761         //
1762         // We don't check `larger_arrays` here because Default does still have
1763         // the 32 items limitation.
1764         let mut generate_ctor = layout.size <= RUST_DERIVE_IN_ARRAY_LIMIT;
1765 
1766         let mut unit_visibility = visibility_kind;
1767         let bfields = self.bitfields();
1768         for (idx, bf) in bfields.iter().enumerate() {
1769             // Codegen not allowed for anonymous bitfields
1770             if bf.name().is_none() {
1771                 continue;
1772             }
1773 
1774             if layout.size > RUST_DERIVE_IN_ARRAY_LIMIT &&
1775                 !ctx.options().rust_features().larger_arrays
1776             {
1777                 continue;
1778             }
1779 
1780             let mut bitfield_representable_as_int = true;
1781             let mut bitfield_visibility = visibility_kind;
1782             bf.codegen(
1783                 ctx,
1784                 visibility_kind,
1785                 accessor_kind,
1786                 parent,
1787                 parent_item,
1788                 last_field && idx == bfields.len() - 1,
1789                 result,
1790                 struct_layout,
1791                 fields,
1792                 methods,
1793                 (
1794                     &unit_field_name,
1795                     &mut bitfield_representable_as_int,
1796                     &mut bitfield_visibility,
1797                 ),
1798             );
1799             if bitfield_visibility < unit_visibility {
1800                 unit_visibility = bitfield_visibility;
1801             }
1802 
1803             // Generating a constructor requires the bitfield to be representable as an integer.
1804             if !bitfield_representable_as_int {
1805                 generate_ctor = false;
1806                 continue;
1807             }
1808 
1809             let param_name = bitfield_getter_name(ctx, bf);
1810             let bitfield_ty_item = ctx.resolve_item(bf.ty());
1811             let bitfield_ty = bitfield_ty_item.expect_type();
1812             let bitfield_ty =
1813                 bitfield_ty.to_rust_ty_or_opaque(ctx, bitfield_ty_item);
1814 
1815             ctor_params.push(quote! {
1816                 #param_name : #bitfield_ty
1817             });
1818             ctor_impl = bf.extend_ctor_impl(ctx, param_name, ctor_impl);
1819         }
1820 
1821         let access_spec = access_specifier(unit_visibility);
1822 
1823         let field = quote! {
1824             #access_spec #unit_field_ident : #field_ty ,
1825         };
1826         fields.extend(Some(field));
1827 
1828         if generate_ctor {
1829             methods.extend(Some(quote! {
1830                 #[inline]
1831                 #access_spec fn #ctor_name ( #( #ctor_params ),* ) -> #unit_field_ty {
1832                     let mut __bindgen_bitfield_unit: #unit_field_ty = Default::default();
1833                     #ctor_impl
1834                     __bindgen_bitfield_unit
1835                 }
1836             }));
1837         }
1838 
1839         struct_layout.saw_bitfield_unit(layout);
1840     }
1841 }
1842 
bitfield_getter_name( ctx: &BindgenContext, bitfield: &Bitfield, ) -> proc_macro2::TokenStream1843 fn bitfield_getter_name(
1844     ctx: &BindgenContext,
1845     bitfield: &Bitfield,
1846 ) -> proc_macro2::TokenStream {
1847     let name = bitfield.getter_name();
1848     let name = ctx.rust_ident_raw(name);
1849     quote! { #name }
1850 }
1851 
bitfield_setter_name( ctx: &BindgenContext, bitfield: &Bitfield, ) -> proc_macro2::TokenStream1852 fn bitfield_setter_name(
1853     ctx: &BindgenContext,
1854     bitfield: &Bitfield,
1855 ) -> proc_macro2::TokenStream {
1856     let setter = bitfield.setter_name();
1857     let setter = ctx.rust_ident_raw(setter);
1858     quote! { #setter }
1859 }
1860 
1861 impl<'a> FieldCodegen<'a> for Bitfield {
1862     type Extra = (&'a str, &'a mut bool, &'a mut FieldVisibilityKind);
1863 
codegen<F, M>( &self, ctx: &BindgenContext, visibility_kind: FieldVisibilityKind, _accessor_kind: FieldAccessorKind, parent: &CompInfo, parent_item: &Item, _last_field: bool, _result: &mut CodegenResult, struct_layout: &mut StructLayoutTracker, _fields: &mut F, methods: &mut M, (unit_field_name, bitfield_representable_as_int, bitfield_visibility): ( &'a str, &mut bool, &'a mut FieldVisibilityKind, ), ) where F: Extend<proc_macro2::TokenStream>, M: Extend<proc_macro2::TokenStream>,1864     fn codegen<F, M>(
1865         &self,
1866         ctx: &BindgenContext,
1867         visibility_kind: FieldVisibilityKind,
1868         _accessor_kind: FieldAccessorKind,
1869         parent: &CompInfo,
1870         parent_item: &Item,
1871         _last_field: bool,
1872         _result: &mut CodegenResult,
1873         struct_layout: &mut StructLayoutTracker,
1874         _fields: &mut F,
1875         methods: &mut M,
1876         (unit_field_name, bitfield_representable_as_int, bitfield_visibility): (
1877             &'a str,
1878             &mut bool,
1879             &'a mut FieldVisibilityKind,
1880         ),
1881     ) where
1882         F: Extend<proc_macro2::TokenStream>,
1883         M: Extend<proc_macro2::TokenStream>,
1884     {
1885         let prefix = ctx.trait_prefix();
1886         let getter_name = bitfield_getter_name(ctx, self);
1887         let setter_name = bitfield_setter_name(ctx, self);
1888         let unit_field_ident = Ident::new(unit_field_name, Span::call_site());
1889 
1890         let bitfield_ty_item = ctx.resolve_item(self.ty());
1891         let bitfield_ty = bitfield_ty_item.expect_type();
1892 
1893         let bitfield_ty_layout = bitfield_ty
1894             .layout(ctx)
1895             .expect("Bitfield without layout? Gah!");
1896         let bitfield_int_ty =
1897             match helpers::integer_type(ctx, bitfield_ty_layout) {
1898                 Some(int_ty) => {
1899                     *bitfield_representable_as_int = true;
1900                     int_ty
1901                 }
1902                 None => {
1903                     *bitfield_representable_as_int = false;
1904                     return;
1905                 }
1906             };
1907 
1908         let bitfield_ty =
1909             bitfield_ty.to_rust_ty_or_opaque(ctx, bitfield_ty_item);
1910 
1911         let offset = self.offset_into_unit();
1912         let width = self.width() as u8;
1913 
1914         let override_visibility = self.name().and_then(|field_name| {
1915             ctx.options().last_callback(|cb| {
1916                 cb.field_visibility(FieldInfo {
1917                     type_name: &parent_item.canonical_name(ctx),
1918                     field_name,
1919                 })
1920             })
1921         });
1922         *bitfield_visibility = compute_visibility(
1923             ctx,
1924             self.is_public(),
1925             override_visibility,
1926             self.annotations(),
1927             visibility_kind,
1928         );
1929         let access_spec = access_specifier(*bitfield_visibility);
1930 
1931         if parent.is_union() && !struct_layout.is_rust_union() {
1932             methods.extend(Some(quote! {
1933                 #[inline]
1934                 #access_spec fn #getter_name(&self) -> #bitfield_ty {
1935                     unsafe {
1936                         ::#prefix::mem::transmute(
1937                             self.#unit_field_ident.as_ref().get(#offset, #width)
1938                                 as #bitfield_int_ty
1939                         )
1940                     }
1941                 }
1942 
1943                 #[inline]
1944                 #access_spec fn #setter_name(&mut self, val: #bitfield_ty) {
1945                     unsafe {
1946                         let val: #bitfield_int_ty = ::#prefix::mem::transmute(val);
1947                         self.#unit_field_ident.as_mut().set(
1948                             #offset,
1949                             #width,
1950                             val as u64
1951                         )
1952                     }
1953                 }
1954             }));
1955         } else {
1956             methods.extend(Some(quote! {
1957                 #[inline]
1958                 #access_spec fn #getter_name(&self) -> #bitfield_ty {
1959                     unsafe {
1960                         ::#prefix::mem::transmute(
1961                             self.#unit_field_ident.get(#offset, #width)
1962                                 as #bitfield_int_ty
1963                         )
1964                     }
1965                 }
1966 
1967                 #[inline]
1968                 #access_spec fn #setter_name(&mut self, val: #bitfield_ty) {
1969                     unsafe {
1970                         let val: #bitfield_int_ty = ::#prefix::mem::transmute(val);
1971                         self.#unit_field_ident.set(
1972                             #offset,
1973                             #width,
1974                             val as u64
1975                         )
1976                     }
1977                 }
1978             }));
1979         }
1980     }
1981 }
1982 
1983 impl CodeGenerator for CompInfo {
1984     type Extra = Item;
1985     type Return = ();
1986 
codegen( &self, ctx: &BindgenContext, result: &mut CodegenResult<'_>, item: &Item, )1987     fn codegen(
1988         &self,
1989         ctx: &BindgenContext,
1990         result: &mut CodegenResult<'_>,
1991         item: &Item,
1992     ) {
1993         debug!("<CompInfo as CodeGenerator>::codegen: item = {:?}", item);
1994         debug_assert!(item.is_enabled_for_codegen(ctx));
1995 
1996         // Don't output classes with template parameters that aren't types, and
1997         // also don't output template specializations, neither total or partial.
1998         if self.has_non_type_template_params() {
1999             return;
2000         }
2001 
2002         let ty = item.expect_type();
2003         let layout = ty.layout(ctx);
2004         let mut packed = self.is_packed(ctx, layout.as_ref());
2005 
2006         let canonical_name = item.canonical_name(ctx);
2007         let canonical_ident = ctx.rust_ident(&canonical_name);
2008 
2009         // Generate the vtable from the method list if appropriate.
2010         //
2011         // TODO: I don't know how this could play with virtual methods that are
2012         // not in the list of methods found by us, we'll see. Also, could the
2013         // order of the vtable pointers vary?
2014         //
2015         // FIXME: Once we generate proper vtables, we need to codegen the
2016         // vtable, but *not* generate a field for it in the case that
2017         // HasVtable::has_vtable_ptr is false but HasVtable::has_vtable is true.
2018         //
2019         // Also, we need to generate the vtable in such a way it "inherits" from
2020         // the parent too.
2021         let is_opaque = item.is_opaque(ctx, &());
2022         let mut fields = vec![];
2023         let visibility = item
2024             .annotations()
2025             .visibility_kind()
2026             .unwrap_or(ctx.options().default_visibility);
2027         let mut struct_layout = StructLayoutTracker::new(
2028             ctx,
2029             self,
2030             ty,
2031             &canonical_name,
2032             visibility,
2033             packed,
2034         );
2035 
2036         let mut generic_param_names = vec![];
2037 
2038         for (idx, ty) in item.used_template_params(ctx).iter().enumerate() {
2039             let param = ctx.resolve_type(*ty);
2040             let name = param.name().unwrap();
2041             let ident = ctx.rust_ident(name);
2042             generic_param_names.push(ident.clone());
2043 
2044             let prefix = ctx.trait_prefix();
2045             let field_name = ctx.rust_ident(format!("_phantom_{}", idx));
2046             fields.push(quote! {
2047                 pub #field_name : ::#prefix::marker::PhantomData<
2048                     ::#prefix::cell::UnsafeCell<#ident>
2049                 > ,
2050             });
2051         }
2052 
2053         if !is_opaque {
2054             if item.has_vtable_ptr(ctx) {
2055                 let vtable = Vtable::new(item.id(), self);
2056                 vtable.codegen(ctx, result, item);
2057 
2058                 let vtable_type = vtable
2059                     .try_to_rust_ty(ctx, &())
2060                     .expect("vtable to Rust type conversion is infallible")
2061                     .to_ptr(true);
2062 
2063                 fields.push(quote! {
2064                     pub vtable_: #vtable_type ,
2065                 });
2066 
2067                 struct_layout.saw_vtable();
2068             }
2069 
2070             for base in self.base_members() {
2071                 if !base.requires_storage(ctx) {
2072                     continue;
2073                 }
2074 
2075                 let inner_item = ctx.resolve_item(base.ty);
2076                 let inner = inner_item
2077                     .to_rust_ty_or_opaque(ctx, &())
2078                     .with_implicit_template_params(ctx, inner_item);
2079                 let field_name = ctx.rust_ident(&base.field_name);
2080 
2081                 struct_layout.saw_base(inner_item.expect_type());
2082 
2083                 let visibility = match (
2084                     base.is_public(),
2085                     ctx.options().respect_cxx_access_specs,
2086                 ) {
2087                     (true, true) => FieldVisibilityKind::Public,
2088                     (false, true) => FieldVisibilityKind::Private,
2089                     _ => ctx.options().default_visibility,
2090                 };
2091 
2092                 let access_spec = access_specifier(visibility);
2093                 fields.push(quote! {
2094                     #access_spec #field_name: #inner,
2095                 });
2096             }
2097         }
2098 
2099         let mut methods = vec![];
2100         if !is_opaque {
2101             let struct_accessor_kind = item
2102                 .annotations()
2103                 .accessor_kind()
2104                 .unwrap_or(FieldAccessorKind::None);
2105             let field_decls = self.fields();
2106             for (idx, field) in field_decls.iter().enumerate() {
2107                 field.codegen(
2108                     ctx,
2109                     visibility,
2110                     struct_accessor_kind,
2111                     self,
2112                     item,
2113                     idx == field_decls.len() - 1,
2114                     result,
2115                     &mut struct_layout,
2116                     &mut fields,
2117                     &mut methods,
2118                     (),
2119                 );
2120             }
2121             // Check whether an explicit padding field is needed
2122             // at the end.
2123             if let Some(comp_layout) = layout {
2124                 fields.extend(
2125                     struct_layout
2126                         .add_tail_padding(&canonical_name, comp_layout),
2127                 );
2128             }
2129         }
2130 
2131         if is_opaque {
2132             // Opaque item should not have generated methods, fields.
2133             debug_assert!(fields.is_empty());
2134             debug_assert!(methods.is_empty());
2135         }
2136 
2137         let is_union = self.kind() == CompKind::Union;
2138         let layout = item.kind().expect_type().layout(ctx);
2139         let zero_sized = item.is_zero_sized(ctx);
2140         let forward_decl = self.is_forward_declaration();
2141 
2142         let mut explicit_align = None;
2143 
2144         // C++ requires every struct to be addressable, so what C++ compilers do
2145         // is making the struct 1-byte sized.
2146         //
2147         // This is apparently not the case for C, see:
2148         // https://github.com/rust-lang/rust-bindgen/issues/551
2149         //
2150         // Just get the layout, and assume C++ if not.
2151         //
2152         // NOTE: This check is conveniently here to avoid the dummy fields we
2153         // may add for unused template parameters.
2154         if !forward_decl && zero_sized {
2155             let has_address = if is_opaque {
2156                 // Generate the address field if it's an opaque type and
2157                 // couldn't determine the layout of the blob.
2158                 layout.is_none()
2159             } else {
2160                 layout.map_or(true, |l| l.size != 0)
2161             };
2162 
2163             if has_address {
2164                 let layout = Layout::new(1, 1);
2165                 let ty = helpers::blob(ctx, Layout::new(1, 1));
2166                 struct_layout.saw_field_with_layout(
2167                     "_address",
2168                     layout,
2169                     /* offset = */ Some(0),
2170                 );
2171                 fields.push(quote! {
2172                     pub _address: #ty,
2173                 });
2174             }
2175         }
2176 
2177         if is_opaque {
2178             match layout {
2179                 Some(l) => {
2180                     explicit_align = Some(l.align);
2181 
2182                     let ty = helpers::blob(ctx, l);
2183                     fields.push(quote! {
2184                         pub _bindgen_opaque_blob: #ty ,
2185                     });
2186                 }
2187                 None => {
2188                     warn!("Opaque type without layout! Expect dragons!");
2189                 }
2190             }
2191         } else if !is_union && !zero_sized {
2192             if let Some(padding_field) =
2193                 layout.and_then(|layout| struct_layout.pad_struct(layout))
2194             {
2195                 fields.push(padding_field);
2196             }
2197 
2198             if let Some(layout) = layout {
2199                 if struct_layout.requires_explicit_align(layout) {
2200                     if layout.align == 1 {
2201                         packed = true;
2202                     } else {
2203                         explicit_align = Some(layout.align);
2204                         if !ctx.options().rust_features.repr_align {
2205                             let ty = helpers::blob(
2206                                 ctx,
2207                                 Layout::new(0, layout.align),
2208                             );
2209                             fields.push(quote! {
2210                                 pub __bindgen_align: #ty ,
2211                             });
2212                         }
2213                     }
2214                 }
2215             }
2216         } else if is_union && !forward_decl {
2217             // TODO(emilio): It'd be nice to unify this with the struct path
2218             // above somehow.
2219             let layout = layout.expect("Unable to get layout information?");
2220             if struct_layout.requires_explicit_align(layout) {
2221                 explicit_align = Some(layout.align);
2222             }
2223 
2224             if !struct_layout.is_rust_union() {
2225                 let ty = helpers::blob(ctx, layout);
2226                 fields.push(quote! {
2227                     pub bindgen_union_field: #ty ,
2228                 })
2229             }
2230         }
2231 
2232         if forward_decl {
2233             fields.push(quote! {
2234                 _unused: [u8; 0],
2235             });
2236         }
2237 
2238         let (flex_array_generic, flex_inner_ty) = if ctx.options().flexarray_dst
2239         {
2240             match self.flex_array_member(ctx) {
2241                 Some(ty) => {
2242                     let inner = ty.to_rust_ty_or_opaque(ctx, &());
2243                     (
2244                         Some(quote! { FAM: ?Sized = [ #inner; 0 ] }),
2245                         Some(quote! { #inner }),
2246                     )
2247                 }
2248                 None => (None, None),
2249             }
2250         } else {
2251             (None, None)
2252         };
2253 
2254         // Generics, including the flexible array member.
2255         //
2256         // generics - generic parameters for the struct declaration
2257         // impl_generics_labels - generic parameters for `impl<...>`
2258         // impl_generics_params - generic parameters for `impl structname<...>`
2259         //
2260         // `impl` blocks are for non-FAM related impls like Default, etc
2261         let (generics, impl_generics_labels, impl_generics_params) =
2262             if !generic_param_names.is_empty() || flex_array_generic.is_some() {
2263                 let (flex_sized, flex_fam) = match flex_inner_ty.as_ref() {
2264                     None => (None, None),
2265                     Some(ty) => (
2266                         Some(quote! { [ #ty; 0 ] }),
2267                         Some(quote! { FAM: ?Sized = [ #ty; 0 ] }),
2268                     ),
2269                 };
2270 
2271                 (
2272                     quote! {
2273                         < #( #generic_param_names , )* #flex_fam >
2274                     },
2275                     quote! {
2276                         < #( #generic_param_names , )* >
2277                     },
2278                     quote! {
2279                         < #( #generic_param_names , )* #flex_sized >
2280                     },
2281                 )
2282             } else {
2283                 (quote! {}, quote! {}, quote! {})
2284             };
2285 
2286         let mut attributes = vec![];
2287         let mut needs_clone_impl = false;
2288         let mut needs_default_impl = false;
2289         let mut needs_debug_impl = false;
2290         let mut needs_partialeq_impl = false;
2291         let needs_flexarray_impl = flex_array_generic.is_some();
2292         if let Some(comment) = item.comment(ctx) {
2293             attributes.push(attributes::doc(comment));
2294         }
2295 
2296         // if a type has both a "packed" attribute and an "align(N)" attribute, then check if the
2297         // "packed" attr is redundant, and do not include it if so.
2298         if packed &&
2299             !is_opaque &&
2300             !(explicit_align.is_some() &&
2301                 self.already_packed(ctx).unwrap_or(false))
2302         {
2303             let n = layout.map_or(1, |l| l.align);
2304             assert!(ctx.options().rust_features().repr_packed_n || n == 1);
2305             let packed_repr = if n == 1 {
2306                 "packed".to_string()
2307             } else {
2308                 format!("packed({})", n)
2309             };
2310             attributes.push(attributes::repr_list(&["C", &packed_repr]));
2311         } else {
2312             attributes.push(attributes::repr("C"));
2313         }
2314 
2315         if ctx.options().rust_features().repr_align {
2316             if let Some(explicit) = explicit_align {
2317                 // Ensure that the struct has the correct alignment even in
2318                 // presence of alignas.
2319                 let explicit = helpers::ast_ty::int_expr(explicit as i64);
2320                 attributes.push(quote! {
2321                     #[repr(align(#explicit))]
2322                 });
2323             }
2324         }
2325 
2326         let derivable_traits = derives_of_item(item, ctx, packed);
2327         if !derivable_traits.contains(DerivableTraits::DEBUG) {
2328             needs_debug_impl = ctx.options().derive_debug &&
2329                 ctx.options().impl_debug &&
2330                 !ctx.no_debug_by_name(item) &&
2331                 !item.annotations().disallow_debug();
2332         }
2333 
2334         if !derivable_traits.contains(DerivableTraits::DEFAULT) {
2335             needs_default_impl = ctx.options().derive_default &&
2336                 !self.is_forward_declaration() &&
2337                 !ctx.no_default_by_name(item) &&
2338                 !item.annotations().disallow_default();
2339         }
2340 
2341         let all_template_params = item.all_template_params(ctx);
2342 
2343         if derivable_traits.contains(DerivableTraits::COPY) &&
2344             !derivable_traits.contains(DerivableTraits::CLONE)
2345         {
2346             needs_clone_impl = true;
2347         }
2348 
2349         if !derivable_traits.contains(DerivableTraits::PARTIAL_EQ) {
2350             needs_partialeq_impl = ctx.options().derive_partialeq &&
2351                 ctx.options().impl_partialeq &&
2352                 ctx.lookup_can_derive_partialeq_or_partialord(item.id()) ==
2353                     CanDerive::Manually;
2354         }
2355 
2356         let mut derives: Vec<_> = derivable_traits.into();
2357         derives.extend(item.annotations().derives().iter().map(String::as_str));
2358 
2359         let is_rust_union = is_union && struct_layout.is_rust_union();
2360 
2361         // The custom derives callback may return a list of derive attributes;
2362         // add them to the end of the list.
2363         let custom_derives = ctx.options().all_callbacks(|cb| {
2364             cb.add_derives(&DeriveInfo {
2365                 name: &canonical_name,
2366                 kind: if is_rust_union {
2367                     DeriveTypeKind::Union
2368                 } else {
2369                     DeriveTypeKind::Struct
2370                 },
2371             })
2372         });
2373         // In most cases this will be a no-op, since custom_derives will be empty.
2374         derives.extend(custom_derives.iter().map(|s| s.as_str()));
2375 
2376         if !derives.is_empty() {
2377             attributes.push(attributes::derives(&derives))
2378         }
2379 
2380         if item.must_use(ctx) {
2381             attributes.push(attributes::must_use());
2382         }
2383 
2384         let mut tokens = if is_rust_union {
2385             quote! {
2386                 #( #attributes )*
2387                 pub union #canonical_ident
2388             }
2389         } else {
2390             quote! {
2391                 #( #attributes )*
2392                 pub struct #canonical_ident
2393             }
2394         };
2395 
2396         tokens.append_all(quote! {
2397             #generics {
2398                 #( #fields )*
2399             }
2400         });
2401         result.push(tokens);
2402 
2403         // Generate the inner types and all that stuff.
2404         //
2405         // TODO: In the future we might want to be smart, and use nested
2406         // modules, and whatnot.
2407         for ty in self.inner_types() {
2408             let child_item = ctx.resolve_item(*ty);
2409             // assert_eq!(child_item.parent_id(), item.id());
2410             child_item.codegen(ctx, result, &());
2411         }
2412 
2413         // NOTE: Some unexposed attributes (like alignment attributes) may
2414         // affect layout, so we're bad and pray to the gods for avoid sending
2415         // all the tests to shit when parsing things like max_align_t.
2416         if self.found_unknown_attr() {
2417             warn!(
2418                 "Type {} has an unknown attribute that may affect layout",
2419                 canonical_ident
2420             );
2421         }
2422 
2423         if all_template_params.is_empty() {
2424             if !is_opaque {
2425                 for var in self.inner_vars() {
2426                     ctx.resolve_item(*var).codegen(ctx, result, &());
2427                 }
2428             }
2429 
2430             if ctx.options().layout_tests && !self.is_forward_declaration() {
2431                 if let Some(layout) = layout {
2432                     let compile_time = ctx.options().rust_features().offset_of;
2433                     let fn_name = if compile_time {
2434                         None
2435                     } else {
2436                         let fn_name =
2437                             format!("bindgen_test_layout_{canonical_ident}");
2438                         Some(ctx.rust_ident_raw(fn_name))
2439                     };
2440                     let prefix = ctx.trait_prefix();
2441                     let size_of_expr = quote! {
2442                         ::#prefix::mem::size_of::<#canonical_ident>()
2443                     };
2444                     let align_of_expr = quote! {
2445                         ::#prefix::mem::align_of::<#canonical_ident>()
2446                     };
2447                     let size = layout.size;
2448                     let align = layout.align;
2449                     let size_of_err = format!("Size of {canonical_ident}");
2450                     let align_of_err =
2451                         format!("Alignment of {canonical_ident}");
2452 
2453                     let check_struct_align = if align >
2454                         ctx.target_pointer_size() &&
2455                         !ctx.options().rust_features().repr_align
2456                     {
2457                         None
2458                     } else if compile_time {
2459                         Some(quote! {
2460                             [#align_of_err][#align_of_expr - #align];
2461                         })
2462                     } else {
2463                         Some(quote! {
2464                             assert_eq!(#align_of_expr, #align, #align_of_err);
2465                         })
2466                     };
2467 
2468                     let should_skip_field_offset_checks = is_opaque;
2469 
2470                     let check_field_offset = if should_skip_field_offset_checks
2471                     {
2472                         vec![]
2473                     } else {
2474                         self.fields()
2475                             .iter()
2476                             .filter_map(|field| match *field {
2477                                 Field::DataMember(ref f) if f.name().is_some() => Some(f),
2478                                 _ => None,
2479                             })
2480                             .flat_map(|field| {
2481                                 let name = field.name().unwrap();
2482                                 field.offset().map(|offset| {
2483                                     let field_offset = offset / 8;
2484                                     let field_name = ctx.rust_ident(name);
2485                                     let offset_of_err = format!("Offset of field: {canonical_ident}::{field_name}");
2486                                     if compile_time {
2487                                         quote! {
2488                                             [#offset_of_err][
2489                                                 ::#prefix::mem::offset_of!(#canonical_ident, #field_name) - #field_offset
2490                                             ];
2491                                         }
2492                                     } else {
2493                                         quote! {
2494                                             assert_eq!(
2495                                                 unsafe {
2496                                                     ::#prefix::ptr::addr_of!((*ptr).#field_name) as usize - ptr as usize
2497                                                 },
2498                                                 #field_offset,
2499                                                 #offset_of_err
2500                                             );
2501                                         }
2502                                     }
2503                                 })
2504                             })
2505                             .collect()
2506                     };
2507 
2508                     let uninit_decl = if check_field_offset.is_empty() ||
2509                         compile_time
2510                     {
2511                         None
2512                     } else {
2513                         // FIXME: When MSRV >= 1.59.0, we can use
2514                         // > const PTR: *const #canonical_ident = ::#prefix::mem::MaybeUninit::uninit().as_ptr();
2515                         Some(quote! {
2516                             // Use a shared MaybeUninit so that rustc with
2517                             // opt-level=0 doesn't take too much stack space,
2518                             // see #2218.
2519                             const UNINIT: ::#prefix::mem::MaybeUninit<#canonical_ident> = ::#prefix::mem::MaybeUninit::uninit();
2520                             let ptr = UNINIT.as_ptr();
2521                         })
2522                     };
2523 
2524                     if compile_time {
2525                         result.push(quote! {
2526                             #[allow(clippy::unnecessary_operation, clippy::identity_op)]
2527                             const _: () = {
2528                                 [#size_of_err][#size_of_expr - #size];
2529                                 #check_struct_align
2530                                 #( #check_field_offset )*
2531                             };
2532                         });
2533                     } else {
2534                         result.push(quote! {
2535                             #[test]
2536                             fn #fn_name() {
2537                                 #uninit_decl
2538                                 assert_eq!(#size_of_expr, #size, #size_of_err);
2539                                 #check_struct_align
2540                                 #( #check_field_offset )*
2541                             }
2542                         });
2543                     }
2544                 }
2545             }
2546 
2547             let mut method_names = Default::default();
2548             if ctx.options().codegen_config.methods() {
2549                 for method in self.methods() {
2550                     assert!(method.kind() != MethodKind::Constructor);
2551                     method.codegen_method(
2552                         ctx,
2553                         &mut methods,
2554                         &mut method_names,
2555                         result,
2556                         self,
2557                     );
2558                 }
2559             }
2560 
2561             if ctx.options().codegen_config.constructors() {
2562                 for sig in self.constructors() {
2563                     Method::new(
2564                         MethodKind::Constructor,
2565                         *sig,
2566                         /* const */
2567                         false,
2568                     )
2569                     .codegen_method(
2570                         ctx,
2571                         &mut methods,
2572                         &mut method_names,
2573                         result,
2574                         self,
2575                     );
2576                 }
2577             }
2578 
2579             if ctx.options().codegen_config.destructors() {
2580                 if let Some((kind, destructor)) = self.destructor() {
2581                     debug_assert!(kind.is_destructor());
2582                     Method::new(kind, destructor, false).codegen_method(
2583                         ctx,
2584                         &mut methods,
2585                         &mut method_names,
2586                         result,
2587                         self,
2588                     );
2589                 }
2590             }
2591         }
2592 
2593         // NB: We can't use to_rust_ty here since for opaque types this tries to
2594         // use the specialization knowledge to generate a blob field.
2595         let ty_for_impl = quote! {
2596             #canonical_ident #impl_generics_params
2597         };
2598 
2599         if needs_clone_impl {
2600             result.push(quote! {
2601                 impl #impl_generics_labels Clone for #ty_for_impl {
2602                     fn clone(&self) -> Self { *self }
2603                 }
2604             });
2605         }
2606 
2607         if needs_flexarray_impl {
2608             result.push(self.generate_flexarray(
2609                 ctx,
2610                 &canonical_ident,
2611                 flex_inner_ty,
2612                 &generic_param_names,
2613                 &impl_generics_labels,
2614             ));
2615         }
2616 
2617         if needs_default_impl {
2618             let prefix = ctx.trait_prefix();
2619             let body = if ctx.options().rust_features().maybe_uninit {
2620                 quote! {
2621                     let mut s = ::#prefix::mem::MaybeUninit::<Self>::uninit();
2622                     unsafe {
2623                         ::#prefix::ptr::write_bytes(s.as_mut_ptr(), 0, 1);
2624                         s.assume_init()
2625                     }
2626                 }
2627             } else {
2628                 quote! {
2629                     unsafe {
2630                         let mut s: Self = ::#prefix::mem::uninitialized();
2631                         ::#prefix::ptr::write_bytes(&mut s, 0, 1);
2632                         s
2633                     }
2634                 }
2635             };
2636             // Note we use `ptr::write_bytes()` instead of `mem::zeroed()` because the latter does
2637             // not necessarily ensure padding bytes are zeroed. Some C libraries are sensitive to
2638             // non-zero padding bytes, especially when forwards/backwards compatibility is
2639             // involved.
2640             result.push(quote! {
2641                 impl #impl_generics_labels Default for #ty_for_impl {
2642                     fn default() -> Self {
2643                         #body
2644                     }
2645                 }
2646             });
2647         }
2648 
2649         if needs_debug_impl {
2650             let impl_ = impl_debug::gen_debug_impl(
2651                 ctx,
2652                 self.fields(),
2653                 item,
2654                 self.kind(),
2655             );
2656 
2657             let prefix = ctx.trait_prefix();
2658 
2659             result.push(quote! {
2660                 impl #impl_generics_labels ::#prefix::fmt::Debug for #ty_for_impl {
2661                     #impl_
2662                 }
2663             });
2664         }
2665 
2666         if needs_partialeq_impl {
2667             if let Some(impl_) = impl_partialeq::gen_partialeq_impl(
2668                 ctx,
2669                 self,
2670                 item,
2671                 &ty_for_impl,
2672             ) {
2673                 let partialeq_bounds = if !generic_param_names.is_empty() {
2674                     let bounds = generic_param_names.iter().map(|t| {
2675                         quote! { #t: PartialEq }
2676                     });
2677                     quote! { where #( #bounds ),* }
2678                 } else {
2679                     quote! {}
2680                 };
2681 
2682                 let prefix = ctx.trait_prefix();
2683                 result.push(quote! {
2684                     impl #impl_generics_labels ::#prefix::cmp::PartialEq for #ty_for_impl #partialeq_bounds {
2685                         #impl_
2686                     }
2687                 });
2688             }
2689         }
2690 
2691         if !methods.is_empty() {
2692             result.push(quote! {
2693                 impl #impl_generics_labels #ty_for_impl {
2694                     #( #methods )*
2695                 }
2696             });
2697         }
2698     }
2699 }
2700 
2701 impl CompInfo {
generate_flexarray( &self, ctx: &BindgenContext, canonical_ident: &Ident, flex_inner_ty: Option<proc_macro2::TokenStream>, generic_param_names: &[Ident], impl_generics_labels: &proc_macro2::TokenStream, ) -> proc_macro2::TokenStream2702     fn generate_flexarray(
2703         &self,
2704         ctx: &BindgenContext,
2705         canonical_ident: &Ident,
2706         flex_inner_ty: Option<proc_macro2::TokenStream>,
2707         generic_param_names: &[Ident],
2708         impl_generics_labels: &proc_macro2::TokenStream,
2709     ) -> proc_macro2::TokenStream {
2710         let prefix = ctx.trait_prefix();
2711 
2712         let flex_array = flex_inner_ty.as_ref().map(|ty| quote! { [ #ty ] });
2713 
2714         let dst_ty_for_impl = quote! {
2715             #canonical_ident < #( #generic_param_names , )* #flex_array >
2716 
2717         };
2718         let sized_ty_for_impl = quote! {
2719             #canonical_ident < #( #generic_param_names , )* [ #flex_inner_ty; 0 ] >
2720         };
2721 
2722         let layout = if ctx.options().rust_features().layout_for_ptr {
2723             quote! {
2724                 pub fn layout(len: usize) -> ::#prefix::alloc::Layout {
2725                     // SAFETY: Null pointers are OK if we don't deref them
2726                     unsafe {
2727                         let p: *const Self = ::#prefix::ptr::from_raw_parts(::#prefix::ptr::null::<()>(), len);
2728                         ::#prefix::alloc::Layout::for_value_raw(p)
2729                     }
2730                 }
2731             }
2732         } else {
2733             quote!()
2734         };
2735 
2736         let (from_ptr_dst, from_ptr_sized) = if ctx
2737             .options()
2738             .rust_features()
2739             .ptr_metadata
2740         {
2741             let flex_ref_inner = ctx.wrap_unsafe_ops(quote! {
2742                 Self::flex_ptr(self, len)
2743             });
2744             let flex_ref_mut_inner = ctx.wrap_unsafe_ops(quote! {
2745                 Self::flex_ptr_mut(self, len).assume_init()
2746             });
2747             let flex_ptr_inner = ctx.wrap_unsafe_ops(quote! {
2748                 &*::#prefix::ptr::from_raw_parts(ptr as *const (), len)
2749             });
2750             let flex_ptr_mut_inner = ctx.wrap_unsafe_ops(quote! {
2751                 // Initialize reference without ever exposing it, as its possibly uninitialized
2752                 let mut uninit = ::#prefix::mem::MaybeUninit::<&mut #dst_ty_for_impl>::uninit();
2753                 (uninit.as_mut_ptr() as *mut *mut #dst_ty_for_impl)
2754                     .write(::#prefix::ptr::from_raw_parts_mut(ptr as *mut (), len));
2755 
2756                 uninit
2757             });
2758 
2759             (
2760                 quote! {
2761                     #[inline]
2762                     pub fn fixed(&self) -> (& #sized_ty_for_impl, usize) {
2763                         unsafe {
2764                             let (ptr, len) = (self as *const Self).to_raw_parts();
2765                             (&*(ptr as *const #sized_ty_for_impl), len)
2766                         }
2767                     }
2768 
2769                     #[inline]
2770                     pub fn fixed_mut(&mut self) -> (&mut #sized_ty_for_impl, usize) {
2771                         unsafe {
2772                             let (ptr, len) = (self as *mut Self).to_raw_parts();
2773                             (&mut *(ptr as *mut #sized_ty_for_impl), len)
2774                         }
2775                     }
2776                 },
2777                 quote! {
2778                     /// Convert a sized prefix to an unsized structure with the given length.
2779                     ///
2780                     /// SAFETY: Underlying storage is initialized up to at least `len` elements.
2781                     pub unsafe fn flex_ref(&self, len: usize) -> &#dst_ty_for_impl {
2782                         // SAFETY: Reference is always valid as pointer. Caller is guaranteeing `len`.
2783                         #flex_ref_inner
2784                     }
2785 
2786                     /// Convert a mutable sized prefix to an unsized structure with the given length.
2787                     ///
2788                     /// SAFETY: Underlying storage is initialized up to at least `len` elements.
2789                     #[inline]
2790                     pub unsafe fn flex_ref_mut(&mut self, len: usize) -> &mut #dst_ty_for_impl {
2791                         // SAFETY: Reference is always valid as pointer. Caller is guaranteeing `len`.
2792                         #flex_ref_mut_inner
2793                     }
2794 
2795                     /// Construct DST variant from a pointer and a size.
2796                     ///
2797                     /// NOTE: lifetime of returned reference is not tied to any underlying storage.
2798                     /// SAFETY: `ptr` is valid. Underlying storage is fully initialized up to at least `len` elements.
2799                     #[inline]
2800                     pub unsafe fn flex_ptr<'unbounded>(ptr: *const Self, len: usize) -> &'unbounded #dst_ty_for_impl {
2801                        #flex_ptr_inner
2802                     }
2803 
2804                     /// Construct mutable DST variant from a pointer and a
2805                     /// size. The returned `&mut` reference is initialized
2806                     /// pointing to memory referenced by `ptr`, but there's
2807                     /// no requirement that that memory be initialized.
2808                     ///
2809                     /// NOTE: lifetime of returned reference is not tied to any underlying storage.
2810                     /// SAFETY: `ptr` is valid. Underlying storage has space for at least `len` elements.
2811                     #[inline]
2812                     pub unsafe fn flex_ptr_mut<'unbounded>(
2813                         ptr: *mut Self,
2814                         len: usize,
2815                     ) -> ::#prefix::mem::MaybeUninit<&'unbounded mut #dst_ty_for_impl> {
2816                         #flex_ptr_mut_inner
2817                     }
2818                 },
2819             )
2820         } else {
2821             (quote!(), quote!())
2822         };
2823 
2824         quote! {
2825             impl #impl_generics_labels #dst_ty_for_impl {
2826                 #layout
2827                 #from_ptr_dst
2828             }
2829 
2830             impl #impl_generics_labels #sized_ty_for_impl {
2831                 #from_ptr_sized
2832             }
2833         }
2834     }
2835 }
2836 
2837 impl Method {
codegen_method( &self, ctx: &BindgenContext, methods: &mut Vec<proc_macro2::TokenStream>, method_names: &mut HashSet<String>, result: &mut CodegenResult<'_>, _parent: &CompInfo, )2838     fn codegen_method(
2839         &self,
2840         ctx: &BindgenContext,
2841         methods: &mut Vec<proc_macro2::TokenStream>,
2842         method_names: &mut HashSet<String>,
2843         result: &mut CodegenResult<'_>,
2844         _parent: &CompInfo,
2845     ) {
2846         assert!({
2847             let cc = &ctx.options().codegen_config;
2848             match self.kind() {
2849                 MethodKind::Constructor => cc.constructors(),
2850                 MethodKind::Destructor => cc.destructors(),
2851                 MethodKind::VirtualDestructor { .. } => cc.destructors(),
2852                 MethodKind::Static |
2853                 MethodKind::Normal |
2854                 MethodKind::Virtual { .. } => cc.methods(),
2855             }
2856         });
2857 
2858         // TODO(emilio): We could generate final stuff at least.
2859         if self.is_virtual() {
2860             return; // FIXME
2861         }
2862 
2863         // First of all, output the actual function.
2864         let function_item = ctx.resolve_item(self.signature());
2865         if !function_item.process_before_codegen(ctx, result) {
2866             return;
2867         }
2868         let function = function_item.expect_function();
2869         let times_seen = function.codegen(ctx, result, function_item);
2870         let times_seen = match times_seen {
2871             Some(seen) => seen,
2872             None => return,
2873         };
2874         let signature_item = ctx.resolve_item(function.signature());
2875         let mut name = match self.kind() {
2876             MethodKind::Constructor => "new".into(),
2877             MethodKind::Destructor => "destruct".into(),
2878             _ => function.name().to_owned(),
2879         };
2880 
2881         let signature = match *signature_item.expect_type().kind() {
2882             TypeKind::Function(ref sig) => sig,
2883             _ => panic!("How in the world?"),
2884         };
2885 
2886         let supported_abi = signature.abi(ctx, Some(&*name)).is_ok();
2887         if !supported_abi {
2888             return;
2889         }
2890 
2891         // Do not generate variadic methods, since rust does not allow
2892         // implementing them, and we don't do a good job at it anyway.
2893         if signature.is_variadic() {
2894             return;
2895         }
2896 
2897         if method_names.contains(&name) {
2898             let mut count = 1;
2899             let mut new_name;
2900 
2901             while {
2902                 new_name = format!("{}{}", name, count);
2903                 method_names.contains(&new_name)
2904             } {
2905                 count += 1;
2906             }
2907 
2908             name = new_name;
2909         }
2910 
2911         method_names.insert(name.clone());
2912 
2913         let mut function_name = function_item.canonical_name(ctx);
2914         if times_seen > 0 {
2915             write!(&mut function_name, "{}", times_seen).unwrap();
2916         }
2917         let function_name = ctx.rust_ident(function_name);
2918         let mut args = utils::fnsig_arguments(ctx, signature);
2919         let mut ret = utils::fnsig_return_ty(ctx, signature);
2920 
2921         if !self.is_static() && !self.is_constructor() {
2922             args[0] = if self.is_const() {
2923                 quote! { &self }
2924             } else {
2925                 quote! { &mut self }
2926             };
2927         }
2928 
2929         // If it's a constructor, we always return `Self`, and we inject the
2930         // "this" parameter, so there's no need to ask the user for it.
2931         //
2932         // Note that constructors in Clang are represented as functions with
2933         // return-type = void.
2934         if self.is_constructor() {
2935             args.remove(0);
2936             ret = quote! { -> Self };
2937         }
2938 
2939         let mut exprs =
2940             helpers::ast_ty::arguments_from_signature(signature, ctx);
2941 
2942         let mut stmts = vec![];
2943 
2944         // If it's a constructor, we need to insert an extra parameter with a
2945         // variable called `__bindgen_tmp` we're going to create.
2946         if self.is_constructor() {
2947             let prefix = ctx.trait_prefix();
2948             let tmp_variable_decl = if ctx
2949                 .options()
2950                 .rust_features()
2951                 .maybe_uninit
2952             {
2953                 exprs[0] = quote! {
2954                     __bindgen_tmp.as_mut_ptr()
2955                 };
2956                 quote! {
2957                     let mut __bindgen_tmp = ::#prefix::mem::MaybeUninit::uninit()
2958                 }
2959             } else {
2960                 exprs[0] = quote! {
2961                     &mut __bindgen_tmp
2962                 };
2963                 quote! {
2964                     let mut __bindgen_tmp = ::#prefix::mem::uninitialized()
2965                 }
2966             };
2967             stmts.push(tmp_variable_decl);
2968         } else if !self.is_static() {
2969             assert!(!exprs.is_empty());
2970             exprs[0] = quote! {
2971                 self
2972             };
2973         };
2974 
2975         let call = quote! {
2976             #function_name (#( #exprs ),* )
2977         };
2978 
2979         stmts.push(call);
2980 
2981         if self.is_constructor() {
2982             stmts.push(if ctx.options().rust_features().maybe_uninit {
2983                 quote! {
2984                     __bindgen_tmp.assume_init()
2985                 }
2986             } else {
2987                 quote! {
2988                     __bindgen_tmp
2989                 }
2990             })
2991         }
2992 
2993         let block = ctx.wrap_unsafe_ops(quote! ( #( #stmts );*));
2994 
2995         let mut attrs = vec![attributes::inline()];
2996 
2997         if signature.must_use() &&
2998             ctx.options().rust_features().must_use_function
2999         {
3000             attrs.push(attributes::must_use());
3001         }
3002 
3003         let name = ctx.rust_ident(&name);
3004         methods.push(quote! {
3005             #(#attrs)*
3006             pub unsafe fn #name ( #( #args ),* ) #ret {
3007                 #block
3008             }
3009         });
3010     }
3011 }
3012 
3013 /// A helper type that represents different enum variations.
3014 #[derive(Copy, Clone, PartialEq, Eq, Debug, Default)]
3015 pub enum EnumVariation {
3016     /// The code for this enum will use a Rust enum. Note that creating this in unsafe code
3017     /// (including FFI) with an invalid value will invoke undefined behaviour, whether or not
3018     /// its marked as non_exhaustive.
3019     Rust {
3020         /// Indicates whether the generated struct should be `#[non_exhaustive]`
3021         non_exhaustive: bool,
3022     },
3023     /// The code for this enum will use a newtype
3024     NewType {
3025         /// Indicates whether the newtype will have bitwise operators
3026         is_bitfield: bool,
3027         /// Indicates whether the variants will be represented as global constants
3028         is_global: bool,
3029     },
3030     /// The code for this enum will use consts
3031     #[default]
3032     Consts,
3033     /// The code for this enum will use a module containing consts
3034     ModuleConsts,
3035 }
3036 
3037 impl EnumVariation {
is_rust(&self) -> bool3038     fn is_rust(&self) -> bool {
3039         matches!(*self, EnumVariation::Rust { .. })
3040     }
3041 
3042     /// Both the `Const` and `ModuleConsts` variants will cause this to return
3043     /// true.
is_const(&self) -> bool3044     fn is_const(&self) -> bool {
3045         matches!(*self, EnumVariation::Consts | EnumVariation::ModuleConsts)
3046     }
3047 }
3048 
3049 impl fmt::Display for EnumVariation {
fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result3050     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
3051         let s = match self {
3052             Self::Rust {
3053                 non_exhaustive: false,
3054             } => "rust",
3055             Self::Rust {
3056                 non_exhaustive: true,
3057             } => "rust_non_exhaustive",
3058             Self::NewType {
3059                 is_bitfield: true, ..
3060             } => "bitfield",
3061             Self::NewType {
3062                 is_bitfield: false,
3063                 is_global,
3064             } => {
3065                 if *is_global {
3066                     "newtype_global"
3067                 } else {
3068                     "newtype"
3069                 }
3070             }
3071             Self::Consts => "consts",
3072             Self::ModuleConsts => "moduleconsts",
3073         };
3074         s.fmt(f)
3075     }
3076 }
3077 
3078 impl std::str::FromStr for EnumVariation {
3079     type Err = std::io::Error;
3080 
3081     /// Create a `EnumVariation` from a string.
from_str(s: &str) -> Result<Self, Self::Err>3082     fn from_str(s: &str) -> Result<Self, Self::Err> {
3083         match s {
3084             "rust" => Ok(EnumVariation::Rust {
3085                 non_exhaustive: false,
3086             }),
3087             "rust_non_exhaustive" => Ok(EnumVariation::Rust {
3088                 non_exhaustive: true,
3089             }),
3090             "bitfield" => Ok(EnumVariation::NewType {
3091                 is_bitfield: true,
3092                 is_global: false,
3093             }),
3094             "consts" => Ok(EnumVariation::Consts),
3095             "moduleconsts" => Ok(EnumVariation::ModuleConsts),
3096             "newtype" => Ok(EnumVariation::NewType {
3097                 is_bitfield: false,
3098                 is_global: false,
3099             }),
3100             "newtype_global" => Ok(EnumVariation::NewType {
3101                 is_bitfield: false,
3102                 is_global: true,
3103             }),
3104             _ => Err(std::io::Error::new(
3105                 std::io::ErrorKind::InvalidInput,
3106                 concat!(
3107                     "Got an invalid EnumVariation. Accepted values ",
3108                     "are 'rust', 'rust_non_exhaustive', 'bitfield', 'consts',",
3109                     "'moduleconsts', 'newtype' and 'newtype_global'."
3110                 ),
3111             )),
3112         }
3113     }
3114 }
3115 
3116 /// A helper type to construct different enum variations.
3117 enum EnumBuilder<'a> {
3118     Rust {
3119         attrs: Vec<proc_macro2::TokenStream>,
3120         ident: Ident,
3121         tokens: proc_macro2::TokenStream,
3122         emitted_any_variants: bool,
3123     },
3124     NewType {
3125         canonical_name: &'a str,
3126         tokens: proc_macro2::TokenStream,
3127         is_bitfield: bool,
3128         is_global: bool,
3129     },
3130     Consts {
3131         variants: Vec<proc_macro2::TokenStream>,
3132     },
3133     ModuleConsts {
3134         module_name: &'a str,
3135         module_items: Vec<proc_macro2::TokenStream>,
3136     },
3137 }
3138 
3139 impl<'a> EnumBuilder<'a> {
3140     /// Returns true if the builder is for a rustified enum.
is_rust_enum(&self) -> bool3141     fn is_rust_enum(&self) -> bool {
3142         matches!(*self, EnumBuilder::Rust { .. })
3143     }
3144 
3145     /// Create a new enum given an item builder, a canonical name, a name for
3146     /// the representation, and which variation it should be generated as.
new( name: &'a str, mut attrs: Vec<proc_macro2::TokenStream>, repr: syn::Type, enum_variation: EnumVariation, has_typedef: bool, ) -> Self3147     fn new(
3148         name: &'a str,
3149         mut attrs: Vec<proc_macro2::TokenStream>,
3150         repr: syn::Type,
3151         enum_variation: EnumVariation,
3152         has_typedef: bool,
3153     ) -> Self {
3154         let ident = Ident::new(name, Span::call_site());
3155 
3156         match enum_variation {
3157             EnumVariation::NewType {
3158                 is_bitfield,
3159                 is_global,
3160             } => EnumBuilder::NewType {
3161                 canonical_name: name,
3162                 tokens: quote! {
3163                     #( #attrs )*
3164                     pub struct #ident (pub #repr);
3165                 },
3166                 is_bitfield,
3167                 is_global,
3168             },
3169 
3170             EnumVariation::Rust { .. } => {
3171                 // `repr` is guaranteed to be Rustified in Enum::codegen
3172                 attrs.insert(0, quote! { #[repr( #repr )] });
3173                 let tokens = quote!();
3174                 EnumBuilder::Rust {
3175                     attrs,
3176                     ident,
3177                     tokens,
3178                     emitted_any_variants: false,
3179                 }
3180             }
3181 
3182             EnumVariation::Consts => {
3183                 let mut variants = Vec::new();
3184 
3185                 if !has_typedef {
3186                     variants.push(quote! {
3187                         #( #attrs )*
3188                         pub type #ident = #repr;
3189                     });
3190                 }
3191 
3192                 EnumBuilder::Consts { variants }
3193             }
3194 
3195             EnumVariation::ModuleConsts => {
3196                 let ident = Ident::new(
3197                     CONSTIFIED_ENUM_MODULE_REPR_NAME,
3198                     Span::call_site(),
3199                 );
3200                 let type_definition = quote! {
3201                     #( #attrs )*
3202                     pub type #ident = #repr;
3203                 };
3204 
3205                 EnumBuilder::ModuleConsts {
3206                     module_name: name,
3207                     module_items: vec![type_definition],
3208                 }
3209             }
3210         }
3211     }
3212 
3213     /// Add a variant to this enum.
with_variant( self, ctx: &BindgenContext, variant: &EnumVariant, mangling_prefix: Option<&str>, rust_ty: syn::Type, result: &mut CodegenResult<'_>, is_ty_named: bool, ) -> Self3214     fn with_variant(
3215         self,
3216         ctx: &BindgenContext,
3217         variant: &EnumVariant,
3218         mangling_prefix: Option<&str>,
3219         rust_ty: syn::Type,
3220         result: &mut CodegenResult<'_>,
3221         is_ty_named: bool,
3222     ) -> Self {
3223         let variant_name = ctx.rust_mangle(variant.name());
3224         let is_rust_enum = self.is_rust_enum();
3225         let expr = match variant.val() {
3226             EnumVariantValue::Boolean(v) if is_rust_enum => {
3227                 helpers::ast_ty::uint_expr(v as u64)
3228             }
3229             EnumVariantValue::Boolean(v) => quote!(#v),
3230             EnumVariantValue::Signed(v) => helpers::ast_ty::int_expr(v),
3231             EnumVariantValue::Unsigned(v) => helpers::ast_ty::uint_expr(v),
3232         };
3233 
3234         let mut doc = quote! {};
3235         if ctx.options().generate_comments {
3236             if let Some(raw_comment) = variant.comment() {
3237                 let comment = ctx.options().process_comment(raw_comment);
3238                 doc = attributes::doc(comment);
3239             }
3240         }
3241 
3242         match self {
3243             EnumBuilder::Rust {
3244                 attrs,
3245                 ident,
3246                 tokens,
3247                 emitted_any_variants: _,
3248             } => {
3249                 let name = ctx.rust_ident(variant_name);
3250                 EnumBuilder::Rust {
3251                     attrs,
3252                     ident,
3253                     tokens: quote! {
3254                         #tokens
3255                         #doc
3256                         #name = #expr,
3257                     },
3258                     emitted_any_variants: true,
3259                 }
3260             }
3261 
3262             EnumBuilder::NewType {
3263                 canonical_name,
3264                 is_global,
3265                 ..
3266             } => {
3267                 if ctx.options().rust_features().associated_const &&
3268                     is_ty_named &&
3269                     !is_global
3270                 {
3271                     let enum_ident = ctx.rust_ident(canonical_name);
3272                     let variant_ident = ctx.rust_ident(variant_name);
3273 
3274                     result.push(quote! {
3275                         impl #enum_ident {
3276                             #doc
3277                             pub const #variant_ident : #rust_ty = #rust_ty ( #expr );
3278                         }
3279                     });
3280                 } else {
3281                     let ident = ctx.rust_ident(match mangling_prefix {
3282                         Some(prefix) => {
3283                             Cow::Owned(format!("{}_{}", prefix, variant_name))
3284                         }
3285                         None => variant_name,
3286                     });
3287                     result.push(quote! {
3288                         #doc
3289                         pub const #ident : #rust_ty = #rust_ty ( #expr );
3290                     });
3291                 }
3292 
3293                 self
3294             }
3295 
3296             EnumBuilder::Consts { .. } => {
3297                 let constant_name = match mangling_prefix {
3298                     Some(prefix) => {
3299                         Cow::Owned(format!("{}_{}", prefix, variant_name))
3300                     }
3301                     None => variant_name,
3302                 };
3303 
3304                 let ident = ctx.rust_ident(constant_name);
3305                 result.push(quote! {
3306                     #doc
3307                     pub const #ident : #rust_ty = #expr ;
3308                 });
3309 
3310                 self
3311             }
3312             EnumBuilder::ModuleConsts {
3313                 module_name,
3314                 mut module_items,
3315             } => {
3316                 let name = ctx.rust_ident(variant_name);
3317                 let ty = ctx.rust_ident(CONSTIFIED_ENUM_MODULE_REPR_NAME);
3318                 module_items.push(quote! {
3319                     #doc
3320                     pub const #name : #ty = #expr ;
3321                 });
3322 
3323                 EnumBuilder::ModuleConsts {
3324                     module_name,
3325                     module_items,
3326                 }
3327             }
3328         }
3329     }
3330 
build( self, ctx: &BindgenContext, rust_ty: syn::Type, result: &mut CodegenResult<'_>, ) -> proc_macro2::TokenStream3331     fn build(
3332         self,
3333         ctx: &BindgenContext,
3334         rust_ty: syn::Type,
3335         result: &mut CodegenResult<'_>,
3336     ) -> proc_macro2::TokenStream {
3337         match self {
3338             EnumBuilder::Rust {
3339                 attrs,
3340                 ident,
3341                 tokens,
3342                 emitted_any_variants,
3343                 ..
3344             } => {
3345                 let variants = if !emitted_any_variants {
3346                     quote!(__bindgen_cannot_repr_c_on_empty_enum = 0)
3347                 } else {
3348                     tokens
3349                 };
3350 
3351                 quote! {
3352                     #( #attrs )*
3353                     pub enum #ident {
3354                         #variants
3355                     }
3356                 }
3357             }
3358             EnumBuilder::NewType {
3359                 canonical_name,
3360                 tokens,
3361                 is_bitfield,
3362                 ..
3363             } => {
3364                 if !is_bitfield {
3365                     return tokens;
3366                 }
3367 
3368                 let rust_ty_name = ctx.rust_ident_raw(canonical_name);
3369                 let prefix = ctx.trait_prefix();
3370 
3371                 result.push(quote! {
3372                     impl ::#prefix::ops::BitOr<#rust_ty> for #rust_ty {
3373                         type Output = Self;
3374 
3375                         #[inline]
3376                         fn bitor(self, other: Self) -> Self {
3377                             #rust_ty_name(self.0 | other.0)
3378                         }
3379                     }
3380                 });
3381 
3382                 result.push(quote! {
3383                     impl ::#prefix::ops::BitOrAssign for #rust_ty {
3384                         #[inline]
3385                         fn bitor_assign(&mut self, rhs: #rust_ty) {
3386                             self.0 |= rhs.0;
3387                         }
3388                     }
3389                 });
3390 
3391                 result.push(quote! {
3392                     impl ::#prefix::ops::BitAnd<#rust_ty> for #rust_ty {
3393                         type Output = Self;
3394 
3395                         #[inline]
3396                         fn bitand(self, other: Self) -> Self {
3397                             #rust_ty_name(self.0 & other.0)
3398                         }
3399                     }
3400                 });
3401 
3402                 result.push(quote! {
3403                     impl ::#prefix::ops::BitAndAssign for #rust_ty {
3404                         #[inline]
3405                         fn bitand_assign(&mut self, rhs: #rust_ty) {
3406                             self.0 &= rhs.0;
3407                         }
3408                     }
3409                 });
3410 
3411                 tokens
3412             }
3413             EnumBuilder::Consts { variants, .. } => quote! { #( #variants )* },
3414             EnumBuilder::ModuleConsts {
3415                 module_items,
3416                 module_name,
3417                 ..
3418             } => {
3419                 let ident = ctx.rust_ident(module_name);
3420                 quote! {
3421                     pub mod #ident {
3422                         #( #module_items )*
3423                     }
3424                 }
3425             }
3426         }
3427     }
3428 }
3429 
3430 impl CodeGenerator for Enum {
3431     type Extra = Item;
3432     type Return = ();
3433 
codegen( &self, ctx: &BindgenContext, result: &mut CodegenResult<'_>, item: &Item, )3434     fn codegen(
3435         &self,
3436         ctx: &BindgenContext,
3437         result: &mut CodegenResult<'_>,
3438         item: &Item,
3439     ) {
3440         debug!("<Enum as CodeGenerator>::codegen: item = {:?}", item);
3441         debug_assert!(item.is_enabled_for_codegen(ctx));
3442 
3443         let name = item.canonical_name(ctx);
3444         let ident = ctx.rust_ident(&name);
3445         let enum_ty = item.expect_type();
3446         let layout = enum_ty.layout(ctx);
3447         let variation = self.computed_enum_variation(ctx, item);
3448 
3449         let repr_translated;
3450         let repr = match self.repr().map(|repr| ctx.resolve_type(repr)) {
3451             Some(repr)
3452                 if !ctx.options().translate_enum_integer_types &&
3453                     !variation.is_rust() =>
3454             {
3455                 repr
3456             }
3457             repr => {
3458                 // An enum's integer type is translated to a native Rust
3459                 // integer type in 3 cases:
3460                 // * the enum is Rustified and we need a translated type for
3461                 //   the repr attribute
3462                 // * the representation couldn't be determined from the C source
3463                 // * it was explicitly requested as a bindgen option
3464 
3465                 let kind = match repr {
3466                     Some(repr) => match *repr.canonical_type(ctx).kind() {
3467                         TypeKind::Int(int_kind) => int_kind,
3468                         _ => panic!("Unexpected type as enum repr"),
3469                     },
3470                     None => {
3471                         warn!(
3472                             "Guessing type of enum! Forward declarations of enums \
3473                              shouldn't be legal!"
3474                         );
3475                         IntKind::Int
3476                     }
3477                 };
3478 
3479                 let signed = kind.is_signed();
3480                 let size = layout
3481                     .map(|l| l.size)
3482                     .or_else(|| kind.known_size())
3483                     .unwrap_or(0);
3484 
3485                 let translated = match (signed, size) {
3486                     (true, 1) => IntKind::I8,
3487                     (false, 1) => IntKind::U8,
3488                     (true, 2) => IntKind::I16,
3489                     (false, 2) => IntKind::U16,
3490                     (true, 4) => IntKind::I32,
3491                     (false, 4) => IntKind::U32,
3492                     (true, 8) => IntKind::I64,
3493                     (false, 8) => IntKind::U64,
3494                     _ => {
3495                         warn!(
3496                             "invalid enum decl: signed: {}, size: {}",
3497                             signed, size
3498                         );
3499                         IntKind::I32
3500                     }
3501                 };
3502 
3503                 repr_translated =
3504                     Type::new(None, None, TypeKind::Int(translated), false);
3505                 &repr_translated
3506             }
3507         };
3508 
3509         let mut attrs = vec![];
3510 
3511         // TODO(emilio): Delegate this to the builders?
3512         match variation {
3513             EnumVariation::Rust { non_exhaustive } => {
3514                 if non_exhaustive &&
3515                     ctx.options().rust_features().non_exhaustive
3516                 {
3517                     attrs.push(attributes::non_exhaustive());
3518                 } else if non_exhaustive &&
3519                     !ctx.options().rust_features().non_exhaustive
3520                 {
3521                     panic!("The rust target you're using doesn't seem to support non_exhaustive enums");
3522                 }
3523             }
3524             EnumVariation::NewType { .. } => {
3525                 if ctx.options().rust_features.repr_transparent {
3526                     attrs.push(attributes::repr("transparent"));
3527                 } else {
3528                     attrs.push(attributes::repr("C"));
3529                 }
3530             }
3531             _ => {}
3532         };
3533 
3534         if let Some(comment) = item.comment(ctx) {
3535             attrs.push(attributes::doc(comment));
3536         }
3537 
3538         if item.must_use(ctx) {
3539             attrs.push(attributes::must_use());
3540         }
3541 
3542         if !variation.is_const() {
3543             let packed = false; // Enums can't be packed in Rust.
3544             let mut derives = derives_of_item(item, ctx, packed);
3545             // For backwards compat, enums always derive
3546             // Clone/Eq/PartialEq/Hash, even if we don't generate those by
3547             // default.
3548             derives.insert(
3549                 DerivableTraits::CLONE |
3550                     DerivableTraits::HASH |
3551                     DerivableTraits::PARTIAL_EQ |
3552                     DerivableTraits::EQ,
3553             );
3554             let mut derives: Vec<_> = derives.into();
3555             for derive in item.annotations().derives().iter() {
3556                 if !derives.contains(&derive.as_str()) {
3557                     derives.push(derive);
3558                 }
3559             }
3560 
3561             // The custom derives callback may return a list of derive attributes;
3562             // add them to the end of the list.
3563             let custom_derives = ctx.options().all_callbacks(|cb| {
3564                 cb.add_derives(&DeriveInfo {
3565                     name: &name,
3566                     kind: DeriveTypeKind::Enum,
3567                 })
3568             });
3569             // In most cases this will be a no-op, since custom_derives will be empty.
3570             derives.extend(custom_derives.iter().map(|s| s.as_str()));
3571 
3572             attrs.push(attributes::derives(&derives));
3573         }
3574 
3575         fn add_constant(
3576             ctx: &BindgenContext,
3577             enum_: &Type,
3578             // Only to avoid recomputing every time.
3579             enum_canonical_name: &Ident,
3580             // May be the same as "variant" if it's because the
3581             // enum is unnamed and we still haven't seen the
3582             // value.
3583             variant_name: &Ident,
3584             referenced_name: &Ident,
3585             enum_rust_ty: syn::Type,
3586             result: &mut CodegenResult<'_>,
3587         ) {
3588             let constant_name = if enum_.name().is_some() {
3589                 if ctx.options().prepend_enum_name {
3590                     format!("{}_{}", enum_canonical_name, variant_name)
3591                 } else {
3592                     format!("{}", variant_name)
3593                 }
3594             } else {
3595                 format!("{}", variant_name)
3596             };
3597             let constant_name = ctx.rust_ident(constant_name);
3598 
3599             result.push(quote! {
3600                 pub const #constant_name : #enum_rust_ty =
3601                     #enum_canonical_name :: #referenced_name ;
3602             });
3603         }
3604 
3605         let repr = repr.to_rust_ty_or_opaque(ctx, item);
3606         let has_typedef = ctx.is_enum_typedef_combo(item.id());
3607 
3608         let mut builder =
3609             EnumBuilder::new(&name, attrs, repr, variation, has_typedef);
3610 
3611         // A map where we keep a value -> variant relation.
3612         let mut seen_values = HashMap::<_, Ident>::default();
3613         let enum_rust_ty = item.to_rust_ty_or_opaque(ctx, &());
3614         let is_toplevel = item.is_toplevel(ctx);
3615 
3616         // Used to mangle the constants we generate in the unnamed-enum case.
3617         let parent_canonical_name = if is_toplevel {
3618             None
3619         } else {
3620             Some(item.parent_id().canonical_name(ctx))
3621         };
3622 
3623         let constant_mangling_prefix = if ctx.options().prepend_enum_name {
3624             if enum_ty.name().is_none() {
3625                 parent_canonical_name.as_deref()
3626             } else {
3627                 Some(&*name)
3628             }
3629         } else {
3630             None
3631         };
3632 
3633         // NB: We defer the creation of constified variants, in case we find
3634         // another variant with the same value (which is the common thing to
3635         // do).
3636         let mut constified_variants = VecDeque::new();
3637 
3638         let mut iter = self.variants().iter().peekable();
3639         while let Some(variant) =
3640             iter.next().or_else(|| constified_variants.pop_front())
3641         {
3642             if variant.hidden() {
3643                 continue;
3644             }
3645 
3646             if variant.force_constification() && iter.peek().is_some() {
3647                 constified_variants.push_back(variant);
3648                 continue;
3649             }
3650 
3651             match seen_values.entry(variant.val()) {
3652                 Entry::Occupied(ref entry) => {
3653                     if variation.is_rust() {
3654                         let variant_name = ctx.rust_mangle(variant.name());
3655                         let mangled_name =
3656                             if is_toplevel || enum_ty.name().is_some() {
3657                                 variant_name
3658                             } else {
3659                                 let parent_name =
3660                                     parent_canonical_name.as_ref().unwrap();
3661 
3662                                 Cow::Owned(format!(
3663                                     "{}_{}",
3664                                     parent_name, variant_name
3665                                 ))
3666                             };
3667 
3668                         let existing_variant_name = entry.get();
3669                         // Use associated constants for named enums.
3670                         if enum_ty.name().is_some() &&
3671                             ctx.options().rust_features().associated_const
3672                         {
3673                             let enum_canonical_name = &ident;
3674                             let variant_name =
3675                                 ctx.rust_ident_raw(&*mangled_name);
3676                             result.push(quote! {
3677                                 impl #enum_rust_ty {
3678                                     pub const #variant_name : #enum_rust_ty =
3679                                         #enum_canonical_name :: #existing_variant_name ;
3680                                 }
3681                             });
3682                         } else {
3683                             add_constant(
3684                                 ctx,
3685                                 enum_ty,
3686                                 &ident,
3687                                 &Ident::new(&mangled_name, Span::call_site()),
3688                                 existing_variant_name,
3689                                 enum_rust_ty.clone(),
3690                                 result,
3691                             );
3692                         }
3693                     } else {
3694                         builder = builder.with_variant(
3695                             ctx,
3696                             variant,
3697                             constant_mangling_prefix,
3698                             enum_rust_ty.clone(),
3699                             result,
3700                             enum_ty.name().is_some(),
3701                         );
3702                     }
3703                 }
3704                 Entry::Vacant(entry) => {
3705                     builder = builder.with_variant(
3706                         ctx,
3707                         variant,
3708                         constant_mangling_prefix,
3709                         enum_rust_ty.clone(),
3710                         result,
3711                         enum_ty.name().is_some(),
3712                     );
3713 
3714                     let variant_name = ctx.rust_ident(variant.name());
3715 
3716                     // If it's an unnamed enum, or constification is enforced,
3717                     // we also generate a constant so it can be properly
3718                     // accessed.
3719                     if (variation.is_rust() && enum_ty.name().is_none()) ||
3720                         variant.force_constification()
3721                     {
3722                         let mangled_name = if is_toplevel {
3723                             variant_name.clone()
3724                         } else {
3725                             let parent_name =
3726                                 parent_canonical_name.as_ref().unwrap();
3727 
3728                             Ident::new(
3729                                 &format!("{}_{}", parent_name, variant_name),
3730                                 Span::call_site(),
3731                             )
3732                         };
3733 
3734                         add_constant(
3735                             ctx,
3736                             enum_ty,
3737                             &ident,
3738                             &mangled_name,
3739                             &variant_name,
3740                             enum_rust_ty.clone(),
3741                             result,
3742                         );
3743                     }
3744 
3745                     entry.insert(variant_name);
3746                 }
3747             }
3748         }
3749 
3750         let item = builder.build(ctx, enum_rust_ty, result);
3751         result.push(item);
3752     }
3753 }
3754 
3755 /// Enum for the default type of macro constants.
3756 #[derive(Copy, Clone, PartialEq, Eq, Debug, Default)]
3757 pub enum MacroTypeVariation {
3758     /// Use i32 or i64
3759     Signed,
3760     /// Use u32 or u64
3761     #[default]
3762     Unsigned,
3763 }
3764 
3765 impl fmt::Display for MacroTypeVariation {
fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result3766     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
3767         let s = match self {
3768             Self::Signed => "signed",
3769             Self::Unsigned => "unsigned",
3770         };
3771         s.fmt(f)
3772     }
3773 }
3774 
3775 impl std::str::FromStr for MacroTypeVariation {
3776     type Err = std::io::Error;
3777 
3778     /// Create a `MacroTypeVariation` from a string.
from_str(s: &str) -> Result<Self, Self::Err>3779     fn from_str(s: &str) -> Result<Self, Self::Err> {
3780         match s {
3781             "signed" => Ok(MacroTypeVariation::Signed),
3782             "unsigned" => Ok(MacroTypeVariation::Unsigned),
3783             _ => Err(std::io::Error::new(
3784                 std::io::ErrorKind::InvalidInput,
3785                 concat!(
3786                     "Got an invalid MacroTypeVariation. Accepted values ",
3787                     "are 'signed' and 'unsigned'"
3788                 ),
3789             )),
3790         }
3791     }
3792 }
3793 
3794 /// Enum for how aliases should be translated.
3795 #[derive(Copy, Clone, PartialEq, Eq, Debug, Default)]
3796 pub enum AliasVariation {
3797     /// Convert to regular Rust alias
3798     #[default]
3799     TypeAlias,
3800     /// Create a new type by wrapping the old type in a struct and using #[repr(transparent)]
3801     NewType,
3802     /// Same as NewStruct but also impl Deref to be able to use the methods of the wrapped type
3803     NewTypeDeref,
3804 }
3805 
3806 impl fmt::Display for AliasVariation {
fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result3807     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
3808         let s = match self {
3809             Self::TypeAlias => "type_alias",
3810             Self::NewType => "new_type",
3811             Self::NewTypeDeref => "new_type_deref",
3812         };
3813 
3814         s.fmt(f)
3815     }
3816 }
3817 
3818 impl std::str::FromStr for AliasVariation {
3819     type Err = std::io::Error;
3820 
3821     /// Create an `AliasVariation` from a string.
from_str(s: &str) -> Result<Self, Self::Err>3822     fn from_str(s: &str) -> Result<Self, Self::Err> {
3823         match s {
3824             "type_alias" => Ok(AliasVariation::TypeAlias),
3825             "new_type" => Ok(AliasVariation::NewType),
3826             "new_type_deref" => Ok(AliasVariation::NewTypeDeref),
3827             _ => Err(std::io::Error::new(
3828                 std::io::ErrorKind::InvalidInput,
3829                 concat!(
3830                     "Got an invalid AliasVariation. Accepted values ",
3831                     "are 'type_alias', 'new_type', and 'new_type_deref'"
3832                 ),
3833             )),
3834         }
3835     }
3836 }
3837 
3838 /// Enum for how non-`Copy` `union`s should be translated.
3839 #[derive(Copy, Clone, PartialEq, Eq, Debug)]
3840 pub enum NonCopyUnionStyle {
3841     /// Wrap members in a type generated by `bindgen`.
3842     BindgenWrapper,
3843     /// Wrap members in [`::core::mem::ManuallyDrop`].
3844     ///
3845     /// Note: `ManuallyDrop` was stabilized in Rust 1.20.0, do not use it if your
3846     /// MSRV is lower.
3847     ManuallyDrop,
3848 }
3849 
3850 impl fmt::Display for NonCopyUnionStyle {
fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result3851     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
3852         let s = match self {
3853             Self::BindgenWrapper => "bindgen_wrapper",
3854             Self::ManuallyDrop => "manually_drop",
3855         };
3856 
3857         s.fmt(f)
3858     }
3859 }
3860 
3861 impl Default for NonCopyUnionStyle {
default() -> Self3862     fn default() -> Self {
3863         Self::BindgenWrapper
3864     }
3865 }
3866 
3867 impl std::str::FromStr for NonCopyUnionStyle {
3868     type Err = std::io::Error;
3869 
from_str(s: &str) -> Result<Self, Self::Err>3870     fn from_str(s: &str) -> Result<Self, Self::Err> {
3871         match s {
3872             "bindgen_wrapper" => Ok(Self::BindgenWrapper),
3873             "manually_drop" => Ok(Self::ManuallyDrop),
3874             _ => Err(std::io::Error::new(
3875                 std::io::ErrorKind::InvalidInput,
3876                 concat!(
3877                     "Got an invalid NonCopyUnionStyle. Accepted values ",
3878                     "are 'bindgen_wrapper' and 'manually_drop'"
3879                 ),
3880             )),
3881         }
3882     }
3883 }
3884 
3885 /// Fallible conversion to an opaque blob.
3886 ///
3887 /// Implementors of this trait should provide the `try_get_layout` method to
3888 /// fallibly get this thing's layout, which the provided `try_to_opaque` trait
3889 /// method will use to convert the `Layout` into an opaque blob Rust type.
3890 pub(crate) trait TryToOpaque {
3891     type Extra;
3892 
3893     /// Get the layout for this thing, if one is available.
try_get_layout( &self, ctx: &BindgenContext, extra: &Self::Extra, ) -> error::Result<Layout>3894     fn try_get_layout(
3895         &self,
3896         ctx: &BindgenContext,
3897         extra: &Self::Extra,
3898     ) -> error::Result<Layout>;
3899 
3900     /// Do not override this provided trait method.
try_to_opaque( &self, ctx: &BindgenContext, extra: &Self::Extra, ) -> error::Result<syn::Type>3901     fn try_to_opaque(
3902         &self,
3903         ctx: &BindgenContext,
3904         extra: &Self::Extra,
3905     ) -> error::Result<syn::Type> {
3906         self.try_get_layout(ctx, extra)
3907             .map(|layout| helpers::blob(ctx, layout))
3908     }
3909 }
3910 
3911 /// Infallible conversion of an IR thing to an opaque blob.
3912 ///
3913 /// The resulting layout is best effort, and is unfortunately not guaranteed to
3914 /// be correct. When all else fails, we fall back to a single byte layout as a
3915 /// last resort, because C++ does not permit zero-sized types. See the note in
3916 /// the `ToRustTyOrOpaque` doc comment about fallible versus infallible traits
3917 /// and when each is appropriate.
3918 ///
3919 /// Don't implement this directly. Instead implement `TryToOpaque`, and then
3920 /// leverage the blanket impl for this trait.
3921 pub(crate) trait ToOpaque: TryToOpaque {
get_layout(&self, ctx: &BindgenContext, extra: &Self::Extra) -> Layout3922     fn get_layout(&self, ctx: &BindgenContext, extra: &Self::Extra) -> Layout {
3923         self.try_get_layout(ctx, extra)
3924             .unwrap_or_else(|_| Layout::for_size(ctx, 1))
3925     }
3926 
to_opaque( &self, ctx: &BindgenContext, extra: &Self::Extra, ) -> syn::Type3927     fn to_opaque(
3928         &self,
3929         ctx: &BindgenContext,
3930         extra: &Self::Extra,
3931     ) -> syn::Type {
3932         let layout = self.get_layout(ctx, extra);
3933         helpers::blob(ctx, layout)
3934     }
3935 }
3936 
3937 impl<T> ToOpaque for T where T: TryToOpaque {}
3938 
3939 /// Fallible conversion from an IR thing to an *equivalent* Rust type.
3940 ///
3941 /// If the C/C++ construct represented by the IR thing cannot (currently) be
3942 /// represented in Rust (for example, instantiations of templates with
3943 /// const-value generic parameters) then the impl should return an `Err`. It
3944 /// should *not* attempt to return an opaque blob with the correct size and
3945 /// alignment. That is the responsibility of the `TryToOpaque` trait.
3946 pub(crate) trait TryToRustTy {
3947     type Extra;
3948 
try_to_rust_ty( &self, ctx: &BindgenContext, extra: &Self::Extra, ) -> error::Result<syn::Type>3949     fn try_to_rust_ty(
3950         &self,
3951         ctx: &BindgenContext,
3952         extra: &Self::Extra,
3953     ) -> error::Result<syn::Type>;
3954 }
3955 
3956 /// Fallible conversion to a Rust type or an opaque blob with the correct size
3957 /// and alignment.
3958 ///
3959 /// Don't implement this directly. Instead implement `TryToRustTy` and
3960 /// `TryToOpaque`, and then leverage the blanket impl for this trait below.
3961 pub(crate) trait TryToRustTyOrOpaque: TryToRustTy + TryToOpaque {
3962     type Extra;
3963 
try_to_rust_ty_or_opaque( &self, ctx: &BindgenContext, extra: &<Self as TryToRustTyOrOpaque>::Extra, ) -> error::Result<syn::Type>3964     fn try_to_rust_ty_or_opaque(
3965         &self,
3966         ctx: &BindgenContext,
3967         extra: &<Self as TryToRustTyOrOpaque>::Extra,
3968     ) -> error::Result<syn::Type>;
3969 }
3970 
3971 impl<E, T> TryToRustTyOrOpaque for T
3972 where
3973     T: TryToRustTy<Extra = E> + TryToOpaque<Extra = E>,
3974 {
3975     type Extra = E;
3976 
try_to_rust_ty_or_opaque( &self, ctx: &BindgenContext, extra: &E, ) -> error::Result<syn::Type>3977     fn try_to_rust_ty_or_opaque(
3978         &self,
3979         ctx: &BindgenContext,
3980         extra: &E,
3981     ) -> error::Result<syn::Type> {
3982         self.try_to_rust_ty(ctx, extra).or_else(|_| {
3983             if let Ok(layout) = self.try_get_layout(ctx, extra) {
3984                 Ok(helpers::blob(ctx, layout))
3985             } else {
3986                 Err(error::Error::NoLayoutForOpaqueBlob)
3987             }
3988         })
3989     }
3990 }
3991 
3992 /// Infallible conversion to a Rust type, or an opaque blob with a best effort
3993 /// of correct size and alignment.
3994 ///
3995 /// Don't implement this directly. Instead implement `TryToRustTy` and
3996 /// `TryToOpaque`, and then leverage the blanket impl for this trait below.
3997 ///
3998 /// ### Fallible vs. Infallible Conversions to Rust Types
3999 ///
4000 /// When should one use this infallible `ToRustTyOrOpaque` trait versus the
4001 /// fallible `TryTo{RustTy, Opaque, RustTyOrOpaque}` triats? All fallible trait
4002 /// implementations that need to convert another thing into a Rust type or
4003 /// opaque blob in a nested manner should also use fallible trait methods and
4004 /// propagate failure up the stack. Only infallible functions and methods like
4005 /// CodeGenerator implementations should use the infallible
4006 /// `ToRustTyOrOpaque`. The further out we push error recovery, the more likely
4007 /// we are to get a usable `Layout` even if we can't generate an equivalent Rust
4008 /// type for a C++ construct.
4009 pub(crate) trait ToRustTyOrOpaque: TryToRustTy + ToOpaque {
4010     type Extra;
4011 
to_rust_ty_or_opaque( &self, ctx: &BindgenContext, extra: &<Self as ToRustTyOrOpaque>::Extra, ) -> syn::Type4012     fn to_rust_ty_or_opaque(
4013         &self,
4014         ctx: &BindgenContext,
4015         extra: &<Self as ToRustTyOrOpaque>::Extra,
4016     ) -> syn::Type;
4017 }
4018 
4019 impl<E, T> ToRustTyOrOpaque for T
4020 where
4021     T: TryToRustTy<Extra = E> + ToOpaque<Extra = E>,
4022 {
4023     type Extra = E;
4024 
to_rust_ty_or_opaque( &self, ctx: &BindgenContext, extra: &E, ) -> syn::Type4025     fn to_rust_ty_or_opaque(
4026         &self,
4027         ctx: &BindgenContext,
4028         extra: &E,
4029     ) -> syn::Type {
4030         self.try_to_rust_ty(ctx, extra)
4031             .unwrap_or_else(|_| self.to_opaque(ctx, extra))
4032     }
4033 }
4034 
4035 impl<T> TryToOpaque for T
4036 where
4037     T: Copy + Into<ItemId>,
4038 {
4039     type Extra = ();
4040 
try_get_layout( &self, ctx: &BindgenContext, _: &(), ) -> error::Result<Layout>4041     fn try_get_layout(
4042         &self,
4043         ctx: &BindgenContext,
4044         _: &(),
4045     ) -> error::Result<Layout> {
4046         ctx.resolve_item((*self).into()).try_get_layout(ctx, &())
4047     }
4048 }
4049 
4050 impl<T> TryToRustTy for T
4051 where
4052     T: Copy + Into<ItemId>,
4053 {
4054     type Extra = ();
4055 
try_to_rust_ty( &self, ctx: &BindgenContext, _: &(), ) -> error::Result<syn::Type>4056     fn try_to_rust_ty(
4057         &self,
4058         ctx: &BindgenContext,
4059         _: &(),
4060     ) -> error::Result<syn::Type> {
4061         ctx.resolve_item((*self).into()).try_to_rust_ty(ctx, &())
4062     }
4063 }
4064 
4065 impl TryToOpaque for Item {
4066     type Extra = ();
4067 
try_get_layout( &self, ctx: &BindgenContext, _: &(), ) -> error::Result<Layout>4068     fn try_get_layout(
4069         &self,
4070         ctx: &BindgenContext,
4071         _: &(),
4072     ) -> error::Result<Layout> {
4073         self.kind().expect_type().try_get_layout(ctx, self)
4074     }
4075 }
4076 
4077 impl TryToRustTy for Item {
4078     type Extra = ();
4079 
try_to_rust_ty( &self, ctx: &BindgenContext, _: &(), ) -> error::Result<syn::Type>4080     fn try_to_rust_ty(
4081         &self,
4082         ctx: &BindgenContext,
4083         _: &(),
4084     ) -> error::Result<syn::Type> {
4085         self.kind().expect_type().try_to_rust_ty(ctx, self)
4086     }
4087 }
4088 
4089 impl TryToOpaque for Type {
4090     type Extra = Item;
4091 
try_get_layout( &self, ctx: &BindgenContext, _: &Item, ) -> error::Result<Layout>4092     fn try_get_layout(
4093         &self,
4094         ctx: &BindgenContext,
4095         _: &Item,
4096     ) -> error::Result<Layout> {
4097         self.layout(ctx).ok_or(error::Error::NoLayoutForOpaqueBlob)
4098     }
4099 }
4100 
4101 impl TryToRustTy for Type {
4102     type Extra = Item;
4103 
try_to_rust_ty( &self, ctx: &BindgenContext, item: &Item, ) -> error::Result<syn::Type>4104     fn try_to_rust_ty(
4105         &self,
4106         ctx: &BindgenContext,
4107         item: &Item,
4108     ) -> error::Result<syn::Type> {
4109         use self::helpers::ast_ty::*;
4110 
4111         match *self.kind() {
4112             TypeKind::Void => Ok(c_void(ctx)),
4113             // TODO: we should do something smart with nullptr, or maybe *const
4114             // c_void is enough?
4115             TypeKind::NullPtr => Ok(c_void(ctx).to_ptr(true)),
4116             TypeKind::Int(ik) => {
4117                 Ok(int_kind_rust_type(ctx, ik, self.layout(ctx)))
4118             }
4119             TypeKind::Float(fk) => {
4120                 Ok(float_kind_rust_type(ctx, fk, self.layout(ctx)))
4121             }
4122             TypeKind::Complex(fk) => {
4123                 let float_path =
4124                     float_kind_rust_type(ctx, fk, self.layout(ctx));
4125 
4126                 ctx.generated_bindgen_complex();
4127                 Ok(if ctx.options().enable_cxx_namespaces {
4128                     syn::parse_quote! { root::__BindgenComplex<#float_path> }
4129                 } else {
4130                     syn::parse_quote! { __BindgenComplex<#float_path> }
4131                 })
4132             }
4133             TypeKind::Function(ref signature) => {
4134                 // We can't rely on the sizeof(Option<NonZero<_>>) ==
4135                 // sizeof(NonZero<_>) optimization with opaque blobs (because
4136                 // they aren't NonZero), so don't *ever* use an or_opaque
4137                 // variant here.
4138                 let ty = signature.try_to_rust_ty(ctx, item)?;
4139 
4140                 let prefix = ctx.trait_prefix();
4141                 Ok(syn::parse_quote! { ::#prefix::option::Option<#ty> })
4142             }
4143             TypeKind::Array(item, len) | TypeKind::Vector(item, len) => {
4144                 let ty = item.try_to_rust_ty(ctx, &())?;
4145                 Ok(syn::parse_quote! { [ #ty ; #len ] })
4146             }
4147             TypeKind::Enum(..) => {
4148                 let path = item.namespace_aware_canonical_path(ctx);
4149                 let path = proc_macro2::TokenStream::from_str(&path.join("::"))
4150                     .unwrap();
4151                 Ok(syn::parse_quote!(#path))
4152             }
4153             TypeKind::TemplateInstantiation(ref inst) => {
4154                 inst.try_to_rust_ty(ctx, item)
4155             }
4156             TypeKind::ResolvedTypeRef(inner) => inner.try_to_rust_ty(ctx, &()),
4157             TypeKind::TemplateAlias(..) |
4158             TypeKind::Alias(..) |
4159             TypeKind::BlockPointer(..) => {
4160                 if self.is_block_pointer() && !ctx.options().generate_block {
4161                     let void = c_void(ctx);
4162                     return Ok(void.to_ptr(/* is_const = */ false));
4163                 }
4164 
4165                 if item.is_opaque(ctx, &()) &&
4166                     item.used_template_params(ctx)
4167                         .into_iter()
4168                         .any(|param| param.is_template_param(ctx, &()))
4169                 {
4170                     self.try_to_opaque(ctx, item)
4171                 } else if let Some(ty) = self
4172                     .name()
4173                     .and_then(|name| utils::type_from_named(ctx, name))
4174                 {
4175                     Ok(ty)
4176                 } else {
4177                     utils::build_path(item, ctx)
4178                 }
4179             }
4180             TypeKind::Comp(ref info) => {
4181                 let template_params = item.all_template_params(ctx);
4182                 if info.has_non_type_template_params() ||
4183                     (item.is_opaque(ctx, &()) && !template_params.is_empty())
4184                 {
4185                     return self.try_to_opaque(ctx, item);
4186                 }
4187 
4188                 utils::build_path(item, ctx)
4189             }
4190             TypeKind::Opaque => self.try_to_opaque(ctx, item),
4191             TypeKind::Pointer(inner) | TypeKind::Reference(inner) => {
4192                 // Check that this type has the same size as the target's pointer type.
4193                 let size = self.get_layout(ctx, item).size;
4194                 if size != ctx.target_pointer_size() {
4195                     return Err(Error::InvalidPointerSize {
4196                         ty_name: self.name().unwrap_or("unknown").into(),
4197                         ty_size: size,
4198                         ptr_size: ctx.target_pointer_size(),
4199                     });
4200                 }
4201 
4202                 let is_const = ctx.resolve_type(inner).is_const();
4203 
4204                 let inner =
4205                     inner.into_resolver().through_type_refs().resolve(ctx);
4206                 let inner_ty = inner.expect_type();
4207 
4208                 let is_objc_pointer =
4209                     matches!(inner_ty.kind(), TypeKind::ObjCInterface(..));
4210 
4211                 // Regardless if we can properly represent the inner type, we
4212                 // should always generate a proper pointer here, so use
4213                 // infallible conversion of the inner type.
4214                 let ty = inner
4215                     .to_rust_ty_or_opaque(ctx, &())
4216                     .with_implicit_template_params(ctx, inner);
4217 
4218                 // Avoid the first function pointer level, since it's already
4219                 // represented in Rust.
4220                 if inner_ty.canonical_type(ctx).is_function() || is_objc_pointer
4221                 {
4222                     Ok(ty)
4223                 } else {
4224                     Ok(ty.to_ptr(is_const))
4225                 }
4226             }
4227             TypeKind::TypeParam => {
4228                 let name = item.canonical_name(ctx);
4229                 let ident = ctx.rust_ident(name);
4230                 Ok(syn::parse_quote! { #ident })
4231             }
4232             TypeKind::ObjCSel => Ok(syn::parse_quote! { objc::runtime::Sel }),
4233             TypeKind::ObjCId => Ok(syn::parse_quote! { id }),
4234             TypeKind::ObjCInterface(ref interface) => {
4235                 let name = ctx.rust_ident(interface.name());
4236                 Ok(syn::parse_quote! { #name })
4237             }
4238             ref u @ TypeKind::UnresolvedTypeRef(..) => {
4239                 unreachable!("Should have been resolved after parsing {:?}!", u)
4240             }
4241         }
4242     }
4243 }
4244 
4245 impl TryToOpaque for TemplateInstantiation {
4246     type Extra = Item;
4247 
try_get_layout( &self, ctx: &BindgenContext, item: &Item, ) -> error::Result<Layout>4248     fn try_get_layout(
4249         &self,
4250         ctx: &BindgenContext,
4251         item: &Item,
4252     ) -> error::Result<Layout> {
4253         item.expect_type()
4254             .layout(ctx)
4255             .ok_or(error::Error::NoLayoutForOpaqueBlob)
4256     }
4257 }
4258 
4259 impl TryToRustTy for TemplateInstantiation {
4260     type Extra = Item;
4261 
try_to_rust_ty( &self, ctx: &BindgenContext, item: &Item, ) -> error::Result<syn::Type>4262     fn try_to_rust_ty(
4263         &self,
4264         ctx: &BindgenContext,
4265         item: &Item,
4266     ) -> error::Result<syn::Type> {
4267         if self.is_opaque(ctx, item) {
4268             return Err(error::Error::InstantiationOfOpaqueType);
4269         }
4270 
4271         let def = self
4272             .template_definition()
4273             .into_resolver()
4274             .through_type_refs()
4275             .resolve(ctx);
4276 
4277         let mut ty = quote! {};
4278         let def_path = def.namespace_aware_canonical_path(ctx);
4279         ty.append_separated(
4280             def_path.into_iter().map(|p| ctx.rust_ident(p)),
4281             quote!(::),
4282         );
4283 
4284         let def_params = def.self_template_params(ctx);
4285         if def_params.is_empty() {
4286             // This can happen if we generated an opaque type for a partial
4287             // template specialization, and we've hit an instantiation of
4288             // that partial specialization.
4289             extra_assert!(def.is_opaque(ctx, &()));
4290             return Err(error::Error::InstantiationOfOpaqueType);
4291         }
4292 
4293         // TODO: If the definition type is a template class/struct
4294         // definition's member template definition, it could rely on
4295         // generic template parameters from its outer template
4296         // class/struct. When we emit bindings for it, it could require
4297         // *more* type arguments than we have here, and we will need to
4298         // reconstruct them somehow. We don't have any means of doing
4299         // that reconstruction at this time.
4300 
4301         let template_args = self
4302             .template_arguments()
4303             .iter()
4304             .zip(def_params.iter())
4305             // Only pass type arguments for the type parameters that
4306             // the def uses.
4307             .filter(|&(_, param)| ctx.uses_template_parameter(def.id(), *param))
4308             .map(|(arg, _)| {
4309                 let arg = arg.into_resolver().through_type_refs().resolve(ctx);
4310                 let ty = arg
4311                     .try_to_rust_ty(ctx, &())?
4312                     .with_implicit_template_params(ctx, arg);
4313                 Ok(ty)
4314             })
4315             .collect::<error::Result<Vec<_>>>()?;
4316 
4317         Ok(if template_args.is_empty() {
4318             syn::parse_quote! { #ty }
4319         } else {
4320             syn::parse_quote! { #ty<#(#template_args),*> }
4321         })
4322     }
4323 }
4324 
4325 impl TryToRustTy for FunctionSig {
4326     type Extra = Item;
4327 
try_to_rust_ty( &self, ctx: &BindgenContext, item: &Item, ) -> error::Result<syn::Type>4328     fn try_to_rust_ty(
4329         &self,
4330         ctx: &BindgenContext,
4331         item: &Item,
4332     ) -> error::Result<syn::Type> {
4333         // TODO: we might want to consider ignoring the reference return value.
4334         let ret = utils::fnsig_return_ty(ctx, self);
4335         let arguments = utils::fnsig_arguments(ctx, self);
4336 
4337         match self.abi(ctx, None) {
4338             Ok(abi) => Ok(
4339                 syn::parse_quote! { unsafe extern #abi fn ( #( #arguments ),* ) #ret },
4340             ),
4341             Err(err) => {
4342 
4343                 Err(err)
4344             }
4345         }
4346     }
4347 }
4348 
4349 impl CodeGenerator for Function {
4350     type Extra = Item;
4351 
4352     /// If we've actually generated the symbol, the number of times we've seen
4353     /// it.
4354     type Return = Option<u32>;
4355 
codegen( &self, ctx: &BindgenContext, result: &mut CodegenResult<'_>, item: &Item, ) -> Self::Return4356     fn codegen(
4357         &self,
4358         ctx: &BindgenContext,
4359         result: &mut CodegenResult<'_>,
4360         item: &Item,
4361     ) -> Self::Return {
4362         debug!("<Function as CodeGenerator>::codegen: item = {:?}", item);
4363         debug_assert!(item.is_enabled_for_codegen(ctx));
4364 
4365         let is_internal = matches!(self.linkage(), Linkage::Internal);
4366 
4367         let signature_item = ctx.resolve_item(self.signature());
4368         let signature = signature_item.kind().expect_type().canonical_type(ctx);
4369         let signature = match *signature.kind() {
4370             TypeKind::Function(ref sig) => sig,
4371             _ => panic!("Signature kind is not a Function: {:?}", signature),
4372         };
4373 
4374         if is_internal {
4375             if !ctx.options().wrap_static_fns {
4376                 // We cannot do anything with internal functions if we are not wrapping them so
4377                 // just avoid generating anything for them.
4378                 return None;
4379             }
4380 
4381             if signature.is_variadic() {
4382                 // We cannot generate wrappers for variadic static functions so we avoid
4383                 // generating any code for them.
4384                 return None;
4385             }
4386         }
4387 
4388         // Pure virtual methods have no actual symbol, so we can't generate
4389         // something meaningful for them.
4390         let is_dynamic_function = match self.kind() {
4391             FunctionKind::Method(ref method_kind)
4392                 if method_kind.is_pure_virtual() =>
4393             {
4394                 return None;
4395             }
4396             FunctionKind::Function => {
4397                 ctx.options().dynamic_library_name.is_some()
4398             }
4399             _ => false,
4400         };
4401 
4402         // Similar to static member variables in a class template, we can't
4403         // generate bindings to template functions, because the set of
4404         // instantiations is open ended and we have no way of knowing which
4405         // monomorphizations actually exist.
4406         if !item.all_template_params(ctx).is_empty() {
4407             return None;
4408         }
4409 
4410         let name = self.name();
4411         let mut canonical_name = item.canonical_name(ctx);
4412         let mangled_name = self.mangled_name();
4413 
4414         {
4415             let seen_symbol_name = mangled_name.unwrap_or(&canonical_name);
4416 
4417             // TODO: Maybe warn here if there's a type/argument mismatch, or
4418             // something?
4419             if result.seen_function(seen_symbol_name) {
4420                 return None;
4421             }
4422             result.saw_function(seen_symbol_name);
4423         }
4424 
4425         let mut attributes = vec![];
4426 
4427         if ctx.options().rust_features().must_use_function {
4428             let must_use = signature.must_use() || {
4429                 let ret_ty = signature
4430                     .return_type()
4431                     .into_resolver()
4432                     .through_type_refs()
4433                     .resolve(ctx);
4434                 ret_ty.must_use(ctx)
4435             };
4436 
4437             if must_use {
4438                 attributes.push(attributes::must_use());
4439             }
4440         }
4441 
4442         if let Some(comment) = item.comment(ctx) {
4443             attributes.push(attributes::doc(comment));
4444         }
4445 
4446         let abi = match signature.abi(ctx, Some(name)) {
4447             Err(err) => {
4448                 if matches!(err, error::Error::UnsupportedAbi(_)) {
4449                 }
4450 
4451                 return None;
4452             }
4453             Ok(ClangAbi::Unknown(unknown_abi)) => {
4454                 panic!(
4455                     "Invalid or unknown abi {:?} for function {:?} ({:?})",
4456                     unknown_abi, canonical_name, self
4457                 );
4458             }
4459             Ok(abi) => abi,
4460         };
4461 
4462         // Handle overloaded functions by giving each overload its own unique
4463         // suffix.
4464         let times_seen = result.overload_number(&canonical_name);
4465         if times_seen > 0 {
4466             write!(&mut canonical_name, "{}", times_seen).unwrap();
4467         }
4468 
4469         let mut has_link_name_attr = false;
4470         if let Some(link_name) = self.link_name() {
4471             attributes.push(attributes::link_name::<false>(link_name));
4472             has_link_name_attr = true;
4473         } else {
4474             let link_name = mangled_name.unwrap_or(name);
4475             if !is_dynamic_function &&
4476                 !utils::names_will_be_identical_after_mangling(
4477                     &canonical_name,
4478                     link_name,
4479                     Some(abi),
4480                 )
4481             {
4482                 attributes.push(attributes::link_name::<false>(link_name));
4483                 has_link_name_attr = true;
4484             }
4485         }
4486 
4487         // Unfortunately this can't piggyback on the `attributes` list because
4488         // the #[link(wasm_import_module)] needs to happen before the `extern
4489         // "C"` block. It doesn't get picked up properly otherwise
4490         let wasm_link_attribute =
4491             ctx.options().wasm_import_module_name.as_ref().map(|name| {
4492                 quote! { #[link(wasm_import_module = #name)] }
4493             });
4494 
4495         let should_wrap =
4496             is_internal && ctx.options().wrap_static_fns && !has_link_name_attr;
4497 
4498         if should_wrap {
4499             let name = canonical_name.clone() + ctx.wrap_static_fns_suffix();
4500             attributes.push(attributes::link_name::<true>(&name));
4501         }
4502 
4503         let wrap_as_variadic = if should_wrap && !signature.is_variadic() {
4504             utils::wrap_as_variadic_fn(ctx, signature, name)
4505         } else {
4506             None
4507         };
4508 
4509         let (ident, args) = if let Some(WrapAsVariadic {
4510             idx_of_va_list_arg,
4511             new_name,
4512         }) = &wrap_as_variadic
4513         {
4514             (
4515                 new_name,
4516                 utils::fnsig_arguments_iter(
4517                     ctx,
4518                     // Prune argument at index (idx_of_va_list_arg)
4519                     signature.argument_types().iter().enumerate().filter_map(
4520                         |(idx, t)| {
4521                             if idx == *idx_of_va_list_arg {
4522                                 None
4523                             } else {
4524                                 Some(t)
4525                             }
4526                         },
4527                     ),
4528                     // and replace it by a `...` (variadic symbol and the end of the signature)
4529                     true,
4530                 ),
4531             )
4532         } else {
4533             (&canonical_name, utils::fnsig_arguments(ctx, signature))
4534         };
4535         let ret = utils::fnsig_return_ty(ctx, signature);
4536 
4537         let ident = ctx.rust_ident(ident);
4538         let tokens = quote! {
4539             #wasm_link_attribute
4540             extern #abi {
4541                 #(#attributes)*
4542                 pub fn #ident ( #( #args ),* ) #ret;
4543             }
4544         };
4545 
4546         // Add the item to the serialization list if necessary
4547         if should_wrap {
4548             result
4549                 .items_to_serialize
4550                 .push((item.id(), wrap_as_variadic));
4551         }
4552 
4553         // If we're doing dynamic binding generation, add to the dynamic items.
4554         if is_dynamic_function {
4555             let args_identifiers =
4556                 utils::fnsig_argument_identifiers(ctx, signature);
4557             let ret_ty = utils::fnsig_return_ty(ctx, signature);
4558             result.dynamic_items().push_func(
4559                 ident,
4560                 abi,
4561                 signature.is_variadic(),
4562                 ctx.options().dynamic_link_require_all,
4563                 args,
4564                 args_identifiers,
4565                 ret,
4566                 ret_ty,
4567                 attributes,
4568                 ctx,
4569             );
4570         } else {
4571             result.push(tokens);
4572         }
4573         Some(times_seen)
4574     }
4575 }
4576 
4577 
4578 
4579 
4580 
4581 
4582 
4583 
4584 
4585 
4586 
4587 
4588 
4589 
objc_method_codegen( ctx: &BindgenContext, method: &ObjCMethod, methods: &mut Vec<proc_macro2::TokenStream>, class_name: Option<&str>, rust_class_name: &str, prefix: &str, )4590 fn objc_method_codegen(
4591     ctx: &BindgenContext,
4592     method: &ObjCMethod,
4593     methods: &mut Vec<proc_macro2::TokenStream>,
4594     class_name: Option<&str>,
4595     rust_class_name: &str,
4596     prefix: &str,
4597 ) {
4598     // This would ideally resolve the method into an Item, and use
4599     // Item::process_before_codegen; however, ObjC methods are not currently
4600     // made into function items.
4601     let name = format!("{}::{}{}", rust_class_name, prefix, method.rust_name());
4602     if ctx.options().blocklisted_items.matches(name) {
4603         return;
4604     }
4605 
4606     let signature = method.signature();
4607     let fn_args = utils::fnsig_arguments(ctx, signature);
4608     let fn_ret = utils::fnsig_return_ty(ctx, signature);
4609 
4610     let sig = if method.is_class_method() {
4611         quote! {
4612             ( #( #fn_args ),* ) #fn_ret
4613         }
4614     } else {
4615         let self_arr = [quote! { &self }];
4616         let args = self_arr.iter().chain(fn_args.iter());
4617         quote! {
4618             ( #( #args ),* ) #fn_ret
4619         }
4620     };
4621 
4622     let methods_and_args = method.format_method_call(&fn_args);
4623 
4624     let body = {
4625         let body = if method.is_class_method() {
4626             let class_name = ctx.rust_ident(
4627                 class_name
4628                     .expect("Generating a class method without class name?"),
4629             );
4630             quote!(msg_send!(class!(#class_name), #methods_and_args))
4631         } else {
4632             quote!(msg_send!(*self, #methods_and_args))
4633         };
4634 
4635         ctx.wrap_unsafe_ops(body)
4636     };
4637 
4638     let method_name =
4639         ctx.rust_ident(format!("{}{}", prefix, method.rust_name()));
4640 
4641     methods.push(quote! {
4642         unsafe fn #method_name #sig where <Self as std::ops::Deref>::Target: objc::Message + Sized {
4643             #body
4644         }
4645     });
4646 }
4647 
4648 impl CodeGenerator for ObjCInterface {
4649     type Extra = Item;
4650     type Return = ();
4651 
codegen( &self, ctx: &BindgenContext, result: &mut CodegenResult<'_>, item: &Item, )4652     fn codegen(
4653         &self,
4654         ctx: &BindgenContext,
4655         result: &mut CodegenResult<'_>,
4656         item: &Item,
4657     ) {
4658         debug_assert!(item.is_enabled_for_codegen(ctx));
4659 
4660         let mut impl_items = vec![];
4661         let rust_class_name = item.path_for_allowlisting(ctx)[1..].join("::");
4662 
4663         for method in self.methods() {
4664             objc_method_codegen(
4665                 ctx,
4666                 method,
4667                 &mut impl_items,
4668                 None,
4669                 &rust_class_name,
4670                 "",
4671             );
4672         }
4673 
4674         for class_method in self.class_methods() {
4675             let ambiquity = self
4676                 .methods()
4677                 .iter()
4678                 .map(|m| m.rust_name())
4679                 .any(|x| x == class_method.rust_name());
4680             let prefix = if ambiquity { "class_" } else { "" };
4681             objc_method_codegen(
4682                 ctx,
4683                 class_method,
4684                 &mut impl_items,
4685                 Some(self.name()),
4686                 &rust_class_name,
4687                 prefix,
4688             );
4689         }
4690 
4691         let trait_name = ctx.rust_ident(self.rust_name());
4692         let trait_constraints = quote! {
4693             Sized + std::ops::Deref
4694         };
4695         let trait_block = if self.is_template() {
4696             let template_names: Vec<Ident> = self
4697                 .template_names
4698                 .iter()
4699                 .map(|g| ctx.rust_ident(g))
4700                 .collect();
4701 
4702             quote! {
4703                 pub trait #trait_name <#(#template_names:'static),*> : #trait_constraints {
4704                     #( #impl_items )*
4705                 }
4706             }
4707         } else {
4708             quote! {
4709                 pub trait #trait_name : #trait_constraints {
4710                     #( #impl_items )*
4711                 }
4712             }
4713         };
4714 
4715         let class_name = ctx.rust_ident(self.name());
4716         if !self.is_category() && !self.is_protocol() {
4717             let struct_block = quote! {
4718                 #[repr(transparent)]
4719                 #[derive(Debug, Copy, Clone)]
4720                 pub struct #class_name(pub id);
4721                 impl std::ops::Deref for #class_name {
4722                     type Target = objc::runtime::Object;
4723                     fn deref(&self) -> &Self::Target {
4724                         unsafe {
4725                             &*self.0
4726                         }
4727                     }
4728                 }
4729                 unsafe impl objc::Message for #class_name { }
4730                 impl #class_name {
4731                     pub fn alloc() -> Self {
4732                         Self(unsafe {
4733                             msg_send!(class!(#class_name), alloc)
4734                         })
4735                     }
4736                 }
4737             };
4738             result.push(struct_block);
4739             let mut protocol_set: HashSet<ItemId> = Default::default();
4740             for protocol_id in self.conforms_to.iter() {
4741                 protocol_set.insert(*protocol_id);
4742                 let protocol_name = ctx.rust_ident(
4743                     ctx.resolve_type(protocol_id.expect_type_id(ctx))
4744                         .name()
4745                         .unwrap(),
4746                 );
4747                 let impl_trait = quote! {
4748                     impl #protocol_name for #class_name { }
4749                 };
4750                 result.push(impl_trait);
4751             }
4752             let mut parent_class = self.parent_class;
4753             while let Some(parent_id) = parent_class {
4754                 let parent = parent_id
4755                     .expect_type_id(ctx)
4756                     .into_resolver()
4757                     .through_type_refs()
4758                     .resolve(ctx)
4759                     .expect_type()
4760                     .kind();
4761 
4762                 let parent = match parent {
4763                     TypeKind::ObjCInterface(ref parent) => parent,
4764                     _ => break,
4765                 };
4766                 parent_class = parent.parent_class;
4767 
4768                 let parent_name = ctx.rust_ident(parent.rust_name());
4769                 let impl_trait = if parent.is_template() {
4770                     let template_names: Vec<Ident> = parent
4771                         .template_names
4772                         .iter()
4773                         .map(|g| ctx.rust_ident(g))
4774                         .collect();
4775                     quote! {
4776                         impl <#(#template_names :'static),*> #parent_name <#(#template_names),*> for #class_name {
4777                         }
4778                     }
4779                 } else {
4780                     quote! {
4781                         impl #parent_name for #class_name { }
4782                     }
4783                 };
4784                 result.push(impl_trait);
4785                 for protocol_id in parent.conforms_to.iter() {
4786                     if protocol_set.insert(*protocol_id) {
4787                         let protocol_name = ctx.rust_ident(
4788                             ctx.resolve_type(protocol_id.expect_type_id(ctx))
4789                                 .name()
4790                                 .unwrap(),
4791                         );
4792                         let impl_trait = quote! {
4793                             impl #protocol_name for #class_name { }
4794                         };
4795                         result.push(impl_trait);
4796                     }
4797                 }
4798                 if !parent.is_template() {
4799                     let parent_struct_name = parent.name();
4800                     let child_struct_name = self.name();
4801                     let parent_struct = ctx.rust_ident(parent_struct_name);
4802                     let from_block = quote! {
4803                         impl From<#class_name> for #parent_struct {
4804                             fn from(child: #class_name) -> #parent_struct {
4805                                 #parent_struct(child.0)
4806                             }
4807                         }
4808                     };
4809                     result.push(from_block);
4810 
4811                     let error_msg = format!(
4812                         "This {} cannot be downcasted to {}",
4813                         parent_struct_name, child_struct_name
4814                     );
4815                     let try_into_block = quote! {
4816                         impl std::convert::TryFrom<#parent_struct> for #class_name {
4817                             type Error = &'static str;
4818                             fn try_from(parent: #parent_struct) -> Result<#class_name, Self::Error> {
4819                                 let is_kind_of : bool = unsafe { msg_send!(parent, isKindOfClass:class!(#class_name))};
4820                                 if is_kind_of {
4821                                     Ok(#class_name(parent.0))
4822                                 } else {
4823                                     Err(#error_msg)
4824                                 }
4825                             }
4826                         }
4827                     };
4828                     result.push(try_into_block);
4829                 }
4830             }
4831         }
4832 
4833         if !self.is_protocol() {
4834             let impl_block = if self.is_template() {
4835                 let template_names: Vec<Ident> = self
4836                     .template_names
4837                     .iter()
4838                     .map(|g| ctx.rust_ident(g))
4839                     .collect();
4840                 quote! {
4841                     impl <#(#template_names :'static),*> #trait_name <#(#template_names),*> for #class_name {
4842                     }
4843                 }
4844             } else {
4845                 quote! {
4846                     impl #trait_name for #class_name {
4847                     }
4848                 }
4849             };
4850             result.push(impl_block);
4851         }
4852 
4853         result.push(trait_block);
4854         result.saw_objc();
4855     }
4856 }
4857 
codegen( context: BindgenContext, ) -> Result<(proc_macro2::TokenStream, BindgenOptions), CodegenError>4858 pub(crate) fn codegen(
4859     context: BindgenContext,
4860 ) -> Result<(proc_macro2::TokenStream, BindgenOptions), CodegenError> {
4861     context.gen(|context| {
4862         let _t = context.timer("codegen");
4863         let counter = Cell::new(0);
4864         let mut result = CodegenResult::new(&counter);
4865 
4866         debug!("codegen: {:?}", context.options());
4867 
4868         if context.options().emit_ir {
4869             let codegen_items = context.codegen_items();
4870             for (id, item) in context.items() {
4871                 if codegen_items.contains(&id) {
4872                     println!("ir: {:?} = {:#?}", id, item);
4873                 }
4874             }
4875         }
4876 
4877         if let Some(path) = context.options().emit_ir_graphviz.as_ref() {
4878             match dot::write_dot_file(context, path) {
4879                 Ok(()) => info!(
4880                     "Your dot file was generated successfully into: {}",
4881                     path
4882                 ),
4883                 Err(e) => warn!("{}", e),
4884             }
4885         }
4886 
4887         if let Some(spec) = context.options().depfile.as_ref() {
4888             match spec.write(context.deps()) {
4889                 Ok(()) => info!(
4890                     "Your depfile was generated successfully into: {}",
4891                     spec.depfile_path.display()
4892                 ),
4893                 Err(e) => warn!("{}", e),
4894             }
4895         }
4896 
4897         context.resolve_item(context.root_module()).codegen(
4898             context,
4899             &mut result,
4900             &(),
4901         );
4902 
4903         if let Some(ref lib_name) = context.options().dynamic_library_name {
4904             let lib_ident = context.rust_ident(lib_name);
4905             let dynamic_items_tokens =
4906                 result.dynamic_items().get_tokens(lib_ident, context);
4907             result.push(dynamic_items_tokens);
4908         }
4909 
4910         utils::serialize_items(&result, context)?;
4911 
4912         Ok(postprocessing::postprocessing(
4913             result.items,
4914             context.options(),
4915         ))
4916     })
4917 }
4918 
4919 pub(crate) mod utils {
4920     use super::helpers::BITFIELD_UNIT;
4921     use super::serialize::CSerialize;
4922     use super::{error, CodegenError, CodegenResult, ToRustTyOrOpaque};
4923     use crate::ir::context::BindgenContext;
4924     use crate::ir::context::TypeId;
4925     use crate::ir::function::{Abi, ClangAbi, FunctionSig};
4926     use crate::ir::item::{Item, ItemCanonicalPath};
4927     use crate::ir::ty::TypeKind;
4928     use crate::{args_are_cpp, file_is_cpp};
4929     use std::borrow::Cow;
4930     use std::io::Write;
4931     use std::mem;
4932     use std::path::PathBuf;
4933     use std::str::FromStr;
4934 
serialize_items( result: &CodegenResult, context: &BindgenContext, ) -> Result<(), CodegenError>4935     pub(super) fn serialize_items(
4936         result: &CodegenResult,
4937         context: &BindgenContext,
4938     ) -> Result<(), CodegenError> {
4939         if result.items_to_serialize.is_empty() {
4940             return Ok(());
4941         }
4942 
4943         let path = context
4944             .options()
4945             .wrap_static_fns_path
4946             .as_ref()
4947             .map(PathBuf::from)
4948             .unwrap_or_else(|| {
4949                 std::env::temp_dir().join("bindgen").join("extern")
4950             });
4951 
4952         let dir = path.parent().unwrap();
4953 
4954         if !dir.exists() {
4955             std::fs::create_dir_all(dir)?;
4956         }
4957 
4958         let is_cpp = args_are_cpp(&context.options().clang_args) ||
4959             context
4960                 .options()
4961                 .input_headers
4962                 .iter()
4963                 .any(|h| file_is_cpp(h));
4964 
4965         let source_path = path.with_extension(if is_cpp { "cpp" } else { "c" });
4966 
4967         let mut code = Vec::new();
4968 
4969         if !context.options().input_headers.is_empty() {
4970             for header in &context.options().input_headers {
4971                 writeln!(code, "#include \"{}\"", header)?;
4972             }
4973 
4974             writeln!(code)?;
4975         }
4976 
4977         if !context.options().input_header_contents.is_empty() {
4978             for (name, contents) in &context.options().input_header_contents {
4979                 writeln!(code, "// {}\n{}", name, contents)?;
4980             }
4981 
4982             writeln!(code)?;
4983         }
4984 
4985         writeln!(code, "// Static wrappers\n")?;
4986 
4987         for (id, wrap_as_variadic) in &result.items_to_serialize {
4988             let item = context.resolve_item(*id);
4989             item.serialize(context, wrap_as_variadic, &mut vec![], &mut code)?;
4990         }
4991 
4992         std::fs::write(source_path, code)?;
4993 
4994         Ok(())
4995     }
4996 
wrap_as_variadic_fn( ctx: &BindgenContext, signature: &FunctionSig, name: &str, ) -> Option<super::WrapAsVariadic>4997     pub(super) fn wrap_as_variadic_fn(
4998         ctx: &BindgenContext,
4999         signature: &FunctionSig,
5000         name: &str,
5001     ) -> Option<super::WrapAsVariadic> {
5002         // Fast path, exclude because:
5003         //  - with 0 args: no va_list possible, so no point searching for one
5004         //  - with 1 args: cannot have a `va_list` and another arg (required by va_start)
5005         if signature.argument_types().len() <= 1 {
5006             return None;
5007         }
5008 
5009         let mut it = signature.argument_types().iter().enumerate().filter_map(
5010             |(idx, (_name, mut type_id))| {
5011                 // Hand rolled visitor that checks for the presence of `va_list`
5012                 loop {
5013                     let ty = ctx.resolve_type(type_id);
5014                     if Some("__builtin_va_list") == ty.name() {
5015                         return Some(idx);
5016                     }
5017                     match ty.kind() {
5018                         TypeKind::Alias(type_id_alias) => {
5019                             type_id = *type_id_alias
5020                         }
5021                         TypeKind::ResolvedTypeRef(type_id_typedef) => {
5022                             type_id = *type_id_typedef
5023                         }
5024                         _ => break,
5025                     }
5026                 }
5027                 None
5028             },
5029         );
5030 
5031         // Return THE idx (by checking that there is no idx after)
5032         // This is done since we cannot handle multiple `va_list`
5033         it.next().filter(|_| it.next().is_none()).and_then(|idx| {
5034             // Call the `wrap_as_variadic_fn` callback
5035             #[cfg(feature = "experimental")]
5036             {
5037                 ctx.options()
5038                     .last_callback(|c| c.wrap_as_variadic_fn(name))
5039                     .map(|new_name| super::WrapAsVariadic {
5040                         new_name,
5041                         idx_of_va_list_arg: idx,
5042                     })
5043             }
5044             #[cfg(not(feature = "experimental"))]
5045             {
5046                 let _ = name;
5047                 let _ = idx;
5048                 None
5049             }
5050         })
5051     }
5052 
prepend_bitfield_unit_type( ctx: &BindgenContext, result: &mut Vec<proc_macro2::TokenStream>, )5053     pub(crate) fn prepend_bitfield_unit_type(
5054         ctx: &BindgenContext,
5055         result: &mut Vec<proc_macro2::TokenStream>,
5056     ) {
5057         if ctx.options().blocklisted_items.matches(BITFIELD_UNIT) ||
5058             ctx.options().blocklisted_types.matches(BITFIELD_UNIT)
5059         {
5060             return;
5061         }
5062 
5063         let bitfield_unit_src = include_str!("./bitfield_unit.rs");
5064         let bitfield_unit_src = if ctx.options().rust_features().min_const_fn {
5065             Cow::Borrowed(bitfield_unit_src)
5066         } else {
5067             Cow::Owned(bitfield_unit_src.replace("const fn ", "fn "))
5068         };
5069         let bitfield_unit_type =
5070             proc_macro2::TokenStream::from_str(&bitfield_unit_src).unwrap();
5071         let bitfield_unit_type = quote!(#bitfield_unit_type);
5072 
5073         let items = vec![bitfield_unit_type];
5074         let old_items = mem::replace(result, items);
5075         result.extend(old_items);
5076     }
5077 
prepend_objc_header( ctx: &BindgenContext, result: &mut Vec<proc_macro2::TokenStream>, )5078     pub(crate) fn prepend_objc_header(
5079         ctx: &BindgenContext,
5080         result: &mut Vec<proc_macro2::TokenStream>,
5081     ) {
5082         let use_objc = if ctx.options().objc_extern_crate {
5083             quote! {
5084                 #[macro_use]
5085                 extern crate objc;
5086             }
5087         } else {
5088             quote! {
5089                 use objc::{self, msg_send, sel, sel_impl, class};
5090             }
5091         };
5092 
5093         let id_type = quote! {
5094             #[allow(non_camel_case_types)]
5095             pub type id = *mut objc::runtime::Object;
5096         };
5097 
5098         let items = vec![use_objc, id_type];
5099         let old_items = mem::replace(result, items);
5100         result.extend(old_items);
5101     }
5102 
prepend_block_header( ctx: &BindgenContext, result: &mut Vec<proc_macro2::TokenStream>, )5103     pub(crate) fn prepend_block_header(
5104         ctx: &BindgenContext,
5105         result: &mut Vec<proc_macro2::TokenStream>,
5106     ) {
5107         let use_block = if ctx.options().block_extern_crate {
5108             quote! {
5109                 extern crate block;
5110             }
5111         } else {
5112             quote! {
5113                 use block;
5114             }
5115         };
5116 
5117         let items = vec![use_block];
5118         let old_items = mem::replace(result, items);
5119         result.extend(old_items);
5120     }
5121 
prepend_union_types( ctx: &BindgenContext, result: &mut Vec<proc_macro2::TokenStream>, )5122     pub(crate) fn prepend_union_types(
5123         ctx: &BindgenContext,
5124         result: &mut Vec<proc_macro2::TokenStream>,
5125     ) {
5126         let prefix = ctx.trait_prefix();
5127 
5128         // If the target supports `const fn`, declare eligible functions
5129         // as `const fn` else just `fn`.
5130         let const_fn = if ctx.options().rust_features().min_const_fn {
5131             quote! { const fn }
5132         } else {
5133             quote! { fn }
5134         };
5135 
5136         // TODO(emilio): The fmt::Debug impl could be way nicer with
5137         // std::intrinsics::type_name, but...
5138         let union_field_decl = quote! {
5139             #[repr(C)]
5140             pub struct __BindgenUnionField<T>(::#prefix::marker::PhantomData<T>);
5141         };
5142 
5143         let transmute =
5144             ctx.wrap_unsafe_ops(quote!(::#prefix::mem::transmute(self)));
5145 
5146         let union_field_impl = quote! {
5147             impl<T> __BindgenUnionField<T> {
5148                 #[inline]
5149                 pub #const_fn new() -> Self {
5150                     __BindgenUnionField(::#prefix::marker::PhantomData)
5151                 }
5152 
5153                 #[inline]
5154                 pub unsafe fn as_ref(&self) -> &T {
5155                     #transmute
5156                 }
5157 
5158                 #[inline]
5159                 pub unsafe fn as_mut(&mut self) -> &mut T {
5160                     #transmute
5161                 }
5162             }
5163         };
5164 
5165         let union_field_default_impl = quote! {
5166             impl<T> ::#prefix::default::Default for __BindgenUnionField<T> {
5167                 #[inline]
5168                 fn default() -> Self {
5169                     Self::new()
5170                 }
5171             }
5172         };
5173 
5174         let union_field_clone_impl = quote! {
5175             impl<T> ::#prefix::clone::Clone for __BindgenUnionField<T> {
5176                 #[inline]
5177                 fn clone(&self) -> Self {
5178                     *self
5179                 }
5180             }
5181         };
5182 
5183         let union_field_copy_impl = quote! {
5184             impl<T> ::#prefix::marker::Copy for __BindgenUnionField<T> {}
5185         };
5186 
5187         let union_field_debug_impl = quote! {
5188             impl<T> ::#prefix::fmt::Debug for __BindgenUnionField<T> {
5189                 fn fmt(&self, fmt: &mut ::#prefix::fmt::Formatter<'_>)
5190                        -> ::#prefix::fmt::Result {
5191                     fmt.write_str("__BindgenUnionField")
5192                 }
5193             }
5194         };
5195 
5196         // The actual memory of the filed will be hashed, so that's why these
5197         // field doesn't do anything with the hash.
5198         let union_field_hash_impl = quote! {
5199             impl<T> ::#prefix::hash::Hash for __BindgenUnionField<T> {
5200                 fn hash<H: ::#prefix::hash::Hasher>(&self, _state: &mut H) {
5201                 }
5202             }
5203         };
5204 
5205         let union_field_partialeq_impl = quote! {
5206             impl<T> ::#prefix::cmp::PartialEq for __BindgenUnionField<T> {
5207                fn eq(&self, _other: &__BindgenUnionField<T>) -> bool {
5208                    true
5209                }
5210            }
5211         };
5212 
5213         let union_field_eq_impl = quote! {
5214            impl<T> ::#prefix::cmp::Eq for __BindgenUnionField<T> {
5215            }
5216         };
5217 
5218         let items = vec![
5219             union_field_decl,
5220             union_field_impl,
5221             union_field_default_impl,
5222             union_field_clone_impl,
5223             union_field_copy_impl,
5224             union_field_debug_impl,
5225             union_field_hash_impl,
5226             union_field_partialeq_impl,
5227             union_field_eq_impl,
5228         ];
5229 
5230         let old_items = mem::replace(result, items);
5231         result.extend(old_items);
5232     }
5233 
prepend_incomplete_array_types( ctx: &BindgenContext, result: &mut Vec<proc_macro2::TokenStream>, )5234     pub(crate) fn prepend_incomplete_array_types(
5235         ctx: &BindgenContext,
5236         result: &mut Vec<proc_macro2::TokenStream>,
5237     ) {
5238         let prefix = ctx.trait_prefix();
5239 
5240         // If the target supports `const fn`, declare eligible functions
5241         // as `const fn` else just `fn`.
5242         let const_fn = if ctx.options().rust_features().min_const_fn {
5243             quote! { const fn }
5244         } else {
5245             quote! { fn }
5246         };
5247 
5248         let incomplete_array_decl = quote! {
5249             #[repr(C)]
5250             #[derive(Default)]
5251             pub struct __IncompleteArrayField<T>(
5252                 ::#prefix::marker::PhantomData<T>, [T; 0]);
5253         };
5254 
5255         let from_raw_parts = ctx.wrap_unsafe_ops(quote! (
5256             ::#prefix::slice::from_raw_parts(self.as_ptr(), len)
5257         ));
5258         let from_raw_parts_mut = ctx.wrap_unsafe_ops(quote! (
5259             ::#prefix::slice::from_raw_parts_mut(self.as_mut_ptr(), len)
5260         ));
5261 
5262         let incomplete_array_impl = quote! {
5263             impl<T> __IncompleteArrayField<T> {
5264                 #[inline]
5265                 pub #const_fn new() -> Self {
5266                     __IncompleteArrayField(::#prefix::marker::PhantomData, [])
5267                 }
5268 
5269                 #[inline]
5270                 pub fn as_ptr(&self) -> *const T {
5271                     self as *const _ as *const T
5272                 }
5273 
5274                 #[inline]
5275                 pub fn as_mut_ptr(&mut self) -> *mut T {
5276                     self as *mut _ as *mut T
5277                 }
5278 
5279                 #[inline]
5280                 pub unsafe fn as_slice(&self, len: usize) -> &[T] {
5281                     #from_raw_parts
5282                 }
5283 
5284                 #[inline]
5285                 pub unsafe fn as_mut_slice(&mut self, len: usize) -> &mut [T] {
5286                     #from_raw_parts_mut
5287                 }
5288             }
5289         };
5290 
5291         let incomplete_array_debug_impl = quote! {
5292             impl<T> ::#prefix::fmt::Debug for __IncompleteArrayField<T> {
5293                 fn fmt(&self, fmt: &mut ::#prefix::fmt::Formatter<'_>)
5294                        -> ::#prefix::fmt::Result {
5295                     fmt.write_str("__IncompleteArrayField")
5296                 }
5297             }
5298         };
5299 
5300         let items = vec![
5301             incomplete_array_decl,
5302             incomplete_array_impl,
5303             incomplete_array_debug_impl,
5304         ];
5305 
5306         let old_items = mem::replace(result, items);
5307         result.extend(old_items);
5308     }
5309 
prepend_float16_type( result: &mut Vec<proc_macro2::TokenStream>, )5310     pub(crate) fn prepend_float16_type(
5311         result: &mut Vec<proc_macro2::TokenStream>,
5312     ) {
5313         let float16_type = quote! {
5314             #[derive(PartialEq, Copy, Clone, Hash, Debug, Default)]
5315             #[repr(transparent)]
5316             pub struct __BindgenFloat16(pub u16);
5317         };
5318 
5319         let items = vec![float16_type];
5320         let old_items = mem::replace(result, items);
5321         result.extend(old_items);
5322     }
5323 
prepend_complex_type( result: &mut Vec<proc_macro2::TokenStream>, )5324     pub(crate) fn prepend_complex_type(
5325         result: &mut Vec<proc_macro2::TokenStream>,
5326     ) {
5327         let complex_type = quote! {
5328             #[derive(PartialEq, Copy, Clone, Hash, Debug, Default)]
5329             #[repr(C)]
5330             pub struct __BindgenComplex<T> {
5331                 pub re: T,
5332                 pub im: T
5333             }
5334         };
5335 
5336         let items = vec![complex_type];
5337         let old_items = mem::replace(result, items);
5338         result.extend(old_items);
5339     }
5340 
build_path( item: &Item, ctx: &BindgenContext, ) -> error::Result<syn::Type>5341     pub(crate) fn build_path(
5342         item: &Item,
5343         ctx: &BindgenContext,
5344     ) -> error::Result<syn::Type> {
5345         let path = item.namespace_aware_canonical_path(ctx);
5346         let tokens =
5347             proc_macro2::TokenStream::from_str(&path.join("::")).unwrap();
5348 
5349         Ok(syn::parse_quote! { #tokens })
5350     }
5351 
primitive_ty(ctx: &BindgenContext, name: &str) -> syn::Type5352     fn primitive_ty(ctx: &BindgenContext, name: &str) -> syn::Type {
5353         let ident = ctx.rust_ident_raw(name);
5354         syn::parse_quote! { #ident }
5355     }
5356 
type_from_named( ctx: &BindgenContext, name: &str, ) -> Option<syn::Type>5357     pub(crate) fn type_from_named(
5358         ctx: &BindgenContext,
5359         name: &str,
5360     ) -> Option<syn::Type> {
5361         // FIXME: We could use the inner item to check this is really a
5362         // primitive type but, who the heck overrides these anyway?
5363         Some(match name {
5364             "int8_t" => primitive_ty(ctx, "i8"),
5365             "uint8_t" => primitive_ty(ctx, "u8"),
5366             "int16_t" => primitive_ty(ctx, "i16"),
5367             "uint16_t" => primitive_ty(ctx, "u16"),
5368             "int32_t" => primitive_ty(ctx, "i32"),
5369             "uint32_t" => primitive_ty(ctx, "u32"),
5370             "int64_t" => primitive_ty(ctx, "i64"),
5371             "uint64_t" => primitive_ty(ctx, "u64"),
5372 
5373             "size_t" if ctx.options().size_t_is_usize => {
5374                 primitive_ty(ctx, "usize")
5375             }
5376             "uintptr_t" => primitive_ty(ctx, "usize"),
5377 
5378             "ssize_t" if ctx.options().size_t_is_usize => {
5379                 primitive_ty(ctx, "isize")
5380             }
5381             "intptr_t" | "ptrdiff_t" => primitive_ty(ctx, "isize"),
5382             _ => return None,
5383         })
5384     }
5385 
fnsig_return_ty_internal( ctx: &BindgenContext, sig: &FunctionSig, ) -> syn::Type5386     fn fnsig_return_ty_internal(
5387         ctx: &BindgenContext,
5388         sig: &FunctionSig,
5389     ) -> syn::Type {
5390         if sig.is_divergent() {
5391             return syn::parse_quote! { ! };
5392         }
5393 
5394         let canonical_type_kind = sig
5395             .return_type()
5396             .into_resolver()
5397             .through_type_refs()
5398             .through_type_aliases()
5399             .resolve(ctx)
5400             .kind()
5401             .expect_type()
5402             .kind();
5403 
5404         match canonical_type_kind {
5405             TypeKind::Void => syn::parse_quote! { () },
5406             _ => sig.return_type().to_rust_ty_or_opaque(ctx, &()),
5407         }
5408     }
5409 
fnsig_return_ty( ctx: &BindgenContext, sig: &FunctionSig, ) -> proc_macro2::TokenStream5410     pub(crate) fn fnsig_return_ty(
5411         ctx: &BindgenContext,
5412         sig: &FunctionSig,
5413     ) -> proc_macro2::TokenStream {
5414         match fnsig_return_ty_internal(ctx, sig) {
5415             syn::Type::Tuple(syn::TypeTuple { elems, .. })
5416                 if elems.is_empty() =>
5417             {
5418                 quote! {}
5419             }
5420             ty => quote! { -> #ty },
5421         }
5422     }
5423 
fnsig_argument_type( ctx: &BindgenContext, ty: &TypeId, ) -> syn::Type5424     pub(crate) fn fnsig_argument_type(
5425         ctx: &BindgenContext,
5426         ty: &TypeId,
5427     ) -> syn::Type {
5428         use super::ToPtr;
5429 
5430         let arg_item = ctx.resolve_item(ty);
5431         let arg_ty = arg_item.kind().expect_type();
5432 
5433         // From the C90 standard[1]:
5434         //
5435         //     A declaration of a parameter as "array of type" shall be
5436         //     adjusted to "qualified pointer to type", where the type
5437         //     qualifiers (if any) are those specified within the [ and ] of
5438         //     the array type derivation.
5439         //
5440         // [1]: http://c0x.coding-guidelines.com/6.7.5.3.html
5441         match *arg_ty.canonical_type(ctx).kind() {
5442             TypeKind::Array(t, _) => {
5443                 let stream = if ctx.options().array_pointers_in_arguments {
5444                     arg_ty.to_rust_ty_or_opaque(ctx, arg_item)
5445                 } else {
5446                     t.to_rust_ty_or_opaque(ctx, &())
5447                 };
5448                 stream
5449                     .to_ptr(ctx.resolve_type(t).is_const() || arg_ty.is_const())
5450             }
5451             TypeKind::Pointer(inner) => {
5452                 let inner = ctx.resolve_item(inner);
5453                 let inner_ty = inner.expect_type();
5454                 if let TypeKind::ObjCInterface(ref interface) =
5455                     *inner_ty.canonical_type(ctx).kind()
5456                 {
5457                     let name = ctx.rust_ident(interface.name());
5458                     syn::parse_quote! { #name }
5459                 } else {
5460                     arg_item.to_rust_ty_or_opaque(ctx, &())
5461                 }
5462             }
5463             _ => arg_item.to_rust_ty_or_opaque(ctx, &()),
5464         }
5465     }
5466 
fnsig_arguments_iter< 'a, I: Iterator<Item = &'a (Option<String>, crate::ir::context::TypeId)>, >( ctx: &BindgenContext, args_iter: I, is_variadic: bool, ) -> Vec<proc_macro2::TokenStream>5467     pub(crate) fn fnsig_arguments_iter<
5468         'a,
5469         I: Iterator<Item = &'a (Option<String>, crate::ir::context::TypeId)>,
5470     >(
5471         ctx: &BindgenContext,
5472         args_iter: I,
5473         is_variadic: bool,
5474     ) -> Vec<proc_macro2::TokenStream> {
5475         let mut unnamed_arguments = 0;
5476         let mut args = args_iter
5477             .map(|(name, ty)| {
5478                 let arg_ty = fnsig_argument_type(ctx, ty);
5479 
5480                 let arg_name = match *name {
5481                     Some(ref name) => ctx.rust_mangle(name).into_owned(),
5482                     None => {
5483                         unnamed_arguments += 1;
5484                         format!("arg{}", unnamed_arguments)
5485                     }
5486                 };
5487 
5488                 assert!(!arg_name.is_empty());
5489                 let arg_name = ctx.rust_ident(arg_name);
5490 
5491                 quote! {
5492                     #arg_name : #arg_ty
5493                 }
5494             })
5495             .collect::<Vec<_>>();
5496 
5497         if is_variadic {
5498             args.push(quote! { ... })
5499         }
5500 
5501         args
5502     }
5503 
fnsig_arguments( ctx: &BindgenContext, sig: &FunctionSig, ) -> Vec<proc_macro2::TokenStream>5504     pub(crate) fn fnsig_arguments(
5505         ctx: &BindgenContext,
5506         sig: &FunctionSig,
5507     ) -> Vec<proc_macro2::TokenStream> {
5508         fnsig_arguments_iter(
5509             ctx,
5510             sig.argument_types().iter(),
5511             sig.is_variadic(),
5512         )
5513     }
5514 
fnsig_argument_identifiers( ctx: &BindgenContext, sig: &FunctionSig, ) -> Vec<proc_macro2::TokenStream>5515     pub(crate) fn fnsig_argument_identifiers(
5516         ctx: &BindgenContext,
5517         sig: &FunctionSig,
5518     ) -> Vec<proc_macro2::TokenStream> {
5519         let mut unnamed_arguments = 0;
5520         let args = sig
5521             .argument_types()
5522             .iter()
5523             .map(|&(ref name, _ty)| {
5524                 let arg_name = match *name {
5525                     Some(ref name) => ctx.rust_mangle(name).into_owned(),
5526                     None => {
5527                         unnamed_arguments += 1;
5528                         format!("arg{}", unnamed_arguments)
5529                     }
5530                 };
5531 
5532                 assert!(!arg_name.is_empty());
5533                 let arg_name = ctx.rust_ident(arg_name);
5534 
5535                 quote! {
5536                     #arg_name
5537                 }
5538             })
5539             .collect::<Vec<_>>();
5540 
5541         args
5542     }
5543 
fnsig_block( ctx: &BindgenContext, sig: &FunctionSig, ) -> proc_macro2::TokenStream5544     pub(crate) fn fnsig_block(
5545         ctx: &BindgenContext,
5546         sig: &FunctionSig,
5547     ) -> proc_macro2::TokenStream {
5548         let args = sig.argument_types().iter().map(|&(_, ty)| {
5549             let arg_item = ctx.resolve_item(ty);
5550 
5551             arg_item.to_rust_ty_or_opaque(ctx, &())
5552         });
5553 
5554         let ret_ty = fnsig_return_ty_internal(ctx, sig);
5555         quote! {
5556             *const ::block::Block<(#(#args,)*), #ret_ty>
5557         }
5558     }
5559 
5560     // Returns true if `canonical_name` will end up as `mangled_name` at the
5561     // machine code level, i.e. after LLVM has applied any target specific
5562     // mangling.
names_will_be_identical_after_mangling( canonical_name: &str, mangled_name: &str, call_conv: Option<ClangAbi>, ) -> bool5563     pub(crate) fn names_will_be_identical_after_mangling(
5564         canonical_name: &str,
5565         mangled_name: &str,
5566         call_conv: Option<ClangAbi>,
5567     ) -> bool {
5568         // If the mangled name and the canonical name are the same then no
5569         // mangling can have happened between the two versions.
5570         if canonical_name == mangled_name {
5571             return true;
5572         }
5573 
5574         // Working with &[u8] makes indexing simpler than with &str
5575         let canonical_name = canonical_name.as_bytes();
5576         let mangled_name = mangled_name.as_bytes();
5577 
5578         let (mangling_prefix, expect_suffix) = match call_conv {
5579             Some(ClangAbi::Known(Abi::C)) |
5580             // None is the case for global variables
5581             None => {
5582                 (b'_', false)
5583             }
5584             Some(ClangAbi::Known(Abi::Stdcall)) => (b'_', true),
5585             Some(ClangAbi::Known(Abi::Fastcall)) => (b'@', true),
5586 
5587             // This is something we don't recognize, stay on the safe side
5588             // by emitting the `#[link_name]` attribute
5589             Some(_) => return false,
5590         };
5591 
5592         // Check that the mangled name is long enough to at least contain the
5593         // canonical name plus the expected prefix.
5594         if mangled_name.len() < canonical_name.len() + 1 {
5595             return false;
5596         }
5597 
5598         // Return if the mangled name does not start with the prefix expected
5599         // for the given calling convention.
5600         if mangled_name[0] != mangling_prefix {
5601             return false;
5602         }
5603 
5604         // Check that the mangled name contains the canonical name after the
5605         // prefix
5606         if &mangled_name[1..canonical_name.len() + 1] != canonical_name {
5607             return false;
5608         }
5609 
5610         // If the given calling convention also prescribes a suffix, check that
5611         // it exists too
5612         if expect_suffix {
5613             let suffix = &mangled_name[canonical_name.len() + 1..];
5614 
5615             // The shortest suffix is "@0"
5616             if suffix.len() < 2 {
5617                 return false;
5618             }
5619 
5620             // Check that the suffix starts with '@' and is all ASCII decimals
5621             // after that.
5622             if suffix[0] != b'@' || !suffix[1..].iter().all(u8::is_ascii_digit)
5623             {
5624                 return false;
5625             }
5626         } else if mangled_name.len() != canonical_name.len() + 1 {
5627             // If we don't expect a prefix but there is one, we need the
5628             // #[link_name] attribute
5629             return false;
5630         }
5631 
5632         true
5633     }
5634 }
5635