cpp_demangle/
ast.rs

1//! Abstract syntax tree types for mangled symbols.
2
3use super::{DemangleNodeType, DemangleOptions, DemangleWrite, ParseOptions};
4use crate::error::{self, Result};
5use crate::index_str::IndexStr;
6use crate::subs::{Substitutable, SubstitutionTable};
7use alloc::boxed::Box;
8use alloc::string::String;
9use alloc::vec::Vec;
10use core::cell::Cell;
11#[cfg(feature = "logging")]
12use core::cell::RefCell;
13use core::fmt::{self, Write};
14use core::hash::{Hash, Hasher};
15use core::mem;
16use core::ops;
17use core::ptr;
18use core::str;
19
20struct AutoLogParse;
21
22#[cfg(feature = "logging")]
23thread_local! {
24    static LOG_DEPTH: RefCell<usize> = RefCell::new(0);
25}
26
27impl AutoLogParse {
28    #[cfg(feature = "logging")]
29    fn new(production: &'static str, input: IndexStr<'_>) -> AutoLogParse {
30        LOG_DEPTH.with(|depth| {
31            if *depth.borrow() == 0 {
32                println!();
33            }
34
35            let indent: String = (0..*depth.borrow() * 4).map(|_| ' ').collect();
36            log!(
37                "{}({} \"{}\" {}",
38                indent,
39                production,
40                String::from_utf8_lossy(input.as_ref()),
41                input.len(),
42            );
43            *depth.borrow_mut() += 1;
44        });
45        AutoLogParse
46    }
47
48    #[cfg(not(feature = "logging"))]
49    #[inline(always)]
50    fn new(_: &'static str, _: IndexStr) -> AutoLogParse {
51        AutoLogParse
52    }
53}
54
55#[cfg(feature = "logging")]
56impl Drop for AutoLogParse {
57    fn drop(&mut self) {
58        LOG_DEPTH.with(|depth| {
59            *depth.borrow_mut() -= 1;
60            let indent: String = (0..*depth.borrow() * 4).map(|_| ' ').collect();
61            log!("{})", indent);
62        });
63    }
64}
65
66/// Performs the two operations that begin every parse:
67///
68/// 1. Keeps track of recursion levels and early returns with an error if there
69///    is too much recursion.
70///
71/// 2. Automatically log start and end parsing in an s-expression format, when the
72///    `logging` feature is enabled.
73macro_rules! try_begin_parse {
74    ( $production:expr , $ctx:expr , $input:expr ) => {
75        let _log = AutoLogParse::new($production, $input);
76        let _auto_check_recursion = AutoParseRecursion::new($ctx)?;
77    };
78}
79
80struct AutoLogDemangle;
81
82impl AutoLogDemangle {
83    #[cfg(feature = "logging")]
84    fn new<P, W>(
85        production: &P,
86        ctx: &DemangleContext<W>,
87        scope: Option<ArgScopeStack>,
88        is_inner: bool,
89    ) -> AutoLogDemangle
90    where
91        P: ?Sized + fmt::Debug,
92        W: DemangleWrite,
93    {
94        LOG_DEPTH.with(|depth| {
95            if *depth.borrow() == 0 {
96                println!();
97            }
98
99            let indent: String = (0..*depth.borrow() * 4).map(|_| ' ').collect();
100            log!("{}(", indent);
101            log!(
102                "{}  {}{:?}",
103                indent,
104                if is_inner { "as_inner: " } else { "" },
105                production
106            );
107            log!("{}  inner = {:?}", indent, ctx.inner);
108            log!("{}  scope = {:?}", indent, scope);
109
110            *depth.borrow_mut() += 1;
111        });
112        AutoLogDemangle
113    }
114
115    #[cfg(not(feature = "logging"))]
116    #[inline(always)]
117    fn new<P, W>(
118        _: &P,
119        _: &DemangleContext<W>,
120        _: Option<ArgScopeStack>,
121        _: bool,
122    ) -> AutoLogDemangle
123    where
124        P: ?Sized + fmt::Debug,
125        W: DemangleWrite,
126    {
127        AutoLogDemangle
128    }
129}
130
131#[cfg(feature = "logging")]
132impl Drop for AutoLogDemangle {
133    fn drop(&mut self) {
134        LOG_DEPTH.with(|depth| {
135            *depth.borrow_mut() -= 1;
136            let indent: String = (0..*depth.borrow() * 4).map(|_| ' ').collect();
137            log!("{})", indent);
138        });
139    }
140}
141
142/// Automatically log start and end demangling in an s-expression format, when
143/// the `logging` feature is enabled.
144macro_rules! try_begin_demangle {
145    ( $production:expr, $ctx:expr, $scope:expr ) => {{
146        let _log = AutoLogDemangle::new($production, $ctx, $scope, false);
147        &mut AutoParseDemangle::new($ctx)?
148    }};
149}
150
151/// Automatically log start and end demangling in an s-expression format, when
152/// the `logging` feature is enabled.
153macro_rules! try_begin_demangle_as_inner {
154    ( $production:expr, $ctx:expr, $scope:expr ) => {{
155        let _log = AutoLogDemangle::new($production, $ctx, $scope, true);
156        &mut AutoParseDemangle::new($ctx)?
157    }};
158}
159
160#[derive(Debug, Default, Clone, Copy)]
161struct ParseContextState {
162    // The current recursion level. Should always be less than or equal to the
163    // maximum.
164    recursion_level: u32,
165    // Whether or not we are currently parsing a conversion operator.
166    in_conversion: bool,
167}
168
169/// Common context needed when parsing.
170#[derive(Debug, Clone)]
171pub struct ParseContext {
172    // Maximum amount of recursive parsing calls we will allow. If this is too
173    // large, we can blow the stack.
174    max_recursion: u32,
175    // Mutable state within the `ParseContext`.
176    state: Cell<ParseContextState>,
177}
178
179impl ParseContext {
180    /// Construct a new `ParseContext`.
181    pub fn new(options: ParseOptions) -> ParseContext {
182        ParseContext {
183            max_recursion: options.recursion_limit.map(|v| v.get()).unwrap_or(96),
184            state: Cell::new(ParseContextState::default()),
185        }
186    }
187
188    /// Get the current recursion level for this context.
189    pub fn recursion_level(&self) -> u32 {
190        self.state.get().recursion_level
191    }
192
193    #[inline]
194    fn enter_recursion(&self) -> error::Result<()> {
195        let mut state = self.state.get();
196        let new_recursion_level = state.recursion_level + 1;
197
198        if new_recursion_level >= self.max_recursion {
199            log!("Hit too much recursion at level {}", self.max_recursion);
200            Err(error::Error::TooMuchRecursion)
201        } else {
202            state.recursion_level = new_recursion_level;
203            self.state.set(state);
204            Ok(())
205        }
206    }
207
208    #[inline]
209    fn exit_recursion(&self) {
210        let mut state = self.state.get();
211        debug_assert!(state.recursion_level >= 1);
212        state.recursion_level -= 1;
213        self.state.set(state);
214    }
215
216    #[inline]
217    fn in_conversion(&self) -> bool {
218        self.state.get().in_conversion
219    }
220
221    fn set_in_conversion(&self, in_conversion: bool) -> bool {
222        let mut state = self.state.get();
223        let previously_in_conversion = state.in_conversion;
224        state.in_conversion = in_conversion;
225        self.state.set(state);
226        previously_in_conversion
227    }
228}
229
230/// An RAII type to automatically check the recursion level against the
231/// maximum. If the maximum has been crossed, return an error. Otherwise,
232/// increment the level upon construction, and decrement it upon destruction.
233struct AutoParseRecursion<'a>(&'a ParseContext);
234
235impl<'a> AutoParseRecursion<'a> {
236    #[inline]
237    fn new(ctx: &'a ParseContext) -> error::Result<AutoParseRecursion<'a>> {
238        ctx.enter_recursion()?;
239        Ok(AutoParseRecursion(ctx))
240    }
241}
242
243impl<'a> Drop for AutoParseRecursion<'a> {
244    #[inline]
245    fn drop(&mut self) {
246        self.0.exit_recursion();
247    }
248}
249
250/// A trait for anything that can be parsed from an `IndexStr` and return a
251/// `Result` of the parsed `Self` value and the rest of the `IndexStr` input
252/// that has not been consumed in parsing the `Self` value.
253///
254/// For AST types representing productions which have `<substitution>` as a
255/// possible right hand side, do not implement this trait directly. Instead,
256/// make a newtype over `usize`, parse either the `<substitution>` back
257/// reference or "real" value, insert the "real" value into the substitution
258/// table if needed, and *always* return the newtype index into the substitution
259/// table.
260#[doc(hidden)]
261pub trait Parse: Sized {
262    /// Parse the `Self` value from `input` and return it, updating the
263    /// substitution table as needed.
264    fn parse<'a, 'b>(
265        ctx: &'a ParseContext,
266        subs: &'a mut SubstitutionTable,
267        input: IndexStr<'b>,
268    ) -> Result<(Self, IndexStr<'b>)>;
269}
270
271/// Determine whether this AST node is an instantiated[*] template function, and
272/// get its concrete template arguments.
273///
274/// [*] Note that we will never see an abstract, un-instantiated template
275/// function, since they don't end up in object files and don't get mangled
276/// names.
277trait GetTemplateArgs {
278    /// Returns `Some` if this is a template function, `None` otherwise.
279    fn get_template_args<'a>(&'a self, subs: &'a SubstitutionTable) -> Option<&'a TemplateArgs>;
280}
281
282/// A leaf name is the part the name that describes some type or class without
283/// any leading namespace qualifiers.
284///
285/// This is used when figuring out how to format constructors and destructors,
286/// which are formatted as `gooble::dodo::Thing::~Thing()` but we don't have
287/// direct access to `Thing` in the `CtorDtorName` AST.
288#[derive(Debug)]
289pub(crate) enum LeafName<'a> {
290    SourceName(&'a SourceName),
291    WellKnownComponent(&'a WellKnownComponent),
292    Closure(&'a ClosureTypeName),
293    UnnamedType(&'a UnnamedTypeName),
294}
295
296impl<'subs, W> DemangleAsLeaf<'subs, W> for LeafName<'subs>
297where
298    W: 'subs + DemangleWrite,
299{
300    fn demangle_as_leaf<'me, 'ctx>(
301        &'me self,
302        ctx: &'ctx mut DemangleContext<'subs, W>,
303    ) -> fmt::Result {
304        match *self {
305            LeafName::SourceName(sn) => sn.demangle(ctx, None),
306            LeafName::Closure(c) => c.demangle(ctx, None),
307            LeafName::WellKnownComponent(wkc) => wkc.demangle_as_leaf(ctx),
308            LeafName::UnnamedType(utn) => utn.demangle_as_leaf(ctx),
309        }
310    }
311}
312
313/// Determine whether this AST node is some kind (potentially namespaced) name
314/// and if so get its leaf name.
315pub(crate) trait GetLeafName<'a> {
316    fn get_leaf_name(&'a self, subs: &'a SubstitutionTable) -> Option<LeafName<'a>>;
317}
318
319/// Determine whether this AST node is a constructor, destructor, or conversion
320/// function.
321pub(crate) trait IsCtorDtorConversion {
322    fn is_ctor_dtor_conversion(&self, subs: &SubstitutionTable) -> bool;
323}
324
325/// When formatting a mangled symbol's parsed AST as a demangled symbol, we need
326/// to resolve indirect references to template and function arguments with
327/// direct `TemplateArg` and `Type` references respectively.
328///
329/// Note that which set of arguments are implicitly referenced change as we
330/// enter and leave different functions' scope. One might usually use de Brujin
331/// indices to keep arguments within scopes separated from each other, but the
332/// Itanium C++ ABI does not allow us the luxury. AFAIK, when the ABI was first
333/// drafted, C++ did not have lambdas, and the issue did not come up at all
334/// since a function simply couldn't refer to the types of closed over
335/// variables.
336///
337/// This trait is implemented by anything that can potentially resolve arguments
338/// for us.
339trait ArgScope<'me, 'ctx>: fmt::Debug {
340    /// Get the current scope's leaf name.
341    fn leaf_name(&'me self) -> Result<LeafName<'ctx>>;
342
343    /// Get the current scope's `index`th template argument.
344    fn get_template_arg(&'me self, index: usize)
345        -> Result<(&'ctx TemplateArg, &'ctx TemplateArgs)>;
346
347    /// Get the current scope's `index`th function argument's type.
348    fn get_function_arg(&'me self, index: usize) -> Result<&'ctx Type>;
349}
350
351/// An `ArgScopeStack` represents the current function and template demangling
352/// scope we are within. As we enter new demangling scopes, we construct new
353/// `ArgScopeStack`s whose `prev` references point back to the old ones. These
354/// `ArgScopeStack`s are kept on the native stack, and as functions return, they
355/// go out of scope and we use the previous `ArgScopeStack`s again.
356#[derive(Copy, Clone, Debug)]
357pub struct ArgScopeStack<'prev, 'subs>
358where
359    'subs: 'prev,
360{
361    item: &'subs dyn ArgScope<'subs, 'subs>,
362    in_arg: Option<(usize, &'subs TemplateArgs)>,
363    prev: Option<&'prev ArgScopeStack<'prev, 'subs>>,
364}
365
366/// When we first begin demangling, we haven't entered any function or template
367/// demangling scope and we don't have any useful `ArgScopeStack`. Therefore, we
368/// are never actually dealing with `ArgScopeStack` directly in practice, but
369/// always an `Option<ArgScopeStack>` instead. Nevertheless, we want to define
370/// useful methods on `Option<ArgScopeStack>`.
371///
372/// A custom "extension" trait with exactly one implementor: Rust's principled
373/// monkey patching!
374trait ArgScopeStackExt<'prev, 'subs>: Copy {
375    /// Push a new `ArgScope` onto this `ArgScopeStack` and return the new
376    /// `ArgScopeStack` with the pushed resolver on top.
377    fn push(
378        &'prev self,
379        item: &'subs dyn ArgScope<'subs, 'subs>,
380    ) -> Option<ArgScopeStack<'prev, 'subs>>;
381}
382
383impl<'prev, 'subs> ArgScopeStackExt<'prev, 'subs> for Option<ArgScopeStack<'prev, 'subs>> {
384    fn push(
385        &'prev self,
386        item: &'subs dyn ArgScope<'subs, 'subs>,
387    ) -> Option<ArgScopeStack<'prev, 'subs>> {
388        log!("ArgScopeStack::push: {:?}", item);
389        Some(ArgScopeStack {
390            prev: self.as_ref(),
391            in_arg: None,
392            item: item,
393        })
394    }
395}
396
397/// A stack of `ArgScope`s is itself an `ArgScope`!
398impl<'prev, 'subs> ArgScope<'prev, 'subs> for Option<ArgScopeStack<'prev, 'subs>> {
399    fn leaf_name(&'prev self) -> Result<LeafName<'subs>> {
400        let mut scope = self.as_ref();
401        while let Some(s) = scope {
402            if let Ok(c) = s.item.leaf_name() {
403                return Ok(c);
404            }
405            scope = s.prev;
406        }
407        Err(error::Error::BadLeafNameReference)
408    }
409
410    fn get_template_arg(
411        &'prev self,
412        idx: usize,
413    ) -> Result<(&'subs TemplateArg, &'subs TemplateArgs)> {
414        let mut scope = self.as_ref();
415        while let Some(s) = scope {
416            if let Ok((arg, args)) = s.item.get_template_arg(idx) {
417                if let Some((in_idx, in_args)) = s.in_arg {
418                    if args as *const TemplateArgs == in_args as *const TemplateArgs
419                        && in_idx <= idx
420                    {
421                        return Err(error::Error::ForwardTemplateArgReference);
422                    }
423                }
424                return Ok((arg, args));
425            }
426            scope = s.prev;
427        }
428
429        Err(error::Error::BadTemplateArgReference)
430    }
431
432    fn get_function_arg(&'prev self, idx: usize) -> Result<&'subs Type> {
433        let mut scope = self.as_ref();
434        while let Some(s) = scope {
435            if let Ok(arg) = s.item.get_function_arg(idx) {
436                return Ok(arg);
437            }
438            scope = s.prev;
439        }
440
441        Err(error::Error::BadFunctionArgReference)
442    }
443}
444
445#[derive(Debug, Copy, Clone)]
446struct DemangleState {
447    /// How deep in the demangling are we?
448    pub recursion_level: u32,
449}
450
451/// An RAII type to automatically check the recursion level against the
452/// maximum. If the maximum has been crossed, return an error. Otherwise,
453/// increment the level upon construction, and decrement it upon destruction.
454struct AutoParseDemangle<'a, 'b, W: 'a + DemangleWrite>(&'b mut DemangleContext<'a, W>);
455
456impl<'a, 'b, W: 'a + DemangleWrite> AutoParseDemangle<'a, 'b, W> {
457    #[inline]
458    fn new(ctx: &'b mut DemangleContext<'a, W>) -> core::result::Result<Self, fmt::Error> {
459        ctx.enter_recursion()?;
460        Ok(AutoParseDemangle(ctx))
461    }
462}
463
464impl<'a, 'b, W: 'a + DemangleWrite> ops::Deref for AutoParseDemangle<'a, 'b, W> {
465    type Target = DemangleContext<'a, W>;
466
467    fn deref(&self) -> &Self::Target {
468        self.0
469    }
470}
471
472impl<'a, 'b, W: 'a + DemangleWrite> ops::DerefMut for AutoParseDemangle<'a, 'b, W> {
473    fn deref_mut(&mut self) -> &mut Self::Target {
474        self.0
475    }
476}
477
478impl<'a, 'b, W: 'a + DemangleWrite> Drop for AutoParseDemangle<'a, 'b, W> {
479    #[inline]
480    fn drop(&mut self) {
481        self.0.exit_recursion();
482    }
483}
484
485/// Common state that is required when demangling a mangled symbol's parsed AST.
486#[doc(hidden)]
487#[derive(Debug)]
488pub struct DemangleContext<'a, W>
489where
490    W: 'a + DemangleWrite,
491{
492    // The substitution table built up when parsing the mangled symbol into an
493    // AST.
494    subs: &'a SubstitutionTable,
495
496    // The maximum recursion
497    max_recursion: u32,
498
499    // Sometimes an AST node needs to insert itself as an inner item within one
500    // of its children when demangling that child. For example, the AST
501    //
502    //     (array 10 int)
503    //
504    // is demangled as `int[10]`, but if we were to demangle the AST
505    //
506    //     (lvalue-ref (array 10 int))
507    //
508    // then we would want this demangled form: `int (&) [10]`, which requires
509    // the parent lvalue-ref to be passed into the child array's demangling
510    // method. This kind of thing also pops up with function pointers.
511    //
512    // The `inner` stack enables such behavior by allowing us to pass AST
513    // parents down to their children as inner items.
514    inner: Vec<&'a dyn DemangleAsInner<'a, W>>,
515
516    // The original input string.
517    input: &'a [u8],
518
519    // `Identifier`s will be placed here, so `UnnamedTypeName` can utilize and print
520    // out the Constructor/Destructor used.
521    source_name: Option<&'a str>,
522
523    // What the demangled name is being written to.
524    out: &'a mut W,
525
526    // The total number of bytes written to `out`. This is maintained by the
527    // `Write` implementation for `DemangleContext`.
528    bytes_written: usize,
529
530    // The last char written to `out`, if any.
531    last_char_written: Option<char>,
532
533    // We are currently demangling a lambda argument, so template substitution
534    // should be suppressed to match libiberty.
535    is_lambda_arg: bool,
536
537    // We are currently demangling a template-prefix.
538    is_template_prefix: bool,
539
540    // We are currently demangling a template-prefix in a nested-name.
541    is_template_prefix_in_nested_name: bool,
542
543    //  `PackExpansion`'s should only print '...', only when there is no template
544    //  argument pack.
545    is_template_argument_pack: bool,
546
547    // Whether to show function parameters.
548    // This must be set to true before calling `demangle` on `Encoding`
549    // unless that call is via the toplevel call to `MangledName::demangle`.
550    show_params: bool,
551
552    // Whether to show function return types.
553    // This must be set to true before calling `demangle` on `Encoding`
554    // unless that call is via the toplevel call to `MangledName::demangle`.
555    show_return_type: bool,
556
557    // Whether to show types of expression literals.
558    show_expression_literal_types: bool,
559
560    // recursion protection.
561    state: Cell<DemangleState>,
562}
563
564impl<'a, W> fmt::Write for DemangleContext<'a, W>
565where
566    W: 'a + DemangleWrite,
567{
568    fn write_str(&mut self, s: &str) -> fmt::Result {
569        if s.is_empty() {
570            return Ok(());
571        }
572
573        log!("DemangleContext::write: '{}'", s);
574
575        self.out.write_string(s).map(|_| {
576            self.last_char_written = s.chars().last();
577            self.bytes_written += s.len();
578        })
579    }
580}
581
582impl<'a, W> DemangleContext<'a, W>
583where
584    W: 'a + DemangleWrite,
585{
586    /// Construct a new `DemangleContext`.
587    pub fn new(
588        subs: &'a SubstitutionTable,
589        input: &'a [u8],
590        options: DemangleOptions,
591        out: &'a mut W,
592    ) -> DemangleContext<'a, W> {
593        DemangleContext {
594            subs: subs,
595            max_recursion: options.recursion_limit.map(|v| v.get()).unwrap_or(128),
596            inner: vec![],
597            input: input,
598            source_name: None,
599            out: out,
600            bytes_written: 0,
601            last_char_written: None,
602            is_lambda_arg: false,
603            is_template_prefix: false,
604            is_template_prefix_in_nested_name: false,
605            is_template_argument_pack: false,
606            show_params: !options.no_params,
607            show_return_type: !options.no_return_type,
608            show_expression_literal_types: !options.hide_expression_literal_types,
609            state: Cell::new(DemangleState { recursion_level: 0 }),
610        }
611    }
612
613    /// Get the current recursion level for this context.
614    pub fn recursion_level(&self) -> u32 {
615        self.state.get().recursion_level
616    }
617
618    #[inline]
619    fn enter_recursion(&self) -> fmt::Result {
620        let mut state = self.state.get();
621        let new_recursion_level = state.recursion_level + 1;
622
623        if new_recursion_level >= self.max_recursion {
624            log!("Hit too much recursion at level {}", self.max_recursion);
625            Err(Default::default())
626        } else {
627            state.recursion_level = new_recursion_level;
628            self.state.set(state);
629            Ok(())
630        }
631    }
632
633    #[inline]
634    fn exit_recursion(&self) {
635        let mut state = self.state.get();
636        debug_assert!(state.recursion_level >= 1);
637        state.recursion_level -= 1;
638        self.state.set(state);
639    }
640
641    #[inline]
642    fn ensure(&mut self, ch: char) -> fmt::Result {
643        if self.last_char_written == Some(ch) {
644            Ok(())
645        } else {
646            write!(self, "{}", ch)?;
647            Ok(())
648        }
649    }
650
651    #[inline]
652    fn ensure_space(&mut self) -> fmt::Result {
653        self.ensure(' ')
654    }
655
656    #[inline]
657    fn push_inner(&mut self, item: &'a dyn DemangleAsInner<'a, W>) {
658        log!("DemangleContext::push_inner: {:?}", item);
659        self.inner.push(item);
660    }
661
662    #[inline]
663    fn pop_inner(&mut self) -> Option<&'a dyn DemangleAsInner<'a, W>> {
664        let popped = self.inner.pop();
665        log!("DemangleContext::pop_inner: {:?}", popped);
666        popped
667    }
668
669    #[inline]
670    fn pop_inner_if(&mut self, inner: &'a dyn DemangleAsInner<'a, W>) -> bool {
671        let last = match self.inner.last() {
672            None => return false,
673            Some(last) => *last,
674        };
675
676        if ptr::eq(last, inner) {
677            self.inner.pop();
678            true
679        } else {
680            false
681        }
682    }
683
684    fn demangle_inner_prefixes<'prev>(
685        &mut self,
686        scope: Option<ArgScopeStack<'prev, 'a>>,
687    ) -> fmt::Result {
688        log!("DemangleContext::demangle_inner_prefixes");
689        let mut new_inner = vec![];
690        while let Some(inner) = self.pop_inner() {
691            if inner
692                .downcast_to_function_type()
693                .map_or(false, |f| !f.cv_qualifiers.is_empty())
694            {
695                log!(
696                    "DemangleContext::demangle_inner_prefixes: not a prefix, saving: {:?}",
697                    inner
698                );
699                new_inner.push(inner);
700            } else {
701                log!(
702                    "DemangleContext::demangle_inner_prefixes: demangling prefix: {:?}",
703                    inner
704                );
705                inner.demangle_as_inner(self, scope)?;
706            }
707        }
708        new_inner.reverse();
709        self.inner = new_inner;
710        Ok(())
711    }
712
713    fn demangle_inners<'prev>(&mut self, scope: Option<ArgScopeStack<'prev, 'a>>) -> fmt::Result {
714        while let Some(inner) = self.pop_inner() {
715            inner.demangle_as_inner(self, scope)?;
716        }
717        Ok(())
718    }
719
720    fn set_source_name(&mut self, start: usize, end: usize) {
721        let ident = &self.input[start..end];
722        self.source_name = str::from_utf8(ident).ok();
723    }
724
725    fn push_demangle_node(&mut self, t: DemangleNodeType) {
726        self.out.push_demangle_node(t);
727    }
728
729    /// This should not be called on error paths.
730    /// pop_inner_if already doesn't balance if there are errors.
731    fn pop_demangle_node(&mut self) {
732        self.out.pop_demangle_node();
733    }
734}
735
736#[doc(hidden)]
737#[derive(Debug)]
738pub struct AutoDemangleContextInnerBarrier<'ctx, 'a, W>
739where
740    W: 'a + DemangleWrite,
741    'a: 'ctx,
742{
743    ctx: &'ctx mut DemangleContext<'a, W>,
744    saved_inner: Vec<&'a dyn DemangleAsInner<'a, W>>,
745}
746
747impl<'ctx, 'a, W> AutoDemangleContextInnerBarrier<'ctx, 'a, W>
748where
749    W: 'a + DemangleWrite,
750    'a: 'ctx,
751{
752    /// Set aside the current inner stack on the demangle context.
753    pub fn new(ctx: &'ctx mut DemangleContext<'a, W>) -> Self {
754        let mut saved_inner = vec![];
755        mem::swap(&mut saved_inner, &mut ctx.inner);
756        AutoDemangleContextInnerBarrier {
757            ctx: ctx,
758            saved_inner: saved_inner,
759        }
760    }
761}
762
763impl<'ctx, 'a, W> ops::Deref for AutoDemangleContextInnerBarrier<'ctx, 'a, W>
764where
765    W: 'a + DemangleWrite,
766    'a: 'ctx,
767{
768    type Target = DemangleContext<'a, W>;
769
770    fn deref(&self) -> &Self::Target {
771        self.ctx
772    }
773}
774
775impl<'ctx, 'a, W> ops::DerefMut for AutoDemangleContextInnerBarrier<'ctx, 'a, W>
776where
777    W: 'a + DemangleWrite,
778    'a: 'ctx,
779{
780    fn deref_mut(&mut self) -> &mut Self::Target {
781        self.ctx
782    }
783}
784
785impl<'ctx, 'a, W> Drop for AutoDemangleContextInnerBarrier<'ctx, 'a, W>
786where
787    W: 'a + DemangleWrite,
788    'a: 'ctx,
789{
790    fn drop(&mut self) {
791        // NB: We cannot assert that the context's inner is empty here,
792        // because if demangling failed we'll unwind the stack without
793        // using everything that put on the inner.
794        if !self.ctx.inner.is_empty() {
795            log!("Context inner was not emptied, did demangling fail?");
796        }
797        mem::swap(&mut self.saved_inner, &mut self.ctx.inner);
798    }
799}
800
801/// The inner stack allows passing AST nodes down deeper into the tree so that
802/// nodes that logically precede something (e.g. PointerRef) can show up after
803/// that thing in the demangled output. What's on the stack may not always be
804/// intended for the first node that looks at the stack to grab, though.
805///
806/// Consider a function with template arguments and parameters, f<T>(a).
807/// The function parameters logically precede the template arguments in the AST,
808/// but they must be reversed in the output. The parameters end up on the inner
809/// stack before processing the template argument nodes. If we're not careful,
810/// a node inside the template arguments might pick the function parameters
811/// off of the inner stack!
812///
813/// To solve this, certain nodes act as "inner barriers". By using this macro,
814/// they set the existing inner stack aside and replace it with an empty stack
815/// while visiting their children. This allows these barrier nodes to have
816/// completely self-contained children.
817macro_rules! inner_barrier {
818    ( $ctx:ident ) => {
819        let mut _ctx = AutoDemangleContextInnerBarrier::new($ctx);
820        let $ctx = &mut _ctx;
821    };
822}
823
824/// Any AST node that can be printed in a demangled form.
825#[doc(hidden)]
826pub trait Demangle<'subs, W>: fmt::Debug
827where
828    W: 'subs + DemangleWrite,
829{
830    /// Write the demangled form of this AST node to the given context.
831    fn demangle<'prev, 'ctx>(
832        &'subs self,
833        ctx: &'ctx mut DemangleContext<'subs, W>,
834        scope: Option<ArgScopeStack<'prev, 'subs>>,
835    ) -> fmt::Result;
836}
837
838/// Any AST node that can be printed as an inner type.
839///
840/// See the comments surrounding `DemangleContext::inner` for details.
841#[doc(hidden)]
842pub trait DemangleAsInner<'subs, W>: Demangle<'subs, W>
843where
844    W: 'subs + DemangleWrite,
845{
846    /// Write the inner demangling form of this AST node to the given context.
847    fn demangle_as_inner<'prev, 'ctx>(
848        &'subs self,
849        ctx: &'ctx mut DemangleContext<'subs, W>,
850        scope: Option<ArgScopeStack<'prev, 'subs>>,
851    ) -> fmt::Result {
852        self.demangle(ctx, scope)
853    }
854
855    /// Cast this `DemangleAsInner` to a `Type`.
856    fn downcast_to_type(&self) -> Option<&Type> {
857        None
858    }
859
860    /// Cast this `DemangleAsInner` to a `FunctionType`.
861    fn downcast_to_function_type(&self) -> Option<&FunctionType> {
862        None
863    }
864
865    /// Cast this `DemangleAsInner` to an `ArrayType`.
866    fn downcast_to_array_type(&self) -> Option<&ArrayType> {
867        None
868    }
869
870    /// Cast this `DemangleAsInner` to a `PointerToMember`.
871    fn downcast_to_pointer_to_member(&self) -> Option<&PointerToMemberType> {
872        None
873    }
874
875    fn is_qualified(&self) -> bool {
876        false
877    }
878}
879
880/// Demangle this thing in the leaf name position.
881///
882/// For most things this should be the same as its `Demangle`
883/// implementation. For `WellKnownComponent`s we need to strip the embedded
884/// `std::` namespace prefix.
885pub(crate) trait DemangleAsLeaf<'subs, W>
886where
887    W: 'subs + DemangleWrite,
888{
889    fn demangle_as_leaf<'me, 'ctx>(
890        &'me self,
891        ctx: &'ctx mut DemangleContext<'subs, W>,
892    ) -> fmt::Result;
893}
894
895macro_rules! reference_newtype {
896    ( $newtype_name:ident , $oldtype:ty ) => {
897        #[derive(Debug)]
898        struct $newtype_name($oldtype);
899
900        impl $newtype_name {
901            #[allow(clippy::ptr_arg)]
902            #[allow(unsafe_code)]
903            fn new(types: &$oldtype) -> &$newtype_name {
904                unsafe {
905                    // This is safe because we only create an immutable
906                    // reference. We are not breaking unique mutable aliasing
907                    // requirements. An immutable reference does not allow
908                    // dropping the referent, so no worries about double-free
909                    // (additionally, see the assertion inside `Drop` below).
910                    &*(types as *const $oldtype as *const $newtype_name)
911                }
912            }
913        }
914
915        impl Drop for $newtype_name {
916            fn drop(&mut self) {
917                unreachable!(
918                    "Dropping implies we dereferenced and took ownership, which \
919                              is not safe for this newtype"
920                );
921            }
922        }
923
924        impl ops::Deref for $newtype_name {
925            type Target = $oldtype;
926
927            fn deref(&self) -> &Self::Target {
928                &self.0
929            }
930        }
931    };
932}
933
934// We can't implement `DemangleAsInner` for newtypes of `[TypeHandle]` like we
935// want to because it is unsized and we need to make trait objects out of
936// `DemangleAsInner` for pushing onto the context's inner stack. Therefore, we
937// have this inelegant newtyping of `Vec<TypeHandle>`.
938
939// A set of function arguments.
940reference_newtype!(FunctionArgList, Vec<TypeHandle>);
941
942// A set of function arguments prefixed by a return type (which we want to
943// ignore).
944reference_newtype!(FunctionArgListAndReturnType, Vec<TypeHandle>);
945
946// A newtype around a slice of type handles that we format as function
947// arguments.
948reference_newtype!(FunctionArgSlice, [TypeHandle]);
949
950// Demangle a slice of TypeHandle as a function argument list.
951impl<'subs, W> Demangle<'subs, W> for FunctionArgSlice
952where
953    W: 'subs + DemangleWrite,
954{
955    fn demangle<'prev, 'ctx>(
956        &'subs self,
957        ctx: &'ctx mut DemangleContext<'subs, W>,
958        scope: Option<ArgScopeStack<'prev, 'subs>>,
959    ) -> fmt::Result {
960        let ctx = try_begin_demangle!(self, ctx, scope);
961
962        let mut saw_needs_paren = false;
963        let (needs_space, needs_paren) = ctx
964            .inner
965            .iter()
966            .rev()
967            .map(|inner| {
968                if inner.downcast_to_pointer_to_member().is_some() {
969                    (true, true)
970                } else {
971                    match inner.downcast_to_type() {
972                        Some(&Type::Qualified(..))
973                        | Some(&Type::Complex(_))
974                        | Some(&Type::Imaginary(_))
975                        | Some(&Type::PointerToMember(_)) => (true, true),
976                        Some(&Type::PointerTo(_))
977                        | Some(&Type::LvalueRef(_))
978                        | Some(&Type::RvalueRef(_)) => (false, true),
979                        _ => (false, false),
980                    }
981                }
982            })
983            .take_while(|&(_, needs_paren)| {
984                if saw_needs_paren {
985                    false
986                } else {
987                    saw_needs_paren |= needs_paren;
988                    true
989                }
990            })
991            .fold(
992                (false, false),
993                |(space, paren), (next_space, next_paren)| {
994                    (space || next_space, paren || next_paren)
995                },
996            );
997
998        if needs_paren {
999            let needs_space = needs_space
1000                || match ctx.last_char_written {
1001                    Some('(') | Some('*') => false,
1002                    _ => true,
1003                };
1004
1005            if needs_space {
1006                ctx.ensure_space()?;
1007            }
1008
1009            write!(ctx, "(")?;
1010        }
1011
1012        ctx.demangle_inner_prefixes(scope)?;
1013
1014        if needs_paren {
1015            write!(ctx, ")")?;
1016        }
1017
1018        write!(ctx, "(")?;
1019
1020        // To maintain compatibility with libiberty, print `()` instead of
1021        // `(void)` for functions that take no arguments.
1022        if self.len() == 1 && self[0].is_void() {
1023            write!(ctx, ")")?;
1024            return Ok(());
1025        }
1026
1027        let mut need_comma = false;
1028        for arg in self.iter() {
1029            if need_comma {
1030                write!(ctx, ", ")?;
1031            }
1032            arg.demangle(ctx, scope)?;
1033            need_comma = true;
1034        }
1035
1036        write!(ctx, ")")?;
1037
1038        ctx.demangle_inners(scope)
1039    }
1040}
1041
1042impl<'subs, W> Demangle<'subs, W> for FunctionArgList
1043where
1044    W: 'subs + DemangleWrite,
1045{
1046    fn demangle<'prev, 'ctx>(
1047        &'subs self,
1048        ctx: &'ctx mut DemangleContext<'subs, W>,
1049        scope: Option<ArgScopeStack<'prev, 'subs>>,
1050    ) -> fmt::Result {
1051        FunctionArgSlice::new(&self.0[..]).demangle(ctx, scope)
1052    }
1053}
1054
1055impl<'subs, W> DemangleAsInner<'subs, W> for FunctionArgList where W: 'subs + DemangleWrite {}
1056
1057impl<'subs, W> Demangle<'subs, W> for FunctionArgListAndReturnType
1058where
1059    W: 'subs + DemangleWrite,
1060{
1061    fn demangle<'prev, 'ctx>(
1062        &'subs self,
1063        ctx: &'ctx mut DemangleContext<'subs, W>,
1064        scope: Option<ArgScopeStack<'prev, 'subs>>,
1065    ) -> fmt::Result {
1066        FunctionArgSlice::new(&self.0[1..]).demangle(ctx, scope)
1067    }
1068}
1069
1070impl<'subs, W> DemangleAsInner<'subs, W> for FunctionArgListAndReturnType where
1071    W: 'subs + DemangleWrite
1072{
1073}
1074
1075/// Define a handle to a AST type that lives inside the substitution table. A
1076/// handle is always either an index into the substitution table, or it is a
1077/// reference to a "well-known" component.
1078///
1079/// This declares:
1080///
1081/// - The enum of either a back reference into the substitution table or a
1082///   reference to a "well-known" component
1083/// - a `Demangle` impl that proxies to the appropriate `Substitutable` in the
1084///   `SubstitutionTable`
1085macro_rules! define_handle {
1086    (
1087        $(#[$attr:meta])*
1088        pub enum $typename:ident
1089    ) => {
1090        define_handle! {
1091            $(#[$attr])*
1092            pub enum $typename {}
1093        }
1094    };
1095
1096    (
1097        $(#[$attr:meta])*
1098        pub enum $typename:ident {
1099            $(
1100                $( #[$extra_attr:meta] )*
1101                extra $extra_variant:ident ( $extra_variant_ty:ty ),
1102            )*
1103        }
1104    ) => {
1105        $(#[$attr])*
1106        #[derive(Clone, Debug, PartialEq, Eq)]
1107        pub enum $typename {
1108            /// A reference to a "well-known" component.
1109            WellKnown(WellKnownComponent),
1110
1111            /// A back-reference into the substitution table to a component we
1112            /// have already parsed.
1113            BackReference(usize),
1114
1115            $(
1116                $( #[$extra_attr] )*
1117                $extra_variant( $extra_variant_ty ),
1118            )*
1119        }
1120
1121        impl $typename {
1122            /// If this is a `BackReference`, get its index.
1123            pub fn back_reference(&self) -> Option<usize> {
1124                match *self {
1125                    $typename::BackReference(n) => Some(n),
1126                    _ => None,
1127                }
1128            }
1129        }
1130
1131        impl<'subs, W> Demangle<'subs, W> for $typename
1132        where
1133            W: 'subs + DemangleWrite
1134        {
1135            #[inline]
1136            fn demangle<'prev, 'ctx>(&'subs self,
1137                                     ctx: &'ctx mut DemangleContext<'subs, W>,
1138                                     scope: Option<ArgScopeStack<'prev, 'subs>>)
1139                                     -> fmt::Result {
1140                match *self {
1141                    $typename::WellKnown(ref comp) => comp.demangle(ctx, scope),
1142                    $typename::BackReference(idx) => ctx.subs[idx].demangle(ctx, scope),
1143                    $(
1144                        $typename::$extra_variant(ref extra) => extra.demangle(ctx, scope),
1145                    )*
1146                }
1147            }
1148        }
1149
1150        impl<'a> GetLeafName<'a> for $typename {
1151            fn get_leaf_name(&'a self, subs: &'a SubstitutionTable) -> Option<LeafName<'a>> {
1152                match *self {
1153                    $typename::WellKnown(ref wk) => wk.get_leaf_name(subs),
1154                    $typename::BackReference(idx) => {
1155                        subs.get(idx).and_then(|s| s.get_leaf_name(subs))
1156                    }
1157                    $(
1158                        $typename::$extra_variant(ref e) => e.get_leaf_name(subs),
1159                    )*
1160                }
1161            }
1162        }
1163    };
1164}
1165
1166/// A handle to a component that is usually substitutable, and lives in the
1167/// substitutions table, but in this particular case does not qualify for
1168/// substitutions.
1169#[derive(Clone, Debug, PartialEq, Eq)]
1170pub struct NonSubstitution(usize);
1171
1172impl<'subs, W> Demangle<'subs, W> for NonSubstitution
1173where
1174    W: 'subs + DemangleWrite,
1175{
1176    fn demangle<'prev, 'ctx>(
1177        &'subs self,
1178        ctx: &'ctx mut DemangleContext<'subs, W>,
1179        scope: Option<ArgScopeStack<'prev, 'subs>>,
1180    ) -> fmt::Result {
1181        ctx.subs.non_substitution(self.0).demangle(ctx, scope)
1182    }
1183}
1184
1185impl<'a> GetLeafName<'a> for NonSubstitution {
1186    fn get_leaf_name(&'a self, subs: &'a SubstitutionTable) -> Option<LeafName<'a>> {
1187        subs.get_non_substitution(self.0)
1188            .and_then(|ns| ns.get_leaf_name(subs))
1189    }
1190}
1191
1192/// Define a "vocabulary" nonterminal, something like `OperatorName` or
1193/// `CtorDtorName` that's basically a big list of constant strings.
1194///
1195/// This declares:
1196///
1197/// - the enum itself
1198/// - a `Parse` impl
1199/// - a `Demangle` impl
1200///
1201/// See the definition of `CTorDtorName` for an example of its use.
1202///
1203/// Optionally, a piece of user data can be attached to the definitions
1204/// and be returned by a generated accessor. See `SimpleOperatorName` for
1205/// an example.
1206macro_rules! define_vocabulary {
1207    ( $(#[$attr:meta])* pub enum $typename:ident {
1208        $($variant:ident ( $mangled:expr, $printable:expr )),*
1209    } ) => {
1210
1211        $(#[$attr])*
1212        pub enum $typename {
1213            $(
1214                #[doc=$printable]
1215                $variant
1216            ),*
1217        }
1218
1219        impl Parse for $typename {
1220            fn parse<'a, 'b>(ctx: &'a ParseContext,
1221                             _subs: &'a mut SubstitutionTable,
1222                             input: IndexStr<'b>)
1223                             -> Result<($typename, IndexStr<'b>)> {
1224                try_begin_parse!(stringify!($typename), ctx, input);
1225
1226                let mut found_prefix = false;
1227                $(
1228                    if let Some((head, tail)) = input.try_split_at($mangled.len()) {
1229                        if head.as_ref() == $mangled {
1230                            return Ok(($typename::$variant, tail));
1231                        }
1232                    } else {
1233                        found_prefix |= 0 < input.len() &&
1234                            input.len() < $mangled.len() &&
1235                            input.as_ref() == &$mangled[..input.len()];
1236                    }
1237                )*
1238
1239                if input.is_empty() || found_prefix {
1240                    Err(error::Error::UnexpectedEnd)
1241                } else {
1242                    Err(error::Error::UnexpectedText)
1243                }
1244            }
1245        }
1246
1247        impl<'subs, W> Demangle<'subs, W> for $typename
1248        where
1249            W: 'subs + DemangleWrite,
1250        {
1251            fn demangle<'prev, 'ctx>(
1252                &'subs self,
1253                ctx: &'ctx mut DemangleContext<'subs, W>,
1254                scope: Option<ArgScopeStack<'prev, 'subs>>
1255            ) -> fmt::Result {
1256                let ctx = try_begin_demangle!(self, ctx, scope);
1257
1258                write!(ctx, "{}", match *self {
1259                    $(
1260                        $typename::$variant => $printable
1261                    ),*
1262                })
1263            }
1264        }
1265
1266        impl $typename {
1267            #[allow(dead_code)]
1268            #[inline]
1269            fn starts_with(byte: u8) -> bool {
1270                $(
1271                    if $mangled[0] == byte {
1272                        return true;
1273                    }
1274                )*
1275
1276                false
1277            }
1278        }
1279    };
1280    ( $(#[$attr:meta])* pub enum $typename:ident {
1281        $($variant:ident ( $mangled:expr, $printable:expr, $userdata:expr)),*
1282    }
1283
1284      impl $typename2:ident {
1285          fn $fn_name:ident(&self) -> $userdata_ty:ty;
1286    } ) => {
1287        define_vocabulary! {
1288            $(#[$attr])*
1289            pub enum $typename {
1290                $(
1291                    $variant ( $mangled, $printable )
1292                ),*
1293            }
1294        }
1295
1296        impl $typename2 {
1297            fn $fn_name(&self) -> $userdata_ty {
1298                match *self {
1299                    $(
1300                        $typename2::$variant => $userdata,
1301                    )*
1302                }
1303            }
1304        }
1305    };
1306}
1307
1308/// The root AST node, and starting production.
1309///
1310/// ```text
1311/// <mangled-name> ::= _Z <encoding> [<clone-suffix>]*
1312///                ::= ___Z <encoding> <block_invoke>
1313///                ::= <type>
1314///
1315/// <block_invoke> ::= _block_invoke
1316///                ::= _block_invoke<decimal-digit>+
1317///                ::= _block_invoke_<decimal-digit>+
1318/// ```
1319#[derive(Clone, Debug, PartialEq, Eq)]
1320pub enum MangledName {
1321    /// The encoding of the mangled symbol name.
1322    Encoding(Encoding, Vec<CloneSuffix>),
1323
1324    /// The encoding of the mangled symbol name.
1325    BlockInvoke(Encoding, Option<isize>),
1326
1327    /// A top-level type. Technically not allowed by the standard, however in
1328    /// practice this can happen, and is tested for by libiberty.
1329    Type(TypeHandle),
1330
1331    /// A global constructor or destructor. This is another de facto standard
1332    /// extension (I think originally from `g++`?) that is not actually part of
1333    /// the standard proper.
1334    GlobalCtorDtor(GlobalCtorDtor),
1335}
1336
1337impl Parse for MangledName {
1338    fn parse<'a, 'b>(
1339        ctx: &'a ParseContext,
1340        subs: &'a mut SubstitutionTable,
1341        input: IndexStr<'b>,
1342    ) -> Result<(MangledName, IndexStr<'b>)> {
1343        try_begin_parse!("MangledName", ctx, input);
1344
1345        if let Ok(tail) = consume(b"_Z", input).or_else(|_| consume(b"__Z", input)) {
1346            let (encoding, tail) = Encoding::parse(ctx, subs, tail)?;
1347            let (clone_suffixes, tail) = zero_or_more(ctx, subs, tail)?;
1348            return Ok((MangledName::Encoding(encoding, clone_suffixes), tail));
1349        }
1350
1351        if let Ok(tail) = consume(b"___Z", input).or_else(|_| consume(b"____Z", input)) {
1352            let (encoding, tail) = Encoding::parse(ctx, subs, tail)?;
1353            let tail = consume(b"_block_invoke", tail)?;
1354
1355            let tail_opt = match consume(b"_", tail).or_else(|_| consume(b".", tail)) {
1356                Ok(tail) => Some(parse_number(10, false, tail)?),
1357                Err(_) => parse_number(10, false, tail).ok(),
1358            };
1359
1360            let (digits, tail) = match tail_opt {
1361                Some((digits, tail)) => (Some(digits), tail),
1362                None => (None, tail),
1363            };
1364
1365            return Ok((MangledName::BlockInvoke(encoding, digits), tail));
1366        }
1367
1368        if let Ok(tail) = consume(b"_GLOBAL_", input) {
1369            let (global_ctor_dtor, tail) = GlobalCtorDtor::parse(ctx, subs, tail)?;
1370            return Ok((MangledName::GlobalCtorDtor(global_ctor_dtor), tail));
1371        }
1372
1373        // The libiberty tests also specify that a type can be top level,
1374        // and they are not prefixed with "_Z".
1375        let (ty, tail) = TypeHandle::parse(ctx, subs, input)?;
1376        Ok((MangledName::Type(ty), tail))
1377    }
1378}
1379
1380impl<'subs, W> Demangle<'subs, W> for MangledName
1381where
1382    W: 'subs + DemangleWrite,
1383{
1384    fn demangle<'prev, 'ctx>(
1385        &'subs self,
1386        ctx: &'ctx mut DemangleContext<'subs, W>,
1387        scope: Option<ArgScopeStack<'prev, 'subs>>,
1388    ) -> fmt::Result {
1389        let ctx = try_begin_demangle!(self, ctx, scope);
1390
1391        match *self {
1392            MangledName::Encoding(ref enc, ref cs) => {
1393                enc.demangle(ctx, scope)?;
1394                if !cs.is_empty() && ctx.show_params {
1395                    for clone_suffix in cs {
1396                        clone_suffix.demangle(ctx, scope)?;
1397                    }
1398                }
1399                Ok(())
1400            }
1401            MangledName::BlockInvoke(ref enc, _) => {
1402                write!(ctx, "invocation function for block in ")?;
1403                enc.demangle(ctx, scope)?;
1404                Ok(())
1405            }
1406            MangledName::Type(ref ty) => ty.demangle(ctx, scope),
1407            MangledName::GlobalCtorDtor(ref gcd) => gcd.demangle(ctx, scope),
1408        }
1409    }
1410}
1411
1412/// The `<encoding>` production.
1413///
1414/// ```text
1415/// <encoding> ::= <function name> <bare-function-type>
1416///            ::= <data name>
1417///            ::= <special-name>
1418/// ```
1419#[derive(Clone, Debug, PartialEq, Eq)]
1420pub enum Encoding {
1421    /// An encoded function.
1422    Function(Name, BareFunctionType),
1423
1424    /// An encoded static variable.
1425    Data(Name),
1426
1427    /// A special encoding.
1428    Special(SpecialName),
1429}
1430
1431impl Parse for Encoding {
1432    fn parse<'a, 'b>(
1433        ctx: &'a ParseContext,
1434        subs: &'a mut SubstitutionTable,
1435        input: IndexStr<'b>,
1436    ) -> Result<(Encoding, IndexStr<'b>)> {
1437        try_begin_parse!("Encoding", ctx, input);
1438
1439        if let Ok((name, tail)) = Name::parse(ctx, subs, input) {
1440            if let Ok((ty, tail)) = BareFunctionType::parse(ctx, subs, tail) {
1441                return Ok((Encoding::Function(name, ty), tail));
1442            } else {
1443                return Ok((Encoding::Data(name), tail));
1444            }
1445        }
1446
1447        let (name, tail) = SpecialName::parse(ctx, subs, input)?;
1448        Ok((Encoding::Special(name), tail))
1449    }
1450}
1451
1452impl<'subs, W> Demangle<'subs, W> for Encoding
1453where
1454    W: 'subs + DemangleWrite,
1455{
1456    fn demangle<'prev, 'ctx>(
1457        &'subs self,
1458        ctx: &'ctx mut DemangleContext<'subs, W>,
1459        scope: Option<ArgScopeStack<'prev, 'subs>>,
1460    ) -> fmt::Result {
1461        let ctx = try_begin_demangle!(self, ctx, scope);
1462        inner_barrier!(ctx);
1463
1464        match *self {
1465            Encoding::Function(ref name, ref fun_ty) => {
1466                // Even if this function takes no args and doesn't have a return
1467                // value (see below), it will have the void parameter.
1468                debug_assert!(!fun_ty.0.is_empty());
1469
1470                let scope = if let Some(leaf) = name.get_leaf_name(ctx.subs) {
1471                    match leaf {
1472                        LeafName::SourceName(leaf) => scope.push(leaf),
1473                        LeafName::WellKnownComponent(leaf) => scope.push(leaf),
1474                        LeafName::Closure(leaf) => scope.push(leaf),
1475                        LeafName::UnnamedType(leaf) => scope.push(leaf),
1476                    }
1477                } else {
1478                    scope
1479                };
1480
1481                // Whether the first type in the BareFunctionType is a return
1482                // type or parameter depends on the context in which it
1483                // appears.
1484                //
1485                // * Templates and functions in a type or parameter position
1486                // have return types, unless they are constructors, destructors,
1487                // or conversion operator functions.
1488                //
1489                // * Non-template functions that are not in a type or parameter
1490                // position do not have a return type.
1491                //
1492                // We know we are not printing a type, so we only need to check
1493                // whether this is a template.
1494                //
1495                // For the details, see
1496                // https://itanium-cxx-abi.github.io/cxx-abi/abi.html#mangle.function-type
1497                let scope = if let Some(template_args) = name.get_template_args(ctx.subs) {
1498                    let scope = scope.push(template_args);
1499                    if ctx.show_return_type && !name.is_ctor_dtor_conversion(ctx.subs) {
1500                        fun_ty.0[0].demangle(ctx, scope)?;
1501                        write!(ctx, " ")?;
1502                    }
1503
1504                    scope
1505                } else {
1506                    scope
1507                };
1508
1509                if ctx.show_params {
1510                    ctx.push_inner(self);
1511                    name.demangle(ctx, scope)?;
1512                    if ctx.pop_inner_if(self) {
1513                        self.demangle_as_inner(ctx, scope)?;
1514                    }
1515                } else {
1516                    name.demangle(ctx, scope)?;
1517                }
1518
1519                Ok(())
1520            }
1521            Encoding::Data(ref name) => name.demangle(ctx, scope),
1522            Encoding::Special(ref name) => name.demangle(ctx, scope),
1523        }
1524    }
1525}
1526
1527impl<'subs, W> DemangleAsInner<'subs, W> for Encoding
1528where
1529    W: 'subs + DemangleWrite,
1530{
1531    fn demangle_as_inner<'prev, 'ctx>(
1532        &'subs self,
1533        ctx: &'ctx mut DemangleContext<'subs, W>,
1534        scope: Option<ArgScopeStack<'prev, 'subs>>,
1535    ) -> fmt::Result {
1536        if let Encoding::Function(ref name, ref fun_ty) = *self {
1537            let (scope, function_args) =
1538                if let Some(template_args) = name.get_template_args(ctx.subs) {
1539                    let scope = scope.push(template_args);
1540                    let function_args = FunctionArgListAndReturnType::new(&fun_ty.0);
1541                    (scope, function_args as &dyn DemangleAsInner<W>)
1542                } else {
1543                    let function_args = FunctionArgList::new(&fun_ty.0);
1544                    (scope, function_args as &dyn DemangleAsInner<W>)
1545                };
1546            function_args.demangle_as_inner(ctx, scope)
1547        } else {
1548            unreachable!("we only push Encoding::Function onto the inner stack");
1549        }
1550    }
1551}
1552
1553/// <clone-suffix> ::= [ . <clone-type-identifier> ] [ . <nonnegative number> ]*
1554
1555#[derive(Clone, Debug, PartialEq, Eq)]
1556pub struct CloneSuffix(CloneTypeIdentifier, Vec<isize>);
1557
1558impl Parse for CloneSuffix {
1559    fn parse<'a, 'b>(
1560        ctx: &'a ParseContext,
1561        subs: &'a mut SubstitutionTable,
1562        input: IndexStr<'b>,
1563    ) -> Result<(CloneSuffix, IndexStr<'b>)> {
1564        try_begin_parse!("CloneSuffix", ctx, input);
1565
1566        let tail = consume(b".", input)?;
1567        let (identifier, mut tail) = CloneTypeIdentifier::parse(ctx, subs, tail)?;
1568
1569        let mut numbers = Vec::with_capacity(1);
1570        while let Ok((n, t)) = consume(b".", tail).and_then(|t| parse_number(10, false, t)) {
1571            numbers.push(n);
1572            tail = t;
1573        }
1574
1575        let clone_suffix = CloneSuffix(identifier, numbers);
1576        Ok((clone_suffix, tail))
1577    }
1578}
1579
1580impl<'subs, W> Demangle<'subs, W> for CloneSuffix
1581where
1582    W: 'subs + DemangleWrite,
1583{
1584    fn demangle<'prev, 'ctx>(
1585        &'subs self,
1586        ctx: &'ctx mut DemangleContext<'subs, W>,
1587        scope: Option<ArgScopeStack<'prev, 'subs>>,
1588    ) -> fmt::Result {
1589        let ctx = try_begin_demangle!(self, ctx, scope);
1590        write!(ctx, " [clone")?;
1591        self.0.demangle(ctx, scope)?;
1592        for nonnegative in &self.1 {
1593            write!(ctx, ".{}", nonnegative)?;
1594        }
1595        write!(ctx, "]")?;
1596        Ok(())
1597    }
1598}
1599
1600/// A global constructor or destructor.
1601#[derive(Clone, Debug, PartialEq, Eq)]
1602pub enum GlobalCtorDtor {
1603    /// A global constructor.
1604    Ctor(Box<MangledName>),
1605    /// A global destructor.
1606    Dtor(Box<MangledName>),
1607}
1608
1609impl Parse for GlobalCtorDtor {
1610    fn parse<'a, 'b>(
1611        ctx: &'a ParseContext,
1612        subs: &'a mut SubstitutionTable,
1613        input: IndexStr<'b>,
1614    ) -> Result<(GlobalCtorDtor, IndexStr<'b>)> {
1615        try_begin_parse!("GlobalCtorDtor", ctx, input);
1616
1617        let tail = match input.next_or(error::Error::UnexpectedEnd)? {
1618            (b'_', t) | (b'.', t) | (b'$', t) => t,
1619            _ => return Err(error::Error::UnexpectedText),
1620        };
1621
1622        match tail.next_or(error::Error::UnexpectedEnd)? {
1623            (b'I', tail) => {
1624                let tail = consume(b"_", tail)?;
1625                let (name, tail) = MangledName::parse(ctx, subs, tail)?;
1626                Ok((GlobalCtorDtor::Ctor(Box::new(name)), tail))
1627            }
1628            (b'D', tail) => {
1629                let tail = consume(b"_", tail)?;
1630                let (name, tail) = MangledName::parse(ctx, subs, tail)?;
1631                Ok((GlobalCtorDtor::Dtor(Box::new(name)), tail))
1632            }
1633            _ => Err(error::Error::UnexpectedText),
1634        }
1635    }
1636}
1637
1638impl<'subs, W> Demangle<'subs, W> for GlobalCtorDtor
1639where
1640    W: 'subs + DemangleWrite,
1641{
1642    fn demangle<'prev, 'ctx>(
1643        &'subs self,
1644        ctx: &'ctx mut DemangleContext<'subs, W>,
1645        scope: Option<ArgScopeStack<'prev, 'subs>>,
1646    ) -> fmt::Result {
1647        let ctx = try_begin_demangle!(self, ctx, scope);
1648        inner_barrier!(ctx);
1649
1650        let saved_show_params = ctx.show_params;
1651        ctx.show_params = true;
1652        let ret = match *self {
1653            GlobalCtorDtor::Ctor(ref name) => {
1654                write!(ctx, "global constructors keyed to ")?;
1655                name.demangle(ctx, scope)
1656            }
1657            GlobalCtorDtor::Dtor(ref name) => {
1658                write!(ctx, "global destructors keyed to ")?;
1659                name.demangle(ctx, scope)
1660            }
1661        };
1662        ctx.show_params = saved_show_params;
1663        ret
1664    }
1665}
1666
1667/// The `<name>` production.
1668///
1669/// ```text
1670/// <name> ::= <nested-name>
1671///        ::= <unscoped-name>
1672///        ::= <unscoped-template-name> <template-args>
1673///        ::= <local-name>
1674/// ```
1675#[derive(Clone, Debug, PartialEq, Eq)]
1676pub enum Name {
1677    /// A nested name
1678    Nested(NestedName),
1679
1680    /// An unscoped name.
1681    Unscoped(UnscopedName),
1682
1683    /// An unscoped template.
1684    UnscopedTemplate(UnscopedTemplateNameHandle, TemplateArgs),
1685
1686    /// A local name.
1687    Local(LocalName),
1688}
1689
1690impl Parse for Name {
1691    fn parse<'a, 'b>(
1692        ctx: &'a ParseContext,
1693        subs: &'a mut SubstitutionTable,
1694        input: IndexStr<'b>,
1695    ) -> Result<(Name, IndexStr<'b>)> {
1696        try_begin_parse!("Name", ctx, input);
1697
1698        if let Ok((name, tail)) = NestedName::parse(ctx, subs, input) {
1699            return Ok((Name::Nested(name), tail));
1700        }
1701
1702        if let Ok((name, tail)) = UnscopedName::parse(ctx, subs, input) {
1703            if tail.peek() == Some(b'I') {
1704                let name = UnscopedTemplateName(name);
1705                let idx = subs.insert(Substitutable::UnscopedTemplateName(name));
1706                let handle = UnscopedTemplateNameHandle::BackReference(idx);
1707
1708                let (args, tail) = TemplateArgs::parse(ctx, subs, tail)?;
1709                return Ok((Name::UnscopedTemplate(handle, args), tail));
1710            } else {
1711                return Ok((Name::Unscoped(name), tail));
1712            }
1713        }
1714
1715        if let Ok((name, tail)) = UnscopedTemplateNameHandle::parse(ctx, subs, input) {
1716            let (args, tail) = TemplateArgs::parse(ctx, subs, tail)?;
1717            return Ok((Name::UnscopedTemplate(name, args), tail));
1718        }
1719
1720        let (name, tail) = LocalName::parse(ctx, subs, input)?;
1721        Ok((Name::Local(name), tail))
1722    }
1723}
1724
1725impl<'subs, W> Demangle<'subs, W> for Name
1726where
1727    W: 'subs + DemangleWrite,
1728{
1729    fn demangle<'prev, 'ctx>(
1730        &'subs self,
1731        ctx: &'ctx mut DemangleContext<'subs, W>,
1732        scope: Option<ArgScopeStack<'prev, 'subs>>,
1733    ) -> fmt::Result {
1734        let ctx = try_begin_demangle!(self, ctx, scope);
1735
1736        match *self {
1737            Name::Nested(ref nested) => nested.demangle(ctx, scope),
1738            Name::Unscoped(ref unscoped) => unscoped.demangle(ctx, scope),
1739            Name::UnscopedTemplate(ref template, ref args) => {
1740                template.demangle(ctx, scope.push(args))?;
1741                args.demangle(ctx, scope)
1742            }
1743            Name::Local(ref local) => local.demangle(ctx, scope),
1744        }
1745    }
1746}
1747
1748impl GetTemplateArgs for Name {
1749    fn get_template_args<'a>(&'a self, subs: &'a SubstitutionTable) -> Option<&'a TemplateArgs> {
1750        match *self {
1751            Name::UnscopedTemplate(_, ref args) => Some(args),
1752            Name::Nested(ref nested) => nested.get_template_args(subs),
1753            Name::Local(ref local) => local.get_template_args(subs),
1754            Name::Unscoped(_) => None,
1755        }
1756    }
1757}
1758
1759impl<'a> GetLeafName<'a> for Name {
1760    fn get_leaf_name(&'a self, subs: &'a SubstitutionTable) -> Option<LeafName<'a>> {
1761        match *self {
1762            Name::UnscopedTemplate(ref templ, _) => templ.get_leaf_name(subs),
1763            Name::Nested(ref nested) => nested.get_leaf_name(subs),
1764            Name::Unscoped(ref unscoped) => unscoped.get_leaf_name(subs),
1765            Name::Local(ref local) => local.get_leaf_name(subs),
1766        }
1767    }
1768}
1769
1770impl IsCtorDtorConversion for Name {
1771    fn is_ctor_dtor_conversion(&self, subs: &SubstitutionTable) -> bool {
1772        match *self {
1773            Name::Unscoped(ref unscoped) => unscoped.is_ctor_dtor_conversion(subs),
1774            Name::Nested(ref nested) => nested.is_ctor_dtor_conversion(subs),
1775            Name::Local(_) | Name::UnscopedTemplate(..) => false,
1776        }
1777    }
1778}
1779
1780/// The `<unscoped-name>` production.
1781///
1782/// ```text
1783/// <unscoped-name> ::= <unqualified-name>
1784///                 ::= St <unqualified-name>   # ::std::
1785/// ```
1786#[derive(Clone, Debug, PartialEq, Eq)]
1787pub enum UnscopedName {
1788    /// An unqualified name.
1789    Unqualified(UnqualifiedName),
1790
1791    /// A name within the `std::` namespace.
1792    Std(UnqualifiedName),
1793}
1794
1795impl Parse for UnscopedName {
1796    fn parse<'a, 'b>(
1797        ctx: &'a ParseContext,
1798        subs: &'a mut SubstitutionTable,
1799        input: IndexStr<'b>,
1800    ) -> Result<(UnscopedName, IndexStr<'b>)> {
1801        try_begin_parse!("UnscopedName", ctx, input);
1802
1803        if let Ok(tail) = consume(b"St", input) {
1804            let (name, tail) = UnqualifiedName::parse(ctx, subs, tail)?;
1805            return Ok((UnscopedName::Std(name), tail));
1806        }
1807
1808        let (name, tail) = UnqualifiedName::parse(ctx, subs, input)?;
1809        Ok((UnscopedName::Unqualified(name), tail))
1810    }
1811}
1812
1813impl<'subs, W> Demangle<'subs, W> for UnscopedName
1814where
1815    W: 'subs + DemangleWrite,
1816{
1817    fn demangle<'prev, 'ctx>(
1818        &'subs self,
1819        ctx: &'ctx mut DemangleContext<'subs, W>,
1820        scope: Option<ArgScopeStack<'prev, 'subs>>,
1821    ) -> fmt::Result {
1822        let ctx = try_begin_demangle!(self, ctx, scope);
1823
1824        match *self {
1825            UnscopedName::Unqualified(ref unqualified) => unqualified.demangle(ctx, scope),
1826            UnscopedName::Std(ref std) => {
1827                write!(ctx, "std::")?;
1828                std.demangle(ctx, scope)
1829            }
1830        }
1831    }
1832}
1833
1834impl<'a> GetLeafName<'a> for UnscopedName {
1835    fn get_leaf_name(&'a self, subs: &'a SubstitutionTable) -> Option<LeafName<'a>> {
1836        match *self {
1837            UnscopedName::Unqualified(ref name) | UnscopedName::Std(ref name) => {
1838                name.get_leaf_name(subs)
1839            }
1840        }
1841    }
1842}
1843
1844impl IsCtorDtorConversion for UnscopedName {
1845    fn is_ctor_dtor_conversion(&self, subs: &SubstitutionTable) -> bool {
1846        match *self {
1847            UnscopedName::Unqualified(ref name) | UnscopedName::Std(ref name) => {
1848                name.is_ctor_dtor_conversion(subs)
1849            }
1850        }
1851    }
1852}
1853
1854/// The `<unscoped-template-name>` production.
1855///
1856/// ```text
1857/// <unscoped-template-name> ::= <unscoped-name>
1858///                          ::= <substitution>
1859/// ```
1860#[derive(Clone, Debug, PartialEq, Eq)]
1861pub struct UnscopedTemplateName(UnscopedName);
1862
1863define_handle! {
1864    /// A handle to an `UnscopedTemplateName`.
1865    pub enum UnscopedTemplateNameHandle {
1866        /// A handle to some `<unscoped-name>` component that isn't by itself
1867        /// substitutable.
1868        extra NonSubstitution(NonSubstitution),
1869    }
1870}
1871
1872impl Parse for UnscopedTemplateNameHandle {
1873    fn parse<'a, 'b>(
1874        ctx: &'a ParseContext,
1875        subs: &'a mut SubstitutionTable,
1876        input: IndexStr<'b>,
1877    ) -> Result<(UnscopedTemplateNameHandle, IndexStr<'b>)> {
1878        try_begin_parse!("UnscopedTemplateNameHandle", ctx, input);
1879
1880        if let Ok((name, tail)) = UnscopedName::parse(ctx, subs, input) {
1881            let name = UnscopedTemplateName(name);
1882            let idx = subs.insert(Substitutable::UnscopedTemplateName(name));
1883            let handle = UnscopedTemplateNameHandle::BackReference(idx);
1884            return Ok((handle, tail));
1885        }
1886
1887        let (sub, tail) = Substitution::parse(ctx, subs, input)?;
1888
1889        match sub {
1890            Substitution::WellKnown(component) => {
1891                Ok((UnscopedTemplateNameHandle::WellKnown(component), tail))
1892            }
1893            Substitution::BackReference(idx) => {
1894                // TODO: should this check/assert that subs[idx] is an
1895                // UnscopedTemplateName?
1896                Ok((UnscopedTemplateNameHandle::BackReference(idx), tail))
1897            }
1898        }
1899    }
1900}
1901
1902impl<'subs, W> Demangle<'subs, W> for UnscopedTemplateName
1903where
1904    W: 'subs + DemangleWrite,
1905{
1906    fn demangle<'prev, 'ctx>(
1907        &'subs self,
1908        ctx: &'ctx mut DemangleContext<'subs, W>,
1909        scope: Option<ArgScopeStack<'prev, 'subs>>,
1910    ) -> fmt::Result {
1911        let ctx = try_begin_demangle!(self, ctx, scope);
1912
1913        self.0.demangle(ctx, scope)
1914    }
1915}
1916
1917impl<'a> GetLeafName<'a> for UnscopedTemplateName {
1918    fn get_leaf_name(&'a self, subs: &'a SubstitutionTable) -> Option<LeafName<'a>> {
1919        self.0.get_leaf_name(subs)
1920    }
1921}
1922
1923/// The `<nested-name>` production.
1924///
1925/// ```text
1926/// <nested-name> ::= N [<CV-qualifiers>] [<ref-qualifier>] <prefix> <unqualified-name> E
1927///               ::= N [<CV-qualifiers>] [<ref-qualifier>] <template-prefix> <template-args> E
1928/// ```
1929#[derive(Clone, Debug, PartialEq, Eq)]
1930pub enum NestedName {
1931    /// A nested name.
1932    Unqualified(
1933        CvQualifiers,
1934        Option<RefQualifier>,
1935        PrefixHandle,
1936        UnqualifiedName,
1937    ),
1938
1939    /// A nested template name. The `<template-args>` are part of the `PrefixHandle`.
1940    Template(CvQualifiers, Option<RefQualifier>, PrefixHandle),
1941}
1942
1943impl Parse for NestedName {
1944    fn parse<'a, 'b>(
1945        ctx: &'a ParseContext,
1946        subs: &'a mut SubstitutionTable,
1947        input: IndexStr<'b>,
1948    ) -> Result<(NestedName, IndexStr<'b>)> {
1949        try_begin_parse!("NestedName", ctx, input);
1950
1951        let tail = consume(b"N", input)?;
1952
1953        let (cv_qualifiers, tail) = if let Ok((q, tail)) = CvQualifiers::parse(ctx, subs, tail) {
1954            (q, tail)
1955        } else {
1956            (Default::default(), tail)
1957        };
1958
1959        let (ref_qualifier, tail) = if let Ok((r, tail)) = RefQualifier::parse(ctx, subs, tail) {
1960            (Some(r), tail)
1961        } else {
1962            (None, tail)
1963        };
1964
1965        let (prefix, tail) = PrefixHandle::parse(ctx, subs, tail)?;
1966        let tail = consume(b"E", tail)?;
1967
1968        let substitutable = match prefix {
1969            PrefixHandle::BackReference(idx) => subs.get(idx),
1970            PrefixHandle::NonSubstitution(NonSubstitution(idx)) => subs.get_non_substitution(idx),
1971            PrefixHandle::WellKnown(_) => None,
1972        };
1973
1974        match substitutable {
1975            Some(&Substitutable::Prefix(Prefix::Nested(ref prefix, ref name))) => Ok((
1976                NestedName::Unqualified(cv_qualifiers, ref_qualifier, prefix.clone(), name.clone()),
1977                tail,
1978            )),
1979            Some(&Substitutable::Prefix(Prefix::Template(..))) => Ok((
1980                NestedName::Template(cv_qualifiers, ref_qualifier, prefix),
1981                tail,
1982            )),
1983            _ => Err(error::Error::UnexpectedText),
1984        }
1985    }
1986}
1987
1988impl NestedName {
1989    /// Get the CV-qualifiers for this name.
1990    pub fn cv_qualifiers(&self) -> &CvQualifiers {
1991        match *self {
1992            NestedName::Unqualified(ref q, ..) | NestedName::Template(ref q, ..) => q,
1993        }
1994    }
1995
1996    /// Get the ref-qualifier for this name, if one exists.
1997    pub fn ref_qualifier(&self) -> Option<&RefQualifier> {
1998        match *self {
1999            NestedName::Unqualified(_, Some(ref r), ..)
2000            | NestedName::Template(_, Some(ref r), ..) => Some(r),
2001            _ => None,
2002        }
2003    }
2004
2005    // Not public because the prefix means different things for different
2006    // variants, and for `::Template` it actually contains part of what
2007    // conceptually belongs to `<nested-name>`.
2008    fn prefix(&self) -> &PrefixHandle {
2009        match *self {
2010            NestedName::Unqualified(_, _, ref p, _) | NestedName::Template(_, _, ref p) => p,
2011        }
2012    }
2013}
2014
2015impl<'subs, W> Demangle<'subs, W> for NestedName
2016where
2017    W: 'subs + DemangleWrite,
2018{
2019    fn demangle<'prev, 'ctx>(
2020        &'subs self,
2021        ctx: &'ctx mut DemangleContext<'subs, W>,
2022        scope: Option<ArgScopeStack<'prev, 'subs>>,
2023    ) -> fmt::Result {
2024        let ctx = try_begin_demangle!(self, ctx, scope);
2025
2026        match *self {
2027            NestedName::Unqualified(_, _, ref p, ref name) => {
2028                ctx.push_demangle_node(DemangleNodeType::NestedName);
2029                p.demangle(ctx, scope)?;
2030                if name.accepts_double_colon() {
2031                    ctx.write_str("::")?;
2032                }
2033                name.demangle(ctx, scope)?;
2034                ctx.pop_demangle_node();
2035            }
2036            NestedName::Template(_, _, ref p) => {
2037                ctx.is_template_prefix_in_nested_name = true;
2038                p.demangle(ctx, scope)?;
2039                ctx.is_template_prefix_in_nested_name = false;
2040            }
2041        }
2042
2043        if let Some(inner) = ctx.pop_inner() {
2044            inner.demangle_as_inner(ctx, scope)?;
2045        }
2046
2047        if self.cv_qualifiers() != &CvQualifiers::default() && ctx.show_params {
2048            self.cv_qualifiers().demangle(ctx, scope)?;
2049        }
2050
2051        if let Some(ref refs) = self.ref_qualifier() {
2052            ctx.ensure_space()?;
2053            refs.demangle(ctx, scope)?;
2054        }
2055
2056        Ok(())
2057    }
2058}
2059
2060impl GetTemplateArgs for NestedName {
2061    fn get_template_args<'a>(&'a self, subs: &'a SubstitutionTable) -> Option<&'a TemplateArgs> {
2062        match *self {
2063            NestedName::Template(_, _, ref prefix) => prefix.get_template_args(subs),
2064            _ => None,
2065        }
2066    }
2067}
2068
2069impl<'a> GetLeafName<'a> for NestedName {
2070    fn get_leaf_name(&'a self, subs: &'a SubstitutionTable) -> Option<LeafName<'a>> {
2071        match *self {
2072            NestedName::Unqualified(_, _, ref prefix, ref name) => name
2073                .get_leaf_name(subs)
2074                .or_else(|| prefix.get_leaf_name(subs)),
2075            NestedName::Template(_, _, ref prefix) => prefix.get_leaf_name(subs),
2076        }
2077    }
2078}
2079
2080impl IsCtorDtorConversion for NestedName {
2081    fn is_ctor_dtor_conversion(&self, subs: &SubstitutionTable) -> bool {
2082        self.prefix().is_ctor_dtor_conversion(subs)
2083    }
2084}
2085
2086/// The `<prefix>` production.
2087///
2088/// ```text
2089/// <prefix> ::= <unqualified-name>
2090///          ::= <prefix> <unqualified-name>
2091///          ::= <template-prefix> <template-args>
2092///          ::= <template-param>
2093///          ::= <decltype>
2094///          ::= <prefix> <data-member-prefix>
2095///          ::= <substitution>
2096///
2097/// <template-prefix> ::= <template unqualified-name>
2098///                   ::= <prefix> <template unqualified-name>
2099///                   ::= <template-param>
2100///                   ::= <substitution>
2101/// ```
2102#[derive(Clone, Debug, PartialEq, Eq)]
2103pub enum Prefix {
2104    /// An unqualified name.
2105    Unqualified(UnqualifiedName),
2106
2107    /// Some nested name.
2108    Nested(PrefixHandle, UnqualifiedName),
2109
2110    /// A prefix and template arguments.
2111    Template(PrefixHandle, TemplateArgs),
2112
2113    /// A template parameter.
2114    TemplateParam(TemplateParam),
2115
2116    /// A decltype.
2117    Decltype(Decltype),
2118
2119    /// A prefix and data member.
2120    DataMember(PrefixHandle, DataMemberPrefix),
2121}
2122
2123impl GetTemplateArgs for Prefix {
2124    fn get_template_args<'a>(&'a self, _: &'a SubstitutionTable) -> Option<&'a TemplateArgs> {
2125        match *self {
2126            Prefix::Template(_, ref args) => Some(args),
2127            Prefix::Unqualified(_)
2128            | Prefix::Nested(_, _)
2129            | Prefix::TemplateParam(_)
2130            | Prefix::Decltype(_)
2131            | Prefix::DataMember(_, _) => None,
2132        }
2133    }
2134}
2135
2136define_handle! {
2137    /// A reference to a parsed `<prefix>` production.
2138    pub enum PrefixHandle {
2139        /// A handle to some `<prefix>` component that isn't by itself
2140        /// substitutable; instead, it's only substitutable *with* its parent
2141        /// component.
2142        extra NonSubstitution(NonSubstitution),
2143    }
2144}
2145
2146impl Parse for PrefixHandle {
2147    fn parse<'a, 'b>(
2148        ctx: &'a ParseContext,
2149        subs: &'a mut SubstitutionTable,
2150        input: IndexStr<'b>,
2151    ) -> Result<(PrefixHandle, IndexStr<'b>)> {
2152        try_begin_parse!("PrefixHandle", ctx, input);
2153
2154        #[inline]
2155        fn save(
2156            subs: &mut SubstitutionTable,
2157            prefix: Prefix,
2158            tail_tail: IndexStr<'_>,
2159        ) -> PrefixHandle {
2160            if let Some(b'E') = tail_tail.peek() {
2161                // An `E` means that we just finished parsing a `<nested-name>`
2162                // and this final set of prefixes isn't substitutable itself,
2163                // only as part of the whole `<nested-name>`. Since they are
2164                // effectively equivalent, it doesn't make sense to add entries
2165                // for both.
2166                let idx = subs.insert_non_substitution(Substitutable::Prefix(prefix));
2167                PrefixHandle::NonSubstitution(NonSubstitution(idx))
2168            } else {
2169                let idx = subs.insert(Substitutable::Prefix(prefix));
2170                PrefixHandle::BackReference(idx)
2171            }
2172        }
2173
2174        let mut tail = input;
2175        let mut current = None;
2176
2177        loop {
2178            try_begin_parse!("PrefixHandle iteration", ctx, tail);
2179
2180            match tail.peek() {
2181                Some(b'E') | None => {
2182                    if let Some(handle) = current {
2183                        return Ok((handle, tail));
2184                    } else {
2185                        return Err(error::Error::UnexpectedEnd);
2186                    }
2187                }
2188                Some(b'S') => {
2189                    // <prefix> ::= <substitution>
2190                    let (sub, tail_tail) = Substitution::parse(ctx, subs, tail)?;
2191                    current = Some(match sub {
2192                        Substitution::WellKnown(component) => PrefixHandle::WellKnown(component),
2193                        Substitution::BackReference(idx) => {
2194                            // TODO: do we need to check that the idx actually points to
2195                            // a Prefix?
2196                            PrefixHandle::BackReference(idx)
2197                        }
2198                    });
2199                    tail = tail_tail;
2200                }
2201                Some(b'T') => {
2202                    // <prefix> ::= <template-param>
2203                    let (param, tail_tail) = TemplateParam::parse(ctx, subs, tail)?;
2204                    current = Some(save(subs, Prefix::TemplateParam(param), tail_tail));
2205                    tail = tail_tail;
2206                }
2207                Some(b'D') => {
2208                    // Either
2209                    //
2210                    //     <prefix> ::= <decltype>
2211                    //
2212                    // or
2213                    //
2214                    //     <prefix> ::= <unqualified-name> ::= <ctor-dtor-name>
2215                    if let Ok((decltype, tail_tail)) = Decltype::parse(ctx, subs, tail) {
2216                        current = Some(save(subs, Prefix::Decltype(decltype), tail_tail));
2217                        tail = tail_tail;
2218                    } else {
2219                        let (name, tail_tail) = UnqualifiedName::parse(ctx, subs, tail)?;
2220                        let prefix = match current {
2221                            None => Prefix::Unqualified(name),
2222                            Some(handle) => Prefix::Nested(handle, name),
2223                        };
2224                        current = Some(save(subs, prefix, tail_tail));
2225                        tail = tail_tail;
2226                    }
2227                }
2228                Some(b'I')
2229                    if current.is_some() && current.as_ref().unwrap().is_template_prefix() =>
2230                {
2231                    // <prefix> ::= <template-prefix> <template-args>
2232                    let (args, tail_tail) = TemplateArgs::parse(ctx, subs, tail)?;
2233                    let prefix = Prefix::Template(current.unwrap(), args);
2234                    current = Some(save(subs, prefix, tail_tail));
2235                    tail = tail_tail;
2236                }
2237                Some(c) if current.is_some() && SourceName::starts_with(c) => {
2238                    // Either
2239                    //
2240                    //     <prefix> ::= <unqualified-name> ::= <source-name>
2241                    //
2242                    // or
2243                    //
2244                    //     <prefix> ::= <data-member-prefix> ::= <prefix> <source-name> M
2245                    debug_assert!(SourceName::starts_with(c));
2246                    debug_assert!(DataMemberPrefix::starts_with(c));
2247
2248                    let (name, tail_tail) = SourceName::parse(ctx, subs, tail)?;
2249                    if tail_tail.peek() == Some(b'M') {
2250                        let prefix = Prefix::DataMember(current.unwrap(), DataMemberPrefix(name));
2251                        current = Some(save(subs, prefix, tail_tail));
2252                        tail = consume(b"M", tail_tail).unwrap();
2253                    } else {
2254                        let name = UnqualifiedName::Source(name);
2255                        let prefix = match current {
2256                            None => Prefix::Unqualified(name),
2257                            Some(handle) => Prefix::Nested(handle, name),
2258                        };
2259                        current = Some(save(subs, prefix, tail_tail));
2260                        tail = tail_tail;
2261                    }
2262                }
2263                Some(c) if UnqualifiedName::starts_with(c, &tail) => {
2264                    // <prefix> ::= <unqualified-name>
2265                    let (name, tail_tail) = UnqualifiedName::parse(ctx, subs, tail)?;
2266                    let prefix = match current {
2267                        None => Prefix::Unqualified(name),
2268                        Some(handle) => Prefix::Nested(handle, name),
2269                    };
2270                    current = Some(save(subs, prefix, tail_tail));
2271                    tail = tail_tail;
2272                }
2273                Some(_) => {
2274                    if let Some(handle) = current {
2275                        return Ok((handle, tail));
2276                    } else if tail.is_empty() {
2277                        return Err(error::Error::UnexpectedEnd);
2278                    } else {
2279                        return Err(error::Error::UnexpectedText);
2280                    }
2281                }
2282            }
2283        }
2284    }
2285}
2286
2287impl<'a> GetLeafName<'a> for Prefix {
2288    fn get_leaf_name(&'a self, subs: &'a SubstitutionTable) -> Option<LeafName<'a>> {
2289        match *self {
2290            Prefix::Nested(ref prefix, ref name) => name
2291                .get_leaf_name(subs)
2292                .or_else(|| prefix.get_leaf_name(subs)),
2293            Prefix::Unqualified(ref name) => name.get_leaf_name(subs),
2294            Prefix::Template(ref prefix, _) => prefix.get_leaf_name(subs),
2295            Prefix::DataMember(_, ref name) => name.get_leaf_name(subs),
2296            Prefix::TemplateParam(_) | Prefix::Decltype(_) => None,
2297        }
2298    }
2299}
2300
2301impl GetTemplateArgs for PrefixHandle {
2302    // XXX: Not an impl GetTemplateArgs for PrefixHandle because the 'me
2303    // reference to self may not live long enough.
2304    fn get_template_args<'a>(&'a self, subs: &'a SubstitutionTable) -> Option<&'a TemplateArgs> {
2305        match *self {
2306            PrefixHandle::BackReference(idx) => {
2307                if let Some(&Substitutable::Prefix(ref p)) = subs.get(idx) {
2308                    p.get_template_args(subs)
2309                } else {
2310                    None
2311                }
2312            }
2313            PrefixHandle::NonSubstitution(NonSubstitution(idx)) => {
2314                if let Some(&Substitutable::Prefix(ref p)) = subs.get_non_substitution(idx) {
2315                    p.get_template_args(subs)
2316                } else {
2317                    None
2318                }
2319            }
2320            _ => None,
2321        }
2322    }
2323}
2324
2325impl<'subs, W> Demangle<'subs, W> for Prefix
2326where
2327    W: 'subs + DemangleWrite,
2328{
2329    fn demangle<'prev, 'ctx>(
2330        &'subs self,
2331        ctx: &'ctx mut DemangleContext<'subs, W>,
2332        scope: Option<ArgScopeStack<'prev, 'subs>>,
2333    ) -> fmt::Result {
2334        let ctx = try_begin_demangle!(self, ctx, scope);
2335        if ctx.is_template_prefix {
2336            ctx.push_demangle_node(DemangleNodeType::TemplatePrefix);
2337            ctx.is_template_prefix = false;
2338        } else if ctx.is_template_prefix_in_nested_name {
2339            ctx.push_demangle_node(DemangleNodeType::NestedName);
2340            ctx.is_template_prefix_in_nested_name = false;
2341        } else {
2342            ctx.push_demangle_node(DemangleNodeType::Prefix);
2343        }
2344
2345        let ret = match *self {
2346            Prefix::Unqualified(ref unqualified) => unqualified.demangle(ctx, scope),
2347            Prefix::Nested(ref prefix, ref unqualified) => {
2348                prefix.demangle(ctx, scope)?;
2349                if unqualified.accepts_double_colon() {
2350                    write!(ctx, "::")?;
2351                }
2352                unqualified.demangle(ctx, scope)
2353            }
2354            Prefix::Template(ref prefix, ref args) => {
2355                ctx.is_template_prefix = true;
2356                prefix.demangle(ctx, scope)?;
2357                ctx.is_template_prefix = false;
2358                args.demangle(ctx, scope)
2359            }
2360            Prefix::TemplateParam(ref param) => param.demangle(ctx, scope),
2361            Prefix::Decltype(ref dt) => dt.demangle(ctx, scope),
2362            Prefix::DataMember(ref prefix, ref member) => {
2363                prefix.demangle(ctx, scope)?;
2364                write!(ctx, "::")?;
2365                member.demangle(ctx, scope)
2366            }
2367        };
2368        ctx.pop_demangle_node();
2369        ret
2370    }
2371}
2372
2373impl IsCtorDtorConversion for Prefix {
2374    fn is_ctor_dtor_conversion(&self, subs: &SubstitutionTable) -> bool {
2375        match *self {
2376            Prefix::Unqualified(ref unqualified) | Prefix::Nested(_, ref unqualified) => {
2377                unqualified.is_ctor_dtor_conversion(subs)
2378            }
2379            Prefix::Template(ref prefix, _) => prefix.is_ctor_dtor_conversion(subs),
2380            _ => false,
2381        }
2382    }
2383}
2384
2385impl IsCtorDtorConversion for PrefixHandle {
2386    fn is_ctor_dtor_conversion(&self, subs: &SubstitutionTable) -> bool {
2387        match *self {
2388            PrefixHandle::BackReference(idx) => {
2389                if let Some(sub) = subs.get(idx) {
2390                    sub.is_ctor_dtor_conversion(subs)
2391                } else {
2392                    false
2393                }
2394            }
2395            PrefixHandle::NonSubstitution(NonSubstitution(idx)) => {
2396                if let Some(sub) = subs.get_non_substitution(idx) {
2397                    sub.is_ctor_dtor_conversion(subs)
2398                } else {
2399                    false
2400                }
2401            }
2402            PrefixHandle::WellKnown(_) => false,
2403        }
2404    }
2405}
2406
2407impl PrefixHandle {
2408    // Is this <prefix> also a valid <template-prefix> production? Not to be
2409    // confused with the `GetTemplateArgs` trait.
2410    fn is_template_prefix(&self) -> bool {
2411        match *self {
2412            PrefixHandle::BackReference(_) | PrefixHandle::WellKnown(_) => true,
2413            PrefixHandle::NonSubstitution(_) => false,
2414        }
2415    }
2416}
2417
2418/// The `<unqualified-name>` production.
2419///
2420/// ```text
2421/// <unqualified-name> ::= <operator-name>
2422///                    ::= <ctor-dtor-name>
2423///                    ::= <source-name>
2424///                    ::= <local-source-name>
2425///                    ::= <unnamed-type-name>
2426///                    ::= <abi-tag>
2427///                    ::= <closure-type-name>
2428///
2429/// # I think this is from an older version of the standard. It isn't in the
2430/// # current version, but all the other demanglers support it, so we will too.
2431/// <local-source-name> ::= L <source-name> [<discriminator>]
2432/// ```
2433#[derive(Clone, Debug, PartialEq, Eq)]
2434pub enum UnqualifiedName {
2435    /// An operator name.
2436    Operator(OperatorName),
2437    /// A constructor or destructor name.
2438    CtorDtor(CtorDtorName),
2439    /// A source name.
2440    Source(SourceName),
2441    /// A local source name.
2442    LocalSourceName(SourceName, Option<Discriminator>),
2443    /// A generated name for an unnamed type.
2444    UnnamedType(UnnamedTypeName),
2445    /// An ABI tag.
2446    ABITag(TaggedName),
2447    /// A closure type name
2448    ClosureType(ClosureTypeName),
2449}
2450
2451impl Parse for UnqualifiedName {
2452    fn parse<'a, 'b>(
2453        ctx: &'a ParseContext,
2454        subs: &'a mut SubstitutionTable,
2455        input: IndexStr<'b>,
2456    ) -> Result<(UnqualifiedName, IndexStr<'b>)> {
2457        try_begin_parse!("UnqualifiedName", ctx, input);
2458
2459        if let Ok((op, tail)) = OperatorName::parse(ctx, subs, input) {
2460            return Ok((UnqualifiedName::Operator(op), tail));
2461        }
2462
2463        if let Ok((ctor_dtor, tail)) = CtorDtorName::parse(ctx, subs, input) {
2464            return Ok((UnqualifiedName::CtorDtor(ctor_dtor), tail));
2465        }
2466
2467        if let Ok(tail) = consume(b"L", input) {
2468            let (name, tail) = SourceName::parse(ctx, subs, tail)?;
2469            let (discr, tail) = if let Ok((d, t)) = Discriminator::parse(ctx, subs, tail) {
2470                (Some(d), t)
2471            } else {
2472                (None, tail)
2473            };
2474            return Ok((UnqualifiedName::LocalSourceName(name, discr), tail));
2475        }
2476
2477        if let Ok((source, tail)) = SourceName::parse(ctx, subs, input) {
2478            return Ok((UnqualifiedName::Source(source), tail));
2479        }
2480
2481        if let Ok((tagged, tail)) = TaggedName::parse(ctx, subs, input) {
2482            return Ok((UnqualifiedName::ABITag(tagged), tail));
2483        }
2484
2485        if let Ok((closure, tail)) = ClosureTypeName::parse(ctx, subs, input) {
2486            return Ok((UnqualifiedName::ClosureType(closure), tail));
2487        }
2488
2489        UnnamedTypeName::parse(ctx, subs, input)
2490            .map(|(unnamed, tail)| (UnqualifiedName::UnnamedType(unnamed), tail))
2491    }
2492}
2493
2494impl<'subs, W> Demangle<'subs, W> for UnqualifiedName
2495where
2496    W: 'subs + DemangleWrite,
2497{
2498    fn demangle<'prev, 'ctx>(
2499        &'subs self,
2500        ctx: &'ctx mut DemangleContext<'subs, W>,
2501        scope: Option<ArgScopeStack<'prev, 'subs>>,
2502    ) -> fmt::Result {
2503        let ctx = try_begin_demangle!(self, ctx, scope);
2504
2505        ctx.push_demangle_node(DemangleNodeType::UnqualifiedName);
2506        let ret = match *self {
2507            UnqualifiedName::Operator(ref op_name) => {
2508                write!(ctx, "operator")?;
2509                op_name.demangle(ctx, scope)
2510            }
2511            UnqualifiedName::CtorDtor(ref ctor_dtor) => ctor_dtor.demangle(ctx, scope),
2512            UnqualifiedName::Source(ref name) | UnqualifiedName::LocalSourceName(ref name, ..) => {
2513                name.demangle(ctx, scope)
2514            }
2515            UnqualifiedName::UnnamedType(ref unnamed) => unnamed.demangle(ctx, scope),
2516            UnqualifiedName::ABITag(ref tagged) => tagged.demangle(ctx, scope),
2517            UnqualifiedName::ClosureType(ref closure) => closure.demangle(ctx, scope),
2518        };
2519        ctx.pop_demangle_node();
2520        ret
2521    }
2522}
2523
2524impl<'a> GetLeafName<'a> for UnqualifiedName {
2525    fn get_leaf_name(&'a self, subs: &'a SubstitutionTable) -> Option<LeafName<'a>> {
2526        match *self {
2527            UnqualifiedName::ABITag(_)
2528            | UnqualifiedName::Operator(_)
2529            | UnqualifiedName::CtorDtor(_) => None,
2530            UnqualifiedName::UnnamedType(ref name) => Some(LeafName::UnnamedType(name)),
2531            UnqualifiedName::ClosureType(ref closure) => closure.get_leaf_name(subs),
2532            UnqualifiedName::Source(ref name) | UnqualifiedName::LocalSourceName(ref name, _) => {
2533                Some(LeafName::SourceName(name))
2534            }
2535        }
2536    }
2537}
2538
2539impl IsCtorDtorConversion for UnqualifiedName {
2540    fn is_ctor_dtor_conversion(&self, _: &SubstitutionTable) -> bool {
2541        match *self {
2542            UnqualifiedName::CtorDtor(_)
2543            | UnqualifiedName::Operator(OperatorName::Conversion(_)) => true,
2544            UnqualifiedName::Operator(_)
2545            | UnqualifiedName::Source(_)
2546            | UnqualifiedName::LocalSourceName(..)
2547            | UnqualifiedName::UnnamedType(_)
2548            | UnqualifiedName::ClosureType(_)
2549            | UnqualifiedName::ABITag(_) => false,
2550        }
2551    }
2552}
2553
2554impl UnqualifiedName {
2555    #[inline]
2556    fn starts_with(byte: u8, input: &IndexStr) -> bool {
2557        byte == b'L'
2558            || OperatorName::starts_with(byte)
2559            || CtorDtorName::starts_with(byte)
2560            || SourceName::starts_with(byte)
2561            || UnnamedTypeName::starts_with(byte)
2562            || TaggedName::starts_with(byte)
2563            || ClosureTypeName::starts_with(byte, input)
2564    }
2565
2566    fn accepts_double_colon(&self) -> bool {
2567        match *self {
2568            UnqualifiedName::Operator(_)
2569            | UnqualifiedName::CtorDtor(_)
2570            | UnqualifiedName::Source(_)
2571            | UnqualifiedName::LocalSourceName(..)
2572            | UnqualifiedName::UnnamedType(_)
2573            | UnqualifiedName::ClosureType(_) => true,
2574            UnqualifiedName::ABITag(_) => false,
2575        }
2576    }
2577}
2578
2579/// The `<source-name>` non-terminal.
2580///
2581/// ```text
2582/// <source-name> ::= <positive length number> <identifier>
2583/// ```
2584#[derive(Clone, Debug, PartialEq, Eq)]
2585pub struct SourceName(Identifier);
2586
2587impl Parse for SourceName {
2588    fn parse<'a, 'b>(
2589        ctx: &'a ParseContext,
2590        subs: &'a mut SubstitutionTable,
2591        input: IndexStr<'b>,
2592    ) -> Result<(SourceName, IndexStr<'b>)> {
2593        try_begin_parse!("SourceName", ctx, input);
2594
2595        let (source_name_len, input) = parse_number(10, false, input)?;
2596        debug_assert!(source_name_len >= 0);
2597        if source_name_len == 0 {
2598            return Err(error::Error::UnexpectedText);
2599        }
2600
2601        let (head, tail) = match input.try_split_at(source_name_len as _) {
2602            Some((head, tail)) => (head, tail),
2603            None => return Err(error::Error::UnexpectedEnd),
2604        };
2605
2606        let (identifier, empty) = Identifier::parse(ctx, subs, head)?;
2607        if !empty.is_empty() {
2608            return Err(error::Error::UnexpectedText);
2609        }
2610
2611        let source_name = SourceName(identifier);
2612        Ok((source_name, tail))
2613    }
2614}
2615
2616impl<'subs> ArgScope<'subs, 'subs> for SourceName {
2617    fn leaf_name(&'subs self) -> Result<LeafName<'subs>> {
2618        Ok(LeafName::SourceName(self))
2619    }
2620
2621    fn get_template_arg(
2622        &'subs self,
2623        _: usize,
2624    ) -> Result<(&'subs TemplateArg, &'subs TemplateArgs)> {
2625        Err(error::Error::BadTemplateArgReference)
2626    }
2627
2628    fn get_function_arg(&'subs self, _: usize) -> Result<&'subs Type> {
2629        Err(error::Error::BadFunctionArgReference)
2630    }
2631}
2632
2633impl SourceName {
2634    #[inline]
2635    fn starts_with(byte: u8) -> bool {
2636        byte == b'0' || (b'0' <= byte && byte <= b'9')
2637    }
2638}
2639
2640impl<'subs, W> Demangle<'subs, W> for SourceName
2641where
2642    W: 'subs + DemangleWrite,
2643{
2644    #[inline]
2645    fn demangle<'prev, 'ctx>(
2646        &'subs self,
2647        ctx: &'ctx mut DemangleContext<'subs, W>,
2648        scope: Option<ArgScopeStack<'prev, 'subs>>,
2649    ) -> fmt::Result {
2650        let ctx = try_begin_demangle!(self, ctx, scope);
2651
2652        self.0.demangle(ctx, scope)
2653    }
2654}
2655
2656/// The `<tagged-name>` non-terminal.
2657///
2658/// ```text
2659/// <tagged-name> ::= <name> B <source-name>
2660/// ```
2661#[derive(Clone, Debug, PartialEq, Eq)]
2662pub struct TaggedName(SourceName);
2663
2664impl Parse for TaggedName {
2665    fn parse<'a, 'b>(
2666        ctx: &'a ParseContext,
2667        subs: &'a mut SubstitutionTable,
2668        input: IndexStr<'b>,
2669    ) -> Result<(TaggedName, IndexStr<'b>)> {
2670        try_begin_parse!("TaggedName", ctx, input);
2671
2672        let tail = consume(b"B", input)?;
2673        let (source_name, tail) = SourceName::parse(ctx, subs, tail)?;
2674        Ok((TaggedName(source_name), tail))
2675    }
2676}
2677
2678impl<'subs, W> Demangle<'subs, W> for TaggedName
2679where
2680    W: 'subs + DemangleWrite,
2681{
2682    fn demangle<'prev, 'ctx>(
2683        &'subs self,
2684        ctx: &'ctx mut DemangleContext<'subs, W>,
2685        scope: Option<ArgScopeStack<'prev, 'subs>>,
2686    ) -> fmt::Result {
2687        let ctx = try_begin_demangle!(self, ctx, scope);
2688
2689        write!(ctx, "[abi:")?;
2690        self.0.demangle(ctx, scope)?;
2691        write!(ctx, "]")
2692    }
2693}
2694
2695impl TaggedName {
2696    #[inline]
2697    fn starts_with(byte: u8) -> bool {
2698        byte == b'B'
2699    }
2700}
2701
2702/// The `<identifier>` pseudo-terminal.
2703///
2704/// ```text
2705/// <identifier> ::= <unqualified source code identifier>
2706/// ```
2707///
2708/// > `<identifier>` is a pseudo-terminal representing the characters in the
2709/// > unqualified identifier for the entity in the source code. This ABI does not
2710/// > yet specify a mangling for identifiers containing characters outside of
2711/// > `_A-Za-z0-9.`.
2712///
2713/// Mangled symbols' identifiers also have `$` characters in the wild.
2714#[derive(Clone, Debug, PartialEq, Eq)]
2715pub struct Identifier {
2716    start: usize,
2717    end: usize,
2718}
2719
2720impl Parse for Identifier {
2721    fn parse<'a, 'b>(
2722        ctx: &'a ParseContext,
2723        _subs: &'a mut SubstitutionTable,
2724        input: IndexStr<'b>,
2725    ) -> Result<(Identifier, IndexStr<'b>)> {
2726        try_begin_parse!("Identifier", ctx, input);
2727
2728        if input.is_empty() {
2729            return Err(error::Error::UnexpectedEnd);
2730        }
2731
2732        let end = input
2733            .as_ref()
2734            .iter()
2735            .map(|&c| c as char)
2736            .take_while(|&c| c == '$' || c == '_' || c == '.' || c.is_digit(36))
2737            .count();
2738
2739        if end == 0 {
2740            return Err(error::Error::UnexpectedText);
2741        }
2742
2743        let tail = input.range_from(end..);
2744
2745        let identifier = Identifier {
2746            start: input.index(),
2747            end: tail.index(),
2748        };
2749
2750        Ok((identifier, tail))
2751    }
2752}
2753
2754impl<'subs, W> Demangle<'subs, W> for Identifier
2755where
2756    W: 'subs + DemangleWrite,
2757{
2758    #[inline]
2759    fn demangle<'prev, 'ctx>(
2760        &'subs self,
2761        ctx: &'ctx mut DemangleContext<'subs, W>,
2762        scope: Option<ArgScopeStack<'prev, 'subs>>,
2763    ) -> fmt::Result {
2764        let ctx = try_begin_demangle!(self, ctx, scope);
2765
2766        let ident = &ctx.input[self.start..self.end];
2767
2768        // Handle GCC's anonymous namespace mangling.
2769        let anon_namespace_prefix = b"_GLOBAL_";
2770        if ident.starts_with(anon_namespace_prefix)
2771            && ident.len() >= anon_namespace_prefix.len() + 2
2772        {
2773            let first = ident[anon_namespace_prefix.len()];
2774            let second = ident[anon_namespace_prefix.len() + 1];
2775
2776            match (first, second) {
2777                (b'.', b'N') | (b'_', b'N') | (b'$', b'N') => {
2778                    write!(ctx, "(anonymous namespace)")?;
2779                    return Ok(());
2780                }
2781                _ => {
2782                    // Fall through.
2783                }
2784            }
2785        }
2786
2787        let source_name = String::from_utf8_lossy(ident);
2788        ctx.set_source_name(self.start, self.end);
2789        write!(ctx, "{}", source_name)?;
2790        Ok(())
2791    }
2792}
2793
2794/// The `<clone-type-identifier>` pseudo-terminal.
2795///
2796/// ```text
2797/// <clone-type-identifier> ::= <unqualified source code identifier>
2798/// ```
2799#[derive(Clone, Debug, PartialEq, Eq)]
2800pub struct CloneTypeIdentifier {
2801    start: usize,
2802    end: usize,
2803}
2804
2805impl Parse for CloneTypeIdentifier {
2806    fn parse<'a, 'b>(
2807        ctx: &'a ParseContext,
2808        _subs: &'a mut SubstitutionTable,
2809        input: IndexStr<'b>,
2810    ) -> Result<(CloneTypeIdentifier, IndexStr<'b>)> {
2811        try_begin_parse!("CloneTypeIdentifier", ctx, input);
2812
2813        if input.is_empty() {
2814            return Err(error::Error::UnexpectedEnd);
2815        }
2816
2817        let end = input
2818            .as_ref()
2819            .iter()
2820            .map(|&c| c as char)
2821            .take_while(|&c| c == '$' || c == '_' || c.is_digit(36))
2822            .count();
2823
2824        if end == 0 {
2825            return Err(error::Error::UnexpectedText);
2826        }
2827
2828        let tail = input.range_from(end..);
2829
2830        let identifier = CloneTypeIdentifier {
2831            start: input.index(),
2832            end: tail.index(),
2833        };
2834
2835        Ok((identifier, tail))
2836    }
2837}
2838
2839impl<'subs, W> Demangle<'subs, W> for CloneTypeIdentifier
2840where
2841    W: 'subs + DemangleWrite,
2842{
2843    #[inline]
2844    fn demangle<'prev, 'ctx>(
2845        &'subs self,
2846        ctx: &'ctx mut DemangleContext<'subs, W>,
2847        scope: Option<ArgScopeStack<'prev, 'subs>>,
2848    ) -> fmt::Result {
2849        let ctx = try_begin_demangle!(self, ctx, scope);
2850
2851        let ident = &ctx.input[self.start..self.end];
2852
2853        let source_name = String::from_utf8_lossy(ident);
2854        ctx.set_source_name(self.start, self.end);
2855        write!(ctx, " .{}", source_name)?;
2856        Ok(())
2857    }
2858}
2859
2860/// The `<number>` production.
2861///
2862/// ```text
2863/// <number> ::= [n] <non-negative decimal integer>
2864/// ```
2865type Number = isize;
2866
2867impl Parse for Number {
2868    fn parse<'a, 'b>(
2869        ctx: &'a ParseContext,
2870        _subs: &'a mut SubstitutionTable,
2871        input: IndexStr<'b>,
2872    ) -> Result<(isize, IndexStr<'b>)> {
2873        try_begin_parse!("Number", ctx, input);
2874        parse_number(10, true, input)
2875    }
2876}
2877
2878/// A <seq-id> production encoding a base-36 positive number.
2879///
2880/// ```text
2881/// <seq-id> ::= <0-9A-Z>+
2882/// ```
2883#[derive(Clone, Debug, PartialEq, Eq)]
2884pub struct SeqId(usize);
2885
2886impl Parse for SeqId {
2887    fn parse<'a, 'b>(
2888        ctx: &'a ParseContext,
2889        _subs: &'a mut SubstitutionTable,
2890        input: IndexStr<'b>,
2891    ) -> Result<(SeqId, IndexStr<'b>)> {
2892        try_begin_parse!("SeqId", ctx, input);
2893
2894        parse_number(36, false, input).map(|(num, tail)| (SeqId(num as _), tail))
2895    }
2896}
2897
2898/// The `<operator-name>` production.
2899///
2900/// ```text
2901/// <operator-name> ::= <simple-operator-name>
2902///                 ::= cv <type>               # (cast)
2903///                 ::= li <source-name>        # operator ""
2904///                 ::= v <digit> <source-name> # vendor extended operator
2905/// ```
2906#[derive(Clone, Debug, PartialEq, Eq)]
2907pub enum OperatorName {
2908    /// A simple operator name.
2909    Simple(SimpleOperatorName),
2910
2911    /// A type cast.
2912    Cast(TypeHandle),
2913
2914    /// A type conversion.
2915    Conversion(TypeHandle),
2916
2917    /// Operator literal, ie `operator ""`.
2918    Literal(SourceName),
2919
2920    /// A non-standard, vendor extension operator.
2921    VendorExtension(u8, SourceName),
2922}
2923
2924impl OperatorName {
2925    fn starts_with(byte: u8) -> bool {
2926        byte == b'c' || byte == b'l' || byte == b'v' || SimpleOperatorName::starts_with(byte)
2927    }
2928
2929    fn arity(&self) -> u8 {
2930        match self {
2931            &OperatorName::Cast(_) | &OperatorName::Conversion(_) | &OperatorName::Literal(_) => 1,
2932            &OperatorName::Simple(ref s) => s.arity(),
2933            &OperatorName::VendorExtension(arity, _) => arity,
2934        }
2935    }
2936
2937    fn parse_from_expr<'a, 'b>(
2938        ctx: &'a ParseContext,
2939        subs: &'a mut SubstitutionTable,
2940        input: IndexStr<'b>,
2941    ) -> Result<(Expression, IndexStr<'b>)> {
2942        let (operator, tail) = OperatorName::parse_internal(ctx, subs, input, true)?;
2943
2944        let arity = operator.arity();
2945        if arity == 1 {
2946            let (first, tail) = Expression::parse(ctx, subs, tail)?;
2947            let expr = Expression::Unary(operator, Box::new(first));
2948            Ok((expr, tail))
2949        } else if arity == 2 {
2950            let (first, tail) = Expression::parse(ctx, subs, tail)?;
2951            let (second, tail) = Expression::parse(ctx, subs, tail)?;
2952            let expr = Expression::Binary(operator, Box::new(first), Box::new(second));
2953            Ok((expr, tail))
2954        } else if arity == 3 {
2955            let (first, tail) = Expression::parse(ctx, subs, tail)?;
2956            let (second, tail) = Expression::parse(ctx, subs, tail)?;
2957            let (third, tail) = Expression::parse(ctx, subs, tail)?;
2958            let expr =
2959                Expression::Ternary(operator, Box::new(first), Box::new(second), Box::new(third));
2960            Ok((expr, tail))
2961        } else {
2962            Err(error::Error::UnexpectedText)
2963        }
2964    }
2965
2966    fn parse_internal<'a, 'b>(
2967        ctx: &'a ParseContext,
2968        subs: &'a mut SubstitutionTable,
2969        input: IndexStr<'b>,
2970        from_expr: bool,
2971    ) -> Result<(OperatorName, IndexStr<'b>)> {
2972        try_begin_parse!("OperatorName", ctx, input);
2973
2974        if let Ok((simple, tail)) = SimpleOperatorName::parse(ctx, subs, input) {
2975            return Ok((OperatorName::Simple(simple), tail));
2976        }
2977
2978        if let Ok(tail) = consume(b"cv", input) {
2979            // If we came through the expression path, we're a cast. If not,
2980            // we're a conversion.
2981            let previously_in_conversion = ctx.set_in_conversion(!from_expr);
2982            let parse_result = TypeHandle::parse(ctx, subs, tail);
2983            ctx.set_in_conversion(previously_in_conversion);
2984            let (ty, tail) = parse_result?;
2985            if from_expr {
2986                return Ok((OperatorName::Cast(ty), tail));
2987            } else {
2988                return Ok((OperatorName::Conversion(ty), tail));
2989            }
2990        }
2991
2992        if let Ok(tail) = consume(b"li", input) {
2993            let (name, tail) = SourceName::parse(ctx, subs, tail)?;
2994            return Ok((OperatorName::Literal(name), tail));
2995        }
2996
2997        let tail = consume(b"v", input)?;
2998        let (arity, tail) = match tail.peek() {
2999            Some(c) if b'0' <= c && c <= b'9' => (c - b'0', tail.range_from(1..)),
3000            None => return Err(error::Error::UnexpectedEnd),
3001            _ => return Err(error::Error::UnexpectedText),
3002        };
3003        let (name, tail) = SourceName::parse(ctx, subs, tail)?;
3004        Ok((OperatorName::VendorExtension(arity, name), tail))
3005    }
3006}
3007
3008impl Parse for OperatorName {
3009    fn parse<'a, 'b>(
3010        ctx: &'a ParseContext,
3011        subs: &'a mut SubstitutionTable,
3012        input: IndexStr<'b>,
3013    ) -> Result<(OperatorName, IndexStr<'b>)> {
3014        OperatorName::parse_internal(ctx, subs, input, false)
3015    }
3016}
3017
3018impl<'subs, W> Demangle<'subs, W> for OperatorName
3019where
3020    W: 'subs + DemangleWrite,
3021{
3022    fn demangle<'prev, 'ctx>(
3023        &'subs self,
3024        ctx: &'ctx mut DemangleContext<'subs, W>,
3025        scope: Option<ArgScopeStack<'prev, 'subs>>,
3026    ) -> fmt::Result {
3027        let ctx = try_begin_demangle!(self, ctx, scope);
3028
3029        match *self {
3030            OperatorName::Simple(ref simple) => {
3031                match *simple {
3032                    SimpleOperatorName::New
3033                    | SimpleOperatorName::NewArray
3034                    | SimpleOperatorName::Delete
3035                    | SimpleOperatorName::DeleteArray => {
3036                        ctx.ensure_space()?;
3037                    }
3038                    _ => {}
3039                }
3040                simple.demangle(ctx, scope)
3041            }
3042            OperatorName::Cast(ref ty) | OperatorName::Conversion(ref ty) => {
3043                ctx.ensure_space()?;
3044
3045                // Cast operators can refer to template arguments before they
3046                // actually appear in the AST, so we go traverse down the tree
3047                // and fetch them if they exist.
3048                let scope = ty
3049                    .get_template_args(ctx.subs)
3050                    .map_or(scope, |args| scope.push(args));
3051
3052                ty.demangle(ctx, scope)?;
3053                Ok(())
3054            }
3055            OperatorName::Literal(ref name) => {
3056                name.demangle(ctx, scope)?;
3057                write!(ctx, "::operator \"\"")?;
3058                Ok(())
3059            }
3060            OperatorName::VendorExtension(arity, ref name) => {
3061                // TODO: no idea how this should be demangled...
3062                name.demangle(ctx, scope)?;
3063                write!(ctx, "::operator {}", arity)?;
3064                Ok(())
3065            }
3066        }
3067    }
3068}
3069
3070define_vocabulary! {
3071    /// The `<simple-operator-name>` production.
3072    #[derive(Clone, Debug, PartialEq, Eq)]
3073    pub enum SimpleOperatorName {
3074        New              (b"nw",  "new",      3),
3075        NewArray         (b"na",  "new[]",    3),
3076        Delete           (b"dl",  "delete",   1),
3077        DeleteArray      (b"da",  "delete[]", 1),
3078        UnaryPlus        (b"ps",  "+",        1),
3079        Neg              (b"ng",  "-",        1),
3080        AddressOf        (b"ad",  "&",        1),
3081        Deref            (b"de",  "*",        1),
3082        BitNot           (b"co",  "~",        1),
3083        Add              (b"pl",  "+",        2),
3084        Sub              (b"mi",  "-",        2),
3085        Mul              (b"ml",  "*",        2),
3086        Div              (b"dv",  "/",        2),
3087        Rem              (b"rm",  "%",        2),
3088        BitAnd           (b"an",  "&",        2),
3089        BitOr            (b"or",  "|",        2),
3090        BitXor           (b"eo",  "^",        2),
3091        Assign           (b"aS",  "=",        2),
3092        AddAssign        (b"pL",  "+=",       2),
3093        SubAssign        (b"mI",  "-=",       2),
3094        MulAssign        (b"mL",  "*=",       2),
3095        DivAssign        (b"dV",  "/=",       2),
3096        RemAssign        (b"rM",  "%=",       2),
3097        BitAndAssign     (b"aN",  "&=",       2),
3098        BitOrAssign      (b"oR",  "|=",       2),
3099        BitXorAssign     (b"eO",  "^=",       2),
3100        Shl              (b"ls",  "<<",       2),
3101        Shr              (b"rs",  ">>",       2),
3102        ShlAssign        (b"lS",  "<<=",      2),
3103        ShrAssign        (b"rS",  ">>=",      2),
3104        Eq               (b"eq",  "==",       2),
3105        Ne               (b"ne",  "!=",       2),
3106        Less             (b"lt",  "<",        2),
3107        Greater          (b"gt",  ">",        2),
3108        LessEq           (b"le",  "<=",       2),
3109        GreaterEq        (b"ge",  ">=",       2),
3110        Not              (b"nt",  "!",        1),
3111        LogicalAnd       (b"aa",  "&&",       2),
3112        LogicalOr        (b"oo",  "||",       2),
3113        PostInc          (b"pp",  "++",       1), // (postfix in <expression> context)
3114        PostDec          (b"mm",  "--",       1), // (postfix in <expression> context)
3115        Comma            (b"cm",  ",",        2),
3116        DerefMemberPtr   (b"pm",  "->*",      2),
3117        DerefMember      (b"pt",  "->",       2),
3118        Call             (b"cl",  "()",       2),
3119        Index            (b"ix",  "[]",       2),
3120        Question         (b"qu",  "?:",       3),
3121        Spaceship        (b"ss",  "<=>",      2)
3122    }
3123
3124    impl SimpleOperatorName {
3125        // Automatically implemented by define_vocabulary!
3126        fn arity(&self) -> u8;
3127    }
3128}
3129
3130/// The `<call-offset>` production.
3131///
3132/// ```text
3133/// <call-offset> ::= h <nv-offset> _
3134///               ::= v <v-offset> _
3135/// ```
3136#[derive(Clone, Debug, PartialEq, Eq)]
3137pub enum CallOffset {
3138    /// A non-virtual offset.
3139    NonVirtual(NvOffset),
3140    /// A virtual offset.
3141    Virtual(VOffset),
3142}
3143
3144impl Parse for CallOffset {
3145    fn parse<'a, 'b>(
3146        ctx: &'a ParseContext,
3147        subs: &'a mut SubstitutionTable,
3148        input: IndexStr<'b>,
3149    ) -> Result<(CallOffset, IndexStr<'b>)> {
3150        try_begin_parse!("CallOffset", ctx, input);
3151
3152        if input.is_empty() {
3153            return Err(error::Error::UnexpectedEnd);
3154        }
3155
3156        if let Ok(tail) = consume(b"h", input) {
3157            let (offset, tail) = NvOffset::parse(ctx, subs, tail)?;
3158            let tail = consume(b"_", tail)?;
3159            return Ok((CallOffset::NonVirtual(offset), tail));
3160        }
3161
3162        if let Ok(tail) = consume(b"v", input) {
3163            let (offset, tail) = VOffset::parse(ctx, subs, tail)?;
3164            let tail = consume(b"_", tail)?;
3165            return Ok((CallOffset::Virtual(offset), tail));
3166        }
3167
3168        Err(error::Error::UnexpectedText)
3169    }
3170}
3171
3172impl<'subs, W> Demangle<'subs, W> for CallOffset
3173where
3174    W: 'subs + DemangleWrite,
3175{
3176    fn demangle<'prev, 'ctx>(
3177        &'subs self,
3178        ctx: &'ctx mut DemangleContext<'subs, W>,
3179        scope: Option<ArgScopeStack<'prev, 'subs>>,
3180    ) -> fmt::Result {
3181        let ctx = try_begin_demangle!(self, ctx, scope);
3182
3183        match *self {
3184            CallOffset::NonVirtual(NvOffset(offset)) => {
3185                write!(ctx, "{{offset({})}}", offset)?;
3186            }
3187            CallOffset::Virtual(VOffset(vbase, vcall)) => {
3188                write!(ctx, "{{virtual offset({}, {})}}", vbase, vcall)?;
3189            }
3190        }
3191        Ok(())
3192    }
3193}
3194
3195/// A non-virtual offset, as described by the <nv-offset> production.
3196///
3197/// ```text
3198/// <nv-offset> ::= <offset number>
3199/// ```
3200#[derive(Clone, Debug, PartialEq, Eq)]
3201pub struct NvOffset(isize);
3202
3203impl Parse for NvOffset {
3204    fn parse<'a, 'b>(
3205        ctx: &'a ParseContext,
3206        subs: &'a mut SubstitutionTable,
3207        input: IndexStr<'b>,
3208    ) -> Result<(NvOffset, IndexStr<'b>)> {
3209        try_begin_parse!("NvOffset", ctx, input);
3210
3211        Number::parse(ctx, subs, input).map(|(num, tail)| (NvOffset(num), tail))
3212    }
3213}
3214
3215/// A virtual offset, as described by the <v-offset> production.
3216///
3217/// ```text
3218/// <v-offset> ::= <offset number> _ <virtual offset number>
3219/// ```
3220#[derive(Clone, Debug, PartialEq, Eq)]
3221pub struct VOffset(isize, isize);
3222
3223impl Parse for VOffset {
3224    fn parse<'a, 'b>(
3225        ctx: &'a ParseContext,
3226        subs: &'a mut SubstitutionTable,
3227        input: IndexStr<'b>,
3228    ) -> Result<(VOffset, IndexStr<'b>)> {
3229        try_begin_parse!("VOffset", ctx, input);
3230
3231        let (offset, tail) = Number::parse(ctx, subs, input)?;
3232        let tail = consume(b"_", tail)?;
3233        let (virtual_offset, tail) = Number::parse(ctx, subs, tail)?;
3234        Ok((VOffset(offset, virtual_offset), tail))
3235    }
3236}
3237
3238/// The `<ctor-dtor-name>` production.
3239///
3240/// ```text
3241/// <ctor-dtor-name> ::= C1  # complete object constructor
3242///                  ::= C2  # base object constructor
3243///                  ::= C3  # complete object allocating constructor
3244///                  ::= D0  # deleting destructor
3245///                  ::= D1  # complete object destructor
3246///                  ::= D2  # base object destructor
3247/// ```
3248///
3249/// GCC also emits a C4 constructor under some conditions when building
3250/// an optimized binary. GCC's source says:
3251///
3252/// ```
3253/// /* This is the old-style "[unified]" constructor.
3254///    In some cases, we may emit this function and call
3255///    it from the clones in order to share code and save space.  */
3256/// ```
3257///
3258/// Based on the GCC source we'll call this the "maybe in-charge constructor".
3259/// Similarly, there is a D4 destructor, the "maybe in-charge destructor".
3260#[derive(Clone, Debug, PartialEq, Eq)]
3261pub enum CtorDtorName {
3262    /// "C1", the "complete object constructor"
3263    CompleteConstructor(Option<Box<Name>>),
3264    /// "C2", the "base object constructor"
3265    BaseConstructor(Option<Box<Name>>),
3266    /// "C3", the "complete object allocating constructor"
3267    CompleteAllocatingConstructor(Option<Box<Name>>),
3268    /// "C4", the "maybe in-charge constructor"
3269    MaybeInChargeConstructor(Option<Box<Name>>),
3270    /// "D0", the "deleting destructor"
3271    DeletingDestructor,
3272    /// "D1", the "complete object destructor"
3273    CompleteDestructor,
3274    /// "D2", the "base object destructor"
3275    BaseDestructor,
3276    /// "D4", the "maybe in-charge destructor"
3277    MaybeInChargeDestructor,
3278}
3279
3280impl CtorDtorName {
3281    fn inheriting_mut(&mut self) -> &mut Option<Box<Name>> {
3282        match self {
3283            CtorDtorName::CompleteConstructor(ref mut inheriting)
3284            | CtorDtorName::BaseConstructor(ref mut inheriting)
3285            | CtorDtorName::CompleteAllocatingConstructor(ref mut inheriting)
3286            | CtorDtorName::MaybeInChargeConstructor(ref mut inheriting) => inheriting,
3287            CtorDtorName::DeletingDestructor
3288            | CtorDtorName::CompleteDestructor
3289            | CtorDtorName::BaseDestructor
3290            | CtorDtorName::MaybeInChargeDestructor => unreachable!(),
3291        }
3292    }
3293}
3294
3295impl Parse for CtorDtorName {
3296    fn parse<'a, 'b>(
3297        ctx: &'a ParseContext,
3298        subs: &'a mut SubstitutionTable,
3299        input: IndexStr<'b>,
3300    ) -> Result<(CtorDtorName, IndexStr<'b>)> {
3301        try_begin_parse!(stringify!(CtorDtorName), ctx, input);
3302
3303        match input.peek() {
3304            Some(b'C') => {
3305                let mut tail = consume(b"C", input)?;
3306                let inheriting = match tail.peek() {
3307                    Some(b'I') => {
3308                        tail = consume(b"I", tail)?;
3309                        true
3310                    }
3311                    _ => false,
3312                };
3313
3314                let mut ctor_type: CtorDtorName = match tail
3315                    .try_split_at(1)
3316                    .as_ref()
3317                    .map(|&(ref h, t)| (h.as_ref(), t))
3318                {
3319                    None => Err(error::Error::UnexpectedEnd),
3320                    Some((b"1", t)) => {
3321                        tail = t;
3322                        Ok(CtorDtorName::CompleteConstructor(None))
3323                    }
3324                    Some((b"2", t)) => {
3325                        tail = t;
3326                        Ok(CtorDtorName::BaseConstructor(None))
3327                    }
3328                    Some((b"3", t)) => {
3329                        tail = t;
3330                        Ok(CtorDtorName::CompleteAllocatingConstructor(None))
3331                    }
3332                    Some((b"4", t)) => {
3333                        tail = t;
3334                        Ok(CtorDtorName::MaybeInChargeConstructor(None))
3335                    }
3336                    _ => Err(error::Error::UnexpectedText),
3337                }?;
3338
3339                if inheriting {
3340                    let (ty, tail) = Name::parse(ctx, subs, tail)?;
3341                    *ctor_type.inheriting_mut() = Some(Box::new(ty));
3342                    Ok((ctor_type, tail))
3343                } else {
3344                    Ok((ctor_type, tail))
3345                }
3346            }
3347            Some(b'D') => {
3348                match input
3349                    .try_split_at(2)
3350                    .as_ref()
3351                    .map(|&(ref h, t)| (h.as_ref(), t))
3352                {
3353                    Some((b"D0", tail)) => Ok((CtorDtorName::DeletingDestructor, tail)),
3354                    Some((b"D1", tail)) => Ok((CtorDtorName::CompleteDestructor, tail)),
3355                    Some((b"D2", tail)) => Ok((CtorDtorName::BaseDestructor, tail)),
3356                    Some((b"D4", tail)) => Ok((CtorDtorName::MaybeInChargeDestructor, tail)),
3357                    _ => Err(error::Error::UnexpectedText),
3358                }
3359            }
3360            None => Err(error::Error::UnexpectedEnd),
3361            _ => Err(error::Error::UnexpectedText),
3362        }
3363    }
3364}
3365
3366impl<'subs, W> Demangle<'subs, W> for CtorDtorName
3367where
3368    W: 'subs + DemangleWrite,
3369{
3370    fn demangle<'prev, 'ctx>(
3371        &'subs self,
3372        ctx: &'ctx mut DemangleContext<'subs, W>,
3373        scope: Option<ArgScopeStack<'prev, 'subs>>,
3374    ) -> fmt::Result {
3375        let ctx = try_begin_demangle!(self, ctx, scope);
3376
3377        let leaf = scope.leaf_name().map_err(|e| {
3378            log!("Error getting leaf name: {}", e);
3379            fmt::Error
3380        })?;
3381
3382        match *self {
3383            CtorDtorName::CompleteConstructor(ref inheriting)
3384            | CtorDtorName::BaseConstructor(ref inheriting)
3385            | CtorDtorName::CompleteAllocatingConstructor(ref inheriting)
3386            | CtorDtorName::MaybeInChargeConstructor(ref inheriting) => match inheriting {
3387                Some(ty) => ty
3388                    .get_leaf_name(ctx.subs)
3389                    .ok_or_else(|| {
3390                        log!("Error getting leaf name: {:?}", ty);
3391                        fmt::Error
3392                    })?
3393                    .demangle_as_leaf(ctx),
3394                None => leaf.demangle_as_leaf(ctx),
3395            },
3396            CtorDtorName::DeletingDestructor
3397            | CtorDtorName::CompleteDestructor
3398            | CtorDtorName::BaseDestructor
3399            | CtorDtorName::MaybeInChargeDestructor => {
3400                write!(ctx, "~")?;
3401                leaf.demangle_as_leaf(ctx)
3402            }
3403        }
3404    }
3405}
3406
3407impl CtorDtorName {
3408    #[inline]
3409    fn starts_with(byte: u8) -> bool {
3410        byte == b'C' || byte == b'D'
3411    }
3412}
3413
3414/// The `<type>` production.
3415///
3416/// ```text
3417/// <type> ::= <builtin-type>
3418///        ::= <function-type>
3419///        ::= <class-enum-type>
3420///        ::= <array-type>
3421///        ::= <vector-type>
3422///        ::= <pointer-to-member-type>
3423///        ::= <template-param>
3424///        ::= <template-template-param> <template-args>
3425///        ::= <decltype>
3426///        ::= <CV-qualifiers> <type>
3427///        ::= P <type>                                 # pointer-to
3428///        ::= R <type>                                 # reference-to
3429///        ::= O <type>                                 # rvalue reference-to (C++0x)
3430///        ::= C <type>                                 # complex pair (C 2000)
3431///        ::= G <type>                                 # imaginary (C 2000)
3432///        ::= U <source-name> [<template-args>] <type> # vendor extended type qualifier
3433///        ::= Dp <type>                                # pack expansion (C++0x)
3434///        ::= <substitution>
3435/// ```
3436#[derive(Clone, Debug, PartialEq, Eq)]
3437#[allow(clippy::large_enum_variant)]
3438pub enum Type {
3439    /// A function type.
3440    Function(FunctionType),
3441
3442    /// A class, union, or enum type.
3443    ClassEnum(ClassEnumType),
3444
3445    /// An array type.
3446    Array(ArrayType),
3447
3448    /// A vector type.
3449    Vector(VectorType),
3450
3451    /// A pointer-to-member type.
3452    PointerToMember(PointerToMemberType),
3453
3454    /// A named template parameter type.
3455    TemplateParam(TemplateParam),
3456
3457    /// A template template type.
3458    TemplateTemplate(TemplateTemplateParamHandle, TemplateArgs),
3459
3460    /// A decltype.
3461    Decltype(Decltype),
3462
3463    /// A const-, restrict-, and/or volatile-qualified type.
3464    Qualified(CvQualifiers, TypeHandle),
3465
3466    /// A pointer to a type.
3467    PointerTo(TypeHandle),
3468
3469    /// An lvalue reference to a type.
3470    LvalueRef(TypeHandle),
3471
3472    /// An rvalue reference to a type.
3473    RvalueRef(TypeHandle),
3474
3475    /// A complex pair of the given type.
3476    Complex(TypeHandle),
3477
3478    /// An imaginary of the given type.
3479    Imaginary(TypeHandle),
3480
3481    /// A vendor extended type qualifier.
3482    VendorExtension(SourceName, Option<TemplateArgs>, TypeHandle),
3483
3484    /// A pack expansion.
3485    PackExpansion(TypeHandle),
3486}
3487
3488define_handle! {
3489    /// A reference to a parsed `Type` production.
3490    pub enum TypeHandle {
3491        /// A builtin type. These don't end up in the substitutions table.
3492        extra Builtin(BuiltinType),
3493
3494        /// A CV-qualified builtin type. These don't end up in the table either.
3495        extra QualifiedBuiltin(QualifiedBuiltin),
3496    }
3497}
3498
3499impl TypeHandle {
3500    fn is_void(&self) -> bool {
3501        match *self {
3502            TypeHandle::Builtin(BuiltinType::Standard(StandardBuiltinType::Void)) => true,
3503            _ => false,
3504        }
3505    }
3506}
3507
3508impl Parse for TypeHandle {
3509    fn parse<'a, 'b>(
3510        ctx: &'a ParseContext,
3511        subs: &'a mut SubstitutionTable,
3512        input: IndexStr<'b>,
3513    ) -> Result<(TypeHandle, IndexStr<'b>)> {
3514        try_begin_parse!("TypeHandle", ctx, input);
3515
3516        /// Insert the given type into the substitution table, and return a
3517        /// handle referencing the index in the table where it ended up.
3518        fn insert_and_return_handle<'a, 'b>(
3519            ty: Type,
3520            subs: &'a mut SubstitutionTable,
3521            tail: IndexStr<'b>,
3522        ) -> Result<(TypeHandle, IndexStr<'b>)> {
3523            let ty = Substitutable::Type(ty);
3524            let idx = subs.insert(ty);
3525            let handle = TypeHandle::BackReference(idx);
3526            Ok((handle, tail))
3527        }
3528
3529        if let Ok((builtin, tail)) = BuiltinType::parse(ctx, subs, input) {
3530            // Builtin types are one of two exceptions that do not end up in the
3531            // substitutions table.
3532            let handle = TypeHandle::Builtin(builtin);
3533            return Ok((handle, tail));
3534        }
3535
3536        if let Ok((ty, tail)) = ClassEnumType::parse(ctx, subs, input) {
3537            let ty = Type::ClassEnum(ty);
3538            return insert_and_return_handle(ty, subs, tail);
3539        }
3540
3541        if let Ok((sub, tail)) = Substitution::parse(ctx, subs, input) {
3542            // If we see an 'I', then this is actually a substitution for a
3543            // <template-template-param>, and the template args are what
3544            // follows. Throw away what we just parsed, and re-parse it in
3545            // `TemplateTemplateParamHandle::parse` for now, but it would be
3546            // nice not to duplicate work we've already done.
3547            if tail.peek() != Some(b'I') {
3548                match sub {
3549                    Substitution::WellKnown(component) => {
3550                        return Ok((TypeHandle::WellKnown(component), tail));
3551                    }
3552                    Substitution::BackReference(idx) => {
3553                        // TODO: should this check if the back reference actually points
3554                        // to a <type>?
3555                        return Ok((TypeHandle::BackReference(idx), tail));
3556                    }
3557                }
3558            }
3559        }
3560
3561        if let Ok((funty, tail)) = FunctionType::parse(ctx, subs, input) {
3562            let ty = Type::Function(funty);
3563            return insert_and_return_handle(ty, subs, tail);
3564        }
3565
3566        if let Ok((ty, tail)) = ArrayType::parse(ctx, subs, input) {
3567            let ty = Type::Array(ty);
3568            return insert_and_return_handle(ty, subs, tail);
3569        }
3570
3571        if let Ok((ty, tail)) = VectorType::parse(ctx, subs, input) {
3572            let ty = Type::Vector(ty);
3573            return insert_and_return_handle(ty, subs, tail);
3574        }
3575
3576        if let Ok((ty, tail)) = PointerToMemberType::parse(ctx, subs, input) {
3577            let ty = Type::PointerToMember(ty);
3578            return insert_and_return_handle(ty, subs, tail);
3579        }
3580
3581        if let Ok((param, tail)) = TemplateParam::parse(ctx, subs, input) {
3582            // Same situation as with `Substitution::parse` at the top of this
3583            // function: this is actually a <template-template-param> and
3584            // <template-args>.
3585            if tail.peek() != Some(b'I') {
3586                let ty = Type::TemplateParam(param);
3587                return insert_and_return_handle(ty, subs, tail);
3588            } else if ctx.in_conversion() {
3589                // This may be <template-template-param> <template-args>.
3590                // But if we're here for a conversion operator, that's only
3591                // possible if the grammar looks like:
3592                //
3593                // <nested-name>
3594                // -> <source-name> cv <template-template-param> <template-args> <template-args>
3595                //
3596                // That is, there must be *another* <template-args> production after ours.
3597                // If there isn't one, then this really is a <template-param>.
3598                //
3599                // NB: Parsing a <template-args> production may modify the substitutions
3600                // table, so we need to avoid contaminating the official copy.
3601                let mut tmp_subs = subs.clone();
3602                if let Ok((_, new_tail)) = TemplateArgs::parse(ctx, &mut tmp_subs, tail) {
3603                    if new_tail.peek() != Some(b'I') {
3604                        // Don't consume the TemplateArgs.
3605                        let ty = Type::TemplateParam(param);
3606                        return insert_and_return_handle(ty, subs, tail);
3607                    }
3608                    // We really do have a <template-template-param>. Fall through.
3609                    // NB: We can't use the arguments we just parsed because a
3610                    // TemplateTemplateParam is substitutable, and if we use it
3611                    // any substitutions in the arguments will come *before* it,
3612                    // putting the substitution table out of order.
3613                }
3614            }
3615        }
3616
3617        if let Ok((ttp, tail)) = TemplateTemplateParamHandle::parse(ctx, subs, input) {
3618            let (args, tail) = TemplateArgs::parse(ctx, subs, tail)?;
3619            let ty = Type::TemplateTemplate(ttp, args);
3620            return insert_and_return_handle(ty, subs, tail);
3621        }
3622
3623        if let Ok((param, tail)) = Decltype::parse(ctx, subs, input) {
3624            let ty = Type::Decltype(param);
3625            return insert_and_return_handle(ty, subs, tail);
3626        }
3627
3628        if let Ok((qualifiers, tail)) = CvQualifiers::parse(ctx, subs, input) {
3629            // CvQualifiers can parse successfully without consuming any input,
3630            // but we don't want to recurse unless we know we did consume some
3631            // input, lest we go into an infinite loop and blow the stack.
3632            if tail.len() < input.len() {
3633                let (ty, tail) = TypeHandle::parse(ctx, subs, tail)?;
3634                let ty = Type::Qualified(qualifiers, ty);
3635                return insert_and_return_handle(ty, subs, tail);
3636            }
3637        }
3638
3639        if let Ok(tail) = consume(b"P", input) {
3640            let (ty, tail) = TypeHandle::parse(ctx, subs, tail)?;
3641            let ty = Type::PointerTo(ty);
3642            return insert_and_return_handle(ty, subs, tail);
3643        }
3644
3645        if let Ok(tail) = consume(b"R", input) {
3646            let (ty, tail) = TypeHandle::parse(ctx, subs, tail)?;
3647            let ty = Type::LvalueRef(ty);
3648            return insert_and_return_handle(ty, subs, tail);
3649        }
3650
3651        if let Ok(tail) = consume(b"O", input) {
3652            let (ty, tail) = TypeHandle::parse(ctx, subs, tail)?;
3653            let ty = Type::RvalueRef(ty);
3654            return insert_and_return_handle(ty, subs, tail);
3655        }
3656
3657        if let Ok(tail) = consume(b"C", input) {
3658            let (ty, tail) = TypeHandle::parse(ctx, subs, tail)?;
3659            let ty = Type::Complex(ty);
3660            return insert_and_return_handle(ty, subs, tail);
3661        }
3662
3663        if let Ok(tail) = consume(b"G", input) {
3664            let (ty, tail) = TypeHandle::parse(ctx, subs, tail)?;
3665            let ty = Type::Imaginary(ty);
3666            return insert_and_return_handle(ty, subs, tail);
3667        }
3668
3669        if let Ok(tail) = consume(b"U", input) {
3670            let (name, tail) = SourceName::parse(ctx, subs, tail)?;
3671            let (args, tail) = if let Ok((args, tail)) = TemplateArgs::parse(ctx, subs, tail) {
3672                (Some(args), tail)
3673            } else {
3674                (None, tail)
3675            };
3676            let (ty, tail) = TypeHandle::parse(ctx, subs, tail)?;
3677            let ty = Type::VendorExtension(name, args, ty);
3678            return insert_and_return_handle(ty, subs, tail);
3679        }
3680
3681        let tail = consume(b"Dp", input)?;
3682        let (ty, tail) = TypeHandle::parse(ctx, subs, tail)?;
3683        let ty = Type::PackExpansion(ty);
3684        insert_and_return_handle(ty, subs, tail)
3685    }
3686}
3687
3688impl GetTemplateArgs for TypeHandle {
3689    fn get_template_args<'a>(&'a self, subs: &'a SubstitutionTable) -> Option<&'a TemplateArgs> {
3690        subs.get_type(self)
3691            .and_then(|ty| ty.get_template_args(subs))
3692    }
3693}
3694
3695impl<'subs, W> Demangle<'subs, W> for Type
3696where
3697    W: 'subs + DemangleWrite,
3698{
3699    fn demangle<'prev, 'ctx>(
3700        &'subs self,
3701        ctx: &'ctx mut DemangleContext<'subs, W>,
3702        scope: Option<ArgScopeStack<'prev, 'subs>>,
3703    ) -> fmt::Result {
3704        let ctx = try_begin_demangle!(self, ctx, scope);
3705
3706        match *self {
3707            Type::Function(ref func_ty) => func_ty.demangle(ctx, scope),
3708            Type::ClassEnum(ref cls_enum_ty) => cls_enum_ty.demangle(ctx, scope),
3709            Type::Array(ref array_ty) => array_ty.demangle(ctx, scope),
3710            Type::Vector(ref vector_ty) => vector_ty.demangle(ctx, scope),
3711            Type::PointerToMember(ref ptm) => ptm.demangle(ctx, scope),
3712            Type::TemplateParam(ref param) => param.demangle(ctx, scope),
3713            Type::TemplateTemplate(ref tt_param, ref args) => {
3714                tt_param.demangle(ctx, scope)?;
3715                args.demangle(ctx, scope)
3716            }
3717            Type::Decltype(ref dt) => dt.demangle(ctx, scope),
3718            Type::Qualified(_, ref ty) => {
3719                ctx.push_inner(self);
3720                ty.demangle(ctx, scope)?;
3721                if ctx.pop_inner_if(self) {
3722                    self.demangle_as_inner(ctx, scope)?;
3723                }
3724                Ok(())
3725            }
3726            Type::PointerTo(ref ty) | Type::LvalueRef(ref ty) | Type::RvalueRef(ref ty) => {
3727                ctx.push_inner(self);
3728                ty.demangle(ctx, scope)?;
3729                if ctx.pop_inner_if(self) {
3730                    self.demangle_as_inner(ctx, scope)?;
3731                }
3732                Ok(())
3733            }
3734            Type::Complex(ref ty) => {
3735                ty.demangle(ctx, scope)?;
3736                write!(ctx, " complex")?;
3737                Ok(())
3738            }
3739            Type::Imaginary(ref ty) => {
3740                ty.demangle(ctx, scope)?;
3741                write!(ctx, " imaginary")?;
3742                Ok(())
3743            }
3744            Type::VendorExtension(ref name, ref template_args, ref ty) => {
3745                ty.demangle(ctx, scope)?;
3746                write!(ctx, " ")?;
3747                name.demangle(ctx, scope)?;
3748                if let Some(ref args) = *template_args {
3749                    args.demangle(ctx, scope)?;
3750                }
3751                Ok(())
3752            }
3753            Type::PackExpansion(ref ty) => {
3754                ty.demangle(ctx, scope)?;
3755                if !ctx.is_template_argument_pack {
3756                    write!(ctx, "...")?;
3757                }
3758                Ok(())
3759            }
3760        }
3761    }
3762}
3763
3764impl<'subs, W> DemangleAsInner<'subs, W> for Type
3765where
3766    W: 'subs + DemangleWrite,
3767{
3768    fn demangle_as_inner<'prev, 'ctx>(
3769        &'subs self,
3770        ctx: &'ctx mut DemangleContext<'subs, W>,
3771        scope: Option<ArgScopeStack<'prev, 'subs>>,
3772    ) -> fmt::Result {
3773        let ctx = try_begin_demangle_as_inner!(self, ctx, scope);
3774
3775        match *self {
3776            Type::Qualified(ref quals, _) => quals.demangle_as_inner(ctx, scope),
3777            Type::PointerTo(_) => write!(ctx, "*"),
3778            Type::RvalueRef(_) => {
3779                while let Some(v) = ctx.inner.last().and_then(|ty| ty.downcast_to_type()) {
3780                    match v {
3781                        // Two r-value references combine into a single r-value reference
3782                        // Consume any adjacent r-value references on the inner stack.
3783                        Type::RvalueRef(_) => {
3784                            ctx.inner.pop().unwrap();
3785                        }
3786                        // An r-value and an l-value reference combine into an l-value reference.
3787                        // Skip printing this, and allow the LvalueRef implementation to
3788                        // continue combining references.
3789                        Type::LvalueRef(_) => return Ok(()),
3790                        _ => break,
3791                    }
3792                }
3793                write!(ctx, "&&")
3794            }
3795            Type::LvalueRef(_) => {
3796                while let Some(v) = ctx.inner.last().and_then(|ty| ty.downcast_to_type()) {
3797                    match v {
3798                        // An l-value reference combines with an r-value reference to form a
3799                        // single l-value reference. Consume any adjacent r-value references
3800                        // on the inner stack.
3801                        Type::RvalueRef(_) => {
3802                            ctx.inner.pop().unwrap();
3803                        }
3804                        // Two l-value references combine to form a single l-value reference.
3805                        // Skip printing this, and allow the LvalueRef implementation for
3806                        // the next l-value reference to continue combining references.
3807                        Type::LvalueRef(_) => return Ok(()),
3808                        _ => break,
3809                    }
3810                }
3811                write!(ctx, "&")
3812            }
3813            ref otherwise => {
3814                unreachable!(
3815                    "We shouldn't ever put any other types on the inner stack: {:?}",
3816                    otherwise
3817                );
3818            }
3819        }
3820    }
3821
3822    fn downcast_to_type(&self) -> Option<&Type> {
3823        Some(self)
3824    }
3825
3826    fn downcast_to_function_type(&self) -> Option<&FunctionType> {
3827        if let Type::Function(ref f) = *self {
3828            Some(f)
3829        } else {
3830            None
3831        }
3832    }
3833
3834    fn downcast_to_array_type(&self) -> Option<&ArrayType> {
3835        if let Type::Array(ref arr) = *self {
3836            Some(arr)
3837        } else {
3838            None
3839        }
3840    }
3841
3842    fn downcast_to_pointer_to_member(&self) -> Option<&PointerToMemberType> {
3843        if let Type::PointerToMember(ref ptm) = *self {
3844            Some(ptm)
3845        } else {
3846            None
3847        }
3848    }
3849
3850    fn is_qualified(&self) -> bool {
3851        match *self {
3852            Type::Qualified(..) => true,
3853            _ => false,
3854        }
3855    }
3856}
3857
3858impl GetTemplateArgs for Type {
3859    fn get_template_args<'a>(&'a self, subs: &'a SubstitutionTable) -> Option<&'a TemplateArgs> {
3860        // TODO: This should probably recurse through all the nested type
3861        // handles too.
3862
3863        match *self {
3864            Type::VendorExtension(_, Some(ref args), _) | Type::TemplateTemplate(_, ref args) => {
3865                Some(args)
3866            }
3867            Type::PointerTo(ref ty) | Type::LvalueRef(ref ty) | Type::RvalueRef(ref ty) => {
3868                ty.get_template_args(subs)
3869            }
3870            _ => None,
3871        }
3872    }
3873}
3874
3875impl<'a> GetLeafName<'a> for Type {
3876    fn get_leaf_name(&'a self, subs: &'a SubstitutionTable) -> Option<LeafName<'a>> {
3877        match *self {
3878            Type::ClassEnum(ref cls_enum_ty) => cls_enum_ty.get_leaf_name(subs),
3879            _ => None,
3880        }
3881    }
3882}
3883
3884/// The `<CV-qualifiers>` production.
3885///
3886/// ```text
3887/// <CV-qualifiers> ::= [r] [V] [K]   # restrict (C99), volatile, const
3888/// ```
3889#[derive(Clone, Debug, Default, Hash, PartialEq, Eq)]
3890pub struct CvQualifiers {
3891    /// Is this `restrict` qualified?
3892    pub restrict: bool,
3893    /// Is this `volatile` qualified?
3894    pub volatile: bool,
3895    /// Is this `const` qualified?
3896    pub const_: bool,
3897}
3898
3899impl CvQualifiers {
3900    #[inline]
3901    fn is_empty(&self) -> bool {
3902        !self.restrict && !self.volatile && !self.const_
3903    }
3904}
3905
3906impl Parse for CvQualifiers {
3907    fn parse<'a, 'b>(
3908        ctx: &'a ParseContext,
3909        _subs: &'a mut SubstitutionTable,
3910        input: IndexStr<'b>,
3911    ) -> Result<(CvQualifiers, IndexStr<'b>)> {
3912        try_begin_parse!("CvQualifiers", ctx, input);
3913
3914        let (restrict, tail) = if let Ok(tail) = consume(b"r", input) {
3915            (true, tail)
3916        } else {
3917            (false, input)
3918        };
3919
3920        let (volatile, tail) = if let Ok(tail) = consume(b"V", tail) {
3921            (true, tail)
3922        } else {
3923            (false, tail)
3924        };
3925
3926        let (const_, tail) = if let Ok(tail) = consume(b"K", tail) {
3927            (true, tail)
3928        } else {
3929            (false, tail)
3930        };
3931
3932        let qualifiers = CvQualifiers {
3933            restrict: restrict,
3934            volatile: volatile,
3935            const_: const_,
3936        };
3937
3938        Ok((qualifiers, tail))
3939    }
3940}
3941
3942impl<'subs, W> Demangle<'subs, W> for CvQualifiers
3943where
3944    W: 'subs + DemangleWrite,
3945{
3946    fn demangle<'prev, 'ctx>(
3947        &'subs self,
3948        ctx: &'ctx mut DemangleContext<'subs, W>,
3949        scope: Option<ArgScopeStack<'prev, 'subs>>,
3950    ) -> fmt::Result {
3951        let ctx = try_begin_demangle!(self, ctx, scope);
3952
3953        if self.const_ {
3954            ctx.ensure_space()?;
3955            write!(ctx, "const")?;
3956        }
3957
3958        if self.volatile {
3959            ctx.ensure_space()?;
3960            write!(ctx, "volatile")?;
3961        }
3962
3963        if self.restrict {
3964            ctx.ensure_space()?;
3965            write!(ctx, "restrict")?;
3966        }
3967
3968        Ok(())
3969    }
3970}
3971
3972impl<'subs, W> DemangleAsInner<'subs, W> for CvQualifiers where W: 'subs + DemangleWrite {}
3973
3974define_vocabulary! {
3975    /// A <ref-qualifier> production.
3976    ///
3977    /// ```text
3978    /// <ref-qualifier> ::= R   # & ref-qualifier
3979    ///                 ::= O   # && ref-qualifier
3980    /// ```
3981    #[derive(Clone, Debug, PartialEq, Eq)]
3982    pub enum RefQualifier {
3983        LValueRef(b"R", "&"),
3984        RValueRef(b"O", "&&")
3985    }
3986}
3987
3988define_vocabulary! {
3989    /// A one of the standard variants of the <builtin-type> production.
3990    ///
3991    /// ```text
3992    /// <builtin-type> ::= v  # void
3993    ///                ::= w  # wchar_t
3994    ///                ::= b  # bool
3995    ///                ::= c  # char
3996    ///                ::= a  # signed char
3997    ///                ::= h  # unsigned char
3998    ///                ::= s  # short
3999    ///                ::= t  # unsigned short
4000    ///                ::= i  # int
4001    ///                ::= j  # unsigned int
4002    ///                ::= l  # long
4003    ///                ::= m  # unsigned long
4004    ///                ::= x  # long long, __int64
4005    ///                ::= y  # unsigned long long, __int64
4006    ///                ::= n  # __int128
4007    ///                ::= o  # unsigned __int128
4008    ///                ::= f  # float
4009    ///                ::= d  # double
4010    ///                ::= e  # long double, __float80
4011    ///                ::= g  # __float128
4012    ///                ::= z  # ellipsis
4013    ///                ::= Dd # IEEE 754r decimal floating point (64 bits)
4014    ///                ::= De # IEEE 754r decimal floating point (128 bits)
4015    ///                ::= Df # IEEE 754r decimal floating point (32 bits)
4016    ///                ::= Dh # IEEE 754r half-precision floating point (16 bits)
4017    ///                ::= Di # char32_t
4018    ///                ::= Ds # char16_t
4019    ///                ::= Du # char8_t
4020    ///                ::= Da # auto
4021    ///                ::= Dc # decltype(auto)
4022    ///                ::= Dn # std::nullptr_t (i.e., decltype(nullptr))
4023    /// ```
4024    #[derive(Clone, Debug, PartialEq, Eq)]
4025    pub enum StandardBuiltinType {
4026        Void             (b"v",  "void"),
4027        Wchar            (b"w",  "wchar_t"),
4028        Bool             (b"b",  "bool"),
4029        Char             (b"c",  "char"),
4030        SignedChar       (b"a",  "signed char"),
4031        UnsignedChar     (b"h",  "unsigned char"),
4032        Short            (b"s",  "short"),
4033        UnsignedShort    (b"t",  "unsigned short"),
4034        Int              (b"i",  "int"),
4035        UnsignedInt      (b"j",  "unsigned int"),
4036        Long             (b"l",  "long"),
4037        UnsignedLong     (b"m",  "unsigned long"),
4038        LongLong         (b"x",  "long long"),
4039        UnsignedLongLong (b"y",  "unsigned long long"),
4040        Int128           (b"n",  "__int128"),
4041        Uint128          (b"o",  "unsigned __int128"),
4042        Float            (b"f",  "float"),
4043        Double           (b"d",  "double"),
4044        LongDouble       (b"e",  "long double"),
4045        Float128         (b"g",  "__float128"),
4046        Ellipsis         (b"z",  "..."),
4047        DecimalFloat64   (b"Dd", "decimal64"),
4048        DecimalFloat128  (b"De", "decimal128"),
4049        DecimalFloat32   (b"Df", "decimal32"),
4050        DecimalFloat16   (b"Dh", "half"),
4051        Char32           (b"Di", "char32_t"),
4052        Char16           (b"Ds", "char16_t"),
4053        Char8            (b"Du", "char8_t"),
4054        Auto             (b"Da", "auto"),
4055        Decltype         (b"Dc", "decltype(auto)"),
4056        Nullptr          (b"Dn", "std::nullptr_t")
4057    }
4058}
4059
4060/// The `<builtin-type>` production.
4061#[derive(Clone, Debug, PartialEq, Eq)]
4062pub enum BuiltinType {
4063    /// A standards compliant builtin type.
4064    Standard(StandardBuiltinType),
4065
4066    /// A non-standard, vendor extension type.
4067    ///
4068    /// ```text
4069    /// <builtin-type> ::= u <source-name>   # vendor extended type
4070    /// ```
4071    Extension(SourceName),
4072}
4073
4074impl Parse for BuiltinType {
4075    fn parse<'a, 'b>(
4076        ctx: &'a ParseContext,
4077        subs: &'a mut SubstitutionTable,
4078        input: IndexStr<'b>,
4079    ) -> Result<(BuiltinType, IndexStr<'b>)> {
4080        try_begin_parse!("BuiltinType", ctx, input);
4081
4082        if let Ok((ty, tail)) = StandardBuiltinType::parse(ctx, subs, input) {
4083            return Ok((BuiltinType::Standard(ty), tail));
4084        }
4085
4086        let tail = consume(b"u", input)?;
4087        let (name, tail) = SourceName::parse(ctx, subs, tail)?;
4088        Ok((BuiltinType::Extension(name), tail))
4089    }
4090}
4091
4092impl<'subs, W> Demangle<'subs, W> for BuiltinType
4093where
4094    W: 'subs + DemangleWrite,
4095{
4096    fn demangle<'prev, 'ctx>(
4097        &'subs self,
4098        ctx: &'ctx mut DemangleContext<'subs, W>,
4099        scope: Option<ArgScopeStack<'prev, 'subs>>,
4100    ) -> fmt::Result {
4101        let ctx = try_begin_demangle!(self, ctx, scope);
4102
4103        match *self {
4104            BuiltinType::Standard(ref ty) => ty.demangle(ctx, scope),
4105            BuiltinType::Extension(ref name) => name.demangle(ctx, scope),
4106        }
4107    }
4108}
4109
4110impl<'a> GetLeafName<'a> for BuiltinType {
4111    fn get_leaf_name(&'a self, _: &'a SubstitutionTable) -> Option<LeafName<'a>> {
4112        None
4113    }
4114}
4115
4116/// A built-in type with CV-qualifiers.
4117///
4118/// Like unqualified built-in types, CV-qualified built-in types do not go into
4119/// the substitutions table.
4120#[derive(Clone, Debug, PartialEq, Eq)]
4121pub struct QualifiedBuiltin(CvQualifiers, BuiltinType);
4122
4123impl<'subs, W> Demangle<'subs, W> for QualifiedBuiltin
4124where
4125    W: 'subs + DemangleWrite,
4126{
4127    fn demangle<'prev, 'ctx>(
4128        &'subs self,
4129        ctx: &'ctx mut DemangleContext<'subs, W>,
4130        scope: Option<ArgScopeStack<'prev, 'subs>>,
4131    ) -> fmt::Result {
4132        let ctx = try_begin_demangle!(self, ctx, scope);
4133
4134        ctx.push_inner(&self.0);
4135        self.1.demangle(ctx, scope)?;
4136        if ctx.pop_inner_if(&self.0) {
4137            self.0.demangle_as_inner(ctx, scope)?;
4138        }
4139        Ok(())
4140    }
4141}
4142
4143impl<'a> GetLeafName<'a> for QualifiedBuiltin {
4144    fn get_leaf_name(&'a self, _: &'a SubstitutionTable) -> Option<LeafName<'a>> {
4145        None
4146    }
4147}
4148
4149/// The `<exception-spec>` production.
4150///
4151/// <exception-spec> ::= Do                # non-throwing exception-specification (e.g., noexcept, throw())
4152///                  ::= DO <expression> E # computed (instantiation-dependent) noexcept
4153///                  ::= Dw <type>+ E      # dynamic exception specification with instantiation-dependent types
4154#[derive(Clone, Debug, PartialEq, Eq)]
4155pub enum ExceptionSpec {
4156    /// noexcept
4157    NoExcept,
4158    /// noexcept(expression)
4159    Computed(Expression),
4160    // Dynamic exception specification is deprecated, lets see if we can get away with
4161    // not implementing it.
4162}
4163
4164impl Parse for ExceptionSpec {
4165    fn parse<'a, 'b>(
4166        ctx: &'a ParseContext,
4167        subs: &'a mut SubstitutionTable,
4168        input: IndexStr<'b>,
4169    ) -> Result<(ExceptionSpec, IndexStr<'b>)> {
4170        try_begin_parse!("ExceptionSpec", ctx, input);
4171
4172        if let Ok(tail) = consume(b"Do", input) {
4173            return Ok((ExceptionSpec::NoExcept, tail));
4174        }
4175
4176        let tail = consume(b"DO", input)?;
4177        let (expr, tail) = Expression::parse(ctx, subs, tail)?;
4178        let tail = consume(b"E", tail)?;
4179        Ok((ExceptionSpec::Computed(expr), tail))
4180    }
4181}
4182
4183impl<'subs, W> Demangle<'subs, W> for ExceptionSpec
4184where
4185    W: 'subs + DemangleWrite,
4186{
4187    fn demangle<'prev, 'ctx>(
4188        &'subs self,
4189        ctx: &'ctx mut DemangleContext<'subs, W>,
4190        scope: Option<ArgScopeStack<'prev, 'subs>>,
4191    ) -> fmt::Result {
4192        let ctx = try_begin_demangle!(self, ctx, scope);
4193
4194        match *self {
4195            ExceptionSpec::NoExcept => write!(ctx, "noexcept"),
4196            ExceptionSpec::Computed(ref expr) => {
4197                write!(ctx, "noexcept(")?;
4198                expr.demangle(ctx, scope)?;
4199                write!(ctx, ")")
4200            }
4201        }
4202    }
4203}
4204
4205/// The `<function-type>` production.
4206///
4207/// ```text
4208/// <function-type> ::= [<CV-qualifiers>] [exception-spec] [Dx] F [Y] <bare-function-type> [<ref-qualifier>] E
4209/// ```
4210#[derive(Clone, Debug, PartialEq, Eq)]
4211pub struct FunctionType {
4212    cv_qualifiers: CvQualifiers,
4213    exception_spec: Option<ExceptionSpec>,
4214    transaction_safe: bool,
4215    extern_c: bool,
4216    bare: BareFunctionType,
4217    ref_qualifier: Option<RefQualifier>,
4218}
4219
4220impl Parse for FunctionType {
4221    fn parse<'a, 'b>(
4222        ctx: &'a ParseContext,
4223        subs: &'a mut SubstitutionTable,
4224        input: IndexStr<'b>,
4225    ) -> Result<(FunctionType, IndexStr<'b>)> {
4226        try_begin_parse!("FunctionType", ctx, input);
4227
4228        let (cv_qualifiers, tail) =
4229            if let Ok((cv_qualifiers, tail)) = CvQualifiers::parse(ctx, subs, input) {
4230                (cv_qualifiers, tail)
4231            } else {
4232                (Default::default(), input)
4233            };
4234
4235        let (exception_spec, tail) =
4236            if let Ok((exception_spec, tail)) = ExceptionSpec::parse(ctx, subs, tail) {
4237                (Some(exception_spec), tail)
4238            } else {
4239                (None, tail)
4240            };
4241
4242        let (transaction_safe, tail) = if let Ok(tail) = consume(b"Dx", tail) {
4243            (true, tail)
4244        } else {
4245            (false, tail)
4246        };
4247
4248        let tail = consume(b"F", tail)?;
4249
4250        let (extern_c, tail) = if let Ok(tail) = consume(b"Y", tail) {
4251            (true, tail)
4252        } else {
4253            (false, tail)
4254        };
4255
4256        let (bare, tail) = BareFunctionType::parse(ctx, subs, tail)?;
4257
4258        let (ref_qualifier, tail) =
4259            if let Ok((ref_qualifier, tail)) = RefQualifier::parse(ctx, subs, tail) {
4260                (Some(ref_qualifier), tail)
4261            } else {
4262                (None, tail)
4263            };
4264
4265        let tail = consume(b"E", tail)?;
4266
4267        let func_ty = FunctionType {
4268            cv_qualifiers: cv_qualifiers,
4269            exception_spec: exception_spec,
4270            transaction_safe: transaction_safe,
4271            extern_c: extern_c,
4272            bare: bare,
4273            ref_qualifier: ref_qualifier,
4274        };
4275        Ok((func_ty, tail))
4276    }
4277}
4278
4279impl<'subs, W> Demangle<'subs, W> for FunctionType
4280where
4281    W: 'subs + DemangleWrite,
4282{
4283    fn demangle<'prev, 'ctx>(
4284        &'subs self,
4285        ctx: &'ctx mut DemangleContext<'subs, W>,
4286        scope: Option<ArgScopeStack<'prev, 'subs>>,
4287    ) -> fmt::Result {
4288        let ctx = try_begin_demangle!(self, ctx, scope);
4289
4290        ctx.push_inner(self);
4291        self.bare.demangle(ctx, scope)?;
4292        if ctx.pop_inner_if(self) {
4293            self.demangle_as_inner(ctx, scope)?;
4294        }
4295        if let Some(ref es) = self.exception_spec {
4296            // Print out a space before printing "noexcept"
4297            ctx.ensure_space()?;
4298            es.demangle(ctx, scope)?;
4299        }
4300        Ok(())
4301    }
4302}
4303
4304impl<'subs, W> DemangleAsInner<'subs, W> for FunctionType
4305where
4306    W: 'subs + DemangleWrite,
4307{
4308    fn demangle_as_inner<'prev, 'ctx>(
4309        &'subs self,
4310        ctx: &'ctx mut DemangleContext<'subs, W>,
4311        scope: Option<ArgScopeStack<'prev, 'subs>>,
4312    ) -> fmt::Result {
4313        let ctx = try_begin_demangle_as_inner!(self, ctx, scope);
4314
4315        if !self.cv_qualifiers.is_empty() {
4316            self.cv_qualifiers.demangle(ctx, scope)?;
4317        }
4318
4319        if let Some(ref rq) = self.ref_qualifier {
4320            // Print out a space before printing "&" or "&&"
4321            ctx.ensure_space()?;
4322            rq.demangle(ctx, scope)?;
4323        }
4324
4325        Ok(())
4326    }
4327
4328    fn downcast_to_function_type(&self) -> Option<&FunctionType> {
4329        Some(self)
4330    }
4331}
4332
4333/// The `<bare-function-type>` production.
4334///
4335/// ```text
4336/// <bare-function-type> ::= <signature type>+
4337///      # types are possible return type, then parameter types
4338/// ```
4339#[derive(Clone, Debug, PartialEq, Eq)]
4340pub struct BareFunctionType(Vec<TypeHandle>);
4341
4342impl BareFunctionType {
4343    fn ret(&self) -> &TypeHandle {
4344        &self.0[0]
4345    }
4346
4347    fn args(&self) -> &FunctionArgListAndReturnType {
4348        FunctionArgListAndReturnType::new(&self.0)
4349    }
4350}
4351
4352impl Parse for BareFunctionType {
4353    fn parse<'a, 'b>(
4354        ctx: &'a ParseContext,
4355        subs: &'a mut SubstitutionTable,
4356        input: IndexStr<'b>,
4357    ) -> Result<(BareFunctionType, IndexStr<'b>)> {
4358        try_begin_parse!("BareFunctionType", ctx, input);
4359
4360        let (types, tail) = one_or_more::<TypeHandle>(ctx, subs, input)?;
4361        Ok((BareFunctionType(types), tail))
4362    }
4363}
4364
4365impl<'subs, W> Demangle<'subs, W> for BareFunctionType
4366where
4367    W: 'subs + DemangleWrite,
4368{
4369    fn demangle<'prev, 'ctx>(
4370        &'subs self,
4371        ctx: &'ctx mut DemangleContext<'subs, W>,
4372        scope: Option<ArgScopeStack<'prev, 'subs>>,
4373    ) -> fmt::Result {
4374        let ctx = try_begin_demangle!(self, ctx, scope);
4375
4376        ctx.push_inner(self);
4377
4378        self.ret().demangle(ctx, scope)?;
4379
4380        if ctx.pop_inner_if(self) {
4381            ctx.ensure_space()?;
4382            self.demangle_as_inner(ctx, scope)?;
4383        }
4384
4385        Ok(())
4386    }
4387}
4388
4389impl<'subs, W> DemangleAsInner<'subs, W> for BareFunctionType
4390where
4391    W: 'subs + DemangleWrite,
4392{
4393    fn demangle_as_inner<'prev, 'ctx>(
4394        &'subs self,
4395        ctx: &'ctx mut DemangleContext<'subs, W>,
4396        scope: Option<ArgScopeStack<'prev, 'subs>>,
4397    ) -> fmt::Result {
4398        let ctx = try_begin_demangle_as_inner!(self, ctx, scope);
4399        self.args().demangle_as_inner(ctx, scope)?;
4400        Ok(())
4401    }
4402}
4403
4404/// The `<decltype>` production.
4405///
4406/// ```text
4407/// <decltype> ::= Dt <expression> E
4408///            ::= DT <expression> E
4409/// ```
4410#[derive(Clone, Debug, PartialEq, Eq)]
4411pub enum Decltype {
4412    /// A `decltype` of an id-expression or class member access (C++0x).
4413    IdExpression(Expression),
4414
4415    /// A `decltype` of an expression (C++0x).
4416    Expression(Expression),
4417}
4418
4419impl Parse for Decltype {
4420    fn parse<'a, 'b>(
4421        ctx: &'a ParseContext,
4422        subs: &'a mut SubstitutionTable,
4423        input: IndexStr<'b>,
4424    ) -> Result<(Decltype, IndexStr<'b>)> {
4425        try_begin_parse!("Decltype", ctx, input);
4426
4427        let tail = consume(b"D", input)?;
4428
4429        if let Ok(tail) = consume(b"t", tail) {
4430            let (expr, tail) = Expression::parse(ctx, subs, tail)?;
4431            let tail = consume(b"E", tail)?;
4432            return Ok((Decltype::IdExpression(expr), tail));
4433        }
4434
4435        let tail = consume(b"T", tail)?;
4436        let (expr, tail) = Expression::parse(ctx, subs, tail)?;
4437        let tail = consume(b"E", tail)?;
4438        Ok((Decltype::Expression(expr), tail))
4439    }
4440}
4441
4442impl<'subs, W> Demangle<'subs, W> for Decltype
4443where
4444    W: 'subs + DemangleWrite,
4445{
4446    fn demangle<'prev, 'ctx>(
4447        &'subs self,
4448        ctx: &'ctx mut DemangleContext<'subs, W>,
4449        scope: Option<ArgScopeStack<'prev, 'subs>>,
4450    ) -> fmt::Result {
4451        let ctx = try_begin_demangle!(self, ctx, scope);
4452
4453        ctx.push_demangle_node(DemangleNodeType::TemplateParam);
4454        let ret = match *self {
4455            Decltype::Expression(ref expr) | Decltype::IdExpression(ref expr) => {
4456                write!(ctx, "decltype (")?;
4457                expr.demangle(ctx, scope)?;
4458                write!(ctx, ")")?;
4459                Ok(())
4460            }
4461        };
4462        ctx.pop_demangle_node();
4463        ret
4464    }
4465}
4466
4467/// The `<class-enum-type>` production.
4468///
4469/// ```text
4470/// <class-enum-type> ::= <name>
4471///                   ::= Ts <name>
4472///                   ::= Tu <name>
4473///                   ::= Te <name>
4474/// ```
4475#[derive(Clone, Debug, PartialEq, Eq)]
4476pub enum ClassEnumType {
4477    /// A non-dependent type name, dependent type name, or dependent
4478    /// typename-specifier.
4479    Named(Name),
4480
4481    /// A dependent elaborated type specifier using 'struct' or 'class'.
4482    ElaboratedStruct(Name),
4483
4484    /// A dependent elaborated type specifier using 'union'.
4485    ElaboratedUnion(Name),
4486
4487    /// A dependent elaborated type specifier using 'enum'.
4488    ElaboratedEnum(Name),
4489}
4490
4491impl Parse for ClassEnumType {
4492    fn parse<'a, 'b>(
4493        ctx: &'a ParseContext,
4494        subs: &'a mut SubstitutionTable,
4495        input: IndexStr<'b>,
4496    ) -> Result<(ClassEnumType, IndexStr<'b>)> {
4497        try_begin_parse!("ClassEnumType", ctx, input);
4498
4499        if let Ok((name, tail)) = Name::parse(ctx, subs, input) {
4500            return Ok((ClassEnumType::Named(name), tail));
4501        }
4502
4503        let tail = consume(b"T", input)?;
4504
4505        if let Ok(tail) = consume(b"s", tail) {
4506            let (name, tail) = Name::parse(ctx, subs, tail)?;
4507            return Ok((ClassEnumType::ElaboratedStruct(name), tail));
4508        }
4509
4510        if let Ok(tail) = consume(b"u", tail) {
4511            let (name, tail) = Name::parse(ctx, subs, tail)?;
4512            return Ok((ClassEnumType::ElaboratedUnion(name), tail));
4513        }
4514
4515        let tail = consume(b"e", tail)?;
4516        let (name, tail) = Name::parse(ctx, subs, tail)?;
4517        Ok((ClassEnumType::ElaboratedEnum(name), tail))
4518    }
4519}
4520
4521impl<'subs, W> Demangle<'subs, W> for ClassEnumType
4522where
4523    W: 'subs + DemangleWrite,
4524{
4525    fn demangle<'prev, 'ctx>(
4526        &'subs self,
4527        ctx: &'ctx mut DemangleContext<'subs, W>,
4528        scope: Option<ArgScopeStack<'prev, 'subs>>,
4529    ) -> fmt::Result {
4530        let ctx = try_begin_demangle!(self, ctx, scope);
4531
4532        match *self {
4533            ClassEnumType::Named(ref name) => name.demangle(ctx, scope),
4534            ClassEnumType::ElaboratedStruct(ref name) => {
4535                write!(ctx, "class ")?;
4536                name.demangle(ctx, scope)
4537            }
4538            ClassEnumType::ElaboratedUnion(ref name) => {
4539                write!(ctx, "union ")?;
4540                name.demangle(ctx, scope)
4541            }
4542            ClassEnumType::ElaboratedEnum(ref name) => {
4543                write!(ctx, "enum ")?;
4544                name.demangle(ctx, scope)
4545            }
4546        }
4547    }
4548}
4549
4550impl<'a> GetLeafName<'a> for ClassEnumType {
4551    fn get_leaf_name(&'a self, subs: &'a SubstitutionTable) -> Option<LeafName<'a>> {
4552        match *self {
4553            ClassEnumType::Named(ref name)
4554            | ClassEnumType::ElaboratedStruct(ref name)
4555            | ClassEnumType::ElaboratedUnion(ref name)
4556            | ClassEnumType::ElaboratedEnum(ref name) => name.get_leaf_name(subs),
4557        }
4558    }
4559}
4560
4561/// The `<unnamed-type-name>` production.
4562///
4563/// ```text
4564/// <unnamed-type-name> ::= Ut [ <nonnegative number> ] _
4565///                     ::= <closure-type-name>
4566/// ```
4567///
4568/// TODO: parse the <closure-type-name> variant
4569#[derive(Clone, Debug, PartialEq, Eq)]
4570pub struct UnnamedTypeName(Option<usize>);
4571
4572impl Parse for UnnamedTypeName {
4573    fn parse<'a, 'b>(
4574        ctx: &'a ParseContext,
4575        _subs: &'a mut SubstitutionTable,
4576        input: IndexStr<'b>,
4577    ) -> Result<(UnnamedTypeName, IndexStr<'b>)> {
4578        try_begin_parse!("UnnamedTypeName", ctx, input);
4579
4580        let input = consume(b"Ut", input)?;
4581        let (number, input) = match parse_number(10, false, input) {
4582            Ok((number, input)) => (Some(number as _), input),
4583            Err(_) => (None, input),
4584        };
4585        let input = consume(b"_", input)?;
4586        Ok((UnnamedTypeName(number), input))
4587    }
4588}
4589
4590impl UnnamedTypeName {
4591    #[inline]
4592    fn starts_with(byte: u8) -> bool {
4593        byte == b'U'
4594    }
4595}
4596
4597impl<'subs, W> Demangle<'subs, W> for UnnamedTypeName
4598where
4599    W: 'subs + DemangleWrite,
4600{
4601    fn demangle<'prev, 'ctx>(
4602        &'subs self,
4603        ctx: &'ctx mut DemangleContext<'subs, W>,
4604        scope: Option<ArgScopeStack<'prev, 'subs>>,
4605    ) -> fmt::Result {
4606        let ctx = try_begin_demangle!(self, ctx, scope);
4607
4608        write!(ctx, "{{unnamed type#{}}}", self.0.map_or(1, |n| n + 1))?;
4609        Ok(())
4610    }
4611}
4612
4613impl<'subs, W> DemangleAsLeaf<'subs, W> for UnnamedTypeName
4614where
4615    W: 'subs + DemangleWrite,
4616{
4617    fn demangle_as_leaf<'me, 'ctx>(
4618        &'me self,
4619        ctx: &'ctx mut DemangleContext<'subs, W>,
4620    ) -> fmt::Result {
4621        let ctx = try_begin_demangle!(self, ctx, None);
4622        if let Some(source_name) = ctx.source_name {
4623            write!(ctx, "{}", source_name)?;
4624        } else {
4625            write!(ctx, "{{unnamed type#{}}}", self.0.map_or(1, |n| n + 1))?;
4626        }
4627        Ok(())
4628    }
4629}
4630
4631impl<'subs> ArgScope<'subs, 'subs> for UnnamedTypeName {
4632    fn leaf_name(&'subs self) -> Result<LeafName<'subs>> {
4633        Ok(LeafName::UnnamedType(self))
4634    }
4635
4636    fn get_template_arg(
4637        &'subs self,
4638        _: usize,
4639    ) -> Result<(&'subs TemplateArg, &'subs TemplateArgs)> {
4640        Err(error::Error::BadTemplateArgReference)
4641    }
4642
4643    fn get_function_arg(&'subs self, _: usize) -> Result<&'subs Type> {
4644        Err(error::Error::BadFunctionArgReference)
4645    }
4646}
4647
4648/// The `<array-type>` production.
4649///
4650/// ```text
4651/// <array-type> ::= A <positive dimension number> _ <element type>
4652///              ::= A [<dimension expression>] _ <element type>
4653/// ```
4654#[derive(Clone, Debug, PartialEq, Eq)]
4655pub enum ArrayType {
4656    /// An array with a number-literal dimension.
4657    DimensionNumber(usize, TypeHandle),
4658
4659    /// An array with an expression for its dimension.
4660    DimensionExpression(Expression, TypeHandle),
4661
4662    /// An array with no dimension.
4663    NoDimension(TypeHandle),
4664}
4665
4666impl Parse for ArrayType {
4667    fn parse<'a, 'b>(
4668        ctx: &'a ParseContext,
4669        subs: &'a mut SubstitutionTable,
4670        input: IndexStr<'b>,
4671    ) -> Result<(ArrayType, IndexStr<'b>)> {
4672        try_begin_parse!("ArrayType", ctx, input);
4673
4674        let tail = consume(b"A", input)?;
4675
4676        if let Ok((num, tail)) = parse_number(10, false, tail) {
4677            debug_assert!(num >= 0);
4678            let tail = consume(b"_", tail)?;
4679            let (ty, tail) = TypeHandle::parse(ctx, subs, tail)?;
4680            return Ok((ArrayType::DimensionNumber(num as _, ty), tail));
4681        }
4682
4683        if let Ok((expr, tail)) = Expression::parse(ctx, subs, tail) {
4684            let tail = consume(b"_", tail)?;
4685            let (ty, tail) = TypeHandle::parse(ctx, subs, tail)?;
4686            return Ok((ArrayType::DimensionExpression(expr, ty), tail));
4687        }
4688
4689        let tail = consume(b"_", tail)?;
4690        let (ty, tail) = TypeHandle::parse(ctx, subs, tail)?;
4691        Ok((ArrayType::NoDimension(ty), tail))
4692    }
4693}
4694
4695impl<'subs, W> Demangle<'subs, W> for ArrayType
4696where
4697    W: 'subs + DemangleWrite,
4698{
4699    fn demangle<'prev, 'ctx>(
4700        &'subs self,
4701        ctx: &'ctx mut DemangleContext<'subs, W>,
4702        scope: Option<ArgScopeStack<'prev, 'subs>>,
4703    ) -> fmt::Result {
4704        let ctx = try_begin_demangle!(self, ctx, scope);
4705
4706        ctx.push_inner(self);
4707
4708        match *self {
4709            ArrayType::DimensionNumber(_, ref ty)
4710            | ArrayType::DimensionExpression(_, ref ty)
4711            | ArrayType::NoDimension(ref ty) => {
4712                ty.demangle(ctx, scope)?;
4713            }
4714        }
4715
4716        if ctx.pop_inner_if(self) {
4717            self.demangle_as_inner(ctx, scope)?;
4718        }
4719
4720        Ok(())
4721    }
4722}
4723
4724impl<'subs, W> DemangleAsInner<'subs, W> for ArrayType
4725where
4726    W: 'subs + DemangleWrite,
4727{
4728    fn demangle_as_inner<'prev, 'ctx>(
4729        &'subs self,
4730        ctx: &'ctx mut DemangleContext<'subs, W>,
4731        scope: Option<ArgScopeStack<'prev, 'subs>>,
4732    ) -> fmt::Result {
4733        let ctx = try_begin_demangle_as_inner!(self, ctx, scope);
4734
4735        // Whether we should add a final space before the dimensions.
4736        let mut needs_space = true;
4737
4738        while let Some(inner) = ctx.pop_inner() {
4739            // We need to add parentheses around array inner types, unless they
4740            // are also (potentially qualified) arrays themselves, in which case
4741            // we format them as multi-dimensional arrays.
4742            let inner_is_array = match inner.downcast_to_type() {
4743                Some(&Type::Qualified(_, ref ty)) => ctx.subs.get_type(ty).map_or(false, |ty| {
4744                    DemangleAsInner::<W>::downcast_to_array_type(ty).is_some()
4745                }),
4746                _ => {
4747                    if inner.downcast_to_array_type().is_some() {
4748                        needs_space = false;
4749                        true
4750                    } else {
4751                        false
4752                    }
4753                }
4754            };
4755
4756            if inner_is_array {
4757                inner.demangle_as_inner(ctx, scope)?;
4758            } else {
4759                ctx.ensure_space()?;
4760
4761                // CvQualifiers should have the parentheses printed after, not before
4762                if inner.is_qualified() {
4763                    inner.demangle_as_inner(ctx, scope)?;
4764                    ctx.ensure_space()?;
4765                    write!(ctx, "(")?;
4766                } else {
4767                    write!(ctx, "(")?;
4768                    inner.demangle_as_inner(ctx, scope)?;
4769                }
4770
4771                ctx.demangle_inners(scope)?;
4772                write!(ctx, ")")?;
4773            }
4774        }
4775
4776        if needs_space {
4777            ctx.ensure_space()?;
4778        }
4779
4780        match *self {
4781            ArrayType::DimensionNumber(n, _) => {
4782                write!(ctx, "[{}]", n)?;
4783            }
4784            ArrayType::DimensionExpression(ref expr, _) => {
4785                write!(ctx, "[")?;
4786                expr.demangle(ctx, scope)?;
4787                write!(ctx, "]")?;
4788            }
4789            ArrayType::NoDimension(_) => {
4790                write!(ctx, "[]")?;
4791            }
4792        }
4793
4794        Ok(())
4795    }
4796
4797    fn downcast_to_array_type(&self) -> Option<&ArrayType> {
4798        Some(self)
4799    }
4800}
4801
4802/// The `<vector-type>` production.
4803///
4804/// ```text
4805/// <vector-type> ::= Dv <number> _ <type>
4806///               ::= Dv <expression> _ <type>
4807/// ```
4808#[derive(Clone, Debug, PartialEq, Eq)]
4809pub enum VectorType {
4810    /// An vector with a number-literal dimension.
4811    DimensionNumber(usize, TypeHandle),
4812
4813    /// An vector with an expression for its dimension.
4814    DimensionExpression(Expression, TypeHandle),
4815}
4816
4817impl Parse for VectorType {
4818    fn parse<'a, 'b>(
4819        ctx: &'a ParseContext,
4820        subs: &'a mut SubstitutionTable,
4821        input: IndexStr<'b>,
4822    ) -> Result<(VectorType, IndexStr<'b>)> {
4823        try_begin_parse!("VectorType", ctx, input);
4824
4825        let tail = consume(b"Dv", input)?;
4826
4827        if let Ok((num, tail)) = parse_number(10, false, tail) {
4828            debug_assert!(num >= 0);
4829            let tail = consume(b"_", tail)?;
4830            let (ty, tail) = TypeHandle::parse(ctx, subs, tail)?;
4831            return Ok((VectorType::DimensionNumber(num as _, ty), tail));
4832        }
4833
4834        let (expr, tail) = Expression::parse(ctx, subs, tail)?;
4835        let tail = consume(b"_", tail)?;
4836        let (ty, tail) = TypeHandle::parse(ctx, subs, tail)?;
4837        Ok((VectorType::DimensionExpression(expr, ty), tail))
4838    }
4839}
4840
4841impl<'subs, W> Demangle<'subs, W> for VectorType
4842where
4843    W: 'subs + DemangleWrite,
4844{
4845    fn demangle<'prev, 'ctx>(
4846        &'subs self,
4847        ctx: &'ctx mut DemangleContext<'subs, W>,
4848        scope: Option<ArgScopeStack<'prev, 'subs>>,
4849    ) -> fmt::Result {
4850        let ctx = try_begin_demangle!(self, ctx, scope);
4851
4852        ctx.push_inner(self);
4853
4854        match *self {
4855            VectorType::DimensionNumber(_, ref ty) | VectorType::DimensionExpression(_, ref ty) => {
4856                ty.demangle(ctx, scope)?;
4857            }
4858        }
4859
4860        if ctx.pop_inner_if(self) {
4861            self.demangle_as_inner(ctx, scope)?;
4862        }
4863
4864        Ok(())
4865    }
4866}
4867
4868impl<'subs, W> DemangleAsInner<'subs, W> for VectorType
4869where
4870    W: 'subs + DemangleWrite,
4871{
4872    fn demangle_as_inner<'prev, 'ctx>(
4873        &'subs self,
4874        ctx: &'ctx mut DemangleContext<'subs, W>,
4875        scope: Option<ArgScopeStack<'prev, 'subs>>,
4876    ) -> fmt::Result {
4877        let ctx = try_begin_demangle_as_inner!(self, ctx, scope);
4878
4879        match *self {
4880            VectorType::DimensionNumber(n, _) => {
4881                write!(ctx, " __vector({})", n)?;
4882            }
4883            VectorType::DimensionExpression(ref expr, _) => {
4884                write!(ctx, " __vector(")?;
4885                expr.demangle(ctx, scope)?;
4886                write!(ctx, ")")?;
4887            }
4888        }
4889
4890        Ok(())
4891    }
4892}
4893
4894/// The `<pointer-to-member-type>` production.
4895///
4896/// ```text
4897/// <pointer-to-member-type> ::= M <class type> <member type>
4898/// ```
4899#[derive(Clone, Debug, PartialEq, Eq)]
4900pub struct PointerToMemberType(TypeHandle, TypeHandle);
4901
4902impl Parse for PointerToMemberType {
4903    fn parse<'a, 'b>(
4904        ctx: &'a ParseContext,
4905        subs: &'a mut SubstitutionTable,
4906        input: IndexStr<'b>,
4907    ) -> Result<(PointerToMemberType, IndexStr<'b>)> {
4908        try_begin_parse!("PointerToMemberType", ctx, input);
4909
4910        let tail = consume(b"M", input)?;
4911        let (ty1, tail) = TypeHandle::parse(ctx, subs, tail)?;
4912        let (ty2, tail) = TypeHandle::parse(ctx, subs, tail)?;
4913        Ok((PointerToMemberType(ty1, ty2), tail))
4914    }
4915}
4916
4917impl<'subs, W> Demangle<'subs, W> for PointerToMemberType
4918where
4919    W: 'subs + DemangleWrite,
4920{
4921    fn demangle<'prev, 'ctx>(
4922        &'subs self,
4923        ctx: &'ctx mut DemangleContext<'subs, W>,
4924        scope: Option<ArgScopeStack<'prev, 'subs>>,
4925    ) -> fmt::Result {
4926        let ctx = try_begin_demangle!(self, ctx, scope);
4927
4928        ctx.push_inner(self);
4929        self.1.demangle(ctx, scope)?;
4930        if ctx.pop_inner_if(self) {
4931            self.demangle_as_inner(ctx, scope)?;
4932        }
4933        Ok(())
4934    }
4935}
4936
4937impl<'subs, W> DemangleAsInner<'subs, W> for PointerToMemberType
4938where
4939    W: 'subs + DemangleWrite,
4940{
4941    fn demangle_as_inner<'prev, 'ctx>(
4942        &'subs self,
4943        ctx: &'ctx mut DemangleContext<'subs, W>,
4944        scope: Option<ArgScopeStack<'prev, 'subs>>,
4945    ) -> fmt::Result {
4946        let ctx = try_begin_demangle_as_inner!(self, ctx, scope);
4947
4948        if ctx.last_char_written != Some('(') {
4949            ctx.ensure_space()?;
4950        }
4951
4952        self.0.demangle(ctx, scope)?;
4953        write!(ctx, "::*")?;
4954        Ok(())
4955    }
4956
4957    fn downcast_to_pointer_to_member(&self) -> Option<&PointerToMemberType> {
4958        Some(self)
4959    }
4960}
4961
4962/// The `<template-param>` production.
4963///
4964/// ```text
4965/// <template-param> ::= T_ # first template parameter
4966///                  ::= T <parameter-2 non-negative number> _
4967/// ```
4968#[derive(Clone, Debug, PartialEq, Eq)]
4969pub struct TemplateParam(usize);
4970
4971impl Parse for TemplateParam {
4972    fn parse<'a, 'b>(
4973        ctx: &'a ParseContext,
4974        _subs: &'a mut SubstitutionTable,
4975        input: IndexStr<'b>,
4976    ) -> Result<(TemplateParam, IndexStr<'b>)> {
4977        try_begin_parse!("TemplateParam", ctx, input);
4978
4979        let input = consume(b"T", input)?;
4980        let (number, input) = match parse_number(10, false, input) {
4981            Ok((number, input)) => ((number + 1) as _, input),
4982            Err(_) => (0, input),
4983        };
4984        let input = consume(b"_", input)?;
4985        Ok((TemplateParam(number), input))
4986    }
4987}
4988
4989impl<'subs, W> Demangle<'subs, W> for TemplateParam
4990where
4991    W: 'subs + DemangleWrite,
4992{
4993    fn demangle<'prev, 'ctx>(
4994        &'subs self,
4995        ctx: &'ctx mut DemangleContext<'subs, W>,
4996        scope: Option<ArgScopeStack<'prev, 'subs>>,
4997    ) -> fmt::Result {
4998        let ctx = try_begin_demangle!(self, ctx, scope);
4999
5000        ctx.push_demangle_node(DemangleNodeType::TemplateParam);
5001        let ret = if ctx.is_lambda_arg {
5002            // To match libiberty, template references are converted to `auto`.
5003            write!(ctx, "auto:{}", self.0 + 1)
5004        } else {
5005            let arg = self.resolve(scope)?;
5006            arg.demangle(ctx, scope)
5007        };
5008        ctx.pop_demangle_node();
5009        ret
5010    }
5011}
5012
5013impl TemplateParam {
5014    fn resolve<'subs, 'prev>(
5015        &'subs self,
5016        scope: Option<ArgScopeStack<'prev, 'subs>>,
5017    ) -> ::core::result::Result<&'subs TemplateArg, fmt::Error> {
5018        scope
5019            .get_template_arg(self.0)
5020            .map_err(|e| {
5021                log!("Error obtaining template argument: {}", e);
5022                fmt::Error
5023            })
5024            .map(|v| v.0)
5025    }
5026}
5027
5028impl<'a> Hash for &'a TemplateParam {
5029    fn hash<H>(&self, state: &mut H)
5030    where
5031        H: Hasher,
5032    {
5033        let self_ref: &TemplateParam = *self;
5034        let self_ptr = self_ref as *const TemplateParam;
5035        self_ptr.hash(state);
5036    }
5037}
5038
5039/// The `<template-template-param>` production.
5040///
5041/// ```text
5042/// <template-template-param> ::= <template-param>
5043///                           ::= <substitution>
5044/// ```
5045#[derive(Clone, Debug, PartialEq, Eq)]
5046pub struct TemplateTemplateParam(TemplateParam);
5047
5048define_handle! {
5049    /// A reference to a parsed `TemplateTemplateParam`.
5050    pub enum TemplateTemplateParamHandle
5051}
5052
5053impl Parse for TemplateTemplateParamHandle {
5054    fn parse<'a, 'b>(
5055        ctx: &'a ParseContext,
5056        subs: &'a mut SubstitutionTable,
5057        input: IndexStr<'b>,
5058    ) -> Result<(TemplateTemplateParamHandle, IndexStr<'b>)> {
5059        try_begin_parse!("TemplateTemplateParamHandle", ctx, input);
5060
5061        if let Ok((sub, tail)) = Substitution::parse(ctx, subs, input) {
5062            match sub {
5063                Substitution::WellKnown(component) => {
5064                    return Ok((TemplateTemplateParamHandle::WellKnown(component), tail));
5065                }
5066                Substitution::BackReference(idx) => {
5067                    // TODO: should this check if the thing at idx is a
5068                    // template-template-param? There could otherwise be ambiguity
5069                    // with <type>'s <substitution> form...
5070                    return Ok((TemplateTemplateParamHandle::BackReference(idx), tail));
5071                }
5072            }
5073        }
5074
5075        let (param, tail) = TemplateParam::parse(ctx, subs, input)?;
5076        let ttp = TemplateTemplateParam(param);
5077        let ttp = Substitutable::TemplateTemplateParam(ttp);
5078        let idx = subs.insert(ttp);
5079        let handle = TemplateTemplateParamHandle::BackReference(idx);
5080        Ok((handle, tail))
5081    }
5082}
5083
5084impl<'subs, W> Demangle<'subs, W> for TemplateTemplateParam
5085where
5086    W: 'subs + DemangleWrite,
5087{
5088    #[inline]
5089    fn demangle<'prev, 'ctx>(
5090        &'subs self,
5091        ctx: &'ctx mut DemangleContext<'subs, W>,
5092        scope: Option<ArgScopeStack<'prev, 'subs>>,
5093    ) -> fmt::Result {
5094        let ctx = try_begin_demangle!(self, ctx, scope);
5095
5096        self.0.demangle(ctx, scope)
5097    }
5098}
5099
5100/// The <function-param> production.
5101///
5102/// ```text
5103/// <function-param> ::= fp <top-level CV-qualifiers> _
5104///                          # L == 0, first parameter
5105///                  ::= fp <top-level CV-qualifiers> <parameter-2 non-negative number> _
5106///                          # L == 0, second and later parameters
5107///                  ::= fL <L-1 non-negative number> p <top-level CV-qualifiers> _
5108///                          # L > 0, first parameter
5109///                  ::= fL <L-1 non-negative number> p <top-level CV-qualifiers> <parameter-2 non-negative number> _
5110///                          # L > 0, second and later parameters
5111/// ```
5112#[derive(Clone, Debug, PartialEq, Eq)]
5113pub struct FunctionParam(usize, CvQualifiers, Option<usize>);
5114
5115impl Parse for FunctionParam {
5116    fn parse<'a, 'b>(
5117        ctx: &'a ParseContext,
5118        subs: &'a mut SubstitutionTable,
5119        input: IndexStr<'b>,
5120    ) -> Result<(FunctionParam, IndexStr<'b>)> {
5121        try_begin_parse!("FunctionParam", ctx, input);
5122
5123        let tail = consume(b"f", input)?;
5124        if tail.is_empty() {
5125            return Err(error::Error::UnexpectedEnd);
5126        }
5127
5128        let (scope, tail) = if let Ok(tail) = consume(b"L", tail) {
5129            parse_number(10, false, tail)?
5130        } else {
5131            (0, tail)
5132        };
5133
5134        let tail = consume(b"p", tail)?;
5135
5136        let (qualifiers, tail) = CvQualifiers::parse(ctx, subs, tail)?;
5137
5138        let (param, tail) = if tail.peek() == Some(b'T') {
5139            (None, consume(b"T", tail)?)
5140        } else if let Ok((num, tail)) = parse_number(10, false, tail) {
5141            (Some(num as usize + 1), consume(b"_", tail)?)
5142        } else {
5143            (Some(0), consume(b"_", tail)?)
5144        };
5145
5146        Ok((FunctionParam(scope as _, qualifiers, param), tail))
5147    }
5148}
5149
5150impl<'subs, W> Demangle<'subs, W> for FunctionParam
5151where
5152    W: 'subs + DemangleWrite,
5153{
5154    fn demangle<'prev, 'ctx>(
5155        &'subs self,
5156        ctx: &'ctx mut DemangleContext<'subs, W>,
5157        scope: Option<ArgScopeStack<'prev, 'subs>>,
5158    ) -> fmt::Result {
5159        let ctx = try_begin_demangle!(self, ctx, scope);
5160
5161        match self.2 {
5162            None => write!(ctx, "this"),
5163            Some(i) => write!(ctx, "{{parm#{}}}", i + 1),
5164        }
5165    }
5166}
5167
5168/// The `<template-args>` production.
5169///
5170/// ```text
5171/// <template-args> ::= I <template-arg>+ E
5172/// ```
5173#[derive(Clone, Debug, PartialEq, Eq)]
5174pub struct TemplateArgs(Vec<TemplateArg>);
5175
5176impl Parse for TemplateArgs {
5177    fn parse<'a, 'b>(
5178        ctx: &'a ParseContext,
5179        subs: &'a mut SubstitutionTable,
5180        input: IndexStr<'b>,
5181    ) -> Result<(TemplateArgs, IndexStr<'b>)> {
5182        try_begin_parse!("TemplateArgs", ctx, input);
5183
5184        let tail = consume(b"I", input)?;
5185
5186        let (args, tail) = one_or_more::<TemplateArg>(ctx, subs, tail)?;
5187        let tail = consume(b"E", tail)?;
5188        Ok((TemplateArgs(args), tail))
5189    }
5190}
5191
5192impl<'subs, W> Demangle<'subs, W> for TemplateArgs
5193where
5194    W: 'subs + DemangleWrite,
5195{
5196    fn demangle<'prev, 'ctx>(
5197        &'subs self,
5198        ctx: &'ctx mut DemangleContext<'subs, W>,
5199        mut scope: Option<ArgScopeStack<'prev, 'subs>>,
5200    ) -> fmt::Result {
5201        let ctx = try_begin_demangle!(self, ctx, scope);
5202        inner_barrier!(ctx);
5203
5204        if ctx.last_char_written == Some('<') {
5205            write!(ctx, " ")?;
5206        }
5207        write!(ctx, "<")?;
5208        ctx.push_demangle_node(DemangleNodeType::TemplateArgs);
5209        let mut need_comma = false;
5210        for arg_index in 0..self.0.len() {
5211            if need_comma {
5212                write!(ctx, ", ")?;
5213            }
5214            if let Some(ref mut scope) = scope {
5215                scope.in_arg = Some((arg_index, self));
5216            }
5217            self.0[arg_index].demangle(ctx, scope)?;
5218            need_comma = true;
5219        }
5220
5221        // Ensure "> >" because old C++ sucks and libiberty (and its tests)
5222        // supports old C++.
5223        if ctx.last_char_written == Some('>') {
5224            write!(ctx, " ")?;
5225        }
5226        ctx.pop_demangle_node();
5227        write!(ctx, ">")?;
5228        Ok(())
5229    }
5230}
5231
5232impl<'subs> ArgScope<'subs, 'subs> for TemplateArgs {
5233    fn leaf_name(&'subs self) -> Result<LeafName<'subs>> {
5234        Err(error::Error::BadLeafNameReference)
5235    }
5236
5237    fn get_template_arg(
5238        &'subs self,
5239        idx: usize,
5240    ) -> Result<(&'subs TemplateArg, &'subs TemplateArgs)> {
5241        self.0
5242            .get(idx)
5243            .ok_or(error::Error::BadTemplateArgReference)
5244            .map(|v| (v, self))
5245    }
5246
5247    fn get_function_arg(&'subs self, _: usize) -> Result<&'subs Type> {
5248        Err(error::Error::BadFunctionArgReference)
5249    }
5250}
5251
5252/// A <template-arg> production.
5253///
5254/// ```text
5255/// <template-arg> ::= <type>                # type or template
5256///                ::= X <expression> E      # expression
5257///                ::= <expr-primary>        # simple expressions
5258///                ::= J <template-arg>* E   # argument pack
5259/// ```
5260#[derive(Clone, Debug, PartialEq, Eq)]
5261pub enum TemplateArg {
5262    /// A type or template.
5263    Type(TypeHandle),
5264
5265    /// An expression.
5266    Expression(Expression),
5267
5268    /// A simple expression.
5269    SimpleExpression(ExprPrimary),
5270
5271    /// An argument pack.
5272    ArgPack(Vec<TemplateArg>),
5273}
5274
5275impl Parse for TemplateArg {
5276    fn parse<'a, 'b>(
5277        ctx: &'a ParseContext,
5278        subs: &'a mut SubstitutionTable,
5279        input: IndexStr<'b>,
5280    ) -> Result<(TemplateArg, IndexStr<'b>)> {
5281        try_begin_parse!("TemplateArg", ctx, input);
5282
5283        if let Ok(tail) = consume(b"X", input) {
5284            let (expr, tail) = Expression::parse(ctx, subs, tail)?;
5285            let tail = consume(b"E", tail)?;
5286            return Ok((TemplateArg::Expression(expr), tail));
5287        }
5288
5289        if let Ok((expr, tail)) = ExprPrimary::parse(ctx, subs, input) {
5290            return Ok((TemplateArg::SimpleExpression(expr), tail));
5291        }
5292
5293        if let Ok((ty, tail)) = TypeHandle::parse(ctx, subs, input) {
5294            return Ok((TemplateArg::Type(ty), tail));
5295        }
5296
5297        let tail = if input.peek() == Some(b'J') {
5298            consume(b"J", input)?
5299        } else {
5300            consume(b"I", input)?
5301        };
5302
5303        let (args, tail) = if tail.peek() == Some(b'E') {
5304            (vec![], tail)
5305        } else {
5306            zero_or_more::<TemplateArg>(ctx, subs, tail)?
5307        };
5308        let tail = consume(b"E", tail)?;
5309        Ok((TemplateArg::ArgPack(args), tail))
5310    }
5311}
5312
5313impl<'subs, W> Demangle<'subs, W> for TemplateArg
5314where
5315    W: 'subs + DemangleWrite,
5316{
5317    fn demangle<'prev, 'ctx>(
5318        &'subs self,
5319        ctx: &'ctx mut DemangleContext<'subs, W>,
5320        scope: Option<ArgScopeStack<'prev, 'subs>>,
5321    ) -> fmt::Result {
5322        let ctx = try_begin_demangle!(self, ctx, scope);
5323
5324        match *self {
5325            TemplateArg::Type(ref ty) => ty.demangle(ctx, scope),
5326            TemplateArg::Expression(ref expr) => expr.demangle(ctx, scope),
5327            TemplateArg::SimpleExpression(ref expr) => expr.demangle(ctx, scope),
5328            TemplateArg::ArgPack(ref args) => {
5329                ctx.is_template_argument_pack = true;
5330                let mut need_comma = false;
5331                for arg in &args[..] {
5332                    if need_comma {
5333                        write!(ctx, ", ")?;
5334                    }
5335                    arg.demangle(ctx, scope)?;
5336                    need_comma = true;
5337                }
5338                Ok(())
5339            }
5340        }
5341    }
5342}
5343
5344/// In libiberty, Member and DerefMember expressions have special handling.
5345/// They parse an `UnqualifiedName` (not an `UnscopedName` as the cxxabi docs
5346/// say) and optionally a `TemplateArgs` if it is present. We can't just parse
5347/// a `Name` or an `UnscopedTemplateName` here because that allows other inputs
5348/// that libiberty does not.
5349#[derive(Clone, Debug, PartialEq, Eq)]
5350pub struct MemberName(Name);
5351
5352impl Parse for MemberName {
5353    fn parse<'a, 'b>(
5354        ctx: &'a ParseContext,
5355        subs: &'a mut SubstitutionTable,
5356        input: IndexStr<'b>,
5357    ) -> Result<(MemberName, IndexStr<'b>)> {
5358        try_begin_parse!("MemberName", ctx, input);
5359
5360        let (name, tail) = UnqualifiedName::parse(ctx, subs, input)?;
5361        let name = UnscopedName::Unqualified(name);
5362        if let Ok((template, tail)) = TemplateArgs::parse(ctx, subs, tail) {
5363            let name = UnscopedTemplateName(name);
5364            // In libiberty, these are unsubstitutable.
5365            let idx = subs.insert_non_substitution(Substitutable::UnscopedTemplateName(name));
5366            let handle = UnscopedTemplateNameHandle::NonSubstitution(NonSubstitution(idx));
5367            Ok((MemberName(Name::UnscopedTemplate(handle, template)), tail))
5368        } else {
5369            Ok((MemberName(Name::Unscoped(name)), tail))
5370        }
5371    }
5372}
5373
5374impl<'subs, W> Demangle<'subs, W> for MemberName
5375where
5376    W: 'subs + DemangleWrite,
5377{
5378    fn demangle<'prev, 'ctx>(
5379        &'subs self,
5380        ctx: &'ctx mut DemangleContext<'subs, W>,
5381        scope: Option<ArgScopeStack<'prev, 'subs>>,
5382    ) -> fmt::Result {
5383        let ctx = try_begin_demangle!(self, ctx, scope);
5384
5385        let needs_parens = self.0.get_template_args(ctx.subs).is_some();
5386        if needs_parens {
5387            write!(ctx, "(")?;
5388        }
5389
5390        self.0.demangle(ctx, scope)?;
5391
5392        if needs_parens {
5393            write!(ctx, ")")?;
5394        }
5395
5396        Ok(())
5397    }
5398}
5399
5400/// The `<expression>` production.
5401///
5402/// ```text
5403///  <expression> ::= <unary operator-name> <expression>
5404///               ::= <binary operator-name> <expression> <expression>
5405///               ::= <ternary operator-name> <expression> <expression> <expression>
5406///               ::= pp_ <expression>                             # prefix ++
5407///               ::= mm_ <expression>                             # prefix --
5408///               ::= cl <expression>+ E                           # expression (expr-list), call
5409///               ::= cv <type> <expression>                       # type (expression), conversion with one argument
5410///               ::= cv <type> _ <expression>* E                  # type (expr-list), conversion with other than one argument
5411///               ::= tl <type> <expression>* E                    # type {expr-list}, conversion with braced-init-list argument
5412///               ::= il <expression> E                            # {expr-list}, braced-init-list in any other context
5413///               ::= [gs] nw <expression>* _ <type> E             # new (expr-list) type
5414///               ::= [gs] nw <expression>* _ <type> <initializer> # new (expr-list) type (init)
5415///               ::= [gs] na <expression>* _ <type> E             # new[] (expr-list) type
5416///               ::= [gs] na <expression>* _ <type> <initializer> # new[] (expr-list) type (init)
5417///               ::= [gs] dl <expression>                         # delete expression
5418///               ::= [gs] da <expression>                         # delete[] expression
5419///               ::= dc <type> <expression>                       # dynamic_cast<type> (expression)
5420///               ::= sc <type> <expression>                       # static_cast<type> (expression)
5421///               ::= cc <type> <expression>                       # const_cast<type> (expression)
5422///               ::= rc <type> <expression>                       # reinterpret_cast<type> (expression)
5423///               ::= ti <type>                                    # typeid (type)
5424///               ::= te <expression>                              # typeid (expression)
5425///               ::= st <type>                                    # sizeof (type)
5426///               ::= sz <expression>                              # sizeof (expression)
5427///               ::= at <type>                                    # alignof (type)
5428///               ::= az <expression>                              # alignof (expression)
5429///               ::= nx <expression>                              # noexcept (expression)
5430///               ::= so <subobject-expr>
5431///               ::= <template-param>
5432///               ::= <function-param>
5433///               ::= dt <expression> <unresolved-name>            # expr.name
5434///               ::= pt <expression> <unresolved-name>            # expr->name
5435///               ::= ds <expression> <expression>                 # expr.*expr
5436///               ::= sZ <template-param>                          # sizeof...(T), size of a template parameter pack
5437///               ::= sZ <function-param>                          # sizeof...(parameter), size of a function parameter pack
5438///               ::= sP <template-arg>* E                         # sizeof...(T), size of a captured template parameter pack from an alias template
5439///               ::= sp <expression>                              # expression..., pack expansion
5440///               ::= tw <expression>                              # throw expression
5441///               ::= tr                                           # throw with no operand (rethrow)
5442///               ::= <unresolved-name>                            # f(p), N::f(p), ::f(p),
5443///                                                                # freestanding dependent name (e.g., T::x),
5444///                                                                # objectless nonstatic member reference
5445///               ::= <expr-primary>
5446/// ```
5447#[derive(Clone, Debug, PartialEq, Eq)]
5448pub enum Expression {
5449    /// A unary operator expression.
5450    Unary(OperatorName, Box<Expression>),
5451
5452    /// A binary operator expression.
5453    Binary(OperatorName, Box<Expression>, Box<Expression>),
5454
5455    /// A ternary operator expression.
5456    Ternary(
5457        OperatorName,
5458        Box<Expression>,
5459        Box<Expression>,
5460        Box<Expression>,
5461    ),
5462
5463    /// A prefix `++`.
5464    PrefixInc(Box<Expression>),
5465
5466    /// A prefix `--`.
5467    PrefixDec(Box<Expression>),
5468
5469    /// A call with functor and arguments.
5470    Call(Box<Expression>, Vec<Expression>),
5471
5472    /// A type conversion with one argument.
5473    ConversionOne(TypeHandle, Box<Expression>),
5474
5475    /// A type conversion with many arguments.
5476    ConversionMany(TypeHandle, Vec<Expression>),
5477
5478    /// A type conversion with many arguments.
5479    ConversionBraced(TypeHandle, Vec<Expression>),
5480
5481    /// A braced init list expression.
5482    BracedInitList(Box<Expression>),
5483
5484    /// The `new` operator.
5485    New(Vec<Expression>, TypeHandle, Option<Initializer>),
5486
5487    /// The global `::new` operator.
5488    GlobalNew(Vec<Expression>, TypeHandle, Option<Initializer>),
5489
5490    /// The `new[]` operator.
5491    NewArray(Vec<Expression>, TypeHandle, Option<Initializer>),
5492
5493    /// The global `::new[]` operator.
5494    GlobalNewArray(Vec<Expression>, TypeHandle, Option<Initializer>),
5495
5496    /// The `delete` operator.
5497    Delete(Box<Expression>),
5498
5499    /// The global `::delete` operator.
5500    GlobalDelete(Box<Expression>),
5501
5502    /// The `delete[]` operator.
5503    DeleteArray(Box<Expression>),
5504
5505    /// The global `::delete[]` operator.
5506    GlobalDeleteArray(Box<Expression>),
5507
5508    /// `dynamic_cast<type> (expression)`
5509    DynamicCast(TypeHandle, Box<Expression>),
5510
5511    /// `static_cast<type> (expression)`
5512    StaticCast(TypeHandle, Box<Expression>),
5513
5514    /// `const_cast<type> (expression)`
5515    ConstCast(TypeHandle, Box<Expression>),
5516
5517    /// `reinterpret_cast<type> (expression)`
5518    ReinterpretCast(TypeHandle, Box<Expression>),
5519
5520    /// `typeid (type)`
5521    TypeidType(TypeHandle),
5522
5523    /// `typeid (expression)`
5524    TypeidExpr(Box<Expression>),
5525
5526    /// `sizeof (type)`
5527    SizeofType(TypeHandle),
5528
5529    /// `sizeof (expression)`
5530    SizeofExpr(Box<Expression>),
5531
5532    /// `alignof (type)`
5533    AlignofType(TypeHandle),
5534
5535    /// `alignof (expression)`
5536    AlignofExpr(Box<Expression>),
5537
5538    /// `noexcept (expression)`
5539    Noexcept(Box<Expression>),
5540
5541    /// Subobject expression,
5542    Subobject(SubobjectExpr),
5543
5544    /// A named template parameter.
5545    TemplateParam(TemplateParam),
5546
5547    /// A function parameter.
5548    FunctionParam(FunctionParam),
5549
5550    /// `expr.name`
5551    Member(Box<Expression>, MemberName),
5552
5553    /// `expr->name`
5554    DerefMember(Box<Expression>, MemberName),
5555
5556    /// `expr.*expr`
5557    PointerToMember(Box<Expression>, Box<Expression>),
5558
5559    /// `sizeof...(T)`, size of a template parameter pack.
5560    SizeofTemplatePack(TemplateParam),
5561
5562    /// `sizeof...(parameter)`, size of a function parameter pack.
5563    SizeofFunctionPack(FunctionParam),
5564
5565    /// `sizeof...(T)`, size of a captured template parameter pack from an alias
5566    /// template.
5567    SizeofCapturedTemplatePack(Vec<TemplateArg>),
5568
5569    /// `expression...`, pack expansion.
5570    PackExpansion(Box<Expression>),
5571
5572    /// `throw expression`
5573    Throw(Box<Expression>),
5574
5575    /// `throw` with no operand
5576    Rethrow,
5577
5578    /// `f(p)`, `N::f(p)`, `::f(p)`, freestanding dependent name (e.g., `T::x`),
5579    /// objectless nonstatic member reference.
5580    UnresolvedName(UnresolvedName),
5581
5582    /// An `<expr-primary>` production.
5583    Primary(ExprPrimary),
5584}
5585
5586impl Parse for Expression {
5587    fn parse<'a, 'b>(
5588        ctx: &'a ParseContext,
5589        subs: &'a mut SubstitutionTable,
5590        input: IndexStr<'b>,
5591    ) -> Result<(Expression, IndexStr<'b>)> {
5592        try_begin_parse!("Expression", ctx, input);
5593
5594        if let Ok(tail) = consume(b"pp_", input) {
5595            let (expr, tail) = Expression::parse(ctx, subs, tail)?;
5596            let expr = Expression::PrefixInc(Box::new(expr));
5597            return Ok((expr, tail));
5598        }
5599
5600        if let Ok(tail) = consume(b"mm_", input) {
5601            let (expr, tail) = Expression::parse(ctx, subs, tail)?;
5602            let expr = Expression::PrefixDec(Box::new(expr));
5603            return Ok((expr, tail));
5604        }
5605
5606        if let Some((head, tail)) = input.try_split_at(2) {
5607            match head.as_ref() {
5608                b"cl" => {
5609                    let (func, tail) = Expression::parse(ctx, subs, tail)?;
5610                    let (args, tail) = zero_or_more::<Expression>(ctx, subs, tail)?;
5611                    let tail = consume(b"E", tail)?;
5612                    let expr = Expression::Call(Box::new(func), args);
5613                    return Ok((expr, tail));
5614                }
5615                b"cv" => {
5616                    let (ty, tail) = TypeHandle::parse(ctx, subs, tail)?;
5617                    if let Ok(tail) = consume(b"_", tail) {
5618                        let (exprs, tail) = zero_or_more::<Expression>(ctx, subs, tail)?;
5619                        let tail = consume(b"E", tail)?;
5620                        let expr = Expression::ConversionMany(ty, exprs);
5621                        return Ok((expr, tail));
5622                    } else {
5623                        let (expr, tail) = Expression::parse(ctx, subs, tail)?;
5624                        let expr = Expression::ConversionOne(ty, Box::new(expr));
5625                        return Ok((expr, tail));
5626                    }
5627                }
5628                b"tl" => {
5629                    let (ty, tail) = TypeHandle::parse(ctx, subs, tail)?;
5630                    let (exprs, tail) = zero_or_more::<Expression>(ctx, subs, tail)?;
5631                    let expr = Expression::ConversionBraced(ty, exprs);
5632                    let tail = consume(b"E", tail)?;
5633                    return Ok((expr, tail));
5634                }
5635                b"il" => {
5636                    let (expr, tail) = Expression::parse(ctx, subs, tail)?;
5637                    let tail = consume(b"E", tail)?;
5638                    let expr = Expression::BracedInitList(Box::new(expr));
5639                    return Ok((expr, tail));
5640                }
5641                b"dc" => {
5642                    let (ty, tail) = TypeHandle::parse(ctx, subs, tail)?;
5643                    let (expr, tail) = Expression::parse(ctx, subs, tail)?;
5644                    let expr = Expression::DynamicCast(ty, Box::new(expr));
5645                    return Ok((expr, tail));
5646                }
5647                b"sc" => {
5648                    let (ty, tail) = TypeHandle::parse(ctx, subs, tail)?;
5649                    let (expr, tail) = Expression::parse(ctx, subs, tail)?;
5650                    let expr = Expression::StaticCast(ty, Box::new(expr));
5651                    return Ok((expr, tail));
5652                }
5653                b"cc" => {
5654                    let (ty, tail) = TypeHandle::parse(ctx, subs, tail)?;
5655                    let (expr, tail) = Expression::parse(ctx, subs, tail)?;
5656                    let expr = Expression::ConstCast(ty, Box::new(expr));
5657                    return Ok((expr, tail));
5658                }
5659                b"rc" => {
5660                    let (ty, tail) = TypeHandle::parse(ctx, subs, tail)?;
5661                    let (expr, tail) = Expression::parse(ctx, subs, tail)?;
5662                    let expr = Expression::ReinterpretCast(ty, Box::new(expr));
5663                    return Ok((expr, tail));
5664                }
5665                b"ti" => {
5666                    let (ty, tail) = TypeHandle::parse(ctx, subs, tail)?;
5667                    let expr = Expression::TypeidType(ty);
5668                    return Ok((expr, tail));
5669                }
5670                b"te" => {
5671                    let (expr, tail) = Expression::parse(ctx, subs, tail)?;
5672                    let expr = Expression::TypeidExpr(Box::new(expr));
5673                    return Ok((expr, tail));
5674                }
5675                b"st" => {
5676                    let (ty, tail) = TypeHandle::parse(ctx, subs, tail)?;
5677                    let expr = Expression::SizeofType(ty);
5678                    return Ok((expr, tail));
5679                }
5680                b"sz" => {
5681                    let (expr, tail) = Expression::parse(ctx, subs, tail)?;
5682                    let expr = Expression::SizeofExpr(Box::new(expr));
5683                    return Ok((expr, tail));
5684                }
5685                b"at" => {
5686                    let (ty, tail) = TypeHandle::parse(ctx, subs, tail)?;
5687                    let expr = Expression::AlignofType(ty);
5688                    return Ok((expr, tail));
5689                }
5690                b"az" => {
5691                    let (expr, tail) = Expression::parse(ctx, subs, tail)?;
5692                    let expr = Expression::AlignofExpr(Box::new(expr));
5693                    return Ok((expr, tail));
5694                }
5695                b"nx" => {
5696                    let (expr, tail) = Expression::parse(ctx, subs, tail)?;
5697                    let expr = Expression::Noexcept(Box::new(expr));
5698                    return Ok((expr, tail));
5699                }
5700                b"so" => {
5701                    let (expr, tail) = SubobjectExpr::parse(ctx, subs, tail)?;
5702                    let expr = Expression::Subobject(expr);
5703                    return Ok((expr, tail));
5704                }
5705                b"dt" => {
5706                    let (expr, tail) = Expression::parse(ctx, subs, tail)?;
5707                    let (name, tail) = MemberName::parse(ctx, subs, tail)?;
5708                    let expr = Expression::Member(Box::new(expr), name);
5709                    return Ok((expr, tail));
5710                }
5711                b"pt" => {
5712                    let (expr, tail) = Expression::parse(ctx, subs, tail)?;
5713                    let (name, tail) = MemberName::parse(ctx, subs, tail)?;
5714                    let expr = Expression::DerefMember(Box::new(expr), name);
5715                    return Ok((expr, tail));
5716                }
5717                b"ds" => {
5718                    let (first, tail) = Expression::parse(ctx, subs, tail)?;
5719                    let (second, tail) = Expression::parse(ctx, subs, tail)?;
5720                    let expr = Expression::PointerToMember(Box::new(first), Box::new(second));
5721                    return Ok((expr, tail));
5722                }
5723                b"sZ" => {
5724                    if let Ok((param, tail)) = TemplateParam::parse(ctx, subs, tail) {
5725                        let expr = Expression::SizeofTemplatePack(param);
5726                        return Ok((expr, tail));
5727                    }
5728
5729                    let (param, tail) = FunctionParam::parse(ctx, subs, tail)?;
5730                    let expr = Expression::SizeofFunctionPack(param);
5731                    return Ok((expr, tail));
5732                }
5733                b"sP" => {
5734                    let (args, tail) = zero_or_more::<TemplateArg>(ctx, subs, tail)?;
5735                    let expr = Expression::SizeofCapturedTemplatePack(args);
5736                    let tail = consume(b"E", tail)?;
5737                    return Ok((expr, tail));
5738                }
5739                b"sp" => {
5740                    let (expr, tail) = Expression::parse(ctx, subs, tail)?;
5741                    let expr = Expression::PackExpansion(Box::new(expr));
5742                    return Ok((expr, tail));
5743                }
5744                b"tw" => {
5745                    let (expr, tail) = Expression::parse(ctx, subs, tail)?;
5746                    let expr = Expression::Throw(Box::new(expr));
5747                    return Ok((expr, tail));
5748                }
5749                b"tr" => {
5750                    let expr = Expression::Rethrow;
5751                    return Ok((expr, tail));
5752                }
5753                b"gs" => {
5754                    if let Ok((expr, tail)) = can_be_global(true, ctx, subs, tail) {
5755                        return Ok((expr, tail));
5756                    }
5757                }
5758                _ => {}
5759            }
5760        }
5761
5762        if let Ok((expr, tail)) = can_be_global(false, ctx, subs, input) {
5763            return Ok((expr, tail));
5764        }
5765
5766        if let Ok((param, tail)) = TemplateParam::parse(ctx, subs, input) {
5767            let expr = Expression::TemplateParam(param);
5768            return Ok((expr, tail));
5769        }
5770
5771        if let Ok((param, tail)) = FunctionParam::parse(ctx, subs, input) {
5772            let expr = Expression::FunctionParam(param);
5773            return Ok((expr, tail));
5774        }
5775
5776        if let Ok((name, tail)) = UnresolvedName::parse(ctx, subs, input) {
5777            let expr = Expression::UnresolvedName(name);
5778            return Ok((expr, tail));
5779        }
5780
5781        if let Ok((prim, tail)) = ExprPrimary::parse(ctx, subs, input) {
5782            let expr = Expression::Primary(prim);
5783            return Ok((expr, tail));
5784        }
5785
5786        // "A production for <expression> that directly specifies an operation
5787        // code (e.g., for the -> operator) takes precedence over one that is
5788        // expressed in terms of (unary/binary/ternary) <operator-name>." So try
5789        // and parse unary/binary/ternary expressions last.
5790        let (expr, tail) = OperatorName::parse_from_expr(ctx, subs, input)?;
5791        return Ok((expr, tail));
5792
5793        // Parse the various expressions that can optionally have a leading "gs"
5794        // to indicate that they are in the global namespace. The input is after
5795        // we have already detected consumed the optional "gs" and if we did
5796        // find it, then `is_global` should be true.
5797        fn can_be_global<'a, 'b>(
5798            is_global: bool,
5799            ctx: &'a ParseContext,
5800            subs: &'a mut SubstitutionTable,
5801            input: IndexStr<'b>,
5802        ) -> Result<(Expression, IndexStr<'b>)> {
5803            match input.try_split_at(2) {
5804                None => Err(error::Error::UnexpectedEnd),
5805                Some((head, tail)) => match head.as_ref() {
5806                    b"nw" => {
5807                        let (exprs, tail) = zero_or_more::<Expression>(ctx, subs, tail)?;
5808                        let tail = consume(b"_", tail)?;
5809                        let (ty, tail) = TypeHandle::parse(ctx, subs, tail)?;
5810                        if let Ok(tail) = consume(b"E", tail) {
5811                            let expr = if is_global {
5812                                Expression::GlobalNew(exprs, ty, None)
5813                            } else {
5814                                Expression::New(exprs, ty, None)
5815                            };
5816                            Ok((expr, tail))
5817                        } else {
5818                            let (init, tail) = Initializer::parse(ctx, subs, tail)?;
5819                            let expr = if is_global {
5820                                Expression::GlobalNew(exprs, ty, Some(init))
5821                            } else {
5822                                Expression::New(exprs, ty, Some(init))
5823                            };
5824                            Ok((expr, tail))
5825                        }
5826                    }
5827                    b"na" => {
5828                        let (exprs, tail) = zero_or_more::<Expression>(ctx, subs, tail)?;
5829                        let tail = consume(b"_", tail)?;
5830                        let (ty, tail) = TypeHandle::parse(ctx, subs, tail)?;
5831                        if let Ok(tail) = consume(b"E", tail) {
5832                            let expr = if is_global {
5833                                Expression::GlobalNewArray(exprs, ty, None)
5834                            } else {
5835                                Expression::NewArray(exprs, ty, None)
5836                            };
5837                            Ok((expr, tail))
5838                        } else {
5839                            let (init, tail) = Initializer::parse(ctx, subs, tail)?;
5840                            let expr = if is_global {
5841                                Expression::GlobalNewArray(exprs, ty, Some(init))
5842                            } else {
5843                                Expression::NewArray(exprs, ty, Some(init))
5844                            };
5845                            Ok((expr, tail))
5846                        }
5847                    }
5848                    b"dl" => {
5849                        let (expr, tail) = Expression::parse(ctx, subs, tail)?;
5850                        let expr = if is_global {
5851                            Expression::GlobalDelete(Box::new(expr))
5852                        } else {
5853                            Expression::Delete(Box::new(expr))
5854                        };
5855                        Ok((expr, tail))
5856                    }
5857                    b"da" => {
5858                        let (expr, tail) = Expression::parse(ctx, subs, tail)?;
5859                        let expr = if is_global {
5860                            Expression::GlobalDeleteArray(Box::new(expr))
5861                        } else {
5862                            Expression::DeleteArray(Box::new(expr))
5863                        };
5864                        Ok((expr, tail))
5865                    }
5866                    _ => Err(error::Error::UnexpectedText),
5867                },
5868            }
5869        }
5870    }
5871}
5872
5873impl<'subs, W> Demangle<'subs, W> for Expression
5874where
5875    W: 'subs + DemangleWrite,
5876{
5877    fn demangle<'prev, 'ctx>(
5878        &'subs self,
5879        ctx: &'ctx mut DemangleContext<'subs, W>,
5880        scope: Option<ArgScopeStack<'prev, 'subs>>,
5881    ) -> fmt::Result {
5882        let ctx = try_begin_demangle!(self, ctx, scope);
5883
5884        match *self {
5885            Expression::Unary(OperatorName::Simple(ref op), ref expr)
5886                if *op == SimpleOperatorName::PostInc || *op == SimpleOperatorName::PostDec =>
5887            {
5888                expr.demangle_as_subexpr(ctx, scope)?;
5889                op.demangle(ctx, scope)
5890            }
5891            Expression::Unary(ref op, ref expr) => {
5892                op.demangle(ctx, scope)?;
5893                expr.demangle_as_subexpr(ctx, scope)
5894            }
5895            // These need an extra set of parens so that it doesn't close any
5896            // template argument accidentally.
5897            Expression::Binary(
5898                OperatorName::Simple(SimpleOperatorName::Greater),
5899                ref lhs,
5900                ref rhs,
5901            ) => {
5902                write!(ctx, "((")?;
5903                lhs.demangle(ctx, scope)?;
5904                write!(ctx, ")>(")?;
5905                rhs.demangle(ctx, scope)?;
5906                write!(ctx, "))")
5907            }
5908            Expression::Binary(ref op, ref lhs, ref rhs) => {
5909                lhs.demangle_as_subexpr(ctx, scope)?;
5910                op.demangle(ctx, scope)?;
5911                rhs.demangle_as_subexpr(ctx, scope)
5912            }
5913            Expression::Ternary(
5914                OperatorName::Simple(SimpleOperatorName::Question),
5915                ref condition,
5916                ref consequent,
5917                ref alternative,
5918            ) => {
5919                condition.demangle_as_subexpr(ctx, scope)?;
5920                write!(ctx, "?")?;
5921                consequent.demangle_as_subexpr(ctx, scope)?;
5922                write!(ctx, " : ")?;
5923                alternative.demangle_as_subexpr(ctx, scope)
5924            }
5925            Expression::Ternary(ref op, ref e1, ref e2, ref e3) => {
5926                // Nonsensical ternary operator? Just print it like a function call,
5927                // I suppose...
5928                //
5929                // TODO: should we detect and reject this during parsing?
5930                op.demangle(ctx, scope)?;
5931                write!(ctx, "(")?;
5932                e1.demangle(ctx, scope)?;
5933                write!(ctx, ", ")?;
5934                e2.demangle(ctx, scope)?;
5935                write!(ctx, ", ")?;
5936                e3.demangle(ctx, scope)?;
5937                write!(ctx, ")")?;
5938                Ok(())
5939            }
5940            Expression::PrefixInc(ref expr) => {
5941                write!(ctx, "++")?;
5942                expr.demangle(ctx, scope)
5943            }
5944            Expression::PrefixDec(ref expr) => {
5945                write!(ctx, "--")?;
5946                expr.demangle(ctx, scope)
5947            }
5948            Expression::Call(ref functor_expr, ref args) => {
5949                functor_expr.demangle_as_subexpr(ctx, scope)?;
5950                write!(ctx, "(")?;
5951                let mut need_comma = false;
5952                for arg in args {
5953                    if need_comma {
5954                        write!(ctx, ", ")?;
5955                    }
5956                    arg.demangle(ctx, scope)?;
5957                    need_comma = true;
5958                }
5959                write!(ctx, ")")?;
5960                Ok(())
5961            }
5962            Expression::ConversionOne(ref ty, ref expr) => {
5963                write!(ctx, "(")?;
5964                ty.demangle(ctx, scope)?;
5965                write!(ctx, ")(")?;
5966                expr.demangle(ctx, scope)?;
5967                write!(ctx, ")")?;
5968                Ok(())
5969            }
5970            Expression::ConversionMany(ref ty, ref exprs) => {
5971                ty.demangle(ctx, scope)?;
5972                write!(ctx, "(")?;
5973                let mut need_comma = false;
5974                for expr in exprs {
5975                    if need_comma {
5976                        write!(ctx, ", ")?;
5977                    }
5978                    expr.demangle(ctx, scope)?;
5979                    need_comma = true;
5980                }
5981                write!(ctx, ")")?;
5982                Ok(())
5983            }
5984            Expression::ConversionBraced(ref ty, ref exprs) => {
5985                ty.demangle(ctx, scope)?;
5986                write!(ctx, "{{")?;
5987                let mut need_comma = false;
5988                for expr in exprs {
5989                    if need_comma {
5990                        write!(ctx, ", ")?;
5991                    }
5992                    expr.demangle(ctx, scope)?;
5993                    need_comma = true;
5994                }
5995                write!(ctx, "}}")?;
5996                Ok(())
5997            }
5998            Expression::BracedInitList(ref expr) => {
5999                write!(ctx, "{{")?;
6000                expr.demangle(ctx, scope)?;
6001                write!(ctx, "}}")?;
6002                Ok(())
6003            }
6004            // TODO: factor out all this duplication in the `new` variants.
6005            Expression::New(ref exprs, ref ty, ref init) => {
6006                write!(ctx, "new (")?;
6007                let mut need_comma = false;
6008                for expr in exprs {
6009                    if need_comma {
6010                        write!(ctx, ", ")?;
6011                    }
6012                    expr.demangle(ctx, scope)?;
6013                    need_comma = true;
6014                }
6015                write!(ctx, ") ")?;
6016                ty.demangle(ctx, scope)?;
6017                if let Some(ref init) = *init {
6018                    init.demangle(ctx, scope)?;
6019                }
6020                Ok(())
6021            }
6022            Expression::GlobalNew(ref exprs, ref ty, ref init) => {
6023                write!(ctx, "::new (")?;
6024                let mut need_comma = false;
6025                for expr in exprs {
6026                    if need_comma {
6027                        write!(ctx, ", ")?;
6028                    }
6029                    expr.demangle(ctx, scope)?;
6030                    need_comma = true;
6031                }
6032                write!(ctx, ") ")?;
6033                ty.demangle(ctx, scope)?;
6034                if let Some(ref init) = *init {
6035                    init.demangle(ctx, scope)?;
6036                }
6037                Ok(())
6038            }
6039            Expression::NewArray(ref exprs, ref ty, ref init) => {
6040                write!(ctx, "new[] (")?;
6041                let mut need_comma = false;
6042                for expr in exprs {
6043                    if need_comma {
6044                        write!(ctx, ", ")?;
6045                    }
6046                    expr.demangle(ctx, scope)?;
6047                    need_comma = true;
6048                }
6049                write!(ctx, ") ")?;
6050                ty.demangle(ctx, scope)?;
6051                if let Some(ref init) = *init {
6052                    init.demangle(ctx, scope)?;
6053                }
6054                Ok(())
6055            }
6056            Expression::GlobalNewArray(ref exprs, ref ty, ref init) => {
6057                write!(ctx, "::new[] (")?;
6058                let mut need_comma = false;
6059                for expr in exprs {
6060                    if need_comma {
6061                        write!(ctx, ", ")?;
6062                    }
6063                    expr.demangle(ctx, scope)?;
6064                    need_comma = true;
6065                }
6066                write!(ctx, ") ")?;
6067                ty.demangle(ctx, scope)?;
6068                if let Some(ref init) = *init {
6069                    init.demangle(ctx, scope)?;
6070                }
6071                Ok(())
6072            }
6073            Expression::Delete(ref expr) => {
6074                write!(ctx, "delete ")?;
6075                expr.demangle(ctx, scope)
6076            }
6077            Expression::GlobalDelete(ref expr) => {
6078                write!(ctx, "::delete ")?;
6079                expr.demangle(ctx, scope)
6080            }
6081            Expression::DeleteArray(ref expr) => {
6082                write!(ctx, "delete[] ")?;
6083                expr.demangle(ctx, scope)
6084            }
6085            Expression::GlobalDeleteArray(ref expr) => {
6086                write!(ctx, "::delete[] ")?;
6087                expr.demangle(ctx, scope)
6088            }
6089            // TODO: factor out duplicated code from cast variants.
6090            Expression::DynamicCast(ref ty, ref expr) => {
6091                write!(ctx, "dynamic_cast<")?;
6092                ty.demangle(ctx, scope)?;
6093                write!(ctx, ">(")?;
6094                expr.demangle(ctx, scope)?;
6095                write!(ctx, ")")?;
6096                Ok(())
6097            }
6098            Expression::StaticCast(ref ty, ref expr) => {
6099                write!(ctx, "static_cast<")?;
6100                ty.demangle(ctx, scope)?;
6101                write!(ctx, ">(")?;
6102                expr.demangle(ctx, scope)?;
6103                write!(ctx, ")")?;
6104                Ok(())
6105            }
6106            Expression::ConstCast(ref ty, ref expr) => {
6107                write!(ctx, "const_cast<")?;
6108                ty.demangle(ctx, scope)?;
6109                write!(ctx, ">(")?;
6110                expr.demangle(ctx, scope)?;
6111                write!(ctx, ")")?;
6112                Ok(())
6113            }
6114            Expression::ReinterpretCast(ref ty, ref expr) => {
6115                write!(ctx, "reinterpret_cast<")?;
6116                ty.demangle(ctx, scope)?;
6117                write!(ctx, ">(")?;
6118                expr.demangle(ctx, scope)?;
6119                write!(ctx, ")")?;
6120                Ok(())
6121            }
6122            Expression::TypeidType(ref ty) => {
6123                write!(ctx, "typeid (")?;
6124                ty.demangle(ctx, scope)?;
6125                write!(ctx, ")")?;
6126                Ok(())
6127            }
6128            Expression::TypeidExpr(ref expr) => {
6129                write!(ctx, "typeid (")?;
6130                expr.demangle(ctx, scope)?;
6131                write!(ctx, ")")?;
6132                Ok(())
6133            }
6134            Expression::SizeofType(ref ty) => {
6135                write!(ctx, "sizeof (")?;
6136                ty.demangle(ctx, scope)?;
6137                write!(ctx, ")")?;
6138                Ok(())
6139            }
6140            Expression::SizeofExpr(ref expr) => {
6141                write!(ctx, "sizeof (")?;
6142                expr.demangle(ctx, scope)?;
6143                write!(ctx, ")")?;
6144                Ok(())
6145            }
6146            Expression::AlignofType(ref ty) => {
6147                write!(ctx, "alignof (")?;
6148                ty.demangle(ctx, scope)?;
6149                write!(ctx, ")")?;
6150                Ok(())
6151            }
6152            Expression::AlignofExpr(ref expr) => {
6153                write!(ctx, "alignof (")?;
6154                expr.demangle(ctx, scope)?;
6155                write!(ctx, ")")?;
6156                Ok(())
6157            }
6158            Expression::Noexcept(ref expr) => {
6159                write!(ctx, "noexcept (")?;
6160                expr.demangle(ctx, scope)?;
6161                write!(ctx, ")")?;
6162                Ok(())
6163            }
6164            Expression::Subobject(ref expr) => expr.demangle(ctx, scope),
6165            Expression::TemplateParam(ref param) => param.demangle(ctx, scope),
6166            Expression::FunctionParam(ref param) => param.demangle(ctx, scope),
6167            Expression::Member(ref expr, ref name) => {
6168                expr.demangle_as_subexpr(ctx, scope)?;
6169                write!(ctx, ".")?;
6170                name.demangle(ctx, scope)
6171            }
6172            Expression::DerefMember(ref expr, ref name) => {
6173                expr.demangle(ctx, scope)?;
6174                write!(ctx, "->")?;
6175                name.demangle(ctx, scope)
6176            }
6177            Expression::PointerToMember(ref e1, ref e2) => {
6178                e1.demangle(ctx, scope)?;
6179                write!(ctx, ".*")?;
6180                e2.demangle(ctx, scope)
6181            }
6182            Expression::SizeofTemplatePack(ref param) => {
6183                write!(ctx, "sizeof...(")?;
6184                param.demangle(ctx, scope)?;
6185                write!(ctx, ")")?;
6186                Ok(())
6187            }
6188            Expression::SizeofFunctionPack(ref param) => {
6189                write!(ctx, "sizeof...(")?;
6190                param.demangle(ctx, scope)?;
6191                write!(ctx, ")")?;
6192                Ok(())
6193            }
6194            Expression::SizeofCapturedTemplatePack(ref args) => {
6195                write!(ctx, "sizeof...(")?;
6196                let mut need_comma = false;
6197                for arg in args {
6198                    if need_comma {
6199                        write!(ctx, ", ")?;
6200                    }
6201                    arg.demangle(ctx, scope)?;
6202                    need_comma = true;
6203                }
6204                write!(ctx, ")")?;
6205                Ok(())
6206            }
6207            Expression::PackExpansion(ref pack) => {
6208                pack.demangle_as_subexpr(ctx, scope)?;
6209                write!(ctx, "...")?;
6210                Ok(())
6211            }
6212            Expression::Throw(ref expr) => {
6213                write!(ctx, "throw ")?;
6214                expr.demangle(ctx, scope)
6215            }
6216            Expression::Rethrow => {
6217                write!(ctx, "throw")?;
6218                Ok(())
6219            }
6220            Expression::UnresolvedName(ref name) => name.demangle(ctx, scope),
6221            Expression::Primary(ref expr) => expr.demangle(ctx, scope),
6222        }
6223    }
6224}
6225
6226impl Expression {
6227    fn demangle_as_subexpr<'subs, 'prev, 'ctx, W>(
6228        &'subs self,
6229        ctx: &'ctx mut DemangleContext<'subs, W>,
6230        scope: Option<ArgScopeStack<'prev, 'subs>>,
6231    ) -> fmt::Result
6232    where
6233        W: 'subs + DemangleWrite,
6234    {
6235        let needs_parens = match *self {
6236            Expression::FunctionParam(_) | Expression::Primary(ExprPrimary::External(_)) => false,
6237            _ => true,
6238        };
6239
6240        if needs_parens {
6241            write!(ctx, "(")?;
6242        }
6243
6244        self.demangle(ctx, scope)?;
6245
6246        if needs_parens {
6247            write!(ctx, ")")?;
6248        }
6249
6250        Ok(())
6251    }
6252}
6253
6254/// The `<unresolved-name>` production.
6255///
6256/// ```text
6257/// <unresolved-name> ::= [gs] <base-unresolved-name>
6258///                          #
6259///                   ::= sr <unresolved-type> <base-unresolved-name>
6260///                          #
6261///                   ::= srN <unresolved-type> <unresolved-qualifier-level>+ E <base-unresolved-name>
6262///                          #
6263///                   ::= [gs] sr <unresolved-qualifier-level>+ E <base-unresolved-name>
6264///                          # A::x, N::y, A<T>::z; "gs" means leading "::"
6265/// ```
6266#[derive(Clone, Debug, PartialEq, Eq)]
6267pub enum UnresolvedName {
6268    /// `x`
6269    Name(BaseUnresolvedName),
6270
6271    /// `::x`
6272    Global(BaseUnresolvedName),
6273
6274    /// `T::x`  or `decltype(p)::x` or `T::N::x` or `decltype(p)::N::x`
6275    Nested1(
6276        UnresolvedTypeHandle,
6277        Vec<UnresolvedQualifierLevel>,
6278        BaseUnresolvedName,
6279    ),
6280
6281    /// `A::x` or `N::y` or `A<T>::z`
6282    Nested2(Vec<UnresolvedQualifierLevel>, BaseUnresolvedName),
6283
6284    /// `::A::x` or `::N::y` or `::A<T>::z`
6285    GlobalNested2(Vec<UnresolvedQualifierLevel>, BaseUnresolvedName),
6286}
6287
6288impl Parse for UnresolvedName {
6289    fn parse<'a, 'b>(
6290        ctx: &'a ParseContext,
6291        subs: &'a mut SubstitutionTable,
6292        input: IndexStr<'b>,
6293    ) -> Result<(UnresolvedName, IndexStr<'b>)> {
6294        try_begin_parse!("UnresolvedName", ctx, input);
6295
6296        if let Ok(tail) = consume(b"gs", input) {
6297            if let Ok((name, tail)) = BaseUnresolvedName::parse(ctx, subs, tail) {
6298                return Ok((UnresolvedName::Global(name), tail));
6299            }
6300
6301            let tail = consume(b"sr", tail)?;
6302            let (levels, tail) = one_or_more::<UnresolvedQualifierLevel>(ctx, subs, tail)?;
6303            let tail = consume(b"E", tail)?;
6304            let (name, tail) = BaseUnresolvedName::parse(ctx, subs, tail)?;
6305            return Ok((UnresolvedName::GlobalNested2(levels, name), tail));
6306        }
6307
6308        if let Ok((name, tail)) = BaseUnresolvedName::parse(ctx, subs, input) {
6309            return Ok((UnresolvedName::Name(name), tail));
6310        }
6311
6312        let tail = consume(b"sr", input)?;
6313
6314        if tail.peek() == Some(b'N') {
6315            let tail = consume(b"N", tail).unwrap();
6316            let (ty, tail) = UnresolvedTypeHandle::parse(ctx, subs, tail)?;
6317            let (levels, tail) = one_or_more::<UnresolvedQualifierLevel>(ctx, subs, tail)?;
6318            let tail = consume(b"E", tail)?;
6319            let (name, tail) = BaseUnresolvedName::parse(ctx, subs, tail)?;
6320            return Ok((UnresolvedName::Nested1(ty, levels, name), tail));
6321        }
6322
6323        if let Ok((ty, tail)) = UnresolvedTypeHandle::parse(ctx, subs, tail) {
6324            let (name, tail) = BaseUnresolvedName::parse(ctx, subs, tail)?;
6325            return Ok((UnresolvedName::Nested1(ty, vec![], name), tail));
6326        }
6327
6328        let (levels, tail) = one_or_more::<UnresolvedQualifierLevel>(ctx, subs, tail)?;
6329        let tail = consume(b"E", tail)?;
6330        let (name, tail) = BaseUnresolvedName::parse(ctx, subs, tail)?;
6331        Ok((UnresolvedName::Nested2(levels, name), tail))
6332    }
6333}
6334
6335impl<'subs, W> Demangle<'subs, W> for UnresolvedName
6336where
6337    W: 'subs + DemangleWrite,
6338{
6339    fn demangle<'prev, 'ctx>(
6340        &'subs self,
6341        ctx: &'ctx mut DemangleContext<'subs, W>,
6342        scope: Option<ArgScopeStack<'prev, 'subs>>,
6343    ) -> fmt::Result {
6344        let ctx = try_begin_demangle!(self, ctx, scope);
6345
6346        match *self {
6347            UnresolvedName::Name(ref name) => name.demangle(ctx, scope),
6348            UnresolvedName::Global(ref name) => {
6349                write!(ctx, "::")?;
6350                name.demangle(ctx, scope)
6351            }
6352            UnresolvedName::Nested1(ref ty, ref levels, ref name) => {
6353                ty.demangle(ctx, scope)?;
6354                write!(ctx, "::")?;
6355                for lvl in &levels[..] {
6356                    lvl.demangle(ctx, scope)?;
6357                    write!(ctx, "::")?;
6358                }
6359                name.demangle(ctx, scope)
6360            }
6361            UnresolvedName::Nested2(ref levels, ref name) => {
6362                for lvl in &levels[..] {
6363                    lvl.demangle(ctx, scope)?;
6364                    write!(ctx, "::")?;
6365                }
6366                name.demangle(ctx, scope)
6367            }
6368            // `::A::x` or `::N::y` or `::A<T>::z`
6369            UnresolvedName::GlobalNested2(ref levels, ref name) => {
6370                write!(ctx, "::")?;
6371                for lvl in &levels[..] {
6372                    lvl.demangle(ctx, scope)?;
6373                    write!(ctx, "::")?;
6374                }
6375                name.demangle(ctx, scope)
6376            }
6377        }
6378    }
6379}
6380
6381/// The `<unresolved-type>` production.
6382///
6383/// ```text
6384/// <unresolved-type> ::= <template-param> [ <template-args> ]  # T:: or T<X,Y>::
6385///                   ::= <decltype>                            # decltype(p)::
6386///                   ::= <substitution>
6387/// ```
6388#[derive(Clone, Debug, PartialEq, Eq)]
6389pub enum UnresolvedType {
6390    /// An unresolved template type.
6391    Template(TemplateParam, Option<TemplateArgs>),
6392
6393    /// An unresolved `decltype`.
6394    Decltype(Decltype),
6395}
6396
6397define_handle! {
6398    /// A reference to a parsed `<unresolved-type>` production.
6399    pub enum UnresolvedTypeHandle
6400}
6401
6402impl Parse for UnresolvedTypeHandle {
6403    fn parse<'a, 'b>(
6404        ctx: &'a ParseContext,
6405        subs: &'a mut SubstitutionTable,
6406        input: IndexStr<'b>,
6407    ) -> Result<(UnresolvedTypeHandle, IndexStr<'b>)> {
6408        try_begin_parse!("UnresolvedTypeHandle", ctx, input);
6409
6410        if let Ok((param, tail)) = TemplateParam::parse(ctx, subs, input) {
6411            let (args, tail) = if let Ok((args, tail)) = TemplateArgs::parse(ctx, subs, tail) {
6412                (Some(args), tail)
6413            } else {
6414                (None, tail)
6415            };
6416            let ty = UnresolvedType::Template(param, args);
6417            let ty = Substitutable::UnresolvedType(ty);
6418            let idx = subs.insert(ty);
6419            let handle = UnresolvedTypeHandle::BackReference(idx);
6420            return Ok((handle, tail));
6421        }
6422
6423        if let Ok((decltype, tail)) = Decltype::parse(ctx, subs, input) {
6424            let ty = UnresolvedType::Decltype(decltype);
6425            let ty = Substitutable::UnresolvedType(ty);
6426            let idx = subs.insert(ty);
6427            let handle = UnresolvedTypeHandle::BackReference(idx);
6428            return Ok((handle, tail));
6429        }
6430
6431        let (sub, tail) = Substitution::parse(ctx, subs, input)?;
6432        match sub {
6433            Substitution::WellKnown(component) => {
6434                Ok((UnresolvedTypeHandle::WellKnown(component), tail))
6435            }
6436            Substitution::BackReference(idx) => {
6437                // TODO: should this check that the back reference actually
6438                // points to an `<unresolved-type>`?
6439                Ok((UnresolvedTypeHandle::BackReference(idx), tail))
6440            }
6441        }
6442    }
6443}
6444
6445impl<'subs, W> Demangle<'subs, W> for UnresolvedType
6446where
6447    W: 'subs + DemangleWrite,
6448{
6449    fn demangle<'prev, 'ctx>(
6450        &'subs self,
6451        ctx: &'ctx mut DemangleContext<'subs, W>,
6452        scope: Option<ArgScopeStack<'prev, 'subs>>,
6453    ) -> fmt::Result {
6454        let ctx = try_begin_demangle!(self, ctx, scope);
6455
6456        match *self {
6457            UnresolvedType::Decltype(ref dt) => dt.demangle(ctx, scope),
6458            UnresolvedType::Template(ref param, ref args) => {
6459                if let Some(ref args) = *args {
6460                    let scope = scope.push(args);
6461                    param.demangle(ctx, scope)?;
6462                    args.demangle(ctx, scope)?;
6463                } else {
6464                    param.demangle(ctx, scope)?;
6465                }
6466                Ok(())
6467            }
6468        }
6469    }
6470}
6471
6472/// The `<unresolved-qualifier-level>` production.
6473///
6474/// ```text
6475/// <unresolved-qualifier-level> ::= <simple-id>
6476/// ```
6477#[derive(Clone, Debug, PartialEq, Eq)]
6478pub struct UnresolvedQualifierLevel(SimpleId);
6479
6480impl Parse for UnresolvedQualifierLevel {
6481    fn parse<'a, 'b>(
6482        ctx: &'a ParseContext,
6483        subs: &'a mut SubstitutionTable,
6484        input: IndexStr<'b>,
6485    ) -> Result<(UnresolvedQualifierLevel, IndexStr<'b>)> {
6486        try_begin_parse!("UnresolvedQualifierLevel", ctx, input);
6487
6488        let (id, tail) = SimpleId::parse(ctx, subs, input)?;
6489        Ok((UnresolvedQualifierLevel(id), tail))
6490    }
6491}
6492
6493impl<'subs, W> Demangle<'subs, W> for UnresolvedQualifierLevel
6494where
6495    W: 'subs + DemangleWrite,
6496{
6497    #[inline]
6498    fn demangle<'prev, 'ctx>(
6499        &'subs self,
6500        ctx: &'ctx mut DemangleContext<'subs, W>,
6501        scope: Option<ArgScopeStack<'prev, 'subs>>,
6502    ) -> fmt::Result {
6503        let ctx = try_begin_demangle!(self, ctx, scope);
6504
6505        self.0.demangle(ctx, scope)
6506    }
6507}
6508
6509/// The `<simple-id>` production.
6510///
6511/// ```text
6512/// <simple-id> ::= <source-name> [ <template-args> ]
6513/// ```
6514#[derive(Clone, Debug, PartialEq, Eq)]
6515pub struct SimpleId(SourceName, Option<TemplateArgs>);
6516
6517impl Parse for SimpleId {
6518    fn parse<'a, 'b>(
6519        ctx: &'a ParseContext,
6520        subs: &'a mut SubstitutionTable,
6521        input: IndexStr<'b>,
6522    ) -> Result<(SimpleId, IndexStr<'b>)> {
6523        try_begin_parse!("SimpleId", ctx, input);
6524
6525        let (name, tail) = SourceName::parse(ctx, subs, input)?;
6526        let (args, tail) = if let Ok((args, tail)) = TemplateArgs::parse(ctx, subs, tail) {
6527            (Some(args), tail)
6528        } else {
6529            (None, tail)
6530        };
6531        Ok((SimpleId(name, args), tail))
6532    }
6533}
6534
6535impl<'subs, W> Demangle<'subs, W> for SimpleId
6536where
6537    W: 'subs + DemangleWrite,
6538{
6539    fn demangle<'prev, 'ctx>(
6540        &'subs self,
6541        ctx: &'ctx mut DemangleContext<'subs, W>,
6542        scope: Option<ArgScopeStack<'prev, 'subs>>,
6543    ) -> fmt::Result {
6544        let ctx = try_begin_demangle!(self, ctx, scope);
6545
6546        self.0.demangle(ctx, scope)?;
6547        if let Some(ref args) = self.1 {
6548            args.demangle(ctx, scope)?;
6549        }
6550        Ok(())
6551    }
6552}
6553
6554/// The `<base-unresolved-name>` production.
6555///
6556/// ```text
6557/// <base-unresolved-name> ::= <simple-id>                        # unresolved name
6558///                        ::= on <operator-name>                 # unresolved operator-function-id
6559///                        ::= on <operator-name> <template-args> # unresolved operator template-id
6560///                        ::= dn <destructor-name>               # destructor or pseudo-destructor;
6561///                                                               # e.g. ~X or ~X<N-1>
6562/// ```
6563#[derive(Clone, Debug, PartialEq, Eq)]
6564pub enum BaseUnresolvedName {
6565    /// An unresolved name.
6566    Name(SimpleId),
6567
6568    /// An unresolved function or template function name.
6569    Operator(OperatorName, Option<TemplateArgs>),
6570
6571    /// An unresolved destructor name.
6572    Destructor(DestructorName),
6573}
6574
6575impl Parse for BaseUnresolvedName {
6576    fn parse<'a, 'b>(
6577        ctx: &'a ParseContext,
6578        subs: &'a mut SubstitutionTable,
6579        input: IndexStr<'b>,
6580    ) -> Result<(BaseUnresolvedName, IndexStr<'b>)> {
6581        try_begin_parse!("BaseUnresolvedName", ctx, input);
6582
6583        if let Ok((name, tail)) = SimpleId::parse(ctx, subs, input) {
6584            return Ok((BaseUnresolvedName::Name(name), tail));
6585        }
6586
6587        if let Ok(tail) = consume(b"on", input) {
6588            let (opname, tail) = OperatorName::parse(ctx, subs, tail)?;
6589            let (args, tail) = if let Ok((args, tail)) = TemplateArgs::parse(ctx, subs, tail) {
6590                (Some(args), tail)
6591            } else {
6592                (None, tail)
6593            };
6594            return Ok((BaseUnresolvedName::Operator(opname, args), tail));
6595        }
6596
6597        let tail = consume(b"dn", input)?;
6598        let (name, tail) = DestructorName::parse(ctx, subs, tail)?;
6599        Ok((BaseUnresolvedName::Destructor(name), tail))
6600    }
6601}
6602
6603impl<'subs, W> Demangle<'subs, W> for BaseUnresolvedName
6604where
6605    W: 'subs + DemangleWrite,
6606{
6607    fn demangle<'prev, 'ctx>(
6608        &'subs self,
6609        ctx: &'ctx mut DemangleContext<'subs, W>,
6610        scope: Option<ArgScopeStack<'prev, 'subs>>,
6611    ) -> fmt::Result {
6612        let ctx = try_begin_demangle!(self, ctx, scope);
6613
6614        match *self {
6615            BaseUnresolvedName::Name(ref name) => name.demangle(ctx, scope),
6616            BaseUnresolvedName::Destructor(ref dtor) => dtor.demangle(ctx, scope),
6617            BaseUnresolvedName::Operator(ref op, ref args) => {
6618                op.demangle(ctx, scope)?;
6619                if let Some(ref args) = *args {
6620                    args.demangle(ctx, scope)?;
6621                }
6622                Ok(())
6623            }
6624        }
6625    }
6626}
6627
6628/// The `<destructor-name>` production.
6629///
6630/// ```text
6631/// <destructor-name> ::= <unresolved-type> # e.g., ~T or ~decltype(f())
6632///                   ::= <simple-id>       # e.g., ~A<2*N>
6633/// ```
6634#[derive(Clone, Debug, PartialEq, Eq)]
6635pub enum DestructorName {
6636    /// A destructor for an unresolved type.
6637    Unresolved(UnresolvedTypeHandle),
6638
6639    /// A destructor for a resolved type name.
6640    Name(SimpleId),
6641}
6642
6643impl Parse for DestructorName {
6644    fn parse<'a, 'b>(
6645        ctx: &'a ParseContext,
6646        subs: &'a mut SubstitutionTable,
6647        input: IndexStr<'b>,
6648    ) -> Result<(DestructorName, IndexStr<'b>)> {
6649        try_begin_parse!("DestructorName", ctx, input);
6650
6651        if let Ok((ty, tail)) = UnresolvedTypeHandle::parse(ctx, subs, input) {
6652            return Ok((DestructorName::Unresolved(ty), tail));
6653        }
6654
6655        let (name, tail) = SimpleId::parse(ctx, subs, input)?;
6656        Ok((DestructorName::Name(name), tail))
6657    }
6658}
6659
6660impl<'subs, W> Demangle<'subs, W> for DestructorName
6661where
6662    W: 'subs + DemangleWrite,
6663{
6664    fn demangle<'prev, 'ctx>(
6665        &'subs self,
6666        ctx: &'ctx mut DemangleContext<'subs, W>,
6667        scope: Option<ArgScopeStack<'prev, 'subs>>,
6668    ) -> fmt::Result {
6669        let ctx = try_begin_demangle!(self, ctx, scope);
6670
6671        write!(ctx, "~")?;
6672        match *self {
6673            DestructorName::Unresolved(ref ty) => ty.demangle(ctx, scope),
6674            DestructorName::Name(ref name) => name.demangle(ctx, scope),
6675        }
6676    }
6677}
6678
6679/// The `<expr-primary>` production.
6680///
6681/// ```text
6682/// <expr-primary> ::= L <type> <value number> E                        # integer literal
6683///                ::= L <type> <value float> E                         # floating literal
6684///                ::= L <string type> E                                # string literal
6685///                ::= L <nullptr type> E                               # nullptr literal (i.e., "LDnE")
6686///                ::= L <pointer type> 0 E                             # null pointer template argument
6687///                ::= L <type> <real-part float> _ <imag-part float> E # complex floating point literal (C 2000)
6688///                ::= L <mangled-name> E                               # external name
6689/// ```
6690#[derive(Clone, Debug, PartialEq, Eq)]
6691pub enum ExprPrimary {
6692    /// A type literal.
6693    Literal(TypeHandle, usize, usize),
6694
6695    /// An external name.
6696    External(MangledName),
6697}
6698
6699impl Parse for ExprPrimary {
6700    fn parse<'a, 'b>(
6701        ctx: &'a ParseContext,
6702        subs: &'a mut SubstitutionTable,
6703        input: IndexStr<'b>,
6704    ) -> Result<(ExprPrimary, IndexStr<'b>)> {
6705        try_begin_parse!("ExprPrimary", ctx, input);
6706
6707        let tail = consume(b"L", input)?;
6708
6709        if let Ok((ty, tail)) = TypeHandle::parse(ctx, subs, tail) {
6710            let start = tail.index();
6711            let num_bytes_in_literal = tail.as_ref().iter().take_while(|&&c| c != b'E').count();
6712            let tail = tail.range_from(num_bytes_in_literal..);
6713            let end = tail.index();
6714            let tail = consume(b"E", tail)?;
6715            let expr = ExprPrimary::Literal(ty, start, end);
6716            return Ok((expr, tail));
6717        }
6718
6719        let (name, tail) = MangledName::parse(ctx, subs, tail)?;
6720        let tail = consume(b"E", tail)?;
6721        let expr = ExprPrimary::External(name);
6722        Ok((expr, tail))
6723    }
6724}
6725
6726impl<'subs, W> Demangle<'subs, W> for ExprPrimary
6727where
6728    W: 'subs + DemangleWrite,
6729{
6730    fn demangle<'prev, 'ctx>(
6731        &'subs self,
6732        ctx: &'ctx mut DemangleContext<'subs, W>,
6733        scope: Option<ArgScopeStack<'prev, 'subs>>,
6734    ) -> fmt::Result {
6735        let ctx = try_begin_demangle!(self, ctx, scope);
6736
6737        fn write_literal<W>(ctx: &mut DemangleContext<W>, start: usize, end: usize) -> fmt::Result
6738        where
6739            W: DemangleWrite,
6740        {
6741            debug_assert!(start <= end);
6742            let start = if start < end && ctx.input[start] == b'n' {
6743                write!(ctx, "-")?;
6744                start + 1
6745            } else {
6746                start
6747            };
6748            let s = str::from_utf8(&ctx.input[start..end]).map_err(|e| {
6749                log!("Error writing literal: {}", e);
6750                fmt::Error
6751            })?;
6752            ctx.write_str(s)
6753        }
6754
6755        match *self {
6756            ExprPrimary::External(ref name) => {
6757                let saved_show_params = ctx.show_params;
6758                ctx.show_params = true;
6759                let ret = name.demangle(ctx, scope);
6760                ctx.show_params = saved_show_params;
6761                ret
6762            }
6763            ExprPrimary::Literal(
6764                TypeHandle::Builtin(BuiltinType::Standard(StandardBuiltinType::Bool)),
6765                start,
6766                end,
6767            ) => match &ctx.input[start..end] {
6768                b"0" => write!(ctx, "false"),
6769                b"1" => write!(ctx, "true"),
6770                _ => {
6771                    write!(ctx, "(bool)")?;
6772                    write_literal(ctx, start, end)
6773                }
6774            },
6775            ExprPrimary::Literal(
6776                TypeHandle::Builtin(BuiltinType::Standard(StandardBuiltinType::Nullptr)),
6777                _,
6778                _,
6779            ) => write!(ctx, "nullptr"),
6780            ExprPrimary::Literal(
6781                ref ty @ TypeHandle::Builtin(BuiltinType::Standard(StandardBuiltinType::Double)),
6782                start,
6783                end,
6784            )
6785            | ExprPrimary::Literal(
6786                ref ty @ TypeHandle::Builtin(BuiltinType::Standard(StandardBuiltinType::Float)),
6787                start,
6788                end,
6789            ) => {
6790                if ctx.show_expression_literal_types {
6791                    write!(ctx, "(")?;
6792                    ty.demangle(ctx, scope)?;
6793                    write!(ctx, ")")?;
6794                }
6795                let start = if start < end && ctx.input[start] == b'n' {
6796                    write!(ctx, "-[")?;
6797                    start + 1
6798                } else {
6799                    write!(ctx, "[")?;
6800                    start
6801                };
6802                let s = str::from_utf8(&ctx.input[start..end]).map_err(|e| {
6803                    log!("Error writing literal: {}", e);
6804                    fmt::Error
6805                })?;
6806                ctx.write_str(s)?;
6807                write!(ctx, "]")
6808            }
6809            ExprPrimary::Literal(
6810                TypeHandle::Builtin(BuiltinType::Standard(StandardBuiltinType::Int)),
6811                start,
6812                end,
6813            ) => write_literal(ctx, start, end),
6814            ExprPrimary::Literal(ref ty, start, end) => {
6815                if ctx.show_expression_literal_types {
6816                    write!(ctx, "(")?;
6817                    ty.demangle(ctx, scope)?;
6818                    write!(ctx, ")")?;
6819                }
6820                write_literal(ctx, start, end)
6821            }
6822        }
6823    }
6824}
6825
6826/// The `<initializer>` production.
6827///
6828/// ```text
6829/// <initializer> ::= pi <expression>* E # parenthesized initialization
6830/// ```
6831#[derive(Clone, Debug, PartialEq, Eq)]
6832pub struct Initializer(Vec<Expression>);
6833
6834impl Parse for Initializer {
6835    fn parse<'a, 'b>(
6836        ctx: &'a ParseContext,
6837        subs: &'a mut SubstitutionTable,
6838        input: IndexStr<'b>,
6839    ) -> Result<(Initializer, IndexStr<'b>)> {
6840        try_begin_parse!("Initializer", ctx, input);
6841
6842        let tail = consume(b"pi", input)?;
6843        let (exprs, tail) = zero_or_more::<Expression>(ctx, subs, tail)?;
6844        let tail = consume(b"E", tail)?;
6845        Ok((Initializer(exprs), tail))
6846    }
6847}
6848
6849impl<'subs, W> Demangle<'subs, W> for Initializer
6850where
6851    W: 'subs + DemangleWrite,
6852{
6853    fn demangle<'prev, 'ctx>(
6854        &'subs self,
6855        ctx: &'ctx mut DemangleContext<'subs, W>,
6856        scope: Option<ArgScopeStack<'prev, 'subs>>,
6857    ) -> fmt::Result {
6858        let ctx = try_begin_demangle!(self, ctx, scope);
6859
6860        write!(ctx, "(")?;
6861        let mut need_comma = false;
6862        for expr in &self.0 {
6863            if need_comma {
6864                write!(ctx, ", ")?;
6865            }
6866            expr.demangle(ctx, scope)?;
6867            need_comma = true;
6868        }
6869        write!(ctx, ")")?;
6870        Ok(())
6871    }
6872}
6873
6874/// The `<local-name>` production.
6875///
6876/// ```text
6877/// <local-name> := Z <function encoding> E <entity name> [<discriminator>]
6878///              := Z <function encoding> E s [<discriminator>]
6879///              := Z <function encoding> Ed [ <parameter number> ] _ <entity name>
6880/// ```
6881#[derive(Clone, Debug, PartialEq, Eq)]
6882pub enum LocalName {
6883    /// The mangling of the enclosing function, the mangling of the entity
6884    /// relative to the function, and an optional discriminator.
6885    Relative(Box<Encoding>, Option<Box<Name>>, Option<Discriminator>),
6886
6887    /// A default argument in a class definition.
6888    Default(Box<Encoding>, Option<usize>, Box<Name>),
6889}
6890
6891impl Parse for LocalName {
6892    fn parse<'a, 'b>(
6893        ctx: &'a ParseContext,
6894        subs: &'a mut SubstitutionTable,
6895        input: IndexStr<'b>,
6896    ) -> Result<(LocalName, IndexStr<'b>)> {
6897        try_begin_parse!("LocalName", ctx, input);
6898
6899        let tail = consume(b"Z", input)?;
6900        let (encoding, tail) = Encoding::parse(ctx, subs, tail)?;
6901        let tail = consume(b"E", tail)?;
6902
6903        if let Ok(tail) = consume(b"s", tail) {
6904            let (disc, tail) = if let Ok((disc, tail)) = Discriminator::parse(ctx, subs, tail) {
6905                (Some(disc), tail)
6906            } else {
6907                (None, tail)
6908            };
6909            return Ok((LocalName::Relative(Box::new(encoding), None, disc), tail));
6910        }
6911
6912        if let Ok(tail) = consume(b"d", tail) {
6913            let (param, tail) = if let Ok((num, tail)) = Number::parse(ctx, subs, tail) {
6914                (Some(num as _), tail)
6915            } else {
6916                (None, tail)
6917            };
6918            let tail = consume(b"_", tail)?;
6919            let (name, tail) = Name::parse(ctx, subs, tail)?;
6920            return Ok((
6921                LocalName::Default(Box::new(encoding), param, Box::new(name)),
6922                tail,
6923            ));
6924        }
6925
6926        let (name, tail) = Name::parse(ctx, subs, tail)?;
6927        let (disc, tail) = if let Ok((disc, tail)) = Discriminator::parse(ctx, subs, tail) {
6928            (Some(disc), tail)
6929        } else {
6930            (None, tail)
6931        };
6932
6933        Ok((
6934            LocalName::Relative(Box::new(encoding), Some(Box::new(name)), disc),
6935            tail,
6936        ))
6937    }
6938}
6939
6940impl<'subs, W> Demangle<'subs, W> for LocalName
6941where
6942    W: 'subs + DemangleWrite,
6943{
6944    fn demangle<'prev, 'ctx>(
6945        &'subs self,
6946        ctx: &'ctx mut DemangleContext<'subs, W>,
6947        scope: Option<ArgScopeStack<'prev, 'subs>>,
6948    ) -> fmt::Result {
6949        let ctx = try_begin_demangle!(self, ctx, scope);
6950
6951        let saved_show_params = ctx.show_params;
6952        ctx.show_params = true;
6953        let ret = match *self {
6954            LocalName::Relative(ref encoding, Some(ref name), _) => {
6955                encoding.demangle(ctx, scope)?;
6956                write!(ctx, "::")?;
6957                name.demangle(ctx, scope)
6958            }
6959            LocalName::Relative(ref encoding, None, _) => {
6960                // No name means that this is the symbol for a string literal.
6961                encoding.demangle(ctx, scope)?;
6962                write!(ctx, "::string literal")?;
6963                Ok(())
6964            }
6965            LocalName::Default(ref encoding, _, _) => encoding.demangle(ctx, scope),
6966        };
6967        ctx.show_params = saved_show_params;
6968        ret
6969    }
6970}
6971
6972impl GetTemplateArgs for LocalName {
6973    fn get_template_args<'a>(&'a self, subs: &'a SubstitutionTable) -> Option<&'a TemplateArgs> {
6974        match *self {
6975            LocalName::Relative(_, None, _) => None,
6976            LocalName::Relative(_, Some(ref name), _) | LocalName::Default(_, _, ref name) => {
6977                name.get_template_args(subs)
6978            }
6979        }
6980    }
6981}
6982
6983impl<'a> GetLeafName<'a> for LocalName {
6984    fn get_leaf_name(&'a self, subs: &'a SubstitutionTable) -> Option<LeafName<'a>> {
6985        match *self {
6986            LocalName::Relative(_, None, _) => None,
6987            LocalName::Relative(_, Some(ref name), _) | LocalName::Default(_, _, ref name) => {
6988                name.get_leaf_name(subs)
6989            }
6990        }
6991    }
6992}
6993
6994/// The `<discriminator>` production.
6995///
6996/// ```text
6997/// <discriminator> := _ <non-negative number>      # when number < 10
6998///                 := __ <non-negative number> _   # when number >= 10
6999/// ```
7000#[derive(Clone, Debug, PartialEq, Eq)]
7001pub struct Discriminator(usize);
7002
7003impl Parse for Discriminator {
7004    fn parse<'a, 'b>(
7005        ctx: &'a ParseContext,
7006        _subs: &'a mut SubstitutionTable,
7007        input: IndexStr<'b>,
7008    ) -> Result<(Discriminator, IndexStr<'b>)> {
7009        try_begin_parse!("Discriminator", ctx, input);
7010
7011        let tail = consume(b"_", input)?;
7012
7013        if let Ok(tail) = consume(b"_", tail) {
7014            let (num, tail) = parse_number(10, false, tail)?;
7015            debug_assert!(num >= 0);
7016            if num < 10 {
7017                return Err(error::Error::UnexpectedText);
7018            }
7019            let tail = consume(b"_", tail)?;
7020            return Ok((Discriminator(num as _), tail));
7021        }
7022
7023        match tail.try_split_at(1) {
7024            None => Err(error::Error::UnexpectedEnd),
7025            Some((head, tail)) => match head.as_ref()[0] {
7026                b'0' => Ok((Discriminator(0), tail)),
7027                b'1' => Ok((Discriminator(1), tail)),
7028                b'2' => Ok((Discriminator(2), tail)),
7029                b'3' => Ok((Discriminator(3), tail)),
7030                b'4' => Ok((Discriminator(4), tail)),
7031                b'5' => Ok((Discriminator(5), tail)),
7032                b'6' => Ok((Discriminator(6), tail)),
7033                b'7' => Ok((Discriminator(7), tail)),
7034                b'8' => Ok((Discriminator(8), tail)),
7035                b'9' => Ok((Discriminator(9), tail)),
7036                _ => Err(error::Error::UnexpectedText),
7037            },
7038        }
7039    }
7040}
7041
7042/// The `<closure-type-name>` production.
7043///
7044/// ```text
7045/// <closure-type-name> ::= Ul <lambda-sig> E [ <nonnegative number> ] _
7046/// ```
7047#[derive(Clone, Debug, PartialEq, Eq)]
7048pub struct ClosureTypeName(LambdaSig, Option<usize>);
7049
7050impl Parse for ClosureTypeName {
7051    fn parse<'a, 'b>(
7052        ctx: &'a ParseContext,
7053        subs: &'a mut SubstitutionTable,
7054        input: IndexStr<'b>,
7055    ) -> Result<(ClosureTypeName, IndexStr<'b>)> {
7056        try_begin_parse!("ClosureTypeName", ctx, input);
7057
7058        let tail = consume(b"Ul", input)?;
7059        let (sig, tail) = LambdaSig::parse(ctx, subs, tail)?;
7060        let tail = consume(b"E", tail)?;
7061        let (num, tail) = if let Ok((num, tail)) = parse_number(10, false, tail) {
7062            (Some(num as _), tail)
7063        } else {
7064            (None, tail)
7065        };
7066        let tail = consume(b"_", tail)?;
7067        Ok((ClosureTypeName(sig, num), tail))
7068    }
7069}
7070
7071impl<'subs, W> Demangle<'subs, W> for ClosureTypeName
7072where
7073    W: 'subs + DemangleWrite,
7074{
7075    fn demangle<'prev, 'ctx>(
7076        &'subs self,
7077        ctx: &'ctx mut DemangleContext<'subs, W>,
7078        scope: Option<ArgScopeStack<'prev, 'subs>>,
7079    ) -> fmt::Result {
7080        let ctx = try_begin_demangle!(self, ctx, scope);
7081
7082        write!(ctx, "{{lambda(")?;
7083        self.0.demangle(ctx, scope)?;
7084        write!(ctx, ")#{}}}", self.1.map_or(1, |n| n + 2))?;
7085        Ok(())
7086    }
7087}
7088
7089impl<'subs> ArgScope<'subs, 'subs> for ClosureTypeName {
7090    fn leaf_name(&'subs self) -> Result<LeafName<'subs>> {
7091        Ok(LeafName::Closure(self))
7092    }
7093
7094    fn get_template_arg(
7095        &'subs self,
7096        _: usize,
7097    ) -> Result<(&'subs TemplateArg, &'subs TemplateArgs)> {
7098        Err(error::Error::BadTemplateArgReference)
7099    }
7100
7101    fn get_function_arg(&'subs self, _: usize) -> Result<&'subs Type> {
7102        Err(error::Error::BadFunctionArgReference)
7103    }
7104}
7105
7106impl<'a> GetLeafName<'a> for ClosureTypeName {
7107    #[inline]
7108    fn get_leaf_name(&'a self, _: &'a SubstitutionTable) -> Option<LeafName<'a>> {
7109        Some(LeafName::Closure(self))
7110    }
7111}
7112
7113impl ClosureTypeName {
7114    #[inline]
7115    fn starts_with(byte: u8, input: &IndexStr) -> bool {
7116        byte == b'U' && input.peek_second().map(|b| b == b'l').unwrap_or(false)
7117    }
7118}
7119
7120/// The `<lambda-sig>` production.
7121///
7122/// ```text
7123/// <lambda-sig> ::= <parameter type>+  # Parameter types or "v" if the lambda has no parameters
7124/// ```
7125#[derive(Clone, Debug, PartialEq, Eq)]
7126pub struct LambdaSig(Vec<TypeHandle>);
7127
7128impl LambdaSig {
7129    fn demangle_args<'subs, 'prev, 'ctx, W>(
7130        &'subs self,
7131        ctx: &'ctx mut DemangleContext<'subs, W>,
7132        scope: Option<ArgScopeStack<'prev, 'subs>>,
7133    ) -> fmt::Result
7134    where
7135        W: 'subs + DemangleWrite,
7136    {
7137        let mut need_comma = false;
7138        for ty in &self.0 {
7139            if need_comma {
7140                write!(ctx, ", ")?;
7141            }
7142            ty.demangle(ctx, scope)?;
7143            need_comma = true;
7144        }
7145        Ok(())
7146    }
7147}
7148
7149impl Parse for LambdaSig {
7150    fn parse<'a, 'b>(
7151        ctx: &'a ParseContext,
7152        subs: &'a mut SubstitutionTable,
7153        input: IndexStr<'b>,
7154    ) -> Result<(LambdaSig, IndexStr<'b>)> {
7155        try_begin_parse!("LambdaSig", ctx, input);
7156
7157        let (types, tail) = if let Ok(tail) = consume(b"v", input) {
7158            (vec![], tail)
7159        } else {
7160            one_or_more::<TypeHandle>(ctx, subs, input)?
7161        };
7162        Ok((LambdaSig(types), tail))
7163    }
7164}
7165
7166impl<'subs, W> Demangle<'subs, W> for LambdaSig
7167where
7168    W: 'subs + DemangleWrite,
7169{
7170    fn demangle<'prev, 'ctx>(
7171        &'subs self,
7172        ctx: &'ctx mut DemangleContext<'subs, W>,
7173        scope: Option<ArgScopeStack<'prev, 'subs>>,
7174    ) -> fmt::Result {
7175        let ctx = try_begin_demangle!(self, ctx, scope);
7176
7177        ctx.is_lambda_arg = true;
7178        let r = self.demangle_args(ctx, scope);
7179        ctx.is_lambda_arg = false;
7180        r
7181    }
7182}
7183
7184/// The `<data-member-prefix>` production.
7185///
7186/// ```text
7187/// <data-member-prefix> := <member source-name> M
7188/// ```
7189#[derive(Clone, Debug, PartialEq, Eq)]
7190pub struct DataMemberPrefix(SourceName);
7191
7192impl Parse for DataMemberPrefix {
7193    fn parse<'a, 'b>(
7194        ctx: &'a ParseContext,
7195        subs: &'a mut SubstitutionTable,
7196        input: IndexStr<'b>,
7197    ) -> Result<(DataMemberPrefix, IndexStr<'b>)> {
7198        try_begin_parse!("DataMemberPrefix", ctx, input);
7199
7200        let (name, tail) = SourceName::parse(ctx, subs, input)?;
7201        let tail = consume(b"M", tail)?;
7202        Ok((DataMemberPrefix(name), tail))
7203    }
7204}
7205
7206impl<'a> GetLeafName<'a> for DataMemberPrefix {
7207    #[inline]
7208    fn get_leaf_name(&'a self, _: &'a SubstitutionTable) -> Option<LeafName<'a>> {
7209        Some(LeafName::SourceName(&self.0))
7210    }
7211}
7212
7213impl DataMemberPrefix {
7214    fn starts_with(byte: u8) -> bool {
7215        SourceName::starts_with(byte)
7216    }
7217}
7218
7219impl<'subs, W> Demangle<'subs, W> for DataMemberPrefix
7220where
7221    W: 'subs + DemangleWrite,
7222{
7223    #[inline]
7224    fn demangle<'prev, 'ctx>(
7225        &'subs self,
7226        ctx: &'ctx mut DemangleContext<'subs, W>,
7227        scope: Option<ArgScopeStack<'prev, 'subs>>,
7228    ) -> fmt::Result {
7229        let ctx = try_begin_demangle!(self, ctx, scope);
7230
7231        ctx.push_demangle_node(DemangleNodeType::DataMemberPrefix);
7232        let ret = self.0.demangle(ctx, scope);
7233        ctx.pop_demangle_node();
7234        ret
7235    }
7236}
7237
7238/// The `<substitution>` form: a back-reference to some component we've already
7239/// parsed.
7240///
7241/// ```text
7242/// <substitution> ::= S <seq-id> _
7243///                ::= S_
7244///                ::= St # ::std::
7245///                ::= Sa # ::std::allocator
7246///                ::= Sb # ::std::basic_string
7247///                ::= Ss # ::std::basic_string < char,
7248///                                               ::std::char_traits<char>,
7249///                                               ::std::allocator<char> >
7250///                ::= Si # ::std::basic_istream<char,  std::char_traits<char> >
7251///                ::= So # ::std::basic_ostream<char,  std::char_traits<char> >
7252///                ::= Sd # ::std::basic_iostream<char, std::char_traits<char> >
7253/// ```
7254#[derive(Clone, Debug, PartialEq, Eq)]
7255pub enum Substitution {
7256    /// A reference to an entity that already occurred, ie the `S_` and `S
7257    /// <seq-id> _` forms.
7258    BackReference(usize),
7259
7260    /// A well-known substitution component. These are the components that do
7261    /// not appear in the substitution table, but have abbreviations specified
7262    /// directly in the grammar.
7263    WellKnown(WellKnownComponent),
7264}
7265
7266impl Parse for Substitution {
7267    fn parse<'a, 'b>(
7268        ctx: &'a ParseContext,
7269        subs: &'a mut SubstitutionTable,
7270        input: IndexStr<'b>,
7271    ) -> Result<(Substitution, IndexStr<'b>)> {
7272        try_begin_parse!("Substitution", ctx, input);
7273
7274        if let Ok((well_known, tail)) = WellKnownComponent::parse(ctx, subs, input) {
7275            return Ok((Substitution::WellKnown(well_known), tail));
7276        }
7277
7278        let tail = consume(b"S", input)?;
7279        let (idx, tail) = if let Ok((idx, tail)) = SeqId::parse(ctx, subs, tail) {
7280            (idx.0 + 1, tail)
7281        } else {
7282            (0, tail)
7283        };
7284
7285        if !subs.contains(idx) {
7286            return Err(error::Error::BadBackReference);
7287        }
7288
7289        let tail = consume(b"_", tail)?;
7290        log!("Found a reference to @ {}", idx);
7291        Ok((Substitution::BackReference(idx), tail))
7292    }
7293}
7294
7295define_vocabulary! {
7296/// The `<substitution>` variants that are encoded directly in the grammar,
7297/// rather than as back references to other components in the substitution
7298/// table.
7299    #[derive(Clone, Debug, PartialEq, Eq)]
7300    pub enum WellKnownComponent {
7301        Std          (b"St", "std"),
7302        StdAllocator (b"Sa", "std::allocator"),
7303        StdString1   (b"Sb", "std::basic_string"),
7304        StdString2   (b"Ss", "std::string"),
7305        StdIstream   (b"Si", "std::basic_istream<char, std::char_traits<char> >"),
7306        StdOstream   (b"So", "std::ostream"),
7307        StdIostream  (b"Sd", "std::basic_iostream<char, std::char_traits<char> >")
7308    }
7309}
7310
7311impl<'a> GetLeafName<'a> for WellKnownComponent {
7312    fn get_leaf_name(&'a self, _: &'a SubstitutionTable) -> Option<LeafName<'a>> {
7313        match *self {
7314            WellKnownComponent::Std => None,
7315            _ => Some(LeafName::WellKnownComponent(self)),
7316        }
7317    }
7318}
7319
7320impl<'a> ArgScope<'a, 'a> for WellKnownComponent {
7321    fn leaf_name(&'a self) -> Result<LeafName<'a>> {
7322        Ok(LeafName::WellKnownComponent(self))
7323    }
7324
7325    fn get_template_arg(&'a self, _: usize) -> Result<(&'a TemplateArg, &'a TemplateArgs)> {
7326        Err(error::Error::BadTemplateArgReference)
7327    }
7328
7329    fn get_function_arg(&'a self, _: usize) -> Result<&'a Type> {
7330        Err(error::Error::BadFunctionArgReference)
7331    }
7332}
7333
7334impl<'subs, W> DemangleAsLeaf<'subs, W> for WellKnownComponent
7335where
7336    W: 'subs + DemangleWrite,
7337{
7338    fn demangle_as_leaf<'me, 'ctx>(
7339        &'me self,
7340        ctx: &'ctx mut DemangleContext<'subs, W>,
7341    ) -> fmt::Result {
7342        match *self {
7343            WellKnownComponent::Std => {
7344                panic!("should never treat `WellKnownComponent::Std` as a leaf name")
7345            }
7346            WellKnownComponent::StdAllocator => write!(ctx, "allocator"),
7347            WellKnownComponent::StdString1 => write!(ctx, "basic_string"),
7348            WellKnownComponent::StdString2 => write!(ctx, "string"),
7349            WellKnownComponent::StdIstream => write!(ctx, "basic_istream"),
7350            WellKnownComponent::StdOstream => write!(ctx, "ostream"),
7351            WellKnownComponent::StdIostream => write!(ctx, "basic_iostream"),
7352        }
7353    }
7354}
7355
7356/// The `<special-name>` production.
7357///
7358/// The `<special-name>` production is spread in pieces through out the ABI
7359/// spec, and then there are a bunch of `g++` extensions that have become de
7360/// facto.
7361///
7362/// ### 5.1.4.1 Virtual Tables and RTTI
7363///
7364/// ```text
7365/// <special-name> ::= TV <type>    # virtual table
7366///                ::= TT <type>    # VTT structure (construction vtable index)
7367///                ::= TI <type>    # typeinfo structure
7368///                ::= TS <type>    # typeinfo name (null-terminated byte string)
7369/// ```
7370///
7371/// ### 5.1.4.2 Virtual Override Thunks
7372///
7373/// ```text
7374/// <special-name> ::= T <call-offset> <base encoding>
7375///     # base is the nominal target function of thunk
7376///
7377/// <special-name> ::= Tc <call-offset> <call-offset> <base encoding>
7378///     # base is the nominal target function of thunk
7379///     # first call-offset is 'this' adjustment
7380///     # second call-offset is result adjustment
7381/// ```
7382///
7383/// ### 5.1.4.4 Guard Variables
7384///
7385/// ```text
7386/// <special-name> ::= GV <object name> # Guard variable for one-time initialization
7387///     # No <type>
7388/// ```
7389///
7390/// ### 5.1.4.5 Lifetime-Extended Temporaries
7391///
7392/// ```text
7393/// <special-name> ::= GR <object name> _             # First temporary
7394/// <special-name> ::= GR <object name> <seq-id> _    # Subsequent temporaries
7395/// ```
7396///
7397/// ### De Facto Standard Extensions
7398///
7399/// ```text
7400/// <special-name> ::= TC <type> <number> _ <type>    # construction vtable
7401///                ::= TF <type>                      # typinfo function
7402///                ::= TH <name>                      # TLS initialization function
7403///                ::= TW <name>                      # TLS wrapper function
7404///                ::= Gr <resource name>             # Java Resource
7405///                ::= GTt <encoding>                 # Transaction-Safe function
7406///                ::= GTn <encoding>                 # Non-Transaction-Safe function
7407/// ```
7408#[derive(Clone, Debug, PartialEq, Eq)]
7409pub enum SpecialName {
7410    /// A virtual table.
7411    VirtualTable(TypeHandle),
7412
7413    /// A VTT structure (construction vtable index).
7414    Vtt(TypeHandle),
7415
7416    /// A typeinfo structure.
7417    Typeinfo(TypeHandle),
7418
7419    /// A typeinfo name (null-terminated byte string).
7420    TypeinfoName(TypeHandle),
7421
7422    /// A virtual override thunk.
7423    VirtualOverrideThunk(CallOffset, Box<Encoding>),
7424
7425    /// A virtual override thunk with a covariant return type.
7426    VirtualOverrideThunkCovariant(CallOffset, CallOffset, Box<Encoding>),
7427
7428    /// An initialization guard for some static storage.
7429    Guard(Name),
7430
7431    /// A temporary used in the initialization of a static storage and promoted
7432    /// to a static lifetime.
7433    GuardTemporary(Name, usize),
7434
7435    /// A construction vtable structure.
7436    ConstructionVtable(TypeHandle, usize, TypeHandle),
7437
7438    /// A typeinfo function.
7439    TypeinfoFunction(TypeHandle),
7440
7441    /// A TLS initialization function.
7442    TlsInit(Name),
7443
7444    /// A TLS wrapper function.
7445    TlsWrapper(Name),
7446
7447    /// A Java Resource.
7448    JavaResource(Vec<ResourceName>),
7449
7450    /// A function declared transaction-safe
7451    TransactionClone(Box<Encoding>),
7452
7453    /// A function declared non-transaction-safe
7454    NonTransactionClone(Box<Encoding>),
7455}
7456
7457impl Parse for SpecialName {
7458    fn parse<'a, 'b>(
7459        ctx: &'a ParseContext,
7460        subs: &'a mut SubstitutionTable,
7461        input: IndexStr<'b>,
7462    ) -> Result<(SpecialName, IndexStr<'b>)> {
7463        try_begin_parse!("SpecialName", ctx, input);
7464
7465        let (head, tail) = match input.try_split_at(2) {
7466            None => return Err(error::Error::UnexpectedEnd),
7467            Some((head, tail)) => (head, tail),
7468        };
7469
7470        match head.as_ref() {
7471            b"TV" => {
7472                let (ty, tail) = TypeHandle::parse(ctx, subs, tail)?;
7473                Ok((SpecialName::VirtualTable(ty), tail))
7474            }
7475            b"TT" => {
7476                let (ty, tail) = TypeHandle::parse(ctx, subs, tail)?;
7477                Ok((SpecialName::Vtt(ty), tail))
7478            }
7479            b"TI" => {
7480                let (ty, tail) = TypeHandle::parse(ctx, subs, tail)?;
7481                Ok((SpecialName::Typeinfo(ty), tail))
7482            }
7483            b"TS" => {
7484                let (ty, tail) = TypeHandle::parse(ctx, subs, tail)?;
7485                Ok((SpecialName::TypeinfoName(ty), tail))
7486            }
7487            b"Tc" => {
7488                let (first, tail) = CallOffset::parse(ctx, subs, tail)?;
7489                let (second, tail) = CallOffset::parse(ctx, subs, tail)?;
7490                let (base, tail) = Encoding::parse(ctx, subs, tail)?;
7491                Ok((
7492                    SpecialName::VirtualOverrideThunkCovariant(first, second, Box::new(base)),
7493                    tail,
7494                ))
7495            }
7496            b"Th" | b"Tv" => {
7497                // The "h"/"v" is part of the `<call-offset>`, so back up to the
7498                // `input`.
7499                let tail = consume(b"T", input).unwrap();
7500                let (offset, tail) = CallOffset::parse(ctx, subs, tail)?;
7501                let (base, tail) = Encoding::parse(ctx, subs, tail)?;
7502                Ok((
7503                    SpecialName::VirtualOverrideThunk(offset, Box::new(base)),
7504                    tail,
7505                ))
7506            }
7507            b"TC" => {
7508                let (ty1, tail) = TypeHandle::parse(ctx, subs, tail)?;
7509                let (n, tail) = parse_number(10, false, tail)?;
7510                let tail = consume(b"_", tail)?;
7511                let (ty2, tail) = TypeHandle::parse(ctx, subs, tail)?;
7512                Ok((SpecialName::ConstructionVtable(ty1, n as usize, ty2), tail))
7513            }
7514            b"TF" => {
7515                let (ty, tail) = TypeHandle::parse(ctx, subs, tail)?;
7516                Ok((SpecialName::TypeinfoFunction(ty), tail))
7517            }
7518            b"TH" => {
7519                let (name, tail) = Name::parse(ctx, subs, tail)?;
7520                Ok((SpecialName::TlsInit(name), tail))
7521            }
7522            b"TW" => {
7523                let (name, tail) = Name::parse(ctx, subs, tail)?;
7524                Ok((SpecialName::TlsWrapper(name), tail))
7525            }
7526            b"GV" => {
7527                let (name, tail) = Name::parse(ctx, subs, tail)?;
7528                Ok((SpecialName::Guard(name), tail))
7529            }
7530            b"GR" => {
7531                let (name, tail) = Name::parse(ctx, subs, tail)?;
7532                let (idx, tail) = if let Ok(tail) = consume(b"_", tail) {
7533                    (0, tail)
7534                } else {
7535                    let (idx, tail) = SeqId::parse(ctx, subs, tail)?;
7536                    let tail = consume(b"_", tail)?;
7537                    (idx.0 + 1, tail)
7538                };
7539                Ok((SpecialName::GuardTemporary(name, idx), tail))
7540            }
7541            b"Gr" => {
7542                let (resource_name_len, tail) = parse_number(10, false, tail)?;
7543                if resource_name_len == 0 {
7544                    return Err(error::Error::UnexpectedText);
7545                }
7546
7547                let (head, tail) = match tail.try_split_at(resource_name_len as _) {
7548                    Some((head, tail)) => (head, tail),
7549                    None => return Err(error::Error::UnexpectedEnd),
7550                };
7551
7552                let head = consume(b"_", head)?;
7553
7554                let (resource_names, empty) = zero_or_more::<ResourceName>(ctx, subs, head)?;
7555                if !empty.is_empty() {
7556                    return Err(error::Error::UnexpectedText);
7557                }
7558
7559                Ok((SpecialName::JavaResource(resource_names), tail))
7560            }
7561            b"GT" => {
7562                match tail.next_or(error::Error::UnexpectedEnd)? {
7563                    (b'n', tail) => {
7564                        let (base, tail) = Encoding::parse(ctx, subs, tail)?;
7565                        Ok((SpecialName::NonTransactionClone(Box::new(base)), tail))
7566                    }
7567                    // Different letters could stand for different types of
7568                    // transactional cloning, but for now, treat them all the same
7569                    (b't', tail) | (_, tail) => {
7570                        let (base, tail) = Encoding::parse(ctx, subs, tail)?;
7571                        Ok((SpecialName::TransactionClone(Box::new(base)), tail))
7572                    }
7573                }
7574            }
7575            _ => Err(error::Error::UnexpectedText),
7576        }
7577    }
7578}
7579
7580impl<'subs, W> Demangle<'subs, W> for SpecialName
7581where
7582    W: 'subs + DemangleWrite,
7583{
7584    fn demangle<'prev, 'ctx>(
7585        &'subs self,
7586        ctx: &'ctx mut DemangleContext<'subs, W>,
7587        scope: Option<ArgScopeStack<'prev, 'subs>>,
7588    ) -> fmt::Result {
7589        let ctx = try_begin_demangle!(self, ctx, scope);
7590
7591        match *self {
7592            SpecialName::VirtualTable(ref ty) => {
7593                write!(ctx, "{{vtable(")?;
7594                ctx.push_demangle_node(DemangleNodeType::VirtualTable);
7595                ty.demangle(ctx, scope)?;
7596                ctx.pop_demangle_node();
7597                write!(ctx, ")}}")?;
7598                Ok(())
7599            }
7600            SpecialName::Vtt(ref ty) => {
7601                write!(ctx, "{{vtt(")?;
7602                ty.demangle(ctx, scope)?;
7603                write!(ctx, ")}}")?;
7604                Ok(())
7605            }
7606            SpecialName::Typeinfo(ref ty) => {
7607                write!(ctx, "typeinfo for ")?;
7608                ty.demangle(ctx, scope)
7609            }
7610            SpecialName::TypeinfoName(ref ty) => {
7611                write!(ctx, "typeinfo name for ")?;
7612                ty.demangle(ctx, scope)
7613            }
7614            SpecialName::VirtualOverrideThunk(ref offset, ref encoding) => {
7615                write!(ctx, "{{virtual override thunk(")?;
7616                offset.demangle(ctx, scope)?;
7617                write!(ctx, ", ")?;
7618                encoding.demangle(ctx, scope)?;
7619                write!(ctx, ")}}")?;
7620                Ok(())
7621            }
7622            SpecialName::VirtualOverrideThunkCovariant(
7623                ref this_offset,
7624                ref result_offset,
7625                ref encoding,
7626            ) => {
7627                write!(ctx, "{{virtual override thunk(")?;
7628                this_offset.demangle(ctx, scope)?;
7629                write!(ctx, ", ")?;
7630                result_offset.demangle(ctx, scope)?;
7631                write!(ctx, ", ")?;
7632                encoding.demangle(ctx, scope)?;
7633                write!(ctx, ")}}")?;
7634                Ok(())
7635            }
7636            SpecialName::Guard(ref name) => {
7637                write!(ctx, "guard variable for ")?;
7638                name.demangle(ctx, scope)
7639            }
7640            SpecialName::GuardTemporary(ref name, n) => {
7641                write!(ctx, "reference temporary #{} for ", n)?;
7642                name.demangle(ctx, scope)
7643            }
7644            SpecialName::ConstructionVtable(ref ty1, _, ref ty2) => {
7645                write!(ctx, "construction vtable for ")?;
7646                ty1.demangle(ctx, scope)?;
7647                write!(ctx, "-in-")?;
7648                ty2.demangle(ctx, scope)
7649            }
7650            SpecialName::TypeinfoFunction(ref ty) => {
7651                write!(ctx, "typeinfo fn for ")?;
7652                ty.demangle(ctx, scope)
7653            }
7654            SpecialName::TlsInit(ref name) => {
7655                write!(ctx, "TLS init function for ")?;
7656                name.demangle(ctx, scope)
7657            }
7658            SpecialName::TlsWrapper(ref name) => {
7659                write!(ctx, "TLS wrapper function for ")?;
7660                name.demangle(ctx, scope)
7661            }
7662            SpecialName::TransactionClone(ref encoding) => {
7663                write!(ctx, "transaction clone for ")?;
7664                encoding.demangle(ctx, scope)
7665            }
7666            SpecialName::NonTransactionClone(ref encoding) => {
7667                write!(ctx, "non-transaction clone for ")?;
7668                encoding.demangle(ctx, scope)
7669            }
7670            SpecialName::JavaResource(ref names) => {
7671                write!(ctx, "java resource ")?;
7672                for name in names {
7673                    name.demangle(ctx, scope)?;
7674                }
7675                Ok(())
7676            }
7677        }
7678    }
7679}
7680
7681/// The `<resource name>` pseudo-terminal.
7682#[derive(Clone, Debug, PartialEq, Eq)]
7683pub struct ResourceName {
7684    start: usize,
7685    end: usize,
7686}
7687
7688impl Parse for ResourceName {
7689    fn parse<'a, 'b>(
7690        ctx: &'a ParseContext,
7691        _subs: &'a mut SubstitutionTable,
7692        input: IndexStr<'b>,
7693    ) -> Result<(ResourceName, IndexStr<'b>)> {
7694        try_begin_parse!("ResourceName", ctx, input);
7695
7696        if input.is_empty() {
7697            return Err(error::Error::UnexpectedEnd);
7698        }
7699
7700        let mut end = input
7701            .as_ref()
7702            .iter()
7703            .map(|&c| c as char)
7704            .take_while(|&c| c != '$' || c.is_digit(36))
7705            .count();
7706
7707        if end == 0 {
7708            return Err(error::Error::UnexpectedText);
7709        }
7710
7711        if input.range_from(end..).peek() == Some(b'$') {
7712            match input.range_from(end..).peek_second() {
7713                Some(b'S') | Some(b'_') | Some(b'$') => end += 2,
7714                _ => return Err(error::Error::UnexpectedText),
7715            }
7716        }
7717
7718        let tail = input.range_from(end..);
7719
7720        let resource_name = ResourceName {
7721            start: input.index(),
7722            end: tail.index(),
7723        };
7724
7725        Ok((resource_name, tail))
7726    }
7727}
7728
7729impl<'subs, W> Demangle<'subs, W> for ResourceName
7730where
7731    W: 'subs + DemangleWrite,
7732{
7733    #[inline]
7734    fn demangle<'prev, 'ctx>(
7735        &'subs self,
7736        ctx: &'ctx mut DemangleContext<'subs, W>,
7737        scope: Option<ArgScopeStack<'prev, 'subs>>,
7738    ) -> fmt::Result {
7739        let ctx = try_begin_demangle!(self, ctx, scope);
7740
7741        let mut i = self.start;
7742        while i < self.end {
7743            let ch = ctx.input[i];
7744            if ch == b'$' {
7745                // Skip past the '$'
7746                i += 1;
7747                match ctx.input[i] {
7748                    b'S' => write!(ctx, "{}", '/')?,
7749                    b'_' => write!(ctx, "{}", '.')?,
7750                    b'$' => write!(ctx, "{}", '$')?,
7751                    _ => {
7752                        // Fall through
7753                    }
7754                }
7755            } else {
7756                write!(ctx, "{}", ch as char)?;
7757            }
7758            i += 1;
7759        }
7760
7761        Ok(())
7762    }
7763}
7764
7765/// The subobject expression production.
7766///
7767/// <expression> ::= so <referent type> <expr> [<offset number>] <union-selector>* [p] E
7768/// <union-selector> ::= _ [<number>]
7769///
7770/// Not yet in the spec: https://github.com/itanium-cxx-abi/cxx-abi/issues/47
7771/// But it has been shipping in clang for some time.
7772#[derive(Clone, Debug, PartialEq, Eq)]
7773pub struct SubobjectExpr {
7774    ty: TypeHandle,
7775    expr: Box<Expression>,
7776    offset: isize,
7777}
7778
7779impl Parse for SubobjectExpr {
7780    fn parse<'a, 'b>(
7781        ctx: &'a ParseContext,
7782        subs: &'a mut SubstitutionTable,
7783        input: IndexStr<'b>,
7784    ) -> Result<(SubobjectExpr, IndexStr<'b>)> {
7785        try_begin_parse!("SubobjectExpr", ctx, input);
7786
7787        let (ty, tail) = TypeHandle::parse(ctx, subs, input)?;
7788        let (expr, tail) = Expression::parse(ctx, subs, tail)?;
7789        let (offset, tail) = parse_number(10, true, tail).unwrap_or((0, tail));
7790
7791        // XXXkhuey handle union-selector and [p]
7792        let tail = consume(b"E", tail)?;
7793        Ok((
7794            SubobjectExpr {
7795                ty: ty,
7796                expr: Box::new(expr),
7797                offset: offset,
7798            },
7799            tail,
7800        ))
7801    }
7802}
7803
7804impl<'subs, W> Demangle<'subs, W> for SubobjectExpr
7805where
7806    W: 'subs + DemangleWrite,
7807{
7808    #[inline]
7809    fn demangle<'prev, 'ctx>(
7810        &'subs self,
7811        ctx: &'ctx mut DemangleContext<'subs, W>,
7812        scope: Option<ArgScopeStack<'prev, 'subs>>,
7813    ) -> fmt::Result {
7814        let ctx = try_begin_demangle!(self, ctx, scope);
7815
7816        self.expr.demangle(ctx, scope)?;
7817        write!(ctx, ".<")?;
7818        self.ty.demangle(ctx, scope)?;
7819        write!(ctx, " at offset {}>", self.offset)
7820    }
7821}
7822
7823/// Expect and consume the given byte str, and return the advanced `IndexStr` if
7824/// we saw the expectation. Otherwise return an error of kind
7825/// `error::Error::UnexpectedText` if the input doesn't match, or
7826/// `error::Error::UnexpectedEnd` if it isn't long enough.
7827#[inline]
7828fn consume<'a>(expected: &[u8], input: IndexStr<'a>) -> Result<IndexStr<'a>> {
7829    match input.try_split_at(expected.len()) {
7830        Some((head, tail)) if head == expected => Ok(tail),
7831        Some(_) => Err(error::Error::UnexpectedText),
7832        None => Err(error::Error::UnexpectedEnd),
7833    }
7834}
7835
7836fn one_or_more<'a, 'b, P>(
7837    ctx: &'a ParseContext,
7838    subs: &'a mut SubstitutionTable,
7839    input: IndexStr<'b>,
7840) -> Result<(Vec<P>, IndexStr<'b>)>
7841where
7842    P: Parse,
7843{
7844    let (first, mut tail) = P::parse(ctx, subs, input)?;
7845    let mut results = vec![first];
7846    loop {
7847        if let Ok((parsed, tail_tail)) = P::parse(ctx, subs, tail) {
7848            results.push(parsed);
7849            tail = tail_tail;
7850        } else {
7851            return Ok((results, tail));
7852        }
7853    }
7854}
7855
7856fn zero_or_more<'a, 'b, P>(
7857    ctx: &'a ParseContext,
7858    subs: &'a mut SubstitutionTable,
7859    input: IndexStr<'b>,
7860) -> Result<(Vec<P>, IndexStr<'b>)>
7861where
7862    P: Parse,
7863{
7864    let mut tail = input;
7865    let mut results = vec![];
7866    loop {
7867        if let Ok((parsed, tail_tail)) = P::parse(ctx, subs, tail) {
7868            results.push(parsed);
7869            tail = tail_tail;
7870        } else {
7871            return Ok((results, tail));
7872        }
7873    }
7874}
7875
7876/// Parse a number with the given `base`. Do not allow negative numbers
7877/// (prefixed with an 'n' instead of a '-') if `allow_signed` is false.
7878#[allow(unsafe_code)]
7879fn parse_number(base: u32, allow_signed: bool, mut input: IndexStr) -> Result<(isize, IndexStr)> {
7880    if input.is_empty() {
7881        return Err(error::Error::UnexpectedEnd);
7882    }
7883
7884    let num_is_negative = if allow_signed && input.as_ref()[0] == b'n' {
7885        input = input.range_from(1..);
7886
7887        if input.is_empty() {
7888            return Err(error::Error::UnexpectedEnd);
7889        }
7890
7891        true
7892    } else {
7893        false
7894    };
7895
7896    let num_numeric = input
7897        .as_ref()
7898        .iter()
7899        .map(|&c| c as char)
7900        .take_while(|c| c.is_digit(base) && (c.is_numeric() || c.is_uppercase()))
7901        .count();
7902    if num_numeric == 0 {
7903        return Err(error::Error::UnexpectedText);
7904    }
7905
7906    let (head, tail) = input.split_at(num_numeric);
7907    let head = head.as_ref();
7908
7909    if num_numeric > 1 && head[0] == b'0' {
7910        // "<number>s appearing in mangled names never have leading zeroes,
7911        // except for the value zero, represented as '0'."
7912        return Err(error::Error::UnexpectedText);
7913    }
7914
7915    let head = unsafe {
7916        // Safe because we know we only have valid numeric chars in this
7917        // slice, which are valid UTF-8.
7918        str::from_utf8_unchecked(head)
7919    };
7920
7921    let mut number = isize::from_str_radix(head, base).map_err(|_| error::Error::Overflow)?;
7922    if num_is_negative {
7923        number = -number;
7924    }
7925
7926    Ok((number, tail))
7927}
7928
7929#[cfg(test)]
7930mod tests {
7931    use super::{
7932        ArrayType, BareFunctionType, BaseUnresolvedName, BuiltinType, CallOffset, ClassEnumType,
7933        ClosureTypeName, CtorDtorName, CvQualifiers, DataMemberPrefix, Decltype, DestructorName,
7934        Discriminator, Encoding, ExceptionSpec, ExprPrimary, Expression, FunctionParam,
7935        FunctionType, GlobalCtorDtor, Identifier, Initializer, LambdaSig, LocalName, MangledName,
7936        MemberName, Name, NestedName, NonSubstitution, Number, NvOffset, OperatorName, Parse,
7937        ParseContext, PointerToMemberType, Prefix, PrefixHandle, RefQualifier, ResourceName, SeqId,
7938        SimpleId, SimpleOperatorName, SourceName, SpecialName, StandardBuiltinType, SubobjectExpr,
7939        Substitution, TaggedName, TemplateArg, TemplateArgs, TemplateParam, TemplateTemplateParam,
7940        TemplateTemplateParamHandle, Type, TypeHandle, UnnamedTypeName, UnqualifiedName,
7941        UnresolvedName, UnresolvedQualifierLevel, UnresolvedType, UnresolvedTypeHandle,
7942        UnscopedName, UnscopedTemplateName, UnscopedTemplateNameHandle, VOffset, VectorType,
7943        WellKnownComponent,
7944    };
7945
7946    use crate::error::Error;
7947    use crate::index_str::IndexStr;
7948    use crate::subs::{Substitutable, SubstitutionTable};
7949    use alloc::boxed::Box;
7950    use alloc::string::String;
7951    use core::fmt::Debug;
7952    use core::iter::FromIterator;
7953
7954    fn assert_parse_ok<P, S1, S2, I1, I2>(
7955        production: &'static str,
7956        subs: S1,
7957        input: I1,
7958        expected: P,
7959        expected_tail: I2,
7960        expected_new_subs: S2,
7961    ) where
7962        P: Debug + Parse + PartialEq,
7963        S1: AsRef<[Substitutable]>,
7964        S2: AsRef<[Substitutable]>,
7965        I1: AsRef<[u8]>,
7966        I2: AsRef<[u8]>,
7967    {
7968        let ctx = ParseContext::new(Default::default());
7969        let input = input.as_ref();
7970        let expected_tail = expected_tail.as_ref();
7971
7972        let expected_subs = SubstitutionTable::from_iter(
7973            subs.as_ref()
7974                .iter()
7975                .cloned()
7976                .chain(expected_new_subs.as_ref().iter().cloned()),
7977        );
7978        let mut subs = SubstitutionTable::from_iter(subs.as_ref().iter().cloned());
7979
7980        match P::parse(&ctx, &mut subs, IndexStr::from(input)) {
7981            Err(error) => panic!(
7982                "Parsing {:?} as {} failed: {}",
7983                String::from_utf8_lossy(input),
7984                production,
7985                error
7986            ),
7987            Ok((value, tail)) => {
7988                if value != expected {
7989                    panic!(
7990                        "Parsing {:?} as {} produced\n\n{:#?}\n\nbut we expected\n\n{:#?}",
7991                        String::from_utf8_lossy(input),
7992                        production,
7993                        value,
7994                        expected
7995                    );
7996                }
7997                if tail != expected_tail {
7998                    panic!(
7999                        "Parsing {:?} as {} left a tail of {:?}, expected {:?}",
8000                        String::from_utf8_lossy(input),
8001                        production,
8002                        tail,
8003                        String::from_utf8_lossy(expected_tail)
8004                    );
8005                }
8006                if subs[..] != expected_subs[..] {
8007                    panic!(
8008                        "Parsing {:?} as {} produced a substitutions table of\n\n\
8009                         {:#?}\n\n\
8010                         but we expected\n\n\
8011                         {:#?}",
8012                        String::from_utf8_lossy(input),
8013                        production,
8014                        subs,
8015                        expected_subs
8016                    );
8017                }
8018            }
8019        }
8020
8021        log!("=== assert_parse_ok PASSED ====================================");
8022    }
8023
8024    fn simple_assert_parse_ok<P, I1, I2>(
8025        production: &'static str,
8026        input: I1,
8027        expected: P,
8028        expected_tail: I2,
8029    ) where
8030        P: Debug + Parse + PartialEq,
8031        I1: AsRef<[u8]>,
8032        I2: AsRef<[u8]>,
8033    {
8034        assert_parse_ok::<P, _, _, _, _>(production, [], input, expected, expected_tail, []);
8035    }
8036
8037    fn assert_parse_err<P, S, I>(production: &'static str, subs: S, input: I, expected_error: Error)
8038    where
8039        P: Debug + Parse + PartialEq,
8040        S: AsRef<[Substitutable]>,
8041        I: AsRef<[u8]>,
8042    {
8043        let input = input.as_ref();
8044        let ctx = ParseContext::new(Default::default());
8045        let mut subs = SubstitutionTable::from_iter(subs.as_ref().iter().cloned());
8046
8047        match P::parse(&ctx, &mut subs, IndexStr::from(input)) {
8048            Err(ref error) if *error == expected_error => {}
8049            Err(ref error) => {
8050                panic!(
8051                    "Parsing {:?} as {} produced an error of kind {:?}, but we expected kind {:?}",
8052                    String::from_utf8_lossy(input),
8053                    production,
8054                    error,
8055                    expected_error
8056                );
8057            }
8058            Ok((value, tail)) => {
8059                panic!(
8060                    "Parsing {:?} as {} produced value\
8061                     \n\n\
8062                     {:#?}\
8063                     \n\n\
8064                     and tail {:?}, but we expected error kind {:?}",
8065                    String::from_utf8_lossy(input),
8066                    production,
8067                    value,
8068                    tail,
8069                    expected_error
8070                );
8071            }
8072        }
8073
8074        log!("=== assert_parse_err PASSED ===================================");
8075    }
8076
8077    fn simple_assert_parse_err<P, I>(production: &'static str, input: I, expected_error: Error)
8078    where
8079        P: Debug + Parse + PartialEq,
8080        I: AsRef<[u8]>,
8081    {
8082        assert_parse_err::<P, _, _>(production, [], input, expected_error);
8083    }
8084
8085    #[test]
8086    fn recursion_limit() {
8087        // Build the mangled symbol for the type `*****char` where the "*****"
8088        // is 10,000 pointer indirections. This is a valid type symbol, but
8089        // something that would cause us to blow the stack.
8090        let mut mangled = String::new();
8091        for _ in 0..10_000 {
8092            mangled.push('P');
8093        }
8094        mangled += "c";
8095
8096        simple_assert_parse_err::<TypeHandle, _>("TypeHandle", mangled, Error::TooMuchRecursion);
8097    }
8098
8099    macro_rules! assert_parse {
8100        ( $production:ident {
8101            $( with subs $subs:expr => {
8102                Ok => {
8103                    $( $input:expr => {
8104                        $expected:expr ,
8105                        $expected_tail:expr ,
8106                        $expected_new_subs:expr
8107                    } )*
8108                }
8109                Err => {
8110                    $( $error_input:expr => $error:expr , )*
8111                }
8112            } )*
8113        } ) => {
8114            $( $(
8115                assert_parse_ok::<$production, _, _, _, _>(stringify!($production),
8116                                                           $subs,
8117                                                           $input,
8118                                                           $expected,
8119                                                           $expected_tail,
8120                                                           $expected_new_subs);
8121            )* )*
8122
8123            $( $(
8124                assert_parse_err::<$production, _, _>(stringify!($production),
8125                                                      $subs,
8126                                                      $error_input,
8127                                                      $error);
8128            )* )*
8129        };
8130
8131        ( $production:ident {
8132            Ok => {
8133                $( $input:expr => {
8134                    $expected:expr ,
8135                    $expected_tail:expr
8136                } )*
8137            }
8138            Err => {
8139                $( $error_input:expr => $error:expr , )*
8140            }
8141        } ) => {
8142            $(
8143                simple_assert_parse_ok::<$production, _, _>(stringify!($production),
8144                                                            $input,
8145                                                            $expected,
8146                                                            $expected_tail);
8147            )*
8148
8149
8150            $(
8151                simple_assert_parse_err::<$production, _>(stringify!($production),
8152                                                          $error_input,
8153                                                          $error);
8154            )*
8155        };
8156    }
8157
8158    #[test]
8159    fn parse_mangled_name() {
8160        assert_parse!(MangledName {
8161            Ok => {
8162                b"_Z3foo..." => {
8163                    MangledName::Encoding(
8164                        Encoding::Data(
8165                            Name::Unscoped(
8166                                UnscopedName::Unqualified(
8167                                    UnqualifiedName::Source(
8168                                        SourceName(Identifier {
8169                                            start: 3,
8170                                            end: 6,
8171                                        }))))), vec![]),
8172                    b"..."
8173                }
8174                b"_GLOBAL__I__Z3foo..." => {
8175                    MangledName::GlobalCtorDtor(
8176                        GlobalCtorDtor::Ctor(
8177                            Box::new(
8178                                MangledName::Encoding(
8179                                    Encoding::Data(
8180                                        Name::Unscoped(
8181                                            UnscopedName::Unqualified(
8182                                                UnqualifiedName::Source(
8183                                                    SourceName(
8184                                                        Identifier {
8185                                                            start: 14,
8186                                                            end: 17,
8187                                                        }))))), vec![])))),
8188                    b"..."
8189                }
8190            }
8191            Err => {
8192                b"_Y" => Error::UnexpectedText,
8193                b"_Z" => Error::UnexpectedEnd,
8194                b"_" => Error::UnexpectedEnd,
8195                b"" => Error::UnexpectedEnd,
8196                b"_GLOBAL_" => Error::UnexpectedEnd,
8197            }
8198        });
8199    }
8200
8201    #[test]
8202    fn parse_encoding() {
8203        assert_parse!(Encoding {
8204            with subs [] => {
8205                Ok => {
8206                    b"3fooi..." => {
8207                        Encoding::Function(
8208                            Name::Unscoped(
8209                                UnscopedName::Unqualified(
8210                                    UnqualifiedName::Source(
8211                                        SourceName(Identifier {
8212                                            start: 1,
8213                                            end: 4,
8214                                        })))),
8215                            BareFunctionType(vec![
8216                                TypeHandle::Builtin(BuiltinType::Standard(StandardBuiltinType::Int))
8217                            ])),
8218                        b"...",
8219                        []
8220                    }
8221                    b"3foo..." => {
8222                        Encoding::Data(
8223                            Name::Unscoped(
8224                                UnscopedName::Unqualified(
8225                                    UnqualifiedName::Source(
8226                                        SourceName(Identifier {
8227                                            start: 1,
8228                                            end: 4,
8229                                        }))))),
8230                        b"...",
8231                        []
8232                    }
8233                    b"GV3abc..." => {
8234                        Encoding::Special(
8235                            SpecialName::Guard(
8236                                Name::Unscoped(
8237                                    UnscopedName::Unqualified(
8238                                        UnqualifiedName::Source(
8239                                            SourceName(Identifier {
8240                                                start: 3,
8241                                                end: 6,
8242                                            })))))),
8243                        b"...",
8244                        []
8245                    }
8246                }
8247                Err => {
8248                    b"zzz" => Error::UnexpectedText,
8249                    b"" => Error::UnexpectedEnd,
8250                }
8251            }
8252        });
8253    }
8254
8255    #[test]
8256    fn parse_global_ctor_dtor() {
8257        assert_parse!(GlobalCtorDtor {
8258            Ok => {
8259                b"_I__Z3foo..." => {
8260                    GlobalCtorDtor::Ctor(
8261                        Box::new(
8262                            MangledName::Encoding(
8263                                Encoding::Data(
8264                                    Name::Unscoped(
8265                                        UnscopedName::Unqualified(
8266                                            UnqualifiedName::Source(
8267                                                SourceName(
8268                                                    Identifier {
8269                                                        start: 6,
8270                                                        end: 9,
8271                                                    }))))), vec![]))),
8272                    b"..."
8273                }
8274                b".I__Z3foo..." => {
8275                    GlobalCtorDtor::Ctor(
8276                        Box::new(
8277                            MangledName::Encoding(
8278                                Encoding::Data(
8279                                    Name::Unscoped(
8280                                        UnscopedName::Unqualified(
8281                                            UnqualifiedName::Source(
8282                                                SourceName(
8283                                                    Identifier {
8284                                                        start: 6,
8285                                                        end: 9,
8286                                                    }))))), vec![]))),
8287                    b"..."
8288                }
8289                b"$I__Z3foo..." => {
8290                    GlobalCtorDtor::Ctor(
8291                        Box::new(
8292                            MangledName::Encoding(
8293                                Encoding::Data(
8294                                    Name::Unscoped(
8295                                        UnscopedName::Unqualified(
8296                                            UnqualifiedName::Source(
8297                                                SourceName(
8298                                                    Identifier {
8299                                                        start: 6,
8300                                                        end: 9,
8301                                                    }))))), vec![]))),
8302                    b"..."
8303                }
8304                b"_D__Z3foo..." => {
8305                    GlobalCtorDtor::Dtor(
8306                        Box::new(
8307                            MangledName::Encoding(
8308                                Encoding::Data(
8309                                    Name::Unscoped(
8310                                        UnscopedName::Unqualified(
8311                                            UnqualifiedName::Source(
8312                                                SourceName(
8313                                                    Identifier {
8314                                                        start: 6,
8315                                                        end: 9,
8316                                                    }))))), vec![]))),
8317                    b"..."
8318                }
8319                b".D__Z3foo..." => {
8320                    GlobalCtorDtor::Dtor(
8321                        Box::new(
8322                            MangledName::Encoding(
8323                                Encoding::Data(
8324                                    Name::Unscoped(
8325                                        UnscopedName::Unqualified(
8326                                            UnqualifiedName::Source(
8327                                                SourceName(
8328                                                    Identifier {
8329                                                        start: 6,
8330                                                        end: 9,
8331                                                    }))))), vec![]))),
8332                    b"..."
8333                }
8334                b"$D__Z3foo..." => {
8335                    GlobalCtorDtor::Dtor(
8336                        Box::new(
8337                            MangledName::Encoding(
8338                                Encoding::Data(
8339                                    Name::Unscoped(
8340                                        UnscopedName::Unqualified(
8341                                            UnqualifiedName::Source(
8342                                                SourceName(
8343                                                    Identifier {
8344                                                        start: 6,
8345                                                        end: 9,
8346                                                    }))))), vec![]))),
8347                    b"..."
8348                }
8349            }
8350            Err => {
8351                b"_I" => Error::UnexpectedEnd,
8352                b"_" => Error::UnexpectedEnd,
8353                b"" => Error::UnexpectedEnd,
8354                b"blag" => Error::UnexpectedText,
8355                b"_J" => Error::UnexpectedText,
8356                b"_IJ" => Error::UnexpectedText,
8357            }
8358        });
8359    }
8360
8361    #[test]
8362    fn parse_name() {
8363        assert_parse!(Name {
8364            with subs [
8365                Substitutable::Prefix(
8366                    Prefix::Unqualified(
8367                        UnqualifiedName::Operator(OperatorName::Simple(SimpleOperatorName::New)))),
8368                Substitutable::Prefix(
8369                    Prefix::Nested(PrefixHandle::BackReference(0),
8370                                   UnqualifiedName::Operator(OperatorName::Simple(SimpleOperatorName::New)))),
8371            ] => {
8372                Ok => {
8373                    b"NS0_3abcE..." => {
8374                        Name::Nested(NestedName::Unqualified(CvQualifiers::default(),
8375                                                             None,
8376                                                             PrefixHandle::BackReference(1),
8377                                                             UnqualifiedName::Source(SourceName(Identifier {
8378                                                                 start: 5,
8379                                                                 end: 8,
8380                                                             })))),
8381                        b"...",
8382                        []
8383                    }
8384                    b"3abc..." => {
8385                        Name::Unscoped(
8386                            UnscopedName::Unqualified(
8387                                UnqualifiedName::Source(
8388                                    SourceName(Identifier {
8389                                        start: 1,
8390                                        end: 4,
8391                                    })))),
8392                        b"...",
8393                        []
8394                    }
8395                    b"dlIcE..." => {
8396                        Name::UnscopedTemplate(
8397                            UnscopedTemplateNameHandle::BackReference(2),
8398                            TemplateArgs(vec![
8399                                TemplateArg::Type(
8400                                    TypeHandle::Builtin(
8401                                        BuiltinType::Standard(StandardBuiltinType::Char)))
8402                            ])),
8403                        b"...",
8404                        [
8405                            Substitutable::UnscopedTemplateName(
8406                                UnscopedTemplateName(
8407                                    UnscopedName::Unqualified(
8408                                        UnqualifiedName::Operator(
8409                                            OperatorName::Simple(
8410                                                SimpleOperatorName::Delete))))),
8411                        ]
8412                    }
8413                    b"Z3abcEs..." => {
8414                        Name::Local(
8415                            LocalName::Relative(
8416                                Box::new(Encoding::Data(
8417                                    Name::Unscoped(
8418                                        UnscopedName::Unqualified(
8419                                            UnqualifiedName::Source(
8420                                                SourceName(Identifier {
8421                                                    start: 2,
8422                                                    end: 5,
8423                                                })))))),
8424                                None,
8425                                None)),
8426                        b"...",
8427                        []
8428                    }
8429                }
8430                Err => {
8431                    b"zzz" => Error::UnexpectedText,
8432                    b"" => Error::UnexpectedEnd,
8433                }
8434            }
8435        });
8436    }
8437
8438    #[test]
8439    fn parse_unscoped_template_name_handle() {
8440        assert_parse!(UnscopedTemplateNameHandle {
8441            with subs [
8442                Substitutable::UnscopedTemplateName(
8443                    UnscopedTemplateName(
8444                        UnscopedName::Unqualified(
8445                            UnqualifiedName::Operator(
8446                                OperatorName::Simple(
8447                                    SimpleOperatorName::New))))),
8448            ] => {
8449                Ok => {
8450                    b"S_..." => {
8451                        UnscopedTemplateNameHandle::BackReference(0),
8452                        b"...",
8453                        []
8454                    }
8455                    b"dl..." => {
8456                        UnscopedTemplateNameHandle::BackReference(1),
8457                        b"...",
8458                        [
8459                            Substitutable::UnscopedTemplateName(
8460                                UnscopedTemplateName(
8461                                    UnscopedName::Unqualified(
8462                                        UnqualifiedName::Operator(
8463                                            OperatorName::Simple(
8464                                                SimpleOperatorName::Delete)))))
8465                        ]
8466                    }
8467                }
8468                Err => {
8469                    b"zzzz" => Error::UnexpectedText,
8470                    b"" => Error::UnexpectedEnd,
8471                }
8472            }
8473        });
8474    }
8475
8476    #[test]
8477    fn parse_nested_name() {
8478        // <nested-name> ::= N [<CV-qualifiers>] [<ref-qualifier>] <prefix> <unqualified-name> E
8479        //               ::= N [<CV-qualifiers>] [<ref-qualifier>] <template-prefix> <template-args> E
8480        assert_parse!(NestedName {
8481            with subs [
8482                Substitutable::Prefix(
8483                    Prefix::Unqualified(
8484                        UnqualifiedName::Operator(
8485                            OperatorName::Simple(
8486                                SimpleOperatorName::New)))),
8487            ] => {
8488                Ok => {
8489                    b"NKOS_3abcE..." => {
8490                        NestedName::Unqualified(
8491                            CvQualifiers {
8492                                restrict: false,
8493                                volatile: false,
8494                                const_: true,
8495                            },
8496                            Some(RefQualifier::RValueRef),
8497                            PrefixHandle::BackReference(0),
8498                            UnqualifiedName::Source(
8499                                SourceName(Identifier {
8500                                    start: 6,
8501                                    end: 9,
8502                                }))),
8503                        b"...",
8504                        []
8505                    }
8506                    b"NOS_3abcE..." => {
8507                        NestedName::Unqualified(
8508                            CvQualifiers {
8509                                restrict: false,
8510                                volatile: false,
8511                                const_: false,
8512                            },
8513                            Some(RefQualifier::RValueRef),
8514                            PrefixHandle::BackReference(0),
8515                            UnqualifiedName::Source(
8516                                SourceName(Identifier {
8517                                    start: 5,
8518                                    end: 8,
8519                                }))),
8520                        b"...",
8521                        []
8522                    }
8523                    b"NS_3abcE..." => {
8524                        NestedName::Unqualified(
8525                            CvQualifiers {
8526                                restrict: false,
8527                                volatile: false,
8528                                const_: false,
8529                            },
8530                            None,
8531                            PrefixHandle::BackReference(0),
8532                            UnqualifiedName::Source(
8533                                SourceName(Identifier {
8534                                    start: 4,
8535                                    end: 7,
8536                                }))),
8537                        b"...",
8538                        []
8539                    }
8540                    b"NKOS_3abcIJEEE..." => {
8541                        NestedName::Template(
8542                            CvQualifiers {
8543                                restrict: false,
8544                                volatile: false,
8545                                const_: true,
8546                            },
8547                            Some(RefQualifier::RValueRef),
8548                            PrefixHandle::NonSubstitution(NonSubstitution(0))),
8549                        b"...",
8550                        [
8551                            Substitutable::Prefix(
8552                                Prefix::Nested(
8553                                    PrefixHandle::BackReference(0),
8554                                    UnqualifiedName::Source(
8555                                        SourceName(Identifier {
8556                                            start: 6,
8557                                            end: 9,
8558                                        })))),
8559                        ]
8560                    }
8561                    b"NOS_3abcIJEEE..." => {
8562                        NestedName::Template(
8563                            CvQualifiers {
8564                                restrict: false,
8565                                volatile: false,
8566                                const_: false,
8567                            },
8568                            Some(RefQualifier::RValueRef),
8569                            PrefixHandle::NonSubstitution(NonSubstitution(0))),
8570                        b"...",
8571                        [
8572                            Substitutable::Prefix(
8573                                Prefix::Nested(
8574                                    PrefixHandle::BackReference(0),
8575                                    UnqualifiedName::Source(
8576                                        SourceName(Identifier {
8577                                            start: 5,
8578                                            end: 8,
8579                                        })))),
8580                        ]
8581                    }
8582                    b"NS_3abcIJEEE..." => {
8583                        NestedName::Template(
8584                            CvQualifiers {
8585                                restrict: false,
8586                                volatile: false,
8587                                const_: false,
8588                            },
8589                            None,
8590                            PrefixHandle::NonSubstitution(NonSubstitution(0))),
8591                        b"...",
8592                        [
8593                            Substitutable::Prefix(
8594                                Prefix::Nested(
8595                                    PrefixHandle::BackReference(0),
8596                                    UnqualifiedName::Source(
8597                                        SourceName(Identifier {
8598                                            start: 4,
8599                                            end: 7,
8600                                        })))),
8601                        ]
8602                    }
8603                }
8604                Err => {
8605                    // Ends with a prefix that is not a name or template.
8606                    b"NS_E..." => Error::UnexpectedText,
8607                    b"NS_DttrEE..." => Error::UnexpectedText,
8608
8609                    b"zzz" => Error::UnexpectedText,
8610                    b"Nzzz" => Error::UnexpectedText,
8611                    b"NKzzz" => Error::UnexpectedText,
8612                    b"NKOzzz" => Error::UnexpectedText,
8613                    b"NKO3abczzz" => Error::UnexpectedText,
8614                    b"NKO3abc3abczzz" => Error::UnexpectedText,
8615                    b"" => Error::UnexpectedEnd,
8616                    b"N" => Error::UnexpectedEnd,
8617                    b"NK" => Error::UnexpectedEnd,
8618                    b"NKO" => Error::UnexpectedEnd,
8619                    b"NKO3abc" => Error::UnexpectedEnd,
8620                    b"NKO3abc3abc" => Error::UnexpectedEnd,
8621                }
8622            }
8623        });
8624    }
8625
8626    #[test]
8627    fn parse_prefix_handle() {
8628        // <prefix> ::= <unqualified-name>
8629        //          ::= <prefix> <unqualified-name>
8630        //          ::= <template-prefix> <template-args>
8631        //          ::= <template-param>
8632        //          ::= <decltype>
8633        //          ::= <prefix> <data-member-prefix>
8634        //          ::= <substitution>
8635        assert_parse!(PrefixHandle {
8636            with subs [
8637                Substitutable::Prefix(
8638                    Prefix::Unqualified(
8639                        UnqualifiedName::Operator(
8640                            OperatorName::Simple(
8641                                SimpleOperatorName::New)))),
8642            ] => {
8643                Ok => {
8644                    b"3foo..." => {
8645                        PrefixHandle::BackReference(1),
8646                        b"...",
8647                        [
8648                            Substitutable::Prefix(
8649                                Prefix::Unqualified(
8650                                    UnqualifiedName::Source(
8651                                        SourceName(Identifier {
8652                                            start: 1,
8653                                            end: 4,
8654                                        }))))
8655                        ]
8656                    }
8657                    b"3abc3def..." => {
8658                        PrefixHandle::BackReference(2),
8659                        b"...",
8660                        [
8661                            Substitutable::Prefix(
8662                                Prefix::Unqualified(
8663                                    UnqualifiedName::Source(
8664                                        SourceName(Identifier {
8665                                            start: 1,
8666                                            end: 4,
8667                                        })))),
8668                            Substitutable::Prefix(
8669                                Prefix::Nested(
8670                                    PrefixHandle::BackReference(1),
8671                                    UnqualifiedName::Source(
8672                                        SourceName(Identifier {
8673                                            start: 5,
8674                                            end: 8,
8675                                        })))),
8676                        ]
8677                    }
8678                    b"3fooIJEE..." => {
8679                        PrefixHandle::BackReference(2),
8680                        b"...",
8681                        [
8682                            Substitutable::Prefix(
8683                                Prefix::Unqualified(
8684                                    UnqualifiedName::Source(
8685                                        SourceName(Identifier {
8686                                            start: 1,
8687                                            end: 4,
8688                                        })))),
8689                            Substitutable::Prefix(
8690                                Prefix::Template(PrefixHandle::BackReference(1),
8691                                                 TemplateArgs(vec![
8692                                                     TemplateArg::ArgPack(vec![]),
8693                                                 ])))
8694                        ]
8695                    }
8696                    b"T_..." => {
8697                        PrefixHandle::BackReference(1),
8698                        b"...",
8699                        [
8700                            Substitutable::Prefix(Prefix::TemplateParam(TemplateParam(0))),
8701                        ]
8702                    }
8703                    b"DTtrE..." => {
8704                        PrefixHandle::BackReference(1),
8705                        b"...",
8706                        [
8707                            Substitutable::Prefix(
8708                                Prefix::Decltype(
8709                                    Decltype::Expression(Expression::Rethrow))),
8710                        ]
8711                    }
8712                    b"3abc3defM..." => {
8713                        PrefixHandle::BackReference(2),
8714                        b"...",
8715                        [
8716                            Substitutable::Prefix(
8717                                Prefix::Unqualified(
8718                                    UnqualifiedName::Source(
8719                                        SourceName(Identifier {
8720                                            start: 1,
8721                                            end: 4,
8722                                        })))),
8723                            Substitutable::Prefix(
8724                                Prefix::DataMember(
8725                                    PrefixHandle::BackReference(1),
8726                                    DataMemberPrefix(
8727                                        SourceName(Identifier {
8728                                            start: 5,
8729                                            end: 8,
8730                                        })))),
8731                        ]
8732                    }
8733                    b"S_..." => {
8734                        PrefixHandle::BackReference(0),
8735                        b"...",
8736                        []
8737                    }
8738                    // The trailing E and <nested-name> case...
8739                    b"3abc3defE..." => {
8740                        PrefixHandle::NonSubstitution(NonSubstitution(0)),
8741                        b"E...",
8742                        [
8743                            Substitutable::Prefix(
8744                                Prefix::Unqualified(
8745                                    UnqualifiedName::Source(
8746                                        SourceName(Identifier {
8747                                            start: 1,
8748                                            end: 4,
8749                                        })))),
8750                        ]
8751                    }
8752                }
8753                Err => {
8754                    b"zzz" => Error::UnexpectedText,
8755                    b"" => Error::UnexpectedEnd,
8756                }
8757            }
8758        });
8759    }
8760
8761    #[test]
8762    fn parse_type_handle() {
8763        assert_parse!(TypeHandle {
8764            with subs [
8765                Substitutable::Type(
8766                    Type::PointerTo(
8767                        TypeHandle::Builtin(BuiltinType::Standard(StandardBuiltinType::Char)))),
8768            ] => {
8769                Ok => {
8770                    b"S_..." => {
8771                        TypeHandle::BackReference(0),
8772                        b"...",
8773                        []
8774                    }
8775                    b"c..." => {
8776                        TypeHandle::Builtin(BuiltinType::Standard(StandardBuiltinType::Char)),
8777                        b"...",
8778                        []
8779                    }
8780                    b"FS_E..." => {
8781                        TypeHandle::BackReference(1),
8782                        b"...",
8783                        [
8784                            Substitutable::Type(
8785                                Type::Function(FunctionType {
8786                                    cv_qualifiers: CvQualifiers {
8787                                        restrict: false,
8788                                        volatile: false,
8789                                        const_: false,
8790                                    },
8791                                    exception_spec: None,
8792                                    transaction_safe: false,
8793                                    extern_c: false,
8794                                    bare: BareFunctionType(vec![TypeHandle::BackReference(0)]),
8795                                    ref_qualifier: None,
8796                                })),
8797                        ]
8798                    }
8799                    b"A_S_..." => {
8800                        TypeHandle::BackReference(1),
8801                        b"...",
8802                        [
8803                            Substitutable::Type(
8804                                Type::Array(ArrayType::NoDimension(TypeHandle::BackReference(0)))),
8805                        ]
8806                    }
8807                    b"MS_S_..." => {
8808                        TypeHandle::BackReference(1),
8809                        b"...",
8810                        [
8811                            Substitutable::Type(
8812                                Type::PointerToMember(
8813                                    PointerToMemberType(TypeHandle::BackReference(0),
8814                                                        TypeHandle::BackReference(0)))),
8815                        ]
8816                    }
8817                    b"T_..." => {
8818                        TypeHandle::BackReference(1),
8819                        b"...",
8820                        [
8821                            Substitutable::Type(Type::TemplateParam(TemplateParam(0))),
8822                        ]
8823                    }
8824                    b"T_IS_E..." => {
8825                        TypeHandle::BackReference(2),
8826                        b"...",
8827                        [
8828                            Substitutable::TemplateTemplateParam(
8829                                TemplateTemplateParam(TemplateParam(0))),
8830                            Substitutable::Type(
8831                                Type::TemplateTemplate(
8832                                    TemplateTemplateParamHandle::BackReference(1),
8833                                    TemplateArgs(vec![
8834                                        TemplateArg::Type(TypeHandle::BackReference(0))
8835                                    ]))),
8836                        ]
8837                    }
8838                    b"DTtrE..." => {
8839                        TypeHandle::BackReference(1),
8840                        b"...",
8841                        [
8842                            Substitutable::Type(
8843                                Type::Decltype(Decltype::Expression(Expression::Rethrow))),
8844                        ]
8845                    }
8846                    b"KS_..." => {
8847                        TypeHandle::BackReference(1),
8848                        b"...",
8849                        [
8850                            Substitutable::Type(Type::Qualified(CvQualifiers {
8851                                restrict: false,
8852                                volatile: false,
8853                                const_: true,
8854                            }, TypeHandle::BackReference(0)))
8855                        ]
8856                    }
8857                    b"PS_..." => {
8858                        TypeHandle::BackReference(1),
8859                        b"...",
8860                        [
8861                            Substitutable::Type(Type::PointerTo(TypeHandle::BackReference(0)))
8862                        ]
8863                    }
8864                    b"RS_..." => {
8865                        TypeHandle::BackReference(1),
8866                        b"...",
8867                        [
8868                            Substitutable::Type(Type::LvalueRef(TypeHandle::BackReference(0)))
8869                        ]
8870                    }
8871                    b"OS_..." => {
8872                        TypeHandle::BackReference(1),
8873                        b"...",
8874                        [
8875                            Substitutable::Type(Type::RvalueRef(TypeHandle::BackReference(0)))
8876                        ]
8877                    }
8878                    b"CS_..." => {
8879                        TypeHandle::BackReference(1),
8880                        b"...",
8881                        [
8882                            Substitutable::Type(Type::Complex(TypeHandle::BackReference(0)))
8883                        ]
8884                    }
8885                    b"GS_..." => {
8886                        TypeHandle::BackReference(1),
8887                        b"...",
8888                        [
8889                            Substitutable::Type(Type::Imaginary(TypeHandle::BackReference(0)))
8890                        ]
8891                    }
8892                    b"U3abcS_..." => {
8893                        TypeHandle::BackReference(1),
8894                        b"...",
8895                        [
8896                            Substitutable::Type(
8897                                Type::VendorExtension(
8898                                    SourceName(Identifier {
8899                                        start: 2,
8900                                        end: 5,
8901                                    }),
8902                                    None,
8903                                    TypeHandle::BackReference(0)))
8904                        ]
8905                    }
8906                    b"U3abcIS_ES_..." => {
8907                        TypeHandle::BackReference(1),
8908                        b"...",
8909                        [
8910                            Substitutable::Type(
8911                                Type::VendorExtension(
8912                                    SourceName(Identifier {
8913                                        start: 2,
8914                                        end: 5,
8915                                    }),
8916                                    Some(TemplateArgs(vec![
8917                                        TemplateArg::Type(TypeHandle::BackReference(0))
8918                                    ])),
8919                                    TypeHandle::BackReference(0)))
8920                        ]
8921                    }
8922                    b"DpS_..." => {
8923                        TypeHandle::BackReference(1),
8924                        b"...",
8925                        [
8926                            Substitutable::Type(
8927                                Type::PackExpansion(TypeHandle::BackReference(0))),
8928                        ]
8929                    }
8930                    b"3abc..." => {
8931                        TypeHandle::BackReference(1),
8932                        b"...",
8933                        [
8934                            Substitutable::Type(
8935                                Type::ClassEnum(
8936                                    ClassEnumType::Named(
8937                                        Name::Unscoped(
8938                                            UnscopedName::Unqualified(
8939                                                UnqualifiedName::Source(
8940                                                    SourceName(Identifier {
8941                                                        start: 1,
8942                                                        end: 4,
8943                                                    })))))))
8944                        ]
8945                    }
8946                }
8947                Err => {
8948                    b"P" => Error::UnexpectedEnd,
8949                    b"R" => Error::UnexpectedEnd,
8950                    b"O" => Error::UnexpectedEnd,
8951                    b"C" => Error::UnexpectedEnd,
8952                    b"G" => Error::UnexpectedEnd,
8953                    b"Dp" => Error::UnexpectedEnd,
8954                    b"D" => Error::UnexpectedEnd,
8955                    b"P" => Error::UnexpectedEnd,
8956                    b"" => Error::UnexpectedEnd,
8957                }
8958            }
8959        });
8960    }
8961
8962    #[test]
8963    fn parse_exception_spec() {
8964        assert_parse!(ExceptionSpec {
8965            Ok => {
8966                b"Do..." => {
8967                    ExceptionSpec::NoExcept,
8968                    b"..."
8969                }
8970                b"DOtrE..." => {
8971                    ExceptionSpec::Computed(Expression::Rethrow),
8972                    b"..."
8973                }
8974            }
8975            Err => {
8976                b"DOtre" => Error::UnexpectedText,
8977                b"DOE" => Error::UnexpectedText,
8978                b"D" => Error::UnexpectedEnd,
8979                b"" => Error::UnexpectedEnd,
8980            }
8981        });
8982    }
8983
8984    #[test]
8985    fn parse_function_type() {
8986        assert_parse!(FunctionType {
8987            with subs [
8988                Substitutable::Type(
8989                    Type::PointerTo(
8990                        TypeHandle::Builtin(BuiltinType::Standard(StandardBuiltinType::Char)))),
8991            ] => {
8992                Ok => {
8993                    b"KDxFYS_RE..." => {
8994                        FunctionType {
8995                            cv_qualifiers: CvQualifiers {
8996                                restrict: false,
8997                                volatile: false,
8998                                const_: true,
8999                            },
9000                            exception_spec: None,
9001                            transaction_safe: true,
9002                            extern_c: true,
9003                            bare: BareFunctionType(vec![TypeHandle::BackReference(0)]),
9004                            ref_qualifier: Some(RefQualifier::LValueRef),
9005                        },
9006                        b"...",
9007                        []
9008                    }
9009                    b"DxFYS_RE..." => {
9010                        FunctionType {
9011                            cv_qualifiers: CvQualifiers {
9012                                restrict: false,
9013                                volatile: false,
9014                                const_: false,
9015                            },
9016                            exception_spec: None,
9017                            transaction_safe: true,
9018                            extern_c: true,
9019                            bare: BareFunctionType(vec![TypeHandle::BackReference(0)]),
9020                            ref_qualifier: Some(RefQualifier::LValueRef),
9021                        },
9022                        b"...",
9023                        []
9024                    }
9025                    b"FYS_RE..." => {
9026                        FunctionType {
9027                            cv_qualifiers: CvQualifiers {
9028                                restrict: false,
9029                                volatile: false,
9030                                const_: false,
9031                            },
9032                            exception_spec: None,
9033                            transaction_safe: false,
9034                            extern_c: true,
9035                            bare: BareFunctionType(vec![TypeHandle::BackReference(0)]),
9036                            ref_qualifier: Some(RefQualifier::LValueRef),
9037                        },
9038                        b"...",
9039                        []
9040                    }
9041                    b"FS_RE..." => {
9042                        FunctionType {
9043                            cv_qualifiers: CvQualifiers {
9044                                restrict: false,
9045                                volatile: false,
9046                                const_: false,
9047                            },
9048                            exception_spec: None,
9049                            transaction_safe: false,
9050                            extern_c: false,
9051                            bare: BareFunctionType(vec![TypeHandle::BackReference(0)]),
9052                            ref_qualifier: Some(RefQualifier::LValueRef),
9053                        },
9054                        b"...",
9055                        []
9056                    }
9057                    b"FS_E..." => {
9058                        FunctionType {
9059                            cv_qualifiers: CvQualifiers {
9060                                restrict: false,
9061                                volatile: false,
9062                                const_: false,
9063                            },
9064                            exception_spec: None,
9065                            transaction_safe: false,
9066                            extern_c: false,
9067                            bare: BareFunctionType(vec![TypeHandle::BackReference(0)]),
9068                            ref_qualifier: None,
9069                        },
9070                        b"...",
9071                        []
9072                    }
9073                }
9074                Err => {
9075                    b"DFYS_E" => Error::UnexpectedText,
9076                    b"KKFS_E" => Error::UnexpectedText,
9077                    b"FYS_..." => Error::UnexpectedText,
9078                    b"FYS_" => Error::UnexpectedEnd,
9079                    b"F" => Error::UnexpectedEnd,
9080                    b"" => Error::UnexpectedEnd,
9081                }
9082            }
9083        });
9084    }
9085
9086    #[test]
9087    fn parse_bare_function_type() {
9088        assert_parse!(BareFunctionType {
9089            with subs [
9090                Substitutable::Type(
9091                    Type::PointerTo(
9092                        TypeHandle::Builtin(BuiltinType::Standard(StandardBuiltinType::Char)))),
9093            ] => {
9094                Ok => {
9095                    b"S_S_..." => {
9096                        BareFunctionType(vec![
9097                            TypeHandle::BackReference(0),
9098                            TypeHandle::BackReference(0),
9099                        ]),
9100                        b"...",
9101                        []
9102                    }
9103                }
9104                Err => {
9105                    b"" => Error::UnexpectedEnd,
9106                }
9107            }
9108        });
9109    }
9110
9111    #[test]
9112    fn parse_decltype() {
9113        assert_parse!(Decltype {
9114            Ok => {
9115                b"DTtrE..." => {
9116                    Decltype::Expression(Expression::Rethrow),
9117                    b"..."
9118                }
9119                b"DttrE..." => {
9120                    Decltype::IdExpression(Expression::Rethrow),
9121                    b"..."
9122                }
9123            }
9124            Err => {
9125                b"Dtrtz" => Error::UnexpectedText,
9126                b"DTrtz" => Error::UnexpectedText,
9127                b"Dz" => Error::UnexpectedText,
9128                b"Dtrt" => Error::UnexpectedText,
9129                b"DTrt" => Error::UnexpectedText,
9130                b"Dt" => Error::UnexpectedEnd,
9131                b"DT" => Error::UnexpectedEnd,
9132                b"D" => Error::UnexpectedEnd,
9133                b"" => Error::UnexpectedEnd,
9134            }
9135        });
9136    }
9137
9138    #[test]
9139    fn parse_class_enum_type() {
9140        assert_parse!(ClassEnumType {
9141            Ok => {
9142                b"3abc..." => {
9143                    ClassEnumType::Named(
9144                        Name::Unscoped(
9145                            UnscopedName::Unqualified(
9146                                UnqualifiedName::Source(
9147                                    SourceName(Identifier {
9148                                        start: 1,
9149                                        end: 4,
9150                                    }))))),
9151                    b"..."
9152                }
9153                b"Ts3abc..." => {
9154                    ClassEnumType::ElaboratedStruct(
9155                        Name::Unscoped(
9156                            UnscopedName::Unqualified(
9157                                UnqualifiedName::Source(
9158                                    SourceName(Identifier {
9159                                        start: 3,
9160                                        end: 6,
9161                                    }))))),
9162                    b"..."
9163                }
9164                b"Tu3abc..." => {
9165                    ClassEnumType::ElaboratedUnion(
9166                        Name::Unscoped(
9167                            UnscopedName::Unqualified(
9168                                UnqualifiedName::Source(
9169                                    SourceName(Identifier {
9170                                        start: 3,
9171                                        end: 6,
9172                                    }))))),
9173                    b"..."
9174                }
9175                b"Te3abc..." => {
9176                    ClassEnumType::ElaboratedEnum(
9177                        Name::Unscoped(
9178                            UnscopedName::Unqualified(
9179                                UnqualifiedName::Source(
9180                                    SourceName(Identifier {
9181                                        start: 3,
9182                                        end: 6,
9183                                    }))))),
9184                    b"..."
9185                }
9186            }
9187            Err => {
9188                b"zzz" => Error::UnexpectedText,
9189                b"Tzzz" => Error::UnexpectedText,
9190                b"T" => Error::UnexpectedEnd,
9191                b"" => Error::UnexpectedEnd,
9192            }
9193        });
9194    }
9195
9196    #[test]
9197    fn parse_array_type() {
9198        assert_parse!(ArrayType {
9199            with subs [
9200                Substitutable::Type(Type::Decltype(Decltype::Expression(Expression::Rethrow)))
9201            ] => {
9202                Ok => {
9203                    b"A10_S_..." => {
9204                        ArrayType::DimensionNumber(10, TypeHandle::BackReference(0)),
9205                        b"...",
9206                        []
9207                    }
9208                    b"A10_Sb..." => {
9209                        ArrayType::DimensionNumber(10,
9210                                                   TypeHandle::WellKnown(
9211                                                       WellKnownComponent::StdString1)),
9212                        b"...",
9213                        []
9214                    }
9215                    b"Atr_S_..." => {
9216                        ArrayType::DimensionExpression(Expression::Rethrow,
9217                                                       TypeHandle::BackReference(0)),
9218                        b"...",
9219                        []
9220                    }
9221                    b"A_S_..." => {
9222                        ArrayType::NoDimension(TypeHandle::BackReference(0)),
9223                        b"...",
9224                        []
9225                    }
9226                }
9227                Err => {
9228                    b"A10_" => Error::UnexpectedEnd,
9229                    b"A10" => Error::UnexpectedEnd,
9230                    b"A" => Error::UnexpectedEnd,
9231                    b"" => Error::UnexpectedEnd,
9232                    b"A10_..." => Error::UnexpectedText,
9233                    b"A10..." => Error::UnexpectedText,
9234                    b"A..." => Error::UnexpectedText,
9235                    b"..." => Error::UnexpectedText,
9236                }
9237            }
9238        });
9239    }
9240
9241    #[test]
9242    fn parse_vector_type() {
9243        assert_parse!(VectorType {
9244            with subs [
9245                Substitutable::Type(Type::Decltype(Decltype::Expression(Expression::Rethrow)))
9246            ] => {
9247                Ok => {
9248                    b"Dv10_S_..." => {
9249                        VectorType::DimensionNumber(10, TypeHandle::BackReference(0)),
9250                        b"...",
9251                        []
9252                    }
9253                    b"Dv10_Sb..." => {
9254                        VectorType::DimensionNumber(10,
9255                                                    TypeHandle::WellKnown(
9256                                                        WellKnownComponent::StdString1)),
9257                        b"...",
9258                        []
9259                    }
9260                    b"Dvtr_S_..." => {
9261                        VectorType::DimensionExpression(Expression::Rethrow,
9262                                                        TypeHandle::BackReference(0)),
9263                        b"...",
9264                        []
9265                    }
9266                }
9267                Err => {
9268                    b"Dq" => Error::UnexpectedText,
9269                    b"Dv" => Error::UnexpectedEnd,
9270                    b"Dv42_" => Error::UnexpectedEnd,
9271                    b"Dv42_..." => Error::UnexpectedText,
9272                    b"Dvtr_" => Error::UnexpectedEnd,
9273                    b"Dvtr_..." => Error::UnexpectedText,
9274                    b"" => Error::UnexpectedEnd,
9275                    b"..." => Error::UnexpectedText,
9276                }
9277            }
9278        });
9279    }
9280
9281    #[test]
9282    fn parse_pointer_to_member_type() {
9283        assert_parse!(PointerToMemberType {
9284            with subs [
9285                Substitutable::Type(Type::Decltype(Decltype::Expression(Expression::Rethrow)))
9286            ] => {
9287                Ok => {
9288                    b"MS_S_..." => {
9289                        PointerToMemberType(TypeHandle::BackReference(0),
9290                                            TypeHandle::BackReference(0)),
9291                        b"...",
9292                        []
9293                    }
9294                }
9295                Err => {
9296                    b"MS_S" => Error::UnexpectedEnd,
9297                    b"MS_" => Error::UnexpectedEnd,
9298                    b"MS" => Error::UnexpectedEnd,
9299                    b"M" => Error::UnexpectedEnd,
9300                    b"" => Error::UnexpectedEnd,
9301                    b"MS_..." => Error::UnexpectedText,
9302                    b"M..." => Error::UnexpectedText,
9303                    b"..." => Error::UnexpectedText,
9304                }
9305            }
9306        });
9307    }
9308
9309    #[test]
9310    fn parse_template_template_param_handle() {
9311        assert_parse!(TemplateTemplateParamHandle {
9312            with subs [
9313                Substitutable::TemplateTemplateParam(TemplateTemplateParam(TemplateParam(0)))
9314            ] => {
9315                Ok => {
9316                    b"S_..." => {
9317                        TemplateTemplateParamHandle::BackReference(0),
9318                        b"...",
9319                        []
9320                    }
9321                    b"T1_..." => {
9322                        TemplateTemplateParamHandle::BackReference(1),
9323                        b"...",
9324                        [
9325                            Substitutable::TemplateTemplateParam(TemplateTemplateParam(TemplateParam(2)))
9326                        ]
9327                    }
9328                }
9329                Err => {
9330                    b"S" => Error::UnexpectedText,
9331                    b"T" => Error::UnexpectedEnd,
9332                    b"" => Error::UnexpectedEnd,
9333                    b"S..." => Error::UnexpectedText,
9334                    b"T..." => Error::UnexpectedText,
9335                    b"..." => Error::UnexpectedText,
9336                }
9337            }
9338        });
9339    }
9340
9341    #[test]
9342    fn parse_template_args() {
9343        assert_parse!(TemplateArgs {
9344            with subs [
9345                Substitutable::Type(Type::Decltype(Decltype::Expression(Expression::Rethrow)))
9346            ] => {
9347                Ok => {
9348                    b"IS_E..." => {
9349                        TemplateArgs(vec![TemplateArg::Type(TypeHandle::BackReference(0))]),
9350                        b"...",
9351                        []
9352                    }
9353                    b"IS_S_S_S_E..." => {
9354                        TemplateArgs(vec![
9355                            TemplateArg::Type(TypeHandle::BackReference(0)),
9356                            TemplateArg::Type(TypeHandle::BackReference(0)),
9357                            TemplateArg::Type(TypeHandle::BackReference(0)),
9358                            TemplateArg::Type(TypeHandle::BackReference(0)),
9359                        ]),
9360                        b"...",
9361                        []
9362                    }
9363                }
9364                Err => {
9365                    b"zzz" => Error::UnexpectedText,
9366                    b"IE" => Error::UnexpectedText,
9367                    b"IS_" => Error::UnexpectedEnd,
9368                    b"I" => Error::UnexpectedEnd,
9369                    b"" => Error::UnexpectedEnd,
9370                }
9371            }
9372        });
9373    }
9374
9375    #[test]
9376    fn parse_template_arg() {
9377        assert_parse!(TemplateArg {
9378            with subs [
9379                Substitutable::Type(Type::Decltype(Decltype::Expression(Expression::Rethrow)))
9380            ] => {
9381                Ok => {
9382                    b"S_..." => {
9383                        TemplateArg::Type(TypeHandle::BackReference(0)),
9384                        b"...",
9385                        []
9386                    }
9387                    b"XtrE..." => {
9388                        TemplateArg::Expression(Expression::Rethrow),
9389                        b"...",
9390                        []
9391                    }
9392                    b"XsrS_1QE..." => {
9393                        TemplateArg::Expression(
9394                            Expression::UnresolvedName(
9395                                UnresolvedName::Nested1(
9396                                    UnresolvedTypeHandle::BackReference(0),
9397                                    vec![],
9398                                    BaseUnresolvedName::Name(
9399                                        SimpleId(
9400                                            SourceName(Identifier {
9401                                                start: 6,
9402                                                end: 7
9403                                            }),
9404                                            None
9405                                        )
9406                                    )
9407                                )
9408                            )
9409                        ),
9410                        b"...",
9411                        []
9412                    }
9413                    b"XsrS_1QIlEE..." => {
9414                        TemplateArg::Expression(
9415                            Expression::UnresolvedName(
9416                                UnresolvedName::Nested1(
9417                                    UnresolvedTypeHandle::BackReference(0),
9418                                    vec![],
9419                                    BaseUnresolvedName::Name(
9420                                        SimpleId(
9421                                            SourceName(Identifier {
9422                                                start: 6,
9423                                                end: 7
9424                                            }),
9425                                            Some(
9426                                                TemplateArgs(
9427                                                    vec![
9428                                                        TemplateArg::Type(
9429                                                            TypeHandle::Builtin(
9430                                                                BuiltinType::Standard(
9431                                                                    StandardBuiltinType::Long
9432                                                                )
9433                                                            )
9434                                                        )
9435                                                    ]
9436                                                )
9437                                            )
9438                                        )
9439                                    )
9440                                )
9441                            )
9442                        ),
9443                        b"...",
9444                        []
9445                    }
9446                    b"LS_E..." => {
9447                        TemplateArg::SimpleExpression(
9448                            ExprPrimary::Literal(TypeHandle::BackReference(0), 3, 3)),
9449                        b"...",
9450                        []
9451                    }
9452                    b"JE..." => {
9453                        TemplateArg::ArgPack(vec![]),
9454                        b"...",
9455                        []
9456                    }
9457                    b"JS_XtrELS_EJEE..." => {
9458                        TemplateArg::ArgPack(vec![
9459                            TemplateArg::Type(TypeHandle::BackReference(0)),
9460                            TemplateArg::Expression(Expression::Rethrow),
9461                            TemplateArg::SimpleExpression(
9462                                ExprPrimary::Literal(TypeHandle::BackReference(0), 10, 10)),
9463                            TemplateArg::ArgPack(vec![]),
9464                        ]),
9465                        b"...",
9466                        []
9467                    }
9468                }
9469                Err => {
9470                    b"..." => Error::UnexpectedText,
9471                    b"X..." => Error::UnexpectedText,
9472                    b"J..." => Error::UnexpectedText,
9473                    b"JS_..." => Error::UnexpectedText,
9474                    b"JS_" => Error::UnexpectedEnd,
9475                    b"X" => Error::UnexpectedEnd,
9476                    b"J" => Error::UnexpectedEnd,
9477                    b"" => Error::UnexpectedEnd,
9478                }
9479            }
9480        });
9481    }
9482
9483    #[test]
9484    fn parse_expression() {
9485        assert_parse!(Expression {
9486            with subs [
9487                Substitutable::Type(
9488                    Type::PointerTo(TypeHandle::Builtin(
9489                        BuiltinType::Standard(StandardBuiltinType::Int)))),
9490            ] => {
9491                Ok => {
9492                    b"psLS_1E..." => {
9493                        Expression::Unary(OperatorName::Simple(SimpleOperatorName::UnaryPlus),
9494                                          Box::new(Expression::Primary(
9495                                              ExprPrimary::Literal(
9496                                                  TypeHandle::BackReference(0),
9497                                                  5,
9498                                                  6)))),
9499                        b"...",
9500                        []
9501                    }
9502                    b"rsLS_1ELS_1E..." => {
9503                        Expression::Binary(OperatorName::Simple(SimpleOperatorName::Shr),
9504                                           Box::new(Expression::Primary(
9505                                               ExprPrimary::Literal(
9506                                                   TypeHandle::BackReference(0),
9507                                                   5,
9508                                                   6))),
9509                                           Box::new(Expression::Primary(
9510                                               ExprPrimary::Literal(
9511                                                   TypeHandle::BackReference(0),
9512                                                   10,
9513                                                   11)))),
9514                        b"...",
9515                        []
9516                    }
9517                    b"quLS_1ELS_2ELS_3E..." => {
9518                        Expression::Ternary(OperatorName::Simple(SimpleOperatorName::Question),
9519                                            Box::new(Expression::Primary(
9520                                                ExprPrimary::Literal(
9521                                                    TypeHandle::BackReference(0),
9522                                                    5,
9523                                                    6))),
9524                                            Box::new(Expression::Primary(
9525                                                ExprPrimary::Literal(
9526                                                    TypeHandle::BackReference(0),
9527                                                    10,
9528                                                    11))),
9529                                            Box::new(Expression::Primary(
9530                                                ExprPrimary::Literal(
9531                                                    TypeHandle::BackReference(0),
9532                                                    15,
9533                                                    16)))),
9534                        b"...",
9535                        []
9536                    }
9537                    b"pp_LS_1E..." => {
9538                        Expression::PrefixInc(
9539                            Box::new(Expression::Primary(
9540                                ExprPrimary::Literal(
9541                                    TypeHandle::BackReference(0),
9542                                    6,
9543                                    7)))),
9544                        b"...",
9545                        []
9546                    }
9547                    b"mm_LS_1E..." => {
9548                        Expression::PrefixDec(
9549                            Box::new(Expression::Primary(
9550                                ExprPrimary::Literal(
9551                                    TypeHandle::BackReference(0),
9552                                    6,
9553                                    7)))),
9554                        b"...",
9555                        []
9556                    }
9557                    b"clLS_1EE..." => {
9558                        Expression::Call(
9559                            Box::new(Expression::Primary(
9560                                ExprPrimary::Literal(
9561                                    TypeHandle::BackReference(0),
9562                                    5,
9563                                    6))),
9564                            vec![]),
9565                        b"...",
9566                        []
9567                    }
9568                    //               ::= cv <type> <expression>                       # type (expression), conversion with one argument
9569                    b"cvS_LS_1E..." => {
9570                        Expression::ConversionOne(
9571                            TypeHandle::BackReference(0),
9572                            Box::new(Expression::Primary(
9573                                ExprPrimary::Literal(
9574                                    TypeHandle::BackReference(0),
9575                                    7,
9576                                    8)))),
9577                        b"...",
9578                        []
9579                    }
9580                    b"cvS__LS_1ELS_1EE..." => {
9581                        Expression::ConversionMany(
9582                            TypeHandle::BackReference(0),
9583                            vec![
9584                                Expression::Primary(
9585                                    ExprPrimary::Literal(
9586                                        TypeHandle::BackReference(0),
9587                                        8,
9588                                        9)),
9589                                Expression::Primary(
9590                                    ExprPrimary::Literal(
9591                                        TypeHandle::BackReference(0),
9592                                        13,
9593                                        14)),
9594                            ]),
9595                        b"...",
9596                        []
9597                    }
9598                    b"tlS_LS_1ELS_1EE..." => {
9599                        Expression::ConversionBraced(
9600                            TypeHandle::BackReference(0),
9601                            vec![
9602                                Expression::Primary(
9603                                    ExprPrimary::Literal(
9604                                        TypeHandle::BackReference(0),
9605                                        7,
9606                                        8)),
9607                                Expression::Primary(
9608                                    ExprPrimary::Literal(
9609                                        TypeHandle::BackReference(0),
9610                                        12,
9611                                        13)),
9612                            ]),
9613                        b"...",
9614                        []
9615                    }
9616                    b"ilLS_1EE..." => {
9617                        Expression::BracedInitList(
9618                            Box::new(Expression::Primary(
9619                                ExprPrimary::Literal(
9620                                    TypeHandle::BackReference(0),
9621                                    5,
9622                                    6)))),
9623                        b"...",
9624                        []
9625                    }
9626                    b"gsnwLS_1E_S_E..." => {
9627                        Expression::GlobalNew(
9628                            vec![
9629                                Expression::Primary(
9630                                    ExprPrimary::Literal(
9631                                        TypeHandle::BackReference(0),
9632                                        7,
9633                                        8))
9634                            ],
9635                            TypeHandle::BackReference(0),
9636                            None),
9637                        b"...",
9638                        []
9639                    }
9640                    b"nwLS_1E_S_E..." => {
9641                        Expression::New(
9642                            vec![
9643                                Expression::Primary(
9644                                    ExprPrimary::Literal(
9645                                        TypeHandle::BackReference(0),
9646                                        5,
9647                                        6))
9648                            ],
9649                            TypeHandle::BackReference(0),
9650                            None),
9651                        b"...",
9652                        []
9653                    }
9654                    b"gsnwLS_1E_S_piE..." => {
9655                        Expression::GlobalNew(
9656                            vec![
9657                                Expression::Primary(
9658                                    ExprPrimary::Literal(
9659                                        TypeHandle::BackReference(0),
9660                                        7,
9661                                        8))
9662                            ],
9663                            TypeHandle::BackReference(0),
9664                            Some(Initializer(vec![]))),
9665                        b"...",
9666                        []
9667                    }
9668                    b"nwLS_1E_S_piE..." => {
9669                        Expression::New(
9670                            vec![
9671                                Expression::Primary(
9672                                    ExprPrimary::Literal(
9673                                        TypeHandle::BackReference(0),
9674                                        5,
9675                                        6))
9676                            ],
9677                            TypeHandle::BackReference(0),
9678                            Some(Initializer(vec![]))),
9679                        b"...",
9680                        []
9681                    }
9682                    b"gsnaLS_1E_S_E..." => {
9683                        Expression::GlobalNewArray(
9684                            vec![
9685                                Expression::Primary(
9686                                    ExprPrimary::Literal(
9687                                        TypeHandle::BackReference(0),
9688                                        7,
9689                                        8))
9690                            ],
9691                            TypeHandle::BackReference(0),
9692                            None),
9693                        b"...",
9694                        []
9695                    }
9696                    b"naLS_1E_S_E..." => {
9697                        Expression::NewArray(
9698                            vec![
9699                                Expression::Primary(
9700                                    ExprPrimary::Literal(
9701                                        TypeHandle::BackReference(0),
9702                                        5,
9703                                        6))
9704                            ],
9705                            TypeHandle::BackReference(0),
9706                            None),
9707                        b"...",
9708                        []
9709                    }
9710                    b"gsnaLS_1E_S_piE..." => {
9711                        Expression::GlobalNewArray(
9712                            vec![
9713                                Expression::Primary(
9714                                    ExprPrimary::Literal(
9715                                        TypeHandle::BackReference(0),
9716                                        7,
9717                                        8))
9718                            ],
9719                            TypeHandle::BackReference(0),
9720                            Some(Initializer(vec![]))),
9721                        b"...",
9722                        []
9723                    }
9724                    b"naLS_1E_S_piE..." => {
9725                        Expression::NewArray(
9726                            vec![
9727                                Expression::Primary(
9728                                    ExprPrimary::Literal(
9729                                        TypeHandle::BackReference(0),
9730                                        5,
9731                                        6))
9732                            ],
9733                            TypeHandle::BackReference(0),
9734                            Some(Initializer(vec![]))),
9735                        b"...",
9736                        []
9737                    }
9738                    b"gsdlLS_1E..." => {
9739                        Expression::GlobalDelete(
9740                            Box::new(Expression::Primary(
9741                                ExprPrimary::Literal(
9742                                    TypeHandle::BackReference(0),
9743                                    7,
9744                                    8)))),
9745                        b"...",
9746                        []
9747                    }
9748                    b"dlLS_1E..." => {
9749                        Expression::Delete(
9750                            Box::new(Expression::Primary(
9751                                ExprPrimary::Literal(
9752                                    TypeHandle::BackReference(0),
9753                                    5,
9754                                    6)))),
9755                        b"...",
9756                        []
9757                    }
9758                    //               ::= [gs] da <expression>                         # delete[] expression
9759                    b"gsdaLS_1E..." => {
9760                        Expression::GlobalDeleteArray(
9761                            Box::new(Expression::Primary(
9762                                ExprPrimary::Literal(
9763                                    TypeHandle::BackReference(0),
9764                                    7,
9765                                    8)))),
9766                        b"...",
9767                        []
9768                    }
9769                    b"daLS_1E..." => {
9770                        Expression::DeleteArray(
9771                            Box::new(Expression::Primary(
9772                                ExprPrimary::Literal(
9773                                    TypeHandle::BackReference(0),
9774                                    5,
9775                                    6)))),
9776                        b"...",
9777                        []
9778                    }
9779                    b"dcS_LS_1E..." => {
9780                        Expression::DynamicCast(
9781                            TypeHandle::BackReference(0),
9782                            Box::new(Expression::Primary(
9783                                ExprPrimary::Literal(
9784                                    TypeHandle::BackReference(0),
9785                                    7,
9786                                    8)))),
9787                        b"...",
9788                        []
9789                    }
9790                    b"scS_LS_1E..." => {
9791                        Expression::StaticCast(
9792                            TypeHandle::BackReference(0),
9793                            Box::new(Expression::Primary(
9794                                ExprPrimary::Literal(
9795                                    TypeHandle::BackReference(0),
9796                                    7,
9797                                    8)))),
9798                        b"...",
9799                        []
9800                    }
9801                    b"ccS_LS_1E..." => {
9802                        Expression::ConstCast(
9803                            TypeHandle::BackReference(0),
9804                            Box::new(Expression::Primary(
9805                                ExprPrimary::Literal(
9806                                    TypeHandle::BackReference(0),
9807                                    7,
9808                                    8)))),
9809                        b"...",
9810                        []
9811                    }
9812                    b"rcS_LS_1E..." => {
9813                        Expression::ReinterpretCast(
9814                            TypeHandle::BackReference(0),
9815                            Box::new(Expression::Primary(
9816                                ExprPrimary::Literal(
9817                                    TypeHandle::BackReference(0),
9818                                    7,
9819                                    8)))),
9820                        b"...",
9821                        []
9822                    }
9823                    b"tiS_..." => {
9824                        Expression::TypeidType(TypeHandle::BackReference(0)),
9825                        b"...",
9826                        []
9827                    }
9828                    b"teLS_1E..." => {
9829                        Expression::TypeidExpr(
9830                            Box::new(Expression::Primary(
9831                                ExprPrimary::Literal(
9832                                    TypeHandle::BackReference(0),
9833                                    5,
9834                                    6)))),
9835                        b"...",
9836                        []
9837                    }
9838                    b"stS_..." => {
9839                        Expression::SizeofType(TypeHandle::BackReference(0)),
9840                        b"...",
9841                        []
9842                    }
9843                    b"szLS_1E..." => {
9844                        Expression::SizeofExpr(
9845                            Box::new(Expression::Primary(
9846                                ExprPrimary::Literal(
9847                                    TypeHandle::BackReference(0),
9848                                    5,
9849                                    6)))),
9850                        b"...",
9851                        []
9852                    }
9853                    b"atS_..." => {
9854                        Expression::AlignofType(TypeHandle::BackReference(0)),
9855                        b"...",
9856                        []
9857                    }
9858                    b"azLS_1E..." => {
9859                        Expression::AlignofExpr(
9860                            Box::new(Expression::Primary(
9861                                ExprPrimary::Literal(
9862                                    TypeHandle::BackReference(0),
9863                                    5,
9864                                    6)))),
9865                        b"...",
9866                        []
9867                    }
9868                    b"nxLS_1E..." => {
9869                        Expression::Noexcept(
9870                            Box::new(Expression::Primary(
9871                                ExprPrimary::Literal(
9872                                    TypeHandle::BackReference(0),
9873                                    5,
9874                                    6)))),
9875                        b"...",
9876                        []
9877                    }
9878                    b"T_..." => {
9879                        Expression::TemplateParam(TemplateParam(0)),
9880                        b"...",
9881                        []
9882                    }
9883                    b"fp_..." => {
9884                        Expression::FunctionParam(FunctionParam(0, CvQualifiers::default(), Some(0))),
9885                        b"...",
9886                        []
9887                    }
9888                    b"dtT_3abc..." => {
9889                        Expression::Member(
9890                            Box::new(Expression::TemplateParam(TemplateParam(0))),
9891                            MemberName(
9892                                Name::Unscoped(
9893                                    UnscopedName::Unqualified(
9894                                        UnqualifiedName::Source(
9895                                            SourceName(
9896                                                Identifier {
9897                                                    start: 5,
9898                                                    end: 8,
9899                                                })))))),
9900                        b"...",
9901                        []
9902                    }
9903                    b"ptT_3abc..." => {
9904                        Expression::DerefMember(
9905                            Box::new(Expression::TemplateParam(TemplateParam(0))),
9906                            MemberName(
9907                                Name::Unscoped(
9908                                    UnscopedName::Unqualified(
9909                                        UnqualifiedName::Source(
9910                                            SourceName(
9911                                                Identifier {
9912                                                    start: 5,
9913                                                    end: 8,
9914                                                })))))),
9915                        b"...",
9916                        []
9917                    }
9918                    b"dtfp_clI3abcE..." => {
9919                        Expression::Member(
9920                            Box::new(Expression::FunctionParam(FunctionParam(0, CvQualifiers::default(), Some(0)))),
9921                            MemberName(
9922                                Name::UnscopedTemplate(
9923                                    UnscopedTemplateNameHandle::NonSubstitution(NonSubstitution(0)),
9924                                    TemplateArgs(vec![
9925                                        TemplateArg::Type(
9926                                            TypeHandle::BackReference(1))])))),
9927                        b"...",
9928                        [
9929                            Substitutable::Type(
9930                                Type::ClassEnum(
9931                                    ClassEnumType::Named(
9932                                        Name::Unscoped(
9933                                            UnscopedName::Unqualified(
9934                                                UnqualifiedName::Source(
9935                                                    SourceName(
9936                                                        Identifier {
9937                                                            start: 9,
9938                                                            end: 12
9939                                                        })))))))
9940                        ]
9941                    }
9942                    //               ::= ds <expression> <expression>                 # expr.*expr
9943                    b"dsT_T_..." => {
9944                        Expression::PointerToMember(
9945                            Box::new(Expression::TemplateParam(TemplateParam(0))),
9946                            Box::new(Expression::TemplateParam(TemplateParam(0)))),
9947                        b"...",
9948                        []
9949                    }
9950                    b"sZT_..." => {
9951                        Expression::SizeofTemplatePack(TemplateParam(0)),
9952                        b"...",
9953                        []
9954                    }
9955                    b"sZfp_..." => {
9956                        Expression::SizeofFunctionPack(
9957                            FunctionParam(0, CvQualifiers::default(), Some(0))),
9958                        b"...",
9959                        []
9960                    }
9961                    b"sPE..." => {
9962                        Expression::SizeofCapturedTemplatePack(vec![]),
9963                        b"...",
9964                        []
9965                    }
9966                    b"spT_..." => {
9967                        Expression::PackExpansion(
9968                            Box::new(Expression::TemplateParam(TemplateParam(0)))),
9969                        b"...",
9970                        []
9971                    }
9972                    b"twT_..." => {
9973                        Expression::Throw(Box::new(Expression::TemplateParam(TemplateParam(0)))),
9974                        b"...",
9975                        []
9976                    }
9977                    b"tr..." => {
9978                        Expression::Rethrow,
9979                        b"...",
9980                        []
9981                    }
9982                    b"3abc..." => {
9983                        Expression::UnresolvedName(
9984                            UnresolvedName::Name(
9985                                BaseUnresolvedName::Name(
9986                                    SimpleId(
9987                                        SourceName(Identifier {
9988                                            start: 1,
9989                                            end: 4,
9990                                        }),
9991                                        None)))),
9992                        b"...",
9993                        []
9994                    }
9995                    b"L_Z3abcE..." => {
9996                        Expression::Primary(
9997                            ExprPrimary::External(
9998                                MangledName::Encoding(
9999                                    Encoding::Data(
10000                                        Name::Unscoped(
10001                                            UnscopedName::Unqualified(
10002                                                UnqualifiedName::Source(
10003                                                    SourceName(Identifier {
10004                                                        start: 4,
10005                                                        end: 7,
10006                                                    }))))), vec![]))),
10007                        b"...",
10008                        []
10009                    }
10010                    // An expression where arity matters
10011                    b"cldtdefpT4TypeadsrT_5EnterE..." => {
10012                        Expression::Call(
10013                            Box::new(Expression::Member(
10014                                Box::new(Expression::Unary(OperatorName::Simple(SimpleOperatorName::Deref),
10015                                                           Box::new(Expression::FunctionParam(
10016                                                               FunctionParam(0,
10017                                                                             CvQualifiers::default(),
10018                                                                             None)
10019                                                           ))
10020                                )),
10021                                MemberName(
10022                                    Name::Unscoped(
10023                                        UnscopedName::Unqualified(
10024                                            UnqualifiedName::Source(
10025                                                SourceName(Identifier {
10026                                                    start: 10,
10027                                                    end: 14,
10028                                                })))
10029                                     )
10030                                )
10031                            )),
10032                            vec![Expression::Unary(OperatorName::Simple(SimpleOperatorName::AddressOf),
10033                                                   Box::new(Expression::UnresolvedName(
10034                                                       UnresolvedName::Nested1(
10035                                                           UnresolvedTypeHandle::BackReference(1),
10036                                                           vec![],
10037                                                           BaseUnresolvedName::Name(
10038                                                               SimpleId(
10039                                                                   SourceName(Identifier {
10040                                                                           start: 21,
10041                                                                           end: 26
10042                                                                   }
10043                                                                   ),
10044                                                                   None
10045                                                               )
10046                                                           )
10047                                                       ))))]
10048                        ),
10049                        b"...",
10050                        [
10051                            Substitutable::UnresolvedType(UnresolvedType::Template(TemplateParam(0), None))
10052                        ]
10053                    }
10054                }
10055                Err => {
10056                    b"dtStfp_clI3abcE..." => Error::UnexpectedText,
10057                }
10058            }
10059        });
10060    }
10061
10062    #[test]
10063    fn parse_unresolved_name() {
10064        assert_parse!(UnresolvedName {
10065            with subs [
10066                Substitutable::UnresolvedType(
10067                    UnresolvedType::Decltype(Decltype::Expression(Expression::Rethrow))),
10068            ] => {
10069                Ok => {
10070                    b"gs3abc..." => {
10071                        UnresolvedName::Global(BaseUnresolvedName::Name(SimpleId(SourceName(Identifier {
10072                            start: 3,
10073                            end: 6,
10074                        }), None))),
10075                        b"...",
10076                        []
10077                    }
10078                    b"3abc..." => {
10079                        UnresolvedName::Name(BaseUnresolvedName::Name(SimpleId(SourceName(Identifier {
10080                            start: 1,
10081                            end: 4,
10082                        }), None))),
10083                        b"...",
10084                        []
10085                    }
10086                    b"srS_3abc..." => {
10087                        UnresolvedName::Nested1(UnresolvedTypeHandle::BackReference(0),
10088                                                vec![],
10089                                                BaseUnresolvedName::Name(SimpleId(SourceName(Identifier {
10090                                                    start: 5,
10091                                                    end: 8,
10092                                                }), None))),
10093                        b"...",
10094                        []
10095                    }
10096                    b"srNS_3abc3abcE3abc..." => {
10097                        UnresolvedName::Nested1(
10098                            UnresolvedTypeHandle::BackReference(0),
10099                            vec![
10100                                UnresolvedQualifierLevel(SimpleId(SourceName(Identifier {
10101                                    start: 6,
10102                                    end: 9,
10103                                }), None)),
10104                                UnresolvedQualifierLevel(SimpleId(SourceName(Identifier {
10105                                    start: 10,
10106                                    end: 13,
10107                                }), None)),
10108                            ],
10109                            BaseUnresolvedName::Name(SimpleId(SourceName(Identifier {
10110                                start: 15,
10111                                end: 18,
10112                            }), None))),
10113                        b"...",
10114                        []
10115                    }
10116                    b"gssr3abcE3abc..." => {
10117                        UnresolvedName::GlobalNested2(
10118                            vec![
10119                                UnresolvedQualifierLevel(SimpleId(SourceName(Identifier {
10120                                    start: 5,
10121                                    end: 8,
10122                                }), None)),
10123                            ],
10124                            BaseUnresolvedName::Name(SimpleId(SourceName(Identifier {
10125                                start: 10,
10126                                end: 13,
10127                            }), None))),
10128                        b"...",
10129                        []
10130                    }
10131                    b"sr3abcE3abc..." => {
10132                        UnresolvedName::Nested2(
10133                            vec![
10134                                UnresolvedQualifierLevel(SimpleId(SourceName(Identifier {
10135                                    start: 3,
10136                                    end: 6,
10137                                }), None)),
10138                            ],
10139                            BaseUnresolvedName::Name(SimpleId(SourceName(Identifier {
10140                                start: 8,
10141                                end: 11,
10142                            }), None))),
10143                        b"...",
10144                        []
10145                    }
10146                }
10147                Err => {
10148                    b"zzzzzz" => Error::UnexpectedText,
10149                    b"gszzz" => Error::UnexpectedText,
10150                    b"gssrzzz" => Error::UnexpectedText,
10151                    b"srNzzz" => Error::UnexpectedText,
10152                    b"srzzz" => Error::UnexpectedText,
10153                    b"srN3abczzzz" => Error::UnexpectedText,
10154                    b"srN3abcE" => Error::UnexpectedText,
10155                    b"srN3abc" => Error::UnexpectedText,
10156                    b"srN" => Error::UnexpectedEnd,
10157                    b"sr" => Error::UnexpectedEnd,
10158                    b"gssr" => Error::UnexpectedEnd,
10159                    b"gs" => Error::UnexpectedEnd,
10160                    b"" => Error::UnexpectedEnd,
10161                }
10162            }
10163        });
10164    }
10165
10166    #[test]
10167    fn parse_unresolved_type_handle() {
10168        assert_parse!(UnresolvedTypeHandle {
10169            with subs [
10170                Substitutable::UnresolvedType(
10171                    UnresolvedType::Decltype(Decltype::Expression(Expression::Rethrow))),
10172            ] => {
10173                Ok => {
10174                    b"S_..." => {
10175                        UnresolvedTypeHandle::BackReference(0),
10176                        b"...",
10177                        []
10178                    }
10179                    b"T_..." => {
10180                        UnresolvedTypeHandle::BackReference(1),
10181                        b"...",
10182                        [
10183                            Substitutable::UnresolvedType(
10184                                UnresolvedType::Template(TemplateParam(0), None)),
10185                        ]
10186                    }
10187                    b"T_IS_E..." => {
10188                        UnresolvedTypeHandle::BackReference(1),
10189                        b"...",
10190                        [
10191                            Substitutable::UnresolvedType(
10192                                UnresolvedType::Template(TemplateParam(0), Some(TemplateArgs(vec![
10193                                    TemplateArg::Type(TypeHandle::BackReference(0))
10194                                ])))),
10195                        ]
10196                    }
10197                    b"DTtrE..." => {
10198                        UnresolvedTypeHandle::BackReference(1),
10199                        b"...",
10200                        [
10201                            Substitutable::UnresolvedType(
10202                                UnresolvedType::Decltype(Decltype::Expression(Expression::Rethrow)))
10203                        ]
10204
10205                    }
10206                }
10207                Err => {
10208                    b"zzzzzzz" => Error::UnexpectedText,
10209                    b"" => Error::UnexpectedEnd,
10210                }
10211            }
10212        });
10213    }
10214
10215    #[test]
10216    fn parse_unresolved_qualifier_level() {
10217        assert_parse!(UnresolvedQualifierLevel {
10218            with subs [
10219                Substitutable::Type(Type::Decltype(Decltype::Expression(Expression::Rethrow)))
10220            ] => {
10221                Ok => {
10222                    b"3abc..." => {
10223                        UnresolvedQualifierLevel(SimpleId(SourceName(Identifier {
10224                            start: 1,
10225                            end: 4,
10226                        }), None)),
10227                        b"...",
10228                        []
10229                    }
10230                    b"3abcIS_E..." => {
10231                        UnresolvedQualifierLevel(SimpleId(SourceName(Identifier {
10232                            start: 1,
10233                            end: 4,
10234                        }), Some(TemplateArgs(vec![
10235                            TemplateArg::Type(TypeHandle::BackReference(0))
10236                        ])))),
10237                        b"...",
10238                        []
10239                    }
10240                }
10241                Err => {
10242                    b"zzz" => Error::UnexpectedText,
10243                    b"" => Error::UnexpectedEnd,
10244                }
10245            }
10246        });
10247    }
10248
10249    #[test]
10250    fn parse_simple_id() {
10251        assert_parse!(SimpleId {
10252            with subs [
10253                Substitutable::Type(Type::Decltype(Decltype::Expression(Expression::Rethrow)))
10254            ] => {
10255                Ok => {
10256                    b"3abc..." => {
10257                        SimpleId(SourceName(Identifier {
10258                            start: 1,
10259                            end: 4,
10260                        }), None),
10261                        b"...",
10262                        []
10263                    }
10264                    b"3abcIS_E..." => {
10265                        SimpleId(SourceName(Identifier {
10266                            start: 1,
10267                            end: 4,
10268                        }), Some(TemplateArgs(vec![
10269                            TemplateArg::Type(TypeHandle::BackReference(0))
10270                        ]))),
10271                        b"...",
10272                        []
10273                    }
10274                }
10275                Err => {
10276                    b"zzz" => Error::UnexpectedText,
10277                    b"" => Error::UnexpectedEnd,
10278                }
10279            }
10280        });
10281    }
10282
10283    #[test]
10284    fn parse_base_unresolved_name() {
10285        assert_parse!(BaseUnresolvedName {
10286            with subs [
10287                Substitutable::Type(Type::Decltype(Decltype::Expression(Expression::Rethrow)))
10288            ] => {
10289                Ok => {
10290                    b"3abc..." => {
10291                        BaseUnresolvedName::Name(SimpleId(SourceName(Identifier {
10292                            start: 1,
10293                            end: 4,
10294                        }), None)),
10295                        b"...",
10296                        []
10297                    }
10298                    b"onnw..." => {
10299                        BaseUnresolvedName::Operator(OperatorName::Simple(SimpleOperatorName::New), None),
10300                        b"...",
10301                        []
10302                    }
10303                    b"onnwIS_E..." => {
10304                        BaseUnresolvedName::Operator(OperatorName::Simple(SimpleOperatorName::New),
10305                                                     Some(TemplateArgs(vec![
10306                                                         TemplateArg::Type(TypeHandle::BackReference(0))
10307                                                     ]))),
10308                        b"...",
10309                        []
10310                    }
10311                    b"dn3abc..." => {
10312                        BaseUnresolvedName::Destructor(DestructorName::Name(SimpleId(SourceName(Identifier {
10313                            start: 3,
10314                            end: 6,
10315                        }), None))),
10316                        b"...",
10317                        []
10318                    }
10319                }
10320                Err => {
10321                    b"ozzz" => Error::UnexpectedText,
10322                    b"dzzz" => Error::UnexpectedText,
10323                    b"dn" => Error::UnexpectedEnd,
10324                    b"on" => Error::UnexpectedEnd,
10325                    b"" => Error::UnexpectedEnd,
10326                }
10327            }
10328        });
10329    }
10330
10331    #[test]
10332    fn parse_destructor_name() {
10333        assert_parse!(DestructorName {
10334            with subs [
10335                Substitutable::UnresolvedType(
10336                    UnresolvedType::Decltype(Decltype::Expression(Expression::Rethrow))),
10337            ] => {
10338                Ok => {
10339                    b"S_..." => {
10340                        DestructorName::Unresolved(UnresolvedTypeHandle::BackReference(0)),
10341                        b"...",
10342                        []
10343                    }
10344                    b"3abc..." => {
10345                        DestructorName::Name(SimpleId(SourceName(Identifier {
10346                            start: 1,
10347                            end: 4,
10348                        }), None)),
10349                        b"...",
10350                        []
10351                    }
10352                }
10353                Err => {
10354                    b"zzz" => Error::UnexpectedText,
10355                    b"" => Error::UnexpectedEnd,
10356                }
10357            }
10358        });
10359    }
10360
10361    #[test]
10362    fn parse_expr_primary() {
10363        assert_parse!(ExprPrimary {
10364            with subs [
10365                Substitutable::Type(Type::Decltype(Decltype::Expression(Expression::Rethrow)))
10366            ] => {
10367                Ok => {
10368                    b"LS_12345E..." => {
10369                        ExprPrimary::Literal(TypeHandle::BackReference(0), 3, 8),
10370                        b"...",
10371                        []
10372                    }
10373                    b"LS_E..." => {
10374                        ExprPrimary::Literal(TypeHandle::BackReference(0), 3, 3),
10375                        b"...",
10376                        []
10377                    }
10378                    b"L_Z3abcE..." => {
10379                        ExprPrimary::External(
10380                            MangledName::Encoding(
10381                                Encoding::Data(
10382                                    Name::Unscoped(
10383                                        UnscopedName::Unqualified(
10384                                            UnqualifiedName::Source(
10385                                                SourceName(Identifier {
10386                                                    start: 4,
10387                                                    end: 7,
10388                                                }))))), vec![])),
10389                        b"...",
10390                        []
10391                    }
10392                }
10393                Err => {
10394                    b"zzz" => Error::UnexpectedText,
10395                    b"LS_zzz" => Error::UnexpectedEnd,
10396                    b"LS_12345" => Error::UnexpectedEnd,
10397                    b"LS_" => Error::UnexpectedEnd,
10398                    b"L" => Error::UnexpectedEnd,
10399                    b"" => Error::UnexpectedEnd,
10400                }
10401            }
10402        });
10403    }
10404
10405    #[test]
10406    fn parse_initializer() {
10407        assert_parse!(Initializer {
10408            Ok => {
10409                b"piE..." => {
10410                    Initializer(vec![]),
10411                    b"..."
10412                }
10413                b"pitrtrtrE..." => {
10414                    Initializer(vec![
10415                        Expression::Rethrow,
10416                        Expression::Rethrow,
10417                        Expression::Rethrow,
10418                    ]),
10419                    b"..."
10420                }
10421            }
10422            Err => {
10423                b"pirtrtrt..." => Error::UnexpectedText,
10424                b"pi..." => Error::UnexpectedText,
10425                b"..." => Error::UnexpectedText,
10426                b"pirt" => Error::UnexpectedText,
10427                b"pi" => Error::UnexpectedEnd,
10428                b"p" => Error::UnexpectedEnd,
10429                b"" => Error::UnexpectedEnd,
10430            }
10431        });
10432    }
10433
10434    #[test]
10435    fn parse_local_name() {
10436        assert_parse!(LocalName {
10437            Ok => {
10438                b"Z3abcE3def_0..." => {
10439                    LocalName::Relative(
10440                        Box::new(Encoding::Data(
10441                            Name::Unscoped(
10442                                UnscopedName::Unqualified(
10443                                    UnqualifiedName::Source(
10444                                        SourceName(Identifier {
10445                                            start: 2,
10446                                            end: 5,
10447                                        })))))),
10448                        Some(Box::new(Name::Unscoped(
10449                            UnscopedName::Unqualified(
10450                                UnqualifiedName::Source(
10451                                    SourceName(Identifier {
10452                                        start: 7,
10453                                        end: 10,
10454                                    })))))),
10455                        Some(Discriminator(0))),
10456                    b"..."
10457                }
10458                b"Z3abcE3def..." => {
10459                    LocalName::Relative(
10460                        Box::new(Encoding::Data(
10461                            Name::Unscoped(
10462                                UnscopedName::Unqualified(
10463                                    UnqualifiedName::Source(
10464                                        SourceName(Identifier {
10465                                            start: 2,
10466                                            end: 5,
10467                                        })))))),
10468                        Some(Box::new(Name::Unscoped(
10469                            UnscopedName::Unqualified(
10470                                UnqualifiedName::Source(
10471                                    SourceName(Identifier {
10472                                        start: 7,
10473                                        end: 10,
10474                                    })))))),
10475                        None),
10476                    b"..."
10477                }
10478                b"Z3abcEs_0..." => {
10479                    LocalName::Relative(
10480                        Box::new(Encoding::Data(
10481                            Name::Unscoped(
10482                                UnscopedName::Unqualified(
10483                                    UnqualifiedName::Source(
10484                                        SourceName(Identifier {
10485                                            start: 2,
10486                                            end: 5,
10487                                        })))))),
10488                        None,
10489                        Some(Discriminator(0))),
10490                    b"..."
10491                }
10492                b"Z3abcEs..." => {
10493                    LocalName::Relative(
10494                        Box::new(Encoding::Data(
10495                            Name::Unscoped(
10496                                UnscopedName::Unqualified(
10497                                    UnqualifiedName::Source(
10498                                        SourceName(Identifier {
10499                                            start: 2,
10500                                            end: 5,
10501                                        })))))),
10502                        None,
10503                        None),
10504                    b"..."
10505                }
10506                b"Z3abcEd1_3abc..." => {
10507                    LocalName::Default(
10508                        Box::new(Encoding::Data(
10509                            Name::Unscoped(
10510                                UnscopedName::Unqualified(
10511                                    UnqualifiedName::Source(
10512                                        SourceName(Identifier {
10513                                            start: 2,
10514                                            end: 5,
10515                                        })))))),
10516                        Some(1),
10517                        Box::new(Name::Unscoped(
10518                            UnscopedName::Unqualified(
10519                                UnqualifiedName::Source(
10520                                    SourceName(Identifier {
10521                                        start: 10,
10522                                        end: 13,
10523                                    })))))),
10524                    b"..."
10525                }
10526                b"Z3abcEd_3abc..." => {
10527                    LocalName::Default(
10528                        Box::new(Encoding::Data(
10529                            Name::Unscoped(
10530                                UnscopedName::Unqualified(
10531                                    UnqualifiedName::Source(
10532                                        SourceName(Identifier {
10533                                            start: 2,
10534                                            end: 5,
10535                                        })))))),
10536                        None,
10537                        Box::new(Name::Unscoped(
10538                            UnscopedName::Unqualified(
10539                                UnqualifiedName::Source(
10540                                    SourceName(Identifier {
10541                                        start: 9,
10542                                        end: 12,
10543                                    })))))),
10544                    b"..."
10545                }
10546            }
10547            Err => {
10548                b"A" => Error::UnexpectedText,
10549                b"Z1a" => Error::UnexpectedEnd,
10550                b"Z1aE" => Error::UnexpectedEnd,
10551                b"Z" => Error::UnexpectedEnd,
10552                b"" => Error::UnexpectedEnd,
10553            }
10554        });
10555    }
10556
10557    #[test]
10558    fn parse_closure_type_name() {
10559        assert_parse!(ClosureTypeName {
10560            Ok => {
10561                b"UlvE_..." => {
10562                    ClosureTypeName(LambdaSig(vec![]), None),
10563                    b"..."
10564                }
10565                b"UlvE36_..." => {
10566                    ClosureTypeName(LambdaSig(vec![]), Some(36)),
10567                    b"..."
10568                }
10569            }
10570            Err => {
10571                b"UlvE36zzz" => Error::UnexpectedText,
10572                b"UlvEzzz" => Error::UnexpectedText,
10573                b"Ulvzzz" => Error::UnexpectedText,
10574                b"zzz" => Error::UnexpectedText,
10575                b"UlvE10" => Error::UnexpectedEnd,
10576                b"UlvE" => Error::UnexpectedEnd,
10577                b"Ulv" => Error::UnexpectedEnd,
10578                b"Ul" => Error::UnexpectedEnd,
10579                b"U" => Error::UnexpectedEnd,
10580                b"" => Error::UnexpectedEnd,
10581            }
10582        });
10583    }
10584
10585    #[test]
10586    fn parse_lambda_sig() {
10587        assert_parse!(LambdaSig {
10588            with subs [
10589                Substitutable::Type(
10590                    Type::PointerTo(
10591                        TypeHandle::Builtin(BuiltinType::Standard(StandardBuiltinType::Bool))))
10592            ] => {
10593                Ok => {
10594                    b"v..." => {
10595                        LambdaSig(vec![]),
10596                        b"...",
10597                        []
10598                    }
10599                    b"S_S_S_..." => {
10600                        LambdaSig(vec![
10601                            TypeHandle::BackReference(0),
10602                            TypeHandle::BackReference(0),
10603                            TypeHandle::BackReference(0),
10604                        ]),
10605                        b"...",
10606                        []
10607                    }
10608                }
10609                Err => {
10610                    b"..." => Error::UnexpectedText,
10611                    b"S" => Error::UnexpectedEnd,
10612                    b"" => Error::UnexpectedEnd,
10613                }
10614            }
10615        });
10616    }
10617
10618    #[test]
10619    fn parse_substitution() {
10620        assert_parse!(Substitution {
10621            with subs [
10622                Substitutable::Type(Type::Decltype(Decltype::Expression(Expression::Rethrow))),
10623                Substitutable::Type(Type::Decltype(Decltype::Expression(Expression::Rethrow))),
10624                Substitutable::Type(Type::Decltype(Decltype::Expression(Expression::Rethrow)))
10625            ] => {
10626                Ok => {
10627                    b"S_..." => {
10628                        Substitution::BackReference(0),
10629                        b"...",
10630                        []
10631                    }
10632                    b"S1_..." => {
10633                        Substitution::BackReference(2),
10634                        b"...",
10635                        []
10636                    }
10637                    b"St..." => {
10638                        Substitution::WellKnown(WellKnownComponent::Std),
10639                        b"...",
10640                        []
10641                    }
10642                    b"Sa..." => {
10643                        Substitution::WellKnown(WellKnownComponent::StdAllocator),
10644                        b"...",
10645                        []
10646                    }
10647                    b"Sb..." => {
10648                        Substitution::WellKnown(WellKnownComponent::StdString1),
10649                        b"...",
10650                        []
10651                    }
10652                    b"Ss..." => {
10653                        Substitution::WellKnown(WellKnownComponent::StdString2),
10654                        b"...",
10655                        []
10656                    }
10657                    b"Si..." => {
10658                        Substitution::WellKnown(WellKnownComponent::StdIstream),
10659                        b"...",
10660                        []
10661                    }
10662                    b"So..." => {
10663                        Substitution::WellKnown(WellKnownComponent::StdOstream),
10664                        b"...",
10665                        []
10666                    }
10667                    b"Sd..." => {
10668                        Substitution::WellKnown(WellKnownComponent::StdIostream),
10669                        b"...",
10670                        []
10671                    }
10672                }
10673                Err => {
10674                    b"S999_" => Error::BadBackReference,
10675                    b"Sz" => Error::UnexpectedText,
10676                    b"zzz" => Error::UnexpectedText,
10677                    b"S1" => Error::UnexpectedEnd,
10678                    b"S" => Error::UnexpectedEnd,
10679                    b"" => Error::UnexpectedEnd,
10680                }
10681            }
10682        });
10683    }
10684
10685    #[test]
10686    fn parse_special_name() {
10687        assert_parse!(SpecialName {
10688            Ok => {
10689                b"TVi..." => {
10690                    SpecialName::VirtualTable(TypeHandle::Builtin(BuiltinType::Standard(StandardBuiltinType::Int))),
10691                    b"..."
10692                }
10693                b"TTi..." => {
10694                    SpecialName::Vtt(TypeHandle::Builtin(BuiltinType::Standard(StandardBuiltinType::Int))),
10695                    b"..."
10696                }
10697                b"TIi..." => {
10698                    SpecialName::Typeinfo(TypeHandle::Builtin(BuiltinType::Standard(StandardBuiltinType::Int))),
10699                    b"..."
10700                }
10701                b"TSi..." => {
10702                    SpecialName::TypeinfoName(TypeHandle::Builtin(BuiltinType::Standard(StandardBuiltinType::Int))),
10703                    b"..."
10704                }
10705                b"Tv42_36_3abc..." => {
10706                    SpecialName::VirtualOverrideThunk(
10707                        CallOffset::Virtual(VOffset(42, 36)),
10708                        Box::new(Encoding::Data(
10709                            Name::Unscoped(
10710                                UnscopedName::Unqualified(
10711                                    UnqualifiedName::Source(
10712                                        SourceName(Identifier {
10713                                            start: 9,
10714                                            end: 12,
10715                                        }))))))),
10716                    b"..."
10717                }
10718                b"Tcv42_36_v42_36_3abc..." => {
10719                    SpecialName::VirtualOverrideThunkCovariant(
10720                        CallOffset::Virtual(VOffset(42, 36)),
10721                        CallOffset::Virtual(VOffset(42, 36)),
10722                        Box::new(Encoding::Data(
10723                            Name::Unscoped(
10724                                UnscopedName::Unqualified(
10725                                    UnqualifiedName::Source(
10726                                        SourceName(Identifier {
10727                                            start: 17,
10728                                            end: 20,
10729                                        }))))))),
10730                    b"..."
10731                }
10732                b"GV3abc..." => {
10733                    SpecialName::Guard(
10734                        Name::Unscoped(
10735                            UnscopedName::Unqualified(
10736                                UnqualifiedName::Source(
10737                                    SourceName(Identifier {
10738                                        start: 3,
10739                                        end: 6,
10740                                    }))))),
10741                    b"..."
10742                }
10743                b"GR3abc_..." => {
10744                    SpecialName::GuardTemporary(
10745                        Name::Unscoped(
10746                            UnscopedName::Unqualified(
10747                                UnqualifiedName::Source(
10748                                    SourceName(Identifier {
10749                                        start: 3,
10750                                        end: 6,
10751                                    })))),
10752                        0),
10753                    b"..."
10754                }
10755                b"GR3abc0_..." => {
10756                    SpecialName::GuardTemporary(
10757                        Name::Unscoped(
10758                            UnscopedName::Unqualified(
10759                                UnqualifiedName::Source(
10760                                    SourceName(Identifier {
10761                                        start: 3,
10762                                        end: 6,
10763                                    })))),
10764                        1),
10765                    b"..."
10766                }
10767                b"Gr4_abc..." => {
10768                    SpecialName::JavaResource(vec![ResourceName {
10769                        start: 4,
10770                        end: 7,
10771                    }]),
10772                    b"..."
10773                }
10774                b"TCc7_i..." => {
10775                    SpecialName::ConstructionVtable(
10776                        TypeHandle::Builtin(BuiltinType::Standard(StandardBuiltinType::Char)),
10777                        7,
10778                        TypeHandle::Builtin(BuiltinType::Standard(StandardBuiltinType::Int))
10779                    ),
10780                    b"..."
10781                }
10782                b"TFi..." => {
10783                    SpecialName::TypeinfoFunction(
10784                        TypeHandle::Builtin(BuiltinType::Standard(StandardBuiltinType::Int))),
10785                    b"..."
10786                }
10787                b"TH4name..." => {
10788                    SpecialName::TlsInit(
10789                        Name::Unscoped(
10790                            UnscopedName::Unqualified(
10791                                UnqualifiedName::Source(
10792                                    SourceName(Identifier { start: 3, end: 7 }))))),
10793                    b"..."
10794                }
10795                b"TW4name..." => {
10796                    SpecialName::TlsWrapper(
10797                        Name::Unscoped(
10798                            UnscopedName::Unqualified(
10799                                UnqualifiedName::Source(
10800                                    SourceName(Identifier { start: 3, end: 7 }))))),
10801                    b"..."
10802                }
10803            }
10804            Err => {
10805                b"TZ" => Error::UnexpectedText,
10806                b"GZ" => Error::UnexpectedText,
10807                b"GR3abcz" => Error::UnexpectedText,
10808                b"GR3abc0z" => Error::UnexpectedText,
10809                b"T" => Error::UnexpectedEnd,
10810                b"G" => Error::UnexpectedEnd,
10811                b"" => Error::UnexpectedEnd,
10812                b"GR3abc" => Error::UnexpectedEnd,
10813                b"GR3abc0" => Error::UnexpectedEnd,
10814                // This number is not allowed to be negative.
10815                b"TCcn7_i..." => Error::UnexpectedText,
10816                b"Gr3abc0" => Error::UnexpectedText,
10817            }
10818        });
10819    }
10820
10821    #[test]
10822    fn parse_function_param() {
10823        assert_parse!(FunctionParam {
10824            Ok => {
10825                b"fpK_..." => {
10826                    FunctionParam(0,
10827                                  CvQualifiers {
10828                                      restrict: false,
10829                                      volatile: false,
10830                                      const_: true,
10831                                  },
10832                                  Some(0)),
10833                    b"..."
10834                }
10835                b"fL1pK_..." => {
10836                    FunctionParam(1,
10837                                  CvQualifiers {
10838                                      restrict: false,
10839                                      volatile: false,
10840                                      const_: true,
10841                                  },
10842                                  Some(0)),
10843                    b"..."
10844                }
10845                b"fpK3_..." => {
10846                    FunctionParam(0,
10847                                  CvQualifiers {
10848                                      restrict: false,
10849                                      volatile: false,
10850                                      const_: true,
10851                                  },
10852                                  Some(4)),
10853                    b"..."
10854                }
10855                b"fL1pK4_..." => {
10856                    FunctionParam(1,
10857                                  CvQualifiers {
10858                                      restrict: false,
10859                                      volatile: false,
10860                                      const_: true,
10861                                  },
10862                                  Some(5)),
10863                    b"..."
10864                }
10865            }
10866            Err => {
10867                b"fz" => Error::UnexpectedText,
10868                b"fLp_" => Error::UnexpectedText,
10869                b"fpL_" => Error::UnexpectedText,
10870                b"fL1pK4z" => Error::UnexpectedText,
10871                b"fL1pK4" => Error::UnexpectedEnd,
10872                b"fL1p" => Error::UnexpectedEnd,
10873                b"fL1" => Error::UnexpectedEnd,
10874                b"fL" => Error::UnexpectedEnd,
10875                b"f" => Error::UnexpectedEnd,
10876                b"" => Error::UnexpectedEnd,
10877            }
10878        });
10879    }
10880
10881    #[test]
10882    fn parse_discriminator() {
10883        assert_parse!(Discriminator {
10884            Ok => {
10885                b"_0..." => {
10886                    Discriminator(0),
10887                    b"..."
10888                }
10889                b"_9..." => {
10890                    Discriminator(9),
10891                    b"..."
10892                }
10893                b"__99_..." => {
10894                    Discriminator(99),
10895                    b"..."
10896                }
10897            }
10898            Err => {
10899                b"_n1" => Error::UnexpectedText,
10900                b"__99..." => Error::UnexpectedText,
10901                b"__99" => Error::UnexpectedEnd,
10902                b"..." => Error::UnexpectedText,
10903            }
10904        });
10905    }
10906
10907    #[test]
10908    fn parse_data_member_prefix() {
10909        assert_parse!(DataMemberPrefix {
10910            Ok => {
10911                b"3fooM..." => {
10912                    DataMemberPrefix(SourceName(Identifier {
10913                        start: 1,
10914                        end: 4,
10915                    })),
10916                    b"..."
10917                }
10918            }
10919            Err => {
10920                b"zzz" => Error::UnexpectedText,
10921                b"1" => Error::UnexpectedEnd,
10922                b"" => Error::UnexpectedEnd,
10923            }
10924        });
10925    }
10926
10927    #[test]
10928    fn parse_ref_qualifier() {
10929        assert_parse!(RefQualifier {
10930            Ok => {
10931                b"R..." => {
10932                    RefQualifier::LValueRef,
10933                    b"..."
10934                }
10935                b"O..." => {
10936                    RefQualifier::RValueRef,
10937                    b"..."
10938                }
10939            }
10940            Err => {
10941                b"..." => Error::UnexpectedText,
10942                b"" => Error::UnexpectedEnd,
10943            }
10944        });
10945    }
10946
10947    #[test]
10948    fn parse_cv_qualifiers() {
10949        assert_parse!(CvQualifiers {
10950            Ok => {
10951                b"" => {
10952                    CvQualifiers { restrict: false, volatile: false, const_: false },
10953                    b""
10954                }
10955                b"..." => {
10956                    CvQualifiers { restrict: false, volatile: false, const_: false },
10957                    b"..."
10958                }
10959                b"r..." => {
10960                    CvQualifiers { restrict: true, volatile: false, const_: false },
10961                    b"..."
10962                }
10963                b"rV..." => {
10964                    CvQualifiers { restrict: true, volatile: true, const_: false },
10965                    b"..."
10966                }
10967                b"rVK..." => {
10968                    CvQualifiers { restrict: true, volatile: true, const_: true },
10969                    b"..."
10970                }
10971                b"V" => {
10972                    CvQualifiers { restrict: false, volatile: true, const_: false },
10973                    b""
10974                }
10975                b"VK" => {
10976                    CvQualifiers { restrict: false, volatile: true, const_: true },
10977                    b""
10978                }
10979                b"K..." => {
10980                    CvQualifiers { restrict: false, volatile: false, const_: true },
10981                    b"..."
10982                }
10983            }
10984            Err => {
10985                // None.
10986            }
10987        });
10988    }
10989
10990    #[test]
10991    fn parse_builtin_type() {
10992        assert_parse!(BuiltinType {
10993            Ok => {
10994                b"c..." => {
10995                    BuiltinType::Standard(StandardBuiltinType::Char),
10996                    b"..."
10997                }
10998                b"c" => {
10999                    BuiltinType::Standard(StandardBuiltinType::Char),
11000                    b""
11001                }
11002                b"u3abc..." => {
11003                    BuiltinType::Extension(SourceName(Identifier {
11004                        start: 2,
11005                        end: 5,
11006                    })),
11007                    b"..."
11008                }
11009            }
11010            Err => {
11011                b"." => Error::UnexpectedText,
11012                b"" => Error::UnexpectedEnd,
11013            }
11014        });
11015    }
11016
11017    #[test]
11018    fn parse_template_param() {
11019        assert_parse!(TemplateParam {
11020            Ok => {
11021                b"T_..." => {
11022                    TemplateParam(0),
11023                    b"..."
11024                }
11025                b"T3_..." => {
11026                    TemplateParam(4),
11027                    b"..."
11028                }
11029            }
11030            Err => {
11031                b"wtf" => Error::UnexpectedText,
11032                b"Twtf" => Error::UnexpectedText,
11033                b"T3wtf" => Error::UnexpectedText,
11034                b"T" => Error::UnexpectedEnd,
11035                b"T3" => Error::UnexpectedEnd,
11036                b"" => Error::UnexpectedEnd,
11037            }
11038        });
11039    }
11040
11041    #[test]
11042    fn parse_unscoped_name() {
11043        assert_parse!(UnscopedName {
11044            Ok => {
11045                b"St5hello..." => {
11046                    UnscopedName::Std(UnqualifiedName::Source(SourceName(Identifier {
11047                        start: 3,
11048                        end: 8,
11049                    }))),
11050                    b"..."
11051                }
11052                b"5hello..." => {
11053                    UnscopedName::Unqualified(UnqualifiedName::Source(SourceName(Identifier {
11054                        start: 1,
11055                        end: 6,
11056                    }))),
11057                    b"..."
11058                }
11059            }
11060            Err => {
11061                b"St..." => Error::UnexpectedText,
11062                b"..." => Error::UnexpectedText,
11063                b"" => Error::UnexpectedEnd,
11064            }
11065        });
11066    }
11067
11068    #[test]
11069    fn parse_unqualified_name() {
11070        assert_parse!(UnqualifiedName {
11071            Ok => {
11072                b"qu.." => {
11073                    UnqualifiedName::Operator(OperatorName::Simple(SimpleOperatorName::Question)),
11074                    b".."
11075                }
11076                b"C1.." => {
11077                    UnqualifiedName::CtorDtor(CtorDtorName::CompleteConstructor(None)),
11078                    b".."
11079                }
11080                b"10abcdefghij..." => {
11081                    UnqualifiedName::Source(SourceName(Identifier {
11082                        start: 2,
11083                        end: 12,
11084                    })),
11085                    b"..."
11086                }
11087                b"UllE_..." => {
11088                    UnqualifiedName::ClosureType(
11089                        ClosureTypeName(
11090                            LambdaSig(vec![
11091                                TypeHandle::Builtin(
11092                                    BuiltinType::Standard(
11093                                        StandardBuiltinType::Long))
11094                            ]),
11095                            None)),
11096                    b"..."
11097                }
11098                b"Ut5_..." => {
11099                    UnqualifiedName::UnnamedType(UnnamedTypeName(Some(5))),
11100                    b"..."
11101                }
11102                b"B5cxx11..." => {
11103                    UnqualifiedName::ABITag(TaggedName(SourceName(Identifier {
11104                        start: 2,
11105                        end: 7,
11106                    }))),
11107                    b"..."
11108                }
11109                b"L3foo_0..." => {
11110                    UnqualifiedName::LocalSourceName(
11111                        SourceName(Identifier {
11112                            start: 2,
11113                            end: 5
11114                        }),
11115                        Some(Discriminator(0))
11116                    ),
11117                    "..."
11118                }
11119                b"L3foo..." => {
11120                    UnqualifiedName::LocalSourceName(
11121                        SourceName(Identifier {
11122                            start: 2,
11123                            end: 5
11124                        }),
11125                        None
11126                    ),
11127                    "..."
11128                }
11129            }
11130            Err => {
11131                b"zzz" => Error::UnexpectedText,
11132                b"Uq" => Error::UnexpectedText,
11133                b"C" => Error::UnexpectedEnd,
11134                b"" => Error::UnexpectedEnd,
11135            }
11136        });
11137    }
11138
11139    #[test]
11140    fn parse_unnamed_type_name() {
11141        assert_parse!(UnnamedTypeName {
11142            Ok => {
11143                b"Ut_abc" => {
11144                    UnnamedTypeName(None),
11145                    b"abc"
11146                }
11147                b"Ut42_abc" => {
11148                    UnnamedTypeName(Some(42)),
11149                    b"abc"
11150                }
11151                b"Ut42_" => {
11152                    UnnamedTypeName(Some(42)),
11153                    b""
11154                }
11155            }
11156            Err => {
11157                b"ut_" => Error::UnexpectedText,
11158                b"u" => Error::UnexpectedEnd,
11159                b"Ut" => Error::UnexpectedEnd,
11160                b"Ut._" => Error::UnexpectedText,
11161                b"Ut42" => Error::UnexpectedEnd,
11162            }
11163        });
11164    }
11165
11166    #[test]
11167    fn parse_identifier() {
11168        assert_parse!(Identifier {
11169            Ok => {
11170                b"1abc" => {
11171                    Identifier { start: 0, end: 4 },
11172                    b""
11173                }
11174                b"_Az1\0\0\0" => {
11175                    Identifier { start: 0, end: 4 },
11176                    b"\0\0\0"
11177                }
11178                b"$_0\0\0\0" => {
11179                    Identifier { start: 0, end: 3 },
11180                    b"\0\0\0"
11181                }
11182            }
11183            Err => {
11184                b"\0\0\0" => Error::UnexpectedText,
11185                b"" => Error::UnexpectedEnd,
11186            }
11187        });
11188    }
11189
11190    #[test]
11191    fn parse_source_name() {
11192        assert_parse!(SourceName {
11193            Ok => {
11194                b"1abc" => {
11195                    SourceName(Identifier { start: 1, end: 2 }),
11196                    b"bc"
11197                }
11198                b"10abcdefghijklm" => {
11199                    SourceName(Identifier { start: 2, end: 12 }),
11200                    b"klm"
11201                }
11202            }
11203            Err => {
11204                b"0abc" => Error::UnexpectedText,
11205                b"n1abc" => Error::UnexpectedText,
11206                b"10abcdef" => Error::UnexpectedEnd,
11207                b"" => Error::UnexpectedEnd,
11208            }
11209        });
11210    }
11211
11212    #[test]
11213    fn parse_number() {
11214        assert_parse!(Number {
11215            Ok => {
11216                b"n2n3" => {
11217                    -2,
11218                    b"n3"
11219                }
11220                b"12345abcdef" => {
11221                    12345,
11222                    b"abcdef"
11223                }
11224                b"0abcdef" => {
11225                    0,
11226                    b"abcdef"
11227                }
11228                b"42" => {
11229                    42,
11230                    b""
11231                }
11232            }
11233            Err => {
11234                b"001" => Error::UnexpectedText,
11235                b"wutang" => Error::UnexpectedText,
11236                b"n" => Error::UnexpectedEnd,
11237                b"" => Error::UnexpectedEnd,
11238            }
11239        });
11240    }
11241
11242    #[test]
11243    fn parse_call_offset() {
11244        assert_parse!(CallOffset {
11245            Ok => {
11246                b"hn42_..." => {
11247                    CallOffset::NonVirtual(NvOffset(-42)),
11248                    b"..."
11249                }
11250                b"vn42_36_..." => {
11251                    CallOffset::Virtual(VOffset(-42, 36)),
11252                    b"..."
11253                }
11254            }
11255            Err => {
11256                b"h1..." => Error::UnexpectedText,
11257                b"v1_1..." => Error::UnexpectedText,
11258                b"hh" => Error::UnexpectedText,
11259                b"vv" => Error::UnexpectedText,
11260                b"z" => Error::UnexpectedText,
11261                b"" => Error::UnexpectedEnd,
11262            }
11263        });
11264    }
11265
11266    #[test]
11267    fn parse_v_offset() {
11268        assert_parse!(VOffset {
11269            Ok => {
11270                b"n2_n3abcdef" => {
11271                    VOffset(-2, -3),
11272                    b"abcdef"
11273                }
11274                b"12345_12345abcdef" => {
11275                    VOffset(12345, 12345),
11276                    b"abcdef"
11277                }
11278                b"0_0abcdef" => {
11279                    VOffset(0, 0),
11280                    b"abcdef"
11281                }
11282                b"42_n3" => {
11283                    VOffset(42, -3),
11284                    b""
11285                }
11286            }
11287            Err => {
11288                b"001" => Error::UnexpectedText,
11289                b"1_001" => Error::UnexpectedText,
11290                b"wutang" => Error::UnexpectedText,
11291                b"n_" => Error::UnexpectedText,
11292                b"1_n" => Error::UnexpectedEnd,
11293                b"1_" => Error::UnexpectedEnd,
11294                b"n" => Error::UnexpectedEnd,
11295                b"" => Error::UnexpectedEnd,
11296            }
11297        });
11298    }
11299
11300    #[test]
11301    fn parse_nv_offset() {
11302        assert_parse!(NvOffset {
11303            Ok => {
11304                b"n2n3" => {
11305                    NvOffset(-2),
11306                    b"n3"
11307                }
11308                b"12345abcdef" => {
11309                    NvOffset(12345),
11310                    b"abcdef"
11311                }
11312                b"0abcdef" => {
11313                    NvOffset(0),
11314                    b"abcdef"
11315                }
11316                b"42" => {
11317                    NvOffset(42),
11318                    b""
11319                }
11320            }
11321            Err => {
11322                b"001" => Error::UnexpectedText,
11323                b"wutang" => Error::UnexpectedText,
11324                b"" => Error::UnexpectedEnd,
11325            }
11326        });
11327    }
11328
11329    #[test]
11330    fn parse_seq_id() {
11331        assert_parse!(SeqId {
11332            Ok => {
11333                b"1_" => {
11334                    SeqId(1),
11335                    b"_"
11336                }
11337                b"42" => {
11338                    SeqId(146),
11339                    b""
11340                }
11341                b"ABCabc" => {
11342                    SeqId(13368),
11343                    b"abc"
11344                }
11345            }
11346            Err => {
11347                b"abc" => Error::UnexpectedText,
11348                b"001" => Error::UnexpectedText,
11349                b"wutang" => Error::UnexpectedText,
11350                b"" => Error::UnexpectedEnd,
11351            }
11352        });
11353    }
11354
11355    #[test]
11356    fn parse_ctor_dtor_name() {
11357        assert_parse!(CtorDtorName {
11358            Ok => {
11359                b"D0" => {
11360                    CtorDtorName::DeletingDestructor,
11361                    b""
11362                }
11363                b"C101" => {
11364                    CtorDtorName::CompleteConstructor(None),
11365                    b"01"
11366                }
11367            }
11368            Err => {
11369                b"gayagaya" => Error::UnexpectedText,
11370                b"C" => Error::UnexpectedEnd,
11371                b"" => Error::UnexpectedEnd,
11372            }
11373        });
11374    }
11375
11376    #[test]
11377    fn parse_operator_name() {
11378        assert_parse!(OperatorName {
11379            Ok => {
11380                b"qu..." => {
11381                    OperatorName::Simple(SimpleOperatorName::Question),
11382                    b"..."
11383                }
11384                b"cvi..." => {
11385                    OperatorName::Conversion(
11386                        TypeHandle::Builtin(
11387                            BuiltinType::Standard(
11388                                StandardBuiltinType::Int))),
11389                    b"..."
11390                }
11391                b"li3Foo..." => {
11392                    OperatorName::Literal(SourceName(Identifier {
11393                        start: 3,
11394                        end: 6,
11395                    })),
11396                    b"..."
11397                }
11398                b"v33Foo..." => {
11399                    OperatorName::VendorExtension(3, SourceName(Identifier {
11400                        start: 3,
11401                        end: 6
11402                    })),
11403                    b"..."
11404                }
11405            }
11406            Err => {
11407                b"cv" => Error::UnexpectedEnd,
11408                b"li3ab" => Error::UnexpectedEnd,
11409                b"li" => Error::UnexpectedEnd,
11410                b"v33ab" => Error::UnexpectedEnd,
11411                b"v3" => Error::UnexpectedEnd,
11412                b"v" => Error::UnexpectedEnd,
11413                b"" => Error::UnexpectedEnd,
11414                b"q" => Error::UnexpectedText,
11415                b"c" => Error::UnexpectedText,
11416                b"l" => Error::UnexpectedText,
11417                b"zzz" => Error::UnexpectedText,
11418            }
11419        });
11420    }
11421
11422    #[test]
11423    fn parse_simple_operator_name() {
11424        assert_parse!(SimpleOperatorName {
11425            Ok => {
11426                b"qu" => {
11427                    SimpleOperatorName::Question,
11428                    b""
11429                }
11430                b"quokka" => {
11431                    SimpleOperatorName::Question,
11432                    b"okka"
11433                }
11434            }
11435            Err => {
11436                b"bu-buuuu" => Error::UnexpectedText,
11437                b"q" => Error::UnexpectedEnd,
11438                b"" => Error::UnexpectedEnd,
11439            }
11440        });
11441    }
11442
11443    #[test]
11444    fn parse_subobject_expr() {
11445        assert_parse!(SubobjectExpr {
11446            with subs [] => {
11447                Ok => {
11448                    "PKcL_Z3FooEE..." => {
11449                        SubobjectExpr {
11450                            ty: TypeHandle::BackReference(1),
11451                            expr: Box::new(Expression::Primary(
11452                                ExprPrimary::External(
11453                                    MangledName::Encoding(
11454                                        Encoding::Data(
11455                                            Name::Unscoped(
11456                                                UnscopedName::Unqualified(
11457                                                    UnqualifiedName::Source(
11458                                                        SourceName(
11459                                                            Identifier {
11460                                                                start: 7,
11461                                                                end: 10,
11462                                                            }
11463                                                        )
11464                                                    )
11465                                                )
11466                                            )
11467                                        ),
11468                                        vec![]
11469                                    )
11470                                )
11471                            )),
11472                            offset: 0,
11473                        },
11474                        b"...",
11475                        [
11476                            Substitutable::Type(
11477                                Type::Qualified(
11478                                    CvQualifiers {
11479                                        restrict: false,
11480                                        volatile: false,
11481                                        const_: true,
11482                                    },
11483                                    TypeHandle::Builtin(
11484                                        BuiltinType::Standard(
11485                                            StandardBuiltinType::Char,
11486                                        ),
11487                                    ),
11488                                )
11489                            ),
11490                            Substitutable::Type(
11491                                Type::PointerTo(
11492                                    TypeHandle::BackReference(
11493                                        0,
11494                                    ),
11495                                ),
11496                            )
11497                        ]
11498                    }
11499                }
11500                Err => {
11501                    "" => Error::UnexpectedEnd,
11502                    "" => Error::UnexpectedEnd,
11503                }
11504            }
11505        });
11506    }
11507}