@@ -100,12 +100,12 @@ void statement_list_typecheckt::typecheck()
100
100
parse_tree.function_blocks )
101
101
{
102
102
symbolt &fb_sym{symbol_table.get_writeable_ref (fb.name )};
103
- typecheck_statement_list_networks (fb. networks , fb_sym);
103
+ typecheck_statement_list_networks (fb, fb_sym);
104
104
}
105
105
for (const statement_list_parse_treet::functiont &fc : parse_tree.functions )
106
106
{
107
107
symbolt &function_sym{symbol_table.get_writeable_ref (fc.name )};
108
- typecheck_statement_list_networks (fc. networks , function_sym);
108
+ typecheck_statement_list_networks (fc, function_sym);
109
109
}
110
110
}
111
111
@@ -149,14 +149,12 @@ void statement_list_typecheckt::typecheck_function_block_declaration(
149
149
param_sym.mode = STATEMENT_LIST_MODE;
150
150
symbol_table.add (param_sym);
151
151
152
- // Setup FB symbol type and value and add it to the symbol table .
152
+ // Setup FB symbol type and value.
153
153
code_typet::parameterst params;
154
154
params.push_back (param);
155
155
code_typet fb_type{params, empty_typet ()};
156
156
fb_type.set (ID_statement_list_type, ID_statement_list_function_block);
157
157
function_block_sym.type = fb_type;
158
- function_block_sym.value = code_blockt{};
159
- typecheck_temp_var_decls (function_block, function_block_sym);
160
158
symbol_table.add (function_block_sym);
161
159
}
162
160
@@ -170,17 +168,16 @@ void statement_list_typecheckt::typecheck_function_declaration(
170
168
function_sym.pretty_name = function_sym.name ;
171
169
function_sym.mode = STATEMENT_LIST_MODE;
172
170
code_typet::parameterst params;
173
- typecheck_function_var_decls (function.var_input , params, function.name );
174
- typecheck_function_var_decls (function.var_inout , params, function.name );
175
- typecheck_function_var_decls (function.var_output , params, function.name );
171
+ typecheck_function_var_decls (
172
+ function.var_input , params, function.name , ID_statement_list_var_input);
173
+ typecheck_function_var_decls (
174
+ function.var_inout , params, function.name , ID_statement_list_var_inout);
175
+ typecheck_function_var_decls (
176
+ function.var_output , params, function.name , ID_statement_list_var_output);
176
177
177
178
code_typet fc_type{params, function.return_type };
178
179
fc_type.set (ID_statement_list_type, ID_statement_list_function);
179
180
function_sym.type = fc_type;
180
- function_sym.value = code_blockt{};
181
-
182
- typecheck_temp_var_decls (function, function_sym);
183
-
184
181
symbol_table.add (function_sym);
185
182
}
186
183
@@ -204,32 +201,39 @@ struct_typet statement_list_typecheckt::create_instance_data_block_type(
204
201
const statement_list_parse_treet::function_blockt &function_block)
205
202
{
206
203
struct_union_typet::componentst components;
207
- typecheck_function_block_var_decls (function_block.var_input , components);
208
- typecheck_function_block_var_decls (function_block.var_inout , components);
209
- typecheck_function_block_var_decls (function_block.var_output , components);
210
- typecheck_function_block_var_decls (function_block.var_static , components);
204
+ typecheck_function_block_var_decls (
205
+ function_block.var_input , components, ID_statement_list_var_input);
206
+ typecheck_function_block_var_decls (
207
+ function_block.var_inout , components, ID_statement_list_var_inout);
208
+ typecheck_function_block_var_decls (
209
+ function_block.var_output , components, ID_statement_list_var_output);
210
+ typecheck_function_block_var_decls (
211
+ function_block.var_static , components, ID_statement_list_var_static);
211
212
212
213
return struct_typet{components};
213
214
}
214
215
215
216
void statement_list_typecheckt::typecheck_function_block_var_decls (
216
217
const statement_list_parse_treet::var_declarationst &var_decls,
217
- struct_union_typet::componentst &components)
218
+ struct_union_typet::componentst &components,
219
+ const irep_idt &var_property)
218
220
{
219
221
for (const statement_list_parse_treet::var_declarationt &declaration :
220
222
var_decls)
221
223
{
222
224
const irep_idt &var_name{declaration.variable .get_identifier ()};
223
225
const typet &var_type{declaration.variable .type ()};
224
226
struct_union_typet::componentt component{var_name, var_type};
227
+ component.set (ID_statement_list_type, var_property);
225
228
components.push_back (component);
226
229
}
227
230
}
228
231
229
232
void statement_list_typecheckt::typecheck_function_var_decls (
230
233
const statement_list_parse_treet::var_declarationst &var_decls,
231
234
code_typet::parameterst ¶ms,
232
- const irep_idt &function_name)
235
+ const irep_idt &function_name,
236
+ const irep_idt &var_property)
233
237
{
234
238
for (const statement_list_parse_treet::var_declarationt &declaration :
235
239
var_decls)
@@ -247,6 +251,7 @@ void statement_list_typecheckt::typecheck_function_var_decls(
247
251
code_typet::parametert param{declaration.variable .type ()};
248
252
param.set_identifier (param_sym.name );
249
253
param.set_base_name (declaration.variable .get_identifier ());
254
+ param.set (ID_statement_list_type, var_property);
250
255
params.push_back (param);
251
256
}
252
257
}
@@ -274,15 +279,23 @@ void statement_list_typecheckt::typecheck_temp_var_decls(
274
279
}
275
280
276
281
void statement_list_typecheckt::typecheck_statement_list_networks (
277
- const statement_list_parse_treet::networkst &networks ,
278
- symbolt &tia_element )
282
+ const statement_list_parse_treet::tia_modulet &tia_module ,
283
+ symbolt &tia_symbol )
279
284
{
280
- for (const auto &network : networks)
285
+ // Leave value empty if there are no networks to iterate through.
286
+ if (tia_module.networks .empty ())
287
+ return ;
288
+ if (tia_symbol.value .is_nil ())
289
+ tia_symbol.value = code_blockt{};
290
+
291
+ typecheck_temp_var_decls (tia_module, tia_symbol);
292
+
293
+ for (const auto &network : tia_module.networks )
281
294
{
282
295
// Set RLO to true each time a new network is entered (TIA behaviour).
283
296
rlo_bit = true_exprt ();
284
297
for (const auto &instruction : network.instructions )
285
- typecheck_statement_list_instruction (instruction, tia_element );
298
+ typecheck_statement_list_instruction (instruction, tia_symbol );
286
299
}
287
300
}
288
301
@@ -1249,9 +1262,10 @@ void statement_list_typecheckt::typecheck_called_function(
1249
1262
symbolt &tia_element)
1250
1263
{
1251
1264
const symbol_exprt call_operand{to_symbol_expr (op_code.op0 ())};
1252
- const symbolt &called_function {
1265
+ const symbolt &called_function_sym {
1253
1266
symbol_table.lookup_ref (call_operand.get_identifier ())};
1254
- const code_typet &called_type{to_code_type (called_function.type )};
1267
+ const symbol_exprt called_function_expr{called_function_sym.symbol_expr ()};
1268
+ const code_typet &called_type{to_code_type (called_function_sym.type )};
1255
1269
1256
1270
// Check if function name is followed by data block.
1257
1271
if (!can_cast_expr<equal_exprt>(op_code.op1 ()))
@@ -1275,11 +1289,22 @@ void statement_list_typecheckt::typecheck_called_function(
1275
1289
1276
1290
for (const code_typet::parametert ¶m : params)
1277
1291
{
1278
- const exprt &arg{typecheck_function_call_arguments (assignments, param)};
1292
+ const exprt &arg{
1293
+ typecheck_function_call_arguments (assignments, param, tia_element)};
1279
1294
args.push_back (arg);
1280
1295
}
1281
- const code_function_callt call{call_operand, args};
1282
- tia_element.value .add_to_operands (call);
1296
+
1297
+ // Check the return value if present.
1298
+ if (called_type.return_type ().is_nil ())
1299
+ tia_element.value .add_to_operands (
1300
+ code_function_callt{called_function_expr, args});
1301
+ else
1302
+ {
1303
+ const exprt lhs{typecheck_return_value_assignment (
1304
+ assignments, called_type.return_type (), tia_element)};
1305
+ tia_element.value .add_to_operands (
1306
+ code_function_callt{lhs, called_function_expr, args});
1307
+ }
1283
1308
}
1284
1309
1285
1310
void statement_list_typecheckt::typecheck_called_function_block (
@@ -1296,23 +1321,60 @@ void statement_list_typecheckt::typecheck_called_function_block(
1296
1321
1297
1322
exprt statement_list_typecheckt::typecheck_function_call_arguments (
1298
1323
const std::vector<equal_exprt> &assignments,
1299
- const code_typet::parametert ¶m)
1324
+ const code_typet::parametert ¶m,
1325
+ const symbolt &tia_element)
1326
+ {
1327
+ const irep_idt ¶m_name = param.get_base_name ();
1328
+ const typet ¶m_type = param.type ();
1329
+ for (const equal_exprt &assignment : assignments)
1330
+ {
1331
+ const symbol_exprt &lhs{to_symbol_expr (assignment.lhs ())};
1332
+ if (param_name == lhs.get_identifier ())
1333
+ {
1334
+ const symbol_exprt &rhs{to_symbol_expr (assignment.rhs ())};
1335
+ const exprt assigned_variable{
1336
+ typecheck_identifier (tia_element, rhs.get_identifier ())};
1337
+ if (param_type == assigned_variable.type ())
1338
+ return assigned_variable;
1339
+ else
1340
+ {
1341
+ error () << " Types of parameter assignment do not match: "
1342
+ << param.type ().id () << " != " << assigned_variable.type ().id ()
1343
+ << eom;
1344
+ throw TYPECHECK_ERROR;
1345
+ }
1346
+ }
1347
+ }
1348
+ error () << " No assignment found for function parameter "
1349
+ << param.get_identifier () << eom;
1350
+ throw TYPECHECK_ERROR;
1351
+ }
1352
+
1353
+ exprt statement_list_typecheckt::typecheck_return_value_assignment (
1354
+ const std::vector<equal_exprt> &assignments,
1355
+ const typet &return_type,
1356
+ const symbolt &tia_element)
1300
1357
{
1301
1358
for (const equal_exprt &assignment : assignments)
1302
1359
{
1303
1360
const symbol_exprt &lhs{to_symbol_expr (assignment.lhs ())};
1304
- if (param. get_identifier () == lhs.get_identifier ())
1361
+ if (ID_statement_list_return_value_id == lhs.get_identifier ())
1305
1362
{
1306
- if (param.type () == assignment.rhs ().type ())
1307
- return assignment.rhs ();
1363
+ const symbol_exprt &rhs{to_symbol_expr (assignment.rhs ())};
1364
+ const exprt assigned_variable{
1365
+ typecheck_identifier (tia_element, rhs.get_identifier ())};
1366
+ if (return_type == assigned_variable.type ())
1367
+ return assigned_variable;
1308
1368
else
1309
1369
{
1310
- error () << " Types of parameter assignment do not match" << eom;
1370
+ error () << " Types of return value assignment do not match: "
1371
+ << return_type.id () << " != " << assigned_variable.type ().id ()
1372
+ << eom;
1311
1373
throw TYPECHECK_ERROR;
1312
1374
}
1313
1375
}
1314
1376
}
1315
- error () << " No assignment found for function parameter " << eom;
1377
+ error () << " No assignment found for function return value " << eom;
1316
1378
throw TYPECHECK_ERROR;
1317
1379
}
1318
1380
0 commit comments