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