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 Test3 {
28   struct A {
29     virtual int f();
30   };
31 
32   struct B final : A { };
33 
34   // CHECK-LABEL: define i32 @_ZN5Test31fEPNS_1BE
f(B * b)35   int f(B *b) {
36     // CHECK: call i32 @_ZN5Test31A1fEv
37     return b->f();
38   }
39 
40   // CHECK-LABEL: define i32 @_ZN5Test31fERNS_1BE
f(B & b)41   int f(B &b) {
42     // CHECK: call i32 @_ZN5Test31A1fEv
43     return b.f();
44   }
45 
46   // CHECK-LABEL: define i32 @_ZN5Test31fEPv
f(void * v)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     virtual int operator-();
57   };
58 
59   struct B final : A {
60     virtual void f();
61     virtual int operator-();
62   };
63 
64   // CHECK-LABEL: define void @_ZN5Test41fEPNS_1BE
f(B * d)65   void f(B* d) {
66     // CHECK: call void @_ZN5Test41B1fEv
67     static_cast<A*>(d)->f();
68     // CHECK: call i32 @_ZN5Test41BngEv
69     -static_cast<A&>(*d);
70   }
71 }
72 
73 namespace Test5 {
74   struct A {
75     virtual void f();
76     virtual int operator-();
77   };
78 
79   struct B : A {
80     virtual void f();
81     virtual int operator-();
82   };
83 
84   struct C final : B {
85   };
86 
87   // CHECK-LABEL: define void @_ZN5Test51fEPNS_1CE
f(C * d)88   void f(C* d) {
89     // 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]]
94     static_cast<A*>(d)->f();
95   }
96   // CHECK-LABEL: define void @_ZN5Test53fopEPNS_1CE
fop(C * d)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   }
105 }
106 
107 namespace 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 
123   // CHECK-LABEL: define void @_ZN5Test61fEPNS_1DE
f(D * d)124   void f(D* d) {
125     // CHECK: call void @_ZN5Test61DD1Ev
126     static_cast<A*>(d)->~A();
127   }
128 }
129 
130 namespace Test7 {
131   struct foo {
gTest7::foo132     virtual void g() {}
133   };
134 
135   struct bar {
fTest7::bar136     virtual int f() { return 0; }
137   };
138 
139   struct zed final : public foo, public bar {
140     int z;
fTest7::zed141     virtual int f() {return z;}
142   };
143 
144   // CHECK-LABEL: define i32 @_ZN5Test71fEPNS_3zedE
f(zed * z)145   int f(zed *z) {
146     // CHECK: alloca
147     // CHECK-NEXT: store
148     // CHECK-NEXT: load
149     // CHECK-NEXT: call i32 @_ZN5Test73zed1fEv
150     // CHECK-NEXT: ret
151     return static_cast<bar*>(z)->f();
152   }
153 }
154 
155 namespace Test8 {
~ATest8::A156   struct A { virtual ~A() {} };
157   struct B {
158     int b;
fooTest8::B159     virtual int foo() { return b; }
160   };
161   struct C final : A, B {  };
162   // CHECK-LABEL: define i32 @_ZN5Test84testEPNS_1CE
test(C * c)163   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 }
169 
170 namespace 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 {
fTest9::RA180     virtual A *f() {
181       return 0;
182     }
operator -Test9::RA183     virtual A *operator-() {
184       return 0;
185     }
186   };
187   struct RC final : public RA {
fTest9::RC188     virtual C *f() {
189       C *x = new C();
190       x->a = 1;
191       x->b = 2;
192       return x;
193     }
operator -Test9::RC194     virtual C *operator-() {
195       C *x = new C();
196       x->a = 1;
197       x->b = 2;
198       return x;
199     }
200   };
201   // CHECK: define {{.*}} @_ZN5Test91fEPNS_2RCE
f(RC * x)202   A *f(RC *x) {
203     // FIXME: It should be possible to devirtualize this case, but that is
204     // not implemented yet.
205     // 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]]
211     // CHECK-NEXT: = call {{.*}} %[[FUNC]]
212     return static_cast<RA*>(x)->f();
213   }
214   // CHECK: define {{.*}} @_ZN5Test93fopEPNS_2RCE
fop(RC * x)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   }
227 }
228 
229 namespace Test10 {
230   struct A {
231     virtual int f();
232   };
233 
234   struct B : A {
235     int f() final;
236   };
237 
238   // CHECK-LABEL: define i32 @_ZN6Test101fEPNS_1BE
f(B * b)239   int f(B *b) {
240     // CHECK: call i32 @_ZN6Test101B1fEv
241     return static_cast<A *>(b)->f();
242   }
243 }
244 
245 namespace Test11 {
246   // Check that the definitions of Derived's operators are emitted.
247 
248   // CHECK-LABEL: define linkonce_odr void @_ZN6Test111SIiE4foo1Ev(
249   // CHECK: call void @_ZN6Test111SIiE7DerivedclEv(
250   // CHECK: call zeroext i1 @_ZN6Test111SIiE7DerivedeqERKNS_4BaseE(
251   // CHECK: call zeroext i1 @_ZN6Test111SIiE7DerivedntEv(
252   // CHECK: call dereferenceable(4) %"class.Test11::Base"* @_ZN6Test111SIiE7DerivedixEi(
253   // CHECK: define linkonce_odr void @_ZN6Test111SIiE7DerivedclEv(
254   // CHECK: define linkonce_odr zeroext i1 @_ZN6Test111SIiE7DerivedeqERKNS_4BaseE(
255   // CHECK: define linkonce_odr zeroext i1 @_ZN6Test111SIiE7DerivedntEv(
256   // CHECK: define linkonce_odr dereferenceable(4) %"class.Test11::Base"* @_ZN6Test111SIiE7DerivedixEi(
257   class Base {
258   public:
operator ()()259     virtual void operator()() {}
operator ==(const Base & other)260     virtual bool operator==(const Base &other) { return false; }
operator !()261     virtual bool operator!() { return false; }
operator [](int i)262     virtual Base &operator[](int i) { return *this; }
263   };
264 
265   template<class T>
266   struct S {
267     class Derived final : public Base {
268     public:
operator ()()269       void operator()() override {}
operator ==(const Base & other)270       bool operator==(const Base &other) override { return true; }
operator !()271       bool operator!() override { return true; }
operator [](int i)272       Base &operator[](int i) override { return *this; }
273     };
274 
275     Derived *ptr = nullptr, *ptr2 = nullptr;
276 
foo1Test11::S277     void foo1() {
278       if (ptr && ptr2) {
279         // These calls get devirtualized. Linkage fails if the definitions of
280         // the called functions are not emitted.
281         (*ptr)();
282         (void)(*ptr == *ptr2);
283         (void)(!(*ptr));
284         (void)((*ptr)[1]);
285       }
286     }
287   };
288 
foo2()289   void foo2() {
290     S<int> *s = new S<int>;
291     s->foo1();
292   }
293 }
294