1*67e74705SXin Li // RUN: %clang_cc1 -triple i386-unknown-unknown -std=c++11 %s -emit-llvm -o - | FileCheck %s 2*67e74705SXin Li 3*67e74705SXin Li namespace Test1 { 4*67e74705SXin Li struct A { 5*67e74705SXin Li virtual int f() final; 6*67e74705SXin Li }; 7*67e74705SXin Li 8*67e74705SXin Li // CHECK-LABEL: define i32 @_ZN5Test11fEPNS_1AE f(A * a)9*67e74705SXin Li int f(A *a) { 10*67e74705SXin Li // CHECK: call i32 @_ZN5Test11A1fEv 11*67e74705SXin Li return a->f(); 12*67e74705SXin Li } 13*67e74705SXin Li } 14*67e74705SXin Li 15*67e74705SXin Li namespace Test2 { 16*67e74705SXin Li struct A final { 17*67e74705SXin Li virtual int f(); 18*67e74705SXin Li }; 19*67e74705SXin Li 20*67e74705SXin Li // CHECK-LABEL: define i32 @_ZN5Test21fEPNS_1AE f(A * a)21*67e74705SXin Li int f(A *a) { 22*67e74705SXin Li // CHECK: call i32 @_ZN5Test21A1fEv 23*67e74705SXin Li return a->f(); 24*67e74705SXin Li } 25*67e74705SXin Li } 26*67e74705SXin Li 27*67e74705SXin Li namespace Test3 { 28*67e74705SXin Li struct A { 29*67e74705SXin Li virtual int f(); 30*67e74705SXin Li }; 31*67e74705SXin Li 32*67e74705SXin Li struct B final : A { }; 33*67e74705SXin Li 34*67e74705SXin Li // CHECK-LABEL: define i32 @_ZN5Test31fEPNS_1BE f(B * b)35*67e74705SXin Li int f(B *b) { 36*67e74705SXin Li // CHECK: call i32 @_ZN5Test31A1fEv 37*67e74705SXin Li return b->f(); 38*67e74705SXin Li } 39*67e74705SXin Li 40*67e74705SXin Li // CHECK-LABEL: define i32 @_ZN5Test31fERNS_1BE f(B & b)41*67e74705SXin Li int f(B &b) { 42*67e74705SXin Li // CHECK: call i32 @_ZN5Test31A1fEv 43*67e74705SXin Li return b.f(); 44*67e74705SXin Li } 45*67e74705SXin Li 46*67e74705SXin Li // CHECK-LABEL: define i32 @_ZN5Test31fEPv f(void * v)47*67e74705SXin Li int f(void *v) { 48*67e74705SXin Li // CHECK: call i32 @_ZN5Test31A1fEv 49*67e74705SXin Li return static_cast<B*>(v)->f(); 50*67e74705SXin Li } 51*67e74705SXin Li } 52*67e74705SXin Li 53*67e74705SXin Li namespace Test4 { 54*67e74705SXin Li struct A { 55*67e74705SXin Li virtual void f(); 56*67e74705SXin Li virtual int operator-(); 57*67e74705SXin Li }; 58*67e74705SXin Li 59*67e74705SXin Li struct B final : A { 60*67e74705SXin Li virtual void f(); 61*67e74705SXin Li virtual int operator-(); 62*67e74705SXin Li }; 63*67e74705SXin Li 64*67e74705SXin Li // CHECK-LABEL: define void @_ZN5Test41fEPNS_1BE f(B * d)65*67e74705SXin Li void f(B* d) { 66*67e74705SXin Li // CHECK: call void @_ZN5Test41B1fEv 67*67e74705SXin Li static_cast<A*>(d)->f(); 68*67e74705SXin Li // CHECK: call i32 @_ZN5Test41BngEv 69*67e74705SXin Li -static_cast<A&>(*d); 70*67e74705SXin Li } 71*67e74705SXin Li } 72*67e74705SXin Li 73*67e74705SXin Li namespace Test5 { 74*67e74705SXin Li struct A { 75*67e74705SXin Li virtual void f(); 76*67e74705SXin Li virtual int operator-(); 77*67e74705SXin Li }; 78*67e74705SXin Li 79*67e74705SXin Li struct B : A { 80*67e74705SXin Li virtual void f(); 81*67e74705SXin Li virtual int operator-(); 82*67e74705SXin Li }; 83*67e74705SXin Li 84*67e74705SXin Li struct C final : B { 85*67e74705SXin Li }; 86*67e74705SXin Li 87*67e74705SXin Li // CHECK-LABEL: define void @_ZN5Test51fEPNS_1CE f(C * d)88*67e74705SXin Li void f(C* d) { 89*67e74705SXin Li // FIXME: It should be possible to devirtualize this case, but that is 90*67e74705SXin Li // not implemented yet. 91*67e74705SXin Li // CHECK: getelementptr 92*67e74705SXin Li // CHECK-NEXT: %[[FUNC:.*]] = load 93*67e74705SXin Li // CHECK-NEXT: call void %[[FUNC]] 94*67e74705SXin Li static_cast<A*>(d)->f(); 95*67e74705SXin Li } 96*67e74705SXin Li // CHECK-LABEL: define void @_ZN5Test53fopEPNS_1CE fop(C * d)97*67e74705SXin Li void fop(C* d) { 98*67e74705SXin Li // FIXME: It should be possible to devirtualize this case, but that is 99*67e74705SXin Li // not implemented yet. 100*67e74705SXin Li // CHECK: getelementptr 101*67e74705SXin Li // CHECK-NEXT: %[[FUNC:.*]] = load 102*67e74705SXin Li // CHECK-NEXT: call i32 %[[FUNC]] 103*67e74705SXin Li -static_cast<A&>(*d); 104*67e74705SXin Li } 105*67e74705SXin Li } 106*67e74705SXin Li 107*67e74705SXin Li namespace Test6 { 108*67e74705SXin Li struct A { 109*67e74705SXin Li virtual ~A(); 110*67e74705SXin Li }; 111*67e74705SXin Li 112*67e74705SXin Li struct B : public A { 113*67e74705SXin Li virtual ~B(); 114*67e74705SXin Li }; 115*67e74705SXin Li 116*67e74705SXin Li struct C { 117*67e74705SXin Li virtual ~C(); 118*67e74705SXin Li }; 119*67e74705SXin Li 120*67e74705SXin Li struct D final : public C, public B { 121*67e74705SXin Li }; 122*67e74705SXin Li 123*67e74705SXin Li // CHECK-LABEL: define void @_ZN5Test61fEPNS_1DE f(D * d)124*67e74705SXin Li void f(D* d) { 125*67e74705SXin Li // CHECK: call void @_ZN5Test61DD1Ev 126*67e74705SXin Li static_cast<A*>(d)->~A(); 127*67e74705SXin Li } 128*67e74705SXin Li } 129*67e74705SXin Li 130*67e74705SXin Li namespace Test7 { 131*67e74705SXin Li struct foo { gTest7::foo132*67e74705SXin Li virtual void g() {} 133*67e74705SXin Li }; 134*67e74705SXin Li 135*67e74705SXin Li struct bar { fTest7::bar136*67e74705SXin Li virtual int f() { return 0; } 137*67e74705SXin Li }; 138*67e74705SXin Li 139*67e74705SXin Li struct zed final : public foo, public bar { 140*67e74705SXin Li int z; fTest7::zed141*67e74705SXin Li virtual int f() {return z;} 142*67e74705SXin Li }; 143*67e74705SXin Li 144*67e74705SXin Li // CHECK-LABEL: define i32 @_ZN5Test71fEPNS_3zedE f(zed * z)145*67e74705SXin Li int f(zed *z) { 146*67e74705SXin Li // CHECK: alloca 147*67e74705SXin Li // CHECK-NEXT: store 148*67e74705SXin Li // CHECK-NEXT: load 149*67e74705SXin Li // CHECK-NEXT: call i32 @_ZN5Test73zed1fEv 150*67e74705SXin Li // CHECK-NEXT: ret 151*67e74705SXin Li return static_cast<bar*>(z)->f(); 152*67e74705SXin Li } 153*67e74705SXin Li } 154*67e74705SXin Li 155*67e74705SXin Li namespace Test8 { ~ATest8::A156*67e74705SXin Li struct A { virtual ~A() {} }; 157*67e74705SXin Li struct B { 158*67e74705SXin Li int b; fooTest8::B159*67e74705SXin Li virtual int foo() { return b; } 160*67e74705SXin Li }; 161*67e74705SXin Li struct C final : A, B { }; 162*67e74705SXin Li // CHECK-LABEL: define i32 @_ZN5Test84testEPNS_1CE test(C * c)163*67e74705SXin Li int test(C *c) { 164*67e74705SXin Li // CHECK: %[[THIS:.*]] = phi 165*67e74705SXin Li // CHECK-NEXT: call i32 @_ZN5Test81B3fooEv(%"struct.Test8::B"* %[[THIS]]) 166*67e74705SXin Li return static_cast<B*>(c)->foo(); 167*67e74705SXin Li } 168*67e74705SXin Li } 169*67e74705SXin Li 170*67e74705SXin Li namespace Test9 { 171*67e74705SXin Li struct A { 172*67e74705SXin Li int a; 173*67e74705SXin Li }; 174*67e74705SXin Li struct B { 175*67e74705SXin Li int b; 176*67e74705SXin Li }; 177*67e74705SXin Li struct C : public B, public A { 178*67e74705SXin Li }; 179*67e74705SXin Li struct RA { fTest9::RA180*67e74705SXin Li virtual A *f() { 181*67e74705SXin Li return 0; 182*67e74705SXin Li } operator -Test9::RA183*67e74705SXin Li virtual A *operator-() { 184*67e74705SXin Li return 0; 185*67e74705SXin Li } 186*67e74705SXin Li }; 187*67e74705SXin Li struct RC final : public RA { fTest9::RC188*67e74705SXin Li virtual C *f() { 189*67e74705SXin Li C *x = new C(); 190*67e74705SXin Li x->a = 1; 191*67e74705SXin Li x->b = 2; 192*67e74705SXin Li return x; 193*67e74705SXin Li } operator -Test9::RC194*67e74705SXin Li virtual C *operator-() { 195*67e74705SXin Li C *x = new C(); 196*67e74705SXin Li x->a = 1; 197*67e74705SXin Li x->b = 2; 198*67e74705SXin Li return x; 199*67e74705SXin Li } 200*67e74705SXin Li }; 201*67e74705SXin Li // CHECK: define {{.*}} @_ZN5Test91fEPNS_2RCE f(RC * x)202*67e74705SXin Li A *f(RC *x) { 203*67e74705SXin Li // FIXME: It should be possible to devirtualize this case, but that is 204*67e74705SXin Li // not implemented yet. 205*67e74705SXin Li // CHECK: load 206*67e74705SXin Li // CHECK: bitcast 207*67e74705SXin Li // CHECK: [[F_PTR_RA:%.+]] = bitcast 208*67e74705SXin Li // CHECK: [[VTABLE:%.+]] = load {{.+}} [[F_PTR_RA]] 209*67e74705SXin Li // CHECK: [[VFN:%.+]] = getelementptr inbounds {{.+}} [[VTABLE]], i{{[0-9]+}} 0 210*67e74705SXin Li // CHECK-NEXT: %[[FUNC:.*]] = load {{.+}} [[VFN]] 211*67e74705SXin Li // CHECK-NEXT: = call {{.*}} %[[FUNC]] 212*67e74705SXin Li return static_cast<RA*>(x)->f(); 213*67e74705SXin Li } 214*67e74705SXin Li // CHECK: define {{.*}} @_ZN5Test93fopEPNS_2RCE fop(RC * x)215*67e74705SXin Li A *fop(RC *x) { 216*67e74705SXin Li // FIXME: It should be possible to devirtualize this case, but that is 217*67e74705SXin Li // not implemented yet. 218*67e74705SXin Li // CHECK: load 219*67e74705SXin Li // CHECK: bitcast 220*67e74705SXin Li // CHECK: [[F_PTR_RA:%.+]] = bitcast 221*67e74705SXin Li // CHECK: [[VTABLE:%.+]] = load {{.+}} [[F_PTR_RA]] 222*67e74705SXin Li // CHECK: [[VFN:%.+]] = getelementptr inbounds {{.+}} [[VTABLE]], i{{[0-9]+}} 1 223*67e74705SXin Li // CHECK-NEXT: %[[FUNC:.*]] = load {{.+}} [[VFN]] 224*67e74705SXin Li // CHECK-NEXT: = call {{.*}} %[[FUNC]] 225*67e74705SXin Li return -static_cast<RA&>(*x); 226*67e74705SXin Li } 227*67e74705SXin Li } 228