From 84914f598e5d48b78243b7e523804a28a4baf1eb Mon Sep 17 00:00:00 2001 From: Tom Tromey Date: Mon, 7 Aug 2023 06:35:51 -0600 Subject: [PATCH] Introduce type::is_array_like and value_to_array This adds the type::is_array_like method and the value_to_array function. The former can be used to see whether a given type is known to be "array-like". This is the currently the case for certain compiler-generated structure types; in particular both the Ada and Rust compilers do this. --- gdb/gdbtypes.c | 16 ++++++++++++++++ gdb/gdbtypes.h | 5 +++++ gdb/valarith.c | 21 +++++++++++++++++++++ gdb/value.h | 4 ++++ 4 files changed, 46 insertions(+) diff --git a/gdb/gdbtypes.c b/gdb/gdbtypes.c index 6b2adc8fe8c..c9322108299 100644 --- a/gdb/gdbtypes.c +++ b/gdb/gdbtypes.c @@ -43,6 +43,8 @@ #include "f-lang.h" #include #include "gmp-utils.h" +#include "rust-lang.h" +#include "ada-lang.h" /* The value of an invalid conversion badness. */ #define INVALID_CONVERSION 100 @@ -5945,6 +5947,20 @@ type::copy_fields (std::vector &src) size_t size = nfields * sizeof (*this->fields ()); memcpy (this->fields (), src.data (), size); } + +bool +type::is_array_like () +{ + if (code () == TYPE_CODE_ARRAY) + return true; + if (HAVE_GNAT_AUX_INFO (this)) + return (ada_is_constrained_packed_array_type (this) + || ada_is_array_descriptor_type (this)); + if (HAVE_RUST_SPECIFIC (this)) + return rust_slice_type_p (this); + return false; +} + static const registry::key gdbtypes_data; diff --git a/gdb/gdbtypes.h b/gdb/gdbtypes.h index 4668fba59c7..f667b10ec7d 100644 --- a/gdb/gdbtypes.h +++ b/gdb/gdbtypes.h @@ -1430,6 +1430,11 @@ struct type return this->code () == TYPE_CODE_PTR || TYPE_IS_REFERENCE (this); } + /* Return true if this type is "array-like". This includes arrays, + but also some forms of structure type that are recognized as + representations of arrays by the type's language. */ + bool is_array_like (); + /* * Type that is a pointer to this type. NULL if no such pointer-to type is known yet. The debugger may add the address of such a type diff --git a/gdb/valarith.c b/gdb/valarith.c index 637047fd853..ef376f05936 100644 --- a/gdb/valarith.c +++ b/gdb/valarith.c @@ -28,6 +28,8 @@ #include "infcall.h" #include "gdbsupport/byte-vector.h" #include "gdbarch.h" +#include "rust-lang.h" +#include "ada-lang.h" /* Forward declarations. */ static struct value *value_subscripted_rvalue (struct value *array, @@ -249,6 +251,25 @@ value_subscripted_rvalue (struct value *array, LONGEST index, return value_from_component (array, elt_type, elt_offs); } +/* See value.h. */ + +struct value * +value_to_array (struct value *val) +{ + struct type *type = check_typedef (val->type ()); + if (type->code () == TYPE_CODE_ARRAY) + return val; + + if (type->is_array_like ()) + { + if (HAVE_GNAT_AUX_INFO (type)) + return ada_coerce_to_simple_array (val); + if (HAVE_RUST_SPECIFIC (type)) + return rust_slice_to_array (val); + } + return nullptr; +} + /* Check to see if either argument is a structure, or a reference to one. This is called so we know whether to go ahead with the normal diff --git a/gdb/value.h b/gdb/value.h index c28b731cc42..1d5a0018f92 100644 --- a/gdb/value.h +++ b/gdb/value.h @@ -1319,6 +1319,10 @@ extern struct value *value_repeat (struct value *arg1, int count); extern struct value *value_subscript (struct value *array, LONGEST index); +/* Assuming VAL is array-like (see type::is_array_like), return an + array form of VAL. */ +extern struct value *value_to_array (struct value *val); + extern struct value *value_bitstring_subscript (struct type *type, struct value *bitstring, LONGEST index); -- 2.30.2