• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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-LABEL: define i32 @_ZN5Test11fEPNS_1AE
f(A * a)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-LABEL: define i32 @_ZN5Test21fEPNS_1AE
f(A * a)21   int f(A *a) {
22     // CHECK: call i32 @_ZN5Test21A1fEv
23     return a->f();
24   }
25 }
26 
27 namespace Test2a {
28   struct A {
~ATest2a::A29     virtual ~A() final {}
30     virtual int f();
31   };
32 
33   // CHECK-LABEL: define i32 @_ZN6Test2a1fEPNS_1AE
f(A * a)34   int f(A *a) {
35     // CHECK: call i32 @_ZN6Test2a1A1fEv
36     return a->f();
37   }
38 }
39 
40 
41 namespace Test3 {
42   struct A {
43     virtual int f();  };
44 
45   struct B final : A { };
46 
47   // CHECK-LABEL: define i32 @_ZN5Test31fEPNS_1BE
f(B * b)48   int f(B *b) {
49     // CHECK: call i32 @_ZN5Test31A1fEv
50     return b->f();
51   }
52 
53   // CHECK-LABEL: define i32 @_ZN5Test31fERNS_1BE
f(B & b)54   int f(B &b) {
55     // CHECK: call i32 @_ZN5Test31A1fEv
56     return b.f();
57   }
58 
59   // CHECK-LABEL: define i32 @_ZN5Test31fEPv
f(void * v)60   int f(void *v) {
61     // CHECK: call i32 @_ZN5Test31A1fEv
62     return static_cast<B*>(v)->f();
63   }
64 }
65 
66 namespace Test4 {
67   struct A {
68     virtual void f();
69     virtual int operator-();
70   };
71 
72   struct B final : A {
73     virtual void f();
74     virtual int operator-();
75   };
76 
77   // CHECK-LABEL: define void @_ZN5Test41fEPNS_1BE
f(B * d)78   void f(B* d) {
79     // CHECK: call void @_ZN5Test41B1fEv
80     static_cast<A*>(d)->f();
81     // CHECK: call i32 @_ZN5Test41BngEv
82     -static_cast<A&>(*d);
83   }
84 }
85 
86 namespace Test5 {
87   struct A {
88     virtual void f();
89     virtual int operator-();
90   };
91 
92   struct B : A {
93     virtual void f();
94     virtual int operator-();
95   };
96 
97   struct C final : B {
98   };
99 
100   // CHECK-LABEL: define void @_ZN5Test51fEPNS_1CE
f(C * d)101   void f(C* d) {
102     // FIXME: It should be possible to devirtualize this case, but that is
103     // not implemented yet.
104     // CHECK: getelementptr
105     // CHECK-NEXT: %[[FUNC:.*]] = load
106     // CHECK-NEXT: call void %[[FUNC]]
107     static_cast<A*>(d)->f();
108   }
109   // CHECK-LABEL: define void @_ZN5Test53fopEPNS_1CE
fop(C * d)110   void fop(C* d) {
111     // FIXME: It should be possible to devirtualize this case, but that is
112     // not implemented yet.
113     // CHECK: getelementptr
114     // CHECK-NEXT: %[[FUNC:.*]] = load
115     // CHECK-NEXT: call i32 %[[FUNC]]
116     -static_cast<A&>(*d);
117   }
118 }
119 
120 namespace Test6 {
121   struct A {
122     virtual ~A();
123   };
124 
125   struct B : public A {
126     virtual ~B();
127   };
128 
129   struct C {
130     virtual ~C();
131   };
132 
133   struct D final : public C, public B {
134   };
135 
136   // CHECK-LABEL: define void @_ZN5Test61fEPNS_1DE
f(D * d)137   void f(D* d) {
138     // CHECK: call void @_ZN5Test61DD1Ev
139     static_cast<A*>(d)->~A();
140   }
141 }
142 
143 namespace Test7 {
144   struct foo {
gTest7::foo145     virtual void g() {}
146   };
147 
148   struct bar {
fTest7::bar149     virtual int f() { return 0; }
150   };
151 
152   struct zed final : public foo, public bar {
153     int z;
fTest7::zed154     virtual int f() {return z;}
155   };
156 
157   // CHECK-LABEL: define i32 @_ZN5Test71fEPNS_3zedE
f(zed * z)158   int f(zed *z) {
159     // CHECK: alloca
160     // CHECK-NEXT: store
161     // CHECK-NEXT: load
162     // CHECK-NEXT: call i32 @_ZN5Test73zed1fEv
163     // CHECK-NEXT: ret
164     return static_cast<bar*>(z)->f();
165   }
166 }
167 
168 namespace Test8 {
~ATest8::A169   struct A { virtual ~A() {} };
170   struct B {
171     int b;
fooTest8::B172     virtual int foo() { return b; }
173   };
174   struct C final : A, B {  };
175   // CHECK-LABEL: define i32 @_ZN5Test84testEPNS_1CE
test(C * c)176   int test(C *c) {
177     // CHECK: %[[THIS:.*]] = phi
178     // CHECK-NEXT: call i32 @_ZN5Test81B3fooEv(%"struct.Test8::B"* {{[^,]*}} %[[THIS]])
179     return static_cast<B*>(c)->foo();
180   }
181 }
182 
183 namespace Test9 {
184   struct A {
185     int a;
186   };
187   struct B {
188     int b;
189   };
190   struct C : public B, public A {
191   };
192   struct RA {
fTest9::RA193     virtual A *f() {
194       return 0;
195     }
operator -Test9::RA196     virtual A *operator-() {
197       return 0;
198     }
199   };
200   struct RC final : public RA {
fTest9::RC201     virtual C *f() {
202       C *x = new C();
203       x->a = 1;
204       x->b = 2;
205       return x;
206     }
operator -Test9::RC207     virtual C *operator-() {
208       C *x = new C();
209       x->a = 1;
210       x->b = 2;
211       return x;
212     }
213   };
214   // CHECK: define {{.*}} @_ZN5Test91fEPNS_2RCE
f(RC * x)215   A *f(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]+}} 0
223     // CHECK-NEXT: %[[FUNC:.*]] = load {{.+}} [[VFN]]
224     // CHECK-NEXT: = call {{.*}} %[[FUNC]]
225     return static_cast<RA*>(x)->f();
226   }
227   // CHECK: define {{.*}} @_ZN5Test93fopEPNS_2RCE
fop(RC * x)228   A *fop(RC *x) {
229     // FIXME: It should be possible to devirtualize this case, but that is
230     // not implemented yet.
231     // CHECK: load
232     // CHECK: bitcast
233     // CHECK: [[F_PTR_RA:%.+]] = bitcast
234     // CHECK: [[VTABLE:%.+]] = load {{.+}} [[F_PTR_RA]]
235     // CHECK: [[VFN:%.+]] = getelementptr inbounds {{.+}} [[VTABLE]], i{{[0-9]+}} 1
236     // CHECK-NEXT: %[[FUNC:.*]] = load {{.+}} [[VFN]]
237     // CHECK-NEXT: = call {{.*}} %[[FUNC]]
238     return -static_cast<RA&>(*x);
239   }
240 }
241 
242 namespace Test10 {
243   struct A {
244     virtual int f();
245   };
246 
247   struct B : A {
248     int f() final;
249   };
250 
251   // CHECK-LABEL: define i32 @_ZN6Test101fEPNS_1BE
f(B * b)252   int f(B *b) {
253     // CHECK: call i32 @_ZN6Test101B1fEv
254     return static_cast<A *>(b)->f();
255   }
256 }
257 
258 namespace TestVBase {
259   struct A { virtual void f(); };
260   struct B : virtual A {};
261   struct C : virtual A { void f() override; };
262 
263   extern struct BC final : B, C {} &bc;
264   extern struct BCusingA final : B, C { using A::f; } &bc_using_a;
265   extern struct BCusingB final : B, C { using B::f; } &bc_using_b;
266   extern struct BCusingC final : B, C { using C::f; } &bc_using_c;
267 
268   extern struct CB final : C, B {} &cb;
269   extern struct CBusingA final : C, B { using A::f; } &cb_using_a;
270   extern struct CBusingB final : C, B { using B::f; } &cb_using_b;
271   extern struct CBusingC final : C, B { using C::f; } &cb_using_c;
272 
273   // CHECK-LABEL: @_ZN9TestVBase4testEv(
test()274   void test() {
275     // FIXME: The 'using A' case can be devirtualized to call A's virtual
276     // adjustment thunk for C::f.
277     // FIXME: The 'using B' case can be devirtualized, but requires us to emit
278     // a derived-to-base or base-to-derived conversion as part of
279     // devirtualization.
280 
281     // CHECK: call void @_ZN9TestVBase1C1fEv(
282     bc.f();
283     // CHECK: call void %
284     bc_using_a.f();
285     // CHECK: call void %
286     bc_using_b.f();
287     // CHECK: call void @_ZN9TestVBase1C1fEv(
288     bc_using_c.f();
289 
290     // CHECK: call void @_ZN9TestVBase1C1fEv(
291     cb.f();
292     // CHECK: call void %
293     cb_using_a.f();
294     // CHECK: call void %
295     cb_using_b.f();
296     // CHECK: call void @_ZN9TestVBase1C1fEv(
297     cb_using_c.f();
298   }
299 }
300 
301 namespace Test11 {
302   // Check that the definitions of Derived's operators are emitted.
303 
304   // CHECK-LABEL: define linkonce_odr void @_ZN6Test111SIiE4foo1Ev(
305   // CHECK: call void @_ZN6Test111SIiE7DerivedclEv(
306   // CHECK: call zeroext i1 @_ZN6Test111SIiE7DerivedeqERKNS_4BaseE(
307   // CHECK: call zeroext i1 @_ZN6Test111SIiE7DerivedntEv(
308   // CHECK: call nonnull align 4 dereferenceable(4) %"class.Test11::Base"* @_ZN6Test111SIiE7DerivedixEi(
309   // CHECK: define linkonce_odr void @_ZN6Test111SIiE7DerivedclEv(
310   // CHECK: define linkonce_odr zeroext i1 @_ZN6Test111SIiE7DerivedeqERKNS_4BaseE(
311   // CHECK: define linkonce_odr zeroext i1 @_ZN6Test111SIiE7DerivedntEv(
312   // CHECK: define linkonce_odr nonnull align 4 dereferenceable(4) %"class.Test11::Base"* @_ZN6Test111SIiE7DerivedixEi(
313   class Base {
314   public:
operator ()()315     virtual void operator()() {}
operator ==(const Base & other)316     virtual bool operator==(const Base &other) { return false; }
operator !()317     virtual bool operator!() { return false; }
operator [](int i)318     virtual Base &operator[](int i) { return *this; }
319   };
320 
321   template<class T>
322   struct S {
323     class Derived final : public Base {
324     public:
operator ()()325       void operator()() override {}
operator ==(const Base & other)326       bool operator==(const Base &other) override { return true; }
operator !()327       bool operator!() override { return true; }
operator [](int i)328       Base &operator[](int i) override { return *this; }
329     };
330 
331     Derived *ptr = nullptr, *ptr2 = nullptr;
332 
foo1Test11::S333     void foo1() {
334       if (ptr && ptr2) {
335         // These calls get devirtualized. Linkage fails if the definitions of
336         // the called functions are not emitted.
337         (*ptr)();
338         (void)(*ptr == *ptr2);
339         (void)(!(*ptr));
340         (void)((*ptr)[1]);
341       }
342     }
343   };
344 
foo2()345   void foo2() {
346     S<int> *s = new S<int>;
347     s->foo1();
348   }
349 }
350