aboutsummaryrefslogtreecommitdiff
path: root/gdb/rust-lang.c
diff options
context:
space:
mode:
Diffstat (limited to 'gdb/rust-lang.c')
-rw-r--r--gdb/rust-lang.c71
1 files changed, 41 insertions, 30 deletions
diff --git a/gdb/rust-lang.c b/gdb/rust-lang.c
index e7fdc28..3957413 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-2024 Free Software Foundation, Inc.
+ Copyright (C) 2016-2025 Free Software Foundation, Inc.
This file is part of GDB.
@@ -116,25 +116,28 @@ rust_tuple_type_p (struct type *type)
}
/* Return true if all non-static fields of a structlike type are in a
- sequence like __0, __1, __2. */
+ sequence like 0, 1, 2. "__" prefixes are also accepted -- rustc
+ emits "__0" but gccrs emits "0". */
static bool
rust_underscore_fields (struct type *type)
{
- int i, field_number;
-
- field_number = 0;
+ int field_number = 0;
if (type->code () != TYPE_CODE_STRUCT)
return false;
- for (i = 0; i < type->num_fields (); ++i)
+ for (int i = 0; i < type->num_fields (); ++i)
{
if (!type->field (i).is_static ())
{
char buf[20];
- xsnprintf (buf, sizeof (buf), "__%d", field_number);
- if (strcmp (buf, type->field (i).name ()) != 0)
+ xsnprintf (buf, sizeof (buf), "%d", field_number);
+
+ const char *field_name = type->field (i).name ();
+ if (startswith (field_name, "__"))
+ field_name += 2;
+ if (strcmp (buf, field_name) != 0)
return false;
field_number++;
}
@@ -178,8 +181,6 @@ rust_slice_type_p (const struct type *type)
static bool
rust_range_type_p (struct type *type)
{
- int i;
-
if (type->code () != TYPE_CODE_STRUCT
|| type->num_fields () > 2
|| type->name () == NULL
@@ -189,12 +190,12 @@ rust_range_type_p (struct type *type)
if (type->num_fields () == 0)
return true;
- i = 0;
+ int field_num = 0;
if (strcmp (type->field (0).name (), "start") == 0)
{
if (type->num_fields () == 1)
return true;
- i = 1;
+ field_num = 1;
}
else if (type->num_fields () == 2)
{
@@ -202,7 +203,7 @@ rust_range_type_p (struct type *type)
return false;
}
- return strcmp (type->field (i).name (), "end") == 0;
+ return strcmp (type->field (field_num).name (), "end") == 0;
}
/* Return true if TYPE is an inclusive range type, otherwise false.
@@ -497,7 +498,6 @@ rust_language::val_print_struct
(struct value *val, struct ui_file *stream, int recurse,
const struct value_print_options *options) const
{
- int i;
int first_field;
struct type *type = check_typedef (val->type ());
@@ -532,7 +532,7 @@ rust_language::val_print_struct
opts.deref_ref = false;
first_field = 1;
- for (i = 0; i < type->num_fields (); ++i)
+ for (int i = 0; i < type->num_fields (); ++i)
{
if (type->field (i).is_static ())
continue;
@@ -1142,13 +1142,22 @@ rust_slice_type (const char *name, struct type *elt_type,
-/* A helper for rust_evaluate_subexp that handles OP_RANGE. */
+namespace expr
+{
struct value *
-rust_range (struct type *expect_type, struct expression *exp,
- enum noside noside, enum range_flag kind,
- struct value *low, struct value *high)
+rust_range_operation::evaluate (struct type *expect_type,
+ struct expression *exp,
+ enum noside noside)
{
+ auto kind = std::get<0> (m_storage);
+ value *low = nullptr;
+ if (std::get<1> (m_storage) != nullptr)
+ low = std::get<1> (m_storage)->evaluate (nullptr, exp, noside);
+ value *high = nullptr;
+ if (std::get<2> (m_storage) != nullptr)
+ high = std::get<2> (m_storage)->evaluate (nullptr, exp, noside);
+
struct value *addrval, *result;
CORE_ADDR addr;
struct type *range_type;
@@ -1225,6 +1234,8 @@ rust_range (struct type *expect_type, struct expression *exp,
return result;
}
+} /* namespace expr */
+
/* A helper function to compute the range and kind given a range
value. TYPE is the type of the range value. RANGE is the range
value. LOW, HIGH, and KIND are out parameters. The LOW and HIGH
@@ -1266,20 +1277,23 @@ rust_compute_range (struct type *type, struct value *range,
}
}
-/* A helper for rust_evaluate_subexp that handles BINOP_SUBSCRIPT. */
+namespace expr
+{
struct value *
-rust_subscript (struct type *expect_type, struct expression *exp,
- enum noside noside, bool for_addr,
- struct value *lhs, struct value *rhs)
+rust_subscript_operation::subscript (struct expression *exp,
+ enum noside noside, bool for_addr)
{
+ value *lhs = std::get<0> (m_storage)->evaluate (nullptr, exp, noside);
+ value *rhs = std::get<1> (m_storage)->evaluate (nullptr, exp, noside);
+
struct value *result;
struct type *rhstype;
LONGEST low, high_bound;
/* Initialized to appease the compiler. */
range_flags kind = RANGE_LOW_BOUND_DEFAULT | RANGE_HIGH_BOUND_DEFAULT;
LONGEST high = 0;
- int want_slice = 0;
+ bool want_slice = false;
rhstype = check_typedef (rhs->type ());
if (rust_range_type_p (rhstype))
@@ -1287,7 +1301,7 @@ rust_subscript (struct type *expect_type, struct expression *exp,
if (!for_addr)
error (_("Can't take slice of array without '&'"));
rust_compute_range (rhstype, rhs, &low, &high, &kind);
- want_slice = 1;
+ want_slice = true;
}
else
low = value_as_long (rhs);
@@ -1413,9 +1427,6 @@ rust_subscript (struct type *expect_type, struct expression *exp,
return result;
}
-namespace expr
-{
-
struct value *
rust_unop_ind_operation::evaluate (struct type *expect_type,
struct expression *exp,
@@ -1460,7 +1471,7 @@ eval_op_rust_array (struct type *expect_type, struct expression *exp,
if (copies < 0)
error (_("Array with negative number of elements"));
- if (noside == EVAL_NORMAL)
+ if (noside == EVAL_NORMAL && copies > 0)
return value_array (0, std::vector<value *> (copies, elt));
else
{
@@ -1481,7 +1492,7 @@ rust_struct_anon::evaluate (struct type *expect_type,
value *lhs = std::get<1> (m_storage)->evaluate (nullptr, exp, noside);
int field_number = std::get<0> (m_storage);
- struct type *type = lhs->type ();
+ struct type *type = check_typedef (lhs->type ());
if (type->code () == TYPE_CODE_STRUCT)
{