Skip to main content

bindgen/codegen/
mod.rs

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