1 // RUN: %clang_cc1 -std=c++11 -emit-llvm %s -o - -cxx-abi microsoft -triple=i386-pc-win32 | FileCheck %s
2 // RUN: %clang_cc1 -std=c++11 -emit-llvm %s -o - -cxx-abi microsoft -triple=x86_64-pc-win32 | FileCheck -check-prefix X64 %s
3
4 template<typename T>
5 class Class {
6 public:
Class()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:
BoolTemplate()18 BoolTemplate() {}
19 };
20
21 template<int param>
22 class IntTemplate {
23 public:
IntTemplate()24 IntTemplate() {}
25 };
26
27 template<>
28 class BoolTemplate<true> {
29 public:
BoolTemplate()30 BoolTemplate() {}
Foo(T arg)31 template<class T> void Foo(T arg) {}
32 };
33
template_mangling()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 {
foo(const T & l)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
use()119 void use() {
120 space::foo(42);
121 }
122
123 // PR13455
124 typedef void (*FunctionPointer)(void);
125
126 template <FunctionPointer function>
FunctionPointerTemplate()127 void FunctionPointerTemplate() {
128 function();
129 }
130
spam()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
variadic_fn_template(const Ts &...args)140 template <typename ...Ts> void variadic_fn_template(const Ts &...args) { }
variadic_fn_instantiate()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 {
VariadicClassVariadicClass150 VariadicClass() { }
151 int x;
152 };
variadic_class_instantiate()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
template_template_fun(Type<Thing<Second,true>,Second>)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 <>
template_template_specialization()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 {};
f(S1<nullptr>)191 void f(S1<nullptr>) {}
192 // CHECK: "\01?f@@YAXU?$S1@$0A@@@@Z"
193