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