From patchwork Thu Feb 23 19:48:00 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Tom Tromey X-Patchwork-Id: 65535 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 AA142385086B for ; Thu, 23 Feb 2023 19:48:38 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org AA142385086B DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=sourceware.org; s=default; t=1677181718; bh=LXbkZOQ7ar5DP+EXnpCiL5n428qGDe47ynnSE9fZgRI=; h=Date:Subject:References:In-Reply-To:To:List-Id:List-Unsubscribe: List-Archive:List-Post:List-Help:List-Subscribe:From:Reply-To: From; b=OBPy3xfy3guImh9c9yAdPE0K68qkj1ZVBZJqVk32buSiqBmWnejMUMyvAV/j+tLD2 HFbvxWphBFiLGb5FMUCmcpjnYm0YBECDuM2xk6cCRBmaX563zb9c4UfjCKIM9xT+DC 0Pk6u1S5uNBNAtKHDVf/BBcxsGqUI2KpFM3Rurec= X-Original-To: gdb-patches@sourceware.org Delivered-To: gdb-patches@sourceware.org Received: from mail-il1-x12a.google.com (mail-il1-x12a.google.com [IPv6:2607:f8b0:4864:20::12a]) by sourceware.org (Postfix) with ESMTPS id 2F603385842B for ; Thu, 23 Feb 2023 19:48:04 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.2 sourceware.org 2F603385842B Received: by mail-il1-x12a.google.com with SMTP id e10so5865755ilu.4 for ; Thu, 23 Feb 2023 11:48:04 -0800 (PST) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; 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=LXbkZOQ7ar5DP+EXnpCiL5n428qGDe47ynnSE9fZgRI=; b=VvYoGjU1EEYMUtciT8l30uVtkpfQPTEWevsxba9f7XOVlyRPDQKj9brRFpAl0H0cCt bvNHVukGlBheiTPex8L1p09OFiyn0CiC5GaoQq6rZT5dNkrW9czARZ2EWPbrW8lDTAwB e5fckoenn5oQKcHxLjNZx3nIWKrBwQ1iDN1TB6kn6FuQASJi6bBmigcj/rpvLvrEuixf igNK0+TNBrJDh/mpDV3tvIdB/26+9wUCXzxapSIjQozQ/IyOKqYRkjLKJApa39j205dU 2tsjN/XpUbDQpHQpK+XaYcbaL4mkuOS7/9JGJTQdMDFO3nxVOqFNDTdOildGJ1pN7mG6 dbeQ== X-Gm-Message-State: AO0yUKUr5qDW9DBerlzCczzuijf+tFuz9relQrx3rhjzqfmMMc5MoSMV ojXIsOagb+a5LJXuWmNhP3fniS3iFKyFEqfJ X-Google-Smtp-Source: AK7set9YP9s/OuoBLqMpVyTGk5HamfmVPnCFuvbZcDsJs7mjPM6Y3CfDCjdB1BTrrb8V/rn/RwUC1A== X-Received: by 2002:a05:6e02:1485:b0:315:3eac:6293 with SMTP id n5-20020a056e02148500b003153eac6293mr9984349ilk.4.1677181683258; Thu, 23 Feb 2023 11:48:03 -0800 (PST) Received: from localhost.localdomain (75-166-130-93.hlrn.qwest.net. [75.166.130.93]) by smtp.gmail.com with ESMTPSA id x4-20020a920604000000b00316e4139270sm2038351ilg.35.2023.02.23.11.48.02 for (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 23 Feb 2023 11:48:02 -0800 (PST) Date: Thu, 23 Feb 2023 12:48:00 -0700 Subject: [PATCH 2/6] Add methods and operators to gdb_mpz MIME-Version: 1.0 Message-Id: <20230223-submit-gmp-hiding-v1-2-ea6ff9e32716@adacore.com> References: <20230223-submit-gmp-hiding-v1-0-ea6ff9e32716@adacore.com> In-Reply-To: <20230223-submit-gmp-hiding-v1-0-ea6ff9e32716@adacore.com> To: gdb-patches@sourceware.org X-Mailer: b4 0.12.0 X-Spam-Status: No, score=-11.7 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.29 Precedence: list List-Id: Gdb-patches mailing list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-Patchwork-Original-From: Tom Tromey via Gdb-patches From: Tom Tromey Reply-To: Tom Tromey Errors-To: gdb-patches-bounces+patchwork=sourceware.org@sourceware.org Sender: "Gdb-patches" This adds various methods and operators to gdb_mpz, as a step toward hiding the implementation. This only adds the operators that were needed. Many more could be added as required. --- gdb/ada-lex.l | 9 ++-- gdb/dwarf2/read.c | 46 +++++++++----------- gdb/gmp-utils.h | 87 +++++++++++++++++++++++++++++++++++++ gdb/unittests/gmp-utils-selftests.c | 54 +++++++++++------------ gdb/valops.c | 2 +- gdb/value.c | 3 +- 6 files changed, 140 insertions(+), 61 deletions(-) diff --git a/gdb/ada-lex.l b/gdb/ada-lex.l index a5cfb84dcae..69fc14f7107 100644 --- a/gdb/ada-lex.l +++ b/gdb/ada-lex.l @@ -422,14 +422,14 @@ processInt (struct parser_state *par_state, const char *base0, int dig = fromhex (*num0); if (dig >= base) error (_("Invalid digit `%c' in based literal"), *num0); - mpz_mul_ui (result.val, result.val, base); - mpz_add_ui (result.val, result.val, dig); + result *= base; + result += dig; ++num0; } while (exp > 0) { - mpz_mul_ui (result.val, result.val, base); + result *= base; exp -= 1; } @@ -462,8 +462,7 @@ processInt (struct parser_state *par_state, const char *base0, return FLOAT; } - gdb_mpz maxval (ULONGEST_MAX); - if (mpz_cmp (result.val, maxval.val) > 0) + if (result > gdb_mpz (ULONGEST_MAX)) error (_("Integer literal out of range")); int int_bits = gdbarch_int_bit (par_state->gdbarch ()); diff --git a/gdb/dwarf2/read.c b/gdb/dwarf2/read.c index a5bc1d89a2d..cef79b6531b 100644 --- a/gdb/dwarf2/read.c +++ b/gdb/dwarf2/read.c @@ -14756,10 +14756,10 @@ get_mpz (struct dwarf2_cu *cu, gdb_mpz *value, struct attribute *attr) &len); if (ptr - blk->data + len <= blk->size) { - mpz_import (value->val, len, - bfd_big_endian (cu->per_objfile->objfile->obfd.get ()) - ? 1 : -1, - 1, 0, 0, ptr); + value->read (gdb::make_array_view (ptr, len), + bfd_big_endian (cu->per_objfile->objfile->obfd.get ()) + ? BFD_ENDIAN_BIG : BFD_ENDIAN_LITTLE, + true); return; } } @@ -14770,10 +14770,10 @@ get_mpz (struct dwarf2_cu *cu, gdb_mpz *value, struct attribute *attr) else if (attr->form_is_block ()) { dwarf_block *blk = attr->as_block (); - mpz_import (value->val, blk->size, - bfd_big_endian (cu->per_objfile->objfile->obfd.get ()) - ? 1 : -1, - 1, 0, 0, blk->data); + value->read (gdb::make_array_view (blk->data, blk->size), + bfd_big_endian (cu->per_objfile->objfile->obfd.get ()) + ? BFD_ENDIAN_BIG : BFD_ENDIAN_LITTLE, + true); } else *value = gdb_mpz (attr->constant_value (1)); @@ -14825,19 +14825,19 @@ get_dwarf2_unsigned_rational_constant (struct die_info *die, gdb_mpz denom (1); get_dwarf2_rational_constant (die, cu, &num, &denom); - if (mpz_sgn (num.val) == -1 && mpz_sgn (denom.val) == -1) + if (num < 0 && denom < 0) { - mpz_neg (num.val, num.val); - mpz_neg (denom.val, denom.val); + num.negate (); + denom.negate (); } - else if (mpz_sgn (num.val) == -1) + else if (num < 0) { complaint (_("unexpected negative value for DW_AT_GNU_numerator" " in DIE at %s"), sect_offset_str (die->sect_off)); return; } - else if (mpz_sgn (denom.val) == -1) + else if (denom < 0) { complaint (_("unexpected negative value for DW_AT_GNU_denominator" " in DIE at %s"), @@ -14876,10 +14876,7 @@ ada_get_gnat_encoded_number (const char *encoding, int &k, gdb_mpz *result) return false; std::string copy (&encoding[start], k - start); - if (mpz_set_str (result->val, copy.c_str (), 10) == -1) - return false; - - return true; + return result->set (copy.c_str (), 10); } /* Scan two numbers from ENCODING at OFFSET, assuming the string is of @@ -14959,16 +14956,16 @@ finish_fixed_point_type (struct type *type, const char *suffix, else if (attr->name == DW_AT_binary_scale) { LONGEST scale_exp = attr->constant_value (0); - gdb_mpz *num_or_denom = scale_exp > 0 ? &scale_num : &scale_denom; + gdb_mpz &num_or_denom = scale_exp > 0 ? scale_num : scale_denom; - mpz_mul_2exp (num_or_denom->val, num_or_denom->val, std::abs (scale_exp)); + num_or_denom <<= std::abs (scale_exp); } else if (attr->name == DW_AT_decimal_scale) { LONGEST scale_exp = attr->constant_value (0); - gdb_mpz *num_or_denom = scale_exp > 0 ? &scale_num : &scale_denom; + gdb_mpz &num_or_denom = scale_exp > 0 ? scale_num : scale_denom; - mpz_ui_pow_ui (num_or_denom->val, 10, std::abs (scale_exp)); + num_or_denom = gdb_mpz::pow (10, std::abs (scale_exp)); } else if (attr->name == DW_AT_small) { @@ -14992,10 +14989,7 @@ finish_fixed_point_type (struct type *type, const char *suffix, sect_offset_str (die->sect_off)); } - gdb_mpq &scaling_factor = type->fixed_point_info ().scaling_factor; - mpz_set (mpq_numref (scaling_factor.val), scale_num.val); - mpz_set (mpq_denref (scaling_factor.val), scale_denom.val); - mpq_canonicalize (scaling_factor.val); + type->fixed_point_info ().scaling_factor = gdb_mpq (scale_num, scale_denom); } /* The gnat-encoding suffix for fixed point. */ @@ -15076,7 +15070,7 @@ has_zero_over_zero_small_attribute (struct die_info *die, gdb_mpz num (1), denom (1); get_dwarf2_rational_constant (scale_die, cu, &num, &denom); - return mpz_sgn (num.val) == 0 && mpz_sgn (denom.val) == 0; + return num == 0 && denom == 0; } /* Initialise and return a floating point type of size BITS suitable for diff --git a/gdb/gmp-utils.h b/gdb/gmp-utils.h index 0522f3453aa..dcb998a1656 100644 --- a/gdb/gmp-utils.h +++ b/gdb/gmp-utils.h @@ -89,6 +89,21 @@ struct gdb_mpz return *this; } + /* Initialize this value from a string and a base. Returns true if + the string was parsed successfully, false otherwise. */ + bool set (const char *str, int base) + { + return mpz_set_str (val, str, base) != -1; + } + + /* Return a new value that is BASE**EXP. */ + static gdb_mpz pow (unsigned long base, unsigned long exp) + { + gdb_mpz result; + mpz_ui_pow_ui (result.val, base, exp); + return result; + } + /* Convert VAL to an integer of the given type. The return type can signed or unsigned, with no size restriction. */ @@ -115,6 +130,56 @@ struct gdb_mpz /* The destructor. */ ~gdb_mpz () { mpz_clear (val); } + /* Negate this value in place. */ + void negate () + { + mpz_neg (val, val); + } + + gdb_mpz &operator*= (long other) + { + mpz_mul_si (val, val, other); + return *this; + } + + gdb_mpz &operator+= (unsigned long other) + { + mpz_add_ui (val, val, other); + return *this; + } + + gdb_mpz &operator-= (unsigned long other) + { + mpz_sub_ui (val, val, other); + return *this; + } + + gdb_mpz &operator<<= (unsigned long nbits) + { + mpz_mul_2exp (val, val, nbits); + return *this; + } + + bool operator> (const gdb_mpz &other) const + { + return mpz_cmp (val, other.val) > 0; + } + + bool operator< (int other) const + { + return mpz_cmp_si (val, other) < 0; + } + + bool operator== (int other) const + { + return mpz_cmp_si (val, other) == 0; + } + + bool operator== (const gdb_mpz &other) const + { + return mpz_cmp (val, other.val) == 0; + } + private: /* Helper template for constructor and operator=. */ @@ -166,6 +231,14 @@ struct gdb_mpq mpq_swap (val, from.val); } + gdb_mpq (const gdb_mpz &num, const gdb_mpz &denom) + { + mpq_init (val); + mpz_set (mpq_numref (val), num.val); + mpz_set (mpq_denref (val), denom.val); + mpq_canonicalize (val); + } + /* Copy assignment operator. */ gdb_mpq &operator= (const gdb_mpq &from) { @@ -179,12 +252,26 @@ struct gdb_mpq return *this; } + gdb_mpq &operator= (const gdb_mpz &from) + { + mpq_set_z (val, from.val); + return *this; + } + /* Return a string representing VAL as " / ". */ std::string str () const { return gmp_string_printf ("%Qd", val); } /* Return VAL rounded to the nearest integer. */ gdb_mpz get_rounded () const; + /* Return this value as an integer, rounded toward zero. */ + gdb_mpz as_integer () const + { + gdb_mpz result; + mpz_tdiv_q (result.val, mpq_numref (val), mpq_denref (val)); + return result; + } + /* Set VAL from the contents of the given byte array (BUF), which contains the unscaled value of a fixed point type object. The byte size of the data is the size of BUF. diff --git a/gdb/unittests/gmp-utils-selftests.c b/gdb/unittests/gmp-utils-selftests.c index e2ccd2ca094..8e028fec88c 100644 --- a/gdb/unittests/gmp-utils-selftests.c +++ b/gdb/unittests/gmp-utils-selftests.c @@ -43,8 +43,8 @@ gdb_mpz_as_integer () /* Start with the smallest LONGEST */ l_expected = (LONGEST) 1 << (sizeof (LONGEST) * 8 - 1); - mpz_ui_pow_ui (v.val, 2, sizeof (LONGEST) * 8 - 1); - mpz_neg (v.val, v.val); + v = gdb_mpz::pow (2, sizeof (LONGEST) * 8 - 1); + v.negate (); SELF_CHECK (v.as_integer () == l_expected); @@ -53,13 +53,13 @@ gdb_mpz_as_integer () for (int i = -256; i <= 256; i++) { l_expected = (LONGEST) i; - mpz_set_si (v.val, i); + v = i; SELF_CHECK (v.as_integer () == l_expected); if (i >= 0) { ul_expected = (ULONGEST) i; - mpz_set_ui (v.val, i); + v = ul_expected; SELF_CHECK (v.as_integer () == ul_expected); } } @@ -68,16 +68,16 @@ gdb_mpz_as_integer () l_expected = LONGEST_MAX; ul_expected = (ULONGEST) l_expected; - mpz_ui_pow_ui (v.val, 2, sizeof (LONGEST) * 8 - 1); - mpz_sub_ui (v.val, v.val, 1); + v = gdb_mpz::pow (2, sizeof (LONGEST) * 8 - 1); + v -= 1; SELF_CHECK (v.as_integer () == l_expected); SELF_CHECK (v.as_integer () == ul_expected); /* Try with ULONGEST_MAX. */ ul_expected = ULONGEST_MAX; - mpz_ui_pow_ui (v.val, 2, sizeof (LONGEST) * 8); - mpz_sub_ui (v.val, v.val, 1); + v = gdb_mpz::pow (2, sizeof (LONGEST) * 8); + v -= 1; SELF_CHECK (v.as_integer () == ul_expected); } @@ -116,9 +116,9 @@ gdb_mpz_as_integer_out_of_range () gdb_mpz v; /* Try LONGEST_MIN minus 1. */ - mpz_ui_pow_ui (v.val, 2, sizeof (LONGEST) * 8 - 1); - mpz_neg (v.val, v.val); - mpz_sub_ui (v.val, v.val, 1); + v = gdb_mpz::pow (2, sizeof (LONGEST) * 8 - 1); + v.negate (); + v -= 1; check_as_integer_raises_out_of_range_error (v); check_as_integer_raises_out_of_range_error (v); @@ -131,14 +131,14 @@ gdb_mpz_as_integer_out_of_range () /* Try LONGEST_MAX plus 1. */ v = LONGEST_MAX; - mpz_add_ui (v.val, v.val, 1); + v += 1; SELF_CHECK (v.as_integer () == (ULONGEST) LONGEST_MAX + 1); check_as_integer_raises_out_of_range_error (v); /* Try ULONGEST_MAX plus 1. */ v = ULONGEST_MAX; - mpz_add_ui (v.val, v.val, 1); + v += 1; check_as_integer_raises_out_of_range_error (v); check_as_integer_raises_out_of_range_error (v); @@ -170,8 +170,8 @@ store_and_read_back (T val, size_t buf_len, enum bfd_endian byte_order, store_integer (buf, buf_len, byte_order, val); /* Pre-initialize ACTUAL to something that's not the expected value. */ - mpz_set (actual.val, expected.val); - mpz_sub_ui (actual.val, actual.val, 500); + actual = expected; + actual -= 500; actual.read ({buf, buf_len}, byte_order, !std::is_signed::value); } @@ -197,10 +197,10 @@ gdb_mpz_read_all_from_small () gdb_mpz expected, actual; store_and_read_back (l, buf_len, BFD_ENDIAN_BIG, expected, actual); - SELF_CHECK (mpz_cmp (actual.val, expected.val) == 0); + SELF_CHECK (actual == expected); store_and_read_back (l, buf_len, BFD_ENDIAN_LITTLE, expected, actual); - SELF_CHECK (mpz_cmp (actual.val, expected.val) == 0); + SELF_CHECK (actual == expected); } /* Do the same as above, but with an unsigned type. */ @@ -212,10 +212,10 @@ gdb_mpz_read_all_from_small () gdb_mpz expected, actual; store_and_read_back (ul, buf_len, BFD_ENDIAN_BIG, expected, actual); - SELF_CHECK (mpz_cmp (actual.val, expected.val) == 0); + SELF_CHECK (actual == expected); store_and_read_back (ul, buf_len, BFD_ENDIAN_LITTLE, expected, actual); - SELF_CHECK (mpz_cmp (actual.val, expected.val) == 0); + SELF_CHECK (actual == expected); } } @@ -232,11 +232,11 @@ gdb_mpz_read_min_max () store_and_read_back (l_min, sizeof (LONGEST), BFD_ENDIAN_BIG, expected, actual); - SELF_CHECK (mpz_cmp (actual.val, expected.val) == 0); + SELF_CHECK (actual == expected); store_and_read_back (l_min, sizeof (LONGEST), BFD_ENDIAN_LITTLE, expected, actual); - SELF_CHECK (mpz_cmp (actual.val, expected.val) == 0); + SELF_CHECK (actual == expected); /* Same with LONGEST_MAX. */ @@ -244,11 +244,11 @@ gdb_mpz_read_min_max () store_and_read_back (l_max, sizeof (LONGEST), BFD_ENDIAN_BIG, expected, actual); - SELF_CHECK (mpz_cmp (actual.val, expected.val) == 0); + SELF_CHECK (actual == expected); store_and_read_back (l_max, sizeof (LONGEST), BFD_ENDIAN_LITTLE, expected, actual); - SELF_CHECK (mpz_cmp (actual.val, expected.val) == 0); + SELF_CHECK (actual == expected); /* Same with the smallest ULONGEST. */ @@ -256,11 +256,11 @@ gdb_mpz_read_min_max () store_and_read_back (ul_min, sizeof (ULONGEST), BFD_ENDIAN_BIG, expected, actual); - SELF_CHECK (mpz_cmp (actual.val, expected.val) == 0); + SELF_CHECK (actual == expected); store_and_read_back (ul_min, sizeof (ULONGEST), BFD_ENDIAN_LITTLE, expected, actual); - SELF_CHECK (mpz_cmp (actual.val, expected.val) == 0); + SELF_CHECK (actual == expected); /* Same with ULONGEST_MAX. */ @@ -268,11 +268,11 @@ gdb_mpz_read_min_max () store_and_read_back (ul_max, sizeof (ULONGEST), BFD_ENDIAN_BIG, expected, actual); - SELF_CHECK (mpz_cmp (actual.val, expected.val) == 0); + SELF_CHECK (actual == expected); store_and_read_back (ul_max, sizeof (ULONGEST), BFD_ENDIAN_LITTLE, expected, actual); - SELF_CHECK (mpz_cmp (actual.val, expected.val) == 0); + SELF_CHECK (actual == expected); } /* A helper function which creates a gdb_mpz object from the given diff --git a/gdb/valops.c b/gdb/valops.c index 3a1b14c3d44..e0936d45cb3 100644 --- a/gdb/valops.c +++ b/gdb/valops.c @@ -354,7 +354,7 @@ value_to_gdb_mpq (struct value *value) gdb_mpz vz; vz.read (value->contents (), type_byte_order (type), type->is_unsigned ()); - mpq_set_z (result.val, vz.val); + result = vz; if (is_fixed_point_type (type)) mpq_mul (result.val, result.val, diff --git a/gdb/value.c b/gdb/value.c index d2c2a2d7859..672e0c7023a 100644 --- a/gdb/value.c +++ b/gdb/value.c @@ -2721,8 +2721,7 @@ unpack_long (struct type *type, const gdb_byte *valaddr) byte_order, nosign, type->fixed_point_scaling_factor ()); - gdb_mpz vz; - mpz_tdiv_q (vz.val, mpq_numref (vq.val), mpq_denref (vq.val)); + gdb_mpz vz = vq.as_integer (); return vz.as_integer (); }