cpp_demangle/
ast.rs

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