blob: 17232fd060ee39914c7e16d6bbd7e61e5f5ee9ae [file] [log] [blame]
Richard Smith9ca5c422011-10-13 22:29:44 +00001// RUN: %clang_cc1 -emit-llvm %s -o - -triple=x86_64-apple-darwin9 -fblocks -std=c++11 | FileCheck %s
Douglas Gregor5fec5b02009-02-13 00:10:09 +00002struct X { };
3struct Y { };
Anders Carlsson4ed74dd2009-03-07 23:57:03 +00004
Anders Carlssondf644fb2009-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
Alexis Huntaecc45c2010-01-24 03:04:27 +000011//CHECK: @pr5966_i = external global
12//CHECK: @_ZL8pr5966_i = internal global
13
Anders Carlssondf644fb2009-09-17 03:46:43 +000014// CHECK: define zeroext i1 @_ZplRK1YRA100_P1X
Douglas Gregor5fec5b02009-02-13 00:10:09 +000015bool operator+(const Y&, X* (&xs)[100]) { return false; }
16
Anders Carlssondf644fb2009-09-17 03:46:43 +000017// CHECK: define void @_Z1f1s
Anders Carlsson4ed74dd2009-03-07 23:57:03 +000018typedef struct { int a; } s;
19void f(s) { }
20
Anders Carlssondf644fb2009-09-17 03:46:43 +000021// CHECK: define void @_Z1f1e
Anders Carlsson4ed74dd2009-03-07 23:57:03 +000022typedef enum { foo } e;
23void f(e) { }
24
Anders Carlssondf644fb2009-09-17 03:46:43 +000025// CHECK: define void @_Z1f1u
Anders Carlsson4ed74dd2009-03-07 23:57:03 +000026typedef union { int a; } u;
27void f(u) { }
Anders Carlsson02751152009-03-10 17:07:44 +000028
Anders Carlssondf644fb2009-09-17 03:46:43 +000029// CHECK: define void @_Z1f1x
Anders Carlsson02751152009-03-10 17:07:44 +000030typedef struct { int a; } x,y;
31void f(y) { }
32
Anders Carlssondf644fb2009-09-17 03:46:43 +000033// CHECK: define void @_Z1fv
Anders Carlsson7a6f8b92009-04-01 00:15:23 +000034void f() { }
Anders Carlsson237f3492009-04-01 00:58:25 +000035
Anders Carlssondf644fb2009-09-17 03:46:43 +000036// CHECK: define void @_ZN1N1fEv
Anders Carlsson237f3492009-04-01 00:58:25 +000037namespace N { void f() { } }
38
Anders Carlssondf644fb2009-09-17 03:46:43 +000039// CHECK: define void @_ZN1N1N1fEv
Anders Carlsson237f3492009-04-01 00:58:25 +000040namespace N { namespace N { void f() { } } }
Anders Carlssoncbaeb9e2009-04-02 05:55:18 +000041
Anders Carlssondf644fb2009-09-17 03:46:43 +000042// CHECK: define void @unmangled_function
Anders Carlssoncbaeb9e2009-04-02 05:55:18 +000043extern "C" { namespace N { void unmangled_function() { } } }
44
Anders Carlssond3a69ce2009-05-16 21:02:39 +000045extern "C" { namespace N { int unmangled_variable = 10; } }
Anders Carlssoncbaeb9e2009-04-02 05:55:18 +000046
Anders Carlssonf2125a02009-04-02 16:05:20 +000047namespace N { int i; }
Anders Carlsson4eca1092009-04-02 16:24:45 +000048
Anders Carlsson4eca1092009-04-02 16:24:45 +000049namespace N { int f(int, int) { static int b; return b; } }
Anders Carlsson1235bbc2009-04-13 18:03:33 +000050
Anders Carlsson1235bbc2009-04-13 18:03:33 +000051namespace N { int h(); void g() { static int a = h(); } }
Chris Lattnerf122cef2009-04-30 02:43:43 +000052
Anders Carlssondf644fb2009-09-17 03:46:43 +000053// CHECK: define void @_Z1fno
Chris Lattnerf122cef2009-04-30 02:43:43 +000054void f(__int128_t, __uint128_t) { }
Anders Carlssonf6e9ece2009-05-15 16:09:15 +000055
56template <typename T> struct S1 {};
57
Anders Carlssondf644fb2009-09-17 03:46:43 +000058// CHECK: define void @_Z1f2S1IiE
Anders Carlssonf6e9ece2009-05-15 16:09:15 +000059void f(S1<int>) {}
60
Anders Carlssondf644fb2009-09-17 03:46:43 +000061// CHECK: define void @_Z1f2S1IdE
Anders Carlssonf6e9ece2009-05-15 16:09:15 +000062void f(S1<double>) {}
63
64template <int N> struct S2 {};
Anders Carlssondf644fb2009-09-17 03:46:43 +000065// CHECK: define void @_Z1f2S2ILi100EE
Anders Carlssonf6e9ece2009-05-15 16:09:15 +000066void f(S2<100>) {}
67
Anders Carlssondf644fb2009-09-17 03:46:43 +000068// CHECK: define void @_Z1f2S2ILin100EE
Anders Carlssonf6e9ece2009-05-15 16:09:15 +000069void f(S2<-100>) {}
70
71template <bool B> struct S3 {};
72
Anders Carlssondf644fb2009-09-17 03:46:43 +000073// CHECK: define void @_Z1f2S3ILb1EE
Anders Carlssonf6e9ece2009-05-15 16:09:15 +000074void f(S3<true>) {}
75
Anders Carlssondf644fb2009-09-17 03:46:43 +000076// CHECK: define void @_Z1f2S3ILb0EE
Anders Carlssonf6e9ece2009-05-15 16:09:15 +000077void f(S3<false>) {}
78
Anders Carlsson23ca0b42009-05-17 17:41:20 +000079struct S;
80
Anders Carlssondf644fb2009-09-17 03:46:43 +000081// CHECK: define void @_Z1fM1SKFvvE
Anders Carlsson23ca0b42009-05-17 17:41:20 +000082void f(void (S::*)() const) {}
83
Anders Carlssondf644fb2009-09-17 03:46:43 +000084// CHECK: define void @_Z1fM1SFvvE
Anders Carlsson23ca0b42009-05-17 17:41:20 +000085void f(void (S::*)()) {}
Anders Carlssonb3e533d2009-09-16 23:53:19 +000086
Anders Carlssondf644fb2009-09-17 03:46:43 +000087// CHECK: define void @_Z1fi
Anders Carlssonb3e533d2009-09-16 23:53:19 +000088void f(const int) { }
89
Anders Carlssona2fb9bc2009-09-17 04:02:31 +000090template<typename T, typename U> void ft1(U u, T t) { }
91
92template<typename T> void ft2(T t, void (*)(T), void (*)(T)) { }
Anders Carlssondf644fb2009-09-17 03:46:43 +000093
Anders Carlsson7a8a74f2009-09-18 02:42:01 +000094template<typename T, typename U = S1<T> > struct S4 { };
95template<typename T> void ft3(S4<T>*) { }
96
Anders Carlsson2b5e1dd2009-09-18 04:29:09 +000097namespace NS {
98 template<typename T> void ft1(T) { }
Anders Carlsson7a8a74f2009-09-18 02:42:01 +000099}
100
Anders Carlssona18322c2009-09-21 01:21:10 +0000101void g1() {
Anders Carlssona2fb9bc2009-09-17 04:02:31 +0000102 // CHECK: @_Z3ft1IidEvT0_T_
103 ft1<int, double>(1, 0);
104
105 // CHECK: @_Z3ft2IcEvT_PFvS0_ES2_
106 ft2<char>(1, 0, 0);
Anders Carlsson7a8a74f2009-09-18 02:42:01 +0000107
108 // CHECK: @_Z3ft3IiEvP2S4IT_2S1IS1_EE
109 ft3<int>(0);
Anders Carlsson2b5e1dd2009-09-18 04:29:09 +0000110
111 // CHECK: @_ZN2NS3ft1IiEEvT_
112 NS::ft1<int>(1);
Anders Carlssonca51ef12009-09-17 16:12:20 +0000113}
Anders Carlsson2b5e1dd2009-09-18 04:29:09 +0000114
Anders Carlssona18322c2009-09-21 01:21:10 +0000115// Expressions
116template<int I> struct S5 { };
117
118template<int I> void ft4(S5<I>) { }
119void g2() {
120 // CHECK: @_Z3ft4ILi10EEv2S5IXT_EE
121 ft4(S5<10>());
122
123 // CHECK: @_Z3ft4ILi20EEv2S5IXT_EE
124 ft4(S5<20>());
125}
126
Anders Carlsson2b5e1dd2009-09-18 04:29:09 +0000127extern "C++" {
128 // CHECK: @_Z1hv
129 void h() { }
130}
131
Anders Carlssonfc51cc92009-09-22 17:23:30 +0000132// PR5019
133extern "C" { struct a { int b; }; }
134
135// CHECK: @_Z1fP1a
136int f(struct a *x) {
137 return x->b;
138}
Anders Carlsson1d3b6f62009-09-22 20:33:31 +0000139
140// PR5017
141extern "C" {
142struct Debug {
Anders Carlsson8a35c792009-12-22 06:36:32 +0000143 const Debug& operator<< (unsigned a) const { return *this; }
Anders Carlsson1d3b6f62009-09-22 20:33:31 +0000144};
145Debug dbg;
146// CHECK: @_ZNK5DebuglsEj
147int main(void) { dbg << 32 ;}
148}
Anders Carlssonbdaaab42009-09-26 02:26:02 +0000149
150template<typename T> struct S6 {
151 typedef int B;
152};
153
154template<typename T> void ft5(typename S6<T>::B) { }
155// CHECK: @_Z3ft5IiEvN2S6IT_E1BE
156template void ft5<int>(int);
Anders Carlsson49232b92009-09-26 20:13:56 +0000157
158template<typename T> class A {};
159
160namespace NS {
161template<typename T> bool operator==(const A<T>&, const A<T>&) { return true; }
162}
163
Anders Carlsson3e83c302009-09-26 22:18:22 +0000164// CHECK: @_ZN2NSeqIcEEbRK1AIT_ES5_
Anders Carlsson49232b92009-09-26 20:13:56 +0000165template bool NS::operator==(const ::A<char>&, const ::A<char>&);
166
167namespace std {
168template<typename T> bool operator==(const A<T>&, const A<T>&) { return true; }
169}
170
171// CHECK: @_ZSteqIcEbRK1AIT_ES4_
172template bool std::operator==(const ::A<char>&, const ::A<char>&);
173
Anders Carlssone00745b2009-09-27 00:38:53 +0000174struct S {
175 typedef int U;
176};
177
178template <typename T> typename T::U ft6(const T&) { return 0; }
179
180// CHECK: @_Z3ft6I1SENT_1UERKS1_
181template int ft6<S>(const S&);
Anders Carlsson02bca732009-09-27 20:11:34 +0000182
John Wiegley65497cc2011-04-27 23:09:49 +0000183template<typename> struct __is_scalar_type {
Anders Carlsson02bca732009-09-27 20:11:34 +0000184 enum { __value = 1 };
185};
186
187template<bool, typename> struct __enable_if { };
188
189template<typename T> struct __enable_if<true, T> {
190 typedef T __type;
191};
192
193// PR5063
John Wiegley65497cc2011-04-27 23:09:49 +0000194template<typename T> typename __enable_if<__is_scalar_type<T>::__value, void>::__type ft7() { }
Anders Carlsson02bca732009-09-27 20:11:34 +0000195
John McCall575fda12011-06-21 22:12:46 +0000196// CHECK: @_Z3ft7IiEN11__enable_ifIXsr16__is_scalar_typeIT_EE7__valueEvE6__typeEv
Anders Carlsson02bca732009-09-27 20:11:34 +0000197template void ft7<int>();
John McCall575fda12011-06-21 22:12:46 +0000198// CHECK: @_Z3ft7IPvEN11__enable_ifIXsr16__is_scalar_typeIT_EE7__valueEvE6__typeEv
Anders Carlsson02bca732009-09-27 20:11:34 +0000199template void ft7<void*>();
Anders Carlsson11d00cf2009-10-06 21:58:01 +0000200
201// PR5144
202extern "C" {
203void extern_f(void);
204};
205
206// CHECK: @extern_f
207void extern_f(void) { }
208
Anders Carlsson1e39bd92009-10-07 01:45:02 +0000209struct S7 {
Anders Carlsson1f78b2b2009-12-04 22:33:25 +0000210 S7();
Anders Carlsson1e39bd92009-10-07 01:45:02 +0000211
Anders Carlsson1f78b2b2009-12-04 22:33:25 +0000212 struct S { S(); };
Anders Carlsson1e39bd92009-10-07 01:45:02 +0000213 struct {
214 S s;
215 } a;
216};
217
218// PR5139
John McCall334ce7c2010-02-18 21:31:48 +0000219// CHECK: @_ZN2S7C1Ev
Anders Carlsson1e39bd92009-10-07 01:45:02 +0000220// CHECK: @_ZN2S7C2Ev
221// CHECK: @"_ZN2S73$_0C1Ev"
222S7::S7() {}
223
Anders Carlsson9e4e0232009-11-06 02:50:19 +0000224// PR5063
John Wiegley65497cc2011-04-27 23:09:49 +0000225template<typename T> typename __enable_if<(__is_scalar_type<T>::__value), void>::__type ft8() { }
John McCall575fda12011-06-21 22:12:46 +0000226// CHECK: @_Z3ft8IiEN11__enable_ifIXsr16__is_scalar_typeIT_EE7__valueEvE6__typeEv
Anders Carlsson9e4e0232009-11-06 02:50:19 +0000227template void ft8<int>();
John McCall575fda12011-06-21 22:12:46 +0000228// CHECK: @_Z3ft8IPvEN11__enable_ifIXsr16__is_scalar_typeIT_EE7__valueEvE6__typeEv
Anders Carlsson9e4e0232009-11-06 02:50:19 +0000229template void ft8<void*>();
Anders Carlssone66e2942009-12-14 01:45:37 +0000230
Anders Carlssonb7e93e22009-12-16 05:48:46 +0000231// PR5796
232namespace PR5796 {
John Wiegley65497cc2011-04-27 23:09:49 +0000233template<typename> struct __is_scalar_type {
Anders Carlssonb7e93e22009-12-16 05:48:46 +0000234 enum { __value = 0 };
235};
236
237template<bool, typename> struct __enable_if {};
238template<typename T> struct __enable_if<true, T> { typedef T __type; };
239template<typename T>
240
John McCall575fda12011-06-21 22:12:46 +0000241// CHECK: define linkonce_odr void @_ZN6PR57968__fill_aIiEENS_11__enable_ifIXntsr16__is_scalar_typeIT_EE7__valueEvE6__typeEv
John Wiegley65497cc2011-04-27 23:09:49 +0000242typename __enable_if<!__is_scalar_type<T>::__value, void>::__type __fill_a() { };
Anders Carlssonb7e93e22009-12-16 05:48:46 +0000243
244void f() { __fill_a<int>(); }
245}
246
Anders Carlssone66e2942009-12-14 01:45:37 +0000247namespace Expressions {
248// Unary operators.
249
Douglas Gregorb14d1232010-03-13 18:23:07 +0000250// CHECK: define weak_odr void @_ZN11Expressions2f1ILi1EEEvPAplngT_Li2E_i
Anders Carlssone66e2942009-12-14 01:45:37 +0000251template <int i> void f1(int (*)[(-i) + 2]) { };
252template void f1<1>(int (*)[1]);
253
Douglas Gregorb14d1232010-03-13 18:23:07 +0000254// CHECK: define weak_odr void @_ZN11Expressions2f2ILi1EEEvPApsT__i
Anders Carlssone66e2942009-12-14 01:45:37 +0000255template <int i> void f2(int (*)[+i]) { };
256template void f2<1>(int (*)[1]);
257
258// Binary operators.
259
Douglas Gregorb14d1232010-03-13 18:23:07 +0000260// CHECK: define weak_odr void @_ZN11Expressions2f3ILi1EEEvPAplT_T__i
Anders Carlssone66e2942009-12-14 01:45:37 +0000261template <int i> void f3(int (*)[i+i]) { };
262template void f3<1>(int (*)[2]);
263
Douglas Gregorb14d1232010-03-13 18:23:07 +0000264// CHECK: define weak_odr void @_ZN11Expressions2f4ILi1EEEvPAplplLi2ET_T__i
Anders Carlssone66e2942009-12-14 01:45:37 +0000265template <int i> void f4(int (*)[2 + i+i]) { };
266template void f4<1>(int (*)[4]);
267
268// The ternary operator.
Douglas Gregorb14d1232010-03-13 18:23:07 +0000269// CHECK: define weak_odr void @_ZN11Expressions2f4ILb1EEEvPAquT_Li1ELi2E_i
Anders Carlssone66e2942009-12-14 01:45:37 +0000270template <bool b> void f4(int (*)[b ? 1 : 2]) { };
271template void f4<true>(int (*)[1]);
Anders Carlssone66e2942009-12-14 01:45:37 +0000272}
Anders Carlsson8a35c792009-12-22 06:36:32 +0000273
274struct Ops {
275 Ops& operator+(const Ops&);
276 Ops& operator-(const Ops&);
277 Ops& operator&(const Ops&);
278 Ops& operator*(const Ops&);
279
280 void *v;
281};
282
283// CHECK: define %struct.Ops* @_ZN3OpsplERKS_
284Ops& Ops::operator+(const Ops&) { return *this; }
285// CHECK: define %struct.Ops* @_ZN3OpsmiERKS_
286Ops& Ops::operator-(const Ops&) { return *this; }
287// CHECK: define %struct.Ops* @_ZN3OpsanERKS_
288Ops& Ops::operator&(const Ops&) { return *this; }
289// CHECK: define %struct.Ops* @_ZN3OpsmlERKS_
290Ops& Ops::operator*(const Ops&) { return *this; }
291
Anders Carlsson910847c2009-12-23 19:30:55 +0000292// PR5861
293namespace PR5861 {
294template<bool> class P;
295template<> class P<true> {};
296
297template<template <bool> class, bool>
298struct Policy { };
299
300template<typename T, typename = Policy<P, true> > class Alloc
301{
302 T *allocate(int, const void*) { return 0; }
303};
304
Douglas Gregorb14d1232010-03-13 18:23:07 +0000305// CHECK: define weak_odr i8* @_ZN6PR58615AllocIcNS_6PolicyINS_1PELb1EEEE8allocateEiPKv
Anders Carlsson910847c2009-12-23 19:30:55 +0000306template class Alloc<char>;
307}
Anders Carlssona88d1972009-12-23 22:31:44 +0000308
309// CHECK: define void @_Z1fU13block_pointerFiiiE
Nuno Lopes950d5b22010-01-07 09:36:51 +0000310void f(int (^)(int, int)) { }
311
Alexis Huntaecc45c2010-01-24 03:04:27 +0000312void pr5966_foo() {
313 extern int pr5966_i;
314 pr5966_i = 0;
315}
316
317static int pr5966_i;
318
319void pr5966_bar() {
320 pr5966_i = 0;
321}
John McCall09de8ec2010-02-04 01:42:13 +0000322
323namespace test0 {
324 int ovl(int x);
325 char ovl(double x);
326
327 template <class T> void f(T, char (&buffer)[sizeof(ovl(T()))]) {}
328
329 void test0() {
330 char buffer[1];
331 f(0.0, buffer);
332 }
333 // CHECK: define void @_ZN5test05test0Ev()
334 // CHECK: define linkonce_odr void @_ZN5test01fIdEEvT_RAszcl3ovlcvS1__EE_c(
335
336 void test1() {
337 char buffer[sizeof(int)];
338 f(1, buffer);
339 }
340 // CHECK: define void @_ZN5test05test1Ev()
341 // CHECK: define linkonce_odr void @_ZN5test01fIiEEvT_RAszcl3ovlcvS1__EE_c(
342
343 template <class T> void g(char (&buffer)[sizeof(T() + 5.0f)]) {}
344 void test2() {
345 char buffer[sizeof(float)];
346 g<float>(buffer);
347 }
John McCalld8d1e2a2011-04-24 03:07:16 +0000348 // CHECK: define linkonce_odr void @_ZN5test01gIfEEvRAszplcvT__ELf40a00000E_c(
John McCall09de8ec2010-02-04 01:42:13 +0000349
350 template <class T> void h(char (&buffer)[sizeof(T() + 5.0)]) {}
351 void test3() {
352 char buffer[sizeof(double)];
353 h<float>(buffer);
354 }
355 // CHECK: define linkonce_odr void @_ZN5test01hIfEEvRAszplcvT__ELd4014000000000000E_c(
John McCalld061b442010-02-04 02:56:29 +0000356
357 template <class T> void j(char (&buffer)[sizeof(T().buffer)]) {}
358 struct A { double buffer[128]; };
359 void test4() {
360 char buffer[1024];
361 j<A>(buffer);
362 }
John McCallde9607b2010-03-01 19:12:25 +0000363 // CHECK: define linkonce_odr void @_ZN5test01jINS_1AEEEvRAszdtcvT__E6buffer_c(
John McCall09de8ec2010-02-04 01:42:13 +0000364}
Douglas Gregora16b0ca2010-02-05 20:45:00 +0000365
366namespace test1 {
367 template<typename T> struct X { };
368 template<template<class> class Y, typename T> void f(Y<T>) { }
Douglas Gregorb14d1232010-03-13 18:23:07 +0000369 // CHECK: define weak_odr void @_ZN5test11fINS_1XEiEEvT_IT0_E
Douglas Gregora16b0ca2010-02-05 20:45:00 +0000370 template void f(X<int>);
371}
Anders Carlsson2c4de4c2010-02-06 04:52:27 +0000372
John McCall290b32b2011-03-22 06:34:45 +0000373// CHECK: define internal void @_ZL27functionWithInternalLinkagev()
Anders Carlsson2c4de4c2010-02-06 04:52:27 +0000374static void functionWithInternalLinkage() { }
375void g() { functionWithInternalLinkage(); }
John McCallbd8d9bd2010-03-01 23:49:17 +0000376
377namespace test2 {
378 template <class T> decltype(((T*) 0)->member) read_member(T& obj) {
379 return obj.member;
380 }
381
382 struct A { int member; } obj;
383 int test() {
384 return read_member(obj);
385 }
386
387 // CHECK: define linkonce_odr i32 @_ZN5test211read_memberINS_1AEEEDtptcvPT_Li0E6memberERS2_(
388}
389
John McCall6dc0a2b2011-04-24 08:23:24 +0000390// rdar://problem/9280586
John McCallbd8d9bd2010-03-01 23:49:17 +0000391namespace test3 {
392 struct AmbiguousBase { int ab; };
393 struct Path1 : AmbiguousBase { float p; };
394 struct Path2 : AmbiguousBase { double p; };
395 struct Derived : Path1, Path2 { };
396
John McCall3ab84762011-05-04 01:45:19 +0000397 // CHECK: define linkonce_odr i32 @_ZN5test38get_ab_1INS_7DerivedEEEDtptcvPT_Li0Esr5Path1E2abERS2_(
John McCall6dc0a2b2011-04-24 08:23:24 +0000398 template <class T> decltype(((T*) 0)->Path1::ab) get_ab_1(T &ref) { return ref.Path1::ab; }
John McCallbd8d9bd2010-03-01 23:49:17 +0000399
John McCall3ab84762011-05-04 01:45:19 +0000400 // CHECK: define linkonce_odr i32 @_ZN5test38get_ab_2INS_7DerivedEEEDtptcvPT_Li0Esr5Path2E2abERS2_(
John McCall6dc0a2b2011-04-24 08:23:24 +0000401 template <class T> decltype(((T*) 0)->Path2::ab) get_ab_2(T &ref) { return ref.Path2::ab; }
402
John McCall3ab84762011-05-04 01:45:19 +0000403 // CHECK: define linkonce_odr float @_ZN5test37get_p_1INS_7DerivedEEEDtptcvPT_Li0Esr5Path1E1pERS2_(
John McCallbd8d9bd2010-03-01 23:49:17 +0000404 template <class T> decltype(((T*) 0)->Path1::p) get_p_1(T &ref) { return ref.Path1::p; }
405
John McCall3ab84762011-05-04 01:45:19 +0000406 // CHECK: define linkonce_odr double @_ZN5test37get_p_2INS_7DerivedEEEDtptcvPT_Li0Esr5Path2E1pERS2_(
John McCallbd8d9bd2010-03-01 23:49:17 +0000407 template <class T> decltype(((T*) 0)->Path2::p) get_p_2(T &ref) { return ref.Path2::p; }
408
409 Derived obj;
410 void test() {
John McCall6dc0a2b2011-04-24 08:23:24 +0000411 get_ab_1(obj);
412 get_ab_2(obj);
John McCallbd8d9bd2010-03-01 23:49:17 +0000413 get_p_1(obj);
414 get_p_2(obj);
415 }
416}
Rafael Espindola4d5c3d92010-03-11 14:07:00 +0000417
418// CHECK: define void @_ZN5test41gEPNS_3zedIXadL_ZNS_3foo3barEEEEE
419namespace test4 {
420 struct foo { int bar; };
421 template <int (foo::*)>
422 struct zed {};
423 void g(zed<&foo::bar>*)
424 {}
425}
426// CHECK: define void @_ZN5test51gEPNS_3zedIXadL_ZNS_3foo3barEEEEE
427namespace test5 {
428 struct foo { static int bar; };
429 template <int *>
430 struct zed {};
431 void g(zed<&foo::bar>*)
432 {}
433}
434// CHECK: define void @_ZN5test61gEPNS_3zedIXadL_ZNS_3foo3barEvEEEE
435namespace test6 {
436 struct foo { int bar(); };
437 template <int (foo::*)()>
438 struct zed {};
439 void g(zed<&foo::bar>*)
440 {}
441}
442// CHECK: define void @_ZN5test71gEPNS_3zedIXadL_ZNS_3foo3barEvEEEE
443namespace test7 {
444 struct foo { static int bar(); };
445 template <int (*f)()>
446 struct zed {};
447 void g(zed<&foo::bar>*)
448 {}
449}
Douglas Gregorb14d1232010-03-13 18:23:07 +0000450// CHECK: define weak_odr void @_ZN5test81AILZNS_1B5valueEEE3incEv
Rafael Espindola4d5c3d92010-03-11 14:07:00 +0000451namespace test8 {
452 template <int &counter> class A { void inc() { counter++; } };
John McCall3155f572010-04-09 19:03:51 +0000453 class B { public: static int value; };
Rafael Espindola4d5c3d92010-03-11 14:07:00 +0000454 template class A<B::value>;
455}
Rafael Espindolacd7eef92010-03-17 04:28:11 +0000456// CHECK: declare void @_ZN5test91fIiNS_3barEEEvRKNT0_3baz1XE
457namespace test9 {
458 template<class T>
459 struct foo {
460 typedef T X;
461 };
462 struct bar {
463 typedef foo<int> baz;
464 };
465 template <class zaz, class zed>
466 void f(const typename zed::baz::X&);
467 void g() {
468 f<int, bar>( 0);
469 }
470}
John McCall092775422010-04-09 21:48:08 +0000471
472// <rdar://problem/7825453>
473namespace test10 {
474 template <char P1> struct S {};
475 template <char P2> void f(struct S<false ? 'a' : P2> ) {}
476
477 // CHECK: define weak_odr void @_ZN6test101fILc3EEEvNS_1SIXquLb0ELc97ET_EEE(
478 template void f<(char) 3>(struct S<3>);
479}
Anders Carlsson728fe442010-06-02 04:40:13 +0000480
481namespace test11 {
482 // CHECK: @_ZN6test111fEz
483 void f(...) { }
484
485 struct A {
486 void f(...);
487 };
488
489 // CHECK: @_ZN6test111A1fEz
490 void A::f(...) { }
491}
Anders Carlssond951a7e2010-06-02 05:07:26 +0000492
493namespace test12 {
494
495 // CHECK: _ZN6test121fENS_1AILt33000EEE
496 template <unsigned short> struct A { };
497 void f(A<33000>) { }
John McCall4f3b5f32010-07-14 06:43:17 +0000498}
499
500// PR7446
501namespace test13 {
502 template <template <class> class T> class A {};
503 template <class U> class B {};
504
505 template <template<class> class T> void foo(const A<T> &a) {}
506
507 // CHECK: define weak_odr void @_ZN6test133fooINS_1BEEEvRKNS_1AIT_EE(
508 template void foo(const A<B> &a);
509}
Eli Friedmanf8340de2010-07-18 20:49:59 +0000510
511namespace test14 {
512 extern "C" {
513 struct S {
514 static int a(), x;
515 };
516 // CHECK: define i32 @_ZN6test141S1aEv
517 // CHECK: load i32* @_ZN6test141S1xE
518 int S::a() { return S::x; }
519 }
520}
John McCall268b5762010-07-24 01:17:35 +0000521
522// rdar://problem/8204122
523namespace test15 {
524 enum E { e = 3 };
525 template <int I> struct S {};
526
527 template <int I> void f(S<I + e>) {}
528
529 // CHECK: define weak_odr void @_ZN6test151fILi7EEEvNS_1SIXplT_LNS_1EE3EEEE(
530 template void f<7>(S<7 + e>);
531}
John McCall49146242010-08-05 22:02:13 +0000532
John McCall6d862022010-08-17 21:51:21 +0000533// rdar://problem/8302148
534namespace test17 {
535 template <int N> struct A {};
536
537 struct B {
538 static int foo(void);
539 };
540
541 template <class T> A<sizeof(T::foo())> func(void);
542
John McCallf834bcd2010-08-20 00:17:19 +0000543 // CHECK: define void @_ZN6test174testEv()
John McCall6d862022010-08-17 21:51:21 +0000544 // CHECK: call {{.*}} @_ZN6test174funcINS_1BEEENS_1AIXszclsrT_3fooEEEEv()
John McCallf834bcd2010-08-20 00:17:19 +0000545 void test() {
546 func<B>();
John McCall6d862022010-08-17 21:51:21 +0000547 }
548}
John McCall78fbb612010-08-18 19:18:59 +0000549
550// PR7891
551namespace test18 {
552 struct A {
553 int operator+();
554 int operator-();
555 int operator*();
556 int operator&();
557 };
558 template <int (A::*)()> struct S {};
559
560 template <typename T> void f(S<&T::operator+>) {}
561 template void f<A>(S<&A::operator+>);
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 // CHECK: define weak_odr void @_ZN6test181fINS_1AEEEvNS_1SIXadsrT_plEEE
573 // CHECK: define weak_odr void @_ZN6test181fINS_1AEEEvNS_1SIXadsrT_miEEE
574 // CHECK: define weak_odr void @_ZN6test181fINS_1AEEEvNS_1SIXadsrT_mlEEE
575 // CHECK: define weak_odr void @_ZN6test181fINS_1AEEEvNS_1SIXadsrT_anEEE
576}
John McCallf834bcd2010-08-20 00:17:19 +0000577
578// rdar://problem/8332117
579namespace test19 {
580 struct A {
581 template <typename T> int f();
582 int operator+();
583 operator int();
584 template <typename T> int operator-();
585 };
586
587 template <int (A::*)()> struct S {};
588
589 template <typename T> void g (S<&T::template f<int> >) {}
590 template <typename T> void g (S<&T::operator+ >) {}
591 template <typename T> void g (S<&T::operator int>) {}
592 template <typename T> void g (S<&T::template operator- <double> >) {}
593
594 // CHECK: define weak_odr void @_ZN6test191gINS_1AEEEvNS_1SIXadsrT_1fIiEEEE(
595 template void g<A>(S<&A::f<int> >);
596 // CHECK: define weak_odr void @_ZN6test191gINS_1AEEEvNS_1SIXadsrT_plEEE(
597 template void g<A>(S<&A::operator+>);
598 // CHECK: define weak_odr void @_ZN6test191gINS_1AEEEvNS_1SIXadsrT_cviEEE(
599 template void g<A>(S<&A::operator int>);
600 // CHECK: define weak_odr void @_ZN6test191gINS_1AEEEvNS_1SIXadsrT_miIdEEEE(
601 template void g<A>(S<&A::operator-<double> >);
602}
603
604namespace test20 {
605 template <class T> T *f(const T&);
606 template <class T> T *f(T*);
607
608 // CHECK: define weak_odr void @_ZN6test205test0IiEEvDTcl1fIPT_ELi0EEE(
609 template <class T> void test0(decltype(f<T*>(0))) {}
610 template void test0<int>(decltype(f<int*>(0)));
611
612 // CHECK: define weak_odr void @_ZN6test205test1IiEEvDTcl1fIEcvT__EEE(
613 template <class T> void test1(decltype(f<>(T()))) {}
614 template void test1<int>(decltype(f<>(int())));
615}
Fariborz Jahaniandc9bc5a2010-11-02 16:54:00 +0000616
617// rdar:// 8620510
618namespace test21 {
619 // CHECK: define void @_ZN6test2112vla_arg_funcEiPA_i(
620 void vla_arg_func(int X, int a[X][X]) {}
621}
Anders Carlsson2683fd62010-11-04 04:31:32 +0000622
623namespace test22 {
624 // CHECK: define void @_ZN6test221fEDn(
625 void f(decltype(nullptr)) { }
626}
John McCall5143d642011-01-26 20:05:40 +0000627
628// rdar://problem/8913416
629namespace test23 {
630 typedef void * const vpc;
631
632 // CHECK: define void @_ZN6test231fERA10_KPv(
633 void f(vpc (&)[10]) {}
634
635 typedef vpc vpca5[5];
636 void f(vpca5 volatile (&)[10]) {}
637 // CHECK: define void @_ZN6test231fERA10_A5_VKPv(
638}
John McCall290b32b2011-03-22 06:34:45 +0000639
640namespace test24 {
641 void test0() {
642 extern int foo();
643 // CHECK: call i32 @_ZN6test243fooEv()
644 foo();
645 }
646
647 static char foo() {}
648 void test1() {
649 // CHECK: call signext i8 @_ZN6test24L3fooEv()
650 foo();
651 }
652}
John McCall617339e2011-04-24 08:43:07 +0000653
654// rdar://problem/8806641
655namespace test25 {
656 template <void (*fn)()> struct A {
657 static void call() { fn(); }
658 };
659 void foo();
660 void test() {
661 // CHECK: call void @_ZN6test251AIXadL_ZNS_3fooEvEEE4callEv()
662 A<foo>::call();
663 }
664}
John McCall3ab84762011-05-04 01:45:19 +0000665
666namespace test26 {
667 template <template <class> class T> void foo(decltype(T<float>::object) &object) {}
668
669 template <class T> struct holder { static T object; };
670
671 void test() {
672 float f;
673
674 // CHECK: call void @_ZN6test263fooINS_6holderEEEvRDtsrT_IfE6objectE(
675 foo<holder>(f);
676 }
677}
678
679namespace test27 {
680 struct A {
681 struct inner {
682 float object;
683 };
684
685 float meth();
686 };
687 typedef A Alias;
688
689 template <class T> void a(decltype(T::inner::object) &object) {}
690 template <class T> void b(decltype(T().Alias::meth()) &object) {}
691
692 void test() {
693 float f;
694 // CHECK: call void @_ZN6test271aINS_1AEEEvRDtsrNT_5innerE6objectE(
695 a<A>(f);
696 // CHECK: call void @_ZN6test271bINS_1AEEEvRDTcldtcvT__Esr5AliasE4methEE(
697 b<A>(f);
698 }
699}
John McCall15547bb2011-06-28 16:49:23 +0000700
701// An injected class name type in a unresolved-name.
702namespace test28 {
703 template <class T> struct A {
704 enum { bit };
705 };
706
707 template <class T> void foo(decltype(A<T>::A::bit) x);
708
709 void test() {
710 foo<char>(A<char>::bit);
711 // CHECK: call void @_ZN6test283fooIcEEvDtsr1AIT_E1AE3bitE(
712 }
713}
714
715// An enclosing template type parameter in an unresolved-name.
716namespace test29 {
717 template <class T> struct A {
718 template <class U> static void foo(decltype(T::fn(U())) x);
719 };
720 struct B { static int fn(int); static long fn(long); };
721
722 void test() {
723 A<B>::foo<int>(0);
724 // CHECK: call void @_ZN6test291AINS_1BEE3fooIiEEvDTclsrS1_2fncvT__EEE(
725 }
726}
727
728// An enclosing template template parameter in an unresolved-name.
729namespace test30 {
730 template <template <class> class T> struct A {
731 template <class U> static void foo(decltype(T<U>::fn()) x);
732 };
733 template <class T> struct B { static T fn(); };
734
735 void test() {
736 A<B>::foo<int>(0);
John McCall3a4a4c52011-07-01 00:04:39 +0000737 // CHECK: call void @_ZN6test301AINS_1BEE3fooIiEEvDTclsrS1_IT_EE2fnEE(
John McCall15547bb2011-06-28 16:49:23 +0000738 }
739}
Douglas Gregor678d76c2011-07-01 01:22:09 +0000740
741namespace test31 { // instantiation-dependent mangling of decltype
742 int x;
743 template<class T> auto f1(T p)->decltype(x) { return 0; }
744 // The return type in the mangling of the template signature
745 // is encoded as "i".
746 template<class T> auto f2(T p)->decltype(p) { return 0; }
747 // The return type in the mangling of the template signature
748 // is encoded as "Dtfp_E".
749 void g(int);
750 template<class T> auto f3(T p)->decltype(g(p)) {}
751
752 // CHECK: define weak_odr i32 @_ZN6test312f1IiEEiT_(
753 template int f1(int);
754 // CHECK: define weak_odr i32 @_ZN6test312f2IiEEDtfp_ET_
755 template int f2(int);
756 // CHECK: define weak_odr void @_ZN6test312f3IiEEDTcl1gfp_EET_
757 template void f3(int);
758}
John McCall2de1c332011-07-01 02:19:08 +0000759
760// PR10205
761namespace test32 {
762 template<typename T, int=T::value> struct A {
763 typedef int type;
764 };
765 struct B { enum { value = 4 }; };
766
767 template <class T> typename A<T>::type foo() { return 0; }
768 void test() {
769 foo<B>();
770 // CHECK: call i32 @_ZN6test323fooINS_1BEEENS_1AIT_XsrS3_5valueEE4typeEv()
771 }
772}
773
774namespace test33 {
775 template <class T> struct X {
776 enum { value = T::value };
777 };
778
779 template<typename T, int=X<T>::value> struct A {
780 typedef int type;
781 };
782 struct B { enum { value = 4 }; };
783
784 template <class T> typename A<T>::type foo() { return 0; }
785
786 void test() {
787 foo<B>();
788 // CHECK: call i32 @_ZN6test333fooINS_1BEEENS_1AIT_Xsr1XIS3_EE5valueEE4typeEv()
789 }
790}
Douglas Gregor2e125502011-07-11 22:38:07 +0000791
792namespace test34 {
Douglas Gregor6ef06cc2011-07-12 04:47:20 +0000793 // Mangling for instantiation-dependent decltype expressions.
Douglas Gregor2e125502011-07-11 22:38:07 +0000794 template<typename T>
795 void f(decltype(sizeof(decltype(T() + T())))) {}
796
797 // CHECK: define weak_odr void @_ZN6test341fIiEEvDTstDTplcvT__EcvS1__EEE
798 template void f<int>(decltype(sizeof(1)));
Douglas Gregor6ef06cc2011-07-12 04:47:20 +0000799
800 // Mangling for non-instantiation-dependent sizeof expressions.
801 template<unsigned N>
802 void f2(int (&)[N + sizeof(int*)]) {}
803
804 // CHECK: define weak_odr void @_ZN6test342f2ILj4EEEvRAplT_Lm8E_i
805 template void f2<4>(int (&)[4 + sizeof(int*)]);
806
807 // Mangling for non-instantiation-dependent sizeof expressions
808 // involving an implicit conversion of the result of the sizeof.
809 template<unsigned long long N>
810 void f3(int (&)[N + sizeof(int*)]) {}
811
812 // CHECK: define weak_odr void @_ZN6test342f3ILy4EEEvRAplT_Ly8E_i
813 template void f3<4>(int (&)[4 + sizeof(int*)]);
Douglas Gregor2207ec22011-07-12 15:18:55 +0000814
815 // Mangling for instantiation-dependent sizeof() expressions as
816 // template arguments.
817 template<unsigned> struct A { };
818
819 template<typename T> void f4(::test34::A<sizeof(sizeof(decltype(T() + T())))>) { }
820
821 // CHECK: define weak_odr void @_ZN6test342f4IiEEvNS_1AIXszstDTplcvT__EcvS2__EEEEE
822 template void f4<int>(A<sizeof(sizeof(int))>);
Douglas Gregor2e125502011-07-11 22:38:07 +0000823}
Douglas Gregor1cf9dd22011-07-12 05:06:05 +0000824
825namespace test35 {
826 // Dependent operator names of unknown arity.
827 struct A {
828 template<typename U> A operator+(U) const;
829 };
830
831 template<typename T>
832 void f1(decltype(sizeof(&T::template operator+<int>))) {}
833
834 // CHECK: define weak_odr void @_ZN6test352f1INS_1AEEEvDTszadsrT_plIiEE
835 template void f1<A>(__SIZE_TYPE__);
836}
Douglas Gregore5802232011-07-12 07:03:48 +0000837
838namespace test36 {
839 template<unsigned> struct A { };
840
841 template<typename ...Types>
842 auto f1(Types... values) -> A<sizeof...(values)> { }
843
844 // CHECK: define weak_odr {{.*}} @_ZN6test362f1IJifEEENS_1AIXsZfp_EEEDpT_
845 template A<2> f1(int, float);
846}