]> git.ipfire.org Git - thirdparty/binutils-gdb.git/commitdiff
2003-06-12 David Carlton <carlton@kealia.com>
authorDavid Carlton <carlton@bactrian.org>
Thu, 12 Jun 2003 18:45:48 +0000 (18:45 +0000)
committerDavid Carlton <carlton@bactrian.org>
Thu, 12 Jun 2003 18:45:48 +0000 (18:45 +0000)
* dwarf2read.c (die_specification): New.
(determine_prefix): Fix memory management.
(read_structure_scope): Set prefix correctly if getting type via
specification.

gdb/ChangeLog
gdb/dwarf2read.c

index ea4253109395f8335f56fd99078e03412d7a935f..040950dbc593f3c7cdaa2117102f650bba707d1e 100644 (file)
@@ -1,3 +1,10 @@
+2003-06-12  David Carlton  <carlton@kealia.com>
+
+       * dwarf2read.c (die_specification): New.
+       (determine_prefix): Fix memory management.
+       (read_structure_scope): Set prefix correctly if getting type via
+       specification.
+
 2003-05-28  David Carlton  <carlton@bactrian.org>
 
        * dwarf2read.c (add_partial_structure): When looking for a
index 276163ad80b1249b989d7f52774e1c1f5214a81a..17ab37498ebc1d9793db662d14e399c6024b5ac8 100644 (file)
@@ -776,6 +776,8 @@ static struct attribute *dwarf_attr (struct die_info *, unsigned int);
 
 static int die_is_declaration (struct die_info *);
 
+static struct die_info *die_specification (struct die_info *die);
+
 static void free_line_header (struct line_header *lh);
 
 static struct line_header *(dwarf_decode_line_header
@@ -3003,6 +3005,7 @@ read_structure_scope (struct die_info *die, struct objfile *objfile,
   struct attribute *attr;
   const char *name;
   const char *previous_prefix = processing_current_prefix;
+  struct cleanup *back_to = NULL;
   /* This says whether or not we want to try to update the structure's
      name to include enclosing namespace/class information, if
      any.  */
@@ -3014,6 +3017,18 @@ read_structure_scope (struct die_info *die, struct objfile *objfile,
   name = dwarf2_name (die);
   if (name != NULL)
     {
+      if (cu_language == language_cplus)
+       {
+         struct die_info *spec_die = die_specification (die);
+
+         if (spec_die != NULL)
+           {
+             char *specification_prefix = determine_prefix (spec_die);
+             processing_current_prefix = specification_prefix;
+             back_to = make_cleanup (xfree, specification_prefix);
+           }
+       }
+
       if (processing_has_namespace_info)
        {
          /* FIXME: carlton/2002-11-26: This variable exists only for
@@ -3022,8 +3037,8 @@ read_structure_scope (struct die_info *die, struct objfile *objfile,
             of changes which would have forced decode_line_1 to take
             a const char **.  */
          char *new_prefix = obconcat (&objfile->type_obstack,
-                                      previous_prefix,
-                                      previous_prefix[0] == '\0'
+                                      processing_current_prefix,
+                                      processing_current_prefix[0] == '\0'
                                       ? "" : "::",
                                       name);
          TYPE_TAG_NAME (type) = new_prefix;
@@ -3200,6 +3215,8 @@ read_structure_scope (struct die_info *die, struct objfile *objfile,
     }
 
   processing_current_prefix = previous_prefix;
+  if (back_to != NULL)
+    do_cleanups (back_to);
 }
 
 /* Given a pointer to a die which begins an enumeration, process all
@@ -4950,6 +4967,19 @@ die_is_declaration (struct die_info *die)
          && ! dwarf_attr (die, DW_AT_specification));
 }
 
+/* Returns the die giving the specification for this one, or NULL if
+   none.  */
+
+static struct die_info *
+die_specification (struct die_info *die)
+{
+  struct attribute *spec_attr = dwarf_attr (die, DW_AT_specification);
+
+  if (spec_attr == NULL)
+    return NULL;
+  else
+    return follow_die_ref (dwarf2_get_ref_die_offset (spec_attr));
+}
 
 /* Free the line_header structure *LH, and any arrays and strings it
    refers to.  */
@@ -6023,15 +6053,17 @@ determine_prefix (struct die_info *die)
   else
     {
       char *parent_prefix = determine_prefix (parent);
+      char *retval;
 
       switch (parent->tag) {
       case DW_TAG_namespace:
        {
          int dummy;
 
-         return typename_concat (parent_prefix,
-                                 namespace_name (parent, &dummy));
+         retval = typename_concat (parent_prefix,
+                                   namespace_name (parent, &dummy));
        }
+       break;
       case DW_TAG_class_type:
       case DW_TAG_structure_type:
        {
@@ -6040,19 +6072,25 @@ determine_prefix (struct die_info *die)
              const char *parent_name = dwarf2_name (parent);
 
              if (parent_name != NULL)
-               return typename_concat (parent_prefix, dwarf2_name (parent));
+               retval = typename_concat (parent_prefix, dwarf2_name (parent));
              else
                /* FIXME: carlton/2003-05-28: I'm not sure what the
                   best thing to do here is.  */
-               return typename_concat (parent_prefix,
-                                       "<<anonymous class>>");
+               retval = typename_concat (parent_prefix,
+                                         "<<anonymous class>>");
            }
          else
-           return class_name (parent);
+           retval = class_name (parent);
        }
+       break;
       default:
-       return parent_prefix;
+       retval = parent_prefix;
+       break;
       }
+
+      if (retval != parent_prefix)
+       xfree (parent_prefix);
+      return retval;
     }
 }