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