From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 38795 invoked by alias); 25 Jun 2016 06:00:55 -0000 Mailing-List: contact gdb-patches-help@sourceware.org; run by ezmlm Precedence: bulk List-Id: List-Subscribe: List-Archive: List-Post: List-Help: , Sender: gdb-patches-owner@sourceware.org Received: (qmail 38776 invoked by uid 89); 25 Jun 2016 06:00:53 -0000 Authentication-Results: sourceware.org; auth=none X-Virus-Found: No X-Spam-SWARE-Status: No, score=-1.6 required=5.0 tests=AWL,BAYES_00,RCVD_IN_DNSWL_LOW,SPF_PASS autolearn=ham version=3.3.2 spammy=strtoul, preexisting X-HELO: mail-wm0-f42.google.com Received: from mail-wm0-f42.google.com (HELO mail-wm0-f42.google.com) (74.125.82.42) by sourceware.org (qpsmtpd/0.93/v0.84-503-g423c35a) with (AES128-GCM-SHA256 encrypted) ESMTPS; Sat, 25 Jun 2016 06:00:43 +0000 Received: by mail-wm0-f42.google.com with SMTP id r201so49004267wme.1 for ; Fri, 24 Jun 2016 23:00:43 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20130820; h=x-gm-message-state:mime-version:in-reply-to:references:from:date :message-id:subject:to:cc; bh=oi4c8Na/66ZvCZNyG73OG9xnkzdr+NzAT+oKPtZLoYY=; b=eE96VUz2l3RqpenuHSQ9RxeSZ8pKOLtuDO4/9qXm1fWqc2yelCsr5EHJI7yCZlG60/ VCVi9iWNXnLNReAtemsfse4sxn5edmkH9k9EuZqs5A46yjnrOxXwQO6K8YhW9PxvxXM0 wKSaYlROkDLIPj7ZriVy0JPEjtCMaVco3nma3jHw29sJvHAd0QOL+b/xdoHvYt5a75gF RwptWo50N/e0LP0sjShUrC2srOL1GpH6WhJQvSdjCCPkdZ2w8CcmZsZSt3I0fk6GNpxA BfdMM3TfoY6snpTDuizgF8L8LxfrYGf57pS8srS9tkIsMItNTujSk+PmFVHABPgNlvBq s/aQ== X-Gm-Message-State: ALyK8tKSUl2wOKYWfC9SxntwYox4J2N8CklYllxVk8SPs6i/d2yhQHtTrLVknjPchV5/w7bnzWaqx/lkfWidBiG2 X-Received: by 10.194.82.161 with SMTP id j1mr7470147wjy.65.1466834440270; Fri, 24 Jun 2016 23:00:40 -0700 (PDT) MIME-Version: 1.0 Received: by 10.28.36.215 with HTTP; Fri, 24 Jun 2016 23:00:39 -0700 (PDT) In-Reply-To: References: From: Manish Goregaokar Date: Sat, 25 Jun 2016 06:00:00 -0000 Message-ID: Subject: Re: [PATCH 1/2][PR gdb/20239] Make evaluation and type-printing of all NonZero-optimized enums work To: gdb-patches@sourceware.org Cc: Tom Tromey Content-Type: text/plain; charset=UTF-8 X-SW-Source: 2016-06/txt/msg00416.txt.bz2 After further fixups, these patches have been pushed as https://sourceware.org/git/gitweb.cgi?p=binutils-gdb.git;a=commit;h=b5a4b3c5e711be9096423f9765623eda449d8f4d and https://sourceware.org/git/gitweb.cgi?p=binutils-gdb.git;a=commit;h=fccb08f8cd2035b50a2b0a5e09983180b7411685 Thanks! -Manish On Tue, Jun 21, 2016 at 3:10 PM, Manish Goregaokar wrote: > Moved over from https://sourceware.org/bugzilla/show_bug.cgi?id=20239. > Regarding the xstrdup, this is done because strsep edits the string > itself. > > Built and tested on OS X El Capitan. Methods tests fail, but they are > a preexisting failure due to Rust's debuginfo changing. > > > > gdb/ChangeLog: > 2016-06-21 Manish Goregaokar > > PR gdb/20239 > * rust-lang.c (rust_get_disr_info): Correctly interpret > NonZero-optimized enums of arbitrary depth. > (rust_print_type): Correctly print NonZero-optimized > enums. > --- > gdb/rust-lang.c | 72 +++++++++++++++++++++++++++++++++++++++++++-------------- > 1 file changed, 55 insertions(+), 17 deletions(-) > > diff --git a/gdb/rust-lang.c b/gdb/rust-lang.c > index 5df99ce..baabf76 100644 > --- a/gdb/rust-lang.c > +++ b/gdb/rust-lang.c > @@ -120,42 +120,69 @@ rust_get_disr_info (struct type *type, const > gdb_byte *valaddr, > if (strncmp (TYPE_FIELD_NAME (type, 0), RUST_ENUM_PREFIX, > strlen (RUST_ENUM_PREFIX)) == 0) > { > - char *tail; > + char *name, *tail, *token; > unsigned long fieldno; > struct type *member_type; > LONGEST value; > > + char *type_name; > + > ret.is_encoded = 1; > > if (TYPE_NFIELDS (type) != 1) > error (_("Only expected one field in %s type"), RUST_ENUM_PREFIX); > > - fieldno = strtoul (TYPE_FIELD_NAME (type, 0) + strlen (RUST_ENUM_PREFIX), > - &tail, 10); > - if (*tail != '$') > + /* Optimized enums have only one field */ > + member_type = TYPE_FIELD_TYPE (type, 0); > + > + name = xstrdup (TYPE_FIELD_NAME (type, 0)); > + cleanup = make_cleanup (xfree, name); > + tail = name + strlen (RUST_ENUM_PREFIX); > + > + /* The location of the value that doubles as a discriminant is > + stored in the name of the field, as > + RUST$ENCODED$ENUM$$$...$ > + where the fieldnos are the indices of the fields that should be > + traversed in order to find the field (which may be several > fields deep) > + and the variantname is the name of the variant of the case when the > + field is zero */ > + while ((token = strsep (&tail, "$")) != NULL) > + { > + if (sscanf (token, "%lu", &fieldno) != 1) > + { > + /* We have reached the enum name, which cannot start with > a digit */ > + break; > + } > + if (fieldno >= TYPE_NFIELDS (member_type)) > + error (_("%s refers to field after end of member type"), > + RUST_ENUM_PREFIX); > + > + embedded_offset += TYPE_FIELD_BITPOS (member_type, fieldno) / 8; > + member_type = TYPE_FIELD_TYPE (member_type, fieldno); > + type_name = TYPE_NAME (member_type); > + }; > + > + if (token >= name + strlen (TYPE_FIELD_NAME (type, 0))) > error (_("Invalid form for %s"), RUST_ENUM_PREFIX); > + value = unpack_long (member_type, > + valaddr + embedded_offset); > + > > - member_type = TYPE_FIELD_TYPE (type, 0); > - if (fieldno >= TYPE_NFIELDS (member_type)) > - error (_("%s refers to field after end of member type"), > - RUST_ENUM_PREFIX); > > - embedded_offset += TYPE_FIELD_BITPOS (member_type, fieldno) / 8; > - value = unpack_long (TYPE_FIELD_TYPE (member_type, fieldno), > - valaddr + embedded_offset); > if (value == 0) > { > ret.field_no = RUST_ENCODED_ENUM_HIDDEN; > - ret.name = concat (TYPE_NAME (type), "::", tail + 1, (char *) NULL); > + ret.name = concat (TYPE_NAME (type), "::", token, (char *) NULL); > } > else > { > ret.field_no = RUST_ENCODED_ENUM_REAL; > ret.name = concat (TYPE_NAME (type), "::", > - rust_last_path_segment (TYPE_NAME (member_type)), > + rust_last_path_segment (TYPE_NAME (TYPE_FIELD_TYPE > (type, 0))), > (char *) NULL); > } > > + do_cleanups (cleanup); > return ret; > } > > @@ -841,6 +868,7 @@ rust_print_type (struct type *type, const char *varstring, > { > /* ADT enums */ > int i, len = 0; > + int skip_to = 1; /* Skip the discriminant field */ > > fputs_filtered ("enum ", stream); > if (TYPE_TAG_NAME (type) != NULL) > @@ -849,7 +877,17 @@ rust_print_type (struct type *type, const char *varstring, > fputs_filtered (" ", stream); > len = strlen (TYPE_TAG_NAME (type)); > } > - fputs_filtered ("{\n", stream); > + fputs_filtered ("{\n", stream); > + > + if (strncmp (TYPE_FIELD_NAME (type, 0), RUST_ENUM_PREFIX, > + strlen (RUST_ENUM_PREFIX)) == 0) { > + char *zero_field = strrchr (TYPE_FIELD_NAME (type, 0), '$'); > + if (zero_field != NULL && strlen (zero_field) > 1) { > + fprintfi_filtered (level+2, stream, "%s,\n", zero_field+1); > + /* there is no explicit discriminant field, skip nothing */ > + skip_to = 0; > + } > + } > > for (i = 0; i < TYPE_NFIELDS (type); ++i) > { > @@ -859,14 +897,14 @@ rust_print_type (struct type *type, const char *varstring, > > fprintfi_filtered (level + 2, stream, "%s", name); > > - if (TYPE_NFIELDS (variant_type) > 1) > + if (TYPE_NFIELDS (variant_type) > skip_to) > { > - int first = 1; > + int first = 1; > int is_tuple = rust_tuple_variant_type_p (variant_type); > int j; > > fputs_filtered (is_tuple ? "(" : "{", stream); > - for (j = 1; j < TYPE_NFIELDS (variant_type); j++) > + for (j = skip_to; j < TYPE_NFIELDS (variant_type); j++) > { > if (first) > first = 0; > -- > 2.8.3