/rust/registry/src/index.crates.io-1949cf8c6b5b557f/cpp_demangle-0.5.1/src/subs.rs
Line | Count | Source |
1 | | //! Types dealing with the substitutions table. |
2 | | |
3 | | use super::DemangleWrite; |
4 | | use crate::ast; |
5 | | use alloc::vec::Vec; |
6 | | use core::fmt; |
7 | | use core::iter::FromIterator; |
8 | | use core::ops::Deref; |
9 | | |
10 | | /// An enumeration of all of the types that can end up in the substitution |
11 | | /// table. |
12 | | #[doc(hidden)] |
13 | | #[derive(Clone, Debug, PartialEq, Eq)] |
14 | | #[allow(clippy::large_enum_variant)] |
15 | | pub enum Substitutable { |
16 | | /// An `<unscoped-template-name>` production. |
17 | | UnscopedTemplateName(ast::UnscopedTemplateName), |
18 | | |
19 | | /// A `<type>` production. |
20 | | Type(ast::Type), |
21 | | |
22 | | /// A `<template-template-param>` production. |
23 | | TemplateTemplateParam(ast::TemplateTemplateParam), |
24 | | |
25 | | /// An `<unresolved-type>` production. |
26 | | UnresolvedType(ast::UnresolvedType), |
27 | | |
28 | | /// A `<prefix>` production. |
29 | | Prefix(ast::Prefix), |
30 | | } |
31 | | |
32 | | impl<'subs, W> ast::Demangle<'subs, W> for Substitutable |
33 | | where |
34 | | W: 'subs + DemangleWrite, |
35 | | { |
36 | 82.9k | fn demangle<'prev, 'ctx>( |
37 | 82.9k | &'subs self, |
38 | 82.9k | ctx: &'ctx mut ast::DemangleContext<'subs, W>, |
39 | 82.9k | scope: Option<ast::ArgScopeStack<'prev, 'subs>>, |
40 | 82.9k | ) -> fmt::Result { |
41 | 82.9k | match *self { |
42 | 106 | Substitutable::UnscopedTemplateName(ref name) => name.demangle(ctx, scope), |
43 | 82.8k | Substitutable::Type(ref ty) => ty.demangle(ctx, scope), |
44 | 0 | Substitutable::TemplateTemplateParam(ref ttp) => ttp.demangle(ctx, scope), |
45 | 0 | Substitutable::UnresolvedType(ref ty) => ty.demangle(ctx, scope), |
46 | 0 | Substitutable::Prefix(ref prefix) => prefix.demangle(ctx, scope), |
47 | | } |
48 | 82.9k | } <cpp_demangle::subs::Substitutable as cpp_demangle::ast::Demangle<symbolic_demangle::BoundedString>>::demangle Line | Count | Source | 36 | 82.9k | fn demangle<'prev, 'ctx>( | 37 | 82.9k | &'subs self, | 38 | 82.9k | ctx: &'ctx mut ast::DemangleContext<'subs, W>, | 39 | 82.9k | scope: Option<ast::ArgScopeStack<'prev, 'subs>>, | 40 | 82.9k | ) -> fmt::Result { | 41 | 82.9k | match *self { | 42 | 106 | Substitutable::UnscopedTemplateName(ref name) => name.demangle(ctx, scope), | 43 | 82.8k | Substitutable::Type(ref ty) => ty.demangle(ctx, scope), | 44 | 0 | Substitutable::TemplateTemplateParam(ref ttp) => ttp.demangle(ctx, scope), | 45 | 0 | Substitutable::UnresolvedType(ref ty) => ty.demangle(ctx, scope), | 46 | 0 | Substitutable::Prefix(ref prefix) => prefix.demangle(ctx, scope), | 47 | | } | 48 | 82.9k | } |
Unexecuted instantiation: <cpp_demangle::subs::Substitutable as cpp_demangle::ast::Demangle<_>>::demangle |
49 | | } |
50 | | |
51 | | impl<'a> ast::GetLeafName<'a> for Substitutable { |
52 | 92 | fn get_leaf_name(&'a self, subs: &'a SubstitutionTable) -> Option<ast::LeafName<'a>> { |
53 | 92 | match *self { |
54 | 67 | Substitutable::UnscopedTemplateName(ref name) => name.get_leaf_name(subs), |
55 | 0 | Substitutable::Prefix(ref prefix) => prefix.get_leaf_name(subs), |
56 | 25 | Substitutable::Type(ref ty) => ty.get_leaf_name(subs), |
57 | 0 | _ => None, |
58 | | } |
59 | 92 | } |
60 | | } |
61 | | |
62 | | impl ast::IsCtorDtorConversion for Substitutable { |
63 | 0 | fn is_ctor_dtor_conversion(&self, subs: &SubstitutionTable) -> bool { |
64 | 0 | match *self { |
65 | 0 | Substitutable::Prefix(ref prefix) => prefix.is_ctor_dtor_conversion(subs), |
66 | 0 | _ => false, |
67 | | } |
68 | 0 | } |
69 | | } |
70 | | |
71 | | /// The table of substitutable components that we have parsed thus far, and for |
72 | | /// which there are potential back-references. |
73 | | #[doc(hidden)] |
74 | | #[derive(Clone, Default, PartialEq, Eq)] |
75 | | pub struct SubstitutionTable { |
76 | | substitutions: Vec<Substitutable>, |
77 | | // There are components which are typically candidates for substitution, but |
78 | | // in some particular circumstances are not. Instances of such components |
79 | | // which are not candidates for substitution end up in this part of the |
80 | | // table. See `<prefix>` parsing for further details. |
81 | | non_substitutions: Vec<Substitutable>, |
82 | | } |
83 | | |
84 | | impl fmt::Debug for SubstitutionTable { |
85 | 0 | fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { |
86 | 0 | f.pad("SubstitutionTable ")?; |
87 | 0 | f.debug_map() |
88 | 0 | .entries(self.substitutions.iter().enumerate()) |
89 | 0 | .finish()?; |
90 | 0 | f.pad(" non_substitutions ")?; |
91 | 0 | f.debug_map() |
92 | 0 | .entries(self.non_substitutions.iter().enumerate()) |
93 | 0 | .finish() |
94 | 0 | } |
95 | | } |
96 | | |
97 | | impl SubstitutionTable { |
98 | | /// Construct a new `SubstitutionTable`. |
99 | 15.3k | pub fn new() -> SubstitutionTable { |
100 | 15.3k | Default::default() |
101 | 15.3k | } |
102 | | |
103 | | /// Insert a freshly-parsed substitutable component into the table and |
104 | | /// return the index at which it now lives. |
105 | 1.33M | pub fn insert(&mut self, entity: Substitutable) -> usize { |
106 | 1.33M | let idx = self.substitutions.len(); |
107 | 1.33M | log!("SubstitutionTable::insert @ {}: {:?}", idx, entity); |
108 | 1.33M | self.substitutions.push(entity); |
109 | 1.33M | idx |
110 | 1.33M | } |
111 | | |
112 | | /// Insert a an entity into the table that is not a candidate for |
113 | | /// substitution. |
114 | 1.18k | pub fn insert_non_substitution(&mut self, entity: Substitutable) -> usize { |
115 | 1.18k | let idx = self.non_substitutions.len(); |
116 | 1.18k | self.non_substitutions.push(entity); |
117 | 1.18k | idx |
118 | 1.18k | } |
119 | | |
120 | | /// Does this substitution table contain a component at the given index? |
121 | 22.6k | pub fn contains(&self, idx: usize) -> bool { |
122 | 22.6k | idx < self.substitutions.len() |
123 | 22.6k | } |
124 | | |
125 | | /// Get the type referenced by the given handle, or None if there is no such |
126 | | /// entry, or there is an entry that is not a type. |
127 | 8.22k | pub fn get_type(&self, handle: &ast::TypeHandle) -> Option<&ast::Type> { |
128 | 8.22k | if let ast::TypeHandle::BackReference(idx) = *handle { |
129 | 8.05k | self.substitutions.get(idx).and_then(|s| match *s { |
130 | 8.05k | Substitutable::Type(ref ty) => Some(ty), |
131 | 0 | _ => None, |
132 | 8.05k | }) |
133 | | } else { |
134 | 168 | None |
135 | | } |
136 | 8.22k | } |
137 | | |
138 | | /// Remove the last entry from the substitutions table and return it, or |
139 | | /// `None` if the table is empty. |
140 | 0 | pub fn pop(&mut self) -> Option<Substitutable> { |
141 | 0 | log!("SubstitutionTable::pop @ {}: {:?}", self.len(), self.last()); |
142 | 0 | self.substitutions.pop() |
143 | 0 | } |
144 | | |
145 | | /// Get the `idx`th entity that is not a candidate for substitution. Panics |
146 | | /// if `idx` is out of bounds. |
147 | 0 | pub fn non_substitution(&self, idx: usize) -> &Substitutable { |
148 | 0 | &self.non_substitutions[idx] |
149 | 0 | } |
150 | | |
151 | | /// Get the `idx`th entity that is not a candidate for substitution. Returns |
152 | | /// `None` if `idx` is out of bounds. |
153 | 1.18k | pub fn get_non_substitution(&self, idx: usize) -> Option<&Substitutable> { |
154 | 1.18k | self.non_substitutions.get(idx) |
155 | 1.18k | } |
156 | | } |
157 | | |
158 | | impl FromIterator<Substitutable> for SubstitutionTable { |
159 | 0 | fn from_iter<I: IntoIterator<Item = Substitutable>>(iter: I) -> Self { |
160 | 0 | SubstitutionTable { |
161 | 0 | substitutions: Vec::from_iter(iter), |
162 | 0 | non_substitutions: vec![], |
163 | 0 | } |
164 | 0 | } |
165 | | } |
166 | | |
167 | | impl Deref for SubstitutionTable { |
168 | | type Target = [Substitutable]; |
169 | | |
170 | 83.0k | fn deref(&self) -> &Self::Target { |
171 | 83.0k | &self.substitutions[..] |
172 | 83.0k | } |
173 | | } |