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