[PATCH] Handle DW_TAG_subrange_type

Andreas Schwab
2003-11-22T20:08:44Z

When trying to debug Ada code you often get a DW_TAG_subrange_type, which
gdb can't handle yet.

Andreas.

2003-11-22 Andreas Schwab <schwab@suse.de>

* dwarf2read.c (dwarf2_non_const_array_bound_ignored_complaint):
New function.
(read_subrange_type): New function.
(process_die): Handle DW_TAG_subrange_type.
(read_type_die): Likewise.

--- gdb/dwarf2read.c.~1.114.~ 2003-11-21 12:51:28.000000000 +0100
+++ gdb/dwarf2read.c 2003-11-22 16:52:42.000000000 +0100
@@ -610,6 +610,13 @@ dwarf2_non_const_array_bound_ignored_com
}

static void
+dwarf2_non_const_subrange_bound_ignored_complaint (const char *arg1)
+{
+ complaint (&symfile_complaints, "non-constant subrange bounds form '%s' ignored",
+ arg1);
+}
+
+static void
dwarf2_statement_list_fits_in_line_number_section_complaint (void)
{
complaint (&symfile_complaints,
@@ -844,6 +851,8 @@ static void read_tag_string_type (struct

static void read_subroutine_type (struct die_info *, struct dwarf2_cu *);

+static void read_subrange_type (struct die_info *, struct dwarf2_cu *);
+
static struct die_info *read_comp_unit (char *, bfd *, struct dwarf2_cu *);

static struct die_info *read_die_and_children (char *info_ptr, bfd *abfd,
@@ -1908,6 +1917,9 @@ process_die (struct die_info *die, struc
new_symbol (die, die->type, cu);
}
break;
+ case DW_TAG_subrange_type:
+ read_subrange_type (die, cu);
+ break;
case DW_TAG_common_block:
read_common_block (die, cu);
break;
@@ -3732,6 +3744,72 @@ read_base_type (struct die_info *die, st
die->type = type;
}

+static void
+read_subrange_type (struct die_info *die, struct dwarf2_cu *cu)
+{
+ struct type *element_type;
+ struct attribute *attr;
+ unsigned int low, high;
+
+ /* Return if we've already decoded this type. */
+ if (die->type)
+ {
+ return;
+ }
+
+ element_type = die_type (die, cu);
+ low = 0;
+ high = -1;
+ if (cu_language == language_fortran)
+ {
+ /* FORTRAN implies a lower bound of 1, if not given. */
+ low = 1;
+ }
+ attr = dwarf_attr (die, DW_AT_lower_bound);
+ if (attr)
+ {
+ if (attr->form == DW_FORM_sdata)
+ low = DW_SND (attr);
+ else if (attr->form == DW_FORM_udata
+ || attr->form == DW_FORM_data1
+ || attr->form == DW_FORM_data2
+ || attr->form == DW_FORM_data4
+ || attr->form == DW_FORM_data8)
+ {
+ low = DW_UNSND (attr);
+ }
+ else
+ {
+ dwarf2_non_const_subrange_bound_ignored_complaint
+ (dwarf_form_name (attr->form));
+ low = 0;
+ }
+ }
+ attr = dwarf_attr (die, DW_AT_upper_bound);
+ if (attr)
+ {
+ if (attr->form == DW_FORM_sdata)
+ {
+ high = DW_SND (attr);
+ }
+ else if (attr->form == DW_FORM_udata
+ || attr->form == DW_FORM_data1
+ || attr->form == DW_FORM_data2
+ || attr->form == DW_FORM_data4
+ || attr->form == DW_FORM_data8)
+ {
+ high = DW_UNSND (attr);
+ }
+ else
+ {
+ dwarf2_non_const_subrange_bound_ignored_complaint
+ (dwarf_form_name (attr->form));
+ high = 1;
+ }
+ }
+ die->type = create_range_type (NULL, element_type, low, high);
+}
+
/* Read a whole compilation unit into a linked list of dies. */

static struct die_info *
@@ -5674,6 +5752,9 @@ read_type_die (struct die_info *die, str
case DW_TAG_base_type:
read_base_type (die, cu);
break;
+ case DW_TAG_subrange_type:
+ read_subrange_type (die, cu);
+ break;
default:
complaint (&symfile_complaints, "unexepected tag in read_type_die: '%s'",
dwarf_tag_name (die->tag));

--
Andreas Schwab, SuSE Labs, schwab@suse.de
SuSE Linux AG, Deutschherrnstr. 15-19, D-90429 NÃ¼rnberg
Key fingerprint = 58CA 54C7 6D53 942B 1756 01D3 44D5 214B 8276 4ED5
"And now for something completely different."