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