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 current.is_some() && 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                    debug_assert!(UnqualifiedName::starts_with(c, &tail));
2347
2348                    let (name, tail_tail) = UnqualifiedName::parse(ctx, subs, tail)?;
2349                    if tail_tail.peek() == Some(b'M') {
2350                        // XXXkhuey This seems to be a legacy thing that's dropped from the standard.
2351                        // Behave the way we used to.
2352                        let UnqualifiedName::Source(name, _) = name else {
2353                            return Err(error::Error::UnexpectedText);
2354                        };
2355                        let prefix = Prefix::DataMember(current.unwrap(), DataMemberPrefix(name));
2356                        current = Some(save(subs, prefix, tail_tail));
2357                        tail = consume(b"M", tail_tail).unwrap();
2358                    } else {
2359                        let prefix = match current {
2360                            None => Prefix::Unqualified(name),
2361                            Some(handle) => Prefix::Nested(handle, name),
2362                        };
2363                        current = Some(save(subs, prefix, tail_tail));
2364                        tail = tail_tail;
2365                    }
2366                }
2367                Some(c) if UnqualifiedName::starts_with(c, &tail) => {
2368                    // <prefix> ::= <unqualified-name>
2369                    let (name, tail_tail) = UnqualifiedName::parse(ctx, subs, tail)?;
2370                    let prefix = match current {
2371                        None => Prefix::Unqualified(name),
2372                        Some(handle) => Prefix::Nested(handle, name),
2373                    };
2374                    current = Some(save(subs, prefix, tail_tail));
2375                    tail = tail_tail;
2376                }
2377                Some(_) => {
2378                    if let Some(handle) = current {
2379                        return Ok((handle, tail));
2380                    } else if tail.is_empty() {
2381                        return Err(error::Error::UnexpectedEnd);
2382                    } else {
2383                        return Err(error::Error::UnexpectedText);
2384                    }
2385                }
2386            }
2387        }
2388    }
2389}
2390
2391impl<'a> GetLeafName<'a> for Prefix {
2392    fn get_leaf_name(&'a self, subs: &'a SubstitutionTable) -> Option<LeafName<'a>> {
2393        match *self {
2394            Prefix::Nested(ref prefix, ref name) => name
2395                .get_leaf_name(subs)
2396                .or_else(|| prefix.get_leaf_name(subs)),
2397            Prefix::Unqualified(ref name) => name.get_leaf_name(subs),
2398            Prefix::Template(ref prefix, _) => prefix.get_leaf_name(subs),
2399            Prefix::DataMember(_, ref name) => name.get_leaf_name(subs),
2400            Prefix::TemplateParam(_) | Prefix::Decltype(_) => None,
2401        }
2402    }
2403}
2404
2405impl GetTemplateArgs for PrefixHandle {
2406    // XXX: Not an impl GetTemplateArgs for PrefixHandle because the 'me
2407    // reference to self may not live long enough.
2408    fn get_template_args<'a>(&'a self, subs: &'a SubstitutionTable) -> Option<&'a TemplateArgs> {
2409        match *self {
2410            PrefixHandle::BackReference(idx) => {
2411                if let Some(&Substitutable::Prefix(ref p)) = subs.get(idx) {
2412                    p.get_template_args(subs)
2413                } else {
2414                    None
2415                }
2416            }
2417            PrefixHandle::NonSubstitution(NonSubstitution(idx)) => {
2418                if let Some(&Substitutable::Prefix(ref p)) = subs.get_non_substitution(idx) {
2419                    p.get_template_args(subs)
2420                } else {
2421                    None
2422                }
2423            }
2424            _ => None,
2425        }
2426    }
2427}
2428
2429impl<'subs, W> Demangle<'subs, W> for Prefix
2430where
2431    W: 'subs + DemangleWrite,
2432{
2433    fn demangle<'prev, 'ctx>(
2434        &'subs self,
2435        ctx: &'ctx mut DemangleContext<'subs, W>,
2436        scope: Option<ArgScopeStack<'prev, 'subs>>,
2437    ) -> fmt::Result {
2438        let ctx = try_begin_demangle!(self, ctx, scope);
2439        if ctx.is_template_prefix {
2440            ctx.push_demangle_node(DemangleNodeType::TemplatePrefix);
2441            ctx.is_template_prefix = false;
2442        } else if ctx.is_template_prefix_in_nested_name {
2443            ctx.push_demangle_node(DemangleNodeType::NestedName);
2444            ctx.is_template_prefix_in_nested_name = false;
2445        } else {
2446            ctx.push_demangle_node(DemangleNodeType::Prefix);
2447        }
2448
2449        let ret = match *self {
2450            Prefix::Unqualified(ref unqualified) => unqualified.demangle(ctx, scope),
2451            Prefix::Nested(ref prefix, ref unqualified) => {
2452                prefix.demangle(ctx, scope)?;
2453                write!(ctx, "::")?;
2454                unqualified.demangle(ctx, scope)
2455            }
2456            Prefix::Template(ref prefix, ref args) => {
2457                ctx.is_template_prefix = true;
2458                prefix.demangle(ctx, scope)?;
2459                ctx.is_template_prefix = false;
2460                args.demangle(ctx, scope)
2461            }
2462            Prefix::TemplateParam(ref param) => param.demangle(ctx, scope),
2463            Prefix::Decltype(ref dt) => dt.demangle(ctx, scope),
2464            Prefix::DataMember(ref prefix, ref member) => {
2465                prefix.demangle(ctx, scope)?;
2466                write!(ctx, "::")?;
2467                member.demangle(ctx, scope)
2468            }
2469        };
2470        ctx.pop_demangle_node();
2471        ret
2472    }
2473}
2474
2475impl IsCtorDtorConversion for Prefix {
2476    fn is_ctor_dtor_conversion(&self, subs: &SubstitutionTable) -> bool {
2477        match *self {
2478            Prefix::Unqualified(ref unqualified) | Prefix::Nested(_, ref unqualified) => {
2479                unqualified.is_ctor_dtor_conversion(subs)
2480            }
2481            Prefix::Template(ref prefix, _) => prefix.is_ctor_dtor_conversion(subs),
2482            _ => false,
2483        }
2484    }
2485}
2486
2487impl IsCtorDtorConversion for PrefixHandle {
2488    fn is_ctor_dtor_conversion(&self, subs: &SubstitutionTable) -> bool {
2489        match *self {
2490            PrefixHandle::BackReference(idx) => {
2491                if let Some(sub) = subs.get(idx) {
2492                    sub.is_ctor_dtor_conversion(subs)
2493                } else {
2494                    false
2495                }
2496            }
2497            PrefixHandle::NonSubstitution(NonSubstitution(idx)) => {
2498                if let Some(sub) = subs.get_non_substitution(idx) {
2499                    sub.is_ctor_dtor_conversion(subs)
2500                } else {
2501                    false
2502                }
2503            }
2504            PrefixHandle::WellKnown(_) => false,
2505        }
2506    }
2507}
2508
2509impl PrefixHandle {
2510    // Is this <prefix> also a valid <template-prefix> production? Not to be
2511    // confused with the `GetTemplateArgs` trait.
2512    fn is_template_prefix(&self) -> bool {
2513        match *self {
2514            PrefixHandle::BackReference(_) | PrefixHandle::WellKnown(_) => true,
2515            PrefixHandle::NonSubstitution(_) => false,
2516        }
2517    }
2518}
2519
2520/// The `<unqualified-name>` production.
2521///
2522/// ```text
2523/// <unqualified-name> ::= <operator-name> [<abi-tags>]
2524///                    ::= <ctor-dtor-name> [<abi-tags>]
2525///                    ::= <source-name> [<abi-tags>]
2526///                    ::= <local-source-name> [<abi-tags>]
2527///                    ::= <unnamed-type-name> [<abi-tags>]
2528///                    ::= <closure-type-name> [<abi-tags>]
2529///
2530/// # I think this is from an older version of the standard. It isn't in the
2531/// # current version, but all the other demanglers support it, so we will too.
2532/// <local-source-name> ::= L <source-name> [<discriminator>]
2533/// ```
2534#[derive(Clone, Debug, PartialEq, Eq)]
2535pub enum UnqualifiedName {
2536    /// An operator name.
2537    Operator(OperatorName, AbiTags),
2538    /// A constructor or destructor name.
2539    CtorDtor(CtorDtorName, AbiTags),
2540    /// A source name.
2541    Source(SourceName, AbiTags),
2542    /// A local source name.
2543    LocalSourceName(SourceName, Option<Discriminator>, AbiTags),
2544    /// A generated name for an unnamed type.
2545    UnnamedType(UnnamedTypeName, AbiTags),
2546    /// A closure type name
2547    ClosureType(ClosureTypeName, AbiTags),
2548}
2549
2550impl Parse for UnqualifiedName {
2551    fn parse<'a, 'b>(
2552        ctx: &'a ParseContext,
2553        subs: &'a mut SubstitutionTable,
2554        input: IndexStr<'b>,
2555    ) -> Result<(UnqualifiedName, IndexStr<'b>)> {
2556        try_begin_parse!("UnqualifiedName", ctx, input);
2557
2558        if let Ok((op, tail)) = try_recurse!(OperatorName::parse(ctx, subs, input)) {
2559            let (abi_tags, tail) = AbiTags::parse(ctx, subs, tail)?;
2560            return Ok((UnqualifiedName::Operator(op, abi_tags), tail));
2561        }
2562
2563        if let Ok((ctor_dtor, tail)) = try_recurse!(CtorDtorName::parse(ctx, subs, input)) {
2564            let (abi_tags, tail) = AbiTags::parse(ctx, subs, tail)?;
2565            return Ok((UnqualifiedName::CtorDtor(ctor_dtor, abi_tags), tail));
2566        }
2567
2568        if let Ok(tail) = consume(b"L", input) {
2569            let (name, tail) = SourceName::parse(ctx, subs, tail)?;
2570            let (discr, tail) =
2571                if let Ok((d, t)) = try_recurse!(Discriminator::parse(ctx, subs, tail)) {
2572                    (Some(d), t)
2573                } else {
2574                    (None, tail)
2575                };
2576            let (abi_tags, tail) = AbiTags::parse(ctx, subs, tail)?;
2577            return Ok((
2578                UnqualifiedName::LocalSourceName(name, discr, abi_tags),
2579                tail,
2580            ));
2581        }
2582
2583        if let Ok((source, tail)) = try_recurse!(SourceName::parse(ctx, subs, input)) {
2584            let (abi_tags, tail) = AbiTags::parse(ctx, subs, tail)?;
2585            return Ok((UnqualifiedName::Source(source, abi_tags), tail));
2586        }
2587
2588        if let Ok((closure, tail)) = try_recurse!(ClosureTypeName::parse(ctx, subs, input)) {
2589            let (abi_tags, tail) = AbiTags::parse(ctx, subs, tail)?;
2590            return Ok((UnqualifiedName::ClosureType(closure, abi_tags), tail));
2591        }
2592
2593        let (unnamed, tail) = UnnamedTypeName::parse(ctx, subs, input)?;
2594        let (abi_tags, tail) = AbiTags::parse(ctx, subs, tail)?;
2595        Ok((UnqualifiedName::UnnamedType(unnamed, abi_tags), tail))
2596    }
2597}
2598
2599impl<'subs, W> Demangle<'subs, W> for UnqualifiedName
2600where
2601    W: 'subs + DemangleWrite,
2602{
2603    fn demangle<'prev, 'ctx>(
2604        &'subs self,
2605        ctx: &'ctx mut DemangleContext<'subs, W>,
2606        scope: Option<ArgScopeStack<'prev, 'subs>>,
2607    ) -> fmt::Result {
2608        let ctx = try_begin_demangle!(self, ctx, scope);
2609
2610        ctx.push_demangle_node(DemangleNodeType::UnqualifiedName);
2611        let ret = match *self {
2612            UnqualifiedName::Operator(ref op_name, ref abi_tags) => {
2613                write!(ctx, "operator")?;
2614                op_name.demangle(ctx, scope)?;
2615                abi_tags.demangle(ctx, scope)
2616            }
2617            UnqualifiedName::CtorDtor(ref ctor_dtor, ref abi_tags) => {
2618                ctor_dtor.demangle(ctx, scope)?;
2619                abi_tags.demangle(ctx, scope)
2620            }
2621            UnqualifiedName::Source(ref name, ref abi_tags)
2622            | UnqualifiedName::LocalSourceName(ref name, _, ref abi_tags) => {
2623                name.demangle(ctx, scope)?;
2624                abi_tags.demangle(ctx, scope)
2625            }
2626            UnqualifiedName::UnnamedType(ref unnamed, ref abi_tags) => {
2627                unnamed.demangle(ctx, scope)?;
2628                abi_tags.demangle(ctx, scope)
2629            }
2630            UnqualifiedName::ClosureType(ref closure, ref abi_tags) => {
2631                closure.demangle(ctx, scope)?;
2632                abi_tags.demangle(ctx, scope)
2633            }
2634        };
2635        ctx.pop_demangle_node();
2636        ret
2637    }
2638}
2639
2640impl<'a> GetLeafName<'a> for UnqualifiedName {
2641    fn get_leaf_name(&'a self, subs: &'a SubstitutionTable) -> Option<LeafName<'a>> {
2642        match *self {
2643            UnqualifiedName::Operator(..) | UnqualifiedName::CtorDtor(..) => None,
2644            UnqualifiedName::UnnamedType(ref name, _) => Some(LeafName::UnnamedType(name)),
2645            UnqualifiedName::ClosureType(ref closure, _) => closure.get_leaf_name(subs),
2646            UnqualifiedName::Source(ref name, _)
2647            | UnqualifiedName::LocalSourceName(ref name, ..) => Some(LeafName::SourceName(name)),
2648        }
2649    }
2650}
2651
2652impl IsCtorDtorConversion for UnqualifiedName {
2653    fn is_ctor_dtor_conversion(&self, _: &SubstitutionTable) -> bool {
2654        match *self {
2655            UnqualifiedName::CtorDtor(..)
2656            | UnqualifiedName::Operator(OperatorName::Conversion(_), _) => true,
2657            UnqualifiedName::Operator(..)
2658            | UnqualifiedName::Source(..)
2659            | UnqualifiedName::LocalSourceName(..)
2660            | UnqualifiedName::UnnamedType(..)
2661            | UnqualifiedName::ClosureType(..) => false,
2662        }
2663    }
2664}
2665
2666impl UnqualifiedName {
2667    #[inline]
2668    fn starts_with(byte: u8, input: &IndexStr) -> bool {
2669        byte == b'L'
2670            || OperatorName::starts_with(byte)
2671            || CtorDtorName::starts_with(byte)
2672            || SourceName::starts_with(byte)
2673            || UnnamedTypeName::starts_with(byte)
2674            || ClosureTypeName::starts_with(byte, input)
2675    }
2676}
2677
2678/// The `<source-name>` non-terminal.
2679///
2680/// ```text
2681/// <source-name> ::= <positive length number> <identifier>
2682/// ```
2683#[derive(Clone, Debug, PartialEq, Eq)]
2684pub struct SourceName(Identifier);
2685
2686impl Parse for SourceName {
2687    fn parse<'a, 'b>(
2688        ctx: &'a ParseContext,
2689        subs: &'a mut SubstitutionTable,
2690        input: IndexStr<'b>,
2691    ) -> Result<(SourceName, IndexStr<'b>)> {
2692        try_begin_parse!("SourceName", ctx, input);
2693
2694        let (source_name_len, input) = parse_number(10, false, input)?;
2695        debug_assert!(source_name_len >= 0);
2696        if source_name_len == 0 {
2697            return Err(error::Error::UnexpectedText);
2698        }
2699
2700        let (head, tail) = match input.try_split_at(source_name_len as _) {
2701            Some((head, tail)) => (head, tail),
2702            None => return Err(error::Error::UnexpectedEnd),
2703        };
2704
2705        let (identifier, empty) = Identifier::parse(ctx, subs, head)?;
2706        if !empty.is_empty() {
2707            return Err(error::Error::UnexpectedText);
2708        }
2709
2710        let source_name = SourceName(identifier);
2711        Ok((source_name, tail))
2712    }
2713}
2714
2715impl<'subs> ArgScope<'subs, 'subs> for SourceName {
2716    fn leaf_name(&'subs self) -> Result<LeafName<'subs>> {
2717        Ok(LeafName::SourceName(self))
2718    }
2719
2720    fn get_template_arg(
2721        &'subs self,
2722        _: usize,
2723    ) -> Result<(&'subs TemplateArg, &'subs TemplateArgs)> {
2724        Err(error::Error::BadTemplateArgReference)
2725    }
2726
2727    fn get_function_arg(&'subs self, _: usize) -> Result<&'subs Type> {
2728        Err(error::Error::BadFunctionArgReference)
2729    }
2730}
2731
2732impl SourceName {
2733    #[inline]
2734    fn starts_with(byte: u8) -> bool {
2735        byte == b'0' || (b'0' <= byte && byte <= b'9')
2736    }
2737}
2738
2739impl<'subs, W> Demangle<'subs, W> for SourceName
2740where
2741    W: 'subs + DemangleWrite,
2742{
2743    #[inline]
2744    fn demangle<'prev, 'ctx>(
2745        &'subs self,
2746        ctx: &'ctx mut DemangleContext<'subs, W>,
2747        scope: Option<ArgScopeStack<'prev, 'subs>>,
2748    ) -> fmt::Result {
2749        let ctx = try_begin_demangle!(self, ctx, scope);
2750
2751        self.0.demangle(ctx, scope)
2752    }
2753}
2754
2755/// The `<abi-tags>` non-terminal.
2756///
2757/// ```text
2758/// <abi-tags> ::= <abi-tag> [<abi-tags>]
2759/// ```
2760///
2761/// To make things easier on ourselves, despite the fact that the `<abi-tags>`
2762/// production requires at least one tag, we'll allow a zero-length vector
2763/// here instead of having to use Option<AbiTags> in everything that accepts
2764/// an AbiTags.
2765#[derive(Clone, Debug, Default, PartialEq, Eq)]
2766pub struct AbiTags(Vec<AbiTag>);
2767
2768impl Parse for AbiTags {
2769    fn parse<'a, 'b>(
2770        ctx: &'a ParseContext,
2771        subs: &'a mut SubstitutionTable,
2772        input: IndexStr<'b>,
2773    ) -> Result<(AbiTags, IndexStr<'b>)> {
2774        try_begin_parse!("AbiTags", ctx, input);
2775
2776        let (tags, tail) = zero_or_more::<AbiTag>(ctx, subs, input)?;
2777        Ok((AbiTags(tags), tail))
2778    }
2779}
2780
2781impl<'subs, W> Demangle<'subs, W> for AbiTags
2782where
2783    W: 'subs + DemangleWrite,
2784{
2785    fn demangle<'prev, 'ctx>(
2786        &'subs self,
2787        ctx: &'ctx mut DemangleContext<'subs, W>,
2788        scope: Option<ArgScopeStack<'prev, 'subs>>,
2789    ) -> fmt::Result {
2790        let ctx = try_begin_demangle!(self, ctx, scope);
2791
2792        for tag in &self.0 {
2793            tag.demangle(ctx, scope)?;
2794        }
2795        Ok(())
2796    }
2797}
2798
2799/// The `<abi-tag>` non-terminal.
2800///
2801/// ```text
2802/// <abi-tag> ::= B <source-name>
2803/// ```
2804#[derive(Clone, Debug, PartialEq, Eq)]
2805pub struct AbiTag(SourceName);
2806
2807impl Parse for AbiTag {
2808    fn parse<'a, 'b>(
2809        ctx: &'a ParseContext,
2810        subs: &'a mut SubstitutionTable,
2811        input: IndexStr<'b>,
2812    ) -> Result<(AbiTag, IndexStr<'b>)> {
2813        try_begin_parse!("AbiTag", ctx, input);
2814
2815        let tail = consume(b"B", input)?;
2816        let (source_name, tail) = SourceName::parse(ctx, subs, tail)?;
2817        Ok((AbiTag(source_name), tail))
2818    }
2819}
2820
2821impl<'subs, W> Demangle<'subs, W> for AbiTag
2822where
2823    W: 'subs + DemangleWrite,
2824{
2825    fn demangle<'prev, 'ctx>(
2826        &'subs self,
2827        ctx: &'ctx mut DemangleContext<'subs, W>,
2828        scope: Option<ArgScopeStack<'prev, 'subs>>,
2829    ) -> fmt::Result {
2830        let ctx = try_begin_demangle!(self, ctx, scope);
2831
2832        write!(ctx, "[abi:")?;
2833        self.0.demangle(ctx, scope)?;
2834        write!(ctx, "]")
2835    }
2836}
2837
2838/// The `<identifier>` pseudo-terminal.
2839///
2840/// ```text
2841/// <identifier> ::= <unqualified source code identifier>
2842/// ```
2843///
2844/// > `<identifier>` is a pseudo-terminal representing the characters in the
2845/// > unqualified identifier for the entity in the source code. This ABI does not
2846/// > yet specify a mangling for identifiers containing characters outside of
2847/// > `_A-Za-z0-9.`.
2848///
2849/// Mangled symbols' identifiers also have `$` characters in the wild.
2850#[derive(Clone, Debug, PartialEq, Eq)]
2851pub struct Identifier {
2852    start: usize,
2853    end: usize,
2854}
2855
2856impl Parse for Identifier {
2857    fn parse<'a, 'b>(
2858        ctx: &'a ParseContext,
2859        _subs: &'a mut SubstitutionTable,
2860        input: IndexStr<'b>,
2861    ) -> Result<(Identifier, IndexStr<'b>)> {
2862        try_begin_parse!("Identifier", ctx, input);
2863
2864        if input.is_empty() {
2865            return Err(error::Error::UnexpectedEnd);
2866        }
2867
2868        let end = input
2869            .as_ref()
2870            .iter()
2871            .map(|&c| c as char)
2872            .take_while(|&c| c == '$' || c == '_' || c == '.' || c.is_digit(36))
2873            .count();
2874
2875        if end == 0 {
2876            return Err(error::Error::UnexpectedText);
2877        }
2878
2879        let tail = input.range_from(end..);
2880
2881        let identifier = Identifier {
2882            start: input.index(),
2883            end: tail.index(),
2884        };
2885
2886        Ok((identifier, tail))
2887    }
2888}
2889
2890impl<'subs, W> Demangle<'subs, W> for Identifier
2891where
2892    W: 'subs + DemangleWrite,
2893{
2894    #[inline]
2895    fn demangle<'prev, 'ctx>(
2896        &'subs self,
2897        ctx: &'ctx mut DemangleContext<'subs, W>,
2898        scope: Option<ArgScopeStack<'prev, 'subs>>,
2899    ) -> fmt::Result {
2900        let ctx = try_begin_demangle!(self, ctx, scope);
2901
2902        let ident = &ctx.input[self.start..self.end];
2903
2904        // Handle GCC's anonymous namespace mangling.
2905        let anon_namespace_prefix = b"_GLOBAL_";
2906        if ident.starts_with(anon_namespace_prefix)
2907            && ident.len() >= anon_namespace_prefix.len() + 2
2908        {
2909            let first = ident[anon_namespace_prefix.len()];
2910            let second = ident[anon_namespace_prefix.len() + 1];
2911
2912            match (first, second) {
2913                (b'.', b'N') | (b'_', b'N') | (b'$', b'N') => {
2914                    write!(ctx, "(anonymous namespace)")?;
2915                    return Ok(());
2916                }
2917                _ => {
2918                    // Fall through.
2919                }
2920            }
2921        }
2922
2923        let source_name = String::from_utf8_lossy(ident);
2924        ctx.set_source_name(self.start, self.end);
2925        write!(ctx, "{}", source_name)?;
2926        Ok(())
2927    }
2928}
2929
2930/// The `<clone-type-identifier>` pseudo-terminal.
2931///
2932/// ```text
2933/// <clone-type-identifier> ::= <unqualified source code identifier>
2934/// ```
2935#[derive(Clone, Debug, PartialEq, Eq)]
2936pub struct CloneTypeIdentifier {
2937    start: usize,
2938    end: usize,
2939}
2940
2941impl Parse for CloneTypeIdentifier {
2942    fn parse<'a, 'b>(
2943        ctx: &'a ParseContext,
2944        _subs: &'a mut SubstitutionTable,
2945        input: IndexStr<'b>,
2946    ) -> Result<(CloneTypeIdentifier, IndexStr<'b>)> {
2947        try_begin_parse!("CloneTypeIdentifier", ctx, input);
2948
2949        if input.is_empty() {
2950            return Err(error::Error::UnexpectedEnd);
2951        }
2952
2953        let end = input
2954            .as_ref()
2955            .iter()
2956            .map(|&c| c as char)
2957            .take_while(|&c| c == '$' || c == '_' || c.is_digit(36))
2958            .count();
2959
2960        if end == 0 {
2961            return Err(error::Error::UnexpectedText);
2962        }
2963
2964        let tail = input.range_from(end..);
2965
2966        let identifier = CloneTypeIdentifier {
2967            start: input.index(),
2968            end: tail.index(),
2969        };
2970
2971        Ok((identifier, tail))
2972    }
2973}
2974
2975impl<'subs, W> Demangle<'subs, W> for CloneTypeIdentifier
2976where
2977    W: 'subs + DemangleWrite,
2978{
2979    #[inline]
2980    fn demangle<'prev, 'ctx>(
2981        &'subs self,
2982        ctx: &'ctx mut DemangleContext<'subs, W>,
2983        scope: Option<ArgScopeStack<'prev, 'subs>>,
2984    ) -> fmt::Result {
2985        let ctx = try_begin_demangle!(self, ctx, scope);
2986
2987        let ident = &ctx.input[self.start..self.end];
2988
2989        let source_name = String::from_utf8_lossy(ident);
2990        ctx.set_source_name(self.start, self.end);
2991        write!(ctx, " .{}", source_name)?;
2992        Ok(())
2993    }
2994}
2995
2996/// The `<number>` production.
2997///
2998/// ```text
2999/// <number> ::= [n] <non-negative decimal integer>
3000/// ```
3001type Number = isize;
3002
3003impl Parse for Number {
3004    fn parse<'a, 'b>(
3005        ctx: &'a ParseContext,
3006        _subs: &'a mut SubstitutionTable,
3007        input: IndexStr<'b>,
3008    ) -> Result<(isize, IndexStr<'b>)> {
3009        try_begin_parse!("Number", ctx, input);
3010        parse_number(10, true, input)
3011    }
3012}
3013
3014/// A <seq-id> production encoding a base-36 positive number.
3015///
3016/// ```text
3017/// <seq-id> ::= <0-9A-Z>+
3018/// ```
3019#[derive(Clone, Debug, PartialEq, Eq)]
3020pub struct SeqId(usize);
3021
3022impl Parse for SeqId {
3023    fn parse<'a, 'b>(
3024        ctx: &'a ParseContext,
3025        _subs: &'a mut SubstitutionTable,
3026        input: IndexStr<'b>,
3027    ) -> Result<(SeqId, IndexStr<'b>)> {
3028        try_begin_parse!("SeqId", ctx, input);
3029
3030        parse_number(36, false, input).map(|(num, tail)| (SeqId(num as _), tail))
3031    }
3032}
3033
3034/// The `<operator-name>` production.
3035///
3036/// ```text
3037/// <operator-name> ::= <simple-operator-name>
3038///                 ::= cv <type>               # (cast)
3039///                 ::= li <source-name>        # operator ""
3040///                 ::= v <digit> <source-name> # vendor extended operator
3041/// ```
3042#[derive(Clone, Debug, PartialEq, Eq)]
3043pub enum OperatorName {
3044    /// A simple operator name.
3045    Simple(SimpleOperatorName),
3046
3047    /// A type cast.
3048    Cast(TypeHandle),
3049
3050    /// A type conversion.
3051    Conversion(TypeHandle),
3052
3053    /// Operator literal, ie `operator ""`.
3054    Literal(SourceName),
3055
3056    /// A non-standard, vendor extension operator.
3057    VendorExtension(u8, SourceName),
3058}
3059
3060impl OperatorName {
3061    fn starts_with(byte: u8) -> bool {
3062        byte == b'c' || byte == b'l' || byte == b'v' || SimpleOperatorName::starts_with(byte)
3063    }
3064
3065    fn arity(&self) -> u8 {
3066        match self {
3067            &OperatorName::Cast(_) | &OperatorName::Conversion(_) | &OperatorName::Literal(_) => 1,
3068            &OperatorName::Simple(ref s) => s.arity(),
3069            &OperatorName::VendorExtension(arity, _) => arity,
3070        }
3071    }
3072
3073    fn parse_from_expr<'a, 'b>(
3074        ctx: &'a ParseContext,
3075        subs: &'a mut SubstitutionTable,
3076        input: IndexStr<'b>,
3077    ) -> Result<(Expression, IndexStr<'b>)> {
3078        let (operator, tail) = OperatorName::parse_internal(ctx, subs, input, true)?;
3079
3080        let arity = operator.arity();
3081        if arity == 1 {
3082            let (first, tail) = Expression::parse(ctx, subs, tail)?;
3083            let expr = Expression::Unary(operator, Box::new(first));
3084            Ok((expr, tail))
3085        } else if arity == 2 {
3086            let (first, tail) = Expression::parse(ctx, subs, tail)?;
3087            let (second, tail) = Expression::parse(ctx, subs, tail)?;
3088            let expr = Expression::Binary(operator, Box::new(first), Box::new(second));
3089            Ok((expr, tail))
3090        } else if arity == 3 {
3091            let (first, tail) = Expression::parse(ctx, subs, tail)?;
3092            let (second, tail) = Expression::parse(ctx, subs, tail)?;
3093            let (third, tail) = Expression::parse(ctx, subs, tail)?;
3094            let expr =
3095                Expression::Ternary(operator, Box::new(first), Box::new(second), Box::new(third));
3096            Ok((expr, tail))
3097        } else {
3098            Err(error::Error::UnexpectedText)
3099        }
3100    }
3101
3102    fn parse_internal<'a, 'b>(
3103        ctx: &'a ParseContext,
3104        subs: &'a mut SubstitutionTable,
3105        input: IndexStr<'b>,
3106        from_expr: bool,
3107    ) -> Result<(OperatorName, IndexStr<'b>)> {
3108        try_begin_parse!("OperatorName", ctx, input);
3109
3110        if let Ok((simple, tail)) = try_recurse!(SimpleOperatorName::parse(ctx, subs, input)) {
3111            return Ok((OperatorName::Simple(simple), tail));
3112        }
3113
3114        if let Ok(tail) = consume(b"cv", input) {
3115            // If we came through the expression path, we're a cast. If not,
3116            // we're a conversion.
3117            let previously_in_conversion = ctx.set_in_conversion(!from_expr);
3118            let parse_result = TypeHandle::parse(ctx, subs, tail);
3119            ctx.set_in_conversion(previously_in_conversion);
3120            let (ty, tail) = parse_result?;
3121            if from_expr {
3122                return Ok((OperatorName::Cast(ty), tail));
3123            } else {
3124                return Ok((OperatorName::Conversion(ty), tail));
3125            }
3126        }
3127
3128        if let Ok(tail) = consume(b"li", input) {
3129            let (name, tail) = SourceName::parse(ctx, subs, tail)?;
3130            return Ok((OperatorName::Literal(name), tail));
3131        }
3132
3133        let tail = consume(b"v", input)?;
3134        let (arity, tail) = match tail.peek() {
3135            Some(c) if b'0' <= c && c <= b'9' => (c - b'0', tail.range_from(1..)),
3136            None => return Err(error::Error::UnexpectedEnd),
3137            _ => return Err(error::Error::UnexpectedText),
3138        };
3139        let (name, tail) = SourceName::parse(ctx, subs, tail)?;
3140        Ok((OperatorName::VendorExtension(arity, name), tail))
3141    }
3142}
3143
3144impl Parse for OperatorName {
3145    fn parse<'a, 'b>(
3146        ctx: &'a ParseContext,
3147        subs: &'a mut SubstitutionTable,
3148        input: IndexStr<'b>,
3149    ) -> Result<(OperatorName, IndexStr<'b>)> {
3150        OperatorName::parse_internal(ctx, subs, input, false)
3151    }
3152}
3153
3154impl<'subs, W> Demangle<'subs, W> for OperatorName
3155where
3156    W: 'subs + DemangleWrite,
3157{
3158    fn demangle<'prev, 'ctx>(
3159        &'subs self,
3160        ctx: &'ctx mut DemangleContext<'subs, W>,
3161        scope: Option<ArgScopeStack<'prev, 'subs>>,
3162    ) -> fmt::Result {
3163        let ctx = try_begin_demangle!(self, ctx, scope);
3164
3165        match *self {
3166            OperatorName::Simple(ref simple) => {
3167                match *simple {
3168                    SimpleOperatorName::New
3169                    | SimpleOperatorName::NewArray
3170                    | SimpleOperatorName::Delete
3171                    | SimpleOperatorName::DeleteArray => {
3172                        ctx.ensure_space()?;
3173                    }
3174                    _ => {}
3175                }
3176                simple.demangle(ctx, scope)
3177            }
3178            OperatorName::Cast(ref ty) | OperatorName::Conversion(ref ty) => {
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                if let Ok((_, new_tail)) =
3774                    try_recurse!(TemplateArgs::parse(ctx, &mut tmp_subs, tail))
3775                {
3776                    if new_tail.peek() != Some(b'I') {
3777                        // Don't consume the TemplateArgs.
3778                        let ty = Type::TemplateParam(param);
3779                        return insert_and_return_handle(ty, subs, tail);
3780                    }
3781                    // We really do have a <template-template-param>. Fall through.
3782                    // NB: We can't use the arguments we just parsed because a
3783                    // TemplateTemplateParam is substitutable, and if we use it
3784                    // any substitutions in the arguments will come *before* it,
3785                    // putting the substitution table out of order.
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///               ::= tw <expression>                              # throw expression
5760///               ::= tr                                           # throw with no operand (rethrow)
5761///               ::= <unresolved-name>                            # f(p), N::f(p), ::f(p),
5762///                                                                # freestanding dependent name (e.g., T::x),
5763///                                                                # objectless nonstatic member reference
5764///               ::= <expr-primary>
5765/// ```
5766#[derive(Clone, Debug, PartialEq, Eq)]
5767pub enum Expression {
5768    /// A unary operator expression.
5769    Unary(OperatorName, Box<Expression>),
5770
5771    /// A binary operator expression.
5772    Binary(OperatorName, Box<Expression>, Box<Expression>),
5773
5774    /// A ternary operator expression.
5775    Ternary(
5776        OperatorName,
5777        Box<Expression>,
5778        Box<Expression>,
5779        Box<Expression>,
5780    ),
5781
5782    /// A prefix `++`.
5783    PrefixInc(Box<Expression>),
5784
5785    /// A prefix `--`.
5786    PrefixDec(Box<Expression>),
5787
5788    /// A call with functor and arguments.
5789    Call(Box<Expression>, Vec<Expression>),
5790
5791    /// A type conversion with one argument.
5792    ConversionOne(TypeHandle, Box<Expression>),
5793
5794    /// A type conversion with many arguments.
5795    ConversionMany(TypeHandle, Vec<Expression>),
5796
5797    /// A type conversion with many arguments.
5798    ConversionBraced(TypeHandle, Vec<Expression>),
5799
5800    /// A braced init list expression.
5801    BracedInitList(Box<Expression>),
5802
5803    /// The `new` operator.
5804    New(Vec<Expression>, TypeHandle, Option<Initializer>),
5805
5806    /// The global `::new` operator.
5807    GlobalNew(Vec<Expression>, TypeHandle, Option<Initializer>),
5808
5809    /// The `new[]` operator.
5810    NewArray(Vec<Expression>, TypeHandle, Option<Initializer>),
5811
5812    /// The global `::new[]` operator.
5813    GlobalNewArray(Vec<Expression>, TypeHandle, Option<Initializer>),
5814
5815    /// The `delete` operator.
5816    Delete(Box<Expression>),
5817
5818    /// The global `::delete` operator.
5819    GlobalDelete(Box<Expression>),
5820
5821    /// The `delete[]` operator.
5822    DeleteArray(Box<Expression>),
5823
5824    /// The global `::delete[]` operator.
5825    GlobalDeleteArray(Box<Expression>),
5826
5827    /// `dynamic_cast<type> (expression)`
5828    DynamicCast(TypeHandle, Box<Expression>),
5829
5830    /// `static_cast<type> (expression)`
5831    StaticCast(TypeHandle, Box<Expression>),
5832
5833    /// `const_cast<type> (expression)`
5834    ConstCast(TypeHandle, Box<Expression>),
5835
5836    /// `reinterpret_cast<type> (expression)`
5837    ReinterpretCast(TypeHandle, Box<Expression>),
5838
5839    /// `typeid (type)`
5840    TypeidType(TypeHandle),
5841
5842    /// `typeid (expression)`
5843    TypeidExpr(Box<Expression>),
5844
5845    /// `sizeof (type)`
5846    SizeofType(TypeHandle),
5847
5848    /// `sizeof (expression)`
5849    SizeofExpr(Box<Expression>),
5850
5851    /// `alignof (type)`
5852    AlignofType(TypeHandle),
5853
5854    /// `alignof (expression)`
5855    AlignofExpr(Box<Expression>),
5856
5857    /// `noexcept (expression)`
5858    Noexcept(Box<Expression>),
5859
5860    /// Subobject expression,
5861    Subobject(SubobjectExpr),
5862
5863    /// A named template parameter.
5864    TemplateParam(TemplateParam),
5865
5866    /// A function parameter.
5867    FunctionParam(FunctionParam),
5868
5869    /// `expr.name`
5870    Member(Box<Expression>, MemberName),
5871
5872    /// `expr->name`
5873    DerefMember(Box<Expression>, MemberName),
5874
5875    /// `expr.*expr`
5876    PointerToMember(Box<Expression>, Box<Expression>),
5877
5878    /// `sizeof...(T)`, size of a template parameter pack.
5879    SizeofTemplatePack(TemplateParam),
5880
5881    /// `sizeof...(parameter)`, size of a function parameter pack.
5882    SizeofFunctionPack(FunctionParam),
5883
5884    /// `sizeof...(T)`, size of a captured template parameter pack from an alias
5885    /// template.
5886    SizeofCapturedTemplatePack(Vec<TemplateArg>),
5887
5888    /// `expression...`, pack expansion.
5889    PackExpansion(Box<Expression>),
5890
5891    /// `throw expression`
5892    Throw(Box<Expression>),
5893
5894    /// `throw` with no operand
5895    Rethrow,
5896
5897    /// `f(p)`, `N::f(p)`, `::f(p)`, freestanding dependent name (e.g., `T::x`),
5898    /// objectless nonstatic member reference.
5899    UnresolvedName(UnresolvedName),
5900
5901    /// An `<expr-primary>` production.
5902    Primary(ExprPrimary),
5903}
5904
5905impl Parse for Expression {
5906    fn parse<'a, 'b>(
5907        ctx: &'a ParseContext,
5908        subs: &'a mut SubstitutionTable,
5909        input: IndexStr<'b>,
5910    ) -> Result<(Expression, IndexStr<'b>)> {
5911        try_begin_parse!("Expression", ctx, input);
5912
5913        if let Ok(tail) = consume(b"pp_", input) {
5914            let (expr, tail) = Expression::parse(ctx, subs, tail)?;
5915            let expr = Expression::PrefixInc(Box::new(expr));
5916            return Ok((expr, tail));
5917        }
5918
5919        if let Ok(tail) = consume(b"mm_", input) {
5920            let (expr, tail) = Expression::parse(ctx, subs, tail)?;
5921            let expr = Expression::PrefixDec(Box::new(expr));
5922            return Ok((expr, tail));
5923        }
5924
5925        if let Some((head, tail)) = input.try_split_at(2) {
5926            match head.as_ref() {
5927                b"cl" => {
5928                    let (func, tail) = Expression::parse(ctx, subs, tail)?;
5929                    let (args, tail) = zero_or_more::<Expression>(ctx, subs, tail)?;
5930                    let tail = consume(b"E", tail)?;
5931                    let expr = Expression::Call(Box::new(func), args);
5932                    return Ok((expr, tail));
5933                }
5934                b"cv" => {
5935                    let (ty, tail) = TypeHandle::parse(ctx, subs, tail)?;
5936                    if let Ok(tail) = consume(b"_", tail) {
5937                        let (exprs, tail) = zero_or_more::<Expression>(ctx, subs, tail)?;
5938                        let tail = consume(b"E", tail)?;
5939                        let expr = Expression::ConversionMany(ty, exprs);
5940                        return Ok((expr, tail));
5941                    } else {
5942                        let (expr, tail) = Expression::parse(ctx, subs, tail)?;
5943                        let expr = Expression::ConversionOne(ty, Box::new(expr));
5944                        return Ok((expr, tail));
5945                    }
5946                }
5947                b"tl" => {
5948                    let (ty, tail) = TypeHandle::parse(ctx, subs, tail)?;
5949                    let (exprs, tail) = zero_or_more::<Expression>(ctx, subs, tail)?;
5950                    let expr = Expression::ConversionBraced(ty, exprs);
5951                    let tail = consume(b"E", tail)?;
5952                    return Ok((expr, tail));
5953                }
5954                b"il" => {
5955                    let (expr, tail) = Expression::parse(ctx, subs, tail)?;
5956                    let tail = consume(b"E", tail)?;
5957                    let expr = Expression::BracedInitList(Box::new(expr));
5958                    return Ok((expr, tail));
5959                }
5960                b"dc" => {
5961                    let (ty, tail) = TypeHandle::parse(ctx, subs, tail)?;
5962                    let (expr, tail) = Expression::parse(ctx, subs, tail)?;
5963                    let expr = Expression::DynamicCast(ty, Box::new(expr));
5964                    return Ok((expr, tail));
5965                }
5966                b"sc" => {
5967                    let (ty, tail) = TypeHandle::parse(ctx, subs, tail)?;
5968                    let (expr, tail) = Expression::parse(ctx, subs, tail)?;
5969                    let expr = Expression::StaticCast(ty, Box::new(expr));
5970                    return Ok((expr, tail));
5971                }
5972                b"cc" => {
5973                    let (ty, tail) = TypeHandle::parse(ctx, subs, tail)?;
5974                    let (expr, tail) = Expression::parse(ctx, subs, tail)?;
5975                    let expr = Expression::ConstCast(ty, Box::new(expr));
5976                    return Ok((expr, tail));
5977                }
5978                b"rc" => {
5979                    let (ty, tail) = TypeHandle::parse(ctx, subs, tail)?;
5980                    let (expr, tail) = Expression::parse(ctx, subs, tail)?;
5981                    let expr = Expression::ReinterpretCast(ty, Box::new(expr));
5982                    return Ok((expr, tail));
5983                }
5984                b"ti" => {
5985                    let (ty, tail) = TypeHandle::parse(ctx, subs, tail)?;
5986                    let expr = Expression::TypeidType(ty);
5987                    return Ok((expr, tail));
5988                }
5989                b"te" => {
5990                    let (expr, tail) = Expression::parse(ctx, subs, tail)?;
5991                    let expr = Expression::TypeidExpr(Box::new(expr));
5992                    return Ok((expr, tail));
5993                }
5994                b"st" => {
5995                    let (ty, tail) = TypeHandle::parse(ctx, subs, tail)?;
5996                    let expr = Expression::SizeofType(ty);
5997                    return Ok((expr, tail));
5998                }
5999                b"sz" => {
6000                    let (expr, tail) = Expression::parse(ctx, subs, tail)?;
6001                    let expr = Expression::SizeofExpr(Box::new(expr));
6002                    return Ok((expr, tail));
6003                }
6004                b"at" => {
6005                    let (ty, tail) = TypeHandle::parse(ctx, subs, tail)?;
6006                    let expr = Expression::AlignofType(ty);
6007                    return Ok((expr, tail));
6008                }
6009                b"az" => {
6010                    let (expr, tail) = Expression::parse(ctx, subs, tail)?;
6011                    let expr = Expression::AlignofExpr(Box::new(expr));
6012                    return Ok((expr, tail));
6013                }
6014                b"nx" => {
6015                    let (expr, tail) = Expression::parse(ctx, subs, tail)?;
6016                    let expr = Expression::Noexcept(Box::new(expr));
6017                    return Ok((expr, tail));
6018                }
6019                b"so" => {
6020                    let (expr, tail) = SubobjectExpr::parse(ctx, subs, tail)?;
6021                    let expr = Expression::Subobject(expr);
6022                    return Ok((expr, tail));
6023                }
6024                b"dt" => {
6025                    let (expr, tail) = Expression::parse(ctx, subs, tail)?;
6026                    let (name, tail) = MemberName::parse(ctx, subs, tail)?;
6027                    let expr = Expression::Member(Box::new(expr), name);
6028                    return Ok((expr, tail));
6029                }
6030                b"pt" => {
6031                    let (expr, tail) = Expression::parse(ctx, subs, tail)?;
6032                    let (name, tail) = MemberName::parse(ctx, subs, tail)?;
6033                    let expr = Expression::DerefMember(Box::new(expr), name);
6034                    return Ok((expr, tail));
6035                }
6036                b"ds" => {
6037                    let (first, tail) = Expression::parse(ctx, subs, tail)?;
6038                    let (second, tail) = Expression::parse(ctx, subs, tail)?;
6039                    let expr = Expression::PointerToMember(Box::new(first), Box::new(second));
6040                    return Ok((expr, tail));
6041                }
6042                b"sZ" => {
6043                    if let Ok((param, tail)) = TemplateParam::parse(ctx, subs, tail) {
6044                        let expr = Expression::SizeofTemplatePack(param);
6045                        return Ok((expr, tail));
6046                    }
6047
6048                    let (param, tail) = FunctionParam::parse(ctx, subs, tail)?;
6049                    let expr = Expression::SizeofFunctionPack(param);
6050                    return Ok((expr, tail));
6051                }
6052                b"sP" => {
6053                    let (args, tail) = zero_or_more::<TemplateArg>(ctx, subs, tail)?;
6054                    let expr = Expression::SizeofCapturedTemplatePack(args);
6055                    let tail = consume(b"E", tail)?;
6056                    return Ok((expr, tail));
6057                }
6058                b"sp" => {
6059                    let (expr, tail) = Expression::parse(ctx, subs, tail)?;
6060                    let expr = Expression::PackExpansion(Box::new(expr));
6061                    return Ok((expr, tail));
6062                }
6063                b"tw" => {
6064                    let (expr, tail) = Expression::parse(ctx, subs, tail)?;
6065                    let expr = Expression::Throw(Box::new(expr));
6066                    return Ok((expr, tail));
6067                }
6068                b"tr" => {
6069                    let expr = Expression::Rethrow;
6070                    return Ok((expr, tail));
6071                }
6072                b"gs" => {
6073                    if let Ok((expr, tail)) = try_recurse!(can_be_global(true, ctx, subs, tail)) {
6074                        return Ok((expr, tail));
6075                    }
6076                }
6077                _ => {}
6078            }
6079        }
6080
6081        if let Ok((expr, tail)) = try_recurse!(can_be_global(false, ctx, subs, input)) {
6082            return Ok((expr, tail));
6083        }
6084
6085        if let Ok((param, tail)) = try_recurse!(TemplateParam::parse(ctx, subs, input)) {
6086            let expr = Expression::TemplateParam(param);
6087            return Ok((expr, tail));
6088        }
6089
6090        if let Ok((param, tail)) = try_recurse!(FunctionParam::parse(ctx, subs, input)) {
6091            let expr = Expression::FunctionParam(param);
6092            return Ok((expr, tail));
6093        }
6094
6095        if let Ok((name, tail)) = try_recurse!(UnresolvedName::parse(ctx, subs, input)) {
6096            let expr = Expression::UnresolvedName(name);
6097            return Ok((expr, tail));
6098        }
6099
6100        if let Ok((prim, tail)) = try_recurse!(ExprPrimary::parse(ctx, subs, input)) {
6101            let expr = Expression::Primary(prim);
6102            return Ok((expr, tail));
6103        }
6104
6105        // "A production for <expression> that directly specifies an operation
6106        // code (e.g., for the -> operator) takes precedence over one that is
6107        // expressed in terms of (unary/binary/ternary) <operator-name>." So try
6108        // and parse unary/binary/ternary expressions last.
6109        let (expr, tail) = OperatorName::parse_from_expr(ctx, subs, input)?;
6110        return Ok((expr, tail));
6111
6112        // Parse the various expressions that can optionally have a leading "gs"
6113        // to indicate that they are in the global namespace. The input is after
6114        // we have already detected consumed the optional "gs" and if we did
6115        // find it, then `is_global` should be true.
6116        fn can_be_global<'a, 'b>(
6117            is_global: bool,
6118            ctx: &'a ParseContext,
6119            subs: &'a mut SubstitutionTable,
6120            input: IndexStr<'b>,
6121        ) -> Result<(Expression, IndexStr<'b>)> {
6122            match input.try_split_at(2) {
6123                None => Err(error::Error::UnexpectedEnd),
6124                Some((head, tail)) => match head.as_ref() {
6125                    b"nw" => {
6126                        let (exprs, tail) = zero_or_more::<Expression>(ctx, subs, tail)?;
6127                        let tail = consume(b"_", tail)?;
6128                        let (ty, tail) = TypeHandle::parse(ctx, subs, tail)?;
6129                        if let Ok(tail) = consume(b"E", tail) {
6130                            let expr = if is_global {
6131                                Expression::GlobalNew(exprs, ty, None)
6132                            } else {
6133                                Expression::New(exprs, ty, None)
6134                            };
6135                            Ok((expr, tail))
6136                        } else {
6137                            let (init, tail) = Initializer::parse(ctx, subs, tail)?;
6138                            let expr = if is_global {
6139                                Expression::GlobalNew(exprs, ty, Some(init))
6140                            } else {
6141                                Expression::New(exprs, ty, Some(init))
6142                            };
6143                            Ok((expr, tail))
6144                        }
6145                    }
6146                    b"na" => {
6147                        let (exprs, tail) = zero_or_more::<Expression>(ctx, subs, tail)?;
6148                        let tail = consume(b"_", tail)?;
6149                        let (ty, tail) = TypeHandle::parse(ctx, subs, tail)?;
6150                        if let Ok(tail) = consume(b"E", tail) {
6151                            let expr = if is_global {
6152                                Expression::GlobalNewArray(exprs, ty, None)
6153                            } else {
6154                                Expression::NewArray(exprs, ty, None)
6155                            };
6156                            Ok((expr, tail))
6157                        } else {
6158                            let (init, tail) = Initializer::parse(ctx, subs, tail)?;
6159                            let expr = if is_global {
6160                                Expression::GlobalNewArray(exprs, ty, Some(init))
6161                            } else {
6162                                Expression::NewArray(exprs, ty, Some(init))
6163                            };
6164                            Ok((expr, tail))
6165                        }
6166                    }
6167                    b"dl" => {
6168                        let (expr, tail) = Expression::parse(ctx, subs, tail)?;
6169                        let expr = if is_global {
6170                            Expression::GlobalDelete(Box::new(expr))
6171                        } else {
6172                            Expression::Delete(Box::new(expr))
6173                        };
6174                        Ok((expr, tail))
6175                    }
6176                    b"da" => {
6177                        let (expr, tail) = Expression::parse(ctx, subs, tail)?;
6178                        let expr = if is_global {
6179                            Expression::GlobalDeleteArray(Box::new(expr))
6180                        } else {
6181                            Expression::DeleteArray(Box::new(expr))
6182                        };
6183                        Ok((expr, tail))
6184                    }
6185                    _ => Err(error::Error::UnexpectedText),
6186                },
6187            }
6188        }
6189    }
6190}
6191
6192impl<'subs, W> Demangle<'subs, W> for Expression
6193where
6194    W: 'subs + DemangleWrite,
6195{
6196    fn demangle<'prev, 'ctx>(
6197        &'subs self,
6198        ctx: &'ctx mut DemangleContext<'subs, W>,
6199        scope: Option<ArgScopeStack<'prev, 'subs>>,
6200    ) -> fmt::Result {
6201        let ctx = try_begin_demangle!(self, ctx, scope);
6202
6203        match *self {
6204            Expression::Unary(OperatorName::Simple(ref op), ref expr)
6205                if *op == SimpleOperatorName::PostInc || *op == SimpleOperatorName::PostDec =>
6206            {
6207                expr.demangle_as_subexpr(ctx, scope)?;
6208                op.demangle(ctx, scope)
6209            }
6210            Expression::Unary(ref op, ref expr) => {
6211                op.demangle(ctx, scope)?;
6212                expr.demangle_as_subexpr(ctx, scope)
6213            }
6214            // These need an extra set of parens so that it doesn't close any
6215            // template argument accidentally.
6216            Expression::Binary(
6217                OperatorName::Simple(SimpleOperatorName::Greater),
6218                ref lhs,
6219                ref rhs,
6220            ) => {
6221                write!(ctx, "((")?;
6222                lhs.demangle(ctx, scope)?;
6223                write!(ctx, ")>(")?;
6224                rhs.demangle(ctx, scope)?;
6225                write!(ctx, "))")
6226            }
6227            Expression::Binary(ref op, ref lhs, ref rhs) => {
6228                lhs.demangle_as_subexpr(ctx, scope)?;
6229                op.demangle(ctx, scope)?;
6230                rhs.demangle_as_subexpr(ctx, scope)
6231            }
6232            Expression::Ternary(
6233                OperatorName::Simple(SimpleOperatorName::Question),
6234                ref condition,
6235                ref consequent,
6236                ref alternative,
6237            ) => {
6238                condition.demangle_as_subexpr(ctx, scope)?;
6239                write!(ctx, "?")?;
6240                consequent.demangle_as_subexpr(ctx, scope)?;
6241                write!(ctx, " : ")?;
6242                alternative.demangle_as_subexpr(ctx, scope)
6243            }
6244            Expression::Ternary(ref op, ref e1, ref e2, ref e3) => {
6245                // Nonsensical ternary operator? Just print it like a function call,
6246                // I suppose...
6247                //
6248                // TODO: should we detect and reject this during parsing?
6249                op.demangle(ctx, scope)?;
6250                write!(ctx, "(")?;
6251                e1.demangle(ctx, scope)?;
6252                write!(ctx, ", ")?;
6253                e2.demangle(ctx, scope)?;
6254                write!(ctx, ", ")?;
6255                e3.demangle(ctx, scope)?;
6256                write!(ctx, ")")?;
6257                Ok(())
6258            }
6259            Expression::PrefixInc(ref expr) => {
6260                write!(ctx, "++")?;
6261                expr.demangle(ctx, scope)
6262            }
6263            Expression::PrefixDec(ref expr) => {
6264                write!(ctx, "--")?;
6265                expr.demangle(ctx, scope)
6266            }
6267            Expression::Call(ref functor_expr, ref args) => {
6268                functor_expr.demangle_as_subexpr(ctx, scope)?;
6269                write!(ctx, "(")?;
6270                let mut need_comma = false;
6271                for arg in args {
6272                    if need_comma {
6273                        write!(ctx, ", ")?;
6274                    }
6275                    arg.demangle(ctx, scope)?;
6276                    need_comma = true;
6277                }
6278                write!(ctx, ")")?;
6279                Ok(())
6280            }
6281            Expression::ConversionOne(ref ty, ref expr) => {
6282                write!(ctx, "(")?;
6283                ty.demangle(ctx, scope)?;
6284                write!(ctx, ")(")?;
6285                expr.demangle(ctx, scope)?;
6286                write!(ctx, ")")?;
6287                Ok(())
6288            }
6289            Expression::ConversionMany(ref ty, ref exprs) => {
6290                ty.demangle(ctx, scope)?;
6291                write!(ctx, "(")?;
6292                let mut need_comma = false;
6293                for expr in exprs {
6294                    if need_comma {
6295                        write!(ctx, ", ")?;
6296                    }
6297                    expr.demangle(ctx, scope)?;
6298                    need_comma = true;
6299                }
6300                write!(ctx, ")")?;
6301                Ok(())
6302            }
6303            Expression::ConversionBraced(ref ty, ref exprs) => {
6304                ty.demangle(ctx, scope)?;
6305                write!(ctx, "{{")?;
6306                let mut need_comma = false;
6307                for expr in exprs {
6308                    if need_comma {
6309                        write!(ctx, ", ")?;
6310                    }
6311                    expr.demangle(ctx, scope)?;
6312                    need_comma = true;
6313                }
6314                write!(ctx, "}}")?;
6315                Ok(())
6316            }
6317            Expression::BracedInitList(ref expr) => {
6318                write!(ctx, "{{")?;
6319                expr.demangle(ctx, scope)?;
6320                write!(ctx, "}}")?;
6321                Ok(())
6322            }
6323            // TODO: factor out all this duplication in the `new` variants.
6324            Expression::New(ref exprs, ref ty, ref init) => {
6325                write!(ctx, "new (")?;
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                ty.demangle(ctx, scope)?;
6336                if let Some(ref init) = *init {
6337                    init.demangle(ctx, scope)?;
6338                }
6339                Ok(())
6340            }
6341            Expression::GlobalNew(ref exprs, ref ty, ref init) => {
6342                write!(ctx, "::new (")?;
6343                let mut need_comma = false;
6344                for expr in exprs {
6345                    if need_comma {
6346                        write!(ctx, ", ")?;
6347                    }
6348                    expr.demangle(ctx, scope)?;
6349                    need_comma = true;
6350                }
6351                write!(ctx, ") ")?;
6352                ty.demangle(ctx, scope)?;
6353                if let Some(ref init) = *init {
6354                    init.demangle(ctx, scope)?;
6355                }
6356                Ok(())
6357            }
6358            Expression::NewArray(ref exprs, ref ty, ref init) => {
6359                write!(ctx, "new[] (")?;
6360                let mut need_comma = false;
6361                for expr in exprs {
6362                    if need_comma {
6363                        write!(ctx, ", ")?;
6364                    }
6365                    expr.demangle(ctx, scope)?;
6366                    need_comma = true;
6367                }
6368                write!(ctx, ") ")?;
6369                ty.demangle(ctx, scope)?;
6370                if let Some(ref init) = *init {
6371                    init.demangle(ctx, scope)?;
6372                }
6373                Ok(())
6374            }
6375            Expression::GlobalNewArray(ref exprs, ref ty, ref init) => {
6376                write!(ctx, "::new[] (")?;
6377                let mut need_comma = false;
6378                for expr in exprs {
6379                    if need_comma {
6380                        write!(ctx, ", ")?;
6381                    }
6382                    expr.demangle(ctx, scope)?;
6383                    need_comma = true;
6384                }
6385                write!(ctx, ") ")?;
6386                ty.demangle(ctx, scope)?;
6387                if let Some(ref init) = *init {
6388                    init.demangle(ctx, scope)?;
6389                }
6390                Ok(())
6391            }
6392            Expression::Delete(ref expr) => {
6393                write!(ctx, "delete ")?;
6394                expr.demangle(ctx, scope)
6395            }
6396            Expression::GlobalDelete(ref expr) => {
6397                write!(ctx, "::delete ")?;
6398                expr.demangle(ctx, scope)
6399            }
6400            Expression::DeleteArray(ref expr) => {
6401                write!(ctx, "delete[] ")?;
6402                expr.demangle(ctx, scope)
6403            }
6404            Expression::GlobalDeleteArray(ref expr) => {
6405                write!(ctx, "::delete[] ")?;
6406                expr.demangle(ctx, scope)
6407            }
6408            // TODO: factor out duplicated code from cast variants.
6409            Expression::DynamicCast(ref ty, ref expr) => {
6410                write!(ctx, "dynamic_cast<")?;
6411                ty.demangle(ctx, scope)?;
6412                write!(ctx, ">(")?;
6413                expr.demangle(ctx, scope)?;
6414                write!(ctx, ")")?;
6415                Ok(())
6416            }
6417            Expression::StaticCast(ref ty, ref expr) => {
6418                write!(ctx, "static_cast<")?;
6419                ty.demangle(ctx, scope)?;
6420                write!(ctx, ">(")?;
6421                expr.demangle(ctx, scope)?;
6422                write!(ctx, ")")?;
6423                Ok(())
6424            }
6425            Expression::ConstCast(ref ty, ref expr) => {
6426                write!(ctx, "const_cast<")?;
6427                ty.demangle(ctx, scope)?;
6428                write!(ctx, ">(")?;
6429                expr.demangle(ctx, scope)?;
6430                write!(ctx, ")")?;
6431                Ok(())
6432            }
6433            Expression::ReinterpretCast(ref ty, ref expr) => {
6434                write!(ctx, "reinterpret_cast<")?;
6435                ty.demangle(ctx, scope)?;
6436                write!(ctx, ">(")?;
6437                expr.demangle(ctx, scope)?;
6438                write!(ctx, ")")?;
6439                Ok(())
6440            }
6441            Expression::TypeidType(ref ty) => {
6442                write!(ctx, "typeid (")?;
6443                ty.demangle(ctx, scope)?;
6444                write!(ctx, ")")?;
6445                Ok(())
6446            }
6447            Expression::TypeidExpr(ref expr) => {
6448                write!(ctx, "typeid (")?;
6449                expr.demangle(ctx, scope)?;
6450                write!(ctx, ")")?;
6451                Ok(())
6452            }
6453            Expression::SizeofType(ref ty) => {
6454                write!(ctx, "sizeof (")?;
6455                ty.demangle(ctx, scope)?;
6456                write!(ctx, ")")?;
6457                Ok(())
6458            }
6459            Expression::SizeofExpr(ref expr) => {
6460                write!(ctx, "sizeof (")?;
6461                expr.demangle(ctx, scope)?;
6462                write!(ctx, ")")?;
6463                Ok(())
6464            }
6465            Expression::AlignofType(ref ty) => {
6466                write!(ctx, "alignof (")?;
6467                ty.demangle(ctx, scope)?;
6468                write!(ctx, ")")?;
6469                Ok(())
6470            }
6471            Expression::AlignofExpr(ref expr) => {
6472                write!(ctx, "alignof (")?;
6473                expr.demangle(ctx, scope)?;
6474                write!(ctx, ")")?;
6475                Ok(())
6476            }
6477            Expression::Noexcept(ref expr) => {
6478                write!(ctx, "noexcept (")?;
6479                expr.demangle(ctx, scope)?;
6480                write!(ctx, ")")?;
6481                Ok(())
6482            }
6483            Expression::Subobject(ref expr) => expr.demangle(ctx, scope),
6484            Expression::TemplateParam(ref param) => param.demangle(ctx, scope),
6485            Expression::FunctionParam(ref param) => param.demangle(ctx, scope),
6486            Expression::Member(ref expr, ref name) => {
6487                expr.demangle_as_subexpr(ctx, scope)?;
6488                write!(ctx, ".")?;
6489                name.demangle(ctx, scope)
6490            }
6491            Expression::DerefMember(ref expr, ref name) => {
6492                expr.demangle(ctx, scope)?;
6493                write!(ctx, "->")?;
6494                name.demangle(ctx, scope)
6495            }
6496            Expression::PointerToMember(ref e1, ref e2) => {
6497                e1.demangle(ctx, scope)?;
6498                write!(ctx, ".*")?;
6499                e2.demangle(ctx, scope)
6500            }
6501            Expression::SizeofTemplatePack(ref param) => {
6502                write!(ctx, "sizeof...(")?;
6503                param.demangle(ctx, scope)?;
6504                write!(ctx, ")")?;
6505                Ok(())
6506            }
6507            Expression::SizeofFunctionPack(ref param) => {
6508                write!(ctx, "sizeof...(")?;
6509                param.demangle(ctx, scope)?;
6510                write!(ctx, ")")?;
6511                Ok(())
6512            }
6513            Expression::SizeofCapturedTemplatePack(ref args) => {
6514                write!(ctx, "sizeof...(")?;
6515                let mut need_comma = false;
6516                for arg in args {
6517                    if need_comma {
6518                        write!(ctx, ", ")?;
6519                    }
6520                    arg.demangle(ctx, scope)?;
6521                    need_comma = true;
6522                }
6523                write!(ctx, ")")?;
6524                Ok(())
6525            }
6526            Expression::PackExpansion(ref pack) => {
6527                pack.demangle_as_subexpr(ctx, scope)?;
6528                write!(ctx, "...")?;
6529                Ok(())
6530            }
6531            Expression::Throw(ref expr) => {
6532                write!(ctx, "throw ")?;
6533                expr.demangle(ctx, scope)
6534            }
6535            Expression::Rethrow => {
6536                write!(ctx, "throw")?;
6537                Ok(())
6538            }
6539            Expression::UnresolvedName(ref name) => name.demangle(ctx, scope),
6540            Expression::Primary(ref expr) => expr.demangle(ctx, scope),
6541        }
6542    }
6543}
6544
6545impl Expression {
6546    fn demangle_as_subexpr<'subs, 'prev, 'ctx, W>(
6547        &'subs self,
6548        ctx: &'ctx mut DemangleContext<'subs, W>,
6549        scope: Option<ArgScopeStack<'prev, 'subs>>,
6550    ) -> fmt::Result
6551    where
6552        W: 'subs + DemangleWrite,
6553    {
6554        let needs_parens = match *self {
6555            Expression::FunctionParam(_) | Expression::Primary(ExprPrimary::External(_)) => false,
6556            _ => true,
6557        };
6558
6559        if needs_parens {
6560            write!(ctx, "(")?;
6561        }
6562
6563        self.demangle(ctx, scope)?;
6564
6565        if needs_parens {
6566            write!(ctx, ")")?;
6567        }
6568
6569        Ok(())
6570    }
6571}
6572
6573/// The `<unresolved-name>` production.
6574///
6575/// ```text
6576/// <unresolved-name> ::= [gs] <base-unresolved-name>
6577///                          #
6578///                   ::= sr <unresolved-type> <base-unresolved-name>
6579///                          #
6580///                   ::= srN <unresolved-type> <unresolved-qualifier-level>+ E <base-unresolved-name>
6581///                          #
6582///                   ::= [gs] sr <unresolved-qualifier-level>+ E <base-unresolved-name>
6583///                          # A::x, N::y, A<T>::z; "gs" means leading "::"
6584/// ```
6585#[derive(Clone, Debug, PartialEq, Eq)]
6586pub enum UnresolvedName {
6587    /// `x`
6588    Name(BaseUnresolvedName),
6589
6590    /// `::x`
6591    Global(BaseUnresolvedName),
6592
6593    /// `T::x`  or `decltype(p)::x` or `T::N::x` or `decltype(p)::N::x`
6594    Nested1(
6595        UnresolvedTypeHandle,
6596        Vec<UnresolvedQualifierLevel>,
6597        BaseUnresolvedName,
6598    ),
6599
6600    /// `A::x` or `N::y` or `A<T>::z`
6601    Nested2(Vec<UnresolvedQualifierLevel>, BaseUnresolvedName),
6602
6603    /// `::A::x` or `::N::y` or `::A<T>::z`
6604    GlobalNested2(Vec<UnresolvedQualifierLevel>, BaseUnresolvedName),
6605}
6606
6607impl Parse for UnresolvedName {
6608    fn parse<'a, 'b>(
6609        ctx: &'a ParseContext,
6610        subs: &'a mut SubstitutionTable,
6611        input: IndexStr<'b>,
6612    ) -> Result<(UnresolvedName, IndexStr<'b>)> {
6613        try_begin_parse!("UnresolvedName", ctx, input);
6614
6615        if let Ok(tail) = consume(b"gs", input) {
6616            if let Ok((name, tail)) = try_recurse!(BaseUnresolvedName::parse(ctx, subs, tail)) {
6617                return Ok((UnresolvedName::Global(name), tail));
6618            }
6619
6620            let tail = consume(b"sr", tail)?;
6621            let (levels, tail) = one_or_more::<UnresolvedQualifierLevel>(ctx, subs, tail)?;
6622            let tail = consume(b"E", tail)?;
6623            let (name, tail) = BaseUnresolvedName::parse(ctx, subs, tail)?;
6624            return Ok((UnresolvedName::GlobalNested2(levels, name), tail));
6625        }
6626
6627        if let Ok((name, tail)) = try_recurse!(BaseUnresolvedName::parse(ctx, subs, input)) {
6628            return Ok((UnresolvedName::Name(name), tail));
6629        }
6630
6631        let tail = consume(b"sr", input)?;
6632
6633        if tail.peek() == Some(b'N') {
6634            let tail = consume(b"N", tail).unwrap();
6635            let (ty, tail) = UnresolvedTypeHandle::parse(ctx, subs, tail)?;
6636            let (levels, tail) = one_or_more::<UnresolvedQualifierLevel>(ctx, subs, tail)?;
6637            let tail = consume(b"E", tail)?;
6638            let (name, tail) = BaseUnresolvedName::parse(ctx, subs, tail)?;
6639            return Ok((UnresolvedName::Nested1(ty, levels, name), tail));
6640        }
6641
6642        if let Ok((ty, tail)) = try_recurse!(UnresolvedTypeHandle::parse(ctx, subs, tail)) {
6643            let (name, tail) = BaseUnresolvedName::parse(ctx, subs, tail)?;
6644            return Ok((UnresolvedName::Nested1(ty, vec![], name), tail));
6645        }
6646
6647        let (levels, tail) = one_or_more::<UnresolvedQualifierLevel>(ctx, subs, tail)?;
6648        let tail = consume(b"E", tail)?;
6649        let (name, tail) = BaseUnresolvedName::parse(ctx, subs, tail)?;
6650        Ok((UnresolvedName::Nested2(levels, name), tail))
6651    }
6652}
6653
6654impl<'subs, W> Demangle<'subs, W> for UnresolvedName
6655where
6656    W: 'subs + DemangleWrite,
6657{
6658    fn demangle<'prev, 'ctx>(
6659        &'subs self,
6660        ctx: &'ctx mut DemangleContext<'subs, W>,
6661        scope: Option<ArgScopeStack<'prev, 'subs>>,
6662    ) -> fmt::Result {
6663        let ctx = try_begin_demangle!(self, ctx, scope);
6664
6665        match *self {
6666            UnresolvedName::Name(ref name) => name.demangle(ctx, scope),
6667            UnresolvedName::Global(ref name) => {
6668                write!(ctx, "::")?;
6669                name.demangle(ctx, scope)
6670            }
6671            UnresolvedName::Nested1(ref ty, ref levels, ref name) => {
6672                ty.demangle(ctx, scope)?;
6673                write!(ctx, "::")?;
6674                for lvl in &levels[..] {
6675                    lvl.demangle(ctx, scope)?;
6676                    write!(ctx, "::")?;
6677                }
6678                name.demangle(ctx, scope)
6679            }
6680            UnresolvedName::Nested2(ref levels, ref name) => {
6681                for lvl in &levels[..] {
6682                    lvl.demangle(ctx, scope)?;
6683                    write!(ctx, "::")?;
6684                }
6685                name.demangle(ctx, scope)
6686            }
6687            // `::A::x` or `::N::y` or `::A<T>::z`
6688            UnresolvedName::GlobalNested2(ref levels, ref name) => {
6689                write!(ctx, "::")?;
6690                for lvl in &levels[..] {
6691                    lvl.demangle(ctx, scope)?;
6692                    write!(ctx, "::")?;
6693                }
6694                name.demangle(ctx, scope)
6695            }
6696        }
6697    }
6698}
6699
6700/// The `<unresolved-type>` production.
6701///
6702/// ```text
6703/// <unresolved-type> ::= <template-param> [ <template-args> ]  # T:: or T<X,Y>::
6704///                   ::= <decltype>                            # decltype(p)::
6705///                   ::= <substitution>
6706/// ```
6707#[derive(Clone, Debug, PartialEq, Eq)]
6708pub enum UnresolvedType {
6709    /// An unresolved template type.
6710    Template(TemplateParam, Option<TemplateArgs>),
6711
6712    /// An unresolved `decltype`.
6713    Decltype(Decltype),
6714}
6715
6716define_handle! {
6717    /// A reference to a parsed `<unresolved-type>` production.
6718    pub enum UnresolvedTypeHandle
6719}
6720
6721impl Parse for UnresolvedTypeHandle {
6722    fn parse<'a, 'b>(
6723        ctx: &'a ParseContext,
6724        subs: &'a mut SubstitutionTable,
6725        input: IndexStr<'b>,
6726    ) -> Result<(UnresolvedTypeHandle, IndexStr<'b>)> {
6727        try_begin_parse!("UnresolvedTypeHandle", ctx, input);
6728
6729        if let Ok((param, tail)) = try_recurse!(TemplateParam::parse(ctx, subs, input)) {
6730            let (args, tail) =
6731                if let Ok((args, tail)) = try_recurse!(TemplateArgs::parse(ctx, subs, tail)) {
6732                    (Some(args), tail)
6733                } else {
6734                    (None, tail)
6735                };
6736            let ty = UnresolvedType::Template(param, args);
6737            let ty = Substitutable::UnresolvedType(ty);
6738            let idx = subs.insert(ty);
6739            let handle = UnresolvedTypeHandle::BackReference(idx);
6740            return Ok((handle, tail));
6741        }
6742
6743        if let Ok((decltype, tail)) = try_recurse!(Decltype::parse(ctx, subs, input)) {
6744            let ty = UnresolvedType::Decltype(decltype);
6745            let ty = Substitutable::UnresolvedType(ty);
6746            let idx = subs.insert(ty);
6747            let handle = UnresolvedTypeHandle::BackReference(idx);
6748            return Ok((handle, tail));
6749        }
6750
6751        let (sub, tail) = Substitution::parse(ctx, subs, input)?;
6752        match sub {
6753            Substitution::WellKnown(component) => {
6754                Ok((UnresolvedTypeHandle::WellKnown(component), tail))
6755            }
6756            Substitution::BackReference(idx) => {
6757                // TODO: should this check that the back reference actually
6758                // points to an `<unresolved-type>`?
6759                Ok((UnresolvedTypeHandle::BackReference(idx), tail))
6760            }
6761        }
6762    }
6763}
6764
6765impl<'subs, W> Demangle<'subs, W> for UnresolvedType
6766where
6767    W: 'subs + DemangleWrite,
6768{
6769    fn demangle<'prev, 'ctx>(
6770        &'subs self,
6771        ctx: &'ctx mut DemangleContext<'subs, W>,
6772        scope: Option<ArgScopeStack<'prev, 'subs>>,
6773    ) -> fmt::Result {
6774        let ctx = try_begin_demangle!(self, ctx, scope);
6775
6776        match *self {
6777            UnresolvedType::Decltype(ref dt) => dt.demangle(ctx, scope),
6778            UnresolvedType::Template(ref param, ref args) => {
6779                if let Some(ref args) = *args {
6780                    let scope = scope.push(args);
6781                    param.demangle(ctx, scope)?;
6782                    args.demangle(ctx, scope)?;
6783                } else {
6784                    param.demangle(ctx, scope)?;
6785                }
6786                Ok(())
6787            }
6788        }
6789    }
6790}
6791
6792/// The `<unresolved-qualifier-level>` production.
6793///
6794/// ```text
6795/// <unresolved-qualifier-level> ::= <simple-id>
6796/// ```
6797#[derive(Clone, Debug, PartialEq, Eq)]
6798pub struct UnresolvedQualifierLevel(SimpleId);
6799
6800impl Parse for UnresolvedQualifierLevel {
6801    fn parse<'a, 'b>(
6802        ctx: &'a ParseContext,
6803        subs: &'a mut SubstitutionTable,
6804        input: IndexStr<'b>,
6805    ) -> Result<(UnresolvedQualifierLevel, IndexStr<'b>)> {
6806        try_begin_parse!("UnresolvedQualifierLevel", ctx, input);
6807
6808        let (id, tail) = SimpleId::parse(ctx, subs, input)?;
6809        Ok((UnresolvedQualifierLevel(id), tail))
6810    }
6811}
6812
6813impl<'subs, W> Demangle<'subs, W> for UnresolvedQualifierLevel
6814where
6815    W: 'subs + DemangleWrite,
6816{
6817    #[inline]
6818    fn demangle<'prev, 'ctx>(
6819        &'subs self,
6820        ctx: &'ctx mut DemangleContext<'subs, W>,
6821        scope: Option<ArgScopeStack<'prev, 'subs>>,
6822    ) -> fmt::Result {
6823        let ctx = try_begin_demangle!(self, ctx, scope);
6824
6825        self.0.demangle(ctx, scope)
6826    }
6827}
6828
6829/// The `<simple-id>` production.
6830///
6831/// ```text
6832/// <simple-id> ::= <source-name> [ <template-args> ]
6833/// ```
6834#[derive(Clone, Debug, PartialEq, Eq)]
6835pub struct SimpleId(SourceName, Option<TemplateArgs>);
6836
6837impl Parse for SimpleId {
6838    fn parse<'a, 'b>(
6839        ctx: &'a ParseContext,
6840        subs: &'a mut SubstitutionTable,
6841        input: IndexStr<'b>,
6842    ) -> Result<(SimpleId, IndexStr<'b>)> {
6843        try_begin_parse!("SimpleId", ctx, input);
6844
6845        let (name, tail) = SourceName::parse(ctx, subs, input)?;
6846        let (args, tail) =
6847            if let Ok((args, tail)) = try_recurse!(TemplateArgs::parse(ctx, subs, tail)) {
6848                (Some(args), tail)
6849            } else {
6850                (None, tail)
6851            };
6852        Ok((SimpleId(name, args), tail))
6853    }
6854}
6855
6856impl<'subs, W> Demangle<'subs, W> for SimpleId
6857where
6858    W: 'subs + DemangleWrite,
6859{
6860    fn demangle<'prev, 'ctx>(
6861        &'subs self,
6862        ctx: &'ctx mut DemangleContext<'subs, W>,
6863        scope: Option<ArgScopeStack<'prev, 'subs>>,
6864    ) -> fmt::Result {
6865        let ctx = try_begin_demangle!(self, ctx, scope);
6866
6867        self.0.demangle(ctx, scope)?;
6868        if let Some(ref args) = self.1 {
6869            args.demangle(ctx, scope)?;
6870        }
6871        Ok(())
6872    }
6873}
6874
6875/// The `<base-unresolved-name>` production.
6876///
6877/// ```text
6878/// <base-unresolved-name> ::= <simple-id>                        # unresolved name
6879///                        ::= on <operator-name>                 # unresolved operator-function-id
6880///                        ::= on <operator-name> <template-args> # unresolved operator template-id
6881///                        ::= dn <destructor-name>               # destructor or pseudo-destructor;
6882///                                                               # e.g. ~X or ~X<N-1>
6883/// ```
6884#[derive(Clone, Debug, PartialEq, Eq)]
6885pub enum BaseUnresolvedName {
6886    /// An unresolved name.
6887    Name(SimpleId),
6888
6889    /// An unresolved function or template function name.
6890    Operator(OperatorName, Option<TemplateArgs>),
6891
6892    /// An unresolved destructor name.
6893    Destructor(DestructorName),
6894}
6895
6896impl Parse for BaseUnresolvedName {
6897    fn parse<'a, 'b>(
6898        ctx: &'a ParseContext,
6899        subs: &'a mut SubstitutionTable,
6900        input: IndexStr<'b>,
6901    ) -> Result<(BaseUnresolvedName, IndexStr<'b>)> {
6902        try_begin_parse!("BaseUnresolvedName", ctx, input);
6903
6904        if let Ok((name, tail)) = try_recurse!(SimpleId::parse(ctx, subs, input)) {
6905            return Ok((BaseUnresolvedName::Name(name), tail));
6906        }
6907
6908        if let Ok(tail) = consume(b"on", input) {
6909            let (opname, tail) = OperatorName::parse(ctx, subs, tail)?;
6910            let (args, tail) =
6911                if let Ok((args, tail)) = try_recurse!(TemplateArgs::parse(ctx, subs, tail)) {
6912                    (Some(args), tail)
6913                } else {
6914                    (None, tail)
6915                };
6916            return Ok((BaseUnresolvedName::Operator(opname, args), tail));
6917        }
6918
6919        let tail = consume(b"dn", input)?;
6920        let (name, tail) = DestructorName::parse(ctx, subs, tail)?;
6921        Ok((BaseUnresolvedName::Destructor(name), tail))
6922    }
6923}
6924
6925impl<'subs, W> Demangle<'subs, W> for BaseUnresolvedName
6926where
6927    W: 'subs + DemangleWrite,
6928{
6929    fn demangle<'prev, 'ctx>(
6930        &'subs self,
6931        ctx: &'ctx mut DemangleContext<'subs, W>,
6932        scope: Option<ArgScopeStack<'prev, 'subs>>,
6933    ) -> fmt::Result {
6934        let ctx = try_begin_demangle!(self, ctx, scope);
6935
6936        match *self {
6937            BaseUnresolvedName::Name(ref name) => name.demangle(ctx, scope),
6938            BaseUnresolvedName::Destructor(ref dtor) => dtor.demangle(ctx, scope),
6939            BaseUnresolvedName::Operator(ref op, ref args) => {
6940                op.demangle(ctx, scope)?;
6941                if let Some(ref args) = *args {
6942                    args.demangle(ctx, scope)?;
6943                }
6944                Ok(())
6945            }
6946        }
6947    }
6948}
6949
6950/// The `<destructor-name>` production.
6951///
6952/// ```text
6953/// <destructor-name> ::= <unresolved-type> # e.g., ~T or ~decltype(f())
6954///                   ::= <simple-id>       # e.g., ~A<2*N>
6955/// ```
6956#[derive(Clone, Debug, PartialEq, Eq)]
6957pub enum DestructorName {
6958    /// A destructor for an unresolved type.
6959    Unresolved(UnresolvedTypeHandle),
6960
6961    /// A destructor for a resolved type name.
6962    Name(SimpleId),
6963}
6964
6965impl Parse for DestructorName {
6966    fn parse<'a, 'b>(
6967        ctx: &'a ParseContext,
6968        subs: &'a mut SubstitutionTable,
6969        input: IndexStr<'b>,
6970    ) -> Result<(DestructorName, IndexStr<'b>)> {
6971        try_begin_parse!("DestructorName", ctx, input);
6972
6973        if let Ok((ty, tail)) = try_recurse!(UnresolvedTypeHandle::parse(ctx, subs, input)) {
6974            return Ok((DestructorName::Unresolved(ty), tail));
6975        }
6976
6977        let (name, tail) = SimpleId::parse(ctx, subs, input)?;
6978        Ok((DestructorName::Name(name), tail))
6979    }
6980}
6981
6982impl<'subs, W> Demangle<'subs, W> for DestructorName
6983where
6984    W: 'subs + DemangleWrite,
6985{
6986    fn demangle<'prev, 'ctx>(
6987        &'subs self,
6988        ctx: &'ctx mut DemangleContext<'subs, W>,
6989        scope: Option<ArgScopeStack<'prev, 'subs>>,
6990    ) -> fmt::Result {
6991        let ctx = try_begin_demangle!(self, ctx, scope);
6992
6993        write!(ctx, "~")?;
6994        match *self {
6995            DestructorName::Unresolved(ref ty) => ty.demangle(ctx, scope),
6996            DestructorName::Name(ref name) => name.demangle(ctx, scope),
6997        }
6998    }
6999}
7000
7001/// The `<expr-primary>` production.
7002///
7003/// ```text
7004/// <expr-primary> ::= L <type> <value number> E                        # integer literal
7005///                ::= L <type> <value float> E                         # floating literal
7006///                ::= L <string type> E                                # string literal
7007///                ::= L <nullptr type> E                               # nullptr literal (i.e., "LDnE")
7008///                ::= L <pointer type> 0 E                             # null pointer template argument
7009///                ::= L <type> <real-part float> _ <imag-part float> E # complex floating point literal (C 2000)
7010///                ::= L <mangled-name> E                               # external name
7011/// ```
7012#[derive(Clone, Debug, PartialEq, Eq)]
7013pub enum ExprPrimary {
7014    /// A type literal.
7015    Literal(TypeHandle, usize, usize),
7016
7017    /// An external name.
7018    External(MangledName),
7019}
7020
7021impl Parse for ExprPrimary {
7022    fn parse<'a, 'b>(
7023        ctx: &'a ParseContext,
7024        subs: &'a mut SubstitutionTable,
7025        input: IndexStr<'b>,
7026    ) -> Result<(ExprPrimary, IndexStr<'b>)> {
7027        try_begin_parse!("ExprPrimary", ctx, input);
7028
7029        let tail = consume(b"L", input)?;
7030
7031        if let Ok((ty, tail)) = try_recurse!(TypeHandle::parse(ctx, subs, tail)) {
7032            let start = tail.index();
7033            let num_bytes_in_literal = tail.as_ref().iter().take_while(|&&c| c != b'E').count();
7034            let tail = tail.range_from(num_bytes_in_literal..);
7035            let end = tail.index();
7036            let tail = consume(b"E", tail)?;
7037            let expr = ExprPrimary::Literal(ty, start, end);
7038            return Ok((expr, tail));
7039        }
7040
7041        let (name, tail) = MangledName::parse(ctx, subs, tail)?;
7042        let tail = consume(b"E", tail)?;
7043        let expr = ExprPrimary::External(name);
7044        Ok((expr, tail))
7045    }
7046}
7047
7048impl<'subs, W> Demangle<'subs, W> for ExprPrimary
7049where
7050    W: 'subs + DemangleWrite,
7051{
7052    fn demangle<'prev, 'ctx>(
7053        &'subs self,
7054        ctx: &'ctx mut DemangleContext<'subs, W>,
7055        scope: Option<ArgScopeStack<'prev, 'subs>>,
7056    ) -> fmt::Result {
7057        let ctx = try_begin_demangle!(self, ctx, scope);
7058
7059        fn write_literal<W>(ctx: &mut DemangleContext<W>, start: usize, end: usize) -> fmt::Result
7060        where
7061            W: DemangleWrite,
7062        {
7063            debug_assert!(start <= end);
7064            let start = if start < end && ctx.input[start] == b'n' {
7065                write!(ctx, "-")?;
7066                start + 1
7067            } else {
7068                start
7069            };
7070            let s = str::from_utf8(&ctx.input[start..end]).map_err(|e| {
7071                log!("Error writing literal: {}", e);
7072                fmt::Error
7073            })?;
7074            ctx.write_str(s)
7075        }
7076
7077        match *self {
7078            ExprPrimary::External(ref name) => {
7079                let saved_show_params = ctx.show_params;
7080                ctx.show_params = true;
7081                let ret = name.demangle(ctx, scope);
7082                ctx.show_params = saved_show_params;
7083                ret
7084            }
7085            ExprPrimary::Literal(
7086                TypeHandle::Builtin(BuiltinType::Standard(StandardBuiltinType::Bool)),
7087                start,
7088                end,
7089            ) => match &ctx.input[start..end] {
7090                b"0" => write!(ctx, "false"),
7091                b"1" => write!(ctx, "true"),
7092                _ => {
7093                    write!(ctx, "(bool)")?;
7094                    write_literal(ctx, start, end)
7095                }
7096            },
7097            ExprPrimary::Literal(
7098                TypeHandle::Builtin(BuiltinType::Standard(StandardBuiltinType::Nullptr)),
7099                _,
7100                _,
7101            ) => write!(ctx, "nullptr"),
7102            ExprPrimary::Literal(
7103                ref ty @ TypeHandle::Builtin(BuiltinType::Standard(StandardBuiltinType::Double)),
7104                start,
7105                end,
7106            )
7107            | ExprPrimary::Literal(
7108                ref ty @ TypeHandle::Builtin(BuiltinType::Standard(StandardBuiltinType::Float)),
7109                start,
7110                end,
7111            ) => {
7112                if ctx.show_expression_literal_types {
7113                    write!(ctx, "(")?;
7114                    ty.demangle(ctx, scope)?;
7115                    write!(ctx, ")")?;
7116                }
7117                let start = if start < end && ctx.input[start] == b'n' {
7118                    write!(ctx, "-[")?;
7119                    start + 1
7120                } else {
7121                    write!(ctx, "[")?;
7122                    start
7123                };
7124                let s = str::from_utf8(&ctx.input[start..end]).map_err(|e| {
7125                    log!("Error writing literal: {}", e);
7126                    fmt::Error
7127                })?;
7128                ctx.write_str(s)?;
7129                write!(ctx, "]")
7130            }
7131            ExprPrimary::Literal(
7132                TypeHandle::Builtin(BuiltinType::Standard(StandardBuiltinType::Int)),
7133                start,
7134                end,
7135            ) => write_literal(ctx, start, end),
7136            ExprPrimary::Literal(ref ty, start, end) => {
7137                if ctx.show_expression_literal_types {
7138                    write!(ctx, "(")?;
7139                    ty.demangle(ctx, scope)?;
7140                    write!(ctx, ")")?;
7141                }
7142                write_literal(ctx, start, end)
7143            }
7144        }
7145    }
7146}
7147
7148/// The `<initializer>` production.
7149///
7150/// ```text
7151/// <initializer> ::= pi <expression>* E # parenthesized initialization
7152/// ```
7153#[derive(Clone, Debug, PartialEq, Eq)]
7154pub struct Initializer(Vec<Expression>);
7155
7156impl Parse for Initializer {
7157    fn parse<'a, 'b>(
7158        ctx: &'a ParseContext,
7159        subs: &'a mut SubstitutionTable,
7160        input: IndexStr<'b>,
7161    ) -> Result<(Initializer, IndexStr<'b>)> {
7162        try_begin_parse!("Initializer", ctx, input);
7163
7164        let tail = consume(b"pi", input)?;
7165        let (exprs, tail) = zero_or_more::<Expression>(ctx, subs, tail)?;
7166        let tail = consume(b"E", tail)?;
7167        Ok((Initializer(exprs), tail))
7168    }
7169}
7170
7171impl<'subs, W> Demangle<'subs, W> for Initializer
7172where
7173    W: 'subs + DemangleWrite,
7174{
7175    fn demangle<'prev, 'ctx>(
7176        &'subs self,
7177        ctx: &'ctx mut DemangleContext<'subs, W>,
7178        scope: Option<ArgScopeStack<'prev, 'subs>>,
7179    ) -> fmt::Result {
7180        let ctx = try_begin_demangle!(self, ctx, scope);
7181
7182        write!(ctx, "(")?;
7183        let mut need_comma = false;
7184        for expr in &self.0 {
7185            if need_comma {
7186                write!(ctx, ", ")?;
7187            }
7188            expr.demangle(ctx, scope)?;
7189            need_comma = true;
7190        }
7191        write!(ctx, ")")?;
7192        Ok(())
7193    }
7194}
7195
7196/// The `<local-name>` production.
7197///
7198/// ```text
7199/// <local-name> := Z <function encoding> E <entity name> [<discriminator>]
7200///              := Z <function encoding> E s [<discriminator>]
7201///              := Z <function encoding> Ed [ <parameter number> ] _ <entity name>
7202/// ```
7203#[derive(Clone, Debug, PartialEq, Eq)]
7204pub enum LocalName {
7205    /// The mangling of the enclosing function, the mangling of the entity
7206    /// relative to the function, and an optional discriminator.
7207    Relative(Box<Encoding>, Option<Box<Name>>, Option<Discriminator>),
7208
7209    /// A default argument in a class definition.
7210    Default(Box<Encoding>, Option<usize>, Box<Name>),
7211}
7212
7213impl Parse for LocalName {
7214    fn parse<'a, 'b>(
7215        ctx: &'a ParseContext,
7216        subs: &'a mut SubstitutionTable,
7217        input: IndexStr<'b>,
7218    ) -> Result<(LocalName, IndexStr<'b>)> {
7219        try_begin_parse!("LocalName", ctx, input);
7220
7221        let tail = consume(b"Z", input)?;
7222        let (encoding, tail) = Encoding::parse(ctx, subs, tail)?;
7223        let tail = consume(b"E", tail)?;
7224
7225        if let Ok(tail) = consume(b"s", tail) {
7226            let (disc, tail) =
7227                if let Ok((disc, tail)) = try_recurse!(Discriminator::parse(ctx, subs, tail)) {
7228                    (Some(disc), tail)
7229                } else {
7230                    (None, tail)
7231                };
7232            return Ok((LocalName::Relative(Box::new(encoding), None, disc), tail));
7233        }
7234
7235        if let Ok(tail) = consume(b"d", tail) {
7236            let (param, tail) =
7237                if let Ok((num, tail)) = try_recurse!(Number::parse(ctx, subs, tail)) {
7238                    (Some(num as _), tail)
7239                } else {
7240                    (None, tail)
7241                };
7242            let tail = consume(b"_", tail)?;
7243            let (name, tail) = Name::parse(ctx, subs, tail)?;
7244            return Ok((
7245                LocalName::Default(Box::new(encoding), param, Box::new(name)),
7246                tail,
7247            ));
7248        }
7249
7250        let (name, tail) = Name::parse(ctx, subs, tail)?;
7251        let (disc, tail) =
7252            if let Ok((disc, tail)) = try_recurse!(Discriminator::parse(ctx, subs, tail)) {
7253                (Some(disc), tail)
7254            } else {
7255                (None, tail)
7256            };
7257
7258        Ok((
7259            LocalName::Relative(Box::new(encoding), Some(Box::new(name)), disc),
7260            tail,
7261        ))
7262    }
7263}
7264
7265impl<'subs, W> Demangle<'subs, W> for LocalName
7266where
7267    W: 'subs + DemangleWrite,
7268{
7269    fn demangle<'prev, 'ctx>(
7270        &'subs self,
7271        ctx: &'ctx mut DemangleContext<'subs, W>,
7272        scope: Option<ArgScopeStack<'prev, 'subs>>,
7273    ) -> fmt::Result {
7274        let ctx = try_begin_demangle!(self, ctx, scope);
7275
7276        let saved_show_params = ctx.show_params;
7277        ctx.show_params = true;
7278        let ret = match *self {
7279            LocalName::Relative(ref encoding, Some(ref name), _) => {
7280                encoding.demangle(ctx, scope)?;
7281                write!(ctx, "::")?;
7282                name.demangle(ctx, scope)
7283            }
7284            LocalName::Relative(ref encoding, None, _) => {
7285                // No name means that this is the symbol for a string literal.
7286                encoding.demangle(ctx, scope)?;
7287                write!(ctx, "::string literal")?;
7288                Ok(())
7289            }
7290            LocalName::Default(ref encoding, _, _) => encoding.demangle(ctx, scope),
7291        };
7292        ctx.show_params = saved_show_params;
7293        ret
7294    }
7295}
7296
7297impl GetTemplateArgs for LocalName {
7298    fn get_template_args<'a>(&'a self, subs: &'a SubstitutionTable) -> Option<&'a TemplateArgs> {
7299        match *self {
7300            LocalName::Relative(_, None, _) => None,
7301            LocalName::Relative(_, Some(ref name), _) | LocalName::Default(_, _, ref name) => {
7302                name.get_template_args(subs)
7303            }
7304        }
7305    }
7306}
7307
7308impl<'a> GetLeafName<'a> for LocalName {
7309    fn get_leaf_name(&'a self, subs: &'a SubstitutionTable) -> Option<LeafName<'a>> {
7310        match *self {
7311            LocalName::Relative(_, None, _) => None,
7312            LocalName::Relative(_, Some(ref name), _) | LocalName::Default(_, _, ref name) => {
7313                name.get_leaf_name(subs)
7314            }
7315        }
7316    }
7317}
7318
7319/// The `<discriminator>` production.
7320///
7321/// ```text
7322/// <discriminator> := _ <non-negative number>      # when number < 10
7323///                 := __ <non-negative number> _   # when number >= 10
7324/// ```
7325#[derive(Clone, Debug, PartialEq, Eq)]
7326pub struct Discriminator(usize);
7327
7328impl Parse for Discriminator {
7329    fn parse<'a, 'b>(
7330        ctx: &'a ParseContext,
7331        _subs: &'a mut SubstitutionTable,
7332        input: IndexStr<'b>,
7333    ) -> Result<(Discriminator, IndexStr<'b>)> {
7334        try_begin_parse!("Discriminator", ctx, input);
7335
7336        let tail = consume(b"_", input)?;
7337
7338        if let Ok(tail) = consume(b"_", tail) {
7339            let (num, tail) = parse_number(10, false, tail)?;
7340            debug_assert!(num >= 0);
7341            if num < 10 {
7342                return Err(error::Error::UnexpectedText);
7343            }
7344            let tail = consume(b"_", tail)?;
7345            return Ok((Discriminator(num as _), tail));
7346        }
7347
7348        match tail.try_split_at(1) {
7349            None => Err(error::Error::UnexpectedEnd),
7350            Some((head, tail)) => match head.as_ref()[0] {
7351                b'0' => Ok((Discriminator(0), tail)),
7352                b'1' => Ok((Discriminator(1), tail)),
7353                b'2' => Ok((Discriminator(2), tail)),
7354                b'3' => Ok((Discriminator(3), tail)),
7355                b'4' => Ok((Discriminator(4), tail)),
7356                b'5' => Ok((Discriminator(5), tail)),
7357                b'6' => Ok((Discriminator(6), tail)),
7358                b'7' => Ok((Discriminator(7), tail)),
7359                b'8' => Ok((Discriminator(8), tail)),
7360                b'9' => Ok((Discriminator(9), tail)),
7361                _ => Err(error::Error::UnexpectedText),
7362            },
7363        }
7364    }
7365}
7366
7367/// The `<closure-type-name>` production.
7368///
7369/// ```text
7370/// <closure-type-name> ::= Ul <lambda-sig> E [ <nonnegative number> ] _
7371/// ```
7372#[derive(Clone, Debug, PartialEq, Eq)]
7373pub struct ClosureTypeName(LambdaSig, Option<usize>);
7374
7375impl Parse for ClosureTypeName {
7376    fn parse<'a, 'b>(
7377        ctx: &'a ParseContext,
7378        subs: &'a mut SubstitutionTable,
7379        input: IndexStr<'b>,
7380    ) -> Result<(ClosureTypeName, IndexStr<'b>)> {
7381        try_begin_parse!("ClosureTypeName", ctx, input);
7382
7383        let tail = consume(b"Ul", input)?;
7384        let (sig, tail) = LambdaSig::parse(ctx, subs, tail)?;
7385        let tail = consume(b"E", tail)?;
7386        let (num, tail) = if let Ok((num, tail)) = parse_number(10, false, tail) {
7387            (Some(num as _), tail)
7388        } else {
7389            (None, tail)
7390        };
7391        let tail = consume(b"_", tail)?;
7392        Ok((ClosureTypeName(sig, num), tail))
7393    }
7394}
7395
7396impl<'subs, W> Demangle<'subs, W> for ClosureTypeName
7397where
7398    W: 'subs + DemangleWrite,
7399{
7400    fn demangle<'prev, 'ctx>(
7401        &'subs self,
7402        ctx: &'ctx mut DemangleContext<'subs, W>,
7403        scope: Option<ArgScopeStack<'prev, 'subs>>,
7404    ) -> fmt::Result {
7405        let ctx = try_begin_demangle!(self, ctx, scope);
7406
7407        write!(ctx, "{{lambda(")?;
7408        self.0.demangle(ctx, scope)?;
7409        write!(ctx, ")#{}}}", self.1.map_or(1, |n| n + 2))?;
7410        Ok(())
7411    }
7412}
7413
7414impl<'subs> ArgScope<'subs, 'subs> for ClosureTypeName {
7415    fn leaf_name(&'subs self) -> Result<LeafName<'subs>> {
7416        Ok(LeafName::Closure(self))
7417    }
7418
7419    fn get_template_arg(
7420        &'subs self,
7421        _: usize,
7422    ) -> Result<(&'subs TemplateArg, &'subs TemplateArgs)> {
7423        Err(error::Error::BadTemplateArgReference)
7424    }
7425
7426    fn get_function_arg(&'subs self, _: usize) -> Result<&'subs Type> {
7427        Err(error::Error::BadFunctionArgReference)
7428    }
7429}
7430
7431impl<'a> GetLeafName<'a> for ClosureTypeName {
7432    #[inline]
7433    fn get_leaf_name(&'a self, _: &'a SubstitutionTable) -> Option<LeafName<'a>> {
7434        Some(LeafName::Closure(self))
7435    }
7436}
7437
7438impl ClosureTypeName {
7439    #[inline]
7440    fn starts_with(byte: u8, input: &IndexStr) -> bool {
7441        byte == b'U' && input.peek_second().map(|b| b == b'l').unwrap_or(false)
7442    }
7443}
7444
7445/// The `<lambda-sig>` production.
7446///
7447/// ```text
7448/// <lambda-sig> ::= <parameter type>+  # Parameter types or "v" if the lambda has no parameters
7449/// ```
7450#[derive(Clone, Debug, PartialEq, Eq)]
7451pub struct LambdaSig(Vec<TypeHandle>);
7452
7453impl LambdaSig {
7454    fn demangle_args<'subs, 'prev, 'ctx, W>(
7455        &'subs self,
7456        ctx: &'ctx mut DemangleContext<'subs, W>,
7457        scope: Option<ArgScopeStack<'prev, 'subs>>,
7458    ) -> fmt::Result
7459    where
7460        W: 'subs + DemangleWrite,
7461    {
7462        let mut need_comma = false;
7463        for ty in &self.0 {
7464            if need_comma {
7465                write!(ctx, ", ")?;
7466            }
7467            ty.demangle(ctx, scope)?;
7468            need_comma = true;
7469        }
7470        Ok(())
7471    }
7472}
7473
7474impl Parse for LambdaSig {
7475    fn parse<'a, 'b>(
7476        ctx: &'a ParseContext,
7477        subs: &'a mut SubstitutionTable,
7478        input: IndexStr<'b>,
7479    ) -> Result<(LambdaSig, IndexStr<'b>)> {
7480        try_begin_parse!("LambdaSig", ctx, input);
7481
7482        let (types, tail) = if let Ok(tail) = consume(b"v", input) {
7483            (vec![], tail)
7484        } else {
7485            one_or_more::<TypeHandle>(ctx, subs, input)?
7486        };
7487        Ok((LambdaSig(types), tail))
7488    }
7489}
7490
7491impl<'subs, W> Demangle<'subs, W> for LambdaSig
7492where
7493    W: 'subs + DemangleWrite,
7494{
7495    fn demangle<'prev, 'ctx>(
7496        &'subs self,
7497        ctx: &'ctx mut DemangleContext<'subs, W>,
7498        scope: Option<ArgScopeStack<'prev, 'subs>>,
7499    ) -> fmt::Result {
7500        let ctx = try_begin_demangle!(self, ctx, scope);
7501
7502        ctx.is_lambda_arg = true;
7503        let r = self.demangle_args(ctx, scope);
7504        ctx.is_lambda_arg = false;
7505        r
7506    }
7507}
7508
7509/// The `<data-member-prefix>` production.
7510///
7511/// ```text
7512/// <data-member-prefix> := <member source-name> M
7513/// ```
7514#[derive(Clone, Debug, PartialEq, Eq)]
7515pub struct DataMemberPrefix(SourceName);
7516
7517impl Parse for DataMemberPrefix {
7518    fn parse<'a, 'b>(
7519        ctx: &'a ParseContext,
7520        subs: &'a mut SubstitutionTable,
7521        input: IndexStr<'b>,
7522    ) -> Result<(DataMemberPrefix, IndexStr<'b>)> {
7523        try_begin_parse!("DataMemberPrefix", ctx, input);
7524
7525        let (name, tail) = SourceName::parse(ctx, subs, input)?;
7526        let tail = consume(b"M", tail)?;
7527        Ok((DataMemberPrefix(name), tail))
7528    }
7529}
7530
7531impl<'a> GetLeafName<'a> for DataMemberPrefix {
7532    #[inline]
7533    fn get_leaf_name(&'a self, _: &'a SubstitutionTable) -> Option<LeafName<'a>> {
7534        Some(LeafName::SourceName(&self.0))
7535    }
7536}
7537
7538impl<'subs, W> Demangle<'subs, W> for DataMemberPrefix
7539where
7540    W: 'subs + DemangleWrite,
7541{
7542    #[inline]
7543    fn demangle<'prev, 'ctx>(
7544        &'subs self,
7545        ctx: &'ctx mut DemangleContext<'subs, W>,
7546        scope: Option<ArgScopeStack<'prev, 'subs>>,
7547    ) -> fmt::Result {
7548        let ctx = try_begin_demangle!(self, ctx, scope);
7549
7550        ctx.push_demangle_node(DemangleNodeType::DataMemberPrefix);
7551        let ret = self.0.demangle(ctx, scope);
7552        ctx.pop_demangle_node();
7553        ret
7554    }
7555}
7556
7557/// The `<substitution>` form: a back-reference to some component we've already
7558/// parsed.
7559///
7560/// ```text
7561/// <substitution> ::= S <seq-id> _
7562///                ::= S_
7563///                ::= St # ::std::
7564///                ::= Sa # ::std::allocator
7565///                ::= Sb # ::std::basic_string
7566///                ::= Ss # ::std::basic_string < char,
7567///                                               ::std::char_traits<char>,
7568///                                               ::std::allocator<char> >
7569///                ::= Si # ::std::basic_istream<char,  std::char_traits<char> >
7570///                ::= So # ::std::basic_ostream<char,  std::char_traits<char> >
7571///                ::= Sd # ::std::basic_iostream<char, std::char_traits<char> >
7572/// ```
7573#[derive(Clone, Debug, PartialEq, Eq)]
7574pub enum Substitution {
7575    /// A reference to an entity that already occurred, ie the `S_` and `S
7576    /// <seq-id> _` forms.
7577    BackReference(usize),
7578
7579    /// A well-known substitution component. These are the components that do
7580    /// not appear in the substitution table, but have abbreviations specified
7581    /// directly in the grammar.
7582    WellKnown(WellKnownComponent),
7583}
7584
7585impl Parse for Substitution {
7586    fn parse<'a, 'b>(
7587        ctx: &'a ParseContext,
7588        subs: &'a mut SubstitutionTable,
7589        input: IndexStr<'b>,
7590    ) -> Result<(Substitution, IndexStr<'b>)> {
7591        try_begin_parse!("Substitution", ctx, input);
7592
7593        if let Ok((well_known, tail)) = try_recurse!(WellKnownComponent::parse(ctx, subs, input)) {
7594            return Ok((Substitution::WellKnown(well_known), tail));
7595        }
7596
7597        let tail = consume(b"S", input)?;
7598        let (idx, tail) = if let Ok((idx, tail)) = try_recurse!(SeqId::parse(ctx, subs, tail)) {
7599            (idx.0 + 1, tail)
7600        } else {
7601            (0, tail)
7602        };
7603
7604        if !subs.contains(idx) {
7605            return Err(error::Error::BadBackReference);
7606        }
7607
7608        let tail = consume(b"_", tail)?;
7609        log!("Found a reference to @ {}", idx);
7610        Ok((Substitution::BackReference(idx), tail))
7611    }
7612}
7613
7614define_vocabulary! {
7615/// The `<substitution>` variants that are encoded directly in the grammar,
7616/// rather than as back references to other components in the substitution
7617/// table.
7618    #[derive(Clone, Debug, PartialEq, Eq)]
7619    pub enum WellKnownComponent {
7620        Std          (b"St", "std"),
7621        StdAllocator (b"Sa", "std::allocator"),
7622        StdString1   (b"Sb", "std::basic_string"),
7623        StdString2   (b"Ss", "std::string"),
7624        StdIstream   (b"Si", "std::basic_istream<char, std::char_traits<char> >"),
7625        StdOstream   (b"So", "std::ostream"),
7626        StdIostream  (b"Sd", "std::basic_iostream<char, std::char_traits<char> >")
7627    }
7628}
7629
7630impl<'a> GetLeafName<'a> for WellKnownComponent {
7631    fn get_leaf_name(&'a self, _: &'a SubstitutionTable) -> Option<LeafName<'a>> {
7632        match *self {
7633            WellKnownComponent::Std => None,
7634            _ => Some(LeafName::WellKnownComponent(self)),
7635        }
7636    }
7637}
7638
7639impl<'a> ArgScope<'a, 'a> for WellKnownComponent {
7640    fn leaf_name(&'a self) -> Result<LeafName<'a>> {
7641        Ok(LeafName::WellKnownComponent(self))
7642    }
7643
7644    fn get_template_arg(&'a self, _: usize) -> Result<(&'a TemplateArg, &'a TemplateArgs)> {
7645        Err(error::Error::BadTemplateArgReference)
7646    }
7647
7648    fn get_function_arg(&'a self, _: usize) -> Result<&'a Type> {
7649        Err(error::Error::BadFunctionArgReference)
7650    }
7651}
7652
7653impl<'subs, W> DemangleAsLeaf<'subs, W> for WellKnownComponent
7654where
7655    W: 'subs + DemangleWrite,
7656{
7657    fn demangle_as_leaf<'me, 'ctx>(
7658        &'me self,
7659        ctx: &'ctx mut DemangleContext<'subs, W>,
7660    ) -> fmt::Result {
7661        match *self {
7662            WellKnownComponent::Std => {
7663                panic!("should never treat `WellKnownComponent::Std` as a leaf name")
7664            }
7665            WellKnownComponent::StdAllocator => write!(ctx, "allocator"),
7666            WellKnownComponent::StdString1 => write!(ctx, "basic_string"),
7667            WellKnownComponent::StdString2 => write!(ctx, "string"),
7668            WellKnownComponent::StdIstream => write!(ctx, "basic_istream"),
7669            WellKnownComponent::StdOstream => write!(ctx, "ostream"),
7670            WellKnownComponent::StdIostream => write!(ctx, "basic_iostream"),
7671        }
7672    }
7673}
7674
7675/// The `<special-name>` production.
7676///
7677/// The `<special-name>` production is spread in pieces through out the ABI
7678/// spec, and then there are a bunch of `g++` extensions that have become de
7679/// facto.
7680///
7681/// ### 5.1.4.1 Virtual Tables and RTTI
7682///
7683/// ```text
7684/// <special-name> ::= TV <type>    # virtual table
7685///                ::= TT <type>    # VTT structure (construction vtable index)
7686///                ::= TI <type>    # typeinfo structure
7687///                ::= TS <type>    # typeinfo name (null-terminated byte string)
7688/// ```
7689///
7690/// ### 5.1.4.2 Virtual Override Thunks
7691///
7692/// ```text
7693/// <special-name> ::= T <call-offset> <base encoding>
7694///     # base is the nominal target function of thunk
7695///
7696/// <special-name> ::= Tc <call-offset> <call-offset> <base encoding>
7697///     # base is the nominal target function of thunk
7698///     # first call-offset is 'this' adjustment
7699///     # second call-offset is result adjustment
7700/// ```
7701///
7702/// ### 5.1.4.4 Guard Variables
7703///
7704/// ```text
7705/// <special-name> ::= GV <object name> # Guard variable for one-time initialization
7706///     # No <type>
7707/// ```
7708///
7709/// ### 5.1.4.5 Lifetime-Extended Temporaries
7710///
7711/// ```text
7712/// <special-name> ::= GR <object name> _             # First temporary
7713/// <special-name> ::= GR <object name> <seq-id> _    # Subsequent temporaries
7714/// ```
7715///
7716/// ### De Facto Standard Extensions
7717///
7718/// ```text
7719/// <special-name> ::= TC <type> <number> _ <type>    # construction vtable
7720///                ::= TF <type>                      # typinfo function
7721///                ::= TH <name>                      # TLS initialization function
7722///                ::= TW <name>                      # TLS wrapper function
7723///                ::= Gr <resource name>             # Java Resource
7724///                ::= GTt <encoding>                 # Transaction-Safe function
7725///                ::= GTn <encoding>                 # Non-Transaction-Safe function
7726/// ```
7727#[derive(Clone, Debug, PartialEq, Eq)]
7728pub enum SpecialName {
7729    /// A virtual table.
7730    VirtualTable(TypeHandle),
7731
7732    /// A VTT structure (construction vtable index).
7733    Vtt(TypeHandle),
7734
7735    /// A typeinfo structure.
7736    Typeinfo(TypeHandle),
7737
7738    /// A typeinfo name (null-terminated byte string).
7739    TypeinfoName(TypeHandle),
7740
7741    /// A virtual override thunk.
7742    VirtualOverrideThunk(CallOffset, Box<Encoding>),
7743
7744    /// A virtual override thunk with a covariant return type.
7745    VirtualOverrideThunkCovariant(CallOffset, CallOffset, Box<Encoding>),
7746
7747    /// An initialization guard for some static storage.
7748    Guard(Name),
7749
7750    /// A temporary used in the initialization of a static storage and promoted
7751    /// to a static lifetime.
7752    GuardTemporary(Name, usize),
7753
7754    /// A construction vtable structure.
7755    ConstructionVtable(TypeHandle, usize, TypeHandle),
7756
7757    /// A typeinfo function.
7758    TypeinfoFunction(TypeHandle),
7759
7760    /// A TLS initialization function.
7761    TlsInit(Name),
7762
7763    /// A TLS wrapper function.
7764    TlsWrapper(Name),
7765
7766    /// A Java Resource.
7767    JavaResource(Vec<ResourceName>),
7768
7769    /// A function declared transaction-safe
7770    TransactionClone(Box<Encoding>),
7771
7772    /// A function declared non-transaction-safe
7773    NonTransactionClone(Box<Encoding>),
7774}
7775
7776impl Parse for SpecialName {
7777    fn parse<'a, 'b>(
7778        ctx: &'a ParseContext,
7779        subs: &'a mut SubstitutionTable,
7780        input: IndexStr<'b>,
7781    ) -> Result<(SpecialName, IndexStr<'b>)> {
7782        try_begin_parse!("SpecialName", ctx, input);
7783
7784        let (head, tail) = match input.try_split_at(2) {
7785            None => return Err(error::Error::UnexpectedEnd),
7786            Some((head, tail)) => (head, tail),
7787        };
7788
7789        match head.as_ref() {
7790            b"TV" => {
7791                let (ty, tail) = TypeHandle::parse(ctx, subs, tail)?;
7792                Ok((SpecialName::VirtualTable(ty), tail))
7793            }
7794            b"TT" => {
7795                let (ty, tail) = TypeHandle::parse(ctx, subs, tail)?;
7796                Ok((SpecialName::Vtt(ty), tail))
7797            }
7798            b"TI" => {
7799                let (ty, tail) = TypeHandle::parse(ctx, subs, tail)?;
7800                Ok((SpecialName::Typeinfo(ty), tail))
7801            }
7802            b"TS" => {
7803                let (ty, tail) = TypeHandle::parse(ctx, subs, tail)?;
7804                Ok((SpecialName::TypeinfoName(ty), tail))
7805            }
7806            b"Tc" => {
7807                let (first, tail) = CallOffset::parse(ctx, subs, tail)?;
7808                let (second, tail) = CallOffset::parse(ctx, subs, tail)?;
7809                let (base, tail) = Encoding::parse(ctx, subs, tail)?;
7810                Ok((
7811                    SpecialName::VirtualOverrideThunkCovariant(first, second, Box::new(base)),
7812                    tail,
7813                ))
7814            }
7815            b"Th" | b"Tv" => {
7816                // The "h"/"v" is part of the `<call-offset>`, so back up to the
7817                // `input`.
7818                let tail = consume(b"T", input).unwrap();
7819                let (offset, tail) = CallOffset::parse(ctx, subs, tail)?;
7820                let (base, tail) = Encoding::parse(ctx, subs, tail)?;
7821                Ok((
7822                    SpecialName::VirtualOverrideThunk(offset, Box::new(base)),
7823                    tail,
7824                ))
7825            }
7826            b"TC" => {
7827                let (ty1, tail) = TypeHandle::parse(ctx, subs, tail)?;
7828                let (n, tail) = parse_number(10, false, tail)?;
7829                let tail = consume(b"_", tail)?;
7830                let (ty2, tail) = TypeHandle::parse(ctx, subs, tail)?;
7831                Ok((SpecialName::ConstructionVtable(ty1, n as usize, ty2), tail))
7832            }
7833            b"TF" => {
7834                let (ty, tail) = TypeHandle::parse(ctx, subs, tail)?;
7835                Ok((SpecialName::TypeinfoFunction(ty), tail))
7836            }
7837            b"TH" => {
7838                let (name, tail) = Name::parse(ctx, subs, tail)?;
7839                Ok((SpecialName::TlsInit(name), tail))
7840            }
7841            b"TW" => {
7842                let (name, tail) = Name::parse(ctx, subs, tail)?;
7843                Ok((SpecialName::TlsWrapper(name), tail))
7844            }
7845            b"GV" => {
7846                let (name, tail) = Name::parse(ctx, subs, tail)?;
7847                Ok((SpecialName::Guard(name), tail))
7848            }
7849            b"GR" => {
7850                let (name, tail) = Name::parse(ctx, subs, tail)?;
7851                let (idx, tail) = if let Ok(tail) = consume(b"_", tail) {
7852                    (0, tail)
7853                } else {
7854                    let (idx, tail) = SeqId::parse(ctx, subs, tail)?;
7855                    let tail = consume(b"_", tail)?;
7856                    (idx.0 + 1, tail)
7857                };
7858                Ok((SpecialName::GuardTemporary(name, idx), tail))
7859            }
7860            b"Gr" => {
7861                let (resource_name_len, tail) = parse_number(10, false, tail)?;
7862                if resource_name_len == 0 {
7863                    return Err(error::Error::UnexpectedText);
7864                }
7865
7866                let (head, tail) = match tail.try_split_at(resource_name_len as _) {
7867                    Some((head, tail)) => (head, tail),
7868                    None => return Err(error::Error::UnexpectedEnd),
7869                };
7870
7871                let head = consume(b"_", head)?;
7872
7873                let (resource_names, empty) = zero_or_more::<ResourceName>(ctx, subs, head)?;
7874                if !empty.is_empty() {
7875                    return Err(error::Error::UnexpectedText);
7876                }
7877
7878                Ok((SpecialName::JavaResource(resource_names), tail))
7879            }
7880            b"GT" => {
7881                match tail.next_or(error::Error::UnexpectedEnd)? {
7882                    (b'n', tail) => {
7883                        let (base, tail) = Encoding::parse(ctx, subs, tail)?;
7884                        Ok((SpecialName::NonTransactionClone(Box::new(base)), tail))
7885                    }
7886                    // Different letters could stand for different types of
7887                    // transactional cloning, but for now, treat them all the same
7888                    (b't', tail) | (_, tail) => {
7889                        let (base, tail) = Encoding::parse(ctx, subs, tail)?;
7890                        Ok((SpecialName::TransactionClone(Box::new(base)), tail))
7891                    }
7892                }
7893            }
7894            _ => Err(error::Error::UnexpectedText),
7895        }
7896    }
7897}
7898
7899impl<'subs, W> Demangle<'subs, W> for SpecialName
7900where
7901    W: 'subs + DemangleWrite,
7902{
7903    fn demangle<'prev, 'ctx>(
7904        &'subs self,
7905        ctx: &'ctx mut DemangleContext<'subs, W>,
7906        scope: Option<ArgScopeStack<'prev, 'subs>>,
7907    ) -> fmt::Result {
7908        let ctx = try_begin_demangle!(self, ctx, scope);
7909
7910        match *self {
7911            SpecialName::VirtualTable(ref ty) => {
7912                write!(ctx, "{{vtable(")?;
7913                ctx.push_demangle_node(DemangleNodeType::VirtualTable);
7914                ty.demangle(ctx, scope)?;
7915                ctx.pop_demangle_node();
7916                write!(ctx, ")}}")?;
7917                Ok(())
7918            }
7919            SpecialName::Vtt(ref ty) => {
7920                write!(ctx, "{{vtt(")?;
7921                ty.demangle(ctx, scope)?;
7922                write!(ctx, ")}}")?;
7923                Ok(())
7924            }
7925            SpecialName::Typeinfo(ref ty) => {
7926                write!(ctx, "typeinfo for ")?;
7927                ty.demangle(ctx, scope)
7928            }
7929            SpecialName::TypeinfoName(ref ty) => {
7930                write!(ctx, "typeinfo name for ")?;
7931                ty.demangle(ctx, scope)
7932            }
7933            SpecialName::VirtualOverrideThunk(ref offset, ref encoding) => {
7934                write!(ctx, "{{virtual override thunk(")?;
7935                offset.demangle(ctx, scope)?;
7936                write!(ctx, ", ")?;
7937                encoding.demangle(ctx, scope)?;
7938                write!(ctx, ")}}")?;
7939                Ok(())
7940            }
7941            SpecialName::VirtualOverrideThunkCovariant(
7942                ref this_offset,
7943                ref result_offset,
7944                ref encoding,
7945            ) => {
7946                write!(ctx, "{{virtual override thunk(")?;
7947                this_offset.demangle(ctx, scope)?;
7948                write!(ctx, ", ")?;
7949                result_offset.demangle(ctx, scope)?;
7950                write!(ctx, ", ")?;
7951                encoding.demangle(ctx, scope)?;
7952                write!(ctx, ")}}")?;
7953                Ok(())
7954            }
7955            SpecialName::Guard(ref name) => {
7956                write!(ctx, "guard variable for ")?;
7957                name.demangle(ctx, scope)
7958            }
7959            SpecialName::GuardTemporary(ref name, n) => {
7960                write!(ctx, "reference temporary #{} for ", n)?;
7961                name.demangle(ctx, scope)
7962            }
7963            SpecialName::ConstructionVtable(ref ty1, _, ref ty2) => {
7964                write!(ctx, "construction vtable for ")?;
7965                ty1.demangle(ctx, scope)?;
7966                write!(ctx, "-in-")?;
7967                ty2.demangle(ctx, scope)
7968            }
7969            SpecialName::TypeinfoFunction(ref ty) => {
7970                write!(ctx, "typeinfo fn for ")?;
7971                ty.demangle(ctx, scope)
7972            }
7973            SpecialName::TlsInit(ref name) => {
7974                write!(ctx, "TLS init function for ")?;
7975                name.demangle(ctx, scope)
7976            }
7977            SpecialName::TlsWrapper(ref name) => {
7978                write!(ctx, "TLS wrapper function for ")?;
7979                name.demangle(ctx, scope)
7980            }
7981            SpecialName::TransactionClone(ref encoding) => {
7982                write!(ctx, "transaction clone for ")?;
7983                encoding.demangle(ctx, scope)
7984            }
7985            SpecialName::NonTransactionClone(ref encoding) => {
7986                write!(ctx, "non-transaction clone for ")?;
7987                encoding.demangle(ctx, scope)
7988            }
7989            SpecialName::JavaResource(ref names) => {
7990                write!(ctx, "java resource ")?;
7991                for name in names {
7992                    name.demangle(ctx, scope)?;
7993                }
7994                Ok(())
7995            }
7996        }
7997    }
7998}
7999
8000/// The `<resource name>` pseudo-terminal.
8001#[derive(Clone, Debug, PartialEq, Eq)]
8002pub struct ResourceName {
8003    start: usize,
8004    end: usize,
8005}
8006
8007impl Parse for ResourceName {
8008    fn parse<'a, 'b>(
8009        ctx: &'a ParseContext,
8010        _subs: &'a mut SubstitutionTable,
8011        input: IndexStr<'b>,
8012    ) -> Result<(ResourceName, IndexStr<'b>)> {
8013        try_begin_parse!("ResourceName", ctx, input);
8014
8015        if input.is_empty() {
8016            return Err(error::Error::UnexpectedEnd);
8017        }
8018
8019        let mut end = input
8020            .as_ref()
8021            .iter()
8022            .map(|&c| c as char)
8023            .take_while(|&c| c != '$' || c.is_digit(36))
8024            .count();
8025
8026        if end == 0 {
8027            return Err(error::Error::UnexpectedText);
8028        }
8029
8030        if input.range_from(end..).peek() == Some(b'$') {
8031            match input.range_from(end..).peek_second() {
8032                Some(b'S') | Some(b'_') | Some(b'$') => end += 2,
8033                _ => return Err(error::Error::UnexpectedText),
8034            }
8035        }
8036
8037        let tail = input.range_from(end..);
8038
8039        let resource_name = ResourceName {
8040            start: input.index(),
8041            end: tail.index(),
8042        };
8043
8044        Ok((resource_name, tail))
8045    }
8046}
8047
8048impl<'subs, W> Demangle<'subs, W> for ResourceName
8049where
8050    W: 'subs + DemangleWrite,
8051{
8052    #[inline]
8053    fn demangle<'prev, 'ctx>(
8054        &'subs self,
8055        ctx: &'ctx mut DemangleContext<'subs, W>,
8056        scope: Option<ArgScopeStack<'prev, 'subs>>,
8057    ) -> fmt::Result {
8058        let ctx = try_begin_demangle!(self, ctx, scope);
8059
8060        let mut i = self.start;
8061        while i < self.end {
8062            let ch = ctx.input[i];
8063            if ch == b'$' {
8064                // Skip past the '$'
8065                i += 1;
8066                match ctx.input[i] {
8067                    b'S' => write!(ctx, "{}", '/')?,
8068                    b'_' => write!(ctx, "{}", '.')?,
8069                    b'$' => write!(ctx, "{}", '$')?,
8070                    _ => {
8071                        // Fall through
8072                    }
8073                }
8074            } else {
8075                write!(ctx, "{}", ch as char)?;
8076            }
8077            i += 1;
8078        }
8079
8080        Ok(())
8081    }
8082}
8083
8084/// The subobject expression production.
8085///
8086/// <expression> ::= so <referent type> <expr> [<offset number>] <union-selector>* [p] E
8087/// <union-selector> ::= _ [<number>]
8088///
8089/// Not yet in the spec: https://github.com/itanium-cxx-abi/cxx-abi/issues/47
8090/// But it has been shipping in clang for some time.
8091#[derive(Clone, Debug, PartialEq, Eq)]
8092pub struct SubobjectExpr {
8093    ty: TypeHandle,
8094    expr: Box<Expression>,
8095    offset: isize,
8096}
8097
8098impl Parse for SubobjectExpr {
8099    fn parse<'a, 'b>(
8100        ctx: &'a ParseContext,
8101        subs: &'a mut SubstitutionTable,
8102        input: IndexStr<'b>,
8103    ) -> Result<(SubobjectExpr, IndexStr<'b>)> {
8104        try_begin_parse!("SubobjectExpr", ctx, input);
8105
8106        let (ty, tail) = TypeHandle::parse(ctx, subs, input)?;
8107        let (expr, tail) = Expression::parse(ctx, subs, tail)?;
8108        let (offset, tail) = parse_number(10, true, tail).unwrap_or((0, tail));
8109
8110        // XXXkhuey handle union-selector and [p]
8111        let tail = consume(b"E", tail)?;
8112        Ok((
8113            SubobjectExpr {
8114                ty: ty,
8115                expr: Box::new(expr),
8116                offset: offset,
8117            },
8118            tail,
8119        ))
8120    }
8121}
8122
8123impl<'subs, W> Demangle<'subs, W> for SubobjectExpr
8124where
8125    W: 'subs + DemangleWrite,
8126{
8127    #[inline]
8128    fn demangle<'prev, 'ctx>(
8129        &'subs self,
8130        ctx: &'ctx mut DemangleContext<'subs, W>,
8131        scope: Option<ArgScopeStack<'prev, 'subs>>,
8132    ) -> fmt::Result {
8133        let ctx = try_begin_demangle!(self, ctx, scope);
8134
8135        self.expr.demangle(ctx, scope)?;
8136        write!(ctx, ".<")?;
8137        self.ty.demangle(ctx, scope)?;
8138        write!(ctx, " at offset {}>", self.offset)
8139    }
8140}
8141
8142/// Expect and consume the given byte str, and return the advanced `IndexStr` if
8143/// we saw the expectation. Otherwise return an error of kind
8144/// `error::Error::UnexpectedText` if the input doesn't match, or
8145/// `error::Error::UnexpectedEnd` if it isn't long enough.
8146#[inline]
8147fn consume<'a>(expected: &[u8], input: IndexStr<'a>) -> Result<IndexStr<'a>> {
8148    match input.try_split_at(expected.len()) {
8149        Some((head, tail)) if head == expected => Ok(tail),
8150        Some(_) => Err(error::Error::UnexpectedText),
8151        None => Err(error::Error::UnexpectedEnd),
8152    }
8153}
8154
8155fn one_or_more<'a, 'b, P>(
8156    ctx: &'a ParseContext,
8157    subs: &'a mut SubstitutionTable,
8158    input: IndexStr<'b>,
8159) -> Result<(Vec<P>, IndexStr<'b>)>
8160where
8161    P: Parse,
8162{
8163    let (first, mut tail) = P::parse(ctx, subs, input)?;
8164    let mut results = vec![first];
8165    loop {
8166        if let Ok((parsed, tail_tail)) = try_recurse!(P::parse(ctx, subs, tail)) {
8167            results.push(parsed);
8168            tail = tail_tail;
8169        } else {
8170            return Ok((results, tail));
8171        }
8172    }
8173}
8174
8175fn zero_or_more<'a, 'b, P>(
8176    ctx: &'a ParseContext,
8177    subs: &'a mut SubstitutionTable,
8178    input: IndexStr<'b>,
8179) -> Result<(Vec<P>, IndexStr<'b>)>
8180where
8181    P: Parse,
8182{
8183    let mut tail = input;
8184    let mut results = vec![];
8185    loop {
8186        if let Ok((parsed, tail_tail)) = try_recurse!(P::parse(ctx, subs, tail)) {
8187            results.push(parsed);
8188            tail = tail_tail;
8189        } else {
8190            return Ok((results, tail));
8191        }
8192    }
8193}
8194
8195/// Parse a number with the given `base`. Do not allow negative numbers
8196/// (prefixed with an 'n' instead of a '-') if `allow_signed` is false.
8197#[allow(unsafe_code)]
8198fn parse_number(base: u32, allow_signed: bool, mut input: IndexStr) -> Result<(isize, IndexStr)> {
8199    if input.is_empty() {
8200        return Err(error::Error::UnexpectedEnd);
8201    }
8202
8203    let num_is_negative = if allow_signed && input.as_ref()[0] == b'n' {
8204        input = input.range_from(1..);
8205
8206        if input.is_empty() {
8207            return Err(error::Error::UnexpectedEnd);
8208        }
8209
8210        true
8211    } else {
8212        false
8213    };
8214
8215    let num_numeric = input
8216        .as_ref()
8217        .iter()
8218        .map(|&c| c as char)
8219        .take_while(|c| c.is_digit(base) && (c.is_numeric() || c.is_uppercase()))
8220        .count();
8221    if num_numeric == 0 {
8222        return Err(error::Error::UnexpectedText);
8223    }
8224
8225    let (head, tail) = input.split_at(num_numeric);
8226    let head = head.as_ref();
8227
8228    if num_numeric > 1 && head[0] == b'0' {
8229        // "<number>s appearing in mangled names never have leading zeroes,
8230        // except for the value zero, represented as '0'."
8231        return Err(error::Error::UnexpectedText);
8232    }
8233
8234    let head = unsafe {
8235        // Safe because we know we only have valid numeric chars in this
8236        // slice, which are valid UTF-8.
8237        str::from_utf8_unchecked(head)
8238    };
8239
8240    let mut number = isize::from_str_radix(head, base).map_err(|_| error::Error::Overflow)?;
8241    if num_is_negative {
8242        number = -number;
8243    }
8244
8245    Ok((number, tail))
8246}
8247
8248#[cfg(test)]
8249mod tests {
8250    use super::{
8251        AbiTag, AbiTags, ArrayType, BareFunctionType, BaseUnresolvedName, BuiltinType, CallOffset,
8252        ClassEnumType, ClosureTypeName, CtorDtorName, CvQualifiers, DataMemberPrefix, Decltype,
8253        DestructorName, Discriminator, Encoding, ExceptionSpec, ExprPrimary, Expression,
8254        FunctionParam, FunctionType, GlobalCtorDtor, Identifier, Initializer, LambdaSig, LocalName,
8255        MangledName, MemberName, Name, NestedName, NonSubstitution, Number, NvOffset, OperatorName,
8256        ParametricBuiltinType, Parse, ParseContext, PointerToMemberType, Prefix, PrefixHandle,
8257        RefQualifier, ResourceName, SeqId, SimpleId, SimpleOperatorName, SourceName, SpecialName,
8258        StandardBuiltinType, SubobjectExpr, Substitution, TemplateArg, TemplateArgs, TemplateParam,
8259        TemplateTemplateParam, TemplateTemplateParamHandle, Type, TypeHandle, UnnamedTypeName,
8260        UnqualifiedName, UnresolvedName, UnresolvedQualifierLevel, UnresolvedType,
8261        UnresolvedTypeHandle, UnscopedName, UnscopedTemplateName, UnscopedTemplateNameHandle,
8262        VOffset, VectorType, WellKnownComponent,
8263    };
8264
8265    use crate::error::Error;
8266    use crate::index_str::IndexStr;
8267    use crate::subs::{Substitutable, SubstitutionTable};
8268    use alloc::boxed::Box;
8269    use alloc::string::String;
8270    use core::fmt::Debug;
8271    use core::iter::FromIterator;
8272
8273    fn assert_parse_ok<P, S1, S2, I1, I2>(
8274        production: &'static str,
8275        subs: S1,
8276        input: I1,
8277        expected: P,
8278        expected_tail: I2,
8279        expected_new_subs: S2,
8280    ) where
8281        P: Debug + Parse + PartialEq,
8282        S1: AsRef<[Substitutable]>,
8283        S2: AsRef<[Substitutable]>,
8284        I1: AsRef<[u8]>,
8285        I2: AsRef<[u8]>,
8286    {
8287        let ctx = ParseContext::new(Default::default());
8288        let input = input.as_ref();
8289        let expected_tail = expected_tail.as_ref();
8290
8291        let expected_subs = SubstitutionTable::from_iter(
8292            subs.as_ref()
8293                .iter()
8294                .cloned()
8295                .chain(expected_new_subs.as_ref().iter().cloned()),
8296        );
8297        let mut subs = SubstitutionTable::from_iter(subs.as_ref().iter().cloned());
8298
8299        match P::parse(&ctx, &mut subs, IndexStr::from(input)) {
8300            Err(error) => panic!(
8301                "Parsing {:?} as {} failed: {}",
8302                String::from_utf8_lossy(input),
8303                production,
8304                error
8305            ),
8306            Ok((value, tail)) => {
8307                if value != expected {
8308                    panic!(
8309                        "Parsing {:?} as {} produced\n\n{:#?}\n\nbut we expected\n\n{:#?}",
8310                        String::from_utf8_lossy(input),
8311                        production,
8312                        value,
8313                        expected
8314                    );
8315                }
8316                if tail != expected_tail {
8317                    panic!(
8318                        "Parsing {:?} as {} left a tail of {:?}, expected {:?}",
8319                        String::from_utf8_lossy(input),
8320                        production,
8321                        tail,
8322                        String::from_utf8_lossy(expected_tail)
8323                    );
8324                }
8325                if subs[..] != expected_subs[..] {
8326                    panic!(
8327                        "Parsing {:?} as {} produced a substitutions table of\n\n\
8328                         {:#?}\n\n\
8329                         but we expected\n\n\
8330                         {:#?}",
8331                        String::from_utf8_lossy(input),
8332                        production,
8333                        subs,
8334                        expected_subs
8335                    );
8336                }
8337            }
8338        }
8339
8340        log!("=== assert_parse_ok PASSED ====================================");
8341    }
8342
8343    fn simple_assert_parse_ok<P, I1, I2>(
8344        production: &'static str,
8345        input: I1,
8346        expected: P,
8347        expected_tail: I2,
8348    ) where
8349        P: Debug + Parse + PartialEq,
8350        I1: AsRef<[u8]>,
8351        I2: AsRef<[u8]>,
8352    {
8353        assert_parse_ok::<P, _, _, _, _>(production, [], input, expected, expected_tail, []);
8354    }
8355
8356    fn assert_parse_err<P, S, I>(production: &'static str, subs: S, input: I, expected_error: Error)
8357    where
8358        P: Debug + Parse + PartialEq,
8359        S: AsRef<[Substitutable]>,
8360        I: AsRef<[u8]>,
8361    {
8362        let input = input.as_ref();
8363        let ctx = ParseContext::new(Default::default());
8364        let mut subs = SubstitutionTable::from_iter(subs.as_ref().iter().cloned());
8365
8366        match P::parse(&ctx, &mut subs, IndexStr::from(input)) {
8367            Err(ref error) if *error == expected_error => {}
8368            Err(ref error) => {
8369                panic!(
8370                    "Parsing {:?} as {} produced an error of kind {:?}, but we expected kind {:?}",
8371                    String::from_utf8_lossy(input),
8372                    production,
8373                    error,
8374                    expected_error
8375                );
8376            }
8377            Ok((value, tail)) => {
8378                panic!(
8379                    "Parsing {:?} as {} produced value\
8380                     \n\n\
8381                     {:#?}\
8382                     \n\n\
8383                     and tail {:?}, but we expected error kind {:?}",
8384                    String::from_utf8_lossy(input),
8385                    production,
8386                    value,
8387                    tail,
8388                    expected_error
8389                );
8390            }
8391        }
8392
8393        log!("=== assert_parse_err PASSED ===================================");
8394    }
8395
8396    fn simple_assert_parse_err<P, I>(production: &'static str, input: I, expected_error: Error)
8397    where
8398        P: Debug + Parse + PartialEq,
8399        I: AsRef<[u8]>,
8400    {
8401        assert_parse_err::<P, _, _>(production, [], input, expected_error);
8402    }
8403
8404    #[test]
8405    fn recursion_limit() {
8406        // Build the mangled symbol for the type `*****char` where the "*****"
8407        // is 10,000 pointer indirections. This is a valid type symbol, but
8408        // something that would cause us to blow the stack.
8409        let mut mangled = String::new();
8410        for _ in 0..10_000 {
8411            mangled.push('P');
8412        }
8413        mangled += "c";
8414
8415        simple_assert_parse_err::<TypeHandle, _>("TypeHandle", mangled, Error::TooMuchRecursion);
8416    }
8417
8418    macro_rules! assert_parse {
8419        ( $production:ident {
8420            $( with subs $subs:expr => {
8421                Ok => {
8422                    $( $input:expr => {
8423                        $expected:expr ,
8424                        $expected_tail:expr ,
8425                        $expected_new_subs:expr
8426                    } )*
8427                }
8428                Err => {
8429                    $( $error_input:expr => $error:expr , )*
8430                }
8431            } )*
8432        } ) => {
8433            $( $(
8434                assert_parse_ok::<$production, _, _, _, _>(stringify!($production),
8435                                                           $subs,
8436                                                           $input,
8437                                                           $expected,
8438                                                           $expected_tail,
8439                                                           $expected_new_subs);
8440            )* )*
8441
8442            $( $(
8443                assert_parse_err::<$production, _, _>(stringify!($production),
8444                                                      $subs,
8445                                                      $error_input,
8446                                                      $error);
8447            )* )*
8448        };
8449
8450        ( $production:ident {
8451            Ok => {
8452                $( $input:expr => {
8453                    $expected:expr ,
8454                    $expected_tail:expr
8455                } )*
8456            }
8457            Err => {
8458                $( $error_input:expr => $error:expr , )*
8459            }
8460        } ) => {
8461            $(
8462                simple_assert_parse_ok::<$production, _, _>(stringify!($production),
8463                                                            $input,
8464                                                            $expected,
8465                                                            $expected_tail);
8466            )*
8467
8468
8469            $(
8470                simple_assert_parse_err::<$production, _>(stringify!($production),
8471                                                          $error_input,
8472                                                          $error);
8473            )*
8474        };
8475    }
8476
8477    #[test]
8478    fn parse_mangled_name() {
8479        assert_parse!(MangledName {
8480            Ok => {
8481                b"_Z3foo..." => {
8482                    MangledName::Encoding(
8483                        Encoding::Data(
8484                            Name::Unscoped(
8485                                UnscopedName::Unqualified(
8486                                    UnqualifiedName::Source(
8487                                        SourceName(Identifier {
8488                                            start: 3,
8489                                            end: 6,
8490                                        }),
8491                                        AbiTags::default())))), vec![]),
8492                    b"..."
8493                }
8494                b"_GLOBAL__I__Z3foo..." => {
8495                    MangledName::GlobalCtorDtor(
8496                        GlobalCtorDtor::Ctor(
8497                            Box::new(
8498                                MangledName::Encoding(
8499                                    Encoding::Data(
8500                                        Name::Unscoped(
8501                                            UnscopedName::Unqualified(
8502                                                UnqualifiedName::Source(
8503                                                    SourceName(
8504                                                        Identifier {
8505                                                            start: 14,
8506                                                            end: 17,
8507                                                        }),
8508                                                    AbiTags::default())))), vec![])))),
8509                    b"..."
8510                }
8511            }
8512            Err => {
8513                b"_Y" => Error::UnexpectedText,
8514                b"_Z" => Error::UnexpectedEnd,
8515                b"_" => Error::UnexpectedEnd,
8516                b"" => Error::UnexpectedEnd,
8517                b"_GLOBAL_" => Error::UnexpectedEnd,
8518            }
8519        });
8520    }
8521
8522    #[test]
8523    fn parse_encoding() {
8524        assert_parse!(Encoding {
8525            with subs [] => {
8526                Ok => {
8527                    b"3fooi..." => {
8528                        Encoding::Function(
8529                            Name::Unscoped(
8530                                UnscopedName::Unqualified(
8531                                    UnqualifiedName::Source(
8532                                        SourceName(Identifier {
8533                                            start: 1,
8534                                            end: 4,
8535                                        }),
8536                                        AbiTags::default()))),
8537                            BareFunctionType(vec![
8538                                TypeHandle::Builtin(BuiltinType::Standard(StandardBuiltinType::Int))
8539                            ])),
8540                        b"...",
8541                        []
8542                    }
8543                    b"3foo..." => {
8544                        Encoding::Data(
8545                            Name::Unscoped(
8546                                UnscopedName::Unqualified(
8547                                    UnqualifiedName::Source(
8548                                        SourceName(Identifier {
8549                                            start: 1,
8550                                            end: 4,
8551                                        }),
8552                                        AbiTags::default())))),
8553                        b"...",
8554                        []
8555                    }
8556                    b"GV3abc..." => {
8557                        Encoding::Special(
8558                            SpecialName::Guard(
8559                                Name::Unscoped(
8560                                    UnscopedName::Unqualified(
8561                                        UnqualifiedName::Source(
8562                                            SourceName(Identifier {
8563                                                start: 3,
8564                                                end: 6,
8565                                            }),
8566                                            AbiTags::default()))))),
8567                        b"...",
8568                        []
8569                    }
8570                }
8571                Err => {
8572                    b"zzz" => Error::UnexpectedText,
8573                    b"" => Error::UnexpectedEnd,
8574                }
8575            }
8576        });
8577    }
8578
8579    #[test]
8580    fn parse_global_ctor_dtor() {
8581        assert_parse!(GlobalCtorDtor {
8582            Ok => {
8583                b"_I__Z3foo..." => {
8584                    GlobalCtorDtor::Ctor(
8585                        Box::new(
8586                            MangledName::Encoding(
8587                                Encoding::Data(
8588                                    Name::Unscoped(
8589                                        UnscopedName::Unqualified(
8590                                            UnqualifiedName::Source(
8591                                                SourceName(
8592                                                    Identifier {
8593                                                        start: 6,
8594                                                        end: 9,
8595                                                    }),
8596                                                AbiTags::default())))), vec![]))),
8597                    b"..."
8598                }
8599                b".I__Z3foo..." => {
8600                    GlobalCtorDtor::Ctor(
8601                        Box::new(
8602                            MangledName::Encoding(
8603                                Encoding::Data(
8604                                    Name::Unscoped(
8605                                        UnscopedName::Unqualified(
8606                                            UnqualifiedName::Source(
8607                                                SourceName(
8608                                                    Identifier {
8609                                                        start: 6,
8610                                                        end: 9,
8611                                                    }),
8612                                                AbiTags::default())))), vec![]))),
8613                    b"..."
8614                }
8615                b"$I__Z3foo..." => {
8616                    GlobalCtorDtor::Ctor(
8617                        Box::new(
8618                            MangledName::Encoding(
8619                                Encoding::Data(
8620                                    Name::Unscoped(
8621                                        UnscopedName::Unqualified(
8622                                            UnqualifiedName::Source(
8623                                                SourceName(
8624                                                    Identifier {
8625                                                        start: 6,
8626                                                        end: 9,
8627                                                    }),
8628                                                AbiTags::default())))), vec![]))),
8629                    b"..."
8630                }
8631                b"_D__Z3foo..." => {
8632                    GlobalCtorDtor::Dtor(
8633                        Box::new(
8634                            MangledName::Encoding(
8635                                Encoding::Data(
8636                                    Name::Unscoped(
8637                                        UnscopedName::Unqualified(
8638                                            UnqualifiedName::Source(
8639                                                SourceName(
8640                                                    Identifier {
8641                                                        start: 6,
8642                                                        end: 9,
8643                                                    }),
8644                                                AbiTags::default())))), vec![]))),
8645                    b"..."
8646                }
8647                b".D__Z3foo..." => {
8648                    GlobalCtorDtor::Dtor(
8649                        Box::new(
8650                            MangledName::Encoding(
8651                                Encoding::Data(
8652                                    Name::Unscoped(
8653                                        UnscopedName::Unqualified(
8654                                            UnqualifiedName::Source(
8655                                                SourceName(
8656                                                    Identifier {
8657                                                        start: 6,
8658                                                        end: 9,
8659                                                    }),
8660                                                AbiTags::default())))), vec![]))),
8661                    b"..."
8662                }
8663                b"$D__Z3foo..." => {
8664                    GlobalCtorDtor::Dtor(
8665                        Box::new(
8666                            MangledName::Encoding(
8667                                Encoding::Data(
8668                                    Name::Unscoped(
8669                                        UnscopedName::Unqualified(
8670                                            UnqualifiedName::Source(
8671                                                SourceName(
8672                                                    Identifier {
8673                                                        start: 6,
8674                                                        end: 9,
8675                                                    }),
8676                                                AbiTags::default())))), vec![]))),
8677                    b"..."
8678                }
8679            }
8680            Err => {
8681                b"_I" => Error::UnexpectedEnd,
8682                b"_" => Error::UnexpectedEnd,
8683                b"" => Error::UnexpectedEnd,
8684                b"blag" => Error::UnexpectedText,
8685                b"_J" => Error::UnexpectedText,
8686                b"_IJ" => Error::UnexpectedText,
8687            }
8688        });
8689    }
8690
8691    #[test]
8692    fn parse_name() {
8693        assert_parse!(Name {
8694            with subs [
8695                Substitutable::Prefix(
8696                    Prefix::Unqualified(
8697                        UnqualifiedName::Operator(OperatorName::Simple(SimpleOperatorName::New),
8698                                                  AbiTags::default()))),
8699                Substitutable::Prefix(
8700                    Prefix::Nested(PrefixHandle::BackReference(0),
8701                                   UnqualifiedName::Operator(OperatorName::Simple(SimpleOperatorName::New),
8702                                                             AbiTags::default()))),
8703            ] => {
8704                Ok => {
8705                    b"NS0_3abcE..." => {
8706                        Name::Nested(NestedName::Unqualified(CvQualifiers::default(),
8707                                                             None,
8708                                                             Some(PrefixHandle::BackReference(1)),
8709                                                             UnqualifiedName::Source(SourceName(Identifier {
8710                                                                 start: 5,
8711                                                                 end: 8,
8712                                                             }), AbiTags::default()))),
8713                        b"...",
8714                        []
8715                    }
8716                    b"3abc..." => {
8717                        Name::Unscoped(
8718                            UnscopedName::Unqualified(
8719                                UnqualifiedName::Source(
8720                                    SourceName(Identifier {
8721                                        start: 1,
8722                                        end: 4,
8723                                    }),
8724                                    AbiTags::default()))),
8725                        b"...",
8726                        []
8727                    }
8728                    b"dlIcE..." => {
8729                        Name::UnscopedTemplate(
8730                            UnscopedTemplateNameHandle::BackReference(2),
8731                            TemplateArgs(vec![
8732                                TemplateArg::Type(
8733                                    TypeHandle::Builtin(
8734                                        BuiltinType::Standard(StandardBuiltinType::Char)))
8735                            ])),
8736                        b"...",
8737                        [
8738                            Substitutable::UnscopedTemplateName(
8739                                UnscopedTemplateName(
8740                                    UnscopedName::Unqualified(
8741                                        UnqualifiedName::Operator(
8742                                            OperatorName::Simple(
8743                                                SimpleOperatorName::Delete),
8744                                            AbiTags::default())))),
8745                        ]
8746                    }
8747                    b"Z3abcEs..." => {
8748                        Name::Local(
8749                            LocalName::Relative(
8750                                Box::new(Encoding::Data(
8751                                    Name::Unscoped(
8752                                        UnscopedName::Unqualified(
8753                                            UnqualifiedName::Source(
8754                                                SourceName(Identifier {
8755                                                    start: 2,
8756                                                    end: 5,
8757                                                }),
8758                                                AbiTags::default()))))),
8759                                None,
8760                                None)),
8761                        b"...",
8762                        []
8763                    }
8764                }
8765                Err => {
8766                    b"zzz" => Error::UnexpectedText,
8767                    b"" => Error::UnexpectedEnd,
8768                }
8769            }
8770        });
8771    }
8772
8773    #[test]
8774    fn parse_unscoped_template_name_handle() {
8775        assert_parse!(UnscopedTemplateNameHandle {
8776            with subs [
8777                Substitutable::UnscopedTemplateName(
8778                    UnscopedTemplateName(
8779                        UnscopedName::Unqualified(
8780                            UnqualifiedName::Operator(
8781                                OperatorName::Simple(
8782                                    SimpleOperatorName::New),
8783                                AbiTags::default())))),
8784            ] => {
8785                Ok => {
8786                    b"S_..." => {
8787                        UnscopedTemplateNameHandle::BackReference(0),
8788                        b"...",
8789                        []
8790                    }
8791                    b"dl..." => {
8792                        UnscopedTemplateNameHandle::BackReference(1),
8793                        b"...",
8794                        [
8795                            Substitutable::UnscopedTemplateName(
8796                                UnscopedTemplateName(
8797                                    UnscopedName::Unqualified(
8798                                        UnqualifiedName::Operator(
8799                                            OperatorName::Simple(
8800                                                SimpleOperatorName::Delete),
8801                                            AbiTags::default()))))
8802                        ]
8803                    }
8804                }
8805                Err => {
8806                    b"zzzz" => Error::UnexpectedText,
8807                    b"" => Error::UnexpectedEnd,
8808                }
8809            }
8810        });
8811    }
8812
8813    #[test]
8814    fn parse_nested_name() {
8815        // <nested-name> ::= N [<CV-qualifiers>] [<ref-qualifier>] <prefix> <unqualified-name> E
8816        //               ::= N [<CV-qualifiers>] [<ref-qualifier>] <template-prefix> <template-args> E
8817        assert_parse!(NestedName {
8818            with subs [
8819                Substitutable::Prefix(
8820                    Prefix::Unqualified(
8821                        UnqualifiedName::Operator(
8822                            OperatorName::Simple(
8823                                SimpleOperatorName::New),
8824                            AbiTags::default()))),
8825            ] => {
8826                Ok => {
8827                    b"NKOS_3abcE..." => {
8828                        NestedName::Unqualified(
8829                            CvQualifiers {
8830                                restrict: false,
8831                                volatile: false,
8832                                const_: true,
8833                            },
8834                            Some(RefQualifier::RValueRef),
8835                            Some(PrefixHandle::BackReference(0)),
8836                            UnqualifiedName::Source(
8837                                SourceName(Identifier {
8838                                    start: 6,
8839                                    end: 9,
8840                                }),
8841                                AbiTags::default())),
8842                        b"...",
8843                        []
8844                    }
8845                    b"NOS_3abcE..." => {
8846                        NestedName::Unqualified(
8847                            CvQualifiers {
8848                                restrict: false,
8849                                volatile: false,
8850                                const_: false,
8851                            },
8852                            Some(RefQualifier::RValueRef),
8853                            Some(PrefixHandle::BackReference(0)),
8854                            UnqualifiedName::Source(
8855                                SourceName(Identifier {
8856                                    start: 5,
8857                                    end: 8,
8858                                }), AbiTags::default())),
8859                        b"...",
8860                        []
8861                    }
8862                    b"NS_3abcE..." => {
8863                        NestedName::Unqualified(
8864                            CvQualifiers {
8865                                restrict: false,
8866                                volatile: false,
8867                                const_: false,
8868                            },
8869                            None,
8870                            Some(PrefixHandle::BackReference(0)),
8871                            UnqualifiedName::Source(
8872                                SourceName(Identifier {
8873                                    start: 4,
8874                                    end: 7,
8875                                }), AbiTags::default())),
8876                        b"...",
8877                        []
8878                    }
8879                    b"NK1fE..." => {
8880                        NestedName::Unqualified(
8881                            CvQualifiers {
8882                                restrict: false,
8883                                volatile: false,
8884                                const_: true,
8885                            },
8886                            None,
8887                            None,
8888                            UnqualifiedName::Source(
8889                                SourceName(Identifier {
8890                                    start: 3,
8891                                    end: 4,
8892                                }),
8893                                AbiTags::default())),
8894                        b"...",
8895                        []
8896                    }
8897                    b"NKOS_3abcIJEEE..." => {
8898                        NestedName::Template(
8899                            CvQualifiers {
8900                                restrict: false,
8901                                volatile: false,
8902                                const_: true,
8903                            },
8904                            Some(RefQualifier::RValueRef),
8905                            PrefixHandle::NonSubstitution(NonSubstitution(0))),
8906                        b"...",
8907                        [
8908                            Substitutable::Prefix(
8909                                Prefix::Nested(
8910                                    PrefixHandle::BackReference(0),
8911                                    UnqualifiedName::Source(
8912                                        SourceName(Identifier {
8913                                            start: 6,
8914                                            end: 9,
8915                                        }),
8916                                        AbiTags::default()))),
8917                        ]
8918                    }
8919                    b"NOS_3abcIJEEE..." => {
8920                        NestedName::Template(
8921                            CvQualifiers {
8922                                restrict: false,
8923                                volatile: false,
8924                                const_: false,
8925                            },
8926                            Some(RefQualifier::RValueRef),
8927                            PrefixHandle::NonSubstitution(NonSubstitution(0))),
8928                        b"...",
8929                        [
8930                            Substitutable::Prefix(
8931                                Prefix::Nested(
8932                                    PrefixHandle::BackReference(0),
8933                                    UnqualifiedName::Source(
8934                                        SourceName(Identifier {
8935                                            start: 5,
8936                                            end: 8,
8937                                        }),
8938                                        AbiTags::default()))),
8939                        ]
8940                    }
8941                    b"NS_3abcIJEEE..." => {
8942                        NestedName::Template(
8943                            CvQualifiers {
8944                                restrict: false,
8945                                volatile: false,
8946                                const_: false,
8947                            },
8948                            None,
8949                            PrefixHandle::NonSubstitution(NonSubstitution(0))),
8950                        b"...",
8951                        [
8952                            Substitutable::Prefix(
8953                                Prefix::Nested(
8954                                    PrefixHandle::BackReference(0),
8955                                    UnqualifiedName::Source(
8956                                        SourceName(Identifier {
8957                                            start: 4,
8958                                            end: 7,
8959                                        }),
8960                                        AbiTags::default()))),
8961                        ]
8962                    }
8963                }
8964                Err => {
8965                    // Ends with a prefix that is not a name or template.
8966                    b"NS_DttrEE..." => Error::UnexpectedText,
8967
8968                    b"zzz" => Error::UnexpectedText,
8969                    b"Nzzz" => Error::UnexpectedText,
8970                    b"NKzzz" => Error::UnexpectedText,
8971                    b"NKOzzz" => Error::UnexpectedText,
8972                    b"NKO3abczzz" => Error::UnexpectedText,
8973                    b"NKO3abc3abczzz" => Error::UnexpectedText,
8974                    b"" => Error::UnexpectedEnd,
8975                    b"N" => Error::UnexpectedEnd,
8976                    b"NK" => Error::UnexpectedEnd,
8977                    b"NKO" => Error::UnexpectedEnd,
8978                    b"NKO3abc" => Error::UnexpectedEnd,
8979                    b"NKO3abc3abc" => Error::UnexpectedEnd,
8980                }
8981            }
8982        });
8983    }
8984
8985    #[test]
8986    fn parse_prefix_handle() {
8987        // <prefix> ::= <unqualified-name>
8988        //          ::= <prefix> <unqualified-name>
8989        //          ::= <template-prefix> <template-args>
8990        //          ::= <template-param>
8991        //          ::= <decltype>
8992        //          ::= <prefix> <data-member-prefix>
8993        //          ::= <substitution>
8994        assert_parse!(PrefixHandle {
8995            with subs [
8996                Substitutable::Prefix(
8997                    Prefix::Unqualified(
8998                        UnqualifiedName::Operator(
8999                            OperatorName::Simple(
9000                                SimpleOperatorName::New),
9001                            AbiTags::default()))),
9002            ] => {
9003                Ok => {
9004                    b"3foo..." => {
9005                        PrefixHandle::BackReference(1),
9006                        b"...",
9007                        [
9008                            Substitutable::Prefix(
9009                                Prefix::Unqualified(
9010                                    UnqualifiedName::Source(
9011                                        SourceName(Identifier {
9012                                            start: 1,
9013                                            end: 4,
9014                                        }),
9015                                        AbiTags::default())))
9016                        ]
9017                    }
9018                    b"3abc3def..." => {
9019                        PrefixHandle::BackReference(2),
9020                        b"...",
9021                        [
9022                            Substitutable::Prefix(
9023                                Prefix::Unqualified(
9024                                    UnqualifiedName::Source(
9025                                        SourceName(Identifier {
9026                                            start: 1,
9027                                            end: 4,
9028                                        }),
9029                                    AbiTags::default()))),
9030                            Substitutable::Prefix(
9031                                Prefix::Nested(
9032                                    PrefixHandle::BackReference(1),
9033                                    UnqualifiedName::Source(
9034                                        SourceName(Identifier {
9035                                            start: 5,
9036                                            end: 8,
9037                                        }),
9038                                    AbiTags::default()))),
9039                        ]
9040                    }
9041                    b"3fooIJEE..." => {
9042                        PrefixHandle::BackReference(2),
9043                        b"...",
9044                        [
9045                            Substitutable::Prefix(
9046                                Prefix::Unqualified(
9047                                    UnqualifiedName::Source(
9048                                        SourceName(Identifier {
9049                                            start: 1,
9050                                            end: 4,
9051                                        }),
9052                                        AbiTags::default()))),
9053                            Substitutable::Prefix(
9054                                Prefix::Template(PrefixHandle::BackReference(1),
9055                                                 TemplateArgs(vec![
9056                                                     TemplateArg::ArgPack(vec![]),
9057                                                 ])))
9058                        ]
9059                    }
9060                    b"T_..." => {
9061                        PrefixHandle::BackReference(1),
9062                        b"...",
9063                        [
9064                            Substitutable::Prefix(Prefix::TemplateParam(TemplateParam(0))),
9065                        ]
9066                    }
9067                    b"DTtrE..." => {
9068                        PrefixHandle::BackReference(1),
9069                        b"...",
9070                        [
9071                            Substitutable::Prefix(
9072                                Prefix::Decltype(
9073                                    Decltype::Expression(Expression::Rethrow))),
9074                        ]
9075                    }
9076                    b"3abc3defM..." => {
9077                        PrefixHandle::BackReference(2),
9078                        b"...",
9079                        [
9080                            Substitutable::Prefix(
9081                                Prefix::Unqualified(
9082                                    UnqualifiedName::Source(
9083                                        SourceName(Identifier {
9084                                            start: 1,
9085                                            end: 4,
9086                                        }),
9087                                        AbiTags::default()))),
9088                            Substitutable::Prefix(
9089                                Prefix::DataMember(
9090                                    PrefixHandle::BackReference(1),
9091                                    DataMemberPrefix(
9092                                        SourceName(Identifier {
9093                                            start: 5,
9094                                            end: 8,
9095                                        })))),
9096                        ]
9097                    }
9098                    b"S_..." => {
9099                        PrefixHandle::BackReference(0),
9100                        b"...",
9101                        []
9102                    }
9103                    // The trailing E and <nested-name> case...
9104                    b"3abc3defE..." => {
9105                        PrefixHandle::NonSubstitution(NonSubstitution(0)),
9106                        b"E...",
9107                        [
9108                            Substitutable::Prefix(
9109                                Prefix::Unqualified(
9110                                    UnqualifiedName::Source(
9111                                        SourceName(Identifier {
9112                                            start: 1,
9113                                            end: 4,
9114                                        }),
9115                                    AbiTags::default()))),
9116                        ]
9117                    }
9118                }
9119                Err => {
9120                    b"zzz" => Error::UnexpectedText,
9121                    b"" => Error::UnexpectedEnd,
9122                }
9123            }
9124        });
9125    }
9126
9127    #[test]
9128    fn parse_type_handle() {
9129        assert_parse!(TypeHandle {
9130            with subs [
9131                Substitutable::Type(
9132                    Type::PointerTo(
9133                        TypeHandle::Builtin(BuiltinType::Standard(StandardBuiltinType::Char)))),
9134            ] => {
9135                Ok => {
9136                    b"S_..." => {
9137                        TypeHandle::BackReference(0),
9138                        b"...",
9139                        []
9140                    }
9141                    b"c..." => {
9142                        TypeHandle::Builtin(BuiltinType::Standard(StandardBuiltinType::Char)),
9143                        b"...",
9144                        []
9145                    }
9146                    b"FS_E..." => {
9147                        TypeHandle::BackReference(1),
9148                        b"...",
9149                        [
9150                            Substitutable::Type(
9151                                Type::Function(FunctionType {
9152                                    cv_qualifiers: CvQualifiers {
9153                                        restrict: false,
9154                                        volatile: false,
9155                                        const_: false,
9156                                    },
9157                                    exception_spec: None,
9158                                    transaction_safe: false,
9159                                    extern_c: false,
9160                                    bare: BareFunctionType(vec![TypeHandle::BackReference(0)]),
9161                                    ref_qualifier: None,
9162                                })),
9163                        ]
9164                    }
9165                    b"A_S_..." => {
9166                        TypeHandle::BackReference(1),
9167                        b"...",
9168                        [
9169                            Substitutable::Type(
9170                                Type::Array(ArrayType::NoDimension(TypeHandle::BackReference(0)))),
9171                        ]
9172                    }
9173                    b"MS_S_..." => {
9174                        TypeHandle::BackReference(1),
9175                        b"...",
9176                        [
9177                            Substitutable::Type(
9178                                Type::PointerToMember(
9179                                    PointerToMemberType(TypeHandle::BackReference(0),
9180                                                        TypeHandle::BackReference(0)))),
9181                        ]
9182                    }
9183                    b"T_..." => {
9184                        TypeHandle::BackReference(1),
9185                        b"...",
9186                        [
9187                            Substitutable::Type(Type::TemplateParam(TemplateParam(0))),
9188                        ]
9189                    }
9190                    b"T_IS_E..." => {
9191                        TypeHandle::BackReference(2),
9192                        b"...",
9193                        [
9194                            Substitutable::TemplateTemplateParam(
9195                                TemplateTemplateParam(TemplateParam(0))),
9196                            Substitutable::Type(
9197                                Type::TemplateTemplate(
9198                                    TemplateTemplateParamHandle::BackReference(1),
9199                                    TemplateArgs(vec![
9200                                        TemplateArg::Type(TypeHandle::BackReference(0))
9201                                    ]))),
9202                        ]
9203                    }
9204                    b"DTtrE..." => {
9205                        TypeHandle::BackReference(1),
9206                        b"...",
9207                        [
9208                            Substitutable::Type(
9209                                Type::Decltype(Decltype::Expression(Expression::Rethrow))),
9210                        ]
9211                    }
9212                    b"KS_..." => {
9213                        TypeHandle::BackReference(1),
9214                        b"...",
9215                        [
9216                            Substitutable::Type(Type::Qualified(CvQualifiers {
9217                                restrict: false,
9218                                volatile: false,
9219                                const_: true,
9220                            }, TypeHandle::BackReference(0)))
9221                        ]
9222                    }
9223                    b"PS_..." => {
9224                        TypeHandle::BackReference(1),
9225                        b"...",
9226                        [
9227                            Substitutable::Type(Type::PointerTo(TypeHandle::BackReference(0)))
9228                        ]
9229                    }
9230                    b"RS_..." => {
9231                        TypeHandle::BackReference(1),
9232                        b"...",
9233                        [
9234                            Substitutable::Type(Type::LvalueRef(TypeHandle::BackReference(0)))
9235                        ]
9236                    }
9237                    b"OS_..." => {
9238                        TypeHandle::BackReference(1),
9239                        b"...",
9240                        [
9241                            Substitutable::Type(Type::RvalueRef(TypeHandle::BackReference(0)))
9242                        ]
9243                    }
9244                    b"CS_..." => {
9245                        TypeHandle::BackReference(1),
9246                        b"...",
9247                        [
9248                            Substitutable::Type(Type::Complex(TypeHandle::BackReference(0)))
9249                        ]
9250                    }
9251                    b"GS_..." => {
9252                        TypeHandle::BackReference(1),
9253                        b"...",
9254                        [
9255                            Substitutable::Type(Type::Imaginary(TypeHandle::BackReference(0)))
9256                        ]
9257                    }
9258                    b"U3abcS_..." => {
9259                        TypeHandle::BackReference(1),
9260                        b"...",
9261                        [
9262                            Substitutable::Type(
9263                                Type::VendorExtension(
9264                                    SourceName(Identifier {
9265                                        start: 2,
9266                                        end: 5,
9267                                    }),
9268                                    None,
9269                                    TypeHandle::BackReference(0)))
9270                        ]
9271                    }
9272                    b"U3abcIS_ES_..." => {
9273                        TypeHandle::BackReference(1),
9274                        b"...",
9275                        [
9276                            Substitutable::Type(
9277                                Type::VendorExtension(
9278                                    SourceName(Identifier {
9279                                        start: 2,
9280                                        end: 5,
9281                                    }),
9282                                    Some(TemplateArgs(vec![
9283                                        TemplateArg::Type(TypeHandle::BackReference(0))
9284                                    ])),
9285                                    TypeHandle::BackReference(0)))
9286                        ]
9287                    }
9288                    b"DpS_..." => {
9289                        TypeHandle::BackReference(1),
9290                        b"...",
9291                        [
9292                            Substitutable::Type(
9293                                Type::PackExpansion(TypeHandle::BackReference(0))),
9294                        ]
9295                    }
9296                    b"3abc..." => {
9297                        TypeHandle::BackReference(1),
9298                        b"...",
9299                        [
9300                            Substitutable::Type(
9301                                Type::ClassEnum(
9302                                    ClassEnumType::Named(
9303                                        Name::Unscoped(
9304                                            UnscopedName::Unqualified(
9305                                                UnqualifiedName::Source(
9306                                                    SourceName(Identifier {
9307                                                        start: 1,
9308                                                        end: 4,
9309                                                    }),
9310                                                    AbiTags::default()))))))
9311                        ]
9312                    }
9313                }
9314                Err => {
9315                    b"P" => Error::UnexpectedEnd,
9316                    b"R" => Error::UnexpectedEnd,
9317                    b"O" => Error::UnexpectedEnd,
9318                    b"C" => Error::UnexpectedEnd,
9319                    b"G" => Error::UnexpectedEnd,
9320                    b"Dp" => Error::UnexpectedEnd,
9321                    b"D" => Error::UnexpectedEnd,
9322                    b"P" => Error::UnexpectedEnd,
9323                    b"UlvE_" => Error::UnexpectedText,
9324                    b"" => Error::UnexpectedEnd,
9325                }
9326            }
9327        });
9328    }
9329
9330    #[test]
9331    fn parse_exception_spec() {
9332        assert_parse!(ExceptionSpec {
9333            Ok => {
9334                b"Do..." => {
9335                    ExceptionSpec::NoExcept,
9336                    b"..."
9337                }
9338                b"DOtrE..." => {
9339                    ExceptionSpec::Computed(Expression::Rethrow),
9340                    b"..."
9341                }
9342            }
9343            Err => {
9344                b"DOtre" => Error::UnexpectedText,
9345                b"DOE" => Error::UnexpectedText,
9346                b"D" => Error::UnexpectedEnd,
9347                b"" => Error::UnexpectedEnd,
9348            }
9349        });
9350    }
9351
9352    #[test]
9353    fn parse_function_type() {
9354        assert_parse!(FunctionType {
9355            with subs [
9356                Substitutable::Type(
9357                    Type::PointerTo(
9358                        TypeHandle::Builtin(BuiltinType::Standard(StandardBuiltinType::Char)))),
9359            ] => {
9360                Ok => {
9361                    b"KDxFYS_RE..." => {
9362                        FunctionType {
9363                            cv_qualifiers: CvQualifiers {
9364                                restrict: false,
9365                                volatile: false,
9366                                const_: true,
9367                            },
9368                            exception_spec: None,
9369                            transaction_safe: true,
9370                            extern_c: true,
9371                            bare: BareFunctionType(vec![TypeHandle::BackReference(0)]),
9372                            ref_qualifier: Some(RefQualifier::LValueRef),
9373                        },
9374                        b"...",
9375                        []
9376                    }
9377                    b"DxFYS_RE..." => {
9378                        FunctionType {
9379                            cv_qualifiers: CvQualifiers {
9380                                restrict: false,
9381                                volatile: false,
9382                                const_: false,
9383                            },
9384                            exception_spec: None,
9385                            transaction_safe: true,
9386                            extern_c: true,
9387                            bare: BareFunctionType(vec![TypeHandle::BackReference(0)]),
9388                            ref_qualifier: Some(RefQualifier::LValueRef),
9389                        },
9390                        b"...",
9391                        []
9392                    }
9393                    b"FYS_RE..." => {
9394                        FunctionType {
9395                            cv_qualifiers: CvQualifiers {
9396                                restrict: false,
9397                                volatile: false,
9398                                const_: false,
9399                            },
9400                            exception_spec: None,
9401                            transaction_safe: false,
9402                            extern_c: true,
9403                            bare: BareFunctionType(vec![TypeHandle::BackReference(0)]),
9404                            ref_qualifier: Some(RefQualifier::LValueRef),
9405                        },
9406                        b"...",
9407                        []
9408                    }
9409                    b"FS_RE..." => {
9410                        FunctionType {
9411                            cv_qualifiers: CvQualifiers {
9412                                restrict: false,
9413                                volatile: false,
9414                                const_: false,
9415                            },
9416                            exception_spec: None,
9417                            transaction_safe: false,
9418                            extern_c: false,
9419                            bare: BareFunctionType(vec![TypeHandle::BackReference(0)]),
9420                            ref_qualifier: Some(RefQualifier::LValueRef),
9421                        },
9422                        b"...",
9423                        []
9424                    }
9425                    b"FS_E..." => {
9426                        FunctionType {
9427                            cv_qualifiers: CvQualifiers {
9428                                restrict: false,
9429                                volatile: false,
9430                                const_: false,
9431                            },
9432                            exception_spec: None,
9433                            transaction_safe: false,
9434                            extern_c: false,
9435                            bare: BareFunctionType(vec![TypeHandle::BackReference(0)]),
9436                            ref_qualifier: None,
9437                        },
9438                        b"...",
9439                        []
9440                    }
9441                }
9442                Err => {
9443                    b"DFYS_E" => Error::UnexpectedText,
9444                    b"KKFS_E" => Error::UnexpectedText,
9445                    b"FYS_..." => Error::UnexpectedText,
9446                    b"FYS_" => Error::UnexpectedEnd,
9447                    b"F" => Error::UnexpectedEnd,
9448                    b"" => Error::UnexpectedEnd,
9449                }
9450            }
9451        });
9452    }
9453
9454    #[test]
9455    fn parse_bare_function_type() {
9456        assert_parse!(BareFunctionType {
9457            with subs [
9458                Substitutable::Type(
9459                    Type::PointerTo(
9460                        TypeHandle::Builtin(BuiltinType::Standard(StandardBuiltinType::Char)))),
9461            ] => {
9462                Ok => {
9463                    b"S_S_..." => {
9464                        BareFunctionType(vec![
9465                            TypeHandle::BackReference(0),
9466                            TypeHandle::BackReference(0),
9467                        ]),
9468                        b"...",
9469                        []
9470                    }
9471                }
9472                Err => {
9473                    b"" => Error::UnexpectedEnd,
9474                }
9475            }
9476        });
9477    }
9478
9479    #[test]
9480    fn parse_decltype() {
9481        assert_parse!(Decltype {
9482            Ok => {
9483                b"DTtrE..." => {
9484                    Decltype::Expression(Expression::Rethrow),
9485                    b"..."
9486                }
9487                b"DttrE..." => {
9488                    Decltype::IdExpression(Expression::Rethrow),
9489                    b"..."
9490                }
9491            }
9492            Err => {
9493                b"Dtrtz" => Error::UnexpectedText,
9494                b"DTrtz" => Error::UnexpectedText,
9495                b"Dz" => Error::UnexpectedText,
9496                b"Dtrt" => Error::UnexpectedText,
9497                b"DTrt" => Error::UnexpectedText,
9498                b"Dt" => Error::UnexpectedEnd,
9499                b"DT" => Error::UnexpectedEnd,
9500                b"D" => Error::UnexpectedEnd,
9501                b"" => Error::UnexpectedEnd,
9502            }
9503        });
9504    }
9505
9506    #[test]
9507    fn parse_class_enum_type() {
9508        assert_parse!(ClassEnumType {
9509            Ok => {
9510                b"3abc..." => {
9511                    ClassEnumType::Named(
9512                        Name::Unscoped(
9513                            UnscopedName::Unqualified(
9514                                UnqualifiedName::Source(
9515                                    SourceName(Identifier {
9516                                        start: 1,
9517                                        end: 4,
9518                                    }),
9519                                    AbiTags::default())))),
9520                    b"..."
9521                }
9522                b"Ts3abc..." => {
9523                    ClassEnumType::ElaboratedStruct(
9524                        Name::Unscoped(
9525                            UnscopedName::Unqualified(
9526                                UnqualifiedName::Source(
9527                                    SourceName(Identifier {
9528                                        start: 3,
9529                                        end: 6,
9530                                    }),
9531                                    AbiTags::default())))),
9532                    b"..."
9533                }
9534                b"Tu3abc..." => {
9535                    ClassEnumType::ElaboratedUnion(
9536                        Name::Unscoped(
9537                            UnscopedName::Unqualified(
9538                                UnqualifiedName::Source(
9539                                    SourceName(Identifier {
9540                                        start: 3,
9541                                        end: 6,
9542                                    }),
9543                                    AbiTags::default())))),
9544                    b"..."
9545                }
9546                b"Te3abc..." => {
9547                    ClassEnumType::ElaboratedEnum(
9548                        Name::Unscoped(
9549                            UnscopedName::Unqualified(
9550                                UnqualifiedName::Source(
9551                                    SourceName(Identifier {
9552                                        start: 3,
9553                                        end: 6,
9554                                    }),
9555                                AbiTags::default())))),
9556                    b"..."
9557                }
9558            }
9559            Err => {
9560                b"zzz" => Error::UnexpectedText,
9561                b"Tzzz" => Error::UnexpectedText,
9562                b"T" => Error::UnexpectedEnd,
9563                b"" => Error::UnexpectedEnd,
9564            }
9565        });
9566    }
9567
9568    #[test]
9569    fn parse_array_type() {
9570        assert_parse!(ArrayType {
9571            with subs [
9572                Substitutable::Type(Type::Decltype(Decltype::Expression(Expression::Rethrow)))
9573            ] => {
9574                Ok => {
9575                    b"A10_S_..." => {
9576                        ArrayType::DimensionNumber(10, TypeHandle::BackReference(0)),
9577                        b"...",
9578                        []
9579                    }
9580                    b"A10_Sb..." => {
9581                        ArrayType::DimensionNumber(10,
9582                                                   TypeHandle::WellKnown(
9583                                                       WellKnownComponent::StdString1)),
9584                        b"...",
9585                        []
9586                    }
9587                    b"Atr_S_..." => {
9588                        ArrayType::DimensionExpression(Expression::Rethrow,
9589                                                       TypeHandle::BackReference(0)),
9590                        b"...",
9591                        []
9592                    }
9593                    b"A_S_..." => {
9594                        ArrayType::NoDimension(TypeHandle::BackReference(0)),
9595                        b"...",
9596                        []
9597                    }
9598                }
9599                Err => {
9600                    b"A10_" => Error::UnexpectedEnd,
9601                    b"A10" => Error::UnexpectedEnd,
9602                    b"A" => Error::UnexpectedEnd,
9603                    b"" => Error::UnexpectedEnd,
9604                    b"A10_..." => Error::UnexpectedText,
9605                    b"A10..." => Error::UnexpectedText,
9606                    b"A..." => Error::UnexpectedText,
9607                    b"..." => Error::UnexpectedText,
9608                }
9609            }
9610        });
9611    }
9612
9613    #[test]
9614    fn parse_vector_type() {
9615        assert_parse!(VectorType {
9616            with subs [
9617                Substitutable::Type(Type::Decltype(Decltype::Expression(Expression::Rethrow)))
9618            ] => {
9619                Ok => {
9620                    b"Dv10_S_..." => {
9621                        VectorType::DimensionNumber(10, TypeHandle::BackReference(0)),
9622                        b"...",
9623                        []
9624                    }
9625                    b"Dv10_Sb..." => {
9626                        VectorType::DimensionNumber(10,
9627                                                    TypeHandle::WellKnown(
9628                                                        WellKnownComponent::StdString1)),
9629                        b"...",
9630                        []
9631                    }
9632                    b"Dvtr_S_..." => {
9633                        VectorType::DimensionExpression(Expression::Rethrow,
9634                                                        TypeHandle::BackReference(0)),
9635                        b"...",
9636                        []
9637                    }
9638                }
9639                Err => {
9640                    b"Dq" => Error::UnexpectedText,
9641                    b"Dv" => Error::UnexpectedEnd,
9642                    b"Dv42_" => Error::UnexpectedEnd,
9643                    b"Dv42_..." => Error::UnexpectedText,
9644                    b"Dvtr_" => Error::UnexpectedEnd,
9645                    b"Dvtr_..." => Error::UnexpectedText,
9646                    b"" => Error::UnexpectedEnd,
9647                    b"..." => Error::UnexpectedText,
9648                }
9649            }
9650        });
9651    }
9652
9653    #[test]
9654    fn parse_pointer_to_member_type() {
9655        assert_parse!(PointerToMemberType {
9656            with subs [
9657                Substitutable::Type(Type::Decltype(Decltype::Expression(Expression::Rethrow)))
9658            ] => {
9659                Ok => {
9660                    b"MS_S_..." => {
9661                        PointerToMemberType(TypeHandle::BackReference(0),
9662                                            TypeHandle::BackReference(0)),
9663                        b"...",
9664                        []
9665                    }
9666                }
9667                Err => {
9668                    b"MS_S" => Error::UnexpectedEnd,
9669                    b"MS_" => Error::UnexpectedEnd,
9670                    b"MS" => Error::UnexpectedEnd,
9671                    b"M" => Error::UnexpectedEnd,
9672                    b"" => Error::UnexpectedEnd,
9673                    b"MS_..." => Error::UnexpectedText,
9674                    b"M..." => Error::UnexpectedText,
9675                    b"..." => Error::UnexpectedText,
9676                }
9677            }
9678        });
9679    }
9680
9681    #[test]
9682    fn parse_template_template_param_handle() {
9683        assert_parse!(TemplateTemplateParamHandle {
9684            with subs [
9685                Substitutable::TemplateTemplateParam(TemplateTemplateParam(TemplateParam(0)))
9686            ] => {
9687                Ok => {
9688                    b"S_..." => {
9689                        TemplateTemplateParamHandle::BackReference(0),
9690                        b"...",
9691                        []
9692                    }
9693                    b"T1_..." => {
9694                        TemplateTemplateParamHandle::BackReference(1),
9695                        b"...",
9696                        [
9697                            Substitutable::TemplateTemplateParam(TemplateTemplateParam(TemplateParam(2)))
9698                        ]
9699                    }
9700                }
9701                Err => {
9702                    b"S" => Error::UnexpectedText,
9703                    b"T" => Error::UnexpectedEnd,
9704                    b"" => Error::UnexpectedEnd,
9705                    b"S..." => Error::UnexpectedText,
9706                    b"T..." => Error::UnexpectedText,
9707                    b"..." => Error::UnexpectedText,
9708                }
9709            }
9710        });
9711    }
9712
9713    #[test]
9714    fn parse_template_args() {
9715        assert_parse!(TemplateArgs {
9716            with subs [
9717                Substitutable::Type(Type::Decltype(Decltype::Expression(Expression::Rethrow)))
9718            ] => {
9719                Ok => {
9720                    b"IS_E..." => {
9721                        TemplateArgs(vec![TemplateArg::Type(TypeHandle::BackReference(0))]),
9722                        b"...",
9723                        []
9724                    }
9725                    b"IS_S_S_S_E..." => {
9726                        TemplateArgs(vec![
9727                            TemplateArg::Type(TypeHandle::BackReference(0)),
9728                            TemplateArg::Type(TypeHandle::BackReference(0)),
9729                            TemplateArg::Type(TypeHandle::BackReference(0)),
9730                            TemplateArg::Type(TypeHandle::BackReference(0)),
9731                        ]),
9732                        b"...",
9733                        []
9734                    }
9735                }
9736                Err => {
9737                    b"zzz" => Error::UnexpectedText,
9738                    b"IE" => Error::UnexpectedText,
9739                    b"IS_" => Error::UnexpectedEnd,
9740                    b"I" => Error::UnexpectedEnd,
9741                    b"" => Error::UnexpectedEnd,
9742                }
9743            }
9744        });
9745    }
9746
9747    #[test]
9748    fn parse_template_arg() {
9749        assert_parse!(TemplateArg {
9750            with subs [
9751                Substitutable::Type(Type::Decltype(Decltype::Expression(Expression::Rethrow)))
9752            ] => {
9753                Ok => {
9754                    b"S_..." => {
9755                        TemplateArg::Type(TypeHandle::BackReference(0)),
9756                        b"...",
9757                        []
9758                    }
9759                    b"XtrE..." => {
9760                        TemplateArg::Expression(Expression::Rethrow),
9761                        b"...",
9762                        []
9763                    }
9764                    b"XsrS_1QE..." => {
9765                        TemplateArg::Expression(
9766                            Expression::UnresolvedName(
9767                                UnresolvedName::Nested1(
9768                                    UnresolvedTypeHandle::BackReference(0),
9769                                    vec![],
9770                                    BaseUnresolvedName::Name(
9771                                        SimpleId(
9772                                            SourceName(Identifier {
9773                                                start: 6,
9774                                                end: 7
9775                                            }),
9776                                            None
9777                                        )
9778                                    )
9779                                )
9780                            )
9781                        ),
9782                        b"...",
9783                        []
9784                    }
9785                    b"XsrS_1QIlEE..." => {
9786                        TemplateArg::Expression(
9787                            Expression::UnresolvedName(
9788                                UnresolvedName::Nested1(
9789                                    UnresolvedTypeHandle::BackReference(0),
9790                                    vec![],
9791                                    BaseUnresolvedName::Name(
9792                                        SimpleId(
9793                                            SourceName(Identifier {
9794                                                start: 6,
9795                                                end: 7
9796                                            }),
9797                                            Some(
9798                                                TemplateArgs(
9799                                                    vec![
9800                                                        TemplateArg::Type(
9801                                                            TypeHandle::Builtin(
9802                                                                BuiltinType::Standard(
9803                                                                    StandardBuiltinType::Long
9804                                                                )
9805                                                            )
9806                                                        )
9807                                                    ]
9808                                                )
9809                                            )
9810                                        )
9811                                    )
9812                                )
9813                            )
9814                        ),
9815                        b"...",
9816                        []
9817                    }
9818                    b"LS_E..." => {
9819                        TemplateArg::SimpleExpression(
9820                            ExprPrimary::Literal(TypeHandle::BackReference(0), 3, 3)),
9821                        b"...",
9822                        []
9823                    }
9824                    b"JE..." => {
9825                        TemplateArg::ArgPack(vec![]),
9826                        b"...",
9827                        []
9828                    }
9829                    b"JS_XtrELS_EJEE..." => {
9830                        TemplateArg::ArgPack(vec![
9831                            TemplateArg::Type(TypeHandle::BackReference(0)),
9832                            TemplateArg::Expression(Expression::Rethrow),
9833                            TemplateArg::SimpleExpression(
9834                                ExprPrimary::Literal(TypeHandle::BackReference(0), 10, 10)),
9835                            TemplateArg::ArgPack(vec![]),
9836                        ]),
9837                        b"...",
9838                        []
9839                    }
9840                }
9841                Err => {
9842                    b"..." => Error::UnexpectedText,
9843                    b"X..." => Error::UnexpectedText,
9844                    b"J..." => Error::UnexpectedText,
9845                    b"JS_..." => Error::UnexpectedText,
9846                    b"JS_" => Error::UnexpectedEnd,
9847                    b"X" => Error::UnexpectedEnd,
9848                    b"J" => Error::UnexpectedEnd,
9849                    b"" => Error::UnexpectedEnd,
9850                }
9851            }
9852        });
9853    }
9854
9855    #[test]
9856    fn parse_expression() {
9857        assert_parse!(Expression {
9858            with subs [
9859                Substitutable::Type(
9860                    Type::PointerTo(TypeHandle::Builtin(
9861                        BuiltinType::Standard(StandardBuiltinType::Int)))),
9862            ] => {
9863                Ok => {
9864                    b"psLS_1E..." => {
9865                        Expression::Unary(OperatorName::Simple(SimpleOperatorName::UnaryPlus),
9866                                          Box::new(Expression::Primary(
9867                                              ExprPrimary::Literal(
9868                                                  TypeHandle::BackReference(0),
9869                                                  5,
9870                                                  6)))),
9871                        b"...",
9872                        []
9873                    }
9874                    b"rsLS_1ELS_1E..." => {
9875                        Expression::Binary(OperatorName::Simple(SimpleOperatorName::Shr),
9876                                           Box::new(Expression::Primary(
9877                                               ExprPrimary::Literal(
9878                                                   TypeHandle::BackReference(0),
9879                                                   5,
9880                                                   6))),
9881                                           Box::new(Expression::Primary(
9882                                               ExprPrimary::Literal(
9883                                                   TypeHandle::BackReference(0),
9884                                                   10,
9885                                                   11)))),
9886                        b"...",
9887                        []
9888                    }
9889                    b"quLS_1ELS_2ELS_3E..." => {
9890                        Expression::Ternary(OperatorName::Simple(SimpleOperatorName::Question),
9891                                            Box::new(Expression::Primary(
9892                                                ExprPrimary::Literal(
9893                                                    TypeHandle::BackReference(0),
9894                                                    5,
9895                                                    6))),
9896                                            Box::new(Expression::Primary(
9897                                                ExprPrimary::Literal(
9898                                                    TypeHandle::BackReference(0),
9899                                                    10,
9900                                                    11))),
9901                                            Box::new(Expression::Primary(
9902                                                ExprPrimary::Literal(
9903                                                    TypeHandle::BackReference(0),
9904                                                    15,
9905                                                    16)))),
9906                        b"...",
9907                        []
9908                    }
9909                    b"pp_LS_1E..." => {
9910                        Expression::PrefixInc(
9911                            Box::new(Expression::Primary(
9912                                ExprPrimary::Literal(
9913                                    TypeHandle::BackReference(0),
9914                                    6,
9915                                    7)))),
9916                        b"...",
9917                        []
9918                    }
9919                    b"mm_LS_1E..." => {
9920                        Expression::PrefixDec(
9921                            Box::new(Expression::Primary(
9922                                ExprPrimary::Literal(
9923                                    TypeHandle::BackReference(0),
9924                                    6,
9925                                    7)))),
9926                        b"...",
9927                        []
9928                    }
9929                    b"clLS_1EE..." => {
9930                        Expression::Call(
9931                            Box::new(Expression::Primary(
9932                                ExprPrimary::Literal(
9933                                    TypeHandle::BackReference(0),
9934                                    5,
9935                                    6))),
9936                            vec![]),
9937                        b"...",
9938                        []
9939                    }
9940                    //               ::= cv <type> <expression>                       # type (expression), conversion with one argument
9941                    b"cvS_LS_1E..." => {
9942                        Expression::ConversionOne(
9943                            TypeHandle::BackReference(0),
9944                            Box::new(Expression::Primary(
9945                                ExprPrimary::Literal(
9946                                    TypeHandle::BackReference(0),
9947                                    7,
9948                                    8)))),
9949                        b"...",
9950                        []
9951                    }
9952                    b"cvS__LS_1ELS_1EE..." => {
9953                        Expression::ConversionMany(
9954                            TypeHandle::BackReference(0),
9955                            vec![
9956                                Expression::Primary(
9957                                    ExprPrimary::Literal(
9958                                        TypeHandle::BackReference(0),
9959                                        8,
9960                                        9)),
9961                                Expression::Primary(
9962                                    ExprPrimary::Literal(
9963                                        TypeHandle::BackReference(0),
9964                                        13,
9965                                        14)),
9966                            ]),
9967                        b"...",
9968                        []
9969                    }
9970                    b"tlS_LS_1ELS_1EE..." => {
9971                        Expression::ConversionBraced(
9972                            TypeHandle::BackReference(0),
9973                            vec![
9974                                Expression::Primary(
9975                                    ExprPrimary::Literal(
9976                                        TypeHandle::BackReference(0),
9977                                        7,
9978                                        8)),
9979                                Expression::Primary(
9980                                    ExprPrimary::Literal(
9981                                        TypeHandle::BackReference(0),
9982                                        12,
9983                                        13)),
9984                            ]),
9985                        b"...",
9986                        []
9987                    }
9988                    b"ilLS_1EE..." => {
9989                        Expression::BracedInitList(
9990                            Box::new(Expression::Primary(
9991                                ExprPrimary::Literal(
9992                                    TypeHandle::BackReference(0),
9993                                    5,
9994                                    6)))),
9995                        b"...",
9996                        []
9997                    }
9998                    b"gsnwLS_1E_S_E..." => {
9999                        Expression::GlobalNew(
10000                            vec![
10001                                Expression::Primary(
10002                                    ExprPrimary::Literal(
10003                                        TypeHandle::BackReference(0),
10004                                        7,
10005                                        8))
10006                            ],
10007                            TypeHandle::BackReference(0),
10008                            None),
10009                        b"...",
10010                        []
10011                    }
10012                    b"nwLS_1E_S_E..." => {
10013                        Expression::New(
10014                            vec![
10015                                Expression::Primary(
10016                                    ExprPrimary::Literal(
10017                                        TypeHandle::BackReference(0),
10018                                        5,
10019                                        6))
10020                            ],
10021                            TypeHandle::BackReference(0),
10022                            None),
10023                        b"...",
10024                        []
10025                    }
10026                    b"gsnwLS_1E_S_piE..." => {
10027                        Expression::GlobalNew(
10028                            vec![
10029                                Expression::Primary(
10030                                    ExprPrimary::Literal(
10031                                        TypeHandle::BackReference(0),
10032                                        7,
10033                                        8))
10034                            ],
10035                            TypeHandle::BackReference(0),
10036                            Some(Initializer(vec![]))),
10037                        b"...",
10038                        []
10039                    }
10040                    b"nwLS_1E_S_piE..." => {
10041                        Expression::New(
10042                            vec![
10043                                Expression::Primary(
10044                                    ExprPrimary::Literal(
10045                                        TypeHandle::BackReference(0),
10046                                        5,
10047                                        6))
10048                            ],
10049                            TypeHandle::BackReference(0),
10050                            Some(Initializer(vec![]))),
10051                        b"...",
10052                        []
10053                    }
10054                    b"gsnaLS_1E_S_E..." => {
10055                        Expression::GlobalNewArray(
10056                            vec![
10057                                Expression::Primary(
10058                                    ExprPrimary::Literal(
10059                                        TypeHandle::BackReference(0),
10060                                        7,
10061                                        8))
10062                            ],
10063                            TypeHandle::BackReference(0),
10064                            None),
10065                        b"...",
10066                        []
10067                    }
10068                    b"naLS_1E_S_E..." => {
10069                        Expression::NewArray(
10070                            vec![
10071                                Expression::Primary(
10072                                    ExprPrimary::Literal(
10073                                        TypeHandle::BackReference(0),
10074                                        5,
10075                                        6))
10076                            ],
10077                            TypeHandle::BackReference(0),
10078                            None),
10079                        b"...",
10080                        []
10081                    }
10082                    b"gsnaLS_1E_S_piE..." => {
10083                        Expression::GlobalNewArray(
10084                            vec![
10085                                Expression::Primary(
10086                                    ExprPrimary::Literal(
10087                                        TypeHandle::BackReference(0),
10088                                        7,
10089                                        8))
10090                            ],
10091                            TypeHandle::BackReference(0),
10092                            Some(Initializer(vec![]))),
10093                        b"...",
10094                        []
10095                    }
10096                    b"naLS_1E_S_piE..." => {
10097                        Expression::NewArray(
10098                            vec![
10099                                Expression::Primary(
10100                                    ExprPrimary::Literal(
10101                                        TypeHandle::BackReference(0),
10102                                        5,
10103                                        6))
10104                            ],
10105                            TypeHandle::BackReference(0),
10106                            Some(Initializer(vec![]))),
10107                        b"...",
10108                        []
10109                    }
10110                    b"gsdlLS_1E..." => {
10111                        Expression::GlobalDelete(
10112                            Box::new(Expression::Primary(
10113                                ExprPrimary::Literal(
10114                                    TypeHandle::BackReference(0),
10115                                    7,
10116                                    8)))),
10117                        b"...",
10118                        []
10119                    }
10120                    b"dlLS_1E..." => {
10121                        Expression::Delete(
10122                            Box::new(Expression::Primary(
10123                                ExprPrimary::Literal(
10124                                    TypeHandle::BackReference(0),
10125                                    5,
10126                                    6)))),
10127                        b"...",
10128                        []
10129                    }
10130                    //               ::= [gs] da <expression>                         # delete[] expression
10131                    b"gsdaLS_1E..." => {
10132                        Expression::GlobalDeleteArray(
10133                            Box::new(Expression::Primary(
10134                                ExprPrimary::Literal(
10135                                    TypeHandle::BackReference(0),
10136                                    7,
10137                                    8)))),
10138                        b"...",
10139                        []
10140                    }
10141                    b"daLS_1E..." => {
10142                        Expression::DeleteArray(
10143                            Box::new(Expression::Primary(
10144                                ExprPrimary::Literal(
10145                                    TypeHandle::BackReference(0),
10146                                    5,
10147                                    6)))),
10148                        b"...",
10149                        []
10150                    }
10151                    b"dcS_LS_1E..." => {
10152                        Expression::DynamicCast(
10153                            TypeHandle::BackReference(0),
10154                            Box::new(Expression::Primary(
10155                                ExprPrimary::Literal(
10156                                    TypeHandle::BackReference(0),
10157                                    7,
10158                                    8)))),
10159                        b"...",
10160                        []
10161                    }
10162                    b"scS_LS_1E..." => {
10163                        Expression::StaticCast(
10164                            TypeHandle::BackReference(0),
10165                            Box::new(Expression::Primary(
10166                                ExprPrimary::Literal(
10167                                    TypeHandle::BackReference(0),
10168                                    7,
10169                                    8)))),
10170                        b"...",
10171                        []
10172                    }
10173                    b"ccS_LS_1E..." => {
10174                        Expression::ConstCast(
10175                            TypeHandle::BackReference(0),
10176                            Box::new(Expression::Primary(
10177                                ExprPrimary::Literal(
10178                                    TypeHandle::BackReference(0),
10179                                    7,
10180                                    8)))),
10181                        b"...",
10182                        []
10183                    }
10184                    b"rcS_LS_1E..." => {
10185                        Expression::ReinterpretCast(
10186                            TypeHandle::BackReference(0),
10187                            Box::new(Expression::Primary(
10188                                ExprPrimary::Literal(
10189                                    TypeHandle::BackReference(0),
10190                                    7,
10191                                    8)))),
10192                        b"...",
10193                        []
10194                    }
10195                    b"tiS_..." => {
10196                        Expression::TypeidType(TypeHandle::BackReference(0)),
10197                        b"...",
10198                        []
10199                    }
10200                    b"teLS_1E..." => {
10201                        Expression::TypeidExpr(
10202                            Box::new(Expression::Primary(
10203                                ExprPrimary::Literal(
10204                                    TypeHandle::BackReference(0),
10205                                    5,
10206                                    6)))),
10207                        b"...",
10208                        []
10209                    }
10210                    b"stS_..." => {
10211                        Expression::SizeofType(TypeHandle::BackReference(0)),
10212                        b"...",
10213                        []
10214                    }
10215                    b"szLS_1E..." => {
10216                        Expression::SizeofExpr(
10217                            Box::new(Expression::Primary(
10218                                ExprPrimary::Literal(
10219                                    TypeHandle::BackReference(0),
10220                                    5,
10221                                    6)))),
10222                        b"...",
10223                        []
10224                    }
10225                    b"atS_..." => {
10226                        Expression::AlignofType(TypeHandle::BackReference(0)),
10227                        b"...",
10228                        []
10229                    }
10230                    b"azLS_1E..." => {
10231                        Expression::AlignofExpr(
10232                            Box::new(Expression::Primary(
10233                                ExprPrimary::Literal(
10234                                    TypeHandle::BackReference(0),
10235                                    5,
10236                                    6)))),
10237                        b"...",
10238                        []
10239                    }
10240                    b"nxLS_1E..." => {
10241                        Expression::Noexcept(
10242                            Box::new(Expression::Primary(
10243                                ExprPrimary::Literal(
10244                                    TypeHandle::BackReference(0),
10245                                    5,
10246                                    6)))),
10247                        b"...",
10248                        []
10249                    }
10250                    b"T_..." => {
10251                        Expression::TemplateParam(TemplateParam(0)),
10252                        b"...",
10253                        []
10254                    }
10255                    b"fp_..." => {
10256                        Expression::FunctionParam(FunctionParam(0, CvQualifiers::default(), Some(0))),
10257                        b"...",
10258                        []
10259                    }
10260                    b"dtT_3abc..." => {
10261                        Expression::Member(
10262                            Box::new(Expression::TemplateParam(TemplateParam(0))),
10263                            MemberName(
10264                                Name::Unscoped(
10265                                    UnscopedName::Unqualified(
10266                                        UnqualifiedName::Source(
10267                                            SourceName(
10268                                                Identifier {
10269                                                    start: 5,
10270                                                    end: 8,
10271                                                }),
10272                                            AbiTags::default()))))),
10273                        b"...",
10274                        []
10275                    }
10276                    b"ptT_3abc..." => {
10277                        Expression::DerefMember(
10278                            Box::new(Expression::TemplateParam(TemplateParam(0))),
10279                            MemberName(
10280                                Name::Unscoped(
10281                                    UnscopedName::Unqualified(
10282                                        UnqualifiedName::Source(
10283                                            SourceName(
10284                                                Identifier {
10285                                                    start: 5,
10286                                                    end: 8,
10287                                                }),
10288                                            AbiTags::default()))))),
10289                        b"...",
10290                        []
10291                    }
10292                    b"dtfp_clI3abcE..." => {
10293                        Expression::Member(
10294                            Box::new(Expression::FunctionParam(FunctionParam(0, CvQualifiers::default(), Some(0)))),
10295                            MemberName(
10296                                Name::UnscopedTemplate(
10297                                    UnscopedTemplateNameHandle::NonSubstitution(NonSubstitution(0)),
10298                                    TemplateArgs(vec![
10299                                        TemplateArg::Type(
10300                                            TypeHandle::BackReference(1))])))),
10301                        b"...",
10302                        [
10303                            Substitutable::Type(
10304                                Type::ClassEnum(
10305                                    ClassEnumType::Named(
10306                                        Name::Unscoped(
10307                                            UnscopedName::Unqualified(
10308                                                UnqualifiedName::Source(
10309                                                    SourceName(
10310                                                        Identifier {
10311                                                            start: 9,
10312                                                            end: 12
10313                                                        }),
10314                                                    AbiTags::default()))))))
10315                        ]
10316                    }
10317                    //               ::= ds <expression> <expression>                 # expr.*expr
10318                    b"dsT_T_..." => {
10319                        Expression::PointerToMember(
10320                            Box::new(Expression::TemplateParam(TemplateParam(0))),
10321                            Box::new(Expression::TemplateParam(TemplateParam(0)))),
10322                        b"...",
10323                        []
10324                    }
10325                    b"sZT_..." => {
10326                        Expression::SizeofTemplatePack(TemplateParam(0)),
10327                        b"...",
10328                        []
10329                    }
10330                    b"sZfp_..." => {
10331                        Expression::SizeofFunctionPack(
10332                            FunctionParam(0, CvQualifiers::default(), Some(0))),
10333                        b"...",
10334                        []
10335                    }
10336                    b"sPE..." => {
10337                        Expression::SizeofCapturedTemplatePack(vec![]),
10338                        b"...",
10339                        []
10340                    }
10341                    b"spT_..." => {
10342                        Expression::PackExpansion(
10343                            Box::new(Expression::TemplateParam(TemplateParam(0)))),
10344                        b"...",
10345                        []
10346                    }
10347                    b"twT_..." => {
10348                        Expression::Throw(Box::new(Expression::TemplateParam(TemplateParam(0)))),
10349                        b"...",
10350                        []
10351                    }
10352                    b"tr..." => {
10353                        Expression::Rethrow,
10354                        b"...",
10355                        []
10356                    }
10357                    b"3abc..." => {
10358                        Expression::UnresolvedName(
10359                            UnresolvedName::Name(
10360                                BaseUnresolvedName::Name(
10361                                    SimpleId(
10362                                        SourceName(Identifier {
10363                                            start: 1,
10364                                            end: 4,
10365                                        }),
10366                                        None)))),
10367                        b"...",
10368                        []
10369                    }
10370                    b"L_Z3abcE..." => {
10371                        Expression::Primary(
10372                            ExprPrimary::External(
10373                                MangledName::Encoding(
10374                                    Encoding::Data(
10375                                        Name::Unscoped(
10376                                            UnscopedName::Unqualified(
10377                                                UnqualifiedName::Source(
10378                                                    SourceName(Identifier {
10379                                                        start: 4,
10380                                                        end: 7,
10381                                                    }),
10382                                                AbiTags::default())))), vec![]))),
10383                        b"...",
10384                        []
10385                    }
10386                    // An expression where arity matters
10387                    b"cldtdefpT4TypeadsrT_5EnterE..." => {
10388                        Expression::Call(
10389                            Box::new(Expression::Member(
10390                                Box::new(Expression::Unary(OperatorName::Simple(SimpleOperatorName::Deref),
10391                                                           Box::new(Expression::FunctionParam(
10392                                                               FunctionParam(0,
10393                                                                             CvQualifiers::default(),
10394                                                                             None)
10395                                                           ))
10396                                )),
10397                                MemberName(
10398                                    Name::Unscoped(
10399                                        UnscopedName::Unqualified(
10400                                            UnqualifiedName::Source(
10401                                                SourceName(Identifier {
10402                                                    start: 10,
10403                                                    end: 14,
10404                                                }),
10405                                                AbiTags::default()))
10406                                     )
10407                                )
10408                            )),
10409                            vec![Expression::Unary(OperatorName::Simple(SimpleOperatorName::AddressOf),
10410                                                   Box::new(Expression::UnresolvedName(
10411                                                       UnresolvedName::Nested1(
10412                                                           UnresolvedTypeHandle::BackReference(1),
10413                                                           vec![],
10414                                                           BaseUnresolvedName::Name(
10415                                                               SimpleId(
10416                                                                   SourceName(Identifier {
10417                                                                           start: 21,
10418                                                                           end: 26
10419                                                                   }
10420                                                                   ),
10421                                                                   None
10422                                                               )
10423                                                           )
10424                                                       ))))]
10425                        ),
10426                        b"...",
10427                        [
10428                            Substitutable::UnresolvedType(UnresolvedType::Template(TemplateParam(0), None))
10429                        ]
10430                    }
10431                }
10432                Err => {
10433                    b"dtStfp_clI3abcE..." => Error::UnexpectedText,
10434                }
10435            }
10436        });
10437    }
10438
10439    #[test]
10440    fn parse_unresolved_name() {
10441        assert_parse!(UnresolvedName {
10442            with subs [
10443                Substitutable::UnresolvedType(
10444                    UnresolvedType::Decltype(Decltype::Expression(Expression::Rethrow))),
10445            ] => {
10446                Ok => {
10447                    b"gs3abc..." => {
10448                        UnresolvedName::Global(BaseUnresolvedName::Name(SimpleId(SourceName(Identifier {
10449                            start: 3,
10450                            end: 6,
10451                        }), None))),
10452                        b"...",
10453                        []
10454                    }
10455                    b"3abc..." => {
10456                        UnresolvedName::Name(BaseUnresolvedName::Name(SimpleId(SourceName(Identifier {
10457                            start: 1,
10458                            end: 4,
10459                        }), None))),
10460                        b"...",
10461                        []
10462                    }
10463                    b"srS_3abc..." => {
10464                        UnresolvedName::Nested1(UnresolvedTypeHandle::BackReference(0),
10465                                                vec![],
10466                                                BaseUnresolvedName::Name(SimpleId(SourceName(Identifier {
10467                                                    start: 5,
10468                                                    end: 8,
10469                                                }), None))),
10470                        b"...",
10471                        []
10472                    }
10473                    b"srNS_3abc3abcE3abc..." => {
10474                        UnresolvedName::Nested1(
10475                            UnresolvedTypeHandle::BackReference(0),
10476                            vec![
10477                                UnresolvedQualifierLevel(SimpleId(SourceName(Identifier {
10478                                    start: 6,
10479                                    end: 9,
10480                                }), None)),
10481                                UnresolvedQualifierLevel(SimpleId(SourceName(Identifier {
10482                                    start: 10,
10483                                    end: 13,
10484                                }), None)),
10485                            ],
10486                            BaseUnresolvedName::Name(SimpleId(SourceName(Identifier {
10487                                start: 15,
10488                                end: 18,
10489                            }), None))),
10490                        b"...",
10491                        []
10492                    }
10493                    b"gssr3abcE3abc..." => {
10494                        UnresolvedName::GlobalNested2(
10495                            vec![
10496                                UnresolvedQualifierLevel(SimpleId(SourceName(Identifier {
10497                                    start: 5,
10498                                    end: 8,
10499                                }), None)),
10500                            ],
10501                            BaseUnresolvedName::Name(SimpleId(SourceName(Identifier {
10502                                start: 10,
10503                                end: 13,
10504                            }), None))),
10505                        b"...",
10506                        []
10507                    }
10508                    b"sr3abcE3abc..." => {
10509                        UnresolvedName::Nested2(
10510                            vec![
10511                                UnresolvedQualifierLevel(SimpleId(SourceName(Identifier {
10512                                    start: 3,
10513                                    end: 6,
10514                                }), None)),
10515                            ],
10516                            BaseUnresolvedName::Name(SimpleId(SourceName(Identifier {
10517                                start: 8,
10518                                end: 11,
10519                            }), None))),
10520                        b"...",
10521                        []
10522                    }
10523                }
10524                Err => {
10525                    b"zzzzzz" => Error::UnexpectedText,
10526                    b"gszzz" => Error::UnexpectedText,
10527                    b"gssrzzz" => Error::UnexpectedText,
10528                    b"srNzzz" => Error::UnexpectedText,
10529                    b"srzzz" => Error::UnexpectedText,
10530                    b"srN3abczzzz" => Error::UnexpectedText,
10531                    b"srN3abcE" => Error::UnexpectedText,
10532                    b"srN3abc" => Error::UnexpectedText,
10533                    b"srN" => Error::UnexpectedEnd,
10534                    b"sr" => Error::UnexpectedEnd,
10535                    b"gssr" => Error::UnexpectedEnd,
10536                    b"gs" => Error::UnexpectedEnd,
10537                    b"" => Error::UnexpectedEnd,
10538                }
10539            }
10540        });
10541    }
10542
10543    #[test]
10544    fn parse_unresolved_type_handle() {
10545        assert_parse!(UnresolvedTypeHandle {
10546            with subs [
10547                Substitutable::UnresolvedType(
10548                    UnresolvedType::Decltype(Decltype::Expression(Expression::Rethrow))),
10549            ] => {
10550                Ok => {
10551                    b"S_..." => {
10552                        UnresolvedTypeHandle::BackReference(0),
10553                        b"...",
10554                        []
10555                    }
10556                    b"T_..." => {
10557                        UnresolvedTypeHandle::BackReference(1),
10558                        b"...",
10559                        [
10560                            Substitutable::UnresolvedType(
10561                                UnresolvedType::Template(TemplateParam(0), None)),
10562                        ]
10563                    }
10564                    b"T_IS_E..." => {
10565                        UnresolvedTypeHandle::BackReference(1),
10566                        b"...",
10567                        [
10568                            Substitutable::UnresolvedType(
10569                                UnresolvedType::Template(TemplateParam(0), Some(TemplateArgs(vec![
10570                                    TemplateArg::Type(TypeHandle::BackReference(0))
10571                                ])))),
10572                        ]
10573                    }
10574                    b"DTtrE..." => {
10575                        UnresolvedTypeHandle::BackReference(1),
10576                        b"...",
10577                        [
10578                            Substitutable::UnresolvedType(
10579                                UnresolvedType::Decltype(Decltype::Expression(Expression::Rethrow)))
10580                        ]
10581
10582                    }
10583                }
10584                Err => {
10585                    b"zzzzzzz" => Error::UnexpectedText,
10586                    b"" => Error::UnexpectedEnd,
10587                }
10588            }
10589        });
10590    }
10591
10592    #[test]
10593    fn parse_unresolved_qualifier_level() {
10594        assert_parse!(UnresolvedQualifierLevel {
10595            with subs [
10596                Substitutable::Type(Type::Decltype(Decltype::Expression(Expression::Rethrow)))
10597            ] => {
10598                Ok => {
10599                    b"3abc..." => {
10600                        UnresolvedQualifierLevel(SimpleId(SourceName(Identifier {
10601                            start: 1,
10602                            end: 4,
10603                        }), None)),
10604                        b"...",
10605                        []
10606                    }
10607                    b"3abcIS_E..." => {
10608                        UnresolvedQualifierLevel(SimpleId(SourceName(Identifier {
10609                            start: 1,
10610                            end: 4,
10611                        }), Some(TemplateArgs(vec![
10612                            TemplateArg::Type(TypeHandle::BackReference(0))
10613                        ])))),
10614                        b"...",
10615                        []
10616                    }
10617                }
10618                Err => {
10619                    b"zzz" => Error::UnexpectedText,
10620                    b"" => Error::UnexpectedEnd,
10621                }
10622            }
10623        });
10624    }
10625
10626    #[test]
10627    fn parse_simple_id() {
10628        assert_parse!(SimpleId {
10629            with subs [
10630                Substitutable::Type(Type::Decltype(Decltype::Expression(Expression::Rethrow)))
10631            ] => {
10632                Ok => {
10633                    b"3abc..." => {
10634                        SimpleId(SourceName(Identifier {
10635                            start: 1,
10636                            end: 4,
10637                        }), None),
10638                        b"...",
10639                        []
10640                    }
10641                    b"3abcIS_E..." => {
10642                        SimpleId(SourceName(Identifier {
10643                            start: 1,
10644                            end: 4,
10645                        }), Some(TemplateArgs(vec![
10646                            TemplateArg::Type(TypeHandle::BackReference(0))
10647                        ]))),
10648                        b"...",
10649                        []
10650                    }
10651                }
10652                Err => {
10653                    b"zzz" => Error::UnexpectedText,
10654                    b"" => Error::UnexpectedEnd,
10655                }
10656            }
10657        });
10658    }
10659
10660    #[test]
10661    fn parse_base_unresolved_name() {
10662        assert_parse!(BaseUnresolvedName {
10663            with subs [
10664                Substitutable::Type(Type::Decltype(Decltype::Expression(Expression::Rethrow)))
10665            ] => {
10666                Ok => {
10667                    b"3abc..." => {
10668                        BaseUnresolvedName::Name(SimpleId(SourceName(Identifier {
10669                            start: 1,
10670                            end: 4,
10671                        }), None)),
10672                        b"...",
10673                        []
10674                    }
10675                    b"onnw..." => {
10676                        BaseUnresolvedName::Operator(OperatorName::Simple(SimpleOperatorName::New), None),
10677                        b"...",
10678                        []
10679                    }
10680                    b"onnwIS_E..." => {
10681                        BaseUnresolvedName::Operator(OperatorName::Simple(SimpleOperatorName::New),
10682                                                     Some(TemplateArgs(vec![
10683                                                         TemplateArg::Type(TypeHandle::BackReference(0))
10684                                                     ]))),
10685                        b"...",
10686                        []
10687                    }
10688                    b"dn3abc..." => {
10689                        BaseUnresolvedName::Destructor(DestructorName::Name(SimpleId(SourceName(Identifier {
10690                            start: 3,
10691                            end: 6,
10692                        }), None))),
10693                        b"...",
10694                        []
10695                    }
10696                }
10697                Err => {
10698                    b"ozzz" => Error::UnexpectedText,
10699                    b"dzzz" => Error::UnexpectedText,
10700                    b"dn" => Error::UnexpectedEnd,
10701                    b"on" => Error::UnexpectedEnd,
10702                    b"" => Error::UnexpectedEnd,
10703                }
10704            }
10705        });
10706    }
10707
10708    #[test]
10709    fn parse_destructor_name() {
10710        assert_parse!(DestructorName {
10711            with subs [
10712                Substitutable::UnresolvedType(
10713                    UnresolvedType::Decltype(Decltype::Expression(Expression::Rethrow))),
10714            ] => {
10715                Ok => {
10716                    b"S_..." => {
10717                        DestructorName::Unresolved(UnresolvedTypeHandle::BackReference(0)),
10718                        b"...",
10719                        []
10720                    }
10721                    b"3abc..." => {
10722                        DestructorName::Name(SimpleId(SourceName(Identifier {
10723                            start: 1,
10724                            end: 4,
10725                        }), None)),
10726                        b"...",
10727                        []
10728                    }
10729                }
10730                Err => {
10731                    b"zzz" => Error::UnexpectedText,
10732                    b"" => Error::UnexpectedEnd,
10733                }
10734            }
10735        });
10736    }
10737
10738    #[test]
10739    fn parse_expr_primary() {
10740        assert_parse!(ExprPrimary {
10741            with subs [
10742                Substitutable::Type(Type::Decltype(Decltype::Expression(Expression::Rethrow)))
10743            ] => {
10744                Ok => {
10745                    b"LS_12345E..." => {
10746                        ExprPrimary::Literal(TypeHandle::BackReference(0), 3, 8),
10747                        b"...",
10748                        []
10749                    }
10750                    b"LS_E..." => {
10751                        ExprPrimary::Literal(TypeHandle::BackReference(0), 3, 3),
10752                        b"...",
10753                        []
10754                    }
10755                    b"L_Z3abcE..." => {
10756                        ExprPrimary::External(
10757                            MangledName::Encoding(
10758                                Encoding::Data(
10759                                    Name::Unscoped(
10760                                        UnscopedName::Unqualified(
10761                                            UnqualifiedName::Source(
10762                                                SourceName(Identifier {
10763                                                    start: 4,
10764                                                    end: 7,
10765                                                }),
10766                                                AbiTags::default())))), vec![])),
10767                        b"...",
10768                        []
10769                    }
10770                }
10771                Err => {
10772                    b"zzz" => Error::UnexpectedText,
10773                    b"LS_zzz" => Error::UnexpectedEnd,
10774                    b"LS_12345" => Error::UnexpectedEnd,
10775                    b"LS_" => Error::UnexpectedEnd,
10776                    b"L" => Error::UnexpectedEnd,
10777                    b"" => Error::UnexpectedEnd,
10778                }
10779            }
10780        });
10781    }
10782
10783    #[test]
10784    fn parse_initializer() {
10785        assert_parse!(Initializer {
10786            Ok => {
10787                b"piE..." => {
10788                    Initializer(vec![]),
10789                    b"..."
10790                }
10791                b"pitrtrtrE..." => {
10792                    Initializer(vec![
10793                        Expression::Rethrow,
10794                        Expression::Rethrow,
10795                        Expression::Rethrow,
10796                    ]),
10797                    b"..."
10798                }
10799            }
10800            Err => {
10801                b"pirtrtrt..." => Error::UnexpectedText,
10802                b"pi..." => Error::UnexpectedText,
10803                b"..." => Error::UnexpectedText,
10804                b"pirt" => Error::UnexpectedText,
10805                b"pi" => Error::UnexpectedEnd,
10806                b"p" => Error::UnexpectedEnd,
10807                b"" => Error::UnexpectedEnd,
10808            }
10809        });
10810    }
10811
10812    #[test]
10813    fn parse_local_name() {
10814        assert_parse!(LocalName {
10815            Ok => {
10816                b"Z3abcE3def_0..." => {
10817                    LocalName::Relative(
10818                        Box::new(Encoding::Data(
10819                            Name::Unscoped(
10820                                UnscopedName::Unqualified(
10821                                    UnqualifiedName::Source(
10822                                        SourceName(Identifier {
10823                                            start: 2,
10824                                            end: 5,
10825                                        }),
10826                                        AbiTags::default()))))),
10827                        Some(Box::new(Name::Unscoped(
10828                            UnscopedName::Unqualified(
10829                                UnqualifiedName::Source(
10830                                    SourceName(Identifier {
10831                                        start: 7,
10832                                        end: 10,
10833                                    }),
10834                                    AbiTags::default()))))),
10835                        Some(Discriminator(0))),
10836                    b"..."
10837                }
10838                b"Z3abcE3def..." => {
10839                    LocalName::Relative(
10840                        Box::new(Encoding::Data(
10841                            Name::Unscoped(
10842                                UnscopedName::Unqualified(
10843                                    UnqualifiedName::Source(
10844                                        SourceName(Identifier {
10845                                            start: 2,
10846                                            end: 5,
10847                                        }),
10848                                        AbiTags::default()))))),
10849                        Some(Box::new(Name::Unscoped(
10850                            UnscopedName::Unqualified(
10851                                UnqualifiedName::Source(
10852                                    SourceName(Identifier {
10853                                        start: 7,
10854                                        end: 10,
10855                                    }),
10856                                    AbiTags::default()))))),
10857                        None),
10858                    b"..."
10859                }
10860                b"Z3abcEs_0..." => {
10861                    LocalName::Relative(
10862                        Box::new(Encoding::Data(
10863                            Name::Unscoped(
10864                                UnscopedName::Unqualified(
10865                                    UnqualifiedName::Source(
10866                                        SourceName(Identifier {
10867                                            start: 2,
10868                                            end: 5,
10869                                        }),
10870                                    AbiTags::default()))))),
10871                        None,
10872                        Some(Discriminator(0))),
10873                    b"..."
10874                }
10875                b"Z3abcEs..." => {
10876                    LocalName::Relative(
10877                        Box::new(Encoding::Data(
10878                            Name::Unscoped(
10879                                UnscopedName::Unqualified(
10880                                    UnqualifiedName::Source(
10881                                        SourceName(Identifier {
10882                                            start: 2,
10883                                            end: 5,
10884                                        }),
10885                                    AbiTags::default()))))),
10886                        None,
10887                        None),
10888                    b"..."
10889                }
10890                b"Z3abcEd1_3abc..." => {
10891                    LocalName::Default(
10892                        Box::new(Encoding::Data(
10893                            Name::Unscoped(
10894                                UnscopedName::Unqualified(
10895                                    UnqualifiedName::Source(
10896                                        SourceName(Identifier {
10897                                            start: 2,
10898                                            end: 5,
10899                                        }),
10900                                    AbiTags::default()))))),
10901                        Some(1),
10902                        Box::new(Name::Unscoped(
10903                            UnscopedName::Unqualified(
10904                                UnqualifiedName::Source(
10905                                    SourceName(Identifier {
10906                                        start: 10,
10907                                        end: 13,
10908                                    }),
10909                                    AbiTags::default()))))),
10910                    b"..."
10911                }
10912                b"Z3abcEd_3abc..." => {
10913                    LocalName::Default(
10914                        Box::new(Encoding::Data(
10915                            Name::Unscoped(
10916                                UnscopedName::Unqualified(
10917                                    UnqualifiedName::Source(
10918                                        SourceName(Identifier {
10919                                            start: 2,
10920                                            end: 5,
10921                                        }),
10922                                        AbiTags::default()))))),
10923                        None,
10924                        Box::new(Name::Unscoped(
10925                            UnscopedName::Unqualified(
10926                                UnqualifiedName::Source(
10927                                    SourceName(Identifier {
10928                                        start: 9,
10929                                        end: 12,
10930                                    }), AbiTags::default()))))),
10931                    b"..."
10932                }
10933            }
10934            Err => {
10935                b"A" => Error::UnexpectedText,
10936                b"Z1a" => Error::UnexpectedEnd,
10937                b"Z1aE" => Error::UnexpectedEnd,
10938                b"Z" => Error::UnexpectedEnd,
10939                b"" => Error::UnexpectedEnd,
10940            }
10941        });
10942    }
10943
10944    #[test]
10945    fn parse_closure_type_name() {
10946        assert_parse!(ClosureTypeName {
10947            Ok => {
10948                b"UlvE_..." => {
10949                    ClosureTypeName(LambdaSig(vec![]), None),
10950                    b"..."
10951                }
10952                b"UlvE36_..." => {
10953                    ClosureTypeName(LambdaSig(vec![]), Some(36)),
10954                    b"..."
10955                }
10956            }
10957            Err => {
10958                b"UlvE36zzz" => Error::UnexpectedText,
10959                b"UlvEzzz" => Error::UnexpectedText,
10960                b"Ulvzzz" => Error::UnexpectedText,
10961                b"zzz" => Error::UnexpectedText,
10962                b"UlvE10" => Error::UnexpectedEnd,
10963                b"UlvE" => Error::UnexpectedEnd,
10964                b"Ulv" => Error::UnexpectedEnd,
10965                b"Ul" => Error::UnexpectedEnd,
10966                b"U" => Error::UnexpectedEnd,
10967                b"" => Error::UnexpectedEnd,
10968            }
10969        });
10970    }
10971
10972    #[test]
10973    fn parse_lambda_sig() {
10974        assert_parse!(LambdaSig {
10975            with subs [
10976                Substitutable::Type(
10977                    Type::PointerTo(
10978                        TypeHandle::Builtin(BuiltinType::Standard(StandardBuiltinType::Bool))))
10979            ] => {
10980                Ok => {
10981                    b"v..." => {
10982                        LambdaSig(vec![]),
10983                        b"...",
10984                        []
10985                    }
10986                    b"S_S_S_..." => {
10987                        LambdaSig(vec![
10988                            TypeHandle::BackReference(0),
10989                            TypeHandle::BackReference(0),
10990                            TypeHandle::BackReference(0),
10991                        ]),
10992                        b"...",
10993                        []
10994                    }
10995                }
10996                Err => {
10997                    b"..." => Error::UnexpectedText,
10998                    b"S" => Error::UnexpectedEnd,
10999                    b"" => Error::UnexpectedEnd,
11000                }
11001            }
11002        });
11003    }
11004
11005    #[test]
11006    fn parse_substitution() {
11007        assert_parse!(Substitution {
11008            with subs [
11009                Substitutable::Type(Type::Decltype(Decltype::Expression(Expression::Rethrow))),
11010                Substitutable::Type(Type::Decltype(Decltype::Expression(Expression::Rethrow))),
11011                Substitutable::Type(Type::Decltype(Decltype::Expression(Expression::Rethrow)))
11012            ] => {
11013                Ok => {
11014                    b"S_..." => {
11015                        Substitution::BackReference(0),
11016                        b"...",
11017                        []
11018                    }
11019                    b"S1_..." => {
11020                        Substitution::BackReference(2),
11021                        b"...",
11022                        []
11023                    }
11024                    b"St..." => {
11025                        Substitution::WellKnown(WellKnownComponent::Std),
11026                        b"...",
11027                        []
11028                    }
11029                    b"Sa..." => {
11030                        Substitution::WellKnown(WellKnownComponent::StdAllocator),
11031                        b"...",
11032                        []
11033                    }
11034                    b"Sb..." => {
11035                        Substitution::WellKnown(WellKnownComponent::StdString1),
11036                        b"...",
11037                        []
11038                    }
11039                    b"Ss..." => {
11040                        Substitution::WellKnown(WellKnownComponent::StdString2),
11041                        b"...",
11042                        []
11043                    }
11044                    b"Si..." => {
11045                        Substitution::WellKnown(WellKnownComponent::StdIstream),
11046                        b"...",
11047                        []
11048                    }
11049                    b"So..." => {
11050                        Substitution::WellKnown(WellKnownComponent::StdOstream),
11051                        b"...",
11052                        []
11053                    }
11054                    b"Sd..." => {
11055                        Substitution::WellKnown(WellKnownComponent::StdIostream),
11056                        b"...",
11057                        []
11058                    }
11059                }
11060                Err => {
11061                    b"S999_" => Error::BadBackReference,
11062                    b"Sz" => Error::UnexpectedText,
11063                    b"zzz" => Error::UnexpectedText,
11064                    b"S1" => Error::UnexpectedEnd,
11065                    b"S" => Error::UnexpectedEnd,
11066                    b"" => Error::UnexpectedEnd,
11067                }
11068            }
11069        });
11070    }
11071
11072    #[test]
11073    fn parse_special_name() {
11074        assert_parse!(SpecialName {
11075            Ok => {
11076                b"TVi..." => {
11077                    SpecialName::VirtualTable(TypeHandle::Builtin(BuiltinType::Standard(StandardBuiltinType::Int))),
11078                    b"..."
11079                }
11080                b"TTi..." => {
11081                    SpecialName::Vtt(TypeHandle::Builtin(BuiltinType::Standard(StandardBuiltinType::Int))),
11082                    b"..."
11083                }
11084                b"TIi..." => {
11085                    SpecialName::Typeinfo(TypeHandle::Builtin(BuiltinType::Standard(StandardBuiltinType::Int))),
11086                    b"..."
11087                }
11088                b"TSi..." => {
11089                    SpecialName::TypeinfoName(TypeHandle::Builtin(BuiltinType::Standard(StandardBuiltinType::Int))),
11090                    b"..."
11091                }
11092                b"Tv42_36_3abc..." => {
11093                    SpecialName::VirtualOverrideThunk(
11094                        CallOffset::Virtual(VOffset(42, 36)),
11095                        Box::new(Encoding::Data(
11096                            Name::Unscoped(
11097                                UnscopedName::Unqualified(
11098                                    UnqualifiedName::Source(
11099                                        SourceName(Identifier {
11100                                            start: 9,
11101                                            end: 12,
11102                                        }), AbiTags::default())))))),
11103                    b"..."
11104                }
11105                b"Tcv42_36_v42_36_3abc..." => {
11106                    SpecialName::VirtualOverrideThunkCovariant(
11107                        CallOffset::Virtual(VOffset(42, 36)),
11108                        CallOffset::Virtual(VOffset(42, 36)),
11109                        Box::new(Encoding::Data(
11110                            Name::Unscoped(
11111                                UnscopedName::Unqualified(
11112                                    UnqualifiedName::Source(
11113                                        SourceName(Identifier {
11114                                            start: 17,
11115                                            end: 20,
11116                                        }), AbiTags::default())))))),
11117                    b"..."
11118                }
11119                b"GV3abc..." => {
11120                    SpecialName::Guard(
11121                        Name::Unscoped(
11122                            UnscopedName::Unqualified(
11123                                UnqualifiedName::Source(
11124                                    SourceName(Identifier {
11125                                        start: 3,
11126                                        end: 6,
11127                                    }), AbiTags::default())))),
11128                    b"..."
11129                }
11130                b"GR3abc_..." => {
11131                    SpecialName::GuardTemporary(
11132                        Name::Unscoped(
11133                            UnscopedName::Unqualified(
11134                                UnqualifiedName::Source(
11135                                    SourceName(Identifier {
11136                                        start: 3,
11137                                        end: 6,
11138                                    }),
11139                                    AbiTags::default()))),
11140                        0),
11141                    b"..."
11142                }
11143                b"GR3abc0_..." => {
11144                    SpecialName::GuardTemporary(
11145                        Name::Unscoped(
11146                            UnscopedName::Unqualified(
11147                                UnqualifiedName::Source(
11148                                    SourceName(Identifier {
11149                                        start: 3,
11150                                        end: 6,
11151                                    }),
11152                                    AbiTags::default()))),
11153                        1),
11154                    b"..."
11155                }
11156                b"Gr4_abc..." => {
11157                    SpecialName::JavaResource(vec![ResourceName {
11158                        start: 4,
11159                        end: 7,
11160                    }]),
11161                    b"..."
11162                }
11163                b"TCc7_i..." => {
11164                    SpecialName::ConstructionVtable(
11165                        TypeHandle::Builtin(BuiltinType::Standard(StandardBuiltinType::Char)),
11166                        7,
11167                        TypeHandle::Builtin(BuiltinType::Standard(StandardBuiltinType::Int))
11168                    ),
11169                    b"..."
11170                }
11171                b"TFi..." => {
11172                    SpecialName::TypeinfoFunction(
11173                        TypeHandle::Builtin(BuiltinType::Standard(StandardBuiltinType::Int))),
11174                    b"..."
11175                }
11176                b"TH4name..." => {
11177                    SpecialName::TlsInit(
11178                        Name::Unscoped(
11179                            UnscopedName::Unqualified(
11180                                UnqualifiedName::Source(
11181                                    SourceName(Identifier { start: 3, end: 7 }),
11182                                AbiTags::default())))),
11183                    b"..."
11184                }
11185                b"TW4name..." => {
11186                    SpecialName::TlsWrapper(
11187                        Name::Unscoped(
11188                            UnscopedName::Unqualified(
11189                                UnqualifiedName::Source(
11190                                    SourceName(Identifier { start: 3, end: 7 }),
11191                                AbiTags::default())))),
11192                    b"..."
11193                }
11194            }
11195            Err => {
11196                b"TZ" => Error::UnexpectedText,
11197                b"GZ" => Error::UnexpectedText,
11198                b"GR3abcz" => Error::UnexpectedText,
11199                b"GR3abc0z" => Error::UnexpectedText,
11200                b"T" => Error::UnexpectedEnd,
11201                b"G" => Error::UnexpectedEnd,
11202                b"" => Error::UnexpectedEnd,
11203                b"GR3abc" => Error::UnexpectedEnd,
11204                b"GR3abc0" => Error::UnexpectedEnd,
11205                // This number is not allowed to be negative.
11206                b"TCcn7_i..." => Error::UnexpectedText,
11207                b"Gr3abc0" => Error::UnexpectedText,
11208            }
11209        });
11210    }
11211
11212    #[test]
11213    fn parse_function_param() {
11214        assert_parse!(FunctionParam {
11215            Ok => {
11216                b"fpK_..." => {
11217                    FunctionParam(0,
11218                                  CvQualifiers {
11219                                      restrict: false,
11220                                      volatile: false,
11221                                      const_: true,
11222                                  },
11223                                  Some(0)),
11224                    b"..."
11225                }
11226                b"fL1pK_..." => {
11227                    FunctionParam(1,
11228                                  CvQualifiers {
11229                                      restrict: false,
11230                                      volatile: false,
11231                                      const_: true,
11232                                  },
11233                                  Some(0)),
11234                    b"..."
11235                }
11236                b"fpK3_..." => {
11237                    FunctionParam(0,
11238                                  CvQualifiers {
11239                                      restrict: false,
11240                                      volatile: false,
11241                                      const_: true,
11242                                  },
11243                                  Some(4)),
11244                    b"..."
11245                }
11246                b"fL1pK4_..." => {
11247                    FunctionParam(1,
11248                                  CvQualifiers {
11249                                      restrict: false,
11250                                      volatile: false,
11251                                      const_: true,
11252                                  },
11253                                  Some(5)),
11254                    b"..."
11255                }
11256            }
11257            Err => {
11258                b"fz" => Error::UnexpectedText,
11259                b"fLp_" => Error::UnexpectedText,
11260                b"fpL_" => Error::UnexpectedText,
11261                b"fL1pK4z" => Error::UnexpectedText,
11262                b"fL1pK4" => Error::UnexpectedEnd,
11263                b"fL1p" => Error::UnexpectedEnd,
11264                b"fL1" => Error::UnexpectedEnd,
11265                b"fL" => Error::UnexpectedEnd,
11266                b"f" => Error::UnexpectedEnd,
11267                b"" => Error::UnexpectedEnd,
11268            }
11269        });
11270    }
11271
11272    #[test]
11273    fn parse_discriminator() {
11274        assert_parse!(Discriminator {
11275            Ok => {
11276                b"_0..." => {
11277                    Discriminator(0),
11278                    b"..."
11279                }
11280                b"_9..." => {
11281                    Discriminator(9),
11282                    b"..."
11283                }
11284                b"__99_..." => {
11285                    Discriminator(99),
11286                    b"..."
11287                }
11288            }
11289            Err => {
11290                b"_n1" => Error::UnexpectedText,
11291                b"__99..." => Error::UnexpectedText,
11292                b"__99" => Error::UnexpectedEnd,
11293                b"..." => Error::UnexpectedText,
11294            }
11295        });
11296    }
11297
11298    #[test]
11299    fn parse_data_member_prefix() {
11300        assert_parse!(DataMemberPrefix {
11301            Ok => {
11302                b"3fooM..." => {
11303                    DataMemberPrefix(SourceName(Identifier {
11304                        start: 1,
11305                        end: 4,
11306                    })),
11307                    b"..."
11308                }
11309            }
11310            Err => {
11311                b"zzz" => Error::UnexpectedText,
11312                b"1" => Error::UnexpectedEnd,
11313                b"" => Error::UnexpectedEnd,
11314            }
11315        });
11316    }
11317
11318    #[test]
11319    fn parse_ref_qualifier() {
11320        assert_parse!(RefQualifier {
11321            Ok => {
11322                b"R..." => {
11323                    RefQualifier::LValueRef,
11324                    b"..."
11325                }
11326                b"O..." => {
11327                    RefQualifier::RValueRef,
11328                    b"..."
11329                }
11330            }
11331            Err => {
11332                b"..." => Error::UnexpectedText,
11333                b"" => Error::UnexpectedEnd,
11334            }
11335        });
11336    }
11337
11338    #[test]
11339    fn parse_cv_qualifiers() {
11340        assert_parse!(CvQualifiers {
11341            Ok => {
11342                b"" => {
11343                    CvQualifiers { restrict: false, volatile: false, const_: false },
11344                    b""
11345                }
11346                b"..." => {
11347                    CvQualifiers { restrict: false, volatile: false, const_: false },
11348                    b"..."
11349                }
11350                b"r..." => {
11351                    CvQualifiers { restrict: true, volatile: false, const_: false },
11352                    b"..."
11353                }
11354                b"rV..." => {
11355                    CvQualifiers { restrict: true, volatile: true, const_: false },
11356                    b"..."
11357                }
11358                b"rVK..." => {
11359                    CvQualifiers { restrict: true, volatile: true, const_: true },
11360                    b"..."
11361                }
11362                b"V" => {
11363                    CvQualifiers { restrict: false, volatile: true, const_: false },
11364                    b""
11365                }
11366                b"VK" => {
11367                    CvQualifiers { restrict: false, volatile: true, const_: true },
11368                    b""
11369                }
11370                b"K..." => {
11371                    CvQualifiers { restrict: false, volatile: false, const_: true },
11372                    b"..."
11373                }
11374            }
11375            Err => {
11376                // None.
11377            }
11378        });
11379    }
11380
11381    #[test]
11382    fn parse_builtin_type() {
11383        assert_parse!(BuiltinType {
11384            Ok => {
11385                b"c..." => {
11386                    BuiltinType::Standard(StandardBuiltinType::Char),
11387                    b"..."
11388                }
11389                b"c" => {
11390                    BuiltinType::Standard(StandardBuiltinType::Char),
11391                    b""
11392                }
11393                b"u3abc..." => {
11394                    BuiltinType::Extension(SourceName(Identifier {
11395                        start: 2,
11396                        end: 5,
11397                    })),
11398                    b"..."
11399                }
11400                b"DF16b..." => {
11401                    BuiltinType::Standard(StandardBuiltinType::BFloat16),
11402                    b"..."
11403                }
11404            }
11405            Err => {
11406                b"." => Error::UnexpectedText,
11407                b"" => Error::UnexpectedEnd,
11408            }
11409        });
11410    }
11411
11412    #[test]
11413    fn parse_parametric_builtin_type() {
11414        assert_parse!(BuiltinType {
11415            Ok => {
11416                b"DB8_..." => {
11417                    BuiltinType::Parametric(ParametricBuiltinType::SignedBitInt(8)),
11418                    b"..."
11419                }
11420                b"DUsZT_" => {
11421                    BuiltinType::Parametric(ParametricBuiltinType::UnsignedBitIntExpression(Box::new(Expression::SizeofTemplatePack(TemplateParam(0))))),
11422                    b""
11423                }
11424                b"DF128_..." => {
11425                    BuiltinType::Parametric(ParametricBuiltinType::FloatN(128)),
11426                    b"..."
11427                }
11428                b"DF256x..." => {
11429                    BuiltinType::Parametric(ParametricBuiltinType::FloatNx(256)),
11430                    b"..."
11431                }
11432            }
11433            Err => {
11434                b"DB100000000000000000000000_" => Error::Overflow,
11435                b"DFsZT_" => Error::UnexpectedText,
11436                b"DB" => Error::UnexpectedEnd,
11437                b"DB32" => Error::UnexpectedEnd,
11438            }
11439        });
11440    }
11441
11442    #[test]
11443    fn parse_template_param() {
11444        assert_parse!(TemplateParam {
11445            Ok => {
11446                b"T_..." => {
11447                    TemplateParam(0),
11448                    b"..."
11449                }
11450                b"T3_..." => {
11451                    TemplateParam(4),
11452                    b"..."
11453                }
11454            }
11455            Err => {
11456                b"wtf" => Error::UnexpectedText,
11457                b"Twtf" => Error::UnexpectedText,
11458                b"T3wtf" => Error::UnexpectedText,
11459                b"T" => Error::UnexpectedEnd,
11460                b"T3" => Error::UnexpectedEnd,
11461                b"" => Error::UnexpectedEnd,
11462            }
11463        });
11464    }
11465
11466    #[test]
11467    fn parse_unscoped_name() {
11468        assert_parse!(UnscopedName {
11469            Ok => {
11470                b"St5hello..." => {
11471                    UnscopedName::Std(UnqualifiedName::Source(SourceName(Identifier {
11472                        start: 3,
11473                        end: 8,
11474                    }),
11475                    AbiTags::default())),
11476                    b"..."
11477                }
11478                b"5hello..." => {
11479                    UnscopedName::Unqualified(UnqualifiedName::Source(SourceName(Identifier {
11480                        start: 1,
11481                        end: 6,
11482                    }), AbiTags::default())),
11483                    b"..."
11484                }
11485            }
11486            Err => {
11487                b"St..." => Error::UnexpectedText,
11488                b"..." => Error::UnexpectedText,
11489                b"" => Error::UnexpectedEnd,
11490            }
11491        });
11492    }
11493
11494    #[test]
11495    fn parse_unqualified_name() {
11496        // <unqualified-name> ::= <operator-name> [<abi-tags>]
11497        //                    ::= <ctor-dtor-name> [<abi-tags>]
11498        //                    ::= <source-name> [<abi-tags>]
11499        //                    ::= <local-source-name> [<abi-tags>]
11500        //                    ::= <unnamed-type-name> [<abi-tags>]
11501        //                    ::= <closure-type-name> [<abi-tags>]
11502        assert_parse!(UnqualifiedName {
11503            Ok => {
11504                b"qu.." => {
11505                    UnqualifiedName::Operator(OperatorName::Simple(SimpleOperatorName::Question), AbiTags::default()),
11506                    b".."
11507                }
11508                b"C1.." => {
11509                    UnqualifiedName::CtorDtor(CtorDtorName::CompleteConstructor(None), AbiTags::default()),
11510                    b".."
11511                }
11512                b"10abcdefghij..." => {
11513                    UnqualifiedName::Source(SourceName(Identifier {
11514                        start: 2,
11515                        end: 12,
11516                    }), AbiTags::default()),
11517                    b"..."
11518                }
11519                b"UllE_..." => {
11520                    UnqualifiedName::ClosureType(
11521                        ClosureTypeName(
11522                            LambdaSig(vec![
11523                                TypeHandle::Builtin(
11524                                    BuiltinType::Standard(
11525                                        StandardBuiltinType::Long))
11526                            ]),
11527                            None),
11528                        AbiTags::default()),
11529                    b"..."
11530                }
11531                b"Ut5_..." => {
11532                    UnqualifiedName::UnnamedType(UnnamedTypeName(Some(5)), AbiTags::default()),
11533                    b"..."
11534                }
11535                b"L3foo_0..." => {
11536                    UnqualifiedName::LocalSourceName(
11537                        SourceName(Identifier {
11538                            start: 2,
11539                            end: 5
11540                        }),
11541                        Some(Discriminator(0)),
11542                        AbiTags::default(),
11543                    ),
11544                    "..."
11545                }
11546                b"L3foo..." => {
11547                    UnqualifiedName::LocalSourceName(
11548                        SourceName(Identifier {
11549                            start: 2,
11550                            end: 5
11551                        }),
11552                        None,
11553                        AbiTags::default(),
11554                    ),
11555                    "..."
11556                }
11557                b"quB1Q.." => {
11558                    UnqualifiedName::Operator(
11559                        OperatorName::Simple(SimpleOperatorName::Question),
11560                        AbiTags(vec![AbiTag(
11561                            SourceName(
11562                                Identifier {
11563                                    start: 4,
11564                                    end: 5,
11565                                },
11566                            ),
11567                        )])
11568                    ),
11569                    b".."
11570                }
11571                b"C1B1Q.." => {
11572                    UnqualifiedName::CtorDtor(
11573                        CtorDtorName::CompleteConstructor(None),
11574                        AbiTags(vec![AbiTag(
11575                            SourceName(
11576                                Identifier {
11577                                    start: 4,
11578                                    end: 5,
11579                                },
11580                            ),
11581                        )])
11582                    ),
11583                    b".."
11584                }
11585                b"10abcdefghijB1QB2lp..." => {
11586                    UnqualifiedName::Source(
11587                        SourceName(Identifier {
11588                            start: 2,
11589                            end: 12,
11590                        }),
11591                        AbiTags(vec![
11592                            AbiTag(
11593                                SourceName(
11594                                    Identifier {
11595                                        start: 14,
11596                                        end: 15,
11597                                    },
11598                                ),
11599                            ),
11600                            AbiTag(
11601                                SourceName(
11602                                    Identifier {
11603                                        start: 17,
11604                                        end: 19,
11605                                    },
11606                                ),
11607                            ),
11608                        ])
11609                    ),
11610                    b"..."
11611                }
11612                b"UllE_B1Q..." => {
11613                    UnqualifiedName::ClosureType(
11614                        ClosureTypeName(
11615                            LambdaSig(vec![
11616                                TypeHandle::Builtin(
11617                                    BuiltinType::Standard(
11618                                        StandardBuiltinType::Long))
11619                            ]),
11620                            None),
11621                        AbiTags(vec![AbiTag(
11622                            SourceName(
11623                                Identifier {
11624                                    start: 7,
11625                                    end: 8,
11626                                },
11627                            ),
11628                        )])
11629                    ),
11630                    b"..."
11631                }
11632                b"Ut5_B1QB2lp..." => {
11633                    UnqualifiedName::UnnamedType(
11634                        UnnamedTypeName(Some(5)),
11635                        AbiTags(vec![
11636                            AbiTag(
11637                                SourceName(
11638                                    Identifier {
11639                                        start: 6,
11640                                        end: 7,
11641                                    },
11642                                ),
11643                            ),
11644                            AbiTag(
11645                                SourceName(
11646                                    Identifier {
11647                                        start: 9,
11648                                        end: 11,
11649                                    },
11650                                ),
11651                            ),
11652                        ])
11653                    ),
11654                    b"..."
11655                }
11656                b"L3foo_0B1Q..." => {
11657                    UnqualifiedName::LocalSourceName(
11658                        SourceName(Identifier {
11659                            start: 2,
11660                            end: 5
11661                        }),
11662                        Some(Discriminator(0)),
11663                        AbiTags(vec![AbiTag(
11664                            SourceName(
11665                                Identifier {
11666                                    start: 9,
11667                                    end: 10,
11668                                },
11669                            ),
11670                        )])
11671                    ),
11672                    "..."
11673                }
11674                b"L3fooB1QB2lp..." => {
11675                    UnqualifiedName::LocalSourceName(
11676                        SourceName(Identifier {
11677                            start: 2,
11678                            end: 5
11679                        }),
11680                        None,
11681                        AbiTags(vec![
11682                            AbiTag(
11683                                SourceName(
11684                                    Identifier {
11685                                        start: 7,
11686                                        end: 8,
11687                                    },
11688                                ),
11689                            ),
11690                            AbiTag(
11691                                SourceName(
11692                                    Identifier {
11693                                        start: 10,
11694                                        end: 12,
11695                                    },
11696                                ),
11697                            )
11698                        ])
11699                    ),
11700                    "..."
11701                }
11702            }
11703            Err => {
11704                b"zzz" => Error::UnexpectedText,
11705                b"Uq" => Error::UnexpectedText,
11706                b"C" => Error::UnexpectedEnd,
11707                b"" => Error::UnexpectedEnd,
11708            }
11709        });
11710    }
11711
11712    #[test]
11713    fn parse_unnamed_type_name() {
11714        assert_parse!(UnnamedTypeName {
11715            Ok => {
11716                b"Ut_abc" => {
11717                    UnnamedTypeName(None),
11718                    b"abc"
11719                }
11720                b"Ut42_abc" => {
11721                    UnnamedTypeName(Some(42)),
11722                    b"abc"
11723                }
11724                b"Ut42_" => {
11725                    UnnamedTypeName(Some(42)),
11726                    b""
11727                }
11728            }
11729            Err => {
11730                b"ut_" => Error::UnexpectedText,
11731                b"u" => Error::UnexpectedEnd,
11732                b"Ut" => Error::UnexpectedEnd,
11733                b"Ut._" => Error::UnexpectedText,
11734                b"Ut42" => Error::UnexpectedEnd,
11735            }
11736        });
11737    }
11738
11739    #[test]
11740    fn parse_identifier() {
11741        assert_parse!(Identifier {
11742            Ok => {
11743                b"1abc" => {
11744                    Identifier { start: 0, end: 4 },
11745                    b""
11746                }
11747                b"_Az1\0\0\0" => {
11748                    Identifier { start: 0, end: 4 },
11749                    b"\0\0\0"
11750                }
11751                b"$_0\0\0\0" => {
11752                    Identifier { start: 0, end: 3 },
11753                    b"\0\0\0"
11754                }
11755            }
11756            Err => {
11757                b"\0\0\0" => Error::UnexpectedText,
11758                b"" => Error::UnexpectedEnd,
11759            }
11760        });
11761    }
11762
11763    #[test]
11764    fn parse_source_name() {
11765        assert_parse!(SourceName {
11766            Ok => {
11767                b"1abc" => {
11768                    SourceName(Identifier { start: 1, end: 2 }),
11769                    b"bc"
11770                }
11771                b"10abcdefghijklm" => {
11772                    SourceName(Identifier { start: 2, end: 12 }),
11773                    b"klm"
11774                }
11775            }
11776            Err => {
11777                b"0abc" => Error::UnexpectedText,
11778                b"n1abc" => Error::UnexpectedText,
11779                b"10abcdef" => Error::UnexpectedEnd,
11780                b"" => Error::UnexpectedEnd,
11781            }
11782        });
11783    }
11784
11785    #[test]
11786    fn parse_number() {
11787        assert_parse!(Number {
11788            Ok => {
11789                b"n2n3" => {
11790                    -2,
11791                    b"n3"
11792                }
11793                b"12345abcdef" => {
11794                    12345,
11795                    b"abcdef"
11796                }
11797                b"0abcdef" => {
11798                    0,
11799                    b"abcdef"
11800                }
11801                b"42" => {
11802                    42,
11803                    b""
11804                }
11805            }
11806            Err => {
11807                b"001" => Error::UnexpectedText,
11808                b"wutang" => Error::UnexpectedText,
11809                b"n" => Error::UnexpectedEnd,
11810                b"" => Error::UnexpectedEnd,
11811            }
11812        });
11813    }
11814
11815    #[test]
11816    fn parse_call_offset() {
11817        assert_parse!(CallOffset {
11818            Ok => {
11819                b"hn42_..." => {
11820                    CallOffset::NonVirtual(NvOffset(-42)),
11821                    b"..."
11822                }
11823                b"vn42_36_..." => {
11824                    CallOffset::Virtual(VOffset(-42, 36)),
11825                    b"..."
11826                }
11827            }
11828            Err => {
11829                b"h1..." => Error::UnexpectedText,
11830                b"v1_1..." => Error::UnexpectedText,
11831                b"hh" => Error::UnexpectedText,
11832                b"vv" => Error::UnexpectedText,
11833                b"z" => Error::UnexpectedText,
11834                b"" => Error::UnexpectedEnd,
11835            }
11836        });
11837    }
11838
11839    #[test]
11840    fn parse_v_offset() {
11841        assert_parse!(VOffset {
11842            Ok => {
11843                b"n2_n3abcdef" => {
11844                    VOffset(-2, -3),
11845                    b"abcdef"
11846                }
11847                b"12345_12345abcdef" => {
11848                    VOffset(12345, 12345),
11849                    b"abcdef"
11850                }
11851                b"0_0abcdef" => {
11852                    VOffset(0, 0),
11853                    b"abcdef"
11854                }
11855                b"42_n3" => {
11856                    VOffset(42, -3),
11857                    b""
11858                }
11859            }
11860            Err => {
11861                b"001" => Error::UnexpectedText,
11862                b"1_001" => Error::UnexpectedText,
11863                b"wutang" => Error::UnexpectedText,
11864                b"n_" => Error::UnexpectedText,
11865                b"1_n" => Error::UnexpectedEnd,
11866                b"1_" => Error::UnexpectedEnd,
11867                b"n" => Error::UnexpectedEnd,
11868                b"" => Error::UnexpectedEnd,
11869            }
11870        });
11871    }
11872
11873    #[test]
11874    fn parse_nv_offset() {
11875        assert_parse!(NvOffset {
11876            Ok => {
11877                b"n2n3" => {
11878                    NvOffset(-2),
11879                    b"n3"
11880                }
11881                b"12345abcdef" => {
11882                    NvOffset(12345),
11883                    b"abcdef"
11884                }
11885                b"0abcdef" => {
11886                    NvOffset(0),
11887                    b"abcdef"
11888                }
11889                b"42" => {
11890                    NvOffset(42),
11891                    b""
11892                }
11893            }
11894            Err => {
11895                b"001" => Error::UnexpectedText,
11896                b"wutang" => Error::UnexpectedText,
11897                b"" => Error::UnexpectedEnd,
11898            }
11899        });
11900    }
11901
11902    #[test]
11903    fn parse_seq_id() {
11904        assert_parse!(SeqId {
11905            Ok => {
11906                b"1_" => {
11907                    SeqId(1),
11908                    b"_"
11909                }
11910                b"42" => {
11911                    SeqId(146),
11912                    b""
11913                }
11914                b"ABCabc" => {
11915                    SeqId(13368),
11916                    b"abc"
11917                }
11918            }
11919            Err => {
11920                b"abc" => Error::UnexpectedText,
11921                b"001" => Error::UnexpectedText,
11922                b"wutang" => Error::UnexpectedText,
11923                b"" => Error::UnexpectedEnd,
11924            }
11925        });
11926    }
11927
11928    #[test]
11929    fn parse_ctor_dtor_name() {
11930        assert_parse!(CtorDtorName {
11931            Ok => {
11932                b"D0" => {
11933                    CtorDtorName::DeletingDestructor,
11934                    b""
11935                }
11936                b"C101" => {
11937                    CtorDtorName::CompleteConstructor(None),
11938                    b"01"
11939                }
11940            }
11941            Err => {
11942                b"gayagaya" => Error::UnexpectedText,
11943                b"C" => Error::UnexpectedEnd,
11944                b"" => Error::UnexpectedEnd,
11945            }
11946        });
11947    }
11948
11949    #[test]
11950    fn parse_operator_name() {
11951        assert_parse!(OperatorName {
11952            Ok => {
11953                b"qu..." => {
11954                    OperatorName::Simple(SimpleOperatorName::Question),
11955                    b"..."
11956                }
11957                b"cvi..." => {
11958                    OperatorName::Conversion(
11959                        TypeHandle::Builtin(
11960                            BuiltinType::Standard(
11961                                StandardBuiltinType::Int))),
11962                    b"..."
11963                }
11964                b"li3Foo..." => {
11965                    OperatorName::Literal(SourceName(Identifier {
11966                        start: 3,
11967                        end: 6,
11968                    })),
11969                    b"..."
11970                }
11971                b"v33Foo..." => {
11972                    OperatorName::VendorExtension(3, SourceName(Identifier {
11973                        start: 3,
11974                        end: 6
11975                    })),
11976                    b"..."
11977                }
11978            }
11979            Err => {
11980                b"cv" => Error::UnexpectedEnd,
11981                b"li3ab" => Error::UnexpectedEnd,
11982                b"li" => Error::UnexpectedEnd,
11983                b"v33ab" => Error::UnexpectedEnd,
11984                b"v3" => Error::UnexpectedEnd,
11985                b"v" => Error::UnexpectedEnd,
11986                b"" => Error::UnexpectedEnd,
11987                b"q" => Error::UnexpectedText,
11988                b"c" => Error::UnexpectedText,
11989                b"l" => Error::UnexpectedText,
11990                b"zzz" => Error::UnexpectedText,
11991            }
11992        });
11993    }
11994
11995    #[test]
11996    fn parse_simple_operator_name() {
11997        assert_parse!(SimpleOperatorName {
11998            Ok => {
11999                b"qu" => {
12000                    SimpleOperatorName::Question,
12001                    b""
12002                }
12003                b"quokka" => {
12004                    SimpleOperatorName::Question,
12005                    b"okka"
12006                }
12007            }
12008            Err => {
12009                b"bu-buuuu" => Error::UnexpectedText,
12010                b"q" => Error::UnexpectedEnd,
12011                b"" => Error::UnexpectedEnd,
12012            }
12013        });
12014    }
12015
12016    #[test]
12017    fn parse_subobject_expr() {
12018        assert_parse!(SubobjectExpr {
12019            with subs [] => {
12020                Ok => {
12021                    "PKcL_Z3FooEE..." => {
12022                        SubobjectExpr {
12023                            ty: TypeHandle::BackReference(1),
12024                            expr: Box::new(Expression::Primary(
12025                                ExprPrimary::External(
12026                                    MangledName::Encoding(
12027                                        Encoding::Data(
12028                                            Name::Unscoped(
12029                                                UnscopedName::Unqualified(
12030                                                    UnqualifiedName::Source(
12031                                                        SourceName(
12032                                                            Identifier {
12033                                                                start: 7,
12034                                                                end: 10,
12035                                                            }
12036                                                        ),
12037                                                        AbiTags::default()
12038                                                    )
12039                                                )
12040                                            )
12041                                        ),
12042                                        vec![]
12043                                    )
12044                                )
12045                            )),
12046                            offset: 0,
12047                        },
12048                        b"...",
12049                        [
12050                            Substitutable::Type(
12051                                Type::Qualified(
12052                                    CvQualifiers {
12053                                        restrict: false,
12054                                        volatile: false,
12055                                        const_: true,
12056                                    },
12057                                    TypeHandle::Builtin(
12058                                        BuiltinType::Standard(
12059                                            StandardBuiltinType::Char,
12060                                        ),
12061                                    ),
12062                                )
12063                            ),
12064                            Substitutable::Type(
12065                                Type::PointerTo(
12066                                    TypeHandle::BackReference(
12067                                        0,
12068                                    ),
12069                                ),
12070                            )
12071                        ]
12072                    }
12073                }
12074                Err => {
12075                    "" => Error::UnexpectedEnd,
12076                    "" => Error::UnexpectedEnd,
12077                }
12078            }
12079        });
12080    }
12081}