From c451ebe5dd0c38617c74e0b6f0d5ef3188c25d56 Mon Sep 17 00:00:00 2001 From: Sanimir Agovic Date: Tue, 19 Nov 2013 12:54:24 +0000 Subject: [PATCH] vla: support for DW_AT_count This patch adds support for DW_AT_count as requested in the code review: https://sourceware.org/ml/gdb-patches/2013-11/msg00200.html gdb/ChangeLog: * dwarf2read.c (read_subrange_type): Convert DW_AT_count to a dynamic property and store it as the high bound and flag the range accordingly. * gdbtypes.c (resolve_dynamic_bounds): If range is flagged as RANGE_UPPER_BOUND_IS_COUNT assign low + high - 1 as the new high bound. * gdbtypes.h (enum range_flags): New enum. (struct range_bounds): Add flags member. --- gdb/ChangeLog | 9 +++++++++ gdb/dwarf2read.c | 18 ++++++++++-------- gdb/gdbtypes.c | 4 ++++ gdb/gdbtypes.h | 5 +++++ 4 files changed, 28 insertions(+), 8 deletions(-) diff --git a/gdb/ChangeLog b/gdb/ChangeLog index 0630f1c..717c197 100644 --- a/gdb/ChangeLog +++ b/gdb/ChangeLog @@ -1,5 +1,14 @@ 2014-04-14 Sanimir Agovic + * dwarf2read.c (read_subrange_type): Convert DW_AT_count to a dynamic + property and store it as the high bound and flag the range accordingly. + * gdbtypes.c (resolve_dynamic_bounds): If range is flagged as + RANGE_UPPER_BOUND_IS_COUNT assign low + high - 1 as the new high bound. + * gdbtypes.h (enum range_flags): New enum. + (struct range_bounds): Add flags member. + +2014-04-14 Sanimir Agovic + * c-typeprint.c (c_type_print_varspec_suffix): Added check for not yet resolved high bound. If unresolved, print "variable length" string to the console instead of random diff --git a/gdb/dwarf2read.c b/gdb/dwarf2read.c index ff66cce..7c64491 100644 --- a/gdb/dwarf2read.c +++ b/gdb/dwarf2read.c @@ -14493,6 +14493,7 @@ read_subrange_type (struct die_info *die, struct dwarf2_cu *cu) struct attribute *attr; struct dynamic_prop low, high; int low_default_is_valid; + int high_bound_is_count = 0; const char *name; LONGEST negative_mask; @@ -14559,15 +14560,13 @@ read_subrange_type (struct die_info *die, struct dwarf2_cu *cu) if (!attr_to_dynamic_prop (attr, die, cu, &high)) { attr = dwarf2_attr (die, DW_AT_count, cu); - if (attr) - { - int count = dwarf2_get_attr_constant_value (attr, 1); - high.data.const_val = low.data.const_val + count - 1; - } - else + if (attr_to_dynamic_prop (attr, die, cu, &high)) { - /* Unspecified array length. */ - high.data.const_val = low.data.const_val - 1; + /* If bounds are constant do the final calculation here. */ + if (low.kind == PROP_CONST && high.kind == PROP_CONST) + high.data.const_val = low.data.const_val + high.data.const_val - 1; + else + high_bound_is_count = 1; } } @@ -14627,6 +14626,9 @@ read_subrange_type (struct die_info *die, struct dwarf2_cu *cu) range_type = create_range_type (NULL, orig_base_type, &low, &high); + if (high_bound_is_count) + TYPE_RANGE_DATA (range_type)->flag_upper_bound_is_count = 1; + /* Ada expects an empty array on no boundary attributes. */ if (attr == NULL && cu->language != language_ada) TYPE_HIGH_BOUND_KIND (range_type) = PROP_UNDEFINED; diff --git a/gdb/gdbtypes.c b/gdb/gdbtypes.c index d510ee6..57101e1 100644 --- a/gdb/gdbtypes.c +++ b/gdb/gdbtypes.c @@ -1698,6 +1698,10 @@ resolve_dynamic_bounds (struct type *type, CORE_ADDR addr) { high_bound.kind = PROP_CONST; high_bound.data.const_val = value; + + if (TYPE_RANGE_DATA (range_type)->flag_upper_bound_is_count) + high_bound.data.const_val + = low_bound.data.const_val + high_bound.data.const_val - 1; } else { diff --git a/gdb/gdbtypes.h b/gdb/gdbtypes.h index 97411d1..6c3bb33 100644 --- a/gdb/gdbtypes.h +++ b/gdb/gdbtypes.h @@ -663,6 +663,11 @@ struct main_type /* * High bound of range. */ struct dynamic_prop high; + + /* True if HIGH range bound contains the number of elements in the + subrange. This affects how the final hight bound is computed. */ + + int flag_upper_bound_is_count : 1; } *bounds; } flds_bnds; -- 2.7.4