273 lines
10 KiB
Diff
273 lines
10 KiB
Diff
|
Subject: [PATCH 11/23] vla: add stride support to fortran arrays.
|
||
|
Message-Id: <1401861266-6240-12-git-send-email-keven.boell@intel.com>
|
||
|
|
||
|
2014-05-28 Sanimir Agovic <sanimir.agovic@intel.com>
|
||
|
Keven Boell <keven.boell@intel.com>
|
||
|
|
||
|
* dwarf2read.c (read_subrange_type): Read dynamic
|
||
|
stride attributes.
|
||
|
* gdbtypes.c (create_array_type_with_stride): Add
|
||
|
stride support
|
||
|
(create_range_type): Add stride parameter.
|
||
|
(create_static_range_type): Pass default stride
|
||
|
parameter.
|
||
|
(resolve_dynamic_range): Evaluate stride baton.
|
||
|
(resolve_dynamic_type): Adjust data location with
|
||
|
the value of byte stride.
|
||
|
* gdbtypes.h (TYPE_BYTE_STRIDE): New macro.
|
||
|
(TYPE_BYTE_STRIDE_BLOCK): New macro.
|
||
|
(TYPE_BYTE_STRIDE_LOCLIST): New macro.
|
||
|
(TYPE_BYTE_STRIDE_KIND): New macro.
|
||
|
* valarith.c (value_subscripted_rvalue): Use stride.
|
||
|
|
||
|
Change-Id: I3d810c0dc37f9d9fd84dba4c764cdefc52d8501e
|
||
|
|
||
|
Signed-off-by: Keven Boell <keven.boell@intel.com>
|
||
|
---
|
||
|
gdb/dwarf2read.c | 13 +++++++++++--
|
||
|
gdb/gdbtypes.c | 40 ++++++++++++++++++++++++++++++++++------
|
||
|
gdb/gdbtypes.h | 17 +++++++++++++++++
|
||
|
gdb/valarith.c | 14 +++++++++++++-
|
||
|
4 files changed, 75 insertions(+), 9 deletions(-)
|
||
|
|
||
|
Index: gdb-7.7.90.20140613/gdb/dwarf2read.c
|
||
|
===================================================================
|
||
|
--- gdb-7.7.90.20140613.orig/gdb/dwarf2read.c 2014-06-16 23:24:12.741584315 +0200
|
||
|
+++ gdb-7.7.90.20140613/gdb/dwarf2read.c 2014-06-16 23:25:12.702640910 +0200
|
||
|
@@ -14696,7 +14696,7 @@ read_subrange_type (struct die_info *die
|
||
|
struct type *base_type, *orig_base_type;
|
||
|
struct type *range_type;
|
||
|
struct attribute *attr;
|
||
|
- struct dynamic_prop low, high;
|
||
|
+ struct dynamic_prop low, high, stride;
|
||
|
int low_default_is_valid;
|
||
|
int high_bound_is_count = 0;
|
||
|
const char *name;
|
||
|
@@ -14716,7 +14716,9 @@ read_subrange_type (struct die_info *die
|
||
|
|
||
|
low.kind = PROP_CONST;
|
||
|
high.kind = PROP_CONST;
|
||
|
+ stride.kind = PROP_CONST;
|
||
|
high.data.const_val = 0;
|
||
|
+ stride.data.const_val = 0;
|
||
|
|
||
|
/* Set LOW_DEFAULT_IS_VALID if current language and DWARF version allow
|
||
|
omitting DW_AT_lower_bound. */
|
||
|
@@ -14749,6 +14751,13 @@ read_subrange_type (struct die_info *die
|
||
|
break;
|
||
|
}
|
||
|
|
||
|
+ attr = dwarf2_attr (die, DW_AT_byte_stride, cu);
|
||
|
+ if (attr)
|
||
|
+ if (!attr_to_dynamic_prop (attr, die, cu, &stride, NULL, 0))
|
||
|
+ complaint (&symfile_complaints, _("Missing DW_AT_byte_stride "
|
||
|
+ "- DIE at 0x%x [in module %s]"),
|
||
|
+ die->offset.sect_off, objfile_name (cu->objfile));
|
||
|
+
|
||
|
attr = dwarf2_attr (die, DW_AT_lower_bound, cu);
|
||
|
if (attr)
|
||
|
attr_to_dynamic_prop (attr, die, cu, &low, NULL, 0);
|
||
|
@@ -14825,7 +14834,7 @@ read_subrange_type (struct die_info *die
|
||
|
&& !TYPE_UNSIGNED (base_type) && (high.data.const_val & negative_mask))
|
||
|
high.data.const_val |= negative_mask;
|
||
|
|
||
|
- range_type = create_range_type (NULL, orig_base_type, &low, &high);
|
||
|
+ range_type = create_range_type (NULL, orig_base_type, &low, &high, &stride);
|
||
|
|
||
|
if (high_bound_is_count)
|
||
|
TYPE_RANGE_DATA (range_type)->flag_upper_bound_is_count = 1;
|
||
|
Index: gdb-7.7.90.20140613/gdb/gdbtypes.c
|
||
|
===================================================================
|
||
|
--- gdb-7.7.90.20140613.orig/gdb/gdbtypes.c 2014-06-16 23:24:12.741584315 +0200
|
||
|
+++ gdb-7.7.90.20140613/gdb/gdbtypes.c 2014-06-16 23:25:12.704640911 +0200
|
||
|
@@ -805,7 +805,8 @@ allocate_stub_method (struct type *type)
|
||
|
struct type *
|
||
|
create_range_type (struct type *result_type, struct type *index_type,
|
||
|
const struct dynamic_prop *low_bound,
|
||
|
- const struct dynamic_prop *high_bound)
|
||
|
+ const struct dynamic_prop *high_bound,
|
||
|
+ const struct dynamic_prop *stride)
|
||
|
{
|
||
|
if (result_type == NULL)
|
||
|
result_type = alloc_type_copy (index_type);
|
||
|
@@ -820,6 +821,7 @@ create_range_type (struct type *result_t
|
||
|
TYPE_ZALLOC (result_type, sizeof (struct range_bounds));
|
||
|
TYPE_RANGE_DATA (result_type)->low = *low_bound;
|
||
|
TYPE_RANGE_DATA (result_type)->high = *high_bound;
|
||
|
+ TYPE_RANGE_DATA (result_type)->stride = *stride;
|
||
|
|
||
|
if (low_bound->kind == PROP_CONST && low_bound->data.const_val >= 0)
|
||
|
TYPE_UNSIGNED (result_type) = 1;
|
||
|
@@ -841,7 +843,7 @@ struct type *
|
||
|
create_static_range_type (struct type *result_type, struct type *index_type,
|
||
|
LONGEST low_bound, LONGEST high_bound)
|
||
|
{
|
||
|
- struct dynamic_prop low, high;
|
||
|
+ struct dynamic_prop low, high, stride;
|
||
|
|
||
|
low.kind = PROP_CONST;
|
||
|
low.data.const_val = low_bound;
|
||
|
@@ -849,7 +851,11 @@ create_static_range_type (struct type *r
|
||
|
high.kind = PROP_CONST;
|
||
|
high.data.const_val = high_bound;
|
||
|
|
||
|
- result_type = create_range_type (result_type, index_type, &low, &high);
|
||
|
+ stride.kind = PROP_CONST;
|
||
|
+ stride.data.const_val = 0;
|
||
|
+
|
||
|
+ result_type = create_range_type (result_type, index_type,
|
||
|
+ &low, &high, &stride);
|
||
|
|
||
|
return result_type;
|
||
|
}
|
||
|
@@ -1006,16 +1012,21 @@ create_array_type_with_stride (struct ty
|
||
|
if (has_static_range (TYPE_RANGE_DATA (range_type))
|
||
|
&& dwarf2_address_data_valid (result_type))
|
||
|
{
|
||
|
- LONGEST low_bound, high_bound;
|
||
|
+ LONGEST low_bound, high_bound, byte_stride;
|
||
|
|
||
|
if (get_discrete_bounds (range_type, &low_bound, &high_bound) < 0)
|
||
|
low_bound = high_bound = 0;
|
||
|
CHECK_TYPEDEF (element_type);
|
||
|
+
|
||
|
+ byte_stride = abs (TYPE_BYTE_STRIDE (range_type));
|
||
|
+
|
||
|
/* Be careful when setting the array length. Ada arrays can be
|
||
|
empty arrays with the high_bound being smaller than the low_bound.
|
||
|
In such cases, the array length should be zero. */
|
||
|
if (high_bound < low_bound)
|
||
|
TYPE_LENGTH (result_type) = 0;
|
||
|
+ else if (byte_stride > 0)
|
||
|
+ TYPE_LENGTH (result_type) = byte_stride * (high_bound - low_bound + 1);
|
||
|
else if (bit_stride > 0)
|
||
|
TYPE_LENGTH (result_type) =
|
||
|
(bit_stride * (high_bound - low_bound + 1) + 7) / 8;
|
||
|
@@ -1697,7 +1708,7 @@ resolve_dynamic_range (struct type *dyn_
|
||
|
struct type *static_range_type;
|
||
|
const struct dynamic_prop *prop;
|
||
|
const struct dwarf2_locexpr_baton *baton;
|
||
|
- struct dynamic_prop low_bound, high_bound;
|
||
|
+ struct dynamic_prop low_bound, high_bound, stride;
|
||
|
struct type *range_copy = copy_type (dyn_range_type);
|
||
|
|
||
|
gdb_assert (TYPE_CODE (dyn_range_type) == TYPE_CODE_RANGE);
|
||
|
@@ -1729,10 +1740,17 @@ resolve_dynamic_range (struct type *dyn_
|
||
|
high_bound.kind = PROP_UNDEFINED;
|
||
|
high_bound.data.const_val = 0;
|
||
|
}
|
||
|
+
|
||
|
+ prop = &TYPE_RANGE_DATA (dyn_range_type)->stride;
|
||
|
+ if (dwarf2_evaluate_property (prop, addr, &value))
|
||
|
+ {
|
||
|
+ stride.kind = PROP_CONST;
|
||
|
+ stride.data.const_val = value;
|
||
|
+ }
|
||
|
|
||
|
static_range_type = create_range_type (range_copy,
|
||
|
TYPE_TARGET_TYPE (range_copy),
|
||
|
- &low_bound, &high_bound);
|
||
|
+ &low_bound, &high_bound, &stride);
|
||
|
TYPE_RANGE_DATA (static_range_type)->flag_bound_evaluated = 1;
|
||
|
return static_range_type;
|
||
|
}
|
||
|
@@ -1996,7 +2014,17 @@ resolve_dynamic_type (struct type *type,
|
||
|
prop = TYPE_DATA_LOCATION (type);
|
||
|
if (dwarf2_evaluate_property (prop, addr, &value))
|
||
|
{
|
||
|
+ struct type *range_type = TYPE_INDEX_TYPE (type);
|
||
|
+
|
||
|
+ /* Adjust the data location with the value of byte stride if set, which
|
||
|
+ can describe the separation between successive elements along the
|
||
|
+ dimension. */
|
||
|
+ if (TYPE_BYTE_STRIDE (range_type) < 0)
|
||
|
+ value += (TYPE_HIGH_BOUND (range_type) - TYPE_LOW_BOUND (range_type))
|
||
|
+ * TYPE_BYTE_STRIDE (range_type);
|
||
|
+
|
||
|
adjusted_address = value;
|
||
|
+
|
||
|
TYPE_DATA_LOCATION_ADDR (type) = value;
|
||
|
TYPE_DATA_LOCATION_KIND (type) = PROP_CONST;
|
||
|
}
|
||
|
Index: gdb-7.7.90.20140613/gdb/gdbtypes.h
|
||
|
===================================================================
|
||
|
--- gdb-7.7.90.20140613.orig/gdb/gdbtypes.h 2014-06-16 23:24:12.741584315 +0200
|
||
|
+++ gdb-7.7.90.20140613/gdb/gdbtypes.h 2014-06-16 23:25:12.704640911 +0200
|
||
|
@@ -670,6 +670,10 @@ struct main_type
|
||
|
|
||
|
struct dynamic_prop high;
|
||
|
|
||
|
+ /* * Stride of range. */
|
||
|
+
|
||
|
+ struct dynamic_prop stride;
|
||
|
+
|
||
|
/* True if HIGH range bound contains the number of elements in the
|
||
|
subrange. This affects how the final hight bound is computed. */
|
||
|
|
||
|
@@ -1219,6 +1223,15 @@ extern void allocate_gnat_aux_type (stru
|
||
|
TYPE_RANGE_DATA(range_type)->high.kind
|
||
|
#define TYPE_LOW_BOUND_KIND(range_type) \
|
||
|
TYPE_RANGE_DATA(range_type)->low.kind
|
||
|
+#define TYPE_BYTE_STRIDE(range_type) \
|
||
|
+ TYPE_RANGE_DATA(range_type)->stride.data.const_val
|
||
|
+#define TYPE_BYTE_STRIDE_BLOCK(range_type) \
|
||
|
+ TYPE_RANGE_DATA(range_type)->stride.data.locexpr
|
||
|
+#define TYPE_BYTE_STRIDE_LOCLIST(range_type) \
|
||
|
+ TYPE_RANGE_DATA(range_type)->stride.data.loclist
|
||
|
+#define TYPE_BYTE_STRIDE_KIND(range_type) \
|
||
|
+ TYPE_RANGE_DATA(range_type)->stride.kind
|
||
|
+
|
||
|
|
||
|
/* Attribute accessors for VLA support. */
|
||
|
#define TYPE_DATA_LOCATION(thistype) \
|
||
|
@@ -1250,6 +1263,9 @@ extern void allocate_gnat_aux_type (stru
|
||
|
TYPE_HIGH_BOUND_UNDEFINED(TYPE_INDEX_TYPE(arraytype))
|
||
|
#define TYPE_ARRAY_LOWER_BOUND_IS_UNDEFINED(arraytype) \
|
||
|
TYPE_LOW_BOUND_UNDEFINED(TYPE_INDEX_TYPE(arraytype))
|
||
|
+#define TYPE_ARRAY_STRIDE_IS_UNDEFINED(arraytype) \
|
||
|
+ (TYPE_BYTE_STRIDE(TYPE_INDEX_TYPE(arraytype)) == 0)
|
||
|
+
|
||
|
|
||
|
#define TYPE_ARRAY_UPPER_BOUND_VALUE(arraytype) \
|
||
|
(TYPE_HIGH_BOUND(TYPE_INDEX_TYPE((arraytype))))
|
||
|
@@ -1718,6 +1734,7 @@ extern struct type *create_array_type_wi
|
||
|
|
||
|
extern struct type *create_range_type (struct type *, struct type *,
|
||
|
const struct dynamic_prop *,
|
||
|
+ const struct dynamic_prop *,
|
||
|
const struct dynamic_prop *);
|
||
|
|
||
|
extern struct type *create_array_type (struct type *, struct type *,
|
||
|
Index: gdb-7.7.90.20140613/gdb/valarith.c
|
||
|
===================================================================
|
||
|
--- gdb-7.7.90.20140613.orig/gdb/valarith.c 2014-06-16 23:24:12.741584315 +0200
|
||
|
+++ gdb-7.7.90.20140613/gdb/valarith.c 2014-06-16 23:26:42.541725886 +0200
|
||
|
@@ -196,6 +196,7 @@ value_subscripted_rvalue (struct value *
|
||
|
struct type *elt_type = check_typedef (TYPE_TARGET_TYPE (array_type));
|
||
|
unsigned int elt_size = TYPE_LENGTH (elt_type);
|
||
|
unsigned int elt_offs;
|
||
|
+ LONGEST elt_stride = TYPE_BYTE_STRIDE (TYPE_INDEX_TYPE (array_type));
|
||
|
struct value *v;
|
||
|
|
||
|
if (TYPE_NOT_ASSOCIATED (array_type))
|
||
|
@@ -203,7 +204,18 @@ value_subscripted_rvalue (struct value *
|
||
|
if (TYPE_NOT_ALLOCATED (array_type))
|
||
|
error (_("no such vector element because not allocated"));
|
||
|
|
||
|
- elt_offs = elt_size * longest_to_int (index - lowerbound);
|
||
|
+ elt_offs = longest_to_int (index - lowerbound);
|
||
|
+
|
||
|
+ if (elt_stride > 0)
|
||
|
+ elt_offs *= elt_stride;
|
||
|
+ else if (elt_stride < 0)
|
||
|
+ {
|
||
|
+ int offs = (elt_offs + 1) * elt_stride;
|
||
|
+
|
||
|
+ elt_offs = TYPE_LENGTH (array_type) + offs;
|
||
|
+ }
|
||
|
+ else
|
||
|
+ elt_offs *= elt_size;
|
||
|
|
||
|
if (index < lowerbound || (!TYPE_ARRAY_UPPER_BOUND_IS_UNDEFINED (array_type)
|
||
|
&& elt_offs >= TYPE_LENGTH (array_type)))
|