@@ -54,6 +54,15 @@ class lazy_goto_functions_mapt final
54
54
goto_functionst::goto_functiont &function,
55
55
journalling_symbol_tablet &function_symbols)>
56
56
post_process_functiont;
57
+ typedef std::function<bool (const irep_idt &name)>
58
+ can_generate_function_bodyt;
59
+ typedef std::function<
60
+ bool (
61
+ const irep_idt &function_name,
62
+ symbol_table_baset &symbol_table,
63
+ goto_functiont &function,
64
+ bool body_available)>
65
+ generate_function_bodyt;
57
66
58
67
private:
59
68
typedef std::map<key_type, goto_functiont> underlying_mapt;
@@ -66,6 +75,8 @@ class lazy_goto_functions_mapt final
66
75
language_filest &language_files;
67
76
symbol_tablet &symbol_table;
68
77
const post_process_functiont post_process_function;
78
+ const can_generate_function_bodyt driver_program_can_generate_function_body;
79
+ const generate_function_bodyt driver_program_generate_function_body;
69
80
message_handlert &message_handler;
70
81
71
82
public:
@@ -75,11 +86,17 @@ class lazy_goto_functions_mapt final
75
86
language_filest &language_files,
76
87
symbol_tablet &symbol_table,
77
88
post_process_functiont post_process_function,
89
+ can_generate_function_bodyt driver_program_can_generate_function_body,
90
+ generate_function_bodyt driver_program_generate_function_body,
78
91
message_handlert &message_handler)
79
92
: goto_functions(goto_functions),
80
93
language_files (language_files),
81
94
symbol_table(symbol_table),
82
- post_process_function(std::move(post_process_function)),
95
+ post_process_function(post_process_function),
96
+ driver_program_can_generate_function_body(
97
+ driver_program_can_generate_function_body),
98
+ driver_program_generate_function_body(
99
+ driver_program_generate_function_body),
83
100
message_handler(message_handler)
84
101
{
85
102
}
@@ -107,7 +124,9 @@ class lazy_goto_functions_mapt final
107
124
// / it a bodyless stub.
108
125
bool can_produce_function (const key_type &name) const
109
126
{
110
- return language_files.can_convert_lazy_method (name);
127
+ return
128
+ language_files.can_convert_lazy_method (name) ||
129
+ driver_program_can_generate_function_body (name);
111
130
}
112
131
113
132
void unload (const key_type &name) const { goto_functions.erase (name); }
@@ -153,14 +172,30 @@ class lazy_goto_functions_mapt final
153
172
underlying_mapt::iterator it=goto_functions.find (name);
154
173
if (it!=goto_functions.end ())
155
174
return *it;
156
- // Fill in symbol table entry body if not already done
157
- // If this returns false then it's a stub
158
- language_files.convert_lazy_method (name, function_symbol_table);
159
- // Create goto_functiont
160
- goto_functionst::goto_functiont function;
161
- goto_convert_functionst convert_functions (
162
- function_symbol_table, message_handler);
163
- convert_functions.convert_function (name, function);
175
+
176
+ goto_functiont function;
177
+
178
+ // First chance: see if the driver program wants to provide a replacement:
179
+ bool body_provided =
180
+ driver_program_generate_function_body (
181
+ name,
182
+ function_symbol_table,
183
+ function,
184
+ language_files.can_convert_lazy_method (name));
185
+
186
+ // Second chance: see if language_filest can provide a body:
187
+ if (!body_provided)
188
+ {
189
+ // Fill in symbol table entry body if not already done
190
+ language_files.convert_lazy_method (name, function_symbol_table);
191
+ body_provided = function_symbol_table.lookup_ref (name).value .is_not_nil ();
192
+
193
+ // Create goto_functiont
194
+ goto_convert_functionst convert_functions (
195
+ function_symbol_table, message_handler);
196
+ convert_functions.convert_function (name, function);
197
+ }
198
+
164
199
// Add to map
165
200
return *goto_functions.emplace (name, std::move (function)).first ;
166
201
}
0 commit comments