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