; 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 ?$RT1@NeedsReferenceTemporary@@3ABHB ; CHECK: int const &NeedsReferenceTemporary::$RT1 ?$RT1@NeedsReferenceTemporary@@3AEBHEB ; CHECK: int const &NeedsReferenceTemporary::$RT1 ?_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) ??$?HH@S@@QEAAAEANH@Z ; CHECK: double & __cdecl S::operator+<int>(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) ?m@@3PRfoo@@DR1@ ; CHECK: char const foo::*m ?m@@3PERfoo@@DER1@ ; CHECK: char const foo::*m ?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 ; undname prints `double const (* color3)[3]`, but this is a bug in undname. ?color3@@3QAY02$$CBNA ; CHECK: double const (*const color3)[3] ; undname prints `double const (* color4)[3]`, but this is a bug in undname. ?color4@@3QAY02$$CBNA ; CHECK: double const (*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 ?local@?1??extern_c_func@@9@4HA ; CHECK: int `extern "C" extern_c_func'::`2'::local ?local@?1??extern_c_func@@9@4HA ; CHECK: int `extern "C" 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) ?swift_func@@YSXXZ ; CHECK: void __attribute__((__swiftcall__)) swift_func(void) ?swift_async_func@@YWXXZ ; CHECK: void __attribute__((__swiftasynccall__)) swift_async_func(void) ??$fn_tmpl@$1?extern_c_func@@YAXXZ@@YAXXZ ; CHECK: void __cdecl fn_tmpl<&void __cdecl extern_c_func(void)>(void) ?overloaded_fn@@$$J0YAXXZ ; CHECK: 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) ??$emplace_back@ABH@?$vector@HV?$allocator@H@std@@@std@@QAE?A?<decltype-auto>@@ABH@Z ; CHECK: <decltype-auto> __thiscall std::vector<int, class std::allocator<int>>::emplace_back<int const &>(int const &) ?pub_foo@S@@QAEXXZ ; CHECK: public: void __thiscall S::pub_foo(void) ?pub_stat_foo@S@@SAXXZ ; CHECK: public: static void __cdecl S::pub_stat_foo(void) ?pub_virt_foo@S@@UAEXXZ ; CHECK: public: virtual void __thiscall S::pub_virt_foo(void) ?prot_foo@S@@IAEXXZ ; CHECK: protected: void __thiscall S::prot_foo(void) ?prot_stat_foo@S@@KAXXZ ; CHECK: protected: static void __cdecl S::prot_stat_foo(void) ?prot_virt_foo@S@@MAEXXZ ; CHECK: protected: virtual void __thiscall S::prot_virt_foo(void) ?priv_foo@S@@AAEXXZ ; CHECK: private: void __thiscall S::priv_foo(void) ?priv_stat_foo@S@@CAXXZ ; CHECK: private: static void __cdecl S::priv_stat_foo(void) ?priv_virt_foo@S@@EAEXXZ ; CHECK: private: virtual void __thiscall S::priv_virt_foo(void)