blob: 9e85e62cf88ecc02391af6a9149186b0064d2c38 [file] [log] [blame]
Timur Iskhodzhanovf2afe632013-02-22 12:42:50 +00001// RUN: %clang_cc1 -triple i686-pc-win32 -cxx-abi microsoft -fms-extensions -verify %s
2
3// Pointers to free functions
4void free_func_default();
5void __cdecl free_func_cdecl();
6void __stdcall free_func_stdcall(); // expected-note {{previous declaration is here}}
7void __fastcall free_func_fastcall(); // expected-note 2 {{previous declaration is here}}
8
9void __cdecl free_func_default(); // expected-note 2 {{previous declaration is here}}
10void __stdcall free_func_default(); // expected-error {{function declared 'stdcall' here was previously declared without calling convention}}
11void __fastcall free_func_default(); // expected-error {{function declared 'fastcall' here was previously declared without calling convention}}
12
13void free_func_cdecl(); // expected-note 2 {{previous declaration is here}}
14void __stdcall free_func_cdecl(); // expected-error {{function declared 'stdcall' here was previously declared 'cdecl'}}
15void __fastcall free_func_cdecl(); // expected-error {{function declared 'fastcall' here was previously declared 'cdecl'}}
16
17void __cdecl free_func_stdcall(); // expected-error {{function declared 'cdecl' here was previously declared 'stdcall'}}
18void free_func_stdcall(); // expected-note {{previous declaration is here}}
19void __fastcall free_func_stdcall(); // expected-error {{function declared 'fastcall' here was previously declared 'stdcall'}}
20
21void __cdecl free_func_fastcall(); // expected-error {{function declared 'cdecl' here was previously declared 'fastcall'}}
22void __stdcall free_func_fastcall(); // expected-error {{function declared 'stdcall' here was previously declared 'fastcall'}}
23void free_func_fastcall();
24
25// Overloaded functions may have different calling conventions
26void __fastcall free_func_default(int);
27void __cdecl free_func_default(int *);
28
29void __thiscall free_func_cdecl(char *);
30void __cdecl free_func_cdecl(double);
31
Reid Klecknera09e44c2013-07-31 21:00:18 +000032typedef void void_fun_t();
33typedef void __cdecl cdecl_fun_t();
Timur Iskhodzhanovf2afe632013-02-22 12:42:50 +000034
35// Pointers to member functions
36struct S {
37 void member_default1(); // expected-note {{previous declaration is here}}
38 void member_default2();
39 void __cdecl member_cdecl1();
40 void __cdecl member_cdecl2(); // expected-note {{previous declaration is here}}
41 void __thiscall member_thiscall1();
42 void __thiscall member_thiscall2(); // expected-note {{previous declaration is here}}
Reid Klecknera09e44c2013-07-31 21:00:18 +000043
44 // Unless attributed, typedefs carry no calling convention and use the default
45 // based on context.
46 void_fun_t member_typedef_default; // expected-note {{previous declaration is here}}
47 cdecl_fun_t member_typedef_cdecl; // expected-note {{previous declaration is here}}
48 __stdcall void_fun_t member_typedef_stdcall;
49
Timur Iskhodzhanovf2afe632013-02-22 12:42:50 +000050 // Static member functions can't be __thiscall
51 static void static_member_default1();
52 static void static_member_default2(); // expected-note {{previous declaration is here}}
53 static void __cdecl static_member_cdecl1();
54 static void __cdecl static_member_cdecl2(); // expected-note {{previous declaration is here}}
55 static void __stdcall static_member_stdcall1();
56 static void __stdcall static_member_stdcall2();
57
58 // Variadic functions can't be other than default or __cdecl
59 void member_variadic_default(int x, ...);
60 void __cdecl member_variadic_cdecl(int x, ...);
61
62 static void static_member_variadic_default(int x, ...);
63 static void __cdecl static_member_variadic_cdecl(int x, ...);
64};
65
66void __cdecl S::member_default1() {} // expected-error {{function declared 'cdecl' here was previously declared without calling convention}}
67void __thiscall S::member_default2() {}
68
Reid Klecknera09e44c2013-07-31 21:00:18 +000069void __cdecl S::member_typedef_default() {} // expected-error {{function declared 'cdecl' here was previously declared without calling convention}}
70void __thiscall S::member_typedef_cdecl() {} // expected-error {{function declared 'thiscall' here was previously declared 'cdecl'}}
71void __stdcall S::member_typedef_stdcall() {}
72
Timur Iskhodzhanovf2afe632013-02-22 12:42:50 +000073void S::member_cdecl1() {}
74void __thiscall S::member_cdecl2() {} // expected-error {{function declared 'thiscall' here was previously declared 'cdecl'}}
75
76void S::member_thiscall1() {}
77void __cdecl S::member_thiscall2() {} // expected-error {{function declared 'cdecl' here was previously declared 'thiscall'}}
78
79void __cdecl S::static_member_default1() {}
80void __stdcall S::static_member_default2() {} // expected-error {{function declared 'stdcall' here was previously declared without calling convention}}
81
82void S::static_member_cdecl1() {}
83void __stdcall S::static_member_cdecl2() {} // expected-error {{function declared 'stdcall' here was previously declared 'cdecl'}}
84
85void __cdecl S::member_variadic_default(int x, ...) {
86 (void)x;
87}
88void S::member_variadic_cdecl(int x, ...) {
89 (void)x;
90}
91
92void __cdecl S::static_member_variadic_default(int x, ...) {
93 (void)x;
94}
95void S::static_member_variadic_cdecl(int x, ...) {
96 (void)x;
97}
98
Reid Klecknera09e44c2013-07-31 21:00:18 +000099// Declare a template using a calling convention.
100template <class CharT> inline int __cdecl mystrlen(const CharT *str) {
101 int i;
102 for (i = 0; str[i]; i++) { }
103 return i;
104}
105extern int sse_strlen(const char *str);
106template <> inline int __cdecl mystrlen(const char *str) {
107 return sse_strlen(str);
108}
109void use_tmpl(const char *str, const int *ints) {
110 mystrlen(str);
111 mystrlen(ints);
112}