blob: 60edc42bc97243d585455278e4339c1ed2e93115 [file] [log] [blame]
John McCallad5e7382010-03-01 23:49:17 +00001// RUN: %clang_cc1 -emit-llvm %s -o - -triple=x86_64-apple-darwin9 -fblocks -std=c++0x | FileCheck %s
Douglas Gregor5f2bfd42009-02-13 00:10:09 +00002struct X { };
3struct Y { };
Anders Carlssonb1d947b2009-03-07 23:57:03 +00004
Anders Carlsson9234b7f2009-09-17 03:46:43 +00005// CHECK: @unmangled_variable = global
6// CHECK: @_ZN1N1iE = global
7// CHECK: @_ZZN1N1fEiiE1b = internal global
8// CHECK: @_ZZN1N1gEvE1a = internal global
9// CHECK: @_ZGVZN1N1gEvE1a = internal global
10
Sean Hunt31455252010-01-24 03:04:27 +000011//CHECK: @pr5966_i = external global
12//CHECK: @_ZL8pr5966_i = internal global
13
Anders Carlsson9234b7f2009-09-17 03:46:43 +000014// CHECK: define zeroext i1 @_ZplRK1YRA100_P1X
Douglas Gregor5f2bfd42009-02-13 00:10:09 +000015bool operator+(const Y&, X* (&xs)[100]) { return false; }
16
Anders Carlsson9234b7f2009-09-17 03:46:43 +000017// CHECK: define void @_Z1f1s
Anders Carlssonb1d947b2009-03-07 23:57:03 +000018typedef struct { int a; } s;
19void f(s) { }
20
Anders Carlsson9234b7f2009-09-17 03:46:43 +000021// CHECK: define void @_Z1f1e
Anders Carlssonb1d947b2009-03-07 23:57:03 +000022typedef enum { foo } e;
23void f(e) { }
24
Anders Carlsson9234b7f2009-09-17 03:46:43 +000025// CHECK: define void @_Z1f1u
Anders Carlssonb1d947b2009-03-07 23:57:03 +000026typedef union { int a; } u;
27void f(u) { }
Anders Carlsson4843e582009-03-10 17:07:44 +000028
Anders Carlsson9234b7f2009-09-17 03:46:43 +000029// CHECK: define void @_Z1f1x
Anders Carlsson4843e582009-03-10 17:07:44 +000030typedef struct { int a; } x,y;
31void f(y) { }
32
Anders Carlsson9234b7f2009-09-17 03:46:43 +000033// CHECK: define void @_Z1fv
Anders Carlssonc6c91bc2009-04-01 00:15:23 +000034void f() { }
Anders Carlsson984e0682009-04-01 00:58:25 +000035
Anders Carlsson9234b7f2009-09-17 03:46:43 +000036// CHECK: define void @_ZN1N1fEv
Anders Carlsson984e0682009-04-01 00:58:25 +000037namespace N { void f() { } }
38
Anders Carlsson9234b7f2009-09-17 03:46:43 +000039// CHECK: define void @_ZN1N1N1fEv
Anders Carlsson984e0682009-04-01 00:58:25 +000040namespace N { namespace N { void f() { } } }
Anders Carlsson91e20dd2009-04-02 05:55:18 +000041
Anders Carlsson9234b7f2009-09-17 03:46:43 +000042// CHECK: define void @unmangled_function
Anders Carlsson91e20dd2009-04-02 05:55:18 +000043extern "C" { namespace N { void unmangled_function() { } } }
44
Anders Carlsson2928c212009-05-16 21:02:39 +000045extern "C" { namespace N { int unmangled_variable = 10; } }
Anders Carlsson91e20dd2009-04-02 05:55:18 +000046
Anders Carlsson329749c2009-04-02 16:05:20 +000047namespace N { int i; }
Anders Carlsson1b42c792009-04-02 16:24:45 +000048
Anders Carlsson1b42c792009-04-02 16:24:45 +000049namespace N { int f(int, int) { static int b; return b; } }
Anders Carlsson283a0622009-04-13 18:03:33 +000050
Anders Carlsson283a0622009-04-13 18:03:33 +000051namespace N { int h(); void g() { static int a = h(); } }
Chris Lattner2df9ced2009-04-30 02:43:43 +000052
Anders Carlsson9234b7f2009-09-17 03:46:43 +000053// CHECK: define void @_Z1fno
Chris Lattner2df9ced2009-04-30 02:43:43 +000054void f(__int128_t, __uint128_t) { }
Anders Carlsson7a0ba872009-05-15 16:09:15 +000055
56template <typename T> struct S1 {};
57
Anders Carlsson9234b7f2009-09-17 03:46:43 +000058// CHECK: define void @_Z1f2S1IiE
Anders Carlsson7a0ba872009-05-15 16:09:15 +000059void f(S1<int>) {}
60
Anders Carlsson9234b7f2009-09-17 03:46:43 +000061// CHECK: define void @_Z1f2S1IdE
Anders Carlsson7a0ba872009-05-15 16:09:15 +000062void f(S1<double>) {}
63
64template <int N> struct S2 {};
Anders Carlsson9234b7f2009-09-17 03:46:43 +000065// CHECK: define void @_Z1f2S2ILi100EE
Anders Carlsson7a0ba872009-05-15 16:09:15 +000066void f(S2<100>) {}
67
Anders Carlsson9234b7f2009-09-17 03:46:43 +000068// CHECK: define void @_Z1f2S2ILin100EE
Anders Carlsson7a0ba872009-05-15 16:09:15 +000069void f(S2<-100>) {}
70
71template <bool B> struct S3 {};
72
Anders Carlsson9234b7f2009-09-17 03:46:43 +000073// CHECK: define void @_Z1f2S3ILb1EE
Anders Carlsson7a0ba872009-05-15 16:09:15 +000074void f(S3<true>) {}
75
Anders Carlsson9234b7f2009-09-17 03:46:43 +000076// CHECK: define void @_Z1f2S3ILb0EE
Anders Carlsson7a0ba872009-05-15 16:09:15 +000077void f(S3<false>) {}
78
Anders Carlsson9234b7f2009-09-17 03:46:43 +000079// CHECK: define void @_Z2f22S3ILb1EE
Anders Carlsson7a0ba872009-05-15 16:09:15 +000080void f2(S3<100>) {}
Anders Carlsson0e650012009-05-17 17:41:20 +000081
82struct S;
83
Anders Carlsson9234b7f2009-09-17 03:46:43 +000084// CHECK: define void @_Z1fM1SKFvvE
Anders Carlsson0e650012009-05-17 17:41:20 +000085void f(void (S::*)() const) {}
86
Anders Carlsson9234b7f2009-09-17 03:46:43 +000087// CHECK: define void @_Z1fM1SFvvE
Anders Carlsson0e650012009-05-17 17:41:20 +000088void f(void (S::*)()) {}
Anders Carlssoncf85b932009-09-16 23:53:19 +000089
Anders Carlsson9234b7f2009-09-17 03:46:43 +000090// CHECK: define void @_Z1fi
Anders Carlssoncf85b932009-09-16 23:53:19 +000091void f(const int) { }
92
Anders Carlsson03c9d532009-09-17 04:02:31 +000093template<typename T, typename U> void ft1(U u, T t) { }
94
95template<typename T> void ft2(T t, void (*)(T), void (*)(T)) { }
Anders Carlsson9234b7f2009-09-17 03:46:43 +000096
Anders Carlsson7624f212009-09-18 02:42:01 +000097template<typename T, typename U = S1<T> > struct S4 { };
98template<typename T> void ft3(S4<T>*) { }
99
Anders Carlsson7482e242009-09-18 04:29:09 +0000100namespace NS {
101 template<typename T> void ft1(T) { }
Anders Carlsson7624f212009-09-18 02:42:01 +0000102}
103
Anders Carlssond553f8c2009-09-21 01:21:10 +0000104void g1() {
Anders Carlsson03c9d532009-09-17 04:02:31 +0000105 // CHECK: @_Z3ft1IidEvT0_T_
106 ft1<int, double>(1, 0);
107
108 // CHECK: @_Z3ft2IcEvT_PFvS0_ES2_
109 ft2<char>(1, 0, 0);
Anders Carlsson7624f212009-09-18 02:42:01 +0000110
111 // CHECK: @_Z3ft3IiEvP2S4IT_2S1IS1_EE
112 ft3<int>(0);
Anders Carlsson7482e242009-09-18 04:29:09 +0000113
114 // CHECK: @_ZN2NS3ft1IiEEvT_
115 NS::ft1<int>(1);
Anders Carlssond58d6f72009-09-17 16:12:20 +0000116}
Anders Carlsson7482e242009-09-18 04:29:09 +0000117
Anders Carlssond553f8c2009-09-21 01:21:10 +0000118// Expressions
119template<int I> struct S5 { };
120
121template<int I> void ft4(S5<I>) { }
122void g2() {
123 // CHECK: @_Z3ft4ILi10EEv2S5IXT_EE
124 ft4(S5<10>());
125
126 // CHECK: @_Z3ft4ILi20EEv2S5IXT_EE
127 ft4(S5<20>());
128}
129
Anders Carlsson7482e242009-09-18 04:29:09 +0000130extern "C++" {
131 // CHECK: @_Z1hv
132 void h() { }
133}
134
Anders Carlsson5cc58c62009-09-22 17:23:30 +0000135// PR5019
136extern "C" { struct a { int b; }; }
137
138// CHECK: @_Z1fP1a
139int f(struct a *x) {
140 return x->b;
141}
Anders Carlssonadd28822009-09-22 20:33:31 +0000142
143// PR5017
144extern "C" {
145struct Debug {
Anders Carlsson8257d412009-12-22 06:36:32 +0000146 const Debug& operator<< (unsigned a) const { return *this; }
Anders Carlssonadd28822009-09-22 20:33:31 +0000147};
148Debug dbg;
149// CHECK: @_ZNK5DebuglsEj
150int main(void) { dbg << 32 ;}
151}
Anders Carlssonae352482009-09-26 02:26:02 +0000152
153template<typename T> struct S6 {
154 typedef int B;
155};
156
157template<typename T> void ft5(typename S6<T>::B) { }
158// CHECK: @_Z3ft5IiEvN2S6IT_E1BE
159template void ft5<int>(int);
Anders Carlsson1668f202009-09-26 20:13:56 +0000160
161template<typename T> class A {};
162
163namespace NS {
164template<typename T> bool operator==(const A<T>&, const A<T>&) { return true; }
165}
166
Anders Carlssonaeb85372009-09-26 22:18:22 +0000167// CHECK: @_ZN2NSeqIcEEbRK1AIT_ES5_
Anders Carlsson1668f202009-09-26 20:13:56 +0000168template bool NS::operator==(const ::A<char>&, const ::A<char>&);
169
170namespace std {
171template<typename T> bool operator==(const A<T>&, const A<T>&) { return true; }
172}
173
174// CHECK: @_ZSteqIcEbRK1AIT_ES4_
175template bool std::operator==(const ::A<char>&, const ::A<char>&);
176
Anders Carlsson0ccdf8d2009-09-27 00:38:53 +0000177struct S {
178 typedef int U;
179};
180
181template <typename T> typename T::U ft6(const T&) { return 0; }
182
183// CHECK: @_Z3ft6I1SENT_1UERKS1_
184template int ft6<S>(const S&);
Anders Carlsson50755b02009-09-27 20:11:34 +0000185
John Wiegley20c0da72011-04-27 23:09:49 +0000186template<typename> struct __is_scalar_type {
Anders Carlsson50755b02009-09-27 20:11:34 +0000187 enum { __value = 1 };
188};
189
190template<bool, typename> struct __enable_if { };
191
192template<typename T> struct __enable_if<true, T> {
193 typedef T __type;
194};
195
196// PR5063
John Wiegley20c0da72011-04-27 23:09:49 +0000197template<typename T> typename __enable_if<__is_scalar_type<T>::__value, void>::__type ft7() { }
Anders Carlsson50755b02009-09-27 20:11:34 +0000198
John McCall26a6ec72011-06-21 22:12:46 +0000199// CHECK: @_Z3ft7IiEN11__enable_ifIXsr16__is_scalar_typeIT_EE7__valueEvE6__typeEv
Anders Carlsson50755b02009-09-27 20:11:34 +0000200template void ft7<int>();
John McCall26a6ec72011-06-21 22:12:46 +0000201// CHECK: @_Z3ft7IPvEN11__enable_ifIXsr16__is_scalar_typeIT_EE7__valueEvE6__typeEv
Anders Carlsson50755b02009-09-27 20:11:34 +0000202template void ft7<void*>();
Anders Carlssonb217c1b2009-10-06 21:58:01 +0000203
204// PR5144
205extern "C" {
206void extern_f(void);
207};
208
209// CHECK: @extern_f
210void extern_f(void) { }
211
Anders Carlssonc4355b62009-10-07 01:45:02 +0000212struct S7 {
Anders Carlsson5c478cf2009-12-04 22:33:25 +0000213 S7();
Anders Carlssonc4355b62009-10-07 01:45:02 +0000214
Anders Carlsson5c478cf2009-12-04 22:33:25 +0000215 struct S { S(); };
Anders Carlssonc4355b62009-10-07 01:45:02 +0000216 struct {
217 S s;
218 } a;
219};
220
221// PR5139
John McCall8e51a1f2010-02-18 21:31:48 +0000222// CHECK: @_ZN2S7C1Ev
Anders Carlssonc4355b62009-10-07 01:45:02 +0000223// CHECK: @_ZN2S7C2Ev
224// CHECK: @"_ZN2S73$_0C1Ev"
225S7::S7() {}
226
Anders Carlssona7694082009-11-06 02:50:19 +0000227// PR5063
John Wiegley20c0da72011-04-27 23:09:49 +0000228template<typename T> typename __enable_if<(__is_scalar_type<T>::__value), void>::__type ft8() { }
John McCall26a6ec72011-06-21 22:12:46 +0000229// CHECK: @_Z3ft8IiEN11__enable_ifIXsr16__is_scalar_typeIT_EE7__valueEvE6__typeEv
Anders Carlssona7694082009-11-06 02:50:19 +0000230template void ft8<int>();
John McCall26a6ec72011-06-21 22:12:46 +0000231// CHECK: @_Z3ft8IPvEN11__enable_ifIXsr16__is_scalar_typeIT_EE7__valueEvE6__typeEv
Anders Carlssona7694082009-11-06 02:50:19 +0000232template void ft8<void*>();
Anders Carlssone170ba72009-12-14 01:45:37 +0000233
Anders Carlsson58040a52009-12-16 05:48:46 +0000234// PR5796
235namespace PR5796 {
John Wiegley20c0da72011-04-27 23:09:49 +0000236template<typename> struct __is_scalar_type {
Anders Carlsson58040a52009-12-16 05:48:46 +0000237 enum { __value = 0 };
238};
239
240template<bool, typename> struct __enable_if {};
241template<typename T> struct __enable_if<true, T> { typedef T __type; };
242template<typename T>
243
John McCall26a6ec72011-06-21 22:12:46 +0000244// CHECK: define linkonce_odr void @_ZN6PR57968__fill_aIiEENS_11__enable_ifIXntsr16__is_scalar_typeIT_EE7__valueEvE6__typeEv
John Wiegley20c0da72011-04-27 23:09:49 +0000245typename __enable_if<!__is_scalar_type<T>::__value, void>::__type __fill_a() { };
Anders Carlsson58040a52009-12-16 05:48:46 +0000246
247void f() { __fill_a<int>(); }
248}
249
Anders Carlssone170ba72009-12-14 01:45:37 +0000250namespace Expressions {
251// Unary operators.
252
Douglas Gregor8f51a4f2010-03-13 18:23:07 +0000253// CHECK: define weak_odr void @_ZN11Expressions2f1ILi1EEEvPAplngT_Li2E_i
Anders Carlssone170ba72009-12-14 01:45:37 +0000254template <int i> void f1(int (*)[(-i) + 2]) { };
255template void f1<1>(int (*)[1]);
256
Douglas Gregor8f51a4f2010-03-13 18:23:07 +0000257// CHECK: define weak_odr void @_ZN11Expressions2f2ILi1EEEvPApsT__i
Anders Carlssone170ba72009-12-14 01:45:37 +0000258template <int i> void f2(int (*)[+i]) { };
259template void f2<1>(int (*)[1]);
260
261// Binary operators.
262
Douglas Gregor8f51a4f2010-03-13 18:23:07 +0000263// CHECK: define weak_odr void @_ZN11Expressions2f3ILi1EEEvPAplT_T__i
Anders Carlssone170ba72009-12-14 01:45:37 +0000264template <int i> void f3(int (*)[i+i]) { };
265template void f3<1>(int (*)[2]);
266
Douglas Gregor8f51a4f2010-03-13 18:23:07 +0000267// CHECK: define weak_odr void @_ZN11Expressions2f4ILi1EEEvPAplplLi2ET_T__i
Anders Carlssone170ba72009-12-14 01:45:37 +0000268template <int i> void f4(int (*)[2 + i+i]) { };
269template void f4<1>(int (*)[4]);
270
271// The ternary operator.
Douglas Gregor8f51a4f2010-03-13 18:23:07 +0000272// CHECK: define weak_odr void @_ZN11Expressions2f4ILb1EEEvPAquT_Li1ELi2E_i
Anders Carlssone170ba72009-12-14 01:45:37 +0000273template <bool b> void f4(int (*)[b ? 1 : 2]) { };
274template void f4<true>(int (*)[1]);
Anders Carlssone170ba72009-12-14 01:45:37 +0000275}
Anders Carlsson8257d412009-12-22 06:36:32 +0000276
277struct Ops {
278 Ops& operator+(const Ops&);
279 Ops& operator-(const Ops&);
280 Ops& operator&(const Ops&);
281 Ops& operator*(const Ops&);
282
283 void *v;
284};
285
286// CHECK: define %struct.Ops* @_ZN3OpsplERKS_
287Ops& Ops::operator+(const Ops&) { return *this; }
288// CHECK: define %struct.Ops* @_ZN3OpsmiERKS_
289Ops& Ops::operator-(const Ops&) { return *this; }
290// CHECK: define %struct.Ops* @_ZN3OpsanERKS_
291Ops& Ops::operator&(const Ops&) { return *this; }
292// CHECK: define %struct.Ops* @_ZN3OpsmlERKS_
293Ops& Ops::operator*(const Ops&) { return *this; }
294
Anders Carlsson9e85c742009-12-23 19:30:55 +0000295// PR5861
296namespace PR5861 {
297template<bool> class P;
298template<> class P<true> {};
299
300template<template <bool> class, bool>
301struct Policy { };
302
303template<typename T, typename = Policy<P, true> > class Alloc
304{
305 T *allocate(int, const void*) { return 0; }
306};
307
Douglas Gregor8f51a4f2010-03-13 18:23:07 +0000308// CHECK: define weak_odr i8* @_ZN6PR58615AllocIcNS_6PolicyINS_1PELb1EEEE8allocateEiPKv
Anders Carlsson9e85c742009-12-23 19:30:55 +0000309template class Alloc<char>;
310}
Anders Carlssonf28c6872009-12-23 22:31:44 +0000311
312// CHECK: define void @_Z1fU13block_pointerFiiiE
Nuno Lopesa9efbf02010-01-07 09:36:51 +0000313void f(int (^)(int, int)) { }
314
Sean Hunt31455252010-01-24 03:04:27 +0000315void pr5966_foo() {
316 extern int pr5966_i;
317 pr5966_i = 0;
318}
319
320static int pr5966_i;
321
322void pr5966_bar() {
323 pr5966_i = 0;
324}
John McCall1dd73832010-02-04 01:42:13 +0000325
326namespace test0 {
327 int ovl(int x);
328 char ovl(double x);
329
330 template <class T> void f(T, char (&buffer)[sizeof(ovl(T()))]) {}
331
332 void test0() {
333 char buffer[1];
334 f(0.0, buffer);
335 }
336 // CHECK: define void @_ZN5test05test0Ev()
337 // CHECK: define linkonce_odr void @_ZN5test01fIdEEvT_RAszcl3ovlcvS1__EE_c(
338
339 void test1() {
340 char buffer[sizeof(int)];
341 f(1, buffer);
342 }
343 // CHECK: define void @_ZN5test05test1Ev()
344 // CHECK: define linkonce_odr void @_ZN5test01fIiEEvT_RAszcl3ovlcvS1__EE_c(
345
346 template <class T> void g(char (&buffer)[sizeof(T() + 5.0f)]) {}
347 void test2() {
348 char buffer[sizeof(float)];
349 g<float>(buffer);
350 }
John McCall1b600522011-04-24 03:07:16 +0000351 // CHECK: define linkonce_odr void @_ZN5test01gIfEEvRAszplcvT__ELf40a00000E_c(
John McCall1dd73832010-02-04 01:42:13 +0000352
353 template <class T> void h(char (&buffer)[sizeof(T() + 5.0)]) {}
354 void test3() {
355 char buffer[sizeof(double)];
356 h<float>(buffer);
357 }
358 // CHECK: define linkonce_odr void @_ZN5test01hIfEEvRAszplcvT__ELd4014000000000000E_c(
John McCall2f27bf82010-02-04 02:56:29 +0000359
360 template <class T> void j(char (&buffer)[sizeof(T().buffer)]) {}
361 struct A { double buffer[128]; };
362 void test4() {
363 char buffer[1024];
364 j<A>(buffer);
365 }
John McCalle1e342f2010-03-01 19:12:25 +0000366 // CHECK: define linkonce_odr void @_ZN5test01jINS_1AEEEvRAszdtcvT__E6buffer_c(
John McCall1dd73832010-02-04 01:42:13 +0000367}
Douglas Gregor32fb4e12010-02-05 20:45:00 +0000368
369namespace test1 {
370 template<typename T> struct X { };
371 template<template<class> class Y, typename T> void f(Y<T>) { }
Douglas Gregor8f51a4f2010-03-13 18:23:07 +0000372 // CHECK: define weak_odr void @_ZN5test11fINS_1XEiEEvT_IT0_E
Douglas Gregor32fb4e12010-02-05 20:45:00 +0000373 template void f(X<int>);
374}
Anders Carlssonaec25232010-02-06 04:52:27 +0000375
John McCall74990f42011-03-22 06:34:45 +0000376// CHECK: define internal void @_ZL27functionWithInternalLinkagev()
Anders Carlssonaec25232010-02-06 04:52:27 +0000377static void functionWithInternalLinkage() { }
378void g() { functionWithInternalLinkage(); }
John McCallad5e7382010-03-01 23:49:17 +0000379
380namespace test2 {
381 template <class T> decltype(((T*) 0)->member) read_member(T& obj) {
382 return obj.member;
383 }
384
385 struct A { int member; } obj;
386 int test() {
387 return read_member(obj);
388 }
389
390 // CHECK: define linkonce_odr i32 @_ZN5test211read_memberINS_1AEEEDtptcvPT_Li0E6memberERS2_(
391}
392
John McCalla0ce15c2011-04-24 08:23:24 +0000393// rdar://problem/9280586
John McCallad5e7382010-03-01 23:49:17 +0000394namespace test3 {
395 struct AmbiguousBase { int ab; };
396 struct Path1 : AmbiguousBase { float p; };
397 struct Path2 : AmbiguousBase { double p; };
398 struct Derived : Path1, Path2 { };
399
John McCall4f4e4132011-05-04 01:45:19 +0000400 // CHECK: define linkonce_odr i32 @_ZN5test38get_ab_1INS_7DerivedEEEDtptcvPT_Li0Esr5Path1E2abERS2_(
John McCalla0ce15c2011-04-24 08:23:24 +0000401 template <class T> decltype(((T*) 0)->Path1::ab) get_ab_1(T &ref) { return ref.Path1::ab; }
John McCallad5e7382010-03-01 23:49:17 +0000402
John McCall4f4e4132011-05-04 01:45:19 +0000403 // CHECK: define linkonce_odr i32 @_ZN5test38get_ab_2INS_7DerivedEEEDtptcvPT_Li0Esr5Path2E2abERS2_(
John McCalla0ce15c2011-04-24 08:23:24 +0000404 template <class T> decltype(((T*) 0)->Path2::ab) get_ab_2(T &ref) { return ref.Path2::ab; }
405
John McCall4f4e4132011-05-04 01:45:19 +0000406 // CHECK: define linkonce_odr float @_ZN5test37get_p_1INS_7DerivedEEEDtptcvPT_Li0Esr5Path1E1pERS2_(
John McCallad5e7382010-03-01 23:49:17 +0000407 template <class T> decltype(((T*) 0)->Path1::p) get_p_1(T &ref) { return ref.Path1::p; }
408
John McCall4f4e4132011-05-04 01:45:19 +0000409 // CHECK: define linkonce_odr double @_ZN5test37get_p_2INS_7DerivedEEEDtptcvPT_Li0Esr5Path2E1pERS2_(
John McCallad5e7382010-03-01 23:49:17 +0000410 template <class T> decltype(((T*) 0)->Path2::p) get_p_2(T &ref) { return ref.Path2::p; }
411
412 Derived obj;
413 void test() {
John McCalla0ce15c2011-04-24 08:23:24 +0000414 get_ab_1(obj);
415 get_ab_2(obj);
John McCallad5e7382010-03-01 23:49:17 +0000416 get_p_1(obj);
417 get_p_2(obj);
418 }
419}
Rafael Espindolad9800722010-03-11 14:07:00 +0000420
421// CHECK: define void @_ZN5test41gEPNS_3zedIXadL_ZNS_3foo3barEEEEE
422namespace test4 {
423 struct foo { int bar; };
424 template <int (foo::*)>
425 struct zed {};
426 void g(zed<&foo::bar>*)
427 {}
428}
429// CHECK: define void @_ZN5test51gEPNS_3zedIXadL_ZNS_3foo3barEEEEE
430namespace test5 {
431 struct foo { static int bar; };
432 template <int *>
433 struct zed {};
434 void g(zed<&foo::bar>*)
435 {}
436}
437// CHECK: define void @_ZN5test61gEPNS_3zedIXadL_ZNS_3foo3barEvEEEE
438namespace test6 {
439 struct foo { int bar(); };
440 template <int (foo::*)()>
441 struct zed {};
442 void g(zed<&foo::bar>*)
443 {}
444}
445// CHECK: define void @_ZN5test71gEPNS_3zedIXadL_ZNS_3foo3barEvEEEE
446namespace test7 {
447 struct foo { static int bar(); };
448 template <int (*f)()>
449 struct zed {};
450 void g(zed<&foo::bar>*)
451 {}
452}
Douglas Gregor8f51a4f2010-03-13 18:23:07 +0000453// CHECK: define weak_odr void @_ZN5test81AILZNS_1B5valueEEE3incEv
Rafael Espindolad9800722010-03-11 14:07:00 +0000454namespace test8 {
455 template <int &counter> class A { void inc() { counter++; } };
John McCall7002f4c2010-04-09 19:03:51 +0000456 class B { public: static int value; };
Rafael Espindolad9800722010-03-11 14:07:00 +0000457 template class A<B::value>;
458}
Rafael Espindola9b35b252010-03-17 04:28:11 +0000459// CHECK: declare void @_ZN5test91fIiNS_3barEEEvRKNT0_3baz1XE
460namespace test9 {
461 template<class T>
462 struct foo {
463 typedef T X;
464 };
465 struct bar {
466 typedef foo<int> baz;
467 };
468 template <class zaz, class zed>
469 void f(const typename zed::baz::X&);
470 void g() {
471 f<int, bar>( 0);
472 }
473}
John McCallde810632010-04-09 21:48:08 +0000474
475// <rdar://problem/7825453>
476namespace test10 {
477 template <char P1> struct S {};
478 template <char P2> void f(struct S<false ? 'a' : P2> ) {}
479
480 // CHECK: define weak_odr void @_ZN6test101fILc3EEEvNS_1SIXquLb0ELc97ET_EEE(
481 template void f<(char) 3>(struct S<3>);
482}
Anders Carlsson93296682010-06-02 04:40:13 +0000483
484namespace test11 {
485 // CHECK: @_ZN6test111fEz
486 void f(...) { }
487
488 struct A {
489 void f(...);
490 };
491
492 // CHECK: @_ZN6test111A1fEz
493 void A::f(...) { }
494}
Anders Carlssondfc0d1f2010-06-02 05:07:26 +0000495
496namespace test12 {
497
498 // CHECK: _ZN6test121fENS_1AILt33000EEE
499 template <unsigned short> struct A { };
500 void f(A<33000>) { }
John McCallb6f532e2010-07-14 06:43:17 +0000501}
502
503// PR7446
504namespace test13 {
505 template <template <class> class T> class A {};
506 template <class U> class B {};
507
508 template <template<class> class T> void foo(const A<T> &a) {}
509
510 // CHECK: define weak_odr void @_ZN6test133fooINS_1BEEEvRKNS_1AIT_EE(
511 template void foo(const A<B> &a);
512}
Eli Friedmanc00cb642010-07-18 20:49:59 +0000513
514namespace test14 {
515 extern "C" {
516 struct S {
517 static int a(), x;
518 };
519 // CHECK: define i32 @_ZN6test141S1aEv
520 // CHECK: load i32* @_ZN6test141S1xE
521 int S::a() { return S::x; }
522 }
523}
John McCall3dc7e7b2010-07-24 01:17:35 +0000524
525// rdar://problem/8204122
526namespace test15 {
527 enum E { e = 3 };
528 template <int I> struct S {};
529
530 template <int I> void f(S<I + e>) {}
531
532 // CHECK: define weak_odr void @_ZN6test151fILi7EEEvNS_1SIXplT_LNS_1EE3EEEE(
533 template void f<7>(S<7 + e>);
534}
John McCall7121c8f2010-08-05 22:02:13 +0000535
John McCall6f615bc2010-08-17 21:51:21 +0000536// rdar://problem/8302148
537namespace test17 {
538 template <int N> struct A {};
539
540 struct B {
541 static int foo(void);
542 };
543
544 template <class T> A<sizeof(T::foo())> func(void);
545
John McCall6dbce192010-08-20 00:17:19 +0000546 // CHECK: define void @_ZN6test174testEv()
John McCall6f615bc2010-08-17 21:51:21 +0000547 // CHECK: call {{.*}} @_ZN6test174funcINS_1BEEENS_1AIXszclsrT_3fooEEEEv()
John McCall6dbce192010-08-20 00:17:19 +0000548 void test() {
549 func<B>();
John McCall6f615bc2010-08-17 21:51:21 +0000550 }
551}
John McCall5e1e89b2010-08-18 19:18:59 +0000552
553// PR7891
554namespace test18 {
555 struct A {
556 int operator+();
557 int operator-();
558 int operator*();
559 int operator&();
560 };
561 template <int (A::*)()> struct S {};
562
563 template <typename T> void f(S<&T::operator+>) {}
564 template void f<A>(S<&A::operator+>);
565
566 template <typename T> void f(S<&T::operator- >) {}
567 template void f<A>(S<&A::operator- >);
568
569 template <typename T> void f(S<&T::operator*>) {}
570 template void f<A>(S<&A::operator*>);
571
572 template <typename T> void f(S<&T::operator&>) {}
573 template void f<A>(S<&A::operator&>);
574
575 // CHECK: define weak_odr void @_ZN6test181fINS_1AEEEvNS_1SIXadsrT_plEEE
576 // CHECK: define weak_odr void @_ZN6test181fINS_1AEEEvNS_1SIXadsrT_miEEE
577 // CHECK: define weak_odr void @_ZN6test181fINS_1AEEEvNS_1SIXadsrT_mlEEE
578 // CHECK: define weak_odr void @_ZN6test181fINS_1AEEEvNS_1SIXadsrT_anEEE
579}
John McCall6dbce192010-08-20 00:17:19 +0000580
581// rdar://problem/8332117
582namespace test19 {
583 struct A {
584 template <typename T> int f();
585 int operator+();
586 operator int();
587 template <typename T> int operator-();
588 };
589
590 template <int (A::*)()> struct S {};
591
592 template <typename T> void g (S<&T::template f<int> >) {}
593 template <typename T> void g (S<&T::operator+ >) {}
594 template <typename T> void g (S<&T::operator int>) {}
595 template <typename T> void g (S<&T::template operator- <double> >) {}
596
597 // CHECK: define weak_odr void @_ZN6test191gINS_1AEEEvNS_1SIXadsrT_1fIiEEEE(
598 template void g<A>(S<&A::f<int> >);
599 // CHECK: define weak_odr void @_ZN6test191gINS_1AEEEvNS_1SIXadsrT_plEEE(
600 template void g<A>(S<&A::operator+>);
601 // CHECK: define weak_odr void @_ZN6test191gINS_1AEEEvNS_1SIXadsrT_cviEEE(
602 template void g<A>(S<&A::operator int>);
603 // CHECK: define weak_odr void @_ZN6test191gINS_1AEEEvNS_1SIXadsrT_miIdEEEE(
604 template void g<A>(S<&A::operator-<double> >);
605}
606
607namespace test20 {
608 template <class T> T *f(const T&);
609 template <class T> T *f(T*);
610
611 // CHECK: define weak_odr void @_ZN6test205test0IiEEvDTcl1fIPT_ELi0EEE(
612 template <class T> void test0(decltype(f<T*>(0))) {}
613 template void test0<int>(decltype(f<int*>(0)));
614
615 // CHECK: define weak_odr void @_ZN6test205test1IiEEvDTcl1fIEcvT__EEE(
616 template <class T> void test1(decltype(f<>(T()))) {}
617 template void test1<int>(decltype(f<>(int())));
618}
Fariborz Jahanian7281d1f2010-11-02 16:54:00 +0000619
620// rdar:// 8620510
621namespace test21 {
622 // CHECK: define void @_ZN6test2112vla_arg_funcEiPA_i(
623 void vla_arg_func(int X, int a[X][X]) {}
624}
Anders Carlssone2923682010-11-04 04:31:32 +0000625
626namespace test22 {
627 // CHECK: define void @_ZN6test221fEDn(
628 void f(decltype(nullptr)) { }
629}
John McCallb47f7482011-01-26 20:05:40 +0000630
631// rdar://problem/8913416
632namespace test23 {
633 typedef void * const vpc;
634
635 // CHECK: define void @_ZN6test231fERA10_KPv(
636 void f(vpc (&)[10]) {}
637
638 typedef vpc vpca5[5];
639 void f(vpca5 volatile (&)[10]) {}
640 // CHECK: define void @_ZN6test231fERA10_A5_VKPv(
641}
John McCall74990f42011-03-22 06:34:45 +0000642
643namespace test24 {
644 void test0() {
645 extern int foo();
646 // CHECK: call i32 @_ZN6test243fooEv()
647 foo();
648 }
649
650 static char foo() {}
651 void test1() {
652 // CHECK: call signext i8 @_ZN6test24L3fooEv()
653 foo();
654 }
655}
John McCallc0a45592011-04-24 08:43:07 +0000656
657// rdar://problem/8806641
658namespace test25 {
659 template <void (*fn)()> struct A {
660 static void call() { fn(); }
661 };
662 void foo();
663 void test() {
664 // CHECK: call void @_ZN6test251AIXadL_ZNS_3fooEvEEE4callEv()
665 A<foo>::call();
666 }
667}
John McCall4f4e4132011-05-04 01:45:19 +0000668
669namespace test26 {
670 template <template <class> class T> void foo(decltype(T<float>::object) &object) {}
671
672 template <class T> struct holder { static T object; };
673
674 void test() {
675 float f;
676
677 // CHECK: call void @_ZN6test263fooINS_6holderEEEvRDtsrT_IfE6objectE(
678 foo<holder>(f);
679 }
680}
681
682namespace test27 {
683 struct A {
684 struct inner {
685 float object;
686 };
687
688 float meth();
689 };
690 typedef A Alias;
691
692 template <class T> void a(decltype(T::inner::object) &object) {}
693 template <class T> void b(decltype(T().Alias::meth()) &object) {}
694
695 void test() {
696 float f;
697 // CHECK: call void @_ZN6test271aINS_1AEEEvRDtsrNT_5innerE6objectE(
698 a<A>(f);
699 // CHECK: call void @_ZN6test271bINS_1AEEEvRDTcldtcvT__Esr5AliasE4methEE(
700 b<A>(f);
701 }
702}
John McCalld3d49bb2011-06-28 16:49:23 +0000703
704// An injected class name type in a unresolved-name.
705namespace test28 {
706 template <class T> struct A {
707 enum { bit };
708 };
709
710 template <class T> void foo(decltype(A<T>::A::bit) x);
711
712 void test() {
713 foo<char>(A<char>::bit);
714 // CHECK: call void @_ZN6test283fooIcEEvDtsr1AIT_E1AE3bitE(
715 }
716}
717
718// An enclosing template type parameter in an unresolved-name.
719namespace test29 {
720 template <class T> struct A {
721 template <class U> static void foo(decltype(T::fn(U())) x);
722 };
723 struct B { static int fn(int); static long fn(long); };
724
725 void test() {
726 A<B>::foo<int>(0);
727 // CHECK: call void @_ZN6test291AINS_1BEE3fooIiEEvDTclsrS1_2fncvT__EEE(
728 }
729}
730
731// An enclosing template template parameter in an unresolved-name.
732namespace test30 {
733 template <template <class> class T> struct A {
734 template <class U> static void foo(decltype(T<U>::fn()) x);
735 };
736 template <class T> struct B { static T fn(); };
737
738 void test() {
739 A<B>::foo<int>(0);
John McCall68a51a72011-07-01 00:04:39 +0000740 // CHECK: call void @_ZN6test301AINS_1BEE3fooIiEEvDTclsrS1_IT_EE2fnEE(
John McCalld3d49bb2011-06-28 16:49:23 +0000741 }
742}
Douglas Gregor561f8122011-07-01 01:22:09 +0000743
744namespace test31 { // instantiation-dependent mangling of decltype
745 int x;
746 template<class T> auto f1(T p)->decltype(x) { return 0; }
747 // The return type in the mangling of the template signature
748 // is encoded as "i".
749 template<class T> auto f2(T p)->decltype(p) { return 0; }
750 // The return type in the mangling of the template signature
751 // is encoded as "Dtfp_E".
752 void g(int);
753 template<class T> auto f3(T p)->decltype(g(p)) {}
754
755 // CHECK: define weak_odr i32 @_ZN6test312f1IiEEiT_(
756 template int f1(int);
757 // CHECK: define weak_odr i32 @_ZN6test312f2IiEEDtfp_ET_
758 template int f2(int);
759 // CHECK: define weak_odr void @_ZN6test312f3IiEEDTcl1gfp_EET_
760 template void f3(int);
761}
John McCall35ee32e2011-07-01 02:19:08 +0000762
763// PR10205
764namespace test32 {
765 template<typename T, int=T::value> struct A {
766 typedef int type;
767 };
768 struct B { enum { value = 4 }; };
769
770 template <class T> typename A<T>::type foo() { return 0; }
771 void test() {
772 foo<B>();
773 // CHECK: call i32 @_ZN6test323fooINS_1BEEENS_1AIT_XsrS3_5valueEE4typeEv()
774 }
775}
776
777namespace test33 {
778 template <class T> struct X {
779 enum { value = T::value };
780 };
781
782 template<typename T, int=X<T>::value> struct A {
783 typedef int type;
784 };
785 struct B { enum { value = 4 }; };
786
787 template <class T> typename A<T>::type foo() { return 0; }
788
789 void test() {
790 foo<B>();
791 // CHECK: call i32 @_ZN6test333fooINS_1BEEENS_1AIT_Xsr1XIS3_EE5valueEE4typeEv()
792 }
793}
Douglas Gregor5e78cd42011-07-11 22:38:07 +0000794
795namespace test34 {
Douglas Gregoredee94b2011-07-12 04:47:20 +0000796 // Mangling for instantiation-dependent decltype expressions.
Douglas Gregor5e78cd42011-07-11 22:38:07 +0000797 template<typename T>
798 void f(decltype(sizeof(decltype(T() + T())))) {}
799
800 // CHECK: define weak_odr void @_ZN6test341fIiEEvDTstDTplcvT__EcvS1__EEE
801 template void f<int>(decltype(sizeof(1)));
Douglas Gregoredee94b2011-07-12 04:47:20 +0000802
803 // Mangling for non-instantiation-dependent sizeof expressions.
804 template<unsigned N>
805 void f2(int (&)[N + sizeof(int*)]) {}
806
807 // CHECK: define weak_odr void @_ZN6test342f2ILj4EEEvRAplT_Lm8E_i
808 template void f2<4>(int (&)[4 + sizeof(int*)]);
809
810 // Mangling for non-instantiation-dependent sizeof expressions
811 // involving an implicit conversion of the result of the sizeof.
812 template<unsigned long long N>
813 void f3(int (&)[N + sizeof(int*)]) {}
814
815 // CHECK: define weak_odr void @_ZN6test342f3ILy4EEEvRAplT_Ly8E_i
816 template void f3<4>(int (&)[4 + sizeof(int*)]);
Douglas Gregorf1588662011-07-12 15:18:55 +0000817
818 // Mangling for instantiation-dependent sizeof() expressions as
819 // template arguments.
820 template<unsigned> struct A { };
821
822 template<typename T> void f4(::test34::A<sizeof(sizeof(decltype(T() + T())))>) { }
823
824 // CHECK: define weak_odr void @_ZN6test342f4IiEEvNS_1AIXszstDTplcvT__EcvS2__EEEEE
825 template void f4<int>(A<sizeof(sizeof(int))>);
Douglas Gregor5e78cd42011-07-11 22:38:07 +0000826}
Douglas Gregor19617912011-07-12 05:06:05 +0000827
828namespace test35 {
829 // Dependent operator names of unknown arity.
830 struct A {
831 template<typename U> A operator+(U) const;
832 };
833
834 template<typename T>
835 void f1(decltype(sizeof(&T::template operator+<int>))) {}
836
837 // CHECK: define weak_odr void @_ZN6test352f1INS_1AEEEvDTszadsrT_plIiEE
838 template void f1<A>(__SIZE_TYPE__);
839}
Douglas Gregor91832362011-07-12 07:03:48 +0000840
841namespace test36 {
842 template<unsigned> struct A { };
843
844 template<typename ...Types>
845 auto f1(Types... values) -> A<sizeof...(values)> { }
846
847 // CHECK: define weak_odr {{.*}} @_ZN6test362f1IJifEEENS_1AIXsZfp_EEEDpT_
848 template A<2> f1(int, float);
849}