1 //! msvc-demangler is a crate for Rust that can demangle C++ symbols which use
2 //! the MSVC mangling scheme.  These are emitted by the Microsoft C++ compiler
3 //! for Windows as well as some others.
4 //!
5 //! # Example
6 //!
7 //! ```
8 //! use msvc_demangler;
9 //! let flags = msvc_demangler::DemangleFlags::llvm();
10 //! let result = msvc_demangler::demangle("??_0klass@@QEAAHH@Z", flags).unwrap();
11 //! println!("{}", result);
12 //! ```
13 //!
14 //! # Behavior
15 //!
16 //! It's functionality is similar to `undname` on Windows and the underlying
17 //! `UnDecorateSymbolName` function.  Since Microsoft does not document the
18 //! mangling scheme this is likely not to be entirely accurate.  When unclear
19 //! the implementation tries to follow what LLVM does.
20 //!
21 //! # License
22 //!
23 //! This msvc-demangler is dual licensed under the MIT and the University of
24 //! Illinois Open Source Licenses.
25 
26 #![deny(missing_debug_implementations)]
27 #![deny(unsafe_code)]
28 
29 #[macro_use]
30 extern crate bitflags;
31 
32 use std::borrow::Cow;
33 use std::cmp::min;
34 use std::error;
35 use std::fmt;
36 use std::io;
37 use std::io::Write;
38 use std::mem;
39 use std::result;
40 use std::str;
41 use std::str::Utf8Error;
42 use std::string::FromUtf8Error;
43 
44 pub struct Error {
45     repr: ErrorRepr,
46 }
47 
48 impl fmt::Debug for Error {
fmt(&self, f: &mut fmt::Formatter) -> fmt::Result49     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
50         fmt::Debug::fmt(&self.repr, f)
51     }
52 }
53 
54 #[derive(Debug)]
55 pub enum ErrorRepr {
56     FromUtf8(FromUtf8Error),
57     Utf8(Utf8Error),
58     Io(io::Error),
59     ParseError(Cow<'static, str>, String, usize),
60     Other(String),
61 }
62 
63 impl Error {
64     /// Creates a simple error message.
new<S: Into<String>>(s: S) -> Error65     pub fn new<S: Into<String>>(s: S) -> Error {
66         Error {
67             repr: ErrorRepr::Other(s.into()),
68         }
69     }
70 
new_parse_error(s: Cow<'static, str>, input: &str, offset: usize) -> Error71     fn new_parse_error(s: Cow<'static, str>, input: &str, offset: usize) -> Error {
72         let context = Cow::Borrowed(input.as_bytes().get(offset..).unwrap_or(&[]));
73         let context = if context.len() > 20 {
74             Cow::Owned(format!("{}...", String::from_utf8_lossy(&context[..20])))
75         } else {
76             String::from_utf8_lossy(&context)
77         };
78         Error {
79             repr: ErrorRepr::ParseError(s, context.to_string(), offset),
80         }
81     }
82 
83     /// Returns the offset in the input where the error happened.
offset(&self) -> Option<usize>84     pub fn offset(&self) -> Option<usize> {
85         match self.repr {
86             ErrorRepr::ParseError(_, _, offset) => Some(offset),
87             _ => None,
88         }
89     }
90 }
91 
92 impl From<Utf8Error> for Error {
from(err: Utf8Error) -> Error93     fn from(err: Utf8Error) -> Error {
94         Error {
95             repr: ErrorRepr::Utf8(err),
96         }
97     }
98 }
99 
100 impl From<FromUtf8Error> for Error {
from(err: FromUtf8Error) -> Error101     fn from(err: FromUtf8Error) -> Error {
102         Error {
103             repr: ErrorRepr::FromUtf8(err),
104         }
105     }
106 }
107 
108 impl From<std::io::Error> for Error {
from(err: std::io::Error) -> Error109     fn from(err: std::io::Error) -> Error {
110         Error {
111             repr: ErrorRepr::Io(err),
112         }
113     }
114 }
115 
116 impl error::Error for Error {
source(&self) -> Option<&(dyn error::Error + 'static)>117     fn source(&self) -> Option<&(dyn error::Error + 'static)> {
118         match self.repr {
119             ErrorRepr::FromUtf8(ref e) => Some(&*e),
120             ErrorRepr::Utf8(ref e) => Some(&*e),
121             ErrorRepr::Io(ref e) => Some(&*e),
122             ErrorRepr::ParseError(..) => None,
123             ErrorRepr::Other(_) => None,
124         }
125     }
126 }
127 
128 impl fmt::Display for Error {
fmt(&self, f: &mut fmt::Formatter) -> fmt::Result129     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
130         match self.repr {
131             ErrorRepr::FromUtf8(ref e) => fmt::Display::fmt(e, f),
132             ErrorRepr::Utf8(ref e) => fmt::Display::fmt(e, f),
133             ErrorRepr::Io(ref e) => fmt::Display::fmt(e, f),
134             ErrorRepr::ParseError(ref msg, ref context, offset) => {
135                 write!(f, "{} (offset: {}, remaining: {:?})", msg, offset, context)
136             }
137             ErrorRepr::Other(ref msg) => write!(f, "{}", msg),
138         }
139     }
140 }
141 
142 type Result<T> = result::Result<T, Error>;
143 
144 bitflags! {
145     pub struct StorageClass: u32 {
146         const CONST       = 0b0_0000_0001;
147         const VOLATILE    = 0b0_0000_0010;
148         const FAR         = 0b0_0000_0100;
149         const HUGE        = 0b0_0000_1000;
150         const UNALIGNED   = 0b0_0001_0000;
151         const RESTRICT    = 0b0_0010_0000;
152         const PTR64       = 0b0_0100_0000;
153         const LVALUE_QUAL = 0b0_1000_0000;
154         const RVALUE_QUAL = 0b1_0000_0000;
155     }
156 }
157 
158 bitflags! {
159     pub struct DemangleFlags: u32 {
160         /// Undecorate 32-bit decorated names.
161         const DECODE_32_BIT = 0x0800;
162         /// Enable full undecoration.
163         const COMPLETE = 0x0000;
164         /// Undecorate only the name for primary declaration. Returns [scope::]name. Does expand template parameters.
165         const NAME_ONLY = 0x1000;
166         /// Disable expansion of access specifiers for members.
167         const NO_ACCESS_SPECIFIERS = 0x0080;
168         // /// Disable expansion of the declaration language specifier.
169         // const NO_ALLOCATION_LANGUAGE = 0x0010;
170         // /// Disable expansion of the declaration model.
171         // const NO_ALLOCATION_MODEL = 0x0008;
172         // /// Do not undecorate function arguments.
173         // const NO_ARGUMENTS = 0x2000;
174         /// Disable expansion of CodeView modifiers on the this type for primary declaration.
175         const NO_CV_THISTYPE = 0x0040;
176         /// Disable expansion of return types for primary declarations.
177         const NO_FUNCTION_RETURNS = 0x0004;
178         // /// Remove leading underscores from Microsoft keywords.
179         // const NO_LEADING_UNDERSCORES = 0x0001;
180         /// Disable expansion of the static or virtual attribute of members.
181         const NO_MEMBER_TYPE = 0x0200;
182         /// Disable expansion of Microsoft keywords.
183         const NO_MS_KEYWORDS = 0x0002;
184         /// Disable expansion of Microsoft keywords on the this type for primary declaration.
185         const NO_MS_THISTYPE = 0x0020;
186         /// Enable Microsoft type names.
187         const MS_TYPENAMES = 0x0400;
188         // /// Disable expansion of the Microsoft model for user-defined type returns.
189         // const NO_RETURN_UDT_MODEL = 0x0400;
190         // /// Do not undecorate special names, such as vtable, vcall, vector, metatype, and so on.
191         // const NO_SPECIAL_SYMS = 0x4000;
192         /// Disable all modifiers on the this type.
193         const NO_THISTYPE = Self::NO_MS_THISTYPE.bits | Self::NO_CV_THISTYPE.bits;
194         // /// Disable expansion of throw-signatures for functions and pointers to functions.
195         // const NO_THROW_SIGNATURES = 0x0100;
196         /// Disable output of struct/union/class/enum specifiers.
197         // (Not sure if this duplicates an existing flag)
198         const NO_CLASS_TYPE = 0x10_0000;
199         /// Insert a space after each comma.
200         const SPACE_AFTER_COMMA = 0x20_0000;
201         /// Make * and & hug the type name.
202         const HUG_TYPE = 0x40_0000;
203         /// Insert a space before pointers.
204         const SPACE_BEFORE_POINTER = 0x80_0000;
205         /// Add ptr64 to output.  This is disabled by default because it's also not
206         /// added by LLVM.  This is in a way the inverse of the DIA `UNDNAME_NO_PTR64`
207         const WITH_PTR64 = 0x100_0000;
208     }
209 }
210 
211 impl DemangleFlags {
llvm() -> DemangleFlags212     pub fn llvm() -> DemangleFlags {
213         DemangleFlags::COMPLETE
214             | DemangleFlags::SPACE_AFTER_COMMA
215             | DemangleFlags::SPACE_BEFORE_POINTER
216             | DemangleFlags::MS_TYPENAMES
217             | DemangleFlags::HUG_TYPE
218     }
219 }
220 
221 // Calling conventions
222 #[derive(Clone, Copy, Debug, PartialEq)]
223 pub enum CallingConv {
224     Cdecl,
225     Pascal,
226     Thiscall,
227     Stdcall,
228     Fastcall,
229     _Regcall,
230 }
231 
232 bitflags! {
233     pub struct FuncClass: u32 {
234         const PUBLIC     = 0b0000_0001;
235         const PROTECTED  = 0b0000_0010;
236         const PRIVATE    = 0b0000_0100;
237         const GLOBAL     = 0b0000_1000;
238         const STATIC     = 0b0001_0000;
239         const VIRTUAL    = 0b0010_0000;
240         const FAR        = 0b0100_0000;
241         const THUNK      = 0b1000_0000;
242     }
243 }
244 
245 // The kind of variable storage. In LLVM this is called storage class.
246 #[derive(Clone, Copy, Debug, PartialEq)]
247 pub enum VarStorageKind {
248     PrivateStatic,
249     ProtectedStatic,
250     PublicStatic,
251     Global,
252     FunctionLocalStatic,
253 }
254 
255 // Represents an identifier which may be a template.
256 #[derive(Clone, PartialEq)]
257 pub enum Name<'a> {
258     Md5(&'a [u8]),
259     Operator(Operator<'a>),
260     NonTemplate(&'a [u8]),
261     AsInterface(&'a [u8]),
262     Template(Box<Name<'a>>, Params<'a>),
263     Discriminator(i32),
264     ParsedName(Box<ParseResult<'a>>),
265     AnonymousNamespace(Option<String>),
266 }
267 
268 impl<'a> fmt::Debug for Name<'a> {
fmt(&self, f: &mut fmt::Formatter) -> fmt::Result269     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
270         match *self {
271             Name::Md5(s) => f
272                 .debug_tuple("Md5")
273                 .field(&String::from_utf8_lossy(s))
274                 .finish(),
275             Name::Operator(ref op) => f.debug_tuple("Operator").field(&op).finish(),
276             Name::NonTemplate(s) => f
277                 .debug_tuple("NonTemplate")
278                 .field(&String::from_utf8_lossy(s))
279                 .finish(),
280             Name::AsInterface(s) => f
281                 .debug_tuple("AsInterface")
282                 .field(&String::from_utf8_lossy(s))
283                 .finish(),
284             Name::Template(ref name, ref params) => {
285                 f.debug_tuple("Template").field(name).field(params).finish()
286             }
287             Name::Discriminator(i) => f.debug_tuple("Discriminator").field(&i).finish(),
288             Name::ParsedName(ref res) => f.debug_tuple("ParsedName").field(res).finish(),
289             Name::AnonymousNamespace(ref name) => {
290                 f.debug_tuple("AnonymousNamespace").field(name).finish()
291             }
292         }
293     }
294 }
295 
296 #[derive(Clone, Debug, PartialEq)]
297 pub enum Operator<'a> {
298     Ctor,
299     Dtor,
300     New,
301     Delete,
302     Equal,
303     RShift,
304     LShift,
305     Bang,
306     EqualEqual,
307     BangEqual,
308     Subscript,
309     Conversion, // TODO
310     Arrow,
311     Star,
312     PlusPlus,
313     MinusMinus,
314     Minus,
315     Plus,
316     Amp,
317     ArrowStar,
318     Slash,
319     Percent,
320     Less,
321     LessEqual,
322     Greater,
323     GreaterEqual,
324     Comma,
325     Call,
326     Tilde,
327     Caret,
328     Pipe,
329     AmpAmp,
330     PipePipe,
331     StarEqual,
332     PlusEqual,
333     MinusEqual,
334     SlashEqual,
335     PercentEqual,
336     GreaterGreaterEqual,
337     LessLessEqual,
338     AmpEqual,
339     PipeEqual,
340     CaretEqual,
341 
342     VFTable,
343     VBTable,
344     VCall,
345     Typeof,
346     LocalStaticGuard(Option<u32>),
347     String,
348     VBaseDtor,
349     VectorDeletingDtor,
350     DefaultCtorClosure,
351     ScalarDeletingDtor,
352     VectorCtorIterator,
353     VectorDtorIterator,
354     VectorVBaseCtorIterator,
355     VirtualDisplacementMap,
356     EHVectorCtorIterator,
357     EHVectorDtorIterator,
358     EHVectorVBaseCtorIterator,
359     CopyCtorClosure,
360 
361     LocalVFTable,
362     LocalVFTableCtorClosure,
363     ArrayNew,
364     ArrayDelete,
365     PlacementDeleteClosure,
366     PlacementArrayDeleteClosure,
367 
368     CoroutineAwait,
369     LiteralOperatorName,
370 
371     RTTITypeDescriptor(StorageClass, Box<Type<'a>>),
372     RTTIBaseClassDescriptor(i32, i32, i32, i32),
373     RTTIBaseClassArray,
374     RTTIClassHierarchyDescriptor,
375     RTTIClassCompleteObjectLocator,
376 
377     DynamicInitializer,
378     DynamicAtexitDtor,
379     LocalStaticThreadGuard(Option<u32>),
380 }
381 
382 #[derive(Clone, Debug, PartialEq)]
383 pub struct NameSequence<'a> {
384     pub names: Vec<Name<'a>>,
385 }
386 
387 #[derive(Clone, Debug, PartialEq)]
388 pub struct Params<'a> {
389     pub types: Vec<Type<'a>>,
390 }
391 
392 #[derive(Clone, Debug, PartialEq)]
393 pub struct Symbol<'a> {
394     pub name: Name<'a>,
395     pub scope: NameSequence<'a>,
396 }
397 
398 // The type class. Mangled symbols are first parsed and converted to
399 // this type and then converted to string.
400 #[derive(Clone, Debug, PartialEq)]
401 pub enum Type<'a> {
402     None,
403     MemberFunction(
404         FuncClass,
405         CallingConv,
406         Params<'a>,
407         StorageClass,
408         Box<Type<'a>>,
409     ), // StorageClass is for the 'this' pointer
410     MemberFunctionPointer(
411         Symbol<'a>,
412         FuncClass,
413         CallingConv,
414         Params<'a>,
415         StorageClass,
416         Box<Type<'a>>,
417     ),
418     NonMemberFunction(CallingConv, Params<'a>, StorageClass, Box<Type<'a>>),
419     CXXVBTable(NameSequence<'a>, StorageClass),
420     CXXVFTable(NameSequence<'a>, StorageClass),
421     VCallThunk(i32, CallingConv),
422     TemplateParameterWithIndex(i32),
423     ThreadSafeStaticGuard(i32),
424     Constant(i32),
425     ConstantString(Vec<u8>),
426     Ptr(Box<Type<'a>>, StorageClass),
427     Ref(Box<Type<'a>>, StorageClass),
428     RValueRef(Box<Type<'a>>, StorageClass),
429     Array(i32, Box<Type<'a>>, StorageClass),
430     Var(Box<Type<'a>>, VarStorageKind, StorageClass),
431 
432     Alias(Symbol<'a>, StorageClass),
433     Struct(Symbol<'a>, StorageClass),
434     Union(Symbol<'a>, StorageClass),
435     Class(Symbol<'a>, StorageClass),
436     Enum(Symbol<'a>, StorageClass),
437 
438     Void(StorageClass),
439     Bool(StorageClass),
440     Char(StorageClass),
441     Schar(StorageClass),
442     Uchar(StorageClass),
443     Short(StorageClass),
444     Ushort(StorageClass),
445     Int(StorageClass),
446     Uint(StorageClass),
447     Long(StorageClass),
448     Ulong(StorageClass),
449     Int64(StorageClass),
450     Uint64(StorageClass),
451     Int128(StorageClass),
452     Uint128(StorageClass),
453     Wchar(StorageClass),
454     Char8(StorageClass),
455     Char16(StorageClass),
456     Char32(StorageClass),
457     Float(StorageClass),
458     Double(StorageClass),
459     Ldouble(StorageClass),
460     VarArgs,
461     EmptyParameterPack,
462     Nullptr,
463     RTTIType,
464 }
465 
466 #[derive(Debug, Clone, PartialEq)]
467 pub struct ParseResult<'a> {
468     pub symbol: Symbol<'a>,
469     pub symbol_type: Type<'a>,
470 }
471 
472 // Demangler class takes the main role in demangling symbols.
473 // It has a set of functions to parse mangled symbols into Type instnaces.
474 // It also has a set of functions to cnovert Type instances to strings.
475 struct ParserState<'a> {
476     // Mangled symbol. read_* functions shorten this string
477     // as they parse it.
478     remaining: &'a [u8],
479 
480     // The original input
481     input: &'a str,
482 
483     // how many bytes we advanced
484     offset: usize,
485 
486     // The first 10 names in a mangled name can be back-referenced by
487     // special name @[0-9]. This is a storage for the first 10 names.
488     memorized_names: Vec<Name<'a>>,
489 
490     memorized_types: Vec<Type<'a>>,
491 }
492 
493 impl<'a> ParserState<'a> {
fail(&self, s: &'static str) -> Error494     fn fail(&self, s: &'static str) -> Error {
495         Error::new_parse_error(Cow::Borrowed(s), self.input, self.offset)
496     }
497 
fail_args(&self, args: fmt::Arguments) -> Error498     fn fail_args(&self, args: fmt::Arguments) -> Error {
499         Error::new_parse_error(Cow::Owned(format!("{}", args)), self.input, self.offset)
500     }
501 
parse(&mut self) -> Result<ParseResult<'a>>502     fn parse(&mut self) -> Result<ParseResult<'a>> {
503         // MSVC-style mangled symbols must start with b'?'.
504         if !self.consume(b"?") {
505             return Err(self.fail("does not start with b'?'"));
506         }
507 
508         if self.consume(b"?@") {
509             let name = self.read_md5_name()?;
510             return Ok(ParseResult {
511                 symbol: Symbol {
512                     name,
513                     scope: NameSequence { names: Vec::new() },
514                 },
515                 symbol_type: Type::None,
516             });
517         }
518 
519         if self.consume(b"$") {
520             if self.consume(b"TSS") {
521                 let mut guard_num: i32 = i32::from(
522                     self.read_digit()
523                         .ok_or_else(|| self.fail("missing digit"))?,
524                 );
525                 while !self.consume(b"@") {
526                     guard_num = guard_num * 10
527                         + i32::from(
528                             self.read_digit()
529                                 .ok_or_else(|| self.fail("missing digit"))?,
530                         );
531                 }
532                 let name = self.read_nested_name()?;
533                 let scope = self.read_scope()?;
534                 self.expect(b"4HA")?;
535                 return Ok(ParseResult {
536                     symbol: Symbol { name, scope },
537                     symbol_type: Type::ThreadSafeStaticGuard(guard_num),
538                 });
539             }
540             let name = self.read_template_name()?;
541             return Ok(ParseResult {
542                 symbol: Symbol {
543                     name,
544                     scope: NameSequence { names: Vec::new() },
545                 },
546                 symbol_type: Type::None,
547             });
548         }
549 
550         // What follows is a main symbol name. This may include
551         // namespaces or class names.
552         let mut symbol = self.read_name(true)?;
553 
554         // Special case for some weird cases where extra data is tacked on
555         // after the main symbol but belongs into the symbol.
556         match symbol.name {
557             Name::Operator(Operator::LocalStaticGuard(ref mut scope_index))
558             | Name::Operator(Operator::LocalStaticThreadGuard(ref mut scope_index)) => {
559                 let _is_visible = if self.consume(b"4IA") {
560                     false
561                 } else if self.consume(b"5") {
562                     true
563                 } else {
564                     return Err(self.fail("unexpected local guard marker"));
565                 };
566                 if !self.remaining.is_empty() {
567                     *scope_index = Some(self.read_unsigned()?);
568                 };
569             }
570             _ => {}
571         }
572 
573         if let Ok(c) = self.get() {
574             let symbol_type = match c {
575                 b'0'..=b'4' => {
576                     // Read a variable.
577                     let kind = match c {
578                         b'0' => VarStorageKind::PrivateStatic,
579                         b'1' => VarStorageKind::ProtectedStatic,
580                         b'2' => VarStorageKind::PublicStatic,
581                         b'3' => VarStorageKind::Global,
582                         b'4' => VarStorageKind::FunctionLocalStatic,
583                         _ => unreachable!(),
584                     };
585                     let ty = self.read_var_type(StorageClass::empty())?;
586                     let sc = self.read_storage_class();
587                     Type::Var(Box::new(ty), kind, sc)
588                 }
589                 b'6' => {
590                     let access_class = self.read_qualifier();
591                     let scope = self.read_scope()?;
592                     Type::CXXVFTable(scope, access_class)
593                 }
594                 b'7' => {
595                     let access_class = self.read_qualifier();
596                     let scope = self.read_scope()?;
597                     Type::CXXVBTable(scope, access_class)
598                 }
599                 b'9' => {
600                     // extern "C" names have their class and type omitted.
601                     Type::None
602                 }
603                 b'Y' => {
604                     // Read a non-member function.
605                     let calling_conv = self.read_calling_conv()?;
606                     let storage_class = self.read_storage_class_for_return()?;
607                     let return_type = self.read_var_type(storage_class)?;
608                     let params = self.read_func_params()?;
609                     Type::NonMemberFunction(
610                         calling_conv,
611                         params,
612                         StorageClass::empty(),
613                         Box::new(return_type),
614                     )
615                 }
616                 b'_' => {
617                     // Read an encoded string.
618                     let char_bytes = match self.get()? {
619                         b'0' => 1, // char
620                         b'1' => 2, // wchar_t
621                         _ => {
622                             return Err(self.fail("unknown string character type"));
623                         }
624                     };
625                     self.read_encoded_string(char_bytes)?
626                 }
627                 b'$' => {
628                     self.expect(b"B")?;
629                     let vftable_offset = self.read_number()?;
630                     self.expect(b"A")?;
631                     let calling_conv = self.read_calling_conv()?;
632                     Type::VCallThunk(vftable_offset, calling_conv)
633                 }
634                 b'8' => Type::RTTIType,
635                 c => {
636                     // Read a member function.
637                     let func_class = self.read_func_class(c)?;
638                     let access_class = if func_class.contains(FuncClass::STATIC) {
639                         StorageClass::empty()
640                     } else {
641                         self.read_func_qualifiers()?
642                     };
643 
644                     let calling_conv = self.read_calling_conv()?;
645                     let storage_class_for_return = self.read_storage_class_for_return()?;
646                     let return_type = self.read_func_return_type(storage_class_for_return)?;
647                     let params = self.read_func_params()?;
648                     Type::MemberFunction(
649                         func_class,
650                         calling_conv,
651                         params,
652                         access_class,
653                         Box::new(return_type),
654                     )
655                 }
656             };
657             Ok(ParseResult {
658                 symbol,
659                 symbol_type,
660             })
661         } else {
662             Ok(ParseResult {
663                 symbol,
664                 symbol_type: Type::None,
665             })
666         }
667     }
668 
peek(&self) -> Option<u8>669     fn peek(&self) -> Option<u8> {
670         self.remaining.first().cloned()
671     }
672 
get(&mut self) -> Result<u8>673     fn get(&mut self) -> Result<u8> {
674         match self.peek() {
675             Some(first) => {
676                 self.advance(1);
677                 Ok(first)
678             }
679             None => Err(self.fail("unexpected end of input")),
680         }
681     }
682 
consume(&mut self, s: &[u8]) -> bool683     fn consume(&mut self, s: &[u8]) -> bool {
684         if self.remaining.starts_with(s) {
685             self.advance(s.len());
686             true
687         } else {
688             false
689         }
690     }
691 
advance(&mut self, len: usize)692     fn advance(&mut self, len: usize) {
693         let new_remaining = self.remaining.get(len..).unwrap_or(&[]);
694         self.offset += self.remaining.len() - new_remaining.len();
695         self.remaining = new_remaining;
696     }
697 
expect(&mut self, s: &[u8]) -> Result<()>698     fn expect(&mut self, s: &[u8]) -> Result<()> {
699         if !self.consume(s) {
700             Err(self.fail_args(format_args!("{} expected", str::from_utf8(s)?,)))
701         } else {
702             Ok(())
703         }
704     }
705 
706     /// An MD5 mangled name is `??@` followed by 32 characters and a terminating `@`.
707     ///
708     /// See https://github.com/llvm/llvm-project/blob/818cf30b83305fa4a2f75821349210b0f7aff4a4/llvm/lib/Demangle/MicrosoftDemangle.cpp#L754
read_md5_name(&mut self) -> Result<Name<'a>>709     fn read_md5_name(&mut self) -> Result<Name<'a>> {
710         let start_offset = self.offset;
711 
712         while self.read_hex_digit().is_some() {}
713         let end_offset = self.offset;
714 
715         if self.offset - start_offset != 32 || !self.consume(b"@") {
716             return Err(self.fail("expected MD5 mangled name of length 32"));
717         }
718         Ok(Name::Md5(&self.input.as_bytes()[start_offset..end_offset]))
719     }
720 
read_digit(&mut self) -> Option<u8>721     fn read_digit(&mut self) -> Option<u8> {
722         match self.peek() {
723             Some(first) => {
724                 if char::from(first).is_digit(10) {
725                     self.advance(1);
726                     Some(first - b'0')
727                 } else {
728                     None
729                 }
730             }
731             None => None,
732         }
733     }
734 
read_hex_digit(&mut self) -> Option<char>735     fn read_hex_digit(&mut self) -> Option<char> {
736         match self.peek() {
737             Some(first) => {
738                 if char::from(first).is_digit(16) {
739                     self.advance(1);
740                     Some(first as char)
741                 } else {
742                     None
743                 }
744             }
745             None => None,
746         }
747     }
748 
read_encoded_string(&mut self, char_bytes: i32) -> Result<Type<'a>>749     fn read_encoded_string(&mut self, char_bytes: i32) -> Result<Type<'a>> {
750         let byte_length = self.read_number()?; // including null terminator
751         let _crc = self.read_number()?;
752         let bytes = min(byte_length, char_bytes * 32);
753 
754         let mut collected = vec![];
755         for _i in 0..bytes {
756             let c = self.get()?;
757             let byte: u8 = match c {
758                 b'0'..=b'9' | b'a'..=b'z' | b'A'..=b'Z' | b'_' | b'$' => c,
759                 b'?' => {
760                     let c = self.get()?;
761                     match c {
762                         b'A'..=b'Z' => c - b'A' + 0xe1,
763                         b'a'..=b'z' => c - b'A' + 0xc1,
764                         b'0'..=b'9' => {
765                             let v = &[
766                                 b',', b'/', b'\\', b':', b'.', b' ', b'\n', b'\t', b'\'', b'-',
767                             ];
768                             v[(c - b'0') as usize]
769                         }
770                         b'$' => {
771                             let high = self.get()? - b'A';
772                             let low = self.get()? - b'A';
773                             high << 4 | low
774                         }
775                         _ => {
776                             return Err(self.fail_args(format_args!(
777                                 "unknown escaped encoded string character {}",
778                                 char::from(c)
779                             )));
780                         }
781                     }
782                 }
783                 _ => {
784                     return Err(self.fail_args(format_args!(
785                         "unknown escaped encoded string character {}",
786                         char::from(c)
787                     )));
788                 }
789             };
790             collected.push(byte);
791         }
792 
793         Ok(Type::ConstantString(collected))
794     }
795 
796     // Sometimes numbers are encoded in mangled symbols. For example,
797     // "int (*x)[20]" is a valid C type (x is a pointer to an array of
798     // length 20), so we need some way to embed numbers as part of symbols.
799     // This function parses it.
800     //
801     // <number>               ::= [?] <non-negative integer>
802     //
803     // <non-negative integer> ::= <decimal digit> # when 1 <= Number <= 10
804     //                        ::= <hex digit>+ @  # when Numbrer == 0 or >= 10
805     //
806     // <hex-digit>            ::= [A-P]           # A = 0, B = 1, ...
read_number(&mut self) -> Result<i32>807     fn read_number(&mut self) -> Result<i32> {
808         let neg = self.consume(b"?");
809 
810         if let Some(digit) = self.read_digit() {
811             let ret = digit + 1;
812             return Ok(if neg { -i32::from(ret) } else { i32::from(ret) });
813         }
814 
815         let mut i = 0;
816         let mut ret = 0;
817         for c in self.remaining {
818             match *c {
819                 b'@' => {
820                     self.advance(i + 1);
821                     return Ok(if neg { -(ret as i32) } else { ret as i32 });
822                 }
823                 b'A'..=b'P' => {
824                     ret = (ret << 4) + i32::from(c - b'A');
825                     i += 1;
826                 }
827                 _ => {
828                     return Err(self.fail("bad number"));
829                 }
830             }
831         }
832         Err(self.fail("bad number"))
833     }
834 
read_unsigned(&mut self) -> Result<u32>835     fn read_unsigned(&mut self) -> Result<u32> {
836         let num = self.read_number()?;
837         if num < 0 {
838             return Err(self.fail("expected unsigned"));
839         }
840         Ok(num as u32)
841     }
842 
843     // Read until the next b'@'.
read_string(&mut self) -> Result<&'a [u8]>844     fn read_string(&mut self) -> Result<&'a [u8]> {
845         if let Some(pos) = self.remaining.iter().position(|&x| x == b'@') {
846             let ret = &self.remaining[0..pos];
847             self.advance(pos + 1);
848             Ok(ret)
849         } else {
850             Err(self.fail("read_string: missing b'@'"))
851         }
852     }
853 
854     // First 10 strings can be referenced by special names ?0, ?1, ..., ?9.
855     // Memorize it.
memorize_name(&mut self, n: &Name<'a>)856     fn memorize_name(&mut self, n: &Name<'a>) {
857         // TODO: the contains check does an equality check on the Name enum, which
858         // might do unexpected things in subtle cases. It's not a pure string equality check.
859         if self.memorized_names.len() < 10 && !self.memorized_names.contains(n) {
860             self.memorized_names.push(n.clone());
861         }
862     }
memorize_type(&mut self, t: &Type<'a>)863     fn memorize_type(&mut self, t: &Type<'a>) {
864         // TODO: the contains check does an equality check on the Type enum, which
865         // might do unexpected things in subtle cases. It's not a pure string equality check.
866         if self.memorized_types.len() < 10 && !self.memorized_types.contains(t) {
867             self.memorized_types.push(t.clone());
868         }
869     }
870 
read_template_name(&mut self) -> Result<Name<'a>>871     fn read_template_name(&mut self) -> Result<Name<'a>> {
872         // Templates have their own context for backreferences.
873         let saved_memorized_names = mem::take(&mut self.memorized_names);
874         let saved_memorized_types = mem::take(&mut self.memorized_types);
875         let name = self.read_unqualified_name(false)?; // how does wine deal with ??$?DM@std@@YA?AV?$complex@M@0@ABMABV10@@Z
876         let template_params = self.read_params()?;
877         let _ = mem::replace(&mut self.memorized_names, saved_memorized_names);
878         let _ = mem::replace(&mut self.memorized_types, saved_memorized_types);
879         Ok(Name::Template(Box::new(name), template_params))
880     }
881 
read_nested_name(&mut self) -> Result<Name<'a>>882     fn read_nested_name(&mut self) -> Result<Name<'a>> {
883         let name = if let Some(i) = self.read_digit() {
884             let i = i as usize;
885             if i >= self.memorized_names.len() {
886                 return Err(self.fail("name reference too large"));
887             }
888             self.memorized_names[i].clone()
889         } else if self.consume(b"?") {
890             match self.peek() {
891                 Some(b'?') => Name::ParsedName(Box::new(self.parse()?)),
892                 _ => {
893                     if self.consume(b"$") {
894                         let name = self.read_template_name()?;
895                         self.memorize_name(&name);
896                         name
897                     } else if self.consume(b"A") {
898                         let id = if self.consume(b"0x") {
899                             let mut name = String::from("0x");
900                             while let Some(c) = self.read_hex_digit() {
901                                 name.push(c);
902                             }
903                             Some(name)
904                         } else {
905                             None
906                         };
907                         self.expect(b"@")?;
908                         let memorize = id.is_some();
909                         let name = Name::AnonymousNamespace(id);
910                         if memorize {
911                             self.memorize_name(&name);
912                         }
913                         name
914                     } else if self.consume(b"Q") {
915                         let name = self.read_string()?;
916                         self.expect(b"@")?;
917                         let name = Name::AsInterface(name);
918                         self.memorize_name(&name);
919                         name
920                     } else {
921                         let discriminator = self.read_number()?;
922                         Name::Discriminator(discriminator)
923                     }
924                 }
925             }
926         } else {
927             // Non-template functions or classes.
928             let name = self.read_string()?;
929             let name = Name::NonTemplate(name);
930             self.memorize_name(&name);
931             name
932         };
933         Ok(name)
934     }
935 
read_unqualified_name(&mut self, function: bool) -> Result<Name<'a>>936     fn read_unqualified_name(&mut self, function: bool) -> Result<Name<'a>> {
937         let name = if let Some(i) = self.read_digit() {
938             let i = i as usize;
939             if i >= self.memorized_names.len() {
940                 return Err(self.fail("name reference too large"));
941             }
942             self.memorized_names[i].clone()
943         } else if self.consume(b"?$") {
944             let name = self.read_template_name()?;
945             if !function {
946                 self.memorize_name(&name);
947             }
948             name
949         } else if self.consume(b"?") {
950             self.read_special_name()?
951         } else {
952             // Non-template functions or classes.
953             let name = self.read_string()?;
954             let name = Name::NonTemplate(name);
955             self.memorize_name(&name);
956             name
957         };
958         Ok(name)
959     }
960 
read_scope(&mut self) -> Result<NameSequence<'a>>961     fn read_scope(&mut self) -> Result<NameSequence<'a>> {
962         let mut names = Vec::new();
963         while !self.consume(b"@") {
964             let name = self.read_nested_name()?;
965             names.push(name);
966         }
967         Ok(NameSequence { names })
968     }
969 
970     // Parses a name in the form of A@B@C@@ which represents C::B::A.
read_name(&mut self, function: bool) -> Result<Symbol<'a>>971     fn read_name(&mut self, function: bool) -> Result<Symbol<'a>> {
972         let name = self.read_unqualified_name(function)?;
973         let scope = self.read_scope()?;
974 
975         Ok(Symbol { name, scope })
976     }
977 
read_func_qualifiers(&mut self) -> Result<StorageClass>978     fn read_func_qualifiers(&mut self) -> Result<StorageClass> {
979         let ptr64 = if self.consume(b"E") {
980             StorageClass::PTR64
981         } else {
982             StorageClass::empty()
983         };
984         let restrict = if self.consume(b"I") {
985             StorageClass::RESTRICT
986         } else {
987             StorageClass::empty()
988         };
989         let unaligned = if self.consume(b"F") {
990             StorageClass::UNALIGNED
991         } else {
992             StorageClass::empty()
993         };
994         let ref_qualifiers = match self.peek() {
995             Some(b'G') => {
996                 self.expect(b"G")?;
997                 StorageClass::LVALUE_QUAL
998             }
999             Some(b'H') => {
1000                 self.expect(b"H")?;
1001                 StorageClass::RVALUE_QUAL
1002             }
1003             _ => StorageClass::empty(),
1004         };
1005         Ok(self.read_qualifier() | ptr64 | restrict | unaligned | ref_qualifiers)
1006     }
1007 
read_func_type(&mut self, read_qualifiers: bool) -> Result<Type<'a>>1008     fn read_func_type(&mut self, read_qualifiers: bool) -> Result<Type<'a>> {
1009         let sc = if read_qualifiers {
1010             self.read_func_qualifiers()?
1011         } else {
1012             StorageClass::empty()
1013         };
1014         let calling_conv = self.read_calling_conv()?;
1015         // this might have to be conditional on template context.  For now
1016         // this does not cause issues.  For more information see
1017         // https://github.com/mstange/msvc-demangler-rust/issues/21
1018         let var_sc = if self.consume(b"?") {
1019             self.read_storage_class()
1020         } else {
1021             StorageClass::empty()
1022         };
1023         let return_type = self.read_var_type(var_sc)?;
1024         let params = self.read_func_params()?;
1025         Ok(Type::NonMemberFunction(
1026             calling_conv,
1027             params,
1028             sc,
1029             Box::new(return_type),
1030         ))
1031     }
1032 
read_special_name(&mut self) -> Result<Name<'a>>1033     fn read_special_name(&mut self) -> Result<Name<'a>> {
1034         Ok(Name::Operator(match self.get()? {
1035             b'0' => Operator::Ctor,
1036             b'1' => Operator::Dtor,
1037             b'2' => Operator::New,
1038             b'3' => Operator::Delete,
1039             b'4' => Operator::Equal,
1040             b'5' => Operator::RShift,
1041             b'6' => Operator::LShift,
1042             b'7' => Operator::Bang,
1043             b'8' => Operator::EqualEqual,
1044             b'9' => Operator::BangEqual,
1045             b'A' => Operator::Subscript,
1046             b'B' => Operator::Conversion,
1047             b'C' => Operator::Arrow,
1048             b'D' => Operator::Star,
1049             b'E' => Operator::PlusPlus,
1050             b'F' => Operator::MinusMinus,
1051             b'G' => Operator::Minus,
1052             b'H' => Operator::Plus,
1053             b'I' => Operator::Amp,
1054             b'J' => Operator::ArrowStar,
1055             b'K' => Operator::Slash,
1056             b'L' => Operator::Percent,
1057             b'M' => Operator::Less,
1058             b'N' => Operator::LessEqual,
1059             b'O' => Operator::Greater,
1060             b'P' => Operator::GreaterEqual,
1061             b'Q' => Operator::Comma,
1062             b'R' => Operator::Call,
1063             b'S' => Operator::Tilde,
1064             b'T' => Operator::Caret,
1065             b'U' => Operator::Pipe,
1066             b'V' => Operator::AmpAmp,
1067             b'W' => Operator::PipePipe,
1068             b'X' => Operator::StarEqual,
1069             b'Y' => Operator::PlusEqual,
1070             b'Z' => Operator::MinusEqual,
1071             b'_' => match self.get()? {
1072                 b'0' => Operator::SlashEqual,
1073                 b'1' => Operator::PercentEqual,
1074                 b'2' => Operator::GreaterGreaterEqual,
1075                 b'3' => Operator::LessLessEqual,
1076                 b'4' => Operator::AmpEqual,
1077                 b'5' => Operator::PipeEqual,
1078                 b'6' => Operator::CaretEqual,
1079                 b'7' => Operator::VFTable,
1080                 b'8' => Operator::VBTable,
1081                 b'9' => Operator::VCall,
1082                 b'A' => Operator::Typeof,
1083                 b'B' => Operator::LocalStaticGuard(None),
1084                 b'C' => Operator::String,
1085                 b'D' => Operator::VBaseDtor,
1086                 b'E' => Operator::VectorDeletingDtor,
1087                 b'F' => Operator::DefaultCtorClosure,
1088                 b'G' => Operator::ScalarDeletingDtor,
1089                 b'H' => Operator::VectorCtorIterator,
1090                 b'I' => Operator::VectorDtorIterator,
1091                 b'J' => Operator::VectorVBaseCtorIterator,
1092                 b'K' => Operator::VirtualDisplacementMap,
1093                 b'L' => Operator::EHVectorCtorIterator,
1094                 b'M' => Operator::EHVectorDtorIterator,
1095                 b'N' => Operator::EHVectorVBaseCtorIterator,
1096                 b'O' => Operator::CopyCtorClosure,
1097                 b'R' => {
1098                     let c = self.get()?;
1099                     match c {
1100                         b'0' => {
1101                             self.expect(b"?")?;
1102                             let storage_class = self.read_storage_class();
1103                             let t = self.read_var_type(storage_class)?;
1104                             Operator::RTTITypeDescriptor(storage_class, Box::new(t))
1105                         }
1106                         b'1' => {
1107                             let nv_offset = self.read_number()?;
1108                             let vbptr_offset = self.read_number()?;
1109                             let vbtable_offset = self.read_number()?;
1110                             let flags = self.read_number()?;
1111                             Operator::RTTIBaseClassDescriptor(
1112                                 nv_offset,
1113                                 vbptr_offset,
1114                                 vbtable_offset,
1115                                 flags,
1116                             )
1117                         }
1118                         b'2' => Operator::RTTIBaseClassArray,
1119                         b'3' => Operator::RTTIClassHierarchyDescriptor,
1120                         b'4' => Operator::RTTIClassCompleteObjectLocator,
1121                         _ => {
1122                             return Err(self.fail("unknown RTTI Operator name"));
1123                         }
1124                     }
1125                 }
1126                 b'S' => Operator::LocalVFTable,
1127                 b'T' => Operator::LocalVFTableCtorClosure,
1128                 b'U' => Operator::ArrayNew,
1129                 b'V' => Operator::ArrayDelete,
1130                 b'X' => Operator::PlacementDeleteClosure,
1131                 b'Y' => Operator::PlacementArrayDeleteClosure,
1132                 b'_' => {
1133                     if self.consume(b"L") {
1134                         Operator::CoroutineAwait
1135                     } else if self.consume(b"E") {
1136                         Operator::DynamicInitializer
1137                     } else if self.consume(b"F") {
1138                         Operator::DynamicAtexitDtor
1139                     } else if self.consume(b"J") {
1140                         Operator::LocalStaticThreadGuard(None)
1141                     } else if self.consume(b"K") {
1142                         Operator::LiteralOperatorName // TODO: read <source-name>, that's the operator name
1143                     } else {
1144                         return Err(self.fail("unknown operator name"));
1145                     }
1146                 }
1147                 _ => {
1148                     return Err(self.fail("unknown operator name"));
1149                 }
1150             },
1151             _ => {
1152                 return Err(self.fail("unknown operator name"));
1153             }
1154         }))
1155     }
1156 
read_func_class(&mut self, c: u8) -> Result<FuncClass>1157     fn read_func_class(&mut self, c: u8) -> Result<FuncClass> {
1158         // TODO: need to figure out how to wrap up the adjustment.
1159         let mut read_thunk = |func_class| -> Result<FuncClass> {
1160             let _adjustment = self.read_number()?;
1161             Ok(func_class | FuncClass::THUNK)
1162         };
1163 
1164         Ok(match c {
1165             b'A' => FuncClass::PRIVATE,
1166             b'B' => FuncClass::PRIVATE | FuncClass::FAR,
1167             b'C' => FuncClass::PRIVATE | FuncClass::STATIC,
1168             b'D' => FuncClass::PRIVATE | FuncClass::STATIC,
1169             b'E' => FuncClass::PRIVATE | FuncClass::VIRTUAL,
1170             b'F' => FuncClass::PRIVATE | FuncClass::VIRTUAL,
1171             // TODO(mitsuhiko): llvm uses adjustor here instead of virtual
1172             b'G' => read_thunk(FuncClass::PRIVATE | FuncClass::VIRTUAL)?,
1173             // TODO(mitsuhiko): llvm uses adjustor here instead of virtual
1174             b'H' => read_thunk(FuncClass::PRIVATE | FuncClass::VIRTUAL | FuncClass::FAR)?,
1175             b'I' => FuncClass::PROTECTED,
1176             b'J' => FuncClass::PROTECTED | FuncClass::FAR,
1177             b'K' => FuncClass::PROTECTED | FuncClass::STATIC,
1178             b'L' => FuncClass::PROTECTED | FuncClass::STATIC | FuncClass::FAR,
1179             b'M' => FuncClass::PROTECTED | FuncClass::VIRTUAL,
1180             b'N' => FuncClass::PROTECTED | FuncClass::VIRTUAL | FuncClass::FAR,
1181             // TODO(mitsuhiko): llvm uses adjustor here instead of virtual
1182             b'O' => read_thunk(FuncClass::PROTECTED | FuncClass::VIRTUAL)?,
1183             // TODO(mitsuhiko): llvm uses adjustor here instead of virtual
1184             b'P' => read_thunk(FuncClass::PROTECTED | FuncClass::VIRTUAL | FuncClass::FAR)?,
1185             b'Q' => FuncClass::PUBLIC,
1186             b'R' => FuncClass::PUBLIC | FuncClass::FAR,
1187             b'S' => FuncClass::PUBLIC | FuncClass::STATIC,
1188             b'T' => FuncClass::PUBLIC | FuncClass::STATIC | FuncClass::FAR,
1189             b'U' => FuncClass::PUBLIC | FuncClass::VIRTUAL,
1190             b'V' => FuncClass::PUBLIC | FuncClass::VIRTUAL | FuncClass::FAR,
1191             // TODO(mitsuhiko): llvm uses adjustor here instead of virtual
1192             b'W' => read_thunk(FuncClass::PUBLIC | FuncClass::VIRTUAL)?,
1193             // TODO(mitsuhiko): llvm uses adjustor here instead of virtual
1194             b'X' => read_thunk(FuncClass::PUBLIC | FuncClass::VIRTUAL | FuncClass::FAR)?,
1195             b'Y' => FuncClass::GLOBAL,
1196             b'Z' => FuncClass::GLOBAL | FuncClass::FAR,
1197             _ => {
1198                 return Err(self.fail("unknown func class"));
1199             }
1200         })
1201     }
1202 
read_qualifier(&mut self) -> StorageClass1203     fn read_qualifier(&mut self) -> StorageClass {
1204         let access_class = match self.peek() {
1205             Some(b'A') => StorageClass::empty(),
1206             Some(b'B') => StorageClass::CONST,
1207             Some(b'C') => StorageClass::VOLATILE,
1208             Some(b'D') => StorageClass::CONST | StorageClass::VOLATILE,
1209             Some(b'Q') => StorageClass::empty(),
1210             Some(b'R') => StorageClass::CONST,
1211             Some(b'S') => StorageClass::VOLATILE,
1212             Some(b'T') => StorageClass::CONST | StorageClass::VOLATILE,
1213             _ => return StorageClass::empty(),
1214         };
1215         self.advance(1);
1216         access_class
1217     }
1218 
read_calling_conv(&mut self) -> Result<CallingConv>1219     fn read_calling_conv(&mut self) -> Result<CallingConv> {
1220         Ok(match self.get()? {
1221             b'A' => CallingConv::Cdecl,
1222             b'B' => CallingConv::Cdecl,
1223             b'C' => CallingConv::Pascal,
1224             b'E' => CallingConv::Thiscall,
1225             b'G' => CallingConv::Stdcall,
1226             b'I' => CallingConv::Fastcall,
1227             _ => {
1228                 return Err(self.fail("unknown calling conv"));
1229             }
1230         })
1231     }
1232 
1233     // <return-type> ::= <type>
1234     //               ::= @ # structors (they have no declared return type)
read_func_return_type(&mut self, storage_class: StorageClass) -> Result<Type<'a>>1235     fn read_func_return_type(&mut self, storage_class: StorageClass) -> Result<Type<'a>> {
1236         if self.consume(b"@") {
1237             Ok(Type::None)
1238         } else {
1239             self.read_var_type(storage_class)
1240         }
1241     }
1242 
read_storage_class(&mut self) -> StorageClass1243     fn read_storage_class(&mut self) -> StorageClass {
1244         let storage_class = match self.peek() {
1245             Some(b'A') => StorageClass::empty(),
1246             Some(b'B') => StorageClass::CONST,
1247             Some(b'C') => StorageClass::VOLATILE,
1248             Some(b'D') => StorageClass::CONST | StorageClass::VOLATILE,
1249             Some(b'E') => StorageClass::FAR,
1250             Some(b'F') => StorageClass::CONST | StorageClass::FAR,
1251             Some(b'G') => StorageClass::VOLATILE | StorageClass::FAR,
1252             Some(b'H') => StorageClass::CONST | StorageClass::VOLATILE | StorageClass::FAR,
1253             Some(b'Q') => StorageClass::empty(),
1254             Some(b'R') => StorageClass::CONST,
1255             Some(b'S') => StorageClass::VOLATILE,
1256             Some(b'T') => StorageClass::CONST | StorageClass::VOLATILE,
1257             _ => return StorageClass::empty(),
1258         };
1259         self.advance(1);
1260         storage_class
1261     }
1262 
read_storage_class_for_return(&mut self) -> Result<StorageClass>1263     fn read_storage_class_for_return(&mut self) -> Result<StorageClass> {
1264         if !self.consume(b"?") {
1265             return Ok(StorageClass::empty());
1266         }
1267 
1268         Ok(match self.get()? {
1269             b'A' => StorageClass::empty(),
1270             b'B' => StorageClass::CONST,
1271             b'C' => StorageClass::VOLATILE,
1272             b'D' => StorageClass::CONST | StorageClass::VOLATILE,
1273             _ => {
1274                 return Err(self.fail("unknown storage class"));
1275             }
1276         })
1277     }
1278 
read_member_function_pointer(&mut self, read_qualifiers: bool) -> Result<Type<'a>>1279     fn read_member_function_pointer(&mut self, read_qualifiers: bool) -> Result<Type<'a>> {
1280         let symbol = self.read_name(true)?;
1281         let ptr64 = if self.consume(b"E") {
1282             StorageClass::PTR64
1283         } else {
1284             StorageClass::empty()
1285         };
1286         let (access_class, func_class) = if read_qualifiers {
1287             (self.read_qualifier() | ptr64, FuncClass::empty())
1288         } else {
1289             let c = self.get()?;
1290             (ptr64, self.read_func_class(c)?)
1291         };
1292         let calling_conv = self.read_calling_conv()?;
1293         let storage_class_for_return = self.read_storage_class_for_return()?;
1294         let return_type = self.read_func_return_type(storage_class_for_return)?;
1295         let params = self.read_func_params()?;
1296         Ok(Type::MemberFunctionPointer(
1297             symbol,
1298             func_class,
1299             calling_conv,
1300             params,
1301             access_class,
1302             Box::new(return_type),
1303         ))
1304     }
1305 
1306     // Reads a variable type.
read_var_type(&mut self, mut sc: StorageClass) -> Result<Type<'a>>1307     fn read_var_type(&mut self, mut sc: StorageClass) -> Result<Type<'a>> {
1308         if self.consume(b"W4") {
1309             let name = self.read_name(false)?;
1310             return Ok(Type::Enum(name, sc));
1311         }
1312 
1313         if self.consume(b"A6") {
1314             let func_type = self.read_func_type(false)?;
1315             return Ok(Type::Ref(Box::new(func_type), sc));
1316         }
1317 
1318         if self.consume(b"P6") {
1319             let func_type = self.read_func_type(false)?;
1320             return Ok(Type::Ptr(Box::new(func_type), sc));
1321         }
1322 
1323         if self.consume(b"P8") {
1324             return self.read_member_function_pointer(true);
1325         }
1326 
1327         if self.consume(b"$") {
1328             if self.consume(b"0") {
1329                 let n = self.read_number()?;
1330                 return Ok(Type::Constant(n));
1331             }
1332             if self.consume(b"D") {
1333                 let n = self.read_number()?;
1334                 return Ok(Type::TemplateParameterWithIndex(n));
1335             }
1336             if self.consume(b"$BY") {
1337                 return self.read_array();
1338             }
1339             if self.consume(b"$Q") {
1340                 return Ok(Type::RValueRef(Box::new(self.read_pointee()?), sc));
1341             }
1342             if self.consume(b"S")
1343                 || self.consume(b"$V")
1344                 || self.consume(b"$Z")
1345                 || self.consume(b"$$V")
1346             {
1347                 return Ok(Type::EmptyParameterPack);
1348             }
1349             if self.consume(b"$T") {
1350                 return Ok(Type::Nullptr);
1351             }
1352             if self.consume(b"$A6") {
1353                 return self.read_func_type(false);
1354             }
1355             if self.consume(b"$A8@@") {
1356                 return self.read_func_type(true);
1357             }
1358             if self.consume(b"$Y") {
1359                 let name = self.read_name(true)?;
1360                 return Ok(Type::Alias(name, sc));
1361             }
1362             // These next cases can fallthrough, so be careful adding new ones!
1363             if self.consume(b"$C") {
1364                 sc = self.read_qualifier();
1365             } else if let Some(x) = self.peek() {
1366                 match x {
1367                     // Inheritance specifiers, which we don't need to remember.
1368                     b'1' | b'H' | b'I' | b'J' => {
1369                         self.advance(1);
1370                         self.expect(b"?")?;
1371                         return self.read_member_function_pointer(false);
1372                     }
1373                     _ => {}
1374                 };
1375             }
1376         }
1377 
1378         if self.consume(b"?") {
1379             let n = self.read_number()?;
1380             return Ok(Type::TemplateParameterWithIndex(-n));
1381         }
1382 
1383         if let Some(n) = self.read_digit() {
1384             if n as usize >= self.memorized_types.len() {
1385                 return Err(self.fail_args(format_args!("invalid backreference: {}", n)));
1386             }
1387 
1388             return Ok(self.memorized_types[n as usize].clone());
1389         }
1390 
1391         Ok(match self.get()? {
1392             b'T' => Type::Union(self.read_name(false)?, sc),
1393             b'U' => Type::Struct(self.read_name(false)?, sc),
1394             b'V' => Type::Class(self.read_name(false)?, sc),
1395             b'A' => Type::Ref(Box::new(self.read_pointee()?), sc),
1396             b'B' => Type::Ref(Box::new(self.read_pointee()?), StorageClass::VOLATILE),
1397             b'P' => Type::Ptr(Box::new(self.read_pointee()?), sc),
1398             b'Q' => Type::Ptr(Box::new(self.read_pointee()?), StorageClass::CONST),
1399             b'R' => Type::Ptr(Box::new(self.read_pointee()?), StorageClass::VOLATILE),
1400             b'S' => Type::Ptr(
1401                 Box::new(self.read_pointee()?),
1402                 StorageClass::CONST | StorageClass::VOLATILE,
1403             ),
1404             b'Y' => self.read_array()?,
1405             b'X' => Type::Void(sc),
1406             b'D' => Type::Char(sc),
1407             b'C' => Type::Schar(sc),
1408             b'E' => Type::Uchar(sc),
1409             b'F' => Type::Short(sc),
1410             b'G' => Type::Ushort(sc),
1411             b'H' => Type::Int(sc),
1412             b'I' => Type::Uint(sc),
1413             b'J' => Type::Long(sc),
1414             b'K' => Type::Ulong(sc),
1415             b'M' => Type::Float(sc),
1416             b'N' => Type::Double(sc),
1417             b'O' => Type::Ldouble(sc),
1418             b'_' => match self.get()? {
1419                 b'N' => Type::Bool(sc),
1420                 b'J' => Type::Int64(sc),
1421                 b'K' => Type::Uint64(sc),
1422                 b'L' => Type::Int128(sc),
1423                 b'M' => Type::Uint128(sc),
1424                 b'W' => Type::Wchar(sc),
1425                 b'Q' => Type::Char8(sc),
1426                 b'S' => Type::Char16(sc),
1427                 b'U' => Type::Char32(sc),
1428                 _ => {
1429                     return Err(self.fail("unknown primitive type"));
1430                 }
1431             },
1432             _c => {
1433                 return Err(self.fail("unknown primitive type"));
1434             }
1435         })
1436     }
1437 
read_pointee(&mut self) -> Result<Type<'a>>1438     fn read_pointee(&mut self) -> Result<Type<'a>> {
1439         let ptr64 = if self.consume(b"E") {
1440             StorageClass::PTR64
1441         } else {
1442             StorageClass::empty()
1443         };
1444         let storage_class = self.read_storage_class();
1445         self.read_var_type(storage_class | ptr64)
1446     }
1447 
read_array(&mut self) -> Result<Type<'a>>1448     fn read_array(&mut self) -> Result<Type<'a>> {
1449         let dimension = self.read_number()?;
1450         if dimension <= 0 {
1451             return Err(self.fail_args(format_args!("invalid array dimension: {}", dimension)));
1452         }
1453         let (array, _) = self.read_nested_array(dimension)?;
1454         Ok(array)
1455     }
1456 
read_nested_array(&mut self, dimension: i32) -> Result<(Type<'a>, StorageClass)>1457     fn read_nested_array(&mut self, dimension: i32) -> Result<(Type<'a>, StorageClass)> {
1458         if dimension > 0 {
1459             let len = self.read_number()?;
1460             let (inner_array, storage_class) = self.read_nested_array(dimension - 1)?;
1461             Ok((
1462                 Type::Array(len, Box::new(inner_array), storage_class),
1463                 storage_class,
1464             ))
1465         } else {
1466             let storage_class = if self.consume(b"$$C") {
1467                 if self.consume(b"B") {
1468                     StorageClass::CONST
1469                 } else if self.consume(b"C") || self.consume(b"D") {
1470                     StorageClass::CONST | StorageClass::VOLATILE
1471                 } else if !self.consume(b"A") {
1472                     return Err(self.fail("unknown storage class"));
1473                 } else {
1474                     StorageClass::empty()
1475                 }
1476             } else {
1477                 StorageClass::empty()
1478             };
1479 
1480             Ok((self.read_var_type(StorageClass::empty())?, storage_class))
1481         }
1482     }
1483 
1484     // Reads a function or a template parameters.
read_params(&mut self) -> Result<Params<'a>>1485     fn read_params(&mut self) -> Result<Params<'a>> {
1486         // println!("read_params on {}", str::from_utf8(self.input)?);
1487         // Within the same parameter list, you can backreference the first 10 types.
1488         // let mut backref: Vec<Type<'a>> = Vec::with_capacity(10);
1489 
1490         let mut params: Vec<Type<'a>> = Vec::new();
1491 
1492         while !self.remaining.starts_with(b"@")
1493             && !self.remaining.starts_with(b"Z")
1494             && !self.remaining.is_empty()
1495         {
1496             if let Some(n) = self.read_digit() {
1497                 if n as usize >= self.memorized_types.len() {
1498                     return Err(self.fail_args(format_args!("invalid backreference: {}", n)));
1499                 }
1500                 // println!("reading a type from memorized_types[{}]. full list: {:#?}", n, self.memorized_types);
1501                 params.push(self.memorized_types[n as usize].clone());
1502                 continue;
1503             }
1504 
1505             let len = self.remaining.len();
1506 
1507             let param_type = self.read_var_type(StorageClass::empty())?;
1508 
1509             // Single-letter types are ignored for backreferences because
1510             // memorizing them doesn't save anything.
1511             if len - self.remaining.len() > 1 {
1512                 self.memorize_type(&param_type);
1513             }
1514             params.push(param_type);
1515         }
1516 
1517         if self.consume(b"Z") {
1518             params.push(Type::VarArgs);
1519         } else if self.remaining.is_empty() {
1520             // this is needed to handle the weird standalone template manglings
1521         } else {
1522             self.expect(b"@")?;
1523         }
1524         Ok(Params { types: params })
1525     }
1526 
1527     // Reads a function parameters.
read_func_params(&mut self) -> Result<Params<'a>>1528     fn read_func_params(&mut self) -> Result<Params<'a>> {
1529         let params = if self.consume(b"X") {
1530             Params {
1531                 types: vec![Type::Void(StorageClass::empty())],
1532             }
1533         } else {
1534             self.read_params()?
1535         };
1536 
1537         self.expect(b"Z")?;
1538 
1539         Ok(params)
1540     }
1541 }
1542 
demangle(input: &str, flags: DemangleFlags) -> Result<String>1543 pub fn demangle(input: &str, flags: DemangleFlags) -> Result<String> {
1544     serialize(&parse(input)?, flags)
1545 }
1546 
parse(input: &str) -> Result<ParseResult>1547 pub fn parse(input: &str) -> Result<ParseResult> {
1548     let mut state = ParserState {
1549         remaining: input.as_bytes(),
1550         input,
1551         offset: 0,
1552         memorized_names: Vec::with_capacity(10),
1553         memorized_types: Vec::with_capacity(10),
1554     };
1555     state.parse()
1556 }
1557 
serialize(input: &ParseResult, flags: DemangleFlags) -> Result<String>1558 pub fn serialize(input: &ParseResult, flags: DemangleFlags) -> Result<String> {
1559     let mut s = Vec::new();
1560     {
1561         let mut serializer = Serializer { flags, w: &mut s };
1562         serializer.serialize(&input)?;
1563     }
1564     Ok(String::from_utf8(s)?)
1565 }
1566 
1567 // Converts an AST to a string.
1568 //
1569 // Converting an AST representing a C++ type to a string is tricky due
1570 // to the bad grammar of the C++ declaration inherited from C. You have
1571 // to construct a string from inside to outside. For example, if a type
1572 // X is a pointer to a function returning int, the order you create a
1573 // string becomes something like this:
1574 //
1575 //   (1) X is a pointer: *X
1576 //   (2) (1) is a function returning int: int (*X)()
1577 //
1578 // So you cannot construct a result just by appending strings to a result.
1579 //
1580 // To deal with this, we split the function into two. write_pre() writes
1581 // the "first half" of type declaration, and write_post() writes the
1582 // "second half". For example, write_pre() writes a return type for a
1583 // function and write_post() writes an parameter list.
1584 struct Serializer<'a> {
1585     flags: DemangleFlags,
1586     w: &'a mut Vec<u8>,
1587 }
1588 
1589 impl<'a> Serializer<'a> {
serialize(&mut self, parse_result: &ParseResult) -> Result<()>1590     fn serialize(&mut self, parse_result: &ParseResult) -> Result<()> {
1591         if !self
1592             .flags
1593             .intersects(DemangleFlags::NAME_ONLY | DemangleFlags::NO_FUNCTION_RETURNS)
1594         {
1595             self.write_pre(&parse_result.symbol_type)?;
1596         }
1597         self.write_name(&parse_result.symbol, Some(&parse_result.symbol_type))?;
1598         if !self.flags.contains(DemangleFlags::NAME_ONLY) {
1599             self.write_post(&parse_result.symbol_type)?;
1600         }
1601         Ok(())
1602     }
1603 
write_calling_conv(&mut self, calling_conv: CallingConv) -> Result<()>1604     fn write_calling_conv(&mut self, calling_conv: CallingConv) -> Result<()> {
1605         match self.w.last() {
1606             Some(b' ') | Some(b'(') => {}
1607             _ => write!(self.w, " ")?,
1608         }
1609         if !self.flags.contains(DemangleFlags::NO_MS_KEYWORDS) {
1610             match calling_conv {
1611                 CallingConv::Cdecl => {
1612                     write!(self.w, "__cdecl ")?;
1613                 }
1614                 CallingConv::Pascal => {
1615                     write!(self.w, "__pascal ")?;
1616                 }
1617                 CallingConv::Thiscall => {
1618                     write!(self.w, "__thiscall ")?;
1619                 }
1620                 CallingConv::Stdcall => {
1621                     write!(self.w, "__stdcall ")?;
1622                 }
1623                 CallingConv::Fastcall => {
1624                     write!(self.w, "__fastcall ")?;
1625                 }
1626                 CallingConv::_Regcall => {
1627                     write!(self.w, "__regcall ")?;
1628                 }
1629             };
1630         }
1631 
1632         Ok(())
1633     }
1634 
1635     // Write the "first half" of a given type.
write_pre(&mut self, t: &Type) -> Result<()>1636     fn write_pre(&mut self, t: &Type) -> Result<()> {
1637         let storage_class = match *t {
1638             Type::None => return Ok(()),
1639             Type::MemberFunction(func_class, calling_conv, _, _, ref inner) => {
1640                 if func_class.contains(FuncClass::THUNK) {
1641                     write!(self.w, "[thunk]: ")?
1642                 }
1643                 if !self.flags.contains(DemangleFlags::NO_ACCESS_SPECIFIERS) {
1644                     if func_class.contains(FuncClass::PRIVATE) {
1645                         write!(self.w, "private: ")?
1646                     }
1647                     if func_class.contains(FuncClass::PROTECTED) {
1648                         write!(self.w, "protected: ")?
1649                     }
1650                     if func_class.contains(FuncClass::PUBLIC) {
1651                         write!(self.w, "public: ")?
1652                     }
1653                 }
1654                 if !self.flags.contains(DemangleFlags::NO_MEMBER_TYPE) {
1655                     if func_class.contains(FuncClass::STATIC) {
1656                         write!(self.w, "static ")?
1657                     }
1658                     if func_class.contains(FuncClass::VIRTUAL) {
1659                         write!(self.w, "virtual ")?;
1660                     }
1661                 }
1662                 self.write_pre(inner)?;
1663                 self.write_calling_conv(calling_conv)?;
1664                 return Ok(());
1665             }
1666             Type::MemberFunctionPointer(ref symbol, _, calling_conv, _, _, ref inner) => {
1667                 self.write_pre(inner)?;
1668                 self.write_space()?;
1669                 write!(self.w, "(")?;
1670                 self.write_calling_conv(calling_conv)?;
1671                 self.write_space()?;
1672                 self.write_space()?;
1673                 self.write_name(symbol, None)?;
1674                 write!(self.w, "::*")?;
1675                 return Ok(());
1676             }
1677             Type::NonMemberFunction(calling_conv, _, _, ref inner) => {
1678                 self.write_pre(inner)?;
1679                 self.write_calling_conv(calling_conv)?;
1680                 return Ok(());
1681             }
1682             Type::VCallThunk(_, calling_conv) => {
1683                 write!(self.w, "[thunk]: ")?;
1684                 self.write_calling_conv(calling_conv)?;
1685                 return Ok(());
1686             }
1687             Type::CXXVBTable(_, sc) => sc,
1688             Type::CXXVFTable(_, sc) => sc,
1689             Type::TemplateParameterWithIndex(n) => {
1690                 write!(self.w, "`template-parameter{}'", n)?;
1691                 return Ok(());
1692             }
1693             Type::ThreadSafeStaticGuard(num) => {
1694                 write!(self.w, "TSS{}", num)?;
1695                 return Ok(());
1696             }
1697             Type::Constant(n) => {
1698                 write!(self.w, "{}", n)?;
1699                 return Ok(());
1700             }
1701             Type::ConstantString(_) => {
1702                 // We have no idea what the original encoding of the string is,
1703                 // and undname doesn't even try to display anything.
1704                 //match str::from_utf8(s).ok() {
1705                 //  Some(ref s) => write!(self.w, "{}", s)?,
1706                 //  None => {},
1707                 //}
1708                 return Ok(());
1709             }
1710             Type::VarArgs => {
1711                 write!(self.w, "...")?;
1712                 return Ok(());
1713             }
1714             Type::Ptr(ref inner, storage_class)
1715             | Type::Ref(ref inner, storage_class)
1716             | Type::RValueRef(ref inner, storage_class) => {
1717                 // "[]" and "()" (for function parameters) take precedence over "*",
1718                 // so "int *x(int)" means "x is a function returning int *". We need
1719                 // parentheses to supercede the default precedence. (e.g. we want to
1720                 // emit something like "int (*x)(int)".)
1721                 match *inner.as_ref() {
1722                     Type::MemberFunction(_, calling_conv, _, _, ref inner)
1723                     | Type::NonMemberFunction(calling_conv, _, _, ref inner) => {
1724                         self.write_pre(inner)?;
1725                         self.write_space()?;
1726                         write!(self.w, "(")?;
1727                         self.write_calling_conv(calling_conv)?;
1728                     }
1729                     Type::Array(_, _, _) => {
1730                         self.write_pre(inner)?;
1731                         self.write_space()?;
1732                         write!(self.w, "(")?;
1733                     }
1734                     _ => {
1735                         self.write_pre(inner)?;
1736                     }
1737                 }
1738 
1739                 match *t {
1740                     Type::Ptr(_, _) => {
1741                         if !self.flags.contains(DemangleFlags::HUG_TYPE) {
1742                             self.write_space()?;
1743                         } else if self.flags.contains(DemangleFlags::SPACE_BEFORE_POINTER) {
1744                             self.write_space_ptr()?;
1745                         }
1746                         write!(self.w, "*")?
1747                     }
1748                     Type::Ref(_, _) => {
1749                         if !self.flags.contains(DemangleFlags::HUG_TYPE) {
1750                             self.write_space()?;
1751                         } else if self.flags.contains(DemangleFlags::SPACE_BEFORE_POINTER) {
1752                             self.write_space_ptr()?;
1753                         }
1754                         write!(self.w, "&")?
1755                     }
1756                     Type::RValueRef(_, _) => {
1757                         if !self.flags.contains(DemangleFlags::HUG_TYPE) {
1758                             self.write_space()?;
1759                         } else if self.flags.contains(DemangleFlags::SPACE_BEFORE_POINTER) {
1760                             self.write_space_ptr()?;
1761                         }
1762                         write!(self.w, "&&")?
1763                     }
1764                     _ => {}
1765                 }
1766 
1767                 storage_class
1768             }
1769             Type::Array(_len, ref inner, storage_class) => {
1770                 self.write_pre(inner)?;
1771                 storage_class
1772             }
1773             Type::Var(ref inner, kind, sc) => {
1774                 match kind {
1775                     VarStorageKind::PrivateStatic => write!(self.w, "private: static ")?,
1776                     VarStorageKind::ProtectedStatic => write!(self.w, "protected: static ")?,
1777                     VarStorageKind::PublicStatic => write!(self.w, "public: static ")?,
1778                     VarStorageKind::Global | VarStorageKind::FunctionLocalStatic => {}
1779                 }
1780                 self.write_pre(inner)?;
1781                 sc
1782             }
1783             Type::Alias(ref names, sc) => {
1784                 self.write_name(names, None)?;
1785                 sc
1786             }
1787             Type::Struct(ref names, sc) => {
1788                 self.write_class(names, "struct")?;
1789                 sc
1790             }
1791             Type::Union(ref names, sc) => {
1792                 self.write_class(names, "union")?;
1793                 sc
1794             }
1795             Type::Class(ref names, sc) => {
1796                 self.write_class(names, "class")?;
1797                 sc
1798             }
1799             Type::Enum(ref names, sc) => {
1800                 self.write_class(names, "enum")?;
1801                 sc
1802             }
1803             Type::Void(sc) => {
1804                 write!(self.w, "void")?;
1805                 sc
1806             }
1807             Type::Bool(sc) => {
1808                 write!(self.w, "bool")?;
1809                 sc
1810             }
1811             Type::Char(sc) => {
1812                 write!(self.w, "char")?;
1813                 sc
1814             }
1815             Type::Schar(sc) => {
1816                 write!(self.w, "signed char")?;
1817                 sc
1818             }
1819             Type::Uchar(sc) => {
1820                 write!(self.w, "unsigned char")?;
1821                 sc
1822             }
1823             Type::Short(sc) => {
1824                 write!(self.w, "short")?;
1825                 sc
1826             }
1827             Type::Ushort(sc) => {
1828                 write!(self.w, "unsigned short")?;
1829                 sc
1830             }
1831             Type::Int(sc) => {
1832                 write!(self.w, "int")?;
1833                 sc
1834             }
1835             Type::Uint(sc) => {
1836                 write!(self.w, "unsigned int")?;
1837                 sc
1838             }
1839             Type::Long(sc) => {
1840                 write!(self.w, "long")?;
1841                 sc
1842             }
1843             Type::Ulong(sc) => {
1844                 write!(self.w, "unsigned long")?;
1845                 sc
1846             }
1847             Type::Int64(sc) => {
1848                 if self.flags.contains(DemangleFlags::MS_TYPENAMES) {
1849                     write!(self.w, "__int64")?;
1850                 } else {
1851                     write!(self.w, "int64_t")?;
1852                 }
1853                 sc
1854             }
1855             Type::Uint64(sc) => {
1856                 if self.flags.contains(DemangleFlags::MS_TYPENAMES) {
1857                     write!(self.w, "unsigned __int64")?;
1858                 } else {
1859                     write!(self.w, "uint64_t")?;
1860                 }
1861                 sc
1862             }
1863             Type::Int128(sc) => {
1864                 if self.flags.contains(DemangleFlags::MS_TYPENAMES) {
1865                     write!(self.w, "__int128")?;
1866                 } else {
1867                     write!(self.w, "int128_t")?;
1868                 }
1869                 sc
1870             }
1871             Type::Uint128(sc) => {
1872                 if self.flags.contains(DemangleFlags::MS_TYPENAMES) {
1873                     write!(self.w, "unsigned __int128")?;
1874                 } else {
1875                     write!(self.w, "uint128_t")?;
1876                 }
1877                 sc
1878             }
1879             Type::Wchar(sc) => {
1880                 write!(self.w, "wchar_t")?;
1881                 sc
1882             }
1883             Type::Float(sc) => {
1884                 write!(self.w, "float")?;
1885                 sc
1886             }
1887             Type::Double(sc) => {
1888                 write!(self.w, "double")?;
1889                 sc
1890             }
1891             Type::Ldouble(sc) => {
1892                 write!(self.w, "long double")?;
1893                 sc
1894             }
1895             Type::Char8(sc) => {
1896                 write!(self.w, "char8_t")?;
1897                 sc
1898             }
1899             Type::Char16(sc) => {
1900                 write!(self.w, "char16_t")?;
1901                 sc
1902             }
1903             Type::Char32(sc) => {
1904                 write!(self.w, "char32_t")?;
1905                 sc
1906             }
1907             Type::Nullptr => {
1908                 write!(self.w, "std::nullptr_t")?;
1909                 return Ok(());
1910             }
1911             Type::EmptyParameterPack => return Ok(()),
1912             Type::RTTIType => return Ok(()),
1913         };
1914 
1915         if storage_class.contains(StorageClass::CONST) {
1916             if self.flags.contains(DemangleFlags::SPACE_BEFORE_POINTER) {
1917                 self.write_space_ptr()?;
1918             } else {
1919                 self.write_space()?;
1920             }
1921             write!(self.w, "const")?;
1922         }
1923         if storage_class.contains(StorageClass::VOLATILE) {
1924             if self.flags.contains(DemangleFlags::SPACE_BEFORE_POINTER) {
1925                 self.write_space_ptr()?;
1926             } else {
1927                 self.write_space()?;
1928             }
1929             write!(self.w, "volatile")?;
1930         }
1931 
1932         Ok(())
1933     }
1934 
write_memfn_qualifiers(&mut self, sc: StorageClass) -> Result<()>1935     fn write_memfn_qualifiers(&mut self, sc: StorageClass) -> Result<()> {
1936         let with_ptr64 = self.flags.contains(DemangleFlags::WITH_PTR64);
1937         if self.flags.contains(DemangleFlags::NO_THISTYPE) {
1938             // TODO: should probably check for NO_CV_THISTYPE and NO_MS_THISTYPE
1939             // separately but I don't know what exactly those affect.
1940             return Ok(());
1941         }
1942         let mut write_one_qual = |flag, s| -> Result<()> {
1943             if sc.contains(flag) {
1944                 self.write_space()?;
1945                 self.w.write_all(s)?;
1946             }
1947 
1948             Ok(())
1949         };
1950 
1951         write_one_qual(StorageClass::CONST, b"const")?;
1952         write_one_qual(StorageClass::VOLATILE, b"volatile")?;
1953         if with_ptr64 {
1954             write_one_qual(StorageClass::PTR64, b"__ptr64")?;
1955         }
1956         // __restrict is different than `restrict`, keep the underscores!
1957         write_one_qual(StorageClass::RESTRICT, b"__restrict")?;
1958         // TODO: undname prints ref-qualifiers tightly to previous qualifiers.
1959         write_one_qual(StorageClass::LVALUE_QUAL, b"&")?;
1960         write_one_qual(StorageClass::RVALUE_QUAL, b"&&")?;
1961 
1962         Ok(())
1963     }
1964 
1965     // Write the "second half" of a given type.
write_post(&mut self, t: &Type) -> Result<()>1966     fn write_post(&mut self, t: &Type) -> Result<()> {
1967         match *t {
1968             Type::MemberFunction(_, _, ref params, sc, ref return_type)
1969             | Type::NonMemberFunction(_, ref params, sc, ref return_type) => {
1970                 write!(self.w, "(")?;
1971                 self.write_types(&params.types)?;
1972                 write!(self.w, ")")?;
1973 
1974                 self.write_memfn_qualifiers(sc)?;
1975                 self.write_post(return_type)?;
1976             }
1977             Type::MemberFunctionPointer(_, _, _, ref params, sc, ref return_type) => {
1978                 write!(self.w, ")(")?;
1979                 self.write_types(&params.types)?;
1980                 write!(self.w, ")")?;
1981 
1982                 self.write_post(return_type)?;
1983 
1984                 if sc.contains(StorageClass::CONST) {
1985                     self.write_space()?;
1986                     write!(self.w, "const")?;
1987                 }
1988             }
1989             Type::CXXVBTable(ref names, _sc) => {
1990                 self.write_scope(names)?;
1991                 write!(self.w, "\'}}")?; // the rest of the "operator"
1992             }
1993             Type::Ptr(ref inner, _sc) | Type::Ref(ref inner, _sc) => {
1994                 match *inner.as_ref() {
1995                     Type::MemberFunction(_, _, _, _, _)
1996                     | Type::NonMemberFunction(_, _, _, _)
1997                     | Type::Array(_, _, _) => {
1998                         write!(self.w, ")")?;
1999                     }
2000                     _ => {}
2001                 }
2002                 self.write_post(inner)?;
2003             }
2004             Type::Array(len, ref inner, _sc) => {
2005                 write!(self.w, "[{}]", len)?;
2006                 self.write_post(inner)?;
2007             }
2008             Type::Var(ref inner, _kind, _sc) => {
2009                 self.write_post(inner)?;
2010             }
2011             Type::CXXVFTable(ref names, _) => {
2012                 if !names.names.is_empty() {
2013                     write!(self.w, "{{for `")?;
2014                     self.write_scope(names)?;
2015                     self.w.write_all(b"'}")?;
2016                 }
2017             }
2018             Type::VCallThunk(offset, _) => {
2019                 write!(self.w, "{{{},", offset)?;
2020                 if self.flags.contains(DemangleFlags::SPACE_AFTER_COMMA) {
2021                     write!(self.w, " ")?;
2022                 }
2023                 write!(self.w, "{{flat}}}}")?;
2024             }
2025             _ => {}
2026         }
2027         Ok(())
2028     }
2029 
2030     // Write a function or template parameter list.
write_types(&mut self, types: &[Type]) -> Result<()>2031     fn write_types(&mut self, types: &[Type]) -> Result<()> {
2032         for (idx, param) in types
2033             .iter()
2034             .filter(|x| **x != Type::EmptyParameterPack)
2035             .enumerate()
2036         {
2037             if idx > 0 {
2038                 write!(self.w, ",")?;
2039                 if self.flags.contains(DemangleFlags::SPACE_AFTER_COMMA) {
2040                     write!(self.w, " ")?;
2041                 }
2042             }
2043             self.write_pre(param)?;
2044             self.write_post(param)?;
2045         }
2046         Ok(())
2047     }
2048 
write_class(&mut self, names: &Symbol, s: &str) -> Result<()>2049     fn write_class(&mut self, names: &Symbol, s: &str) -> Result<()> {
2050         if !self.flags.contains(DemangleFlags::NO_CLASS_TYPE) {
2051             write!(self.w, "{}", s)?;
2052             write!(self.w, " ")?;
2053         }
2054         self.write_name(names, None)?;
2055         Ok(())
2056     }
2057 
write_space_pre(&mut self) -> Result<()>2058     fn write_space_pre(&mut self) -> Result<()> {
2059         if let Some(&c) = self.w.last() {
2060             if char::from(c).is_ascii_alphabetic() || c == b'&' || c == b'>' || c == b')' {
2061                 write!(self.w, " ")?;
2062             }
2063         }
2064         Ok(())
2065     }
2066 
write_space_ptr(&mut self) -> Result<()>2067     fn write_space_ptr(&mut self) -> Result<()> {
2068         if let Some(&c) = self.w.last() {
2069             if char::from(c).is_ascii_alphabetic() || c == b'>' || c == b')' {
2070                 write!(self.w, " ")?;
2071             }
2072         }
2073         Ok(())
2074     }
2075 
write_space(&mut self) -> Result<()>2076     fn write_space(&mut self) -> Result<()> {
2077         if let Some(&c) = self.w.last() {
2078             if char::from(c).is_ascii_alphabetic()
2079                 || c == b'*'
2080                 || c == b'&'
2081                 || c == b'>'
2082                 || c == b')'
2083             {
2084                 write!(self.w, " ")?;
2085             }
2086         }
2087         Ok(())
2088     }
2089 
write_operator_name(&mut self, op: &Operator) -> Result<()>2090     fn write_operator_name(&mut self, op: &Operator) -> Result<()> {
2091         let s = match *op {
2092             Operator::Ctor => "ctor",
2093             Operator::Dtor => "dtor",
2094             Operator::New => "operator new",
2095             Operator::Delete => "operator delete",
2096             Operator::Equal => "operator=",
2097             Operator::RShift => "operator>>",
2098             Operator::LShift => "operator<<",
2099             Operator::Bang => "operator!",
2100             Operator::EqualEqual => "operator==",
2101             Operator::BangEqual => "operator!=",
2102             Operator::Subscript => "operator[]",
2103 
2104             // this is special cased for most situations unless demangling
2105             // produced something really wacky
2106             Operator::Conversion => "operatorcast",
2107             Operator::Arrow => "operator->",
2108             Operator::Star => "operator*",
2109             Operator::PlusPlus => "operator++",
2110             Operator::MinusMinus => "operator--",
2111             Operator::Minus => "operator-",
2112             Operator::Plus => "operator+",
2113             Operator::Amp => "operator&",
2114             Operator::ArrowStar => "operator->*",
2115             Operator::Slash => "operator/",
2116             Operator::Percent => "operator%",
2117             Operator::Less => "operator<",
2118             Operator::LessEqual => "operator<=",
2119             Operator::Greater => "operator>",
2120             Operator::GreaterEqual => "operator>=",
2121             Operator::Comma => "operator,",
2122             Operator::Call => "operator()",
2123             Operator::Tilde => "operator~",
2124             Operator::Caret => "operator^",
2125             Operator::Pipe => "operator|",
2126             Operator::AmpAmp => "operator&&",
2127             Operator::PipePipe => "operator||",
2128             Operator::StarEqual => "operator*=",
2129             Operator::PlusEqual => "operator+=",
2130             Operator::MinusEqual => "operator-=",
2131             Operator::SlashEqual => "operator/=",
2132             Operator::PercentEqual => "operator%=",
2133             Operator::GreaterGreaterEqual => "operator>>=",
2134             Operator::LessLessEqual => "operator<<=",
2135             Operator::AmpEqual => "operator&=",
2136             Operator::PipeEqual => "operator|=",
2137             Operator::CaretEqual => "operator^=",
2138 
2139             Operator::VFTable => "`vftable'",
2140             Operator::VBTable => "`vbtable'",
2141             Operator::VCall => "`vcall'",
2142             Operator::Typeof => "`typeof'",
2143             Operator::LocalStaticGuard(scope) => {
2144                 write!(self.w, "`local static guard'")?;
2145                 if let Some(scope) = scope {
2146                     write!(self.w, "{{{}}}", scope)?;
2147                 }
2148                 return Ok(());
2149             }
2150             Operator::String => "`string'",
2151             Operator::VBaseDtor => "`vbase destructor'",
2152             Operator::VectorDeletingDtor => "`vector deleting destructor'",
2153             Operator::DefaultCtorClosure => "`default constructor closure'",
2154             Operator::ScalarDeletingDtor => "`scalar deleting destructor'",
2155             Operator::VectorCtorIterator => "`vector constructor iterator'",
2156             Operator::VectorDtorIterator => "`vector destructor iterator'",
2157             Operator::VectorVBaseCtorIterator => "`vector vbase constructor iterator'",
2158             Operator::VirtualDisplacementMap => "`virtual displacement map'",
2159             Operator::EHVectorCtorIterator => "`eh vector constructor iterator'",
2160             Operator::EHVectorDtorIterator => "`eh vector destructor iterator'",
2161             Operator::EHVectorVBaseCtorIterator => "`eh vector vbase constructor iterator'",
2162             Operator::CopyCtorClosure => "`copy constructor closure'",
2163 
2164             Operator::LocalVFTable => "`local vftable'",
2165             Operator::LocalVFTableCtorClosure => "`local vftable constructor closure'",
2166             Operator::ArrayNew => "operator new[]",
2167             Operator::ArrayDelete => "operator delete[]",
2168             Operator::PlacementDeleteClosure => "`placement delete closure'",
2169             Operator::PlacementArrayDeleteClosure => "`placement delete[] closure'",
2170 
2171             Operator::CoroutineAwait => " co_await",
2172             Operator::LiteralOperatorName => "operator \"\"",
2173 
2174             Operator::RTTITypeDescriptor(_, ref inner) => {
2175                 self.write_pre(inner)?;
2176                 // XXX(mitsuhiko): llvm uses a space here instead of `::`.  No
2177                 // idea why, seems inconsistent
2178                 write!(self.w, "::`RTTI Type Descriptor'")?;
2179                 return Ok(());
2180             }
2181             Operator::RTTIBaseClassDescriptor(nv_offset, vbptr_offset, vbtable_offset, flags) => {
2182                 let sp = if self.flags.contains(DemangleFlags::SPACE_AFTER_COMMA) {
2183                     " "
2184                 } else {
2185                     ""
2186                 };
2187                 write!(
2188                     self.w,
2189                     "`RTTI Base Class Descriptor at ({},{}{},{}{},{}{})'",
2190                     nv_offset, sp, vbptr_offset, sp, vbtable_offset, sp, flags
2191                 )?;
2192                 return Ok(());
2193             }
2194             Operator::RTTIBaseClassArray => "`RTTI Base Class Array'",
2195             Operator::RTTIClassHierarchyDescriptor => "`RTTI Class Hierarchy Descriptor'",
2196             Operator::RTTIClassCompleteObjectLocator => "`RTTI Complete Object Locator'",
2197 
2198             Operator::DynamicInitializer => "`dynamic initializer'",
2199             Operator::DynamicAtexitDtor => "`dynamic atexit destructor'",
2200             Operator::LocalStaticThreadGuard(scope) => {
2201                 write!(self.w, "`local static thread guard'")?;
2202                 if let Some(scope) = scope {
2203                     write!(self.w, "{{{}}}", scope)?;
2204                 }
2205                 return Ok(());
2206             }
2207         };
2208         write!(self.w, "{}", s)?;
2209         Ok(())
2210     }
2211 
write_one_name(&mut self, name: &Name) -> Result<()>2212     fn write_one_name(&mut self, name: &Name) -> Result<()> {
2213         match *name {
2214             Name::Md5(ref name) => {
2215                 write!(self.w, "??@")?;
2216                 self.w.write_all(name)?;
2217                 write!(self.w, "@")?;
2218             }
2219             Name::Operator(ref op) => {
2220                 self.write_space()?;
2221                 self.write_operator_name(op)?;
2222             }
2223             Name::NonTemplate(ref name) => {
2224                 self.w.write_all(name)?;
2225             }
2226             Name::AsInterface(ref name) => {
2227                 write!(self.w, "[")?;
2228                 self.w.write_all(name)?;
2229                 write!(self.w, "]")?;
2230             }
2231             Name::Template(ref name, ref params) => {
2232                 self.write_one_name(name)?;
2233                 self.write_tmpl_params(&params)?;
2234             }
2235             Name::Discriminator(ref val) => {
2236                 write!(self.w, "`{}'", val)?;
2237             }
2238             Name::ParsedName(ref val) => {
2239                 write!(self.w, "`{}'", serialize(val, self.flags)?)?;
2240             }
2241             Name::AnonymousNamespace(_) => {
2242                 write!(self.w, "`anonymous namespace'")?;
2243             }
2244         }
2245         Ok(())
2246     }
2247 
write_scope(&mut self, names: &NameSequence) -> Result<()>2248     fn write_scope(&mut self, names: &NameSequence) -> Result<()> {
2249         // Print out namespaces or outer class names.
2250         let mut i = names.names.iter().rev();
2251         if let Some(name) = i.next() {
2252             self.write_one_name(&name)?;
2253         }
2254         for name in i {
2255             write!(self.w, "::")?;
2256             self.write_one_name(&name)?;
2257         }
2258         Ok(())
2259     }
2260 
2261     // Write a name read by read_name().
write_name(&mut self, names: &Symbol, ty: Option<&Type<'_>>) -> Result<()>2262     fn write_name(&mut self, names: &Symbol, ty: Option<&Type<'_>>) -> Result<()> {
2263         if !self.flags.contains(DemangleFlags::SPACE_BEFORE_POINTER) {
2264             self.write_space_pre()?;
2265         } else {
2266             self.write_space_ptr()?;
2267         }
2268 
2269         let mut was_literal_op = false;
2270         if let Name::Operator(Operator::LiteralOperatorName) = names.name {
2271             self.write_space()?;
2272             self.write_operator_name(&Operator::LiteralOperatorName)?;
2273             was_literal_op = true;
2274         }
2275 
2276         self.write_scope(&names.scope)?;
2277 
2278         if !names.scope.names.is_empty() && !was_literal_op {
2279             write!(self.w, "::")?;
2280         }
2281 
2282         match names.name {
2283             Name::Md5(ref name) => {
2284                 write!(self.w, "??@")?;
2285                 self.w.write_all(name)?;
2286                 write!(self.w, "@")?;
2287             }
2288             Name::Operator(ref op) => {
2289                 match *op {
2290                     Operator::Ctor => {
2291                         let prev = names.scope.names.get(0).ok_or_else(|| {
2292                             Error::new(
2293                                 "If there's a ctor, there should be another name in this sequence",
2294                             )
2295                         })?;
2296                         self.write_one_name(prev)?;
2297                     }
2298                     Operator::Dtor => {
2299                         let prev = names.scope.names.get(0).ok_or_else(|| {
2300                             Error::new(
2301                                 "If there's a dtor, there should be another name in this sequence",
2302                             )
2303                         })?;
2304                         write!(self.w, "~")?;
2305                         self.write_one_name(prev)?;
2306                     }
2307                     Operator::VBTable => {
2308                         write!(self.w, "`vbtable'{{for `")?;
2309                         // The rest will be written by write_post of the
2310                         // symbol type.
2311                     }
2312                     Operator::Conversion => {
2313                         if let Some(Type::MemberFunction(_, _, _, _, ref rv)) = ty {
2314                             write!(self.w, "operator ")?;
2315                             self.write_pre(rv)?;
2316                             self.write_post(rv)?;
2317                         } else {
2318                             self.write_space()?;
2319                             self.write_operator_name(op)?;
2320                         }
2321                     }
2322                     Operator::LiteralOperatorName => {}
2323                     _ => {
2324                         self.write_space()?;
2325                         // Print out an overloaded operator.
2326                         self.write_operator_name(op)?;
2327                     }
2328                 }
2329             }
2330             Name::NonTemplate(ref name) => {
2331                 self.w.write_all(name)?;
2332             }
2333             Name::AsInterface(ref name) => {
2334                 write!(self.w, "[")?;
2335                 self.w.write_all(name)?;
2336                 write!(self.w, "]")?;
2337             }
2338             Name::Template(ref name, ref params) => {
2339                 self.write_one_name(name)?;
2340                 self.write_tmpl_params(&params)?;
2341             }
2342             Name::Discriminator(ref val) => {
2343                 write!(self.w, "`{}'", val)?;
2344             }
2345             Name::ParsedName(ref val) => {
2346                 write!(self.w, "{}", serialize(val, self.flags)?)?;
2347             }
2348             Name::AnonymousNamespace(_) => {
2349                 // this should never happen as they are handled elsewhere
2350                 debug_assert!(false, "not supposed to be here");
2351             }
2352         }
2353         Ok(())
2354     }
2355 
write_tmpl_params<'b>(&mut self, params: &Params<'b>) -> Result<()>2356     fn write_tmpl_params<'b>(&mut self, params: &Params<'b>) -> Result<()> {
2357         write!(self.w, "<")?;
2358         if !params.types.is_empty() {
2359             self.write_types(&params.types)?;
2360             if let Some(&b'>') = self.w.last() {
2361                 write!(self.w, " ")?;
2362             }
2363         }
2364         write!(self.w, ">")?;
2365         Ok(())
2366     }
2367 }
2368 
2369 // grammar from MicrosoftMangle.cpp:
2370 
2371 // <mangled-name> ::= ? <name> <type-encoding>
2372 // <name> ::= <unscoped-name> {[<named-scope>]+ | [<nested-name>]}? @
2373 // <unqualified-name> ::= <operator-name>
2374 //                    ::= <ctor-dtor-name>
2375 //                    ::= <source-name>
2376 //                    ::= <template-name>
2377 // <operator-name> ::= ???
2378 //                 ::= ?B # cast, the target type is encoded as the return type.
2379 // <source-name> ::= <identifier> @
2380 //
2381 // mangleNestedName: calls into mangle, which is responsible for <mangled-name>, and into mangleUnqualifiedName
2382 // <postfix> ::= <unqualified-name> [<postfix>]
2383 //           ::= <substitution> [<postfix>]
2384 //
2385 // <template-name> ::= <unscoped-template-name> <template-args>
2386 //                 ::= <substitution>
2387 // <unscoped-template-name> ::= ?$ <unqualified-name>
2388 // <type-encoding> ::= <function-class> <function-type>
2389 //                 ::= <storage-class> <variable-type>
2390 // <function-class>  ::= <member-function> E? # E designates a 64-bit 'this'
2391 //                                            # pointer. in 64-bit mode *all*
2392 //                                            # 'this' pointers are 64-bit.
2393 //                   ::= <global-function>
2394 // <function-type> ::= <this-cvr-qualifiers> <calling-convention>
2395 //                     <return-type> <argument-list> <throw-spec>
2396 // <member-function> ::= A # private: near
2397 //                   ::= B # private: far
2398 //                   ::= C # private: static near
2399 //                   ::= D # private: static far
2400 //                   ::= E # private: near
2401 //                   ::= F # private: far
2402 //                   ::= I # near
2403 //                   ::= J # far
2404 //                   ::= K # static near
2405 //                   ::= L # static far
2406 //                   ::= M # near
2407 //                   ::= N # far
2408 //                   ::= Q # near
2409 //                   ::= R # far
2410 //                   ::= S # static near
2411 //                   ::= T # static far
2412 //                   ::= U # near
2413 //                   ::= V # far
2414 // <global-function> ::= Y # global near
2415 //                   ::= Z # global far
2416 // <storage-class> ::= 0  # private static member
2417 //                 ::= 1  # protected static member
2418 //                 ::= 2  # public static member
2419 //                 ::= 3  # global
2420 //                 ::= 4  # static local
2421