Coverage Report

Created: 2023-04-25 07:07

/rust/registry/src/index.crates.io-6f17d22bba15001f/cpp_demangle-0.3.5/src/ast.rs
Line
Count
Source (jump to first uncovered line)
1
//! Abstract syntax tree types for mangled symbols.
2
3
use super::{DemangleNodeType, DemangleOptions, DemangleWrite, ParseOptions};
4
use boxed::Box;
5
use error::{self, Result};
6
use index_str::IndexStr;
7
use std::cell::Cell;
8
#[cfg(feature = "logging")]
9
use std::cell::RefCell;
10
use std::fmt::{self, Write};
11
use std::hash::{Hash, Hasher};
12
use std::mem;
13
use std::ops;
14
use std::ptr;
15
use string::String;
16
use subs::{Substitutable, SubstitutionTable};
17
use vec::Vec;
18
19
struct AutoLogParse;
20
21
#[cfg(feature = "logging")]
22
thread_local! {
23
    static LOG_DEPTH: RefCell<usize> = RefCell::new(0);
24
}
25
26
impl AutoLogParse {
27
    #[cfg(feature = "logging")]
28
    fn new(production: &'static str, input: IndexStr<'_>) -> AutoLogParse {
29
        LOG_DEPTH.with(|depth| {
30
            if *depth.borrow() == 0 {
31
                println!();
32
            }
33
34
            let indent: String = (0..*depth.borrow() * 4).map(|_| ' ').collect();
35
            log!(
36
                "{}({} \"{}\" {}",
37
                indent,
38
                production,
39
                String::from_utf8_lossy(input.as_ref()),
40
                input.len(),
41
            );
42
            *depth.borrow_mut() += 1;
43
        });
44
        AutoLogParse
45
    }
46
47
    #[cfg(not(feature = "logging"))]
48
    #[inline(always)]
49
74.7M
    fn new(_: &'static str, _: IndexStr) -> AutoLogParse {
50
74.7M
        AutoLogParse
51
74.7M
    }
52
}
53
54
#[cfg(feature = "logging")]
55
impl Drop for AutoLogParse {
56
    fn drop(&mut self) {
57
        LOG_DEPTH.with(|depth| {
58
            *depth.borrow_mut() -= 1;
59
            let indent: String = (0..*depth.borrow() * 4).map(|_| ' ').collect();
60
            log!("{})", indent);
61
        });
62
    }
63
}
64
65
/// Performs the two operations that begin every parse:
66
///
67
/// 1. Keeps track of recursion levels and early returns with an error if there
68
///    is too much recursion.
69
///
70
/// 2. Automatically log start and end parsing in an s-expression format, when the
71
///    `logging` feature is enabled.
72
macro_rules! try_begin_parse {
73
    ( $production:expr , $ctx:expr , $input:expr ) => {
74
        let _log = AutoLogParse::new($production, $input);
75
        let _auto_check_recursion = AutoParseRecursion::new($ctx)?;
76
    };
77
}
78
79
struct AutoLogDemangle;
80
81
impl AutoLogDemangle {
82
    #[cfg(feature = "logging")]
83
    fn new<P, W>(
84
        production: &P,
85
        ctx: &DemangleContext<W>,
86
        scope: Option<ArgScopeStack>,
87
        is_inner: bool,
88
    ) -> AutoLogDemangle
89
    where
90
        P: ?Sized + fmt::Debug,
91
        W: DemangleWrite,
92
    {
93
        LOG_DEPTH.with(|depth| {
94
            if *depth.borrow() == 0 {
95
                println!();
96
            }
97
98
            let indent: String = (0..*depth.borrow() * 4).map(|_| ' ').collect();
99
            log!("{}(", indent);
100
            log!(
101
                "{}  {}{:?}",
102
                indent,
103
                if is_inner { "as_inner: " } else { "" },
104
                production
105
            );
106
            log!("{}  inner = {:?}", indent, ctx.inner);
107
            log!("{}  scope = {:?}", indent, scope);
108
109
            *depth.borrow_mut() += 1;
110
        });
111
        AutoLogDemangle
112
    }
113
114
    #[cfg(not(feature = "logging"))]
115
    #[inline(always)]
116
0
    fn new<P, W>(
117
0
        _: &P,
118
0
        _: &DemangleContext<W>,
119
0
        _: Option<ArgScopeStack>,
120
0
        _: bool,
121
0
    ) -> AutoLogDemangle
122
0
    where
123
0
        P: ?Sized + fmt::Debug,
124
0
        W: DemangleWrite,
125
0
    {
126
0
        AutoLogDemangle
127
0
    }
Unexecuted instantiation: <cpp_demangle::ast::AutoLogDemangle>::new::<cpp_demangle::ast::VectorType, alloc::string::String>
Unexecuted instantiation: <cpp_demangle::ast::AutoLogDemangle>::new::<cpp_demangle::ast::BaseUnresolvedName, alloc::string::String>
Unexecuted instantiation: <cpp_demangle::ast::AutoLogDemangle>::new::<cpp_demangle::ast::UnresolvedQualifierLevel, alloc::string::String>
Unexecuted instantiation: <cpp_demangle::ast::AutoLogDemangle>::new::<cpp_demangle::ast::NestedName, alloc::string::String>
Unexecuted instantiation: <cpp_demangle::ast::AutoLogDemangle>::new::<cpp_demangle::ast::UnresolvedName, alloc::string::String>
Unexecuted instantiation: <cpp_demangle::ast::AutoLogDemangle>::new::<cpp_demangle::ast::TemplateArg, alloc::string::String>
Unexecuted instantiation: <cpp_demangle::ast::AutoLogDemangle>::new::<cpp_demangle::ast::CvQualifiers, alloc::string::String>
Unexecuted instantiation: <cpp_demangle::ast::AutoLogDemangle>::new::<cpp_demangle::ast::SourceName, alloc::string::String>
Unexecuted instantiation: <cpp_demangle::ast::AutoLogDemangle>::new::<cpp_demangle::ast::RefQualifier, alloc::string::String>
Unexecuted instantiation: <cpp_demangle::ast::AutoLogDemangle>::new::<cpp_demangle::ast::PointerToMemberType, alloc::string::String>
Unexecuted instantiation: <cpp_demangle::ast::AutoLogDemangle>::new::<cpp_demangle::ast::ResourceName, alloc::string::String>
Unexecuted instantiation: <cpp_demangle::ast::AutoLogDemangle>::new::<cpp_demangle::ast::OperatorName, alloc::string::String>
Unexecuted instantiation: <cpp_demangle::ast::AutoLogDemangle>::new::<cpp_demangle::ast::LocalName, alloc::string::String>
Unexecuted instantiation: <cpp_demangle::ast::AutoLogDemangle>::new::<cpp_demangle::ast::TemplateArgs, alloc::string::String>
Unexecuted instantiation: <cpp_demangle::ast::AutoLogDemangle>::new::<cpp_demangle::ast::UnnamedTypeName, alloc::string::String>
Unexecuted instantiation: <cpp_demangle::ast::AutoLogDemangle>::new::<cpp_demangle::ast::QualifiedBuiltin, alloc::string::String>
Unexecuted instantiation: <cpp_demangle::ast::AutoLogDemangle>::new::<cpp_demangle::ast::TaggedName, alloc::string::String>
Unexecuted instantiation: <cpp_demangle::ast::AutoLogDemangle>::new::<cpp_demangle::ast::UnscopedName, alloc::string::String>
Unexecuted instantiation: <cpp_demangle::ast::AutoLogDemangle>::new::<cpp_demangle::ast::ClassEnumType, alloc::string::String>
Unexecuted instantiation: <cpp_demangle::ast::AutoLogDemangle>::new::<cpp_demangle::ast::SimpleOperatorName, alloc::string::String>
Unexecuted instantiation: <cpp_demangle::ast::AutoLogDemangle>::new::<cpp_demangle::ast::MangledName, alloc::string::String>
Unexecuted instantiation: <cpp_demangle::ast::AutoLogDemangle>::new::<cpp_demangle::ast::TemplateTemplateParam, alloc::string::String>
Unexecuted instantiation: <cpp_demangle::ast::AutoLogDemangle>::new::<cpp_demangle::ast::Expression, alloc::string::String>
Unexecuted instantiation: <cpp_demangle::ast::AutoLogDemangle>::new::<cpp_demangle::ast::Encoding, alloc::string::String>
Unexecuted instantiation: <cpp_demangle::ast::AutoLogDemangle>::new::<cpp_demangle::ast::CloneTypeIdentifier, alloc::string::String>
Unexecuted instantiation: <cpp_demangle::ast::AutoLogDemangle>::new::<cpp_demangle::ast::ClosureTypeName, alloc::string::String>
Unexecuted instantiation: <cpp_demangle::ast::AutoLogDemangle>::new::<cpp_demangle::ast::UnscopedTemplateName, alloc::string::String>
Unexecuted instantiation: <cpp_demangle::ast::AutoLogDemangle>::new::<cpp_demangle::ast::UnqualifiedName, alloc::string::String>
Unexecuted instantiation: <cpp_demangle::ast::AutoLogDemangle>::new::<cpp_demangle::ast::ArrayType, alloc::string::String>
Unexecuted instantiation: <cpp_demangle::ast::AutoLogDemangle>::new::<cpp_demangle::ast::Prefix, alloc::string::String>
Unexecuted instantiation: <cpp_demangle::ast::AutoLogDemangle>::new::<cpp_demangle::ast::Type, alloc::string::String>
Unexecuted instantiation: <cpp_demangle::ast::AutoLogDemangle>::new::<cpp_demangle::ast::BuiltinType, alloc::string::String>
Unexecuted instantiation: <cpp_demangle::ast::AutoLogDemangle>::new::<cpp_demangle::ast::BareFunctionType, alloc::string::String>
Unexecuted instantiation: <cpp_demangle::ast::AutoLogDemangle>::new::<cpp_demangle::ast::Decltype, alloc::string::String>
Unexecuted instantiation: <cpp_demangle::ast::AutoLogDemangle>::new::<cpp_demangle::ast::CloneSuffix, alloc::string::String>
Unexecuted instantiation: <cpp_demangle::ast::AutoLogDemangle>::new::<cpp_demangle::ast::LambdaSig, alloc::string::String>
Unexecuted instantiation: <cpp_demangle::ast::AutoLogDemangle>::new::<cpp_demangle::ast::FunctionArgSlice, alloc::string::String>
Unexecuted instantiation: <cpp_demangle::ast::AutoLogDemangle>::new::<cpp_demangle::ast::CtorDtorName, alloc::string::String>
Unexecuted instantiation: <cpp_demangle::ast::AutoLogDemangle>::new::<cpp_demangle::ast::ExprPrimary, alloc::string::String>
Unexecuted instantiation: <cpp_demangle::ast::AutoLogDemangle>::new::<cpp_demangle::ast::Initializer, alloc::string::String>
Unexecuted instantiation: <cpp_demangle::ast::AutoLogDemangle>::new::<cpp_demangle::ast::FunctionType, alloc::string::String>
Unexecuted instantiation: <cpp_demangle::ast::AutoLogDemangle>::new::<cpp_demangle::ast::WellKnownComponent, alloc::string::String>
Unexecuted instantiation: <cpp_demangle::ast::AutoLogDemangle>::new::<cpp_demangle::ast::Identifier, alloc::string::String>
Unexecuted instantiation: <cpp_demangle::ast::AutoLogDemangle>::new::<cpp_demangle::ast::SpecialName, alloc::string::String>
Unexecuted instantiation: <cpp_demangle::ast::AutoLogDemangle>::new::<cpp_demangle::ast::UnresolvedType, alloc::string::String>
Unexecuted instantiation: <cpp_demangle::ast::AutoLogDemangle>::new::<cpp_demangle::ast::StandardBuiltinType, alloc::string::String>
Unexecuted instantiation: <cpp_demangle::ast::AutoLogDemangle>::new::<cpp_demangle::ast::DataMemberPrefix, alloc::string::String>
Unexecuted instantiation: <cpp_demangle::ast::AutoLogDemangle>::new::<cpp_demangle::ast::SimpleId, alloc::string::String>
Unexecuted instantiation: <cpp_demangle::ast::AutoLogDemangle>::new::<cpp_demangle::ast::CallOffset, alloc::string::String>
Unexecuted instantiation: <cpp_demangle::ast::AutoLogDemangle>::new::<cpp_demangle::ast::GlobalCtorDtor, alloc::string::String>
Unexecuted instantiation: <cpp_demangle::ast::AutoLogDemangle>::new::<cpp_demangle::ast::Name, alloc::string::String>
Unexecuted instantiation: <cpp_demangle::ast::AutoLogDemangle>::new::<cpp_demangle::ast::FunctionParam, alloc::string::String>
Unexecuted instantiation: <cpp_demangle::ast::AutoLogDemangle>::new::<cpp_demangle::ast::DestructorName, alloc::string::String>
Unexecuted instantiation: <cpp_demangle::ast::AutoLogDemangle>::new::<cpp_demangle::ast::TemplateParam, alloc::string::String>
Unexecuted instantiation: <cpp_demangle::ast::AutoLogDemangle>::new::<cpp_demangle::ast::MemberName, alloc::string::String>
Unexecuted instantiation: <cpp_demangle::ast::AutoLogDemangle>::new::<_, _>
128
}
129
130
#[cfg(feature = "logging")]
131
impl Drop for AutoLogDemangle {
132
    fn drop(&mut self) {
133
        LOG_DEPTH.with(|depth| {
134
            *depth.borrow_mut() -= 1;
135
            let indent: String = (0..*depth.borrow() * 4).map(|_| ' ').collect();
136
            log!("{})", indent);
137
        });
138
    }
139
}
140
141
/// Automatically log start and end demangling in an s-expression format, when
142
/// the `logging` feature is enabled.
143
macro_rules! try_begin_demangle {
144
    ( $production:expr, $ctx:expr, $scope:expr ) => {{
145
        let _log = AutoLogDemangle::new($production, $ctx, $scope, false);
146
        &mut AutoParseDemangle::new($ctx)?
147
    }};
148
}
149
150
/// Automatically log start and end demangling in an s-expression format, when
151
/// the `logging` feature is enabled.
152
macro_rules! try_begin_demangle_as_inner {
153
    ( $production:expr, $ctx:expr, $scope:expr ) => {{
154
        let _log = AutoLogDemangle::new($production, $ctx, $scope, true);
155
        &mut AutoParseDemangle::new($ctx)?
156
    }};
157
}
158
159
1.69M
#[derive(Debug, Default, Clone, Copy)]
160
struct ParseContextState {
161
    // The current recursion level. Should always be less than or equal to the
162
    // maximum.
163
    recursion_level: u32,
164
    // Whether or not we are currently parsing a conversion operator.
165
    in_conversion: bool,
166
}
167
168
/// Common context needed when parsing.
169
0
#[derive(Debug, Clone)]
170
pub struct ParseContext {
171
    // Maximum amount of recursive parsing calls we will allow. If this is too
172
    // large, we can blow the stack.
173
    max_recursion: u32,
174
    // Mutable state within the `ParseContext`.
175
    state: Cell<ParseContextState>,
176
}
177
178
impl ParseContext {
179
    /// Construct a new `ParseContext`.
180
1.69M
    pub fn new(options: ParseOptions) -> ParseContext {
181
1.69M
        ParseContext {
182
1.69M
            max_recursion: options.recursion_limit.map(|v| v.get()).unwrap_or(96),
183
1.69M
            state: Cell::new(ParseContextState::default()),
184
1.69M
        }
185
1.69M
    }
186
187
    /// Get the current recursion level for this context.
188
0
    pub fn recursion_level(&self) -> u32 {
189
0
        self.state.get().recursion_level
190
0
    }
191
192
    #[inline]
193
74.7M
    fn enter_recursion(&self) -> error::Result<()> {
194
74.7M
        let mut state = self.state.get();
195
74.7M
        let new_recursion_level = state.recursion_level + 1;
196
74.7M
197
74.7M
        if new_recursion_level >= self.max_recursion {
198
0
            log!("Hit too much recursion at level {}", self.max_recursion);
199
0
            Err(error::Error::TooMuchRecursion)
200
        } else {
201
74.7M
            state.recursion_level = new_recursion_level;
202
74.7M
            self.state.set(state);
203
74.7M
            Ok(())
204
        }
205
74.7M
    }
206
207
    #[inline]
208
74.7M
    fn exit_recursion(&self) {
209
74.7M
        let mut state = self.state.get();
210
0
        debug_assert!(state.recursion_level >= 1);
211
74.7M
        state.recursion_level -= 1;
212
74.7M
        self.state.set(state);
213
74.7M
    }
214
215
    #[inline]
216
0
    fn in_conversion(&self) -> bool {
217
0
        self.state.get().in_conversion
218
0
    }
219
220
0
    fn set_in_conversion(&self, in_conversion: bool) -> bool {
221
0
        let mut state = self.state.get();
222
0
        let previously_in_conversion = state.in_conversion;
223
0
        state.in_conversion = in_conversion;
224
0
        self.state.set(state);
225
0
        previously_in_conversion
226
0
    }
227
}
228
229
/// An RAII type to automatically check the recursion level against the
230
/// maximum. If the maximum has been crossed, return an error. Otherwise,
231
/// increment the level upon construction, and decrement it upon destruction.
232
struct AutoParseRecursion<'a>(&'a ParseContext);
233
234
impl<'a> AutoParseRecursion<'a> {
235
    #[inline]
236
    fn new(ctx: &'a ParseContext) -> error::Result<AutoParseRecursion<'a>> {
237
74.7M
        ctx.enter_recursion()?;
238
74.7M
        Ok(AutoParseRecursion(ctx))
239
74.7M
    }
240
}
241
242
impl<'a> Drop for AutoParseRecursion<'a> {
243
    #[inline]
244
74.7M
    fn drop(&mut self) {
245
74.7M
        self.0.exit_recursion();
246
74.7M
    }
247
}
248
249
/// A trait for anything that can be parsed from an `IndexStr` and return a
250
/// `Result` of the parsed `Self` value and the rest of the `IndexStr` input
251
/// that has not been consumed in parsing the `Self` value.
252
///
253
/// For AST types representing productions which have `<substitution>` as a
254
/// possible right hand side, do not implement this trait directly. Instead,
255
/// make a newtype over `usize`, parse either the `<substitution>` back
256
/// reference or "real" value, insert the "real" value into the substitution
257
/// table if needed, and *always* return the newtype index into the substitution
258
/// table.
259
#[doc(hidden)]
260
pub trait Parse: Sized {
261
    /// Parse the `Self` value from `input` and return it, updating the
262
    /// substitution table as needed.
263
    fn parse<'a, 'b>(
264
        ctx: &'a ParseContext,
265
        subs: &'a mut SubstitutionTable,
266
        input: IndexStr<'b>,
267
    ) -> Result<(Self, IndexStr<'b>)>;
268
}
269
270
/// Determine whether this AST node is an instantiated[*] template function, and
271
/// get its concrete template arguments.
272
///
273
/// [*] Note that we will never see an abstract, un-instantiated template
274
/// function, since they don't end up in object files and don't get mangled
275
/// names.
276
trait GetTemplateArgs {
277
    /// Returns `Some` if this is a template function, `None` otherwise.
278
    fn get_template_args<'a>(&'a self, subs: &'a SubstitutionTable) -> Option<&'a TemplateArgs>;
279
}
280
281
/// A leaf name is the part the name that describes some type or class without
282
/// any leading namespace qualifiers.
283
///
284
/// This is used when figuring out how to format constructors and destructors,
285
/// which are formatted as `gooble::dodo::Thing::~Thing()` but we don't have
286
/// direct access to `Thing` in the `CtorDtorName` AST.
287
0
#[derive(Debug)]
288
pub(crate) enum LeafName<'a> {
289
    SourceName(&'a SourceName),
290
    WellKnownComponent(&'a WellKnownComponent),
291
    Closure(&'a ClosureTypeName),
292
    UnnamedType(&'a UnnamedTypeName),
293
}
294
295
impl<'subs, W> DemangleAsLeaf<'subs, W> for LeafName<'subs>
296
where
297
    W: 'subs + DemangleWrite,
298
{
299
0
    fn demangle_as_leaf<'me, 'ctx>(
300
0
        &'me self,
301
0
        ctx: &'ctx mut DemangleContext<'subs, W>,
302
0
    ) -> fmt::Result {
303
0
        match *self {
304
0
            LeafName::SourceName(sn) => sn.demangle(ctx, None),
305
0
            LeafName::Closure(c) => c.demangle(ctx, None),
306
0
            LeafName::WellKnownComponent(wkc) => wkc.demangle_as_leaf(ctx),
307
0
            LeafName::UnnamedType(utn) => utn.demangle_as_leaf(ctx),
308
        }
309
0
    }
Unexecuted instantiation: <cpp_demangle::ast::LeafName as cpp_demangle::ast::DemangleAsLeaf<alloc::string::String>>::demangle_as_leaf
Unexecuted instantiation: <cpp_demangle::ast::LeafName as cpp_demangle::ast::DemangleAsLeaf<_>>::demangle_as_leaf
310
}
311
312
/// Determine whether this AST node is some kind (potentially namespaced) name
313
/// and if so get its leaf name.
314
pub(crate) trait GetLeafName<'a> {
315
    fn get_leaf_name(&'a self, subs: &'a SubstitutionTable) -> Option<LeafName<'a>>;
316
}
317
318
/// Determine whether this AST node is a constructor, destructor, or conversion
319
/// function.
320
pub(crate) trait IsCtorDtorConversion {
321
    fn is_ctor_dtor_conversion(&self, subs: &SubstitutionTable) -> bool;
322
}
323
324
/// When formatting a mangled symbol's parsed AST as a demangled symbol, we need
325
/// to resolve indirect references to template and function arguments with
326
/// direct `TemplateArg` and `Type` references respectively.
327
///
328
/// Note that which set of arguments are implicitly referenced change as we
329
/// enter and leave different functions' scope. One might usually use de Brujin
330
/// indices to keep arguments within scopes separated from each other, but the
331
/// Itanium C++ ABI does not allow us the luxury. AFAIK, when the ABI was first
332
/// drafted, C++ did not have lambdas, and the issue did not come up at all
333
/// since a function simply couldn't refer to the types of closed over
334
/// variables.
335
///
336
/// This trait is implemented by anything that can potentially resolve arguments
337
/// for us.
338
trait ArgScope<'me, 'ctx>: fmt::Debug {
339
    /// Get the current scope's leaf name.
340
    fn leaf_name(&'me self) -> Result<LeafName<'ctx>>;
341
342
    /// Get the current scope's `index`th template argument.
343
    fn get_template_arg(&'me self, index: usize)
344
        -> Result<(&'ctx TemplateArg, &'ctx TemplateArgs)>;
345
346
    /// Get the current scope's `index`th function argument's type.
347
    fn get_function_arg(&'me self, index: usize) -> Result<&'ctx Type>;
348
}
349
350
/// An `ArgScopeStack` represents the current function and template demangling
351
/// scope we are within. As we enter new demangling scopes, we construct new
352
/// `ArgScopeStack`s whose `prev` references point back to the old ones. These
353
/// `ArgScopeStack`s are kept on the native stack, and as functions return, they
354
/// go out of scope and we use the previous `ArgScopeStack`s again.
355
0
#[derive(Copy, Clone, Debug)]
356
pub struct ArgScopeStack<'prev, 'subs>
357
where
358
    'subs: 'prev,
359
{
360
    item: &'subs dyn ArgScope<'subs, 'subs>,
361
    in_arg: Option<(usize, &'subs TemplateArgs)>,
362
    prev: Option<&'prev ArgScopeStack<'prev, 'subs>>,
363
}
364
365
/// When we first begin demangling, we haven't entered any function or template
366
/// demangling scope and we don't have any useful `ArgScopeStack`. Therefore, we
367
/// are never actually dealing with `ArgScopeStack` directly in practice, but
368
/// always an `Option<ArgScopeStack>` instead. Nevertheless, we want to define
369
/// useful methods on `Option<ArgScopeStack>`.
370
///
371
/// A custom "extension" trait with exactly one implementor: Rust's principled
372
/// monkey patching!
373
trait ArgScopeStackExt<'prev, 'subs>: Copy {
374
    /// Push a new `ArgScope` onto this `ArgScopeStack` and return the new
375
    /// `ArgScopeStack` with the pushed resolver on top.
376
    fn push(
377
        &'prev self,
378
        item: &'subs dyn ArgScope<'subs, 'subs>,
379
    ) -> Option<ArgScopeStack<'prev, 'subs>>;
380
}
381
382
impl<'prev, 'subs> ArgScopeStackExt<'prev, 'subs> for Option<ArgScopeStack<'prev, 'subs>> {
383
0
    fn push(
384
0
        &'prev self,
385
0
        item: &'subs dyn ArgScope<'subs, 'subs>,
386
0
    ) -> Option<ArgScopeStack<'prev, 'subs>> {
387
0
        log!("ArgScopeStack::push: {:?}", item);
388
0
        Some(ArgScopeStack {
389
0
            prev: self.as_ref(),
390
0
            in_arg: None,
391
0
            item: item,
392
0
        })
393
0
    }
394
}
395
396
/// A stack of `ArgScope`s is itself an `ArgScope`!
397
impl<'prev, 'subs> ArgScope<'prev, 'subs> for Option<ArgScopeStack<'prev, 'subs>> {
398
0
    fn leaf_name(&'prev self) -> Result<LeafName<'subs>> {
399
0
        let mut scope = self.as_ref();
400
0
        while let Some(s) = scope {
401
0
            if let Ok(c) = s.item.leaf_name() {
402
0
                return Ok(c);
403
0
            }
404
0
            scope = s.prev;
405
        }
406
0
        Err(error::Error::BadLeafNameReference)
407
0
    }
408
409
0
    fn get_template_arg(
410
0
        &'prev self,
411
0
        idx: usize,
412
0
    ) -> Result<(&'subs TemplateArg, &'subs TemplateArgs)> {
413
0
        let mut scope = self.as_ref();
414
0
        while let Some(s) = scope {
415
0
            if let Ok((arg, args)) = s.item.get_template_arg(idx) {
416
0
                if let Some((in_idx, in_args)) = s.in_arg {
417
0
                    if args as *const TemplateArgs == in_args as *const TemplateArgs
418
0
                        && in_idx <= idx
419
                    {
420
0
                        return Err(error::Error::ForwardTemplateArgReference);
421
0
                    }
422
0
                }
423
0
                return Ok((arg, args));
424
0
            }
425
0
            scope = s.prev;
426
        }
427
428
0
        Err(error::Error::BadTemplateArgReference)
429
0
    }
430
431
0
    fn get_function_arg(&'prev self, idx: usize) -> Result<&'subs Type> {
432
0
        let mut scope = self.as_ref();
433
0
        while let Some(s) = scope {
434
0
            if let Ok(arg) = s.item.get_function_arg(idx) {
435
0
                return Ok(arg);
436
0
            }
437
0
            scope = s.prev;
438
        }
439
440
0
        Err(error::Error::BadFunctionArgReference)
441
0
    }
442
}
443
444
0
#[derive(Debug, Copy, Clone)]
445
struct DemangleState {
446
    /// How deep in the demangling are we?
447
    pub recursion_level: u32,
448
}
449
450
/// An RAII type to automatically check the recursion level against the
451
/// maximum. If the maximum has been crossed, return an error. Otherwise,
452
/// increment the level upon construction, and decrement it upon destruction.
453
struct AutoParseDemangle<'a, 'b, W: 'a + DemangleWrite>(&'b mut DemangleContext<'a, W>);
454
455
impl<'a, 'b, W: 'a + DemangleWrite> AutoParseDemangle<'a, 'b, W> {
456
    #[inline]
457
    fn new(ctx: &'b mut DemangleContext<'a, W>) -> std::result::Result<Self, fmt::Error> {
458
0
        ctx.enter_recursion()?;
459
0
        Ok(AutoParseDemangle(ctx))
460
0
    }
Unexecuted instantiation: <cpp_demangle::ast::AutoParseDemangle<alloc::string::String>>::new
Unexecuted instantiation: <cpp_demangle::ast::AutoParseDemangle<_>>::new
461
}
462
463
impl<'a, 'b, W: 'a + DemangleWrite> std::ops::Deref for AutoParseDemangle<'a, 'b, W> {
464
    type Target = DemangleContext<'a, W>;
465
466
0
    fn deref(&self) -> &Self::Target {
467
0
        self.0
468
0
    }
Unexecuted instantiation: <cpp_demangle::ast::AutoParseDemangle<alloc::string::String> as core::ops::deref::Deref>::deref
Unexecuted instantiation: <cpp_demangle::ast::AutoParseDemangle<_> as core::ops::deref::Deref>::deref
469
}
470
471
impl<'a, 'b, W: 'a + DemangleWrite> std::ops::DerefMut for AutoParseDemangle<'a, 'b, W> {
472
0
    fn deref_mut(&mut self) -> &mut Self::Target {
473
0
        self.0
474
0
    }
Unexecuted instantiation: <cpp_demangle::ast::AutoParseDemangle<alloc::string::String> as core::ops::deref::DerefMut>::deref_mut
Unexecuted instantiation: <cpp_demangle::ast::AutoParseDemangle<_> as core::ops::deref::DerefMut>::deref_mut
475
}
476
477
impl<'a, 'b, W: 'a + DemangleWrite> Drop for AutoParseDemangle<'a, 'b, W> {
478
    #[inline]
479
0
    fn drop(&mut self) {
480
0
        self.0.exit_recursion();
481
0
    }
Unexecuted instantiation: <cpp_demangle::ast::AutoParseDemangle<alloc::string::String> as core::ops::drop::Drop>::drop
Unexecuted instantiation: <cpp_demangle::ast::AutoParseDemangle<_> as core::ops::drop::Drop>::drop
482
}
483
484
/// Common state that is required when demangling a mangled symbol's parsed AST.
485
#[doc(hidden)]
486
0
#[derive(Debug)]
487
pub struct DemangleContext<'a, W>
488
where
489
    W: 'a + DemangleWrite,
490
{
491
    // The substitution table built up when parsing the mangled symbol into an
492
    // AST.
493
    subs: &'a SubstitutionTable,
494
495
    // The maximum recursion
496
    max_recursion: u32,
497
498
    // Sometimes an AST node needs to insert itself as an inner item within one
499
    // of its children when demangling that child. For example, the AST
500
    //
501
    //     (array 10 int)
502
    //
503
    // is demangled as `int[10]`, but if we were to demangle the AST
504
    //
505
    //     (lvalue-ref (array 10 int))
506
    //
507
    // then we would want this demangled form: `int (&) [10]`, which requires
508
    // the parent lvalue-ref to be passed into the child array's demangling
509
    // method. This kind of thing also pops up with function pointers.
510
    //
511
    // The `inner` stack enables such behavior by allowing us to pass AST
512
    // parents down to their children as inner items.
513
    inner: Vec<&'a dyn DemangleAsInner<'a, W>>,
514
515
    // The original input string.
516
    input: &'a [u8],
517
518
    // `Identifier`s will be placed here, so `UnnamedTypeName` can utilize and print
519
    // out the Constructor/Destructor used.
520
    source_name: Option<&'a str>,
521
522
    // What the demangled name is being written to.
523
    out: &'a mut W,
524
525
    // The total number of bytes written to `out`. This is maintained by the
526
    // `Write` implementation for `DemangleContext`.
527
    bytes_written: usize,
528
529
    // The last char written to `out`, if any.
530
    last_char_written: Option<char>,
531
532
    // We are currently demangling a lambda argument, so template substitution
533
    // should be suppressed to match libiberty.
534
    is_lambda_arg: bool,
535
536
    // We are currently demangling a template-prefix.
537
    is_template_prefix: bool,
538
539
    // We are currently demangling a template-prefix in a nested-name.
540
    is_template_prefix_in_nested_name: bool,
541
542
    //  `PackExpansion`'s should only print '...', only when there is no template
543
    //  argument pack.
544
    is_template_argument_pack: bool,
545
546
    // Whether to show function parameters.
547
    // This must be set to true before calling `demangle` on `Encoding`
548
    // unless that call is via the toplevel call to `MangledName::demangle`.
549
    show_params: bool,
550
551
    // Whether to show function return types.
552
    // This must be set to true before calling `demangle` on `Encoding`
553
    // unless that call is via the toplevel call to `MangledName::demangle`.
554
    show_return_type: bool,
555
556
    // Whether to show types of expression literals.
557
    show_expression_literal_types: bool,
558
559
    // recursion protection.
560
    state: Cell<DemangleState>,
561
}
562
563
impl<'a, W> fmt::Write for DemangleContext<'a, W>
564
where
565
    W: 'a + DemangleWrite,
566
{
567
0
    fn write_str(&mut self, s: &str) -> fmt::Result {
568
0
        if s.is_empty() {
569
0
            return Ok(());
570
0
        }
571
0
572
0
        log!("DemangleContext::write: '{}'", s);
573
574
0
        self.out.write_string(s).map(|_| {
575
0
            self.last_char_written = s.chars().last();
576
0
            self.bytes_written += s.len();
577
0
        })
Unexecuted instantiation: <cpp_demangle::ast::DemangleContext<alloc::string::String> as core::fmt::Write>::write_str::{closure#0}
Unexecuted instantiation: <cpp_demangle::ast::DemangleContext<_> as core::fmt::Write>::write_str::{closure#0}
578
0
    }
Unexecuted instantiation: <cpp_demangle::ast::DemangleContext<alloc::string::String> as core::fmt::Write>::write_str
Unexecuted instantiation: <cpp_demangle::ast::DemangleContext<_> as core::fmt::Write>::write_str
579
}
580
581
impl<'a, W> DemangleContext<'a, W>
582
where
583
    W: 'a + DemangleWrite,
584
{
585
    /// Construct a new `DemangleContext`.
586
0
    pub fn new(
587
0
        subs: &'a SubstitutionTable,
588
0
        input: &'a [u8],
589
0
        options: DemangleOptions,
590
0
        out: &'a mut W,
591
0
    ) -> DemangleContext<'a, W> {
592
0
        DemangleContext {
593
0
            subs: subs,
594
0
            max_recursion: options.recursion_limit.map(|v| v.get()).unwrap_or(128),
Unexecuted instantiation: <cpp_demangle::ast::DemangleContext<alloc::string::String>>::new::{closure#0}
Unexecuted instantiation: <cpp_demangle::ast::DemangleContext<_>>::new::{closure#0}
595
0
            inner: vec![],
596
0
            input: input,
597
0
            source_name: None,
598
0
            out: out,
599
0
            bytes_written: 0,
600
0
            last_char_written: None,
601
0
            is_lambda_arg: false,
602
0
            is_template_prefix: false,
603
0
            is_template_prefix_in_nested_name: false,
604
0
            is_template_argument_pack: false,
605
0
            show_params: !options.no_params,
606
0
            show_return_type: !options.no_return_type,
607
0
            show_expression_literal_types: !options.hide_expression_literal_types,
608
0
            state: Cell::new(DemangleState { recursion_level: 0 }),
609
0
        }
610
0
    }
Unexecuted instantiation: <cpp_demangle::ast::DemangleContext<alloc::string::String>>::new
Unexecuted instantiation: <cpp_demangle::ast::DemangleContext<_>>::new
611
612
    /// Get the current recursion level for this context.
613
0
    pub fn recursion_level(&self) -> u32 {
614
0
        self.state.get().recursion_level
615
0
    }
616
617
    #[inline]
618
0
    fn enter_recursion(&self) -> fmt::Result {
619
0
        let mut state = self.state.get();
620
0
        let new_recursion_level = state.recursion_level + 1;
621
0
622
0
        if new_recursion_level >= self.max_recursion {
623
0
            log!("Hit too much recursion at level {}", self.max_recursion);
624
0
            Err(Default::default())
625
        } else {
626
0
            state.recursion_level = new_recursion_level;
627
0
            self.state.set(state);
628
0
            Ok(())
629
        }
630
0
    }
Unexecuted instantiation: <cpp_demangle::ast::DemangleContext<alloc::string::String>>::enter_recursion
Unexecuted instantiation: <cpp_demangle::ast::DemangleContext<_>>::enter_recursion
631
632
    #[inline]
633
0
    fn exit_recursion(&self) {
634
0
        let mut state = self.state.get();
635
0
        debug_assert!(state.recursion_level >= 1);
636
0
        state.recursion_level -= 1;
637
0
        self.state.set(state);
638
0
    }
Unexecuted instantiation: <cpp_demangle::ast::DemangleContext<alloc::string::String>>::exit_recursion
Unexecuted instantiation: <cpp_demangle::ast::DemangleContext<_>>::exit_recursion
639
640
    #[inline]
641
0
    fn ensure(&mut self, ch: char) -> fmt::Result {
642
0
        if self.last_char_written == Some(ch) {
643
0
            Ok(())
644
        } else {
645
0
            write!(self, "{}", ch)?;
646
0
            Ok(())
647
        }
648
0
    }
Unexecuted instantiation: <cpp_demangle::ast::DemangleContext<alloc::string::String>>::ensure
Unexecuted instantiation: <cpp_demangle::ast::DemangleContext<_>>::ensure
649
650
    #[inline]
651
0
    fn ensure_space(&mut self) -> fmt::Result {
652
0
        self.ensure(' ')
653
0
    }
Unexecuted instantiation: <cpp_demangle::ast::DemangleContext<alloc::string::String>>::ensure_space
Unexecuted instantiation: <cpp_demangle::ast::DemangleContext<_>>::ensure_space
654
655
    #[inline]
656
0
    fn push_inner(&mut self, item: &'a dyn DemangleAsInner<'a, W>) {
657
0
        log!("DemangleContext::push_inner: {:?}", item);
658
0
        self.inner.push(item);
659
0
    }
Unexecuted instantiation: <cpp_demangle::ast::DemangleContext<alloc::string::String>>::push_inner
Unexecuted instantiation: <cpp_demangle::ast::DemangleContext<_>>::push_inner
660
661
    #[inline]
662
0
    fn pop_inner(&mut self) -> Option<&'a dyn DemangleAsInner<'a, W>> {
663
0
        let popped = self.inner.pop();
664
0
        log!("DemangleContext::pop_inner: {:?}", popped);
665
0
        popped
666
0
    }
Unexecuted instantiation: <cpp_demangle::ast::DemangleContext<alloc::string::String>>::pop_inner
Unexecuted instantiation: <cpp_demangle::ast::DemangleContext<_>>::pop_inner
667
668
    #[inline]
669
0
    fn pop_inner_if(&mut self, inner: &'a dyn DemangleAsInner<'a, W>) -> bool {
670
0
        let last = match self.inner.last() {
671
0
            None => return false,
672
0
            Some(last) => *last,
673
0
        };
674
0
675
0
        if ptr::eq(last, inner) {
676
0
            self.inner.pop();
677
0
            true
678
        } else {
679
0
            false
680
        }
681
0
    }
Unexecuted instantiation: <cpp_demangle::ast::DemangleContext<alloc::string::String>>::pop_inner_if
Unexecuted instantiation: <cpp_demangle::ast::DemangleContext<_>>::pop_inner_if
682
683
0
    fn demangle_inner_prefixes<'prev>(
684
0
        &mut self,
685
0
        scope: Option<ArgScopeStack<'prev, 'a>>,
686
0
    ) -> fmt::Result {
687
0
        log!("DemangleContext::demangle_inner_prefixes");
688
0
        let mut new_inner = vec![];
689
0
        while let Some(inner) = self.pop_inner() {
690
0
            if inner
691
0
                .downcast_to_function_type()
692
0
                .map_or(false, |f| !f.cv_qualifiers.is_empty())
Unexecuted instantiation: <cpp_demangle::ast::DemangleContext<alloc::string::String>>::demangle_inner_prefixes::{closure#0}
Unexecuted instantiation: <cpp_demangle::ast::DemangleContext<_>>::demangle_inner_prefixes::{closure#0}
693
            {
694
0
                log!(
695
0
                    "DemangleContext::demangle_inner_prefixes: not a prefix, saving: {:?}",
696
                    inner
697
                );
698
0
                new_inner.push(inner);
699
            } else {
700
0
                log!(
701
0
                    "DemangleContext::demangle_inner_prefixes: demangling prefix: {:?}",
702
                    inner
703
                );
704
0
                inner.demangle_as_inner(self, scope)?;
705
            }
706
        }
707
0
        new_inner.reverse();
708
0
        self.inner = new_inner;
709
0
        Ok(())
710
0
    }
Unexecuted instantiation: <cpp_demangle::ast::DemangleContext<alloc::string::String>>::demangle_inner_prefixes
Unexecuted instantiation: <cpp_demangle::ast::DemangleContext<_>>::demangle_inner_prefixes
711
712
0
    fn demangle_inners<'prev>(&mut self, scope: Option<ArgScopeStack<'prev, 'a>>) -> fmt::Result {
713
0
        while let Some(inner) = self.pop_inner() {
714
0
            inner.demangle_as_inner(self, scope)?;
715
        }
716
0
        Ok(())
717
0
    }
Unexecuted instantiation: <cpp_demangle::ast::DemangleContext<alloc::string::String>>::demangle_inners
Unexecuted instantiation: <cpp_demangle::ast::DemangleContext<_>>::demangle_inners
718
719
0
    fn set_source_name(&mut self, start: usize, end: usize) {
720
0
        let ident = &self.input[start..end];
721
0
        self.source_name = std::str::from_utf8(ident).ok();
722
0
    }
Unexecuted instantiation: <cpp_demangle::ast::DemangleContext<alloc::string::String>>::set_source_name
Unexecuted instantiation: <cpp_demangle::ast::DemangleContext<_>>::set_source_name
723
724
0
    fn push_demangle_node(&mut self, t: DemangleNodeType) {
725
0
        self.out.push_demangle_node(t);
726
0
    }
Unexecuted instantiation: <cpp_demangle::ast::DemangleContext<alloc::string::String>>::push_demangle_node
Unexecuted instantiation: <cpp_demangle::ast::DemangleContext<_>>::push_demangle_node
727
728
    /// This should not be called on error paths.
729
    /// pop_inner_if already doesn't balance if there are errors.
730
0
    fn pop_demangle_node(&mut self) {
731
0
        self.out.pop_demangle_node();
732
0
    }
Unexecuted instantiation: <cpp_demangle::ast::DemangleContext<alloc::string::String>>::pop_demangle_node
Unexecuted instantiation: <cpp_demangle::ast::DemangleContext<_>>::pop_demangle_node
733
}
734
735
#[doc(hidden)]
736
0
#[derive(Debug)]
737
pub struct AutoDemangleContextInnerBarrier<'ctx, 'a, W>
738
where
739
    W: 'a + DemangleWrite,
740
    'a: 'ctx,
741
{
742
    ctx: &'ctx mut DemangleContext<'a, W>,
743
    saved_inner: Vec<&'a dyn DemangleAsInner<'a, W>>,
744
}
745
746
impl<'ctx, 'a, W> AutoDemangleContextInnerBarrier<'ctx, 'a, W>
747
where
748
    W: 'a + DemangleWrite,
749
    'a: 'ctx,
750
{
751
    /// Set aside the current inner stack on the demangle context.
752
0
    pub fn new(ctx: &'ctx mut DemangleContext<'a, W>) -> Self {
753
0
        let mut saved_inner = vec![];
754
0
        mem::swap(&mut saved_inner, &mut ctx.inner);
755
0
        AutoDemangleContextInnerBarrier {
756
0
            ctx: ctx,
757
0
            saved_inner: saved_inner,
758
0
        }
759
0
    }
Unexecuted instantiation: <cpp_demangle::ast::AutoDemangleContextInnerBarrier<alloc::string::String>>::new
Unexecuted instantiation: <cpp_demangle::ast::AutoDemangleContextInnerBarrier<_>>::new
760
}
761
762
impl<'ctx, 'a, W> ops::Deref for AutoDemangleContextInnerBarrier<'ctx, 'a, W>
763
where
764
    W: 'a + DemangleWrite,
765
    'a: 'ctx,
766
{
767
    type Target = DemangleContext<'a, W>;
768
769
0
    fn deref(&self) -> &Self::Target {
770
0
        self.ctx
771
0
    }
Unexecuted instantiation: <cpp_demangle::ast::AutoDemangleContextInnerBarrier<alloc::string::String> as core::ops::deref::Deref>::deref
Unexecuted instantiation: <cpp_demangle::ast::AutoDemangleContextInnerBarrier<_> as core::ops::deref::Deref>::deref
772
}
773
774
impl<'ctx, 'a, W> ops::DerefMut for AutoDemangleContextInnerBarrier<'ctx, 'a, W>
775
where
776
    W: 'a + DemangleWrite,
777
    'a: 'ctx,
778
{
779
0
    fn deref_mut(&mut self) -> &mut Self::Target {
780
0
        self.ctx
781
0
    }
Unexecuted instantiation: <cpp_demangle::ast::AutoDemangleContextInnerBarrier<alloc::string::String> as core::ops::deref::DerefMut>::deref_mut
Unexecuted instantiation: <cpp_demangle::ast::AutoDemangleContextInnerBarrier<_> as core::ops::deref::DerefMut>::deref_mut
782
}
783
784
impl<'ctx, 'a, W> Drop for AutoDemangleContextInnerBarrier<'ctx, 'a, W>
785
where
786
    W: 'a + DemangleWrite,
787
    'a: 'ctx,
788
{
789
0
    fn drop(&mut self) {
790
0
        // NB: We cannot assert that the context's inner is empty here,
791
0
        // because if demangling failed we'll unwind the stack without
792
0
        // using everything that put on the inner.
793
0
        if !self.ctx.inner.is_empty() {
794
0
            log!("Context inner was not emptied, did demangling fail?");
795
0
        }
796
0
        mem::swap(&mut self.saved_inner, &mut self.ctx.inner);
797
0
    }
Unexecuted instantiation: <cpp_demangle::ast::AutoDemangleContextInnerBarrier<alloc::string::String> as core::ops::drop::Drop>::drop
Unexecuted instantiation: <cpp_demangle::ast::AutoDemangleContextInnerBarrier<_> as core::ops::drop::Drop>::drop
798
}
799
800
/// The inner stack allows passing AST nodes down deeper into the tree so that
801
/// nodes that logically precede something (e.g. PointerRef) can show up after
802
/// that thing in the demangled output. What's on the stack may not always be
803
/// intended for the first node that looks at the stack to grab, though.
804
///
805
/// Consider a function with template arguments and parameters, f<T>(a).
806
/// The function parameters logically precede the template arguments in the AST,
807
/// but they must be reversed in the output. The parameters end up on the inner
808
/// stack before processing the template argument nodes. If we're not careful,
809
/// a node inside the template arguments might pick the function parameters
810
/// off of the inner stack!
811
///
812
/// To solve this, certain nodes act as "inner barriers". By using this macro,
813
/// they set the existing inner stack aside and replace it with an empty stack
814
/// while visiting their children. This allows these barrier nodes to have
815
/// completely self-contained children.
816
macro_rules! inner_barrier {
817
    ( $ctx:ident ) => {
818
        let mut _ctx = AutoDemangleContextInnerBarrier::new($ctx);
819
        let $ctx = &mut _ctx;
820
    };
821
}
822
823
/// Any AST node that can be printed in a demangled form.
824
#[doc(hidden)]
825
pub trait Demangle<'subs, W>: fmt::Debug
826
where
827
    W: 'subs + DemangleWrite,
828
{
829
    /// Write the demangled form of this AST node to the given context.
830
    fn demangle<'prev, 'ctx>(
831
        &'subs self,
832
        ctx: &'ctx mut DemangleContext<'subs, W>,
833
        scope: Option<ArgScopeStack<'prev, 'subs>>,
834
    ) -> fmt::Result;
835
}
836
837
/// Any AST node that can be printed as an inner type.
838
///
839
/// See the comments surrounding `DemangleContext::inner` for details.
840
#[doc(hidden)]
841
pub trait DemangleAsInner<'subs, W>: Demangle<'subs, W>
842
where
843
    W: 'subs + DemangleWrite,
844
{
845
    /// Write the inner demangling form of this AST node to the given context.
846
0
    fn demangle_as_inner<'prev, 'ctx>(
847
0
        &'subs self,
848
0
        ctx: &'ctx mut DemangleContext<'subs, W>,
849
0
        scope: Option<ArgScopeStack<'prev, 'subs>>,
850
0
    ) -> fmt::Result {
851
0
        self.demangle(ctx, scope)
852
0
    }
Unexecuted instantiation: <cpp_demangle::ast::CvQualifiers as cpp_demangle::ast::DemangleAsInner<alloc::string::String>>::demangle_as_inner
Unexecuted instantiation: <cpp_demangle::ast::FunctionArgListAndReturnType as cpp_demangle::ast::DemangleAsInner<alloc::string::String>>::demangle_as_inner
Unexecuted instantiation: <cpp_demangle::ast::FunctionArgList as cpp_demangle::ast::DemangleAsInner<alloc::string::String>>::demangle_as_inner
Unexecuted instantiation: <_ as cpp_demangle::ast::DemangleAsInner<_>>::demangle_as_inner
853
854
    /// Cast this `DemangleAsInner` to a `Type`.
855
0
    fn downcast_to_type(&self) -> Option<&Type> {
856
0
        None
857
0
    }
Unexecuted instantiation: <cpp_demangle::ast::FunctionArgListAndReturnType as cpp_demangle::ast::DemangleAsInner<alloc::string::String>>::downcast_to_type
Unexecuted instantiation: <cpp_demangle::ast::BareFunctionType as cpp_demangle::ast::DemangleAsInner<alloc::string::String>>::downcast_to_type
Unexecuted instantiation: <cpp_demangle::ast::PointerToMemberType as cpp_demangle::ast::DemangleAsInner<alloc::string::String>>::downcast_to_type
Unexecuted instantiation: <cpp_demangle::ast::FunctionType as cpp_demangle::ast::DemangleAsInner<alloc::string::String>>::downcast_to_type
Unexecuted instantiation: <cpp_demangle::ast::VectorType as cpp_demangle::ast::DemangleAsInner<alloc::string::String>>::downcast_to_type
Unexecuted instantiation: <cpp_demangle::ast::ArrayType as cpp_demangle::ast::DemangleAsInner<alloc::string::String>>::downcast_to_type
Unexecuted instantiation: <cpp_demangle::ast::Encoding as cpp_demangle::ast::DemangleAsInner<alloc::string::String>>::downcast_to_type
Unexecuted instantiation: <cpp_demangle::ast::FunctionArgList as cpp_demangle::ast::DemangleAsInner<alloc::string::String>>::downcast_to_type
Unexecuted instantiation: <cpp_demangle::ast::CvQualifiers as cpp_demangle::ast::DemangleAsInner<alloc::string::String>>::downcast_to_type
Unexecuted instantiation: <_ as cpp_demangle::ast::DemangleAsInner<_>>::downcast_to_type
858
859
    /// Cast this `DemangleAsInner` to a `FunctionType`.
860
0
    fn downcast_to_function_type(&self) -> Option<&FunctionType> {
861
0
        None
862
0
    }
Unexecuted instantiation: <cpp_demangle::ast::PointerToMemberType as cpp_demangle::ast::DemangleAsInner<alloc::string::String>>::downcast_to_function_type
Unexecuted instantiation: <cpp_demangle::ast::BareFunctionType as cpp_demangle::ast::DemangleAsInner<alloc::string::String>>::downcast_to_function_type
Unexecuted instantiation: <cpp_demangle::ast::FunctionArgList as cpp_demangle::ast::DemangleAsInner<alloc::string::String>>::downcast_to_function_type
Unexecuted instantiation: <cpp_demangle::ast::Encoding as cpp_demangle::ast::DemangleAsInner<alloc::string::String>>::downcast_to_function_type
Unexecuted instantiation: <cpp_demangle::ast::VectorType as cpp_demangle::ast::DemangleAsInner<alloc::string::String>>::downcast_to_function_type
Unexecuted instantiation: <cpp_demangle::ast::CvQualifiers as cpp_demangle::ast::DemangleAsInner<alloc::string::String>>::downcast_to_function_type
Unexecuted instantiation: <cpp_demangle::ast::ArrayType as cpp_demangle::ast::DemangleAsInner<alloc::string::String>>::downcast_to_function_type
Unexecuted instantiation: <cpp_demangle::ast::FunctionArgListAndReturnType as cpp_demangle::ast::DemangleAsInner<alloc::string::String>>::downcast_to_function_type
Unexecuted instantiation: <_ as cpp_demangle::ast::DemangleAsInner<_>>::downcast_to_function_type
863
864
    /// Cast this `DemangleAsInner` to an `ArrayType`.
865
0
    fn downcast_to_array_type(&self) -> Option<&ArrayType> {
866
0
        None
867
0
    }
Unexecuted instantiation: <cpp_demangle::ast::VectorType as cpp_demangle::ast::DemangleAsInner<alloc::string::String>>::downcast_to_array_type
Unexecuted instantiation: <cpp_demangle::ast::BareFunctionType as cpp_demangle::ast::DemangleAsInner<alloc::string::String>>::downcast_to_array_type
Unexecuted instantiation: <cpp_demangle::ast::Encoding as cpp_demangle::ast::DemangleAsInner<alloc::string::String>>::downcast_to_array_type
Unexecuted instantiation: <cpp_demangle::ast::FunctionType as cpp_demangle::ast::DemangleAsInner<alloc::string::String>>::downcast_to_array_type
Unexecuted instantiation: <cpp_demangle::ast::PointerToMemberType as cpp_demangle::ast::DemangleAsInner<alloc::string::String>>::downcast_to_array_type
Unexecuted instantiation: <cpp_demangle::ast::CvQualifiers as cpp_demangle::ast::DemangleAsInner<alloc::string::String>>::downcast_to_array_type
Unexecuted instantiation: <cpp_demangle::ast::FunctionArgList as cpp_demangle::ast::DemangleAsInner<alloc::string::String>>::downcast_to_array_type
Unexecuted instantiation: <cpp_demangle::ast::FunctionArgListAndReturnType as cpp_demangle::ast::DemangleAsInner<alloc::string::String>>::downcast_to_array_type
Unexecuted instantiation: <_ as cpp_demangle::ast::DemangleAsInner<_>>::downcast_to_array_type
868
869
    /// Cast this `DemangleAsInner` to a `PointerToMember`.
870
0
    fn downcast_to_pointer_to_member(&self) -> Option<&PointerToMemberType> {
871
0
        None
872
0
    }
Unexecuted instantiation: <cpp_demangle::ast::FunctionArgListAndReturnType as cpp_demangle::ast::DemangleAsInner<alloc::string::String>>::downcast_to_pointer_to_member
Unexecuted instantiation: <cpp_demangle::ast::FunctionArgList as cpp_demangle::ast::DemangleAsInner<alloc::string::String>>::downcast_to_pointer_to_member
Unexecuted instantiation: <cpp_demangle::ast::CvQualifiers as cpp_demangle::ast::DemangleAsInner<alloc::string::String>>::downcast_to_pointer_to_member
Unexecuted instantiation: <cpp_demangle::ast::FunctionType as cpp_demangle::ast::DemangleAsInner<alloc::string::String>>::downcast_to_pointer_to_member
Unexecuted instantiation: <cpp_demangle::ast::Encoding as cpp_demangle::ast::DemangleAsInner<alloc::string::String>>::downcast_to_pointer_to_member
Unexecuted instantiation: <cpp_demangle::ast::BareFunctionType as cpp_demangle::ast::DemangleAsInner<alloc::string::String>>::downcast_to_pointer_to_member
Unexecuted instantiation: <cpp_demangle::ast::VectorType as cpp_demangle::ast::DemangleAsInner<alloc::string::String>>::downcast_to_pointer_to_member
Unexecuted instantiation: <cpp_demangle::ast::ArrayType as cpp_demangle::ast::DemangleAsInner<alloc::string::String>>::downcast_to_pointer_to_member
Unexecuted instantiation: <_ as cpp_demangle::ast::DemangleAsInner<_>>::downcast_to_pointer_to_member
873
874
0
    fn is_qualified(&self) -> bool {
875
0
        false
876
0
    }
Unexecuted instantiation: <cpp_demangle::ast::FunctionArgList as cpp_demangle::ast::DemangleAsInner<alloc::string::String>>::is_qualified
Unexecuted instantiation: <cpp_demangle::ast::FunctionType as cpp_demangle::ast::DemangleAsInner<alloc::string::String>>::is_qualified
Unexecuted instantiation: <cpp_demangle::ast::BareFunctionType as cpp_demangle::ast::DemangleAsInner<alloc::string::String>>::is_qualified
Unexecuted instantiation: <cpp_demangle::ast::CvQualifiers as cpp_demangle::ast::DemangleAsInner<alloc::string::String>>::is_qualified
Unexecuted instantiation: <cpp_demangle::ast::FunctionArgListAndReturnType as cpp_demangle::ast::DemangleAsInner<alloc::string::String>>::is_qualified
Unexecuted instantiation: <cpp_demangle::ast::PointerToMemberType as cpp_demangle::ast::DemangleAsInner<alloc::string::String>>::is_qualified
Unexecuted instantiation: <cpp_demangle::ast::VectorType as cpp_demangle::ast::DemangleAsInner<alloc::string::String>>::is_qualified
Unexecuted instantiation: <cpp_demangle::ast::ArrayType as cpp_demangle::ast::DemangleAsInner<alloc::string::String>>::is_qualified
Unexecuted instantiation: <cpp_demangle::ast::Encoding as cpp_demangle::ast::DemangleAsInner<alloc::string::String>>::is_qualified
Unexecuted instantiation: <_ as cpp_demangle::ast::DemangleAsInner<_>>::is_qualified
877
}
878
879
/// Demangle this thing in the leaf name position.
880
///
881
/// For most things this should be the same as its `Demangle`
882
/// implementation. For `WellKnownComponent`s we need to strip the embedded
883
/// `std::` namespace prefix.
884
pub(crate) trait DemangleAsLeaf<'subs, W>
885
where
886
    W: 'subs + DemangleWrite,
887
{
888
    fn demangle_as_leaf<'me, 'ctx>(
889
        &'me self,
890
        ctx: &'ctx mut DemangleContext<'subs, W>,
891
    ) -> fmt::Result;
892
}
893
894
macro_rules! reference_newtype {
895
    ( $newtype_name:ident , $oldtype:ty ) => {
896
0
        #[derive(Debug)]
Unexecuted instantiation: <cpp_demangle::ast::FunctionArgList as core::fmt::Debug>::fmt
Unexecuted instantiation: <cpp_demangle::ast::FunctionArgListAndReturnType as core::fmt::Debug>::fmt
Unexecuted instantiation: <cpp_demangle::ast::FunctionArgSlice as core::fmt::Debug>::fmt
897
        struct $newtype_name($oldtype);
898
899
        impl $newtype_name {
900
            #[allow(clippy::ptr_arg)]
901
            #[allow(unsafe_code)]
902
0
            fn new(types: &$oldtype) -> &$newtype_name {
903
0
                unsafe {
904
0
                    // This is safe because we only create an immutable
905
0
                    // reference. We are not breaking unique mutable aliasing
906
0
                    // requirements. An immutable reference does not allow
907
0
                    // dropping the referent, so no worries about double-free
908
0
                    // (additionally, see the assertion inside `Drop` below).
909
0
                    &*(types as *const $oldtype as *const $newtype_name)
910
0
                }
911
0
            }
Unexecuted instantiation: <cpp_demangle::ast::FunctionArgListAndReturnType>::new
Unexecuted instantiation: <cpp_demangle::ast::FunctionArgSlice>::new
Unexecuted instantiation: <cpp_demangle::ast::FunctionArgList>::new
912
        }
913
914
        impl Drop for $newtype_name {
915
0
            fn drop(&mut self) {
916
0
                unreachable!(
917
0
                    "Dropping implies we dereferenced and took ownership, which \
918
0
                              is not safe for this newtype"
919
0
                );
920
0
            }
Unexecuted instantiation: <cpp_demangle::ast::FunctionArgListAndReturnType as core::ops::drop::Drop>::drop
Unexecuted instantiation: <cpp_demangle::ast::FunctionArgList as core::ops::drop::Drop>::drop
Unexecuted instantiation: <cpp_demangle::ast::FunctionArgSlice as core::ops::drop::Drop>::drop
921
        }
922
923
        impl ops::Deref for $newtype_name {
924
            type Target = $oldtype;
925
926
0
            fn deref(&self) -> &Self::Target {
927
0
                &self.0
928
0
            }
Unexecuted instantiation: <cpp_demangle::ast::FunctionArgListAndReturnType as core::ops::deref::Deref>::deref
Unexecuted instantiation: <cpp_demangle::ast::FunctionArgList as core::ops::deref::Deref>::deref
Unexecuted instantiation: <cpp_demangle::ast::FunctionArgSlice as core::ops::deref::Deref>::deref
929
        }
930
    };
931
}
932
933
// We can't implement `DemangleAsInner` for newtypes of `[TypeHandle]` like we
934
// want to because it is unsized and we need to make trait objects out of
935
// `DemangleAsInner` for pushing onto the context's inner stack. Therefore, we
936
// have this inelegant newtyping of `Vec<TypeHandle>`.
937
938
// A set of function arguments.
939
reference_newtype!(FunctionArgList, Vec<TypeHandle>);
940
941
// A set of function arguments prefixed by a return type (which we want to
942
// ignore).
943
reference_newtype!(FunctionArgListAndReturnType, Vec<TypeHandle>);
944
945
// A newtype around a slice of type handles that we format as function
946
// arguments.
947
reference_newtype!(FunctionArgSlice, [TypeHandle]);
948
949
// Demangle a slice of TypeHandle as a function argument list.
950
impl<'subs, W> Demangle<'subs, W> for FunctionArgSlice
951
where
952
    W: 'subs + DemangleWrite,
953
{
954
0
    fn demangle<'prev, 'ctx>(
955
0
        &'subs self,
956
0
        ctx: &'ctx mut DemangleContext<'subs, W>,
957
0
        scope: Option<ArgScopeStack<'prev, 'subs>>,
958
0
    ) -> fmt::Result {
959
0
        let ctx = try_begin_demangle!(self, ctx, scope);
960
961
0
        let mut saw_needs_paren = false;
962
0
        let (needs_space, needs_paren) = ctx
963
0
            .inner
964
0
            .iter()
965
0
            .rev()
966
0
            .map(|inner| {
967
0
                if inner.downcast_to_pointer_to_member().is_some() {
968
0
                    (true, true)
969
                } else {
970
0
                    match inner.downcast_to_type() {
971
                        Some(&Type::Qualified(..))
972
                        | Some(&Type::Complex(_))
973
                        | Some(&Type::Imaginary(_))
974
0
                        | Some(&Type::PointerToMember(_)) => (true, true),
975
                        Some(&Type::PointerTo(_))
976
                        | Some(&Type::LvalueRef(_))
977
0
                        | Some(&Type::RvalueRef(_)) => (false, true),
978
0
                        _ => (false, false),
979
                    }
980
                }
981
0
            })
Unexecuted instantiation: <cpp_demangle::ast::FunctionArgSlice as cpp_demangle::ast::Demangle<alloc::string::String>>::demangle::{closure#0}
Unexecuted instantiation: <cpp_demangle::ast::FunctionArgSlice as cpp_demangle::ast::Demangle<_>>::demangle::{closure#0}
982
0
            .take_while(|&(_, needs_paren)| {
983
0
                if saw_needs_paren {
984
0
                    false
985
                } else {
986
0
                    saw_needs_paren |= needs_paren;
987
0
                    true
988
                }
989
0
            })
Unexecuted instantiation: <cpp_demangle::ast::FunctionArgSlice as cpp_demangle::ast::Demangle<alloc::string::String>>::demangle::{closure#1}
Unexecuted instantiation: <cpp_demangle::ast::FunctionArgSlice as cpp_demangle::ast::Demangle<_>>::demangle::{closure#1}
990
0
            .fold(
991
0
                (false, false),
992
0
                |(space, paren), (next_space, next_paren)| {
993
0
                    (space || next_space, paren || next_paren)
994
0
                },
Unexecuted instantiation: <cpp_demangle::ast::FunctionArgSlice as cpp_demangle::ast::Demangle<alloc::string::String>>::demangle::{closure#2}
Unexecuted instantiation: <cpp_demangle::ast::FunctionArgSlice as cpp_demangle::ast::Demangle<_>>::demangle::{closure#2}
995
0
            );
996
0
997
0
        if needs_paren {
998
0
            let needs_space = needs_space
999
0
                || match ctx.last_char_written {
1000
0
                    Some('(') | Some('*') => false,
1001
0
                    _ => true,
1002
                };
1003
1004
0
            if needs_space {
1005
0
                ctx.ensure_space()?;
1006
0
            }
1007
1008
0
            write!(ctx, "(")?;
1009
0
        }
1010
1011
0
        ctx.demangle_inner_prefixes(scope)?;
1012
1013
0
        if needs_paren {
1014
0
            write!(ctx, ")")?;
1015
0
        }
1016
1017
0
        write!(ctx, "(")?;
1018
1019
        // To maintain compatibility with libiberty, print `()` instead of
1020
        // `(void)` for functions that take no arguments.
1021
0
        if self.len() == 1 && self[0].is_void() {
1022
0
            write!(ctx, ")")?;
1023
0
            return Ok(());
1024
0
        }
1025
0
1026
0
        let mut need_comma = false;
1027
0
        for arg in self.iter() {
1028
0
            if need_comma {
1029
0
                write!(ctx, ", ")?;
1030
0
            }
1031
0
            arg.demangle(ctx, scope)?;
1032
0
            need_comma = true;
1033
        }
1034
1035
0
        write!(ctx, ")")?;
1036
1037
0
        ctx.demangle_inners(scope)
1038
0
    }
Unexecuted instantiation: <cpp_demangle::ast::FunctionArgSlice as cpp_demangle::ast::Demangle<alloc::string::String>>::demangle
Unexecuted instantiation: <cpp_demangle::ast::FunctionArgSlice as cpp_demangle::ast::Demangle<_>>::demangle
1039
}
1040
1041
impl<'subs, W> Demangle<'subs, W> for FunctionArgList
1042
where
1043
    W: 'subs + DemangleWrite,
1044
{
1045
0
    fn demangle<'prev, 'ctx>(
1046
0
        &'subs self,
1047
0
        ctx: &'ctx mut DemangleContext<'subs, W>,
1048
0
        scope: Option<ArgScopeStack<'prev, 'subs>>,
1049
0
    ) -> fmt::Result {
1050
0
        FunctionArgSlice::new(&self.0[..]).demangle(ctx, scope)
1051
0
    }
Unexecuted instantiation: <cpp_demangle::ast::FunctionArgList as cpp_demangle::ast::Demangle<alloc::string::String>>::demangle
Unexecuted instantiation: <cpp_demangle::ast::FunctionArgList as cpp_demangle::ast::Demangle<_>>::demangle
1052
}
1053
1054
impl<'subs, W> DemangleAsInner<'subs, W> for FunctionArgList where W: 'subs + DemangleWrite {}
1055
1056
impl<'subs, W> Demangle<'subs, W> for FunctionArgListAndReturnType
1057
where
1058
    W: 'subs + DemangleWrite,
1059
{
1060
0
    fn demangle<'prev, 'ctx>(
1061
0
        &'subs self,
1062
0
        ctx: &'ctx mut DemangleContext<'subs, W>,
1063
0
        scope: Option<ArgScopeStack<'prev, 'subs>>,
1064
0
    ) -> fmt::Result {
1065
0
        FunctionArgSlice::new(&self.0[1..]).demangle(ctx, scope)
1066
0
    }
Unexecuted instantiation: <cpp_demangle::ast::FunctionArgListAndReturnType as cpp_demangle::ast::Demangle<alloc::string::String>>::demangle
Unexecuted instantiation: <cpp_demangle::ast::FunctionArgListAndReturnType as cpp_demangle::ast::Demangle<_>>::demangle
1067
}
1068
1069
impl<'subs, W> DemangleAsInner<'subs, W> for FunctionArgListAndReturnType where
1070
    W: 'subs + DemangleWrite
1071
{
1072
}
1073
1074
/// Define a handle to a AST type that lives inside the substitution table. A
1075
/// handle is always either an index into the substitution table, or it is a
1076
/// reference to a "well-known" component.
1077
///
1078
/// This declares:
1079
///
1080
/// - The enum of either a back reference into the substitution table or a
1081
///   reference to a "well-known" component
1082
/// - a `Demangle` impl that proxies to the appropriate `Substitutable` in the
1083
///   `SubstitutionTable`
1084
macro_rules! define_handle {
1085
    (
1086
        $(#[$attr:meta])*
1087
        pub enum $typename:ident
1088
    ) => {
1089
        define_handle! {
1090
            $(#[$attr])*
1091
            pub enum $typename {}
1092
        }
1093
    };
1094
1095
    (
1096
        $(#[$attr:meta])*
1097
        pub enum $typename:ident {
1098
            $(
1099
                $( #[$extra_attr:meta] )*
1100
                extra $extra_variant:ident ( $extra_variant_ty:ty ),
1101
            )*
1102
        }
1103
    ) => {
1104
        $(#[$attr])*
1105
0
        #[derive(Clone, Debug, PartialEq, Eq)]
Unexecuted instantiation: <cpp_demangle::ast::PrefixHandle as core::clone::Clone>::clone
Unexecuted instantiation: <cpp_demangle::ast::TypeHandle as core::clone::Clone>::clone
Unexecuted instantiation: <cpp_demangle::ast::UnresolvedTypeHandle as core::clone::Clone>::clone
Unexecuted instantiation: <cpp_demangle::ast::TemplateTemplateParamHandle as core::clone::Clone>::clone
Unexecuted instantiation: <cpp_demangle::ast::UnscopedTemplateNameHandle as core::clone::Clone>::clone
Unexecuted instantiation: <cpp_demangle::ast::TypeHandle as core::fmt::Debug>::fmt
Unexecuted instantiation: <cpp_demangle::ast::PrefixHandle as core::fmt::Debug>::fmt
Unexecuted instantiation: <cpp_demangle::ast::TemplateTemplateParamHandle as core::fmt::Debug>::fmt
Unexecuted instantiation: <cpp_demangle::ast::UnscopedTemplateNameHandle as core::fmt::Debug>::fmt
Unexecuted instantiation: <cpp_demangle::ast::UnresolvedTypeHandle as core::fmt::Debug>::fmt
Unexecuted instantiation: <cpp_demangle::ast::UnscopedTemplateNameHandle as core::cmp::PartialEq>::eq
Unexecuted instantiation: <cpp_demangle::ast::PrefixHandle as core::cmp::PartialEq>::eq
Unexecuted instantiation: <cpp_demangle::ast::TemplateTemplateParamHandle as core::cmp::PartialEq>::eq
Unexecuted instantiation: <cpp_demangle::ast::TypeHandle as core::cmp::PartialEq>::eq
Unexecuted instantiation: <cpp_demangle::ast::UnresolvedTypeHandle as core::cmp::PartialEq>::eq
1106
        pub enum $typename {
1107
            /// A reference to a "well-known" component.
1108
            WellKnown(WellKnownComponent),
1109
1110
            /// A back-reference into the substitution table to a component we
1111
            /// have already parsed.
1112
            BackReference(usize),
1113
1114
            $(
1115
                $( #[$extra_attr] )*
1116
                $extra_variant( $extra_variant_ty ),
1117
            )*
1118
        }
1119
1120
        impl $typename {
1121
            /// If this is a `BackReference`, get its index.
1122
0
            pub fn back_reference(&self) -> Option<usize> {
1123
0
                match *self {
1124
0
                    $typename::BackReference(n) => Some(n),
1125
0
                    _ => None,
1126
                }
1127
0
            }
Unexecuted instantiation: <cpp_demangle::ast::TypeHandle>::back_reference
Unexecuted instantiation: <cpp_demangle::ast::PrefixHandle>::back_reference
Unexecuted instantiation: <cpp_demangle::ast::TemplateTemplateParamHandle>::back_reference
Unexecuted instantiation: <cpp_demangle::ast::UnresolvedTypeHandle>::back_reference
Unexecuted instantiation: <cpp_demangle::ast::UnscopedTemplateNameHandle>::back_reference
1128
        }
1129
1130
        impl<'subs, W> Demangle<'subs, W> for $typename
1131
        where
1132
            W: 'subs + DemangleWrite
1133
        {
1134
            #[inline]
1135
0
            fn demangle<'prev, 'ctx>(&'subs self,
1136
0
                                     ctx: &'ctx mut DemangleContext<'subs, W>,
1137
0
                                     scope: Option<ArgScopeStack<'prev, 'subs>>)
1138
0
                                     -> fmt::Result {
1139
0
                match *self {
1140
0
                    $typename::WellKnown(ref comp) => comp.demangle(ctx, scope),
1141
0
                    $typename::BackReference(idx) => ctx.subs[idx].demangle(ctx, scope),
1142
                    $(
1143
0
                        $typename::$extra_variant(ref extra) => extra.demangle(ctx, scope),
1144
                    )*
1145
                }
1146
0
            }
Unexecuted instantiation: <cpp_demangle::ast::PrefixHandle as cpp_demangle::ast::Demangle<alloc::string::String>>::demangle
Unexecuted instantiation: <cpp_demangle::ast::UnresolvedTypeHandle as cpp_demangle::ast::Demangle<alloc::string::String>>::demangle
Unexecuted instantiation: <cpp_demangle::ast::TypeHandle as cpp_demangle::ast::Demangle<alloc::string::String>>::demangle
Unexecuted instantiation: <cpp_demangle::ast::UnscopedTemplateNameHandle as cpp_demangle::ast::Demangle<alloc::string::String>>::demangle
Unexecuted instantiation: <cpp_demangle::ast::TemplateTemplateParamHandle as cpp_demangle::ast::Demangle<alloc::string::String>>::demangle
Unexecuted instantiation: <cpp_demangle::ast::TypeHandle as cpp_demangle::ast::Demangle<_>>::demangle
Unexecuted instantiation: <cpp_demangle::ast::UnresolvedTypeHandle as cpp_demangle::ast::Demangle<_>>::demangle
Unexecuted instantiation: <cpp_demangle::ast::PrefixHandle as cpp_demangle::ast::Demangle<_>>::demangle
Unexecuted instantiation: <cpp_demangle::ast::UnscopedTemplateNameHandle as cpp_demangle::ast::Demangle<_>>::demangle
Unexecuted instantiation: <cpp_demangle::ast::TemplateTemplateParamHandle as cpp_demangle::ast::Demangle<_>>::demangle
1147
        }
1148
1149
        impl<'a> GetLeafName<'a> for $typename {
1150
0
            fn get_leaf_name(&'a self, subs: &'a SubstitutionTable) -> Option<LeafName<'a>> {
1151
0
                match *self {
1152
0
                    $typename::WellKnown(ref wk) => wk.get_leaf_name(subs),
1153
0
                    $typename::BackReference(idx) => {
1154
0
                        subs.get(idx).and_then(|s| s.get_leaf_name(subs))
1155
                    }
1156
                    $(
1157
0
                        $typename::$extra_variant(ref e) => e.get_leaf_name(subs),
1158
                    )*
1159
                }
1160
0
            }
Unexecuted instantiation: <cpp_demangle::ast::PrefixHandle as cpp_demangle::ast::GetLeafName>::get_leaf_name
Unexecuted instantiation: <cpp_demangle::ast::UnscopedTemplateNameHandle as cpp_demangle::ast::GetLeafName>::get_leaf_name
Unexecuted instantiation: <cpp_demangle::ast::TemplateTemplateParamHandle as cpp_demangle::ast::GetLeafName>::get_leaf_name
Unexecuted instantiation: <cpp_demangle::ast::UnresolvedTypeHandle as cpp_demangle::ast::GetLeafName>::get_leaf_name
Unexecuted instantiation: <cpp_demangle::ast::TypeHandle as cpp_demangle::ast::GetLeafName>::get_leaf_name
1161
        }
1162
    };
1163
}
1164
1165
/// A handle to a component that is usually substitutable, and lives in the
1166
/// substitutions table, but in this particular case does not qualify for
1167
/// substitutions.
1168
0
#[derive(Clone, Debug, PartialEq, Eq)]
1169
pub struct NonSubstitution(usize);
1170
1171
impl<'subs, W> Demangle<'subs, W> for NonSubstitution
1172
where
1173
    W: 'subs + DemangleWrite,
1174
{
1175
0
    fn demangle<'prev, 'ctx>(
1176
0
        &'subs self,
1177
0
        ctx: &'ctx mut DemangleContext<'subs, W>,
1178
0
        scope: Option<ArgScopeStack<'prev, 'subs>>,
1179
0
    ) -> fmt::Result {
1180
0
        ctx.subs.non_substitution(self.0).demangle(ctx, scope)
1181
0
    }
Unexecuted instantiation: <cpp_demangle::ast::NonSubstitution as cpp_demangle::ast::Demangle<alloc::string::String>>::demangle
Unexecuted instantiation: <cpp_demangle::ast::NonSubstitution as cpp_demangle::ast::Demangle<_>>::demangle
1182
}
1183
1184
impl<'a> GetLeafName<'a> for NonSubstitution {
1185
0
    fn get_leaf_name(&'a self, subs: &'a SubstitutionTable) -> Option<LeafName<'a>> {
1186
0
        subs.get_non_substitution(self.0)
1187
0
            .and_then(|ns| ns.get_leaf_name(subs))
1188
0
    }
1189
}
1190
1191
/// Define a "vocabulary" nonterminal, something like `OperatorName` or
1192
/// `CtorDtorName` that's basically a big list of constant strings.
1193
///
1194
/// This declares:
1195
///
1196
/// - the enum itself
1197
/// - a `Parse` impl
1198
/// - a `Demangle` impl
1199
///
1200
/// See the definition of `CTorDtorName` for an example of its use.
1201
///
1202
/// Optionally, a piece of user data can be attached to the definitions
1203
/// and be returned by a generated accessor. See `SimpleOperatorName` for
1204
/// an example.
1205
macro_rules! define_vocabulary {
1206
    ( $(#[$attr:meta])* pub enum $typename:ident {
1207
        $($variant:ident ( $mangled:expr, $printable:expr )),*
1208
    } ) => {
1209
1210
        $(#[$attr])*
1211
        pub enum $typename {
1212
            $(
1213
                #[doc=$printable]
1214
                $variant
1215
            ),*
1216
        }
1217
1218
        impl Parse for $typename {
1219
10.8M
            fn parse<'a, 'b>(ctx: &'a ParseContext,
1220
10.8M
                             _subs: &'a mut SubstitutionTable,
1221
10.8M
                             input: IndexStr<'b>)
1222
10.8M
                             -> Result<($typename, IndexStr<'b>)> {
1223
10.8M
                try_begin_parse!(stringify!($typename), ctx, input);
1224
1225
10.8M
                let mut found_prefix = false;
1226
                $(
1227
10.8M
                    if let Some((head, tail)) = input.try_split_at($mangled.len()) {
1228
10.8M
                        if head.as_ref() == $mangled {
1229
0
                            return Ok(($typename::$variant, tail));
1230
254M
                        }
1231
                    } else {
1232
0
                        found_prefix |= 0 < input.len() &&
1233
0
                            input.len() < $mangled.len() &&
1234
0
                            input.as_ref() == &$mangled[..input.len()];
1235
                    }
1236
                )*
1237
1238
9.94M
                if input.is_empty() || found_prefix {
1239
0
                    Err(error::Error::UnexpectedEnd)
1240
                } else {
1241
9.94M
                    Err(error::Error::UnexpectedText)
1242
                }
1243
10.8M
            }
<cpp_demangle::ast::StandardBuiltinType as cpp_demangle::ast::Parse>::parse
Line
Count
Source
1219
2.52M
            fn parse<'a, 'b>(ctx: &'a ParseContext,
1220
2.52M
                             _subs: &'a mut SubstitutionTable,
1221
2.52M
                             input: IndexStr<'b>)
1222
2.52M
                             -> Result<($typename, IndexStr<'b>)> {
1223
2.52M
                try_begin_parse!(stringify!($typename), ctx, input);
1224
1225
2.52M
                let mut found_prefix = false;
1226
                $(
1227
2.52M
                    if let Some((head, tail)) = input.try_split_at($mangled.len()) {
1228
2.52M
                        if head.as_ref() == $mangled {
1229
0
                            return Ok(($typename::$variant, tail));
1230
60.7M
                        }
1231
                    } else {
1232
0
                        found_prefix |= 0 < input.len() &&
1233
0
                            input.len() < $mangled.len() &&
1234
0
                            input.as_ref() == &$mangled[..input.len()];
1235
                    }
1236
                )*
1237
1238
1.65M
                if input.is_empty() || found_prefix {
1239
0
                    Err(error::Error::UnexpectedEnd)
1240
                } else {
1241
1.65M
                    Err(error::Error::UnexpectedText)
1242
                }
1243
2.52M
            }
<cpp_demangle::ast::SimpleOperatorName as cpp_demangle::ast::Parse>::parse
Line
Count
Source
1219
3.31M
            fn parse<'a, 'b>(ctx: &'a ParseContext,
1220
3.31M
                             _subs: &'a mut SubstitutionTable,
1221
3.31M
                             input: IndexStr<'b>)
1222
3.31M
                             -> Result<($typename, IndexStr<'b>)> {
1223
3.31M
                try_begin_parse!(stringify!($typename), ctx, input);
1224
1225
3.31M
                let mut found_prefix = false;
1226
                $(
1227
3.31M
                    if let Some((head, tail)) = input.try_split_at($mangled.len()) {
1228
3.31M
                        if head.as_ref() == $mangled {
1229
0
                            return Ok(($typename::$variant, tail));
1230
159M
                        }
1231
                    } else {
1232
0
                        found_prefix |= 0 < input.len() &&
1233
0
                            input.len() < $mangled.len() &&
1234
0
                            input.as_ref() == &$mangled[..input.len()];
1235
                    }
1236
                )*
1237
1238
3.31M
                if input.is_empty() || found_prefix {
1239
0
                    Err(error::Error::UnexpectedEnd)
1240
                } else {
1241
3.31M
                    Err(error::Error::UnexpectedText)
1242
                }
1243
3.31M
            }
<cpp_demangle::ast::WellKnownComponent as cpp_demangle::ast::Parse>::parse
Line
Count
Source
1219
4.97M
            fn parse<'a, 'b>(ctx: &'a ParseContext,
1220
4.97M
                             _subs: &'a mut SubstitutionTable,
1221
4.97M
                             input: IndexStr<'b>)
1222
4.97M
                             -> Result<($typename, IndexStr<'b>)> {
1223
4.97M
                try_begin_parse!(stringify!($typename), ctx, input);
1224
1225
4.97M
                let mut found_prefix = false;
1226
                $(
1227
4.97M
                    if let Some((head, tail)) = input.try_split_at($mangled.len()) {
1228
4.97M
                        if head.as_ref() == $mangled {
1229
0
                            return Ok(($typename::$variant, tail));
1230
34.8M
                        }
1231
                    } else {
1232
0
                        found_prefix |= 0 < input.len() &&
1233
0
                            input.len() < $mangled.len() &&
1234
0
                            input.as_ref() == &$mangled[..input.len()];
1235
                    }
1236
                )*
1237
1238
4.97M
                if input.is_empty() || found_prefix {
1239
0
                    Err(error::Error::UnexpectedEnd)
1240
                } else {
1241
4.97M
                    Err(error::Error::UnexpectedText)
1242
                }
1243
4.97M
            }
Unexecuted instantiation: <cpp_demangle::ast::RefQualifier as cpp_demangle::ast::Parse>::parse
1244
        }
1245
1246
        impl<'subs, W> Demangle<'subs, W> for $typename
1247
        where
1248
            W: 'subs + DemangleWrite,
1249
        {
1250
0
            fn demangle<'prev, 'ctx>(
1251
0
                &'subs self,
1252
0
                ctx: &'ctx mut DemangleContext<'subs, W>,
1253
0
                scope: Option<ArgScopeStack<'prev, 'subs>>
1254
0
            ) -> fmt::Result {
1255
0
                let ctx = try_begin_demangle!(self, ctx, scope);
1256
1257
0
                write!(ctx, "{}", match *self {
1258
0
                    $(
1259
0
                        $typename::$variant => $printable
1260
0
                    ),*
1261
0
                })
1262
0
            }
Unexecuted instantiation: <cpp_demangle::ast::RefQualifier as cpp_demangle::ast::Demangle<alloc::string::String>>::demangle
Unexecuted instantiation: <cpp_demangle::ast::StandardBuiltinType as cpp_demangle::ast::Demangle<alloc::string::String>>::demangle
Unexecuted instantiation: <cpp_demangle::ast::WellKnownComponent as cpp_demangle::ast::Demangle<alloc::string::String>>::demangle
Unexecuted instantiation: <cpp_demangle::ast::SimpleOperatorName as cpp_demangle::ast::Demangle<alloc::string::String>>::demangle
Unexecuted instantiation: <cpp_demangle::ast::RefQualifier as cpp_demangle::ast::Demangle<_>>::demangle
Unexecuted instantiation: <cpp_demangle::ast::SimpleOperatorName as cpp_demangle::ast::Demangle<_>>::demangle
Unexecuted instantiation: <cpp_demangle::ast::WellKnownComponent as cpp_demangle::ast::Demangle<_>>::demangle
Unexecuted instantiation: <cpp_demangle::ast::StandardBuiltinType as cpp_demangle::ast::Demangle<_>>::demangle
1263
        }
1264
1265
        impl $typename {
1266
            #[allow(dead_code)]
1267
            #[inline]
1268
            fn starts_with(byte: u8) -> bool {
1269
                $(
1270
0
                    if $mangled[0] == byte {
1271
0
                        return true;
1272
0
                    }
1273
0
                )*
1274
0
1275
0
                false
1276
0
            }
Unexecuted instantiation: <cpp_demangle::ast::RefQualifier>::starts_with
Unexecuted instantiation: <cpp_demangle::ast::SimpleOperatorName>::starts_with
Unexecuted instantiation: <cpp_demangle::ast::StandardBuiltinType>::starts_with
Unexecuted instantiation: <cpp_demangle::ast::WellKnownComponent>::starts_with
1277
        }
1278
    };
1279
    ( $(#[$attr:meta])* pub enum $typename:ident {
1280
        $($variant:ident ( $mangled:expr, $printable:expr, $userdata:expr)),*
1281
    }
1282
1283
      impl $typename2:ident {
1284
          fn $fn_name:ident(&self) -> $userdata_ty:ty;
1285
    } ) => {
1286
        define_vocabulary! {
1287
            $(#[$attr])*
1288
            pub enum $typename {
1289
                $(
1290
                    $variant ( $mangled, $printable )
1291
                ),*
1292
            }
1293
        }
1294
1295
        impl $typename2 {
1296
0
            fn $fn_name(&self) -> $userdata_ty {
1297
0
                match *self {
1298
                    $(
1299
                        $typename2::$variant => $userdata,
1300
                    )*
1301
                }
1302
0
            }
1303
        }
1304
    };
1305
}
1306
1307
/// The root AST node, and starting production.
1308
///
1309
/// ```text
1310
/// <mangled-name> ::= _Z <encoding> [<clone-suffix>]*
1311
///                ::= ___Z <encoding> <block_invoke>
1312
///                ::= <type>
1313
///
1314
/// <block_invoke> ::= _block_invoke
1315
///                ::= _block_invoke<decimal-digit>+
1316
///                ::= _block_invoke_<decimal-digit>+
1317
/// ```
1318
0
#[derive(Clone, Debug, PartialEq, Eq)]
1319
pub enum MangledName {
1320
    /// The encoding of the mangled symbol name.
1321
    Encoding(Encoding, Vec<CloneSuffix>),
1322
1323
    /// The encoding of the mangled symbol name.
1324
    BlockInvoke(Encoding, Option<isize>),
1325
1326
    /// A top-level type. Technically not allowed by the standard, however in
1327
    /// practice this can happen, and is tested for by libiberty.
1328
    Type(TypeHandle),
1329
1330
    /// A global constructor or destructor. This is another de facto standard
1331
    /// extension (I think originally from `g++`?) that is not actually part of
1332
    /// the standard proper.
1333
    GlobalCtorDtor(GlobalCtorDtor),
1334
}
1335
1336
impl Parse for MangledName {
1337
1.69M
    fn parse<'a, 'b>(
1338
1.69M
        ctx: &'a ParseContext,
1339
1.69M
        subs: &'a mut SubstitutionTable,
1340
1.69M
        input: IndexStr<'b>,
1341
1.69M
    ) -> Result<(MangledName, IndexStr<'b>)> {
1342
1.69M
        try_begin_parse!("MangledName", ctx, input);
1343
1344
1.69M
        if let Ok(tail) = consume(b"_Z", input).or_else(|_| consume(b"__Z", input)) {
1345
0
            let (encoding, tail) = Encoding::parse(ctx, subs, tail)?;
1346
0
            let (clone_suffixes, tail) = zero_or_more(ctx, subs, tail)?;
1347
0
            return Ok((MangledName::Encoding(encoding, clone_suffixes), tail));
1348
1.69M
        }
1349
1350
1.69M
        if let Ok(tail) = consume(b"___Z", input).or_else(|_| consume(b"____Z", input)) {
1351
0
            let (encoding, tail) = Encoding::parse(ctx, subs, tail)?;
1352
0
            let tail = consume(b"_block_invoke", tail)?;
1353
1354
0
            let tail_opt = match consume(b"_", tail).or_else(|_| consume(b".", tail)) {
1355
0
                Ok(tail) => Some(parse_number(10, false, tail)?),
1356
0
                Err(_) => parse_number(10, false, tail).ok(),
1357
            };
1358
1359
0
            let (digits, tail) = match tail_opt {
1360
0
                Some((digits, tail)) => (Some(digits), tail),
1361
0
                None => (None, tail),
1362
            };
1363
1364
0
            return Ok((MangledName::BlockInvoke(encoding, digits), tail));
1365
1.69M
        }
1366
1367
1.69M
        if let Ok(tail) = consume(b"_GLOBAL_", input) {
1368
0
            let (global_ctor_dtor, tail) = GlobalCtorDtor::parse(ctx, subs, tail)?;
1369
0
            return Ok((MangledName::GlobalCtorDtor(global_ctor_dtor), tail));
1370
1.69M
        }
1371
1372
        // The libiberty tests also specify that a type can be top level,
1373
        // and they are not prefixed with "_Z".
1374
1.69M
        let (ty, tail) = TypeHandle::parse(ctx, subs, input)?;
1375
863k
        Ok((MangledName::Type(ty), tail))
1376
1.69M
    }
1377
}
1378
1379
impl<'subs, W> Demangle<'subs, W> for MangledName
1380
where
1381
    W: 'subs + DemangleWrite,
1382
{
1383
0
    fn demangle<'prev, 'ctx>(
1384
0
        &'subs self,
1385
0
        ctx: &'ctx mut DemangleContext<'subs, W>,
1386
0
        scope: Option<ArgScopeStack<'prev, 'subs>>,
1387
0
    ) -> fmt::Result {
1388
0
        let ctx = try_begin_demangle!(self, ctx, scope);
1389
1390
0
        match *self {
1391
0
            MangledName::Encoding(ref enc, ref cs) => {
1392
0
                enc.demangle(ctx, scope)?;
1393
0
                if !cs.is_empty() && ctx.show_params {
1394
0
                    for clone_suffix in cs {
1395
0
                        clone_suffix.demangle(ctx, scope)?;
1396
                    }
1397
0
                }
1398
0
                Ok(())
1399
            }
1400
0
            MangledName::BlockInvoke(ref enc, _) => {
1401
0
                write!(ctx, "invocation function for block in ")?;
1402
0
                enc.demangle(ctx, scope)?;
1403
0
                Ok(())
1404
            }
1405
0
            MangledName::Type(ref ty) => ty.demangle(ctx, scope),
1406
0
            MangledName::GlobalCtorDtor(ref gcd) => gcd.demangle(ctx, scope),
1407
        }
1408
0
    }
Unexecuted instantiation: <cpp_demangle::ast::MangledName as cpp_demangle::ast::Demangle<alloc::string::String>>::demangle
Unexecuted instantiation: <cpp_demangle::ast::MangledName as cpp_demangle::ast::Demangle<_>>::demangle
1409
}
1410
1411
/// The `<encoding>` production.
1412
///
1413
/// ```text
1414
/// <encoding> ::= <function name> <bare-function-type>
1415
///            ::= <data name>
1416
///            ::= <special-name>
1417
/// ```
1418
0
#[derive(Clone, Debug, PartialEq, Eq)]
1419
pub enum Encoding {
1420
    /// An encoded function.
1421
    Function(Name, BareFunctionType),
1422
1423
    /// An encoded static variable.
1424
    Data(Name),
1425
1426
    /// A special encoding.
1427
    Special(SpecialName),
1428
}
1429
1430
impl Parse for Encoding {
1431
0
    fn parse<'a, 'b>(
1432
0
        ctx: &'a ParseContext,
1433
0
        subs: &'a mut SubstitutionTable,
1434
0
        input: IndexStr<'b>,
1435
0
    ) -> Result<(Encoding, IndexStr<'b>)> {
1436
0
        try_begin_parse!("Encoding", ctx, input);
1437
1438
0
        if let Ok((name, tail)) = Name::parse(ctx, subs, input) {
1439
0
            if let Ok((ty, tail)) = BareFunctionType::parse(ctx, subs, tail) {
1440
0
                return Ok((Encoding::Function(name, ty), tail));
1441
            } else {
1442
0
                return Ok((Encoding::Data(name), tail));
1443
            }
1444
0
        }
1445
1446
0
        let (name, tail) = SpecialName::parse(ctx, subs, input)?;
1447
0
        Ok((Encoding::Special(name), tail))
1448
0
    }
1449
}
1450
1451
impl<'subs, W> Demangle<'subs, W> for Encoding
1452
where
1453
    W: 'subs + DemangleWrite,
1454
{
1455
0
    fn demangle<'prev, 'ctx>(
1456
0
        &'subs self,
1457
0
        ctx: &'ctx mut DemangleContext<'subs, W>,
1458
0
        scope: Option<ArgScopeStack<'prev, 'subs>>,
1459
0
    ) -> fmt::Result {
1460
0
        let ctx = try_begin_demangle!(self, ctx, scope);
1461
0
        inner_barrier!(ctx);
1462
0
1463
0
        match *self {
1464
0
            Encoding::Function(ref name, ref fun_ty) => {
1465
                // Even if this function takes no args and doesn't have a return
1466
                // value (see below), it will have the void parameter.
1467
0
                debug_assert!(!fun_ty.0.is_empty());
1468
1469
0
                let scope = if let Some(leaf) = name.get_leaf_name(ctx.subs) {
1470
0
                    match leaf {
1471
0
                        LeafName::SourceName(leaf) => scope.push(leaf),
1472
0
                        LeafName::WellKnownComponent(leaf) => scope.push(leaf),
1473
0
                        LeafName::Closure(leaf) => scope.push(leaf),
1474
0
                        LeafName::UnnamedType(leaf) => scope.push(leaf),
1475
                    }
1476
                } else {
1477
0
                    scope
1478
                };
1479
1480
                // Whether the first type in the BareFunctionType is a return
1481
                // type or parameter depends on the context in which it
1482
                // appears.
1483
                //
1484
                // * Templates and functions in a type or parameter position
1485
                // have return types, unless they are constructors, destructors,
1486
                // or conversion operator functions.
1487
                //
1488
                // * Non-template functions that are not in a type or parameter
1489
                // position do not have a return type.
1490
                //
1491
                // We know we are not printing a type, so we only need to check
1492
                // whether this is a template.
1493
                //
1494
                // For the details, see
1495
                // https://itanium-cxx-abi.github.io/cxx-abi/abi.html#mangle.function-type
1496
0
                let scope = if let Some(template_args) = name.get_template_args(ctx.subs) {
1497
0
                    let scope = scope.push(template_args);
1498
0
                    if ctx.show_return_type && !name.is_ctor_dtor_conversion(ctx.subs) {
1499
0
                        fun_ty.0[0].demangle(ctx, scope)?;
1500
0
                        write!(ctx, " ")?;
1501
0
                    }
1502
1503
0
                    scope
1504
                } else {
1505
0
                    scope
1506
                };
1507
1508
0
                if ctx.show_params {
1509
0
                    ctx.push_inner(self);
1510
0
                    name.demangle(ctx, scope)?;
1511
0
                    if ctx.pop_inner_if(self) {
1512
0
                        self.demangle_as_inner(ctx, scope)?;
1513
0
                    }
1514
                } else {
1515
0
                    name.demangle(ctx, scope)?;
1516
                }
1517
1518
0
                Ok(())
1519
            }
1520
0
            Encoding::Data(ref name) => name.demangle(ctx, scope),
1521
0
            Encoding::Special(ref name) => name.demangle(ctx, scope),
1522
        }
1523
0
    }
Unexecuted instantiation: <cpp_demangle::ast::Encoding as cpp_demangle::ast::Demangle<alloc::string::String>>::demangle
Unexecuted instantiation: <cpp_demangle::ast::Encoding as cpp_demangle::ast::Demangle<_>>::demangle
1524
}
1525
1526
impl<'subs, W> DemangleAsInner<'subs, W> for Encoding
1527
where
1528
    W: 'subs + DemangleWrite,
1529
{
1530
0
    fn demangle_as_inner<'prev, 'ctx>(
1531
0
        &'subs self,
1532
0
        ctx: &'ctx mut DemangleContext<'subs, W>,
1533
0
        scope: Option<ArgScopeStack<'prev, 'subs>>,
1534
0
    ) -> fmt::Result {
1535
0
        if let Encoding::Function(ref name, ref fun_ty) = *self {
1536
0
            let (scope, function_args) =
1537
0
                if let Some(template_args) = name.get_template_args(ctx.subs) {
1538
0
                    let scope = scope.push(template_args);
1539
0
                    let function_args = FunctionArgListAndReturnType::new(&fun_ty.0);
1540
0
                    (scope, function_args as &dyn DemangleAsInner<W>)
1541
                } else {
1542
0
                    let function_args = FunctionArgList::new(&fun_ty.0);
1543
0
                    (scope, function_args as &dyn DemangleAsInner<W>)
1544
                };
1545
0
            function_args.demangle_as_inner(ctx, scope)
1546
        } else {
1547
0
            unreachable!("we only push Encoding::Function onto the inner stack");
1548
        }
1549
0
    }
Unexecuted instantiation: <cpp_demangle::ast::Encoding as cpp_demangle::ast::DemangleAsInner<alloc::string::String>>::demangle_as_inner
Unexecuted instantiation: <cpp_demangle::ast::Encoding as cpp_demangle::ast::DemangleAsInner<_>>::demangle_as_inner
1550
}
1551
1552
/// <clone-suffix> ::= [ . <clone-type-identifier> ] [ . <nonnegative number> ]*
1553
1554
0
#[derive(Clone, Debug, PartialEq, Eq)]
1555
pub struct CloneSuffix(CloneTypeIdentifier, Vec<isize>);
1556
1557
impl Parse for CloneSuffix {
1558
0
    fn parse<'a, 'b>(
1559
0
        ctx: &'a ParseContext,
1560
0
        subs: &'a mut SubstitutionTable,
1561
0
        input: IndexStr<'b>,
1562
0
    ) -> Result<(CloneSuffix, IndexStr<'b>)> {
1563
0
        try_begin_parse!("CloneSuffix", ctx, input);
1564
1565
0
        let tail = consume(b".", input)?;
1566
0
        let (identifier, mut tail) = CloneTypeIdentifier::parse(ctx, subs, tail)?;
1567
1568
0
        let mut numbers = Vec::with_capacity(1);
1569
0
        while let Ok((n, t)) = consume(b".", tail).and_then(|t| parse_number(10, false, t)) {
1570
0
            numbers.push(n);
1571
0
            tail = t;
1572
0
        }
1573
1574
0
        let clone_suffix = CloneSuffix(identifier, numbers);
1575
0
        Ok((clone_suffix, tail))
1576
0
    }
1577
}
1578
1579
impl<'subs, W> Demangle<'subs, W> for CloneSuffix
1580
where
1581
    W: 'subs + DemangleWrite,
1582
{
1583
0
    fn demangle<'prev, 'ctx>(
1584
0
        &'subs self,
1585
0
        ctx: &'ctx mut DemangleContext<'subs, W>,
1586
0
        scope: Option<ArgScopeStack<'prev, 'subs>>,
1587
0
    ) -> fmt::Result {
1588
0
        let ctx = try_begin_demangle!(self, ctx, scope);
1589
0
        write!(ctx, " [clone")?;
1590
0
        self.0.demangle(ctx, scope)?;
1591
0
        for nonnegative in &self.1 {
1592
0
            write!(ctx, ".{}", nonnegative)?;
1593
        }
1594
0
        write!(ctx, "]")?;
1595
0
        Ok(())
1596
0
    }
Unexecuted instantiation: <cpp_demangle::ast::CloneSuffix as cpp_demangle::ast::Demangle<alloc::string::String>>::demangle
Unexecuted instantiation: <cpp_demangle::ast::CloneSuffix as cpp_demangle::ast::Demangle<_>>::demangle
1597
}
1598
1599
/// A global constructor or destructor.
1600
0
#[derive(Clone, Debug, PartialEq, Eq)]
1601
pub enum GlobalCtorDtor {
1602
    /// A global constructor.
1603
    Ctor(Box<MangledName>),
1604
    /// A global destructor.
1605
    Dtor(Box<MangledName>),
1606
}
1607
1608
impl Parse for GlobalCtorDtor {
1609
0
    fn parse<'a, 'b>(
1610
0
        ctx: &'a ParseContext,
1611
0
        subs: &'a mut SubstitutionTable,
1612
0
        input: IndexStr<'b>,
1613
0
    ) -> Result<(GlobalCtorDtor, IndexStr<'b>)> {
1614
0
        try_begin_parse!("GlobalCtorDtor", ctx, input);
1615
1616
0
        let tail = match input.next_or(error::Error::UnexpectedEnd)? {
1617
0
            (b'_', t) | (b'.', t) | (b'$', t) => t,
1618
0
            _ => return Err(error::Error::UnexpectedText),
1619
        };
1620
1621
0
        match tail.next_or(error::Error::UnexpectedEnd)? {
1622
0
            (b'I', tail) => {
1623
0
                let tail = consume(b"_", tail)?;
1624
0
                let (name, tail) = MangledName::parse(ctx, subs, tail)?;
1625
0
                Ok((GlobalCtorDtor::Ctor(Box::new(name)), tail))
1626
            }
1627
0
            (b'D', tail) => {
1628
0
                let tail = consume(b"_", tail)?;
1629
0
                let (name, tail) = MangledName::parse(ctx, subs, tail)?;
1630
0
                Ok((GlobalCtorDtor::Dtor(Box::new(name)), tail))
1631
            }
1632
0
            _ => Err(error::Error::UnexpectedText),
1633
        }
1634
0
    }
1635
}
1636
1637
impl<'subs, W> Demangle<'subs, W> for GlobalCtorDtor
1638
where
1639
    W: 'subs + DemangleWrite,
1640
{
1641
0
    fn demangle<'prev, 'ctx>(
1642
0
        &'subs self,
1643
0
        ctx: &'ctx mut DemangleContext<'subs, W>,
1644
0
        scope: Option<ArgScopeStack<'prev, 'subs>>,
1645
0
    ) -> fmt::Result {
1646
0
        let ctx = try_begin_demangle!(self, ctx, scope);
1647
0
        inner_barrier!(ctx);
1648
0
1649
0
        let saved_show_params = ctx.show_params;
1650
0
        ctx.show_params = true;
1651
0
        let ret = match *self {
1652
0
            GlobalCtorDtor::Ctor(ref name) => {
1653
0
                write!(ctx, "global constructors keyed to ")?;
1654
0
                name.demangle(ctx, scope)
1655
            }
1656
0
            GlobalCtorDtor::Dtor(ref name) => {
1657
0
                write!(ctx, "global destructors keyed to ")?;
1658
0
                name.demangle(ctx, scope)
1659
            }
1660
        };
1661
0
        ctx.show_params = saved_show_params;
1662
0
        ret
1663
0
    }
Unexecuted instantiation: <cpp_demangle::ast::GlobalCtorDtor as cpp_demangle::ast::Demangle<alloc::string::String>>::demangle
Unexecuted instantiation: <cpp_demangle::ast::GlobalCtorDtor as cpp_demangle::ast::Demangle<_>>::demangle
1664
}
1665
1666
/// The `<name>` production.
1667
///
1668
/// ```text
1669
/// <name> ::= <nested-name>
1670
///        ::= <unscoped-name>
1671
///        ::= <unscoped-template-name> <template-args>
1672
///        ::= <local-name>
1673
/// ```
1674
0
#[derive(Clone, Debug, PartialEq, Eq)]
1675
pub enum Name {
1676
    /// A nested name
1677
    Nested(NestedName),
1678
1679
    /// An unscoped name.
1680
    Unscoped(UnscopedName),
1681
1682
    /// An unscoped template.
1683
    UnscopedTemplate(UnscopedTemplateNameHandle, TemplateArgs),
1684
1685
    /// A local name.
1686
    Local(LocalName),
1687
}
1688
1689
impl Parse for Name {
1690
1.65M
    fn parse<'a, 'b>(
1691
1.65M
        ctx: &'a ParseContext,
1692
1.65M
        subs: &'a mut SubstitutionTable,
1693
1.65M
        input: IndexStr<'b>,
1694
1.65M
    ) -> Result<(Name, IndexStr<'b>)> {
1695
1.65M
        try_begin_parse!("Name", ctx, input);
1696
1697
1.65M
        if let Ok((name, tail)) = NestedName::parse(ctx, subs, input) {
1698
0
            return Ok((Name::Nested(name), tail));
1699
1.65M
        }
1700
1701
1.65M
        if let Ok((name, tail)) = UnscopedName::parse(ctx, subs, input) {
1702
0
            if tail.peek() == Some(b'I') {
1703
0
                let name = UnscopedTemplateName(name);
1704
0
                let idx = subs.insert(Substitutable::UnscopedTemplateName(name));
1705
0
                let handle = UnscopedTemplateNameHandle::BackReference(idx);
1706
1707
0
                let (args, tail) = TemplateArgs::parse(ctx, subs, tail)?;
1708
0
                return Ok((Name::UnscopedTemplate(handle, args), tail));
1709
            } else {
1710
0
                return Ok((Name::Unscoped(name), tail));
1711
            }
1712
1.65M
        }
1713
1714
1.65M
        if let Ok((name, tail)) = UnscopedTemplateNameHandle::parse(ctx, subs, input) {
1715
0
            let (args, tail) = TemplateArgs::parse(ctx, subs, tail)?;
1716
0
            return Ok((Name::UnscopedTemplate(name, args), tail));
1717
1.65M
        }
1718
1719
1.65M
        let (name, tail) = LocalName::parse(ctx, subs, input)?;
1720
0
        Ok((Name::Local(name), tail))
1721
1.65M
    }
1722
}
1723
1724
impl<'subs, W> Demangle<'subs, W> for Name
1725
where
1726
    W: 'subs + DemangleWrite,
1727
{
1728
0
    fn demangle<'prev, 'ctx>(
1729
0
        &'subs self,
1730
0
        ctx: &'ctx mut DemangleContext<'subs, W>,
1731
0
        scope: Option<ArgScopeStack<'prev, 'subs>>,
1732
0
    ) -> fmt::Result {
1733
0
        let ctx = try_begin_demangle!(self, ctx, scope);
1734
1735
0
        match *self {
1736
0
            Name::Nested(ref nested) => nested.demangle(ctx, scope),
1737
0
            Name::Unscoped(ref unscoped) => unscoped.demangle(ctx, scope),
1738
0
            Name::UnscopedTemplate(ref template, ref args) => {
1739
0
                template.demangle(ctx, scope.push(args))?;
1740
0
                args.demangle(ctx, scope)
1741
            }
1742
0
            Name::Local(ref local) => local.demangle(ctx, scope),
1743
        }
1744
0
    }
Unexecuted instantiation: <cpp_demangle::ast::Name as cpp_demangle::ast::Demangle<alloc::string::String>>::demangle
Unexecuted instantiation: <cpp_demangle::ast::Name as cpp_demangle::ast::Demangle<_>>::demangle
1745
}
1746
1747
impl GetTemplateArgs for Name {
1748
0
    fn get_template_args<'a>(&'a self, subs: &'a SubstitutionTable) -> Option<&'a TemplateArgs> {
1749
0
        match *self {
1750
0
            Name::UnscopedTemplate(_, ref args) => Some(args),
1751
0
            Name::Nested(ref nested) => nested.get_template_args(subs),
1752
0
            Name::Local(ref local) => local.get_template_args(subs),
1753
0
            Name::Unscoped(_) => None,
1754
        }
1755
0
    }
1756
}
1757
1758
impl<'a> GetLeafName<'a> for Name {
1759
0
    fn get_leaf_name(&'a self, subs: &'a SubstitutionTable) -> Option<LeafName<'a>> {
1760
0
        match *self {
1761
0
            Name::UnscopedTemplate(ref templ, _) => templ.get_leaf_name(subs),
1762
0
            Name::Nested(ref nested) => nested.get_leaf_name(subs),
1763
0
            Name::Unscoped(ref unscoped) => unscoped.get_leaf_name(subs),
1764
0
            Name::Local(ref local) => local.get_leaf_name(subs),
1765
        }
1766
0
    }
1767
}
1768
1769
impl IsCtorDtorConversion for Name {
1770
0
    fn is_ctor_dtor_conversion(&self, subs: &SubstitutionTable) -> bool {
1771
0
        match *self {
1772
0
            Name::Unscoped(ref unscoped) => unscoped.is_ctor_dtor_conversion(subs),
1773
0
            Name::Nested(ref nested) => nested.is_ctor_dtor_conversion(subs),
1774
0
            Name::Local(_) | Name::UnscopedTemplate(..) => false,
1775
        }
1776
0
    }
1777
}
1778
1779
/// The `<unscoped-name>` production.
1780
///
1781
/// ```text
1782
/// <unscoped-name> ::= <unqualified-name>
1783
///                 ::= St <unqualified-name>   # ::std::
1784
/// ```
1785
0
#[derive(Clone, Debug, PartialEq, Eq)]
1786
pub enum UnscopedName {
1787
    /// An unqualified name.
1788
    Unqualified(UnqualifiedName),
1789
1790
    /// A name within the `std::` namespace.
1791
    Std(UnqualifiedName),
1792
}
1793
1794
impl Parse for UnscopedName {
1795
3.31M
    fn parse<'a, 'b>(
1796
3.31M
        ctx: &'a ParseContext,
1797
3.31M
        subs: &'a mut SubstitutionTable,
1798
3.31M
        input: IndexStr<'b>,
1799
3.31M
    ) -> Result<(UnscopedName, IndexStr<'b>)> {
1800
3.31M
        try_begin_parse!("UnscopedName", ctx, input);
1801
1802
3.31M
        if let Ok(tail) = consume(b"St", input) {
1803
0
            let (name, tail) = UnqualifiedName::parse(ctx, subs, tail)?;
1804
0
            return Ok((UnscopedName::Std(name), tail));
1805
3.31M
        }
1806
1807
3.31M
        let (name, tail) = UnqualifiedName::parse(ctx, subs, input)?;
1808
0
        Ok((UnscopedName::Unqualified(name), tail))
1809
3.31M
    }
1810
}
1811
1812
impl<'subs, W> Demangle<'subs, W> for UnscopedName
1813
where
1814
    W: 'subs + DemangleWrite,
1815
{
1816
0
    fn demangle<'prev, 'ctx>(
1817
0
        &'subs self,
1818
0
        ctx: &'ctx mut DemangleContext<'subs, W>,
1819
0
        scope: Option<ArgScopeStack<'prev, 'subs>>,
1820
0
    ) -> fmt::Result {
1821
0
        let ctx = try_begin_demangle!(self, ctx, scope);
1822
1823
0
        match *self {
1824
0
            UnscopedName::Unqualified(ref unqualified) => unqualified.demangle(ctx, scope),
1825
0
            UnscopedName::Std(ref std) => {
1826
0
                write!(ctx, "std::")?;
1827
0
                std.demangle(ctx, scope)
1828
            }
1829
        }
1830
0
    }
Unexecuted instantiation: <cpp_demangle::ast::UnscopedName as cpp_demangle::ast::Demangle<alloc::string::String>>::demangle
Unexecuted instantiation: <cpp_demangle::ast::UnscopedName as cpp_demangle::ast::Demangle<_>>::demangle
1831
}
1832
1833
impl<'a> GetLeafName<'a> for UnscopedName {
1834
0
    fn get_leaf_name(&'a self, subs: &'a SubstitutionTable) -> Option<LeafName<'a>> {
1835
0
        match *self {
1836
0
            UnscopedName::Unqualified(ref name) | UnscopedName::Std(ref name) => {
1837
0
                name.get_leaf_name(subs)
1838
0
            }
1839
0
        }
1840
0
    }
1841
}
1842
1843
impl IsCtorDtorConversion for UnscopedName {
1844
0
    fn is_ctor_dtor_conversion(&self, subs: &SubstitutionTable) -> bool {
1845
0
        match *self {
1846
0
            UnscopedName::Unqualified(ref name) | UnscopedName::Std(ref name) => {
1847
0
                name.is_ctor_dtor_conversion(subs)
1848
0
            }
1849
0
        }
1850
0
    }
1851
}
1852
1853
/// The `<unscoped-template-name>` production.
1854
///
1855
/// ```text
1856
/// <unscoped-template-name> ::= <unscoped-name>
1857
///                          ::= <substitution>
1858
/// ```
1859
0
#[derive(Clone, Debug, PartialEq, Eq)]
1860
pub struct UnscopedTemplateName(UnscopedName);
1861
1862
0
define_handle! {
1863
0
    /// A handle to an `UnscopedTemplateName`.
1864
0
    pub enum UnscopedTemplateNameHandle {
1865
0
        /// A handle to some `<unscoped-name>` component that isn't by itself
1866
0
        /// substitutable.
1867
0
        extra NonSubstitution(NonSubstitution),
1868
0
    }
1869
0
}
1870
1871
impl Parse for UnscopedTemplateNameHandle {
1872
1.65M
    fn parse<'a, 'b>(
1873
1.65M
        ctx: &'a ParseContext,
1874
1.65M
        subs: &'a mut SubstitutionTable,
1875
1.65M
        input: IndexStr<'b>,
1876
1.65M
    ) -> Result<(UnscopedTemplateNameHandle, IndexStr<'b>)> {
1877
1.65M
        try_begin_parse!("UnscopedTemplateNameHandle", ctx, input);
1878
1879
1.65M
        if let Ok((name, tail)) = UnscopedName::parse(ctx, subs, input) {
1880
0
            let name = UnscopedTemplateName(name);
1881
0
            let idx = subs.insert(Substitutable::UnscopedTemplateName(name));
1882
0
            let handle = UnscopedTemplateNameHandle::BackReference(idx);
1883
0
            return Ok((handle, tail));
1884
1.65M
        }
1885
1886
1.65M
        let (sub, tail) = Substitution::parse(ctx, subs, input)?;
1887
1888
0
        match sub {
1889
0
            Substitution::WellKnown(component) => {
1890
0
                Ok((UnscopedTemplateNameHandle::WellKnown(component), tail))
1891
            }
1892
0
            Substitution::BackReference(idx) => {
1893
0
                // TODO: should this check/assert that subs[idx] is an
1894
0
                // UnscopedTemplateName?
1895
0
                Ok((UnscopedTemplateNameHandle::BackReference(idx), tail))
1896
            }
1897
        }
1898
1.65M
    }
1899
}
1900
1901
impl<'subs, W> Demangle<'subs, W> for UnscopedTemplateName
1902
where
1903
    W: 'subs + DemangleWrite,
1904
{
1905
0
    fn demangle<'prev, 'ctx>(
1906
0
        &'subs self,
1907
0
        ctx: &'ctx mut DemangleContext<'subs, W>,
1908
0
        scope: Option<ArgScopeStack<'prev, 'subs>>,
1909
0
    ) -> fmt::Result {
1910
0
        let ctx = try_begin_demangle!(self, ctx, scope);
1911
1912
0
        self.0.demangle(ctx, scope)
1913
0
    }
Unexecuted instantiation: <cpp_demangle::ast::UnscopedTemplateName as cpp_demangle::ast::Demangle<alloc::string::String>>::demangle
Unexecuted instantiation: <cpp_demangle::ast::UnscopedTemplateName as cpp_demangle::ast::Demangle<_>>::demangle
1914
}
1915
1916
impl<'a> GetLeafName<'a> for UnscopedTemplateName {
1917
0
    fn get_leaf_name(&'a self, subs: &'a SubstitutionTable) -> Option<LeafName<'a>> {
1918
0
        self.0.get_leaf_name(subs)
1919
0
    }
1920
}
1921
1922
/// The `<nested-name>` production.
1923
///
1924
/// ```text
1925
/// <nested-name> ::= N [<CV-qualifiers>] [<ref-qualifier>] <prefix> <unqualified-name> E
1926
///               ::= N [<CV-qualifiers>] [<ref-qualifier>] <template-prefix> <template-args> E
1927
/// ```
1928
0
#[derive(Clone, Debug, PartialEq, Eq)]
1929
pub enum NestedName {
1930
    /// A nested name.
1931
    Unqualified(
1932
        CvQualifiers,
1933
        Option<RefQualifier>,
1934
        PrefixHandle,
1935
        UnqualifiedName,
1936
    ),
1937
1938
    /// A nested template name. The `<template-args>` are part of the `PrefixHandle`.
1939
    Template(CvQualifiers, Option<RefQualifier>, PrefixHandle),
1940
}
1941
1942
impl Parse for NestedName {
1943
1.65M
    fn parse<'a, 'b>(
1944
1.65M
        ctx: &'a ParseContext,
1945
1.65M
        subs: &'a mut SubstitutionTable,
1946
1.65M
        input: IndexStr<'b>,
1947
1.65M
    ) -> Result<(NestedName, IndexStr<'b>)> {
1948
1.65M
        try_begin_parse!("NestedName", ctx, input);
1949
1950
1.65M
        let tail = consume(b"N", input)?;
1951
1952
0
        let (cv_qualifiers, tail) = if let Ok((q, tail)) = CvQualifiers::parse(ctx, subs, tail) {
1953
0
            (q, tail)
1954
        } else {
1955
0
            (Default::default(), tail)
1956
        };
1957
1958
0
        let (ref_qualifier, tail) = if let Ok((r, tail)) = RefQualifier::parse(ctx, subs, tail) {
1959
0
            (Some(r), tail)
1960
        } else {
1961
0
            (None, tail)
1962
        };
1963
1964
0
        let (prefix, tail) = PrefixHandle::parse(ctx, subs, tail)?;
1965
0
        let tail = consume(b"E", tail)?;
1966
1967
0
        let substitutable = match prefix {
1968
0
            PrefixHandle::BackReference(idx) => subs.get(idx),
1969
0
            PrefixHandle::NonSubstitution(NonSubstitution(idx)) => subs.get_non_substitution(idx),
1970
0
            PrefixHandle::WellKnown(_) => None,
1971
        };
1972
1973
0
        match substitutable {
1974
0
            Some(&Substitutable::Prefix(Prefix::Nested(ref prefix, ref name))) => Ok((
1975
0
                NestedName::Unqualified(cv_qualifiers, ref_qualifier, prefix.clone(), name.clone()),
1976
0
                tail,
1977
0
            )),
1978
0
            Some(&Substitutable::Prefix(Prefix::Template(..))) => Ok((
1979
0
                NestedName::Template(cv_qualifiers, ref_qualifier, prefix),
1980
0
                tail,
1981
0
            )),
1982
0
            _ => Err(error::Error::UnexpectedText),
1983
        }
1984
1.65M
    }
1985
}
1986
1987
impl NestedName {
1988
    /// Get the CV-qualifiers for this name.
1989
0
    pub fn cv_qualifiers(&self) -> &CvQualifiers {
1990
0
        match *self {
1991
0
            NestedName::Unqualified(ref q, ..) | NestedName::Template(ref q, ..) => q,
1992
0
        }
1993
0
    }
1994
1995
    /// Get the ref-qualifier for this name, if one exists.
1996
    pub fn ref_qualifier(&self) -> Option<&RefQualifier> {
1997
0
        match *self {
1998
0
            NestedName::Unqualified(_, Some(ref r), ..)
1999
0
            | NestedName::Template(_, Some(ref r), ..) => Some(r),
2000
0
            _ => None,
2001
        }
2002
0
    }
2003
2004
    // Not public because the prefix means different things for different
2005
    // variants, and for `::Template` it actually contains part of what
2006
    // conceptually belongs to `<nested-name>`.
2007
0
    fn prefix(&self) -> &PrefixHandle {
2008
0
        match *self {
2009
0
            NestedName::Unqualified(_, _, ref p, _) | NestedName::Template(_, _, ref p) => p,
2010
0
        }
2011
0
    }
2012
}
2013
2014
impl<'subs, W> Demangle<'subs, W> for NestedName
2015
where
2016
    W: 'subs + DemangleWrite,
2017
{
2018
0
    fn demangle<'prev, 'ctx>(
2019
0
        &'subs self,
2020
0
        ctx: &'ctx mut DemangleContext<'subs, W>,
2021
0
        scope: Option<ArgScopeStack<'prev, 'subs>>,
2022
0
    ) -> fmt::Result {
2023
0
        let ctx = try_begin_demangle!(self, ctx, scope);
2024
2025
0
        match *self {
2026
0
            NestedName::Unqualified(_, _, ref p, ref name) => {
2027
0
                ctx.push_demangle_node(DemangleNodeType::NestedName);
2028
0
                p.demangle(ctx, scope)?;
2029
0
                if name.accepts_double_colon() {
2030
0
                    ctx.write_str("::")?;
2031
0
                }
2032
0
                name.demangle(ctx, scope)?;
2033
0
                ctx.pop_demangle_node();
2034
            }
2035
0
            NestedName::Template(_, _, ref p) => {
2036
0
                ctx.is_template_prefix_in_nested_name = true;
2037
0
                p.demangle(ctx, scope)?;
2038
0
                ctx.is_template_prefix_in_nested_name = false;
2039
            }
2040
        }
2041
2042
0
        if let Some(inner) = ctx.pop_inner() {
2043
0
            inner.demangle_as_inner(ctx, scope)?;
2044
0
        }
2045
2046
0
        if self.cv_qualifiers() != &CvQualifiers::default() && ctx.show_params {
2047
0
            self.cv_qualifiers().demangle(ctx, scope)?;
2048
0
        }
2049
2050
0
        if let Some(ref refs) = self.ref_qualifier() {
2051
0
            ctx.ensure_space()?;
2052
0
            refs.demangle(ctx, scope)?;
2053
0
        }
2054
2055
0
        Ok(())
2056
0
    }
Unexecuted instantiation: <cpp_demangle::ast::NestedName as cpp_demangle::ast::Demangle<alloc::string::String>>::demangle
Unexecuted instantiation: <cpp_demangle::ast::NestedName as cpp_demangle::ast::Demangle<_>>::demangle
2057
}
2058
2059
impl GetTemplateArgs for NestedName {
2060
0
    fn get_template_args<'a>(&'a self, subs: &'a SubstitutionTable) -> Option<&'a TemplateArgs> {
2061
0
        match *self {
2062
0
            NestedName::Template(_, _, ref prefix) => prefix.get_template_args(subs),
2063
0
            _ => None,
2064
        }
2065
0
    }
2066
}
2067
2068
impl<'a> GetLeafName<'a> for NestedName {
2069
0
    fn get_leaf_name(&'a self, subs: &'a SubstitutionTable) -> Option<LeafName<'a>> {
2070
0
        match *self {
2071
0
            NestedName::Unqualified(_, _, ref prefix, ref name) => name
2072
0
                .get_leaf_name(subs)
2073
0
                .or_else(|| prefix.get_leaf_name(subs)),
2074
0
            NestedName::Template(_, _, ref prefix) => prefix.get_leaf_name(subs),
2075
        }
2076
0
    }
2077
}
2078
2079
impl IsCtorDtorConversion for NestedName {
2080
0
    fn is_ctor_dtor_conversion(&self, subs: &SubstitutionTable) -> bool {
2081
0
        self.prefix().is_ctor_dtor_conversion(subs)
2082
0
    }
2083
}
2084
2085
/// The `<prefix>` production.
2086
///
2087
/// ```text
2088
/// <prefix> ::= <unqualified-name>
2089
///          ::= <prefix> <unqualified-name>
2090
///          ::= <template-prefix> <template-args>
2091
///          ::= <template-param>
2092
///          ::= <decltype>
2093
///          ::= <prefix> <data-member-prefix>
2094
///          ::= <substitution>
2095
///
2096
/// <template-prefix> ::= <template unqualified-name>
2097
///                   ::= <prefix> <template unqualified-name>
2098
///                   ::= <template-param>
2099
///                   ::= <substitution>
2100
/// ```
2101
0
#[derive(Clone, Debug, PartialEq, Eq)]
2102
pub enum Prefix {
2103
    /// An unqualified name.
2104
    Unqualified(UnqualifiedName),
2105
2106
    /// Some nested name.
2107
    Nested(PrefixHandle, UnqualifiedName),
2108
2109
    /// A prefix and template arguments.
2110
    Template(PrefixHandle, TemplateArgs),
2111
2112
    /// A template parameter.
2113
    TemplateParam(TemplateParam),
2114
2115
    /// A decltype.
2116
    Decltype(Decltype),
2117
2118
    /// A prefix and data member.
2119
    DataMember(PrefixHandle, DataMemberPrefix),
2120
}
2121
2122
impl GetTemplateArgs for Prefix {
2123
0
    fn get_template_args<'a>(&'a self, _: &'a SubstitutionTable) -> Option<&'a TemplateArgs> {
2124
0
        match *self {
2125
0
            Prefix::Template(_, ref args) => Some(args),
2126
            Prefix::Unqualified(_)
2127
            | Prefix::Nested(_, _)
2128
            | Prefix::TemplateParam(_)
2129
            | Prefix::Decltype(_)
2130
0
            | Prefix::DataMember(_, _) => None,
2131
        }
2132
0
    }
2133
}
2134
2135
0
define_handle! {
2136
0
    /// A reference to a parsed `<prefix>` production.
2137
0
    pub enum PrefixHandle {
2138
0
        /// A handle to some `<prefix>` component that isn't by itself
2139
0
        /// substitutable; instead, it's only substitutable *with* its parent
2140
0
        /// component.
2141
0
        extra NonSubstitution(NonSubstitution),
2142
0
    }
2143
0
}
2144
2145
impl Parse for PrefixHandle {
2146
0
    fn parse<'a, 'b>(
2147
0
        ctx: &'a ParseContext,
2148
0
        subs: &'a mut SubstitutionTable,
2149
0
        input: IndexStr<'b>,
2150
0
    ) -> Result<(PrefixHandle, IndexStr<'b>)> {
2151
0
        try_begin_parse!("PrefixHandle", ctx, input);
2152
2153
        #[inline]
2154
0
        fn save(
2155
0
            subs: &mut SubstitutionTable,
2156
0
            prefix: Prefix,
2157
0
            tail_tail: IndexStr<'_>,
2158
0
        ) -> PrefixHandle {
2159
0
            if let Some(b'E') = tail_tail.peek() {
2160
                // An `E` means that we just finished parsing a `<nested-name>`
2161
                // and this final set of prefixes isn't substitutable itself,
2162
                // only as part of the whole `<nested-name>`. Since they are
2163
                // effectively equivalent, it doesn't make sense to add entries
2164
                // for both.
2165
0
                let idx = subs.insert_non_substitution(Substitutable::Prefix(prefix));
2166
0
                PrefixHandle::NonSubstitution(NonSubstitution(idx))
2167
            } else {
2168
0
                let idx = subs.insert(Substitutable::Prefix(prefix));
2169
0
                PrefixHandle::BackReference(idx)
2170
            }
2171
0
        }
2172
2173
0
        let mut tail = input;
2174
0
        let mut current = None;
2175
2176
0
        loop {
2177
0
            try_begin_parse!("PrefixHandle iteration", ctx, tail);
2178
2179
0
            match tail.peek() {
2180
                Some(b'E') | None => {
2181
0
                    if let Some(handle) = current {
2182
0
                        return Ok((handle, tail));
2183
                    } else {
2184
0
                        return Err(error::Error::UnexpectedEnd);
2185
                    }
2186
                }
2187
                Some(b'S') => {
2188
                    // <prefix> ::= <substitution>
2189
0
                    let (sub, tail_tail) = Substitution::parse(ctx, subs, tail)?;
2190
0
                    current = Some(match sub {
2191
0
                        Substitution::WellKnown(component) => PrefixHandle::WellKnown(component),
2192
0
                        Substitution::BackReference(idx) => {
2193
0
                            // TODO: do we need to check that the idx actually points to
2194
0
                            // a Prefix?
2195
0
                            PrefixHandle::BackReference(idx)
2196
                        }
2197
                    });
2198
0
                    tail = tail_tail;
2199
                }
2200
0
                Some(b'T') => {
2201
0
                    // <prefix> ::= <template-param>
2202
0
                    let (param, tail_tail) = TemplateParam::parse(ctx, subs, tail)?;
2203
0
                    current = Some(save(subs, Prefix::TemplateParam(param), tail_tail));
2204
0
                    tail = tail_tail;
2205
                }
2206
                Some(b'D') => {
2207
                    // Either
2208
                    //
2209
                    //     <prefix> ::= <decltype>
2210
                    //
2211
                    // or
2212
                    //
2213
                    //     <prefix> ::= <unqualified-name> ::= <ctor-dtor-name>
2214
0
                    if let Ok((decltype, tail_tail)) = Decltype::parse(ctx, subs, tail) {
2215
0
                        current = Some(save(subs, Prefix::Decltype(decltype), tail_tail));
2216
0
                        tail = tail_tail;
2217
0
                    } else {
2218
0
                        let (name, tail_tail) = UnqualifiedName::parse(ctx, subs, tail)?;
2219
0
                        let prefix = match current {
2220
0
                            None => Prefix::Unqualified(name),
2221
0
                            Some(handle) => Prefix::Nested(handle, name),
2222
                        };
2223
0
                        current = Some(save(subs, prefix, tail_tail));
2224
0
                        tail = tail_tail;
2225
                    }
2226
                }
2227
                Some(b'I')
2228
0
                    if current.is_some() && current.as_ref().unwrap().is_template_prefix() =>
2229
0
                {
2230
0
                    // <prefix> ::= <template-prefix> <template-args>
2231
0
                    let (args, tail_tail) = TemplateArgs::parse(ctx, subs, tail)?;
2232
0
                    let prefix = Prefix::Template(current.unwrap(), args);
2233
0
                    current = Some(save(subs, prefix, tail_tail));
2234
0
                    tail = tail_tail;
2235
                }
2236
0
                Some(c) if current.is_some() && SourceName::starts_with(c) => {
2237
                    // Either
2238
                    //
2239
                    //     <prefix> ::= <unqualified-name> ::= <source-name>
2240
                    //
2241
                    // or
2242
                    //
2243
                    //     <prefix> ::= <data-member-prefix> ::= <prefix> <source-name> M
2244
0
                    debug_assert!(SourceName::starts_with(c));
2245
0
                    debug_assert!(DataMemberPrefix::starts_with(c));
2246
2247
0
                    let (name, tail_tail) = SourceName::parse(ctx, subs, tail)?;
2248
0
                    if tail_tail.peek() == Some(b'M') {
2249
0
                        let prefix = Prefix::DataMember(current.unwrap(), DataMemberPrefix(name));
2250
0
                        current = Some(save(subs, prefix, tail_tail));
2251
0
                        tail = consume(b"M", tail_tail).unwrap();
2252
0
                    } else {
2253
0
                        let name = UnqualifiedName::Source(name);
2254
0
                        let prefix = match current {
2255
0
                            None => Prefix::Unqualified(name),
2256
0
                            Some(handle) => Prefix::Nested(handle, name),
2257
                        };
2258
0
                        current = Some(save(subs, prefix, tail_tail));
2259
0
                        tail = tail_tail;
2260
                    }
2261
                }
2262
0
                Some(c) if UnqualifiedName::starts_with(c, &tail) => {
2263
                    // <prefix> ::= <unqualified-name>
2264
0
                    let (name, tail_tail) = UnqualifiedName::parse(ctx, subs, tail)?;
2265
0
                    let prefix = match current {
2266
0
                        None => Prefix::Unqualified(name),
2267
0
                        Some(handle) => Prefix::Nested(handle, name),
2268
                    };
2269
0
                    current = Some(save(subs, prefix, tail_tail));
2270
0
                    tail = tail_tail;
2271
                }
2272
                Some(_) => {
2273
0
                    if let Some(handle) = current {
2274
0
                        return Ok((handle, tail));
2275
0
                    } else if tail.is_empty() {
2276
0
                        return Err(error::Error::UnexpectedEnd);
2277
                    } else {
2278
0
                        return Err(error::Error::UnexpectedText);
2279
                    }
2280
                }
2281
            }
2282
        }
2283
0
    }
2284
}
2285
2286
impl<'a> GetLeafName<'a> for Prefix {
2287
0
    fn get_leaf_name(&'a self, subs: &'a SubstitutionTable) -> Option<LeafName<'a>> {
2288
0
        match *self {
2289
0
            Prefix::Nested(ref prefix, ref name) => name
2290
0
                .get_leaf_name(subs)
2291
0
                .or_else(|| prefix.get_leaf_name(subs)),
2292
0
            Prefix::Unqualified(ref name) => name.get_leaf_name(subs),
2293
0
            Prefix::Template(ref prefix, _) => prefix.get_leaf_name(subs),
2294
0
            Prefix::DataMember(_, ref name) => name.get_leaf_name(subs),
2295
0
            Prefix::TemplateParam(_) | Prefix::Decltype(_) => None,
2296
        }
2297
0
    }
2298
}
2299
2300
impl GetTemplateArgs for PrefixHandle {
2301
    // XXX: Not an impl GetTemplateArgs for PrefixHandle because the 'me
2302
    // reference to self may not live long enough.
2303
0
    fn get_template_args<'a>(&'a self, subs: &'a SubstitutionTable) -> Option<&'a TemplateArgs> {
2304
0
        match *self {
2305
0
            PrefixHandle::BackReference(idx) => {
2306
0
                if let Some(&Substitutable::Prefix(ref p)) = subs.get(idx) {
2307
0
                    p.get_template_args(subs)
2308
                } else {
2309
0
                    None
2310
                }
2311
            }
2312
0
            PrefixHandle::NonSubstitution(NonSubstitution(idx)) => {
2313
0
                if let Some(&Substitutable::Prefix(ref p)) = subs.get_non_substitution(idx) {
2314
0
                    p.get_template_args(subs)
2315
                } else {
2316
0
                    None
2317
                }
2318
            }
2319
0
            _ => None,
2320
        }
2321
0
    }
2322
}
2323
2324
impl<'subs, W> Demangle<'subs, W> for Prefix
2325
where
2326
    W: 'subs + DemangleWrite,
2327
{
2328
0
    fn demangle<'prev, 'ctx>(
2329
0
        &'subs self,
2330
0
        ctx: &'ctx mut DemangleContext<'subs, W>,
2331
0
        scope: Option<ArgScopeStack<'prev, 'subs>>,
2332
0
    ) -> fmt::Result {
2333
0
        let ctx = try_begin_demangle!(self, ctx, scope);
2334
0
        if ctx.is_template_prefix {
2335
0
            ctx.push_demangle_node(DemangleNodeType::TemplatePrefix);
2336
0
            ctx.is_template_prefix = false;
2337
0
        } else if ctx.is_template_prefix_in_nested_name {
2338
0
            ctx.push_demangle_node(DemangleNodeType::NestedName);
2339
0
            ctx.is_template_prefix_in_nested_name = false;
2340
0
        } else {
2341
0
            ctx.push_demangle_node(DemangleNodeType::Prefix);
2342
0
        }
2343
2344
0
        let ret = match *self {
2345
0
            Prefix::Unqualified(ref unqualified) => unqualified.demangle(ctx, scope),
2346
0
            Prefix::Nested(ref prefix, ref unqualified) => {
2347
0
                prefix.demangle(ctx, scope)?;
2348
0
                if unqualified.accepts_double_colon() {
2349
0
                    write!(ctx, "::")?;
2350
0
                }
2351
0
                unqualified.demangle(ctx, scope)
2352
            }
2353
0
            Prefix::Template(ref prefix, ref args) => {
2354
0
                ctx.is_template_prefix = true;
2355
0
                prefix.demangle(ctx, scope)?;
2356
0
                ctx.is_template_prefix = false;
2357
0
                args.demangle(ctx, scope)
2358
            }
2359
0
            Prefix::TemplateParam(ref param) => param.demangle(ctx, scope),
2360
0
            Prefix::Decltype(ref dt) => dt.demangle(ctx, scope),
2361
0
            Prefix::DataMember(ref prefix, ref member) => {
2362
0
                prefix.demangle(ctx, scope)?;
2363
0
                write!(ctx, "::")?;
2364
0
                member.demangle(ctx, scope)
2365
            }
2366
        };
2367
0
        ctx.pop_demangle_node();
2368
0
        ret
2369
0
    }
Unexecuted instantiation: <cpp_demangle::ast::Prefix as cpp_demangle::ast::Demangle<alloc::string::String>>::demangle
Unexecuted instantiation: <cpp_demangle::ast::Prefix as cpp_demangle::ast::Demangle<_>>::demangle
2370
}
2371
2372
impl IsCtorDtorConversion for Prefix {
2373
0
    fn is_ctor_dtor_conversion(&self, subs: &SubstitutionTable) -> bool {
2374
0
        match *self {
2375
0
            Prefix::Unqualified(ref unqualified) | Prefix::Nested(_, ref unqualified) => {
2376
0
                unqualified.is_ctor_dtor_conversion(subs)
2377
            }
2378
0
            Prefix::Template(ref prefix, _) => prefix.is_ctor_dtor_conversion(subs),
2379
0
            _ => false,
2380
        }
2381
0
    }
2382
}
2383
2384
impl IsCtorDtorConversion for PrefixHandle {
2385
0
    fn is_ctor_dtor_conversion(&self, subs: &SubstitutionTable) -> bool {
2386
0
        match *self {
2387
0
            PrefixHandle::BackReference(idx) => {
2388
0
                if let Some(sub) = subs.get(idx) {
2389
0
                    sub.is_ctor_dtor_conversion(subs)
2390
                } else {
2391
0
                    false
2392
                }
2393
            }
2394
0
            PrefixHandle::NonSubstitution(NonSubstitution(idx)) => {
2395
0
                if let Some(sub) = subs.get_non_substitution(idx) {
2396
0
                    sub.is_ctor_dtor_conversion(subs)
2397
                } else {
2398
0
                    false
2399
                }
2400
            }
2401
0
            PrefixHandle::WellKnown(_) => false,
2402
        }
2403
0
    }
2404
}
2405
2406
impl PrefixHandle {
2407
    // Is this <prefix> also a valid <template-prefix> production? Not to be
2408
    // confused with the `GetTemplateArgs` trait.
2409
0
    fn is_template_prefix(&self) -> bool {
2410
0
        match *self {
2411
0
            PrefixHandle::BackReference(_) | PrefixHandle::WellKnown(_) => true,
2412
0
            PrefixHandle::NonSubstitution(_) => false,
2413
        }
2414
0
    }
2415
}
2416
2417
/// The `<unqualified-name>` production.
2418
///
2419
/// ```text
2420
/// <unqualified-name> ::= <operator-name>
2421
///                    ::= <ctor-dtor-name>
2422
///                    ::= <source-name>
2423
///                    ::= <local-source-name>
2424
///                    ::= <unnamed-type-name>
2425
///                    ::= <abi-tag>
2426
///                    ::= <closure-type-name>
2427
///
2428
/// # I think this is from an older version of the standard. It isn't in the
2429
/// # current version, but all the other demanglers support it, so we will too.
2430
/// <local-source-name> ::= L <source-name> [<discriminator>]
2431
/// ```
2432
0
#[derive(Clone, Debug, PartialEq, Eq)]
2433
pub enum UnqualifiedName {
2434
    /// An operator name.
2435
    Operator(OperatorName),
2436
    /// A constructor or destructor name.
2437
    CtorDtor(CtorDtorName),
2438
    /// A source name.
2439
    Source(SourceName),
2440
    /// A local source name.
2441
    LocalSourceName(SourceName, Option<Discriminator>),
2442
    /// A generated name for an unnamed type.
2443
    UnnamedType(UnnamedTypeName),
2444
    /// An ABI tag.
2445
    ABITag(TaggedName),
2446
    /// A closure type name
2447
    ClosureType(ClosureTypeName),
2448
}
2449
2450
impl Parse for UnqualifiedName {
2451
3.31M
    fn parse<'a, 'b>(
2452
3.31M
        ctx: &'a ParseContext,
2453
3.31M
        subs: &'a mut SubstitutionTable,
2454
3.31M
        input: IndexStr<'b>,
2455
3.31M
    ) -> Result<(UnqualifiedName, IndexStr<'b>)> {
2456
3.31M
        try_begin_parse!("UnqualifiedName", ctx, input);
2457
2458
3.31M
        if let Ok((op, tail)) = OperatorName::parse(ctx, subs, input) {
2459
0
            return Ok((UnqualifiedName::Operator(op), tail));
2460
3.31M
        }
2461
2462
3.31M
        if let Ok((ctor_dtor, tail)) = CtorDtorName::parse(ctx, subs, input) {
2463
0
            return Ok((UnqualifiedName::CtorDtor(ctor_dtor), tail));
2464
3.31M
        }
2465
2466
3.31M
        if let Ok(tail) = consume(b"L", input) {
2467
0
            let (name, tail) = SourceName::parse(ctx, subs, tail)?;
2468
0
            let (discr, tail) = if let Ok((d, t)) = Discriminator::parse(ctx, subs, tail) {
2469
0
                (Some(d), t)
2470
            } else {
2471
0
                (None, tail)
2472
            };
2473
0
            return Ok((UnqualifiedName::LocalSourceName(name, discr), tail));
2474
3.31M
        }
2475
2476
3.31M
        if let Ok((source, tail)) = SourceName::parse(ctx, subs, input) {
2477
0
            return Ok((UnqualifiedName::Source(source), tail));
2478
3.31M
        }
2479
2480
3.31M
        if let Ok((tagged, tail)) = TaggedName::parse(ctx, subs, input) {
2481
0
            return Ok((UnqualifiedName::ABITag(tagged), tail));
2482
3.31M
        }
2483
2484
3.31M
        if let Ok((closure, tail)) = ClosureTypeName::parse(ctx, subs, input) {
2485
0
            return Ok((UnqualifiedName::ClosureType(closure), tail));
2486
3.31M
        }
2487
3.31M
2488
3.31M
        UnnamedTypeName::parse(ctx, subs, input)
2489
3.31M
            .map(|(unnamed, tail)| (UnqualifiedName::UnnamedType(unnamed), tail))
2490
3.31M
    }
2491
}
2492
2493
impl<'subs, W> Demangle<'subs, W> for UnqualifiedName
2494
where
2495
    W: 'subs + DemangleWrite,
2496
{
2497
0
    fn demangle<'prev, 'ctx>(
2498
0
        &'subs self,
2499
0
        ctx: &'ctx mut DemangleContext<'subs, W>,
2500
0
        scope: Option<ArgScopeStack<'prev, 'subs>>,
2501
0
    ) -> fmt::Result {
2502
0
        let ctx = try_begin_demangle!(self, ctx, scope);
2503
2504
0
        ctx.push_demangle_node(DemangleNodeType::UnqualifiedName);
2505
0
        let ret = match *self {
2506
0
            UnqualifiedName::Operator(ref op_name) => {
2507
0
                write!(ctx, "operator")?;
2508
0
                op_name.demangle(ctx, scope)
2509
            }
2510
0
            UnqualifiedName::CtorDtor(ref ctor_dtor) => ctor_dtor.demangle(ctx, scope),
2511
0
            UnqualifiedName::Source(ref name) | UnqualifiedName::LocalSourceName(ref name, ..) => {
2512
0
                name.demangle(ctx, scope)
2513
            }
2514
0
            UnqualifiedName::UnnamedType(ref unnamed) => unnamed.demangle(ctx, scope),
2515
0
            UnqualifiedName::ABITag(ref tagged) => tagged.demangle(ctx, scope),
2516
0
            UnqualifiedName::ClosureType(ref closure) => closure.demangle(ctx, scope),
2517
        };
2518
0
        ctx.pop_demangle_node();
2519
0
        ret
2520
0
    }
Unexecuted instantiation: <cpp_demangle::ast::UnqualifiedName as cpp_demangle::ast::Demangle<alloc::string::String>>::demangle
Unexecuted instantiation: <cpp_demangle::ast::UnqualifiedName as cpp_demangle::ast::Demangle<_>>::demangle
2521
}
2522
2523
impl<'a> GetLeafName<'a> for UnqualifiedName {
2524
0
    fn get_leaf_name(&'a self, subs: &'a SubstitutionTable) -> Option<LeafName<'a>> {
2525
0
        match *self {
2526
            UnqualifiedName::ABITag(_)
2527
            | UnqualifiedName::Operator(_)
2528
0
            | UnqualifiedName::CtorDtor(_) => None,
2529
0
            UnqualifiedName::UnnamedType(ref name) => Some(LeafName::UnnamedType(name)),
2530
0
            UnqualifiedName::ClosureType(ref closure) => closure.get_leaf_name(subs),
2531
0
            UnqualifiedName::Source(ref name) | UnqualifiedName::LocalSourceName(ref name, _) => {
2532
0
                Some(LeafName::SourceName(name))
2533
            }
2534
        }
2535
0
    }
2536
}
2537
2538
impl IsCtorDtorConversion for UnqualifiedName {
2539
    fn is_ctor_dtor_conversion(&self, _: &SubstitutionTable) -> bool {
2540
0
        match *self {
2541
            UnqualifiedName::CtorDtor(_)
2542
0
            | UnqualifiedName::Operator(OperatorName::Conversion(_)) => true,
2543
            UnqualifiedName::Operator(_)
2544
            | UnqualifiedName::Source(_)
2545
            | UnqualifiedName::LocalSourceName(..)
2546
            | UnqualifiedName::UnnamedType(_)
2547
            | UnqualifiedName::ClosureType(_)
2548
0
            | UnqualifiedName::ABITag(_) => false,
2549
        }
2550
0
    }
2551
}
2552
2553
impl UnqualifiedName {
2554
    #[inline]
2555
0
    fn starts_with(byte: u8, input: &IndexStr) -> bool {
2556
0
        byte == b'L'
2557
0
            || OperatorName::starts_with(byte)
2558
0
            || CtorDtorName::starts_with(byte)
2559
0
            || SourceName::starts_with(byte)
2560
0
            || UnnamedTypeName::starts_with(byte)
2561
0
            || TaggedName::starts_with(byte)
2562
0
            || ClosureTypeName::starts_with(byte, input)
2563
0
    }
2564
2565
0
    fn accepts_double_colon(&self) -> bool {
2566
0
        match *self {
2567
            UnqualifiedName::Operator(_)
2568
            | UnqualifiedName::CtorDtor(_)
2569
            | UnqualifiedName::Source(_)
2570
            | UnqualifiedName::LocalSourceName(..)
2571
            | UnqualifiedName::UnnamedType(_)
2572
0
            | UnqualifiedName::ClosureType(_) => true,
2573
0
            UnqualifiedName::ABITag(_) => false,
2574
        }
2575
0
    }
2576
}
2577
2578
/// The `<source-name>` non-terminal.
2579
///
2580
/// ```text
2581
/// <source-name> ::= <positive length number> <identifier>
2582
/// ```
2583
0
#[derive(Clone, Debug, PartialEq, Eq)]
2584
pub struct SourceName(Identifier);
2585
2586
impl Parse for SourceName {
2587
4.14M
    fn parse<'a, 'b>(
2588
4.14M
        ctx: &'a ParseContext,
2589
4.14M
        subs: &'a mut SubstitutionTable,
2590
4.14M
        input: IndexStr<'b>,
2591
4.14M
    ) -> Result<(SourceName, IndexStr<'b>)> {
2592
4.14M
        try_begin_parse!("SourceName", ctx, input);
2593
2594
4.14M
        let (source_name_len, input) = parse_number(10, false, input)?;
2595
0
        debug_assert!(source_name_len >= 0);
2596
0
        if source_name_len == 0 {
2597
0
            return Err(error::Error::UnexpectedText);
2598
0
        }
2599
2600
0
        let (head, tail) = match input.try_split_at(source_name_len as _) {
2601
0
            Some((head, tail)) => (head, tail),
2602
0
            None => return Err(error::Error::UnexpectedEnd),
2603
        };
2604
2605
0
        let (identifier, empty) = Identifier::parse(ctx, subs, head)?;
2606
0
        if !empty.is_empty() {
2607
0
            return Err(error::Error::UnexpectedText);
2608
0
        }
2609
0
2610
0
        let source_name = SourceName(identifier);
2611
0
        Ok((source_name, tail))
2612
4.14M
    }
2613
}
2614
2615
impl<'subs> ArgScope<'subs, 'subs> for SourceName {
2616
0
    fn leaf_name(&'subs self) -> Result<LeafName<'subs>> {
2617
0
        Ok(LeafName::SourceName(self))
2618
0
    }
2619
2620
0
    fn get_template_arg(
2621
0
        &'subs self,
2622
0
        _: usize,
2623
0
    ) -> Result<(&'subs TemplateArg, &'subs TemplateArgs)> {
2624
0
        Err(error::Error::BadTemplateArgReference)
2625
0
    }
2626
2627
0
    fn get_function_arg(&'subs self, _: usize) -> Result<&'subs Type> {
2628
0
        Err(error::Error::BadFunctionArgReference)
2629
0
    }
2630
}
2631
2632
impl SourceName {
2633
    #[inline]
2634
0
    fn starts_with(byte: u8) -> bool {
2635
0
        byte == b'0' || (b'0' <= byte && byte <= b'9')
2636
0
    }
2637
}
2638
2639
impl<'subs, W> Demangle<'subs, W> for SourceName
2640
where
2641
    W: 'subs + DemangleWrite,
2642
{
2643
    #[inline]
2644
0
    fn demangle<'prev, 'ctx>(
2645
0
        &'subs self,
2646
0
        ctx: &'ctx mut DemangleContext<'subs, W>,
2647
0
        scope: Option<ArgScopeStack<'prev, 'subs>>,
2648
0
    ) -> fmt::Result {
2649
0
        let ctx = try_begin_demangle!(self, ctx, scope);
2650
2651
0
        self.0.demangle(ctx, scope)
2652
0
    }
Unexecuted instantiation: <cpp_demangle::ast::SourceName as cpp_demangle::ast::Demangle<alloc::string::String>>::demangle
Unexecuted instantiation: <cpp_demangle::ast::SourceName as cpp_demangle::ast::Demangle<_>>::demangle
2653
}
2654
2655
/// The `<tagged-name>` non-terminal.
2656
///
2657
/// ```text
2658
/// <tagged-name> ::= <name> B <source-name>
2659
/// ```
2660
0
#[derive(Clone, Debug, PartialEq, Eq)]
2661
pub struct TaggedName(SourceName);
2662
2663
impl Parse for TaggedName {
2664
3.31M
    fn parse<'a, 'b>(
2665
3.31M
        ctx: &'a ParseContext,
2666
3.31M
        subs: &'a mut SubstitutionTable,
2667
3.31M
        input: IndexStr<'b>,
2668
3.31M
    ) -> Result<(TaggedName, IndexStr<'b>)> {
2669
3.31M
        try_begin_parse!("TaggedName", ctx, input);
2670
2671
3.31M
        let tail = consume(b"B", input)?;
2672
0
        let (source_name, tail) = SourceName::parse(ctx, subs, tail)?;
2673
0
        Ok((TaggedName(source_name), tail))
2674
3.31M
    }
2675
}
2676
2677
impl<'subs, W> Demangle<'subs, W> for TaggedName
2678
where
2679
    W: 'subs + DemangleWrite,
2680
{
2681
0
    fn demangle<'prev, 'ctx>(
2682
0
        &'subs self,
2683
0
        ctx: &'ctx mut DemangleContext<'subs, W>,
2684
0
        scope: Option<ArgScopeStack<'prev, 'subs>>,
2685
0
    ) -> fmt::Result {
2686
0
        let ctx = try_begin_demangle!(self, ctx, scope);
2687
2688
0
        write!(ctx, "[abi:")?;
2689
0
        self.0.demangle(ctx, scope)?;
2690
0
        write!(ctx, "]")
2691
0
    }
Unexecuted instantiation: <cpp_demangle::ast::TaggedName as cpp_demangle::ast::Demangle<alloc::string::String>>::demangle
Unexecuted instantiation: <cpp_demangle::ast::TaggedName as cpp_demangle::ast::Demangle<_>>::demangle
2692
}
2693
2694
impl TaggedName {
2695
    #[inline]
2696
0
    fn starts_with(byte: u8) -> bool {
2697
0
        byte == b'B'
2698
0
    }
2699
}
2700
2701
/// The `<identifier>` pseudo-terminal.
2702
///
2703
/// ```text
2704
/// <identifier> ::= <unqualified source code identifier>
2705
/// ```
2706
///
2707
/// > `<identifier>` is a pseudo-terminal representing the characters in the
2708
/// > unqualified identifier for the entity in the source code. This ABI does not
2709
/// > yet specify a mangling for identifiers containing characters outside of
2710
/// > `_A-Za-z0-9.`.
2711
///
2712
/// Mangled symbols' identifiers also have `$` characters in the wild.
2713
0
#[derive(Clone, Debug, PartialEq, Eq)]
2714
pub struct Identifier {
2715
    start: usize,
2716
    end: usize,
2717
}
2718
2719
impl Parse for Identifier {
2720
0
    fn parse<'a, 'b>(
2721
0
        ctx: &'a ParseContext,
2722
0
        _subs: &'a mut SubstitutionTable,
2723
0
        input: IndexStr<'b>,
2724
0
    ) -> Result<(Identifier, IndexStr<'b>)> {
2725
0
        try_begin_parse!("Identifier", ctx, input);
2726
2727
0
        if input.is_empty() {
2728
0
            return Err(error::Error::UnexpectedEnd);
2729
0
        }
2730
0
2731
0
        let end = input
2732
0
            .as_ref()
2733
0
            .iter()
2734
0
            .map(|&c| c as char)
2735
0
            .take_while(|&c| c == '$' || c == '_' || c == '.' || c.is_digit(36))
2736
0
            .count();
2737
0
2738
0
        if end == 0 {
2739
0
            return Err(error::Error::UnexpectedText);
2740
0
        }
2741
0
2742
0
        let tail = input.range_from(end..);
2743
0
2744
0
        let identifier = Identifier {
2745
0
            start: input.index(),
2746
0
            end: tail.index(),
2747
0
        };
2748
0
2749
0
        Ok((identifier, tail))
2750
0
    }
2751
}
2752
2753
impl<'subs, W> Demangle<'subs, W> for Identifier
2754
where
2755
    W: 'subs + DemangleWrite,
2756
{
2757
    #[inline]
2758
0
    fn demangle<'prev, 'ctx>(
2759
0
        &'subs self,
2760
0
        ctx: &'ctx mut DemangleContext<'subs, W>,
2761
0
        scope: Option<ArgScopeStack<'prev, 'subs>>,
2762
0
    ) -> fmt::Result {
2763
0
        let ctx = try_begin_demangle!(self, ctx, scope);
2764
2765
0
        let ident = &ctx.input[self.start..self.end];
2766
0
2767
0
        // Handle GCC's anonymous namespace mangling.
2768
0
        let anon_namespace_prefix = b"_GLOBAL_";
2769
0
        if ident.starts_with(anon_namespace_prefix)
2770
0
            && ident.len() >= anon_namespace_prefix.len() + 2
2771
        {
2772
0
            let first = ident[anon_namespace_prefix.len()];
2773
0
            let second = ident[anon_namespace_prefix.len() + 1];
2774
0
2775
0
            match (first, second) {
2776
                (b'.', b'N') | (b'_', b'N') | (b'$', b'N') => {
2777
0
                    write!(ctx, "(anonymous namespace)")?;
2778
0
                    return Ok(());
2779
                }
2780
0
                _ => {
2781
0
                    // Fall through.
2782
0
                }
2783
            }
2784
0
        }
2785
2786
0
        let source_name = String::from_utf8_lossy(ident);
2787
0
        ctx.set_source_name(self.start, self.end);
2788
0
        write!(ctx, "{}", source_name)?;
2789
0
        Ok(())
2790
0
    }
Unexecuted instantiation: <cpp_demangle::ast::Identifier as cpp_demangle::ast::Demangle<alloc::string::String>>::demangle
Unexecuted instantiation: <cpp_demangle::ast::Identifier as cpp_demangle::ast::Demangle<_>>::demangle
2791
}
2792
2793
/// The `<clone-type-identifier>` pseudo-terminal.
2794
///
2795
/// ```text
2796
/// <clone-type-identifier> ::= <unqualified source code identifier>
2797
/// ```
2798
0
#[derive(Clone, Debug, PartialEq, Eq)]
2799
pub struct CloneTypeIdentifier {
2800
    start: usize,
2801
    end: usize,
2802
}
2803
2804
impl Parse for CloneTypeIdentifier {
2805
0
    fn parse<'a, 'b>(
2806
0
        ctx: &'a ParseContext,
2807
0
        _subs: &'a mut SubstitutionTable,
2808
0
        input: IndexStr<'b>,
2809
0
    ) -> Result<(CloneTypeIdentifier, IndexStr<'b>)> {
2810
0
        try_begin_parse!("CloneTypeIdentifier", ctx, input);
2811
2812
0
        if input.is_empty() {
2813
0
            return Err(error::Error::UnexpectedEnd);
2814
0
        }
2815
0
2816
0
        let end = input
2817
0
            .as_ref()
2818
0
            .iter()
2819
0
            .map(|&c| c as char)
2820
0
            .take_while(|&c| c == '$' || c == '_' || c.is_digit(36))
2821
0
            .count();
2822
0
2823
0
        if end == 0 {
2824
0
            return Err(error::Error::UnexpectedText);
2825
0
        }
2826
0
2827
0
        let tail = input.range_from(end..);
2828
0
2829
0
        let identifier = CloneTypeIdentifier {
2830
0
            start: input.index(),
2831
0
            end: tail.index(),
2832
0
        };
2833
0
2834
0
        Ok((identifier, tail))
2835
0
    }
2836
}
2837
2838
impl<'subs, W> Demangle<'subs, W> for CloneTypeIdentifier
2839
where
2840
    W: 'subs + DemangleWrite,
2841
{
2842
    #[inline]
2843
0
    fn demangle<'prev, 'ctx>(
2844
0
        &'subs self,
2845
0
        ctx: &'ctx mut DemangleContext<'subs, W>,
2846
0
        scope: Option<ArgScopeStack<'prev, 'subs>>,
2847
0
    ) -> fmt::Result {
2848
0
        let ctx = try_begin_demangle!(self, ctx, scope);
2849
2850
0
        let ident = &ctx.input[self.start..self.end];
2851
0
2852
0
        let source_name = String::from_utf8_lossy(ident);
2853
0
        ctx.set_source_name(self.start, self.end);
2854
0
        write!(ctx, " .{}", source_name)?;
2855
0
        Ok(())
2856
0
    }
Unexecuted instantiation: <cpp_demangle::ast::CloneTypeIdentifier as cpp_demangle::ast::Demangle<alloc::string::String>>::demangle
Unexecuted instantiation: <cpp_demangle::ast::CloneTypeIdentifier as cpp_demangle::ast::Demangle<_>>::demangle
2857
}
2858
2859
/// The `<number>` production.
2860
///
2861
/// ```text
2862
/// <number> ::= [n] <non-negative decimal integer>
2863
/// ```
2864
type Number = isize;
2865
2866
impl Parse for Number {
2867
0
    fn parse<'a, 'b>(
2868
0
        ctx: &'a ParseContext,
2869
0
        _subs: &'a mut SubstitutionTable,
2870
0
        input: IndexStr<'b>,
2871
0
    ) -> Result<(isize, IndexStr<'b>)> {
2872
0
        try_begin_parse!("Number", ctx, input);
2873
0
        parse_number(10, true, input)
2874
0
    }
2875
}
2876
2877
/// A <seq-id> production encoding a base-36 positive number.
2878
///
2879
/// ```text
2880
/// <seq-id> ::= <0-9A-Z>+
2881
/// ```
2882
0
#[derive(Clone, Debug, PartialEq, Eq)]
2883
pub struct SeqId(usize);
2884
2885
impl Parse for SeqId {
2886
0
    fn parse<'a, 'b>(
2887
0
        ctx: &'a ParseContext,
2888
0
        _subs: &'a mut SubstitutionTable,
2889
0
        input: IndexStr<'b>,
2890
0
    ) -> Result<(SeqId, IndexStr<'b>)> {
2891
0
        try_begin_parse!("SeqId", ctx, input);
2892
2893
0
        parse_number(36, false, input).map(|(num, tail)| (SeqId(num as _), tail))
2894
0
    }
2895
}
2896
2897
/// The `<operator-name>` production.
2898
///
2899
/// ```text
2900
/// <operator-name> ::= <simple-operator-name>
2901
///                 ::= cv <type>               # (cast)
2902
///                 ::= li <source-name>        # operator ""
2903
///                 ::= v <digit> <source-name> # vendor extended operator
2904
/// ```
2905
0
#[derive(Clone, Debug, PartialEq, Eq)]
2906
pub enum OperatorName {
2907
    /// A simple operator name.
2908
    Simple(SimpleOperatorName),
2909
2910
    /// A type cast.
2911
    Cast(TypeHandle),
2912
2913
    /// A type conversion.
2914
    Conversion(TypeHandle),
2915
2916
    /// Operator literal, ie `operator ""`.
2917
    Literal(SourceName),
2918
2919
    /// A non-standard, vendor extension operator.
2920
    VendorExtension(u8, SourceName),
2921
}
2922
2923
impl OperatorName {
2924
0
    fn starts_with(byte: u8) -> bool {
2925
0
        byte == b'c' || byte == b'l' || byte == b'v' || SimpleOperatorName::starts_with(byte)
2926
0
    }
2927
2928
0
    fn arity(&self) -> u8 {
2929
0
        match self {
2930
0
            &OperatorName::Cast(_) | &OperatorName::Conversion(_) | &OperatorName::Literal(_) => 1,
2931
0
            &OperatorName::Simple(ref s) => s.arity(),
2932
0
            &OperatorName::VendorExtension(arity, _) => arity,
2933
        }
2934
0
    }
2935
2936
0
    fn parse_from_expr<'a, 'b>(
2937
0
        ctx: &'a ParseContext,
2938
0
        subs: &'a mut SubstitutionTable,
2939
0
        input: IndexStr<'b>,
2940
0
    ) -> Result<(Expression, IndexStr<'b>)> {
2941
0
        let (operator, tail) = OperatorName::parse_internal(ctx, subs, input, true)?;
2942
2943
0
        let arity = operator.arity();
2944
0
        if arity == 1 {
2945
0
            let (first, tail) = Expression::parse(ctx, subs, tail)?;
2946
0
            let expr = Expression::Unary(operator, Box::new(first));
2947
0
            Ok((expr, tail))
2948
0
        } else if arity == 2 {
2949
0
            let (first, tail) = Expression::parse(ctx, subs, tail)?;
2950
0
            let (second, tail) = Expression::parse(ctx, subs, tail)?;
2951
0
            let expr = Expression::Binary(operator, Box::new(first), Box::new(second));
2952
0
            Ok((expr, tail))
2953
0
        } else if arity == 3 {
2954
0
            let (first, tail) = Expression::parse(ctx, subs, tail)?;
2955
0
            let (second, tail) = Expression::parse(ctx, subs, tail)?;
2956
0
            let (third, tail) = Expression::parse(ctx, subs, tail)?;
2957
0
            let expr =
2958
0
                Expression::Ternary(operator, Box::new(first), Box::new(second), Box::new(third));
2959
0
            Ok((expr, tail))
2960
        } else {
2961
0
            Err(error::Error::UnexpectedText)
2962
        }
2963
0
    }
2964
2965
3.31M
    fn parse_internal<'a, 'b>(
2966
3.31M
        ctx: &'a ParseContext,
2967
3.31M
        subs: &'a mut SubstitutionTable,
2968
3.31M
        input: IndexStr<'b>,
2969
3.31M
        from_expr: bool,
2970
3.31M
    ) -> Result<(OperatorName, IndexStr<'b>)> {
2971
3.31M
        try_begin_parse!("OperatorName", ctx, input);
2972
2973
3.31M
        if let Ok((simple, tail)) = SimpleOperatorName::parse(ctx, subs, input) {
2974
0
            return Ok((OperatorName::Simple(simple), tail));
2975
3.31M
        }
2976
2977
3.31M
        if let Ok(tail) = consume(b"cv", input) {
2978
            // If we came through the expression path, we're a cast. If not,
2979
            // we're a conversion.
2980
0
            let previously_in_conversion = ctx.set_in_conversion(!from_expr);
2981
0
            let parse_result = TypeHandle::parse(ctx, subs, tail);
2982
0
            ctx.set_in_conversion(previously_in_conversion);
2983
0
            let (ty, tail) = parse_result?;
2984
0
            if from_expr {
2985
0
                return Ok((OperatorName::Cast(ty), tail));
2986
            } else {
2987
0
                return Ok((OperatorName::Conversion(ty), tail));
2988
            }
2989
3.31M
        }
2990
2991
3.31M
        if let Ok(tail) = consume(b"li", input) {
2992
0
            let (name, tail) = SourceName::parse(ctx, subs, tail)?;
2993
0
            return Ok((OperatorName::Literal(name), tail));
2994
3.31M
        }
2995
2996
3.31M
        let tail = consume(b"v", input)?;
2997
0
        let (arity, tail) = match tail.peek() {
2998
0
            Some(c) if b'0' <= c && c <= b'9' => (c - b'0', tail.range_from(1..)),
2999
0
            None => return Err(error::Error::UnexpectedEnd),
3000
0
            _ => return Err(error::Error::UnexpectedText),
3001
        };
3002
0
        let (name, tail) = SourceName::parse(ctx, subs, tail)?;
3003
0
        Ok((OperatorName::VendorExtension(arity, name), tail))
3004
3.31M
    }
3005
}
3006
3007
impl Parse for OperatorName {
3008
3.31M
    fn parse<'a, 'b>(
3009
3.31M
        ctx: &'a ParseContext,
3010
3.31M
        subs: &'a mut SubstitutionTable,
3011
3.31M
        input: IndexStr<'b>,
3012
3.31M
    ) -> Result<(OperatorName, IndexStr<'b>)> {
3013
3.31M
        OperatorName::parse_internal(ctx, subs, input, false)
3014
3.31M
    }
3015
}
3016
3017
impl<'subs, W> Demangle<'subs, W> for OperatorName
3018
where
3019
    W: 'subs + DemangleWrite,
3020
{
3021
0
    fn demangle<'prev, 'ctx>(
3022
0
        &'subs self,
3023
0
        ctx: &'ctx mut DemangleContext<'subs, W>,
3024
0
        scope: Option<ArgScopeStack<'prev, 'subs>>,
3025
0
    ) -> fmt::Result {
3026
0
        let ctx = try_begin_demangle!(self, ctx, scope);
3027
3028
0
        match *self {
3029
0
            OperatorName::Simple(ref simple) => {
3030
0
                match *simple {
3031
                    SimpleOperatorName::New
3032
                    | SimpleOperatorName::NewArray
3033
                    | SimpleOperatorName::Delete
3034
                    | SimpleOperatorName::DeleteArray => {
3035
0
                        ctx.ensure_space()?;
3036
                    }
3037
0
                    _ => {}
3038
                }
3039
0
                simple.demangle(ctx, scope)
3040
            }
3041
0
            OperatorName::Cast(ref ty) | OperatorName::Conversion(ref ty) => {
3042
0
                ctx.ensure_space()?;
3043
3044
                // Cast operators can refer to template arguments before they
3045
                // actually appear in the AST, so we go traverse down the tree
3046
                // and fetch them if they exist.
3047
0
                let scope = ty
3048
0
                    .get_template_args(ctx.subs)
3049
0
                    .map_or(scope, |args| scope.push(args));
Unexecuted instantiation: <cpp_demangle::ast::OperatorName as cpp_demangle::ast::Demangle<alloc::string::String>>::demangle::{closure#0}
Unexecuted instantiation: <cpp_demangle::ast::OperatorName as cpp_demangle::ast::Demangle<_>>::demangle::{closure#0}
3050
0
3051
0
                ty.demangle(ctx, scope)?;
3052
0
                Ok(())
3053
            }
3054
0
            OperatorName::Literal(ref name) => {
3055
0
                name.demangle(ctx, scope)?;
3056
0
                write!(ctx, "::operator \"\"")?;
3057
0
                Ok(())
3058
            }
3059
0
            OperatorName::VendorExtension(arity, ref name) => {
3060
0
                // TODO: no idea how this should be demangled...
3061
0
                name.demangle(ctx, scope)?;
3062
0
                write!(ctx, "::operator {}", arity)?;
3063
0
                Ok(())
3064
            }
3065
        }
3066
0
    }
Unexecuted instantiation: <cpp_demangle::ast::OperatorName as cpp_demangle::ast::Demangle<alloc::string::String>>::demangle
Unexecuted instantiation: <cpp_demangle::ast::OperatorName as cpp_demangle::ast::Demangle<_>>::demangle
3067
}
3068
3069
define_vocabulary! {
3070
    /// The `<simple-operator-name>` production.
3071
0
    #[derive(Clone, Debug, PartialEq, Eq)]
Unexecuted instantiation: <cpp_demangle::ast::SimpleOperatorName as core::cmp::PartialEq>::eq
Unexecuted instantiation: <cpp_demangle::ast::SimpleOperatorName as core::cmp::PartialEq>::eq
3072
    pub enum SimpleOperatorName {
3073
        New              (b"nw",  "new",      3),
3074
        NewArray         (b"na",  "new[]",    3),
3075
        Delete           (b"dl",  "delete",   1),
3076
        DeleteArray      (b"da",  "delete[]", 1),
3077
        UnaryPlus        (b"ps",  "+",        1),
3078
        Neg              (b"ng",  "-",        1),
3079
        AddressOf        (b"ad",  "&",        1),
3080
        Deref            (b"de",  "*",        1),
3081
        BitNot           (b"co",  "~",        1),
3082
        Add              (b"pl",  "+",        2),
3083
        Sub              (b"mi",  "-",        2),
3084
        Mul              (b"ml",  "*",        2),
3085
        Div              (b"dv",  "/",        2),
3086
        Rem              (b"rm",  "%",        2),
3087
        BitAnd           (b"an",  "&",        2),
3088
        BitOr            (b"or",  "|",        2),
3089
        BitXor           (b"eo",  "^",        2),
3090
        Assign           (b"aS",  "=",        2),
3091
        AddAssign        (b"pL",  "+=",       2),
3092
        SubAssign        (b"mI",  "-=",       2),
3093
        MulAssign        (b"mL",  "*=",       2),
3094
        DivAssign        (b"dV",  "/=",       2),
3095
        RemAssign        (b"rM",  "%=",       2),
3096
        BitAndAssign     (b"aN",  "&=",       2),
3097
        BitOrAssign      (b"oR",  "|=",       2),
3098
        BitXorAssign     (b"eO",  "^=",       2),
3099
        Shl              (b"ls",  "<<",       2),
3100
        Shr              (b"rs",  ">>",       2),
3101
        ShlAssign        (b"lS",  "<<=",      2),
3102
        ShrAssign        (b"rS",  ">>=",      2),
3103
        Eq               (b"eq",  "==",       2),
3104
        Ne               (b"ne",  "!=",       2),
3105
        Less             (b"lt",  "<",        2),
3106
        Greater          (b"gt",  ">",        2),
3107
        LessEq           (b"le",  "<=",       2),
3108
        GreaterEq        (b"ge",  ">=",       2),
3109
        Not              (b"nt",  "!",        1),
3110
        LogicalAnd       (b"aa",  "&&",       2),
3111
        LogicalOr        (b"oo",  "||",       2),
3112
        PostInc          (b"pp",  "++",       1), // (postfix in <expression> context)
3113
        PostDec          (b"mm",  "--",       1), // (postfix in <expression> context)
3114
        Comma            (b"cm",  ",",        2),
3115
        DerefMemberPtr   (b"pm",  "->*",      2),
3116
        DerefMember      (b"pt",  "->",       2),
3117
        Call             (b"cl",  "()",       2),
3118
        Index            (b"ix",  "[]",       2),
3119
        Question         (b"qu",  "?:",       3),
3120
        Spaceship        (b"ss",  "<=>",      2)
3121
    }
3122
3123
    impl SimpleOperatorName {
3124
        // Automatically implemented by define_vocabulary!
3125
        fn arity(&self) -> u8;
3126
    }
3127
}
3128
3129
/// The `<call-offset>` production.
3130
///
3131
/// ```text
3132
/// <call-offset> ::= h <nv-offset> _
3133
///               ::= v <v-offset> _
3134
/// ```
3135
0
#[derive(Clone, Debug, PartialEq, Eq)]
3136
pub enum CallOffset {
3137
    /// A non-virtual offset.
3138
    NonVirtual(NvOffset),
3139
    /// A virtual offset.
3140
    Virtual(VOffset),
3141
}
3142
3143
impl Parse for CallOffset {
3144
0
    fn parse<'a, 'b>(
3145
0
        ctx: &'a ParseContext,
3146
0
        subs: &'a mut SubstitutionTable,
3147
0
        input: IndexStr<'b>,
3148
0
    ) -> Result<(CallOffset, IndexStr<'b>)> {
3149
0
        try_begin_parse!("CallOffset", ctx, input);
3150
3151
0
        if input.is_empty() {
3152
0
            return Err(error::Error::UnexpectedEnd);
3153
0
        }
3154
3155
0
        if let Ok(tail) = consume(b"h", input) {
3156
0
            let (offset, tail) = NvOffset::parse(ctx, subs, tail)?;
3157
0
            let tail = consume(b"_", tail)?;
3158
0
            return Ok((CallOffset::NonVirtual(offset), tail));
3159
0
        }
3160
3161
0
        if let Ok(tail) = consume(b"v", input) {
3162
0
            let (offset, tail) = VOffset::parse(ctx, subs, tail)?;
3163
0
            let tail = consume(b"_", tail)?;
3164
0
            return Ok((CallOffset::Virtual(offset), tail));
3165
0
        }
3166
0
3167
0
        Err(error::Error::UnexpectedText)
3168
0
    }
3169
}
3170
3171
impl<'subs, W> Demangle<'subs, W> for CallOffset
3172
where
3173
    W: 'subs + DemangleWrite,
3174
{
3175
0
    fn demangle<'prev, 'ctx>(
3176
0
        &'subs self,
3177
0
        ctx: &'ctx mut DemangleContext<'subs, W>,
3178
0
        scope: Option<ArgScopeStack<'prev, 'subs>>,
3179
0
    ) -> fmt::Result {
3180
0
        let ctx = try_begin_demangle!(self, ctx, scope);
3181
3182
0
        match *self {
3183
0
            CallOffset::NonVirtual(NvOffset(offset)) => {
3184
0
                write!(ctx, "{{offset({})}}", offset)?;
3185
            }
3186
0
            CallOffset::Virtual(VOffset(vbase, vcall)) => {
3187
0
                write!(ctx, "{{virtual offset({}, {})}}", vbase, vcall)?;
3188
            }
3189
        }
3190
0
        Ok(())
3191
0
    }
Unexecuted instantiation: <cpp_demangle::ast::CallOffset as cpp_demangle::ast::Demangle<alloc::string::String>>::demangle
Unexecuted instantiation: <cpp_demangle::ast::CallOffset as cpp_demangle::ast::Demangle<_>>::demangle
3192
}
3193
3194
/// A non-virtual offset, as described by the <nv-offset> production.
3195
///
3196
/// ```text
3197
/// <nv-offset> ::= <offset number>
3198
/// ```
3199
0
#[derive(Clone, Debug, PartialEq, Eq)]
3200
pub struct NvOffset(isize);
3201
3202
impl Parse for NvOffset {
3203
0
    fn parse<'a, 'b>(
3204
0
        ctx: &'a ParseContext,
3205
0
        subs: &'a mut SubstitutionTable,
3206
0
        input: IndexStr<'b>,
3207
0
    ) -> Result<(NvOffset, IndexStr<'b>)> {
3208
0
        try_begin_parse!("NvOffset", ctx, input);
3209
3210
0
        Number::parse(ctx, subs, input).map(|(num, tail)| (NvOffset(num), tail))
3211
0
    }
3212
}
3213
3214
/// A virtual offset, as described by the <v-offset> production.
3215
///
3216
/// ```text
3217
/// <v-offset> ::= <offset number> _ <virtual offset number>
3218
/// ```
3219
0
#[derive(Clone, Debug, PartialEq, Eq)]
3220
pub struct VOffset(isize, isize);
3221
3222
impl Parse for VOffset {
3223
0
    fn parse<'a, 'b>(
3224
0
        ctx: &'a ParseContext,
3225
0
        subs: &'a mut SubstitutionTable,
3226
0
        input: IndexStr<'b>,
3227
0
    ) -> Result<(VOffset, IndexStr<'b>)> {
3228
0
        try_begin_parse!("VOffset", ctx, input);
3229
3230
0
        let (offset, tail) = Number::parse(ctx, subs, input)?;
3231
0
        let tail = consume(b"_", tail)?;
3232
0
        let (virtual_offset, tail) = Number::parse(ctx, subs, tail)?;
3233
0
        Ok((VOffset(offset, virtual_offset), tail))
3234
0
    }
3235
}
3236
3237
/// The `<ctor-dtor-name>` production.
3238
///
3239
/// ```text
3240
/// <ctor-dtor-name> ::= C1  # complete object constructor
3241
///                  ::= C2  # base object constructor
3242
///                  ::= C3  # complete object allocating constructor
3243
///                  ::= D0  # deleting destructor
3244
///                  ::= D1  # complete object destructor
3245
///                  ::= D2  # base object destructor
3246
/// ```
3247
///
3248
/// GCC also emits a C4 constructor under some conditions when building
3249
/// an optimized binary. GCC's source says:
3250
///
3251
/// ```
3252
/// /* This is the old-style "[unified]" constructor.
3253
///    In some cases, we may emit this function and call
3254
///    it from the clones in order to share code and save space.  */
3255
/// ```
3256
///
3257
/// Based on the GCC source we'll call this the "maybe in-charge constructor".
3258
/// Similarly, there is a D4 destructor, the "maybe in-charge destructor".
3259
0
#[derive(Clone, Debug, PartialEq, Eq)]
3260
pub enum CtorDtorName {
3261
    /// "C1", the "complete object constructor"
3262
    CompleteConstructor(Option<TypeHandle>),
3263
    /// "C2", the "base object constructor"
3264
    BaseConstructor(Option<TypeHandle>),
3265
    /// "C3", the "complete object allocating constructor"
3266
    CompleteAllocatingConstructor(Option<TypeHandle>),
3267
    /// "C4", the "maybe in-charge constructor"
3268
    MaybeInChargeConstructor(Option<TypeHandle>),
3269
    /// "D0", the "deleting destructor"
3270
    DeletingDestructor,
3271
    /// "D1", the "complete object destructor"
3272
    CompleteDestructor,
3273
    /// "D2", the "base object destructor"
3274
    BaseDestructor,
3275
    /// "D4", the "maybe in-charge destructor"
3276
    MaybeInChargeDestructor,
3277
}
3278
3279
impl CtorDtorName {
3280
0
    fn inheriting_mut(&mut self) -> &mut Option<TypeHandle> {
3281
0
        match self {
3282
0
            CtorDtorName::CompleteConstructor(ref mut inheriting)
3283
0
            | CtorDtorName::BaseConstructor(ref mut inheriting)
3284
0
            | CtorDtorName::CompleteAllocatingConstructor(ref mut inheriting)
3285
0
            | CtorDtorName::MaybeInChargeConstructor(ref mut inheriting) => inheriting,
3286
            CtorDtorName::DeletingDestructor
3287
            | CtorDtorName::CompleteDestructor
3288
            | CtorDtorName::BaseDestructor
3289
0
            | CtorDtorName::MaybeInChargeDestructor => unreachable!(),
3290
        }
3291
0
    }
3292
}
3293
3294
impl Parse for CtorDtorName {
3295
3.31M
    fn parse<'a, 'b>(
3296
3.31M
        ctx: &'a ParseContext,
3297
3.31M
        subs: &'a mut SubstitutionTable,
3298
3.31M
        input: IndexStr<'b>,
3299
3.31M
    ) -> Result<(CtorDtorName, IndexStr<'b>)> {
3300
3.31M
        try_begin_parse!(stringify!(CtorDtorName), ctx, input);
3301
3302
3.31M
        match input.peek() {
3303
            Some(b'C') => {
3304
0
                let mut tail = consume(b"C", input)?;
3305
0
                let inheriting = match tail.peek() {
3306
                    Some(b'I') => {
3307
0
                        tail = consume(b"I", tail)?;
3308
0
                        true
3309
                    }
3310
0
                    _ => false,
3311
                };
3312
3313
0
                let mut ctor_type: CtorDtorName = match tail
3314
0
                    .try_split_at(1)
3315
0
                    .as_ref()
3316
0
                    .map(|&(ref h, t)| (h.as_ref(), t))
3317
                {
3318
0
                    None => Err(error::Error::UnexpectedEnd),
3319
0
                    Some((b"1", t)) => {
3320
0
                        tail = t;
3321
0
                        Ok(CtorDtorName::CompleteConstructor(None))
3322
                    }
3323
0
                    Some((b"2", t)) => {
3324
0
                        tail = t;
3325
0
                        Ok(CtorDtorName::BaseConstructor(None))
3326
                    }
3327
0
                    Some((b"3", t)) => {
3328
0
                        tail = t;
3329
0
                        Ok(CtorDtorName::CompleteAllocatingConstructor(None))
3330
                    }
3331
0
                    Some((b"4", t)) => {
3332
0
                        tail = t;
3333
0
                        Ok(CtorDtorName::MaybeInChargeConstructor(None))
3334
                    }
3335
0
                    _ => Err(error::Error::UnexpectedText),
3336
0
                }?;
3337
3338
0
                if inheriting {
3339
0
                    let (ty, tail) = TypeHandle::parse(ctx, subs, tail)?;
3340
0
                    *ctor_type.inheriting_mut() = Some(ty);
3341
0
                    Ok((ctor_type, tail))
3342
                } else {
3343
0
                    Ok((ctor_type, tail))
3344
                }
3345
            }
3346
            Some(b'D') => {
3347
0
                match input
3348
0
                    .try_split_at(2)
3349
0
                    .as_ref()
3350
0
                    .map(|&(ref h, t)| (h.as_ref(), t))
3351
                {
3352
0
                    Some((b"D0", tail)) => Ok((CtorDtorName::DeletingDestructor, tail)),
3353
0
                    Some((b"D1", tail)) => Ok((CtorDtorName::CompleteDestructor, tail)),
3354
0
                    Some((b"D2", tail)) => Ok((CtorDtorName::BaseDestructor, tail)),
3355
0
                    Some((b"D4", tail)) => Ok((CtorDtorName::MaybeInChargeDestructor, tail)),
3356
0
                    _ => Err(error::Error::UnexpectedText),
3357
                }
3358
            }
3359
0
            None => Err(error::Error::UnexpectedEnd),
3360
3.31M
            _ => Err(error::Error::UnexpectedText),
3361
        }
3362
3.31M
    }
3363
}
3364
3365
impl<'subs, W> Demangle<'subs, W> for CtorDtorName
3366
where
3367
    W: 'subs + DemangleWrite,
3368
{
3369
0
    fn demangle<'prev, 'ctx>(
3370
0
        &'subs self,
3371
0
        ctx: &'ctx mut DemangleContext<'subs, W>,
3372
0
        scope: Option<ArgScopeStack<'prev, 'subs>>,
3373
0
    ) -> fmt::Result {
3374
0
        let ctx = try_begin_demangle!(self, ctx, scope);
3375
3376
0
        let leaf = scope.leaf_name().map_err(|e| {
3377
0
            log!("Error getting leaf name: {}", e);
3378
0
            fmt::Error
3379
0
        })?;
Unexecuted instantiation: <cpp_demangle::ast::CtorDtorName as cpp_demangle::ast::Demangle<alloc::string::String>>::demangle::{closure#0}
Unexecuted instantiation: <cpp_demangle::ast::CtorDtorName as cpp_demangle::ast::Demangle<_>>::demangle::{closure#0}
3380
3381
0
        match *self {
3382
0
            CtorDtorName::CompleteConstructor(ref inheriting)
3383
0
            | CtorDtorName::BaseConstructor(ref inheriting)
3384
0
            | CtorDtorName::CompleteAllocatingConstructor(ref inheriting)
3385
0
            | CtorDtorName::MaybeInChargeConstructor(ref inheriting) => match inheriting {
3386
0
                Some(ty) => ty
3387
0
                    .get_leaf_name(ctx.subs)
3388
0
                    .ok_or_else(|| {
3389
0
                        log!("Error getting leaf name: {:?}", ty);
3390
0
                        fmt::Error
3391
0
                    })?
Unexecuted instantiation: <cpp_demangle::ast::CtorDtorName as cpp_demangle::ast::Demangle<alloc::string::String>>::demangle::{closure#1}
Unexecuted instantiation: <cpp_demangle::ast::CtorDtorName as cpp_demangle::ast::Demangle<_>>::demangle::{closure#1}
3392
0
                    .demangle_as_leaf(ctx),
3393
0
                None => leaf.demangle_as_leaf(ctx),
3394
            },
3395
            CtorDtorName::DeletingDestructor
3396
            | CtorDtorName::CompleteDestructor
3397
            | CtorDtorName::BaseDestructor
3398
            | CtorDtorName::MaybeInChargeDestructor => {
3399
0
                write!(ctx, "~")?;
3400
0
                leaf.demangle_as_leaf(ctx)
3401
            }
3402
        }
3403
0
    }
Unexecuted instantiation: <cpp_demangle::ast::CtorDtorName as cpp_demangle::ast::Demangle<alloc::string::String>>::demangle
Unexecuted instantiation: <cpp_demangle::ast::CtorDtorName as cpp_demangle::ast::Demangle<_>>::demangle
3404
}
3405
3406
impl CtorDtorName {
3407
    #[inline]
3408
0
    fn starts_with(byte: u8) -> bool {
3409
0
        byte == b'C' || byte == b'D'
3410
0
    }
3411
}
3412
3413
/// The `<type>` production.
3414
///
3415
/// ```text
3416
/// <type> ::= <builtin-type>
3417
///        ::= <function-type>
3418
///        ::= <class-enum-type>
3419
///        ::= <array-type>
3420
///        ::= <vector-type>
3421
///        ::= <pointer-to-member-type>
3422
///        ::= <template-param>
3423
///        ::= <template-template-param> <template-args>
3424
///        ::= <decltype>
3425
///        ::= <CV-qualifiers> <type>
3426
///        ::= P <type>                                 # pointer-to
3427
///        ::= R <type>                                 # reference-to
3428
///        ::= O <type>                                 # rvalue reference-to (C++0x)
3429
///        ::= C <type>                                 # complex pair (C 2000)
3430
///        ::= G <type>                                 # imaginary (C 2000)
3431
///        ::= U <source-name> [<template-args>] <type> # vendor extended type qualifier
3432
///        ::= Dp <type>                                # pack expansion (C++0x)
3433
///        ::= <substitution>
3434
/// ```
3435
0
#[derive(Clone, Debug, PartialEq, Eq)]
3436
#[allow(clippy::large_enum_variant)]
3437
pub enum Type {
3438
    /// A function type.
3439
    Function(FunctionType),
3440
3441
    /// A class, union, or enum type.
3442
    ClassEnum(ClassEnumType),
3443
3444
    /// An array type.
3445
    Array(ArrayType),
3446
3447
    /// A vector type.
3448
    Vector(VectorType),
3449
3450
    /// A pointer-to-member type.
3451
    PointerToMember(PointerToMemberType),
3452
3453
    /// A named template parameter type.
3454
    TemplateParam(TemplateParam),
3455
3456
    /// A template template type.
3457
    TemplateTemplate(TemplateTemplateParamHandle, TemplateArgs),
3458
3459
    /// A decltype.
3460
    Decltype(Decltype),
3461
3462
    /// A const-, restrict-, and/or volatile-qualified type.
3463
    Qualified(CvQualifiers, TypeHandle),
3464
3465
    /// A pointer to a type.
3466
    PointerTo(TypeHandle),
3467
3468
    /// An lvalue reference to a type.
3469
    LvalueRef(TypeHandle),
3470
3471
    /// An rvalue reference to a type.
3472
    RvalueRef(TypeHandle),
3473
3474
    /// A complex pair of the given type.
3475
    Complex(TypeHandle),
3476
3477
    /// An imaginary of the given type.
3478
    Imaginary(TypeHandle),
3479
3480
    /// A vendor extended type qualifier.
3481
    VendorExtension(SourceName, Option<TemplateArgs>, TypeHandle),
3482
3483
    /// A pack expansion.
3484
    PackExpansion(TypeHandle),
3485
}
3486
3487
0
define_handle! {
3488
0
    /// A reference to a parsed `Type` production.
3489
0
    pub enum TypeHandle {
3490
0
        /// A builtin type. These don't end up in the substitutions table.
3491
0
        extra Builtin(BuiltinType),
3492
0
3493
0
        /// A CV-qualified builtin type. These don't end up in the table either.
3494
0
        extra QualifiedBuiltin(QualifiedBuiltin),
3495
0
    }
3496
0
}
3497
3498
impl TypeHandle {
3499
    fn is_void(&self) -> bool {
3500
0
        match *self {
3501
0
            TypeHandle::Builtin(BuiltinType::Standard(StandardBuiltinType::Void)) => true,
3502
0
            _ => false,
3503
        }
3504
0
    }
3505
}
3506
3507
impl Parse for TypeHandle {
3508
2.52M
    fn parse<'a, 'b>(
3509
2.52M
        ctx: &'a ParseContext,
3510
2.52M
        subs: &'a mut SubstitutionTable,
3511
2.52M
        input: IndexStr<'b>,
3512
2.52M
    ) -> Result<(TypeHandle, IndexStr<'b>)> {
3513
2.52M
        try_begin_parse!("TypeHandle", ctx, input);
3514
3515
        /// Insert the given type into the substitution table, and return a
3516
        /// handle referencing the index in the table where it ended up.
3517
0
        fn insert_and_return_handle<'a, 'b>(
3518
0
            ty: Type,
3519
0
            subs: &'a mut SubstitutionTable,
3520
0
            tail: IndexStr<'b>,
3521
0
        ) -> Result<(TypeHandle, IndexStr<'b>)> {
3522
0
            let ty = Substitutable::Type(ty);
3523
0
            let idx = subs.insert(ty);
3524
0
            let handle = TypeHandle::BackReference(idx);
3525
0
            Ok((handle, tail))
3526
0
        }
3527
3528
2.52M
        if let Ok((builtin, tail)) = BuiltinType::parse(ctx, subs, input) {
3529
            // Builtin types are one of two exceptions that do not end up in the
3530
            // substitutions table.
3531
863k
            let handle = TypeHandle::Builtin(builtin);
3532
863k
            return Ok((handle, tail));
3533
1.65M
        }
3534
3535
1.65M
        if let Ok((ty, tail)) = ClassEnumType::parse(ctx, subs, input) {
3536
0
            let ty = Type::ClassEnum(ty);
3537
0
            return insert_and_return_handle(ty, subs, tail);
3538
1.65M
        }
3539
3540
1.65M
        if let Ok((sub, tail)) = Substitution::parse(ctx, subs, input) {
3541
            // If we see an 'I', then this is actually a substitution for a
3542
            // <template-template-param>, and the template args are what
3543
            // follows. Throw away what we just parsed, and re-parse it in
3544
            // `TemplateTemplateParamHandle::parse` for now, but it would be
3545
            // nice not to duplicate work we've already done.
3546
0
            if tail.peek() != Some(b'I') {
3547
0
                match sub {
3548
0
                    Substitution::WellKnown(component) => {
3549
0
                        return Ok((TypeHandle::WellKnown(component), tail));
3550
                    }
3551
0
                    Substitution::BackReference(idx) => {
3552
0
                        // TODO: should this check if the back reference actually points
3553
0
                        // to a <type>?
3554
0
                        return Ok((TypeHandle::BackReference(idx), tail));
3555
                    }
3556
                }
3557
0
            }
3558
1.65M
        }
3559
3560
1.65M
        if let Ok((funty, tail)) = FunctionType::parse(ctx, subs, input) {
3561
0
            let ty = Type::Function(funty);
3562
0
            return insert_and_return_handle(ty, subs, tail);
3563
1.65M
        }
3564
3565
1.65M
        if let Ok((ty, tail)) = ArrayType::parse(ctx, subs, input) {
3566
0
            let ty = Type::Array(ty);
3567
0
            return insert_and_return_handle(ty, subs, tail);
3568
1.65M
        }
3569
3570
1.65M
        if let Ok((ty, tail)) = VectorType::parse(ctx, subs, input) {
3571
0
            let ty = Type::Vector(ty);
3572
0
            return insert_and_return_handle(ty, subs, tail);
3573
1.65M
        }
3574
3575
1.65M
        if let Ok((ty, tail)) = PointerToMemberType::parse(ctx, subs, input) {
3576
0
            let ty = Type::PointerToMember(ty);
3577
0
            return insert_and_return_handle(ty, subs, tail);
3578
1.65M
        }
3579
3580
1.65M
        if let Ok((param, tail)) = TemplateParam::parse(ctx, subs, input) {
3581
            // Same situation as with `Substitution::parse` at the top of this
3582
            // function: this is actually a <template-template-param> and
3583
            // <template-args>.
3584
0
            if tail.peek() != Some(b'I') {
3585
0
                let ty = Type::TemplateParam(param);
3586
0
                return insert_and_return_handle(ty, subs, tail);
3587
0
            } else if ctx.in_conversion() {
3588
                // This may be <template-template-param> <template-args>.
3589
                // But if we're here for a conversion operator, that's only
3590
                // possible if the grammar looks like:
3591
                //
3592
                // <nested-name>
3593
                // -> <source-name> cv <template-template-param> <template-args> <template-args>
3594
                //
3595
                // That is, there must be *another* <template-args> production after ours.
3596
                // If there isn't one, then this really is a <template-param>.
3597
                //
3598
                // NB: Parsing a <template-args> production may modify the substitutions
3599
                // table, so we need to avoid contaminating the official copy.
3600
0
                let mut tmp_subs = subs.clone();
3601
0
                if let Ok((_, new_tail)) = TemplateArgs::parse(ctx, &mut tmp_subs, tail) {
3602
0
                    if new_tail.peek() != Some(b'I') {
3603
                        // Don't consume the TemplateArgs.
3604
0
                        let ty = Type::TemplateParam(param);
3605
0
                        return insert_and_return_handle(ty, subs, tail);
3606
0
                    }
3607
                    // We really do have a <template-template-param>. Fall through.
3608
                    // NB: We can't use the arguments we just parsed because a
3609
                    // TemplateTemplateParam is substitutable, and if we use it
3610
                    // any substitutions in the arguments will come *before* it,
3611
                    // putting the substitution table out of order.
3612
0
                }
3613
0
            }
3614
1.65M
        }
3615
3616
1.65M
        if let Ok((ttp, tail)) = TemplateTemplateParamHandle::parse(ctx, subs, input) {
3617
0
            let (args, tail) = TemplateArgs::parse(ctx, subs, tail)?;
3618
0
            let ty = Type::TemplateTemplate(ttp, args);
3619
0
            return insert_and_return_handle(ty, subs, tail);
3620
1.65M
        }
3621
3622
1.65M
        if let Ok((param, tail)) = Decltype::parse(ctx, subs, input) {
3623
0
            let ty = Type::Decltype(param);
3624
0
            return insert_and_return_handle(ty, subs, tail);
3625
1.65M
        }
3626
3627
1.65M
        if let Ok((qualifiers, tail)) = CvQualifiers::parse(ctx, subs, input) {
3628
            // CvQualifiers can parse successfully without consuming any input,
3629
            // but we don't want to recurse unless we know we did consume some
3630
            // input, lest we go into an infinite loop and blow the stack.
3631
1.65M
            if tail.len() < input.len() {
3632
828k
                let (ty, tail) = TypeHandle::parse(ctx, subs, tail)?;
3633
0
                let ty = Type::Qualified(qualifiers, ty);
3634
0
                return insert_and_return_handle(ty, subs, tail);
3635
828k
            }
3636
0
        }
3637
3638
828k
        if let Ok(tail) = consume(b"P", input) {
3639
0
            let (ty, tail) = TypeHandle::parse(ctx, subs, tail)?;
3640
0
            let ty = Type::PointerTo(ty);
3641
0
            return insert_and_return_handle(ty, subs, tail);
3642
828k
        }
3643
3644
828k
        if let Ok(tail) = consume(b"R", input) {
3645
0
            let (ty, tail) = TypeHandle::parse(ctx, subs, tail)?;
3646
0
            let ty = Type::LvalueRef(ty);
3647
0
            return insert_and_return_handle(ty, subs, tail);
3648
828k
        }
3649
3650
828k
        if let Ok(tail) = consume(b"O", input) {
3651
0
            let (ty, tail) = TypeHandle::parse(ctx, subs, tail)?;
3652
0
            let ty = Type::RvalueRef(ty);
3653
0
            return insert_and_return_handle(ty, subs, tail);
3654
828k
        }
3655
3656
828k
        if let Ok(tail) = consume(b"C", input) {
3657
0
            let (ty, tail) = TypeHandle::parse(ctx, subs, tail)?;
3658
0
            let ty = Type::Complex(ty);
3659
0
            return insert_and_return_handle(ty, subs, tail);
3660
828k
        }
3661
3662
828k
        if let Ok(tail) = consume(b"G", input) {
3663
0
            let (ty, tail) = TypeHandle::parse(ctx, subs, tail)?;
3664
0
            let ty = Type::Imaginary(ty);
3665
0
            return insert_and_return_handle(ty, subs, tail);
3666
828k
        }
3667
3668
828k
        if let Ok(tail) = consume(b"U", input) {
3669
0
            let (name, tail) = SourceName::parse(ctx, subs, tail)?;
3670
0
            let (args, tail) = if let Ok((args, tail)) = TemplateArgs::parse(ctx, subs, tail) {
3671
0
                (Some(args), tail)
3672
            } else {
3673
0
                (None, tail)
3674
            };
3675
0
            let (ty, tail) = TypeHandle::parse(ctx, subs, tail)?;
3676
0
            let ty = Type::VendorExtension(name, args, ty);
3677
0
            return insert_and_return_handle(ty, subs, tail);
3678
828k
        }
3679
3680
828k
        let tail = consume(b"Dp", input)?;
3681
0
        let (ty, tail) = TypeHandle::parse(ctx, subs, tail)?;
3682
0
        let ty = Type::PackExpansion(ty);
3683
0
        insert_and_return_handle(ty, subs, tail)
3684
2.52M
    }
3685
}
3686
3687
impl GetTemplateArgs for TypeHandle {
3688
0
    fn get_template_args<'a>(&'a self, subs: &'a SubstitutionTable) -> Option<&'a TemplateArgs> {
3689
0
        subs.get_type(self)
3690
0
            .and_then(|ty| ty.get_template_args(subs))
3691
0
    }
3692
}
3693
3694
impl<'subs, W> Demangle<'subs, W> for Type
3695
where
3696
    W: 'subs + DemangleWrite,
3697
{
3698
0
    fn demangle<'prev, 'ctx>(
3699
0
        &'subs self,
3700
0
        ctx: &'ctx mut DemangleContext<'subs, W>,
3701
0
        scope: Option<ArgScopeStack<'prev, 'subs>>,
3702
0
    ) -> fmt::Result {
3703
0
        let ctx = try_begin_demangle!(self, ctx, scope);
3704
3705
0
        match *self {
3706
0
            Type::Function(ref func_ty) => func_ty.demangle(ctx, scope),
3707
0
            Type::ClassEnum(ref cls_enum_ty) => cls_enum_ty.demangle(ctx, scope),
3708
0
            Type::Array(ref array_ty) => array_ty.demangle(ctx, scope),
3709
0
            Type::Vector(ref vector_ty) => vector_ty.demangle(ctx, scope),
3710
0
            Type::PointerToMember(ref ptm) => ptm.demangle(ctx, scope),
3711
0
            Type::TemplateParam(ref param) => param.demangle(ctx, scope),
3712
0
            Type::TemplateTemplate(ref tt_param, ref args) => {
3713
0
                tt_param.demangle(ctx, scope)?;
3714
0
                args.demangle(ctx, scope)
3715
            }
3716
0
            Type::Decltype(ref dt) => dt.demangle(ctx, scope),
3717
0
            Type::Qualified(_, ref ty) => {
3718
0
                ctx.push_inner(self);
3719
0
                ty.demangle(ctx, scope)?;
3720
0
                if ctx.pop_inner_if(self) {
3721
0
                    self.demangle_as_inner(ctx, scope)?;
3722
0
                }
3723
0
                Ok(())
3724
            }
3725
0
            Type::PointerTo(ref ty) | Type::LvalueRef(ref ty) | Type::RvalueRef(ref ty) => {
3726
0
                ctx.push_inner(self);
3727
0
                ty.demangle(ctx, scope)?;
3728
0
                if ctx.pop_inner_if(self) {
3729
0
                    self.demangle_as_inner(ctx, scope)?;
3730
0
                }
3731
0
                Ok(())
3732
            }
3733
0
            Type::Complex(ref ty) => {
3734
0
                ty.demangle(ctx, scope)?;
3735
0
                write!(ctx, " complex")?;
3736
0
                Ok(())
3737
            }
3738
0
            Type::Imaginary(ref ty) => {
3739
0
                ty.demangle(ctx, scope)?;
3740
0
                write!(ctx, " imaginary")?;
3741
0
                Ok(())
3742
            }
3743
0
            Type::VendorExtension(ref name, ref template_args, ref ty) => {
3744
0
                ty.demangle(ctx, scope)?;
3745
0
                write!(ctx, " ")?;
3746
0
                name.demangle(ctx, scope)?;
3747
0
                if let Some(ref args) = *template_args {
3748
0
                    args.demangle(ctx, scope)?;
3749
0
                }
3750
0
                Ok(())
3751
            }
3752
0
            Type::PackExpansion(ref ty) => {
3753
0
                ty.demangle(ctx, scope)?;
3754
0
                if !ctx.is_template_argument_pack {
3755
0
                    write!(ctx, "...")?;
3756
0
                }
3757
0
                Ok(())
3758
            }
3759
        }
3760
0
    }
Unexecuted instantiation: <cpp_demangle::ast::Type as cpp_demangle::ast::Demangle<alloc::string::String>>::demangle
Unexecuted instantiation: <cpp_demangle::ast::Type as cpp_demangle::ast::Demangle<_>>::demangle
3761
}
3762
3763
impl<'subs, W> DemangleAsInner<'subs, W> for Type
3764
where
3765
    W: 'subs + DemangleWrite,
3766
{
3767
0
    fn demangle_as_inner<'prev, 'ctx>(
3768
0
        &'subs self,
3769
0
        ctx: &'ctx mut DemangleContext<'subs, W>,
3770
0
        scope: Option<ArgScopeStack<'prev, 'subs>>,
3771
0
    ) -> fmt::Result {
3772
0
        let ctx = try_begin_demangle_as_inner!(self, ctx, scope);
3773
3774
0
        match *self {
3775
0
            Type::Qualified(ref quals, _) => quals.demangle_as_inner(ctx, scope),
3776
0
            Type::PointerTo(_) => write!(ctx, "*"),
3777
            Type::RvalueRef(_) => {
3778
0
                while let Some(v) = ctx.inner.last().and_then(|ty| ty.downcast_to_type()) {
Unexecuted instantiation: <cpp_demangle::ast::Type as cpp_demangle::ast::DemangleAsInner<alloc::string::String>>::demangle_as_inner::{closure#0}
Unexecuted instantiation: <cpp_demangle::ast::Type as cpp_demangle::ast::DemangleAsInner<_>>::demangle_as_inner::{closure#0}
3779
0
                    match v {
3780
                        // Two r-value references combine into a single r-value reference
3781
                        // Consume any adjacent r-value references on the inner stack.
3782
0
                        Type::RvalueRef(_) => {
3783
0
                            ctx.inner.pop().unwrap();
3784
0
                        }
3785
                        // An r-value and an l-value reference combine into an l-value reference.
3786
                        // Skip printing this, and allow the LvalueRef implementation to
3787
                        // continue combining references.
3788
0
                        Type::LvalueRef(_) => return Ok(()),
3789
0
                        _ => break,
3790
                    }
3791
                }
3792
0
                write!(ctx, "&&")
3793
            }
3794
            Type::LvalueRef(_) => {
3795
0
                while let Some(v) = ctx.inner.last().and_then(|ty| ty.downcast_to_type()) {
Unexecuted instantiation: <cpp_demangle::ast::Type as cpp_demangle::ast::DemangleAsInner<alloc::string::String>>::demangle_as_inner::{closure#1}
Unexecuted instantiation: <cpp_demangle::ast::Type as cpp_demangle::ast::DemangleAsInner<_>>::demangle_as_inner::{closure#1}
3796
0
                    match v {
3797
                        // An l-value reference combines with an r-value reference to form a
3798
                        // single l-value reference. Consume any adjacent r-value references
3799
                        // on the inner stack.
3800
0
                        Type::RvalueRef(_) => {
3801
0
                            ctx.inner.pop().unwrap();
3802
0
                        }
3803
                        // Two l-value references combine to form a single l-value reference.
3804
                        // Skip printing this, and allow the LvalueRef implementation for
3805
                        // the next l-value reference to continue combining references.
3806
0
                        Type::LvalueRef(_) => return Ok(()),
3807
0
                        _ => break,
3808
                    }
3809
                }
3810
0
                write!(ctx, "&")
3811
            }
3812
0
            ref otherwise => {
3813
0
                unreachable!(
3814
0
                    "We shouldn't ever put any other types on the inner stack: {:?}",
3815
0
                    otherwise
3816
0
                );
3817
            }
3818
        }
3819
0
    }
Unexecuted instantiation: <cpp_demangle::ast::Type as cpp_demangle::ast::DemangleAsInner<alloc::string::String>>::demangle_as_inner
Unexecuted instantiation: <cpp_demangle::ast::Type as cpp_demangle::ast::DemangleAsInner<_>>::demangle_as_inner
3820
3821
0
    fn downcast_to_type(&self) -> Option<&Type> {
3822
0
        Some(self)
3823
0
    }
Unexecuted instantiation: <cpp_demangle::ast::Type as cpp_demangle::ast::DemangleAsInner<alloc::string::String>>::downcast_to_type
Unexecuted instantiation: <cpp_demangle::ast::Type as cpp_demangle::ast::DemangleAsInner<_>>::downcast_to_type
3824
3825
    fn downcast_to_function_type(&self) -> Option<&FunctionType> {
3826
0
        if let Type::Function(ref f) = *self {
3827
0
            Some(f)
3828
        } else {
3829
0
            None
3830
        }
3831
0
    }
Unexecuted instantiation: <cpp_demangle::ast::Type as cpp_demangle::ast::DemangleAsInner<alloc::string::String>>::downcast_to_function_type
Unexecuted instantiation: <cpp_demangle::ast::Type as cpp_demangle::ast::DemangleAsInner<_>>::downcast_to_function_type
3832
3833
    fn downcast_to_array_type(&self) -> Option<&ArrayType> {
3834
0
        if let Type::Array(ref arr) = *self {
3835
0
            Some(arr)
3836
        } else {
3837
0
            None
3838
        }
3839
0
    }
Unexecuted instantiation: <cpp_demangle::ast::Type as cpp_demangle::ast::DemangleAsInner<alloc::string::String>>::downcast_to_array_type
Unexecuted instantiation: <cpp_demangle::ast::Type as cpp_demangle::ast::DemangleAsInner<_>>::downcast_to_array_type
3840
3841
    fn downcast_to_pointer_to_member(&self) -> Option<&PointerToMemberType> {
3842
0
        if let Type::PointerToMember(ref ptm) = *self {
3843
0
            Some(ptm)
3844
        } else {
3845
0
            None
3846
        }
3847
0
    }
Unexecuted instantiation: <cpp_demangle::ast::Type as cpp_demangle::ast::DemangleAsInner<alloc::string::String>>::downcast_to_pointer_to_member
Unexecuted instantiation: <cpp_demangle::ast::Type as cpp_demangle::ast::DemangleAsInner<_>>::downcast_to_pointer_to_member
3848
3849
0
    fn is_qualified(&self) -> bool {
3850
0
        match *self {
3851
0
            Type::Qualified(..) => true,
3852
0
            _ => false,
3853
        }
3854
0
    }
Unexecuted instantiation: <cpp_demangle::ast::Type as cpp_demangle::ast::DemangleAsInner<alloc::string::String>>::is_qualified
Unexecuted instantiation: <cpp_demangle::ast::Type as cpp_demangle::ast::DemangleAsInner<_>>::is_qualified
3855
}
3856
3857
impl GetTemplateArgs for Type {
3858
    fn get_template_args<'a>(&'a self, subs: &'a SubstitutionTable) -> Option<&'a TemplateArgs> {
3859
        // TODO: This should probably recurse through all the nested type
3860
        // handles too.
3861
3862
0
        match *self {
3863
0
            Type::VendorExtension(_, Some(ref args), _) | Type::TemplateTemplate(_, ref args) => {
3864
0
                Some(args)
3865
            }
3866
0
            Type::PointerTo(ref ty) | Type::LvalueRef(ref ty) | Type::RvalueRef(ref ty) => {
3867
0
                ty.get_template_args(subs)
3868
            }
3869
0
            _ => None,
3870
        }
3871
0
    }
3872
}
3873
3874
impl<'a> GetLeafName<'a> for Type {
3875
0
    fn get_leaf_name(&'a self, subs: &'a SubstitutionTable) -> Option<LeafName<'a>> {
3876
0
        match *self {
3877
0
            Type::ClassEnum(ref cls_enum_ty) => cls_enum_ty.get_leaf_name(subs),
3878
0
            _ => None,
3879
        }
3880
0
    }
3881
}
3882
3883
/// The `<CV-qualifiers>` production.
3884
///
3885
/// ```text
3886
/// <CV-qualifiers> ::= [r] [V] [K]   # restrict (C99), volatile, const
3887
/// ```
3888
0
#[derive(Clone, Debug, Default, Hash, PartialEq, Eq)]
Unexecuted instantiation: <cpp_demangle::ast::CvQualifiers as core::default::Default>::default
Unexecuted instantiation: <cpp_demangle::ast::CvQualifiers as core::default::Default>::default
Unexecuted instantiation: <cpp_demangle::ast::CvQualifiers as core::cmp::PartialEq>::eq
Unexecuted instantiation: <cpp_demangle::ast::CvQualifiers as core::cmp::PartialEq>::eq
3889
pub struct CvQualifiers {
3890
    /// Is this `restrict` qualified?
3891
    pub restrict: bool,
3892
    /// Is this `volatile` qualified?
3893
    pub volatile: bool,
3894
    /// Is this `const` qualified?
3895
    pub const_: bool,
3896
}
3897
3898
impl CvQualifiers {
3899
    #[inline]
3900
0
    fn is_empty(&self) -> bool {
3901
0
        !self.restrict && !self.volatile && !self.const_
3902
0
    }
Unexecuted instantiation: <cpp_demangle::ast::CvQualifiers>::is_empty
Unexecuted instantiation: <cpp_demangle::ast::CvQualifiers>::is_empty
3903
}
3904
3905
impl Parse for CvQualifiers {
3906
3.31M
    fn parse<'a, 'b>(
3907
3.31M
        ctx: &'a ParseContext,
3908
3.31M
        _subs: &'a mut SubstitutionTable,
3909
3.31M
        input: IndexStr<'b>,
3910
3.31M
    ) -> Result<(CvQualifiers, IndexStr<'b>)> {
3911
3.31M
        try_begin_parse!("CvQualifiers", ctx, input);
3912
3913
3.31M
        let (restrict, tail) = if let Ok(tail) = consume(b"r", input) {
3914
1.65M
            (true, tail)
3915
        } else {
3916
1.65M
            (false, input)
3917
        };
3918
3919
3.31M
        let (volatile, tail) = if let Ok(tail) = consume(b"V", tail) {
3920
0
            (true, tail)
3921
        } else {
3922
3.31M
            (false, tail)
3923
        };
3924
3925
3.31M
        let (const_, tail) = if let Ok(tail) = consume(b"K", tail) {
3926
0
            (true, tail)
3927
        } else {
3928
3.31M
            (false, tail)
3929
        };
3930
3931
3.31M
        let qualifiers = CvQualifiers {
3932
3.31M
            restrict: restrict,
3933
3.31M
            volatile: volatile,
3934
3.31M
            const_: const_,
3935
3.31M
        };
3936
3.31M
3937
3.31M
        Ok((qualifiers, tail))
3938
3.31M
    }
3939
}
3940
3941
impl<'subs, W> Demangle<'subs, W> for CvQualifiers
3942
where
3943
    W: 'subs + DemangleWrite,
3944
{
3945
0
    fn demangle<'prev, 'ctx>(
3946
0
        &'subs self,
3947
0
        ctx: &'ctx mut DemangleContext<'subs, W>,
3948
0
        scope: Option<ArgScopeStack<'prev, 'subs>>,
3949
0
    ) -> fmt::Result {
3950
0
        let ctx = try_begin_demangle!(self, ctx, scope);
3951
3952
0
        if self.const_ {
3953
0
            ctx.ensure_space()?;
3954
0
            write!(ctx, "const")?;
3955
0
        }
3956
3957
0
        if self.volatile {
3958
0
            ctx.ensure_space()?;
3959
0
            write!(ctx, "volatile")?;
3960
0
        }
3961
3962
0
        if self.restrict {
3963
0
            ctx.ensure_space()?;
3964
0
            write!(ctx, "restrict")?;
3965
0
        }
3966
3967
0
        Ok(())
3968
0
    }
Unexecuted instantiation: <cpp_demangle::ast::CvQualifiers as cpp_demangle::ast::Demangle<alloc::string::String>>::demangle
Unexecuted instantiation: <cpp_demangle::ast::CvQualifiers as cpp_demangle::ast::Demangle<_>>::demangle
3969
}
3970
3971
impl<'subs, W> DemangleAsInner<'subs, W> for CvQualifiers where W: 'subs + DemangleWrite {}
3972
3973
define_vocabulary! {
3974
    /// A <ref-qualifier> production.
3975
    ///
3976
    /// ```text
3977
    /// <ref-qualifier> ::= R   # & ref-qualifier
3978
    ///                 ::= O   # && ref-qualifier
3979
    /// ```
3980
0
    #[derive(Clone, Debug, PartialEq, Eq)]
3981
    pub enum RefQualifier {
3982
        LValueRef(b"R", "&"),
3983
        RValueRef(b"O", "&&")
3984
    }
3985
}
3986
3987
define_vocabulary! {
3988
    /// A one of the standard variants of the <builtin-type> production.
3989
    ///
3990
    /// ```text
3991
    /// <builtin-type> ::= v  # void
3992
    ///                ::= w  # wchar_t
3993
    ///                ::= b  # bool
3994
    ///                ::= c  # char
3995
    ///                ::= a  # signed char
3996
    ///                ::= h  # unsigned char
3997
    ///                ::= s  # short
3998
    ///                ::= t  # unsigned short
3999
    ///                ::= i  # int
4000
    ///                ::= j  # unsigned int
4001
    ///                ::= l  # long
4002
    ///                ::= m  # unsigned long
4003
    ///                ::= x  # long long, __int64
4004
    ///                ::= y  # unsigned long long, __int64
4005
    ///                ::= n  # __int128
4006
    ///                ::= o  # unsigned __int128
4007
    ///                ::= f  # float
4008
    ///                ::= d  # double
4009
    ///                ::= e  # long double, __float80
4010
    ///                ::= g  # __float128
4011
    ///                ::= z  # ellipsis
4012
    ///                ::= Dd # IEEE 754r decimal floating point (64 bits)
4013
    ///                ::= De # IEEE 754r decimal floating point (128 bits)
4014
    ///                ::= Df # IEEE 754r decimal floating point (32 bits)
4015
    ///                ::= Dh # IEEE 754r half-precision floating point (16 bits)
4016
    ///                ::= Di # char32_t
4017
    ///                ::= Ds # char16_t
4018
    ///                ::= Du # char8_t
4019
    ///                ::= Da # auto
4020
    ///                ::= Dc # decltype(auto)
4021
    ///                ::= Dn # std::nullptr_t (i.e., decltype(nullptr))
4022
    /// ```
4023
0
    #[derive(Clone, Debug, PartialEq, Eq)]
4024
    pub enum StandardBuiltinType {
4025
        Void             (b"v",  "void"),
4026
        Wchar            (b"w",  "wchar_t"),
4027
        Bool             (b"b",  "bool"),
4028
        Char             (b"c",  "char"),
4029
        SignedChar       (b"a",  "signed char"),
4030
        UnsignedChar     (b"h",  "unsigned char"),
4031
        Short            (b"s",  "short"),
4032
        UnsignedShort    (b"t",  "unsigned short"),
4033
        Int              (b"i",  "int"),
4034
        UnsignedInt      (b"j",  "unsigned int"),
4035
        Long             (b"l",  "long"),
4036
        UnsignedLong     (b"m",  "unsigned long"),
4037
        LongLong         (b"x",  "long long"),
4038
        UnsignedLongLong (b"y",  "unsigned long long"),
4039
        Int128           (b"n",  "__int128"),
4040
        Uint128          (b"o",  "unsigned __int128"),
4041
        Float            (b"f",  "float"),
4042
        Double           (b"d",  "double"),
4043
        LongDouble       (b"e",  "long double"),
4044
        Float128         (b"g",  "__float128"),
4045
        Ellipsis         (b"z",  "..."),
4046
        DecimalFloat64   (b"Dd", "decimal64"),
4047
        DecimalFloat128  (b"De", "decimal128"),
4048
        DecimalFloat32   (b"Df", "decimal32"),
4049
        DecimalFloat16   (b"Dh", "half"),
4050
        Char32           (b"Di", "char32_t"),
4051
        Char16           (b"Ds", "char16_t"),
4052
        Char8            (b"Du", "char8_t"),
4053
        Auto             (b"Da", "auto"),
4054
        Decltype         (b"Dc", "decltype(auto)"),
4055
        Nullptr          (b"Dn", "std::nullptr_t")
4056
    }
4057
}
4058
4059
/// The `<builtin-type>` production.
4060
0
#[derive(Clone, Debug, PartialEq, Eq)]
4061
pub enum BuiltinType {
4062
    /// A standards compliant builtin type.
4063
    Standard(StandardBuiltinType),
4064
4065
    /// A non-standard, vendor extension type.
4066
    ///
4067
    /// ```text
4068
    /// <builtin-type> ::= u <source-name>   # vendor extended type
4069
    /// ```
4070
    Extension(SourceName),
4071
}
4072
4073
impl Parse for BuiltinType {
4074
2.52M
    fn parse<'a, 'b>(
4075
2.52M
        ctx: &'a ParseContext,
4076
2.52M
        subs: &'a mut SubstitutionTable,
4077
2.52M
        input: IndexStr<'b>,
4078
2.52M
    ) -> Result<(BuiltinType, IndexStr<'b>)> {
4079
2.52M
        try_begin_parse!("BuiltinType", ctx, input);
4080
4081
2.52M
        if let Ok((ty, tail)) = StandardBuiltinType::parse(ctx, subs, input) {
4082
863k
            return Ok((BuiltinType::Standard(ty), tail));
4083
1.65M
        }
4084
4085
1.65M
        let tail = consume(b"u", input)?;
4086
828k
        let (name, tail) = SourceName::parse(ctx, subs, tail)?;
4087
0
        Ok((BuiltinType::Extension(name), tail))
4088
2.52M
    }
4089
}
4090
4091
impl<'subs, W> Demangle<'subs, W> for BuiltinType
4092
where
4093
    W: 'subs + DemangleWrite,
4094
{
4095
0
    fn demangle<'prev, 'ctx>(
4096
0
        &'subs self,
4097
0
        ctx: &'ctx mut DemangleContext<'subs, W>,
4098
0
        scope: Option<ArgScopeStack<'prev, 'subs>>,
4099
0
    ) -> fmt::Result {
4100
0
        let ctx = try_begin_demangle!(self, ctx, scope);
4101
4102
0
        match *self {
4103
0
            BuiltinType::Standard(ref ty) => ty.demangle(ctx, scope),
4104
0
            BuiltinType::Extension(ref name) => name.demangle(ctx, scope),
4105
        }
4106
0
    }
Unexecuted instantiation: <cpp_demangle::ast::BuiltinType as cpp_demangle::ast::Demangle<alloc::string::String>>::demangle
Unexecuted instantiation: <cpp_demangle::ast::BuiltinType as cpp_demangle::ast::Demangle<_>>::demangle
4107
}
4108
4109
impl<'a> GetLeafName<'a> for BuiltinType {
4110
0
    fn get_leaf_name(&'a self, _: &'a SubstitutionTable) -> Option<LeafName<'a>> {
4111
0
        None
4112
0
    }
4113
}
4114
4115
/// A built-in type with CV-qualifiers.
4116
///
4117
/// Like unqualified built-in types, CV-qualified built-in types do not go into
4118
/// the substitutions table.
4119
0
#[derive(Clone, Debug, PartialEq, Eq)]
4120
pub struct QualifiedBuiltin(CvQualifiers, BuiltinType);
4121
4122
impl<'subs, W> Demangle<'subs, W> for QualifiedBuiltin
4123
where
4124
    W: 'subs + DemangleWrite,
4125
{
4126
0
    fn demangle<'prev, 'ctx>(
4127
0
        &'subs self,
4128
0
        ctx: &'ctx mut DemangleContext<'subs, W>,
4129
0
        scope: Option<ArgScopeStack<'prev, 'subs>>,
4130
0
    ) -> fmt::Result {
4131
0
        let ctx = try_begin_demangle!(self, ctx, scope);
4132
4133
0
        ctx.push_inner(&self.0);
4134
0
        self.1.demangle(ctx, scope)?;
4135
0
        if ctx.pop_inner_if(&self.0) {
4136
0
            self.0.demangle_as_inner(ctx, scope)?;
4137
0
        }
4138
0
        Ok(())
4139
0
    }
Unexecuted instantiation: <cpp_demangle::ast::QualifiedBuiltin as cpp_demangle::ast::Demangle<alloc::string::String>>::demangle
Unexecuted instantiation: <cpp_demangle::ast::QualifiedBuiltin as cpp_demangle::ast::Demangle<_>>::demangle
4140
}
4141
4142
impl<'a> GetLeafName<'a> for QualifiedBuiltin {
4143
0
    fn get_leaf_name(&'a self, _: &'a SubstitutionTable) -> Option<LeafName<'a>> {
4144
0
        None
4145
0
    }
4146
}
4147
4148
/// The `<function-type>` production.
4149
///
4150
/// ```text
4151
/// <function-type> ::= [<CV-qualifiers>] [Dx] F [Y] <bare-function-type> [<ref-qualifier>] E
4152
/// ```
4153
0
#[derive(Clone, Debug, PartialEq, Eq)]
4154
pub struct FunctionType {
4155
    cv_qualifiers: CvQualifiers,
4156
    transaction_safe: bool,
4157
    extern_c: bool,
4158
    bare: BareFunctionType,
4159
    ref_qualifier: Option<RefQualifier>,
4160
}
4161
4162
impl Parse for FunctionType {
4163
1.65M
    fn parse<'a, 'b>(
4164
1.65M
        ctx: &'a ParseContext,
4165
1.65M
        subs: &'a mut SubstitutionTable,
4166
1.65M
        input: IndexStr<'b>,
4167
1.65M
    ) -> Result<(FunctionType, IndexStr<'b>)> {
4168
1.65M
        try_begin_parse!("FunctionType", ctx, input);
4169
4170
1.65M
        let (cv_qualifiers, tail) =
4171
1.65M
            if let Ok((cv_qualifiers, tail)) = CvQualifiers::parse(ctx, subs, input) {
4172
1.65M
                (cv_qualifiers, tail)
4173
            } else {
4174
0
                (Default::default(), input)
4175
            };
4176
4177
1.65M
        let (transaction_safe, tail) = if let Ok(tail) = consume(b"Dx", tail) {
4178
0
            (true, tail)
4179
        } else {
4180
1.65M
            (false, tail)
4181
        };
4182
4183
1.65M
        let tail = consume(b"F", tail)?;
4184
4185
0
        let (extern_c, tail) = if let Ok(tail) = consume(b"Y", tail) {
4186
0
            (true, tail)
4187
        } else {
4188
0
            (false, tail)
4189
        };
4190
4191
0
        let (bare, tail) = BareFunctionType::parse(ctx, subs, tail)?;
4192
4193
0
        let (ref_qualifier, tail) =
4194
0
            if let Ok((ref_qualifier, tail)) = RefQualifier::parse(ctx, subs, tail) {
4195
0
                (Some(ref_qualifier), tail)
4196
            } else {
4197
0
                (None, tail)
4198
            };
4199
4200
0
        let tail = consume(b"E", tail)?;
4201
4202
0
        let func_ty = FunctionType {
4203
0
            cv_qualifiers: cv_qualifiers,
4204
0
            transaction_safe: transaction_safe,
4205
0
            extern_c: extern_c,
4206
0
            bare: bare,
4207
0
            ref_qualifier: ref_qualifier,
4208
0
        };
4209
0
        Ok((func_ty, tail))
4210
1.65M
    }
4211
}
4212
4213
impl<'subs, W> Demangle<'subs, W> for FunctionType
4214
where
4215
    W: 'subs + DemangleWrite,
4216
{
4217
0
    fn demangle<'prev, 'ctx>(
4218
0
        &'subs self,
4219
0
        ctx: &'ctx mut DemangleContext<'subs, W>,
4220
0
        scope: Option<ArgScopeStack<'prev, 'subs>>,
4221
0
    ) -> fmt::Result {
4222
0
        let ctx = try_begin_demangle!(self, ctx, scope);
4223
4224
0
        ctx.push_inner(self);
4225
0
        self.bare.demangle(ctx, scope)?;
4226
0
        if ctx.pop_inner_if(self) {
4227
0
            self.demangle_as_inner(ctx, scope)?;
4228
0
        }
4229
0
        Ok(())
4230
0
    }
Unexecuted instantiation: <cpp_demangle::ast::FunctionType as cpp_demangle::ast::Demangle<alloc::string::String>>::demangle
Unexecuted instantiation: <cpp_demangle::ast::FunctionType as cpp_demangle::ast::Demangle<_>>::demangle
4231
}
4232
4233
impl<'subs, W> DemangleAsInner<'subs, W> for FunctionType
4234
where
4235
    W: 'subs + DemangleWrite,
4236
{
4237
0
    fn demangle_as_inner<'prev, 'ctx>(
4238
0
        &'subs self,
4239
0
        ctx: &'ctx mut DemangleContext<'subs, W>,
4240
0
        scope: Option<ArgScopeStack<'prev, 'subs>>,
4241
0
    ) -> fmt::Result {
4242
0
        let ctx = try_begin_demangle_as_inner!(self, ctx, scope);
4243
4244
0
        if !self.cv_qualifiers.is_empty() {
4245
0
            self.cv_qualifiers.demangle(ctx, scope)?;
4246
0
        }
4247
4248
0
        if let Some(ref rq) = self.ref_qualifier {
4249
            // Print out a space before printing "&" or "&&"
4250
0
            ctx.ensure_space()?;
4251
0
            rq.demangle(ctx, scope)?;
4252
0
        }
4253
4254
0
        Ok(())
4255
0
    }
Unexecuted instantiation: <cpp_demangle::ast::FunctionType as cpp_demangle::ast::DemangleAsInner<alloc::string::String>>::demangle_as_inner
Unexecuted instantiation: <cpp_demangle::ast::FunctionType as cpp_demangle::ast::DemangleAsInner<_>>::demangle_as_inner
4256
4257
0
    fn downcast_to_function_type(&self) -> Option<&FunctionType> {
4258
0
        Some(self)
4259
0
    }
Unexecuted instantiation: <cpp_demangle::ast::FunctionType as cpp_demangle::ast::DemangleAsInner<alloc::string::String>>::downcast_to_function_type
Unexecuted instantiation: <cpp_demangle::ast::FunctionType as cpp_demangle::ast::DemangleAsInner<_>>::downcast_to_function_type
4260
}
4261
4262
/// The `<bare-function-type>` production.
4263
///
4264
/// ```text
4265
/// <bare-function-type> ::= <signature type>+
4266
///      # types are possible return type, then parameter types
4267
/// ```
4268
0
#[derive(Clone, Debug, PartialEq, Eq)]
4269
pub struct BareFunctionType(Vec<TypeHandle>);
4270
4271
impl BareFunctionType {
4272
0
    fn ret(&self) -> &TypeHandle {
4273
0
        &self.0[0]
4274
0
    }
4275
4276
0
    fn args(&self) -> &FunctionArgListAndReturnType {
4277
0
        FunctionArgListAndReturnType::new(&self.0)
4278
0
    }
4279
}
4280
4281
impl Parse for BareFunctionType {
4282
0
    fn parse<'a, 'b>(
4283
0
        ctx: &'a ParseContext,
4284
0
        subs: &'a mut SubstitutionTable,
4285
0
        input: IndexStr<'b>,
4286
0
    ) -> Result<(BareFunctionType, IndexStr<'b>)> {
4287
0
        try_begin_parse!("BareFunctionType", ctx, input);
4288
4289
0
        let (types, tail) = one_or_more::<TypeHandle>(ctx, subs, input)?;
4290
0
        Ok((BareFunctionType(types), tail))
4291
0
    }
4292
}
4293
4294
impl<'subs, W> Demangle<'subs, W> for BareFunctionType
4295
where
4296
    W: 'subs + DemangleWrite,
4297
{
4298
0
    fn demangle<'prev, 'ctx>(
4299
0
        &'subs self,
4300
0
        ctx: &'ctx mut DemangleContext<'subs, W>,
4301
0
        scope: Option<ArgScopeStack<'prev, 'subs>>,
4302
0
    ) -> fmt::Result {
4303
0
        let ctx = try_begin_demangle!(self, ctx, scope);
4304
4305
0
        ctx.push_inner(self);
4306
0
4307
0
        self.ret().demangle(ctx, scope)?;
4308
4309
0
        if ctx.pop_inner_if(self) {
4310
0
            ctx.ensure_space()?;
4311
0
            self.demangle_as_inner(ctx, scope)?;
4312
0
        }
4313
4314
0
        Ok(())
4315
0
    }
Unexecuted instantiation: <cpp_demangle::ast::BareFunctionType as cpp_demangle::ast::Demangle<alloc::string::String>>::demangle
Unexecuted instantiation: <cpp_demangle::ast::BareFunctionType as cpp_demangle::ast::Demangle<_>>::demangle
4316
}
4317
4318
impl<'subs, W> DemangleAsInner<'subs, W> for BareFunctionType
4319
where
4320
    W: 'subs + DemangleWrite,
4321
{
4322
0
    fn demangle_as_inner<'prev, 'ctx>(
4323
0
        &'subs self,
4324
0
        ctx: &'ctx mut DemangleContext<'subs, W>,
4325
0
        scope: Option<ArgScopeStack<'prev, 'subs>>,
4326
0
    ) -> fmt::Result {
4327
0
        let ctx = try_begin_demangle_as_inner!(self, ctx, scope);
4328
0
        self.args().demangle_as_inner(ctx, scope)?;
4329
0
        Ok(())
4330
0
    }
Unexecuted instantiation: <cpp_demangle::ast::BareFunctionType as cpp_demangle::ast::DemangleAsInner<alloc::string::String>>::demangle_as_inner
Unexecuted instantiation: <cpp_demangle::ast::BareFunctionType as cpp_demangle::ast::DemangleAsInner<_>>::demangle_as_inner
4331
}
4332
4333
/// The `<decltype>` production.
4334
///
4335
/// ```text
4336
/// <decltype> ::= Dt <expression> E
4337
///            ::= DT <expression> E
4338
/// ```
4339
0
#[derive(Clone, Debug, PartialEq, Eq)]
4340
pub enum Decltype {
4341
    /// A `decltype` of an id-expression or class member access (C++0x).
4342
    IdExpression(Expression),
4343
4344
    /// A `decltype` of an expression (C++0x).
4345
    Expression(Expression),
4346
}
4347
4348
impl Parse for Decltype {
4349
1.65M
    fn parse<'a, 'b>(
4350
1.65M
        ctx: &'a ParseContext,
4351
1.65M
        subs: &'a mut SubstitutionTable,
4352
1.65M
        input: IndexStr<'b>,
4353
1.65M
    ) -> Result<(Decltype, IndexStr<'b>)> {
4354
1.65M
        try_begin_parse!("Decltype", ctx, input);
4355
4356
1.65M
        let tail = consume(b"D", input)?;
4357
4358
0
        if let Ok(tail) = consume(b"t", tail) {
4359
0
            let (expr, tail) = Expression::parse(ctx, subs, tail)?;
4360
0
            let tail = consume(b"E", tail)?;
4361
0
            return Ok((Decltype::IdExpression(expr), tail));
4362
0
        }
4363
4364
0
        let tail = consume(b"T", tail)?;
4365
0
        let (expr, tail) = Expression::parse(ctx, subs, tail)?;
4366
0
        let tail = consume(b"E", tail)?;
4367
0
        Ok((Decltype::Expression(expr), tail))
4368
1.65M
    }
4369
}
4370
4371
impl<'subs, W> Demangle<'subs, W> for Decltype
4372
where
4373
    W: 'subs + DemangleWrite,
4374
{
4375
0
    fn demangle<'prev, 'ctx>(
4376
0
        &'subs self,
4377
0
        ctx: &'ctx mut DemangleContext<'subs, W>,
4378
0
        scope: Option<ArgScopeStack<'prev, 'subs>>,
4379
0
    ) -> fmt::Result {
4380
0
        let ctx = try_begin_demangle!(self, ctx, scope);
4381
4382
0
        ctx.push_demangle_node(DemangleNodeType::TemplateParam);
4383
0
        let ret = match *self {
4384
0
            Decltype::Expression(ref expr) | Decltype::IdExpression(ref expr) => {
4385
0
                write!(ctx, "decltype (")?;
4386
0
                expr.demangle(ctx, scope)?;
4387
0
                write!(ctx, ")")?;
4388
0
                Ok(())
4389
0
            }
4390
0
        };
4391
0
        ctx.pop_demangle_node();
4392
0
        ret
4393
0
    }
Unexecuted instantiation: <cpp_demangle::ast::Decltype as cpp_demangle::ast::Demangle<alloc::string::String>>::demangle
Unexecuted instantiation: <cpp_demangle::ast::Decltype as cpp_demangle::ast::Demangle<_>>::demangle
4394
}
4395
4396
/// The `<class-enum-type>` production.
4397
///
4398
/// ```text
4399
/// <class-enum-type> ::= <name>
4400
///                   ::= Ts <name>
4401
///                   ::= Tu <name>
4402
///                   ::= Te <name>
4403
/// ```
4404
0
#[derive(Clone, Debug, PartialEq, Eq)]
4405
pub enum ClassEnumType {
4406
    /// A non-dependent type name, dependent type name, or dependent
4407
    /// typename-specifier.
4408
    Named(Name),
4409
4410
    /// A dependent elaborated type specifier using 'struct' or 'class'.
4411
    ElaboratedStruct(Name),
4412
4413
    /// A dependent elaborated type specifier using 'union'.
4414
    ElaboratedUnion(Name),
4415
4416
    /// A dependent elaborated type specifier using 'enum'.
4417
    ElaboratedEnum(Name),
4418
}
4419
4420
impl Parse for ClassEnumType {
4421
1.65M
    fn parse<'a, 'b>(
4422
1.65M
        ctx: &'a ParseContext,
4423
1.65M
        subs: &'a mut SubstitutionTable,
4424
1.65M
        input: IndexStr<'b>,
4425
1.65M
    ) -> Result<(ClassEnumType, IndexStr<'b>)> {
4426
1.65M
        try_begin_parse!("ClassEnumType", ctx, input);
4427
4428
1.65M
        if let Ok((name, tail)) = Name::parse(ctx, subs, input) {
4429
0
            return Ok((ClassEnumType::Named(name), tail));
4430
1.65M
        }
4431
4432
1.65M
        let tail = consume(b"T", input)?;
4433
4434
0
        if let Ok(tail) = consume(b"s", tail) {
4435
0
            let (name, tail) = Name::parse(ctx, subs, tail)?;
4436
0
            return Ok((ClassEnumType::ElaboratedStruct(name), tail));
4437
0
        }
4438
4439
0
        if let Ok(tail) = consume(b"u", tail) {
4440
0
            let (name, tail) = Name::parse(ctx, subs, tail)?;
4441
0
            return Ok((ClassEnumType::ElaboratedUnion(name), tail));
4442
0
        }
4443
4444
0
        let tail = consume(b"e", tail)?;
4445
0
        let (name, tail) = Name::parse(ctx, subs, tail)?;
4446
0
        Ok((ClassEnumType::ElaboratedEnum(name), tail))
4447
1.65M
    }
4448
}
4449
4450
impl<'subs, W> Demangle<'subs, W> for ClassEnumType
4451
where
4452
    W: 'subs + DemangleWrite,
4453
{
4454
0
    fn demangle<'prev, 'ctx>(
4455
0
        &'subs self,
4456
0
        ctx: &'ctx mut DemangleContext<'subs, W>,
4457
0
        scope: Option<ArgScopeStack<'prev, 'subs>>,
4458
0
    ) -> fmt::Result {
4459
0
        let ctx = try_begin_demangle!(self, ctx, scope);
4460
4461
0
        match *self {
4462
0
            ClassEnumType::Named(ref name) => name.demangle(ctx, scope),
4463
0
            ClassEnumType::ElaboratedStruct(ref name) => {
4464
0
                write!(ctx, "class ")?;
4465
0
                name.demangle(ctx, scope)
4466
            }
4467
0
            ClassEnumType::ElaboratedUnion(ref name) => {
4468
0
                write!(ctx, "union ")?;
4469
0
                name.demangle(ctx, scope)
4470
            }
4471
0
            ClassEnumType::ElaboratedEnum(ref name) => {
4472
0
                write!(ctx, "enum ")?;
4473
0
                name.demangle(ctx, scope)
4474
            }
4475
        }
4476
0
    }
Unexecuted instantiation: <cpp_demangle::ast::ClassEnumType as cpp_demangle::ast::Demangle<alloc::string::String>>::demangle
Unexecuted instantiation: <cpp_demangle::ast::ClassEnumType as cpp_demangle::ast::Demangle<_>>::demangle
4477
}
4478
4479
impl<'a> GetLeafName<'a> for ClassEnumType {
4480
0
    fn get_leaf_name(&'a self, subs: &'a SubstitutionTable) -> Option<LeafName<'a>> {
4481
0
        match *self {
4482
0
            ClassEnumType::Named(ref name)
4483
0
            | ClassEnumType::ElaboratedStruct(ref name)
4484
0
            | ClassEnumType::ElaboratedUnion(ref name)
4485
0
            | ClassEnumType::ElaboratedEnum(ref name) => name.get_leaf_name(subs),
4486
0
        }
4487
0
    }
4488
}
4489
4490
/// The `<unnamed-type-name>` production.
4491
///
4492
/// ```text
4493
/// <unnamed-type-name> ::= Ut [ <nonnegative number> ] _
4494
///                     ::= <closure-type-name>
4495
/// ```
4496
///
4497
/// TODO: parse the <closure-type-name> variant
4498
0
#[derive(Clone, Debug, PartialEq, Eq)]
4499
pub struct UnnamedTypeName(Option<usize>);
4500
4501
impl Parse for UnnamedTypeName {
4502
3.31M
    fn parse<'a, 'b>(
4503
3.31M
        ctx: &'a ParseContext,
4504
3.31M
        _subs: &'a mut SubstitutionTable,
4505
3.31M
        input: IndexStr<'b>,
4506
3.31M
    ) -> Result<(UnnamedTypeName, IndexStr<'b>)> {
4507
3.31M
        try_begin_parse!("UnnamedTypeName", ctx, input);
4508
4509
3.31M
        let input = consume(b"Ut", input)?;
4510
0
        let (number, input) = match parse_number(10, false, input) {
4511
0
            Ok((number, input)) => (Some(number as _), input),
4512
0
            Err(_) => (None, input),
4513
        };
4514
0
        let input = consume(b"_", input)?;
4515
0
        Ok((UnnamedTypeName(number), input))
4516
3.31M
    }
4517
}
4518
4519
impl UnnamedTypeName {
4520
    #[inline]
4521
0
    fn starts_with(byte: u8) -> bool {
4522
0
        byte == b'U'
4523
0
    }
4524
}
4525
4526
impl<'subs, W> Demangle<'subs, W> for UnnamedTypeName
4527
where
4528
    W: 'subs + DemangleWrite,
4529
{
4530
0
    fn demangle<'prev, 'ctx>(
4531
0
        &'subs self,
4532
0
        ctx: &'ctx mut DemangleContext<'subs, W>,
4533
0
        scope: Option<ArgScopeStack<'prev, 'subs>>,
4534
0
    ) -> fmt::Result {
4535
0
        let ctx = try_begin_demangle!(self, ctx, scope);
4536
4537
0
        write!(ctx, "{{unnamed type#{}}}", self.0.map_or(1, |n| n + 1))?;
Unexecuted instantiation: <cpp_demangle::ast::UnnamedTypeName as cpp_demangle::ast::Demangle<alloc::string::String>>::demangle::{closure#0}
Unexecuted instantiation: <cpp_demangle::ast::UnnamedTypeName as cpp_demangle::ast::Demangle<_>>::demangle::{closure#0}
4538
0
        Ok(())
4539
0
    }
Unexecuted instantiation: <cpp_demangle::ast::UnnamedTypeName as cpp_demangle::ast::Demangle<alloc::string::String>>::demangle
Unexecuted instantiation: <cpp_demangle::ast::UnnamedTypeName as cpp_demangle::ast::Demangle<_>>::demangle
4540
}
4541
4542
impl<'subs, W> DemangleAsLeaf<'subs, W> for UnnamedTypeName
4543
where
4544
    W: 'subs + DemangleWrite,
4545
{
4546
0
    fn demangle_as_leaf<'me, 'ctx>(
4547
0
        &'me self,
4548
0
        ctx: &'ctx mut DemangleContext<'subs, W>,
4549
0
    ) -> fmt::Result {
4550
0
        let ctx = try_begin_demangle!(self, ctx, None);
4551
0
        if let Some(source_name) = ctx.source_name {
4552
0
            write!(ctx, "{}", source_name)?;
4553
        } else {
4554
0
            write!(ctx, "{{unnamed type#{}}}", self.0.map_or(1, |n| n + 1))?;
Unexecuted instantiation: <cpp_demangle::ast::UnnamedTypeName as cpp_demangle::ast::DemangleAsLeaf<alloc::string::String>>::demangle_as_leaf::{closure#0}
Unexecuted instantiation: <cpp_demangle::ast::UnnamedTypeName as cpp_demangle::ast::DemangleAsLeaf<_>>::demangle_as_leaf::{closure#0}
4555
        }
4556
0
        Ok(())
4557
0
    }
Unexecuted instantiation: <cpp_demangle::ast::UnnamedTypeName as cpp_demangle::ast::DemangleAsLeaf<alloc::string::String>>::demangle_as_leaf
Unexecuted instantiation: <cpp_demangle::ast::UnnamedTypeName as cpp_demangle::ast::DemangleAsLeaf<_>>::demangle_as_leaf
4558
}
4559
4560
impl<'subs> ArgScope<'subs, 'subs> for UnnamedTypeName {
4561
0
    fn leaf_name(&'subs self) -> Result<LeafName<'subs>> {
4562
0
        Ok(LeafName::UnnamedType(self))
4563
0
    }
4564
4565
0
    fn get_template_arg(
4566
0
        &'subs self,
4567
0
        _: usize,
4568
0
    ) -> Result<(&'subs TemplateArg, &'subs TemplateArgs)> {
4569
0
        Err(error::Error::BadTemplateArgReference)
4570
0
    }
4571
4572
0
    fn get_function_arg(&'subs self, _: usize) -> Result<&'subs Type> {
4573
0
        Err(error::Error::BadFunctionArgReference)
4574
0
    }
4575
}
4576
4577
/// The `<array-type>` production.
4578
///
4579
/// ```text
4580
/// <array-type> ::= A <positive dimension number> _ <element type>
4581
///              ::= A [<dimension expression>] _ <element type>
4582
/// ```
4583
0
#[derive(Clone, Debug, PartialEq, Eq)]
4584
pub enum ArrayType {
4585
    /// An array with a number-literal dimension.
4586
    DimensionNumber(usize, TypeHandle),
4587
4588
    /// An array with an expression for its dimension.
4589
    DimensionExpression(Expression, TypeHandle),
4590
4591
    /// An array with no dimension.
4592
    NoDimension(TypeHandle),
4593
}
4594
4595
impl Parse for ArrayType {
4596
1.65M
    fn parse<'a, 'b>(
4597
1.65M
        ctx: &'a ParseContext,
4598
1.65M
        subs: &'a mut SubstitutionTable,
4599
1.65M
        input: IndexStr<'b>,
4600
1.65M
    ) -> Result<(ArrayType, IndexStr<'b>)> {
4601
1.65M
        try_begin_parse!("ArrayType", ctx, input);
4602
4603
1.65M
        let tail = consume(b"A", input)?;
4604
4605
0
        if let Ok((num, tail)) = parse_number(10, false, tail) {
4606
0
            debug_assert!(num >= 0);
4607
0
            let tail = consume(b"_", tail)?;
4608
0
            let (ty, tail) = TypeHandle::parse(ctx, subs, tail)?;
4609
0
            return Ok((ArrayType::DimensionNumber(num as _, ty), tail));
4610
0
        }
4611
4612
0
        if let Ok((expr, tail)) = Expression::parse(ctx, subs, tail) {
4613
0
            let tail = consume(b"_", tail)?;
4614
0
            let (ty, tail) = TypeHandle::parse(ctx, subs, tail)?;
4615
0
            return Ok((ArrayType::DimensionExpression(expr, ty), tail));
4616
0
        }
4617
4618
0
        let tail = consume(b"_", tail)?;
4619
0
        let (ty, tail) = TypeHandle::parse(ctx, subs, tail)?;
4620
0
        Ok((ArrayType::NoDimension(ty), tail))
4621
1.65M
    }
4622
}
4623
4624
impl<'subs, W> Demangle<'subs, W> for ArrayType
4625
where
4626
    W: 'subs + DemangleWrite,
4627
{
4628
0
    fn demangle<'prev, 'ctx>(
4629
0
        &'subs self,
4630
0
        ctx: &'ctx mut DemangleContext<'subs, W>,
4631
0
        scope: Option<ArgScopeStack<'prev, 'subs>>,
4632
0
    ) -> fmt::Result {
4633
0
        let ctx = try_begin_demangle!(self, ctx, scope);
4634
4635
0
        ctx.push_inner(self);
4636
0
4637
0
        match *self {
4638
0
            ArrayType::DimensionNumber(_, ref ty)
4639
0
            | ArrayType::DimensionExpression(_, ref ty)
4640
0
            | ArrayType::NoDimension(ref ty) => {
4641
0
                ty.demangle(ctx, scope)?;
4642
            }
4643
        }
4644
4645
0
        if ctx.pop_inner_if(self) {
4646
0
            self.demangle_as_inner(ctx, scope)?;
4647
0
        }
4648
4649
0
        Ok(())
4650
0
    }
Unexecuted instantiation: <cpp_demangle::ast::ArrayType as cpp_demangle::ast::Demangle<alloc::string::String>>::demangle
Unexecuted instantiation: <cpp_demangle::ast::ArrayType as cpp_demangle::ast::Demangle<_>>::demangle
4651
}
4652
4653
impl<'subs, W> DemangleAsInner<'subs, W> for ArrayType
4654
where
4655
    W: 'subs + DemangleWrite,
4656
{
4657
0
    fn demangle_as_inner<'prev, 'ctx>(
4658
0
        &'subs self,
4659
0
        ctx: &'ctx mut DemangleContext<'subs, W>,
4660
0
        scope: Option<ArgScopeStack<'prev, 'subs>>,
4661
0
    ) -> fmt::Result {
4662
0
        let ctx = try_begin_demangle_as_inner!(self, ctx, scope);
4663
4664
        // Whether we should add a final space before the dimensions.
4665
0
        let mut needs_space = true;
4666
4667
0
        while let Some(inner) = ctx.pop_inner() {
4668
            // We need to add parentheses around array inner types, unless they
4669
            // are also (potentially qualified) arrays themselves, in which case
4670
            // we format them as multi-dimensional arrays.
4671
0
            let inner_is_array = match inner.downcast_to_type() {
4672
0
                Some(&Type::Qualified(_, ref ty)) => ctx.subs.get_type(ty).map_or(false, |ty| {
4673
0
                    DemangleAsInner::<W>::downcast_to_array_type(ty).is_some()
4674
0
                }),
Unexecuted instantiation: <cpp_demangle::ast::ArrayType as cpp_demangle::ast::DemangleAsInner<alloc::string::String>>::demangle_as_inner::{closure#0}
Unexecuted instantiation: <cpp_demangle::ast::ArrayType as cpp_demangle::ast::DemangleAsInner<_>>::demangle_as_inner::{closure#0}
4675
                _ => {
4676
0
                    if inner.downcast_to_array_type().is_some() {
4677
0
                        needs_space = false;
4678
0
                        true
4679
                    } else {
4680
0
                        false
4681
                    }
4682
                }
4683
            };
4684
4685
0
            if inner_is_array {
4686
0
                inner.demangle_as_inner(ctx, scope)?;
4687
            } else {
4688
0
                ctx.ensure_space()?;
4689
4690
                // CvQualifiers should have the parentheses printed after, not before
4691
0
                if inner.is_qualified() {
4692
0
                    inner.demangle_as_inner(ctx, scope)?;
4693
0
                    ctx.ensure_space()?;
4694
0
                    write!(ctx, "(")?;
4695
                } else {
4696
0
                    write!(ctx, "(")?;
4697
0
                    inner.demangle_as_inner(ctx, scope)?;
4698
                }
4699
4700
0
                ctx.demangle_inners(scope)?;
4701
0
                write!(ctx, ")")?;
4702
            }
4703
        }
4704
4705
0
        if needs_space {
4706
0
            ctx.ensure_space()?;
4707
0
        }
4708
4709
0
        match *self {
4710
0
            ArrayType::DimensionNumber(n, _) => {
4711
0
                write!(ctx, "[{}]", n)?;
4712
            }
4713
0
            ArrayType::DimensionExpression(ref expr, _) => {
4714
0
                write!(ctx, "[")?;
4715
0
                expr.demangle(ctx, scope)?;
4716
0
                write!(ctx, "]")?;
4717
            }
4718
            ArrayType::NoDimension(_) => {
4719
0
                write!(ctx, "[]")?;
4720
            }
4721
        }
4722
4723
0
        Ok(())
4724
0
    }
Unexecuted instantiation: <cpp_demangle::ast::ArrayType as cpp_demangle::ast::DemangleAsInner<alloc::string::String>>::demangle_as_inner
Unexecuted instantiation: <cpp_demangle::ast::ArrayType as cpp_demangle::ast::DemangleAsInner<_>>::demangle_as_inner
4725
4726
0
    fn downcast_to_array_type(&self) -> Option<&ArrayType> {
4727
0
        Some(self)
4728
0
    }
Unexecuted instantiation: <cpp_demangle::ast::ArrayType as cpp_demangle::ast::DemangleAsInner<alloc::string::String>>::downcast_to_array_type
Unexecuted instantiation: <cpp_demangle::ast::ArrayType as cpp_demangle::ast::DemangleAsInner<_>>::downcast_to_array_type
4729
}
4730
4731
/// The `<vector-type>` production.
4732
///
4733
/// ```text
4734
/// <vector-type> ::= Dv <number> _ <type>
4735
///               ::= Dv <expression> _ <type>
4736
/// ```
4737
0
#[derive(Clone, Debug, PartialEq, Eq)]
4738
pub enum VectorType {
4739
    /// An vector with a number-literal dimension.
4740
    DimensionNumber(usize, TypeHandle),
4741
4742
    /// An vector with an expression for its dimension.
4743
    DimensionExpression(Expression, TypeHandle),
4744
}
4745
4746
impl Parse for VectorType {
4747
1.65M
    fn parse<'a, 'b>(
4748
1.65M
        ctx: &'a ParseContext,
4749
1.65M
        subs: &'a mut SubstitutionTable,
4750
1.65M
        input: IndexStr<'b>,
4751
1.65M
    ) -> Result<(VectorType, IndexStr<'b>)> {
4752
1.65M
        try_begin_parse!("VectorType", ctx, input);
4753
4754
1.65M
        let tail = consume(b"Dv", input)?;
4755
4756
0
        if let Ok((num, tail)) = parse_number(10, false, tail) {
4757
0
            debug_assert!(num >= 0);
4758
0
            let tail = consume(b"_", tail)?;
4759
0
            let (ty, tail) = TypeHandle::parse(ctx, subs, tail)?;
4760
0
            return Ok((VectorType::DimensionNumber(num as _, ty), tail));
4761
0
        }
4762
4763
0
        let (expr, tail) = Expression::parse(ctx, subs, tail)?;
4764
0
        let tail = consume(b"_", tail)?;
4765
0
        let (ty, tail) = TypeHandle::parse(ctx, subs, tail)?;
4766
0
        Ok((VectorType::DimensionExpression(expr, ty), tail))
4767
1.65M
    }
4768
}
4769
4770
impl<'subs, W> Demangle<'subs, W> for VectorType
4771
where
4772
    W: 'subs + DemangleWrite,
4773
{
4774
0
    fn demangle<'prev, 'ctx>(
4775
0
        &'subs self,
4776
0
        ctx: &'ctx mut DemangleContext<'subs, W>,
4777
0
        scope: Option<ArgScopeStack<'prev, 'subs>>,
4778
0
    ) -> fmt::Result {
4779
0
        let ctx = try_begin_demangle!(self, ctx, scope);
4780
4781
0
        ctx.push_inner(self);
4782
0
4783
0
        match *self {
4784
0
            VectorType::DimensionNumber(_, ref ty) | VectorType::DimensionExpression(_, ref ty) => {
4785
0
                ty.demangle(ctx, scope)?;
4786
            }
4787
        }
4788
4789
0
        if ctx.pop_inner_if(self) {
4790
0
            self.demangle_as_inner(ctx, scope)?;
4791
0
        }
4792
4793
0
        Ok(())
4794
0
    }
Unexecuted instantiation: <cpp_demangle::ast::VectorType as cpp_demangle::ast::Demangle<alloc::string::String>>::demangle
Unexecuted instantiation: <cpp_demangle::ast::VectorType as cpp_demangle::ast::Demangle<_>>::demangle
4795
}
4796
4797
impl<'subs, W> DemangleAsInner<'subs, W> for VectorType
4798
where
4799
    W: 'subs + DemangleWrite,
4800
{
4801
0
    fn demangle_as_inner<'prev, 'ctx>(
4802
0
        &'subs self,
4803
0
        ctx: &'ctx mut DemangleContext<'subs, W>,
4804
0
        scope: Option<ArgScopeStack<'prev, 'subs>>,
4805
0
    ) -> fmt::Result {
4806
0
        let ctx = try_begin_demangle_as_inner!(self, ctx, scope);
4807
4808
0
        match *self {
4809
0
            VectorType::DimensionNumber(n, _) => {
4810
0
                write!(ctx, " __vector({})", n)?;
4811
            }
4812
0
            VectorType::DimensionExpression(ref expr, _) => {
4813
0
                write!(ctx, " __vector(")?;
4814
0
                expr.demangle(ctx, scope)?;
4815
0
                write!(ctx, ")")?;
4816
            }
4817
        }
4818
4819
0
        Ok(())
4820
0
    }
Unexecuted instantiation: <cpp_demangle::ast::VectorType as cpp_demangle::ast::DemangleAsInner<alloc::string::String>>::demangle_as_inner
Unexecuted instantiation: <cpp_demangle::ast::VectorType as cpp_demangle::ast::DemangleAsInner<_>>::demangle_as_inner
4821
}
4822
4823
/// The `<pointer-to-member-type>` production.
4824
///
4825
/// ```text
4826
/// <pointer-to-member-type> ::= M <class type> <member type>
4827
/// ```
4828
0
#[derive(Clone, Debug, PartialEq, Eq)]
4829
pub struct PointerToMemberType(TypeHandle, TypeHandle);
4830
4831
impl Parse for PointerToMemberType {
4832
1.65M
    fn parse<'a, 'b>(
4833
1.65M
        ctx: &'a ParseContext,
4834
1.65M
        subs: &'a mut SubstitutionTable,
4835
1.65M
        input: IndexStr<'b>,
4836
1.65M
    ) -> Result<(PointerToMemberType, IndexStr<'b>)> {
4837
1.65M
        try_begin_parse!("PointerToMemberType", ctx, input);
4838
4839
1.65M
        let tail = consume(b"M", input)?;
4840
0
        let (ty1, tail) = TypeHandle::parse(ctx, subs, tail)?;
4841
0
        let (ty2, tail) = TypeHandle::parse(ctx, subs, tail)?;
4842
0
        Ok((PointerToMemberType(ty1, ty2), tail))
4843
1.65M
    }
4844
}
4845
4846
impl<'subs, W> Demangle<'subs, W> for PointerToMemberType
4847
where
4848
    W: 'subs + DemangleWrite,
4849
{
4850
0
    fn demangle<'prev, 'ctx>(
4851
0
        &'subs self,
4852
0
        ctx: &'ctx mut DemangleContext<'subs, W>,
4853
0
        scope: Option<ArgScopeStack<'prev, 'subs>>,
4854
0
    ) -> fmt::Result {
4855
0
        let ctx = try_begin_demangle!(self, ctx, scope);
4856
4857
0
        ctx.push_inner(self);
4858
0
        self.1.demangle(ctx, scope)?;
4859
0
        if ctx.pop_inner_if(self) {
4860
0
            self.demangle_as_inner(ctx, scope)?;
4861
0
        }
4862
0
        Ok(())
4863
0
    }
Unexecuted instantiation: <cpp_demangle::ast::PointerToMemberType as cpp_demangle::ast::Demangle<alloc::string::String>>::demangle
Unexecuted instantiation: <cpp_demangle::ast::PointerToMemberType as cpp_demangle::ast::Demangle<_>>::demangle
4864
}
4865
4866
impl<'subs, W> DemangleAsInner<'subs, W> for PointerToMemberType
4867
where
4868
    W: 'subs + DemangleWrite,
4869
{
4870
0
    fn demangle_as_inner<'prev, 'ctx>(
4871
0
        &'subs self,
4872
0
        ctx: &'ctx mut DemangleContext<'subs, W>,
4873
0
        scope: Option<ArgScopeStack<'prev, 'subs>>,
4874
0
    ) -> fmt::Result {
4875
0
        let ctx = try_begin_demangle_as_inner!(self, ctx, scope);
4876
4877
0
        if ctx.last_char_written != Some('(') {
4878
0
            ctx.ensure_space()?;
4879
0
        }
4880
4881
0
        self.0.demangle(ctx, scope)?;
4882
0
        write!(ctx, "::*")?;
4883
0
        Ok(())
4884
0
    }
Unexecuted instantiation: <cpp_demangle::ast::PointerToMemberType as cpp_demangle::ast::DemangleAsInner<alloc::string::String>>::demangle_as_inner
Unexecuted instantiation: <cpp_demangle::ast::PointerToMemberType as cpp_demangle::ast::DemangleAsInner<_>>::demangle_as_inner
4885
4886
0
    fn downcast_to_pointer_to_member(&self) -> Option<&PointerToMemberType> {
4887
0
        Some(self)
4888
0
    }
Unexecuted instantiation: <cpp_demangle::ast::PointerToMemberType as cpp_demangle::ast::DemangleAsInner<alloc::string::String>>::downcast_to_pointer_to_member
Unexecuted instantiation: <cpp_demangle::ast::PointerToMemberType as cpp_demangle::ast::DemangleAsInner<_>>::downcast_to_pointer_to_member
4889
}
4890
4891
/// The `<template-param>` production.
4892
///
4893
/// ```text
4894
/// <template-param> ::= T_ # first template parameter
4895
///                  ::= T <parameter-2 non-negative number> _
4896
/// ```
4897
0
#[derive(Clone, Debug, PartialEq, Eq)]
4898
pub struct TemplateParam(usize);
4899
4900
impl Parse for TemplateParam {
4901
3.31M
    fn parse<'a, 'b>(
4902
3.31M
        ctx: &'a ParseContext,
4903
3.31M
        _subs: &'a mut SubstitutionTable,
4904
3.31M
        input: IndexStr<'b>,
4905
3.31M
    ) -> Result<(TemplateParam, IndexStr<'b>)> {
4906
3.31M
        try_begin_parse!("TemplateParam", ctx, input);
4907
4908
3.31M
        let input = consume(b"T", input)?;
4909
0
        let (number, input) = match parse_number(10, false, input) {
4910
0
            Ok((number, input)) => ((number + 1) as _, input),
4911
0
            Err(_) => (0, input),
4912
        };
4913
0
        let input = consume(b"_", input)?;
4914
0
        Ok((TemplateParam(number), input))
4915
3.31M
    }
4916
}
4917
4918
impl<'subs, W> Demangle<'subs, W> for TemplateParam
4919
where
4920
    W: 'subs + DemangleWrite,
4921
{
4922
0
    fn demangle<'prev, 'ctx>(
4923
0
        &'subs self,
4924
0
        ctx: &'ctx mut DemangleContext<'subs, W>,
4925
0
        scope: Option<ArgScopeStack<'prev, 'subs>>,
4926
0
    ) -> fmt::Result {
4927
0
        let ctx = try_begin_demangle!(self, ctx, scope);
4928
4929
0
        ctx.push_demangle_node(DemangleNodeType::TemplateParam);
4930
0
        let ret = if ctx.is_lambda_arg {
4931
            // To match libiberty, template references are converted to `auto`.
4932
0
            write!(ctx, "auto:{}", self.0 + 1)
4933
        } else {
4934
0
            let arg = self.resolve(scope)?;
4935
0
            arg.demangle(ctx, scope)
4936
        };
4937
0
        ctx.pop_demangle_node();
4938
0
        ret
4939
0
    }
Unexecuted instantiation: <cpp_demangle::ast::TemplateParam as cpp_demangle::ast::Demangle<alloc::string::String>>::demangle
Unexecuted instantiation: <cpp_demangle::ast::TemplateParam as cpp_demangle::ast::Demangle<_>>::demangle
4940
}
4941
4942
impl TemplateParam {
4943
0
    fn resolve<'subs, 'prev>(
4944
0
        &'subs self,
4945
0
        scope: Option<ArgScopeStack<'prev, 'subs>>,
4946
0
    ) -> ::std::result::Result<&'subs TemplateArg, fmt::Error> {
4947
0
        scope
4948
0
            .get_template_arg(self.0)
4949
0
            .map_err(|e| {
4950
0
                log!("Error obtaining template argument: {}", e);
4951
0
                fmt::Error
4952
0
            })
4953
0
            .map(|v| v.0)
4954
0
    }
4955
}
4956
4957
impl<'a> Hash for &'a TemplateParam {
4958
0
    fn hash<H>(&self, state: &mut H)
4959
0
    where
4960
0
        H: Hasher,
4961
0
    {
4962
0
        let self_ref: &TemplateParam = *self;
4963
0
        let self_ptr = self_ref as *const TemplateParam;
4964
0
        self_ptr.hash(state);
4965
0
    }
4966
}
4967
4968
/// The `<template-template-param>` production.
4969
///
4970
/// ```text
4971
/// <template-template-param> ::= <template-param>
4972
///                           ::= <substitution>
4973
/// ```
4974
0
#[derive(Clone, Debug, PartialEq, Eq)]
4975
pub struct TemplateTemplateParam(TemplateParam);
4976
4977
0
define_handle! {
4978
0
    /// A reference to a parsed `TemplateTemplateParam`.
4979
0
    pub enum TemplateTemplateParamHandle
4980
0
}
4981
4982
impl Parse for TemplateTemplateParamHandle {
4983
1.65M
    fn parse<'a, 'b>(
4984
1.65M
        ctx: &'a ParseContext,
4985
1.65M
        subs: &'a mut SubstitutionTable,
4986
1.65M
        input: IndexStr<'b>,
4987
1.65M
    ) -> Result<(TemplateTemplateParamHandle, IndexStr<'b>)> {
4988
1.65M
        try_begin_parse!("TemplateTemplateParamHandle", ctx, input);
4989
4990
1.65M
        if let Ok((sub, tail)) = Substitution::parse(ctx, subs, input) {
4991
0
            match sub {
4992
0
                Substitution::WellKnown(component) => {
4993
0
                    return Ok((TemplateTemplateParamHandle::WellKnown(component), tail));
4994
                }
4995
0
                Substitution::BackReference(idx) => {
4996
0
                    // TODO: should this check if the thing at idx is a
4997
0
                    // template-template-param? There could otherwise be ambiguity
4998
0
                    // with <type>'s <substitution> form...
4999
0
                    return Ok((TemplateTemplateParamHandle::BackReference(idx), tail));
5000
                }
5001
            }
5002
1.65M
        }
5003
5004
1.65M
        let (param, tail) = TemplateParam::parse(ctx, subs, input)?;
5005
0
        let ttp = TemplateTemplateParam(param);
5006
0
        let ttp = Substitutable::TemplateTemplateParam(ttp);
5007
0
        let idx = subs.insert(ttp);
5008
0
        let handle = TemplateTemplateParamHandle::BackReference(idx);
5009
0
        Ok((handle, tail))
5010
1.65M
    }
5011
}
5012
5013
impl<'subs, W> Demangle<'subs, W> for TemplateTemplateParam
5014
where
5015
    W: 'subs + DemangleWrite,
5016
{
5017
    #[inline]
5018
0
    fn demangle<'prev, 'ctx>(
5019
0
        &'subs self,
5020
0
        ctx: &'ctx mut DemangleContext<'subs, W>,
5021
0
        scope: Option<ArgScopeStack<'prev, 'subs>>,
5022
0
    ) -> fmt::Result {
5023
0
        let ctx = try_begin_demangle!(self, ctx, scope);
5024
5025
0
        self.0.demangle(ctx, scope)
5026
0
    }
Unexecuted instantiation: <cpp_demangle::ast::TemplateTemplateParam as cpp_demangle::ast::Demangle<alloc::string::String>>::demangle
Unexecuted instantiation: <cpp_demangle::ast::TemplateTemplateParam as cpp_demangle::ast::Demangle<_>>::demangle
5027
}
5028
5029
/// The <function-param> production.
5030
///
5031
/// ```text
5032
/// <function-param> ::= fp <top-level CV-qualifiers> _
5033
///                          # L == 0, first parameter
5034
///                  ::= fp <top-level CV-qualifiers> <parameter-2 non-negative number> _
5035
///                          # L == 0, second and later parameters
5036
///                  ::= fL <L-1 non-negative number> p <top-level CV-qualifiers> _
5037
///                          # L > 0, first parameter
5038
///                  ::= fL <L-1 non-negative number> p <top-level CV-qualifiers> <parameter-2 non-negative number> _
5039
///                          # L > 0, second and later parameters
5040
/// ```
5041
0
#[derive(Clone, Debug, PartialEq, Eq)]
5042
pub struct FunctionParam(usize, CvQualifiers, Option<usize>);
5043
5044
impl Parse for FunctionParam {
5045
0
    fn parse<'a, 'b>(
5046
0
        ctx: &'a ParseContext,
5047
0
        subs: &'a mut SubstitutionTable,
5048
0
        input: IndexStr<'b>,
5049
0
    ) -> Result<(FunctionParam, IndexStr<'b>)> {
5050
0
        try_begin_parse!("FunctionParam", ctx, input);
5051
5052
0
        let tail = consume(b"f", input)?;
5053
0
        if tail.is_empty() {
5054
0
            return Err(error::Error::UnexpectedEnd);
5055
0
        }
5056
5057
0
        let (scope, tail) = if let Ok(tail) = consume(b"L", tail) {
5058
0
            parse_number(10, false, tail)?
5059
        } else {
5060
0
            (0, tail)
5061
        };
5062
5063
0
        let tail = consume(b"p", tail)?;
5064
5065
0
        let (qualifiers, tail) = CvQualifiers::parse(ctx, subs, tail)?;
5066
5067
0
        let (param, tail) = if tail.peek() == Some(b'T') {
5068
0
            (None, consume(b"T", tail)?)
5069
0
        } else if let Ok((num, tail)) = parse_number(10, false, tail) {
5070
0
            (Some(num as usize + 1), consume(b"_", tail)?)
5071
        } else {
5072
0
            (Some(0), consume(b"_", tail)?)
5073
        };
5074
5075
0
        Ok((FunctionParam(scope as _, qualifiers, param), tail))
5076
0
    }
5077
}
5078
5079
impl<'subs, W> Demangle<'subs, W> for FunctionParam
5080
where
5081
    W: 'subs + DemangleWrite,
5082
{
5083
0
    fn demangle<'prev, 'ctx>(
5084
0
        &'subs self,
5085
0
        ctx: &'ctx mut DemangleContext<'subs, W>,
5086
0
        scope: Option<ArgScopeStack<'prev, 'subs>>,
5087
0
    ) -> fmt::Result {
5088
0
        let ctx = try_begin_demangle!(self, ctx, scope);
5089
5090
0
        match self.2 {
5091
0
            None => write!(ctx, "this"),
5092
0
            Some(i) => write!(ctx, "{{parm#{}}}", i + 1),
5093
        }
5094
0
    }
Unexecuted instantiation: <cpp_demangle::ast::FunctionParam as cpp_demangle::ast::Demangle<alloc::string::String>>::demangle
Unexecuted instantiation: <cpp_demangle::ast::FunctionParam as cpp_demangle::ast::Demangle<_>>::demangle
5095
}
5096
5097
/// The `<template-args>` production.
5098
///
5099
/// ```text
5100
/// <template-args> ::= I <template-arg>+ E
5101
/// ```
5102
0
#[derive(Clone, Debug, PartialEq, Eq)]
5103
pub struct TemplateArgs(Vec<TemplateArg>);
5104
5105
impl Parse for TemplateArgs {
5106
0
    fn parse<'a, 'b>(
5107
0
        ctx: &'a ParseContext,
5108
0
        subs: &'a mut SubstitutionTable,
5109
0
        input: IndexStr<'b>,
5110
0
    ) -> Result<(TemplateArgs, IndexStr<'b>)> {
5111
0
        try_begin_parse!("TemplateArgs", ctx, input);
5112
5113
0
        let tail = consume(b"I", input)?;
5114
5115
0
        let (args, tail) = one_or_more::<TemplateArg>(ctx, subs, tail)?;
5116
0
        let tail = consume(b"E", tail)?;
5117
0
        Ok((TemplateArgs(args), tail))
5118
0
    }
5119
}
5120
5121
impl<'subs, W> Demangle<'subs, W> for TemplateArgs
5122
where
5123
    W: 'subs + DemangleWrite,
5124
{
5125
0
    fn demangle<'prev, 'ctx>(
5126
0
        &'subs self,
5127
0
        ctx: &'ctx mut DemangleContext<'subs, W>,
5128
0
        mut scope: Option<ArgScopeStack<'prev, 'subs>>,
5129
0
    ) -> fmt::Result {
5130
0
        let ctx = try_begin_demangle!(self, ctx, scope);
5131
0
        inner_barrier!(ctx);
5132
0
5133
0
        if ctx.last_char_written == Some('<') {
5134
0
            write!(ctx, " ")?;
5135
0
        }
5136
0
        write!(ctx, "<")?;
5137
0
        ctx.push_demangle_node(DemangleNodeType::TemplateArgs);
5138
0
        let mut need_comma = false;
5139
0
        for arg_index in 0..self.0.len() {
5140
0
            if need_comma {
5141
0
                write!(ctx, ", ")?;
5142
0
            }
5143
0
            if let Some(ref mut scope) = scope {
5144
0
                scope.in_arg = Some((arg_index, self));
5145
0
            }
5146
0
            self.0[arg_index].demangle(ctx, scope)?;
5147
0
            need_comma = true;
5148
        }
5149
5150
        // Ensure "> >" because old C++ sucks and libiberty (and its tests)
5151
        // supports old C++.
5152
0
        if ctx.last_char_written == Some('>') {
5153
0
            write!(ctx, " ")?;
5154
0
        }
5155
0
        ctx.pop_demangle_node();
5156
0
        write!(ctx, ">")?;
5157
0
        Ok(())
5158
0
    }
Unexecuted instantiation: <cpp_demangle::ast::TemplateArgs as cpp_demangle::ast::Demangle<alloc::string::String>>::demangle
Unexecuted instantiation: <cpp_demangle::ast::TemplateArgs as cpp_demangle::ast::Demangle<_>>::demangle
5159
}
5160
5161
impl<'subs> ArgScope<'subs, 'subs> for TemplateArgs {
5162
0
    fn leaf_name(&'subs self) -> Result<LeafName<'subs>> {
5163
0
        Err(error::Error::BadLeafNameReference)
5164
0
    }
5165
5166
0
    fn get_template_arg(
5167
0
        &'subs self,
5168
0
        idx: usize,
5169
0
    ) -> Result<(&'subs TemplateArg, &'subs TemplateArgs)> {
5170
0
        self.0
5171
0
            .get(idx)
5172
0
            .ok_or(error::Error::BadTemplateArgReference)
5173
0
            .map(|v| (v, self))
5174
0
    }
5175
5176
0
    fn get_function_arg(&'subs self, _: usize) -> Result<&'subs Type> {
5177
0
        Err(error::Error::BadFunctionArgReference)
5178
0
    }
5179
}
5180
5181
/// A <template-arg> production.
5182
///
5183
/// ```text
5184
/// <template-arg> ::= <type>                # type or template
5185
///                ::= X <expression> E      # expression
5186
///                ::= <expr-primary>        # simple expressions
5187
///                ::= J <template-arg>* E   # argument pack
5188
/// ```
5189
0
#[derive(Clone, Debug, PartialEq, Eq)]
5190
pub enum TemplateArg {
5191
    /// A type or template.
5192
    Type(TypeHandle),
5193
5194
    /// An expression.
5195
    Expression(Expression),
5196
5197
    /// A simple expression.
5198
    SimpleExpression(ExprPrimary),
5199
5200
    /// An argument pack.
5201
    ArgPack(Vec<TemplateArg>),
5202
}
5203
5204
impl Parse for TemplateArg {
5205
0
    fn parse<'a, 'b>(
5206
0
        ctx: &'a ParseContext,
5207
0
        subs: &'a mut SubstitutionTable,
5208
0
        input: IndexStr<'b>,
5209
0
    ) -> Result<(TemplateArg, IndexStr<'b>)> {
5210
0
        try_begin_parse!("TemplateArg", ctx, input);
5211
5212
0
        if let Ok(tail) = consume(b"X", input) {
5213
0
            let (expr, tail) = Expression::parse(ctx, subs, tail)?;
5214
0
            let tail = consume(b"E", tail)?;
5215
0
            return Ok((TemplateArg::Expression(expr), tail));
5216
0
        }
5217
5218
0
        if let Ok((expr, tail)) = ExprPrimary::parse(ctx, subs, input) {
5219
0
            return Ok((TemplateArg::SimpleExpression(expr), tail));
5220
0
        }
5221
5222
0
        if let Ok((ty, tail)) = TypeHandle::parse(ctx, subs, input) {
5223
0
            return Ok((TemplateArg::Type(ty), tail));
5224
0
        }
5225
5226
0
        let tail = if input.peek() == Some(b'J') {
5227
0
            consume(b"J", input)?
5228
        } else {
5229
0
            consume(b"I", input)?
5230
        };
5231
5232
0
        let (args, tail) = if tail.peek() == Some(b'E') {
5233
0
            (vec![], tail)
5234
        } else {
5235
0
            zero_or_more::<TemplateArg>(ctx, subs, tail)?
5236
        };
5237
0
        let tail = consume(b"E", tail)?;
5238
0
        Ok((TemplateArg::ArgPack(args), tail))
5239
0
    }
5240
}
5241
5242
impl<'subs, W> Demangle<'subs, W> for TemplateArg
5243
where
5244
    W: 'subs + DemangleWrite,
5245
{
5246
0
    fn demangle<'prev, 'ctx>(
5247
0
        &'subs self,
5248
0
        ctx: &'ctx mut DemangleContext<'subs, W>,
5249
0
        scope: Option<ArgScopeStack<'prev, 'subs>>,
5250
0
    ) -> fmt::Result {
5251
0
        let ctx = try_begin_demangle!(self, ctx, scope);
5252
5253
0
        match *self {
5254
0
            TemplateArg::Type(ref ty) => ty.demangle(ctx, scope),
5255
0
            TemplateArg::Expression(ref expr) => expr.demangle(ctx, scope),
5256
0
            TemplateArg::SimpleExpression(ref expr) => expr.demangle(ctx, scope),
5257
0
            TemplateArg::ArgPack(ref args) => {
5258
0
                ctx.is_template_argument_pack = true;
5259
0
                let mut need_comma = false;
5260
0
                for arg in &args[..] {
5261
0
                    if need_comma {
5262
0
                        write!(ctx, ", ")?;
5263
0
                    }
5264
0
                    arg.demangle(ctx, scope)?;
5265
0
                    need_comma = true;
5266
                }
5267
0
                Ok(())
5268
            }
5269
        }
5270
0
    }
Unexecuted instantiation: <cpp_demangle::ast::TemplateArg as cpp_demangle::ast::Demangle<alloc::string::String>>::demangle
Unexecuted instantiation: <cpp_demangle::ast::TemplateArg as cpp_demangle::ast::Demangle<_>>::demangle
5271
}
5272
5273
/// In libiberty, Member and DerefMember expressions have special handling.
5274
/// They parse an `UnqualifiedName` (not an `UnscopedName` as the cxxabi docs
5275
/// say) and optionally a `TemplateArgs` if it is present. We can't just parse
5276
/// a `Name` or an `UnscopedTemplateName` here because that allows other inputs
5277
/// that libiberty does not.
5278
0
#[derive(Clone, Debug, PartialEq, Eq)]
5279
pub struct MemberName(Name);
5280
5281
impl Parse for MemberName {
5282
0
    fn parse<'a, 'b>(
5283
0
        ctx: &'a ParseContext,
5284
0
        subs: &'a mut SubstitutionTable,
5285
0
        input: IndexStr<'b>,
5286
0
    ) -> Result<(MemberName, IndexStr<'b>)> {
5287
0
        try_begin_parse!("MemberName", ctx, input);
5288
5289
0
        let (name, tail) = UnqualifiedName::parse(ctx, subs, input)?;
5290
0
        let name = UnscopedName::Unqualified(name);
5291
0
        if let Ok((template, tail)) = TemplateArgs::parse(ctx, subs, tail) {
5292
0
            let name = UnscopedTemplateName(name);
5293
0
            // In libiberty, these are unsubstitutable.
5294
0
            let idx = subs.insert_non_substitution(Substitutable::UnscopedTemplateName(name));
5295
0
            let handle = UnscopedTemplateNameHandle::NonSubstitution(NonSubstitution(idx));
5296
0
            Ok((MemberName(Name::UnscopedTemplate(handle, template)), tail))
5297
        } else {
5298
0
            Ok((MemberName(Name::Unscoped(name)), tail))
5299
        }
5300
0
    }
5301
}
5302
5303
impl<'subs, W> Demangle<'subs, W> for MemberName
5304
where
5305
    W: 'subs + DemangleWrite,
5306
{
5307
0
    fn demangle<'prev, 'ctx>(
5308
0
        &'subs self,
5309
0
        ctx: &'ctx mut DemangleContext<'subs, W>,
5310
0
        scope: Option<ArgScopeStack<'prev, 'subs>>,
5311
0
    ) -> fmt::Result {
5312
0
        let ctx = try_begin_demangle!(self, ctx, scope);
5313
5314
0
        let needs_parens = self.0.get_template_args(ctx.subs).is_some();
5315
0
        if needs_parens {
5316
0
            write!(ctx, "(")?;
5317
0
        }
5318
5319
0
        self.0.demangle(ctx, scope)?;
5320
5321
0
        if needs_parens {
5322
0
            write!(ctx, ")")?;
5323
0
        }
5324
5325
0
        Ok(())
5326
0
    }
Unexecuted instantiation: <cpp_demangle::ast::MemberName as cpp_demangle::ast::Demangle<alloc::string::String>>::demangle
Unexecuted instantiation: <cpp_demangle::ast::MemberName as cpp_demangle::ast::Demangle<_>>::demangle
5327
}
5328
5329
/// The `<expression>` production.
5330
///
5331
/// ```text
5332
///  <expression> ::= <unary operator-name> <expression>
5333
///               ::= <binary operator-name> <expression> <expression>
5334
///               ::= <ternary operator-name> <expression> <expression> <expression>
5335
///               ::= pp_ <expression>                             # prefix ++
5336
///               ::= mm_ <expression>                             # prefix --
5337
///               ::= cl <expression>+ E                           # expression (expr-list), call
5338
///               ::= cv <type> <expression>                       # type (expression), conversion with one argument
5339
///               ::= cv <type> _ <expression>* E                  # type (expr-list), conversion with other than one argument
5340
///               ::= tl <type> <expression>* E                    # type {expr-list}, conversion with braced-init-list argument
5341
///               ::= il <expression> E                            # {expr-list}, braced-init-list in any other context
5342
///               ::= [gs] nw <expression>* _ <type> E             # new (expr-list) type
5343
///               ::= [gs] nw <expression>* _ <type> <initializer> # new (expr-list) type (init)
5344
///               ::= [gs] na <expression>* _ <type> E             # new[] (expr-list) type
5345
///               ::= [gs] na <expression>* _ <type> <initializer> # new[] (expr-list) type (init)
5346
///               ::= [gs] dl <expression>                         # delete expression
5347
///               ::= [gs] da <expression>                         # delete[] expression
5348
///               ::= dc <type> <expression>                       # dynamic_cast<type> (expression)
5349
///               ::= sc <type> <expression>                       # static_cast<type> (expression)
5350
///               ::= cc <type> <expression>                       # const_cast<type> (expression)
5351
///               ::= rc <type> <expression>                       # reinterpret_cast<type> (expression)
5352
///               ::= ti <type>                                    # typeid (type)
5353
///               ::= te <expression>                              # typeid (expression)
5354
///               ::= st <type>                                    # sizeof (type)
5355
///               ::= sz <expression>                              # sizeof (expression)
5356
///               ::= at <type>                                    # alignof (type)
5357
///               ::= az <expression>                              # alignof (expression)
5358
///               ::= nx <expression>                              # noexcept (expression)
5359
///               ::= <template-param>
5360
///               ::= <function-param>
5361
///               ::= dt <expression> <unresolved-name>            # expr.name
5362
///               ::= pt <expression> <unresolved-name>            # expr->name
5363
///               ::= ds <expression> <expression>                 # expr.*expr
5364
///               ::= sZ <template-param>                          # sizeof...(T), size of a template parameter pack
5365
///               ::= sZ <function-param>                          # sizeof...(parameter), size of a function parameter pack
5366
///               ::= sP <template-arg>* E                         # sizeof...(T), size of a captured template parameter pack from an alias template
5367
///               ::= sp <expression>                              # expression..., pack expansion
5368
///               ::= tw <expression>                              # throw expression
5369
///               ::= tr                                           # throw with no operand (rethrow)
5370
///               ::= <unresolved-name>                            # f(p), N::f(p), ::f(p),
5371
///                                                                # freestanding dependent name (e.g., T::x),
5372
///                                                                # objectless nonstatic member reference
5373
///               ::= <expr-primary>
5374
/// ```
5375
0
#[derive(Clone, Debug, PartialEq, Eq)]
5376
pub enum Expression {
5377
    /// A unary operator expression.
5378
    Unary(OperatorName, Box<Expression>),
5379
5380
    /// A binary operator expression.
5381
    Binary(OperatorName, Box<Expression>, Box<Expression>),
5382
5383
    /// A ternary operator expression.
5384
    Ternary(
5385
        OperatorName,
5386
        Box<Expression>,
5387
        Box<Expression>,
5388
        Box<Expression>,
5389
    ),
5390
5391
    /// A prefix `++`.
5392
    PrefixInc(Box<Expression>),
5393
5394
    /// A prefix `--`.
5395
    PrefixDec(Box<Expression>),
5396
5397
    /// A call with functor and arguments.
5398
    Call(Box<Expression>, Vec<Expression>),
5399
5400
    /// A type conversion with one argument.
5401
    ConversionOne(TypeHandle, Box<Expression>),
5402
5403
    /// A type conversion with many arguments.
5404
    ConversionMany(TypeHandle, Vec<Expression>),
5405
5406
    /// A type conversion with many arguments.
5407
    ConversionBraced(TypeHandle, Vec<Expression>),
5408
5409
    /// A braced init list expression.
5410
    BracedInitList(Box<Expression>),
5411
5412
    /// The `new` operator.
5413
    New(Vec<Expression>, TypeHandle, Option<Initializer>),
5414
5415
    /// The global `::new` operator.
5416
    GlobalNew(Vec<Expression>, TypeHandle, Option<Initializer>),
5417
5418
    /// The `new[]` operator.
5419
    NewArray(Vec<Expression>, TypeHandle, Option<Initializer>),
5420
5421
    /// The global `::new[]` operator.
5422
    GlobalNewArray(Vec<Expression>, TypeHandle, Option<Initializer>),
5423
5424
    /// The `delete` operator.
5425
    Delete(Box<Expression>),
5426
5427
    /// The global `::delete` operator.
5428
    GlobalDelete(Box<Expression>),
5429
5430
    /// The `delete[]` operator.
5431
    DeleteArray(Box<Expression>),
5432
5433
    /// The global `::delete[]` operator.
5434
    GlobalDeleteArray(Box<Expression>),
5435
5436
    /// `dynamic_cast<type> (expression)`
5437
    DynamicCast(TypeHandle, Box<Expression>),
5438
5439
    /// `static_cast<type> (expression)`
5440
    StaticCast(TypeHandle, Box<Expression>),
5441
5442
    /// `const_cast<type> (expression)`
5443
    ConstCast(TypeHandle, Box<Expression>),
5444
5445
    /// `reinterpret_cast<type> (expression)`
5446
    ReinterpretCast(TypeHandle, Box<Expression>),
5447
5448
    /// `typeid (type)`
5449
    TypeidType(TypeHandle),
5450
5451
    /// `typeid (expression)`
5452
    TypeidExpr(Box<Expression>),
5453
5454
    /// `sizeof (type)`
5455
    SizeofType(TypeHandle),
5456
5457
    /// `sizeof (expression)`
5458
    SizeofExpr(Box<Expression>),
5459
5460
    /// `alignof (type)`
5461
    AlignofType(TypeHandle),
5462
5463
    /// `alignof (expression)`
5464
    AlignofExpr(Box<Expression>),
5465
5466
    /// `noexcept (expression)`
5467
    Noexcept(Box<Expression>),
5468
5469
    /// A named template parameter.
5470
    TemplateParam(TemplateParam),
5471
5472
    /// A function parameter.
5473
    FunctionParam(FunctionParam),
5474
5475
    /// `expr.name`
5476
    Member(Box<Expression>, MemberName),
5477
5478
    /// `expr->name`
5479
    DerefMember(Box<Expression>, MemberName),
5480
5481
    /// `expr.*expr`
5482
    PointerToMember(Box<Expression>, Box<Expression>),
5483
5484
    /// `sizeof...(T)`, size of a template parameter pack.
5485
    SizeofTemplatePack(TemplateParam),
5486
5487
    /// `sizeof...(parameter)`, size of a function parameter pack.
5488
    SizeofFunctionPack(FunctionParam),
5489
5490
    /// `sizeof...(T)`, size of a captured template parameter pack from an alias
5491
    /// template.
5492
    SizeofCapturedTemplatePack(Vec<TemplateArg>),
5493
5494
    /// `expression...`, pack expansion.
5495
    PackExpansion(Box<Expression>),
5496
5497
    /// `throw expression`
5498
    Throw(Box<Expression>),
5499
5500
    /// `throw` with no operand
5501
    Rethrow,
5502
5503
    /// `f(p)`, `N::f(p)`, `::f(p)`, freestanding dependent name (e.g., `T::x`),
5504
    /// objectless nonstatic member reference.
5505
    UnresolvedName(UnresolvedName),
5506
5507
    /// An `<expr-primary>` production.
5508
    Primary(ExprPrimary),
5509
}
5510
5511
impl Parse for Expression {
5512
0
    fn parse<'a, 'b>(
5513
0
        ctx: &'a ParseContext,
5514
0
        subs: &'a mut SubstitutionTable,
5515
0
        input: IndexStr<'b>,
5516
0
    ) -> Result<(Expression, IndexStr<'b>)> {
5517
0
        try_begin_parse!("Expression", ctx, input);
5518
5519
0
        if let Ok(tail) = consume(b"pp_", input) {
5520
0
            let (expr, tail) = Expression::parse(ctx, subs, tail)?;
5521
0
            let expr = Expression::PrefixInc(Box::new(expr));
5522
0
            return Ok((expr, tail));
5523
0
        }
5524
5525
0
        if let Ok(tail) = consume(b"mm_", input) {
5526
0
            let (expr, tail) = Expression::parse(ctx, subs, tail)?;
5527
0
            let expr = Expression::PrefixDec(Box::new(expr));
5528
0
            return Ok((expr, tail));
5529
0
        }
5530
5531
0
        if let Some((head, tail)) = input.try_split_at(2) {
5532
0
            match head.as_ref() {
5533
0
                b"cl" => {
5534
0
                    let (func, tail) = Expression::parse(ctx, subs, tail)?;
5535
0
                    let (args, tail) = zero_or_more::<Expression>(ctx, subs, tail)?;
5536
0
                    let tail = consume(b"E", tail)?;
5537
0
                    let expr = Expression::Call(Box::new(func), args);
5538
0
                    return Ok((expr, tail));
5539
                }
5540
                b"cv" => {
5541
0
                    let (ty, tail) = TypeHandle::parse(ctx, subs, tail)?;
5542
0
                    if let Ok(tail) = consume(b"_", tail) {
5543
0
                        let (exprs, tail) = zero_or_more::<Expression>(ctx, subs, tail)?;
5544
0
                        let tail = consume(b"E", tail)?;
5545
0
                        let expr = Expression::ConversionMany(ty, exprs);
5546
0
                        return Ok((expr, tail));
5547
                    } else {
5548
0
                        let (expr, tail) = Expression::parse(ctx, subs, tail)?;
5549
0
                        let expr = Expression::ConversionOne(ty, Box::new(expr));
5550
0
                        return Ok((expr, tail));
5551
                    }
5552
                }
5553
                b"tl" => {
5554
0
                    let (ty, tail) = TypeHandle::parse(ctx, subs, tail)?;
5555
0
                    let (exprs, tail) = zero_or_more::<Expression>(ctx, subs, tail)?;
5556
0
                    let expr = Expression::ConversionBraced(ty, exprs);
5557
0
                    let tail = consume(b"E", tail)?;
5558
0
                    return Ok((expr, tail));
5559
                }
5560
                b"il" => {
5561
0
                    let (expr, tail) = Expression::parse(ctx, subs, tail)?;
5562
0
                    let tail = consume(b"E", tail)?;
5563
0
                    let expr = Expression::BracedInitList(Box::new(expr));
5564
0
                    return Ok((expr, tail));
5565
                }
5566
                b"dc" => {
5567
0
                    let (ty, tail) = TypeHandle::parse(ctx, subs, tail)?;
5568
0
                    let (expr, tail) = Expression::parse(ctx, subs, tail)?;
5569
0
                    let expr = Expression::DynamicCast(ty, Box::new(expr));
5570
0
                    return Ok((expr, tail));
5571
                }
5572
                b"sc" => {
5573
0
                    let (ty, tail) = TypeHandle::parse(ctx, subs, tail)?;
5574
0
                    let (expr, tail) = Expression::parse(ctx, subs, tail)?;
5575
0
                    let expr = Expression::StaticCast(ty, Box::new(expr));
5576
0
                    return Ok((expr, tail));
5577
                }
5578
                b"cc" => {
5579
0
                    let (ty, tail) = TypeHandle::parse(ctx, subs, tail)?;
5580
0
                    let (expr, tail) = Expression::parse(ctx, subs, tail)?;
5581
0
                    let expr = Expression::ConstCast(ty, Box::new(expr));
5582
0
                    return Ok((expr, tail));
5583
                }
5584
                b"rc" => {
5585
0
                    let (ty, tail) = TypeHandle::parse(ctx, subs, tail)?;
5586
0
                    let (expr, tail) = Expression::parse(ctx, subs, tail)?;
5587
0
                    let expr = Expression::ReinterpretCast(ty, Box::new(expr));
5588
0
                    return Ok((expr, tail));
5589
                }
5590
                b"ti" => {
5591
0
                    let (ty, tail) = TypeHandle::parse(ctx, subs, tail)?;
5592
0
                    let expr = Expression::TypeidType(ty);
5593
0
                    return Ok((expr, tail));
5594
                }
5595
                b"te" => {
5596
0
                    let (expr, tail) = Expression::parse(ctx, subs, tail)?;
5597
0
                    let expr = Expression::TypeidExpr(Box::new(expr));
5598
0
                    return Ok((expr, tail));
5599
                }
5600
                b"st" => {
5601
0
                    let (ty, tail) = TypeHandle::parse(ctx, subs, tail)?;
5602
0
                    let expr = Expression::SizeofType(ty);
5603
0
                    return Ok((expr, tail));
5604
                }
5605
                b"sz" => {
5606
0
                    let (expr, tail) = Expression::parse(ctx, subs, tail)?;
5607
0
                    let expr = Expression::SizeofExpr(Box::new(expr));
5608
0
                    return Ok((expr, tail));
5609
                }
5610
                b"at" => {
5611
0
                    let (ty, tail) = TypeHandle::parse(ctx, subs, tail)?;
5612
0
                    let expr = Expression::AlignofType(ty);
5613
0
                    return Ok((expr, tail));
5614
                }
5615
                b"az" => {
5616
0
                    let (expr, tail) = Expression::parse(ctx, subs, tail)?;
5617
0
                    let expr = Expression::AlignofExpr(Box::new(expr));
5618
0
                    return Ok((expr, tail));
5619
                }
5620
                b"nx" => {
5621
0
                    let (expr, tail) = Expression::parse(ctx, subs, tail)?;
5622
0
                    let expr = Expression::Noexcept(Box::new(expr));
5623
0
                    return Ok((expr, tail));
5624
                }
5625
                b"dt" => {
5626
0
                    let (expr, tail) = Expression::parse(ctx, subs, tail)?;
5627
0
                    let (name, tail) = MemberName::parse(ctx, subs, tail)?;
5628
0
                    let expr = Expression::Member(Box::new(expr), name);
5629
0
                    return Ok((expr, tail));
5630
                }
5631
                b"pt" => {
5632
0
                    let (expr, tail) = Expression::parse(ctx, subs, tail)?;
5633
0
                    let (name, tail) = MemberName::parse(ctx, subs, tail)?;
5634
0
                    let expr = Expression::DerefMember(Box::new(expr), name);
5635
0
                    return Ok((expr, tail));
5636
                }
5637
                b"ds" => {
5638
0
                    let (first, tail) = Expression::parse(ctx, subs, tail)?;
5639
0
                    let (second, tail) = Expression::parse(ctx, subs, tail)?;
5640
0
                    let expr = Expression::PointerToMember(Box::new(first), Box::new(second));
5641
0
                    return Ok((expr, tail));
5642
                }
5643
                b"sZ" => {
5644
0
                    if let Ok((param, tail)) = TemplateParam::parse(ctx, subs, tail) {
5645
0
                        let expr = Expression::SizeofTemplatePack(param);
5646
0
                        return Ok((expr, tail));
5647
0
                    }
5648
5649
0
                    let (param, tail) = FunctionParam::parse(ctx, subs, tail)?;
5650
0
                    let expr = Expression::SizeofFunctionPack(param);
5651
0
                    return Ok((expr, tail));
5652
                }
5653
                b"sP" => {
5654
0
                    let (args, tail) = zero_or_more::<TemplateArg>(ctx, subs, tail)?;
5655
0
                    let expr = Expression::SizeofCapturedTemplatePack(args);
5656
0
                    let tail = consume(b"E", tail)?;
5657
0
                    return Ok((expr, tail));
5658
                }
5659
                b"sp" => {
5660
0
                    let (expr, tail) = Expression::parse(ctx, subs, tail)?;
5661
0
                    let expr = Expression::PackExpansion(Box::new(expr));
5662
0
                    return Ok((expr, tail));
5663
                }
5664
                b"tw" => {
5665
0
                    let (expr, tail) = Expression::parse(ctx, subs, tail)?;
5666
0
                    let expr = Expression::Throw(Box::new(expr));
5667
0
                    return Ok((expr, tail));
5668
                }
5669
                b"tr" => {
5670
0
                    let expr = Expression::Rethrow;
5671
0
                    return Ok((expr, tail));
5672
                }
5673
                b"gs" => {
5674
0
                    if let Ok((expr, tail)) = can_be_global(true, ctx, subs, tail) {
5675
0
                        return Ok((expr, tail));
5676
0
                    }
5677
                }
5678
0
                _ => {}
5679
            }
5680
0
        }
5681
5682
0
        if let Ok((expr, tail)) = can_be_global(false, ctx, subs, input) {
5683
0
            return Ok((expr, tail));
5684
0
        }
5685
5686
0
        if let Ok((param, tail)) = TemplateParam::parse(ctx, subs, input) {
5687
0
            let expr = Expression::TemplateParam(param);
5688
0
            return Ok((expr, tail));
5689
0
        }
5690
5691
0
        if let Ok((param, tail)) = FunctionParam::parse(ctx, subs, input) {
5692
0
            let expr = Expression::FunctionParam(param);
5693
0
            return Ok((expr, tail));
5694
0
        }
5695
5696
0
        if let Ok((name, tail)) = UnresolvedName::parse(ctx, subs, input) {
5697
0
            let expr = Expression::UnresolvedName(name);
5698
0
            return Ok((expr, tail));
5699
0
        }
5700
5701
0
        if let Ok((prim, tail)) = ExprPrimary::parse(ctx, subs, input) {
5702
0
            let expr = Expression::Primary(prim);
5703
0
            return Ok((expr, tail));
5704
0
        }
5705
5706
        // "A production for <expression> that directly specifies an operation
5707
        // code (e.g., for the -> operator) takes precedence over one that is
5708
        // expressed in terms of (unary/binary/ternary) <operator-name>." So try
5709
        // and parse unary/binary/ternary expressions last.
5710
0
        let (expr, tail) = OperatorName::parse_from_expr(ctx, subs, input)?;
5711
0
        return Ok((expr, tail));
5712
5713
        // Parse the various expressions that can optionally have a leading "gs"
5714
        // to indicate that they are in the global namespace. The input is after
5715
        // we have already detected consumed the optional "gs" and if we did
5716
        // find it, then `is_global` should be true.
5717
0
        fn can_be_global<'a, 'b>(
5718
0
            is_global: bool,
5719
0
            ctx: &'a ParseContext,
5720
0
            subs: &'a mut SubstitutionTable,
5721
0
            input: IndexStr<'b>,
5722
0
        ) -> Result<(Expression, IndexStr<'b>)> {
5723
0
            match input.try_split_at(2) {
5724
0
                None => Err(error::Error::UnexpectedEnd),
5725
0
                Some((head, tail)) => match head.as_ref() {
5726
0
                    b"nw" => {
5727
0
                        let (exprs, tail) = zero_or_more::<Expression>(ctx, subs, tail)?;
5728
0
                        let tail = consume(b"_", tail)?;
5729
0
                        let (ty, tail) = TypeHandle::parse(ctx, subs, tail)?;
5730
0
                        if let Ok(tail) = consume(b"E", tail) {
5731
0
                            let expr = if is_global {
5732
0
                                Expression::GlobalNew(exprs, ty, None)
5733
                            } else {
5734
0
                                Expression::New(exprs, ty, None)
5735
                            };
5736
0
                            Ok((expr, tail))
5737
                        } else {
5738
0
                            let (init, tail) = Initializer::parse(ctx, subs, tail)?;
5739
0
                            let expr = if is_global {
5740
0
                                Expression::GlobalNew(exprs, ty, Some(init))
5741
                            } else {
5742
0
                                Expression::New(exprs, ty, Some(init))
5743
                            };
5744
0
                            Ok((expr, tail))
5745
                        }
5746
                    }
5747
                    b"na" => {
5748
0
                        let (exprs, tail) = zero_or_more::<Expression>(ctx, subs, tail)?;
5749
0
                        let tail = consume(b"_", tail)?;
5750
0
                        let (ty, tail) = TypeHandle::parse(ctx, subs, tail)?;
5751
0
                        if let Ok(tail) = consume(b"E", tail) {
5752
0
                            let expr = if is_global {
5753
0
                                Expression::GlobalNewArray(exprs, ty, None)
5754
                            } else {
5755
0
                                Expression::NewArray(exprs, ty, None)
5756
                            };
5757
0
                            Ok((expr, tail))
5758
                        } else {
5759
0
                            let (init, tail) = Initializer::parse(ctx, subs, tail)?;
5760
0
                            let expr = if is_global {
5761
0
                                Expression::GlobalNewArray(exprs, ty, Some(init))
5762
                            } else {
5763
0
                                Expression::NewArray(exprs, ty, Some(init))
5764
                            };
5765
0
                            Ok((expr, tail))
5766
                        }
5767
                    }
5768
                    b"dl" => {
5769
0
                        let (expr, tail) = Expression::parse(ctx, subs, tail)?;
5770
0
                        let expr = if is_global {
5771
0
                            Expression::GlobalDelete(Box::new(expr))
5772
                        } else {
5773
0
                            Expression::Delete(Box::new(expr))
5774
                        };
5775
0
                        Ok((expr, tail))
5776
                    }
5777
                    b"da" => {
5778
0
                        let (expr, tail) = Expression::parse(ctx, subs, tail)?;
5779
0
                        let expr = if is_global {
5780
0
                            Expression::GlobalDeleteArray(Box::new(expr))
5781
                        } else {
5782
0
                            Expression::DeleteArray(Box::new(expr))
5783
                        };
5784
0
                        Ok((expr, tail))
5785
                    }
5786
0
                    _ => Err(error::Error::UnexpectedText),
5787
                },
5788
            }
5789
0
        }
5790
0
    }
5791
}
5792
5793
impl<'subs, W> Demangle<'subs, W> for Expression
5794
where
5795
    W: 'subs + DemangleWrite,
5796
{
5797
0
    fn demangle<'prev, 'ctx>(
5798
0
        &'subs self,
5799
0
        ctx: &'ctx mut DemangleContext<'subs, W>,
5800
0
        scope: Option<ArgScopeStack<'prev, 'subs>>,
5801
0
    ) -> fmt::Result {
5802
0
        let ctx = try_begin_demangle!(self, ctx, scope);
5803
5804
0
        match *self {
5805
0
            Expression::Unary(OperatorName::Simple(ref op), ref expr)
5806
0
                if *op == SimpleOperatorName::PostInc || *op == SimpleOperatorName::PostDec =>
5807
0
            {
5808
0
                expr.demangle_as_subexpr(ctx, scope)?;
5809
0
                op.demangle(ctx, scope)
5810
            }
5811
0
            Expression::Unary(ref op, ref expr) => {
5812
0
                op.demangle(ctx, scope)?;
5813
0
                expr.demangle_as_subexpr(ctx, scope)
5814
            }
5815
            // These need an extra set of parens so that it doesn't close any
5816
            // template argument accidentally.
5817
            Expression::Binary(
5818
                OperatorName::Simple(SimpleOperatorName::Greater),
5819
0
                ref lhs,
5820
0
                ref rhs,
5821
0
            ) => {
5822
0
                write!(ctx, "((")?;
5823
0
                lhs.demangle(ctx, scope)?;
5824
0
                write!(ctx, ")>(")?;
5825
0
                rhs.demangle(ctx, scope)?;
5826
0
                write!(ctx, "))")
5827
            }
5828
0
            Expression::Binary(ref op, ref lhs, ref rhs) => {
5829
0
                lhs.demangle_as_subexpr(ctx, scope)?;
5830
0
                op.demangle(ctx, scope)?;
5831
0
                rhs.demangle_as_subexpr(ctx, scope)
5832
            }
5833
            Expression::Ternary(
5834
                OperatorName::Simple(SimpleOperatorName::Question),
5835
0
                ref condition,
5836
0
                ref consequent,
5837
0
                ref alternative,
5838
0
            ) => {
5839
0
                condition.demangle_as_subexpr(ctx, scope)?;
5840
0
                write!(ctx, "?")?;
5841
0
                consequent.demangle_as_subexpr(ctx, scope)?;
5842
0
                write!(ctx, " : ")?;
5843
0
                alternative.demangle_as_subexpr(ctx, scope)
5844
            }
5845
0
            Expression::Ternary(ref op, ref e1, ref e2, ref e3) => {
5846
0
                // Nonsensical ternary operator? Just print it like a function call,
5847
0
                // I suppose...
5848
0
                //
5849
0
                // TODO: should we detect and reject this during parsing?
5850
0
                op.demangle(ctx, scope)?;
5851
0
                write!(ctx, "(")?;
5852
0
                e1.demangle(ctx, scope)?;
5853
0
                write!(ctx, ", ")?;
5854
0
                e2.demangle(ctx, scope)?;
5855
0
                write!(ctx, ", ")?;
5856
0
                e3.demangle(ctx, scope)?;
5857
0
                write!(ctx, ")")?;
5858
0
                Ok(())
5859
            }
5860
0
            Expression::PrefixInc(ref expr) => {
5861
0
                write!(ctx, "++")?;
5862
0
                expr.demangle(ctx, scope)
5863
            }
5864
0
            Expression::PrefixDec(ref expr) => {
5865
0
                write!(ctx, "--")?;
5866
0
                expr.demangle(ctx, scope)
5867
            }
5868
0
            Expression::Call(ref functor_expr, ref args) => {
5869
0
                functor_expr.demangle_as_subexpr(ctx, scope)?;
5870
0
                write!(ctx, "(")?;
5871
0
                let mut need_comma = false;
5872
0
                for arg in args {
5873
0
                    if need_comma {
5874
0
                        write!(ctx, ", ")?;
5875
0
                    }
5876
0
                    arg.demangle(ctx, scope)?;
5877
0
                    need_comma = true;
5878
                }
5879
0
                write!(ctx, ")")?;
5880
0
                Ok(())
5881
            }
5882
0
            Expression::ConversionOne(ref ty, ref expr) => {
5883
0
                write!(ctx, "(")?;
5884
0
                ty.demangle(ctx, scope)?;
5885
0
                write!(ctx, ")(")?;
5886
0
                expr.demangle(ctx, scope)?;
5887
0
                write!(ctx, ")")?;
5888
0
                Ok(())
5889
            }
5890
0
            Expression::ConversionMany(ref ty, ref exprs) => {
5891
0
                ty.demangle(ctx, scope)?;
5892
0
                write!(ctx, "(")?;
5893
0
                let mut need_comma = false;
5894
0
                for expr in exprs {
5895
0
                    if need_comma {
5896
0
                        write!(ctx, ", ")?;
5897
0
                    }
5898
0
                    expr.demangle(ctx, scope)?;
5899
0
                    need_comma = true;
5900
                }
5901
0
                write!(ctx, ")")?;
5902
0
                Ok(())
5903
            }
5904
0
            Expression::ConversionBraced(ref ty, ref exprs) => {
5905
0
                ty.demangle(ctx, scope)?;
5906
0
                write!(ctx, "{{")?;
5907
0
                let mut need_comma = false;
5908
0
                for expr in exprs {
5909
0
                    if need_comma {
5910
0
                        write!(ctx, ", ")?;
5911
0
                    }
5912
0
                    expr.demangle(ctx, scope)?;
5913
0
                    need_comma = true;
5914
                }
5915
0
                write!(ctx, "}}")?;
5916
0
                Ok(())
5917
            }
5918
0
            Expression::BracedInitList(ref expr) => {
5919
0
                write!(ctx, "{{")?;
5920
0
                expr.demangle(ctx, scope)?;
5921
0
                write!(ctx, "}}")?;
5922
0
                Ok(())
5923
            }
5924
            // TODO: factor out all this duplication in the `new` variants.
5925
0
            Expression::New(ref exprs, ref ty, ref init) => {
5926
0
                write!(ctx, "new (")?;
5927
0
                let mut need_comma = false;
5928
0
                for expr in exprs {
5929
0
                    if need_comma {
5930
0
                        write!(ctx, ", ")?;
5931
0
                    }
5932
0
                    expr.demangle(ctx, scope)?;
5933
0
                    need_comma = true;
5934
                }
5935
0
                write!(ctx, ") ")?;
5936
0
                ty.demangle(ctx, scope)?;
5937
0
                if let Some(ref init) = *init {
5938
0
                    init.demangle(ctx, scope)?;
5939
0
                }
5940
0
                Ok(())
5941
            }
5942
0
            Expression::GlobalNew(ref exprs, ref ty, ref init) => {
5943
0
                write!(ctx, "::new (")?;
5944
0
                let mut need_comma = false;
5945
0
                for expr in exprs {
5946
0
                    if need_comma {
5947
0
                        write!(ctx, ", ")?;
5948
0
                    }
5949
0
                    expr.demangle(ctx, scope)?;
5950
0
                    need_comma = true;
5951
                }
5952
0
                write!(ctx, ") ")?;
5953
0
                ty.demangle(ctx, scope)?;
5954
0
                if let Some(ref init) = *init {
5955
0
                    init.demangle(ctx, scope)?;
5956
0
                }
5957
0
                Ok(())
5958
            }
5959
0
            Expression::NewArray(ref exprs, ref ty, ref init) => {
5960
0
                write!(ctx, "new[] (")?;
5961
0
                let mut need_comma = false;
5962
0
                for expr in exprs {
5963
0
                    if need_comma {
5964
0
                        write!(ctx, ", ")?;
5965
0
                    }
5966
0
                    expr.demangle(ctx, scope)?;
5967
0
                    need_comma = true;
5968
                }
5969
0
                write!(ctx, ") ")?;
5970
0
                ty.demangle(ctx, scope)?;
5971
0
                if let Some(ref init) = *init {
5972
0
                    init.demangle(ctx, scope)?;
5973
0
                }
5974
0
                Ok(())
5975
            }
5976
0
            Expression::GlobalNewArray(ref exprs, ref ty, ref init) => {
5977
0
                write!(ctx, "::new[] (")?;
5978
0
                let mut need_comma = false;
5979
0
                for expr in exprs {
5980
0
                    if need_comma {
5981
0
                        write!(ctx, ", ")?;
5982
0
                    }
5983
0
                    expr.demangle(ctx, scope)?;
5984
0
                    need_comma = true;
5985
                }
5986
0
                write!(ctx, ") ")?;
5987
0
                ty.demangle(ctx, scope)?;
5988
0
                if let Some(ref init) = *init {
5989
0
                    init.demangle(ctx, scope)?;
5990
0
                }
5991
0
                Ok(())
5992
            }
5993
0
            Expression::Delete(ref expr) => {
5994
0
                write!(ctx, "delete ")?;
5995
0
                expr.demangle(ctx, scope)
5996
            }
5997
0
            Expression::GlobalDelete(ref expr) => {
5998
0
                write!(ctx, "::delete ")?;
5999
0
                expr.demangle(ctx, scope)
6000
            }
6001
0
            Expression::DeleteArray(ref expr) => {
6002
0
                write!(ctx, "delete[] ")?;
6003
0
                expr.demangle(ctx, scope)
6004
            }
6005
0
            Expression::GlobalDeleteArray(ref expr) => {
6006
0
                write!(ctx, "::delete[] ")?;
6007
0
                expr.demangle(ctx, scope)
6008
            }
6009
            // TODO: factor out duplicated code from cast variants.
6010
0
            Expression::DynamicCast(ref ty, ref expr) => {
6011
0
                write!(ctx, "dynamic_cast<")?;
6012
0
                ty.demangle(ctx, scope)?;
6013
0
                write!(ctx, ">(")?;
6014
0
                expr.demangle(ctx, scope)?;
6015
0
                write!(ctx, ")")?;
6016
0
                Ok(())
6017
            }
6018
0
            Expression::StaticCast(ref ty, ref expr) => {
6019
0
                write!(ctx, "static_cast<")?;
6020
0
                ty.demangle(ctx, scope)?;
6021
0
                write!(ctx, ">(")?;
6022
0
                expr.demangle(ctx, scope)?;
6023
0
                write!(ctx, ")")?;
6024
0
                Ok(())
6025
            }
6026
0
            Expression::ConstCast(ref ty, ref expr) => {
6027
0
                write!(ctx, "const_cast<")?;
6028
0
                ty.demangle(ctx, scope)?;
6029
0
                write!(ctx, ">(")?;
6030
0
                expr.demangle(ctx, scope)?;
6031
0
                write!(ctx, ")")?;
6032
0
                Ok(())
6033
            }
6034
0
            Expression::ReinterpretCast(ref ty, ref expr) => {
6035
0
                write!(ctx, "reinterpret_cast<")?;
6036
0
                ty.demangle(ctx, scope)?;
6037
0
                write!(ctx, ">(")?;
6038
0
                expr.demangle(ctx, scope)?;
6039
0
                write!(ctx, ")")?;
6040
0
                Ok(())
6041
            }
6042
0
            Expression::TypeidType(ref ty) => {
6043
0
                write!(ctx, "typeid (")?;
6044
0
                ty.demangle(ctx, scope)?;
6045
0
                write!(ctx, ")")?;
6046
0
                Ok(())
6047
            }
6048
0
            Expression::TypeidExpr(ref expr) => {
6049
0
                write!(ctx, "typeid (")?;
6050
0
                expr.demangle(ctx, scope)?;
6051
0
                write!(ctx, ")")?;
6052
0
                Ok(())
6053
            }
6054
0
            Expression::SizeofType(ref ty) => {
6055
0
                write!(ctx, "sizeof (")?;
6056
0
                ty.demangle(ctx, scope)?;
6057
0
                write!(ctx, ")")?;
6058
0
                Ok(())
6059
            }
6060
0
            Expression::SizeofExpr(ref expr) => {
6061
0
                write!(ctx, "sizeof (")?;
6062
0
                expr.demangle(ctx, scope)?;
6063
0
                write!(ctx, ")")?;
6064
0
                Ok(())
6065
            }
6066
0
            Expression::AlignofType(ref ty) => {
6067
0
                write!(ctx, "alignof (")?;
6068
0
                ty.demangle(ctx, scope)?;
6069
0
                write!(ctx, ")")?;
6070
0
                Ok(())
6071
            }
6072
0
            Expression::AlignofExpr(ref expr) => {
6073
0
                write!(ctx, "alignof (")?;
6074
0
                expr.demangle(ctx, scope)?;
6075
0
                write!(ctx, ")")?;
6076
0
                Ok(())
6077
            }
6078
0
            Expression::Noexcept(ref expr) => {
6079
0
                write!(ctx, "noexcept (")?;
6080
0
                expr.demangle(ctx, scope)?;
6081
0
                write!(ctx, ")")?;
6082
0
                Ok(())
6083
            }
6084
0
            Expression::TemplateParam(ref param) => param.demangle(ctx, scope),
6085
0
            Expression::FunctionParam(ref param) => param.demangle(ctx, scope),
6086
0
            Expression::Member(ref expr, ref name) => {
6087
0
                expr.demangle_as_subexpr(ctx, scope)?;
6088
0
                write!(ctx, ".")?;
6089
0
                name.demangle(ctx, scope)
6090
            }
6091
0
            Expression::DerefMember(ref expr, ref name) => {
6092
0
                expr.demangle(ctx, scope)?;
6093
0
                write!(ctx, "->")?;
6094
0
                name.demangle(ctx, scope)
6095
            }
6096
0
            Expression::PointerToMember(ref e1, ref e2) => {
6097
0
                e1.demangle(ctx, scope)?;
6098
0
                write!(ctx, ".*")?;
6099
0
                e2.demangle(ctx, scope)
6100
            }
6101
0
            Expression::SizeofTemplatePack(ref param) => {
6102
0
                write!(ctx, "sizeof...(")?;
6103
0
                param.demangle(ctx, scope)?;
6104
0
                write!(ctx, ")")?;
6105
0
                Ok(())
6106
            }
6107
0
            Expression::SizeofFunctionPack(ref param) => {
6108
0
                write!(ctx, "sizeof...(")?;
6109
0
                param.demangle(ctx, scope)?;
6110
0
                write!(ctx, ")")?;
6111
0
                Ok(())
6112
            }
6113
0
            Expression::SizeofCapturedTemplatePack(ref args) => {
6114
0
                write!(ctx, "sizeof...(")?;
6115
0
                let mut need_comma = false;
6116
0
                for arg in args {
6117
0
                    if need_comma {
6118
0
                        write!(ctx, ", ")?;
6119
0
                    }
6120
0
                    arg.demangle(ctx, scope)?;
6121
0
                    need_comma = true;
6122
                }
6123
0
                write!(ctx, ")")?;
6124
0
                Ok(())
6125
            }
6126
0
            Expression::PackExpansion(ref pack) => {
6127
0
                pack.demangle_as_subexpr(ctx, scope)?;
6128
0
                write!(ctx, "...")?;
6129
0
                Ok(())
6130
            }
6131
0
            Expression::Throw(ref expr) => {
6132
0
                write!(ctx, "throw ")?;
6133
0
                expr.demangle(ctx, scope)
6134
            }
6135
            Expression::Rethrow => {
6136
0
                write!(ctx, "throw")?;
6137
0
                Ok(())
6138
            }
6139
0
            Expression::UnresolvedName(ref name) => name.demangle(ctx, scope),
6140
0
            Expression::Primary(ref expr) => expr.demangle(ctx, scope),
6141
        }
6142
0
    }
Unexecuted instantiation: <cpp_demangle::ast::Expression as cpp_demangle::ast::Demangle<alloc::string::String>>::demangle
Unexecuted instantiation: <cpp_demangle::ast::Expression as cpp_demangle::ast::Demangle<_>>::demangle
6143
}
6144
6145
impl Expression {
6146
0
    fn demangle_as_subexpr<'subs, 'prev, 'ctx, W>(
6147
0
        &'subs self,
6148
0
        ctx: &'ctx mut DemangleContext<'subs, W>,
6149
0
        scope: Option<ArgScopeStack<'prev, 'subs>>,
6150
0
    ) -> fmt::Result
6151
0
    where
6152
0
        W: 'subs + DemangleWrite,
6153
0
    {
6154
0
        let needs_parens = match *self {
6155
0
            Expression::FunctionParam(_) | Expression::Primary(ExprPrimary::External(_)) => false,
6156
0
            _ => true,
6157
        };
6158
6159
0
        if needs_parens {
6160
0
            write!(ctx, "(")?;
6161
0
        }
6162
6163
0
        self.demangle(ctx, scope)?;
6164
6165
0
        if needs_parens {
6166
0
            write!(ctx, ")")?;
6167
0
        }
6168
6169
0
        Ok(())
6170
0
    }
Unexecuted instantiation: <cpp_demangle::ast::Expression>::demangle_as_subexpr::<alloc::string::String>
Unexecuted instantiation: <cpp_demangle::ast::Expression>::demangle_as_subexpr::<_>
6171
}
6172
6173
/// The `<unresolved-name>` production.
6174
///
6175
/// ```text
6176
/// <unresolved-name> ::= [gs] <base-unresolved-name>
6177
///                          #
6178
///                   ::= sr <unresolved-type> <base-unresolved-name>
6179
///                          #
6180
///                   ::= srN <unresolved-type> <unresolved-qualifier-level>+ E <base-unresolved-name>
6181
///                          #
6182
///                   ::= [gs] sr <unresolved-qualifier-level>+ E <base-unresolved-name>
6183
///                          # A::x, N::y, A<T>::z; "gs" means leading "::"
6184
/// ```
6185
0
#[derive(Clone, Debug, PartialEq, Eq)]
6186
pub enum UnresolvedName {
6187
    /// `x`
6188
    Name(BaseUnresolvedName),
6189
6190
    /// `::x`
6191
    Global(BaseUnresolvedName),
6192
6193
    /// `T::x`  or `decltype(p)::x` or `T::N::x` or `decltype(p)::N::x`
6194
    Nested1(
6195
        UnresolvedTypeHandle,
6196
        Vec<UnresolvedQualifierLevel>,
6197
        BaseUnresolvedName,
6198
    ),
6199
6200
    /// `A::x` or `N::y` or `A<T>::z`
6201
    Nested2(Vec<UnresolvedQualifierLevel>, BaseUnresolvedName),
6202
6203
    /// `::A::x` or `::N::y` or `::A<T>::z`
6204
    GlobalNested2(Vec<UnresolvedQualifierLevel>, BaseUnresolvedName),
6205
}
6206
6207
impl Parse for UnresolvedName {
6208
0
    fn parse<'a, 'b>(
6209
0
        ctx: &'a ParseContext,
6210
0
        subs: &'a mut SubstitutionTable,
6211
0
        input: IndexStr<'b>,
6212
0
    ) -> Result<(UnresolvedName, IndexStr<'b>)> {
6213
0
        try_begin_parse!("UnresolvedName", ctx, input);
6214
6215
0
        if let Ok(tail) = consume(b"gs", input) {
6216
0
            if let Ok((name, tail)) = BaseUnresolvedName::parse(ctx, subs, tail) {
6217
0
                return Ok((UnresolvedName::Global(name), tail));
6218
0
            }
6219
6220
0
            let tail = consume(b"sr", tail)?;
6221
0
            let (levels, tail) = one_or_more::<UnresolvedQualifierLevel>(ctx, subs, tail)?;
6222
0
            let tail = consume(b"E", tail)?;
6223
0
            let (name, tail) = BaseUnresolvedName::parse(ctx, subs, tail)?;
6224
0
            return Ok((UnresolvedName::GlobalNested2(levels, name), tail));
6225
0
        }
6226
6227
0
        if let Ok((name, tail)) = BaseUnresolvedName::parse(ctx, subs, input) {
6228
0
            return Ok((UnresolvedName::Name(name), tail));
6229
0
        }
6230
6231
0
        let tail = consume(b"sr", input)?;
6232
6233
0
        if tail.peek() == Some(b'N') {
6234
0
            let tail = consume(b"N", tail).unwrap();
6235
0
            let (ty, tail) = UnresolvedTypeHandle::parse(ctx, subs, tail)?;
6236
0
            let (levels, tail) = one_or_more::<UnresolvedQualifierLevel>(ctx, subs, tail)?;
6237
0
            let tail = consume(b"E", tail)?;
6238
0
            let (name, tail) = BaseUnresolvedName::parse(ctx, subs, tail)?;
6239
0
            return Ok((UnresolvedName::Nested1(ty, levels, name), tail));
6240
0
        }
6241
6242
0
        if let Ok((ty, tail)) = UnresolvedTypeHandle::parse(ctx, subs, tail) {
6243
0
            let (name, tail) = BaseUnresolvedName::parse(ctx, subs, tail)?;
6244
0
            return Ok((UnresolvedName::Nested1(ty, vec![], name), tail));
6245
0
        }
6246
6247
0
        let (levels, tail) = one_or_more::<UnresolvedQualifierLevel>(ctx, subs, tail)?;
6248
0
        let tail = consume(b"E", tail)?;
6249
0
        let (name, tail) = BaseUnresolvedName::parse(ctx, subs, tail)?;
6250
0
        Ok((UnresolvedName::Nested2(levels, name), tail))
6251
0
    }
6252
}
6253
6254
impl<'subs, W> Demangle<'subs, W> for UnresolvedName
6255
where
6256
    W: 'subs + DemangleWrite,
6257
{
6258
0
    fn demangle<'prev, 'ctx>(
6259
0
        &'subs self,
6260
0
        ctx: &'ctx mut DemangleContext<'subs, W>,
6261
0
        scope: Option<ArgScopeStack<'prev, 'subs>>,
6262
0
    ) -> fmt::Result {
6263
0
        let ctx = try_begin_demangle!(self, ctx, scope);
6264
6265
0
        match *self {
6266
0
            UnresolvedName::Name(ref name) => name.demangle(ctx, scope),
6267
0
            UnresolvedName::Global(ref name) => {
6268
0
                write!(ctx, "::")?;
6269
0
                name.demangle(ctx, scope)
6270
            }
6271
0
            UnresolvedName::Nested1(ref ty, ref levels, ref name) => {
6272
0
                ty.demangle(ctx, scope)?;
6273
0
                write!(ctx, "::")?;
6274
0
                for lvl in &levels[..] {
6275
0
                    lvl.demangle(ctx, scope)?;
6276
0
                    write!(ctx, "::")?;
6277
                }
6278
0
                name.demangle(ctx, scope)
6279
            }
6280
0
            UnresolvedName::Nested2(ref levels, ref name) => {
6281
0
                for lvl in &levels[..] {
6282
0
                    lvl.demangle(ctx, scope)?;
6283
0
                    write!(ctx, "::")?;
6284
                }
6285
0
                name.demangle(ctx, scope)
6286
            }
6287
            // `::A::x` or `::N::y` or `::A<T>::z`
6288
0
            UnresolvedName::GlobalNested2(ref levels, ref name) => {
6289
0
                write!(ctx, "::")?;
6290
0
                for lvl in &levels[..] {
6291
0
                    lvl.demangle(ctx, scope)?;
6292
0
                    write!(ctx, "::")?;
6293
                }
6294
0
                name.demangle(ctx, scope)
6295
            }
6296
        }
6297
0
    }
Unexecuted instantiation: <cpp_demangle::ast::UnresolvedName as cpp_demangle::ast::Demangle<alloc::string::String>>::demangle
Unexecuted instantiation: <cpp_demangle::ast::UnresolvedName as cpp_demangle::ast::Demangle<_>>::demangle
6298
}
6299
6300
/// The `<unresolved-type>` production.
6301
///
6302
/// ```text
6303
/// <unresolved-type> ::= <template-param> [ <template-args> ]  # T:: or T<X,Y>::
6304
///                   ::= <decltype>                            # decltype(p)::
6305
///                   ::= <substitution>
6306
/// ```
6307
0
#[derive(Clone, Debug, PartialEq, Eq)]
6308
pub enum UnresolvedType {
6309
    /// An unresolved template type.
6310
    Template(TemplateParam, Option<TemplateArgs>),
6311
6312
    /// An unresolved `decltype`.
6313
    Decltype(Decltype),
6314
}
6315
6316
0
define_handle! {
6317
0
    /// A reference to a parsed `<unresolved-type>` production.
6318
0
    pub enum UnresolvedTypeHandle
6319
0
}
6320
6321
impl Parse for UnresolvedTypeHandle {
6322
0
    fn parse<'a, 'b>(
6323
0
        ctx: &'a ParseContext,
6324
0
        subs: &'a mut SubstitutionTable,
6325
0
        input: IndexStr<'b>,
6326
0
    ) -> Result<(UnresolvedTypeHandle, IndexStr<'b>)> {
6327
0
        try_begin_parse!("UnresolvedTypeHandle", ctx, input);
6328
6329
0
        if let Ok((param, tail)) = TemplateParam::parse(ctx, subs, input) {
6330
0
            let (args, tail) = if let Ok((args, tail)) = TemplateArgs::parse(ctx, subs, tail) {
6331
0
                (Some(args), tail)
6332
            } else {
6333
0
                (None, tail)
6334
            };
6335
0
            let ty = UnresolvedType::Template(param, args);
6336
0
            let ty = Substitutable::UnresolvedType(ty);
6337
0
            let idx = subs.insert(ty);
6338
0
            let handle = UnresolvedTypeHandle::BackReference(idx);
6339
0
            return Ok((handle, tail));
6340
0
        }
6341
6342
0
        if let Ok((decltype, tail)) = Decltype::parse(ctx, subs, input) {
6343
0
            let ty = UnresolvedType::Decltype(decltype);
6344
0
            let ty = Substitutable::UnresolvedType(ty);
6345
0
            let idx = subs.insert(ty);
6346
0
            let handle = UnresolvedTypeHandle::BackReference(idx);
6347
0
            return Ok((handle, tail));
6348
0
        }
6349
6350
0
        let (sub, tail) = Substitution::parse(ctx, subs, input)?;
6351
0
        match sub {
6352
0
            Substitution::WellKnown(component) => {
6353
0
                Ok((UnresolvedTypeHandle::WellKnown(component), tail))
6354
            }
6355
0
            Substitution::BackReference(idx) => {
6356
0
                // TODO: should this check that the back reference actually
6357
0
                // points to an `<unresolved-type>`?
6358
0
                Ok((UnresolvedTypeHandle::BackReference(idx), tail))
6359
            }
6360
        }
6361
0
    }
6362
}
6363
6364
impl<'subs, W> Demangle<'subs, W> for UnresolvedType
6365
where
6366
    W: 'subs + DemangleWrite,
6367
{
6368
0
    fn demangle<'prev, 'ctx>(
6369
0
        &'subs self,
6370
0
        ctx: &'ctx mut DemangleContext<'subs, W>,
6371
0
        scope: Option<ArgScopeStack<'prev, 'subs>>,
6372
0
    ) -> fmt::Result {
6373
0
        let ctx = try_begin_demangle!(self, ctx, scope);
6374
6375
0
        match *self {
6376
0
            UnresolvedType::Decltype(ref dt) => dt.demangle(ctx, scope),
6377
0
            UnresolvedType::Template(ref param, ref args) => {
6378
0
                if let Some(ref args) = *args {
6379
0
                    let scope = scope.push(args);
6380
0
                    param.demangle(ctx, scope)?;
6381
0
                    args.demangle(ctx, scope)?;
6382
                } else {
6383
0
                    param.demangle(ctx, scope)?;
6384
                }
6385
0
                Ok(())
6386
            }
6387
        }
6388
0
    }
Unexecuted instantiation: <cpp_demangle::ast::UnresolvedType as cpp_demangle::ast::Demangle<alloc::string::String>>::demangle
Unexecuted instantiation: <cpp_demangle::ast::UnresolvedType as cpp_demangle::ast::Demangle<_>>::demangle
6389
}
6390
6391
/// The `<unresolved-qualifier-level>` production.
6392
///
6393
/// ```text
6394
/// <unresolved-qualifier-level> ::= <simple-id>
6395
/// ```
6396
0
#[derive(Clone, Debug, PartialEq, Eq)]
6397
pub struct UnresolvedQualifierLevel(SimpleId);
6398
6399
impl Parse for UnresolvedQualifierLevel {
6400
0
    fn parse<'a, 'b>(
6401
0
        ctx: &'a ParseContext,
6402
0
        subs: &'a mut SubstitutionTable,
6403
0
        input: IndexStr<'b>,
6404
0
    ) -> Result<(UnresolvedQualifierLevel, IndexStr<'b>)> {
6405
0
        try_begin_parse!("UnresolvedQualifierLevel", ctx, input);
6406
6407
0
        let (id, tail) = SimpleId::parse(ctx, subs, input)?;
6408
0
        Ok((UnresolvedQualifierLevel(id), tail))
6409
0
    }
6410
}
6411
6412
impl<'subs, W> Demangle<'subs, W> for UnresolvedQualifierLevel
6413
where
6414
    W: 'subs + DemangleWrite,
6415
{
6416
    #[inline]
6417
0
    fn demangle<'prev, 'ctx>(
6418
0
        &'subs self,
6419
0
        ctx: &'ctx mut DemangleContext<'subs, W>,
6420
0
        scope: Option<ArgScopeStack<'prev, 'subs>>,
6421
0
    ) -> fmt::Result {
6422
0
        let ctx = try_begin_demangle!(self, ctx, scope);
6423
6424
0
        self.0.demangle(ctx, scope)
6425
0
    }
Unexecuted instantiation: <cpp_demangle::ast::UnresolvedQualifierLevel as cpp_demangle::ast::Demangle<alloc::string::String>>::demangle
Unexecuted instantiation: <cpp_demangle::ast::UnresolvedQualifierLevel as cpp_demangle::ast::Demangle<_>>::demangle
6426
}
6427
6428
/// The `<simple-id>` production.
6429
///
6430
/// ```text
6431
/// <simple-id> ::= <source-name> [ <template-args> ]
6432
/// ```
6433
0
#[derive(Clone, Debug, PartialEq, Eq)]
6434
pub struct SimpleId(SourceName, Option<TemplateArgs>);
6435
6436
impl Parse for SimpleId {
6437
0
    fn parse<'a, 'b>(
6438
0
        ctx: &'a ParseContext,
6439
0
        subs: &'a mut SubstitutionTable,
6440
0
        input: IndexStr<'b>,
6441
0
    ) -> Result<(SimpleId, IndexStr<'b>)> {
6442
0
        try_begin_parse!("SimpleId", ctx, input);
6443
6444
0
        let (name, tail) = SourceName::parse(ctx, subs, input)?;
6445
0
        let (args, tail) = if let Ok((args, tail)) = TemplateArgs::parse(ctx, subs, tail) {
6446
0
            (Some(args), tail)
6447
        } else {
6448
0
            (None, tail)
6449
        };
6450
0
        Ok((SimpleId(name, args), tail))
6451
0
    }
6452
}
6453
6454
impl<'subs, W> Demangle<'subs, W> for SimpleId
6455
where
6456
    W: 'subs + DemangleWrite,
6457
{
6458
0
    fn demangle<'prev, 'ctx>(
6459
0
        &'subs self,
6460
0
        ctx: &'ctx mut DemangleContext<'subs, W>,
6461
0
        scope: Option<ArgScopeStack<'prev, 'subs>>,
6462
0
    ) -> fmt::Result {
6463
0
        let ctx = try_begin_demangle!(self, ctx, scope);
6464
6465
0
        self.0.demangle(ctx, scope)?;
6466
0
        if let Some(ref args) = self.1 {
6467
0
            args.demangle(ctx, scope)?;
6468
0
        }
6469
0
        Ok(())
6470
0
    }
Unexecuted instantiation: <cpp_demangle::ast::SimpleId as cpp_demangle::ast::Demangle<alloc::string::String>>::demangle
Unexecuted instantiation: <cpp_demangle::ast::SimpleId as cpp_demangle::ast::Demangle<_>>::demangle
6471
}
6472
6473
/// The `<base-unresolved-name>` production.
6474
///
6475
/// ```text
6476
/// <base-unresolved-name> ::= <simple-id>                        # unresolved name
6477
///                        ::= on <operator-name>                 # unresolved operator-function-id
6478
///                        ::= on <operator-name> <template-args> # unresolved operator template-id
6479
///                        ::= dn <destructor-name>               # destructor or pseudo-destructor;
6480
///                                                               # e.g. ~X or ~X<N-1>
6481
/// ```
6482
0
#[derive(Clone, Debug, PartialEq, Eq)]
6483
pub enum BaseUnresolvedName {
6484
    /// An unresolved name.
6485
    Name(SimpleId),
6486
6487
    /// An unresolved function or template function name.
6488
    Operator(OperatorName, Option<TemplateArgs>),
6489
6490
    /// An unresolved destructor name.
6491
    Destructor(DestructorName),
6492
}
6493
6494
impl Parse for BaseUnresolvedName {
6495
0
    fn parse<'a, 'b>(
6496
0
        ctx: &'a ParseContext,
6497
0
        subs: &'a mut SubstitutionTable,
6498
0
        input: IndexStr<'b>,
6499
0
    ) -> Result<(BaseUnresolvedName, IndexStr<'b>)> {
6500
0
        try_begin_parse!("BaseUnresolvedName", ctx, input);
6501
6502
0
        if let Ok((name, tail)) = SimpleId::parse(ctx, subs, input) {
6503
0
            return Ok((BaseUnresolvedName::Name(name), tail));
6504
0
        }
6505
6506
0
        if let Ok(tail) = consume(b"on", input) {
6507
0
            let (opname, tail) = OperatorName::parse(ctx, subs, tail)?;
6508
0
            let (args, tail) = if let Ok((args, tail)) = TemplateArgs::parse(ctx, subs, tail) {
6509
0
                (Some(args), tail)
6510
            } else {
6511
0
                (None, tail)
6512
            };
6513
0
            return Ok((BaseUnresolvedName::Operator(opname, args), tail));
6514
0
        }
6515
6516
0
        let tail = consume(b"dn", input)?;
6517
0
        let (name, tail) = DestructorName::parse(ctx, subs, tail)?;
6518
0
        Ok((BaseUnresolvedName::Destructor(name), tail))
6519
0
    }
6520
}
6521
6522
impl<'subs, W> Demangle<'subs, W> for BaseUnresolvedName
6523
where
6524
    W: 'subs + DemangleWrite,
6525
{
6526
0
    fn demangle<'prev, 'ctx>(
6527
0
        &'subs self,
6528
0
        ctx: &'ctx mut DemangleContext<'subs, W>,
6529
0
        scope: Option<ArgScopeStack<'prev, 'subs>>,
6530
0
    ) -> fmt::Result {
6531
0
        let ctx = try_begin_demangle!(self, ctx, scope);
6532
6533
0
        match *self {
6534
0
            BaseUnresolvedName::Name(ref name) => name.demangle(ctx, scope),
6535
0
            BaseUnresolvedName::Destructor(ref dtor) => dtor.demangle(ctx, scope),
6536
0
            BaseUnresolvedName::Operator(ref op, ref args) => {
6537
0
                op.demangle(ctx, scope)?;
6538
0
                if let Some(ref args) = *args {
6539
0
                    args.demangle(ctx, scope)?;
6540
0
                }
6541
0
                Ok(())
6542
            }
6543
        }
6544
0
    }
Unexecuted instantiation: <cpp_demangle::ast::BaseUnresolvedName as cpp_demangle::ast::Demangle<alloc::string::String>>::demangle
Unexecuted instantiation: <cpp_demangle::ast::BaseUnresolvedName as cpp_demangle::ast::Demangle<_>>::demangle
6545
}
6546
6547
/// The `<destructor-name>` production.
6548
///
6549
/// ```text
6550
/// <destructor-name> ::= <unresolved-type> # e.g., ~T or ~decltype(f())
6551
///                   ::= <simple-id>       # e.g., ~A<2*N>
6552
/// ```
6553
0
#[derive(Clone, Debug, PartialEq, Eq)]
6554
pub enum DestructorName {
6555
    /// A destructor for an unresolved type.
6556
    Unresolved(UnresolvedTypeHandle),
6557
6558
    /// A destructor for a resolved type name.
6559
    Name(SimpleId),
6560
}
6561
6562
impl Parse for DestructorName {
6563
0
    fn parse<'a, 'b>(
6564
0
        ctx: &'a ParseContext,
6565
0
        subs: &'a mut SubstitutionTable,
6566
0
        input: IndexStr<'b>,
6567
0
    ) -> Result<(DestructorName, IndexStr<'b>)> {
6568
0
        try_begin_parse!("DestructorName", ctx, input);
6569
6570
0
        if let Ok((ty, tail)) = UnresolvedTypeHandle::parse(ctx, subs, input) {
6571
0
            return Ok((DestructorName::Unresolved(ty), tail));
6572
0
        }
6573
6574
0
        let (name, tail) = SimpleId::parse(ctx, subs, input)?;
6575
0
        Ok((DestructorName::Name(name), tail))
6576
0
    }
6577
}
6578
6579
impl<'subs, W> Demangle<'subs, W> for DestructorName
6580
where
6581
    W: 'subs + DemangleWrite,
6582
{
6583
0
    fn demangle<'prev, 'ctx>(
6584
0
        &'subs self,
6585
0
        ctx: &'ctx mut DemangleContext<'subs, W>,
6586
0
        scope: Option<ArgScopeStack<'prev, 'subs>>,
6587
0
    ) -> fmt::Result {
6588
0
        let ctx = try_begin_demangle!(self, ctx, scope);
6589
6590
0
        write!(ctx, "~")?;
6591
0
        match *self {
6592
0
            DestructorName::Unresolved(ref ty) => ty.demangle(ctx, scope),
6593
0
            DestructorName::Name(ref name) => name.demangle(ctx, scope),
6594
        }
6595
0
    }
Unexecuted instantiation: <cpp_demangle::ast::DestructorName as cpp_demangle::ast::Demangle<alloc::string::String>>::demangle
Unexecuted instantiation: <cpp_demangle::ast::DestructorName as cpp_demangle::ast::Demangle<_>>::demangle
6596
}
6597
6598
/// The `<expr-primary>` production.
6599
///
6600
/// ```text
6601
/// <expr-primary> ::= L <type> <value number> E                        # integer literal
6602
///                ::= L <type> <value float> E                         # floating literal
6603
///                ::= L <string type> E                                # string literal
6604
///                ::= L <nullptr type> E                               # nullptr literal (i.e., "LDnE")
6605
///                ::= L <pointer type> 0 E                             # null pointer template argument
6606
///                ::= L <type> <real-part float> _ <imag-part float> E # complex floating point literal (C 2000)
6607
///                ::= L <mangled-name> E                               # external name
6608
/// ```
6609
0
#[derive(Clone, Debug, PartialEq, Eq)]
6610
pub enum ExprPrimary {
6611
    /// A type literal.
6612
    Literal(TypeHandle, usize, usize),
6613
6614
    /// An external name.
6615
    External(MangledName),
6616
}
6617
6618
impl Parse for ExprPrimary {
6619
0
    fn parse<'a, 'b>(
6620
0
        ctx: &'a ParseContext,
6621
0
        subs: &'a mut SubstitutionTable,
6622
0
        input: IndexStr<'b>,
6623
0
    ) -> Result<(ExprPrimary, IndexStr<'b>)> {
6624
0
        try_begin_parse!("ExprPrimary", ctx, input);
6625
6626
0
        let tail = consume(b"L", input)?;
6627
6628
0
        if let Ok((ty, tail)) = TypeHandle::parse(ctx, subs, tail) {
6629
0
            let start = tail.index();
6630
0
            let num_bytes_in_literal = tail.as_ref().iter().take_while(|&&c| c != b'E').count();
6631
0
            let tail = tail.range_from(num_bytes_in_literal..);
6632
0
            let end = tail.index();
6633
0
            let tail = consume(b"E", tail)?;
6634
0
            let expr = ExprPrimary::Literal(ty, start, end);
6635
0
            return Ok((expr, tail));
6636
0
        }
6637
6638
0
        let (name, tail) = MangledName::parse(ctx, subs, tail)?;
6639
0
        let tail = consume(b"E", tail)?;
6640
0
        let expr = ExprPrimary::External(name);
6641
0
        Ok((expr, tail))
6642
0
    }
6643
}
6644
6645
impl<'subs, W> Demangle<'subs, W> for ExprPrimary
6646
where
6647
    W: 'subs + DemangleWrite,
6648
{
6649
0
    fn demangle<'prev, 'ctx>(
6650
0
        &'subs self,
6651
0
        ctx: &'ctx mut DemangleContext<'subs, W>,
6652
0
        scope: Option<ArgScopeStack<'prev, 'subs>>,
6653
0
    ) -> fmt::Result {
6654
0
        let ctx = try_begin_demangle!(self, ctx, scope);
6655
6656
0
        fn write_literal<W>(ctx: &mut DemangleContext<W>, start: usize, end: usize) -> fmt::Result
6657
0
        where
6658
0
            W: DemangleWrite,
6659
0
        {
6660
0
            debug_assert!(start <= end);
6661
0
            let start = if start < end && ctx.input[start] == b'n' {
6662
0
                write!(ctx, "-")?;
6663
0
                start + 1
6664
            } else {
6665
0
                start
6666
            };
6667
0
            let s = ::std::str::from_utf8(&ctx.input[start..end]).map_err(|e| {
6668
0
                log!("Error writing literal: {}", e);
6669
0
                fmt::Error
6670
0
            })?;
Unexecuted instantiation: <cpp_demangle::ast::ExprPrimary as cpp_demangle::ast::Demangle<_>>::demangle::write_literal::<alloc::string::String>::{closure#0}
Unexecuted instantiation: <cpp_demangle::ast::ExprPrimary as cpp_demangle::ast::Demangle<_>>::demangle::write_literal::<_>::{closure#0}
6671
0
            ctx.write_str(s)
6672
0
        }
Unexecuted instantiation: <cpp_demangle::ast::ExprPrimary as cpp_demangle::ast::Demangle<_>>::demangle::write_literal::<alloc::string::String>
Unexecuted instantiation: <cpp_demangle::ast::ExprPrimary as cpp_demangle::ast::Demangle<_>>::demangle::write_literal::<_>
6673
6674
0
        match *self {
6675
0
            ExprPrimary::External(ref name) => {
6676
0
                let saved_show_params = ctx.show_params;
6677
0
                ctx.show_params = true;
6678
0
                let ret = name.demangle(ctx, scope);
6679
0
                ctx.show_params = saved_show_params;
6680
0
                ret
6681
            }
6682
            ExprPrimary::Literal(
6683
                TypeHandle::Builtin(BuiltinType::Standard(StandardBuiltinType::Bool)),
6684
0
                start,
6685
0
                end,
6686
0
            ) => match &ctx.input[start..end] {
6687
0
                b"0" => write!(ctx, "false"),
6688
0
                b"1" => write!(ctx, "true"),
6689
                _ => {
6690
0
                    write!(ctx, "(bool)")?;
6691
0
                    write_literal(ctx, start, end)
6692
                }
6693
            },
6694
            ExprPrimary::Literal(
6695
                TypeHandle::Builtin(BuiltinType::Standard(StandardBuiltinType::Nullptr)),
6696
                _,
6697
                _,
6698
0
            ) => write!(ctx, "nullptr"),
6699
            ExprPrimary::Literal(
6700
0
                ref ty @ TypeHandle::Builtin(BuiltinType::Standard(StandardBuiltinType::Double)),
6701
0
                start,
6702
0
                end,
6703
            )
6704
            | ExprPrimary::Literal(
6705
0
                ref ty @ TypeHandle::Builtin(BuiltinType::Standard(StandardBuiltinType::Float)),
6706
0
                start,
6707
0
                end,
6708
            ) => {
6709
0
                if ctx.show_expression_literal_types {
6710
0
                    write!(ctx, "(")?;
6711
0
                    ty.demangle(ctx, scope)?;
6712
0
                    write!(ctx, ")")?;
6713
0
                }
6714
0
                let start = if start < end && ctx.input[start] == b'n' {
6715
0
                    write!(ctx, "-[")?;
6716
0
                    start + 1
6717
                } else {
6718
0
                    write!(ctx, "[")?;
6719
0
                    start
6720
                };
6721
0
                let s = ::std::str::from_utf8(&ctx.input[start..end]).map_err(|e| {
6722
0
                    log!("Error writing literal: {}", e);
6723
0
                    fmt::Error
6724
0
                })?;
Unexecuted instantiation: <cpp_demangle::ast::ExprPrimary as cpp_demangle::ast::Demangle<alloc::string::String>>::demangle::{closure#0}
Unexecuted instantiation: <cpp_demangle::ast::ExprPrimary as cpp_demangle::ast::Demangle<_>>::demangle::{closure#0}
6725
0
                ctx.write_str(s)?;
6726
0
                write!(ctx, "]")
6727
            }
6728
            ExprPrimary::Literal(
6729
                TypeHandle::Builtin(BuiltinType::Standard(StandardBuiltinType::Int)),
6730
0
                start,
6731
0
                end,
6732
0
            ) => write_literal(ctx, start, end),
6733
0
            ExprPrimary::Literal(ref ty, start, end) => {
6734
0
                if ctx.show_expression_literal_types {
6735
0
                    write!(ctx, "(")?;
6736
0
                    ty.demangle(ctx, scope)?;
6737
0
                    write!(ctx, ")")?;
6738
0
                }
6739
0
                write_literal(ctx, start, end)
6740
            }
6741
        }
6742
0
    }
Unexecuted instantiation: <cpp_demangle::ast::ExprPrimary as cpp_demangle::ast::Demangle<alloc::string::String>>::demangle
Unexecuted instantiation: <cpp_demangle::ast::ExprPrimary as cpp_demangle::ast::Demangle<_>>::demangle
6743
}
6744
6745
/// The `<initializer>` production.
6746
///
6747
/// ```text
6748
/// <initializer> ::= pi <expression>* E # parenthesized initialization
6749
/// ```
6750
0
#[derive(Clone, Debug, PartialEq, Eq)]
6751
pub struct Initializer(Vec<Expression>);
6752
6753
impl Parse for Initializer {
6754
0
    fn parse<'a, 'b>(
6755
0
        ctx: &'a ParseContext,
6756
0
        subs: &'a mut SubstitutionTable,
6757
0
        input: IndexStr<'b>,
6758
0
    ) -> Result<(Initializer, IndexStr<'b>)> {
6759
0
        try_begin_parse!("Initializer", ctx, input);
6760
6761
0
        let tail = consume(b"pi", input)?;
6762
0
        let (exprs, tail) = zero_or_more::<Expression>(ctx, subs, tail)?;
6763
0
        let tail = consume(b"E", tail)?;
6764
0
        Ok((Initializer(exprs), tail))
6765
0
    }
6766
}
6767
6768
impl<'subs, W> Demangle<'subs, W> for Initializer
6769
where
6770
    W: 'subs + DemangleWrite,
6771
{
6772
0
    fn demangle<'prev, 'ctx>(
6773
0
        &'subs self,
6774
0
        ctx: &'ctx mut DemangleContext<'subs, W>,
6775
0
        scope: Option<ArgScopeStack<'prev, 'subs>>,
6776
0
    ) -> fmt::Result {
6777
0
        let ctx = try_begin_demangle!(self, ctx, scope);
6778
6779
0
        write!(ctx, "(")?;
6780
0
        let mut need_comma = false;
6781
0
        for expr in &self.0 {
6782
0
            if need_comma {
6783
0
                write!(ctx, ", ")?;
6784
0
            }
6785
0
            expr.demangle(ctx, scope)?;
6786
0
            need_comma = true;
6787
        }
6788
0
        write!(ctx, ")")?;
6789
0
        Ok(())
6790
0
    }
Unexecuted instantiation: <cpp_demangle::ast::Initializer as cpp_demangle::ast::Demangle<alloc::string::String>>::demangle
Unexecuted instantiation: <cpp_demangle::ast::Initializer as cpp_demangle::ast::Demangle<_>>::demangle
6791
}
6792
6793
/// The `<local-name>` production.
6794
///
6795
/// ```text
6796
/// <local-name> := Z <function encoding> E <entity name> [<discriminator>]
6797
///              := Z <function encoding> E s [<discriminator>]
6798
///              := Z <function encoding> Ed [ <parameter number> ] _ <entity name>
6799
/// ```
6800
0
#[derive(Clone, Debug, PartialEq, Eq)]
6801
pub enum LocalName {
6802
    /// The mangling of the enclosing function, the mangling of the entity
6803
    /// relative to the function, and an optional discriminator.
6804
    Relative(Box<Encoding>, Option<Box<Name>>, Option<Discriminator>),
6805
6806
    /// A default argument in a class definition.
6807
    Default(Box<Encoding>, Option<usize>, Box<Name>),
6808
}
6809
6810
impl Parse for LocalName {
6811
1.65M
    fn parse<'a, 'b>(
6812
1.65M
        ctx: &'a ParseContext,
6813
1.65M
        subs: &'a mut SubstitutionTable,
6814
1.65M
        input: IndexStr<'b>,
6815
1.65M
    ) -> Result<(LocalName, IndexStr<'b>)> {
6816
1.65M
        try_begin_parse!("LocalName", ctx, input);
6817
6818
1.65M
        let tail = consume(b"Z", input)?;
6819
0
        let (encoding, tail) = Encoding::parse(ctx, subs, tail)?;
6820
0
        let tail = consume(b"E", tail)?;
6821
6822
0
        if let Ok(tail) = consume(b"s", tail) {
6823
0
            let (disc, tail) = if let Ok((disc, tail)) = Discriminator::parse(ctx, subs, tail) {
6824
0
                (Some(disc), tail)
6825
            } else {
6826
0
                (None, tail)
6827
            };
6828
0
            return Ok((LocalName::Relative(Box::new(encoding), None, disc), tail));
6829
0
        }
6830
6831
0
        if let Ok(tail) = consume(b"d", tail) {
6832
0
            let (param, tail) = if let Ok((num, tail)) = Number::parse(ctx, subs, tail) {
6833
0
                (Some(num as _), tail)
6834
            } else {
6835
0
                (None, tail)
6836
            };
6837
0
            let tail = consume(b"_", tail)?;
6838
0
            let (name, tail) = Name::parse(ctx, subs, tail)?;
6839
0
            return Ok((
6840
0
                LocalName::Default(Box::new(encoding), param, Box::new(name)),
6841
0
                tail,
6842
0
            ));
6843
0
        }
6844
6845
0
        let (name, tail) = Name::parse(ctx, subs, tail)?;
6846
0
        let (disc, tail) = if let Ok((disc, tail)) = Discriminator::parse(ctx, subs, tail) {
6847
0
            (Some(disc), tail)
6848
        } else {
6849
0
            (None, tail)
6850
        };
6851
6852
0
        Ok((
6853
0
            LocalName::Relative(Box::new(encoding), Some(Box::new(name)), disc),
6854
0
            tail,
6855
0
        ))
6856
1.65M
    }
6857
}
6858
6859
impl<'subs, W> Demangle<'subs, W> for LocalName
6860
where
6861
    W: 'subs + DemangleWrite,
6862
{
6863
0
    fn demangle<'prev, 'ctx>(
6864
0
        &'subs self,
6865
0
        ctx: &'ctx mut DemangleContext<'subs, W>,
6866
0
        scope: Option<ArgScopeStack<'prev, 'subs>>,
6867
0
    ) -> fmt::Result {
6868
0
        let ctx = try_begin_demangle!(self, ctx, scope);
6869
6870
0
        let saved_show_params = ctx.show_params;
6871
0
        ctx.show_params = true;
6872
0
        let ret = match *self {
6873
0
            LocalName::Relative(ref encoding, Some(ref name), _) => {
6874
0
                encoding.demangle(ctx, scope)?;
6875
0
                write!(ctx, "::")?;
6876
0
                name.demangle(ctx, scope)
6877
            }
6878
0
            LocalName::Relative(ref encoding, None, _) => {
6879
0
                // No name means that this is the symbol for a string literal.
6880
0
                encoding.demangle(ctx, scope)?;
6881
0
                write!(ctx, "::string literal")?;
6882
0
                Ok(())
6883
            }
6884
0
            LocalName::Default(ref encoding, _, _) => encoding.demangle(ctx, scope),
6885
        };
6886
0
        ctx.show_params = saved_show_params;
6887
0
        ret
6888
0
    }
Unexecuted instantiation: <cpp_demangle::ast::LocalName as cpp_demangle::ast::Demangle<alloc::string::String>>::demangle
Unexecuted instantiation: <cpp_demangle::ast::LocalName as cpp_demangle::ast::Demangle<_>>::demangle
6889
}
6890
6891
impl GetTemplateArgs for LocalName {
6892
    fn get_template_args<'a>(&'a self, subs: &'a SubstitutionTable) -> Option<&'a TemplateArgs> {
6893
0
        match *self {
6894
0
            LocalName::Relative(_, None, _) => None,
6895
0
            LocalName::Relative(_, Some(ref name), _) | LocalName::Default(_, _, ref name) => {
6896
0
                name.get_template_args(subs)
6897
            }
6898
        }
6899
0
    }
6900
}
6901
6902
impl<'a> GetLeafName<'a> for LocalName {
6903
    fn get_leaf_name(&'a self, subs: &'a SubstitutionTable) -> Option<LeafName<'a>> {
6904
0
        match *self {
6905
0
            LocalName::Relative(_, None, _) => None,
6906
0
            LocalName::Relative(_, Some(ref name), _) | LocalName::Default(_, _, ref name) => {
6907
0
                name.get_leaf_name(subs)
6908
            }
6909
        }
6910
0
    }
6911
}
6912
6913
/// The `<discriminator>` production.
6914
///
6915
/// ```text
6916
/// <discriminator> := _ <non-negative number>      # when number < 10
6917
///                 := __ <non-negative number> _   # when number >= 10
6918
/// ```
6919
0
#[derive(Clone, Debug, PartialEq, Eq)]
6920
pub struct Discriminator(usize);
6921
6922
impl Parse for Discriminator {
6923
0
    fn parse<'a, 'b>(
6924
0
        ctx: &'a ParseContext,
6925
0
        _subs: &'a mut SubstitutionTable,
6926
0
        input: IndexStr<'b>,
6927
0
    ) -> Result<(Discriminator, IndexStr<'b>)> {
6928
0
        try_begin_parse!("Discriminator", ctx, input);
6929
6930
0
        let tail = consume(b"_", input)?;
6931
6932
0
        if let Ok(tail) = consume(b"_", tail) {
6933
0
            let (num, tail) = parse_number(10, false, tail)?;
6934
0
            debug_assert!(num >= 0);
6935
0
            if num < 10 {
6936
0
                return Err(error::Error::UnexpectedText);
6937
0
            }
6938
0
            let tail = consume(b"_", tail)?;
6939
0
            return Ok((Discriminator(num as _), tail));
6940
0
        }
6941
0
6942
0
        match tail.try_split_at(1) {
6943
0
            None => Err(error::Error::UnexpectedEnd),
6944
0
            Some((head, tail)) => match head.as_ref()[0] {
6945
0
                b'0' => Ok((Discriminator(0), tail)),
6946
0
                b'1' => Ok((Discriminator(1), tail)),
6947
0
                b'2' => Ok((Discriminator(2), tail)),
6948
0
                b'3' => Ok((Discriminator(3), tail)),
6949
0
                b'4' => Ok((Discriminator(4), tail)),
6950
0
                b'5' => Ok((Discriminator(5), tail)),
6951
0
                b'6' => Ok((Discriminator(6), tail)),
6952
0
                b'7' => Ok((Discriminator(7), tail)),
6953
0
                b'8' => Ok((Discriminator(8), tail)),
6954
0
                b'9' => Ok((Discriminator(9), tail)),
6955
0
                _ => Err(error::Error::UnexpectedText),
6956
            },
6957
        }
6958
0
    }
6959
}
6960
6961
/// The `<closure-type-name>` production.
6962
///
6963
/// ```text
6964
/// <closure-type-name> ::= Ul <lambda-sig> E [ <nonnegative number> ] _
6965
/// ```
6966
0
#[derive(Clone, Debug, PartialEq, Eq)]
6967
pub struct ClosureTypeName(LambdaSig, Option<usize>);
6968
6969
impl Parse for ClosureTypeName {
6970
3.31M
    fn parse<'a, 'b>(
6971
3.31M
        ctx: &'a ParseContext,
6972
3.31M
        subs: &'a mut SubstitutionTable,
6973
3.31M
        input: IndexStr<'b>,
6974
3.31M
    ) -> Result<(ClosureTypeName, IndexStr<'b>)> {
6975
3.31M
        try_begin_parse!("ClosureTypeName", ctx, input);
6976
6977
3.31M
        let tail = consume(b"Ul", input)?;
6978
0
        let (sig, tail) = LambdaSig::parse(ctx, subs, tail)?;
6979
0
        let tail = consume(b"E", tail)?;
6980
0
        let (num, tail) = if let Ok((num, tail)) = parse_number(10, false, tail) {
6981
0
            (Some(num as _), tail)
6982
        } else {
6983
0
            (None, tail)
6984
        };
6985
0
        let tail = consume(b"_", tail)?;
6986
0
        Ok((ClosureTypeName(sig, num), tail))
6987
3.31M
    }
6988
}
6989
6990
impl<'subs, W> Demangle<'subs, W> for ClosureTypeName
6991
where
6992
    W: 'subs + DemangleWrite,
6993
{
6994
0
    fn demangle<'prev, 'ctx>(
6995
0
        &'subs self,
6996
0
        ctx: &'ctx mut DemangleContext<'subs, W>,
6997
0
        scope: Option<ArgScopeStack<'prev, 'subs>>,
6998
0
    ) -> fmt::Result {
6999
0
        let ctx = try_begin_demangle!(self, ctx, scope);
7000
7001
0
        write!(ctx, "{{lambda(")?;
7002
0
        self.0.demangle(ctx, scope)?;
7003
0
        write!(ctx, ")#{}}}", self.1.map_or(1, |n| n + 2))?;
Unexecuted instantiation: <cpp_demangle::ast::ClosureTypeName as cpp_demangle::ast::Demangle<alloc::string::String>>::demangle::{closure#0}
Unexecuted instantiation: <cpp_demangle::ast::ClosureTypeName as cpp_demangle::ast::Demangle<_>>::demangle::{closure#0}
7004
0
        Ok(())
7005
0
    }
Unexecuted instantiation: <cpp_demangle::ast::ClosureTypeName as cpp_demangle::ast::Demangle<alloc::string::String>>::demangle
Unexecuted instantiation: <cpp_demangle::ast::ClosureTypeName as cpp_demangle::ast::Demangle<_>>::demangle
7006
}
7007
7008
impl<'subs> ArgScope<'subs, 'subs> for ClosureTypeName {
7009
0
    fn leaf_name(&'subs self) -> Result<LeafName<'subs>> {
7010
0
        Ok(LeafName::Closure(self))
7011
0
    }
7012
7013
0
    fn get_template_arg(
7014
0
        &'subs self,
7015
0
        _: usize,
7016
0
    ) -> Result<(&'subs TemplateArg, &'subs TemplateArgs)> {
7017
0
        Err(error::Error::BadTemplateArgReference)
7018
0
    }
7019
7020
0
    fn get_function_arg(&'subs self, _: usize) -> Result<&'subs Type> {
7021
0
        Err(error::Error::BadFunctionArgReference)
7022
0
    }
7023
}
7024
7025
impl<'a> GetLeafName<'a> for ClosureTypeName {
7026
    #[inline]
7027
0
    fn get_leaf_name(&'a self, _: &'a SubstitutionTable) -> Option<LeafName<'a>> {
7028
0
        Some(LeafName::Closure(self))
7029
0
    }
7030
}
7031
7032
impl ClosureTypeName {
7033
    #[inline]
7034
0
    fn starts_with(byte: u8, input: &IndexStr) -> bool {
7035
0
        byte == b'U' && input.peek_second().map(|b| b == b'l').unwrap_or(false)
7036
0
    }
7037
}
7038
7039
/// The `<lambda-sig>` production.
7040
///
7041
/// ```text
7042
/// <lambda-sig> ::= <parameter type>+  # Parameter types or "v" if the lambda has no parameters
7043
/// ```
7044
0
#[derive(Clone, Debug, PartialEq, Eq)]
7045
pub struct LambdaSig(Vec<TypeHandle>);
7046
7047
impl LambdaSig {
7048
0
    fn demangle_args<'subs, 'prev, 'ctx, W>(
7049
0
        &'subs self,
7050
0
        ctx: &'ctx mut DemangleContext<'subs, W>,
7051
0
        scope: Option<ArgScopeStack<'prev, 'subs>>,
7052
0
    ) -> fmt::Result
7053
0
    where
7054
0
        W: 'subs + DemangleWrite,
7055
0
    {
7056
0
        let mut need_comma = false;
7057
0
        for ty in &self.0 {
7058
0
            if need_comma {
7059
0
                write!(ctx, ", ")?;
7060
0
            }
7061
0
            ty.demangle(ctx, scope)?;
7062
0
            need_comma = true;
7063
        }
7064
0
        Ok(())
7065
0
    }
Unexecuted instantiation: <cpp_demangle::ast::LambdaSig>::demangle_args::<alloc::string::String>
Unexecuted instantiation: <cpp_demangle::ast::LambdaSig>::demangle_args::<_>
7066
}
7067
7068
impl Parse for LambdaSig {
7069
0
    fn parse<'a, 'b>(
7070
0
        ctx: &'a ParseContext,
7071
0
        subs: &'a mut SubstitutionTable,
7072
0
        input: IndexStr<'b>,
7073
0
    ) -> Result<(LambdaSig, IndexStr<'b>)> {
7074
0
        try_begin_parse!("LambdaSig", ctx, input);
7075
7076
0
        let (types, tail) = if let Ok(tail) = consume(b"v", input) {
7077
0
            (vec![], tail)
7078
        } else {
7079
0
            one_or_more::<TypeHandle>(ctx, subs, input)?
7080
        };
7081
0
        Ok((LambdaSig(types), tail))
7082
0
    }
7083
}
7084
7085
impl<'subs, W> Demangle<'subs, W> for LambdaSig
7086
where
7087
    W: 'subs + DemangleWrite,
7088
{
7089
0
    fn demangle<'prev, 'ctx>(
7090
0
        &'subs self,
7091
0
        ctx: &'ctx mut DemangleContext<'subs, W>,
7092
0
        scope: Option<ArgScopeStack<'prev, 'subs>>,
7093
0
    ) -> fmt::Result {
7094
0
        let ctx = try_begin_demangle!(self, ctx, scope);
7095
7096
0
        ctx.is_lambda_arg = true;
7097
0
        let r = self.demangle_args(ctx, scope);
7098
0
        ctx.is_lambda_arg = false;
7099
0
        r
7100
0
    }
Unexecuted instantiation: <cpp_demangle::ast::LambdaSig as cpp_demangle::ast::Demangle<alloc::string::String>>::demangle
Unexecuted instantiation: <cpp_demangle::ast::LambdaSig as cpp_demangle::ast::Demangle<_>>::demangle
7101
}
7102
7103
/// The `<data-member-prefix>` production.
7104
///
7105
/// ```text
7106
/// <data-member-prefix> := <member source-name> M
7107
/// ```
7108
0
#[derive(Clone, Debug, PartialEq, Eq)]
7109
pub struct DataMemberPrefix(SourceName);
7110
7111
impl Parse for DataMemberPrefix {
7112
0
    fn parse<'a, 'b>(
7113
0
        ctx: &'a ParseContext,
7114
0
        subs: &'a mut SubstitutionTable,
7115
0
        input: IndexStr<'b>,
7116
0
    ) -> Result<(DataMemberPrefix, IndexStr<'b>)> {
7117
0
        try_begin_parse!("DataMemberPrefix", ctx, input);
7118
7119
0
        let (name, tail) = SourceName::parse(ctx, subs, input)?;
7120
0
        let tail = consume(b"M", tail)?;
7121
0
        Ok((DataMemberPrefix(name), tail))
7122
0
    }
7123
}
7124
7125
impl<'a> GetLeafName<'a> for DataMemberPrefix {
7126
    #[inline]
7127
0
    fn get_leaf_name(&'a self, _: &'a SubstitutionTable) -> Option<LeafName<'a>> {
7128
0
        Some(LeafName::SourceName(&self.0))
7129
0
    }
7130
}
7131
7132
impl DataMemberPrefix {
7133
0
    fn starts_with(byte: u8) -> bool {
7134
0
        SourceName::starts_with(byte)
7135
0
    }
7136
}
7137
7138
impl<'subs, W> Demangle<'subs, W> for DataMemberPrefix
7139
where
7140
    W: 'subs + DemangleWrite,
7141
{
7142
    #[inline]
7143
0
    fn demangle<'prev, 'ctx>(
7144
0
        &'subs self,
7145
0
        ctx: &'ctx mut DemangleContext<'subs, W>,
7146
0
        scope: Option<ArgScopeStack<'prev, 'subs>>,
7147
0
    ) -> fmt::Result {
7148
0
        let ctx = try_begin_demangle!(self, ctx, scope);
7149
7150
0
        ctx.push_demangle_node(DemangleNodeType::DataMemberPrefix);
7151
0
        let ret = self.0.demangle(ctx, scope);
7152
0
        ctx.pop_demangle_node();
7153
0
        ret
7154
0
    }
Unexecuted instantiation: <cpp_demangle::ast::DataMemberPrefix as cpp_demangle::ast::Demangle<alloc::string::String>>::demangle
Unexecuted instantiation: <cpp_demangle::ast::DataMemberPrefix as cpp_demangle::ast::Demangle<_>>::demangle
7155
}
7156
7157
/// The `<substitution>` form: a back-reference to some component we've already
7158
/// parsed.
7159
///
7160
/// ```text
7161
/// <substitution> ::= S <seq-id> _
7162
///                ::= S_
7163
///                ::= St # ::std::
7164
///                ::= Sa # ::std::allocator
7165
///                ::= Sb # ::std::basic_string
7166
///                ::= Ss # ::std::basic_string < char,
7167
///                                               ::std::char_traits<char>,
7168
///                                               ::std::allocator<char> >
7169
///                ::= Si # ::std::basic_istream<char,  std::char_traits<char> >
7170
///                ::= So # ::std::basic_ostream<char,  std::char_traits<char> >
7171
///                ::= Sd # ::std::basic_iostream<char, std::char_traits<char> >
7172
/// ```
7173
0
#[derive(Clone, Debug, PartialEq, Eq)]
7174
pub enum Substitution {
7175
    /// A reference to an entity that already occurred, ie the `S_` and `S
7176
    /// <seq-id> _` forms.
7177
    BackReference(usize),
7178
7179
    /// A well-known substitution component. These are the components that do
7180
    /// not appear in the substitution table, but have abbreviations specified
7181
    /// directly in the grammar.
7182
    WellKnown(WellKnownComponent),
7183
}
7184
7185
impl Parse for Substitution {
7186
4.97M
    fn parse<'a, 'b>(
7187
4.97M
        ctx: &'a ParseContext,
7188
4.97M
        subs: &'a mut SubstitutionTable,
7189
4.97M
        input: IndexStr<'b>,
7190
4.97M
    ) -> Result<(Substitution, IndexStr<'b>)> {
7191
4.97M
        try_begin_parse!("Substitution", ctx, input);
7192
7193
4.97M
        if let Ok((well_known, tail)) = WellKnownComponent::parse(ctx, subs, input) {
7194
0
            return Ok((Substitution::WellKnown(well_known), tail));
7195
4.97M
        }
7196
7197
4.97M
        let tail = consume(b"S", input)?;
7198
0
        let (idx, tail) = if let Ok((idx, tail)) = SeqId::parse(ctx, subs, tail) {
7199
0
            (idx.0 + 1, tail)
7200
        } else {
7201
0
            (0, tail)
7202
        };
7203
7204
0
        if !subs.contains(idx) {
7205
0
            return Err(error::Error::BadBackReference);
7206
0
        }
7207
7208
0
        let tail = consume(b"_", tail)?;
7209
0
        log!("Found a reference to @ {}", idx);
7210
0
        Ok((Substitution::BackReference(idx), tail))
7211
4.97M
    }
7212
}
7213
7214
define_vocabulary! {
7215
/// The `<substitution>` variants that are encoded directly in the grammar,
7216
/// rather than as back references to other components in the substitution
7217
/// table.
7218
0
    #[derive(Clone, Debug, PartialEq, Eq)]
7219
    pub enum WellKnownComponent {
7220
        Std          (b"St", "std"),
7221
        StdAllocator (b"Sa", "std::allocator"),
7222
        StdString1   (b"Sb", "std::basic_string"),
7223
        StdString2   (b"Ss", "std::string"),
7224
        StdIstream   (b"Si", "std::basic_istream<char, std::char_traits<char> >"),
7225
        StdOstream   (b"So", "std::ostream"),
7226
        StdIostream  (b"Sd", "std::basic_iostream<char, std::char_traits<char> >")
7227
    }
7228
}
7229
7230
impl<'a> GetLeafName<'a> for WellKnownComponent {
7231
0
    fn get_leaf_name(&'a self, _: &'a SubstitutionTable) -> Option<LeafName<'a>> {
7232
0
        match *self {
7233
0
            WellKnownComponent::Std => None,
7234
0
            _ => Some(LeafName::WellKnownComponent(self)),
7235
        }
7236
0
    }
7237
}
7238
7239
impl<'a> ArgScope<'a, 'a> for WellKnownComponent {
7240
0
    fn leaf_name(&'a self) -> Result<LeafName<'a>> {
7241
0
        Ok(LeafName::WellKnownComponent(self))
7242
0
    }
7243
7244
0
    fn get_template_arg(&'a self, _: usize) -> Result<(&'a TemplateArg, &'a TemplateArgs)> {
7245
0
        Err(error::Error::BadTemplateArgReference)
7246
0
    }
7247
7248
0
    fn get_function_arg(&'a self, _: usize) -> Result<&'a Type> {
7249
0
        Err(error::Error::BadFunctionArgReference)
7250
0
    }
7251
}
7252
7253
impl<'subs, W> DemangleAsLeaf<'subs, W> for WellKnownComponent
7254
where
7255
    W: 'subs + DemangleWrite,
7256
{
7257
0
    fn demangle_as_leaf<'me, 'ctx>(
7258
0
        &'me self,
7259
0
        ctx: &'ctx mut DemangleContext<'subs, W>,
7260
0
    ) -> fmt::Result {
7261
0
        match *self {
7262
            WellKnownComponent::Std => {
7263
0
                panic!("should never treat `WellKnownComponent::Std` as a leaf name")
7264
            }
7265
0
            WellKnownComponent::StdAllocator => write!(ctx, "allocator"),
7266
0
            WellKnownComponent::StdString1 => write!(ctx, "basic_string"),
7267
0
            WellKnownComponent::StdString2 => write!(ctx, "string"),
7268
0
            WellKnownComponent::StdIstream => write!(ctx, "basic_istream"),
7269
0
            WellKnownComponent::StdOstream => write!(ctx, "ostream"),
7270
0
            WellKnownComponent::StdIostream => write!(ctx, "basic_iostream"),
7271
        }
7272
0
    }
Unexecuted instantiation: <cpp_demangle::ast::WellKnownComponent as cpp_demangle::ast::DemangleAsLeaf<alloc::string::String>>::demangle_as_leaf
Unexecuted instantiation: <cpp_demangle::ast::WellKnownComponent as cpp_demangle::ast::DemangleAsLeaf<_>>::demangle_as_leaf
7273
}
7274
7275
/// The `<special-name>` production.
7276
///
7277
/// The `<special-name>` production is spread in pieces through out the ABI
7278
/// spec, and then there are a bunch of `g++` extensions that have become de
7279
/// facto.
7280
///
7281
/// ### 5.1.4.1 Virtual Tables and RTTI
7282
///
7283
/// ```text
7284
/// <special-name> ::= TV <type>    # virtual table
7285
///                ::= TT <type>    # VTT structure (construction vtable index)
7286
///                ::= TI <type>    # typeinfo structure
7287
///                ::= TS <type>    # typeinfo name (null-terminated byte string)
7288
/// ```
7289
///
7290
/// ### 5.1.4.2 Virtual Override Thunks
7291
///
7292
/// ```text
7293
/// <special-name> ::= T <call-offset> <base encoding>
7294
///     # base is the nominal target function of thunk
7295
///
7296
/// <special-name> ::= Tc <call-offset> <call-offset> <base encoding>
7297
///     # base is the nominal target function of thunk
7298
///     # first call-offset is 'this' adjustment
7299
///     # second call-offset is result adjustment
7300
/// ```
7301
///
7302
/// ### 5.1.4.4 Guard Variables
7303
///
7304
/// ```text
7305
/// <special-name> ::= GV <object name> # Guard variable for one-time initialization
7306
///     # No <type>
7307
/// ```
7308
///
7309
/// ### 5.1.4.5 Lifetime-Extended Temporaries
7310
///
7311
/// ```text
7312
/// <special-name> ::= GR <object name> _             # First temporary
7313
/// <special-name> ::= GR <object name> <seq-id> _    # Subsequent temporaries
7314
/// ```
7315
///
7316
/// ### De Facto Standard Extensions
7317
///
7318
/// ```text
7319
/// <special-name> ::= TC <type> <number> _ <type>    # construction vtable
7320
///                ::= TF <type>                      # typinfo function
7321
///                ::= TH <name>                      # TLS initialization function
7322
///                ::= TW <name>                      # TLS wrapper function
7323
///                ::= Gr <resource name>             # Java Resource
7324
///                ::= GTt <encoding>                 # Transaction-Safe function
7325
///                ::= GTn <encoding>                 # Non-Transaction-Safe function
7326
/// ```
7327
0
#[derive(Clone, Debug, PartialEq, Eq)]
7328
pub enum SpecialName {
7329
    /// A virtual table.
7330
    VirtualTable(TypeHandle),
7331
7332
    /// A VTT structure (construction vtable index).
7333
    Vtt(TypeHandle),
7334
7335
    /// A typeinfo structure.
7336
    Typeinfo(TypeHandle),
7337
7338
    /// A typeinfo name (null-terminated byte string).
7339
    TypeinfoName(TypeHandle),
7340
7341
    /// A virtual override thunk.
7342
    VirtualOverrideThunk(CallOffset, Box<Encoding>),
7343
7344
    /// A virtual override thunk with a covariant return type.
7345
    VirtualOverrideThunkCovariant(CallOffset, CallOffset, Box<Encoding>),
7346
7347
    /// An initialization guard for some static storage.
7348
    Guard(Name),
7349
7350
    /// A temporary used in the initialization of a static storage and promoted
7351
    /// to a static lifetime.
7352
    GuardTemporary(Name, usize),
7353
7354
    /// A construction vtable structure.
7355
    ConstructionVtable(TypeHandle, usize, TypeHandle),
7356
7357
    /// A typeinfo function.
7358
    TypeinfoFunction(TypeHandle),
7359
7360
    /// A TLS initialization function.
7361
    TlsInit(Name),
7362
7363
    /// A TLS wrapper function.
7364
    TlsWrapper(Name),
7365
7366
    /// A Java Resource.
7367
    JavaResource(Vec<ResourceName>),
7368
7369
    /// A function declared transaction-safe
7370
    TransactionClone(Box<Encoding>),
7371
7372
    /// A function declared non-transaction-safe
7373
    NonTransactionClone(Box<Encoding>),
7374
}
7375
7376
impl Parse for SpecialName {
7377
0
    fn parse<'a, 'b>(
7378
0
        ctx: &'a ParseContext,
7379
0
        subs: &'a mut SubstitutionTable,
7380
0
        input: IndexStr<'b>,
7381
0
    ) -> Result<(SpecialName, IndexStr<'b>)> {
7382
0
        try_begin_parse!("SpecialName", ctx, input);
7383
7384
0
        let (head, tail) = match input.try_split_at(2) {
7385
0
            None => return Err(error::Error::UnexpectedEnd),
7386
0
            Some((head, tail)) => (head, tail),
7387
0
        };
7388
0
7389
0
        match head.as_ref() {
7390
0
            b"TV" => {
7391
0
                let (ty, tail) = TypeHandle::parse(ctx, subs, tail)?;
7392
0
                Ok((SpecialName::VirtualTable(ty), tail))
7393
            }
7394
            b"TT" => {
7395
0
                let (ty, tail) = TypeHandle::parse(ctx, subs, tail)?;
7396
0
                Ok((SpecialName::Vtt(ty), tail))
7397
            }
7398
            b"TI" => {
7399
0
                let (ty, tail) = TypeHandle::parse(ctx, subs, tail)?;
7400
0
                Ok((SpecialName::Typeinfo(ty), tail))
7401
            }
7402
            b"TS" => {
7403
0
                let (ty, tail) = TypeHandle::parse(ctx, subs, tail)?;
7404
0
                Ok((SpecialName::TypeinfoName(ty), tail))
7405
            }
7406
            b"Tc" => {
7407
0
                let (first, tail) = CallOffset::parse(ctx, subs, tail)?;
7408
0
                let (second, tail) = CallOffset::parse(ctx, subs, tail)?;
7409
0
                let (base, tail) = Encoding::parse(ctx, subs, tail)?;
7410
0
                Ok((
7411
0
                    SpecialName::VirtualOverrideThunkCovariant(first, second, Box::new(base)),
7412
0
                    tail,
7413
0
                ))
7414
            }
7415
            b"Th" | b"Tv" => {
7416
                // The "h"/"v" is part of the `<call-offset>`, so back up to the
7417
                // `input`.
7418
0
                let tail = consume(b"T", input).unwrap();
7419
0
                let (offset, tail) = CallOffset::parse(ctx, subs, tail)?;
7420
0
                let (base, tail) = Encoding::parse(ctx, subs, tail)?;
7421
0
                Ok((
7422
0
                    SpecialName::VirtualOverrideThunk(offset, Box::new(base)),
7423
0
                    tail,
7424
0
                ))
7425
            }
7426
            b"TC" => {
7427
0
                let (ty1, tail) = TypeHandle::parse(ctx, subs, tail)?;
7428
0
                let (n, tail) = parse_number(10, false, tail)?;
7429
0
                let tail = consume(b"_", tail)?;
7430
0
                let (ty2, tail) = TypeHandle::parse(ctx, subs, tail)?;
7431
0
                Ok((SpecialName::ConstructionVtable(ty1, n as usize, ty2), tail))
7432
            }
7433
            b"TF" => {
7434
0
                let (ty, tail) = TypeHandle::parse(ctx, subs, tail)?;
7435
0
                Ok((SpecialName::TypeinfoFunction(ty), tail))
7436
            }
7437
            b"TH" => {
7438
0
                let (name, tail) = Name::parse(ctx, subs, tail)?;
7439
0
                Ok((SpecialName::TlsInit(name), tail))
7440
            }
7441
            b"TW" => {
7442
0
                let (name, tail) = Name::parse(ctx, subs, tail)?;
7443
0
                Ok((SpecialName::TlsWrapper(name), tail))
7444
            }
7445
            b"GV" => {
7446
0
                let (name, tail) = Name::parse(ctx, subs, tail)?;
7447
0
                Ok((SpecialName::Guard(name), tail))
7448
            }
7449
            b"GR" => {
7450
0
                let (name, tail) = Name::parse(ctx, subs, tail)?;
7451
0
                let (idx, tail) = if let Ok(tail) = consume(b"_", tail) {
7452
0
                    (0, tail)
7453
                } else {
7454
0
                    let (idx, tail) = SeqId::parse(ctx, subs, tail)?;
7455
0
                    let tail = consume(b"_", tail)?;
7456
0
                    (idx.0 + 1, tail)
7457
                };
7458
0
                Ok((SpecialName::GuardTemporary(name, idx), tail))
7459
            }
7460
            b"Gr" => {
7461
0
                let (resource_name_len, tail) = parse_number(10, false, tail)?;
7462
0
                if resource_name_len == 0 {
7463
0
                    return Err(error::Error::UnexpectedText);
7464
0
                }
7465
7466
0
                let (head, tail) = match tail.try_split_at(resource_name_len as _) {
7467
0
                    Some((head, tail)) => (head, tail),
7468
0
                    None => return Err(error::Error::UnexpectedEnd),
7469
                };
7470
7471
0
                let head = consume(b"_", head)?;
7472
7473
0
                let (resource_names, empty) = zero_or_more::<ResourceName>(ctx, subs, head)?;
7474
0
                if !empty.is_empty() {
7475
0
                    return Err(error::Error::UnexpectedText);
7476
0
                }
7477
0
7478
0
                Ok((SpecialName::JavaResource(resource_names), tail))
7479
            }
7480
            b"GT" => {
7481
0
                match tail.next_or(error::Error::UnexpectedEnd)? {
7482
0
                    (b'n', tail) => {
7483
0
                        let (base, tail) = Encoding::parse(ctx, subs, tail)?;
7484
0
                        Ok((SpecialName::NonTransactionClone(Box::new(base)), tail))
7485
                    }
7486
                    // Different letters could stand for different types of
7487
                    // transactional cloning, but for now, treat them all the same
7488
0
                    (b't', tail) | (_, tail) => {
7489
0
                        let (base, tail) = Encoding::parse(ctx, subs, tail)?;
7490
0
                        Ok((SpecialName::TransactionClone(Box::new(base)), tail))
7491
                    }
7492
                }
7493
            }
7494
0
            _ => Err(error::Error::UnexpectedText),
7495
        }
7496
0
    }
7497
}
7498
7499
impl<'subs, W> Demangle<'subs, W> for SpecialName
7500
where
7501
    W: 'subs + DemangleWrite,
7502
{
7503
0
    fn demangle<'prev, 'ctx>(
7504
0
        &'subs self,
7505
0
        ctx: &'ctx mut DemangleContext<'subs, W>,
7506
0
        scope: Option<ArgScopeStack<'prev, 'subs>>,
7507
0
    ) -> fmt::Result {
7508
0
        let ctx = try_begin_demangle!(self, ctx, scope);
7509
7510
0
        match *self {
7511
0
            SpecialName::VirtualTable(ref ty) => {
7512
0
                write!(ctx, "{{vtable(")?;
7513
0
                ctx.push_demangle_node(DemangleNodeType::VirtualTable);
7514
0
                ty.demangle(ctx, scope)?;
7515
0
                ctx.pop_demangle_node();
7516
0
                write!(ctx, ")}}")?;
7517
0
                Ok(())
7518
            }
7519
0
            SpecialName::Vtt(ref ty) => {
7520
0
                write!(ctx, "{{vtt(")?;
7521
0
                ty.demangle(ctx, scope)?;
7522
0
                write!(ctx, ")}}")?;
7523
0
                Ok(())
7524
            }
7525
0
            SpecialName::Typeinfo(ref ty) => {
7526
0
                write!(ctx, "typeinfo for ")?;
7527
0
                ty.demangle(ctx, scope)
7528
            }
7529
0
            SpecialName::TypeinfoName(ref ty) => {
7530
0
                write!(ctx, "typeinfo name for ")?;
7531
0
                ty.demangle(ctx, scope)
7532
            }
7533
0
            SpecialName::VirtualOverrideThunk(ref offset, ref encoding) => {
7534
0
                write!(ctx, "{{virtual override thunk(")?;
7535
0
                offset.demangle(ctx, scope)?;
7536
0
                write!(ctx, ", ")?;
7537
0
                encoding.demangle(ctx, scope)?;
7538
0
                write!(ctx, ")}}")?;
7539
0
                Ok(())
7540
            }
7541
            SpecialName::VirtualOverrideThunkCovariant(
7542
0
                ref this_offset,
7543
0
                ref result_offset,
7544
0
                ref encoding,
7545
0
            ) => {
7546
0
                write!(ctx, "{{virtual override thunk(")?;
7547
0
                this_offset.demangle(ctx, scope)?;
7548
0
                write!(ctx, ", ")?;
7549
0
                result_offset.demangle(ctx, scope)?;
7550
0
                write!(ctx, ", ")?;
7551
0
                encoding.demangle(ctx, scope)?;
7552
0
                write!(ctx, ")}}")?;
7553
0
                Ok(())
7554
            }
7555
0
            SpecialName::Guard(ref name) => {
7556
0
                write!(ctx, "guard variable for ")?;
7557
0
                name.demangle(ctx, scope)
7558
            }
7559
0
            SpecialName::GuardTemporary(ref name, n) => {
7560
0
                write!(ctx, "reference temporary #{} for ", n)?;
7561
0
                name.demangle(ctx, scope)
7562
            }
7563
0
            SpecialName::ConstructionVtable(ref ty1, _, ref ty2) => {
7564
0
                write!(ctx, "construction vtable for ")?;
7565
0
                ty1.demangle(ctx, scope)?;
7566
0
                write!(ctx, "-in-")?;
7567
0
                ty2.demangle(ctx, scope)
7568
            }
7569
0
            SpecialName::TypeinfoFunction(ref ty) => {
7570
0
                write!(ctx, "typeinfo fn for ")?;
7571
0
                ty.demangle(ctx, scope)
7572
            }
7573
0
            SpecialName::TlsInit(ref name) => {
7574
0
                write!(ctx, "TLS init function for ")?;
7575
0
                name.demangle(ctx, scope)
7576
            }
7577
0
            SpecialName::TlsWrapper(ref name) => {
7578
0
                write!(ctx, "TLS wrapper function for ")?;
7579
0
                name.demangle(ctx, scope)
7580
            }
7581
0
            SpecialName::TransactionClone(ref encoding) => {
7582
0
                write!(ctx, "transaction clone for ")?;
7583
0
                encoding.demangle(ctx, scope)
7584
            }
7585
0
            SpecialName::NonTransactionClone(ref encoding) => {
7586
0
                write!(ctx, "non-transaction clone for ")?;
7587
0
                encoding.demangle(ctx, scope)
7588
            }
7589
0
            SpecialName::JavaResource(ref names) => {
7590
0
                write!(ctx, "java resource ")?;
7591
0
                for name in names {
7592
0
                    name.demangle(ctx, scope)?;
7593
                }
7594
0
                Ok(())
7595
            }
7596
        }
7597
0
    }
Unexecuted instantiation: <cpp_demangle::ast::SpecialName as cpp_demangle::ast::Demangle<alloc::string::String>>::demangle
Unexecuted instantiation: <cpp_demangle::ast::SpecialName as cpp_demangle::ast::Demangle<_>>::demangle
7598
}
7599
7600
/// The `<resource name>` pseudo-terminal.
7601
0
#[derive(Clone, Debug, PartialEq, Eq)]
7602
pub struct ResourceName {
7603
    start: usize,
7604
    end: usize,
7605
}
7606
7607
impl Parse for ResourceName {
7608
0
    fn parse<'a, 'b>(
7609
0
        ctx: &'a ParseContext,
7610
0
        _subs: &'a mut SubstitutionTable,
7611
0
        input: IndexStr<'b>,
7612
0
    ) -> Result<(ResourceName, IndexStr<'b>)> {
7613
0
        try_begin_parse!("ResourceName", ctx, input);
7614
7615
0
        if input.is_empty() {
7616
0
            return Err(error::Error::UnexpectedEnd);
7617
0
        }
7618
0
7619
0
        let mut end = input
7620
0
            .as_ref()
7621
0
            .iter()
7622
0
            .map(|&c| c as char)
7623
0
            .take_while(|&c| c != '$' || c.is_digit(36))
7624
0
            .count();
7625
0
7626
0
        if end == 0 {
7627
0
            return Err(error::Error::UnexpectedText);
7628
0
        }
7629
0
7630
0
        if input.range_from(end..).peek() == Some(b'$') {
7631
0
            match input.range_from(end..).peek_second() {
7632
0
                Some(b'S') | Some(b'_') | Some(b'$') => end += 2,
7633
0
                _ => return Err(error::Error::UnexpectedText),
7634
            }
7635
0
        }
7636
7637
0
        let tail = input.range_from(end..);
7638
0
7639
0
        let resource_name = ResourceName {
7640
0
            start: input.index(),
7641
0
            end: tail.index(),
7642
0
        };
7643
0
7644
0
        Ok((resource_name, tail))
7645
0
    }
7646
}
7647
7648
impl<'subs, W> Demangle<'subs, W> for ResourceName
7649
where
7650
    W: 'subs + DemangleWrite,
7651
{
7652
    #[inline]
7653
0
    fn demangle<'prev, 'ctx>(
7654
0
        &'subs self,
7655
0
        ctx: &'ctx mut DemangleContext<'subs, W>,
7656
0
        scope: Option<ArgScopeStack<'prev, 'subs>>,
7657
0
    ) -> fmt::Result {
7658
0
        let ctx = try_begin_demangle!(self, ctx, scope);
7659
7660
0
        let mut i = self.start;
7661
0
        while i < self.end {
7662
0
            let ch = ctx.input[i];
7663
0
            if ch == b'$' {
7664
                // Skip past the '$'
7665
0
                i += 1;
7666
0
                match ctx.input[i] {
7667
0
                    b'S' => write!(ctx, "{}", '/')?,
7668
0
                    b'_' => write!(ctx, "{}", '.')?,
7669
0
                    b'$' => write!(ctx, "{}", '$')?,
7670
0
                    _ => {
7671
0
                        // Fall through
7672
0
                    }
7673
                }
7674
            } else {
7675
0
                write!(ctx, "{}", ch as char)?;
7676
            }
7677
0
            i += 1;
7678
        }
7679
7680
0
        Ok(())
7681
0
    }
Unexecuted instantiation: <cpp_demangle::ast::ResourceName as cpp_demangle::ast::Demangle<alloc::string::String>>::demangle
Unexecuted instantiation: <cpp_demangle::ast::ResourceName as cpp_demangle::ast::Demangle<_>>::demangle
7682
}
7683
/// Expect and consume the given byte str, and return the advanced `IndexStr` if
7684
/// we saw the expectation. Otherwise return an error of kind
7685
/// `error::Error::UnexpectedText` if the input doesn't match, or
7686
/// `error::Error::UnexpectedEnd` if it isn't long enough.
7687
#[inline]
7688
fn consume<'a>(expected: &[u8], input: IndexStr<'a>) -> Result<IndexStr<'a>> {
7689
75.5M
    match input.try_split_at(expected.len()) {
7690
74.7M
        Some((head, tail)) if head == expected => Ok(tail),
7691
72.2M
        Some(_) => Err(error::Error::UnexpectedText),
7692
829k
        None => Err(error::Error::UnexpectedEnd),
7693
    }
7694
75.5M
}
7695
7696
0
fn one_or_more<'a, 'b, P>(
7697
0
    ctx: &'a ParseContext,
7698
0
    subs: &'a mut SubstitutionTable,
7699
0
    input: IndexStr<'b>,
7700
0
) -> Result<(Vec<P>, IndexStr<'b>)>
7701
0
where
7702
0
    P: Parse,
7703
0
{
7704
0
    let (first, mut tail) = P::parse(ctx, subs, input)?;
7705
0
    let mut results = vec![first];
7706
    loop {
7707
0
        if let Ok((parsed, tail_tail)) = P::parse(ctx, subs, tail) {
7708
0
            results.push(parsed);
7709
0
            tail = tail_tail;
7710
0
        } else {
7711
0
            return Ok((results, tail));
7712
        }
7713
    }
7714
0
}
Unexecuted instantiation: cpp_demangle::ast::one_or_more::<cpp_demangle::ast::UnresolvedQualifierLevel>
Unexecuted instantiation: cpp_demangle::ast::one_or_more::<cpp_demangle::ast::TemplateArg>
Unexecuted instantiation: cpp_demangle::ast::one_or_more::<cpp_demangle::ast::TypeHandle>
7715
7716
0
fn zero_or_more<'a, 'b, P>(
7717
0
    ctx: &'a ParseContext,
7718
0
    subs: &'a mut SubstitutionTable,
7719
0
    input: IndexStr<'b>,
7720
0
) -> Result<(Vec<P>, IndexStr<'b>)>
7721
0
where
7722
0
    P: Parse,
7723
0
{
7724
0
    let mut tail = input;
7725
0
    let mut results = vec![];
7726
    loop {
7727
0
        if let Ok((parsed, tail_tail)) = P::parse(ctx, subs, tail) {
7728
0
            results.push(parsed);
7729
0
            tail = tail_tail;
7730
0
        } else {
7731
0
            return Ok((results, tail));
7732
0
        }
7733
0
    }
7734
0
}
Unexecuted instantiation: cpp_demangle::ast::zero_or_more::<cpp_demangle::ast::CloneSuffix>
Unexecuted instantiation: cpp_demangle::ast::zero_or_more::<cpp_demangle::ast::Expression>
Unexecuted instantiation: cpp_demangle::ast::zero_or_more::<cpp_demangle::ast::ResourceName>
Unexecuted instantiation: cpp_demangle::ast::zero_or_more::<cpp_demangle::ast::TemplateArg>
7735
7736
/// Parse a number with the given `base`. Do not allow negative numbers
7737
/// (prefixed with an 'n' instead of a '-') if `allow_signed` is false.
7738
#[allow(unsafe_code)]
7739
4.14M
fn parse_number(base: u32, allow_signed: bool, mut input: IndexStr) -> Result<(isize, IndexStr)> {
7740
4.14M
    if input.is_empty() {
7741
0
        return Err(error::Error::UnexpectedEnd);
7742
4.14M
    }
7743
7744
4.14M
    let num_is_negative = if allow_signed && input.as_ref()[0] == b'n' {
7745
0
        input = input.range_from(1..);
7746
0
7747
0
        if input.is_empty() {
7748
0
            return Err(error::Error::UnexpectedEnd);
7749
0
        }
7750
0
7751
0
        true
7752
    } else {
7753
4.14M
        false
7754
    };
7755
7756
4.14M
    let num_numeric = input
7757
4.14M
        .as_ref()
7758
4.14M
        .iter()
7759
4.14M
        .map(|&c| c as char)
7760
4.14M
        .take_while(|c| c.is_digit(base) && (c.is_numeric() || c.is_uppercase()))
7761
4.14M
        .count();
7762
4.14M
    if num_numeric == 0 {
7763
4.14M
        return Err(error::Error::UnexpectedText);
7764
0
    }
7765
0
7766
0
    let (head, tail) = input.split_at(num_numeric);
7767
0
    let head = head.as_ref();
7768
0
7769
0
    if num_numeric > 1 && head[0] == b'0' {
7770
        // "<number>s appearing in mangled names never have leading zeroes,
7771
        // except for the value zero, represented as '0'."
7772
0
        return Err(error::Error::UnexpectedText);
7773
0
    }
7774
0
7775
0
    let head = unsafe {
7776
0
        // Safe because we know we only have valid numeric chars in this
7777
0
        // slice, which are valid UTF-8.
7778
0
        ::std::str::from_utf8_unchecked(head)
7779
    };
7780
7781
0
    let mut number = isize::from_str_radix(head, base).map_err(|_| error::Error::Overflow)?;
7782
0
    if num_is_negative {
7783
0
        number = -number;
7784
0
    }
7785
7786
0
    Ok((number, tail))
7787
4.14M
}
7788
7789
#[cfg(test)]
7790
mod tests {
7791
    use super::{
7792
        ArrayType, BareFunctionType, BaseUnresolvedName, BuiltinType, CallOffset, ClassEnumType,
7793
        ClosureTypeName, CtorDtorName, CvQualifiers, DataMemberPrefix, Decltype, DestructorName,
7794
        Discriminator, Encoding, ExprPrimary, Expression, FunctionParam, FunctionType,
7795
        GlobalCtorDtor, Identifier, Initializer, LambdaSig, LocalName, MangledName, MemberName,
7796
        Name, NestedName, NonSubstitution, Number, NvOffset, OperatorName, Parse, ParseContext,
7797
        PointerToMemberType, Prefix, PrefixHandle, RefQualifier, ResourceName, SeqId, SimpleId,
7798
        SimpleOperatorName, SourceName, SpecialName, StandardBuiltinType, Substitution, TaggedName,
7799
        TemplateArg, TemplateArgs, TemplateParam, TemplateTemplateParam,
7800
        TemplateTemplateParamHandle, Type, TypeHandle, UnnamedTypeName, UnqualifiedName,
7801
        UnresolvedName, UnresolvedQualifierLevel, UnresolvedType, UnresolvedTypeHandle,
7802
        UnscopedName, UnscopedTemplateName, UnscopedTemplateNameHandle, VOffset, VectorType,
7803
        WellKnownComponent,
7804
    };
7805
7806
    use boxed::Box;
7807
    use error::Error;
7808
    use index_str::IndexStr;
7809
    use std::fmt::Debug;
7810
    use std::iter::FromIterator;
7811
    use string::String;
7812
    use subs::{Substitutable, SubstitutionTable};
7813
7814
    fn assert_parse_ok<P, S1, S2, I1, I2>(
7815
        production: &'static str,
7816
        subs: S1,
7817
        input: I1,
7818
        expected: P,
7819
        expected_tail: I2,
7820
        expected_new_subs: S2,
7821
    ) where
7822
        P: Debug + Parse + PartialEq,
7823
        S1: AsRef<[Substitutable]>,
7824
        S2: AsRef<[Substitutable]>,
7825
        I1: AsRef<[u8]>,
7826
        I2: AsRef<[u8]>,
7827
    {
7828
        let ctx = ParseContext::new(Default::default());
7829
        let input = input.as_ref();
7830
        let expected_tail = expected_tail.as_ref();
7831
7832
        let expected_subs = SubstitutionTable::from_iter(
7833
            subs.as_ref()
7834
                .iter()
7835
                .cloned()
7836
                .chain(expected_new_subs.as_ref().iter().cloned()),
7837
        );
7838
        let mut subs = SubstitutionTable::from_iter(subs.as_ref().iter().cloned());
7839
7840
        match P::parse(&ctx, &mut subs, IndexStr::from(input)) {
7841
            Err(error) => panic!(
7842
                "Parsing {:?} as {} failed: {}",
7843
                String::from_utf8_lossy(input),
7844
                production,
7845
                error
7846
            ),
7847
            Ok((value, tail)) => {
7848
                if value != expected {
7849
                    panic!(
7850
                        "Parsing {:?} as {} produced\n\n{:#?}\n\nbut we expected\n\n{:#?}",
7851
                        String::from_utf8_lossy(input),
7852
                        production,
7853
                        value,
7854
                        expected
7855
                    );
7856
                }
7857
                if tail != expected_tail {
7858
                    panic!(
7859
                        "Parsing {:?} as {} left a tail of {:?}, expected {:?}",
7860
                        String::from_utf8_lossy(input),
7861
                        production,
7862
                        tail,
7863
                        String::from_utf8_lossy(expected_tail)
7864
                    );
7865
                }
7866
                if subs[..] != expected_subs[..] {
7867
                    panic!(
7868
                        "Parsing {:?} as {} produced a substitutions table of\n\n\
7869
                         {:#?}\n\n\
7870
                         but we expected\n\n\
7871
                         {:#?}",
7872
                        String::from_utf8_lossy(input),
7873
                        production,
7874
                        subs,
7875
                        expected_subs
7876
                    );
7877
                }
7878
            }
7879
        }
7880
7881
        log!("=== assert_parse_ok PASSED ====================================");
7882
    }
7883
7884
    fn simple_assert_parse_ok<P, I1, I2>(
7885
        production: &'static str,
7886
        input: I1,
7887
        expected: P,
7888
        expected_tail: I2,
7889
    ) where
7890
        P: Debug + Parse + PartialEq,
7891
        I1: AsRef<[u8]>,
7892
        I2: AsRef<[u8]>,
7893
    {
7894
        assert_parse_ok::<P, _, _, _, _>(production, [], input, expected, expected_tail, []);
7895
    }
7896
7897
    fn assert_parse_err<P, S, I>(production: &'static str, subs: S, input: I, expected_error: Error)
7898
    where
7899
        P: Debug + Parse + PartialEq,
7900
        S: AsRef<[Substitutable]>,
7901
        I: AsRef<[u8]>,
7902
    {
7903
        let input = input.as_ref();
7904
        let ctx = ParseContext::new(Default::default());
7905
        let mut subs = SubstitutionTable::from_iter(subs.as_ref().iter().cloned());
7906
7907
        match P::parse(&ctx, &mut subs, IndexStr::from(input)) {
7908
            Err(ref error) if *error == expected_error => {}
7909
            Err(ref error) => {
7910
                panic!(
7911
                    "Parsing {:?} as {} produced an error of kind {:?}, but we expected kind {:?}",
7912
                    String::from_utf8_lossy(input),
7913
                    production,
7914
                    error,
7915
                    expected_error
7916
                );
7917
            }
7918
            Ok((value, tail)) => {
7919
                panic!(
7920
                    "Parsing {:?} as {} produced value\
7921
                     \n\n\
7922
                     {:#?}\
7923
                     \n\n\
7924
                     and tail {:?}, but we expected error kind {:?}",
7925
                    String::from_utf8_lossy(input),
7926
                    production,
7927
                    value,
7928
                    tail,
7929
                    expected_error
7930
                );
7931
            }
7932
        }
7933
7934
        log!("=== assert_parse_err PASSED ===================================");
7935
    }
7936
7937
    fn simple_assert_parse_err<P, I>(production: &'static str, input: I, expected_error: Error)
7938
    where
7939
        P: Debug + Parse + PartialEq,
7940
        I: AsRef<[u8]>,
7941
    {
7942
        assert_parse_err::<P, _, _>(production, [], input, expected_error);
7943
    }
7944
7945
    #[test]
7946
    fn recursion_limit() {
7947
        // Build the mangled symbol for the type `*****char` where the "*****"
7948
        // is 10,000 pointer indirections. This is a valid type symbol, but
7949
        // something that would cause us to blow the stack.
7950
        let mut mangled = String::new();
7951
        for _ in 0..10_000 {
7952
            mangled.push('P');
7953
        }
7954
        mangled += "c";
7955
7956
        simple_assert_parse_err::<TypeHandle, _>("TypeHandle", mangled, Error::TooMuchRecursion);
7957
    }
7958
7959
    macro_rules! assert_parse {
7960
        ( $production:ident {
7961
            $( with subs $subs:expr => {
7962
                Ok => {
7963
                    $( $input:expr => {
7964
                        $expected:expr ,
7965
                        $expected_tail:expr ,
7966
                        $expected_new_subs:expr
7967
                    } )*
7968
                }
7969
                Err => {
7970
                    $( $error_input:expr => $error:expr , )*
7971
                }
7972
            } )*
7973
        } ) => {
7974
            $( $(
7975
                assert_parse_ok::<$production, _, _, _, _>(stringify!($production),
7976
                                                           $subs,
7977
                                                           $input,
7978
                                                           $expected,
7979
                                                           $expected_tail,
7980
                                                           $expected_new_subs);
7981
            )* )*
7982
7983
            $( $(
7984
                assert_parse_err::<$production, _, _>(stringify!($production),
7985
                                                      $subs,
7986
                                                      $error_input,
7987
                                                      $error);
7988
            )* )*
7989
        };
7990
7991
        ( $production:ident {
7992
            Ok => {
7993
                $( $input:expr => {
7994
                    $expected:expr ,
7995
                    $expected_tail:expr
7996
                } )*
7997
            }
7998
            Err => {
7999
                $( $error_input:expr => $error:expr , )*
8000
            }
8001
        } ) => {
8002
            $(
8003
                simple_assert_parse_ok::<$production, _, _>(stringify!($production),
8004
                                                            $input,
8005
                                                            $expected,
8006
                                                            $expected_tail);
8007
            )*
8008
8009
8010
            $(
8011
                simple_assert_parse_err::<$production, _>(stringify!($production),
8012
                                                          $error_input,
8013
                                                          $error);
8014
            )*
8015
        };
8016
    }
8017
8018
    #[test]
8019
    fn parse_mangled_name() {
8020
        assert_parse!(MangledName {
8021
            Ok => {
8022
                b"_Z3foo..." => {
8023
                    MangledName::Encoding(
8024
                        Encoding::Data(
8025
                            Name::Unscoped(
8026
                                UnscopedName::Unqualified(
8027
                                    UnqualifiedName::Source(
8028
                                        SourceName(Identifier {
8029
                                            start: 3,
8030
                                            end: 6,
8031
                                        }))))), vec![]),
8032
                    b"..."
8033
                }
8034
                b"_GLOBAL__I__Z3foo..." => {
8035
                    MangledName::GlobalCtorDtor(
8036
                        GlobalCtorDtor::Ctor(
8037
                            Box::new(
8038
                                MangledName::Encoding(
8039
                                    Encoding::Data(
8040
                                        Name::Unscoped(
8041
                                            UnscopedName::Unqualified(
8042
                                                UnqualifiedName::Source(
8043
                                                    SourceName(
8044
                                                        Identifier {
8045
                                                            start: 14,
8046
                                                            end: 17,
8047
                                                        }))))), vec![])))),
8048
                    b"..."
8049
                }
8050
            }
8051
            Err => {
8052
                b"_Y" => Error::UnexpectedText,
8053
                b"_Z" => Error::UnexpectedEnd,
8054
                b"_" => Error::UnexpectedEnd,
8055
                b"" => Error::UnexpectedEnd,
8056
                b"_GLOBAL_" => Error::UnexpectedEnd,
8057
            }
8058
        });
8059
    }
8060
8061
    #[test]
8062
    fn parse_encoding() {
8063
        assert_parse!(Encoding {
8064
            with subs [] => {
8065
                Ok => {
8066
                    b"3fooi..." => {
8067
                        Encoding::Function(
8068
                            Name::Unscoped(
8069
                                UnscopedName::Unqualified(
8070
                                    UnqualifiedName::Source(
8071
                                        SourceName(Identifier {
8072
                                            start: 1,
8073
                                            end: 4,
8074
                                        })))),
8075
                            BareFunctionType(vec![
8076
                                TypeHandle::Builtin(BuiltinType::Standard(StandardBuiltinType::Int))
8077
                            ])),
8078
                        b"...",
8079
                        []
8080
                    }
8081
                    b"3foo..." => {
8082
                        Encoding::Data(
8083
                            Name::Unscoped(
8084
                                UnscopedName::Unqualified(
8085
                                    UnqualifiedName::Source(
8086
                                        SourceName(Identifier {
8087
                                            start: 1,
8088
                                            end: 4,
8089
                                        }))))),
8090
                        b"...",
8091
                        []
8092
                    }
8093
                    b"GV3abc..." => {
8094
                        Encoding::Special(
8095
                            SpecialName::Guard(
8096
                                Name::Unscoped(
8097
                                    UnscopedName::Unqualified(
8098
                                        UnqualifiedName::Source(
8099
                                            SourceName(Identifier {
8100
                                                start: 3,
8101
                                                end: 6,
8102
                                            })))))),
8103
                        b"...",
8104
                        []
8105
                    }
8106
                }
8107
                Err => {
8108
                    b"zzz" => Error::UnexpectedText,
8109
                    b"" => Error::UnexpectedEnd,
8110
                }
8111
            }
8112
        });
8113
    }
8114
8115
    #[test]
8116
    fn parse_global_ctor_dtor() {
8117
        assert_parse!(GlobalCtorDtor {
8118
            Ok => {
8119
                b"_I__Z3foo..." => {
8120
                    GlobalCtorDtor::Ctor(
8121
                        Box::new(
8122
                            MangledName::Encoding(
8123
                                Encoding::Data(
8124
                                    Name::Unscoped(
8125
                                        UnscopedName::Unqualified(
8126
                                            UnqualifiedName::Source(
8127
                                                SourceName(
8128
                                                    Identifier {
8129
                                                        start: 6,
8130
                                                        end: 9,
8131
                                                    }))))), vec![]))),
8132
                    b"..."
8133
                }
8134
                b".I__Z3foo..." => {
8135
                    GlobalCtorDtor::Ctor(
8136
                        Box::new(
8137
                            MangledName::Encoding(
8138
                                Encoding::Data(
8139
                                    Name::Unscoped(
8140
                                        UnscopedName::Unqualified(
8141
                                            UnqualifiedName::Source(
8142
                                                SourceName(
8143
                                                    Identifier {
8144
                                                        start: 6,
8145
                                                        end: 9,
8146
                                                    }))))), vec![]))),
8147
                    b"..."
8148
                }
8149
                b"$I__Z3foo..." => {
8150
                    GlobalCtorDtor::Ctor(
8151
                        Box::new(
8152
                            MangledName::Encoding(
8153
                                Encoding::Data(
8154
                                    Name::Unscoped(
8155
                                        UnscopedName::Unqualified(
8156
                                            UnqualifiedName::Source(
8157
                                                SourceName(
8158
                                                    Identifier {
8159
                                                        start: 6,
8160
                                                        end: 9,
8161
                                                    }))))), vec![]))),
8162
                    b"..."
8163
                }
8164
                b"_D__Z3foo..." => {
8165
                    GlobalCtorDtor::Dtor(
8166
                        Box::new(
8167
                            MangledName::Encoding(
8168
                                Encoding::Data(
8169
                                    Name::Unscoped(
8170
                                        UnscopedName::Unqualified(
8171
                                            UnqualifiedName::Source(
8172
                                                SourceName(
8173
                                                    Identifier {
8174
                                                        start: 6,
8175
                                                        end: 9,
8176
                                                    }))))), vec![]))),
8177
                    b"..."
8178
                }
8179
                b".D__Z3foo..." => {
8180
                    GlobalCtorDtor::Dtor(
8181
                        Box::new(
8182
                            MangledName::Encoding(
8183
                                Encoding::Data(
8184
                                    Name::Unscoped(
8185
                                        UnscopedName::Unqualified(
8186
                                            UnqualifiedName::Source(
8187
                                                SourceName(
8188
                                                    Identifier {
8189
                                                        start: 6,
8190
                                                        end: 9,
8191
                                                    }))))), vec![]))),
8192
                    b"..."
8193
                }
8194
                b"$D__Z3foo..." => {
8195
                    GlobalCtorDtor::Dtor(
8196
                        Box::new(
8197
                            MangledName::Encoding(
8198
                                Encoding::Data(
8199
                                    Name::Unscoped(
8200
                                        UnscopedName::Unqualified(
8201
                                            UnqualifiedName::Source(
8202
                                                SourceName(
8203
                                                    Identifier {
8204
                                                        start: 6,
8205
                                                        end: 9,
8206
                                                    }))))), vec![]))),
8207
                    b"..."
8208
                }
8209
            }
8210
            Err => {
8211
                b"_I" => Error::UnexpectedEnd,
8212
                b"_" => Error::UnexpectedEnd,
8213
                b"" => Error::UnexpectedEnd,
8214
                b"blag" => Error::UnexpectedText,
8215
                b"_J" => Error::UnexpectedText,
8216
                b"_IJ" => Error::UnexpectedText,
8217
            }
8218
        });
8219
    }
8220
8221
    #[test]
8222
    fn parse_name() {
8223
        assert_parse!(Name {
8224
            with subs [
8225
                Substitutable::Prefix(
8226
                    Prefix::Unqualified(
8227
                        UnqualifiedName::Operator(OperatorName::Simple(SimpleOperatorName::New)))),
8228
                Substitutable::Prefix(
8229
                    Prefix::Nested(PrefixHandle::BackReference(0),
8230
                                   UnqualifiedName::Operator(OperatorName::Simple(SimpleOperatorName::New)))),
8231
            ] => {
8232
                Ok => {
8233
                    b"NS0_3abcE..." => {
8234
                        Name::Nested(NestedName::Unqualified(CvQualifiers::default(),
8235
                                                             None,
8236
                                                             PrefixHandle::BackReference(1),
8237
                                                             UnqualifiedName::Source(SourceName(Identifier {
8238
                                                                 start: 5,
8239
                                                                 end: 8,
8240
                                                             })))),
8241
                        b"...",
8242
                        []
8243
                    }
8244
                    b"3abc..." => {
8245
                        Name::Unscoped(
8246
                            UnscopedName::Unqualified(
8247
                                UnqualifiedName::Source(
8248
                                    SourceName(Identifier {
8249
                                        start: 1,
8250
                                        end: 4,
8251
                                    })))),
8252
                        b"...",
8253
                        []
8254
                    }
8255
                    b"dlIcE..." => {
8256
                        Name::UnscopedTemplate(
8257
                            UnscopedTemplateNameHandle::BackReference(2),
8258
                            TemplateArgs(vec![
8259
                                TemplateArg::Type(
8260
                                    TypeHandle::Builtin(
8261
                                        BuiltinType::Standard(StandardBuiltinType::Char)))
8262
                            ])),
8263
                        b"...",
8264
                        [
8265
                            Substitutable::UnscopedTemplateName(
8266
                                UnscopedTemplateName(
8267
                                    UnscopedName::Unqualified(
8268
                                        UnqualifiedName::Operator(
8269
                                            OperatorName::Simple(
8270
                                                SimpleOperatorName::Delete))))),
8271
                        ]
8272
                    }
8273
                    b"Z3abcEs..." => {
8274
                        Name::Local(
8275
                            LocalName::Relative(
8276
                                Box::new(Encoding::Data(
8277
                                    Name::Unscoped(
8278
                                        UnscopedName::Unqualified(
8279
                                            UnqualifiedName::Source(
8280
                                                SourceName(Identifier {
8281
                                                    start: 2,
8282
                                                    end: 5,
8283
                                                })))))),
8284
                                None,
8285
                                None)),
8286
                        b"...",
8287
                        []
8288
                    }
8289
                }
8290
                Err => {
8291
                    b"zzz" => Error::UnexpectedText,
8292
                    b"" => Error::UnexpectedEnd,
8293
                }
8294
            }
8295
        });
8296
    }
8297
8298
    #[test]
8299
    fn parse_unscoped_template_name_handle() {
8300
        assert_parse!(UnscopedTemplateNameHandle {
8301
            with subs [
8302
                Substitutable::UnscopedTemplateName(
8303
                    UnscopedTemplateName(
8304
                        UnscopedName::Unqualified(
8305
                            UnqualifiedName::Operator(
8306
                                OperatorName::Simple(
8307
                                    SimpleOperatorName::New))))),
8308
            ] => {
8309
                Ok => {
8310
                    b"S_..." => {
8311
                        UnscopedTemplateNameHandle::BackReference(0),
8312
                        b"...",
8313
                        []
8314
                    }
8315
                    b"dl..." => {
8316
                        UnscopedTemplateNameHandle::BackReference(1),
8317
                        b"...",
8318
                        [
8319
                            Substitutable::UnscopedTemplateName(
8320
                                UnscopedTemplateName(
8321
                                    UnscopedName::Unqualified(
8322
                                        UnqualifiedName::Operator(
8323
                                            OperatorName::Simple(
8324
                                                SimpleOperatorName::Delete)))))
8325
                        ]
8326
                    }
8327
                }
8328
                Err => {
8329
                    b"zzzz" => Error::UnexpectedText,
8330
                    b"" => Error::UnexpectedEnd,
8331
                }
8332
            }
8333
        });
8334
    }
8335
8336
    #[test]
8337
    fn parse_nested_name() {
8338
        // <nested-name> ::= N [<CV-qualifiers>] [<ref-qualifier>] <prefix> <unqualified-name> E
8339
        //               ::= N [<CV-qualifiers>] [<ref-qualifier>] <template-prefix> <template-args> E
8340
        assert_parse!(NestedName {
8341
            with subs [
8342
                Substitutable::Prefix(
8343
                    Prefix::Unqualified(
8344
                        UnqualifiedName::Operator(
8345
                            OperatorName::Simple(
8346
                                SimpleOperatorName::New)))),
8347
            ] => {
8348
                Ok => {
8349
                    b"NKOS_3abcE..." => {
8350
                        NestedName::Unqualified(
8351
                            CvQualifiers {
8352
                                restrict: false,
8353
                                volatile: false,
8354
                                const_: true,
8355
                            },
8356
                            Some(RefQualifier::RValueRef),
8357
                            PrefixHandle::BackReference(0),
8358
                            UnqualifiedName::Source(
8359
                                SourceName(Identifier {
8360
                                    start: 6,
8361
                                    end: 9,
8362
                                }))),
8363
                        b"...",
8364
                        []
8365
                    }
8366
                    b"NOS_3abcE..." => {
8367
                        NestedName::Unqualified(
8368
                            CvQualifiers {
8369
                                restrict: false,
8370
                                volatile: false,
8371
                                const_: false,
8372
                            },
8373
                            Some(RefQualifier::RValueRef),
8374
                            PrefixHandle::BackReference(0),
8375
                            UnqualifiedName::Source(
8376
                                SourceName(Identifier {
8377
                                    start: 5,
8378
                                    end: 8,
8379
                                }))),
8380
                        b"...",
8381
                        []
8382
                    }
8383
                    b"NS_3abcE..." => {
8384
                        NestedName::Unqualified(
8385
                            CvQualifiers {
8386
                                restrict: false,
8387
                                volatile: false,
8388
                                const_: false,
8389
                            },
8390
                            None,
8391
                            PrefixHandle::BackReference(0),
8392
                            UnqualifiedName::Source(
8393
                                SourceName(Identifier {
8394
                                    start: 4,
8395
                                    end: 7,
8396
                                }))),
8397
                        b"...",
8398
                        []
8399
                    }
8400
                    b"NKOS_3abcIJEEE..." => {
8401
                        NestedName::Template(
8402
                            CvQualifiers {
8403
                                restrict: false,
8404
                                volatile: false,
8405
                                const_: true,
8406
                            },
8407
                            Some(RefQualifier::RValueRef),
8408
                            PrefixHandle::NonSubstitution(NonSubstitution(0))),
8409
                        b"...",
8410
                        [
8411
                            Substitutable::Prefix(
8412
                                Prefix::Nested(
8413
                                    PrefixHandle::BackReference(0),
8414
                                    UnqualifiedName::Source(
8415
                                        SourceName(Identifier {
8416
                                            start: 6,
8417
                                            end: 9,
8418
                                        })))),
8419
                        ]
8420
                    }
8421
                    b"NOS_3abcIJEEE..." => {
8422
                        NestedName::Template(
8423
                            CvQualifiers {
8424
                                restrict: false,
8425
                                volatile: false,
8426
                                const_: false,
8427
                            },
8428
                            Some(RefQualifier::RValueRef),
8429
                            PrefixHandle::NonSubstitution(NonSubstitution(0))),
8430
                        b"...",
8431
                        [
8432
                            Substitutable::Prefix(
8433
                                Prefix::Nested(
8434
                                    PrefixHandle::BackReference(0),
8435
                                    UnqualifiedName::Source(
8436
                                        SourceName(Identifier {
8437
                                            start: 5,
8438
                                            end: 8,
8439
                                        })))),
8440
                        ]
8441
                    }
8442
                    b"NS_3abcIJEEE..." => {
8443
                        NestedName::Template(
8444
                            CvQualifiers {
8445
                                restrict: false,
8446
                                volatile: false,
8447
                                const_: false,
8448
                            },
8449
                            None,
8450
                            PrefixHandle::NonSubstitution(NonSubstitution(0))),
8451
                        b"...",
8452
                        [
8453
                            Substitutable::Prefix(
8454
                                Prefix::Nested(
8455
                                    PrefixHandle::BackReference(0),
8456
                                    UnqualifiedName::Source(
8457
                                        SourceName(Identifier {
8458
                                            start: 4,
8459
                                            end: 7,
8460
                                        })))),
8461
                        ]
8462
                    }
8463
                }
8464
                Err => {
8465
                    // Ends with a prefix that is not a name or template.
8466
                    b"NS_E..." => Error::UnexpectedText,
8467
                    b"NS_DttrEE..." => Error::UnexpectedText,
8468
8469
                    b"zzz" => Error::UnexpectedText,
8470
                    b"Nzzz" => Error::UnexpectedText,
8471
                    b"NKzzz" => Error::UnexpectedText,
8472
                    b"NKOzzz" => Error::UnexpectedText,
8473
                    b"NKO3abczzz" => Error::UnexpectedText,
8474
                    b"NKO3abc3abczzz" => Error::UnexpectedText,
8475
                    b"" => Error::UnexpectedEnd,
8476
                    b"N" => Error::UnexpectedEnd,
8477
                    b"NK" => Error::UnexpectedEnd,
8478
                    b"NKO" => Error::UnexpectedEnd,
8479
                    b"NKO3abc" => Error::UnexpectedEnd,
8480
                    b"NKO3abc3abc" => Error::UnexpectedEnd,
8481
                }
8482
            }
8483
        });
8484
    }
8485
8486
    #[test]
8487
    fn parse_prefix_handle() {
8488
        // <prefix> ::= <unqualified-name>
8489
        //          ::= <prefix> <unqualified-name>
8490
        //          ::= <template-prefix> <template-args>
8491
        //          ::= <template-param>
8492
        //          ::= <decltype>
8493
        //          ::= <prefix> <data-member-prefix>
8494
        //          ::= <substitution>
8495
        assert_parse!(PrefixHandle {
8496
            with subs [
8497
                Substitutable::Prefix(
8498
                    Prefix::Unqualified(
8499
                        UnqualifiedName::Operator(
8500
                            OperatorName::Simple(
8501
                                SimpleOperatorName::New)))),
8502
            ] => {
8503
                Ok => {
8504
                    b"3foo..." => {
8505
                        PrefixHandle::BackReference(1),
8506
                        b"...",
8507
                        [
8508
                            Substitutable::Prefix(
8509
                                Prefix::Unqualified(
8510
                                    UnqualifiedName::Source(
8511
                                        SourceName(Identifier {
8512
                                            start: 1,
8513
                                            end: 4,
8514
                                        }))))
8515
                        ]
8516
                    }
8517
                    b"3abc3def..." => {
8518
                        PrefixHandle::BackReference(2),
8519
                        b"...",
8520
                        [
8521
                            Substitutable::Prefix(
8522
                                Prefix::Unqualified(
8523
                                    UnqualifiedName::Source(
8524
                                        SourceName(Identifier {
8525
                                            start: 1,
8526
                                            end: 4,
8527
                                        })))),
8528
                            Substitutable::Prefix(
8529
                                Prefix::Nested(
8530
                                    PrefixHandle::BackReference(1),
8531
                                    UnqualifiedName::Source(
8532
                                        SourceName(Identifier {
8533
                                            start: 5,
8534
                                            end: 8,
8535
                                        })))),
8536
                        ]
8537
                    }
8538
                    b"3fooIJEE..." => {
8539
                        PrefixHandle::BackReference(2),
8540
                        b"...",
8541
                        [
8542
                            Substitutable::Prefix(
8543
                                Prefix::Unqualified(
8544
                                    UnqualifiedName::Source(
8545
                                        SourceName(Identifier {
8546
                                            start: 1,
8547
                                            end: 4,
8548
                                        })))),
8549
                            Substitutable::Prefix(
8550
                                Prefix::Template(PrefixHandle::BackReference(1),
8551
                                                 TemplateArgs(vec![
8552
                                                     TemplateArg::ArgPack(vec![]),
8553
                                                 ])))
8554
                        ]
8555
                    }
8556
                    b"T_..." => {
8557
                        PrefixHandle::BackReference(1),
8558
                        b"...",
8559
                        [
8560
                            Substitutable::Prefix(Prefix::TemplateParam(TemplateParam(0))),
8561
                        ]
8562
                    }
8563
                    b"DTtrE..." => {
8564
                        PrefixHandle::BackReference(1),
8565
                        b"...",
8566
                        [
8567
                            Substitutable::Prefix(
8568
                                Prefix::Decltype(
8569
                                    Decltype::Expression(Expression::Rethrow))),
8570
                        ]
8571
                    }
8572
                    b"3abc3defM..." => {
8573
                        PrefixHandle::BackReference(2),
8574
                        b"...",
8575
                        [
8576
                            Substitutable::Prefix(
8577
                                Prefix::Unqualified(
8578
                                    UnqualifiedName::Source(
8579
                                        SourceName(Identifier {
8580
                                            start: 1,
8581
                                            end: 4,
8582
                                        })))),
8583
                            Substitutable::Prefix(
8584
                                Prefix::DataMember(
8585
                                    PrefixHandle::BackReference(1),
8586
                                    DataMemberPrefix(
8587
                                        SourceName(Identifier {
8588
                                            start: 5,
8589
                                            end: 8,
8590
                                        })))),
8591
                        ]
8592
                    }
8593
                    b"S_..." => {
8594
                        PrefixHandle::BackReference(0),
8595
                        b"...",
8596
                        []
8597
                    }
8598
                    // The trailing E and <nested-name> case...
8599
                    b"3abc3defE..." => {
8600
                        PrefixHandle::NonSubstitution(NonSubstitution(0)),
8601
                        b"E...",
8602
                        [
8603
                            Substitutable::Prefix(
8604
                                Prefix::Unqualified(
8605
                                    UnqualifiedName::Source(
8606
                                        SourceName(Identifier {
8607
                                            start: 1,
8608
                                            end: 4,
8609
                                        })))),
8610
                        ]
8611
                    }
8612
                }
8613
                Err => {
8614
                    b"zzz" => Error::UnexpectedText,
8615
                    b"" => Error::UnexpectedEnd,
8616
                }
8617
            }
8618
        });
8619
    }
8620
8621
    #[test]
8622
    fn parse_type_handle() {
8623
        assert_parse!(TypeHandle {
8624
            with subs [
8625
                Substitutable::Type(
8626
                    Type::PointerTo(
8627
                        TypeHandle::Builtin(BuiltinType::Standard(StandardBuiltinType::Char)))),
8628
            ] => {
8629
                Ok => {
8630
                    b"S_..." => {
8631
                        TypeHandle::BackReference(0),
8632
                        b"...",
8633
                        []
8634
                    }
8635
                    b"c..." => {
8636
                        TypeHandle::Builtin(BuiltinType::Standard(StandardBuiltinType::Char)),
8637
                        b"...",
8638
                        []
8639
                    }
8640
                    b"FS_E..." => {
8641
                        TypeHandle::BackReference(1),
8642
                        b"...",
8643
                        [
8644
                            Substitutable::Type(
8645
                                Type::Function(FunctionType {
8646
                                    cv_qualifiers: CvQualifiers {
8647
                                        restrict: false,
8648
                                        volatile: false,
8649
                                        const_: false,
8650
                                    },
8651
                                    transaction_safe: false,
8652
                                    extern_c: false,
8653
                                    bare: BareFunctionType(vec![TypeHandle::BackReference(0)]),
8654
                                    ref_qualifier: None,
8655
                                })),
8656
                        ]
8657
                    }
8658
                    b"A_S_..." => {
8659
                        TypeHandle::BackReference(1),
8660
                        b"...",
8661
                        [
8662
                            Substitutable::Type(
8663
                                Type::Array(ArrayType::NoDimension(TypeHandle::BackReference(0)))),
8664
                        ]
8665
                    }
8666
                    b"MS_S_..." => {
8667
                        TypeHandle::BackReference(1),
8668
                        b"...",
8669
                        [
8670
                            Substitutable::Type(
8671
                                Type::PointerToMember(
8672
                                    PointerToMemberType(TypeHandle::BackReference(0),
8673
                                                        TypeHandle::BackReference(0)))),
8674
                        ]
8675
                    }
8676
                    b"T_..." => {
8677
                        TypeHandle::BackReference(1),
8678
                        b"...",
8679
                        [
8680
                            Substitutable::Type(Type::TemplateParam(TemplateParam(0))),
8681
                        ]
8682
                    }
8683
                    b"T_IS_E..." => {
8684
                        TypeHandle::BackReference(2),
8685
                        b"...",
8686
                        [
8687
                            Substitutable::TemplateTemplateParam(
8688
                                TemplateTemplateParam(TemplateParam(0))),
8689
                            Substitutable::Type(
8690
                                Type::TemplateTemplate(
8691
                                    TemplateTemplateParamHandle::BackReference(1),
8692
                                    TemplateArgs(vec![
8693
                                        TemplateArg::Type(TypeHandle::BackReference(0))
8694
                                    ]))),
8695
                        ]
8696
                    }
8697
                    b"DTtrE..." => {
8698
                        TypeHandle::BackReference(1),
8699
                        b"...",
8700
                        [
8701
                            Substitutable::Type(
8702
                                Type::Decltype(Decltype::Expression(Expression::Rethrow))),
8703
                        ]
8704
                    }
8705
                    b"KS_..." => {
8706
                        TypeHandle::BackReference(1),
8707
                        b"...",
8708
                        [
8709
                            Substitutable::Type(Type::Qualified(CvQualifiers {
8710
                                restrict: false,
8711
                                volatile: false,
8712
                                const_: true,
8713
                            }, TypeHandle::BackReference(0)))
8714
                        ]
8715
                    }
8716
                    b"PS_..." => {
8717
                        TypeHandle::BackReference(1),
8718
                        b"...",
8719
                        [
8720
                            Substitutable::Type(Type::PointerTo(TypeHandle::BackReference(0)))
8721
                        ]
8722
                    }
8723
                    b"RS_..." => {
8724
                        TypeHandle::BackReference(1),
8725
                        b"...",
8726
                        [
8727
                            Substitutable::Type(Type::LvalueRef(TypeHandle::BackReference(0)))
8728
                        ]
8729
                    }
8730
                    b"OS_..." => {
8731
                        TypeHandle::BackReference(1),
8732
                        b"...",
8733
                        [
8734
                            Substitutable::Type(Type::RvalueRef(TypeHandle::BackReference(0)))
8735
                        ]
8736
                    }
8737
                    b"CS_..." => {
8738
                        TypeHandle::BackReference(1),
8739
                        b"...",
8740
                        [
8741
                            Substitutable::Type(Type::Complex(TypeHandle::BackReference(0)))
8742
                        ]
8743
                    }
8744
                    b"GS_..." => {
8745
                        TypeHandle::BackReference(1),
8746
                        b"...",
8747
                        [
8748
                            Substitutable::Type(Type::Imaginary(TypeHandle::BackReference(0)))
8749
                        ]
8750
                    }
8751
                    b"U3abcS_..." => {
8752
                        TypeHandle::BackReference(1),
8753
                        b"...",
8754
                        [
8755
                            Substitutable::Type(
8756
                                Type::VendorExtension(
8757
                                    SourceName(Identifier {
8758
                                        start: 2,
8759
                                        end: 5,
8760
                                    }),
8761
                                    None,
8762
                                    TypeHandle::BackReference(0)))
8763
                        ]
8764
                    }
8765
                    b"U3abcIS_ES_..." => {
8766
                        TypeHandle::BackReference(1),
8767
                        b"...",
8768
                        [
8769
                            Substitutable::Type(
8770
                                Type::VendorExtension(
8771
                                    SourceName(Identifier {
8772
                                        start: 2,
8773
                                        end: 5,
8774
                                    }),
8775
                                    Some(TemplateArgs(vec![
8776
                                        TemplateArg::Type(TypeHandle::BackReference(0))
8777
                                    ])),
8778
                                    TypeHandle::BackReference(0)))
8779
                        ]
8780
                    }
8781
                    b"DpS_..." => {
8782
                        TypeHandle::BackReference(1),
8783
                        b"...",
8784
                        [
8785
                            Substitutable::Type(
8786
                                Type::PackExpansion(TypeHandle::BackReference(0))),
8787
                        ]
8788
                    }
8789
                    b"3abc..." => {
8790
                        TypeHandle::BackReference(1),
8791
                        b"...",
8792
                        [
8793
                            Substitutable::Type(
8794
                                Type::ClassEnum(
8795
                                    ClassEnumType::Named(
8796
                                        Name::Unscoped(
8797
                                            UnscopedName::Unqualified(
8798
                                                UnqualifiedName::Source(
8799
                                                    SourceName(Identifier {
8800
                                                        start: 1,
8801
                                                        end: 4,
8802
                                                    })))))))
8803
                        ]
8804
                    }
8805
                }
8806
                Err => {
8807
                    b"P" => Error::UnexpectedEnd,
8808
                    b"R" => Error::UnexpectedEnd,
8809
                    b"O" => Error::UnexpectedEnd,
8810
                    b"C" => Error::UnexpectedEnd,
8811
                    b"G" => Error::UnexpectedEnd,
8812
                    b"Dp" => Error::UnexpectedEnd,
8813
                    b"D" => Error::UnexpectedEnd,
8814
                    b"P" => Error::UnexpectedEnd,
8815
                    b"" => Error::UnexpectedEnd,
8816
                }
8817
            }
8818
        });
8819
    }
8820
8821
    #[test]
8822
    fn parse_function_type() {
8823
        assert_parse!(FunctionType {
8824
            with subs [
8825
                Substitutable::Type(
8826
                    Type::PointerTo(
8827
                        TypeHandle::Builtin(BuiltinType::Standard(StandardBuiltinType::Char)))),
8828
            ] => {
8829
                Ok => {
8830
                    b"KDxFYS_RE..." => {
8831
                        FunctionType {
8832
                            cv_qualifiers: CvQualifiers {
8833
                                restrict: false,
8834
                                volatile: false,
8835
                                const_: true,
8836
                            },
8837
                            transaction_safe: true,
8838
                            extern_c: true,
8839
                            bare: BareFunctionType(vec![TypeHandle::BackReference(0)]),
8840
                            ref_qualifier: Some(RefQualifier::LValueRef),
8841
                        },
8842
                        b"...",
8843
                        []
8844
                    }
8845
                    b"DxFYS_RE..." => {
8846
                        FunctionType {
8847
                            cv_qualifiers: CvQualifiers {
8848
                                restrict: false,
8849
                                volatile: false,
8850
                                const_: false,
8851
                            },
8852
                            transaction_safe: true,
8853
                            extern_c: true,
8854
                            bare: BareFunctionType(vec![TypeHandle::BackReference(0)]),
8855
                            ref_qualifier: Some(RefQualifier::LValueRef),
8856
                        },
8857
                        b"...",
8858
                        []
8859
                    }
8860
                    b"FYS_RE..." => {
8861
                        FunctionType {
8862
                            cv_qualifiers: CvQualifiers {
8863
                                restrict: false,
8864
                                volatile: false,
8865
                                const_: false,
8866
                            },
8867
                            transaction_safe: false,
8868
                            extern_c: true,
8869
                            bare: BareFunctionType(vec![TypeHandle::BackReference(0)]),
8870
                            ref_qualifier: Some(RefQualifier::LValueRef),
8871
                        },
8872
                        b"...",
8873
                        []
8874
                    }
8875
                    b"FS_RE..." => {
8876
                        FunctionType {
8877
                            cv_qualifiers: CvQualifiers {
8878
                                restrict: false,
8879
                                volatile: false,
8880
                                const_: false,
8881
                            },
8882
                            transaction_safe: false,
8883
                            extern_c: false,
8884
                            bare: BareFunctionType(vec![TypeHandle::BackReference(0)]),
8885
                            ref_qualifier: Some(RefQualifier::LValueRef),
8886
                        },
8887
                        b"...",
8888
                        []
8889
                    }
8890
                    b"FS_E..." => {
8891
                        FunctionType {
8892
                            cv_qualifiers: CvQualifiers {
8893
                                restrict: false,
8894
                                volatile: false,
8895
                                const_: false,
8896
                            },
8897
                            transaction_safe: false,
8898
                            extern_c: false,
8899
                            bare: BareFunctionType(vec![TypeHandle::BackReference(0)]),
8900
                            ref_qualifier: None,
8901
                        },
8902
                        b"...",
8903
                        []
8904
                    }
8905
                }
8906
                Err => {
8907
                    b"DFYS_E" => Error::UnexpectedText,
8908
                    b"KKFS_E" => Error::UnexpectedText,
8909
                    b"FYS_..." => Error::UnexpectedText,
8910
                    b"FYS_" => Error::UnexpectedEnd,
8911
                    b"F" => Error::UnexpectedEnd,
8912
                    b"" => Error::UnexpectedEnd,
8913
                }
8914
            }
8915
        });
8916
    }
8917
8918
    #[test]
8919
    fn parse_bare_function_type() {
8920
        assert_parse!(BareFunctionType {
8921
            with subs [
8922
                Substitutable::Type(
8923
                    Type::PointerTo(
8924
                        TypeHandle::Builtin(BuiltinType::Standard(StandardBuiltinType::Char)))),
8925
            ] => {
8926
                Ok => {
8927
                    b"S_S_..." => {
8928
                        BareFunctionType(vec![
8929
                            TypeHandle::BackReference(0),
8930
                            TypeHandle::BackReference(0),
8931
                        ]),
8932
                        b"...",
8933
                        []
8934
                    }
8935
                }
8936
                Err => {
8937
                    b"" => Error::UnexpectedEnd,
8938
                }
8939
            }
8940
        });
8941
    }
8942
8943
    #[test]
8944
    fn parse_decltype() {
8945
        assert_parse!(Decltype {
8946
            Ok => {
8947
                b"DTtrE..." => {
8948
                    Decltype::Expression(Expression::Rethrow),
8949
                    b"..."
8950
                }
8951
                b"DttrE..." => {
8952
                    Decltype::IdExpression(Expression::Rethrow),
8953
                    b"..."
8954
                }
8955
            }
8956
            Err => {
8957
                b"Dtrtz" => Error::UnexpectedText,
8958
                b"DTrtz" => Error::UnexpectedText,
8959
                b"Dz" => Error::UnexpectedText,
8960
                b"Dtrt" => Error::UnexpectedText,
8961
                b"DTrt" => Error::UnexpectedText,
8962
                b"Dt" => Error::UnexpectedEnd,
8963
                b"DT" => Error::UnexpectedEnd,
8964
                b"D" => Error::UnexpectedEnd,
8965
                b"" => Error::UnexpectedEnd,
8966
            }
8967
        });
8968
    }
8969
8970
    #[test]
8971
    fn parse_class_enum_type() {
8972
        assert_parse!(ClassEnumType {
8973
            Ok => {
8974
                b"3abc..." => {
8975
                    ClassEnumType::Named(
8976
                        Name::Unscoped(
8977
                            UnscopedName::Unqualified(
8978
                                UnqualifiedName::Source(
8979
                                    SourceName(Identifier {
8980
                                        start: 1,
8981
                                        end: 4,
8982
                                    }))))),
8983
                    b"..."
8984
                }
8985
                b"Ts3abc..." => {
8986
                    ClassEnumType::ElaboratedStruct(
8987
                        Name::Unscoped(
8988
                            UnscopedName::Unqualified(
8989
                                UnqualifiedName::Source(
8990
                                    SourceName(Identifier {
8991
                                        start: 3,
8992
                                        end: 6,
8993
                                    }))))),
8994
                    b"..."
8995
                }
8996
                b"Tu3abc..." => {
8997
                    ClassEnumType::ElaboratedUnion(
8998
                        Name::Unscoped(
8999
                            UnscopedName::Unqualified(
9000
                                UnqualifiedName::Source(
9001
                                    SourceName(Identifier {
9002
                                        start: 3,
9003
                                        end: 6,
9004
                                    }))))),
9005
                    b"..."
9006
                }
9007
                b"Te3abc..." => {
9008
                    ClassEnumType::ElaboratedEnum(
9009
                        Name::Unscoped(
9010
                            UnscopedName::Unqualified(
9011
                                UnqualifiedName::Source(
9012
                                    SourceName(Identifier {
9013
                                        start: 3,
9014
                                        end: 6,
9015
                                    }))))),
9016
                    b"..."
9017
                }
9018
            }
9019
            Err => {
9020
                b"zzz" => Error::UnexpectedText,
9021
                b"Tzzz" => Error::UnexpectedText,
9022
                b"T" => Error::UnexpectedEnd,
9023
                b"" => Error::UnexpectedEnd,
9024
            }
9025
        });
9026
    }
9027
9028
    #[test]
9029
    fn parse_array_type() {
9030
        assert_parse!(ArrayType {
9031
            with subs [
9032
                Substitutable::Type(Type::Decltype(Decltype::Expression(Expression::Rethrow)))
9033
            ] => {
9034
                Ok => {
9035
                    b"A10_S_..." => {
9036
                        ArrayType::DimensionNumber(10, TypeHandle::BackReference(0)),
9037
                        b"...",
9038
                        []
9039
                    }
9040
                    b"A10_Sb..." => {
9041
                        ArrayType::DimensionNumber(10,
9042
                                                   TypeHandle::WellKnown(
9043
                                                       WellKnownComponent::StdString1)),
9044
                        b"...",
9045
                        []
9046
                    }
9047
                    b"Atr_S_..." => {
9048
                        ArrayType::DimensionExpression(Expression::Rethrow,
9049
                                                       TypeHandle::BackReference(0)),
9050
                        b"...",
9051
                        []
9052
                    }
9053
                    b"A_S_..." => {
9054
                        ArrayType::NoDimension(TypeHandle::BackReference(0)),
9055
                        b"...",
9056
                        []
9057
                    }
9058
                }
9059
                Err => {
9060
                    b"A10_" => Error::UnexpectedEnd,
9061
                    b"A10" => Error::UnexpectedEnd,
9062
                    b"A" => Error::UnexpectedEnd,
9063
                    b"" => Error::UnexpectedEnd,
9064
                    b"A10_..." => Error::UnexpectedText,
9065
                    b"A10..." => Error::UnexpectedText,
9066
                    b"A..." => Error::UnexpectedText,
9067
                    b"..." => Error::UnexpectedText,
9068
                }
9069
            }
9070
        });
9071
    }
9072
9073
    #[test]
9074
    fn parse_vector_type() {
9075
        assert_parse!(VectorType {
9076
            with subs [
9077
                Substitutable::Type(Type::Decltype(Decltype::Expression(Expression::Rethrow)))
9078
            ] => {
9079
                Ok => {
9080
                    b"Dv10_S_..." => {
9081
                        VectorType::DimensionNumber(10, TypeHandle::BackReference(0)),
9082
                        b"...",
9083
                        []
9084
                    }
9085
                    b"Dv10_Sb..." => {
9086
                        VectorType::DimensionNumber(10,
9087
                                                    TypeHandle::WellKnown(
9088
                                                        WellKnownComponent::StdString1)),
9089
                        b"...",
9090
                        []
9091
                    }
9092
                    b"Dvtr_S_..." => {
9093
                        VectorType::DimensionExpression(Expression::Rethrow,
9094
                                                        TypeHandle::BackReference(0)),
9095
                        b"...",
9096
                        []
9097
                    }
9098
                }
9099
                Err => {
9100
                    b"Dq" => Error::UnexpectedText,
9101
                    b"Dv" => Error::UnexpectedEnd,
9102
                    b"Dv42_" => Error::UnexpectedEnd,
9103
                    b"Dv42_..." => Error::UnexpectedText,
9104
                    b"Dvtr_" => Error::UnexpectedEnd,
9105
                    b"Dvtr_..." => Error::UnexpectedText,
9106
                    b"" => Error::UnexpectedEnd,
9107
                    b"..." => Error::UnexpectedText,
9108
                }
9109
            }
9110
        });
9111
    }
9112
9113
    #[test]
9114
    fn parse_pointer_to_member_type() {
9115
        assert_parse!(PointerToMemberType {
9116
            with subs [
9117
                Substitutable::Type(Type::Decltype(Decltype::Expression(Expression::Rethrow)))
9118
            ] => {
9119
                Ok => {
9120
                    b"MS_S_..." => {
9121
                        PointerToMemberType(TypeHandle::BackReference(0),
9122
                                            TypeHandle::BackReference(0)),
9123
                        b"...",
9124
                        []
9125
                    }
9126
                }
9127
                Err => {
9128
                    b"MS_S" => Error::UnexpectedEnd,
9129
                    b"MS_" => Error::UnexpectedEnd,
9130
                    b"MS" => Error::UnexpectedEnd,
9131
                    b"M" => Error::UnexpectedEnd,
9132
                    b"" => Error::UnexpectedEnd,
9133
                    b"MS_..." => Error::UnexpectedText,
9134
                    b"M..." => Error::UnexpectedText,
9135
                    b"..." => Error::UnexpectedText,
9136
                }
9137
            }
9138
        });
9139
    }
9140
9141
    #[test]
9142
    fn parse_template_template_param_handle() {
9143
        assert_parse!(TemplateTemplateParamHandle {
9144
            with subs [
9145
                Substitutable::TemplateTemplateParam(TemplateTemplateParam(TemplateParam(0)))
9146
            ] => {
9147
                Ok => {
9148
                    b"S_..." => {
9149
                        TemplateTemplateParamHandle::BackReference(0),
9150
                        b"...",
9151
                        []
9152
                    }
9153
                    b"T1_..." => {
9154
                        TemplateTemplateParamHandle::BackReference(1),
9155
                        b"...",
9156
                        [
9157
                            Substitutable::TemplateTemplateParam(TemplateTemplateParam(TemplateParam(2)))
9158
                        ]
9159
                    }
9160
                }
9161
                Err => {
9162
                    b"S" => Error::UnexpectedText,
9163
                    b"T" => Error::UnexpectedEnd,
9164
                    b"" => Error::UnexpectedEnd,
9165
                    b"S..." => Error::UnexpectedText,
9166
                    b"T..." => Error::UnexpectedText,
9167
                    b"..." => Error::UnexpectedText,
9168
                }
9169
            }
9170
        });
9171
    }
9172
9173
    #[test]
9174
    fn parse_template_args() {
9175
        assert_parse!(TemplateArgs {
9176
            with subs [
9177
                Substitutable::Type(Type::Decltype(Decltype::Expression(Expression::Rethrow)))
9178
            ] => {
9179
                Ok => {
9180
                    b"IS_E..." => {
9181
                        TemplateArgs(vec![TemplateArg::Type(TypeHandle::BackReference(0))]),
9182
                        b"...",
9183
                        []
9184
                    }
9185
                    b"IS_S_S_S_E..." => {
9186
                        TemplateArgs(vec![
9187
                            TemplateArg::Type(TypeHandle::BackReference(0)),
9188
                            TemplateArg::Type(TypeHandle::BackReference(0)),
9189
                            TemplateArg::Type(TypeHandle::BackReference(0)),
9190
                            TemplateArg::Type(TypeHandle::BackReference(0)),
9191
                        ]),
9192
                        b"...",
9193
                        []
9194
                    }
9195
                }
9196
                Err => {
9197
                    b"zzz" => Error::UnexpectedText,
9198
                    b"IE" => Error::UnexpectedText,
9199
                    b"IS_" => Error::UnexpectedEnd,
9200
                    b"I" => Error::UnexpectedEnd,
9201
                    b"" => Error::UnexpectedEnd,
9202
                }
9203
            }
9204
        });
9205
    }
9206
9207
    #[test]
9208
    fn parse_template_arg() {
9209
        assert_parse!(TemplateArg {
9210
            with subs [
9211
                Substitutable::Type(Type::Decltype(Decltype::Expression(Expression::Rethrow)))
9212
            ] => {
9213
                Ok => {
9214
                    b"S_..." => {
9215
                        TemplateArg::Type(TypeHandle::BackReference(0)),
9216
                        b"...",
9217
                        []
9218
                    }
9219
                    b"XtrE..." => {
9220
                        TemplateArg::Expression(Expression::Rethrow),
9221
                        b"...",
9222
                        []
9223
                    }
9224
                    b"XsrS_1QE..." => {
9225
                        TemplateArg::Expression(
9226
                            Expression::UnresolvedName(
9227
                                UnresolvedName::Nested1(
9228
                                    UnresolvedTypeHandle::BackReference(0),
9229
                                    vec![],
9230
                                    BaseUnresolvedName::Name(
9231
                                        SimpleId(
9232
                                            SourceName(Identifier {
9233
                                                start: 6,
9234
                                                end: 7
9235
                                            }),
9236
                                            None
9237
                                        )
9238
                                    )
9239
                                )
9240
                            )
9241
                        ),
9242
                        b"...",
9243
                        []
9244
                    }
9245
                    b"XsrS_1QIlEE..." => {
9246
                        TemplateArg::Expression(
9247
                            Expression::UnresolvedName(
9248
                                UnresolvedName::Nested1(
9249
                                    UnresolvedTypeHandle::BackReference(0),
9250
                                    vec![],
9251
                                    BaseUnresolvedName::Name(
9252
                                        SimpleId(
9253
                                            SourceName(Identifier {
9254
                                                start: 6,
9255
                                                end: 7
9256
                                            }),
9257
                                            Some(
9258
                                                TemplateArgs(
9259
                                                    vec![
9260
                                                        TemplateArg::Type(
9261
                                                            TypeHandle::Builtin(
9262
                                                                BuiltinType::Standard(
9263
                                                                    StandardBuiltinType::Long
9264
                                                                )
9265
                                                            )
9266
                                                        )
9267
                                                    ]
9268
                                                )
9269
                                            )
9270
                                        )
9271
                                    )
9272
                                )
9273
                            )
9274
                        ),
9275
                        b"...",
9276
                        []
9277
                    }
9278
                    b"LS_E..." => {
9279
                        TemplateArg::SimpleExpression(
9280
                            ExprPrimary::Literal(TypeHandle::BackReference(0), 3, 3)),
9281
                        b"...",
9282
                        []
9283
                    }
9284
                    b"JE..." => {
9285
                        TemplateArg::ArgPack(vec![]),
9286
                        b"...",
9287
                        []
9288
                    }
9289
                    b"JS_XtrELS_EJEE..." => {
9290
                        TemplateArg::ArgPack(vec![
9291
                            TemplateArg::Type(TypeHandle::BackReference(0)),
9292
                            TemplateArg::Expression(Expression::Rethrow),
9293
                            TemplateArg::SimpleExpression(
9294
                                ExprPrimary::Literal(TypeHandle::BackReference(0), 10, 10)),
9295
                            TemplateArg::ArgPack(vec![]),
9296
                        ]),
9297
                        b"...",
9298
                        []
9299
                    }
9300
                }
9301
                Err => {
9302
                    b"..." => Error::UnexpectedText,
9303
                    b"X..." => Error::UnexpectedText,
9304
                    b"J..." => Error::UnexpectedText,
9305
                    b"JS_..." => Error::UnexpectedText,
9306
                    b"JS_" => Error::UnexpectedEnd,
9307
                    b"X" => Error::UnexpectedEnd,
9308
                    b"J" => Error::UnexpectedEnd,
9309
                    b"" => Error::UnexpectedEnd,
9310
                }
9311
            }
9312
        });
9313
    }
9314
9315
    #[test]
9316
    fn parse_expression() {
9317
        assert_parse!(Expression {
9318
            with subs [
9319
                Substitutable::Type(
9320
                    Type::PointerTo(TypeHandle::Builtin(
9321
                        BuiltinType::Standard(StandardBuiltinType::Int)))),
9322
            ] => {
9323
                Ok => {
9324
                    b"psLS_1E..." => {
9325
                        Expression::Unary(OperatorName::Simple(SimpleOperatorName::UnaryPlus),
9326
                                          Box::new(Expression::Primary(
9327
                                              ExprPrimary::Literal(
9328
                                                  TypeHandle::BackReference(0),
9329
                                                  5,
9330
                                                  6)))),
9331
                        b"...",
9332
                        []
9333
                    }
9334
                    b"rsLS_1ELS_1E..." => {
9335
                        Expression::Binary(OperatorName::Simple(SimpleOperatorName::Shr),
9336
                                           Box::new(Expression::Primary(
9337
                                               ExprPrimary::Literal(
9338
                                                   TypeHandle::BackReference(0),
9339
                                                   5,
9340
                                                   6))),
9341
                                           Box::new(Expression::Primary(
9342
                                               ExprPrimary::Literal(
9343
                                                   TypeHandle::BackReference(0),
9344
                                                   10,
9345
                                                   11)))),
9346
                        b"...",
9347
                        []
9348
                    }
9349
                    b"quLS_1ELS_2ELS_3E..." => {
9350
                        Expression::Ternary(OperatorName::Simple(SimpleOperatorName::Question),
9351
                                            Box::new(Expression::Primary(
9352
                                                ExprPrimary::Literal(
9353
                                                    TypeHandle::BackReference(0),
9354
                                                    5,
9355
                                                    6))),
9356
                                            Box::new(Expression::Primary(
9357
                                                ExprPrimary::Literal(
9358
                                                    TypeHandle::BackReference(0),
9359
                                                    10,
9360
                                                    11))),
9361
                                            Box::new(Expression::Primary(
9362
                                                ExprPrimary::Literal(
9363
                                                    TypeHandle::BackReference(0),
9364
                                                    15,
9365
                                                    16)))),
9366
                        b"...",
9367
                        []
9368
                    }
9369
                    b"pp_LS_1E..." => {
9370
                        Expression::PrefixInc(
9371
                            Box::new(Expression::Primary(
9372
                                ExprPrimary::Literal(
9373
                                    TypeHandle::BackReference(0),
9374
                                    6,
9375
                                    7)))),
9376
                        b"...",
9377
                        []
9378
                    }
9379
                    b"mm_LS_1E..." => {
9380
                        Expression::PrefixDec(
9381
                            Box::new(Expression::Primary(
9382
                                ExprPrimary::Literal(
9383
                                    TypeHandle::BackReference(0),
9384
                                    6,
9385
                                    7)))),
9386
                        b"...",
9387
                        []
9388
                    }
9389
                    b"clLS_1EE..." => {
9390
                        Expression::Call(
9391
                            Box::new(Expression::Primary(
9392
                                ExprPrimary::Literal(
9393
                                    TypeHandle::BackReference(0),
9394
                                    5,
9395
                                    6))),
9396
                            vec![]),
9397
                        b"...",
9398
                        []
9399
                    }
9400
                    //               ::= cv <type> <expression>                       # type (expression), conversion with one argument
9401
                    b"cvS_LS_1E..." => {
9402
                        Expression::ConversionOne(
9403
                            TypeHandle::BackReference(0),
9404
                            Box::new(Expression::Primary(
9405
                                ExprPrimary::Literal(
9406
                                    TypeHandle::BackReference(0),
9407
                                    7,
9408
                                    8)))),
9409
                        b"...",
9410
                        []
9411
                    }
9412
                    b"cvS__LS_1ELS_1EE..." => {
9413
                        Expression::ConversionMany(
9414
                            TypeHandle::BackReference(0),
9415
                            vec![
9416
                                Expression::Primary(
9417
                                    ExprPrimary::Literal(
9418
                                        TypeHandle::BackReference(0),
9419
                                        8,
9420
                                        9)),
9421
                                Expression::Primary(
9422
                                    ExprPrimary::Literal(
9423
                                        TypeHandle::BackReference(0),
9424
                                        13,
9425
                                        14)),
9426
                            ]),
9427
                        b"...",
9428
                        []
9429
                    }
9430
                    b"tlS_LS_1ELS_1EE..." => {
9431
                        Expression::ConversionBraced(
9432
                            TypeHandle::BackReference(0),
9433
                            vec![
9434
                                Expression::Primary(
9435
                                    ExprPrimary::Literal(
9436
                                        TypeHandle::BackReference(0),
9437
                                        7,
9438
                                        8)),
9439
                                Expression::Primary(
9440
                                    ExprPrimary::Literal(
9441
                                        TypeHandle::BackReference(0),
9442
                                        12,
9443
                                        13)),
9444
                            ]),
9445
                        b"...",
9446
                        []
9447
                    }
9448
                    b"ilLS_1EE..." => {
9449
                        Expression::BracedInitList(
9450
                            Box::new(Expression::Primary(
9451
                                ExprPrimary::Literal(
9452
                                    TypeHandle::BackReference(0),
9453
                                    5,
9454
                                    6)))),
9455
                        b"...",
9456
                        []
9457
                    }
9458
                    b"gsnwLS_1E_S_E..." => {
9459
                        Expression::GlobalNew(
9460
                            vec![
9461
                                Expression::Primary(
9462
                                    ExprPrimary::Literal(
9463
                                        TypeHandle::BackReference(0),
9464
                                        7,
9465
                                        8))
9466
                            ],
9467
                            TypeHandle::BackReference(0),
9468
                            None),
9469
                        b"...",
9470
                        []
9471
                    }
9472
                    b"nwLS_1E_S_E..." => {
9473
                        Expression::New(
9474
                            vec![
9475
                                Expression::Primary(
9476
                                    ExprPrimary::Literal(
9477
                                        TypeHandle::BackReference(0),
9478
                                        5,
9479
                                        6))
9480
                            ],
9481
                            TypeHandle::BackReference(0),
9482
                            None),
9483
                        b"...",
9484
                        []
9485
                    }
9486
                    b"gsnwLS_1E_S_piE..." => {
9487
                        Expression::GlobalNew(
9488
                            vec![
9489
                                Expression::Primary(
9490
                                    ExprPrimary::Literal(
9491
                                        TypeHandle::BackReference(0),
9492
                                        7,
9493
                                        8))
9494
                            ],
9495
                            TypeHandle::BackReference(0),
9496
                            Some(Initializer(vec![]))),
9497
                        b"...",
9498
                        []
9499
                    }
9500
                    b"nwLS_1E_S_piE..." => {
9501
                        Expression::New(
9502
                            vec![
9503
                                Expression::Primary(
9504
                                    ExprPrimary::Literal(
9505
                                        TypeHandle::BackReference(0),
9506
                                        5,
9507
                                        6))
9508
                            ],
9509
                            TypeHandle::BackReference(0),
9510
                            Some(Initializer(vec![]))),
9511
                        b"...",
9512
                        []
9513
                    }
9514
                    b"gsnaLS_1E_S_E..." => {
9515
                        Expression::GlobalNewArray(
9516
                            vec![
9517
                                Expression::Primary(
9518
                                    ExprPrimary::Literal(
9519
                                        TypeHandle::BackReference(0),
9520
                                        7,
9521
                                        8))
9522
                            ],
9523
                            TypeHandle::BackReference(0),
9524
                            None),
9525
                        b"...",
9526
                        []
9527
                    }
9528
                    b"naLS_1E_S_E..." => {
9529
                        Expression::NewArray(
9530
                            vec![
9531
                                Expression::Primary(
9532
                                    ExprPrimary::Literal(
9533
                                        TypeHandle::BackReference(0),
9534
                                        5,
9535
                                        6))
9536
                            ],
9537
                            TypeHandle::BackReference(0),
9538
                            None),
9539
                        b"...",
9540
                        []
9541
                    }
9542
                    b"gsnaLS_1E_S_piE..." => {
9543
                        Expression::GlobalNewArray(
9544
                            vec![
9545
                                Expression::Primary(
9546
                                    ExprPrimary::Literal(
9547
                                        TypeHandle::BackReference(0),
9548
                                        7,
9549
                                        8))
9550
                            ],
9551
                            TypeHandle::BackReference(0),
9552
                            Some(Initializer(vec![]))),
9553
                        b"...",
9554
                        []
9555
                    }
9556
                    b"naLS_1E_S_piE..." => {
9557
                        Expression::NewArray(
9558
                            vec![
9559
                                Expression::Primary(
9560
                                    ExprPrimary::Literal(
9561
                                        TypeHandle::BackReference(0),
9562
                                        5,
9563
                                        6))
9564
                            ],
9565
                            TypeHandle::BackReference(0),
9566
                            Some(Initializer(vec![]))),
9567
                        b"...",
9568
                        []
9569
                    }
9570
                    b"gsdlLS_1E..." => {
9571
                        Expression::GlobalDelete(
9572
                            Box::new(Expression::Primary(
9573
                                ExprPrimary::Literal(
9574
                                    TypeHandle::BackReference(0),
9575
                                    7,
9576
                                    8)))),
9577
                        b"...",
9578
                        []
9579
                    }
9580
                    b"dlLS_1E..." => {
9581
                        Expression::Delete(
9582
                            Box::new(Expression::Primary(
9583
                                ExprPrimary::Literal(
9584
                                    TypeHandle::BackReference(0),
9585
                                    5,
9586
                                    6)))),
9587
                        b"...",
9588
                        []
9589
                    }
9590
                    //               ::= [gs] da <expression>                         # delete[] expression
9591
                    b"gsdaLS_1E..." => {
9592
                        Expression::GlobalDeleteArray(
9593
                            Box::new(Expression::Primary(
9594
                                ExprPrimary::Literal(
9595
                                    TypeHandle::BackReference(0),
9596
                                    7,
9597
                                    8)))),
9598
                        b"...",
9599
                        []
9600
                    }
9601
                    b"daLS_1E..." => {
9602
                        Expression::DeleteArray(
9603
                            Box::new(Expression::Primary(
9604
                                ExprPrimary::Literal(
9605
                                    TypeHandle::BackReference(0),
9606
                                    5,
9607
                                    6)))),
9608
                        b"...",
9609
                        []
9610
                    }
9611
                    b"dcS_LS_1E..." => {
9612
                        Expression::DynamicCast(
9613
                            TypeHandle::BackReference(0),
9614
                            Box::new(Expression::Primary(
9615
                                ExprPrimary::Literal(
9616
                                    TypeHandle::BackReference(0),
9617
                                    7,
9618
                                    8)))),
9619
                        b"...",
9620
                        []
9621
                    }
9622
                    b"scS_LS_1E..." => {
9623
                        Expression::StaticCast(
9624
                            TypeHandle::BackReference(0),
9625
                            Box::new(Expression::Primary(
9626
                                ExprPrimary::Literal(
9627
                                    TypeHandle::BackReference(0),
9628
                                    7,
9629
                                    8)))),
9630
                        b"...",
9631
                        []
9632
                    }
9633
                    b"ccS_LS_1E..." => {
9634
                        Expression::ConstCast(
9635
                            TypeHandle::BackReference(0),
9636
                            Box::new(Expression::Primary(
9637
                                ExprPrimary::Literal(
9638
                                    TypeHandle::BackReference(0),
9639
                                    7,
9640
                                    8)))),
9641
                        b"...",
9642
                        []
9643
                    }
9644
                    b"rcS_LS_1E..." => {
9645
                        Expression::ReinterpretCast(
9646
                            TypeHandle::BackReference(0),
9647
                            Box::new(Expression::Primary(
9648
                                ExprPrimary::Literal(
9649
                                    TypeHandle::BackReference(0),
9650
                                    7,
9651
                                    8)))),
9652
                        b"...",
9653
                        []
9654
                    }
9655
                    b"tiS_..." => {
9656
                        Expression::TypeidType(TypeHandle::BackReference(0)),
9657
                        b"...",
9658
                        []
9659
                    }
9660
                    b"teLS_1E..." => {
9661
                        Expression::TypeidExpr(
9662
                            Box::new(Expression::Primary(
9663
                                ExprPrimary::Literal(
9664
                                    TypeHandle::BackReference(0),
9665
                                    5,
9666
                                    6)))),
9667
                        b"...",
9668
                        []
9669
                    }
9670
                    b"stS_..." => {
9671
                        Expression::SizeofType(TypeHandle::BackReference(0)),
9672
                        b"...",
9673
                        []
9674
                    }
9675
                    b"szLS_1E..." => {
9676
                        Expression::SizeofExpr(
9677
                            Box::new(Expression::Primary(
9678
                                ExprPrimary::Literal(
9679
                                    TypeHandle::BackReference(0),
9680
                                    5,
9681
                                    6)))),
9682
                        b"...",
9683
                        []
9684
                    }
9685
                    b"atS_..." => {
9686
                        Expression::AlignofType(TypeHandle::BackReference(0)),
9687
                        b"...",
9688
                        []
9689
                    }
9690
                    b"azLS_1E..." => {
9691
                        Expression::AlignofExpr(
9692
                            Box::new(Expression::Primary(
9693
                                ExprPrimary::Literal(
9694
                                    TypeHandle::BackReference(0),
9695
                                    5,
9696
                                    6)))),
9697
                        b"...",
9698
                        []
9699
                    }
9700
                    b"nxLS_1E..." => {
9701
                        Expression::Noexcept(
9702
                            Box::new(Expression::Primary(
9703
                                ExprPrimary::Literal(
9704
                                    TypeHandle::BackReference(0),
9705
                                    5,
9706
                                    6)))),
9707
                        b"...",
9708
                        []
9709
                    }
9710
                    b"T_..." => {
9711
                        Expression::TemplateParam(TemplateParam(0)),
9712
                        b"...",
9713
                        []
9714
                    }
9715
                    b"fp_..." => {
9716
                        Expression::FunctionParam(FunctionParam(0, CvQualifiers::default(), Some(0))),
9717
                        b"...",
9718
                        []
9719
                    }
9720
                    b"dtT_3abc..." => {
9721
                        Expression::Member(
9722
                            Box::new(Expression::TemplateParam(TemplateParam(0))),
9723
                            MemberName(
9724
                                Name::Unscoped(
9725
                                    UnscopedName::Unqualified(
9726
                                        UnqualifiedName::Source(
9727
                                            SourceName(
9728
                                                Identifier {
9729
                                                    start: 5,
9730
                                                    end: 8,
9731
                                                })))))),
9732
                        b"...",
9733
                        []
9734
                    }
9735
                    b"ptT_3abc..." => {
9736
                        Expression::DerefMember(
9737
                            Box::new(Expression::TemplateParam(TemplateParam(0))),
9738
                            MemberName(
9739
                                Name::Unscoped(
9740
                                    UnscopedName::Unqualified(
9741
                                        UnqualifiedName::Source(
9742
                                            SourceName(
9743
                                                Identifier {
9744
                                                    start: 5,
9745
                                                    end: 8,
9746
                                                })))))),
9747
                        b"...",
9748
                        []
9749
                    }
9750
                    b"dtfp_clI3abcE..." => {
9751
                        Expression::Member(
9752
                            Box::new(Expression::FunctionParam(FunctionParam(0, CvQualifiers::default(), Some(0)))),
9753
                            MemberName(
9754
                                Name::UnscopedTemplate(
9755
                                    UnscopedTemplateNameHandle::NonSubstitution(NonSubstitution(0)),
9756
                                    TemplateArgs(vec![
9757
                                        TemplateArg::Type(
9758
                                            TypeHandle::BackReference(1))])))),
9759
                        b"...",
9760
                        [
9761
                            Substitutable::Type(
9762
                                Type::ClassEnum(
9763
                                    ClassEnumType::Named(
9764
                                        Name::Unscoped(
9765
                                            UnscopedName::Unqualified(
9766
                                                UnqualifiedName::Source(
9767
                                                    SourceName(
9768
                                                        Identifier {
9769
                                                            start: 9,
9770
                                                            end: 12
9771
                                                        })))))))
9772
                        ]
9773
                    }
9774
                    //               ::= ds <expression> <expression>                 # expr.*expr
9775
                    b"dsT_T_..." => {
9776
                        Expression::PointerToMember(
9777
                            Box::new(Expression::TemplateParam(TemplateParam(0))),
9778
                            Box::new(Expression::TemplateParam(TemplateParam(0)))),
9779
                        b"...",
9780
                        []
9781
                    }
9782
                    b"sZT_..." => {
9783
                        Expression::SizeofTemplatePack(TemplateParam(0)),
9784
                        b"...",
9785
                        []
9786
                    }
9787
                    b"sZfp_..." => {
9788
                        Expression::SizeofFunctionPack(
9789
                            FunctionParam(0, CvQualifiers::default(), Some(0))),
9790
                        b"...",
9791
                        []
9792
                    }
9793
                    b"sPE..." => {
9794
                        Expression::SizeofCapturedTemplatePack(vec![]),
9795
                        b"...",
9796
                        []
9797
                    }
9798
                    b"spT_..." => {
9799
                        Expression::PackExpansion(
9800
                            Box::new(Expression::TemplateParam(TemplateParam(0)))),
9801
                        b"...",
9802
                        []
9803
                    }
9804
                    b"twT_..." => {
9805
                        Expression::Throw(Box::new(Expression::TemplateParam(TemplateParam(0)))),
9806
                        b"...",
9807
                        []
9808
                    }
9809
                    b"tr..." => {
9810
                        Expression::Rethrow,
9811
                        b"...",
9812
                        []
9813
                    }
9814
                    b"3abc..." => {
9815
                        Expression::UnresolvedName(
9816
                            UnresolvedName::Name(
9817
                                BaseUnresolvedName::Name(
9818
                                    SimpleId(
9819
                                        SourceName(Identifier {
9820
                                            start: 1,
9821
                                            end: 4,
9822
                                        }),
9823
                                        None)))),
9824
                        b"...",
9825
                        []
9826
                    }
9827
                    b"L_Z3abcE..." => {
9828
                        Expression::Primary(
9829
                            ExprPrimary::External(
9830
                                MangledName::Encoding(
9831
                                    Encoding::Data(
9832
                                        Name::Unscoped(
9833
                                            UnscopedName::Unqualified(
9834
                                                UnqualifiedName::Source(
9835
                                                    SourceName(Identifier {
9836
                                                        start: 4,
9837
                                                        end: 7,
9838
                                                    }))))), vec![]))),
9839
                        b"...",
9840
                        []
9841
                    }
9842
                    // An expression where arity matters
9843
                    b"cldtdefpT4TypeadsrT_5EnterE..." => {
9844
                        Expression::Call(
9845
                            Box::new(Expression::Member(
9846
                                Box::new(Expression::Unary(OperatorName::Simple(SimpleOperatorName::Deref),
9847
                                                           Box::new(Expression::FunctionParam(
9848
                                                               FunctionParam(0,
9849
                                                                             CvQualifiers::default(),
9850
                                                                             None)
9851
                                                           ))
9852
                                )),
9853
                                MemberName(
9854
                                    Name::Unscoped(
9855
                                        UnscopedName::Unqualified(
9856
                                            UnqualifiedName::Source(
9857
                                                SourceName(Identifier {
9858
                                                    start: 10,
9859
                                                    end: 14,
9860
                                                })))
9861
                                     )
9862
                                )
9863
                            )),
9864
                            vec![Expression::Unary(OperatorName::Simple(SimpleOperatorName::AddressOf),
9865
                                                   Box::new(Expression::UnresolvedName(
9866
                                                       UnresolvedName::Nested1(
9867
                                                           UnresolvedTypeHandle::BackReference(1),
9868
                                                           vec![],
9869
                                                           BaseUnresolvedName::Name(
9870
                                                               SimpleId(
9871
                                                                   SourceName(Identifier {
9872
                                                                           start: 21,
9873
                                                                           end: 26
9874
                                                                   }
9875
                                                                   ),
9876
                                                                   None
9877
                                                               )
9878
                                                           )
9879
                                                       ))))]
9880
                        ),
9881
                        b"...",
9882
                        [
9883
                            Substitutable::UnresolvedType(UnresolvedType::Template(TemplateParam(0), None))
9884
                        ]
9885
                    }
9886
                }
9887
                Err => {
9888
                    b"dtStfp_clI3abcE..." => Error::UnexpectedText,
9889
                }
9890
            }
9891
        });
9892
    }
9893
9894
    #[test]
9895
    fn parse_unresolved_name() {
9896
        assert_parse!(UnresolvedName {
9897
            with subs [
9898
                Substitutable::UnresolvedType(
9899
                    UnresolvedType::Decltype(Decltype::Expression(Expression::Rethrow))),
9900
            ] => {
9901
                Ok => {
9902
                    b"gs3abc..." => {
9903
                        UnresolvedName::Global(BaseUnresolvedName::Name(SimpleId(SourceName(Identifier {
9904
                            start: 3,
9905
                            end: 6,
9906
                        }), None))),
9907
                        b"...",
9908
                        []
9909
                    }
9910
                    b"3abc..." => {
9911
                        UnresolvedName::Name(BaseUnresolvedName::Name(SimpleId(SourceName(Identifier {
9912
                            start: 1,
9913
                            end: 4,
9914
                        }), None))),
9915
                        b"...",
9916
                        []
9917
                    }
9918
                    b"srS_3abc..." => {
9919
                        UnresolvedName::Nested1(UnresolvedTypeHandle::BackReference(0),
9920
                                                vec![],
9921
                                                BaseUnresolvedName::Name(SimpleId(SourceName(Identifier {
9922
                                                    start: 5,
9923
                                                    end: 8,
9924
                                                }), None))),
9925
                        b"...",
9926
                        []
9927
                    }
9928
                    b"srNS_3abc3abcE3abc..." => {
9929
                        UnresolvedName::Nested1(
9930
                            UnresolvedTypeHandle::BackReference(0),
9931
                            vec![
9932
                                UnresolvedQualifierLevel(SimpleId(SourceName(Identifier {
9933
                                    start: 6,
9934
                                    end: 9,
9935
                                }), None)),
9936
                                UnresolvedQualifierLevel(SimpleId(SourceName(Identifier {
9937
                                    start: 10,
9938
                                    end: 13,
9939
                                }), None)),
9940
                            ],
9941
                            BaseUnresolvedName::Name(SimpleId(SourceName(Identifier {
9942
                                start: 15,
9943
                                end: 18,
9944
                            }), None))),
9945
                        b"...",
9946
                        []
9947
                    }
9948
                    b"gssr3abcE3abc..." => {
9949
                        UnresolvedName::GlobalNested2(
9950
                            vec![
9951
                                UnresolvedQualifierLevel(SimpleId(SourceName(Identifier {
9952
                                    start: 5,
9953
                                    end: 8,
9954
                                }), None)),
9955
                            ],
9956
                            BaseUnresolvedName::Name(SimpleId(SourceName(Identifier {
9957
                                start: 10,
9958
                                end: 13,
9959
                            }), None))),
9960
                        b"...",
9961
                        []
9962
                    }
9963
                    b"sr3abcE3abc..." => {
9964
                        UnresolvedName::Nested2(
9965
                            vec![
9966
                                UnresolvedQualifierLevel(SimpleId(SourceName(Identifier {
9967
                                    start: 3,
9968
                                    end: 6,
9969
                                }), None)),
9970
                            ],
9971
                            BaseUnresolvedName::Name(SimpleId(SourceName(Identifier {
9972
                                start: 8,
9973
                                end: 11,
9974
                            }), None))),
9975
                        b"...",
9976
                        []
9977
                    }
9978
                }
9979
                Err => {
9980
                    b"zzzzzz" => Error::UnexpectedText,
9981
                    b"gszzz" => Error::UnexpectedText,
9982
                    b"gssrzzz" => Error::UnexpectedText,
9983
                    b"srNzzz" => Error::UnexpectedText,
9984
                    b"srzzz" => Error::UnexpectedText,
9985
                    b"srN3abczzzz" => Error::UnexpectedText,
9986
                    b"srN3abcE" => Error::UnexpectedText,
9987
                    b"srN3abc" => Error::UnexpectedText,
9988
                    b"srN" => Error::UnexpectedEnd,
9989
                    b"sr" => Error::UnexpectedEnd,
9990
                    b"gssr" => Error::UnexpectedEnd,
9991
                    b"gs" => Error::UnexpectedEnd,
9992
                    b"" => Error::UnexpectedEnd,
9993
                }
9994
            }
9995
        });
9996
    }
9997
9998
    #[test]
9999
    fn parse_unresolved_type_handle() {
10000
        assert_parse!(UnresolvedTypeHandle {
10001
            with subs [
10002
                Substitutable::UnresolvedType(
10003
                    UnresolvedType::Decltype(Decltype::Expression(Expression::Rethrow))),
10004
            ] => {
10005
                Ok => {
10006
                    b"S_..." => {
10007
                        UnresolvedTypeHandle::BackReference(0),
10008
                        b"...",
10009
                        []
10010
                    }
10011
                    b"T_..." => {
10012
                        UnresolvedTypeHandle::BackReference(1),
10013
                        b"...",
10014
                        [
10015
                            Substitutable::UnresolvedType(
10016
                                UnresolvedType::Template(TemplateParam(0), None)),
10017
                        ]
10018
                    }
10019
                    b"T_IS_E..." => {
10020
                        UnresolvedTypeHandle::BackReference(1),
10021
                        b"...",
10022
                        [
10023
                            Substitutable::UnresolvedType(
10024
                                UnresolvedType::Template(TemplateParam(0), Some(TemplateArgs(vec![
10025
                                    TemplateArg::Type(TypeHandle::BackReference(0))
10026
                                ])))),
10027
                        ]
10028
                    }
10029
                    b"DTtrE..." => {
10030
                        UnresolvedTypeHandle::BackReference(1),
10031
                        b"...",
10032
                        [
10033
                            Substitutable::UnresolvedType(
10034
                                UnresolvedType::Decltype(Decltype::Expression(Expression::Rethrow)))
10035
                        ]
10036
10037
                    }
10038
                }
10039
                Err => {
10040
                    b"zzzzzzz" => Error::UnexpectedText,
10041
                    b"" => Error::UnexpectedEnd,
10042
                }
10043
            }
10044
        });
10045
    }
10046
10047
    #[test]
10048
    fn parse_unresolved_qualifier_level() {
10049
        assert_parse!(UnresolvedQualifierLevel {
10050
            with subs [
10051
                Substitutable::Type(Type::Decltype(Decltype::Expression(Expression::Rethrow)))
10052
            ] => {
10053
                Ok => {
10054
                    b"3abc..." => {
10055
                        UnresolvedQualifierLevel(SimpleId(SourceName(Identifier {
10056
                            start: 1,
10057
                            end: 4,
10058
                        }), None)),
10059
                        b"...",
10060
                        []
10061
                    }
10062
                    b"3abcIS_E..." => {
10063
                        UnresolvedQualifierLevel(SimpleId(SourceName(Identifier {
10064
                            start: 1,
10065
                            end: 4,
10066
                        }), Some(TemplateArgs(vec![
10067
                            TemplateArg::Type(TypeHandle::BackReference(0))
10068
                        ])))),
10069
                        b"...",
10070
                        []
10071
                    }
10072
                }
10073
                Err => {
10074
                    b"zzz" => Error::UnexpectedText,
10075
                    b"" => Error::UnexpectedEnd,
10076
                }
10077
            }
10078
        });
10079
    }
10080
10081
    #[test]
10082
    fn parse_simple_id() {
10083
        assert_parse!(SimpleId {
10084
            with subs [
10085
                Substitutable::Type(Type::Decltype(Decltype::Expression(Expression::Rethrow)))
10086
            ] => {
10087
                Ok => {
10088
                    b"3abc..." => {
10089
                        SimpleId(SourceName(Identifier {
10090
                            start: 1,
10091
                            end: 4,
10092
                        }), None),
10093
                        b"...",
10094
                        []
10095
                    }
10096
                    b"3abcIS_E..." => {
10097
                        SimpleId(SourceName(Identifier {
10098
                            start: 1,
10099
                            end: 4,
10100
                        }), Some(TemplateArgs(vec![
10101
                            TemplateArg::Type(TypeHandle::BackReference(0))
10102
                        ]))),
10103
                        b"...",
10104
                        []
10105
                    }
10106
                }
10107
                Err => {
10108
                    b"zzz" => Error::UnexpectedText,
10109
                    b"" => Error::UnexpectedEnd,
10110
                }
10111
            }
10112
        });
10113
    }
10114
10115
    #[test]
10116
    fn parse_base_unresolved_name() {
10117
        assert_parse!(BaseUnresolvedName {
10118
            with subs [
10119
                Substitutable::Type(Type::Decltype(Decltype::Expression(Expression::Rethrow)))
10120
            ] => {
10121
                Ok => {
10122
                    b"3abc..." => {
10123
                        BaseUnresolvedName::Name(SimpleId(SourceName(Identifier {
10124
                            start: 1,
10125
                            end: 4,
10126
                        }), None)),
10127
                        b"...",
10128
                        []
10129
                    }
10130
                    b"onnw..." => {
10131
                        BaseUnresolvedName::Operator(OperatorName::Simple(SimpleOperatorName::New), None),
10132
                        b"...",
10133
                        []
10134
                    }
10135
                    b"onnwIS_E..." => {
10136
                        BaseUnresolvedName::Operator(OperatorName::Simple(SimpleOperatorName::New),
10137
                                                     Some(TemplateArgs(vec![
10138
                                                         TemplateArg::Type(TypeHandle::BackReference(0))
10139
                                                     ]))),
10140
                        b"...",
10141
                        []
10142
                    }
10143
                    b"dn3abc..." => {
10144
                        BaseUnresolvedName::Destructor(DestructorName::Name(SimpleId(SourceName(Identifier {
10145
                            start: 3,
10146
                            end: 6,
10147
                        }), None))),
10148
                        b"...",
10149
                        []
10150
                    }
10151
                }
10152
                Err => {
10153
                    b"ozzz" => Error::UnexpectedText,
10154
                    b"dzzz" => Error::UnexpectedText,
10155
                    b"dn" => Error::UnexpectedEnd,
10156
                    b"on" => Error::UnexpectedEnd,
10157
                    b"" => Error::UnexpectedEnd,
10158
                }
10159
            }
10160
        });
10161
    }
10162
10163
    #[test]
10164
    fn parse_destructor_name() {
10165
        assert_parse!(DestructorName {
10166
            with subs [
10167
                Substitutable::UnresolvedType(
10168
                    UnresolvedType::Decltype(Decltype::Expression(Expression::Rethrow))),
10169
            ] => {
10170
                Ok => {
10171
                    b"S_..." => {
10172
                        DestructorName::Unresolved(UnresolvedTypeHandle::BackReference(0)),
10173
                        b"...",
10174
                        []
10175
                    }
10176
                    b"3abc..." => {
10177
                        DestructorName::Name(SimpleId(SourceName(Identifier {
10178
                            start: 1,
10179
                            end: 4,
10180
                        }), None)),
10181
                        b"...",
10182
                        []
10183
                    }
10184
                }
10185
                Err => {
10186
                    b"zzz" => Error::UnexpectedText,
10187
                    b"" => Error::UnexpectedEnd,
10188
                }
10189
            }
10190
        });
10191
    }
10192
10193
    #[test]
10194
    fn parse_expr_primary() {
10195
        assert_parse!(ExprPrimary {
10196
            with subs [
10197
                Substitutable::Type(Type::Decltype(Decltype::Expression(Expression::Rethrow)))
10198
            ] => {
10199
                Ok => {
10200
                    b"LS_12345E..." => {
10201
                        ExprPrimary::Literal(TypeHandle::BackReference(0), 3, 8),
10202
                        b"...",
10203
                        []
10204
                    }
10205
                    b"LS_E..." => {
10206
                        ExprPrimary::Literal(TypeHandle::BackReference(0), 3, 3),
10207
                        b"...",
10208
                        []
10209
                    }
10210
                    b"L_Z3abcE..." => {
10211
                        ExprPrimary::External(
10212
                            MangledName::Encoding(
10213
                                Encoding::Data(
10214
                                    Name::Unscoped(
10215
                                        UnscopedName::Unqualified(
10216
                                            UnqualifiedName::Source(
10217
                                                SourceName(Identifier {
10218
                                                    start: 4,
10219
                                                    end: 7,
10220
                                                }))))), vec![])),
10221
                        b"...",
10222
                        []
10223
                    }
10224
                }
10225
                Err => {
10226
                    b"zzz" => Error::UnexpectedText,
10227
                    b"LS_zzz" => Error::UnexpectedEnd,
10228
                    b"LS_12345" => Error::UnexpectedEnd,
10229
                    b"LS_" => Error::UnexpectedEnd,
10230
                    b"L" => Error::UnexpectedEnd,
10231
                    b"" => Error::UnexpectedEnd,
10232
                }
10233
            }
10234
        });
10235
    }
10236
10237
    #[test]
10238
    fn parse_initializer() {
10239
        assert_parse!(Initializer {
10240
            Ok => {
10241
                b"piE..." => {
10242
                    Initializer(vec![]),
10243
                    b"..."
10244
                }
10245
                b"pitrtrtrE..." => {
10246
                    Initializer(vec![
10247
                        Expression::Rethrow,
10248
                        Expression::Rethrow,
10249
                        Expression::Rethrow,
10250
                    ]),
10251
                    b"..."
10252
                }
10253
            }
10254
            Err => {
10255
                b"pirtrtrt..." => Error::UnexpectedText,
10256
                b"pi..." => Error::UnexpectedText,
10257
                b"..." => Error::UnexpectedText,
10258
                b"pirt" => Error::UnexpectedText,
10259
                b"pi" => Error::UnexpectedEnd,
10260
                b"p" => Error::UnexpectedEnd,
10261
                b"" => Error::UnexpectedEnd,
10262
            }
10263
        });
10264
    }
10265
10266
    #[test]
10267
    fn parse_local_name() {
10268
        assert_parse!(LocalName {
10269
            Ok => {
10270
                b"Z3abcE3def_0..." => {
10271
                    LocalName::Relative(
10272
                        Box::new(Encoding::Data(
10273
                            Name::Unscoped(
10274
                                UnscopedName::Unqualified(
10275
                                    UnqualifiedName::Source(
10276
                                        SourceName(Identifier {
10277
                                            start: 2,
10278
                                            end: 5,
10279
                                        })))))),
10280
                        Some(Box::new(Name::Unscoped(
10281
                            UnscopedName::Unqualified(
10282
                                UnqualifiedName::Source(
10283
                                    SourceName(Identifier {
10284
                                        start: 7,
10285
                                        end: 10,
10286
                                    })))))),
10287
                        Some(Discriminator(0))),
10288
                    b"..."
10289
                }
10290
                b"Z3abcE3def..." => {
10291
                    LocalName::Relative(
10292
                        Box::new(Encoding::Data(
10293
                            Name::Unscoped(
10294
                                UnscopedName::Unqualified(
10295
                                    UnqualifiedName::Source(
10296
                                        SourceName(Identifier {
10297
                                            start: 2,
10298
                                            end: 5,
10299
                                        })))))),
10300
                        Some(Box::new(Name::Unscoped(
10301
                            UnscopedName::Unqualified(
10302
                                UnqualifiedName::Source(
10303
                                    SourceName(Identifier {
10304
                                        start: 7,
10305
                                        end: 10,
10306
                                    })))))),
10307
                        None),
10308
                    b"..."
10309
                }
10310
                b"Z3abcEs_0..." => {
10311
                    LocalName::Relative(
10312
                        Box::new(Encoding::Data(
10313
                            Name::Unscoped(
10314
                                UnscopedName::Unqualified(
10315
                                    UnqualifiedName::Source(
10316
                                        SourceName(Identifier {
10317
                                            start: 2,
10318
                                            end: 5,
10319
                                        })))))),
10320
                        None,
10321
                        Some(Discriminator(0))),
10322
                    b"..."
10323
                }
10324
                b"Z3abcEs..." => {
10325
                    LocalName::Relative(
10326
                        Box::new(Encoding::Data(
10327
                            Name::Unscoped(
10328
                                UnscopedName::Unqualified(
10329
                                    UnqualifiedName::Source(
10330
                                        SourceName(Identifier {
10331
                                            start: 2,
10332
                                            end: 5,
10333
                                        })))))),
10334
                        None,
10335
                        None),
10336
                    b"..."
10337
                }
10338
                b"Z3abcEd1_3abc..." => {
10339
                    LocalName::Default(
10340
                        Box::new(Encoding::Data(
10341
                            Name::Unscoped(
10342
                                UnscopedName::Unqualified(
10343
                                    UnqualifiedName::Source(
10344
                                        SourceName(Identifier {
10345
                                            start: 2,
10346
                                            end: 5,
10347
                                        })))))),
10348
                        Some(1),
10349
                        Box::new(Name::Unscoped(
10350
                            UnscopedName::Unqualified(
10351
                                UnqualifiedName::Source(
10352
                                    SourceName(Identifier {
10353
                                        start: 10,
10354
                                        end: 13,
10355
                                    })))))),
10356
                    b"..."
10357
                }
10358
                b"Z3abcEd_3abc..." => {
10359
                    LocalName::Default(
10360
                        Box::new(Encoding::Data(
10361
                            Name::Unscoped(
10362
                                UnscopedName::Unqualified(
10363
                                    UnqualifiedName::Source(
10364
                                        SourceName(Identifier {
10365
                                            start: 2,
10366
                                            end: 5,
10367
                                        })))))),
10368
                        None,
10369
                        Box::new(Name::Unscoped(
10370
                            UnscopedName::Unqualified(
10371
                                UnqualifiedName::Source(
10372
                                    SourceName(Identifier {
10373
                                        start: 9,
10374
                                        end: 12,
10375
                                    })))))),
10376
                    b"..."
10377
                }
10378
            }
10379
            Err => {
10380
                b"A" => Error::UnexpectedText,
10381
                b"Z1a" => Error::UnexpectedEnd,
10382
                b"Z1aE" => Error::UnexpectedEnd,
10383
                b"Z" => Error::UnexpectedEnd,
10384
                b"" => Error::UnexpectedEnd,
10385
            }
10386
        });
10387
    }
10388
10389
    #[test]
10390
    fn parse_closure_type_name() {
10391
        assert_parse!(ClosureTypeName {
10392
            Ok => {
10393
                b"UlvE_..." => {
10394
                    ClosureTypeName(LambdaSig(vec![]), None),
10395
                    b"..."
10396
                }
10397
                b"UlvE36_..." => {
10398
                    ClosureTypeName(LambdaSig(vec![]), Some(36)),
10399
                    b"..."
10400
                }
10401
            }
10402
            Err => {
10403
                b"UlvE36zzz" => Error::UnexpectedText,
10404
                b"UlvEzzz" => Error::UnexpectedText,
10405
                b"Ulvzzz" => Error::UnexpectedText,
10406
                b"zzz" => Error::UnexpectedText,
10407
                b"UlvE10" => Error::UnexpectedEnd,
10408
                b"UlvE" => Error::UnexpectedEnd,
10409
                b"Ulv" => Error::UnexpectedEnd,
10410
                b"Ul" => Error::UnexpectedEnd,
10411
                b"U" => Error::UnexpectedEnd,
10412
                b"" => Error::UnexpectedEnd,
10413
            }
10414
        });
10415
    }
10416
10417
    #[test]
10418
    fn parse_lambda_sig() {
10419
        assert_parse!(LambdaSig {
10420
            with subs [
10421
                Substitutable::Type(
10422
                    Type::PointerTo(
10423
                        TypeHandle::Builtin(BuiltinType::Standard(StandardBuiltinType::Bool))))
10424
            ] => {
10425
                Ok => {
10426
                    b"v..." => {
10427
                        LambdaSig(vec![]),
10428
                        b"...",
10429
                        []
10430
                    }
10431
                    b"S_S_S_..." => {
10432
                        LambdaSig(vec![
10433
                            TypeHandle::BackReference(0),
10434
                            TypeHandle::BackReference(0),
10435
                            TypeHandle::BackReference(0),
10436
                        ]),
10437
                        b"...",
10438
                        []
10439
                    }
10440
                }
10441
                Err => {
10442
                    b"..." => Error::UnexpectedText,
10443
                    b"S" => Error::UnexpectedEnd,
10444
                    b"" => Error::UnexpectedEnd,
10445
                }
10446
            }
10447
        });
10448
    }
10449
10450
    #[test]
10451
    fn parse_substitution() {
10452
        assert_parse!(Substitution {
10453
            with subs [
10454
                Substitutable::Type(Type::Decltype(Decltype::Expression(Expression::Rethrow))),
10455
                Substitutable::Type(Type::Decltype(Decltype::Expression(Expression::Rethrow))),
10456
                Substitutable::Type(Type::Decltype(Decltype::Expression(Expression::Rethrow)))
10457
            ] => {
10458
                Ok => {
10459
                    b"S_..." => {
10460
                        Substitution::BackReference(0),
10461
                        b"...",
10462
                        []
10463
                    }
10464
                    b"S1_..." => {
10465
                        Substitution::BackReference(2),
10466
                        b"...",
10467
                        []
10468
                    }
10469
                    b"St..." => {
10470
                        Substitution::WellKnown(WellKnownComponent::Std),
10471
                        b"...",
10472
                        []
10473
                    }
10474
                    b"Sa..." => {
10475
                        Substitution::WellKnown(WellKnownComponent::StdAllocator),
10476
                        b"...",
10477
                        []
10478
                    }
10479
                    b"Sb..." => {
10480
                        Substitution::WellKnown(WellKnownComponent::StdString1),
10481
                        b"...",
10482
                        []
10483
                    }
10484
                    b"Ss..." => {
10485
                        Substitution::WellKnown(WellKnownComponent::StdString2),
10486
                        b"...",
10487
                        []
10488
                    }
10489
                    b"Si..." => {
10490
                        Substitution::WellKnown(WellKnownComponent::StdIstream),
10491
                        b"...",
10492
                        []
10493
                    }
10494
                    b"So..." => {
10495
                        Substitution::WellKnown(WellKnownComponent::StdOstream),
10496
                        b"...",
10497
                        []
10498
                    }
10499
                    b"Sd..." => {
10500
                        Substitution::WellKnown(WellKnownComponent::StdIostream),
10501
                        b"...",
10502
                        []
10503
                    }
10504
                }
10505
                Err => {
10506
                    b"S999_" => Error::BadBackReference,
10507
                    b"Sz" => Error::UnexpectedText,
10508
                    b"zzz" => Error::UnexpectedText,
10509
                    b"S1" => Error::UnexpectedEnd,
10510
                    b"S" => Error::UnexpectedEnd,
10511
                    b"" => Error::UnexpectedEnd,
10512
                }
10513
            }
10514
        });
10515
    }
10516
10517
    #[test]
10518
    fn parse_special_name() {
10519
        assert_parse!(SpecialName {
10520
            Ok => {
10521
                b"TVi..." => {
10522
                    SpecialName::VirtualTable(TypeHandle::Builtin(BuiltinType::Standard(StandardBuiltinType::Int))),
10523
                    b"..."
10524
                }
10525
                b"TTi..." => {
10526
                    SpecialName::Vtt(TypeHandle::Builtin(BuiltinType::Standard(StandardBuiltinType::Int))),
10527
                    b"..."
10528
                }
10529
                b"TIi..." => {
10530
                    SpecialName::Typeinfo(TypeHandle::Builtin(BuiltinType::Standard(StandardBuiltinType::Int))),
10531
                    b"..."
10532
                }
10533
                b"TSi..." => {
10534
                    SpecialName::TypeinfoName(TypeHandle::Builtin(BuiltinType::Standard(StandardBuiltinType::Int))),
10535
                    b"..."
10536
                }
10537
                b"Tv42_36_3abc..." => {
10538
                    SpecialName::VirtualOverrideThunk(
10539
                        CallOffset::Virtual(VOffset(42, 36)),
10540
                        Box::new(Encoding::Data(
10541
                            Name::Unscoped(
10542
                                UnscopedName::Unqualified(
10543
                                    UnqualifiedName::Source(
10544
                                        SourceName(Identifier {
10545
                                            start: 9,
10546
                                            end: 12,
10547
                                        }))))))),
10548
                    b"..."
10549
                }
10550
                b"Tcv42_36_v42_36_3abc..." => {
10551
                    SpecialName::VirtualOverrideThunkCovariant(
10552
                        CallOffset::Virtual(VOffset(42, 36)),
10553
                        CallOffset::Virtual(VOffset(42, 36)),
10554
                        Box::new(Encoding::Data(
10555
                            Name::Unscoped(
10556
                                UnscopedName::Unqualified(
10557
                                    UnqualifiedName::Source(
10558
                                        SourceName(Identifier {
10559
                                            start: 17,
10560
                                            end: 20,
10561
                                        }))))))),
10562
                    b"..."
10563
                }
10564
                b"GV3abc..." => {
10565
                    SpecialName::Guard(
10566
                        Name::Unscoped(
10567
                            UnscopedName::Unqualified(
10568
                                UnqualifiedName::Source(
10569
                                    SourceName(Identifier {
10570
                                        start: 3,
10571
                                        end: 6,
10572
                                    }))))),
10573
                    b"..."
10574
                }
10575
                b"GR3abc_..." => {
10576
                    SpecialName::GuardTemporary(
10577
                        Name::Unscoped(
10578
                            UnscopedName::Unqualified(
10579
                                UnqualifiedName::Source(
10580
                                    SourceName(Identifier {
10581
                                        start: 3,
10582
                                        end: 6,
10583
                                    })))),
10584
                        0),
10585
                    b"..."
10586
                }
10587
                b"GR3abc0_..." => {
10588
                    SpecialName::GuardTemporary(
10589
                        Name::Unscoped(
10590
                            UnscopedName::Unqualified(
10591
                                UnqualifiedName::Source(
10592
                                    SourceName(Identifier {
10593
                                        start: 3,
10594
                                        end: 6,
10595
                                    })))),
10596
                        1),
10597
                    b"..."
10598
                }
10599
                b"Gr4_abc..." => {
10600
                    SpecialName::JavaResource(vec![ResourceName {
10601
                        start: 4,
10602
                        end: 7,
10603
                    }]),
10604
                    b"..."
10605
                }
10606
                b"TCc7_i..." => {
10607
                    SpecialName::ConstructionVtable(
10608
                        TypeHandle::Builtin(BuiltinType::Standard(StandardBuiltinType::Char)),
10609
                        7,
10610
                        TypeHandle::Builtin(BuiltinType::Standard(StandardBuiltinType::Int))
10611
                    ),
10612
                    b"..."
10613
                }
10614
                b"TFi..." => {
10615
                    SpecialName::TypeinfoFunction(
10616
                        TypeHandle::Builtin(BuiltinType::Standard(StandardBuiltinType::Int))),
10617
                    b"..."
10618
                }
10619
                b"TH4name..." => {
10620
                    SpecialName::TlsInit(
10621
                        Name::Unscoped(
10622
                            UnscopedName::Unqualified(
10623
                                UnqualifiedName::Source(
10624
                                    SourceName(Identifier { start: 3, end: 7 }))))),
10625
                    b"..."
10626
                }
10627
                b"TW4name..." => {
10628
                    SpecialName::TlsWrapper(
10629
                        Name::Unscoped(
10630
                            UnscopedName::Unqualified(
10631
                                UnqualifiedName::Source(
10632
                                    SourceName(Identifier { start: 3, end: 7 }))))),
10633
                    b"..."
10634
                }
10635
            }
10636
            Err => {
10637
                b"TZ" => Error::UnexpectedText,
10638
                b"GZ" => Error::UnexpectedText,
10639
                b"GR3abcz" => Error::UnexpectedText,
10640
                b"GR3abc0z" => Error::UnexpectedText,
10641
                b"T" => Error::UnexpectedEnd,
10642
                b"G" => Error::UnexpectedEnd,
10643
                b"" => Error::UnexpectedEnd,
10644
                b"GR3abc" => Error::UnexpectedEnd,
10645
                b"GR3abc0" => Error::UnexpectedEnd,
10646
                // This number is not allowed to be negative.
10647
                b"TCcn7_i..." => Error::UnexpectedText,
10648
                b"Gr3abc0" => Error::UnexpectedText,
10649
            }
10650
        });
10651
    }
10652
10653
    #[test]
10654
    fn parse_function_param() {
10655
        assert_parse!(FunctionParam {
10656
            Ok => {
10657
                b"fpK_..." => {
10658
                    FunctionParam(0,
10659
                                  CvQualifiers {
10660
                                      restrict: false,
10661
                                      volatile: false,
10662
                                      const_: true,
10663
                                  },
10664
                                  Some(0)),
10665
                    b"..."
10666
                }
10667
                b"fL1pK_..." => {
10668
                    FunctionParam(1,
10669
                                  CvQualifiers {
10670
                                      restrict: false,
10671
                                      volatile: false,
10672
                                      const_: true,
10673
                                  },
10674
                                  Some(0)),
10675
                    b"..."
10676
                }
10677
                b"fpK3_..." => {
10678
                    FunctionParam(0,
10679
                                  CvQualifiers {
10680
                                      restrict: false,
10681
                                      volatile: false,
10682
                                      const_: true,
10683
                                  },
10684
                                  Some(4)),
10685
                    b"..."
10686
                }
10687
                b"fL1pK4_..." => {
10688
                    FunctionParam(1,
10689
                                  CvQualifiers {
10690
                                      restrict: false,
10691
                                      volatile: false,
10692
                                      const_: true,
10693
                                  },
10694
                                  Some(5)),
10695
                    b"..."
10696
                }
10697
            }
10698
            Err => {
10699
                b"fz" => Error::UnexpectedText,
10700
                b"fLp_" => Error::UnexpectedText,
10701
                b"fpL_" => Error::UnexpectedText,
10702
                b"fL1pK4z" => Error::UnexpectedText,
10703
                b"fL1pK4" => Error::UnexpectedEnd,
10704
                b"fL1p" => Error::UnexpectedEnd,
10705
                b"fL1" => Error::UnexpectedEnd,
10706
                b"fL" => Error::UnexpectedEnd,
10707
                b"f" => Error::UnexpectedEnd,
10708
                b"" => Error::UnexpectedEnd,
10709
            }
10710
        });
10711
    }
10712
10713
    #[test]
10714
    fn parse_discriminator() {
10715
        assert_parse!(Discriminator {
10716
            Ok => {
10717
                b"_0..." => {
10718
                    Discriminator(0),
10719
                    b"..."
10720
                }
10721
                b"_9..." => {
10722
                    Discriminator(9),
10723
                    b"..."
10724
                }
10725
                b"__99_..." => {
10726
                    Discriminator(99),
10727
                    b"..."
10728
                }
10729
            }
10730
            Err => {
10731
                b"_n1" => Error::UnexpectedText,
10732
                b"__99..." => Error::UnexpectedText,
10733
                b"__99" => Error::UnexpectedEnd,
10734
                b"..." => Error::UnexpectedText,
10735
            }
10736
        });
10737
    }
10738
10739
    #[test]
10740
    fn parse_data_member_prefix() {
10741
        assert_parse!(DataMemberPrefix {
10742
            Ok => {
10743
                b"3fooM..." => {
10744
                    DataMemberPrefix(SourceName(Identifier {
10745
                        start: 1,
10746
                        end: 4,
10747
                    })),
10748
                    b"..."
10749
                }
10750
            }
10751
            Err => {
10752
                b"zzz" => Error::UnexpectedText,
10753
                b"1" => Error::UnexpectedEnd,
10754
                b"" => Error::UnexpectedEnd,
10755
            }
10756
        });
10757
    }
10758
10759
    #[test]
10760
    fn parse_ref_qualifier() {
10761
        assert_parse!(RefQualifier {
10762
            Ok => {
10763
                b"R..." => {
10764
                    RefQualifier::LValueRef,
10765
                    b"..."
10766
                }
10767
                b"O..." => {
10768
                    RefQualifier::RValueRef,
10769
                    b"..."
10770
                }
10771
            }
10772
            Err => {
10773
                b"..." => Error::UnexpectedText,
10774
                b"" => Error::UnexpectedEnd,
10775
            }
10776
        });
10777
    }
10778
10779
    #[test]
10780
    fn parse_cv_qualifiers() {
10781
        assert_parse!(CvQualifiers {
10782
            Ok => {
10783
                b"" => {
10784
                    CvQualifiers { restrict: false, volatile: false, const_: false },
10785
                    b""
10786
                }
10787
                b"..." => {
10788
                    CvQualifiers { restrict: false, volatile: false, const_: false },
10789
                    b"..."
10790
                }
10791
                b"r..." => {
10792
                    CvQualifiers { restrict: true, volatile: false, const_: false },
10793
                    b"..."
10794
                }
10795
                b"rV..." => {
10796
                    CvQualifiers { restrict: true, volatile: true, const_: false },
10797
                    b"..."
10798
                }
10799
                b"rVK..." => {
10800
                    CvQualifiers { restrict: true, volatile: true, const_: true },
10801
                    b"..."
10802
                }
10803
                b"V" => {
10804
                    CvQualifiers { restrict: false, volatile: true, const_: false },
10805
                    b""
10806
                }
10807
                b"VK" => {
10808
                    CvQualifiers { restrict: false, volatile: true, const_: true },
10809
                    b""
10810
                }
10811
                b"K..." => {
10812
                    CvQualifiers { restrict: false, volatile: false, const_: true },
10813
                    b"..."
10814
                }
10815
            }
10816
            Err => {
10817
                // None.
10818
            }
10819
        });
10820
    }
10821
10822
    #[test]
10823
    fn parse_builtin_type() {
10824
        assert_parse!(BuiltinType {
10825
            Ok => {
10826
                b"c..." => {
10827
                    BuiltinType::Standard(StandardBuiltinType::Char),
10828
                    b"..."
10829
                }
10830
                b"c" => {
10831
                    BuiltinType::Standard(StandardBuiltinType::Char),
10832
                    b""
10833
                }
10834
                b"u3abc..." => {
10835
                    BuiltinType::Extension(SourceName(Identifier {
10836
                        start: 2,
10837
                        end: 5,
10838
                    })),
10839
                    b"..."
10840
                }
10841
            }
10842
            Err => {
10843
                b"." => Error::UnexpectedText,
10844
                b"" => Error::UnexpectedEnd,
10845
            }
10846
        });
10847
    }
10848
10849
    #[test]
10850
    fn parse_template_param() {
10851
        assert_parse!(TemplateParam {
10852
            Ok => {
10853
                b"T_..." => {
10854
                    TemplateParam(0),
10855
                    b"..."
10856
                }
10857
                b"T3_..." => {
10858
                    TemplateParam(4),
10859
                    b"..."
10860
                }
10861
            }
10862
            Err => {
10863
                b"wtf" => Error::UnexpectedText,
10864
                b"Twtf" => Error::UnexpectedText,
10865
                b"T3wtf" => Error::UnexpectedText,
10866
                b"T" => Error::UnexpectedEnd,
10867
                b"T3" => Error::UnexpectedEnd,
10868
                b"" => Error::UnexpectedEnd,
10869
            }
10870
        });
10871
    }
10872
10873
    #[test]
10874
    fn parse_unscoped_name() {
10875
        assert_parse!(UnscopedName {
10876
            Ok => {
10877
                b"St5hello..." => {
10878
                    UnscopedName::Std(UnqualifiedName::Source(SourceName(Identifier {
10879
                        start: 3,
10880
                        end: 8,
10881
                    }))),
10882
                    b"..."
10883
                }
10884
                b"5hello..." => {
10885
                    UnscopedName::Unqualified(UnqualifiedName::Source(SourceName(Identifier {
10886
                        start: 1,
10887
                        end: 6,
10888
                    }))),
10889
                    b"..."
10890
                }
10891
            }
10892
            Err => {
10893
                b"St..." => Error::UnexpectedText,
10894
                b"..." => Error::UnexpectedText,
10895
                b"" => Error::UnexpectedEnd,
10896
            }
10897
        });
10898
    }
10899
10900
    #[test]
10901
    fn parse_unqualified_name() {
10902
        assert_parse!(UnqualifiedName {
10903
            Ok => {
10904
                b"qu.." => {
10905
                    UnqualifiedName::Operator(OperatorName::Simple(SimpleOperatorName::Question)),
10906
                    b".."
10907
                }
10908
                b"C1.." => {
10909
                    UnqualifiedName::CtorDtor(CtorDtorName::CompleteConstructor(None)),
10910
                    b".."
10911
                }
10912
                b"10abcdefghij..." => {
10913
                    UnqualifiedName::Source(SourceName(Identifier {
10914
                        start: 2,
10915
                        end: 12,
10916
                    })),
10917
                    b"..."
10918
                }
10919
                b"UllE_..." => {
10920
                    UnqualifiedName::ClosureType(
10921
                        ClosureTypeName(
10922
                            LambdaSig(vec![
10923
                                TypeHandle::Builtin(
10924
                                    BuiltinType::Standard(
10925
                                        StandardBuiltinType::Long))
10926
                            ]),
10927
                            None)),
10928
                    b"..."
10929
                }
10930
                b"Ut5_..." => {
10931
                    UnqualifiedName::UnnamedType(UnnamedTypeName(Some(5))),
10932
                    b"..."
10933
                }
10934
                b"B5cxx11..." => {
10935
                    UnqualifiedName::ABITag(TaggedName(SourceName(Identifier {
10936
                        start: 2,
10937
                        end: 7,
10938
                    }))),
10939
                    b"..."
10940
                }
10941
                b"L3foo_0..." => {
10942
                    UnqualifiedName::LocalSourceName(
10943
                        SourceName(Identifier {
10944
                            start: 2,
10945
                            end: 5
10946
                        }),
10947
                        Some(Discriminator(0))
10948
                    ),
10949
                    "..."
10950
                }
10951
                b"L3foo..." => {
10952
                    UnqualifiedName::LocalSourceName(
10953
                        SourceName(Identifier {
10954
                            start: 2,
10955
                            end: 5
10956
                        }),
10957
                        None
10958
                    ),
10959
                    "..."
10960
                }
10961
            }
10962
            Err => {
10963
                b"zzz" => Error::UnexpectedText,
10964
                b"Uq" => Error::UnexpectedText,
10965
                b"C" => Error::UnexpectedEnd,
10966
                b"" => Error::UnexpectedEnd,
10967
            }
10968
        });
10969
    }
10970
10971
    #[test]
10972
    fn parse_unnamed_type_name() {
10973
        assert_parse!(UnnamedTypeName {
10974
            Ok => {
10975
                b"Ut_abc" => {
10976
                    UnnamedTypeName(None),
10977
                    b"abc"
10978
                }
10979
                b"Ut42_abc" => {
10980
                    UnnamedTypeName(Some(42)),
10981
                    b"abc"
10982
                }
10983
                b"Ut42_" => {
10984
                    UnnamedTypeName(Some(42)),
10985
                    b""
10986
                }
10987
            }
10988
            Err => {
10989
                b"ut_" => Error::UnexpectedText,
10990
                b"u" => Error::UnexpectedEnd,
10991
                b"Ut" => Error::UnexpectedEnd,
10992
                b"Ut._" => Error::UnexpectedText,
10993
                b"Ut42" => Error::UnexpectedEnd,
10994
            }
10995
        });
10996
    }
10997
10998
    #[test]
10999
    fn parse_identifier() {
11000
        assert_parse!(Identifier {
11001
            Ok => {
11002
                b"1abc" => {
11003
                    Identifier { start: 0, end: 4 },
11004
                    b""
11005
                }
11006
                b"_Az1\0\0\0" => {
11007
                    Identifier { start: 0, end: 4 },
11008
                    b"\0\0\0"
11009
                }
11010
                b"$_0\0\0\0" => {
11011
                    Identifier { start: 0, end: 3 },
11012
                    b"\0\0\0"
11013
                }
11014
            }
11015
            Err => {
11016
                b"\0\0\0" => Error::UnexpectedText,
11017
                b"" => Error::UnexpectedEnd,
11018
            }
11019
        });
11020
    }
11021
11022
    #[test]
11023
    fn parse_source_name() {
11024
        assert_parse!(SourceName {
11025
            Ok => {
11026
                b"1abc" => {
11027
                    SourceName(Identifier { start: 1, end: 2 }),
11028
                    b"bc"
11029
                }
11030
                b"10abcdefghijklm" => {
11031
                    SourceName(Identifier { start: 2, end: 12 }),
11032
                    b"klm"
11033
                }
11034
            }
11035
            Err => {
11036
                b"0abc" => Error::UnexpectedText,
11037
                b"n1abc" => Error::UnexpectedText,
11038
                b"10abcdef" => Error::UnexpectedEnd,
11039
                b"" => Error::UnexpectedEnd,
11040
            }
11041
        });
11042
    }
11043
11044
    #[test]
11045
    fn parse_number() {
11046
        assert_parse!(Number {
11047
            Ok => {
11048
                b"n2n3" => {
11049
                    -2,
11050
                    b"n3"
11051
                }
11052
                b"12345abcdef" => {
11053
                    12345,
11054
                    b"abcdef"
11055
                }
11056
                b"0abcdef" => {
11057
                    0,
11058
                    b"abcdef"
11059
                }
11060
                b"42" => {
11061
                    42,
11062
                    b""
11063
                }
11064
            }
11065
            Err => {
11066
                b"001" => Error::UnexpectedText,
11067
                b"wutang" => Error::UnexpectedText,
11068
                b"n" => Error::UnexpectedEnd,
11069
                b"" => Error::UnexpectedEnd,
11070
            }
11071
        });
11072
    }
11073
11074
    #[test]
11075
    fn parse_call_offset() {
11076
        assert_parse!(CallOffset {
11077
            Ok => {
11078
                b"hn42_..." => {
11079
                    CallOffset::NonVirtual(NvOffset(-42)),
11080
                    b"..."
11081
                }
11082
                b"vn42_36_..." => {
11083
                    CallOffset::Virtual(VOffset(-42, 36)),
11084
                    b"..."
11085
                }
11086
            }
11087
            Err => {
11088
                b"h1..." => Error::UnexpectedText,
11089
                b"v1_1..." => Error::UnexpectedText,
11090
                b"hh" => Error::UnexpectedText,
11091
                b"vv" => Error::UnexpectedText,
11092
                b"z" => Error::UnexpectedText,
11093
                b"" => Error::UnexpectedEnd,
11094
            }
11095
        });
11096
    }
11097
11098
    #[test]
11099
    fn parse_v_offset() {
11100
        assert_parse!(VOffset {
11101
            Ok => {
11102
                b"n2_n3abcdef" => {
11103
                    VOffset(-2, -3),
11104
                    b"abcdef"
11105
                }
11106
                b"12345_12345abcdef" => {
11107
                    VOffset(12345, 12345),
11108
                    b"abcdef"
11109
                }
11110
                b"0_0abcdef" => {
11111
                    VOffset(0, 0),
11112
                    b"abcdef"
11113
                }
11114
                b"42_n3" => {
11115
                    VOffset(42, -3),
11116
                    b""
11117
                }
11118
            }
11119
            Err => {
11120
                b"001" => Error::UnexpectedText,
11121
                b"1_001" => Error::UnexpectedText,
11122
                b"wutang" => Error::UnexpectedText,
11123
                b"n_" => Error::UnexpectedText,
11124
                b"1_n" => Error::UnexpectedEnd,
11125
                b"1_" => Error::UnexpectedEnd,
11126
                b"n" => Error::UnexpectedEnd,
11127
                b"" => Error::UnexpectedEnd,
11128
            }
11129
        });
11130
    }
11131
11132
    #[test]
11133
    fn parse_nv_offset() {
11134
        assert_parse!(NvOffset {
11135
            Ok => {
11136
                b"n2n3" => {
11137
                    NvOffset(-2),
11138
                    b"n3"
11139
                }
11140
                b"12345abcdef" => {
11141
                    NvOffset(12345),
11142
                    b"abcdef"
11143
                }
11144
                b"0abcdef" => {
11145
                    NvOffset(0),
11146
                    b"abcdef"
11147
                }
11148
                b"42" => {
11149
                    NvOffset(42),
11150
                    b""
11151
                }
11152
            }
11153
            Err => {
11154
                b"001" => Error::UnexpectedText,
11155
                b"wutang" => Error::UnexpectedText,
11156
                b"" => Error::UnexpectedEnd,
11157
            }
11158
        });
11159
    }
11160
11161
    #[test]
11162
    fn parse_seq_id() {
11163
        assert_parse!(SeqId {
11164
            Ok => {
11165
                b"1_" => {
11166
                    SeqId(1),
11167
                    b"_"
11168
                }
11169
                b"42" => {
11170
                    SeqId(146),
11171
                    b""
11172
                }
11173
                b"ABCabc" => {
11174
                    SeqId(13368),
11175
                    b"abc"
11176
                }
11177
            }
11178
            Err => {
11179
                b"abc" => Error::UnexpectedText,
11180
                b"001" => Error::UnexpectedText,
11181
                b"wutang" => Error::UnexpectedText,
11182
                b"" => Error::UnexpectedEnd,
11183
            }
11184
        });
11185
    }
11186
11187
    #[test]
11188
    fn parse_ctor_dtor_name() {
11189
        assert_parse!(CtorDtorName {
11190
            Ok => {
11191
                b"D0" => {
11192
                    CtorDtorName::DeletingDestructor,
11193
                    b""
11194
                }
11195
                b"C101" => {
11196
                    CtorDtorName::CompleteConstructor(None),
11197
                    b"01"
11198
                }
11199
            }
11200
            Err => {
11201
                b"gayagaya" => Error::UnexpectedText,
11202
                b"C" => Error::UnexpectedEnd,
11203
                b"" => Error::UnexpectedEnd,
11204
            }
11205
        });
11206
    }
11207
11208
    #[test]
11209
    fn parse_operator_name() {
11210
        assert_parse!(OperatorName {
11211
            Ok => {
11212
                b"qu..." => {
11213
                    OperatorName::Simple(SimpleOperatorName::Question),
11214
                    b"..."
11215
                }
11216
                b"cvi..." => {
11217
                    OperatorName::Conversion(
11218
                        TypeHandle::Builtin(
11219
                            BuiltinType::Standard(
11220
                                StandardBuiltinType::Int))),
11221
                    b"..."
11222
                }
11223
                b"li3Foo..." => {
11224
                    OperatorName::Literal(SourceName(Identifier {
11225
                        start: 3,
11226
                        end: 6,
11227
                    })),
11228
                    b"..."
11229
                }
11230
                b"v33Foo..." => {
11231
                    OperatorName::VendorExtension(3, SourceName(Identifier {
11232
                        start: 3,
11233
                        end: 6
11234
                    })),
11235
                    b"..."
11236
                }
11237
            }
11238
            Err => {
11239
                b"cv" => Error::UnexpectedEnd,
11240
                b"li3ab" => Error::UnexpectedEnd,
11241
                b"li" => Error::UnexpectedEnd,
11242
                b"v33ab" => Error::UnexpectedEnd,
11243
                b"v3" => Error::UnexpectedEnd,
11244
                b"v" => Error::UnexpectedEnd,
11245
                b"" => Error::UnexpectedEnd,
11246
                b"q" => Error::UnexpectedText,
11247
                b"c" => Error::UnexpectedText,
11248
                b"l" => Error::UnexpectedText,
11249
                b"zzz" => Error::UnexpectedText,
11250
            }
11251
        });
11252
    }
11253
11254
    #[test]
11255
    fn parse_simple_operator_name() {
11256
        assert_parse!(SimpleOperatorName {
11257
            Ok => {
11258
                b"qu" => {
11259
                    SimpleOperatorName::Question,
11260
                    b""
11261
                }
11262
                b"quokka" => {
11263
                    SimpleOperatorName::Question,
11264
                    b"okka"
11265
                }
11266
            }
11267
            Err => {
11268
                b"bu-buuuu" => Error::UnexpectedText,
11269
                b"q" => Error::UnexpectedEnd,
11270
                b"" => Error::UnexpectedEnd,
11271
            }
11272
        });
11273
    }
11274
}