xref: /minix3/external/bsd/llvm/dist/clang/test/CodeGenCXX/mangle-ms-templates.cpp (revision eda6f5931d42c77e1480347b1fc3eef2f8d33806)
1 // RUN: %clang_cc1 -std=c++11 -emit-llvm %s -o - -cxx-abi microsoft -fms-extensions -fdelayed-template-parsing -triple=i386-pc-win32 | FileCheck %s
2 // RUN: %clang_cc1 -std=c++11 -emit-llvm %s -o - -cxx-abi microsoft -fms-extensions -fdelayed-template-parsing -triple=x86_64-pc-win32 | FileCheck -check-prefix X64 %s
3 
4 template<typename T>
5 class Class {
6  public:
7   Class() {}
8 };
9 
10 class Typename { };
11 
12 template<typename T>
13 class Nested { };
14 
15 template<bool flag>
16 class BoolTemplate {
17  public:
18   BoolTemplate() {}
19 };
20 
21 template<int param>
22 class IntTemplate {
23  public:
24   IntTemplate() {}
25 };
26 
27 template<>
28 class BoolTemplate<true> {
29  public:
30   BoolTemplate() {}
31   template<class T> void Foo(T arg) {}
32 };
33 
34 void template_mangling() {
35   Class<Typename> c1;
36 // CHECK: call {{.*}} @"\01??0?$Class@VTypename@@@@QAE@XZ"
37 // X64: call {{.*}} @"\01??0?$Class@VTypename@@@@QEAA@XZ"
38 
39   Class<const Typename> c1_const;
40 // CHECK: call {{.*}} @"\01??0?$Class@$$CBVTypename@@@@QAE@XZ"
41 // X64: call {{.*}} @"\01??0?$Class@$$CBVTypename@@@@QEAA@XZ"
42   Class<volatile Typename> c1_volatile;
43 // CHECK: call {{.*}} @"\01??0?$Class@$$CCVTypename@@@@QAE@XZ"
44 // X64: call {{.*}} @"\01??0?$Class@$$CCVTypename@@@@QEAA@XZ"
45   Class<const volatile Typename> c1_cv;
46 // CHECK: call {{.*}} @"\01??0?$Class@$$CDVTypename@@@@QAE@XZ"
47 // X64: call {{.*}} @"\01??0?$Class@$$CDVTypename@@@@QEAA@XZ"
48 
49   Class<Nested<Typename> > c2;
50 // CHECK: call {{.*}} @"\01??0?$Class@V?$Nested@VTypename@@@@@@QAE@XZ"
51 // X64: call {{.*}} @"\01??0?$Class@V?$Nested@VTypename@@@@@@QEAA@XZ"
52 
53   Class<int * const> c_intpc;
54 // CHECK: call {{.*}} @"\01??0?$Class@QAH@@QAE@XZ"
55 // X64: call {{.*}} @"\01??0?$Class@QEAH@@QEAA@XZ"
56   Class<int()> c_ft;
57 // CHECK: call {{.*}} @"\01??0?$Class@$$A6AHXZ@@QAE@XZ"
58 // X64: call {{.*}} @"\01??0?$Class@$$A6AHXZ@@QEAA@XZ"
59   Class<int[]> c_inti;
60 // CHECK: call {{.*}} @"\01??0?$Class@$$BY0A@H@@QAE@XZ"
61 // X64: call {{.*}} @"\01??0?$Class@$$BY0A@H@@QEAA@XZ"
62   Class<int[5]> c_int5;
63 // CHECK: call {{.*}} @"\01??0?$Class@$$BY04H@@QAE@XZ"
64 // X64: call {{.*}} @"\01??0?$Class@$$BY04H@@QEAA@XZ"
65   Class<const int[5]> c_intc5;
66 // CHECK: call {{.*}} @"\01??0?$Class@$$BY04$$CBH@@QAE@XZ"
67 // X64: call {{.*}} @"\01??0?$Class@$$BY04$$CBH@@QEAA@XZ"
68   Class<int * const[5]> c_intpc5;
69 // CHECK: call {{.*}} @"\01??0?$Class@$$BY04QAH@@QAE@XZ"
70 // X64: call {{.*}} @"\01??0?$Class@$$BY04QEAH@@QEAA@XZ"
71 
72   BoolTemplate<false> _false;
73 // CHECK: call {{.*}} @"\01??0?$BoolTemplate@$0A@@@QAE@XZ"
74 // X64: call {{.*}} @"\01??0?$BoolTemplate@$0A@@@QEAA@XZ"
75 
76   BoolTemplate<true> _true;
77   // PR13158
78   _true.Foo(1);
79 // CHECK: call {{.*}} @"\01??0?$BoolTemplate@$00@@QAE@XZ"
80 // X64: call {{.*}} @"\01??0?$BoolTemplate@$00@@QEAA@XZ"
81 // CHECK: call {{.*}} @"\01??$Foo@H@?$BoolTemplate@$00@@QAEXH@Z"
82 // X64: call {{.*}} @"\01??$Foo@H@?$BoolTemplate@$00@@QEAAXH@Z"
83 
84   IntTemplate<0> zero;
85 // CHECK: call {{.*}} @"\01??0?$IntTemplate@$0A@@@QAE@XZ"
86 // X64: call {{.*}} @"\01??0?$IntTemplate@$0A@@@QEAA@XZ"
87 
88   IntTemplate<5> five;
89 // CHECK: call {{.*}} @"\01??0?$IntTemplate@$04@@QAE@XZ"
90 // X64: call {{.*}} @"\01??0?$IntTemplate@$04@@QEAA@XZ"
91 
92   IntTemplate<11> eleven;
93 // CHECK: call {{.*}} @"\01??0?$IntTemplate@$0L@@@QAE@XZ"
94 // X64: call {{.*}} @"\01??0?$IntTemplate@$0L@@@QEAA@XZ"
95 
96   IntTemplate<256> _256;
97 // CHECK: call {{.*}} @"\01??0?$IntTemplate@$0BAA@@@QAE@XZ"
98 // X64: call {{.*}} @"\01??0?$IntTemplate@$0BAA@@@QEAA@XZ"
99 
100   IntTemplate<513> _513;
101 // CHECK: call {{.*}} @"\01??0?$IntTemplate@$0CAB@@@QAE@XZ"
102 // X64: call {{.*}} @"\01??0?$IntTemplate@$0CAB@@@QEAA@XZ"
103 
104   IntTemplate<1026> _1026;
105 // CHECK: call {{.*}} @"\01??0?$IntTemplate@$0EAC@@@QAE@XZ"
106 // X64: call {{.*}} @"\01??0?$IntTemplate@$0EAC@@@QEAA@XZ"
107 
108   IntTemplate<65535> ffff;
109 // CHECK: call {{.*}} @"\01??0?$IntTemplate@$0PPPP@@@QAE@XZ"
110 // X64: call {{.*}} @"\01??0?$IntTemplate@$0PPPP@@@QEAA@XZ"
111 }
112 
113 namespace space {
114   template<class T> const T& foo(const T& l) { return l; }
115 }
116 // CHECK: "\01??$foo@H@space@@YAABHABH@Z"
117 // X64: "\01??$foo@H@space@@YAAEBHAEBH@Z"
118 
119 void use() {
120   space::foo(42);
121 }
122 
123 // PR13455
124 typedef void (*FunctionPointer)(void);
125 
126 template <FunctionPointer function>
127 void FunctionPointerTemplate() {
128   function();
129 }
130 
131 void spam() {
132   FunctionPointerTemplate<spam>();
133 // CHECK: "\01??$FunctionPointerTemplate@$1?spam@@YAXXZ@@YAXXZ"
134 // X64: "\01??$FunctionPointerTemplate@$1?spam@@YAXXZ@@YAXXZ"
135 }
136 
137 // Unlike Itanium, there is no character code to indicate an argument pack.
138 // Tested with MSVC 2013, the first version which supports variadic templates.
139 
140 template <typename ...Ts> void variadic_fn_template(const Ts &...args) { }
141 void variadic_fn_instantiate() {
142   variadic_fn_template(0, 1, 3, 4);
143   variadic_fn_template(0, 1, 'a', "b");
144 }
145 // CHECK: "\01??$variadic_fn_template@HHHH@@YAXABH000@Z"
146 // CHECK: "\01??$variadic_fn_template@HHD$$BY01D@@YAXABH0ABDAAY01$$CBD@Z"
147 
148 template <typename ...Ts>
149 struct VariadicClass {
150   VariadicClass() { }
151   int x;
152 };
153 void variadic_class_instantiate() {
154   VariadicClass<int, char, bool> a;
155   VariadicClass<bool, char, int> b;
156 }
157 // CHECK: call {{.*}} @"\01??0?$VariadicClass@HD_N@@QAE@XZ"
158 // CHECK: call {{.*}} @"\01??0?$VariadicClass@_NDH@@QAE@XZ"
159 
160 template <typename T>
161 struct Second {};
162 
163 template <typename T, template <class> class>
164 struct Type {};
165 
166 template <template <class> class T>
167 struct Type2 {};
168 
169 template <template <class> class T, bool B>
170 struct Thing;
171 
172 template <template <class> class T>
173 struct Thing<T, false> { };
174 
175 template <template <class> class T>
176 struct Thing<T, true> { };
177 
178 void template_template_fun(Type<Thing<Second, true>, Second>) { }
179 // CHECK: "\01?template_template_fun@@YAXU?$Type@U?$Thing@USecond@@$00@@USecond@@@@@Z"
180 
181 template <typename T>
182 void template_template_specialization();
183 
184 template <>
185 void template_template_specialization<void (Type<Thing<Second, true>, Second>)>() {
186 }
187 // CHECK: "\01??$template_template_specialization@$$A6AXU?$Type@U?$Thing@USecond@@$00@@USecond@@@@@Z@@YAXXZ"
188 
189 // PR16788
190 template <decltype(nullptr)> struct S1 {};
191 void f(S1<nullptr>) {}
192 // CHECK: "\01?f@@YAXU?$S1@$0A@@@@Z"
193 
194 struct record {
195   int first;
196   int second;
197 };
198 template <const record &>
199 struct type1 {
200 };
201 extern const record inst;
202 void recref(type1<inst>) {}
203 // CHECK: "\01?recref@@YAXU?$type1@$E?inst@@3Urecord@@B@@@Z"
204 
205 struct _GUID {};
206 struct __declspec(uuid("{12345678-1234-1234-1234-1234567890aB}")) uuid;
207 
208 template <typename T, const _GUID *G = &__uuidof(T)>
209 struct UUIDType1 {};
210 
211 template <typename T, const _GUID &G = __uuidof(T)>
212 struct UUIDType2 {};
213 
214 void fun(UUIDType1<uuid> a) {}
215 // CHECK: "\01?fun@@YAXU?$UUIDType1@Uuuid@@$1?_GUID_12345678_1234_1234_1234_1234567890ab@@3U__s_GUID@@B@@@Z"
216 void fun(UUIDType2<uuid> b) {}
217 // CHECK: "\01?fun@@YAXU?$UUIDType2@Uuuid@@$E?_GUID_12345678_1234_1234_1234_1234567890ab@@3U__s_GUID@@B@@@Z"
218 
219 template <typename T> struct TypeWithFriendDefinition {
220   friend void FunctionDefinedWithInjectedName(TypeWithFriendDefinition<T>) {}
221 };
222 // CHECK: call {{.*}} @"\01?FunctionDefinedWithInjectedName@@YAXU?$TypeWithFriendDefinition@H@@@Z"
223 void CallFunctionDefinedWithInjectedName() {
224   FunctionDefinedWithInjectedName(TypeWithFriendDefinition<int>());
225 }
226 // CHECK: @"\01?FunctionDefinedWithInjectedName@@YAXU?$TypeWithFriendDefinition@H@@@Z"
227