* cp-valprint.c (cplus_print_value): Don't dump core if the
authorJim Kingdon <jkingdon@engr.sgi.com>
Fri, 30 Jul 1993 01:42:09 +0000 (01:42 +0000)
committerJim Kingdon <jkingdon@engr.sgi.com>
Fri, 30 Jul 1993 01:42:09 +0000 (01:42 +0000)
baseclass doesn't have a name.
* values.c (vb_match): New function, which finds the virtual
base class pointer even if the types are nameless.
(baseclass_{addr,offset}): Use it.

gdb/ChangeLog
gdb/cp-valprint.c
gdb/values.c

index a6d2267fed4e0c90246d2ba553a7b601b2260e3e..adf4bcd716d2f99e4cb0624b961093eef0df5388 100644 (file)
@@ -1,5 +1,11 @@
 Thu Jul 29 12:09:46 1993  Jim Kingdon  (kingdon@lioth.cygnus.com)
 
+       * cp-valprint.c (cplus_print_value): Don't dump core if the
+       baseclass doesn't have a name.
+       * values.c (vb_match): New function, which finds the virtual
+       base class pointer even if the types are nameless.
+       (baseclass_{addr,offset}): Use it.
+
        * hppa-tdep.c: Make "maintenance print unwind" command from old
        "unwind" command.
 
index 680a75dc699966a35105f64f52d17d895076b2a6..bde58797e3b63beaf767b549ec48f1da259998c7 100644 (file)
@@ -338,6 +338,7 @@ cplus_print_value (type, valaddr, stream, format, recurse, pretty, dont_print)
     {
       char *baddr;
       int err;
+      char *basename = TYPE_NAME (TYPE_BASECLASS (type, i));
 
       if (BASETYPE_VIA_VIRTUAL (type, i))
        {
@@ -357,8 +358,8 @@ cplus_print_value (type, valaddr, stream, format, recurse, pretty, dont_print)
       /* Fix to use baseclass_offset instead. FIXME */
       baddr = baseclass_addr (type, i, valaddr, 0, &err);
       if (err == 0 && baddr == 0)
-       error ("could not find virtual baseclass `%s'\n",
-              type_name_no_tag (TYPE_BASECLASS (type, i)));
+       error ("could not find virtual baseclass %s\n",
+              basename ? basename : "");
 
       if (pretty)
        {
@@ -366,7 +367,9 @@ cplus_print_value (type, valaddr, stream, format, recurse, pretty, dont_print)
          print_spaces_filtered (2 * recurse, stream);
        }
       fputs_filtered ("<", stream);
-      fputs_filtered (type_name_no_tag (TYPE_BASECLASS (type, i)), stream);
+      /* Not sure what the best notation is in the case where there is no
+        baseclass name.  */
+      fputs_filtered (basename ? basename : "", stream);
       fputs_filtered ("> = ", stream);
       if (err != 0)
        fprintf_filtered (stream, "<invalid address 0x%x>", baddr);
index f9296c67057af1b3f12100b1264cf037dd573f0b..337dd10b666d54e9b6e3ba24ed3d4a42acefdc0b 100644 (file)
@@ -991,6 +991,56 @@ value_from_vtable_info (arg, type)
   return value_headof (arg, 0, type);
 }
 
+/* Return true if the INDEXth field of TYPE is a virtual baseclass
+   pointer which is for the base class whose type is BASECLASS.  */
+
+static int
+vb_match (type, index, basetype)
+     struct type *type;
+     int index;
+     struct type *basetype;
+{
+  struct type *fieldtype;
+  struct type *fieldtype_target_type;
+  char *name = TYPE_FIELD_NAME (type, index);
+  char *field_class_name = NULL;
+
+  if (*name != '_')
+    return 0;
+  /* gcc 2.4 uses _vb$.  */
+  if (name[1] == 'v' && name[2] == 'b' && name[3] == CPLUS_MARKER)
+    field_class_name = name + 4;
+  /* gcc 2.5 will use __vb_.  */
+  if (name[1] == '_' && name[2] == 'v' && name[3] == 'b' && name[4] == '_')
+    field_class_name = name + 5;
+
+  if (field_class_name == NULL)
+    /* This field is not a virtual base class pointer.  */
+    return 0;
+
+  /* It's a virtual baseclass pointer, now we just need to find out whether
+     it is for this baseclass.  */
+  fieldtype = TYPE_FIELD_TYPE (type, index);
+  if (fieldtype == NULL
+      || TYPE_CODE (fieldtype) != TYPE_CODE_PTR)
+    /* "Can't happen".  */
+    return 0;
+
+  /* What we check for is that either the types are equal (needed for
+     nameless types) or have the same name.  This is ugly, and a more
+     elegant solution should be devised (which would probably just push
+     the ugliness into symbol reading unless we change the stabs format).  */
+  if (TYPE_TARGET_TYPE (fieldtype) == basetype)
+    return 1;
+
+  if (TYPE_NAME (basetype) != NULL
+      && TYPE_NAME (TYPE_TARGET_TYPE (fieldtype)) != NULL
+      && STREQ (TYPE_NAME (basetype),
+               TYPE_NAME (TYPE_TARGET_TYPE (fieldtype))))
+    return 1;
+  return 0;
+}
+
 /* Compute the offset of the baseclass which is
    the INDEXth baseclass of class TYPE, for a value ARG,
    wih extra offset of OFFSET.
@@ -1013,15 +1063,12 @@ baseclass_offset (type, index, arg, offset)
       /* Must hunt for the pointer to this virtual baseclass.  */
       register int i, len = TYPE_NFIELDS (type);
       register int n_baseclasses = TYPE_N_BASECLASSES (type);
-      char *vbase_name, *type_name = type_name_no_tag (basetype);
 
-      vbase_name = (char *)alloca (strlen (type_name) + 8);
-      sprintf (vbase_name, "_vb%c%s", CPLUS_MARKER, type_name);
       /* First look for the virtual baseclass pointer
         in the fields.  */
       for (i = n_baseclasses; i < len; i++)
        {
-         if (STREQ (vbase_name, TYPE_FIELD_NAME (type, i)))
+         if (vb_match (type, i, basetype))
            {
              CORE_ADDR addr
                = unpack_pointer (TYPE_FIELD_TYPE (type, i),
@@ -1081,15 +1128,12 @@ baseclass_addr (type, index, valaddr, valuep, errp)
       /* Must hunt for the pointer to this virtual baseclass.  */
       register int i, len = TYPE_NFIELDS (type);
       register int n_baseclasses = TYPE_N_BASECLASSES (type);
-      char *vbase_name, *type_name = type_name_no_tag (basetype);
 
-      vbase_name = (char *)alloca (strlen (type_name) + 8);
-      sprintf (vbase_name, "_vb%c%s", CPLUS_MARKER, type_name);
       /* First look for the virtual baseclass pointer
         in the fields.  */
       for (i = n_baseclasses; i < len; i++)
        {
-         if (STREQ (vbase_name, TYPE_FIELD_NAME (type, i)))
+         if (vb_match (type, i, basetype))
            {
              value val = allocate_value (basetype);
              CORE_ADDR addr;