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