* [PATCH] Allow dynamic DW_AT_bit_stride on DW_TAG_array_type
@ 2026-03-20 12:53 Tom Tromey
2026-04-03 19:56 ` Keith Seitz
0 siblings, 1 reply; 3+ messages in thread
From: Tom Tromey @ 2026-03-20 12:53 UTC (permalink / raw)
To: gdb-patches; +Cc: Tom Tromey
In Ada, it's possible to create an array where the stride is dynamic.
For example, this happens in array_of_symbolic_length.exp where GCC
emits:
<2><143a>: Abbrev Number: 12 (DW_TAG_array_type)
<143b> DW_AT_byte_stride : 7 byte block: fd 86 13 0 0 34 1e (DW_OP_GNU_variable_value: <0x1386>; DW_OP_lit4; DW_OP_mul)
<1443> DW_AT_type : <0x13c4>
<1447> DW_AT_sibling : <0x1455>
For gnat-llvm, though, it was more convenient to always emit a bit
stride. Using an expression for this is a DWARF extension, but it's a
fairly obvious one, and something similar is already used in gdb.
This patch adds support for dynamic bit strides on an array to gdb. A
new test case, derived from gdb.dwarf2/arr-stride.exp (the derivation
explains the copyright dates) is included.
---
gdb/ada-lang.c | 36 ++++++-
gdb/dwarf2/read.c | 44 +++++---
gdb/gdbtypes.c | 71 ++++++++-----
gdb/gdbtypes.h | 31 +++---
gdb/testsuite/gdb.dwarf2/arr-stride-dyn.exp | 109 ++++++++++++++++++++
5 files changed, 234 insertions(+), 57 deletions(-)
create mode 100644 gdb/testsuite/gdb.dwarf2/arr-stride-dyn.exp
diff --git a/gdb/ada-lang.c b/gdb/ada-lang.c
index 1d1c021a51a..e764db67f17 100644
--- a/gdb/ada-lang.c
+++ b/gdb/ada-lang.c
@@ -3142,10 +3142,24 @@ ada_value_slice_from_ptr (struct value *array_ptr, struct type *type,
type_allocator alloc (base_index_type);
struct type *index_type
= create_static_range_type (alloc, base_index_type, low, high);
+
+ dynamic_prop prop_storage;
+ dynamic_prop *prop = type0->dyn_prop (DYN_PROP_BYTE_STRIDE);
+ bool is_byte_stride = true;
+ if (prop == nullptr)
+ {
+ prop = type0->dyn_prop (DYN_PROP_BIT_STRIDE);
+ is_byte_stride = false;
+ if (prop == nullptr)
+ {
+ prop = &prop_storage;
+ prop->set_const_val (type0->field (0).bitsize ());
+ }
+ }
+
struct type *slice_type = create_array_type_with_stride
(alloc, type0->target_type (), index_type,
- type0->dyn_prop (DYN_PROP_BYTE_STRIDE),
- type0->field (0).bitsize ());
+ prop, is_byte_stride);
LONGEST base_low = ada_discrete_type_low_bound (type0->index_type ());
std::optional<LONGEST> base_low_pos, low_pos;
CORE_ADDR base;
@@ -3177,10 +3191,24 @@ ada_value_slice (struct value *array, LONGEST low, LONGEST high)
type_allocator alloc (type->index_type ());
struct type *index_type
= create_static_range_type (alloc, type->index_type (), low, high);
+
+ dynamic_prop prop_storage;
+ dynamic_prop *prop = type->dyn_prop (DYN_PROP_BYTE_STRIDE);
+ bool is_byte_stride = true;
+ if (prop == nullptr)
+ {
+ prop = type->dyn_prop (DYN_PROP_BIT_STRIDE);
+ is_byte_stride = false;
+ if (prop == nullptr)
+ {
+ prop = &prop_storage;
+ prop->set_const_val (type->field (0).bitsize ());
+ }
+ }
+
struct type *slice_type = create_array_type_with_stride
(alloc, type->target_type (), index_type,
- type->dyn_prop (DYN_PROP_BYTE_STRIDE),
- type->field (0).bitsize ());
+ prop, is_byte_stride);
std::optional<LONGEST> low_pos, high_pos;
diff --git a/gdb/dwarf2/read.c b/gdb/dwarf2/read.c
index 8b87d58dd9c..b216db137bc 100644
--- a/gdb/dwarf2/read.c
+++ b/gdb/dwarf2/read.c
@@ -11483,13 +11483,13 @@ read_array_type (struct die_info *die, struct dwarf2_cu *cu)
struct type *type;
struct type *element_type, *range_type, *index_type;
const char *name;
- unsigned int bit_stride = 0;
/* If the stride is seen and used, byte_stride_prop will be
non-NULL. In this case stride_storage will be used to store the
data locally. */
- dynamic_prop *byte_stride_prop = nullptr;
+ dynamic_prop *stride_prop = nullptr;
dynamic_prop stride_storage;
+ bool is_byte_stride = true;
element_type = die_type (die, cu);
@@ -11503,10 +11503,9 @@ read_array_type (struct die_info *die, struct dwarf2_cu *cu)
{
struct type *prop_type = cu->addr_sized_int_type (false);
- byte_stride_prop = &stride_storage;
- bool stride_ok
- = attr_to_dynamic_prop (attr, die, cu, byte_stride_prop, prop_type);
-
+ stride_prop = &stride_storage;
+ bool stride_ok = attr_to_dynamic_prop (attr, die, cu, stride_prop,
+ prop_type);
if (!stride_ok)
{
complaint (_("unable to read array DW_AT_byte_stride "
@@ -11516,13 +11515,30 @@ read_array_type (struct die_info *die, struct dwarf2_cu *cu)
/* Ignore this attribute. We will likely not be able to print
arrays of this type correctly, but there is little we can do
to help if we cannot read the attribute's value. */
- byte_stride_prop = NULL;
+ stride_prop = nullptr;
}
}
if (attribute *attr = dwarf2_attr (die, DW_AT_bit_stride, cu);
attr != nullptr)
- bit_stride = attr->unsigned_constant ().value_or (0);
+ {
+ if (stride_prop != nullptr)
+ complaint (_("Found DW_AT_bit_stride and DW_AT_byte_stride "
+ "- DIE at %s [in module %s]"),
+ sect_offset_str (die->sect_off),
+ objfile_name (cu->per_objfile->objfile));
+ else if (attr_to_dynamic_prop (attr, die, cu, &stride_storage,
+ cu->addr_sized_int_type (false)))
+ {
+ stride_prop = &stride_storage;
+ is_byte_stride = false;
+ }
+ else
+ complaint (_("unable to read array DW_AT_bit_stride "
+ " - DIE at %s [in module %s]"),
+ sect_offset_str (die->sect_off),
+ objfile_name (cu->per_objfile->objfile));
+ }
/* Irix 6.2 native cc creates array types without children for
arrays with unspecified length. */
@@ -11532,7 +11548,7 @@ read_array_type (struct die_info *die, struct dwarf2_cu *cu)
index_type = alloc.copy_type (builtin_type (objfile)->builtin_int);
range_type = create_static_range_type (alloc, index_type, 0, -1);
type = create_array_type_with_stride (alloc, element_type, range_type,
- byte_stride_prop, bit_stride);
+ stride_prop, is_byte_stride);
return set_die_type (die, type, cu);
}
@@ -11574,10 +11590,9 @@ read_array_type (struct die_info *die, struct dwarf2_cu *cu)
while (i < range_types.size ())
{
type = create_array_type_with_stride (alloc, type, range_types[i++],
- byte_stride_prop, bit_stride);
+ stride_prop, is_byte_stride);
type->set_is_multi_dimensional (true);
- bit_stride = 0;
- byte_stride_prop = nullptr;
+ stride_prop = nullptr;
}
}
else
@@ -11586,10 +11601,9 @@ read_array_type (struct die_info *die, struct dwarf2_cu *cu)
while (ndim-- > 0)
{
type = create_array_type_with_stride (alloc, type, range_types[ndim],
- byte_stride_prop, bit_stride);
+ stride_prop, is_byte_stride);
type->set_is_multi_dimensional (true);
- bit_stride = 0;
- byte_stride_prop = nullptr;
+ stride_prop = nullptr;
}
}
diff --git a/gdb/gdbtypes.c b/gdb/gdbtypes.c
index d880d707ee8..064f64d0388 100644
--- a/gdb/gdbtypes.c
+++ b/gdb/gdbtypes.c
@@ -1172,6 +1172,7 @@ update_static_array_size (struct type *type)
struct type *range_type = type->index_type ();
if (type->dyn_prop (DYN_PROP_BYTE_STRIDE) == nullptr
+ && type->dyn_prop (DYN_PROP_BIT_STRIDE) == nullptr
&& has_static_range (range_type->bounds ())
&& (!type_not_associated (type)
&& !type_not_allocated (type)))
@@ -1233,17 +1234,19 @@ struct type *
create_array_type_with_stride (type_allocator &alloc,
struct type *element_type,
struct type *range_type,
- struct dynamic_prop *byte_stride_prop,
- unsigned int bit_stride)
+ dynamic_prop *stride_prop,
+ bool is_byte_stride)
{
- if (byte_stride_prop != nullptr && byte_stride_prop->is_constant ())
+ unsigned bit_stride = 0;
+
+ if (stride_prop != nullptr && stride_prop->is_constant ())
{
- /* The byte stride is actually not dynamic. Pretend we were
- called with bit_stride set instead of byte_stride_prop.
- This will give us the same result type, while avoiding
- the need to handle this as a special case. */
- bit_stride = byte_stride_prop->const_val () * 8;
- byte_stride_prop = NULL;
+ /* The stride is actually not dynamic, so use the value
+ directly. */
+ bit_stride = stride_prop->const_val ();
+ if (is_byte_stride)
+ bit_stride *= 8;
+ stride_prop = nullptr;
}
struct type *result_type = alloc.new_type ();
@@ -1253,8 +1256,11 @@ create_array_type_with_stride (type_allocator &alloc,
result_type->alloc_fields (1);
result_type->set_index_type (range_type);
- if (byte_stride_prop != NULL)
- result_type->add_dyn_prop (DYN_PROP_BYTE_STRIDE, *byte_stride_prop);
+ if (stride_prop != nullptr)
+ result_type->add_dyn_prop (is_byte_stride
+ ? DYN_PROP_BYTE_STRIDE
+ : DYN_PROP_BIT_STRIDE,
+ *stride_prop);
else if (bit_stride > 0)
result_type->field (0).set_bitsize (bit_stride);
@@ -1284,7 +1290,7 @@ create_array_type (type_allocator &alloc,
struct type *range_type)
{
return create_array_type_with_stride (alloc, element_type,
- range_type, NULL, 0);
+ range_type, nullptr, false);
}
struct type *
@@ -1899,15 +1905,19 @@ stub_noname_complaint (void)
complaint (_("stub type has NULL name"));
}
-/* Return true if TYPE has a DYN_PROP_BYTE_STRIDE dynamic property
- attached to it, and that property has a non-constant value. */
+/* Return true if TYPE has a dynamic stride property attached to
+ it, and that property has a non-constant value. */
static bool
array_type_has_dynamic_stride (struct type *type)
{
- struct dynamic_prop *prop = type->dyn_prop (DYN_PROP_BYTE_STRIDE);
-
- return prop != nullptr && prop->is_constant ();
+ if (dynamic_prop *prop = type->dyn_prop (DYN_PROP_BYTE_STRIDE);
+ prop != nullptr && !prop->is_constant ())
+ return true;
+ if (dynamic_prop *prop = type->dyn_prop (DYN_PROP_BIT_STRIDE);
+ prop != nullptr && !prop->is_constant ())
+ return true;
+ return false;
}
/* Worker for is_dynamic_type. */
@@ -2236,15 +2246,22 @@ resolve_dynamic_array_or_string_1 (struct type *type,
else
elt_type = type->target_type ();
- prop = type->dyn_prop (DYN_PROP_BYTE_STRIDE);
- if (prop != nullptr && type->code () == TYPE_CODE_STRING)
- prop = nullptr;
- if (prop != NULL && resolve_p)
+ dynamic_prop_node_kind kind = DYN_PROP_BYTE_STRIDE;
+ prop = type->dyn_prop (kind);
+ if (prop == nullptr)
+ {
+ kind = DYN_PROP_BIT_STRIDE;
+ prop = type->dyn_prop (kind);
+ }
+
+ if (prop != nullptr && type->code () != TYPE_CODE_STRING && resolve_p)
{
if (dwarf2_evaluate_property (prop, frame, addr_stack, &value))
{
- type->remove_dyn_prop (DYN_PROP_BYTE_STRIDE);
- bit_stride = (unsigned int) (value * 8);
+ bit_stride = (unsigned int) value;
+ if (kind == DYN_PROP_BYTE_STRIDE)
+ bit_stride *= 8;
+ type->remove_dyn_prop (kind);
}
else
{
@@ -2262,8 +2279,12 @@ resolve_dynamic_array_or_string_1 (struct type *type,
if (type->code () == TYPE_CODE_STRING)
return create_string_type (alloc, elt_type, range_type);
else
- return create_array_type_with_stride (alloc, elt_type, range_type, NULL,
- bit_stride);
+ {
+ dynamic_prop temp_prop;
+ temp_prop.set_const_val (bit_stride);
+ return create_array_type_with_stride (alloc, elt_type, range_type,
+ &temp_prop, false);
+ }
}
/* Resolve an array or string type with dynamic properties, return a new
diff --git a/gdb/gdbtypes.h b/gdb/gdbtypes.h
index 139467cfd85..da9397eddf8 100644
--- a/gdb/gdbtypes.h
+++ b/gdb/gdbtypes.h
@@ -448,6 +448,11 @@ enum dynamic_prop_node_kind
/* A property providing an array's byte stride. */
DYN_PROP_BYTE_STRIDE,
+ /* A property providing an array's bit stride. Note that the bit-
+ and byte-stride are mutually exclusive; if both happen to be
+ provided somehow, the byte stride will take precedence. */
+ DYN_PROP_BIT_STRIDE,
+
/* A property holding variant parts. */
DYN_PROP_VARIANT_PARTS,
@@ -2518,21 +2523,21 @@ extern struct type *create_static_range_type (type_allocator &alloc,
Elements will be of type ELEMENT_TYPE, the indices will be of type
RANGE_TYPE.
- BYTE_STRIDE_PROP, when not NULL, provides the array's byte stride.
- This byte stride property is added to the resulting array type
- as a DYN_PROP_BYTE_STRIDE. As a consequence, the BYTE_STRIDE_PROP
- argument can only be used to create types that are objfile-owned
- (see add_dyn_prop), meaning that either this function must be called
- with an objfile-owned RESULT_TYPE, or an objfile-owned RANGE_TYPE.
+ STRIDE_PROP, when not NULL, provides the array's stride. If
+ IS_BYTE_STRIDE is true, then this is a byte stride; when false this
+ is a bit stride. This stride property is added to the resulting
+ array type as a DYN_PROP_BYTE_STRIDE or a DYN_PROP_BIT_SIZE, as
+ appropriate. As a consequence, the STRIDE_PROP argument can only
+ be used to create types that are objfile-owned (see add_dyn_prop),
+ meaning that either this function must be called with an
+ objfile-owned RESULT_TYPE, or an objfile-owned RANGE_TYPE.
- BIT_STRIDE is taken into account only when BYTE_STRIDE_PROP is NULL.
- If BIT_STRIDE is not zero, build a packed array type whose element
- size is BIT_STRIDE. Otherwise, ignore this parameter. */
+ IS_BYTE_STRIDE is ignored when STRIDE_PROP is NULL. */
extern struct type *create_array_type_with_stride
(type_allocator &alloc, struct type *element_type,
- struct type *range_type, struct dynamic_prop *byte_stride_prop,
- unsigned int bit_stride);
+ struct type *range_type, dynamic_prop *stride_prop,
+ bool is_byte_stride);
/* Create a range type using ALLOC with a dynamic range from LOW_BOUND
to HIGH_BOUND, inclusive. INDEX_TYPE is the underlying type. BIAS
@@ -2555,8 +2560,8 @@ extern struct type *create_range_type_with_stride
const struct dynamic_prop *high_bound, LONGEST bias,
const struct dynamic_prop *stride, bool byte_stride_p);
-/* Same as create_array_type_with_stride but with no bit_stride
- (BIT_STRIDE = 0), thus building an unpacked array. */
+/* Same as create_array_type_with_stride but with no stride, thus
+ building an unpacked array. */
extern struct type *create_array_type (type_allocator &alloc,
struct type *element_type,
diff --git a/gdb/testsuite/gdb.dwarf2/arr-stride-dyn.exp b/gdb/testsuite/gdb.dwarf2/arr-stride-dyn.exp
new file mode 100644
index 00000000000..56246180ef6
--- /dev/null
+++ b/gdb/testsuite/gdb.dwarf2/arr-stride-dyn.exp
@@ -0,0 +1,109 @@
+# Copyright 2014-2026 Free Software Foundation, Inc.
+
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
+load_lib dwarf.exp
+
+# This test can only be run on targets which support DWARF-2 and use gas.
+require dwarf2_support
+
+standard_testfile main.c -dw.S
+
+# Make some DWARF for the test.
+set asm_file [standard_output_file $srcfile2]
+Dwarf::assemble $asm_file {
+ cu {} {
+ DW_TAG_compile_unit {
+ DW_AT_language @DW_LANG_Ada95
+ DW_AT_name foo.adb
+ DW_AT_comp_dir /tmp
+ } {
+ declare_labels integer_label array_elt_label array_label \
+ struct_label
+
+ integer_label: DW_TAG_base_type {
+ DW_AT_byte_size 4 DW_FORM_sdata
+ DW_AT_encoding @DW_ATE_signed
+ DW_AT_name integer
+ }
+
+ array_elt_label: DW_TAG_subrange_type {
+ DW_AT_lower_bound 0x00 DW_FORM_data1
+ DW_AT_upper_bound 0x03 DW_FORM_data1
+ DW_AT_name pck__item
+ DW_AT_type :$integer_label
+ }
+
+ DW_TAG_typedef {
+ DW_AT_name pck__table
+ DW_AT_type :$array_label
+ }
+
+ array_label: DW_TAG_array_type {
+ DW_AT_name pck__table
+ DW_AT_bit_stride {
+ DW_OP_const1u 2
+ } SPECIAL_expr
+ DW_AT_type :$array_elt_label
+ DW_AT_byte_size 1 DW_FORM_sdata
+ } {
+ DW_TAG_subrange_type {
+ DW_AT_type :$integer_label
+ DW_AT_lower_bound 0 DW_FORM_data1
+ DW_AT_upper_bound 3 DW_FORM_data1
+ }
+ }
+
+ struct_label: DW_TAG_structure_type {
+ DW_AT_name struct_type
+ DW_AT_byte_size 16 DW_FORM_sdata
+ } {
+ member {
+ DW_AT_name intfield
+ DW_AT_type :$integer_label
+ DW_AT_data_member_location 0 DW_FORM_sdata
+ }
+ member {
+ DW_AT_name arrayfield
+ DW_AT_type :$array_label
+ DW_AT_data_member_location 4 DW_FORM_sdata
+ }
+ }
+
+ DW_TAG_variable {
+ DW_AT_name the_struct
+ DW_AT_external 1 DW_FORM_flag
+ DW_AT_location {
+ DW_OP_const1u 1
+ DW_OP_stack_value
+ DW_OP_piece 4
+ # This is (1, 1, 1, 1):
+ DW_OP_const1u 85
+ DW_OP_stack_value
+ DW_OP_piece 1
+ } SPECIAL_expr
+ DW_AT_type :$struct_label
+ }
+ }
+ }
+}
+
+if { [prepare_for_testing "failed to prepare" ${testfile} \
+ [list $srcfile $asm_file] {nodebug}] } {
+ return
+}
+
+gdb_test_no_output "set language ada"
+
+gdb_test "print the_struct" \
+ [quotemeta "(intfield => 1, arrayfield => (0 => 1, 1, 1, 1))"]
base-commit: e5425f2687d66034a8d3fe94264cf99b42c1cb1a
--
2.53.0
^ permalink raw reply [flat|nested] 3+ messages in thread
* Re: [PATCH] Allow dynamic DW_AT_bit_stride on DW_TAG_array_type
2026-03-20 12:53 [PATCH] Allow dynamic DW_AT_bit_stride on DW_TAG_array_type Tom Tromey
@ 2026-04-03 19:56 ` Keith Seitz
2026-04-06 16:36 ` Tom Tromey
0 siblings, 1 reply; 3+ messages in thread
From: Keith Seitz @ 2026-04-03 19:56 UTC (permalink / raw)
To: Tom Tromey, gdb-patches
Hi,
On 3/20/26 5:53 AM, Tom Tromey wrote:
> In Ada, it's possible to create an array where the stride is dynamic.
> For example, this happens in array_of_symbolic_length.exp where GCC
> emits:
>
> <2><143a>: Abbrev Number: 12 (DW_TAG_array_type)
> <143b> DW_AT_byte_stride : 7 byte block: fd 86 13 0 0 34 1e (DW_OP_GNU_variable_value: <0x1386>; DW_OP_lit4; DW_OP_mul)
> <1443> DW_AT_type : <0x13c4>
> <1447> DW_AT_sibling : <0x1455>
>
> For gnat-llvm, though, it was more convenient to always emit a bit
> stride. Using an expression for this is a DWARF extension, but it's a
> fairly obvious one, and something similar is already used in gdb.
>
> This patch adds support for dynamic bit strides on an array to gdb. A
> new test case, derived from gdb.dwarf2/arr-stride.exp (the derivation
> explains the copyright dates) is included.
I think this is relatively straightforward, and aside from a few
minor observations, LGTM.
Reviewed-By: Keith Seitz <keiths@redhat.com>
Keith
> diff --git a/gdb/ada-lang.c b/gdb/ada-lang.c
> index 1d1c021a51a..e764db67f17 100644
> --- a/gdb/ada-lang.c
> +++ b/gdb/ada-lang.c
> @@ -3142,10 +3142,24 @@ ada_value_slice_from_ptr (struct value *array_ptr, struct type *type,
> type_allocator alloc (base_index_type);
> struct type *index_type
> = create_static_range_type (alloc, base_index_type, low, high);
> +
> + dynamic_prop prop_storage;
> + dynamic_prop *prop = type0->dyn_prop (DYN_PROP_BYTE_STRIDE);
> + bool is_byte_stride = true;
> + if (prop == nullptr)
> + {
> + prop = type0->dyn_prop (DYN_PROP_BIT_STRIDE);
> + is_byte_stride = false;
> + if (prop == nullptr)
> + {
> + prop = &prop_storage;
> + prop->set_const_val (type0->field (0).bitsize ());
> + }
> + }
> +
I see the above code is duplicated below -- is it worth the bother to
separate into a function? Not an action item. Just a question.
> struct type *slice_type = create_array_type_with_stride
> (alloc, type0->target_type (), index_type,
> - type0->dyn_prop (DYN_PROP_BYTE_STRIDE),
> - type0->field (0).bitsize ());
> + prop, is_byte_stride);
> LONGEST base_low = ada_discrete_type_low_bound (type0->index_type ());
> std::optional<LONGEST> base_low_pos, low_pos;
> CORE_ADDR base;
> @@ -3177,10 +3191,24 @@ ada_value_slice (struct value *array, LONGEST low, LONGEST high)
> type_allocator alloc (type->index_type ());
> struct type *index_type
> = create_static_range_type (alloc, type->index_type (), low, high);
> +
> + dynamic_prop prop_storage;
> + dynamic_prop *prop = type->dyn_prop (DYN_PROP_BYTE_STRIDE);
> + bool is_byte_stride = true;
> + if (prop == nullptr)
> + {
> + prop = type->dyn_prop (DYN_PROP_BIT_STRIDE);
> + is_byte_stride = false;
> + if (prop == nullptr)
> + {
> + prop = &prop_storage;
> + prop->set_const_val (type->field (0).bitsize ());
> + }
> + }
> +
> struct type *slice_type = create_array_type_with_stride
> (alloc, type->target_type (), index_type,
> - type->dyn_prop (DYN_PROP_BYTE_STRIDE),
> - type->field (0).bitsize ());
> + prop, is_byte_stride);
> std::optional<LONGEST> low_pos, high_pos;
>
>
> diff --git a/gdb/dwarf2/read.c b/gdb/dwarf2/read.c
> index 8b87d58dd9c..b216db137bc 100644
> --- a/gdb/dwarf2/read.c
> +++ b/gdb/dwarf2/read.c
> @@ -11483,13 +11483,13 @@ read_array_type (struct die_info *die, struct dwarf2_cu *cu)
> struct type *type;
> struct type *element_type, *range_type, *index_type;
> const char *name;
> - unsigned int bit_stride = 0;
>
> /* If the stride is seen and used, byte_stride_prop will be
> non-NULL. In this case stride_storage will be used to store the
> data locally. */
I think the above comment should now refer to `stride_prop' instead of
`byte_stride_prop'.
> - dynamic_prop *byte_stride_prop = nullptr;
> + dynamic_prop *stride_prop = nullptr;
> dynamic_prop stride_storage;
> + bool is_byte_stride = true;
>
> element_type = die_type (die, cu);
>
> diff --git a/gdb/gdbtypes.h b/gdb/gdbtypes.h
> index 139467cfd85..da9397eddf8 100644
> --- a/gdb/gdbtypes.h
> +++ b/gdb/gdbtypes.h
> @@ -2518,21 +2523,21 @@ extern struct type *create_static_range_type (type_allocator &alloc,
> Elements will be of type ELEMENT_TYPE, the indices will be of type
> RANGE_TYPE.
>
> - BYTE_STRIDE_PROP, when not NULL, provides the array's byte stride.
> - This byte stride property is added to the resulting array type
> - as a DYN_PROP_BYTE_STRIDE. As a consequence, the BYTE_STRIDE_PROP
> - argument can only be used to create types that are objfile-owned
> - (see add_dyn_prop), meaning that either this function must be called
> - with an objfile-owned RESULT_TYPE, or an objfile-owned RANGE_TYPE.
> + STRIDE_PROP, when not NULL, provides the array's stride. If
> + IS_BYTE_STRIDE is true, then this is a byte stride; when false this
> + is a bit stride. This stride property is added to the resulting
> + array type as a DYN_PROP_BYTE_STRIDE or a DYN_PROP_BIT_SIZE, as
Should this refer to DYN_PROP_BIT_STRIDE?
> + appropriate. As a consequence, the STRIDE_PROP argument can only
> + be used to create types that are objfile-owned (see add_dyn_prop),
> + meaning that either this function must be called with an
> + objfile-owned RESULT_TYPE, or an objfile-owned RANGE_TYPE.
>
> - BIT_STRIDE is taken into account only when BYTE_STRIDE_PROP is NULL.
> - If BIT_STRIDE is not zero, build a packed array type whose element
> - size is BIT_STRIDE. Otherwise, ignore this parameter. */
> + IS_BYTE_STRIDE is ignored when STRIDE_PROP is NULL. */
>
> extern struct type *create_array_type_with_stride
> (type_allocator &alloc, struct type *element_type,
> - struct type *range_type, struct dynamic_prop *byte_stride_prop,
> - unsigned int bit_stride);
> + struct type *range_type, dynamic_prop *stride_prop,
> + bool is_byte_stride);
>
> /* Create a range type using ALLOC with a dynamic range from LOW_BOUND
> to HIGH_BOUND, inclusive. INDEX_TYPE is the underlying type. BIAS
^ permalink raw reply [flat|nested] 3+ messages in thread
* Re: [PATCH] Allow dynamic DW_AT_bit_stride on DW_TAG_array_type
2026-04-03 19:56 ` Keith Seitz
@ 2026-04-06 16:36 ` Tom Tromey
0 siblings, 0 replies; 3+ messages in thread
From: Tom Tromey @ 2026-04-06 16:36 UTC (permalink / raw)
To: Keith Seitz; +Cc: Tom Tromey, gdb-patches
>>>>> "Keith" == Keith Seitz <keiths@redhat.com> writes:
Keith> I think this is relatively straightforward, and aside from a few
Keith> minor observations, LGTM.
Thanks.
Keith> I see the above code is duplicated below -- is it worth the bother to
Keith> separate into a function? Not an action item. Just a question.
I think the two functions can probably be merged.
I'll take a look at that separately.
>> /* If the stride is seen and used, byte_stride_prop will be
>> non-NULL. In this case stride_storage will be used to store the
>> data locally. */
Keith> I think the above comment should now refer to `stride_prop' instead of
Keith> `byte_stride_prop'.
Yeah, fixed.
>> + IS_BYTE_STRIDE is true, then this is a byte stride; when false this
>> + is a bit stride. This stride property is added to the resulting
>> + array type as a DYN_PROP_BYTE_STRIDE or a DYN_PROP_BIT_SIZE, as
Keith> Should this refer to DYN_PROP_BIT_STRIDE?
Yes, thank you.
I'm going to check this in now.
Tom
^ permalink raw reply [flat|nested] 3+ messages in thread
end of thread, other threads:[~2026-04-06 16:36 UTC | newest]
Thread overview: 3+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2026-03-20 12:53 [PATCH] Allow dynamic DW_AT_bit_stride on DW_TAG_array_type Tom Tromey
2026-04-03 19:56 ` Keith Seitz
2026-04-06 16:36 ` Tom Tromey
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox