@@ -198,7 +198,12 @@ void unreachable_instructions(
198198 const goto_programt &goto_program=f_it->second .body ;
199199 dead_mapt dead_map;
200200
201- if (called.find (f_it->first )!=called.end ())
201+ const symbolt &decl=ns.lookup (f_it->first );
202+
203+ // f_it->first may be a link-time renamed version, use the
204+ // base_name instead; do not list inlined functions
205+ if (called.find (decl.base_name )!=called.end () ||
206+ f_it->second .is_inlined ())
202207 unreachable_instructions (goto_program, dead_map);
203208 else
204209 all_unreachable (goto_program, dead_map);
@@ -215,3 +220,150 @@ void unreachable_instructions(
215220 if (json && !json_result.array .empty ())
216221 os << json_result << std::endl;
217222}
223+
224+ /* ******************************************************************\
225+
226+ Function: json_output_function
227+
228+ Inputs:
229+
230+ Outputs:
231+
232+ Purpose:
233+
234+ \*******************************************************************/
235+
236+ static void json_output_function (
237+ const irep_idt &function,
238+ const source_locationt &first_location,
239+ const source_locationt &last_location,
240+ json_arrayt &dest)
241+ {
242+ json_objectt &entry=dest.push_back ().make_object ();
243+
244+ entry[" function" ]=json_stringt (id2string (function));
245+ entry[" file name" ]=
246+ json_stringt (concat_dir_file (
247+ id2string (first_location.get_working_directory ()),
248+ id2string (first_location.get_file ())));
249+ entry[" first line" ]=
250+ json_numbert (id2string (first_location.get_line ()));
251+ entry[" last line" ]=
252+ json_numbert (id2string (last_location.get_line ()));
253+ }
254+
255+ /* ******************************************************************\
256+
257+ Function: list_functions
258+
259+ Inputs:
260+
261+ Outputs:
262+
263+ Purpose:
264+
265+ \*******************************************************************/
266+
267+ static void list_functions (
268+ const goto_modelt &goto_model,
269+ const bool json,
270+ std::ostream &os,
271+ bool unreachable)
272+ {
273+ json_arrayt json_result;
274+
275+ std::set<irep_idt> called;
276+ compute_called_functions (goto_model, called);
277+
278+ const namespacet ns (goto_model.symbol_table );
279+
280+ forall_goto_functions (f_it, goto_model.goto_functions )
281+ {
282+ const symbolt &decl=ns.lookup (f_it->first );
283+
284+ // f_it->first may be a link-time renamed version, use the
285+ // base_name instead; do not list inlined functions
286+ if (unreachable ==
287+ (called.find (decl.base_name )!=called.end () ||
288+ f_it->second .is_inlined ()))
289+ continue ;
290+
291+ source_locationt first_location=decl.location ;
292+
293+ source_locationt last_location;
294+ if (f_it->second .body_available ())
295+ {
296+ const goto_programt &goto_program=f_it->second .body ;
297+
298+ goto_programt::const_targett end_function=
299+ goto_program.instructions .end ();
300+ --end_function;
301+ assert (end_function->is_end_function ());
302+ last_location=end_function->source_location ;
303+ }
304+ else
305+ // completely ignore functions without a body, both for
306+ // reachable and unreachable functions; we could also restrict
307+ // this to macros/asm renaming
308+ continue ;
309+
310+ if (!json)
311+ {
312+ os << concat_dir_file (
313+ id2string (first_location.get_working_directory ()),
314+ id2string (first_location.get_file ())) << " "
315+ << decl.base_name << " "
316+ << first_location.get_line () << " "
317+ << last_location.get_line () << " \n " ;
318+ }
319+ else
320+ json_output_function (
321+ decl.base_name ,
322+ first_location,
323+ last_location,
324+ json_result);
325+ }
326+
327+ if (json && !json_result.array .empty ())
328+ os << json_result << std::endl;
329+ }
330+
331+ /* ******************************************************************\
332+
333+ Function: unreachable_functions
334+
335+ Inputs:
336+
337+ Outputs:
338+
339+ Purpose:
340+
341+ \*******************************************************************/
342+
343+ void unreachable_functions (
344+ const goto_modelt &goto_model,
345+ const bool json,
346+ std::ostream &os)
347+ {
348+ list_functions (goto_model, json, os, true );
349+ }
350+
351+ /* ******************************************************************\
352+
353+ Function: reachable_functions
354+
355+ Inputs:
356+
357+ Outputs:
358+
359+ Purpose:
360+
361+ \*******************************************************************/
362+
363+ void reachable_functions (
364+ const goto_modelt &goto_model,
365+ const bool json,
366+ std::ostream &os)
367+ {
368+ list_functions (goto_model, json, os, false );
369+ }
0 commit comments