@@ -41,8 +41,10 @@ call_grapht::call_grapht(
41
41
{
42
42
forall_goto_functions (f_it, goto_functions)
43
43
{
44
- const goto_programt &body=f_it->second .body ;
45
- add (f_it->first , body);
44
+ const irep_idt &function_name = f_it->first ;
45
+ const goto_programt &body = f_it->second .body ;
46
+ nodes.insert (function_name);
47
+ add (function_name, body);
46
48
}
47
49
}
48
50
@@ -84,12 +86,14 @@ call_grapht::call_grapht(
84
86
const goto_programt &goto_program=
85
87
goto_functions.function_map .at (function).body ;
86
88
89
+ nodes.insert (function);
90
+
87
91
forall_callsites (
88
92
goto_program,
89
93
[&](goto_programt::const_targett i_it, const irep_idt &callee)
90
94
{
91
95
add (function, callee, i_it);
92
- if (graph .find (callee)==graph .end ())
96
+ if (edges .find (callee)==edges .end ())
93
97
pending_stack.push (callee);
94
98
}
95
99
); // NOLINT
@@ -129,7 +133,9 @@ void call_grapht::add(
129
133
const irep_idt &caller,
130
134
const irep_idt &callee)
131
135
{
132
- graph.insert (std::pair<irep_idt, irep_idt>(caller, callee));
136
+ edges.insert ({caller, callee});
137
+ nodes.insert (caller);
138
+ nodes.insert (callee);
133
139
}
134
140
135
141
// / Add edge with optional callsite information
@@ -152,7 +158,8 @@ void call_grapht::add(
152
158
call_grapht call_grapht::get_inverted () const
153
159
{
154
160
call_grapht result;
155
- for (const auto &caller_callee : graph)
161
+ result.nodes = nodes;
162
+ for (const auto &caller_callee : edges)
156
163
result.add (caller_callee.second , caller_callee.first );
157
164
return result;
158
165
}
@@ -197,7 +204,12 @@ call_grapht::directed_grapht call_grapht::get_directed_graph() const
197
204
call_grapht::directed_grapht ret;
198
205
function_indicest function_indices (ret);
199
206
200
- for (const auto &edge : graph)
207
+ // To make sure we include unreachable functions we first create indices
208
+ // for all nodes in the graph
209
+ for (const irep_idt &function_name : nodes)
210
+ function_indices[function_name];
211
+
212
+ for (const auto &edge : edges)
201
213
{
202
214
auto a_index=function_indices[edge.first ];
203
215
auto b_index=function_indices[edge.second ];
@@ -237,7 +249,7 @@ void call_grapht::output_dot(std::ostream &out) const
237
249
{
238
250
out << " digraph call_graph {\n " ;
239
251
240
- for (const auto &edge : graph )
252
+ for (const auto &edge : edges )
241
253
{
242
254
out << " \" " << edge.first << " \" -> "
243
255
<< " \" " << edge.second << " \" "
@@ -252,7 +264,7 @@ void call_grapht::output_dot(std::ostream &out) const
252
264
253
265
void call_grapht::output (std::ostream &out) const
254
266
{
255
- for (const auto &edge : graph )
267
+ for (const auto &edge : edges )
256
268
{
257
269
out << edge.first << " -> " << edge.second << " \n " ;
258
270
if (collect_callsites)
@@ -267,7 +279,7 @@ void call_grapht::output_xml(std::ostream &out) const
267
279
if (collect_callsites)
268
280
out << " <!-- XML call-graph representation does not document callsites yet."
269
281
" If you need this, edit call_grapht::output_xml -->\n " ;
270
- for (const auto &edge : graph )
282
+ for (const auto &edge : edges )
271
283
{
272
284
out << " <call_graph_edge caller=\" " ;
273
285
xmlt::escape_attribute (id2string (edge.first ), out);
0 commit comments