#include <string>
#include <vector>
-extern initialize_file_ftype _initialize_rust_language;
-
/* Returns the last segment of a Rust path like foo::bar::baz. Will
not handle cases where the last segment contains generics. This
will return NULL if the last segment cannot be found. */
{
return (TYPE_CODE (type) == TYPE_CODE_STRUCT
&& TYPE_TAG_NAME (type) != NULL
- && strncmp (TYPE_TAG_NAME (type), "&[", 2) == 0);
+ && (strncmp (TYPE_TAG_NAME (type), "&[", 2) == 0
+ || strcmp (TYPE_TAG_NAME (type), "&str") == 0));
}
/* Return true if TYPE is a range type, otherwise false. */
\f
+/* Helper function to print a string slice. */
+
+static void
+rust_val_print_str (struct ui_file *stream, struct value *val,
+ const struct value_print_options *options)
+{
+ struct value *base = value_struct_elt (&val, NULL, "data_ptr", NULL,
+ "slice");
+ struct value *len = value_struct_elt (&val, NULL, "length", NULL, "slice");
+
+ val_print_string (TYPE_TARGET_TYPE (value_type (base)), "UTF-8",
+ value_as_address (base), value_as_long (len), stream,
+ options);
+}
+
/* rust_print_type branch for structs and untagged unions. */
static void
{
int i;
int first_field;
+
+ if (rust_slice_type_p (type) && strcmp (TYPE_NAME (type), "&str") == 0)
+ {
+ rust_val_print_str (stream, val, options);
+ return;
+ }
+
bool is_tuple = rust_tuple_type_p (type);
bool is_tuple_struct = !is_tuple && rust_tuple_struct_type_p (type);
struct value_print_options opts;
fputs_filtered ("[", stream);
rust_print_type (TYPE_TARGET_TYPE (type), NULL,
stream, show - 1, level, flags);
- fputs_filtered ("; ", stream);
if (TYPE_HIGH_BOUND_KIND (TYPE_INDEX_TYPE (type)) == PROP_LOCEXPR
|| TYPE_HIGH_BOUND_KIND (TYPE_INDEX_TYPE (type)) == PROP_LOCLIST)
- fprintf_filtered (stream, "variable length");
+ fprintf_filtered (stream, "; variable length");
else if (get_array_bounds (type, &low_bound, &high_bound))
- fprintf_filtered (stream, "%s",
+ fprintf_filtered (stream, "; %s",
plongest (high_bound - low_bound + 1));
fputs_filtered ("]", stream);
}
if (noside == EVAL_AVOID_SIDE_EFFECTS)
result = value_zero (TYPE_TARGET_TYPE (fn_type), not_lval);
else
- result = call_function_by_hand (function, num_args + 1, args.data ());
+ result = call_function_by_hand (function, NULL, num_args + 1, args.data ());
return result;
}
else
low = value_as_long (rhs);
+ struct type *type = check_typedef (value_type (lhs));
if (noside == EVAL_AVOID_SIDE_EFFECTS)
{
- struct type *type = check_typedef (value_type (lhs));
+ struct type *base_type = nullptr;
+ if (TYPE_CODE (type) == 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)
+ {
+ if (strcmp (TYPE_FIELD_NAME (type, i), "data_ptr") == 0)
+ {
+ base_type = TYPE_TARGET_TYPE (TYPE_FIELD_TYPE (type, i));
+ break;
+ }
+ }
+ if (base_type == nullptr)
+ error (_("Could not find 'data_ptr' in slice type"));
+ }
+ else if (TYPE_CODE (type) == TYPE_CODE_PTR)
+ base_type = TYPE_TARGET_TYPE (type);
+ else
+ error (_("Cannot subscript non-array type"));
+
+ struct type *new_type;
+ if (want_slice)
+ {
+ if (rust_slice_type_p (type))
+ new_type = type;
+ else
+ {
+ struct type *usize
+ = language_lookup_primitive_type (exp->language_defn,
+ exp->gdbarch,
+ "usize");
+ new_type = rust_slice_type ("&[*gdb*]", base_type, usize);
+ }
+ }
+ else
+ new_type = base_type;
- result = value_zero (TYPE_TARGET_TYPE (type), VALUE_LVAL (lhs));
+ return value_zero (new_type, VALUE_LVAL (lhs));
}
else
{
LONGEST low_bound;
struct value *base;
- struct type *type = check_typedef (value_type (lhs));
if (TYPE_CODE (type) == TYPE_CODE_ARRAY)
{
usize = language_lookup_primitive_type (exp->language_defn,
exp->gdbarch,
"usize");
- slice = rust_slice_type ("&[*gdb*]", value_type (result),
- usize);
+ const char *new_name = ((type != nullptr
+ && rust_slice_type_p (type))
+ ? TYPE_NAME (type) : "&[*gdb*]");
+
+ slice = rust_slice_type (new_name, value_type (result), usize);
addrval = value_allocate_space_in_inferior (TYPE_LENGTH (slice));
addr = value_as_long (addrval);
\f
+/* la_watch_location_expression for Rust. */
+
+static gdb::unique_xmalloc_ptr<char>
+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<char>
+ (xstrprintf ("*(%s as *mut %s)", core_addr_to_string (addr),
+ name.c_str ()));
+}
+
+\f
+
static const struct exp_descriptor exp_descriptor_rust =
{
rust_print_subexp,
".rs", NULL
};
-static const struct language_defn rust_language_defn =
+extern const struct language_defn rust_language_defn =
{
"rust",
"Rust",
1, /* c-style arrays */
0, /* String lower bound */
default_word_break_characters,
- default_make_symbol_completion_list,
+ default_collect_symbol_completion_matches,
rust_language_arch_info,
default_print_array_index,
default_pass_by_reference,
c_get_string,
+ rust_watch_location_expression,
NULL, /* la_get_symbol_name_cmp */
iterate_over_symbols,
&default_varobj_ops,
NULL,
LANG_MAGIC
};
-
-void
-_initialize_rust_language (void)
-{
- add_language (&rust_language_defn);
-}