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