From patchwork Sun Dec 8 18:29:17 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Tom Tromey X-Patchwork-Id: 36606 Received: (qmail 101853 invoked by alias); 8 Dec 2019 18:30:32 -0000 Mailing-List: contact gdb-patches-help@sourceware.org; run by ezmlm Precedence: bulk List-Id: List-Unsubscribe: List-Subscribe: List-Archive: List-Post: List-Help: , Sender: gdb-patches-owner@sourceware.org Delivered-To: mailing list gdb-patches@sourceware.org Received: (qmail 101215 invoked by uid 89); 8 Dec 2019 18:30:18 -0000 Authentication-Results: sourceware.org; auth=none X-Spam-SWARE-Status: No, score=-20.4 required=5.0 tests=AWL, BAYES_00, FORGED_SPF_HELO, GIT_PATCH_0, GIT_PATCH_1, GIT_PATCH_2, GIT_PATCH_3, SPF_HELO_PASS autolearn=ham version=3.3.1 spammy= X-HELO: gateway22.websitewelcome.com Received: from gateway34.websitewelcome.com (HELO gateway22.websitewelcome.com) (192.185.46.126) by sourceware.org (qpsmtpd/0.93/v0.84-503-g423c35a) with ESMTP; Sun, 08 Dec 2019 18:30:13 +0000 Received: from cm17.websitewelcome.com (cm17.websitewelcome.com [100.42.49.20]) by gateway22.websitewelcome.com (Postfix) with ESMTP id BA1B15D41 for ; Sun, 8 Dec 2019 12:30:03 -0600 (CST) Received: from box5379.bluehost.com ([162.241.216.53]) by cmsmtp with SMTP id e1JjipQlmqNtve1JjiYrOh; Sun, 08 Dec 2019 12:30:03 -0600 DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=tromey.com; s=default; h=References:In-Reply-To:Message-Id:Date:Subject:Cc:To:From: Sender:Reply-To:MIME-Version:Content-Type:Content-Transfer-Encoding: Content-ID:Content-Description:Resent-Date:Resent-From:Resent-Sender: Resent-To:Resent-Cc:Resent-Message-ID:List-Id:List-Help:List-Unsubscribe: List-Subscribe:List-Post:List-Owner:List-Archive; bh=dXgpulCTwlyuTlweZ1B+RPMoJcUZgkQxtHOICT2LQQ8=; b=ycK132+HtaL69yqytziipbWpox E4MlQ6VZpu0cU3qfRvcoJ5JsYbawPBbUzJ23exSn6Oa/rHWsmRlFRVsN7Gr30nX/GEUk149kOyRGu pw6iLlAgvUGMAWvAa3WLINNnh; Received: from 75-166-123-50.hlrn.qwest.net ([75.166.123.50]:53620 helo=bapiya.Home) by box5379.bluehost.com with esmtpa (Exim 4.92) (envelope-from ) id 1ie1Jj-0045Dk-Hk; Sun, 08 Dec 2019 11:30:03 -0700 From: Tom Tromey To: gdb-patches@sourceware.org Cc: Tom Tromey Subject: [PATCH 14/55] Introduce value_print_array_elements Date: Sun, 8 Dec 2019 11:29:17 -0700 Message-Id: <20191208182958.10181-15-tom@tromey.com> In-Reply-To: <20191208182958.10181-1-tom@tromey.com> References: <20191208182958.10181-1-tom@tromey.com> This introduces value_print_array_elements, which is an analogue of val_print_array_elements that uses the value API. gdb/ChangeLog 2019-12-08 Tom Tromey * valprint.c (value_print_array_elements): New function. * valprint.h (value_print_array_elements): Declare. Change-Id: I82d7666ce30b8cae3689fbf392177b08ef861a3b --- gdb/ChangeLog | 5 ++ gdb/valprint.c | 126 +++++++++++++++++++++++++++++++++++++++++++++++++ gdb/valprint.h | 6 +++ 3 files changed, 137 insertions(+) diff --git a/gdb/valprint.c b/gdb/valprint.c index d09a42926e2..b2506dc6fc4 100644 --- a/gdb/valprint.c +++ b/gdb/valprint.c @@ -2184,6 +2184,132 @@ val_print_array_elements (struct type *type, } } +/* See valprint.h. */ + +void +value_print_array_elements (struct value *val, struct ui_file *stream, + int recurse, + const struct value_print_options *options, + unsigned int i) +{ + unsigned int things_printed = 0; + unsigned len; + struct type *elttype, *index_type, *base_index_type; + unsigned eltlen; + /* Position of the array element we are examining to see + whether it is repeated. */ + unsigned int rep1; + /* Number of repetitions we have detected so far. */ + unsigned int reps; + LONGEST low_bound, high_bound; + LONGEST low_pos, high_pos; + + struct type *type = check_typedef (value_type (val)); + + elttype = TYPE_TARGET_TYPE (type); + eltlen = type_length_units (check_typedef (elttype)); + index_type = TYPE_INDEX_TYPE (type); + + if (get_array_bounds (type, &low_bound, &high_bound)) + { + if (TYPE_CODE (index_type) == TYPE_CODE_RANGE) + base_index_type = TYPE_TARGET_TYPE (index_type); + else + base_index_type = index_type; + + /* Non-contiguous enumerations types can by used as index types + in some languages (e.g. Ada). In this case, the array length + shall be computed from the positions of the first and last + literal in the enumeration type, and not from the values + of these literals. */ + if (!discrete_position (base_index_type, low_bound, &low_pos) + || !discrete_position (base_index_type, high_bound, &high_pos)) + { + warning (_("unable to get positions in array, use bounds instead")); + low_pos = low_bound; + high_pos = high_bound; + } + + /* The array length should normally be HIGH_POS - LOW_POS + 1. + But we have to be a little extra careful, because some languages + such as Ada allow LOW_POS to be greater than HIGH_POS for + empty arrays. In that situation, the array length is just zero, + not negative! */ + if (low_pos > high_pos) + len = 0; + else + len = high_pos - low_pos + 1; + } + else + { + warning (_("unable to get bounds of array, assuming null array")); + low_bound = 0; + len = 0; + } + + annotate_array_section_begin (i, elttype); + + for (; i < len && things_printed < options->print_max; i++) + { + scoped_value_mark free_values; + + if (i != 0) + { + if (options->prettyformat_arrays) + { + fprintf_filtered (stream, ",\n"); + print_spaces_filtered (2 + 2 * recurse, stream); + } + else + { + fprintf_filtered (stream, ", "); + } + } + wrap_here (n_spaces (2 + 2 * recurse)); + maybe_print_array_index (index_type, i + low_bound, + stream, options); + + rep1 = i + 1; + reps = 1; + /* Only check for reps if repeat_count_threshold is not set to + UINT_MAX (unlimited). */ + if (options->repeat_count_threshold < UINT_MAX) + { + while (rep1 < len + && value_contents_eq (val, i * eltlen, + val, rep1 * eltlen, + eltlen)) + { + ++reps; + ++rep1; + } + } + + struct value *element = value_from_component (val, elttype, eltlen * i); + common_val_print (element, stream, recurse + 1, options, + current_language); + + if (reps > options->repeat_count_threshold) + { + annotate_elt_rep (reps); + fprintf_filtered (stream, " %p[%p]", + metadata_style.style ().ptr (), reps, nullptr); + annotate_elt_rep_end (); + + i = rep1 - 1; + things_printed += options->repeat_count_threshold; + } + else + { + annotate_elt (); + things_printed++; + } + } + annotate_array_section_end (); + if (i < len) + fprintf_filtered (stream, "..."); +} + /* Read LEN bytes of target memory at address MEMADDR, placing the results in GDB's memory at MYADDR. Returns a count of the bytes actually read, and optionally a target_xfer_status value in the diff --git a/gdb/valprint.h b/gdb/valprint.h index f1c93aa26b6..68b1083c742 100644 --- a/gdb/valprint.h +++ b/gdb/valprint.h @@ -134,6 +134,12 @@ extern void val_print_array_elements (struct type *, LONGEST, const struct value_print_options *, unsigned int); +/* Print elements of an array. */ + +extern void value_print_array_elements (struct value *, struct ui_file *, int, + const struct value_print_options *, + unsigned int); + extern void val_print_scalar_formatted (struct type *, LONGEST, struct value *,