10b4fe503ef00d9f8ea330850d3e3b303e9c7c876Rafael Espindola// RUN: %clang_cc1 -std=c++11 %s -emit-llvm -o - | FileCheck %s 2bd2bfae2a6e5dc264e1f13183ad2ac11095766bbAnders Carlsson 3bd2bfae2a6e5dc264e1f13183ad2ac11095766bbAnders Carlssonnamespace Test1 { 4bd2bfae2a6e5dc264e1f13183ad2ac11095766bbAnders Carlsson struct A { 5f89e0424b8903438179f4a2f16dddd5e5bdc814eAnders Carlsson virtual int f() final; 6bd2bfae2a6e5dc264e1f13183ad2ac11095766bbAnders Carlsson }; 7bd2bfae2a6e5dc264e1f13183ad2ac11095766bbAnders Carlsson 8bd2bfae2a6e5dc264e1f13183ad2ac11095766bbAnders Carlsson // CHECK: define i32 @_ZN5Test11fEPNS_1AE 9d66f42856539bf1c764c13fba41758228fc4cb9bAnders Carlsson int f(A *a) { 10f89e0424b8903438179f4a2f16dddd5e5bdc814eAnders Carlsson // CHECK: call i32 @_ZN5Test11A1fEv 11d66f42856539bf1c764c13fba41758228fc4cb9bAnders Carlsson return a->f(); 12d66f42856539bf1c764c13fba41758228fc4cb9bAnders Carlsson } 13d66f42856539bf1c764c13fba41758228fc4cb9bAnders Carlsson} 14d66f42856539bf1c764c13fba41758228fc4cb9bAnders Carlsson 15d66f42856539bf1c764c13fba41758228fc4cb9bAnders Carlssonnamespace Test2 { 16f89e0424b8903438179f4a2f16dddd5e5bdc814eAnders Carlsson struct A final { 17f89e0424b8903438179f4a2f16dddd5e5bdc814eAnders Carlsson virtual int f(); 18d66f42856539bf1c764c13fba41758228fc4cb9bAnders Carlsson }; 19d66f42856539bf1c764c13fba41758228fc4cb9bAnders Carlsson 20d66f42856539bf1c764c13fba41758228fc4cb9bAnders Carlsson // CHECK: define i32 @_ZN5Test21fEPNS_1AE 21d66f42856539bf1c764c13fba41758228fc4cb9bAnders Carlsson int f(A *a) { 22f89e0424b8903438179f4a2f16dddd5e5bdc814eAnders Carlsson // CHECK: call i32 @_ZN5Test21A1fEv 23bd2bfae2a6e5dc264e1f13183ad2ac11095766bbAnders Carlsson return a->f(); 24bd2bfae2a6e5dc264e1f13183ad2ac11095766bbAnders Carlsson } 25bd2bfae2a6e5dc264e1f13183ad2ac11095766bbAnders Carlsson} 261679f5a84ae1e578b0de347c89eaf31e0465f33cAnders Carlsson 271679f5a84ae1e578b0de347c89eaf31e0465f33cAnders Carlssonnamespace Test3 { 281679f5a84ae1e578b0de347c89eaf31e0465f33cAnders Carlsson struct A { 291679f5a84ae1e578b0de347c89eaf31e0465f33cAnders Carlsson virtual int f(); 301679f5a84ae1e578b0de347c89eaf31e0465f33cAnders Carlsson }; 311679f5a84ae1e578b0de347c89eaf31e0465f33cAnders Carlsson 321679f5a84ae1e578b0de347c89eaf31e0465f33cAnders Carlsson struct B final : A { }; 331679f5a84ae1e578b0de347c89eaf31e0465f33cAnders Carlsson 341679f5a84ae1e578b0de347c89eaf31e0465f33cAnders Carlsson // CHECK: define i32 @_ZN5Test31fEPNS_1BE 351679f5a84ae1e578b0de347c89eaf31e0465f33cAnders Carlsson int f(B *b) { 361679f5a84ae1e578b0de347c89eaf31e0465f33cAnders Carlsson // CHECK: call i32 @_ZN5Test31A1fEv 371679f5a84ae1e578b0de347c89eaf31e0465f33cAnders Carlsson return b->f(); 381679f5a84ae1e578b0de347c89eaf31e0465f33cAnders Carlsson } 39268ab8c6b92dc40c678d8458a335698fa34915c9Anders Carlsson 40268ab8c6b92dc40c678d8458a335698fa34915c9Anders Carlsson // CHECK: define i32 @_ZN5Test31fERNS_1BE 41268ab8c6b92dc40c678d8458a335698fa34915c9Anders Carlsson int f(B &b) { 42268ab8c6b92dc40c678d8458a335698fa34915c9Anders Carlsson // CHECK: call i32 @_ZN5Test31A1fEv 43268ab8c6b92dc40c678d8458a335698fa34915c9Anders Carlsson return b.f(); 44268ab8c6b92dc40c678d8458a335698fa34915c9Anders Carlsson } 45268ab8c6b92dc40c678d8458a335698fa34915c9Anders Carlsson 46268ab8c6b92dc40c678d8458a335698fa34915c9Anders Carlsson // CHECK: define i32 @_ZN5Test31fEPv 47268ab8c6b92dc40c678d8458a335698fa34915c9Anders Carlsson int f(void *v) { 48268ab8c6b92dc40c678d8458a335698fa34915c9Anders Carlsson // CHECK: call i32 @_ZN5Test31A1fEv 49268ab8c6b92dc40c678d8458a335698fa34915c9Anders Carlsson return static_cast<B*>(v)->f(); 50268ab8c6b92dc40c678d8458a335698fa34915c9Anders Carlsson } 511679f5a84ae1e578b0de347c89eaf31e0465f33cAnders Carlsson} 520b4fe503ef00d9f8ea330850d3e3b303e9c7c876Rafael Espindola 530b4fe503ef00d9f8ea330850d3e3b303e9c7c876Rafael Espindolanamespace Test4 { 540b4fe503ef00d9f8ea330850d3e3b303e9c7c876Rafael Espindola struct A { 550b4fe503ef00d9f8ea330850d3e3b303e9c7c876Rafael Espindola virtual void f(); 560b4fe503ef00d9f8ea330850d3e3b303e9c7c876Rafael Espindola }; 570b4fe503ef00d9f8ea330850d3e3b303e9c7c876Rafael Espindola 580b4fe503ef00d9f8ea330850d3e3b303e9c7c876Rafael Espindola struct B final : A { 590b4fe503ef00d9f8ea330850d3e3b303e9c7c876Rafael Espindola virtual void f(); 600b4fe503ef00d9f8ea330850d3e3b303e9c7c876Rafael Espindola }; 610b4fe503ef00d9f8ea330850d3e3b303e9c7c876Rafael Espindola 620b4fe503ef00d9f8ea330850d3e3b303e9c7c876Rafael Espindola // CHECK: define void @_ZN5Test41fEPNS_1BE 630b4fe503ef00d9f8ea330850d3e3b303e9c7c876Rafael Espindola void f(B* d) { 640b4fe503ef00d9f8ea330850d3e3b303e9c7c876Rafael Espindola // CHECK: call void @_ZN5Test41B1fEv 650b4fe503ef00d9f8ea330850d3e3b303e9c7c876Rafael Espindola static_cast<A*>(d)->f(); 660b4fe503ef00d9f8ea330850d3e3b303e9c7c876Rafael Espindola } 670b4fe503ef00d9f8ea330850d3e3b303e9c7c876Rafael Espindola} 680b4fe503ef00d9f8ea330850d3e3b303e9c7c876Rafael Espindola 690b4fe503ef00d9f8ea330850d3e3b303e9c7c876Rafael Espindolanamespace Test5 { 700b4fe503ef00d9f8ea330850d3e3b303e9c7c876Rafael Espindola struct A { 710b4fe503ef00d9f8ea330850d3e3b303e9c7c876Rafael Espindola virtual void f(); 720b4fe503ef00d9f8ea330850d3e3b303e9c7c876Rafael Espindola }; 730b4fe503ef00d9f8ea330850d3e3b303e9c7c876Rafael Espindola 740b4fe503ef00d9f8ea330850d3e3b303e9c7c876Rafael Espindola struct B : A { 750b4fe503ef00d9f8ea330850d3e3b303e9c7c876Rafael Espindola virtual void f(); 760b4fe503ef00d9f8ea330850d3e3b303e9c7c876Rafael Espindola }; 770b4fe503ef00d9f8ea330850d3e3b303e9c7c876Rafael Espindola 780b4fe503ef00d9f8ea330850d3e3b303e9c7c876Rafael Espindola struct C final : B { 790b4fe503ef00d9f8ea330850d3e3b303e9c7c876Rafael Espindola }; 800b4fe503ef00d9f8ea330850d3e3b303e9c7c876Rafael Espindola 810b4fe503ef00d9f8ea330850d3e3b303e9c7c876Rafael Espindola // CHECK: define void @_ZN5Test51fEPNS_1CE 820b4fe503ef00d9f8ea330850d3e3b303e9c7c876Rafael Espindola void f(C* d) { 83ea01d7661751e062bb670cc1a0bdfee5789cb96fRafael Espindola // FIXME: It should be possible to devirtualize this case, but that is 84ea01d7661751e062bb670cc1a0bdfee5789cb96fRafael Espindola // not implemented yet. 85ea01d7661751e062bb670cc1a0bdfee5789cb96fRafael Espindola // CHECK: getelementptr 86ea01d7661751e062bb670cc1a0bdfee5789cb96fRafael Espindola // CHECK-NEXT: %[[FUNC:.*]] = load 87ea01d7661751e062bb670cc1a0bdfee5789cb96fRafael Espindola // CHECK-NEXT: call void %[[FUNC]] 880b4fe503ef00d9f8ea330850d3e3b303e9c7c876Rafael Espindola static_cast<A*>(d)->f(); 890b4fe503ef00d9f8ea330850d3e3b303e9c7c876Rafael Espindola } 900b4fe503ef00d9f8ea330850d3e3b303e9c7c876Rafael Espindola} 910b4fe503ef00d9f8ea330850d3e3b303e9c7c876Rafael Espindola 920b4fe503ef00d9f8ea330850d3e3b303e9c7c876Rafael Espindolanamespace Test6 { 930b4fe503ef00d9f8ea330850d3e3b303e9c7c876Rafael Espindola struct A { 940b4fe503ef00d9f8ea330850d3e3b303e9c7c876Rafael Espindola virtual ~A(); 950b4fe503ef00d9f8ea330850d3e3b303e9c7c876Rafael Espindola }; 960b4fe503ef00d9f8ea330850d3e3b303e9c7c876Rafael Espindola 970b4fe503ef00d9f8ea330850d3e3b303e9c7c876Rafael Espindola struct B : public A { 980b4fe503ef00d9f8ea330850d3e3b303e9c7c876Rafael Espindola virtual ~B(); 990b4fe503ef00d9f8ea330850d3e3b303e9c7c876Rafael Espindola }; 1000b4fe503ef00d9f8ea330850d3e3b303e9c7c876Rafael Espindola 1010b4fe503ef00d9f8ea330850d3e3b303e9c7c876Rafael Espindola struct C { 1020b4fe503ef00d9f8ea330850d3e3b303e9c7c876Rafael Espindola virtual ~C(); 1030b4fe503ef00d9f8ea330850d3e3b303e9c7c876Rafael Espindola }; 1040b4fe503ef00d9f8ea330850d3e3b303e9c7c876Rafael Espindola 1050b4fe503ef00d9f8ea330850d3e3b303e9c7c876Rafael Espindola struct D final : public C, public B { 1060b4fe503ef00d9f8ea330850d3e3b303e9c7c876Rafael Espindola }; 1070b4fe503ef00d9f8ea330850d3e3b303e9c7c876Rafael Espindola 1080b4fe503ef00d9f8ea330850d3e3b303e9c7c876Rafael Espindola // CHECK: define void @_ZN5Test61fEPNS_1DE 1090b4fe503ef00d9f8ea330850d3e3b303e9c7c876Rafael Espindola void f(D* d) { 1100b4fe503ef00d9f8ea330850d3e3b303e9c7c876Rafael Espindola // CHECK: call void @_ZN5Test61DD1Ev 1110b4fe503ef00d9f8ea330850d3e3b303e9c7c876Rafael Espindola static_cast<A*>(d)->~A(); 1120b4fe503ef00d9f8ea330850d3e3b303e9c7c876Rafael Espindola } 1130b4fe503ef00d9f8ea330850d3e3b303e9c7c876Rafael Espindola} 114632fbaa22fbed7c090eb83775731bfff786c2198Rafael Espindola 115632fbaa22fbed7c090eb83775731bfff786c2198Rafael Espindolanamespace Test7 { 116632fbaa22fbed7c090eb83775731bfff786c2198Rafael Espindola struct foo { 117632fbaa22fbed7c090eb83775731bfff786c2198Rafael Espindola virtual void g() {} 118632fbaa22fbed7c090eb83775731bfff786c2198Rafael Espindola }; 119632fbaa22fbed7c090eb83775731bfff786c2198Rafael Espindola 120632fbaa22fbed7c090eb83775731bfff786c2198Rafael Espindola struct bar { 121632fbaa22fbed7c090eb83775731bfff786c2198Rafael Espindola virtual int f() { return 0; } 122632fbaa22fbed7c090eb83775731bfff786c2198Rafael Espindola }; 123632fbaa22fbed7c090eb83775731bfff786c2198Rafael Espindola 124632fbaa22fbed7c090eb83775731bfff786c2198Rafael Espindola struct zed final : public foo, public bar { 125632fbaa22fbed7c090eb83775731bfff786c2198Rafael Espindola int z; 126632fbaa22fbed7c090eb83775731bfff786c2198Rafael Espindola virtual int f() {return z;} 127632fbaa22fbed7c090eb83775731bfff786c2198Rafael Espindola }; 128632fbaa22fbed7c090eb83775731bfff786c2198Rafael Espindola 129632fbaa22fbed7c090eb83775731bfff786c2198Rafael Espindola // CHECK: define i32 @_ZN5Test71fEPNS_3zedE 130632fbaa22fbed7c090eb83775731bfff786c2198Rafael Espindola int f(zed *z) { 131632fbaa22fbed7c090eb83775731bfff786c2198Rafael Espindola // CHECK: alloca 132632fbaa22fbed7c090eb83775731bfff786c2198Rafael Espindola // CHECK-NEXT: store 133632fbaa22fbed7c090eb83775731bfff786c2198Rafael Espindola // CHECK-NEXT: load 134632fbaa22fbed7c090eb83775731bfff786c2198Rafael Espindola // CHECK-NEXT: bitcast 135632fbaa22fbed7c090eb83775731bfff786c2198Rafael Espindola // CHECK-NEXT: call {{.*}} @_ZN5Test73zed1fEv 136632fbaa22fbed7c090eb83775731bfff786c2198Rafael Espindola // CHECK-NEXT: ret 137632fbaa22fbed7c090eb83775731bfff786c2198Rafael Espindola return static_cast<bar*>(z)->f(); 138632fbaa22fbed7c090eb83775731bfff786c2198Rafael Espindola } 139632fbaa22fbed7c090eb83775731bfff786c2198Rafael Espindola} 140ea01d7661751e062bb670cc1a0bdfee5789cb96fRafael Espindola 141ea01d7661751e062bb670cc1a0bdfee5789cb96fRafael Espindolanamespace Test8 { 142ea01d7661751e062bb670cc1a0bdfee5789cb96fRafael Espindola struct A { virtual ~A() {} }; 143ea01d7661751e062bb670cc1a0bdfee5789cb96fRafael Espindola struct B { 144ea01d7661751e062bb670cc1a0bdfee5789cb96fRafael Espindola int b; 145ea01d7661751e062bb670cc1a0bdfee5789cb96fRafael Espindola virtual int foo() { return b; } 146ea01d7661751e062bb670cc1a0bdfee5789cb96fRafael Espindola }; 147ea01d7661751e062bb670cc1a0bdfee5789cb96fRafael Espindola struct C final : A, B { }; 148ea01d7661751e062bb670cc1a0bdfee5789cb96fRafael Espindola // CHECK: define i32 @_ZN5Test84testEPNS_1CE 149ea01d7661751e062bb670cc1a0bdfee5789cb96fRafael Espindola int test(C *c) { 150ea01d7661751e062bb670cc1a0bdfee5789cb96fRafael Espindola // CHECK: %[[THIS:.*]] = phi 151ea01d7661751e062bb670cc1a0bdfee5789cb96fRafael Espindola // CHECK-NEXT: call i32 @_ZN5Test81B3fooEv(%"struct.Test8::B"* %[[THIS]]) 152ea01d7661751e062bb670cc1a0bdfee5789cb96fRafael Espindola return static_cast<B*>(c)->foo(); 153ea01d7661751e062bb670cc1a0bdfee5789cb96fRafael Espindola } 154ea01d7661751e062bb670cc1a0bdfee5789cb96fRafael Espindola} 1554a889e47bd5a8d08a705a87962a35a504728d7f6Rafael Espindola 1564a889e47bd5a8d08a705a87962a35a504728d7f6Rafael Espindolanamespace Test9 { 1574a889e47bd5a8d08a705a87962a35a504728d7f6Rafael Espindola struct A { 1584a889e47bd5a8d08a705a87962a35a504728d7f6Rafael Espindola int a; 1594a889e47bd5a8d08a705a87962a35a504728d7f6Rafael Espindola }; 1604a889e47bd5a8d08a705a87962a35a504728d7f6Rafael Espindola struct B { 1614a889e47bd5a8d08a705a87962a35a504728d7f6Rafael Espindola int b; 1624a889e47bd5a8d08a705a87962a35a504728d7f6Rafael Espindola }; 1634a889e47bd5a8d08a705a87962a35a504728d7f6Rafael Espindola struct C : public B, public A { 1644a889e47bd5a8d08a705a87962a35a504728d7f6Rafael Espindola }; 1654a889e47bd5a8d08a705a87962a35a504728d7f6Rafael Espindola struct RA { 1664a889e47bd5a8d08a705a87962a35a504728d7f6Rafael Espindola virtual A *f() { 1674a889e47bd5a8d08a705a87962a35a504728d7f6Rafael Espindola return 0; 1684a889e47bd5a8d08a705a87962a35a504728d7f6Rafael Espindola } 1694a889e47bd5a8d08a705a87962a35a504728d7f6Rafael Espindola }; 1704a889e47bd5a8d08a705a87962a35a504728d7f6Rafael Espindola struct RC final : public RA { 1714a889e47bd5a8d08a705a87962a35a504728d7f6Rafael Espindola virtual C *f() { 1724a889e47bd5a8d08a705a87962a35a504728d7f6Rafael Espindola C *x = new C(); 1734a889e47bd5a8d08a705a87962a35a504728d7f6Rafael Espindola x->a = 1; 1744a889e47bd5a8d08a705a87962a35a504728d7f6Rafael Espindola x->b = 2; 1754a889e47bd5a8d08a705a87962a35a504728d7f6Rafael Espindola return x; 1764a889e47bd5a8d08a705a87962a35a504728d7f6Rafael Espindola } 1774a889e47bd5a8d08a705a87962a35a504728d7f6Rafael Espindola }; 1784a889e47bd5a8d08a705a87962a35a504728d7f6Rafael Espindola // CHECK: define {{.*}} @_ZN5Test91fEPNS_2RCE 1794a889e47bd5a8d08a705a87962a35a504728d7f6Rafael Espindola A *f(RC *x) { 1804a889e47bd5a8d08a705a87962a35a504728d7f6Rafael Espindola // FIXME: It should be possible to devirtualize this case, but that is 1814a889e47bd5a8d08a705a87962a35a504728d7f6Rafael Espindola // not implemented yet. 1824a889e47bd5a8d08a705a87962a35a504728d7f6Rafael Espindola // CHECK: getelementptr 1834a889e47bd5a8d08a705a87962a35a504728d7f6Rafael Espindola // CHECK-NEXT: %[[FUNC:.*]] = load 1844a889e47bd5a8d08a705a87962a35a504728d7f6Rafael Espindola // CHECK-NEXT: bitcast 1854a889e47bd5a8d08a705a87962a35a504728d7f6Rafael Espindola // CHECK-NEXT: = call {{.*}} %[[FUNC]] 1864a889e47bd5a8d08a705a87962a35a504728d7f6Rafael Espindola return static_cast<RA*>(x)->f(); 1874a889e47bd5a8d08a705a87962a35a504728d7f6Rafael Espindola } 1884a889e47bd5a8d08a705a87962a35a504728d7f6Rafael Espindola} 189