7
7
\*******************************************************************/
8
8
9
9
#include < util/prefix.h>
10
+ #include < util/type_eq.h>
10
11
11
12
#include " class_hierarchy.h"
12
13
#include " remove_virtual_functions.h"
@@ -43,15 +44,23 @@ class remove_virtual_functionst
43
44
class functiont
44
45
{
45
46
public:
47
+ functiont () {}
48
+ explicit functiont (const irep_idt& _class_id) :
49
+ class_id(_class_id)
50
+ {}
51
+
46
52
symbol_exprt symbol_expr;
47
53
irep_idt class_id;
48
54
};
49
55
50
56
typedef std::vector<functiont> functionst;
51
57
void get_functions (const exprt &, functionst &);
52
- void get_child_functions_rec (const irep_idt &, const symbol_exprt &,
53
- const irep_idt &, functionst &);
54
- exprt get_method (const irep_idt &class_id, const irep_idt &component_name);
58
+ void get_child_functions_rec (
59
+ const irep_idt &, const symbol_exprt &,
60
+ const irep_idt &, functionst &) const ;
61
+ exprt get_method (
62
+ const irep_idt &class_id,
63
+ const irep_idt &component_name) const ;
55
64
56
65
exprt build_class_identifier (const exprt &);
57
66
};
@@ -180,7 +189,7 @@ void remove_virtual_functionst::remove_virtual_function(
180
189
exprt this_expr=code.arguments ()[0 ];
181
190
assert (this_expr.type ().id ()==ID_pointer &&
182
191
" Non-pointer this-arg in remove-virtuals?" );
183
- const auto & points_to=this_expr.type ().subtype ();
192
+ const auto & points_to=this_expr.type ().subtype ();
184
193
if (points_to==empty_typet ())
185
194
{
186
195
symbol_typet symbol_type (functions.back ().class_id );
@@ -193,14 +202,14 @@ void remove_virtual_functionst::remove_virtual_function(
193
202
for (const auto &fun : functions)
194
203
{
195
204
goto_programt::targett t1=new_code_calls.add_instruction ();
196
- if (fun.symbol_expr .get_identifier ()!= irep_idt ())
205
+ if (! fun.symbol_expr .get_identifier (). empty ())
197
206
{
198
207
// call function
199
208
t1->make_function_call (code);
200
- auto & newcall=to_code_function_call (t1->code );
209
+ auto & newcall=to_code_function_call (t1->code );
201
210
newcall.function ()=fun.symbol_expr ;
202
211
pointer_typet need_type (symbol_typet (fun.symbol_expr .get (ID_C_class)));
203
- if (newcall.arguments ()[0 ].type ()!= need_type)
212
+ if (! type_eq ( newcall.arguments ()[0 ].type (), need_type, ns) )
204
213
newcall.arguments ()[0 ].make_typecast (need_type);
205
214
}
206
215
else
@@ -253,11 +262,33 @@ void remove_virtual_functionst::remove_virtual_function(
253
262
target->make_skip ();
254
263
}
255
264
265
+ /* ******************************************************************\
266
+
267
+ Function: remove_virtual_functionst::get_child_functions_rec
268
+
269
+ Inputs: `this_id`: class name
270
+ `last_method_defn`: the most-derived parent of `this_id`
271
+ to define the requested function
272
+ `component_name`: name of the function searched for
273
+
274
+ Outputs: `functions` is assigned a list of {class name, function symbol}
275
+ pairs indicating that if `this` is of the given class, then the
276
+ call will target the given function. Thus if A <: B <: C and A
277
+ and C provide overrides of `f` (but B does not),
278
+ get_child_functions_rec("C", C.f, "f") -> [{"C", C.f},
279
+ {"B", C.f},
280
+ {"A", A.f}]
281
+
282
+ Purpose: Used by get_functions to track the most-derived parent that
283
+ provides an override of a given function.
284
+
285
+ \*******************************************************************/
286
+
256
287
void remove_virtual_functionst::get_child_functions_rec (
257
288
const irep_idt &this_id,
258
289
const symbol_exprt &last_method_defn,
259
290
const irep_idt &component_name,
260
- functionst &functions)
291
+ functionst &functions) const
261
292
{
262
293
auto findit=class_hierarchy.class_map .find (this_id);
263
294
if (findit==class_hierarchy.class_map .end ())
@@ -266,19 +297,23 @@ void remove_virtual_functionst::get_child_functions_rec(
266
297
for (const auto & child : findit->second .children )
267
298
{
268
299
exprt method=get_method (child, component_name);
269
- functiont function;
270
- function.class_id =child;
300
+ functiont function (child);
271
301
if (method.is_not_nil ())
272
302
{
273
303
function.symbol_expr =to_symbol_expr (method);
274
304
function.symbol_expr .set (ID_C_class, child);
275
305
}
276
- else {
306
+ else
307
+ {
277
308
function.symbol_expr =last_method_defn;
278
309
}
279
310
functions.push_back (function);
280
311
281
- get_child_functions_rec (child,function.symbol_expr ,component_name,functions);
312
+ get_child_functions_rec (
313
+ child,
314
+ function.symbol_expr ,
315
+ component_name,
316
+ functions);
282
317
}
283
318
}
284
319
@@ -324,17 +359,20 @@ void remove_virtual_functionst::get_functions(
324
359
c=parents.front ();
325
360
}
326
361
327
- if (root_function.class_id == irep_idt ())
362
+ if (root_function.class_id . empty ())
328
363
{
329
364
// No definition here; this is an abstract function.
330
365
root_function.class_id =class_id;
331
366
}
332
367
333
368
// iterate over all children, transitively
334
- get_child_functions_rec (class_id,root_function.symbol_expr ,component_name,functions);
369
+ get_child_functions_rec (
370
+ class_id,
371
+ root_function.symbol_expr ,
372
+ component_name,
373
+ functions);
335
374
336
375
functions.push_back (root_function);
337
-
338
376
}
339
377
340
378
/* ******************************************************************\
@@ -351,7 +389,7 @@ Function: remove_virtual_functionst::get_method
351
389
352
390
exprt remove_virtual_functionst::get_method (
353
391
const irep_idt &class_id,
354
- const irep_idt &component_name)
392
+ const irep_idt &component_name) const
355
393
{
356
394
irep_idt id=id2string (class_id)+" ." +
357
395
id2string (component_name);
0 commit comments