X-Git-Url: http://git.efficios.com/?a=blobdiff_plain;f=gdb%2Frust-lang.c;h=9123bf2146d516dabb72f9d9caff728dced98ef0;hb=4f83758119ddf0f114477760d79bdde7bbc76835;hp=43db722142b87aeb2069c50979f269da4c590de0;hpb=4a3fe98f885a2d1db804584e7ea265ab3ccef4d7;p=deliverable%2Fbinutils-gdb.git diff --git a/gdb/rust-lang.c b/gdb/rust-lang.c index 43db722142..9123bf2146 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-2020 Free Software Foundation, Inc. This file is part of GDB. @@ -37,6 +37,7 @@ #include #include #include +#include "cli/cli-style.h" /* See rust-lang.h. */ @@ -226,6 +227,26 @@ rust_chartype_p (struct type *type) && TYPE_UNSIGNED (type)); } +/* Return true if TYPE is a string type. */ + +static bool +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 + && 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 + && !rust_enum_p (type) + && rust_slice_type_p (type) + && strcmp (TYPE_NAME (type), "&str") == 0)); +} + /* If VALUE represents a trait object pointer, return the underlying pointer with the correct (i.e., runtime) type. Otherwise, return NULL. */ @@ -358,6 +379,14 @@ val_print_struct (struct type *type, int embedded_offset, if (rust_slice_type_p (type) && strcmp (TYPE_NAME (type), "&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 + will be the type of the structure representing the string we want + to print. + However, RUST_VAL_PRINT_STR looks up the fields of the string + inside VAL, assuming that VAL is the string. + So, recreate VAL as a value representing just the string. */ + val = value_at_lazy (type, value_address (val) + embedded_offset); rust_val_print_str (stream, val, options); return; } @@ -445,7 +474,9 @@ rust_print_enum (struct type *type, int embedded_offset, if (rust_empty_enum_p (type)) { /* Print the enum type name here to be more clear. */ - fprintf_filtered (stream, _("%s {}"), TYPE_NAME (type)); + fprintf_filtered (stream, _("%s {%p[%p]}"), + TYPE_NAME (type), + metadata_style.style ().ptr (), nullptr); return; } @@ -798,9 +829,9 @@ rust_print_typedef (struct type *type, struct ui_file *stream) { type = check_typedef (type); - fprintf_filtered (stream, "type %s = ", SYMBOL_PRINT_NAME (new_symbol)); + fprintf_filtered (stream, "type %s = ", new_symbol->print_name ()); type_print (type, "", stream, 0); - fprintf_filtered (stream, ";\n"); + fprintf_filtered (stream, ";"); } /* la_print_type implementation for Rust. */ @@ -811,8 +842,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) @@ -846,7 +875,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) @@ -891,7 +920,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) @@ -902,7 +931,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); @@ -920,6 +949,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); @@ -1160,7 +1203,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; } @@ -1731,18 +1774,17 @@ tuple structs, and tuple-like enum variants")); field_name, TYPE_NAME (outer_type), rust_last_path_segment (TYPE_NAME (type))); - TRY + try { result = value_struct_elt (&lhs, NULL, field_name, NULL, "structure"); } - CATCH (except, RETURN_MASK_ERROR) + 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))); } - END_CATCH } else result = value_struct_elt (&lhs, NULL, field_name, NULL, "structure"); @@ -2008,7 +2050,7 @@ rust_lookup_symbol_nonlocal (const struct language_defn *langdef, const struct block *block, const domain_enum domain) { - struct block_symbol result = {NULL, NULL}; + struct block_symbol result = {}; if (symbol_lookup_debug) { @@ -2123,7 +2165,6 @@ extern const struct language_defn rust_language_defn = rust_language_arch_info, default_print_array_index, default_pass_by_reference, - c_get_string, rust_watch_location_expression, NULL, /* la_get_symbol_name_matcher */ iterate_over_symbols, @@ -2131,5 +2172,6 @@ extern const struct language_defn rust_language_defn = &default_varobj_ops, NULL, NULL, - LANG_MAGIC + rust_is_string_type_p, + "{...}" /* la_struct_too_deep_ellipsis */ };