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