560 lines · cpp
1// RUN: %clang_cc1 %s -I%S -triple=x86_64-apple-darwin10 -std=c++98 -emit-llvm -o %t2// RUN: %clang_cc1 %s -I%S -triple=x86_64-apple-darwin10 -std=c++98 -O2 -disable-llvm-passes -emit-llvm -o %t.opt3// 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-aliases4// RUN: FileCheck -allow-deprecated-dag-overlap --check-prefix=CHECK-TEST1 %s < %t5// RUN: FileCheck -allow-deprecated-dag-overlap --check-prefix=CHECK-TEST2 %s < %t6// RUN: FileCheck -allow-deprecated-dag-overlap --check-prefix=CHECK-TEST5 %s < %t7// RUN: FileCheck -allow-deprecated-dag-overlap --check-prefix=CHECK-TEST8 %s < %t.opt8// RUN: FileCheck -allow-deprecated-dag-overlap --check-prefix=CHECK-TEST9 %s < %t.opt9// RUN: FileCheck -allow-deprecated-dag-overlap --check-prefix=CHECK-TEST10 %s < %t.opt10// RUN: FileCheck -allow-deprecated-dag-overlap --check-prefix=CHECK-TEST11 %s < %t.opt11// RUN: FileCheck -allow-deprecated-dag-overlap --check-prefix=CHECK-TEST12 %s < %t.opt12// RUN: FileCheck -allow-deprecated-dag-overlap --check-prefix=CHECK-TEST13 %s < %t.opt13// RUN: FileCheck -allow-deprecated-dag-overlap --check-prefix=CHECK-TEST14 %s < %t.opt14// RUN: FileCheck -allow-deprecated-dag-overlap --check-prefix=CHECK-TEST15 %s < %t.opt15// RUN: FileCheck -allow-deprecated-dag-overlap --check-prefix=CHECK-TEST16 %s < %t.opt16// RUN: FileCheck -allow-deprecated-dag-overlap --check-prefix=CHECK-TEST17 %s < %t.opt17// RUN: FileCheck -allow-deprecated-dag-overlap --check-prefix=CHECK-FORCE-EMIT %s < %t.vtable18 19 20#include <typeinfo>21 22// CHECK-TEST1: @_ZTVN5Test11AE = external unnamed_addr constant23// CHECK-FORCE-EMIT-DAG: @_ZTVN5Test11AE = available_externally unnamed_addr constant24namespace 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 @_ZN5Test11gEv39// CHECK: call void @_ZN5Test11A1fEv40void 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 when48// 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 linkage50// updated correctly.51 52// CHECK-TEST2: @_ZTIN5Test21AE ={{.*}} constant53// CHECK-TEST2: @_ZTSN5Test21AE ={{.*}} constant54// CHECK-TEST2: @_ZTVN5Test21AE ={{.*}} unnamed_addr constant55namespace 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 @_ZN5Test51A1fEv117namespace 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 constant173// vtable for X is not generated because there are no stores here174struct 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} // Test8191 192namespace Test9 {193// All virtual functions are outline, so we can assume that it will194// be generated in translation unit where foo is defined.195// CHECK-TEST9-DAG: @_ZTVN5Test91AE = available_externally unnamed_addr constant196// CHECK-TEST9-DAG: @_ZTVN5Test91BE = available_externally unnamed_addr constant197struct 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} // Test9215 216namespace Test10 {217 218// because A's key function is defined here, vtable is generated in this TU219// CHECK-TEST10-DAG: @_ZTVN6Test101AE ={{.*}} unnamed_addr constant220// CHECK-FORCE-EMIT-DAG: @_ZTVN6Test101AE ={{.*}} unnamed_addr constant221struct 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 constant229// CHECK-FORCE-EMIT-DAG: @_ZTVN6Test101DE = linkonce_odr unnamed_addr constant230struct 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 constant237struct 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 we243// can't guarantee that we will be able to refer to bar from name244// so (at the moment) we can't emit vtable available_externally.245// CHECK-TEST10-DAG: @_ZTVN6Test101CE = external unnamed_addr constant246// CHECK-FORCE-EMIT-DAG: @_ZTVN6Test101CE = available_externally unnamed_addr constant247struct C : A {248 void bar() {} // defined in body - not key function249 virtual inline void gar(); // inline in body - not key function250 virtual void car();251};252 253// Inline definition outside body, so we can't emit vtable available_externally254// (see previous).255// CHECK-TEST10-DAG: @_ZTVN6Test101FE = external unnamed_addr constant256struct F : A {257 void foo();258 virtual void cat(); // inline outside body259};260inline void F::cat() {}261 262// no key function, vtable will be generated everywhere it will be used263// CHECK-TEST10-DAG: @_ZTVN6Test101EE = linkonce_odr unnamed_addr constant264// CHECK-FORCE-EMIT-DAG: @_ZTVN6Test101EE = linkonce_odr unnamed_addr constant265 266struct E : A {};267 268void h(A& a) {269 a.foo();270 a.bar();271}272 273void g() {274 A a;275 h(a);276 B b;277 h(b);278 C c;279 h(c);280 D d;281 h(d);282 E e;283 h(e);284 F f;285 h(f);286}287 288} // Test10289 290namespace Test11 {291struct D;292// Can emit C's vtable available_externally.293// CHECK-TEST11: @_ZTVN6Test111CE = available_externally unnamed_addr constant294struct C {295 virtual D& operator=(const D&);296};297 298// Can emit D's vtable available_externally.299// CHECK-TEST11: @_ZTVN6Test111DE = available_externally unnamed_addr constant300struct D : C {301 virtual void key();302};303D f();304 305void g(D& a) {306 C c;307 c = a;308 a.key();309 a.key();310}311void g() {312 D d;313 d = f();314 g(d);315}316} // Test 11317 318namespace Test12 {319 320// CHECK-TEST12: @_ZTVN6Test121AE = external unnamed_addr constant321// CHECK-FORCE-EMIT-DAG: @_ZTVN6Test121AE = available_externally unnamed_addr constant322struct A {323 virtual void foo();324 virtual ~A() {}325};326// CHECK-TEST12: @_ZTVN6Test121BE = external unnamed_addr constant327// CHECK-FORCE-EMIT-DAG: @_ZTVN6Test121BE = available_externally unnamed_addr constant328struct B : A {329 void foo();330};331 332void g() {333 A a;334 a.foo();335 B b;336 b.foo();337}338}339 340namespace Test13 {341 342// CHECK-TEST13-DAG: @_ZTVN6Test131AE = available_externally unnamed_addr constant343// CHECK-TEST13-DAG: @_ZTVN6Test131BE = external unnamed_addr constant344// CHECK-FORCE-EMIT-DAG: @_ZTVN6Test131AE = available_externally unnamed_addr constant345// CHECK-FORCE-EMIT-DAG: @_ZTVN6Test131BE = available_externally unnamed_addr constant346 347struct A {348 virtual ~A();349};350struct B : A {351 virtual void f();352 void operator delete(void *);353 ~B() {}354};355 356void g() {357 A *b = new B;358}359}360 361namespace Test14 {362 363// CHECK-TEST14: @_ZTVN6Test141AE = available_externally unnamed_addr constant364struct A {365 virtual void f();366 void operator delete(void *);367 ~A();368};369 370void g() {371 A *b = new A;372 delete b;373}374}375 376namespace Test15 {377// In this test D's vtable has two slots for function f(), but uses only one,378// so the second slot is set to null.379// CHECK-TEST15: @_ZTVN6Test151DE = available_externally unnamed_addr constant380struct A { virtual void f() {} };381struct B : virtual A {};382struct C : virtual A {};383struct D : B, C {384 virtual void g();385 void f();386};387 388void test() {389 D * d = new D;390 d->f();391}392}393 394namespace Test16 {395// S has virtual method that is hidden, because of it we can't396// generate available_externally vtable for it.397// CHECK-TEST16-DAG: @_ZTVN6Test161SE = external unnamed_addr constant398// CHECK-TEST16-DAG: @_ZTVN6Test162S2E = available_externally399// CHECK-FORCE-EMIT-DAG: @_ZTVN6Test161SE = external unnamed_addr constant400// CHECK-FORCE-EMIT-DAG: @_ZTVN6Test162S2E = available_externally401 402struct S {403 __attribute__((visibility("hidden"))) virtual void doStuff();404};405 406struct S2 {407 virtual void doStuff();408 __attribute__((visibility("hidden"))) void unused();409 410};411 412void test() {413 S *s = new S;414 s->doStuff();415 416 S2 *s2 = new S2;417 s2->doStuff();418}419}420 421namespace Test17 {422// This test checks if we emit vtables opportunistically.423// CHECK-TEST17-DAG: @_ZTVN6Test171AE = available_externally424// CHECK-TEST17-DAG: @_ZTVN6Test171BE = external425// CHECK-FORCE-EMIT-DAG: @_ZTVN6Test171AE = available_externally426// CHECK-FORCE-EMIT-DAG: @_ZTVN6Test171BE = available_externally427// CHECK-FORCE-EMIT-DAG: define linkonce_odr void @_ZN6Test171BD2Ev(428// CHECK-FORCE-EMIT-DAG: define linkonce_odr void @_ZN6Test171BD0Ev(429 430struct A {431 virtual void key();432 virtual void bar() {}433};434 435// We won't gonna use deleting destructor for this type, which will disallow436// emitting vtable as available_externally437struct B {438 virtual void key();439 virtual ~B() {}440};441 442void testcaseA() {443 A a;444 a.bar(); // this forces to emit definition of bar445}446 447void testcaseB() {448 B b; // This only forces emitting of complete object destructor449}450 451} // namespace Test17452 453namespace Test18 {454// Here vtable will be only emitted because it is referenced by assume-load455// after the Derived construction.456// CHECK-FORCE-EMIT-DAG: @_ZTVN6Test187DerivedE = linkonce_odr unnamed_addr constant {{.*}} @_ZTIN6Test187DerivedE, {{.*}} @_ZN6Test184Base3funEv, {{.*}} @_ZN6Test184BaseD2Ev, {{.*}} @_ZN6Test187DerivedD0Ev457// CHECK-FORCE-EMIT-DAG: define linkonce_odr void @_ZN6Test187DerivedD0Ev458// CHECK-FORCE-EMIT-DAG: define linkonce_odr void @_ZN6Test184BaseD2Ev459// CHECK-FORCE-EMIT-DAG: define linkonce_odr noundef i32 @_ZN6Test184Base3funEv460// CHECK-FORCE-EMIT-DAG: @_ZTIN6Test187DerivedE = linkonce_odr constant461 462struct Base {463 virtual int fun() { return 42; }464 virtual ~Base() { }465};466 467struct Derived : Base {468 Derived();469};470 471int foo() {472 Derived *der = new Derived();473 return der->fun();474}475}476 477namespace TestTemplates {478 479// CHECK-FORCE-EMIT-DAG: @_ZTVN13TestTemplates8TemplateIiEE = linkonce_odr unnamed_addr constant {{.*}} @_ZTIN13TestTemplates8TemplateIiEE, {{.*}} @_ZN13TestTemplates8TemplateIiE3fooEi, {{.*}}@_ZN13TestTemplates8TemplateIiE22thisShouldBeEmittedTooEi, {{.*}}@_ZN13TestTemplates8TemplateIiED1Ev, {{.*}}@_ZN13TestTemplates8TemplateIiED0Ev480// CHECK-FORCE-EMIT-DAG: define linkonce_odr noundef i32 @_ZN13TestTemplates8TemplateIiE22thisShouldBeEmittedTooEi481 482template<class T>483struct Template {484 Template();485 virtual T foo(T val);486 // CHECK-FORCE-EMIT-DAG: define linkonce_odr noundef i32 @_ZN13TestTemplates8TemplateIiE22thisShouldBeEmittedTooEi487 virtual T thisShouldBeEmittedToo(T val) { return val; }488 virtual ~Template();489};490 491 492struct NonTemplate {493 typedef int T;494 NonTemplate();495 virtual T foo(T val);496 // CHECK-FORCE-EMIT-DAG: define linkonce_odr noundef i32 @_ZN13TestTemplates11NonTemplate22thisShouldBeEmittedTooEi497 virtual T thisShouldBeEmittedToo(T val) { return val; }498 virtual ~NonTemplate();499};500 501// CHECK-FORCE-EMIT-DAG: @_ZTVN13TestTemplates16OuterNonTemplate27NestedTemplateInNonTemplateIiEE = linkonce_odr {{.*}} @_ZTIN13TestTemplates16OuterNonTemplate27NestedTemplateInNonTemplateIiEE, {{.*}} @_ZN13TestTemplates16OuterNonTemplate27NestedTemplateInNonTemplateIiE3fooEi, {{.*}} @_ZN13TestTemplates16OuterNonTemplate27NestedTemplateInNonTemplateIiE22thisShouldBeEmittedTooEi, {{.*}} @_ZN13TestTemplates16OuterNonTemplate27NestedTemplateInNonTemplateIiED1Ev, {{.*}} @_ZN13TestTemplates16OuterNonTemplate27NestedTemplateInNonTemplateIiED0Ev502 503struct OuterNonTemplate {504 template<class T>505 struct NestedTemplateInNonTemplate {506 NestedTemplateInNonTemplate();507 virtual T foo(T val);508 // CHECK-FORCE-EMIT-DAG: define linkonce_odr noundef i32 @_ZN13TestTemplates16OuterNonTemplate27NestedTemplateInNonTemplateIiE22thisShouldBeEmittedTooEi509 virtual T thisShouldBeEmittedToo(T val) { return val; }510 virtual ~NestedTemplateInNonTemplate();511 };512 513 struct NestedNonTemplateInNonTemplate {514 typedef int T;515 NestedNonTemplateInNonTemplate();516 virtual T foo(T val);517 // CHECK-FORCE-EMIT-DAG: define linkonce_odr noundef i32 @_ZN13TestTemplates16OuterNonTemplate30NestedNonTemplateInNonTemplate22thisShouldBeEmittedTooEi518 virtual T thisShouldBeEmittedToo(T val) { return val; }519 virtual ~NestedNonTemplateInNonTemplate();520 };521};522 523template<class>524struct OuterTemplate {525 template<class T>526 struct NestedTemplateInTemplate {527 NestedTemplateInTemplate();528 virtual T foo(T val);529 // CHECK-FORCE-EMIT-DAG: define linkonce_odr noundef i32 @_ZN13TestTemplates13OuterTemplateIlE24NestedTemplateInTemplateIiE22thisShouldBeEmittedTooEi530 virtual T thisShouldBeEmittedToo(T val) { return val; }531 virtual ~NestedTemplateInTemplate();532 };533 534 struct NestedNonTemplateInTemplate {535 typedef int T;536 NestedNonTemplateInTemplate();537 virtual T foo(T val);538 // CHECK-FORCE-EMIT-DAG: define linkonce_odr noundef i32 @_ZN13TestTemplates13OuterTemplateIlE27NestedNonTemplateInTemplate22thisShouldBeEmittedTooEi539 virtual T thisShouldBeEmittedToo(T val) { return val; }540 virtual ~NestedNonTemplateInTemplate();541 };542};543 544template<class T>545int use() {546 T *ptr = new T();547 return ptr->foo(42);548}549 550void test() {551 use<Template<int> >();552 use<OuterTemplate<long>::NestedTemplateInTemplate<int> >();553 use<OuterNonTemplate::NestedTemplateInNonTemplate<int> >();554 555 use<NonTemplate>();556 use<OuterTemplate<long>::NestedNonTemplateInTemplate>();557 use<OuterNonTemplate::NestedNonTemplateInNonTemplate>();558}559}560