From 91a3b1fdc68d6f77c8d15a7990b5ed23f69e271e Mon Sep 17 00:00:00 2001 From: Slavomir Kucera Date: Wed, 16 Mar 2022 09:50:38 +0100 Subject: [PATCH 1/4] Refactor data_def length evaluation --- .../data_definition/data_def_fields.h | 21 ++++++ .../data_definition/data_def_type_base.cpp | 69 ++++++++++--------- .../data_definition/data_def_type_base.h | 30 ++++---- .../checking/data_definition/data_def_types.h | 30 ++++---- .../data_def_types_fixed_point.cpp | 10 +-- .../data_definition/data_def_types_string.cpp | 20 +++--- .../data_definition_operand.cpp | 6 +- .../src/expressions/data_definition.cpp | 40 +++++++++-- .../src/expressions/data_definition.h | 1 + .../data_def_postponed_statement.cpp | 8 +-- .../src/semantics/operand_impls.cpp | 26 +++++++ parser_library/src/semantics/operand_impls.h | 2 + .../data_definition_integer_test.cpp | 18 ++--- .../data_definition_length_test.cpp | 22 +++--- .../data_definition_scale_test.cpp | 10 +-- 15 files changed, 199 insertions(+), 114 deletions(-) diff --git a/parser_library/src/checking/data_definition/data_def_fields.h b/parser_library/src/checking/data_definition/data_def_fields.h index c69587ec4..955e12541 100644 --- a/parser_library/src/checking/data_definition/data_def_fields.h +++ b/parser_library/src/checking/data_definition/data_def_fields.h @@ -94,6 +94,7 @@ struct data_def_address using expr_or_address = std::variant; using nominal_value_expressions = std::vector; using nominal_value_t = data_def_field>; +using reduced_nominal_value_t = data_def_field>; using scale_modifier_t = data_def_field; using exponent_modifier_t = data_def_field; using dupl_factor_modifier_t = data_def_field; @@ -104,6 +105,26 @@ inline T round_up(T n, T m) return ((n + m - 1) / m) * m; } +inline reduced_nominal_value_t reduce_nominal_value(const nominal_value_t& n) +{ + struct + { + std::variant operator()(const std::string& s) const { return s; } + std::variant operator()(const nominal_value_expressions& e) const { return e.size(); } + } visitor; + return reduced_nominal_value_t(n.present, std::visit(visitor, n.value), n.rng); +} + +inline reduced_nominal_value_t reduce_nominal_value(nominal_value_t&& n) +{ + struct + { + std::variant operator()(std::string&& s) const { return std::move(s); } + std::variant operator()(nominal_value_expressions&& e) const { return e.size(); } + } visitor; + return reduced_nominal_value_t(n.present, std::visit(visitor, std::move(n.value)), n.rng); +} + } // namespace hlasm_plugin::parser_library::checking #endif // !HLASMPLUGIN_PARSERLIBRARY_CHECKING_DATA_DEF_FIELDS_H diff --git a/parser_library/src/checking/data_definition/data_def_type_base.cpp b/parser_library/src/checking/data_definition/data_def_type_base.cpp index 4155a89f8..aca71861c 100644 --- a/parser_library/src/checking/data_definition/data_def_type_base.cpp +++ b/parser_library/src/checking/data_definition/data_def_type_base.cpp @@ -95,7 +95,7 @@ bool data_def_type::check(const data_definition_operand& op, const diagnostic_co if (!ret) return false; // if operand is ok, we can call get_length and check if it is not too long - if (get_length(op) >= (1ll << 31) * 8) + if (get_length(op) >= ((1ll << 31) - 1) * 8) { add_diagnostic(diagnostic_op::error_D028(op.operand_range)); return false; @@ -150,21 +150,21 @@ bool check_modifier(const data_def_field& modifier, return true; } -uint64_t data_def_type::get_nominal_length(const nominal_value_t&) const +uint64_t data_def_type::get_nominal_length(const reduced_nominal_value_t&) const { // all types that have implicit length as needed must override this function assert(false); return uint64_t(); } -uint32_t data_def_type::get_nominal_length_attribute(const nominal_value_t&) const +uint32_t data_def_type::get_nominal_length_attribute(const reduced_nominal_value_t&) const { // all types that have implicit length as needed must override this function assert(false); return uint32_t(); } -int16_t data_def_type::get_implicit_scale(const nominal_value_t&) const +int16_t data_def_type::get_implicit_scale(const reduced_nominal_value_t&) const { // All types except P and Z have implicit scale 0. return 0; @@ -228,33 +228,33 @@ modifier_spec data_def_type::get_bit_length_spec() const } bool data_def_type::check_dupl_factor( - const data_definition_operand& op, const diagnostic_collector& add_diagnostic) const + const data_def_field& dupl_factor, const diagnostic_collector& add_diagnostic) const { - if (op.dupl_factor.present) - if (op.dupl_factor.value < 0) + if (dupl_factor.present) + if (dupl_factor.value < 0) { // Duplication factor must be non negative - add_diagnostic(diagnostic_op::error_D011(op.dupl_factor.rng)); + add_diagnostic(diagnostic_op::error_D011(dupl_factor.rng)); return false; } return true; } template -bool data_def_type::check_length(const data_definition_operand& op, const diagnostic_collector& add_diagnostic) const +bool data_def_type::check_length(const data_def_length_t& length, const diagnostic_collector& add_diagnostic) const { - if (std::holds_alternative(bit_length_spec_) && op.length.len_type == data_def_length_t::length_type::BIT) + if (std::holds_alternative(bit_length_spec_) && length.len_type == data_def_length_t::length_type::BIT) { // bit length not allowed with this type - add_diagnostic(diagnostic_op::error_D007(op.length.rng, type_str)); + add_diagnostic(diagnostic_op::error_D007(length.rng, type_str)); return false; } else { - if (op.length.len_type == data_def_length_t::length_type::BIT) - return check_modifier(op.length, type_str, "bit length", get_bit_length_spec(), add_diagnostic); + if (length.len_type == data_def_length_t::length_type::BIT) + return check_modifier(length, type_str, "bit length", get_bit_length_spec(), add_diagnostic); else - return check_modifier(op.length, type_str, "length", get_length_spec(), add_diagnostic); + return check_modifier(length, type_str, "length", get_length_spec(), add_diagnostic); } } @@ -309,8 +309,8 @@ std::pair data_def_type::check_base( { assert(op.type.value == type); assert(op.extension.value == extension); - bool ret = check_dupl_factor(op, add_diagnostic); - ret &= check_length(op, add_diagnostic); + bool ret = check_dupl_factor(op.dupl_factor, add_diagnostic); + ret &= check_length(op.length, add_diagnostic); ret &= check_modifier(op.scale, type_str, "scale", scale_spec_, add_diagnostic); ret &= check_modifier(op.exponent, type_str, "exponent", exponent_spec_, add_diagnostic); @@ -336,7 +336,7 @@ context::alignment data_def_type::get_alignment(bool length_present) const return alignment_; } -size_t data_def_type::get_number_of_values_in_nominal(const nominal_value_t& nom) const +size_t data_def_type::get_number_of_values_in_nominal(const reduced_nominal_value_t& nom) const { if (type == 'C' || type == 'G') // C and G do not support multiple nominal values return 1; @@ -346,36 +346,43 @@ size_t data_def_type::get_number_of_values_in_nominal(const nominal_value_t& nom return std::count(s.begin(), s.end(), ',') + 1; } else - return std::get(nom.value).size(); + return std::get(nom.value); } // this function assumes, that the operand is already checked and was OK uint64_t data_def_type::get_length(const data_definition_operand& op) const +{ + return get_length(op.dupl_factor, op.length, reduce_nominal_value(op.nominal_value)); +} +uint64_t data_def_type::get_length(const data_def_field& dupl_factor, + const data_def_length_t& length, + const reduced_nominal_value_t& rnv) const { uint64_t len_in_bits; - if (op.length.present) + if (length.present) { - uint64_t val_count = get_number_of_values_in_nominal(op.nominal_value); - len_in_bits = val_count * op.length.value; + uint64_t val_count = get_number_of_values_in_nominal(rnv); + len_in_bits = val_count * length.value; - if (op.length.len_type == data_def_length_t::BYTE) + if (length.len_type == data_def_length_t::BYTE) len_in_bits *= 8; } else if (std::holds_alternative(implicit_length_)) - len_in_bits = get_nominal_length(op.nominal_value) * 8; - else if (!op.nominal_value.present) + len_in_bits = get_nominal_length(rnv) * 8; + else if (!rnv.present) len_in_bits = std::get(implicit_length_) * 8; else { - uint64_t val_count = get_number_of_values_in_nominal(op.nominal_value); + uint64_t val_count = get_number_of_values_in_nominal(rnv); len_in_bits = val_count * std::get(implicit_length_) * 8; } - if (op.dupl_factor.present) - len_in_bits *= (uint64_t)op.dupl_factor.value; + if (dupl_factor.present) + len_in_bits *= (uint64_t)dupl_factor.value; return len_in_bits; } -uint32_t data_def_type::get_length_attribute(const data_def_length_t& length, const nominal_value_t& nominal) const +uint32_t data_def_type::get_length_attribute( + const data_def_length_t& length, const reduced_nominal_value_t& nominal) const { if (length.present) { @@ -394,7 +401,7 @@ uint32_t data_def_type::get_length_attribute(const data_def_length_t& length, co return (uint32_t)std::get(implicit_length_); } -int16_t data_def_type::get_scale_attribute(const scale_modifier_t& scale, const nominal_value_t& nominal) const +int16_t data_def_type::get_scale_attribute(const scale_modifier_t& scale, const reduced_nominal_value_t& nominal) const { if (scale.present) return scale.value; @@ -403,7 +410,7 @@ int16_t data_def_type::get_scale_attribute(const scale_modifier_t& scale, const } int32_t data_def_type::get_integer_attribute( - const data_def_length_t& length, const scale_modifier_t& scale, const nominal_value_t& nominal) const + const data_def_length_t& length, const scale_modifier_t& scale, const reduced_nominal_value_t& nominal) const { uint32_t L = get_length_attribute(length, nominal); int32_t S = get_scale_attribute(scale, nominal); @@ -462,7 +469,7 @@ const data_def_type* data_def_type::access_data_def_type(char type, char extensi return found == types_and_extensions.end() ? nullptr : found->second.get(); } -data_def_type::~data_def_type() {} +data_def_type::~data_def_type() = default; template bool data_def_type::check( const data_definition_operand& op, const diagnostic_collector& add_diagnostic) const; diff --git a/parser_library/src/checking/data_definition/data_def_type_base.h b/parser_library/src/checking/data_definition/data_def_type_base.h index a906b4606..8ae1aaf08 100644 --- a/parser_library/src/checking/data_definition/data_def_type_base.h +++ b/parser_library/src/checking/data_definition/data_def_type_base.h @@ -113,13 +113,16 @@ class data_def_type context::alignment get_alignment(bool length_present) const; // returns length of the operand in bits uint64_t get_length(const data_definition_operand& op) const; + uint64_t get_length(const data_def_field& dupl_factor, + const data_def_length_t& length, + const reduced_nominal_value_t& rnv) const; // returns the length attribute of operand with specified length modifier and nominal value - uint32_t get_length_attribute(const data_def_length_t& length, const nominal_value_t& nominal) const; + uint32_t get_length_attribute(const data_def_length_t& length, const reduced_nominal_value_t& nominal) const; // returns scale attribute of operand with specified scale modifier and nominal value - int16_t get_scale_attribute(const scale_modifier_t& scale, const nominal_value_t& nominal) const; + int16_t get_scale_attribute(const scale_modifier_t& scale, const reduced_nominal_value_t& nominal) const; // returns length of operand with specified scale modifier and nominal value int32_t get_integer_attribute( - const data_def_length_t& length, const scale_modifier_t& scale, const nominal_value_t& nominal) const; + const data_def_length_t& length, const scale_modifier_t& scale, const reduced_nominal_value_t& nominal) const; // Returns type corresponding to specified type and extension. static const data_def_type* access_data_def_type(char type, char extension); @@ -127,6 +130,13 @@ class data_def_type virtual ~data_def_type() = 0; + // Checks duplication factor. + bool check_dupl_factor(const data_def_field& op, const diagnostic_collector& add_diagnostic) const; + + // Checks the length modifier. + template + bool check_length(const data_def_length_t& op, const diagnostic_collector& add_diagnostic) const; + protected: char type; char extension; @@ -134,11 +144,11 @@ class data_def_type // When implicit length is "as needed" - it depends on nominal value, returns the implicit length in bytes. // All types that have implicit length "as needed" must override this function. - virtual uint64_t get_nominal_length(const nominal_value_t& op) const; + virtual uint64_t get_nominal_length(const reduced_nominal_value_t& op) const; - virtual uint32_t get_nominal_length_attribute(const nominal_value_t& op) const; + virtual uint32_t get_nominal_length_attribute(const reduced_nominal_value_t& op) const; // Gets the value of scale attribute when there is no scale modifier defined by user. - virtual int16_t get_implicit_scale(const nominal_value_t& op) const; + virtual int16_t get_implicit_scale(const reduced_nominal_value_t& op) const; virtual int32_t get_integer_attribute_impl(uint32_t length, int32_t scale) const; @@ -155,12 +165,6 @@ class data_def_type // Concatenates the two characters and returns resulting string. static std::string init_type_str(char type, char extension); - // Checks duplication factor. - bool check_dupl_factor(const data_definition_operand& op, const diagnostic_collector& add_diagnostic) const; - - // Checks the length modifier. - template - bool check_length(const data_definition_operand& op, const diagnostic_collector& add_diagnostic) const; // Checks whether the nominal value is present when it is mandatory. Returns two booleans: the first one specifies // whether there was an error, the second one specifies whether the nominal value is present and needs to be checked @@ -172,7 +176,7 @@ class data_def_type // Checks if nominal value has the right type and is safe to access. Expects that nominal type is present. bool check_nominal_type(const data_definition_operand& op, const diagnostic_collector& add_diagnostic) const; - size_t get_number_of_values_in_nominal(const nominal_value_t& nom) const; + size_t get_number_of_values_in_nominal(const reduced_nominal_value_t& nom) const; template modifier_spec get_length_spec() const; diff --git a/parser_library/src/checking/data_definition/data_def_types.h b/parser_library/src/checking/data_definition/data_def_types.h index 34a5d3356..7cd61d4ac 100644 --- a/parser_library/src/checking/data_definition/data_def_types.h +++ b/parser_library/src/checking/data_definition/data_def_types.h @@ -31,8 +31,8 @@ class data_def_type_B final : public data_def_type const diagnostic_collector& add_diagnostic, bool check_nominal) const override; - uint64_t get_nominal_length(const nominal_value_t& op) const override; - uint32_t get_nominal_length_attribute(const nominal_value_t& op) const override; + uint64_t get_nominal_length(const reduced_nominal_value_t& op) const override; + uint32_t get_nominal_length_attribute(const reduced_nominal_value_t& op) const override; }; class data_def_type_CA_CE : public data_def_type @@ -40,8 +40,8 @@ class data_def_type_CA_CE : public data_def_type public: data_def_type_CA_CE(char extension); - uint64_t get_nominal_length(const nominal_value_t& op) const override; - uint32_t get_nominal_length_attribute(const nominal_value_t& op) const override; + uint64_t get_nominal_length(const reduced_nominal_value_t& op) const override; + uint32_t get_nominal_length_attribute(const reduced_nominal_value_t& op) const override; }; class data_def_type_C final : public data_def_type_CA_CE @@ -71,8 +71,8 @@ class data_def_type_CU final : public data_def_type const diagnostic_collector& add_diagnostic, bool check_nominal) const override; - uint64_t get_nominal_length(const nominal_value_t& op) const override; - uint32_t get_nominal_length_attribute(const nominal_value_t& op) const override; + uint64_t get_nominal_length(const reduced_nominal_value_t& op) const override; + uint32_t get_nominal_length_attribute(const reduced_nominal_value_t& op) const override; }; class data_def_type_G final : public data_def_type @@ -84,8 +84,8 @@ class data_def_type_G final : public data_def_type const diagnostic_collector& add_diagnostic, bool check_nominal) const override; - uint64_t get_nominal_length(const nominal_value_t& op) const override; - uint32_t get_nominal_length_attribute(const nominal_value_t& op) const override; + uint64_t get_nominal_length(const reduced_nominal_value_t& op) const override; + uint32_t get_nominal_length_attribute(const reduced_nominal_value_t& op) const override; }; class data_def_type_X final : public data_def_type @@ -97,8 +97,8 @@ class data_def_type_X final : public data_def_type const diagnostic_collector& add_diagnostic, bool check_nominal) const override; - uint64_t get_nominal_length(const nominal_value_t& op) const override; - uint32_t get_nominal_length_attribute(const nominal_value_t& op) const override; + uint64_t get_nominal_length(const reduced_nominal_value_t& op) const override; + uint32_t get_nominal_length_attribute(const reduced_nominal_value_t& op) const override; }; //************* fixed point types ***************** @@ -143,7 +143,7 @@ class data_def_type_P_Z : public data_def_type bool check(const data_definition_operand& op, const diagnostic_collector& add_diagnostic, bool check_nominal) const override; - int16_t get_implicit_scale(const nominal_value_t& op) const override; + int16_t get_implicit_scale(const reduced_nominal_value_t& op) const override; }; class data_def_type_P final : public data_def_type_P_Z @@ -152,8 +152,8 @@ class data_def_type_P final : public data_def_type_P_Z data_def_type_P(); protected: - uint64_t get_nominal_length(const nominal_value_t& op) const override; - uint32_t get_nominal_length_attribute(const nominal_value_t& op) const override; + uint64_t get_nominal_length(const reduced_nominal_value_t& op) const override; + uint32_t get_nominal_length_attribute(const reduced_nominal_value_t& op) const override; int32_t get_integer_attribute_impl(uint32_t length, int32_t scale) const override; @@ -165,8 +165,8 @@ class data_def_type_Z final : public data_def_type_P_Z data_def_type_Z(); protected: - uint64_t get_nominal_length(const nominal_value_t& op) const override; - uint32_t get_nominal_length_attribute(const nominal_value_t& op) const override; + uint64_t get_nominal_length(const reduced_nominal_value_t& op) const override; + uint32_t get_nominal_length_attribute(const reduced_nominal_value_t& op) const override; int32_t get_integer_attribute_impl(uint32_t length, int32_t scale) const override; }; diff --git a/parser_library/src/checking/data_definition/data_def_types_fixed_point.cpp b/parser_library/src/checking/data_definition/data_def_types_fixed_point.cpp index 7c8f35782..297665e18 100644 --- a/parser_library/src/checking/data_definition/data_def_types_fixed_point.cpp +++ b/parser_library/src/checking/data_definition/data_def_types_fixed_point.cpp @@ -166,7 +166,7 @@ bool data_def_type_P_Z::check( return true; } -int16_t data_def_type_P_Z::get_implicit_scale(const nominal_value_t& op) const +int16_t data_def_type_P_Z::get_implicit_scale(const reduced_nominal_value_t& op) const { if (!op.present || !std::holds_alternative(op.value)) return 0; @@ -191,7 +191,7 @@ data_def_type_P::data_def_type_P() : data_def_type_P_Z('P') {} -uint64_t data_def_type_P::get_nominal_length(const nominal_value_t& op) const +uint64_t data_def_type_P::get_nominal_length(const reduced_nominal_value_t& op) const { if (!op.present || !std::holds_alternative(op.value)) return 1; @@ -218,7 +218,7 @@ uint64_t data_def_type_P::get_nominal_length(const nominal_value_t& op) const } uint32_t hlasm_plugin::parser_library::checking::data_def_type_P::get_nominal_length_attribute( - const nominal_value_t& op) const + const reduced_nominal_value_t& op) const { if (!op.present || !std::holds_alternative(op.value)) return 1; @@ -248,7 +248,7 @@ data_def_type_Z::data_def_type_Z() : data_def_type_P_Z('Z') {} -uint64_t data_def_type_Z::get_nominal_length(const nominal_value_t& op) const +uint64_t data_def_type_Z::get_nominal_length(const reduced_nominal_value_t& op) const { if (!op.present || !std::holds_alternative(op.value)) return 1; @@ -260,7 +260,7 @@ uint64_t data_def_type_Z::get_nominal_length(const nominal_value_t& op) const return std::count_if(s.cbegin(), s.cend(), &is_digit); } -uint32_t data_def_type_Z::get_nominal_length_attribute(const nominal_value_t& op) const +uint32_t data_def_type_Z::get_nominal_length_attribute(const reduced_nominal_value_t& op) const { if (!op.present || !std::holds_alternative(op.value)) return 1; diff --git a/parser_library/src/checking/data_definition/data_def_types_string.cpp b/parser_library/src/checking/data_definition/data_def_types_string.cpp index 315b45ca7..ac23ff4cf 100644 --- a/parser_library/src/checking/data_definition/data_def_types_string.cpp +++ b/parser_library/src/checking/data_definition/data_def_types_string.cpp @@ -103,7 +103,7 @@ bool data_def_type_B::check( return true; } -uint64_t data_def_type_B::get_nominal_length(const nominal_value_t& op) const +uint64_t data_def_type_B::get_nominal_length(const reduced_nominal_value_t& op) const { if (!op.present) return 1; @@ -111,7 +111,7 @@ uint64_t data_def_type_B::get_nominal_length(const nominal_value_t& op) const return get_X_B_length(std::get(op.value), 8); } -uint32_t data_def_type_B::get_nominal_length_attribute(const nominal_value_t& nom) const +uint32_t data_def_type_B::get_nominal_length_attribute(const reduced_nominal_value_t& nom) const { if (!nom.present) return 1; @@ -138,7 +138,7 @@ data_def_type_CA_CE::data_def_type_CA_CE(char extension) as_needed()) {} -uint64_t data_def_type_CA_CE::get_nominal_length(const nominal_value_t& op) const +uint64_t data_def_type_CA_CE::get_nominal_length(const reduced_nominal_value_t& op) const { if (!op.present) return 1; @@ -146,7 +146,7 @@ uint64_t data_def_type_CA_CE::get_nominal_length(const nominal_value_t& op) cons return std::get(op.value).size(); } -uint32_t data_def_type_CA_CE::get_nominal_length_attribute(const nominal_value_t& nom) const +uint32_t data_def_type_CA_CE::get_nominal_length_attribute(const reduced_nominal_value_t& nom) const { if (!nom.present) return 1; @@ -176,7 +176,7 @@ data_def_type_CU::data_def_type_CU() 'C', 'U', n_a(), modifier_bound { 1, 256 }, n_a(), n_a(), nominal_value_type::STRING, no_align, as_needed()) {} -uint64_t data_def_type_CU::get_nominal_length(const nominal_value_t& op) const +uint64_t data_def_type_CU::get_nominal_length(const reduced_nominal_value_t& op) const { if (!op.present) return 2; @@ -184,7 +184,7 @@ uint64_t data_def_type_CU::get_nominal_length(const nominal_value_t& op) const return 2 * (uint64_t)std::get(op.value).size(); } -uint32_t data_def_type_CU::get_nominal_length_attribute(const nominal_value_t& nom) const +uint32_t data_def_type_CU::get_nominal_length_attribute(const reduced_nominal_value_t& nom) const { if (!nom.present) return 2; @@ -233,7 +233,7 @@ bool data_def_type_G::check(const data_definition_operand& op, const diagnostic_ return true; } -uint64_t data_def_type_G::get_nominal_length(const nominal_value_t& op) const +uint64_t data_def_type_G::get_nominal_length(const reduced_nominal_value_t& op) const { if (!op.present) return 2; @@ -244,7 +244,7 @@ uint64_t data_def_type_G::get_nominal_length(const nominal_value_t& op) const } } -uint32_t data_def_type_G::get_nominal_length_attribute(const nominal_value_t& nom) const +uint32_t data_def_type_G::get_nominal_length_attribute(const reduced_nominal_value_t& nom) const { if (!nom.present) return 2; @@ -290,7 +290,7 @@ bool data_def_type_X::check( return true; } -uint64_t data_def_type_X::get_nominal_length(const nominal_value_t& op) const +uint64_t data_def_type_X::get_nominal_length(const reduced_nominal_value_t& op) const { if (!op.present) return 1; @@ -298,7 +298,7 @@ uint64_t data_def_type_X::get_nominal_length(const nominal_value_t& op) const return get_X_B_length(std::get(op.value), 2); } -uint32_t data_def_type_X::get_nominal_length_attribute(const nominal_value_t& nom) const +uint32_t data_def_type_X::get_nominal_length_attribute(const reduced_nominal_value_t& nom) const { if (!nom.present) return 1; diff --git a/parser_library/src/checking/data_definition/data_definition_operand.cpp b/parser_library/src/checking/data_definition/data_definition_operand.cpp index f50e71f93..3dc513c2e 100644 --- a/parser_library/src/checking/data_definition/data_definition_operand.cpp +++ b/parser_library/src/checking/data_definition/data_definition_operand.cpp @@ -66,7 +66,7 @@ int16_t data_definition_operand::get_scale_attribute() const { auto def_type = access_data_def_type(); if (def_type) - return def_type->get_scale_attribute(scale, nominal_value); + return def_type->get_scale_attribute(scale, reduce_nominal_value(nominal_value)); else return 0; } @@ -75,7 +75,7 @@ uint32_t data_definition_operand::get_length_attribute() const { auto def_type = access_data_def_type(); if (def_type) - return def_type->get_length_attribute(length, nominal_value); + return def_type->get_length_attribute(length, reduce_nominal_value(nominal_value)); else return 0; } @@ -84,7 +84,7 @@ uint32_t data_definition_operand::get_integer_attribute() const { auto def_type = access_data_def_type(); if (def_type) - return def_type->get_integer_attribute(length, scale, nominal_value); + return def_type->get_integer_attribute(length, scale, reduce_nominal_value(nominal_value)); else return 0; } diff --git a/parser_library/src/expressions/data_definition.cpp b/parser_library/src/expressions/data_definition.cpp index b59e0f56f..92c7671cb 100644 --- a/parser_library/src/expressions/data_definition.cpp +++ b/parser_library/src/expressions/data_definition.cpp @@ -137,7 +137,7 @@ int32_t data_definition::get_scale_attribute(context::dependency_solver& info, d { auto def_type = access_data_def_type(); if (def_type) - return def_type->get_scale_attribute(evaluate_scale(info, diags), evaluate_nominal_value(info, diags)); + return def_type->get_scale_attribute(evaluate_scale(info, diags), evaluate_reduced_nominal_value()); else return 0; } @@ -146,7 +146,7 @@ uint32_t data_definition::get_length_attribute(context::dependency_solver& info, { auto def_type = access_data_def_type(); if (def_type) - return def_type->get_length_attribute(evaluate_length(info, diags), evaluate_nominal_value(info, diags)); + return def_type->get_length_attribute(evaluate_length(info, diags), evaluate_reduced_nominal_value()); else return 0; } @@ -156,7 +156,7 @@ int32_t data_definition::get_integer_attribute(context::dependency_solver& info, auto def_type = access_data_def_type(); if (def_type) return def_type->get_integer_attribute( - evaluate_length(info, diags), evaluate_scale(info, diags), evaluate_nominal_value(info, diags)); + evaluate_length(info, diags), evaluate_scale(info, diags), evaluate_reduced_nominal_value()); else return 0; } @@ -222,14 +222,18 @@ checking::data_def_field set_data_def_field( using namespace checking; data_def_field field; // if the expression cannot be evaluated, we return field as if it was not there - field.present = e != nullptr && !e->get_dependencies(info).contains_dependencies(); - if (field.present) + if (e) { field.rng = e->get_range(); + field.present = !e->get_dependencies(info).contains_dependencies(); + } + if (field.present) + { // TODO get_reloc get_abs - auto ret(e->evaluate(info, diags)); + auto ret = e->evaluate(info, diags); + if (ret.value_kind() == context::symbol_value_kind::ABS) - field.value = e->evaluate(info, diags).get_abs(); + field.value = ret.get_abs(); } return field; } @@ -342,6 +346,28 @@ checking::nominal_value_t data_definition::evaluate_nominal_value( return nom; } +checking::reduced_nominal_value_t data_definition::evaluate_reduced_nominal_value() const +{ + if (!nominal_value) + return {}; + + checking::reduced_nominal_value_t nom; + nom.present = true; + if (nominal_value->access_string()) + { + nom.value = nominal_value->access_string()->value; + nom.rng = nominal_value->access_string()->value_range; + } + else if (nominal_value->access_exprs()) + { + nom.value = nominal_value->access_exprs()->exprs.size(); + } + else + assert(false); + + return nom; +} + void data_definition::apply(mach_expr_visitor& visitor) const { if (dupl_factor) diff --git a/parser_library/src/expressions/data_definition.h b/parser_library/src/expressions/data_definition.h index 2b9a15dd9..aed19a1b1 100644 --- a/parser_library/src/expressions/data_definition.h +++ b/parser_library/src/expressions/data_definition.h @@ -97,6 +97,7 @@ struct data_definition final : public context::dependable // data_def_expr::ignored or data_def_address::ignored set to false checking::nominal_value_t evaluate_nominal_value( context::dependency_solver& info, diagnostic_op_consumer& diags) const; + checking::reduced_nominal_value_t evaluate_reduced_nominal_value() const; void apply(mach_expr_visitor& visitor) const; diff --git a/parser_library/src/processing/instruction_sets/data_def_postponed_statement.cpp b/parser_library/src/processing/instruction_sets/data_def_postponed_statement.cpp index e7dcd80b0..a04731033 100644 --- a/parser_library/src/processing/instruction_sets/data_def_postponed_statement.cpp +++ b/parser_library/src/processing/instruction_sets/data_def_postponed_statement.cpp @@ -71,14 +71,12 @@ int32_t data_def_dependency::get_operands_length(const semantics::op // enforce data def alignment round_up_bytes(solver.operands_bit_length, dd->get_alignment().boundary); } - const auto o = op->access_data_def()->get_operand_value(solver, diags); - const auto* dd_op = dynamic_cast(o.get()); + long long len = op->access_data_def()->get_length(solver, diags); - - if (!dd_op->check(diagnostic_collector())) + if (len < 0) return 0; - solver.operands_bit_length += dd_op->get_length(); + solver.operands_bit_length += len; } // align to whole byte diff --git a/parser_library/src/semantics/operand_impls.cpp b/parser_library/src/semantics/operand_impls.cpp index 3a139b01d..2574654e1 100644 --- a/parser_library/src/semantics/operand_impls.cpp +++ b/parser_library/src/semantics/operand_impls.cpp @@ -573,6 +573,32 @@ checking::data_definition_operand data_def_operand::get_operand_value( void data_def_operand::apply(operand_visitor& visitor) const { visitor.visit(*this); } +long long data_def_operand::get_length(context::dependency_solver& info, diagnostic_op_consumer& diags) const +{ + auto type = checking::data_def_type::access_data_def_type(value->type, value->extension); + if (!type) + return -1; + auto dupl = value->evaluate_dupl_factor(info, diags); + auto len = value->evaluate_length(info, diags); + + if (!type->check_dupl_factor(dupl, diagnostic_collector())) + return -1; + + if (value->nominal_value) + { + if (!type->check_length(len, diagnostic_collector())) + return -1; + } + else + { + if (!type->check_length(len, diagnostic_collector())) + return -1; + } + + auto result = type->get_length(dupl, len, value->evaluate_reduced_nominal_value()); + return result >= ((1ll << 31) - 1) * 8 ? -1 : (long long)result; +} + string_assembler_operand::string_assembler_operand(std::string value, range operand_range) : evaluable_operand(operand_type::ASM, std::move(operand_range)) , assembler_operand(asm_kind::STRING) diff --git a/parser_library/src/semantics/operand_impls.h b/parser_library/src/semantics/operand_impls.h index bd1ef24f1..f5033864c 100644 --- a/parser_library/src/semantics/operand_impls.h +++ b/parser_library/src/semantics/operand_impls.h @@ -349,6 +349,8 @@ struct data_def_operand final : evaluable_operand const expressions::data_definition& dd, context::dependency_solver& info, diagnostic_op_consumer& diags); void apply(operand_visitor& visitor) const override; + + long long get_length(context::dependency_solver& info, diagnostic_op_consumer& diags) const; }; diff --git a/parser_library/test/checking/data_definition/data_definition_integer_test.cpp b/parser_library/test/checking/data_definition/data_definition_integer_test.cpp index 323951d84..99eb3993a 100644 --- a/parser_library/test/checking/data_definition/data_definition_integer_test.cpp +++ b/parser_library/test/checking/data_definition/data_definition_integer_test.cpp @@ -32,7 +32,7 @@ TEST(data_def_integer_attribute, H) diag_collector col; EXPECT_TRUE(t.check_DC(op, ADD_DIAG(col))); - EXPECT_EQ(t.get_integer_attribute(op.length, op.scale, op.nominal_value), 9); + EXPECT_EQ(t.get_integer_attribute(op.length, op.scale, reduce_nominal_value(op.nominal_value)), 9); } TEST(data_def_integer_attribute, F) @@ -44,7 +44,7 @@ TEST(data_def_integer_attribute, F) diag_collector col; EXPECT_TRUE(t.check_DC(op, ADD_DIAG(col))); - EXPECT_EQ(t.get_integer_attribute(op.length, op.scale, op.nominal_value), 23); + EXPECT_EQ(t.get_integer_attribute(op.length, op.scale, reduce_nominal_value(op.nominal_value)), 23); } TEST(data_def_integer_attribute, E) @@ -56,7 +56,7 @@ TEST(data_def_integer_attribute, E) diag_collector col; EXPECT_TRUE(t.check_DC(op, ADD_DIAG(col))); - EXPECT_EQ(t.get_integer_attribute(op.length, op.scale, op.nominal_value), 4); + EXPECT_EQ(t.get_integer_attribute(op.length, op.scale, reduce_nominal_value(op.nominal_value)), 4); } TEST(data_def_integer_attribute, D) @@ -68,7 +68,7 @@ TEST(data_def_integer_attribute, D) diag_collector col; EXPECT_TRUE(t.check_DC(op, ADD_DIAG(col))); - EXPECT_EQ(t.get_integer_attribute(op.length, op.scale, op.nominal_value), 9); + EXPECT_EQ(t.get_integer_attribute(op.length, op.scale, reduce_nominal_value(op.nominal_value)), 9); } TEST(data_def_integer_attribute, L) @@ -80,7 +80,7 @@ TEST(data_def_integer_attribute, L) diag_collector col; EXPECT_TRUE(t.check_DC(op, ADD_DIAG(col))); - EXPECT_EQ(t.get_integer_attribute(op.length, op.scale, op.nominal_value), 18); + EXPECT_EQ(t.get_integer_attribute(op.length, op.scale, reduce_nominal_value(op.nominal_value)), 18); } TEST(data_def_integer_attribute, P) @@ -91,7 +91,7 @@ TEST(data_def_integer_attribute, P) diag_collector col; EXPECT_TRUE(t.check_DC(op, ADD_DIAG(col))); - EXPECT_EQ(t.get_integer_attribute(op.length, op.scale, op.nominal_value), 2); + EXPECT_EQ(t.get_integer_attribute(op.length, op.scale, reduce_nominal_value(op.nominal_value)), 2); } TEST(data_def_integer_attribute, Z) @@ -102,7 +102,7 @@ TEST(data_def_integer_attribute, Z) diag_collector col; EXPECT_TRUE(t.check_DC(op, ADD_DIAG(col))); - EXPECT_EQ(t.get_integer_attribute(op.length, op.scale, op.nominal_value), 1); + EXPECT_EQ(t.get_integer_attribute(op.length, op.scale, reduce_nominal_value(op.nominal_value)), 1); } TEST(data_def_integer_attribute, LD) @@ -113,7 +113,7 @@ TEST(data_def_integer_attribute, LD) diag_collector col; EXPECT_TRUE(t.check_DC(op, ADD_DIAG(col))); - EXPECT_EQ(t.get_integer_attribute(op.length, op.scale, op.nominal_value), 0); + EXPECT_EQ(t.get_integer_attribute(op.length, op.scale, reduce_nominal_value(op.nominal_value)), 0); } TEST(data_def_integer_attribute, LB) @@ -124,5 +124,5 @@ TEST(data_def_integer_attribute, LB) diag_collector col; EXPECT_TRUE(t.check_DC(op, ADD_DIAG(col))); - EXPECT_EQ(t.get_integer_attribute(op.length, op.scale, op.nominal_value), 0); + EXPECT_EQ(t.get_integer_attribute(op.length, op.scale, reduce_nominal_value(op.nominal_value)), 0); } \ No newline at end of file diff --git a/parser_library/test/checking/data_definition/data_definition_length_test.cpp b/parser_library/test/checking/data_definition/data_definition_length_test.cpp index e6ff2d3b4..f000a5a05 100644 --- a/parser_library/test/checking/data_definition/data_definition_length_test.cpp +++ b/parser_library/test/checking/data_definition/data_definition_length_test.cpp @@ -97,7 +97,7 @@ TEST(data_def_length_attribute, B_multiple) diag_collector col; ASSERT_TRUE(t.check_DC(op, ADD_DIAG(col))); - EXPECT_EQ(t.get_length_attribute(op.length, op.nominal_value), 2U); + EXPECT_EQ(t.get_length_attribute(op.length, reduce_nominal_value(op.nominal_value)), 2U); } TEST(data_def_length_attribute, B_explicit) @@ -109,7 +109,7 @@ TEST(data_def_length_attribute, B_explicit) diag_collector col; ASSERT_TRUE(t.check_DC(op, ADD_DIAG(col))); - EXPECT_EQ(t.get_length_attribute(op.length, op.nominal_value), 5U); + EXPECT_EQ(t.get_length_attribute(op.length, reduce_nominal_value(op.nominal_value)), 5U); } TEST(data_def_length, dupl_factor_bit_length) @@ -196,7 +196,7 @@ TEST(data_def_length_attribute, CA) ASSERT_TRUE(t.check_DC(op, ADD_DIAG(col))); - EXPECT_EQ(t.get_length_attribute(op.length, op.nominal_value), 5U); + EXPECT_EQ(t.get_length_attribute(op.length, reduce_nominal_value(op.nominal_value)), 5U); } TEST(data_def_length_attribute, CA_bit_length) @@ -209,7 +209,7 @@ TEST(data_def_length_attribute, CA_bit_length) ASSERT_TRUE(t.check_DC(op, ADD_DIAG(col))); - EXPECT_EQ(t.get_length_attribute(op.length, op.nominal_value), 4U); + EXPECT_EQ(t.get_length_attribute(op.length, reduce_nominal_value(op.nominal_value)), 4U); } @@ -270,7 +270,7 @@ TEST(data_def_length_attribute, CU) diag_collector col; EXPECT_TRUE(t.check_DC(op, ADD_DIAG(col))); - EXPECT_EQ(t.get_length_attribute(op.length, op.nominal_value), 12U); + EXPECT_EQ(t.get_length_attribute(op.length, reduce_nominal_value(op.nominal_value)), 12U); } TEST(data_def_length, CU_no_nominal) @@ -355,7 +355,7 @@ TEST(data_def_length_attribute, X_multiple) diag_collector col; EXPECT_TRUE(t.check_DC(op, ADD_DIAG(col))); - EXPECT_EQ(t.get_length_attribute(op.length, op.nominal_value), 2U); + EXPECT_EQ(t.get_length_attribute(op.length, reduce_nominal_value(op.nominal_value)), 2U); } TEST(data_def_length, X_even) @@ -415,7 +415,7 @@ TEST(data_def_length_attribute, F) diag_collector col; EXPECT_TRUE(t.check_DC(op, ADD_DIAG(col))); - EXPECT_EQ(t.get_length_attribute(op.length, op.nominal_value), 4U); + EXPECT_EQ(t.get_length_attribute(op.length, reduce_nominal_value(op.nominal_value)), 4U); } TEST(data_def_length, F_no_nominal) @@ -487,7 +487,7 @@ TEST(data_def_length_attribute, P_multiple) diag_collector col; EXPECT_TRUE(t.check_DC(op, ADD_DIAG(col))); - EXPECT_EQ(t.get_length_attribute(op.length, op.nominal_value), 4U); + EXPECT_EQ(t.get_length_attribute(op.length, reduce_nominal_value(op.nominal_value)), 4U); } TEST(data_def_length_attribute, P_simple) @@ -499,7 +499,7 @@ TEST(data_def_length_attribute, P_simple) diag_collector col; EXPECT_TRUE(t.check_DC(op, ADD_DIAG(col))); - EXPECT_EQ(t.get_length_attribute(op.length, op.nominal_value), 2U); + EXPECT_EQ(t.get_length_attribute(op.length, reduce_nominal_value(op.nominal_value)), 2U); } TEST(data_def_length, Z) @@ -523,7 +523,7 @@ TEST(data_def_length_attribute, Z_multiple) diag_collector col; EXPECT_TRUE(t.check_DC(op, ADD_DIAG(col))); - EXPECT_EQ(t.get_length_attribute(op.length, op.nominal_value), 4U); + EXPECT_EQ(t.get_length_attribute(op.length, reduce_nominal_value(op.nominal_value)), 4U); } TEST(data_def_length_attribute, Z_simple) @@ -535,7 +535,7 @@ TEST(data_def_length_attribute, Z_simple) diag_collector col; EXPECT_TRUE(t.check_DC(op, ADD_DIAG(col))); - EXPECT_EQ(t.get_length_attribute(op.length, op.nominal_value), 2U); + EXPECT_EQ(t.get_length_attribute(op.length, reduce_nominal_value(op.nominal_value)), 2U); } TEST(data_def_length, A) diff --git a/parser_library/test/checking/data_definition/data_definition_scale_test.cpp b/parser_library/test/checking/data_definition/data_definition_scale_test.cpp index 1d28c6731..6c4052b02 100644 --- a/parser_library/test/checking/data_definition/data_definition_scale_test.cpp +++ b/parser_library/test/checking/data_definition/data_definition_scale_test.cpp @@ -32,7 +32,7 @@ TEST(data_def_scale_attribute, P) diag_collector col; EXPECT_TRUE(t.check_DC(op, ADD_DIAG(col))); - EXPECT_EQ(t.get_scale_attribute(op.scale, op.nominal_value), 4); + EXPECT_EQ(t.get_scale_attribute(op.scale, reduce_nominal_value(op.nominal_value)), 4); } TEST(data_def_scale_attribute, P_no_integral) @@ -44,7 +44,7 @@ TEST(data_def_scale_attribute, P_no_integral) diag_collector col; EXPECT_TRUE(t.check_DC(op, ADD_DIAG(col))); - EXPECT_EQ(t.get_scale_attribute(op.scale, op.nominal_value), 4); + EXPECT_EQ(t.get_scale_attribute(op.scale, reduce_nominal_value(op.nominal_value)), 4); } TEST(data_def_scale_attribute, P_no_fraction) @@ -56,7 +56,7 @@ TEST(data_def_scale_attribute, P_no_fraction) diag_collector col; EXPECT_TRUE(t.check_DC(op, ADD_DIAG(col))); - EXPECT_EQ(t.get_scale_attribute(op.scale, op.nominal_value), 0); + EXPECT_EQ(t.get_scale_attribute(op.scale, reduce_nominal_value(op.nominal_value)), 0); } TEST(data_def_scale_attribute, P_simple_number) @@ -68,7 +68,7 @@ TEST(data_def_scale_attribute, P_simple_number) diag_collector col; EXPECT_TRUE(t.check_DC(op, ADD_DIAG(col))); - EXPECT_EQ(t.get_scale_attribute(op.scale, op.nominal_value), 0); + EXPECT_EQ(t.get_scale_attribute(op.scale, reduce_nominal_value(op.nominal_value)), 0); } TEST(data_def_scale_attribute, H_explicit) @@ -82,5 +82,5 @@ TEST(data_def_scale_attribute, H_explicit) diag_collector col; EXPECT_TRUE(t.check_DC(op, ADD_DIAG(col))); - EXPECT_EQ(t.get_scale_attribute(op.scale, op.nominal_value), 5); + EXPECT_EQ(t.get_scale_attribute(op.scale, reduce_nominal_value(op.nominal_value)), 5); } From 65e2471b6fa74bd22ce9591b73fabe900c2f863a Mon Sep 17 00:00:00 2001 From: Slavomir Kucera Date: Wed, 16 Mar 2022 10:03:17 +0100 Subject: [PATCH 2/4] rename --- .../data_def_postponed_statement.cpp | 2 +- parser_library/src/semantics/operand_impls.cpp | 14 ++++++++------ parser_library/src/semantics/operand_impls.h | 2 +- 3 files changed, 10 insertions(+), 8 deletions(-) diff --git a/parser_library/src/processing/instruction_sets/data_def_postponed_statement.cpp b/parser_library/src/processing/instruction_sets/data_def_postponed_statement.cpp index a04731033..a9a0d1625 100644 --- a/parser_library/src/processing/instruction_sets/data_def_postponed_statement.cpp +++ b/parser_library/src/processing/instruction_sets/data_def_postponed_statement.cpp @@ -71,7 +71,7 @@ int32_t data_def_dependency::get_operands_length(const semantics::op // enforce data def alignment round_up_bytes(solver.operands_bit_length, dd->get_alignment().boundary); } - long long len = op->access_data_def()->get_length(solver, diags); + long long len = op->access_data_def()->evaluate_length(solver, diags); if (len < 0) return 0; diff --git a/parser_library/src/semantics/operand_impls.cpp b/parser_library/src/semantics/operand_impls.cpp index 2574654e1..ff019eea9 100644 --- a/parser_library/src/semantics/operand_impls.cpp +++ b/parser_library/src/semantics/operand_impls.cpp @@ -573,25 +573,27 @@ checking::data_definition_operand data_def_operand::get_operand_value( void data_def_operand::apply(operand_visitor& visitor) const { visitor.visit(*this); } -long long data_def_operand::get_length(context::dependency_solver& info, diagnostic_op_consumer& diags) const +long long data_def_operand::evaluate_length(context::dependency_solver& info, diagnostic_op_consumer& diags) const { - auto type = checking::data_def_type::access_data_def_type(value->type, value->extension); - if (!type) + auto dd_type = checking::data_def_type::access_data_def_type(value->type, value->extension); + if (!dd_type) return -1; auto dupl = value->evaluate_dupl_factor(info, diags); auto len = value->evaluate_length(info, diags); - if (!type->check_dupl_factor(dupl, diagnostic_collector())) + diagnostic_collector drop_diags; + + if (!dd_type->check_dupl_factor(dupl, drop_diags)) return -1; if (value->nominal_value) { - if (!type->check_length(len, diagnostic_collector())) + if (!dd_type->check_length(len, drop_diags)) return -1; } else { - if (!type->check_length(len, diagnostic_collector())) + if (!dd_type->check_length(len, drop_diags)) return -1; } diff --git a/parser_library/src/semantics/operand_impls.h b/parser_library/src/semantics/operand_impls.h index f5033864c..fa0e623d9 100644 --- a/parser_library/src/semantics/operand_impls.h +++ b/parser_library/src/semantics/operand_impls.h @@ -350,7 +350,7 @@ struct data_def_operand final : evaluable_operand void apply(operand_visitor& visitor) const override; - long long get_length(context::dependency_solver& info, diagnostic_op_consumer& diags) const; + long long evaluate_length(context::dependency_solver& info, diagnostic_op_consumer& diags) const; }; From 273366869d40ebb9797b3887e1bd6094a926628d Mon Sep 17 00:00:00 2001 From: Slavomir Kucera Date: Wed, 16 Mar 2022 10:34:30 +0100 Subject: [PATCH 3/4] Move data def length evaluation --- parser_library/src/context/literal_pool.cpp | 5 +++- .../src/expressions/data_definition.cpp | 28 +++++++++++++++++++ .../src/expressions/data_definition.h | 2 ++ .../src/semantics/operand_impls.cpp | 25 +---------------- 4 files changed, 35 insertions(+), 25 deletions(-) diff --git a/parser_library/src/context/literal_pool.cpp b/parser_library/src/context/literal_pool.cpp index 33e23147d..a523b3e0f 100644 --- a/parser_library/src/context/literal_pool.cpp +++ b/parser_library/src/context/literal_pool.cpp @@ -126,7 +126,10 @@ void literal_pool::generate_pool(diagnosable_ctx& diags) it->first.generation, it->first.unique_id, }); - size = (semantics::data_def_operand::get_operand_value(*lit, solver, diags).get_length() + 7) / 8; + auto bit_length = lit->evaluate_total_length(solver, diags); + if (bit_length < 0) + continue; + size = (bit_length + 7) / 8; if (size == 0) continue; diff --git a/parser_library/src/expressions/data_definition.cpp b/parser_library/src/expressions/data_definition.cpp index 92c7671cb..aec625a7a 100644 --- a/parser_library/src/expressions/data_definition.cpp +++ b/parser_library/src/expressions/data_definition.cpp @@ -368,6 +368,34 @@ checking::reduced_nominal_value_t data_definition::evaluate_reduced_nominal_valu return nom; } +long long data_definition::evaluate_total_length(context::dependency_solver& info, diagnostic_op_consumer& diags) const +{ + auto dd_type = checking::data_def_type::access_data_def_type(type, extension); + if (!dd_type) + return -1; + auto dupl = evaluate_dupl_factor(info, diags); + auto len = evaluate_length(info, diags); + + diagnostic_collector drop_diags; + + if (!dd_type->check_dupl_factor(dupl, drop_diags)) + return -1; + + if (nominal_value) + { + if (!dd_type->check_length(len, drop_diags)) + return -1; + } + else + { + if (!dd_type->check_length(len, drop_diags)) + return -1; + } + + auto result = dd_type->get_length(dupl, len, evaluate_reduced_nominal_value()); + return result >= ((1ll << 31) - 1) * 8 ? -1 : (long long)result; +} + void data_definition::apply(mach_expr_visitor& visitor) const { if (dupl_factor) diff --git a/parser_library/src/expressions/data_definition.h b/parser_library/src/expressions/data_definition.h index aed19a1b1..01aa56d10 100644 --- a/parser_library/src/expressions/data_definition.h +++ b/parser_library/src/expressions/data_definition.h @@ -99,6 +99,8 @@ struct data_definition final : public context::dependable context::dependency_solver& info, diagnostic_op_consumer& diags) const; checking::reduced_nominal_value_t evaluate_reduced_nominal_value() const; + long long evaluate_total_length(context::dependency_solver& info, diagnostic_op_consumer& diags) const; + void apply(mach_expr_visitor& visitor) const; friend bool is_similar(const data_definition& l, const data_definition& r) noexcept; diff --git a/parser_library/src/semantics/operand_impls.cpp b/parser_library/src/semantics/operand_impls.cpp index ff019eea9..259065770 100644 --- a/parser_library/src/semantics/operand_impls.cpp +++ b/parser_library/src/semantics/operand_impls.cpp @@ -575,30 +575,7 @@ void data_def_operand::apply(operand_visitor& visitor) const { visitor.visit(*th long long data_def_operand::evaluate_length(context::dependency_solver& info, diagnostic_op_consumer& diags) const { - auto dd_type = checking::data_def_type::access_data_def_type(value->type, value->extension); - if (!dd_type) - return -1; - auto dupl = value->evaluate_dupl_factor(info, diags); - auto len = value->evaluate_length(info, diags); - - diagnostic_collector drop_diags; - - if (!dd_type->check_dupl_factor(dupl, drop_diags)) - return -1; - - if (value->nominal_value) - { - if (!dd_type->check_length(len, drop_diags)) - return -1; - } - else - { - if (!dd_type->check_length(len, drop_diags)) - return -1; - } - - auto result = type->get_length(dupl, len, value->evaluate_reduced_nominal_value()); - return result >= ((1ll << 31) - 1) * 8 ? -1 : (long long)result; + return value->evaluate_total_length(info, diags); } string_assembler_operand::string_assembler_operand(std::string value, range operand_range) From 127cdbb57715c3611e6634417fb5b3a8306f1032 Mon Sep 17 00:00:00 2001 From: Slavomir Kucera Date: Wed, 16 Mar 2022 09:13:25 +0100 Subject: [PATCH 4/4] rename --- .../instruction_sets/data_def_postponed_statement.cpp | 2 +- parser_library/src/semantics/operand_impls.cpp | 2 +- parser_library/src/semantics/operand_impls.h | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/parser_library/src/processing/instruction_sets/data_def_postponed_statement.cpp b/parser_library/src/processing/instruction_sets/data_def_postponed_statement.cpp index a9a0d1625..e7594b7e9 100644 --- a/parser_library/src/processing/instruction_sets/data_def_postponed_statement.cpp +++ b/parser_library/src/processing/instruction_sets/data_def_postponed_statement.cpp @@ -71,7 +71,7 @@ int32_t data_def_dependency::get_operands_length(const semantics::op // enforce data def alignment round_up_bytes(solver.operands_bit_length, dd->get_alignment().boundary); } - long long len = op->access_data_def()->evaluate_length(solver, diags); + long long len = op->access_data_def()->evaluate_total_length(solver, diags); if (len < 0) return 0; diff --git a/parser_library/src/semantics/operand_impls.cpp b/parser_library/src/semantics/operand_impls.cpp index 259065770..da1da2be1 100644 --- a/parser_library/src/semantics/operand_impls.cpp +++ b/parser_library/src/semantics/operand_impls.cpp @@ -573,7 +573,7 @@ checking::data_definition_operand data_def_operand::get_operand_value( void data_def_operand::apply(operand_visitor& visitor) const { visitor.visit(*this); } -long long data_def_operand::evaluate_length(context::dependency_solver& info, diagnostic_op_consumer& diags) const +long long data_def_operand::evaluate_total_length(context::dependency_solver& info, diagnostic_op_consumer& diags) const { return value->evaluate_total_length(info, diags); } diff --git a/parser_library/src/semantics/operand_impls.h b/parser_library/src/semantics/operand_impls.h index fa0e623d9..8dd4f863d 100644 --- a/parser_library/src/semantics/operand_impls.h +++ b/parser_library/src/semantics/operand_impls.h @@ -350,7 +350,7 @@ struct data_def_operand final : evaluable_operand void apply(operand_visitor& visitor) const override; - long long evaluate_length(context::dependency_solver& info, diagnostic_op_consumer& diags) const; + long long evaluate_total_length(context::dependency_solver& info, diagnostic_op_consumer& diags) const; };