Skip to content

Commit d4c4298

Browse files
authored
Merge pull request #2816 from smowton/smowton/feature/json-symbol-table
Add JSON symbol table
2 parents 0f0d50b + 20e5d89 commit d4c4298

File tree

12 files changed

+206
-22
lines changed

12 files changed

+206
-22
lines changed

jbmc/src/janalyzer/janalyzer_parse_options.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -377,7 +377,7 @@ int janalyzer_parse_optionst::doit()
377377
// show it?
378378
if(cmdline.isset("show-symbol-table"))
379379
{
380-
::show_symbol_table(goto_model.symbol_table, get_ui());
380+
::show_symbol_table(goto_model.symbol_table, ui_message_handler);
381381
return CPROVER_EXIT_SUCCESS;
382382
}
383383

jbmc/src/jbmc/jbmc_parse_options.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -652,7 +652,7 @@ int jbmc_parse_optionst::get_goto_program(
652652
if(cmdline.isset("show-symbol-table"))
653653
{
654654
show_symbol_table(
655-
lazy_goto_model.symbol_table, ui_message_handler.get_ui());
655+
lazy_goto_model.symbol_table, ui_message_handler);
656656
return 0;
657657
}
658658

@@ -832,7 +832,7 @@ bool jbmc_parse_optionst::show_loaded_functions(
832832
if(cmdline.isset("show-symbol-table"))
833833
{
834834
show_symbol_table(
835-
goto_model.get_symbol_table(), ui_message_handler.get_ui());
835+
goto_model.get_symbol_table(), ui_message_handler);
836836
return true;
837837
}
838838

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
2+
int main(int argc, char** argv) {
3+
int x = 5;
4+
++x;
5+
}
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
CORE
2+
test.c
3+
--list-symbols --json-ui
4+
"symbolTable": \{
5+
"main": \{
6+
"main::1::x": \{
7+
^EXIT=0$
8+
^SIGNAL=0$
9+
--
10+
^warning: ignoring
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
2+
int main(int argc, char** argv) {
3+
int x = 5;
4+
++x;
5+
}
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
CORE
2+
test.c
3+
--show-symbol-table --json-ui
4+
"symbolTable": \{
5+
"main": \{
6+
"main::1::x": \{
7+
^EXIT=0$
8+
^SIGNAL=0$
9+
--
10+
^warning: ignoring

src/cbmc/cbmc_parse_options.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -587,7 +587,7 @@ int cbmc_parse_optionst::get_goto_program(
587587

588588
if(cmdline.isset("show-symbol-table"))
589589
{
590-
show_symbol_table(goto_model, ui_message_handler.get_ui());
590+
show_symbol_table(goto_model, ui_message_handler);
591591
return CPROVER_EXIT_SUCCESS;
592592
}
593593

src/goto-analyzer/goto_analyzer_parse_options.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -409,7 +409,7 @@ int goto_analyzer_parse_optionst::doit()
409409
// show it?
410410
if(cmdline.isset("show-symbol-table"))
411411
{
412-
::show_symbol_table(goto_model.symbol_table, get_ui());
412+
::show_symbol_table(goto_model.symbol_table, ui_message_handler);
413413
return CPROVER_EXIT_SUCCESS;
414414
}
415415

src/goto-instrument/goto_instrument_parse_options.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -464,7 +464,7 @@ int goto_instrument_parse_optionst::doit()
464464

465465
if(cmdline.isset("show-symbol-table"))
466466
{
467-
::show_symbol_table(goto_model, get_ui());
467+
::show_symbol_table(goto_model, ui_message_handler);
468468
return CPROVER_EXIT_SUCCESS;
469469
}
470470

@@ -519,7 +519,7 @@ int goto_instrument_parse_optionst::doit()
519519

520520
if(cmdline.isset("list-symbols"))
521521
{
522-
show_symbol_table_brief(goto_model, get_ui());
522+
show_symbol_table_brief(goto_model, ui_message_handler);
523523
return CPROVER_EXIT_SUCCESS;
524524
}
525525

src/goto-programs/show_symbol_table.cpp

Lines changed: 146 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -11,12 +11,15 @@ Author: Daniel Kroening, [email protected]
1111

1212
#include "show_symbol_table.h"
1313

14+
#include <algorithm>
1415
#include <iostream>
1516
#include <memory>
1617

1718
#include <langapi/language.h>
1819
#include <langapi/mode.h>
1920

21+
#include <util/json_irep.h>
22+
2023
#include "goto_model.h"
2124

2225
void show_symbol_table_xml_ui()
@@ -68,16 +71,16 @@ void show_symbol_table_plain(
6871
out << '\n' << "Symbols:" << '\n' << '\n';
6972

7073
// we want to sort alphabetically
71-
std::set<std::string> symbols;
74+
std::vector<std::string> symbols;
75+
symbols.reserve(symbol_table.symbols.size());
7276

7377
for(const auto &symbol_pair : symbol_table.symbols)
74-
{
75-
symbols.insert(id2string(symbol_pair.first));
76-
}
78+
symbols.push_back(id2string(symbol_pair.first));
79+
std::sort(symbols.begin(), symbols.end());
7780

7881
const namespacet ns(symbol_table);
7982

80-
for(const std::string &id : symbols)
83+
for(const irep_idt &id : symbols)
8184
{
8285
const symbolt &symbol=ns.lookup(id);
8386

@@ -152,11 +155,139 @@ void show_symbol_table_plain(
152155
}
153156
}
154157

158+
static void show_symbol_table_json_ui(
159+
const symbol_tablet &symbol_table,
160+
message_handlert &message_handler)
161+
{
162+
json_stream_arrayt &out = message_handler.get_json_stream();
163+
164+
json_stream_objectt &result_wrapper = out.push_back_stream_object();
165+
json_stream_objectt &result =
166+
result_wrapper.push_back_stream_object("symbolTable");
167+
168+
const namespacet ns(symbol_table);
169+
json_irept irep_converter(true);
170+
171+
for(const auto &id_and_symbol : symbol_table.symbols)
172+
{
173+
const symbolt &symbol = id_and_symbol.second;
174+
175+
std::unique_ptr<languaget> ptr;
176+
177+
if(symbol.mode=="")
178+
{
179+
ptr=get_default_language();
180+
}
181+
else
182+
{
183+
ptr=get_language_from_mode(symbol.mode);
184+
}
185+
186+
if(!ptr)
187+
throw "symbol "+id2string(symbol.name)+" has unknown mode";
188+
189+
std::string type_str, value_str;
190+
191+
if(symbol.type.is_not_nil())
192+
ptr->from_type(symbol.type, type_str, ns);
193+
194+
if(symbol.value.is_not_nil())
195+
ptr->from_expr(symbol.value, value_str, ns);
196+
197+
json_objectt symbol_json;
198+
symbol_json["prettyName"] = json_stringt(symbol.pretty_name);
199+
symbol_json["baseName"] = json_stringt(symbol.base_name);
200+
symbol_json["mode"] = json_stringt(symbol.mode);
201+
symbol_json["module"] = json_stringt(symbol.module);
202+
203+
symbol_json["prettyType"] = json_stringt(type_str);
204+
symbol_json["prettyValue"] = json_stringt(value_str);
205+
206+
symbol_json["type"] = irep_converter.convert_from_irep(symbol.type);
207+
symbol_json["value"] = irep_converter.convert_from_irep(symbol.value);
208+
symbol_json["location"] = irep_converter.convert_from_irep(symbol.location);
209+
210+
symbol_json["isType"] = jsont::json_boolean(symbol.is_type);
211+
symbol_json["isMacro"] = jsont::json_boolean(symbol.is_macro);
212+
symbol_json["isExported"] = jsont::json_boolean(symbol.is_exported);
213+
symbol_json["isInput"] = jsont::json_boolean(symbol.is_input);
214+
symbol_json["isOutput"] = jsont::json_boolean(symbol.is_output);
215+
symbol_json["isStateVar"] = jsont::json_boolean(symbol.is_state_var);
216+
symbol_json["isProperty"] = jsont::json_boolean(symbol.is_property);
217+
symbol_json["isStaticLifetime"] =
218+
jsont::json_boolean(symbol.is_static_lifetime);
219+
symbol_json["isThreadLocal"] =
220+
jsont::json_boolean(symbol.is_thread_local);
221+
symbol_json["isLvalue"] = jsont::json_boolean(symbol.is_lvalue);
222+
symbol_json["isFileLocal"] = jsont::json_boolean(symbol.is_file_local);
223+
symbol_json["isExtern"] = jsont::json_boolean(symbol.is_extern);
224+
symbol_json["isVolatile"] = jsont::json_boolean(symbol.is_volatile);
225+
symbol_json["isParameter"] = jsont::json_boolean(symbol.is_parameter);
226+
symbol_json["isAuxiliary"] = jsont::json_boolean(symbol.is_auxiliary);
227+
symbol_json["isWeak"] = jsont::json_boolean(symbol.is_weak);
228+
229+
result.push_back(id2string(symbol.name), symbol_json);
230+
}
231+
}
232+
233+
static void show_symbol_table_brief_json_ui(
234+
const symbol_tablet &symbol_table,
235+
message_handlert &message_handler)
236+
{
237+
json_stream_arrayt &out = message_handler.get_json_stream();
238+
239+
json_stream_objectt &result_wrapper = out.push_back_stream_object();
240+
json_stream_objectt &result =
241+
result_wrapper.push_back_stream_object("symbolTable");
242+
243+
const namespacet ns(symbol_table);
244+
json_irept irep_converter(true);
245+
246+
for(const auto &id_and_symbol : symbol_table.symbols)
247+
{
248+
const symbolt &symbol = id_and_symbol.second;
249+
250+
std::unique_ptr<languaget> ptr;
251+
252+
if(symbol.mode=="")
253+
{
254+
ptr=get_default_language();
255+
}
256+
else
257+
{
258+
ptr=get_language_from_mode(symbol.mode);
259+
}
260+
261+
if(!ptr)
262+
throw "symbol "+id2string(symbol.name)+" has unknown mode";
263+
264+
std::string type_str, value_str;
265+
266+
if(symbol.type.is_not_nil())
267+
ptr->from_type(symbol.type, type_str, ns);
268+
269+
if(symbol.value.is_not_nil())
270+
ptr->from_expr(symbol.value, value_str, ns);
271+
272+
json_objectt symbol_json;
273+
symbol_json["prettyName"] = json_stringt(symbol.pretty_name);
274+
symbol_json["baseName"] = json_stringt(symbol.base_name);
275+
symbol_json["mode"] = json_stringt(symbol.mode);
276+
symbol_json["module"] = json_stringt(symbol.module);
277+
278+
symbol_json["prettyType"] = json_stringt(type_str);
279+
280+
symbol_json["type"] = irep_converter.convert_from_irep(symbol.type);
281+
282+
result.push_back(id2string(symbol.name), symbol_json);
283+
}
284+
}
285+
155286
void show_symbol_table(
156287
const symbol_tablet &symbol_table,
157-
ui_message_handlert::uit ui)
288+
ui_message_handlert &ui)
158289
{
159-
switch(ui)
290+
switch(ui.get_ui())
160291
{
161292
case ui_message_handlert::uit::PLAIN:
162293
show_symbol_table_plain(symbol_table, std::cout);
@@ -166,23 +297,26 @@ void show_symbol_table(
166297
show_symbol_table_xml_ui();
167298
break;
168299

300+
case ui_message_handlert::uit::JSON_UI:
301+
show_symbol_table_json_ui(symbol_table, ui);
302+
169303
default:
170304
break;
171305
}
172306
}
173307

174308
void show_symbol_table(
175309
const goto_modelt &goto_model,
176-
ui_message_handlert::uit ui)
310+
ui_message_handlert &ui)
177311
{
178312
show_symbol_table(goto_model.symbol_table, ui);
179313
}
180314

181315
void show_symbol_table_brief(
182316
const symbol_tablet &symbol_table,
183-
ui_message_handlert::uit ui)
317+
ui_message_handlert &ui)
184318
{
185-
switch(ui)
319+
switch(ui.get_ui())
186320
{
187321
case ui_message_handlert::uit::PLAIN:
188322
show_symbol_table_brief_plain(symbol_table, std::cout);
@@ -193,13 +327,14 @@ void show_symbol_table_brief(
193327
break;
194328

195329
default:
330+
show_symbol_table_brief_json_ui(symbol_table, ui);
196331
break;
197332
}
198333
}
199334

200335
void show_symbol_table_brief(
201336
const goto_modelt &goto_model,
202-
ui_message_handlert::uit ui)
337+
ui_message_handlert &ui)
203338
{
204339
show_symbol_table_brief(goto_model.symbol_table, ui);
205340
}

src/goto-programs/show_symbol_table.h

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -19,18 +19,18 @@ class goto_modelt;
1919

2020
void show_symbol_table(
2121
const symbol_tablet &,
22-
ui_message_handlert::uit ui);
22+
ui_message_handlert &ui);
2323

2424
void show_symbol_table_brief(
2525
const symbol_tablet &,
26-
ui_message_handlert::uit ui);
26+
ui_message_handlert &ui);
2727

2828
void show_symbol_table(
2929
const goto_modelt &,
30-
ui_message_handlert::uit ui);
30+
ui_message_handlert &ui);
3131

3232
void show_symbol_table_brief(
3333
const goto_modelt &,
34-
ui_message_handlert::uit ui);
34+
ui_message_handlert &ui);
3535

3636
#endif // CPROVER_GOTO_PROGRAMS_SHOW_SYMBOL_TABLE_H

src/util/json_stream.h

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -169,6 +169,25 @@ class json_stream_objectt : public json_streamt
169169
return it->second;
170170
}
171171

172+
/// Push back a JSON element into the current object stream.
173+
/// Note the pushed key won't be available via operator[], as it has been
174+
/// output already.
175+
/// Provided for compatibility with `jsont`.
176+
/// \param key: new key to create in the streamed object
177+
/// \param json: a non-streaming JSON element
178+
void push_back(const std::string &key, const jsont &json)
179+
{
180+
PRECONDITION(open);
181+
// Check the key is not already due to be output later:
182+
PRECONDITION(!object.count(key));
183+
// To ensure consistency of the output, we flush and
184+
// close the current child stream before printing the given element.
185+
output_child_stream();
186+
output_delimiter();
187+
jsont::output_key(out, key);
188+
json.output_rec(out, indent + 1);
189+
}
190+
172191
json_stream_objectt &push_back_stream_object(const std::string &key);
173192
json_stream_arrayt &push_back_stream_array(const std::string &key);
174193

0 commit comments

Comments
 (0)