blob: 193ee5f804060d66da5502595484fa109ff6e4f3 [file] [log] [blame]
Ulrich Weigand92309972012-10-24 12:22:56 +00001// RUN: %clang_cc1 -triple i386-unknown-unknown -std=c++11 %s -emit-llvm -o - | FileCheck %s
Anders Carlssonf89e0422011-01-23 21:07:30 +00002
3namespace Test1 {
4 struct A {
5 virtual int f() final;
6 };
7
Stephen Lin93ab6bf2013-08-15 06:47:53 +00008 // CHECK-LABEL: define i32 @_ZN5Test11fEPNS_1AE
Anders Carlssonf89e0422011-01-23 21:07:30 +00009 int f(A *a) {
10 // CHECK: call i32 @_ZN5Test11A1fEv
11 return a->f();
12 }
13}
14
15namespace Test2 {
16 struct A final {
17 virtual int f();
18 };
19
Stephen Lin93ab6bf2013-08-15 06:47:53 +000020 // CHECK-LABEL: define i32 @_ZN5Test21fEPNS_1AE
Anders Carlssonf89e0422011-01-23 21:07:30 +000021 int f(A *a) {
22 // CHECK: call i32 @_ZN5Test21A1fEv
23 return a->f();
24 }
25}
Anders Carlsson1679f5a2011-01-29 03:52:01 +000026
27namespace Test3 {
28 struct A {
29 virtual int f();
30 };
31
32 struct B final : A { };
33
Stephen Lin93ab6bf2013-08-15 06:47:53 +000034 // CHECK-LABEL: define i32 @_ZN5Test31fEPNS_1BE
Anders Carlsson1679f5a2011-01-29 03:52:01 +000035 int f(B *b) {
36 // CHECK: call i32 @_ZN5Test31A1fEv
37 return b->f();
38 }
Anders Carlsson268ab8c2011-01-29 05:04:11 +000039
Stephen Lin93ab6bf2013-08-15 06:47:53 +000040 // CHECK-LABEL: define i32 @_ZN5Test31fERNS_1BE
Anders Carlsson268ab8c2011-01-29 05:04:11 +000041 int f(B &b) {
42 // CHECK: call i32 @_ZN5Test31A1fEv
43 return b.f();
44 }
45
Stephen Lin93ab6bf2013-08-15 06:47:53 +000046 // CHECK-LABEL: define i32 @_ZN5Test31fEPv
Anders Carlsson268ab8c2011-01-29 05:04:11 +000047 int f(void *v) {
48 // CHECK: call i32 @_ZN5Test31A1fEv
49 return static_cast<B*>(v)->f();
50 }
Anders Carlsson1679f5a2011-01-29 03:52:01 +000051}
Rafael Espindola0b4fe502012-06-26 17:45:31 +000052
53namespace Test4 {
54 struct A {
55 virtual void f();
Stephen Hines0e2c34f2015-03-23 12:09:02 -070056 virtual int operator-();
Rafael Espindola0b4fe502012-06-26 17:45:31 +000057 };
58
59 struct B final : A {
60 virtual void f();
Stephen Hines0e2c34f2015-03-23 12:09:02 -070061 virtual int operator-();
Rafael Espindola0b4fe502012-06-26 17:45:31 +000062 };
63
Stephen Lin93ab6bf2013-08-15 06:47:53 +000064 // CHECK-LABEL: define void @_ZN5Test41fEPNS_1BE
Rafael Espindola0b4fe502012-06-26 17:45:31 +000065 void f(B* d) {
66 // CHECK: call void @_ZN5Test41B1fEv
67 static_cast<A*>(d)->f();
Stephen Hines0e2c34f2015-03-23 12:09:02 -070068 // CHECK: call i32 @_ZN5Test41BngEv
69 -static_cast<A&>(*d);
Rafael Espindola0b4fe502012-06-26 17:45:31 +000070 }
71}
72
73namespace Test5 {
74 struct A {
75 virtual void f();
Stephen Hines0e2c34f2015-03-23 12:09:02 -070076 virtual int operator-();
Rafael Espindola0b4fe502012-06-26 17:45:31 +000077 };
78
79 struct B : A {
80 virtual void f();
Stephen Hines0e2c34f2015-03-23 12:09:02 -070081 virtual int operator-();
Rafael Espindola0b4fe502012-06-26 17:45:31 +000082 };
83
84 struct C final : B {
85 };
86
Stephen Lin93ab6bf2013-08-15 06:47:53 +000087 // CHECK-LABEL: define void @_ZN5Test51fEPNS_1CE
Rafael Espindola0b4fe502012-06-26 17:45:31 +000088 void f(C* d) {
Rafael Espindolaea01d762012-06-28 14:28:57 +000089 // FIXME: It should be possible to devirtualize this case, but that is
90 // not implemented yet.
91 // CHECK: getelementptr
92 // CHECK-NEXT: %[[FUNC:.*]] = load
93 // CHECK-NEXT: call void %[[FUNC]]
Rafael Espindola0b4fe502012-06-26 17:45:31 +000094 static_cast<A*>(d)->f();
95 }
Stephen Hines0e2c34f2015-03-23 12:09:02 -070096 // CHECK-LABEL: define void @_ZN5Test53fopEPNS_1CE
97 void fop(C* d) {
98 // FIXME: It should be possible to devirtualize this case, but that is
99 // not implemented yet.
100 // CHECK: getelementptr
101 // CHECK-NEXT: %[[FUNC:.*]] = load
102 // CHECK-NEXT: call i32 %[[FUNC]]
103 -static_cast<A&>(*d);
104 }
Rafael Espindola0b4fe502012-06-26 17:45:31 +0000105}
106
107namespace Test6 {
108 struct A {
109 virtual ~A();
110 };
111
112 struct B : public A {
113 virtual ~B();
114 };
115
116 struct C {
117 virtual ~C();
118 };
119
120 struct D final : public C, public B {
121 };
122
Stephen Lin93ab6bf2013-08-15 06:47:53 +0000123 // CHECK-LABEL: define void @_ZN5Test61fEPNS_1DE
Rafael Espindola0b4fe502012-06-26 17:45:31 +0000124 void f(D* d) {
125 // CHECK: call void @_ZN5Test61DD1Ev
126 static_cast<A*>(d)->~A();
127 }
128}
Rafael Espindola632fbaa2012-06-28 01:56:38 +0000129
130namespace Test7 {
131 struct foo {
132 virtual void g() {}
133 };
134
135 struct bar {
136 virtual int f() { return 0; }
137 };
138
139 struct zed final : public foo, public bar {
140 int z;
141 virtual int f() {return z;}
142 };
143
Stephen Lin93ab6bf2013-08-15 06:47:53 +0000144 // CHECK-LABEL: define i32 @_ZN5Test71fEPNS_3zedE
Rafael Espindola632fbaa2012-06-28 01:56:38 +0000145 int f(zed *z) {
146 // CHECK: alloca
147 // CHECK-NEXT: store
148 // CHECK-NEXT: load
Eli Friedman465e89e2012-10-25 00:12:49 +0000149 // CHECK-NEXT: call i32 @_ZN5Test73zed1fEv
Rafael Espindola632fbaa2012-06-28 01:56:38 +0000150 // CHECK-NEXT: ret
151 return static_cast<bar*>(z)->f();
152 }
153}
Rafael Espindolaea01d762012-06-28 14:28:57 +0000154
155namespace Test8 {
156 struct A { virtual ~A() {} };
157 struct B {
158 int b;
159 virtual int foo() { return b; }
160 };
161 struct C final : A, B { };
Stephen Lin93ab6bf2013-08-15 06:47:53 +0000162 // CHECK-LABEL: define i32 @_ZN5Test84testEPNS_1CE
Rafael Espindolaea01d762012-06-28 14:28:57 +0000163 int test(C *c) {
164 // CHECK: %[[THIS:.*]] = phi
165 // CHECK-NEXT: call i32 @_ZN5Test81B3fooEv(%"struct.Test8::B"* %[[THIS]])
166 return static_cast<B*>(c)->foo();
167 }
168}
Rafael Espindola4a889e42012-06-28 15:11:39 +0000169
170namespace Test9 {
171 struct A {
172 int a;
173 };
174 struct B {
175 int b;
176 };
177 struct C : public B, public A {
178 };
179 struct RA {
180 virtual A *f() {
181 return 0;
182 }
Stephen Hines0e2c34f2015-03-23 12:09:02 -0700183 virtual A *operator-() {
184 return 0;
185 }
Rafael Espindola4a889e42012-06-28 15:11:39 +0000186 };
187 struct RC final : public RA {
188 virtual C *f() {
189 C *x = new C();
190 x->a = 1;
191 x->b = 2;
192 return x;
193 }
Stephen Hines0e2c34f2015-03-23 12:09:02 -0700194 virtual C *operator-() {
195 C *x = new C();
196 x->a = 1;
197 x->b = 2;
198 return x;
199 }
Rafael Espindola4a889e42012-06-28 15:11:39 +0000200 };
201 // CHECK: define {{.*}} @_ZN5Test91fEPNS_2RCE
202 A *f(RC *x) {
203 // FIXME: It should be possible to devirtualize this case, but that is
204 // not implemented yet.
Stephen Hines176edba2014-12-01 14:53:08 -0800205 // CHECK: load
206 // CHECK: bitcast
207 // CHECK: [[F_PTR_RA:%.+]] = bitcast
208 // CHECK: [[VTABLE:%.+]] = load {{.+}} [[F_PTR_RA]]
209 // CHECK: [[VFN:%.+]] = getelementptr inbounds {{.+}} [[VTABLE]], i{{[0-9]+}} 0
210 // CHECK-NEXT: %[[FUNC:.*]] = load {{.+}} [[VFN]]
Rafael Espindola4a889e42012-06-28 15:11:39 +0000211 // CHECK-NEXT: = call {{.*}} %[[FUNC]]
212 return static_cast<RA*>(x)->f();
213 }
Stephen Hines0e2c34f2015-03-23 12:09:02 -0700214 // CHECK: define {{.*}} @_ZN5Test93fopEPNS_2RCE
215 A *fop(RC *x) {
216 // FIXME: It should be possible to devirtualize this case, but that is
217 // not implemented yet.
218 // CHECK: load
219 // CHECK: bitcast
220 // CHECK: [[F_PTR_RA:%.+]] = bitcast
221 // CHECK: [[VTABLE:%.+]] = load {{.+}} [[F_PTR_RA]]
222 // CHECK: [[VFN:%.+]] = getelementptr inbounds {{.+}} [[VTABLE]], i{{[0-9]+}} 1
223 // CHECK-NEXT: %[[FUNC:.*]] = load {{.+}} [[VFN]]
224 // CHECK-NEXT: = call {{.*}} %[[FUNC]]
225 return -static_cast<RA&>(*x);
226 }
Rafael Espindola4a889e42012-06-28 15:11:39 +0000227}