77\*******************************************************************/
88
99#include < util/prefix.h>
10+ #include < util/type_eq.h>
1011
1112#include " class_hierarchy.h"
1213#include " remove_virtual_functions.h"
@@ -43,15 +44,23 @@ class remove_virtual_functionst
4344 class functiont
4445 {
4546 public:
47+ functiont () {}
48+ explicit functiont (const irep_idt& _class_id) :
49+ class_id(_class_id)
50+ {}
51+
4652 symbol_exprt symbol_expr;
4753 irep_idt class_id;
4854 };
4955
5056 typedef std::vector<functiont> functionst;
5157 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 ;
5564
5665 exprt build_class_identifier (const exprt &);
5766};
@@ -180,7 +189,7 @@ void remove_virtual_functionst::remove_virtual_function(
180189 exprt this_expr=code.arguments ()[0 ];
181190 assert (this_expr.type ().id ()==ID_pointer &&
182191 " 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 ();
184193 if (points_to==empty_typet ())
185194 {
186195 symbol_typet symbol_type (functions.back ().class_id );
@@ -193,14 +202,14 @@ void remove_virtual_functionst::remove_virtual_function(
193202 for (const auto &fun : functions)
194203 {
195204 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 ())
197206 {
198207 // call function
199208 t1->make_function_call (code);
200- auto & newcall=to_code_function_call (t1->code );
209+ auto & newcall=to_code_function_call (t1->code );
201210 newcall.function ()=fun.symbol_expr ;
202211 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) )
204213 newcall.arguments ()[0 ].make_typecast (need_type);
205214 }
206215 else
@@ -253,11 +262,33 @@ void remove_virtual_functionst::remove_virtual_function(
253262 target->make_skip ();
254263}
255264
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+
256287void remove_virtual_functionst::get_child_functions_rec (
257288 const irep_idt &this_id,
258289 const symbol_exprt &last_method_defn,
259290 const irep_idt &component_name,
260- functionst &functions)
291+ functionst &functions) const
261292{
262293 auto findit=class_hierarchy.class_map .find (this_id);
263294 if (findit==class_hierarchy.class_map .end ())
@@ -266,19 +297,23 @@ void remove_virtual_functionst::get_child_functions_rec(
266297 for (const auto & child : findit->second .children )
267298 {
268299 exprt method=get_method (child, component_name);
269- functiont function;
270- function.class_id =child;
300+ functiont function (child);
271301 if (method.is_not_nil ())
272302 {
273303 function.symbol_expr =to_symbol_expr (method);
274304 function.symbol_expr .set (ID_C_class, child);
275305 }
276- else {
306+ else
307+ {
277308 function.symbol_expr =last_method_defn;
278309 }
279310 functions.push_back (function);
280311
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);
282317 }
283318}
284319
@@ -324,17 +359,20 @@ void remove_virtual_functionst::get_functions(
324359 c=parents.front ();
325360 }
326361
327- if (root_function.class_id == irep_idt ())
362+ if (root_function.class_id . empty ())
328363 {
329364 // No definition here; this is an abstract function.
330365 root_function.class_id =class_id;
331366 }
332367
333368 // 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);
335374
336375 functions.push_back (root_function);
337-
338376}
339377
340378/* ******************************************************************\
@@ -351,7 +389,7 @@ Function: remove_virtual_functionst::get_method
351389
352390exprt remove_virtual_functionst::get_method (
353391 const irep_idt &class_id,
354- const irep_idt &component_name)
392+ const irep_idt &component_name) const
355393{
356394 irep_idt id=id2string (class_id)+" ." +
357395 id2string (component_name);
0 commit comments