262 /* If there is no other parameter declared, then we are passing too many parameters... */ |
262 /* If there is no other parameter declared, then we are passing too many parameters... */ |
263 /* This error should have been caught in data type verification, so we simply abandon our check! */ |
263 /* This error should have been caught in data type verification, so we simply abandon our check! */ |
264 if(param_name == NULL) return; |
264 if(param_name == NULL) return; |
265 } while ((strcmp(param_name->value, "EN") == 0) || (strcmp(param_name->value, "ENO") == 0)); |
265 } while ((strcmp(param_name->value, "EN") == 0) || (strcmp(param_name->value, "ENO") == 0)); |
266 |
266 |
267 /* Find the corresponding parameter in function declaration, and it's direction (IN, OUT, IN_OUT) */ |
267 /* Determine the direction (IN, OUT, IN_OUT) of the parameter... */ |
268 function_param_iterator_c::param_direction_t param_direction = fp_iterator.param_direction(); |
268 function_param_iterator_c::param_direction_t param_direction = fp_iterator.param_direction(); |
269 |
269 |
270 /* We only check if 'call_param_value' is a valid lvalue if the value is being passed |
270 /* We only check if 'call_param_value' is a valid lvalue if the value is being passed |
271 * to a valid paramater of the function being called, and that parameter is either OUT or IN_OUT. |
271 * to a valid paramater of the function being called, and that parameter is either OUT or IN_OUT. |
272 */ |
272 */ |
388 current_il_operand = NULL; |
388 current_il_operand = NULL; |
389 return NULL; |
389 return NULL; |
390 } |
390 } |
391 |
391 |
392 |
392 |
|
393 |
|
394 |
|
395 /* | function_name [il_operand_list] */ |
|
396 /* NOTE: The parameters 'called_function_declaration' and 'extensible_param_count' are used to pass data between the stage 3 and stage 4. */ |
|
397 // SYM_REF2(il_function_call_c, function_name, il_operand_list, symbol_c *called_function_declaration; int extensible_param_count;) |
|
398 void *lvalue_check_c::visit(il_function_call_c *symbol) { |
|
399 /* The first parameter of a non formal function call in IL will be the 'current value' (i.e. the prev_il_instruction) |
|
400 * In order to be able to handle this without coding special cases, we will simply prepend that symbol |
|
401 * to the il_operand_list, and remove it after calling handle_function_call(). |
|
402 * |
|
403 * However, if no further paramters are given, then il_operand_list will be NULL, and we will |
|
404 * need to create a new object to hold the pointer to prev_il_instruction. |
|
405 * This change will also be undone at the end of this method. |
|
406 */ |
|
407 /* TODO: Copying the location data will result in confusing error message. |
|
408 * We need to make this better, by inserting code to handle this special situation explicitly! |
|
409 */ |
|
410 /* NOTE: When calling a function, using the 'current value' as the first parameter of the function invocation |
|
411 * implies that we can only call functions whose first parameter is IN. It would not do to pass |
|
412 * the 'current value' to an OUT or IN_OUT parameter. |
|
413 * In order to make sure that this will be caught by the check_nonformal_call() function, |
|
414 * we add a symbol that cannot be an lvalue; in this case, a real_c (REAL literal). |
|
415 */ |
|
416 real_c param_value(NULL); |
|
417 *((symbol_c *)(¶m_value)) = *((symbol_c *)symbol); /* copy the symbol location (file, line, offset) data */ |
|
418 if (NULL == symbol->il_operand_list) symbol->il_operand_list = new il_operand_list_c; |
|
419 if (NULL == symbol->il_operand_list) ERROR; |
|
420 ((list_c *)symbol->il_operand_list)->insert_element(¶m_value, 0); |
|
421 |
|
422 check_nonformal_call(symbol, symbol->called_function_declaration); |
|
423 |
|
424 /* Undo the changes to the abstract syntax tree we made above... */ |
|
425 ((list_c *)symbol->il_operand_list)->remove_element(0); |
|
426 if (((list_c *)symbol->il_operand_list)->n == 0) { |
|
427 /* if the list becomes empty, then that means that it did not exist before we made these changes, so we delete it! */ |
|
428 delete symbol->il_operand_list; |
|
429 symbol->il_operand_list = NULL; |
|
430 } |
|
431 |
|
432 return NULL; |
|
433 } |
|
434 |
|
435 |
|
436 |
|
437 |
|
438 |
|
439 |
|
440 /* il_call_operator prev_declared_fb_name |
|
441 * | il_call_operator prev_declared_fb_name '(' ')' |
|
442 * | il_call_operator prev_declared_fb_name '(' eol_list ')' |
|
443 * | il_call_operator prev_declared_fb_name '(' il_operand_list ')' |
|
444 * | il_call_operator prev_declared_fb_name '(' eol_list il_param_list ')' |
|
445 */ |
|
446 /* NOTE: The parameter 'called_fb_declaration'is used to pass data between stage 3 and stage4 (although currently it is not used in stage 4 */ |
|
447 // SYM_REF4(il_fb_call_c, il_call_operator, fb_name, il_operand_list, il_param_list, symbol_c *called_fb_declaration) |
|
448 void *lvalue_check_c::visit(il_fb_call_c *symbol) { |
|
449 if (NULL != symbol->il_operand_list) check_nonformal_call(symbol, symbol->called_fb_declaration); |
|
450 if (NULL != symbol-> il_param_list) check_formal_call(symbol, symbol->called_fb_declaration); |
|
451 return NULL; |
|
452 } |
|
453 |
|
454 |
|
455 /* | function_name '(' eol_list [il_param_list] ')' */ |
|
456 /* NOTE: The parameter 'called_function_declaration' is used to pass data between the stage 3 and stage 4. */ |
|
457 // SYM_REF2(il_formal_funct_call_c, function_name, il_param_list, symbol_c *called_function_declaration; int extensible_param_count;) |
|
458 void *lvalue_check_c::visit(il_formal_funct_call_c *symbol) { |
|
459 check_formal_call(symbol, symbol->called_function_declaration); |
|
460 return NULL; |
|
461 } |
|
462 |
|
463 |
|
464 |
|
465 |
|
466 |
|
467 |
393 /*******************/ |
468 /*******************/ |
394 /* B 2.2 Operators */ |
469 /* B 2.2 Operators */ |
395 /*******************/ |
470 /*******************/ |
396 void *lvalue_check_c::visit(ST_operator_c *symbol) { |
471 void *lvalue_check_c::visit(ST_operator_c *symbol) { |
397 verify_is_lvalue(current_il_operand); |
472 verify_is_lvalue(current_il_operand); |