180 if ((NULL != ext_parm_count) && (extensible_parameter_highest_index >=0) /* if call to extensible function */) |
180 if ((NULL != ext_parm_count) && (extensible_parameter_highest_index >=0) /* if call to extensible function */) |
181 *ext_parm_count = 1 + extensible_parameter_highest_index - fp_iterator.first_extensible_param_index(); |
181 *ext_parm_count = 1 + extensible_parameter_highest_index - fp_iterator.first_extensible_param_index(); |
182 } |
182 } |
183 |
183 |
184 |
184 |
|
185 /* |
|
186 typedef struct { |
|
187 symbol_c *function_name, |
|
188 symbol_c *nonformal_operand_list, |
|
189 symbol_c * formal_operand_list, |
|
190 |
|
191 std::vector <symbol_c *> &candidate_functions, |
|
192 symbol_c &*called_function_declaration, |
|
193 int &extensible_param_count |
|
194 } generic_function_call_t; |
|
195 */ |
|
196 void narrow_candidate_datatypes_c::narrow_function_invocation(symbol_c *fcall, generic_function_call_t fcall_data) { |
|
197 /* set the called_function_declaration. */ |
|
198 fcall_data.called_function_declaration = NULL; |
|
199 |
|
200 /* set the called_function_declaration taking into account the datatype that we need to return */ |
|
201 for(unsigned int i = 0; i < fcall->candidate_datatypes.size(); i++) { |
|
202 if (is_type_equal(fcall->candidate_datatypes[i], fcall->datatype)) { |
|
203 fcall_data.called_function_declaration = fcall_data.candidate_functions[i]; |
|
204 break; |
|
205 } |
|
206 } |
|
207 |
|
208 /* NOTE: If we can't figure out the declaration of the function being called, this is not |
|
209 * necessarily an internal compiler error. It could be because the symbol->datatype is NULL |
|
210 * (because the ST code being analysed has an error _before_ this function invocation). |
|
211 * However, we don't just give, up, we carry on recursivly analysing the code, so as to be |
|
212 * able to print out any error messages related to the parameters being passed in this function |
|
213 * invocation. |
|
214 */ |
|
215 /* if (NULL == symbol->called_function_declaration) ERROR; */ |
|
216 if (fcall->candidate_datatypes.size() == 1) { |
|
217 /* If only one function declaration, then we use that (even if symbol->datatypes == NULL) |
|
218 * so we can check for errors in the expressions used to pass parameters in this |
|
219 * function invocation. |
|
220 */ |
|
221 fcall_data.called_function_declaration = fcall_data.candidate_functions[0]; |
|
222 } |
|
223 |
|
224 /* If an overloaded function is being invoked, and we cannot determine which version to use, |
|
225 * then we can not meaningfully verify the expressions used inside that function invocation. |
|
226 * We simply give up! |
|
227 */ |
|
228 if (NULL == fcall_data.called_function_declaration) |
|
229 return; |
|
230 |
|
231 if (NULL != fcall_data.nonformal_operand_list) narrow_nonformal_call(fcall, fcall_data.called_function_declaration, &(fcall_data.extensible_param_count)); |
|
232 if (NULL != fcall_data. formal_operand_list) narrow_formal_call(fcall, fcall_data.called_function_declaration, &(fcall_data.extensible_param_count)); |
|
233 |
|
234 return; |
|
235 } |
|
236 |
|
237 |
185 |
238 |
186 /* a helper function... */ |
239 /* a helper function... */ |
187 symbol_c *narrow_candidate_datatypes_c::base_type(symbol_c *symbol) { |
240 symbol_c *narrow_candidate_datatypes_c::base_type(symbol_c *symbol) { |
188 /* NOTE: symbol == NULL is valid. It will occur when, for e.g., an undefined/undeclared symbolic_variable is used |
241 /* NOTE: symbol == NULL is valid. It will occur when, for e.g., an undefined/undeclared symbolic_variable is used |
189 * in the code. |
242 * in the code. |
322 symbol->il_simple_operator->accept(*this); |
375 symbol->il_simple_operator->accept(*this); |
323 il_operand = NULL; |
376 il_operand = NULL; |
324 return NULL; |
377 return NULL; |
325 } |
378 } |
326 |
379 |
|
380 /* | function_name [il_operand_list] */ |
|
381 /* NOTE: The parameters 'called_function_declaration' and 'extensible_param_count' are used to pass data between the stage 3 and stage 4. */ |
|
382 // SYM_REF2(il_function_call_c, function_name, il_operand_list, symbol_c *called_function_declaration; int extensible_param_count;) |
327 void *narrow_candidate_datatypes_c::visit(il_function_call_c *symbol) { |
383 void *narrow_candidate_datatypes_c::visit(il_function_call_c *symbol) { |
|
384 generic_function_call_t fcall_param = { |
|
385 /* fcall_param.function_name = */ symbol->function_name, |
|
386 /* fcall_param.nonformal_operand_list = */ symbol->il_operand_list, |
|
387 /* fcall_param.formal_operand_list = */ NULL, |
|
388 /* fcall_param.candidate_functions = */ symbol->candidate_functions, |
|
389 /* fcall_param.called_function_declaration = */ symbol->called_function_declaration, |
|
390 /* fcall_param.extensible_param_count = */ symbol->extensible_param_count |
|
391 }; |
|
392 |
|
393 /* The first parameter of a non formal function call in IL will be the 'current value' (i.e. the prev_il_instruction) |
|
394 * In order to be able to handle this without coding special cases, we simply prepend that symbol |
|
395 * to the il_operand_list (done in fill_candidate_datatypes_c), and remove it later (in the print_datatypes_error_c). |
|
396 * |
|
397 * Since this class is executed after fill_candidate_datatypes_c, and before print_datatypes_error_c, |
|
398 * the following code is actually correct! |
|
399 */ |
|
400 narrow_function_invocation(symbol, fcall_param); |
328 return NULL; |
401 return NULL; |
329 } |
402 } |
330 |
403 |
331 /* MJS: Manuele, could you please not delete the following 2 lines of comments. They help me understand where this class is used |
404 /* MJS: Manuele, could you please not delete the following 2 lines of comments. They help me understand where this class is used |
332 * and when it is created by bison - syntax parse, and how it can show up in the abstract syntax tree. |
405 * and when it is created by bison - syntax parse, and how it can show up in the abstract syntax tree. |
343 |
416 |
344 void *narrow_candidate_datatypes_c::visit(il_fb_call_c *symbol) { |
417 void *narrow_candidate_datatypes_c::visit(il_fb_call_c *symbol) { |
345 return NULL; |
418 return NULL; |
346 } |
419 } |
347 |
420 |
|
421 /* | function_name '(' eol_list [il_param_list] ')' */ |
|
422 /* NOTE: The parameter 'called_function_declaration' is used to pass data between the stage 3 and stage 4. */ |
|
423 // SYM_REF2(il_formal_funct_call_c, function_name, il_param_list, symbol_c *called_function_declaration; int extensible_param_count;) |
348 void *narrow_candidate_datatypes_c::visit(il_formal_funct_call_c *symbol) { |
424 void *narrow_candidate_datatypes_c::visit(il_formal_funct_call_c *symbol) { |
|
425 generic_function_call_t fcall_param = { |
|
426 /* fcall_param.function_name = */ symbol->function_name, |
|
427 /* fcall_param.nonformal_operand_list = */ NULL, |
|
428 /* fcall_param.formal_operand_list = */ symbol->il_param_list, |
|
429 /* fcall_param.candidate_functions = */ symbol->candidate_functions, |
|
430 /* fcall_param.called_function_declaration = */ symbol->called_function_declaration, |
|
431 /* fcall_param.extensible_param_count = */ symbol->extensible_param_count |
|
432 }; |
|
433 |
|
434 narrow_function_invocation(symbol, fcall_param); |
349 return NULL; |
435 return NULL; |
350 } |
436 } |
351 |
437 |
352 |
438 |
353 /* |
439 /* |
1018 symbol->exp->accept(*this); |
1104 symbol->exp->accept(*this); |
1019 return NULL; |
1105 return NULL; |
1020 } |
1106 } |
1021 |
1107 |
1022 |
1108 |
|
1109 |
|
1110 /* NOTE: The parameter 'called_function_declaration', 'extensible_param_count' and 'candidate_functions' are used to pass data between the stage 3 and stage 4. */ |
|
1111 /* formal_param_list -> may be NULL ! */ |
|
1112 /* nonformal_param_list -> may be NULL ! */ |
|
1113 // SYM_REF3(function_invocation_c, function_name, formal_param_list, nonformal_param_list, symbol_c *called_function_declaration; int extensible_param_count; std::vector <symbol_c *> candidate_functions;) |
1023 void *narrow_candidate_datatypes_c::visit(function_invocation_c *symbol) { |
1114 void *narrow_candidate_datatypes_c::visit(function_invocation_c *symbol) { |
1024 int ext_parm_count; |
1115 generic_function_call_t fcall_param = { |
1025 |
1116 /* fcall_param.function_name = */ symbol->function_name, |
1026 /* set the called_function_declaration. */ |
1117 /* fcall_param.nonformal_operand_list = */ symbol->nonformal_param_list, |
1027 symbol->called_function_declaration = NULL; |
1118 /* fcall_param.formal_operand_list = */ symbol->formal_param_list, |
1028 |
1119 /* fcall_param.candidate_functions = */ symbol->candidate_functions, |
1029 /* set the called_function_declaration taking into account the datatype that we need to return */ |
1120 /* fcall_param.called_function_declaration = */ symbol->called_function_declaration, |
1030 for(unsigned int i = 0; i < symbol->candidate_datatypes.size(); i++) { |
1121 /* fcall_param.extensible_param_count = */ symbol->extensible_param_count |
1031 if (is_type_equal(symbol->candidate_datatypes[i], symbol->datatype)) { |
1122 }; |
1032 symbol->called_function_declaration = symbol->candidate_functions[i]; |
1123 |
1033 break; |
1124 narrow_function_invocation(symbol, fcall_param); |
1034 } |
|
1035 } |
|
1036 |
|
1037 /* NOTE: If we can't figure out the declaration of the function being called, this is not |
|
1038 * necessarily an internal compiler error. It could be because the symbol->datatype is NULL |
|
1039 * (because the ST code being analysed has an error _before_ this function invocation). |
|
1040 * However, we don't just give, up, we carry on recursivly analysing the code, so as to be |
|
1041 * able to print out any error messages related to the parameters being passed in this function |
|
1042 * invocation. |
|
1043 */ |
|
1044 /* if (NULL == symbol->called_function_declaration) ERROR; */ |
|
1045 if (symbol->candidate_datatypes.size() == 1) { |
|
1046 /* If only one function declaration, then we use that (even if symbol->datatypes == NULL) |
|
1047 * so we can check for errors in the expressions used to pass parameters in this |
|
1048 * function invocation. |
|
1049 */ |
|
1050 symbol->called_function_declaration = symbol->candidate_functions[0]; |
|
1051 } |
|
1052 |
|
1053 /* If an overloaded function is being invoked, and we cannot determine which version to use, |
|
1054 * then we can not meaningfully verify the expressions used inside that function invocation. |
|
1055 * We simply give up! |
|
1056 */ |
|
1057 if (NULL == symbol->called_function_declaration) |
|
1058 return NULL; |
|
1059 |
|
1060 if (NULL != symbol->nonformal_param_list) narrow_nonformal_call(symbol, symbol->called_function_declaration, &ext_parm_count); |
|
1061 if (NULL != symbol-> formal_param_list) narrow_formal_call(symbol, symbol->called_function_declaration, &ext_parm_count); |
|
1062 symbol->extensible_param_count = ext_parm_count; |
|
1063 |
|
1064 return NULL; |
1125 return NULL; |
1065 } |
1126 } |
1066 |
1127 |
1067 /********************/ |
1128 /********************/ |
1068 /* B 3.2 Statements */ |
1129 /* B 3.2 Statements */ |