diff options
-rw-r--r-- | gdb/ChangeLog | 6 | ||||
-rw-r--r-- | gdb/cp-valprint.c | 9 | ||||
-rw-r--r-- | gdb/values.c | 60 |
3 files changed, 64 insertions, 11 deletions
diff --git a/gdb/ChangeLog b/gdb/ChangeLog index a6d2267..adf4bcd 100644 --- a/gdb/ChangeLog +++ b/gdb/ChangeLog @@ -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. diff --git a/gdb/cp-valprint.c b/gdb/cp-valprint.c index 680a75d..bde5879 100644 --- a/gdb/cp-valprint.c +++ b/gdb/cp-valprint.c @@ -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); diff --git a/gdb/values.c b/gdb/values.c index f9296c6..337dd10 100644 --- a/gdb/values.c +++ b/gdb/values.c @@ -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; |