1*67e74705SXin Li // RUN: %clang_cc1 -std=c++14 -triple i686-pc-win32 -fms-extensions -DMSABI -verify %s
2*67e74705SXin Li // RUN: %clang_cc1 -std=c++14 -triple i686-pc-mingw32 -verify %s
3*67e74705SXin Li // RUN: %clang_cc1 -std=c++14 -triple i686-pc-mingw32 -fms-extensions -verify %s
4*67e74705SXin Li
5*67e74705SXin Li typedef void void_fun_t();
6*67e74705SXin Li typedef void __cdecl cdecl_fun_t();
7*67e74705SXin Li
8*67e74705SXin Li // Pointers to free functions
9*67e74705SXin Li void free_func_default(); // expected-note 2 {{previous declaration is here}}
10*67e74705SXin Li void __cdecl free_func_cdecl(); // expected-note 2 {{previous declaration is here}}
11*67e74705SXin Li void __stdcall free_func_stdcall(); // expected-note 2 {{previous declaration is here}}
12*67e74705SXin Li void __fastcall free_func_fastcall(); // expected-note 2 {{previous declaration is here}}
13*67e74705SXin Li void __vectorcall free_func_vectorcall(); // expected-note 2 {{previous declaration is here}}
14*67e74705SXin Li
15*67e74705SXin Li void __cdecl free_func_default();
16*67e74705SXin Li void __stdcall free_func_default(); // expected-error {{function declared 'stdcall' here was previously declared without calling convention}}
17*67e74705SXin Li void __fastcall free_func_default(); // expected-error {{function declared 'fastcall' here was previously declared without calling convention}}
18*67e74705SXin Li
19*67e74705SXin Li void free_func_cdecl();
20*67e74705SXin Li void __stdcall free_func_cdecl(); // expected-error {{function declared 'stdcall' here was previously declared 'cdecl'}}
21*67e74705SXin Li void __fastcall free_func_cdecl(); // expected-error {{function declared 'fastcall' here was previously declared 'cdecl'}}
22*67e74705SXin Li
23*67e74705SXin Li void free_func_stdcall();
24*67e74705SXin Li void __cdecl free_func_stdcall(); // expected-error {{function declared 'cdecl' here was previously declared 'stdcall'}}
25*67e74705SXin Li void __fastcall free_func_stdcall(); // expected-error {{function declared 'fastcall' here was previously declared 'stdcall'}}
26*67e74705SXin Li
27*67e74705SXin Li void __cdecl free_func_fastcall(); // expected-error {{function declared 'cdecl' here was previously declared 'fastcall'}}
28*67e74705SXin Li void __stdcall free_func_fastcall(); // expected-error {{function declared 'stdcall' here was previously declared 'fastcall'}}
29*67e74705SXin Li void free_func_fastcall();
30*67e74705SXin Li
31*67e74705SXin Li void __cdecl free_func_vectorcall(); // expected-error {{function declared 'cdecl' here was previously declared 'vectorcall'}}
32*67e74705SXin Li void __stdcall free_func_vectorcall(); // expected-error {{function declared 'stdcall' here was previously declared 'vectorcall'}}
33*67e74705SXin Li void free_func_vectorcall();
34*67e74705SXin Li
35*67e74705SXin Li // Overloaded functions may have different calling conventions
36*67e74705SXin Li void __fastcall free_func_default(int);
37*67e74705SXin Li void __cdecl free_func_default(int *);
38*67e74705SXin Li
39*67e74705SXin Li void __thiscall free_func_cdecl(char *);
40*67e74705SXin Li void __cdecl free_func_cdecl(double);
41*67e74705SXin Li
42*67e74705SXin Li typedef void void_fun_t();
43*67e74705SXin Li typedef void __cdecl cdecl_fun_t();
44*67e74705SXin Li
45*67e74705SXin Li // Pointers to member functions
46*67e74705SXin Li struct S {
47*67e74705SXin Li void member_default1(); // expected-note {{previous declaration is here}}
48*67e74705SXin Li void member_default2();
49*67e74705SXin Li void __cdecl member_cdecl1();
50*67e74705SXin Li void __cdecl member_cdecl2(); // expected-note {{previous declaration is here}}
51*67e74705SXin Li void __thiscall member_thiscall1();
52*67e74705SXin Li void __thiscall member_thiscall2(); // expected-note {{previous declaration is here}}
53*67e74705SXin Li void __vectorcall member_vectorcall1();
54*67e74705SXin Li void __vectorcall member_vectorcall2(); // expected-note {{previous declaration is here}}
55*67e74705SXin Li
56*67e74705SXin Li // Typedefs carrying the __cdecl convention are adjusted to __thiscall.
57*67e74705SXin Li void_fun_t member_typedef_default; // expected-note {{previous declaration is here}}
58*67e74705SXin Li cdecl_fun_t member_typedef_cdecl1; // expected-note {{previous declaration is here}}
59*67e74705SXin Li cdecl_fun_t __cdecl member_typedef_cdecl2;
60*67e74705SXin Li void_fun_t __stdcall member_typedef_stdcall;
61*67e74705SXin Li
62*67e74705SXin Li // Static member functions can't be __thiscall
63*67e74705SXin Li static void static_member_default1();
64*67e74705SXin Li static void static_member_default2();
65*67e74705SXin Li static void static_member_default3(); // expected-note {{previous declaration is here}}
66*67e74705SXin Li static void __cdecl static_member_cdecl1();
67*67e74705SXin Li static void __cdecl static_member_cdecl2(); // expected-note {{previous declaration is here}}
68*67e74705SXin Li static void __stdcall static_member_stdcall1();
69*67e74705SXin Li static void __stdcall static_member_stdcall2();
70*67e74705SXin Li
71*67e74705SXin Li // Variadic functions can't be other than default or __cdecl
72*67e74705SXin Li void member_variadic_default(int x, ...);
73*67e74705SXin Li void __cdecl member_variadic_cdecl(int x, ...);
74*67e74705SXin Li
75*67e74705SXin Li static void static_member_variadic_default(int x, ...);
76*67e74705SXin Li static void __cdecl static_member_variadic_cdecl(int x, ...);
77*67e74705SXin Li
78*67e74705SXin Li // Structors can't be other than default in MS ABI environment
79*67e74705SXin Li #ifdef MSABI
80*67e74705SXin Li __vectorcall S(); // expected-warning {{vectorcall calling convention ignored on constructor/destructor}}
81*67e74705SXin Li #endif
82*67e74705SXin Li };
83*67e74705SXin Li
member_default1()84*67e74705SXin Li void __cdecl S::member_default1() {} // expected-error {{function declared 'cdecl' here was previously declared without calling convention}}
member_default2()85*67e74705SXin Li void __thiscall S::member_default2() {}
86*67e74705SXin Li
member_typedef_default()87*67e74705SXin Li void __cdecl S::member_typedef_default() {} // expected-error {{function declared 'cdecl' here was previously declared without calling convention}}
member_typedef_cdecl1()88*67e74705SXin Li void __cdecl S::member_typedef_cdecl1() {} // expected-error {{function declared 'cdecl' here was previously declared without calling convention}}
member_typedef_cdecl2()89*67e74705SXin Li void __cdecl S::member_typedef_cdecl2() {}
member_typedef_stdcall()90*67e74705SXin Li void __stdcall S::member_typedef_stdcall() {}
91*67e74705SXin Li
member_cdecl1()92*67e74705SXin Li void S::member_cdecl1() {}
member_cdecl2()93*67e74705SXin Li void __thiscall S::member_cdecl2() {} // expected-error {{function declared 'thiscall' here was previously declared 'cdecl'}}
94*67e74705SXin Li
member_thiscall1()95*67e74705SXin Li void S::member_thiscall1() {}
member_thiscall2()96*67e74705SXin Li void __cdecl S::member_thiscall2() {} // expected-error {{function declared 'cdecl' here was previously declared 'thiscall'}}
97*67e74705SXin Li
member_vectorcall1()98*67e74705SXin Li void S::member_vectorcall1() {}
member_vectorcall2()99*67e74705SXin Li void __cdecl S::member_vectorcall2() {} // expected-error {{function declared 'cdecl' here was previously declared 'vectorcall'}}
100*67e74705SXin Li
static_member_default1()101*67e74705SXin Li void S::static_member_default1() {}
static_member_default2()102*67e74705SXin Li void __cdecl S::static_member_default2() {}
static_member_default3()103*67e74705SXin Li void __stdcall S::static_member_default3() {} // expected-error {{function declared 'stdcall' here was previously declared without calling convention}}
104*67e74705SXin Li
static_member_cdecl1()105*67e74705SXin Li void S::static_member_cdecl1() {}
static_member_cdecl2()106*67e74705SXin Li void __stdcall S::static_member_cdecl2() {} // expected-error {{function declared 'stdcall' here was previously declared 'cdecl'}}
107*67e74705SXin Li
member_variadic_default(int x,...)108*67e74705SXin Li void __cdecl S::member_variadic_default(int x, ...) { (void)x; }
member_variadic_cdecl(int x,...)109*67e74705SXin Li void S::member_variadic_cdecl(int x, ...) { (void)x; }
110*67e74705SXin Li
static_member_variadic_default(int x,...)111*67e74705SXin Li void __cdecl S::static_member_variadic_default(int x, ...) { (void)x; }
static_member_variadic_cdecl(int x,...)112*67e74705SXin Li void S::static_member_variadic_cdecl(int x, ...) { (void)x; }
113*67e74705SXin Li
114*67e74705SXin Li // Declare a template using a calling convention.
mystrlen(const CharT * str)115*67e74705SXin Li template <class CharT> inline int __cdecl mystrlen(const CharT *str) {
116*67e74705SXin Li int i;
117*67e74705SXin Li for (i = 0; str[i]; i++) { }
118*67e74705SXin Li return i;
119*67e74705SXin Li }
120*67e74705SXin Li extern int sse_strlen(const char *str);
mystrlen(const char * str)121*67e74705SXin Li template <> inline int __cdecl mystrlen(const char *str) {
122*67e74705SXin Li return sse_strlen(str);
123*67e74705SXin Li }
use_tmpl(const char * str,const int * ints)124*67e74705SXin Li void use_tmpl(const char *str, const int *ints) {
125*67e74705SXin Li mystrlen(str);
126*67e74705SXin Li mystrlen(ints);
127*67e74705SXin Li }
128*67e74705SXin Li
129*67e74705SXin Li struct MixedCCStaticOverload {
130*67e74705SXin Li static void overloaded(int a);
131*67e74705SXin Li static void __stdcall overloaded(short a);
132*67e74705SXin Li };
133*67e74705SXin Li
overloaded(int a)134*67e74705SXin Li void MixedCCStaticOverload::overloaded(int a) {}
overloaded(short a)135*67e74705SXin Li void MixedCCStaticOverload::overloaded(short a) {}
136*67e74705SXin Li
137*67e74705SXin Li // Friend function decls are cdecl by default, not thiscall. Friend method
138*67e74705SXin Li // decls should always be redeclarations, because the class cannot be
139*67e74705SXin Li // incomplete.
140*67e74705SXin Li struct FriendClass {
friend_methodFriendClass141*67e74705SXin Li void friend_method() {}
142*67e74705SXin Li };
friend_stdcall1()143*67e74705SXin Li void __stdcall friend_stdcall1() {}
144*67e74705SXin Li class MakeFriendDecls {
145*67e74705SXin Li int x;
146*67e74705SXin Li friend void FriendClass::friend_method();
147*67e74705SXin Li friend void friend_default();
148*67e74705SXin Li friend void friend_stdcall1();
149*67e74705SXin Li friend void __stdcall friend_stdcall2();
150*67e74705SXin Li friend void friend_stdcall3(); // expected-note {{previous declaration is here}}
151*67e74705SXin Li };
friend_default()152*67e74705SXin Li void friend_default() {}
friend_stdcall3()153*67e74705SXin Li void __stdcall friend_stdcall3() {} // expected-error {{function declared 'stdcall' here was previously declared without calling convention}}
friend_stdcall2()154*67e74705SXin Li void __stdcall friend_stdcall2() {}
155*67e74705SXin Li
156*67e74705SXin Li // Test functions with multiple attributes.
157*67e74705SXin Li void __attribute__((noreturn)) __stdcall __attribute__((regparm(1))) multi_attribute(int x);
multi_attribute(int x)158*67e74705SXin Li void multi_attribute(int x) { __builtin_unreachable(); }
159*67e74705SXin Li
160*67e74705SXin Li
161*67e74705SXin Li // expected-error@+3 {{vectorcall and cdecl attributes are not compatible}}
162*67e74705SXin Li // expected-error@+2 {{stdcall and cdecl attributes are not compatible}}
163*67e74705SXin Li // expected-error@+1 {{fastcall and cdecl attributes are not compatible}}
164*67e74705SXin Li void __cdecl __cdecl __stdcall __cdecl __fastcall __vectorcall multi_cc(int x);
165*67e74705SXin Li
StdcallTemplate(T)166*67e74705SXin Li template <typename T> void __stdcall StdcallTemplate(T) {}
StdcallTemplate(int)167*67e74705SXin Li template <> void StdcallTemplate<int>(int) {}
StdcallTemplate(short)168*67e74705SXin Li template <> void __stdcall StdcallTemplate<short>(short) {}
169*67e74705SXin Li
170*67e74705SXin Li // FIXME: Note the template, not the implicit instantiation.
171*67e74705SXin Li // expected-error@+2 {{function declared 'cdecl' here was previously declared 'stdcall}}
172*67e74705SXin Li // expected-note@+1 {{previous declaration is here}}
StdcallTemplate(long)173*67e74705SXin Li template <> void __cdecl StdcallTemplate<long>(long) {}
174*67e74705SXin Li
175*67e74705SXin Li struct ExactlyInt {
cast_to_intExactlyInt176*67e74705SXin Li template <typename T> static int cast_to_int(T) {
177*67e74705SXin Li return T::this_is_not_an_int();
178*67e74705SXin Li }
179*67e74705SXin Li };
cast_to_int(int x)180*67e74705SXin Li template <> inline int ExactlyInt::cast_to_int<int>(int x) { return x; }
181*67e74705SXin Li
182*67e74705SXin Li namespace test2 {
183*67e74705SXin Li class foo {
184*67e74705SXin Li template <typename T> void bar(T v);
185*67e74705SXin Li };
186*67e74705SXin Li extern template void foo::bar(const void *);
187*67e74705SXin Li }
188*67e74705SXin Li
189*67e74705SXin Li namespace test3 {
190*67e74705SXin Li struct foo {
191*67e74705SXin Li typedef void bar();
192*67e74705SXin Li };
193*67e74705SXin Li bool zed(foo::bar *);
bah()194*67e74705SXin Li void bah() {}
baz()195*67e74705SXin Li void baz() { zed(bah); }
196*67e74705SXin Li }
197*67e74705SXin Li
198*67e74705SXin Li namespace test4 {
199*67e74705SXin Li class foo {
200*67e74705SXin Li template <typename T> static void bar(T v);
201*67e74705SXin Li };
202*67e74705SXin Li extern template void foo::bar(const void *);
203*67e74705SXin Li }
204*67e74705SXin Li
205*67e74705SXin Li namespace test5 {
206*67e74705SXin Li template <class T>
207*67e74705SXin Li class valarray {
208*67e74705SXin Li void bar();
209*67e74705SXin Li };
210*67e74705SXin Li extern template void valarray<int>::bar();
211*67e74705SXin Li }
212*67e74705SXin Li
213*67e74705SXin Li namespace test6 {
214*67e74705SXin Li struct foo {
215*67e74705SXin Li int bar();
216*67e74705SXin Li };
217*67e74705SXin Li typedef int bar_t();
zed(bar_t foo::*)218*67e74705SXin Li void zed(bar_t foo::*) {
219*67e74705SXin Li }
baz()220*67e74705SXin Li void baz() {
221*67e74705SXin Li zed(&foo::bar);
222*67e74705SXin Li }
223*67e74705SXin Li }
224*67e74705SXin Li
225*67e74705SXin Li namespace test7 {
226*67e74705SXin Li template <typename T>
227*67e74705SXin Li struct S {
ftest7::S228*67e74705SXin Li void f(T t) {
229*67e74705SXin Li t = 42;
230*67e74705SXin Li }
231*67e74705SXin Li };
232*67e74705SXin Li template<> void S<void*>::f(void*);
g(S<void * > s,void * p)233*67e74705SXin Li void g(S<void*> s, void* p) {
234*67e74705SXin Li s.f(p);
235*67e74705SXin Li }
236*67e74705SXin Li }
237*67e74705SXin Li
238*67e74705SXin Li namespace test8 {
239*67e74705SXin Li template <typename T>
240*67e74705SXin Li struct S {
ftest8::S241*67e74705SXin Li void f(T t) { // expected-note {{previous declaration is here}}
242*67e74705SXin Li t = 42; // expected-error {{assigning to 'void *' from incompatible type 'int'}}
243*67e74705SXin Li }
244*67e74705SXin Li };
245*67e74705SXin Li template<> void __cdecl S<void*>::f(void*); // expected-error {{function declared 'cdecl' here was previously declared without calling convention}}
g(S<void * > s,void * p)246*67e74705SXin Li void g(S<void*> s, void* p) {
247*67e74705SXin Li s.f(p); // expected-note {{in instantiation of member function 'test8::S<void *>::f' requested here}}
248*67e74705SXin Li }
249*67e74705SXin Li }
250*67e74705SXin Li
251*67e74705SXin Li namespace test9 {
252*67e74705SXin Li // Used to fail when we forgot to make lambda call operators use __thiscall.
253*67e74705SXin Li template <typename F>
deduce(F f)254*67e74705SXin Li decltype(auto) deduce(F f) {
255*67e74705SXin Li return &decltype(f)::operator();
256*67e74705SXin Li }
257*67e74705SXin Li template <typename C, typename R, typename A>
signaturehelper(R (C::* f)(A)const)258*67e74705SXin Li decltype(auto) signaturehelper(R (C::*f)(A) const) {
259*67e74705SXin Li return R();
260*67e74705SXin Li }
f()261*67e74705SXin Li void f() {
262*67e74705SXin Li auto l = [](int x) { return x * 2; };
263*67e74705SXin Li decltype(signaturehelper(deduce(l))) p;
264*67e74705SXin Li }
265*67e74705SXin Li }
266