Located variables may have other data types besides ANY_BIT.
--- a/stage3/fill_candidate_datatypes.cc Sun May 13 17:57:15 2012 +0200
+++ b/stage3/fill_candidate_datatypes.cc Tue May 15 15:50:43 2012 +0100
@@ -696,8 +696,83 @@
/* AT direct_variable */
// SYM_REF1(location_c, direct_variable)
void *fill_candidate_datatypes_c::visit(location_c *symbol) {
+ /* This is a special situation.
+ *
+ * The reason is that a located variable may be declared to be of any data type, as long as the size
+ * matches the location (lines 1 3 and 4 of table 17). For example:
+ * var1 AT %MB42.0 : BYTE;
+ * var1 AT %MB42.1 : SINT;
+ * var1 AT %MB42.2 : USINT;
+ * var1 AT %MW64 : INT;
+ * var1 AT %MD56 : DINT;
+ * var1 AT %MD57 : REAL;
+ * are all valid!!
+ *
+ * However, when used inside an expression, the direct variable (uses the same syntax as the location
+ * of a located variable) is limited to the following (ANY_BIT) data types:
+ * %MX --> BOOL
+ * %MB --> BYTE
+ * %MW --> WORD
+ * %MD --> DWORD
+ * %ML --> LWORD
+ *
+ * So, in order to be able to analyse expressions with direct variables
+ * e.g: var1 := 66 OR %MW34
+ * where the direct variable may only take the ANY_BIT data types, the fill_candidate_datatypes_c
+ * considers that only the ANY_BIT data types are allowed for a direct variable.
+ * However, it appears from the examples in the standard (lines 1 3 and 4 of table 17)
+ * a location may have any data type (presumably as long as the size in bits match).
+ * For this reason, a location_c may have more allowable data types than a direct_variable_c
+ */
+
symbol->direct_variable->accept(*this);
- symbol->candidate_datatypes = symbol->direct_variable->candidate_datatypes;
+ for (unsigned int i = 0; i < symbol->direct_variable->candidate_datatypes.size(); i++) {
+ switch (get_sizeof_datatype_c::getsize(symbol->direct_variable->candidate_datatypes[i])) {
+ case 1: /* bit - 1 bit */
+ add_datatype_to_candidate_list(symbol, &search_constant_type_c::bool_type_name);
+ add_datatype_to_candidate_list(symbol, &search_constant_type_c::safebool_type_name);
+ break;
+ case 8: /* byte - 8 bits */
+ add_datatype_to_candidate_list(symbol, &search_constant_type_c::byte_type_name);
+ add_datatype_to_candidate_list(symbol, &search_constant_type_c::safebyte_type_name);
+ add_datatype_to_candidate_list(symbol, &search_constant_type_c::sint_type_name);
+ add_datatype_to_candidate_list(symbol, &search_constant_type_c::safesint_type_name);
+ add_datatype_to_candidate_list(symbol, &search_constant_type_c::usint_type_name);
+ add_datatype_to_candidate_list(symbol, &search_constant_type_c::safeusint_type_name);
+ break;
+ case 16: /* word - 16 bits */
+ add_datatype_to_candidate_list(symbol, &search_constant_type_c::word_type_name);
+ add_datatype_to_candidate_list(symbol, &search_constant_type_c::safeword_type_name);
+ add_datatype_to_candidate_list(symbol, &search_constant_type_c::int_type_name);
+ add_datatype_to_candidate_list(symbol, &search_constant_type_c::safeint_type_name);
+ add_datatype_to_candidate_list(symbol, &search_constant_type_c::uint_type_name);
+ add_datatype_to_candidate_list(symbol, &search_constant_type_c::safeuint_type_name);
+ break;
+ case 32: /* dword - 32 bits */
+ add_datatype_to_candidate_list(symbol, &search_constant_type_c::dword_type_name);
+ add_datatype_to_candidate_list(symbol, &search_constant_type_c::safedword_type_name);
+ add_datatype_to_candidate_list(symbol, &search_constant_type_c::dint_type_name);
+ add_datatype_to_candidate_list(symbol, &search_constant_type_c::safedint_type_name);
+ add_datatype_to_candidate_list(symbol, &search_constant_type_c::udint_type_name);
+ add_datatype_to_candidate_list(symbol, &search_constant_type_c::safeudint_type_name);
+ add_datatype_to_candidate_list(symbol, &search_constant_type_c::real_type_name);
+ add_datatype_to_candidate_list(symbol, &search_constant_type_c::safereal_type_name);
+ break;
+ case 64: /* lword - 64 bits */
+ add_datatype_to_candidate_list(symbol, &search_constant_type_c::lword_type_name);
+ add_datatype_to_candidate_list(symbol, &search_constant_type_c::safelword_type_name);
+ add_datatype_to_candidate_list(symbol, &search_constant_type_c::lint_type_name);
+ add_datatype_to_candidate_list(symbol, &search_constant_type_c::safelint_type_name);
+ add_datatype_to_candidate_list(symbol, &search_constant_type_c::ulint_type_name);
+ add_datatype_to_candidate_list(symbol, &search_constant_type_c::safeulint_type_name);
+ add_datatype_to_candidate_list(symbol, &search_constant_type_c::lreal_type_name);
+ add_datatype_to_candidate_list(symbol, &search_constant_type_c::safelreal_type_name);
+ break;
+ default: /* if none of the above, then no valid datatype allowed... */
+ break;
+ } /* switch() */
+ } /* for */
+
return NULL;
}
--- a/stage3/print_datatypes_error.cc Sun May 13 17:57:15 2012 +0200
+++ b/stage3/print_datatypes_error.cc Tue May 15 15:50:43 2012 +0100
@@ -649,7 +649,7 @@
/* It does not make sense to call symbol->location->accept(*this). The check is done right here if the following if() */
// symbol->location->accept(*this);
if ((is_type_valid(symbol->located_var_spec_init->datatype)) && (!is_type_valid(symbol->location->datatype)))
- STAGE3_ERROR(0, symbol, symbol, "Location is incompatible with data type.");
+ STAGE3_ERROR(0, symbol, symbol, "Bit size of data type is incompatible with bit size of location.");
return NULL;
}