cpp_demangle/
ast.rs

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