2003-09-30 David Carlton <carlton@kealia.com>
authorDavid Carlton <carlton@bactrian.org>
Tue, 30 Sep 2003 22:29:28 +0000 (22:29 +0000)
committerDavid Carlton <carlton@bactrian.org>
Tue, 30 Sep 2003 22:29:28 +0000 (22:29 +0000)
* 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
gdb/dwarf2read.c

index 8ebd90d..720229b 100644 (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
index bb614e5..3c3ec91 100644 (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 ();
 
+  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);
     }
 }