@@ -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,7 +105,7 @@ 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
@@ -196,8 +197,14 @@ Function: smv_typecheckt::flatten_hierarchy
196197
197198void smv_typecheckt::flatten_hierarchy (smv_parse_treet::modulet &smv_module)
198199{
199- for (auto &element : smv_module.elements )
200+ // Not using ranged for since we will append to the list we are
201+ // iterating over! This avoids recursion.
202+ for (auto element_it = smv_module.elements .begin ();
203+ element_it != smv_module.elements .end ();
204+ ++element_it)
200205 {
206+ auto &element = *element_it;
207+
201208 if (element.is_var () && element.expr .type ().id () == ID_smv_submodule)
202209 {
203210 exprt &inst =
@@ -235,145 +242,65 @@ void smv_typecheckt::instantiate(
235242 smv_parse_treet::modulet &smv_module,
236243 const irep_idt &identifier,
237244 const irep_idt &instance,
238- const exprt::operandst &operands ,
245+ const exprt::operandst &arguments ,
239246 const source_locationt &location)
240247{
241- symbol_table_baset::symbolst::const_iterator s_it =
242- symbol_table. symbols .find (identifier);
248+ // Find the module
249+ auto module_it = smv_parse_tree. modules .find (identifier);
243250
244- if (s_it==symbol_table. symbols .end ())
251+ if (module_it == smv_parse_tree. modules .end ())
245252 {
246253 throw errort ().with_location (location)
247254 << " submodule `" << identifier << " ' not found" ;
248255 }
249256
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+ const auto &instantiated_module = module_it->second ;
258+ const auto ¶meters = instantiated_module.parameters ;
257259
258- // do the arguments/ports
259-
260- if (ports.size ()!=operands.size ())
260+ // map the arguments to parameters
261+ if (parameters.size () != arguments.size ())
261262 {
262263 throw errort ().with_location (location)
263264 << " submodule `" << identifier << " ' has wrong number of arguments" ;
264265 }
265266
266- std::set<irep_idt> port_identifiers;
267- rename_mapt rename_map;
267+ rename_mapt parameter_map;
268268
269- for (std::size_t i = 0 ; i < ports .size (); i++)
269+ for (std::size_t i = 0 ; i < parameters .size (); i++)
270270 {
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);
271+ parameter_map.emplace (parameters[i], arguments[i]);
274272 }
275273
276- // do the variables
277-
278- std::string new_prefix=
279- id2string (smv_module.name )+" ::var::" +id2string (instance)+" ." ;
274+ const std::string prefix = id2string (instance)+' .' ;
280275
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++)
276+ // copy the parse tree elements
277+ for (auto &src_element : instantiated_module.elements )
286278 {
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- }
279+ auto copy = src_element;
294280
295- if (port_identifiers.find (s_it2->first ) != port_identifiers.end ())
296- {
297- }
298- else if (s_it2->second .type .id () == ID_module)
281+ // replace the parameter identifiers,
282+ // and add the prefix to non-parameter identifiers
283+ copy.expr .visit_post ([¶meter_map, &prefix](exprt &expr)
299284 {
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" )
285+ if (expr.id () == ID_smv_identifier)
309286 {
310- symbol.pretty_name =
311- id2string (instance) + ' .' + id2string (symbol.base_name );
312- }
313- else
314- {
315- symbol.pretty_name = strip_smv_prefix (symbol.name );
287+ auto identifier = to_smv_identifier_expr (expr).identifier ();
288+ auto parameter_it = parameter_map.find (identifier);
289+ if (parameter_it != parameter_map.end ())
290+ {
291+ expr = parameter_it->second ;
292+ }
293+ else
294+ {
295+ // add the prefix
296+ to_smv_identifier_expr (expr).identifier (prefix + id2string (identifier));
297+ }
316298 }
299+ });
317300
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 );
351-
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);
301+ // add to main parse tree
302+ smv_module.elements .push_back (copy);
361303 }
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 ())
371- {
372- exprt tmp (trans.trans ());
373- instantiate_rename (tmp, rename_map);
374- smv_module.add_trans (tmp);
375- }
376-
377304}
378305
379306/* ******************************************************************\
@@ -2497,10 +2424,10 @@ void smv_typecheckt::convert(smv_parse_treet::modulet &smv_module)
24972424
24982425 define_map.clear ();
24992426
2500- // check for re-use of variables/defines/parameter identifiers
2501- variable_checks (smv_module);
2427+ // expand the module hierarchy
2428+ flatten_hierarchy (smv_module);
25022429
2503- // variables/defines first, can be used before their declaration
2430+ // Now do variables/defines, which can be used before their declaration
25042431 create_var_symbols (smv_module.elements );
25052432
25062433 // transition relation
@@ -2524,8 +2451,6 @@ void smv_typecheckt::convert(smv_parse_treet::modulet &smv_module)
25242451 if (!element.is_var () && !element.is_ivar ())
25252452 convert (element);
25262453
2527- flatten_hierarchy (smv_module);
2528-
25292454 // we first need to collect all the defines
25302455
25312456 for (auto &element : smv_module.elements )
@@ -2631,6 +2556,13 @@ Function: smv_typecheckt::typecheck
26312556
26322557void smv_typecheckt::typecheck ()
26332558{
2559+ if (module != " smv::main" )
2560+ return ;
2561+
2562+ // check all modules for duplicate identifiers
2563+ for (auto &module_it : smv_parse_tree.modules )
2564+ variable_checks (module_it.second );
2565+
26342566 smv_parse_treet::modulest::iterator it=smv_parse_tree.modules .find (module );
26352567
26362568 if (it==smv_parse_tree.modules .end ())
0 commit comments