From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from simark.ca by simark.ca with LMTP id THzXHIfhu19ETgAAWB0awg (envelope-from ) for ; Mon, 23 Nov 2020 11:21:27 -0500 Received: by simark.ca (Postfix, from userid 112) id 622531F0AB; Mon, 23 Nov 2020 11:21:27 -0500 (EST) X-Spam-Checker-Version: SpamAssassin 3.4.2 (2018-09-13) on simark.ca X-Spam-Level: X-Spam-Status: No, score=0.2 required=5.0 tests=DKIM_SIGNED,DKIM_VALID, DKIM_VALID_AU,MAILING_LIST_MULTI,RDNS_NONE,URIBL_BLOCKED autolearn=no autolearn_force=no version=3.4.2 Received: from sourceware.org (unknown [8.43.85.97]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits) server-digest SHA256) (No client certificate requested) by simark.ca (Postfix) with ESMTPS id C613E1F0A9 for ; Mon, 23 Nov 2020 11:21:26 -0500 (EST) Received: from server2.sourceware.org (localhost [IPv6:::1]) by sourceware.org (Postfix) with ESMTP id 686F638708CC; Mon, 23 Nov 2020 16:21:26 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org 686F638708CC DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=sourceware.org; s=default; t=1606148486; bh=wK/iAdYa1E1QAIIE8lp4rTSNX2FI4uTTI/6qZmQdMik=; h=To:Subject:Date:In-Reply-To:References:List-Id:List-Unsubscribe: List-Archive:List-Post:List-Help:List-Subscribe:From:Reply-To:Cc: From; b=KXSA6m81OP1RY+TqOlpxfOcEqnT+RyivylHchoK/kZuRs8RPqcz0ooBfNRw4vp+ZB u9lFe7+V8XlU3jVaQGf5WEjCG2oav4vWfp5mznVBr9feQsN9gbIuk8/PtPKxFkyQn/ DxhWITcV/uw6TL4j4j7DUGO7SHDJ81YBF1lHcu00= Received: from barracuda.ebox.ca (barracuda.ebox.ca [96.127.255.19]) by sourceware.org (Postfix) with ESMTPS id 05F1D38708BC for ; Mon, 23 Nov 2020 16:21:23 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.3.2 sourceware.org 05F1D38708BC X-ASG-Debug-ID: 1606148481-0c856e6cd51cb400001-fS2M51 Received: from smtp.ebox.ca (smtp.ebox.ca [96.127.255.82]) by barracuda.ebox.ca with ESMTP id 6g0TCFSyXIMNXOTX (version=TLSv1 cipher=DHE-RSA-AES256-SHA bits=256 verify=NO); Mon, 23 Nov 2020 11:21:22 -0500 (EST) X-Barracuda-Envelope-From: simon.marchi@efficios.com X-Barracuda-RBL-Trusted-Forwarder: 96.127.255.82 Received: from epycamd.internal.efficios.com (192-222-181-218.qc.cable.ebox.net [192.222.181.218]) by smtp.ebox.ca (Postfix) with ESMTP id C4CBB441D67; Mon, 23 Nov 2020 11:21:21 -0500 (EST) X-Barracuda-RBL-IP: 192.222.181.218 X-Barracuda-Effective-Source-IP: 192-222-181-218.qc.cable.ebox.net[192.222.181.218] X-Barracuda-Apparent-Source-IP: 192.222.181.218 To: gdb-patches@sourceware.org Subject: [PATCH 3/4] gdb: split get_discrete_bounds in two Date: Mon, 23 Nov 2020 11:21:19 -0500 X-ASG-Orig-Subj: [PATCH 3/4] gdb: split get_discrete_bounds in two Message-Id: <20201123162120.3778679-4-simon.marchi@efficios.com> X-Mailer: git-send-email 2.29.2 In-Reply-To: <20201123162120.3778679-1-simon.marchi@efficios.com> References: <20201123162120.3778679-1-simon.marchi@efficios.com> MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Barracuda-Connect: smtp.ebox.ca[96.127.255.82] X-Barracuda-Start-Time: 1606148482 X-Barracuda-Encrypted: DHE-RSA-AES256-SHA X-Barracuda-URL: https://96.127.255.19:443/cgi-mod/mark.cgi X-Barracuda-BRTS-Status: 1 X-Virus-Scanned: by bsmtpd at ebox.ca X-Barracuda-Scan-Msg-Size: 7191 X-Barracuda-Spam-Score: 0.50 X-Barracuda-Spam-Status: No, SCORE=0.50 using global scores of TAG_LEVEL=1000.0 QUARANTINE_LEVEL=1000.0 KILL_LEVEL=8.0 tests=BSF_RULE7568M X-Barracuda-Spam-Report: Code version 3.2, rules version 3.2.3.86072 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- 0.50 BSF_RULE7568M Custom Rule 7568M 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: , From: Simon Marchi via Gdb-patches Reply-To: Simon Marchi Cc: Simon Marchi Errors-To: gdb-patches-bounces@sourceware.org Sender: "Gdb-patches" get_discrete_bounds is not flexible for ranges (TYPE_CODE_RANGE), in the sense that it returns true (success) only if both bounds are present and constant values. This is a problem for code that only needs to know the low bound and fails unnecessarily if the high bound is unknown. Split the function in two, get_discrete_low_bound and get_discrete_high_bound, that both return an optional. Provide a new implementation of get_discrete_bounds based on the two others, so the callers don't have to be changed. gdb/ChangeLog: * gdbtypes.c (get_discrete_bounds): Implement with get_discrete_low_bound and get_discrete_high_bound. (get_discrete_low_bound): New. (get_discrete_high_bound): New. Change-Id: I986b5e9c0dd969800e3fb9546af9c827d52e80d0 --- gdb/gdbtypes.c | 187 ++++++++++++++++++++++++++++++++++--------------- 1 file changed, 130 insertions(+), 57 deletions(-) diff --git a/gdb/gdbtypes.c b/gdb/gdbtypes.c index b47bd28945d..4df23cfe0fe 100644 --- a/gdb/gdbtypes.c +++ b/gdb/gdbtypes.c @@ -1036,71 +1036,127 @@ has_static_range (const struct range_bounds *bounds) && bounds->stride.kind () == PROP_CONST); } -/* See gdbtypes.h. */ +/* If TYPE's low bound is a known constant, return it, else return nullopt. */ -bool -get_discrete_bounds (struct type *type, LONGEST *lowp, LONGEST *highp) +static gdb::optional +get_discrete_low_bound (struct type *type) { type = check_typedef (type); switch (type->code ()) { case TYPE_CODE_RANGE: - /* This function currently only works for ranges with two defined, - constant bounds. */ - if (type->bounds ()->low.kind () != PROP_CONST - || type->bounds ()->high.kind () != PROP_CONST) + { + /* This function only works for ranges with a constant low bound. */ + if (type->bounds ()->low.kind () != PROP_CONST) + return {}; + + LONGEST low = type->bounds ()->low.const_val (); + + if (TYPE_TARGET_TYPE (type)->code () == TYPE_CODE_ENUM) + { + gdb::optional low_pos + = discrete_position (TYPE_TARGET_TYPE (type), low); + + if (low_pos.has_value ()) + low = *low_pos; + } + + return low; + } + + case TYPE_CODE_ENUM: + { + if (type->num_fields () > 0) + { + /* The enums may not be sorted by value, so search all + entries. */ + LONGEST low = TYPE_FIELD_ENUMVAL (type, 0); + + for (int i = 0; i < type->num_fields (); i++) + { + if (TYPE_FIELD_ENUMVAL (type, i) < low) + low = TYPE_FIELD_ENUMVAL (type, i); + } + + /* Set unsigned indicator if warranted. */ + if (low >= 0) + type->set_is_unsigned (true); + + return low; + } + else + return 0; + } + + case TYPE_CODE_BOOL: + return 0; + + case TYPE_CODE_INT: + if (TYPE_LENGTH (type) > sizeof (LONGEST)) /* Too big */ return false; - *lowp = type->bounds ()->low.const_val (); - *highp = type->bounds ()->high.const_val (); + if (!type->is_unsigned ()) + return -(1 << (TYPE_LENGTH (type) * TARGET_CHAR_BIT - 1)); - if (TYPE_TARGET_TYPE (type)->code () == TYPE_CODE_ENUM) - { - gdb::optional low_pos - = discrete_position (TYPE_TARGET_TYPE (type), *lowp); + /* fall through */ + case TYPE_CODE_CHAR: + return 0; - if (low_pos.has_value ()) - *lowp = *low_pos; + default: + return false; + } +} - gdb::optional high_pos - = discrete_position (TYPE_TARGET_TYPE (type), *highp); +/* If TYPE's high bound is a known constant, return it, else return nullopt. */ - if (high_pos.has_value ()) - *highp = *high_pos; - } - return true; +static gdb::optional +get_discrete_high_bound (struct type *type) +{ + type = check_typedef (type); + switch (type->code ()) + { + case TYPE_CODE_RANGE: + { + /* This function only works for ranges with a constant high bound. */ + if (type->bounds ()->high.kind () != PROP_CONST) + return {}; + + LONGEST high = type->bounds ()->high.const_val (); + + if (TYPE_TARGET_TYPE (type)->code () == TYPE_CODE_ENUM) + { + gdb::optional high_pos + = discrete_position (TYPE_TARGET_TYPE (type), high); + + if (high_pos.has_value ()) + high = *high_pos; + } + + return high; + } case TYPE_CODE_ENUM: - if (type->num_fields () > 0) - { - /* The enums may not be sorted by value, so search all - entries. */ - int i; + { + if (type->num_fields () > 0) + { + /* The enums may not be sorted by value, so search all + entries. */ + LONGEST high = TYPE_FIELD_ENUMVAL (type, 0); - *lowp = *highp = TYPE_FIELD_ENUMVAL (type, 0); - for (i = 0; i < type->num_fields (); i++) - { - if (TYPE_FIELD_ENUMVAL (type, i) < *lowp) - *lowp = TYPE_FIELD_ENUMVAL (type, i); - if (TYPE_FIELD_ENUMVAL (type, i) > *highp) - *highp = TYPE_FIELD_ENUMVAL (type, i); - } + for (int i = 0; i < type->num_fields (); i++) + { + if (TYPE_FIELD_ENUMVAL (type, i) > high) + high = TYPE_FIELD_ENUMVAL (type, i); + } - /* Set unsigned indicator if warranted. */ - if (*lowp >= 0) - type->set_is_unsigned (true); - } - else - { - *lowp = 0; - *highp = -1; - } - return true; + return high; + } + else + return -1; + } case TYPE_CODE_BOOL: - *lowp = 0; - *highp = 1; - return true; + return 1; case TYPE_CODE_INT: if (TYPE_LENGTH (type) > sizeof (LONGEST)) /* Too big */ @@ -1108,25 +1164,42 @@ get_discrete_bounds (struct type *type, LONGEST *lowp, LONGEST *highp) if (!type->is_unsigned ()) { - *lowp = -(1 << (TYPE_LENGTH (type) * TARGET_CHAR_BIT - 1)); - *highp = -*lowp - 1; - return true; + LONGEST low = -(1 << (TYPE_LENGTH (type) * TARGET_CHAR_BIT - 1)); + return -low - 1; } + /* fall through */ case TYPE_CODE_CHAR: - *lowp = 0; - /* This round-about calculation is to avoid shifting by - TYPE_LENGTH (type) * TARGET_CHAR_BIT, which will not work - if TYPE_LENGTH (type) == sizeof (LONGEST). */ - *highp = 1 << (TYPE_LENGTH (type) * TARGET_CHAR_BIT - 1); - *highp = (*highp - 1) | *highp; - return true; + { + /* This round-about calculation is to avoid shifting by + TYPE_LENGTH (type) * TARGET_CHAR_BIT, which will not work + if TYPE_LENGTH (type) == sizeof (LONGEST). */ + LONGEST high = 1 << (TYPE_LENGTH (type) * TARGET_CHAR_BIT - 1); + return (high - 1) | high; + } default: return false; } } +/* See gdbtypes.h. */ + +bool +get_discrete_bounds (struct type *type, LONGEST *lowp, LONGEST *highp) +{ + gdb::optional low = get_discrete_low_bound (type); + gdb::optional high = get_discrete_high_bound (type); + + if (!low.has_value () || !high.has_value ()) + return false; + + *lowp = *low; + *highp = *high; + + return true; +} + /* See gdbtypes.h */ bool -- 2.29.2