51 * Fill the candidate datatype list for all symbols that may legally 'have' a data type (e.g. variables, literals, function calls, expressions, etc.) |
51 * Fill the candidate datatype list for all symbols that may legally 'have' a data type (e.g. variables, literals, function calls, expressions, etc.) |
52 * |
52 * |
53 * The candidate datatype list will be filled with a list of all the data types that expression may legally take. |
53 * The candidate datatype list will be filled with a list of all the data types that expression may legally take. |
54 * For example, the very simple literal '0' (as in foo := 0), may represent a: |
54 * For example, the very simple literal '0' (as in foo := 0), may represent a: |
55 * BOOL, BYTE, WORD, DWORD, LWORD, USINT, SINT, UINT, INT, UDINT, DINT, ULINT, LINT (as well as the SAFE versions of these data tyes too!) |
55 * BOOL, BYTE, WORD, DWORD, LWORD, USINT, SINT, UINT, INT, UDINT, DINT, ULINT, LINT (as well as the SAFE versions of these data tyes too!) |
|
56 * |
|
57 * WARNING: This visitor class starts off by building a map of all enumeration constants that are defined in the source code (i.e. a library_c symbol), |
|
58 * and this map is later used to determine the datatpe of each use of an enumeration constant. By implication, the fill_candidate_datatypes_c |
|
59 * visitor class will only work corretly if it is asked to visit a symbol of class library_c!! |
56 */ |
60 */ |
57 |
61 |
58 #include <../main.hh> /* required for UINT64_MAX, INT64_MAX, INT64_MIN, ... */ |
62 #include <../main.hh> /* required for UINT64_MAX, INT64_MAX, INT64_MIN, ... */ |
59 #include "fill_candidate_datatypes.hh" |
63 #include "fill_candidate_datatypes.hh" |
60 #include "datatype_functions.hh" |
64 #include "datatype_functions.hh" |
71 /* set to 1 to see debug info during execution */ |
75 /* set to 1 to see debug info during execution */ |
72 static int debug = 0; |
76 static int debug = 0; |
73 |
77 |
74 |
78 |
75 |
79 |
76 |
|
77 /*****************************************************/ |
80 /*****************************************************/ |
78 /* */ |
81 /* */ |
79 /* A small helper class... */ |
82 /* A small helper class... */ |
80 /* */ |
83 /* */ |
81 /*****************************************************/ |
84 /*****************************************************/ |
82 |
85 |
|
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. |
|
88 */ |
|
89 |
|
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; |
|
92 |
|
93 |
|
94 class populate_globalenumvalue_symtable_c: public iterator_visitor_c { |
|
95 private: |
|
96 symbol_c *current_enumerated_type; |
|
97 |
|
98 public: |
|
99 populate_globalenumvalue_symtable_c(void) {current_enumerated_type = NULL;}; |
|
100 ~populate_globalenumvalue_symtable_c(void) {} |
|
101 |
|
102 public: |
|
103 /*************************/ |
|
104 /* B.1 - Common elements */ |
|
105 /*************************/ |
|
106 /**********************/ |
|
107 /* B.1.3 - Data types */ |
|
108 /**********************/ |
|
109 /********************************/ |
|
110 /* B 1.3.3 - Derived data types */ |
|
111 /********************************/ |
|
112 /* enumerated_type_name ':' enumerated_spec_init */ |
|
113 void *visit(enumerated_type_declaration_c *symbol) { |
|
114 //current_enumerated_type = symbol->enumerated_type_name; |
|
115 current_enumerated_type = symbol; |
|
116 symbol->enumerated_spec_init->accept(*this); |
|
117 current_enumerated_type = NULL; |
|
118 return NULL; |
|
119 } |
|
120 |
|
121 /* enumerated_specification ASSIGN enumerated_value */ |
|
122 void *visit(enumerated_spec_init_c *symbol) { |
|
123 return symbol->enumerated_specification->accept(*this); |
|
124 } |
|
125 |
|
126 /* [enumerated_type_name '#'] identifier */ |
|
127 void *visit(enumerated_value_c *symbol) { |
|
128 if (current_enumerated_type == NULL) ERROR; |
|
129 if (symbol->type != NULL) ERROR; |
|
130 |
|
131 symbol_c *value_type = global_enumerated_value_symtable.find_value(symbol->value); |
|
132 /* NOTE: The following condition checks whether the same identifier is used more than once |
|
133 * when defining the enumerated values of the type declaration of the new enumerated type. |
|
134 * If this occurs, then the program beeing compiled contains a semantic error, which |
|
135 * must be caught and reported by the semantic analyser. However, since |
|
136 * this code is run before the semantic analyser, we must not yet raise the ERROR (internal |
|
137 * compiler error message). |
|
138 * For this reason, the follosing check is commented out. |
|
139 */ |
|
140 /* if (value_type == current_enumerated_type) ERROR; */ |
|
141 |
|
142 if (value_type == global_enumerated_value_symtable.end_value()) |
|
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; |
|
154 } |
|
155 |
|
156 /**************************************/ |
|
157 /* B.1.5 - Program organization units */ |
|
158 /**************************************/ |
|
159 /* B 1.5.1 - Functions */ |
|
160 void *visit(function_declaration_c *symbol) {return NULL;} |
|
161 /* B 1.5.2 - Function Blocks */ |
|
162 void *visit(function_block_declaration_c *symbol) {return NULL;} |
|
163 /* B 1.5.3 - Programs */ |
|
164 void *visit(program_declaration_c *symbol) {return NULL;} |
|
165 |
|
166 }; /* populate_globalenumvalue_symtable_c */ |
|
167 |
|
168 static populate_globalenumvalue_symtable_c populate_globalenumvalue_symtable; |
|
169 |
|
170 |
|
171 /*****************************************************/ |
|
172 /* */ |
|
173 /* A small helper class... */ |
|
174 /* */ |
|
175 /*****************************************************/ |
|
176 |
83 /* Add to the local_enumerated_value_symtable the local enum value constants */ |
177 /* Add to the local_enumerated_value_symtable the local enum value constants */ |
84 /* WARNING: This visitor expects to visit a POU (function, FB, program, ...) |
|
85 * It should not be called to visit any symbol that may include a TYPE .., END_TYPE declaration! |
|
86 */ |
|
87 /* Notes: |
178 /* Notes: |
88 * Some enumerations are |
179 * Some enumerations are |
89 * (A) declared anonymously inside a VAR ... END_VAR declaration |
180 * (A) declared anonymously inside a VAR ... END_VAR declaration |
90 * (e.g. VAR enum_var : (enumvalue1, enumvalue2); END_VAR) |
181 * (e.g. VAR enum_var : (enumvalue1, enumvalue2); END_VAR) |
91 * while others are |
182 * while others are |
139 /* B.1.3 - Data types */ |
230 /* B.1.3 - Data types */ |
140 /**********************/ |
231 /**********************/ |
141 /********************************/ |
232 /********************************/ |
142 /* B 1.3.3 - Derived data types */ |
233 /* B 1.3.3 - Derived data types */ |
143 /********************************/ |
234 /********************************/ |
|
235 /* TYPE type_declaration_list END_TYPE */ |
|
236 void *visit(data_type_declaration_c *symbol) {return NULL;} // do not visit the type declarations!! |
|
237 |
144 /* enumerated_specification ASSIGN enumerated_value */ |
238 /* enumerated_specification ASSIGN enumerated_value */ |
145 void *visit(enumerated_spec_init_c *symbol) { |
239 void *visit(enumerated_spec_init_c *symbol) { |
146 current_enumerated_type = symbol; |
240 current_enumerated_type = symbol; |
147 symbol->enumerated_specification->accept(*this); |
241 symbol->enumerated_specification->accept(*this); |
148 /* DO NOT visit the symbol->enumerated_value !!! */ |
242 /* DO NOT visit the symbol->enumerated_value !!! */ |
155 /* 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 */ |
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 */ |
156 if (current_enumerated_type == NULL) return NULL; |
250 if (current_enumerated_type == NULL) return NULL; |
157 /* 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 !! */ |
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 !! */ |
158 if (symbol->type != NULL) ERROR; |
252 if (symbol->type != NULL) ERROR; |
159 |
253 |
160 // symbol_c *global_value_type = enumerated_value_symtable.find_value(symbol->value); |
254 // symbol_c *global_value_type = global_enumerated_value_symtable.find_value(symbol->value); |
161 symbol_c *local_value_type = local_enumerated_value_symtable.find_value(symbol->value); |
255 symbol_c *local_value_type = local_enumerated_value_symtable.find_value(symbol->value); |
162 if (local_value_type == local_enumerated_value_symtable.end_value()) |
256 if (local_value_type == local_enumerated_value_symtable.end_value()) |
163 /* 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. */ |
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. */ |
164 local_enumerated_value_symtable.insert(symbol->value, current_enumerated_type); |
258 local_enumerated_value_symtable.insert(symbol->value, current_enumerated_type); |
165 else |
259 else |
179 /* Main FILL candidate datatypes algorithm... */ |
273 /* Main FILL candidate datatypes algorithm... */ |
180 /* */ |
274 /* */ |
181 /*****************************************************/ |
275 /*****************************************************/ |
182 |
276 |
183 |
277 |
184 |
|
185 fill_candidate_datatypes_c::fill_candidate_datatypes_c(symbol_c *ignore) { |
278 fill_candidate_datatypes_c::fill_candidate_datatypes_c(symbol_c *ignore) { |
186 il_operand = NULL; |
279 il_operand = NULL; |
187 prev_il_instruction = NULL; |
280 prev_il_instruction = NULL; |
188 search_varfb_instance_type = NULL; |
281 search_varfb_instance_type = NULL; |
189 current_enumerated_spec_type = NULL; |
282 current_enumerated_spec_type = NULL; |
190 } |
283 } |
191 |
284 |
192 fill_candidate_datatypes_c::~fill_candidate_datatypes_c(void) { |
285 fill_candidate_datatypes_c::~fill_candidate_datatypes_c(void) { |
193 } |
286 } |
|
287 |
|
288 |
|
289 |
|
290 |
|
291 |
|
292 |
194 |
293 |
195 symbol_c *fill_candidate_datatypes_c::widening_conversion(symbol_c *left_type, symbol_c *right_type, const struct widen_entry widen_table[]) { |
294 symbol_c *fill_candidate_datatypes_c::widening_conversion(symbol_c *left_type, symbol_c *right_type, const struct widen_entry widen_table[]) { |
196 int k; |
295 int k; |
197 /* find a widening table entry compatible */ |
296 /* find a widening table entry compatible */ |
198 for (k = 0; NULL != widen_table[k].left; k++) |
297 for (k = 0; NULL != widen_table[k].left; k++) |
549 /* NOTE: symbol == NULL is valid. It will occur when, for e.g., an undefined/undeclared symbolic_variable is used in the code. */ |
648 /* NOTE: symbol == NULL is valid. It will occur when, for e.g., an undefined/undeclared symbolic_variable is used in the code. */ |
550 if (symbol == NULL) return NULL; |
649 if (symbol == NULL) return NULL; |
551 return search_base_type_c::get_basetype_decl(symbol); |
650 return search_base_type_c::get_basetype_decl(symbol); |
552 } |
651 } |
553 |
652 |
|
653 |
|
654 /***************************/ |
|
655 /* B 0 - Programming Model */ |
|
656 /***************************/ |
|
657 /* main entry function! */ |
|
658 void *fill_candidate_datatypes_c::visit(library_c *symbol) { |
|
659 symbol->accept(populate_globalenumvalue_symtable); |
|
660 /* Now let the base class iterator_visitor_c iterate through all the library elements */ |
|
661 return iterator_visitor_c::visit(symbol); |
|
662 } |
|
663 |
|
664 |
554 /*********************/ |
665 /*********************/ |
555 /* B 1.2 - Constants */ |
666 /* B 1.2 - Constants */ |
556 /*********************/ |
667 /*********************/ |
557 /******************************/ |
668 /******************************/ |
558 /* B 1.2.1 - Numeric Literals */ |
669 /* B 1.2.1 - Numeric Literals */ |
807 symbol_c *enumerated_type; |
918 symbol_c *enumerated_type; |
808 |
919 |
809 if (NULL != symbol->type) |
920 if (NULL != symbol->type) |
810 enumerated_type = symbol->type; /* TODO: check whether the value really belongs to that datatype!! */ |
921 enumerated_type = symbol->type; /* TODO: check whether the value really belongs to that datatype!! */ |
811 else { |
922 else { |
812 global_enumerated_type = enumerated_value_symtable.find_value(symbol->value); |
923 global_enumerated_type = global_enumerated_value_symtable.find_value(symbol->value); |
813 local_enumerated_type = local_enumerated_value_symtable.find_value(symbol->value); |
924 local_enumerated_type = local_enumerated_value_symtable.find_value(symbol->value); |
814 if ((local_enumerated_type == local_enumerated_value_symtable.end_value()) && (global_enumerated_type == enumerated_value_symtable.end_value())) |
925 if (( local_enumerated_type == local_enumerated_value_symtable.end_value()) && (global_enumerated_type == global_enumerated_value_symtable.end_value())) |
815 enumerated_type = NULL; // not found! |
926 enumerated_type = NULL; // not found! |
816 else if ((local_enumerated_type != local_enumerated_value_symtable.end_value()) && (local_enumerated_type == NULL)) |
927 else if (( local_enumerated_type != local_enumerated_value_symtable.end_value()) && (local_enumerated_type == NULL)) |
817 enumerated_type = NULL; // Duplicate, so it is ambiguous! |
928 enumerated_type = NULL; // Duplicate, so it is ambiguous! |
818 else if ((local_enumerated_type != local_enumerated_value_symtable.end_value())) |
929 else if (( local_enumerated_type != local_enumerated_value_symtable.end_value())) |
819 enumerated_type = local_enumerated_type; |
930 enumerated_type = local_enumerated_type; |
820 else if ((global_enumerated_type != enumerated_value_symtable.end_value()) && (global_enumerated_type == NULL)) |
931 else if ((global_enumerated_type != global_enumerated_value_symtable.end_value()) && (global_enumerated_type == NULL)) |
821 enumerated_type = NULL; // Duplicate, so it is ambiguous! |
932 enumerated_type = NULL; // Duplicate, so it is ambiguous! |
822 else if ((global_enumerated_type != enumerated_value_symtable.end_value())) |
933 else if ((global_enumerated_type != global_enumerated_value_symtable.end_value())) |
823 enumerated_type = global_enumerated_type; |
934 enumerated_type = global_enumerated_type; |
824 else ERROR; |
935 else ERROR; |
825 } |
936 } |
826 enumerated_type = base_type(enumerated_type); |
937 enumerated_type = base_type(enumerated_type); |
827 if (NULL != enumerated_type) |
938 if (NULL != enumerated_type) |