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 |