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 | |