@@ -76,13 +76,6 @@ class remove_virtual_functionst
76
76
const irep_idt &function_id,
77
77
goto_programt &goto_program);
78
78
79
- goto_programt::targett remove_virtual_function (
80
- const irep_idt &function_id,
81
- goto_programt &goto_program,
82
- goto_programt::targett target,
83
- const dispatch_table_entriest &functions,
84
- virtual_dispatch_fallback_actiont fallback_action);
85
-
86
79
private:
87
80
const class_hierarchyt &class_hierarchy;
88
81
symbol_table_baset &symbol_table;
@@ -94,42 +87,6 @@ class remove_virtual_functionst
94
87
goto_programt::targett target);
95
88
};
96
89
97
- // / Replace specified virtual function call with a static call to its
98
- // / most derived implementation
99
- // / \param function_id: The identifier of the function we are currently
100
- // / analysing
101
- // / \param [in,out] goto_program: GOTO program to modify
102
- // / \param target: iterator to a function in the supplied GOTO program
103
- // / to replace. Must point to a virtual function call.
104
- // / \return Returns a pointer to the statement in the supplied GOTO
105
- // / program after replaced function call
106
- goto_programt::targett remove_virtual_functionst::remove_virtual_function (
107
- const irep_idt &function_id,
108
- goto_programt &goto_program,
109
- goto_programt::targett target)
110
- {
111
- const code_function_callt &code = target->get_function_call ();
112
-
113
- const exprt &function=code.function ();
114
- INVARIANT (
115
- function.id ()==ID_virtual_function,
116
- " remove_virtual_function must take a virtual function call instruction" );
117
- INVARIANT (
118
- !code.arguments ().empty (),
119
- " virtual function calls must have at least a this-argument" );
120
-
121
- get_virtual_calleest get_callees (symbol_table, class_hierarchy);
122
- dispatch_table_entriest functions;
123
- get_callees.get_functions (function, functions);
124
-
125
- return remove_virtual_function (
126
- function_id,
127
- goto_program,
128
- target,
129
- functions,
130
- virtual_dispatch_fallback_actiont::CALL_LAST_FUNCTION);
131
- }
132
-
133
90
// / Create a concrete function call to replace a virtual one
134
91
// / \param [in,out] call: the function call to update
135
92
// / \param function_symbol: the function to be called
@@ -285,6 +242,7 @@ static void process_this_argument(
285
242
// / implementation. If there's a type mismatch between implementation
286
243
// / and the instance type or if fallback_action is set to
287
244
// / ASSUME_FALSE, then function is substituted with a call to ASSUME(false)
245
+ // / \param symbol_table: Symbol table associated with \p goto_program
288
246
// / \param function_id: The identifier of the function we are currently
289
247
// / analysing
290
248
// / \param [in,out] goto_program: GOTO program to modify
@@ -297,7 +255,8 @@ static void process_this_argument(
297
255
// / with the most derived matching call
298
256
// / \return Returns a pointer to the statement in the supplied GOTO
299
257
// / program after replaced function call
300
- goto_programt::targett remove_virtual_functionst::remove_virtual_function (
258
+ static goto_programt::targett replace_virtual_function_with_dispatch_table (
259
+ symbol_table_baset &symbol_table,
301
260
const irep_idt &function_id,
302
261
goto_programt &goto_program,
303
262
goto_programt::targett target,
@@ -308,6 +267,7 @@ goto_programt::targett remove_virtual_functionst::remove_virtual_function(
308
267
target->is_function_call (),
309
268
" remove_virtual_function must target a FUNCTION_CALL instruction" );
310
269
270
+ namespacet ns (symbol_table);
311
271
goto_programt::targett next_target = std::next (target);
312
272
313
273
if (functions.empty ())
@@ -499,6 +459,43 @@ goto_programt::targett remove_virtual_functionst::remove_virtual_function(
499
459
return next_target;
500
460
}
501
461
462
+ // / Replace specified virtual function call with a static call to its
463
+ // / most derived implementation
464
+ // / \param function_id: The identifier of the function we are currently
465
+ // / analysing
466
+ // / \param [in,out] goto_program: GOTO program to modify
467
+ // / \param target: iterator to a function in the supplied GOTO program
468
+ // / to replace. Must point to a virtual function call.
469
+ // / \return Returns a pointer to the statement in the supplied GOTO
470
+ // / program after replaced function call
471
+ goto_programt::targett remove_virtual_functionst::remove_virtual_function (
472
+ const irep_idt &function_id,
473
+ goto_programt &goto_program,
474
+ goto_programt::targett target)
475
+ {
476
+ const code_function_callt &code = target->get_function_call ();
477
+
478
+ const exprt &function = code.function ();
479
+ INVARIANT (
480
+ function.id () == ID_virtual_function,
481
+ " remove_virtual_function must take a virtual function call instruction" );
482
+ INVARIANT (
483
+ !code.arguments ().empty (),
484
+ " virtual function calls must have at least a this-argument" );
485
+
486
+ get_virtual_calleest get_callees (symbol_table, class_hierarchy);
487
+ dispatch_table_entriest functions;
488
+ get_callees.get_functions (function, functions);
489
+
490
+ return replace_virtual_function_with_dispatch_table (
491
+ symbol_table,
492
+ function_id,
493
+ goto_program,
494
+ target,
495
+ functions,
496
+ virtual_dispatch_fallback_actiont::CALL_LAST_FUNCTION);
497
+ }
498
+
502
499
// / Used by get_functions to track the most-derived parent that provides an
503
500
// / override of a given function.
504
501
// / \param this_id: class name
@@ -740,6 +737,8 @@ void remove_virtual_functionst::operator()(goto_functionst &functions)
740
737
741
738
// / Remove virtual function calls from all functions in the specified
742
739
// / list and replace them with their most derived implementations
740
+ // / \param symbol_table: symbol table associated with \p goto_functions
741
+ // / \param goto_functions: functions from which to remove virtual function calls
743
742
void remove_virtual_functions (
744
743
symbol_table_baset &symbol_table,
745
744
goto_functionst &goto_functions)
@@ -750,14 +749,47 @@ void remove_virtual_functions(
750
749
rvf (goto_functions);
751
750
}
752
751
752
+ // / Remove virtual function calls from all functions in the specified
753
+ // / list and replace them with their most derived implementations
754
+ // / \param symbol_table: symbol table associated with \p goto_functions
755
+ // / \param goto_functions: functions from which to remove virtual function calls
756
+ // / \param class_hierarchy: class hierarchy derived from symbol_table
757
+ // / This should already be populated (i.e. class_hierarchyt::operator() has
758
+ // / already been called)
759
+ void remove_virtual_functions (
760
+ symbol_table_baset &symbol_table,
761
+ goto_functionst &goto_functions,
762
+ const class_hierarchyt &class_hierarchy)
763
+ {
764
+ remove_virtual_functionst rvf (symbol_table, class_hierarchy);
765
+ rvf (goto_functions);
766
+ }
767
+
753
768
// / Remove virtual function calls from the specified model
769
+ // / \param goto_model: model from which to remove virtual functions
754
770
void remove_virtual_functions (goto_modelt &goto_model)
755
771
{
756
772
remove_virtual_functions (
757
773
goto_model.symbol_table , goto_model.goto_functions );
758
774
}
759
775
776
+ // / Remove virtual function calls from the specified model
777
+ // / \param goto_model: model from which to remove virtual functions
778
+ // / \param class_hierarchy: class hierarchy derived from model.symbol_table
779
+ // / This should already be populated (i.e. class_hierarchyt::operator() has
780
+ // / already been called)
781
+ void remove_virtual_functions (
782
+ goto_modelt &goto_model,
783
+ const class_hierarchyt &class_hierarchy)
784
+ {
785
+ remove_virtual_functions (
786
+ goto_model.symbol_table , goto_model.goto_functions , class_hierarchy);
787
+ }
788
+
760
789
// / Remove virtual function calls from the specified model function
790
+ // / May change the location numbers in `function`.
791
+ // / \param function: function from which virtual functions should be converted
792
+ // / to explicit dispatch tables.
761
793
void remove_virtual_functions (goto_model_functiont &function)
762
794
{
763
795
class_hierarchyt class_hierarchy;
@@ -767,6 +799,22 @@ void remove_virtual_functions(goto_model_functiont &function)
767
799
function.get_function_id (), function.get_goto_function ().body );
768
800
}
769
801
802
+ // / Remove virtual function calls from the specified model function
803
+ // / May change the location numbers in `function`.
804
+ // / \param function: function from which virtual functions should be converted
805
+ // / to explicit dispatch tables.
806
+ // / \param class_hierarchy: class hierarchy derived from function.symbol_table
807
+ // / This should already be populated (i.e. class_hierarchyt::operator() has
808
+ // / already been called)
809
+ void remove_virtual_functions (
810
+ goto_model_functiont &function,
811
+ const class_hierarchyt &class_hierarchy)
812
+ {
813
+ remove_virtual_functionst rvf (function.get_symbol_table (), class_hierarchy);
814
+ rvf.remove_virtual_functions (
815
+ function.get_function_id (), function.get_goto_function ().body );
816
+ }
817
+
770
818
// / Replace virtual function call with a static function call
771
819
// / Achieved by substituting a virtual function with its most derived
772
820
// / implementation. If there's a type mismatch between implementation
@@ -793,12 +841,13 @@ goto_programt::targett remove_virtual_function(
793
841
const dispatch_table_entriest &dispatch_table,
794
842
virtual_dispatch_fallback_actiont fallback_action)
795
843
{
796
- class_hierarchyt class_hierarchy;
797
- class_hierarchy (symbol_table);
798
- remove_virtual_functionst rvf (symbol_table, class_hierarchy);
799
-
800
- goto_programt::targett next = rvf.remove_virtual_function (
801
- function_id, goto_program, instruction, dispatch_table, fallback_action);
844
+ goto_programt::targett next = replace_virtual_function_with_dispatch_table (
845
+ symbol_table,
846
+ function_id,
847
+ goto_program,
848
+ instruction,
849
+ dispatch_table,
850
+ fallback_action);
802
851
803
852
goto_program.update ();
804
853
0 commit comments