blob: 5012c3b37981e676fe102af5775ab5a357d95f74 [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
Richard Smitha41c97a2013-09-20 01:15:31 +000012//CHECK: @_ZL8pr5966_j = internal global
Sean Hunt31455252010-01-24 03:04:27 +000013
Stephen Lin93ab6bf2013-08-15 06:47:53 +000014// CHECK-LABEL: define zeroext i1 @_ZplRK1YRA100_P1X
Douglas Gregor5f2bfd42009-02-13 00:10:09 +000015bool operator+(const Y&, X* (&xs)[100]) { return false; }
16
Stephen Lin93ab6bf2013-08-15 06:47:53 +000017// CHECK-LABEL: define void @_Z1f1s
Anders Carlssonb1d947b2009-03-07 23:57:03 +000018typedef struct { int a; } s;
19void f(s) { }
20
Stephen Lin93ab6bf2013-08-15 06:47:53 +000021// CHECK-LABEL: define void @_Z1f1e
Anders Carlssonb1d947b2009-03-07 23:57:03 +000022typedef enum { foo } e;
23void f(e) { }
24
Stephen Lin93ab6bf2013-08-15 06:47:53 +000025// CHECK-LABEL: 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
Stephen Lin93ab6bf2013-08-15 06:47:53 +000029// CHECK-LABEL: define void @_Z1f1x
Anders Carlsson4843e582009-03-10 17:07:44 +000030typedef struct { int a; } x,y;
31void f(y) { }
32
Stephen Lin93ab6bf2013-08-15 06:47:53 +000033// CHECK-LABEL: define void @_Z1fv
Anders Carlssonc6c91bc2009-04-01 00:15:23 +000034void f() { }
Anders Carlsson984e0682009-04-01 00:58:25 +000035
Stephen Lin93ab6bf2013-08-15 06:47:53 +000036// CHECK-LABEL: define void @_ZN1N1fEv
Anders Carlsson984e0682009-04-01 00:58:25 +000037namespace N { void f() { } }
38
Stephen Lin93ab6bf2013-08-15 06:47:53 +000039// CHECK-LABEL: define void @_ZN1N1N1fEv
Anders Carlsson984e0682009-04-01 00:58:25 +000040namespace N { namespace N { void f() { } } }
Anders Carlsson91e20dd2009-04-02 05:55:18 +000041
Stephen Lin93ab6bf2013-08-15 06:47:53 +000042// CHECK-LABEL: 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
Stephen Lin93ab6bf2013-08-15 06:47:53 +000053// CHECK-LABEL: 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
Stephen Lin93ab6bf2013-08-15 06:47:53 +000058// CHECK-LABEL: define void @_Z1f2S1IiE
Anders Carlsson7a0ba872009-05-15 16:09:15 +000059void f(S1<int>) {}
60
Stephen Lin93ab6bf2013-08-15 06:47:53 +000061// CHECK-LABEL: define void @_Z1f2S1IdE
Anders Carlsson7a0ba872009-05-15 16:09:15 +000062void f(S1<double>) {}
63
64template <int N> struct S2 {};
Stephen Lin93ab6bf2013-08-15 06:47:53 +000065// CHECK-LABEL: define void @_Z1f2S2ILi100EE
Anders Carlsson7a0ba872009-05-15 16:09:15 +000066void f(S2<100>) {}
67
Stephen Lin93ab6bf2013-08-15 06:47:53 +000068// CHECK-LABEL: define void @_Z1f2S2ILin100EE
Anders Carlsson7a0ba872009-05-15 16:09:15 +000069void f(S2<-100>) {}
70
71template <bool B> struct S3 {};
72
Stephen Lin93ab6bf2013-08-15 06:47:53 +000073// CHECK-LABEL: define void @_Z1f2S3ILb1EE
Anders Carlsson7a0ba872009-05-15 16:09:15 +000074void f(S3<true>) {}
75
Stephen Lin93ab6bf2013-08-15 06:47:53 +000076// CHECK-LABEL: 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
Stephen Lin93ab6bf2013-08-15 06:47:53 +000081// CHECK-LABEL: define void @_Z1fM1SKFvvE
Anders Carlsson0e650012009-05-17 17:41:20 +000082void f(void (S::*)() const) {}
83
Stephen Lin93ab6bf2013-08-15 06:47:53 +000084// CHECK-LABEL: define void @_Z1fM1SFvvE
Anders Carlsson0e650012009-05-17 17:41:20 +000085void f(void (S::*)()) {}
Anders Carlssoncf85b932009-09-16 23:53:19 +000086
Stephen Lin93ab6bf2013-08-15 06:47:53 +000087// CHECK-LABEL: 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
Anders Carlssonc4355b62009-10-07 01:45:02 +0000219// CHECK: @_ZN2S7C2Ev
David Blaikie66cff722012-11-14 01:52:05 +0000220// CHECK: @_ZN2S7Ut_C1Ev
Stephen Hines651f13c2014-04-23 16:59:28 -0700221// CHECK: @_ZN2S7C1Ev
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
Stephen Lin93ab6bf2013-08-15 06:47:53 +0000241// CHECK-LABEL: 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
Stephen Lin93ab6bf2013-08-15 06:47:53 +0000250// CHECK-LABEL: 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
Stephen Lin93ab6bf2013-08-15 06:47:53 +0000254// CHECK-LABEL: 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
Stephen Lin93ab6bf2013-08-15 06:47:53 +0000260// CHECK-LABEL: 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
Stephen Lin93ab6bf2013-08-15 06:47:53 +0000264// CHECK-LABEL: 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.
Stephen Lin93ab6bf2013-08-15 06:47:53 +0000269// CHECK-LABEL: 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
Stephen Hines176edba2014-12-01 14:53:08 -0800283// CHECK-LABEL: define dereferenceable({{[0-9]+}}) %struct.Ops* @_ZN3OpsplERKS_
Anders Carlsson8257d412009-12-22 06:36:32 +0000284Ops& Ops::operator+(const Ops&) { return *this; }
Stephen Hines176edba2014-12-01 14:53:08 -0800285// CHECK-LABEL: define dereferenceable({{[0-9]+}}) %struct.Ops* @_ZN3OpsmiERKS_
Anders Carlsson8257d412009-12-22 06:36:32 +0000286Ops& Ops::operator-(const Ops&) { return *this; }
Stephen Hines176edba2014-12-01 14:53:08 -0800287// CHECK-LABEL: define dereferenceable({{[0-9]+}}) %struct.Ops* @_ZN3OpsanERKS_
Anders Carlsson8257d412009-12-22 06:36:32 +0000288Ops& Ops::operator&(const Ops&) { return *this; }
Stephen Hines176edba2014-12-01 14:53:08 -0800289// CHECK-LABEL: define dereferenceable({{[0-9]+}}) %struct.Ops* @_ZN3OpsmlERKS_
Anders Carlsson8257d412009-12-22 06:36:32 +0000290Ops& 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
Stephen Lin93ab6bf2013-08-15 06:47:53 +0000305// CHECK-LABEL: 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
Stephen Lin93ab6bf2013-08-15 06:47:53 +0000309// CHECK-LABEL: 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
Richard Smitha41c97a2013-09-20 01:15:31 +0000317static int pr5966_j;
Sean Hunt31455252010-01-24 03:04:27 +0000318
319void pr5966_bar() {
Richard Smitha41c97a2013-09-20 01:15:31 +0000320 pr5966_j = 0;
Sean Hunt31455252010-01-24 03:04:27 +0000321}
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 }
Stephen Lin93ab6bf2013-08-15 06:47:53 +0000333 // CHECK-LABEL: define void @_ZN5test05test0Ev()
334 // CHECK-LABEL: define linkonce_odr void @_ZN5test01fIdEEvT_RAszcl3ovlcvS1__EE_c(
John McCall1dd73832010-02-04 01:42:13 +0000335
336 void test1() {
337 char buffer[sizeof(int)];
338 f(1, buffer);
339 }
Stephen Lin93ab6bf2013-08-15 06:47:53 +0000340 // CHECK-LABEL: define void @_ZN5test05test1Ev()
341 // CHECK-LABEL: define linkonce_odr void @_ZN5test01fIiEEvT_RAszcl3ovlcvS1__EE_c(
John McCall1dd73832010-02-04 01:42:13 +0000342
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 }
Stephen Lin93ab6bf2013-08-15 06:47:53 +0000348 // CHECK-LABEL: 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 }
Stephen Lin93ab6bf2013-08-15 06:47:53 +0000355 // CHECK-LABEL: 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 }
Stephen Lin93ab6bf2013-08-15 06:47:53 +0000363 // CHECK-LABEL: 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 }
Stephen Lin93ab6bf2013-08-15 06:47:53 +0000370 // CHECK-LABEL: define linkonce_odr void @_ZN5test01kIfEEvRAszplcvT__ELf00000000E_c(
John McCall0c8731a2012-01-30 18:36:31 +0000371
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>) { }
Stephen Lin93ab6bf2013-08-15 06:47:53 +0000377 // CHECK-LABEL: 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
Stephen Lin93ab6bf2013-08-15 06:47:53 +0000381// CHECK-LABEL: 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
Stephen Lin93ab6bf2013-08-15 06:47:53 +0000395 // CHECK-LABEL: define linkonce_odr i32 @_ZN5test211read_memberINS_1AEEEDtptcvPT_Li0E6memberERS2_(
John McCallad5e7382010-03-01 23:49:17 +0000396}
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
Stephen Lin93ab6bf2013-08-15 06:47:53 +0000405 // CHECK-LABEL: 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
Stephen Lin93ab6bf2013-08-15 06:47:53 +0000408 // CHECK-LABEL: 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
Stephen Lin93ab6bf2013-08-15 06:47:53 +0000411 // CHECK-LABEL: 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
Stephen Lin93ab6bf2013-08-15 06:47:53 +0000414 // CHECK-LABEL: 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
Stephen Lin93ab6bf2013-08-15 06:47:53 +0000426// CHECK-LABEL: define void @_ZN5test41gEPNS_3zedIXadL_ZNS_3foo3barEEEEE
Rafael Espindolad9800722010-03-11 14:07:00 +0000427namespace test4 {
428 struct foo { int bar; };
429 template <int (foo::*)>
430 struct zed {};
431 void g(zed<&foo::bar>*)
432 {}
433}
Stephen Lin93ab6bf2013-08-15 06:47:53 +0000434// CHECK-LABEL: define void @_ZN5test51gEPNS_3zedIXadL_ZNS_3foo3barEEEEE
Rafael Espindolad9800722010-03-11 14:07:00 +0000435namespace test5 {
436 struct foo { static int bar; };
437 template <int *>
438 struct zed {};
439 void g(zed<&foo::bar>*)
440 {}
441}
Stephen Lin93ab6bf2013-08-15 06:47:53 +0000442// CHECK-LABEL: define void @_ZN5test61gEPNS_3zedIXadL_ZNS_3foo3barEvEEEE
Rafael Espindolad9800722010-03-11 14:07:00 +0000443namespace test6 {
444 struct foo { int bar(); };
445 template <int (foo::*)()>
446 struct zed {};
447 void g(zed<&foo::bar>*)
448 {}
449}
Stephen Lin93ab6bf2013-08-15 06:47:53 +0000450// CHECK-LABEL: define void @_ZN5test71gEPNS_3zedIXadL_ZNS_3foo3barEvEEEE
Rafael Espindolad9800722010-03-11 14:07:00 +0000451namespace test7 {
452 struct foo { static int bar(); };
453 template <int (*f)()>
454 struct zed {};
455 void g(zed<&foo::bar>*)
456 {}
457}
Stephen Hines0e2c34f2015-03-23 12:09:02 -0700458// CHECK-LABEL: define weak_odr void @_ZN5test81AIL_ZNS_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
Stephen Lin93ab6bf2013-08-15 06:47:53 +0000485 // CHECK-LABEL: define weak_odr void @_ZN6test101fILc3EEEvNS_1SIXquLb0ELc97ET_EEE(
John McCallde810632010-04-09 21:48:08 +0000486 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
Stephen Lin93ab6bf2013-08-15 06:47:53 +0000515 // CHECK-LABEL: define weak_odr void @_ZN6test133fooINS_1BEEEvRKNS_1AIT_EE(
John McCallb6f532e2010-07-14 06:43:17 +0000516 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 };
Stephen Lin93ab6bf2013-08-15 06:47:53 +0000524 // CHECK-LABEL: define i32 @_ZN6test141S1aEv
Pirama Arumuga Nainar3ea9e332015-04-08 08:57:32 -0700525 // CHECK: load i32, i32* @_ZN6test141S1xE
Eli Friedmanc00cb642010-07-18 20:49:59 +0000526 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
Stephen Lin93ab6bf2013-08-15 06:47:53 +0000537 // CHECK-LABEL: define weak_odr void @_ZN6test151fILi7EEEvNS_1SIXplT_LNS_1EE3EEEE(
John McCall3dc7e7b2010-07-24 01:17:35 +0000538 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
Stephen Lin93ab6bf2013-08-15 06:47:53 +0000551 // CHECK-LABEL: 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
Stephen Hines0e2c34f2015-03-23 12:09:02 -0700580 // CHECK-LABEL: define weak_odr void @_ZN6test181fINS_1AEEEvNS_1SIXadsrT_onplEEE
581 // CHECK-LABEL: define weak_odr void @_ZN6test181fINS_1AEEEvNS_1SIXadsrT_onmiEEE
582 // CHECK-LABEL: define weak_odr void @_ZN6test181fINS_1AEEEvNS_1SIXadsrT_onmlEEE
583 // CHECK-LABEL: define weak_odr void @_ZN6test181fINS_1AEEEvNS_1SIXadsrT_onanEEE
John McCall5e1e89b2010-08-18 19:18:59 +0000584}
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
Stephen Lin93ab6bf2013-08-15 06:47:53 +0000602 // CHECK-LABEL: define weak_odr void @_ZN6test191gINS_1AEEEvNS_1SIXadsrT_1fIiEEEE(
John McCall6dbce192010-08-20 00:17:19 +0000603 template void g<A>(S<&A::f<int> >);
Stephen Hines0e2c34f2015-03-23 12:09:02 -0700604 // CHECK-LABEL: define weak_odr void @_ZN6test191gINS_1AEEEvNS_1SIXadsrT_onplEEE(
John McCall6dbce192010-08-20 00:17:19 +0000605 template void g<A>(S<&A::operator+>);
Stephen Hines0e2c34f2015-03-23 12:09:02 -0700606 // CHECK-LABEL: define weak_odr void @_ZN6test191gINS_1AEEEvNS_1SIXadsrT_oncviEEE(
John McCall6dbce192010-08-20 00:17:19 +0000607 template void g<A>(S<&A::operator int>);
Stephen Hines0e2c34f2015-03-23 12:09:02 -0700608 // CHECK-LABEL: define weak_odr void @_ZN6test191gINS_1AEEEvNS_1SIXadsrT_onmiIdEEEE(
John McCall6dbce192010-08-20 00:17:19 +0000609 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
Stephen Lin93ab6bf2013-08-15 06:47:53 +0000616 // CHECK-LABEL: define weak_odr void @_ZN6test205test0IiEEvDTcl1fIPT_ELi0EEE(
John McCall6dbce192010-08-20 00:17:19 +0000617 template <class T> void test0(decltype(f<T*>(0))) {}
618 template void test0<int>(decltype(f<int*>(0)));
619
Stephen Lin93ab6bf2013-08-15 06:47:53 +0000620 // CHECK-LABEL: define weak_odr void @_ZN6test205test1IiEEvDTcl1fIEcvT__EEE(
John McCall6dbce192010-08-20 00:17:19 +0000621 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 {
Stephen Lin93ab6bf2013-08-15 06:47:53 +0000627 // CHECK-LABEL: define void @_ZN6test2112vla_arg_funcEiPA_i(
Fariborz Jahanian7281d1f2010-11-02 16:54:00 +0000628 void vla_arg_func(int X, int a[X][X]) {}
629}
Anders Carlssone2923682010-11-04 04:31:32 +0000630
631namespace test22 {
Stephen Lin93ab6bf2013-08-15 06:47:53 +0000632 // CHECK-LABEL: define void @_ZN6test221fEDn(
Anders Carlssone2923682010-11-04 04:31:32 +0000633 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
Stephen Lin93ab6bf2013-08-15 06:47:53 +0000640 // CHECK-LABEL: define void @_ZN6test231fERA10_KPv(
John McCallb47f7482011-01-26 20:05:40 +0000641 void f(vpc (&)[10]) {}
642
643 typedef vpc vpca5[5];
644 void f(vpca5 volatile (&)[10]) {}
Stephen Lin93ab6bf2013-08-15 06:47:53 +0000645 // CHECK-LABEL: define void @_ZN6test231fERA10_A5_VKPv(
John McCallb47f7482011-01-26 20:05:40 +0000646}
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
Richard Smitha41c97a2013-09-20 01:15:31 +0000655 static char bar() {}
John McCall74990f42011-03-22 06:34:45 +0000656 void test1() {
Richard Smitha41c97a2013-09-20 01:15:31 +0000657 // CHECK: call signext i8 @_ZN6test24L3barEv()
658 bar();
John McCall74990f42011-03-22 06:34:45 +0000659 }
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
Stephen Lin93ab6bf2013-08-15 06:47:53 +0000760 // CHECK-LABEL: define weak_odr i32 @_ZN6test312f1IiEEiT_(
Douglas Gregor561f8122011-07-01 01:22:09 +0000761 template int f1(int);
Stephen Lin93ab6bf2013-08-15 06:47:53 +0000762 // CHECK-LABEL: define weak_odr i32 @_ZN6test312f2IiEEDtfp_ET_
Douglas Gregor561f8122011-07-01 01:22:09 +0000763 template int f2(int);
Stephen Lin93ab6bf2013-08-15 06:47:53 +0000764 // CHECK-LABEL: define weak_odr void @_ZN6test312f3IiEEDTcl1gfp_EET_
Douglas Gregor561f8122011-07-01 01:22:09 +0000765 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
Stephen Lin93ab6bf2013-08-15 06:47:53 +0000805 // CHECK-LABEL: define weak_odr void @_ZN6test341fIiEEvDTstDTplcvT__EcvS1__EEE
Douglas Gregor5e78cd42011-07-11 22:38:07 +0000806 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
Stephen Lin93ab6bf2013-08-15 06:47:53 +0000812 // CHECK-LABEL: define weak_odr void @_ZN6test342f2ILj4EEEvRAplT_Lm8E_i
Douglas Gregoredee94b2011-07-12 04:47:20 +0000813 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
Stephen Lin93ab6bf2013-08-15 06:47:53 +0000820 // CHECK-LABEL: define weak_odr void @_ZN6test342f3ILy4EEEvRAplT_Ly8E_i
Douglas Gregoredee94b2011-07-12 04:47:20 +0000821 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
Stephen Lin93ab6bf2013-08-15 06:47:53 +0000829 // CHECK-LABEL: define weak_odr void @_ZN6test342f4IiEEvNS_1AIXszstDTplcvT__EcvS2__EEEEE
Douglas Gregorf1588662011-07-12 15:18:55 +0000830 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
Stephen Hines0e2c34f2015-03-23 12:09:02 -0700842 // CHECK-LABEL: define weak_odr void @_ZN6test352f1INS_1AEEEvDTszadsrT_onplIiEE
Douglas Gregor19617912011-07-12 05:06:05 +0000843 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() {
Stephen Lin93ab6bf2013-08-15 06:47:53 +0000867 // CHECK-LABEL: define linkonce_odr void @_ZN6test374funcINS_3fooUt_EEEvT_
David Blaikie66cff722012-11-14 01:52:05 +0000868 func(foo().a);
Stephen Lin93ab6bf2013-08-15 06:47:53 +0000869 // CHECK-LABEL: define linkonce_odr void @_ZN6test374funcINS_3fooUt0_EEEvT_
David Blaikie66cff722012-11-14 01:52:05 +0000870 func(*foo::c());
Stephen Lin93ab6bf2013-08-15 06:47:53 +0000871 // CHECK-LABEL: define linkonce_odr void @_ZN6test374funcINS_3fooUt1_EEEvT_
David Blaikie66cff722012-11-14 01:52:05 +0000872 func(foo().d);
873 }
874}
Tanya Lattnerf21107b2013-02-08 01:07:32 +0000875
Stephen Lin93ab6bf2013-08-15 06:47:53 +0000876// CHECK-LABEL: define void @_Z6ASfuncPU3AS3i
Tanya Lattnerf21107b2013-02-08 01:07:32 +0000877void ASfunc(__attribute__((address_space(3))) int* x) {}
Rafael Espindola5bbb0582013-05-28 14:09:46 +0000878
879namespace test38 {
Stephen Lin93ab6bf2013-08-15 06:47:53 +0000880 // CHECK-LABEL: define linkonce_odr void @_ZN6test384funcINS_3fooUt_EEEvT_
Rafael Espindola5bbb0582013-05-28 14:09:46 +0000881 typedef struct {
882 struct {
883 } a;
884 } foo;
885
886 template <typename T> void func(T) {}
887 void test() { func(foo().a); }
888}
889
890namespace test39 {
Stephen Lin93ab6bf2013-08-15 06:47:53 +0000891 // CHECK-LABEL: define internal void @"_ZN6test394funcINS_3$_03$_1EEEvT_"
Rafael Espindola5bbb0582013-05-28 14:09:46 +0000892 typedef struct {
893 struct {} a;
894 } *foo;
895 template<typename T> void func(T) {}
896 void test(foo x) {
897 func(x->a);
898 }
899}
Eli Friedman5e867c82013-07-10 00:30:46 +0000900
901namespace test40 {
Stephen Hinesc568f1e2014-07-21 00:47:37 -0700902 // CHECK: i32* {{.*}} @_ZZN6test401fEvE1a_0
Eli Friedman5e867c82013-07-10 00:30:46 +0000903 void h(int&);
904 inline void f() {
905 if (0) {
906 static int a;
907 }
908 static int a;
909 h(a);
910 };
911 void g() { f(); }
912}
David Majnemer9d57b8d2013-08-28 23:48:32 +0000913
914namespace test41 {
915 // CHECK: define linkonce_odr void @_ZN6test414funcINS_1XEEEvNS_3fooILi20ES1_EE
916 template <int i, class T> struct foo {
917 template <class T2 = T> friend void func(foo x) {}
918 };
919
920 struct X {};
921
922 void g() { func(foo<20, X>()); }
923}
924
925namespace test42 {
926 // CHECK: define linkonce_odr void @_ZN6test424funcINS_1XEEEvNS_3fooILi20ES1_EE
927 template <int i, template <class> class T> struct foo {
928 template <template <class> class T2 = T> friend void func(foo x) {}
929 };
930
931 template <class V> struct X {
932 };
933
934 void g() { func(foo<20, X>()); }
935}
David Majnemer885d8bf2013-10-23 20:52:43 +0000936
937namespace test43 {
938 // CHECK-LABEL: define void @_ZN6test431gEPNS_3zedIXadL_ZNS_3fooUt_3barEEEEE
939 struct foo { union { int bar; }; };
940 template <int (foo::*)>
941 struct zed {};
942 void g(zed<&foo::bar>*)
943 {}
944}
David Majnemer62e93702013-11-03 23:51:28 +0000945
946namespace test44 {
947 struct foo { void bar() __restrict { }; } obj;
948
949 void f() {
950 obj.bar();
951 }
952 // CHECK-LABEL: define linkonce_odr void @_ZN6test443foo3barEv(%"struct.test44::foo"* %this)
953}
Stephen Hines6bcf27b2014-05-29 04:14:42 -0700954
955namespace test45 {
956 struct S {
957 enum e {};
958 };
959 template <typename T>
960 void f(enum T::e *) {}
961 template void f<S>(S::e *);
962 // CHECK-LABEL: define weak_odr void @_ZN6test451fINS_1SEEEvPTeNT_1eE(i32*)
963}
964
965namespace test46 {
966 struct S {
967 struct s {};
968 };
969 template <typename T>
970 void f(struct T::s *) {}
971 template void f<S>(S::s *);
972 // CHECK-LABEL: define weak_odr void @_ZN6test461fINS_1SEEEvPTsNT_1sE(%"struct.test46::S::s"*)
973}
974
975namespace test47 {
976 struct S {
977 class c {};
978 };
979 template <typename T>
980 void f(class T::c *) {}
981 template void f<S>(S::c *);
982 // CHECK-LABEL: define weak_odr void @_ZN6test471fINS_1SEEEvPTsNT_1cE(%"class.test47::S::c"*)
983}
984
985namespace test48 {
986 struct S {
987 union u {};
988 };
989 template <typename T>
990 void f(union T::u *) {}
991 template void f<S>(S::u *);
992 // CHECK-LABEL: define weak_odr void @_ZN6test481fINS_1SEEEvPTuNT_1uE(%"union.test48::S::u"*)
993}
Stephen Hines176edba2014-12-01 14:53:08 -0800994
995namespace test49 {
996 template <int>
997 struct S {};
998
999 template <template <int> class T>
1000 T<3> fin(T<3>);
1001
1002 auto v = fin<S>;
1003 // CHECK-LABEL: declare void @_ZN6test493finINS_1SEEET_ILi3EES3_()
1004}
1005
1006namespace test50 {
1007 template <int>
1008 struct S {};
1009
1010 template <template <int> class T>
1011 T<3> fin(T<4>);
1012
1013 auto v = fin<S>;
1014 // CHECK-LABEL: declare void @_ZN6test503finINS_1SEEET_ILi3EES2_ILi4EE()
1015}
Stephen Hines0e2c34f2015-03-23 12:09:02 -07001016
1017namespace test51 {
1018 template <typename T>
1019 decltype(T().~T()) fun() {}
1020 template void fun<int>();
1021 // CHECK-LABEL: @_ZN6test513funIiEEDTcldtcvT__EdnS1_EEv
1022 template void fun<X>();
1023 // CHECK-LABEL: @_ZN6test513funI1XEEDTcldtcvT__EdnS2_EEv
1024 template void fun<S1<int> >();
1025 // CHECK-LABEL: @_ZN6test513funI2S1IiEEEDTcldtcvT__EdnS3_EEv
1026
1027 enum E {};
1028 template <typename T>
1029 struct X {
1030 struct Y {};
1031 };
1032
1033 template <typename T>
1034 decltype(S1<T>().~S1<T>()) fun1() {};
1035 template <typename U, typename T>
1036 decltype(U().~S1<T>()) fun2() {}
1037 template <typename U, typename T>
1038 decltype(S1<T>().~U()) fun3() {}
1039 template <typename T>
1040 decltype(S1<T>().~S1<T>(), S1<T>().~S1<T>()) fun4() {};
1041 template <typename T>
1042 decltype(S1<int>().~S1<T>()) fun5(){};
1043 template <template <typename T> class U>
1044 decltype(S1<int>().~U<int>()) fun6(){};
1045 template <typename T>
1046 decltype(E().E::~T()) fun7() {}
1047 template <template <typename> class U>
1048 decltype(X<int>::Y().U<int>::Y::~Y()) fun8() {}
1049 template void fun1<int>();
1050 // CHECK-LABEL: @_ZN6test514fun1IiEEDTcldtcv2S1IT_E_Edn2S1IS2_EEEv
1051 template void fun2<S1<int>, int>();
1052 // CHECK-LABEL: @_ZN6test514fun2I2S1IiEiEEDTcldtcvT__Edn2S1IT0_EEEv
1053 template void fun3<S1<int>, int>();
1054 // CHECK-LABEL: @_ZN6test514fun3I2S1IiEiEEDTcldtcvS1_IT0_E_EdnT_EEv
1055 template void fun4<int>();
1056 // CHECK-LABEL: @_ZN6test514fun4IiEEDTcmcldtcv2S1IT_E_Edn2S1IS2_EEcldtcvS3__Edn2S1IS2_EEEv
1057 template void fun5<int>();
1058 // CHECK-LABEL: @_ZN6test514fun5IiEEDTcldtcv2S1IiE_Edn2S1IT_EEEv
1059 template void fun6<S1>();
1060 // CHECK-LABEL: @_ZN6test514fun6I2S1EEDTcldtcvS1_IiE_EdnT_IiEEEv
1061 template void fun7<E>();
1062 // CHECK-LABEL: @_ZN6test514fun7INS_1EEEEDTcldtcvS1__Esr1EEdnT_EEv
1063 template void fun8<X>();
1064}
1065
1066namespace test52 {
1067struct X {};
1068void operator+(X);
1069template <typename... T>
1070auto f4(T... x) -> decltype(operator+(x...));
1071// CHECK-LABEL: @_ZN6test522f4IJNS_1XEEEEDTclonplspfp_EEDpT_
1072void use() { f4(X{}); }
1073}
Pirama Arumuga Nainar3ea9e332015-04-08 08:57:32 -07001074
1075namespace test53 {
1076struct c {
1077 using t1 = struct { int z; };
1078 using t2 = struct { double z; };
1079 using t3 = struct { float z; };
1080 using t4 = struct { float z; };
1081
1082 __attribute__((used)) c(t1) {}
1083 __attribute__((used)) c(t2) {}
1084 __attribute__((used)) c(t3) {}
1085 __attribute__((used)) c(t4) {}
1086 // CHECK-LABEL: @_ZN6test531cC2ENS0_2t1E
1087 // CHECK-LABEL: @_ZN6test531cC2ENS0_2t2E
1088 // CHECK-LABEL: @_ZN6test531cC2ENS0_2t3E
1089 // CHECK-LABEL: @_ZN6test531cC2ENS0_2t4E
1090};
1091}
1092
1093namespace test54 {
1094struct c {
1095 using t1 = struct { int z; } *;
1096 using t2 = struct { double z; } *;
1097
1098 __attribute__((used)) c(t1) {}
1099 __attribute__((used)) c(t2) {}
1100 // CHECK-LABEL: @_ZN6test541cC2EPNS0_Ut_E
1101 // CHECK-LABEL: @_ZN6test541cC2EPNS0_Ut0_E
1102};
1103}