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