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