stage3/narrow_candidate_datatypes.cc
changeset 438 744b125d911e
parent 428 42d02558ebd9
child 439 cf7d6862033d
equal deleted inserted replaced
437:0e09a8840c92 438:744b125d911e
   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 */