diff options
author | Tom Tromey <tromey@adacore.com> | 2024-03-05 07:25:08 -0700 |
---|---|---|
committer | Tom Tromey <tromey@adacore.com> | 2024-04-02 11:24:26 -0600 |
commit | d9d782dd8b6c3665c28f6b610175a0756a7805a4 (patch) | |
tree | a673e1724f14062e581bb43370169275d28067cb | |
parent | c2cf30e7608093773286081ebfc4067246ecba7e (diff) | |
download | gdb-d9d782dd8b6c3665c28f6b610175a0756a7805a4.zip gdb-d9d782dd8b6c3665c28f6b610175a0756a7805a4.tar.gz gdb-d9d782dd8b6c3665c28f6b610175a0756a7805a4.tar.bz2 |
Introduce and use aggregate_assigner type
This patch is a refactoring to add a new aggregate_assigner type.
This type is passed to Ada aggregate assignment operations in place of
passing a number of separate arguments. This new approach makes it
simpler to change some aspects of aggregate assignment behavior.
-rw-r--r-- | gdb/ada-exp.h | 88 | ||||
-rw-r--r-- | gdb/ada-lang.c | 153 |
2 files changed, 114 insertions, 127 deletions
diff --git a/gdb/ada-exp.h b/gdb/ada-exp.h index 69d4e90..6122502 100644 --- a/gdb/ada-exp.h +++ b/gdb/ada-exp.h @@ -588,20 +588,48 @@ private: ada_assign_operation *m_lhs; }; +/* When constructing an aggregate, an object of this type is created + to track the needed state. */ + +struct aggregate_assigner +{ + /* An lvalue containing LHS (possibly LHS itself). */ + value *container; + + /* An lvalue of record or array type; this is the object being + assigned to. */ + value *lhs; + + /* The expression being evaluated. */ + expression *exp; + + /* The bounds of LHS. This is used by the 'others' component. */ + LONGEST low; + LONGEST high; + + /* This indicates which sub-components have already been assigned + to. */ + std::vector<LONGEST> indices; + + /* Assign the result of evaluating ARG to the INDEXth component of + LHS (a simple array or a record). Does not modify the inferior's + memory, nor does it modify LHS (unless LHS == CONTAINER). */ + void assign (LONGEST index, operation_up &arg); + + /* Add the interval [FROM .. TO] to the sorted set of intervals + [ INDICES[0] .. INDICES[1] ],... The resulting intervals do not + overlap. */ + void add_interval (LONGEST low, LONGEST high); +}; + /* This abstract class represents a single component in an Ada aggregate assignment. */ class ada_component { public: - /* Assign to LHS, which is part of CONTAINER. EXP is the expression - being evaluated. INDICES, LOW, and HIGH indicate which - sub-components have already been assigned; INDICES should be - updated by this call. */ - virtual void assign (struct value *container, - struct value *lhs, struct expression *exp, - std::vector<LONGEST> &indices, - LONGEST low, LONGEST high) = 0; + /* Assign to ASSIGNER. */ + virtual void assign (aggregate_assigner &assigner) = 0; /* Same as operation::uses_objfile. */ virtual bool uses_objfile (struct objfile *objfile) = 0; @@ -664,10 +692,7 @@ public: ada_aggregate_component (operation_up &&base, std::vector<ada_component_up> &&components); - void assign (struct value *container, - struct value *lhs, struct expression *exp, - std::vector<LONGEST> &indices, - LONGEST low, LONGEST high) override; + void assign (aggregate_assigner &assigner) override; bool uses_objfile (struct objfile *objfile) override; @@ -694,10 +719,7 @@ public: { } - void assign (struct value *container, - struct value *lhs, struct expression *exp, - std::vector<LONGEST> &indices, - LONGEST low, LONGEST high) override; + void assign (aggregate_assigner &assigner) override; bool uses_objfile (struct objfile *objfile) override; @@ -719,10 +741,7 @@ public: { } - void assign (struct value *container, - struct value *lhs, struct expression *exp, - std::vector<LONGEST> &indices, - LONGEST low, LONGEST high) override; + void assign (aggregate_assigner &assigner) override; bool uses_objfile (struct objfile *objfile) override; @@ -740,14 +759,10 @@ class ada_association public: /* Like ada_component::assign, but takes an operation as a - parameter. The operation is evaluated and then assigned into LHS - according to the rules of the concrete implementation. */ - virtual void assign (struct value *container, - struct value *lhs, - struct expression *exp, - std::vector<LONGEST> &indices, - LONGEST low, LONGEST high, - operation_up &op) = 0; + parameter. The operation is evaluated and then assigned into + ASSIGNER according to the rules of the concrete + implementation. */ + virtual void assign (aggregate_assigner &assigner, operation_up &op) = 0; /* Same as operation::uses_objfile. */ virtual bool uses_objfile (struct objfile *objfile) = 0; @@ -785,10 +800,7 @@ public: m_assocs = std::move (assoc); } - void assign (struct value *container, - struct value *lhs, struct expression *exp, - std::vector<LONGEST> &indices, - LONGEST low, LONGEST high) override; + void assign (aggregate_assigner &assigner) override; bool uses_objfile (struct objfile *objfile) override; @@ -811,11 +823,7 @@ public: { } - void assign (struct value *container, - struct value *lhs, struct expression *exp, - std::vector<LONGEST> &indices, - LONGEST low, LONGEST high, - operation_up &op) override; + void assign (aggregate_assigner &assigner, operation_up &op) override; bool uses_objfile (struct objfile *objfile) override; @@ -839,11 +847,7 @@ public: { } - void assign (struct value *container, - struct value *lhs, struct expression *exp, - std::vector<LONGEST> &indices, - LONGEST low, LONGEST high, - operation_up &op) override; + void assign (aggregate_assigner &assigner, operation_up &op) override; bool uses_objfile (struct objfile *objfile) override; diff --git a/gdb/ada-lang.c b/gdb/ada-lang.c index c9f12d7..84576e7 100644 --- a/gdb/ada-lang.c +++ b/gdb/ada-lang.c @@ -190,9 +190,6 @@ static int ada_is_direct_array_type (struct type *); static struct value *ada_index_struct_field (int, struct value *, int, struct type *); -static void add_component_interval (LONGEST, LONGEST, std::vector<LONGEST> &); - - static struct type *ada_find_any_type (const char *name); static symbol_name_matcher_ftype *ada_get_symbol_name_matcher @@ -9322,13 +9319,10 @@ check_objfile (const std::unique_ptr<ada_component> &comp, return comp->uses_objfile (objfile); } -/* Assign the result of evaluating ARG to the INDEXth component of LHS - (a simple array or a record). Does not modify the inferior's - memory, nor does it modify LHS (unless LHS == CONTAINER). */ +/* See ada-exp.h. */ -static void -assign_component (struct value *container, struct value *lhs, LONGEST index, - struct expression *exp, operation_up &arg) +void +aggregate_assigner::assign (LONGEST index, operation_up &arg) { scoped_value_mark mark; @@ -9383,23 +9377,21 @@ ada_aggregate_component::dump (ui_file *stream, int depth) } void -ada_aggregate_component::assign (struct value *container, - struct value *lhs, struct expression *exp, - std::vector<LONGEST> &indices, - LONGEST low, LONGEST high) +ada_aggregate_component::assign (aggregate_assigner &assigner) { if (m_base != nullptr) { - value *base = m_base->evaluate (nullptr, exp, EVAL_NORMAL); + value *base = m_base->evaluate (nullptr, assigner.exp, EVAL_NORMAL); if (ada_is_direct_array_type (base->type ())) base = ada_coerce_to_simple_array (base); - if (!types_deeply_equal (container->type (), base->type ())) + if (!types_deeply_equal (assigner.container->type (), base->type ())) error (_("Type mismatch in delta aggregate")); - value_assign_to_component (container, container, base); + value_assign_to_component (assigner.container, assigner.container, + base); } for (auto &item : m_components) - item->assign (container, lhs, exp, indices, low, high); + item->assign (assigner); } /* See ada-exp.h. */ @@ -9428,7 +9420,7 @@ ada_aggregate_operation::assign_aggregate (struct value *container, struct expression *exp) { struct type *lhs_type; - LONGEST low_index, high_index; + aggregate_assigner assigner; container = ada_coerce_ref (container); if (ada_is_direct_array_type (container->type ())) @@ -9442,23 +9434,27 @@ ada_aggregate_operation::assign_aggregate (struct value *container, { lhs = ada_coerce_to_simple_array (lhs); lhs_type = check_typedef (lhs->type ()); - low_index = lhs_type->bounds ()->low.const_val (); - high_index = lhs_type->bounds ()->high.const_val (); + assigner.low = lhs_type->bounds ()->low.const_val (); + assigner.high = lhs_type->bounds ()->high.const_val (); } else if (lhs_type->code () == TYPE_CODE_STRUCT) { - low_index = 0; - high_index = num_visible_fields (lhs_type) - 1; + assigner.low = 0; + assigner.high = num_visible_fields (lhs_type) - 1; } else error (_("Left-hand side must be array or record.")); - std::vector<LONGEST> indices (4); - indices[0] = indices[1] = low_index - 1; - indices[2] = indices[3] = high_index + 1; + assigner.indices.push_back (assigner.low - 1); + assigner.indices.push_back (assigner.low - 1); + assigner.indices.push_back (assigner.high + 1); + assigner.indices.push_back (assigner.high + 1); + + assigner.container = container; + assigner.lhs = lhs; + assigner.exp = exp; - std::get<0> (m_storage)->assign (container, lhs, exp, indices, - low_index, high_index); + std::get<0> (m_storage)->assign (assigner); return container; } @@ -9482,19 +9478,16 @@ ada_positional_component::dump (ui_file *stream, int depth) LOW, where HIGH is the upper bound. Record the position in INDICES. CONTAINER is as for assign_aggregate. */ void -ada_positional_component::assign (struct value *container, - struct value *lhs, struct expression *exp, - std::vector<LONGEST> &indices, - LONGEST low, LONGEST high) +ada_positional_component::assign (aggregate_assigner &assigner) { - LONGEST ind = m_index + low; + LONGEST ind = m_index + assigner.low; - if (ind - 1 == high) + if (ind - 1 == assigner.high) warning (_("Extra components in aggregate ignored.")); - if (ind <= high) + if (ind <= assigner.high) { - add_component_interval (ind, ind, indices); - assign_component (container, lhs, ind, exp, m_op); + assigner.add_interval (ind, ind); + assigner.assign (ind, m_op); } } @@ -9513,23 +9506,21 @@ ada_discrete_range_association::dump (ui_file *stream, int depth) } void -ada_discrete_range_association::assign (struct value *container, - struct value *lhs, - struct expression *exp, - std::vector<LONGEST> &indices, - LONGEST low, LONGEST high, +ada_discrete_range_association::assign (aggregate_assigner &assigner, operation_up &op) { - LONGEST lower = value_as_long (m_low->evaluate (nullptr, exp, EVAL_NORMAL)); - LONGEST upper = value_as_long (m_high->evaluate (nullptr, exp, EVAL_NORMAL)); + LONGEST lower = value_as_long (m_low->evaluate (nullptr, assigner.exp, + EVAL_NORMAL)); + LONGEST upper = value_as_long (m_high->evaluate (nullptr, assigner.exp, + EVAL_NORMAL)); - if (lower <= upper && (lower < low || upper > high)) + if (lower <= upper && (lower < assigner.low || upper > assigner.high)) error (_("Index in component association out of bounds.")); - add_component_interval (lower, upper, indices); + assigner.add_interval (lower, upper); while (lower <= upper) { - assign_component (container, lhs, lower, exp, op); + assigner.assign (lower, op); lower += 1; } } @@ -9548,18 +9539,16 @@ ada_name_association::dump (ui_file *stream, int depth) } void -ada_name_association::assign (struct value *container, - struct value *lhs, - struct expression *exp, - std::vector<LONGEST> &indices, - LONGEST low, LONGEST high, +ada_name_association::assign (aggregate_assigner &assigner, operation_up &op) { int index; - if (ada_is_direct_array_type (lhs->type ())) - index = longest_to_int (value_as_long (m_val->evaluate (nullptr, exp, - EVAL_NORMAL))); + if (ada_is_direct_array_type (assigner.lhs->type ())) + { + value *tem = m_val->evaluate (nullptr, assigner.exp, EVAL_NORMAL); + index = longest_to_int (value_as_long (tem)); + } else { ada_string_operation *strop @@ -9585,13 +9574,13 @@ ada_name_association::assign (struct value *container, } index = 0; - if (! find_struct_field (name, lhs->type (), 0, + if (! find_struct_field (name, assigner.lhs->type (), 0, NULL, NULL, NULL, NULL, &index)) error (_("Unknown component name: %s."), name); } - add_component_interval (index, index, indices); - assign_component (container, lhs, index, exp, op); + assigner.add_interval (index, index); + assigner.assign (index, op); } bool @@ -9619,13 +9608,10 @@ ada_choices_component::dump (ui_file *stream, int depth) the allowable indices are LOW..HIGH. Record the indices assigned to in INDICES. CONTAINER is as for assign_aggregate. */ void -ada_choices_component::assign (struct value *container, - struct value *lhs, struct expression *exp, - std::vector<LONGEST> &indices, - LONGEST low, LONGEST high) +ada_choices_component::assign (aggregate_assigner &assigner) { for (auto &item : m_assocs) - item->assign (container, lhs, exp, indices, low, high, m_op); + item->assign (assigner, m_op); } bool @@ -9646,16 +9632,15 @@ ada_others_component::dump (ui_file *stream, int depth) have not been previously assigned. The index intervals already assigned are in INDICES. CONTAINER is as for assign_aggregate. */ void -ada_others_component::assign (struct value *container, - struct value *lhs, struct expression *exp, - std::vector<LONGEST> &indices, - LONGEST low, LONGEST high) +ada_others_component::assign (aggregate_assigner &assigner) { - int num_indices = indices.size (); + int num_indices = assigner.indices.size (); for (int i = 0; i < num_indices - 2; i += 2) { - for (LONGEST ind = indices[i + 1] + 1; ind < indices[i + 2]; ind += 1) - assign_component (container, lhs, ind, exp, m_op); + for (LONGEST ind = assigner.indices[i + 1] + 1; + ind < assigner.indices[i + 2]; + ind += 1) + assigner.assign (ind, m_op); } } @@ -9696,46 +9681,44 @@ ada_assign_operation::evaluate (struct type *expect_type, return ada_value_assign (arg1, arg2); } -} /* namespace expr */ +/* See ada-exp.h. */ -/* Add the interval [LOW .. HIGH] to the sorted set of intervals - [ INDICES[0] .. INDICES[1] ],... The resulting intervals do not - overlap. */ -static void -add_component_interval (LONGEST low, LONGEST high, - std::vector<LONGEST> &indices) +void +aggregate_assigner::add_interval (LONGEST from, LONGEST to) { int i, j; int size = indices.size (); for (i = 0; i < size; i += 2) { - if (high >= indices[i] && low <= indices[i + 1]) + if (to >= indices[i] && from <= indices[i + 1]) { int kh; for (kh = i + 2; kh < size; kh += 2) - if (high < indices[kh]) + if (to < indices[kh]) break; - if (low < indices[i]) - indices[i] = low; + if (from < indices[i]) + indices[i] = from; indices[i + 1] = indices[kh - 1]; - if (high > indices[i + 1]) - indices[i + 1] = high; + if (to > indices[i + 1]) + indices[i + 1] = to; memcpy (indices.data () + i + 2, indices.data () + kh, size - kh); indices.resize (kh - i - 2); return; } - else if (high < indices[i]) + else if (to < indices[i]) break; } indices.resize (indices.size () + 2); for (j = indices.size () - 1; j >= i + 2; j -= 1) indices[j] = indices[j - 2]; - indices[i] = low; - indices[i + 1] = high; + indices[i] = from; + indices[i + 1] = to; } +} /* namespace expr */ + /* Perform and Ada cast of ARG2 to type TYPE if the type of ARG2 is different. */ |