1 extern crate msvc_demangler;
2 
3 use msvc_demangler::{demangle, DemangleFlags};
4 
expect_with_flags(input: &str, reference: &str, flags: u32)5 fn expect_with_flags(input: &str, reference: &str, flags: u32) {
6     let demangled = demangle(input, ::DemangleFlags::from_bits(flags).unwrap());
7     let reference = reference.to_owned();
8     if let Ok(demangled) = demangled {
9         assert_eq!(demangled, reference);
10     } else {
11         panic!("{:?} != {:?}", demangled, Ok::<_, ()>(reference));
12     }
13 }
14 
15 // For cases where undname demangles differently/better than we do.
expect_failure(input: &str, reference: &str)16 fn expect_failure(input: &str, reference: &str) {
17     let demangled = demangle(input, ::DemangleFlags::COMPLETE).unwrap();
18     let reference = reference.to_owned();
19     assert_ne!(demangled, reference);
20 }
21 // std::basic_filebuf<char,struct std::char_traits<char> >::basic_filebuf<char,struct std::char_traits<char> >
22 // std::basic_filebuf<char,struct std::char_traits<char> >::"operator ctor"
23 // "operator ctor" = ?0
24 
25 #[test]
other_tests()26 fn other_tests() {
27     let expect = |input, reference| {
28         expect_with_flags(input, reference, 0x0);
29     };
30 
31     expect("?f@@YAHQBH@Z", "int __cdecl f(int const * const)");
32     expect("?f@@YA_WQB_W@Z", "wchar_t __cdecl f(wchar_t const * const)");
33     expect(
34         "?f@@YA_UQB_U@Z",
35         "char32_t __cdecl f(char32_t const * const)",
36     );
37     expect(
38         "?f@@YA_SQB_S@Z",
39         "char16_t __cdecl f(char16_t const * const)",
40     );
41     expect(
42         "?g@@YAHQAY0EA@$$CBH@Z",
43         "int __cdecl g(int const (* const)[64])",
44     );
45     expect(
46         "??0Klass@std@@AEAA@AEBV01@@Z",
47         "private: __cdecl std::Klass::Klass(class std::Klass const &)",
48     );
49     expect("??0?$Klass@V?$Mass@_N@@@std@@QEAA@AEBV01@@Z",
50             "public: __cdecl std::Klass<class Mass<bool> >::Klass<class Mass<bool> >(class std::Klass<class Mass<bool> > const &)");
51     expect(
52         "??$load@M@UnsharedOps@js@@SAMV?$SharedMem@PAM@@@Z",
53         "public: static float __cdecl js::UnsharedOps::load<float>(class SharedMem<float *>)",
54     );
55 
56     expect("?cached@?1??GetLong@BinaryPath@mozilla@@SA?AW4nsresult@@QA_W@Z@4_NA",
57             "bool `public: static enum nsresult __cdecl mozilla::BinaryPath::GetLong(wchar_t * const)\'::`2\'::cached");
58     expect(
59         "??0?$A@_K@B@@QAE@$$QAV01@@Z",
60         "public: __thiscall B::A<uint64_t>::A<uint64_t>(class B::A<uint64_t> &&)",
61     );
62     expect("??_7nsI@@6B@", "const nsI::`vftable\'");
63     expect("??_7W@?A@@6B@", "const `anonymous namespace'::W::`vftable'");
64     expect(
65         "??_7?$RunnableMethodImpl@PEAVLazyIdleThread@mozilla@@P812@EAAXXZ$0A@$0A@$$V@detail@mozilla@@6BnsIRunnable@@@",
66         "const mozilla::detail::RunnableMethodImpl<class mozilla::LazyIdleThread *,void (__cdecl mozilla::LazyIdleThread::*)(void),0,0>::`vftable\'{for `nsIRunnable\'}",
67     );
68     expect_failure(
69         "??_7?$RunnableMethodImpl@PEAVLazyIdleThread@mozilla@@P812@EAAXXZ$0A@$0A@$$V@detail@mozilla@@6BnsIRunnable@@@",
70         "const mozilla::detail::RunnableMethodImpl<class mozilla::LazyIdleThread * __ptr64,void (__cdecl mozilla::LazyIdleThread::*)(void) __ptr64,0,0>::`vftable\'{for `nsIRunnable\'}",
71     );
72     expect(
73         "??1?$ns@$$CBVtxXP@@@@QAE@XZ",
74         "public: __thiscall ns<class txXP const>::~ns<class txXP const>(void)",
75     );
76     /* XXX: undname prints void (__thiscall*)(void *) for the parameter type. */
77     expect(
78         "??_I@YGXPAXIIP6EX0@Z@Z",
79         "void __stdcall `vector destructor iterator'(void *,unsigned int,unsigned int,void (__thiscall *)(void *))",
80     );
81     expect(
82         "??_GnsWindowsShellService@@EAEPAXI@Z",
83         "private: virtual void * __thiscall nsWindowsShellService::`scalar deleting destructor'(unsigned int)",
84     );
85     expect(
86         "??1?$nsAutoPtr@$$CBVtxXPathNode@@@@QAE@XZ",
87         "public: __thiscall nsAutoPtr<class txXPathNode const>::~nsAutoPtr<class txXPathNode const>(void)",
88     );
89     expect(
90         "??_EPrintfTarget@mozilla@@MAEPAXI@Z",
91         "protected: virtual void * __thiscall mozilla::PrintfTarget::`vector deleting destructor'(unsigned int)",
92     );
93     expect(
94         "??_GDynamicFrameEventFilter@?A0xcdaa5fa8@@AAEPAXI@Z",
95         "private: void * __thiscall `anonymous namespace'::DynamicFrameEventFilter::`scalar deleting destructor\'(unsigned int)",
96     );
97     /* XXX: undname tacks on `adjustor{16}` to the name. */
98     expect(
99         "?Release@ContentSignatureVerifier@@WBA@AGKXZ",
100         "[thunk]: public: virtual unsigned long __stdcall ContentSignatureVerifier::Release(void)",
101     );
102     expect(
103         "??$new_@VWatchpointMap@js@@$$V@?$MallocProvider@UZone@JS@@@js@@QAEPAVWatchpointMap@1@XZ",
104         "public: class js::WatchpointMap * __thiscall js::MallocProvider<struct JS::Zone>::new_<class js::WatchpointMap>(void)",
105     );
106     expect(
107         "??$templ_fun_with_ty_pack@$$V@@YAXXZ",
108         "void __cdecl templ_fun_with_ty_pack<>(void)",
109     );
110     expect(
111         "??4?$RefPtr@VnsRange@@@@QAEAAV0@$$T@Z",
112         "public: class RefPtr<class nsRange> & __thiscall RefPtr<class nsRange>::operator=(std::nullptr_t)",
113     );
114     expect(
115         "??1?$function@$$A6AXXZ@std@@QAE@XZ",
116         "public: __thiscall std::function<void __cdecl (void)>::~function<void __cdecl (void)>(void)",
117     );
118     expect_failure(
119         "??1?$function@$$A6AXXZ@std@@QAE@XZ",
120         "public: __thiscall std::function<void __cdecl(void)>::~function<void __cdecl(void)>(void)",
121     );
122     expect(
123         "??B?$function@$$A6AXXZ@std@@QBE_NXZ",
124         "public: bool __thiscall std::function<void __cdecl (void)>::operator bool(void) const",
125     );
126     expect_failure(
127         "??B?$function@$$A6AXXZ@std@@QBE_NXZ",
128         "public: __thiscall std::function<void __cdecl(void)>::operator bool(void) const",
129     );
130     expect(
131         "??$?RA6AXXZ$$V@SkOnce@@QAEXA6AXXZ@Z",
132         "public: void __thiscall SkOnce::operator()<void (__cdecl &)(void)>(void (__cdecl &)(void))",
133     );
134     expect_failure(
135         "??$?RA6AXXZ$$V@SkOnce@@QAEXA6AXXZ@Z",
136         "public: void __thiscall SkOnce::operator()<void (__cdecl&)(void)>(void (__cdecl&)(void))",
137     );
138     expect(
139         "?foo@A@PR19361@@QIHAEXXZ",
140         "public: void __thiscall PR19361::A::foo(void) __restrict &&",
141     );
142     expect_failure(
143         "?foo@A@PR19361@@QIHAEXXZ",
144         "public: void __thiscall PR19361::A::foo(void) __restrict&& ",
145     );
146     expect(
147         "??$GenericCreateConstructor@$1?construct@SetObject@js@@CA_NPEAUJSContext@@IPEATValue@JS@@@Z$0A@$0A@$0A@@js@@YAPEAVJSObject@@PEAUJSContext@@W4JSProtoKey@@@Z",
148         "class JSObject * __cdecl js::GenericCreateConstructor<bool (__cdecl js::SetObject::construct::*)(struct JSContext *,unsigned int,union JS::Value *),0,0,0>(struct JSContext *,enum JSProtoKey)",
149     );
150     expect_failure(
151         "??$GenericCreateConstructor@$1?construct@SetObject@js@@CA_NPEAUJSContext@@IPEATValue@JS@@@Z$0A@$0A@$0A@@js@@YAPEAVJSObject@@PEAUJSContext@@W4JSProtoKey@@@Z",
152         "class JSObject * __ptr64 __cdecl js::GenericCreateConstructor<&private: static bool (__cdecl js::SetObject::construct::*)(struct JSContext * __ptr64,unsigned int,union JS::Value * __ptr64),0,0,0>(struct JSContext * __ptr64,enum JSProtoKey)",
153     );
154     expect(
155         "??$emplace_hint@AEBUpiecewise_construct_t@std@@V?$tuple@AEBH@2@V?$tuple@$$V@2@@?$_Tree@V?$_Tmap_traits@HUPayload@RtpUtility@webrtc@@U?$less@H@std@@V?$allocator@U?$pair@$$CBHUPayload@RtpUtility@webrtc@@@std@@@5@$0A@@std@@@std@@QEAA?AV?$_Tree_iterator@V?$_Tree_val@U?$_Tree_simple_types@U?$pair@$$CBHUPayload@RtpUtility@webrtc@@@std@@@std@@@std@@@1@V?$_Tree_const_iterator@V?$_Tree_val@U?$_Tree_simple_types@U?$pair@$$CBHUPayload@RtpUtility@webrtc@@@std@@@std@@@std@@@1@AEBUpiecewise_construct_t@1@$$QEAV?$tuple@AEBH@1@$$QEAV?$tuple@$$V@1@@Z",
156         "public: class std::_Tree_iterator<class std::_Tree_val<struct std::_Tree_simple_types<struct std::pair<int const,struct webrtc::RtpUtility::Payload> > > > __cdecl std::_Tree<class std::_Tmap_traits<int,struct webrtc::RtpUtility::Payload,struct std::less<int>,class std::allocator<struct std::pair<int const,struct webrtc::RtpUtility::Payload> >,0> >::emplace_hint<struct std::piecewise_construct_t const &,class std::tuple<int const &>,class std::tuple<> >(class std::_Tree_const_iterator<class std::_Tree_val<struct std::_Tree_simple_types<struct std::pair<int const,struct webrtc::RtpUtility::Payload> > > >,struct std::piecewise_construct_t const &,class std::tuple<int const &> &&,class std::tuple<> &&)",
157     );
158     expect(
159         "?_OptionsStorage@?1??__local_stdio_scanf_options@@9@9",
160         "`__local_stdio_scanf_options'::`2'::_OptionsStorage",
161     );
162     expect(
163         "??_9nsDocument@@$BDMI@AE",
164         "[thunk]: __thiscall nsDocument::`vcall'{968,{flat}}",
165     );
166     expect(
167         "??_R0?AUCollationCacheEntry@icu_61@@@8",
168         "struct icu_61::CollationCacheEntry::`RTTI Type Descriptor\'",
169     );
170     expect(
171         "??_R0?AV?$KxTree@V?$KxSpe@DI@@I@@@8",
172         "class KxTree<class KxSpe<char,unsigned int>,unsigned int>::`RTTI Type Descriptor'",
173     );
174     expect("??_R2A@@8", "A::`RTTI Base Class Array'");
175     expect("??_R3UO@i@@8", "i::UO::`RTTI Class Hierarchy Descriptor'");
176     expect(
177         "??_R1A@?0A@EA@U@i@@8",
178         "i::U::`RTTI Base Class Descriptor at (0,-1,0,64)'",
179     );
180     expect(
181         "?getFactory@SkImageShader@@UBEP6A?AV?$sk_sp@VSkFlattenable@@@@AAVSkReadBuffer@@@ZXZ",
182         "public: virtual class sk_sp<class SkFlattenable> (__cdecl * __thiscall SkImageShader::getFactory(void) const)(class SkReadBuffer &)"
183     );
184 
185     expect(
186         "?Present1@?QIDXGISwapChain4@@CDXGISwapChain@@UAGJIIPBUDXGI_PRESENT_PARAMETERS@@@Z",
187         "public: virtual long __stdcall CDXGISwapChain::[IDXGISwapChain4]::Present1(unsigned int,unsigned int,struct DXGI_PRESENT_PARAMETERS const *)");
188 
189     // An MD5 mangled name is "valid" but output as-is
190     expect(
191         "??@8ba8d245c9eca390356129098dbe9f73@",
192         "??@8ba8d245c9eca390356129098dbe9f73@",
193     );
194 }
195 
196 #[test]
test_strings()197 fn test_strings() {
198     let expect = |input, reference| {
199         expect_with_flags(input, reference, 0x0);
200     };
201 
202     // Test symbols extracted from clang's test/CodeGenCXX/mangle-ms-string-literals.cpp.
203     // Even though we don't print the encoded strings, these tests
204     // exhaustively cover all the cases we'll run into.
205 
206     // Single-byte characters.
207     expect("??_C@_01CNACBAHC@?$PP?$AA@", "`string'");
208     expect("??_C@_01DEBJCBDD@?$PO?$AA@", "`string'");
209     expect("??_C@_01BPDEHCPA@?$PN?$AA@", "`string'");
210     expect("??_C@_01GCPEDLB@?$PM?$AA@", "`string'");
211     expect("??_C@_01EJGONFHG@?$PL?$AA@", "`string'");
212     expect("??_C@_01FAHFOEDH@?z?$AA@", "`string'");
213     expect("??_C@_01HLFILHPE@?y?$AA@", "`string'");
214     expect("??_C@_01GCEDIGLF@?x?$AA@", "`string'");
215     expect("??_C@_01OFNLJKHK@?w?$AA@", "`string'");
216     expect("??_C@_01PMMAKLDL@?v?$AA@", "`string'");
217     expect("??_C@_01NHONPIPI@?u?$AA@", "`string'");
218     expect("??_C@_01MOPGMJLJ@?t?$AA@", "`string'");
219     expect("??_C@_01IBLHFPHO@?s?$AA@", "`string'");
220     expect("??_C@_01JIKMGODP@?r?$AA@", "`string'");
221     expect("??_C@_01LDIBDNPM@?q?$AA@", "`string'");
222     expect("??_C@_01KKJKAMLN@?p?$AA@", "`string'");
223     expect("??_C@_01GHMAACCD@?o?$AA@", "`string'");
224     expect("??_C@_01HONLDDGC@?n?$AA@", "`string'");
225     expect("??_C@_01FFPGGAKB@?m?$AA@", "`string'");
226     expect("??_C@_01EMONFBOA@?l?$AA@", "`string'");
227     expect("??_C@_01DKMMHCH@?k?$AA@", "`string'");
228     expect("??_C@_01BKLHPGGG@?j?$AA@", "`string'");
229     expect("??_C@_01DBJKKFKF@?i?$AA@", "`string'");
230     expect("??_C@_01CIIBJEOE@?h?$AA@", "`string'");
231     expect("??_C@_01KPBJIICL@?g?$AA@", "`string'");
232     expect("??_C@_01LGACLJGK@?f?$AA@", "`string'");
233     expect("??_C@_01JNCPOKKJ@?e?$AA@", "`string'");
234     expect("??_C@_01IEDENLOI@?d?$AA@", "`string'");
235     expect("??_C@_01MLHFENCP@?c?$AA@", "`string'");
236     expect("??_C@_01NCGOHMGO@?b?$AA@", "`string'");
237     expect("??_C@_01PJEDCPKN@?a?$AA@", "`string'");
238     expect("??_C@_01OAFIBOOM@?$OA?$AA@", "`string'");
239     expect("??_C@_01LIIGDENA@?$NP?$AA@", "`string'");
240     expect("??_C@_01KBJNAFJB@?$NO?$AA@", "`string'");
241     expect("??_C@_01IKLAFGFC@?$NN?$AA@", "`string'");
242     expect("??_C@_01JDKLGHBD@?$NM?$AA@", "`string'");
243     expect("??_C@_01NMOKPBNE@?$NL?$AA@", "`string'");
244     expect("??_C@_01MFPBMAJF@?Z?$AA@", "`string'");
245     expect("??_C@_01OONMJDFG@?Y?$AA@", "`string'");
246     expect("??_C@_01PHMHKCBH@?X?$AA@", "`string'");
247     expect("??_C@_01HAFPLONI@?W?$AA@", "`string'");
248     expect("??_C@_01GJEEIPJJ@?V?$AA@", "`string'");
249     expect("??_C@_01ECGJNMFK@?U?$AA@", "`string'");
250     expect("??_C@_01FLHCONBL@?T?$AA@", "`string'");
251     expect("??_C@_01BEDDHLNM@?S?$AA@", "`string'");
252     expect("??_C@_01NCIEKJN@?R?$AA@", "`string'");
253     expect("??_C@_01CGAFBJFO@?Q?$AA@", "`string'");
254     expect("??_C@_01DPBOCIBP@?P?$AA@", "`string'");
255     expect("??_C@_01PCEECGIB@?O?$AA@", "`string'");
256     expect("??_C@_01OLFPBHMA@?N?$AA@", "`string'");
257     expect("??_C@_01MAHCEEAD@?M?$AA@", "`string'");
258     expect("??_C@_01NJGJHFEC@?L?$AA@", "`string'");
259     expect("??_C@_01JGCIODIF@?K?$AA@", "`string'");
260     expect("??_C@_01IPDDNCME@?J?$AA@", "`string'");
261     expect("??_C@_01KEBOIBAH@?I?$AA@", "`string'");
262     expect("??_C@_01LNAFLAEG@?H?$AA@", "`string'");
263     expect("??_C@_01DKJNKMIJ@?G?$AA@", "`string'");
264     expect("??_C@_01CDIGJNMI@?F?$AA@", "`string'");
265     expect("??_C@_01IKLMOAL@?E?$AA@", "`string'");
266     expect("??_C@_01BBLAPPEK@?D?$AA@", "`string'");
267     expect("??_C@_01FOPBGJIN@?C?$AA@", "`string'");
268     expect("??_C@_01EHOKFIMM@?B?$AA@", "`string'");
269     expect("??_C@_01GMMHALAP@?A?$AA@", "`string'");
270     expect("??_C@_01HFNMDKEO@?$MA?$AA@", "`string'");
271     expect("??_C@_01NNHLFPHH@?$LP?$AA@", "`string'");
272     expect("??_C@_01MEGAGODG@?$LO?$AA@", "`string'");
273     expect("??_C@_01OPENDNPF@?$LN?$AA@", "`string'");
274     expect("??_C@_01PGFGAMLE@?$LM?$AA@", "`string'");
275     expect("??_C@_01LJBHJKHD@?$LL?$AA@", "`string'");
276     expect("??_C@_01KAAMKLDC@?$LK?$AA@", "`string'");
277     expect("??_C@_01ILCBPIPB@?$LJ?$AA@", "`string'");
278     expect("??_C@_01JCDKMJLA@?$LI?$AA@", "`string'");
279     expect("??_C@_01BFKCNFHP@?$LH?$AA@", "`string'");
280     expect("??_C@_01MLJOEDO@?$LG?$AA@", "`string'");
281     expect("??_C@_01CHJELHPN@?$LF?$AA@", "`string'");
282     expect("??_C@_01DOIPIGLM@?$LE?$AA@", "`string'");
283     expect("??_C@_01HBMOBAHL@?$LD?$AA@", "`string'");
284     expect("??_C@_01GINFCBDK@?$LC?$AA@", "`string'");
285     expect("??_C@_01EDPIHCPJ@?$LB?$AA@", "`string'");
286     expect("??_C@_01FKODEDLI@?$LA?$AA@", "`string'");
287     expect("??_C@_01JHLJENCG@?$KP?$AA@", "`string'");
288     expect("??_C@_01IOKCHMGH@?$KO?$AA@", "`string'");
289     expect("??_C@_01KFIPCPKE@?$KN?$AA@", "`string'");
290     expect("??_C@_01LMJEBOOF@?$KM?$AA@", "`string'");
291     expect("??_C@_01PDNFIICC@?$KL?$AA@", "`string'");
292     expect("??_C@_01OKMOLJGD@?$KK?$AA@", "`string'");
293     expect("??_C@_01MBODOKKA@?$KJ?$AA@", "`string'");
294     expect("??_C@_01NIPINLOB@?$KI?$AA@", "`string'");
295     expect("??_C@_01FPGAMHCO@?$KH?$AA@", "`string'");
296     expect("??_C@_01EGHLPGGP@?$KG?$AA@", "`string'");
297     expect("??_C@_01GNFGKFKM@?$KF?$AA@", "`string'");
298     expect("??_C@_01HEENJEON@?$KE?$AA@", "`string'");
299     expect("??_C@_01DLAMACCK@?$KD?$AA@", "`string'");
300     expect("??_C@_01CCBHDDGL@?$KC?$AA@", "`string'");
301     expect("??_C@_01JDKGAKI@?$KB?$AA@", "`string'");
302     expect("??_C@_01BACBFBOJ@?$KA?$AA@", "`string'");
303     expect("??_C@_01EIPPHLNF@?$JP?$AA@", "`string'");
304     expect("??_C@_01FBOEEKJE@?$JO?$AA@", "`string'");
305     expect("??_C@_01HKMJBJFH@?$JN?$AA@", "`string'");
306     expect("??_C@_01GDNCCIBG@?$JM?$AA@", "`string'");
307     expect("??_C@_01CMJDLONB@?$JL?$AA@", "`string'");
308     expect("??_C@_01DFIIIPJA@?$JK?$AA@", "`string'");
309     expect("??_C@_01BOKFNMFD@?$JJ?$AA@", "`string'");
310     expect("??_C@_01HLOONBC@?$JI?$AA@", "`string'");
311     expect("??_C@_01IACGPBNN@?$JH?$AA@", "`string'");
312     expect("??_C@_01JJDNMAJM@?$JG?$AA@", "`string'");
313     expect("??_C@_01LCBAJDFP@?$JF?$AA@", "`string'");
314     expect("??_C@_01KLALKCBO@?$JE?$AA@", "`string'");
315     expect("??_C@_01OEEKDENJ@?$JD?$AA@", "`string'");
316     expect("??_C@_01PNFBAFJI@?$JC?$AA@", "`string'");
317     expect("??_C@_01NGHMFGFL@?$JB?$AA@", "`string'");
318     expect("??_C@_01MPGHGHBK@?$JA?$AA@", "`string'");
319     expect("??_C@_01CDNGJIE@?$IP?$AA@", "`string'");
320     expect("??_C@_01BLCGFIMF@?$IO?$AA@", "`string'");
321     expect("??_C@_01DAALALAG@?$IN?$AA@", "`string'");
322     expect("??_C@_01CJBADKEH@?$IM?$AA@", "`string'");
323     expect("??_C@_01GGFBKMIA@?$IL?$AA@", "`string'");
324     expect("??_C@_01HPEKJNMB@?$IK?$AA@", "`string'");
325     expect("??_C@_01FEGHMOAC@?$IJ?$AA@", "`string'");
326     expect("??_C@_01ENHMPPED@?$II?$AA@", "`string'");
327     expect("??_C@_01MKOEODIM@?$IH?$AA@", "`string'");
328     expect("??_C@_01NDPPNCMN@?$IG?$AA@", "`string'");
329     expect("??_C@_01PINCIBAO@?$IF?$AA@", "`string'");
330     expect("??_C@_01OBMJLAEP@?$IE?$AA@", "`string'");
331     expect("??_C@_01KOIICGII@?$ID?$AA@", "`string'");
332     expect("??_C@_01LHJDBHMJ@?$IC?$AA@", "`string'");
333     expect("??_C@_01JMLOEEAK@?$IB?$AA@", "`string'");
334     expect("??_C@_01IFKFHFEL@?$IA?$AA@", "`string'");
335     expect("??_C@_01BGIBIIDJ@?$HP?$AA@", "`string'");
336     expect("??_C@_01PJKLJHI@?$HO?$AA@", "`string'");
337     expect("??_C@_01CELHOKLL@?$HN?$AA@", "`string'");
338     expect("??_C@_01DNKMNLPK@?$HM?$AA@", "`string'");
339     expect("??_C@_01HCONENDN@?$HL?$AA@", "`string'");
340     expect("??_C@_01GLPGHMHM@z?$AA@", "`string'");
341     expect("??_C@_01EANLCPLP@y?$AA@", "`string'");
342     expect("??_C@_01FJMABOPO@x?$AA@", "`string'");
343     expect("??_C@_01NOFIACDB@w?$AA@", "`string'");
344     expect("??_C@_01MHEDDDHA@v?$AA@", "`string'");
345     expect("??_C@_01OMGOGALD@u?$AA@", "`string'");
346     expect("??_C@_01PFHFFBPC@t?$AA@", "`string'");
347     expect("??_C@_01LKDEMHDF@s?$AA@", "`string'");
348     expect("??_C@_01KDCPPGHE@r?$AA@", "`string'");
349     expect("??_C@_01IIACKFLH@q?$AA@", "`string'");
350     expect("??_C@_01JBBJJEPG@p?$AA@", "`string'");
351     expect("??_C@_01FMEDJKGI@o?$AA@", "`string'");
352     expect("??_C@_01EFFIKLCJ@n?$AA@", "`string'");
353     expect("??_C@_01GOHFPIOK@m?$AA@", "`string'");
354     expect("??_C@_01HHGOMJKL@l?$AA@", "`string'");
355     expect("??_C@_01DICPFPGM@k?$AA@", "`string'");
356     expect("??_C@_01CBDEGOCN@j?$AA@", "`string'");
357     expect("??_C@_01KBJDNOO@i?$AA@", "`string'");
358     expect("??_C@_01BDACAMKP@h?$AA@", "`string'");
359     expect("??_C@_01JEJKBAGA@g?$AA@", "`string'");
360     expect("??_C@_01INIBCBCB@f?$AA@", "`string'");
361     expect("??_C@_01KGKMHCOC@e?$AA@", "`string'");
362     expect("??_C@_01LPLHEDKD@d?$AA@", "`string'");
363     expect("??_C@_01PAPGNFGE@c?$AA@", "`string'");
364     expect("??_C@_01OJONOECF@b?$AA@", "`string'");
365     expect("??_C@_01MCMALHOG@a?$AA@", "`string'");
366     expect("??_C@_01NLNLIGKH@?$GA?$AA@", "`string'");
367     expect("??_C@_01IDAFKMJL@_?$AA@", "`string'");
368     expect("??_C@_01JKBOJNNK@?$FO?$AA@", "`string'");
369     expect("??_C@_01LBDDMOBJ@?$FN?$AA@", "`string'");
370     expect("??_C@_01KICIPPFI@?2?$AA@", "`string'");
371     expect("??_C@_01OHGJGJJP@?$FL?$AA@", "`string'");
372     expect("??_C@_01POHCFINO@Z?$AA@", "`string'");
373     expect("??_C@_01NFFPALBN@Y?$AA@", "`string'");
374     expect("??_C@_01MMEEDKFM@X?$AA@", "`string'");
375     expect("??_C@_01ELNMCGJD@W?$AA@", "`string'");
376     expect("??_C@_01FCMHBHNC@V?$AA@", "`string'");
377     expect("??_C@_01HJOKEEBB@U?$AA@", "`string'");
378     expect("??_C@_01GAPBHFFA@T?$AA@", "`string'");
379     expect("??_C@_01CPLAODJH@S?$AA@", "`string'");
380     expect("??_C@_01DGKLNCNG@R?$AA@", "`string'");
381     expect("??_C@_01BNIGIBBF@Q?$AA@", "`string'");
382     expect("??_C@_01EJNLAFE@P?$AA@", "`string'");
383     expect("??_C@_01MJMHLOMK@O?$AA@", "`string'");
384     expect("??_C@_01NANMIPIL@N?$AA@", "`string'");
385     expect("??_C@_01PLPBNMEI@M?$AA@", "`string'");
386     expect("??_C@_01OCOKONAJ@L?$AA@", "`string'");
387     expect("??_C@_01KNKLHLMO@K?$AA@", "`string'");
388     expect("??_C@_01LELAEKIP@J?$AA@", "`string'");
389     expect("??_C@_01JPJNBJEM@I?$AA@", "`string'");
390     expect("??_C@_01IGIGCIAN@H?$AA@", "`string'");
391     expect("??_C@_01BBODEMC@G?$AA@", "`string'");
392     expect("??_C@_01BIAFAFID@F?$AA@", "`string'");
393     expect("??_C@_01DDCIFGEA@E?$AA@", "`string'");
394     expect("??_C@_01CKDDGHAB@D?$AA@", "`string'");
395     expect("??_C@_01GFHCPBMG@C?$AA@", "`string'");
396     expect("??_C@_01HMGJMAIH@B?$AA@", "`string'");
397     expect("??_C@_01FHEEJDEE@A?$AA@", "`string'");
398     expect("??_C@_01EOFPKCAF@?$EA?$AA@", "`string'");
399     expect("??_C@_01OGPIMHDM@?$DP?$AA@", "`string'");
400     expect("??_C@_01PPODPGHN@?$DO?$AA@", "`string'");
401     expect("??_C@_01NEMOKFLO@?$DN?$AA@", "`string'");
402     expect("??_C@_01MNNFJEPP@?$DM?$AA@", "`string'");
403     expect("??_C@_01ICJEACDI@?$DL?$AA@", "`string'");
404     expect("??_C@_01JLIPDDHJ@?3?$AA@", "`string'");
405     expect("??_C@_01LAKCGALK@9?$AA@", "`string'");
406     expect("??_C@_01KJLJFBPL@8?$AA@", "`string'");
407     expect("??_C@_01COCBENDE@7?$AA@", "`string'");
408     expect("??_C@_01DHDKHMHF@6?$AA@", "`string'");
409     expect("??_C@_01BMBHCPLG@5?$AA@", "`string'");
410     expect("??_C@_01FAMBOPH@4?$AA@", "`string'");
411     expect("??_C@_01EKENIIDA@3?$AA@", "`string'");
412     expect("??_C@_01FDFGLJHB@2?$AA@", "`string'");
413     expect("??_C@_01HIHLOKLC@1?$AA@", "`string'");
414     expect("??_C@_01GBGANLPD@0?$AA@", "`string'");
415     expect("??_C@_01KMDKNFGN@?1?$AA@", "`string'");
416     expect("??_C@_01LFCBOECM@?4?$AA@", "`string'");
417     expect("??_C@_01JOAMLHOP@?9?$AA@", "`string'");
418     expect("??_C@_01IHBHIGKO@?0?$AA@", "`string'");
419     expect("??_C@_01MIFGBAGJ@?$CL?$AA@", "`string'");
420     expect("??_C@_01NBENCBCI@?$CK?$AA@", "`string'");
421     expect("??_C@_01PKGAHCOL@?$CJ?$AA@", "`string'");
422     expect("??_C@_01ODHLEDKK@?$CI?$AA@", "`string'");
423     expect("??_C@_01GEODFPGF@?8?$AA@", "`string'");
424     expect("??_C@_01HNPIGOCE@?$CG?$AA@", "`string'");
425     expect("??_C@_01FGNFDNOH@?$CF?$AA@", "`string'");
426     expect("??_C@_01EPMOAMKG@$?$AA@", "`string'");
427     expect("??_C@_01IPJKGB@?$CD?$AA@", "`string'");
428     expect("??_C@_01BJJEKLCA@?$CC?$AA@", "`string'");
429     expect("??_C@_01DCLJPIOD@?$CB?$AA@", "`string'");
430     expect("??_C@_01CLKCMJKC@?5?$AA@", "`string'");
431     expect("??_C@_01HDHMODJO@?$BP?$AA@", "`string'");
432     expect("??_C@_01GKGHNCNP@?$BO?$AA@", "`string'");
433     expect("??_C@_01EBEKIBBM@?$BN?$AA@", "`string'");
434     expect("??_C@_01FIFBLAFN@?$BM?$AA@", "`string'");
435     expect("??_C@_01BHBACGJK@?$BL?$AA@", "`string'");
436     expect("??_C@_01OALBHNL@?$BK?$AA@", "`string'");
437     expect("??_C@_01CFCGEEBI@?$BJ?$AA@", "`string'");
438     expect("??_C@_01DMDNHFFJ@?$BI?$AA@", "`string'");
439     expect("??_C@_01LLKFGJJG@?$BH?$AA@", "`string'");
440     expect("??_C@_01KCLOFINH@?$BG?$AA@", "`string'");
441     expect("??_C@_01IJJDALBE@?$BF?$AA@", "`string'");
442     expect("??_C@_01JAIIDKFF@?$BE?$AA@", "`string'");
443     expect("??_C@_01NPMJKMJC@?$BD?$AA@", "`string'");
444     expect("??_C@_01MGNCJNND@?$BC?$AA@", "`string'");
445     expect("??_C@_01ONPPMOBA@?$BB?$AA@", "`string'");
446     expect("??_C@_01PEOEPPFB@?$BA?$AA@", "`string'");
447     expect("??_C@_01DJLOPBMP@?$AP?$AA@", "`string'");
448     expect("??_C@_01CAKFMAIO@?$AO?$AA@", "`string'");
449     expect("??_C@_01LIIJDEN@?$AN?$AA@", "`string'");
450     expect("??_C@_01BCJDKCAM@?$AM?$AA@", "`string'");
451     expect("??_C@_01FNNCDEML@?$AL?$AA@", "`string'");
452     expect("??_C@_01EEMJAFIK@?6?$AA@", "`string'");
453     expect("??_C@_01GPOEFGEJ@?7?$AA@", "`string'");
454     expect("??_C@_01HGPPGHAI@?$AI?$AA@", "`string'");
455     expect("??_C@_01PBGHHLMH@?$AH?$AA@", "`string'");
456     expect("??_C@_01OIHMEKIG@?$AG?$AA@", "`string'");
457     expect("??_C@_01MDFBBJEF@?$AF?$AA@", "`string'");
458     expect("??_C@_01NKEKCIAE@?$AE?$AA@", "`string'");
459     expect("??_C@_01JFALLOMD@?$AD?$AA@", "`string'");
460     expect("??_C@_01IMBAIPIC@?$AC?$AA@", "`string'");
461     expect("??_C@_01KHDNNMEB@?$AB?$AA@", "`string'");
462     expect("??_C@_01LOCGONAA@?$AA?$AA@", "`string'");
463 
464     // Wide characters.
465     expect("??_C@_13KDLDGPGJ@?$AA?7?$AA?$AA@", "`string'");
466     expect("??_C@_13LBAGMAIH@?$AA?6?$AA?$AA@", "`string'");
467     expect("??_C@_13JLKKHOC@?$AA?$AL?$AA?$AA@", "`string'");
468     expect("??_C@_13HOIJIPNN@?$AA?5?$AA?$AA@", "`string'");
469     expect("??_C@_13MGDFOILI@?$AA?$CB?$AA?$AA@", "`string'");
470     expect("??_C@_13NEIAEHFG@?$AA?$CC?$AA?$AA@", "`string'");
471     expect("??_C@_13GMDMCADD@?$AA?$CD?$AA?$AA@", "`string'");
472     expect("??_C@_13PBOLBIIK@?$AA$?$AA?$AA@", "`string'");
473     expect("??_C@_13EJFHHPOP@?$AA?$CF?$AA?$AA@", "`string'");
474     expect("??_C@_13FLOCNAAB@?$AA?$CG?$AA?$AA@", "`string'");
475     expect("??_C@_13ODFOLHGE@?$AA?8?$AA?$AA@", "`string'");
476     expect("??_C@_13LLDNKHDC@?$AA?$CI?$AA?$AA@", "`string'");
477     expect("??_C@_13DIBMAFH@?$AA?$CJ?$AA?$AA@", "`string'");
478     expect("??_C@_13BBDEGPLJ@?$AA?$CK?$AA?$AA@", "`string'");
479     expect("??_C@_13KJIIAINM@?$AA?$CL?$AA?$AA@", "`string'");
480     expect("??_C@_13DEFPDAGF@?$AA?0?$AA?$AA@", "`string'");
481     expect("??_C@_13IMODFHAA@?$AA?9?$AA?$AA@", "`string'");
482     expect("??_C@_13JOFGPIOO@?$AA?4?$AA?$AA@", "`string'");
483     expect("??_C@_13CGOKJPIL@?$AA?1?$AA?$AA@", "`string'");
484     expect("??_C@_13COJANIEC@?$AA0?$AA?$AA@", "`string'");
485     expect("??_C@_13JGCMLPCH@?$AA1?$AA?$AA@", "`string'");
486     expect("??_C@_13IEJJBAMJ@?$AA2?$AA?$AA@", "`string'");
487     expect("??_C@_13DMCFHHKM@?$AA3?$AA?$AA@", "`string'");
488     expect("??_C@_13KBPCEPBF@?$AA4?$AA?$AA@", "`string'");
489     expect("??_C@_13BJEOCIHA@?$AA5?$AA?$AA@", "`string'");
490     expect("??_C@_13LPLIHJO@?$AA6?$AA?$AA@", "`string'");
491     expect("??_C@_13LDEHOAPL@?$AA7?$AA?$AA@", "`string'");
492     expect("??_C@_13OLCEPAKN@?$AA8?$AA?$AA@", "`string'");
493     expect("??_C@_13FDJIJHMI@?$AA9?$AA?$AA@", "`string'");
494     expect("??_C@_13EBCNDICG@?$AA?3?$AA?$AA@", "`string'");
495     expect("??_C@_13PJJBFPED@?$AA?$DL?$AA?$AA@", "`string'");
496     expect("??_C@_13GEEGGHPK@?$AA?$DM?$AA?$AA@", "`string'");
497     expect("??_C@_13NMPKAAJP@?$AA?$DN?$AA?$AA@", "`string'");
498     expect("??_C@_13MOEPKPHB@?$AA?$DO?$AA?$AA@", "`string'");
499     expect("??_C@_13HGPDMIBE@?$AA?$DP?$AA?$AA@", "`string'");
500     expect("??_C@_13EFKPHINO@?$AA?$EA?$AA?$AA@", "`string'");
501     expect("??_C@_13PNBDBPLL@?$AAA?$AA?$AA@", "`string'");
502     expect("??_C@_13OPKGLAFF@?$AAB?$AA?$AA@", "`string'");
503     expect("??_C@_13FHBKNHDA@?$AAC?$AA?$AA@", "`string'");
504     expect("??_C@_13MKMNOPIJ@?$AAD?$AA?$AA@", "`string'");
505     expect("??_C@_13HCHBIIOM@?$AAE?$AA?$AA@", "`string'");
506     expect("??_C@_13GAMECHAC@?$AAF?$AA?$AA@", "`string'");
507     expect("??_C@_13NIHIEAGH@?$AAG?$AA?$AA@", "`string'");
508     expect("??_C@_13IABLFADB@?$AAH?$AA?$AA@", "`string'");
509     expect("??_C@_13DIKHDHFE@?$AAI?$AA?$AA@", "`string'");
510     expect("??_C@_13CKBCJILK@?$AAJ?$AA?$AA@", "`string'");
511     expect("??_C@_13JCKOPPNP@?$AAK?$AA?$AA@", "`string'");
512     expect("??_C@_13PHJMHGG@?$AAL?$AA?$AA@", "`string'");
513     expect("??_C@_13LHMFKAAD@?$AAM?$AA?$AA@", "`string'");
514     expect("??_C@_13KFHAAPON@?$AAN?$AA?$AA@", "`string'");
515     expect("??_C@_13BNMMGIII@?$AAO?$AA?$AA@", "`string'");
516     expect("??_C@_13BFLGCPEB@?$AAP?$AA?$AA@", "`string'");
517     expect("??_C@_13KNAKEICE@?$AAQ?$AA?$AA@", "`string'");
518     expect("??_C@_13LPLPOHMK@?$AAR?$AA?$AA@", "`string'");
519     expect("??_C@_13HADIAKP@?$AAS?$AA?$AA@", "`string'");
520     expect("??_C@_13JKNELIBG@?$AAT?$AA?$AA@", "`string'");
521     expect("??_C@_13CCGINPHD@?$AAU?$AA?$AA@", "`string'");
522     expect("??_C@_13DANNHAJN@?$AAV?$AA?$AA@", "`string'");
523     expect("??_C@_13IIGBBHPI@?$AAW?$AA?$AA@", "`string'");
524     expect("??_C@_13NAACAHKO@?$AAX?$AA?$AA@", "`string'");
525     expect("??_C@_13GILOGAML@?$AAY?$AA?$AA@", "`string'");
526     expect("??_C@_13HKALMPCF@?$AAZ?$AA?$AA@", "`string'");
527     expect("??_C@_13MCLHKIEA@?$AA?$FL?$AA?$AA@", "`string'");
528     expect("??_C@_13FPGAJAPJ@?$AA?2?$AA?$AA@", "`string'");
529     expect("??_C@_13OHNMPHJM@?$AA?$FN?$AA?$AA@", "`string'");
530     expect("??_C@_13PFGJFIHC@?$AA?$FO?$AA?$AA@", "`string'");
531     expect("??_C@_13ENNFDPBH@?$AA_?$AA?$AA@", "`string'");
532     expect("??_C@_13OFJNNHOA@?$AA?$GA?$AA?$AA@", "`string'");
533     expect("??_C@_13FNCBLAIF@?$AAa?$AA?$AA@", "`string'");
534     expect("??_C@_13EPJEBPGL@?$AAb?$AA?$AA@", "`string'");
535     expect("??_C@_13PHCIHIAO@?$AAc?$AA?$AA@", "`string'");
536     expect("??_C@_13GKPPEALH@?$AAd?$AA?$AA@", "`string'");
537     expect("??_C@_13NCEDCHNC@?$AAe?$AA?$AA@", "`string'");
538     expect("??_C@_13MAPGIIDM@?$AAf?$AA?$AA@", "`string'");
539     expect("??_C@_13HIEKOPFJ@?$AAg?$AA?$AA@", "`string'");
540     expect("??_C@_13CACJPPAP@?$AAh?$AA?$AA@", "`string'");
541     expect("??_C@_13JIJFJIGK@?$AAi?$AA?$AA@", "`string'");
542     expect("??_C@_13IKCADHIE@?$AAj?$AA?$AA@", "`string'");
543     expect("??_C@_13DCJMFAOB@?$AAk?$AA?$AA@", "`string'");
544     expect("??_C@_13KPELGIFI@?$AAl?$AA?$AA@", "`string'");
545     expect("??_C@_13BHPHAPDN@?$AAm?$AA?$AA@", "`string'");
546     expect("??_C@_13FECKAND@?$AAn?$AA?$AA@", "`string'");
547     expect("??_C@_13LNPOMHLG@?$AAo?$AA?$AA@", "`string'");
548     expect("??_C@_13LFIEIAHP@?$AAp?$AA?$AA@", "`string'");
549     expect("??_C@_13NDIOHBK@?$AAq?$AA?$AA@", "`string'");
550     expect("??_C@_13BPINEIPE@?$AAr?$AA?$AA@", "`string'");
551     expect("??_C@_13KHDBCPJB@?$AAs?$AA?$AA@", "`string'");
552     expect("??_C@_13DKOGBHCI@?$AAt?$AA?$AA@", "`string'");
553     expect("??_C@_13ICFKHAEN@?$AAu?$AA?$AA@", "`string'");
554     expect("??_C@_13JAOPNPKD@?$AAv?$AA?$AA@", "`string'");
555     expect("??_C@_13CIFDLIMG@?$AAw?$AA?$AA@", "`string'");
556     expect("??_C@_13HADAKIJA@?$AAx?$AA?$AA@", "`string'");
557     expect("??_C@_13MIIMMPPF@?$AAy?$AA?$AA@", "`string'");
558     expect("??_C@_13NKDJGABL@?$AAz?$AA?$AA@", "`string'");
559     expect("??_C@_13GCIFAHHO@?$AA?$HL?$AA?$AA@", "`string'");
560     expect("??_C@_13PPFCDPMH@?$AA?$HM?$AA?$AA@", "`string'");
561     expect("??_C@_13EHOOFIKC@?$AA?$HN?$AA?$AA@", "`string'");
562     expect("??_C@_13FFFLPHEM@?$AA?$HO?$AA?$AA@", "`string'");
563 
564     // Tests for maximum string length
565     expect(
566         "??_C@_0CF@LABBIIMO@012345678901234567890123456789AB@",
567         "`string'",
568     );
569     expect("??_C@_1EK@KFPEBLPK@?$AA0?$AA1?$AA2?$AA3?$AA4?$AA5?$AA6?$AA7?$AA8?$AA9?$AA0?$AA1?$AA2?$AA3?$AA4?$AA5?$AA6?$AA7?$AA8?$AA9?$AA0?$AA1?$AA2?$AA3?$AA4?$AA5?$AA6?$AA7?$AA8?$AA9?$AAA?$AAB@", "`string'");
570     // Unicode character.
571     expect("??_C@_13IIHIAFKH@?W?$PP?$AA?$AA@", "`string'");
572     // u8/u/U literal strings.
573     expect("??_C@_02PCEFGMJL@hi?$AA@", "`string'");
574     expect("??_C@_05OMLEGLOC@h?$AAi?$AA?$AA?$AA@", "`string'");
575     expect(
576         "??_C@_0M@GFNAJIPG@h?$AA?$AA?$AAi?$AA?$AA?$AA?$AA?$AA?$AA?$AA@",
577         "`string'",
578     );
579 }
580 
581 #[test]
upstream_tests()582 fn upstream_tests() {
583     let expect = |input, reference| {
584         expect_with_flags(input, reference, 0x0);
585     };
586     expect("?x@@3HA", "int x");
587     expect("?x@@3PEAHEA", "int *x");
588     expect("?x@@3PEAPEAHEA", "int * *x");
589     expect("?x@@3PEAY02HEA", "int (*x)[3]");
590     expect("?x@@3PEAY124HEA", "int (*x)[3][5]");
591     expect("?x@@3PEAY02$$CBHEA", "int const (*x)[3]");
592     expect("?x@@3PEAEEA", "unsigned char *x");
593     expect("?x@@3PEAY1NKM@5HEA", "int (*x)[3500][6]");
594     expect("?x@@YAXMH@Z", "void __cdecl x(float,int)");
595     expect("?x@@YAXMH@Z", "void __cdecl x(float,int)");
596     expect("?x@@3P6AHMNH@ZEA", "int (__cdecl *x)(float,double,int)");
597     expect(
598         "?x@@3P6AHP6AHM@ZN@ZEA",
599         "int (__cdecl *x)(int (__cdecl *)(float),double)",
600     );
601     expect(
602         "?x@@3P6AHP6AHM@Z0@ZEA",
603         "int (__cdecl *x)(int (__cdecl *)(float),int (__cdecl *)(float))",
604     );
605 
606     expect("?x@ns@@3HA", "int ns::x");
607 
608     // Microsoft's undname returns "int const * const x" for this symbol.
609     // I believe it's their bug.
610     expect("?x@@3PEBHEB", "int const *x");
611 
612     expect("?x@@3QEAHEB", "int * const x");
613     expect("?x@@3QEBHEB", "int const * const x");
614 
615     expect("?x@@3AEBHEB", "int const & x");
616 
617     expect("?x@@3PEAUty@@EA", "struct ty *x");
618     expect("?x@@3PEATty@@EA", "union ty *x");
619     expect("?x@@3PEAUty@@EA", "struct ty *x");
620     expect("?x@@3PEAW4ty@@EA", "enum ty *x");
621     expect("?x@@3PEAVty@@EA", "class ty *x");
622 
623     expect("?x@@3PEAV?$tmpl@H@@EA", "class tmpl<int> *x");
624     expect("?x@@3PEAU?$tmpl@H@@EA", "struct tmpl<int> *x");
625     expect("?x@@3PEAT?$tmpl@H@@EA", "union tmpl<int> *x");
626     expect("?instance@@3Vklass@@A", "class klass instance");
627     expect(
628         "?instance$initializer$@@3P6AXXZEA",
629         "void (__cdecl *instance$initializer$)(void)",
630     );
631     expect("??0klass@@QEAA@XZ", "public: __cdecl klass::klass(void)");
632     expect("??1klass@@QEAA@XZ", "public: __cdecl klass::~klass(void)");
633     expect(
634         "?x@@YAHPEAVklass@@AEAV1@@Z",
635         "int __cdecl x(class klass *,class klass &)",
636     );
637     expect(
638         "?x@ns@@3PEAV?$klass@HH@1@EA",
639         "class ns::klass<int,int> *ns::x",
640     );
641     expect(
642         "?fn@?$klass@H@ns@@QEBAIXZ",
643         "public: unsigned int __cdecl ns::klass<int>::fn(void) const",
644     );
645 
646     expect(
647         "??4klass@@QEAAAEBV0@AEBV0@@Z",
648         "public: class klass const & __cdecl klass::operator=(class klass const &)",
649     );
650     expect(
651         "??7klass@@QEAA_NXZ",
652         "public: bool __cdecl klass::operator!(void)",
653     );
654     expect(
655         "??8klass@@QEAA_NAEBV0@@Z",
656         "public: bool __cdecl klass::operator==(class klass const &)",
657     );
658     expect(
659         "??9klass@@QEAA_NAEBV0@@Z",
660         "public: bool __cdecl klass::operator!=(class klass const &)",
661     );
662     expect(
663         "??Aklass@@QEAAH_K@Z",
664         "public: int __cdecl klass::operator[](uint64_t)",
665     );
666     expect(
667         "??Cklass@@QEAAHXZ",
668         "public: int __cdecl klass::operator->(void)",
669     );
670     expect(
671         "??Dklass@@QEAAHXZ",
672         "public: int __cdecl klass::operator*(void)",
673     );
674     expect(
675         "??Eklass@@QEAAHXZ",
676         "public: int __cdecl klass::operator++(void)",
677     );
678     expect(
679         "??Eklass@@QEAAHH@Z",
680         "public: int __cdecl klass::operator++(int)",
681     );
682     expect(
683         "??Fklass@@QEAAHXZ",
684         "public: int __cdecl klass::operator--(void)",
685     );
686     expect(
687         "??Fklass@@QEAAHH@Z",
688         "public: int __cdecl klass::operator--(int)",
689     );
690     expect(
691         "??Hklass@@QEAAHH@Z",
692         "public: int __cdecl klass::operator+(int)",
693     );
694     expect(
695         "??Gklass@@QEAAHH@Z",
696         "public: int __cdecl klass::operator-(int)",
697     );
698     expect(
699         "??Iklass@@QEAAHH@Z",
700         "public: int __cdecl klass::operator&(int)",
701     );
702     expect(
703         "??Jklass@@QEAAHH@Z",
704         "public: int __cdecl klass::operator->*(int)",
705     );
706     expect(
707         "??Kklass@@QEAAHH@Z",
708         "public: int __cdecl klass::operator/(int)",
709     );
710     expect(
711         "??Mklass@@QEAAHH@Z",
712         "public: int __cdecl klass::operator<(int)",
713     );
714     expect(
715         "??Nklass@@QEAAHH@Z",
716         "public: int __cdecl klass::operator<=(int)",
717     );
718     expect(
719         "??Oklass@@QEAAHH@Z",
720         "public: int __cdecl klass::operator>(int)",
721     );
722     expect(
723         "??Pklass@@QEAAHH@Z",
724         "public: int __cdecl klass::operator>=(int)",
725     );
726     expect(
727         "??Qklass@@QEAAHH@Z",
728         "public: int __cdecl klass::operator,(int)",
729     );
730     expect(
731         "??Rklass@@QEAAHH@Z",
732         "public: int __cdecl klass::operator()(int)",
733     );
734     expect(
735         "??Sklass@@QEAAHXZ",
736         "public: int __cdecl klass::operator~(void)",
737     );
738     expect(
739         "??Tklass@@QEAAHH@Z",
740         "public: int __cdecl klass::operator^(int)",
741     );
742     expect(
743         "??Uklass@@QEAAHH@Z",
744         "public: int __cdecl klass::operator|(int)",
745     );
746     expect(
747         "??Vklass@@QEAAHH@Z",
748         "public: int __cdecl klass::operator&&(int)",
749     );
750     expect(
751         "??Wklass@@QEAAHH@Z",
752         "public: int __cdecl klass::operator||(int)",
753     );
754     expect(
755         "??Xklass@@QEAAHH@Z",
756         "public: int __cdecl klass::operator*=(int)",
757     );
758     expect(
759         "??Yklass@@QEAAHH@Z",
760         "public: int __cdecl klass::operator+=(int)",
761     );
762     expect(
763         "??Zklass@@QEAAHH@Z",
764         "public: int __cdecl klass::operator-=(int)",
765     );
766     expect(
767         "??_0klass@@QEAAHH@Z",
768         "public: int __cdecl klass::operator/=(int)",
769     );
770     expect(
771         "??_1klass@@QEAAHH@Z",
772         "public: int __cdecl klass::operator%=(int)",
773     );
774     expect(
775         "??_2klass@@QEAAHH@Z",
776         "public: int __cdecl klass::operator>>=(int)",
777     );
778     expect(
779         "??_3klass@@QEAAHH@Z",
780         "public: int __cdecl klass::operator<<=(int)",
781     );
782     expect(
783         "??_6klass@@QEAAHH@Z",
784         "public: int __cdecl klass::operator^=(int)",
785     );
786     expect(
787         "??6@YAAEBVklass@@AEBV0@H@Z",
788         "class klass const & __cdecl operator<<(class klass const &,int)",
789     );
790     expect(
791         "??5@YAAEBVklass@@AEBV0@_K@Z",
792         "class klass const & __cdecl operator>>(class klass const &,uint64_t)",
793     );
794     expect(
795         "??2@YAPEAX_KAEAVklass@@@Z",
796         "void * __cdecl operator new(uint64_t,class klass &)",
797     );
798     expect(
799         "??_U@YAPEAX_KAEAVklass@@@Z",
800         "void * __cdecl operator new[](uint64_t,class klass &)",
801     );
802     expect(
803         "??3@YAXPEAXAEAVklass@@@Z",
804         "void __cdecl operator delete(void *,class klass &)",
805     );
806     expect(
807         "??_V@YAXPEAXAEAVklass@@@Z",
808         "void __cdecl operator delete[](void *,class klass &)",
809     );
810     expect(
811         "?DispatchToCallback@?$I@U?$Y@$S@y@x@@$$V@y@x@@QEAAXV?$C@$$A6AXXZ@base@@@Z",
812         "public: void __cdecl x::y::I<struct x::y::Y<> >::DispatchToCallback(class base::C<void __cdecl (void)>)",
813     );
814     expect(
815         "?DispatchToCallback@?$I@U?$Y@$$Z@y@x@@$$V@y@x@@QEAAXV?$C@$$A6AXXZ@base@@@Z",
816         "public: void __cdecl x::y::I<struct x::y::Y<> >::DispatchToCallback(class base::C<void __cdecl (void)>)",
817     );
818     expect(
819         "??$func@H$$ZH@@YAHAEBU?$Foo@H@@0@Z",
820         "int __cdecl func<int,int>(struct Foo<int> const &,struct Foo<int> const &)",
821     );
822     expect(
823         "??$func@HH$$Z@@YAHAEBU?$Foo@H@@0@Z",
824         "int __cdecl func<int,int>(struct Foo<int> const &,struct Foo<int> const &)",
825     );
826     expect(
827         "??$templ_fun_with_pack@$S@@YAXXZ",
828         "void __cdecl templ_fun_with_pack<>(void)",
829     );
830     expect(
831         "??$templ_fun_with_ty_pack@$$$V@@YAXXZ",
832         "void __cdecl templ_fun_with_ty_pack<>(void)",
833     );
834     expect(
835         "??$templ_fun_with_ty_pack@$$V@@YAXXZ",
836         "void __cdecl templ_fun_with_ty_pack<>(void)",
837     );
838     expect(
839         "??__FFLASH_TEMP_FILENAME@sandboxing@mozilla@@YAXXZ",
840         "void __cdecl mozilla::sandboxing::FLASH_TEMP_FILENAME::`dynamic atexit destructor'(void)",
841     );
842     expect(
843         "??__J?1??f@@YAAAUS@@XZ@5BB@",
844         "`struct S & __cdecl f(void)'::`2'::`local static thread guard'{17}",
845     );
846     expect(
847         "??__J?@??f@@YAAAUS@@XZ@5BB@",
848         "`struct S & __cdecl f(void)'::`0'::`local static thread guard'{17}",
849     );
850     expect(
851         "??__J?A@??f@@YAAAUS@@XZ@5BB@",
852         "`struct S & __cdecl f(void)'::`anonymous namespace'::`local static thread guard'{17}",
853     );
854     expect(
855         "??__J?B@??f@@YAAAUS@@XZ@5BB@",
856         "`struct S & __cdecl f(void)'::`1'::`local static thread guard'{17}",
857     );
858     expect(
859         "??__J?@??f@@YAAAUS@@XZ@5BB@",
860         "`struct S & __cdecl f(void)'::`0'::`local static thread guard'{17}",
861     );
862 }
863