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