From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 123724 invoked by alias); 29 Oct 2016 01:07:48 -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 123712 invoked by uid 89); 29 Oct 2016 01:07:47 -0000 Authentication-Results: sourceware.org; auth=none X-Virus-Found: No X-Spam-SWARE-Status: No, score=-1.5 required=5.0 tests=AWL,BAYES_00,RCVD_IN_DNSWL_NONE,RCVD_IN_SORBS_SPAM,SPF_PASS autolearn=no version=3.3.2 spammy= X-HELO: mail-wm0-f51.google.com Received: from mail-wm0-f51.google.com (HELO mail-wm0-f51.google.com) (74.125.82.51) by sourceware.org (qpsmtpd/0.93/v0.84-503-g423c35a) with ESMTP; Sat, 29 Oct 2016 01:07:45 +0000 Received: by mail-wm0-f51.google.com with SMTP id e69so135059992wmg.0 for ; Fri, 28 Oct 2016 18:07:45 -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=VtZZNw8m5g5MTed13LEKFeWNF5+umzNJuR2q2q4DjBk=; b=VF2PmW3K0SrO916cX/LLJeB+fgloifxwgG3AKjBYD243CC8MYWDrRRnKxpjSBLrKJX q1yvOHq4PJwt00J/2/AuGcRaBrKSjAlq9ZAeGaPaer/qRsAQOSCzVhf6SptB2gyc3o0d nFcxw12ysw5UTdupfv81mAbZ8uZBXrbgfV4QYFz39Z7H4kDVDeUHtVJlPrp6lESXNejQ 5yykCk1RiiOKArblsP6PfURIQhsPlfPgAOa8V1PWscTII8omTCYhW5fOQmah7vaCPMSB x2nq2c9YMVIAUwlygY4Yp1YCtS2Z9y1LUVZRYJGk5QvPseSb1K6ci50nJ32vEtPKy8El gjJQ== X-Gm-Message-State: ABUngvf7sGRGtWqVp56ZCOevMt//SpQ8Rs234TiNwyLZAIZ1NiSu0iIdus7D/VkVsrmNTnkcjsKpKeN2P1uR8cZY X-Received: by 10.194.157.169 with SMTP id wn9mr13297481wjb.195.1477703263720; Fri, 28 Oct 2016 18:07:43 -0700 (PDT) MIME-Version: 1.0 Received: by 10.28.131.21 with HTTP; Fri, 28 Oct 2016 18:07:23 -0700 (PDT) In-Reply-To: References: From: Manish Goregaokar Date: Sat, 29 Oct 2016 01:07:00 -0000 Message-ID: Subject: Re: [PATCH] Add support for untagged unions To: gdb-patches@sourceware.org Cc: Tom Tromey Content-Type: text/plain; charset=UTF-8 X-IsSubscribed: yes X-SW-Source: 2016-10/txt/msg00828.txt.bz2 Commit message of this and the previous patch should probably say "in Rust" somewhere (will amend before pushing) -Manish On Fri, Oct 28, 2016 at 6:02 PM, Manish Goregaokar wrote: > Rust supports untagged unions (C unions) now (using the same syntax as > structs but with `union` instead of `struct` in the declaration). > These are mainly used for FFI. > > No tests because stable Rust doesn't have these yet. Let me know if I > should add them. > > From: Manish Goregaokar > Subject: [PATCH] Add support for untagged unions > > 2016-10-28 Manish Goregaokar > > gdb/ChangeLog: > * rust-lang.c (rust_union_is_untagged): Add function to > check if a union is an untagged unioni > * rust-lang.c (rust_val_print): Handle printing of untagged union values > * rust-lang.c (rust_print_type): Handle printing of untagged union types > * rust-lang.c (rust_evaluate_subexp): Handle evaluating field > access on untagged unions > --- > gdb/rust-lang.c | 56 ++++++++++++++++++++++++++++++++++++++++++++++++++++---- > 1 file changed, 52 insertions(+), 4 deletions(-) > > diff --git a/gdb/rust-lang.c b/gdb/rust-lang.c > index 9569584..5376efc 100644 > --- a/gdb/rust-lang.c > +++ b/gdb/rust-lang.c > @@ -93,6 +93,28 @@ struct disr_info > > #define RUST_ENCODED_ENUM_HIDDEN 1 > > +/* Whether or not a TYPE_CODE_UNION value is an untagged union > + as opposed to being a regular Rust enum. */ > +static bool > +rust_union_is_untagged(struct type *type) { > + /* Unions must have at least one field. */ > + if (TYPE_NFIELDS (type) == 0) > + return false; > + /* If the first field is named, but the name has the rust enum prefix, > + it is an enum. */ > + if (strncmp (TYPE_FIELD_NAME (type, 0), RUST_ENUM_PREFIX, > + strlen (RUST_ENUM_PREFIX)) == 0) > + return false; > + /* Unions only have named fields. */ > + for (int i = 0; i < TYPE_NFIELDS (type); ++i) > + { > + if (strlen (TYPE_FIELD_NAME (type, i)) == 0) > + return false; > + } > + return true; > + > +} > + > /* Utility function to get discriminant info for a given value. */ > > static struct disr_info > @@ -566,6 +588,14 @@ rust_val_print (struct type *type, const gdb_byte > *valaddr, int embedded_offset, > struct value_print_options opts; > struct cleanup *cleanup; > > + /* Untagged unions are printed as if they are structs. > + Since the field bit positions overlap in the debuginfo, > + the code for printing a union is same as that for a struct, > + the only difference is that the input type will have overlapping > + fields. */ > + if (rust_union_is_untagged (type)) > + goto struct_val; > + > opts = *options; > opts.deref_ref = 0; > > @@ -638,6 +668,7 @@ rust_val_print (struct type *type, const gdb_byte > *valaddr, int embedded_offset, > break; > > case TYPE_CODE_STRUCT: > + struct_val: > { > int i; > int first_field; > @@ -809,6 +840,7 @@ rust_print_type (struct type *type, const char *varstring, > break; > > case TYPE_CODE_STRUCT: > + struct_printer: > { > int is_tuple_struct; > > @@ -823,7 +855,12 @@ rust_print_type (struct type *type, const char *varstring, > if (TYPE_N_BASECLASSES (type) > 0) > goto c_printer; > > - fputs_filtered ("struct ", stream); > + /* This code path is also used by unions. */ > + if (TYPE_CODE (type) == TYPE_CODE_STRUCT) > + fputs_filtered ("struct ", stream); > + else > + fputs_filtered ("union ", stream); > + > if (TYPE_TAG_NAME (type) != NULL) > fputs_filtered (TYPE_TAG_NAME (type), stream); > > @@ -899,6 +936,13 @@ rust_print_type (struct type *type, const char *varstring, > /* Skip the discriminant field. */ > int skip_to = 1; > > + /* Unions and structs have the same syntax in Rust, > + the only difference is that structs are declared with `struct` > + and union with `union`. This difference is handled in the struct > + printer. */ > + if (rust_union_is_untagged (type)) > + goto struct_printer; > + > fputs_filtered ("enum ", stream); > if (TYPE_TAG_NAME (type) != NULL) > { > @@ -1637,7 +1681,10 @@ rust_evaluate_subexp (struct type *expect_type, > struct expression *exp, > lhs = evaluate_subexp (NULL_TYPE, exp, pos, noside); > > type = value_type (lhs); > - if (TYPE_CODE (type) == TYPE_CODE_UNION) > + /* Untagged unions can't have anonymous field access since > + they can only have named fields. */ > + if (TYPE_CODE (type) == TYPE_CODE_UNION > + && !rust_union_is_untagged (type)) > { > struct cleanup *cleanup; > > @@ -1712,8 +1759,8 @@ tuple structs, and tuple-like enum variants")); > lhs = evaluate_subexp (NULL_TYPE, exp, pos, noside); > > type = value_type (lhs); > - > - if (TYPE_CODE (type) == TYPE_CODE_UNION) > + if (TYPE_CODE (type) == TYPE_CODE_UNION > + && !rust_union_is_untagged (type)) > { > int i, start; > struct disr_info disr; > @@ -1762,6 +1809,7 @@ which has only anonymous fields"), > } > else > { > + /* Field access in structs and untagged unions works like C. */ > *pos = pc; > result = evaluate_subexp_standard (expect_type, exp, pos, noside); > } > -- > 2.10.1