From: Manish Goregaokar <manish@mozilla.com>
To: gdb-patches@sourceware.org
Cc: Tom Tromey <tom@tromey.com>
Subject: [PATCH] Add support for untagged unions
Date: Sat, 29 Oct 2016 01:02:00 -0000 [thread overview]
Message-ID: <CAFOnWk=gVjBMMNrR1m16Wri62ZgUNAS_7q+MJDk_QYxPjECezQ@mail.gmail.com> (raw)
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 <manish@mozilla.com>
Subject: [PATCH] Add support for untagged unions
2016-10-28 Manish Goregaokar <manish@mozilla.com>
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
next reply other threads:[~2016-10-29 1:02 UTC|newest]
Thread overview: 6+ messages / expand[flat|nested] mbox.gz Atom feed top
2016-10-29 1:02 Manish Goregaokar [this message]
2016-10-29 1:07 ` Manish Goregaokar
2016-10-31 3:13 ` Tom Tromey
2016-10-31 3:42 ` Manish Goregaokar
[not found] ` <CAFOnWk=Fe7UrrN1dLgWhzmnmhUzPbAQPfyXGLNqHnnej_gdciw@mail.gmail.com>
[not found] ` <87bmxy7r8y.fsf@tromey.com>
[not found] ` <CAFOnWkkUibsZKsqFrwGv1kpJ52mNiDYCEEpc5utO1=LLh6W+XQ@mail.gmail.com>
2016-11-03 21:33 ` Tom Tromey
2016-11-03 22:47 ` Manish Goregaokar
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to='CAFOnWk=gVjBMMNrR1m16Wri62ZgUNAS_7q+MJDk_QYxPjECezQ@mail.gmail.com' \
--to=manish@mozilla.com \
--cc=gdb-patches@sourceware.org \
--cc=tom@tromey.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox