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