8
8
9
9
// / \file
10
10
// / Remove Virtual Function (Method) Calls
11
+ #include < algorithm>
11
12
12
13
#include " remove_virtual_functions.h"
13
14
#include " class_hierarchy.h"
@@ -47,15 +48,20 @@ class remove_virtual_functionst
47
48
goto_programt::targett target);
48
49
49
50
void get_functions (const exprt &, dispatch_table_entriest &);
51
+ typedef std::function<
52
+ resolve_concrete_function_callt::concrete_function_callt (
53
+ const irep_idt &,
54
+ const irep_idt &)>
55
+ function_call_resolvert;
50
56
void get_child_functions_rec (
51
57
const irep_idt &,
52
58
const symbol_exprt &,
53
59
const irep_idt &,
54
60
dispatch_table_entriest &,
55
- std::set<irep_idt> &visited) const ;
56
- exprt get_method (
57
- const irep_idt &class_id,
58
- const irep_idt &component_name) const ;
61
+ std::set<irep_idt> &visited,
62
+ const function_call_resolvert &) const ;
63
+ exprt
64
+ get_method ( const irep_idt &class_id, const irep_idt &component_name) const ;
59
65
};
60
66
61
67
remove_virtual_functionst::remove_virtual_functionst (
@@ -194,7 +200,8 @@ void remove_virtual_functionst::remove_virtual_function(
194
200
t1->make_assertion (false_exprt ());
195
201
t1->source_location .set_comment (
196
202
(" cannot find calls for " +
197
- id2string (code.function ().get (ID_identifier))));
203
+ id2string (code.function ().get (ID_identifier)) + " dispatching " +
204
+ id2string (fun.class_id )));
198
205
}
199
206
insertit.first ->second =t1;
200
207
// goto final
@@ -250,6 +257,7 @@ void remove_virtual_functionst::remove_virtual_function(
250
257
// / `last_method_defn`: the most-derived parent of `this_id` to define the
251
258
// / requested function
252
259
// / `component_name`: name of the function searched for
260
+ // / `resolve_function_call`: function to resolve abstract method call
253
261
// / \return `functions` is assigned a list of {class name, function symbol}
254
262
// / pairs indicating that if `this` is of the given class, then the call will
255
263
// / target the given function. Thus if A <: B <: C and A and C provide
@@ -260,7 +268,8 @@ void remove_virtual_functionst::get_child_functions_rec(
260
268
const symbol_exprt &last_method_defn,
261
269
const irep_idt &component_name,
262
270
dispatch_table_entriest &functions,
263
- std::set<irep_idt> &visited) const
271
+ std::set<irep_idt> &visited,
272
+ const function_call_resolvert &resolve_function_call) const
264
273
{
265
274
auto findit=class_hierarchy.class_map .find (this_id);
266
275
if (findit==class_hierarchy.class_map .end ())
@@ -281,14 +290,30 @@ void remove_virtual_functionst::get_child_functions_rec(
281
290
{
282
291
function.symbol_expr =last_method_defn;
283
292
}
293
+ if (function.symbol_expr == symbol_exprt ())
294
+ {
295
+ const resolve_concrete_function_callt::concrete_function_callt
296
+ &resolved_call = resolve_function_call (child, component_name);
297
+ if (resolved_call.is_valid ())
298
+ {
299
+ function.class_id = resolved_call.get_class_identifier ();
300
+ const symbolt &called_symbol =
301
+ symbol_table.lookup_ref (resolved_call.get_virtual_method_name ());
302
+
303
+ function.symbol_expr = called_symbol.symbol_expr ();
304
+ function.symbol_expr .set (
305
+ ID_C_class, resolved_call.get_class_identifier ());
306
+ }
307
+ }
284
308
functions.push_back (function);
285
309
286
310
get_child_functions_rec (
287
311
child,
288
312
function.symbol_expr ,
289
313
component_name,
290
314
functions,
291
- visited);
315
+ visited,
316
+ resolve_function_call);
292
317
}
293
318
}
294
319
@@ -297,21 +322,30 @@ void remove_virtual_functionst::get_functions(
297
322
dispatch_table_entriest &functions)
298
323
{
299
324
const irep_idt class_id=function.get (ID_C_class);
325
+ const std::string class_id_string (id2string (class_id));
300
326
const irep_idt component_name=function.get (ID_component_name);
327
+ const std::string component_name_string (id2string (component_name));
301
328
INVARIANT (!class_id.empty (), " All virtual functions must have a class" );
302
329
303
330
resolve_concrete_function_callt get_virtual_call_target (
304
331
symbol_table, class_hierarchy);
305
- const resolve_concrete_function_callt::concrete_function_callt &
306
- resolved_call=get_virtual_call_target (class_id, component_name);
332
+ const function_call_resolvert resolve_function_call =
333
+ [&get_virtual_call_target](
334
+ const irep_idt &class_id, const irep_idt &component_name) {
335
+ return get_virtual_call_target (class_id, component_name);
336
+ };
337
+
338
+ const resolve_concrete_function_callt::concrete_function_callt
339
+ &resolved_call = get_virtual_call_target (class_id, component_name);
340
+
307
341
dispatch_table_entryt root_function;
308
342
309
343
if (resolved_call.is_valid ())
310
344
{
311
345
root_function.class_id =resolved_call.get_class_identifier ();
312
346
313
- const symbolt &called_symbol=
314
- * symbol_table.lookup (resolved_call.get_virtual_method_name ());
347
+ const symbolt &called_symbol =
348
+ symbol_table.lookup_ref (resolved_call.get_virtual_method_name ());
315
349
316
350
root_function.symbol_expr =called_symbol.symbol_expr ();
317
351
root_function.symbol_expr .set (
@@ -330,7 +364,8 @@ void remove_virtual_functionst::get_functions(
330
364
root_function.symbol_expr ,
331
365
component_name,
332
366
functions,
333
- visited);
367
+ visited,
368
+ resolve_function_call);
334
369
335
370
if (root_function.symbol_expr !=symbol_exprt ())
336
371
functions.push_back (root_function);
0 commit comments