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