From patchwork Thu Mar 21 19:03:29 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Tom Tromey X-Patchwork-Id: 87470 Return-Path: X-Original-To: patchwork@sourceware.org Delivered-To: patchwork@sourceware.org Received: from server2.sourceware.org (localhost [IPv6:::1]) by sourceware.org (Postfix) with ESMTP id 38AD63858293 for ; Thu, 21 Mar 2024 19:04:27 +0000 (GMT) X-Original-To: gdb-patches@sourceware.org Delivered-To: gdb-patches@sourceware.org Received: from mail-io1-xd2a.google.com (mail-io1-xd2a.google.com [IPv6:2607:f8b0:4864:20::d2a]) by sourceware.org (Postfix) with ESMTPS id 222713858D38 for ; Thu, 21 Mar 2024 19:03:31 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.2 sourceware.org 222713858D38 Authentication-Results: sourceware.org; dmarc=pass (p=quarantine dis=none) header.from=adacore.com Authentication-Results: sourceware.org; spf=pass smtp.mailfrom=adacore.com ARC-Filter: OpenARC Filter v1.0.0 sourceware.org 222713858D38 Authentication-Results: server2.sourceware.org; arc=none smtp.remote-ip=2607:f8b0:4864:20::d2a ARC-Seal: i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1711047815; cv=none; b=IRWlJqsFZPEQED9g1SaxnfKd1KihRxKmRTv2qDglVew3l1xKZOqypfv4VP1R/oc2ZlPGQ/BbyMWoIKujjvQ+EqExoVKln3dIuew4lHp+ZclPlEq78t5zGcx7a+KIudrdn+qJd6fdL2ftfsFIxPirEbUAH96qjyBqWDl8qlLcMZw= ARC-Message-Signature: i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1711047815; c=relaxed/simple; bh=C+pOPiPH4LSDlzHSGZPZnWEmwON1V1ZPO5FVS69zHlk=; h=DKIM-Signature:From:Date:Subject:MIME-Version:Message-Id:To; b=HV7fYMBK2ug/0wxrJmQxA+egdYD4EIbXGk1Wj09MR+2KkJflZLLyMFl/KT7Xb+DiuliK6Gxq1zTqucrSNRb6c2rjzc/pxzEjA62i01SxyoJLkjDhX2pcqjRtm486JrTlFxs4GdEjPREGPLLam+RXJOtXXhqewDfhKSuNNfAnybU= ARC-Authentication-Results: i=1; server2.sourceware.org Received: by mail-io1-xd2a.google.com with SMTP id ca18e2360f4ac-7cde3cbf03aso63080839f.1 for ; Thu, 21 Mar 2024 12:03:31 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=adacore.com; s=google; t=1711047810; x=1711652610; darn=sourceware.org; h=to:in-reply-to:references:message-id:content-transfer-encoding :mime-version:subject:date:from:from:to:cc:subject:date:message-id :reply-to; bh=3CTCBagNV/Tp5M++ByH2+Oo1U1YhHC0h8SM0ssu3QN4=; b=cUaY+fZ48L+fi0ICR/bcQFsZx/G2qco24tOZxHpu59KTNuG6+nBn3RVWjdkPgHbl8O uF+He7bEEpqvL3ZrnIV+skPGu4F7xO0/Wo2uUL287D1T5o0vU3xkXXTd+KVzC/+6iIiD DHQN2RNJI5TQH+RpzpgUZd9rPvYvDZUGoBy4ExkxxjZdr5eoJ5zlUvd2V9wisnBMUupf u1Bmkbf7plRVmh56lAam5qNWG3SjpYsZrqiDB7f9g0Xty3yZSSI8nBOvjUSacgcih9Al 2uWwCP8ZHSitgPolCCfCpJJAtnn5QPuqTa5Ksa+DcVENjPvrxnCZ4CtECQgoLaZRg3Dk +RkA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1711047810; x=1711652610; h=to:in-reply-to:references:message-id:content-transfer-encoding :mime-version:subject:date:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=3CTCBagNV/Tp5M++ByH2+Oo1U1YhHC0h8SM0ssu3QN4=; b=NLtv7eAiwGSUHgIip6+o+L8u9wDzfeOBcCWNuwjE9kh6Rhgvbpqul8XLbX9IF2gZvY z8VuRmp9ASQ1WTjoJIwEZWwqWtvu3oXyGEeL7Bm6aXPnHHF4joPswG75WGNQkEm4uLYE vBGmtuS0riMZSc+uizLQe2zXrC2BOdSxPPkFfmvfQy/rQdQPTaPWIZqWxuNvXqO37pLp KHFQn0ZlJwP7lchzF1MHVj9t8we3UMhlGf5UufRgV9WduztOhoGQJyvz/kp/qybJe/mj tN0cB4tWrKBGwM2qUUf39Vh0ZFpBHgAAwQ7Dt4/rmKPIY/4sU39S229c6xzxoIqatKnY s6sQ== X-Gm-Message-State: AOJu0YyXhj+MOapY6U/h0aE3LwHvVKcJh+31vQw2Dm7U+mK4dBjxmrDZ u09lFUhlvIu04C7d/XxIDtayrn1hjRGfoIqE9uioBrRRCLYBd8rQPVU79+17Y3HXTgrMBUqLERM = X-Google-Smtp-Source: AGHT+IHHP7h0TdbpdYgRVgf7tjK8xag3p3r3jDjMt+liDAI8Ng5Tz/lK6KD8JEfCv2rRMf0yRCMd9Q== X-Received: by 2002:a6b:e719:0:b0:7cc:b3:889e with SMTP id b25-20020a6be719000000b007cc00b3889emr417206ioh.11.1711047810220; Thu, 21 Mar 2024 12:03:30 -0700 (PDT) Received: from localhost.localdomain (97-122-82-115.hlrn.qwest.net. [97.122.82.115]) by smtp.gmail.com with ESMTPSA id dp10-20020a0566381c8a00b00476f2bfc3f8sm53358jab.87.2024.03.21.12.03.29 for (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 21 Mar 2024 12:03:30 -0700 (PDT) From: Tom Tromey Date: Thu, 21 Mar 2024 13:03:29 -0600 Subject: [PATCH 01/12] Introduce and use aggregate_assigner type MIME-Version: 1.0 Message-Id: <20240321-ada-iterated-assign-v1-1-925cdd4f1f4a@adacore.com> References: <20240321-ada-iterated-assign-v1-0-925cdd4f1f4a@adacore.com> In-Reply-To: <20240321-ada-iterated-assign-v1-0-925cdd4f1f4a@adacore.com> To: gdb-patches@sourceware.org X-Mailer: b4 0.12.4 X-Spam-Status: No, score=-11.2 required=5.0 tests=BAYES_00, DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, DKIM_VALID_EF, GIT_PATCH_0, RCVD_IN_DNSWL_NONE, SPF_HELO_NONE, SPF_PASS, TXREP autolearn=ham autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on server2.sourceware.org X-BeenThere: gdb-patches@sourceware.org X-Mailman-Version: 2.1.30 Precedence: list List-Id: Gdb-patches mailing list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: gdb-patches-bounces+patchwork=sourceware.org@sourceware.org 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. --- 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 @@ class ada_target_operation : public operation 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 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 &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 @@ class ada_aggregate_component : public ada_component ada_aggregate_component (operation_up &&base, std::vector &&components); - 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; bool uses_objfile (struct objfile *objfile) override; @@ -694,10 +719,7 @@ class ada_positional_component : public ada_component { } - 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; bool uses_objfile (struct objfile *objfile) override; @@ -719,10 +741,7 @@ class ada_others_component : public ada_component { } - 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; 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 &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 @@ class ada_choices_component : public ada_component m_assocs = std::move (assoc); } - 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; bool uses_objfile (struct objfile *objfile) override; @@ -811,11 +823,7 @@ class ada_discrete_range_association : public ada_association { } - 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; bool uses_objfile (struct objfile *objfile) override; @@ -839,11 +847,7 @@ class ada_name_association : public ada_association { } - 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; bool uses_objfile (struct objfile *objfile) override; diff --git a/gdb/ada-lang.c b/gdb/ada-lang.c index 493ef3b6c7d..c9cbeca40bc 100644 --- a/gdb/ada-lang.c +++ b/gdb/ada-lang.c @@ -191,9 +191,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 &); - - static struct type *ada_find_any_type (const char *name); static symbol_name_matcher_ftype *ada_get_symbol_name_matcher @@ -9323,13 +9320,10 @@ check_objfile (const std::unique_ptr &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; @@ -9384,23 +9378,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 &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. */ @@ -9429,7 +9421,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 ())) @@ -9443,23 +9435,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 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; } @@ -9483,19 +9479,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 &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); } } @@ -9514,23 +9507,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 &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; } } @@ -9549,18 +9540,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 &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 @@ -9586,13 +9575,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 @@ -9620,13 +9609,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 &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 @@ -9647,16 +9633,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 &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); } } @@ -9697,46 +9682,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 &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. */