• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 //! Compound types (unions and structs) in our intermediate representation.
2 
3 
4 use super::analysis::Sizedness;
5 use super::annotations::Annotations;
6 use super::context::{BindgenContext, FunctionId, ItemId, TypeId, VarId};
7 use super::dot::DotAttributes;
8 use super::item::{IsOpaque, Item};
9 use super::layout::Layout;
10 use super::template::TemplateParameters;
11 use super::traversal::{EdgeKind, Trace, Tracer};
12 use super::ty::RUST_DERIVE_IN_ARRAY_LIMIT;
13 use crate::clang;
14 use crate::codegen::struct_layout::{align_to, bytes_from_bits_pow2};
15 use crate::ir::derive::CanDeriveCopy;
16 use crate::parse::ParseError;
17 use crate::HashMap;
18 use crate::NonCopyUnionStyle;
19 use std::cmp;
20 use std::io;
21 use std::mem;
22 
23 /// The kind of compound type.
24 #[derive(Debug, Copy, Clone, PartialEq, Eq)]
25 pub(crate) enum CompKind {
26     /// A struct.
27     Struct,
28     /// A union.
29     Union,
30 }
31 
32 /// The kind of C++ method.
33 #[derive(Debug, Copy, Clone, PartialEq, Eq)]
34 pub(crate) enum MethodKind {
35     /// A constructor. We represent it as method for convenience, to avoid code
36     /// duplication.
37     Constructor,
38     /// A destructor.
39     Destructor,
40     /// A virtual destructor.
41     VirtualDestructor {
42         /// Whether it's pure virtual.
43         pure_virtual: bool,
44     },
45     /// A static method.
46     Static,
47     /// A normal method.
48     Normal,
49     /// A virtual method.
50     Virtual {
51         /// Whether it's pure virtual.
52         pure_virtual: bool,
53     },
54 }
55 
56 impl MethodKind {
57     /// Is this a destructor method?
is_destructor(&self) -> bool58     pub(crate) fn is_destructor(&self) -> bool {
59         matches!(
60             *self,
61             MethodKind::Destructor | MethodKind::VirtualDestructor { .. }
62         )
63     }
64 
65     /// Is this a pure virtual method?
is_pure_virtual(&self) -> bool66     pub(crate) fn is_pure_virtual(&self) -> bool {
67         match *self {
68             MethodKind::Virtual { pure_virtual } |
69             MethodKind::VirtualDestructor { pure_virtual } => pure_virtual,
70             _ => false,
71         }
72     }
73 }
74 
75 /// A struct representing a C++ method, either static, normal, or virtual.
76 #[derive(Debug)]
77 pub(crate) struct Method {
78     kind: MethodKind,
79     /// The signature of the method. Take into account this is not a `Type`
80     /// item, but a `Function` one.
81     ///
82     /// This is tricky and probably this field should be renamed.
83     signature: FunctionId,
84     is_const: bool,
85 }
86 
87 impl Method {
88     /// Construct a new `Method`.
new( kind: MethodKind, signature: FunctionId, is_const: bool, ) -> Self89     pub(crate) fn new(
90         kind: MethodKind,
91         signature: FunctionId,
92         is_const: bool,
93     ) -> Self {
94         Method {
95             kind,
96             signature,
97             is_const,
98         }
99     }
100 
101     /// What kind of method is this?
kind(&self) -> MethodKind102     pub(crate) fn kind(&self) -> MethodKind {
103         self.kind
104     }
105 
106     /// Is this a constructor?
is_constructor(&self) -> bool107     pub(crate) fn is_constructor(&self) -> bool {
108         self.kind == MethodKind::Constructor
109     }
110 
111     /// Is this a virtual method?
is_virtual(&self) -> bool112     pub(crate) fn is_virtual(&self) -> bool {
113         matches!(
114             self.kind,
115             MethodKind::Virtual { .. } | MethodKind::VirtualDestructor { .. }
116         )
117     }
118 
119     /// Is this a static method?
is_static(&self) -> bool120     pub(crate) fn is_static(&self) -> bool {
121         self.kind == MethodKind::Static
122     }
123 
124     /// Get the ID for the `Function` signature for this method.
signature(&self) -> FunctionId125     pub(crate) fn signature(&self) -> FunctionId {
126         self.signature
127     }
128 
129     /// Is this a const qualified method?
is_const(&self) -> bool130     pub(crate) fn is_const(&self) -> bool {
131         self.is_const
132     }
133 }
134 
135 /// Methods common to the various field types.
136 pub(crate) trait FieldMethods {
137     /// Get the name of this field.
name(&self) -> Option<&str>138     fn name(&self) -> Option<&str>;
139 
140     /// Get the type of this field.
ty(&self) -> TypeId141     fn ty(&self) -> TypeId;
142 
143     /// Get the comment for this field.
comment(&self) -> Option<&str>144     fn comment(&self) -> Option<&str>;
145 
146     /// If this is a bitfield, how many bits does it need?
bitfield_width(&self) -> Option<u32>147     fn bitfield_width(&self) -> Option<u32>;
148 
149     /// Is this field declared public?
is_public(&self) -> bool150     fn is_public(&self) -> bool;
151 
152     /// Get the annotations for this field.
annotations(&self) -> &Annotations153     fn annotations(&self) -> &Annotations;
154 
155     /// The offset of the field (in bits)
offset(&self) -> Option<usize>156     fn offset(&self) -> Option<usize>;
157 }
158 
159 /// A contiguous set of logical bitfields that live within the same physical
160 /// allocation unit. See 9.2.4 [class.bit] in the C++ standard and [section
161 /// 2.4.II.1 in the Itanium C++
162 /// ABI](http://itanium-cxx-abi.github.io/cxx-abi/abi.html#class-types).
163 #[derive(Debug)]
164 pub(crate) struct BitfieldUnit {
165     nth: usize,
166     layout: Layout,
167     bitfields: Vec<Bitfield>,
168 }
169 
170 impl BitfieldUnit {
171     /// Get the 1-based index of this bitfield unit within its containing
172     /// struct. Useful for generating a Rust struct's field name for this unit
173     /// of bitfields.
nth(&self) -> usize174     pub(crate) fn nth(&self) -> usize {
175         self.nth
176     }
177 
178     /// Get the layout within which these bitfields reside.
layout(&self) -> Layout179     pub(crate) fn layout(&self) -> Layout {
180         self.layout
181     }
182 
183     /// Get the bitfields within this unit.
bitfields(&self) -> &[Bitfield]184     pub(crate) fn bitfields(&self) -> &[Bitfield] {
185         &self.bitfields
186     }
187 }
188 
189 /// A struct representing a C++ field.
190 #[derive(Debug)]
191 pub(crate) enum Field {
192     /// A normal data member.
193     DataMember(FieldData),
194 
195     /// A physical allocation unit containing many logical bitfields.
196     Bitfields(BitfieldUnit),
197 }
198 
199 impl Field {
200     /// Get this field's layout.
layout(&self, ctx: &BindgenContext) -> Option<Layout>201     pub(crate) fn layout(&self, ctx: &BindgenContext) -> Option<Layout> {
202         match *self {
203             Field::Bitfields(BitfieldUnit { layout, .. }) => Some(layout),
204             Field::DataMember(ref data) => {
205                 ctx.resolve_type(data.ty).layout(ctx)
206             }
207         }
208     }
209 }
210 
211 impl Trace for Field {
212     type Extra = ();
213 
trace<T>(&self, _: &BindgenContext, tracer: &mut T, _: &()) where T: Tracer,214     fn trace<T>(&self, _: &BindgenContext, tracer: &mut T, _: &())
215     where
216         T: Tracer,
217     {
218         match *self {
219             Field::DataMember(ref data) => {
220                 tracer.visit_kind(data.ty.into(), EdgeKind::Field);
221             }
222             Field::Bitfields(BitfieldUnit { ref bitfields, .. }) => {
223                 for bf in bitfields {
224                     tracer.visit_kind(bf.ty().into(), EdgeKind::Field);
225                 }
226             }
227         }
228     }
229 }
230 
231 impl DotAttributes for Field {
dot_attributes<W>( &self, ctx: &BindgenContext, out: &mut W, ) -> io::Result<()> where W: io::Write,232     fn dot_attributes<W>(
233         &self,
234         ctx: &BindgenContext,
235         out: &mut W,
236     ) -> io::Result<()>
237     where
238         W: io::Write,
239     {
240         match *self {
241             Field::DataMember(ref data) => data.dot_attributes(ctx, out),
242             Field::Bitfields(BitfieldUnit {
243                 layout,
244                 ref bitfields,
245                 ..
246             }) => {
247                 writeln!(
248                     out,
249                     r#"<tr>
250                               <td>bitfield unit</td>
251                               <td>
252                                 <table border="0">
253                                   <tr>
254                                     <td>unit.size</td><td>{}</td>
255                                   </tr>
256                                   <tr>
257                                     <td>unit.align</td><td>{}</td>
258                                   </tr>
259                          "#,
260                     layout.size, layout.align
261                 )?;
262                 for bf in bitfields {
263                     bf.dot_attributes(ctx, out)?;
264                 }
265                 writeln!(out, "</table></td></tr>")
266             }
267         }
268     }
269 }
270 
271 impl DotAttributes for FieldData {
dot_attributes<W>( &self, _ctx: &BindgenContext, out: &mut W, ) -> io::Result<()> where W: io::Write,272     fn dot_attributes<W>(
273         &self,
274         _ctx: &BindgenContext,
275         out: &mut W,
276     ) -> io::Result<()>
277     where
278         W: io::Write,
279     {
280         writeln!(
281             out,
282             "<tr><td>{}</td><td>{:?}</td></tr>",
283             self.name().unwrap_or("(anonymous)"),
284             self.ty()
285         )
286     }
287 }
288 
289 impl DotAttributes for Bitfield {
dot_attributes<W>( &self, _ctx: &BindgenContext, out: &mut W, ) -> io::Result<()> where W: io::Write,290     fn dot_attributes<W>(
291         &self,
292         _ctx: &BindgenContext,
293         out: &mut W,
294     ) -> io::Result<()>
295     where
296         W: io::Write,
297     {
298         writeln!(
299             out,
300             "<tr><td>{} : {}</td><td>{:?}</td></tr>",
301             self.name().unwrap_or("(anonymous)"),
302             self.width(),
303             self.ty()
304         )
305     }
306 }
307 
308 /// A logical bitfield within some physical bitfield allocation unit.
309 #[derive(Debug)]
310 pub(crate) struct Bitfield {
311     /// Index of the bit within this bitfield's allocation unit where this
312     /// bitfield's bits begin.
313     offset_into_unit: usize,
314 
315     /// The field data for this bitfield.
316     data: FieldData,
317 
318     /// Name of the generated Rust getter for this bitfield.
319     ///
320     /// Should be assigned before codegen.
321     getter_name: Option<String>,
322 
323     /// Name of the generated Rust setter for this bitfield.
324     ///
325     /// Should be assigned before codegen.
326     setter_name: Option<String>,
327 }
328 
329 impl Bitfield {
330     /// Construct a new bitfield.
new(offset_into_unit: usize, raw: RawField) -> Bitfield331     fn new(offset_into_unit: usize, raw: RawField) -> Bitfield {
332         assert!(raw.bitfield_width().is_some());
333 
334         Bitfield {
335             offset_into_unit,
336             data: raw.0,
337             getter_name: None,
338             setter_name: None,
339         }
340     }
341 
342     /// Get the index of the bit within this bitfield's allocation unit where
343     /// this bitfield begins.
offset_into_unit(&self) -> usize344     pub(crate) fn offset_into_unit(&self) -> usize {
345         self.offset_into_unit
346     }
347 
348     /// Get the bit width of this bitfield.
width(&self) -> u32349     pub(crate) fn width(&self) -> u32 {
350         self.data.bitfield_width().unwrap()
351     }
352 
353     /// Name of the generated Rust getter for this bitfield.
354     ///
355     /// Panics if called before assigning bitfield accessor names or if
356     /// this bitfield have no name.
getter_name(&self) -> &str357     pub(crate) fn getter_name(&self) -> &str {
358         assert!(
359             self.name().is_some(),
360             "`Bitfield::getter_name` called on anonymous field"
361         );
362         self.getter_name.as_ref().expect(
363             "`Bitfield::getter_name` should only be called after\
364              assigning bitfield accessor names",
365         )
366     }
367 
368     /// Name of the generated Rust setter for this bitfield.
369     ///
370     /// Panics if called before assigning bitfield accessor names or if
371     /// this bitfield have no name.
setter_name(&self) -> &str372     pub(crate) fn setter_name(&self) -> &str {
373         assert!(
374             self.name().is_some(),
375             "`Bitfield::setter_name` called on anonymous field"
376         );
377         self.setter_name.as_ref().expect(
378             "`Bitfield::setter_name` should only be called\
379              after assigning bitfield accessor names",
380         )
381     }
382 }
383 
384 impl FieldMethods for Bitfield {
name(&self) -> Option<&str>385     fn name(&self) -> Option<&str> {
386         self.data.name()
387     }
388 
ty(&self) -> TypeId389     fn ty(&self) -> TypeId {
390         self.data.ty()
391     }
392 
comment(&self) -> Option<&str>393     fn comment(&self) -> Option<&str> {
394         self.data.comment()
395     }
396 
bitfield_width(&self) -> Option<u32>397     fn bitfield_width(&self) -> Option<u32> {
398         self.data.bitfield_width()
399     }
400 
is_public(&self) -> bool401     fn is_public(&self) -> bool {
402         self.data.is_public()
403     }
404 
annotations(&self) -> &Annotations405     fn annotations(&self) -> &Annotations {
406         self.data.annotations()
407     }
408 
offset(&self) -> Option<usize>409     fn offset(&self) -> Option<usize> {
410         self.data.offset()
411     }
412 }
413 
414 /// A raw field might be either of a plain data member or a bitfield within a
415 /// bitfield allocation unit, but we haven't processed it and determined which
416 /// yet (which would involve allocating it into a bitfield unit if it is a
417 /// bitfield).
418 #[derive(Debug)]
419 struct RawField(FieldData);
420 
421 impl RawField {
422     /// Construct a new `RawField`.
new( name: Option<String>, ty: TypeId, comment: Option<String>, annotations: Option<Annotations>, bitfield_width: Option<u32>, public: bool, offset: Option<usize>, ) -> RawField423     fn new(
424         name: Option<String>,
425         ty: TypeId,
426         comment: Option<String>,
427         annotations: Option<Annotations>,
428         bitfield_width: Option<u32>,
429         public: bool,
430         offset: Option<usize>,
431     ) -> RawField {
432         RawField(FieldData {
433             name,
434             ty,
435             comment,
436             annotations: annotations.unwrap_or_default(),
437             bitfield_width,
438             public,
439             offset,
440         })
441     }
442 }
443 
444 impl FieldMethods for RawField {
name(&self) -> Option<&str>445     fn name(&self) -> Option<&str> {
446         self.0.name()
447     }
448 
ty(&self) -> TypeId449     fn ty(&self) -> TypeId {
450         self.0.ty()
451     }
452 
comment(&self) -> Option<&str>453     fn comment(&self) -> Option<&str> {
454         self.0.comment()
455     }
456 
bitfield_width(&self) -> Option<u32>457     fn bitfield_width(&self) -> Option<u32> {
458         self.0.bitfield_width()
459     }
460 
is_public(&self) -> bool461     fn is_public(&self) -> bool {
462         self.0.is_public()
463     }
464 
annotations(&self) -> &Annotations465     fn annotations(&self) -> &Annotations {
466         self.0.annotations()
467     }
468 
offset(&self) -> Option<usize>469     fn offset(&self) -> Option<usize> {
470         self.0.offset()
471     }
472 }
473 
474 /// Convert the given ordered set of raw fields into a list of either plain data
475 /// members, and/or bitfield units containing multiple bitfields.
476 ///
477 /// If we do not have the layout for a bitfield's type, then we can't reliably
478 /// compute its allocation unit. In such cases, we return an error.
raw_fields_to_fields_and_bitfield_units<I>( ctx: &BindgenContext, raw_fields: I, packed: bool, ) -> Result<(Vec<Field>, bool), ()> where I: IntoIterator<Item = RawField>,479 fn raw_fields_to_fields_and_bitfield_units<I>(
480     ctx: &BindgenContext,
481     raw_fields: I,
482     packed: bool,
483 ) -> Result<(Vec<Field>, bool), ()>
484 where
485     I: IntoIterator<Item = RawField>,
486 {
487     let mut raw_fields = raw_fields.into_iter().fuse().peekable();
488     let mut fields = vec![];
489     let mut bitfield_unit_count = 0;
490 
491     loop {
492         // While we have plain old data members, just keep adding them to our
493         // resulting fields. We introduce a scope here so that we can use
494         // `raw_fields` again after the `by_ref` iterator adaptor is dropped.
495         {
496             let non_bitfields = raw_fields
497                 .by_ref()
498                 .map(|f| Field::DataMember(f.0));
499             fields.extend(non_bitfields);
500         }
501 
502         // Now gather all the consecutive bitfields. Only consecutive bitfields
503         // may potentially share a bitfield allocation unit with each other in
504         // the Itanium C++ ABI.
505         let mut bitfields = raw_fields
506             .by_ref()
507             .peekable();
508 
509         if bitfields.peek().is_none() {
510             break;
511         }
512 
513         bitfields_to_allocation_units(
514             ctx,
515             &mut bitfield_unit_count,
516             &mut fields,
517             bitfields,
518             packed,
519         )?;
520     }
521 
522     assert!(
523         raw_fields.next().is_none(),
524         "The above loop should consume all items in `raw_fields`"
525     );
526 
527     Ok((fields, bitfield_unit_count != 0))
528 }
529 
530 /// Given a set of contiguous raw bitfields, group and allocate them into
531 /// (potentially multiple) bitfield units.
bitfields_to_allocation_units<E, I>( ctx: &BindgenContext, bitfield_unit_count: &mut usize, fields: &mut E, raw_bitfields: I, packed: bool, ) -> Result<(), ()> where E: Extend<Field>, I: IntoIterator<Item = RawField>,532 fn bitfields_to_allocation_units<E, I>(
533     ctx: &BindgenContext,
534     bitfield_unit_count: &mut usize,
535     fields: &mut E,
536     raw_bitfields: I,
537     packed: bool,
538 ) -> Result<(), ()>
539 where
540     E: Extend<Field>,
541     I: IntoIterator<Item = RawField>,
542 {
543     assert!(ctx.collected_typerefs());
544 
545     // NOTE: What follows is reverse-engineered from LLVM's
546     // lib/AST/RecordLayoutBuilder.cpp
547     //
548     // FIXME(emilio): There are some differences between Microsoft and the
549     // Itanium ABI, but we'll ignore those and stick to Itanium for now.
550     //
551     // Also, we need to handle packed bitfields and stuff.
552     //
553     // TODO(emilio): Take into account C++'s wide bitfields, and
554     // packing, sigh.
555 
556     fn flush_allocation_unit<E>(
557         fields: &mut E,
558         bitfield_unit_count: &mut usize,
559         unit_size_in_bits: usize,
560         unit_align_in_bits: usize,
561         bitfields: Vec<Bitfield>,
562         packed: bool,
563     ) where
564         E: Extend<Field>,
565     {
566         *bitfield_unit_count += 1;
567         let align = if packed {
568             1
569         } else {
570             bytes_from_bits_pow2(unit_align_in_bits)
571         };
572         let size = align_to(unit_size_in_bits, 8) / 8;
573         let layout = Layout::new(size, align);
574         fields.extend(Some(Field::Bitfields(BitfieldUnit {
575             nth: *bitfield_unit_count,
576             layout,
577             bitfields,
578         })));
579     }
580 
581     let mut max_align = 0;
582     let mut unfilled_bits_in_unit = 0;
583     let mut unit_size_in_bits = 0;
584     let mut unit_align = 0;
585     let mut bitfields_in_unit = vec![];
586 
587     // TODO(emilio): Determine this from attributes or pragma ms_struct
588     // directives. Also, perhaps we should check if the target is MSVC?
589     const is_ms_struct: bool = false;
590 
591     for bitfield in raw_bitfields {
592         let bitfield_width = bitfield.bitfield_width().unwrap() as usize;
593         let bitfield_layout =
594             ctx.resolve_type(bitfield.ty()).layout(ctx).ok_or(())?;
595         let bitfield_size = bitfield_layout.size;
596         let bitfield_align = bitfield_layout.align;
597 
598         let mut offset = unit_size_in_bits;
599         if !packed {
600             if is_ms_struct {
601                 if unit_size_in_bits != 0 &&
602                     (bitfield_width == 0 ||
603                         bitfield_width > unfilled_bits_in_unit)
604                 {
605                     // We've reached the end of this allocation unit, so flush it
606                     // and its bitfields.
607                     unit_size_in_bits =
608                         align_to(unit_size_in_bits, unit_align * 8);
609                     flush_allocation_unit(
610                         fields,
611                         bitfield_unit_count,
612                         unit_size_in_bits,
613                         unit_align,
614                         mem::take(&mut bitfields_in_unit),
615                         packed,
616                     );
617 
618                     // Now we're working on a fresh bitfield allocation unit, so reset
619                     // the current unit size and alignment.
620                     offset = 0;
621                     unit_align = 0;
622                 }
623             } else if offset != 0 &&
624                 (bitfield_width == 0 ||
625                     (offset & (bitfield_align * 8 - 1)) + bitfield_width >
626                         bitfield_size * 8)
627             {
628                 offset = align_to(offset, bitfield_align * 8);
629             }
630         }
631 
632         // According to the x86[-64] ABI spec: "Unnamed bit-fields’ types do not
633         // affect the alignment of a structure or union". This makes sense: such
634         // bit-fields are only used for padding, and we can't perform an
635         // un-aligned read of something we can't read because we can't even name
636         // it.
637         if bitfield.name().is_some() {
638             max_align = cmp::max(max_align, bitfield_align);
639 
640             // NB: The `bitfield_width` here is completely, absolutely
641             // intentional.  Alignment of the allocation unit is based on the
642             // maximum bitfield width, not (directly) on the bitfields' types'
643             // alignment.
644             unit_align = cmp::max(unit_align, bitfield_width);
645         }
646 
647         // Always keep all bitfields around. While unnamed bitifields are used
648         // for padding (and usually not needed hereafter), large unnamed
649         // bitfields over their types size cause weird allocation size behavior from clang.
650         // Therefore, all bitfields needed to be kept around in order to check for this
651         // and make the struct opaque in this case
652         bitfields_in_unit.push(Bitfield::new(offset, bitfield));
653 
654         unit_size_in_bits = offset + bitfield_width;
655 
656         // Compute what the physical unit's final size would be given what we
657         // have seen so far, and use that to compute how many bits are still
658         // available in the unit.
659         let data_size = align_to(unit_size_in_bits, bitfield_align * 8);
660         unfilled_bits_in_unit = data_size - unit_size_in_bits;
661     }
662 
663     if unit_size_in_bits != 0 {
664         // Flush the last allocation unit and its bitfields.
665         flush_allocation_unit(
666             fields,
667             bitfield_unit_count,
668             unit_size_in_bits,
669             unit_align,
670             bitfields_in_unit,
671             packed,
672         );
673     }
674 
675     Ok(())
676 }
677 
678 /// A compound structure's fields are initially raw, and have bitfields that
679 /// have not been grouped into allocation units. During this time, the fields
680 /// are mutable and we build them up during parsing.
681 ///
682 /// Then, once resolving typerefs is completed, we compute all structs' fields'
683 /// bitfield allocation units, and they remain frozen and immutable forever
684 /// after.
685 #[derive(Debug)]
686 enum CompFields {
687     Before(Vec<RawField>),
688     After {
689         fields: Vec<Field>,
690         has_bitfield_units: bool,
691     },
692     Error,
693 }
694 
695 impl Default for CompFields {
default() -> CompFields696     fn default() -> CompFields {
697         CompFields::Before(vec![])
698     }
699 }
700 
701 impl CompFields {
append_raw_field(&mut self, raw: RawField)702     fn append_raw_field(&mut self, raw: RawField) {
703         match *self {
704             CompFields::Before(ref mut raws) => {
705                 raws.push(raw);
706             }
707             _ => {
708                 panic!(
709                     "Must not append new fields after computing bitfield allocation units"
710                 );
711             }
712         }
713     }
714 
compute_bitfield_units(&mut self, ctx: &BindgenContext, packed: bool)715     fn compute_bitfield_units(&mut self, ctx: &BindgenContext, packed: bool) {
716         let raws = match *self {
717             CompFields::Before(ref mut raws) => mem::take(raws),
718             _ => {
719                 panic!("Already computed bitfield units");
720             }
721         };
722 
723         let result = raw_fields_to_fields_and_bitfield_units(ctx, raws, packed);
724 
725         match result {
726             Ok((fields, has_bitfield_units)) => {
727                 *self = CompFields::After {
728                     fields,
729                     has_bitfield_units,
730                 };
731             }
732             Err(()) => {
733                 *self = CompFields::Error;
734             }
735         }
736     }
737 
deanonymize_fields(&mut self, ctx: &BindgenContext, methods: &[Method])738     fn deanonymize_fields(&mut self, ctx: &BindgenContext, methods: &[Method]) {
739         let fields = match *self {
740             CompFields::After { ref mut fields, .. } => fields,
741             // Nothing to do here.
742             CompFields::Error => return,
743             CompFields::Before(_) => {
744                 panic!("Not yet computed bitfield units.");
745             }
746         };
747 
748         fn has_method(
749             methods: &[Method],
750             ctx: &BindgenContext,
751             name: &str,
752         ) -> bool {
753             methods.iter().any(|method| {
754                 let method_name = ctx.resolve_func(method.signature()).name();
755                 method_name == name || ctx.rust_mangle(method_name) == name
756             })
757         }
758 
759         struct AccessorNamesPair {
760             getter: String,
761             setter: String,
762         }
763 
764         let mut accessor_names: HashMap<String, AccessorNamesPair> = fields
765             .iter()
766             .flat_map(|field| match *field {
767                 Field::Bitfields(ref bu) => &*bu.bitfields,
768                 Field::DataMember(_) => &[],
769             })
770             .filter_map(|bitfield| bitfield.name())
771             .map(|bitfield_name| {
772                 let bitfield_name = bitfield_name.to_string();
773                 let getter = {
774                     let mut getter =
775                         ctx.rust_mangle(&bitfield_name).to_string();
776                     if has_method(methods, ctx, &getter) {
777                         getter.push_str("_bindgen_bitfield");
778                     }
779                     getter
780                 };
781                 let setter = {
782                     let setter = format!("set_{}", bitfield_name);
783                     let mut setter = ctx.rust_mangle(&setter).to_string();
784                     if has_method(methods, ctx, &setter) {
785                         setter.push_str("_bindgen_bitfield");
786                     }
787                     setter
788                 };
789                 (bitfield_name, AccessorNamesPair { getter, setter })
790             })
791             .collect();
792 
793         let mut anon_field_counter = 0;
794         for field in fields.iter_mut() {
795             match *field {
796                 Field::DataMember(FieldData { ref mut name, .. }) => {
797                     if name.is_some() {
798                         continue;
799                     }
800 
801                     anon_field_counter += 1;
802                     *name = Some(format!(
803                         "{}{}",
804                         ctx.options().anon_fields_prefix,
805                         anon_field_counter
806                     ));
807                 }
808                 Field::Bitfields(ref mut bu) => {
809                     for bitfield in &mut bu.bitfields {
810                         if bitfield.name().is_none() {
811                             continue;
812                         }
813 
814                         if let Some(AccessorNamesPair { getter, setter }) =
815                             accessor_names.remove(bitfield.name().unwrap())
816                         {
817                             bitfield.getter_name = Some(getter);
818                             bitfield.setter_name = Some(setter);
819                         }
820                     }
821                 }
822             }
823         }
824     }
825 
826     /// Return the flex array member for the struct/class, if any.
flex_array_member(&self, ctx: &BindgenContext) -> Option<TypeId>827     fn flex_array_member(&self, ctx: &BindgenContext) -> Option<TypeId> {
828         let fields = match self {
829             CompFields::Before(_) => panic!("raw fields"),
830             CompFields::After { fields, .. } => fields,
831             CompFields::Error => return None, // panic?
832         };
833 
834         match fields.last()? {
835             Field::Bitfields(..) => None,
836             Field::DataMember(FieldData { ty, .. }) => ctx
837                 .resolve_type(*ty)
838                 .is_incomplete_array(ctx)
839                 .map(|item| item.expect_type_id(ctx)),
840         }
841     }
842 }
843 
844 impl Trace for CompFields {
845     type Extra = ();
846 
trace<T>(&self, context: &BindgenContext, tracer: &mut T, _: &()) where T: Tracer,847     fn trace<T>(&self, context: &BindgenContext, tracer: &mut T, _: &())
848     where
849         T: Tracer,
850     {
851         match *self {
852             CompFields::Error => {}
853             CompFields::Before(ref fields) => {
854                 for f in fields {
855                     tracer.visit_kind(f.ty().into(), EdgeKind::Field);
856                 }
857             }
858             CompFields::After { ref fields, .. } => {
859                 for f in fields {
860                     f.trace(context, tracer, &());
861                 }
862             }
863         }
864     }
865 }
866 
867 /// Common data shared across different field types.
868 #[derive(Clone, Debug)]
869 pub(crate) struct FieldData {
870     /// The name of the field, empty if it's an unnamed bitfield width.
871     name: Option<String>,
872 
873     /// The inner type.
874     ty: TypeId,
875 
876     /// The doc comment on the field if any.
877     comment: Option<String>,
878 
879     /// Annotations for this field, or the default.
880     annotations: Annotations,
881 
882     /// If this field is a bitfield, and how many bits does it contain if it is.
883     bitfield_width: Option<u32>,
884 
885     /// If the C++ field is declared `public`
886     public: bool,
887 
888     /// The offset of the field (in bits)
889     offset: Option<usize>,
890 }
891 
892 impl FieldMethods for FieldData {
name(&self) -> Option<&str>893     fn name(&self) -> Option<&str> {
894         self.name.as_deref()
895     }
896 
ty(&self) -> TypeId897     fn ty(&self) -> TypeId {
898         self.ty
899     }
900 
comment(&self) -> Option<&str>901     fn comment(&self) -> Option<&str> {
902         self.comment.as_deref()
903     }
904 
bitfield_width(&self) -> Option<u32>905     fn bitfield_width(&self) -> Option<u32> {
906         self.bitfield_width
907     }
908 
is_public(&self) -> bool909     fn is_public(&self) -> bool {
910         self.public
911     }
912 
annotations(&self) -> &Annotations913     fn annotations(&self) -> &Annotations {
914         &self.annotations
915     }
916 
offset(&self) -> Option<usize>917     fn offset(&self) -> Option<usize> {
918         self.offset
919     }
920 }
921 
922 /// The kind of inheritance a base class is using.
923 #[derive(Clone, Debug, PartialEq, Eq)]
924 pub(crate) enum BaseKind {
925     /// Normal inheritance, like:
926     ///
927     /// ```cpp
928     /// class A : public B {};
929     /// ```
930     Normal,
931     /// Virtual inheritance, like:
932     ///
933     /// ```cpp
934     /// class A: public virtual B {};
935     /// ```
936     Virtual,
937 }
938 
939 /// A base class.
940 #[derive(Clone, Debug)]
941 pub(crate) struct Base {
942     /// The type of this base class.
943     pub(crate) ty: TypeId,
944     /// The kind of inheritance we're doing.
945     pub(crate) kind: BaseKind,
946     /// Name of the field in which this base should be stored.
947     pub(crate) field_name: String,
948     /// Whether this base is inherited from publicly.
949     pub(crate) is_pub: bool,
950 }
951 
952 impl Base {
953     /// Whether this base class is inheriting virtually.
is_virtual(&self) -> bool954     pub(crate) fn is_virtual(&self) -> bool {
955         self.kind == BaseKind::Virtual
956     }
957 
958     /// Whether this base class should have it's own field for storage.
requires_storage(&self, ctx: &BindgenContext) -> bool959     pub(crate) fn requires_storage(&self, ctx: &BindgenContext) -> bool {
960         // Virtual bases are already taken into account by the vtable
961         // pointer.
962         //
963         // FIXME(emilio): Is this always right?
964         if self.is_virtual() {
965             return false;
966         }
967 
968         // NB: We won't include zero-sized types in our base chain because they
969         // would contribute to our size given the dummy field we insert for
970         // zero-sized types.
971         if self.ty.is_zero_sized(ctx) {
972             return false;
973         }
974 
975         true
976     }
977 
978     /// Whether this base is inherited from publicly.
is_public(&self) -> bool979     pub(crate) fn is_public(&self) -> bool {
980         self.is_pub
981     }
982 }
983 
984 /// A compound type.
985 ///
986 /// Either a struct or union, a compound type is built up from the combination
987 /// of fields which also are associated with their own (potentially compound)
988 /// type.
989 #[derive(Debug)]
990 pub(crate) struct CompInfo {
991     /// Whether this is a struct or a union.
992     kind: CompKind,
993 
994     /// The members of this struct or union.
995     fields: CompFields,
996 
997     /// The abstract template parameters of this class. Note that these are NOT
998     /// concrete template arguments, and should always be a
999     /// `Type(TypeKind::TypeParam(name))`. For concrete template arguments, see
1000     /// `TypeKind::TemplateInstantiation`.
1001     template_params: Vec<TypeId>,
1002 
1003     /// The method declarations inside this class, if in C++ mode.
1004     methods: Vec<Method>,
1005 
1006     /// The different constructors this struct or class contains.
1007     constructors: Vec<FunctionId>,
1008 
1009     /// The destructor of this type. The bool represents whether this destructor
1010     /// is virtual.
1011     destructor: Option<(MethodKind, FunctionId)>,
1012 
1013     /// Vector of classes this one inherits from.
1014     base_members: Vec<Base>,
1015 
1016     /// The inner types that were declared inside this class, in something like:
1017     ///
1018     /// class Foo {
1019     ///     typedef int FooTy;
1020     ///     struct Bar {
1021     ///         int baz;
1022     ///     };
1023     /// }
1024     ///
1025     /// static Foo::Bar const = {3};
1026     inner_types: Vec<TypeId>,
1027 
1028     /// Set of static constants declared inside this class.
1029     inner_vars: Vec<VarId>,
1030 
1031     /// Whether this type should generate an vtable (TODO: Should be able to
1032     /// look at the virtual methods and ditch this field).
1033     has_own_virtual_method: bool,
1034 
1035     /// Whether this type has destructor.
1036     has_destructor: bool,
1037 
1038     /// Whether this type has a base type with more than one member.
1039     ///
1040     /// TODO: We should be able to compute this.
1041     has_nonempty_base: bool,
1042 
1043     /// If this type has a template parameter which is not a type (e.g.: a
1044     /// size_t)
1045     has_non_type_template_params: bool,
1046 
1047     /// Whether this type has a bit field member whose width couldn't be
1048     /// evaluated (e.g. if it depends on a template parameter). We generate an
1049     /// opaque type in this case.
1050     has_unevaluable_bit_field_width: bool,
1051 
1052     /// Whether we saw `__attribute__((packed))` on or within this type.
1053     packed_attr: bool,
1054 
1055     /// Used to know if we've found an opaque attribute that could cause us to
1056     /// generate a type with invalid layout. This is explicitly used to avoid us
1057     /// generating bad alignments when parsing types like max_align_t.
1058     ///
1059     /// It's not clear what the behavior should be here, if generating the item
1060     /// and pray, or behave as an opaque type.
1061     found_unknown_attr: bool,
1062 
1063     /// Used to indicate when a struct has been forward declared. Usually used
1064     /// in headers so that APIs can't modify them directly.
1065     is_forward_declaration: bool,
1066 }
1067 
1068 impl CompInfo {
1069     /// Construct a new compound type.
new(kind: CompKind) -> Self1070     pub(crate) fn new(kind: CompKind) -> Self {
1071         CompInfo {
1072             kind,
1073             fields: CompFields::default(),
1074             template_params: vec![],
1075             methods: vec![],
1076             constructors: vec![],
1077             destructor: None,
1078             base_members: vec![],
1079             inner_types: vec![],
1080             inner_vars: vec![],
1081             has_own_virtual_method: false,
1082             has_destructor: false,
1083             has_nonempty_base: false,
1084             has_non_type_template_params: false,
1085             has_unevaluable_bit_field_width: false,
1086             packed_attr: false,
1087             found_unknown_attr: false,
1088             is_forward_declaration: false,
1089         }
1090     }
1091 
1092     /// Compute the layout of this type.
1093     ///
1094     /// This is called as a fallback under some circumstances where LLVM doesn't
1095     /// give us the correct layout.
1096     ///
1097     /// If we're a union without known layout, we try to compute it from our
1098     /// members. This is not ideal, but clang fails to report the size for these
1099     /// kind of unions, see test/headers/template_union.hpp
layout(&self, ctx: &BindgenContext) -> Option<Layout>1100     pub(crate) fn layout(&self, ctx: &BindgenContext) -> Option<Layout> {
1101         // We can't do better than clang here, sorry.
1102         if self.kind == CompKind::Struct {
1103             return None;
1104         }
1105 
1106         // By definition, we don't have the right layout information here if
1107         // we're a forward declaration.
1108         if self.is_forward_declaration() {
1109             return None;
1110         }
1111 
1112         // empty union case
1113         if !self.has_fields() {
1114             return None;
1115         }
1116 
1117         let mut max_size = 0;
1118         // Don't allow align(0)
1119         let mut max_align = 1;
1120         self.each_known_field_layout(ctx, |layout| {
1121             max_size = cmp::max(max_size, layout.size);
1122             max_align = cmp::max(max_align, layout.align);
1123         });
1124 
1125         Some(Layout::new(max_size, max_align))
1126     }
1127 
1128     /// Get this type's set of fields.
fields(&self) -> &[Field]1129     pub(crate) fn fields(&self) -> &[Field] {
1130         match self.fields {
1131             CompFields::Error => &[],
1132             CompFields::After { ref fields, .. } => fields,
1133             CompFields::Before(..) => {
1134                 panic!("Should always have computed bitfield units first");
1135             }
1136         }
1137     }
1138 
1139     /// Return the flex array member and its element type if any
flex_array_member( &self, ctx: &BindgenContext, ) -> Option<TypeId>1140     pub(crate) fn flex_array_member(
1141         &self,
1142         ctx: &BindgenContext,
1143     ) -> Option<TypeId> {
1144         self.fields.flex_array_member(ctx)
1145     }
1146 
has_fields(&self) -> bool1147     fn has_fields(&self) -> bool {
1148         match self.fields {
1149             CompFields::Error => false,
1150             CompFields::After { ref fields, .. } => !fields.is_empty(),
1151             CompFields::Before(ref raw_fields) => !raw_fields.is_empty(),
1152         }
1153     }
1154 
each_known_field_layout( &self, ctx: &BindgenContext, mut callback: impl FnMut(Layout), )1155     fn each_known_field_layout(
1156         &self,
1157         ctx: &BindgenContext,
1158         mut callback: impl FnMut(Layout),
1159     ) {
1160         match self.fields {
1161             CompFields::Error => {}
1162             CompFields::After { ref fields, .. } => {
1163                 for field in fields.iter() {
1164                     if let Some(layout) = field.layout(ctx) {
1165                         callback(layout);
1166                     }
1167                 }
1168             }
1169             CompFields::Before(ref raw_fields) => {
1170                 for field in raw_fields.iter() {
1171                     let field_ty = ctx.resolve_type(field.0.ty);
1172                     if let Some(layout) = field_ty.layout(ctx) {
1173                         callback(layout);
1174                     }
1175                 }
1176             }
1177         }
1178     }
1179 
has_bitfields(&self) -> bool1180     fn has_bitfields(&self) -> bool {
1181         match self.fields {
1182             CompFields::Error => false,
1183             CompFields::After {
1184                 has_bitfield_units, ..
1185             } => has_bitfield_units,
1186             CompFields::Before(_) => {
1187                 panic!("Should always have computed bitfield units first");
1188             }
1189         }
1190     }
1191 
1192     /// Returns whether we have a too large bitfield unit, in which case we may
1193     /// not be able to derive some of the things we should be able to normally
1194     /// derive.
has_too_large_bitfield_unit(&self) -> bool1195     pub(crate) fn has_too_large_bitfield_unit(&self) -> bool {
1196         if !self.has_bitfields() {
1197             return false;
1198         }
1199         self.fields().iter().any(|field| match *field {
1200             Field::DataMember(..) => false,
1201             Field::Bitfields(ref unit) => {
1202                 unit.layout.size > RUST_DERIVE_IN_ARRAY_LIMIT
1203             }
1204         })
1205     }
1206 
1207     /// Does this type have any template parameters that aren't types
1208     /// (e.g. int)?
has_non_type_template_params(&self) -> bool1209     pub(crate) fn has_non_type_template_params(&self) -> bool {
1210         self.has_non_type_template_params
1211     }
1212 
1213     /// Do we see a virtual function during parsing?
1214     /// Get the has_own_virtual_method boolean.
has_own_virtual_method(&self) -> bool1215     pub(crate) fn has_own_virtual_method(&self) -> bool {
1216         self.has_own_virtual_method
1217     }
1218 
1219     /// Did we see a destructor when parsing this type?
has_own_destructor(&self) -> bool1220     pub(crate) fn has_own_destructor(&self) -> bool {
1221         self.has_destructor
1222     }
1223 
1224     /// Get this type's set of methods.
methods(&self) -> &[Method]1225     pub(crate) fn methods(&self) -> &[Method] {
1226         &self.methods
1227     }
1228 
1229     /// Get this type's set of constructors.
constructors(&self) -> &[FunctionId]1230     pub(crate) fn constructors(&self) -> &[FunctionId] {
1231         &self.constructors
1232     }
1233 
1234     /// Get this type's destructor.
destructor(&self) -> Option<(MethodKind, FunctionId)>1235     pub(crate) fn destructor(&self) -> Option<(MethodKind, FunctionId)> {
1236         self.destructor
1237     }
1238 
1239     /// What kind of compound type is this?
kind(&self) -> CompKind1240     pub(crate) fn kind(&self) -> CompKind {
1241         self.kind
1242     }
1243 
1244     /// Is this a union?
is_union(&self) -> bool1245     pub(crate) fn is_union(&self) -> bool {
1246         self.kind() == CompKind::Union
1247     }
1248 
1249     /// The set of types that this one inherits from.
base_members(&self) -> &[Base]1250     pub(crate) fn base_members(&self) -> &[Base] {
1251         &self.base_members
1252     }
1253 
1254     /// Construct a new compound type from a Clang type.
from_ty( potential_id: ItemId, ty: &clang::Type, location: Option<clang::Cursor>, ctx: &mut BindgenContext, ) -> Result<Self, ParseError>1255     pub(crate) fn from_ty(
1256         potential_id: ItemId,
1257         ty: &clang::Type,
1258         location: Option<clang::Cursor>,
1259         ctx: &mut BindgenContext,
1260     ) -> Result<Self, ParseError> {
1261         use clang_sys::*;
1262         assert!(
1263             ty.template_args().is_none(),
1264             "We handle template instantiations elsewhere"
1265         );
1266 
1267         let mut cursor = ty.declaration();
1268         let mut kind = Self::kind_from_cursor(&cursor);
1269         if kind.is_err() {
1270             if let Some(location) = location {
1271                 kind = Self::kind_from_cursor(&location);
1272                 cursor = location;
1273             }
1274         }
1275 
1276         let kind = kind?;
1277 
1278         debug!("CompInfo::from_ty({:?}, {:?})", kind, cursor);
1279 
1280         let mut ci = CompInfo::new(kind);
1281         ci.is_forward_declaration =
1282             location.map_or(true, |cur| match cur.kind() {
1283                 CXCursor_ParmDecl => true,
1284                 CXCursor_StructDecl | CXCursor_UnionDecl |
1285                 CXCursor_ClassDecl => !cur.is_definition(),
1286                 _ => false,
1287             });
1288 
1289         let mut maybe_anonymous_struct_field = None;
1290         cursor.visit(|cur| {
1291             if cur.kind() != CXCursor_FieldDecl {
1292                 if let Some((ty, clang_ty, public, offset)) =
1293                     maybe_anonymous_struct_field.take()
1294                 {
1295                     if cur.kind() == CXCursor_TypedefDecl &&
1296                         cur.typedef_type().unwrap().canonical_type() ==
1297                             clang_ty
1298                     {
1299                         // Typedefs of anonymous structs appear later in the ast
1300                         // than the struct itself, that would otherwise be an
1301                         // anonymous field. Detect that case here, and do
1302                         // nothing.
1303                     } else {
1304                         let field = RawField::new(
1305                             None, ty, None, None, None, public, offset,
1306                         );
1307                         ci.fields.append_raw_field(field);
1308                     }
1309                 }
1310             }
1311 
1312             match cur.kind() {
1313                 CXCursor_FieldDecl => {
1314                     if let Some((ty, clang_ty, public, offset)) =
1315                         maybe_anonymous_struct_field.take()
1316                     {
1317                         let mut used = false;
1318                         cur.visit(|child| {
1319                             if child.cur_type() == clang_ty {
1320                                 used = true;
1321                             }
1322                             CXChildVisit_Continue
1323                         });
1324 
1325                         if !used {
1326                             let field = RawField::new(
1327                                 None, ty, None, None, None, public, offset,
1328                             );
1329                             ci.fields.append_raw_field(field);
1330                         }
1331                     }
1332 
1333                     let bit_width = if cur.is_bit_field() {
1334                         let width = cur.bit_width();
1335 
1336                         // Make opaque type if the bit width couldn't be
1337                         // evaluated.
1338                         if width.is_none() {
1339                             ci.has_unevaluable_bit_field_width = true;
1340                             return CXChildVisit_Break;
1341                         }
1342 
1343                         width
1344                     } else {
1345                         None
1346                     };
1347 
1348                     let field_type = Item::from_ty_or_ref(
1349                         cur.cur_type(),
1350                         cur,
1351                         Some(potential_id),
1352                         ctx,
1353                     );
1354 
1355                     let comment = cur.raw_comment();
1356                     let annotations = Annotations::new(&cur);
1357                     let name = cur.spelling();
1358                     let is_public = cur.public_accessible();
1359                     let offset = cur.offset_of_field().ok();
1360 
1361                     // Name can be empty if there are bitfields, for example,
1362                     // see tests/headers/struct_with_bitfields.h
1363                     assert!(
1364                         !name.is_empty() || bit_width.is_some(),
1365                         "Empty field name?"
1366                     );
1367 
1368                     let name = if name.is_empty() { None } else { Some(name) };
1369 
1370                     let field = RawField::new(
1371                         name,
1372                         field_type,
1373                         comment,
1374                         annotations,
1375                         bit_width,
1376                         is_public,
1377                         offset,
1378                     );
1379                     ci.fields.append_raw_field(field);
1380 
1381                     // No we look for things like attributes and stuff.
1382                     cur.visit(|cur| {
1383                         if cur.kind() == CXCursor_UnexposedAttr {
1384                             ci.found_unknown_attr = true;
1385                         }
1386                         CXChildVisit_Continue
1387                     });
1388                 }
1389                 CXCursor_UnexposedAttr => {
1390                     ci.found_unknown_attr = true;
1391                 }
1392                 CXCursor_EnumDecl |
1393                 CXCursor_TypeAliasDecl |
1394                 CXCursor_TypeAliasTemplateDecl |
1395                 CXCursor_TypedefDecl |
1396                 CXCursor_StructDecl |
1397                 CXCursor_UnionDecl |
1398                 CXCursor_ClassTemplate |
1399                 CXCursor_ClassDecl => {
1400                     // We can find non-semantic children here, clang uses a
1401                     // StructDecl to note incomplete structs that haven't been
1402                     // forward-declared before, see [1].
1403                     //
1404                     // Also, clang seems to scope struct definitions inside
1405                     // unions, and other named struct definitions inside other
1406                     // structs to the whole translation unit.
1407                     //
1408                     // Let's just assume that if the cursor we've found is a
1409                     // definition, it's a valid inner type.
1410                     //
1411                     // [1]: https://github.com/rust-lang/rust-bindgen/issues/482
1412                     let is_inner_struct =
1413                         cur.semantic_parent() == cursor || cur.is_definition();
1414                     if !is_inner_struct {
1415                         return CXChildVisit_Continue;
1416                     }
1417 
1418                     // Even if this is a definition, we may not be the semantic
1419                     // parent, see #1281.
1420                     let inner = Item::parse(cur, Some(potential_id), ctx)
1421                         .expect("Inner ClassDecl");
1422 
1423                     // If we avoided recursion parsing this type (in
1424                     // `Item::from_ty_with_id()`), then this might not be a
1425                     // valid type ID, so check and gracefully handle this.
1426                     if ctx.resolve_item_fallible(inner).is_some() {
1427                         let inner = inner.expect_type_id(ctx);
1428 
1429                         ci.inner_types.push(inner);
1430 
1431                         // A declaration of an union or a struct without name
1432                         // could also be an unnamed field, unfortunately.
1433                         if cur.is_anonymous() && cur.kind() != CXCursor_EnumDecl
1434                         {
1435                             let ty = cur.cur_type();
1436                             let public = cur.public_accessible();
1437                             let offset = cur.offset_of_field().ok();
1438 
1439                             maybe_anonymous_struct_field =
1440                                 Some((inner, ty, public, offset));
1441                         }
1442                     }
1443                 }
1444                 CXCursor_PackedAttr => {
1445                     ci.packed_attr = true;
1446                 }
1447                 CXCursor_TemplateTypeParameter => {
1448                     let param = Item::type_param(None, cur, ctx).expect(
1449                         "Item::type_param shouldn't fail when pointing \
1450                          at a TemplateTypeParameter",
1451                     );
1452                     ci.template_params.push(param);
1453                 }
1454                 CXCursor_CXXBaseSpecifier => {
1455                     let is_virtual_base = cur.is_virtual_base();
1456                     ci.has_own_virtual_method |= is_virtual_base;
1457 
1458                     let kind = if is_virtual_base {
1459                         BaseKind::Virtual
1460                     } else {
1461                         BaseKind::Normal
1462                     };
1463 
1464                     let field_name = match ci.base_members.len() {
1465                         0 => "_base".into(),
1466                         n => format!("_base_{}", n),
1467                     };
1468                     let type_id =
1469                         Item::from_ty_or_ref(cur.cur_type(), cur, None, ctx);
1470                     ci.base_members.push(Base {
1471                         ty: type_id,
1472                         kind,
1473                         field_name,
1474                         is_pub: cur.access_specifier() ==
1475                             clang_sys::CX_CXXPublic,
1476                     });
1477                 }
1478                 CXCursor_Constructor | CXCursor_Destructor |
1479                 CXCursor_CXXMethod => {
1480                     let is_virtual = cur.method_is_virtual();
1481                     let is_static = cur.method_is_static();
1482                     debug_assert!(!(is_static && is_virtual), "How?");
1483 
1484                     ci.has_destructor |= cur.kind() == CXCursor_Destructor;
1485                     ci.has_own_virtual_method |= is_virtual;
1486 
1487                     // This used to not be here, but then I tried generating
1488                     // stylo bindings with this (without path filters), and
1489                     // cried a lot with a method in gfx/Point.h
1490                     // (ToUnknownPoint), that somehow was causing the same type
1491                     // to be inserted in the map two times.
1492                     //
1493                     // I couldn't make a reduced test case, but anyway...
1494                     // Methods of template functions not only used to be inlined,
1495                     // but also instantiated, and we wouldn't be able to call
1496                     // them, so just bail out.
1497                     if !ci.template_params.is_empty() {
1498                         return CXChildVisit_Continue;
1499                     }
1500 
1501                     // NB: This gets us an owned `Function`, not a
1502                     // `FunctionSig`.
1503                     let signature =
1504                         match Item::parse(cur, Some(potential_id), ctx) {
1505                             Ok(item)
1506                                 if ctx
1507                                     .resolve_item(item)
1508                                     .kind()
1509                                     .is_function() =>
1510                             {
1511                                 item
1512                             }
1513                             _ => return CXChildVisit_Continue,
1514                         };
1515 
1516                     let signature = signature.expect_function_id(ctx);
1517 
1518                     match cur.kind() {
1519                         CXCursor_Constructor => {
1520                             ci.constructors.push(signature);
1521                         }
1522                         CXCursor_Destructor => {
1523                             let kind = if is_virtual {
1524                                 MethodKind::VirtualDestructor {
1525                                     pure_virtual: cur.method_is_pure_virtual(),
1526                                 }
1527                             } else {
1528                                 MethodKind::Destructor
1529                             };
1530                             ci.destructor = Some((kind, signature));
1531                         }
1532                         CXCursor_CXXMethod => {
1533                             let is_const = cur.method_is_const();
1534                             let method_kind = if is_static {
1535                                 MethodKind::Static
1536                             } else if is_virtual {
1537                                 MethodKind::Virtual {
1538                                     pure_virtual: cur.method_is_pure_virtual(),
1539                                 }
1540                             } else {
1541                                 MethodKind::Normal
1542                             };
1543 
1544                             let method =
1545                                 Method::new(method_kind, signature, is_const);
1546 
1547                             ci.methods.push(method);
1548                         }
1549                         _ => unreachable!("How can we see this here?"),
1550                     }
1551                 }
1552                 CXCursor_NonTypeTemplateParameter => {
1553                     ci.has_non_type_template_params = true;
1554                 }
1555                 CXCursor_VarDecl => {
1556                     let linkage = cur.linkage();
1557                     if linkage != CXLinkage_External &&
1558                         linkage != CXLinkage_UniqueExternal
1559                     {
1560                         return CXChildVisit_Continue;
1561                     }
1562 
1563                     let visibility = cur.visibility();
1564                     if visibility != CXVisibility_Default {
1565                         return CXChildVisit_Continue;
1566                     }
1567 
1568                     if let Ok(item) = Item::parse(cur, Some(potential_id), ctx)
1569                     {
1570                         ci.inner_vars.push(item.as_var_id_unchecked());
1571                     }
1572                 }
1573                 // Intentionally not handled
1574                 CXCursor_CXXAccessSpecifier |
1575                 CXCursor_CXXFinalAttr |
1576                 CXCursor_FunctionTemplate |
1577                 CXCursor_ConversionFunction => {}
1578                 _ => {
1579                     warn!(
1580                         "unhandled comp member `{}` (kind {:?}) in `{}` ({})",
1581                         cur.spelling(),
1582                         clang::kind_to_str(cur.kind()),
1583                         cursor.spelling(),
1584                         cur.location()
1585                     );
1586                 }
1587             }
1588             CXChildVisit_Continue
1589         });
1590 
1591         if let Some((ty, _, public, offset)) = maybe_anonymous_struct_field {
1592             let field =
1593                 RawField::new(None, ty, None, None, None, public, offset);
1594             ci.fields.append_raw_field(field);
1595         }
1596 
1597         Ok(ci)
1598     }
1599 
kind_from_cursor( cursor: &clang::Cursor, ) -> Result<CompKind, ParseError>1600     fn kind_from_cursor(
1601         cursor: &clang::Cursor,
1602     ) -> Result<CompKind, ParseError> {
1603         use clang_sys::*;
1604         Ok(match cursor.kind() {
1605             CXCursor_UnionDecl => CompKind::Union,
1606             CXCursor_ClassDecl | CXCursor_StructDecl => CompKind::Struct,
1607             CXCursor_CXXBaseSpecifier |
1608             CXCursor_ClassTemplatePartialSpecialization |
1609             CXCursor_ClassTemplate => match cursor.template_kind() {
1610                 CXCursor_UnionDecl => CompKind::Union,
1611                 _ => CompKind::Struct,
1612             },
1613             _ => {
1614                 warn!("Unknown kind for comp type: {:?}", cursor);
1615                 return Err(ParseError::Continue);
1616             }
1617         })
1618     }
1619 
1620     /// Get the set of types that were declared within this compound type
1621     /// (e.g. nested class definitions).
inner_types(&self) -> &[TypeId]1622     pub(crate) fn inner_types(&self) -> &[TypeId] {
1623         &self.inner_types
1624     }
1625 
1626     /// Get the set of static variables declared within this compound type.
inner_vars(&self) -> &[VarId]1627     pub(crate) fn inner_vars(&self) -> &[VarId] {
1628         &self.inner_vars
1629     }
1630 
1631     /// Have we found a field with an opaque type that could potentially mess up
1632     /// the layout of this compound type?
found_unknown_attr(&self) -> bool1633     pub(crate) fn found_unknown_attr(&self) -> bool {
1634         self.found_unknown_attr
1635     }
1636 
1637     /// Is this compound type packed?
is_packed( &self, ctx: &BindgenContext, layout: Option<&Layout>, ) -> bool1638     pub(crate) fn is_packed(
1639         &self,
1640         ctx: &BindgenContext,
1641         layout: Option<&Layout>,
1642     ) -> bool {
1643         if self.packed_attr {
1644             return true;
1645         }
1646 
1647         // Even though `libclang` doesn't expose `#pragma packed(...)`, we can
1648         // detect it through its effects.
1649         if let Some(parent_layout) = layout {
1650             let mut packed = false;
1651             self.each_known_field_layout(ctx, |layout| {
1652                 packed = packed || layout.align > parent_layout.align;
1653             });
1654             if packed {
1655                 info!("Found a struct that was defined within `#pragma packed(...)`");
1656                 return true;
1657             }
1658 
1659             if self.has_own_virtual_method && parent_layout.align == 1 {
1660                 return true;
1661             }
1662         }
1663 
1664         false
1665     }
1666 
1667     /// Return true if a compound type is "naturally packed". This means we can exclude the
1668     /// "packed" attribute without changing the layout.
1669     /// This is useful for types that need an "align(N)" attribute since rustc won't compile
1670     /// structs that have both of those attributes.
already_packed(&self, ctx: &BindgenContext) -> Option<bool>1671     pub(crate) fn already_packed(&self, ctx: &BindgenContext) -> Option<bool> {
1672         let mut total_size: usize = 0;
1673 
1674         for field in self.fields().iter() {
1675             let layout = field.layout(ctx)?;
1676 
1677             if layout.align != 0 && total_size % layout.align != 0 {
1678                 return Some(false);
1679             }
1680 
1681             total_size += layout.size;
1682         }
1683 
1684         Some(true)
1685     }
1686 
1687     /// Returns true if compound type has been forward declared
is_forward_declaration(&self) -> bool1688     pub(crate) fn is_forward_declaration(&self) -> bool {
1689         self.is_forward_declaration
1690     }
1691 
1692     /// Compute this compound structure's bitfield allocation units.
compute_bitfield_units( &mut self, ctx: &BindgenContext, layout: Option<&Layout>, )1693     pub(crate) fn compute_bitfield_units(
1694         &mut self,
1695         ctx: &BindgenContext,
1696         layout: Option<&Layout>,
1697     ) {
1698         let packed = self.is_packed(ctx, layout);
1699         self.fields.compute_bitfield_units(ctx, packed)
1700     }
1701 
1702     /// Assign for each anonymous field a generated name.
deanonymize_fields(&mut self, ctx: &BindgenContext)1703     pub(crate) fn deanonymize_fields(&mut self, ctx: &BindgenContext) {
1704         self.fields.deanonymize_fields(ctx, &self.methods);
1705     }
1706 
1707     /// Returns whether the current union can be represented as a Rust `union`
1708     ///
1709     /// Requirements:
1710     ///     1. Current RustTarget allows for `untagged_union`
1711     ///     2. Each field can derive `Copy` or we use ManuallyDrop.
1712     ///     3. It's not zero-sized.
1713     ///
1714     /// Second boolean returns whether all fields can be copied (and thus
1715     /// ManuallyDrop is not needed).
is_rust_union( &self, ctx: &BindgenContext, layout: Option<&Layout>, name: &str, ) -> (bool, bool)1716     pub(crate) fn is_rust_union(
1717         &self,
1718         ctx: &BindgenContext,
1719         layout: Option<&Layout>,
1720         name: &str,
1721     ) -> (bool, bool) {
1722         if !self.is_union() {
1723             return (false, false);
1724         }
1725 
1726         if !ctx.options().untagged_union {
1727             return (false, false);
1728         }
1729 
1730         if self.is_forward_declaration() {
1731             return (false, false);
1732         }
1733 
1734         let union_style = if ctx.options().bindgen_wrapper_union.matches(name) {
1735             NonCopyUnionStyle::BindgenWrapper
1736         } else if ctx.options().manually_drop_union.matches(name) {
1737             NonCopyUnionStyle::ManuallyDrop
1738         } else {
1739             ctx.options().default_non_copy_union_style
1740         };
1741 
1742         let all_can_copy = self.fields().iter().all(|f| match *f {
1743             Field::DataMember(ref field_data) => {
1744                 field_data.ty().can_derive_copy(ctx)
1745             }
1746             Field::Bitfields(_) => true,
1747         });
1748 
1749         if !all_can_copy && union_style == NonCopyUnionStyle::BindgenWrapper {
1750             return (false, false);
1751         }
1752 
1753         if layout.map_or(false, |l| l.size == 0) {
1754             return (false, false);
1755         }
1756 
1757         (true, all_can_copy)
1758     }
1759 }
1760 
1761 impl DotAttributes for CompInfo {
dot_attributes<W>( &self, ctx: &BindgenContext, out: &mut W, ) -> io::Result<()> where W: io::Write,1762     fn dot_attributes<W>(
1763         &self,
1764         ctx: &BindgenContext,
1765         out: &mut W,
1766     ) -> io::Result<()>
1767     where
1768         W: io::Write,
1769     {
1770         writeln!(out, "<tr><td>CompKind</td><td>{:?}</td></tr>", self.kind)?;
1771 
1772         if self.has_own_virtual_method {
1773             writeln!(out, "<tr><td>has_vtable</td><td>true</td></tr>")?;
1774         }
1775 
1776         if self.has_destructor {
1777             writeln!(out, "<tr><td>has_destructor</td><td>true</td></tr>")?;
1778         }
1779 
1780         if self.has_nonempty_base {
1781             writeln!(out, "<tr><td>has_nonempty_base</td><td>true</td></tr>")?;
1782         }
1783 
1784         if self.has_non_type_template_params {
1785             writeln!(
1786                 out,
1787                 "<tr><td>has_non_type_template_params</td><td>true</td></tr>"
1788             )?;
1789         }
1790 
1791         if self.packed_attr {
1792             writeln!(out, "<tr><td>packed_attr</td><td>true</td></tr>")?;
1793         }
1794 
1795         if self.is_forward_declaration {
1796             writeln!(
1797                 out,
1798                 "<tr><td>is_forward_declaration</td><td>true</td></tr>"
1799             )?;
1800         }
1801 
1802         if !self.fields().is_empty() {
1803             writeln!(out, r#"<tr><td>fields</td><td><table border="0">"#)?;
1804             for field in self.fields() {
1805                 field.dot_attributes(ctx, out)?;
1806             }
1807             writeln!(out, "</table></td></tr>")?;
1808         }
1809 
1810         Ok(())
1811     }
1812 }
1813 
1814 impl IsOpaque for CompInfo {
1815     type Extra = Option<Layout>;
1816 
is_opaque(&self, ctx: &BindgenContext, layout: &Option<Layout>) -> bool1817     fn is_opaque(&self, ctx: &BindgenContext, layout: &Option<Layout>) -> bool {
1818         if self.has_non_type_template_params ||
1819             self.has_unevaluable_bit_field_width
1820         {
1821             return true;
1822         }
1823 
1824         // When we do not have the layout for a bitfield's type (for example, it
1825         // is a type parameter), then we can't compute bitfield units. We are
1826         // left with no choice but to make the whole struct opaque, or else we
1827         // might generate structs with incorrect sizes and alignments.
1828         if let CompFields::Error = self.fields {
1829             return true;
1830         }
1831 
1832         // Bitfields with a width that is larger than their unit's width have
1833         // some strange things going on, and the best we can do is make the
1834         // whole struct opaque.
1835         if self.fields().iter().any(|f| match *f {
1836             Field::DataMember(_) => false,
1837             Field::Bitfields(ref unit) => unit.bitfields().iter().any(|bf| {
1838                 let bitfield_layout = ctx
1839                     .resolve_type(bf.ty())
1840                     .layout(ctx)
1841                     .expect("Bitfield without layout? Gah!");
1842                 bf.width() / 8 > bitfield_layout.size as u32
1843             }),
1844         }) {
1845             return true;
1846         }
1847 
1848         if !ctx.options().rust_features().repr_packed_n {
1849             // If we don't have `#[repr(packed(N)]`, the best we can
1850             // do is make this struct opaque.
1851             //
1852             // See https://github.com/rust-lang/rust-bindgen/issues/537 and
1853             // https://github.com/rust-lang/rust/issues/33158
1854             if self.is_packed(ctx, layout.as_ref()) &&
1855                 layout.map_or(false, |l| l.align > 1)
1856             {
1857                 warn!("Found a type that is both packed and aligned to greater than \
1858                        1; Rust before version 1.33 doesn't have `#[repr(packed(N))]`, so we \
1859                        are treating it as opaque. You may wish to set bindgen's rust target \
1860                        version to 1.33 or later to enable `#[repr(packed(N))]` support.");
1861                 return true;
1862             }
1863         }
1864 
1865         false
1866     }
1867 }
1868 
1869 impl TemplateParameters for CompInfo {
self_template_params(&self, _ctx: &BindgenContext) -> Vec<TypeId>1870     fn self_template_params(&self, _ctx: &BindgenContext) -> Vec<TypeId> {
1871         self.template_params.clone()
1872     }
1873 }
1874 
1875 impl Trace for CompInfo {
1876     type Extra = Item;
1877 
trace<T>(&self, context: &BindgenContext, tracer: &mut T, item: &Item) where T: Tracer,1878     fn trace<T>(&self, context: &BindgenContext, tracer: &mut T, item: &Item)
1879     where
1880         T: Tracer,
1881     {
1882         for p in item.all_template_params(context) {
1883             tracer.visit_kind(p.into(), EdgeKind::TemplateParameterDefinition);
1884         }
1885 
1886         for ty in self.inner_types() {
1887             tracer.visit_kind(ty.into(), EdgeKind::InnerType);
1888         }
1889 
1890         for &var in self.inner_vars() {
1891             tracer.visit_kind(var.into(), EdgeKind::InnerVar);
1892         }
1893 
1894         for method in self.methods() {
1895             tracer.visit_kind(method.signature.into(), EdgeKind::Method);
1896         }
1897 
1898         if let Some((_kind, signature)) = self.destructor() {
1899             tracer.visit_kind(signature.into(), EdgeKind::Destructor);
1900         }
1901 
1902         for ctor in self.constructors() {
1903             tracer.visit_kind(ctor.into(), EdgeKind::Constructor);
1904         }
1905 
1906         // Base members and fields are not generated for opaque types (but all
1907         // of the above things are) so stop here.
1908         if item.is_opaque(context, &()) {
1909             return;
1910         }
1911 
1912         for base in self.base_members() {
1913             tracer.visit_kind(base.ty.into(), EdgeKind::BaseMember);
1914         }
1915 
1916         self.fields.trace(context, tracer, &());
1917     }
1918 }
1919