88 */ |
88 */ |
89 if (symbol == NULL) return NULL; |
89 if (symbol == NULL) return NULL; |
90 return (symbol_c *)symbol->accept(search_base_type); |
90 return (symbol_c *)symbol->accept(search_base_type); |
91 } |
91 } |
92 |
92 |
|
93 |
|
94 |
|
95 |
|
96 /* |
|
97 typedef struct { |
|
98 symbol_c *function_name, |
|
99 symbol_c *nonformal_operand_list, |
|
100 symbol_c * formal_operand_list, |
|
101 |
|
102 std::vector <symbol_c *> &candidate_functions, |
|
103 symbol_c &*called_function_declaration, |
|
104 int &extensible_param_count |
|
105 } generic_function_call_t; |
|
106 */ |
|
107 void print_datatypes_error_c::handle_function_invocation(symbol_c *fcall, generic_function_call_t fcall_data) { |
|
108 symbol_c *param_value, *param_name; |
|
109 function_call_param_iterator_c fcp_iterator(fcall); |
|
110 bool function_invocation_error = false; |
|
111 |
|
112 if ((NULL != fcall_data.formal_operand_list) && (NULL != fcall_data.nonformal_operand_list)) |
|
113 ERROR; |
|
114 |
|
115 symbol_c *f_decl = fcall_data.called_function_declaration; |
|
116 if (NULL == f_decl) { |
|
117 STAGE3_ERROR(0, fcall, fcall, "Unable to resolve which overloaded function '%s' is being invoked.", ((identifier_c *)fcall_data.function_name)->value); |
|
118 /* we now try to find any function declaration with the same name, just so we can provide some relevant error messages */ |
|
119 function_symtable_t::iterator lower = function_symtable.lower_bound(fcall_data.function_name); |
|
120 if (lower == function_symtable.end()) ERROR; |
|
121 f_decl = function_symtable.get_value(lower); |
|
122 } |
|
123 |
|
124 if (NULL != fcall_data.formal_operand_list) { |
|
125 fcall_data.formal_operand_list->accept(*this); |
|
126 if (NULL != f_decl) { |
|
127 function_param_iterator_c fp_iterator(f_decl); |
|
128 while ((param_name = fcp_iterator.next_f()) != NULL) { |
|
129 param_value = fcp_iterator.get_current_value(); |
|
130 /* Find the corresponding parameter in function declaration */ |
|
131 if (NULL == fp_iterator.search(param_name)) { |
|
132 STAGE3_ERROR(0, fcall, fcall, "Invalid parameter '%s' when invoking function '%s'", ((identifier_c *)param_name)->value, ((identifier_c *)fcall_data.function_name)->value); |
|
133 } else if (NULL == param_value->datatype) { |
|
134 function_invocation_error = true; |
|
135 STAGE3_ERROR(0, fcall, fcall, "Data type incompatibility between parameter '%s' and value being passed, when invoking function '%s'", ((identifier_c *)param_name)->value, ((identifier_c *)fcall_data.function_name)->value); |
|
136 } |
|
137 } |
|
138 } |
|
139 } |
|
140 if (NULL != fcall_data.nonformal_operand_list) { |
|
141 fcall_data.nonformal_operand_list->accept(*this); |
|
142 if (f_decl) |
|
143 for (int i = 1; (param_value = fcp_iterator.next_nf()) != NULL; i++) { |
|
144 if (NULL == param_value->datatype) { |
|
145 function_invocation_error = true; |
|
146 STAGE3_ERROR(0, fcall, fcall, "Data type incompatibility for value passed in position %d when invoking function '%s'", i, ((identifier_c *)fcall_data.function_name)->value); |
|
147 } |
|
148 } |
|
149 } |
|
150 |
|
151 if (function_invocation_error) { |
|
152 /* No compatible function exists */ |
|
153 STAGE3_ERROR(2, fcall, fcall, "Invalid parameters when invoking function '%s'", ((identifier_c *)fcall_data.function_name)->value); |
|
154 } |
|
155 |
|
156 return; |
|
157 } |
|
158 |
|
159 |
|
160 |
|
161 |
|
162 |
93 /*********************/ |
163 /*********************/ |
94 /* B 1.2 - Constants */ |
164 /* B 1.2 - Constants */ |
95 /*********************/ |
165 /*********************/ |
96 /******************************/ |
166 /******************************/ |
97 /* B 1.2.1 - Numeric Literals */ |
167 /* B 1.2.1 - Numeric Literals */ |
442 symbol->il_simple_operator->accept(*this); |
512 symbol->il_simple_operator->accept(*this); |
443 il_operand = NULL; |
513 il_operand = NULL; |
444 return NULL; |
514 return NULL; |
445 } |
515 } |
446 |
516 |
|
517 /* | function_name [il_operand_list] */ |
|
518 /* NOTE: The parameters 'called_function_declaration' and 'extensible_param_count' are used to pass data between the stage 3 and stage 4. */ |
|
519 // SYM_REF2(il_function_call_c, function_name, il_operand_list, symbol_c *called_function_declaration; int extensible_param_count;) |
447 void *print_datatypes_error_c::visit(il_function_call_c *symbol) { |
520 void *print_datatypes_error_c::visit(il_function_call_c *symbol) { |
|
521 generic_function_call_t fcall_param = { |
|
522 /* fcall_param.function_name = */ symbol->function_name, |
|
523 /* fcall_param.nonformal_operand_list = */ symbol->il_operand_list, |
|
524 /* fcall_param.formal_operand_list = */ NULL, |
|
525 /* fcall_param.candidate_functions = */ symbol->candidate_functions, |
|
526 /* fcall_param.called_function_declaration = */ symbol->called_function_declaration, |
|
527 /* fcall_param.extensible_param_count = */ symbol->extensible_param_count |
|
528 }; |
|
529 |
|
530 handle_function_invocation(symbol, fcall_param); |
|
531 |
|
532 /* The first parameter of a non formal function call in IL will be the 'current value' (i.e. the prev_il_instruction) |
|
533 * In order to be able to handle this without coding special cases, we will simply prepend that symbol |
|
534 * to the il_operand_list. This is done in fill_candidate_datatypes_c. |
|
535 * We now undo those changes! |
|
536 */ |
|
537 ((list_c *)symbol->il_operand_list)->remove_element(0); |
|
538 if (((list_c *)symbol->il_operand_list)->n == 0) { |
|
539 /* if the list becomes empty, then that means that it did not exist before we made these changes, so we delete it! */ |
|
540 delete symbol->il_operand_list; |
|
541 symbol->il_operand_list = NULL; |
|
542 } |
|
543 |
448 return NULL; |
544 return NULL; |
449 } |
545 } |
450 |
546 |
451 void *print_datatypes_error_c::visit(il_expression_c *symbol) { |
547 void *print_datatypes_error_c::visit(il_expression_c *symbol) { |
452 return NULL; |
548 return NULL; |
454 |
550 |
455 void *print_datatypes_error_c::visit(il_fb_call_c *symbol) { |
551 void *print_datatypes_error_c::visit(il_fb_call_c *symbol) { |
456 return NULL; |
552 return NULL; |
457 } |
553 } |
458 |
554 |
|
555 /* | function_name '(' eol_list [il_param_list] ')' */ |
|
556 /* NOTE: The parameter 'called_function_declaration' is used to pass data between the stage 3 and stage 4. */ |
|
557 // SYM_REF2(il_formal_funct_call_c, function_name, il_param_list, symbol_c *called_function_declaration; int extensible_param_count;) |
459 void *print_datatypes_error_c::visit(il_formal_funct_call_c *symbol) { |
558 void *print_datatypes_error_c::visit(il_formal_funct_call_c *symbol) { |
|
559 generic_function_call_t fcall_param = { |
|
560 /* fcall_param.function_name = */ symbol->function_name, |
|
561 /* fcall_param.nonformal_operand_list = */ NULL, |
|
562 /* fcall_param.formal_operand_list = */ symbol->il_param_list, |
|
563 /* fcall_param.candidate_functions = */ symbol->candidate_functions, |
|
564 /* fcall_param.called_function_declaration = */ symbol->called_function_declaration, |
|
565 /* fcall_param.extensible_param_count = */ symbol->extensible_param_count |
|
566 }; |
|
567 |
|
568 handle_function_invocation(symbol, fcall_param); |
460 return NULL; |
569 return NULL; |
461 } |
570 } |
462 |
571 |
463 |
572 |
464 /* |
573 /* |