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