1 | // RUN: %clang_cc1 %s -I%S -triple=x86_64-apple-darwin10 -std=c++98 -emit-llvm -o %t |
2 | // RUN: %clang_cc1 %s -I%S -triple=x86_64-apple-darwin10 -std=c++98 -O2 -disable-llvm-passes -emit-llvm -o %t.opt |
3 | // RUN: %clang_cc1 %s -I%S -triple=x86_64-apple-darwin10 -std=c++98 -O2 -disable-llvm-passes -emit-llvm -o %t.vtable -fforce-emit-vtables -fstrict-vtable-pointers -mconstructor-aliases |
4 | // RUN: FileCheck -allow-deprecated-dag-overlap --check-prefix=CHECK-TEST1 %s < %t |
5 | // RUN: FileCheck -allow-deprecated-dag-overlap --check-prefix=CHECK-TEST2 %s < %t |
6 | // RUN: FileCheck -allow-deprecated-dag-overlap --check-prefix=CHECK-TEST5 %s < %t |
7 | // RUN: FileCheck -allow-deprecated-dag-overlap --check-prefix=CHECK-TEST8 %s < %t.opt |
8 | // RUN: FileCheck -allow-deprecated-dag-overlap --check-prefix=CHECK-TEST9 %s < %t.opt |
9 | // RUN: FileCheck -allow-deprecated-dag-overlap --check-prefix=CHECK-TEST10 %s < %t.opt |
10 | // RUN: FileCheck -allow-deprecated-dag-overlap --check-prefix=CHECK-TEST11 %s < %t.opt |
11 | // RUN: FileCheck -allow-deprecated-dag-overlap --check-prefix=CHECK-TEST12 %s < %t.opt |
12 | // RUN: FileCheck -allow-deprecated-dag-overlap --check-prefix=CHECK-TEST13 %s < %t.opt |
13 | // RUN: FileCheck -allow-deprecated-dag-overlap --check-prefix=CHECK-TEST14 %s < %t.opt |
14 | // RUN: FileCheck -allow-deprecated-dag-overlap --check-prefix=CHECK-TEST15 %s < %t.opt |
15 | // RUN: FileCheck -allow-deprecated-dag-overlap --check-prefix=CHECK-TEST16 %s < %t.opt |
16 | // RUN: FileCheck -allow-deprecated-dag-overlap --check-prefix=CHECK-TEST17 %s < %t.opt |
17 | // RUN: FileCheck -allow-deprecated-dag-overlap --check-prefix=CHECK-FORCE-EMIT %s < %t.vtable |
18 | |
19 | |
20 | #include <typeinfo> |
21 | |
22 | // CHECK-TEST1: @_ZTVN5Test11AE = external unnamed_addr constant |
23 | // CHECK-FORCE-EMIT-DAG: @_ZTVN5Test11AE = available_externally unnamed_addr constant |
24 | namespace Test1 { |
25 | |
26 | struct A { |
27 | A(); |
28 | virtual void f(); |
29 | virtual ~A() { } |
30 | }; |
31 | |
32 | A::A() { } |
33 | |
34 | void f(A* a) { |
35 | a->f(); |
36 | }; |
37 | |
38 | // CHECK-LABEL: define void @_ZN5Test11gEv |
39 | // CHECK: call void @_ZN5Test11A1fEv |
40 | void g() { |
41 | A a; |
42 | f(&a); |
43 | } |
44 | |
45 | } |
46 | |
47 | // Test2::A's key function (f) is defined in this translation unit, but when |
48 | // we're doing codegen for the typeid(A) call, we don't know that yet. |
49 | // This tests mainly that the typeinfo and typename constants have their linkage |
50 | // updated correctly. |
51 | |
52 | // CHECK-TEST2: @_ZTSN5Test21AE = constant |
53 | // CHECK-TEST2: @_ZTIN5Test21AE = constant |
54 | // CHECK-TEST2: @_ZTVN5Test21AE = unnamed_addr constant |
55 | namespace Test2 { |
56 | struct A { |
57 | virtual void f(); |
58 | }; |
59 | |
60 | const std::type_info &g() { |
61 | return typeid(A); |
62 | }; |
63 | |
64 | void A::f() { } |
65 | } |
66 | |
67 | // Test that we don't assert on this test. |
68 | namespace Test3 { |
69 | |
70 | struct A { |
71 | virtual void f(); |
72 | virtual ~A() { } |
73 | }; |
74 | |
75 | struct B : A { |
76 | B(); |
77 | virtual void f(); |
78 | }; |
79 | |
80 | B::B() { } |
81 | |
82 | void g(A* a) { |
83 | a->f(); |
84 | }; |
85 | |
86 | } |
87 | |
88 | // PR9114, test that we don't try to instantiate RefPtr<Node>. |
89 | namespace Test4 { |
90 | |
91 | template <class T> struct RefPtr { |
92 | T* p; |
93 | ~RefPtr() { |
94 | p->deref(); |
95 | } |
96 | }; |
97 | |
98 | struct A { |
99 | virtual ~A(); |
100 | }; |
101 | |
102 | struct Node; |
103 | |
104 | struct B : A { |
105 | virtual void deref(); |
106 | RefPtr<Node> m; |
107 | }; |
108 | |
109 | void f() { |
110 | RefPtr<B> b; |
111 | } |
112 | |
113 | } |
114 | |
115 | // PR9130, test that we emit a definition of A::f. |
116 | // CHECK-TEST5-LABEL: define linkonce_odr void @_ZN5Test51A1fEv |
117 | namespace Test5 { |
118 | |
119 | struct A { |
120 | virtual void f() { } |
121 | }; |
122 | |
123 | struct B : A { |
124 | virtual ~B(); |
125 | }; |
126 | |
127 | B::~B() { } |
128 | |
129 | } |
130 | |
131 | // Check that we don't assert on this test. |
132 | namespace Test6 { |
133 | |
134 | struct A { |
135 | virtual ~A(); |
136 | int a; |
137 | }; |
138 | |
139 | struct B { |
140 | virtual ~B(); |
141 | int b; |
142 | }; |
143 | |
144 | struct C : A, B { |
145 | C(); |
146 | }; |
147 | |
148 | struct D : C { |
149 | virtual void f(); |
150 | D(); |
151 | }; |
152 | |
153 | D::D() { } |
154 | |
155 | } |
156 | |
157 | namespace Test7 { |
158 | |
159 | struct c1 {}; |
160 | struct c10 : c1{ |
161 | virtual void foo (); |
162 | }; |
163 | struct c11 : c10, c1{ |
164 | virtual void f6 (); |
165 | }; |
166 | struct c28 : virtual c11{ |
167 | void f6 (); |
168 | }; |
169 | } |
170 | |
171 | namespace Test8 { |
172 | // CHECK-TEST8: @_ZTVN5Test81YE = available_externally unnamed_addr constant |
173 | // vtable for X is not generated because there are no stores here |
174 | struct X { |
175 | X(); |
176 | virtual void foo(); |
177 | }; |
178 | struct Y : X { |
179 | void foo(); |
180 | }; |
181 | |
182 | void g(X* p) { p->foo(); } |
183 | void f() { |
184 | Y y; |
185 | g(&y); |
186 | X x; |
187 | g(&x); |
188 | } |
189 | |
190 | } // Test8 |
191 | |
192 | namespace Test9 { |
193 | // All virtual functions are outline, so we can assume that it will |
194 | // be generated in translation unit where foo is defined. |
195 | // CHECK-TEST9-DAG: @_ZTVN5Test91AE = available_externally unnamed_addr constant |
196 | // CHECK-TEST9-DAG: @_ZTVN5Test91BE = available_externally unnamed_addr constant |
197 | struct A { |
198 | virtual void foo(); |
199 | virtual void bar(); |
200 | }; |
201 | void A::bar() {} |
202 | |
203 | struct B : A { |
204 | void foo(); |
205 | }; |
206 | |
207 | void g() { |
208 | A a; |
209 | a.foo(); |
210 | B b; |
211 | b.foo(); |
212 | } |
213 | |
214 | } // Test9 |
215 | |
216 | namespace Test10 { |
217 | |
218 | // because A's key function is defined here, vtable is generated in this TU |
219 | // CHECK-TEST10-DAG: @_ZTVN6Test101AE = unnamed_addr constant |
220 | // CHECK-FORCE-EMIT-DAG: @_ZTVN6Test101AE = unnamed_addr constant |
221 | struct A { |
222 | virtual void foo(); |
223 | virtual void bar(); |
224 | }; |
225 | void A::foo() {} |
226 | |
227 | // Because key function is inline we will generate vtable as linkonce_odr. |
228 | // CHECK-TEST10-DAG: @_ZTVN6Test101DE = linkonce_odr unnamed_addr constant |
229 | // CHECK-FORCE-EMIT-DAG: @_ZTVN6Test101DE = linkonce_odr unnamed_addr constant |
230 | struct D : A { |
231 | void bar(); |
232 | }; |
233 | inline void D::bar() {} |
234 | |
235 | // Because B has outline all virtual functions, we can refer to them. |
236 | // CHECK-TEST10-DAG: @_ZTVN6Test101BE = available_externally unnamed_addr constant |
237 | struct B : A { |
238 | void foo(); |
239 | void bar(); |
240 | }; |
241 | |
242 | // C's key function (car) is outline, but C has inline virtual function so we |
243 | // can't guarantee that we will be able to refer to bar from name |
244 | // so (at the moment) we can't emit vtable available_externally. |
245 | // CHECK-TEST10-DAG: @_ZTVN6Test101CE = external unnamed_addr constant |
246 | // CHECK-FORCE-EMIT-DAG: @_ZTVN6Test101CE = available_externally unnamed_addr constant |
247 | struct C : A { |
248 | void bar() {} // defined in body - not key function |
249 | virtual inline void gar(); // inline in body - not key function |
250 | virtual void car(); |
251 | }; |
252 | |
253 | // no key function, vtable will be generated everywhere it will be used |
254 | // CHECK-TEST10-DAG: @_ZTVN6Test101EE = linkonce_odr unnamed_addr constant |
255 | // CHECK-FORCE-EMIT-DAG: @_ZTVN6Test101EE = linkonce_odr unnamed_addr constant |
256 | |
257 | struct E : A {}; |
258 | |
259 | void g(A& a) { |
260 | a.foo(); |
261 | a.bar(); |
262 | } |
263 | |
264 | void f() { |
265 | A a; |
266 | g(a); |
267 | B b; |
268 | g(b); |
269 | C c; |
270 | g(c); |
271 | D d; |
272 | g(d); |
273 | E e; |
274 | g(e); |
275 | } |
276 | |
277 | } // Test10 |
278 | |
279 | namespace Test11 { |
280 | struct D; |
281 | // Can emit C's vtable available_externally. |
282 | // CHECK-TEST11: @_ZTVN6Test111CE = available_externally unnamed_addr constant |
283 | struct C { |
284 | virtual D& operator=(const D&); |
285 | }; |
286 | |
287 | // Can emit D's vtable available_externally. |
288 | // CHECK-TEST11: @_ZTVN6Test111DE = available_externally unnamed_addr constant |
289 | struct D : C { |
290 | virtual void key(); |
291 | }; |
292 | D f(); |
293 | |
294 | void g(D& a) { |
295 | C c; |
296 | c = a; |
297 | a.key(); |
298 | a.key(); |
299 | } |
300 | void g() { |
301 | D d; |
302 | d = f(); |
303 | g(d); |
304 | } |
305 | } // Test 11 |
306 | |
307 | namespace Test12 { |
308 | |
309 | // CHECK-TEST12: @_ZTVN6Test121AE = external unnamed_addr constant |
310 | // CHECK-FORCE-EMIT-DAG: @_ZTVN6Test121AE = available_externally unnamed_addr constant |
311 | struct A { |
312 | virtual void foo(); |
313 | virtual ~A() {} |
314 | }; |
315 | // CHECK-TEST12: @_ZTVN6Test121BE = external unnamed_addr constant |
316 | // CHECK-FORCE-EMIT-DAG: @_ZTVN6Test121BE = available_externally unnamed_addr constant |
317 | struct B : A { |
318 | void foo(); |
319 | }; |
320 | |
321 | void g() { |
322 | A a; |
323 | a.foo(); |
324 | B b; |
325 | b.foo(); |
326 | } |
327 | } |
328 | |
329 | namespace Test13 { |
330 | |
331 | // CHECK-TEST13-DAG: @_ZTVN6Test131AE = available_externally unnamed_addr constant |
332 | // CHECK-TEST13-DAG: @_ZTVN6Test131BE = external unnamed_addr constant |
333 | // CHECK-FORCE-EMIT-DAG: @_ZTVN6Test131AE = available_externally unnamed_addr constant |
334 | // CHECK-FORCE-EMIT-DAG: @_ZTVN6Test131BE = available_externally unnamed_addr constant |
335 | |
336 | struct A { |
337 | virtual ~A(); |
338 | }; |
339 | struct B : A { |
340 | virtual void f(); |
341 | void operator delete(void *); |
342 | ~B() {} |
343 | }; |
344 | |
345 | void g() { |
346 | A *b = new B; |
347 | } |
348 | } |
349 | |
350 | namespace Test14 { |
351 | |
352 | // CHECK-TEST14: @_ZTVN6Test141AE = available_externally unnamed_addr constant |
353 | struct A { |
354 | virtual void f(); |
355 | void operator delete(void *); |
356 | ~A(); |
357 | }; |
358 | |
359 | void g() { |
360 | A *b = new A; |
361 | delete b; |
362 | } |
363 | } |
364 | |
365 | namespace Test15 { |
366 | // In this test D's vtable has two slots for function f(), but uses only one, |
367 | // so the second slot is set to null. |
368 | // CHECK-TEST15: @_ZTVN6Test151DE = available_externally unnamed_addr constant |
369 | struct A { virtual void f() {} }; |
370 | struct B : virtual A {}; |
371 | struct C : virtual A {}; |
372 | struct D : B, C { |
373 | virtual void g(); |
374 | void f(); |
375 | }; |
376 | |
377 | void test() { |
378 | D * d = new D; |
379 | d->f(); |
380 | } |
381 | } |
382 | |
383 | namespace Test16 { |
384 | // S has virtual method that is hidden, because of it we can't |
385 | // generate available_externally vtable for it. |
386 | // CHECK-TEST16-DAG: @_ZTVN6Test161SE = external unnamed_addr constant |
387 | // CHECK-TEST16-DAG: @_ZTVN6Test162S2E = available_externally |
388 | // CHECK-FORCE-EMIT-DAG: @_ZTVN6Test161SE = external unnamed_addr constant |
389 | // CHECK-FORCE-EMIT-DAG: @_ZTVN6Test162S2E = available_externally |
390 | |
391 | struct S { |
392 | __attribute__((visibility("hidden"))) virtual void doStuff(); |
393 | }; |
394 | |
395 | struct S2 { |
396 | virtual void doStuff(); |
397 | __attribute__((visibility("hidden"))) void unused(); |
398 | |
399 | }; |
400 | |
401 | void test() { |
402 | S *s = new S; |
403 | s->doStuff(); |
404 | |
405 | S2 *s2 = new S2; |
406 | s2->doStuff(); |
407 | } |
408 | } |
409 | |
410 | namespace Test17 { |
411 | // This test checks if we emit vtables opportunistically. |
412 | // CHECK-TEST17-DAG: @_ZTVN6Test171AE = available_externally |
413 | // CHECK-TEST17-DAG: @_ZTVN6Test171BE = external |
414 | // CHECK-FORCE-EMIT-DAG: @_ZTVN6Test171AE = available_externally |
415 | // CHECK-FORCE-EMIT-DAG: @_ZTVN6Test171BE = available_externally |
416 | // CHECK-FORCE-EMIT-DAG: define linkonce_odr void @_ZN6Test171BD2Ev( |
417 | // CHECK-FORCE-EMIT-DAG: define linkonce_odr void @_ZN6Test171BD0Ev( |
418 | |
419 | struct A { |
420 | virtual void key(); |
421 | virtual void bar() {} |
422 | }; |
423 | |
424 | // We won't gonna use deleting destructor for this type, which will disallow |
425 | // emitting vtable as available_externally |
426 | struct B { |
427 | virtual void key(); |
428 | virtual ~B() {} |
429 | }; |
430 | |
431 | void testcaseA() { |
432 | A a; |
433 | a.bar(); // this forces to emit definition of bar |
434 | } |
435 | |
436 | void testcaseB() { |
437 | B b; // This only forces emitting of complete object destructor |
438 | } |
439 | |
440 | } // namespace Test17 |
441 | |
442 | namespace Test18 { |
443 | // Here vtable will be only emitted because it is referenced by assume-load |
444 | // after the Derived construction. |
445 | // CHECK-FORCE-EMIT-DAG: @_ZTVN6Test187DerivedE = linkonce_odr unnamed_addr constant {{.*}} @_ZTIN6Test187DerivedE {{.*}} @_ZN6Test184Base3funEv {{.*}} @_ZN6Test184BaseD2Ev {{.*}} @_ZN6Test187DerivedD0Ev |
446 | // CHECK-FORCE-EMIT-DAG: define linkonce_odr void @_ZN6Test187DerivedD0Ev |
447 | // CHECK-FORCE-EMIT-DAG: define linkonce_odr void @_ZN6Test184BaseD2Ev |
448 | // CHECK-FORCE-EMIT-DAG: define linkonce_odr i32 @_ZN6Test184Base3funEv |
449 | // CHECK-FORCE-EMIT-DAG: @_ZTIN6Test187DerivedE = linkonce_odr constant |
450 | |
451 | struct Base { |
452 | virtual int fun() { return 42; } |
453 | virtual ~Base() { } |
454 | }; |
455 | |
456 | struct Derived : Base { |
457 | Derived(); |
458 | }; |
459 | |
460 | int foo() { |
461 | Derived *der = new Derived(); |
462 | return der->fun(); |
463 | } |
464 | } |
465 | |
466 | namespace TestTemplates { |
467 | |
468 | // CHECK-FORCE-EMIT-DAG: @_ZTVN13TestTemplates8TemplateIiEE = linkonce_odr unnamed_addr constant {{.*}} @_ZTIN13TestTemplates8TemplateIiEE {{.*}} @_ZN13TestTemplates8TemplateIiE3fooEi {{.*}}@_ZN13TestTemplates8TemplateIiE22thisShouldBeEmittedTooEi {{.*}}@_ZN13TestTemplates8TemplateIiED1Ev {{.*}}@_ZN13TestTemplates8TemplateIiED0Ev |
469 | // CHECK-FORCE-EMIT-DAG: define linkonce_odr i32 @_ZN13TestTemplates8TemplateIiE22thisShouldBeEmittedTooEi |
470 | |
471 | template<class T> |
472 | struct Template { |
473 | Template(); |
474 | virtual T foo(T val); |
475 | // CHECK-FORCE-EMIT-DAG: define linkonce_odr i32 @_ZN13TestTemplates8TemplateIiE22thisShouldBeEmittedTooEi |
476 | virtual T thisShouldBeEmittedToo(T val) { return val; } |
477 | virtual ~Template(); |
478 | }; |
479 | |
480 | |
481 | struct NonTemplate { |
482 | typedef int T; |
483 | NonTemplate(); |
484 | virtual T foo(T val); |
485 | // CHECK-FORCE-EMIT-DAG: define linkonce_odr i32 @_ZN13TestTemplates11NonTemplate22thisShouldBeEmittedTooEi |
486 | virtual T thisShouldBeEmittedToo(T val) { return val; } |
487 | virtual ~NonTemplate(); |
488 | }; |
489 | |
490 | // CHECK-FORCE-EMIT-DAG: @_ZTVN13TestTemplates16OuterNonTemplate27NestedTemplateInNonTemplateIiEE = linkonce_odr {{.*}} @_ZTIN13TestTemplates16OuterNonTemplate27NestedTemplateInNonTemplateIiEE {{.*}} @_ZN13TestTemplates16OuterNonTemplate27NestedTemplateInNonTemplateIiE3fooEi {{.*}} @_ZN13TestTemplates16OuterNonTemplate27NestedTemplateInNonTemplateIiE22thisShouldBeEmittedTooEi {{.*}} @_ZN13TestTemplates16OuterNonTemplate27NestedTemplateInNonTemplateIiED1Ev {{.*}} @_ZN13TestTemplates16OuterNonTemplate27NestedTemplateInNonTemplateIiED0Ev |
491 | |
492 | struct OuterNonTemplate { |
493 | template<class T> |
494 | struct NestedTemplateInNonTemplate { |
495 | NestedTemplateInNonTemplate(); |
496 | virtual T foo(T val); |
497 | // CHECK-FORCE-EMIT-DAG: define linkonce_odr i32 @_ZN13TestTemplates16OuterNonTemplate27NestedTemplateInNonTemplateIiE22thisShouldBeEmittedTooEi |
498 | virtual T thisShouldBeEmittedToo(T val) { return val; } |
499 | virtual ~NestedTemplateInNonTemplate(); |
500 | }; |
501 | |
502 | struct NestedNonTemplateInNonTemplate { |
503 | typedef int T; |
504 | NestedNonTemplateInNonTemplate(); |
505 | virtual T foo(T val); |
506 | // CHECK-FORCE-EMIT-DAG: define linkonce_odr i32 @_ZN13TestTemplates16OuterNonTemplate30NestedNonTemplateInNonTemplate22thisShouldBeEmittedTooEi |
507 | virtual T thisShouldBeEmittedToo(T val) { return val; } |
508 | virtual ~NestedNonTemplateInNonTemplate(); |
509 | }; |
510 | }; |
511 | |
512 | template<class> |
513 | struct OuterTemplate { |
514 | template<class T> |
515 | struct NestedTemplateInTemplate { |
516 | NestedTemplateInTemplate(); |
517 | virtual T foo(T val); |
518 | // CHECK-FORCE-EMIT-DAG: define linkonce_odr i32 @_ZN13TestTemplates13OuterTemplateIlE24NestedTemplateInTemplateIiE22thisShouldBeEmittedTooEi |
519 | virtual T thisShouldBeEmittedToo(T val) { return val; } |
520 | virtual ~NestedTemplateInTemplate(); |
521 | }; |
522 | |
523 | struct NestedNonTemplateInTemplate { |
524 | typedef int T; |
525 | NestedNonTemplateInTemplate(); |
526 | virtual T foo(T val); |
527 | // CHECK-FORCE-EMIT-DAG: define linkonce_odr i32 @_ZN13TestTemplates13OuterTemplateIlE27NestedNonTemplateInTemplate22thisShouldBeEmittedTooEi |
528 | virtual T thisShouldBeEmittedToo(T val) { return val; } |
529 | virtual ~NestedNonTemplateInTemplate(); |
530 | }; |
531 | }; |
532 | |
533 | template<class T> |
534 | int use() { |
535 | T *ptr = new T(); |
536 | return ptr->foo(42); |
537 | } |
538 | |
539 | void test() { |
540 | use<Template<int> >(); |
541 | use<OuterTemplate<long>::NestedTemplateInTemplate<int> >(); |
542 | use<OuterNonTemplate::NestedTemplateInNonTemplate<int> >(); |
543 | |
544 | use<NonTemplate>(); |
545 | use<OuterTemplate<long>::NestedNonTemplateInTemplate>(); |
546 | use<OuterNonTemplate::NestedNonTemplateInNonTemplate>(); |
547 | } |
548 | } |
549 | |