1*f4a2713aSLionel Sambuc // RUN: %clang_cc1 %s -triple=x86_64-apple-darwin10 -emit-llvm -o %t 2*f4a2713aSLionel Sambuc // RUN: %clang_cc1 %s -triple=x86_64-apple-darwin10 -fhidden-weak-vtables -emit-llvm -o %t.hidden 3*f4a2713aSLionel Sambuc // RUN: %clang_cc1 %s -triple=x86_64-apple-darwin10 -disable-llvm-optzns -O3 -emit-llvm -o %t.opt 4*f4a2713aSLionel Sambuc // RUN: FileCheck --check-prefix=CHECK %s < %t 5*f4a2713aSLionel Sambuc // RUN: FileCheck --check-prefix=CHECK-HIDDEN %s < %t.hidden 6*f4a2713aSLionel Sambuc // RUN: FileCheck --check-prefix=CHECK-OPT %s < %t.opt 7*f4a2713aSLionel Sambuc 8*f4a2713aSLionel Sambuc namespace { 9*f4a2713aSLionel Sambuc struct A { 10*f4a2713aSLionel Sambuc virtual void f() { } 11*f4a2713aSLionel Sambuc }; 12*f4a2713aSLionel Sambuc } 13*f4a2713aSLionel Sambuc 14*f4a2713aSLionel Sambuc void f() { A b; } 15*f4a2713aSLionel Sambuc 16*f4a2713aSLionel Sambuc struct B { 17*f4a2713aSLionel Sambuc B(); 18*f4a2713aSLionel Sambuc virtual void f(); 19*f4a2713aSLionel Sambuc }; 20*f4a2713aSLionel Sambuc 21*f4a2713aSLionel Sambuc B::B() { } 22*f4a2713aSLionel Sambuc 23*f4a2713aSLionel Sambuc struct C : virtual B { 24*f4a2713aSLionel Sambuc C(); 25*f4a2713aSLionel Sambuc virtual void f() { } 26*f4a2713aSLionel Sambuc }; 27*f4a2713aSLionel Sambuc 28*f4a2713aSLionel Sambuc C::C() { } 29*f4a2713aSLionel Sambuc 30*f4a2713aSLionel Sambuc struct D { 31*f4a2713aSLionel Sambuc virtual void f(); 32*f4a2713aSLionel Sambuc }; 33*f4a2713aSLionel Sambuc 34*f4a2713aSLionel Sambuc void D::f() { } 35*f4a2713aSLionel Sambuc 36*f4a2713aSLionel Sambuc static struct : D { } e; 37*f4a2713aSLionel Sambuc 38*f4a2713aSLionel Sambuc // The destructor is the key function. 39*f4a2713aSLionel Sambuc template<typename T> 40*f4a2713aSLionel Sambuc struct E { 41*f4a2713aSLionel Sambuc virtual ~E(); 42*f4a2713aSLionel Sambuc }; 43*f4a2713aSLionel Sambuc 44*f4a2713aSLionel Sambuc template<typename T> E<T>::~E() { } 45*f4a2713aSLionel Sambuc 46*f4a2713aSLionel Sambuc // Anchor is the key function 47*f4a2713aSLionel Sambuc template<> 48*f4a2713aSLionel Sambuc struct E<char> { 49*f4a2713aSLionel Sambuc virtual void anchor(); 50*f4a2713aSLionel Sambuc }; 51*f4a2713aSLionel Sambuc 52*f4a2713aSLionel Sambuc void E<char>::anchor() { } 53*f4a2713aSLionel Sambuc 54*f4a2713aSLionel Sambuc template struct E<short>; 55*f4a2713aSLionel Sambuc extern template struct E<int>; 56*f4a2713aSLionel Sambuc 57*f4a2713aSLionel Sambuc void use_E() { 58*f4a2713aSLionel Sambuc E<int> ei; 59*f4a2713aSLionel Sambuc (void)ei; 60*f4a2713aSLionel Sambuc E<long> el; 61*f4a2713aSLionel Sambuc (void)el; 62*f4a2713aSLionel Sambuc } 63*f4a2713aSLionel Sambuc 64*f4a2713aSLionel Sambuc // No key function 65*f4a2713aSLionel Sambuc template<typename T> 66*f4a2713aSLionel Sambuc struct F { 67*f4a2713aSLionel Sambuc virtual void foo() { } 68*f4a2713aSLionel Sambuc }; 69*f4a2713aSLionel Sambuc 70*f4a2713aSLionel Sambuc // No key function 71*f4a2713aSLionel Sambuc template<> 72*f4a2713aSLionel Sambuc struct F<char> { 73*f4a2713aSLionel Sambuc virtual void foo() { } 74*f4a2713aSLionel Sambuc }; 75*f4a2713aSLionel Sambuc 76*f4a2713aSLionel Sambuc template struct F<short>; 77*f4a2713aSLionel Sambuc extern template struct F<int>; 78*f4a2713aSLionel Sambuc 79*f4a2713aSLionel Sambuc void use_F() { 80*f4a2713aSLionel Sambuc F<char> fc; 81*f4a2713aSLionel Sambuc fc.foo(); 82*f4a2713aSLionel Sambuc F<int> fi; 83*f4a2713aSLionel Sambuc fi.foo(); 84*f4a2713aSLionel Sambuc F<long> fl; 85*f4a2713aSLionel Sambuc (void)fl; 86*f4a2713aSLionel Sambuc } 87*f4a2713aSLionel Sambuc 88*f4a2713aSLionel Sambuc // B has a key function that is not defined in this translation unit so its vtable 89*f4a2713aSLionel Sambuc // has external linkage. 90*f4a2713aSLionel Sambuc // CHECK-DAG: @_ZTV1B = external unnamed_addr constant 91*f4a2713aSLionel Sambuc 92*f4a2713aSLionel Sambuc // C has no key function, so its vtable should have weak_odr linkage 93*f4a2713aSLionel Sambuc // and hidden visibility (rdar://problem/7523229). 94*f4a2713aSLionel Sambuc // CHECK-DAG: @_ZTV1C = linkonce_odr unnamed_addr constant 95*f4a2713aSLionel Sambuc // CHECK-DAG: @_ZTS1C = linkonce_odr constant 96*f4a2713aSLionel Sambuc // CHECK-DAG: @_ZTI1C = linkonce_odr unnamed_addr constant 97*f4a2713aSLionel Sambuc // CHECK-DAG: @_ZTT1C = linkonce_odr unnamed_addr constant 98*f4a2713aSLionel Sambuc // CHECK-HIDDEN-DAG: @_ZTV1C = linkonce_odr hidden unnamed_addr constant 99*f4a2713aSLionel Sambuc // CHECK-HIDDEN-DAG: @_ZTS1C = linkonce_odr constant 100*f4a2713aSLionel Sambuc // CHECK-HIDDEN-DAG: @_ZTI1C = linkonce_odr hidden unnamed_addr constant 101*f4a2713aSLionel Sambuc // CHECK-HIDDEN-DAG: @_ZTT1C = linkonce_odr hidden unnamed_addr constant 102*f4a2713aSLionel Sambuc 103*f4a2713aSLionel Sambuc // D has a key function that is defined in this translation unit so its vtable is 104*f4a2713aSLionel Sambuc // defined in the translation unit. 105*f4a2713aSLionel Sambuc // CHECK-DAG: @_ZTV1D = unnamed_addr constant 106*f4a2713aSLionel Sambuc // CHECK-DAG: @_ZTS1D = constant 107*f4a2713aSLionel Sambuc // CHECK-DAG: @_ZTI1D = unnamed_addr constant 108*f4a2713aSLionel Sambuc 109*f4a2713aSLionel Sambuc // E<char> is an explicit specialization with a key function defined 110*f4a2713aSLionel Sambuc // in this translation unit, so its vtable should have external 111*f4a2713aSLionel Sambuc // linkage. 112*f4a2713aSLionel Sambuc // CHECK-DAG: @_ZTV1EIcE = unnamed_addr constant 113*f4a2713aSLionel Sambuc // CHECK-DAG: @_ZTS1EIcE = constant 114*f4a2713aSLionel Sambuc // CHECK-DAG: @_ZTI1EIcE = unnamed_addr constant 115*f4a2713aSLionel Sambuc 116*f4a2713aSLionel Sambuc // E<short> is an explicit template instantiation with a key function 117*f4a2713aSLionel Sambuc // defined in this translation unit, so its vtable should have 118*f4a2713aSLionel Sambuc // weak_odr linkage. 119*f4a2713aSLionel Sambuc // CHECK-DAG: @_ZTV1EIsE = weak_odr unnamed_addr constant 120*f4a2713aSLionel Sambuc // CHECK-DAG: @_ZTS1EIsE = weak_odr constant 121*f4a2713aSLionel Sambuc // CHECK-DAG: @_ZTI1EIsE = weak_odr unnamed_addr constant 122*f4a2713aSLionel Sambuc // CHECK-HIDDEN-DAG: @_ZTV1EIsE = weak_odr unnamed_addr constant 123*f4a2713aSLionel Sambuc // CHECK-HIDDEN-DAG: @_ZTS1EIsE = weak_odr constant 124*f4a2713aSLionel Sambuc // CHECK-HIDDEN-DAG: @_ZTI1EIsE = weak_odr unnamed_addr constant 125*f4a2713aSLionel Sambuc 126*f4a2713aSLionel Sambuc // F<short> is an explicit template instantiation without a key 127*f4a2713aSLionel Sambuc // function, so its vtable should have weak_odr linkage 128*f4a2713aSLionel Sambuc // CHECK-DAG: @_ZTV1FIsE = weak_odr unnamed_addr constant 129*f4a2713aSLionel Sambuc // CHECK-DAG: @_ZTS1FIsE = weak_odr constant 130*f4a2713aSLionel Sambuc // CHECK-DAG: @_ZTI1FIsE = weak_odr unnamed_addr constant 131*f4a2713aSLionel Sambuc // CHECK-HIDDEN-DAG: @_ZTV1FIsE = weak_odr unnamed_addr constant 132*f4a2713aSLionel Sambuc // CHECK-HIDDEN-DAG: @_ZTS1FIsE = weak_odr constant 133*f4a2713aSLionel Sambuc // CHECK-HIDDEN-DAG: @_ZTI1FIsE = weak_odr unnamed_addr constant 134*f4a2713aSLionel Sambuc 135*f4a2713aSLionel Sambuc // E<long> is an implicit template instantiation with a key function 136*f4a2713aSLionel Sambuc // defined in this translation unit, so its vtable should have 137*f4a2713aSLionel Sambuc // linkonce_odr linkage. 138*f4a2713aSLionel Sambuc // CHECK-DAG: @_ZTV1EIlE = linkonce_odr unnamed_addr constant 139*f4a2713aSLionel Sambuc // CHECK-DAG: @_ZTS1EIlE = linkonce_odr constant 140*f4a2713aSLionel Sambuc // CHECK-DAG: @_ZTI1EIlE = linkonce_odr unnamed_addr constant 141*f4a2713aSLionel Sambuc 142*f4a2713aSLionel Sambuc // F<long> is an implicit template instantiation with no key function, 143*f4a2713aSLionel Sambuc // so its vtable should have linkonce_odr linkage. 144*f4a2713aSLionel Sambuc // CHECK-DAG: @_ZTV1FIlE = linkonce_odr unnamed_addr constant 145*f4a2713aSLionel Sambuc // CHECK-DAG: @_ZTS1FIlE = linkonce_odr constant 146*f4a2713aSLionel Sambuc // CHECK-DAG: @_ZTI1FIlE = linkonce_odr unnamed_addr constant 147*f4a2713aSLionel Sambuc 148*f4a2713aSLionel Sambuc // F<int> is an explicit template instantiation declaration without a 149*f4a2713aSLionel Sambuc // key function, so its vtable should have external linkage. 150*f4a2713aSLionel Sambuc // CHECK-DAG: @_ZTV1FIiE = external unnamed_addr constant 151*f4a2713aSLionel Sambuc // CHECK-OPT-DAG: @_ZTV1FIiE = external unnamed_addr constant 152*f4a2713aSLionel Sambuc 153*f4a2713aSLionel Sambuc // E<int> is an explicit template instantiation declaration. It has a 154*f4a2713aSLionel Sambuc // key function that is not instantiated, so we should only reference 155*f4a2713aSLionel Sambuc // its vtable, not define it. 156*f4a2713aSLionel Sambuc // CHECK-DAG: @_ZTV1EIiE = external unnamed_addr constant 157*f4a2713aSLionel Sambuc // CHECK-OPT-DAG: @_ZTV1EIiE = external unnamed_addr constant 158*f4a2713aSLionel Sambuc 159*f4a2713aSLionel Sambuc // The anonymous struct for e has no linkage, so the vtable should have 160*f4a2713aSLionel Sambuc // internal linkage. 161*f4a2713aSLionel Sambuc // CHECK-DAG: @"_ZTV3$_0" = internal unnamed_addr constant 162*f4a2713aSLionel Sambuc // CHECK-DAG: @"_ZTS3$_0" = internal constant 163*f4a2713aSLionel Sambuc // CHECK-DAG: @"_ZTI3$_0" = internal unnamed_addr constant 164*f4a2713aSLionel Sambuc 165*f4a2713aSLionel Sambuc // The A vtable should have internal linkage since it is inside an anonymous 166*f4a2713aSLionel Sambuc // namespace. 167*f4a2713aSLionel Sambuc // CHECK-DAG: @_ZTVN12_GLOBAL__N_11AE = internal unnamed_addr constant 168*f4a2713aSLionel Sambuc // CHECK-DAG: @_ZTSN12_GLOBAL__N_11AE = internal constant 169*f4a2713aSLionel Sambuc // CHECK-DAG: @_ZTIN12_GLOBAL__N_11AE = internal unnamed_addr constant 170*f4a2713aSLionel Sambuc 171*f4a2713aSLionel Sambuc // F<char> is an explicit specialization without a key function, so 172*f4a2713aSLionel Sambuc // its vtable should have linkonce_odr linkage. 173*f4a2713aSLionel Sambuc // CHECK-DAG: @_ZTV1FIcE = linkonce_odr unnamed_addr constant 174*f4a2713aSLionel Sambuc // CHECK-DAG: @_ZTS1FIcE = linkonce_odr constant 175*f4a2713aSLionel Sambuc // CHECK-DAG: @_ZTI1FIcE = linkonce_odr unnamed_addr constant 176*f4a2713aSLionel Sambuc 177*f4a2713aSLionel Sambuc // CHECK-DAG: @_ZTV1GIiE = linkonce_odr unnamed_addr constant 178*f4a2713aSLionel Sambuc template <typename T> 179*f4a2713aSLionel Sambuc class G { 180*f4a2713aSLionel Sambuc public: 181*f4a2713aSLionel Sambuc G() {} 182*f4a2713aSLionel Sambuc virtual void f0(); 183*f4a2713aSLionel Sambuc virtual void f1(); 184*f4a2713aSLionel Sambuc }; 185*f4a2713aSLionel Sambuc template <> 186*f4a2713aSLionel Sambuc void G<int>::f1() {} 187*f4a2713aSLionel Sambuc template <typename T> 188*f4a2713aSLionel Sambuc void G<T>::f0() {} 189*f4a2713aSLionel Sambuc void G_f0() { new G<int>(); } 190*f4a2713aSLionel Sambuc 191*f4a2713aSLionel Sambuc // H<int> has a key function without a body but it's a template instantiation 192*f4a2713aSLionel Sambuc // so its VTable must be emitted. 193*f4a2713aSLionel Sambuc // CHECK-DAG: @_ZTV1HIiE = linkonce_odr unnamed_addr constant 194*f4a2713aSLionel Sambuc template <typename T> 195*f4a2713aSLionel Sambuc class H { 196*f4a2713aSLionel Sambuc public: 197*f4a2713aSLionel Sambuc virtual ~H(); 198*f4a2713aSLionel Sambuc }; 199*f4a2713aSLionel Sambuc 200*f4a2713aSLionel Sambuc void use_H() { 201*f4a2713aSLionel Sambuc H<int> h; 202*f4a2713aSLionel Sambuc } 203*f4a2713aSLionel Sambuc 204*f4a2713aSLionel Sambuc // I<int> has an explicit instantiation declaration and needs a VTT and 205*f4a2713aSLionel Sambuc // construction vtables. 206*f4a2713aSLionel Sambuc 207*f4a2713aSLionel Sambuc // CHECK-DAG: @_ZTV1IIiE = external unnamed_addr constant 208*f4a2713aSLionel Sambuc // CHECK-DAG: @_ZTT1IIiE = external unnamed_addr constant 209*f4a2713aSLionel Sambuc // CHECK-NOT: @_ZTC1IIiE 210*f4a2713aSLionel Sambuc // 211*f4a2713aSLionel Sambuc // CHECK-OPT-DAG: @_ZTV1IIiE = external unnamed_addr constant 212*f4a2713aSLionel Sambuc // CHECK-OPT-DAG: @_ZTT1IIiE = external unnamed_addr constant 213*f4a2713aSLionel Sambuc struct VBase1 { virtual void f(); }; struct VBase2 : virtual VBase1 {}; 214*f4a2713aSLionel Sambuc template<typename T> 215*f4a2713aSLionel Sambuc struct I : VBase2 {}; 216*f4a2713aSLionel Sambuc extern template struct I<int>; 217*f4a2713aSLionel Sambuc I<int> i; 218