This is the mail archive of the
gdb-patches@sourceware.org
mailing list for the GDB project.
Re: Support constants for DW_AT_data_member_location
On Thursday 29 November 2007 22:38:37 you wrote:
> Vladimir Prus <vladimir at codesourcery.com> writes:
> > DWARF standard allows DW_AT_data_member_location value
> > to be a plain constant, but GDB does not. Is the following OK?
>
> A constant can have other FORMs, too; how about this?
>
> gdb/ChangeLog:
> 2007-11-29 Jim Blandy <jimb@codesourcery.com>
>
> * dwarf2read.c (dwarf2_attr_is_constant): New function.
> (dwarf2_add_field): Use it to recognize DW_AT_data_member_location
> attributes with constant values; use
> dwarf2_get_attr_constant_value to get said values.
>
> diff -r c4f654de59cf gdb/dwarf2read.c
> --- a/gdb/dwarf2read.c Thu Nov 29 11:28:59 2007 -0800
> +++ b/gdb/dwarf2read.c Thu Nov 29 11:33:57 2007 -0800
> @@ -1012,6 +1012,8 @@ static void store_in_ref_table (unsigned
>
> static unsigned int dwarf2_get_ref_die_offset (struct attribute *,
> struct dwarf2_cu *);
> +
> +static int dwarf2_attr_is_constant (struct attribute *);
>
> static int dwarf2_get_attr_constant_value (struct attribute *, int);
>
> @@ -3380,8 +3382,11 @@ dwarf2_add_field (struct field_info *fip
> attr = dwarf2_attr (die, DW_AT_data_member_location, cu);
> if (attr)
> {
> - FIELD_BITPOS (*fp) =
> - decode_locdesc (DW_BLOCK (attr), cu) * bits_per_byte;
> + if (dwarf2_attr_is_constant (attr))
> + FIELD_BITPOS (*fp) = dwarf2_get_attr_constant_value (attr, 0);
> + else
> + FIELD_BITPOS (*fp) =
> + decode_locdesc (DW_BLOCK (attr), cu) * bits_per_byte;
> }
> else
> FIELD_BITPOS (*fp) = 0;
> @@ -9008,6 +9013,26 @@ dwarf2_get_ref_die_offset (struct attrib
> return result;
> }
>
> +/* Return non-zero if ATTR's value falls in the 'constant' class, or
> + zero otherwise. When this function returns true, you can apply
> + dwarf2_get_attr_constant_value to it. */
> +static int
> +dwarf2_attr_is_constant (struct attribute *attr)
> +{
> + switch (attr->form)
> + {
> + case DW_FORM_sdata:
> + case DW_FORM_udata:
> + case DW_FORM_data1:
> + case DW_FORM_data2:
> + case DW_FORM_data4:
This is wrong, per DWARF standard:
Some encodings are members of more than one class; in that case,
the list of classes allowed by the applicable attribute in
Figure 18 determines the class of the form. DW_FORM_data4 and
DW_FORM_data8 may be members of classes constant, lineptr,
loclistptr, macptr and rangelistptr. They are members of the
class constant if used for the value of an attribute that allows class
constant but not class lineptr, loclistptr, macptr or rangelistptr.
They are members of the class lineptr, loclistptr, macptr or
rangelistptr if used for the value of an attribute that allows
one of those classes.
Referring to Figure 18, I see:
Attribute name Classes
DW_AT_data_member_location block, constant, loclistptr
So, DW_FORM_data4 used for DW_AT_data_member_location is never interepreted
as constant. Maybe we should have "is_surely_constant" function?
- Volodya