stage3/lvalue_check.cc
changeset 509 35d391c38a30
parent 508 dc6906338042
child 510 9317e04c1dde
equal deleted inserted replaced
508:dc6906338042 509:35d391c38a30
    68 
    68 
    69 int lvalue_check_c::get_error_found() {
    69 int lvalue_check_c::get_error_found() {
    70 	return error_found;
    70 	return error_found;
    71 }
    71 }
    72 
    72 
       
    73 
       
    74 #include <strings.h>
    73 /* No writing to iterator variables (used in FOR loops) inside the loop itself */
    75 /* No writing to iterator variables (used in FOR loops) inside the loop itself */
    74 void lvalue_check_c::check_for_controlvar_assignment(symbolic_variable_c * lvalue) {
    76 void lvalue_check_c::check_assignment_to_controlvar(symbol_c *lvalue) {
    75 	for (unsigned int i = 0; i < control_variables.size(); i++) {
    77 	for (unsigned int i = 0; i < control_variables.size(); i++) {
    76 		symbolic_variable_c *cvar = (symbolic_variable_c *)control_variables[i];
    78 		symbolic_variable_c *cvar = (symbolic_variable_c *)control_variables[i];
    77 		if (strcasecmp(((identifier_c *)lvalue->var_name)->value, ((identifier_c *)cvar->var_name)->value) == 0) {
    79 		if (strcasecmp(((identifier_c *)((symbolic_variable_c *)lvalue)->var_name)->value, ((identifier_c *)((symbolic_variable_c *)cvar)->var_name)->value) == 0) {
    78 			STAGE3_ERROR(0, lvalue, lvalue, "Assignment to FOR control variable are not be allowed.");
    80 			STAGE3_ERROR(0, lvalue, lvalue, "Assignment to FOR control variable are not be allowed.");
    79 			break;
    81 			break;
    80 		}
    82 		}
    81 	}
    83 	}
    82 }
    84 }
    83 
    85 
       
    86 
    84 /* fb_instance.var := ...  is not valid if var is output (not input ??) variable */
    87 /* fb_instance.var := ...  is not valid if var is output (not input ??) variable */
    85 void lvalue_check_c::check_output_assignment(symbolic_variable_c * lvalue) {
    88 void lvalue_check_c::check_assignment_to_output(symbol_c * lvalue) {
    86 	symbol_c *type_id = search_varfb_instance_type->get_basetype_id(lvalue->var_name);
    89 	symbol_c *type_id = search_varfb_instance_type->get_basetype_id(lvalue);
    87 	if (NULL != type_id) {
    90 	if (NULL != type_id) {
    88 		function_block_declaration_c *fb_decl = function_block_type_symtable.find_value(type_id);
    91 		function_block_declaration_c *fb_decl = function_block_type_symtable.find_value(type_id);
    89 		if (function_block_type_symtable.end_value() != fb_decl) {
    92 		if (function_block_type_symtable.end_value() != fb_decl) {
    90 			search_var_instance_decl_c   search_var_instance_decl(fb_decl);
    93 			search_var_instance_decl_c   search_var_instance_decl(fb_decl);
    91 			structured_variable_c * str_var = (structured_variable_c *)lvalue;
    94 			structured_variable_c * str_var = (structured_variable_c *)lvalue;
    92 			unsigned int vartype = search_var_instance_decl.get_vartype(str_var->field_selector);
    95 			unsigned int vartype = search_var_instance_decl.get_vartype(str_var->field_selector);
    93 			if (vartype == search_var_instance_decl_c::output_vt)
    96 			if (vartype == search_var_instance_decl_c::output_vt)
    94 				STAGE3_ERROR(0, lvalue, lvalue, "Assignment to FB output field variable are not be allowed.");
    97 				STAGE3_ERROR(0, lvalue, lvalue, "Assignment to FB output field variable is not be allowed.");
    95 		}
    98 		}
    96 	}
    99 	}
    97 }
   100 }
    98 
   101 
       
   102 
    99 /*  No writing to CONSTANTs */
   103 /*  No writing to CONSTANTs */
   100 void lvalue_check_c::check_constant_assignment(symbolic_variable_c *lvalue) {
   104 void lvalue_check_c::check_assignment_to_constant(symbol_c *lvalue) {
   101 	unsigned int option = search_var_instance_decl->get_option(lvalue->var_name);
   105 	unsigned int option = search_var_instance_decl->get_option(lvalue);
   102 	if (option == search_var_instance_decl_c::constant_opt) {
   106 	if (option == search_var_instance_decl_c::constant_opt) {
   103 		STAGE3_ERROR(0, lvalue, lvalue, "Assignment to CONSTANT variables are not be allowed.");
   107 		STAGE3_ERROR(0, lvalue, lvalue, "Assignment to CONSTANT variables is not be allowed.");
   104 	}
   108 	}
   105 }
   109 }
   106 
   110 
   107 /* function_name(45)  will check whether the first parameter of the function is not an output variable. */
   111 
   108 /* function_name(var_name)  will check whether var_name is lvalue if the first parameter of the function is an output variable. */
   112 /*  No assigning values to expressions. */
   109 void lvalue_check_c::check_function_call_parameter(function_invocation_c *f_call) {
   113 void lvalue_check_c::check_assignment_to_expression(symbol_c *lvalue) {
   110 	function_declaration_c *f_decl;
   114 	/* TODO: check whether the lvalue is an expresion! */
   111 	identifier_c *param_name;
   115 	/* This may occur in function invocations, when passing values (possibly an expression) to one 
   112 	symbol_c *call_param_value;
   116 	 * of the function's OUTPUT parameters.
   113 
       
   114 	if (NULL == f_call)
       
   115 		return;
       
   116 	/* We use called_function_declaration and for this reason LVALUE
       
   117 	 * check must be run after DATA TYPE check
       
   118 	 */
   117 	 */
   119 	if (NULL == f_call->called_function_declaration)
   118 }
   120 		ERROR;
   119 
   121 	f_decl = (function_declaration_c *)f_call->called_function_declaration;
   120 
   122 	search_constant_type_c search_constant_type;
   121 
       
   122 void lvalue_check_c::verify_is_lvalue(symbol_c *lvalue) {
       
   123 	check_assignment_to_controlvar(lvalue);
       
   124 	check_assignment_to_output(lvalue);
       
   125 	check_assignment_to_constant(lvalue);
       
   126 	check_assignment_to_expression(lvalue);
       
   127 }
       
   128 
       
   129 
       
   130 
       
   131 
       
   132 /* check whether all values passed to OUT or IN_OUT parameters are legal lvalues. */
       
   133 void lvalue_check_c::check_nonformal_call(symbol_c *f_call, symbol_c *f_decl) {
       
   134   /* TODO */
       
   135 }
       
   136 
       
   137   
       
   138 /* check whether all values passed to OUT or IN_OUT parameters are legal lvalues. */
       
   139 void lvalue_check_c::check_formal_call(symbol_c *f_call, symbol_c *f_decl) {
       
   140 	/* if data type semantic verification was unable to determine which function is being called,
       
   141 	 * then it does not make sense to go ahead and check for lvalues to unknown parameters.
       
   142 	 * We simply bug out!
       
   143 	 */
       
   144 	if (NULL == f_decl) return;
       
   145 	
       
   146 	symbol_c *call_param_name;
       
   147 	function_param_iterator_c       fp_iterator(f_decl);
   123 	function_call_param_iterator_c fcp_iterator(f_call);
   148 	function_call_param_iterator_c fcp_iterator(f_call);
   124 	function_param_iterator_c       fp_iterator(f_decl);
   149 
   125 	do {
   150 	/* Iterating through the formal parameters of the function call */
   126 		param_name = fp_iterator.next();
   151 	while((call_param_name = fcp_iterator.next_f()) != NULL) {
   127 		if(param_name == NULL) return;
   152 
   128 	} while ((strcmp(param_name->value, "EN")  == 0) || (strcmp(param_name->value, "ENO") == 0));
   153 		/* Obtaining the value being passed in the function call */
   129 	while((call_param_value = fcp_iterator.next_nf()) != NULL) {
   154 		symbol_c *call_param_value = fcp_iterator.get_current_value();
   130 		if (search_constant_type.is_constant_value(call_param_value)) {
   155 		if (NULL == call_param_value) ERROR;
   131 			if (function_param_iterator_c::direction_out == fp_iterator.param_direction())
   156 
   132 				STAGE3_ERROR(0, call_param_value, call_param_value, "Assignment Constant value to Output parameter are not be allowed.");
   157 		/* Find the corresponding parameter in function declaration, and it's direction (IN, OUT, IN_OUT) */
       
   158 		identifier_c *param_name = fp_iterator.search(call_param_name);
       
   159 		function_param_iterator_c::param_direction_t param_direction = fp_iterator.param_direction();
       
   160 		
       
   161 		/* We only check if 'call_param_value' is a valid lvalue if the value is being passed
       
   162 		 * to a valid paramater of the function being called, and that parameter is either OUT or IN_OUT.
       
   163 		 */
       
   164 		if ((param_name != NULL) && 
       
   165 		    ((function_param_iterator_c::direction_out == param_direction) || (function_param_iterator_c::direction_inout == param_direction))) {
       
   166 			verify_is_lvalue(call_param_value);
   133 		}
   167 		}
   134 		param_name = fp_iterator.next();
   168 	}
   135 	}
   169 }
   136 }
   170 
       
   171 
       
   172 
       
   173 
   137 
   174 
   138 
   175 
   139 
   176 
   140 /**************************************/
   177 /**************************************/
   141 /* B 1.5 - Program organisation units */
   178 /* B 1.5 - Program organisation units */
   186 /* B.3 - Language ST (Structured Text) */
   223 /* B.3 - Language ST (Structured Text) */
   187 /***************************************/
   224 /***************************************/
   188 /***********************/
   225 /***********************/
   189 /* B 3.1 - Expressions */
   226 /* B 3.1 - Expressions */
   190 /***********************/
   227 /***********************/
       
   228 // 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;)
   191 void *lvalue_check_c::visit(function_invocation_c *symbol) {
   229 void *lvalue_check_c::visit(function_invocation_c *symbol) {
   192 	check_function_call_parameter(symbol);
   230 	if (NULL != symbol->formal_param_list)
       
   231 		check_formal_call(symbol, symbol->called_function_declaration);
       
   232 	if (NULL != symbol->nonformal_param_list)
       
   233 		check_nonformal_call(symbol, symbol->called_function_declaration);
   193 	return NULL;
   234 	return NULL;
   194 }
   235 }
   195 
   236 
   196 /*********************************/
   237 /*********************************/
   197 /* B 3.2.1 Assignment Statements */
   238 /* B 3.2.1 Assignment Statements */
   198 /*********************************/
   239 /*********************************/
   199 void *lvalue_check_c::visit(assignment_statement_c *symbol) {
   240 void *lvalue_check_c::visit(assignment_statement_c *symbol) {
   200 	symbolic_variable_c *lvalue;
   241 	verify_is_lvalue(symbol->l_exp);
   201 
       
   202 	lvalue = (symbolic_variable_c *)symbol->l_exp;
       
   203 	check_for_controlvar_assignment(lvalue);
       
   204 	check_output_assignment(lvalue);
       
   205 	check_constant_assignment(lvalue);
       
   206 	/* We call visit r_exp to check function_call */
   242 	/* We call visit r_exp to check function_call */
   207 	symbol->r_exp->accept(*this);
   243 	symbol->r_exp->accept(*this);
   208 	return NULL;
   244 	return NULL;
   209 }
   245 }
   210 
   246