@@ -30,6 +30,48 @@ Author: Matthias Weiss, matthias.weiss@diffblue.com
3030// / Name of the CPROVER-specific hide label.
3131#define CPROVER_HIDE CPROVER_PREFIX " HIDE"
3232
33+ // / Searches for symbols with the given name (which is considered to be the
34+ // / name of the main symbol) and returns false if there is exactly one symbol
35+ // / with that name in the given symbol table. Prints an error message and
36+ // / returns true if there are multiple or no matches.
37+ // / \param symbol_table: Symbol table to search through.
38+ // / \param message_handler: Used for printing error messages.
39+ // / \param main_symbol_name: Name of the symbol to look for.
40+ // / \return False if there is exactly one match, true otherwise.
41+ static bool is_main_symbol_invalid (
42+ const symbol_tablet &symbol_table,
43+ message_handlert &message_handler,
44+ const irep_idt &main_symbol_name)
45+ {
46+ bool found = false ;
47+
48+ for (const std::pair<const irep_idt, symbolt> &pair : symbol_table)
49+ {
50+ if (pair.first == main_symbol_name && pair.second .type .id () == ID_code)
51+ {
52+ if (found)
53+ {
54+ messaget message (message_handler);
55+ message.error () << " main symbol `" << main_symbol_name
56+ << " ' is ambiguous" << messaget::eom;
57+ return true ;
58+ }
59+ else
60+ found = true ;
61+ }
62+ }
63+
64+ if (found)
65+ return false ;
66+ else
67+ {
68+ messaget message (message_handler);
69+ message.error () << " main symbol `" << main_symbol_name << " ' not found"
70+ << messaget::eom;
71+ return true ;
72+ }
73+ }
74+
3375// / Creates a call to __CPROVER_initialize and adds it to the start function's
3476// / body.
3577// / \param [out] function_body: Body of the start function.
@@ -162,40 +204,23 @@ bool statement_list_entry_point(
162204
163205 irep_idt main_symbol_name;
164206
165- // Find main symbol, if any is given .
207+ // Find main symbol given by the user .
166208 if (config.main .has_value ())
167209 {
168- std::list<irep_idt> matches;
169-
170- for (const std::pair<const irep_idt, symbolt> &pair : symbol_table)
171- if (pair.first == config.main .value () && pair.second .type .id () == ID_code)
172- matches.push_back (pair.first );
173-
174- if (matches.empty ())
175- {
176- messaget message (message_handler);
177- message.error () << " main symbol `" << config.main .value () << " ' not found"
178- << messaget::eom;
179- return true ;
180- }
181-
182- if (matches.size () > 1 )
183- {
184- messaget message (message_handler);
185- message.error () << " main symbol `" << config.main .value ()
186- << " ' is ambiguous" << messaget::eom;
210+ if (is_main_symbol_invalid (
211+ symbol_table, message_handler, config.main .value ()))
187212 return true ;
188- }
189-
190- main_symbol_name = matches.front ();
213+ main_symbol_name = config.main .value ();
191214 }
215+ // Fallback: Search for block with TIA main standard name.
216+ // TODO: Support the standard entry point of STL (organisation blocks).
217+ // This also requires to expand the grammar and typecheck.
192218 else
193219 {
194- // TODO: Support the standard entry point of STL (organisation blocks).
195- // This also requires to expand the grammar and typecheck.
196- // For now, return false to let the typecheck itself pass (vital for
197- // --show-symbol-table). The missing entry symbol will be caught later.
198- return false ;
220+ if (is_main_symbol_invalid (
221+ symbol_table, message_handler, ID_statement_list_main_function))
222+ return true ;
223+ main_symbol_name = ID_statement_list_main_function;
199224 }
200225
201226 const symbolt &main = symbol_table.lookup_ref (main_symbol_name);
0 commit comments