1 // RUN: %clang_cc1 -verify -Wno-return-type -Wno-main -std=c++11 -emit-llvm -triple %itanium_abi_triple -o - %s | FileCheck %s 2 // expected-no-diagnostics 3 4 namespace test1 { 5 int x; 6 template <int& D> class T { }; 7 // CHECK: void @_ZN5test12f0ENS_1TILZNS_1xEEEE( 8 void f0(T<x> a0) {} 9 } 10 11 namespace test1 { 12 // CHECK: void @_ZN5test12f0Ef 13 void f0(float) {} 14 template<void (&)(float)> struct t1 {}; 15 // CHECK: void @_ZN5test12f1ENS_2t1ILZNS_2f0EfEEE( 16 void f1(t1<f0> a0) {} 17 } 18 19 namespace test2 { 20 // CHECK: void @_ZN5test22f0Ef 21 void f0(float) {} 22 template<void (*)(float)> struct t1 {}; 23 // FIXME: Fails because we don't treat as an expression. 24 // CHECK-FIXME: void @_ZN5test22f1ENS_2t1IXadL_ZNS_2f0EfEEEE( 25 void f1(t1<f0> a0) {} 26 } 27 28 namespace test3 { 29 // CHECK: void @test3_f0 30 extern "C" void test3_f0(float) {} 31 template<void (&)(float)> struct t1 {}; 32 // FIXME: Fails because we tack on a namespace. 33 // CHECK-FIXME: void @_ZN5test32f1ENS_2t1ILZ8test3_f0EEE( 34 void f1(t1<test3_f0> a0) {} 35 } 36 37 namespace test4 { 38 // CHECK: void @test4_f0 39 extern "C" void test4_f0(float) {} 40 template<void (*)(float)> struct t1 {}; 41 // FIXME: Fails because we don't treat as an expression. 42 // CHECK-FIXME: void @_ZN5test42f1ENS_2t1IXadL_Z8test4_f0EEEE( 43 void f1(t1<test4_f0> a0) {} 44 } 45 46 // CHECK: void @test5_f0 47 extern "C" void test5_f0(float) {} 48 int main(int) {} 49 50 namespace test5 { 51 template<void (&)(float)> struct t1 {}; 52 // CHECK: void @_ZN5test52f1ENS_2t1ILZ8test5_f0EEE( 53 void f1(t1<test5_f0> a0) {} 54 55 template<int (&)(int)> struct t2 {}; 56 // CHECK: void @_ZN5test52f2ENS_2t2ILZ4mainEEE 57 void f2(t2<main> a0) {} 58 } 59 60 // FIXME: This fails. 61 namespace test6 { 62 struct A { void im0(float); }; 63 // CHECK: void @_ZN5test61A3im0Ef 64 void A::im0(float) {} 65 template <void(A::*)(float)> class T { }; 66 // FIXME: Fails because we don't treat as an expression. 67 // CHECK-FAIL: void @_ZN5test62f0ENS_1TIXadL_ZNS_1A3im0EfEEEE( 68 void f0(T<&A::im0> a0) {} 69 } 70 71 namespace test7 { 72 template<typename T> 73 struct meta { 74 static const unsigned value = sizeof(T); 75 }; 76 77 template<unsigned> struct int_c { 78 typedef float type; 79 }; 80 81 template<typename T> 82 struct X { 83 template<typename U> 84 X(U*, typename int_c<(meta<T>::value + meta<U>::value)>::type *) { } 85 }; 86 87 // CHECK: define weak_odr {{.*}} @_ZN5test71XIiEC1IdEEPT_PNS_5int_cIXplL_ZNS_4metaIiE5valueEEsr4metaIS3_EE5valueEE4typeE( 88 template X<int>::X(double*, float*); 89 } 90 91 namespace test8 { 92 template<typename T> 93 struct meta { 94 struct type { 95 static const unsigned value = sizeof(T); 96 }; 97 }; 98 99 template<unsigned> struct int_c { 100 typedef float type; 101 }; 102 103 template<typename T> 104 void f(int_c<meta<T>::type::value>) { } 105 106 // CHECK-LABEL: define weak_odr void @_ZN5test81fIiEEvNS_5int_cIXsr4metaIT_E4typeE5valueEEE( 107 template void f<int>(int_c<sizeof(int)>); 108 } 109 110 namespace test9 { 111 template<typename T> 112 struct supermeta { 113 template<typename U> 114 struct apply { 115 typedef T U::*type; 116 }; 117 }; 118 119 struct X { }; 120 121 template<typename T, typename U> 122 typename supermeta<T>::template apply<U>::type f(); 123 124 void test_f() { 125 // CHECK: @_ZN5test91fIiNS_1XEEENS_9supermetaIT_E5applyIT0_E4typeEv() 126 // Note: GCC incorrectly mangles this as 127 // _ZN5test91fIiNS_1XEEENS_9supermetaIT_E5apply4typeEv, while EDG 128 // gets it right. 129 f<int, X>(); 130 } 131 } 132 133 namespace test10 { 134 template<typename T> 135 struct X { 136 template<typename U> 137 struct definition { 138 }; 139 }; 140 141 // CHECK: _ZN6test101fIidEENS_1XIT_E10definitionIT0_EES2_S5_ 142 template<typename T, typename U> 143 typename X<T>::template definition<U> f(T, U) { } 144 145 void g(int i, double d) { 146 f(i, d); 147 } 148 } 149 150 // Report from cxx-abi-dev, 2012.01.04. 151 namespace test11 { 152 int cmp(char a, char b); 153 template <typename T, int (*cmp)(T, T)> struct A {}; 154 template <typename T> void f(A<T,cmp> &) {} 155 template void f<char>(A<char,cmp> &); 156 // CHECK: @_ZN6test111fIcEEvRNS_1AIT_L_ZNS_3cmpEccEEE( 157 } 158 159 namespace test12 { 160 // Make sure we can mangle non-type template args with internal linkage. 161 static int f() {} 162 const int n = 10; 163 template<typename T, T v> void test() {} 164 void use() { 165 // CHECK-LABEL: define internal void @_ZN6test124testIFivEXadL_ZNS_L1fEvEEEEvv( 166 test<int(), &f>(); 167 // CHECK-LABEL: define internal void @_ZN6test124testIRFivELZNS_L1fEvEEEvv( 168 test<int(&)(), f>(); 169 // CHECK-LABEL: define internal void @_ZN6test124testIPKiXadL_ZNS_L1nEEEEEvv( 170 test<const int*, &n>(); 171 // CHECK-LABEL: define internal void @_ZN6test124testIRKiLZNS_L1nEEEEvv( 172 test<const int&, n>(); 173 } 174 } 175 176 // rdar://problem/12072531 177 // Test the boundary condition of minimal signed integers. 178 namespace test13 { 179 template <char c> char returnChar() { return c; } 180 template char returnChar<-128>(); 181 // CHECK: @_ZN6test1310returnCharILcn128EEEcv() 182 183 template <short s> short returnShort() { return s; } 184 template short returnShort<-32768>(); 185 // CHECK: @_ZN6test1311returnShortILsn32768EEEsv() 186 } 187 188 namespace test14 { 189 template <typename> inline int inl(bool b) { 190 if (b) { 191 static struct { 192 int field; 193 } a; 194 // CHECK: @_ZZN6test143inlIvEEibE1a 195 196 return a.field; 197 } else { 198 static struct { 199 int field; 200 } a; 201 // CHECK: @_ZZN6test143inlIvEEibE1a_0 202 203 return a.field; 204 } 205 } 206 207 int call(bool b) { return inl<void>(b); } 208 } 209