CBMC
Loading...
Searching...
No Matches
class_hierarchy.cpp
Go to the documentation of this file.
1/*******************************************************************\
2
3Module: Class Hierarchy
4
5Author: Daniel Kroening
6
7Date: April 2016
8
9\*******************************************************************/
10
13
14#include "class_hierarchy.h"
15
16#include <util/json_stream.h>
17#include <util/std_types.h>
19#include <util/ui_message.h>
20
21#include <iterator>
22#include <ostream>
23
30{
31 // Add nodes for all classes:
32 for(const auto &symbol_pair : symbol_table.symbols)
33 {
34 if(symbol_pair.second.is_type && symbol_pair.second.type.id() == ID_struct)
35 {
38 (*this)[new_node_index].class_identifier = symbol_pair.first;
39 }
40 }
41
42 // Add parent -> child edges:
43 for(const auto &symbol_pair : symbol_table.symbols)
44 {
45 if(symbol_pair.second.is_type && symbol_pair.second.type.id() == ID_struct)
46 {
48
49 for(const auto &base : struct_type.bases())
50 {
51 const irep_idt &parent = base.type().get_identifier();
52 if(!parent.empty())
53 {
54 const auto parent_node_it = nodes_by_name.find(parent);
57 "parent class not in symbol table");
59 }
60 }
61 }
62 }
63}
64
68 const std::vector<node_indext> &node_indices) const
69{
70 idst result;
71 std::transform(
72 node_indices.begin(),
73 node_indices.end(),
74 back_inserter(result),
75 [&](const node_indext &node_index) {
76 return (*this)[node_index].class_identifier;
77 });
78 return result;
79}
80
86{
87 const node_indext &node_index = nodes_by_name.at(c);
88 const auto &child_indices = get_successors(node_index);
90}
91
94 const irep_idt &c,
95 bool forwards) const
96{
98 const node_indext &node_index = nodes_by_name.at(c);
99 const auto &reachable_indices = get_reachable(node_index, forwards);
101 // Remove c itself from the list
102 // TODO Adding it first and then removing it is not ideal. It would be
103 // better to define a function grapht::get_other_reachable and directly use
104 // that here.
105 reachable_ids.erase(
106 std::remove(reachable_ids.begin(), reachable_ids.end(), c),
107 reachable_ids.end());
108 return reachable_ids;
109}
110
119
128
130 const irep_idt &c,
131 idst &dest) const
132{
133 class_mapt::const_iterator it=class_map.find(c);
134 if(it==class_map.end())
135 return;
136 const entryt &entry=it->second;
137
138 for(const auto &child : entry.children)
139 dest.push_back(child);
140
141 // recursive calls
142 for(const auto &child : entry.children)
144}
145
151{
152 for(const auto &symbol_pair : symbol_table.symbols)
153 {
154 if(symbol_pair.second.is_type && symbol_pair.second.type.id() == ID_struct)
155 {
157
158 class_map[symbol_pair.first].is_abstract =
159 struct_type.get_bool(ID_abstract);
160
161 for(const auto &base : struct_type.bases())
162 {
163 const irep_idt &parent = base.type().get_identifier();
164 if(parent.empty())
165 continue;
166
167 class_map[parent].children.push_back(symbol_pair.first);
168 class_map[symbol_pair.first].parents.push_back(parent);
169 }
170 }
171 }
172}
173
180 const irep_idt &c,
181 idst &dest) const
182{
183 class_mapt::const_iterator it=class_map.find(c);
184 if(it==class_map.end())
185 return;
186 const entryt &entry=it->second;
187
188 for(const auto &child : entry.parents)
189 dest.push_back(child);
190
191 // recursive calls
192 for(const auto &child : entry.parents)
194}
195
199void class_hierarchyt::output(std::ostream &out, bool children_only) const
200{
201 for(const auto &c : class_map)
202 {
203 out << c.first << (c.second.is_abstract ? " (abstract)" : "") << ":\n";
204 if(!children_only)
205 {
206 out << " parents:\n";
207 for(const auto &pa : c.second.parents)
208 out << " " << pa << '\n';
209 }
210 out << " children:\n";
211 for(const auto &ch : c.second.children)
212 out << " " << ch << '\n';
213 }
214}
215
218void class_hierarchyt::output_dot(std::ostream &ostr) const
219{
220 ostr << "digraph class_hierarchy {\n"
221 << " rankdir=BT;\n"
222 << " node [fontsize=12 shape=box];\n";
223 for(const auto &c : class_map)
224 {
225 for(const auto &ch : c.second.parents)
226 {
227 ostr << " \"" << c.first << "\" -> "
228 << "\"" << ch << "\" "
229 << " [arrowhead=\"vee\"];"
230 << "\n";
231 }
232 }
233 ostr << "}\n";
234}
235
240 json_stream_arrayt &json_stream,
241 bool children_only) const
242{
243 for(const auto &c : class_map)
244 {
246 json_class["name"] = json_stringt(c.first);
247 json_class["isAbstract"] = jsont::json_boolean(c.second.is_abstract);
248 if(!children_only)
249 {
251 json_class.push_back_stream_array("parents");
252 for(const auto &pa : c.second.parents)
253 json_parents.push_back(json_stringt(pa));
254 }
256 json_class.push_back_stream_array("children");
257 for(const auto &ch : c.second.children)
258 json_children.push_back(json_stringt(ch));
259 }
260}
261
264 ui_message_handlert &message_handler,
265 bool children_only)
266{
267 messaget msg(message_handler);
268 switch(message_handler.get_ui())
269 {
272 msg.result() << messaget::eom;
273 break;
275 if(msg.result().tellp() > 0)
276 msg.result() << messaget::eom; // force end of previous message
277 hierarchy.output(message_handler.get_json_stream(), children_only);
278 break;
281 }
282}
void show_class_hierarchy(const class_hierarchyt &hierarchy, ui_message_handlert &message_handler, bool children_only)
Output the class hierarchy.
Class Hierarchy.
virtual void output(const namespacet &ns, const irep_idt &function_id, const goto_programt &goto_program, std::ostream &out) const
Output the abstract states for a single function.
Definition ai.cpp:39
ait supplies three of the four components needed: an abstract interpreter (in this case handling func...
Definition ai.h:562
void populate(const symbol_table_baset &)
Populate the class hierarchy graph, such that there is a node for every struct type in the symbol tab...
nodes_by_namet nodes_by_name
Maps class identifiers onto node indices.
idst get_children_trans(const irep_idt &c) const
Get all the classes that inherit (directly or indirectly) from class c.
std::vector< irep_idt > idst
idst get_direct_children(const irep_idt &c) const
Get all the classes that directly (i.e.
idst get_other_reachable_ids(const irep_idt &c, bool forwards) const
Helper function for get_children_trans and get_parents_trans
idst get_parents_trans(const irep_idt &c) const
Get all the classes that class c inherits from (directly or indirectly).
idst ids_from_indices(const std::vector< node_indext > &nodes) const
Helper function that converts a vector of node_indext to a vector of ids that are stored in the corre...
Non-graph-based representation of the class hierarchy.
void output_dot(std::ostream &) const
Output class hierarchy in Graphviz DOT format.
void get_parents_trans_rec(const irep_idt &, idst &) const
Get all the classes that class c inherits from (directly or indirectly).
void operator()(const symbol_table_baset &)
Looks for all the struct types in the symbol table and construct a map from class names to a data str...
void get_children_trans_rec(const irep_idt &, idst &) const
void output(std::ostream &, bool children_only) const
Output the class hierarchy in plain text.
std::vector< irep_idt > idst
dstringt has one field, an unsigned integer no which is an index into a static table of strings.
Definition dstring.h:38
bool empty() const
Definition dstring.h:89
std::vector< node_indext > get_reachable(node_indext src, bool forwards) const
Run depth-first search on the graph, starting from a single source node.
Definition graph.h:602
node_indext add_node(arguments &&... values)
Definition graph.h:180
void add_edge(node_indext a, node_indext b)
Definition graph.h:232
std::vector< node_indext > get_successors(const node_indext &n) const
Definition graph.h:956
Provides methods for streaming JSON arrays.
Definition json_stream.h:93
json_stream_objectt & push_back_stream_object()
Add a JSON object child stream.
Provides methods for streaming JSON objects.
static jsont json_boolean(bool value)
Definition json.h:97
Class that provides messages with a built-in verbosity 'level'.
Definition message.h:154
static eomt eom
Definition message.h:289
Structure type, corresponds to C style structs.
Definition std_types.h:231
The symbol table base class interface.
const symbolst & symbols
Read-only field, used to look up symbols given their names.
virtual uit get_ui() const
Definition ui_message.h:33
virtual json_stream_arrayt & get_json_stream()
Definition ui_message.h:40
std::size_t node_indext
Definition scope_tree.h:19
#define DATA_INVARIANT(CONDITION, REASON)
This condition should be used to document that assumptions that are made on goto_functions,...
Definition invariant.h:534
#define UNIMPLEMENTED
Definition invariant.h:558
Pre-defined types.
const struct_typet & to_struct_type(const typet &type)
Cast a typet to a struct_typet.
Definition std_types.h:308
Author: Diffblue Ltd.