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