* Re: [PATCH] Handle DW_TAG_subrange_type
@ 2004-01-08 23:33 Elena Zannoni
2004-01-14 17:28 ` Joel Brobecker
0 siblings, 1 reply; 11+ messages in thread
From: Elena Zannoni @ 2004-01-08 23:33 UTC (permalink / raw)
To: brobecker, schwab; +Cc: gdb-patches
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));
^ permalink raw reply [flat|nested] 11+ messages in thread
* Re: [PATCH] Handle DW_TAG_subrange_type
2004-01-08 23:33 [PATCH] Handle DW_TAG_subrange_type Elena Zannoni
@ 2004-01-14 17:28 ` Joel Brobecker
2004-01-15 17:11 ` Elena Zannoni
0 siblings, 1 reply; 11+ messages in thread
From: Joel Brobecker @ 2004-01-14 17:28 UTC (permalink / raw)
To: Elena Zannoni; +Cc: schwab, gdb-patches
[-- Attachment #1: Type: text/plain, Size: 1627 bytes --]
Hello Helena,
> 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.
Here is a revised patch, which I hope addresses all your comments.
Tested on x86-linux, using gcc HEAD. No regression.
I should also mention that I am about to send a patch to gcc-patches,
which slightly modifies the dwarf-2 output, and will likely cause GCC
to generate more of these subrange_type DIEs. It is more a cleanup
patch than anything else, but I did verify that GDB together with the
attached patch handle the new GCC without trouble.
2004-01-14 J. Brobecker <brobecker@gnat.com>
* dwarf2read.c (dwarf2_non_const_array_bound_ignored_complaint):
Delete, no longer used.
(read_subrange_type): New function, mostly extracted from
read_array_type().
(read_array_type): Replace extracted code by call to
read_subrange_type().
(dwarf2_get_attr_constant_value): New function.
(scan_partial_symbols): Add handling for DW_TAG_subrange_type.
(add_partial_symbol): Likewise.
(process_die): Likewise.
(new_symbol): Likewise.
(read_type_die): Likewise.
OK to apply?
Thanks,
--
Joel
[-- Attachment #2: gdb-subrange.diff --]
[-- Type: text/plain, Size: 9396 bytes --]
Index: dwarf2read.c
===================================================================
RCS file: /cvs/src/src/gdb/dwarf2read.c,v
retrieving revision 1.119
diff -u -p -r1.119 dwarf2read.c
--- dwarf2read.c 9 Jan 2004 22:22:07 -0000 1.119
+++ dwarf2read.c 14 Jan 2004 15:13:02 -0000
@@ -592,13 +592,6 @@ struct field_info
/* Various complaints about symbol reading that don't abort the process */
static void
-dwarf2_non_const_array_bound_ignored_complaint (const char *arg1)
-{
- complaint (&symfile_complaints, "non-constant array bounds form '%s' ignored",
- arg1);
-}
-
-static void
dwarf2_statement_list_fits_in_line_number_section_complaint (void)
{
complaint (&symfile_complaints,
@@ -781,6 +774,8 @@ static void read_typedef (struct die_inf
static void read_base_type (struct die_info *, struct dwarf2_cu *);
+static void read_subrange_type (struct die_info *die, struct dwarf2_cu *cu);
+
static void read_file_scope (struct die_info *, struct dwarf2_cu *);
static void read_func_scope (struct die_info *, struct dwarf2_cu *);
@@ -889,6 +884,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 *, int);
+
static struct die_info *follow_die_ref (unsigned int);
static struct type *dwarf2_fundamental_type (struct objfile *, int);
@@ -1384,6 +1381,7 @@ scan_partial_symbols (char *info_ptr, CO
}
break;
case DW_TAG_base_type:
+ case DW_TAG_subrange_type:
/* File scope base type definitions are added to the partial
symbol table. */
add_partial_symbol (&pdi, cu, namespace);
@@ -1496,6 +1494,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 (actual_name, strlen (actual_name),
VAR_DOMAIN, LOC_TYPEDEF,
&objfile->static_psymbols,
@@ -1858,6 +1857,14 @@ process_die (struct die_info *die, struc
new_symbol (die, die->type, cu);
}
break;
+ case DW_TAG_subrange_type:
+ read_subrange_type (die, cu);
+ if (dwarf_attr (die, DW_AT_name))
+ {
+ /* Add a typedef symbol for the base type definition. */
+ new_symbol (die, die->type, cu);
+ }
+ break;
case DW_TAG_common_block:
read_common_block (die, cu);
break;
@@ -3062,88 +3069,22 @@ read_array_type (struct die_info *die, s
{
if (child_die->tag == DW_TAG_subrange_type)
{
- unsigned int low, high;
-
- /* Default bounds to an array with unspecified length. */
- low = 0;
- high = -1;
- if (cu_language == language_fortran)
- {
- /* FORTRAN implies a lower bound of 1, if not given. */
- low = 1;
- }
-
- index_type = die_type (child_die, cu);
- attr = dwarf_attr (child_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_array_bound_ignored_complaint
- (dwarf_form_name (attr->form));
- low = 0;
- }
- }
- attr = dwarf_attr (child_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 if (attr->form == DW_FORM_block1)
- {
- /* GCC encodes arrays with unspecified or dynamic length
- with a DW_FORM_block1 attribute.
- FIXME: GDB does not yet know how to handle dynamic
- arrays properly, treat them as arrays with unspecified
- length for now.
-
- FIXME: jimb/2003-09-22: GDB does not really know
- how to handle arrays of unspecified length
- either; we just represent them as zero-length
- arrays. Choose an appropriate upper bound given
- the lower bound we've computed above. */
- high = low - 1;
- }
- else
- {
- dwarf2_non_const_array_bound_ignored_complaint
- (dwarf_form_name (attr->form));
- high = 1;
- }
- }
+ read_subrange_type (child_die, cu);
- /* Create a range type and save it for array type creation. */
- if ((ndim % DW_FIELD_ALLOC_CHUNK) == 0)
- {
- range_types = (struct type **)
- xrealloc (range_types, (ndim + DW_FIELD_ALLOC_CHUNK)
- * sizeof (struct type *));
- if (ndim == 0)
- make_cleanup (free_current_contents, &range_types);
- }
- range_types[ndim++] = create_range_type (NULL, index_type, low, high);
+ if (child_die->type != NULL)
+ {
+ /* The range type was succesfully read. Save it for
+ the array type creation. */
+ if ((ndim % DW_FIELD_ALLOC_CHUNK) == 0)
+ {
+ range_types = (struct type **)
+ xrealloc (range_types, (ndim + DW_FIELD_ALLOC_CHUNK)
+ * sizeof (struct type *));
+ if (ndim == 0)
+ make_cleanup (free_current_contents, &range_types);
+ }
+ range_types[ndim++] = child_die->type;
+ }
}
child_die = sibling_die (child_die);
}
@@ -3689,6 +3630,78 @@ 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 dwarf2_cu *cu)
+{
+ 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, cu);
+ if (base_type == NULL)
+ {
+ complaint (&symfile_complaints,
+ "DW_AT_type missing from DW_TAG_subrange_type");
+ return;
+ }
+
+ if (TYPE_CODE (base_type) == TYPE_CODE_VOID)
+ base_type = alloc_type (NULL);
+
+ 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)
+ low = dwarf2_get_attr_constant_value (attr, 0);
+
+ attr = dwarf_attr (die, DW_AT_upper_bound);
+ if (attr)
+ {
+ if (attr->form == DW_FORM_block1)
+ {
+ /* GCC encodes arrays with unspecified or dynamic length
+ with a DW_FORM_block1 attribute.
+ FIXME: GDB does not yet know how to handle dynamic
+ arrays properly, treat them as arrays with unspecified
+ length for now.
+
+ FIXME: jimb/2003-09-22: GDB does not really know
+ how to handle arrays of unspecified length
+ either; we just represent them as zero-length
+ arrays. Choose an appropriate upper bound given
+ the lower bound we've computed above. */
+ high = low - 1;
+ }
+ else
+ high = dwarf2_get_attr_constant_value (attr, 1);
+ }
+
+ 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);
+
+ attr = dwarf_attr (die, DW_AT_byte_size);
+ if (attr)
+ TYPE_LENGTH (range_type) = DW_UNSND (attr);
+
+ die->type = range_type;
+}
+
+
/* Read a whole compilation unit into a linked list of dies. */
static struct die_info *
@@ -5344,6 +5357,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);
@@ -5626,6 +5640,9 @@ read_type_die (struct die_info *die, str
case DW_TAG_typedef:
read_typedef (die, cu);
break;
+ case DW_TAG_subrange_type:
+ read_subrange_type (die, cu);
+ break;
case DW_TAG_base_type:
read_base_type (die, cu);
break;
@@ -6733,6 +6750,28 @@ 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, int default_value)
+{
+ 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 (%s)",
+ dwarf_form_name (attr->form));
+ return default_value;
+ }
}
static struct die_info *
^ permalink raw reply [flat|nested] 11+ messages in thread
* Re: [PATCH] Handle DW_TAG_subrange_type
2004-01-14 17:28 ` Joel Brobecker
@ 2004-01-15 17:11 ` Elena Zannoni
2004-01-17 5:37 ` Joel Brobecker
0 siblings, 1 reply; 11+ messages in thread
From: Elena Zannoni @ 2004-01-15 17:11 UTC (permalink / raw)
To: Joel Brobecker; +Cc: Elena Zannoni, schwab, gdb-patches
Joel Brobecker writes:
> Hello Helena,
>
> > 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.
>
> Here is a revised patch, which I hope addresses all your comments.
> Tested on x86-linux, using gcc HEAD. No regression.
>
> I should also mention that I am about to send a patch to gcc-patches,
> which slightly modifies the dwarf-2 output, and will likely cause GCC
> to generate more of these subrange_type DIEs. It is more a cleanup
> patch than anything else, but I did verify that GDB together with the
> attached patch handle the new GCC without trouble.
>
> 2004-01-14 J. Brobecker <brobecker@gnat.com>
>
> * dwarf2read.c (dwarf2_non_const_array_bound_ignored_complaint):
> Delete, no longer used.
> (read_subrange_type): New function, mostly extracted from
> read_array_type().
> (read_array_type): Replace extracted code by call to
> read_subrange_type().
> (dwarf2_get_attr_constant_value): New function.
> (scan_partial_symbols): Add handling for DW_TAG_subrange_type.
> (add_partial_symbol): Likewise.
> (process_die): Likewise.
> (new_symbol): Likewise.
> (read_type_die): Likewise.
>
> OK to apply?
sure
elena
^ permalink raw reply [flat|nested] 11+ messages in thread
* Re: [PATCH] Handle DW_TAG_subrange_type
2004-01-15 17:11 ` Elena Zannoni
@ 2004-01-17 5:37 ` Joel Brobecker
0 siblings, 0 replies; 11+ messages in thread
From: Joel Brobecker @ 2004-01-17 5:37 UTC (permalink / raw)
To: Elena Zannoni; +Cc: schwab, gdb-patches
> > 2004-01-14 J. Brobecker <brobecker@gnat.com>
> >
> > * dwarf2read.c (dwarf2_non_const_array_bound_ignored_complaint):
> > Delete, no longer used.
> > (read_subrange_type): New function, mostly extracted from
> > read_array_type().
> > (read_array_type): Replace extracted code by call to
> > read_subrange_type().
> > (dwarf2_get_attr_constant_value): New function.
> > (scan_partial_symbols): Add handling for DW_TAG_subrange_type.
> > (add_partial_symbol): Likewise.
> > (process_die): Likewise.
> > (new_symbol): Likewise.
> > (read_type_die): Likewise.
> >
> > OK to apply?
>
> sure
Thank you. Checked in.
(btw, the gcc cleanup I mentionned in my previous message has also been
checked in).
--
Joel
^ permalink raw reply [flat|nested] 11+ messages in thread
* Re: [PATCH] Handle DW_TAG_subrange_type
2003-12-04 17:49 ` Joel Brobecker
@ 2003-12-04 18:16 ` Elena Zannoni
0 siblings, 0 replies; 11+ messages in thread
From: Elena Zannoni @ 2003-12-04 18:16 UTC (permalink / raw)
To: Joel Brobecker; +Cc: Elena Zannoni, Andreas Schwab, gdb-patches
Joel Brobecker writes:
> > Can you post an example of the debug info you see for Ada in this
> > case, just for the record?
>
> In addition to the example posted by Andreas, here is the code in GCC
> that generates these subrange types:
>
[...]
>
> So the only information we are stuffing in these types are the name,
> the bounds, and a reference to the parent type.
>
Ok, thanks. Makes sense.
elena
^ permalink raw reply [flat|nested] 11+ messages in thread
* Re: [PATCH] Handle DW_TAG_subrange_type
2003-12-04 16:51 ` Elena Zannoni
2003-12-04 17:29 ` Andreas Schwab
@ 2003-12-04 17:49 ` Joel Brobecker
2003-12-04 18:16 ` Elena Zannoni
1 sibling, 1 reply; 11+ messages in thread
From: Joel Brobecker @ 2003-12-04 17:49 UTC (permalink / raw)
To: Elena Zannoni; +Cc: Andreas Schwab, gdb-patches
> Can you post an example of the debug info you see for Ada in this
> case, just for the record?
In addition to the example posted by Andreas, here is the code in GCC
that generates these subrange types:
static dw_die_ref
subrange_type_die (tree type)
{
dw_die_ref subtype_die;
dw_die_ref subrange_die;
tree name = TYPE_NAME (type);
subtype_die = base_type_die (TREE_TYPE (type));
if (TREE_CODE (name) == TYPE_DECL)
name = DECL_NAME (name);
subrange_die = new_die (DW_TAG_subrange_type, comp_unit_die, type);
add_name_attribute (subrange_die, IDENTIFIER_POINTER (name));
if (TYPE_MIN_VALUE (type) != NULL)
add_bound_info (subrange_die, DW_AT_lower_bound,
TYPE_MIN_VALUE (type));
if (TYPE_MAX_VALUE (type) != NULL)
add_bound_info (subrange_die, DW_AT_upper_bound,
TYPE_MAX_VALUE (type));
add_AT_die_ref (subrange_die, DW_AT_type, subtype_die);
return subrange_die;
}
So the only information we are stuffing in these types are the name,
the bounds, and a reference to the parent type.
--
Joel
^ permalink raw reply [flat|nested] 11+ messages in thread
* Re: [PATCH] Handle DW_TAG_subrange_type
2003-12-04 16:51 ` Elena Zannoni
@ 2003-12-04 17:29 ` Andreas Schwab
2003-12-04 17:49 ` Joel Brobecker
1 sibling, 0 replies; 11+ messages in thread
From: Andreas Schwab @ 2003-12-04 17:29 UTC (permalink / raw)
To: Elena Zannoni; +Cc: gdb-patches
Elena Zannoni <ezannoni@redhat.com> writes:
> Can you post an example of the debug info you see for Ada in this
> case, just for the record?
These are a few examples extracted from 'readelf -w gnatbind':
<2><4b3>: Abbrev Number: 13 (DW_TAG_subrange_type)
DW_AT_type : <4ba>
DW_AT_upper_bound : 41
<1><4d11>: Abbrev Number: 8 (DW_TAG_subrange_type)
DW_AT_name : (indirect string, offset: 0x34ba): ada__exceptions__code_loc___XDLU_0__18446744073709551615
DW_AT_lower_bound : 0
DW_AT_type : <4d0a>
<2><4e53>: Abbrev Number: 13 (DW_TAG_subrange_type)
DW_AT_type : <4df2>
DW_AT_lower_bound : 1
DW_AT_upper_bound : 50
<2><54ca>: Abbrev Number: 22 (DW_TAG_variable)
DW_AT_artificial : 1
DW_AT_type : <5339>
DW_AT_location : 24 byte block: 92 29 0 92 25 0 31 1c 2d 28 6 0 92 29 0 2f 5 0 92 25 0 31 1c 96 (DW_OP_bregx: 41 0; DW_OP_bregx: 37 0; DW_OP_lit1; DW_OP_minus; DW_OP_lt; DW_OP_bra: 6; DW_OP_bregx: 41 0; DW_OP_skip: 5; DW_OP_bregx: 37 0; DW_OP_lit1; DW_OP_minus; DW_OP_nop)
<2><55b5>: Abbrev Number: 33 (DW_TAG_subrange_type)
DW_AT_type : <4df2>
DW_AT_upper_bound : <54ca>
Andreas.
--
Andreas Schwab, SuSE Labs, schwab@suse.de
SuSE Linux AG, MaxfeldstraÃe 5, 90409 Nürnberg, Germany
Key fingerprint = 58CA 54C7 6D53 942B 1756 01D3 44D5 214B 8276 4ED5
"And now for something completely different."
^ permalink raw reply [flat|nested] 11+ messages in thread
* Re: [PATCH] Handle DW_TAG_subrange_type
2003-11-22 20:08 Andreas Schwab
2003-11-24 9:51 ` Joel Brobecker
@ 2003-12-04 16:51 ` Elena Zannoni
2003-12-04 17:29 ` Andreas Schwab
2003-12-04 17:49 ` Joel Brobecker
1 sibling, 2 replies; 11+ messages in thread
From: Elena Zannoni @ 2003-12-04 16:51 UTC (permalink / raw)
To: Andreas Schwab; +Cc: gdb-patches
Andreas Schwab writes:
> 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.
>
OK. Reading the Dwarf2 spec, there is a lot more that could be
apearing in the debug info for a subrange type, I guess we'll improve
on this as we encounter other unhandled cases.
Can you post an example of the debug info you see for Ada in this
case, just for the record?
elena
^ permalink raw reply [flat|nested] 11+ messages in thread
* Re: [PATCH] Handle DW_TAG_subrange_type
2003-11-24 9:51 ` Joel Brobecker
@ 2003-11-24 12:16 ` Andreas Schwab
0 siblings, 0 replies; 11+ messages in thread
From: Andreas Schwab @ 2003-11-24 12:16 UTC (permalink / raw)
To: Joel Brobecker; +Cc: gdb-patches
Joel Brobecker <brobecker@gnat.com> writes:
>> When trying to debug Ada code you often get a DW_TAG_subrange_type, which
>> gdb can't handle yet.
>
> Hmmm, I don't remember having submitted the patch to emit these subrange
> types. Maybe somebody else managed to add this capability already?
> Do you confirm these types are emitted for modular types (for instance
> "type Mod_Type is mod 4")?
See dwarf2out.c:is_ada_subrange_type.
Andreas.
--
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."
^ permalink raw reply [flat|nested] 11+ messages in thread
* Re: [PATCH] Handle DW_TAG_subrange_type
2003-11-22 20:08 Andreas Schwab
@ 2003-11-24 9:51 ` Joel Brobecker
2003-11-24 12:16 ` Andreas Schwab
2003-12-04 16:51 ` Elena Zannoni
1 sibling, 1 reply; 11+ messages in thread
From: Joel Brobecker @ 2003-11-24 9:51 UTC (permalink / raw)
To: Andreas Schwab; +Cc: gdb-patches
[-- Attachment #1: Type: text/plain, Size: 929 bytes --]
> When trying to debug Ada code you often get a DW_TAG_subrange_type, which
> gdb can't handle yet.
Hmmm, I don't remember having submitted the patch to emit these subrange
types. Maybe somebody else managed to add this capability already?
Do you confirm these types are emitted for modular types (for instance
"type Mod_Type is mod 4")?
> 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.
Also, FYI, we made a very similar change in GDB to support these types.
We did factor out a bit the code that extracts constant bound values
into a function. And we also sprinkled a bit more of the handlers for
DW_TAG_subrange_type cases. I am attaching the patch (against GDB 6.0,
but shouldn't be too hard to adapt).
Cheers,
--
Joel
[-- Attachment #2: dwarf2read.c.diff --]
[-- Type: text/plain, Size: 4785 bytes --]
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 *
^ permalink raw reply [flat|nested] 11+ messages in thread
* [PATCH] Handle DW_TAG_subrange_type
@ 2003-11-22 20:08 Andreas Schwab
2003-11-24 9:51 ` Joel Brobecker
2003-12-04 16:51 ` Elena Zannoni
0 siblings, 2 replies; 11+ messages in thread
From: Andreas Schwab @ 2003-11-22 20:08 UTC (permalink / raw)
To: gdb-patches
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."
^ permalink raw reply [flat|nested] 11+ messages in thread
end of thread, other threads:[~2004-01-17 5:37 UTC | newest]
Thread overview: 11+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2004-01-08 23:33 [PATCH] Handle DW_TAG_subrange_type Elena Zannoni
2004-01-14 17:28 ` Joel Brobecker
2004-01-15 17:11 ` Elena Zannoni
2004-01-17 5:37 ` Joel Brobecker
-- strict thread matches above, loose matches on Subject: below --
2003-11-22 20:08 Andreas Schwab
2003-11-24 9:51 ` Joel Brobecker
2003-11-24 12:16 ` Andreas Schwab
2003-12-04 16:51 ` Elena Zannoni
2003-12-04 17:29 ` Andreas Schwab
2003-12-04 17:49 ` Joel Brobecker
2003-12-04 18:16 ` Elena Zannoni
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox