-
Notifications
You must be signed in to change notification settings - Fork 287
Expand file tree
/
Copy pathremove_function.cpp
More file actions
137 lines (114 loc) · 4.08 KB
/
remove_function.cpp
File metadata and controls
137 lines (114 loc) · 4.08 KB
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
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
/*******************************************************************\
Module: Remove function definition
Author: Michael Tautschnig
Date: April 2017
\*******************************************************************/
/// \file
/// Remove function definition
#include "remove_function.h"
#include <util/message.h>
#include <goto-programs/goto_model.h>
#include <regex>
/// Remove the body of function "identifier" such that an analysis will treat it
/// as a side-effect free function with non-deterministic return value.
/// \par parameters: symbol_table Input symbol table to be modified
/// goto_model Input program to be modified
/// identifier Function to be removed
/// message_handler Error/status output
void remove_function(
goto_modelt &goto_model,
const irep_idt &identifier,
message_handlert &message_handler)
{
messaget message(message_handler);
goto_functionst::function_mapt::iterator entry=
goto_model.goto_functions.function_map.find(identifier);
if(entry==goto_model.goto_functions.function_map.end())
{
message.error() << "No function " << identifier
<< " in goto program" << messaget::eom;
return;
}
else if(to_code_type(goto_model.symbol_table.lookup_ref(identifier).type)
.get_inlined())
{
message.warning() << "Function " << identifier << " is inlined, "
<< "instantiations will not be removed"
<< messaget::eom;
}
if(entry->second.body_available())
{
message.status() << "Removing body of " << identifier
<< messaget::eom;
entry->second.clear();
symbolt &symbol = goto_model.symbol_table.get_writeable_ref(identifier);
symbol.value.make_nil();
symbol.is_file_local = false;
}
}
/// Remove the body of all functions listed in "names" such that an analysis
/// will treat it as a side-effect free function with non-deterministic return
/// value.
/// \par parameters: symbol_table Input symbol table to be modified
/// goto_model Input program to be modified
/// names List of functions to be removed
/// message_handler Error/status output
void remove_functions(
goto_modelt &goto_model,
const std::list<std::string> &names,
message_handlert &message_handler)
{
for(const auto &f : names)
remove_function(goto_model, f, message_handler);
}
/// Remove functions matching a regular expression pattern
/// \param goto_model: The goto model to modify
/// \param pattern: The regex pattern to match function names against
/// \param pattern_as_str: The string representation of \p pattern
/// \param message_handler: For status/warning/error messages
static void remove_functions_regex(
goto_modelt &goto_model,
const std::regex &pattern,
const std::string &pattern_as_str,
message_handlert &message_handler)
{
messaget message{message_handler};
message.debug() << "Removing functions matching pattern: " << pattern_as_str
<< messaget::eom;
// Collect matching function names first to avoid modifying the map while
// iterating
std::list<irep_idt> matching_functions;
for(const auto &entry : goto_model.goto_functions.function_map)
{
const std::string &function_name = id2string(entry.first);
if(std::regex_match(function_name, pattern))
{
matching_functions.push_back(entry.first);
}
}
// Now remove all matching functions
for(const auto &func : matching_functions)
{
remove_function(goto_model, func, message_handler);
}
message.debug() << "Removed " << matching_functions.size()
<< " function(s) matching pattern: " << pattern_as_str
<< messaget::eom;
}
void remove_functions_regex(
goto_modelt &goto_model,
const std::string &pattern,
message_handlert &message_handler)
{
messaget message{message_handler};
try
{
std::regex regex_pattern{pattern};
remove_functions_regex(goto_model, regex_pattern, pattern, message_handler);
}
catch(const std::regex_error &e)
{
message.error() << "Invalid regular expression pattern: " << pattern << " ("
<< e.what() << ")" << messaget::eom;
}
}