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