Re: [PATCH] Handle DW_TAG_subrange_type

Elena Zannoni
2004-01-08T23:33:37Z

This is about
http://sources.redhat.com/ml/gdb-patches/2003-11/msg00468.html

[I lost the original mail]

I inserted both patches below for reference.

comments:

I agree that the subrange type should be handled in more places, so ok
with Joel's calls for that.

Almost identical code is in read_array_type. Would it be possible to
unify that as well into a single function read_subrange_type? I.e. do
you think that that "else if (attr->form == DW_FORM_block1)" clause
will interfere with the ADA case? If not and we can unify them, then,
I'd prefer the version that Andreas has, since it handles the default
high and low, not as -1, but the same as the original code. In that
case we can also get rid of
dwarf2_non_const_array_bound_ignored_complaint and use the more
specific dwarf2_non_const_subrange_bound_ignored_complaint instead.

yes on Joel's addition of a new symbol if we have a name.

elena

Joel's patch:

> Index: dwarf2read.c
> ===================================================================
> RCS file: /nile.c/cvs/Dev/gdb/gdb-6.0/gdb/dwarf2read.c,v
> retrieving revision 1.1
> retrieving revision 1.5
> diff -u -p -r1.1 -r1.5
> --- dwarf2read.c 5 Oct 2003 10:39:45 -0000 1.1
> +++ dwarf2read.c 19 Nov 2003 18:02:23 -0000 1.5
> @@ -783,6 +783,9 @@ static void read_typedef (struct die_inf
>
> static void read_base_type (struct die_info *, struct objfile *);
>
> +static void read_subrange_type (struct die_info *die, struct objfile *objfile,
> + const struct comp_unit_head *cu_header);
> +
> static void read_file_scope (struct die_info *, struct objfile *,
> const struct comp_unit_head *);
>
> @@ -896,6 +899,8 @@ static void dwarf2_empty_hash_tables (vo
>
> static unsigned int dwarf2_get_ref_die_offset (struct attribute *);
>
> +static int dwarf2_get_attr_constant_value (struct attribute *);
> +
> static struct die_info *follow_die_ref (unsigned int);
>
> static struct type *dwarf2_fundamental_type (struct objfile *, int);
> @@ -1418,6 +1455,7 @@ scan_partial_symbols (char *info_ptr, st
> case DW_TAG_structure_type:
> case DW_TAG_union_type:
> case DW_TAG_enumeration_type:
> + case DW_TAG_subrange_type:
> if ((pdi.is_external || nesting_level == file_scope_level)
> && !pdi.is_declaration)
> {
> @@ -1555,6 +1595,7 @@ add_partial_symbol (struct partial_die_i
> break;
> case DW_TAG_typedef:
> case DW_TAG_base_type:
> + case DW_TAG_subrange_type:
> add_psymbol_to_list (pdi->name, strlen (pdi->name),
> VAR_DOMAIN, LOC_TYPEDEF,
> &objfile->static_psymbols,
> @@ -1803,6 +1844,14 @@ process_die (struct die_info *die, struc
> new_symbol (die, die->type, objfile, cu_header);
> }
> break;
> + case DW_TAG_subrange_type:
> + read_subrange_type (die, objfile, cu_header);
> + if (dwarf_attr (die, DW_AT_name))
> + {
> + /* Add a typedef symbol for the base type definition. */
> + new_symbol (die, die->type, objfile, cu_header);
> + }
> + break;
> case DW_TAG_common_block:
> read_common_block (die, objfile, cu_header);
> break;
> @@ -3644,6 +3725,47 @@ read_base_type (struct die_info *die, st
> die->type = type;
> }
>
> +/* Read the given DW_AT_subrange DIE. */
> +
> +static void
> +read_subrange_type (struct die_info *die, struct objfile *objfile,
> + const struct comp_unit_head *cu_header)
> +{
> + struct type *base_type;
> + struct type *range_type;
> + struct attribute *attr;
> + int low = 0;
> + int high = -1;
> +
> + /* If we have already decoded this die, then nothing more to do. */
> + if (die->type)
> + return;
> +
> + base_type = die_type (die, objfile, cu_header);
> + if (base_type == NULL)
> + {
> + complaint (&symfile_complaints,
> + "DW_AT_type missing from DW_TAG_subrange_type");
> + return;
> + }
> +
> + attr = dwarf_attr (die, DW_AT_lower_bound);
> + if (attr)
> + low = dwarf2_get_attr_constant_value (attr);
> +
> + attr = dwarf_attr (die, DW_AT_upper_bound);
> + if (attr)
> + high = dwarf2_get_attr_constant_value (attr);
> +
> + range_type = create_range_type (NULL, base_type, low, high);
> +
> + attr = dwarf_attr (die, DW_AT_name);
> + if (attr && DW_STRING (attr))
> + TYPE_NAME (range_type) = DW_STRING (attr);
> +
> + die->type = range_type;
> +}
> +
> /* Read a whole compilation unit into a linked list of dies. */
>
> static struct die_info *
> case DW_TAG_variable:
> @@ -5274,6 +5409,7 @@ new_symbol (struct die_info *die, struct
> break;
> case DW_TAG_typedef:
> case DW_TAG_base_type:
> + case DW_TAG_subrange_type:
> SYMBOL_CLASS (sym) = LOC_TYPEDEF;
> SYMBOL_DOMAIN (sym) = VAR_DOMAIN;
> add_symbol_to_list (sym, list_in_scope);
> @@ -5555,6 +5691,9 @@ read_type_die (struct die_info *die, str
> case DW_TAG_typedef:
> read_typedef (die, objfile, cu_header);
> break;
> + case DW_TAG_subrange_type:
> + read_subrange_type (die, objfile, cu_header);
> + break;
> case DW_TAG_base_type:
> read_base_type (die, objfile);
> break;
> @@ -6693,6 +6836,27 @@ dwarf2_get_ref_die_offset (struct attrib
> dwarf_form_name (attr->form));
> }
> return result;
> +}
> +
> +/* Return the constant value held by the given attribute. Return -1
> + if the value held by the attribute is not constant. */
> +
> +static int
> +dwarf2_get_attr_constant_value (struct attribute *attr)
> +{
> + if (attr->form == DW_FORM_sdata)
> + return 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)
> + return DW_UNSND (attr);
> + else
> + {
> + complaint (&symfile_complaints, "Attribute value is not a constant");
> + return -1;
> + }
> }
>
> static struct die_info *

Andreas' patch:

> 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));