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