Coverage Report

Created: 2021-03-22 08:29

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