@@ -54,6 +54,15 @@ class lazy_goto_functions_mapt final
5454 goto_functionst::goto_functiont &function,
5555 journalling_symbol_tablet &function_symbols)>
5656 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;
5766
5867private:
5968 typedef std::map<key_type, goto_functiont> underlying_mapt;
@@ -66,6 +75,8 @@ class lazy_goto_functions_mapt final
6675 language_filest &language_files;
6776 symbol_tablet &symbol_table;
6877 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;
6980 message_handlert &message_handler;
7081
7182public:
@@ -75,11 +86,17 @@ class lazy_goto_functions_mapt final
7586 language_filest &language_files,
7687 symbol_tablet &symbol_table,
7788 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,
7891 message_handlert &message_handler)
7992 : goto_functions(goto_functions),
8093 language_files (language_files),
8194 symbol_table(symbol_table),
8295 post_process_function(std::move(post_process_function)),
96+ driver_program_can_generate_function_body(
97+ std::move (driver_program_can_generate_function_body)),
98+ driver_program_generate_function_body(
99+ std::move (driver_program_generate_function_body)),
83100 message_handler(message_handler)
84101 {
85102 }
@@ -107,7 +124,9 @@ class lazy_goto_functions_mapt final
107124 // / it a bodyless stub.
108125 bool can_produce_function (const key_type &name) const
109126 {
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);
111130 }
112131
113132 void unload (const key_type &name) const { goto_functions.erase (name); }
@@ -153,14 +172,30 @@ class lazy_goto_functions_mapt final
153172 underlying_mapt::iterator it=goto_functions.find (name);
154173 if (it!=goto_functions.end ())
155174 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+
164199 // Add to map
165200 return *goto_functions.emplace (name, std::move (function)).first ;
166201 }
0 commit comments