1 //! Bindgen's core intermediate representation type.
2 
3 use super::super::codegen::{EnumVariation, CONSTIFIED_ENUM_MODULE_REPR_NAME};
4 use super::analysis::{HasVtable, HasVtableResult, Sizedness, SizednessResult};
5 use super::annotations::Annotations;
6 use super::comment;
7 use super::comp::{CompKind, MethodKind};
8 use super::context::{BindgenContext, ItemId, PartialType, TypeId};
9 use super::derive::{
10     CanDeriveCopy, CanDeriveDebug, CanDeriveDefault, CanDeriveEq,
11     CanDeriveHash, CanDeriveOrd, CanDerivePartialEq, CanDerivePartialOrd,
12 };
13 use super::dot::DotAttributes;
14 use super::function::{Function, FunctionKind};
15 use super::item_kind::ItemKind;
16 use super::layout::Opaque;
17 use super::module::Module;
18 use super::template::{AsTemplateParam, TemplateParameters};
19 use super::traversal::{EdgeKind, Trace, Tracer};
20 use super::ty::{Type, TypeKind};
21 use crate::clang;
22 use crate::parse::{
23     ClangItemParser, ClangSubItemParser, ParseError, ParseResult,
24 };
25 use clang_sys;
26 use lazycell::LazyCell;
27 use regex;
28 use std::cell::Cell;
29 use std::collections::BTreeSet;
30 use std::fmt::Write;
31 use std::io;
32 use std::iter;
33 
34 /// A trait to get the canonical name from an item.
35 ///
36 /// This is the trait that will eventually isolate all the logic related to name
37 /// mangling and that kind of stuff.
38 ///
39 /// This assumes no nested paths, at some point I'll have to make it a more
40 /// complex thing.
41 ///
42 /// This name is required to be safe for Rust, that is, is not expected to
43 /// return any rust keyword from here.
44 pub trait ItemCanonicalName {
45     /// Get the canonical name for this item.
canonical_name(&self, ctx: &BindgenContext) -> String46     fn canonical_name(&self, ctx: &BindgenContext) -> String;
47 }
48 
49 /// The same, but specifies the path that needs to be followed to reach an item.
50 ///
51 /// To contrast with canonical_name, here's an example:
52 ///
53 /// ```c++
54 /// namespace foo {
55 ///     const BAR = 3;
56 /// }
57 /// ```
58 ///
59 /// For bar, the canonical path is `vec!["foo", "BAR"]`, while the canonical
60 /// name is just `"BAR"`.
61 pub trait ItemCanonicalPath {
62     /// Get the namespace-aware canonical path for this item. This means that if
63     /// namespaces are disabled, you'll get a single item, and otherwise you get
64     /// the whole path.
namespace_aware_canonical_path( &self, ctx: &BindgenContext, ) -> Vec<String>65     fn namespace_aware_canonical_path(
66         &self,
67         ctx: &BindgenContext,
68     ) -> Vec<String>;
69 
70     /// Get the canonical path for this item.
canonical_path(&self, ctx: &BindgenContext) -> Vec<String>71     fn canonical_path(&self, ctx: &BindgenContext) -> Vec<String>;
72 }
73 
74 /// A trait for determining if some IR thing is opaque or not.
75 pub trait IsOpaque {
76     /// Extra context the IR thing needs to determine if it is opaque or not.
77     type Extra;
78 
79     /// Returns `true` if the thing is opaque, and `false` otherwise.
80     ///
81     /// May only be called when `ctx` is in the codegen phase.
is_opaque(&self, ctx: &BindgenContext, extra: &Self::Extra) -> bool82     fn is_opaque(&self, ctx: &BindgenContext, extra: &Self::Extra) -> bool;
83 }
84 
85 /// A trait for determining if some IR thing has type parameter in array or not.
86 pub trait HasTypeParamInArray {
87     /// Returns `true` if the thing has Array, and `false` otherwise.
has_type_param_in_array(&self, ctx: &BindgenContext) -> bool88     fn has_type_param_in_array(&self, ctx: &BindgenContext) -> bool;
89 }
90 
91 /// A trait for determining if some IR thing has float or not.
92 pub trait HasFloat {
93     /// Returns `true` if the thing has float, and `false` otherwise.
has_float(&self, ctx: &BindgenContext) -> bool94     fn has_float(&self, ctx: &BindgenContext) -> bool;
95 }
96 
97 /// A trait for iterating over an item and its parents and up its ancestor chain
98 /// up to (but not including) the implicit root module.
99 pub trait ItemAncestors {
100     /// Get an iterable over this item's ancestors.
ancestors<'a>(&self, ctx: &'a BindgenContext) -> ItemAncestorsIter<'a>101     fn ancestors<'a>(&self, ctx: &'a BindgenContext) -> ItemAncestorsIter<'a>;
102 }
103 
104 #[cfg(testing_only_extra_assertions)]
105 type DebugOnlyItemSet = ItemSet;
106 
107 #[cfg(not(testing_only_extra_assertions))]
108 struct DebugOnlyItemSet;
109 
110 #[cfg(not(testing_only_extra_assertions))]
111 impl DebugOnlyItemSet {
new() -> Self112     fn new() -> Self {
113         DebugOnlyItemSet
114     }
115 
contains(&self, _id: &ItemId) -> bool116     fn contains(&self, _id: &ItemId) -> bool {
117         false
118     }
119 
insert(&mut self, _id: ItemId)120     fn insert(&mut self, _id: ItemId) {}
121 }
122 
123 /// An iterator over an item and its ancestors.
124 pub struct ItemAncestorsIter<'a> {
125     item: ItemId,
126     ctx: &'a BindgenContext,
127     seen: DebugOnlyItemSet,
128 }
129 
130 impl<'a> ItemAncestorsIter<'a> {
new<Id: Into<ItemId>>(ctx: &'a BindgenContext, id: Id) -> Self131     fn new<Id: Into<ItemId>>(ctx: &'a BindgenContext, id: Id) -> Self {
132         ItemAncestorsIter {
133             item: id.into(),
134             ctx,
135             seen: DebugOnlyItemSet::new(),
136         }
137     }
138 }
139 
140 impl<'a> Iterator for ItemAncestorsIter<'a> {
141     type Item = ItemId;
142 
next(&mut self) -> Option<Self::Item>143     fn next(&mut self) -> Option<Self::Item> {
144         let item = self.ctx.resolve_item(self.item);
145 
146         if item.parent_id() == self.item {
147             None
148         } else {
149             self.item = item.parent_id();
150 
151             extra_assert!(!self.seen.contains(&item.id()));
152             self.seen.insert(item.id());
153 
154             Some(item.id())
155         }
156     }
157 }
158 
159 impl<T> AsTemplateParam for T
160 where
161     T: Copy + Into<ItemId>,
162 {
163     type Extra = ();
164 
as_template_param( &self, ctx: &BindgenContext, _: &(), ) -> Option<TypeId>165     fn as_template_param(
166         &self,
167         ctx: &BindgenContext,
168         _: &(),
169     ) -> Option<TypeId> {
170         ctx.resolve_item((*self).into()).as_template_param(ctx, &())
171     }
172 }
173 
174 impl AsTemplateParam for Item {
175     type Extra = ();
176 
as_template_param( &self, ctx: &BindgenContext, _: &(), ) -> Option<TypeId>177     fn as_template_param(
178         &self,
179         ctx: &BindgenContext,
180         _: &(),
181     ) -> Option<TypeId> {
182         self.kind.as_template_param(ctx, self)
183     }
184 }
185 
186 impl AsTemplateParam for ItemKind {
187     type Extra = Item;
188 
as_template_param( &self, ctx: &BindgenContext, item: &Item, ) -> Option<TypeId>189     fn as_template_param(
190         &self,
191         ctx: &BindgenContext,
192         item: &Item,
193     ) -> Option<TypeId> {
194         match *self {
195             ItemKind::Type(ref ty) => ty.as_template_param(ctx, item),
196             ItemKind::Module(..) |
197             ItemKind::Function(..) |
198             ItemKind::Var(..) => None,
199         }
200     }
201 }
202 
203 impl<T> ItemCanonicalName for T
204 where
205     T: Copy + Into<ItemId>,
206 {
canonical_name(&self, ctx: &BindgenContext) -> String207     fn canonical_name(&self, ctx: &BindgenContext) -> String {
208         debug_assert!(
209             ctx.in_codegen_phase(),
210             "You're not supposed to call this yet"
211         );
212         ctx.resolve_item(*self).canonical_name(ctx)
213     }
214 }
215 
216 impl<T> ItemCanonicalPath for T
217 where
218     T: Copy + Into<ItemId>,
219 {
namespace_aware_canonical_path( &self, ctx: &BindgenContext, ) -> Vec<String>220     fn namespace_aware_canonical_path(
221         &self,
222         ctx: &BindgenContext,
223     ) -> Vec<String> {
224         debug_assert!(
225             ctx.in_codegen_phase(),
226             "You're not supposed to call this yet"
227         );
228         ctx.resolve_item(*self).namespace_aware_canonical_path(ctx)
229     }
230 
canonical_path(&self, ctx: &BindgenContext) -> Vec<String>231     fn canonical_path(&self, ctx: &BindgenContext) -> Vec<String> {
232         debug_assert!(
233             ctx.in_codegen_phase(),
234             "You're not supposed to call this yet"
235         );
236         ctx.resolve_item(*self).canonical_path(ctx)
237     }
238 }
239 
240 impl<T> ItemAncestors for T
241 where
242     T: Copy + Into<ItemId>,
243 {
ancestors<'a>(&self, ctx: &'a BindgenContext) -> ItemAncestorsIter<'a>244     fn ancestors<'a>(&self, ctx: &'a BindgenContext) -> ItemAncestorsIter<'a> {
245         ItemAncestorsIter::new(ctx, *self)
246     }
247 }
248 
249 impl ItemAncestors for Item {
ancestors<'a>(&self, ctx: &'a BindgenContext) -> ItemAncestorsIter<'a>250     fn ancestors<'a>(&self, ctx: &'a BindgenContext) -> ItemAncestorsIter<'a> {
251         self.id().ancestors(ctx)
252     }
253 }
254 
255 impl<Id> Trace for Id
256 where
257     Id: Copy + Into<ItemId>,
258 {
259     type Extra = ();
260 
trace<T>(&self, ctx: &BindgenContext, tracer: &mut T, extra: &()) where T: Tracer,261     fn trace<T>(&self, ctx: &BindgenContext, tracer: &mut T, extra: &())
262     where
263         T: Tracer,
264     {
265         ctx.resolve_item(*self).trace(ctx, tracer, extra);
266     }
267 }
268 
269 impl Trace for Item {
270     type Extra = ();
271 
trace<T>(&self, ctx: &BindgenContext, tracer: &mut T, _extra: &()) where T: Tracer,272     fn trace<T>(&self, ctx: &BindgenContext, tracer: &mut T, _extra: &())
273     where
274         T: Tracer,
275     {
276         // Even if this item is blocklisted/hidden, we want to trace it. It is
277         // traversal iterators' consumers' responsibility to filter items as
278         // needed. Generally, this filtering happens in the implementation of
279         // `Iterator` for `allowlistedItems`. Fully tracing blocklisted items is
280         // necessary for things like the template parameter usage analysis to
281         // function correctly.
282 
283         match *self.kind() {
284             ItemKind::Type(ref ty) => {
285                 // There are some types, like resolved type references, where we
286                 // don't want to stop collecting types even though they may be
287                 // opaque.
288                 if ty.should_be_traced_unconditionally() ||
289                     !self.is_opaque(ctx, &())
290                 {
291                     ty.trace(ctx, tracer, self);
292                 }
293             }
294             ItemKind::Function(ref fun) => {
295                 // Just the same way, it has not real meaning for a function to
296                 // be opaque, so we trace across it.
297                 tracer.visit(fun.signature().into());
298             }
299             ItemKind::Var(ref var) => {
300                 tracer.visit_kind(var.ty().into(), EdgeKind::VarType);
301             }
302             ItemKind::Module(_) => {
303                 // Module -> children edges are "weak", and we do not want to
304                 // trace them. If we did, then allowlisting wouldn't work as
305                 // expected: everything in every module would end up
306                 // allowlisted.
307                 //
308                 // TODO: make a new edge kind for module -> children edges and
309                 // filter them during allowlisting traversals.
310             }
311         }
312     }
313 }
314 
315 impl CanDeriveDebug for Item {
can_derive_debug(&self, ctx: &BindgenContext) -> bool316     fn can_derive_debug(&self, ctx: &BindgenContext) -> bool {
317         self.id().can_derive_debug(ctx)
318     }
319 }
320 
321 impl CanDeriveDefault for Item {
can_derive_default(&self, ctx: &BindgenContext) -> bool322     fn can_derive_default(&self, ctx: &BindgenContext) -> bool {
323         self.id().can_derive_default(ctx)
324     }
325 }
326 
327 impl CanDeriveCopy for Item {
can_derive_copy(&self, ctx: &BindgenContext) -> bool328     fn can_derive_copy(&self, ctx: &BindgenContext) -> bool {
329         self.id().can_derive_copy(ctx)
330     }
331 }
332 
333 impl CanDeriveHash for Item {
can_derive_hash(&self, ctx: &BindgenContext) -> bool334     fn can_derive_hash(&self, ctx: &BindgenContext) -> bool {
335         self.id().can_derive_hash(ctx)
336     }
337 }
338 
339 impl CanDerivePartialOrd for Item {
can_derive_partialord(&self, ctx: &BindgenContext) -> bool340     fn can_derive_partialord(&self, ctx: &BindgenContext) -> bool {
341         self.id().can_derive_partialord(ctx)
342     }
343 }
344 
345 impl CanDerivePartialEq for Item {
can_derive_partialeq(&self, ctx: &BindgenContext) -> bool346     fn can_derive_partialeq(&self, ctx: &BindgenContext) -> bool {
347         self.id().can_derive_partialeq(ctx)
348     }
349 }
350 
351 impl CanDeriveEq for Item {
can_derive_eq(&self, ctx: &BindgenContext) -> bool352     fn can_derive_eq(&self, ctx: &BindgenContext) -> bool {
353         self.id().can_derive_eq(ctx)
354     }
355 }
356 
357 impl CanDeriveOrd for Item {
can_derive_ord(&self, ctx: &BindgenContext) -> bool358     fn can_derive_ord(&self, ctx: &BindgenContext) -> bool {
359         self.id().can_derive_ord(ctx)
360     }
361 }
362 
363 /// An item is the base of the bindgen representation, it can be either a
364 /// module, a type, a function, or a variable (see `ItemKind` for more
365 /// information).
366 ///
367 /// Items refer to each other by `ItemId`. Every item has its parent's
368 /// id. Depending on the kind of item this is, it may also refer to other items,
369 /// such as a compound type item referring to other types. Collectively, these
370 /// references form a graph.
371 ///
372 /// The entry-point to this graph is the "root module": a meta-item used to hold
373 /// all top-level items.
374 ///
375 /// An item may have a comment, and annotations (see the `annotations` module).
376 ///
377 /// Note that even though we parse all the types of annotations in comments, not
378 /// all of them apply to every item. Those rules are described in the
379 /// `annotations` module.
380 #[derive(Debug)]
381 pub struct Item {
382     /// This item's id.
383     id: ItemId,
384 
385     /// The item's local id, unique only amongst its siblings. Only used for
386     /// anonymous items.
387     ///
388     /// Lazily initialized in local_id().
389     ///
390     /// Note that only structs, unions, and enums get a local type id. In any
391     /// case this is an implementation detail.
392     local_id: LazyCell<usize>,
393 
394     /// The next local id to use for a child or template instantiation.
395     next_child_local_id: Cell<usize>,
396 
397     /// A cached copy of the canonical name, as returned by `canonical_name`.
398     ///
399     /// This is a fairly used operation during codegen so this makes bindgen
400     /// considerably faster in those cases.
401     canonical_name: LazyCell<String>,
402 
403     /// The path to use for allowlisting and other name-based checks, as
404     /// returned by `path_for_allowlisting`, lazily constructed.
405     path_for_allowlisting: LazyCell<Vec<String>>,
406 
407     /// A doc comment over the item, if any.
408     comment: Option<String>,
409     /// Annotations extracted from the doc comment, or the default ones
410     /// otherwise.
411     annotations: Annotations,
412     /// An item's parent id. This will most likely be a class where this item
413     /// was declared, or a module, etc.
414     ///
415     /// All the items have a parent, except the root module, in which case the
416     /// parent id is its own id.
417     parent_id: ItemId,
418     /// The item kind.
419     kind: ItemKind,
420     /// The source location of the item.
421     location: Option<clang::SourceLocation>,
422 }
423 
424 impl AsRef<ItemId> for Item {
as_ref(&self) -> &ItemId425     fn as_ref(&self) -> &ItemId {
426         &self.id
427     }
428 }
429 
430 impl Item {
431     /// Construct a new `Item`.
new( id: ItemId, comment: Option<String>, annotations: Option<Annotations>, parent_id: ItemId, kind: ItemKind, location: Option<clang::SourceLocation>, ) -> Self432     pub fn new(
433         id: ItemId,
434         comment: Option<String>,
435         annotations: Option<Annotations>,
436         parent_id: ItemId,
437         kind: ItemKind,
438         location: Option<clang::SourceLocation>,
439     ) -> Self {
440         debug_assert!(id != parent_id || kind.is_module());
441         Item {
442             id,
443             local_id: LazyCell::new(),
444             next_child_local_id: Cell::new(1),
445             canonical_name: LazyCell::new(),
446             path_for_allowlisting: LazyCell::new(),
447             parent_id,
448             comment,
449             annotations: annotations.unwrap_or_default(),
450             kind,
451             location,
452         }
453     }
454 
455     /// Construct a new opaque item type.
new_opaque_type( with_id: ItemId, ty: &clang::Type, ctx: &mut BindgenContext, ) -> TypeId456     pub fn new_opaque_type(
457         with_id: ItemId,
458         ty: &clang::Type,
459         ctx: &mut BindgenContext,
460     ) -> TypeId {
461         let location = ty.declaration().location();
462         let ty = Opaque::from_clang_ty(ty, ctx);
463         let kind = ItemKind::Type(ty);
464         let parent = ctx.root_module().into();
465         ctx.add_item(
466             Item::new(with_id, None, None, parent, kind, Some(location)),
467             None,
468             None,
469         );
470         with_id.as_type_id_unchecked()
471     }
472 
473     /// Get this `Item`'s identifier.
id(&self) -> ItemId474     pub fn id(&self) -> ItemId {
475         self.id
476     }
477 
478     /// Get this `Item`'s parent's identifier.
479     ///
480     /// For the root module, the parent's ID is its own ID.
parent_id(&self) -> ItemId481     pub fn parent_id(&self) -> ItemId {
482         self.parent_id
483     }
484 
485     /// Set this item's parent id.
486     ///
487     /// This is only used so replacements get generated in the proper module.
set_parent_for_replacement<Id: Into<ItemId>>(&mut self, id: Id)488     pub fn set_parent_for_replacement<Id: Into<ItemId>>(&mut self, id: Id) {
489         self.parent_id = id.into();
490     }
491 
492     /// Returns the depth this item is indented to.
493     ///
494     /// FIXME(emilio): This may need fixes for the enums within modules stuff.
codegen_depth(&self, ctx: &BindgenContext) -> usize495     pub fn codegen_depth(&self, ctx: &BindgenContext) -> usize {
496         if !ctx.options().enable_cxx_namespaces {
497             return 0;
498         }
499 
500         self.ancestors(ctx)
501             .filter(|id| {
502                 ctx.resolve_item(*id).as_module().map_or(false, |module| {
503                     !module.is_inline() ||
504                         ctx.options().conservative_inline_namespaces
505                 })
506             })
507             .count() +
508             1
509     }
510 
511     /// Get this `Item`'s comment, if it has any, already preprocessed and with
512     /// the right indentation.
comment(&self, ctx: &BindgenContext) -> Option<String>513     pub fn comment(&self, ctx: &BindgenContext) -> Option<String> {
514         if !ctx.options().generate_comments {
515             return None;
516         }
517 
518         self.comment.as_ref().map(|comment| {
519             comment::preprocess(comment, self.codegen_depth(ctx))
520         })
521     }
522 
523     /// What kind of item is this?
kind(&self) -> &ItemKind524     pub fn kind(&self) -> &ItemKind {
525         &self.kind
526     }
527 
528     /// Get a mutable reference to this item's kind.
kind_mut(&mut self) -> &mut ItemKind529     pub fn kind_mut(&mut self) -> &mut ItemKind {
530         &mut self.kind
531     }
532 
533     /// Get an identifier that differentiates this item from its siblings.
534     ///
535     /// This should stay relatively stable in the face of code motion outside or
536     /// below this item's lexical scope, meaning that this can be useful for
537     /// generating relatively stable identifiers within a scope.
local_id(&self, ctx: &BindgenContext) -> usize538     pub fn local_id(&self, ctx: &BindgenContext) -> usize {
539         *self.local_id.borrow_with(|| {
540             let parent = ctx.resolve_item(self.parent_id);
541             parent.next_child_local_id()
542         })
543     }
544 
545     /// Get an identifier that differentiates a child of this item of other
546     /// related items.
547     ///
548     /// This is currently used for anonymous items, and template instantiation
549     /// tests, in both cases in order to reduce noise when system headers are at
550     /// place.
next_child_local_id(&self) -> usize551     pub fn next_child_local_id(&self) -> usize {
552         let local_id = self.next_child_local_id.get();
553         self.next_child_local_id.set(local_id + 1);
554         local_id
555     }
556 
557     /// Returns whether this item is a top-level item, from the point of view of
558     /// bindgen.
559     ///
560     /// This point of view changes depending on whether namespaces are enabled
561     /// or not. That way, in the following example:
562     ///
563     /// ```c++
564     /// namespace foo {
565     ///     static int var;
566     /// }
567     /// ```
568     ///
569     /// `var` would be a toplevel item if namespaces are disabled, but won't if
570     /// they aren't.
571     ///
572     /// This function is used to determine when the codegen phase should call
573     /// `codegen` on an item, since any item that is not top-level will be
574     /// generated by its parent.
is_toplevel(&self, ctx: &BindgenContext) -> bool575     pub fn is_toplevel(&self, ctx: &BindgenContext) -> bool {
576         // FIXME: Workaround for some types falling behind when parsing weird
577         // stl classes, for example.
578         if ctx.options().enable_cxx_namespaces &&
579             self.kind().is_module() &&
580             self.id() != ctx.root_module()
581         {
582             return false;
583         }
584 
585         let mut parent = self.parent_id;
586         loop {
587             let parent_item = match ctx.resolve_item_fallible(parent) {
588                 Some(item) => item,
589                 None => return false,
590             };
591 
592             if parent_item.id() == ctx.root_module() {
593                 return true;
594             } else if ctx.options().enable_cxx_namespaces ||
595                 !parent_item.kind().is_module()
596             {
597                 return false;
598             }
599 
600             parent = parent_item.parent_id();
601         }
602     }
603 
604     /// Get a reference to this item's underlying `Type`. Panic if this is some
605     /// other kind of item.
expect_type(&self) -> &Type606     pub fn expect_type(&self) -> &Type {
607         self.kind().expect_type()
608     }
609 
610     /// Get a reference to this item's underlying `Type`, or `None` if this is
611     /// some other kind of item.
as_type(&self) -> Option<&Type>612     pub fn as_type(&self) -> Option<&Type> {
613         self.kind().as_type()
614     }
615 
616     /// Get a reference to this item's underlying `Function`. Panic if this is
617     /// some other kind of item.
expect_function(&self) -> &Function618     pub fn expect_function(&self) -> &Function {
619         self.kind().expect_function()
620     }
621 
622     /// Is this item a module?
is_module(&self) -> bool623     pub fn is_module(&self) -> bool {
624         matches!(self.kind, ItemKind::Module(..))
625     }
626 
627     /// Get this item's annotations.
annotations(&self) -> &Annotations628     pub fn annotations(&self) -> &Annotations {
629         &self.annotations
630     }
631 
632     /// Whether this item should be blocklisted.
633     ///
634     /// This may be due to either annotations or to other kind of configuration.
is_blocklisted(&self, ctx: &BindgenContext) -> bool635     pub fn is_blocklisted(&self, ctx: &BindgenContext) -> bool {
636         debug_assert!(
637             ctx.in_codegen_phase(),
638             "You're not supposed to call this yet"
639         );
640         if self.annotations.hide() {
641             return true;
642         }
643 
644         if !ctx.options().blocklisted_files.is_empty() {
645             if let Some(location) = &self.location {
646                 let (file, _, _, _) = location.location();
647                 if let Some(filename) = file.name() {
648                     if ctx.options().blocklisted_files.matches(&filename) {
649                         return true;
650                     }
651                 }
652             }
653         }
654 
655         let path = self.path_for_allowlisting(ctx);
656         let name = path[1..].join("::");
657         ctx.options().blocklisted_items.matches(&name) ||
658             match self.kind {
659                 ItemKind::Type(..) => {
660                     ctx.options().blocklisted_types.matches(&name) ||
661                         ctx.is_replaced_type(path, self.id)
662                 }
663                 ItemKind::Function(..) => {
664                     ctx.options().blocklisted_functions.matches(&name)
665                 }
666                 // TODO: Add constant / namespace blocklisting?
667                 ItemKind::Var(..) | ItemKind::Module(..) => false,
668             }
669     }
670 
671     /// Is this a reference to another type?
is_type_ref(&self) -> bool672     pub fn is_type_ref(&self) -> bool {
673         self.as_type().map_or(false, |ty| ty.is_type_ref())
674     }
675 
676     /// Is this item a var type?
is_var(&self) -> bool677     pub fn is_var(&self) -> bool {
678         matches!(*self.kind(), ItemKind::Var(..))
679     }
680 
681     /// Take out item NameOptions
name<'a>(&'a self, ctx: &'a BindgenContext) -> NameOptions<'a>682     pub fn name<'a>(&'a self, ctx: &'a BindgenContext) -> NameOptions<'a> {
683         NameOptions::new(self, ctx)
684     }
685 
686     /// Get the target item id for name generation.
name_target(&self, ctx: &BindgenContext) -> ItemId687     fn name_target(&self, ctx: &BindgenContext) -> ItemId {
688         let mut targets_seen = DebugOnlyItemSet::new();
689         let mut item = self;
690 
691         loop {
692             extra_assert!(!targets_seen.contains(&item.id()));
693             targets_seen.insert(item.id());
694 
695             if self.annotations().use_instead_of().is_some() {
696                 return self.id();
697             }
698 
699             match *item.kind() {
700                 ItemKind::Type(ref ty) => match *ty.kind() {
701                     TypeKind::ResolvedTypeRef(inner) => {
702                         item = ctx.resolve_item(inner);
703                     }
704                     TypeKind::TemplateInstantiation(ref inst) => {
705                         item = ctx.resolve_item(inst.template_definition());
706                     }
707                     _ => return item.id(),
708                 },
709                 _ => return item.id(),
710             }
711         }
712     }
713 
714     /// Create a fully disambiguated name for an item, including template
715     /// parameters if it is a type
full_disambiguated_name(&self, ctx: &BindgenContext) -> String716     pub fn full_disambiguated_name(&self, ctx: &BindgenContext) -> String {
717         let mut s = String::new();
718         let level = 0;
719         self.push_disambiguated_name(ctx, &mut s, level);
720         s
721     }
722 
723     /// Helper function for full_disambiguated_name
push_disambiguated_name( &self, ctx: &BindgenContext, to: &mut String, level: u8, )724     fn push_disambiguated_name(
725         &self,
726         ctx: &BindgenContext,
727         to: &mut String,
728         level: u8,
729     ) {
730         to.push_str(&self.canonical_name(ctx));
731         if let ItemKind::Type(ref ty) = *self.kind() {
732             if let TypeKind::TemplateInstantiation(ref inst) = *ty.kind() {
733                 to.push_str(&format!("_open{}_", level));
734                 for arg in inst.template_arguments() {
735                     arg.into_resolver()
736                         .through_type_refs()
737                         .resolve(ctx)
738                         .push_disambiguated_name(ctx, to, level + 1);
739                     to.push('_');
740                 }
741                 to.push_str(&format!("close{}", level));
742             }
743         }
744     }
745 
746     /// Get this function item's name, or `None` if this item is not a function.
func_name(&self) -> Option<&str>747     fn func_name(&self) -> Option<&str> {
748         match *self.kind() {
749             ItemKind::Function(ref func) => Some(func.name()),
750             _ => None,
751         }
752     }
753 
754     /// Get the overload index for this method. If this is not a method, return
755     /// `None`.
overload_index(&self, ctx: &BindgenContext) -> Option<usize>756     fn overload_index(&self, ctx: &BindgenContext) -> Option<usize> {
757         self.func_name().and_then(|func_name| {
758             let parent = ctx.resolve_item(self.parent_id());
759             if let ItemKind::Type(ref ty) = *parent.kind() {
760                 if let TypeKind::Comp(ref ci) = *ty.kind() {
761                     // All the constructors have the same name, so no need to
762                     // resolve and check.
763                     return ci
764                         .constructors()
765                         .iter()
766                         .position(|c| *c == self.id())
767                         .or_else(|| {
768                             ci.methods()
769                                 .iter()
770                                 .filter(|m| {
771                                     let item = ctx.resolve_item(m.signature());
772                                     let func = item.expect_function();
773                                     func.name() == func_name
774                                 })
775                                 .position(|m| m.signature() == self.id())
776                         });
777                 }
778             }
779 
780             None
781         })
782     }
783 
784     /// Get this item's base name (aka non-namespaced name).
base_name(&self, ctx: &BindgenContext) -> String785     fn base_name(&self, ctx: &BindgenContext) -> String {
786         if let Some(path) = self.annotations().use_instead_of() {
787             return path.last().unwrap().clone();
788         }
789 
790         match *self.kind() {
791             ItemKind::Var(ref var) => var.name().to_owned(),
792             ItemKind::Module(ref module) => {
793                 module.name().map(ToOwned::to_owned).unwrap_or_else(|| {
794                     format!("_bindgen_mod_{}", self.exposed_id(ctx))
795                 })
796             }
797             ItemKind::Type(ref ty) => {
798                 ty.sanitized_name(ctx).map(Into::into).unwrap_or_else(|| {
799                     format!("_bindgen_ty_{}", self.exposed_id(ctx))
800                 })
801             }
802             ItemKind::Function(ref fun) => {
803                 let mut name = fun.name().to_owned();
804 
805                 if let Some(idx) = self.overload_index(ctx) {
806                     if idx > 0 {
807                         write!(&mut name, "{}", idx).unwrap();
808                     }
809                 }
810 
811                 name
812             }
813         }
814     }
815 
is_anon(&self) -> bool816     fn is_anon(&self) -> bool {
817         match self.kind() {
818             ItemKind::Module(module) => module.name().is_none(),
819             ItemKind::Type(ty) => ty.name().is_none(),
820             ItemKind::Function(_) => false,
821             ItemKind::Var(_) => false,
822         }
823     }
824 
825     /// Get the canonical name without taking into account the replaces
826     /// annotation.
827     ///
828     /// This is the base logic used to implement hiding and replacing via
829     /// annotations, and also to implement proper name mangling.
830     ///
831     /// The idea is that each generated type in the same "level" (read: module
832     /// or namespace) has a unique canonical name.
833     ///
834     /// This name should be derived from the immutable state contained in the
835     /// type and the parent chain, since it should be consistent.
836     ///
837     /// If `BindgenOptions::disable_nested_struct_naming` is true then returned
838     /// name is the inner most non-anonymous name plus all the anonymous base names
839     /// that follows.
real_canonical_name( &self, ctx: &BindgenContext, opt: &NameOptions, ) -> String840     pub fn real_canonical_name(
841         &self,
842         ctx: &BindgenContext,
843         opt: &NameOptions,
844     ) -> String {
845         let target = ctx.resolve_item(self.name_target(ctx));
846 
847         // Short-circuit if the target has an override, and just use that.
848         if let Some(path) = target.annotations.use_instead_of() {
849             if ctx.options().enable_cxx_namespaces {
850                 return path.last().unwrap().clone();
851             }
852             return path.join("_");
853         }
854 
855         let base_name = target.base_name(ctx);
856 
857         // Named template type arguments are never namespaced, and never
858         // mangled.
859         if target.is_template_param(ctx, &()) {
860             return base_name;
861         }
862 
863         // Ancestors' id iter
864         let mut ids_iter = target
865             .parent_id()
866             .ancestors(ctx)
867             .filter(|id| *id != ctx.root_module())
868             .take_while(|id| {
869                 // Stop iterating ancestors once we reach a non-inline namespace
870                 // when opt.within_namespaces is set.
871                 !opt.within_namespaces || !ctx.resolve_item(*id).is_module()
872             })
873             .filter(|id| {
874                 if !ctx.options().conservative_inline_namespaces {
875                     if let ItemKind::Module(ref module) =
876                         *ctx.resolve_item(*id).kind()
877                     {
878                         return !module.is_inline();
879                     }
880                 }
881 
882                 true
883             });
884 
885         let ids: Vec<_> = if ctx.options().disable_nested_struct_naming {
886             let mut ids = Vec::new();
887 
888             // If target is anonymous we need find its first named ancestor.
889             if target.is_anon() {
890                 for id in ids_iter.by_ref() {
891                     ids.push(id);
892 
893                     if !ctx.resolve_item(id).is_anon() {
894                         break;
895                     }
896                 }
897             }
898 
899             ids
900         } else {
901             ids_iter.collect()
902         };
903 
904         // Concatenate this item's ancestors' names together.
905         let mut names: Vec<_> = ids
906             .into_iter()
907             .map(|id| {
908                 let item = ctx.resolve_item(id);
909                 let target = ctx.resolve_item(item.name_target(ctx));
910                 target.base_name(ctx)
911             })
912             .filter(|name| !name.is_empty())
913             .collect();
914 
915         names.reverse();
916 
917         if !base_name.is_empty() {
918             names.push(base_name);
919         }
920 
921         if ctx.options().c_naming {
922             if let Some(prefix) = self.c_naming_prefix() {
923                 names.insert(0, prefix.to_string());
924             }
925         }
926 
927         let name = names.join("_");
928 
929         let name = if opt.user_mangled == UserMangled::Yes {
930             ctx.parse_callbacks()
931                 .and_then(|callbacks| callbacks.item_name(&name))
932                 .unwrap_or(name)
933         } else {
934             name
935         };
936 
937         ctx.rust_mangle(&name).into_owned()
938     }
939 
940     /// The exposed id that represents an unique id among the siblings of a
941     /// given item.
exposed_id(&self, ctx: &BindgenContext) -> String942     pub fn exposed_id(&self, ctx: &BindgenContext) -> String {
943         // Only use local ids for enums, classes, structs and union types.  All
944         // other items use their global id.
945         let ty_kind = self.kind().as_type().map(|t| t.kind());
946         if let Some(ty_kind) = ty_kind {
947             match *ty_kind {
948                 TypeKind::Comp(..) |
949                 TypeKind::TemplateInstantiation(..) |
950                 TypeKind::Enum(..) => return self.local_id(ctx).to_string(),
951                 _ => {}
952             }
953         }
954 
955         // Note that this `id_` prefix prevents (really unlikely) collisions
956         // between the global id and the local id of an item with the same
957         // parent.
958         format!("id_{}", self.id().as_usize())
959     }
960 
961     /// Get a reference to this item's `Module`, or `None` if this is not a
962     /// `Module` item.
as_module(&self) -> Option<&Module>963     pub fn as_module(&self) -> Option<&Module> {
964         match self.kind {
965             ItemKind::Module(ref module) => Some(module),
966             _ => None,
967         }
968     }
969 
970     /// Get a mutable reference to this item's `Module`, or `None` if this is
971     /// not a `Module` item.
as_module_mut(&mut self) -> Option<&mut Module>972     pub fn as_module_mut(&mut self) -> Option<&mut Module> {
973         match self.kind {
974             ItemKind::Module(ref mut module) => Some(module),
975             _ => None,
976         }
977     }
978 
979     /// Returns whether the item is a constified module enum
is_constified_enum_module(&self, ctx: &BindgenContext) -> bool980     fn is_constified_enum_module(&self, ctx: &BindgenContext) -> bool {
981         // Do not jump through aliases, except for aliases that point to a type
982         // with the same name, since we dont generate coe for them.
983         let item = self.id.into_resolver().through_type_refs().resolve(ctx);
984         let type_ = match *item.kind() {
985             ItemKind::Type(ref type_) => type_,
986             _ => return false,
987         };
988 
989         match *type_.kind() {
990             TypeKind::Enum(ref enum_) => {
991                 enum_.computed_enum_variation(ctx, self) ==
992                     EnumVariation::ModuleConsts
993             }
994             TypeKind::Alias(inner_id) => {
995                 // TODO(emilio): Make this "hop through type aliases that aren't
996                 // really generated" an option in `ItemResolver`?
997                 let inner_item = ctx.resolve_item(inner_id);
998                 let name = item.canonical_name(ctx);
999 
1000                 if inner_item.canonical_name(ctx) == name {
1001                     inner_item.is_constified_enum_module(ctx)
1002                 } else {
1003                     false
1004                 }
1005             }
1006             _ => false,
1007         }
1008     }
1009 
1010     /// Is this item of a kind that is enabled for code generation?
is_enabled_for_codegen(&self, ctx: &BindgenContext) -> bool1011     pub fn is_enabled_for_codegen(&self, ctx: &BindgenContext) -> bool {
1012         let cc = &ctx.options().codegen_config;
1013         match *self.kind() {
1014             ItemKind::Module(..) => true,
1015             ItemKind::Var(_) => cc.vars(),
1016             ItemKind::Type(_) => cc.types(),
1017             ItemKind::Function(ref f) => match f.kind() {
1018                 FunctionKind::Function => cc.functions(),
1019                 FunctionKind::Method(MethodKind::Constructor) => {
1020                     cc.constructors()
1021                 }
1022                 FunctionKind::Method(MethodKind::Destructor) |
1023                 FunctionKind::Method(MethodKind::VirtualDestructor {
1024                     ..
1025                 }) => cc.destructors(),
1026                 FunctionKind::Method(MethodKind::Static) |
1027                 FunctionKind::Method(MethodKind::Normal) |
1028                 FunctionKind::Method(MethodKind::Virtual { .. }) => {
1029                     cc.methods()
1030                 }
1031             },
1032         }
1033     }
1034 
1035     /// Returns the path we should use for allowlisting / blocklisting, which
1036     /// doesn't include user-mangling.
path_for_allowlisting(&self, ctx: &BindgenContext) -> &Vec<String>1037     pub fn path_for_allowlisting(&self, ctx: &BindgenContext) -> &Vec<String> {
1038         self.path_for_allowlisting
1039             .borrow_with(|| self.compute_path(ctx, UserMangled::No))
1040     }
1041 
compute_path( &self, ctx: &BindgenContext, mangled: UserMangled, ) -> Vec<String>1042     fn compute_path(
1043         &self,
1044         ctx: &BindgenContext,
1045         mangled: UserMangled,
1046     ) -> Vec<String> {
1047         if let Some(path) = self.annotations().use_instead_of() {
1048             let mut ret =
1049                 vec![ctx.resolve_item(ctx.root_module()).name(ctx).get()];
1050             ret.extend_from_slice(path);
1051             return ret;
1052         }
1053 
1054         let target = ctx.resolve_item(self.name_target(ctx));
1055         let mut path: Vec<_> = target
1056             .ancestors(ctx)
1057             .chain(iter::once(ctx.root_module().into()))
1058             .map(|id| ctx.resolve_item(id))
1059             .filter(|item| {
1060                 item.id() == target.id() ||
1061                     item.as_module().map_or(false, |module| {
1062                         !module.is_inline() ||
1063                             ctx.options().conservative_inline_namespaces
1064                     })
1065             })
1066             .map(|item| {
1067                 ctx.resolve_item(item.name_target(ctx))
1068                     .name(ctx)
1069                     .within_namespaces()
1070                     .user_mangled(mangled)
1071                     .get()
1072             })
1073             .collect();
1074         path.reverse();
1075         path
1076     }
1077 
1078     /// Returns a prefix for the canonical name when C naming is enabled.
c_naming_prefix(&self) -> Option<&str>1079     fn c_naming_prefix(&self) -> Option<&str> {
1080         let ty = match self.kind {
1081             ItemKind::Type(ref ty) => ty,
1082             _ => return None,
1083         };
1084 
1085         Some(match ty.kind() {
1086             TypeKind::Comp(ref ci) => match ci.kind() {
1087                 CompKind::Struct => "struct",
1088                 CompKind::Union => "union",
1089             },
1090             TypeKind::Enum(..) => "enum",
1091             _ => return None,
1092         })
1093     }
1094 }
1095 
1096 impl<T> IsOpaque for T
1097 where
1098     T: Copy + Into<ItemId>,
1099 {
1100     type Extra = ();
1101 
is_opaque(&self, ctx: &BindgenContext, _: &()) -> bool1102     fn is_opaque(&self, ctx: &BindgenContext, _: &()) -> bool {
1103         debug_assert!(
1104             ctx.in_codegen_phase(),
1105             "You're not supposed to call this yet"
1106         );
1107         ctx.resolve_item((*self).into()).is_opaque(ctx, &())
1108     }
1109 }
1110 
1111 impl IsOpaque for Item {
1112     type Extra = ();
1113 
is_opaque(&self, ctx: &BindgenContext, _: &()) -> bool1114     fn is_opaque(&self, ctx: &BindgenContext, _: &()) -> bool {
1115         debug_assert!(
1116             ctx.in_codegen_phase(),
1117             "You're not supposed to call this yet"
1118         );
1119         self.annotations.opaque() ||
1120             self.as_type().map_or(false, |ty| ty.is_opaque(ctx, self)) ||
1121             ctx.opaque_by_name(self.path_for_allowlisting(ctx))
1122     }
1123 }
1124 
1125 impl<T> HasVtable for T
1126 where
1127     T: Copy + Into<ItemId>,
1128 {
has_vtable(&self, ctx: &BindgenContext) -> bool1129     fn has_vtable(&self, ctx: &BindgenContext) -> bool {
1130         let id: ItemId = (*self).into();
1131         id.as_type_id(ctx).map_or(false, |id| {
1132             !matches!(ctx.lookup_has_vtable(id), HasVtableResult::No)
1133         })
1134     }
1135 
has_vtable_ptr(&self, ctx: &BindgenContext) -> bool1136     fn has_vtable_ptr(&self, ctx: &BindgenContext) -> bool {
1137         let id: ItemId = (*self).into();
1138         id.as_type_id(ctx).map_or(false, |id| {
1139             matches!(ctx.lookup_has_vtable(id), HasVtableResult::SelfHasVtable)
1140         })
1141     }
1142 }
1143 
1144 impl HasVtable for Item {
has_vtable(&self, ctx: &BindgenContext) -> bool1145     fn has_vtable(&self, ctx: &BindgenContext) -> bool {
1146         self.id().has_vtable(ctx)
1147     }
1148 
has_vtable_ptr(&self, ctx: &BindgenContext) -> bool1149     fn has_vtable_ptr(&self, ctx: &BindgenContext) -> bool {
1150         self.id().has_vtable_ptr(ctx)
1151     }
1152 }
1153 
1154 impl<T> Sizedness for T
1155 where
1156     T: Copy + Into<ItemId>,
1157 {
sizedness(&self, ctx: &BindgenContext) -> SizednessResult1158     fn sizedness(&self, ctx: &BindgenContext) -> SizednessResult {
1159         let id: ItemId = (*self).into();
1160         id.as_type_id(ctx)
1161             .map_or(SizednessResult::default(), |id| ctx.lookup_sizedness(id))
1162     }
1163 }
1164 
1165 impl Sizedness for Item {
sizedness(&self, ctx: &BindgenContext) -> SizednessResult1166     fn sizedness(&self, ctx: &BindgenContext) -> SizednessResult {
1167         self.id().sizedness(ctx)
1168     }
1169 }
1170 
1171 impl<T> HasTypeParamInArray for T
1172 where
1173     T: Copy + Into<ItemId>,
1174 {
has_type_param_in_array(&self, ctx: &BindgenContext) -> bool1175     fn has_type_param_in_array(&self, ctx: &BindgenContext) -> bool {
1176         debug_assert!(
1177             ctx.in_codegen_phase(),
1178             "You're not supposed to call this yet"
1179         );
1180         ctx.lookup_has_type_param_in_array(*self)
1181     }
1182 }
1183 
1184 impl HasTypeParamInArray for Item {
has_type_param_in_array(&self, ctx: &BindgenContext) -> bool1185     fn has_type_param_in_array(&self, ctx: &BindgenContext) -> bool {
1186         debug_assert!(
1187             ctx.in_codegen_phase(),
1188             "You're not supposed to call this yet"
1189         );
1190         ctx.lookup_has_type_param_in_array(self.id())
1191     }
1192 }
1193 
1194 impl<T> HasFloat for T
1195 where
1196     T: Copy + Into<ItemId>,
1197 {
has_float(&self, ctx: &BindgenContext) -> bool1198     fn has_float(&self, ctx: &BindgenContext) -> bool {
1199         debug_assert!(
1200             ctx.in_codegen_phase(),
1201             "You're not supposed to call this yet"
1202         );
1203         ctx.lookup_has_float(*self)
1204     }
1205 }
1206 
1207 impl HasFloat for Item {
has_float(&self, ctx: &BindgenContext) -> bool1208     fn has_float(&self, ctx: &BindgenContext) -> bool {
1209         debug_assert!(
1210             ctx.in_codegen_phase(),
1211             "You're not supposed to call this yet"
1212         );
1213         ctx.lookup_has_float(self.id())
1214     }
1215 }
1216 
1217 /// A set of items.
1218 pub type ItemSet = BTreeSet<ItemId>;
1219 
1220 impl DotAttributes for Item {
dot_attributes<W>( &self, ctx: &BindgenContext, out: &mut W, ) -> io::Result<()> where W: io::Write,1221     fn dot_attributes<W>(
1222         &self,
1223         ctx: &BindgenContext,
1224         out: &mut W,
1225     ) -> io::Result<()>
1226     where
1227         W: io::Write,
1228     {
1229         writeln!(
1230             out,
1231             "<tr><td>{:?}</td></tr>
1232                        <tr><td>name</td><td>{}</td></tr>",
1233             self.id,
1234             self.name(ctx).get()
1235         )?;
1236 
1237         if self.is_opaque(ctx, &()) {
1238             writeln!(out, "<tr><td>opaque</td><td>true</td></tr>")?;
1239         }
1240 
1241         self.kind.dot_attributes(ctx, out)
1242     }
1243 }
1244 
1245 impl<T> TemplateParameters for T
1246 where
1247     T: Copy + Into<ItemId>,
1248 {
self_template_params(&self, ctx: &BindgenContext) -> Vec<TypeId>1249     fn self_template_params(&self, ctx: &BindgenContext) -> Vec<TypeId> {
1250         ctx.resolve_item_fallible(*self)
1251             .map_or(vec![], |item| item.self_template_params(ctx))
1252     }
1253 }
1254 
1255 impl TemplateParameters for Item {
self_template_params(&self, ctx: &BindgenContext) -> Vec<TypeId>1256     fn self_template_params(&self, ctx: &BindgenContext) -> Vec<TypeId> {
1257         self.kind.self_template_params(ctx)
1258     }
1259 }
1260 
1261 impl TemplateParameters for ItemKind {
self_template_params(&self, ctx: &BindgenContext) -> Vec<TypeId>1262     fn self_template_params(&self, ctx: &BindgenContext) -> Vec<TypeId> {
1263         match *self {
1264             ItemKind::Type(ref ty) => ty.self_template_params(ctx),
1265             // If we start emitting bindings to explicitly instantiated
1266             // functions, then we'll need to check ItemKind::Function for
1267             // template params.
1268             ItemKind::Function(_) | ItemKind::Module(_) | ItemKind::Var(_) => {
1269                 vec![]
1270             }
1271         }
1272     }
1273 }
1274 
1275 // An utility function to handle recursing inside nested types.
visit_child( cur: clang::Cursor, id: ItemId, ty: &clang::Type, parent_id: Option<ItemId>, ctx: &mut BindgenContext, result: &mut Result<TypeId, ParseError>, ) -> clang_sys::CXChildVisitResult1276 fn visit_child(
1277     cur: clang::Cursor,
1278     id: ItemId,
1279     ty: &clang::Type,
1280     parent_id: Option<ItemId>,
1281     ctx: &mut BindgenContext,
1282     result: &mut Result<TypeId, ParseError>,
1283 ) -> clang_sys::CXChildVisitResult {
1284     use clang_sys::*;
1285     if result.is_ok() {
1286         return CXChildVisit_Break;
1287     }
1288 
1289     *result = Item::from_ty_with_id(id, ty, cur, parent_id, ctx);
1290 
1291     match *result {
1292         Ok(..) => CXChildVisit_Break,
1293         Err(ParseError::Recurse) => {
1294             cur.visit(|c| visit_child(c, id, ty, parent_id, ctx, result));
1295             CXChildVisit_Continue
1296         }
1297         Err(ParseError::Continue) => CXChildVisit_Continue,
1298     }
1299 }
1300 
1301 impl ClangItemParser for Item {
builtin_type( kind: TypeKind, is_const: bool, ctx: &mut BindgenContext, ) -> TypeId1302     fn builtin_type(
1303         kind: TypeKind,
1304         is_const: bool,
1305         ctx: &mut BindgenContext,
1306     ) -> TypeId {
1307         // Feel free to add more here, I'm just lazy.
1308         match kind {
1309             TypeKind::Void |
1310             TypeKind::Int(..) |
1311             TypeKind::Pointer(..) |
1312             TypeKind::Float(..) => {}
1313             _ => panic!("Unsupported builtin type"),
1314         }
1315 
1316         let ty = Type::new(None, None, kind, is_const);
1317         let id = ctx.next_item_id();
1318         let module = ctx.root_module().into();
1319         ctx.add_item(
1320             Item::new(id, None, None, module, ItemKind::Type(ty), None),
1321             None,
1322             None,
1323         );
1324         id.as_type_id_unchecked()
1325     }
1326 
parse( cursor: clang::Cursor, parent_id: Option<ItemId>, ctx: &mut BindgenContext, ) -> Result<ItemId, ParseError>1327     fn parse(
1328         cursor: clang::Cursor,
1329         parent_id: Option<ItemId>,
1330         ctx: &mut BindgenContext,
1331     ) -> Result<ItemId, ParseError> {
1332         use crate::ir::var::Var;
1333         use clang_sys::*;
1334 
1335         if !cursor.is_valid() {
1336             return Err(ParseError::Continue);
1337         }
1338 
1339         let comment = cursor.raw_comment();
1340         let annotations = Annotations::new(&cursor);
1341 
1342         let current_module = ctx.current_module().into();
1343         let relevant_parent_id = parent_id.unwrap_or(current_module);
1344 
1345         macro_rules! try_parse {
1346             ($what:ident) => {
1347                 match $what::parse(cursor, ctx) {
1348                     Ok(ParseResult::New(item, declaration)) => {
1349                         let id = ctx.next_item_id();
1350 
1351                         ctx.add_item(
1352                             Item::new(
1353                                 id,
1354                                 comment,
1355                                 annotations,
1356                                 relevant_parent_id,
1357                                 ItemKind::$what(item),
1358                                 Some(cursor.location()),
1359                             ),
1360                             declaration,
1361                             Some(cursor),
1362                         );
1363                         return Ok(id);
1364                     }
1365                     Ok(ParseResult::AlreadyResolved(id)) => {
1366                         return Ok(id);
1367                     }
1368                     Err(ParseError::Recurse) => return Err(ParseError::Recurse),
1369                     Err(ParseError::Continue) => {}
1370                 }
1371             };
1372         }
1373 
1374         try_parse!(Module);
1375 
1376         // NOTE: Is extremely important to parse functions and vars **before**
1377         // types.  Otherwise we can parse a function declaration as a type
1378         // (which is legal), and lose functions to generate.
1379         //
1380         // In general, I'm not totally confident this split between
1381         // ItemKind::Function and TypeKind::FunctionSig is totally worth it, but
1382         // I guess we can try.
1383         try_parse!(Function);
1384         try_parse!(Var);
1385 
1386         // Types are sort of special, so to avoid parsing template classes
1387         // twice, handle them separately.
1388         {
1389             let definition = cursor.definition();
1390             let applicable_cursor = definition.unwrap_or(cursor);
1391 
1392             let relevant_parent_id = match definition {
1393                 Some(definition) => {
1394                     if definition != cursor {
1395                         ctx.add_semantic_parent(definition, relevant_parent_id);
1396                         return Ok(Item::from_ty_or_ref(
1397                             applicable_cursor.cur_type(),
1398                             cursor,
1399                             parent_id,
1400                             ctx,
1401                         )
1402                         .into());
1403                     }
1404                     ctx.known_semantic_parent(definition)
1405                         .or(parent_id)
1406                         .unwrap_or_else(|| ctx.current_module().into())
1407                 }
1408                 None => relevant_parent_id,
1409             };
1410 
1411             match Item::from_ty(
1412                 &applicable_cursor.cur_type(),
1413                 applicable_cursor,
1414                 Some(relevant_parent_id),
1415                 ctx,
1416             ) {
1417                 Ok(ty) => return Ok(ty.into()),
1418                 Err(ParseError::Recurse) => return Err(ParseError::Recurse),
1419                 Err(ParseError::Continue) => {}
1420             }
1421         }
1422 
1423         // Guess how does clang treat extern "C" blocks?
1424         if cursor.kind() == CXCursor_UnexposedDecl {
1425             Err(ParseError::Recurse)
1426         } else {
1427             // We allowlist cursors here known to be unhandled, to prevent being
1428             // too noisy about this.
1429             match cursor.kind() {
1430                 CXCursor_MacroDefinition |
1431                 CXCursor_MacroExpansion |
1432                 CXCursor_UsingDeclaration |
1433                 CXCursor_UsingDirective |
1434                 CXCursor_StaticAssert |
1435                 CXCursor_FunctionTemplate => {
1436                     debug!(
1437                         "Unhandled cursor kind {:?}: {:?}",
1438                         cursor.kind(),
1439                         cursor
1440                     );
1441                 }
1442                 CXCursor_InclusionDirective => {
1443                     let file = cursor.get_included_file_name();
1444                     match file {
1445                         None => {
1446                             warn!(
1447                                 "Inclusion of a nameless file in {:?}",
1448                                 cursor
1449                             );
1450                         }
1451                         Some(filename) => {
1452                             ctx.include_file(filename);
1453                         }
1454                     }
1455                 }
1456                 _ => {
1457                     // ignore toplevel operator overloads
1458                     let spelling = cursor.spelling();
1459                     if !spelling.starts_with("operator") {
1460                         warn!(
1461                             "Unhandled cursor kind {:?}: {:?}",
1462                             cursor.kind(),
1463                             cursor
1464                         );
1465                     }
1466                 }
1467             }
1468 
1469             Err(ParseError::Continue)
1470         }
1471     }
1472 
from_ty_or_ref( ty: clang::Type, location: clang::Cursor, parent_id: Option<ItemId>, ctx: &mut BindgenContext, ) -> TypeId1473     fn from_ty_or_ref(
1474         ty: clang::Type,
1475         location: clang::Cursor,
1476         parent_id: Option<ItemId>,
1477         ctx: &mut BindgenContext,
1478     ) -> TypeId {
1479         let id = ctx.next_item_id();
1480         Self::from_ty_or_ref_with_id(id, ty, location, parent_id, ctx)
1481     }
1482 
1483     /// Parse a C++ type. If we find a reference to a type that has not been
1484     /// defined yet, use `UnresolvedTypeRef` as a placeholder.
1485     ///
1486     /// This logic is needed to avoid parsing items with the incorrect parent
1487     /// and it's sort of complex to explain, so I'll just point to
1488     /// `tests/headers/typeref.hpp` to see the kind of constructs that forced
1489     /// this.
1490     ///
1491     /// Typerefs are resolved once parsing is completely done, see
1492     /// `BindgenContext::resolve_typerefs`.
from_ty_or_ref_with_id( potential_id: ItemId, ty: clang::Type, location: clang::Cursor, parent_id: Option<ItemId>, ctx: &mut BindgenContext, ) -> TypeId1493     fn from_ty_or_ref_with_id(
1494         potential_id: ItemId,
1495         ty: clang::Type,
1496         location: clang::Cursor,
1497         parent_id: Option<ItemId>,
1498         ctx: &mut BindgenContext,
1499     ) -> TypeId {
1500         debug!(
1501             "from_ty_or_ref_with_id: {:?} {:?}, {:?}, {:?}",
1502             potential_id, ty, location, parent_id
1503         );
1504 
1505         if ctx.collected_typerefs() {
1506             debug!("refs already collected, resolving directly");
1507             return Item::from_ty_with_id(
1508                 potential_id,
1509                 &ty,
1510                 location,
1511                 parent_id,
1512                 ctx,
1513             )
1514             .unwrap_or_else(|_| Item::new_opaque_type(potential_id, &ty, ctx));
1515         }
1516 
1517         if let Some(ty) = ctx.builtin_or_resolved_ty(
1518             potential_id,
1519             parent_id,
1520             &ty,
1521             Some(location),
1522         ) {
1523             debug!("{:?} already resolved: {:?}", ty, location);
1524             return ty;
1525         }
1526 
1527         debug!("New unresolved type reference: {:?}, {:?}", ty, location);
1528 
1529         let is_const = ty.is_const();
1530         let kind = TypeKind::UnresolvedTypeRef(ty, location, parent_id);
1531         let current_module = ctx.current_module();
1532 
1533         ctx.add_item(
1534             Item::new(
1535                 potential_id,
1536                 None,
1537                 None,
1538                 parent_id.unwrap_or_else(|| current_module.into()),
1539                 ItemKind::Type(Type::new(None, None, kind, is_const)),
1540                 Some(location.location()),
1541             ),
1542             None,
1543             None,
1544         );
1545         potential_id.as_type_id_unchecked()
1546     }
1547 
from_ty( ty: &clang::Type, location: clang::Cursor, parent_id: Option<ItemId>, ctx: &mut BindgenContext, ) -> Result<TypeId, ParseError>1548     fn from_ty(
1549         ty: &clang::Type,
1550         location: clang::Cursor,
1551         parent_id: Option<ItemId>,
1552         ctx: &mut BindgenContext,
1553     ) -> Result<TypeId, ParseError> {
1554         let id = ctx.next_item_id();
1555         Item::from_ty_with_id(id, ty, location, parent_id, ctx)
1556     }
1557 
1558     /// This is one of the trickiest methods you'll find (probably along with
1559     /// some of the ones that handle templates in `BindgenContext`).
1560     ///
1561     /// This method parses a type, given the potential id of that type (if
1562     /// parsing it was correct), an optional location we're scanning, which is
1563     /// critical some times to obtain information, an optional parent item id,
1564     /// that will, if it's `None`, become the current module id, and the
1565     /// context.
from_ty_with_id( id: ItemId, ty: &clang::Type, location: clang::Cursor, parent_id: Option<ItemId>, ctx: &mut BindgenContext, ) -> Result<TypeId, ParseError>1566     fn from_ty_with_id(
1567         id: ItemId,
1568         ty: &clang::Type,
1569         location: clang::Cursor,
1570         parent_id: Option<ItemId>,
1571         ctx: &mut BindgenContext,
1572     ) -> Result<TypeId, ParseError> {
1573         use clang_sys::*;
1574 
1575         debug!(
1576             "Item::from_ty_with_id: {:?}\n\
1577              \tty = {:?},\n\
1578              \tlocation = {:?}",
1579             id, ty, location
1580         );
1581 
1582         if ty.kind() == clang_sys::CXType_Unexposed ||
1583             location.cur_type().kind() == clang_sys::CXType_Unexposed
1584         {
1585             if ty.is_associated_type() ||
1586                 location.cur_type().is_associated_type()
1587             {
1588                 return Ok(Item::new_opaque_type(id, ty, ctx));
1589             }
1590 
1591             if let Some(param_id) = Item::type_param(None, location, ctx) {
1592                 return Ok(ctx.build_ty_wrapper(id, param_id, None, ty));
1593             }
1594         }
1595 
1596         // Treat all types that are declared inside functions as opaque. The Rust binding
1597         // won't be able to do anything with them anyway.
1598         //
1599         // (If we don't do this check here, we can have subtle logic bugs because we generally
1600         // ignore function bodies. See issue #2036.)
1601         if let Some(ref parent) = ty.declaration().fallible_semantic_parent() {
1602             if FunctionKind::from_cursor(parent).is_some() {
1603                 debug!("Skipping type declared inside function: {:?}", ty);
1604                 return Ok(Item::new_opaque_type(id, ty, ctx));
1605             }
1606         }
1607 
1608         let decl = {
1609             let canonical_def = ty.canonical_type().declaration().definition();
1610             canonical_def.unwrap_or_else(|| ty.declaration())
1611         };
1612 
1613         let comment = decl.raw_comment().or_else(|| location.raw_comment());
1614         let annotations =
1615             Annotations::new(&decl).or_else(|| Annotations::new(&location));
1616 
1617         if let Some(ref annotations) = annotations {
1618             if let Some(replaced) = annotations.use_instead_of() {
1619                 ctx.replace(replaced, id);
1620             }
1621         }
1622 
1623         if let Some(ty) =
1624             ctx.builtin_or_resolved_ty(id, parent_id, ty, Some(location))
1625         {
1626             return Ok(ty);
1627         }
1628 
1629         // First, check we're not recursing.
1630         let mut valid_decl = decl.kind() != CXCursor_NoDeclFound;
1631         let declaration_to_look_for = if valid_decl {
1632             decl.canonical()
1633         } else if location.kind() == CXCursor_ClassTemplate {
1634             valid_decl = true;
1635             location
1636         } else {
1637             decl
1638         };
1639 
1640         if valid_decl {
1641             if let Some(partial) = ctx
1642                 .currently_parsed_types()
1643                 .iter()
1644                 .find(|ty| *ty.decl() == declaration_to_look_for)
1645             {
1646                 debug!("Avoiding recursion parsing type: {:?}", ty);
1647                 // Unchecked because we haven't finished this type yet.
1648                 return Ok(partial.id().as_type_id_unchecked());
1649             }
1650         }
1651 
1652         let current_module = ctx.current_module().into();
1653         let partial_ty = PartialType::new(declaration_to_look_for, id);
1654         if valid_decl {
1655             ctx.begin_parsing(partial_ty);
1656         }
1657 
1658         let result = Type::from_clang_ty(id, ty, location, parent_id, ctx);
1659         let relevant_parent_id = parent_id.unwrap_or(current_module);
1660         let ret = match result {
1661             Ok(ParseResult::AlreadyResolved(ty)) => {
1662                 Ok(ty.as_type_id_unchecked())
1663             }
1664             Ok(ParseResult::New(item, declaration)) => {
1665                 ctx.add_item(
1666                     Item::new(
1667                         id,
1668                         comment,
1669                         annotations,
1670                         relevant_parent_id,
1671                         ItemKind::Type(item),
1672                         Some(location.location()),
1673                     ),
1674                     declaration,
1675                     Some(location),
1676                 );
1677                 Ok(id.as_type_id_unchecked())
1678             }
1679             Err(ParseError::Continue) => Err(ParseError::Continue),
1680             Err(ParseError::Recurse) => {
1681                 debug!("Item::from_ty recursing in the ast");
1682                 let mut result = Err(ParseError::Recurse);
1683 
1684                 // Need to pop here, otherwise we'll get stuck.
1685                 //
1686                 // TODO: Find a nicer interface, really. Also, the
1687                 // declaration_to_look_for suspiciously shares a lot of
1688                 // logic with ir::context, so we should refactor that.
1689                 if valid_decl {
1690                     let finished = ctx.finish_parsing();
1691                     assert_eq!(*finished.decl(), declaration_to_look_for);
1692                 }
1693 
1694                 location.visit(|cur| {
1695                     visit_child(cur, id, ty, parent_id, ctx, &mut result)
1696                 });
1697 
1698                 if valid_decl {
1699                     let partial_ty =
1700                         PartialType::new(declaration_to_look_for, id);
1701                     ctx.begin_parsing(partial_ty);
1702                 }
1703 
1704                 // If we have recursed into the AST all we know, and we still
1705                 // haven't found what we've got, let's just try and make a named
1706                 // type.
1707                 //
1708                 // This is what happens with some template members, for example.
1709                 if let Err(ParseError::Recurse) = result {
1710                     warn!(
1711                         "Unknown type, assuming named template type: \
1712                          id = {:?}; spelling = {}",
1713                         id,
1714                         ty.spelling()
1715                     );
1716                     Item::type_param(Some(id), location, ctx)
1717                         .map(Ok)
1718                         .unwrap_or(Err(ParseError::Recurse))
1719                 } else {
1720                     result
1721                 }
1722             }
1723         };
1724 
1725         if valid_decl {
1726             let partial_ty = ctx.finish_parsing();
1727             assert_eq!(*partial_ty.decl(), declaration_to_look_for);
1728         }
1729 
1730         ret
1731     }
1732 
1733     /// A named type is a template parameter, e.g., the "T" in Foo<T>. They're
1734     /// always local so it's the only exception when there's no declaration for
1735     /// a type.
type_param( with_id: Option<ItemId>, location: clang::Cursor, ctx: &mut BindgenContext, ) -> Option<TypeId>1736     fn type_param(
1737         with_id: Option<ItemId>,
1738         location: clang::Cursor,
1739         ctx: &mut BindgenContext,
1740     ) -> Option<TypeId> {
1741         let ty = location.cur_type();
1742 
1743         debug!(
1744             "Item::type_param:\n\
1745              \twith_id = {:?},\n\
1746              \tty = {} {:?},\n\
1747              \tlocation: {:?}",
1748             with_id,
1749             ty.spelling(),
1750             ty,
1751             location
1752         );
1753 
1754         if ty.kind() != clang_sys::CXType_Unexposed {
1755             // If the given cursor's type's kind is not Unexposed, then we
1756             // aren't looking at a template parameter. This check may need to be
1757             // updated in the future if they start properly exposing template
1758             // type parameters.
1759             return None;
1760         }
1761 
1762         let ty_spelling = ty.spelling();
1763 
1764         // Clang does not expose any information about template type parameters
1765         // via their clang::Type, nor does it give us their canonical cursors
1766         // the straightforward way. However, there are three situations from
1767         // which we can find the definition of the template type parameter, if
1768         // the cursor is indeed looking at some kind of a template type
1769         // parameter or use of one:
1770         //
1771         // 1. The cursor is pointing at the template type parameter's
1772         // definition. This is the trivial case.
1773         //
1774         //     (kind = TemplateTypeParameter, ...)
1775         //
1776         // 2. The cursor is pointing at a TypeRef whose referenced() cursor is
1777         // situation (1).
1778         //
1779         //     (kind = TypeRef,
1780         //      referenced = (kind = TemplateTypeParameter, ...),
1781         //      ...)
1782         //
1783         // 3. The cursor is pointing at some use of a template type parameter
1784         // (for example, in a FieldDecl), and this cursor has a child cursor
1785         // whose spelling is the same as the parent's type's spelling, and whose
1786         // kind is a TypeRef of the situation (2) variety.
1787         //
1788         //    (kind = FieldDecl,
1789         //     type = (kind = Unexposed,
1790         //             spelling = "T",
1791         //             ...),
1792         //     children =
1793         //        (kind = TypeRef,
1794         //         spelling = "T",
1795         //         referenced = (kind = TemplateTypeParameter,
1796         //                       spelling = "T",
1797         //                       ...),
1798         //         ...)
1799         //     ...)
1800         //
1801         // TODO: The alternative to this hacky pattern matching would be to
1802         // maintain proper scopes of template parameters while parsing and use
1803         // de Brujin indices to access template parameters, which clang exposes
1804         // in the cursor's type's canonical type's spelling:
1805         // "type-parameter-x-y". That is probably a better approach long-term,
1806         // but maintaining these scopes properly would require more changes to
1807         // the whole libclang -> IR parsing code.
1808 
1809         fn is_template_with_spelling(
1810             refd: &clang::Cursor,
1811             spelling: &str,
1812         ) -> bool {
1813             lazy_static! {
1814                 static ref ANON_TYPE_PARAM_RE: regex::Regex =
1815                     regex::Regex::new(r"^type\-parameter\-\d+\-\d+$").unwrap();
1816             }
1817 
1818             if refd.kind() != clang_sys::CXCursor_TemplateTypeParameter {
1819                 return false;
1820             }
1821 
1822             let refd_spelling = refd.spelling();
1823             refd_spelling == spelling ||
1824                 // Allow for anonymous template parameters.
1825                 (refd_spelling.is_empty() && ANON_TYPE_PARAM_RE.is_match(spelling.as_ref()))
1826         }
1827 
1828         let definition = if is_template_with_spelling(&location, &ty_spelling) {
1829             // Situation (1)
1830             location
1831         } else if location.kind() == clang_sys::CXCursor_TypeRef {
1832             // Situation (2)
1833             match location.referenced() {
1834                 Some(refd)
1835                     if is_template_with_spelling(&refd, &ty_spelling) =>
1836                 {
1837                     refd
1838                 }
1839                 _ => return None,
1840             }
1841         } else {
1842             // Situation (3)
1843             let mut definition = None;
1844 
1845             location.visit(|child| {
1846                 let child_ty = child.cur_type();
1847                 if child_ty.kind() == clang_sys::CXCursor_TypeRef &&
1848                     child_ty.spelling() == ty_spelling
1849                 {
1850                     match child.referenced() {
1851                         Some(refd)
1852                             if is_template_with_spelling(
1853                                 &refd,
1854                                 &ty_spelling,
1855                             ) =>
1856                         {
1857                             definition = Some(refd);
1858                             return clang_sys::CXChildVisit_Break;
1859                         }
1860                         _ => {}
1861                     }
1862                 }
1863 
1864                 clang_sys::CXChildVisit_Continue
1865             });
1866 
1867             definition?
1868         };
1869         assert!(is_template_with_spelling(&definition, &ty_spelling));
1870 
1871         // Named types are always parented to the root module. They are never
1872         // referenced with namespace prefixes, and they can't inherit anything
1873         // from their parent either, so it is simplest to just hang them off
1874         // something we know will always exist.
1875         let parent = ctx.root_module().into();
1876 
1877         if let Some(id) = ctx.get_type_param(&definition) {
1878             if let Some(with_id) = with_id {
1879                 return Some(ctx.build_ty_wrapper(
1880                     with_id,
1881                     id,
1882                     Some(parent),
1883                     &ty,
1884                 ));
1885             } else {
1886                 return Some(id);
1887             }
1888         }
1889 
1890         // See tests/headers/const_tparam.hpp and
1891         // tests/headers/variadic_tname.hpp.
1892         let name = ty_spelling.replace("const ", "").replace(".", "");
1893 
1894         let id = with_id.unwrap_or_else(|| ctx.next_item_id());
1895         let item = Item::new(
1896             id,
1897             None,
1898             None,
1899             parent,
1900             ItemKind::Type(Type::named(name)),
1901             Some(location.location()),
1902         );
1903         ctx.add_type_param(item, definition);
1904         Some(id.as_type_id_unchecked())
1905     }
1906 }
1907 
1908 impl ItemCanonicalName for Item {
canonical_name(&self, ctx: &BindgenContext) -> String1909     fn canonical_name(&self, ctx: &BindgenContext) -> String {
1910         debug_assert!(
1911             ctx.in_codegen_phase(),
1912             "You're not supposed to call this yet"
1913         );
1914         self.canonical_name
1915             .borrow_with(|| {
1916                 let in_namespace = ctx.options().enable_cxx_namespaces ||
1917                     ctx.options().disable_name_namespacing;
1918 
1919                 if in_namespace {
1920                     self.name(ctx).within_namespaces().get()
1921                 } else {
1922                     self.name(ctx).get()
1923                 }
1924             })
1925             .clone()
1926     }
1927 }
1928 
1929 impl ItemCanonicalPath for Item {
namespace_aware_canonical_path( &self, ctx: &BindgenContext, ) -> Vec<String>1930     fn namespace_aware_canonical_path(
1931         &self,
1932         ctx: &BindgenContext,
1933     ) -> Vec<String> {
1934         let mut path = self.canonical_path(ctx);
1935 
1936         // ASSUMPTION: (disable_name_namespacing && cxx_namespaces)
1937         // is equivalent to
1938         // disable_name_namespacing
1939         if ctx.options().disable_name_namespacing {
1940             // Only keep the last item in path
1941             let split_idx = path.len() - 1;
1942             path = path.split_off(split_idx);
1943         } else if !ctx.options().enable_cxx_namespaces {
1944             // Ignore first item "root"
1945             path = vec![path[1..].join("_")];
1946         }
1947 
1948         if self.is_constified_enum_module(ctx) {
1949             path.push(CONSTIFIED_ENUM_MODULE_REPR_NAME.into());
1950         }
1951 
1952         path
1953     }
1954 
canonical_path(&self, ctx: &BindgenContext) -> Vec<String>1955     fn canonical_path(&self, ctx: &BindgenContext) -> Vec<String> {
1956         self.compute_path(ctx, UserMangled::Yes)
1957     }
1958 }
1959 
1960 /// Whether to use the user-mangled name (mangled by the `item_name` callback or
1961 /// not.
1962 ///
1963 /// Most of the callers probably want just yes, but the ones dealing with
1964 /// allowlisting and blocklisting don't.
1965 #[derive(Copy, Clone, Debug, PartialEq)]
1966 enum UserMangled {
1967     No,
1968     Yes,
1969 }
1970 
1971 /// Builder struct for naming variations, which hold inside different
1972 /// flags for naming options.
1973 #[derive(Debug)]
1974 pub struct NameOptions<'a> {
1975     item: &'a Item,
1976     ctx: &'a BindgenContext,
1977     within_namespaces: bool,
1978     user_mangled: UserMangled,
1979 }
1980 
1981 impl<'a> NameOptions<'a> {
1982     /// Construct a new `NameOptions`
new(item: &'a Item, ctx: &'a BindgenContext) -> Self1983     pub fn new(item: &'a Item, ctx: &'a BindgenContext) -> Self {
1984         NameOptions {
1985             item,
1986             ctx,
1987             within_namespaces: false,
1988             user_mangled: UserMangled::Yes,
1989         }
1990     }
1991 
1992     /// Construct the name without the item's containing C++ namespaces mangled
1993     /// into it. In other words, the item's name within the item's namespace.
within_namespaces(&mut self) -> &mut Self1994     pub fn within_namespaces(&mut self) -> &mut Self {
1995         self.within_namespaces = true;
1996         self
1997     }
1998 
user_mangled(&mut self, user_mangled: UserMangled) -> &mut Self1999     fn user_mangled(&mut self, user_mangled: UserMangled) -> &mut Self {
2000         self.user_mangled = user_mangled;
2001         self
2002     }
2003 
2004     /// Construct a name `String`
get(&self) -> String2005     pub fn get(&self) -> String {
2006         self.item.real_canonical_name(self.ctx, self)
2007     }
2008 }
2009