86 /* Add to the global_enumerated_value_symtable the global enum value constants, i.e. the enum constants used in the enumerated |
86 /* Add to the global_enumerated_value_symtable the global enum value constants, i.e. the enum constants used in the enumerated |
87 * datatypes that are defined inside a TYPE ... END_TYPE declaration. |
87 * datatypes that are defined inside a TYPE ... END_TYPE declaration. |
88 */ |
88 */ |
89 |
89 |
90 symbol_c null_globalenumvalue_symbol; /* cannot be static, so it may be used in the template!! */ |
90 symbol_c null_globalenumvalue_symbol; /* cannot be static, so it may be used in the template!! */ |
91 static symtable_c<symbol_c *, &null_globalenumvalue_symbol> global_enumerated_value_symtable; |
91 static dsymtable_c<symbol_c *, &null_globalenumvalue_symbol> global_enumerated_value_symtable; |
92 |
92 |
93 |
93 |
94 class populate_globalenumvalue_symtable_c: public iterator_visitor_c { |
94 class populate_globalenumvalue_symtable_c: public iterator_visitor_c { |
95 private: |
95 private: |
96 symbol_c *current_enumerated_type; |
96 symbol_c *current_enumerated_type; |
137 * compiler error message). |
137 * compiler error message). |
138 * For this reason, the follosing check is commented out. |
138 * For this reason, the follosing check is commented out. |
139 */ |
139 */ |
140 /* if (value_type == current_enumerated_type) ERROR; */ |
140 /* if (value_type == current_enumerated_type) ERROR; */ |
141 |
141 |
142 if (value_type == global_enumerated_value_symtable.end_value()) |
142 global_enumerated_value_symtable.insert(symbol->value, current_enumerated_type); |
143 /* This identifier has not yet been used in any previous declaration of an enumeration data type. |
|
144 * so we add it to the symbol table. |
|
145 */ |
|
146 global_enumerated_value_symtable.insert(symbol->value, current_enumerated_type); |
|
147 else if (value_type != NULL) |
|
148 /* This identifier has already been used in a previous declaration of an enumeration data type. |
|
149 * so we set the symbol in symbol table pointing to NULL. |
|
150 */ |
|
151 global_enumerated_value_symtable.set(symbol->value, NULL); |
|
152 |
|
153 return NULL; |
143 return NULL; |
154 } |
144 } |
155 |
145 |
156 /**************************************/ |
146 /**************************************/ |
157 /* B.1.5 - Program organization units */ |
147 /* B.1.5 - Program organization units */ |
185 * Values in (A) are added to the enumerated_value_symtable in absyntaxt_utils.cc. |
175 * Values in (A) are added to the enumerated_value_symtable in absyntaxt_utils.cc. |
186 * Values in (B) are only in scope inside the POU with the VAR END_VAR declaration. |
176 * Values in (B) are only in scope inside the POU with the VAR END_VAR declaration. |
187 * |
177 * |
188 * This class will add the enum values in (B) to the local_enumerated_value_symtable. |
178 * This class will add the enum values in (B) to the local_enumerated_value_symtable. |
189 * |
179 * |
190 * If a locally defined enum value is identical to another locally defined enum_value, the |
180 * If a locally defined enum value is identical to another locally defined enum_value, a |
191 * corresponding entry in local_enumerated_value_symtable is set to NULL. |
181 * duplicate entry is created. |
192 * However, if a locally defined enum value is identical to another globally defined enum_value, the |
182 * However, if a locally defined enum value is identical to another globally defined enum_value, the |
193 * corresponding entry in local_enumerated_value_symtable is set to the local datatype (and not NULL). |
183 * corresponding entry in local_enumerated_value_symtable is also set to the local datatype. |
194 * This is because anonynous locally feined enum datatypes are anonymous, and its enum values cannot therefore |
184 * This is because anonynous locally feined enum datatypes are anonymous, and its enum values cannot therefore |
195 * be disambiguated using EnumType#enum_value (since the enum type does not have a name, it is anonymous!). |
185 * be disambiguated using EnumType#enum_value (since the enum type does not have a name, it is anonymous!). |
196 * For this reason we implement the semantics where locally defined enum values, when in scope, will 'cover' |
186 * For this reason we implement the semantics where locally defined enum values, when in scope, will 'cover' |
197 * the globally defined enum value with the same name/identifier. |
187 * the globally defined enum value with the same name/identifier. |
198 * For example: |
188 * For example: |
209 * GlobalEnumVar := GlobalEnumT#xxx1; |
199 * GlobalEnumVar := GlobalEnumT#xxx1; |
210 * END_FUNCTION_BLOCK |
200 * END_FUNCTION_BLOCK |
211 */ |
201 */ |
212 |
202 |
213 symbol_c null_localenumvalue_symbol; /* cannot be static, so it may be used in the template!! */ |
203 symbol_c null_localenumvalue_symbol; /* cannot be static, so it may be used in the template!! */ |
214 static symtable_c<symbol_c *, &null_localenumvalue_symbol> local_enumerated_value_symtable; |
204 static dsymtable_c<symbol_c *, &null_localenumvalue_symbol> local_enumerated_value_symtable; |
215 |
205 |
216 |
206 |
217 class populate_enumvalue_symtable_c: public iterator_visitor_c { |
207 class populate_enumvalue_symtable_c: public iterator_visitor_c { |
218 private: |
208 private: |
219 symbol_c *current_enumerated_type; |
209 symbol_c *current_enumerated_type; |
249 /* if the enumerated_value_c is not inside a enumerated_spec_init_c (e.g. used as the inital value of a variable), we simply return */ |
239 /* if the enumerated_value_c is not inside a enumerated_spec_init_c (e.g. used as the inital value of a variable), we simply return */ |
250 if (current_enumerated_type == NULL) return NULL; |
240 if (current_enumerated_type == NULL) return NULL; |
251 /* this is really an ERROR! The initial value may use the syntax NUM_TYPE#enum_value, but in that case we should have return'd in the above statement !! */ |
241 /* this is really an ERROR! The initial value may use the syntax NUM_TYPE#enum_value, but in that case we should have return'd in the above statement !! */ |
252 if (symbol->type != NULL) ERROR; |
242 if (symbol->type != NULL) ERROR; |
253 |
243 |
254 // symbol_c *global_value_type = global_enumerated_value_symtable.find_value(symbol->value); |
|
255 symbol_c *local_value_type = local_enumerated_value_symtable.find_value(symbol->value); |
244 symbol_c *local_value_type = local_enumerated_value_symtable.find_value(symbol->value); |
256 if (local_value_type == local_enumerated_value_symtable.end_value()) |
245 |
257 /* This identifier has not yet been used in any previous local declaration of an enumeration data type, so we add it to the local symbol table. */ |
246 /* add it to the local symbol table. */ |
258 local_enumerated_value_symtable.insert(symbol->value, current_enumerated_type); |
247 local_enumerated_value_symtable.insert(symbol->value, current_enumerated_type); |
259 else |
|
260 /* This identifier has already been used in a previous declaration of an enumeration data type. so we set the symbol in symbol table pointing to NULL. */ |
|
261 local_enumerated_value_symtable.set(symbol->value, NULL); |
|
262 return NULL; |
248 return NULL; |
263 } |
249 } |
264 }; // class populate_enumvalue_symtable_c |
250 }; // class populate_enumvalue_symtable_c |
265 |
251 |
266 static populate_enumvalue_symtable_c populate_enumvalue_symtable; |
252 static populate_enumvalue_symtable_c populate_enumvalue_symtable; |
526 * spurious error messages. |
512 * spurious error messages. |
527 * Even if the parameters to the function call are invalid, doing this is still safe, as the |
513 * Even if the parameters to the function call are invalid, doing this is still safe, as the |
528 * expressions inside the function call will themselves have erros and will guarantee that |
514 * expressions inside the function call will themselves have erros and will guarantee that |
529 * compilation is aborted in stage3 (in print_datatypes_error_c). |
515 * compilation is aborted in stage3 (in print_datatypes_error_c). |
530 */ |
516 */ |
531 if (function_symtable.multiplicity(fcall_data.function_name) == 1) { |
517 if (function_symtable.count(fcall_data.function_name) == 1) { |
532 f_decl = function_symtable.get_value(lower); |
518 f_decl = function_symtable.get_value(lower); |
533 returned_parameter_type = base_type(f_decl->type_name); |
519 returned_parameter_type = base_type(f_decl->type_name); |
534 if (add_datatype_to_candidate_list(fcall, returned_parameter_type)) |
520 if (add_datatype_to_candidate_list(fcall, returned_parameter_type)) |
535 /* we only add it to the function declaration list if this entry was not already present in the candidate datatype list! */ |
521 /* we only add it to the function declaration list if this entry was not already present in the candidate datatype list! */ |
536 fcall_data.candidate_functions.push_back(f_decl); |
522 fcall_data.candidate_functions.push_back(f_decl); |
918 symbol_c *enumerated_type; |
904 symbol_c *enumerated_type; |
919 |
905 |
920 if (NULL != symbol->type) |
906 if (NULL != symbol->type) |
921 enumerated_type = symbol->type; /* TODO: check whether the value really belongs to that datatype!! */ |
907 enumerated_type = symbol->type; /* TODO: check whether the value really belongs to that datatype!! */ |
922 else { |
908 else { |
923 global_enumerated_type = global_enumerated_value_symtable.find_value(symbol->value); |
909 symbol_c *global_enumerated_type = global_enumerated_value_symtable.find_value (symbol->value); |
924 local_enumerated_type = local_enumerated_value_symtable.find_value(symbol->value); |
910 symbol_c * local_enumerated_type = local_enumerated_value_symtable.find_value (symbol->value); |
925 if (( local_enumerated_type == local_enumerated_value_symtable.end_value()) && (global_enumerated_type == global_enumerated_value_symtable.end_value())) |
911 int global_multiplicity = global_enumerated_value_symtable.count(symbol->value); |
|
912 int local_multiplicity = local_enumerated_value_symtable.count(symbol->value); |
|
913 |
|
914 if (( local_multiplicity == 0) && (global_multiplicity == 0)) |
926 enumerated_type = NULL; // not found! |
915 enumerated_type = NULL; // not found! |
927 else if (( local_enumerated_type != local_enumerated_value_symtable.end_value()) && (local_enumerated_type == NULL)) |
916 else if ( local_multiplicity > 1) |
928 enumerated_type = NULL; // Duplicate, so it is ambiguous! |
917 enumerated_type = NULL; // Local duplicate, so it is ambiguous! |
929 else if (( local_enumerated_type != local_enumerated_value_symtable.end_value())) |
918 else if ( local_multiplicity == 1) |
930 enumerated_type = local_enumerated_type; |
919 enumerated_type = local_enumerated_type; |
931 else if ((global_enumerated_type != global_enumerated_value_symtable.end_value()) && (global_enumerated_type == NULL)) |
920 else if ( global_multiplicity > 1) |
932 enumerated_type = NULL; // Duplicate, so it is ambiguous! |
921 enumerated_type = NULL; // Global duplicate, so it is ambiguous! |
933 else if ((global_enumerated_type != global_enumerated_value_symtable.end_value())) |
922 else if ( global_multiplicity == 1) |
934 enumerated_type = global_enumerated_type; |
923 enumerated_type = global_enumerated_type; |
935 else ERROR; |
924 else ERROR; |
936 } |
925 } |
937 enumerated_type = base_type(enumerated_type); |
926 enumerated_type = base_type(enumerated_type); |
938 if (NULL != enumerated_type) |
927 if (NULL != enumerated_type) |