CBMC
All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Modules Pages
json_goto_trace.cpp
Go to the documentation of this file.
1/*******************************************************************\
2
3Module: Traces of GOTO Programs
4
5Author: Daniel Kroening
6
7 Date: November 2005
8
9\*******************************************************************/
10
13
14#include "json_goto_trace.h"
15
16#include <util/invariant.h>
17#include <util/namespace.h>
18#include <util/simplify_expr.h>
19#include <util/symbol.h>
20
22
23#include "goto_trace.h"
24#include "json_expr.h"
25
36{
38 const jsont &location = conversion_dependencies.location;
39
40 json_failure["stepType"] = json_stringt("failure");
41 json_failure["hidden"] = jsont::json_boolean(step.hidden);
42 json_failure["internal"] = jsont::json_boolean(step.internal);
43 json_failure["thread"] = json_numbert(std::to_string(step.thread_nr));
44 json_failure["reason"] = json_stringt(step.comment);
45 json_failure["property"] = json_stringt(step.property_id);
46
47 if(!location.is_null())
48 json_failure["sourceLocation"] = location;
49}
50
64{
68
69 auto lhs_object=step.get_lhs_object();
70
71 irep_idt identifier =
72 lhs_object.has_value()?lhs_object->get_identifier():irep_idt();
73
74 json_assignment["stepType"] = json_stringt("assignment");
75
76 if(!json_location.is_null())
77 json_assignment["sourceLocation"] = json_location;
78
81
83 step.full_lhs.is_not_nil(), "full_lhs in assignment must not be nil");
85
86 if(trace_options.json_full_lhs)
87 {
89 {
90 private:
91 const namespacet &ns;
92
93 public:
94 explicit comment_base_name_visitort(const namespacet &ns) : ns(ns)
95 {
96 }
97
98 void operator()(exprt &expr) override
99 {
100 if(expr.id() == ID_symbol)
101 {
102 const symbolt &symbol = ns.lookup(to_symbol_expr(expr));
103
104 if(expr.find(ID_C_base_name).is_not_nil())
105 INVARIANT(
106 expr.find(ID_C_base_name).id() == symbol.base_name,
107 "base_name comment does not match symbol's base_name");
108 else
109 expr.add(ID_C_base_name, irept(symbol.base_name));
110 }
111 }
112 };
115 }
116
117 full_lhs_string = from_expr(ns, identifier, simplified);
118
119 const symbolt *symbol;
120 irep_idt base_name, display_name;
121
124 "full_lhs_value in assignment must not be nil");
125
126 if(!ns.lookup(identifier, symbol))
127 {
128 base_name = symbol->base_name;
129 display_name = symbol->display_name();
130 if(type_string.empty())
131 type_string = from_type(ns, identifier, symbol->type);
132
133 json_assignment["mode"] = json_stringt(symbol->mode);
134 const exprt simplified_expr = simplify_expr(step.full_lhs_value, ns);
135
136 full_lhs_value = json(simplified_expr, ns, symbol->mode);
137 }
138 else
139 {
141 }
142
145 if(trace_options.json_full_lhs)
146 {
147 // Not language specific, still mangled, fully-qualified name of lhs
149 }
151 json_assignment["internal"] = jsont::json_boolean(step.internal);
152 json_assignment["thread"] = json_numbert(std::to_string(step.thread_nr));
153
154 json_assignment["assignmentType"] = json_stringt(
156 ? "actual-parameter"
157 : "variable");
158}
159
170{
171 const goto_trace_stept &step = conversion_dependencies.step;
172 const jsont &location = conversion_dependencies.location;
173 const namespacet &ns = conversion_dependencies.ns;
174
175 json_output["stepType"] = json_stringt("output");
176 json_output["hidden"] = jsont::json_boolean(step.hidden);
177 json_output["internal"] = jsont::json_boolean(step.internal);
178 json_output["thread"] = json_numbert(std::to_string(step.thread_nr));
179 json_output["outputID"] = json_stringt(step.io_id);
180
181 // Recovering the mode from the function
182 irep_idt mode;
183 const symbolt *function_name;
184 if(ns.lookup(step.function_id, function_name))
185 // Failed to find symbol
186 mode = ID_unknown;
187 else
188 mode = function_name->mode;
189 json_output["mode"] = json_stringt(mode);
190 json_arrayt &json_values = json_output["values"].make_array();
191
192 for(const auto &arg : step.io_args)
193 {
194 arg.is_nil() ? json_values.push_back(json_stringt(""))
195 : json_values.push_back(json(arg, ns, mode));
196 }
197
198 if(!location.is_null())
199 json_output["sourceLocation"] = location;
200}
201
212{
213 const goto_trace_stept &step = conversion_dependencies.step;
214 const jsont &location = conversion_dependencies.location;
215 const namespacet &ns = conversion_dependencies.ns;
216
217 json_input["stepType"] = json_stringt("input");
218 json_input["hidden"] = jsont::json_boolean(step.hidden);
219 json_input["internal"] = jsont::json_boolean(step.internal);
220 json_input["thread"] = json_numbert(std::to_string(step.thread_nr));
221 json_input["inputID"] = json_stringt(step.io_id);
222
223 // Recovering the mode from the function
224 irep_idt mode;
225 const symbolt *function_name;
226 if(ns.lookup(step.function_id, function_name))
227 // Failed to find symbol
228 mode = ID_unknown;
229 else
230 mode = function_name->mode;
231 json_input["mode"] = json_stringt(mode);
232 json_arrayt &json_values = json_input["values"].make_array();
233
234 for(const auto &arg : step.io_args)
235 {
236 arg.is_nil() ? json_values.push_back(json_stringt(""))
237 : json_values.push_back(json(arg, ns, mode));
238 }
239
240 if(!location.is_null())
241 json_input["sourceLocation"] = location;
242}
243
254{
255 const goto_trace_stept &step = conversion_dependencies.step;
256 const jsont &location = conversion_dependencies.location;
257 const namespacet &ns = conversion_dependencies.ns;
258
259 std::string tag = (step.type == goto_trace_stept::typet::FUNCTION_CALL)
260 ? "function-call"
261 : "function-return";
262
263 json_call_return["stepType"] = json_stringt(tag);
266 json_call_return["thread"] = json_numbert(std::to_string(step.thread_nr));
267
268 const irep_idt &function_identifier = step.called_function;
269
270 const symbolt &symbol = ns.lookup(function_identifier);
271 json_call_return["function"] =
272 json_objectt({{"displayName", json_stringt(symbol.display_name())},
273 {"identifier", json_stringt(function_identifier)},
274 {"sourceLocation", json(symbol.location)}});
275
276 if(!location.is_null())
277 json_call_return["sourceLocation"] = location;
278}
279
283{
284 json_location_only["stepType"] =
287 json_location_only["thread"] =
288 json_numbert(std::to_string(default_step.thread_number));
289 json_location_only["sourceLocation"] = json(default_step.location);
290}
virtual bool visit(const irep_idt &function_id, trace_ptrt p, working_sett &working_set, const goto_programt &goto_program, const goto_functionst &goto_functions, const namespacet &ns)
Perform one step of abstract interpretation from trace t Depending on the instruction type it may com...
Definition ai.cpp:267
void operator()(const irep_idt &function_id, const goto_programt &goto_program, const namespacet &ns)
Run abstract interpretation on a single function.
Definition ai.h:143
ait supplies three of the four components needed: an abstract interpreter (in this case handling func...
Definition ai.h:562
ait()
Definition ai.h:565
dstringt has one field, an unsigned integer no which is an index into a static table of strings.
Definition dstring.h:38
Base class for all expressions.
Definition expr.h:56
Step of the trace of a GOTO program.
Definition goto_trace.h:50
std::string comment
Definition goto_trace.h:124
irep_idt function_id
Definition goto_trace.h:111
unsigned thread_nr
Definition goto_trace.h:115
irep_idt property_id
Definition goto_trace.h:123
irep_idt called_function
Definition goto_trace.h:142
assignment_typet assignment_type
Definition goto_trace.h:107
std::optional< symbol_exprt > get_lhs_object() const
There are a large number of kinds of tree structured or tree-like data in CPROVER.
Definition irep.h:364
const irept & find(const irep_idt &name) const
Definition irep.cpp:93
bool is_not_nil() const
Definition irep.h:372
const irep_idt & id() const
Definition irep.h:388
irept & add(const irep_idt &name)
Definition irep.cpp:103
json_objectt convert_from_irep(const irept &) const
To convert to JSON from an irep structure by recursively generating JSON for the different sub trees.
Definition json_irep.cpp:31
Definition json.h:27
bool is_null() const
Definition json.h:81
static jsont json_boolean(bool value)
Definition json.h:97
A namespacet is essentially one or two symbol tables bound together, to allow for symbol lookups in t...
Definition namespace.h:91
bool lookup(const irep_idt &name, const symbolt *&symbol) const override
See documentation for namespace_baset::lookup().
Symbol table entry.
Definition symbol.h:28
source_locationt location
Source code location of definition of symbol.
Definition symbol.h:37
typet type
Type of symbol.
Definition symbol.h:31
irep_idt irep_idt base_name
Name of module the symbol belongs to.
Definition symbol.h:46
const irep_idt & display_name() const
Return language specific display name if present.
Definition symbol.h:55
irep_idt mode
Language mode.
Definition symbol.h:49
Traces of GOTO Programs.
Expressions in JSON.
void convert_assert(json_objectt &json_failure, const conversion_dependenciest &conversion_dependencies)
Convert an ASSERT goto_trace step.
void convert_output(json_objectt &json_output, const conversion_dependenciest &conversion_dependencies)
Convert an OUTPUT goto_trace step.
void convert_input(json_objectt &json_input, const conversion_dependenciest &conversion_dependencies)
Convert an INPUT goto_trace step.
void convert_decl(json_objectt &json_assignment, const conversion_dependenciest &conversion_dependencies, const trace_optionst &trace_options)
Convert a DECL goto_trace step.
void convert_return(json_objectt &json_call_return, const conversion_dependenciest &conversion_dependencies)
Convert a FUNCTION_RETURN goto_trace step.
void convert_default(json_objectt &json_location_only, const default_trace_stept &default_step)
Convert all other types of steps not already handled by the other conversion functions.
Traces of GOTO Programs.
std::string from_expr(const namespacet &ns, const irep_idt &identifier, const exprt &expr)
std::string from_type(const namespacet &ns, const irep_idt &identifier, const typet &type)
static void json(json_objectT &result, const irep_idt &property_id, const property_infot &property_info)
exprt simplify_expr(exprt src, const namespacet &ns)
#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 INVARIANT(CONDITION, REASON)
This macro uses the wrapper function 'invariant_violated_string'.
Definition invariant.h:423
const symbol_exprt & to_symbol_expr(const exprt &expr)
Cast an exprt to a symbol_exprt.
Definition std_expr.h:272
This is structure is here to facilitate passing arguments to the conversion functions.
Options for printing the trace using show_goto_trace.
Definition goto_trace.h:221
std::string default_step_name(const default_step_kindt &step_type)
Turns a default_step_kindt into a string that can be used in the trace.
std::optional< default_trace_stept > default_step(const goto_trace_stept &step, const source_locationt &previous_source_location)
Symbol table entry.
dstringt irep_idt
xmlt full_lhs_value(const goto_trace_stept &step, const namespacet &ns)