68 #define VALID_CVALUE(dtype, symbol) (symbol_c::cs_const_value == (symbol)->const_value._##dtype.status) |
68 #define VALID_CVALUE(dtype, symbol) (symbol_c::cs_const_value == (symbol)->const_value._##dtype.status) |
69 #define IS_OVERFLOW(dtype, symbol) (symbol_c::cs_overflow == (symbol)->const_value._##dtype.status) |
69 #define IS_OVERFLOW(dtype, symbol) (symbol_c::cs_overflow == (symbol)->const_value._##dtype.status) |
70 |
70 |
71 /* set to 1 to see debug info during execution */ |
71 /* set to 1 to see debug info during execution */ |
72 static int debug = 0; |
72 static int debug = 0; |
|
73 |
|
74 |
|
75 |
|
76 |
|
77 /*****************************************************/ |
|
78 /* */ |
|
79 /* A small helper class... */ |
|
80 /* */ |
|
81 /*****************************************************/ |
|
82 |
|
83 /* 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: |
|
88 * Some enumerations are |
|
89 * (A) declared anonymously inside a VAR ... END_VAR declaration |
|
90 * (e.g. VAR enum_var : (enumvalue1, enumvalue2); END_VAR) |
|
91 * while others are |
|
92 * (B) declared (with a name) inside a TYPE .. END_TYPE declaration. |
|
93 * |
|
94 * Values in (A) are added to the enumerated_value_symtable in absyntaxt_utils.cc. |
|
95 * Values in (B) are only in scope inside the POU with the VAR END_VAR declaration. |
|
96 * |
|
97 * This class will add the enum values in (B) to the local_enumerated_value_symtable. |
|
98 * |
|
99 * If a locally defined enum value is identical to another locally defined enum_value, the |
|
100 * corresponding entry in local_enumerated_value_symtable is set to NULL. |
|
101 * However, if a locally defined enum value is identical to another globally defined enum_value, the |
|
102 * corresponding entry in local_enumerated_value_symtable is set to the local datatype (and not NULL). |
|
103 * This is because anonynous locally feined enum datatypes are anonymous, and its enum values cannot therefore |
|
104 * be disambiguated using EnumType#enum_value (since the enum type does not have a name, it is anonymous!). |
|
105 * For this reason we implement the semantics where locally defined enum values, when in scope, will 'cover' |
|
106 * the globally defined enum value with the same name/identifier. |
|
107 * For example: |
|
108 * |
|
109 * TYPE GlobalEnumT: (xxx1, xxx2, xxx3) END_TYPE |
|
110 * |
|
111 * FUNCTION_BLOCK FOO |
|
112 * VAR_INPUT |
|
113 * GlobalEnumVar: GlobalEnumT; |
|
114 * LocalEnumVar : (xxx1, yyy2, yyy3); |
|
115 * END_VAR |
|
116 * LocalEnumVar := xxx1; <-- We consider it OK!!! xxx1 will reference the anonymous type used for LocalEnumVar |
|
117 * GlobalEnumVar := xxx1; <-- We consider it an error. xxx1 will reference the anonymous type used for LocalEnumVar |
|
118 * GlobalEnumVar := GlobalEnumT#xxx1; |
|
119 * END_FUNCTION_BLOCK |
|
120 */ |
|
121 |
|
122 symbol_c null_enumvalue_symbol; /* cannot be static, so it may be used in the template!! */ |
|
123 static symtable_c<symbol_c *, &null_enumvalue_symbol> local_enumerated_value_symtable; |
|
124 |
|
125 |
|
126 class populate_enumvalue_symtable_c: public iterator_visitor_c { |
|
127 private: |
|
128 symbol_c *current_enumerated_type; |
|
129 |
|
130 public: |
|
131 populate_enumvalue_symtable_c(void) {current_enumerated_type = NULL;}; |
|
132 ~populate_enumvalue_symtable_c(void) {} |
|
133 |
|
134 public: |
|
135 /*************************/ |
|
136 /* B.1 - Common elements */ |
|
137 /*************************/ |
|
138 /**********************/ |
|
139 /* B.1.3 - Data types */ |
|
140 /**********************/ |
|
141 /********************************/ |
|
142 /* B 1.3.3 - Derived data types */ |
|
143 /********************************/ |
|
144 /* enumerated_specification ASSIGN enumerated_value */ |
|
145 void *visit(enumerated_spec_init_c *symbol) { |
|
146 current_enumerated_type = symbol; |
|
147 symbol->enumerated_specification->accept(*this); |
|
148 /* DO NOT visit the symbol->enumerated_value !!! */ |
|
149 current_enumerated_type = NULL; |
|
150 return NULL; |
|
151 } |
|
152 |
|
153 /* [enumerated_type_name '#'] identifier */ |
|
154 void *visit(enumerated_value_c *symbol) { |
|
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 */ |
|
156 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 !! */ |
|
158 if (symbol->type != NULL) ERROR; |
|
159 |
|
160 // symbol_c *global_value_type = enumerated_value_symtable.find_value(symbol->value); |
|
161 symbol_c *local_value_type = local_enumerated_value_symtable.find_value(symbol->value); |
|
162 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. */ |
|
164 local_enumerated_value_symtable.insert(symbol->value, current_enumerated_type); |
|
165 else |
|
166 /* 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. */ |
|
167 local_enumerated_value_symtable.set(symbol->value, NULL); |
|
168 return NULL; |
|
169 } |
|
170 }; // class populate_enumvalue_symtable_c |
|
171 |
|
172 static populate_enumvalue_symtable_c populate_enumvalue_symtable; |
|
173 |
|
174 |
|
175 |
|
176 |
|
177 /*****************************************************/ |
|
178 /* */ |
|
179 /* Main FILL candidate datatypes algorithm... */ |
|
180 /* */ |
|
181 /*****************************************************/ |
|
182 |
|
183 |
73 |
184 |
74 fill_candidate_datatypes_c::fill_candidate_datatypes_c(symbol_c *ignore) { |
185 fill_candidate_datatypes_c::fill_candidate_datatypes_c(symbol_c *ignore) { |
75 il_operand = NULL; |
186 il_operand = NULL; |
76 prev_il_instruction = NULL; |
187 prev_il_instruction = NULL; |
77 search_varfb_instance_type = NULL; |
188 search_varfb_instance_type = NULL; |
628 return NULL; |
739 return NULL; |
629 } |
740 } |
630 */ |
741 */ |
631 |
742 |
632 void *fill_candidate_datatypes_c::visit(enumerated_value_c *symbol) { |
743 void *fill_candidate_datatypes_c::visit(enumerated_value_c *symbol) { |
|
744 symbol_c *global_enumerated_type; |
|
745 symbol_c *local_enumerated_type; |
633 symbol_c *enumerated_type; |
746 symbol_c *enumerated_type; |
634 |
747 |
635 if (NULL != symbol->type) |
748 if (NULL != symbol->type) |
636 enumerated_type = symbol->type; |
749 enumerated_type = symbol->type; /* TODO: check whether the value really belongs to that datatype!! */ |
637 else { |
750 else { |
638 enumerated_type = enumerated_value_symtable.find_value(symbol->value); |
751 global_enumerated_type = enumerated_value_symtable.find_value(symbol->value); |
639 if (enumerated_type == enumerated_value_symtable.end_value()) |
752 local_enumerated_type = local_enumerated_value_symtable.find_value(symbol->value); |
640 enumerated_type = NULL; |
753 if ((local_enumerated_type == local_enumerated_value_symtable.end_value()) && (global_enumerated_type == enumerated_value_symtable.end_value())) |
|
754 enumerated_type = NULL; // not found! |
|
755 else if ((local_enumerated_type != local_enumerated_value_symtable.end_value()) && (local_enumerated_type == NULL)) |
|
756 enumerated_type = NULL; // Duplicate, so it is ambiguous! |
|
757 else if ((local_enumerated_type != local_enumerated_value_symtable.end_value())) |
|
758 enumerated_type = local_enumerated_type; |
|
759 else if ((global_enumerated_type != enumerated_value_symtable.end_value()) && (global_enumerated_type == NULL)) |
|
760 enumerated_type = NULL; // Duplicate, so it is ambiguous! |
|
761 else if ((global_enumerated_type != enumerated_value_symtable.end_value())) |
|
762 enumerated_type = global_enumerated_type; |
|
763 else ERROR; |
641 } |
764 } |
642 enumerated_type = base_type(enumerated_type); |
765 enumerated_type = base_type(enumerated_type); |
643 if (NULL != enumerated_type) |
766 if (NULL != enumerated_type) |
644 add_datatype_to_candidate_list(symbol, enumerated_type); |
767 add_datatype_to_candidate_list(symbol, enumerated_type); |
645 |
768 |
847 /*********************/ |
970 /*********************/ |
848 /* B 1.5.1 Functions */ |
971 /* B 1.5.1 Functions */ |
849 /*********************/ |
972 /*********************/ |
850 void *fill_candidate_datatypes_c::visit(function_declaration_c *symbol) { |
973 void *fill_candidate_datatypes_c::visit(function_declaration_c *symbol) { |
851 if (debug) printf("Filling candidate data types list of function %s\n", ((token_c *)(symbol->derived_function_name))->value); |
974 if (debug) printf("Filling candidate data types list of function %s\n", ((token_c *)(symbol->derived_function_name))->value); |
|
975 local_enumerated_value_symtable.reset(); |
|
976 symbol->var_declarations_list->accept(populate_enumvalue_symtable); |
|
977 |
852 search_varfb_instance_type = new search_varfb_instance_type_c(symbol); |
978 search_varfb_instance_type = new search_varfb_instance_type_c(symbol); |
853 symbol->var_declarations_list->accept(*this); |
979 symbol->var_declarations_list->accept(*this); |
854 symbol->function_body->accept(*this); |
980 symbol->function_body->accept(*this); |
855 delete search_varfb_instance_type; |
981 delete search_varfb_instance_type; |
856 search_varfb_instance_type = NULL; |
982 search_varfb_instance_type = NULL; |
|
983 |
|
984 local_enumerated_value_symtable.reset(); |
857 return NULL; |
985 return NULL; |
858 } |
986 } |
859 |
987 |
860 /***************************/ |
988 /***************************/ |
861 /* B 1.5.2 Function blocks */ |
989 /* B 1.5.2 Function blocks */ |
862 /***************************/ |
990 /***************************/ |
863 void *fill_candidate_datatypes_c::visit(function_block_declaration_c *symbol) { |
991 void *fill_candidate_datatypes_c::visit(function_block_declaration_c *symbol) { |
864 if (debug) printf("Filling candidate data types list of FB %s\n", ((token_c *)(symbol->fblock_name))->value); |
992 if (debug) printf("Filling candidate data types list of FB %s\n", ((token_c *)(symbol->fblock_name))->value); |
|
993 local_enumerated_value_symtable.reset(); |
|
994 symbol->var_declarations->accept(populate_enumvalue_symtable); |
|
995 |
865 search_varfb_instance_type = new search_varfb_instance_type_c(symbol); |
996 search_varfb_instance_type = new search_varfb_instance_type_c(symbol); |
866 symbol->var_declarations->accept(*this); |
997 symbol->var_declarations->accept(*this); |
867 symbol->fblock_body->accept(*this); |
998 symbol->fblock_body->accept(*this); |
868 delete search_varfb_instance_type; |
999 delete search_varfb_instance_type; |
869 search_varfb_instance_type = NULL; |
1000 search_varfb_instance_type = NULL; |
|
1001 |
|
1002 local_enumerated_value_symtable.reset(); |
870 return NULL; |
1003 return NULL; |
871 } |
1004 } |
872 |
1005 |
873 /**********************/ |
1006 /**********************/ |
874 /* B 1.5.3 - Programs */ |
1007 /* B 1.5.3 - Programs */ |
875 /**********************/ |
1008 /**********************/ |
876 void *fill_candidate_datatypes_c::visit(program_declaration_c *symbol) { |
1009 void *fill_candidate_datatypes_c::visit(program_declaration_c *symbol) { |
877 if (debug) printf("Filling candidate data types list in program %s\n", ((token_c *)(symbol->program_type_name))->value); |
1010 if (debug) printf("Filling candidate data types list in program %s\n", ((token_c *)(symbol->program_type_name))->value); |
|
1011 local_enumerated_value_symtable.reset(); |
|
1012 symbol->var_declarations->accept(populate_enumvalue_symtable); |
|
1013 |
878 search_varfb_instance_type = new search_varfb_instance_type_c(symbol); |
1014 search_varfb_instance_type = new search_varfb_instance_type_c(symbol); |
879 symbol->var_declarations->accept(*this); |
1015 symbol->var_declarations->accept(*this); |
880 symbol->function_block_body->accept(*this); |
1016 symbol->function_block_body->accept(*this); |
881 delete search_varfb_instance_type; |
1017 delete search_varfb_instance_type; |
882 search_varfb_instance_type = NULL; |
1018 search_varfb_instance_type = NULL; |
|
1019 |
|
1020 local_enumerated_value_symtable.reset(); |
883 return NULL; |
1021 return NULL; |
884 } |
1022 } |
885 |
1023 |
886 |
1024 |
887 |
1025 |