X-Git-Url: http://git.efficios.com/?a=blobdiff_plain;f=gdb%2Fcp-valprint.c;h=f362d8475369202fe4771f9be4b4796dc4a48474;hb=114019bb6e6a29549f225b60e1dfda358c605367;hp=ff2bec865a83b9c11501f17552d8ba360dbe220b;hpb=ed288bb597072176e84fc8279707a3f2f475779b;p=deliverable%2Fbinutils-gdb.git diff --git a/gdb/cp-valprint.c b/gdb/cp-valprint.c index ff2bec865a..f362d84753 100644 --- a/gdb/cp-valprint.c +++ b/gdb/cp-valprint.c @@ -1,5 +1,6 @@ /* Support for printing C++ values for GDB, the GNU debugger. - Copyright 1986, 1988, 1989, 1991, 1994, 1995, 1996 + Copyright 1986, 1988, 1989, 1991, 1992, 1993, 1994, 1995, 1996, 1997, + 2000, 2001, 2002 Free Software Foundation, Inc. This file is part of GDB. @@ -20,7 +21,7 @@ Boston, MA 02111-1307, USA. */ #include "defs.h" -#include "obstack.h" +#include "gdb_obstack.h" #include "symtab.h" #include "gdbtypes.h" #include "expression.h" @@ -32,6 +33,7 @@ #include "gdb_string.h" #include "c-lang.h" #include "target.h" +#include "cp-abi.h" /* Indication of presence of HP-compiled object files */ extern int hp_som_som_object_present; /* defined in symtab.c */ @@ -45,26 +47,27 @@ int static_field_print; /* Controls printing of static fields. */ static struct obstack dont_print_vb_obstack; static struct obstack dont_print_statmem_obstack; -extern void _initialize_cp_valprint PARAMS ((void)); +extern void _initialize_cp_valprint (void); -static void -cp_print_static_field PARAMS ((struct type *, value_ptr, GDB_FILE *, int, int, - enum val_prettyprint)); +static void cp_print_static_field (struct type *, struct value *, + struct ui_file *, int, int, + enum val_prettyprint); -static void -cp_print_value PARAMS ((struct type *, struct type *, char *, int, CORE_ADDR, GDB_FILE *, - int, int, enum val_prettyprint, struct type **)); +static void cp_print_value (struct type *, struct type *, char *, int, + CORE_ADDR, struct ui_file *, int, int, + enum val_prettyprint, struct type **); -static void -cp_print_hpacc_virtual_table_entries PARAMS ((struct type *, int *, value_ptr, GDB_FILE *, - int, int, enum val_prettyprint)); +static void cp_print_hpacc_virtual_table_entries (struct type *, int *, + struct value *, + struct ui_file *, int, + int, + enum val_prettyprint); void -cp_print_class_method (valaddr, type, stream) - char *valaddr; - struct type *type; - GDB_FILE *stream; +cp_print_class_method (char *valaddr, + struct type *type, + struct ui_file *stream) { struct type *domain; struct fn_field *f = NULL; @@ -94,13 +97,11 @@ cp_print_class_method (valaddr, type, stream) f = TYPE_FN_FIELDLIST1 (domain, i); len2 = TYPE_FN_FIELDLIST_LENGTH (domain, i); + check_stub_method_group (domain, i); for (j = 0; j < len2; j++) { - QUIT; if (TYPE_FN_FIELD_VOFFSET (f, j) == offset) { - if (TYPE_FN_FIELD_STUB (f, j)) - check_stub_method (domain, i, j); kind = "virtual "; goto common; } @@ -126,19 +127,15 @@ cp_print_class_method (valaddr, type, stream) f = TYPE_FN_FIELDLIST1 (domain, i); len2 = TYPE_FN_FIELDLIST_LENGTH (domain, i); + check_stub_method_group (domain, i); for (j = 0; j < len2; j++) { - QUIT; - if (TYPE_FN_FIELD_STUB (f, j)) - check_stub_method (domain, i, j); if (STREQ (SYMBOL_NAME (sym), TYPE_FN_FIELD_PHYSNAME (f, j))) - { - goto common; - } + goto common; } } } -common: + common: if (i < len) { char *demangled_name; @@ -153,7 +150,7 @@ common: else { fputs_filtered (demangled_name, stream); - free (demangled_name); + xfree (demangled_name); } } else @@ -164,41 +161,32 @@ common: } } -/* This was what it was for gcc 2.4.5 and earlier. */ -static const char vtbl_ptr_name_old[] = -{CPLUS_MARKER, 'v', 't', 'b', 'l', '_', 'p', 't', 'r', '_', 't', 'y', 'p', 'e', 0}; -/* It was changed to this after 2.4.5. */ -const char vtbl_ptr_name[] = -{'_', '_', 'v', 't', 'b', 'l', '_', 'p', 't', 'r', '_', 't', 'y', 'p', 'e', 0}; - -/* HP aCC uses different names */ -const char hpacc_vtbl_ptr_name[] = -{'_', '_', 'v', 'f', 'p', 0}; -const char hpacc_vtbl_ptr_type_name[] = -{'_', '_', 'v', 'f', 't', 'y', 'p', 0}; +/* GCC versions after 2.4.5 use this. */ +const char vtbl_ptr_name[] = "__vtbl_ptr_type"; +/* HP aCC uses different names. */ +const char hpacc_vtbl_ptr_name[] = "__vfp"; +const char hpacc_vtbl_ptr_type_name[] = "__vftyp"; /* Return truth value for assertion that TYPE is of the type "pointer to virtual function". */ int -cp_is_vtbl_ptr_type (type) - struct type *type; +cp_is_vtbl_ptr_type (struct type *type) { char *typename = type_name_no_tag (type); - return (typename != NULL - && (STREQ (typename, vtbl_ptr_name) - || STREQ (typename, vtbl_ptr_name_old))); + return (typename != NULL && !strcmp (typename, vtbl_ptr_name)); } /* Return truth value for the assertion that TYPE is of the type "pointer to virtual function table". */ int -cp_is_vtbl_member (type) - struct type *type; +cp_is_vtbl_member (struct type *type) { + /* With older versions of g++, the vtbl field pointed to an array + of structures. Nowadays it points directly to the structure. */ if (TYPE_CODE (type) == TYPE_CODE_PTR) { type = TYPE_TARGET_TYPE (type); @@ -213,6 +201,17 @@ cp_is_vtbl_member (type) return cp_is_vtbl_ptr_type (type); } } + else if (TYPE_CODE (type) == TYPE_CODE_STRUCT) /* if not using thunks */ + { + return cp_is_vtbl_ptr_type (type); + } + else if (TYPE_CODE (type) == TYPE_CODE_PTR) /* if using thunks */ + { + /* The type name of the thunk pointer is NULL when using dwarf2. + We could test for a pointer to a function, but there is + no type info for the virtual table either, so it wont help. */ + return cp_is_vtbl_ptr_type (type); + } } return 0; } @@ -230,19 +229,10 @@ cp_is_vtbl_member (type) should not print, or zero if called from top level. */ void -cp_print_value_fields (type, real_type, valaddr, offset, address, stream, format, recurse, pretty, - dont_print_vb, dont_print_statmem) - struct type *type; - struct type *real_type; - char *valaddr; - int offset; - CORE_ADDR address; - GDB_FILE *stream; - int format; - int recurse; - enum val_prettyprint pretty; - struct type **dont_print_vb; - int dont_print_statmem; +cp_print_value_fields (struct type *type, struct type *real_type, char *valaddr, + int offset, CORE_ADDR address, struct ui_file *stream, + int format, int recurse, enum val_prettyprint pretty, + struct type **dont_print_vb, int dont_print_statmem) { int i, len, n_baseclasses; struct obstack tmp_obstack; @@ -266,11 +256,12 @@ cp_print_value_fields (type, real_type, valaddr, offset, address, stream, format /* If there are no data fields, or if the only field is the * vtbl pointer, skip this part */ - if ((len == n_baseclasses) || - ((len - n_baseclasses == 1) && - TYPE_HAS_VTABLE (type) && - STREQN (TYPE_FIELD_NAME (type, n_baseclasses), hpacc_vtbl_ptr_name, 5)) || - !len) + if ((len == n_baseclasses) + || ((len - n_baseclasses == 1) + && TYPE_HAS_VTABLE (type) + && STREQN (TYPE_FIELD_NAME (type, n_baseclasses), + hpacc_vtbl_ptr_name, 5)) + || !len) fprintf_filtered (stream, ""); else { @@ -292,7 +283,8 @@ cp_print_value_fields (type, real_type, valaddr, offset, address, stream, format continue; /* If a vtable pointer appears, we'll print it out later */ - if (TYPE_HAS_VTABLE (type) && STREQN (TYPE_FIELD_NAME (type, i), hpacc_vtbl_ptr_name, 5)) + if (TYPE_HAS_VTABLE (type) + && STREQN (TYPE_FIELD_NAME (type, i), hpacc_vtbl_ptr_name, 5)) continue; if (fields_seen) @@ -354,7 +346,7 @@ cp_print_value_fields (type, real_type, valaddr, offset, address, stream, format if (!TYPE_FIELD_STATIC (type, i) && TYPE_FIELD_PACKED (type, i)) { - value_ptr v; + struct value *v; /* Bitfields require special handling, especially due to byte order problems. */ @@ -364,11 +356,12 @@ cp_print_value_fields (type, real_type, valaddr, offset, address, stream, format } else { - v = value_from_longest (TYPE_FIELD_TYPE (type, i), - unpack_field_as_long (type, valaddr + offset, i)); + v = value_from_longest + (TYPE_FIELD_TYPE (type, i), + unpack_field_as_long (type, valaddr + offset, i)); - val_print (TYPE_FIELD_TYPE (type, i), VALUE_CONTENTS (v), 0, 0, - stream, format, 0, recurse + 1, pretty); + val_print (TYPE_FIELD_TYPE (type, i), VALUE_CONTENTS (v), + 0, 0, stream, format, 0, recurse + 1, pretty); } } else @@ -379,7 +372,7 @@ cp_print_value_fields (type, real_type, valaddr, offset, address, stream, format } else if (TYPE_FIELD_STATIC (type, i)) { - value_ptr v = value_static_field (type, i); + struct value *v = value_static_field (type, i); if (v == NULL) fputs_filtered ("", stream); else @@ -390,7 +383,7 @@ cp_print_value_fields (type, real_type, valaddr, offset, address, stream, format else { val_print (TYPE_FIELD_TYPE (type, i), - valaddr, offset + TYPE_FIELD_BITPOS (type, i) / 8, + valaddr, offset + TYPE_FIELD_BITPOS (type, i) / 8, address + TYPE_FIELD_BITPOS (type, i) / 8, stream, format, 0, recurse + 1, pretty); } @@ -413,9 +406,12 @@ cp_print_value_fields (type, real_type, valaddr, offset, address, stream, format } } /* if there are data fields */ /* Now print out the virtual table pointer if there is one */ - if (TYPE_HAS_VTABLE (type) && STREQN (TYPE_FIELD_NAME (type, n_baseclasses), hpacc_vtbl_ptr_name, 5)) + if (TYPE_HAS_VTABLE (type) + && STREQN (TYPE_FIELD_NAME (type, n_baseclasses), + hpacc_vtbl_ptr_name, + 5)) { - value_ptr v; + struct value *v; /* First get the virtual table pointer and print it out */ #if 0 @@ -427,7 +423,7 @@ cp_print_value_fields (type, real_type, valaddr, offset, address, stream, format /* pai: FIXME 32x64 problem? */ /* Not sure what the best notation is in the case where there is no baseclass name. */ - v = value_from_longest (lookup_pointer_type (builtin_type_unsigned_long), + v = value_from_pointer (lookup_pointer_type (builtin_type_unsigned_long), *(unsigned long *) (valaddr + offset)); val_print (VALUE_TYPE (v), VALUE_CONTENTS (v), 0, 0, @@ -447,7 +443,8 @@ cp_print_value_fields (type, real_type, valaddr, offset, address, stream, format if (1) { - /* no RRBC support; function pointers embedded directly in vtable */ + /* no RRBC support; function pointers embedded directly + in vtable */ int vfuncs = count_virtual_fns (real_type); @@ -455,7 +452,8 @@ cp_print_value_fields (type, real_type, valaddr, offset, address, stream, format /* FIXME : doesn't work at present */ #if 0 - fprintf_filtered (stream, "%d entr%s: ", vfuncs, vfuncs == 1 ? "y" : "ies"); + fprintf_filtered (stream, "%d entr%s: ", vfuncs, + vfuncs == 1 ? "y" : "ies"); #else fputs_filtered ("not implemented", stream); @@ -464,13 +462,15 @@ cp_print_value_fields (type, real_type, valaddr, offset, address, stream, format /* recursive function that prints all virtual function entries */ #if 0 - cp_print_hpacc_virtual_table_entries (real_type, &vfuncs, v, stream, format, recurse, pretty); + cp_print_hpacc_virtual_table_entries (real_type, &vfuncs, v, + stream, format, recurse, + pretty); #endif fputs_filtered ("}", stream); } /* non-RRBC case */ else { - /* FIXME -- seem comments above */ + /* FIXME -- see comments above */ /* RRBC support present; function pointers are found * by indirection through the class segment entries. */ @@ -493,23 +493,17 @@ cp_print_value_fields (type, real_type, valaddr, offset, address, stream, format baseclasses. */ static void -cp_print_value (type, real_type, valaddr, offset, address, stream, format, recurse, pretty, - dont_print_vb) - struct type *type; - struct type *real_type; - char *valaddr; - int offset; - CORE_ADDR address; - GDB_FILE *stream; - int format; - int recurse; - enum val_prettyprint pretty; - struct type **dont_print_vb; +cp_print_value (struct type *type, struct type *real_type, char *valaddr, + int offset, CORE_ADDR address, struct ui_file *stream, + int format, int recurse, enum val_prettyprint pretty, + struct type **dont_print_vb) { struct obstack tmp_obstack; struct type **last_dont_print - = (struct type **) obstack_next_free (&dont_print_vb_obstack); + = (struct type **) obstack_next_free (&dont_print_vb_obstack); int i, n_baseclasses = TYPE_N_BASECLASSES (type); + int thisoffset; + struct type *thistype; if (dont_print_vb == 0) { @@ -532,10 +526,10 @@ cp_print_value (type, real_type, valaddr, offset, address, stream, format, recur if (BASETYPE_VIA_VIRTUAL (type, i)) { struct type **first_dont_print - = (struct type **) obstack_base (&dont_print_vb_obstack); + = (struct type **) obstack_base (&dont_print_vb_obstack); int j = (struct type **) obstack_next_free (&dont_print_vb_obstack) - - first_dont_print; + - first_dont_print; while (--j >= 0) if (baseclass == first_dont_print[j]) @@ -544,32 +538,43 @@ cp_print_value (type, real_type, valaddr, offset, address, stream, format, recur obstack_ptr_grow (&dont_print_vb_obstack, baseclass); } + thisoffset = offset; + thistype = real_type; if (TYPE_HAS_VTABLE (type) && BASETYPE_VIA_VIRTUAL (type, i)) { /* Assume HP/Taligent runtime convention */ find_rt_vbase_offset (type, TYPE_BASECLASS (type, i), valaddr, offset, &boffset, &skip); if (skip >= 0) - error ("Virtual base class offset not found from vtable while printing"); + error ("Virtual base class offset not found from vtable while" + " printing"); base_valaddr = valaddr; } else { - boffset = baseclass_offset (type, i, valaddr + offset, address + offset); + boffset = baseclass_offset (type, i, + valaddr + offset, + address + offset); skip = ((boffset == -1) || (boffset + offset) < 0) ? 1 : -1; if (BASETYPE_VIA_VIRTUAL (type, i)) { - /* The virtual base class pointer might have been clobbered by the - user program. Make sure that it still points to a valid memory - location. */ + /* The virtual base class pointer might have been + clobbered by the user program. Make sure that it + still points to a valid memory location. */ - if (boffset != -1 && ((boffset + offset) < 0 || (boffset + offset) >= TYPE_LENGTH (type))) + if (boffset != -1 + && ((boffset + offset) < 0 + || (boffset + offset) >= TYPE_LENGTH (type))) { + /* FIXME (alloca): unsafe if baseclass is really really large. */ base_valaddr = (char *) alloca (TYPE_LENGTH (baseclass)); - if (target_read_memory (address + boffset, base_valaddr, + if (target_read_memory (address + offset + boffset, base_valaddr, TYPE_LENGTH (baseclass)) != 0) skip = 1; + thisoffset = 0; + boffset = 0; + thistype = baseclass; } else base_valaddr = valaddr; @@ -594,9 +599,11 @@ cp_print_value (type, real_type, valaddr, offset, address, stream, format, recur if (skip >= 1) fprintf_filtered (stream, ""); else - cp_print_value_fields (baseclass, real_type, base_valaddr, offset + boffset, address, - stream, format, recurse, pretty, - (struct type **) obstack_base (&dont_print_vb_obstack), + cp_print_value_fields (baseclass, thistype, base_valaddr, + thisoffset + boffset, address, stream, format, + recurse, pretty, + ((struct type **) + obstack_base (&dont_print_vb_obstack)), 0); fputs_filtered (", ", stream); @@ -625,13 +632,12 @@ cp_print_value (type, real_type, valaddr, offset, address, stream, format, recur have the same meanings as in c_val_print. */ static void -cp_print_static_field (type, val, stream, format, recurse, pretty) - struct type *type; - value_ptr val; - GDB_FILE *stream; - int format; - int recurse; - enum val_prettyprint pretty; +cp_print_static_field (struct type *type, + struct value *val, + struct ui_file *stream, + int format, + int recurse, + enum val_prettyprint pretty) { if (TYPE_CODE (type) == TYPE_CODE_STRUCT) { @@ -647,7 +653,8 @@ cp_print_static_field (type, val, stream, format, recurse, pretty) { if (VALUE_ADDRESS (val) == first_dont_print[i]) { - fputs_filtered ("", + fputs_filtered ("", stream); return; } @@ -657,20 +664,19 @@ cp_print_static_field (type, val, stream, format, recurse, pretty) sizeof (CORE_ADDR)); CHECK_TYPEDEF (type); - cp_print_value_fields (type, type, VALUE_CONTENTS_ALL (val), VALUE_EMBEDDED_OFFSET (val), VALUE_ADDRESS (val), + cp_print_value_fields (type, type, VALUE_CONTENTS_ALL (val), + VALUE_EMBEDDED_OFFSET (val), VALUE_ADDRESS (val), stream, format, recurse, pretty, NULL, 1); return; } - val_print (type, VALUE_CONTENTS_ALL (val), VALUE_EMBEDDED_OFFSET (val), VALUE_ADDRESS (val), + val_print (type, VALUE_CONTENTS_ALL (val), + VALUE_EMBEDDED_OFFSET (val), VALUE_ADDRESS (val), stream, format, 0, recurse, pretty); } void -cp_print_class_member (valaddr, domain, stream, prefix) - char *valaddr; - struct type *domain; - GDB_FILE *stream; - char *prefix; +cp_print_class_member (char *valaddr, struct type *domain, + struct ui_file *stream, char *prefix) { /* VAL is a byte offset into the structure type DOMAIN. @@ -726,7 +732,7 @@ cp_print_class_member (valaddr, domain, stream, prefix) fprintf_filtered (stream, " (offset in bits)"); } else - fprintf_filtered (stream, "%d", val >> 3); + fprintf_filtered (stream, "%ld", (long) (val >> 3)); } @@ -744,14 +750,10 @@ cp_print_class_member (valaddr, domain, stream, prefix) static void -cp_print_hpacc_virtual_table_entries (type, vfuncs, v, stream, format, recurse, pretty) - struct type *type; - int *vfuncs; - value_ptr v; - GDB_FILE *stream; - int format; - int recurse; - enum val_prettyprint pretty; +cp_print_hpacc_virtual_table_entries (struct type *type, int *vfuncs, + struct value *v, struct ui_file *stream, + int format, int recurse, + enum val_prettyprint pretty) { int fn, oi; @@ -762,7 +764,8 @@ cp_print_hpacc_virtual_table_entries (type, vfuncs, v, stream, format, recurse, /* Recursion on other classes that can share the same vtable */ struct type *pbc = primary_base_class (type); if (pbc) - cp_print_hpacc_virtual_table_entries (pbc, vfuncs, v, stream, format, recurse, pretty); + cp_print_hpacc_virtual_table_entries (pbc, vfuncs, v, stream, format, + recurse, pretty); /* Now deal with vfuncs declared in this class */ for (fn = 0; fn < TYPE_NFN_FIELDS (type); fn++) @@ -770,23 +773,28 @@ cp_print_hpacc_virtual_table_entries (type, vfuncs, v, stream, format, recurse, if (TYPE_FN_FIELD_VIRTUAL_P (TYPE_FN_FIELDLIST1 (type, fn), oi)) { char *vf_name; + const char *field_physname; /* virtual function offset */ - int vx = TYPE_FN_FIELD_VOFFSET (TYPE_FN_FIELDLIST1 (type, fn), oi) - 1; + int vx = (TYPE_FN_FIELD_VOFFSET (TYPE_FN_FIELDLIST1 (type, fn), oi) + - 1); /* Get the address of the vfunction entry */ - value_ptr vf = value_copy (v); + struct value *vf = value_copy (v); if (VALUE_LAZY (vf)) (void) value_fetch_lazy (vf); - vf->aligner.contents[0] += 4 * (HP_ACC_VFUNC_START + vx); /* adjust by offset */ + /* adjust by offset */ + vf->aligner.contents[0] += 4 * (HP_ACC_VFUNC_START + vx); vf = value_ind (vf); /* get the entry */ VALUE_TYPE (vf) = VALUE_TYPE (v); /* make it a pointer */ /* print out the entry */ val_print (VALUE_TYPE (vf), VALUE_CONTENTS (vf), 0, 0, stream, format, 0, recurse + 1, pretty); - vf_name = cplus_demangle (TYPE_FN_FIELD_PHYSNAME (TYPE_FN_FIELDLIST1 (type, fn), oi), - DMGL_ARM); /* pai: (temp) FIXME Maybe this should be DMGL_ANSI */ + field_physname + = TYPE_FN_FIELD_PHYSNAME (TYPE_FN_FIELDLIST1 (type, fn), oi); + /* pai: (temp) FIXME Maybe this should be DMGL_ANSI */ + vf_name = cplus_demangle (field_physname, DMGL_ARM); fprintf_filtered (stream, " %s", vf_name); if (--(*vfuncs) > 0) fputs_filtered (", ", stream); @@ -796,7 +804,7 @@ cp_print_hpacc_virtual_table_entries (type, vfuncs, v, stream, format, recurse, void -_initialize_cp_valprint () +_initialize_cp_valprint (void) { add_show_from_set (add_set_cmd ("static-members", class_support, var_boolean, @@ -825,5 +833,5 @@ _initialize_cp_valprint () obstack_begin (&dont_print_vb_obstack, 32 * sizeof (struct type *)); obstack_specify_allocation (&dont_print_statmem_obstack, 32 * sizeof (CORE_ADDR), sizeof (CORE_ADDR), - xmalloc, free); + xmalloc, xfree); }