diff -r 0e09a8840c92 -r 744b125d911e stage3/narrow_candidate_datatypes.cc --- a/stage3/narrow_candidate_datatypes.cc Wed Feb 08 18:33:01 2012 +0000 +++ b/stage3/narrow_candidate_datatypes.cc Fri Feb 10 19:04:31 2012 +0000 @@ -182,6 +182,59 @@ } +/* +typedef struct { + symbol_c *function_name, + symbol_c *nonformal_operand_list, + symbol_c * formal_operand_list, + + std::vector &candidate_functions, + symbol_c &*called_function_declaration, + int &extensible_param_count +} generic_function_call_t; +*/ +void narrow_candidate_datatypes_c::narrow_function_invocation(symbol_c *fcall, generic_function_call_t fcall_data) { + /* set the called_function_declaration. */ + fcall_data.called_function_declaration = NULL; + + /* set the called_function_declaration taking into account the datatype that we need to return */ + for(unsigned int i = 0; i < fcall->candidate_datatypes.size(); i++) { + if (is_type_equal(fcall->candidate_datatypes[i], fcall->datatype)) { + fcall_data.called_function_declaration = fcall_data.candidate_functions[i]; + break; + } + } + + /* NOTE: If we can't figure out the declaration of the function being called, this is not + * necessarily an internal compiler error. It could be because the symbol->datatype is NULL + * (because the ST code being analysed has an error _before_ this function invocation). + * However, we don't just give, up, we carry on recursivly analysing the code, so as to be + * able to print out any error messages related to the parameters being passed in this function + * invocation. + */ + /* if (NULL == symbol->called_function_declaration) ERROR; */ + if (fcall->candidate_datatypes.size() == 1) { + /* If only one function declaration, then we use that (even if symbol->datatypes == NULL) + * so we can check for errors in the expressions used to pass parameters in this + * function invocation. + */ + fcall_data.called_function_declaration = fcall_data.candidate_functions[0]; + } + + /* If an overloaded function is being invoked, and we cannot determine which version to use, + * then we can not meaningfully verify the expressions used inside that function invocation. + * We simply give up! + */ + if (NULL == fcall_data.called_function_declaration) + return; + + if (NULL != fcall_data.nonformal_operand_list) narrow_nonformal_call(fcall, fcall_data.called_function_declaration, &(fcall_data.extensible_param_count)); + if (NULL != fcall_data. formal_operand_list) narrow_formal_call(fcall, fcall_data.called_function_declaration, &(fcall_data.extensible_param_count)); + + return; +} + + /* a helper function... */ symbol_c *narrow_candidate_datatypes_c::base_type(symbol_c *symbol) { @@ -324,7 +377,27 @@ return NULL; } +/* | function_name [il_operand_list] */ +/* NOTE: The parameters 'called_function_declaration' and 'extensible_param_count' are used to pass data between the stage 3 and stage 4. */ +// SYM_REF2(il_function_call_c, function_name, il_operand_list, symbol_c *called_function_declaration; int extensible_param_count;) void *narrow_candidate_datatypes_c::visit(il_function_call_c *symbol) { + generic_function_call_t fcall_param = { + /* fcall_param.function_name = */ symbol->function_name, + /* fcall_param.nonformal_operand_list = */ symbol->il_operand_list, + /* fcall_param.formal_operand_list = */ NULL, + /* fcall_param.candidate_functions = */ symbol->candidate_functions, + /* fcall_param.called_function_declaration = */ symbol->called_function_declaration, + /* fcall_param.extensible_param_count = */ symbol->extensible_param_count + }; + + /* The first parameter of a non formal function call in IL will be the 'current value' (i.e. the prev_il_instruction) + * In order to be able to handle this without coding special cases, we simply prepend that symbol + * to the il_operand_list (done in fill_candidate_datatypes_c), and remove it later (in the print_datatypes_error_c). + * + * Since this class is executed after fill_candidate_datatypes_c, and before print_datatypes_error_c, + * the following code is actually correct! + */ + narrow_function_invocation(symbol, fcall_param); return NULL; } @@ -345,7 +418,20 @@ return NULL; } +/* | function_name '(' eol_list [il_param_list] ')' */ +/* NOTE: The parameter 'called_function_declaration' is used to pass data between the stage 3 and stage 4. */ +// SYM_REF2(il_formal_funct_call_c, function_name, il_param_list, symbol_c *called_function_declaration; int extensible_param_count;) void *narrow_candidate_datatypes_c::visit(il_formal_funct_call_c *symbol) { + generic_function_call_t fcall_param = { + /* fcall_param.function_name = */ symbol->function_name, + /* fcall_param.nonformal_operand_list = */ NULL, + /* fcall_param.formal_operand_list = */ symbol->il_param_list, + /* fcall_param.candidate_functions = */ symbol->candidate_functions, + /* fcall_param.called_function_declaration = */ symbol->called_function_declaration, + /* fcall_param.extensible_param_count = */ symbol->extensible_param_count + }; + + narrow_function_invocation(symbol, fcall_param); return NULL; } @@ -1020,47 +1106,22 @@ } + +/* NOTE: The parameter 'called_function_declaration', 'extensible_param_count' and 'candidate_functions' are used to pass data between the stage 3 and stage 4. */ +/* formal_param_list -> may be NULL ! */ +/* nonformal_param_list -> may be NULL ! */ +// SYM_REF3(function_invocation_c, function_name, formal_param_list, nonformal_param_list, symbol_c *called_function_declaration; int extensible_param_count; std::vector candidate_functions;) void *narrow_candidate_datatypes_c::visit(function_invocation_c *symbol) { - int ext_parm_count; - - /* set the called_function_declaration. */ - symbol->called_function_declaration = NULL; - - /* set the called_function_declaration taking into account the datatype that we need to return */ - for(unsigned int i = 0; i < symbol->candidate_datatypes.size(); i++) { - if (is_type_equal(symbol->candidate_datatypes[i], symbol->datatype)) { - symbol->called_function_declaration = symbol->candidate_functions[i]; - break; - } - } - - /* NOTE: If we can't figure out the declaration of the function being called, this is not - * necessarily an internal compiler error. It could be because the symbol->datatype is NULL - * (because the ST code being analysed has an error _before_ this function invocation). - * However, we don't just give, up, we carry on recursivly analysing the code, so as to be - * able to print out any error messages related to the parameters being passed in this function - * invocation. - */ - /* if (NULL == symbol->called_function_declaration) ERROR; */ - if (symbol->candidate_datatypes.size() == 1) { - /* If only one function declaration, then we use that (even if symbol->datatypes == NULL) - * so we can check for errors in the expressions used to pass parameters in this - * function invocation. - */ - symbol->called_function_declaration = symbol->candidate_functions[0]; - } - - /* If an overloaded function is being invoked, and we cannot determine which version to use, - * then we can not meaningfully verify the expressions used inside that function invocation. - * We simply give up! - */ - if (NULL == symbol->called_function_declaration) - return NULL; - - if (NULL != symbol->nonformal_param_list) narrow_nonformal_call(symbol, symbol->called_function_declaration, &ext_parm_count); - if (NULL != symbol-> formal_param_list) narrow_formal_call(symbol, symbol->called_function_declaration, &ext_parm_count); - symbol->extensible_param_count = ext_parm_count; - + generic_function_call_t fcall_param = { + /* fcall_param.function_name = */ symbol->function_name, + /* fcall_param.nonformal_operand_list = */ symbol->nonformal_param_list, + /* fcall_param.formal_operand_list = */ symbol->formal_param_list, + /* fcall_param.candidate_functions = */ symbol->candidate_functions, + /* fcall_param.called_function_declaration = */ symbol->called_function_declaration, + /* fcall_param.extensible_param_count = */ symbol->extensible_param_count + }; + + narrow_function_invocation(symbol, fcall_param); return NULL; }