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