@@ -60,6 +60,7 @@ class smv_typecheckt:public typecheckt
6060 } modet;
6161
6262 void convert (smv_parse_treet::modulet &);
63+
6364 void create_var_symbols (const smv_parse_treet::modulet::element_listt &);
6465
6566 void collect_define (const equal_exprt &);
@@ -104,16 +105,14 @@ class smv_typecheckt:public typecheckt
104105 smv_parse_treet::modulet &,
105106 const irep_idt &identifier,
106107 const irep_idt &instance,
107- const exprt::operandst &operands ,
108+ const exprt::operandst &arguments ,
108109 const source_locationt &);
109110
110111 typet
111112 type_union (const typet &type1, const typet &type2, const source_locationt &);
112113
113114 typedef std::map<irep_idt, exprt> rename_mapt;
114115
115- void instantiate_rename (exprt &, const rename_mapt &rename_map);
116-
117116 void convert_ports (smv_parse_treet::modulet &, typet &dest);
118117
119118 // for defines
@@ -196,8 +195,14 @@ Function: smv_typecheckt::flatten_hierarchy
196195
197196void smv_typecheckt::flatten_hierarchy (smv_parse_treet::modulet &smv_module)
198197{
199- for (auto &element : smv_module.elements )
198+ // Not using ranged for since we will append to the list we are
199+ // iterating over! This avoids recursion.
200+ for (auto element_it = smv_module.elements .begin ();
201+ element_it != smv_module.elements .end ();
202+ ++element_it)
200203 {
204+ auto &element = *element_it;
205+
201206 if (element.is_var () && element.expr .type ().id () == ID_smv_submodule)
202207 {
203208 exprt &inst =
@@ -235,195 +240,66 @@ void smv_typecheckt::instantiate(
235240 smv_parse_treet::modulet &smv_module,
236241 const irep_idt &identifier,
237242 const irep_idt &instance,
238- const exprt::operandst &operands ,
243+ const exprt::operandst &arguments ,
239244 const source_locationt &location)
240245{
241- symbol_table_baset::symbolst::const_iterator s_it =
242- symbol_table. symbols .find (identifier);
246+ // Find the module
247+ auto module_it = smv_parse_tree. module_map .find (identifier);
243248
244- if (s_it==symbol_table. symbols .end ())
249+ if (module_it == smv_parse_tree. module_map .end ())
245250 {
246251 throw errort ().with_location (location)
247252 << " submodule `" << identifier << " ' not found" ;
248253 }
249254
250- if (s_it->second .type .id ()!=ID_module)
251- {
252- throw errort ().with_location (location)
253- << " submodule `" << identifier << " ' not a module" ;
254- }
255-
256- const irept::subt &ports=s_it->second .type .find (ID_ports).get_sub ();
257-
258- // do the arguments/ports
255+ const auto &instantiated_module = *module_it->second ;
256+ const auto ¶meters = instantiated_module.parameters ;
259257
260- if (ports.size ()!=operands.size ())
258+ // map the arguments to parameters
259+ if (parameters.size () != arguments.size ())
261260 {
262261 throw errort ().with_location (location)
263262 << " submodule `" << identifier << " ' has wrong number of arguments" ;
264263 }
265264
266- std::set<irep_idt> port_identifiers;
267- rename_mapt rename_map;
268-
269- for (std::size_t i = 0 ; i < ports.size (); i++)
270- {
271- const irep_idt &identifier=ports[i].get (ID_identifier);
272- rename_map.insert (std::pair<irep_idt, exprt>(identifier, operands[i]));
273- port_identifiers.insert (identifier);
274- }
275-
276- // do the variables
277-
278- std::string new_prefix=
279- id2string (smv_module.name )+" ::var::" +id2string (instance)+" ." ;
280-
281- std::set<irep_idt> var_identifiers;
282-
283- for (auto v_it=symbol_table.symbol_module_map .lower_bound (identifier);
284- v_it!=symbol_table.symbol_module_map .upper_bound (identifier);
285- v_it++)
286- {
287- symbol_table_baset::symbolst::const_iterator s_it2 =
288- symbol_table.symbols .find (v_it->second );
289-
290- if (s_it2==symbol_table.symbols .end ())
291- {
292- throw errort () << " symbol `" << v_it->second << " ' not found" ;
293- }
294-
295- if (port_identifiers.find (s_it2->first ) != port_identifiers.end ())
296- {
297- }
298- else if (s_it2->second .type .id () == ID_module)
299- {
300- }
301- else
302- {
303- symbolt symbol (s_it2->second );
304-
305- symbol.name =new_prefix+id2string (symbol.base_name );
306- symbol.module =smv_module.name ;
307-
308- if (smv_module.name == " smv::main" )
309- {
310- symbol.pretty_name =
311- id2string (instance) + ' .' + id2string (symbol.base_name );
312- }
313- else
314- {
315- symbol.pretty_name = strip_smv_prefix (symbol.name );
316- }
317-
318- rename_map.insert (
319- std::pair<irep_idt, exprt>(s_it2->first , symbol.symbol_expr ()));
320-
321- var_identifiers.insert (symbol.name );
322-
323- symbol_table.add (symbol);
324- }
325- }
326-
327- // fix values (macros)
328-
329- for (const auto &v_id : var_identifiers)
330- {
331- auto s_it2 = symbol_table.get_writeable (v_id);
332-
333- if (s_it2==nullptr )
334- {
335- throw errort () << " symbol `" << v_id << " ' not found" ;
336- }
337-
338- symbolt &symbol=*s_it2;
339-
340- if (!symbol.value .is_nil ())
341- {
342- instantiate_rename (symbol.value , rename_map);
343- typecheck (symbol.value , OTHER);
344- convert_expr_to (symbol.value , symbol.type );
345- }
346- }
347-
348- // get the transition system
349-
350- const transt &trans=to_trans_expr (s_it->second .value );
265+ rename_mapt parameter_map;
351266
352- std::string old_prefix=id2string (s_it->first )+" ::var::" ;
353-
354- // do the transition system
355-
356- if (!trans.invar ().is_true ())
357- {
358- exprt tmp (trans.invar ());
359- instantiate_rename (tmp, rename_map);
360- smv_module.add_invar (tmp);
361- }
362-
363- if (!trans.init ().is_true ())
364- {
365- exprt tmp (trans.init ());
366- instantiate_rename (tmp, rename_map);
367- smv_module.add_init (tmp);
368- }
369-
370- if (!trans.trans ().is_true ())
267+ for (std::size_t i = 0 ; i < parameters.size (); i++)
371268 {
372- exprt tmp (trans.trans ());
373- instantiate_rename (tmp, rename_map);
374- smv_module.add_trans (tmp);
269+ parameter_map.emplace (parameters[i], arguments[i]);
375270 }
376271
377- }
378-
379- /* ******************************************************************\
380-
381- Function: smv_typecheckt::instantiate_rename
382-
383- Inputs:
384-
385- Outputs:
386-
387- Purpose:
272+ const std::string prefix = id2string (instance) + ' .' ;
388273
389- \*******************************************************************/
390-
391- void smv_typecheckt::instantiate_rename (
392- exprt &expr,
393- const rename_mapt &rename_map)
394- {
395- for (auto &op : expr.operands ())
396- instantiate_rename (op, rename_map);
397-
398- if (expr.id ()==ID_symbol || expr.id ()==ID_next_symbol)
274+ // copy the parse tree elements
275+ for (auto &src_element : instantiated_module.elements )
399276 {
400- const irep_idt &old_identifier=expr.get (ID_identifier);
401- bool next=expr.id ()==ID_next_symbol;
402-
403- rename_mapt::const_iterator it=
404- rename_map.find (old_identifier);
277+ auto copy = src_element;
405278
406- if (it!=rename_map.end ())
407- {
408- expr=it->second ;
409-
410- if (next)
279+ // replace the parameter identifiers,
280+ // and add the prefix to non-parameter identifiers
281+ copy.expr .visit_post (
282+ [¶meter_map, &prefix](exprt &expr)
411283 {
412- if (expr.id ()==ID_symbol)
413- {
414- expr=it->second ;
415- expr.id (ID_next_symbol);
416- }
417- else
284+ if (expr.id () == ID_smv_identifier)
418285 {
419- throw errort ().with_location (expr.find_source_location ())
420- << " expected symbol expression here, but got "
421- << to_string (it->second );
286+ auto identifier = to_smv_identifier_expr (expr).identifier ();
287+ auto parameter_it = parameter_map.find (identifier);
288+ if (parameter_it != parameter_map.end ())
289+ {
290+ expr = parameter_it->second ;
291+ }
292+ else
293+ {
294+ // add the prefix
295+ to_smv_identifier_expr (expr).identifier (
296+ prefix + id2string (identifier));
297+ }
422298 }
423- }
424- else
425- expr=it-> second ;
426- }
299+ });
300+
301+ // add to main parse tree
302+ smv_module. elements . push_back (copy);
427303 }
428304}
429305
@@ -2497,10 +2373,10 @@ void smv_typecheckt::convert(smv_parse_treet::modulet &smv_module)
24972373
24982374 define_map.clear ();
24992375
2500- // check for re-use of variables/defines/parameter identifiers
2501- variable_checks (smv_module);
2376+ // expand the module hierarchy
2377+ flatten_hierarchy (smv_module);
25022378
2503- // variables/defines first, can be used before their declaration
2379+ // Now do variables/defines, which can be used before their declaration
25042380 create_var_symbols (smv_module.elements );
25052381
25062382 // transition relation
@@ -2524,8 +2400,6 @@ void smv_typecheckt::convert(smv_parse_treet::modulet &smv_module)
25242400 if (!element.is_var () && !element.is_ivar ())
25252401 convert (element);
25262402
2527- flatten_hierarchy (smv_module);
2528-
25292403 // we first need to collect all the defines
25302404
25312405 for (auto &element : smv_module.elements )
@@ -2631,6 +2505,13 @@ Function: smv_typecheckt::typecheck
26312505
26322506void smv_typecheckt::typecheck ()
26332507{
2508+ if (module != " smv::main" )
2509+ return ;
2510+
2511+ // check all modules for duplicate identifiers
2512+ for (auto &module : smv_parse_tree.module_list )
2513+ variable_checks (module );
2514+
26342515 auto it = smv_parse_tree.module_map .find (module );
26352516
26362517 if (it == smv_parse_tree.module_map .end ())
0 commit comments