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