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::ty::RUST_DERIVE_IN_ARRAY_LIMIT;
10 use super::template::TemplateParameters;
11 use super::traversal::{EdgeKind, Trace, Tracer};
12 use clang;
13 use codegen::struct_layout::{align_to, bytes_from_bits_pow2};
14 use ir::derive::CanDeriveCopy;
15 use parse::{ClangItemParser, ParseError};
16 use peeking_take_while::PeekableExt;
17 use std::cmp;
18 use std::io;
19 use std::mem;
20 use HashMap;
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 field marked as `mutable`?
is_mutable(&self) -> bool152     fn is_mutable(&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_mutable(&self) -> bool418     fn is_mutable(&self) -> bool {
419         self.data.is_mutable()
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>, mutable: 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         mutable: 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             mutable,
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_mutable(&self) -> bool478     fn is_mutable(&self) -> bool {
479         self.0.is_mutable()
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, ) -> Result<Vec<Field>, ()> where I: IntoIterator<Item = RawField>,496 fn raw_fields_to_fields_and_bitfield_units<I>(
497     ctx: &BindgenContext,
498     raw_fields: I,
499 ) -> Result<Vec<Field>, ()>
500 where
501     I: IntoIterator<Item = RawField>,
502 {
503     let mut raw_fields = raw_fields.into_iter().fuse().peekable();
504     let mut fields = vec![];
505     let mut bitfield_unit_count = 0;
506 
507     loop {
508         // While we have plain old data members, just keep adding them to our
509         // resulting fields. We introduce a scope here so that we can use
510         // `raw_fields` again after the `by_ref` iterator adaptor is dropped.
511         {
512             let non_bitfields = raw_fields
513                 .by_ref()
514                 .peeking_take_while(|f| f.bitfield_width().is_none())
515                 .map(|f| Field::DataMember(f.0));
516             fields.extend(non_bitfields);
517         }
518 
519         // Now gather all the consecutive bitfields. Only consecutive bitfields
520         // may potentially share a bitfield allocation unit with each other in
521         // the Itanium C++ ABI.
522         let mut bitfields = raw_fields
523             .by_ref()
524             .peeking_take_while(|f| f.bitfield_width().is_some())
525             .peekable();
526 
527         if bitfields.peek().is_none() {
528             break;
529         }
530 
531         bitfields_to_allocation_units(
532             ctx,
533             &mut bitfield_unit_count,
534             &mut fields,
535             bitfields,
536         )?;
537     }
538 
539     assert!(
540         raw_fields.next().is_none(),
541         "The above loop should consume all items in `raw_fields`"
542     );
543 
544     Ok(fields)
545 }
546 
547 /// Given a set of contiguous raw bitfields, group and allocate them into
548 /// (potentially multiple) bitfield units.
bitfields_to_allocation_units<E, I>( ctx: &BindgenContext, bitfield_unit_count: &mut usize, fields: &mut E, raw_bitfields: I, ) -> Result<(), ()> where E: Extend<Field>, I: IntoIterator<Item = RawField>,549 fn bitfields_to_allocation_units<E, I>(
550     ctx: &BindgenContext,
551     bitfield_unit_count: &mut usize,
552     fields: &mut E,
553     raw_bitfields: I,
554 ) -> Result<(), ()>
555 where
556     E: Extend<Field>,
557     I: IntoIterator<Item = RawField>,
558 {
559     assert!(ctx.collected_typerefs());
560 
561     // NOTE: What follows is reverse-engineered from LLVM's
562     // lib/AST/RecordLayoutBuilder.cpp
563     //
564     // FIXME(emilio): There are some differences between Microsoft and the
565     // Itanium ABI, but we'll ignore those and stick to Itanium for now.
566     //
567     // Also, we need to handle packed bitfields and stuff.
568     //
569     // TODO(emilio): Take into account C++'s wide bitfields, and
570     // packing, sigh.
571 
572     fn flush_allocation_unit<E>(
573         fields: &mut E,
574         bitfield_unit_count: &mut usize,
575         unit_size_in_bits: usize,
576         unit_align_in_bits: usize,
577         bitfields: Vec<Bitfield>,
578     ) where
579         E: Extend<Field>,
580     {
581         *bitfield_unit_count += 1;
582         let align = bytes_from_bits_pow2(unit_align_in_bits);
583         let size = align_to(unit_size_in_bits, align * 8) / 8;
584         let layout = Layout::new(size, align);
585         fields.extend(Some(Field::Bitfields(BitfieldUnit {
586             nth: *bitfield_unit_count,
587             layout: layout,
588             bitfields: bitfields,
589         })));
590     }
591 
592     let mut max_align = 0;
593     let mut unfilled_bits_in_unit = 0;
594     let mut unit_size_in_bits = 0;
595     let mut unit_align = 0;
596     let mut bitfields_in_unit = vec![];
597 
598     // TODO(emilio): Determine this from attributes or pragma ms_struct
599     // directives. Also, perhaps we should check if the target is MSVC?
600     const is_ms_struct: bool = false;
601 
602     for bitfield in raw_bitfields {
603         let bitfield_width = bitfield.bitfield_width().unwrap() as usize;
604         let bitfield_layout =
605             ctx.resolve_type(bitfield.ty()).layout(ctx).ok_or(())?;
606         let bitfield_size = bitfield_layout.size;
607         let bitfield_align = bitfield_layout.align;
608 
609         let mut offset = unit_size_in_bits;
610         if is_ms_struct {
611             if unit_size_in_bits != 0 &&
612                 (bitfield_width == 0 ||
613                     bitfield_width > unfilled_bits_in_unit)
614             {
615                 // We've reached the end of this allocation unit, so flush it
616                 // and its bitfields.
617                 unit_size_in_bits = align_to(unit_size_in_bits, unit_align * 8);
618                 flush_allocation_unit(
619                     fields,
620                     bitfield_unit_count,
621                     unit_size_in_bits,
622                     unit_align,
623                     mem::replace(&mut bitfields_in_unit, vec![]),
624                 );
625 
626                 // Now we're working on a fresh bitfield allocation unit, so reset
627                 // the current unit size and alignment.
628                 offset = 0;
629                 unit_align = 0;
630             }
631         } else {
632             if offset != 0 &&
633                 (bitfield_width == 0 ||
634                     (offset & (bitfield_align * 8 - 1)) + bitfield_width >
635                         bitfield_size * 8)
636             {
637                 offset = align_to(offset, bitfield_align * 8);
638             }
639         }
640 
641         // According to the x86[-64] ABI spec: "Unnamed bit-fields’ types do not
642         // affect the alignment of a structure or union". This makes sense: such
643         // bit-fields are only used for padding, and we can't perform an
644         // un-aligned read of something we can't read because we can't even name
645         // it.
646         if bitfield.name().is_some() {
647             max_align = cmp::max(max_align, bitfield_align);
648 
649             // NB: The `bitfield_width` here is completely, absolutely
650             // intentional.  Alignment of the allocation unit is based on the
651             // maximum bitfield width, not (directly) on the bitfields' types'
652             // alignment.
653             unit_align = cmp::max(unit_align, bitfield_width);
654         }
655 
656         // Always keep all bitfields around. While unnamed bitifields are used
657         // for padding (and usually not needed hereafter), large unnamed
658         // bitfields over their types size cause weird allocation size behavior from clang.
659         // Therefore, all bitfields needed to be kept around in order to check for this
660         // and make the struct opaque in this case
661         bitfields_in_unit.push(Bitfield::new(offset, bitfield));
662 
663         unit_size_in_bits = offset + bitfield_width;
664 
665         // Compute what the physical unit's final size would be given what we
666         // have seen so far, and use that to compute how many bits are still
667         // available in the unit.
668         let data_size = align_to(unit_size_in_bits, bitfield_align * 8);
669         unfilled_bits_in_unit = data_size - unit_size_in_bits;
670     }
671 
672     if unit_size_in_bits != 0 {
673         // Flush the last allocation unit and its bitfields.
674         flush_allocation_unit(
675             fields,
676             bitfield_unit_count,
677             unit_size_in_bits,
678             unit_align,
679             bitfields_in_unit,
680         );
681     }
682 
683     Ok(())
684 }
685 
686 /// A compound structure's fields are initially raw, and have bitfields that
687 /// have not been grouped into allocation units. During this time, the fields
688 /// are mutable and we build them up during parsing.
689 ///
690 /// Then, once resolving typerefs is completed, we compute all structs' fields'
691 /// bitfield allocation units, and they remain frozen and immutable forever
692 /// after.
693 #[derive(Debug)]
694 enum CompFields {
695     BeforeComputingBitfieldUnits(Vec<RawField>),
696     AfterComputingBitfieldUnits(Vec<Field>),
697     ErrorComputingBitfieldUnits,
698 }
699 
700 impl Default for CompFields {
default() -> CompFields701     fn default() -> CompFields {
702         CompFields::BeforeComputingBitfieldUnits(vec![])
703     }
704 }
705 
706 impl CompFields {
append_raw_field(&mut self, raw: RawField)707     fn append_raw_field(&mut self, raw: RawField) {
708         match *self {
709             CompFields::BeforeComputingBitfieldUnits(ref mut raws) => {
710                 raws.push(raw);
711             }
712             _ => {
713                 panic!(
714                     "Must not append new fields after computing bitfield allocation units"
715                 );
716             }
717         }
718     }
719 
compute_bitfield_units(&mut self, ctx: &BindgenContext)720     fn compute_bitfield_units(&mut self, ctx: &BindgenContext) {
721         let raws = match *self {
722             CompFields::BeforeComputingBitfieldUnits(ref mut raws) => {
723                 mem::replace(raws, vec![])
724             }
725             _ => {
726                 panic!("Already computed bitfield units");
727             }
728         };
729 
730         let result = raw_fields_to_fields_and_bitfield_units(ctx, raws);
731 
732         match result {
733             Ok(fields_and_units) => {
734                 mem::replace(
735                     self,
736                     CompFields::AfterComputingBitfieldUnits(fields_and_units),
737                 );
738             }
739             Err(()) => {
740                 mem::replace(self, CompFields::ErrorComputingBitfieldUnits);
741             }
742         }
743     }
744 
deanonymize_fields(&mut self, ctx: &BindgenContext, methods: &[Method])745     fn deanonymize_fields(&mut self, ctx: &BindgenContext, methods: &[Method]) {
746         let fields = match *self {
747             CompFields::AfterComputingBitfieldUnits(ref mut fields) => fields,
748             CompFields::ErrorComputingBitfieldUnits => {
749                 // Nothing to do here.
750                 return;
751             }
752             CompFields::BeforeComputingBitfieldUnits(_) => {
753                 panic!("Not yet computed bitfield units.");
754             }
755         };
756 
757         fn has_method(
758             methods: &[Method],
759             ctx: &BindgenContext,
760             name: &str,
761         ) -> bool {
762             methods.iter().any(|method| {
763                 let method_name = ctx.resolve_func(method.signature()).name();
764                 method_name == name || ctx.rust_mangle(&method_name) == name
765             })
766         }
767 
768         struct AccessorNamesPair {
769             getter: String,
770             setter: String,
771         }
772 
773         let mut accessor_names: HashMap<String, AccessorNamesPair> = fields
774             .iter()
775             .flat_map(|field| match *field {
776                 Field::Bitfields(ref bu) => &*bu.bitfields,
777                 Field::DataMember(_) => &[],
778             })
779             .filter_map(|bitfield| bitfield.name())
780             .map(|bitfield_name| {
781                 let bitfield_name = bitfield_name.to_string();
782                 let getter = {
783                     let mut getter =
784                         ctx.rust_mangle(&bitfield_name).to_string();
785                     if has_method(methods, ctx, &getter) {
786                         getter.push_str("_bindgen_bitfield");
787                     }
788                     getter
789                 };
790                 let setter = {
791                     let setter = format!("set_{}", bitfield_name);
792                     let mut setter = ctx.rust_mangle(&setter).to_string();
793                     if has_method(methods, ctx, &setter) {
794                         setter.push_str("_bindgen_bitfield");
795                     }
796                     setter
797                 };
798                 (bitfield_name, AccessorNamesPair { getter, setter })
799             })
800             .collect();
801 
802         let mut anon_field_counter = 0;
803         for field in fields.iter_mut() {
804             match *field {
805                 Field::DataMember(FieldData { ref mut name, .. }) => {
806                     if let Some(_) = *name {
807                         continue;
808                     }
809 
810                     anon_field_counter += 1;
811                     let generated_name =
812                         format!("__bindgen_anon_{}", anon_field_counter);
813                     *name = Some(generated_name);
814                 }
815                 Field::Bitfields(ref mut bu) => {
816                     for bitfield in &mut bu.bitfields {
817                         if bitfield.name().is_none() {
818                             continue;
819                         }
820 
821                         if let Some(AccessorNamesPair { getter, setter }) =
822                             accessor_names.remove(bitfield.name().unwrap())
823                         {
824                             bitfield.getter_name = Some(getter);
825                             bitfield.setter_name = Some(setter);
826                         }
827                     }
828                 }
829             }
830         }
831     }
832 }
833 
834 impl Trace for CompFields {
835     type Extra = ();
836 
trace<T>(&self, context: &BindgenContext, tracer: &mut T, _: &()) where T: Tracer,837     fn trace<T>(&self, context: &BindgenContext, tracer: &mut T, _: &())
838     where
839         T: Tracer,
840     {
841         match *self {
842             CompFields::ErrorComputingBitfieldUnits => {}
843             CompFields::BeforeComputingBitfieldUnits(ref fields) => {
844                 for f in fields {
845                     tracer.visit_kind(f.ty().into(), EdgeKind::Field);
846                 }
847             }
848             CompFields::AfterComputingBitfieldUnits(ref fields) => {
849                 for f in fields {
850                     f.trace(context, tracer, &());
851                 }
852             }
853         }
854     }
855 }
856 
857 /// Common data shared across different field types.
858 #[derive(Clone, Debug)]
859 pub struct FieldData {
860     /// The name of the field, empty if it's an unnamed bitfield width.
861     name: Option<String>,
862 
863     /// The inner type.
864     ty: TypeId,
865 
866     /// The doc comment on the field if any.
867     comment: Option<String>,
868 
869     /// Annotations for this field, or the default.
870     annotations: Annotations,
871 
872     /// If this field is a bitfield, and how many bits does it contain if it is.
873     bitfield_width: Option<u32>,
874 
875     /// If the C++ field is marked as `mutable`
876     mutable: bool,
877 
878     /// The offset of the field (in bits)
879     offset: Option<usize>,
880 }
881 
882 impl FieldMethods for FieldData {
name(&self) -> Option<&str>883     fn name(&self) -> Option<&str> {
884         self.name.as_ref().map(|n| &**n)
885     }
886 
ty(&self) -> TypeId887     fn ty(&self) -> TypeId {
888         self.ty
889     }
890 
comment(&self) -> Option<&str>891     fn comment(&self) -> Option<&str> {
892         self.comment.as_ref().map(|c| &**c)
893     }
894 
bitfield_width(&self) -> Option<u32>895     fn bitfield_width(&self) -> Option<u32> {
896         self.bitfield_width
897     }
898 
is_mutable(&self) -> bool899     fn is_mutable(&self) -> bool {
900         self.mutable
901     }
902 
annotations(&self) -> &Annotations903     fn annotations(&self) -> &Annotations {
904         &self.annotations
905     }
906 
offset(&self) -> Option<usize>907     fn offset(&self) -> Option<usize> {
908         self.offset
909     }
910 }
911 
912 /// The kind of inheritance a base class is using.
913 #[derive(Clone, Debug, PartialEq, Eq)]
914 pub enum BaseKind {
915     /// Normal inheritance, like:
916     ///
917     /// ```cpp
918     /// class A : public B {};
919     /// ```
920     Normal,
921     /// Virtual inheritance, like:
922     ///
923     /// ```cpp
924     /// class A: public virtual B {};
925     /// ```
926     Virtual,
927 }
928 
929 /// A base class.
930 #[derive(Clone, Debug)]
931 pub struct Base {
932     /// The type of this base class.
933     pub ty: TypeId,
934     /// The kind of inheritance we're doing.
935     pub kind: BaseKind,
936     /// Name of the field in which this base should be stored.
937     pub field_name: String,
938 }
939 
940 impl Base {
941     /// Whether this base class is inheriting virtually.
is_virtual(&self) -> bool942     pub fn is_virtual(&self) -> bool {
943         self.kind == BaseKind::Virtual
944     }
945 
946     /// Whether this base class should have it's own field for storage.
requires_storage(&self, ctx: &BindgenContext) -> bool947     pub fn requires_storage(&self, ctx: &BindgenContext) -> bool {
948         // Virtual bases are already taken into account by the vtable
949         // pointer.
950         //
951         // FIXME(emilio): Is this always right?
952         if self.is_virtual() {
953             return false;
954         }
955 
956         // NB: We won't include zero-sized types in our base chain because they
957         // would contribute to our size given the dummy field we insert for
958         // zero-sized types.
959         if self.ty.is_zero_sized(ctx) {
960             return false;
961         }
962 
963         true
964     }
965 }
966 
967 /// A compound type.
968 ///
969 /// Either a struct or union, a compound type is built up from the combination
970 /// of fields which also are associated with their own (potentially compound)
971 /// type.
972 #[derive(Debug)]
973 pub struct CompInfo {
974     /// Whether this is a struct or a union.
975     kind: CompKind,
976 
977     /// The members of this struct or union.
978     fields: CompFields,
979 
980     /// The abstract template parameters of this class. Note that these are NOT
981     /// concrete template arguments, and should always be a
982     /// `Type(TypeKind::TypeParam(name))`. For concrete template arguments, see
983     /// `TypeKind::TemplateInstantiation`.
984     template_params: Vec<TypeId>,
985 
986     /// The method declarations inside this class, if in C++ mode.
987     methods: Vec<Method>,
988 
989     /// The different constructors this struct or class contains.
990     constructors: Vec<FunctionId>,
991 
992     /// The destructor of this type. The bool represents whether this destructor
993     /// is virtual.
994     destructor: Option<(MethodKind, FunctionId)>,
995 
996     /// Vector of classes this one inherits from.
997     base_members: Vec<Base>,
998 
999     /// The inner types that were declared inside this class, in something like:
1000     ///
1001     /// class Foo {
1002     ///     typedef int FooTy;
1003     ///     struct Bar {
1004     ///         int baz;
1005     ///     };
1006     /// }
1007     ///
1008     /// static Foo::Bar const = {3};
1009     inner_types: Vec<TypeId>,
1010 
1011     /// Set of static constants declared inside this class.
1012     inner_vars: Vec<VarId>,
1013 
1014     /// Whether this type should generate an vtable (TODO: Should be able to
1015     /// look at the virtual methods and ditch this field).
1016     has_own_virtual_method: bool,
1017 
1018     /// Whether this type has destructor.
1019     has_destructor: bool,
1020 
1021     /// Whether this type has a base type with more than one member.
1022     ///
1023     /// TODO: We should be able to compute this.
1024     has_nonempty_base: bool,
1025 
1026     /// If this type has a template parameter which is not a type (e.g.: a
1027     /// size_t)
1028     has_non_type_template_params: bool,
1029 
1030     /// Whether we saw `__attribute__((packed))` on or within this type.
1031     packed_attr: bool,
1032 
1033     /// Used to know if we've found an opaque attribute that could cause us to
1034     /// generate a type with invalid layout. This is explicitly used to avoid us
1035     /// generating bad alignments when parsing types like max_align_t.
1036     ///
1037     /// It's not clear what the behavior should be here, if generating the item
1038     /// and pray, or behave as an opaque type.
1039     found_unknown_attr: bool,
1040 
1041     /// Used to indicate when a struct has been forward declared. Usually used
1042     /// in headers so that APIs can't modify them directly.
1043     is_forward_declaration: bool,
1044 }
1045 
1046 impl CompInfo {
1047     /// Construct a new compound type.
new(kind: CompKind) -> Self1048     pub fn new(kind: CompKind) -> Self {
1049         CompInfo {
1050             kind: kind,
1051             fields: CompFields::default(),
1052             template_params: vec![],
1053             methods: vec![],
1054             constructors: vec![],
1055             destructor: None,
1056             base_members: vec![],
1057             inner_types: vec![],
1058             inner_vars: vec![],
1059             has_own_virtual_method: false,
1060             has_destructor: false,
1061             has_nonempty_base: false,
1062             has_non_type_template_params: false,
1063             packed_attr: false,
1064             found_unknown_attr: false,
1065             is_forward_declaration: false,
1066         }
1067     }
1068 
1069     /// Compute the layout of this type.
1070     ///
1071     /// This is called as a fallback under some circumstances where LLVM doesn't
1072     /// give us the correct layout.
1073     ///
1074     /// If we're a union without known layout, we try to compute it from our
1075     /// members. This is not ideal, but clang fails to report the size for these
1076     /// kind of unions, see test/headers/template_union.hpp
layout(&self, ctx: &BindgenContext) -> Option<Layout>1077     pub fn layout(&self, ctx: &BindgenContext) -> Option<Layout> {
1078         // We can't do better than clang here, sorry.
1079         if self.kind == CompKind::Struct {
1080             return None;
1081         }
1082 
1083         // By definition, we don't have the right layout information here if
1084         // we're a forward declaration.
1085         if self.is_forward_declaration() {
1086             return None;
1087         }
1088 
1089         // empty union case
1090         if self.fields().is_empty() {
1091             return None;
1092         }
1093 
1094         let mut max_size = 0;
1095         // Don't allow align(0)
1096         let mut max_align = 1;
1097         for field in self.fields() {
1098             let field_layout = field.layout(ctx);
1099 
1100             if let Some(layout) = field_layout {
1101                 max_size = cmp::max(max_size, layout.size);
1102                 max_align = cmp::max(max_align, layout.align);
1103             }
1104         }
1105 
1106         Some(Layout::new(max_size, max_align))
1107     }
1108 
1109     /// Get this type's set of fields.
fields(&self) -> &[Field]1110     pub fn fields(&self) -> &[Field] {
1111         match self.fields {
1112             CompFields::ErrorComputingBitfieldUnits => &[],
1113             CompFields::AfterComputingBitfieldUnits(ref fields) => fields,
1114             CompFields::BeforeComputingBitfieldUnits(_) => {
1115                 panic!("Should always have computed bitfield units first");
1116             }
1117         }
1118     }
1119 
1120     /// Does this type have any template parameters that aren't types
1121     /// (e.g. int)?
has_non_type_template_params(&self) -> bool1122     pub fn has_non_type_template_params(&self) -> bool {
1123         self.has_non_type_template_params
1124     }
1125 
1126     /// Do we see a virtual function during parsing?
1127     /// Get the has_own_virtual_method boolean.
has_own_virtual_method(&self) -> bool1128     pub fn has_own_virtual_method(&self) -> bool {
1129         return self.has_own_virtual_method;
1130     }
1131 
1132     /// Did we see a destructor when parsing this type?
has_own_destructor(&self) -> bool1133     pub fn has_own_destructor(&self) -> bool {
1134         self.has_destructor
1135     }
1136 
1137     /// Get this type's set of methods.
methods(&self) -> &[Method]1138     pub fn methods(&self) -> &[Method] {
1139         &self.methods
1140     }
1141 
1142     /// Get this type's set of constructors.
constructors(&self) -> &[FunctionId]1143     pub fn constructors(&self) -> &[FunctionId] {
1144         &self.constructors
1145     }
1146 
1147     /// Get this type's destructor.
destructor(&self) -> Option<(MethodKind, FunctionId)>1148     pub fn destructor(&self) -> Option<(MethodKind, FunctionId)> {
1149         self.destructor
1150     }
1151 
1152     /// What kind of compound type is this?
kind(&self) -> CompKind1153     pub fn kind(&self) -> CompKind {
1154         self.kind
1155     }
1156 
1157     /// Is this a union?
is_union(&self) -> bool1158     pub fn is_union(&self) -> bool {
1159         self.kind() == CompKind::Union
1160     }
1161 
1162     /// The set of types that this one inherits from.
base_members(&self) -> &[Base]1163     pub fn base_members(&self) -> &[Base] {
1164         &self.base_members
1165     }
1166 
1167     /// 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>1168     pub fn from_ty(
1169         potential_id: ItemId,
1170         ty: &clang::Type,
1171         location: Option<clang::Cursor>,
1172         ctx: &mut BindgenContext,
1173     ) -> Result<Self, ParseError> {
1174         use clang_sys::*;
1175         assert!(
1176             ty.template_args().is_none(),
1177             "We handle template instantiations elsewhere"
1178         );
1179 
1180         let mut cursor = ty.declaration();
1181         let mut kind = Self::kind_from_cursor(&cursor);
1182         if kind.is_err() {
1183             if let Some(location) = location {
1184                 kind = Self::kind_from_cursor(&location);
1185                 cursor = location;
1186             }
1187         }
1188 
1189         let kind = kind?;
1190 
1191         debug!("CompInfo::from_ty({:?}, {:?})", kind, cursor);
1192 
1193         let mut ci = CompInfo::new(kind);
1194         ci.is_forward_declaration =
1195             location.map_or(true, |cur| match cur.kind() {
1196                 CXCursor_StructDecl | CXCursor_UnionDecl |
1197                 CXCursor_ClassDecl => !cur.is_definition(),
1198                 _ => false,
1199             });
1200 
1201         let mut maybe_anonymous_struct_field = None;
1202         cursor.visit(|cur| {
1203             if cur.kind() != CXCursor_FieldDecl {
1204                 if let Some((ty, clang_ty, offset)) =
1205                     maybe_anonymous_struct_field.take()
1206                 {
1207                     if cur.kind() == CXCursor_TypedefDecl &&
1208                         cur.typedef_type().unwrap().canonical_type() ==
1209                             clang_ty
1210                     {
1211                         // Typedefs of anonymous structs appear later in the ast
1212                         // than the struct itself, that would otherwise be an
1213                         // anonymous field. Detect that case here, and do
1214                         // nothing.
1215                     } else {
1216                         let field = RawField::new(
1217                             None, ty, None, None, None, false, offset,
1218                         );
1219                         ci.fields.append_raw_field(field);
1220                     }
1221                 }
1222             }
1223 
1224             match cur.kind() {
1225                 CXCursor_FieldDecl => {
1226                     if let Some((ty, clang_ty, offset)) =
1227                         maybe_anonymous_struct_field.take()
1228                     {
1229                         let mut used = false;
1230                         cur.visit(|child| {
1231                             if child.cur_type() == clang_ty {
1232                                 used = true;
1233                             }
1234                             CXChildVisit_Continue
1235                         });
1236                         if !used {
1237                             let field = RawField::new(
1238                                 None, ty, None, None, None, false, offset,
1239                             );
1240                             ci.fields.append_raw_field(field);
1241                         }
1242                     }
1243 
1244                     let bit_width = cur.bit_width();
1245                     let field_type = Item::from_ty_or_ref(
1246                         cur.cur_type(),
1247                         cur,
1248                         Some(potential_id),
1249                         ctx,
1250                     );
1251 
1252                     let comment = cur.raw_comment();
1253                     let annotations = Annotations::new(&cur);
1254                     let name = cur.spelling();
1255                     let is_mutable = cursor.is_mutable_field();
1256                     let offset = cur.offset_of_field().ok();
1257 
1258                     // Name can be empty if there are bitfields, for example,
1259                     // see tests/headers/struct_with_bitfields.h
1260                     assert!(
1261                         !name.is_empty() || bit_width.is_some(),
1262                         "Empty field name?"
1263                     );
1264 
1265                     let name = if name.is_empty() { None } else { Some(name) };
1266 
1267                     let field = RawField::new(
1268                         name,
1269                         field_type,
1270                         comment,
1271                         annotations,
1272                         bit_width,
1273                         is_mutable,
1274                         offset,
1275                     );
1276                     ci.fields.append_raw_field(field);
1277 
1278                     // No we look for things like attributes and stuff.
1279                     cur.visit(|cur| {
1280                         if cur.kind() == CXCursor_UnexposedAttr {
1281                             ci.found_unknown_attr = true;
1282                         }
1283                         CXChildVisit_Continue
1284                     });
1285                 }
1286                 CXCursor_UnexposedAttr => {
1287                     ci.found_unknown_attr = true;
1288                 }
1289                 CXCursor_EnumDecl |
1290                 CXCursor_TypeAliasDecl |
1291                 CXCursor_TypeAliasTemplateDecl |
1292                 CXCursor_TypedefDecl |
1293                 CXCursor_StructDecl |
1294                 CXCursor_UnionDecl |
1295                 CXCursor_ClassTemplate |
1296                 CXCursor_ClassDecl => {
1297                     // We can find non-semantic children here, clang uses a
1298                     // StructDecl to note incomplete structs that haven't been
1299                     // forward-declared before, see [1].
1300                     //
1301                     // Also, clang seems to scope struct definitions inside
1302                     // unions, and other named struct definitions inside other
1303                     // structs to the whole translation unit.
1304                     //
1305                     // Let's just assume that if the cursor we've found is a
1306                     // definition, it's a valid inner type.
1307                     //
1308                     // [1]: https://github.com/rust-lang/rust-bindgen/issues/482
1309                     let is_inner_struct =
1310                         cur.semantic_parent() == cursor || cur.is_definition();
1311                     if !is_inner_struct {
1312                         return CXChildVisit_Continue;
1313                     }
1314 
1315                     // Even if this is a definition, we may not be the semantic
1316                     // parent, see #1281.
1317                     let inner = Item::parse(cur, Some(potential_id), ctx)
1318                         .expect("Inner ClassDecl");
1319 
1320                     let inner = inner.expect_type_id(ctx);
1321 
1322                     ci.inner_types.push(inner);
1323 
1324                     // A declaration of an union or a struct without name could
1325                     // also be an unnamed field, unfortunately.
1326                     if cur.spelling().is_empty() &&
1327                         cur.kind() != CXCursor_EnumDecl
1328                     {
1329                         let ty = cur.cur_type();
1330                         let offset = cur.offset_of_field().ok();
1331                         maybe_anonymous_struct_field =
1332                             Some((inner, ty, offset));
1333                     }
1334                 }
1335                 CXCursor_PackedAttr => {
1336                     ci.packed_attr = true;
1337                 }
1338                 CXCursor_TemplateTypeParameter => {
1339                     let param = Item::type_param(None, cur, ctx).expect(
1340                         "Item::type_param should't fail when pointing \
1341                          at a TemplateTypeParameter",
1342                     );
1343                     ci.template_params.push(param);
1344                 }
1345                 CXCursor_CXXBaseSpecifier => {
1346                     let is_virtual_base = cur.is_virtual_base();
1347                     ci.has_own_virtual_method |= is_virtual_base;
1348 
1349                     let kind = if is_virtual_base {
1350                         BaseKind::Virtual
1351                     } else {
1352                         BaseKind::Normal
1353                     };
1354 
1355                     let field_name = match ci.base_members.len() {
1356                         0 => "_base".into(),
1357                         n => format!("_base_{}", n),
1358                     };
1359                     let type_id =
1360                         Item::from_ty_or_ref(cur.cur_type(), cur, None, ctx);
1361                     ci.base_members.push(Base {
1362                         ty: type_id,
1363                         kind: kind,
1364                         field_name: field_name,
1365                     });
1366                 }
1367                 CXCursor_Constructor | CXCursor_Destructor |
1368                 CXCursor_CXXMethod => {
1369                     let is_virtual = cur.method_is_virtual();
1370                     let is_static = cur.method_is_static();
1371                     debug_assert!(!(is_static && is_virtual), "How?");
1372 
1373                     ci.has_destructor |= cur.kind() == CXCursor_Destructor;
1374                     ci.has_own_virtual_method |= is_virtual;
1375 
1376                     // This used to not be here, but then I tried generating
1377                     // stylo bindings with this (without path filters), and
1378                     // cried a lot with a method in gfx/Point.h
1379                     // (ToUnknownPoint), that somehow was causing the same type
1380                     // to be inserted in the map two times.
1381                     //
1382                     // I couldn't make a reduced test case, but anyway...
1383                     // Methods of template functions not only used to be inlined,
1384                     // but also instantiated, and we wouldn't be able to call
1385                     // them, so just bail out.
1386                     if !ci.template_params.is_empty() {
1387                         return CXChildVisit_Continue;
1388                     }
1389 
1390                     // NB: This gets us an owned `Function`, not a
1391                     // `FunctionSig`.
1392                     let signature =
1393                         match Item::parse(cur, Some(potential_id), ctx) {
1394                             Ok(item)
1395                                 if ctx
1396                                     .resolve_item(item)
1397                                     .kind()
1398                                     .is_function() =>
1399                             {
1400                                 item
1401                             }
1402                             _ => return CXChildVisit_Continue,
1403                         };
1404 
1405                     let signature = signature.expect_function_id(ctx);
1406 
1407                     match cur.kind() {
1408                         CXCursor_Constructor => {
1409                             ci.constructors.push(signature);
1410                         }
1411                         CXCursor_Destructor => {
1412                             let kind = if is_virtual {
1413                                 MethodKind::VirtualDestructor {
1414                                     pure_virtual: cur.method_is_pure_virtual(),
1415                                 }
1416                             } else {
1417                                 MethodKind::Destructor
1418                             };
1419                             ci.destructor = Some((kind, signature));
1420                         }
1421                         CXCursor_CXXMethod => {
1422                             let is_const = cur.method_is_const();
1423                             let method_kind = if is_static {
1424                                 MethodKind::Static
1425                             } else if is_virtual {
1426                                 MethodKind::Virtual {
1427                                     pure_virtual: cur.method_is_pure_virtual(),
1428                                 }
1429                             } else {
1430                                 MethodKind::Normal
1431                             };
1432 
1433                             let method =
1434                                 Method::new(method_kind, signature, is_const);
1435 
1436                             ci.methods.push(method);
1437                         }
1438                         _ => unreachable!("How can we see this here?"),
1439                     }
1440                 }
1441                 CXCursor_NonTypeTemplateParameter => {
1442                     ci.has_non_type_template_params = true;
1443                 }
1444                 CXCursor_VarDecl => {
1445                     let linkage = cur.linkage();
1446                     if linkage != CXLinkage_External &&
1447                         linkage != CXLinkage_UniqueExternal
1448                     {
1449                         return CXChildVisit_Continue;
1450                     }
1451 
1452                     let visibility = cur.visibility();
1453                     if visibility != CXVisibility_Default {
1454                         return CXChildVisit_Continue;
1455                     }
1456 
1457                     if let Ok(item) = Item::parse(cur, Some(potential_id), ctx)
1458                     {
1459                         ci.inner_vars.push(item.as_var_id_unchecked());
1460                     }
1461                 }
1462                 // Intentionally not handled
1463                 CXCursor_CXXAccessSpecifier |
1464                 CXCursor_CXXFinalAttr |
1465                 CXCursor_FunctionTemplate |
1466                 CXCursor_ConversionFunction => {}
1467                 _ => {
1468                     warn!(
1469                         "unhandled comp member `{}` (kind {:?}) in `{}` ({})",
1470                         cur.spelling(),
1471                         clang::kind_to_str(cur.kind()),
1472                         cursor.spelling(),
1473                         cur.location()
1474                     );
1475                 }
1476             }
1477             CXChildVisit_Continue
1478         });
1479 
1480         if let Some((ty, _, offset)) = maybe_anonymous_struct_field {
1481             let field =
1482                 RawField::new(None, ty, None, None, None, false, offset);
1483             ci.fields.append_raw_field(field);
1484         }
1485 
1486         Ok(ci)
1487     }
1488 
kind_from_cursor( cursor: &clang::Cursor, ) -> Result<CompKind, ParseError>1489     fn kind_from_cursor(
1490         cursor: &clang::Cursor,
1491     ) -> Result<CompKind, ParseError> {
1492         use clang_sys::*;
1493         Ok(match cursor.kind() {
1494             CXCursor_UnionDecl => CompKind::Union,
1495             CXCursor_ClassDecl | CXCursor_StructDecl => CompKind::Struct,
1496             CXCursor_CXXBaseSpecifier |
1497             CXCursor_ClassTemplatePartialSpecialization |
1498             CXCursor_ClassTemplate => match cursor.template_kind() {
1499                 CXCursor_UnionDecl => CompKind::Union,
1500                 _ => CompKind::Struct,
1501             },
1502             _ => {
1503                 warn!("Unknown kind for comp type: {:?}", cursor);
1504                 return Err(ParseError::Continue);
1505             }
1506         })
1507     }
1508 
1509     /// Get the set of types that were declared within this compound type
1510     /// (e.g. nested class definitions).
inner_types(&self) -> &[TypeId]1511     pub fn inner_types(&self) -> &[TypeId] {
1512         &self.inner_types
1513     }
1514 
1515     /// Get the set of static variables declared within this compound type.
inner_vars(&self) -> &[VarId]1516     pub fn inner_vars(&self) -> &[VarId] {
1517         &self.inner_vars
1518     }
1519 
1520     /// Have we found a field with an opaque type that could potentially mess up
1521     /// the layout of this compound type?
found_unknown_attr(&self) -> bool1522     pub fn found_unknown_attr(&self) -> bool {
1523         self.found_unknown_attr
1524     }
1525 
1526     /// Is this compound type packed?
is_packed( &self, ctx: &BindgenContext, layout: &Option<Layout>, ) -> bool1527     pub fn is_packed(
1528         &self,
1529         ctx: &BindgenContext,
1530         layout: &Option<Layout>,
1531     ) -> bool {
1532         if self.packed_attr {
1533             return true;
1534         }
1535 
1536         // Even though `libclang` doesn't expose `#pragma packed(...)`, we can
1537         // detect it through its effects.
1538         if let Some(ref parent_layout) = *layout {
1539             if self.fields().iter().any(|f| match *f {
1540                 Field::Bitfields(ref unit) => {
1541                     unit.layout().align > parent_layout.align
1542                 }
1543                 Field::DataMember(ref data) => {
1544                     let field_ty = ctx.resolve_type(data.ty());
1545                     field_ty.layout(ctx).map_or(false, |field_ty_layout| {
1546                         field_ty_layout.align > parent_layout.align
1547                     })
1548                 }
1549             }) {
1550                 info!("Found a struct that was defined within `#pragma packed(...)`");
1551                 return true;
1552             } else if self.has_own_virtual_method {
1553                 if parent_layout.align == 1 {
1554                     return true;
1555                 }
1556             }
1557         }
1558 
1559         false
1560     }
1561 
1562     /// Returns true if compound type has been forward declared
is_forward_declaration(&self) -> bool1563     pub fn is_forward_declaration(&self) -> bool {
1564         self.is_forward_declaration
1565     }
1566 
1567     /// Compute this compound structure's bitfield allocation units.
compute_bitfield_units(&mut self, ctx: &BindgenContext)1568     pub fn compute_bitfield_units(&mut self, ctx: &BindgenContext) {
1569         self.fields.compute_bitfield_units(ctx);
1570     }
1571 
1572     /// Assign for each anonymous field a generated name.
deanonymize_fields(&mut self, ctx: &BindgenContext)1573     pub fn deanonymize_fields(&mut self, ctx: &BindgenContext) {
1574         self.fields.deanonymize_fields(ctx, &self.methods);
1575     }
1576 
1577     /// Returns whether the current union can be represented as a Rust `union`
1578     ///
1579     /// Requirements:
1580     ///     1. Current RustTarget allows for `untagged_union`
1581     ///     2. Each field can derive `Copy`
can_be_rust_union(&self, ctx: &BindgenContext) -> bool1582     pub fn can_be_rust_union(&self, ctx: &BindgenContext) -> bool {
1583         if !ctx.options().rust_features().untagged_union {
1584             return false;
1585         }
1586 
1587         if self.is_forward_declaration() {
1588             return false;
1589         }
1590 
1591         self.fields().iter().all(|f| match *f {
1592             Field::DataMember(ref field_data) => {
1593                 field_data.ty().can_derive_copy(ctx)
1594             }
1595             Field::Bitfields(_) => true,
1596         })
1597     }
1598 }
1599 
1600 impl DotAttributes for CompInfo {
dot_attributes<W>( &self, ctx: &BindgenContext, out: &mut W, ) -> io::Result<()> where W: io::Write,1601     fn dot_attributes<W>(
1602         &self,
1603         ctx: &BindgenContext,
1604         out: &mut W,
1605     ) -> io::Result<()>
1606     where
1607         W: io::Write,
1608     {
1609         writeln!(out, "<tr><td>CompKind</td><td>{:?}</td></tr>", self.kind)?;
1610 
1611         if self.has_own_virtual_method {
1612             writeln!(out, "<tr><td>has_vtable</td><td>true</td></tr>")?;
1613         }
1614 
1615         if self.has_destructor {
1616             writeln!(out, "<tr><td>has_destructor</td><td>true</td></tr>")?;
1617         }
1618 
1619         if self.has_nonempty_base {
1620             writeln!(out, "<tr><td>has_nonempty_base</td><td>true</td></tr>")?;
1621         }
1622 
1623         if self.has_non_type_template_params {
1624             writeln!(
1625                 out,
1626                 "<tr><td>has_non_type_template_params</td><td>true</td></tr>"
1627             )?;
1628         }
1629 
1630         if self.packed_attr {
1631             writeln!(out, "<tr><td>packed_attr</td><td>true</td></tr>")?;
1632         }
1633 
1634         if self.is_forward_declaration {
1635             writeln!(
1636                 out,
1637                 "<tr><td>is_forward_declaration</td><td>true</td></tr>"
1638             )?;
1639         }
1640 
1641         if !self.fields().is_empty() {
1642             writeln!(out, r#"<tr><td>fields</td><td><table border="0">"#)?;
1643             for field in self.fields() {
1644                 field.dot_attributes(ctx, out)?;
1645             }
1646             writeln!(out, "</table></td></tr>")?;
1647         }
1648 
1649         Ok(())
1650     }
1651 }
1652 
1653 impl IsOpaque for CompInfo {
1654     type Extra = Option<Layout>;
1655 
is_opaque(&self, ctx: &BindgenContext, layout: &Option<Layout>) -> bool1656     fn is_opaque(&self, ctx: &BindgenContext, layout: &Option<Layout>) -> bool {
1657         if self.has_non_type_template_params {
1658             return true;
1659         }
1660 
1661         // When we do not have the layout for a bitfield's type (for example, it
1662         // is a type parameter), then we can't compute bitfield units. We are
1663         // left with no choice but to make the whole struct opaque, or else we
1664         // might generate structs with incorrect sizes and alignments.
1665         if let CompFields::ErrorComputingBitfieldUnits = self.fields {
1666             return true;
1667         }
1668 
1669         // Bitfields with a width that is larger than their unit's width have
1670         // some strange things going on, and the best we can do is make the
1671         // whole struct opaque.
1672         if self.fields().iter().any(|f| match *f {
1673             Field::DataMember(_) => false,
1674             Field::Bitfields(ref unit) => unit.bitfields().iter().any(|bf| {
1675                 let bitfield_layout = ctx
1676                     .resolve_type(bf.ty())
1677                     .layout(ctx)
1678                     .expect("Bitfield without layout? Gah!");
1679                 bf.width() / 8 > bitfield_layout.size as u32
1680             }),
1681         }) {
1682             return true;
1683         }
1684 
1685         if !ctx.options().rust_features().repr_packed_n {
1686             // If we don't have `#[repr(packed(N)]`, the best we can
1687             // do is make this struct opaque.
1688             //
1689             // See https://github.com/rust-lang/rust-bindgen/issues/537 and
1690             // https://github.com/rust-lang/rust/issues/33158
1691             if self.is_packed(ctx, layout) &&
1692                 layout.map_or(false, |l| l.align > 1)
1693             {
1694                 warn!("Found a type that is both packed and aligned to greater than \
1695                        1; Rust before version 1.33 doesn't have `#[repr(packed(N))]`, so we \
1696                        are treating it as opaque. You may wish to set bindgen's rust target \
1697                        version to 1.33 or later to enable `#[repr(packed(N))]` support.");
1698                 return true;
1699             }
1700         }
1701 
1702         false
1703     }
1704 }
1705 
1706 impl TemplateParameters for CompInfo {
self_template_params(&self, _ctx: &BindgenContext) -> Vec<TypeId>1707     fn self_template_params(&self, _ctx: &BindgenContext) -> Vec<TypeId> {
1708         self.template_params.clone()
1709     }
1710 }
1711 
1712 impl Trace for CompInfo {
1713     type Extra = Item;
1714 
trace<T>(&self, context: &BindgenContext, tracer: &mut T, item: &Item) where T: Tracer,1715     fn trace<T>(&self, context: &BindgenContext, tracer: &mut T, item: &Item)
1716     where
1717         T: Tracer,
1718     {
1719         for p in item.all_template_params(context) {
1720             tracer.visit_kind(p.into(), EdgeKind::TemplateParameterDefinition);
1721         }
1722 
1723         for ty in self.inner_types() {
1724             tracer.visit_kind(ty.into(), EdgeKind::InnerType);
1725         }
1726 
1727         for &var in self.inner_vars() {
1728             tracer.visit_kind(var.into(), EdgeKind::InnerVar);
1729         }
1730 
1731         for method in self.methods() {
1732             tracer.visit_kind(method.signature.into(), EdgeKind::Method);
1733         }
1734 
1735         if let Some((_kind, signature)) = self.destructor() {
1736             tracer.visit_kind(signature.into(), EdgeKind::Destructor);
1737         }
1738 
1739         for ctor in self.constructors() {
1740             tracer.visit_kind(ctor.into(), EdgeKind::Constructor);
1741         }
1742 
1743         // Base members and fields are not generated for opaque types (but all
1744         // of the above things are) so stop here.
1745         if item.is_opaque(context, &()) {
1746             return;
1747         }
1748 
1749         for base in self.base_members() {
1750             tracer.visit_kind(base.ty.into(), EdgeKind::BaseMember);
1751         }
1752 
1753         self.fields.trace(context, tracer, &());
1754     }
1755 }
1756