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