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