|  | ; These tests are based on clang/test/CodeGenCXX/mangle-ms.cpp | 
|  | ; RUN: llvm-undname < %s | FileCheck %s | 
|  |  | 
|  | ; CHECK-NOT: Invalid mangled name | 
|  |  | 
|  | ?a@@3HA | 
|  | ; CHECK: int a | 
|  |  | 
|  | ?b@N@@3HA | 
|  | ; CHECK: int N::b | 
|  |  | 
|  | ?anonymous@?A@N@@3HA | 
|  | ; CHECK: int N::`anonymous namespace'::anonymous | 
|  |  | 
|  | ; FIXME: Reference Temporaries | 
|  | ; ?$RT1@NeedsReferenceTemporary@@3ABHB | 
|  | ; ?$RT1@NeedsReferenceTemporary@@3AEBHEB | 
|  |  | 
|  | ?_c@@YAHXZ | 
|  | ; CHECK: int __cdecl _c(void) | 
|  |  | 
|  | ?d@foo@@0FB | 
|  | ; CHECK: static short const foo::d | 
|  |  | 
|  | ?e@foo@@1JC | 
|  | ; CHECK: static long volatile foo::e | 
|  |  | 
|  | ?f@foo@@2DD | 
|  | ; CHECK: static char const volatile foo::f | 
|  |  | 
|  | ??0foo@@QAE@XZ | 
|  | ; CHECK: __thiscall foo::foo(void) | 
|  |  | 
|  | ??0foo@@QEAA@XZ | 
|  | ; CHECK: __cdecl foo::foo(void) | 
|  |  | 
|  | ??1foo@@QAE@XZ | 
|  | ; CHECK: __thiscall foo::~foo(void) | 
|  |  | 
|  | ??1foo@@QEAA@XZ | 
|  | ; CHECK: __cdecl foo::~foo(void) | 
|  |  | 
|  | ??0foo@@QAE@H@Z | 
|  | ; CHECK: __thiscall foo::foo(int) | 
|  |  | 
|  | ??0foo@@QEAA@H@Z | 
|  | ; CHECK: __cdecl foo::foo(int) | 
|  |  | 
|  | ??0foo@@QAE@PAD@Z | 
|  | ; CHECK: __thiscall foo::foo(char *) | 
|  |  | 
|  | ??0foo@@QEAA@PEAD@Z | 
|  | ; CHECK: __cdecl foo::foo(char *) | 
|  |  | 
|  | ?bar@@YA?AVfoo@@XZ | 
|  | ; CHECK: class foo __cdecl bar(void) | 
|  |  | 
|  | ?bar@@YA?AVfoo@@XZ | 
|  | ; CHECK: class foo __cdecl bar(void) | 
|  |  | 
|  | ??Hfoo@@QAEHH@Z | 
|  | ; CHECK: int __thiscall foo::operator+(int) | 
|  |  | 
|  | ??Hfoo@@QEAAHH@Z | 
|  | ; CHECK: int __cdecl foo::operator+(int) | 
|  |  | 
|  | ?static_method@foo@@SAPAV1@XZ | 
|  | ; CHECK: static class foo * __cdecl foo::static_method(void) | 
|  |  | 
|  | ?static_method@foo@@SAPEAV1@XZ | 
|  | ; CHECK: static class foo * __cdecl foo::static_method(void) | 
|  |  | 
|  | ?g@bar@@2HA | 
|  | ; CHECK: static int bar::g | 
|  |  | 
|  | ; undname returns `int *h1`, but it is a bug in their demangler.  Their mangler | 
|  | ; correctly mangles `int *h1` as ?h1@3PAHA and `int * const h1` as ?h1@3QAHA | 
|  | ?h1@@3QAHA | 
|  | ; CHECK: int *const h1 | 
|  |  | 
|  | ?h2@@3QBHB | 
|  | ; CHECK: int const *const h2 | 
|  |  | 
|  | ?h3@@3QIAHIA | 
|  | ; CHECK: int *const __restrict h3 | 
|  |  | 
|  | ?h3@@3QEIAHEIA | 
|  | ; CHECK: int *const __restrict h3 | 
|  |  | 
|  | ?i@@3PAY0BE@HA | 
|  | ; CHECK: int (*i)[20] | 
|  |  | 
|  | ?FunArr@@3PAY0BE@P6AHHH@ZA | 
|  | ; CHECK: int (__cdecl *(*FunArr)[20])(int, int) | 
|  |  | 
|  | ?j@@3P6GHCE@ZA | 
|  | ; CHECK: int (__stdcall *j)(signed char, unsigned char) | 
|  |  | 
|  | ?funptr@@YAP6AHXZXZ | 
|  | ; CHECK: int (__cdecl * __cdecl funptr(void))(void) | 
|  |  | 
|  | ?k@@3PTfoo@@DT1@ | 
|  | ; CHECK: char const volatile foo::*k | 
|  |  | 
|  | ?k@@3PETfoo@@DET1@ | 
|  | ; CHECK: char const volatile foo::*k | 
|  |  | 
|  | ?l@@3P8foo@@AEHH@ZQ1@ | 
|  | ; CHECK: int (__thiscall foo::*l)(int) | 
|  |  | 
|  | ?g_cInt@@3HB | 
|  | ; CHECK: int const g_cInt | 
|  |  | 
|  | ?g_vInt@@3HC | 
|  | ; CHECK: int volatile g_vInt | 
|  |  | 
|  | ?g_cvInt@@3HD | 
|  | ; CHECK: int const volatile g_cvInt | 
|  |  | 
|  | ?beta@@YI_N_J_W@Z | 
|  | ; CHECK: bool __fastcall beta(__int64, wchar_t) | 
|  |  | 
|  | ?beta@@YA_N_J_W@Z | 
|  | ; CHECK: bool __cdecl beta(__int64, wchar_t) | 
|  |  | 
|  | ?alpha@@YGXMN@Z | 
|  | ; CHECK: void __stdcall alpha(float, double) | 
|  |  | 
|  | ?alpha@@YAXMN@Z | 
|  | ; CHECK: void __cdecl alpha(float, double) | 
|  |  | 
|  | ?gamma@@YAXVfoo@@Ubar@@Tbaz@@W4quux@@@Z | 
|  | ; CHECK: void __cdecl gamma(class foo, struct bar, union baz, enum quux) | 
|  |  | 
|  | ?gamma@@YAXVfoo@@Ubar@@Tbaz@@W4quux@@@Z | 
|  | ; CHECK: void __cdecl gamma(class foo, struct bar, union baz, enum quux) | 
|  |  | 
|  | ?delta@@YAXQAHABJ@Z | 
|  | ; CHECK: void __cdecl delta(int *const, long const &) | 
|  |  | 
|  | ?delta@@YAXQEAHAEBJ@Z | 
|  | ; CHECK: void __cdecl delta(int *const, long const &) | 
|  |  | 
|  | ?epsilon@@YAXQAY19BE@H@Z | 
|  | ; CHECK: void __cdecl epsilon(int (*const)[10][20]) | 
|  |  | 
|  | ?epsilon@@YAXQEAY19BE@H@Z | 
|  | ; CHECK: void __cdecl epsilon(int (*const)[10][20]) | 
|  |  | 
|  | ?zeta@@YAXP6AHHH@Z@Z | 
|  | ; CHECK: void __cdecl zeta(int (__cdecl *)(int, int)) | 
|  |  | 
|  | ?zeta@@YAXP6AHHH@Z@Z | 
|  | ; CHECK: void __cdecl zeta(int (__cdecl *)(int, int)) | 
|  |  | 
|  | ; FIXME: We don't support blocks yet. | 
|  |  | 
|  | ; ?eta@@YAXP_EAHHH@Z@Z | 
|  | ; FIXME: void eta(int (^)(int, int)) | 
|  | ; ?theta@@YAXP_EAHHH@Z@Z | 
|  | ; FIXME: void theta(int(int,int)^ block) | 
|  |  | 
|  | ??2@YAPAXI@Z | 
|  | ; CHECK: void * __cdecl operator new(unsigned int) | 
|  |  | 
|  | ??3@YAXPAX@Z | 
|  | ; CHECK: void __cdecl operator delete(void *) | 
|  |  | 
|  | ??_U@YAPAXI@Z | 
|  | ; CHECK: void * __cdecl operator new[](unsigned int) | 
|  |  | 
|  | ??_V@YAXPAX@Z | 
|  | ; CHECK: void __cdecl operator delete[](void *) | 
|  |  | 
|  | ?color1@@3PANA | 
|  | ; CHECK: double *color1 | 
|  |  | 
|  | ?color2@@3QBNB | 
|  | ; CHECK: double const *const color2 | 
|  |  | 
|  | ; FIXME-EXTRACONST: These tests fails because we print an extra const inside the parens. | 
|  | ; ?color3@@3QAY02$$CBNA | 
|  | ; FIXME-EXTRACONST: double const (*color3)[3] | 
|  |  | 
|  | ; ?color4@@3QAY02$$CBNA | 
|  | ; FIXME-EXTRACONST: double const (*color4)[3] | 
|  |  | 
|  | ?memptr1@@3RESB@@HES1@ | 
|  | ; CHECK: int volatile B::*volatile memptr1 | 
|  |  | 
|  | ?memptr2@@3PESB@@HES1@ | 
|  | ; CHECK: int volatile B::*memptr2 | 
|  |  | 
|  | ?memptr3@@3REQB@@HEQ1@ | 
|  | ; CHECK: int B::*volatile memptr3 | 
|  |  | 
|  | ?funmemptr1@@3RESB@@R6AHXZES1@ | 
|  | ; CHECK: int (__cdecl *volatile B::*volatile funmemptr1)(void) | 
|  |  | 
|  | ?funmemptr2@@3PESB@@R6AHXZES1@ | 
|  | ; CHECK: int (__cdecl *volatile B::*funmemptr2)(void) | 
|  |  | 
|  | ?funmemptr3@@3REQB@@P6AHXZEQ1@ | 
|  | ; CHECK: int (__cdecl *B::*volatile funmemptr3)(void) | 
|  |  | 
|  | ?memptrtofun1@@3R8B@@EAAXXZEQ1@ | 
|  | ; CHECK: void (__cdecl B::*volatile memptrtofun1)(void) | 
|  |  | 
|  | ?memptrtofun2@@3P8B@@EAAXXZEQ1@ | 
|  | ; CHECK: void (__cdecl B::*memptrtofun2)(void) | 
|  |  | 
|  | ?memptrtofun3@@3P8B@@EAAXXZEQ1@ | 
|  | ; CHECK: void (__cdecl B::*memptrtofun3)(void) | 
|  |  | 
|  | ?memptrtofun4@@3R8B@@EAAHXZEQ1@ | 
|  | ; CHECK: int (__cdecl B::*volatile memptrtofun4)(void) | 
|  |  | 
|  | ?memptrtofun5@@3P8B@@EAA?CHXZEQ1@ | 
|  | ; CHECK: int volatile (__cdecl B::*memptrtofun5)(void) | 
|  |  | 
|  | ?memptrtofun6@@3P8B@@EAA?BHXZEQ1@ | 
|  | ; CHECK: int const (__cdecl B::*memptrtofun6)(void) | 
|  |  | 
|  | ?memptrtofun7@@3R8B@@EAAP6AHXZXZEQ1@ | 
|  | ; CHECK: int (__cdecl * (__cdecl B::*volatile memptrtofun7)(void))(void) | 
|  |  | 
|  | ?memptrtofun8@@3P8B@@EAAR6AHXZXZEQ1@ | 
|  | ; CHECK: int (__cdecl *volatile (__cdecl B::*memptrtofun8)(void))(void) | 
|  |  | 
|  | ?memptrtofun9@@3P8B@@EAAQ6AHXZXZEQ1@ | 
|  | ; CHECK: int (__cdecl *const (__cdecl B::*memptrtofun9)(void))(void) | 
|  |  | 
|  |  | 
|  | ?fooE@@YA?AW4E@@XZ | 
|  | ; CHECK: enum E __cdecl fooE(void) | 
|  |  | 
|  | ?fooE@@YA?AW4E@@XZ | 
|  | ; CHECK: enum E __cdecl fooE(void) | 
|  |  | 
|  | ?fooX@@YA?AVX@@XZ | 
|  | ; CHECK: class X __cdecl fooX(void) | 
|  |  | 
|  | ?fooX@@YA?AVX@@XZ | 
|  | ; CHECK: class X __cdecl fooX(void) | 
|  |  | 
|  | ?s0@PR13182@@3PADA | 
|  | ; CHECK: char *PR13182::s0 | 
|  |  | 
|  | ?s1@PR13182@@3PADA | 
|  | ; CHECK: char *PR13182::s1 | 
|  |  | 
|  | ?s2@PR13182@@3QBDB | 
|  | ; CHECK: char const *const PR13182::s2 | 
|  |  | 
|  | ?s3@PR13182@@3QBDB | 
|  | ; CHECK: char const *const PR13182::s3 | 
|  |  | 
|  | ?s4@PR13182@@3RCDC | 
|  | ; CHECK: char volatile *volatile PR13182::s4 | 
|  |  | 
|  | ?s5@PR13182@@3SDDD | 
|  | ; CHECK: char const volatile *const volatile PR13182::s5 | 
|  |  | 
|  | ; undname adds an extra const in here, but it seems like their bug. | 
|  | ?s6@PR13182@@3PBQBDB | 
|  | ; CHECK: char const *const *PR13182::s6 | 
|  |  | 
|  | ; FIXME: We don't properly support extern "C" functions yet. | 
|  | ; ?local@?1??extern_c_func@@9@4HA | 
|  | ; FIXME: int `extern_c_func'::`2'::local | 
|  |  | 
|  | ; ?local@?1??extern_c_func@@9@4HA | 
|  | ; FIXME: int `extern_c_func'::`2'::local | 
|  |  | 
|  | ?v@?1??f@@YAHXZ@4U<unnamed-type-v>@?1??1@YAHXZ@A | 
|  | ; CHECK: struct `int __cdecl f(void)'::`2'::<unnamed-type-v> `int __cdecl f(void)'::`2'::v | 
|  |  | 
|  | ?v@?1???$f@H@@YAHXZ@4U<unnamed-type-v>@?1???$f@H@@YAHXZ@A | 
|  | ; CHECK: struct `int __cdecl f<int>(void)'::`2'::<unnamed-type-v> `int __cdecl f<int>(void)'::`2'::v | 
|  |  | 
|  | ??2OverloadedNewDelete@@SAPAXI@Z | 
|  | ; CHECK: static void * __cdecl OverloadedNewDelete::operator new(unsigned int) | 
|  |  | 
|  |  | 
|  | ??_UOverloadedNewDelete@@SAPAXI@Z | 
|  | ; CHECK: static void * __cdecl OverloadedNewDelete::operator new[](unsigned int) | 
|  |  | 
|  | ??3OverloadedNewDelete@@SAXPAX@Z | 
|  | ; CHECK: static void __cdecl OverloadedNewDelete::operator delete(void *) | 
|  |  | 
|  |  | 
|  | ??_VOverloadedNewDelete@@SAXPAX@Z | 
|  | ; CHECK: static void __cdecl OverloadedNewDelete::operator delete[](void *) | 
|  |  | 
|  | ??HOverloadedNewDelete@@QAEHH@Z | 
|  | ; CHECK: int __thiscall OverloadedNewDelete::operator+(int) | 
|  |  | 
|  | ??2OverloadedNewDelete@@SAPEAX_K@Z | 
|  | ; CHECK: static void * __cdecl OverloadedNewDelete::operator new(unsigned __int64) | 
|  |  | 
|  | ??_UOverloadedNewDelete@@SAPEAX_K@Z | 
|  | ; CHECK: static void * __cdecl OverloadedNewDelete::operator new[](unsigned __int64) | 
|  |  | 
|  | ??3OverloadedNewDelete@@SAXPEAX@Z | 
|  | ; CHECK: static void __cdecl OverloadedNewDelete::operator delete(void *) | 
|  |  | 
|  |  | 
|  | ??_VOverloadedNewDelete@@SAXPEAX@Z | 
|  | ; CHECK: static void __cdecl OverloadedNewDelete::operator delete[](void *) | 
|  |  | 
|  | ??HOverloadedNewDelete@@QEAAHH@Z | 
|  | ; CHECK: int __cdecl OverloadedNewDelete::operator+(int) | 
|  |  | 
|  |  | 
|  | ??2TypedefNewDelete@@SAPAXI@Z | 
|  | ; CHECK: static void * __cdecl TypedefNewDelete::operator new(unsigned int) | 
|  |  | 
|  |  | 
|  | ??_UTypedefNewDelete@@SAPAXI@Z | 
|  | ; CHECK: static void * __cdecl TypedefNewDelete::operator new[](unsigned int) | 
|  |  | 
|  | ??3TypedefNewDelete@@SAXPAX@Z | 
|  | ; CHECK: static void __cdecl TypedefNewDelete::operator delete(void *) | 
|  |  | 
|  | ??_VTypedefNewDelete@@SAXPAX@Z | 
|  | ; CHECK: static void __cdecl TypedefNewDelete::operator delete[](void *) | 
|  |  | 
|  | ?vector_func@@YQXXZ | 
|  | ; CHECK: void __vectorcall vector_func(void) | 
|  |  | 
|  | ; FIXME: We don't support extern C funcs currently. | 
|  | ; ??$fn_tmpl@$1?extern_c_func@@YAXXZ@@YAXXZ | 
|  | ; FIXME: void __cdecl fn_tmpl<&void __cdecl extern_c_func(void)>(void) | 
|  |  | 
|  | ; ?overloaded_fn@@$$J0YAXXZ | 
|  | ; FIXME-EXTERNC: extern \"C\" void __cdecl overloaded_fn(void) | 
|  |  | 
|  | ?f@UnnamedType@@YAXQAPAU<unnamed-type-T1>@S@1@@Z | 
|  | ; CHECK: void __cdecl UnnamedType::f(struct UnnamedType::S::<unnamed-type-T1> **const) | 
|  |  | 
|  | ?f@UnnamedType@@YAXUT2@S@1@@Z | 
|  | ; CHECK: void __cdecl UnnamedType::f(struct UnnamedType::S::T2) | 
|  |  | 
|  | ?f@UnnamedType@@YAXPAUT4@S@1@@Z | 
|  | ; CHECK: void __cdecl UnnamedType::f(struct UnnamedType::S::T4 *) | 
|  |  | 
|  | ?f@UnnamedType@@YAXUT4@S@1@@Z | 
|  | ; CHECK: void __cdecl UnnamedType::f(struct UnnamedType::S::T4) | 
|  |  | 
|  | ?f@UnnamedType@@YAXUT5@S@1@@Z | 
|  | ; CHECK: void __cdecl UnnamedType::f(struct UnnamedType::S::T5) | 
|  |  | 
|  | ?f@UnnamedType@@YAXUT2@S@1@@Z | 
|  | ; CHECK: void __cdecl UnnamedType::f(struct UnnamedType::S::T2) | 
|  |  | 
|  | ?f@UnnamedType@@YAXUT4@S@1@@Z | 
|  | ; CHECK: void __cdecl UnnamedType::f(struct UnnamedType::S::T4) | 
|  |  | 
|  | ?f@UnnamedType@@YAXUT5@S@1@@Z | 
|  | ; CHECK: void __cdecl UnnamedType::f(struct UnnamedType::S::T5) | 
|  |  | 
|  |  | 
|  | ; ?foo@PassObjectSize@@YAHQAHW4__pass_object_size0@__clang@@@Z | 
|  | ; FIXME: int foo(int *const i __attribute__((pass_object_size(0)))); | 
|  | ; ?bar@PassObjectSize@@YAHQAHW4__pass_object_size1@__clang@@@Z | 
|  | ; FIXME: int bar(int *const i __attribute__((pass_object_size(1)))); | 
|  | ; ?qux@PassObjectSize@@YAHQAHW4__pass_object_size1@__clang@@0W4__pass_object_size0@3@@Z | 
|  | ; FIXME: int qux(int *const i __attribute__((pass_object_size(1))), int *const j __attribute__((pass_object_size(0)))); | 
|  | ; ?zot@PassObjectSize@@YAHQAHW4__pass_object_size1@__clang@@01@Z | 
|  | ; FIXME: int zot(int *const i __attribute__((pass_object_size(1))), int *const j __attribute__((pass_object_size(1)))); | 
|  |  | 
|  |  | 
|  |  | 
|  | ?f@Atomic@@YAXU?$_Atomic@H@__clang@@@Z | 
|  | ; CHECK: void __cdecl Atomic::f(struct __clang::_Atomic<int>) | 
|  |  | 
|  | ?f@Complex@@YAXU?$_Complex@H@__clang@@@Z | 
|  | ; CHECK: void __cdecl Complex::f(struct __clang::_Complex<int>) | 
|  |  | 
|  | ?f@Float16@@YAXU_Float16@__clang@@@Z | 
|  | ; CHECK: void __cdecl Float16::f(struct __clang::_Float16) | 
|  |  | 
|  |  | 
|  | ??0?$L@H@NS@@QEAA@XZ | 
|  | ; CHECK: __cdecl NS::L<int>::L<int>(void) | 
|  |  | 
|  | ??0Bar@Foo@@QEAA@XZ | 
|  | ; CHECK: __cdecl Foo::Bar::Bar(void) | 
|  |  | 
|  | ??0?$L@V?$H@PAH@PR26029@@@PR26029@@QAE@XZ | 
|  | ; CHECK: __thiscall PR26029::L<class PR26029::H<int *>>::L<class PR26029::H<int *>>(void) |