1 // RUN: %clang_cc1 -fms-extensions -fblocks -emit-llvm %s -o - -cxx-abi microsoft -triple=i386-pc-win32 | FileCheck %s
2 // RUN: %clang_cc1 -fms-compatibility -fblocks -emit-llvm %s -o - -cxx-abi microsoft -triple=x86_64-pc-win32 | FileCheck -check-prefix X64 %s
3 
4 // CHECK: @"\01?a@@3HA"
5 // CHECK: @"\01?b@N@@3HA"
6 // CHECK: @"\01?anonymous@?A@N@@3HA"
7 // CHECK: @c
8 // CHECK: @"\01?d@foo@@0FB"
9 // CHECK: @"\01?e@foo@@1JC"
10 // CHECK: @"\01?f@foo@@2DD"
11 // CHECK: @"\01?g@bar@@2HA"
12 // CHECK: @"\01?h1@@3QAHA"
13 // CHECK: @"\01?h2@@3QBHB"
14 // CHECK: @"\01?i@@3PAY0BE@HA"
15 // CHECK: @"\01?j@@3P6GHCE@ZA"
16 // CHECK: @"\01?k@@3PTfoo@@DA"
17 // CHECK: @"\01?l@@3P8foo@@AEHH@ZA"
18 // CHECK: @"\01?color1@@3PANA"
19 // CHECK: @"\01?color2@@3QBNB"
20 
21 // FIXME: The following three tests currently fail, see http://llvm.org/PR13182
22 // Replace "CHECK-NOT" with "CHECK" when it is fixed.
23 // CHECK-NOT: @"\01?color3@@3QAY02$$CBNA"
24 // CHECK-NOT: @"\01?color4@@3QAY02$$CBNA"
25 
26 int a;
27 
28 namespace N {
29   int b;
30 
31   namespace {
32     int anonymous;
33   }
34 }
35 
36 static int c;
37 int _c(void) {return N::anonymous + c;}
38 // CHECK: @"\01?_c@@YAHXZ"
39 
40 class foo {
41   static const short d;
42 protected:
43   static volatile long e;
44 public:
45   static const volatile char f;
46   int operator+(int a);
47   foo(){}
48 //CHECK: @"\01??0foo@@QAE@XZ"
49 
50   ~foo(){}
51 //CHECK: @"\01??1foo@@QAE@XZ"
52 
53   foo(int i){}
54 //CHECK: @"\01??0foo@@QAE@H@Z"
55 
56   foo(char *q){}
57 //CHECK: @"\01??0foo@@QAE@PAD@Z"
58 
59   static foo* static_method() { return 0; }
60 
61 }f,s1(1),s2((char*)0);
62 
63 typedef foo (foo2);
64 
65 struct bar {
66   static int g;
67 };
68 
69 union baz {
70   int a;
71   char b;
72   double c;
73 };
74 
75 enum quux {
76   qone,
77   qtwo,
78   qthree
79 };
80 
81 foo bar() { return foo(); }
82 //CHECK: @"\01?bar@@YA?AVfoo@@XZ"
83 
84 int foo::operator+(int a) {
85 //CHECK: @"\01??Hfoo@@QAEHH@Z"
86 
87   foo::static_method();
88 //CHECK: @"\01?static_method@foo@@SAPAV1@XZ"
89   bar();
90   return a;
91 }
92 
93 const short foo::d = 0;
94 volatile long foo::e;
95 const volatile char foo::f = 'C';
96 
97 int bar::g;
98 
99 extern int * const h1 = &a;
100 extern const int * const h2 = &a;
101 
102 int i[10][20];
103 
104 int (__stdcall *j)(signed char, unsigned char);
105 
106 const volatile char foo2::*k;
107 
108 int (foo2::*l)(int);
109 
110 // Static functions are mangled, too.
111 // Also make sure calling conventions, arglists, and throw specs work.
112 static void __stdcall alpha(float a, double b) throw() {}
113 bool __fastcall beta(long long a, wchar_t b) throw(signed char, unsigned char) {
114 // CHECK: @"\01?beta@@YI_N_J_W@Z"
115   alpha(0.f, 0.0);
116   return false;
117 }
118 
119 // CHECK: @"\01?alpha@@YGXMN@Z"
120 // X64: @"\01?alpha@@YAXMN@Z"
121 
122 // Make sure tag-type mangling works.
123 void gamma(class foo, struct bar, union baz, enum quux) {}
124 // CHECK: @"\01?gamma@@YAXVfoo@@Ubar@@Tbaz@@W4quux@@@Z"
125 
126 // Make sure pointer/reference-type mangling works.
127 void delta(int * const a, const long &) {}
128 // CHECK: @"\01?delta@@YAXQAHABJ@Z"
129 
130 // Array mangling.
131 void epsilon(int a[][10][20]) {}
132 // CHECK: @"\01?epsilon@@YAXQAY19BE@H@Z"
133 
134 void zeta(int (*)(int, int)) {}
135 // CHECK: @"\01?zeta@@YAXP6AHHH@Z@Z"
136 
137 // Blocks mangling (Clang extension). A block should be mangled slightly
138 // differently from a similar function pointer.
139 void eta(int (^)(int, int)) {}
140 // CHECK: @"\01?eta@@YAXP_EAHHH@Z@Z"
141 
142 typedef int theta_arg(int,int);
143 void theta(theta_arg^ block) {}
144 // CHECK: @"\01?theta@@YAXP_EAHHH@Z@Z"
145 
146 void operator_new_delete() {
147   char *ptr = new char;
148 // CHECK: @"\01??2@YAPAXI@Z"
149 
150   delete ptr;
151 // CHECK: @"\01??3@YAXPAX@Z"
152 
153   char *array = new char[42];
154 // CHECK: @"\01??_U@YAPAXI@Z"
155 
156   delete [] array;
157 // CHECK: @"\01??_V@YAXPAX@Z"
158 }
159 
160 // PR13022
161 void (redundant_parens)();
162 void redundant_parens_use() { redundant_parens(); }
163 // CHECK: @"\01?redundant_parens@@YAXXZ"
164 
165 // PR13047
166 typedef double RGB[3];
167 RGB color1;
168 extern const RGB color2 = {};
169 extern RGB const color3[5] = {};
170 extern RGB const ((color4)[5]) = {};
171 
172 // PR12603
173 enum E {};
174 // CHECK: "\01?fooE@@YA?AW4E@@XZ"
175 E fooE() { return E(); }
176 
177 class X {};
178 // CHECK: "\01?fooX@@YA?AVX@@XZ"
179 X fooX() { return X(); }
180 
181 namespace PR13182 {
182   extern char s0[];
183   // CHECK: @"\01?s0@PR13182@@3PADA"
184   extern char s1[42];
185   // CHECK: @"\01?s1@PR13182@@3PADA"
186   extern const char s2[];
187   // CHECK: @"\01?s2@PR13182@@3QBDB"
188   extern const char s3[42];
189   // CHECK: @"\01?s3@PR13182@@3QBDB"
190   extern volatile char s4[];
191   // CHECK: @"\01?s4@PR13182@@3RCDC"
192   extern const volatile char s5[];
193   // CHECK: @"\01?s5@PR13182@@3SDDD"
194   extern const char* const* s6;
195   // CHECK: @"\01?s6@PR13182@@3PBQBDB"
196 
197   char foo() {
198     return s0[0] + s1[0] + s2[0] + s3[0] + s4[0] + s5[0] + s6[0][0];
199   }
200 }
201