Various fixes to improve g++ debugging. See ChangeLog.
authorPer Bothner <per@bothner.com>
Sat, 26 Oct 1991 02:05:14 +0000 (02:05 +0000)
committerPer Bothner <per@bothner.com>
Sat, 26 Oct 1991 02:05:14 +0000 (02:05 +0000)
gdb/ChangeLog
gdb/dbxread.c
gdb/symtab.c
gdb/symtab.h
gdb/valprint.c
gdb/values.c

index 89099cd855976a6f78c740d9c79b42adb77067c3..139a92433a0f622a637e58bde6a10b29389bc1c1 100644 (file)
@@ -1,3 +1,28 @@
+Fri Oct 25 18:59:32 1991  Per Bothner  (bothner at cygnus.com)
+
+       Various fixes to improve g++ debugging.
+       * symtab.h:  Add is_const and is_volatile flags for each method.
+       These are bit fields - take their space from voffset,
+       which shrinks to 30 bits.  Since voffset is now a bitfield,
+       make it unsigned for portability.  This changes its interpretation
+       slightly:  Static methods now have voffset 1 instead of -1,
+       and virtual offsets start at 2, not 1.
+       * symtab.c:  Renamed gdb_mangle_typename to gdb_mangle_name,
+       since it now returns an entire magled method name, not just
+       the type part.  This avoids some duplication.
+       It also allows us to correctly mangle const and volatile
+       methods (using the new is_const and is_volatile bit fields
+       mentioned above).
+       * valprint.c (type_print_base), values.c (check_stub_method):
+       Simplify by using new gdb_mangle_name.
+       * values.c (value_headof):  Fix to correctly handle single
+       inheritance (actually two fixes, either of which suffices).
+       * dbxread.c (read_struct_type):  Handle const and volatile
+       method specifiers.
+       * dbxread.c (read_struct_type):  Yet one more place where
+       we must handle '\\' continuations.
+       * valprint.c (vtbl_ptr_name): Add final '\0'.
+
 Fri Oct 25 16:06:38 1991  Stu Grossman  (grossman at cygnus.com)
 
        * tm-sparc.h, tm-68k.h (EXTRACT_RETURN_VALUE):  fix output of
index dbb786a9ae8251a2d164359f0d3a43f2d1acca30..7fb59c7f0c1ff6620374e13bd933561e4edd3d15 100644 (file)
@@ -4628,21 +4628,33 @@ read_struct_type (pp, type)
              *pp = p + 1;
              new_sublist->visibility = *(*pp)++ - '0';
              if (**pp == '\\') *pp = next_symbol_text ();
-             /* FIXME-tiemann: need to add const/volatile info
-                to the methods.  For now, just skip the char.
-                In future, here's what we need to implement:
-
-                A for normal functions.
-                B for `const' member functions.
-                C for `volatile' member functions.
-                D for `const volatile' member functions.  */
-             if (**pp == 'A' || **pp == 'B' || **pp == 'C' || **pp == 'D')
-               (*pp)++;
-
-             /* This probably just means we're processing a file compiled
-                with g++ version 1.  */
-             else
-               complain(&const_vol_complaint, **pp);
+             switch (**pp)
+               {
+               case 'A': /* Normal functions. */
+                 new_sublist->fn_field.is_const = 0;
+                 new_sublist->fn_field.is_volatile = 0;
+                 (*pp)++;
+                 break;
+               case 'B': /* `const' member functions. */
+                 new_sublist->fn_field.is_const = 1;
+                 new_sublist->fn_field.is_volatile = 0;
+                 (*pp)++;
+                 break;
+               case 'C': /* `volatile' member function. */
+                 new_sublist->fn_field.is_const = 0;
+                 new_sublist->fn_field.is_volatile = 1;
+                 (*pp)++;
+                 break;
+               case 'D': /* `const volatile' member function. */
+                 new_sublist->fn_field.is_const = 1;
+                 new_sublist->fn_field.is_volatile = 1;
+                 (*pp)++;
+                 break;
+               default:
+                 /* This probably just means we're processing a file compiled
+                    with g++ version 1.  */
+                 complain(&const_vol_complaint, **pp);
+               }
 
              switch (*(*pp)++)
                {
@@ -4655,7 +4667,7 @@ read_struct_type (pp, type)
                     the sign bit out, and usable as a valid index into
                     the array.  Remove the sign bit here.  */
                  new_sublist->fn_field.voffset =
-                     (0x7fffffff & read_number (pp, ';')) + 1;
+                     (0x7fffffff & read_number (pp, ';')) + 2;
 
                  if (**pp == '\\') *pp = next_symbol_text ();
 
@@ -4697,6 +4709,7 @@ read_struct_type (pp, type)
              new_sublist->next = sublist;
              sublist = new_sublist;
              length++;
+             if (**pp == '\\') *pp = next_symbol_text ();
            }
          while (**pp != ';' && **pp != '\0');
 
index 0a53dcc2111fd759aa1441d40c82cd3d326c58cb..81f7ec10218a8151f317b3d2b9e0dd019d7a9ea4 100644 (file)
@@ -41,6 +41,7 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.  */
 extern char *getenv ();
 
 extern char *cplus_demangle ();
+extern char *cplus_mangle_opname ();
 extern struct value *value_of_this ();
 extern void break_command ();
 extern void select_source_symtab ();
@@ -224,31 +225,52 @@ check_stub_type(type)
 
 /* Demangle a GDB method stub type.  */
 char *
-gdb_mangle_typename (type)
+gdb_mangle_name (type, i, j)
      struct type *type;
+     int i, j;
 {
-  static struct type *last_type;
-  static char *mangled_typename;
+  int mangled_name_len;
+  char *mangled_name;
+  struct fn_field *f = TYPE_FN_FIELDLIST1 (type, i);
+  struct fn_field *method = &f[j];
+  char *field_name = TYPE_FN_FIELDLIST_NAME (type, i);
 
-  if (type != last_type)
+  /* Need a new type prefix.  */
+  char *strchr ();
+  char *const_prefix = method->is_const ? "C" : "";
+  char *volatile_prefix = method->is_volatile ? "V" : "";
+  char *newname = type_name_no_tag (type);
+  char buf[20];
+  int len = strlen (newname);
+
+  sprintf (buf, "__%s%s%d", const_prefix, volatile_prefix, len);
+  mangled_name_len = (strlen (field_name)
+                         + strlen (buf) + len
+                         + strlen (TYPE_FN_FIELD_PHYSNAME (f, j))
+                         + 1);
+
+  if (OPNAME_PREFIX_P (field_name))
+    {
+      char *opname = cplus_mangle_opname (field_name + 3);
+      if (opname == NULL)
+       error ("No mangling for \"%s\"", field_name);
+      mangled_name_len += strlen (opname);
+      mangled_name = (char *)xmalloc (mangled_name_len);
+
+      strncpy (mangled_name, field_name, 3);
+      mangled_name[3] = '\0';
+      strcat (mangled_name, opname);
+    }
+  else
     {
-      /* Need a new type prefix.  */
-      char *strchr ();
-      char *newname = type_name_no_tag (type);
-      char buf[20];
-      int len;
-
-      if (mangled_typename)
-       free (mangled_typename);
-
-      len = strlen (newname);
-      sprintf (buf, "__%d", len);
-      mangled_typename = (char *)xmalloc (strlen (buf) + len + 1);
-      strcpy (mangled_typename, buf);
-      strcat (mangled_typename, newname);
-      /* Now we have built "__#newname".  */
+      mangled_name = (char *)xmalloc (mangled_name_len);
+      strcpy (mangled_name, TYPE_FN_FIELDLIST_NAME (type, i));
     }
-  return mangled_typename;
+  strcat (mangled_name, buf);
+  strcat (mangled_name, newname);
+  strcat (mangled_name, TYPE_FN_FIELD_PHYSNAME (f, j));
+
+  return mangled_name;
 }
 
 /* Lookup a primitive type named NAME. 
index 1f8ff418acc8d859a8a8e6842b886aa21a4dd54d..d220a8398ba7fd48f93eb2933e48784142c660dc 100644 (file)
@@ -247,10 +247,12 @@ struct type
          /* For virtual functions.   */
          /* First baseclass that defines this virtual function.   */
          struct type *fcontext;
+         unsigned int is_const : 1;
+         unsigned int is_volatile : 1;
          /* Index into that baseclass's virtual function table,
-            minus 1; else if static: VOFFSET_STATIC; else: 0.  */
-         int voffset;
-#        define VOFFSET_STATIC (-1)
+            minus 2; else if static: VOFFSET_STATIC; else: 0.  */
+         unsigned long voffset : 30;
+#        define VOFFSET_STATIC 1
        } *fn_fields;
 
       B_TYPE *private_fn_field_bits;
@@ -729,9 +731,9 @@ int current_source_line;
 #define TYPE_FN_FIELD_TYPE(thistype, n) (thistype)[n].type
 #define TYPE_FN_FIELD_ARGS(thistype, n) TYPE_ARG_TYPES ((thistype)[n].type)
 #define TYPE_FN_FIELD_PHYSNAME(thistype, n) (thistype)[n].physname
-#define TYPE_FN_FIELD_VIRTUAL_P(thistype, n) ((thistype)[n].voffset > 0)
+#define TYPE_FN_FIELD_VIRTUAL_P(thistype, n) ((thistype)[n].voffset > 1)
 #define TYPE_FN_FIELD_STATIC_P(thistype, n) ((thistype)[n].voffset == VOFFSET_STATIC)
-#define TYPE_FN_FIELD_VOFFSET(thistype, n) ((thistype)[n].voffset-1)
+#define TYPE_FN_FIELD_VOFFSET(thistype, n) ((thistype)[n].voffset-2)
 #define TYPE_FN_FIELD_FCONTEXT(thistype, n) ((thistype)[n].fcontext)
 
 #define TYPE_FN_PRIVATE_BITS(thistype) (thistype).private_fn_field_bits
index f893eda4d3eb30749ecd287397f7eca0daed7a5a..d10b55dea3ce43213a761b1ac26fe464dfc77ce1 100644 (file)
@@ -409,7 +409,7 @@ is_vtbl_ptr_type(type)
 {
   char *typename = TYPE_NAME(type);
   static const char vtbl_ptr_name[] =
-    { CPLUS_MARKER,'v','t','b','l','_','p','t','r','_','t','y','p','e' };
+    { CPLUS_MARKER,'v','t','b','l','_','p','t','r','_','t','y','p','e', 0 };
 
   return (typename != NULL && !strcmp(typename, vtbl_ptr_name));
 }
@@ -1718,18 +1718,9 @@ type_print_base (type, stream, show, level)
                  if (TYPE_FLAGS (TYPE_FN_FIELD_TYPE (f, j)) & TYPE_FLAG_STUB)
                    {
                      /* Build something we can demangle.  */
-                     char *strchr (), *gdb_mangle_typename ();
-                     char *inner_name = gdb_mangle_typename (type);
-                     char *mangled_name
-                       = (char *)xmalloc (strlen (TYPE_FN_FIELDLIST_NAME (type, i))
-                                         + strlen (inner_name)
-                                         + strlen (TYPE_FN_FIELD_PHYSNAME (f, j))
-                                         + 1);
-                     char *demangled_name, *cplus_demangle ();
-                     strcpy (mangled_name, TYPE_FN_FIELDLIST_NAME (type, i));
-                     strcat (mangled_name, inner_name);
-                     strcat (mangled_name, TYPE_FN_FIELD_PHYSNAME (f, j));
-                     demangled_name = cplus_demangle (mangled_name, 1);
+                     char *strchr (), *gdb_mangle_name (), *cplus_demangle ();
+                     char *mangled_name = gdb_mangle_name (type, i, j);
+                     char *demangled_name = cplus_demangle (mangled_name, 1);
                      if (demangled_name == 0)
                        fprintf_filtered (stream, " <badly mangled name %s>",
                            mangled_name);
index 0f5e1e7c364bd33abe71260002720c79dfee64b3..a5b2c69f6c2eac22280426d685787d515a966e20 100644 (file)
@@ -29,7 +29,6 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.  */
 #include "gdbcmd.h"
 
 extern char *cplus_demangle ();
-extern char *cplus_mangle_opname ();
 
 /* The value-history records all the values printed
    by print commands during this session.  Each chunk
@@ -995,7 +994,6 @@ value_headof (arg, btype, dtype)
   struct symbol *sym;
   CORE_ADDR pc_for_sym;
   char *demangled_name;
-
   btype = TYPE_VPTR_BASETYPE (dtype);
   check_stub_type (btype);
   if (btype != dtype)
@@ -1006,7 +1004,7 @@ value_headof (arg, btype, dtype)
 
   /* Check that VTBL looks like it points to a virtual function table.  */
   i = find_pc_misc_function (VALUE_ADDRESS (vtbl));
-  if (i < 0 || ! VTBL_PREFIX_P (misc_function_vector[i].name))
+  if (i < 0 || ! VTBL_PREFIX_P (demangled_name = misc_function_vector[i].name))
     {
       /* If we expected to find a vtable, but did not, let the user
         know that we aren't happy, but don't throw an error.
@@ -1026,27 +1024,40 @@ value_headof (arg, btype, dtype)
       entry = value_subscript (vtbl, value_from_longest (builtin_type_int, 
                                                      (LONGEST) i));
       offset = longest_to_int (value_as_long (value_field (entry, 0)));
-      if (offset < best_offset)
+      /* If we use '<=' we can handle single inheritance
+       * where all offsets are zero - just use the first entry found. */
+      if (offset <= best_offset)
        {
          best_offset = offset;
          best_entry = entry;
        }
     }
-  if (best_entry == 0)
-    return arg;
-
   /* Move the pointer according to BEST_ENTRY's offset, and figure
      out what type we should return as the new pointer.  */
-  pc_for_sym = value_as_pointer (value_field (best_entry, 2));
-  sym = find_pc_function (pc_for_sym);
-  demangled_name = cplus_demangle (SYMBOL_NAME (sym), -1);
-  *(strchr (demangled_name, ':')) = '\0';
+  if (best_entry == 0)
+    {
+      /* An alternative method (which should no longer be necessary).
+       * But we leave it in for future use, when we will hopefully
+       * have optimizes the vtable to use thunks instead of offsets. */
+      /* Use the name of vtable itself to extract a base type. */
+      demangled_name += 4;  /* Skip _vt$ prefix. */
+    }
+  else
+    {
+      pc_for_sym = value_as_pointer (value_field (best_entry, 2));
+      sym = find_pc_function (pc_for_sym);
+      demangled_name = cplus_demangle (SYMBOL_NAME (sym), -1);
+      *(strchr (demangled_name, ':')) = '\0';
+    }
   sym = lookup_symbol (demangled_name, 0, VAR_NAMESPACE, 0, 0);
   if (sym == 0)
     error ("could not find type declaration for `%s'", SYMBOL_NAME (sym));
-  free (demangled_name);
-  arg = value_add (value_cast (builtin_type_int, arg),
-                  value_field (best_entry, 0));
+  if (best_entry)
+    {
+      free (demangled_name);
+      arg = value_add (value_cast (builtin_type_int, arg),
+                      value_field (best_entry, 0));
+    }
   VALUE_TYPE (arg) = lookup_pointer_type (SYMBOL_TYPE (sym));
   return arg;
 }
@@ -1241,41 +1252,14 @@ check_stub_method (type, i, j)
      struct type *type;
      int i, j;
 {
-  extern char *gdb_mangle_typename (), *strchr ();
+  extern char *gdb_mangle_name (), *strchr ();
   struct fn_field *f = TYPE_FN_FIELDLIST1 (type, i);
-  char *field_name = TYPE_FN_FIELDLIST_NAME (type, i);
-  char *inner_name = gdb_mangle_typename (type);
-  int mangled_name_len = (strlen (field_name)
-                         + strlen (inner_name)
-                         + strlen (TYPE_FN_FIELD_PHYSNAME (f, j))
-                         + 1);
-  char *mangled_name;
-  char *demangled_name;
+  char *mangled_name = gdb_mangle_name (type, i, j);
+  char *demangled_name = cplus_demangle (mangled_name, 0);
   char *argtypetext, *p;
   int depth = 0, argcount = 1;
   struct type **argtypes;
 
-  if (OPNAME_PREFIX_P (field_name))
-    {
-      char *opname = cplus_mangle_opname (field_name + 3);
-      if (opname == NULL)
-       error ("No mangling for \"%s\"", field_name);
-      mangled_name_len += strlen (opname);
-      mangled_name = (char *)xmalloc (mangled_name_len);
-
-      strncpy (mangled_name, field_name, 3);
-      mangled_name[3] = '\0';
-      strcat (mangled_name, opname);
-    }
-  else
-    {
-      mangled_name = (char *)xmalloc (mangled_name_len);
-      strcpy (mangled_name, TYPE_FN_FIELDLIST_NAME (type, i));
-    }
-  strcat (mangled_name, inner_name);
-  strcat (mangled_name, TYPE_FN_FIELD_PHYSNAME (f, j));
-  demangled_name = cplus_demangle (mangled_name, 0);
-
   /* Now, read in the parameters that define this type.  */
   argtypetext = strchr (demangled_name, '(') + 1;
   p = argtypetext;