[patch] static_kind -> bit0, bit1 [Re: [gdb] Fortran dynamic arrays]

Jan Kratochvil
2008-09-07T11:59:26Z

[-- Attachment #1: Type: text/plain, Size: 3900 bytes --]

Hi,

On Mon, 18 Aug 2008 13:11:20 +0200, Joel Brobecker wrote:
> could you show us how Fortran arrays are described in DWARF?).

They use regular DWARF BLOCKs. Just so far GDB supported these blocks only for
DW_AT_location while for Fortran they are used even for other attributes.
There is also new DW_OP_push_object_address, DW_AT_data_location,
DW_AT_associated and DW_AT_allocated.

<2><6e>: Abbrev Number: 5 (DW_TAG_variable)
<6f> DW_AT_name : (indirect string, offset: 0x63): varv
<73> DW_AT_decl_file : 1
<74> DW_AT_decl_line : 23
<75> DW_AT_type : <0x197>
<79> DW_AT_location : 3 byte block: 91 f0 7e (DW_OP_fbreg: -144)
<1><197>: Abbrev Number: 13 (DW_TAG_array_type)
<198> DW_AT_name : (indirect string, offset: 0x107): array3_real(kind=4)
<19c> DW_AT_ordering : 1 (column major)
<19d> DW_AT_data_location: 2 byte block: 97 6 (DW_OP_push_object_address; DW_OP_deref)
<1a0> DW_AT_associated : 4 byte block: 97 6 30 2e (DW_OP_push_object_address; DW_OP_deref; DW_OP_lit0; DW_OP_ne)
<1a5> DW_AT_type : <0x190>
<1a9> DW_AT_sibling : <0x1e4>
<2><1ad>: Abbrev Number: 14 (DW_TAG_subrange_type)
<1ae> DW_AT_lower_bound : 4 byte block: 97 23 20 6 (DW_OP_push_object_address; DW_OP_plus_uconst: 32; DW_OP_deref)
<1b3> DW_AT_upper_bound : 4 byte block: 97 23 28 6 (DW_OP_push_object_address; DW_OP_plus_uconst: 40; DW_OP_deref)
<1b8> DW_AT_stride : 6 byte block: 97 23 18 6 34 1e (DW_OP_push_object_address; DW_OP_plus_uconst: 24; DW_OP_deref;
DW_OP_lit4; DW_OP_mul)

The patchset for HEAD as a single file is at:
http://people.redhat.com/jkratoch/fortran-dynamic-arrays-HEAD-7.patch
(just FYI, not for a review as it is not split)

Attaching its first part - a very useless one on its own - its target is to
get a new storage space for two bits of info (TYPE_BOUND_IS_DWARF_BLOCK and
TYPE_BOUND_IS_DWARF_BLOCK). I do not think it is the best way but it is
a minimal change without expanding the structure size.

One of such spare space there is `enum array_bound_type' Except for
BOUND_CANNOT_BE_DETERMINED it is never set anywhere. BOUND_BY_* are read only
in f-valprint.c. In fact it could be probably used for the new bits
TYPE_BOUND_IS_DWARF_BLOCK and possibly TYPE_HIGH_BOUND_IS_COUNT but I would
rather like to later remove `enum array_bound_type' and its fields at all.

The patch modifies a lot of sources trying to follow the new style of
main_type bitfields instead of the former FLAGS variable. I do not think
current main_type layout is right but the patch tries to follow the current
main_type style. The original version of this patch (in current Fedora
Rawhide) used the FLAGS style access:
+#define TYPE_BOUND_IS_DWARF_BLOCK_MASK 1
+#define TYPE_BOUND_IS_DWARF_BLOCK_VAR(range_type, fieldno) \
+ TYPE_FIELD_STATIC_KIND (range_type, fieldno)
+#define TYPE_HIGH_BOUND_IS_COUNT_MASK 2
+#define TYPE_HIGH_BOUND_IS_COUNT_VAR(range_type) \
+ TYPE_FIELD_STATIC_KIND (range_type, 1)
+ TYPE_BOUND_IS_DWARF_BLOCK_VAR (range_type, 1)
+ |= TYPE_BOUND_IS_DWARF_BLOCK_MASK;
+ if ((TYPE_BOUND_IS_DWARF_BLOCK_VAR (range_type, 0)
+ & TYPE_BOUND_IS_DWARF_BLOCK_MASK) != 0

Also I do not understand why exist all the macros like this one at all:
#define TYPE_MAIN_TYPE(thistype) (thistype)->main_type
Why we cannot use it expanded? This way it is always one (or more)
"tags"-jump (VIM ctrl-]) indirections while navigating the source files.

In the attached patch FIELD_STATIC_KIND was removed so the pairs like
- FIELD_BITPOS (*f) = sh->value;
- FIELD_STATIC_KIND (*f) = 0;
were replaced by
+ SET_FIELD_BITPOS (*f, sh->value);
but still just assignments to FIELD_BITPOS (without an assignment to
FIELD_STATIC_KIND) were left as they are.

Regards,
Jan

[-- Attachment #2: fortran7-bit01.patch --]
[-- Type: text/plain, Size: 9489 bytes --]

2008-09-07 Jan Kratochvil <jan.kratochvil@redhat.com>

Split two-bit STATIC_KIND to two separate bitfield single bits.
* gdbtypes.h (struct main_type <static_kind>): Split to ...
(struct main_type <bit0>, <bit1>): ... here.
(FIELD_STATIC_KIND): Split to ...
(FIELD_BIT0, FIELD_BIT1): ... here.
(SET_FIELD_BITPOS): New.
(SET_FIELD_PHYSNAME, SET_FIELD_PHYSADDR, TYPE_FIELD_STATIC)
(TYPE_FIELD_STATIC_HAS_ADDR): Update for the split.
(TYPE_FIELD_STATIC_KIND): Remove.
(TYPE_FIELD_STATIC_HAS_NAME): New.
* coffread.c, dwarf2read.c, eval.c, gdbtypes.c, mdebugread.c: Update
throughout.

--- ./gdb/gdbtypes.h 2008-08-26 20:24:20.000000000 +0200
+++ ./gdb/gdbtypes.h 2008-09-07 13:39:11.000000000 +0200
@@ -463,11 +463,14 @@ struct main_type
user. */
unsigned int artificial : 1;

- /* This flag is zero for non-static fields, 1 for fields whose location
- is specified by the label loc.physname, and 2 for fields whose location
- is specified by loc.physaddr. */
+ /* For a field of structure:
+ BIT0 is 0 and BIT1 is 0: Static field using LOC.BITPOS.
+ BIT0 is 1 and BIT1 is 0: Dynamic field using LOC.PHYSADDR.
+ BIT0 is 0 and BIT1 is 1: Dynamic field using LOC.PHYSNAME.
+ BIT0 is 1 and BIT1 is 1: Undefined. */

- unsigned int static_kind : 2;
+ unsigned int bit0 : 1;
+ unsigned int bit1 : 1;

/* Size of this field, in bits, or zero if not packed.
For an unpacked field, the field's type's length
@@ -858,13 +861,16 @@ extern void allocate_cplus_struct_type (
#define FIELD_BITPOS(thisfld) ((thisfld).loc.bitpos)
#define FIELD_ARTIFICIAL(thisfld) ((thisfld).artificial)
#define FIELD_BITSIZE(thisfld) ((thisfld).bitsize)
-#define FIELD_STATIC_KIND(thisfld) ((thisfld).static_kind)
+#define FIELD_BIT0(thisfld) ((thisfld).bit0)
+#define FIELD_BIT1(thisfld) ((thisfld).bit1)
#define FIELD_PHYSNAME(thisfld) ((thisfld).loc.physname)
#define FIELD_PHYSADDR(thisfld) ((thisfld).loc.physaddr)
+#define SET_FIELD_BITPOS(thisfld, bitpos) \
+ ((thisfld).bit0 = 0, (thisfld).bit1 = 0, FIELD_PHYSADDR(thisfld) = (bitpos))
+#define SET_FIELD_PHYSADDR(thisfld, addr) \
+ ((thisfld).bit0 = 1, (thisfld).bit1 = 0, FIELD_PHYSADDR(thisfld) = (addr))
#define SET_FIELD_PHYSNAME(thisfld, name) \
- ((thisfld).static_kind = 1, FIELD_PHYSNAME(thisfld) = (name))
-#define SET_FIELD_PHYSADDR(thisfld, name) \
- ((thisfld).static_kind = 2, FIELD_PHYSADDR(thisfld) = (name))
+ ((thisfld).bit0 = 0, (thisfld).bit1 = 1, FIELD_PHYSNAME(thisfld) = (name))
#define TYPE_FIELD(thistype, n) TYPE_MAIN_TYPE(thistype)->fields[n]
#define TYPE_FIELD_TYPE(thistype, n) FIELD_TYPE(TYPE_FIELD(thistype, n))
#define TYPE_FIELD_NAME(thistype, n) FIELD_NAME(TYPE_FIELD(thistype, n))
@@ -903,11 +909,14 @@ extern void allocate_cplus_struct_type (
(TYPE_CPLUS_SPECIFIC(thistype)->virtual_field_bits == NULL ? 0 \
: B_TST(TYPE_CPLUS_SPECIFIC(thistype)->virtual_field_bits, (n)))

-#define TYPE_FIELD_STATIC(thistype, n) (TYPE_MAIN_TYPE (thistype)->fields[n].static_kind != 0)
-#define TYPE_FIELD_STATIC_KIND(thistype, n) TYPE_MAIN_TYPE (thistype)->fields[n].static_kind
-#define TYPE_FIELD_STATIC_HAS_ADDR(thistype, n) (TYPE_MAIN_TYPE (thistype)->fields[n].static_kind == 2)
-#define TYPE_FIELD_STATIC_PHYSNAME(thistype, n) FIELD_PHYSNAME(TYPE_FIELD(thistype, n))
+#define TYPE_FIELD_BIT0(thistype, n) (TYPE_MAIN_TYPE (thistype)->fields[n].bit0)
+#define TYPE_FIELD_BIT1(thistype, n) (TYPE_MAIN_TYPE (thistype)->fields[n].bit1)
+#define TYPE_FIELD_STATIC_HAS_ADDR(thistype, n) TYPE_FIELD_BIT0 (thistype, n)
+#define TYPE_FIELD_STATIC_HAS_NAME(thistype, n) TYPE_FIELD_BIT1 (thistype, n)
+#define TYPE_FIELD_STATIC(thistype, n) (TYPE_FIELD_STATIC_HAS_ADDR (thistype, n) \
+ || TYPE_FIELD_STATIC_HAS_NAME (thistype, n))
#define TYPE_FIELD_STATIC_PHYSADDR(thistype, n) FIELD_PHYSADDR(TYPE_FIELD(thistype, n))
+#define TYPE_FIELD_STATIC_PHYSNAME(thistype, n) FIELD_PHYSNAME(TYPE_FIELD(thistype, n))

#define TYPE_FN_FIELDLISTS(thistype) TYPE_CPLUS_SPECIFIC(thistype)->fn_fieldlists
#define TYPE_FN_FIELDLIST(thistype, n) TYPE_CPLUS_SPECIFIC(thistype)->fn_fieldlists[n]
--- ./gdb/coffread.c 2008-08-26 20:24:18.000000000 +0200
+++ ./gdb/coffread.c 2008-09-07 13:34:35.000000000 +0200
@@ -1943,9 +1943,8 @@ coff_read_struct_type (int index, int le
obsavestring (name, strlen (name), &objfile->objfile_obstack);
FIELD_TYPE (list->field) = decode_type (ms, ms->c_type, &sub_aux,
objfile);
- FIELD_BITPOS (list->field) = 8 * ms->c_value;
+ SET_FIELD_BITPOS (list->field, 8 * ms->c_value);
FIELD_BITSIZE (list->field) = 0;
- FIELD_STATIC_KIND (list->field) = 0;
nfields++;
break;

@@ -1961,9 +1960,8 @@ coff_read_struct_type (int index, int le
obsavestring (name, strlen (name), &objfile->objfile_obstack);
FIELD_TYPE (list->field) = decode_type (ms, ms->c_type, &sub_aux,
objfile);
- FIELD_BITPOS (list->field) = ms->c_value;
+ SET_FIELD_BITPOS (list->field, ms->c_value);
FIELD_BITSIZE (list->field) = sub_aux.x_sym.x_misc.x_lnsz.x_size;
- FIELD_STATIC_KIND (list->field) = 0;
nfields++;
break;

@@ -2080,11 +2078,10 @@ coff_read_enum_type (int index, int leng
struct symbol *xsym = syms->symbol[j];
SYMBOL_TYPE (xsym) = type;
TYPE_FIELD_NAME (type, n) = SYMBOL_LINKAGE_NAME (xsym);
- TYPE_FIELD_BITPOS (type, n) = SYMBOL_VALUE (xsym);
+ SET_FIELD_BITPOS (TYPE_FIELD (type, n), SYMBOL_VALUE (xsym));
if (SYMBOL_VALUE (xsym) < 0)
unsigned_enum = 0;
TYPE_FIELD_BITSIZE (type, n) = 0;
- TYPE_FIELD_STATIC_KIND (type, n) = 0;
}
if (syms == osyms)
break;
--- ./gdb/dwarf2read.c 2008-09-02 00:21:45.000000000 +0200
+++ ./gdb/dwarf2read.c 2008-09-07 13:34:35.000000000 +0200
@@ -3498,8 +3498,6 @@ dwarf2_add_field (struct field_info *fip
/* Get type of field. */
fp->type = die_type (die, cu);

- FIELD_STATIC_KIND (*fp) = 0;
-
/* Get bit size of field (zero if none). */
attr = dwarf2_attr (die, DW_AT_bit_size, cu);
if (attr)
@@ -3527,10 +3525,10 @@ dwarf2_add_field (struct field_info *fip
else
byte_offset = decode_locdesc (DW_BLOCK (attr), cu);

- FIELD_BITPOS (*fp) = byte_offset * bits_per_byte;
+ SET_FIELD_BITPOS (*fp, byte_offset * bits_per_byte);
}
else
- FIELD_BITPOS (*fp) = 0;
+ SET_FIELD_BITPOS (*fp, 0);
attr = dwarf2_attr (die, DW_AT_bit_offset, cu);
if (attr)
{
@@ -3622,10 +3620,9 @@ dwarf2_add_field (struct field_info *fip
/* C++ base class field. */
attr = dwarf2_attr (die, DW_AT_data_member_location, cu);
if (attr)
- FIELD_BITPOS (*fp) = (decode_locdesc (DW_BLOCK (attr), cu)
- * bits_per_byte);
+ SET_FIELD_BITPOS (*fp, decode_locdesc (DW_BLOCK (attr), cu)
+ * bits_per_byte);
FIELD_BITSIZE (*fp) = 0;
- FIELD_STATIC_KIND (*fp) = 0;
FIELD_TYPE (*fp) = die_type (die, cu);
FIELD_NAME (*fp) = type_name_no_tag (fp->type);
fip->nbaseclasses++;
@@ -4343,9 +4340,8 @@ process_enumeration_scope (struct die_in

FIELD_NAME (fields[num_fields]) = SYMBOL_LINKAGE_NAME (sym);
FIELD_TYPE (fields[num_fields]) = NULL;
- FIELD_BITPOS (fields[num_fields]) = SYMBOL_VALUE (sym);
+ SET_FIELD_BITPOS (fields[num_fields], SYMBOL_VALUE (sym));
FIELD_BITSIZE (fields[num_fields]) = 0;
- FIELD_STATIC_KIND (fields[num_fields]) = 0;

num_fields++;
}
--- ./gdb/eval.c 2008-08-21 22:13:08.000000000 +0200
+++ ./gdb/eval.c 2008-09-07 13:34:35.000000000 +0200
@@ -319,7 +319,7 @@ evaluate_struct_tuple (struct value *str
fieldno++;
/* Skip static fields. */
while (fieldno < TYPE_NFIELDS (struct_type)
- && TYPE_FIELD_STATIC_KIND (struct_type, fieldno))
+ && TYPE_FIELD_STATIC (struct_type, fieldno))
fieldno++;
subfieldno = fieldno;
if (fieldno >= TYPE_NFIELDS (struct_type))
--- ./gdb/gdbtypes.c 2008-08-26 20:24:20.000000000 +0200
+++ ./gdb/gdbtypes.c 2008-09-07 13:34:35.000000000 +0200
@@ -3013,11 +3013,8 @@ copy_type_recursive (struct objfile *obj
xstrdup (TYPE_FIELD_STATIC_PHYSNAME (type,
i)));
else
- {
- TYPE_FIELD_BITPOS (new_type, i) =
- TYPE_FIELD_BITPOS (type, i);
- TYPE_FIELD_STATIC_KIND (new_type, i) = 0;
- }
+ SET_FIELD_BITPOS (TYPE_FIELD (new_type, i),
+ TYPE_FIELD_BITPOS (type, i));
}
}

--- ./gdb/mdebugread.c 2008-08-26 20:24:20.000000000 +0200
+++ ./gdb/mdebugread.c 2008-09-07 13:34:35.000000000 +0200
@@ -1054,11 +1054,10 @@ parse_symbol (SYMR *sh, union aux_ext *a
if (tsym.st != stMember)
break;

- FIELD_BITPOS (*f) = tsym.value;
+ SET_FIELD_BITPOS (*f, tsym.value);
FIELD_TYPE (*f) = t;
FIELD_NAME (*f) = debug_info->ss + cur_fdr->issBase + tsym.iss;
FIELD_BITSIZE (*f) = 0;
- FIELD_STATIC_KIND (*f) = 0;

enum_sym = ((struct symbol *)
obstack_alloc (&current_objfile->objfile_obstack,
@@ -1241,11 +1240,10 @@ parse_symbol (SYMR *sh, union aux_ext *a
case stMember: /* member of struct or union */
f = &TYPE_FIELDS (top_stack->cur_type)[top_stack->cur_field++];
FIELD_NAME (*f) = name;
- FIELD_BITPOS (*f) = sh->value;
+ SET_FIELD_BITPOS (*f, sh->value);
bitsize = 0;
FIELD_TYPE (*f) = parse_type (cur_fd, ax, sh->index, &bitsize, bigend, name);
FIELD_BITSIZE (*f) = bitsize;
- FIELD_STATIC_KIND (*f) = 0;
break;

case stIndirect: /* forward declaration on Irix5 */