83 int declaration_check_c::get_error_count() { |
84 int declaration_check_c::get_error_count() { |
84 return error_count; |
85 return error_count; |
85 } |
86 } |
86 |
87 |
87 void declaration_check_c::check_global_decl(symbol_c *p_decl) { |
88 void declaration_check_c::check_global_decl(symbol_c *p_decl) { |
88 symbol_c *var_name; |
89 if (NULL == current_pou_decl) ERROR; |
89 |
90 |
90 search_var_instance_decl_c search_var_instance_glo_decl(current_pou_decl); |
91 search_var_instance_decl_c search_var_instance_pou_glo_decl(current_pou_decl); |
91 search_var_instance_decl_c search_var_instance_ext_decl(p_decl); |
92 search_var_instance_decl_c search_var_instance_res_glo_decl(current_resource_decl); |
92 function_param_iterator_c fpi(p_decl); |
93 search_var_instance_decl_c search_var_instance_ext_decl(p_decl); |
93 while((var_name = fpi.next()) != NULL) { |
94 function_param_iterator_c fpi(p_decl); |
94 if (fpi.param_direction() == function_param_iterator_c::direction_extref) { |
95 |
95 /* found an external reference parameter. */ |
96 symbol_c *var_name; |
96 symbol_c *glo_decl = search_var_instance_glo_decl.get_decl(var_name); |
97 while((var_name = fpi.next()) != NULL) { |
97 symbol_c *ext_decl = search_var_instance_ext_decl.get_decl(var_name); |
98 if (fpi.param_direction() == function_param_iterator_c::direction_extref) { |
98 if (glo_decl == NULL) { |
99 /* found an external reference parameter. */ |
99 STAGE3_ERROR(0, ext_decl, ext_decl, "Declaration error an external doesn't mach with any global var."); |
100 symbol_c *ext_decl = search_var_instance_ext_decl.get_decl(var_name); |
100 continue; |
101 |
101 } |
102 // NOTE: Must check the POU first, and RESOURCE second! |
102 if (search_var_instance_glo_decl.get_option(var_name) != search_var_instance_ext_decl.get_option(var_name)) |
103 symbol_c *glo_decl = search_var_instance_res_glo_decl.get_decl(var_name); |
103 STAGE3_ERROR(0, glo_decl, glo_decl, "Declaration error an external redefinition option."); |
104 search_var_instance_decl_c *search_var_instance_glo_decl = &search_var_instance_res_glo_decl; |
104 |
105 if (NULL == glo_decl) { |
105 /* TODO: Check redefinition data type. |
106 glo_decl = search_var_instance_pou_glo_decl.get_decl(var_name); |
106 * We need a new class (like search_base_type class) to get type id by variable declaration. |
107 search_var_instance_glo_decl = &search_var_instance_pou_glo_decl; |
107 * symbol_c *glo_type = ????; |
|
108 * symbol_c *ext_type = fpi.param_type(); |
|
109 */ |
|
110 /* For the moment, we will just use search_base_type_c instead... */ |
|
111 symbol_c *glo_type = search_base_type_c::get_basetype_decl(glo_decl); |
|
112 symbol_c *ext_type = search_base_type_c::get_basetype_decl(ext_decl); |
|
113 if (! get_datatype_info_c::is_type_equal(glo_type, ext_type)) |
|
114 STAGE3_ERROR(0, ext_decl, ext_decl, "Declaration error an external redefinition data type."); |
|
115 } |
108 } |
116 } |
109 |
117 |
110 if (NULL == glo_decl) { |
|
111 STAGE3_ERROR(0, ext_decl, ext_decl, "Declaration error. The external variable does not match with any global variable."); |
|
112 continue; |
|
113 } |
|
114 |
|
115 if (search_var_instance_glo_decl->get_option(var_name) != search_var_instance_ext_decl.get_option(var_name)) |
|
116 STAGE3_ERROR(0, glo_decl, glo_decl, "Declaration error. The external variable options do not match with thos of the global variable."); |
|
117 |
|
118 /* TODO: Check redefinition data type. |
|
119 * We need a new class (like search_base_type class) to get type id by variable declaration. |
|
120 * symbol_c *glo_type = ????; |
|
121 * symbol_c *ext_type = fpi.param_type(); |
|
122 */ |
|
123 /* For the moment, we will just use search_base_type_c instead... */ |
|
124 symbol_c *glo_type = search_base_type_c::get_basetype_decl(glo_decl); |
|
125 symbol_c *ext_type = search_base_type_c::get_basetype_decl(ext_decl); |
|
126 if (! get_datatype_info_c::is_type_equal(glo_type, ext_type)) |
|
127 STAGE3_ERROR(0, ext_decl, ext_decl, "Declaration error. Data type mismatch between external and global variable declarations."); |
|
128 } |
|
129 } |
118 } |
130 } |
119 |
131 |
120 |
132 |
121 |
133 |
122 /*****************************/ |
134 /*****************************/ |
123 /* B 1.5.2 - Function Blocks */ |
135 /* B 1.5.2 - Function Blocks */ |
124 /*****************************/ |
136 /*****************************/ |
125 /* FUNCTION_BLOCK derived_function_block_name io_OR_other_var_declarations function_block_body END_FUNCTION_BLOCK */ |
137 /* FUNCTION_BLOCK derived_function_block_name io_OR_other_var_declarations function_block_body END_FUNCTION_BLOCK */ |
126 // SYM_REF3(function_block_declaration_c, fblock_name, var_declarations, fblock_body) |
138 // SYM_REF3(function_block_declaration_c, fblock_name, var_declarations, fblock_body) |
127 void *declaration_check_c::visit(function_block_declaration_c *symbol) { |
139 void *declaration_check_c::visit(function_block_declaration_c *symbol) { |
128 current_pou_decl = symbol; |
140 /* The following two lines of code are only valid for v3 of IEC 61131-3, that allows VAR_GLOBAL declarations inside FBs! |
|
141 * current_pou_decl = symbol; |
|
142 * current_resource_decl = NULL; |
|
143 */ |
129 /* check if any FB declared as a VAR has any incompatible VAR_EXTERNAL declarations */ |
144 /* check if any FB declared as a VAR has any incompatible VAR_EXTERNAL declarations */ |
130 if (NULL != symbol->var_declarations) |
145 if (NULL != symbol->var_declarations) |
131 symbol->var_declarations->accept(*this); |
146 symbol->var_declarations->accept(*this); |
132 return NULL; |
147 return NULL; |
133 } |
148 } |
136 /* B 1.5.3 - Declaration & Initialisation */ |
151 /* B 1.5.3 - Declaration & Initialisation */ |
137 /******************************************/ |
152 /******************************************/ |
138 /* PROGRAM program_type_name program_var_declarations_list function_block_body END_PROGRAM */ |
153 /* PROGRAM program_type_name program_var_declarations_list function_block_body END_PROGRAM */ |
139 // SYM_REF3(program_declaration_c, program_type_name, var_declarations, function_block_body) |
154 // SYM_REF3(program_declaration_c, program_type_name, var_declarations, function_block_body) |
140 void *declaration_check_c::visit(program_declaration_c *symbol) { |
155 void *declaration_check_c::visit(program_declaration_c *symbol) { |
141 current_pou_decl = symbol; |
156 /* The following two lines of code are only valid for v3 of IEC 61131-3, that allows VAR_GLOBAL declarations inside PROGRAMs! |
|
157 * current_pou_decl = symbol; |
|
158 * current_resource_decl = NULL; |
|
159 */ |
142 /* check if any FB declared as a VAR has any incompatible VAR_EXTERNAL declarations */ |
160 /* check if any FB declared as a VAR has any incompatible VAR_EXTERNAL declarations */ |
143 if (NULL != symbol->var_declarations) |
161 if (NULL != symbol->var_declarations) |
144 symbol->var_declarations->accept(*this); |
162 symbol->var_declarations->accept(*this); |
145 return NULL; |
163 return NULL; |
146 } |
164 } |
160 void *declaration_check_c::visit(configuration_declaration_c *symbol) { |
178 void *declaration_check_c::visit(configuration_declaration_c *symbol) { |
161 current_pou_decl = symbol; |
179 current_pou_decl = symbol; |
162 /* check if any FB declared as a VAR has any incompatible VAR_EXTERNAL declarations */ |
180 /* check if any FB declared as a VAR has any incompatible VAR_EXTERNAL declarations */ |
163 if (NULL != symbol->resource_declarations) |
181 if (NULL != symbol->resource_declarations) |
164 symbol->resource_declarations->accept(*this); |
182 symbol->resource_declarations->accept(*this); |
165 return NULL; |
183 current_pou_decl = NULL; |
166 } |
184 return NULL; |
167 |
185 } |
|
186 |
|
187 /* |
|
188 RESOURCE resource_name ON resource_type_name |
|
189 optional_global_var_declarations |
|
190 single_resource_declaration |
|
191 END_RESOURCE |
|
192 */ |
|
193 /* enumvalue_symtable is filled in by enum_declaration_check_c, during stage3 semantic verification, with a list of all enumerated constants declared inside this POU */ |
|
194 // SYM_REF4(resource_declaration_c, resource_name, resource_type_name, global_var_declarations, resource_declaration, enumvalue_symtable_t enumvalue_symtable;) |
|
195 void *declaration_check_c::visit(resource_declaration_c *symbol) { |
|
196 current_resource_decl = symbol; |
|
197 /* check if any FB declared as a VAR has any incompatible VAR_EXTERNAL declarations */ |
|
198 symbol->resource_declaration->accept(*this); |
|
199 current_resource_decl = NULL; |
|
200 return NULL; |
|
201 } |
|
202 |
|
203 /* PROGRAM [RETAIN | NON_RETAIN] program_name [WITH task_name] ':' program_type_name ['(' prog_conf_elements ')'] */ |
168 void *declaration_check_c::visit(program_configuration_c *symbol) { |
204 void *declaration_check_c::visit(program_configuration_c *symbol) { |
169 symbol_c *p_decl = program_type_symtable.find_value(symbol->program_type_name); |
205 symbol_c *p_decl = program_type_symtable.find_value(symbol->program_type_name); |
170 if (p_decl == program_type_symtable.end_value()) |
206 if (p_decl == program_type_symtable.end_value()) |
171 p_decl = function_block_type_symtable.find_value(symbol->program_type_name); |
207 p_decl = function_block_type_symtable.find_value(symbol->program_type_name); |
172 /* stage1_2 guarantees that we are sure to find a declaration in FB or Program symtable. */ |
208 /* stage1_2 guarantees that we are sure to find a declaration in FB or Program symtable. */ |