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