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