template-instantiation.cpp revision e4d645cbe073042d8abc1a4eb600af4ff7a8dffb
1// RUN: %clang_cc1 %s -O1 -triple=x86_64-apple-darwin10 -emit-llvm -o - | FileCheck %s 2 3// CHECK: @_ZN7PR100011xE = global 4// CHECK-NOT: @_ZN7PR100014kBarE = external global i32 5// 6// CHECK-NOT: @_ZTVN5test118stdio_sync_filebufIwEE = constant 7// CHECK-NOT: _ZTVN5test315basic_fstreamXXIcEE 8// CHECK: @_ZTVN5test018stdio_sync_filebufIwEE = unnamed_addr constant 9 10// CHECK: @_ZN7PR100011SIiE3arrE = weak_odr global [3 x i32] 11// CHECK-NOT: @_ZN7PR100011SIiE3arr2E = weak_odr global [3 x i32]A 12 13// CHECK-NOT: _ZTVN5test31SIiEE 14// CHECK-NOT: _ZTSN5test31SIiEE 15 16// CHECK: define linkonce_odr void @_ZN5test21CIiEC1Ev(%"class.test2::C"* nocapture %this) unnamed_addr 17// CHECK: define linkonce_odr void @_ZN5test21CIiE6foobarIdEEvT_( 18// CHECK: define available_externally void @_ZN5test21CIiE6zedbarEd( 19 20namespace test0 { 21 struct basic_streambuf { 22 virtual ~basic_streambuf(); 23 }; 24 template<typename _CharT > 25 struct stdio_sync_filebuf : public basic_streambuf { 26 virtual void xsgetn(); 27 }; 28 29 // This specialization should cause the vtable to be emitted, even with 30 // the following extern template declaration. 31 template<> void stdio_sync_filebuf<wchar_t>::xsgetn() { 32 } 33 extern template class stdio_sync_filebuf<wchar_t>; 34} 35 36namespace test1 { 37 struct basic_streambuf { 38 virtual ~basic_streambuf(); 39 }; 40 template<typename _CharT > 41 struct stdio_sync_filebuf : public basic_streambuf { 42 virtual void xsgetn(); 43 }; 44 45 // Just a declaration should not force the vtable to be emitted. 46 template<> void stdio_sync_filebuf<wchar_t>::xsgetn(); 47} 48 49namespace test2 { 50 template<typename T1> 51 class C { 52 public: 53 virtual ~C(); 54 void zedbar(double) { 55 } 56 template<typename T2> 57 void foobar(T2 foo) { 58 } 59 }; 60 extern template class C<int>; 61 void g() { 62 // The extern template declaration should not prevent us from producing 63 // the implicit constructor (test at the top). 64 C<int> a; 65 66 // or foobar(test at the top). 67 a.foobar(0.0); 68 69 // But it should prevent zebbar 70 // (test at the top). 71 a.zedbar(0.0); 72 } 73} 74 75namespace test3 { 76 template<typename T> 77 class basic_fstreamXX { 78 virtual void foo(){} 79 virtual void is_open() const { } 80 }; 81 82 extern template class basic_fstreamXX<char>; 83 // This template instantiation should not cause us to produce a vtable. 84 // (test at the top). 85 template void basic_fstreamXX<char>::is_open() const; 86} 87 88namespace test3 { 89 template <typename T> 90 struct S { 91 virtual void m(); 92 }; 93 94 template<typename T> 95 void S<T>::m() { } 96 97 // Should not cause us to produce vtable because template instantiations 98 // don't have key functions. 99 template void S<int>::m(); 100} 101 102namespace test4 { 103 template <class T> struct A { static void foo(); }; 104 105 class B { 106 template <class T> friend void A<T>::foo(); 107 B(); 108 }; 109 110 template <class T> void A<T>::foo() { 111 B b; 112 } 113 114 unsigned test() { 115 A<int>::foo(); 116 } 117} 118 119namespace PR8505 { 120// Hits an assertion due to bogus instantiation of class B. 121template <int i> class A { 122 class B* g; 123}; 124class B { 125 void f () {} 126}; 127// Should not instantiate class B since it is introduced in namespace scope. 128// CHECK-NOT: _ZN6PR85051AILi0EE1B1fEv 129template class A<0>; 130} 131 132// Ensure that when instantiating initializers for static data members to 133// complete their type in an unevaluated context, we *do* emit initializers with 134// side-effects, but *don't* emit initializers and variables which are otherwise 135// unused in the program. 136namespace PR10001 { 137 template <typename T> struct S { 138 static const int arr[]; 139 static const int arr2[]; 140 static const int x, y; 141 static int f(); 142 }; 143 144 extern int foo(); 145 extern int kBar; 146 147 template <typename T> const int S<T>::arr[] = { 1, 2, foo() }; // possible side effects 148 template <typename T> const int S<T>::arr2[] = { 1, 2, kBar }; // no side effects 149 template <typename T> const int S<T>::x = sizeof(arr) / sizeof(arr[0]); 150 template <typename T> const int S<T>::y = sizeof(arr2) / sizeof(arr2[0]); 151 template <typename T> int S<T>::f() { return x + y; } 152 153 int x = S<int>::f(); 154} 155