From 639d11d30824e0fb7f9585400eac60534cd7fc9a Mon Sep 17 00:00:00 2001 From: David Carlton Date: Tue, 30 Sep 2003 22:29:28 +0000 Subject: [PATCH] 2003-09-30 David Carlton * 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. --- gdb/ChangeLog | 20 +++++ gdb/dwarf2read.c | 219 ++++++++++++++++++++++++++--------------------- 2 files changed, 143 insertions(+), 96 deletions(-) diff --git a/gdb/ChangeLog b/gdb/ChangeLog index 8ebd90d09f5..720229bcd64 100644 --- a/gdb/ChangeLog +++ b/gdb/ChangeLog @@ -1,3 +1,23 @@ +2003-09-30 David Carlton + + * 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 * rs6000-tdep.c (rs6000_gdbarch_init): Set the PowerOpen red zone diff --git a/gdb/dwarf2read.c b/gdb/dwarf2read.c index bb614e5ef9a..3c3ec918ef1 100644 --- a/gdb/dwarf2read.c +++ b/gdb/dwarf2read.c @@ -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 (); + 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) + { + 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->sibling = NULL; + die->parent = parent; + return 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; - nesting_level = 0; - first_die = last_die = NULL; - do + first_die = last_sibling = NULL; + + while (1) { - cur_ptr = read_full_die (&die, abfd, cur_ptr, cu_header); - if (die->has_children) + struct die_info *die + = read_die_and_children (cur_ptr, abfd, cu_header, + &cur_ptr, parent); + + if (!first_die) { - nesting_level++; + first_die = die; } - if (die->tag == 0) + else { - nesting_level--; + last_sibling->sibling = die; } - die->next = NULL; - - /* Enter die in reference hash table */ - store_in_ref_table (die->offset, die); - - if (!first_die) + if (die->tag == 0) { - first_die = last_die = die; + *new_info_ptr = cur_ptr; + return first_die; } else { - last_die->next = die; - last_die = die; + 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); } } -- 2.30.2