1 //! Abstract syntax tree types for mangled symbols.
2 
3 use super::{DemangleNodeType, DemangleOptions, DemangleWrite, ParseOptions};
4 use boxed::Box;
5 use error::{self, Result};
6 use index_str::IndexStr;
7 use std::cell::Cell;
8 #[cfg(feature = "logging")]
9 use std::cell::RefCell;
10 use std::fmt::{self, Write};
11 use std::hash::{Hash, Hasher};
12 use std::mem;
13 use std::ops;
14 use std::ptr;
15 use string::String;
16 use subs::{Substitutable, SubstitutionTable};
17 use vec::Vec;
18 
19 struct AutoLogParse;
20 
21 #[cfg(feature = "logging")]
22 thread_local! {
23     static LOG_DEPTH: RefCell<usize> = RefCell::new(0);
24 }
25 
26 impl AutoLogParse {
27     #[cfg(feature = "logging")]
new(production: &'static str, input: IndexStr<'_>) -> AutoLogParse28     fn new(production: &'static str, input: IndexStr<'_>) -> AutoLogParse {
29         LOG_DEPTH.with(|depth| {
30             if *depth.borrow() == 0 {
31                 println!();
32             }
33 
34             let indent: String = (0..*depth.borrow() * 4).map(|_| ' ').collect();
35             log!(
36                 "{}({} \"{}\" {}",
37                 indent,
38                 production,
39                 String::from_utf8_lossy(input.as_ref()),
40                 input.len(),
41             );
42             *depth.borrow_mut() += 1;
43         });
44         AutoLogParse
45     }
46 
47     #[cfg(not(feature = "logging"))]
48     #[inline(always)]
new(_: &'static str, _: IndexStr) -> AutoLogParse49     fn new(_: &'static str, _: IndexStr) -> AutoLogParse {
50         AutoLogParse
51     }
52 }
53 
54 #[cfg(feature = "logging")]
55 impl Drop for AutoLogParse {
drop(&mut self)56     fn drop(&mut self) {
57         LOG_DEPTH.with(|depth| {
58             *depth.borrow_mut() -= 1;
59             let indent: String = (0..*depth.borrow() * 4).map(|_| ' ').collect();
60             log!("{})", indent);
61         });
62     }
63 }
64 
65 /// Performs the two operations that begin every parse:
66 ///
67 /// 1. Keeps track of recursion levels and early returns with an error if there
68 ///    is too much recursion.
69 ///
70 /// 2. Automatically log start and end parsing in an s-expression format, when the
71 ///    `logging` feature is enabled.
72 macro_rules! try_begin_parse {
73     ( $production:expr , $ctx:expr , $input:expr ) => {
74         let _log = AutoLogParse::new($production, $input);
75         let _auto_check_recursion = AutoParseRecursion::new($ctx)?;
76     };
77 }
78 
79 struct AutoLogDemangle;
80 
81 impl AutoLogDemangle {
82     #[cfg(feature = "logging")]
new<P, W>( production: &P, ctx: &DemangleContext<W>, scope: Option<ArgScopeStack>, is_inner: bool, ) -> AutoLogDemangle where P: ?Sized + fmt::Debug, W: DemangleWrite,83     fn new<P, W>(
84         production: &P,
85         ctx: &DemangleContext<W>,
86         scope: Option<ArgScopeStack>,
87         is_inner: bool,
88     ) -> AutoLogDemangle
89     where
90         P: ?Sized + fmt::Debug,
91         W: DemangleWrite,
92     {
93         LOG_DEPTH.with(|depth| {
94             if *depth.borrow() == 0 {
95                 println!();
96             }
97 
98             let indent: String = (0..*depth.borrow() * 4).map(|_| ' ').collect();
99             log!("{}(", indent);
100             log!(
101                 "{}  {}{:?}",
102                 indent,
103                 if is_inner { "as_inner: " } else { "" },
104                 production
105             );
106             log!("{}  inner = {:?}", indent, ctx.inner);
107             log!("{}  scope = {:?}", indent, scope);
108 
109             *depth.borrow_mut() += 1;
110         });
111         AutoLogDemangle
112     }
113 
114     #[cfg(not(feature = "logging"))]
115     #[inline(always)]
new<P, W>( _: &P, _: &DemangleContext<W>, _: Option<ArgScopeStack>, _: bool, ) -> AutoLogDemangle where P: ?Sized + fmt::Debug, W: DemangleWrite,116     fn new<P, W>(
117         _: &P,
118         _: &DemangleContext<W>,
119         _: Option<ArgScopeStack>,
120         _: bool,
121     ) -> AutoLogDemangle
122     where
123         P: ?Sized + fmt::Debug,
124         W: DemangleWrite,
125     {
126         AutoLogDemangle
127     }
128 }
129 
130 #[cfg(feature = "logging")]
131 impl Drop for AutoLogDemangle {
drop(&mut self)132     fn drop(&mut self) {
133         LOG_DEPTH.with(|depth| {
134             *depth.borrow_mut() -= 1;
135             let indent: String = (0..*depth.borrow() * 4).map(|_| ' ').collect();
136             log!("{})", indent);
137         });
138     }
139 }
140 
141 /// Automatically log start and end demangling in an s-expression format, when
142 /// the `logging` feature is enabled.
143 macro_rules! try_begin_demangle {
144     ( $production:expr, $ctx:expr, $scope:expr ) => {{
145         let _log = AutoLogDemangle::new($production, $ctx, $scope, false);
146         &mut AutoParseDemangle::new($ctx)?
147     }};
148 }
149 
150 /// Automatically log start and end demangling in an s-expression format, when
151 /// the `logging` feature is enabled.
152 macro_rules! try_begin_demangle_as_inner {
153     ( $production:expr, $ctx:expr, $scope:expr ) => {{
154         let _log = AutoLogDemangle::new($production, $ctx, $scope, true);
155         &mut AutoParseDemangle::new($ctx)?
156     }};
157 }
158 
159 #[derive(Debug, Default, Clone, Copy)]
160 struct ParseContextState {
161     // The current recursion level. Should always be less than or equal to the
162     // maximum.
163     recursion_level: u32,
164     // Whether or not we are currently parsing a conversion operator.
165     in_conversion: bool,
166 }
167 
168 /// Common context needed when parsing.
169 #[derive(Debug, Clone)]
170 pub struct ParseContext {
171     // Maximum amount of recursive parsing calls we will allow. If this is too
172     // large, we can blow the stack.
173     max_recursion: u32,
174     // Mutable state within the `ParseContext`.
175     state: Cell<ParseContextState>,
176 }
177 
178 impl ParseContext {
179     /// Construct a new `ParseContext`.
new(options: ParseOptions) -> ParseContext180     pub fn new(options: ParseOptions) -> ParseContext {
181         ParseContext {
182             max_recursion: options.recursion_limit.map(|v| v.get()).unwrap_or(96),
183             state: Cell::new(ParseContextState::default()),
184         }
185     }
186 
187     /// Get the current recursion level for this context.
recursion_level(&self) -> u32188     pub fn recursion_level(&self) -> u32 {
189         self.state.get().recursion_level
190     }
191 
192     #[inline]
enter_recursion(&self) -> error::Result<()>193     fn enter_recursion(&self) -> error::Result<()> {
194         let mut state = self.state.get();
195         let new_recursion_level = state.recursion_level + 1;
196 
197         if new_recursion_level >= self.max_recursion {
198             log!("Hit too much recursion at level {}", self.max_recursion);
199             Err(error::Error::TooMuchRecursion)
200         } else {
201             state.recursion_level = new_recursion_level;
202             self.state.set(state);
203             Ok(())
204         }
205     }
206 
207     #[inline]
exit_recursion(&self)208     fn exit_recursion(&self) {
209         let mut state = self.state.get();
210         debug_assert!(state.recursion_level >= 1);
211         state.recursion_level -= 1;
212         self.state.set(state);
213     }
214 
215     #[inline]
in_conversion(&self) -> bool216     fn in_conversion(&self) -> bool {
217         self.state.get().in_conversion
218     }
219 
set_in_conversion(&self, in_conversion: bool) -> bool220     fn set_in_conversion(&self, in_conversion: bool) -> bool {
221         let mut state = self.state.get();
222         let previously_in_conversion = state.in_conversion;
223         state.in_conversion = in_conversion;
224         self.state.set(state);
225         previously_in_conversion
226     }
227 }
228 
229 /// An RAII type to automatically check the recursion level against the
230 /// maximum. If the maximum has been crossed, return an error. Otherwise,
231 /// increment the level upon construction, and decrement it upon destruction.
232 struct AutoParseRecursion<'a>(&'a ParseContext);
233 
234 impl<'a> AutoParseRecursion<'a> {
235     #[inline]
new(ctx: &'a ParseContext) -> error::Result<AutoParseRecursion<'a>>236     fn new(ctx: &'a ParseContext) -> error::Result<AutoParseRecursion<'a>> {
237         ctx.enter_recursion()?;
238         Ok(AutoParseRecursion(ctx))
239     }
240 }
241 
242 impl<'a> Drop for AutoParseRecursion<'a> {
243     #[inline]
drop(&mut self)244     fn drop(&mut self) {
245         self.0.exit_recursion();
246     }
247 }
248 
249 /// A trait for anything that can be parsed from an `IndexStr` and return a
250 /// `Result` of the parsed `Self` value and the rest of the `IndexStr` input
251 /// that has not been consumed in parsing the `Self` value.
252 ///
253 /// For AST types representing productions which have `<substitution>` as a
254 /// possible right hand side, do not implement this trait directly. Instead,
255 /// make a newtype over `usize`, parse either the `<substitution>` back
256 /// reference or "real" value, insert the "real" value into the substitution
257 /// table if needed, and *always* return the newtype index into the substitution
258 /// table.
259 #[doc(hidden)]
260 pub trait Parse: Sized {
261     /// Parse the `Self` value from `input` and return it, updating the
262     /// substitution table as needed.
parse<'a, 'b>( ctx: &'a ParseContext, subs: &'a mut SubstitutionTable, input: IndexStr<'b>, ) -> Result<(Self, IndexStr<'b>)>263     fn parse<'a, 'b>(
264         ctx: &'a ParseContext,
265         subs: &'a mut SubstitutionTable,
266         input: IndexStr<'b>,
267     ) -> Result<(Self, IndexStr<'b>)>;
268 }
269 
270 /// Determine whether this AST node is an instantiated[*] template function, and
271 /// get its concrete template arguments.
272 ///
273 /// [*] Note that we will never see an abstract, un-instantiated template
274 /// function, since they don't end up in object files and don't get mangled
275 /// names.
276 trait GetTemplateArgs {
277     /// Returns `Some` if this is a template function, `None` otherwise.
get_template_args<'a>(&'a self, subs: &'a SubstitutionTable) -> Option<&'a TemplateArgs>278     fn get_template_args<'a>(&'a self, subs: &'a SubstitutionTable) -> Option<&'a TemplateArgs>;
279 }
280 
281 /// A leaf name is the part the name that describes some type or class without
282 /// any leading namespace qualifiers.
283 ///
284 /// This is used when figuring out how to format constructors and destructors,
285 /// which are formatted as `gooble::dodo::Thing::~Thing()` but we don't have
286 /// direct access to `Thing` in the `CtorDtorName` AST.
287 #[derive(Debug)]
288 pub(crate) enum LeafName<'a> {
289     SourceName(&'a SourceName),
290     WellKnownComponent(&'a WellKnownComponent),
291     Closure(&'a ClosureTypeName),
292     UnnamedType(&'a UnnamedTypeName),
293 }
294 
295 impl<'subs, W> DemangleAsLeaf<'subs, W> for LeafName<'subs>
296 where
297     W: 'subs + DemangleWrite,
298 {
demangle_as_leaf<'me, 'ctx>( &'me self, ctx: &'ctx mut DemangleContext<'subs, W>, ) -> fmt::Result299     fn demangle_as_leaf<'me, 'ctx>(
300         &'me self,
301         ctx: &'ctx mut DemangleContext<'subs, W>,
302     ) -> fmt::Result {
303         match *self {
304             LeafName::SourceName(sn) => sn.demangle(ctx, None),
305             LeafName::Closure(c) => c.demangle(ctx, None),
306             LeafName::WellKnownComponent(wkc) => wkc.demangle_as_leaf(ctx),
307             LeafName::UnnamedType(utn) => utn.demangle_as_leaf(ctx),
308         }
309     }
310 }
311 
312 /// Determine whether this AST node is some kind (potentially namespaced) name
313 /// and if so get its leaf name.
314 pub(crate) trait GetLeafName<'a> {
get_leaf_name(&'a self, subs: &'a SubstitutionTable) -> Option<LeafName<'a>>315     fn get_leaf_name(&'a self, subs: &'a SubstitutionTable) -> Option<LeafName<'a>>;
316 }
317 
318 /// Determine whether this AST node is a constructor, destructor, or conversion
319 /// function.
320 pub(crate) trait IsCtorDtorConversion {
is_ctor_dtor_conversion(&self, subs: &SubstitutionTable) -> bool321     fn is_ctor_dtor_conversion(&self, subs: &SubstitutionTable) -> bool;
322 }
323 
324 /// When formatting a mangled symbol's parsed AST as a demangled symbol, we need
325 /// to resolve indirect references to template and function arguments with
326 /// direct `TemplateArg` and `Type` references respectively.
327 ///
328 /// Note that which set of arguments are implicitly referenced change as we
329 /// enter and leave different functions' scope. One might usually use de Brujin
330 /// indices to keep arguments within scopes separated from each other, but the
331 /// Itanium C++ ABI does not allow us the luxury. AFAIK, when the ABI was first
332 /// drafted, C++ did not have lambdas, and the issue did not come up at all
333 /// since a function simply couldn't refer to the types of closed over
334 /// variables.
335 ///
336 /// This trait is implemented by anything that can potentially resolve arguments
337 /// for us.
338 trait ArgScope<'me, 'ctx>: fmt::Debug {
339     /// Get the current scope's leaf name.
leaf_name(&'me self) -> Result<LeafName<'ctx>>340     fn leaf_name(&'me self) -> Result<LeafName<'ctx>>;
341 
342     /// Get the current scope's `index`th template argument.
get_template_arg(&'me self, index: usize) -> Result<(&'ctx TemplateArg, &'ctx TemplateArgs)>343     fn get_template_arg(&'me self, index: usize)
344         -> Result<(&'ctx TemplateArg, &'ctx TemplateArgs)>;
345 
346     /// Get the current scope's `index`th function argument's type.
get_function_arg(&'me self, index: usize) -> Result<&'ctx Type>347     fn get_function_arg(&'me self, index: usize) -> Result<&'ctx Type>;
348 }
349 
350 /// An `ArgScopeStack` represents the current function and template demangling
351 /// scope we are within. As we enter new demangling scopes, we construct new
352 /// `ArgScopeStack`s whose `prev` references point back to the old ones. These
353 /// `ArgScopeStack`s are kept on the native stack, and as functions return, they
354 /// go out of scope and we use the previous `ArgScopeStack`s again.
355 #[derive(Copy, Clone, Debug)]
356 pub struct ArgScopeStack<'prev, 'subs>
357 where
358     'subs: 'prev,
359 {
360     item: &'subs dyn ArgScope<'subs, 'subs>,
361     in_arg: Option<(usize, &'subs TemplateArgs)>,
362     prev: Option<&'prev ArgScopeStack<'prev, 'subs>>,
363 }
364 
365 /// When we first begin demangling, we haven't entered any function or template
366 /// demangling scope and we don't have any useful `ArgScopeStack`. Therefore, we
367 /// are never actually dealing with `ArgScopeStack` directly in practice, but
368 /// always an `Option<ArgScopeStack>` instead. Nevertheless, we want to define
369 /// useful methods on `Option<ArgScopeStack>`.
370 ///
371 /// A custom "extension" trait with exactly one implementor: Rust's principled
372 /// monkey patching!
373 trait ArgScopeStackExt<'prev, 'subs>: Copy {
374     /// Push a new `ArgScope` onto this `ArgScopeStack` and return the new
375     /// `ArgScopeStack` with the pushed resolver on top.
push( &'prev self, item: &'subs dyn ArgScope<'subs, 'subs>, ) -> Option<ArgScopeStack<'prev, 'subs>>376     fn push(
377         &'prev self,
378         item: &'subs dyn ArgScope<'subs, 'subs>,
379     ) -> Option<ArgScopeStack<'prev, 'subs>>;
380 }
381 
382 impl<'prev, 'subs> ArgScopeStackExt<'prev, 'subs> for Option<ArgScopeStack<'prev, 'subs>> {
push( &'prev self, item: &'subs dyn ArgScope<'subs, 'subs>, ) -> Option<ArgScopeStack<'prev, 'subs>>383     fn push(
384         &'prev self,
385         item: &'subs dyn ArgScope<'subs, 'subs>,
386     ) -> Option<ArgScopeStack<'prev, 'subs>> {
387         log!("ArgScopeStack::push: {:?}", item);
388         Some(ArgScopeStack {
389             prev: self.as_ref(),
390             in_arg: None,
391             item: item,
392         })
393     }
394 }
395 
396 /// A stack of `ArgScope`s is itself an `ArgScope`!
397 impl<'prev, 'subs> ArgScope<'prev, 'subs> for Option<ArgScopeStack<'prev, 'subs>> {
leaf_name(&'prev self) -> Result<LeafName<'subs>>398     fn leaf_name(&'prev self) -> Result<LeafName<'subs>> {
399         let mut scope = self.as_ref();
400         while let Some(s) = scope {
401             if let Ok(c) = s.item.leaf_name() {
402                 return Ok(c);
403             }
404             scope = s.prev;
405         }
406         Err(error::Error::BadLeafNameReference)
407     }
408 
get_template_arg( &'prev self, idx: usize, ) -> Result<(&'subs TemplateArg, &'subs TemplateArgs)>409     fn get_template_arg(
410         &'prev self,
411         idx: usize,
412     ) -> Result<(&'subs TemplateArg, &'subs TemplateArgs)> {
413         let mut scope = self.as_ref();
414         while let Some(s) = scope {
415             if let Ok((arg, args)) = s.item.get_template_arg(idx) {
416                 if let Some((in_idx, in_args)) = s.in_arg {
417                     if args as *const TemplateArgs == in_args as *const TemplateArgs
418                         && in_idx <= idx
419                     {
420                         return Err(error::Error::ForwardTemplateArgReference);
421                     }
422                 }
423                 return Ok((arg, args));
424             }
425             scope = s.prev;
426         }
427 
428         Err(error::Error::BadTemplateArgReference)
429     }
430 
get_function_arg(&'prev self, idx: usize) -> Result<&'subs Type>431     fn get_function_arg(&'prev self, idx: usize) -> Result<&'subs Type> {
432         let mut scope = self.as_ref();
433         while let Some(s) = scope {
434             if let Ok(arg) = s.item.get_function_arg(idx) {
435                 return Ok(arg);
436             }
437             scope = s.prev;
438         }
439 
440         Err(error::Error::BadFunctionArgReference)
441     }
442 }
443 
444 #[derive(Debug, Copy, Clone)]
445 struct DemangleState {
446     /// How deep in the demangling are we?
447     pub recursion_level: u32,
448 }
449 
450 /// An RAII type to automatically check the recursion level against the
451 /// maximum. If the maximum has been crossed, return an error. Otherwise,
452 /// increment the level upon construction, and decrement it upon destruction.
453 struct AutoParseDemangle<'a, 'b, W: 'a + DemangleWrite>(&'b mut DemangleContext<'a, W>);
454 
455 impl<'a, 'b, W: 'a + DemangleWrite> AutoParseDemangle<'a, 'b, W> {
456     #[inline]
new(ctx: &'b mut DemangleContext<'a, W>) -> std::result::Result<Self, fmt::Error>457     fn new(ctx: &'b mut DemangleContext<'a, W>) -> std::result::Result<Self, fmt::Error> {
458         ctx.enter_recursion()?;
459         Ok(AutoParseDemangle(ctx))
460     }
461 }
462 
463 impl<'a, 'b, W: 'a + DemangleWrite> std::ops::Deref for AutoParseDemangle<'a, 'b, W> {
464     type Target = DemangleContext<'a, W>;
465 
deref(&self) -> &Self::Target466     fn deref(&self) -> &Self::Target {
467         self.0
468     }
469 }
470 
471 impl<'a, 'b, W: 'a + DemangleWrite> std::ops::DerefMut for AutoParseDemangle<'a, 'b, W> {
deref_mut(&mut self) -> &mut Self::Target472     fn deref_mut(&mut self) -> &mut Self::Target {
473         self.0
474     }
475 }
476 
477 impl<'a, 'b, W: 'a + DemangleWrite> Drop for AutoParseDemangle<'a, 'b, W> {
478     #[inline]
drop(&mut self)479     fn drop(&mut self) {
480         self.0.exit_recursion();
481     }
482 }
483 
484 /// Common state that is required when demangling a mangled symbol's parsed AST.
485 #[doc(hidden)]
486 #[derive(Debug)]
487 pub struct DemangleContext<'a, W>
488 where
489     W: 'a + DemangleWrite,
490 {
491     // The substitution table built up when parsing the mangled symbol into an
492     // AST.
493     subs: &'a SubstitutionTable,
494 
495     // The maximum recursion
496     max_recursion: u32,
497 
498     // Sometimes an AST node needs to insert itself as an inner item within one
499     // of its children when demangling that child. For example, the AST
500     //
501     //     (array 10 int)
502     //
503     // is demangled as `int[10]`, but if we were to demangle the AST
504     //
505     //     (lvalue-ref (array 10 int))
506     //
507     // then we would want this demangled form: `int (&) [10]`, which requires
508     // the parent lvalue-ref to be passed into the child array's demangling
509     // method. This kind of thing also pops up with function pointers.
510     //
511     // The `inner` stack enables such behavior by allowing us to pass AST
512     // parents down to their children as inner items.
513     inner: Vec<&'a dyn DemangleAsInner<'a, W>>,
514 
515     // The original input string.
516     input: &'a [u8],
517 
518     // `Identifier`s will be placed here, so `UnnamedTypeName` can utilize and print
519     // out the Constructor/Destructor used.
520     source_name: Option<&'a str>,
521 
522     // What the demangled name is being written to.
523     out: &'a mut W,
524 
525     // The total number of bytes written to `out`. This is maintained by the
526     // `Write` implementation for `DemangleContext`.
527     bytes_written: usize,
528 
529     // The last char written to `out`, if any.
530     last_char_written: Option<char>,
531 
532     // We are currently demangling a lambda argument, so template substitution
533     // should be suppressed to match libiberty.
534     is_lambda_arg: bool,
535 
536     // We are currently demangling a template-prefix.
537     is_template_prefix: bool,
538 
539     // We are currently demangling a template-prefix in a nested-name.
540     is_template_prefix_in_nested_name: bool,
541 
542     //  `PackExpansion`'s should only print '...', only when there is no template
543     //  argument pack.
544     is_template_argument_pack: bool,
545 
546     // Whether to show function parameters.
547     // This must be set to true before calling `demangle` on `Encoding`
548     // unless that call is via the toplevel call to `MangledName::demangle`.
549     show_params: bool,
550 
551     // Whether to show function return types.
552     // This must be set to true before calling `demangle` on `Encoding`
553     // unless that call is via the toplevel call to `MangledName::demangle`.
554     show_return_type: bool,
555 
556     // recursion protection.
557     state: Cell<DemangleState>,
558 }
559 
560 impl<'a, W> fmt::Write for DemangleContext<'a, W>
561 where
562     W: 'a + DemangleWrite,
563 {
write_str(&mut self, s: &str) -> fmt::Result564     fn write_str(&mut self, s: &str) -> fmt::Result {
565         if s.is_empty() {
566             return Ok(());
567         }
568 
569         log!("DemangleContext::write: '{}'", s);
570 
571         self.out.write_string(s).map(|_| {
572             self.last_char_written = s.chars().last();
573             self.bytes_written += s.len();
574         })
575     }
576 }
577 
578 impl<'a, W> DemangleContext<'a, W>
579 where
580     W: 'a + DemangleWrite,
581 {
582     /// Construct a new `DemangleContext`.
new( subs: &'a SubstitutionTable, input: &'a [u8], options: DemangleOptions, out: &'a mut W, ) -> DemangleContext<'a, W>583     pub fn new(
584         subs: &'a SubstitutionTable,
585         input: &'a [u8],
586         options: DemangleOptions,
587         out: &'a mut W,
588     ) -> DemangleContext<'a, W> {
589         DemangleContext {
590             subs: subs,
591             max_recursion: options.recursion_limit.map(|v| v.get()).unwrap_or(128),
592             inner: vec![],
593             input: input,
594             source_name: None,
595             out: out,
596             bytes_written: 0,
597             last_char_written: None,
598             is_lambda_arg: false,
599             is_template_prefix: false,
600             is_template_prefix_in_nested_name: false,
601             is_template_argument_pack: false,
602             show_params: !options.no_params,
603             show_return_type: !options.no_return_type,
604             state: Cell::new(DemangleState { recursion_level: 0 }),
605         }
606     }
607 
608     /// Get the current recursion level for this context.
recursion_level(&self) -> u32609     pub fn recursion_level(&self) -> u32 {
610         self.state.get().recursion_level
611     }
612 
613     #[inline]
enter_recursion(&self) -> fmt::Result614     fn enter_recursion(&self) -> fmt::Result {
615         let mut state = self.state.get();
616         let new_recursion_level = state.recursion_level + 1;
617 
618         if new_recursion_level >= self.max_recursion {
619             log!("Hit too much recursion at level {}", self.max_recursion);
620             Err(Default::default())
621         } else {
622             state.recursion_level = new_recursion_level;
623             self.state.set(state);
624             Ok(())
625         }
626     }
627 
628     #[inline]
exit_recursion(&self)629     fn exit_recursion(&self) {
630         let mut state = self.state.get();
631         debug_assert!(state.recursion_level >= 1);
632         state.recursion_level -= 1;
633         self.state.set(state);
634     }
635 
636     #[inline]
ensure(&mut self, ch: char) -> fmt::Result637     fn ensure(&mut self, ch: char) -> fmt::Result {
638         if self.last_char_written == Some(ch) {
639             Ok(())
640         } else {
641             write!(self, "{}", ch)?;
642             Ok(())
643         }
644     }
645 
646     #[inline]
ensure_space(&mut self) -> fmt::Result647     fn ensure_space(&mut self) -> fmt::Result {
648         self.ensure(' ')
649     }
650 
651     #[inline]
push_inner(&mut self, item: &'a dyn DemangleAsInner<'a, W>)652     fn push_inner(&mut self, item: &'a dyn DemangleAsInner<'a, W>) {
653         log!("DemangleContext::push_inner: {:?}", item);
654         self.inner.push(item);
655     }
656 
657     #[inline]
pop_inner(&mut self) -> Option<&'a dyn DemangleAsInner<'a, W>>658     fn pop_inner(&mut self) -> Option<&'a dyn DemangleAsInner<'a, W>> {
659         let popped = self.inner.pop();
660         log!("DemangleContext::pop_inner: {:?}", popped);
661         popped
662     }
663 
664     #[inline]
pop_inner_if(&mut self, inner: &'a dyn DemangleAsInner<'a, W>) -> bool665     fn pop_inner_if(&mut self, inner: &'a dyn DemangleAsInner<'a, W>) -> bool {
666         let last = match self.inner.last() {
667             None => return false,
668             Some(last) => *last,
669         };
670 
671         if ptr::eq(last, inner) {
672             self.inner.pop();
673             true
674         } else {
675             false
676         }
677     }
678 
demangle_inner_prefixes<'prev>( &mut self, scope: Option<ArgScopeStack<'prev, 'a>>, ) -> fmt::Result679     fn demangle_inner_prefixes<'prev>(
680         &mut self,
681         scope: Option<ArgScopeStack<'prev, 'a>>,
682     ) -> fmt::Result {
683         log!("DemangleContext::demangle_inner_prefixes");
684         let mut new_inner = vec![];
685         while let Some(inner) = self.pop_inner() {
686             if inner
687                 .downcast_to_function_type()
688                 .map_or(false, |f| !f.cv_qualifiers.is_empty())
689             {
690                 log!(
691                     "DemangleContext::demangle_inner_prefixes: not a prefix, saving: {:?}",
692                     inner
693                 );
694                 new_inner.push(inner);
695             } else {
696                 log!(
697                     "DemangleContext::demangle_inner_prefixes: demangling prefix: {:?}",
698                     inner
699                 );
700                 inner.demangle_as_inner(self, scope)?;
701             }
702         }
703         new_inner.reverse();
704         self.inner = new_inner;
705         Ok(())
706     }
707 
demangle_inners<'prev>(&mut self, scope: Option<ArgScopeStack<'prev, 'a>>) -> fmt::Result708     fn demangle_inners<'prev>(&mut self, scope: Option<ArgScopeStack<'prev, 'a>>) -> fmt::Result {
709         while let Some(inner) = self.pop_inner() {
710             inner.demangle_as_inner(self, scope)?;
711         }
712         Ok(())
713     }
714 
set_source_name(&mut self, start: usize, end: usize)715     fn set_source_name(&mut self, start: usize, end: usize) {
716         let ident = &self.input[start..end];
717         self.source_name = std::str::from_utf8(ident).ok();
718     }
719 
push_demangle_node(&mut self, t: DemangleNodeType)720     fn push_demangle_node(&mut self, t: DemangleNodeType) {
721         self.out.push_demangle_node(t);
722     }
723 
724     /// This should not be called on error paths.
725     /// pop_inner_if already doesn't balance if there are errors.
pop_demangle_node(&mut self)726     fn pop_demangle_node(&mut self) {
727         self.out.pop_demangle_node();
728     }
729 }
730 
731 #[doc(hidden)]
732 #[derive(Debug)]
733 pub struct AutoDemangleContextInnerBarrier<'ctx, 'a, W>
734 where
735     W: 'a + DemangleWrite,
736     'a: 'ctx,
737 {
738     ctx: &'ctx mut DemangleContext<'a, W>,
739     saved_inner: Vec<&'a dyn DemangleAsInner<'a, W>>,
740 }
741 
742 impl<'ctx, 'a, W> AutoDemangleContextInnerBarrier<'ctx, 'a, W>
743 where
744     W: 'a + DemangleWrite,
745     'a: 'ctx,
746 {
747     /// Set aside the current inner stack on the demangle context.
new(ctx: &'ctx mut DemangleContext<'a, W>) -> Self748     pub fn new(ctx: &'ctx mut DemangleContext<'a, W>) -> Self {
749         let mut saved_inner = vec![];
750         mem::swap(&mut saved_inner, &mut ctx.inner);
751         AutoDemangleContextInnerBarrier {
752             ctx: ctx,
753             saved_inner: saved_inner,
754         }
755     }
756 }
757 
758 impl<'ctx, 'a, W> ops::Deref for AutoDemangleContextInnerBarrier<'ctx, 'a, W>
759 where
760     W: 'a + DemangleWrite,
761     'a: 'ctx,
762 {
763     type Target = DemangleContext<'a, W>;
764 
deref(&self) -> &Self::Target765     fn deref(&self) -> &Self::Target {
766         self.ctx
767     }
768 }
769 
770 impl<'ctx, 'a, W> ops::DerefMut for AutoDemangleContextInnerBarrier<'ctx, 'a, W>
771 where
772     W: 'a + DemangleWrite,
773     'a: 'ctx,
774 {
deref_mut(&mut self) -> &mut Self::Target775     fn deref_mut(&mut self) -> &mut Self::Target {
776         self.ctx
777     }
778 }
779 
780 impl<'ctx, 'a, W> Drop for AutoDemangleContextInnerBarrier<'ctx, 'a, W>
781 where
782     W: 'a + DemangleWrite,
783     'a: 'ctx,
784 {
drop(&mut self)785     fn drop(&mut self) {
786         // NB: We cannot assert that the context's inner is empty here,
787         // because if demangling failed we'll unwind the stack without
788         // using everything that put on the inner.
789         if !self.ctx.inner.is_empty() {
790             log!("Context inner was not emptied, did demangling fail?");
791         }
792         mem::swap(&mut self.saved_inner, &mut self.ctx.inner);
793     }
794 }
795 
796 /// The inner stack allows passing AST nodes down deeper into the tree so that
797 /// nodes that logically precede something (e.g. PointerRef) can show up after
798 /// that thing in the demangled output. What's on the stack may not always be
799 /// intended for the first node that looks at the stack to grab, though.
800 ///
801 /// Consider a function with template arguments and parameters, f<T>(a).
802 /// The function parameters logically precede the template arguments in the AST,
803 /// but they must be reversed in the output. The parameters end up on the inner
804 /// stack before processing the template argument nodes. If we're not careful,
805 /// a node inside the template arguments might pick the function parameters
806 /// off of the inner stack!
807 ///
808 /// To solve this, certain nodes act as "inner barriers". By using this macro,
809 /// they set the existing inner stack aside and replace it with an empty stack
810 /// while visiting their children. This allows these barrier nodes to have
811 /// completely self-contained children.
812 macro_rules! inner_barrier {
813     ( $ctx:ident ) => {
814         let mut _ctx = AutoDemangleContextInnerBarrier::new($ctx);
815         let $ctx = &mut _ctx;
816     };
817 }
818 
819 /// Any AST node that can be printed in a demangled form.
820 #[doc(hidden)]
821 pub trait Demangle<'subs, W>: fmt::Debug
822 where
823     W: 'subs + DemangleWrite,
824 {
825     /// Write the demangled form of this AST node to the given context.
demangle<'prev, 'ctx>( &'subs self, ctx: &'ctx mut DemangleContext<'subs, W>, scope: Option<ArgScopeStack<'prev, 'subs>>, ) -> fmt::Result826     fn demangle<'prev, 'ctx>(
827         &'subs self,
828         ctx: &'ctx mut DemangleContext<'subs, W>,
829         scope: Option<ArgScopeStack<'prev, 'subs>>,
830     ) -> fmt::Result;
831 }
832 
833 /// Any AST node that can be printed as an inner type.
834 ///
835 /// See the comments surrounding `DemangleContext::inner` for details.
836 #[doc(hidden)]
837 pub trait DemangleAsInner<'subs, W>: Demangle<'subs, W>
838 where
839     W: 'subs + DemangleWrite,
840 {
841     /// Write the inner demangling form of this AST node to the given context.
demangle_as_inner<'prev, 'ctx>( &'subs self, ctx: &'ctx mut DemangleContext<'subs, W>, scope: Option<ArgScopeStack<'prev, 'subs>>, ) -> fmt::Result842     fn demangle_as_inner<'prev, 'ctx>(
843         &'subs self,
844         ctx: &'ctx mut DemangleContext<'subs, W>,
845         scope: Option<ArgScopeStack<'prev, 'subs>>,
846     ) -> fmt::Result {
847         self.demangle(ctx, scope)
848     }
849 
850     /// Cast this `DemangleAsInner` to a `Type`.
downcast_to_type(&self) -> Option<&Type>851     fn downcast_to_type(&self) -> Option<&Type> {
852         None
853     }
854 
855     /// Cast this `DemangleAsInner` to a `FunctionType`.
downcast_to_function_type(&self) -> Option<&FunctionType>856     fn downcast_to_function_type(&self) -> Option<&FunctionType> {
857         None
858     }
859 
860     /// Cast this `DemangleAsInner` to an `ArrayType`.
downcast_to_array_type(&self) -> Option<&ArrayType>861     fn downcast_to_array_type(&self) -> Option<&ArrayType> {
862         None
863     }
864 
865     /// Cast this `DemangleAsInner` to a `PointerToMember`.
downcast_to_pointer_to_member(&self) -> Option<&PointerToMemberType>866     fn downcast_to_pointer_to_member(&self) -> Option<&PointerToMemberType> {
867         None
868     }
869 
is_qualified(&self) -> bool870     fn is_qualified(&self) -> bool {
871         false
872     }
873 }
874 
875 /// Demangle this thing in the leaf name position.
876 ///
877 /// For most things this should be the same as its `Demangle`
878 /// implementation. For `WellKnownComponent`s we need to strip the embedded
879 /// `std::` namespace prefix.
880 pub(crate) trait DemangleAsLeaf<'subs, W>
881 where
882     W: 'subs + DemangleWrite,
883 {
demangle_as_leaf<'me, 'ctx>( &'me self, ctx: &'ctx mut DemangleContext<'subs, W>, ) -> fmt::Result884     fn demangle_as_leaf<'me, 'ctx>(
885         &'me self,
886         ctx: &'ctx mut DemangleContext<'subs, W>,
887     ) -> fmt::Result;
888 }
889 
890 macro_rules! reference_newtype {
891     ( $newtype_name:ident , $oldtype:ty ) => {
892         #[derive(Debug)]
893         struct $newtype_name($oldtype);
894 
895         impl $newtype_name {
896             #[allow(clippy::ptr_arg)]
897             #[allow(unsafe_code)]
898             fn new(types: &$oldtype) -> &$newtype_name {
899                 unsafe {
900                     // This is safe because we only create an immutable
901                     // reference. We are not breaking unique mutable aliasing
902                     // requirements. An immutable reference does not allow
903                     // dropping the referent, so no worries about double-free
904                     // (additionally, see the assertion inside `Drop` below).
905                     &*(types as *const $oldtype as *const $newtype_name)
906                 }
907             }
908         }
909 
910         impl Drop for $newtype_name {
911             fn drop(&mut self) {
912                 unreachable!(
913                     "Dropping implies we dereferenced and took ownership, which \
914                               is not safe for this newtype"
915                 );
916             }
917         }
918 
919         impl ops::Deref for $newtype_name {
920             type Target = $oldtype;
921 
922             fn deref(&self) -> &Self::Target {
923                 &self.0
924             }
925         }
926     };
927 }
928 
929 // We can't implement `DemangleAsInner` for newtypes of `[TypeHandle]` like we
930 // want to because it is unsized and we need to make trait objects out of
931 // `DemangleAsInner` for pushing onto the context's inner stack. Therefore, we
932 // have this inelegant newtyping of `Vec<TypeHandle>`.
933 
934 // A set of function arguments.
935 reference_newtype!(FunctionArgList, Vec<TypeHandle>);
936 
937 // A set of function arguments prefixed by a return type (which we want to
938 // ignore).
939 reference_newtype!(FunctionArgListAndReturnType, Vec<TypeHandle>);
940 
941 // A newtype around a slice of type handles that we format as function
942 // arguments.
943 reference_newtype!(FunctionArgSlice, [TypeHandle]);
944 
945 // Demangle a slice of TypeHandle as a function argument list.
946 impl<'subs, W> Demangle<'subs, W> for FunctionArgSlice
947 where
948     W: 'subs + DemangleWrite,
949 {
demangle<'prev, 'ctx>( &'subs self, ctx: &'ctx mut DemangleContext<'subs, W>, scope: Option<ArgScopeStack<'prev, 'subs>>, ) -> fmt::Result950     fn demangle<'prev, 'ctx>(
951         &'subs self,
952         ctx: &'ctx mut DemangleContext<'subs, W>,
953         scope: Option<ArgScopeStack<'prev, 'subs>>,
954     ) -> fmt::Result {
955         let ctx = try_begin_demangle!(self, ctx, scope);
956 
957         let mut saw_needs_paren = false;
958         let (needs_space, needs_paren) = ctx
959             .inner
960             .iter()
961             .rev()
962             .map(|inner| {
963                 if inner.downcast_to_pointer_to_member().is_some() {
964                     (true, true)
965                 } else {
966                     match inner.downcast_to_type() {
967                         Some(&Type::Qualified(..))
968                         | Some(&Type::Complex(_))
969                         | Some(&Type::Imaginary(_))
970                         | Some(&Type::PointerToMember(_)) => (true, true),
971                         Some(&Type::PointerTo(_))
972                         | Some(&Type::LvalueRef(_))
973                         | Some(&Type::RvalueRef(_)) => (false, true),
974                         _ => (false, false),
975                     }
976                 }
977             })
978             .take_while(|&(_, needs_paren)| {
979                 if saw_needs_paren {
980                     false
981                 } else {
982                     saw_needs_paren |= needs_paren;
983                     true
984                 }
985             })
986             .fold(
987                 (false, false),
988                 |(space, paren), (next_space, next_paren)| {
989                     (space || next_space, paren || next_paren)
990                 },
991             );
992 
993         if needs_paren {
994             let needs_space = needs_space
995                 || match ctx.last_char_written {
996                     Some('(') | Some('*') => false,
997                     _ => true,
998                 };
999 
1000             if needs_space {
1001                 ctx.ensure_space()?;
1002             }
1003 
1004             write!(ctx, "(")?;
1005         }
1006 
1007         ctx.demangle_inner_prefixes(scope)?;
1008 
1009         if needs_paren {
1010             write!(ctx, ")")?;
1011         }
1012 
1013         write!(ctx, "(")?;
1014 
1015         // To maintain compatibility with libiberty, print `()` instead of
1016         // `(void)` for functions that take no arguments.
1017         if self.len() == 1 && self[0].is_void() {
1018             write!(ctx, ")")?;
1019             return Ok(());
1020         }
1021 
1022         let mut need_comma = false;
1023         for arg in self.iter() {
1024             if need_comma {
1025                 write!(ctx, ", ")?;
1026             }
1027             arg.demangle(ctx, scope)?;
1028             need_comma = true;
1029         }
1030 
1031         write!(ctx, ")")?;
1032 
1033         ctx.demangle_inners(scope)
1034     }
1035 }
1036 
1037 impl<'subs, W> Demangle<'subs, W> for FunctionArgList
1038 where
1039     W: 'subs + DemangleWrite,
1040 {
demangle<'prev, 'ctx>( &'subs self, ctx: &'ctx mut DemangleContext<'subs, W>, scope: Option<ArgScopeStack<'prev, 'subs>>, ) -> fmt::Result1041     fn demangle<'prev, 'ctx>(
1042         &'subs self,
1043         ctx: &'ctx mut DemangleContext<'subs, W>,
1044         scope: Option<ArgScopeStack<'prev, 'subs>>,
1045     ) -> fmt::Result {
1046         FunctionArgSlice::new(&self.0[..]).demangle(ctx, scope)
1047     }
1048 }
1049 
1050 impl<'subs, W> DemangleAsInner<'subs, W> for FunctionArgList where W: 'subs + DemangleWrite {}
1051 
1052 impl<'subs, W> Demangle<'subs, W> for FunctionArgListAndReturnType
1053 where
1054     W: 'subs + DemangleWrite,
1055 {
demangle<'prev, 'ctx>( &'subs self, ctx: &'ctx mut DemangleContext<'subs, W>, scope: Option<ArgScopeStack<'prev, 'subs>>, ) -> fmt::Result1056     fn demangle<'prev, 'ctx>(
1057         &'subs self,
1058         ctx: &'ctx mut DemangleContext<'subs, W>,
1059         scope: Option<ArgScopeStack<'prev, 'subs>>,
1060     ) -> fmt::Result {
1061         FunctionArgSlice::new(&self.0[1..]).demangle(ctx, scope)
1062     }
1063 }
1064 
1065 impl<'subs, W> DemangleAsInner<'subs, W> for FunctionArgListAndReturnType where
1066     W: 'subs + DemangleWrite
1067 {
1068 }
1069 
1070 /// Define a handle to a AST type that lives inside the substitution table. A
1071 /// handle is always either an index into the substitution table, or it is a
1072 /// reference to a "well-known" component.
1073 ///
1074 /// This declares:
1075 ///
1076 /// - The enum of either a back reference into the substitution table or a
1077 ///   reference to a "well-known" component
1078 /// - a `Demangle` impl that proxies to the appropriate `Substitutable` in the
1079 ///   `SubstitutionTable`
1080 macro_rules! define_handle {
1081     (
1082         $(#[$attr:meta])*
1083         pub enum $typename:ident
1084     ) => {
1085         define_handle! {
1086             $(#[$attr])*
1087             pub enum $typename {}
1088         }
1089     };
1090 
1091     (
1092         $(#[$attr:meta])*
1093         pub enum $typename:ident {
1094             $(
1095                 $( #[$extra_attr:meta] )*
1096                 extra $extra_variant:ident ( $extra_variant_ty:ty ),
1097             )*
1098         }
1099     ) => {
1100         $(#[$attr])*
1101         #[derive(Clone, Debug, PartialEq, Eq)]
1102         pub enum $typename {
1103             /// A reference to a "well-known" component.
1104             WellKnown(WellKnownComponent),
1105 
1106             /// A back-reference into the substitution table to a component we
1107             /// have already parsed.
1108             BackReference(usize),
1109 
1110             $(
1111                 $( #[$extra_attr] )*
1112                 $extra_variant( $extra_variant_ty ),
1113             )*
1114         }
1115 
1116         impl $typename {
1117             /// If this is a `BackReference`, get its index.
1118             pub fn back_reference(&self) -> Option<usize> {
1119                 match *self {
1120                     $typename::BackReference(n) => Some(n),
1121                     _ => None,
1122                 }
1123             }
1124         }
1125 
1126         impl<'subs, W> Demangle<'subs, W> for $typename
1127         where
1128             W: 'subs + DemangleWrite
1129         {
1130             #[inline]
1131             fn demangle<'prev, 'ctx>(&'subs self,
1132                                      ctx: &'ctx mut DemangleContext<'subs, W>,
1133                                      scope: Option<ArgScopeStack<'prev, 'subs>>)
1134                                      -> fmt::Result {
1135                 match *self {
1136                     $typename::WellKnown(ref comp) => comp.demangle(ctx, scope),
1137                     $typename::BackReference(idx) => ctx.subs[idx].demangle(ctx, scope),
1138                     $(
1139                         $typename::$extra_variant(ref extra) => extra.demangle(ctx, scope),
1140                     )*
1141                 }
1142             }
1143         }
1144 
1145         impl<'a> GetLeafName<'a> for $typename {
1146             fn get_leaf_name(&'a self, subs: &'a SubstitutionTable) -> Option<LeafName<'a>> {
1147                 match *self {
1148                     $typename::WellKnown(ref wk) => wk.get_leaf_name(subs),
1149                     $typename::BackReference(idx) => {
1150                         subs.get(idx).and_then(|s| s.get_leaf_name(subs))
1151                     }
1152                     $(
1153                         $typename::$extra_variant(ref e) => e.get_leaf_name(subs),
1154                     )*
1155                 }
1156             }
1157         }
1158     };
1159 }
1160 
1161 /// A handle to a component that is usually substitutable, and lives in the
1162 /// substitutions table, but in this particular case does not qualify for
1163 /// substitutions.
1164 #[derive(Clone, Debug, PartialEq, Eq)]
1165 pub struct NonSubstitution(usize);
1166 
1167 impl<'subs, W> Demangle<'subs, W> for NonSubstitution
1168 where
1169     W: 'subs + DemangleWrite,
1170 {
demangle<'prev, 'ctx>( &'subs self, ctx: &'ctx mut DemangleContext<'subs, W>, scope: Option<ArgScopeStack<'prev, 'subs>>, ) -> fmt::Result1171     fn demangle<'prev, 'ctx>(
1172         &'subs self,
1173         ctx: &'ctx mut DemangleContext<'subs, W>,
1174         scope: Option<ArgScopeStack<'prev, 'subs>>,
1175     ) -> fmt::Result {
1176         ctx.subs.non_substitution(self.0).demangle(ctx, scope)
1177     }
1178 }
1179 
1180 impl<'a> GetLeafName<'a> for NonSubstitution {
get_leaf_name(&'a self, subs: &'a SubstitutionTable) -> Option<LeafName<'a>>1181     fn get_leaf_name(&'a self, subs: &'a SubstitutionTable) -> Option<LeafName<'a>> {
1182         subs.get_non_substitution(self.0)
1183             .and_then(|ns| ns.get_leaf_name(subs))
1184     }
1185 }
1186 
1187 /// Define a "vocabulary" nonterminal, something like `OperatorName` or
1188 /// `CtorDtorName` that's basically a big list of constant strings.
1189 ///
1190 /// This declares:
1191 ///
1192 /// - the enum itself
1193 /// - a `Parse` impl
1194 /// - a `Demangle` impl
1195 ///
1196 /// See the definition of `CTorDtorName` for an example of its use.
1197 ///
1198 /// Optionally, a piece of user data can be attached to the definitions
1199 /// and be returned by a generated accessor. See `SimpleOperatorName` for
1200 /// an example.
1201 macro_rules! define_vocabulary {
1202     ( $(#[$attr:meta])* pub enum $typename:ident {
1203         $($variant:ident ( $mangled:expr, $printable:expr )),*
1204     } ) => {
1205 
1206         $(#[$attr])*
1207         pub enum $typename {
1208             $(
1209                 #[doc=$printable]
1210                 $variant
1211             ),*
1212         }
1213 
1214         impl Parse for $typename {
1215             fn parse<'a, 'b>(ctx: &'a ParseContext,
1216                              _subs: &'a mut SubstitutionTable,
1217                              input: IndexStr<'b>)
1218                              -> Result<($typename, IndexStr<'b>)> {
1219                 try_begin_parse!(stringify!($typename), ctx, input);
1220 
1221                 let mut found_prefix = false;
1222                 $(
1223                     if let Some((head, tail)) = input.try_split_at($mangled.len()) {
1224                         if head.as_ref() == $mangled {
1225                             return Ok(($typename::$variant, tail));
1226                         }
1227                     } else {
1228                         found_prefix |= 0 < input.len() &&
1229                             input.len() < $mangled.len() &&
1230                             input.as_ref() == &$mangled[..input.len()];
1231                     }
1232                 )*
1233 
1234                 if input.is_empty() || found_prefix {
1235                     Err(error::Error::UnexpectedEnd)
1236                 } else {
1237                     Err(error::Error::UnexpectedText)
1238                 }
1239             }
1240         }
1241 
1242         impl<'subs, W> Demangle<'subs, W> for $typename
1243         where
1244             W: 'subs + DemangleWrite,
1245         {
1246             fn demangle<'prev, 'ctx>(
1247                 &'subs self,
1248                 ctx: &'ctx mut DemangleContext<'subs, W>,
1249                 scope: Option<ArgScopeStack<'prev, 'subs>>
1250             ) -> fmt::Result {
1251                 let ctx = try_begin_demangle!(self, ctx, scope);
1252 
1253                 write!(ctx, "{}", match *self {
1254                     $(
1255                         $typename::$variant => $printable
1256                     ),*
1257                 })
1258             }
1259         }
1260 
1261         impl $typename {
1262             #[allow(dead_code)]
1263             #[inline]
1264             fn starts_with(byte: u8) -> bool {
1265                 $(
1266                     if $mangled[0] == byte {
1267                         return true;
1268                     }
1269                 )*
1270 
1271                 false
1272             }
1273         }
1274     };
1275     ( $(#[$attr:meta])* pub enum $typename:ident {
1276         $($variant:ident ( $mangled:expr, $printable:expr, $userdata:expr)),*
1277     }
1278 
1279       impl $typename2:ident {
1280           fn $fn_name:ident(&self) -> $userdata_ty:ty;
1281     } ) => {
1282         define_vocabulary! {
1283             $(#[$attr])*
1284             pub enum $typename {
1285                 $(
1286                     $variant ( $mangled, $printable )
1287                 ),*
1288             }
1289         }
1290 
1291         impl $typename2 {
1292             fn $fn_name(&self) -> $userdata_ty {
1293                 match *self {
1294                     $(
1295                         $typename2::$variant => $userdata,
1296                     )*
1297                 }
1298             }
1299         }
1300     };
1301 }
1302 
1303 /// The root AST node, and starting production.
1304 ///
1305 /// ```text
1306 /// <mangled-name> ::= _Z <encoding> [<clone-suffix>]*
1307 ///                ::= ___Z <encoding> <block_invoke>
1308 ///                ::= <type>
1309 ///
1310 /// <block_invoke> ::= _block_invoke
1311 ///                ::= _block_invoke<decimal-digit>+
1312 ///                ::= _block_invoke_<decimal-digit>+
1313 /// ```
1314 #[derive(Clone, Debug, PartialEq, Eq)]
1315 pub enum MangledName {
1316     /// The encoding of the mangled symbol name.
1317     Encoding(Encoding, Vec<CloneSuffix>),
1318 
1319     /// The encoding of the mangled symbol name.
1320     BlockInvoke(Encoding, Option<isize>),
1321 
1322     /// A top-level type. Technically not allowed by the standard, however in
1323     /// practice this can happen, and is tested for by libiberty.
1324     Type(TypeHandle),
1325 
1326     /// A global constructor or destructor. This is another de facto standard
1327     /// extension (I think originally from `g++`?) that is not actually part of
1328     /// the standard proper.
1329     GlobalCtorDtor(GlobalCtorDtor),
1330 }
1331 
1332 impl Parse for MangledName {
parse<'a, 'b>( ctx: &'a ParseContext, subs: &'a mut SubstitutionTable, input: IndexStr<'b>, ) -> Result<(MangledName, IndexStr<'b>)>1333     fn parse<'a, 'b>(
1334         ctx: &'a ParseContext,
1335         subs: &'a mut SubstitutionTable,
1336         input: IndexStr<'b>,
1337     ) -> Result<(MangledName, IndexStr<'b>)> {
1338         try_begin_parse!("MangledName", ctx, input);
1339 
1340         if let Ok(tail) = consume(b"_Z", input).or_else(|_| consume(b"__Z", input)) {
1341             let (encoding, tail) = Encoding::parse(ctx, subs, tail)?;
1342             let (clone_suffixes, tail) = zero_or_more(ctx, subs, tail)?;
1343             return Ok((MangledName::Encoding(encoding, clone_suffixes), tail));
1344         }
1345 
1346         if let Ok(tail) = consume(b"___Z", input).or_else(|_| consume(b"____Z", input)) {
1347             let (encoding, tail) = Encoding::parse(ctx, subs, tail)?;
1348             let tail = consume(b"_block_invoke", tail)?;
1349 
1350             let tail_opt = match consume(b"_", tail).or_else(|_| consume(b".", tail)) {
1351                 Ok(tail) => Some(parse_number(10, false, tail)?),
1352                 Err(_) => parse_number(10, false, tail).ok(),
1353             };
1354 
1355             let (digits, tail) = match tail_opt {
1356                 Some((digits, tail)) => (Some(digits), tail),
1357                 None => (None, tail),
1358             };
1359 
1360             return Ok((MangledName::BlockInvoke(encoding, digits), tail));
1361         }
1362 
1363         if let Ok(tail) = consume(b"_GLOBAL_", input) {
1364             let (global_ctor_dtor, tail) = GlobalCtorDtor::parse(ctx, subs, tail)?;
1365             return Ok((MangledName::GlobalCtorDtor(global_ctor_dtor), tail));
1366         }
1367 
1368         // The libiberty tests also specify that a type can be top level,
1369         // and they are not prefixed with "_Z".
1370         let (ty, tail) = TypeHandle::parse(ctx, subs, input)?;
1371         Ok((MangledName::Type(ty), tail))
1372     }
1373 }
1374 
1375 impl<'subs, W> Demangle<'subs, W> for MangledName
1376 where
1377     W: 'subs + DemangleWrite,
1378 {
demangle<'prev, 'ctx>( &'subs self, ctx: &'ctx mut DemangleContext<'subs, W>, scope: Option<ArgScopeStack<'prev, 'subs>>, ) -> fmt::Result1379     fn demangle<'prev, 'ctx>(
1380         &'subs self,
1381         ctx: &'ctx mut DemangleContext<'subs, W>,
1382         scope: Option<ArgScopeStack<'prev, 'subs>>,
1383     ) -> fmt::Result {
1384         let ctx = try_begin_demangle!(self, ctx, scope);
1385 
1386         match *self {
1387             MangledName::Encoding(ref enc, ref cs) => {
1388                 enc.demangle(ctx, scope)?;
1389                 if !cs.is_empty() && ctx.show_params {
1390                     for clone_suffix in cs {
1391                         clone_suffix.demangle(ctx, scope)?;
1392                     }
1393                 }
1394                 Ok(())
1395             }
1396             MangledName::BlockInvoke(ref enc, _) => {
1397                 write!(ctx, "invocation function for block in ")?;
1398                 enc.demangle(ctx, scope)?;
1399                 Ok(())
1400             }
1401             MangledName::Type(ref ty) => ty.demangle(ctx, scope),
1402             MangledName::GlobalCtorDtor(ref gcd) => gcd.demangle(ctx, scope),
1403         }
1404     }
1405 }
1406 
1407 /// The `<encoding>` production.
1408 ///
1409 /// ```text
1410 /// <encoding> ::= <function name> <bare-function-type>
1411 ///            ::= <data name>
1412 ///            ::= <special-name>
1413 /// ```
1414 #[derive(Clone, Debug, PartialEq, Eq)]
1415 pub enum Encoding {
1416     /// An encoded function.
1417     Function(Name, BareFunctionType),
1418 
1419     /// An encoded static variable.
1420     Data(Name),
1421 
1422     /// A special encoding.
1423     Special(SpecialName),
1424 }
1425 
1426 impl Parse for Encoding {
parse<'a, 'b>( ctx: &'a ParseContext, subs: &'a mut SubstitutionTable, input: IndexStr<'b>, ) -> Result<(Encoding, IndexStr<'b>)>1427     fn parse<'a, 'b>(
1428         ctx: &'a ParseContext,
1429         subs: &'a mut SubstitutionTable,
1430         input: IndexStr<'b>,
1431     ) -> Result<(Encoding, IndexStr<'b>)> {
1432         try_begin_parse!("Encoding", ctx, input);
1433 
1434         if let Ok((name, tail)) = Name::parse(ctx, subs, input) {
1435             if let Ok((ty, tail)) = BareFunctionType::parse(ctx, subs, tail) {
1436                 return Ok((Encoding::Function(name, ty), tail));
1437             } else {
1438                 return Ok((Encoding::Data(name), tail));
1439             }
1440         }
1441 
1442         let (name, tail) = SpecialName::parse(ctx, subs, input)?;
1443         Ok((Encoding::Special(name), tail))
1444     }
1445 }
1446 
1447 impl<'subs, W> Demangle<'subs, W> for Encoding
1448 where
1449     W: 'subs + DemangleWrite,
1450 {
demangle<'prev, 'ctx>( &'subs self, ctx: &'ctx mut DemangleContext<'subs, W>, scope: Option<ArgScopeStack<'prev, 'subs>>, ) -> fmt::Result1451     fn demangle<'prev, 'ctx>(
1452         &'subs self,
1453         ctx: &'ctx mut DemangleContext<'subs, W>,
1454         scope: Option<ArgScopeStack<'prev, 'subs>>,
1455     ) -> fmt::Result {
1456         let ctx = try_begin_demangle!(self, ctx, scope);
1457         inner_barrier!(ctx);
1458 
1459         match *self {
1460             Encoding::Function(ref name, ref fun_ty) => {
1461                 // Even if this function takes no args and doesn't have a return
1462                 // value (see below), it will have the void parameter.
1463                 debug_assert!(!fun_ty.0.is_empty());
1464 
1465                 let scope = if let Some(leaf) = name.get_leaf_name(ctx.subs) {
1466                     match leaf {
1467                         LeafName::SourceName(leaf) => scope.push(leaf),
1468                         LeafName::WellKnownComponent(leaf) => scope.push(leaf),
1469                         LeafName::Closure(leaf) => scope.push(leaf),
1470                         LeafName::UnnamedType(leaf) => scope.push(leaf),
1471                     }
1472                 } else {
1473                     scope
1474                 };
1475 
1476                 // Whether the first type in the BareFunctionType is a return
1477                 // type or parameter depends on the context in which it
1478                 // appears.
1479                 //
1480                 // * Templates and functions in a type or parameter position
1481                 // have return types, unless they are constructors, destructors,
1482                 // or conversion operator functions.
1483                 //
1484                 // * Non-template functions that are not in a type or parameter
1485                 // position do not have a return type.
1486                 //
1487                 // We know we are not printing a type, so we only need to check
1488                 // whether this is a template.
1489                 //
1490                 // For the details, see
1491                 // http://itanium-cxx-abi.github.io/cxx-abi/abi.html#mangle.function-type
1492                 let scope = if let Some(template_args) = name.get_template_args(ctx.subs) {
1493                     let scope = scope.push(template_args);
1494                     if ctx.show_return_type && !name.is_ctor_dtor_conversion(ctx.subs) {
1495                         fun_ty.0[0].demangle(ctx, scope)?;
1496                         write!(ctx, " ")?;
1497                     }
1498 
1499                     scope
1500                 } else {
1501                     scope
1502                 };
1503 
1504                 if ctx.show_params {
1505                     ctx.push_inner(self);
1506                     name.demangle(ctx, scope)?;
1507                     if ctx.pop_inner_if(self) {
1508                         self.demangle_as_inner(ctx, scope)?;
1509                     }
1510                 } else {
1511                     name.demangle(ctx, scope)?;
1512                 }
1513 
1514                 Ok(())
1515             }
1516             Encoding::Data(ref name) => name.demangle(ctx, scope),
1517             Encoding::Special(ref name) => name.demangle(ctx, scope),
1518         }
1519     }
1520 }
1521 
1522 impl<'subs, W> DemangleAsInner<'subs, W> for Encoding
1523 where
1524     W: 'subs + DemangleWrite,
1525 {
demangle_as_inner<'prev, 'ctx>( &'subs self, ctx: &'ctx mut DemangleContext<'subs, W>, scope: Option<ArgScopeStack<'prev, 'subs>>, ) -> fmt::Result1526     fn demangle_as_inner<'prev, 'ctx>(
1527         &'subs self,
1528         ctx: &'ctx mut DemangleContext<'subs, W>,
1529         scope: Option<ArgScopeStack<'prev, 'subs>>,
1530     ) -> fmt::Result {
1531         if let Encoding::Function(ref name, ref fun_ty) = *self {
1532             let (scope, function_args) =
1533                 if let Some(template_args) = name.get_template_args(ctx.subs) {
1534                     let scope = scope.push(template_args);
1535                     let function_args = FunctionArgListAndReturnType::new(&fun_ty.0);
1536                     (scope, function_args as &dyn DemangleAsInner<W>)
1537                 } else {
1538                     let function_args = FunctionArgList::new(&fun_ty.0);
1539                     (scope, function_args as &dyn DemangleAsInner<W>)
1540                 };
1541             function_args.demangle_as_inner(ctx, scope)
1542         } else {
1543             unreachable!("we only push Encoding::Function onto the inner stack");
1544         }
1545     }
1546 }
1547 
1548 /// <clone-suffix> ::= [ . <clone-type-identifier> ] [ . <nonnegative number> ]*
1549 
1550 #[derive(Clone, Debug, PartialEq, Eq)]
1551 pub struct CloneSuffix(CloneTypeIdentifier, Vec<isize>);
1552 
1553 impl Parse for CloneSuffix {
parse<'a, 'b>( ctx: &'a ParseContext, subs: &'a mut SubstitutionTable, input: IndexStr<'b>, ) -> Result<(CloneSuffix, IndexStr<'b>)>1554     fn parse<'a, 'b>(
1555         ctx: &'a ParseContext,
1556         subs: &'a mut SubstitutionTable,
1557         input: IndexStr<'b>,
1558     ) -> Result<(CloneSuffix, IndexStr<'b>)> {
1559         try_begin_parse!("CloneSuffix", ctx, input);
1560 
1561         let tail = consume(b".", input)?;
1562         let (identifier, mut tail) = CloneTypeIdentifier::parse(ctx, subs, tail)?;
1563 
1564         let mut numbers = Vec::with_capacity(1);
1565         while let Ok((n, t)) = consume(b".", tail).and_then(|t| parse_number(10, false, t)) {
1566             numbers.push(n);
1567             tail = t;
1568         }
1569 
1570         let clone_suffix = CloneSuffix(identifier, numbers);
1571         Ok((clone_suffix, tail))
1572     }
1573 }
1574 
1575 impl<'subs, W> Demangle<'subs, W> for CloneSuffix
1576 where
1577     W: 'subs + DemangleWrite,
1578 {
demangle<'prev, 'ctx>( &'subs self, ctx: &'ctx mut DemangleContext<'subs, W>, scope: Option<ArgScopeStack<'prev, 'subs>>, ) -> fmt::Result1579     fn demangle<'prev, 'ctx>(
1580         &'subs self,
1581         ctx: &'ctx mut DemangleContext<'subs, W>,
1582         scope: Option<ArgScopeStack<'prev, 'subs>>,
1583     ) -> fmt::Result {
1584         let ctx = try_begin_demangle!(self, ctx, scope);
1585         write!(ctx, " [clone")?;
1586         self.0.demangle(ctx, scope)?;
1587         for nonnegative in &self.1 {
1588             write!(ctx, ".{}", nonnegative)?;
1589         }
1590         write!(ctx, "]")?;
1591         Ok(())
1592     }
1593 }
1594 
1595 /// A global constructor or destructor.
1596 #[derive(Clone, Debug, PartialEq, Eq)]
1597 pub enum GlobalCtorDtor {
1598     /// A global constructor.
1599     Ctor(Box<MangledName>),
1600     /// A global destructor.
1601     Dtor(Box<MangledName>),
1602 }
1603 
1604 impl Parse for GlobalCtorDtor {
parse<'a, 'b>( ctx: &'a ParseContext, subs: &'a mut SubstitutionTable, input: IndexStr<'b>, ) -> Result<(GlobalCtorDtor, IndexStr<'b>)>1605     fn parse<'a, 'b>(
1606         ctx: &'a ParseContext,
1607         subs: &'a mut SubstitutionTable,
1608         input: IndexStr<'b>,
1609     ) -> Result<(GlobalCtorDtor, IndexStr<'b>)> {
1610         try_begin_parse!("GlobalCtorDtor", ctx, input);
1611 
1612         let tail = match input.next_or(error::Error::UnexpectedEnd)? {
1613             (b'_', t) | (b'.', t) | (b'$', t) => t,
1614             _ => return Err(error::Error::UnexpectedText),
1615         };
1616 
1617         match tail.next_or(error::Error::UnexpectedEnd)? {
1618             (b'I', tail) => {
1619                 let tail = consume(b"_", tail)?;
1620                 let (name, tail) = MangledName::parse(ctx, subs, tail)?;
1621                 Ok((GlobalCtorDtor::Ctor(Box::new(name)), tail))
1622             }
1623             (b'D', tail) => {
1624                 let tail = consume(b"_", tail)?;
1625                 let (name, tail) = MangledName::parse(ctx, subs, tail)?;
1626                 Ok((GlobalCtorDtor::Dtor(Box::new(name)), tail))
1627             }
1628             _ => Err(error::Error::UnexpectedText),
1629         }
1630     }
1631 }
1632 
1633 impl<'subs, W> Demangle<'subs, W> for GlobalCtorDtor
1634 where
1635     W: 'subs + DemangleWrite,
1636 {
demangle<'prev, 'ctx>( &'subs self, ctx: &'ctx mut DemangleContext<'subs, W>, scope: Option<ArgScopeStack<'prev, 'subs>>, ) -> fmt::Result1637     fn demangle<'prev, 'ctx>(
1638         &'subs self,
1639         ctx: &'ctx mut DemangleContext<'subs, W>,
1640         scope: Option<ArgScopeStack<'prev, 'subs>>,
1641     ) -> fmt::Result {
1642         let ctx = try_begin_demangle!(self, ctx, scope);
1643         inner_barrier!(ctx);
1644 
1645         let saved_show_params = ctx.show_params;
1646         ctx.show_params = true;
1647         let ret = match *self {
1648             GlobalCtorDtor::Ctor(ref name) => {
1649                 write!(ctx, "global constructors keyed to ")?;
1650                 name.demangle(ctx, scope)
1651             }
1652             GlobalCtorDtor::Dtor(ref name) => {
1653                 write!(ctx, "global destructors keyed to ")?;
1654                 name.demangle(ctx, scope)
1655             }
1656         };
1657         ctx.show_params = saved_show_params;
1658         ret
1659     }
1660 }
1661 
1662 /// The `<name>` production.
1663 ///
1664 /// ```text
1665 /// <name> ::= <nested-name>
1666 ///        ::= <unscoped-name>
1667 ///        ::= <unscoped-template-name> <template-args>
1668 ///        ::= <local-name>
1669 /// ```
1670 #[derive(Clone, Debug, PartialEq, Eq)]
1671 pub enum Name {
1672     /// A nested name
1673     Nested(NestedName),
1674 
1675     /// An unscoped name.
1676     Unscoped(UnscopedName),
1677 
1678     /// An unscoped template.
1679     UnscopedTemplate(UnscopedTemplateNameHandle, TemplateArgs),
1680 
1681     /// A local name.
1682     Local(LocalName),
1683 }
1684 
1685 impl Parse for Name {
parse<'a, 'b>( ctx: &'a ParseContext, subs: &'a mut SubstitutionTable, input: IndexStr<'b>, ) -> Result<(Name, IndexStr<'b>)>1686     fn parse<'a, 'b>(
1687         ctx: &'a ParseContext,
1688         subs: &'a mut SubstitutionTable,
1689         input: IndexStr<'b>,
1690     ) -> Result<(Name, IndexStr<'b>)> {
1691         try_begin_parse!("Name", ctx, input);
1692 
1693         if let Ok((name, tail)) = NestedName::parse(ctx, subs, input) {
1694             return Ok((Name::Nested(name), tail));
1695         }
1696 
1697         if let Ok((name, tail)) = UnscopedName::parse(ctx, subs, input) {
1698             if tail.peek() == Some(b'I') {
1699                 let name = UnscopedTemplateName(name);
1700                 let idx = subs.insert(Substitutable::UnscopedTemplateName(name));
1701                 let handle = UnscopedTemplateNameHandle::BackReference(idx);
1702 
1703                 let (args, tail) = TemplateArgs::parse(ctx, subs, tail)?;
1704                 return Ok((Name::UnscopedTemplate(handle, args), tail));
1705             } else {
1706                 return Ok((Name::Unscoped(name), tail));
1707             }
1708         }
1709 
1710         if let Ok((name, tail)) = UnscopedTemplateNameHandle::parse(ctx, subs, input) {
1711             let (args, tail) = TemplateArgs::parse(ctx, subs, tail)?;
1712             return Ok((Name::UnscopedTemplate(name, args), tail));
1713         }
1714 
1715         let (name, tail) = LocalName::parse(ctx, subs, input)?;
1716         Ok((Name::Local(name), tail))
1717     }
1718 }
1719 
1720 impl<'subs, W> Demangle<'subs, W> for Name
1721 where
1722     W: 'subs + DemangleWrite,
1723 {
demangle<'prev, 'ctx>( &'subs self, ctx: &'ctx mut DemangleContext<'subs, W>, scope: Option<ArgScopeStack<'prev, 'subs>>, ) -> fmt::Result1724     fn demangle<'prev, 'ctx>(
1725         &'subs self,
1726         ctx: &'ctx mut DemangleContext<'subs, W>,
1727         scope: Option<ArgScopeStack<'prev, 'subs>>,
1728     ) -> fmt::Result {
1729         let ctx = try_begin_demangle!(self, ctx, scope);
1730 
1731         match *self {
1732             Name::Nested(ref nested) => nested.demangle(ctx, scope),
1733             Name::Unscoped(ref unscoped) => unscoped.demangle(ctx, scope),
1734             Name::UnscopedTemplate(ref template, ref args) => {
1735                 template.demangle(ctx, scope.push(args))?;
1736                 args.demangle(ctx, scope)
1737             }
1738             Name::Local(ref local) => local.demangle(ctx, scope),
1739         }
1740     }
1741 }
1742 
1743 impl GetTemplateArgs for Name {
get_template_args<'a>(&'a self, subs: &'a SubstitutionTable) -> Option<&'a TemplateArgs>1744     fn get_template_args<'a>(&'a self, subs: &'a SubstitutionTable) -> Option<&'a TemplateArgs> {
1745         match *self {
1746             Name::UnscopedTemplate(_, ref args) => Some(args),
1747             Name::Nested(ref nested) => nested.get_template_args(subs),
1748             Name::Local(ref local) => local.get_template_args(subs),
1749             Name::Unscoped(_) => None,
1750         }
1751     }
1752 }
1753 
1754 impl<'a> GetLeafName<'a> for Name {
get_leaf_name(&'a self, subs: &'a SubstitutionTable) -> Option<LeafName<'a>>1755     fn get_leaf_name(&'a self, subs: &'a SubstitutionTable) -> Option<LeafName<'a>> {
1756         match *self {
1757             Name::UnscopedTemplate(ref templ, _) => templ.get_leaf_name(subs),
1758             Name::Nested(ref nested) => nested.get_leaf_name(subs),
1759             Name::Unscoped(ref unscoped) => unscoped.get_leaf_name(subs),
1760             Name::Local(ref local) => local.get_leaf_name(subs),
1761         }
1762     }
1763 }
1764 
1765 impl IsCtorDtorConversion for Name {
is_ctor_dtor_conversion(&self, subs: &SubstitutionTable) -> bool1766     fn is_ctor_dtor_conversion(&self, subs: &SubstitutionTable) -> bool {
1767         match *self {
1768             Name::Unscoped(ref unscoped) => unscoped.is_ctor_dtor_conversion(subs),
1769             Name::Nested(ref nested) => nested.is_ctor_dtor_conversion(subs),
1770             Name::Local(_) | Name::UnscopedTemplate(..) => false,
1771         }
1772     }
1773 }
1774 
1775 /// The `<unscoped-name>` production.
1776 ///
1777 /// ```text
1778 /// <unscoped-name> ::= <unqualified-name>
1779 ///                 ::= St <unqualified-name>   # ::std::
1780 /// ```
1781 #[derive(Clone, Debug, PartialEq, Eq)]
1782 pub enum UnscopedName {
1783     /// An unqualified name.
1784     Unqualified(UnqualifiedName),
1785 
1786     /// A name within the `std::` namespace.
1787     Std(UnqualifiedName),
1788 }
1789 
1790 impl Parse for UnscopedName {
parse<'a, 'b>( ctx: &'a ParseContext, subs: &'a mut SubstitutionTable, input: IndexStr<'b>, ) -> Result<(UnscopedName, IndexStr<'b>)>1791     fn parse<'a, 'b>(
1792         ctx: &'a ParseContext,
1793         subs: &'a mut SubstitutionTable,
1794         input: IndexStr<'b>,
1795     ) -> Result<(UnscopedName, IndexStr<'b>)> {
1796         try_begin_parse!("UnscopedName", ctx, input);
1797 
1798         if let Ok(tail) = consume(b"St", input) {
1799             let (name, tail) = UnqualifiedName::parse(ctx, subs, tail)?;
1800             return Ok((UnscopedName::Std(name), tail));
1801         }
1802 
1803         let (name, tail) = UnqualifiedName::parse(ctx, subs, input)?;
1804         Ok((UnscopedName::Unqualified(name), tail))
1805     }
1806 }
1807 
1808 impl<'subs, W> Demangle<'subs, W> for UnscopedName
1809 where
1810     W: 'subs + DemangleWrite,
1811 {
demangle<'prev, 'ctx>( &'subs self, ctx: &'ctx mut DemangleContext<'subs, W>, scope: Option<ArgScopeStack<'prev, 'subs>>, ) -> fmt::Result1812     fn demangle<'prev, 'ctx>(
1813         &'subs self,
1814         ctx: &'ctx mut DemangleContext<'subs, W>,
1815         scope: Option<ArgScopeStack<'prev, 'subs>>,
1816     ) -> fmt::Result {
1817         let ctx = try_begin_demangle!(self, ctx, scope);
1818 
1819         match *self {
1820             UnscopedName::Unqualified(ref unqualified) => unqualified.demangle(ctx, scope),
1821             UnscopedName::Std(ref std) => {
1822                 write!(ctx, "std::")?;
1823                 std.demangle(ctx, scope)
1824             }
1825         }
1826     }
1827 }
1828 
1829 impl<'a> GetLeafName<'a> for UnscopedName {
get_leaf_name(&'a self, subs: &'a SubstitutionTable) -> Option<LeafName<'a>>1830     fn get_leaf_name(&'a self, subs: &'a SubstitutionTable) -> Option<LeafName<'a>> {
1831         match *self {
1832             UnscopedName::Unqualified(ref name) | UnscopedName::Std(ref name) => {
1833                 name.get_leaf_name(subs)
1834             }
1835         }
1836     }
1837 }
1838 
1839 impl IsCtorDtorConversion for UnscopedName {
is_ctor_dtor_conversion(&self, subs: &SubstitutionTable) -> bool1840     fn is_ctor_dtor_conversion(&self, subs: &SubstitutionTable) -> bool {
1841         match *self {
1842             UnscopedName::Unqualified(ref name) | UnscopedName::Std(ref name) => {
1843                 name.is_ctor_dtor_conversion(subs)
1844             }
1845         }
1846     }
1847 }
1848 
1849 /// The `<unscoped-template-name>` production.
1850 ///
1851 /// ```text
1852 /// <unscoped-template-name> ::= <unscoped-name>
1853 ///                          ::= <substitution>
1854 /// ```
1855 #[derive(Clone, Debug, PartialEq, Eq)]
1856 pub struct UnscopedTemplateName(UnscopedName);
1857 
1858 define_handle! {
1859     /// A handle to an `UnscopedTemplateName`.
1860     pub enum UnscopedTemplateNameHandle {
1861         /// A handle to some `<unscoped-name>` component that isn't by itself
1862         /// substitutable.
1863         extra NonSubstitution(NonSubstitution),
1864     }
1865 }
1866 
1867 impl Parse for UnscopedTemplateNameHandle {
parse<'a, 'b>( ctx: &'a ParseContext, subs: &'a mut SubstitutionTable, input: IndexStr<'b>, ) -> Result<(UnscopedTemplateNameHandle, IndexStr<'b>)>1868     fn parse<'a, 'b>(
1869         ctx: &'a ParseContext,
1870         subs: &'a mut SubstitutionTable,
1871         input: IndexStr<'b>,
1872     ) -> Result<(UnscopedTemplateNameHandle, IndexStr<'b>)> {
1873         try_begin_parse!("UnscopedTemplateNameHandle", ctx, input);
1874 
1875         if let Ok((name, tail)) = UnscopedName::parse(ctx, subs, input) {
1876             let name = UnscopedTemplateName(name);
1877             let idx = subs.insert(Substitutable::UnscopedTemplateName(name));
1878             let handle = UnscopedTemplateNameHandle::BackReference(idx);
1879             return Ok((handle, tail));
1880         }
1881 
1882         let (sub, tail) = Substitution::parse(ctx, subs, input)?;
1883 
1884         match sub {
1885             Substitution::WellKnown(component) => {
1886                 Ok((UnscopedTemplateNameHandle::WellKnown(component), tail))
1887             }
1888             Substitution::BackReference(idx) => {
1889                 // TODO: should this check/assert that subs[idx] is an
1890                 // UnscopedTemplateName?
1891                 Ok((UnscopedTemplateNameHandle::BackReference(idx), tail))
1892             }
1893         }
1894     }
1895 }
1896 
1897 impl<'subs, W> Demangle<'subs, W> for UnscopedTemplateName
1898 where
1899     W: 'subs + DemangleWrite,
1900 {
demangle<'prev, 'ctx>( &'subs self, ctx: &'ctx mut DemangleContext<'subs, W>, scope: Option<ArgScopeStack<'prev, 'subs>>, ) -> fmt::Result1901     fn demangle<'prev, 'ctx>(
1902         &'subs self,
1903         ctx: &'ctx mut DemangleContext<'subs, W>,
1904         scope: Option<ArgScopeStack<'prev, 'subs>>,
1905     ) -> fmt::Result {
1906         let ctx = try_begin_demangle!(self, ctx, scope);
1907 
1908         self.0.demangle(ctx, scope)
1909     }
1910 }
1911 
1912 impl<'a> GetLeafName<'a> for UnscopedTemplateName {
get_leaf_name(&'a self, subs: &'a SubstitutionTable) -> Option<LeafName<'a>>1913     fn get_leaf_name(&'a self, subs: &'a SubstitutionTable) -> Option<LeafName<'a>> {
1914         self.0.get_leaf_name(subs)
1915     }
1916 }
1917 
1918 /// The `<nested-name>` production.
1919 ///
1920 /// ```text
1921 /// <nested-name> ::= N [<CV-qualifiers>] [<ref-qualifier>] <prefix> <unqualified-name> E
1922 ///               ::= N [<CV-qualifiers>] [<ref-qualifier>] <template-prefix> <template-args> E
1923 /// ```
1924 #[derive(Clone, Debug, PartialEq, Eq)]
1925 pub enum NestedName {
1926     /// A nested name.
1927     Unqualified(
1928         CvQualifiers,
1929         Option<RefQualifier>,
1930         PrefixHandle,
1931         UnqualifiedName,
1932     ),
1933 
1934     /// A nested template name. The `<template-args>` are part of the `PrefixHandle`.
1935     Template(CvQualifiers, Option<RefQualifier>, PrefixHandle),
1936 }
1937 
1938 impl Parse for NestedName {
parse<'a, 'b>( ctx: &'a ParseContext, subs: &'a mut SubstitutionTable, input: IndexStr<'b>, ) -> Result<(NestedName, IndexStr<'b>)>1939     fn parse<'a, 'b>(
1940         ctx: &'a ParseContext,
1941         subs: &'a mut SubstitutionTable,
1942         input: IndexStr<'b>,
1943     ) -> Result<(NestedName, IndexStr<'b>)> {
1944         try_begin_parse!("NestedName", ctx, input);
1945 
1946         let tail = consume(b"N", input)?;
1947 
1948         let (cv_qualifiers, tail) = if let Ok((q, tail)) = CvQualifiers::parse(ctx, subs, tail) {
1949             (q, tail)
1950         } else {
1951             (Default::default(), tail)
1952         };
1953 
1954         let (ref_qualifier, tail) = if let Ok((r, tail)) = RefQualifier::parse(ctx, subs, tail) {
1955             (Some(r), tail)
1956         } else {
1957             (None, tail)
1958         };
1959 
1960         let (prefix, tail) = PrefixHandle::parse(ctx, subs, tail)?;
1961         let tail = consume(b"E", tail)?;
1962 
1963         let substitutable = match prefix {
1964             PrefixHandle::BackReference(idx) => subs.get(idx),
1965             PrefixHandle::NonSubstitution(NonSubstitution(idx)) => subs.get_non_substitution(idx),
1966             PrefixHandle::WellKnown(_) => None,
1967         };
1968 
1969         match substitutable {
1970             Some(&Substitutable::Prefix(Prefix::Nested(ref prefix, ref name))) => Ok((
1971                 NestedName::Unqualified(cv_qualifiers, ref_qualifier, prefix.clone(), name.clone()),
1972                 tail,
1973             )),
1974             Some(&Substitutable::Prefix(Prefix::Template(..))) => Ok((
1975                 NestedName::Template(cv_qualifiers, ref_qualifier, prefix),
1976                 tail,
1977             )),
1978             _ => Err(error::Error::UnexpectedText),
1979         }
1980     }
1981 }
1982 
1983 impl NestedName {
1984     /// Get the CV-qualifiers for this name.
cv_qualifiers(&self) -> &CvQualifiers1985     pub fn cv_qualifiers(&self) -> &CvQualifiers {
1986         match *self {
1987             NestedName::Unqualified(ref q, ..) | NestedName::Template(ref q, ..) => q,
1988         }
1989     }
1990 
1991     /// Get the ref-qualifier for this name, if one exists.
ref_qualifier(&self) -> Option<&RefQualifier>1992     pub fn ref_qualifier(&self) -> Option<&RefQualifier> {
1993         match *self {
1994             NestedName::Unqualified(_, Some(ref r), ..)
1995             | NestedName::Template(_, Some(ref r), ..) => Some(r),
1996             _ => None,
1997         }
1998     }
1999 
2000     // Not public because the prefix means different things for different
2001     // variants, and for `::Template` it actually contains part of what
2002     // conceptually belongs to `<nested-name>`.
prefix(&self) -> &PrefixHandle2003     fn prefix(&self) -> &PrefixHandle {
2004         match *self {
2005             NestedName::Unqualified(_, _, ref p, _) | NestedName::Template(_, _, ref p) => p,
2006         }
2007     }
2008 }
2009 
2010 impl<'subs, W> Demangle<'subs, W> for NestedName
2011 where
2012     W: 'subs + DemangleWrite,
2013 {
demangle<'prev, 'ctx>( &'subs self, ctx: &'ctx mut DemangleContext<'subs, W>, scope: Option<ArgScopeStack<'prev, 'subs>>, ) -> fmt::Result2014     fn demangle<'prev, 'ctx>(
2015         &'subs self,
2016         ctx: &'ctx mut DemangleContext<'subs, W>,
2017         scope: Option<ArgScopeStack<'prev, 'subs>>,
2018     ) -> fmt::Result {
2019         let ctx = try_begin_demangle!(self, ctx, scope);
2020 
2021         match *self {
2022             NestedName::Unqualified(_, _, ref p, ref name) => {
2023                 ctx.push_demangle_node(DemangleNodeType::NestedName);
2024                 p.demangle(ctx, scope)?;
2025                 if name.accepts_double_colon() {
2026                     ctx.write_str("::")?;
2027                 }
2028                 name.demangle(ctx, scope)?;
2029                 ctx.pop_demangle_node();
2030             }
2031             NestedName::Template(_, _, ref p) => {
2032                 ctx.is_template_prefix_in_nested_name = true;
2033                 p.demangle(ctx, scope)?;
2034                 ctx.is_template_prefix_in_nested_name = false;
2035             }
2036         }
2037 
2038         if let Some(inner) = ctx.pop_inner() {
2039             inner.demangle_as_inner(ctx, scope)?;
2040         }
2041 
2042         if self.cv_qualifiers() != &CvQualifiers::default() && ctx.show_params {
2043             self.cv_qualifiers().demangle(ctx, scope)?;
2044         }
2045 
2046         if let Some(ref refs) = self.ref_qualifier() {
2047             ctx.ensure_space()?;
2048             refs.demangle(ctx, scope)?;
2049         }
2050 
2051         Ok(())
2052     }
2053 }
2054 
2055 impl GetTemplateArgs for NestedName {
get_template_args<'a>(&'a self, subs: &'a SubstitutionTable) -> Option<&'a TemplateArgs>2056     fn get_template_args<'a>(&'a self, subs: &'a SubstitutionTable) -> Option<&'a TemplateArgs> {
2057         match *self {
2058             NestedName::Template(_, _, ref prefix) => prefix.get_template_args(subs),
2059             _ => None,
2060         }
2061     }
2062 }
2063 
2064 impl<'a> GetLeafName<'a> for NestedName {
get_leaf_name(&'a self, subs: &'a SubstitutionTable) -> Option<LeafName<'a>>2065     fn get_leaf_name(&'a self, subs: &'a SubstitutionTable) -> Option<LeafName<'a>> {
2066         match *self {
2067             NestedName::Unqualified(_, _, ref prefix, ref name) => name
2068                 .get_leaf_name(subs)
2069                 .or_else(|| prefix.get_leaf_name(subs)),
2070             NestedName::Template(_, _, ref prefix) => prefix.get_leaf_name(subs),
2071         }
2072     }
2073 }
2074 
2075 impl IsCtorDtorConversion for NestedName {
is_ctor_dtor_conversion(&self, subs: &SubstitutionTable) -> bool2076     fn is_ctor_dtor_conversion(&self, subs: &SubstitutionTable) -> bool {
2077         self.prefix().is_ctor_dtor_conversion(subs)
2078     }
2079 }
2080 
2081 /// The `<prefix>` production.
2082 ///
2083 /// ```text
2084 /// <prefix> ::= <unqualified-name>
2085 ///          ::= <prefix> <unqualified-name>
2086 ///          ::= <template-prefix> <template-args>
2087 ///          ::= <template-param>
2088 ///          ::= <decltype>
2089 ///          ::= <prefix> <data-member-prefix>
2090 ///          ::= <substitution>
2091 ///
2092 /// <template-prefix> ::= <template unqualified-name>
2093 ///                   ::= <prefix> <template unqualified-name>
2094 ///                   ::= <template-param>
2095 ///                   ::= <substitution>
2096 /// ```
2097 #[derive(Clone, Debug, PartialEq, Eq)]
2098 pub enum Prefix {
2099     /// An unqualified name.
2100     Unqualified(UnqualifiedName),
2101 
2102     /// Some nested name.
2103     Nested(PrefixHandle, UnqualifiedName),
2104 
2105     /// A prefix and template arguments.
2106     Template(PrefixHandle, TemplateArgs),
2107 
2108     /// A template parameter.
2109     TemplateParam(TemplateParam),
2110 
2111     /// A decltype.
2112     Decltype(Decltype),
2113 
2114     /// A prefix and data member.
2115     DataMember(PrefixHandle, DataMemberPrefix),
2116 }
2117 
2118 impl GetTemplateArgs for Prefix {
get_template_args<'a>(&'a self, _: &'a SubstitutionTable) -> Option<&'a TemplateArgs>2119     fn get_template_args<'a>(&'a self, _: &'a SubstitutionTable) -> Option<&'a TemplateArgs> {
2120         match *self {
2121             Prefix::Template(_, ref args) => Some(args),
2122             Prefix::Unqualified(_)
2123             | Prefix::Nested(_, _)
2124             | Prefix::TemplateParam(_)
2125             | Prefix::Decltype(_)
2126             | Prefix::DataMember(_, _) => None,
2127         }
2128     }
2129 }
2130 
2131 define_handle! {
2132     /// A reference to a parsed `<prefix>` production.
2133     pub enum PrefixHandle {
2134         /// A handle to some `<prefix>` component that isn't by itself
2135         /// substitutable; instead, it's only substitutable *with* its parent
2136         /// component.
2137         extra NonSubstitution(NonSubstitution),
2138     }
2139 }
2140 
2141 impl Parse for PrefixHandle {
parse<'a, 'b>( ctx: &'a ParseContext, subs: &'a mut SubstitutionTable, input: IndexStr<'b>, ) -> Result<(PrefixHandle, IndexStr<'b>)>2142     fn parse<'a, 'b>(
2143         ctx: &'a ParseContext,
2144         subs: &'a mut SubstitutionTable,
2145         input: IndexStr<'b>,
2146     ) -> Result<(PrefixHandle, IndexStr<'b>)> {
2147         try_begin_parse!("PrefixHandle", ctx, input);
2148 
2149         #[inline]
2150         fn save(
2151             subs: &mut SubstitutionTable,
2152             prefix: Prefix,
2153             tail_tail: IndexStr<'_>,
2154         ) -> PrefixHandle {
2155             if let Some(b'E') = tail_tail.peek() {
2156                 // An `E` means that we just finished parsing a `<nested-name>`
2157                 // and this final set of prefixes isn't substitutable itself,
2158                 // only as part of the whole `<nested-name>`. Since they are
2159                 // effectively equivalent, it doesn't make sense to add entries
2160                 // for both.
2161                 let idx = subs.insert_non_substitution(Substitutable::Prefix(prefix));
2162                 PrefixHandle::NonSubstitution(NonSubstitution(idx))
2163             } else {
2164                 let idx = subs.insert(Substitutable::Prefix(prefix));
2165                 PrefixHandle::BackReference(idx)
2166             }
2167         }
2168 
2169         let mut tail = input;
2170         let mut current = None;
2171 
2172         loop {
2173             try_begin_parse!("PrefixHandle iteration", ctx, tail);
2174 
2175             match tail.peek() {
2176                 Some(b'E') | None => {
2177                     if let Some(handle) = current {
2178                         return Ok((handle, tail));
2179                     } else {
2180                         return Err(error::Error::UnexpectedEnd);
2181                     }
2182                 }
2183                 Some(b'S') => {
2184                     // <prefix> ::= <substitution>
2185                     let (sub, tail_tail) = Substitution::parse(ctx, subs, tail)?;
2186                     current = Some(match sub {
2187                         Substitution::WellKnown(component) => PrefixHandle::WellKnown(component),
2188                         Substitution::BackReference(idx) => {
2189                             // TODO: do we need to check that the idx actually points to
2190                             // a Prefix?
2191                             PrefixHandle::BackReference(idx)
2192                         }
2193                     });
2194                     tail = tail_tail;
2195                 }
2196                 Some(b'T') => {
2197                     // <prefix> ::= <template-param>
2198                     let (param, tail_tail) = TemplateParam::parse(ctx, subs, tail)?;
2199                     current = Some(save(subs, Prefix::TemplateParam(param), tail_tail));
2200                     tail = tail_tail;
2201                 }
2202                 Some(b'D') => {
2203                     // Either
2204                     //
2205                     //     <prefix> ::= <decltype>
2206                     //
2207                     // or
2208                     //
2209                     //     <prefix> ::= <unqualified-name> ::= <ctor-dtor-name>
2210                     if let Ok((decltype, tail_tail)) = Decltype::parse(ctx, subs, tail) {
2211                         current = Some(save(subs, Prefix::Decltype(decltype), tail_tail));
2212                         tail = tail_tail;
2213                     } else {
2214                         let (name, tail_tail) = UnqualifiedName::parse(ctx, subs, tail)?;
2215                         let prefix = match current {
2216                             None => Prefix::Unqualified(name),
2217                             Some(handle) => Prefix::Nested(handle, name),
2218                         };
2219                         current = Some(save(subs, prefix, tail_tail));
2220                         tail = tail_tail;
2221                     }
2222                 }
2223                 Some(b'I')
2224                     if current.is_some() && current.as_ref().unwrap().is_template_prefix() =>
2225                 {
2226                     // <prefix> ::= <template-prefix> <template-args>
2227                     let (args, tail_tail) = TemplateArgs::parse(ctx, subs, tail)?;
2228                     let prefix = Prefix::Template(current.unwrap(), args);
2229                     current = Some(save(subs, prefix, tail_tail));
2230                     tail = tail_tail;
2231                 }
2232                 Some(c) if current.is_some() && SourceName::starts_with(c) => {
2233                     // Either
2234                     //
2235                     //     <prefix> ::= <unqualified-name> ::= <source-name>
2236                     //
2237                     // or
2238                     //
2239                     //     <prefix> ::= <data-member-prefix> ::= <prefix> <source-name> M
2240                     debug_assert!(SourceName::starts_with(c));
2241                     debug_assert!(DataMemberPrefix::starts_with(c));
2242 
2243                     let (name, tail_tail) = SourceName::parse(ctx, subs, tail)?;
2244                     if tail_tail.peek() == Some(b'M') {
2245                         let prefix = Prefix::DataMember(current.unwrap(), DataMemberPrefix(name));
2246                         current = Some(save(subs, prefix, tail_tail));
2247                         tail = consume(b"M", tail_tail).unwrap();
2248                     } else {
2249                         let name = UnqualifiedName::Source(name);
2250                         let prefix = match current {
2251                             None => Prefix::Unqualified(name),
2252                             Some(handle) => Prefix::Nested(handle, name),
2253                         };
2254                         current = Some(save(subs, prefix, tail_tail));
2255                         tail = tail_tail;
2256                     }
2257                 }
2258                 Some(c) if UnqualifiedName::starts_with(c, &tail) => {
2259                     // <prefix> ::= <unqualified-name>
2260                     let (name, tail_tail) = UnqualifiedName::parse(ctx, subs, tail)?;
2261                     let prefix = match current {
2262                         None => Prefix::Unqualified(name),
2263                         Some(handle) => Prefix::Nested(handle, name),
2264                     };
2265                     current = Some(save(subs, prefix, tail_tail));
2266                     tail = tail_tail;
2267                 }
2268                 Some(_) => {
2269                     if let Some(handle) = current {
2270                         return Ok((handle, tail));
2271                     } else if tail.is_empty() {
2272                         return Err(error::Error::UnexpectedEnd);
2273                     } else {
2274                         return Err(error::Error::UnexpectedText);
2275                     }
2276                 }
2277             }
2278         }
2279     }
2280 }
2281 
2282 impl<'a> GetLeafName<'a> for Prefix {
get_leaf_name(&'a self, subs: &'a SubstitutionTable) -> Option<LeafName<'a>>2283     fn get_leaf_name(&'a self, subs: &'a SubstitutionTable) -> Option<LeafName<'a>> {
2284         match *self {
2285             Prefix::Nested(ref prefix, ref name) => name
2286                 .get_leaf_name(subs)
2287                 .or_else(|| prefix.get_leaf_name(subs)),
2288             Prefix::Unqualified(ref name) => name.get_leaf_name(subs),
2289             Prefix::Template(ref prefix, _) => prefix.get_leaf_name(subs),
2290             Prefix::DataMember(_, ref name) => name.get_leaf_name(subs),
2291             Prefix::TemplateParam(_) | Prefix::Decltype(_) => None,
2292         }
2293     }
2294 }
2295 
2296 impl GetTemplateArgs for PrefixHandle {
2297     // XXX: Not an impl GetTemplateArgs for PrefixHandle because the 'me
2298     // reference to self may not live long enough.
get_template_args<'a>(&'a self, subs: &'a SubstitutionTable) -> Option<&'a TemplateArgs>2299     fn get_template_args<'a>(&'a self, subs: &'a SubstitutionTable) -> Option<&'a TemplateArgs> {
2300         match *self {
2301             PrefixHandle::BackReference(idx) => {
2302                 if let Some(&Substitutable::Prefix(ref p)) = subs.get(idx) {
2303                     p.get_template_args(subs)
2304                 } else {
2305                     None
2306                 }
2307             }
2308             PrefixHandle::NonSubstitution(NonSubstitution(idx)) => {
2309                 if let Some(&Substitutable::Prefix(ref p)) = subs.get_non_substitution(idx) {
2310                     p.get_template_args(subs)
2311                 } else {
2312                     None
2313                 }
2314             }
2315             _ => None,
2316         }
2317     }
2318 }
2319 
2320 impl<'subs, W> Demangle<'subs, W> for Prefix
2321 where
2322     W: 'subs + DemangleWrite,
2323 {
demangle<'prev, 'ctx>( &'subs self, ctx: &'ctx mut DemangleContext<'subs, W>, scope: Option<ArgScopeStack<'prev, 'subs>>, ) -> fmt::Result2324     fn demangle<'prev, 'ctx>(
2325         &'subs self,
2326         ctx: &'ctx mut DemangleContext<'subs, W>,
2327         scope: Option<ArgScopeStack<'prev, 'subs>>,
2328     ) -> fmt::Result {
2329         let ctx = try_begin_demangle!(self, ctx, scope);
2330         if ctx.is_template_prefix {
2331             ctx.push_demangle_node(DemangleNodeType::TemplatePrefix);
2332             ctx.is_template_prefix = false;
2333         } else if ctx.is_template_prefix_in_nested_name {
2334             ctx.push_demangle_node(DemangleNodeType::NestedName);
2335             ctx.is_template_prefix_in_nested_name = false;
2336         } else {
2337             ctx.push_demangle_node(DemangleNodeType::Prefix);
2338         }
2339 
2340         let ret = match *self {
2341             Prefix::Unqualified(ref unqualified) => unqualified.demangle(ctx, scope),
2342             Prefix::Nested(ref prefix, ref unqualified) => {
2343                 prefix.demangle(ctx, scope)?;
2344                 if unqualified.accepts_double_colon() {
2345                     write!(ctx, "::")?;
2346                 }
2347                 unqualified.demangle(ctx, scope)
2348             }
2349             Prefix::Template(ref prefix, ref args) => {
2350                 ctx.is_template_prefix = true;
2351                 prefix.demangle(ctx, scope)?;
2352                 ctx.is_template_prefix = false;
2353                 args.demangle(ctx, scope)
2354             }
2355             Prefix::TemplateParam(ref param) => param.demangle(ctx, scope),
2356             Prefix::Decltype(ref dt) => dt.demangle(ctx, scope),
2357             Prefix::DataMember(ref prefix, ref member) => {
2358                 prefix.demangle(ctx, scope)?;
2359                 write!(ctx, "::")?;
2360                 member.demangle(ctx, scope)
2361             }
2362         };
2363         ctx.pop_demangle_node();
2364         ret
2365     }
2366 }
2367 
2368 impl IsCtorDtorConversion for Prefix {
is_ctor_dtor_conversion(&self, subs: &SubstitutionTable) -> bool2369     fn is_ctor_dtor_conversion(&self, subs: &SubstitutionTable) -> bool {
2370         match *self {
2371             Prefix::Unqualified(ref unqualified) | Prefix::Nested(_, ref unqualified) => {
2372                 unqualified.is_ctor_dtor_conversion(subs)
2373             }
2374             Prefix::Template(ref prefix, _) => prefix.is_ctor_dtor_conversion(subs),
2375             _ => false,
2376         }
2377     }
2378 }
2379 
2380 impl IsCtorDtorConversion for PrefixHandle {
is_ctor_dtor_conversion(&self, subs: &SubstitutionTable) -> bool2381     fn is_ctor_dtor_conversion(&self, subs: &SubstitutionTable) -> bool {
2382         match *self {
2383             PrefixHandle::BackReference(idx) => {
2384                 if let Some(sub) = subs.get(idx) {
2385                     sub.is_ctor_dtor_conversion(subs)
2386                 } else {
2387                     false
2388                 }
2389             }
2390             PrefixHandle::NonSubstitution(NonSubstitution(idx)) => {
2391                 if let Some(sub) = subs.get_non_substitution(idx) {
2392                     sub.is_ctor_dtor_conversion(subs)
2393                 } else {
2394                     false
2395                 }
2396             }
2397             PrefixHandle::WellKnown(_) => false,
2398         }
2399     }
2400 }
2401 
2402 impl PrefixHandle {
2403     // Is this <prefix> also a valid <template-prefix> production? Not to be
2404     // confused with the `GetTemplateArgs` trait.
is_template_prefix(&self) -> bool2405     fn is_template_prefix(&self) -> bool {
2406         match *self {
2407             PrefixHandle::BackReference(_) | PrefixHandle::WellKnown(_) => true,
2408             PrefixHandle::NonSubstitution(_) => false,
2409         }
2410     }
2411 }
2412 
2413 /// The `<unqualified-name>` production.
2414 ///
2415 /// ```text
2416 /// <unqualified-name> ::= <operator-name>
2417 ///                    ::= <ctor-dtor-name>
2418 ///                    ::= <source-name>
2419 ///                    ::= <local-source-name>
2420 ///                    ::= <unnamed-type-name>
2421 ///                    ::= <abi-tag>
2422 ///                    ::= <closure-type-name>
2423 ///
2424 /// # I think this is from an older version of the standard. It isn't in the
2425 /// # current version, but all the other demanglers support it, so we will too.
2426 /// <local-source-name> ::= L <source-name> [<discriminator>]
2427 /// ```
2428 #[derive(Clone, Debug, PartialEq, Eq)]
2429 pub enum UnqualifiedName {
2430     /// An operator name.
2431     Operator(OperatorName),
2432     /// A constructor or destructor name.
2433     CtorDtor(CtorDtorName),
2434     /// A source name.
2435     Source(SourceName),
2436     /// A local source name.
2437     LocalSourceName(SourceName, Option<Discriminator>),
2438     /// A generated name for an unnamed type.
2439     UnnamedType(UnnamedTypeName),
2440     /// An ABI tag.
2441     ABITag(TaggedName),
2442     /// A closure type name
2443     ClosureType(ClosureTypeName),
2444 }
2445 
2446 impl Parse for UnqualifiedName {
parse<'a, 'b>( ctx: &'a ParseContext, subs: &'a mut SubstitutionTable, input: IndexStr<'b>, ) -> Result<(UnqualifiedName, IndexStr<'b>)>2447     fn parse<'a, 'b>(
2448         ctx: &'a ParseContext,
2449         subs: &'a mut SubstitutionTable,
2450         input: IndexStr<'b>,
2451     ) -> Result<(UnqualifiedName, IndexStr<'b>)> {
2452         try_begin_parse!("UnqualifiedName", ctx, input);
2453 
2454         if let Ok((op, tail)) = OperatorName::parse(ctx, subs, input) {
2455             return Ok((UnqualifiedName::Operator(op), tail));
2456         }
2457 
2458         if let Ok((ctor_dtor, tail)) = CtorDtorName::parse(ctx, subs, input) {
2459             return Ok((UnqualifiedName::CtorDtor(ctor_dtor), tail));
2460         }
2461 
2462         if let Ok(tail) = consume(b"L", input) {
2463             let (name, tail) = SourceName::parse(ctx, subs, tail)?;
2464             let (discr, tail) = if let Ok((d, t)) = Discriminator::parse(ctx, subs, tail) {
2465                 (Some(d), t)
2466             } else {
2467                 (None, tail)
2468             };
2469             return Ok((UnqualifiedName::LocalSourceName(name, discr), tail));
2470         }
2471 
2472         if let Ok((source, tail)) = SourceName::parse(ctx, subs, input) {
2473             return Ok((UnqualifiedName::Source(source), tail));
2474         }
2475 
2476         if let Ok((tagged, tail)) = TaggedName::parse(ctx, subs, input) {
2477             return Ok((UnqualifiedName::ABITag(tagged), tail));
2478         }
2479 
2480         if let Ok((closure, tail)) = ClosureTypeName::parse(ctx, subs, input) {
2481             return Ok((UnqualifiedName::ClosureType(closure), tail));
2482         }
2483 
2484         UnnamedTypeName::parse(ctx, subs, input)
2485             .map(|(unnamed, tail)| (UnqualifiedName::UnnamedType(unnamed), tail))
2486     }
2487 }
2488 
2489 impl<'subs, W> Demangle<'subs, W> for UnqualifiedName
2490 where
2491     W: 'subs + DemangleWrite,
2492 {
demangle<'prev, 'ctx>( &'subs self, ctx: &'ctx mut DemangleContext<'subs, W>, scope: Option<ArgScopeStack<'prev, 'subs>>, ) -> fmt::Result2493     fn demangle<'prev, 'ctx>(
2494         &'subs self,
2495         ctx: &'ctx mut DemangleContext<'subs, W>,
2496         scope: Option<ArgScopeStack<'prev, 'subs>>,
2497     ) -> fmt::Result {
2498         let ctx = try_begin_demangle!(self, ctx, scope);
2499 
2500         ctx.push_demangle_node(DemangleNodeType::UnqualifiedName);
2501         let ret = match *self {
2502             UnqualifiedName::Operator(ref op_name) => {
2503                 write!(ctx, "operator")?;
2504                 op_name.demangle(ctx, scope)
2505             }
2506             UnqualifiedName::CtorDtor(ref ctor_dtor) => ctor_dtor.demangle(ctx, scope),
2507             UnqualifiedName::Source(ref name) | UnqualifiedName::LocalSourceName(ref name, ..) => {
2508                 name.demangle(ctx, scope)
2509             }
2510             UnqualifiedName::UnnamedType(ref unnamed) => unnamed.demangle(ctx, scope),
2511             UnqualifiedName::ABITag(ref tagged) => tagged.demangle(ctx, scope),
2512             UnqualifiedName::ClosureType(ref closure) => closure.demangle(ctx, scope),
2513         };
2514         ctx.pop_demangle_node();
2515         ret
2516     }
2517 }
2518 
2519 impl<'a> GetLeafName<'a> for UnqualifiedName {
get_leaf_name(&'a self, subs: &'a SubstitutionTable) -> Option<LeafName<'a>>2520     fn get_leaf_name(&'a self, subs: &'a SubstitutionTable) -> Option<LeafName<'a>> {
2521         match *self {
2522             UnqualifiedName::ABITag(_)
2523             | UnqualifiedName::Operator(_)
2524             | UnqualifiedName::CtorDtor(_) => None,
2525             UnqualifiedName::UnnamedType(ref name) => Some(LeafName::UnnamedType(name)),
2526             UnqualifiedName::ClosureType(ref closure) => closure.get_leaf_name(subs),
2527             UnqualifiedName::Source(ref name) | UnqualifiedName::LocalSourceName(ref name, _) => {
2528                 Some(LeafName::SourceName(name))
2529             }
2530         }
2531     }
2532 }
2533 
2534 impl IsCtorDtorConversion for UnqualifiedName {
is_ctor_dtor_conversion(&self, _: &SubstitutionTable) -> bool2535     fn is_ctor_dtor_conversion(&self, _: &SubstitutionTable) -> bool {
2536         match *self {
2537             UnqualifiedName::CtorDtor(_)
2538             | UnqualifiedName::Operator(OperatorName::Conversion(_)) => true,
2539             UnqualifiedName::Operator(_)
2540             | UnqualifiedName::Source(_)
2541             | UnqualifiedName::LocalSourceName(..)
2542             | UnqualifiedName::UnnamedType(_)
2543             | UnqualifiedName::ClosureType(_)
2544             | UnqualifiedName::ABITag(_) => false,
2545         }
2546     }
2547 }
2548 
2549 impl UnqualifiedName {
2550     #[inline]
starts_with(byte: u8, input: &IndexStr) -> bool2551     fn starts_with(byte: u8, input: &IndexStr) -> bool {
2552         byte == b'L'
2553             || OperatorName::starts_with(byte)
2554             || CtorDtorName::starts_with(byte)
2555             || SourceName::starts_with(byte)
2556             || UnnamedTypeName::starts_with(byte)
2557             || TaggedName::starts_with(byte)
2558             || ClosureTypeName::starts_with(byte, input)
2559     }
2560 
accepts_double_colon(&self) -> bool2561     fn accepts_double_colon(&self) -> bool {
2562         match *self {
2563             UnqualifiedName::Operator(_)
2564             | UnqualifiedName::CtorDtor(_)
2565             | UnqualifiedName::Source(_)
2566             | UnqualifiedName::LocalSourceName(..)
2567             | UnqualifiedName::UnnamedType(_)
2568             | UnqualifiedName::ClosureType(_) => true,
2569             UnqualifiedName::ABITag(_) => false,
2570         }
2571     }
2572 }
2573 
2574 /// The `<source-name>` non-terminal.
2575 ///
2576 /// ```text
2577 /// <source-name> ::= <positive length number> <identifier>
2578 /// ```
2579 #[derive(Clone, Debug, PartialEq, Eq)]
2580 pub struct SourceName(Identifier);
2581 
2582 impl Parse for SourceName {
parse<'a, 'b>( ctx: &'a ParseContext, subs: &'a mut SubstitutionTable, input: IndexStr<'b>, ) -> Result<(SourceName, IndexStr<'b>)>2583     fn parse<'a, 'b>(
2584         ctx: &'a ParseContext,
2585         subs: &'a mut SubstitutionTable,
2586         input: IndexStr<'b>,
2587     ) -> Result<(SourceName, IndexStr<'b>)> {
2588         try_begin_parse!("SourceName", ctx, input);
2589 
2590         let (source_name_len, input) = parse_number(10, false, input)?;
2591         debug_assert!(source_name_len >= 0);
2592         if source_name_len == 0 {
2593             return Err(error::Error::UnexpectedText);
2594         }
2595 
2596         let (head, tail) = match input.try_split_at(source_name_len as _) {
2597             Some((head, tail)) => (head, tail),
2598             None => return Err(error::Error::UnexpectedEnd),
2599         };
2600 
2601         let (identifier, empty) = Identifier::parse(ctx, subs, head)?;
2602         if !empty.is_empty() {
2603             return Err(error::Error::UnexpectedText);
2604         }
2605 
2606         let source_name = SourceName(identifier);
2607         Ok((source_name, tail))
2608     }
2609 }
2610 
2611 impl<'subs> ArgScope<'subs, 'subs> for SourceName {
leaf_name(&'subs self) -> Result<LeafName<'subs>>2612     fn leaf_name(&'subs self) -> Result<LeafName<'subs>> {
2613         Ok(LeafName::SourceName(self))
2614     }
2615 
get_template_arg( &'subs self, _: usize, ) -> Result<(&'subs TemplateArg, &'subs TemplateArgs)>2616     fn get_template_arg(
2617         &'subs self,
2618         _: usize,
2619     ) -> Result<(&'subs TemplateArg, &'subs TemplateArgs)> {
2620         Err(error::Error::BadTemplateArgReference)
2621     }
2622 
get_function_arg(&'subs self, _: usize) -> Result<&'subs Type>2623     fn get_function_arg(&'subs self, _: usize) -> Result<&'subs Type> {
2624         Err(error::Error::BadFunctionArgReference)
2625     }
2626 }
2627 
2628 impl SourceName {
2629     #[inline]
starts_with(byte: u8) -> bool2630     fn starts_with(byte: u8) -> bool {
2631         byte == b'0' || (b'0' <= byte && byte <= b'9')
2632     }
2633 }
2634 
2635 impl<'subs, W> Demangle<'subs, W> for SourceName
2636 where
2637     W: 'subs + DemangleWrite,
2638 {
2639     #[inline]
demangle<'prev, 'ctx>( &'subs self, ctx: &'ctx mut DemangleContext<'subs, W>, scope: Option<ArgScopeStack<'prev, 'subs>>, ) -> fmt::Result2640     fn demangle<'prev, 'ctx>(
2641         &'subs self,
2642         ctx: &'ctx mut DemangleContext<'subs, W>,
2643         scope: Option<ArgScopeStack<'prev, 'subs>>,
2644     ) -> fmt::Result {
2645         let ctx = try_begin_demangle!(self, ctx, scope);
2646 
2647         self.0.demangle(ctx, scope)
2648     }
2649 }
2650 
2651 /// The `<tagged-name>` non-terminal.
2652 ///
2653 /// ```text
2654 /// <tagged-name> ::= <name> B <source-name>
2655 /// ```
2656 #[derive(Clone, Debug, PartialEq, Eq)]
2657 pub struct TaggedName(SourceName);
2658 
2659 impl Parse for TaggedName {
parse<'a, 'b>( ctx: &'a ParseContext, subs: &'a mut SubstitutionTable, input: IndexStr<'b>, ) -> Result<(TaggedName, IndexStr<'b>)>2660     fn parse<'a, 'b>(
2661         ctx: &'a ParseContext,
2662         subs: &'a mut SubstitutionTable,
2663         input: IndexStr<'b>,
2664     ) -> Result<(TaggedName, IndexStr<'b>)> {
2665         try_begin_parse!("TaggedName", ctx, input);
2666 
2667         let tail = consume(b"B", input)?;
2668         let (source_name, tail) = SourceName::parse(ctx, subs, tail)?;
2669         Ok((TaggedName(source_name), tail))
2670     }
2671 }
2672 
2673 impl<'subs, W> Demangle<'subs, W> for TaggedName
2674 where
2675     W: 'subs + DemangleWrite,
2676 {
demangle<'prev, 'ctx>( &'subs self, ctx: &'ctx mut DemangleContext<'subs, W>, scope: Option<ArgScopeStack<'prev, 'subs>>, ) -> fmt::Result2677     fn demangle<'prev, 'ctx>(
2678         &'subs self,
2679         ctx: &'ctx mut DemangleContext<'subs, W>,
2680         scope: Option<ArgScopeStack<'prev, 'subs>>,
2681     ) -> fmt::Result {
2682         let ctx = try_begin_demangle!(self, ctx, scope);
2683 
2684         write!(ctx, "[abi:")?;
2685         self.0.demangle(ctx, scope)?;
2686         write!(ctx, "]")
2687     }
2688 }
2689 
2690 impl TaggedName {
2691     #[inline]
starts_with(byte: u8) -> bool2692     fn starts_with(byte: u8) -> bool {
2693         byte == b'B'
2694     }
2695 }
2696 
2697 /// The `<identifier>` pseudo-terminal.
2698 ///
2699 /// ```text
2700 /// <identifier> ::= <unqualified source code identifier>
2701 /// ```
2702 ///
2703 /// > `<identifier>` is a pseudo-terminal representing the characters in the
2704 /// > unqualified identifier for the entity in the source code. This ABI does not
2705 /// > yet specify a mangling for identifiers containing characters outside of
2706 /// > `_A-Za-z0-9.`.
2707 ///
2708 /// Mangled symbols' identifiers also have `$` characters in the wild.
2709 #[derive(Clone, Debug, PartialEq, Eq)]
2710 pub struct Identifier {
2711     start: usize,
2712     end: usize,
2713 }
2714 
2715 impl Parse for Identifier {
parse<'a, 'b>( ctx: &'a ParseContext, _subs: &'a mut SubstitutionTable, input: IndexStr<'b>, ) -> Result<(Identifier, IndexStr<'b>)>2716     fn parse<'a, 'b>(
2717         ctx: &'a ParseContext,
2718         _subs: &'a mut SubstitutionTable,
2719         input: IndexStr<'b>,
2720     ) -> Result<(Identifier, IndexStr<'b>)> {
2721         try_begin_parse!("Identifier", ctx, input);
2722 
2723         if input.is_empty() {
2724             return Err(error::Error::UnexpectedEnd);
2725         }
2726 
2727         let end = input
2728             .as_ref()
2729             .iter()
2730             .map(|&c| c as char)
2731             .take_while(|&c| c == '$' || c == '_' || c == '.' || c.is_digit(36))
2732             .count();
2733 
2734         if end == 0 {
2735             return Err(error::Error::UnexpectedText);
2736         }
2737 
2738         let tail = input.range_from(end..);
2739 
2740         let identifier = Identifier {
2741             start: input.index(),
2742             end: tail.index(),
2743         };
2744 
2745         Ok((identifier, tail))
2746     }
2747 }
2748 
2749 impl<'subs, W> Demangle<'subs, W> for Identifier
2750 where
2751     W: 'subs + DemangleWrite,
2752 {
2753     #[inline]
demangle<'prev, 'ctx>( &'subs self, ctx: &'ctx mut DemangleContext<'subs, W>, scope: Option<ArgScopeStack<'prev, 'subs>>, ) -> fmt::Result2754     fn demangle<'prev, 'ctx>(
2755         &'subs self,
2756         ctx: &'ctx mut DemangleContext<'subs, W>,
2757         scope: Option<ArgScopeStack<'prev, 'subs>>,
2758     ) -> fmt::Result {
2759         let ctx = try_begin_demangle!(self, ctx, scope);
2760 
2761         let ident = &ctx.input[self.start..self.end];
2762 
2763         // Handle GCC's anonymous namespace mangling.
2764         let anon_namespace_prefix = b"_GLOBAL_";
2765         if ident.starts_with(anon_namespace_prefix)
2766             && ident.len() >= anon_namespace_prefix.len() + 2
2767         {
2768             let first = ident[anon_namespace_prefix.len()];
2769             let second = ident[anon_namespace_prefix.len() + 1];
2770 
2771             match (first, second) {
2772                 (b'.', b'N') | (b'_', b'N') | (b'$', b'N') => {
2773                     write!(ctx, "(anonymous namespace)")?;
2774                     return Ok(());
2775                 }
2776                 _ => {
2777                     // Fall through.
2778                 }
2779             }
2780         }
2781 
2782         let source_name = String::from_utf8_lossy(ident);
2783         ctx.set_source_name(self.start, self.end);
2784         write!(ctx, "{}", source_name)?;
2785         Ok(())
2786     }
2787 }
2788 
2789 /// The `<clone-type-identifier>` pseudo-terminal.
2790 ///
2791 /// ```text
2792 /// <clone-type-identifier> ::= <unqualified source code identifier>
2793 /// ```
2794 #[derive(Clone, Debug, PartialEq, Eq)]
2795 pub struct CloneTypeIdentifier {
2796     start: usize,
2797     end: usize,
2798 }
2799 
2800 impl Parse for CloneTypeIdentifier {
parse<'a, 'b>( ctx: &'a ParseContext, _subs: &'a mut SubstitutionTable, input: IndexStr<'b>, ) -> Result<(CloneTypeIdentifier, IndexStr<'b>)>2801     fn parse<'a, 'b>(
2802         ctx: &'a ParseContext,
2803         _subs: &'a mut SubstitutionTable,
2804         input: IndexStr<'b>,
2805     ) -> Result<(CloneTypeIdentifier, IndexStr<'b>)> {
2806         try_begin_parse!("CloneTypeIdentifier", ctx, input);
2807 
2808         if input.is_empty() {
2809             return Err(error::Error::UnexpectedEnd);
2810         }
2811 
2812         let end = input
2813             .as_ref()
2814             .iter()
2815             .map(|&c| c as char)
2816             .take_while(|&c| c == '$' || c == '_' || c.is_digit(36))
2817             .count();
2818 
2819         if end == 0 {
2820             return Err(error::Error::UnexpectedText);
2821         }
2822 
2823         let tail = input.range_from(end..);
2824 
2825         let identifier = CloneTypeIdentifier {
2826             start: input.index(),
2827             end: tail.index(),
2828         };
2829 
2830         Ok((identifier, tail))
2831     }
2832 }
2833 
2834 impl<'subs, W> Demangle<'subs, W> for CloneTypeIdentifier
2835 where
2836     W: 'subs + DemangleWrite,
2837 {
2838     #[inline]
demangle<'prev, 'ctx>( &'subs self, ctx: &'ctx mut DemangleContext<'subs, W>, scope: Option<ArgScopeStack<'prev, 'subs>>, ) -> fmt::Result2839     fn demangle<'prev, 'ctx>(
2840         &'subs self,
2841         ctx: &'ctx mut DemangleContext<'subs, W>,
2842         scope: Option<ArgScopeStack<'prev, 'subs>>,
2843     ) -> fmt::Result {
2844         let ctx = try_begin_demangle!(self, ctx, scope);
2845 
2846         let ident = &ctx.input[self.start..self.end];
2847 
2848         let source_name = String::from_utf8_lossy(ident);
2849         ctx.set_source_name(self.start, self.end);
2850         write!(ctx, " .{}", source_name)?;
2851         Ok(())
2852     }
2853 }
2854 
2855 /// The `<number>` production.
2856 ///
2857 /// ```text
2858 /// <number> ::= [n] <non-negative decimal integer>
2859 /// ```
2860 type Number = isize;
2861 
2862 impl Parse for Number {
parse<'a, 'b>( ctx: &'a ParseContext, _subs: &'a mut SubstitutionTable, input: IndexStr<'b>, ) -> Result<(isize, IndexStr<'b>)>2863     fn parse<'a, 'b>(
2864         ctx: &'a ParseContext,
2865         _subs: &'a mut SubstitutionTable,
2866         input: IndexStr<'b>,
2867     ) -> Result<(isize, IndexStr<'b>)> {
2868         try_begin_parse!("Number", ctx, input);
2869         parse_number(10, true, input)
2870     }
2871 }
2872 
2873 /// A <seq-id> production encoding a base-36 positive number.
2874 ///
2875 /// ```text
2876 /// <seq-id> ::= <0-9A-Z>+
2877 /// ```
2878 #[derive(Clone, Debug, PartialEq, Eq)]
2879 pub struct SeqId(usize);
2880 
2881 impl Parse for SeqId {
parse<'a, 'b>( ctx: &'a ParseContext, _subs: &'a mut SubstitutionTable, input: IndexStr<'b>, ) -> Result<(SeqId, IndexStr<'b>)>2882     fn parse<'a, 'b>(
2883         ctx: &'a ParseContext,
2884         _subs: &'a mut SubstitutionTable,
2885         input: IndexStr<'b>,
2886     ) -> Result<(SeqId, IndexStr<'b>)> {
2887         try_begin_parse!("SeqId", ctx, input);
2888 
2889         parse_number(36, false, input).map(|(num, tail)| (SeqId(num as _), tail))
2890     }
2891 }
2892 
2893 /// The `<operator-name>` production.
2894 ///
2895 /// ```text
2896 /// <operator-name> ::= <simple-operator-name>
2897 ///                 ::= cv <type>               # (cast)
2898 ///                 ::= li <source-name>        # operator ""
2899 ///                 ::= v <digit> <source-name> # vendor extended operator
2900 /// ```
2901 #[derive(Clone, Debug, PartialEq, Eq)]
2902 pub enum OperatorName {
2903     /// A simple operator name.
2904     Simple(SimpleOperatorName),
2905 
2906     /// A type cast.
2907     Cast(TypeHandle),
2908 
2909     /// A type conversion.
2910     Conversion(TypeHandle),
2911 
2912     /// Operator literal, ie `operator ""`.
2913     Literal(SourceName),
2914 
2915     /// A non-standard, vendor extension operator.
2916     VendorExtension(u8, SourceName),
2917 }
2918 
2919 impl OperatorName {
starts_with(byte: u8) -> bool2920     fn starts_with(byte: u8) -> bool {
2921         byte == b'c' || byte == b'l' || byte == b'v' || SimpleOperatorName::starts_with(byte)
2922     }
2923 
arity(&self) -> u82924     fn arity(&self) -> u8 {
2925         match self {
2926             &OperatorName::Cast(_) | &OperatorName::Conversion(_) | &OperatorName::Literal(_) => 1,
2927             &OperatorName::Simple(ref s) => s.arity(),
2928             &OperatorName::VendorExtension(arity, _) => arity,
2929         }
2930     }
2931 
parse_from_expr<'a, 'b>( ctx: &'a ParseContext, subs: &'a mut SubstitutionTable, input: IndexStr<'b>, ) -> Result<(Expression, IndexStr<'b>)>2932     fn parse_from_expr<'a, 'b>(
2933         ctx: &'a ParseContext,
2934         subs: &'a mut SubstitutionTable,
2935         input: IndexStr<'b>,
2936     ) -> Result<(Expression, IndexStr<'b>)> {
2937         let (operator, tail) = OperatorName::parse_internal(ctx, subs, input, true)?;
2938 
2939         let arity = operator.arity();
2940         if arity == 1 {
2941             let (first, tail) = Expression::parse(ctx, subs, tail)?;
2942             let expr = Expression::Unary(operator, Box::new(first));
2943             Ok((expr, tail))
2944         } else if arity == 2 {
2945             let (first, tail) = Expression::parse(ctx, subs, tail)?;
2946             let (second, tail) = Expression::parse(ctx, subs, tail)?;
2947             let expr = Expression::Binary(operator, Box::new(first), Box::new(second));
2948             Ok((expr, tail))
2949         } else if arity == 3 {
2950             let (first, tail) = Expression::parse(ctx, subs, tail)?;
2951             let (second, tail) = Expression::parse(ctx, subs, tail)?;
2952             let (third, tail) = Expression::parse(ctx, subs, tail)?;
2953             let expr =
2954                 Expression::Ternary(operator, Box::new(first), Box::new(second), Box::new(third));
2955             Ok((expr, tail))
2956         } else {
2957             Err(error::Error::UnexpectedText)
2958         }
2959     }
2960 
parse_internal<'a, 'b>( ctx: &'a ParseContext, subs: &'a mut SubstitutionTable, input: IndexStr<'b>, from_expr: bool, ) -> Result<(OperatorName, IndexStr<'b>)>2961     fn parse_internal<'a, 'b>(
2962         ctx: &'a ParseContext,
2963         subs: &'a mut SubstitutionTable,
2964         input: IndexStr<'b>,
2965         from_expr: bool,
2966     ) -> Result<(OperatorName, IndexStr<'b>)> {
2967         try_begin_parse!("OperatorName", ctx, input);
2968 
2969         if let Ok((simple, tail)) = SimpleOperatorName::parse(ctx, subs, input) {
2970             return Ok((OperatorName::Simple(simple), tail));
2971         }
2972 
2973         if let Ok(tail) = consume(b"cv", input) {
2974             // If we came through the expression path, we're a cast. If not,
2975             // we're a conversion.
2976             let previously_in_conversion = ctx.set_in_conversion(!from_expr);
2977             let parse_result = TypeHandle::parse(ctx, subs, tail);
2978             ctx.set_in_conversion(previously_in_conversion);
2979             let (ty, tail) = parse_result?;
2980             if from_expr {
2981                 return Ok((OperatorName::Cast(ty), tail));
2982             } else {
2983                 return Ok((OperatorName::Conversion(ty), tail));
2984             }
2985         }
2986 
2987         if let Ok(tail) = consume(b"li", input) {
2988             let (name, tail) = SourceName::parse(ctx, subs, tail)?;
2989             return Ok((OperatorName::Literal(name), tail));
2990         }
2991 
2992         let tail = consume(b"v", input)?;
2993         let (arity, tail) = match tail.peek() {
2994             Some(c) if b'0' <= c && c <= b'9' => (c - b'0', tail.range_from(1..)),
2995             None => return Err(error::Error::UnexpectedEnd),
2996             _ => return Err(error::Error::UnexpectedText),
2997         };
2998         let (name, tail) = SourceName::parse(ctx, subs, tail)?;
2999         Ok((OperatorName::VendorExtension(arity, name), tail))
3000     }
3001 }
3002 
3003 impl Parse for OperatorName {
parse<'a, 'b>( ctx: &'a ParseContext, subs: &'a mut SubstitutionTable, input: IndexStr<'b>, ) -> Result<(OperatorName, IndexStr<'b>)>3004     fn parse<'a, 'b>(
3005         ctx: &'a ParseContext,
3006         subs: &'a mut SubstitutionTable,
3007         input: IndexStr<'b>,
3008     ) -> Result<(OperatorName, IndexStr<'b>)> {
3009         OperatorName::parse_internal(ctx, subs, input, false)
3010     }
3011 }
3012 
3013 impl<'subs, W> Demangle<'subs, W> for OperatorName
3014 where
3015     W: 'subs + DemangleWrite,
3016 {
demangle<'prev, 'ctx>( &'subs self, ctx: &'ctx mut DemangleContext<'subs, W>, scope: Option<ArgScopeStack<'prev, 'subs>>, ) -> fmt::Result3017     fn demangle<'prev, 'ctx>(
3018         &'subs self,
3019         ctx: &'ctx mut DemangleContext<'subs, W>,
3020         scope: Option<ArgScopeStack<'prev, 'subs>>,
3021     ) -> fmt::Result {
3022         let ctx = try_begin_demangle!(self, ctx, scope);
3023 
3024         match *self {
3025             OperatorName::Simple(ref simple) => {
3026                 match *simple {
3027                     SimpleOperatorName::New
3028                     | SimpleOperatorName::NewArray
3029                     | SimpleOperatorName::Delete
3030                     | SimpleOperatorName::DeleteArray => {
3031                         ctx.ensure_space()?;
3032                     }
3033                     _ => {}
3034                 }
3035                 simple.demangle(ctx, scope)
3036             }
3037             OperatorName::Cast(ref ty) | OperatorName::Conversion(ref ty) => {
3038                 ctx.ensure_space()?;
3039 
3040                 // Cast operators can refer to template arguments before they
3041                 // actually appear in the AST, so we go traverse down the tree
3042                 // and fetch them if they exist.
3043                 let scope = ty
3044                     .get_template_args(ctx.subs)
3045                     .map_or(scope, |args| scope.push(args));
3046 
3047                 ty.demangle(ctx, scope)?;
3048                 Ok(())
3049             }
3050             OperatorName::Literal(ref name) => {
3051                 name.demangle(ctx, scope)?;
3052                 write!(ctx, "::operator \"\"")?;
3053                 Ok(())
3054             }
3055             OperatorName::VendorExtension(arity, ref name) => {
3056                 // TODO: no idea how this should be demangled...
3057                 name.demangle(ctx, scope)?;
3058                 write!(ctx, "::operator {}", arity)?;
3059                 Ok(())
3060             }
3061         }
3062     }
3063 }
3064 
3065 define_vocabulary! {
3066     /// The `<simple-operator-name>` production.
3067     #[derive(Clone, Debug, PartialEq, Eq)]
3068     pub enum SimpleOperatorName {
3069         New              (b"nw",  "new",      3),
3070         NewArray         (b"na",  "new[]",    3),
3071         Delete           (b"dl",  "delete",   1),
3072         DeleteArray      (b"da",  "delete[]", 1),
3073         UnaryPlus        (b"ps",  "+",        1),
3074         Neg              (b"ng",  "-",        1),
3075         AddressOf        (b"ad",  "&",        1),
3076         Deref            (b"de",  "*",        1),
3077         BitNot           (b"co",  "~",        1),
3078         Add              (b"pl",  "+",        2),
3079         Sub              (b"mi",  "-",        2),
3080         Mul              (b"ml",  "*",        2),
3081         Div              (b"dv",  "/",        2),
3082         Rem              (b"rm",  "%",        2),
3083         BitAnd           (b"an",  "&",        2),
3084         BitOr            (b"or",  "|",        2),
3085         BitXor           (b"eo",  "^",        2),
3086         Assign           (b"aS",  "=",        2),
3087         AddAssign        (b"pL",  "+=",       2),
3088         SubAssign        (b"mI",  "-=",       2),
3089         MulAssign        (b"mL",  "*=",       2),
3090         DivAssign        (b"dV",  "/=",       2),
3091         RemAssign        (b"rM",  "%=",       2),
3092         BitAndAssign     (b"aN",  "&=",       2),
3093         BitOrAssign      (b"oR",  "|=",       2),
3094         BitXorAssign     (b"eO",  "^=",       2),
3095         Shl              (b"ls",  "<<",       2),
3096         Shr              (b"rs",  ">>",       2),
3097         ShlAssign        (b"lS",  "<<=",      2),
3098         ShrAssign        (b"rS",  ">>=",      2),
3099         Eq               (b"eq",  "==",       2),
3100         Ne               (b"ne",  "!=",       2),
3101         Less             (b"lt",  "<",        2),
3102         Greater          (b"gt",  ">",        2),
3103         LessEq           (b"le",  "<=",       2),
3104         GreaterEq        (b"ge",  ">=",       2),
3105         Not              (b"nt",  "!",        1),
3106         LogicalAnd       (b"aa",  "&&",       2),
3107         LogicalOr        (b"oo",  "||",       2),
3108         PostInc          (b"pp",  "++",       1), // (postfix in <expression> context)
3109         PostDec          (b"mm",  "--",       1), // (postfix in <expression> context)
3110         Comma            (b"cm",  ",",        2),
3111         DerefMemberPtr   (b"pm",  "->*",      2),
3112         DerefMember      (b"pt",  "->",       2),
3113         Call             (b"cl",  "()",       2),
3114         Index            (b"ix",  "[]",       2),
3115         Question         (b"qu",  "?:",       3),
3116         Spaceship        (b"ss",  "<=>",      2)
3117     }
3118 
3119     impl SimpleOperatorName {
3120         // Automatically implemented by define_vocabulary!
3121         fn arity(&self) -> u8;
3122     }
3123 }
3124 
3125 /// The `<call-offset>` production.
3126 ///
3127 /// ```text
3128 /// <call-offset> ::= h <nv-offset> _
3129 ///               ::= v <v-offset> _
3130 /// ```
3131 #[derive(Clone, Debug, PartialEq, Eq)]
3132 pub enum CallOffset {
3133     /// A non-virtual offset.
3134     NonVirtual(NvOffset),
3135     /// A virtual offset.
3136     Virtual(VOffset),
3137 }
3138 
3139 impl Parse for CallOffset {
parse<'a, 'b>( ctx: &'a ParseContext, subs: &'a mut SubstitutionTable, input: IndexStr<'b>, ) -> Result<(CallOffset, IndexStr<'b>)>3140     fn parse<'a, 'b>(
3141         ctx: &'a ParseContext,
3142         subs: &'a mut SubstitutionTable,
3143         input: IndexStr<'b>,
3144     ) -> Result<(CallOffset, IndexStr<'b>)> {
3145         try_begin_parse!("CallOffset", ctx, input);
3146 
3147         if input.is_empty() {
3148             return Err(error::Error::UnexpectedEnd);
3149         }
3150 
3151         if let Ok(tail) = consume(b"h", input) {
3152             let (offset, tail) = NvOffset::parse(ctx, subs, tail)?;
3153             let tail = consume(b"_", tail)?;
3154             return Ok((CallOffset::NonVirtual(offset), tail));
3155         }
3156 
3157         if let Ok(tail) = consume(b"v", input) {
3158             let (offset, tail) = VOffset::parse(ctx, subs, tail)?;
3159             let tail = consume(b"_", tail)?;
3160             return Ok((CallOffset::Virtual(offset), tail));
3161         }
3162 
3163         Err(error::Error::UnexpectedText)
3164     }
3165 }
3166 
3167 impl<'subs, W> Demangle<'subs, W> for CallOffset
3168 where
3169     W: 'subs + DemangleWrite,
3170 {
demangle<'prev, 'ctx>( &'subs self, ctx: &'ctx mut DemangleContext<'subs, W>, scope: Option<ArgScopeStack<'prev, 'subs>>, ) -> fmt::Result3171     fn demangle<'prev, 'ctx>(
3172         &'subs self,
3173         ctx: &'ctx mut DemangleContext<'subs, W>,
3174         scope: Option<ArgScopeStack<'prev, 'subs>>,
3175     ) -> fmt::Result {
3176         let ctx = try_begin_demangle!(self, ctx, scope);
3177 
3178         match *self {
3179             CallOffset::NonVirtual(NvOffset(offset)) => {
3180                 write!(ctx, "{{offset({})}}", offset)?;
3181             }
3182             CallOffset::Virtual(VOffset(vbase, vcall)) => {
3183                 write!(ctx, "{{virtual offset({}, {})}}", vbase, vcall)?;
3184             }
3185         }
3186         Ok(())
3187     }
3188 }
3189 
3190 /// A non-virtual offset, as described by the <nv-offset> production.
3191 ///
3192 /// ```text
3193 /// <nv-offset> ::= <offset number>
3194 /// ```
3195 #[derive(Clone, Debug, PartialEq, Eq)]
3196 pub struct NvOffset(isize);
3197 
3198 impl Parse for NvOffset {
parse<'a, 'b>( ctx: &'a ParseContext, subs: &'a mut SubstitutionTable, input: IndexStr<'b>, ) -> Result<(NvOffset, IndexStr<'b>)>3199     fn parse<'a, 'b>(
3200         ctx: &'a ParseContext,
3201         subs: &'a mut SubstitutionTable,
3202         input: IndexStr<'b>,
3203     ) -> Result<(NvOffset, IndexStr<'b>)> {
3204         try_begin_parse!("NvOffset", ctx, input);
3205 
3206         Number::parse(ctx, subs, input).map(|(num, tail)| (NvOffset(num), tail))
3207     }
3208 }
3209 
3210 /// A virtual offset, as described by the <v-offset> production.
3211 ///
3212 /// ```text
3213 /// <v-offset> ::= <offset number> _ <virtual offset number>
3214 /// ```
3215 #[derive(Clone, Debug, PartialEq, Eq)]
3216 pub struct VOffset(isize, isize);
3217 
3218 impl Parse for VOffset {
parse<'a, 'b>( ctx: &'a ParseContext, subs: &'a mut SubstitutionTable, input: IndexStr<'b>, ) -> Result<(VOffset, IndexStr<'b>)>3219     fn parse<'a, 'b>(
3220         ctx: &'a ParseContext,
3221         subs: &'a mut SubstitutionTable,
3222         input: IndexStr<'b>,
3223     ) -> Result<(VOffset, IndexStr<'b>)> {
3224         try_begin_parse!("VOffset", ctx, input);
3225 
3226         let (offset, tail) = Number::parse(ctx, subs, input)?;
3227         let tail = consume(b"_", tail)?;
3228         let (virtual_offset, tail) = Number::parse(ctx, subs, tail)?;
3229         Ok((VOffset(offset, virtual_offset), tail))
3230     }
3231 }
3232 
3233 /// The `<ctor-dtor-name>` production.
3234 ///
3235 /// ```text
3236 /// <ctor-dtor-name> ::= C1  # complete object constructor
3237 ///                  ::= C2  # base object constructor
3238 ///                  ::= C3  # complete object allocating constructor
3239 ///                  ::= D0  # deleting destructor
3240 ///                  ::= D1  # complete object destructor
3241 ///                  ::= D2  # base object destructor
3242 /// ```
3243 ///
3244 /// GCC also emits a C4 constructor under some conditions when building
3245 /// an optimized binary. GCC's source says:
3246 ///
3247 /// ```
3248 /// /* This is the old-style "[unified]" constructor.
3249 ///    In some cases, we may emit this function and call
3250 ///    it from the clones in order to share code and save space.  */
3251 /// ```
3252 ///
3253 /// Based on the GCC source we'll call this the "maybe in-charge constructor".
3254 /// Similarly, there is a D4 destructor, the "maybe in-charge destructor".
3255 #[derive(Clone, Debug, PartialEq, Eq)]
3256 pub enum CtorDtorName {
3257     /// "C1", the "complete object constructor"
3258     CompleteConstructor(Option<TypeHandle>),
3259     /// "C2", the "base object constructor"
3260     BaseConstructor(Option<TypeHandle>),
3261     /// "C3", the "complete object allocating constructor"
3262     CompleteAllocatingConstructor(Option<TypeHandle>),
3263     /// "C4", the "maybe in-charge constructor"
3264     MaybeInChargeConstructor(Option<TypeHandle>),
3265     /// "D0", the "deleting destructor"
3266     DeletingDestructor,
3267     /// "D1", the "complete object destructor"
3268     CompleteDestructor,
3269     /// "D2", the "base object destructor"
3270     BaseDestructor,
3271     /// "D4", the "maybe in-charge destructor"
3272     MaybeInChargeDestructor,
3273 }
3274 
3275 impl CtorDtorName {
inheriting_mut(&mut self) -> &mut Option<TypeHandle>3276     fn inheriting_mut(&mut self) -> &mut Option<TypeHandle> {
3277         match self {
3278             CtorDtorName::CompleteConstructor(ref mut inheriting)
3279             | CtorDtorName::BaseConstructor(ref mut inheriting)
3280             | CtorDtorName::CompleteAllocatingConstructor(ref mut inheriting)
3281             | CtorDtorName::MaybeInChargeConstructor(ref mut inheriting) => inheriting,
3282             CtorDtorName::DeletingDestructor
3283             | CtorDtorName::CompleteDestructor
3284             | CtorDtorName::BaseDestructor
3285             | CtorDtorName::MaybeInChargeDestructor => unreachable!(),
3286         }
3287     }
3288 }
3289 
3290 impl Parse for CtorDtorName {
parse<'a, 'b>( ctx: &'a ParseContext, subs: &'a mut SubstitutionTable, input: IndexStr<'b>, ) -> Result<(CtorDtorName, IndexStr<'b>)>3291     fn parse<'a, 'b>(
3292         ctx: &'a ParseContext,
3293         subs: &'a mut SubstitutionTable,
3294         input: IndexStr<'b>,
3295     ) -> Result<(CtorDtorName, IndexStr<'b>)> {
3296         try_begin_parse!(stringify!(CtorDtorName), ctx, input);
3297 
3298         match input.peek() {
3299             Some(b'C') => {
3300                 let mut tail = consume(b"C", input)?;
3301                 let inheriting = match tail.peek() {
3302                     Some(b'I') => {
3303                         tail = consume(b"I", tail)?;
3304                         true
3305                     }
3306                     _ => false,
3307                 };
3308 
3309                 let mut ctor_type: CtorDtorName = match tail
3310                     .try_split_at(1)
3311                     .as_ref()
3312                     .map(|&(ref h, t)| (h.as_ref(), t))
3313                 {
3314                     None => Err(error::Error::UnexpectedEnd),
3315                     Some((b"1", t)) => {
3316                         tail = t;
3317                         Ok(CtorDtorName::CompleteConstructor(None))
3318                     }
3319                     Some((b"2", t)) => {
3320                         tail = t;
3321                         Ok(CtorDtorName::BaseConstructor(None))
3322                     }
3323                     Some((b"3", t)) => {
3324                         tail = t;
3325                         Ok(CtorDtorName::CompleteAllocatingConstructor(None))
3326                     }
3327                     Some((b"4", t)) => {
3328                         tail = t;
3329                         Ok(CtorDtorName::MaybeInChargeConstructor(None))
3330                     }
3331                     _ => Err(error::Error::UnexpectedText),
3332                 }?;
3333 
3334                 if inheriting {
3335                     let (ty, tail) = TypeHandle::parse(ctx, subs, tail)?;
3336                     *ctor_type.inheriting_mut() = Some(ty);
3337                     Ok((ctor_type, tail))
3338                 } else {
3339                     Ok((ctor_type, tail))
3340                 }
3341             }
3342             Some(b'D') => {
3343                 match input
3344                     .try_split_at(2)
3345                     .as_ref()
3346                     .map(|&(ref h, t)| (h.as_ref(), t))
3347                 {
3348                     Some((b"D0", tail)) => Ok((CtorDtorName::DeletingDestructor, tail)),
3349                     Some((b"D1", tail)) => Ok((CtorDtorName::CompleteDestructor, tail)),
3350                     Some((b"D2", tail)) => Ok((CtorDtorName::BaseDestructor, tail)),
3351                     Some((b"D4", tail)) => Ok((CtorDtorName::MaybeInChargeDestructor, tail)),
3352                     _ => Err(error::Error::UnexpectedText),
3353                 }
3354             }
3355             None => Err(error::Error::UnexpectedEnd),
3356             _ => Err(error::Error::UnexpectedText),
3357         }
3358     }
3359 }
3360 
3361 impl<'subs, W> Demangle<'subs, W> for CtorDtorName
3362 where
3363     W: 'subs + DemangleWrite,
3364 {
demangle<'prev, 'ctx>( &'subs self, ctx: &'ctx mut DemangleContext<'subs, W>, scope: Option<ArgScopeStack<'prev, 'subs>>, ) -> fmt::Result3365     fn demangle<'prev, 'ctx>(
3366         &'subs self,
3367         ctx: &'ctx mut DemangleContext<'subs, W>,
3368         scope: Option<ArgScopeStack<'prev, 'subs>>,
3369     ) -> fmt::Result {
3370         let ctx = try_begin_demangle!(self, ctx, scope);
3371 
3372         let leaf = scope.leaf_name().map_err(|e| {
3373             log!("Error getting leaf name: {}", e);
3374             fmt::Error
3375         })?;
3376 
3377         match *self {
3378             CtorDtorName::CompleteConstructor(ref inheriting)
3379             | CtorDtorName::BaseConstructor(ref inheriting)
3380             | CtorDtorName::CompleteAllocatingConstructor(ref inheriting)
3381             | CtorDtorName::MaybeInChargeConstructor(ref inheriting) => match inheriting {
3382                 Some(ty) => ty
3383                     .get_leaf_name(ctx.subs)
3384                     .ok_or_else(|| {
3385                         log!("Error getting leaf name: {:?}", ty);
3386                         fmt::Error
3387                     })?
3388                     .demangle_as_leaf(ctx),
3389                 None => leaf.demangle_as_leaf(ctx),
3390             },
3391             CtorDtorName::DeletingDestructor
3392             | CtorDtorName::CompleteDestructor
3393             | CtorDtorName::BaseDestructor
3394             | CtorDtorName::MaybeInChargeDestructor => {
3395                 write!(ctx, "~")?;
3396                 leaf.demangle_as_leaf(ctx)
3397             }
3398         }
3399     }
3400 }
3401 
3402 impl CtorDtorName {
3403     #[inline]
starts_with(byte: u8) -> bool3404     fn starts_with(byte: u8) -> bool {
3405         byte == b'C' || byte == b'D'
3406     }
3407 }
3408 
3409 /// The `<type>` production.
3410 ///
3411 /// ```text
3412 /// <type> ::= <builtin-type>
3413 ///        ::= <function-type>
3414 ///        ::= <class-enum-type>
3415 ///        ::= <array-type>
3416 ///        ::= <vector-type>
3417 ///        ::= <pointer-to-member-type>
3418 ///        ::= <template-param>
3419 ///        ::= <template-template-param> <template-args>
3420 ///        ::= <decltype>
3421 ///        ::= <CV-qualifiers> <type>
3422 ///        ::= P <type>                                 # pointer-to
3423 ///        ::= R <type>                                 # reference-to
3424 ///        ::= O <type>                                 # rvalue reference-to (C++0x)
3425 ///        ::= C <type>                                 # complex pair (C 2000)
3426 ///        ::= G <type>                                 # imaginary (C 2000)
3427 ///        ::= U <source-name> [<template-args>] <type> # vendor extended type qualifier
3428 ///        ::= Dp <type>                                # pack expansion (C++0x)
3429 ///        ::= <substitution>
3430 /// ```
3431 #[derive(Clone, Debug, PartialEq, Eq)]
3432 #[allow(clippy::large_enum_variant)]
3433 pub enum Type {
3434     /// A function type.
3435     Function(FunctionType),
3436 
3437     /// A class, union, or enum type.
3438     ClassEnum(ClassEnumType),
3439 
3440     /// An array type.
3441     Array(ArrayType),
3442 
3443     /// A vector type.
3444     Vector(VectorType),
3445 
3446     /// A pointer-to-member type.
3447     PointerToMember(PointerToMemberType),
3448 
3449     /// A named template parameter type.
3450     TemplateParam(TemplateParam),
3451 
3452     /// A template template type.
3453     TemplateTemplate(TemplateTemplateParamHandle, TemplateArgs),
3454 
3455     /// A decltype.
3456     Decltype(Decltype),
3457 
3458     /// A const-, restrict-, and/or volatile-qualified type.
3459     Qualified(CvQualifiers, TypeHandle),
3460 
3461     /// A pointer to a type.
3462     PointerTo(TypeHandle),
3463 
3464     /// An lvalue reference to a type.
3465     LvalueRef(TypeHandle),
3466 
3467     /// An rvalue reference to a type.
3468     RvalueRef(TypeHandle),
3469 
3470     /// A complex pair of the given type.
3471     Complex(TypeHandle),
3472 
3473     /// An imaginary of the given type.
3474     Imaginary(TypeHandle),
3475 
3476     /// A vendor extended type qualifier.
3477     VendorExtension(SourceName, Option<TemplateArgs>, TypeHandle),
3478 
3479     /// A pack expansion.
3480     PackExpansion(TypeHandle),
3481 }
3482 
3483 define_handle! {
3484     /// A reference to a parsed `Type` production.
3485     pub enum TypeHandle {
3486         /// A builtin type. These don't end up in the substitutions table.
3487         extra Builtin(BuiltinType),
3488 
3489         /// A CV-qualified builtin type. These don't end up in the table either.
3490         extra QualifiedBuiltin(QualifiedBuiltin),
3491     }
3492 }
3493 
3494 impl TypeHandle {
is_void(&self) -> bool3495     fn is_void(&self) -> bool {
3496         match *self {
3497             TypeHandle::Builtin(BuiltinType::Standard(StandardBuiltinType::Void)) => true,
3498             _ => false,
3499         }
3500     }
3501 }
3502 
3503 impl Parse for TypeHandle {
parse<'a, 'b>( ctx: &'a ParseContext, subs: &'a mut SubstitutionTable, input: IndexStr<'b>, ) -> Result<(TypeHandle, IndexStr<'b>)>3504     fn parse<'a, 'b>(
3505         ctx: &'a ParseContext,
3506         subs: &'a mut SubstitutionTable,
3507         input: IndexStr<'b>,
3508     ) -> Result<(TypeHandle, IndexStr<'b>)> {
3509         try_begin_parse!("TypeHandle", ctx, input);
3510 
3511         /// Insert the given type into the substitution table, and return a
3512         /// handle referencing the index in the table where it ended up.
3513         fn insert_and_return_handle<'a, 'b>(
3514             ty: Type,
3515             subs: &'a mut SubstitutionTable,
3516             tail: IndexStr<'b>,
3517         ) -> Result<(TypeHandle, IndexStr<'b>)> {
3518             let ty = Substitutable::Type(ty);
3519             let idx = subs.insert(ty);
3520             let handle = TypeHandle::BackReference(idx);
3521             Ok((handle, tail))
3522         }
3523 
3524         if let Ok((builtin, tail)) = BuiltinType::parse(ctx, subs, input) {
3525             // Builtin types are one of two exceptions that do not end up in the
3526             // substitutions table.
3527             let handle = TypeHandle::Builtin(builtin);
3528             return Ok((handle, tail));
3529         }
3530 
3531         if let Ok((ty, tail)) = ClassEnumType::parse(ctx, subs, input) {
3532             let ty = Type::ClassEnum(ty);
3533             return insert_and_return_handle(ty, subs, tail);
3534         }
3535 
3536         if let Ok((sub, tail)) = Substitution::parse(ctx, subs, input) {
3537             // If we see an 'I', then this is actually a substitution for a
3538             // <template-template-param>, and the template args are what
3539             // follows. Throw away what we just parsed, and re-parse it in
3540             // `TemplateTemplateParamHandle::parse` for now, but it would be
3541             // nice not to duplicate work we've already done.
3542             if tail.peek() != Some(b'I') {
3543                 match sub {
3544                     Substitution::WellKnown(component) => {
3545                         return Ok((TypeHandle::WellKnown(component), tail));
3546                     }
3547                     Substitution::BackReference(idx) => {
3548                         // TODO: should this check if the back reference actually points
3549                         // to a <type>?
3550                         return Ok((TypeHandle::BackReference(idx), tail));
3551                     }
3552                 }
3553             }
3554         }
3555 
3556         if let Ok((funty, tail)) = FunctionType::parse(ctx, subs, input) {
3557             let ty = Type::Function(funty);
3558             return insert_and_return_handle(ty, subs, tail);
3559         }
3560 
3561         if let Ok((ty, tail)) = ArrayType::parse(ctx, subs, input) {
3562             let ty = Type::Array(ty);
3563             return insert_and_return_handle(ty, subs, tail);
3564         }
3565 
3566         if let Ok((ty, tail)) = VectorType::parse(ctx, subs, input) {
3567             let ty = Type::Vector(ty);
3568             return insert_and_return_handle(ty, subs, tail);
3569         }
3570 
3571         if let Ok((ty, tail)) = PointerToMemberType::parse(ctx, subs, input) {
3572             let ty = Type::PointerToMember(ty);
3573             return insert_and_return_handle(ty, subs, tail);
3574         }
3575 
3576         if let Ok((param, tail)) = TemplateParam::parse(ctx, subs, input) {
3577             // Same situation as with `Substitution::parse` at the top of this
3578             // function: this is actually a <template-template-param> and
3579             // <template-args>.
3580             if tail.peek() != Some(b'I') {
3581                 let ty = Type::TemplateParam(param);
3582                 return insert_and_return_handle(ty, subs, tail);
3583             } else if ctx.in_conversion() {
3584                 // This may be <template-template-param> <template-args>.
3585                 // But if we're here for a conversion operator, that's only
3586                 // possible if the grammar looks like:
3587                 //
3588                 // <nested-name>
3589                 // -> <source-name> cv <template-template-param> <template-args> <template-args>
3590                 //
3591                 // That is, there must be *another* <template-args> production after ours.
3592                 // If there isn't one, then this really is a <template-param>.
3593                 //
3594                 // NB: Parsing a <template-args> production may modify the substitutions
3595                 // table, so we need to avoid contaminating the official copy.
3596                 let mut tmp_subs = subs.clone();
3597                 if let Ok((_, new_tail)) = TemplateArgs::parse(ctx, &mut tmp_subs, tail) {
3598                     if new_tail.peek() != Some(b'I') {
3599                         // Don't consume the TemplateArgs.
3600                         let ty = Type::TemplateParam(param);
3601                         return insert_and_return_handle(ty, subs, tail);
3602                     }
3603                     // We really do have a <template-template-param>. Fall through.
3604                     // NB: We can't use the arguments we just parsed because a
3605                     // TemplateTemplateParam is substitutable, and if we use it
3606                     // any substitutions in the arguments will come *before* it,
3607                     // putting the substitution table out of order.
3608                 }
3609             }
3610         }
3611 
3612         if let Ok((ttp, tail)) = TemplateTemplateParamHandle::parse(ctx, subs, input) {
3613             let (args, tail) = TemplateArgs::parse(ctx, subs, tail)?;
3614             let ty = Type::TemplateTemplate(ttp, args);
3615             return insert_and_return_handle(ty, subs, tail);
3616         }
3617 
3618         if let Ok((param, tail)) = Decltype::parse(ctx, subs, input) {
3619             let ty = Type::Decltype(param);
3620             return insert_and_return_handle(ty, subs, tail);
3621         }
3622 
3623         if let Ok((qualifiers, tail)) = CvQualifiers::parse(ctx, subs, input) {
3624             // CvQualifiers can parse successfully without consuming any input,
3625             // but we don't want to recurse unless we know we did consume some
3626             // input, lest we go into an infinite loop and blow the stack.
3627             if tail.len() < input.len() {
3628                 let (ty, tail) = TypeHandle::parse(ctx, subs, tail)?;
3629                 let ty = Type::Qualified(qualifiers, ty);
3630                 return insert_and_return_handle(ty, subs, tail);
3631             }
3632         }
3633 
3634         if let Ok(tail) = consume(b"P", input) {
3635             let (ty, tail) = TypeHandle::parse(ctx, subs, tail)?;
3636             let ty = Type::PointerTo(ty);
3637             return insert_and_return_handle(ty, subs, tail);
3638         }
3639 
3640         if let Ok(tail) = consume(b"R", input) {
3641             let (ty, tail) = TypeHandle::parse(ctx, subs, tail)?;
3642             let ty = Type::LvalueRef(ty);
3643             return insert_and_return_handle(ty, subs, tail);
3644         }
3645 
3646         if let Ok(tail) = consume(b"O", input) {
3647             let (ty, tail) = TypeHandle::parse(ctx, subs, tail)?;
3648             let ty = Type::RvalueRef(ty);
3649             return insert_and_return_handle(ty, subs, tail);
3650         }
3651 
3652         if let Ok(tail) = consume(b"C", input) {
3653             let (ty, tail) = TypeHandle::parse(ctx, subs, tail)?;
3654             let ty = Type::Complex(ty);
3655             return insert_and_return_handle(ty, subs, tail);
3656         }
3657 
3658         if let Ok(tail) = consume(b"G", input) {
3659             let (ty, tail) = TypeHandle::parse(ctx, subs, tail)?;
3660             let ty = Type::Imaginary(ty);
3661             return insert_and_return_handle(ty, subs, tail);
3662         }
3663 
3664         if let Ok(tail) = consume(b"U", input) {
3665             let (name, tail) = SourceName::parse(ctx, subs, tail)?;
3666             let (args, tail) = if let Ok((args, tail)) = TemplateArgs::parse(ctx, subs, tail) {
3667                 (Some(args), tail)
3668             } else {
3669                 (None, tail)
3670             };
3671             let (ty, tail) = TypeHandle::parse(ctx, subs, tail)?;
3672             let ty = Type::VendorExtension(name, args, ty);
3673             return insert_and_return_handle(ty, subs, tail);
3674         }
3675 
3676         let tail = consume(b"Dp", input)?;
3677         let (ty, tail) = TypeHandle::parse(ctx, subs, tail)?;
3678         let ty = Type::PackExpansion(ty);
3679         insert_and_return_handle(ty, subs, tail)
3680     }
3681 }
3682 
3683 impl GetTemplateArgs for TypeHandle {
get_template_args<'a>(&'a self, subs: &'a SubstitutionTable) -> Option<&'a TemplateArgs>3684     fn get_template_args<'a>(&'a self, subs: &'a SubstitutionTable) -> Option<&'a TemplateArgs> {
3685         subs.get_type(self)
3686             .and_then(|ty| ty.get_template_args(subs))
3687     }
3688 }
3689 
3690 impl<'subs, W> Demangle<'subs, W> for Type
3691 where
3692     W: 'subs + DemangleWrite,
3693 {
demangle<'prev, 'ctx>( &'subs self, ctx: &'ctx mut DemangleContext<'subs, W>, scope: Option<ArgScopeStack<'prev, 'subs>>, ) -> fmt::Result3694     fn demangle<'prev, 'ctx>(
3695         &'subs self,
3696         ctx: &'ctx mut DemangleContext<'subs, W>,
3697         scope: Option<ArgScopeStack<'prev, 'subs>>,
3698     ) -> fmt::Result {
3699         let ctx = try_begin_demangle!(self, ctx, scope);
3700 
3701         match *self {
3702             Type::Function(ref func_ty) => func_ty.demangle(ctx, scope),
3703             Type::ClassEnum(ref cls_enum_ty) => cls_enum_ty.demangle(ctx, scope),
3704             Type::Array(ref array_ty) => array_ty.demangle(ctx, scope),
3705             Type::Vector(ref vector_ty) => vector_ty.demangle(ctx, scope),
3706             Type::PointerToMember(ref ptm) => ptm.demangle(ctx, scope),
3707             Type::TemplateParam(ref param) => param.demangle(ctx, scope),
3708             Type::TemplateTemplate(ref tt_param, ref args) => {
3709                 tt_param.demangle(ctx, scope)?;
3710                 args.demangle(ctx, scope)
3711             }
3712             Type::Decltype(ref dt) => dt.demangle(ctx, scope),
3713             Type::Qualified(_, ref ty) => {
3714                 ctx.push_inner(self);
3715                 ty.demangle(ctx, scope)?;
3716                 if ctx.pop_inner_if(self) {
3717                     self.demangle_as_inner(ctx, scope)?;
3718                 }
3719                 Ok(())
3720             }
3721             Type::PointerTo(ref ty) | Type::LvalueRef(ref ty) | Type::RvalueRef(ref ty) => {
3722                 ctx.push_inner(self);
3723                 ty.demangle(ctx, scope)?;
3724                 if ctx.pop_inner_if(self) {
3725                     self.demangle_as_inner(ctx, scope)?;
3726                 }
3727                 Ok(())
3728             }
3729             Type::Complex(ref ty) => {
3730                 ty.demangle(ctx, scope)?;
3731                 write!(ctx, " complex")?;
3732                 Ok(())
3733             }
3734             Type::Imaginary(ref ty) => {
3735                 ty.demangle(ctx, scope)?;
3736                 write!(ctx, " imaginary")?;
3737                 Ok(())
3738             }
3739             Type::VendorExtension(ref name, ref template_args, ref ty) => {
3740                 ty.demangle(ctx, scope)?;
3741                 write!(ctx, " ")?;
3742                 name.demangle(ctx, scope)?;
3743                 if let Some(ref args) = *template_args {
3744                     args.demangle(ctx, scope)?;
3745                 }
3746                 Ok(())
3747             }
3748             Type::PackExpansion(ref ty) => {
3749                 ty.demangle(ctx, scope)?;
3750                 if !ctx.is_template_argument_pack {
3751                     write!(ctx, "...")?;
3752                 }
3753                 Ok(())
3754             }
3755         }
3756     }
3757 }
3758 
3759 impl<'subs, W> DemangleAsInner<'subs, W> for Type
3760 where
3761     W: 'subs + DemangleWrite,
3762 {
demangle_as_inner<'prev, 'ctx>( &'subs self, ctx: &'ctx mut DemangleContext<'subs, W>, scope: Option<ArgScopeStack<'prev, 'subs>>, ) -> fmt::Result3763     fn demangle_as_inner<'prev, 'ctx>(
3764         &'subs self,
3765         ctx: &'ctx mut DemangleContext<'subs, W>,
3766         scope: Option<ArgScopeStack<'prev, 'subs>>,
3767     ) -> fmt::Result {
3768         let ctx = try_begin_demangle_as_inner!(self, ctx, scope);
3769 
3770         match *self {
3771             Type::Qualified(ref quals, _) => quals.demangle_as_inner(ctx, scope),
3772             Type::PointerTo(_) => write!(ctx, "*"),
3773             Type::RvalueRef(_) => {
3774                 while let Some(v) = ctx.inner.last().and_then(|ty| ty.downcast_to_type()) {
3775                     match v {
3776                         // Two r-value references combine into a single r-value reference
3777                         // Consume any adjacent r-value references on the inner stack.
3778                         Type::RvalueRef(_) => {
3779                             ctx.inner.pop().unwrap();
3780                         }
3781                         // An r-value and an l-value reference combine into an l-value reference.
3782                         // Skip printing this, and allow the LvalueRef implementation to
3783                         // continue combining references.
3784                         Type::LvalueRef(_) => return Ok(()),
3785                         _ => break,
3786                     }
3787                 }
3788                 write!(ctx, "&&")
3789             }
3790             Type::LvalueRef(_) => {
3791                 while let Some(v) = ctx.inner.last().and_then(|ty| ty.downcast_to_type()) {
3792                     match v {
3793                         // An l-value reference combines with an r-value reference to form a
3794                         // single l-value reference. Consume any adjacent r-value references
3795                         // on the inner stack.
3796                         Type::RvalueRef(_) => {
3797                             ctx.inner.pop().unwrap();
3798                         }
3799                         // Two l-value references combine to form a single l-value reference.
3800                         // Skip printing this, and allow the LvalueRef implementation for
3801                         // the next l-value reference to continue combining references.
3802                         Type::LvalueRef(_) => return Ok(()),
3803                         _ => break,
3804                     }
3805                 }
3806                 write!(ctx, "&")
3807             }
3808             ref otherwise => {
3809                 unreachable!(
3810                     "We shouldn't ever put any other types on the inner stack: {:?}",
3811                     otherwise
3812                 );
3813             }
3814         }
3815     }
3816 
downcast_to_type(&self) -> Option<&Type>3817     fn downcast_to_type(&self) -> Option<&Type> {
3818         Some(self)
3819     }
3820 
downcast_to_function_type(&self) -> Option<&FunctionType>3821     fn downcast_to_function_type(&self) -> Option<&FunctionType> {
3822         if let Type::Function(ref f) = *self {
3823             Some(f)
3824         } else {
3825             None
3826         }
3827     }
3828 
downcast_to_array_type(&self) -> Option<&ArrayType>3829     fn downcast_to_array_type(&self) -> Option<&ArrayType> {
3830         if let Type::Array(ref arr) = *self {
3831             Some(arr)
3832         } else {
3833             None
3834         }
3835     }
3836 
downcast_to_pointer_to_member(&self) -> Option<&PointerToMemberType>3837     fn downcast_to_pointer_to_member(&self) -> Option<&PointerToMemberType> {
3838         if let Type::PointerToMember(ref ptm) = *self {
3839             Some(ptm)
3840         } else {
3841             None
3842         }
3843     }
3844 
is_qualified(&self) -> bool3845     fn is_qualified(&self) -> bool {
3846         match *self {
3847             Type::Qualified(..) => true,
3848             _ => false,
3849         }
3850     }
3851 }
3852 
3853 impl GetTemplateArgs for Type {
get_template_args<'a>(&'a self, subs: &'a SubstitutionTable) -> Option<&'a TemplateArgs>3854     fn get_template_args<'a>(&'a self, subs: &'a SubstitutionTable) -> Option<&'a TemplateArgs> {
3855         // TODO: This should probably recurse through all the nested type
3856         // handles too.
3857 
3858         match *self {
3859             Type::VendorExtension(_, Some(ref args), _) | Type::TemplateTemplate(_, ref args) => {
3860                 Some(args)
3861             }
3862             Type::PointerTo(ref ty) | Type::LvalueRef(ref ty) | Type::RvalueRef(ref ty) => {
3863                 ty.get_template_args(subs)
3864             }
3865             _ => None,
3866         }
3867     }
3868 }
3869 
3870 impl<'a> GetLeafName<'a> for Type {
get_leaf_name(&'a self, subs: &'a SubstitutionTable) -> Option<LeafName<'a>>3871     fn get_leaf_name(&'a self, subs: &'a SubstitutionTable) -> Option<LeafName<'a>> {
3872         match *self {
3873             Type::ClassEnum(ref cls_enum_ty) => cls_enum_ty.get_leaf_name(subs),
3874             _ => None,
3875         }
3876     }
3877 }
3878 
3879 /// The `<CV-qualifiers>` production.
3880 ///
3881 /// ```text
3882 /// <CV-qualifiers> ::= [r] [V] [K]   # restrict (C99), volatile, const
3883 /// ```
3884 #[derive(Clone, Debug, Default, Hash, PartialEq, Eq)]
3885 pub struct CvQualifiers {
3886     /// Is this `restrict` qualified?
3887     pub restrict: bool,
3888     /// Is this `volatile` qualified?
3889     pub volatile: bool,
3890     /// Is this `const` qualified?
3891     pub const_: bool,
3892 }
3893 
3894 impl CvQualifiers {
3895     #[inline]
is_empty(&self) -> bool3896     fn is_empty(&self) -> bool {
3897         !self.restrict && !self.volatile && !self.const_
3898     }
3899 }
3900 
3901 impl Parse for CvQualifiers {
parse<'a, 'b>( ctx: &'a ParseContext, _subs: &'a mut SubstitutionTable, input: IndexStr<'b>, ) -> Result<(CvQualifiers, IndexStr<'b>)>3902     fn parse<'a, 'b>(
3903         ctx: &'a ParseContext,
3904         _subs: &'a mut SubstitutionTable,
3905         input: IndexStr<'b>,
3906     ) -> Result<(CvQualifiers, IndexStr<'b>)> {
3907         try_begin_parse!("CvQualifiers", ctx, input);
3908 
3909         let (restrict, tail) = if let Ok(tail) = consume(b"r", input) {
3910             (true, tail)
3911         } else {
3912             (false, input)
3913         };
3914 
3915         let (volatile, tail) = if let Ok(tail) = consume(b"V", tail) {
3916             (true, tail)
3917         } else {
3918             (false, tail)
3919         };
3920 
3921         let (const_, tail) = if let Ok(tail) = consume(b"K", tail) {
3922             (true, tail)
3923         } else {
3924             (false, tail)
3925         };
3926 
3927         let qualifiers = CvQualifiers {
3928             restrict: restrict,
3929             volatile: volatile,
3930             const_: const_,
3931         };
3932 
3933         Ok((qualifiers, tail))
3934     }
3935 }
3936 
3937 impl<'subs, W> Demangle<'subs, W> for CvQualifiers
3938 where
3939     W: 'subs + DemangleWrite,
3940 {
demangle<'prev, 'ctx>( &'subs self, ctx: &'ctx mut DemangleContext<'subs, W>, scope: Option<ArgScopeStack<'prev, 'subs>>, ) -> fmt::Result3941     fn demangle<'prev, 'ctx>(
3942         &'subs self,
3943         ctx: &'ctx mut DemangleContext<'subs, W>,
3944         scope: Option<ArgScopeStack<'prev, 'subs>>,
3945     ) -> fmt::Result {
3946         let ctx = try_begin_demangle!(self, ctx, scope);
3947 
3948         if self.const_ {
3949             ctx.ensure_space()?;
3950             write!(ctx, "const")?;
3951         }
3952 
3953         if self.volatile {
3954             ctx.ensure_space()?;
3955             write!(ctx, "volatile")?;
3956         }
3957 
3958         if self.restrict {
3959             ctx.ensure_space()?;
3960             write!(ctx, "restrict")?;
3961         }
3962 
3963         Ok(())
3964     }
3965 }
3966 
3967 impl<'subs, W> DemangleAsInner<'subs, W> for CvQualifiers where W: 'subs + DemangleWrite {}
3968 
3969 define_vocabulary! {
3970     /// A <ref-qualifier> production.
3971     ///
3972     /// ```text
3973     /// <ref-qualifier> ::= R   # & ref-qualifier
3974     ///                 ::= O   # && ref-qualifier
3975     /// ```
3976     #[derive(Clone, Debug, PartialEq, Eq)]
3977     pub enum RefQualifier {
3978         LValueRef(b"R", "&"),
3979         RValueRef(b"O", "&&")
3980     }
3981 }
3982 
3983 define_vocabulary! {
3984     /// A one of the standard variants of the <builtin-type> production.
3985     ///
3986     /// ```text
3987     /// <builtin-type> ::= v  # void
3988     ///                ::= w  # wchar_t
3989     ///                ::= b  # bool
3990     ///                ::= c  # char
3991     ///                ::= a  # signed char
3992     ///                ::= h  # unsigned char
3993     ///                ::= s  # short
3994     ///                ::= t  # unsigned short
3995     ///                ::= i  # int
3996     ///                ::= j  # unsigned int
3997     ///                ::= l  # long
3998     ///                ::= m  # unsigned long
3999     ///                ::= x  # long long, __int64
4000     ///                ::= y  # unsigned long long, __int64
4001     ///                ::= n  # __int128
4002     ///                ::= o  # unsigned __int128
4003     ///                ::= f  # float
4004     ///                ::= d  # double
4005     ///                ::= e  # long double, __float80
4006     ///                ::= g  # __float128
4007     ///                ::= z  # ellipsis
4008     ///                ::= Dd # IEEE 754r decimal floating point (64 bits)
4009     ///                ::= De # IEEE 754r decimal floating point (128 bits)
4010     ///                ::= Df # IEEE 754r decimal floating point (32 bits)
4011     ///                ::= Dh # IEEE 754r half-precision floating point (16 bits)
4012     ///                ::= Di # char32_t
4013     ///                ::= Ds # char16_t
4014     ///                ::= Da # auto
4015     ///                ::= Dc # decltype(auto)
4016     ///                ::= Dn # std::nullptr_t (i.e., decltype(nullptr))
4017     /// ```
4018     #[derive(Clone, Debug, PartialEq, Eq)]
4019     pub enum StandardBuiltinType {
4020         Void             (b"v",  "void"),
4021         Wchar            (b"w",  "wchar_t"),
4022         Bool             (b"b",  "bool"),
4023         Char             (b"c",  "char"),
4024         SignedChar       (b"a",  "signed char"),
4025         UnsignedChar     (b"h",  "unsigned char"),
4026         Short            (b"s",  "short"),
4027         UnsignedShort    (b"t",  "unsigned short"),
4028         Int              (b"i",  "int"),
4029         UnsignedInt      (b"j",  "unsigned int"),
4030         Long             (b"l",  "long"),
4031         UnsignedLong     (b"m",  "unsigned long"),
4032         LongLong         (b"x",  "long long"),
4033         UnsignedLongLong (b"y",  "unsigned long long"),
4034         Int128           (b"n",  "__int128"),
4035         Uint128          (b"o",  "unsigned __int128"),
4036         Float            (b"f",  "float"),
4037         Double           (b"d",  "double"),
4038         LongDouble       (b"e",  "long double"),
4039         Float128         (b"g",  "__float128"),
4040         Ellipsis         (b"z",  "..."),
4041         DecimalFloat64   (b"Dd", "decimal64"),
4042         DecimalFloat128  (b"De", "decimal128"),
4043         DecimalFloat32   (b"Df", "decimal32"),
4044         DecimalFloat16   (b"Dh", "half"),
4045         Char32           (b"Di", "char32_t"),
4046         Char16           (b"Ds", "char16_t"),
4047         Auto             (b"Da", "auto"),
4048         Decltype         (b"Dc", "decltype(auto)"),
4049         Nullptr          (b"Dn", "std::nullptr_t")
4050     }
4051 }
4052 
4053 /// The `<builtin-type>` production.
4054 #[derive(Clone, Debug, PartialEq, Eq)]
4055 pub enum BuiltinType {
4056     /// A standards compliant builtin type.
4057     Standard(StandardBuiltinType),
4058 
4059     /// A non-standard, vendor extension type.
4060     ///
4061     /// ```text
4062     /// <builtin-type> ::= u <source-name>   # vendor extended type
4063     /// ```
4064     Extension(SourceName),
4065 }
4066 
4067 impl Parse for BuiltinType {
parse<'a, 'b>( ctx: &'a ParseContext, subs: &'a mut SubstitutionTable, input: IndexStr<'b>, ) -> Result<(BuiltinType, IndexStr<'b>)>4068     fn parse<'a, 'b>(
4069         ctx: &'a ParseContext,
4070         subs: &'a mut SubstitutionTable,
4071         input: IndexStr<'b>,
4072     ) -> Result<(BuiltinType, IndexStr<'b>)> {
4073         try_begin_parse!("BuiltinType", ctx, input);
4074 
4075         if let Ok((ty, tail)) = StandardBuiltinType::parse(ctx, subs, input) {
4076             return Ok((BuiltinType::Standard(ty), tail));
4077         }
4078 
4079         let tail = consume(b"u", input)?;
4080         let (name, tail) = SourceName::parse(ctx, subs, tail)?;
4081         Ok((BuiltinType::Extension(name), tail))
4082     }
4083 }
4084 
4085 impl<'subs, W> Demangle<'subs, W> for BuiltinType
4086 where
4087     W: 'subs + DemangleWrite,
4088 {
demangle<'prev, 'ctx>( &'subs self, ctx: &'ctx mut DemangleContext<'subs, W>, scope: Option<ArgScopeStack<'prev, 'subs>>, ) -> fmt::Result4089     fn demangle<'prev, 'ctx>(
4090         &'subs self,
4091         ctx: &'ctx mut DemangleContext<'subs, W>,
4092         scope: Option<ArgScopeStack<'prev, 'subs>>,
4093     ) -> fmt::Result {
4094         let ctx = try_begin_demangle!(self, ctx, scope);
4095 
4096         match *self {
4097             BuiltinType::Standard(ref ty) => ty.demangle(ctx, scope),
4098             BuiltinType::Extension(ref name) => name.demangle(ctx, scope),
4099         }
4100     }
4101 }
4102 
4103 impl<'a> GetLeafName<'a> for BuiltinType {
get_leaf_name(&'a self, _: &'a SubstitutionTable) -> Option<LeafName<'a>>4104     fn get_leaf_name(&'a self, _: &'a SubstitutionTable) -> Option<LeafName<'a>> {
4105         None
4106     }
4107 }
4108 
4109 /// A built-in type with CV-qualifiers.
4110 ///
4111 /// Like unqualified built-in types, CV-qualified built-in types do not go into
4112 /// the substitutions table.
4113 #[derive(Clone, Debug, PartialEq, Eq)]
4114 pub struct QualifiedBuiltin(CvQualifiers, BuiltinType);
4115 
4116 impl<'subs, W> Demangle<'subs, W> for QualifiedBuiltin
4117 where
4118     W: 'subs + DemangleWrite,
4119 {
demangle<'prev, 'ctx>( &'subs self, ctx: &'ctx mut DemangleContext<'subs, W>, scope: Option<ArgScopeStack<'prev, 'subs>>, ) -> fmt::Result4120     fn demangle<'prev, 'ctx>(
4121         &'subs self,
4122         ctx: &'ctx mut DemangleContext<'subs, W>,
4123         scope: Option<ArgScopeStack<'prev, 'subs>>,
4124     ) -> fmt::Result {
4125         let ctx = try_begin_demangle!(self, ctx, scope);
4126 
4127         ctx.push_inner(&self.0);
4128         self.1.demangle(ctx, scope)?;
4129         if ctx.pop_inner_if(&self.0) {
4130             self.0.demangle_as_inner(ctx, scope)?;
4131         }
4132         Ok(())
4133     }
4134 }
4135 
4136 impl<'a> GetLeafName<'a> for QualifiedBuiltin {
get_leaf_name(&'a self, _: &'a SubstitutionTable) -> Option<LeafName<'a>>4137     fn get_leaf_name(&'a self, _: &'a SubstitutionTable) -> Option<LeafName<'a>> {
4138         None
4139     }
4140 }
4141 
4142 /// The `<function-type>` production.
4143 ///
4144 /// ```text
4145 /// <function-type> ::= [<CV-qualifiers>] [Dx] F [Y] <bare-function-type> [<ref-qualifier>] E
4146 /// ```
4147 #[derive(Clone, Debug, PartialEq, Eq)]
4148 pub struct FunctionType {
4149     cv_qualifiers: CvQualifiers,
4150     transaction_safe: bool,
4151     extern_c: bool,
4152     bare: BareFunctionType,
4153     ref_qualifier: Option<RefQualifier>,
4154 }
4155 
4156 impl Parse for FunctionType {
parse<'a, 'b>( ctx: &'a ParseContext, subs: &'a mut SubstitutionTable, input: IndexStr<'b>, ) -> Result<(FunctionType, IndexStr<'b>)>4157     fn parse<'a, 'b>(
4158         ctx: &'a ParseContext,
4159         subs: &'a mut SubstitutionTable,
4160         input: IndexStr<'b>,
4161     ) -> Result<(FunctionType, IndexStr<'b>)> {
4162         try_begin_parse!("FunctionType", ctx, input);
4163 
4164         let (cv_qualifiers, tail) =
4165             if let Ok((cv_qualifiers, tail)) = CvQualifiers::parse(ctx, subs, input) {
4166                 (cv_qualifiers, tail)
4167             } else {
4168                 (Default::default(), input)
4169             };
4170 
4171         let (transaction_safe, tail) = if let Ok(tail) = consume(b"Dx", tail) {
4172             (true, tail)
4173         } else {
4174             (false, tail)
4175         };
4176 
4177         let tail = consume(b"F", tail)?;
4178 
4179         let (extern_c, tail) = if let Ok(tail) = consume(b"Y", tail) {
4180             (true, tail)
4181         } else {
4182             (false, tail)
4183         };
4184 
4185         let (bare, tail) = BareFunctionType::parse(ctx, subs, tail)?;
4186 
4187         let (ref_qualifier, tail) =
4188             if let Ok((ref_qualifier, tail)) = RefQualifier::parse(ctx, subs, tail) {
4189                 (Some(ref_qualifier), tail)
4190             } else {
4191                 (None, tail)
4192             };
4193 
4194         let tail = consume(b"E", tail)?;
4195 
4196         let func_ty = FunctionType {
4197             cv_qualifiers: cv_qualifiers,
4198             transaction_safe: transaction_safe,
4199             extern_c: extern_c,
4200             bare: bare,
4201             ref_qualifier: ref_qualifier,
4202         };
4203         Ok((func_ty, tail))
4204     }
4205 }
4206 
4207 impl<'subs, W> Demangle<'subs, W> for FunctionType
4208 where
4209     W: 'subs + DemangleWrite,
4210 {
demangle<'prev, 'ctx>( &'subs self, ctx: &'ctx mut DemangleContext<'subs, W>, scope: Option<ArgScopeStack<'prev, 'subs>>, ) -> fmt::Result4211     fn demangle<'prev, 'ctx>(
4212         &'subs self,
4213         ctx: &'ctx mut DemangleContext<'subs, W>,
4214         scope: Option<ArgScopeStack<'prev, 'subs>>,
4215     ) -> fmt::Result {
4216         let ctx = try_begin_demangle!(self, ctx, scope);
4217 
4218         ctx.push_inner(self);
4219         self.bare.demangle(ctx, scope)?;
4220         if ctx.pop_inner_if(self) {
4221             self.demangle_as_inner(ctx, scope)?;
4222         }
4223         Ok(())
4224     }
4225 }
4226 
4227 impl<'subs, W> DemangleAsInner<'subs, W> for FunctionType
4228 where
4229     W: 'subs + DemangleWrite,
4230 {
demangle_as_inner<'prev, 'ctx>( &'subs self, ctx: &'ctx mut DemangleContext<'subs, W>, scope: Option<ArgScopeStack<'prev, 'subs>>, ) -> fmt::Result4231     fn demangle_as_inner<'prev, 'ctx>(
4232         &'subs self,
4233         ctx: &'ctx mut DemangleContext<'subs, W>,
4234         scope: Option<ArgScopeStack<'prev, 'subs>>,
4235     ) -> fmt::Result {
4236         let ctx = try_begin_demangle_as_inner!(self, ctx, scope);
4237 
4238         if !self.cv_qualifiers.is_empty() {
4239             self.cv_qualifiers.demangle(ctx, scope)?;
4240         }
4241 
4242         if let Some(ref rq) = self.ref_qualifier {
4243             // Print out a space before printing "&" or "&&"
4244             ctx.ensure_space()?;
4245             rq.demangle(ctx, scope)?;
4246         }
4247 
4248         Ok(())
4249     }
4250 
downcast_to_function_type(&self) -> Option<&FunctionType>4251     fn downcast_to_function_type(&self) -> Option<&FunctionType> {
4252         Some(self)
4253     }
4254 }
4255 
4256 /// The `<bare-function-type>` production.
4257 ///
4258 /// ```text
4259 /// <bare-function-type> ::= <signature type>+
4260 ///      # types are possible return type, then parameter types
4261 /// ```
4262 #[derive(Clone, Debug, PartialEq, Eq)]
4263 pub struct BareFunctionType(Vec<TypeHandle>);
4264 
4265 impl BareFunctionType {
ret(&self) -> &TypeHandle4266     fn ret(&self) -> &TypeHandle {
4267         &self.0[0]
4268     }
4269 
args(&self) -> &FunctionArgListAndReturnType4270     fn args(&self) -> &FunctionArgListAndReturnType {
4271         FunctionArgListAndReturnType::new(&self.0)
4272     }
4273 }
4274 
4275 impl Parse for BareFunctionType {
parse<'a, 'b>( ctx: &'a ParseContext, subs: &'a mut SubstitutionTable, input: IndexStr<'b>, ) -> Result<(BareFunctionType, IndexStr<'b>)>4276     fn parse<'a, 'b>(
4277         ctx: &'a ParseContext,
4278         subs: &'a mut SubstitutionTable,
4279         input: IndexStr<'b>,
4280     ) -> Result<(BareFunctionType, IndexStr<'b>)> {
4281         try_begin_parse!("BareFunctionType", ctx, input);
4282 
4283         let (types, tail) = one_or_more::<TypeHandle>(ctx, subs, input)?;
4284         Ok((BareFunctionType(types), tail))
4285     }
4286 }
4287 
4288 impl<'subs, W> Demangle<'subs, W> for BareFunctionType
4289 where
4290     W: 'subs + DemangleWrite,
4291 {
demangle<'prev, 'ctx>( &'subs self, ctx: &'ctx mut DemangleContext<'subs, W>, scope: Option<ArgScopeStack<'prev, 'subs>>, ) -> fmt::Result4292     fn demangle<'prev, 'ctx>(
4293         &'subs self,
4294         ctx: &'ctx mut DemangleContext<'subs, W>,
4295         scope: Option<ArgScopeStack<'prev, 'subs>>,
4296     ) -> fmt::Result {
4297         let ctx = try_begin_demangle!(self, ctx, scope);
4298 
4299         ctx.push_inner(self);
4300 
4301         self.ret().demangle(ctx, scope)?;
4302 
4303         if ctx.pop_inner_if(self) {
4304             ctx.ensure_space()?;
4305             self.demangle_as_inner(ctx, scope)?;
4306         }
4307 
4308         Ok(())
4309     }
4310 }
4311 
4312 impl<'subs, W> DemangleAsInner<'subs, W> for BareFunctionType
4313 where
4314     W: 'subs + DemangleWrite,
4315 {
demangle_as_inner<'prev, 'ctx>( &'subs self, ctx: &'ctx mut DemangleContext<'subs, W>, scope: Option<ArgScopeStack<'prev, 'subs>>, ) -> fmt::Result4316     fn demangle_as_inner<'prev, 'ctx>(
4317         &'subs self,
4318         ctx: &'ctx mut DemangleContext<'subs, W>,
4319         scope: Option<ArgScopeStack<'prev, 'subs>>,
4320     ) -> fmt::Result {
4321         let ctx = try_begin_demangle_as_inner!(self, ctx, scope);
4322         self.args().demangle_as_inner(ctx, scope)?;
4323         Ok(())
4324     }
4325 }
4326 
4327 /// The `<decltype>` production.
4328 ///
4329 /// ```text
4330 /// <decltype> ::= Dt <expression> E
4331 ///            ::= DT <expression> E
4332 /// ```
4333 #[derive(Clone, Debug, PartialEq, Eq)]
4334 pub enum Decltype {
4335     /// A `decltype` of an id-expression or class member access (C++0x).
4336     IdExpression(Expression),
4337 
4338     /// A `decltype` of an expression (C++0x).
4339     Expression(Expression),
4340 }
4341 
4342 impl Parse for Decltype {
parse<'a, 'b>( ctx: &'a ParseContext, subs: &'a mut SubstitutionTable, input: IndexStr<'b>, ) -> Result<(Decltype, IndexStr<'b>)>4343     fn parse<'a, 'b>(
4344         ctx: &'a ParseContext,
4345         subs: &'a mut SubstitutionTable,
4346         input: IndexStr<'b>,
4347     ) -> Result<(Decltype, IndexStr<'b>)> {
4348         try_begin_parse!("Decltype", ctx, input);
4349 
4350         let tail = consume(b"D", input)?;
4351 
4352         if let Ok(tail) = consume(b"t", tail) {
4353             let (expr, tail) = Expression::parse(ctx, subs, tail)?;
4354             let tail = consume(b"E", tail)?;
4355             return Ok((Decltype::IdExpression(expr), tail));
4356         }
4357 
4358         let tail = consume(b"T", tail)?;
4359         let (expr, tail) = Expression::parse(ctx, subs, tail)?;
4360         let tail = consume(b"E", tail)?;
4361         Ok((Decltype::Expression(expr), tail))
4362     }
4363 }
4364 
4365 impl<'subs, W> Demangle<'subs, W> for Decltype
4366 where
4367     W: 'subs + DemangleWrite,
4368 {
demangle<'prev, 'ctx>( &'subs self, ctx: &'ctx mut DemangleContext<'subs, W>, scope: Option<ArgScopeStack<'prev, 'subs>>, ) -> fmt::Result4369     fn demangle<'prev, 'ctx>(
4370         &'subs self,
4371         ctx: &'ctx mut DemangleContext<'subs, W>,
4372         scope: Option<ArgScopeStack<'prev, 'subs>>,
4373     ) -> fmt::Result {
4374         let ctx = try_begin_demangle!(self, ctx, scope);
4375 
4376         ctx.push_demangle_node(DemangleNodeType::TemplateParam);
4377         let ret = match *self {
4378             Decltype::Expression(ref expr) | Decltype::IdExpression(ref expr) => {
4379                 write!(ctx, "decltype (")?;
4380                 expr.demangle(ctx, scope)?;
4381                 write!(ctx, ")")?;
4382                 Ok(())
4383             }
4384         };
4385         ctx.pop_demangle_node();
4386         ret
4387     }
4388 }
4389 
4390 /// The `<class-enum-type>` production.
4391 ///
4392 /// ```text
4393 /// <class-enum-type> ::= <name>
4394 ///                   ::= Ts <name>
4395 ///                   ::= Tu <name>
4396 ///                   ::= Te <name>
4397 /// ```
4398 #[derive(Clone, Debug, PartialEq, Eq)]
4399 pub enum ClassEnumType {
4400     /// A non-dependent type name, dependent type name, or dependent
4401     /// typename-specifier.
4402     Named(Name),
4403 
4404     /// A dependent elaborated type specifier using 'struct' or 'class'.
4405     ElaboratedStruct(Name),
4406 
4407     /// A dependent elaborated type specifier using 'union'.
4408     ElaboratedUnion(Name),
4409 
4410     /// A dependent elaborated type specifier using 'enum'.
4411     ElaboratedEnum(Name),
4412 }
4413 
4414 impl Parse for ClassEnumType {
parse<'a, 'b>( ctx: &'a ParseContext, subs: &'a mut SubstitutionTable, input: IndexStr<'b>, ) -> Result<(ClassEnumType, IndexStr<'b>)>4415     fn parse<'a, 'b>(
4416         ctx: &'a ParseContext,
4417         subs: &'a mut SubstitutionTable,
4418         input: IndexStr<'b>,
4419     ) -> Result<(ClassEnumType, IndexStr<'b>)> {
4420         try_begin_parse!("ClassEnumType", ctx, input);
4421 
4422         if let Ok((name, tail)) = Name::parse(ctx, subs, input) {
4423             return Ok((ClassEnumType::Named(name), tail));
4424         }
4425 
4426         let tail = consume(b"T", input)?;
4427 
4428         if let Ok(tail) = consume(b"s", tail) {
4429             let (name, tail) = Name::parse(ctx, subs, tail)?;
4430             return Ok((ClassEnumType::ElaboratedStruct(name), tail));
4431         }
4432 
4433         if let Ok(tail) = consume(b"u", tail) {
4434             let (name, tail) = Name::parse(ctx, subs, tail)?;
4435             return Ok((ClassEnumType::ElaboratedUnion(name), tail));
4436         }
4437 
4438         let tail = consume(b"e", tail)?;
4439         let (name, tail) = Name::parse(ctx, subs, tail)?;
4440         Ok((ClassEnumType::ElaboratedEnum(name), tail))
4441     }
4442 }
4443 
4444 impl<'subs, W> Demangle<'subs, W> for ClassEnumType
4445 where
4446     W: 'subs + DemangleWrite,
4447 {
demangle<'prev, 'ctx>( &'subs self, ctx: &'ctx mut DemangleContext<'subs, W>, scope: Option<ArgScopeStack<'prev, 'subs>>, ) -> fmt::Result4448     fn demangle<'prev, 'ctx>(
4449         &'subs self,
4450         ctx: &'ctx mut DemangleContext<'subs, W>,
4451         scope: Option<ArgScopeStack<'prev, 'subs>>,
4452     ) -> fmt::Result {
4453         let ctx = try_begin_demangle!(self, ctx, scope);
4454 
4455         match *self {
4456             ClassEnumType::Named(ref name) => name.demangle(ctx, scope),
4457             ClassEnumType::ElaboratedStruct(ref name) => {
4458                 write!(ctx, "class ")?;
4459                 name.demangle(ctx, scope)
4460             }
4461             ClassEnumType::ElaboratedUnion(ref name) => {
4462                 write!(ctx, "union ")?;
4463                 name.demangle(ctx, scope)
4464             }
4465             ClassEnumType::ElaboratedEnum(ref name) => {
4466                 write!(ctx, "enum ")?;
4467                 name.demangle(ctx, scope)
4468             }
4469         }
4470     }
4471 }
4472 
4473 impl<'a> GetLeafName<'a> for ClassEnumType {
get_leaf_name(&'a self, subs: &'a SubstitutionTable) -> Option<LeafName<'a>>4474     fn get_leaf_name(&'a self, subs: &'a SubstitutionTable) -> Option<LeafName<'a>> {
4475         match *self {
4476             ClassEnumType::Named(ref name)
4477             | ClassEnumType::ElaboratedStruct(ref name)
4478             | ClassEnumType::ElaboratedUnion(ref name)
4479             | ClassEnumType::ElaboratedEnum(ref name) => name.get_leaf_name(subs),
4480         }
4481     }
4482 }
4483 
4484 /// The `<unnamed-type-name>` production.
4485 ///
4486 /// ```text
4487 /// <unnamed-type-name> ::= Ut [ <nonnegative number> ] _
4488 ///                     ::= <closure-type-name>
4489 /// ```
4490 ///
4491 /// TODO: parse the <closure-type-name> variant
4492 #[derive(Clone, Debug, PartialEq, Eq)]
4493 pub struct UnnamedTypeName(Option<usize>);
4494 
4495 impl Parse for UnnamedTypeName {
parse<'a, 'b>( ctx: &'a ParseContext, _subs: &'a mut SubstitutionTable, input: IndexStr<'b>, ) -> Result<(UnnamedTypeName, IndexStr<'b>)>4496     fn parse<'a, 'b>(
4497         ctx: &'a ParseContext,
4498         _subs: &'a mut SubstitutionTable,
4499         input: IndexStr<'b>,
4500     ) -> Result<(UnnamedTypeName, IndexStr<'b>)> {
4501         try_begin_parse!("UnnamedTypeName", ctx, input);
4502 
4503         let input = consume(b"Ut", input)?;
4504         let (number, input) = match parse_number(10, false, input) {
4505             Ok((number, input)) => (Some(number as _), input),
4506             Err(_) => (None, input),
4507         };
4508         let input = consume(b"_", input)?;
4509         Ok((UnnamedTypeName(number), input))
4510     }
4511 }
4512 
4513 impl UnnamedTypeName {
4514     #[inline]
starts_with(byte: u8) -> bool4515     fn starts_with(byte: u8) -> bool {
4516         byte == b'U'
4517     }
4518 }
4519 
4520 impl<'subs, W> Demangle<'subs, W> for UnnamedTypeName
4521 where
4522     W: 'subs + DemangleWrite,
4523 {
demangle<'prev, 'ctx>( &'subs self, ctx: &'ctx mut DemangleContext<'subs, W>, scope: Option<ArgScopeStack<'prev, 'subs>>, ) -> fmt::Result4524     fn demangle<'prev, 'ctx>(
4525         &'subs self,
4526         ctx: &'ctx mut DemangleContext<'subs, W>,
4527         scope: Option<ArgScopeStack<'prev, 'subs>>,
4528     ) -> fmt::Result {
4529         let ctx = try_begin_demangle!(self, ctx, scope);
4530 
4531         write!(ctx, "{{unnamed type#{}}}", self.0.map_or(1, |n| n + 1))?;
4532         Ok(())
4533     }
4534 }
4535 
4536 impl<'subs, W> DemangleAsLeaf<'subs, W> for UnnamedTypeName
4537 where
4538     W: 'subs + DemangleWrite,
4539 {
demangle_as_leaf<'me, 'ctx>( &'me self, ctx: &'ctx mut DemangleContext<'subs, W>, ) -> fmt::Result4540     fn demangle_as_leaf<'me, 'ctx>(
4541         &'me self,
4542         ctx: &'ctx mut DemangleContext<'subs, W>,
4543     ) -> fmt::Result {
4544         let ctx = try_begin_demangle!(self, ctx, None);
4545         if let Some(source_name) = ctx.source_name {
4546             write!(ctx, "{}", source_name)?;
4547         } else {
4548             write!(ctx, "{{unnamed type#{}}}", self.0.map_or(1, |n| n + 1))?;
4549         }
4550         Ok(())
4551     }
4552 }
4553 
4554 impl<'subs> ArgScope<'subs, 'subs> for UnnamedTypeName {
leaf_name(&'subs self) -> Result<LeafName<'subs>>4555     fn leaf_name(&'subs self) -> Result<LeafName<'subs>> {
4556         Ok(LeafName::UnnamedType(self))
4557     }
4558 
get_template_arg( &'subs self, _: usize, ) -> Result<(&'subs TemplateArg, &'subs TemplateArgs)>4559     fn get_template_arg(
4560         &'subs self,
4561         _: usize,
4562     ) -> Result<(&'subs TemplateArg, &'subs TemplateArgs)> {
4563         Err(error::Error::BadTemplateArgReference)
4564     }
4565 
get_function_arg(&'subs self, _: usize) -> Result<&'subs Type>4566     fn get_function_arg(&'subs self, _: usize) -> Result<&'subs Type> {
4567         Err(error::Error::BadFunctionArgReference)
4568     }
4569 }
4570 
4571 /// The `<array-type>` production.
4572 ///
4573 /// ```text
4574 /// <array-type> ::= A <positive dimension number> _ <element type>
4575 ///              ::= A [<dimension expression>] _ <element type>
4576 /// ```
4577 #[derive(Clone, Debug, PartialEq, Eq)]
4578 pub enum ArrayType {
4579     /// An array with a number-literal dimension.
4580     DimensionNumber(usize, TypeHandle),
4581 
4582     /// An array with an expression for its dimension.
4583     DimensionExpression(Expression, TypeHandle),
4584 
4585     /// An array with no dimension.
4586     NoDimension(TypeHandle),
4587 }
4588 
4589 impl Parse for ArrayType {
parse<'a, 'b>( ctx: &'a ParseContext, subs: &'a mut SubstitutionTable, input: IndexStr<'b>, ) -> Result<(ArrayType, IndexStr<'b>)>4590     fn parse<'a, 'b>(
4591         ctx: &'a ParseContext,
4592         subs: &'a mut SubstitutionTable,
4593         input: IndexStr<'b>,
4594     ) -> Result<(ArrayType, IndexStr<'b>)> {
4595         try_begin_parse!("ArrayType", ctx, input);
4596 
4597         let tail = consume(b"A", input)?;
4598 
4599         if let Ok((num, tail)) = parse_number(10, false, tail) {
4600             debug_assert!(num >= 0);
4601             let tail = consume(b"_", tail)?;
4602             let (ty, tail) = TypeHandle::parse(ctx, subs, tail)?;
4603             return Ok((ArrayType::DimensionNumber(num as _, ty), tail));
4604         }
4605 
4606         if let Ok((expr, tail)) = Expression::parse(ctx, subs, tail) {
4607             let tail = consume(b"_", tail)?;
4608             let (ty, tail) = TypeHandle::parse(ctx, subs, tail)?;
4609             return Ok((ArrayType::DimensionExpression(expr, ty), tail));
4610         }
4611 
4612         let tail = consume(b"_", tail)?;
4613         let (ty, tail) = TypeHandle::parse(ctx, subs, tail)?;
4614         Ok((ArrayType::NoDimension(ty), tail))
4615     }
4616 }
4617 
4618 impl<'subs, W> Demangle<'subs, W> for ArrayType
4619 where
4620     W: 'subs + DemangleWrite,
4621 {
demangle<'prev, 'ctx>( &'subs self, ctx: &'ctx mut DemangleContext<'subs, W>, scope: Option<ArgScopeStack<'prev, 'subs>>, ) -> fmt::Result4622     fn demangle<'prev, 'ctx>(
4623         &'subs self,
4624         ctx: &'ctx mut DemangleContext<'subs, W>,
4625         scope: Option<ArgScopeStack<'prev, 'subs>>,
4626     ) -> fmt::Result {
4627         let ctx = try_begin_demangle!(self, ctx, scope);
4628 
4629         ctx.push_inner(self);
4630 
4631         match *self {
4632             ArrayType::DimensionNumber(_, ref ty)
4633             | ArrayType::DimensionExpression(_, ref ty)
4634             | ArrayType::NoDimension(ref ty) => {
4635                 ty.demangle(ctx, scope)?;
4636             }
4637         }
4638 
4639         if ctx.pop_inner_if(self) {
4640             self.demangle_as_inner(ctx, scope)?;
4641         }
4642 
4643         Ok(())
4644     }
4645 }
4646 
4647 impl<'subs, W> DemangleAsInner<'subs, W> for ArrayType
4648 where
4649     W: 'subs + DemangleWrite,
4650 {
demangle_as_inner<'prev, 'ctx>( &'subs self, ctx: &'ctx mut DemangleContext<'subs, W>, scope: Option<ArgScopeStack<'prev, 'subs>>, ) -> fmt::Result4651     fn demangle_as_inner<'prev, 'ctx>(
4652         &'subs self,
4653         ctx: &'ctx mut DemangleContext<'subs, W>,
4654         scope: Option<ArgScopeStack<'prev, 'subs>>,
4655     ) -> fmt::Result {
4656         let ctx = try_begin_demangle_as_inner!(self, ctx, scope);
4657 
4658         // Whether we should add a final space before the dimensions.
4659         let mut needs_space = true;
4660 
4661         while let Some(inner) = ctx.pop_inner() {
4662             // We need to add parentheses around array inner types, unless they
4663             // are also (potentially qualified) arrays themselves, in which case
4664             // we format them as multi-dimensional arrays.
4665             let inner_is_array = match inner.downcast_to_type() {
4666                 Some(&Type::Qualified(_, ref ty)) => ctx.subs.get_type(ty).map_or(false, |ty| {
4667                     DemangleAsInner::<W>::downcast_to_array_type(ty).is_some()
4668                 }),
4669                 _ => {
4670                     if inner.downcast_to_array_type().is_some() {
4671                         needs_space = false;
4672                         true
4673                     } else {
4674                         false
4675                     }
4676                 }
4677             };
4678 
4679             if inner_is_array {
4680                 inner.demangle_as_inner(ctx, scope)?;
4681             } else {
4682                 ctx.ensure_space()?;
4683 
4684                 // CvQualifiers should have the parentheses printed after, not before
4685                 if inner.is_qualified() {
4686                     inner.demangle_as_inner(ctx, scope)?;
4687                     ctx.ensure_space()?;
4688                     write!(ctx, "(")?;
4689                 } else {
4690                     write!(ctx, "(")?;
4691                     inner.demangle_as_inner(ctx, scope)?;
4692                 }
4693 
4694                 ctx.demangle_inners(scope)?;
4695                 write!(ctx, ")")?;
4696             }
4697         }
4698 
4699         if needs_space {
4700             ctx.ensure_space()?;
4701         }
4702 
4703         match *self {
4704             ArrayType::DimensionNumber(n, _) => {
4705                 write!(ctx, "[{}]", n)?;
4706             }
4707             ArrayType::DimensionExpression(ref expr, _) => {
4708                 write!(ctx, "[")?;
4709                 expr.demangle(ctx, scope)?;
4710                 write!(ctx, "]")?;
4711             }
4712             ArrayType::NoDimension(_) => {
4713                 write!(ctx, "[]")?;
4714             }
4715         }
4716 
4717         Ok(())
4718     }
4719 
downcast_to_array_type(&self) -> Option<&ArrayType>4720     fn downcast_to_array_type(&self) -> Option<&ArrayType> {
4721         Some(self)
4722     }
4723 }
4724 
4725 /// The `<vector-type>` production.
4726 ///
4727 /// ```text
4728 /// <vector-type> ::= Dv <number> _ <type>
4729 ///               ::= Dv _ <expression> _ <type>
4730 /// ```
4731 #[derive(Clone, Debug, PartialEq, Eq)]
4732 pub enum VectorType {
4733     /// An vector with a number-literal dimension.
4734     DimensionNumber(usize, TypeHandle),
4735 
4736     /// An vector with an expression for its dimension.
4737     DimensionExpression(Expression, TypeHandle),
4738 }
4739 
4740 impl Parse for VectorType {
parse<'a, 'b>( ctx: &'a ParseContext, subs: &'a mut SubstitutionTable, input: IndexStr<'b>, ) -> Result<(VectorType, IndexStr<'b>)>4741     fn parse<'a, 'b>(
4742         ctx: &'a ParseContext,
4743         subs: &'a mut SubstitutionTable,
4744         input: IndexStr<'b>,
4745     ) -> Result<(VectorType, IndexStr<'b>)> {
4746         try_begin_parse!("VectorType", ctx, input);
4747 
4748         let tail = consume(b"Dv", input)?;
4749 
4750         if let Ok((num, tail)) = parse_number(10, false, tail) {
4751             debug_assert!(num >= 0);
4752             let tail = consume(b"_", tail)?;
4753             let (ty, tail) = TypeHandle::parse(ctx, subs, tail)?;
4754             return Ok((VectorType::DimensionNumber(num as _, ty), tail));
4755         }
4756 
4757         let tail = consume(b"_", tail)?;
4758         let (expr, tail) = Expression::parse(ctx, subs, tail)?;
4759         let tail = consume(b"_", tail)?;
4760         let (ty, tail) = TypeHandle::parse(ctx, subs, tail)?;
4761         Ok((VectorType::DimensionExpression(expr, ty), tail))
4762     }
4763 }
4764 
4765 impl<'subs, W> Demangle<'subs, W> for VectorType
4766 where
4767     W: 'subs + DemangleWrite,
4768 {
demangle<'prev, 'ctx>( &'subs self, ctx: &'ctx mut DemangleContext<'subs, W>, scope: Option<ArgScopeStack<'prev, 'subs>>, ) -> fmt::Result4769     fn demangle<'prev, 'ctx>(
4770         &'subs self,
4771         ctx: &'ctx mut DemangleContext<'subs, W>,
4772         scope: Option<ArgScopeStack<'prev, 'subs>>,
4773     ) -> fmt::Result {
4774         let ctx = try_begin_demangle!(self, ctx, scope);
4775 
4776         ctx.push_inner(self);
4777 
4778         match *self {
4779             VectorType::DimensionNumber(_, ref ty) | VectorType::DimensionExpression(_, ref ty) => {
4780                 ty.demangle(ctx, scope)?;
4781             }
4782         }
4783 
4784         if ctx.pop_inner_if(self) {
4785             self.demangle_as_inner(ctx, scope)?;
4786         }
4787 
4788         Ok(())
4789     }
4790 }
4791 
4792 impl<'subs, W> DemangleAsInner<'subs, W> for VectorType
4793 where
4794     W: 'subs + DemangleWrite,
4795 {
demangle_as_inner<'prev, 'ctx>( &'subs self, ctx: &'ctx mut DemangleContext<'subs, W>, scope: Option<ArgScopeStack<'prev, 'subs>>, ) -> fmt::Result4796     fn demangle_as_inner<'prev, 'ctx>(
4797         &'subs self,
4798         ctx: &'ctx mut DemangleContext<'subs, W>,
4799         scope: Option<ArgScopeStack<'prev, 'subs>>,
4800     ) -> fmt::Result {
4801         let ctx = try_begin_demangle_as_inner!(self, ctx, scope);
4802 
4803         match *self {
4804             VectorType::DimensionNumber(n, _) => {
4805                 write!(ctx, " __vector({})", n)?;
4806             }
4807             VectorType::DimensionExpression(ref expr, _) => {
4808                 write!(ctx, " __vector(")?;
4809                 expr.demangle(ctx, scope)?;
4810                 write!(ctx, ")")?;
4811             }
4812         }
4813 
4814         Ok(())
4815     }
4816 }
4817 
4818 /// The `<pointer-to-member-type>` production.
4819 ///
4820 /// ```text
4821 /// <pointer-to-member-type> ::= M <class type> <member type>
4822 /// ```
4823 #[derive(Clone, Debug, PartialEq, Eq)]
4824 pub struct PointerToMemberType(TypeHandle, TypeHandle);
4825 
4826 impl Parse for PointerToMemberType {
parse<'a, 'b>( ctx: &'a ParseContext, subs: &'a mut SubstitutionTable, input: IndexStr<'b>, ) -> Result<(PointerToMemberType, IndexStr<'b>)>4827     fn parse<'a, 'b>(
4828         ctx: &'a ParseContext,
4829         subs: &'a mut SubstitutionTable,
4830         input: IndexStr<'b>,
4831     ) -> Result<(PointerToMemberType, IndexStr<'b>)> {
4832         try_begin_parse!("PointerToMemberType", ctx, input);
4833 
4834         let tail = consume(b"M", input)?;
4835         let (ty1, tail) = TypeHandle::parse(ctx, subs, tail)?;
4836         let (ty2, tail) = TypeHandle::parse(ctx, subs, tail)?;
4837         Ok((PointerToMemberType(ty1, ty2), tail))
4838     }
4839 }
4840 
4841 impl<'subs, W> Demangle<'subs, W> for PointerToMemberType
4842 where
4843     W: 'subs + DemangleWrite,
4844 {
demangle<'prev, 'ctx>( &'subs self, ctx: &'ctx mut DemangleContext<'subs, W>, scope: Option<ArgScopeStack<'prev, 'subs>>, ) -> fmt::Result4845     fn demangle<'prev, 'ctx>(
4846         &'subs self,
4847         ctx: &'ctx mut DemangleContext<'subs, W>,
4848         scope: Option<ArgScopeStack<'prev, 'subs>>,
4849     ) -> fmt::Result {
4850         let ctx = try_begin_demangle!(self, ctx, scope);
4851 
4852         ctx.push_inner(self);
4853         self.1.demangle(ctx, scope)?;
4854         if ctx.pop_inner_if(self) {
4855             self.demangle_as_inner(ctx, scope)?;
4856         }
4857         Ok(())
4858     }
4859 }
4860 
4861 impl<'subs, W> DemangleAsInner<'subs, W> for PointerToMemberType
4862 where
4863     W: 'subs + DemangleWrite,
4864 {
demangle_as_inner<'prev, 'ctx>( &'subs self, ctx: &'ctx mut DemangleContext<'subs, W>, scope: Option<ArgScopeStack<'prev, 'subs>>, ) -> fmt::Result4865     fn demangle_as_inner<'prev, 'ctx>(
4866         &'subs self,
4867         ctx: &'ctx mut DemangleContext<'subs, W>,
4868         scope: Option<ArgScopeStack<'prev, 'subs>>,
4869     ) -> fmt::Result {
4870         let ctx = try_begin_demangle_as_inner!(self, ctx, scope);
4871 
4872         if ctx.last_char_written != Some('(') {
4873             ctx.ensure_space()?;
4874         }
4875 
4876         self.0.demangle(ctx, scope)?;
4877         write!(ctx, "::*")?;
4878         Ok(())
4879     }
4880 
downcast_to_pointer_to_member(&self) -> Option<&PointerToMemberType>4881     fn downcast_to_pointer_to_member(&self) -> Option<&PointerToMemberType> {
4882         Some(self)
4883     }
4884 }
4885 
4886 /// The `<template-param>` production.
4887 ///
4888 /// ```text
4889 /// <template-param> ::= T_ # first template parameter
4890 ///                  ::= T <parameter-2 non-negative number> _
4891 /// ```
4892 #[derive(Clone, Debug, PartialEq, Eq)]
4893 pub struct TemplateParam(usize);
4894 
4895 impl Parse for TemplateParam {
parse<'a, 'b>( ctx: &'a ParseContext, _subs: &'a mut SubstitutionTable, input: IndexStr<'b>, ) -> Result<(TemplateParam, IndexStr<'b>)>4896     fn parse<'a, 'b>(
4897         ctx: &'a ParseContext,
4898         _subs: &'a mut SubstitutionTable,
4899         input: IndexStr<'b>,
4900     ) -> Result<(TemplateParam, IndexStr<'b>)> {
4901         try_begin_parse!("TemplateParam", ctx, input);
4902 
4903         let input = consume(b"T", input)?;
4904         let (number, input) = match parse_number(10, false, input) {
4905             Ok((number, input)) => ((number + 1) as _, input),
4906             Err(_) => (0, input),
4907         };
4908         let input = consume(b"_", input)?;
4909         Ok((TemplateParam(number), input))
4910     }
4911 }
4912 
4913 impl<'subs, W> Demangle<'subs, W> for TemplateParam
4914 where
4915     W: 'subs + DemangleWrite,
4916 {
demangle<'prev, 'ctx>( &'subs self, ctx: &'ctx mut DemangleContext<'subs, W>, scope: Option<ArgScopeStack<'prev, 'subs>>, ) -> fmt::Result4917     fn demangle<'prev, 'ctx>(
4918         &'subs self,
4919         ctx: &'ctx mut DemangleContext<'subs, W>,
4920         scope: Option<ArgScopeStack<'prev, 'subs>>,
4921     ) -> fmt::Result {
4922         let ctx = try_begin_demangle!(self, ctx, scope);
4923 
4924         ctx.push_demangle_node(DemangleNodeType::TemplateParam);
4925         let ret = if ctx.is_lambda_arg {
4926             // To match libiberty, template references are converted to `auto`.
4927             write!(ctx, "auto:{}", self.0 + 1)
4928         } else {
4929             let arg = self.resolve(scope)?;
4930             arg.demangle(ctx, scope)
4931         };
4932         ctx.pop_demangle_node();
4933         ret
4934     }
4935 }
4936 
4937 impl TemplateParam {
resolve<'subs, 'prev>( &'subs self, scope: Option<ArgScopeStack<'prev, 'subs>>, ) -> ::std::result::Result<&'subs TemplateArg, fmt::Error>4938     fn resolve<'subs, 'prev>(
4939         &'subs self,
4940         scope: Option<ArgScopeStack<'prev, 'subs>>,
4941     ) -> ::std::result::Result<&'subs TemplateArg, fmt::Error> {
4942         scope
4943             .get_template_arg(self.0)
4944             .map_err(|e| {
4945                 log!("Error obtaining template argument: {}", e);
4946                 fmt::Error
4947             })
4948             .map(|v| v.0)
4949     }
4950 }
4951 
4952 impl<'a> Hash for &'a TemplateParam {
hash<H>(&self, state: &mut H) where H: Hasher,4953     fn hash<H>(&self, state: &mut H)
4954     where
4955         H: Hasher,
4956     {
4957         let self_ref: &TemplateParam = *self;
4958         let self_ptr = self_ref as *const TemplateParam;
4959         self_ptr.hash(state);
4960     }
4961 }
4962 
4963 /// The `<template-template-param>` production.
4964 ///
4965 /// ```text
4966 /// <template-template-param> ::= <template-param>
4967 ///                           ::= <substitution>
4968 /// ```
4969 #[derive(Clone, Debug, PartialEq, Eq)]
4970 pub struct TemplateTemplateParam(TemplateParam);
4971 
4972 define_handle! {
4973     /// A reference to a parsed `TemplateTemplateParam`.
4974     pub enum TemplateTemplateParamHandle
4975 }
4976 
4977 impl Parse for TemplateTemplateParamHandle {
parse<'a, 'b>( ctx: &'a ParseContext, subs: &'a mut SubstitutionTable, input: IndexStr<'b>, ) -> Result<(TemplateTemplateParamHandle, IndexStr<'b>)>4978     fn parse<'a, 'b>(
4979         ctx: &'a ParseContext,
4980         subs: &'a mut SubstitutionTable,
4981         input: IndexStr<'b>,
4982     ) -> Result<(TemplateTemplateParamHandle, IndexStr<'b>)> {
4983         try_begin_parse!("TemplateTemplateParamHandle", ctx, input);
4984 
4985         if let Ok((sub, tail)) = Substitution::parse(ctx, subs, input) {
4986             match sub {
4987                 Substitution::WellKnown(component) => {
4988                     return Ok((TemplateTemplateParamHandle::WellKnown(component), tail));
4989                 }
4990                 Substitution::BackReference(idx) => {
4991                     // TODO: should this check if the thing at idx is a
4992                     // template-template-param? There could otherwise be ambiguity
4993                     // with <type>'s <substitution> form...
4994                     return Ok((TemplateTemplateParamHandle::BackReference(idx), tail));
4995                 }
4996             }
4997         }
4998 
4999         let (param, tail) = TemplateParam::parse(ctx, subs, input)?;
5000         let ttp = TemplateTemplateParam(param);
5001         let ttp = Substitutable::TemplateTemplateParam(ttp);
5002         let idx = subs.insert(ttp);
5003         let handle = TemplateTemplateParamHandle::BackReference(idx);
5004         Ok((handle, tail))
5005     }
5006 }
5007 
5008 impl<'subs, W> Demangle<'subs, W> for TemplateTemplateParam
5009 where
5010     W: 'subs + DemangleWrite,
5011 {
5012     #[inline]
demangle<'prev, 'ctx>( &'subs self, ctx: &'ctx mut DemangleContext<'subs, W>, scope: Option<ArgScopeStack<'prev, 'subs>>, ) -> fmt::Result5013     fn demangle<'prev, 'ctx>(
5014         &'subs self,
5015         ctx: &'ctx mut DemangleContext<'subs, W>,
5016         scope: Option<ArgScopeStack<'prev, 'subs>>,
5017     ) -> fmt::Result {
5018         let ctx = try_begin_demangle!(self, ctx, scope);
5019 
5020         self.0.demangle(ctx, scope)
5021     }
5022 }
5023 
5024 /// The <function-param> production.
5025 ///
5026 /// ```text
5027 /// <function-param> ::= fp <top-level CV-qualifiers> _
5028 ///                          # L == 0, first parameter
5029 ///                  ::= fp <top-level CV-qualifiers> <parameter-2 non-negative number> _
5030 ///                          # L == 0, second and later parameters
5031 ///                  ::= fL <L-1 non-negative number> p <top-level CV-qualifiers> _
5032 ///                          # L > 0, first parameter
5033 ///                  ::= fL <L-1 non-negative number> p <top-level CV-qualifiers> <parameter-2 non-negative number> _
5034 ///                          # L > 0, second and later parameters
5035 /// ```
5036 #[derive(Clone, Debug, PartialEq, Eq)]
5037 pub struct FunctionParam(usize, CvQualifiers, Option<usize>);
5038 
5039 impl Parse for FunctionParam {
parse<'a, 'b>( ctx: &'a ParseContext, subs: &'a mut SubstitutionTable, input: IndexStr<'b>, ) -> Result<(FunctionParam, IndexStr<'b>)>5040     fn parse<'a, 'b>(
5041         ctx: &'a ParseContext,
5042         subs: &'a mut SubstitutionTable,
5043         input: IndexStr<'b>,
5044     ) -> Result<(FunctionParam, IndexStr<'b>)> {
5045         try_begin_parse!("FunctionParam", ctx, input);
5046 
5047         let tail = consume(b"f", input)?;
5048         if tail.is_empty() {
5049             return Err(error::Error::UnexpectedEnd);
5050         }
5051 
5052         let (scope, tail) = if let Ok(tail) = consume(b"L", tail) {
5053             parse_number(10, false, tail)?
5054         } else {
5055             (0, tail)
5056         };
5057 
5058         let tail = consume(b"p", tail)?;
5059 
5060         let (qualifiers, tail) = CvQualifiers::parse(ctx, subs, tail)?;
5061 
5062         let (param, tail) = if tail.peek() == Some(b'T') {
5063             (None, consume(b"T", tail)?)
5064         } else if let Ok((num, tail)) = parse_number(10, false, tail) {
5065             (Some(num as usize + 1), consume(b"_", tail)?)
5066         } else {
5067             (Some(0), consume(b"_", tail)?)
5068         };
5069 
5070         Ok((FunctionParam(scope as _, qualifiers, param), tail))
5071     }
5072 }
5073 
5074 impl<'subs, W> Demangle<'subs, W> for FunctionParam
5075 where
5076     W: 'subs + DemangleWrite,
5077 {
demangle<'prev, 'ctx>( &'subs self, ctx: &'ctx mut DemangleContext<'subs, W>, scope: Option<ArgScopeStack<'prev, 'subs>>, ) -> fmt::Result5078     fn demangle<'prev, 'ctx>(
5079         &'subs self,
5080         ctx: &'ctx mut DemangleContext<'subs, W>,
5081         scope: Option<ArgScopeStack<'prev, 'subs>>,
5082     ) -> fmt::Result {
5083         let ctx = try_begin_demangle!(self, ctx, scope);
5084 
5085         match self.2 {
5086             None => write!(ctx, "this"),
5087             Some(i) => write!(ctx, "{{parm#{}}}", i + 1),
5088         }
5089     }
5090 }
5091 
5092 /// The `<template-args>` production.
5093 ///
5094 /// ```text
5095 /// <template-args> ::= I <template-arg>+ E
5096 /// ```
5097 #[derive(Clone, Debug, PartialEq, Eq)]
5098 pub struct TemplateArgs(Vec<TemplateArg>);
5099 
5100 impl Parse for TemplateArgs {
parse<'a, 'b>( ctx: &'a ParseContext, subs: &'a mut SubstitutionTable, input: IndexStr<'b>, ) -> Result<(TemplateArgs, IndexStr<'b>)>5101     fn parse<'a, 'b>(
5102         ctx: &'a ParseContext,
5103         subs: &'a mut SubstitutionTable,
5104         input: IndexStr<'b>,
5105     ) -> Result<(TemplateArgs, IndexStr<'b>)> {
5106         try_begin_parse!("TemplateArgs", ctx, input);
5107 
5108         let tail = consume(b"I", input)?;
5109 
5110         let (args, tail) = one_or_more::<TemplateArg>(ctx, subs, tail)?;
5111         let tail = consume(b"E", tail)?;
5112         Ok((TemplateArgs(args), tail))
5113     }
5114 }
5115 
5116 impl<'subs, W> Demangle<'subs, W> for TemplateArgs
5117 where
5118     W: 'subs + DemangleWrite,
5119 {
demangle<'prev, 'ctx>( &'subs self, ctx: &'ctx mut DemangleContext<'subs, W>, mut scope: Option<ArgScopeStack<'prev, 'subs>>, ) -> fmt::Result5120     fn demangle<'prev, 'ctx>(
5121         &'subs self,
5122         ctx: &'ctx mut DemangleContext<'subs, W>,
5123         mut scope: Option<ArgScopeStack<'prev, 'subs>>,
5124     ) -> fmt::Result {
5125         let ctx = try_begin_demangle!(self, ctx, scope);
5126         inner_barrier!(ctx);
5127 
5128         if ctx.last_char_written == Some('<') {
5129             write!(ctx, " ")?;
5130         }
5131         write!(ctx, "<")?;
5132         ctx.push_demangle_node(DemangleNodeType::TemplateArgs);
5133         let mut need_comma = false;
5134         for arg_index in 0..self.0.len() {
5135             if need_comma {
5136                 write!(ctx, ", ")?;
5137             }
5138             if let Some(ref mut scope) = scope {
5139                 scope.in_arg = Some((arg_index, self));
5140             }
5141             self.0[arg_index].demangle(ctx, scope)?;
5142             need_comma = true;
5143         }
5144 
5145         // Ensure "> >" because old C++ sucks and libiberty (and its tests)
5146         // supports old C++.
5147         if ctx.last_char_written == Some('>') {
5148             write!(ctx, " ")?;
5149         }
5150         ctx.pop_demangle_node();
5151         write!(ctx, ">")?;
5152         Ok(())
5153     }
5154 }
5155 
5156 impl<'subs> ArgScope<'subs, 'subs> for TemplateArgs {
leaf_name(&'subs self) -> Result<LeafName<'subs>>5157     fn leaf_name(&'subs self) -> Result<LeafName<'subs>> {
5158         Err(error::Error::BadLeafNameReference)
5159     }
5160 
get_template_arg( &'subs self, idx: usize, ) -> Result<(&'subs TemplateArg, &'subs TemplateArgs)>5161     fn get_template_arg(
5162         &'subs self,
5163         idx: usize,
5164     ) -> Result<(&'subs TemplateArg, &'subs TemplateArgs)> {
5165         self.0
5166             .get(idx)
5167             .ok_or(error::Error::BadTemplateArgReference)
5168             .map(|v| (v, self))
5169     }
5170 
get_function_arg(&'subs self, _: usize) -> Result<&'subs Type>5171     fn get_function_arg(&'subs self, _: usize) -> Result<&'subs Type> {
5172         Err(error::Error::BadFunctionArgReference)
5173     }
5174 }
5175 
5176 /// A <template-arg> production.
5177 ///
5178 /// ```text
5179 /// <template-arg> ::= <type>                # type or template
5180 ///                ::= X <expression> E      # expression
5181 ///                ::= <expr-primary>        # simple expressions
5182 ///                ::= J <template-arg>* E   # argument pack
5183 /// ```
5184 #[derive(Clone, Debug, PartialEq, Eq)]
5185 pub enum TemplateArg {
5186     /// A type or template.
5187     Type(TypeHandle),
5188 
5189     /// An expression.
5190     Expression(Expression),
5191 
5192     /// A simple expression.
5193     SimpleExpression(ExprPrimary),
5194 
5195     /// An argument pack.
5196     ArgPack(Vec<TemplateArg>),
5197 }
5198 
5199 impl Parse for TemplateArg {
parse<'a, 'b>( ctx: &'a ParseContext, subs: &'a mut SubstitutionTable, input: IndexStr<'b>, ) -> Result<(TemplateArg, IndexStr<'b>)>5200     fn parse<'a, 'b>(
5201         ctx: &'a ParseContext,
5202         subs: &'a mut SubstitutionTable,
5203         input: IndexStr<'b>,
5204     ) -> Result<(TemplateArg, IndexStr<'b>)> {
5205         try_begin_parse!("TemplateArg", ctx, input);
5206 
5207         if let Ok(tail) = consume(b"X", input) {
5208             let (expr, tail) = Expression::parse(ctx, subs, tail)?;
5209             let tail = consume(b"E", tail)?;
5210             return Ok((TemplateArg::Expression(expr), tail));
5211         }
5212 
5213         if let Ok((expr, tail)) = ExprPrimary::parse(ctx, subs, input) {
5214             return Ok((TemplateArg::SimpleExpression(expr), tail));
5215         }
5216 
5217         if let Ok((ty, tail)) = TypeHandle::parse(ctx, subs, input) {
5218             return Ok((TemplateArg::Type(ty), tail));
5219         }
5220 
5221         let tail = if input.peek() == Some(b'J') {
5222             consume(b"J", input)?
5223         } else {
5224             consume(b"I", input)?
5225         };
5226 
5227         let (args, tail) = if tail.peek() == Some(b'E') {
5228             (vec![], tail)
5229         } else {
5230             zero_or_more::<TemplateArg>(ctx, subs, tail)?
5231         };
5232         let tail = consume(b"E", tail)?;
5233         Ok((TemplateArg::ArgPack(args), tail))
5234     }
5235 }
5236 
5237 impl<'subs, W> Demangle<'subs, W> for TemplateArg
5238 where
5239     W: 'subs + DemangleWrite,
5240 {
demangle<'prev, 'ctx>( &'subs self, ctx: &'ctx mut DemangleContext<'subs, W>, scope: Option<ArgScopeStack<'prev, 'subs>>, ) -> fmt::Result5241     fn demangle<'prev, 'ctx>(
5242         &'subs self,
5243         ctx: &'ctx mut DemangleContext<'subs, W>,
5244         scope: Option<ArgScopeStack<'prev, 'subs>>,
5245     ) -> fmt::Result {
5246         let ctx = try_begin_demangle!(self, ctx, scope);
5247 
5248         match *self {
5249             TemplateArg::Type(ref ty) => ty.demangle(ctx, scope),
5250             TemplateArg::Expression(ref expr) => expr.demangle(ctx, scope),
5251             TemplateArg::SimpleExpression(ref expr) => expr.demangle(ctx, scope),
5252             TemplateArg::ArgPack(ref args) => {
5253                 ctx.is_template_argument_pack = true;
5254                 let mut need_comma = false;
5255                 for arg in &args[..] {
5256                     if need_comma {
5257                         write!(ctx, ", ")?;
5258                     }
5259                     arg.demangle(ctx, scope)?;
5260                     need_comma = true;
5261                 }
5262                 Ok(())
5263             }
5264         }
5265     }
5266 }
5267 
5268 /// In libiberty, Member and DerefMember expressions have special handling.
5269 /// They parse an `UnqualifiedName` (not an `UnscopedName` as the cxxabi docs
5270 /// say) and optionally a `TemplateArgs` if it is present. We can't just parse
5271 /// a `Name` or an `UnscopedTemplateName` here because that allows other inputs
5272 /// that libiberty does not.
5273 #[derive(Clone, Debug, PartialEq, Eq)]
5274 pub struct MemberName(Name);
5275 
5276 impl Parse for MemberName {
parse<'a, 'b>( ctx: &'a ParseContext, subs: &'a mut SubstitutionTable, input: IndexStr<'b>, ) -> Result<(MemberName, IndexStr<'b>)>5277     fn parse<'a, 'b>(
5278         ctx: &'a ParseContext,
5279         subs: &'a mut SubstitutionTable,
5280         input: IndexStr<'b>,
5281     ) -> Result<(MemberName, IndexStr<'b>)> {
5282         try_begin_parse!("MemberName", ctx, input);
5283 
5284         let (name, tail) = UnqualifiedName::parse(ctx, subs, input)?;
5285         let name = UnscopedName::Unqualified(name);
5286         if let Ok((template, tail)) = TemplateArgs::parse(ctx, subs, tail) {
5287             let name = UnscopedTemplateName(name);
5288             // In libiberty, these are unsubstitutable.
5289             let idx = subs.insert_non_substitution(Substitutable::UnscopedTemplateName(name));
5290             let handle = UnscopedTemplateNameHandle::NonSubstitution(NonSubstitution(idx));
5291             Ok((MemberName(Name::UnscopedTemplate(handle, template)), tail))
5292         } else {
5293             Ok((MemberName(Name::Unscoped(name)), tail))
5294         }
5295     }
5296 }
5297 
5298 impl<'subs, W> Demangle<'subs, W> for MemberName
5299 where
5300     W: 'subs + DemangleWrite,
5301 {
demangle<'prev, 'ctx>( &'subs self, ctx: &'ctx mut DemangleContext<'subs, W>, scope: Option<ArgScopeStack<'prev, 'subs>>, ) -> fmt::Result5302     fn demangle<'prev, 'ctx>(
5303         &'subs self,
5304         ctx: &'ctx mut DemangleContext<'subs, W>,
5305         scope: Option<ArgScopeStack<'prev, 'subs>>,
5306     ) -> fmt::Result {
5307         let ctx = try_begin_demangle!(self, ctx, scope);
5308 
5309         let needs_parens = self.0.get_template_args(ctx.subs).is_some();
5310         if needs_parens {
5311             write!(ctx, "(")?;
5312         }
5313 
5314         self.0.demangle(ctx, scope)?;
5315 
5316         if needs_parens {
5317             write!(ctx, ")")?;
5318         }
5319 
5320         Ok(())
5321     }
5322 }
5323 
5324 /// The `<expression>` production.
5325 ///
5326 /// ```text
5327 ///  <expression> ::= <unary operator-name> <expression>
5328 ///               ::= <binary operator-name> <expression> <expression>
5329 ///               ::= <ternary operator-name> <expression> <expression> <expression>
5330 ///               ::= pp_ <expression>                             # prefix ++
5331 ///               ::= mm_ <expression>                             # prefix --
5332 ///               ::= cl <expression>+ E                           # expression (expr-list), call
5333 ///               ::= cv <type> <expression>                       # type (expression), conversion with one argument
5334 ///               ::= cv <type> _ <expression>* E                  # type (expr-list), conversion with other than one argument
5335 ///               ::= tl <type> <expression>* E                    # type {expr-list}, conversion with braced-init-list argument
5336 ///               ::= il <expression> E                            # {expr-list}, braced-init-list in any other context
5337 ///               ::= [gs] nw <expression>* _ <type> E             # new (expr-list) type
5338 ///               ::= [gs] nw <expression>* _ <type> <initializer> # new (expr-list) type (init)
5339 ///               ::= [gs] na <expression>* _ <type> E             # new[] (expr-list) type
5340 ///               ::= [gs] na <expression>* _ <type> <initializer> # new[] (expr-list) type (init)
5341 ///               ::= [gs] dl <expression>                         # delete expression
5342 ///               ::= [gs] da <expression>                         # delete[] expression
5343 ///               ::= dc <type> <expression>                       # dynamic_cast<type> (expression)
5344 ///               ::= sc <type> <expression>                       # static_cast<type> (expression)
5345 ///               ::= cc <type> <expression>                       # const_cast<type> (expression)
5346 ///               ::= rc <type> <expression>                       # reinterpret_cast<type> (expression)
5347 ///               ::= ti <type>                                    # typeid (type)
5348 ///               ::= te <expression>                              # typeid (expression)
5349 ///               ::= st <type>                                    # sizeof (type)
5350 ///               ::= sz <expression>                              # sizeof (expression)
5351 ///               ::= at <type>                                    # alignof (type)
5352 ///               ::= az <expression>                              # alignof (expression)
5353 ///               ::= nx <expression>                              # noexcept (expression)
5354 ///               ::= <template-param>
5355 ///               ::= <function-param>
5356 ///               ::= dt <expression> <unresolved-name>            # expr.name
5357 ///               ::= pt <expression> <unresolved-name>            # expr->name
5358 ///               ::= ds <expression> <expression>                 # expr.*expr
5359 ///               ::= sZ <template-param>                          # sizeof...(T), size of a template parameter pack
5360 ///               ::= sZ <function-param>                          # sizeof...(parameter), size of a function parameter pack
5361 ///               ::= sP <template-arg>* E                         # sizeof...(T), size of a captured template parameter pack from an alias template
5362 ///               ::= sp <expression>                              # expression..., pack expansion
5363 ///               ::= tw <expression>                              # throw expression
5364 ///               ::= tr                                           # throw with no operand (rethrow)
5365 ///               ::= <unresolved-name>                            # f(p), N::f(p), ::f(p),
5366 ///                                                                # freestanding dependent name (e.g., T::x),
5367 ///                                                                # objectless nonstatic member reference
5368 ///               ::= <expr-primary>
5369 /// ```
5370 #[derive(Clone, Debug, PartialEq, Eq)]
5371 pub enum Expression {
5372     /// A unary operator expression.
5373     Unary(OperatorName, Box<Expression>),
5374 
5375     /// A binary operator expression.
5376     Binary(OperatorName, Box<Expression>, Box<Expression>),
5377 
5378     /// A ternary operator expression.
5379     Ternary(
5380         OperatorName,
5381         Box<Expression>,
5382         Box<Expression>,
5383         Box<Expression>,
5384     ),
5385 
5386     /// A prefix `++`.
5387     PrefixInc(Box<Expression>),
5388 
5389     /// A prefix `--`.
5390     PrefixDec(Box<Expression>),
5391 
5392     /// A call with functor and arguments.
5393     Call(Box<Expression>, Vec<Expression>),
5394 
5395     /// A type conversion with one argument.
5396     ConversionOne(TypeHandle, Box<Expression>),
5397 
5398     /// A type conversion with many arguments.
5399     ConversionMany(TypeHandle, Vec<Expression>),
5400 
5401     /// A type conversion with many arguments.
5402     ConversionBraced(TypeHandle, Vec<Expression>),
5403 
5404     /// A braced init list expression.
5405     BracedInitList(Box<Expression>),
5406 
5407     /// The `new` operator.
5408     New(Vec<Expression>, TypeHandle, Option<Initializer>),
5409 
5410     /// The global `::new` operator.
5411     GlobalNew(Vec<Expression>, TypeHandle, Option<Initializer>),
5412 
5413     /// The `new[]` operator.
5414     NewArray(Vec<Expression>, TypeHandle, Option<Initializer>),
5415 
5416     /// The global `::new[]` operator.
5417     GlobalNewArray(Vec<Expression>, TypeHandle, Option<Initializer>),
5418 
5419     /// The `delete` operator.
5420     Delete(Box<Expression>),
5421 
5422     /// The global `::delete` operator.
5423     GlobalDelete(Box<Expression>),
5424 
5425     /// The `delete[]` operator.
5426     DeleteArray(Box<Expression>),
5427 
5428     /// The global `::delete[]` operator.
5429     GlobalDeleteArray(Box<Expression>),
5430 
5431     /// `dynamic_cast<type> (expression)`
5432     DynamicCast(TypeHandle, Box<Expression>),
5433 
5434     /// `static_cast<type> (expression)`
5435     StaticCast(TypeHandle, Box<Expression>),
5436 
5437     /// `const_cast<type> (expression)`
5438     ConstCast(TypeHandle, Box<Expression>),
5439 
5440     /// `reinterpret_cast<type> (expression)`
5441     ReinterpretCast(TypeHandle, Box<Expression>),
5442 
5443     /// `typeid (type)`
5444     TypeidType(TypeHandle),
5445 
5446     /// `typeid (expression)`
5447     TypeidExpr(Box<Expression>),
5448 
5449     /// `sizeof (type)`
5450     SizeofType(TypeHandle),
5451 
5452     /// `sizeof (expression)`
5453     SizeofExpr(Box<Expression>),
5454 
5455     /// `alignof (type)`
5456     AlignofType(TypeHandle),
5457 
5458     /// `alignof (expression)`
5459     AlignofExpr(Box<Expression>),
5460 
5461     /// `noexcept (expression)`
5462     Noexcept(Box<Expression>),
5463 
5464     /// A named template parameter.
5465     TemplateParam(TemplateParam),
5466 
5467     /// A function parameter.
5468     FunctionParam(FunctionParam),
5469 
5470     /// `expr.name`
5471     Member(Box<Expression>, MemberName),
5472 
5473     /// `expr->name`
5474     DerefMember(Box<Expression>, MemberName),
5475 
5476     /// `expr.*expr`
5477     PointerToMember(Box<Expression>, Box<Expression>),
5478 
5479     /// `sizeof...(T)`, size of a template parameter pack.
5480     SizeofTemplatePack(TemplateParam),
5481 
5482     /// `sizeof...(parameter)`, size of a function parameter pack.
5483     SizeofFunctionPack(FunctionParam),
5484 
5485     /// `sizeof...(T)`, size of a captured template parameter pack from an alias
5486     /// template.
5487     SizeofCapturedTemplatePack(Vec<TemplateArg>),
5488 
5489     /// `expression...`, pack expansion.
5490     PackExpansion(Box<Expression>),
5491 
5492     /// `throw expression`
5493     Throw(Box<Expression>),
5494 
5495     /// `throw` with no operand
5496     Rethrow,
5497 
5498     /// `f(p)`, `N::f(p)`, `::f(p)`, freestanding dependent name (e.g., `T::x`),
5499     /// objectless nonstatic member reference.
5500     UnresolvedName(UnresolvedName),
5501 
5502     /// An `<expr-primary>` production.
5503     Primary(ExprPrimary),
5504 }
5505 
5506 impl Parse for Expression {
parse<'a, 'b>( ctx: &'a ParseContext, subs: &'a mut SubstitutionTable, input: IndexStr<'b>, ) -> Result<(Expression, IndexStr<'b>)>5507     fn parse<'a, 'b>(
5508         ctx: &'a ParseContext,
5509         subs: &'a mut SubstitutionTable,
5510         input: IndexStr<'b>,
5511     ) -> Result<(Expression, IndexStr<'b>)> {
5512         try_begin_parse!("Expression", ctx, input);
5513 
5514         if let Ok(tail) = consume(b"pp_", input) {
5515             let (expr, tail) = Expression::parse(ctx, subs, tail)?;
5516             let expr = Expression::PrefixInc(Box::new(expr));
5517             return Ok((expr, tail));
5518         }
5519 
5520         if let Ok(tail) = consume(b"mm_", input) {
5521             let (expr, tail) = Expression::parse(ctx, subs, tail)?;
5522             let expr = Expression::PrefixDec(Box::new(expr));
5523             return Ok((expr, tail));
5524         }
5525 
5526         if let Some((head, tail)) = input.try_split_at(2) {
5527             match head.as_ref() {
5528                 b"cl" => {
5529                     let (func, tail) = Expression::parse(ctx, subs, tail)?;
5530                     let (args, tail) = zero_or_more::<Expression>(ctx, subs, tail)?;
5531                     let tail = consume(b"E", tail)?;
5532                     let expr = Expression::Call(Box::new(func), args);
5533                     return Ok((expr, tail));
5534                 }
5535                 b"cv" => {
5536                     let (ty, tail) = TypeHandle::parse(ctx, subs, tail)?;
5537                     if let Ok(tail) = consume(b"_", tail) {
5538                         let (exprs, tail) = zero_or_more::<Expression>(ctx, subs, tail)?;
5539                         let tail = consume(b"E", tail)?;
5540                         let expr = Expression::ConversionMany(ty, exprs);
5541                         return Ok((expr, tail));
5542                     } else {
5543                         let (expr, tail) = Expression::parse(ctx, subs, tail)?;
5544                         let expr = Expression::ConversionOne(ty, Box::new(expr));
5545                         return Ok((expr, tail));
5546                     }
5547                 }
5548                 b"tl" => {
5549                     let (ty, tail) = TypeHandle::parse(ctx, subs, tail)?;
5550                     let (exprs, tail) = zero_or_more::<Expression>(ctx, subs, tail)?;
5551                     let expr = Expression::ConversionBraced(ty, exprs);
5552                     let tail = consume(b"E", tail)?;
5553                     return Ok((expr, tail));
5554                 }
5555                 b"il" => {
5556                     let (expr, tail) = Expression::parse(ctx, subs, tail)?;
5557                     let tail = consume(b"E", tail)?;
5558                     let expr = Expression::BracedInitList(Box::new(expr));
5559                     return Ok((expr, tail));
5560                 }
5561                 b"dc" => {
5562                     let (ty, tail) = TypeHandle::parse(ctx, subs, tail)?;
5563                     let (expr, tail) = Expression::parse(ctx, subs, tail)?;
5564                     let expr = Expression::DynamicCast(ty, Box::new(expr));
5565                     return Ok((expr, tail));
5566                 }
5567                 b"sc" => {
5568                     let (ty, tail) = TypeHandle::parse(ctx, subs, tail)?;
5569                     let (expr, tail) = Expression::parse(ctx, subs, tail)?;
5570                     let expr = Expression::StaticCast(ty, Box::new(expr));
5571                     return Ok((expr, tail));
5572                 }
5573                 b"cc" => {
5574                     let (ty, tail) = TypeHandle::parse(ctx, subs, tail)?;
5575                     let (expr, tail) = Expression::parse(ctx, subs, tail)?;
5576                     let expr = Expression::ConstCast(ty, Box::new(expr));
5577                     return Ok((expr, tail));
5578                 }
5579                 b"rc" => {
5580                     let (ty, tail) = TypeHandle::parse(ctx, subs, tail)?;
5581                     let (expr, tail) = Expression::parse(ctx, subs, tail)?;
5582                     let expr = Expression::ReinterpretCast(ty, Box::new(expr));
5583                     return Ok((expr, tail));
5584                 }
5585                 b"ti" => {
5586                     let (ty, tail) = TypeHandle::parse(ctx, subs, tail)?;
5587                     let expr = Expression::TypeidType(ty);
5588                     return Ok((expr, tail));
5589                 }
5590                 b"te" => {
5591                     let (expr, tail) = Expression::parse(ctx, subs, tail)?;
5592                     let expr = Expression::TypeidExpr(Box::new(expr));
5593                     return Ok((expr, tail));
5594                 }
5595                 b"st" => {
5596                     let (ty, tail) = TypeHandle::parse(ctx, subs, tail)?;
5597                     let expr = Expression::SizeofType(ty);
5598                     return Ok((expr, tail));
5599                 }
5600                 b"sz" => {
5601                     let (expr, tail) = Expression::parse(ctx, subs, tail)?;
5602                     let expr = Expression::SizeofExpr(Box::new(expr));
5603                     return Ok((expr, tail));
5604                 }
5605                 b"at" => {
5606                     let (ty, tail) = TypeHandle::parse(ctx, subs, tail)?;
5607                     let expr = Expression::AlignofType(ty);
5608                     return Ok((expr, tail));
5609                 }
5610                 b"az" => {
5611                     let (expr, tail) = Expression::parse(ctx, subs, tail)?;
5612                     let expr = Expression::AlignofExpr(Box::new(expr));
5613                     return Ok((expr, tail));
5614                 }
5615                 b"nx" => {
5616                     let (expr, tail) = Expression::parse(ctx, subs, tail)?;
5617                     let expr = Expression::Noexcept(Box::new(expr));
5618                     return Ok((expr, tail));
5619                 }
5620                 b"dt" => {
5621                     let (expr, tail) = Expression::parse(ctx, subs, tail)?;
5622                     let (name, tail) = MemberName::parse(ctx, subs, tail)?;
5623                     let expr = Expression::Member(Box::new(expr), name);
5624                     return Ok((expr, tail));
5625                 }
5626                 b"pt" => {
5627                     let (expr, tail) = Expression::parse(ctx, subs, tail)?;
5628                     let (name, tail) = MemberName::parse(ctx, subs, tail)?;
5629                     let expr = Expression::DerefMember(Box::new(expr), name);
5630                     return Ok((expr, tail));
5631                 }
5632                 b"ds" => {
5633                     let (first, tail) = Expression::parse(ctx, subs, tail)?;
5634                     let (second, tail) = Expression::parse(ctx, subs, tail)?;
5635                     let expr = Expression::PointerToMember(Box::new(first), Box::new(second));
5636                     return Ok((expr, tail));
5637                 }
5638                 b"sZ" => {
5639                     if let Ok((param, tail)) = TemplateParam::parse(ctx, subs, tail) {
5640                         let expr = Expression::SizeofTemplatePack(param);
5641                         return Ok((expr, tail));
5642                     }
5643 
5644                     let (param, tail) = FunctionParam::parse(ctx, subs, tail)?;
5645                     let expr = Expression::SizeofFunctionPack(param);
5646                     return Ok((expr, tail));
5647                 }
5648                 b"sP" => {
5649                     let (args, tail) = zero_or_more::<TemplateArg>(ctx, subs, tail)?;
5650                     let expr = Expression::SizeofCapturedTemplatePack(args);
5651                     let tail = consume(b"E", tail)?;
5652                     return Ok((expr, tail));
5653                 }
5654                 b"sp" => {
5655                     let (expr, tail) = Expression::parse(ctx, subs, tail)?;
5656                     let expr = Expression::PackExpansion(Box::new(expr));
5657                     return Ok((expr, tail));
5658                 }
5659                 b"tw" => {
5660                     let (expr, tail) = Expression::parse(ctx, subs, tail)?;
5661                     let expr = Expression::Throw(Box::new(expr));
5662                     return Ok((expr, tail));
5663                 }
5664                 b"tr" => {
5665                     let expr = Expression::Rethrow;
5666                     return Ok((expr, tail));
5667                 }
5668                 b"gs" => {
5669                     if let Ok((expr, tail)) = can_be_global(true, ctx, subs, tail) {
5670                         return Ok((expr, tail));
5671                     }
5672                 }
5673                 _ => {}
5674             }
5675         }
5676 
5677         if let Ok((expr, tail)) = can_be_global(false, ctx, subs, input) {
5678             return Ok((expr, tail));
5679         }
5680 
5681         if let Ok((param, tail)) = TemplateParam::parse(ctx, subs, input) {
5682             let expr = Expression::TemplateParam(param);
5683             return Ok((expr, tail));
5684         }
5685 
5686         if let Ok((param, tail)) = FunctionParam::parse(ctx, subs, input) {
5687             let expr = Expression::FunctionParam(param);
5688             return Ok((expr, tail));
5689         }
5690 
5691         if let Ok((name, tail)) = UnresolvedName::parse(ctx, subs, input) {
5692             let expr = Expression::UnresolvedName(name);
5693             return Ok((expr, tail));
5694         }
5695 
5696         if let Ok((prim, tail)) = ExprPrimary::parse(ctx, subs, input) {
5697             let expr = Expression::Primary(prim);
5698             return Ok((expr, tail));
5699         }
5700 
5701         // "A production for <expression> that directly specifies an operation
5702         // code (e.g., for the -> operator) takes precedence over one that is
5703         // expressed in terms of (unary/binary/ternary) <operator-name>." So try
5704         // and parse unary/binary/ternary expressions last.
5705         let (expr, tail) = OperatorName::parse_from_expr(ctx, subs, input)?;
5706         return Ok((expr, tail));
5707 
5708         // Parse the various expressions that can optionally have a leading "gs"
5709         // to indicate that they are in the global namespace. The input is after
5710         // we have already detected consumed the optional "gs" and if we did
5711         // find it, then `is_global` should be true.
5712         fn can_be_global<'a, 'b>(
5713             is_global: bool,
5714             ctx: &'a ParseContext,
5715             subs: &'a mut SubstitutionTable,
5716             input: IndexStr<'b>,
5717         ) -> Result<(Expression, IndexStr<'b>)> {
5718             match input.try_split_at(2) {
5719                 None => Err(error::Error::UnexpectedEnd),
5720                 Some((head, tail)) => match head.as_ref() {
5721                     b"nw" => {
5722                         let (exprs, tail) = zero_or_more::<Expression>(ctx, subs, tail)?;
5723                         let tail = consume(b"_", tail)?;
5724                         let (ty, tail) = TypeHandle::parse(ctx, subs, tail)?;
5725                         if let Ok(tail) = consume(b"E", tail) {
5726                             let expr = if is_global {
5727                                 Expression::GlobalNew(exprs, ty, None)
5728                             } else {
5729                                 Expression::New(exprs, ty, None)
5730                             };
5731                             Ok((expr, tail))
5732                         } else {
5733                             let (init, tail) = Initializer::parse(ctx, subs, tail)?;
5734                             let expr = if is_global {
5735                                 Expression::GlobalNew(exprs, ty, Some(init))
5736                             } else {
5737                                 Expression::New(exprs, ty, Some(init))
5738                             };
5739                             Ok((expr, tail))
5740                         }
5741                     }
5742                     b"na" => {
5743                         let (exprs, tail) = zero_or_more::<Expression>(ctx, subs, tail)?;
5744                         let tail = consume(b"_", tail)?;
5745                         let (ty, tail) = TypeHandle::parse(ctx, subs, tail)?;
5746                         if let Ok(tail) = consume(b"E", tail) {
5747                             let expr = if is_global {
5748                                 Expression::GlobalNewArray(exprs, ty, None)
5749                             } else {
5750                                 Expression::NewArray(exprs, ty, None)
5751                             };
5752                             Ok((expr, tail))
5753                         } else {
5754                             let (init, tail) = Initializer::parse(ctx, subs, tail)?;
5755                             let expr = if is_global {
5756                                 Expression::GlobalNewArray(exprs, ty, Some(init))
5757                             } else {
5758                                 Expression::NewArray(exprs, ty, Some(init))
5759                             };
5760                             Ok((expr, tail))
5761                         }
5762                     }
5763                     b"dl" => {
5764                         let (expr, tail) = Expression::parse(ctx, subs, tail)?;
5765                         let expr = if is_global {
5766                             Expression::GlobalDelete(Box::new(expr))
5767                         } else {
5768                             Expression::Delete(Box::new(expr))
5769                         };
5770                         Ok((expr, tail))
5771                     }
5772                     b"da" => {
5773                         let (expr, tail) = Expression::parse(ctx, subs, tail)?;
5774                         let expr = if is_global {
5775                             Expression::GlobalDeleteArray(Box::new(expr))
5776                         } else {
5777                             Expression::DeleteArray(Box::new(expr))
5778                         };
5779                         Ok((expr, tail))
5780                     }
5781                     _ => Err(error::Error::UnexpectedText),
5782                 },
5783             }
5784         }
5785     }
5786 }
5787 
5788 impl<'subs, W> Demangle<'subs, W> for Expression
5789 where
5790     W: 'subs + DemangleWrite,
5791 {
demangle<'prev, 'ctx>( &'subs self, ctx: &'ctx mut DemangleContext<'subs, W>, scope: Option<ArgScopeStack<'prev, 'subs>>, ) -> fmt::Result5792     fn demangle<'prev, 'ctx>(
5793         &'subs self,
5794         ctx: &'ctx mut DemangleContext<'subs, W>,
5795         scope: Option<ArgScopeStack<'prev, 'subs>>,
5796     ) -> fmt::Result {
5797         let ctx = try_begin_demangle!(self, ctx, scope);
5798 
5799         match *self {
5800             Expression::Unary(OperatorName::Simple(ref op), ref expr)
5801                 if *op == SimpleOperatorName::PostInc || *op == SimpleOperatorName::PostDec =>
5802             {
5803                 expr.demangle_as_subexpr(ctx, scope)?;
5804                 op.demangle(ctx, scope)
5805             }
5806             Expression::Unary(ref op, ref expr) => {
5807                 op.demangle(ctx, scope)?;
5808                 expr.demangle_as_subexpr(ctx, scope)
5809             }
5810             // These need an extra set of parens so that it doesn't close any
5811             // template argument accidentally.
5812             Expression::Binary(
5813                 OperatorName::Simple(SimpleOperatorName::Greater),
5814                 ref lhs,
5815                 ref rhs,
5816             ) => {
5817                 write!(ctx, "((")?;
5818                 lhs.demangle(ctx, scope)?;
5819                 write!(ctx, ")>(")?;
5820                 rhs.demangle(ctx, scope)?;
5821                 write!(ctx, "))")
5822             }
5823             Expression::Binary(ref op, ref lhs, ref rhs) => {
5824                 lhs.demangle_as_subexpr(ctx, scope)?;
5825                 op.demangle(ctx, scope)?;
5826                 rhs.demangle_as_subexpr(ctx, scope)
5827             }
5828             Expression::Ternary(
5829                 OperatorName::Simple(SimpleOperatorName::Question),
5830                 ref condition,
5831                 ref consequent,
5832                 ref alternative,
5833             ) => {
5834                 condition.demangle_as_subexpr(ctx, scope)?;
5835                 write!(ctx, "?")?;
5836                 consequent.demangle_as_subexpr(ctx, scope)?;
5837                 write!(ctx, " : ")?;
5838                 alternative.demangle_as_subexpr(ctx, scope)
5839             }
5840             Expression::Ternary(ref op, ref e1, ref e2, ref e3) => {
5841                 // Nonsensical ternary operator? Just print it like a function call,
5842                 // I suppose...
5843                 //
5844                 // TODO: should we detect and reject this during parsing?
5845                 op.demangle(ctx, scope)?;
5846                 write!(ctx, "(")?;
5847                 e1.demangle(ctx, scope)?;
5848                 write!(ctx, ", ")?;
5849                 e2.demangle(ctx, scope)?;
5850                 write!(ctx, ", ")?;
5851                 e3.demangle(ctx, scope)?;
5852                 write!(ctx, ")")?;
5853                 Ok(())
5854             }
5855             Expression::PrefixInc(ref expr) => {
5856                 write!(ctx, "++")?;
5857                 expr.demangle(ctx, scope)
5858             }
5859             Expression::PrefixDec(ref expr) => {
5860                 write!(ctx, "--")?;
5861                 expr.demangle(ctx, scope)
5862             }
5863             Expression::Call(ref functor_expr, ref args) => {
5864                 functor_expr.demangle_as_subexpr(ctx, scope)?;
5865                 write!(ctx, "(")?;
5866                 let mut need_comma = false;
5867                 for arg in args {
5868                     if need_comma {
5869                         write!(ctx, ", ")?;
5870                     }
5871                     arg.demangle(ctx, scope)?;
5872                     need_comma = true;
5873                 }
5874                 write!(ctx, ")")?;
5875                 Ok(())
5876             }
5877             Expression::ConversionOne(ref ty, ref expr) => {
5878                 write!(ctx, "(")?;
5879                 ty.demangle(ctx, scope)?;
5880                 write!(ctx, ")(")?;
5881                 expr.demangle(ctx, scope)?;
5882                 write!(ctx, ")")?;
5883                 Ok(())
5884             }
5885             Expression::ConversionMany(ref ty, ref exprs) => {
5886                 ty.demangle(ctx, scope)?;
5887                 write!(ctx, "(")?;
5888                 let mut need_comma = false;
5889                 for expr in exprs {
5890                     if need_comma {
5891                         write!(ctx, ", ")?;
5892                     }
5893                     expr.demangle(ctx, scope)?;
5894                     need_comma = true;
5895                 }
5896                 write!(ctx, ")")?;
5897                 Ok(())
5898             }
5899             Expression::ConversionBraced(ref ty, ref exprs) => {
5900                 ty.demangle(ctx, scope)?;
5901                 write!(ctx, "{{")?;
5902                 let mut need_comma = false;
5903                 for expr in exprs {
5904                     if need_comma {
5905                         write!(ctx, ", ")?;
5906                     }
5907                     expr.demangle(ctx, scope)?;
5908                     need_comma = true;
5909                 }
5910                 write!(ctx, "}}")?;
5911                 Ok(())
5912             }
5913             Expression::BracedInitList(ref expr) => {
5914                 write!(ctx, "{{")?;
5915                 expr.demangle(ctx, scope)?;
5916                 write!(ctx, "}}")?;
5917                 Ok(())
5918             }
5919             // TODO: factor out all this duplication in the `new` variants.
5920             Expression::New(ref exprs, ref ty, ref init) => {
5921                 write!(ctx, "new (")?;
5922                 let mut need_comma = false;
5923                 for expr in exprs {
5924                     if need_comma {
5925                         write!(ctx, ", ")?;
5926                     }
5927                     expr.demangle(ctx, scope)?;
5928                     need_comma = true;
5929                 }
5930                 write!(ctx, ") ")?;
5931                 ty.demangle(ctx, scope)?;
5932                 if let Some(ref init) = *init {
5933                     init.demangle(ctx, scope)?;
5934                 }
5935                 Ok(())
5936             }
5937             Expression::GlobalNew(ref exprs, ref ty, ref init) => {
5938                 write!(ctx, "::new (")?;
5939                 let mut need_comma = false;
5940                 for expr in exprs {
5941                     if need_comma {
5942                         write!(ctx, ", ")?;
5943                     }
5944                     expr.demangle(ctx, scope)?;
5945                     need_comma = true;
5946                 }
5947                 write!(ctx, ") ")?;
5948                 ty.demangle(ctx, scope)?;
5949                 if let Some(ref init) = *init {
5950                     init.demangle(ctx, scope)?;
5951                 }
5952                 Ok(())
5953             }
5954             Expression::NewArray(ref exprs, ref ty, ref init) => {
5955                 write!(ctx, "new[] (")?;
5956                 let mut need_comma = false;
5957                 for expr in exprs {
5958                     if need_comma {
5959                         write!(ctx, ", ")?;
5960                     }
5961                     expr.demangle(ctx, scope)?;
5962                     need_comma = true;
5963                 }
5964                 write!(ctx, ") ")?;
5965                 ty.demangle(ctx, scope)?;
5966                 if let Some(ref init) = *init {
5967                     init.demangle(ctx, scope)?;
5968                 }
5969                 Ok(())
5970             }
5971             Expression::GlobalNewArray(ref exprs, ref ty, ref init) => {
5972                 write!(ctx, "::new[] (")?;
5973                 let mut need_comma = false;
5974                 for expr in exprs {
5975                     if need_comma {
5976                         write!(ctx, ", ")?;
5977                     }
5978                     expr.demangle(ctx, scope)?;
5979                     need_comma = true;
5980                 }
5981                 write!(ctx, ") ")?;
5982                 ty.demangle(ctx, scope)?;
5983                 if let Some(ref init) = *init {
5984                     init.demangle(ctx, scope)?;
5985                 }
5986                 Ok(())
5987             }
5988             Expression::Delete(ref expr) => {
5989                 write!(ctx, "delete ")?;
5990                 expr.demangle(ctx, scope)
5991             }
5992             Expression::GlobalDelete(ref expr) => {
5993                 write!(ctx, "::delete ")?;
5994                 expr.demangle(ctx, scope)
5995             }
5996             Expression::DeleteArray(ref expr) => {
5997                 write!(ctx, "delete[] ")?;
5998                 expr.demangle(ctx, scope)
5999             }
6000             Expression::GlobalDeleteArray(ref expr) => {
6001                 write!(ctx, "::delete[] ")?;
6002                 expr.demangle(ctx, scope)
6003             }
6004             // TODO: factor out duplicated code from cast variants.
6005             Expression::DynamicCast(ref ty, ref expr) => {
6006                 write!(ctx, "dynamic_cast<")?;
6007                 ty.demangle(ctx, scope)?;
6008                 write!(ctx, ">(")?;
6009                 expr.demangle(ctx, scope)?;
6010                 write!(ctx, ")")?;
6011                 Ok(())
6012             }
6013             Expression::StaticCast(ref ty, ref expr) => {
6014                 write!(ctx, "static_cast<")?;
6015                 ty.demangle(ctx, scope)?;
6016                 write!(ctx, ">(")?;
6017                 expr.demangle(ctx, scope)?;
6018                 write!(ctx, ")")?;
6019                 Ok(())
6020             }
6021             Expression::ConstCast(ref ty, ref expr) => {
6022                 write!(ctx, "const_cast<")?;
6023                 ty.demangle(ctx, scope)?;
6024                 write!(ctx, ">(")?;
6025                 expr.demangle(ctx, scope)?;
6026                 write!(ctx, ")")?;
6027                 Ok(())
6028             }
6029             Expression::ReinterpretCast(ref ty, ref expr) => {
6030                 write!(ctx, "reinterpret_cast<")?;
6031                 ty.demangle(ctx, scope)?;
6032                 write!(ctx, ">(")?;
6033                 expr.demangle(ctx, scope)?;
6034                 write!(ctx, ")")?;
6035                 Ok(())
6036             }
6037             Expression::TypeidType(ref ty) => {
6038                 write!(ctx, "typeid (")?;
6039                 ty.demangle(ctx, scope)?;
6040                 write!(ctx, ")")?;
6041                 Ok(())
6042             }
6043             Expression::TypeidExpr(ref expr) => {
6044                 write!(ctx, "typeid (")?;
6045                 expr.demangle(ctx, scope)?;
6046                 write!(ctx, ")")?;
6047                 Ok(())
6048             }
6049             Expression::SizeofType(ref ty) => {
6050                 write!(ctx, "sizeof (")?;
6051                 ty.demangle(ctx, scope)?;
6052                 write!(ctx, ")")?;
6053                 Ok(())
6054             }
6055             Expression::SizeofExpr(ref expr) => {
6056                 write!(ctx, "sizeof (")?;
6057                 expr.demangle(ctx, scope)?;
6058                 write!(ctx, ")")?;
6059                 Ok(())
6060             }
6061             Expression::AlignofType(ref ty) => {
6062                 write!(ctx, "alignof (")?;
6063                 ty.demangle(ctx, scope)?;
6064                 write!(ctx, ")")?;
6065                 Ok(())
6066             }
6067             Expression::AlignofExpr(ref expr) => {
6068                 write!(ctx, "alignof (")?;
6069                 expr.demangle(ctx, scope)?;
6070                 write!(ctx, ")")?;
6071                 Ok(())
6072             }
6073             Expression::Noexcept(ref expr) => {
6074                 write!(ctx, "noexcept (")?;
6075                 expr.demangle(ctx, scope)?;
6076                 write!(ctx, ")")?;
6077                 Ok(())
6078             }
6079             Expression::TemplateParam(ref param) => param.demangle(ctx, scope),
6080             Expression::FunctionParam(ref param) => param.demangle(ctx, scope),
6081             Expression::Member(ref expr, ref name) => {
6082                 expr.demangle_as_subexpr(ctx, scope)?;
6083                 write!(ctx, ".")?;
6084                 name.demangle(ctx, scope)
6085             }
6086             Expression::DerefMember(ref expr, ref name) => {
6087                 expr.demangle(ctx, scope)?;
6088                 write!(ctx, "->")?;
6089                 name.demangle(ctx, scope)
6090             }
6091             Expression::PointerToMember(ref e1, ref e2) => {
6092                 e1.demangle(ctx, scope)?;
6093                 write!(ctx, ".*")?;
6094                 e2.demangle(ctx, scope)
6095             }
6096             Expression::SizeofTemplatePack(ref param) => {
6097                 write!(ctx, "sizeof...(")?;
6098                 param.demangle(ctx, scope)?;
6099                 write!(ctx, ")")?;
6100                 Ok(())
6101             }
6102             Expression::SizeofFunctionPack(ref param) => {
6103                 write!(ctx, "sizeof...(")?;
6104                 param.demangle(ctx, scope)?;
6105                 write!(ctx, ")")?;
6106                 Ok(())
6107             }
6108             Expression::SizeofCapturedTemplatePack(ref args) => {
6109                 write!(ctx, "sizeof...(")?;
6110                 let mut need_comma = false;
6111                 for arg in args {
6112                     if need_comma {
6113                         write!(ctx, ", ")?;
6114                     }
6115                     arg.demangle(ctx, scope)?;
6116                     need_comma = true;
6117                 }
6118                 write!(ctx, ")")?;
6119                 Ok(())
6120             }
6121             Expression::PackExpansion(ref pack) => {
6122                 pack.demangle_as_subexpr(ctx, scope)?;
6123                 write!(ctx, "...")?;
6124                 Ok(())
6125             }
6126             Expression::Throw(ref expr) => {
6127                 write!(ctx, "throw ")?;
6128                 expr.demangle(ctx, scope)
6129             }
6130             Expression::Rethrow => {
6131                 write!(ctx, "throw")?;
6132                 Ok(())
6133             }
6134             Expression::UnresolvedName(ref name) => name.demangle(ctx, scope),
6135             Expression::Primary(ref expr) => expr.demangle(ctx, scope),
6136         }
6137     }
6138 }
6139 
6140 impl Expression {
demangle_as_subexpr<'subs, 'prev, 'ctx, W>( &'subs self, ctx: &'ctx mut DemangleContext<'subs, W>, scope: Option<ArgScopeStack<'prev, 'subs>>, ) -> fmt::Result where W: 'subs + DemangleWrite,6141     fn demangle_as_subexpr<'subs, 'prev, 'ctx, W>(
6142         &'subs self,
6143         ctx: &'ctx mut DemangleContext<'subs, W>,
6144         scope: Option<ArgScopeStack<'prev, 'subs>>,
6145     ) -> fmt::Result
6146     where
6147         W: 'subs + DemangleWrite,
6148     {
6149         let needs_parens = match *self {
6150             Expression::FunctionParam(_) | Expression::Primary(ExprPrimary::External(_)) => false,
6151             _ => true,
6152         };
6153 
6154         if needs_parens {
6155             write!(ctx, "(")?;
6156         }
6157 
6158         self.demangle(ctx, scope)?;
6159 
6160         if needs_parens {
6161             write!(ctx, ")")?;
6162         }
6163 
6164         Ok(())
6165     }
6166 }
6167 
6168 /// The `<unresolved-name>` production.
6169 ///
6170 /// ```text
6171 /// <unresolved-name> ::= [gs] <base-unresolved-name>
6172 ///                          #
6173 ///                   ::= sr <unresolved-type> <base-unresolved-name>
6174 ///                          #
6175 ///                   ::= srN <unresolved-type> <unresolved-qualifier-level>+ E <base-unresolved-name>
6176 ///                          #
6177 ///                   ::= [gs] sr <unresolved-qualifier-level>+ E <base-unresolved-name>
6178 ///                          # A::x, N::y, A<T>::z; "gs" means leading "::"
6179 /// ```
6180 #[derive(Clone, Debug, PartialEq, Eq)]
6181 pub enum UnresolvedName {
6182     /// `x`
6183     Name(BaseUnresolvedName),
6184 
6185     /// `::x`
6186     Global(BaseUnresolvedName),
6187 
6188     /// `T::x`  or `decltype(p)::x` or `T::N::x` or `decltype(p)::N::x`
6189     Nested1(
6190         UnresolvedTypeHandle,
6191         Vec<UnresolvedQualifierLevel>,
6192         BaseUnresolvedName,
6193     ),
6194 
6195     /// `A::x` or `N::y` or `A<T>::z`
6196     Nested2(Vec<UnresolvedQualifierLevel>, BaseUnresolvedName),
6197 
6198     /// `::A::x` or `::N::y` or `::A<T>::z`
6199     GlobalNested2(Vec<UnresolvedQualifierLevel>, BaseUnresolvedName),
6200 }
6201 
6202 impl Parse for UnresolvedName {
parse<'a, 'b>( ctx: &'a ParseContext, subs: &'a mut SubstitutionTable, input: IndexStr<'b>, ) -> Result<(UnresolvedName, IndexStr<'b>)>6203     fn parse<'a, 'b>(
6204         ctx: &'a ParseContext,
6205         subs: &'a mut SubstitutionTable,
6206         input: IndexStr<'b>,
6207     ) -> Result<(UnresolvedName, IndexStr<'b>)> {
6208         try_begin_parse!("UnresolvedName", ctx, input);
6209 
6210         if let Ok(tail) = consume(b"gs", input) {
6211             if let Ok((name, tail)) = BaseUnresolvedName::parse(ctx, subs, tail) {
6212                 return Ok((UnresolvedName::Global(name), tail));
6213             }
6214 
6215             let tail = consume(b"sr", tail)?;
6216             let (levels, tail) = one_or_more::<UnresolvedQualifierLevel>(ctx, subs, tail)?;
6217             let tail = consume(b"E", tail)?;
6218             let (name, tail) = BaseUnresolvedName::parse(ctx, subs, tail)?;
6219             return Ok((UnresolvedName::GlobalNested2(levels, name), tail));
6220         }
6221 
6222         if let Ok((name, tail)) = BaseUnresolvedName::parse(ctx, subs, input) {
6223             return Ok((UnresolvedName::Name(name), tail));
6224         }
6225 
6226         let tail = consume(b"sr", input)?;
6227 
6228         if tail.peek() == Some(b'N') {
6229             let tail = consume(b"N", tail).unwrap();
6230             let (ty, tail) = UnresolvedTypeHandle::parse(ctx, subs, tail)?;
6231             let (levels, tail) = one_or_more::<UnresolvedQualifierLevel>(ctx, subs, tail)?;
6232             let tail = consume(b"E", tail)?;
6233             let (name, tail) = BaseUnresolvedName::parse(ctx, subs, tail)?;
6234             return Ok((UnresolvedName::Nested1(ty, levels, name), tail));
6235         }
6236 
6237         if let Ok((ty, tail)) = UnresolvedTypeHandle::parse(ctx, subs, tail) {
6238             let (name, tail) = BaseUnresolvedName::parse(ctx, subs, tail)?;
6239             return Ok((UnresolvedName::Nested1(ty, vec![], name), tail));
6240         }
6241 
6242         let (levels, tail) = one_or_more::<UnresolvedQualifierLevel>(ctx, subs, tail)?;
6243         let tail = consume(b"E", tail)?;
6244         let (name, tail) = BaseUnresolvedName::parse(ctx, subs, tail)?;
6245         Ok((UnresolvedName::Nested2(levels, name), tail))
6246     }
6247 }
6248 
6249 impl<'subs, W> Demangle<'subs, W> for UnresolvedName
6250 where
6251     W: 'subs + DemangleWrite,
6252 {
demangle<'prev, 'ctx>( &'subs self, ctx: &'ctx mut DemangleContext<'subs, W>, scope: Option<ArgScopeStack<'prev, 'subs>>, ) -> fmt::Result6253     fn demangle<'prev, 'ctx>(
6254         &'subs self,
6255         ctx: &'ctx mut DemangleContext<'subs, W>,
6256         scope: Option<ArgScopeStack<'prev, 'subs>>,
6257     ) -> fmt::Result {
6258         let ctx = try_begin_demangle!(self, ctx, scope);
6259 
6260         match *self {
6261             UnresolvedName::Name(ref name) => name.demangle(ctx, scope),
6262             UnresolvedName::Global(ref name) => {
6263                 write!(ctx, "::")?;
6264                 name.demangle(ctx, scope)
6265             }
6266             UnresolvedName::Nested1(ref ty, ref levels, ref name) => {
6267                 ty.demangle(ctx, scope)?;
6268                 write!(ctx, "::")?;
6269                 for lvl in &levels[..] {
6270                     lvl.demangle(ctx, scope)?;
6271                     write!(ctx, "::")?;
6272                 }
6273                 name.demangle(ctx, scope)
6274             }
6275             UnresolvedName::Nested2(ref levels, ref name) => {
6276                 for lvl in &levels[..] {
6277                     lvl.demangle(ctx, scope)?;
6278                     write!(ctx, "::")?;
6279                 }
6280                 name.demangle(ctx, scope)
6281             }
6282             // `::A::x` or `::N::y` or `::A<T>::z`
6283             UnresolvedName::GlobalNested2(ref levels, ref name) => {
6284                 write!(ctx, "::")?;
6285                 for lvl in &levels[..] {
6286                     lvl.demangle(ctx, scope)?;
6287                     write!(ctx, "::")?;
6288                 }
6289                 name.demangle(ctx, scope)
6290             }
6291         }
6292     }
6293 }
6294 
6295 /// The `<unresolved-type>` production.
6296 ///
6297 /// ```text
6298 /// <unresolved-type> ::= <template-param> [ <template-args> ]  # T:: or T<X,Y>::
6299 ///                   ::= <decltype>                            # decltype(p)::
6300 ///                   ::= <substitution>
6301 /// ```
6302 #[derive(Clone, Debug, PartialEq, Eq)]
6303 pub enum UnresolvedType {
6304     /// An unresolved template type.
6305     Template(TemplateParam, Option<TemplateArgs>),
6306 
6307     /// An unresolved `decltype`.
6308     Decltype(Decltype),
6309 }
6310 
6311 define_handle! {
6312     /// A reference to a parsed `<unresolved-type>` production.
6313     pub enum UnresolvedTypeHandle
6314 }
6315 
6316 impl Parse for UnresolvedTypeHandle {
parse<'a, 'b>( ctx: &'a ParseContext, subs: &'a mut SubstitutionTable, input: IndexStr<'b>, ) -> Result<(UnresolvedTypeHandle, IndexStr<'b>)>6317     fn parse<'a, 'b>(
6318         ctx: &'a ParseContext,
6319         subs: &'a mut SubstitutionTable,
6320         input: IndexStr<'b>,
6321     ) -> Result<(UnresolvedTypeHandle, IndexStr<'b>)> {
6322         try_begin_parse!("UnresolvedTypeHandle", ctx, input);
6323 
6324         if let Ok((param, tail)) = TemplateParam::parse(ctx, subs, input) {
6325             let (args, tail) = if let Ok((args, tail)) = TemplateArgs::parse(ctx, subs, tail) {
6326                 (Some(args), tail)
6327             } else {
6328                 (None, tail)
6329             };
6330             let ty = UnresolvedType::Template(param, args);
6331             let ty = Substitutable::UnresolvedType(ty);
6332             let idx = subs.insert(ty);
6333             let handle = UnresolvedTypeHandle::BackReference(idx);
6334             return Ok((handle, tail));
6335         }
6336 
6337         if let Ok((decltype, tail)) = Decltype::parse(ctx, subs, input) {
6338             let ty = UnresolvedType::Decltype(decltype);
6339             let ty = Substitutable::UnresolvedType(ty);
6340             let idx = subs.insert(ty);
6341             let handle = UnresolvedTypeHandle::BackReference(idx);
6342             return Ok((handle, tail));
6343         }
6344 
6345         let (sub, tail) = Substitution::parse(ctx, subs, input)?;
6346         match sub {
6347             Substitution::WellKnown(component) => {
6348                 Ok((UnresolvedTypeHandle::WellKnown(component), tail))
6349             }
6350             Substitution::BackReference(idx) => {
6351                 // TODO: should this check that the back reference actually
6352                 // points to an `<unresolved-type>`?
6353                 Ok((UnresolvedTypeHandle::BackReference(idx), tail))
6354             }
6355         }
6356     }
6357 }
6358 
6359 impl<'subs, W> Demangle<'subs, W> for UnresolvedType
6360 where
6361     W: 'subs + DemangleWrite,
6362 {
demangle<'prev, 'ctx>( &'subs self, ctx: &'ctx mut DemangleContext<'subs, W>, scope: Option<ArgScopeStack<'prev, 'subs>>, ) -> fmt::Result6363     fn demangle<'prev, 'ctx>(
6364         &'subs self,
6365         ctx: &'ctx mut DemangleContext<'subs, W>,
6366         scope: Option<ArgScopeStack<'prev, 'subs>>,
6367     ) -> fmt::Result {
6368         let ctx = try_begin_demangle!(self, ctx, scope);
6369 
6370         match *self {
6371             UnresolvedType::Decltype(ref dt) => dt.demangle(ctx, scope),
6372             UnresolvedType::Template(ref param, ref args) => {
6373                 if let Some(ref args) = *args {
6374                     let scope = scope.push(args);
6375                     param.demangle(ctx, scope)?;
6376                     args.demangle(ctx, scope)?;
6377                 } else {
6378                     param.demangle(ctx, scope)?;
6379                 }
6380                 Ok(())
6381             }
6382         }
6383     }
6384 }
6385 
6386 /// The `<unresolved-qualifier-level>` production.
6387 ///
6388 /// ```text
6389 /// <unresolved-qualifier-level> ::= <simple-id>
6390 /// ```
6391 #[derive(Clone, Debug, PartialEq, Eq)]
6392 pub struct UnresolvedQualifierLevel(SimpleId);
6393 
6394 impl Parse for UnresolvedQualifierLevel {
parse<'a, 'b>( ctx: &'a ParseContext, subs: &'a mut SubstitutionTable, input: IndexStr<'b>, ) -> Result<(UnresolvedQualifierLevel, IndexStr<'b>)>6395     fn parse<'a, 'b>(
6396         ctx: &'a ParseContext,
6397         subs: &'a mut SubstitutionTable,
6398         input: IndexStr<'b>,
6399     ) -> Result<(UnresolvedQualifierLevel, IndexStr<'b>)> {
6400         try_begin_parse!("UnresolvedQualifierLevel", ctx, input);
6401 
6402         let (id, tail) = SimpleId::parse(ctx, subs, input)?;
6403         Ok((UnresolvedQualifierLevel(id), tail))
6404     }
6405 }
6406 
6407 impl<'subs, W> Demangle<'subs, W> for UnresolvedQualifierLevel
6408 where
6409     W: 'subs + DemangleWrite,
6410 {
6411     #[inline]
demangle<'prev, 'ctx>( &'subs self, ctx: &'ctx mut DemangleContext<'subs, W>, scope: Option<ArgScopeStack<'prev, 'subs>>, ) -> fmt::Result6412     fn demangle<'prev, 'ctx>(
6413         &'subs self,
6414         ctx: &'ctx mut DemangleContext<'subs, W>,
6415         scope: Option<ArgScopeStack<'prev, 'subs>>,
6416     ) -> fmt::Result {
6417         let ctx = try_begin_demangle!(self, ctx, scope);
6418 
6419         self.0.demangle(ctx, scope)
6420     }
6421 }
6422 
6423 /// The `<simple-id>` production.
6424 ///
6425 /// ```text
6426 /// <simple-id> ::= <source-name> [ <template-args> ]
6427 /// ```
6428 #[derive(Clone, Debug, PartialEq, Eq)]
6429 pub struct SimpleId(SourceName, Option<TemplateArgs>);
6430 
6431 impl Parse for SimpleId {
parse<'a, 'b>( ctx: &'a ParseContext, subs: &'a mut SubstitutionTable, input: IndexStr<'b>, ) -> Result<(SimpleId, IndexStr<'b>)>6432     fn parse<'a, 'b>(
6433         ctx: &'a ParseContext,
6434         subs: &'a mut SubstitutionTable,
6435         input: IndexStr<'b>,
6436     ) -> Result<(SimpleId, IndexStr<'b>)> {
6437         try_begin_parse!("SimpleId", ctx, input);
6438 
6439         let (name, tail) = SourceName::parse(ctx, subs, input)?;
6440         let (args, tail) = if let Ok((args, tail)) = TemplateArgs::parse(ctx, subs, tail) {
6441             (Some(args), tail)
6442         } else {
6443             (None, tail)
6444         };
6445         Ok((SimpleId(name, args), tail))
6446     }
6447 }
6448 
6449 impl<'subs, W> Demangle<'subs, W> for SimpleId
6450 where
6451     W: 'subs + DemangleWrite,
6452 {
demangle<'prev, 'ctx>( &'subs self, ctx: &'ctx mut DemangleContext<'subs, W>, scope: Option<ArgScopeStack<'prev, 'subs>>, ) -> fmt::Result6453     fn demangle<'prev, 'ctx>(
6454         &'subs self,
6455         ctx: &'ctx mut DemangleContext<'subs, W>,
6456         scope: Option<ArgScopeStack<'prev, 'subs>>,
6457     ) -> fmt::Result {
6458         let ctx = try_begin_demangle!(self, ctx, scope);
6459 
6460         self.0.demangle(ctx, scope)?;
6461         if let Some(ref args) = self.1 {
6462             args.demangle(ctx, scope)?;
6463         }
6464         Ok(())
6465     }
6466 }
6467 
6468 /// The `<base-unresolved-name>` production.
6469 ///
6470 /// ```text
6471 /// <base-unresolved-name> ::= <simple-id>                        # unresolved name
6472 ///                        ::= on <operator-name>                 # unresolved operator-function-id
6473 ///                        ::= on <operator-name> <template-args> # unresolved operator template-id
6474 ///                        ::= dn <destructor-name>               # destructor or pseudo-destructor;
6475 ///                                                               # e.g. ~X or ~X<N-1>
6476 /// ```
6477 #[derive(Clone, Debug, PartialEq, Eq)]
6478 pub enum BaseUnresolvedName {
6479     /// An unresolved name.
6480     Name(SimpleId),
6481 
6482     /// An unresolved function or template function name.
6483     Operator(OperatorName, Option<TemplateArgs>),
6484 
6485     /// An unresolved destructor name.
6486     Destructor(DestructorName),
6487 }
6488 
6489 impl Parse for BaseUnresolvedName {
parse<'a, 'b>( ctx: &'a ParseContext, subs: &'a mut SubstitutionTable, input: IndexStr<'b>, ) -> Result<(BaseUnresolvedName, IndexStr<'b>)>6490     fn parse<'a, 'b>(
6491         ctx: &'a ParseContext,
6492         subs: &'a mut SubstitutionTable,
6493         input: IndexStr<'b>,
6494     ) -> Result<(BaseUnresolvedName, IndexStr<'b>)> {
6495         try_begin_parse!("BaseUnresolvedName", ctx, input);
6496 
6497         if let Ok((name, tail)) = SimpleId::parse(ctx, subs, input) {
6498             return Ok((BaseUnresolvedName::Name(name), tail));
6499         }
6500 
6501         if let Ok(tail) = consume(b"on", input) {
6502             let (opname, tail) = OperatorName::parse(ctx, subs, tail)?;
6503             let (args, tail) = if let Ok((args, tail)) = TemplateArgs::parse(ctx, subs, tail) {
6504                 (Some(args), tail)
6505             } else {
6506                 (None, tail)
6507             };
6508             return Ok((BaseUnresolvedName::Operator(opname, args), tail));
6509         }
6510 
6511         let tail = consume(b"dn", input)?;
6512         let (name, tail) = DestructorName::parse(ctx, subs, tail)?;
6513         Ok((BaseUnresolvedName::Destructor(name), tail))
6514     }
6515 }
6516 
6517 impl<'subs, W> Demangle<'subs, W> for BaseUnresolvedName
6518 where
6519     W: 'subs + DemangleWrite,
6520 {
demangle<'prev, 'ctx>( &'subs self, ctx: &'ctx mut DemangleContext<'subs, W>, scope: Option<ArgScopeStack<'prev, 'subs>>, ) -> fmt::Result6521     fn demangle<'prev, 'ctx>(
6522         &'subs self,
6523         ctx: &'ctx mut DemangleContext<'subs, W>,
6524         scope: Option<ArgScopeStack<'prev, 'subs>>,
6525     ) -> fmt::Result {
6526         let ctx = try_begin_demangle!(self, ctx, scope);
6527 
6528         match *self {
6529             BaseUnresolvedName::Name(ref name) => name.demangle(ctx, scope),
6530             BaseUnresolvedName::Destructor(ref dtor) => dtor.demangle(ctx, scope),
6531             BaseUnresolvedName::Operator(ref op, ref args) => {
6532                 op.demangle(ctx, scope)?;
6533                 if let Some(ref args) = *args {
6534                     args.demangle(ctx, scope)?;
6535                 }
6536                 Ok(())
6537             }
6538         }
6539     }
6540 }
6541 
6542 /// The `<destructor-name>` production.
6543 ///
6544 /// ```text
6545 /// <destructor-name> ::= <unresolved-type> # e.g., ~T or ~decltype(f())
6546 ///                   ::= <simple-id>       # e.g., ~A<2*N>
6547 /// ```
6548 #[derive(Clone, Debug, PartialEq, Eq)]
6549 pub enum DestructorName {
6550     /// A destructor for an unresolved type.
6551     Unresolved(UnresolvedTypeHandle),
6552 
6553     /// A destructor for a resolved type name.
6554     Name(SimpleId),
6555 }
6556 
6557 impl Parse for DestructorName {
parse<'a, 'b>( ctx: &'a ParseContext, subs: &'a mut SubstitutionTable, input: IndexStr<'b>, ) -> Result<(DestructorName, IndexStr<'b>)>6558     fn parse<'a, 'b>(
6559         ctx: &'a ParseContext,
6560         subs: &'a mut SubstitutionTable,
6561         input: IndexStr<'b>,
6562     ) -> Result<(DestructorName, IndexStr<'b>)> {
6563         try_begin_parse!("DestructorName", ctx, input);
6564 
6565         if let Ok((ty, tail)) = UnresolvedTypeHandle::parse(ctx, subs, input) {
6566             return Ok((DestructorName::Unresolved(ty), tail));
6567         }
6568 
6569         let (name, tail) = SimpleId::parse(ctx, subs, input)?;
6570         Ok((DestructorName::Name(name), tail))
6571     }
6572 }
6573 
6574 impl<'subs, W> Demangle<'subs, W> for DestructorName
6575 where
6576     W: 'subs + DemangleWrite,
6577 {
demangle<'prev, 'ctx>( &'subs self, ctx: &'ctx mut DemangleContext<'subs, W>, scope: Option<ArgScopeStack<'prev, 'subs>>, ) -> fmt::Result6578     fn demangle<'prev, 'ctx>(
6579         &'subs self,
6580         ctx: &'ctx mut DemangleContext<'subs, W>,
6581         scope: Option<ArgScopeStack<'prev, 'subs>>,
6582     ) -> fmt::Result {
6583         let ctx = try_begin_demangle!(self, ctx, scope);
6584 
6585         write!(ctx, "~")?;
6586         match *self {
6587             DestructorName::Unresolved(ref ty) => ty.demangle(ctx, scope),
6588             DestructorName::Name(ref name) => name.demangle(ctx, scope),
6589         }
6590     }
6591 }
6592 
6593 /// The `<expr-primary>` production.
6594 ///
6595 /// ```text
6596 /// <expr-primary> ::= L <type> <value number> E                        # integer literal
6597 ///                ::= L <type> <value float> E                         # floating literal
6598 ///                ::= L <string type> E                                # string literal
6599 ///                ::= L <nullptr type> E                               # nullptr literal (i.e., "LDnE")
6600 ///                ::= L <pointer type> 0 E                             # null pointer template argument
6601 ///                ::= L <type> <real-part float> _ <imag-part float> E # complex floating point literal (C 2000)
6602 ///                ::= L <mangled-name> E                               # external name
6603 /// ```
6604 #[derive(Clone, Debug, PartialEq, Eq)]
6605 pub enum ExprPrimary {
6606     /// A type literal.
6607     Literal(TypeHandle, usize, usize),
6608 
6609     /// An external name.
6610     External(MangledName),
6611 }
6612 
6613 impl Parse for ExprPrimary {
parse<'a, 'b>( ctx: &'a ParseContext, subs: &'a mut SubstitutionTable, input: IndexStr<'b>, ) -> Result<(ExprPrimary, IndexStr<'b>)>6614     fn parse<'a, 'b>(
6615         ctx: &'a ParseContext,
6616         subs: &'a mut SubstitutionTable,
6617         input: IndexStr<'b>,
6618     ) -> Result<(ExprPrimary, IndexStr<'b>)> {
6619         try_begin_parse!("ExprPrimary", ctx, input);
6620 
6621         let tail = consume(b"L", input)?;
6622 
6623         if let Ok((ty, tail)) = TypeHandle::parse(ctx, subs, tail) {
6624             let start = tail.index();
6625             let num_bytes_in_literal = tail.as_ref().iter().take_while(|&&c| c != b'E').count();
6626             let tail = tail.range_from(num_bytes_in_literal..);
6627             let end = tail.index();
6628             let tail = consume(b"E", tail)?;
6629             let expr = ExprPrimary::Literal(ty, start, end);
6630             return Ok((expr, tail));
6631         }
6632 
6633         let (name, tail) = MangledName::parse(ctx, subs, tail)?;
6634         let tail = consume(b"E", tail)?;
6635         let expr = ExprPrimary::External(name);
6636         Ok((expr, tail))
6637     }
6638 }
6639 
6640 impl<'subs, W> Demangle<'subs, W> for ExprPrimary
6641 where
6642     W: 'subs + DemangleWrite,
6643 {
demangle<'prev, 'ctx>( &'subs self, ctx: &'ctx mut DemangleContext<'subs, W>, scope: Option<ArgScopeStack<'prev, 'subs>>, ) -> fmt::Result6644     fn demangle<'prev, 'ctx>(
6645         &'subs self,
6646         ctx: &'ctx mut DemangleContext<'subs, W>,
6647         scope: Option<ArgScopeStack<'prev, 'subs>>,
6648     ) -> fmt::Result {
6649         let ctx = try_begin_demangle!(self, ctx, scope);
6650 
6651         fn write_literal<W>(ctx: &mut DemangleContext<W>, start: usize, end: usize) -> fmt::Result
6652         where
6653             W: DemangleWrite,
6654         {
6655             debug_assert!(start <= end);
6656             let start = if start < end && ctx.input[start] == b'n' {
6657                 write!(ctx, "-")?;
6658                 start + 1
6659             } else {
6660                 start
6661             };
6662             let s = ::std::str::from_utf8(&ctx.input[start..end]).map_err(|e| {
6663                 log!("Error writing literal: {}", e);
6664                 fmt::Error
6665             })?;
6666             ctx.write_str(s)
6667         }
6668 
6669         match *self {
6670             ExprPrimary::External(ref name) => {
6671                 let saved_show_params = ctx.show_params;
6672                 ctx.show_params = true;
6673                 let ret = name.demangle(ctx, scope);
6674                 ctx.show_params = saved_show_params;
6675                 ret
6676             }
6677             ExprPrimary::Literal(
6678                 TypeHandle::Builtin(BuiltinType::Standard(StandardBuiltinType::Bool)),
6679                 start,
6680                 end,
6681             ) => match &ctx.input[start..end] {
6682                 b"0" => write!(ctx, "false"),
6683                 b"1" => write!(ctx, "true"),
6684                 _ => {
6685                     write!(ctx, "(bool)")?;
6686                     write_literal(ctx, start, end)
6687                 }
6688             },
6689             ExprPrimary::Literal(
6690                 TypeHandle::Builtin(BuiltinType::Standard(StandardBuiltinType::Nullptr)),
6691                 _,
6692                 _,
6693             ) => write!(ctx, "nullptr"),
6694             ExprPrimary::Literal(
6695                 ref ty @ TypeHandle::Builtin(BuiltinType::Standard(StandardBuiltinType::Double)),
6696                 start,
6697                 end,
6698             )
6699             | ExprPrimary::Literal(
6700                 ref ty @ TypeHandle::Builtin(BuiltinType::Standard(StandardBuiltinType::Float)),
6701                 start,
6702                 end,
6703             ) => {
6704                 write!(ctx, "(")?;
6705                 ty.demangle(ctx, scope)?;
6706                 let start = if start < end && ctx.input[start] == b'n' {
6707                     write!(ctx, ")-[")?;
6708                     start + 1
6709                 } else {
6710                     write!(ctx, ")[")?;
6711                     start
6712                 };
6713                 let s = ::std::str::from_utf8(&ctx.input[start..end]).map_err(|e| {
6714                     log!("Error writing literal: {}", e);
6715                     fmt::Error
6716                 })?;
6717                 ctx.write_str(s)?;
6718                 write!(ctx, "]")
6719             }
6720             ExprPrimary::Literal(
6721                 TypeHandle::Builtin(BuiltinType::Standard(StandardBuiltinType::Int)),
6722                 start,
6723                 end,
6724             ) => write_literal(ctx, start, end),
6725             ExprPrimary::Literal(ref ty, start, end) => {
6726                 write!(ctx, "(")?;
6727                 ty.demangle(ctx, scope)?;
6728                 write!(ctx, ")")?;
6729                 write_literal(ctx, start, end)
6730             }
6731         }
6732     }
6733 }
6734 
6735 /// The `<initializer>` production.
6736 ///
6737 /// ```text
6738 /// <initializer> ::= pi <expression>* E # parenthesized initialization
6739 /// ```
6740 #[derive(Clone, Debug, PartialEq, Eq)]
6741 pub struct Initializer(Vec<Expression>);
6742 
6743 impl Parse for Initializer {
parse<'a, 'b>( ctx: &'a ParseContext, subs: &'a mut SubstitutionTable, input: IndexStr<'b>, ) -> Result<(Initializer, IndexStr<'b>)>6744     fn parse<'a, 'b>(
6745         ctx: &'a ParseContext,
6746         subs: &'a mut SubstitutionTable,
6747         input: IndexStr<'b>,
6748     ) -> Result<(Initializer, IndexStr<'b>)> {
6749         try_begin_parse!("Initializer", ctx, input);
6750 
6751         let tail = consume(b"pi", input)?;
6752         let (exprs, tail) = zero_or_more::<Expression>(ctx, subs, tail)?;
6753         let tail = consume(b"E", tail)?;
6754         Ok((Initializer(exprs), tail))
6755     }
6756 }
6757 
6758 impl<'subs, W> Demangle<'subs, W> for Initializer
6759 where
6760     W: 'subs + DemangleWrite,
6761 {
demangle<'prev, 'ctx>( &'subs self, ctx: &'ctx mut DemangleContext<'subs, W>, scope: Option<ArgScopeStack<'prev, 'subs>>, ) -> fmt::Result6762     fn demangle<'prev, 'ctx>(
6763         &'subs self,
6764         ctx: &'ctx mut DemangleContext<'subs, W>,
6765         scope: Option<ArgScopeStack<'prev, 'subs>>,
6766     ) -> fmt::Result {
6767         let ctx = try_begin_demangle!(self, ctx, scope);
6768 
6769         write!(ctx, "(")?;
6770         let mut need_comma = false;
6771         for expr in &self.0 {
6772             if need_comma {
6773                 write!(ctx, ", ")?;
6774             }
6775             expr.demangle(ctx, scope)?;
6776             need_comma = true;
6777         }
6778         write!(ctx, ")")?;
6779         Ok(())
6780     }
6781 }
6782 
6783 /// The `<local-name>` production.
6784 ///
6785 /// ```text
6786 /// <local-name> := Z <function encoding> E <entity name> [<discriminator>]
6787 ///              := Z <function encoding> E s [<discriminator>]
6788 ///              := Z <function encoding> Ed [ <parameter number> ] _ <entity name>
6789 /// ```
6790 #[derive(Clone, Debug, PartialEq, Eq)]
6791 pub enum LocalName {
6792     /// The mangling of the enclosing function, the mangling of the entity
6793     /// relative to the function, and an optional discriminator.
6794     Relative(Box<Encoding>, Option<Box<Name>>, Option<Discriminator>),
6795 
6796     /// A default argument in a class definition.
6797     Default(Box<Encoding>, Option<usize>, Box<Name>),
6798 }
6799 
6800 impl Parse for LocalName {
parse<'a, 'b>( ctx: &'a ParseContext, subs: &'a mut SubstitutionTable, input: IndexStr<'b>, ) -> Result<(LocalName, IndexStr<'b>)>6801     fn parse<'a, 'b>(
6802         ctx: &'a ParseContext,
6803         subs: &'a mut SubstitutionTable,
6804         input: IndexStr<'b>,
6805     ) -> Result<(LocalName, IndexStr<'b>)> {
6806         try_begin_parse!("LocalName", ctx, input);
6807 
6808         let tail = consume(b"Z", input)?;
6809         let (encoding, tail) = Encoding::parse(ctx, subs, tail)?;
6810         let tail = consume(b"E", tail)?;
6811 
6812         if let Ok(tail) = consume(b"s", tail) {
6813             let (disc, tail) = if let Ok((disc, tail)) = Discriminator::parse(ctx, subs, tail) {
6814                 (Some(disc), tail)
6815             } else {
6816                 (None, tail)
6817             };
6818             return Ok((LocalName::Relative(Box::new(encoding), None, disc), tail));
6819         }
6820 
6821         if let Ok(tail) = consume(b"d", tail) {
6822             let (param, tail) = if let Ok((num, tail)) = Number::parse(ctx, subs, tail) {
6823                 (Some(num as _), tail)
6824             } else {
6825                 (None, tail)
6826             };
6827             let tail = consume(b"_", tail)?;
6828             let (name, tail) = Name::parse(ctx, subs, tail)?;
6829             return Ok((
6830                 LocalName::Default(Box::new(encoding), param, Box::new(name)),
6831                 tail,
6832             ));
6833         }
6834 
6835         let (name, tail) = Name::parse(ctx, subs, tail)?;
6836         let (disc, tail) = if let Ok((disc, tail)) = Discriminator::parse(ctx, subs, tail) {
6837             (Some(disc), tail)
6838         } else {
6839             (None, tail)
6840         };
6841 
6842         Ok((
6843             LocalName::Relative(Box::new(encoding), Some(Box::new(name)), disc),
6844             tail,
6845         ))
6846     }
6847 }
6848 
6849 impl<'subs, W> Demangle<'subs, W> for LocalName
6850 where
6851     W: 'subs + DemangleWrite,
6852 {
demangle<'prev, 'ctx>( &'subs self, ctx: &'ctx mut DemangleContext<'subs, W>, scope: Option<ArgScopeStack<'prev, 'subs>>, ) -> fmt::Result6853     fn demangle<'prev, 'ctx>(
6854         &'subs self,
6855         ctx: &'ctx mut DemangleContext<'subs, W>,
6856         scope: Option<ArgScopeStack<'prev, 'subs>>,
6857     ) -> fmt::Result {
6858         let ctx = try_begin_demangle!(self, ctx, scope);
6859 
6860         let saved_show_params = ctx.show_params;
6861         ctx.show_params = true;
6862         let ret = match *self {
6863             LocalName::Relative(ref encoding, Some(ref name), _) => {
6864                 encoding.demangle(ctx, scope)?;
6865                 write!(ctx, "::")?;
6866                 name.demangle(ctx, scope)
6867             }
6868             LocalName::Relative(ref encoding, None, _) => {
6869                 // No name means that this is the symbol for a string literal.
6870                 encoding.demangle(ctx, scope)?;
6871                 write!(ctx, "::string literal")?;
6872                 Ok(())
6873             }
6874             LocalName::Default(ref encoding, _, _) => encoding.demangle(ctx, scope),
6875         };
6876         ctx.show_params = saved_show_params;
6877         ret
6878     }
6879 }
6880 
6881 impl GetTemplateArgs for LocalName {
get_template_args<'a>(&'a self, subs: &'a SubstitutionTable) -> Option<&'a TemplateArgs>6882     fn get_template_args<'a>(&'a self, subs: &'a SubstitutionTable) -> Option<&'a TemplateArgs> {
6883         match *self {
6884             LocalName::Relative(_, None, _) => None,
6885             LocalName::Relative(_, Some(ref name), _) | LocalName::Default(_, _, ref name) => {
6886                 name.get_template_args(subs)
6887             }
6888         }
6889     }
6890 }
6891 
6892 impl<'a> GetLeafName<'a> for LocalName {
get_leaf_name(&'a self, subs: &'a SubstitutionTable) -> Option<LeafName<'a>>6893     fn get_leaf_name(&'a self, subs: &'a SubstitutionTable) -> Option<LeafName<'a>> {
6894         match *self {
6895             LocalName::Relative(_, None, _) => None,
6896             LocalName::Relative(_, Some(ref name), _) | LocalName::Default(_, _, ref name) => {
6897                 name.get_leaf_name(subs)
6898             }
6899         }
6900     }
6901 }
6902 
6903 /// The `<discriminator>` production.
6904 ///
6905 /// ```text
6906 /// <discriminator> := _ <non-negative number>      # when number < 10
6907 ///                 := __ <non-negative number> _   # when number >= 10
6908 /// ```
6909 #[derive(Clone, Debug, PartialEq, Eq)]
6910 pub struct Discriminator(usize);
6911 
6912 impl Parse for Discriminator {
parse<'a, 'b>( ctx: &'a ParseContext, _subs: &'a mut SubstitutionTable, input: IndexStr<'b>, ) -> Result<(Discriminator, IndexStr<'b>)>6913     fn parse<'a, 'b>(
6914         ctx: &'a ParseContext,
6915         _subs: &'a mut SubstitutionTable,
6916         input: IndexStr<'b>,
6917     ) -> Result<(Discriminator, IndexStr<'b>)> {
6918         try_begin_parse!("Discriminator", ctx, input);
6919 
6920         let tail = consume(b"_", input)?;
6921 
6922         if let Ok(tail) = consume(b"_", tail) {
6923             let (num, tail) = parse_number(10, false, tail)?;
6924             debug_assert!(num >= 0);
6925             if num < 10 {
6926                 return Err(error::Error::UnexpectedText);
6927             }
6928             let tail = consume(b"_", tail)?;
6929             return Ok((Discriminator(num as _), tail));
6930         }
6931 
6932         match tail.try_split_at(1) {
6933             None => Err(error::Error::UnexpectedEnd),
6934             Some((head, tail)) => match head.as_ref()[0] {
6935                 b'0' => Ok((Discriminator(0), tail)),
6936                 b'1' => Ok((Discriminator(1), tail)),
6937                 b'2' => Ok((Discriminator(2), tail)),
6938                 b'3' => Ok((Discriminator(3), tail)),
6939                 b'4' => Ok((Discriminator(4), tail)),
6940                 b'5' => Ok((Discriminator(5), tail)),
6941                 b'6' => Ok((Discriminator(6), tail)),
6942                 b'7' => Ok((Discriminator(7), tail)),
6943                 b'8' => Ok((Discriminator(8), tail)),
6944                 b'9' => Ok((Discriminator(9), tail)),
6945                 _ => Err(error::Error::UnexpectedText),
6946             },
6947         }
6948     }
6949 }
6950 
6951 /// The `<closure-type-name>` production.
6952 ///
6953 /// ```text
6954 /// <closure-type-name> ::= Ul <lambda-sig> E [ <nonnegative number> ] _
6955 /// ```
6956 #[derive(Clone, Debug, PartialEq, Eq)]
6957 pub struct ClosureTypeName(LambdaSig, Option<usize>);
6958 
6959 impl Parse for ClosureTypeName {
parse<'a, 'b>( ctx: &'a ParseContext, subs: &'a mut SubstitutionTable, input: IndexStr<'b>, ) -> Result<(ClosureTypeName, IndexStr<'b>)>6960     fn parse<'a, 'b>(
6961         ctx: &'a ParseContext,
6962         subs: &'a mut SubstitutionTable,
6963         input: IndexStr<'b>,
6964     ) -> Result<(ClosureTypeName, IndexStr<'b>)> {
6965         try_begin_parse!("ClosureTypeName", ctx, input);
6966 
6967         let tail = consume(b"Ul", input)?;
6968         let (sig, tail) = LambdaSig::parse(ctx, subs, tail)?;
6969         let tail = consume(b"E", tail)?;
6970         let (num, tail) = if let Ok((num, tail)) = parse_number(10, false, tail) {
6971             (Some(num as _), tail)
6972         } else {
6973             (None, tail)
6974         };
6975         let tail = consume(b"_", tail)?;
6976         Ok((ClosureTypeName(sig, num), tail))
6977     }
6978 }
6979 
6980 impl<'subs, W> Demangle<'subs, W> for ClosureTypeName
6981 where
6982     W: 'subs + DemangleWrite,
6983 {
demangle<'prev, 'ctx>( &'subs self, ctx: &'ctx mut DemangleContext<'subs, W>, scope: Option<ArgScopeStack<'prev, 'subs>>, ) -> fmt::Result6984     fn demangle<'prev, 'ctx>(
6985         &'subs self,
6986         ctx: &'ctx mut DemangleContext<'subs, W>,
6987         scope: Option<ArgScopeStack<'prev, 'subs>>,
6988     ) -> fmt::Result {
6989         let ctx = try_begin_demangle!(self, ctx, scope);
6990 
6991         write!(ctx, "{{lambda(")?;
6992         self.0.demangle(ctx, scope)?;
6993         write!(ctx, ")#{}}}", self.1.map_or(1, |n| n + 2))?;
6994         Ok(())
6995     }
6996 }
6997 
6998 impl<'subs> ArgScope<'subs, 'subs> for ClosureTypeName {
leaf_name(&'subs self) -> Result<LeafName<'subs>>6999     fn leaf_name(&'subs self) -> Result<LeafName<'subs>> {
7000         Ok(LeafName::Closure(self))
7001     }
7002 
get_template_arg( &'subs self, _: usize, ) -> Result<(&'subs TemplateArg, &'subs TemplateArgs)>7003     fn get_template_arg(
7004         &'subs self,
7005         _: usize,
7006     ) -> Result<(&'subs TemplateArg, &'subs TemplateArgs)> {
7007         Err(error::Error::BadTemplateArgReference)
7008     }
7009 
get_function_arg(&'subs self, _: usize) -> Result<&'subs Type>7010     fn get_function_arg(&'subs self, _: usize) -> Result<&'subs Type> {
7011         Err(error::Error::BadFunctionArgReference)
7012     }
7013 }
7014 
7015 impl<'a> GetLeafName<'a> for ClosureTypeName {
7016     #[inline]
get_leaf_name(&'a self, _: &'a SubstitutionTable) -> Option<LeafName<'a>>7017     fn get_leaf_name(&'a self, _: &'a SubstitutionTable) -> Option<LeafName<'a>> {
7018         Some(LeafName::Closure(self))
7019     }
7020 }
7021 
7022 impl ClosureTypeName {
7023     #[inline]
starts_with(byte: u8, input: &IndexStr) -> bool7024     fn starts_with(byte: u8, input: &IndexStr) -> bool {
7025         byte == b'U' && input.peek_second().map(|b| b == b'l').unwrap_or(false)
7026     }
7027 }
7028 
7029 /// The `<lambda-sig>` production.
7030 ///
7031 /// ```text
7032 /// <lambda-sig> ::= <parameter type>+  # Parameter types or "v" if the lambda has no parameters
7033 /// ```
7034 #[derive(Clone, Debug, PartialEq, Eq)]
7035 pub struct LambdaSig(Vec<TypeHandle>);
7036 
7037 impl LambdaSig {
demangle_args<'subs, 'prev, 'ctx, W>( &'subs self, ctx: &'ctx mut DemangleContext<'subs, W>, scope: Option<ArgScopeStack<'prev, 'subs>>, ) -> fmt::Result where W: 'subs + DemangleWrite,7038     fn demangle_args<'subs, 'prev, 'ctx, W>(
7039         &'subs self,
7040         ctx: &'ctx mut DemangleContext<'subs, W>,
7041         scope: Option<ArgScopeStack<'prev, 'subs>>,
7042     ) -> fmt::Result
7043     where
7044         W: 'subs + DemangleWrite,
7045     {
7046         let mut need_comma = false;
7047         for ty in &self.0 {
7048             if need_comma {
7049                 write!(ctx, ", ")?;
7050             }
7051             ty.demangle(ctx, scope)?;
7052             need_comma = true;
7053         }
7054         Ok(())
7055     }
7056 }
7057 
7058 impl Parse for LambdaSig {
parse<'a, 'b>( ctx: &'a ParseContext, subs: &'a mut SubstitutionTable, input: IndexStr<'b>, ) -> Result<(LambdaSig, IndexStr<'b>)>7059     fn parse<'a, 'b>(
7060         ctx: &'a ParseContext,
7061         subs: &'a mut SubstitutionTable,
7062         input: IndexStr<'b>,
7063     ) -> Result<(LambdaSig, IndexStr<'b>)> {
7064         try_begin_parse!("LambdaSig", ctx, input);
7065 
7066         let (types, tail) = if let Ok(tail) = consume(b"v", input) {
7067             (vec![], tail)
7068         } else {
7069             one_or_more::<TypeHandle>(ctx, subs, input)?
7070         };
7071         Ok((LambdaSig(types), tail))
7072     }
7073 }
7074 
7075 impl<'subs, W> Demangle<'subs, W> for LambdaSig
7076 where
7077     W: 'subs + DemangleWrite,
7078 {
demangle<'prev, 'ctx>( &'subs self, ctx: &'ctx mut DemangleContext<'subs, W>, scope: Option<ArgScopeStack<'prev, 'subs>>, ) -> fmt::Result7079     fn demangle<'prev, 'ctx>(
7080         &'subs self,
7081         ctx: &'ctx mut DemangleContext<'subs, W>,
7082         scope: Option<ArgScopeStack<'prev, 'subs>>,
7083     ) -> fmt::Result {
7084         let ctx = try_begin_demangle!(self, ctx, scope);
7085 
7086         ctx.is_lambda_arg = true;
7087         let r = self.demangle_args(ctx, scope);
7088         ctx.is_lambda_arg = false;
7089         r
7090     }
7091 }
7092 
7093 /// The `<data-member-prefix>` production.
7094 ///
7095 /// ```text
7096 /// <data-member-prefix> := <member source-name> M
7097 /// ```
7098 #[derive(Clone, Debug, PartialEq, Eq)]
7099 pub struct DataMemberPrefix(SourceName);
7100 
7101 impl Parse for DataMemberPrefix {
parse<'a, 'b>( ctx: &'a ParseContext, subs: &'a mut SubstitutionTable, input: IndexStr<'b>, ) -> Result<(DataMemberPrefix, IndexStr<'b>)>7102     fn parse<'a, 'b>(
7103         ctx: &'a ParseContext,
7104         subs: &'a mut SubstitutionTable,
7105         input: IndexStr<'b>,
7106     ) -> Result<(DataMemberPrefix, IndexStr<'b>)> {
7107         try_begin_parse!("DataMemberPrefix", ctx, input);
7108 
7109         let (name, tail) = SourceName::parse(ctx, subs, input)?;
7110         let tail = consume(b"M", tail)?;
7111         Ok((DataMemberPrefix(name), tail))
7112     }
7113 }
7114 
7115 impl<'a> GetLeafName<'a> for DataMemberPrefix {
7116     #[inline]
get_leaf_name(&'a self, _: &'a SubstitutionTable) -> Option<LeafName<'a>>7117     fn get_leaf_name(&'a self, _: &'a SubstitutionTable) -> Option<LeafName<'a>> {
7118         Some(LeafName::SourceName(&self.0))
7119     }
7120 }
7121 
7122 impl DataMemberPrefix {
starts_with(byte: u8) -> bool7123     fn starts_with(byte: u8) -> bool {
7124         SourceName::starts_with(byte)
7125     }
7126 }
7127 
7128 impl<'subs, W> Demangle<'subs, W> for DataMemberPrefix
7129 where
7130     W: 'subs + DemangleWrite,
7131 {
7132     #[inline]
demangle<'prev, 'ctx>( &'subs self, ctx: &'ctx mut DemangleContext<'subs, W>, scope: Option<ArgScopeStack<'prev, 'subs>>, ) -> fmt::Result7133     fn demangle<'prev, 'ctx>(
7134         &'subs self,
7135         ctx: &'ctx mut DemangleContext<'subs, W>,
7136         scope: Option<ArgScopeStack<'prev, 'subs>>,
7137     ) -> fmt::Result {
7138         let ctx = try_begin_demangle!(self, ctx, scope);
7139 
7140         ctx.push_demangle_node(DemangleNodeType::DataMemberPrefix);
7141         let ret = self.0.demangle(ctx, scope);
7142         ctx.pop_demangle_node();
7143         ret
7144     }
7145 }
7146 
7147 /// The `<substitution>` form: a back-reference to some component we've already
7148 /// parsed.
7149 ///
7150 /// ```text
7151 /// <substitution> ::= S <seq-id> _
7152 ///                ::= S_
7153 ///                ::= St # ::std::
7154 ///                ::= Sa # ::std::allocator
7155 ///                ::= Sb # ::std::basic_string
7156 ///                ::= Ss # ::std::basic_string < char,
7157 ///                                               ::std::char_traits<char>,
7158 ///                                               ::std::allocator<char> >
7159 ///                ::= Si # ::std::basic_istream<char,  std::char_traits<char> >
7160 ///                ::= So # ::std::basic_ostream<char,  std::char_traits<char> >
7161 ///                ::= Sd # ::std::basic_iostream<char, std::char_traits<char> >
7162 /// ```
7163 #[derive(Clone, Debug, PartialEq, Eq)]
7164 pub enum Substitution {
7165     /// A reference to an entity that already occurred, ie the `S_` and `S
7166     /// <seq-id> _` forms.
7167     BackReference(usize),
7168 
7169     /// A well-known substitution component. These are the components that do
7170     /// not appear in the substitution table, but have abbreviations specified
7171     /// directly in the grammar.
7172     WellKnown(WellKnownComponent),
7173 }
7174 
7175 impl Parse for Substitution {
parse<'a, 'b>( ctx: &'a ParseContext, subs: &'a mut SubstitutionTable, input: IndexStr<'b>, ) -> Result<(Substitution, IndexStr<'b>)>7176     fn parse<'a, 'b>(
7177         ctx: &'a ParseContext,
7178         subs: &'a mut SubstitutionTable,
7179         input: IndexStr<'b>,
7180     ) -> Result<(Substitution, IndexStr<'b>)> {
7181         try_begin_parse!("Substitution", ctx, input);
7182 
7183         if let Ok((well_known, tail)) = WellKnownComponent::parse(ctx, subs, input) {
7184             return Ok((Substitution::WellKnown(well_known), tail));
7185         }
7186 
7187         let tail = consume(b"S", input)?;
7188         let (idx, tail) = if let Ok((idx, tail)) = SeqId::parse(ctx, subs, tail) {
7189             (idx.0 + 1, tail)
7190         } else {
7191             (0, tail)
7192         };
7193 
7194         if !subs.contains(idx) {
7195             return Err(error::Error::BadBackReference);
7196         }
7197 
7198         let tail = consume(b"_", tail)?;
7199         log!("Found a reference to @ {}", idx);
7200         Ok((Substitution::BackReference(idx), tail))
7201     }
7202 }
7203 
7204 define_vocabulary! {
7205 /// The `<substitution>` variants that are encoded directly in the grammar,
7206 /// rather than as back references to other components in the substitution
7207 /// table.
7208     #[derive(Clone, Debug, PartialEq, Eq)]
7209     pub enum WellKnownComponent {
7210         Std          (b"St", "std"),
7211         StdAllocator (b"Sa", "std::allocator"),
7212         StdString1   (b"Sb", "std::basic_string"),
7213         StdString2   (b"Ss", "std::string"),
7214         StdIstream   (b"Si", "std::basic_istream<char, std::char_traits<char> >"),
7215         StdOstream   (b"So", "std::ostream"),
7216         StdIostream  (b"Sd", "std::basic_iostream<char, std::char_traits<char> >")
7217     }
7218 }
7219 
7220 impl<'a> GetLeafName<'a> for WellKnownComponent {
get_leaf_name(&'a self, _: &'a SubstitutionTable) -> Option<LeafName<'a>>7221     fn get_leaf_name(&'a self, _: &'a SubstitutionTable) -> Option<LeafName<'a>> {
7222         match *self {
7223             WellKnownComponent::Std => None,
7224             _ => Some(LeafName::WellKnownComponent(self)),
7225         }
7226     }
7227 }
7228 
7229 impl<'a> ArgScope<'a, 'a> for WellKnownComponent {
leaf_name(&'a self) -> Result<LeafName<'a>>7230     fn leaf_name(&'a self) -> Result<LeafName<'a>> {
7231         Ok(LeafName::WellKnownComponent(self))
7232     }
7233 
get_template_arg(&'a self, _: usize) -> Result<(&'a TemplateArg, &'a TemplateArgs)>7234     fn get_template_arg(&'a self, _: usize) -> Result<(&'a TemplateArg, &'a TemplateArgs)> {
7235         Err(error::Error::BadTemplateArgReference)
7236     }
7237 
get_function_arg(&'a self, _: usize) -> Result<&'a Type>7238     fn get_function_arg(&'a self, _: usize) -> Result<&'a Type> {
7239         Err(error::Error::BadFunctionArgReference)
7240     }
7241 }
7242 
7243 impl<'subs, W> DemangleAsLeaf<'subs, W> for WellKnownComponent
7244 where
7245     W: 'subs + DemangleWrite,
7246 {
demangle_as_leaf<'me, 'ctx>( &'me self, ctx: &'ctx mut DemangleContext<'subs, W>, ) -> fmt::Result7247     fn demangle_as_leaf<'me, 'ctx>(
7248         &'me self,
7249         ctx: &'ctx mut DemangleContext<'subs, W>,
7250     ) -> fmt::Result {
7251         match *self {
7252             WellKnownComponent::Std => {
7253                 panic!("should never treat `WellKnownComponent::Std` as a leaf name")
7254             }
7255             WellKnownComponent::StdAllocator => write!(ctx, "allocator"),
7256             WellKnownComponent::StdString1 => write!(ctx, "basic_string"),
7257             WellKnownComponent::StdString2 => write!(ctx, "string"),
7258             WellKnownComponent::StdIstream => write!(ctx, "basic_istream"),
7259             WellKnownComponent::StdOstream => write!(ctx, "ostream"),
7260             WellKnownComponent::StdIostream => write!(ctx, "basic_iostream"),
7261         }
7262     }
7263 }
7264 
7265 /// The `<special-name>` production.
7266 ///
7267 /// The `<special-name>` production is spread in pieces through out the ABI
7268 /// spec, and then there are a bunch of `g++` extensions that have become de
7269 /// facto.
7270 ///
7271 /// ### 5.1.4.1 Virtual Tables and RTTI
7272 ///
7273 /// ```text
7274 /// <special-name> ::= TV <type>    # virtual table
7275 ///                ::= TT <type>    # VTT structure (construction vtable index)
7276 ///                ::= TI <type>    # typeinfo structure
7277 ///                ::= TS <type>    # typeinfo name (null-terminated byte string)
7278 /// ```
7279 ///
7280 /// ### 5.1.4.2 Virtual Override Thunks
7281 ///
7282 /// ```text
7283 /// <special-name> ::= T <call-offset> <base encoding>
7284 ///     # base is the nominal target function of thunk
7285 ///
7286 /// <special-name> ::= Tc <call-offset> <call-offset> <base encoding>
7287 ///     # base is the nominal target function of thunk
7288 ///     # first call-offset is 'this' adjustment
7289 ///     # second call-offset is result adjustment
7290 /// ```
7291 ///
7292 /// ### 5.1.4.4 Guard Variables
7293 ///
7294 /// ```text
7295 /// <special-name> ::= GV <object name> # Guard variable for one-time initialization
7296 ///     # No <type>
7297 /// ```
7298 ///
7299 /// ### 5.1.4.5 Lifetime-Extended Temporaries
7300 ///
7301 /// ```text
7302 /// <special-name> ::= GR <object name> _             # First temporary
7303 /// <special-name> ::= GR <object name> <seq-id> _    # Subsequent temporaries
7304 /// ```
7305 ///
7306 /// ### De Facto Standard Extensions
7307 ///
7308 /// ```text
7309 /// <special-name> ::= TC <type> <number> _ <type>    # construction vtable
7310 ///                ::= TF <type>                      # typinfo function
7311 ///                ::= TH <name>                      # TLS initialization function
7312 ///                ::= TW <name>                      # TLS wrapper function
7313 ///                ::= Gr <resource name>             # Java Resource
7314 ///                ::= GTt <encoding>                 # Transaction-Safe function
7315 ///                ::= GTn <encoding>                 # Non-Transaction-Safe function
7316 /// ```
7317 #[derive(Clone, Debug, PartialEq, Eq)]
7318 pub enum SpecialName {
7319     /// A virtual table.
7320     VirtualTable(TypeHandle),
7321 
7322     /// A VTT structure (construction vtable index).
7323     Vtt(TypeHandle),
7324 
7325     /// A typeinfo structure.
7326     Typeinfo(TypeHandle),
7327 
7328     /// A typeinfo name (null-terminated byte string).
7329     TypeinfoName(TypeHandle),
7330 
7331     /// A virtual override thunk.
7332     VirtualOverrideThunk(CallOffset, Box<Encoding>),
7333 
7334     /// A virtual override thunk with a covariant return type.
7335     VirtualOverrideThunkCovariant(CallOffset, CallOffset, Box<Encoding>),
7336 
7337     /// An initialization guard for some static storage.
7338     Guard(Name),
7339 
7340     /// A temporary used in the initialization of a static storage and promoted
7341     /// to a static lifetime.
7342     GuardTemporary(Name, usize),
7343 
7344     /// A construction vtable structure.
7345     ConstructionVtable(TypeHandle, usize, TypeHandle),
7346 
7347     /// A typeinfo function.
7348     TypeinfoFunction(TypeHandle),
7349 
7350     /// A TLS initialization function.
7351     TlsInit(Name),
7352 
7353     /// A TLS wrapper function.
7354     TlsWrapper(Name),
7355 
7356     /// A Java Resource.
7357     JavaResource(Vec<ResourceName>),
7358 
7359     /// A function declared transaction-safe
7360     TransactionClone(Box<Encoding>),
7361 
7362     /// A function declared non-transaction-safe
7363     NonTransactionClone(Box<Encoding>),
7364 }
7365 
7366 impl Parse for SpecialName {
parse<'a, 'b>( ctx: &'a ParseContext, subs: &'a mut SubstitutionTable, input: IndexStr<'b>, ) -> Result<(SpecialName, IndexStr<'b>)>7367     fn parse<'a, 'b>(
7368         ctx: &'a ParseContext,
7369         subs: &'a mut SubstitutionTable,
7370         input: IndexStr<'b>,
7371     ) -> Result<(SpecialName, IndexStr<'b>)> {
7372         try_begin_parse!("SpecialName", ctx, input);
7373 
7374         let (head, tail) = match input.try_split_at(2) {
7375             None => return Err(error::Error::UnexpectedEnd),
7376             Some((head, tail)) => (head, tail),
7377         };
7378 
7379         match head.as_ref() {
7380             b"TV" => {
7381                 let (ty, tail) = TypeHandle::parse(ctx, subs, tail)?;
7382                 Ok((SpecialName::VirtualTable(ty), tail))
7383             }
7384             b"TT" => {
7385                 let (ty, tail) = TypeHandle::parse(ctx, subs, tail)?;
7386                 Ok((SpecialName::Vtt(ty), tail))
7387             }
7388             b"TI" => {
7389                 let (ty, tail) = TypeHandle::parse(ctx, subs, tail)?;
7390                 Ok((SpecialName::Typeinfo(ty), tail))
7391             }
7392             b"TS" => {
7393                 let (ty, tail) = TypeHandle::parse(ctx, subs, tail)?;
7394                 Ok((SpecialName::TypeinfoName(ty), tail))
7395             }
7396             b"Tc" => {
7397                 let (first, tail) = CallOffset::parse(ctx, subs, tail)?;
7398                 let (second, tail) = CallOffset::parse(ctx, subs, tail)?;
7399                 let (base, tail) = Encoding::parse(ctx, subs, tail)?;
7400                 Ok((
7401                     SpecialName::VirtualOverrideThunkCovariant(first, second, Box::new(base)),
7402                     tail,
7403                 ))
7404             }
7405             b"Th" | b"Tv" => {
7406                 // The "h"/"v" is part of the `<call-offset>`, so back up to the
7407                 // `input`.
7408                 let tail = consume(b"T", input).unwrap();
7409                 let (offset, tail) = CallOffset::parse(ctx, subs, tail)?;
7410                 let (base, tail) = Encoding::parse(ctx, subs, tail)?;
7411                 Ok((
7412                     SpecialName::VirtualOverrideThunk(offset, Box::new(base)),
7413                     tail,
7414                 ))
7415             }
7416             b"TC" => {
7417                 let (ty1, tail) = TypeHandle::parse(ctx, subs, tail)?;
7418                 let (n, tail) = parse_number(10, false, tail)?;
7419                 let tail = consume(b"_", tail)?;
7420                 let (ty2, tail) = TypeHandle::parse(ctx, subs, tail)?;
7421                 Ok((SpecialName::ConstructionVtable(ty1, n as usize, ty2), tail))
7422             }
7423             b"TF" => {
7424                 let (ty, tail) = TypeHandle::parse(ctx, subs, tail)?;
7425                 Ok((SpecialName::TypeinfoFunction(ty), tail))
7426             }
7427             b"TH" => {
7428                 let (name, tail) = Name::parse(ctx, subs, tail)?;
7429                 Ok((SpecialName::TlsInit(name), tail))
7430             }
7431             b"TW" => {
7432                 let (name, tail) = Name::parse(ctx, subs, tail)?;
7433                 Ok((SpecialName::TlsWrapper(name), tail))
7434             }
7435             b"GV" => {
7436                 let (name, tail) = Name::parse(ctx, subs, tail)?;
7437                 Ok((SpecialName::Guard(name), tail))
7438             }
7439             b"GR" => {
7440                 let (name, tail) = Name::parse(ctx, subs, tail)?;
7441                 let (idx, tail) = if let Ok(tail) = consume(b"_", tail) {
7442                     (0, tail)
7443                 } else {
7444                     let (idx, tail) = SeqId::parse(ctx, subs, tail)?;
7445                     let tail = consume(b"_", tail)?;
7446                     (idx.0 + 1, tail)
7447                 };
7448                 Ok((SpecialName::GuardTemporary(name, idx), tail))
7449             }
7450             b"Gr" => {
7451                 let (resource_name_len, tail) = parse_number(10, false, tail)?;
7452                 if resource_name_len == 0 {
7453                     return Err(error::Error::UnexpectedText);
7454                 }
7455 
7456                 let (head, tail) = match tail.try_split_at(resource_name_len as _) {
7457                     Some((head, tail)) => (head, tail),
7458                     None => return Err(error::Error::UnexpectedEnd),
7459                 };
7460 
7461                 let head = consume(b"_", head)?;
7462 
7463                 let (resource_names, empty) = zero_or_more::<ResourceName>(ctx, subs, head)?;
7464                 if !empty.is_empty() {
7465                     return Err(error::Error::UnexpectedText);
7466                 }
7467 
7468                 Ok((SpecialName::JavaResource(resource_names), tail))
7469             }
7470             b"GT" => {
7471                 match tail.next_or(error::Error::UnexpectedEnd)? {
7472                     (b'n', tail) => {
7473                         let (base, tail) = Encoding::parse(ctx, subs, tail)?;
7474                         Ok((SpecialName::NonTransactionClone(Box::new(base)), tail))
7475                     }
7476                     // Different letters could stand for different types of
7477                     // transactional cloning, but for now, treat them all the same
7478                     (b't', tail) | (_, tail) => {
7479                         let (base, tail) = Encoding::parse(ctx, subs, tail)?;
7480                         Ok((SpecialName::TransactionClone(Box::new(base)), tail))
7481                     }
7482                 }
7483             }
7484             _ => Err(error::Error::UnexpectedText),
7485         }
7486     }
7487 }
7488 
7489 impl<'subs, W> Demangle<'subs, W> for SpecialName
7490 where
7491     W: 'subs + DemangleWrite,
7492 {
demangle<'prev, 'ctx>( &'subs self, ctx: &'ctx mut DemangleContext<'subs, W>, scope: Option<ArgScopeStack<'prev, 'subs>>, ) -> fmt::Result7493     fn demangle<'prev, 'ctx>(
7494         &'subs self,
7495         ctx: &'ctx mut DemangleContext<'subs, W>,
7496         scope: Option<ArgScopeStack<'prev, 'subs>>,
7497     ) -> fmt::Result {
7498         let ctx = try_begin_demangle!(self, ctx, scope);
7499 
7500         match *self {
7501             SpecialName::VirtualTable(ref ty) => {
7502                 write!(ctx, "{{vtable(")?;
7503                 ctx.push_demangle_node(DemangleNodeType::VirtualTable);
7504                 ty.demangle(ctx, scope)?;
7505                 ctx.pop_demangle_node();
7506                 write!(ctx, ")}}")?;
7507                 Ok(())
7508             }
7509             SpecialName::Vtt(ref ty) => {
7510                 write!(ctx, "{{vtt(")?;
7511                 ty.demangle(ctx, scope)?;
7512                 write!(ctx, ")}}")?;
7513                 Ok(())
7514             }
7515             SpecialName::Typeinfo(ref ty) => {
7516                 write!(ctx, "typeinfo for ")?;
7517                 ty.demangle(ctx, scope)
7518             }
7519             SpecialName::TypeinfoName(ref ty) => {
7520                 write!(ctx, "typeinfo name for ")?;
7521                 ty.demangle(ctx, scope)
7522             }
7523             SpecialName::VirtualOverrideThunk(ref offset, ref encoding) => {
7524                 write!(ctx, "{{virtual override thunk(")?;
7525                 offset.demangle(ctx, scope)?;
7526                 write!(ctx, ", ")?;
7527                 encoding.demangle(ctx, scope)?;
7528                 write!(ctx, ")}}")?;
7529                 Ok(())
7530             }
7531             SpecialName::VirtualOverrideThunkCovariant(
7532                 ref this_offset,
7533                 ref result_offset,
7534                 ref encoding,
7535             ) => {
7536                 write!(ctx, "{{virtual override thunk(")?;
7537                 this_offset.demangle(ctx, scope)?;
7538                 write!(ctx, ", ")?;
7539                 result_offset.demangle(ctx, scope)?;
7540                 write!(ctx, ", ")?;
7541                 encoding.demangle(ctx, scope)?;
7542                 write!(ctx, ")}}")?;
7543                 Ok(())
7544             }
7545             SpecialName::Guard(ref name) => {
7546                 write!(ctx, "guard variable for ")?;
7547                 name.demangle(ctx, scope)
7548             }
7549             SpecialName::GuardTemporary(ref name, n) => {
7550                 write!(ctx, "reference temporary #{} for ", n)?;
7551                 name.demangle(ctx, scope)
7552             }
7553             SpecialName::ConstructionVtable(ref ty1, _, ref ty2) => {
7554                 write!(ctx, "construction vtable for ")?;
7555                 ty1.demangle(ctx, scope)?;
7556                 write!(ctx, "-in-")?;
7557                 ty2.demangle(ctx, scope)
7558             }
7559             SpecialName::TypeinfoFunction(ref ty) => {
7560                 write!(ctx, "typeinfo fn for ")?;
7561                 ty.demangle(ctx, scope)
7562             }
7563             SpecialName::TlsInit(ref name) => {
7564                 write!(ctx, "TLS init function for ")?;
7565                 name.demangle(ctx, scope)
7566             }
7567             SpecialName::TlsWrapper(ref name) => {
7568                 write!(ctx, "TLS wrapper function for ")?;
7569                 name.demangle(ctx, scope)
7570             }
7571             SpecialName::TransactionClone(ref encoding) => {
7572                 write!(ctx, "transaction clone for ")?;
7573                 encoding.demangle(ctx, scope)
7574             }
7575             SpecialName::NonTransactionClone(ref encoding) => {
7576                 write!(ctx, "non-transaction clone for ")?;
7577                 encoding.demangle(ctx, scope)
7578             }
7579             SpecialName::JavaResource(ref names) => {
7580                 write!(ctx, "java resource ")?;
7581                 for name in names {
7582                     name.demangle(ctx, scope)?;
7583                 }
7584                 Ok(())
7585             }
7586         }
7587     }
7588 }
7589 
7590 /// The `<resource name>` pseudo-terminal.
7591 #[derive(Clone, Debug, PartialEq, Eq)]
7592 pub struct ResourceName {
7593     start: usize,
7594     end: usize,
7595 }
7596 
7597 impl Parse for ResourceName {
parse<'a, 'b>( ctx: &'a ParseContext, _subs: &'a mut SubstitutionTable, input: IndexStr<'b>, ) -> Result<(ResourceName, IndexStr<'b>)>7598     fn parse<'a, 'b>(
7599         ctx: &'a ParseContext,
7600         _subs: &'a mut SubstitutionTable,
7601         input: IndexStr<'b>,
7602     ) -> Result<(ResourceName, IndexStr<'b>)> {
7603         try_begin_parse!("ResourceName", ctx, input);
7604 
7605         if input.is_empty() {
7606             return Err(error::Error::UnexpectedEnd);
7607         }
7608 
7609         let mut end = input
7610             .as_ref()
7611             .iter()
7612             .map(|&c| c as char)
7613             .take_while(|&c| c != '$' || c.is_digit(36))
7614             .count();
7615 
7616         if end == 0 {
7617             return Err(error::Error::UnexpectedText);
7618         }
7619 
7620         if input.range_from(end..).peek() == Some(b'$') {
7621             match input.range_from(end..).peek_second() {
7622                 Some(b'S') | Some(b'_') | Some(b'$') => end += 2,
7623                 _ => return Err(error::Error::UnexpectedText),
7624             }
7625         }
7626 
7627         let tail = input.range_from(end..);
7628 
7629         let resource_name = ResourceName {
7630             start: input.index(),
7631             end: tail.index(),
7632         };
7633 
7634         Ok((resource_name, tail))
7635     }
7636 }
7637 
7638 impl<'subs, W> Demangle<'subs, W> for ResourceName
7639 where
7640     W: 'subs + DemangleWrite,
7641 {
7642     #[inline]
demangle<'prev, 'ctx>( &'subs self, ctx: &'ctx mut DemangleContext<'subs, W>, scope: Option<ArgScopeStack<'prev, 'subs>>, ) -> fmt::Result7643     fn demangle<'prev, 'ctx>(
7644         &'subs self,
7645         ctx: &'ctx mut DemangleContext<'subs, W>,
7646         scope: Option<ArgScopeStack<'prev, 'subs>>,
7647     ) -> fmt::Result {
7648         let ctx = try_begin_demangle!(self, ctx, scope);
7649 
7650         let mut i = self.start;
7651         while i < self.end {
7652             let ch = ctx.input[i];
7653             if ch == b'$' {
7654                 // Skip past the '$'
7655                 i += 1;
7656                 match ctx.input[i] {
7657                     b'S' => write!(ctx, "{}", '/')?,
7658                     b'_' => write!(ctx, "{}", '.')?,
7659                     b'$' => write!(ctx, "{}", '$')?,
7660                     _ => {
7661                         // Fall through
7662                     }
7663                 }
7664             } else {
7665                 write!(ctx, "{}", ch as char)?;
7666             }
7667             i += 1;
7668         }
7669 
7670         Ok(())
7671     }
7672 }
7673 /// Expect and consume the given byte str, and return the advanced `IndexStr` if
7674 /// we saw the expectation. Otherwise return an error of kind
7675 /// `error::Error::UnexpectedText` if the input doesn't match, or
7676 /// `error::Error::UnexpectedEnd` if it isn't long enough.
7677 #[inline]
consume<'a>(expected: &[u8], input: IndexStr<'a>) -> Result<IndexStr<'a>>7678 fn consume<'a>(expected: &[u8], input: IndexStr<'a>) -> Result<IndexStr<'a>> {
7679     match input.try_split_at(expected.len()) {
7680         Some((head, tail)) if head == expected => Ok(tail),
7681         Some(_) => Err(error::Error::UnexpectedText),
7682         None => Err(error::Error::UnexpectedEnd),
7683     }
7684 }
7685 
one_or_more<'a, 'b, P>( ctx: &'a ParseContext, subs: &'a mut SubstitutionTable, input: IndexStr<'b>, ) -> Result<(Vec<P>, IndexStr<'b>)> where P: Parse,7686 fn one_or_more<'a, 'b, P>(
7687     ctx: &'a ParseContext,
7688     subs: &'a mut SubstitutionTable,
7689     input: IndexStr<'b>,
7690 ) -> Result<(Vec<P>, IndexStr<'b>)>
7691 where
7692     P: Parse,
7693 {
7694     let (first, mut tail) = P::parse(ctx, subs, input)?;
7695     let mut results = vec![first];
7696     loop {
7697         if let Ok((parsed, tail_tail)) = P::parse(ctx, subs, tail) {
7698             results.push(parsed);
7699             tail = tail_tail;
7700         } else {
7701             return Ok((results, tail));
7702         }
7703     }
7704 }
7705 
zero_or_more<'a, 'b, P>( ctx: &'a ParseContext, subs: &'a mut SubstitutionTable, input: IndexStr<'b>, ) -> Result<(Vec<P>, IndexStr<'b>)> where P: Parse,7706 fn zero_or_more<'a, 'b, P>(
7707     ctx: &'a ParseContext,
7708     subs: &'a mut SubstitutionTable,
7709     input: IndexStr<'b>,
7710 ) -> Result<(Vec<P>, IndexStr<'b>)>
7711 where
7712     P: Parse,
7713 {
7714     let mut tail = input;
7715     let mut results = vec![];
7716     loop {
7717         if let Ok((parsed, tail_tail)) = P::parse(ctx, subs, tail) {
7718             results.push(parsed);
7719             tail = tail_tail;
7720         } else {
7721             return Ok((results, tail));
7722         }
7723     }
7724 }
7725 
7726 /// Parse a number with the given `base`. Do not allow negative numbers
7727 /// (prefixed with an 'n' instead of a '-') if `allow_signed` is false.
7728 #[allow(unsafe_code)]
parse_number(base: u32, allow_signed: bool, mut input: IndexStr) -> Result<(isize, IndexStr)>7729 fn parse_number(base: u32, allow_signed: bool, mut input: IndexStr) -> Result<(isize, IndexStr)> {
7730     if input.is_empty() {
7731         return Err(error::Error::UnexpectedEnd);
7732     }
7733 
7734     let num_is_negative = if allow_signed && input.as_ref()[0] == b'n' {
7735         input = input.range_from(1..);
7736 
7737         if input.is_empty() {
7738             return Err(error::Error::UnexpectedEnd);
7739         }
7740 
7741         true
7742     } else {
7743         false
7744     };
7745 
7746     let num_numeric = input
7747         .as_ref()
7748         .iter()
7749         .map(|&c| c as char)
7750         .take_while(|c| c.is_digit(base) && (c.is_numeric() || c.is_uppercase()))
7751         .count();
7752     if num_numeric == 0 {
7753         return Err(error::Error::UnexpectedText);
7754     }
7755 
7756     let (head, tail) = input.split_at(num_numeric);
7757     let head = head.as_ref();
7758 
7759     if num_numeric > 1 && head[0] == b'0' {
7760         // "<number>s appearing in mangled names never have leading zeroes,
7761         // except for the value zero, represented as '0'."
7762         return Err(error::Error::UnexpectedText);
7763     }
7764 
7765     let head = unsafe {
7766         // Safe because we know we only have valid numeric chars in this
7767         // slice, which are valid UTF-8.
7768         ::std::str::from_utf8_unchecked(head)
7769     };
7770 
7771     let mut number = isize::from_str_radix(head, base).map_err(|_| error::Error::Overflow)?;
7772     if num_is_negative {
7773         number = -number;
7774     }
7775 
7776     Ok((number, tail))
7777 }
7778 
7779 #[cfg(test)]
7780 mod tests {
7781     use super::{
7782         ArrayType, BareFunctionType, BaseUnresolvedName, BuiltinType, CallOffset, ClassEnumType,
7783         ClosureTypeName, CtorDtorName, CvQualifiers, DataMemberPrefix, Decltype, DestructorName,
7784         Discriminator, Encoding, ExprPrimary, Expression, FunctionParam, FunctionType,
7785         GlobalCtorDtor, Identifier, Initializer, LambdaSig, LocalName, MangledName, MemberName,
7786         Name, NestedName, NonSubstitution, Number, NvOffset, OperatorName, Parse, ParseContext,
7787         PointerToMemberType, Prefix, PrefixHandle, RefQualifier, ResourceName, SeqId, SimpleId,
7788         SimpleOperatorName, SourceName, SpecialName, StandardBuiltinType, Substitution, TaggedName,
7789         TemplateArg, TemplateArgs, TemplateParam, TemplateTemplateParam,
7790         TemplateTemplateParamHandle, Type, TypeHandle, UnnamedTypeName, UnqualifiedName,
7791         UnresolvedName, UnresolvedQualifierLevel, UnresolvedType, UnresolvedTypeHandle,
7792         UnscopedName, UnscopedTemplateName, UnscopedTemplateNameHandle, VOffset, VectorType,
7793         WellKnownComponent,
7794     };
7795 
7796     use boxed::Box;
7797     use error::Error;
7798     use index_str::IndexStr;
7799     use std::fmt::Debug;
7800     use std::iter::FromIterator;
7801     use string::String;
7802     use subs::{Substitutable, SubstitutionTable};
7803 
assert_parse_ok<P, S1, S2, I1, I2>( production: &'static str, subs: S1, input: I1, expected: P, expected_tail: I2, expected_new_subs: S2, ) where P: Debug + Parse + PartialEq, S1: AsRef<[Substitutable]>, S2: AsRef<[Substitutable]>, I1: AsRef<[u8]>, I2: AsRef<[u8]>,7804     fn assert_parse_ok<P, S1, S2, I1, I2>(
7805         production: &'static str,
7806         subs: S1,
7807         input: I1,
7808         expected: P,
7809         expected_tail: I2,
7810         expected_new_subs: S2,
7811     ) where
7812         P: Debug + Parse + PartialEq,
7813         S1: AsRef<[Substitutable]>,
7814         S2: AsRef<[Substitutable]>,
7815         I1: AsRef<[u8]>,
7816         I2: AsRef<[u8]>,
7817     {
7818         let ctx = ParseContext::new(Default::default());
7819         let input = input.as_ref();
7820         let expected_tail = expected_tail.as_ref();
7821 
7822         let expected_subs = SubstitutionTable::from_iter(
7823             subs.as_ref()
7824                 .iter()
7825                 .cloned()
7826                 .chain(expected_new_subs.as_ref().iter().cloned()),
7827         );
7828         let mut subs = SubstitutionTable::from_iter(subs.as_ref().iter().cloned());
7829 
7830         match P::parse(&ctx, &mut subs, IndexStr::from(input)) {
7831             Err(error) => panic!(
7832                 "Parsing {:?} as {} failed: {}",
7833                 String::from_utf8_lossy(input),
7834                 production,
7835                 error
7836             ),
7837             Ok((value, tail)) => {
7838                 if value != expected {
7839                     panic!(
7840                         "Parsing {:?} as {} produced\n\n{:#?}\n\nbut we expected\n\n{:#?}",
7841                         String::from_utf8_lossy(input),
7842                         production,
7843                         value,
7844                         expected
7845                     );
7846                 }
7847                 if tail != expected_tail {
7848                     panic!(
7849                         "Parsing {:?} as {} left a tail of {:?}, expected {:?}",
7850                         String::from_utf8_lossy(input),
7851                         production,
7852                         tail,
7853                         String::from_utf8_lossy(expected_tail)
7854                     );
7855                 }
7856                 if subs[..] != expected_subs[..] {
7857                     panic!(
7858                         "Parsing {:?} as {} produced a substitutions table of\n\n\
7859                          {:#?}\n\n\
7860                          but we expected\n\n\
7861                          {:#?}",
7862                         String::from_utf8_lossy(input),
7863                         production,
7864                         subs,
7865                         expected_subs
7866                     );
7867                 }
7868             }
7869         }
7870 
7871         log!("=== assert_parse_ok PASSED ====================================");
7872     }
7873 
simple_assert_parse_ok<P, I1, I2>( production: &'static str, input: I1, expected: P, expected_tail: I2, ) where P: Debug + Parse + PartialEq, I1: AsRef<[u8]>, I2: AsRef<[u8]>,7874     fn simple_assert_parse_ok<P, I1, I2>(
7875         production: &'static str,
7876         input: I1,
7877         expected: P,
7878         expected_tail: I2,
7879     ) where
7880         P: Debug + Parse + PartialEq,
7881         I1: AsRef<[u8]>,
7882         I2: AsRef<[u8]>,
7883     {
7884         assert_parse_ok::<P, _, _, _, _>(production, [], input, expected, expected_tail, []);
7885     }
7886 
assert_parse_err<P, S, I>(production: &'static str, subs: S, input: I, expected_error: Error) where P: Debug + Parse + PartialEq, S: AsRef<[Substitutable]>, I: AsRef<[u8]>,7887     fn assert_parse_err<P, S, I>(production: &'static str, subs: S, input: I, expected_error: Error)
7888     where
7889         P: Debug + Parse + PartialEq,
7890         S: AsRef<[Substitutable]>,
7891         I: AsRef<[u8]>,
7892     {
7893         let input = input.as_ref();
7894         let ctx = ParseContext::new(Default::default());
7895         let mut subs = SubstitutionTable::from_iter(subs.as_ref().iter().cloned());
7896 
7897         match P::parse(&ctx, &mut subs, IndexStr::from(input)) {
7898             Err(ref error) if *error == expected_error => {}
7899             Err(ref error) => {
7900                 panic!(
7901                     "Parsing {:?} as {} produced an error of kind {:?}, but we expected kind {:?}",
7902                     String::from_utf8_lossy(input),
7903                     production,
7904                     error,
7905                     expected_error
7906                 );
7907             }
7908             Ok((value, tail)) => {
7909                 panic!(
7910                     "Parsing {:?} as {} produced value\
7911                      \n\n\
7912                      {:#?}\
7913                      \n\n\
7914                      and tail {:?}, but we expected error kind {:?}",
7915                     String::from_utf8_lossy(input),
7916                     production,
7917                     value,
7918                     tail,
7919                     expected_error
7920                 );
7921             }
7922         }
7923 
7924         log!("=== assert_parse_err PASSED ===================================");
7925     }
7926 
simple_assert_parse_err<P, I>(production: &'static str, input: I, expected_error: Error) where P: Debug + Parse + PartialEq, I: AsRef<[u8]>,7927     fn simple_assert_parse_err<P, I>(production: &'static str, input: I, expected_error: Error)
7928     where
7929         P: Debug + Parse + PartialEq,
7930         I: AsRef<[u8]>,
7931     {
7932         assert_parse_err::<P, _, _>(production, [], input, expected_error);
7933     }
7934 
7935     #[test]
recursion_limit()7936     fn recursion_limit() {
7937         // Build the mangled symbol for the type `*****char` where the "*****"
7938         // is 10,000 pointer indirections. This is a valid type symbol, but
7939         // something that would cause us to blow the stack.
7940         let mut mangled = String::new();
7941         for _ in 0..10_000 {
7942             mangled.push('P');
7943         }
7944         mangled += "c";
7945 
7946         simple_assert_parse_err::<TypeHandle, _>("TypeHandle", mangled, Error::TooMuchRecursion);
7947     }
7948 
7949     macro_rules! assert_parse {
7950         ( $production:ident {
7951             $( with subs $subs:expr => {
7952                 Ok => {
7953                     $( $input:expr => {
7954                         $expected:expr ,
7955                         $expected_tail:expr ,
7956                         $expected_new_subs:expr
7957                     } )*
7958                 }
7959                 Err => {
7960                     $( $error_input:expr => $error:expr , )*
7961                 }
7962             } )*
7963         } ) => {
7964             $( $(
7965                 assert_parse_ok::<$production, _, _, _, _>(stringify!($production),
7966                                                            $subs,
7967                                                            $input,
7968                                                            $expected,
7969                                                            $expected_tail,
7970                                                            $expected_new_subs);
7971             )* )*
7972 
7973             $( $(
7974                 assert_parse_err::<$production, _, _>(stringify!($production),
7975                                                       $subs,
7976                                                       $error_input,
7977                                                       $error);
7978             )* )*
7979         };
7980 
7981         ( $production:ident {
7982             Ok => {
7983                 $( $input:expr => {
7984                     $expected:expr ,
7985                     $expected_tail:expr
7986                 } )*
7987             }
7988             Err => {
7989                 $( $error_input:expr => $error:expr , )*
7990             }
7991         } ) => {
7992             $(
7993                 simple_assert_parse_ok::<$production, _, _>(stringify!($production),
7994                                                             $input,
7995                                                             $expected,
7996                                                             $expected_tail);
7997             )*
7998 
7999 
8000             $(
8001                 simple_assert_parse_err::<$production, _>(stringify!($production),
8002                                                           $error_input,
8003                                                           $error);
8004             )*
8005         };
8006     }
8007 
8008     #[test]
parse_mangled_name()8009     fn parse_mangled_name() {
8010         assert_parse!(MangledName {
8011             Ok => {
8012                 b"_Z3foo..." => {
8013                     MangledName::Encoding(
8014                         Encoding::Data(
8015                             Name::Unscoped(
8016                                 UnscopedName::Unqualified(
8017                                     UnqualifiedName::Source(
8018                                         SourceName(Identifier {
8019                                             start: 3,
8020                                             end: 6,
8021                                         }))))), vec![]),
8022                     b"..."
8023                 }
8024                 b"_GLOBAL__I__Z3foo..." => {
8025                     MangledName::GlobalCtorDtor(
8026                         GlobalCtorDtor::Ctor(
8027                             Box::new(
8028                                 MangledName::Encoding(
8029                                     Encoding::Data(
8030                                         Name::Unscoped(
8031                                             UnscopedName::Unqualified(
8032                                                 UnqualifiedName::Source(
8033                                                     SourceName(
8034                                                         Identifier {
8035                                                             start: 14,
8036                                                             end: 17,
8037                                                         }))))), vec![])))),
8038                     b"..."
8039                 }
8040             }
8041             Err => {
8042                 b"_Y" => Error::UnexpectedText,
8043                 b"_Z" => Error::UnexpectedEnd,
8044                 b"_" => Error::UnexpectedEnd,
8045                 b"" => Error::UnexpectedEnd,
8046                 b"_GLOBAL_" => Error::UnexpectedEnd,
8047             }
8048         });
8049     }
8050 
8051     #[test]
parse_encoding()8052     fn parse_encoding() {
8053         assert_parse!(Encoding {
8054             with subs [] => {
8055                 Ok => {
8056                     b"3fooi..." => {
8057                         Encoding::Function(
8058                             Name::Unscoped(
8059                                 UnscopedName::Unqualified(
8060                                     UnqualifiedName::Source(
8061                                         SourceName(Identifier {
8062                                             start: 1,
8063                                             end: 4,
8064                                         })))),
8065                             BareFunctionType(vec![
8066                                 TypeHandle::Builtin(BuiltinType::Standard(StandardBuiltinType::Int))
8067                             ])),
8068                         b"...",
8069                         []
8070                     }
8071                     b"3foo..." => {
8072                         Encoding::Data(
8073                             Name::Unscoped(
8074                                 UnscopedName::Unqualified(
8075                                     UnqualifiedName::Source(
8076                                         SourceName(Identifier {
8077                                             start: 1,
8078                                             end: 4,
8079                                         }))))),
8080                         b"...",
8081                         []
8082                     }
8083                     b"GV3abc..." => {
8084                         Encoding::Special(
8085                             SpecialName::Guard(
8086                                 Name::Unscoped(
8087                                     UnscopedName::Unqualified(
8088                                         UnqualifiedName::Source(
8089                                             SourceName(Identifier {
8090                                                 start: 3,
8091                                                 end: 6,
8092                                             })))))),
8093                         b"...",
8094                         []
8095                     }
8096                 }
8097                 Err => {
8098                     b"zzz" => Error::UnexpectedText,
8099                     b"" => Error::UnexpectedEnd,
8100                 }
8101             }
8102         });
8103     }
8104 
8105     #[test]
parse_global_ctor_dtor()8106     fn parse_global_ctor_dtor() {
8107         assert_parse!(GlobalCtorDtor {
8108             Ok => {
8109                 b"_I__Z3foo..." => {
8110                     GlobalCtorDtor::Ctor(
8111                         Box::new(
8112                             MangledName::Encoding(
8113                                 Encoding::Data(
8114                                     Name::Unscoped(
8115                                         UnscopedName::Unqualified(
8116                                             UnqualifiedName::Source(
8117                                                 SourceName(
8118                                                     Identifier {
8119                                                         start: 6,
8120                                                         end: 9,
8121                                                     }))))), vec![]))),
8122                     b"..."
8123                 }
8124                 b".I__Z3foo..." => {
8125                     GlobalCtorDtor::Ctor(
8126                         Box::new(
8127                             MangledName::Encoding(
8128                                 Encoding::Data(
8129                                     Name::Unscoped(
8130                                         UnscopedName::Unqualified(
8131                                             UnqualifiedName::Source(
8132                                                 SourceName(
8133                                                     Identifier {
8134                                                         start: 6,
8135                                                         end: 9,
8136                                                     }))))), vec![]))),
8137                     b"..."
8138                 }
8139                 b"$I__Z3foo..." => {
8140                     GlobalCtorDtor::Ctor(
8141                         Box::new(
8142                             MangledName::Encoding(
8143                                 Encoding::Data(
8144                                     Name::Unscoped(
8145                                         UnscopedName::Unqualified(
8146                                             UnqualifiedName::Source(
8147                                                 SourceName(
8148                                                     Identifier {
8149                                                         start: 6,
8150                                                         end: 9,
8151                                                     }))))), vec![]))),
8152                     b"..."
8153                 }
8154                 b"_D__Z3foo..." => {
8155                     GlobalCtorDtor::Dtor(
8156                         Box::new(
8157                             MangledName::Encoding(
8158                                 Encoding::Data(
8159                                     Name::Unscoped(
8160                                         UnscopedName::Unqualified(
8161                                             UnqualifiedName::Source(
8162                                                 SourceName(
8163                                                     Identifier {
8164                                                         start: 6,
8165                                                         end: 9,
8166                                                     }))))), vec![]))),
8167                     b"..."
8168                 }
8169                 b".D__Z3foo..." => {
8170                     GlobalCtorDtor::Dtor(
8171                         Box::new(
8172                             MangledName::Encoding(
8173                                 Encoding::Data(
8174                                     Name::Unscoped(
8175                                         UnscopedName::Unqualified(
8176                                             UnqualifiedName::Source(
8177                                                 SourceName(
8178                                                     Identifier {
8179                                                         start: 6,
8180                                                         end: 9,
8181                                                     }))))), vec![]))),
8182                     b"..."
8183                 }
8184                 b"$D__Z3foo..." => {
8185                     GlobalCtorDtor::Dtor(
8186                         Box::new(
8187                             MangledName::Encoding(
8188                                 Encoding::Data(
8189                                     Name::Unscoped(
8190                                         UnscopedName::Unqualified(
8191                                             UnqualifiedName::Source(
8192                                                 SourceName(
8193                                                     Identifier {
8194                                                         start: 6,
8195                                                         end: 9,
8196                                                     }))))), vec![]))),
8197                     b"..."
8198                 }
8199             }
8200             Err => {
8201                 b"_I" => Error::UnexpectedEnd,
8202                 b"_" => Error::UnexpectedEnd,
8203                 b"" => Error::UnexpectedEnd,
8204                 b"blag" => Error::UnexpectedText,
8205                 b"_J" => Error::UnexpectedText,
8206                 b"_IJ" => Error::UnexpectedText,
8207             }
8208         });
8209     }
8210 
8211     #[test]
parse_name()8212     fn parse_name() {
8213         assert_parse!(Name {
8214             with subs [
8215                 Substitutable::Prefix(
8216                     Prefix::Unqualified(
8217                         UnqualifiedName::Operator(OperatorName::Simple(SimpleOperatorName::New)))),
8218                 Substitutable::Prefix(
8219                     Prefix::Nested(PrefixHandle::BackReference(0),
8220                                    UnqualifiedName::Operator(OperatorName::Simple(SimpleOperatorName::New)))),
8221             ] => {
8222                 Ok => {
8223                     b"NS0_3abcE..." => {
8224                         Name::Nested(NestedName::Unqualified(CvQualifiers::default(),
8225                                                              None,
8226                                                              PrefixHandle::BackReference(1),
8227                                                              UnqualifiedName::Source(SourceName(Identifier {
8228                                                                  start: 5,
8229                                                                  end: 8,
8230                                                              })))),
8231                         b"...",
8232                         []
8233                     }
8234                     b"3abc..." => {
8235                         Name::Unscoped(
8236                             UnscopedName::Unqualified(
8237                                 UnqualifiedName::Source(
8238                                     SourceName(Identifier {
8239                                         start: 1,
8240                                         end: 4,
8241                                     })))),
8242                         b"...",
8243                         []
8244                     }
8245                     b"dlIcE..." => {
8246                         Name::UnscopedTemplate(
8247                             UnscopedTemplateNameHandle::BackReference(2),
8248                             TemplateArgs(vec![
8249                                 TemplateArg::Type(
8250                                     TypeHandle::Builtin(
8251                                         BuiltinType::Standard(StandardBuiltinType::Char)))
8252                             ])),
8253                         b"...",
8254                         [
8255                             Substitutable::UnscopedTemplateName(
8256                                 UnscopedTemplateName(
8257                                     UnscopedName::Unqualified(
8258                                         UnqualifiedName::Operator(
8259                                             OperatorName::Simple(
8260                                                 SimpleOperatorName::Delete))))),
8261                         ]
8262                     }
8263                     b"Z3abcEs..." => {
8264                         Name::Local(
8265                             LocalName::Relative(
8266                                 Box::new(Encoding::Data(
8267                                     Name::Unscoped(
8268                                         UnscopedName::Unqualified(
8269                                             UnqualifiedName::Source(
8270                                                 SourceName(Identifier {
8271                                                     start: 2,
8272                                                     end: 5,
8273                                                 })))))),
8274                                 None,
8275                                 None)),
8276                         b"...",
8277                         []
8278                     }
8279                 }
8280                 Err => {
8281                     b"zzz" => Error::UnexpectedText,
8282                     b"" => Error::UnexpectedEnd,
8283                 }
8284             }
8285         });
8286     }
8287 
8288     #[test]
parse_unscoped_template_name_handle()8289     fn parse_unscoped_template_name_handle() {
8290         assert_parse!(UnscopedTemplateNameHandle {
8291             with subs [
8292                 Substitutable::UnscopedTemplateName(
8293                     UnscopedTemplateName(
8294                         UnscopedName::Unqualified(
8295                             UnqualifiedName::Operator(
8296                                 OperatorName::Simple(
8297                                     SimpleOperatorName::New))))),
8298             ] => {
8299                 Ok => {
8300                     b"S_..." => {
8301                         UnscopedTemplateNameHandle::BackReference(0),
8302                         b"...",
8303                         []
8304                     }
8305                     b"dl..." => {
8306                         UnscopedTemplateNameHandle::BackReference(1),
8307                         b"...",
8308                         [
8309                             Substitutable::UnscopedTemplateName(
8310                                 UnscopedTemplateName(
8311                                     UnscopedName::Unqualified(
8312                                         UnqualifiedName::Operator(
8313                                             OperatorName::Simple(
8314                                                 SimpleOperatorName::Delete)))))
8315                         ]
8316                     }
8317                 }
8318                 Err => {
8319                     b"zzzz" => Error::UnexpectedText,
8320                     b"" => Error::UnexpectedEnd,
8321                 }
8322             }
8323         });
8324     }
8325 
8326     #[test]
parse_nested_name()8327     fn parse_nested_name() {
8328         // <nested-name> ::= N [<CV-qualifiers>] [<ref-qualifier>] <prefix> <unqualified-name> E
8329         //               ::= N [<CV-qualifiers>] [<ref-qualifier>] <template-prefix> <template-args> E
8330         assert_parse!(NestedName {
8331             with subs [
8332                 Substitutable::Prefix(
8333                     Prefix::Unqualified(
8334                         UnqualifiedName::Operator(
8335                             OperatorName::Simple(
8336                                 SimpleOperatorName::New)))),
8337             ] => {
8338                 Ok => {
8339                     b"NKOS_3abcE..." => {
8340                         NestedName::Unqualified(
8341                             CvQualifiers {
8342                                 restrict: false,
8343                                 volatile: false,
8344                                 const_: true,
8345                             },
8346                             Some(RefQualifier::RValueRef),
8347                             PrefixHandle::BackReference(0),
8348                             UnqualifiedName::Source(
8349                                 SourceName(Identifier {
8350                                     start: 6,
8351                                     end: 9,
8352                                 }))),
8353                         b"...",
8354                         []
8355                     }
8356                     b"NOS_3abcE..." => {
8357                         NestedName::Unqualified(
8358                             CvQualifiers {
8359                                 restrict: false,
8360                                 volatile: false,
8361                                 const_: false,
8362                             },
8363                             Some(RefQualifier::RValueRef),
8364                             PrefixHandle::BackReference(0),
8365                             UnqualifiedName::Source(
8366                                 SourceName(Identifier {
8367                                     start: 5,
8368                                     end: 8,
8369                                 }))),
8370                         b"...",
8371                         []
8372                     }
8373                     b"NS_3abcE..." => {
8374                         NestedName::Unqualified(
8375                             CvQualifiers {
8376                                 restrict: false,
8377                                 volatile: false,
8378                                 const_: false,
8379                             },
8380                             None,
8381                             PrefixHandle::BackReference(0),
8382                             UnqualifiedName::Source(
8383                                 SourceName(Identifier {
8384                                     start: 4,
8385                                     end: 7,
8386                                 }))),
8387                         b"...",
8388                         []
8389                     }
8390                     b"NKOS_3abcIJEEE..." => {
8391                         NestedName::Template(
8392                             CvQualifiers {
8393                                 restrict: false,
8394                                 volatile: false,
8395                                 const_: true,
8396                             },
8397                             Some(RefQualifier::RValueRef),
8398                             PrefixHandle::NonSubstitution(NonSubstitution(0))),
8399                         b"...",
8400                         [
8401                             Substitutable::Prefix(
8402                                 Prefix::Nested(
8403                                     PrefixHandle::BackReference(0),
8404                                     UnqualifiedName::Source(
8405                                         SourceName(Identifier {
8406                                             start: 6,
8407                                             end: 9,
8408                                         })))),
8409                         ]
8410                     }
8411                     b"NOS_3abcIJEEE..." => {
8412                         NestedName::Template(
8413                             CvQualifiers {
8414                                 restrict: false,
8415                                 volatile: false,
8416                                 const_: false,
8417                             },
8418                             Some(RefQualifier::RValueRef),
8419                             PrefixHandle::NonSubstitution(NonSubstitution(0))),
8420                         b"...",
8421                         [
8422                             Substitutable::Prefix(
8423                                 Prefix::Nested(
8424                                     PrefixHandle::BackReference(0),
8425                                     UnqualifiedName::Source(
8426                                         SourceName(Identifier {
8427                                             start: 5,
8428                                             end: 8,
8429                                         })))),
8430                         ]
8431                     }
8432                     b"NS_3abcIJEEE..." => {
8433                         NestedName::Template(
8434                             CvQualifiers {
8435                                 restrict: false,
8436                                 volatile: false,
8437                                 const_: false,
8438                             },
8439                             None,
8440                             PrefixHandle::NonSubstitution(NonSubstitution(0))),
8441                         b"...",
8442                         [
8443                             Substitutable::Prefix(
8444                                 Prefix::Nested(
8445                                     PrefixHandle::BackReference(0),
8446                                     UnqualifiedName::Source(
8447                                         SourceName(Identifier {
8448                                             start: 4,
8449                                             end: 7,
8450                                         })))),
8451                         ]
8452                     }
8453                 }
8454                 Err => {
8455                     // Ends with a prefix that is not a name or template.
8456                     b"NS_E..." => Error::UnexpectedText,
8457                     b"NS_DttrEE..." => Error::UnexpectedText,
8458 
8459                     b"zzz" => Error::UnexpectedText,
8460                     b"Nzzz" => Error::UnexpectedText,
8461                     b"NKzzz" => Error::UnexpectedText,
8462                     b"NKOzzz" => Error::UnexpectedText,
8463                     b"NKO3abczzz" => Error::UnexpectedText,
8464                     b"NKO3abc3abczzz" => Error::UnexpectedText,
8465                     b"" => Error::UnexpectedEnd,
8466                     b"N" => Error::UnexpectedEnd,
8467                     b"NK" => Error::UnexpectedEnd,
8468                     b"NKO" => Error::UnexpectedEnd,
8469                     b"NKO3abc" => Error::UnexpectedEnd,
8470                     b"NKO3abc3abc" => Error::UnexpectedEnd,
8471                 }
8472             }
8473         });
8474     }
8475 
8476     #[test]
parse_prefix_handle()8477     fn parse_prefix_handle() {
8478         // <prefix> ::= <unqualified-name>
8479         //          ::= <prefix> <unqualified-name>
8480         //          ::= <template-prefix> <template-args>
8481         //          ::= <template-param>
8482         //          ::= <decltype>
8483         //          ::= <prefix> <data-member-prefix>
8484         //          ::= <substitution>
8485         assert_parse!(PrefixHandle {
8486             with subs [
8487                 Substitutable::Prefix(
8488                     Prefix::Unqualified(
8489                         UnqualifiedName::Operator(
8490                             OperatorName::Simple(
8491                                 SimpleOperatorName::New)))),
8492             ] => {
8493                 Ok => {
8494                     b"3foo..." => {
8495                         PrefixHandle::BackReference(1),
8496                         b"...",
8497                         [
8498                             Substitutable::Prefix(
8499                                 Prefix::Unqualified(
8500                                     UnqualifiedName::Source(
8501                                         SourceName(Identifier {
8502                                             start: 1,
8503                                             end: 4,
8504                                         }))))
8505                         ]
8506                     }
8507                     b"3abc3def..." => {
8508                         PrefixHandle::BackReference(2),
8509                         b"...",
8510                         [
8511                             Substitutable::Prefix(
8512                                 Prefix::Unqualified(
8513                                     UnqualifiedName::Source(
8514                                         SourceName(Identifier {
8515                                             start: 1,
8516                                             end: 4,
8517                                         })))),
8518                             Substitutable::Prefix(
8519                                 Prefix::Nested(
8520                                     PrefixHandle::BackReference(1),
8521                                     UnqualifiedName::Source(
8522                                         SourceName(Identifier {
8523                                             start: 5,
8524                                             end: 8,
8525                                         })))),
8526                         ]
8527                     }
8528                     b"3fooIJEE..." => {
8529                         PrefixHandle::BackReference(2),
8530                         b"...",
8531                         [
8532                             Substitutable::Prefix(
8533                                 Prefix::Unqualified(
8534                                     UnqualifiedName::Source(
8535                                         SourceName(Identifier {
8536                                             start: 1,
8537                                             end: 4,
8538                                         })))),
8539                             Substitutable::Prefix(
8540                                 Prefix::Template(PrefixHandle::BackReference(1),
8541                                                  TemplateArgs(vec![
8542                                                      TemplateArg::ArgPack(vec![]),
8543                                                  ])))
8544                         ]
8545                     }
8546                     b"T_..." => {
8547                         PrefixHandle::BackReference(1),
8548                         b"...",
8549                         [
8550                             Substitutable::Prefix(Prefix::TemplateParam(TemplateParam(0))),
8551                         ]
8552                     }
8553                     b"DTtrE..." => {
8554                         PrefixHandle::BackReference(1),
8555                         b"...",
8556                         [
8557                             Substitutable::Prefix(
8558                                 Prefix::Decltype(
8559                                     Decltype::Expression(Expression::Rethrow))),
8560                         ]
8561                     }
8562                     b"3abc3defM..." => {
8563                         PrefixHandle::BackReference(2),
8564                         b"...",
8565                         [
8566                             Substitutable::Prefix(
8567                                 Prefix::Unqualified(
8568                                     UnqualifiedName::Source(
8569                                         SourceName(Identifier {
8570                                             start: 1,
8571                                             end: 4,
8572                                         })))),
8573                             Substitutable::Prefix(
8574                                 Prefix::DataMember(
8575                                     PrefixHandle::BackReference(1),
8576                                     DataMemberPrefix(
8577                                         SourceName(Identifier {
8578                                             start: 5,
8579                                             end: 8,
8580                                         })))),
8581                         ]
8582                     }
8583                     b"S_..." => {
8584                         PrefixHandle::BackReference(0),
8585                         b"...",
8586                         []
8587                     }
8588                     // The trailing E and <nested-name> case...
8589                     b"3abc3defE..." => {
8590                         PrefixHandle::NonSubstitution(NonSubstitution(0)),
8591                         b"E...",
8592                         [
8593                             Substitutable::Prefix(
8594                                 Prefix::Unqualified(
8595                                     UnqualifiedName::Source(
8596                                         SourceName(Identifier {
8597                                             start: 1,
8598                                             end: 4,
8599                                         })))),
8600                         ]
8601                     }
8602                 }
8603                 Err => {
8604                     b"zzz" => Error::UnexpectedText,
8605                     b"" => Error::UnexpectedEnd,
8606                 }
8607             }
8608         });
8609     }
8610 
8611     #[test]
parse_type_handle()8612     fn parse_type_handle() {
8613         assert_parse!(TypeHandle {
8614             with subs [
8615                 Substitutable::Type(
8616                     Type::PointerTo(
8617                         TypeHandle::Builtin(BuiltinType::Standard(StandardBuiltinType::Char)))),
8618             ] => {
8619                 Ok => {
8620                     b"S_..." => {
8621                         TypeHandle::BackReference(0),
8622                         b"...",
8623                         []
8624                     }
8625                     b"c..." => {
8626                         TypeHandle::Builtin(BuiltinType::Standard(StandardBuiltinType::Char)),
8627                         b"...",
8628                         []
8629                     }
8630                     b"FS_E..." => {
8631                         TypeHandle::BackReference(1),
8632                         b"...",
8633                         [
8634                             Substitutable::Type(
8635                                 Type::Function(FunctionType {
8636                                     cv_qualifiers: CvQualifiers {
8637                                         restrict: false,
8638                                         volatile: false,
8639                                         const_: false,
8640                                     },
8641                                     transaction_safe: false,
8642                                     extern_c: false,
8643                                     bare: BareFunctionType(vec![TypeHandle::BackReference(0)]),
8644                                     ref_qualifier: None,
8645                                 })),
8646                         ]
8647                     }
8648                     b"A_S_..." => {
8649                         TypeHandle::BackReference(1),
8650                         b"...",
8651                         [
8652                             Substitutable::Type(
8653                                 Type::Array(ArrayType::NoDimension(TypeHandle::BackReference(0)))),
8654                         ]
8655                     }
8656                     b"MS_S_..." => {
8657                         TypeHandle::BackReference(1),
8658                         b"...",
8659                         [
8660                             Substitutable::Type(
8661                                 Type::PointerToMember(
8662                                     PointerToMemberType(TypeHandle::BackReference(0),
8663                                                         TypeHandle::BackReference(0)))),
8664                         ]
8665                     }
8666                     b"T_..." => {
8667                         TypeHandle::BackReference(1),
8668                         b"...",
8669                         [
8670                             Substitutable::Type(Type::TemplateParam(TemplateParam(0))),
8671                         ]
8672                     }
8673                     b"T_IS_E..." => {
8674                         TypeHandle::BackReference(2),
8675                         b"...",
8676                         [
8677                             Substitutable::TemplateTemplateParam(
8678                                 TemplateTemplateParam(TemplateParam(0))),
8679                             Substitutable::Type(
8680                                 Type::TemplateTemplate(
8681                                     TemplateTemplateParamHandle::BackReference(1),
8682                                     TemplateArgs(vec![
8683                                         TemplateArg::Type(TypeHandle::BackReference(0))
8684                                     ]))),
8685                         ]
8686                     }
8687                     b"DTtrE..." => {
8688                         TypeHandle::BackReference(1),
8689                         b"...",
8690                         [
8691                             Substitutable::Type(
8692                                 Type::Decltype(Decltype::Expression(Expression::Rethrow))),
8693                         ]
8694                     }
8695                     b"KS_..." => {
8696                         TypeHandle::BackReference(1),
8697                         b"...",
8698                         [
8699                             Substitutable::Type(Type::Qualified(CvQualifiers {
8700                                 restrict: false,
8701                                 volatile: false,
8702                                 const_: true,
8703                             }, TypeHandle::BackReference(0)))
8704                         ]
8705                     }
8706                     b"PS_..." => {
8707                         TypeHandle::BackReference(1),
8708                         b"...",
8709                         [
8710                             Substitutable::Type(Type::PointerTo(TypeHandle::BackReference(0)))
8711                         ]
8712                     }
8713                     b"RS_..." => {
8714                         TypeHandle::BackReference(1),
8715                         b"...",
8716                         [
8717                             Substitutable::Type(Type::LvalueRef(TypeHandle::BackReference(0)))
8718                         ]
8719                     }
8720                     b"OS_..." => {
8721                         TypeHandle::BackReference(1),
8722                         b"...",
8723                         [
8724                             Substitutable::Type(Type::RvalueRef(TypeHandle::BackReference(0)))
8725                         ]
8726                     }
8727                     b"CS_..." => {
8728                         TypeHandle::BackReference(1),
8729                         b"...",
8730                         [
8731                             Substitutable::Type(Type::Complex(TypeHandle::BackReference(0)))
8732                         ]
8733                     }
8734                     b"GS_..." => {
8735                         TypeHandle::BackReference(1),
8736                         b"...",
8737                         [
8738                             Substitutable::Type(Type::Imaginary(TypeHandle::BackReference(0)))
8739                         ]
8740                     }
8741                     b"U3abcS_..." => {
8742                         TypeHandle::BackReference(1),
8743                         b"...",
8744                         [
8745                             Substitutable::Type(
8746                                 Type::VendorExtension(
8747                                     SourceName(Identifier {
8748                                         start: 2,
8749                                         end: 5,
8750                                     }),
8751                                     None,
8752                                     TypeHandle::BackReference(0)))
8753                         ]
8754                     }
8755                     b"U3abcIS_ES_..." => {
8756                         TypeHandle::BackReference(1),
8757                         b"...",
8758                         [
8759                             Substitutable::Type(
8760                                 Type::VendorExtension(
8761                                     SourceName(Identifier {
8762                                         start: 2,
8763                                         end: 5,
8764                                     }),
8765                                     Some(TemplateArgs(vec![
8766                                         TemplateArg::Type(TypeHandle::BackReference(0))
8767                                     ])),
8768                                     TypeHandle::BackReference(0)))
8769                         ]
8770                     }
8771                     b"DpS_..." => {
8772                         TypeHandle::BackReference(1),
8773                         b"...",
8774                         [
8775                             Substitutable::Type(
8776                                 Type::PackExpansion(TypeHandle::BackReference(0))),
8777                         ]
8778                     }
8779                     b"3abc..." => {
8780                         TypeHandle::BackReference(1),
8781                         b"...",
8782                         [
8783                             Substitutable::Type(
8784                                 Type::ClassEnum(
8785                                     ClassEnumType::Named(
8786                                         Name::Unscoped(
8787                                             UnscopedName::Unqualified(
8788                                                 UnqualifiedName::Source(
8789                                                     SourceName(Identifier {
8790                                                         start: 1,
8791                                                         end: 4,
8792                                                     })))))))
8793                         ]
8794                     }
8795                 }
8796                 Err => {
8797                     b"P" => Error::UnexpectedEnd,
8798                     b"R" => Error::UnexpectedEnd,
8799                     b"O" => Error::UnexpectedEnd,
8800                     b"C" => Error::UnexpectedEnd,
8801                     b"G" => Error::UnexpectedEnd,
8802                     b"Dp" => Error::UnexpectedEnd,
8803                     b"D" => Error::UnexpectedEnd,
8804                     b"P" => Error::UnexpectedEnd,
8805                     b"" => Error::UnexpectedEnd,
8806                 }
8807             }
8808         });
8809     }
8810 
8811     #[test]
parse_function_type()8812     fn parse_function_type() {
8813         assert_parse!(FunctionType {
8814             with subs [
8815                 Substitutable::Type(
8816                     Type::PointerTo(
8817                         TypeHandle::Builtin(BuiltinType::Standard(StandardBuiltinType::Char)))),
8818             ] => {
8819                 Ok => {
8820                     b"KDxFYS_RE..." => {
8821                         FunctionType {
8822                             cv_qualifiers: CvQualifiers {
8823                                 restrict: false,
8824                                 volatile: false,
8825                                 const_: true,
8826                             },
8827                             transaction_safe: true,
8828                             extern_c: true,
8829                             bare: BareFunctionType(vec![TypeHandle::BackReference(0)]),
8830                             ref_qualifier: Some(RefQualifier::LValueRef),
8831                         },
8832                         b"...",
8833                         []
8834                     }
8835                     b"DxFYS_RE..." => {
8836                         FunctionType {
8837                             cv_qualifiers: CvQualifiers {
8838                                 restrict: false,
8839                                 volatile: false,
8840                                 const_: false,
8841                             },
8842                             transaction_safe: true,
8843                             extern_c: true,
8844                             bare: BareFunctionType(vec![TypeHandle::BackReference(0)]),
8845                             ref_qualifier: Some(RefQualifier::LValueRef),
8846                         },
8847                         b"...",
8848                         []
8849                     }
8850                     b"FYS_RE..." => {
8851                         FunctionType {
8852                             cv_qualifiers: CvQualifiers {
8853                                 restrict: false,
8854                                 volatile: false,
8855                                 const_: false,
8856                             },
8857                             transaction_safe: false,
8858                             extern_c: true,
8859                             bare: BareFunctionType(vec![TypeHandle::BackReference(0)]),
8860                             ref_qualifier: Some(RefQualifier::LValueRef),
8861                         },
8862                         b"...",
8863                         []
8864                     }
8865                     b"FS_RE..." => {
8866                         FunctionType {
8867                             cv_qualifiers: CvQualifiers {
8868                                 restrict: false,
8869                                 volatile: false,
8870                                 const_: false,
8871                             },
8872                             transaction_safe: false,
8873                             extern_c: false,
8874                             bare: BareFunctionType(vec![TypeHandle::BackReference(0)]),
8875                             ref_qualifier: Some(RefQualifier::LValueRef),
8876                         },
8877                         b"...",
8878                         []
8879                     }
8880                     b"FS_E..." => {
8881                         FunctionType {
8882                             cv_qualifiers: CvQualifiers {
8883                                 restrict: false,
8884                                 volatile: false,
8885                                 const_: false,
8886                             },
8887                             transaction_safe: false,
8888                             extern_c: false,
8889                             bare: BareFunctionType(vec![TypeHandle::BackReference(0)]),
8890                             ref_qualifier: None,
8891                         },
8892                         b"...",
8893                         []
8894                     }
8895                 }
8896                 Err => {
8897                     b"DFYS_E" => Error::UnexpectedText,
8898                     b"KKFS_E" => Error::UnexpectedText,
8899                     b"FYS_..." => Error::UnexpectedText,
8900                     b"FYS_" => Error::UnexpectedEnd,
8901                     b"F" => Error::UnexpectedEnd,
8902                     b"" => Error::UnexpectedEnd,
8903                 }
8904             }
8905         });
8906     }
8907 
8908     #[test]
parse_bare_function_type()8909     fn parse_bare_function_type() {
8910         assert_parse!(BareFunctionType {
8911             with subs [
8912                 Substitutable::Type(
8913                     Type::PointerTo(
8914                         TypeHandle::Builtin(BuiltinType::Standard(StandardBuiltinType::Char)))),
8915             ] => {
8916                 Ok => {
8917                     b"S_S_..." => {
8918                         BareFunctionType(vec![
8919                             TypeHandle::BackReference(0),
8920                             TypeHandle::BackReference(0),
8921                         ]),
8922                         b"...",
8923                         []
8924                     }
8925                 }
8926                 Err => {
8927                     b"" => Error::UnexpectedEnd,
8928                 }
8929             }
8930         });
8931     }
8932 
8933     #[test]
parse_decltype()8934     fn parse_decltype() {
8935         assert_parse!(Decltype {
8936             Ok => {
8937                 b"DTtrE..." => {
8938                     Decltype::Expression(Expression::Rethrow),
8939                     b"..."
8940                 }
8941                 b"DttrE..." => {
8942                     Decltype::IdExpression(Expression::Rethrow),
8943                     b"..."
8944                 }
8945             }
8946             Err => {
8947                 b"Dtrtz" => Error::UnexpectedText,
8948                 b"DTrtz" => Error::UnexpectedText,
8949                 b"Dz" => Error::UnexpectedText,
8950                 b"Dtrt" => Error::UnexpectedText,
8951                 b"DTrt" => Error::UnexpectedText,
8952                 b"Dt" => Error::UnexpectedEnd,
8953                 b"DT" => Error::UnexpectedEnd,
8954                 b"D" => Error::UnexpectedEnd,
8955                 b"" => Error::UnexpectedEnd,
8956             }
8957         });
8958     }
8959 
8960     #[test]
parse_class_enum_type()8961     fn parse_class_enum_type() {
8962         assert_parse!(ClassEnumType {
8963             Ok => {
8964                 b"3abc..." => {
8965                     ClassEnumType::Named(
8966                         Name::Unscoped(
8967                             UnscopedName::Unqualified(
8968                                 UnqualifiedName::Source(
8969                                     SourceName(Identifier {
8970                                         start: 1,
8971                                         end: 4,
8972                                     }))))),
8973                     b"..."
8974                 }
8975                 b"Ts3abc..." => {
8976                     ClassEnumType::ElaboratedStruct(
8977                         Name::Unscoped(
8978                             UnscopedName::Unqualified(
8979                                 UnqualifiedName::Source(
8980                                     SourceName(Identifier {
8981                                         start: 3,
8982                                         end: 6,
8983                                     }))))),
8984                     b"..."
8985                 }
8986                 b"Tu3abc..." => {
8987                     ClassEnumType::ElaboratedUnion(
8988                         Name::Unscoped(
8989                             UnscopedName::Unqualified(
8990                                 UnqualifiedName::Source(
8991                                     SourceName(Identifier {
8992                                         start: 3,
8993                                         end: 6,
8994                                     }))))),
8995                     b"..."
8996                 }
8997                 b"Te3abc..." => {
8998                     ClassEnumType::ElaboratedEnum(
8999                         Name::Unscoped(
9000                             UnscopedName::Unqualified(
9001                                 UnqualifiedName::Source(
9002                                     SourceName(Identifier {
9003                                         start: 3,
9004                                         end: 6,
9005                                     }))))),
9006                     b"..."
9007                 }
9008             }
9009             Err => {
9010                 b"zzz" => Error::UnexpectedText,
9011                 b"Tzzz" => Error::UnexpectedText,
9012                 b"T" => Error::UnexpectedEnd,
9013                 b"" => Error::UnexpectedEnd,
9014             }
9015         });
9016     }
9017 
9018     #[test]
parse_array_type()9019     fn parse_array_type() {
9020         assert_parse!(ArrayType {
9021             with subs [
9022                 Substitutable::Type(Type::Decltype(Decltype::Expression(Expression::Rethrow)))
9023             ] => {
9024                 Ok => {
9025                     b"A10_S_..." => {
9026                         ArrayType::DimensionNumber(10, TypeHandle::BackReference(0)),
9027                         b"...",
9028                         []
9029                     }
9030                     b"A10_Sb..." => {
9031                         ArrayType::DimensionNumber(10,
9032                                                    TypeHandle::WellKnown(
9033                                                        WellKnownComponent::StdString1)),
9034                         b"...",
9035                         []
9036                     }
9037                     b"Atr_S_..." => {
9038                         ArrayType::DimensionExpression(Expression::Rethrow,
9039                                                        TypeHandle::BackReference(0)),
9040                         b"...",
9041                         []
9042                     }
9043                     b"A_S_..." => {
9044                         ArrayType::NoDimension(TypeHandle::BackReference(0)),
9045                         b"...",
9046                         []
9047                     }
9048                 }
9049                 Err => {
9050                     b"A10_" => Error::UnexpectedEnd,
9051                     b"A10" => Error::UnexpectedEnd,
9052                     b"A" => Error::UnexpectedEnd,
9053                     b"" => Error::UnexpectedEnd,
9054                     b"A10_..." => Error::UnexpectedText,
9055                     b"A10..." => Error::UnexpectedText,
9056                     b"A..." => Error::UnexpectedText,
9057                     b"..." => Error::UnexpectedText,
9058                 }
9059             }
9060         });
9061     }
9062 
9063     #[test]
parse_vector_type()9064     fn parse_vector_type() {
9065         assert_parse!(VectorType {
9066             with subs [
9067                 Substitutable::Type(Type::Decltype(Decltype::Expression(Expression::Rethrow)))
9068             ] => {
9069                 Ok => {
9070                     b"Dv10_S_..." => {
9071                         VectorType::DimensionNumber(10, TypeHandle::BackReference(0)),
9072                         b"...",
9073                         []
9074                     }
9075                     b"Dv10_Sb..." => {
9076                         VectorType::DimensionNumber(10,
9077                                                     TypeHandle::WellKnown(
9078                                                         WellKnownComponent::StdString1)),
9079                         b"...",
9080                         []
9081                     }
9082                     b"Dv_tr_S_..." => {
9083                         VectorType::DimensionExpression(Expression::Rethrow,
9084                                                         TypeHandle::BackReference(0)),
9085                         b"...",
9086                         []
9087                     }
9088                 }
9089                 Err => {
9090                     b"Dq" => Error::UnexpectedText,
9091                     b"Dv" => Error::UnexpectedEnd,
9092                     b"Dv42_" => Error::UnexpectedEnd,
9093                     b"Dv42_..." => Error::UnexpectedText,
9094                     b"Dvtr_" => Error::UnexpectedText,
9095                     b"" => Error::UnexpectedEnd,
9096                     b"..." => Error::UnexpectedText,
9097                 }
9098             }
9099         });
9100     }
9101 
9102     #[test]
parse_pointer_to_member_type()9103     fn parse_pointer_to_member_type() {
9104         assert_parse!(PointerToMemberType {
9105             with subs [
9106                 Substitutable::Type(Type::Decltype(Decltype::Expression(Expression::Rethrow)))
9107             ] => {
9108                 Ok => {
9109                     b"MS_S_..." => {
9110                         PointerToMemberType(TypeHandle::BackReference(0),
9111                                             TypeHandle::BackReference(0)),
9112                         b"...",
9113                         []
9114                     }
9115                 }
9116                 Err => {
9117                     b"MS_S" => Error::UnexpectedEnd,
9118                     b"MS_" => Error::UnexpectedEnd,
9119                     b"MS" => Error::UnexpectedEnd,
9120                     b"M" => Error::UnexpectedEnd,
9121                     b"" => Error::UnexpectedEnd,
9122                     b"MS_..." => Error::UnexpectedText,
9123                     b"M..." => Error::UnexpectedText,
9124                     b"..." => Error::UnexpectedText,
9125                 }
9126             }
9127         });
9128     }
9129 
9130     #[test]
parse_template_template_param_handle()9131     fn parse_template_template_param_handle() {
9132         assert_parse!(TemplateTemplateParamHandle {
9133             with subs [
9134                 Substitutable::TemplateTemplateParam(TemplateTemplateParam(TemplateParam(0)))
9135             ] => {
9136                 Ok => {
9137                     b"S_..." => {
9138                         TemplateTemplateParamHandle::BackReference(0),
9139                         b"...",
9140                         []
9141                     }
9142                     b"T1_..." => {
9143                         TemplateTemplateParamHandle::BackReference(1),
9144                         b"...",
9145                         [
9146                             Substitutable::TemplateTemplateParam(TemplateTemplateParam(TemplateParam(2)))
9147                         ]
9148                     }
9149                 }
9150                 Err => {
9151                     b"S" => Error::UnexpectedText,
9152                     b"T" => Error::UnexpectedEnd,
9153                     b"" => Error::UnexpectedEnd,
9154                     b"S..." => Error::UnexpectedText,
9155                     b"T..." => Error::UnexpectedText,
9156                     b"..." => Error::UnexpectedText,
9157                 }
9158             }
9159         });
9160     }
9161 
9162     #[test]
parse_template_args()9163     fn parse_template_args() {
9164         assert_parse!(TemplateArgs {
9165             with subs [
9166                 Substitutable::Type(Type::Decltype(Decltype::Expression(Expression::Rethrow)))
9167             ] => {
9168                 Ok => {
9169                     b"IS_E..." => {
9170                         TemplateArgs(vec![TemplateArg::Type(TypeHandle::BackReference(0))]),
9171                         b"...",
9172                         []
9173                     }
9174                     b"IS_S_S_S_E..." => {
9175                         TemplateArgs(vec![
9176                             TemplateArg::Type(TypeHandle::BackReference(0)),
9177                             TemplateArg::Type(TypeHandle::BackReference(0)),
9178                             TemplateArg::Type(TypeHandle::BackReference(0)),
9179                             TemplateArg::Type(TypeHandle::BackReference(0)),
9180                         ]),
9181                         b"...",
9182                         []
9183                     }
9184                 }
9185                 Err => {
9186                     b"zzz" => Error::UnexpectedText,
9187                     b"IE" => Error::UnexpectedText,
9188                     b"IS_" => Error::UnexpectedEnd,
9189                     b"I" => Error::UnexpectedEnd,
9190                     b"" => Error::UnexpectedEnd,
9191                 }
9192             }
9193         });
9194     }
9195 
9196     #[test]
parse_template_arg()9197     fn parse_template_arg() {
9198         assert_parse!(TemplateArg {
9199             with subs [
9200                 Substitutable::Type(Type::Decltype(Decltype::Expression(Expression::Rethrow)))
9201             ] => {
9202                 Ok => {
9203                     b"S_..." => {
9204                         TemplateArg::Type(TypeHandle::BackReference(0)),
9205                         b"...",
9206                         []
9207                     }
9208                     b"XtrE..." => {
9209                         TemplateArg::Expression(Expression::Rethrow),
9210                         b"...",
9211                         []
9212                     }
9213                     b"XsrS_1QE..." => {
9214                         TemplateArg::Expression(
9215                             Expression::UnresolvedName(
9216                                 UnresolvedName::Nested1(
9217                                     UnresolvedTypeHandle::BackReference(0),
9218                                     vec![],
9219                                     BaseUnresolvedName::Name(
9220                                         SimpleId(
9221                                             SourceName(Identifier {
9222                                                 start: 6,
9223                                                 end: 7
9224                                             }),
9225                                             None
9226                                         )
9227                                     )
9228                                 )
9229                             )
9230                         ),
9231                         b"...",
9232                         []
9233                     }
9234                     b"XsrS_1QIlEE..." => {
9235                         TemplateArg::Expression(
9236                             Expression::UnresolvedName(
9237                                 UnresolvedName::Nested1(
9238                                     UnresolvedTypeHandle::BackReference(0),
9239                                     vec![],
9240                                     BaseUnresolvedName::Name(
9241                                         SimpleId(
9242                                             SourceName(Identifier {
9243                                                 start: 6,
9244                                                 end: 7
9245                                             }),
9246                                             Some(
9247                                                 TemplateArgs(
9248                                                     vec![
9249                                                         TemplateArg::Type(
9250                                                             TypeHandle::Builtin(
9251                                                                 BuiltinType::Standard(
9252                                                                     StandardBuiltinType::Long
9253                                                                 )
9254                                                             )
9255                                                         )
9256                                                     ]
9257                                                 )
9258                                             )
9259                                         )
9260                                     )
9261                                 )
9262                             )
9263                         ),
9264                         b"...",
9265                         []
9266                     }
9267                     b"LS_E..." => {
9268                         TemplateArg::SimpleExpression(
9269                             ExprPrimary::Literal(TypeHandle::BackReference(0), 3, 3)),
9270                         b"...",
9271                         []
9272                     }
9273                     b"JE..." => {
9274                         TemplateArg::ArgPack(vec![]),
9275                         b"...",
9276                         []
9277                     }
9278                     b"JS_XtrELS_EJEE..." => {
9279                         TemplateArg::ArgPack(vec![
9280                             TemplateArg::Type(TypeHandle::BackReference(0)),
9281                             TemplateArg::Expression(Expression::Rethrow),
9282                             TemplateArg::SimpleExpression(
9283                                 ExprPrimary::Literal(TypeHandle::BackReference(0), 10, 10)),
9284                             TemplateArg::ArgPack(vec![]),
9285                         ]),
9286                         b"...",
9287                         []
9288                     }
9289                 }
9290                 Err => {
9291                     b"..." => Error::UnexpectedText,
9292                     b"X..." => Error::UnexpectedText,
9293                     b"J..." => Error::UnexpectedText,
9294                     b"JS_..." => Error::UnexpectedText,
9295                     b"JS_" => Error::UnexpectedEnd,
9296                     b"X" => Error::UnexpectedEnd,
9297                     b"J" => Error::UnexpectedEnd,
9298                     b"" => Error::UnexpectedEnd,
9299                 }
9300             }
9301         });
9302     }
9303 
9304     #[test]
parse_expression()9305     fn parse_expression() {
9306         assert_parse!(Expression {
9307             with subs [
9308                 Substitutable::Type(
9309                     Type::PointerTo(TypeHandle::Builtin(
9310                         BuiltinType::Standard(StandardBuiltinType::Int)))),
9311             ] => {
9312                 Ok => {
9313                     b"psLS_1E..." => {
9314                         Expression::Unary(OperatorName::Simple(SimpleOperatorName::UnaryPlus),
9315                                           Box::new(Expression::Primary(
9316                                               ExprPrimary::Literal(
9317                                                   TypeHandle::BackReference(0),
9318                                                   5,
9319                                                   6)))),
9320                         b"...",
9321                         []
9322                     }
9323                     b"rsLS_1ELS_1E..." => {
9324                         Expression::Binary(OperatorName::Simple(SimpleOperatorName::Shr),
9325                                            Box::new(Expression::Primary(
9326                                                ExprPrimary::Literal(
9327                                                    TypeHandle::BackReference(0),
9328                                                    5,
9329                                                    6))),
9330                                            Box::new(Expression::Primary(
9331                                                ExprPrimary::Literal(
9332                                                    TypeHandle::BackReference(0),
9333                                                    10,
9334                                                    11)))),
9335                         b"...",
9336                         []
9337                     }
9338                     b"quLS_1ELS_2ELS_3E..." => {
9339                         Expression::Ternary(OperatorName::Simple(SimpleOperatorName::Question),
9340                                             Box::new(Expression::Primary(
9341                                                 ExprPrimary::Literal(
9342                                                     TypeHandle::BackReference(0),
9343                                                     5,
9344                                                     6))),
9345                                             Box::new(Expression::Primary(
9346                                                 ExprPrimary::Literal(
9347                                                     TypeHandle::BackReference(0),
9348                                                     10,
9349                                                     11))),
9350                                             Box::new(Expression::Primary(
9351                                                 ExprPrimary::Literal(
9352                                                     TypeHandle::BackReference(0),
9353                                                     15,
9354                                                     16)))),
9355                         b"...",
9356                         []
9357                     }
9358                     b"pp_LS_1E..." => {
9359                         Expression::PrefixInc(
9360                             Box::new(Expression::Primary(
9361                                 ExprPrimary::Literal(
9362                                     TypeHandle::BackReference(0),
9363                                     6,
9364                                     7)))),
9365                         b"...",
9366                         []
9367                     }
9368                     b"mm_LS_1E..." => {
9369                         Expression::PrefixDec(
9370                             Box::new(Expression::Primary(
9371                                 ExprPrimary::Literal(
9372                                     TypeHandle::BackReference(0),
9373                                     6,
9374                                     7)))),
9375                         b"...",
9376                         []
9377                     }
9378                     b"clLS_1EE..." => {
9379                         Expression::Call(
9380                             Box::new(Expression::Primary(
9381                                 ExprPrimary::Literal(
9382                                     TypeHandle::BackReference(0),
9383                                     5,
9384                                     6))),
9385                             vec![]),
9386                         b"...",
9387                         []
9388                     }
9389                     //               ::= cv <type> <expression>                       # type (expression), conversion with one argument
9390                     b"cvS_LS_1E..." => {
9391                         Expression::ConversionOne(
9392                             TypeHandle::BackReference(0),
9393                             Box::new(Expression::Primary(
9394                                 ExprPrimary::Literal(
9395                                     TypeHandle::BackReference(0),
9396                                     7,
9397                                     8)))),
9398                         b"...",
9399                         []
9400                     }
9401                     b"cvS__LS_1ELS_1EE..." => {
9402                         Expression::ConversionMany(
9403                             TypeHandle::BackReference(0),
9404                             vec![
9405                                 Expression::Primary(
9406                                     ExprPrimary::Literal(
9407                                         TypeHandle::BackReference(0),
9408                                         8,
9409                                         9)),
9410                                 Expression::Primary(
9411                                     ExprPrimary::Literal(
9412                                         TypeHandle::BackReference(0),
9413                                         13,
9414                                         14)),
9415                             ]),
9416                         b"...",
9417                         []
9418                     }
9419                     b"tlS_LS_1ELS_1EE..." => {
9420                         Expression::ConversionBraced(
9421                             TypeHandle::BackReference(0),
9422                             vec![
9423                                 Expression::Primary(
9424                                     ExprPrimary::Literal(
9425                                         TypeHandle::BackReference(0),
9426                                         7,
9427                                         8)),
9428                                 Expression::Primary(
9429                                     ExprPrimary::Literal(
9430                                         TypeHandle::BackReference(0),
9431                                         12,
9432                                         13)),
9433                             ]),
9434                         b"...",
9435                         []
9436                     }
9437                     b"ilLS_1EE..." => {
9438                         Expression::BracedInitList(
9439                             Box::new(Expression::Primary(
9440                                 ExprPrimary::Literal(
9441                                     TypeHandle::BackReference(0),
9442                                     5,
9443                                     6)))),
9444                         b"...",
9445                         []
9446                     }
9447                     b"gsnwLS_1E_S_E..." => {
9448                         Expression::GlobalNew(
9449                             vec![
9450                                 Expression::Primary(
9451                                     ExprPrimary::Literal(
9452                                         TypeHandle::BackReference(0),
9453                                         7,
9454                                         8))
9455                             ],
9456                             TypeHandle::BackReference(0),
9457                             None),
9458                         b"...",
9459                         []
9460                     }
9461                     b"nwLS_1E_S_E..." => {
9462                         Expression::New(
9463                             vec![
9464                                 Expression::Primary(
9465                                     ExprPrimary::Literal(
9466                                         TypeHandle::BackReference(0),
9467                                         5,
9468                                         6))
9469                             ],
9470                             TypeHandle::BackReference(0),
9471                             None),
9472                         b"...",
9473                         []
9474                     }
9475                     b"gsnwLS_1E_S_piE..." => {
9476                         Expression::GlobalNew(
9477                             vec![
9478                                 Expression::Primary(
9479                                     ExprPrimary::Literal(
9480                                         TypeHandle::BackReference(0),
9481                                         7,
9482                                         8))
9483                             ],
9484                             TypeHandle::BackReference(0),
9485                             Some(Initializer(vec![]))),
9486                         b"...",
9487                         []
9488                     }
9489                     b"nwLS_1E_S_piE..." => {
9490                         Expression::New(
9491                             vec![
9492                                 Expression::Primary(
9493                                     ExprPrimary::Literal(
9494                                         TypeHandle::BackReference(0),
9495                                         5,
9496                                         6))
9497                             ],
9498                             TypeHandle::BackReference(0),
9499                             Some(Initializer(vec![]))),
9500                         b"...",
9501                         []
9502                     }
9503                     b"gsnaLS_1E_S_E..." => {
9504                         Expression::GlobalNewArray(
9505                             vec![
9506                                 Expression::Primary(
9507                                     ExprPrimary::Literal(
9508                                         TypeHandle::BackReference(0),
9509                                         7,
9510                                         8))
9511                             ],
9512                             TypeHandle::BackReference(0),
9513                             None),
9514                         b"...",
9515                         []
9516                     }
9517                     b"naLS_1E_S_E..." => {
9518                         Expression::NewArray(
9519                             vec![
9520                                 Expression::Primary(
9521                                     ExprPrimary::Literal(
9522                                         TypeHandle::BackReference(0),
9523                                         5,
9524                                         6))
9525                             ],
9526                             TypeHandle::BackReference(0),
9527                             None),
9528                         b"...",
9529                         []
9530                     }
9531                     b"gsnaLS_1E_S_piE..." => {
9532                         Expression::GlobalNewArray(
9533                             vec![
9534                                 Expression::Primary(
9535                                     ExprPrimary::Literal(
9536                                         TypeHandle::BackReference(0),
9537                                         7,
9538                                         8))
9539                             ],
9540                             TypeHandle::BackReference(0),
9541                             Some(Initializer(vec![]))),
9542                         b"...",
9543                         []
9544                     }
9545                     b"naLS_1E_S_piE..." => {
9546                         Expression::NewArray(
9547                             vec![
9548                                 Expression::Primary(
9549                                     ExprPrimary::Literal(
9550                                         TypeHandle::BackReference(0),
9551                                         5,
9552                                         6))
9553                             ],
9554                             TypeHandle::BackReference(0),
9555                             Some(Initializer(vec![]))),
9556                         b"...",
9557                         []
9558                     }
9559                     b"gsdlLS_1E..." => {
9560                         Expression::GlobalDelete(
9561                             Box::new(Expression::Primary(
9562                                 ExprPrimary::Literal(
9563                                     TypeHandle::BackReference(0),
9564                                     7,
9565                                     8)))),
9566                         b"...",
9567                         []
9568                     }
9569                     b"dlLS_1E..." => {
9570                         Expression::Delete(
9571                             Box::new(Expression::Primary(
9572                                 ExprPrimary::Literal(
9573                                     TypeHandle::BackReference(0),
9574                                     5,
9575                                     6)))),
9576                         b"...",
9577                         []
9578                     }
9579                     //               ::= [gs] da <expression>                         # delete[] expression
9580                     b"gsdaLS_1E..." => {
9581                         Expression::GlobalDeleteArray(
9582                             Box::new(Expression::Primary(
9583                                 ExprPrimary::Literal(
9584                                     TypeHandle::BackReference(0),
9585                                     7,
9586                                     8)))),
9587                         b"...",
9588                         []
9589                     }
9590                     b"daLS_1E..." => {
9591                         Expression::DeleteArray(
9592                             Box::new(Expression::Primary(
9593                                 ExprPrimary::Literal(
9594                                     TypeHandle::BackReference(0),
9595                                     5,
9596                                     6)))),
9597                         b"...",
9598                         []
9599                     }
9600                     b"dcS_LS_1E..." => {
9601                         Expression::DynamicCast(
9602                             TypeHandle::BackReference(0),
9603                             Box::new(Expression::Primary(
9604                                 ExprPrimary::Literal(
9605                                     TypeHandle::BackReference(0),
9606                                     7,
9607                                     8)))),
9608                         b"...",
9609                         []
9610                     }
9611                     b"scS_LS_1E..." => {
9612                         Expression::StaticCast(
9613                             TypeHandle::BackReference(0),
9614                             Box::new(Expression::Primary(
9615                                 ExprPrimary::Literal(
9616                                     TypeHandle::BackReference(0),
9617                                     7,
9618                                     8)))),
9619                         b"...",
9620                         []
9621                     }
9622                     b"ccS_LS_1E..." => {
9623                         Expression::ConstCast(
9624                             TypeHandle::BackReference(0),
9625                             Box::new(Expression::Primary(
9626                                 ExprPrimary::Literal(
9627                                     TypeHandle::BackReference(0),
9628                                     7,
9629                                     8)))),
9630                         b"...",
9631                         []
9632                     }
9633                     b"rcS_LS_1E..." => {
9634                         Expression::ReinterpretCast(
9635                             TypeHandle::BackReference(0),
9636                             Box::new(Expression::Primary(
9637                                 ExprPrimary::Literal(
9638                                     TypeHandle::BackReference(0),
9639                                     7,
9640                                     8)))),
9641                         b"...",
9642                         []
9643                     }
9644                     b"tiS_..." => {
9645                         Expression::TypeidType(TypeHandle::BackReference(0)),
9646                         b"...",
9647                         []
9648                     }
9649                     b"teLS_1E..." => {
9650                         Expression::TypeidExpr(
9651                             Box::new(Expression::Primary(
9652                                 ExprPrimary::Literal(
9653                                     TypeHandle::BackReference(0),
9654                                     5,
9655                                     6)))),
9656                         b"...",
9657                         []
9658                     }
9659                     b"stS_..." => {
9660                         Expression::SizeofType(TypeHandle::BackReference(0)),
9661                         b"...",
9662                         []
9663                     }
9664                     b"szLS_1E..." => {
9665                         Expression::SizeofExpr(
9666                             Box::new(Expression::Primary(
9667                                 ExprPrimary::Literal(
9668                                     TypeHandle::BackReference(0),
9669                                     5,
9670                                     6)))),
9671                         b"...",
9672                         []
9673                     }
9674                     b"atS_..." => {
9675                         Expression::AlignofType(TypeHandle::BackReference(0)),
9676                         b"...",
9677                         []
9678                     }
9679                     b"azLS_1E..." => {
9680                         Expression::AlignofExpr(
9681                             Box::new(Expression::Primary(
9682                                 ExprPrimary::Literal(
9683                                     TypeHandle::BackReference(0),
9684                                     5,
9685                                     6)))),
9686                         b"...",
9687                         []
9688                     }
9689                     b"nxLS_1E..." => {
9690                         Expression::Noexcept(
9691                             Box::new(Expression::Primary(
9692                                 ExprPrimary::Literal(
9693                                     TypeHandle::BackReference(0),
9694                                     5,
9695                                     6)))),
9696                         b"...",
9697                         []
9698                     }
9699                     b"T_..." => {
9700                         Expression::TemplateParam(TemplateParam(0)),
9701                         b"...",
9702                         []
9703                     }
9704                     b"fp_..." => {
9705                         Expression::FunctionParam(FunctionParam(0, CvQualifiers::default(), Some(0))),
9706                         b"...",
9707                         []
9708                     }
9709                     b"dtT_3abc..." => {
9710                         Expression::Member(
9711                             Box::new(Expression::TemplateParam(TemplateParam(0))),
9712                             MemberName(
9713                                 Name::Unscoped(
9714                                     UnscopedName::Unqualified(
9715                                         UnqualifiedName::Source(
9716                                             SourceName(
9717                                                 Identifier {
9718                                                     start: 5,
9719                                                     end: 8,
9720                                                 })))))),
9721                         b"...",
9722                         []
9723                     }
9724                     b"ptT_3abc..." => {
9725                         Expression::DerefMember(
9726                             Box::new(Expression::TemplateParam(TemplateParam(0))),
9727                             MemberName(
9728                                 Name::Unscoped(
9729                                     UnscopedName::Unqualified(
9730                                         UnqualifiedName::Source(
9731                                             SourceName(
9732                                                 Identifier {
9733                                                     start: 5,
9734                                                     end: 8,
9735                                                 })))))),
9736                         b"...",
9737                         []
9738                     }
9739                     b"dtfp_clI3abcE..." => {
9740                         Expression::Member(
9741                             Box::new(Expression::FunctionParam(FunctionParam(0, CvQualifiers::default(), Some(0)))),
9742                             MemberName(
9743                                 Name::UnscopedTemplate(
9744                                     UnscopedTemplateNameHandle::NonSubstitution(NonSubstitution(0)),
9745                                     TemplateArgs(vec![
9746                                         TemplateArg::Type(
9747                                             TypeHandle::BackReference(1))])))),
9748                         b"...",
9749                         [
9750                             Substitutable::Type(
9751                                 Type::ClassEnum(
9752                                     ClassEnumType::Named(
9753                                         Name::Unscoped(
9754                                             UnscopedName::Unqualified(
9755                                                 UnqualifiedName::Source(
9756                                                     SourceName(
9757                                                         Identifier {
9758                                                             start: 9,
9759                                                             end: 12
9760                                                         })))))))
9761                         ]
9762                     }
9763                     //               ::= ds <expression> <expression>                 # expr.*expr
9764                     b"dsT_T_..." => {
9765                         Expression::PointerToMember(
9766                             Box::new(Expression::TemplateParam(TemplateParam(0))),
9767                             Box::new(Expression::TemplateParam(TemplateParam(0)))),
9768                         b"...",
9769                         []
9770                     }
9771                     b"sZT_..." => {
9772                         Expression::SizeofTemplatePack(TemplateParam(0)),
9773                         b"...",
9774                         []
9775                     }
9776                     b"sZfp_..." => {
9777                         Expression::SizeofFunctionPack(
9778                             FunctionParam(0, CvQualifiers::default(), Some(0))),
9779                         b"...",
9780                         []
9781                     }
9782                     b"sPE..." => {
9783                         Expression::SizeofCapturedTemplatePack(vec![]),
9784                         b"...",
9785                         []
9786                     }
9787                     b"spT_..." => {
9788                         Expression::PackExpansion(
9789                             Box::new(Expression::TemplateParam(TemplateParam(0)))),
9790                         b"...",
9791                         []
9792                     }
9793                     b"twT_..." => {
9794                         Expression::Throw(Box::new(Expression::TemplateParam(TemplateParam(0)))),
9795                         b"...",
9796                         []
9797                     }
9798                     b"tr..." => {
9799                         Expression::Rethrow,
9800                         b"...",
9801                         []
9802                     }
9803                     b"3abc..." => {
9804                         Expression::UnresolvedName(
9805                             UnresolvedName::Name(
9806                                 BaseUnresolvedName::Name(
9807                                     SimpleId(
9808                                         SourceName(Identifier {
9809                                             start: 1,
9810                                             end: 4,
9811                                         }),
9812                                         None)))),
9813                         b"...",
9814                         []
9815                     }
9816                     b"L_Z3abcE..." => {
9817                         Expression::Primary(
9818                             ExprPrimary::External(
9819                                 MangledName::Encoding(
9820                                     Encoding::Data(
9821                                         Name::Unscoped(
9822                                             UnscopedName::Unqualified(
9823                                                 UnqualifiedName::Source(
9824                                                     SourceName(Identifier {
9825                                                         start: 4,
9826                                                         end: 7,
9827                                                     }))))), vec![]))),
9828                         b"...",
9829                         []
9830                     }
9831                     // An expression where arity matters
9832                     b"cldtdefpT4TypeadsrT_5EnterE..." => {
9833                         Expression::Call(
9834                             Box::new(Expression::Member(
9835                                 Box::new(Expression::Unary(OperatorName::Simple(SimpleOperatorName::Deref),
9836                                                            Box::new(Expression::FunctionParam(
9837                                                                FunctionParam(0,
9838                                                                              CvQualifiers::default(),
9839                                                                              None)
9840                                                            ))
9841                                 )),
9842                                 MemberName(
9843                                     Name::Unscoped(
9844                                         UnscopedName::Unqualified(
9845                                             UnqualifiedName::Source(
9846                                                 SourceName(Identifier {
9847                                                     start: 10,
9848                                                     end: 14,
9849                                                 })))
9850                                      )
9851                                 )
9852                             )),
9853                             vec![Expression::Unary(OperatorName::Simple(SimpleOperatorName::AddressOf),
9854                                                    Box::new(Expression::UnresolvedName(
9855                                                        UnresolvedName::Nested1(
9856                                                            UnresolvedTypeHandle::BackReference(1),
9857                                                            vec![],
9858                                                            BaseUnresolvedName::Name(
9859                                                                SimpleId(
9860                                                                    SourceName(Identifier {
9861                                                                            start: 21,
9862                                                                            end: 26
9863                                                                    }
9864                                                                    ),
9865                                                                    None
9866                                                                )
9867                                                            )
9868                                                        ))))]
9869                         ),
9870                         b"...",
9871                         [
9872                             Substitutable::UnresolvedType(UnresolvedType::Template(TemplateParam(0), None))
9873                         ]
9874                     }
9875                 }
9876                 Err => {
9877                     b"dtStfp_clI3abcE..." => Error::UnexpectedText,
9878                 }
9879             }
9880         });
9881     }
9882 
9883     #[test]
parse_unresolved_name()9884     fn parse_unresolved_name() {
9885         assert_parse!(UnresolvedName {
9886             with subs [
9887                 Substitutable::UnresolvedType(
9888                     UnresolvedType::Decltype(Decltype::Expression(Expression::Rethrow))),
9889             ] => {
9890                 Ok => {
9891                     b"gs3abc..." => {
9892                         UnresolvedName::Global(BaseUnresolvedName::Name(SimpleId(SourceName(Identifier {
9893                             start: 3,
9894                             end: 6,
9895                         }), None))),
9896                         b"...",
9897                         []
9898                     }
9899                     b"3abc..." => {
9900                         UnresolvedName::Name(BaseUnresolvedName::Name(SimpleId(SourceName(Identifier {
9901                             start: 1,
9902                             end: 4,
9903                         }), None))),
9904                         b"...",
9905                         []
9906                     }
9907                     b"srS_3abc..." => {
9908                         UnresolvedName::Nested1(UnresolvedTypeHandle::BackReference(0),
9909                                                 vec![],
9910                                                 BaseUnresolvedName::Name(SimpleId(SourceName(Identifier {
9911                                                     start: 5,
9912                                                     end: 8,
9913                                                 }), None))),
9914                         b"...",
9915                         []
9916                     }
9917                     b"srNS_3abc3abcE3abc..." => {
9918                         UnresolvedName::Nested1(
9919                             UnresolvedTypeHandle::BackReference(0),
9920                             vec![
9921                                 UnresolvedQualifierLevel(SimpleId(SourceName(Identifier {
9922                                     start: 6,
9923                                     end: 9,
9924                                 }), None)),
9925                                 UnresolvedQualifierLevel(SimpleId(SourceName(Identifier {
9926                                     start: 10,
9927                                     end: 13,
9928                                 }), None)),
9929                             ],
9930                             BaseUnresolvedName::Name(SimpleId(SourceName(Identifier {
9931                                 start: 15,
9932                                 end: 18,
9933                             }), None))),
9934                         b"...",
9935                         []
9936                     }
9937                     b"gssr3abcE3abc..." => {
9938                         UnresolvedName::GlobalNested2(
9939                             vec![
9940                                 UnresolvedQualifierLevel(SimpleId(SourceName(Identifier {
9941                                     start: 5,
9942                                     end: 8,
9943                                 }), None)),
9944                             ],
9945                             BaseUnresolvedName::Name(SimpleId(SourceName(Identifier {
9946                                 start: 10,
9947                                 end: 13,
9948                             }), None))),
9949                         b"...",
9950                         []
9951                     }
9952                     b"sr3abcE3abc..." => {
9953                         UnresolvedName::Nested2(
9954                             vec![
9955                                 UnresolvedQualifierLevel(SimpleId(SourceName(Identifier {
9956                                     start: 3,
9957                                     end: 6,
9958                                 }), None)),
9959                             ],
9960                             BaseUnresolvedName::Name(SimpleId(SourceName(Identifier {
9961                                 start: 8,
9962                                 end: 11,
9963                             }), None))),
9964                         b"...",
9965                         []
9966                     }
9967                 }
9968                 Err => {
9969                     b"zzzzzz" => Error::UnexpectedText,
9970                     b"gszzz" => Error::UnexpectedText,
9971                     b"gssrzzz" => Error::UnexpectedText,
9972                     b"srNzzz" => Error::UnexpectedText,
9973                     b"srzzz" => Error::UnexpectedText,
9974                     b"srN3abczzzz" => Error::UnexpectedText,
9975                     b"srN3abcE" => Error::UnexpectedText,
9976                     b"srN3abc" => Error::UnexpectedText,
9977                     b"srN" => Error::UnexpectedEnd,
9978                     b"sr" => Error::UnexpectedEnd,
9979                     b"gssr" => Error::UnexpectedEnd,
9980                     b"gs" => Error::UnexpectedEnd,
9981                     b"" => Error::UnexpectedEnd,
9982                 }
9983             }
9984         });
9985     }
9986 
9987     #[test]
parse_unresolved_type_handle()9988     fn parse_unresolved_type_handle() {
9989         assert_parse!(UnresolvedTypeHandle {
9990             with subs [
9991                 Substitutable::UnresolvedType(
9992                     UnresolvedType::Decltype(Decltype::Expression(Expression::Rethrow))),
9993             ] => {
9994                 Ok => {
9995                     b"S_..." => {
9996                         UnresolvedTypeHandle::BackReference(0),
9997                         b"...",
9998                         []
9999                     }
10000                     b"T_..." => {
10001                         UnresolvedTypeHandle::BackReference(1),
10002                         b"...",
10003                         [
10004                             Substitutable::UnresolvedType(
10005                                 UnresolvedType::Template(TemplateParam(0), None)),
10006                         ]
10007                     }
10008                     b"T_IS_E..." => {
10009                         UnresolvedTypeHandle::BackReference(1),
10010                         b"...",
10011                         [
10012                             Substitutable::UnresolvedType(
10013                                 UnresolvedType::Template(TemplateParam(0), Some(TemplateArgs(vec![
10014                                     TemplateArg::Type(TypeHandle::BackReference(0))
10015                                 ])))),
10016                         ]
10017                     }
10018                     b"DTtrE..." => {
10019                         UnresolvedTypeHandle::BackReference(1),
10020                         b"...",
10021                         [
10022                             Substitutable::UnresolvedType(
10023                                 UnresolvedType::Decltype(Decltype::Expression(Expression::Rethrow)))
10024                         ]
10025 
10026                     }
10027                 }
10028                 Err => {
10029                     b"zzzzzzz" => Error::UnexpectedText,
10030                     b"" => Error::UnexpectedEnd,
10031                 }
10032             }
10033         });
10034     }
10035 
10036     #[test]
parse_unresolved_qualifier_level()10037     fn parse_unresolved_qualifier_level() {
10038         assert_parse!(UnresolvedQualifierLevel {
10039             with subs [
10040                 Substitutable::Type(Type::Decltype(Decltype::Expression(Expression::Rethrow)))
10041             ] => {
10042                 Ok => {
10043                     b"3abc..." => {
10044                         UnresolvedQualifierLevel(SimpleId(SourceName(Identifier {
10045                             start: 1,
10046                             end: 4,
10047                         }), None)),
10048                         b"...",
10049                         []
10050                     }
10051                     b"3abcIS_E..." => {
10052                         UnresolvedQualifierLevel(SimpleId(SourceName(Identifier {
10053                             start: 1,
10054                             end: 4,
10055                         }), Some(TemplateArgs(vec![
10056                             TemplateArg::Type(TypeHandle::BackReference(0))
10057                         ])))),
10058                         b"...",
10059                         []
10060                     }
10061                 }
10062                 Err => {
10063                     b"zzz" => Error::UnexpectedText,
10064                     b"" => Error::UnexpectedEnd,
10065                 }
10066             }
10067         });
10068     }
10069 
10070     #[test]
parse_simple_id()10071     fn parse_simple_id() {
10072         assert_parse!(SimpleId {
10073             with subs [
10074                 Substitutable::Type(Type::Decltype(Decltype::Expression(Expression::Rethrow)))
10075             ] => {
10076                 Ok => {
10077                     b"3abc..." => {
10078                         SimpleId(SourceName(Identifier {
10079                             start: 1,
10080                             end: 4,
10081                         }), None),
10082                         b"...",
10083                         []
10084                     }
10085                     b"3abcIS_E..." => {
10086                         SimpleId(SourceName(Identifier {
10087                             start: 1,
10088                             end: 4,
10089                         }), Some(TemplateArgs(vec![
10090                             TemplateArg::Type(TypeHandle::BackReference(0))
10091                         ]))),
10092                         b"...",
10093                         []
10094                     }
10095                 }
10096                 Err => {
10097                     b"zzz" => Error::UnexpectedText,
10098                     b"" => Error::UnexpectedEnd,
10099                 }
10100             }
10101         });
10102     }
10103 
10104     #[test]
parse_base_unresolved_name()10105     fn parse_base_unresolved_name() {
10106         assert_parse!(BaseUnresolvedName {
10107             with subs [
10108                 Substitutable::Type(Type::Decltype(Decltype::Expression(Expression::Rethrow)))
10109             ] => {
10110                 Ok => {
10111                     b"3abc..." => {
10112                         BaseUnresolvedName::Name(SimpleId(SourceName(Identifier {
10113                             start: 1,
10114                             end: 4,
10115                         }), None)),
10116                         b"...",
10117                         []
10118                     }
10119                     b"onnw..." => {
10120                         BaseUnresolvedName::Operator(OperatorName::Simple(SimpleOperatorName::New), None),
10121                         b"...",
10122                         []
10123                     }
10124                     b"onnwIS_E..." => {
10125                         BaseUnresolvedName::Operator(OperatorName::Simple(SimpleOperatorName::New),
10126                                                      Some(TemplateArgs(vec![
10127                                                          TemplateArg::Type(TypeHandle::BackReference(0))
10128                                                      ]))),
10129                         b"...",
10130                         []
10131                     }
10132                     b"dn3abc..." => {
10133                         BaseUnresolvedName::Destructor(DestructorName::Name(SimpleId(SourceName(Identifier {
10134                             start: 3,
10135                             end: 6,
10136                         }), None))),
10137                         b"...",
10138                         []
10139                     }
10140                 }
10141                 Err => {
10142                     b"ozzz" => Error::UnexpectedText,
10143                     b"dzzz" => Error::UnexpectedText,
10144                     b"dn" => Error::UnexpectedEnd,
10145                     b"on" => Error::UnexpectedEnd,
10146                     b"" => Error::UnexpectedEnd,
10147                 }
10148             }
10149         });
10150     }
10151 
10152     #[test]
parse_destructor_name()10153     fn parse_destructor_name() {
10154         assert_parse!(DestructorName {
10155             with subs [
10156                 Substitutable::UnresolvedType(
10157                     UnresolvedType::Decltype(Decltype::Expression(Expression::Rethrow))),
10158             ] => {
10159                 Ok => {
10160                     b"S_..." => {
10161                         DestructorName::Unresolved(UnresolvedTypeHandle::BackReference(0)),
10162                         b"...",
10163                         []
10164                     }
10165                     b"3abc..." => {
10166                         DestructorName::Name(SimpleId(SourceName(Identifier {
10167                             start: 1,
10168                             end: 4,
10169                         }), None)),
10170                         b"...",
10171                         []
10172                     }
10173                 }
10174                 Err => {
10175                     b"zzz" => Error::UnexpectedText,
10176                     b"" => Error::UnexpectedEnd,
10177                 }
10178             }
10179         });
10180     }
10181 
10182     #[test]
parse_expr_primary()10183     fn parse_expr_primary() {
10184         assert_parse!(ExprPrimary {
10185             with subs [
10186                 Substitutable::Type(Type::Decltype(Decltype::Expression(Expression::Rethrow)))
10187             ] => {
10188                 Ok => {
10189                     b"LS_12345E..." => {
10190                         ExprPrimary::Literal(TypeHandle::BackReference(0), 3, 8),
10191                         b"...",
10192                         []
10193                     }
10194                     b"LS_E..." => {
10195                         ExprPrimary::Literal(TypeHandle::BackReference(0), 3, 3),
10196                         b"...",
10197                         []
10198                     }
10199                     b"L_Z3abcE..." => {
10200                         ExprPrimary::External(
10201                             MangledName::Encoding(
10202                                 Encoding::Data(
10203                                     Name::Unscoped(
10204                                         UnscopedName::Unqualified(
10205                                             UnqualifiedName::Source(
10206                                                 SourceName(Identifier {
10207                                                     start: 4,
10208                                                     end: 7,
10209                                                 }))))), vec![])),
10210                         b"...",
10211                         []
10212                     }
10213                 }
10214                 Err => {
10215                     b"zzz" => Error::UnexpectedText,
10216                     b"LS_zzz" => Error::UnexpectedEnd,
10217                     b"LS_12345" => Error::UnexpectedEnd,
10218                     b"LS_" => Error::UnexpectedEnd,
10219                     b"L" => Error::UnexpectedEnd,
10220                     b"" => Error::UnexpectedEnd,
10221                 }
10222             }
10223         });
10224     }
10225 
10226     #[test]
parse_initializer()10227     fn parse_initializer() {
10228         assert_parse!(Initializer {
10229             Ok => {
10230                 b"piE..." => {
10231                     Initializer(vec![]),
10232                     b"..."
10233                 }
10234                 b"pitrtrtrE..." => {
10235                     Initializer(vec![
10236                         Expression::Rethrow,
10237                         Expression::Rethrow,
10238                         Expression::Rethrow,
10239                     ]),
10240                     b"..."
10241                 }
10242             }
10243             Err => {
10244                 b"pirtrtrt..." => Error::UnexpectedText,
10245                 b"pi..." => Error::UnexpectedText,
10246                 b"..." => Error::UnexpectedText,
10247                 b"pirt" => Error::UnexpectedText,
10248                 b"pi" => Error::UnexpectedEnd,
10249                 b"p" => Error::UnexpectedEnd,
10250                 b"" => Error::UnexpectedEnd,
10251             }
10252         });
10253     }
10254 
10255     #[test]
parse_local_name()10256     fn parse_local_name() {
10257         assert_parse!(LocalName {
10258             Ok => {
10259                 b"Z3abcE3def_0..." => {
10260                     LocalName::Relative(
10261                         Box::new(Encoding::Data(
10262                             Name::Unscoped(
10263                                 UnscopedName::Unqualified(
10264                                     UnqualifiedName::Source(
10265                                         SourceName(Identifier {
10266                                             start: 2,
10267                                             end: 5,
10268                                         })))))),
10269                         Some(Box::new(Name::Unscoped(
10270                             UnscopedName::Unqualified(
10271                                 UnqualifiedName::Source(
10272                                     SourceName(Identifier {
10273                                         start: 7,
10274                                         end: 10,
10275                                     })))))),
10276                         Some(Discriminator(0))),
10277                     b"..."
10278                 }
10279                 b"Z3abcE3def..." => {
10280                     LocalName::Relative(
10281                         Box::new(Encoding::Data(
10282                             Name::Unscoped(
10283                                 UnscopedName::Unqualified(
10284                                     UnqualifiedName::Source(
10285                                         SourceName(Identifier {
10286                                             start: 2,
10287                                             end: 5,
10288                                         })))))),
10289                         Some(Box::new(Name::Unscoped(
10290                             UnscopedName::Unqualified(
10291                                 UnqualifiedName::Source(
10292                                     SourceName(Identifier {
10293                                         start: 7,
10294                                         end: 10,
10295                                     })))))),
10296                         None),
10297                     b"..."
10298                 }
10299                 b"Z3abcEs_0..." => {
10300                     LocalName::Relative(
10301                         Box::new(Encoding::Data(
10302                             Name::Unscoped(
10303                                 UnscopedName::Unqualified(
10304                                     UnqualifiedName::Source(
10305                                         SourceName(Identifier {
10306                                             start: 2,
10307                                             end: 5,
10308                                         })))))),
10309                         None,
10310                         Some(Discriminator(0))),
10311                     b"..."
10312                 }
10313                 b"Z3abcEs..." => {
10314                     LocalName::Relative(
10315                         Box::new(Encoding::Data(
10316                             Name::Unscoped(
10317                                 UnscopedName::Unqualified(
10318                                     UnqualifiedName::Source(
10319                                         SourceName(Identifier {
10320                                             start: 2,
10321                                             end: 5,
10322                                         })))))),
10323                         None,
10324                         None),
10325                     b"..."
10326                 }
10327                 b"Z3abcEd1_3abc..." => {
10328                     LocalName::Default(
10329                         Box::new(Encoding::Data(
10330                             Name::Unscoped(
10331                                 UnscopedName::Unqualified(
10332                                     UnqualifiedName::Source(
10333                                         SourceName(Identifier {
10334                                             start: 2,
10335                                             end: 5,
10336                                         })))))),
10337                         Some(1),
10338                         Box::new(Name::Unscoped(
10339                             UnscopedName::Unqualified(
10340                                 UnqualifiedName::Source(
10341                                     SourceName(Identifier {
10342                                         start: 10,
10343                                         end: 13,
10344                                     })))))),
10345                     b"..."
10346                 }
10347                 b"Z3abcEd_3abc..." => {
10348                     LocalName::Default(
10349                         Box::new(Encoding::Data(
10350                             Name::Unscoped(
10351                                 UnscopedName::Unqualified(
10352                                     UnqualifiedName::Source(
10353                                         SourceName(Identifier {
10354                                             start: 2,
10355                                             end: 5,
10356                                         })))))),
10357                         None,
10358                         Box::new(Name::Unscoped(
10359                             UnscopedName::Unqualified(
10360                                 UnqualifiedName::Source(
10361                                     SourceName(Identifier {
10362                                         start: 9,
10363                                         end: 12,
10364                                     })))))),
10365                     b"..."
10366                 }
10367             }
10368             Err => {
10369                 b"A" => Error::UnexpectedText,
10370                 b"Z1a" => Error::UnexpectedEnd,
10371                 b"Z1aE" => Error::UnexpectedEnd,
10372                 b"Z" => Error::UnexpectedEnd,
10373                 b"" => Error::UnexpectedEnd,
10374             }
10375         });
10376     }
10377 
10378     #[test]
parse_closure_type_name()10379     fn parse_closure_type_name() {
10380         assert_parse!(ClosureTypeName {
10381             Ok => {
10382                 b"UlvE_..." => {
10383                     ClosureTypeName(LambdaSig(vec![]), None),
10384                     b"..."
10385                 }
10386                 b"UlvE36_..." => {
10387                     ClosureTypeName(LambdaSig(vec![]), Some(36)),
10388                     b"..."
10389                 }
10390             }
10391             Err => {
10392                 b"UlvE36zzz" => Error::UnexpectedText,
10393                 b"UlvEzzz" => Error::UnexpectedText,
10394                 b"Ulvzzz" => Error::UnexpectedText,
10395                 b"zzz" => Error::UnexpectedText,
10396                 b"UlvE10" => Error::UnexpectedEnd,
10397                 b"UlvE" => Error::UnexpectedEnd,
10398                 b"Ulv" => Error::UnexpectedEnd,
10399                 b"Ul" => Error::UnexpectedEnd,
10400                 b"U" => Error::UnexpectedEnd,
10401                 b"" => Error::UnexpectedEnd,
10402             }
10403         });
10404     }
10405 
10406     #[test]
parse_lambda_sig()10407     fn parse_lambda_sig() {
10408         assert_parse!(LambdaSig {
10409             with subs [
10410                 Substitutable::Type(
10411                     Type::PointerTo(
10412                         TypeHandle::Builtin(BuiltinType::Standard(StandardBuiltinType::Bool))))
10413             ] => {
10414                 Ok => {
10415                     b"v..." => {
10416                         LambdaSig(vec![]),
10417                         b"...",
10418                         []
10419                     }
10420                     b"S_S_S_..." => {
10421                         LambdaSig(vec![
10422                             TypeHandle::BackReference(0),
10423                             TypeHandle::BackReference(0),
10424                             TypeHandle::BackReference(0),
10425                         ]),
10426                         b"...",
10427                         []
10428                     }
10429                 }
10430                 Err => {
10431                     b"..." => Error::UnexpectedText,
10432                     b"S" => Error::UnexpectedEnd,
10433                     b"" => Error::UnexpectedEnd,
10434                 }
10435             }
10436         });
10437     }
10438 
10439     #[test]
parse_substitution()10440     fn parse_substitution() {
10441         assert_parse!(Substitution {
10442             with subs [
10443                 Substitutable::Type(Type::Decltype(Decltype::Expression(Expression::Rethrow))),
10444                 Substitutable::Type(Type::Decltype(Decltype::Expression(Expression::Rethrow))),
10445                 Substitutable::Type(Type::Decltype(Decltype::Expression(Expression::Rethrow)))
10446             ] => {
10447                 Ok => {
10448                     b"S_..." => {
10449                         Substitution::BackReference(0),
10450                         b"...",
10451                         []
10452                     }
10453                     b"S1_..." => {
10454                         Substitution::BackReference(2),
10455                         b"...",
10456                         []
10457                     }
10458                     b"St..." => {
10459                         Substitution::WellKnown(WellKnownComponent::Std),
10460                         b"...",
10461                         []
10462                     }
10463                     b"Sa..." => {
10464                         Substitution::WellKnown(WellKnownComponent::StdAllocator),
10465                         b"...",
10466                         []
10467                     }
10468                     b"Sb..." => {
10469                         Substitution::WellKnown(WellKnownComponent::StdString1),
10470                         b"...",
10471                         []
10472                     }
10473                     b"Ss..." => {
10474                         Substitution::WellKnown(WellKnownComponent::StdString2),
10475                         b"...",
10476                         []
10477                     }
10478                     b"Si..." => {
10479                         Substitution::WellKnown(WellKnownComponent::StdIstream),
10480                         b"...",
10481                         []
10482                     }
10483                     b"So..." => {
10484                         Substitution::WellKnown(WellKnownComponent::StdOstream),
10485                         b"...",
10486                         []
10487                     }
10488                     b"Sd..." => {
10489                         Substitution::WellKnown(WellKnownComponent::StdIostream),
10490                         b"...",
10491                         []
10492                     }
10493                 }
10494                 Err => {
10495                     b"S999_" => Error::BadBackReference,
10496                     b"Sz" => Error::UnexpectedText,
10497                     b"zzz" => Error::UnexpectedText,
10498                     b"S1" => Error::UnexpectedEnd,
10499                     b"S" => Error::UnexpectedEnd,
10500                     b"" => Error::UnexpectedEnd,
10501                 }
10502             }
10503         });
10504     }
10505 
10506     #[test]
parse_special_name()10507     fn parse_special_name() {
10508         assert_parse!(SpecialName {
10509             Ok => {
10510                 b"TVi..." => {
10511                     SpecialName::VirtualTable(TypeHandle::Builtin(BuiltinType::Standard(StandardBuiltinType::Int))),
10512                     b"..."
10513                 }
10514                 b"TTi..." => {
10515                     SpecialName::Vtt(TypeHandle::Builtin(BuiltinType::Standard(StandardBuiltinType::Int))),
10516                     b"..."
10517                 }
10518                 b"TIi..." => {
10519                     SpecialName::Typeinfo(TypeHandle::Builtin(BuiltinType::Standard(StandardBuiltinType::Int))),
10520                     b"..."
10521                 }
10522                 b"TSi..." => {
10523                     SpecialName::TypeinfoName(TypeHandle::Builtin(BuiltinType::Standard(StandardBuiltinType::Int))),
10524                     b"..."
10525                 }
10526                 b"Tv42_36_3abc..." => {
10527                     SpecialName::VirtualOverrideThunk(
10528                         CallOffset::Virtual(VOffset(42, 36)),
10529                         Box::new(Encoding::Data(
10530                             Name::Unscoped(
10531                                 UnscopedName::Unqualified(
10532                                     UnqualifiedName::Source(
10533                                         SourceName(Identifier {
10534                                             start: 9,
10535                                             end: 12,
10536                                         }))))))),
10537                     b"..."
10538                 }
10539                 b"Tcv42_36_v42_36_3abc..." => {
10540                     SpecialName::VirtualOverrideThunkCovariant(
10541                         CallOffset::Virtual(VOffset(42, 36)),
10542                         CallOffset::Virtual(VOffset(42, 36)),
10543                         Box::new(Encoding::Data(
10544                             Name::Unscoped(
10545                                 UnscopedName::Unqualified(
10546                                     UnqualifiedName::Source(
10547                                         SourceName(Identifier {
10548                                             start: 17,
10549                                             end: 20,
10550                                         }))))))),
10551                     b"..."
10552                 }
10553                 b"GV3abc..." => {
10554                     SpecialName::Guard(
10555                         Name::Unscoped(
10556                             UnscopedName::Unqualified(
10557                                 UnqualifiedName::Source(
10558                                     SourceName(Identifier {
10559                                         start: 3,
10560                                         end: 6,
10561                                     }))))),
10562                     b"..."
10563                 }
10564                 b"GR3abc_..." => {
10565                     SpecialName::GuardTemporary(
10566                         Name::Unscoped(
10567                             UnscopedName::Unqualified(
10568                                 UnqualifiedName::Source(
10569                                     SourceName(Identifier {
10570                                         start: 3,
10571                                         end: 6,
10572                                     })))),
10573                         0),
10574                     b"..."
10575                 }
10576                 b"GR3abc0_..." => {
10577                     SpecialName::GuardTemporary(
10578                         Name::Unscoped(
10579                             UnscopedName::Unqualified(
10580                                 UnqualifiedName::Source(
10581                                     SourceName(Identifier {
10582                                         start: 3,
10583                                         end: 6,
10584                                     })))),
10585                         1),
10586                     b"..."
10587                 }
10588                 b"Gr4_abc..." => {
10589                     SpecialName::JavaResource(vec![ResourceName {
10590                         start: 4,
10591                         end: 7,
10592                     }]),
10593                     b"..."
10594                 }
10595                 b"TCc7_i..." => {
10596                     SpecialName::ConstructionVtable(
10597                         TypeHandle::Builtin(BuiltinType::Standard(StandardBuiltinType::Char)),
10598                         7,
10599                         TypeHandle::Builtin(BuiltinType::Standard(StandardBuiltinType::Int))
10600                     ),
10601                     b"..."
10602                 }
10603                 b"TFi..." => {
10604                     SpecialName::TypeinfoFunction(
10605                         TypeHandle::Builtin(BuiltinType::Standard(StandardBuiltinType::Int))),
10606                     b"..."
10607                 }
10608                 b"TH4name..." => {
10609                     SpecialName::TlsInit(
10610                         Name::Unscoped(
10611                             UnscopedName::Unqualified(
10612                                 UnqualifiedName::Source(
10613                                     SourceName(Identifier { start: 3, end: 7 }))))),
10614                     b"..."
10615                 }
10616                 b"TW4name..." => {
10617                     SpecialName::TlsWrapper(
10618                         Name::Unscoped(
10619                             UnscopedName::Unqualified(
10620                                 UnqualifiedName::Source(
10621                                     SourceName(Identifier { start: 3, end: 7 }))))),
10622                     b"..."
10623                 }
10624             }
10625             Err => {
10626                 b"TZ" => Error::UnexpectedText,
10627                 b"GZ" => Error::UnexpectedText,
10628                 b"GR3abcz" => Error::UnexpectedText,
10629                 b"GR3abc0z" => Error::UnexpectedText,
10630                 b"T" => Error::UnexpectedEnd,
10631                 b"G" => Error::UnexpectedEnd,
10632                 b"" => Error::UnexpectedEnd,
10633                 b"GR3abc" => Error::UnexpectedEnd,
10634                 b"GR3abc0" => Error::UnexpectedEnd,
10635                 // This number is not allowed to be negative.
10636                 b"TCcn7_i..." => Error::UnexpectedText,
10637                 b"Gr3abc0" => Error::UnexpectedText,
10638             }
10639         });
10640     }
10641 
10642     #[test]
parse_function_param()10643     fn parse_function_param() {
10644         assert_parse!(FunctionParam {
10645             Ok => {
10646                 b"fpK_..." => {
10647                     FunctionParam(0,
10648                                   CvQualifiers {
10649                                       restrict: false,
10650                                       volatile: false,
10651                                       const_: true,
10652                                   },
10653                                   Some(0)),
10654                     b"..."
10655                 }
10656                 b"fL1pK_..." => {
10657                     FunctionParam(1,
10658                                   CvQualifiers {
10659                                       restrict: false,
10660                                       volatile: false,
10661                                       const_: true,
10662                                   },
10663                                   Some(0)),
10664                     b"..."
10665                 }
10666                 b"fpK3_..." => {
10667                     FunctionParam(0,
10668                                   CvQualifiers {
10669                                       restrict: false,
10670                                       volatile: false,
10671                                       const_: true,
10672                                   },
10673                                   Some(4)),
10674                     b"..."
10675                 }
10676                 b"fL1pK4_..." => {
10677                     FunctionParam(1,
10678                                   CvQualifiers {
10679                                       restrict: false,
10680                                       volatile: false,
10681                                       const_: true,
10682                                   },
10683                                   Some(5)),
10684                     b"..."
10685                 }
10686             }
10687             Err => {
10688                 b"fz" => Error::UnexpectedText,
10689                 b"fLp_" => Error::UnexpectedText,
10690                 b"fpL_" => Error::UnexpectedText,
10691                 b"fL1pK4z" => Error::UnexpectedText,
10692                 b"fL1pK4" => Error::UnexpectedEnd,
10693                 b"fL1p" => Error::UnexpectedEnd,
10694                 b"fL1" => Error::UnexpectedEnd,
10695                 b"fL" => Error::UnexpectedEnd,
10696                 b"f" => Error::UnexpectedEnd,
10697                 b"" => Error::UnexpectedEnd,
10698             }
10699         });
10700     }
10701 
10702     #[test]
parse_discriminator()10703     fn parse_discriminator() {
10704         assert_parse!(Discriminator {
10705             Ok => {
10706                 b"_0..." => {
10707                     Discriminator(0),
10708                     b"..."
10709                 }
10710                 b"_9..." => {
10711                     Discriminator(9),
10712                     b"..."
10713                 }
10714                 b"__99_..." => {
10715                     Discriminator(99),
10716                     b"..."
10717                 }
10718             }
10719             Err => {
10720                 b"_n1" => Error::UnexpectedText,
10721                 b"__99..." => Error::UnexpectedText,
10722                 b"__99" => Error::UnexpectedEnd,
10723                 b"..." => Error::UnexpectedText,
10724             }
10725         });
10726     }
10727 
10728     #[test]
parse_data_member_prefix()10729     fn parse_data_member_prefix() {
10730         assert_parse!(DataMemberPrefix {
10731             Ok => {
10732                 b"3fooM..." => {
10733                     DataMemberPrefix(SourceName(Identifier {
10734                         start: 1,
10735                         end: 4,
10736                     })),
10737                     b"..."
10738                 }
10739             }
10740             Err => {
10741                 b"zzz" => Error::UnexpectedText,
10742                 b"1" => Error::UnexpectedEnd,
10743                 b"" => Error::UnexpectedEnd,
10744             }
10745         });
10746     }
10747 
10748     #[test]
parse_ref_qualifier()10749     fn parse_ref_qualifier() {
10750         assert_parse!(RefQualifier {
10751             Ok => {
10752                 b"R..." => {
10753                     RefQualifier::LValueRef,
10754                     b"..."
10755                 }
10756                 b"O..." => {
10757                     RefQualifier::RValueRef,
10758                     b"..."
10759                 }
10760             }
10761             Err => {
10762                 b"..." => Error::UnexpectedText,
10763                 b"" => Error::UnexpectedEnd,
10764             }
10765         });
10766     }
10767 
10768     #[test]
parse_cv_qualifiers()10769     fn parse_cv_qualifiers() {
10770         assert_parse!(CvQualifiers {
10771             Ok => {
10772                 b"" => {
10773                     CvQualifiers { restrict: false, volatile: false, const_: false },
10774                     b""
10775                 }
10776                 b"..." => {
10777                     CvQualifiers { restrict: false, volatile: false, const_: false },
10778                     b"..."
10779                 }
10780                 b"r..." => {
10781                     CvQualifiers { restrict: true, volatile: false, const_: false },
10782                     b"..."
10783                 }
10784                 b"rV..." => {
10785                     CvQualifiers { restrict: true, volatile: true, const_: false },
10786                     b"..."
10787                 }
10788                 b"rVK..." => {
10789                     CvQualifiers { restrict: true, volatile: true, const_: true },
10790                     b"..."
10791                 }
10792                 b"V" => {
10793                     CvQualifiers { restrict: false, volatile: true, const_: false },
10794                     b""
10795                 }
10796                 b"VK" => {
10797                     CvQualifiers { restrict: false, volatile: true, const_: true },
10798                     b""
10799                 }
10800                 b"K..." => {
10801                     CvQualifiers { restrict: false, volatile: false, const_: true },
10802                     b"..."
10803                 }
10804             }
10805             Err => {
10806                 // None.
10807             }
10808         });
10809     }
10810 
10811     #[test]
parse_builtin_type()10812     fn parse_builtin_type() {
10813         assert_parse!(BuiltinType {
10814             Ok => {
10815                 b"c..." => {
10816                     BuiltinType::Standard(StandardBuiltinType::Char),
10817                     b"..."
10818                 }
10819                 b"c" => {
10820                     BuiltinType::Standard(StandardBuiltinType::Char),
10821                     b""
10822                 }
10823                 b"u3abc..." => {
10824                     BuiltinType::Extension(SourceName(Identifier {
10825                         start: 2,
10826                         end: 5,
10827                     })),
10828                     b"..."
10829                 }
10830             }
10831             Err => {
10832                 b"." => Error::UnexpectedText,
10833                 b"" => Error::UnexpectedEnd,
10834             }
10835         });
10836     }
10837 
10838     #[test]
parse_template_param()10839     fn parse_template_param() {
10840         assert_parse!(TemplateParam {
10841             Ok => {
10842                 b"T_..." => {
10843                     TemplateParam(0),
10844                     b"..."
10845                 }
10846                 b"T3_..." => {
10847                     TemplateParam(4),
10848                     b"..."
10849                 }
10850             }
10851             Err => {
10852                 b"wtf" => Error::UnexpectedText,
10853                 b"Twtf" => Error::UnexpectedText,
10854                 b"T3wtf" => Error::UnexpectedText,
10855                 b"T" => Error::UnexpectedEnd,
10856                 b"T3" => Error::UnexpectedEnd,
10857                 b"" => Error::UnexpectedEnd,
10858             }
10859         });
10860     }
10861 
10862     #[test]
parse_unscoped_name()10863     fn parse_unscoped_name() {
10864         assert_parse!(UnscopedName {
10865             Ok => {
10866                 b"St5hello..." => {
10867                     UnscopedName::Std(UnqualifiedName::Source(SourceName(Identifier {
10868                         start: 3,
10869                         end: 8,
10870                     }))),
10871                     b"..."
10872                 }
10873                 b"5hello..." => {
10874                     UnscopedName::Unqualified(UnqualifiedName::Source(SourceName(Identifier {
10875                         start: 1,
10876                         end: 6,
10877                     }))),
10878                     b"..."
10879                 }
10880             }
10881             Err => {
10882                 b"St..." => Error::UnexpectedText,
10883                 b"..." => Error::UnexpectedText,
10884                 b"" => Error::UnexpectedEnd,
10885             }
10886         });
10887     }
10888 
10889     #[test]
parse_unqualified_name()10890     fn parse_unqualified_name() {
10891         assert_parse!(UnqualifiedName {
10892             Ok => {
10893                 b"qu.." => {
10894                     UnqualifiedName::Operator(OperatorName::Simple(SimpleOperatorName::Question)),
10895                     b".."
10896                 }
10897                 b"C1.." => {
10898                     UnqualifiedName::CtorDtor(CtorDtorName::CompleteConstructor(None)),
10899                     b".."
10900                 }
10901                 b"10abcdefghij..." => {
10902                     UnqualifiedName::Source(SourceName(Identifier {
10903                         start: 2,
10904                         end: 12,
10905                     })),
10906                     b"..."
10907                 }
10908                 b"UllE_..." => {
10909                     UnqualifiedName::ClosureType(
10910                         ClosureTypeName(
10911                             LambdaSig(vec![
10912                                 TypeHandle::Builtin(
10913                                     BuiltinType::Standard(
10914                                         StandardBuiltinType::Long))
10915                             ]),
10916                             None)),
10917                     b"..."
10918                 }
10919                 b"Ut5_..." => {
10920                     UnqualifiedName::UnnamedType(UnnamedTypeName(Some(5))),
10921                     b"..."
10922                 }
10923                 b"B5cxx11..." => {
10924                     UnqualifiedName::ABITag(TaggedName(SourceName(Identifier {
10925                         start: 2,
10926                         end: 7,
10927                     }))),
10928                     b"..."
10929                 }
10930                 b"L3foo_0..." => {
10931                     UnqualifiedName::LocalSourceName(
10932                         SourceName(Identifier {
10933                             start: 2,
10934                             end: 5
10935                         }),
10936                         Some(Discriminator(0))
10937                     ),
10938                     "..."
10939                 }
10940                 b"L3foo..." => {
10941                     UnqualifiedName::LocalSourceName(
10942                         SourceName(Identifier {
10943                             start: 2,
10944                             end: 5
10945                         }),
10946                         None
10947                     ),
10948                     "..."
10949                 }
10950             }
10951             Err => {
10952                 b"zzz" => Error::UnexpectedText,
10953                 b"Uq" => Error::UnexpectedText,
10954                 b"C" => Error::UnexpectedEnd,
10955                 b"" => Error::UnexpectedEnd,
10956             }
10957         });
10958     }
10959 
10960     #[test]
parse_unnamed_type_name()10961     fn parse_unnamed_type_name() {
10962         assert_parse!(UnnamedTypeName {
10963             Ok => {
10964                 b"Ut_abc" => {
10965                     UnnamedTypeName(None),
10966                     b"abc"
10967                 }
10968                 b"Ut42_abc" => {
10969                     UnnamedTypeName(Some(42)),
10970                     b"abc"
10971                 }
10972                 b"Ut42_" => {
10973                     UnnamedTypeName(Some(42)),
10974                     b""
10975                 }
10976             }
10977             Err => {
10978                 b"ut_" => Error::UnexpectedText,
10979                 b"u" => Error::UnexpectedEnd,
10980                 b"Ut" => Error::UnexpectedEnd,
10981                 b"Ut._" => Error::UnexpectedText,
10982                 b"Ut42" => Error::UnexpectedEnd,
10983             }
10984         });
10985     }
10986 
10987     #[test]
parse_identifier()10988     fn parse_identifier() {
10989         assert_parse!(Identifier {
10990             Ok => {
10991                 b"1abc" => {
10992                     Identifier { start: 0, end: 4 },
10993                     b""
10994                 }
10995                 b"_Az1\0\0\0" => {
10996                     Identifier { start: 0, end: 4 },
10997                     b"\0\0\0"
10998                 }
10999                 b"$_0\0\0\0" => {
11000                     Identifier { start: 0, end: 3 },
11001                     b"\0\0\0"
11002                 }
11003             }
11004             Err => {
11005                 b"\0\0\0" => Error::UnexpectedText,
11006                 b"" => Error::UnexpectedEnd,
11007             }
11008         });
11009     }
11010 
11011     #[test]
parse_source_name()11012     fn parse_source_name() {
11013         assert_parse!(SourceName {
11014             Ok => {
11015                 b"1abc" => {
11016                     SourceName(Identifier { start: 1, end: 2 }),
11017                     b"bc"
11018                 }
11019                 b"10abcdefghijklm" => {
11020                     SourceName(Identifier { start: 2, end: 12 }),
11021                     b"klm"
11022                 }
11023             }
11024             Err => {
11025                 b"0abc" => Error::UnexpectedText,
11026                 b"n1abc" => Error::UnexpectedText,
11027                 b"10abcdef" => Error::UnexpectedEnd,
11028                 b"" => Error::UnexpectedEnd,
11029             }
11030         });
11031     }
11032 
11033     #[test]
parse_number()11034     fn parse_number() {
11035         assert_parse!(Number {
11036             Ok => {
11037                 b"n2n3" => {
11038                     -2,
11039                     b"n3"
11040                 }
11041                 b"12345abcdef" => {
11042                     12345,
11043                     b"abcdef"
11044                 }
11045                 b"0abcdef" => {
11046                     0,
11047                     b"abcdef"
11048                 }
11049                 b"42" => {
11050                     42,
11051                     b""
11052                 }
11053             }
11054             Err => {
11055                 b"001" => Error::UnexpectedText,
11056                 b"wutang" => Error::UnexpectedText,
11057                 b"n" => Error::UnexpectedEnd,
11058                 b"" => Error::UnexpectedEnd,
11059             }
11060         });
11061     }
11062 
11063     #[test]
parse_call_offset()11064     fn parse_call_offset() {
11065         assert_parse!(CallOffset {
11066             Ok => {
11067                 b"hn42_..." => {
11068                     CallOffset::NonVirtual(NvOffset(-42)),
11069                     b"..."
11070                 }
11071                 b"vn42_36_..." => {
11072                     CallOffset::Virtual(VOffset(-42, 36)),
11073                     b"..."
11074                 }
11075             }
11076             Err => {
11077                 b"h1..." => Error::UnexpectedText,
11078                 b"v1_1..." => Error::UnexpectedText,
11079                 b"hh" => Error::UnexpectedText,
11080                 b"vv" => Error::UnexpectedText,
11081                 b"z" => Error::UnexpectedText,
11082                 b"" => Error::UnexpectedEnd,
11083             }
11084         });
11085     }
11086 
11087     #[test]
parse_v_offset()11088     fn parse_v_offset() {
11089         assert_parse!(VOffset {
11090             Ok => {
11091                 b"n2_n3abcdef" => {
11092                     VOffset(-2, -3),
11093                     b"abcdef"
11094                 }
11095                 b"12345_12345abcdef" => {
11096                     VOffset(12345, 12345),
11097                     b"abcdef"
11098                 }
11099                 b"0_0abcdef" => {
11100                     VOffset(0, 0),
11101                     b"abcdef"
11102                 }
11103                 b"42_n3" => {
11104                     VOffset(42, -3),
11105                     b""
11106                 }
11107             }
11108             Err => {
11109                 b"001" => Error::UnexpectedText,
11110                 b"1_001" => Error::UnexpectedText,
11111                 b"wutang" => Error::UnexpectedText,
11112                 b"n_" => Error::UnexpectedText,
11113                 b"1_n" => Error::UnexpectedEnd,
11114                 b"1_" => Error::UnexpectedEnd,
11115                 b"n" => Error::UnexpectedEnd,
11116                 b"" => Error::UnexpectedEnd,
11117             }
11118         });
11119     }
11120 
11121     #[test]
parse_nv_offset()11122     fn parse_nv_offset() {
11123         assert_parse!(NvOffset {
11124             Ok => {
11125                 b"n2n3" => {
11126                     NvOffset(-2),
11127                     b"n3"
11128                 }
11129                 b"12345abcdef" => {
11130                     NvOffset(12345),
11131                     b"abcdef"
11132                 }
11133                 b"0abcdef" => {
11134                     NvOffset(0),
11135                     b"abcdef"
11136                 }
11137                 b"42" => {
11138                     NvOffset(42),
11139                     b""
11140                 }
11141             }
11142             Err => {
11143                 b"001" => Error::UnexpectedText,
11144                 b"wutang" => Error::UnexpectedText,
11145                 b"" => Error::UnexpectedEnd,
11146             }
11147         });
11148     }
11149 
11150     #[test]
parse_seq_id()11151     fn parse_seq_id() {
11152         assert_parse!(SeqId {
11153             Ok => {
11154                 b"1_" => {
11155                     SeqId(1),
11156                     b"_"
11157                 }
11158                 b"42" => {
11159                     SeqId(146),
11160                     b""
11161                 }
11162                 b"ABCabc" => {
11163                     SeqId(13368),
11164                     b"abc"
11165                 }
11166             }
11167             Err => {
11168                 b"abc" => Error::UnexpectedText,
11169                 b"001" => Error::UnexpectedText,
11170                 b"wutang" => Error::UnexpectedText,
11171                 b"" => Error::UnexpectedEnd,
11172             }
11173         });
11174     }
11175 
11176     #[test]
parse_ctor_dtor_name()11177     fn parse_ctor_dtor_name() {
11178         assert_parse!(CtorDtorName {
11179             Ok => {
11180                 b"D0" => {
11181                     CtorDtorName::DeletingDestructor,
11182                     b""
11183                 }
11184                 b"C101" => {
11185                     CtorDtorName::CompleteConstructor(None),
11186                     b"01"
11187                 }
11188             }
11189             Err => {
11190                 b"gayagaya" => Error::UnexpectedText,
11191                 b"C" => Error::UnexpectedEnd,
11192                 b"" => Error::UnexpectedEnd,
11193             }
11194         });
11195     }
11196 
11197     #[test]
parse_operator_name()11198     fn parse_operator_name() {
11199         assert_parse!(OperatorName {
11200             Ok => {
11201                 b"qu..." => {
11202                     OperatorName::Simple(SimpleOperatorName::Question),
11203                     b"..."
11204                 }
11205                 b"cvi..." => {
11206                     OperatorName::Conversion(
11207                         TypeHandle::Builtin(
11208                             BuiltinType::Standard(
11209                                 StandardBuiltinType::Int))),
11210                     b"..."
11211                 }
11212                 b"li3Foo..." => {
11213                     OperatorName::Literal(SourceName(Identifier {
11214                         start: 3,
11215                         end: 6,
11216                     })),
11217                     b"..."
11218                 }
11219                 b"v33Foo..." => {
11220                     OperatorName::VendorExtension(3, SourceName(Identifier {
11221                         start: 3,
11222                         end: 6
11223                     })),
11224                     b"..."
11225                 }
11226             }
11227             Err => {
11228                 b"cv" => Error::UnexpectedEnd,
11229                 b"li3ab" => Error::UnexpectedEnd,
11230                 b"li" => Error::UnexpectedEnd,
11231                 b"v33ab" => Error::UnexpectedEnd,
11232                 b"v3" => Error::UnexpectedEnd,
11233                 b"v" => Error::UnexpectedEnd,
11234                 b"" => Error::UnexpectedEnd,
11235                 b"q" => Error::UnexpectedText,
11236                 b"c" => Error::UnexpectedText,
11237                 b"l" => Error::UnexpectedText,
11238                 b"zzz" => Error::UnexpectedText,
11239             }
11240         });
11241     }
11242 
11243     #[test]
parse_simple_operator_name()11244     fn parse_simple_operator_name() {
11245         assert_parse!(SimpleOperatorName {
11246             Ok => {
11247                 b"qu" => {
11248                     SimpleOperatorName::Question,
11249                     b""
11250                 }
11251                 b"quokka" => {
11252                     SimpleOperatorName::Question,
11253                     b"okka"
11254                 }
11255             }
11256             Err => {
11257                 b"bu-buuuu" => Error::UnexpectedText,
11258                 b"q" => Error::UnexpectedEnd,
11259                 b"" => Error::UnexpectedEnd,
11260             }
11261         });
11262     }
11263 }
11264