1 //! Common context that is passed around during parsing and codegen.
2 
3 use super::super::time::Timer;
4 use super::analysis::{
5     analyze, as_cannot_derive_set, CannotDerive, DeriveTrait,
6     HasDestructorAnalysis, HasFloat, HasTypeParameterInArray,
7     HasVtableAnalysis, HasVtableResult, SizednessAnalysis, SizednessResult,
8     UsedTemplateParameters,
9 };
10 use super::derive::{
11     CanDerive, CanDeriveCopy, CanDeriveDebug, CanDeriveDefault, CanDeriveEq,
12     CanDeriveHash, CanDeriveOrd, CanDerivePartialEq, CanDerivePartialOrd,
13 };
14 use super::function::Function;
15 use super::int::IntKind;
16 use super::item::{IsOpaque, Item, ItemAncestors, ItemSet};
17 use super::item_kind::ItemKind;
18 use super::module::{Module, ModuleKind};
19 use super::template::{TemplateInstantiation, TemplateParameters};
20 use super::traversal::{self, Edge, ItemTraversal};
21 use super::ty::{FloatKind, Type, TypeKind};
22 use callbacks::ParseCallbacks;
23 use cexpr;
24 use clang::{self, Cursor};
25 use clang_sys;
26 use parse::ClangItemParser;
27 use proc_macro2::{Ident, Span};
28 use std::borrow::Cow;
29 use std::cell::Cell;
30 use std::collections::HashMap as StdHashMap;
31 use std::iter::IntoIterator;
32 use std::mem;
33 use BindgenOptions;
34 use {Entry, HashMap, HashSet};
35 
36 /// An identifier for some kind of IR item.
37 #[derive(Debug, Copy, Clone, Eq, PartialOrd, Ord, Hash)]
38 pub struct ItemId(usize);
39 
40 macro_rules! item_id_newtype {
41     (
42         $( #[$attr:meta] )*
43         pub struct $name:ident(ItemId)
44         where
45             $( #[$checked_attr:meta] )*
46             checked = $checked:ident with $check_method:ident,
47             $( #[$expected_attr:meta] )*
48             expected = $expected:ident,
49             $( #[$unchecked_attr:meta] )*
50             unchecked = $unchecked:ident;
51     ) => {
52         $( #[$attr] )*
53         #[derive(Debug, Copy, Clone, Eq, PartialOrd, Ord, Hash)]
54         pub struct $name(ItemId);
55 
56         impl $name {
57             /// Create an `ItemResolver` from this id.
58             pub fn into_resolver(self) -> ItemResolver {
59                 let id: ItemId = self.into();
60                 id.into()
61             }
62         }
63 
64         impl<T> ::std::cmp::PartialEq<T> for $name
65         where
66             T: Copy + Into<ItemId>
67         {
68             fn eq(&self, rhs: &T) -> bool {
69                 let rhs: ItemId = (*rhs).into();
70                 self.0 == rhs
71             }
72         }
73 
74         impl From<$name> for ItemId {
75             fn from(id: $name) -> ItemId {
76                 id.0
77             }
78         }
79 
80         impl<'a> From<&'a $name> for ItemId {
81             fn from(id: &'a $name) -> ItemId {
82                 id.0
83             }
84         }
85 
86         impl ItemId {
87             $( #[$checked_attr] )*
88             pub fn $checked(&self, ctx: &BindgenContext) -> Option<$name> {
89                 if ctx.resolve_item(*self).kind().$check_method() {
90                     Some($name(*self))
91                 } else {
92                     None
93                 }
94             }
95 
96             $( #[$expected_attr] )*
97             pub fn $expected(&self, ctx: &BindgenContext) -> $name {
98                 self.$checked(ctx)
99                     .expect(concat!(
100                         stringify!($expected),
101                         " called with ItemId that points to the wrong ItemKind"
102                     ))
103             }
104 
105             $( #[$unchecked_attr] )*
106             pub fn $unchecked(&self) -> $name {
107                 $name(*self)
108             }
109         }
110     }
111 }
112 
113 item_id_newtype! {
114     /// An identifier for an `Item` whose `ItemKind` is known to be
115     /// `ItemKind::Type`.
116     pub struct TypeId(ItemId)
117     where
118         /// Convert this `ItemId` into a `TypeId` if its associated item is a type,
119         /// otherwise return `None`.
120         checked = as_type_id with is_type,
121 
122         /// Convert this `ItemId` into a `TypeId`.
123         ///
124         /// If this `ItemId` does not point to a type, then panic.
125         expected = expect_type_id,
126 
127         /// Convert this `ItemId` into a `TypeId` without actually checking whether
128         /// this id actually points to a `Type`.
129         unchecked = as_type_id_unchecked;
130 }
131 
132 item_id_newtype! {
133     /// An identifier for an `Item` whose `ItemKind` is known to be
134     /// `ItemKind::Module`.
135     pub struct ModuleId(ItemId)
136     where
137         /// Convert this `ItemId` into a `ModuleId` if its associated item is a
138         /// module, otherwise return `None`.
139         checked = as_module_id with is_module,
140 
141         /// Convert this `ItemId` into a `ModuleId`.
142         ///
143         /// If this `ItemId` does not point to a module, then panic.
144         expected = expect_module_id,
145 
146         /// Convert this `ItemId` into a `ModuleId` without actually checking
147         /// whether this id actually points to a `Module`.
148         unchecked = as_module_id_unchecked;
149 }
150 
151 item_id_newtype! {
152     /// An identifier for an `Item` whose `ItemKind` is known to be
153     /// `ItemKind::Var`.
154     pub struct VarId(ItemId)
155     where
156         /// Convert this `ItemId` into a `VarId` if its associated item is a var,
157         /// otherwise return `None`.
158         checked = as_var_id with is_var,
159 
160         /// Convert this `ItemId` into a `VarId`.
161         ///
162         /// If this `ItemId` does not point to a var, then panic.
163         expected = expect_var_id,
164 
165         /// Convert this `ItemId` into a `VarId` without actually checking whether
166         /// this id actually points to a `Var`.
167         unchecked = as_var_id_unchecked;
168 }
169 
170 item_id_newtype! {
171     /// An identifier for an `Item` whose `ItemKind` is known to be
172     /// `ItemKind::Function`.
173     pub struct FunctionId(ItemId)
174     where
175         /// Convert this `ItemId` into a `FunctionId` if its associated item is a function,
176         /// otherwise return `None`.
177         checked = as_function_id with is_function,
178 
179         /// Convert this `ItemId` into a `FunctionId`.
180         ///
181         /// If this `ItemId` does not point to a function, then panic.
182         expected = expect_function_id,
183 
184         /// Convert this `ItemId` into a `FunctionId` without actually checking whether
185         /// this id actually points to a `Function`.
186         unchecked = as_function_id_unchecked;
187 }
188 
189 impl From<ItemId> for usize {
from(id: ItemId) -> usize190     fn from(id: ItemId) -> usize {
191         id.0
192     }
193 }
194 
195 impl ItemId {
196     /// Get a numeric representation of this id.
as_usize(&self) -> usize197     pub fn as_usize(&self) -> usize {
198         (*self).into()
199     }
200 }
201 
202 impl<T> ::std::cmp::PartialEq<T> for ItemId
203 where
204     T: Copy + Into<ItemId>,
205 {
eq(&self, rhs: &T) -> bool206     fn eq(&self, rhs: &T) -> bool {
207         let rhs: ItemId = (*rhs).into();
208         self.0 == rhs.0
209     }
210 }
211 
212 impl<T> CanDeriveDebug for T
213 where
214     T: Copy + Into<ItemId>,
215 {
can_derive_debug(&self, ctx: &BindgenContext) -> bool216     fn can_derive_debug(&self, ctx: &BindgenContext) -> bool {
217         ctx.options().derive_debug && ctx.lookup_can_derive_debug(*self)
218     }
219 }
220 
221 impl<T> CanDeriveDefault for T
222 where
223     T: Copy + Into<ItemId>,
224 {
can_derive_default(&self, ctx: &BindgenContext) -> bool225     fn can_derive_default(&self, ctx: &BindgenContext) -> bool {
226         ctx.options().derive_default && ctx.lookup_can_derive_default(*self)
227     }
228 }
229 
230 impl<T> CanDeriveCopy for T
231 where
232     T: Copy + Into<ItemId>,
233 {
can_derive_copy(&self, ctx: &BindgenContext) -> bool234     fn can_derive_copy(&self, ctx: &BindgenContext) -> bool {
235         ctx.options().derive_copy && ctx.lookup_can_derive_copy(*self)
236     }
237 }
238 
239 impl<T> CanDeriveHash for T
240 where
241     T: Copy + Into<ItemId>,
242 {
can_derive_hash(&self, ctx: &BindgenContext) -> bool243     fn can_derive_hash(&self, ctx: &BindgenContext) -> bool {
244         ctx.options().derive_hash && ctx.lookup_can_derive_hash(*self)
245     }
246 }
247 
248 impl<T> CanDerivePartialOrd for T
249 where
250     T: Copy + Into<ItemId>,
251 {
can_derive_partialord(&self, ctx: &BindgenContext) -> bool252     fn can_derive_partialord(&self, ctx: &BindgenContext) -> bool {
253         ctx.options().derive_partialord &&
254             ctx.lookup_can_derive_partialeq_or_partialord(*self) ==
255                 CanDerive::Yes
256     }
257 }
258 
259 impl<T> CanDerivePartialEq for T
260 where
261     T: Copy + Into<ItemId>,
262 {
can_derive_partialeq(&self, ctx: &BindgenContext) -> bool263     fn can_derive_partialeq(&self, ctx: &BindgenContext) -> bool {
264         ctx.options().derive_partialeq &&
265             ctx.lookup_can_derive_partialeq_or_partialord(*self) ==
266                 CanDerive::Yes
267     }
268 }
269 
270 impl<T> CanDeriveEq for T
271 where
272     T: Copy + Into<ItemId>,
273 {
can_derive_eq(&self, ctx: &BindgenContext) -> bool274     fn can_derive_eq(&self, ctx: &BindgenContext) -> bool {
275         ctx.options().derive_eq &&
276             ctx.lookup_can_derive_partialeq_or_partialord(*self) ==
277                 CanDerive::Yes &&
278             !ctx.lookup_has_float(*self)
279     }
280 }
281 
282 impl<T> CanDeriveOrd for T
283 where
284     T: Copy + Into<ItemId>,
285 {
can_derive_ord(&self, ctx: &BindgenContext) -> bool286     fn can_derive_ord(&self, ctx: &BindgenContext) -> bool {
287         ctx.options().derive_ord &&
288             ctx.lookup_can_derive_partialeq_or_partialord(*self) ==
289                 CanDerive::Yes &&
290             !ctx.lookup_has_float(*self)
291     }
292 }
293 
294 /// A key used to index a resolved type, so we only process it once.
295 ///
296 /// This is almost always a USR string (an unique identifier generated by
297 /// clang), but it can also be the canonical declaration if the type is unnamed,
298 /// in which case clang may generate the same USR for multiple nested unnamed
299 /// types.
300 #[derive(Eq, PartialEq, Hash, Debug)]
301 enum TypeKey {
302     USR(String),
303     Declaration(Cursor),
304 }
305 
306 /// A context used during parsing and generation of structs.
307 #[derive(Debug)]
308 pub struct BindgenContext {
309     /// The map of all the items parsed so far, keyed off ItemId.
310     items: Vec<Option<Item>>,
311 
312     /// Clang USR to type map. This is needed to be able to associate types with
313     /// item ids during parsing.
314     types: HashMap<TypeKey, TypeId>,
315 
316     /// Maps from a cursor to the item id of the named template type parameter
317     /// for that cursor.
318     type_params: HashMap<clang::Cursor, TypeId>,
319 
320     /// A cursor to module map. Similar reason than above.
321     modules: HashMap<Cursor, ModuleId>,
322 
323     /// The root module, this is guaranteed to be an item of kind Module.
324     root_module: ModuleId,
325 
326     /// Current module being traversed.
327     current_module: ModuleId,
328 
329     /// A HashMap keyed on a type definition, and whose value is the parent id
330     /// of the declaration.
331     ///
332     /// This is used to handle the cases where the semantic and the lexical
333     /// parents of the cursor differ, like when a nested class is defined
334     /// outside of the parent class.
335     semantic_parents: HashMap<clang::Cursor, ItemId>,
336 
337     /// A stack with the current type declarations and types we're parsing. This
338     /// is needed to avoid infinite recursion when parsing a type like:
339     ///
340     /// struct c { struct c* next; };
341     ///
342     /// This means effectively, that a type has a potential ID before knowing if
343     /// it's a correct type. But that's not important in practice.
344     ///
345     /// We could also use the `types` HashMap, but my intention with it is that
346     /// only valid types and declarations end up there, and this could
347     /// potentially break that assumption.
348     currently_parsed_types: Vec<PartialType>,
349 
350     /// A map with all the already parsed macro names. This is done to avoid
351     /// hard errors while parsing duplicated macros, as well to allow macro
352     /// expression parsing.
353     ///
354     /// This needs to be an std::HashMap because the cexpr API requires it.
355     parsed_macros: StdHashMap<Vec<u8>, cexpr::expr::EvalResult>,
356 
357     /// The active replacements collected from replaces="xxx" annotations.
358     replacements: HashMap<Vec<String>, ItemId>,
359 
360     collected_typerefs: bool,
361 
362     in_codegen: bool,
363 
364     /// The clang index for parsing.
365     index: clang::Index,
366 
367     /// The translation unit for parsing.
368     translation_unit: clang::TranslationUnit,
369 
370     /// Target information that can be useful for some stuff.
371     target_info: Option<clang::TargetInfo>,
372 
373     /// The options given by the user via cli or other medium.
374     options: BindgenOptions,
375 
376     /// Whether a bindgen complex was generated
377     generated_bindgen_complex: Cell<bool>,
378 
379     /// The set of `ItemId`s that are whitelisted. This the very first thing
380     /// computed after parsing our IR, and before running any of our analyses.
381     whitelisted: Option<ItemSet>,
382 
383     /// The set of `ItemId`s that are whitelisted for code generation _and_ that
384     /// we should generate accounting for the codegen options.
385     ///
386     /// It's computed right after computing the whitelisted items.
387     codegen_items: Option<ItemSet>,
388 
389     /// Map from an item's id to the set of template parameter items that it
390     /// uses. See `ir::named` for more details. Always `Some` during the codegen
391     /// phase.
392     used_template_parameters: Option<HashMap<ItemId, ItemSet>>,
393 
394     /// The set of `TypeKind::Comp` items found during parsing that need their
395     /// bitfield allocation units computed. Drained in `compute_bitfield_units`.
396     need_bitfield_allocation: Vec<ItemId>,
397 
398     /// The set of (`ItemId`s of) types that can't derive debug.
399     ///
400     /// This is populated when we enter codegen by `compute_cannot_derive_debug`
401     /// and is always `None` before that and `Some` after.
402     cannot_derive_debug: Option<HashSet<ItemId>>,
403 
404     /// The set of (`ItemId`s of) types that can't derive default.
405     ///
406     /// This is populated when we enter codegen by `compute_cannot_derive_default`
407     /// and is always `None` before that and `Some` after.
408     cannot_derive_default: Option<HashSet<ItemId>>,
409 
410     /// The set of (`ItemId`s of) types that can't derive copy.
411     ///
412     /// This is populated when we enter codegen by `compute_cannot_derive_copy`
413     /// and is always `None` before that and `Some` after.
414     cannot_derive_copy: Option<HashSet<ItemId>>,
415 
416     /// The set of (`ItemId`s of) types that can't derive copy in array.
417     ///
418     /// This is populated when we enter codegen by `compute_cannot_derive_copy`
419     /// and is always `None` before that and `Some` after.
420     cannot_derive_copy_in_array: Option<HashSet<ItemId>>,
421 
422     /// The set of (`ItemId`s of) types that can't derive hash.
423     ///
424     /// This is populated when we enter codegen by `compute_can_derive_hash`
425     /// and is always `None` before that and `Some` after.
426     cannot_derive_hash: Option<HashSet<ItemId>>,
427 
428     /// The map why specified `ItemId`s of) types that can't derive hash.
429     ///
430     /// This is populated when we enter codegen by
431     /// `compute_cannot_derive_partialord_partialeq_or_eq` and is always `None`
432     /// before that and `Some` after.
433     cannot_derive_partialeq_or_partialord: Option<HashMap<ItemId, CanDerive>>,
434 
435     /// The sizedness of types.
436     ///
437     /// This is populated by `compute_sizedness` and is always `None` before
438     /// that function is invoked and `Some` afterwards.
439     sizedness: Option<HashMap<TypeId, SizednessResult>>,
440 
441     /// The set of (`ItemId's of`) types that has vtable.
442     ///
443     /// Populated when we enter codegen by `compute_has_vtable`; always `None`
444     /// before that and `Some` after.
445     have_vtable: Option<HashMap<ItemId, HasVtableResult>>,
446 
447     /// The set of (`ItemId's of`) types that has destructor.
448     ///
449     /// Populated when we enter codegen by `compute_has_destructor`; always `None`
450     /// before that and `Some` after.
451     have_destructor: Option<HashSet<ItemId>>,
452 
453     /// The set of (`ItemId's of`) types that has array.
454     ///
455     /// Populated when we enter codegen by `compute_has_type_param_in_array`; always `None`
456     /// before that and `Some` after.
457     has_type_param_in_array: Option<HashSet<ItemId>>,
458 
459     /// The set of (`ItemId's of`) types that has float.
460     ///
461     /// Populated when we enter codegen by `compute_has_float`; always `None`
462     /// before that and `Some` after.
463     has_float: Option<HashSet<ItemId>>,
464 }
465 
466 /// A traversal of whitelisted items.
467 struct WhitelistedItemsTraversal<'ctx> {
468     ctx: &'ctx BindgenContext,
469     traversal: ItemTraversal<
470         'ctx,
471         ItemSet,
472         Vec<ItemId>,
473         for<'a> fn(&'a BindgenContext, Edge) -> bool,
474     >,
475 }
476 
477 impl<'ctx> Iterator for WhitelistedItemsTraversal<'ctx> {
478     type Item = ItemId;
479 
next(&mut self) -> Option<ItemId>480     fn next(&mut self) -> Option<ItemId> {
481         loop {
482             let id = self.traversal.next()?;
483 
484             if self.ctx.resolve_item(id).is_blacklisted(self.ctx) {
485                 continue;
486             }
487 
488             return Some(id);
489         }
490     }
491 }
492 
493 impl<'ctx> WhitelistedItemsTraversal<'ctx> {
494     /// Construct a new whitelisted items traversal.
new<R>( ctx: &'ctx BindgenContext, roots: R, predicate: for<'a> fn(&'a BindgenContext, Edge) -> bool, ) -> Self where R: IntoIterator<Item = ItemId>,495     pub fn new<R>(
496         ctx: &'ctx BindgenContext,
497         roots: R,
498         predicate: for<'a> fn(&'a BindgenContext, Edge) -> bool,
499     ) -> Self
500     where
501         R: IntoIterator<Item = ItemId>,
502     {
503         WhitelistedItemsTraversal {
504             ctx,
505             traversal: ItemTraversal::new(ctx, roots, predicate),
506         }
507     }
508 }
509 
510 const HOST_TARGET: &'static str =
511     include_str!(concat!(env!("OUT_DIR"), "/host-target.txt"));
512 
513 /// Returns the effective target, and whether it was explicitly specified on the
514 /// clang flags.
find_effective_target(clang_args: &[String]) -> (String, bool)515 fn find_effective_target(clang_args: &[String]) -> (String, bool) {
516     use std::env;
517 
518     let mut args = clang_args.iter();
519     while let Some(opt) = args.next() {
520         if opt.starts_with("--target=") {
521             let mut split = opt.split('=');
522             split.next();
523             return (split.next().unwrap().to_owned(), true);
524         }
525 
526         if opt == "-target" {
527             if let Some(target) = args.next() {
528                 return (target.clone(), true);
529             }
530         }
531     }
532 
533     // If we're running from a build script, try to find the cargo target.
534     if let Ok(t) = env::var("TARGET") {
535         return (t, false);
536     }
537 
538     (HOST_TARGET.to_owned(), false)
539 }
540 
541 impl BindgenContext {
542     /// Construct the context for the given `options`.
new(options: BindgenOptions) -> Self543     pub(crate) fn new(options: BindgenOptions) -> Self {
544         // TODO(emilio): Use the CXTargetInfo here when available.
545         //
546         // see: https://reviews.llvm.org/D32389
547         let (effective_target, explicit_target) =
548             find_effective_target(&options.clang_args);
549 
550         let index = clang::Index::new(false, true);
551 
552         let parse_options =
553             clang_sys::CXTranslationUnit_DetailedPreprocessingRecord;
554 
555         let translation_unit = {
556             let _t =
557                 Timer::new("translation_unit").with_output(options.time_phases);
558             let clang_args = if explicit_target {
559                 Cow::Borrowed(&options.clang_args)
560             } else {
561                 let mut args = Vec::with_capacity(options.clang_args.len() + 1);
562                 args.push(format!("--target={}", effective_target));
563                 args.extend_from_slice(&options.clang_args);
564                 Cow::Owned(args)
565             };
566 
567             clang::TranslationUnit::parse(
568                 &index,
569                 "",
570                 &clang_args,
571                 &options.input_unsaved_files,
572                 parse_options,
573             ).expect("libclang error; possible causes include:
574 - Invalid flag syntax
575 - Unrecognized flags
576 - Invalid flag arguments
577 - File I/O errors
578 - Host vs. target architecture mismatch
579 If you encounter an error missing from this list, please file an issue or a PR!")
580         };
581 
582         let target_info = clang::TargetInfo::new(&translation_unit);
583 
584         #[cfg(debug_assertions)]
585         {
586             if let Some(ref ti) = target_info {
587                 if effective_target == HOST_TARGET {
588                     assert_eq!(
589                         ti.pointer_width / 8,
590                         mem::size_of::<*mut ()>(),
591                         "{:?} {:?}",
592                         effective_target,
593                         HOST_TARGET
594                     );
595                 }
596             }
597         }
598 
599         let root_module = Self::build_root_module(ItemId(0));
600         let root_module_id = root_module.id().as_module_id_unchecked();
601 
602         BindgenContext {
603             items: vec![Some(root_module)],
604             types: Default::default(),
605             type_params: Default::default(),
606             modules: Default::default(),
607             root_module: root_module_id,
608             current_module: root_module_id,
609             semantic_parents: Default::default(),
610             currently_parsed_types: vec![],
611             parsed_macros: Default::default(),
612             replacements: Default::default(),
613             collected_typerefs: false,
614             in_codegen: false,
615             index,
616             translation_unit,
617             target_info,
618             options,
619             generated_bindgen_complex: Cell::new(false),
620             whitelisted: None,
621             codegen_items: None,
622             used_template_parameters: None,
623             need_bitfield_allocation: Default::default(),
624             cannot_derive_debug: None,
625             cannot_derive_default: None,
626             cannot_derive_copy: None,
627             cannot_derive_copy_in_array: None,
628             cannot_derive_hash: None,
629             cannot_derive_partialeq_or_partialord: None,
630             sizedness: None,
631             have_vtable: None,
632             have_destructor: None,
633             has_type_param_in_array: None,
634             has_float: None,
635         }
636     }
637 
638     /// Creates a timer for the current bindgen phase. If time_phases is `true`,
639     /// the timer will print to stderr when it is dropped, otherwise it will do
640     /// nothing.
timer<'a>(&self, name: &'a str) -> Timer<'a>641     pub fn timer<'a>(&self, name: &'a str) -> Timer<'a> {
642         Timer::new(name).with_output(self.options.time_phases)
643     }
644 
645     /// Returns the pointer width to use for the target for the current
646     /// translation.
target_pointer_size(&self) -> usize647     pub fn target_pointer_size(&self) -> usize {
648         if let Some(ref ti) = self.target_info {
649             return ti.pointer_width / 8;
650         }
651         mem::size_of::<*mut ()>()
652     }
653 
654     /// Get the stack of partially parsed types that we are in the middle of
655     /// parsing.
currently_parsed_types(&self) -> &[PartialType]656     pub fn currently_parsed_types(&self) -> &[PartialType] {
657         &self.currently_parsed_types[..]
658     }
659 
660     /// Begin parsing the given partial type, and push it onto the
661     /// `currently_parsed_types` stack so that we won't infinite recurse if we
662     /// run into a reference to it while parsing it.
begin_parsing(&mut self, partial_ty: PartialType)663     pub fn begin_parsing(&mut self, partial_ty: PartialType) {
664         self.currently_parsed_types.push(partial_ty);
665     }
666 
667     /// Finish parsing the current partial type, pop it off the
668     /// `currently_parsed_types` stack, and return it.
finish_parsing(&mut self) -> PartialType669     pub fn finish_parsing(&mut self) -> PartialType {
670         self.currently_parsed_types.pop().expect(
671             "should have been parsing a type, if we finished parsing a type",
672         )
673     }
674 
675     /// Get the user-provided callbacks by reference, if any.
parse_callbacks(&self) -> Option<&dyn ParseCallbacks>676     pub fn parse_callbacks(&self) -> Option<&dyn ParseCallbacks> {
677         self.options().parse_callbacks.as_ref().map(|t| &**t)
678     }
679 
680     /// Define a new item.
681     ///
682     /// This inserts it into the internal items set, and its type into the
683     /// internal types set.
add_item( &mut self, item: Item, declaration: Option<Cursor>, location: Option<Cursor>, )684     pub fn add_item(
685         &mut self,
686         item: Item,
687         declaration: Option<Cursor>,
688         location: Option<Cursor>,
689     ) {
690         debug!(
691             "BindgenContext::add_item({:?}, declaration: {:?}, loc: {:?}",
692             item, declaration, location
693         );
694         debug_assert!(
695             declaration.is_some() ||
696                 !item.kind().is_type() ||
697                 item.kind().expect_type().is_builtin_or_type_param() ||
698                 item.kind().expect_type().is_opaque(self, &item) ||
699                 item.kind().expect_type().is_unresolved_ref(),
700             "Adding a type without declaration?"
701         );
702 
703         let id = item.id();
704         let is_type = item.kind().is_type();
705         let is_unnamed = is_type && item.expect_type().name().is_none();
706         let is_template_instantiation =
707             is_type && item.expect_type().is_template_instantiation();
708 
709         if item.id() != self.root_module {
710             self.add_item_to_module(&item);
711         }
712 
713         if is_type && item.expect_type().is_comp() {
714             self.need_bitfield_allocation.push(id);
715         }
716 
717         let old_item = mem::replace(&mut self.items[id.0], Some(item));
718         assert!(
719             old_item.is_none(),
720             "should not have already associated an item with the given id"
721         );
722 
723         // Unnamed items can have an USR, but they can't be referenced from
724         // other sites explicitly and the USR can match if the unnamed items are
725         // nested, so don't bother tracking them.
726         if is_type && !is_template_instantiation && declaration.is_some() {
727             let mut declaration = declaration.unwrap();
728             if !declaration.is_valid() {
729                 if let Some(location) = location {
730                     if location.is_template_like() {
731                         declaration = location;
732                     }
733                 }
734             }
735             declaration = declaration.canonical();
736             if !declaration.is_valid() {
737                 // This could happen, for example, with types like `int*` or
738                 // similar.
739                 //
740                 // Fortunately, we don't care about those types being
741                 // duplicated, so we can just ignore them.
742                 debug!(
743                     "Invalid declaration {:?} found for type {:?}",
744                     declaration,
745                     self.resolve_item_fallible(id)
746                         .unwrap()
747                         .kind()
748                         .expect_type()
749                 );
750                 return;
751             }
752 
753             let key = if is_unnamed {
754                 TypeKey::Declaration(declaration)
755             } else if let Some(usr) = declaration.usr() {
756                 TypeKey::USR(usr)
757             } else {
758                 warn!(
759                     "Valid declaration with no USR: {:?}, {:?}",
760                     declaration, location
761                 );
762                 TypeKey::Declaration(declaration)
763             };
764 
765             let old = self.types.insert(key, id.as_type_id_unchecked());
766             debug_assert_eq!(old, None);
767         }
768     }
769 
770     /// Ensure that every item (other than the root module) is in a module's
771     /// children list. This is to make sure that every whitelisted item get's
772     /// codegen'd, even if its parent is not whitelisted. See issue #769 for
773     /// details.
add_item_to_module(&mut self, item: &Item)774     fn add_item_to_module(&mut self, item: &Item) {
775         assert!(item.id() != self.root_module);
776         assert!(self.resolve_item_fallible(item.id()).is_none());
777 
778         if let Some(ref mut parent) = self.items[item.parent_id().0] {
779             if let Some(module) = parent.as_module_mut() {
780                 debug!(
781                     "add_item_to_module: adding {:?} as child of parent module {:?}",
782                     item.id(),
783                     item.parent_id()
784                 );
785 
786                 module.children_mut().insert(item.id());
787                 return;
788             }
789         }
790 
791         debug!(
792             "add_item_to_module: adding {:?} as child of current module {:?}",
793             item.id(),
794             self.current_module
795         );
796 
797         self.items[(self.current_module.0).0]
798             .as_mut()
799             .expect("Should always have an item for self.current_module")
800             .as_module_mut()
801             .expect("self.current_module should always be a module")
802             .children_mut()
803             .insert(item.id());
804     }
805 
806     /// Add a new named template type parameter to this context's item set.
add_type_param(&mut self, item: Item, definition: clang::Cursor)807     pub fn add_type_param(&mut self, item: Item, definition: clang::Cursor) {
808         debug!(
809             "BindgenContext::add_type_param: item = {:?}; definition = {:?}",
810             item, definition
811         );
812 
813         assert!(
814             item.expect_type().is_type_param(),
815             "Should directly be a named type, not a resolved reference or anything"
816         );
817         assert_eq!(
818             definition.kind(),
819             clang_sys::CXCursor_TemplateTypeParameter
820         );
821 
822         self.add_item_to_module(&item);
823 
824         let id = item.id();
825         let old_item = mem::replace(&mut self.items[id.0], Some(item));
826         assert!(
827             old_item.is_none(),
828             "should not have already associated an item with the given id"
829         );
830 
831         let old_named_ty = self
832             .type_params
833             .insert(definition, id.as_type_id_unchecked());
834         assert!(
835             old_named_ty.is_none(),
836             "should not have already associated a named type with this id"
837         );
838     }
839 
840     /// Get the named type defined at the given cursor location, if we've
841     /// already added one.
get_type_param(&self, definition: &clang::Cursor) -> Option<TypeId>842     pub fn get_type_param(&self, definition: &clang::Cursor) -> Option<TypeId> {
843         assert_eq!(
844             definition.kind(),
845             clang_sys::CXCursor_TemplateTypeParameter
846         );
847         self.type_params.get(definition).cloned()
848     }
849 
850     // TODO: Move all this syntax crap to other part of the code.
851 
852     /// Mangles a name so it doesn't conflict with any keyword.
rust_mangle<'a>(&self, name: &'a str) -> Cow<'a, str>853     pub fn rust_mangle<'a>(&self, name: &'a str) -> Cow<'a, str> {
854         if name.contains("@") ||
855             name.contains("?") ||
856             name.contains("$") ||
857             match name {
858                 "abstract" | "alignof" | "as" | "async" | "become" |
859                 "box" | "break" | "const" | "continue" | "crate" | "do" |
860                 "else" | "enum" | "extern" | "false" | "final" | "fn" |
861                 "for" | "if" | "impl" | "in" | "let" | "loop" | "macro" |
862                 "match" | "mod" | "move" | "mut" | "offsetof" |
863                 "override" | "priv" | "proc" | "pub" | "pure" | "ref" |
864                 "return" | "Self" | "self" | "sizeof" | "static" |
865                 "struct" | "super" | "trait" | "true" | "type" | "typeof" |
866                 "unsafe" | "unsized" | "use" | "virtual" | "where" |
867                 "while" | "yield" | "bool" | "_" => true,
868                 _ => false,
869             }
870         {
871             let mut s = name.to_owned();
872             s = s.replace("@", "_");
873             s = s.replace("?", "_");
874             s = s.replace("$", "_");
875             s.push_str("_");
876             return Cow::Owned(s);
877         }
878         Cow::Borrowed(name)
879     }
880 
881     /// Returns a mangled name as a rust identifier.
rust_ident<S>(&self, name: S) -> Ident where S: AsRef<str>,882     pub fn rust_ident<S>(&self, name: S) -> Ident
883     where
884         S: AsRef<str>,
885     {
886         self.rust_ident_raw(self.rust_mangle(name.as_ref()))
887     }
888 
889     /// Returns a mangled name as a rust identifier.
rust_ident_raw<T>(&self, name: T) -> Ident where T: AsRef<str>,890     pub fn rust_ident_raw<T>(&self, name: T) -> Ident
891     where
892         T: AsRef<str>,
893     {
894         Ident::new(name.as_ref(), Span::call_site())
895     }
896 
897     /// Iterate over all items that have been defined.
items(&self) -> impl Iterator<Item = (ItemId, &Item)>898     pub fn items(&self) -> impl Iterator<Item = (ItemId, &Item)> {
899         self.items.iter().enumerate().filter_map(|(index, item)| {
900             let item = item.as_ref()?;
901             Some((ItemId(index), item))
902         })
903     }
904 
905     /// Have we collected all unresolved type references yet?
collected_typerefs(&self) -> bool906     pub fn collected_typerefs(&self) -> bool {
907         self.collected_typerefs
908     }
909 
910     /// Gather all the unresolved type references.
collect_typerefs( &mut self, ) -> Vec<(ItemId, clang::Type, clang::Cursor, Option<ItemId>)>911     fn collect_typerefs(
912         &mut self,
913     ) -> Vec<(ItemId, clang::Type, clang::Cursor, Option<ItemId>)> {
914         debug_assert!(!self.collected_typerefs);
915         self.collected_typerefs = true;
916         let mut typerefs = vec![];
917 
918         for (id, item) in self.items() {
919             let kind = item.kind();
920             let ty = match kind.as_type() {
921                 Some(ty) => ty,
922                 None => continue,
923             };
924 
925             match *ty.kind() {
926                 TypeKind::UnresolvedTypeRef(ref ty, loc, parent_id) => {
927                     typerefs.push((id, ty.clone(), loc, parent_id));
928                 }
929                 _ => {}
930             };
931         }
932         typerefs
933     }
934 
935     /// Collect all of our unresolved type references and resolve them.
resolve_typerefs(&mut self)936     fn resolve_typerefs(&mut self) {
937         let _t = self.timer("resolve_typerefs");
938 
939         let typerefs = self.collect_typerefs();
940 
941         for (id, ty, loc, parent_id) in typerefs {
942             let _resolved =
943                 {
944                     let resolved = Item::from_ty(&ty, loc, parent_id, self)
945                     .unwrap_or_else(|_| {
946                         warn!("Could not resolve type reference, falling back \
947                                to opaque blob");
948                         Item::new_opaque_type(self.next_item_id(), &ty, self)
949                     });
950 
951                     let item = self.items[id.0].as_mut().unwrap();
952                     *item.kind_mut().as_type_mut().unwrap().kind_mut() =
953                         TypeKind::ResolvedTypeRef(resolved);
954                     resolved
955                 };
956 
957             // Something in the STL is trolling me. I don't need this assertion
958             // right now, but worth investigating properly once this lands.
959             //
960             // debug_assert!(self.items.get(&resolved).is_some(), "How?");
961             //
962             // if let Some(parent_id) = parent_id {
963             //     assert_eq!(self.items[&resolved].parent_id(), parent_id);
964             // }
965         }
966     }
967 
968     /// Temporarily loan `Item` with the given `ItemId`. This provides means to
969     /// mutably borrow `Item` while having a reference to `BindgenContext`.
970     ///
971     /// `Item` with the given `ItemId` is removed from the context, given
972     /// closure is executed and then `Item` is placed back.
973     ///
974     /// # Panics
975     ///
976     /// Panics if attempt to resolve given `ItemId` inside the given
977     /// closure is made.
with_loaned_item<F, T>(&mut self, id: ItemId, f: F) -> T where F: (FnOnce(&BindgenContext, &mut Item) -> T),978     fn with_loaned_item<F, T>(&mut self, id: ItemId, f: F) -> T
979     where
980         F: (FnOnce(&BindgenContext, &mut Item) -> T),
981     {
982         let mut item = self.items[id.0].take().unwrap();
983 
984         let result = f(self, &mut item);
985 
986         let existing = mem::replace(&mut self.items[id.0], Some(item));
987         assert!(existing.is_none());
988 
989         result
990     }
991 
992     /// Compute the bitfield allocation units for all `TypeKind::Comp` items we
993     /// parsed.
compute_bitfield_units(&mut self)994     fn compute_bitfield_units(&mut self) {
995         let _t = self.timer("compute_bitfield_units");
996 
997         assert!(self.collected_typerefs());
998 
999         let need_bitfield_allocation =
1000             mem::replace(&mut self.need_bitfield_allocation, vec![]);
1001         for id in need_bitfield_allocation {
1002             self.with_loaned_item(id, |ctx, item| {
1003                 item.kind_mut()
1004                     .as_type_mut()
1005                     .unwrap()
1006                     .as_comp_mut()
1007                     .unwrap()
1008                     .compute_bitfield_units(ctx);
1009             });
1010         }
1011     }
1012 
1013     /// Assign a new generated name for each anonymous field.
deanonymize_fields(&mut self)1014     fn deanonymize_fields(&mut self) {
1015         let _t = self.timer("deanonymize_fields");
1016 
1017         let comp_item_ids: Vec<ItemId> = self
1018             .items()
1019             .filter_map(|(id, item)| {
1020                 if item.kind().as_type()?.is_comp() {
1021                     return Some(id);
1022                 }
1023                 None
1024             })
1025             .collect();
1026 
1027         for id in comp_item_ids {
1028             self.with_loaned_item(id, |ctx, item| {
1029                 item.kind_mut()
1030                     .as_type_mut()
1031                     .unwrap()
1032                     .as_comp_mut()
1033                     .unwrap()
1034                     .deanonymize_fields(ctx);
1035             });
1036         }
1037     }
1038 
1039     /// Iterate over all items and replace any item that has been named in a
1040     /// `replaces="SomeType"` annotation with the replacement type.
process_replacements(&mut self)1041     fn process_replacements(&mut self) {
1042         let _t = self.timer("process_replacements");
1043         if self.replacements.is_empty() {
1044             debug!("No replacements to process");
1045             return;
1046         }
1047 
1048         // FIXME: This is linear, but the replaces="xxx" annotation was already
1049         // there, and for better or worse it's useful, sigh...
1050         //
1051         // We leverage the ResolvedTypeRef thing, though, which is cool :P.
1052 
1053         let mut replacements = vec![];
1054 
1055         for (id, item) in self.items() {
1056             if item.annotations().use_instead_of().is_some() {
1057                 continue;
1058             }
1059 
1060             // Calls to `canonical_name` are expensive, so eagerly filter out
1061             // items that cannot be replaced.
1062             let ty = match item.kind().as_type() {
1063                 Some(ty) => ty,
1064                 None => continue,
1065             };
1066 
1067             match *ty.kind() {
1068                 TypeKind::Comp(..) |
1069                 TypeKind::TemplateAlias(..) |
1070                 TypeKind::Enum(..) |
1071                 TypeKind::Alias(..) => {}
1072                 _ => continue,
1073             }
1074 
1075             let path = item.path_for_whitelisting(self);
1076             let replacement = self.replacements.get(&path[1..]);
1077 
1078             if let Some(replacement) = replacement {
1079                 if *replacement != id {
1080                     // We set this just after parsing the annotation. It's
1081                     // very unlikely, but this can happen.
1082                     if self.resolve_item_fallible(*replacement).is_some() {
1083                         replacements.push((
1084                             id.expect_type_id(self),
1085                             replacement.expect_type_id(self),
1086                         ));
1087                     }
1088                 }
1089             }
1090         }
1091 
1092         for (id, replacement_id) in replacements {
1093             debug!("Replacing {:?} with {:?}", id, replacement_id);
1094             let new_parent = {
1095                 let item_id: ItemId = id.into();
1096                 let item = self.items[item_id.0].as_mut().unwrap();
1097                 *item.kind_mut().as_type_mut().unwrap().kind_mut() =
1098                     TypeKind::ResolvedTypeRef(replacement_id);
1099                 item.parent_id()
1100             };
1101 
1102             // Relocate the replacement item from where it was declared, to
1103             // where the thing it is replacing was declared.
1104             //
1105             // First, we'll make sure that its parent id is correct.
1106 
1107             let old_parent = self.resolve_item(replacement_id).parent_id();
1108             if new_parent == old_parent {
1109                 // Same parent and therefore also same containing
1110                 // module. Nothing to do here.
1111                 continue;
1112             }
1113 
1114             let replacement_item_id: ItemId = replacement_id.into();
1115             self.items[replacement_item_id.0]
1116                 .as_mut()
1117                 .unwrap()
1118                 .set_parent_for_replacement(new_parent);
1119 
1120             // Second, make sure that it is in the correct module's children
1121             // set.
1122 
1123             let old_module = {
1124                 let immut_self = &*self;
1125                 old_parent
1126                     .ancestors(immut_self)
1127                     .chain(Some(immut_self.root_module.into()))
1128                     .find(|id| {
1129                         let item = immut_self.resolve_item(*id);
1130                         item.as_module().map_or(false, |m| {
1131                             m.children().contains(&replacement_id.into())
1132                         })
1133                     })
1134             };
1135             let old_module = old_module
1136                 .expect("Every replacement item should be in a module");
1137 
1138             let new_module = {
1139                 let immut_self = &*self;
1140                 new_parent
1141                     .ancestors(immut_self)
1142                     .find(|id| immut_self.resolve_item(*id).is_module())
1143             };
1144             let new_module = new_module.unwrap_or(self.root_module.into());
1145 
1146             if new_module == old_module {
1147                 // Already in the correct module.
1148                 continue;
1149             }
1150 
1151             self.items[old_module.0]
1152                 .as_mut()
1153                 .unwrap()
1154                 .as_module_mut()
1155                 .unwrap()
1156                 .children_mut()
1157                 .remove(&replacement_id.into());
1158 
1159             self.items[new_module.0]
1160                 .as_mut()
1161                 .unwrap()
1162                 .as_module_mut()
1163                 .unwrap()
1164                 .children_mut()
1165                 .insert(replacement_id.into());
1166         }
1167     }
1168 
1169     /// Enter the code generation phase, invoke the given callback `cb`, and
1170     /// leave the code generation phase.
gen<F, Out>(mut self, cb: F) -> (Out, BindgenOptions) where F: FnOnce(&Self) -> Out,1171     pub(crate) fn gen<F, Out>(mut self, cb: F) -> (Out, BindgenOptions)
1172     where
1173         F: FnOnce(&Self) -> Out,
1174     {
1175         self.in_codegen = true;
1176 
1177         self.resolve_typerefs();
1178         self.compute_bitfield_units();
1179         self.process_replacements();
1180 
1181         self.deanonymize_fields();
1182 
1183         self.assert_no_dangling_references();
1184 
1185         // Compute the whitelisted set after processing replacements and
1186         // resolving type refs, as those are the final mutations of the IR
1187         // graph, and their completion means that the IR graph is now frozen.
1188         self.compute_whitelisted_and_codegen_items();
1189 
1190         // Make sure to do this after processing replacements, since that messes
1191         // with the parentage and module children, and we want to assert that it
1192         // messes with them correctly.
1193         self.assert_every_item_in_a_module();
1194 
1195         self.compute_has_vtable();
1196         self.compute_sizedness();
1197         self.compute_has_destructor();
1198         self.find_used_template_parameters();
1199         self.compute_cannot_derive_debug();
1200         self.compute_cannot_derive_default();
1201         self.compute_cannot_derive_copy();
1202         self.compute_has_type_param_in_array();
1203         self.compute_has_float();
1204         self.compute_cannot_derive_hash();
1205         self.compute_cannot_derive_partialord_partialeq_or_eq();
1206 
1207         let ret = cb(&self);
1208         (ret, self.options)
1209     }
1210 
1211     /// When the `testing_only_extra_assertions` feature is enabled, this
1212     /// function walks the IR graph and asserts that we do not have any edges
1213     /// referencing an ItemId for which we do not have an associated IR item.
assert_no_dangling_references(&self)1214     fn assert_no_dangling_references(&self) {
1215         if cfg!(feature = "testing_only_extra_assertions") {
1216             for _ in self.assert_no_dangling_item_traversal() {
1217                 // The iterator's next method does the asserting for us.
1218             }
1219         }
1220     }
1221 
assert_no_dangling_item_traversal( &self, ) -> traversal::AssertNoDanglingItemsTraversal1222     fn assert_no_dangling_item_traversal(
1223         &self,
1224     ) -> traversal::AssertNoDanglingItemsTraversal {
1225         assert!(self.in_codegen_phase());
1226         assert!(self.current_module == self.root_module);
1227 
1228         let roots = self.items().map(|(id, _)| id);
1229         traversal::AssertNoDanglingItemsTraversal::new(
1230             self,
1231             roots,
1232             traversal::all_edges,
1233         )
1234     }
1235 
1236     /// When the `testing_only_extra_assertions` feature is enabled, walk over
1237     /// every item and ensure that it is in the children set of one of its
1238     /// module ancestors.
assert_every_item_in_a_module(&self)1239     fn assert_every_item_in_a_module(&self) {
1240         if cfg!(feature = "testing_only_extra_assertions") {
1241             assert!(self.in_codegen_phase());
1242             assert!(self.current_module == self.root_module);
1243 
1244             for (id, _item) in self.items() {
1245                 if id == self.root_module {
1246                     continue;
1247                 }
1248 
1249                 assert!(
1250                     {
1251                         let id = id
1252                             .into_resolver()
1253                             .through_type_refs()
1254                             .through_type_aliases()
1255                             .resolve(self)
1256                             .id();
1257                         id.ancestors(self)
1258                             .chain(Some(self.root_module.into()))
1259                             .any(|ancestor| {
1260                                 debug!(
1261                                     "Checking if {:?} is a child of {:?}",
1262                                     id, ancestor
1263                                 );
1264                                 self.resolve_item(ancestor)
1265                                     .as_module()
1266                                     .map_or(false, |m| {
1267                                         m.children().contains(&id)
1268                                     })
1269                             })
1270                     },
1271                     "{:?} should be in some ancestor module's children set",
1272                     id
1273                 );
1274             }
1275         }
1276     }
1277 
1278     /// Compute for every type whether it is sized or not, and whether it is
1279     /// sized or not as a base class.
compute_sizedness(&mut self)1280     fn compute_sizedness(&mut self) {
1281         let _t = self.timer("compute_sizedness");
1282         assert!(self.sizedness.is_none());
1283         self.sizedness = Some(analyze::<SizednessAnalysis>(self));
1284     }
1285 
1286     /// Look up whether the type with the given id is sized or not.
lookup_sizedness(&self, id: TypeId) -> SizednessResult1287     pub fn lookup_sizedness(&self, id: TypeId) -> SizednessResult {
1288         assert!(
1289             self.in_codegen_phase(),
1290             "We only compute sizedness after we've entered codegen"
1291         );
1292 
1293         self.sizedness
1294             .as_ref()
1295             .unwrap()
1296             .get(&id)
1297             .cloned()
1298             .unwrap_or(SizednessResult::ZeroSized)
1299     }
1300 
1301     /// Compute whether the type has vtable.
compute_has_vtable(&mut self)1302     fn compute_has_vtable(&mut self) {
1303         let _t = self.timer("compute_has_vtable");
1304         assert!(self.have_vtable.is_none());
1305         self.have_vtable = Some(analyze::<HasVtableAnalysis>(self));
1306     }
1307 
1308     /// Look up whether the item with `id` has vtable or not.
lookup_has_vtable(&self, id: TypeId) -> HasVtableResult1309     pub fn lookup_has_vtable(&self, id: TypeId) -> HasVtableResult {
1310         assert!(
1311             self.in_codegen_phase(),
1312             "We only compute vtables when we enter codegen"
1313         );
1314 
1315         // Look up the computed value for whether the item with `id` has a
1316         // vtable or not.
1317         self.have_vtable
1318             .as_ref()
1319             .unwrap()
1320             .get(&id.into())
1321             .cloned()
1322             .unwrap_or(HasVtableResult::No)
1323     }
1324 
1325     /// Compute whether the type has a destructor.
compute_has_destructor(&mut self)1326     fn compute_has_destructor(&mut self) {
1327         let _t = self.timer("compute_has_destructor");
1328         assert!(self.have_destructor.is_none());
1329         self.have_destructor = Some(analyze::<HasDestructorAnalysis>(self));
1330     }
1331 
1332     /// Look up whether the item with `id` has a destructor.
lookup_has_destructor(&self, id: TypeId) -> bool1333     pub fn lookup_has_destructor(&self, id: TypeId) -> bool {
1334         assert!(
1335             self.in_codegen_phase(),
1336             "We only compute destructors when we enter codegen"
1337         );
1338 
1339         self.have_destructor.as_ref().unwrap().contains(&id.into())
1340     }
1341 
find_used_template_parameters(&mut self)1342     fn find_used_template_parameters(&mut self) {
1343         let _t = self.timer("find_used_template_parameters");
1344         if self.options.whitelist_recursively {
1345             let used_params = analyze::<UsedTemplateParameters>(self);
1346             self.used_template_parameters = Some(used_params);
1347         } else {
1348             // If you aren't recursively whitelisting, then we can't really make
1349             // any sense of template parameter usage, and you're on your own.
1350             let mut used_params = HashMap::default();
1351             for &id in self.whitelisted_items() {
1352                 used_params.entry(id).or_insert(
1353                     id.self_template_params(self)
1354                         .into_iter()
1355                         .map(|p| p.into())
1356                         .collect(),
1357                 );
1358             }
1359             self.used_template_parameters = Some(used_params);
1360         }
1361     }
1362 
1363     /// Return `true` if `item` uses the given `template_param`, `false`
1364     /// otherwise.
1365     ///
1366     /// This method may only be called during the codegen phase, because the
1367     /// template usage information is only computed as we enter the codegen
1368     /// phase.
1369     ///
1370     /// If the item is blacklisted, then we say that it always uses the template
1371     /// parameter. This is a little subtle. The template parameter usage
1372     /// analysis only considers whitelisted items, and if any blacklisted item
1373     /// shows up in the generated bindings, it is the user's responsibility to
1374     /// manually provide a definition for them. To give them the most
1375     /// flexibility when doing that, we assume that they use every template
1376     /// parameter and always pass template arguments through in instantiations.
uses_template_parameter( &self, item: ItemId, template_param: TypeId, ) -> bool1377     pub fn uses_template_parameter(
1378         &self,
1379         item: ItemId,
1380         template_param: TypeId,
1381     ) -> bool {
1382         assert!(
1383             self.in_codegen_phase(),
1384             "We only compute template parameter usage as we enter codegen"
1385         );
1386 
1387         if self.resolve_item(item).is_blacklisted(self) {
1388             return true;
1389         }
1390 
1391         let template_param = template_param
1392             .into_resolver()
1393             .through_type_refs()
1394             .through_type_aliases()
1395             .resolve(self)
1396             .id();
1397 
1398         self.used_template_parameters
1399             .as_ref()
1400             .expect("should have found template parameter usage if we're in codegen")
1401             .get(&item)
1402             .map_or(false, |items_used_params| items_used_params.contains(&template_param))
1403     }
1404 
1405     /// Return `true` if `item` uses any unbound, generic template parameters,
1406     /// `false` otherwise.
1407     ///
1408     /// Has the same restrictions that `uses_template_parameter` has.
uses_any_template_parameters(&self, item: ItemId) -> bool1409     pub fn uses_any_template_parameters(&self, item: ItemId) -> bool {
1410         assert!(
1411             self.in_codegen_phase(),
1412             "We only compute template parameter usage as we enter codegen"
1413         );
1414 
1415         self.used_template_parameters
1416             .as_ref()
1417             .expect(
1418                 "should have template parameter usage info in codegen phase",
1419             )
1420             .get(&item)
1421             .map_or(false, |used| !used.is_empty())
1422     }
1423 
1424     // This deserves a comment. Builtin types don't get a valid declaration, so
1425     // we can't add it to the cursor->type map.
1426     //
1427     // That being said, they're not generated anyway, and are few, so the
1428     // duplication and special-casing is fine.
1429     //
1430     // If at some point we care about the memory here, probably a map TypeKind
1431     // -> builtin type ItemId would be the best to improve that.
add_builtin_item(&mut self, item: Item)1432     fn add_builtin_item(&mut self, item: Item) {
1433         debug!("add_builtin_item: item = {:?}", item);
1434         debug_assert!(item.kind().is_type());
1435         self.add_item_to_module(&item);
1436         let id = item.id();
1437         let old_item = mem::replace(&mut self.items[id.0], Some(item));
1438         assert!(old_item.is_none(), "Inserted type twice?");
1439     }
1440 
build_root_module(id: ItemId) -> Item1441     fn build_root_module(id: ItemId) -> Item {
1442         let module = Module::new(Some("root".into()), ModuleKind::Normal);
1443         Item::new(id, None, None, id, ItemKind::Module(module))
1444     }
1445 
1446     /// Get the root module.
root_module(&self) -> ModuleId1447     pub fn root_module(&self) -> ModuleId {
1448         self.root_module
1449     }
1450 
1451     /// Resolve a type with the given id.
1452     ///
1453     /// Panics if there is no item for the given `TypeId` or if the resolved
1454     /// item is not a `Type`.
resolve_type(&self, type_id: TypeId) -> &Type1455     pub fn resolve_type(&self, type_id: TypeId) -> &Type {
1456         self.resolve_item(type_id).kind().expect_type()
1457     }
1458 
1459     /// Resolve a function with the given id.
1460     ///
1461     /// Panics if there is no item for the given `FunctionId` or if the resolved
1462     /// item is not a `Function`.
resolve_func(&self, func_id: FunctionId) -> &Function1463     pub fn resolve_func(&self, func_id: FunctionId) -> &Function {
1464         self.resolve_item(func_id).kind().expect_function()
1465     }
1466 
1467     /// Resolve the given `ItemId` as a type, or `None` if there is no item with
1468     /// the given id.
1469     ///
1470     /// Panics if the id resolves to an item that is not a type.
safe_resolve_type(&self, type_id: TypeId) -> Option<&Type>1471     pub fn safe_resolve_type(&self, type_id: TypeId) -> Option<&Type> {
1472         self.resolve_item_fallible(type_id)
1473             .map(|t| t.kind().expect_type())
1474     }
1475 
1476     /// Resolve the given `ItemId` into an `Item`, or `None` if no such item
1477     /// exists.
resolve_item_fallible<Id: Into<ItemId>>( &self, id: Id, ) -> Option<&Item>1478     pub fn resolve_item_fallible<Id: Into<ItemId>>(
1479         &self,
1480         id: Id,
1481     ) -> Option<&Item> {
1482         self.items.get(id.into().0)?.as_ref()
1483     }
1484 
1485     /// Resolve the given `ItemId` into an `Item`.
1486     ///
1487     /// Panics if the given id does not resolve to any item.
resolve_item<Id: Into<ItemId>>(&self, item_id: Id) -> &Item1488     pub fn resolve_item<Id: Into<ItemId>>(&self, item_id: Id) -> &Item {
1489         let item_id = item_id.into();
1490         match self.resolve_item_fallible(item_id) {
1491             Some(item) => item,
1492             None => panic!("Not an item: {:?}", item_id),
1493         }
1494     }
1495 
1496     /// Get the current module.
current_module(&self) -> ModuleId1497     pub fn current_module(&self) -> ModuleId {
1498         self.current_module
1499     }
1500 
1501     /// Add a semantic parent for a given type definition.
1502     ///
1503     /// We do this from the type declaration, in order to be able to find the
1504     /// correct type definition afterwards.
1505     ///
1506     /// TODO(emilio): We could consider doing this only when
1507     /// declaration.lexical_parent() != definition.lexical_parent(), but it's
1508     /// not sure it's worth it.
add_semantic_parent( &mut self, definition: clang::Cursor, parent_id: ItemId, )1509     pub fn add_semantic_parent(
1510         &mut self,
1511         definition: clang::Cursor,
1512         parent_id: ItemId,
1513     ) {
1514         self.semantic_parents.insert(definition, parent_id);
1515     }
1516 
1517     /// Returns a known semantic parent for a given definition.
known_semantic_parent( &self, definition: clang::Cursor, ) -> Option<ItemId>1518     pub fn known_semantic_parent(
1519         &self,
1520         definition: clang::Cursor,
1521     ) -> Option<ItemId> {
1522         self.semantic_parents.get(&definition).cloned()
1523     }
1524 
1525     /// Given a cursor pointing to the location of a template instantiation,
1526     /// return a tuple of the form `(declaration_cursor, declaration_id,
1527     /// num_expected_template_args)`.
1528     ///
1529     /// Note that `declaration_id` is not guaranteed to be in the context's item
1530     /// set! It is possible that it is a partial type that we are still in the
1531     /// middle of parsing.
get_declaration_info_for_template_instantiation( &self, instantiation: &Cursor, ) -> Option<(Cursor, ItemId, usize)>1532     fn get_declaration_info_for_template_instantiation(
1533         &self,
1534         instantiation: &Cursor,
1535     ) -> Option<(Cursor, ItemId, usize)> {
1536         instantiation
1537             .cur_type()
1538             .canonical_declaration(Some(instantiation))
1539             .and_then(|canon_decl| {
1540                 self.get_resolved_type(&canon_decl).and_then(
1541                     |template_decl_id| {
1542                         let num_params =
1543                             template_decl_id.num_self_template_params(self);
1544                         if num_params == 0 {
1545                             None
1546                         } else {
1547                             Some((
1548                                 *canon_decl.cursor(),
1549                                 template_decl_id.into(),
1550                                 num_params,
1551                             ))
1552                         }
1553                     },
1554                 )
1555             })
1556             .or_else(|| {
1557                 // If we haven't already parsed the declaration of
1558                 // the template being instantiated, then it *must*
1559                 // be on the stack of types we are currently
1560                 // parsing. If it wasn't then clang would have
1561                 // already errored out before we started
1562                 // constructing our IR because you can't instantiate
1563                 // a template until it is fully defined.
1564                 instantiation
1565                     .referenced()
1566                     .and_then(|referenced| {
1567                         self.currently_parsed_types()
1568                             .iter()
1569                             .find(|partial_ty| *partial_ty.decl() == referenced)
1570                             .cloned()
1571                     })
1572                     .and_then(|template_decl| {
1573                         let num_template_params =
1574                             template_decl.num_self_template_params(self);
1575                         if num_template_params == 0 {
1576                             None
1577                         } else {
1578                             Some((
1579                                 *template_decl.decl(),
1580                                 template_decl.id(),
1581                                 num_template_params,
1582                             ))
1583                         }
1584                     })
1585             })
1586     }
1587 
1588     /// Parse a template instantiation, eg `Foo<int>`.
1589     ///
1590     /// This is surprisingly difficult to do with libclang, due to the fact that
1591     /// it doesn't provide explicit template argument information, except for
1592     /// function template declarations(!?!??!).
1593     ///
1594     /// The only way to do this is manually inspecting the AST and looking for
1595     /// TypeRefs and TemplateRefs inside. This, unfortunately, doesn't work for
1596     /// more complex cases, see the comment on the assertion below.
1597     ///
1598     /// To add insult to injury, the AST itself has structure that doesn't make
1599     /// sense. Sometimes `Foo<Bar<int>>` has an AST with nesting like you might
1600     /// expect: `(Foo (Bar (int)))`. Other times, the AST we get is completely
1601     /// flat: `(Foo Bar int)`.
1602     ///
1603     /// To see an example of what this method handles:
1604     ///
1605     /// ```c++
1606     /// template<typename T>
1607     /// class Incomplete {
1608     ///   T p;
1609     /// };
1610     ///
1611     /// template<typename U>
1612     /// class Foo {
1613     ///   Incomplete<U> bar;
1614     /// };
1615     /// ```
1616     ///
1617     /// Finally, template instantiations are always children of the current
1618     /// module. They use their template's definition for their name, so the
1619     /// parent is only useful for ensuring that their layout tests get
1620     /// codegen'd.
instantiate_template( &mut self, with_id: ItemId, template: TypeId, ty: &clang::Type, location: clang::Cursor, ) -> Option<TypeId>1621     fn instantiate_template(
1622         &mut self,
1623         with_id: ItemId,
1624         template: TypeId,
1625         ty: &clang::Type,
1626         location: clang::Cursor,
1627     ) -> Option<TypeId> {
1628         let num_expected_args =
1629             self.resolve_type(template).num_self_template_params(self);
1630         if num_expected_args == 0 {
1631             warn!(
1632                 "Tried to instantiate a template for which we could not \
1633                  determine any template parameters"
1634             );
1635             return None;
1636         }
1637 
1638         let mut args = vec![];
1639         let mut found_const_arg = false;
1640         let mut children = location.collect_children();
1641 
1642         if children.iter().all(|c| !c.has_children()) {
1643             // This is insanity... If clang isn't giving us a properly nested
1644             // AST for which template arguments belong to which template we are
1645             // instantiating, we'll need to construct it ourselves. However,
1646             // there is an extra `NamespaceRef, NamespaceRef, ..., TemplateRef`
1647             // representing a reference to the outermost template declaration
1648             // that we need to filter out of the children. We need to do this
1649             // filtering because we already know which template declaration is
1650             // being specialized via the `location`'s type, and if we do not
1651             // filter it out, we'll add an extra layer of template instantiation
1652             // on accident.
1653             let idx = children
1654                 .iter()
1655                 .position(|c| c.kind() == clang_sys::CXCursor_TemplateRef);
1656             if let Some(idx) = idx {
1657                 if children
1658                     .iter()
1659                     .take(idx)
1660                     .all(|c| c.kind() == clang_sys::CXCursor_NamespaceRef)
1661                 {
1662                     children = children.into_iter().skip(idx + 1).collect();
1663                 }
1664             }
1665         }
1666 
1667         for child in children.iter().rev() {
1668             match child.kind() {
1669                 clang_sys::CXCursor_TypeRef |
1670                 clang_sys::CXCursor_TypedefDecl |
1671                 clang_sys::CXCursor_TypeAliasDecl => {
1672                     // The `with_id` id will potentially end up unused if we give up
1673                     // on this type (for example, because it has const value
1674                     // template args), so if we pass `with_id` as the parent, it is
1675                     // potentially a dangling reference. Instead, use the canonical
1676                     // template declaration as the parent. It is already parsed and
1677                     // has a known-resolvable `ItemId`.
1678                     let ty = Item::from_ty_or_ref(
1679                         child.cur_type(),
1680                         *child,
1681                         Some(template.into()),
1682                         self,
1683                     );
1684                     args.push(ty);
1685                 }
1686                 clang_sys::CXCursor_TemplateRef => {
1687                     let (
1688                         template_decl_cursor,
1689                         template_decl_id,
1690                         num_expected_template_args,
1691                     ) = self.get_declaration_info_for_template_instantiation(
1692                         child,
1693                     )?;
1694 
1695                     if num_expected_template_args == 0 ||
1696                         child.has_at_least_num_children(
1697                             num_expected_template_args,
1698                         )
1699                     {
1700                         // Do a happy little parse. See comment in the TypeRef
1701                         // match arm about parent IDs.
1702                         let ty = Item::from_ty_or_ref(
1703                             child.cur_type(),
1704                             *child,
1705                             Some(template.into()),
1706                             self,
1707                         );
1708                         args.push(ty);
1709                     } else {
1710                         // This is the case mentioned in the doc comment where
1711                         // clang gives us a flattened AST and we have to
1712                         // reconstruct which template arguments go to which
1713                         // instantiation :(
1714                         let args_len = args.len();
1715                         if args_len < num_expected_template_args {
1716                             warn!(
1717                                 "Found a template instantiation without \
1718                                  enough template arguments"
1719                             );
1720                             return None;
1721                         }
1722 
1723                         let mut sub_args: Vec<_> = args
1724                             .drain(args_len - num_expected_template_args..)
1725                             .collect();
1726                         sub_args.reverse();
1727 
1728                         let sub_name = Some(template_decl_cursor.spelling());
1729                         let sub_inst = TemplateInstantiation::new(
1730                             // This isn't guaranteed to be a type that we've
1731                             // already finished parsing yet.
1732                             template_decl_id.as_type_id_unchecked(),
1733                             sub_args,
1734                         );
1735                         let sub_kind =
1736                             TypeKind::TemplateInstantiation(sub_inst);
1737                         let sub_ty = Type::new(
1738                             sub_name,
1739                             template_decl_cursor
1740                                 .cur_type()
1741                                 .fallible_layout(self)
1742                                 .ok(),
1743                             sub_kind,
1744                             false,
1745                         );
1746                         let sub_id = self.next_item_id();
1747                         let sub_item = Item::new(
1748                             sub_id,
1749                             None,
1750                             None,
1751                             self.current_module.into(),
1752                             ItemKind::Type(sub_ty),
1753                         );
1754 
1755                         // Bypass all the validations in add_item explicitly.
1756                         debug!(
1757                             "instantiate_template: inserting nested \
1758                              instantiation item: {:?}",
1759                             sub_item
1760                         );
1761                         self.add_item_to_module(&sub_item);
1762                         debug_assert_eq!(sub_id, sub_item.id());
1763                         self.items[sub_id.0] = Some(sub_item);
1764                         args.push(sub_id.as_type_id_unchecked());
1765                     }
1766                 }
1767                 _ => {
1768                     warn!(
1769                         "Found template arg cursor we can't handle: {:?}",
1770                         child
1771                     );
1772                     found_const_arg = true;
1773                 }
1774             }
1775         }
1776 
1777         if found_const_arg {
1778             // This is a dependently typed template instantiation. That is, an
1779             // instantiation of a template with one or more const values as
1780             // template arguments, rather than only types as template
1781             // arguments. For example, `Foo<true, 5>` versus `Bar<bool, int>`.
1782             // We can't handle these instantiations, so just punt in this
1783             // situation...
1784             warn!(
1785                 "Found template instantiated with a const value; \
1786                  bindgen can't handle this kind of template instantiation!"
1787             );
1788             return None;
1789         }
1790 
1791         if args.len() != num_expected_args {
1792             warn!(
1793                 "Found a template with an unexpected number of template \
1794                  arguments"
1795             );
1796             return None;
1797         }
1798 
1799         args.reverse();
1800         let type_kind = TypeKind::TemplateInstantiation(
1801             TemplateInstantiation::new(template, args),
1802         );
1803         let name = ty.spelling();
1804         let name = if name.is_empty() { None } else { Some(name) };
1805         let ty = Type::new(
1806             name,
1807             ty.fallible_layout(self).ok(),
1808             type_kind,
1809             ty.is_const(),
1810         );
1811         let item = Item::new(
1812             with_id,
1813             None,
1814             None,
1815             self.current_module.into(),
1816             ItemKind::Type(ty),
1817         );
1818 
1819         // Bypass all the validations in add_item explicitly.
1820         debug!("instantiate_template: inserting item: {:?}", item);
1821         self.add_item_to_module(&item);
1822         debug_assert_eq!(with_id, item.id());
1823         self.items[with_id.0] = Some(item);
1824         Some(with_id.as_type_id_unchecked())
1825     }
1826 
1827     /// If we have already resolved the type for the given type declaration,
1828     /// return its `ItemId`. Otherwise, return `None`.
get_resolved_type( &self, decl: &clang::CanonicalTypeDeclaration, ) -> Option<TypeId>1829     pub fn get_resolved_type(
1830         &self,
1831         decl: &clang::CanonicalTypeDeclaration,
1832     ) -> Option<TypeId> {
1833         self.types
1834             .get(&TypeKey::Declaration(*decl.cursor()))
1835             .or_else(|| {
1836                 decl.cursor()
1837                     .usr()
1838                     .and_then(|usr| self.types.get(&TypeKey::USR(usr)))
1839             })
1840             .cloned()
1841     }
1842 
1843     /// Looks up for an already resolved type, either because it's builtin, or
1844     /// because we already have it in the map.
builtin_or_resolved_ty( &mut self, with_id: ItemId, parent_id: Option<ItemId>, ty: &clang::Type, location: Option<clang::Cursor>, ) -> Option<TypeId>1845     pub fn builtin_or_resolved_ty(
1846         &mut self,
1847         with_id: ItemId,
1848         parent_id: Option<ItemId>,
1849         ty: &clang::Type,
1850         location: Option<clang::Cursor>,
1851     ) -> Option<TypeId> {
1852         use clang_sys::{CXCursor_TypeAliasTemplateDecl, CXCursor_TypeRef};
1853         debug!(
1854             "builtin_or_resolved_ty: {:?}, {:?}, {:?}",
1855             ty, location, parent_id
1856         );
1857 
1858         if let Some(decl) = ty.canonical_declaration(location.as_ref()) {
1859             if let Some(id) = self.get_resolved_type(&decl) {
1860                 debug!(
1861                     "Already resolved ty {:?}, {:?}, {:?} {:?}",
1862                     id, decl, ty, location
1863                 );
1864                 // If the declaration already exists, then either:
1865                 //
1866                 //   * the declaration is a template declaration of some sort,
1867                 //     and we are looking at an instantiation or specialization
1868                 //     of it, or
1869                 //   * we have already parsed and resolved this type, and
1870                 //     there's nothing left to do.
1871                 if decl.cursor().is_template_like() &&
1872                     *ty != decl.cursor().cur_type() &&
1873                     location.is_some()
1874                 {
1875                     let location = location.unwrap();
1876 
1877                     // For specialized type aliases, there's no way to get the
1878                     // template parameters as of this writing (for a struct
1879                     // specialization we wouldn't be in this branch anyway).
1880                     //
1881                     // Explicitly return `None` if there aren't any
1882                     // unspecialized parameters (contains any `TypeRef`) so we
1883                     // resolve the canonical type if there is one and it's
1884                     // exposed.
1885                     //
1886                     // This is _tricky_, I know :(
1887                     if decl.cursor().kind() == CXCursor_TypeAliasTemplateDecl &&
1888                         !location.contains_cursor(CXCursor_TypeRef) &&
1889                         ty.canonical_type().is_valid_and_exposed()
1890                     {
1891                         return None;
1892                     }
1893 
1894                     return self
1895                         .instantiate_template(with_id, id, ty, location)
1896                         .or_else(|| Some(id));
1897                 }
1898 
1899                 return Some(self.build_ty_wrapper(with_id, id, parent_id, ty));
1900             }
1901         }
1902 
1903         debug!("Not resolved, maybe builtin?");
1904         self.build_builtin_ty(ty)
1905     }
1906 
1907     /// Make a new item that is a resolved type reference to the `wrapped_id`.
1908     ///
1909     /// This is unfortunately a lot of bloat, but is needed to properly track
1910     /// constness et al.
1911     ///
1912     /// We should probably make the constness tracking separate, so it doesn't
1913     /// bloat that much, but hey, we already bloat the heck out of builtin
1914     /// types.
build_ty_wrapper( &mut self, with_id: ItemId, wrapped_id: TypeId, parent_id: Option<ItemId>, ty: &clang::Type, ) -> TypeId1915     pub fn build_ty_wrapper(
1916         &mut self,
1917         with_id: ItemId,
1918         wrapped_id: TypeId,
1919         parent_id: Option<ItemId>,
1920         ty: &clang::Type,
1921     ) -> TypeId {
1922         self.build_wrapper(with_id, wrapped_id, parent_id, ty, ty.is_const())
1923     }
1924 
1925     /// A wrapper over a type that adds a const qualifier explicitly.
1926     ///
1927     /// Needed to handle const methods in C++, wrapping the type .
build_const_wrapper( &mut self, with_id: ItemId, wrapped_id: TypeId, parent_id: Option<ItemId>, ty: &clang::Type, ) -> TypeId1928     pub fn build_const_wrapper(
1929         &mut self,
1930         with_id: ItemId,
1931         wrapped_id: TypeId,
1932         parent_id: Option<ItemId>,
1933         ty: &clang::Type,
1934     ) -> TypeId {
1935         self.build_wrapper(
1936             with_id, wrapped_id, parent_id, ty, /* is_const = */ true,
1937         )
1938     }
1939 
build_wrapper( &mut self, with_id: ItemId, wrapped_id: TypeId, parent_id: Option<ItemId>, ty: &clang::Type, is_const: bool, ) -> TypeId1940     fn build_wrapper(
1941         &mut self,
1942         with_id: ItemId,
1943         wrapped_id: TypeId,
1944         parent_id: Option<ItemId>,
1945         ty: &clang::Type,
1946         is_const: bool,
1947     ) -> TypeId {
1948         let spelling = ty.spelling();
1949         let layout = ty.fallible_layout(self).ok();
1950         let type_kind = TypeKind::ResolvedTypeRef(wrapped_id);
1951         let ty = Type::new(Some(spelling), layout, type_kind, is_const);
1952         let item = Item::new(
1953             with_id,
1954             None,
1955             None,
1956             parent_id.unwrap_or(self.current_module.into()),
1957             ItemKind::Type(ty),
1958         );
1959         self.add_builtin_item(item);
1960         with_id.as_type_id_unchecked()
1961     }
1962 
1963     /// Returns the next item id to be used for an item.
next_item_id(&mut self) -> ItemId1964     pub fn next_item_id(&mut self) -> ItemId {
1965         let ret = ItemId(self.items.len());
1966         self.items.push(None);
1967         ret
1968     }
1969 
build_builtin_ty(&mut self, ty: &clang::Type) -> Option<TypeId>1970     fn build_builtin_ty(&mut self, ty: &clang::Type) -> Option<TypeId> {
1971         use clang_sys::*;
1972         let type_kind = match ty.kind() {
1973             CXType_NullPtr => TypeKind::NullPtr,
1974             CXType_Void => TypeKind::Void,
1975             CXType_Bool => TypeKind::Int(IntKind::Bool),
1976             CXType_Int => TypeKind::Int(IntKind::Int),
1977             CXType_UInt => TypeKind::Int(IntKind::UInt),
1978             CXType_Char_S => TypeKind::Int(IntKind::Char { is_signed: true }),
1979             CXType_Char_U => TypeKind::Int(IntKind::Char { is_signed: false }),
1980             CXType_SChar => TypeKind::Int(IntKind::SChar),
1981             CXType_UChar => TypeKind::Int(IntKind::UChar),
1982             CXType_Short => TypeKind::Int(IntKind::Short),
1983             CXType_UShort => TypeKind::Int(IntKind::UShort),
1984             CXType_WChar => TypeKind::Int(IntKind::WChar),
1985             CXType_Char16 => TypeKind::Int(IntKind::U16),
1986             CXType_Char32 => TypeKind::Int(IntKind::U32),
1987             CXType_Long => TypeKind::Int(IntKind::Long),
1988             CXType_ULong => TypeKind::Int(IntKind::ULong),
1989             CXType_LongLong => TypeKind::Int(IntKind::LongLong),
1990             CXType_ULongLong => TypeKind::Int(IntKind::ULongLong),
1991             CXType_Int128 => TypeKind::Int(IntKind::I128),
1992             CXType_UInt128 => TypeKind::Int(IntKind::U128),
1993             CXType_Float => TypeKind::Float(FloatKind::Float),
1994             CXType_Double => TypeKind::Float(FloatKind::Double),
1995             CXType_LongDouble => TypeKind::Float(FloatKind::LongDouble),
1996             CXType_Float128 => TypeKind::Float(FloatKind::Float128),
1997             CXType_Complex => {
1998                 let float_type =
1999                     ty.elem_type().expect("Not able to resolve complex type?");
2000                 let float_kind = match float_type.kind() {
2001                     CXType_Float => FloatKind::Float,
2002                     CXType_Double => FloatKind::Double,
2003                     CXType_LongDouble => FloatKind::LongDouble,
2004                     CXType_Float128 => FloatKind::Float128,
2005                     _ => panic!(
2006                         "Non floating-type complex? {:?}, {:?}",
2007                         ty, float_type,
2008                     ),
2009                 };
2010                 TypeKind::Complex(float_kind)
2011             }
2012             _ => return None,
2013         };
2014 
2015         let spelling = ty.spelling();
2016         let is_const = ty.is_const();
2017         let layout = ty.fallible_layout(self).ok();
2018         let ty = Type::new(Some(spelling), layout, type_kind, is_const);
2019         let id = self.next_item_id();
2020         let item = Item::new(
2021             id,
2022             None,
2023             None,
2024             self.root_module.into(),
2025             ItemKind::Type(ty),
2026         );
2027         self.add_builtin_item(item);
2028         Some(id.as_type_id_unchecked())
2029     }
2030 
2031     /// Get the current Clang translation unit that is being processed.
translation_unit(&self) -> &clang::TranslationUnit2032     pub fn translation_unit(&self) -> &clang::TranslationUnit {
2033         &self.translation_unit
2034     }
2035 
2036     /// Have we parsed the macro named `macro_name` already?
parsed_macro(&self, macro_name: &[u8]) -> bool2037     pub fn parsed_macro(&self, macro_name: &[u8]) -> bool {
2038         self.parsed_macros.contains_key(macro_name)
2039     }
2040 
2041     /// Get the currently parsed macros.
parsed_macros( &self, ) -> &StdHashMap<Vec<u8>, cexpr::expr::EvalResult>2042     pub fn parsed_macros(
2043         &self,
2044     ) -> &StdHashMap<Vec<u8>, cexpr::expr::EvalResult> {
2045         debug_assert!(!self.in_codegen_phase());
2046         &self.parsed_macros
2047     }
2048 
2049     /// Mark the macro named `macro_name` as parsed.
note_parsed_macro( &mut self, id: Vec<u8>, value: cexpr::expr::EvalResult, )2050     pub fn note_parsed_macro(
2051         &mut self,
2052         id: Vec<u8>,
2053         value: cexpr::expr::EvalResult,
2054     ) {
2055         self.parsed_macros.insert(id, value);
2056     }
2057 
2058     /// Are we in the codegen phase?
in_codegen_phase(&self) -> bool2059     pub fn in_codegen_phase(&self) -> bool {
2060         self.in_codegen
2061     }
2062 
2063     /// Mark the type with the given `name` as replaced by the type with id
2064     /// `potential_ty`.
2065     ///
2066     /// Replacement types are declared using the `replaces="xxx"` annotation,
2067     /// and implies that the original type is hidden.
replace(&mut self, name: &[String], potential_ty: ItemId)2068     pub fn replace(&mut self, name: &[String], potential_ty: ItemId) {
2069         match self.replacements.entry(name.into()) {
2070             Entry::Vacant(entry) => {
2071                 debug!(
2072                     "Defining replacement for {:?} as {:?}",
2073                     name, potential_ty
2074                 );
2075                 entry.insert(potential_ty);
2076             }
2077             Entry::Occupied(occupied) => {
2078                 warn!(
2079                     "Replacement for {:?} already defined as {:?}; \
2080                      ignoring duplicate replacement definition as {:?}",
2081                     name,
2082                     occupied.get(),
2083                     potential_ty
2084                 );
2085             }
2086         }
2087     }
2088 
2089     /// Has the item with the given `name` and `id` been replaced by another
2090     /// type?
is_replaced_type<Id: Into<ItemId>>( &self, path: &[String], id: Id, ) -> bool2091     pub fn is_replaced_type<Id: Into<ItemId>>(
2092         &self,
2093         path: &[String],
2094         id: Id,
2095     ) -> bool {
2096         let id = id.into();
2097         match self.replacements.get(path) {
2098             Some(replaced_by) if *replaced_by != id => true,
2099             _ => false,
2100         }
2101     }
2102 
2103     /// Is the type with the given `name` marked as opaque?
opaque_by_name(&self, path: &[String]) -> bool2104     pub fn opaque_by_name(&self, path: &[String]) -> bool {
2105         debug_assert!(
2106             self.in_codegen_phase(),
2107             "You're not supposed to call this yet"
2108         );
2109         self.options.opaque_types.matches(&path[1..].join("::"))
2110     }
2111 
2112     /// Get the options used to configure this bindgen context.
options(&self) -> &BindgenOptions2113     pub(crate) fn options(&self) -> &BindgenOptions {
2114         &self.options
2115     }
2116 
2117     /// Tokenizes a namespace cursor in order to get the name and kind of the
2118     /// namespace.
tokenize_namespace( &self, cursor: &clang::Cursor, ) -> (Option<String>, ModuleKind)2119     fn tokenize_namespace(
2120         &self,
2121         cursor: &clang::Cursor,
2122     ) -> (Option<String>, ModuleKind) {
2123         assert_eq!(
2124             cursor.kind(),
2125             ::clang_sys::CXCursor_Namespace,
2126             "Be a nice person"
2127         );
2128 
2129         let mut module_name = None;
2130         let spelling = cursor.spelling();
2131         if !spelling.is_empty() {
2132             module_name = Some(spelling)
2133         }
2134 
2135         let tokens = cursor.tokens();
2136         let mut iter = tokens.iter();
2137         let mut kind = ModuleKind::Normal;
2138         let mut found_namespace_keyword = false;
2139         while let Some(token) = iter.next() {
2140             match token.spelling() {
2141                 b"inline" => {
2142                     assert!(!found_namespace_keyword);
2143                     assert!(kind != ModuleKind::Inline);
2144                     kind = ModuleKind::Inline;
2145                 }
2146                 // The double colon allows us to handle nested namespaces like
2147                 // namespace foo::bar { }
2148                 //
2149                 // libclang still gives us two namespace cursors, which is cool,
2150                 // but the tokenization of the second begins with the double
2151                 // colon. That's ok, so we only need to handle the weird
2152                 // tokenization here.
2153                 //
2154                 // Fortunately enough, inline nested namespace specifiers aren't
2155                 // a thing, and are invalid C++ :)
2156                 b"namespace" | b"::" => {
2157                     found_namespace_keyword = true;
2158                 }
2159                 b"{" => {
2160                     assert!(found_namespace_keyword);
2161                     break;
2162                 }
2163                 name if found_namespace_keyword => {
2164                     if module_name.is_none() {
2165                         module_name =
2166                             Some(String::from_utf8_lossy(name).into_owned());
2167                     }
2168                     break;
2169                 }
2170                 spelling if !found_namespace_keyword => {
2171                     // This is _likely_, but not certainly, a macro that's been placed just before
2172                     // the namespace keyword. Unfortunately, clang tokens don't let us easily see
2173                     // through the ifdef tokens, so we don't know what this token should really be.
2174                     // Instead of panicking though, we warn the user that we assumed the token was
2175                     // blank, and then move on.
2176                     //
2177                     // See also https://github.com/rust-lang/rust-bindgen/issues/1676.
2178                     warn!(
2179                         "Ignored unknown namespace prefix '{}' at {:?} in {:?}",
2180                         String::from_utf8_lossy(spelling),
2181                         token,
2182                         cursor
2183                     );
2184                 }
2185                 spelling => {
2186                     panic!(
2187                         "Unknown token '{}' while processing namespace at {:?} in {:?}",
2188                         String::from_utf8_lossy(spelling),
2189                         token,
2190                         cursor
2191                     );
2192                 }
2193             }
2194         }
2195 
2196         (module_name, kind)
2197     }
2198 
2199     /// Given a CXCursor_Namespace cursor, return the item id of the
2200     /// corresponding module, or create one on the fly.
module(&mut self, cursor: clang::Cursor) -> ModuleId2201     pub fn module(&mut self, cursor: clang::Cursor) -> ModuleId {
2202         use clang_sys::*;
2203         assert_eq!(cursor.kind(), CXCursor_Namespace, "Be a nice person");
2204         let cursor = cursor.canonical();
2205         if let Some(id) = self.modules.get(&cursor) {
2206             return *id;
2207         }
2208 
2209         let (module_name, kind) = self.tokenize_namespace(&cursor);
2210 
2211         let module_id = self.next_item_id();
2212         let module = Module::new(module_name, kind);
2213         let module = Item::new(
2214             module_id,
2215             None,
2216             None,
2217             self.current_module.into(),
2218             ItemKind::Module(module),
2219         );
2220 
2221         let module_id = module.id().as_module_id_unchecked();
2222         self.modules.insert(cursor, module_id);
2223 
2224         self.add_item(module, None, None);
2225 
2226         module_id
2227     }
2228 
2229     /// Start traversing the module with the given `module_id`, invoke the
2230     /// callback `cb`, and then return to traversing the original module.
with_module<F>(&mut self, module_id: ModuleId, cb: F) where F: FnOnce(&mut Self),2231     pub fn with_module<F>(&mut self, module_id: ModuleId, cb: F)
2232     where
2233         F: FnOnce(&mut Self),
2234     {
2235         debug_assert!(self.resolve_item(module_id).kind().is_module(), "Wat");
2236 
2237         let previous_id = self.current_module;
2238         self.current_module = module_id;
2239 
2240         cb(self);
2241 
2242         self.current_module = previous_id;
2243     }
2244 
2245     /// Iterate over all (explicitly or transitively) whitelisted items.
2246     ///
2247     /// If no items are explicitly whitelisted, then all items are considered
2248     /// whitelisted.
whitelisted_items(&self) -> &ItemSet2249     pub fn whitelisted_items(&self) -> &ItemSet {
2250         assert!(self.in_codegen_phase());
2251         assert!(self.current_module == self.root_module);
2252 
2253         self.whitelisted.as_ref().unwrap()
2254     }
2255 
2256     /// Get a reference to the set of items we should generate.
codegen_items(&self) -> &ItemSet2257     pub fn codegen_items(&self) -> &ItemSet {
2258         assert!(self.in_codegen_phase());
2259         assert!(self.current_module == self.root_module);
2260         self.codegen_items.as_ref().unwrap()
2261     }
2262 
2263     /// Compute the whitelisted items set and populate `self.whitelisted`.
compute_whitelisted_and_codegen_items(&mut self)2264     fn compute_whitelisted_and_codegen_items(&mut self) {
2265         assert!(self.in_codegen_phase());
2266         assert!(self.current_module == self.root_module);
2267         assert!(self.whitelisted.is_none());
2268         let _t = self.timer("compute_whitelisted_and_codegen_items");
2269 
2270         let roots = {
2271             let mut roots = self
2272                 .items()
2273                 // Only consider roots that are enabled for codegen.
2274                 .filter(|&(_, item)| item.is_enabled_for_codegen(self))
2275                 .filter(|&(_, item)| {
2276                     // If nothing is explicitly whitelisted, then everything is fair
2277                     // game.
2278                     if self.options().whitelisted_types.is_empty() &&
2279                         self.options().whitelisted_functions.is_empty() &&
2280                         self.options().whitelisted_vars.is_empty()
2281                     {
2282                         return true;
2283                     }
2284 
2285                     // If this is a type that explicitly replaces another, we assume
2286                     // you know what you're doing.
2287                     if item.annotations().use_instead_of().is_some() {
2288                         return true;
2289                     }
2290 
2291                     let name = item.path_for_whitelisting(self)[1..].join("::");
2292                     debug!("whitelisted_items: testing {:?}", name);
2293                     match *item.kind() {
2294                         ItemKind::Module(..) => true,
2295                         ItemKind::Function(_) => {
2296                             self.options().whitelisted_functions.matches(&name)
2297                         }
2298                         ItemKind::Var(_) => {
2299                             self.options().whitelisted_vars.matches(&name)
2300                         }
2301                         ItemKind::Type(ref ty) => {
2302                             if self.options().whitelisted_types.matches(&name) {
2303                                 return true;
2304                             }
2305 
2306                             // Auto-whitelist types that don't need code
2307                             // generation if not whitelisting recursively, to
2308                             // make the #[derive] analysis not be lame.
2309                             if !self.options().whitelist_recursively {
2310                                 match *ty.kind() {
2311                                     TypeKind::Void |
2312                                     TypeKind::NullPtr |
2313                                     TypeKind::Int(..) |
2314                                     TypeKind::Float(..) |
2315                                     TypeKind::Complex(..) |
2316                                     TypeKind::Array(..) |
2317                                     TypeKind::Vector(..) |
2318                                     TypeKind::Pointer(..) |
2319                                     TypeKind::Reference(..) |
2320                                     TypeKind::Function(..) |
2321                                     TypeKind::ResolvedTypeRef(..) |
2322                                     TypeKind::Opaque |
2323                                     TypeKind::TypeParam => return true,
2324                                     _ => {}
2325                                 };
2326                             }
2327 
2328                             // Unnamed top-level enums are special and we
2329                             // whitelist them via the `whitelisted_vars` filter,
2330                             // since they're effectively top-level constants,
2331                             // and there's no way for them to be referenced
2332                             // consistently.
2333                             let parent = self.resolve_item(item.parent_id());
2334                             if !parent.is_module() {
2335                                 return false;
2336                             }
2337 
2338                             let enum_ = match *ty.kind() {
2339                                 TypeKind::Enum(ref e) => e,
2340                                 _ => return false,
2341                             };
2342 
2343                             if ty.name().is_some() {
2344                                 return false;
2345                             }
2346 
2347                             let mut prefix_path =
2348                                 parent.path_for_whitelisting(self).clone();
2349                             enum_.variants().iter().any(|variant| {
2350                                 prefix_path.push(variant.name().into());
2351                                 let name = prefix_path[1..].join("::");
2352                                 prefix_path.pop().unwrap();
2353                                 self.options().whitelisted_vars.matches(&name)
2354                             })
2355                         }
2356                     }
2357                 })
2358                 .map(|(id, _)| id)
2359                 .collect::<Vec<_>>();
2360 
2361             // The reversal preserves the expected ordering of traversal,
2362             // resulting in more stable-ish bindgen-generated names for
2363             // anonymous types (like unions).
2364             roots.reverse();
2365             roots
2366         };
2367 
2368         let whitelisted_items_predicate =
2369             if self.options().whitelist_recursively {
2370                 traversal::all_edges
2371             } else {
2372                 // Only follow InnerType edges from the whitelisted roots.
2373                 // Such inner types (e.g. anonymous structs/unions) are
2374                 // always emitted by codegen, and they need to be whitelisted
2375                 // to make sure they are processed by e.g. the derive analysis.
2376                 traversal::only_inner_type_edges
2377             };
2378 
2379         let whitelisted = WhitelistedItemsTraversal::new(
2380             self,
2381             roots.clone(),
2382             whitelisted_items_predicate,
2383         )
2384         .collect::<ItemSet>();
2385 
2386         let codegen_items = if self.options().whitelist_recursively {
2387             WhitelistedItemsTraversal::new(
2388                 self,
2389                 roots.clone(),
2390                 traversal::codegen_edges,
2391             )
2392             .collect::<ItemSet>()
2393         } else {
2394             whitelisted.clone()
2395         };
2396 
2397         self.whitelisted = Some(whitelisted);
2398         self.codegen_items = Some(codegen_items);
2399 
2400         for item in self.options().whitelisted_functions.unmatched_items() {
2401             error!("unused option: --whitelist-function {}", item);
2402         }
2403 
2404         for item in self.options().whitelisted_vars.unmatched_items() {
2405             error!("unused option: --whitelist-var {}", item);
2406         }
2407 
2408         for item in self.options().whitelisted_types.unmatched_items() {
2409             error!("unused option: --whitelist-type {}", item);
2410         }
2411     }
2412 
2413     /// Convenient method for getting the prefix to use for most traits in
2414     /// codegen depending on the `use_core` option.
trait_prefix(&self) -> Ident2415     pub fn trait_prefix(&self) -> Ident {
2416         if self.options().use_core {
2417             self.rust_ident_raw("core")
2418         } else {
2419             self.rust_ident_raw("std")
2420         }
2421     }
2422 
2423     /// Call if a bindgen complex is generated
generated_bindgen_complex(&self)2424     pub fn generated_bindgen_complex(&self) {
2425         self.generated_bindgen_complex.set(true)
2426     }
2427 
2428     /// Whether we need to generate the bindgen complex type
need_bindgen_complex_type(&self) -> bool2429     pub fn need_bindgen_complex_type(&self) -> bool {
2430         self.generated_bindgen_complex.get()
2431     }
2432 
2433     /// Compute whether we can derive debug.
compute_cannot_derive_debug(&mut self)2434     fn compute_cannot_derive_debug(&mut self) {
2435         let _t = self.timer("compute_cannot_derive_debug");
2436         assert!(self.cannot_derive_debug.is_none());
2437         if self.options.derive_debug {
2438             self.cannot_derive_debug =
2439                 Some(as_cannot_derive_set(analyze::<CannotDerive>((
2440                     self,
2441                     DeriveTrait::Debug,
2442                 ))));
2443         }
2444     }
2445 
2446     /// Look up whether the item with `id` can
2447     /// derive debug or not.
lookup_can_derive_debug<Id: Into<ItemId>>(&self, id: Id) -> bool2448     pub fn lookup_can_derive_debug<Id: Into<ItemId>>(&self, id: Id) -> bool {
2449         let id = id.into();
2450         assert!(
2451             self.in_codegen_phase(),
2452             "We only compute can_derive_debug when we enter codegen"
2453         );
2454 
2455         // Look up the computed value for whether the item with `id` can
2456         // derive debug or not.
2457         !self.cannot_derive_debug.as_ref().unwrap().contains(&id)
2458     }
2459 
2460     /// Compute whether we can derive default.
compute_cannot_derive_default(&mut self)2461     fn compute_cannot_derive_default(&mut self) {
2462         let _t = self.timer("compute_cannot_derive_default");
2463         assert!(self.cannot_derive_default.is_none());
2464         if self.options.derive_default {
2465             self.cannot_derive_default =
2466                 Some(as_cannot_derive_set(analyze::<CannotDerive>((
2467                     self,
2468                     DeriveTrait::Default,
2469                 ))));
2470         }
2471     }
2472 
2473     /// Look up whether the item with `id` can
2474     /// derive default or not.
lookup_can_derive_default<Id: Into<ItemId>>(&self, id: Id) -> bool2475     pub fn lookup_can_derive_default<Id: Into<ItemId>>(&self, id: Id) -> bool {
2476         let id = id.into();
2477         assert!(
2478             self.in_codegen_phase(),
2479             "We only compute can_derive_default when we enter codegen"
2480         );
2481 
2482         // Look up the computed value for whether the item with `id` can
2483         // derive default or not.
2484         !self.cannot_derive_default.as_ref().unwrap().contains(&id)
2485     }
2486 
2487     /// Compute whether we can derive copy.
compute_cannot_derive_copy(&mut self)2488     fn compute_cannot_derive_copy(&mut self) {
2489         let _t = self.timer("compute_cannot_derive_copy");
2490         assert!(self.cannot_derive_copy.is_none());
2491         self.cannot_derive_copy =
2492             Some(as_cannot_derive_set(analyze::<CannotDerive>((
2493                 self,
2494                 DeriveTrait::Copy,
2495             ))));
2496     }
2497 
2498     /// Compute whether we can derive hash.
compute_cannot_derive_hash(&mut self)2499     fn compute_cannot_derive_hash(&mut self) {
2500         let _t = self.timer("compute_cannot_derive_hash");
2501         assert!(self.cannot_derive_hash.is_none());
2502         if self.options.derive_hash {
2503             self.cannot_derive_hash =
2504                 Some(as_cannot_derive_set(analyze::<CannotDerive>((
2505                     self,
2506                     DeriveTrait::Hash,
2507                 ))));
2508         }
2509     }
2510 
2511     /// Look up whether the item with `id` can
2512     /// derive hash or not.
lookup_can_derive_hash<Id: Into<ItemId>>(&self, id: Id) -> bool2513     pub fn lookup_can_derive_hash<Id: Into<ItemId>>(&self, id: Id) -> bool {
2514         let id = id.into();
2515         assert!(
2516             self.in_codegen_phase(),
2517             "We only compute can_derive_debug when we enter codegen"
2518         );
2519 
2520         // Look up the computed value for whether the item with `id` can
2521         // derive hash or not.
2522         !self.cannot_derive_hash.as_ref().unwrap().contains(&id)
2523     }
2524 
2525     /// Compute whether we can derive PartialOrd, PartialEq or Eq.
compute_cannot_derive_partialord_partialeq_or_eq(&mut self)2526     fn compute_cannot_derive_partialord_partialeq_or_eq(&mut self) {
2527         let _t = self.timer("compute_cannot_derive_partialord_partialeq_or_eq");
2528         assert!(self.cannot_derive_partialeq_or_partialord.is_none());
2529         if self.options.derive_partialord ||
2530             self.options.derive_partialeq ||
2531             self.options.derive_eq
2532         {
2533             self.cannot_derive_partialeq_or_partialord =
2534                 Some(analyze::<CannotDerive>((
2535                     self,
2536                     DeriveTrait::PartialEqOrPartialOrd,
2537                 )));
2538         }
2539     }
2540 
2541     /// Look up whether the item with `id` can derive `Partial{Eq,Ord}`.
lookup_can_derive_partialeq_or_partialord<Id: Into<ItemId>>( &self, id: Id, ) -> CanDerive2542     pub fn lookup_can_derive_partialeq_or_partialord<Id: Into<ItemId>>(
2543         &self,
2544         id: Id,
2545     ) -> CanDerive {
2546         let id = id.into();
2547         assert!(
2548             self.in_codegen_phase(),
2549             "We only compute can_derive_partialeq_or_partialord when we enter codegen"
2550         );
2551 
2552         // Look up the computed value for whether the item with `id` can
2553         // derive partialeq or not.
2554         self.cannot_derive_partialeq_or_partialord
2555             .as_ref()
2556             .unwrap()
2557             .get(&id)
2558             .cloned()
2559             .unwrap_or(CanDerive::Yes)
2560     }
2561 
2562     /// Look up whether the item with `id` can derive `Copy` or not.
lookup_can_derive_copy<Id: Into<ItemId>>(&self, id: Id) -> bool2563     pub fn lookup_can_derive_copy<Id: Into<ItemId>>(&self, id: Id) -> bool {
2564         assert!(
2565             self.in_codegen_phase(),
2566             "We only compute can_derive_debug when we enter codegen"
2567         );
2568 
2569         // Look up the computed value for whether the item with `id` can
2570         // derive `Copy` or not.
2571         let id = id.into();
2572 
2573         !self.lookup_has_type_param_in_array(id) &&
2574             !self.cannot_derive_copy.as_ref().unwrap().contains(&id)
2575     }
2576 
2577     /// Compute whether the type has type parameter in array.
compute_has_type_param_in_array(&mut self)2578     fn compute_has_type_param_in_array(&mut self) {
2579         let _t = self.timer("compute_has_type_param_in_array");
2580         assert!(self.has_type_param_in_array.is_none());
2581         self.has_type_param_in_array =
2582             Some(analyze::<HasTypeParameterInArray>(self));
2583     }
2584 
2585     /// Look up whether the item with `id` has type parameter in array or not.
lookup_has_type_param_in_array<Id: Into<ItemId>>( &self, id: Id, ) -> bool2586     pub fn lookup_has_type_param_in_array<Id: Into<ItemId>>(
2587         &self,
2588         id: Id,
2589     ) -> bool {
2590         assert!(
2591             self.in_codegen_phase(),
2592             "We only compute has array when we enter codegen"
2593         );
2594 
2595         // Look up the computed value for whether the item with `id` has
2596         // type parameter in array or not.
2597         self.has_type_param_in_array
2598             .as_ref()
2599             .unwrap()
2600             .contains(&id.into())
2601     }
2602 
2603     /// Compute whether the type has float.
compute_has_float(&mut self)2604     fn compute_has_float(&mut self) {
2605         let _t = self.timer("compute_has_float");
2606         assert!(self.has_float.is_none());
2607         if self.options.derive_eq || self.options.derive_ord {
2608             self.has_float = Some(analyze::<HasFloat>(self));
2609         }
2610     }
2611 
2612     /// Look up whether the item with `id` has array or not.
lookup_has_float<Id: Into<ItemId>>(&self, id: Id) -> bool2613     pub fn lookup_has_float<Id: Into<ItemId>>(&self, id: Id) -> bool {
2614         assert!(
2615             self.in_codegen_phase(),
2616             "We only compute has float when we enter codegen"
2617         );
2618 
2619         // Look up the computed value for whether the item with `id` has
2620         // float or not.
2621         self.has_float.as_ref().unwrap().contains(&id.into())
2622     }
2623 
2624     /// Check if `--no-partialeq` flag is enabled for this item.
no_partialeq_by_name(&self, item: &Item) -> bool2625     pub fn no_partialeq_by_name(&self, item: &Item) -> bool {
2626         let name = item.path_for_whitelisting(self)[1..].join("::");
2627         self.options().no_partialeq_types.matches(&name)
2628     }
2629 
2630     /// Check if `--no-copy` flag is enabled for this item.
no_copy_by_name(&self, item: &Item) -> bool2631     pub fn no_copy_by_name(&self, item: &Item) -> bool {
2632         let name = item.path_for_whitelisting(self)[1..].join("::");
2633         self.options().no_copy_types.matches(&name)
2634     }
2635 
2636     /// Check if `--no-hash` flag is enabled for this item.
no_hash_by_name(&self, item: &Item) -> bool2637     pub fn no_hash_by_name(&self, item: &Item) -> bool {
2638         let name = item.path_for_whitelisting(self)[1..].join("::");
2639         self.options().no_hash_types.matches(&name)
2640     }
2641 }
2642 
2643 /// A builder struct for configuring item resolution options.
2644 #[derive(Debug, Copy, Clone)]
2645 pub struct ItemResolver {
2646     id: ItemId,
2647     through_type_refs: bool,
2648     through_type_aliases: bool,
2649 }
2650 
2651 impl ItemId {
2652     /// Create an `ItemResolver` from this item id.
into_resolver(self) -> ItemResolver2653     pub fn into_resolver(self) -> ItemResolver {
2654         self.into()
2655     }
2656 }
2657 
2658 impl<T> From<T> for ItemResolver
2659 where
2660     T: Into<ItemId>,
2661 {
from(id: T) -> ItemResolver2662     fn from(id: T) -> ItemResolver {
2663         ItemResolver::new(id)
2664     }
2665 }
2666 
2667 impl ItemResolver {
2668     /// Construct a new `ItemResolver` from the given id.
new<Id: Into<ItemId>>(id: Id) -> ItemResolver2669     pub fn new<Id: Into<ItemId>>(id: Id) -> ItemResolver {
2670         let id = id.into();
2671         ItemResolver {
2672             id: id,
2673             through_type_refs: false,
2674             through_type_aliases: false,
2675         }
2676     }
2677 
2678     /// Keep resolving through `Type::TypeRef` items.
through_type_refs(mut self) -> ItemResolver2679     pub fn through_type_refs(mut self) -> ItemResolver {
2680         self.through_type_refs = true;
2681         self
2682     }
2683 
2684     /// Keep resolving through `Type::Alias` items.
through_type_aliases(mut self) -> ItemResolver2685     pub fn through_type_aliases(mut self) -> ItemResolver {
2686         self.through_type_aliases = true;
2687         self
2688     }
2689 
2690     /// Finish configuring and perform the actual item resolution.
resolve(self, ctx: &BindgenContext) -> &Item2691     pub fn resolve(self, ctx: &BindgenContext) -> &Item {
2692         assert!(ctx.collected_typerefs());
2693 
2694         let mut id = self.id;
2695         loop {
2696             let item = ctx.resolve_item(id);
2697             let ty_kind = item.as_type().map(|t| t.kind());
2698             match ty_kind {
2699                 Some(&TypeKind::ResolvedTypeRef(next_id))
2700                     if self.through_type_refs =>
2701                 {
2702                     id = next_id.into();
2703                 }
2704                 // We intentionally ignore template aliases here, as they are
2705                 // more complicated, and don't represent a simple renaming of
2706                 // some type.
2707                 Some(&TypeKind::Alias(next_id))
2708                     if self.through_type_aliases =>
2709                 {
2710                     id = next_id.into();
2711                 }
2712                 _ => return item,
2713             }
2714         }
2715     }
2716 }
2717 
2718 /// A type that we are in the middle of parsing.
2719 #[derive(Clone, Copy, Debug, PartialEq, Eq)]
2720 pub struct PartialType {
2721     decl: Cursor,
2722     // Just an ItemId, and not a TypeId, because we haven't finished this type
2723     // yet, so there's still time for things to go wrong.
2724     id: ItemId,
2725 }
2726 
2727 impl PartialType {
2728     /// Construct a new `PartialType`.
new(decl: Cursor, id: ItemId) -> PartialType2729     pub fn new(decl: Cursor, id: ItemId) -> PartialType {
2730         // assert!(decl == decl.canonical());
2731         PartialType { decl: decl, id: id }
2732     }
2733 
2734     /// The cursor pointing to this partial type's declaration location.
decl(&self) -> &Cursor2735     pub fn decl(&self) -> &Cursor {
2736         &self.decl
2737     }
2738 
2739     /// The item ID allocated for this type. This is *NOT* a key for an entry in
2740     /// the context's item set yet!
id(&self) -> ItemId2741     pub fn id(&self) -> ItemId {
2742         self.id
2743     }
2744 }
2745 
2746 impl TemplateParameters for PartialType {
self_template_params(&self, _ctx: &BindgenContext) -> Vec<TypeId>2747     fn self_template_params(&self, _ctx: &BindgenContext) -> Vec<TypeId> {
2748         // Maybe at some point we will eagerly parse named types, but for now we
2749         // don't and this information is unavailable.
2750         vec![]
2751     }
2752 
num_self_template_params(&self, _ctx: &BindgenContext) -> usize2753     fn num_self_template_params(&self, _ctx: &BindgenContext) -> usize {
2754         // Wouldn't it be nice if libclang would reliably give us this
2755         // information‽
2756         match self.decl().kind() {
2757             clang_sys::CXCursor_ClassTemplate |
2758             clang_sys::CXCursor_FunctionTemplate |
2759             clang_sys::CXCursor_TypeAliasTemplateDecl => {
2760                 let mut num_params = 0;
2761                 self.decl().visit(|c| {
2762                     match c.kind() {
2763                         clang_sys::CXCursor_TemplateTypeParameter |
2764                         clang_sys::CXCursor_TemplateTemplateParameter |
2765                         clang_sys::CXCursor_NonTypeTemplateParameter => {
2766                             num_params += 1;
2767                         }
2768                         _ => {}
2769                     };
2770                     clang_sys::CXChildVisit_Continue
2771                 });
2772                 num_params
2773             }
2774             _ => 0,
2775         }
2776     }
2777 }
2778