-
Notifications
You must be signed in to change notification settings - Fork 273
/
Copy pathparameter_assignments.cpp
105 lines (81 loc) · 2.62 KB
/
parameter_assignments.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
/*******************************************************************\
Module: Add parameter assignments
Author: Daniel Kroening
Date: September 2015
\*******************************************************************/
/// \file
/// Add parameter assignments
#include "parameter_assignments.h"
#include <util/std_expr.h>
#include "goto_model.h"
class parameter_assignmentst
{
public:
explicit parameter_assignmentst(symbol_table_baset &_symbol_table)
: symbol_table(_symbol_table)
{
}
void operator()(
goto_functionst &goto_functions);
protected:
symbol_table_baset &symbol_table;
void do_function_calls(
goto_programt &goto_program);
};
/// turns x=f(...) into f(...); lhs=f#return_value;
void parameter_assignmentst::do_function_calls(
goto_programt &goto_program)
{
Forall_goto_program_instructions(i_it, goto_program)
{
if(i_it->is_function_call())
{
// add x=y for f(y) where x is the parameter
PRECONDITION(as_const(*i_it).call_function().id() == ID_symbol);
const irep_idt &identifier =
to_symbol_expr(as_const(*i_it).call_function()).get_identifier();
// see if we have it
const namespacet ns(symbol_table);
const symbolt &function_symbol=ns.lookup(identifier);
const code_typet &code_type=to_code_type(function_symbol.type);
goto_programt tmp;
for(std::size_t nr=0; nr<code_type.parameters().size(); nr++)
{
irep_idt p_identifier=code_type.parameters()[nr].get_identifier();
if(p_identifier.empty())
continue;
if(nr < as_const(*i_it).call_arguments().size())
{
const symbolt &lhs_symbol=ns.lookup(p_identifier);
symbol_exprt lhs=lhs_symbol.symbol_expr();
exprt rhs = typecast_exprt::conditional_cast(
as_const(*i_it).call_arguments()[nr], lhs.type());
tmp.add(goto_programt::make_assignment(
code_assignt(lhs, rhs), i_it->source_location()));
}
}
std::size_t count=tmp.instructions.size();
goto_program.insert_before_swap(i_it, tmp);
for(; count!=0; count--) i_it++;
}
}
}
void parameter_assignmentst::operator()(goto_functionst &goto_functions)
{
for(auto &gf_entry : goto_functions.function_map)
do_function_calls(gf_entry.second.body);
}
/// removes returns
void parameter_assignments(
symbol_table_baset &symbol_table,
goto_functionst &goto_functions)
{
parameter_assignmentst rr(symbol_table);
rr(goto_functions);
}
/// removes returns
void parameter_assignments(goto_modelt &goto_model)
{
parameter_assignmentst rr(goto_model.symbol_table);
rr(goto_model.goto_functions);
}