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