1*67e74705SXin Li // RUN: %clang_cc1 %s -O1 -disable-llvm-optzns -triple=x86_64-apple-darwin10 -emit-llvm -o - | FileCheck %s 2*67e74705SXin Li 3*67e74705SXin Li // CHECK: @_ZN7PR100011xE = global 4*67e74705SXin Li // CHECK-NOT: @_ZN7PR100014kBarE = external global i32 5*67e74705SXin Li // 6*67e74705SXin Li // CHECK-NOT: @_ZTVN5test118stdio_sync_filebufIwEE = constant 7*67e74705SXin Li // CHECK-NOT: _ZTVN5test315basic_fstreamXXIcEE 8*67e74705SXin Li // CHECK-NOT: @_ZTVN5test018stdio_sync_filebufIA1_iEE 9*67e74705SXin Li // CHECK-NOT: @_ZTVN5test018stdio_sync_filebufIA2_iEE 10*67e74705SXin Li // CHECK: @_ZTVN5test018stdio_sync_filebufIA3_iEE = weak_odr unnamed_addr constant 11*67e74705SXin Li 12*67e74705SXin Li // CHECK: @_ZN7PR100011SIiE3arrE = linkonce_odr global [3 x i32] 13*67e74705SXin Li // CHECK-NOT: @_ZN7PR100011SIiE3arr2E = linkonce_odr global [3 x i32]A 14*67e74705SXin Li 15*67e74705SXin Li // CHECK: @_ZTVN5test018stdio_sync_filebufIA4_iEE = linkonce_odr unnamed_addr constant 16*67e74705SXin Li 17*67e74705SXin Li // CHECK-NOT: _ZTVN5test31SIiEE 18*67e74705SXin Li // CHECK-NOT: _ZTSN5test31SIiEE 19*67e74705SXin Li 20*67e74705SXin Li // CHECK-LABEL: define linkonce_odr void @_ZN5test21CIiEC1Ev(%"class.test2::C"* %this) unnamed_addr 21*67e74705SXin Li // CHECK-LABEL: define linkonce_odr void @_ZN5test21CIiE6foobarIdEEvT_( 22*67e74705SXin Li // CHECK-LABEL: define available_externally void @_ZN5test21CIiE6zedbarEd( 23*67e74705SXin Li 24*67e74705SXin Li // CHECK-LABEL: define linkonce_odr void @_ZN7PR106662g1ENS_1SILi1EEE() 25*67e74705SXin Li // CHECK-LABEL: define linkonce_odr void @_ZN7PR106662g1ENS_1SILi2EEE() 26*67e74705SXin Li // CHECK-LABEL: define linkonce_odr void @_ZN7PR106662g1ENS_1SILi3EEE() 27*67e74705SXin Li // CHECK-LABEL: define linkonce_odr void @_ZN7PR106662g2ENS_1SILi1EEE() 28*67e74705SXin Li // CHECK-LABEL: define linkonce_odr void @_ZN7PR106662g2ENS_1SILi2EEE() 29*67e74705SXin Li // CHECK-LABEL: define linkonce_odr void @_ZN7PR106662g2ENS_1SILi3EEE() 30*67e74705SXin Li // CHECK: declare void @_ZN7PR106662h1ENS_1SILi1EEE() 31*67e74705SXin Li // CHECK: declare void @_ZN7PR106662h1ENS_1SILi2EEE() 32*67e74705SXin Li // CHECK: declare void @_ZN7PR106662h1ENS_1SILi3EEE() 33*67e74705SXin Li // CHECK: declare void @_ZN7PR106662h2ENS_1SILi1EEE() 34*67e74705SXin Li // CHECK: declare void @_ZN7PR106662h2ENS_1SILi2EEE() 35*67e74705SXin Li // CHECK: declare void @_ZN7PR106662h2ENS_1SILi3EEE() 36*67e74705SXin Li 37*67e74705SXin Li namespace test0 { 38*67e74705SXin Li struct basic_streambuf { 39*67e74705SXin Li virtual ~basic_streambuf(); 40*67e74705SXin Li }; 41*67e74705SXin Li template<typename _CharT > 42*67e74705SXin Li struct stdio_sync_filebuf : public basic_streambuf { 43*67e74705SXin Li virtual void xsgetn(); 44*67e74705SXin Li }; 45*67e74705SXin Li 46*67e74705SXin Li // This specialization is not a key function, so doesn't cause the vtable to 47*67e74705SXin Li // be instantiated unless we're instantiating a class definition anyway. xsgetn()48*67e74705SXin Li template<> void stdio_sync_filebuf<int[1]>::xsgetn() { 49*67e74705SXin Li } xsgetn()50*67e74705SXin Li template<> void stdio_sync_filebuf<int[2]>::xsgetn() { 51*67e74705SXin Li } xsgetn()52*67e74705SXin Li template<> void stdio_sync_filebuf<int[3]>::xsgetn() { 53*67e74705SXin Li } xsgetn()54*67e74705SXin Li template<> void stdio_sync_filebuf<int[4]>::xsgetn() { 55*67e74705SXin Li } 56*67e74705SXin Li extern template class stdio_sync_filebuf<int[2]>; 57*67e74705SXin Li 58*67e74705SXin Li // These two both cause vtables to be emitted. 59*67e74705SXin Li template class stdio_sync_filebuf<int[3]>; 60*67e74705SXin Li stdio_sync_filebuf<int[4]> implicit_instantiation; 61*67e74705SXin Li } 62*67e74705SXin Li 63*67e74705SXin Li namespace test1 { 64*67e74705SXin Li struct basic_streambuf { 65*67e74705SXin Li virtual ~basic_streambuf(); 66*67e74705SXin Li }; 67*67e74705SXin Li template<typename _CharT > 68*67e74705SXin Li struct stdio_sync_filebuf : public basic_streambuf { 69*67e74705SXin Li virtual void xsgetn(); 70*67e74705SXin Li }; 71*67e74705SXin Li 72*67e74705SXin Li // Just a declaration should not force the vtable to be emitted. 73*67e74705SXin Li template<> void stdio_sync_filebuf<wchar_t>::xsgetn(); 74*67e74705SXin Li } 75*67e74705SXin Li 76*67e74705SXin Li namespace test2 { 77*67e74705SXin Li template<typename T1> 78*67e74705SXin Li class C { 79*67e74705SXin Li public: 80*67e74705SXin Li virtual ~C(); zedbar(double)81*67e74705SXin Li void zedbar(double) { 82*67e74705SXin Li } 83*67e74705SXin Li template<typename T2> foobar(T2 foo)84*67e74705SXin Li void foobar(T2 foo) { 85*67e74705SXin Li } 86*67e74705SXin Li }; 87*67e74705SXin Li extern template class C<int>; g()88*67e74705SXin Li void g() { 89*67e74705SXin Li // The extern template declaration should not prevent us from producing 90*67e74705SXin Li // the implicit constructor (test at the top). 91*67e74705SXin Li C<int> a; 92*67e74705SXin Li 93*67e74705SXin Li // or foobar(test at the top). 94*67e74705SXin Li a.foobar(0.0); 95*67e74705SXin Li 96*67e74705SXin Li // But it should prevent zebbar 97*67e74705SXin Li // (test at the top). 98*67e74705SXin Li a.zedbar(0.0); 99*67e74705SXin Li } 100*67e74705SXin Li } 101*67e74705SXin Li 102*67e74705SXin Li namespace test3 { 103*67e74705SXin Li template<typename T> 104*67e74705SXin Li class basic_fstreamXX { foo()105*67e74705SXin Li virtual void foo(){} is_open() const106*67e74705SXin Li virtual void is_open() const { } 107*67e74705SXin Li }; 108*67e74705SXin Li 109*67e74705SXin Li extern template class basic_fstreamXX<char>; 110*67e74705SXin Li // This template instantiation should not cause us to produce a vtable. 111*67e74705SXin Li // (test at the top). 112*67e74705SXin Li template void basic_fstreamXX<char>::is_open() const; 113*67e74705SXin Li } 114*67e74705SXin Li 115*67e74705SXin Li namespace test3 { 116*67e74705SXin Li template <typename T> 117*67e74705SXin Li struct S { 118*67e74705SXin Li virtual void m(); 119*67e74705SXin Li }; 120*67e74705SXin Li 121*67e74705SXin Li template<typename T> m()122*67e74705SXin Li void S<T>::m() { } 123*67e74705SXin Li 124*67e74705SXin Li // Should not cause us to produce vtable because template instantiations 125*67e74705SXin Li // don't have key functions. 126*67e74705SXin Li template void S<int>::m(); 127*67e74705SXin Li } 128*67e74705SXin Li 129*67e74705SXin Li namespace test4 { 130*67e74705SXin Li template <class T> struct A { static void foo(); }; 131*67e74705SXin Li 132*67e74705SXin Li class B { 133*67e74705SXin Li template <class T> friend void A<T>::foo(); 134*67e74705SXin Li B(); 135*67e74705SXin Li }; 136*67e74705SXin Li foo()137*67e74705SXin Li template <class T> void A<T>::foo() { 138*67e74705SXin Li B b; 139*67e74705SXin Li } 140*67e74705SXin Li test()141*67e74705SXin Li unsigned test() { 142*67e74705SXin Li A<int>::foo(); 143*67e74705SXin Li } 144*67e74705SXin Li } 145*67e74705SXin Li 146*67e74705SXin Li namespace PR8505 { 147*67e74705SXin Li // Hits an assertion due to bogus instantiation of class B. 148*67e74705SXin Li template <int i> class A { 149*67e74705SXin Li class B* g; 150*67e74705SXin Li }; 151*67e74705SXin Li class B { f()152*67e74705SXin Li void f () {} 153*67e74705SXin Li }; 154*67e74705SXin Li // Should not instantiate class B since it is introduced in namespace scope. 155*67e74705SXin Li // CHECK-NOT: _ZN6PR85051AILi0EE1B1fEv 156*67e74705SXin Li template class A<0>; 157*67e74705SXin Li } 158*67e74705SXin Li 159*67e74705SXin Li // Ensure that when instantiating initializers for static data members to 160*67e74705SXin Li // complete their type in an unevaluated context, we *do* emit initializers with 161*67e74705SXin Li // side-effects, but *don't* emit initializers and variables which are otherwise 162*67e74705SXin Li // unused in the program. 163*67e74705SXin Li namespace PR10001 { 164*67e74705SXin Li template <typename T> struct S { 165*67e74705SXin Li static const int arr[]; 166*67e74705SXin Li static const int arr2[]; 167*67e74705SXin Li static const int x, y; 168*67e74705SXin Li static int f(); 169*67e74705SXin Li }; 170*67e74705SXin Li 171*67e74705SXin Li extern int foo(); 172*67e74705SXin Li extern int kBar; 173*67e74705SXin Li 174*67e74705SXin Li template <typename T> const int S<T>::arr[] = { 1, 2, foo() }; // possible side effects 175*67e74705SXin Li template <typename T> const int S<T>::arr2[] = { 1, 2, kBar }; // no side effects 176*67e74705SXin Li template <typename T> const int S<T>::x = sizeof(arr) / sizeof(arr[0]); 177*67e74705SXin Li template <typename T> const int S<T>::y = sizeof(arr2) / sizeof(arr2[0]); f()178*67e74705SXin Li template <typename T> int S<T>::f() { return x + y; } 179*67e74705SXin Li 180*67e74705SXin Li int x = S<int>::f(); 181*67e74705SXin Li } 182*67e74705SXin Li 183*67e74705SXin Li // Ensure that definitions are emitted for all friend functions defined within 184*67e74705SXin Li // class templates. Order of declaration is extremely important here. Different 185*67e74705SXin Li // instantiations of the class happen at different points during the deferred 186*67e74705SXin Li // method body parsing and afterward. Those different points of instantiation 187*67e74705SXin Li // change the exact form the class template appears to have. 188*67e74705SXin Li namespace PR10666 { 189*67e74705SXin Li template <int N> struct S { f1PR10666::S190*67e74705SXin Li void f1() { S<1> s; } g1(S s)191*67e74705SXin Li friend void g1(S s) {} 192*67e74705SXin Li friend void h1(S s); f2PR10666::S193*67e74705SXin Li void f2() { S<2> s; } g2(S s)194*67e74705SXin Li friend void g2(S s) {} 195*67e74705SXin Li friend void h2(S s); f3PR10666::S196*67e74705SXin Li void f3() { S<3> s; } 197*67e74705SXin Li }; test(S<1> s1,S<2> s2,S<3> s3)198*67e74705SXin Li void test(S<1> s1, S<2> s2, S<3> s3) { 199*67e74705SXin Li g1(s1); g1(s2); g1(s3); 200*67e74705SXin Li g2(s1); g2(s2); g2(s3); 201*67e74705SXin Li h1(s1); h1(s2); h1(s3); 202*67e74705SXin Li h2(s1); h2(s2); h2(s3); 203*67e74705SXin Li } 204*67e74705SXin Li } 205