stage3/print_datatypes_error.cc
changeset 449 3c6225521059
parent 448 1bd18fc06911
child 451 a1b87eb155e4
equal deleted inserted replaced
448:1bd18fc06911 449:3c6225521059
   122 		/* Due to the way the syntax analysis is buit (i.e. stage 2), this should never occur. */
   122 		/* Due to the way the syntax analysis is buit (i.e. stage 2), this should never occur. */
   123 		/* I.e., a FB invocation using an undefined FB variable is not possible in the current implementation of stage 2. */
   123 		/* I.e., a FB invocation using an undefined FB variable is not possible in the current implementation of stage 2. */
   124 		ERROR;
   124 		ERROR;
   125 	}
   125 	}
   126 	if (NULL == f_decl) {
   126 	if (NULL == f_decl) {
   127 		STAGE3_ERROR(0, fcall, fcall, "Unable to resolve which overloaded %s '%s' is being invoked.", POU_str, ((identifier_c *)fcall_data.function_name)->value);
       
   128 		/* we now try to find any function declaration with the same name, just so we can provide some relevant error messages */
   127 		/* we now try to find any function declaration with the same name, just so we can provide some relevant error messages */
   129 		function_symtable_t::iterator lower = function_symtable.lower_bound(fcall_data.function_name);
   128 		function_symtable_t::iterator lower = function_symtable.lower_bound(fcall_data.function_name);
   130 		if (lower == function_symtable.end()) ERROR;
   129 		if (lower == function_symtable.end()) ERROR;
   131 		f_decl = function_symtable.get_value(lower);
   130 		f_decl = function_symtable.get_value(lower);
   132 	}
   131 	}
   134 	if (NULL != fcall_data.formal_operand_list) {
   133 	if (NULL != fcall_data.formal_operand_list) {
   135 		fcall_data.formal_operand_list->accept(*this);
   134 		fcall_data.formal_operand_list->accept(*this);
   136 		if (NULL != f_decl) {
   135 		if (NULL != f_decl) {
   137 			function_param_iterator_c fp_iterator(f_decl);
   136 			function_param_iterator_c fp_iterator(f_decl);
   138 			while ((param_name = fcp_iterator.next_f()) != NULL) {
   137 			while ((param_name = fcp_iterator.next_f()) != NULL) {
   139 #if 0
       
   140 /* TODO: check whether direction (IN, OUT, IN_OUT) and assignment types (:= , =>) are compatible !!! */
       
   141 
       
   142 
       
   143 /* TODO: Check if there are duplicat parameter values */
       
   144 		verify_duplicate_param = fcp_iterator.search_f(call_param_name);
       
   145 		if(verify_duplicate_param != call_param_value)
       
   146 			return false;
       
   147 #endif
       
   148 				param_value = fcp_iterator.get_current_value();
   138 				param_value = fcp_iterator.get_current_value();
       
   139 
       
   140 				/* Check if there are duplicate parameter values */
       
   141 				if(fcp_iterator.search_f(param_name) != param_value) {
       
   142 					function_invocation_error = true;
       
   143 					STAGE3_ERROR(0, param_name, param_name, "Duplicate parameter '%s' when invoking %s '%s'", ((identifier_c *)param_name)->value, POU_str, ((identifier_c *)fcall_data.function_name)->value);
       
   144 					continue; /* jump to next parameter */
       
   145 				}
       
   146 
   149 				/* Find the corresponding parameter in function declaration */
   147 				/* Find the corresponding parameter in function declaration */
   150 				if (NULL == fp_iterator.search(param_name)) {
   148 				if (NULL == fp_iterator.search(param_name)) {
   151 					STAGE3_ERROR(0, param_name, param_name, "Invalid parameter '%s' when invoking %s '%s'", ((identifier_c *)param_name)->value, POU_str, ((identifier_c *)fcall_data.function_name)->value);		  
   149 					function_invocation_error = true;
   152 				} else if (NULL == param_value->datatype) {
   150 					STAGE3_ERROR(0, param_name, param_name, "Invalid parameter '%s' when invoking %s '%s'", ((identifier_c *)param_name)->value, POU_str, ((identifier_c *)fcall_data.function_name)->value);
       
   151 					continue; /* jump to next parameter */
       
   152 				} 
       
   153 
       
   154 				/* check whether direction (IN, OUT, IN_OUT) and assignment types (:= , =>) are compatible !!! */
       
   155 				/* Obtaining the assignment direction:  := (assign_in) or => (assign_out) */
       
   156 				function_call_param_iterator_c::assign_direction_t call_param_dir = fcp_iterator.get_assign_direction();
       
   157 				/* Get the parameter direction: IN, OUT, IN_OUT */
       
   158 				function_param_iterator_c::param_direction_t param_dir = fp_iterator.param_direction();
       
   159 				if          (function_call_param_iterator_c::assign_in  == call_param_dir) {
       
   160 					if ((function_param_iterator_c::direction_in    != param_dir) &&
       
   161 					    (function_param_iterator_c::direction_inout != param_dir)) {
       
   162 						function_invocation_error = true;
       
   163 						STAGE3_ERROR(0, param_name, param_name, "Invalid assignment syntax ':=' used for parameter '%s', when invoking %s '%s'", ((identifier_c *)param_name)->value, POU_str, ((identifier_c *)fcall_data.function_name)->value);
       
   164 						continue; /* jump to next parameter */
       
   165 					}
       
   166 				} else if   (function_call_param_iterator_c::assign_out == call_param_dir) {
       
   167 					if ((function_param_iterator_c::direction_out   != param_dir)) {
       
   168 						function_invocation_error = true;
       
   169 						STAGE3_ERROR(0, param_name, param_name, "Invalid assignment syntax '=>' used for parameter '%s', when invoking %s '%s'", ((identifier_c *)param_name)->value, POU_str, ((identifier_c *)fcall_data.function_name)->value);
       
   170 						continue; /* jump to next parameter */
       
   171 					}
       
   172 				} else ERROR;
       
   173 
       
   174 				if (NULL == param_value->datatype) {
   153 					function_invocation_error = true;
   175 					function_invocation_error = true;
   154 					STAGE3_ERROR(0, param_value, param_value, "Data type incompatibility between parameter '%s' and value being passed, when invoking %s '%s'", ((identifier_c *)param_name)->value, POU_str, ((identifier_c *)fcall_data.function_name)->value);
   176 					STAGE3_ERROR(0, param_value, param_value, "Data type incompatibility between parameter '%s' and value being passed, when invoking %s '%s'", ((identifier_c *)param_name)->value, POU_str, ((identifier_c *)fcall_data.function_name)->value);
       
   177 					continue; /* jump to next parameter */
   155 				}
   178 				}
   156 			}
   179 			}
   157 		}
   180 		}
   158 	}
   181 	}
   159 	if (NULL != fcall_data.nonformal_operand_list) {
   182 	if (NULL != fcall_data.nonformal_operand_list) {
   163 				if (NULL == param_value->datatype) {
   186 				if (NULL == param_value->datatype) {
   164 					function_invocation_error = true;
   187 					function_invocation_error = true;
   165 					STAGE3_ERROR(0, param_value, param_value, "Data type incompatibility for value passed in position %d when invoking %s '%s'", i, POU_str, ((identifier_c *)fcall_data.function_name)->value);
   188 					STAGE3_ERROR(0, param_value, param_value, "Data type incompatibility for value passed in position %d when invoking %s '%s'", i, POU_str, ((identifier_c *)fcall_data.function_name)->value);
   166 				}
   189 				}
   167 			}
   190 			}
       
   191 	}
       
   192 
       
   193 	if (NULL == fcall_data.called_function_declaration) {
       
   194 		function_invocation_error = true;
       
   195 		STAGE3_ERROR(0, fcall, fcall, "Unable to resolve which overloaded %s '%s' is being invoked.", POU_str, ((identifier_c *)fcall_data.function_name)->value);
   168 	}
   196 	}
   169 
   197 
   170 	if (function_invocation_error) {
   198 	if (function_invocation_error) {
   171 		/* No compatible function exists */
   199 		/* No compatible function exists */
   172 		STAGE3_ERROR(2, fcall, fcall, "Invalid parameters when invoking %s '%s'", POU_str, ((identifier_c *)fcall_data.function_name)->value);
   200 		STAGE3_ERROR(2, fcall, fcall, "Invalid parameters when invoking %s '%s'", POU_str, ((identifier_c *)fcall_data.function_name)->value);