summaryrefslogtreecommitdiff
path: root/gdb/gdbtypes.h
diff options
context:
space:
mode:
authorAndrew Burgess <andrew.burgess@embecosm.com>2019-10-24 11:12:11 +0100
committerAndrew Burgess <andrew.burgess@embecosm.com>2019-12-01 22:31:30 +0000
commit5bbd8269fa8d138e8ea1dd3c8cdf42412c1dfa41 (patch)
tree424045e6cff4208f62566e5ab727aafe23cfca7c /gdb/gdbtypes.h
parent82e3b5645f9c4edc1d84e57c32665d0e76bbbd77 (diff)
downloadbinutils-gdb-5bbd8269fa8d138e8ea1dd3c8cdf42412c1dfa41.tar.gz
gdb/fortran: array stride support
Currently GDB supports a byte or bit stride on arrays, in DWARF this would be DW_AT_bit_stride or DW_AT_byte_stride on DW_TAG_array_type. However, DWARF can also support DW_AT_byte_stride or DW_AT_bit_stride on DW_TAG_subrange_type, the tag used to describe each dimension of an array. Strides on subranges are used by gFortran to represent Fortran arrays, and this commit adds support for this to GDB. I've extended the range_bounds struct to include the stride information. The name is possibly a little inaccurate now, but this still sort of makes sense, the structure represents information about the bounds of the range, and also how to move from the lower to the upper bound (the stride). I've added initial support for bit strides, but I've never actually seen an example of this being generated. Further, I don't really see right now how GDB would currently handle a bit stride that was not a multiple of the byte size as the code in, for example, valarith.c:value_subscripted_rvalue seems geared around byte addressing. As a consequence if we see a bit stride that is not a multiple of 8 then GDB will give an error. gdb/ChangeLog: * dwarf2read.c (read_subrange_type): Read bit and byte stride and create a range with stride where appropriate. * f-valprint.c: Include 'gdbarch.h'. (f77_print_array_1): Take the stride into account when walking the array. Also convert the stride into addressable units. * gdbtypes.c (create_range_type): Initialise the stride to constant zero. (create_range_type_with_stride): New function, initialise the range as normal, and then setup the stride. (has_static_range): Include the stride here. Also change the return type to bool. (create_array_type_with_stride): Consider the range stride if the array isn't given its own stride. (resolve_dynamic_range): Resolve the stride if needed. * gdbtypes.h (struct range_bounds) <stride>: New member variable. (struct range_bounds) <flag_is_byte_stride>: New member variable. (TYPE_BIT_STRIDE): Define. (TYPE_ARRAY_BIT_STRIDE): Define. (create_range_type_with_stride): Declare. * valarith.c (value_subscripted_rvalue): Take range stride into account when walking the array. gdb/testsuite/ChangeLog: * gdb.fortran/derived-type-striding.exp: New file. * gdb.fortran/derived-type-striding.f90: New file. * gdb.fortran/array-slices.exp: New file. * gdb.fortran/array-slices.f90: New file. Change-Id: I9af2bcd1f2d4c56f76f5f3f9f89d8f06bef10d9a
Diffstat (limited to 'gdb/gdbtypes.h')
-rw-r--r--gdb/gdbtypes.h27
1 files changed, 27 insertions, 0 deletions
diff --git a/gdb/gdbtypes.h b/gdb/gdbtypes.h
index 2e128aae063..963314dcc81 100644
--- a/gdb/gdbtypes.h
+++ b/gdb/gdbtypes.h
@@ -623,6 +623,13 @@ struct range_bounds
struct dynamic_prop high;
+ /* The stride value for this range. This can be stored in bits or bytes
+ based on the value of BYTE_STRIDE_P. It is optional to have a stride
+ value, if this range has no stride value defined then this will be set
+ to the constant zero. */
+
+ struct dynamic_prop stride;
+
/* * The bias. Sometimes a range value is biased before storage.
The bias is added to the stored bits to form the true value. */
@@ -637,6 +644,10 @@ struct range_bounds
a dynamic one. */
unsigned int flag_bound_evaluated : 1;
+
+ /* If this is true this STRIDE is in bytes, otherwise STRIDE is in bits. */
+
+ unsigned int flag_is_byte_stride : 1;
};
/* Compare two range_bounds objects for equality. Simply does
@@ -1352,6 +1363,9 @@ extern bool set_type_align (struct type *, ULONGEST);
TYPE_RANGE_DATA(range_type)->high.kind
#define TYPE_LOW_BOUND_KIND(range_type) \
TYPE_RANGE_DATA(range_type)->low.kind
+#define TYPE_BIT_STRIDE(range_type) \
+ (TYPE_RANGE_DATA(range_type)->stride.data.const_val \
+ * (TYPE_RANGE_DATA(range_type)->flag_is_byte_stride ? 8 : 1))
/* Property accessors for the type data location. */
#define TYPE_DATA_LOCATION(thistype) \
@@ -1394,6 +1408,9 @@ extern bool set_type_align (struct type *, ULONGEST);
#define TYPE_ARRAY_LOWER_BOUND_VALUE(arraytype) \
(TYPE_LOW_BOUND(TYPE_INDEX_TYPE((arraytype))))
+#define TYPE_ARRAY_BIT_STRIDE(arraytype) \
+ (TYPE_BIT_STRIDE(TYPE_INDEX_TYPE((arraytype))))
+
/* C++ */
#define TYPE_SELF_TYPE(thistype) internal_type_self_type (thistype)
@@ -1966,6 +1983,16 @@ extern struct type *create_range_type (struct type *, struct type *,
const struct dynamic_prop *,
LONGEST);
+/* Like CREATE_RANGE_TYPE but also sets up a stride. When BYTE_STRIDE_P
+ is true the value in STRIDE is a byte stride, otherwise STRIDE is a bit
+ stride. */
+
+extern struct type * create_range_type_with_stride
+ (struct type *result_type, struct type *index_type,
+ const struct dynamic_prop *low_bound,
+ const struct dynamic_prop *high_bound, LONGEST bias,
+ const struct dynamic_prop *stride, bool byte_stride_p);
+
extern struct type *create_array_type (struct type *, struct type *,
struct type *);