From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 115795 invoked by alias); 29 Oct 2016 01:02:37 -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 115785 invoked by uid 89); 29 Oct 2016 01:02:36 -0000 Authentication-Results: sourceware.org; auth=none X-Virus-Found: No X-Spam-SWARE-Status: No, score=-1.9 required=5.0 tests=AWL,BAYES_00,RCVD_IN_DNSWL_NONE,SPF_PASS autolearn=ham version=3.3.2 spammy=overlapping, unions X-HELO: mail-wm0-f47.google.com Received: from mail-wm0-f47.google.com (HELO mail-wm0-f47.google.com) (74.125.82.47) by sourceware.org (qpsmtpd/0.93/v0.84-503-g423c35a) with ESMTP; Sat, 29 Oct 2016 01:02:34 +0000 Received: by mail-wm0-f47.google.com with SMTP id n67so141799276wme.1 for ; Fri, 28 Oct 2016 18:02:34 -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:from:date:message-id:subject:to:cc; bh=GVuVde/COOgvgcY6GkCJTH4xxyYvFpIYRHAwsPXyVI0=; b=RRHJRbN3kvV7mmRnz9No46Eq0AoSXA/JTx6tb54hSsfH0li5oOz52Wauq5zMNDafBC O7fmHhXjsYyj/fLC75TMw7JUY63oDqQbqAP1NsNQkpIAtxyYFb2GFTO44UzYFZ4A/I/r T+h0B+S6Nrmp6VXDLcwuSa4Y97ZfznBOUYasQzw6AkygGqvu3AZxWbB0XZCRyaCxJBFW T3xhrkb0uKq88QGRQIDoK67SmNXP5YCTS5unka4uQWn17aRM5LBl+QDmbic/geIcnN0i 2SII2urlkY66oi/M5tU2WGbs3YSI4aOrdu0NNT0e7FNtV4a0ic7jQfth02jBA7R4pNaf Tkgg== X-Gm-Message-State: ABUngvfp2G27ZXjz1IvHeOGpP+DTLMQ6sieAe+4VAlLqBsUz4cq1ubvKtw3joS66A+XWA4Y/jgvtyGo5hSVqmDKi X-Received: by 10.28.2.68 with SMTP id 65mr973988wmc.5.1477702952457; Fri, 28 Oct 2016 18:02:32 -0700 (PDT) MIME-Version: 1.0 Received: by 10.28.131.21 with HTTP; Fri, 28 Oct 2016 18:02:12 -0700 (PDT) From: Manish Goregaokar Date: Sat, 29 Oct 2016 01:02:00 -0000 Message-ID: Subject: [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/msg00827.txt.bz2 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