Various fixes to improve g++ debugging. See ChangeLog.

This commit is contained in:
Per Bothner 1991-10-26 02:05:14 +00:00
parent 5ab580ccf8
commit bcccec8c8d
6 changed files with 134 additions and 97 deletions

View 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

View 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');

View 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))
{
/* Need a new type prefix. */
char *strchr ();
char *newname = type_name_no_tag (type);
char buf[20];
int len;
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);
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". */
strncpy (mangled_name, field_name, 3);
mangled_name[3] = '\0';
strcat (mangled_name, opname);
}
return mangled_typename;
else
{
mangled_name = (char *)xmalloc (mangled_name_len);
strcpy (mangled_name, TYPE_FN_FIELDLIST_NAME (type, i));
}
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.

View 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

View 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);

View 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;