X-Git-Url: http://drtracing.org/?a=blobdiff_plain;f=gdb%2Frust-lang.c;h=d251dab29fc403232897b99aa1083e46429f72d2;hb=60db1b8565060f4bd2287b060ea9724c93289982;hp=f2fb0119b00c7a35f1034dfe65efc3b1d32470b8;hpb=24e99c6c3c78e38a9919c9f8e8b831713f8303a3;p=deliverable%2Fbinutils-gdb.git diff --git a/gdb/rust-lang.c b/gdb/rust-lang.c index f2fb0119b0..d251dab29f 100644 --- a/gdb/rust-lang.c +++ b/gdb/rust-lang.c @@ -81,7 +81,7 @@ rust_enum_p (struct type *type) static bool rust_empty_enum_p (const struct type *type) { - return TYPE_NFIELDS (type) == 0; + return type->num_fields () == 0; } /* Given an already-resolved enum type and contents, find which @@ -91,7 +91,7 @@ static int rust_enum_variant (struct type *type) { /* The active variant is simply the first non-artificial field. */ - for (int i = 0; i < TYPE_NFIELDS (type); ++i) + for (int i = 0; i < type->num_fields (); ++i) if (!TYPE_FIELD_ARTIFICIAL (type, i)) return i; @@ -109,9 +109,9 @@ rust_tuple_type_p (struct type *type) /* The current implementation is a bit of a hack, but there's nothing else in the debuginfo to distinguish a tuple from a struct. */ - return (TYPE_CODE (type) == TYPE_CODE_STRUCT - && TYPE_NAME (type) != NULL - && TYPE_NAME (type)[0] == '('); + return (type->code () == TYPE_CODE_STRUCT + && type->name () != NULL + && type->name ()[0] == '('); } /* Return true if all non-static fields of a structlike type are in a @@ -124,11 +124,11 @@ rust_underscore_fields (struct type *type) field_number = 0; - if (TYPE_CODE (type) != TYPE_CODE_STRUCT) + if (type->code () != TYPE_CODE_STRUCT) return false; - for (i = 0; i < TYPE_NFIELDS (type); ++i) + for (i = 0; i < type->num_fields (); ++i) { - if (!field_is_static (&TYPE_FIELD (type, i))) + if (!field_is_static (&type->field (i))) { char buf[20]; @@ -149,7 +149,7 @@ rust_tuple_struct_type_p (struct type *type) /* This is just an approximation until DWARF can represent Rust more precisely. We exclude zero-length structs because they may not be tuple structs, and there's no way to tell. */ - return TYPE_NFIELDS (type) > 0 && rust_underscore_fields (type); + return type->num_fields () > 0 && rust_underscore_fields (type); } /* Return true if TYPE is a slice type, otherwise false. */ @@ -157,10 +157,10 @@ rust_tuple_struct_type_p (struct type *type) static bool rust_slice_type_p (struct type *type) { - return (TYPE_CODE (type) == TYPE_CODE_STRUCT - && TYPE_NAME (type) != NULL - && (strncmp (TYPE_NAME (type), "&[", 2) == 0 - || strcmp (TYPE_NAME (type), "&str") == 0)); + return (type->code () == TYPE_CODE_STRUCT + && type->name () != NULL + && (strncmp (type->name (), "&[", 2) == 0 + || strcmp (type->name (), "&str") == 0)); } /* Return true if TYPE is a range type, otherwise false. */ @@ -170,23 +170,23 @@ rust_range_type_p (struct type *type) { int i; - if (TYPE_CODE (type) != TYPE_CODE_STRUCT - || TYPE_NFIELDS (type) > 2 - || TYPE_NAME (type) == NULL - || strstr (TYPE_NAME (type), "::Range") == NULL) + if (type->code () != TYPE_CODE_STRUCT + || type->num_fields () > 2 + || type->name () == NULL + || strstr (type->name (), "::Range") == NULL) return false; - if (TYPE_NFIELDS (type) == 0) + if (type->num_fields () == 0) return true; i = 0; if (strcmp (TYPE_FIELD_NAME (type, 0), "start") == 0) { - if (TYPE_NFIELDS (type) == 1) + if (type->num_fields () == 1) return true; i = 1; } - else if (TYPE_NFIELDS (type) == 2) + else if (type->num_fields () == 2) { /* First field had to be "start". */ return false; @@ -202,8 +202,8 @@ rust_range_type_p (struct type *type) static bool rust_inclusive_range_type_p (struct type *type) { - return (strstr (TYPE_NAME (type), "::RangeInclusive") != NULL - || strstr (TYPE_NAME (type), "::RangeToInclusive") != NULL); + return (strstr (type->name (), "::RangeInclusive") != NULL + || strstr (type->name (), "::RangeToInclusive") != NULL); } /* Return true if TYPE seems to be the type "u8", otherwise false. */ @@ -211,7 +211,7 @@ rust_inclusive_range_type_p (struct type *type) static bool rust_u8_type_p (struct type *type) { - return (TYPE_CODE (type) == TYPE_CODE_INT + return (type->code () == TYPE_CODE_INT && TYPE_UNSIGNED (type) && TYPE_LENGTH (type) == 1); } @@ -221,7 +221,7 @@ rust_u8_type_p (struct type *type) static bool rust_chartype_p (struct type *type) { - return (TYPE_CODE (type) == TYPE_CODE_CHAR + return (type->code () == TYPE_CODE_CHAR && TYPE_LENGTH (type) == 4 && TYPE_UNSIGNED (type)); } @@ -234,16 +234,16 @@ rust_is_string_type_p (struct type *type) LONGEST low_bound, high_bound; type = check_typedef (type); - return ((TYPE_CODE (type) == TYPE_CODE_STRING) - || (TYPE_CODE (type) == TYPE_CODE_PTR - && (TYPE_CODE (TYPE_TARGET_TYPE (type)) == TYPE_CODE_ARRAY + return ((type->code () == TYPE_CODE_STRING) + || (type->code () == TYPE_CODE_PTR + && (TYPE_TARGET_TYPE (type)->code () == TYPE_CODE_ARRAY && rust_u8_type_p (TYPE_TARGET_TYPE (TYPE_TARGET_TYPE (type))) && get_array_bounds (TYPE_TARGET_TYPE (type), &low_bound, &high_bound))) - || (TYPE_CODE (type) == TYPE_CODE_STRUCT + || (type->code () == TYPE_CODE_STRUCT && !rust_enum_p (type) && rust_slice_type_p (type) - && strcmp (TYPE_NAME (type), "&str") == 0)); + && strcmp (type->name (), "&str") == 0)); } /* If VALUE represents a trait object pointer, return the underlying @@ -255,7 +255,7 @@ rust_get_trait_object_pointer (struct value *value) { struct type *type = check_typedef (value_type (value)); - if (TYPE_CODE (type) != TYPE_CODE_STRUCT || TYPE_NFIELDS (type) != 2) + if (type->code () != TYPE_CODE_STRUCT || type->num_fields () != 2) return NULL; /* Try to be a bit resilient if the ABI changes. */ @@ -379,7 +379,7 @@ val_print_struct (struct value *val, struct ui_file *stream, int recurse, int first_field; struct type *type = check_typedef (value_type (val)); - if (rust_slice_type_p (type) && strcmp (TYPE_NAME (type), "&str") == 0) + if (rust_slice_type_p (type) && strcmp (type->name (), "&str") == 0) { /* If what we are printing here is actually a string within a structure then VAL will be the original parent value, while TYPE @@ -399,13 +399,13 @@ val_print_struct (struct value *val, struct ui_file *stream, int recurse, if (!is_tuple) { - if (TYPE_NAME (type) != NULL) - fprintf_filtered (stream, "%s", TYPE_NAME (type)); + if (type->name () != NULL) + fprintf_filtered (stream, "%s", type->name ()); - if (TYPE_NFIELDS (type) == 0) + if (type->num_fields () == 0) return; - if (TYPE_NAME (type) != NULL) + if (type->name () != NULL) fputs_filtered (" ", stream); } @@ -418,9 +418,9 @@ val_print_struct (struct value *val, struct ui_file *stream, int recurse, opts.deref_ref = 0; first_field = 1; - for (i = 0; i < TYPE_NFIELDS (type); ++i) + for (i = 0; i < type->num_fields (); ++i) { - if (field_is_static (&TYPE_FIELD (type, i))) + if (field_is_static (&type->field (i))) continue; if (!first_field) @@ -479,20 +479,20 @@ rust_print_enum (struct value *val, struct ui_file *stream, int recurse, { /* Print the enum type name here to be more clear. */ fprintf_filtered (stream, _("%s {%p[%p]}"), - TYPE_NAME (type), + type->name (), metadata_style.style ().ptr (), nullptr); return; } int variant_fieldno = rust_enum_variant (type); val = value_field (val, variant_fieldno); - struct type *variant_type = TYPE_FIELD_TYPE (type, variant_fieldno); + struct type *variant_type = type->field (variant_fieldno).type (); - int nfields = TYPE_NFIELDS (variant_type); + int nfields = variant_type->num_fields (); bool is_tuple = rust_tuple_struct_type_p (variant_type); - fprintf_filtered (stream, "%s", TYPE_NAME (variant_type)); + fprintf_filtered (stream, "%s", variant_type->name ()); if (nfields == 0) { /* In case of a nullary variant like 'None', just output @@ -510,7 +510,7 @@ rust_print_enum (struct value *val, struct ui_file *stream, int recurse, } bool first_field = true; - for (int j = 0; j < TYPE_NFIELDS (variant_type); j++) + for (int j = 0; j < variant_type->num_fields (); j++) { if (!first_field) fputs_filtered (", ", stream); @@ -559,13 +559,13 @@ rust_value_print_inner (struct value *val, struct ui_file *stream, ? Val_prettyformat : Val_no_prettyformat); struct type *type = check_typedef (value_type (val)); - switch (TYPE_CODE (type)) + switch (type->code ()) { case TYPE_CODE_PTR: { LONGEST low_bound, high_bound; - if (TYPE_CODE (TYPE_TARGET_TYPE (type)) == TYPE_CODE_ARRAY + if (TYPE_TARGET_TYPE (type)->code () == TYPE_CODE_ARRAY && rust_u8_type_p (TYPE_TARGET_TYPE (TYPE_TARGET_TYPE (type))) && get_array_bounds (TYPE_TARGET_TYPE (type), &low_bound, &high_bound)) @@ -599,7 +599,7 @@ rust_value_print_inner (struct value *val, struct ui_file *stream, case TYPE_CODE_INT: /* Recognize the unit type. */ if (TYPE_UNSIGNED (type) && TYPE_LENGTH (type) == 0 - && TYPE_NAME (type) != NULL && strcmp (TYPE_NAME (type), "()") == 0) + && type->name () != NULL && strcmp (type->name (), "()") == 0) { fputs_filtered ("()", stream); break; @@ -676,7 +676,7 @@ rust_print_struct_def (struct type *type, const char *varstring, /* Print a tuple type simply. */ if (rust_tuple_type_p (type)) { - fputs_filtered (TYPE_NAME (type), stream); + fputs_filtered (type->name (), stream); return; } @@ -693,7 +693,7 @@ rust_print_struct_def (struct type *type, const char *varstring, /* Compute properties of TYPE here because, in the enum case, the rest of the code ends up looking only at the variant part. */ - const char *tagname = TYPE_NAME (type); + const char *tagname = type->name (); bool is_tuple_struct = rust_tuple_struct_type_p (type); bool is_tuple = rust_tuple_type_p (type); bool is_enum = rust_enum_p (type); @@ -712,7 +712,7 @@ rust_print_struct_def (struct type *type, const char *varstring, if (prop != nullptr && prop->kind == PROP_TYPE) type = prop->data.original_type; } - else if (TYPE_CODE (type) == TYPE_CODE_STRUCT) + else if (type->code () == TYPE_CODE_STRUCT) fputs_filtered ("struct ", stream); else fputs_filtered ("union ", stream); @@ -721,7 +721,7 @@ rust_print_struct_def (struct type *type, const char *varstring, fputs_filtered (tagname, stream); } - if (TYPE_NFIELDS (type) == 0 && !is_tuple) + if (type->num_fields () == 0 && !is_tuple) return; if (for_rust_enum && !flags->print_offsets) fputs_filtered (is_tuple_struct ? "(" : "{", stream); @@ -733,9 +733,9 @@ rust_print_struct_def (struct type *type, const char *varstring, field indices here because it simplifies calls to print_offset_data::update below. */ std::vector fields; - for (int i = 0; i < TYPE_NFIELDS (type); ++i) + for (int i = 0; i < type->num_fields (); ++i) { - if (field_is_static (&TYPE_FIELD (type, i))) + if (field_is_static (&type->field (i))) continue; if (is_enum && TYPE_FIELD_ARTIFICIAL (type, i)) continue; @@ -753,7 +753,7 @@ rust_print_struct_def (struct type *type, const char *varstring, { QUIT; - gdb_assert (!field_is_static (&TYPE_FIELD (type, i))); + gdb_assert (!field_is_static (&type->field (i))); gdb_assert (! (is_enum && TYPE_FIELD_ARTIFICIAL (type, i))); if (flags->print_offsets) @@ -775,7 +775,7 @@ rust_print_struct_def (struct type *type, const char *varstring, styled_string (variable_name_style.style (), TYPE_FIELD_NAME (type, i))); - rust_internal_print_type (TYPE_FIELD_TYPE (type, i), NULL, + rust_internal_print_type (type->field (i).type (), NULL, stream, (is_enum ? show : show - 1), level + 2, flags, is_enum, podata); if (!for_rust_enum || flags->print_offsets) @@ -783,7 +783,7 @@ rust_print_struct_def (struct type *type, const char *varstring, /* Note that this check of "I" is ok because we only sorted the fields by offset when print_offsets was set, so we won't take this branch in that case. */ - else if (i + 1 < TYPE_NFIELDS (type)) + else if (i + 1 < type->num_fields ()) fputs_filtered (", ", stream); } @@ -824,19 +824,19 @@ rust_internal_print_type (struct type *type, const char *varstring, { QUIT; if (show <= 0 - && TYPE_NAME (type) != NULL) + && type->name () != NULL) { /* Rust calls the unit type "void" in its debuginfo, but we don't want to print it as that. */ - if (TYPE_CODE (type) == TYPE_CODE_VOID) + if (type->code () == TYPE_CODE_VOID) fputs_filtered ("()", stream); else - fputs_filtered (TYPE_NAME (type), stream); + fputs_filtered (type->name (), stream); return; } type = check_typedef (type); - switch (TYPE_CODE (type)) + switch (type->code ()) { case TYPE_CODE_VOID: /* If we have an enum, we've already printed the type's @@ -855,17 +855,17 @@ rust_internal_print_type (struct type *type, const char *varstring, if (varstring != NULL) fputs_filtered (varstring, stream); fputs_filtered ("(", stream); - for (int i = 0; i < TYPE_NFIELDS (type); ++i) + for (int i = 0; i < type->num_fields (); ++i) { QUIT; if (i > 0) fputs_filtered (", ", stream); - rust_internal_print_type (TYPE_FIELD_TYPE (type, i), "", stream, + rust_internal_print_type (type->field (i).type (), "", stream, -1, 0, flags, false, podata); } fputs_filtered (")", stream); /* If it returns unit, we can omit the return type. */ - if (TYPE_CODE (TYPE_TARGET_TYPE (type)) != TYPE_CODE_VOID) + if (TYPE_TARGET_TYPE (type)->code () != TYPE_CODE_VOID) { fputs_filtered (" -> ", stream); rust_internal_print_type (TYPE_TARGET_TYPE (type), "", stream, @@ -882,8 +882,8 @@ rust_internal_print_type (struct type *type, const char *varstring, stream, show - 1, level, flags, false, podata); - if (TYPE_HIGH_BOUND_KIND (TYPE_INDEX_TYPE (type)) == PROP_LOCEXPR - || TYPE_HIGH_BOUND_KIND (TYPE_INDEX_TYPE (type)) == PROP_LOCLIST) + if (TYPE_HIGH_BOUND_KIND (type->index_type ()) == PROP_LOCEXPR + || TYPE_HIGH_BOUND_KIND (type->index_type ()) == PROP_LOCLIST) fprintf_filtered (stream, "; variable length"); else if (get_array_bounds (type, &low_bound, &high_bound)) fprintf_filtered (stream, "; %s", @@ -903,22 +903,22 @@ rust_internal_print_type (struct type *type, const char *varstring, int len = 0; fputs_filtered ("enum ", stream); - if (TYPE_NAME (type) != NULL) + if (type->name () != NULL) { - fputs_filtered (TYPE_NAME (type), stream); + fputs_filtered (type->name (), stream); fputs_filtered (" ", stream); - len = strlen (TYPE_NAME (type)); + len = strlen (type->name ()); } fputs_filtered ("{\n", stream); - for (int i = 0; i < TYPE_NFIELDS (type); ++i) + for (int i = 0; i < type->num_fields (); ++i) { const char *name = TYPE_FIELD_NAME (type, i); QUIT; if (len > 0 - && strncmp (name, TYPE_NAME (type), len) == 0 + && strncmp (name, type->name (), len) == 0 && name[len] == ':' && name[len + 1] == ':') name += len + 2; @@ -933,8 +933,8 @@ rust_internal_print_type (struct type *type, const char *varstring, case TYPE_CODE_PTR: { - if (TYPE_NAME (type) != nullptr) - fputs_filtered (TYPE_NAME (type), stream); + if (type->name () != nullptr) + fputs_filtered (type->name (), stream); else { /* We currently can't distinguish between pointers and @@ -951,16 +951,6 @@ rust_internal_print_type (struct type *type, const char *varstring, } } -static void -rust_print_type (struct type *type, const char *varstring, - struct ui_file *stream, int show, int level, - const struct type_print_options *flags) -{ - print_offset_data podata; - rust_internal_print_type (type, varstring, stream, show, level, - flags, false, &podata); -} - /* Like arch_composite_type, but uses TYPE to decide how to allocate @@ -981,29 +971,29 @@ rust_composite_type (struct type *original, if (field2 != NULL) ++nfields; - TYPE_CODE (result) = TYPE_CODE_STRUCT; - TYPE_NAME (result) = name; + result->set_code (TYPE_CODE_STRUCT); + result->set_name (name); - TYPE_NFIELDS (result) = nfields; - TYPE_FIELDS (result) - = (struct field *) TYPE_ZALLOC (result, nfields * sizeof (struct field)); + result->set_num_fields (nfields); + result->set_fields + ((struct field *) TYPE_ZALLOC (result, nfields * sizeof (struct field))); i = 0; bitpos = 0; if (field1 != NULL) { - struct field *field = &TYPE_FIELD (result, i); + struct field *field = &result->field (i); SET_FIELD_BITPOS (*field, bitpos); bitpos += TYPE_LENGTH (type1) * TARGET_CHAR_BIT; FIELD_NAME (*field) = field1; - FIELD_TYPE (*field) = type1; + field->set_type (type1); ++i; } if (field2 != NULL) { - struct field *field = &TYPE_FIELD (result, i); + struct field *field = &result->field (i); unsigned align = type_align (type2); if (align != 0) @@ -1018,14 +1008,14 @@ rust_composite_type (struct type *original, SET_FIELD_BITPOS (*field, bitpos); FIELD_NAME (*field) = field2; - FIELD_TYPE (*field) = type2; + field->set_type (type2); ++i; } if (i > 0) TYPE_LENGTH (result) = (TYPE_FIELD_BITPOS (result, i - 1) / TARGET_CHAR_BIT + - TYPE_LENGTH (TYPE_FIELD_TYPE (result, i - 1))); + TYPE_LENGTH (result->field (i - 1).type ())); return result; } @@ -1066,51 +1056,6 @@ enum rust_primitive_types nr_rust_primitive_types }; -/* la_language_arch_info implementation for Rust. */ - -static void -rust_language_arch_info (struct gdbarch *gdbarch, - struct language_arch_info *lai) -{ - const struct builtin_type *builtin = builtin_type (gdbarch); - struct type *tem; - struct type **types; - unsigned int length; - - types = GDBARCH_OBSTACK_CALLOC (gdbarch, nr_rust_primitive_types + 1, - struct type *); - - types[rust_primitive_bool] = arch_boolean_type (gdbarch, 8, 1, "bool"); - types[rust_primitive_char] = arch_character_type (gdbarch, 32, 1, "char"); - types[rust_primitive_i8] = arch_integer_type (gdbarch, 8, 0, "i8"); - types[rust_primitive_u8] = arch_integer_type (gdbarch, 8, 1, "u8"); - types[rust_primitive_i16] = arch_integer_type (gdbarch, 16, 0, "i16"); - types[rust_primitive_u16] = arch_integer_type (gdbarch, 16, 1, "u16"); - types[rust_primitive_i32] = arch_integer_type (gdbarch, 32, 0, "i32"); - types[rust_primitive_u32] = arch_integer_type (gdbarch, 32, 1, "u32"); - types[rust_primitive_i64] = arch_integer_type (gdbarch, 64, 0, "i64"); - types[rust_primitive_u64] = arch_integer_type (gdbarch, 64, 1, "u64"); - - length = 8 * TYPE_LENGTH (builtin->builtin_data_ptr); - types[rust_primitive_isize] = arch_integer_type (gdbarch, length, 0, "isize"); - types[rust_primitive_usize] = arch_integer_type (gdbarch, length, 1, "usize"); - - types[rust_primitive_f32] = arch_float_type (gdbarch, 32, "f32", - floatformats_ieee_single); - types[rust_primitive_f64] = arch_float_type (gdbarch, 64, "f64", - floatformats_ieee_double); - - types[rust_primitive_unit] = arch_integer_type (gdbarch, 0, 1, "()"); - - tem = make_cv_type (1, 0, types[rust_primitive_u8], NULL); - types[rust_primitive_str] = rust_slice_type ("&str", tem, - types[rust_primitive_usize]); - - lai->primitive_type_vector = types; - lai->bool_type_default = types[rust_primitive_bool]; - lai->string_char_type = types[rust_primitive_u8]; -} - /* A helper for rust_evaluate_subexp that handles OP_FUNCALL. */ @@ -1151,19 +1096,19 @@ rust_evaluate_funcall (struct expression *exp, int *pos, enum noside noside) args[0] = arg0; /* We don't yet implement real Deref semantics. */ - while (TYPE_CODE (value_type (args[0])) == TYPE_CODE_PTR) + while (value_type (args[0])->code () == TYPE_CODE_PTR) args[0] = value_ind (args[0]); type = value_type (args[0]); - if ((TYPE_CODE (type) != TYPE_CODE_STRUCT - && TYPE_CODE (type) != TYPE_CODE_UNION - && TYPE_CODE (type) != TYPE_CODE_ENUM) + if ((type->code () != TYPE_CODE_STRUCT + && type->code () != TYPE_CODE_UNION + && type->code () != TYPE_CODE_ENUM) || rust_tuple_type_p (type)) error (_("Method calls only supported on struct or enum types")); - if (TYPE_NAME (type) == NULL) + if (type->name () == NULL) error (_("Method call on nameless type")); - std::string name = std::string (TYPE_NAME (type)) + "::" + method; + std::string name = std::string (type->name ()) + "::" + method; block = get_selected_block (0); sym = lookup_symbol (name.c_str (), block, VAR_DOMAIN, NULL); @@ -1171,10 +1116,10 @@ rust_evaluate_funcall (struct expression *exp, int *pos, enum noside noside) error (_("Could not find function named '%s'"), name.c_str ()); fn_type = SYMBOL_TYPE (sym.symbol); - if (TYPE_NFIELDS (fn_type) == 0) + if (fn_type->num_fields () == 0) error (_("Function '%s' takes no arguments"), name.c_str ()); - if (TYPE_CODE (TYPE_FIELD_TYPE (fn_type, 0)) == TYPE_CODE_PTR) + if (fn_type->field (0).type ()->code () == TYPE_CODE_PTR) args[0] = value_addr (args[0]); function = address_of_variable (sym.symbol, block); @@ -1303,7 +1248,7 @@ rust_compute_range (struct type *type, struct value *range, *high = 0; *kind = BOTH_BOUND_DEFAULT; - if (TYPE_NFIELDS (type) == 0) + if (type->num_fields () == 0) return; i = 0; @@ -1313,7 +1258,7 @@ rust_compute_range (struct type *type, struct value *range, *low = value_as_long (value_field (range, 0)); ++i; } - if (TYPE_NFIELDS (type) > i + if (type->num_fields () > i && strcmp (TYPE_FIELD_NAME (type, i), "end") == 0) { *kind = (*kind == BOTH_BOUND_DEFAULT @@ -1361,22 +1306,22 @@ rust_subscript (struct expression *exp, int *pos, enum noside noside, if (noside == EVAL_AVOID_SIDE_EFFECTS) { struct type *base_type = nullptr; - if (TYPE_CODE (type) == TYPE_CODE_ARRAY) + if (type->code () == TYPE_CODE_ARRAY) base_type = TYPE_TARGET_TYPE (type); else if (rust_slice_type_p (type)) { - for (int i = 0; i < TYPE_NFIELDS (type); ++i) + for (int i = 0; i < type->num_fields (); ++i) { if (strcmp (TYPE_FIELD_NAME (type, i), "data_ptr") == 0) { - base_type = TYPE_TARGET_TYPE (TYPE_FIELD_TYPE (type, i)); + base_type = TYPE_TARGET_TYPE (type->field (i).type ()); break; } } if (base_type == nullptr) error (_("Could not find 'data_ptr' in slice type")); } - else if (TYPE_CODE (type) == TYPE_CODE_PTR) + else if (type->code () == TYPE_CODE_PTR) base_type = TYPE_TARGET_TYPE (type); else error (_("Cannot subscript non-array type")); @@ -1405,7 +1350,7 @@ rust_subscript (struct expression *exp, int *pos, enum noside noside, LONGEST low_bound; struct value *base; - if (TYPE_CODE (type) == TYPE_CODE_ARRAY) + if (type->code () == TYPE_CODE_ARRAY) { base = lhs; if (!get_array_bounds (type, &low_bound, &high_bound)) @@ -1423,7 +1368,7 @@ rust_subscript (struct expression *exp, int *pos, enum noside noside, low_bound = 0; high_bound = value_as_long (len); } - else if (TYPE_CODE (type) == TYPE_CODE_PTR) + else if (type->code () == TYPE_CODE_PTR) { base = lhs; low_bound = 0; @@ -1465,7 +1410,7 @@ rust_subscript (struct expression *exp, int *pos, enum noside noside, "usize"); const char *new_name = ((type != nullptr && rust_slice_type_p (type)) - ? TYPE_NAME (type) : "&[*gdb*]"); + ? type->name () : "&[*gdb*]"); slice = rust_slice_type (new_name, value_type (result), usize); @@ -1526,7 +1471,7 @@ rust_evaluate_subexp (struct type *expect_type, struct expression *exp, /* Preserving the type is enough. */ return value; } - if (TYPE_CODE (value_type (value)) == TYPE_CODE_BOOL) + if (value_type (value)->code () == TYPE_CODE_BOOL) result = value_from_longest (value_type (value), value_logical_not (value)); else @@ -1655,7 +1600,7 @@ rust_evaluate_subexp (struct type *expect_type, struct expression *exp, type = value_type (lhs); - if (TYPE_CODE (type) == TYPE_CODE_STRUCT) + if (type->code () == TYPE_CODE_STRUCT) { struct type *outer_type = NULL; @@ -1667,7 +1612,7 @@ rust_evaluate_subexp (struct type *expect_type, struct expression *exp, if (rust_empty_enum_p (type)) error (_("Cannot access field %d of empty enum %s"), - field_number, TYPE_NAME (type)); + field_number, type->name ()); int fieldno = rust_enum_variant (type); lhs = value_primitive_field (lhs, 0, fieldno, type); @@ -1676,20 +1621,20 @@ rust_evaluate_subexp (struct type *expect_type, struct expression *exp, } /* Tuples and tuple structs */ - nfields = TYPE_NFIELDS (type); + nfields = type->num_fields (); if (field_number >= nfields || field_number < 0) { if (outer_type != NULL) error(_("Cannot access field %d of variant %s::%s, " "there are only %d fields"), - field_number, TYPE_NAME (outer_type), - rust_last_path_segment (TYPE_NAME (type)), + field_number, outer_type->name (), + rust_last_path_segment (type->name ()), nfields); else error(_("Cannot access field %d of %s, " "there are only %d fields"), - field_number, TYPE_NAME (type), nfields); + field_number, type->name (), nfields); } /* Tuples are tuple structs too. */ @@ -1697,13 +1642,13 @@ rust_evaluate_subexp (struct type *expect_type, struct expression *exp, { if (outer_type != NULL) error(_("Variant %s::%s is not a tuple variant"), - TYPE_NAME (outer_type), - rust_last_path_segment (TYPE_NAME (type))); + outer_type->name (), + rust_last_path_segment (type->name ())); else error(_("Attempting to access anonymous field %d " "of %s, which is not a tuple, tuple struct, or " "tuple-like variant"), - field_number, TYPE_NAME (type)); + field_number, type->name ()); } result = value_primitive_field (lhs, 0, field_number, type); @@ -1727,7 +1672,7 @@ tuple structs, and tuple-like enum variants")); const char *field_name = &exp->elts[pc + 2].string; type = value_type (lhs); - if (TYPE_CODE (type) == TYPE_CODE_STRUCT && rust_enum_p (type)) + if (type->code () == TYPE_CODE_STRUCT && rust_enum_p (type)) { gdb::array_view view (value_contents (lhs), TYPE_LENGTH (type)); @@ -1735,7 +1680,7 @@ tuple structs, and tuple-like enum variants")); if (rust_empty_enum_p (type)) error (_("Cannot access field %s of empty enum %s"), - field_name, TYPE_NAME (type)); + field_name, type->name ()); int fieldno = rust_enum_variant (type); lhs = value_primitive_field (lhs, 0, fieldno, type); @@ -1745,8 +1690,8 @@ tuple structs, and tuple-like enum variants")); if (rust_tuple_type_p (type) || rust_tuple_struct_type_p (type)) error (_("Attempting to access named field %s of tuple " "variant %s::%s, which has only anonymous fields"), - field_name, TYPE_NAME (outer_type), - rust_last_path_segment (TYPE_NAME (type))); + field_name, outer_type->name (), + rust_last_path_segment (type->name ())); try { @@ -1756,8 +1701,8 @@ tuple structs, and tuple-like enum variants")); catch (const gdb_exception_error &except) { error (_("Could not find field %s of struct variant %s::%s"), - field_name, TYPE_NAME (outer_type), - rust_last_path_segment (TYPE_NAME (type))); + field_name, outer_type->name (), + rust_last_path_segment (type->name ())); } } else @@ -2016,76 +1961,6 @@ rust_operator_check (struct expression *exp, int pos, -/* Implementation of la_lookup_symbol_nonlocal for Rust. */ - -static struct block_symbol -rust_lookup_symbol_nonlocal (const struct language_defn *langdef, - const char *name, - const struct block *block, - const domain_enum domain) -{ - struct block_symbol result = {}; - - if (symbol_lookup_debug) - { - fprintf_unfiltered (gdb_stdlog, - "rust_lookup_symbol_non_local" - " (%s, %s (scope %s), %s)\n", - name, host_address_to_string (block), - block_scope (block), domain_name (domain)); - } - - /* Look up bare names in the block's scope. */ - std::string scopedname; - if (name[cp_find_first_component (name)] == '\0') - { - const char *scope = block_scope (block); - - if (scope[0] != '\0') - { - scopedname = std::string (scope) + "::" + name; - name = scopedname.c_str (); - } - else - name = NULL; - } - - if (name != NULL) - { - result = lookup_symbol_in_static_block (name, block, domain); - if (result.symbol == NULL) - result = lookup_global_symbol (name, block, domain); - } - return result; -} - - - -/* la_sniff_from_mangled_name for Rust. */ - -static int -rust_sniff_from_mangled_name (const char *mangled, char **demangled) -{ - *demangled = gdb_demangle (mangled, DMGL_PARAMS | DMGL_ANSI); - return *demangled != NULL; -} - - - -/* la_watch_location_expression for Rust. */ - -static gdb::unique_xmalloc_ptr -rust_watch_location_expression (struct type *type, CORE_ADDR addr) -{ - type = check_typedef (TYPE_TARGET_TYPE (check_typedef (type))); - std::string name = type_to_string (type); - return gdb::unique_xmalloc_ptr - (xstrprintf ("*(%s as *mut %s)", core_addr_to_string (addr), - name.c_str ())); -} - - - static const struct exp_descriptor exp_descriptor_rust = { rust_print_subexp, @@ -2101,7 +1976,9 @@ static const char *rust_extensions[] = ".rs", NULL }; -extern const struct language_defn rust_language_defn = +/* Constant data representing the Rust language. */ + +extern const struct language_data rust_language_data = { "rust", "Rust", @@ -2117,35 +1994,156 @@ extern const struct language_defn rust_language_defn = rust_printchar, /* Print a character constant */ rust_printstr, /* Function to print string constant */ rust_emitchar, /* Print a single char */ - rust_print_type, /* Print a type using appropriate syntax */ rust_print_typedef, /* Print a typedef using appropriate syntax */ - rust_value_print_inner, /* la_value_print_inner */ - c_value_print, /* Print a top-level value */ - default_read_var_value, /* la_read_var_value */ - NULL, /* Language specific skip_trampoline */ NULL, /* name_of_this */ false, /* la_store_sym_names_in_linkage_form_p */ - rust_lookup_symbol_nonlocal, /* lookup_symbol_nonlocal */ - basic_lookup_transparent_type,/* lookup_transparent_type */ - gdb_demangle, /* Language specific symbol demangler */ - rust_sniff_from_mangled_name, - NULL, /* Language specific - class_name_from_physname */ c_op_print_tab, /* expression operators for printing */ 1, /* c-style arrays */ 0, /* String lower bound */ - default_word_break_characters, - default_collect_symbol_completion_matches, - rust_language_arch_info, - default_print_array_index, - default_pass_by_reference, - rust_watch_location_expression, - NULL, /* la_get_symbol_name_matcher */ - iterate_over_symbols, - default_search_name_hash, &default_varobj_ops, - NULL, - NULL, rust_is_string_type_p, "{...}" /* la_struct_too_deep_ellipsis */ }; + +/* Class representing the Rust language. */ + +class rust_language : public language_defn +{ +public: + rust_language () + : language_defn (language_rust, rust_language_data) + { /* Nothing. */ } + + /* See language.h. */ + void language_arch_info (struct gdbarch *gdbarch, + struct language_arch_info *lai) const override + { + const struct builtin_type *builtin = builtin_type (gdbarch); + + struct type **types + = GDBARCH_OBSTACK_CALLOC (gdbarch, nr_rust_primitive_types + 1, + struct type *); + + types[rust_primitive_bool] = arch_boolean_type (gdbarch, 8, 1, "bool"); + types[rust_primitive_char] = arch_character_type (gdbarch, 32, 1, "char"); + types[rust_primitive_i8] = arch_integer_type (gdbarch, 8, 0, "i8"); + types[rust_primitive_u8] = arch_integer_type (gdbarch, 8, 1, "u8"); + types[rust_primitive_i16] = arch_integer_type (gdbarch, 16, 0, "i16"); + types[rust_primitive_u16] = arch_integer_type (gdbarch, 16, 1, "u16"); + types[rust_primitive_i32] = arch_integer_type (gdbarch, 32, 0, "i32"); + types[rust_primitive_u32] = arch_integer_type (gdbarch, 32, 1, "u32"); + types[rust_primitive_i64] = arch_integer_type (gdbarch, 64, 0, "i64"); + types[rust_primitive_u64] = arch_integer_type (gdbarch, 64, 1, "u64"); + + unsigned int length = 8 * TYPE_LENGTH (builtin->builtin_data_ptr); + types[rust_primitive_isize] = arch_integer_type (gdbarch, length, 0, "isize"); + types[rust_primitive_usize] = arch_integer_type (gdbarch, length, 1, "usize"); + + types[rust_primitive_f32] = arch_float_type (gdbarch, 32, "f32", + floatformats_ieee_single); + types[rust_primitive_f64] = arch_float_type (gdbarch, 64, "f64", + floatformats_ieee_double); + + types[rust_primitive_unit] = arch_integer_type (gdbarch, 0, 1, "()"); + + struct type *tem = make_cv_type (1, 0, types[rust_primitive_u8], NULL); + types[rust_primitive_str] = rust_slice_type ("&str", tem, + types[rust_primitive_usize]); + + lai->primitive_type_vector = types; + lai->bool_type_default = types[rust_primitive_bool]; + lai->string_char_type = types[rust_primitive_u8]; + } + + /* See language.h. */ + bool sniff_from_mangled_name (const char *mangled, + char **demangled) const override + { + *demangled = gdb_demangle (mangled, DMGL_PARAMS | DMGL_ANSI); + return *demangled != NULL; + } + + /* See language.h. */ + + char *demangle (const char *mangled, int options) const override + { + return gdb_demangle (mangled, options); + } + + /* See language.h. */ + + void print_type (struct type *type, const char *varstring, + struct ui_file *stream, int show, int level, + const struct type_print_options *flags) const override + { + print_offset_data podata; + rust_internal_print_type (type, varstring, stream, show, level, + flags, false, &podata); + } + + /* See language.h. */ + + gdb::unique_xmalloc_ptr watch_location_expression + (struct type *type, CORE_ADDR addr) const override + { + type = check_typedef (TYPE_TARGET_TYPE (check_typedef (type))); + std::string name = type_to_string (type); + return gdb::unique_xmalloc_ptr + (xstrprintf ("*(%s as *mut %s)", core_addr_to_string (addr), + name.c_str ())); + } + + /* See language.h. */ + + void value_print_inner + (struct value *val, struct ui_file *stream, int recurse, + const struct value_print_options *options) const override + { + return rust_value_print_inner (val, stream, recurse, options); + } + + /* See language.h. */ + + struct block_symbol lookup_symbol_nonlocal + (const char *name, const struct block *block, + const domain_enum domain) const override + { + struct block_symbol result = {}; + + if (symbol_lookup_debug) + { + fprintf_unfiltered (gdb_stdlog, + "rust_lookup_symbol_non_local" + " (%s, %s (scope %s), %s)\n", + name, host_address_to_string (block), + block_scope (block), domain_name (domain)); + } + + /* Look up bare names in the block's scope. */ + std::string scopedname; + if (name[cp_find_first_component (name)] == '\0') + { + const char *scope = block_scope (block); + + if (scope[0] != '\0') + { + scopedname = std::string (scope) + "::" + name; + name = scopedname.c_str (); + } + else + name = NULL; + } + + if (name != NULL) + { + result = lookup_symbol_in_static_block (name, block, domain); + if (result.symbol == NULL) + result = lookup_global_symbol (name, block, domain); + } + return result; + } +}; + +/* Single instance of the Rust language class. */ + +static rust_language rust_language_defn;