blob: e7955a8ed910cb625d6a96f53deef292972463e2 [file] [log] [blame]
Richard Smith762bb9d2011-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 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 Carlsson0e650012009-05-17 17:41:20 +000079struct S;
80
Anders Carlsson9234b7f2009-09-17 03:46:43 +000081// CHECK: define void @_Z1fM1SKFvvE
Anders Carlsson0e650012009-05-17 17:41:20 +000082void f(void (S::*)() const) {}
83
Anders Carlsson9234b7f2009-09-17 03:46:43 +000084// CHECK: define void @_Z1fM1SFvvE
Anders Carlsson0e650012009-05-17 17:41:20 +000085void f(void (S::*)()) {}
Anders Carlssoncf85b932009-09-16 23:53:19 +000086
Anders Carlsson9234b7f2009-09-17 03:46:43 +000087// CHECK: define void @_Z1fi
Anders Carlssoncf85b932009-09-16 23:53:19 +000088void f(const int) { }
89
Anders Carlsson03c9d532009-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 Carlsson9234b7f2009-09-17 03:46:43 +000093
Anders Carlsson7624f212009-09-18 02:42:01 +000094template<typename T, typename U = S1<T> > struct S4 { };
95template<typename T> void ft3(S4<T>*) { }
96
Anders Carlsson7482e242009-09-18 04:29:09 +000097namespace NS {
98 template<typename T> void ft1(T) { }
Anders Carlsson7624f212009-09-18 02:42:01 +000099}
100
Anders Carlssond553f8c2009-09-21 01:21:10 +0000101void g1() {
Anders Carlsson03c9d532009-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 Carlsson7624f212009-09-18 02:42:01 +0000107
108 // CHECK: @_Z3ft3IiEvP2S4IT_2S1IS1_EE
109 ft3<int>(0);
Anders Carlsson7482e242009-09-18 04:29:09 +0000110
111 // CHECK: @_ZN2NS3ft1IiEEvT_
112 NS::ft1<int>(1);
Anders Carlssond58d6f72009-09-17 16:12:20 +0000113}
Anders Carlsson7482e242009-09-18 04:29:09 +0000114
Anders Carlssond553f8c2009-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 Carlsson7482e242009-09-18 04:29:09 +0000127extern "C++" {
128 // CHECK: @_Z1hv
129 void h() { }
130}
131
Anders Carlsson5cc58c62009-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 Carlssonadd28822009-09-22 20:33:31 +0000139
140// PR5017
141extern "C" {
142struct Debug {
Anders Carlsson8257d412009-12-22 06:36:32 +0000143 const Debug& operator<< (unsigned a) const { return *this; }
Anders Carlssonadd28822009-09-22 20:33:31 +0000144};
145Debug dbg;
146// CHECK: @_ZNK5DebuglsEj
147int main(void) { dbg << 32 ;}
148}
Anders Carlssonae352482009-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 Carlsson1668f202009-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 Carlssonaeb85372009-09-26 22:18:22 +0000164// CHECK: @_ZN2NSeqIcEEbRK1AIT_ES5_
Anders Carlsson1668f202009-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 Carlsson0ccdf8d2009-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 Carlsson50755b02009-09-27 20:11:34 +0000182
John Wiegley20c0da72011-04-27 23:09:49 +0000183template<typename> struct __is_scalar_type {
Richard Smith2bcb9842012-09-13 22:00:12 +0000184 enum { __value = 1 };
Anders Carlsson50755b02009-09-27 20:11:34 +0000185};
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 Wiegley20c0da72011-04-27 23:09:49 +0000194template<typename T> typename __enable_if<__is_scalar_type<T>::__value, void>::__type ft7() { }
Anders Carlsson50755b02009-09-27 20:11:34 +0000195
John McCall26a6ec72011-06-21 22:12:46 +0000196// CHECK: @_Z3ft7IiEN11__enable_ifIXsr16__is_scalar_typeIT_EE7__valueEvE6__typeEv
Anders Carlsson50755b02009-09-27 20:11:34 +0000197template void ft7<int>();
John McCall26a6ec72011-06-21 22:12:46 +0000198// CHECK: @_Z3ft7IPvEN11__enable_ifIXsr16__is_scalar_typeIT_EE7__valueEvE6__typeEv
Anders Carlsson50755b02009-09-27 20:11:34 +0000199template void ft7<void*>();
Anders Carlssonb217c1b2009-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 Carlssonc4355b62009-10-07 01:45:02 +0000209struct S7 {
Anders Carlsson5c478cf2009-12-04 22:33:25 +0000210 S7();
Anders Carlssonc4355b62009-10-07 01:45:02 +0000211
Anders Carlsson5c478cf2009-12-04 22:33:25 +0000212 struct S { S(); };
Anders Carlssonc4355b62009-10-07 01:45:02 +0000213 struct {
214 S s;
215 } a;
216};
217
218// PR5139
John McCall8e51a1f2010-02-18 21:31:48 +0000219// CHECK: @_ZN2S7C1Ev
Anders Carlssonc4355b62009-10-07 01:45:02 +0000220// CHECK: @_ZN2S7C2Ev
David Blaikie66cff722012-11-14 01:52:05 +0000221// CHECK: @_ZN2S7Ut_C1Ev
Anders Carlssonc4355b62009-10-07 01:45:02 +0000222S7::S7() {}
223
Anders Carlssona7694082009-11-06 02:50:19 +0000224// PR5063
John Wiegley20c0da72011-04-27 23:09:49 +0000225template<typename T> typename __enable_if<(__is_scalar_type<T>::__value), void>::__type ft8() { }
John McCall26a6ec72011-06-21 22:12:46 +0000226// CHECK: @_Z3ft8IiEN11__enable_ifIXsr16__is_scalar_typeIT_EE7__valueEvE6__typeEv
Anders Carlssona7694082009-11-06 02:50:19 +0000227template void ft8<int>();
John McCall26a6ec72011-06-21 22:12:46 +0000228// CHECK: @_Z3ft8IPvEN11__enable_ifIXsr16__is_scalar_typeIT_EE7__valueEvE6__typeEv
Anders Carlssona7694082009-11-06 02:50:19 +0000229template void ft8<void*>();
Anders Carlssone170ba72009-12-14 01:45:37 +0000230
Anders Carlsson58040a52009-12-16 05:48:46 +0000231// PR5796
232namespace PR5796 {
John Wiegley20c0da72011-04-27 23:09:49 +0000233template<typename> struct __is_scalar_type {
Richard Smith2bcb9842012-09-13 22:00:12 +0000234 enum { __value = 0 };
Anders Carlsson58040a52009-12-16 05:48:46 +0000235};
236
237template<bool, typename> struct __enable_if {};
238template<typename T> struct __enable_if<true, T> { typedef T __type; };
239template<typename T>
240
John McCall26a6ec72011-06-21 22:12:46 +0000241// CHECK: define linkonce_odr void @_ZN6PR57968__fill_aIiEENS_11__enable_ifIXntsr16__is_scalar_typeIT_EE7__valueEvE6__typeEv
John Wiegley20c0da72011-04-27 23:09:49 +0000242typename __enable_if<!__is_scalar_type<T>::__value, void>::__type __fill_a() { };
Anders Carlsson58040a52009-12-16 05:48:46 +0000243
244void f() { __fill_a<int>(); }
245}
246
Anders Carlssone170ba72009-12-14 01:45:37 +0000247namespace Expressions {
248// Unary operators.
249
Douglas Gregor8f51a4f2010-03-13 18:23:07 +0000250// CHECK: define weak_odr void @_ZN11Expressions2f1ILi1EEEvPAplngT_Li2E_i
Anders Carlssone170ba72009-12-14 01:45:37 +0000251template <int i> void f1(int (*)[(-i) + 2]) { };
252template void f1<1>(int (*)[1]);
253
Douglas Gregor8f51a4f2010-03-13 18:23:07 +0000254// CHECK: define weak_odr void @_ZN11Expressions2f2ILi1EEEvPApsT__i
Anders Carlssone170ba72009-12-14 01:45:37 +0000255template <int i> void f2(int (*)[+i]) { };
256template void f2<1>(int (*)[1]);
257
258// Binary operators.
259
Douglas Gregor8f51a4f2010-03-13 18:23:07 +0000260// CHECK: define weak_odr void @_ZN11Expressions2f3ILi1EEEvPAplT_T__i
Anders Carlssone170ba72009-12-14 01:45:37 +0000261template <int i> void f3(int (*)[i+i]) { };
262template void f3<1>(int (*)[2]);
263
Douglas Gregor8f51a4f2010-03-13 18:23:07 +0000264// CHECK: define weak_odr void @_ZN11Expressions2f4ILi1EEEvPAplplLi2ET_T__i
Anders Carlssone170ba72009-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 Gregor8f51a4f2010-03-13 18:23:07 +0000269// CHECK: define weak_odr void @_ZN11Expressions2f4ILb1EEEvPAquT_Li1ELi2E_i
Anders Carlssone170ba72009-12-14 01:45:37 +0000270template <bool b> void f4(int (*)[b ? 1 : 2]) { };
271template void f4<true>(int (*)[1]);
Anders Carlssone170ba72009-12-14 01:45:37 +0000272}
Anders Carlsson8257d412009-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 Carlsson9e85c742009-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 Gregor8f51a4f2010-03-13 18:23:07 +0000305// CHECK: define weak_odr i8* @_ZN6PR58615AllocIcNS_6PolicyINS_1PELb1EEEE8allocateEiPKv
Anders Carlsson9e85c742009-12-23 19:30:55 +0000306template class Alloc<char>;
307}
Anders Carlssonf28c6872009-12-23 22:31:44 +0000308
309// CHECK: define void @_Z1fU13block_pointerFiiiE
Nuno Lopesa9efbf02010-01-07 09:36:51 +0000310void f(int (^)(int, int)) { }
311
Sean Hunt31455252010-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 McCall1dd73832010-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 McCall1b600522011-04-24 03:07:16 +0000348 // CHECK: define linkonce_odr void @_ZN5test01gIfEEvRAszplcvT__ELf40a00000E_c(
John McCall1dd73832010-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 McCall2f27bf82010-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 McCalle1e342f2010-03-01 19:12:25 +0000363 // CHECK: define linkonce_odr void @_ZN5test01jINS_1AEEEvRAszdtcvT__E6buffer_c(
John McCall0c8731a2012-01-30 18:36:31 +0000364
365 template <class T> void k(char (&buffer)[sizeof(T() + 0.0f)]) {}
366 void test5() {
367 char buffer[sizeof(float)];
368 k<float>(buffer);
369 }
370 // CHECK: define linkonce_odr void @_ZN5test01kIfEEvRAszplcvT__ELf00000000E_c(
371
John McCall1dd73832010-02-04 01:42:13 +0000372}
Douglas Gregor32fb4e12010-02-05 20:45:00 +0000373
374namespace test1 {
375 template<typename T> struct X { };
376 template<template<class> class Y, typename T> void f(Y<T>) { }
Douglas Gregor8f51a4f2010-03-13 18:23:07 +0000377 // CHECK: define weak_odr void @_ZN5test11fINS_1XEiEEvT_IT0_E
Douglas Gregor32fb4e12010-02-05 20:45:00 +0000378 template void f(X<int>);
379}
Anders Carlssonaec25232010-02-06 04:52:27 +0000380
John McCall74990f42011-03-22 06:34:45 +0000381// CHECK: define internal void @_ZL27functionWithInternalLinkagev()
Anders Carlssonaec25232010-02-06 04:52:27 +0000382static void functionWithInternalLinkage() { }
383void g() { functionWithInternalLinkage(); }
John McCallad5e7382010-03-01 23:49:17 +0000384
385namespace test2 {
386 template <class T> decltype(((T*) 0)->member) read_member(T& obj) {
387 return obj.member;
388 }
389
390 struct A { int member; } obj;
391 int test() {
392 return read_member(obj);
393 }
394
395 // CHECK: define linkonce_odr i32 @_ZN5test211read_memberINS_1AEEEDtptcvPT_Li0E6memberERS2_(
396}
397
John McCalla0ce15c2011-04-24 08:23:24 +0000398// rdar://problem/9280586
John McCallad5e7382010-03-01 23:49:17 +0000399namespace test3 {
400 struct AmbiguousBase { int ab; };
401 struct Path1 : AmbiguousBase { float p; };
402 struct Path2 : AmbiguousBase { double p; };
403 struct Derived : Path1, Path2 { };
404
John McCall4f4e4132011-05-04 01:45:19 +0000405 // CHECK: define linkonce_odr i32 @_ZN5test38get_ab_1INS_7DerivedEEEDtptcvPT_Li0Esr5Path1E2abERS2_(
John McCalla0ce15c2011-04-24 08:23:24 +0000406 template <class T> decltype(((T*) 0)->Path1::ab) get_ab_1(T &ref) { return ref.Path1::ab; }
John McCallad5e7382010-03-01 23:49:17 +0000407
John McCall4f4e4132011-05-04 01:45:19 +0000408 // CHECK: define linkonce_odr i32 @_ZN5test38get_ab_2INS_7DerivedEEEDtptcvPT_Li0Esr5Path2E2abERS2_(
John McCalla0ce15c2011-04-24 08:23:24 +0000409 template <class T> decltype(((T*) 0)->Path2::ab) get_ab_2(T &ref) { return ref.Path2::ab; }
410
John McCall4f4e4132011-05-04 01:45:19 +0000411 // CHECK: define linkonce_odr float @_ZN5test37get_p_1INS_7DerivedEEEDtptcvPT_Li0Esr5Path1E1pERS2_(
John McCallad5e7382010-03-01 23:49:17 +0000412 template <class T> decltype(((T*) 0)->Path1::p) get_p_1(T &ref) { return ref.Path1::p; }
413
John McCall4f4e4132011-05-04 01:45:19 +0000414 // CHECK: define linkonce_odr double @_ZN5test37get_p_2INS_7DerivedEEEDtptcvPT_Li0Esr5Path2E1pERS2_(
John McCallad5e7382010-03-01 23:49:17 +0000415 template <class T> decltype(((T*) 0)->Path2::p) get_p_2(T &ref) { return ref.Path2::p; }
416
417 Derived obj;
418 void test() {
John McCalla0ce15c2011-04-24 08:23:24 +0000419 get_ab_1(obj);
420 get_ab_2(obj);
John McCallad5e7382010-03-01 23:49:17 +0000421 get_p_1(obj);
422 get_p_2(obj);
423 }
424}
Rafael Espindolad9800722010-03-11 14:07:00 +0000425
426// CHECK: define void @_ZN5test41gEPNS_3zedIXadL_ZNS_3foo3barEEEEE
427namespace test4 {
428 struct foo { int bar; };
429 template <int (foo::*)>
430 struct zed {};
431 void g(zed<&foo::bar>*)
432 {}
433}
434// CHECK: define void @_ZN5test51gEPNS_3zedIXadL_ZNS_3foo3barEEEEE
435namespace test5 {
436 struct foo { static int bar; };
437 template <int *>
438 struct zed {};
439 void g(zed<&foo::bar>*)
440 {}
441}
442// CHECK: define void @_ZN5test61gEPNS_3zedIXadL_ZNS_3foo3barEvEEEE
443namespace test6 {
444 struct foo { int bar(); };
445 template <int (foo::*)()>
446 struct zed {};
447 void g(zed<&foo::bar>*)
448 {}
449}
450// CHECK: define void @_ZN5test71gEPNS_3zedIXadL_ZNS_3foo3barEvEEEE
451namespace test7 {
452 struct foo { static int bar(); };
453 template <int (*f)()>
454 struct zed {};
455 void g(zed<&foo::bar>*)
456 {}
457}
Douglas Gregor8f51a4f2010-03-13 18:23:07 +0000458// CHECK: define weak_odr void @_ZN5test81AILZNS_1B5valueEEE3incEv
Rafael Espindolad9800722010-03-11 14:07:00 +0000459namespace test8 {
460 template <int &counter> class A { void inc() { counter++; } };
John McCall7002f4c2010-04-09 19:03:51 +0000461 class B { public: static int value; };
Rafael Espindolad9800722010-03-11 14:07:00 +0000462 template class A<B::value>;
463}
Rafael Espindola9b35b252010-03-17 04:28:11 +0000464// CHECK: declare void @_ZN5test91fIiNS_3barEEEvRKNT0_3baz1XE
465namespace test9 {
466 template<class T>
467 struct foo {
468 typedef T X;
469 };
470 struct bar {
471 typedef foo<int> baz;
472 };
473 template <class zaz, class zed>
474 void f(const typename zed::baz::X&);
475 void g() {
476 f<int, bar>( 0);
477 }
478}
John McCallde810632010-04-09 21:48:08 +0000479
480// <rdar://problem/7825453>
481namespace test10 {
482 template <char P1> struct S {};
483 template <char P2> void f(struct S<false ? 'a' : P2> ) {}
484
485 // CHECK: define weak_odr void @_ZN6test101fILc3EEEvNS_1SIXquLb0ELc97ET_EEE(
486 template void f<(char) 3>(struct S<3>);
487}
Anders Carlsson93296682010-06-02 04:40:13 +0000488
489namespace test11 {
490 // CHECK: @_ZN6test111fEz
491 void f(...) { }
492
493 struct A {
494 void f(...);
495 };
496
497 // CHECK: @_ZN6test111A1fEz
498 void A::f(...) { }
499}
Anders Carlssondfc0d1f2010-06-02 05:07:26 +0000500
501namespace test12 {
502
503 // CHECK: _ZN6test121fENS_1AILt33000EEE
504 template <unsigned short> struct A { };
505 void f(A<33000>) { }
John McCallb6f532e2010-07-14 06:43:17 +0000506}
507
508// PR7446
509namespace test13 {
510 template <template <class> class T> class A {};
511 template <class U> class B {};
512
513 template <template<class> class T> void foo(const A<T> &a) {}
514
515 // CHECK: define weak_odr void @_ZN6test133fooINS_1BEEEvRKNS_1AIT_EE(
516 template void foo(const A<B> &a);
517}
Eli Friedmanc00cb642010-07-18 20:49:59 +0000518
519namespace test14 {
520 extern "C" {
521 struct S {
522 static int a(), x;
523 };
524 // CHECK: define i32 @_ZN6test141S1aEv
525 // CHECK: load i32* @_ZN6test141S1xE
526 int S::a() { return S::x; }
527 }
528}
John McCall3dc7e7b2010-07-24 01:17:35 +0000529
530// rdar://problem/8204122
531namespace test15 {
532 enum E { e = 3 };
533 template <int I> struct S {};
534
535 template <int I> void f(S<I + e>) {}
536
537 // CHECK: define weak_odr void @_ZN6test151fILi7EEEvNS_1SIXplT_LNS_1EE3EEEE(
538 template void f<7>(S<7 + e>);
539}
John McCall7121c8f2010-08-05 22:02:13 +0000540
John McCall6f615bc2010-08-17 21:51:21 +0000541// rdar://problem/8302148
542namespace test17 {
543 template <int N> struct A {};
544
545 struct B {
546 static int foo(void);
547 };
548
549 template <class T> A<sizeof(T::foo())> func(void);
550
John McCall6dbce192010-08-20 00:17:19 +0000551 // CHECK: define void @_ZN6test174testEv()
John McCall6f615bc2010-08-17 21:51:21 +0000552 // CHECK: call {{.*}} @_ZN6test174funcINS_1BEEENS_1AIXszclsrT_3fooEEEEv()
John McCall6dbce192010-08-20 00:17:19 +0000553 void test() {
554 func<B>();
John McCall6f615bc2010-08-17 21:51:21 +0000555 }
556}
John McCall5e1e89b2010-08-18 19:18:59 +0000557
558// PR7891
559namespace test18 {
560 struct A {
561 int operator+();
562 int operator-();
563 int operator*();
564 int operator&();
565 };
566 template <int (A::*)()> struct S {};
567
568 template <typename T> void f(S<&T::operator+>) {}
569 template void f<A>(S<&A::operator+>);
570
571 template <typename T> void f(S<&T::operator- >) {}
572 template void f<A>(S<&A::operator- >);
573
574 template <typename T> void f(S<&T::operator*>) {}
575 template void f<A>(S<&A::operator*>);
576
577 template <typename T> void f(S<&T::operator&>) {}
578 template void f<A>(S<&A::operator&>);
579
580 // CHECK: define weak_odr void @_ZN6test181fINS_1AEEEvNS_1SIXadsrT_plEEE
581 // CHECK: define weak_odr void @_ZN6test181fINS_1AEEEvNS_1SIXadsrT_miEEE
582 // CHECK: define weak_odr void @_ZN6test181fINS_1AEEEvNS_1SIXadsrT_mlEEE
583 // CHECK: define weak_odr void @_ZN6test181fINS_1AEEEvNS_1SIXadsrT_anEEE
584}
John McCall6dbce192010-08-20 00:17:19 +0000585
586// rdar://problem/8332117
587namespace test19 {
588 struct A {
589 template <typename T> int f();
590 int operator+();
591 operator int();
592 template <typename T> int operator-();
593 };
594
595 template <int (A::*)()> struct S {};
596
597 template <typename T> void g (S<&T::template f<int> >) {}
598 template <typename T> void g (S<&T::operator+ >) {}
599 template <typename T> void g (S<&T::operator int>) {}
600 template <typename T> void g (S<&T::template operator- <double> >) {}
601
602 // CHECK: define weak_odr void @_ZN6test191gINS_1AEEEvNS_1SIXadsrT_1fIiEEEE(
603 template void g<A>(S<&A::f<int> >);
604 // CHECK: define weak_odr void @_ZN6test191gINS_1AEEEvNS_1SIXadsrT_plEEE(
605 template void g<A>(S<&A::operator+>);
606 // CHECK: define weak_odr void @_ZN6test191gINS_1AEEEvNS_1SIXadsrT_cviEEE(
607 template void g<A>(S<&A::operator int>);
608 // CHECK: define weak_odr void @_ZN6test191gINS_1AEEEvNS_1SIXadsrT_miIdEEEE(
609 template void g<A>(S<&A::operator-<double> >);
610}
611
612namespace test20 {
613 template <class T> T *f(const T&);
614 template <class T> T *f(T*);
615
616 // CHECK: define weak_odr void @_ZN6test205test0IiEEvDTcl1fIPT_ELi0EEE(
617 template <class T> void test0(decltype(f<T*>(0))) {}
618 template void test0<int>(decltype(f<int*>(0)));
619
620 // CHECK: define weak_odr void @_ZN6test205test1IiEEvDTcl1fIEcvT__EEE(
621 template <class T> void test1(decltype(f<>(T()))) {}
622 template void test1<int>(decltype(f<>(int())));
623}
Fariborz Jahanian7281d1f2010-11-02 16:54:00 +0000624
625// rdar:// 8620510
626namespace test21 {
627 // CHECK: define void @_ZN6test2112vla_arg_funcEiPA_i(
628 void vla_arg_func(int X, int a[X][X]) {}
629}
Anders Carlssone2923682010-11-04 04:31:32 +0000630
631namespace test22 {
632 // CHECK: define void @_ZN6test221fEDn(
633 void f(decltype(nullptr)) { }
634}
John McCallb47f7482011-01-26 20:05:40 +0000635
636// rdar://problem/8913416
637namespace test23 {
638 typedef void * const vpc;
639
640 // CHECK: define void @_ZN6test231fERA10_KPv(
641 void f(vpc (&)[10]) {}
642
643 typedef vpc vpca5[5];
644 void f(vpca5 volatile (&)[10]) {}
645 // CHECK: define void @_ZN6test231fERA10_A5_VKPv(
646}
John McCall74990f42011-03-22 06:34:45 +0000647
648namespace test24 {
649 void test0() {
650 extern int foo();
651 // CHECK: call i32 @_ZN6test243fooEv()
652 foo();
653 }
654
655 static char foo() {}
656 void test1() {
657 // CHECK: call signext i8 @_ZN6test24L3fooEv()
658 foo();
659 }
660}
John McCallc0a45592011-04-24 08:43:07 +0000661
662// rdar://problem/8806641
663namespace test25 {
664 template <void (*fn)()> struct A {
665 static void call() { fn(); }
666 };
667 void foo();
668 void test() {
669 // CHECK: call void @_ZN6test251AIXadL_ZNS_3fooEvEEE4callEv()
670 A<foo>::call();
671 }
672}
John McCall4f4e4132011-05-04 01:45:19 +0000673
674namespace test26 {
675 template <template <class> class T> void foo(decltype(T<float>::object) &object) {}
676
677 template <class T> struct holder { static T object; };
678
679 void test() {
680 float f;
681
682 // CHECK: call void @_ZN6test263fooINS_6holderEEEvRDtsrT_IfE6objectE(
683 foo<holder>(f);
684 }
685}
686
687namespace test27 {
688 struct A {
689 struct inner {
690 float object;
691 };
692
693 float meth();
694 };
695 typedef A Alias;
696
697 template <class T> void a(decltype(T::inner::object) &object) {}
698 template <class T> void b(decltype(T().Alias::meth()) &object) {}
699
700 void test() {
701 float f;
702 // CHECK: call void @_ZN6test271aINS_1AEEEvRDtsrNT_5innerE6objectE(
703 a<A>(f);
704 // CHECK: call void @_ZN6test271bINS_1AEEEvRDTcldtcvT__Esr5AliasE4methEE(
705 b<A>(f);
706 }
707}
John McCalld3d49bb2011-06-28 16:49:23 +0000708
709// An injected class name type in a unresolved-name.
710namespace test28 {
711 template <class T> struct A {
712 enum { bit };
713 };
714
715 template <class T> void foo(decltype(A<T>::A::bit) x);
716
717 void test() {
718 foo<char>(A<char>::bit);
719 // CHECK: call void @_ZN6test283fooIcEEvDtsr1AIT_E1AE3bitE(
720 }
721}
722
723// An enclosing template type parameter in an unresolved-name.
724namespace test29 {
725 template <class T> struct A {
726 template <class U> static void foo(decltype(T::fn(U())) x);
727 };
728 struct B { static int fn(int); static long fn(long); };
729
730 void test() {
731 A<B>::foo<int>(0);
732 // CHECK: call void @_ZN6test291AINS_1BEE3fooIiEEvDTclsrS1_2fncvT__EEE(
733 }
734}
735
736// An enclosing template template parameter in an unresolved-name.
737namespace test30 {
738 template <template <class> class T> struct A {
739 template <class U> static void foo(decltype(T<U>::fn()) x);
740 };
741 template <class T> struct B { static T fn(); };
742
743 void test() {
744 A<B>::foo<int>(0);
John McCall68a51a72011-07-01 00:04:39 +0000745 // CHECK: call void @_ZN6test301AINS_1BEE3fooIiEEvDTclsrS1_IT_EE2fnEE(
John McCalld3d49bb2011-06-28 16:49:23 +0000746 }
747}
Douglas Gregor561f8122011-07-01 01:22:09 +0000748
749namespace test31 { // instantiation-dependent mangling of decltype
750 int x;
751 template<class T> auto f1(T p)->decltype(x) { return 0; }
752 // The return type in the mangling of the template signature
753 // is encoded as "i".
754 template<class T> auto f2(T p)->decltype(p) { return 0; }
755 // The return type in the mangling of the template signature
756 // is encoded as "Dtfp_E".
757 void g(int);
758 template<class T> auto f3(T p)->decltype(g(p)) {}
759
760 // CHECK: define weak_odr i32 @_ZN6test312f1IiEEiT_(
761 template int f1(int);
762 // CHECK: define weak_odr i32 @_ZN6test312f2IiEEDtfp_ET_
763 template int f2(int);
764 // CHECK: define weak_odr void @_ZN6test312f3IiEEDTcl1gfp_EET_
765 template void f3(int);
766}
John McCall35ee32e2011-07-01 02:19:08 +0000767
768// PR10205
769namespace test32 {
770 template<typename T, int=T::value> struct A {
771 typedef int type;
772 };
773 struct B { enum { value = 4 }; };
774
775 template <class T> typename A<T>::type foo() { return 0; }
776 void test() {
777 foo<B>();
778 // CHECK: call i32 @_ZN6test323fooINS_1BEEENS_1AIT_XsrS3_5valueEE4typeEv()
779 }
780}
781
782namespace test33 {
783 template <class T> struct X {
784 enum { value = T::value };
785 };
786
787 template<typename T, int=X<T>::value> struct A {
788 typedef int type;
789 };
790 struct B { enum { value = 4 }; };
791
792 template <class T> typename A<T>::type foo() { return 0; }
793
794 void test() {
795 foo<B>();
796 // CHECK: call i32 @_ZN6test333fooINS_1BEEENS_1AIT_Xsr1XIS3_EE5valueEE4typeEv()
797 }
798}
Douglas Gregor5e78cd42011-07-11 22:38:07 +0000799
800namespace test34 {
Douglas Gregoredee94b2011-07-12 04:47:20 +0000801 // Mangling for instantiation-dependent decltype expressions.
Douglas Gregor5e78cd42011-07-11 22:38:07 +0000802 template<typename T>
803 void f(decltype(sizeof(decltype(T() + T())))) {}
804
805 // CHECK: define weak_odr void @_ZN6test341fIiEEvDTstDTplcvT__EcvS1__EEE
806 template void f<int>(decltype(sizeof(1)));
Douglas Gregoredee94b2011-07-12 04:47:20 +0000807
808 // Mangling for non-instantiation-dependent sizeof expressions.
809 template<unsigned N>
810 void f2(int (&)[N + sizeof(int*)]) {}
811
812 // CHECK: define weak_odr void @_ZN6test342f2ILj4EEEvRAplT_Lm8E_i
813 template void f2<4>(int (&)[4 + sizeof(int*)]);
814
815 // Mangling for non-instantiation-dependent sizeof expressions
816 // involving an implicit conversion of the result of the sizeof.
817 template<unsigned long long N>
818 void f3(int (&)[N + sizeof(int*)]) {}
819
820 // CHECK: define weak_odr void @_ZN6test342f3ILy4EEEvRAplT_Ly8E_i
821 template void f3<4>(int (&)[4 + sizeof(int*)]);
Douglas Gregorf1588662011-07-12 15:18:55 +0000822
823 // Mangling for instantiation-dependent sizeof() expressions as
824 // template arguments.
825 template<unsigned> struct A { };
826
827 template<typename T> void f4(::test34::A<sizeof(sizeof(decltype(T() + T())))>) { }
828
829 // CHECK: define weak_odr void @_ZN6test342f4IiEEvNS_1AIXszstDTplcvT__EcvS2__EEEEE
830 template void f4<int>(A<sizeof(sizeof(int))>);
Douglas Gregor5e78cd42011-07-11 22:38:07 +0000831}
Douglas Gregor19617912011-07-12 05:06:05 +0000832
833namespace test35 {
834 // Dependent operator names of unknown arity.
835 struct A {
836 template<typename U> A operator+(U) const;
837 };
838
839 template<typename T>
840 void f1(decltype(sizeof(&T::template operator+<int>))) {}
841
842 // CHECK: define weak_odr void @_ZN6test352f1INS_1AEEEvDTszadsrT_plIiEE
843 template void f1<A>(__SIZE_TYPE__);
844}
Douglas Gregor91832362011-07-12 07:03:48 +0000845
846namespace test36 {
847 template<unsigned> struct A { };
848
849 template<typename ...Types>
850 auto f1(Types... values) -> A<sizeof...(values)> { }
851
852 // CHECK: define weak_odr {{.*}} @_ZN6test362f1IJifEEENS_1AIXsZfp_EEEDpT_
853 template A<2> f1(int, float);
854}
David Blaikie66cff722012-11-14 01:52:05 +0000855
856namespace test37 {
857 struct foo {
858 struct {
859 } a;
860 typedef struct { } b;
861 typedef struct { } *c;
862 struct {
863 } d;
864 };
865 template<typename T> void func(T) { }
866 void test() {
867 // CHECK: define linkonce_odr void @_ZN6test374funcINS_3fooUt_EEEvT_
868 func(foo().a);
869 // CHECK: define linkonce_odr void @_ZN6test374funcINS_3fooUt0_EEEvT_
870 func(*foo::c());
871 // CHECK: define linkonce_odr void @_ZN6test374funcINS_3fooUt1_EEEvT_
872 func(foo().d);
873 }
874}
Tanya Lattnerf21107b2013-02-08 01:07:32 +0000875
876// CHECK: define void @_Z6ASfuncPU3AS3i
877void ASfunc(__attribute__((address_space(3))) int* x) {}