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