1*f4a2713aSLionel Sambuc // RUN: %clang_cc1 -triple i686-pc-win32 -cxx-abi microsoft -fms-extensions -verify %s 2*f4a2713aSLionel Sambuc 3*f4a2713aSLionel Sambuc typedef void void_fun_t(); 4*f4a2713aSLionel Sambuc typedef void __cdecl cdecl_fun_t(); 5*f4a2713aSLionel Sambuc 6*f4a2713aSLionel Sambuc // Pointers to free functions 7*f4a2713aSLionel Sambuc void free_func_default(); // expected-note 2 {{previous declaration is here}} 8*f4a2713aSLionel Sambuc void __cdecl free_func_cdecl(); // expected-note 2 {{previous declaration is here}} 9*f4a2713aSLionel Sambuc void __stdcall free_func_stdcall(); // expected-note 2 {{previous declaration is here}} 10*f4a2713aSLionel Sambuc void __fastcall free_func_fastcall(); // expected-note 2 {{previous declaration is here}} 11*f4a2713aSLionel Sambuc 12*f4a2713aSLionel Sambuc void __cdecl free_func_default(); 13*f4a2713aSLionel Sambuc void __stdcall free_func_default(); // expected-error {{function declared 'stdcall' here was previously declared without calling convention}} 14*f4a2713aSLionel Sambuc void __fastcall free_func_default(); // expected-error {{function declared 'fastcall' here was previously declared without calling convention}} 15*f4a2713aSLionel Sambuc 16*f4a2713aSLionel Sambuc void free_func_cdecl(); 17*f4a2713aSLionel Sambuc void __stdcall free_func_cdecl(); // expected-error {{function declared 'stdcall' here was previously declared 'cdecl'}} 18*f4a2713aSLionel Sambuc void __fastcall free_func_cdecl(); // expected-error {{function declared 'fastcall' here was previously declared 'cdecl'}} 19*f4a2713aSLionel Sambuc 20*f4a2713aSLionel Sambuc void free_func_stdcall(); 21*f4a2713aSLionel Sambuc void __cdecl free_func_stdcall(); // expected-error {{function declared 'cdecl' here was previously declared 'stdcall'}} 22*f4a2713aSLionel Sambuc void __fastcall free_func_stdcall(); // expected-error {{function declared 'fastcall' here was previously declared 'stdcall'}} 23*f4a2713aSLionel Sambuc 24*f4a2713aSLionel Sambuc void __cdecl free_func_fastcall(); // expected-error {{function declared 'cdecl' here was previously declared 'fastcall'}} 25*f4a2713aSLionel Sambuc void __stdcall free_func_fastcall(); // expected-error {{function declared 'stdcall' here was previously declared 'fastcall'}} 26*f4a2713aSLionel Sambuc void free_func_fastcall(); 27*f4a2713aSLionel Sambuc 28*f4a2713aSLionel Sambuc // Overloaded functions may have different calling conventions 29*f4a2713aSLionel Sambuc void __fastcall free_func_default(int); 30*f4a2713aSLionel Sambuc void __cdecl free_func_default(int *); 31*f4a2713aSLionel Sambuc 32*f4a2713aSLionel Sambuc void __thiscall free_func_cdecl(char *); 33*f4a2713aSLionel Sambuc void __cdecl free_func_cdecl(double); 34*f4a2713aSLionel Sambuc 35*f4a2713aSLionel Sambuc typedef void void_fun_t(); 36*f4a2713aSLionel Sambuc typedef void __cdecl cdecl_fun_t(); 37*f4a2713aSLionel Sambuc 38*f4a2713aSLionel Sambuc // Pointers to member functions 39*f4a2713aSLionel Sambuc struct S { 40*f4a2713aSLionel Sambuc void member_default1(); // expected-note {{previous declaration is here}} 41*f4a2713aSLionel Sambuc void member_default2(); 42*f4a2713aSLionel Sambuc void __cdecl member_cdecl1(); 43*f4a2713aSLionel Sambuc void __cdecl member_cdecl2(); // expected-note {{previous declaration is here}} 44*f4a2713aSLionel Sambuc void __thiscall member_thiscall1(); 45*f4a2713aSLionel Sambuc void __thiscall member_thiscall2(); // expected-note {{previous declaration is here}} 46*f4a2713aSLionel Sambuc 47*f4a2713aSLionel Sambuc // Typedefs carrying the __cdecl convention are adjusted to __thiscall. 48*f4a2713aSLionel Sambuc void_fun_t member_typedef_default; // expected-note {{previous declaration is here}} 49*f4a2713aSLionel Sambuc cdecl_fun_t member_typedef_cdecl1; // expected-note {{previous declaration is here}} 50*f4a2713aSLionel Sambuc cdecl_fun_t __cdecl member_typedef_cdecl2; 51*f4a2713aSLionel Sambuc void_fun_t __stdcall member_typedef_stdcall; 52*f4a2713aSLionel Sambuc 53*f4a2713aSLionel Sambuc // Static member functions can't be __thiscall 54*f4a2713aSLionel Sambuc static void static_member_default1(); 55*f4a2713aSLionel Sambuc static void static_member_default2(); 56*f4a2713aSLionel Sambuc static void static_member_default3(); // expected-note {{previous declaration is here}} 57*f4a2713aSLionel Sambuc static void __cdecl static_member_cdecl1(); 58*f4a2713aSLionel Sambuc static void __cdecl static_member_cdecl2(); // expected-note {{previous declaration is here}} 59*f4a2713aSLionel Sambuc static void __stdcall static_member_stdcall1(); 60*f4a2713aSLionel Sambuc static void __stdcall static_member_stdcall2(); 61*f4a2713aSLionel Sambuc 62*f4a2713aSLionel Sambuc // Variadic functions can't be other than default or __cdecl 63*f4a2713aSLionel Sambuc void member_variadic_default(int x, ...); 64*f4a2713aSLionel Sambuc void __cdecl member_variadic_cdecl(int x, ...); 65*f4a2713aSLionel Sambuc 66*f4a2713aSLionel Sambuc static void static_member_variadic_default(int x, ...); 67*f4a2713aSLionel Sambuc static void __cdecl static_member_variadic_cdecl(int x, ...); 68*f4a2713aSLionel Sambuc }; 69*f4a2713aSLionel Sambuc 70*f4a2713aSLionel Sambuc void __cdecl S::member_default1() {} // expected-error {{function declared 'cdecl' here was previously declared without calling convention}} 71*f4a2713aSLionel Sambuc void __thiscall S::member_default2() {} 72*f4a2713aSLionel Sambuc 73*f4a2713aSLionel Sambuc void __cdecl S::member_typedef_default() {} // expected-error {{function declared 'cdecl' here was previously declared without calling convention}} 74*f4a2713aSLionel Sambuc void __cdecl S::member_typedef_cdecl1() {} // expected-error {{function declared 'cdecl' here was previously declared without calling convention}} 75*f4a2713aSLionel Sambuc void __cdecl S::member_typedef_cdecl2() {} 76*f4a2713aSLionel Sambuc void __stdcall S::member_typedef_stdcall() {} 77*f4a2713aSLionel Sambuc 78*f4a2713aSLionel Sambuc void S::member_cdecl1() {} 79*f4a2713aSLionel Sambuc void __thiscall S::member_cdecl2() {} // expected-error {{function declared 'thiscall' here was previously declared 'cdecl'}} 80*f4a2713aSLionel Sambuc 81*f4a2713aSLionel Sambuc void S::member_thiscall1() {} 82*f4a2713aSLionel Sambuc void __cdecl S::member_thiscall2() {} // expected-error {{function declared 'cdecl' here was previously declared 'thiscall'}} 83*f4a2713aSLionel Sambuc 84*f4a2713aSLionel Sambuc void S::static_member_default1() {} 85*f4a2713aSLionel Sambuc void __cdecl S::static_member_default2() {} 86*f4a2713aSLionel Sambuc void __stdcall S::static_member_default3() {} // expected-error {{function declared 'stdcall' here was previously declared without calling convention}} 87*f4a2713aSLionel Sambuc 88*f4a2713aSLionel Sambuc void S::static_member_cdecl1() {} 89*f4a2713aSLionel Sambuc void __stdcall S::static_member_cdecl2() {} // expected-error {{function declared 'stdcall' here was previously declared 'cdecl'}} 90*f4a2713aSLionel Sambuc 91*f4a2713aSLionel Sambuc void __cdecl S::member_variadic_default(int x, ...) { (void)x; } 92*f4a2713aSLionel Sambuc void S::member_variadic_cdecl(int x, ...) { (void)x; } 93*f4a2713aSLionel Sambuc 94*f4a2713aSLionel Sambuc void __cdecl S::static_member_variadic_default(int x, ...) { (void)x; } 95*f4a2713aSLionel Sambuc void S::static_member_variadic_cdecl(int x, ...) { (void)x; } 96*f4a2713aSLionel Sambuc 97*f4a2713aSLionel Sambuc // Declare a template using a calling convention. 98*f4a2713aSLionel Sambuc template <class CharT> inline int __cdecl mystrlen(const CharT *str) { 99*f4a2713aSLionel Sambuc int i; 100*f4a2713aSLionel Sambuc for (i = 0; str[i]; i++) { } 101*f4a2713aSLionel Sambuc return i; 102*f4a2713aSLionel Sambuc } 103*f4a2713aSLionel Sambuc extern int sse_strlen(const char *str); 104*f4a2713aSLionel Sambuc template <> inline int __cdecl mystrlen(const char *str) { 105*f4a2713aSLionel Sambuc return sse_strlen(str); 106*f4a2713aSLionel Sambuc } 107*f4a2713aSLionel Sambuc void use_tmpl(const char *str, const int *ints) { 108*f4a2713aSLionel Sambuc mystrlen(str); 109*f4a2713aSLionel Sambuc mystrlen(ints); 110*f4a2713aSLionel Sambuc } 111*f4a2713aSLionel Sambuc 112*f4a2713aSLionel Sambuc struct MixedCCStaticOverload { 113*f4a2713aSLionel Sambuc static void overloaded(int a); 114*f4a2713aSLionel Sambuc static void __stdcall overloaded(short a); 115*f4a2713aSLionel Sambuc }; 116*f4a2713aSLionel Sambuc 117*f4a2713aSLionel Sambuc void MixedCCStaticOverload::overloaded(int a) {} 118*f4a2713aSLionel Sambuc void MixedCCStaticOverload::overloaded(short a) {} 119*f4a2713aSLionel Sambuc 120*f4a2713aSLionel Sambuc // Friend function decls are cdecl by default, not thiscall. Friend method 121*f4a2713aSLionel Sambuc // decls should always be redeclarations, because the class cannot be 122*f4a2713aSLionel Sambuc // incomplete. 123*f4a2713aSLionel Sambuc struct FriendClass { 124*f4a2713aSLionel Sambuc void friend_method() {} 125*f4a2713aSLionel Sambuc }; 126*f4a2713aSLionel Sambuc void __stdcall friend_stdcall1() {} 127*f4a2713aSLionel Sambuc class MakeFriendDecls { 128*f4a2713aSLionel Sambuc int x; 129*f4a2713aSLionel Sambuc friend void FriendClass::friend_method(); 130*f4a2713aSLionel Sambuc friend void friend_default(); 131*f4a2713aSLionel Sambuc friend void friend_stdcall1(); 132*f4a2713aSLionel Sambuc friend void __stdcall friend_stdcall2(); 133*f4a2713aSLionel Sambuc friend void friend_stdcall3(); // expected-note {{previous declaration is here}} 134*f4a2713aSLionel Sambuc }; 135*f4a2713aSLionel Sambuc void friend_default() {} 136*f4a2713aSLionel Sambuc void __stdcall friend_stdcall3() {} // expected-error {{function declared 'stdcall' here was previously declared without calling convention}} 137*f4a2713aSLionel Sambuc void __stdcall friend_stdcall2() {} 138*f4a2713aSLionel Sambuc 139*f4a2713aSLionel Sambuc // Test functions with multiple attributes. 140*f4a2713aSLionel Sambuc void __attribute__((noreturn)) __stdcall __attribute__((regparm(1))) multi_attribute(int x); 141*f4a2713aSLionel Sambuc void multi_attribute(int x) { __builtin_unreachable(); } 142*f4a2713aSLionel Sambuc 143*f4a2713aSLionel Sambuc 144*f4a2713aSLionel Sambuc // expected-error@+2 {{stdcall and cdecl attributes are not compatible}} 145*f4a2713aSLionel Sambuc // expected-error@+1 {{fastcall and cdecl attributes are not compatible}} 146*f4a2713aSLionel Sambuc void __cdecl __cdecl __stdcall __cdecl __fastcall multi_cc(int x); 147*f4a2713aSLionel Sambuc 148*f4a2713aSLionel Sambuc template <typename T> void __stdcall StdcallTemplate(T) {} 149*f4a2713aSLionel Sambuc template <> void StdcallTemplate<int>(int) {} 150*f4a2713aSLionel Sambuc template <> void __stdcall StdcallTemplate<short>(short) {} 151*f4a2713aSLionel Sambuc 152*f4a2713aSLionel Sambuc // FIXME: Note the template, not the implicit instantiation. 153*f4a2713aSLionel Sambuc // expected-error@+2 {{function declared 'cdecl' here was previously declared 'stdcall}} 154*f4a2713aSLionel Sambuc // expected-note@+1 {{previous declaration is here}} 155*f4a2713aSLionel Sambuc template <> void __cdecl StdcallTemplate<long>(long) {} 156*f4a2713aSLionel Sambuc 157*f4a2713aSLionel Sambuc struct ExactlyInt { 158*f4a2713aSLionel Sambuc template <typename T> static int cast_to_int(T) { 159*f4a2713aSLionel Sambuc return T::this_is_not_an_int(); 160*f4a2713aSLionel Sambuc } 161*f4a2713aSLionel Sambuc }; 162*f4a2713aSLionel Sambuc template <> inline int ExactlyInt::cast_to_int<int>(int x) { return x; } 163*f4a2713aSLionel Sambuc 164*f4a2713aSLionel Sambuc namespace test2 { 165*f4a2713aSLionel Sambuc class foo { 166*f4a2713aSLionel Sambuc template <typename T> void bar(T v); 167*f4a2713aSLionel Sambuc }; 168*f4a2713aSLionel Sambuc extern template void foo::bar(const void *); 169*f4a2713aSLionel Sambuc } 170*f4a2713aSLionel Sambuc 171*f4a2713aSLionel Sambuc namespace test3 { 172*f4a2713aSLionel Sambuc struct foo { 173*f4a2713aSLionel Sambuc typedef void bar(); 174*f4a2713aSLionel Sambuc }; 175*f4a2713aSLionel Sambuc bool zed(foo::bar *); 176*f4a2713aSLionel Sambuc void bah() {} 177*f4a2713aSLionel Sambuc void baz() { zed(bah); } 178*f4a2713aSLionel Sambuc } 179*f4a2713aSLionel Sambuc 180*f4a2713aSLionel Sambuc namespace test4 { 181*f4a2713aSLionel Sambuc class foo { 182*f4a2713aSLionel Sambuc template <typename T> static void bar(T v); 183*f4a2713aSLionel Sambuc }; 184*f4a2713aSLionel Sambuc extern template void foo::bar(const void *); 185*f4a2713aSLionel Sambuc } 186