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