Clang Project

clang_source_code/test/CodeGenCXX/vtable-available-externally.cpp
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
24namespace Test1 {
25
26struct A {
27  A();
28  virtual void f();
29  virtual ~A() { }
30};
31
32A::A() { }
33
34void f(A* a) {
35  a->f();
36};
37
38// CHECK-LABEL: define void @_ZN5Test11gEv
39// CHECK: call void @_ZN5Test11A1fEv
40void 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
55namespace 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.
68namespace Test3 {
69
70struct A {
71  virtual void f();
72  virtual ~A() { }
73};
74
75struct B : A {
76  B();
77  virtual void f();
78};
79
80B::B() { }
81
82void g(A* a) {
83  a->f();
84};
85
86}
87
88// PR9114, test that we don't try to instantiate RefPtr<Node>.
89namespace Test4 {
90
91template <class T> struct RefPtr {
92  T* p;
93  ~RefPtr() {
94    p->deref();
95  }
96};
97
98struct A {
99  virtual ~A();
100};
101
102struct Node;
103
104struct B : A {
105  virtual void deref();
106  RefPtr<Node> m;
107};
108
109void 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
117namespace Test5 {
118
119struct A {
120  virtual void f() { }
121};
122
123struct B : A { 
124  virtual ~B();
125};
126
127B::~B() { }
128
129}
130
131// Check that we don't assert on this test.
132namespace Test6 {
133
134struct A {
135  virtual ~A();
136  int a;
137};
138
139struct B {
140  virtual ~B();
141  int b;
142};
143
144struct C : A, B { 
145  C();
146};
147
148struct D : C {
149  virtual void f();
150  D();
151};
152
153D::D() { }
154
155}
156
157namespace Test7 {
158
159struct c1 {};
160struct c10 : c1{
161  virtual void foo ();
162};
163struct c11 : c10, c1{
164  virtual void f6 ();
165};
166struct c28 : virtual c11{
167  void f6 ();
168};
169}
170
171namespace Test8 {
172// CHECK-TEST8: @_ZTVN5Test81YE = available_externally unnamed_addr constant
173// vtable for X is not generated because there are no stores here
174struct X {
175  X();
176  virtual void foo();
177};
178struct Y : X {
179  void foo();
180};
181
182void g(X* p) { p->foo(); }
183void f() {
184  Y y;
185  g(&y);
186  X x;
187  g(&x);
188}
189
190}  // Test8
191
192namespace 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
197struct A {
198  virtual void foo();
199  virtual void bar();
200};
201void A::bar() {}
202
203struct B : A {
204  void foo();
205};
206
207void g() {
208  A a;
209  a.foo();
210  B b;
211  b.foo();
212}
213
214}  // Test9
215
216namespace 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
221struct A {
222  virtual void foo();
223  virtual void bar();
224};
225void 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
230struct D : A {
231  void bar();
232};
233inline 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
237struct 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
247struct 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
257struct E : A {};
258
259void g(A& a) {
260  a.foo();
261  a.bar();
262}
263
264void 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
279namespace Test11 {
280struct D;
281// Can emit C's vtable available_externally.
282// CHECK-TEST11: @_ZTVN6Test111CE = available_externally unnamed_addr constant
283struct 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
289struct D : C {
290  virtual void key();
291};
292D f();
293
294void g(D& a) {
295  C c;
296  c = a;
297  a.key();
298  a.key();
299}
300void g() {
301  D d;
302  d = f();
303  g(d);
304}
305}  // Test 11
306
307namespace Test12 {
308
309// CHECK-TEST12: @_ZTVN6Test121AE = external unnamed_addr constant
310// CHECK-FORCE-EMIT-DAG: @_ZTVN6Test121AE = available_externally unnamed_addr constant
311struct 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
317struct B : A {
318  void foo();
319};
320
321void g() {
322  A a;
323  a.foo();
324  B b;
325  b.foo();
326}
327}
328
329namespace 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
336struct A {
337  virtual ~A();
338};
339struct B : A {
340  virtual void f();
341  void operator delete(void *);
342  ~B() {}
343};
344
345void g() {
346  A *b = new B;
347}
348}
349
350namespace Test14 {
351
352// CHECK-TEST14: @_ZTVN6Test141AE = available_externally unnamed_addr constant
353struct A {
354  virtual void f();
355  void operator delete(void *);
356  ~A();
357};
358
359void g() {
360  A *b = new A;
361  delete b;
362}
363}
364
365namespace 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
369struct A { virtual void f() {} };
370struct B : virtual A {};
371struct C : virtual A {};
372struct D : B, C {
373  virtual void g();
374  void f();
375};
376
377void test() {
378  D * d = new D;
379  d->f();
380}
381}
382
383namespace 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
391struct S {
392  __attribute__((visibility("hidden"))) virtual void doStuff();
393};
394
395struct S2 {
396  virtual void doStuff();
397  __attribute__((visibility("hidden"))) void unused();
398
399};
400
401void test() {
402  S *s = new S;
403  s->doStuff();
404
405  S2 *s2 = new S2;
406  s2->doStuff();
407}
408}
409
410namespace 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
419struct 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
426struct B {
427  virtual void key();
428  virtual ~B() {}
429};
430
431void testcaseA() {
432  A a;
433  a.bar(); // this forces to emit definition of bar
434}
435
436void testcaseB() {
437  B b; // This only forces emitting of complete object destructor
438}
439
440} // namespace Test17
441
442namespace 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
451struct Base {
452  virtual int fun() { return 42; }
453  virtual ~Base() { }
454};
455
456struct Derived : Base {
457  Derived();
458};
459
460int foo() {
461  Derived *der = new Derived();
462  return der->fun();
463}
464}
465
466namespace 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
471template<class T>
472struct 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
481struct 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
492struct 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
512template<class>
513struct 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
533template<class T>
534int use() {
535  T *ptr = new T();
536  return ptr->foo(42);
537}
538
539void 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