34
34
// / Generate an entry point that calls a function with the given name, based on
35
35
// / the functions language mode in the symbol table
36
36
static bool generate_entry_point_for_function (
37
- const irep_idt &entry_function_name,
38
37
const optionst &options,
39
- goto_modelt &goto_model ,
38
+ symbol_tablet &symbol_table ,
40
39
message_handlert &message_handler)
41
40
{
42
- auto const entry_function_sym =
43
- goto_model.symbol_table .lookup (entry_function_name);
41
+ const irep_idt &entry_function_name = options.get_option (" function" );
42
+ CHECK_RETURN (!entry_function_name.empty ());
43
+ auto const entry_function_sym = symbol_table.lookup (entry_function_name);
44
44
if (entry_function_sym == nullptr )
45
45
{
46
46
throw invalid_command_line_argument_exceptiont{
@@ -54,42 +54,23 @@ static bool generate_entry_point_for_function(
54
54
CHECK_RETURN (entry_language != nullptr );
55
55
entry_language->set_message_handler (message_handler);
56
56
entry_language->set_language_options (options);
57
- return entry_language->generate_support_functions (goto_model. symbol_table );
57
+ return entry_language->generate_support_functions (symbol_table);
58
58
}
59
59
60
- goto_modelt initialize_goto_model (
61
- const std::vector<std::string> &files,
62
- message_handlert &message_handler,
63
- const optionst &options)
60
+ void initialize_from_source_files (
61
+ const std::list<std::string> &sources,
62
+ const optionst &options,
63
+ language_filest &language_files,
64
+ symbol_tablet &symbol_table,
65
+ message_handlert &message_handler)
64
66
{
65
- messaget msg (message_handler);
66
- if (files.empty ())
67
- {
68
- throw invalid_command_line_argument_exceptiont (
69
- " missing program argument" ,
70
- " filename" ,
71
- " one or more paths to program files" );
72
- }
73
-
74
- std::list<std::string> binaries, sources;
75
-
76
- for (const auto &file : files)
77
- {
78
- if (is_goto_binary (file, message_handler))
79
- binaries.push_back (file);
80
- else
81
- sources.push_back (file);
82
- }
67
+ if (sources.empty ())
68
+ return ;
83
69
84
- language_filest language_files;
85
- language_files.set_message_handler (message_handler);
86
-
87
- goto_modelt goto_model;
70
+ messaget msg (message_handler);
88
71
89
- if (! sources. empty () )
72
+ for ( const auto &filename : sources)
90
73
{
91
- for (const auto &filename : sources)
92
- {
93
74
#ifdef _MSC_VER
94
75
std::ifstream infile (widen (filename));
95
76
#else
@@ -107,8 +88,8 @@ goto_modelt initialize_goto_model(
107
88
108
89
if (lf.language ==nullptr )
109
90
{
110
- throw invalid_source_file_exceptiont (
111
- " Failed to figure out type of file ' " + filename + ' \' ' ) ;
91
+ throw invalid_command_line_argument_exceptiont{
92
+ " Failed to figure out type of file" , filename} ;
112
93
}
113
94
114
95
languaget &language=*lf.language ;
@@ -119,75 +100,127 @@ goto_modelt initialize_goto_model(
119
100
120
101
if (language.parse (infile, filename))
121
102
{
122
- throw invalid_source_file_exceptiont (" PARSING ERROR" );
103
+ throw invalid_input_exceptiont (" PARSING ERROR" );
123
104
}
124
105
125
106
lf.get_modules ();
126
107
}
127
108
128
109
msg.status () << " Converting" << messaget::eom;
129
110
130
- if (language_files.typecheck (goto_model. symbol_table ))
111
+ if (language_files.typecheck (symbol_table))
131
112
{
132
- throw invalid_source_file_exceptiont (" CONVERSION ERROR" );
113
+ throw invalid_input_exceptiont (" CONVERSION ERROR" );
133
114
}
134
- }
135
-
136
- if (read_objects_and_link (binaries, goto_model, message_handler))
137
- {
138
- throw invalid_source_file_exceptiont{
139
- " failed to read object or link in files" };
140
- }
115
+ }
141
116
142
- bool binaries_provided_start=
143
- goto_model.symbol_table .has_symbol (goto_functionst::entry_point ());
117
+ void set_up_custom_entry_point (
118
+ language_filest &language_files,
119
+ symbol_tablet &symbol_table,
120
+ const std::function<void (const irep_idt &)> &unload,
121
+ const optionst &options,
122
+ bool try_mode_lookup,
123
+ message_handlert &message_handler)
124
+ {
125
+ bool binaries_provided_start =
126
+ symbol_table.has_symbol (goto_functionst::entry_point ());
144
127
145
128
bool entry_point_generation_failed=false ;
146
129
147
130
if (binaries_provided_start && options.is_set (" function" ))
148
131
{
132
+ // The goto binaries provided already contain a __CPROVER_start
133
+ // function that may be tied to a different entry point `function`.
134
+ // Hence, we will rebuild the __CPROVER_start function.
135
+
149
136
// Get the language annotation of the existing __CPROVER_start function.
150
- std::unique_ptr<languaget> language = get_entry_point_language (
151
- goto_model. symbol_table , options, message_handler);
137
+ std::unique_ptr<languaget> language =
138
+ get_entry_point_language ( symbol_table, options, message_handler);
152
139
153
140
// To create a new entry point we must first remove the old one
154
- remove_existing_entry_point (goto_model. symbol_table );
141
+ remove_existing_entry_point (symbol_table);
155
142
156
143
// Create the new entry-point
157
144
entry_point_generation_failed =
158
- language->generate_support_functions (goto_model. symbol_table );
145
+ language->generate_support_functions (symbol_table);
159
146
160
147
// Remove the function from the goto functions so it is copied back in
161
148
// from the symbol table during goto_convert
162
149
if (!entry_point_generation_failed)
163
- goto_model. unload (goto_functionst::entry_point ());
150
+ unload (goto_functionst::entry_point ());
164
151
}
165
152
else if (!binaries_provided_start)
166
153
{
167
- if (options.is_set (" function" ))
154
+ if (try_mode_lookup && options.is_set (" function" ))
168
155
{
169
156
// no entry point is present; Use the mode of the specified entry function
170
157
// to generate one
171
158
entry_point_generation_failed = generate_entry_point_for_function (
172
- options. get_option ( " function " ), options, goto_model , message_handler);
159
+ options, symbol_table , message_handler);
173
160
}
174
- if (entry_point_generation_failed || !options.is_set (" function" ))
161
+ if (
162
+ !try_mode_lookup || entry_point_generation_failed ||
163
+ !options.is_set (" function" ))
175
164
{
176
165
// Allow all language front-ends to try to provide the user-specified
177
166
// (--function) entry-point, or some language-specific default:
178
167
entry_point_generation_failed =
179
- language_files.generate_support_functions (goto_model. symbol_table );
168
+ language_files.generate_support_functions (symbol_table);
180
169
}
181
170
}
182
171
183
172
if (entry_point_generation_failed)
184
173
{
185
- throw invalid_source_file_exceptiont (" SUPPORT FUNCTION GENERATION ERROR" );
174
+ throw invalid_input_exceptiont (" SUPPORT FUNCTION GENERATION ERROR" );
175
+ }
176
+ }
177
+
178
+ goto_modelt initialize_goto_model (
179
+ const std::vector<std::string> &files,
180
+ message_handlert &message_handler,
181
+ const optionst &options)
182
+ {
183
+ messaget msg (message_handler);
184
+ if (files.empty ())
185
+ {
186
+ throw invalid_command_line_argument_exceptiont (
187
+ " missing program argument" ,
188
+ " filename" ,
189
+ " one or more paths to program files" );
190
+ }
191
+
192
+ std::list<std::string> binaries, sources;
193
+
194
+ for (const auto &file : files)
195
+ {
196
+ if (is_goto_binary (file, message_handler))
197
+ binaries.push_back (file);
198
+ else
199
+ sources.push_back (file);
186
200
}
187
201
202
+ language_filest language_files;
203
+ language_files.set_message_handler (message_handler);
204
+
205
+ goto_modelt goto_model;
206
+
207
+ initialize_from_source_files (
208
+ sources, options, language_files, goto_model.symbol_table , message_handler);
209
+
210
+ if (read_objects_and_link (binaries, goto_model, message_handler))
211
+ throw incorrect_goto_program_exceptiont{" failed to read/link goto model" };
212
+
213
+ set_up_custom_entry_point (
214
+ language_files,
215
+ goto_model.symbol_table ,
216
+ [&goto_model](const irep_idt &id) { goto_model.goto_functions .unload (id); },
217
+ options,
218
+ true ,
219
+ message_handler);
220
+
188
221
if (language_files.final (goto_model.symbol_table ))
189
222
{
190
- throw invalid_source_file_exceptiont (" FINAL STAGE CONVERSION ERROR" );
223
+ throw invalid_input_exceptiont (" FINAL STAGE CONVERSION ERROR" );
191
224
}
192
225
193
226
msg.status () << " Generating GOTO Program" << messaget::eom;
0 commit comments