From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: by sourceware.org (Postfix, from userid 2126) id 63F653858425; Tue, 2 Apr 2024 17:35:32 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org 63F653858425 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=sourceware.org; s=default; t=1712079332; bh=6qKFFYTtN+fz3tbehBkd8KUYwS6UrHEgejlyJltRC3o=; h=From:To:Subject:Date:From; b=VP2iAxceNPKc6JozcprxrYI+AlT6YmuuL/7s6hyhiMV/YGRf7Iv2Tcfr4USH/U8cw S2N7dqGURNwZgym+jtWJFqDCOvFe3Ux6qcoH+9qAS6+WWftaGmnLqgifm39K3lqI2E du7yklXjnWzPfD41YWwDGh2KTF0lQh3cbCkbwbXs= Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable From: Tom Tromey To: gdb-cvs@sourceware.org Subject: [binutils-gdb] Introduce and use aggregate_assigner type X-Act-Checkin: binutils-gdb X-Git-Author: Tom Tromey X-Git-Refname: refs/heads/master X-Git-Oldrev: c2cf30e7608093773286081ebfc4067246ecba7e X-Git-Newrev: d9d782dd8b6c3665c28f6b610175a0756a7805a4 Message-Id: <20240402173532.63F653858425@sourceware.org> Date: Tue, 2 Apr 2024 17:35:32 +0000 (GMT) List-Id: https://sourceware.org/git/gitweb.cgi?p=3Dbinutils-gdb.git;h=3Dd9d782dd8b6c= 3665c28f6b610175a0756a7805a4 commit d9d782dd8b6c3665c28f6b610175a0756a7805a4 Author: Tom Tromey Date: Tue Mar 5 07:25:08 2024 -0700 Introduce and use aggregate_assigner type =20 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. Diff: --- gdb/ada-exp.h | 88 +++++++++++++++++---------------- 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 69d4e90e410..6122502dcdc 100644 --- a/gdb/ada-exp.h +++ b/gdb/ada-exp.h @@ -588,20 +588,48 @@ private: ada_assign_operation *m_lhs; }; =20 +/* 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 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 =3D=3D 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: =20 - /* 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 &indices, - LONGEST low, LONGEST high) =3D 0; + /* Assign to ASSIGNER. */ + virtual void assign (aggregate_assigner &assigner) =3D 0; =20 /* Same as operation::uses_objfile. */ virtual bool uses_objfile (struct objfile *objfile) =3D 0; @@ -664,10 +692,7 @@ public: ada_aggregate_component (operation_up &&base, std::vector &&components); =20 - void assign (struct value *container, - struct value *lhs, struct expression *exp, - std::vector &indices, - LONGEST low, LONGEST high) override; + void assign (aggregate_assigner &assigner) override; =20 bool uses_objfile (struct objfile *objfile) override; =20 @@ -694,10 +719,7 @@ public: { } =20 - void assign (struct value *container, - struct value *lhs, struct expression *exp, - std::vector &indices, - LONGEST low, LONGEST high) override; + void assign (aggregate_assigner &assigner) override; =20 bool uses_objfile (struct objfile *objfile) override; =20 @@ -719,10 +741,7 @@ public: { } =20 - void assign (struct value *container, - struct value *lhs, struct expression *exp, - std::vector &indices, - LONGEST low, LONGEST high) override; + void assign (aggregate_assigner &assigner) override; =20 bool uses_objfile (struct objfile *objfile) override; =20 @@ -740,14 +759,10 @@ class ada_association public: =20 /* 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 &indices, - LONGEST low, LONGEST high, - operation_up &op) =3D 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) =3D= 0; =20 /* Same as operation::uses_objfile. */ virtual bool uses_objfile (struct objfile *objfile) =3D 0; @@ -785,10 +800,7 @@ public: m_assocs =3D std::move (assoc); } =20 - void assign (struct value *container, - struct value *lhs, struct expression *exp, - std::vector &indices, - LONGEST low, LONGEST high) override; + void assign (aggregate_assigner &assigner) override; =20 bool uses_objfile (struct objfile *objfile) override; =20 @@ -811,11 +823,7 @@ public: { } =20 - void assign (struct value *container, - struct value *lhs, struct expression *exp, - std::vector &indices, - LONGEST low, LONGEST high, - operation_up &op) override; + void assign (aggregate_assigner &assigner, operation_up &op) override; =20 bool uses_objfile (struct objfile *objfile) override; =20 @@ -839,11 +847,7 @@ public: { } =20 - void assign (struct value *container, - struct value *lhs, struct expression *exp, - std::vector &indices, - LONGEST low, LONGEST high, - operation_up &op) override; + void assign (aggregate_assigner &assigner, operation_up &op) override; =20 bool uses_objfile (struct objfile *objfile) override; =20 diff --git a/gdb/ada-lang.c b/gdb/ada-lang.c index c9f12d72b70..84576e7db7d 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 *); =20 -static void add_component_interval (LONGEST, LONGEST, std::vector= &); - - static struct type *ada_find_any_type (const char *name); =20 static symbol_name_matcher_ftype *ada_get_symbol_name_matcher @@ -9322,13 +9319,10 @@ check_objfile (const std::unique_ptr= &comp, return comp->uses_objfile (objfile); } =20 -/* 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 =3D=3D CONTAINER). */ +/* See ada-exp.h. */ =20 -static void -assign_component (struct value *container, struct value *lhs, LONGEST inde= x, - struct expression *exp, operation_up &arg) +void +aggregate_assigner::assign (LONGEST index, operation_up &arg) { scoped_value_mark mark; =20 @@ -9383,23 +9377,21 @@ ada_aggregate_component::dump (ui_file *stream, int= depth) } =20 void -ada_aggregate_component::assign (struct value *container, - struct value *lhs, struct expression *exp, - std::vector &indices, - LONGEST low, LONGEST high) +ada_aggregate_component::assign (aggregate_assigner &assigner) { if (m_base !=3D nullptr) { - value *base =3D m_base->evaluate (nullptr, exp, EVAL_NORMAL); + value *base =3D m_base->evaluate (nullptr, assigner.exp, EVAL_NORMAL= ); if (ada_is_direct_array_type (base->type ())) base =3D 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); } =20 for (auto &item : m_components) - item->assign (container, lhs, exp, indices, low, high); + item->assign (assigner); } =20 /* See ada-exp.h. */ @@ -9428,7 +9420,7 @@ ada_aggregate_operation::assign_aggregate (struct val= ue *container, struct expression *exp) { struct type *lhs_type; - LONGEST low_index, high_index; + aggregate_assigner assigner; =20 container =3D ada_coerce_ref (container); if (ada_is_direct_array_type (container->type ())) @@ -9442,23 +9434,27 @@ ada_aggregate_operation::assign_aggregate (struct v= alue *container, { lhs =3D ada_coerce_to_simple_array (lhs); lhs_type =3D check_typedef (lhs->type ()); - low_index =3D lhs_type->bounds ()->low.const_val (); - high_index =3D lhs_type->bounds ()->high.const_val (); + assigner.low =3D lhs_type->bounds ()->low.const_val (); + assigner.high =3D lhs_type->bounds ()->high.const_val (); } else if (lhs_type->code () =3D=3D TYPE_CODE_STRUCT) { - low_index =3D 0; - high_index =3D num_visible_fields (lhs_type) - 1; + assigner.low =3D 0; + assigner.high =3D num_visible_fields (lhs_type) - 1; } else error (_("Left-hand side must be array or record.")); =20 - std::vector indices (4); - indices[0] =3D indices[1] =3D low_index - 1; - indices[2] =3D indices[3] =3D 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 =3D container; + assigner.lhs =3D lhs; + assigner.exp =3D exp; =20 - std::get<0> (m_storage)->assign (container, lhs, exp, indices, - low_index, high_index); + std::get<0> (m_storage)->assign (assigner); =20 return container; } @@ -9482,19 +9478,16 @@ ada_positional_component::dump (ui_file *stream, in= t 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 &indices, - LONGEST low, LONGEST high) +ada_positional_component::assign (aggregate_assigner &assigner) { - LONGEST ind =3D m_index + low; + LONGEST ind =3D m_index + assigner.low; =20 - if (ind - 1 =3D=3D high) + if (ind - 1 =3D=3D assigner.high) warning (_("Extra components in aggregate ignored.")); - if (ind <=3D high) + if (ind <=3D 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); } } =20 @@ -9513,23 +9506,21 @@ ada_discrete_range_association::dump (ui_file *stre= am, int depth) } =20 void -ada_discrete_range_association::assign (struct value *container, - struct value *lhs, - struct expression *exp, - std::vector &indices, - LONGEST low, LONGEST high, +ada_discrete_range_association::assign (aggregate_assigner &assigner, operation_up &op) { - LONGEST lower =3D value_as_long (m_low->evaluate (nullptr, exp, EVAL_NOR= MAL)); - LONGEST upper =3D value_as_long (m_high->evaluate (nullptr, exp, EVAL_NO= RMAL)); + LONGEST lower =3D value_as_long (m_low->evaluate (nullptr, assigner.exp, + EVAL_NORMAL)); + LONGEST upper =3D value_as_long (m_high->evaluate (nullptr, assigner.exp, + EVAL_NORMAL)); =20 - if (lower <=3D upper && (lower < low || upper > high)) + if (lower <=3D upper && (lower < assigner.low || upper > assigner.high)) error (_("Index in component association out of bounds.")); =20 - add_component_interval (lower, upper, indices); + assigner.add_interval (lower, upper); while (lower <=3D upper) { - assign_component (container, lhs, lower, exp, op); + assigner.assign (lower, op); lower +=3D 1; } } @@ -9548,18 +9539,16 @@ ada_name_association::dump (ui_file *stream, int de= pth) } =20 void -ada_name_association::assign (struct value *container, - struct value *lhs, - struct expression *exp, - std::vector &indices, - LONGEST low, LONGEST high, +ada_name_association::assign (aggregate_assigner &assigner, operation_up &op) { int index; =20 - if (ada_is_direct_array_type (lhs->type ())) - index =3D longest_to_int (value_as_long (m_val->evaluate (nullptr, exp, - EVAL_NORMAL))); + if (ada_is_direct_array_type (assigner.lhs->type ())) + { + value *tem =3D m_val->evaluate (nullptr, assigner.exp, EVAL_NORMAL); + index =3D longest_to_int (value_as_long (tem)); + } else { ada_string_operation *strop @@ -9585,13 +9574,13 @@ ada_name_association::assign (struct value *contain= er, } =20 index =3D 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); } =20 - add_component_interval (index, index, indices); - assign_component (container, lhs, index, exp, op); + assigner.add_interval (index, index); + assigner.assign (index, op); } =20 bool @@ -9619,13 +9608,10 @@ ada_choices_component::dump (ui_file *stream, int d= epth) 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 &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); } =20 bool @@ -9646,16 +9632,15 @@ ada_others_component::dump (ui_file *stream, int de= pth) 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 &indices, - LONGEST low, LONGEST high) +ada_others_component::assign (aggregate_assigner &assigner) { - int num_indices =3D indices.size (); + int num_indices =3D assigner.indices.size (); for (int i =3D 0; i < num_indices - 2; i +=3D 2) { - for (LONGEST ind =3D indices[i + 1] + 1; ind < indices[i + 2]; ind += =3D 1) - assign_component (container, lhs, ind, exp, m_op); + for (LONGEST ind =3D assigner.indices[i + 1] + 1; + ind < assigner.indices[i + 2]; + ind +=3D 1) + assigner.assign (ind, m_op); } } =20 @@ -9696,46 +9681,44 @@ ada_assign_operation::evaluate (struct type *expect= _type, return ada_value_assign (arg1, arg2); } =20 -} /* namespace expr */ +/* See ada-exp.h. */ =20 -/* 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,=20 - std::vector &indices) +void +aggregate_assigner::add_interval (LONGEST from, LONGEST to) { int i, j; =20 int size =3D indices.size (); for (i =3D 0; i < size; i +=3D 2) { - if (high >=3D indices[i] && low <=3D indices[i + 1]) + if (to >=3D indices[i] && from <=3D indices[i + 1]) { int kh; =20 for (kh =3D i + 2; kh < size; kh +=3D 2) - if (high < indices[kh]) + if (to < indices[kh]) break; - if (low < indices[i]) - indices[i] =3D low; + if (from < indices[i]) + indices[i] =3D from; indices[i + 1] =3D indices[kh - 1]; - if (high > indices[i + 1]) - indices[i + 1] =3D high; + if (to > indices[i + 1]) + indices[i + 1] =3D 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; } =09 indices.resize (indices.size () + 2); for (j =3D indices.size () - 1; j >=3D i + 2; j -=3D 1) indices[j] =3D indices[j - 2]; - indices[i] =3D low; - indices[i + 1] =3D high; + indices[i] =3D from; + indices[i + 1] =3D to; } =20 +} /* namespace expr */ + /* Perform and Ada cast of ARG2 to type TYPE if the type of ARG2 is different. */