2003-09-30 David Carlton <carlton@kealia.com>

* dwarf2read.c (struct die_info): Add 'parent' field; replace
	'has_children' and 'next' by 'child' and 'sibling'.
	(read_comp_unit): Rework algorithm, breaking body into
	read_die_and_children and read_die_and_siblings.
	(read_die_and_children, read_die_and_siblings): New.
	(read_full_die): Add 'has_children' argument; set it instead of
	the die's 'has_children' field.  Minor formatting cleanup.
	(free_die_list): Use die->child and die->sibling instead of
	die->next.
	(dump_die_list): Ditto.
	(sibling_die): Use die->sibling.
	(psymtab_to_symtab_1): Use die's 'child' field in place of its
	'has_children' and 'next' fields.
	(process_die, read_file_scope, read_func_scope)
	(read_lexical_block_scope, read_structure_scope)
	(read_enumeration, read_array_type, read_common_block)
	(read_namespace, read_subroutine_type, dump_die): Ditto.
This commit is contained in:
David Carlton 2003-09-30 22:29:28 +00:00
parent 1fc0d17365
commit 639d11d308
2 changed files with 145 additions and 98 deletions

View File

@ -1,3 +1,23 @@
2003-09-30 David Carlton <carlton@kealia.com>
* dwarf2read.c (struct die_info): Add 'parent' field; replace
'has_children' and 'next' by 'child' and 'sibling'.
(read_comp_unit): Rework algorithm, breaking body into
read_die_and_children and read_die_and_siblings.
(read_die_and_children, read_die_and_siblings): New.
(read_full_die): Add 'has_children' argument; set it instead of
the die's 'has_children' field. Minor formatting cleanup.
(free_die_list): Use die->child and die->sibling instead of
die->next.
(dump_die_list): Ditto.
(sibling_die): Use die->sibling.
(psymtab_to_symtab_1): Use die's 'child' field in place of its
'has_children' and 'next' fields.
(process_die, read_file_scope, read_func_scope)
(read_lexical_block_scope, read_structure_scope)
(read_enumeration, read_array_type, read_common_block)
(read_namespace, read_subroutine_type, dump_die): Ditto.
2003-09-30 Andrew Cagney <cagney@redhat.com>
* rs6000-tdep.c (rs6000_gdbarch_init): Set the PowerOpen red zone

View File

@ -315,13 +315,14 @@ struct attr_abbrev
struct die_info
{
enum dwarf_tag tag; /* Tag indicating type of die */
unsigned short has_children; /* Does the die have children */
unsigned int abbrev; /* Abbrev number */
unsigned int offset; /* Offset in .debug_info section */
unsigned int num_attrs; /* Number of attributes */
struct attribute *attrs; /* An array of attributes */
struct die_info *next_ref; /* Next die in ref hash table */
struct die_info *next; /* Next die in linked list */
struct die_info *child; /* Its first child, if any. */
struct die_info *sibling; /* Its next sibling, if any. */
struct die_info *parent; /* Its parent, if any. */
struct type *type; /* Cached type information */
};
@ -716,7 +717,7 @@ static char *read_partial_die (struct partial_die_info *,
const struct comp_unit_head *);
static char *read_full_die (struct die_info **, bfd *, char *,
const struct comp_unit_head *);
const struct comp_unit_head *, int *);
static char *read_attribute (struct attribute *, struct attr_abbrev *,
bfd *, char *, const struct comp_unit_head *);
@ -873,6 +874,16 @@ static void read_subroutine_type (struct die_info *, struct objfile *,
static struct die_info *read_comp_unit (char *, bfd *,
const struct comp_unit_head *);
static struct die_info *read_die_and_children (char *info_ptr, bfd *abfd,
const struct comp_unit_head *,
char **new_info_ptr,
struct die_info *parent);
static struct die_info *read_die_and_siblings (char *info_ptr, bfd *abfd,
const struct comp_unit_head *,
char **new_info_ptr,
struct die_info *parent);
static void free_die_list (struct die_info *);
static struct cleanup *make_cleanup_free_die_list (struct die_info *);
@ -1836,9 +1847,9 @@ psymtab_to_symtab_1 (struct partial_symtab *pst)
the compilation unit. If the DW_AT_high_pc is missing,
synthesize it, by scanning the DIE's below the compilation unit. */
highpc = 0;
if (dies->has_children)
if (dies->child != NULL)
{
child_die = dies->next;
child_die = dies->child;
while (child_die && child_die->tag)
{
if (child_die->tag == DW_TAG_subprogram)
@ -1958,7 +1969,7 @@ process_die (struct die_info *die, struct objfile *objfile,
processing_has_namespace_info = 1;
processing_current_namespace = "";
}
gdb_assert (!die->has_children);
gdb_assert (die->child == NULL);
break;
default:
new_symbol (die, NULL, objfile, cu_header);
@ -1988,9 +1999,9 @@ read_file_scope (struct die_info *die, struct objfile *objfile,
if (!dwarf2_get_pc_bounds (die, &lowpc, &highpc, objfile, cu_header))
{
if (die->has_children)
if (die->child != NULL)
{
child_die = die->next;
child_die = die->child;
while (child_die && child_die->tag)
{
if (child_die->tag == DW_TAG_subprogram)
@ -2069,9 +2080,9 @@ read_file_scope (struct die_info *die, struct objfile *objfile,
initialize_cu_func_list ();
/* Process all dies in compilation unit. */
if (die->has_children)
if (die->child != NULL)
{
child_die = die->next;
child_die = die->child;
while (child_die && child_die->tag)
{
process_die (child_die, objfile, cu_header);
@ -2209,9 +2220,9 @@ read_func_scope (struct die_info *die, struct objfile *objfile,
list_in_scope = &local_symbols;
if (die->has_children)
if (die->child != NULL)
{
child_die = die->next;
child_die = die->child;
while (child_die && child_die->tag)
{
process_die (child_die, objfile, cu_header);
@ -2259,9 +2270,9 @@ read_lexical_block_scope (struct die_info *die, struct objfile *objfile,
highpc += baseaddr;
push_context (0, lowpc);
if (die->has_children)
if (die->child != NULL)
{
child_die = die->next;
child_die = die->child;
while (child_die && child_die->tag)
{
process_die (child_die, objfile, cu_header);
@ -2936,7 +2947,7 @@ read_structure_scope (struct die_info *die, struct objfile *objfile,
type within the structure itself. */
die->type = type;
if (die->has_children && ! die_is_declaration (die))
if (die->child != NULL && ! die_is_declaration (die))
{
struct field_info fi;
struct die_info *child_die;
@ -2944,7 +2955,7 @@ read_structure_scope (struct die_info *die, struct objfile *objfile,
memset (&fi, 0, sizeof (struct field_info));
child_die = die->next;
child_die = die->child;
while (child_die && child_die->tag)
{
@ -3082,9 +3093,9 @@ read_enumeration (struct die_info *die, struct objfile *objfile,
num_fields = 0;
fields = NULL;
if (die->has_children)
if (die->child != NULL)
{
child_die = die->next;
child_die = die->child;
while (child_die && child_die->tag)
{
if (child_die->tag != DW_TAG_enumerator)
@ -3163,7 +3174,7 @@ read_array_type (struct die_info *die, struct objfile *objfile,
/* Irix 6.2 native cc creates array types without children for
arrays with unspecified length. */
if (die->has_children == 0)
if (die->child == NULL)
{
index_type = dwarf2_fundamental_type (objfile, FT_INTEGER);
range_type = create_range_type (NULL, index_type, 0, -1);
@ -3172,7 +3183,7 @@ read_array_type (struct die_info *die, struct objfile *objfile,
}
back_to = make_cleanup (null_cleanup, NULL);
child_die = die->next;
child_die = die->child;
while (child_die && child_die->tag)
{
if (child_die->tag == DW_TAG_subrange_type)
@ -3324,9 +3335,9 @@ read_common_block (struct die_info *die, struct objfile *objfile,
"common block member");
}
}
if (die->has_children)
if (die->child != NULL)
{
child_die = die->next;
child_die = die->child;
while (child_die && child_die->tag)
{
sym = new_symbol (child_die, NULL, objfile, cu_header);
@ -3412,9 +3423,9 @@ read_namespace (struct die_info *die, struct objfile *objfile,
strlen (processing_current_namespace));
}
if (die->has_children)
if (die->child != NULL)
{
struct die_info *child_die = die->next;
struct die_info *child_die = die->child;
while (child_die && child_die->tag)
{
@ -3649,7 +3660,7 @@ read_subroutine_type (struct die_info *die, struct objfile *objfile,
|| cu_language == language_cplus)
TYPE_FLAGS (ftype) |= TYPE_FLAG_PROTOTYPED;
if (die->has_children)
if (die->child != NULL)
{
struct die_info *child_die;
int nparams = 0;
@ -3658,7 +3669,7 @@ read_subroutine_type (struct die_info *die, struct objfile *objfile,
/* Count the number of parameters.
FIXME: GDB currently ignores vararg functions, but knows about
vararg member functions. */
child_die = die->next;
child_die = die->child;
while (child_die && child_die->tag)
{
if (child_die->tag == DW_TAG_formal_parameter)
@ -3673,7 +3684,7 @@ read_subroutine_type (struct die_info *die, struct objfile *objfile,
TYPE_FIELDS (ftype) = (struct field *)
TYPE_ALLOC (ftype, nparams * sizeof (struct field));
child_die = die->next;
child_die = die->child;
while (child_die && child_die->tag)
{
if (child_die->tag == DW_TAG_formal_parameter)
@ -3808,46 +3819,89 @@ static struct die_info *
read_comp_unit (char *info_ptr, bfd *abfd,
const struct comp_unit_head *cu_header)
{
struct die_info *first_die, *last_die, *die;
char *cur_ptr;
int nesting_level;
/* Reset die reference table; we are
building new ones now. */
dwarf2_empty_hash_tables ();
cur_ptr = info_ptr;
nesting_level = 0;
first_die = last_die = NULL;
do
return read_die_and_children (info_ptr, abfd, cu_header, &info_ptr, NULL);
}
/* Read a single die and all its descendents. Set the die's sibling
field to NULL; set other fields in the die correctly, and set all
of the descendents' fields correctly. Set *NEW_INFO_PTR to the
location of the info_ptr after reading all of those dies. PARENT
is the parent of the die in question. */
static struct die_info *
read_die_and_children (char *info_ptr, bfd *abfd,
const struct comp_unit_head *cu_header,
char **new_info_ptr,
struct die_info *parent)
{
struct die_info *die;
char *cur_ptr;
int has_children;
cur_ptr = read_full_die (&die, abfd, info_ptr, cu_header, &has_children);
store_in_ref_table (die->offset, die);
if (has_children)
{
cur_ptr = read_full_die (&die, abfd, cur_ptr, cu_header);
if (die->has_children)
{
nesting_level++;
}
if (die->tag == 0)
{
nesting_level--;
}
die->child = read_die_and_siblings (cur_ptr, abfd, cu_header,
new_info_ptr, die);
}
else
{
die->child = NULL;
*new_info_ptr = cur_ptr;
}
die->next = NULL;
die->sibling = NULL;
die->parent = parent;
return die;
}
/* Enter die in reference hash table */
store_in_ref_table (die->offset, die);
/* Read a die, all of its descendents, and all of its siblings; set
all of the fields of all of the dies correctly. Arguments are as
in read_die_and_children. */
static struct die_info *
read_die_and_siblings (char *info_ptr, bfd *abfd,
const struct comp_unit_head *cu_header,
char **new_info_ptr,
struct die_info *parent)
{
struct die_info *first_die, *last_sibling;
char *cur_ptr;
cur_ptr = info_ptr;
first_die = last_sibling = NULL;
while (1)
{
struct die_info *die
= read_die_and_children (cur_ptr, abfd, cu_header,
&cur_ptr, parent);
if (!first_die)
{
first_die = last_die = die;
first_die = die;
}
else
{
last_die->next = die;
last_die = die;
last_sibling->sibling = die;
}
if (die->tag == 0)
{
*new_info_ptr = cur_ptr;
return first_die;
}
else
{
last_sibling = die;
}
}
while (nesting_level > 0);
return first_die;
}
/* Free a linked list of dies. */
@ -3860,7 +3914,9 @@ free_die_list (struct die_info *dies)
die = dies;
while (die)
{
next = die->next;
if (die->child != NULL)
free_die_list (die->child);
next = die->sibling;
xfree (die->attrs);
xfree (die);
die = next;
@ -4173,12 +4229,14 @@ read_partial_die (struct partial_die_info *part_die, bfd *abfd,
return info_ptr;
}
/* Read the die from the .debug_info section buffer. And set diep to
point to a newly allocated die with its information. */
/* Read the die from the .debug_info section buffer. Set DIEP to
point to a newly allocated die with its information, except for its
child, sibling, and parent fields. Set HAS_CHILDREN to tell
whether the die has children or not. */
static char *
read_full_die (struct die_info **diep, bfd *abfd, char *info_ptr,
const struct comp_unit_head *cu_header)
const struct comp_unit_head *cu_header, int *has_children)
{
unsigned int abbrev_number, bytes_read, i, offset;
struct abbrev_info *abbrev;
@ -4194,19 +4252,20 @@ read_full_die (struct die_info **diep, bfd *abfd, char *info_ptr,
die->abbrev = abbrev_number;
die->type = NULL;
*diep = die;
*has_children = 0;
return info_ptr;
}
abbrev = dwarf2_lookup_abbrev (abbrev_number, cu_header);
if (!abbrev)
{
error ("Dwarf Error: could not find abbrev number %d [in module %s]", abbrev_number,
bfd_get_filename (abfd));
error ("Dwarf Error: could not find abbrev number %d [in module %s]",
abbrev_number,
bfd_get_filename (abfd));
}
die = dwarf_alloc_die ();
die->offset = offset;
die->tag = abbrev->tag;
die->has_children = abbrev->has_children;
die->abbrev = abbrev_number;
die->type = NULL;
@ -4221,6 +4280,7 @@ read_full_die (struct die_info **diep, bfd *abfd, char *info_ptr,
}
*diep = die;
*has_children = abbrev->has_children;
return info_ptr;
}
@ -5822,43 +5882,7 @@ copy_die (struct die_info *old_die)
static struct die_info *
sibling_die (struct die_info *die)
{
int nesting_level = 0;
if (!die->has_children)
{
if (die->next && (die->next->tag == 0))
{
return NULL;
}
else
{
return die->next;
}
}
else
{
do
{
if (die->has_children)
{
nesting_level++;
}
if (die->tag == 0)
{
nesting_level--;
}
die = die->next;
}
while (nesting_level);
if (die && (die->tag == 0))
{
return NULL;
}
else
{
return die;
}
}
return die->sibling;
}
/* Get linkage name of a die, return NULL if not found. */
@ -6727,7 +6751,7 @@ dump_die (struct die_info *die)
fprintf_unfiltered (gdb_stderr, "Die: %s (abbrev = %d, offset = %d)\n",
dwarf_tag_name (die->tag), die->abbrev, die->offset);
fprintf_unfiltered (gdb_stderr, "\thas children: %s\n",
dwarf_bool_name (die->has_children));
dwarf_bool_name (die->child != NULL));
fprintf_unfiltered (gdb_stderr, "\tattributes:\n");
for (i = 0; i < die->num_attrs; ++i)
@ -6790,7 +6814,10 @@ dump_die_list (struct die_info *die)
while (die)
{
dump_die (die);
die = die->next;
if (die->child != NULL)
dump_die_list (die->child);
if (die->sibling != NULL)
dump_die_list (die->sibling);
}
}