1// RUN: %clang_cc1 %s -I%S -triple=x86_64-apple-darwin10 -emit-llvm -o %t
2// RUN: %clang_cc1 %s -I%S -triple=x86_64-apple-darwin10 -O2 -disable-llvm-optzns -emit-llvm -o %t.opt
3// RUN: FileCheck --check-prefix=CHECK-TEST1 %s < %t
4// RUN: FileCheck --check-prefix=CHECK-TEST2 %s < %t
5// RUN: FileCheck --check-prefix=CHECK-TEST5 %s < %t
6// RUN: FileCheck --check-prefix=CHECK-TEST8 %s < %t.opt
7// RUN: FileCheck --check-prefix=CHECK-TEST9 %s < %t.opt
8// RUN: FileCheck --check-prefix=CHECK-TEST10 %s < %t.opt
9// RUN: FileCheck --check-prefix=CHECK-TEST11 %s < %t.opt
10// RUN: FileCheck --check-prefix=CHECK-TEST12 %s < %t.opt
11// RUN: FileCheck --check-prefix=CHECK-TEST13 %s < %t.opt
12// RUN: FileCheck --check-prefix=CHECK-TEST14 %s < %t.opt
13// RUN: FileCheck --check-prefix=CHECK-TEST15 %s < %t.opt
14// RUN: FileCheck --check-prefix=CHECK-TEST16 %s < %t.opt
15
16#include <typeinfo>
17
18// CHECK-TEST1: @_ZTVN5Test11AE = external unnamed_addr constant
19namespace Test1 {
20
21struct A {
22  A();
23  virtual void f();
24  virtual ~A() { }
25};
26
27A::A() { }
28
29void f(A* a) {
30  a->f();
31};
32
33// CHECK-LABEL: define void @_ZN5Test11gEv
34// CHECK: call void @_ZN5Test11A1fEv
35void g() {
36  A a;
37  f(&a);
38}
39
40}
41
42// Test2::A's key function (f) is defined in this translation unit, but when
43// we're doing codegen for the typeid(A) call, we don't know that yet.
44// This tests mainly that the typeinfo and typename constants have their linkage
45// updated correctly.
46
47// CHECK-TEST2: @_ZTSN5Test21AE = constant
48// CHECK-TEST2: @_ZTIN5Test21AE = constant
49// CHECK-TEST2: @_ZTVN5Test21AE = unnamed_addr constant
50namespace Test2 {
51  struct A {
52    virtual void f();
53  };
54
55  const std::type_info &g() {
56    return typeid(A);
57  };
58
59  void A::f() { }
60}
61
62// Test that we don't assert on this test.
63namespace Test3 {
64
65struct A {
66  virtual void f();
67  virtual ~A() { }
68};
69
70struct B : A {
71  B();
72  virtual void f();
73};
74
75B::B() { }
76
77void g(A* a) {
78  a->f();
79};
80
81}
82
83// PR9114, test that we don't try to instantiate RefPtr<Node>.
84namespace Test4 {
85
86template <class T> struct RefPtr {
87  T* p;
88  ~RefPtr() {
89    p->deref();
90  }
91};
92
93struct A {
94  virtual ~A();
95};
96
97struct Node;
98
99struct B : A {
100  virtual void deref();
101  RefPtr<Node> m;
102};
103
104void f() {
105  RefPtr<B> b;
106}
107
108}
109
110// PR9130, test that we emit a definition of A::f.
111// CHECK-TEST5-LABEL: define linkonce_odr void @_ZN5Test51A1fEv
112namespace Test5 {
113
114struct A {
115  virtual void f() { }
116};
117
118struct B : A {
119  virtual ~B();
120};
121
122B::~B() { }
123
124}
125
126// Check that we don't assert on this test.
127namespace Test6 {
128
129struct A {
130  virtual ~A();
131  int a;
132};
133
134struct B {
135  virtual ~B();
136  int b;
137};
138
139struct C : A, B {
140  C();
141};
142
143struct D : C {
144  virtual void f();
145  D();
146};
147
148D::D() { }
149
150}
151
152namespace Test7 {
153
154struct c1 {};
155struct c10 : c1{
156  virtual void foo ();
157};
158struct c11 : c10, c1{
159  virtual void f6 ();
160};
161struct c28 : virtual c11{
162  void f6 ();
163};
164}
165
166namespace Test8 {
167// CHECK-TEST8: @_ZTVN5Test81YE = available_externally unnamed_addr constant
168// vtable for X is not generated because there are no stores here
169struct X {
170  X();
171  virtual void foo();
172};
173struct Y : X {
174  void foo();
175};
176
177void g(X* p) { p->foo(); }
178void f() {
179  Y y;
180  g(&y);
181  X x;
182  g(&x);
183}
184
185}  // Test8
186
187namespace Test9 {
188// All virtual functions are outline, so we can assume that it will
189// be generated in translation unit where foo is defined.
190// CHECK-TEST9-DAG: @_ZTVN5Test91AE = available_externally unnamed_addr constant
191// CHECK-TEST9-DAG: @_ZTVN5Test91BE = available_externally unnamed_addr constant
192struct A {
193  virtual void foo();
194  virtual void bar();
195};
196void A::bar() {}
197
198struct B : A {
199  void foo();
200};
201
202void g() {
203  A a;
204  a.foo();
205  B b;
206  b.foo();
207}
208
209}  // Test9
210
211namespace Test10 {
212
213// because A's key function is defined here, vtable is generated in this TU
214// CHECK-TEST10-DAG: @_ZTVN6Test101AE = unnamed_addr constant
215struct A {
216  virtual void foo();
217  virtual void bar();
218};
219void A::foo() {}
220
221// Because key function is inline we will generate vtable as linkonce_odr.
222// CHECK-TEST10-DAG: @_ZTVN6Test101DE = linkonce_odr unnamed_addr constant
223struct D : A {
224  void bar();
225};
226inline void D::bar() {}
227
228// Because B has outline all virtual functions, we can refer to them.
229// CHECK-TEST10-DAG: @_ZTVN6Test101BE = available_externally unnamed_addr constant
230struct B : A {
231  void foo();
232  void bar();
233};
234
235// C's key function (car) is outline, but C has inline virtual function so we
236// can't guarantee that we will be able to refer to bar from name
237// so (at the moment) we can't emit vtable available_externally.
238// CHECK-TEST10-DAG: @_ZTVN6Test101CE = external unnamed_addr constant
239struct C : A {
240  void bar() {}               // defined in body - not key function
241  virtual inline void gar();  // inline in body - not key function
242  virtual void car();
243};
244
245// no key function, vtable will be generated everywhere it will be used
246// CHECK-TEST10-DAG: @_ZTVN6Test101EE = linkonce_odr unnamed_addr constant
247struct E : A {};
248
249void g(A& a) {
250  a.foo();
251  a.bar();
252}
253
254void f() {
255  A a;
256  g(a);
257  B b;
258  g(b);
259  C c;
260  g(c);
261  D d;
262  g(d);
263  E e;
264  g(e);
265}
266
267}  // Test10
268
269namespace Test11 {
270struct D;
271// Can emit C's vtable available_externally.
272// CHECK-TEST11: @_ZTVN6Test111CE = available_externally unnamed_addr constant
273struct C {
274  virtual D& operator=(const D&);
275};
276
277// Cannot emit B's vtable available_externally, because we cannot create
278// a reference to the inline virtual B::operator= function.
279// CHECK-TEST11: @_ZTVN6Test111DE = external unnamed_addr constant
280struct D : C {
281  virtual void key();
282};
283D f();
284
285void g(D& a) {
286  C c;
287  c = a;
288  a.key();
289  a.key();
290}
291void g() {
292  D d;
293  d = f();
294  g(d);
295}
296}  // Test 11
297
298namespace Test12 {
299
300// CHECK-TEST12: @_ZTVN6Test121AE = external unnamed_addr constant
301struct A {
302  virtual void foo();
303  virtual ~A() {}
304};
305// CHECK-TEST12: @_ZTVN6Test121BE = external unnamed_addr constant
306struct B : A {
307  void foo();
308};
309
310void g() {
311  A a;
312  a.foo();
313  B b;
314  b.foo();
315}
316}
317
318namespace Test13 {
319
320// CHECK-TEST13-DAG: @_ZTVN6Test131AE = available_externally unnamed_addr constant
321// CHECK-TEST13-DAG: @_ZTVN6Test131BE = external unnamed_addr constant
322struct A {
323  virtual ~A();
324};
325struct B : A {
326  virtual void f();
327  void operator delete(void *);
328  ~B() {}
329};
330
331void g() {
332  A *b = new B;
333}
334}
335
336namespace Test14 {
337
338// CHECK-TEST14: @_ZTVN6Test141AE = available_externally unnamed_addr constant
339struct A {
340  virtual void f();
341  void operator delete(void *);
342  ~A();
343};
344
345void g() {
346  A *b = new A;
347  delete b;
348}
349}
350
351namespace Test15 {
352// In this test D's vtable has two slots for function f(), but uses only one,
353// so the second slot is set to null.
354// CHECK-TEST15: @_ZTVN6Test151DE = available_externally unnamed_addr constant
355struct A { virtual void f() {} };
356struct B : virtual A {};
357struct C : virtual A {};
358struct D : B, C {
359  virtual void g();
360  void f();
361};
362
363void test() {
364  D * d = new D;
365  d->f();
366}
367}
368
369namespace Test16 {
370// S has virtual method that is hidden, because of it we can't
371// generate available_externally vtable for it.
372// CHECK-TEST16-DAG: @_ZTVN6Test161SE = external unnamed_addr constant
373// CHECK-TEST16-DAG: @_ZTVN6Test162S2E = available_externally
374
375struct S {
376  __attribute__((visibility("hidden"))) virtual void doStuff();
377};
378
379struct S2 {
380  virtual void doStuff();
381  __attribute__((visibility("hidden"))) void unused();
382
383};
384
385void test() {
386  S *s = new S;
387  s->doStuff();
388
389  S2 *s2 = new S2;
390  s2->doStuff();
391}
392}
393
394