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