X-Git-Url: http://drtracing.org/?a=blobdiff_plain;f=gdb%2Frust-lang.c;h=1cd92ff47a865159338bc9d3a77758cfe913ddac;hb=be6d4f74c77c6f521afc873d226480e001cb99c2;hp=5f4aceb86ba91949ff2f8ce2293698e2b068956a;hpb=a33ccfc7afd9e32dd310f54d04719efeec8df342;p=deliverable%2Fbinutils-gdb.git diff --git a/gdb/rust-lang.c b/gdb/rust-lang.c index 5f4aceb86b..1cd92ff47a 100644 --- a/gdb/rust-lang.c +++ b/gdb/rust-lang.c @@ -1,6 +1,6 @@ /* Rust language support routines for GDB, the GNU debugger. - Copyright (C) 2016-2018 Free Software Foundation, Inc. + Copyright (C) 2016-2019 Free Software Foundation, Inc. This file is part of GDB. @@ -74,9 +74,22 @@ rust_enum_p (const struct type *type) && TYPE_FLAG_DISCRIMINATED_UNION (TYPE_FIELD_TYPE (type, 0))); } +/* Return true if TYPE, which must be an enum type, has no + variants. */ + +static bool +rust_empty_enum_p (const struct type *type) +{ + gdb_assert (rust_enum_p (type)); + /* In Rust the enum always fills the containing structure. */ + gdb_assert (TYPE_FIELD_BITPOS (type, 0) == 0); + + return TYPE_NFIELDS (TYPE_FIELD_TYPE (type, 0)) == 0; +} + /* Given an enum type and contents, find which variant is active. */ -struct field * +static struct field * rust_enum_variant (struct type *type, const gdb_byte *contents) { /* In Rust the enum always fills the containing structure. */ @@ -429,6 +442,13 @@ rust_print_enum (struct type *type, int embedded_offset, opts.deref_ref = 0; + if (rust_empty_enum_p (type)) + { + /* Print the enum type name here to be more clear. */ + fprintf_filtered (stream, _("%s {}"), TYPE_NAME (type)); + return; + } + const gdb_byte *valaddr = value_contents_for_printing (val); struct field *variant_field = rust_enum_variant (type, valaddr); embedded_offset += FIELD_BITPOS (*variant_field) / 8; @@ -664,6 +684,18 @@ rust_print_struct_def (struct type *type, const char *varstring, if (is_enum) { fputs_filtered ("enum ", stream); + + if (rust_empty_enum_p (type)) + { + if (tagname != NULL) + { + fputs_filtered (tagname, stream); + fputs_filtered (" ", stream); + } + fputs_filtered ("{}", stream); + return; + } + type = TYPE_FIELD_TYPE (type, 0); struct dynamic_prop *discriminant_prop @@ -779,8 +811,6 @@ rust_internal_print_type (struct type *type, const char *varstring, const struct type_print_options *flags, bool for_rust_enum, print_offset_data *podata) { - int i; - QUIT; if (show <= 0 && TYPE_NAME (type) != NULL) @@ -814,7 +844,7 @@ rust_internal_print_type (struct type *type, const char *varstring, if (varstring != NULL) fputs_filtered (varstring, stream); fputs_filtered ("(", stream); - for (i = 0; i < TYPE_NFIELDS (type); ++i) + for (int i = 0; i < TYPE_NFIELDS (type); ++i) { QUIT; if (i > 0) @@ -859,7 +889,7 @@ rust_internal_print_type (struct type *type, const char *varstring, case TYPE_CODE_ENUM: { - int i, len = 0; + int len = 0; fputs_filtered ("enum ", stream); if (TYPE_NAME (type) != NULL) @@ -870,7 +900,7 @@ rust_internal_print_type (struct type *type, const char *varstring, } fputs_filtered ("{\n", stream); - for (i = 0; i < TYPE_NFIELDS (type); ++i) + for (int i = 0; i < TYPE_NFIELDS (type); ++i) { const char *name = TYPE_FIELD_NAME (type, i); @@ -888,6 +918,20 @@ rust_internal_print_type (struct type *type, const char *varstring, } break; + case TYPE_CODE_PTR: + { + if (TYPE_NAME (type) != nullptr) + fputs_filtered (TYPE_NAME (type), stream); + else + { + /* We currently can't distinguish between pointers and + references. */ + fputs_filtered ("*mut ", stream); + type_print (TYPE_TARGET_TYPE (type), "", stream, 0); + } + } + break; + default: c_printer: c_print_type (type, varstring, stream, show, level, flags); @@ -1128,7 +1172,7 @@ rust_evaluate_funcall (struct expression *exp, int *pos, enum noside noside) if (noside == EVAL_AVOID_SIDE_EFFECTS) result = value_zero (TYPE_TARGET_TYPE (fn_type), not_lval); else - result = call_function_by_hand (function, NULL, num_args + 1, args.data ()); + result = call_function_by_hand (function, NULL, args); return result; } @@ -1555,7 +1599,7 @@ rust_evaluate_subexp (struct type *expect_type, struct expression *exp, case OP_RUST_ARRAY: { - int pc = (*pos)++; + (*pos)++; int copies; struct value *elt; struct value *ncopies; @@ -1589,7 +1633,7 @@ rust_evaluate_subexp (struct type *expect_type, struct expression *exp, /* Anonymous field access, i.e. foo.1. */ struct value *lhs; int pc, field_number, nfields; - struct type *type, *variant_type; + struct type *type; pc = (*pos)++; field_number = longest_to_int (exp->elts[pc + 1].longconst); @@ -1604,6 +1648,10 @@ rust_evaluate_subexp (struct type *expect_type, struct expression *exp, if (rust_enum_p (type)) { + if (rust_empty_enum_p (type)) + error (_("Cannot access field %d of empty enum %s"), + field_number, TYPE_NAME (type)); + const gdb_byte *valaddr = value_contents (lhs); struct field *variant_field = rust_enum_variant (type, valaddr); @@ -1672,6 +1720,10 @@ tuple structs, and tuple-like enum variants")); type = value_type (lhs); if (TYPE_CODE (type) == TYPE_CODE_STRUCT && rust_enum_p (type)) { + if (rust_empty_enum_p (type)) + error (_("Cannot access field %s of empty enum %s"), + field_name, TYPE_NAME (type)); + const gdb_byte *valaddr = value_contents (lhs); struct field *variant_field = rust_enum_variant (type, valaddr); @@ -1686,9 +1738,9 @@ tuple structs, and tuple-like enum variants")); struct type *outer_type = type; type = value_type (lhs); if (rust_tuple_type_p (type) || rust_tuple_struct_type_p (type)) - error (_("Attempting to access named field foo of tuple " + error (_("Attempting to access named field %s of tuple " "variant %s::%s, which has only anonymous fields"), - TYPE_NAME (outer_type), + field_name, TYPE_NAME (outer_type), rust_last_path_segment (TYPE_NAME (type))); TRY