blob: 634bf84b416d02b757d3417b79a0a03530128a38 [file] [log] [blame]
Rafael Espindola0b4fe502012-06-26 17:45:31 +00001// RUN: %clang_cc1 -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
8 // CHECK: define i32 @_ZN5Test11fEPNS_1AE
9 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
20 // CHECK: define i32 @_ZN5Test21fEPNS_1AE
21 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
34 // CHECK: define i32 @_ZN5Test31fEPNS_1BE
35 int f(B *b) {
36 // CHECK: call i32 @_ZN5Test31A1fEv
37 return b->f();
38 }
Anders Carlsson268ab8c2011-01-29 05:04:11 +000039
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 }
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();
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
69namespace 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) {
Rafael Espindolaea01d762012-06-28 14:28:57 +000083 // 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]]
Rafael Espindola0b4fe502012-06-26 17:45:31 +000088 static_cast<A*>(d)->f();
89 }
90}
91
92namespace 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}
Rafael Espindola632fbaa2012-06-28 01:56:38 +0000114
115namespace 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: bitcast
135 // CHECK-NEXT: call {{.*}} @_ZN5Test73zed1fEv
136 // CHECK-NEXT: ret
137 return static_cast<bar*>(z)->f();
138 }
139}
Rafael Espindolaea01d762012-06-28 14:28:57 +0000140
141namespace Test8 {
142 struct A { virtual ~A() {} };
143 struct B {
144 int b;
145 virtual int foo() { return b; }
146 };
147 struct C final : A, B { };
148 // CHECK: define i32 @_ZN5Test84testEPNS_1CE
149 int test(C *c) {
150 // CHECK: %[[THIS:.*]] = phi
151 // CHECK-NEXT: call i32 @_ZN5Test81B3fooEv(%"struct.Test8::B"* %[[THIS]])
152 return static_cast<B*>(c)->foo();
153 }
154}
Rafael Espindola4a889e42012-06-28 15:11:39 +0000155
156namespace Test9 {
157 struct A {
158 int a;
159 };
160 struct B {
161 int b;
162 };
163 struct C : public B, public A {
164 };
165 struct RA {
166 virtual A *f() {
167 return 0;
168 }
169 };
170 struct RC final : public RA {
171 virtual C *f() {
172 C *x = new C();
173 x->a = 1;
174 x->b = 2;
175 return x;
176 }
177 };
178 // CHECK: define {{.*}} @_ZN5Test91fEPNS_2RCE
179 A *f(RC *x) {
180 // FIXME: It should be possible to devirtualize this case, but that is
181 // not implemented yet.
182 // CHECK: getelementptr
183 // CHECK-NEXT: %[[FUNC:.*]] = load
184 // CHECK-NEXT: bitcast
185 // CHECK-NEXT: = call {{.*}} %[[FUNC]]
186 return static_cast<RA*>(x)->f();
187 }
188}