X-Git-Url: https://repo.jachan.dev/binutils.git/blobdiff_plain/a8a69e6332cc7f83a608af394e757e00355f5550..f164292134b1140be664f767c83db76693dd0616:/gdb/cp-valprint.c diff --git a/gdb/cp-valprint.c b/gdb/cp-valprint.c index 5222f7b947..47b38f803d 100644 --- a/gdb/cp-valprint.c +++ b/gdb/cp-valprint.c @@ -25,6 +25,7 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ #include "value.h" #include "command.h" #include "gdbcmd.h" +#include "demangle.h" int vtblprint; /* Controls printing of vtbl's */ int objectprint; /* Controls looking up an object's derived type @@ -60,6 +61,104 @@ c_val_print PARAMS ((struct type *, char *, CORE_ADDR, FILE *, int, int, int, /* END-FIXME */ +void +cp_print_class_method (valaddr, type, stream) + char *valaddr; + struct type *type; + FILE *stream; +{ + struct type *domain; + struct fn_field *f = NULL; + int j = 0; + int len2; + int offset; + char *kind = ""; + CORE_ADDR addr; + struct symbol *sym; + unsigned len; + unsigned int i; + + check_stub_type (TYPE_TARGET_TYPE (type)); + domain = TYPE_DOMAIN_TYPE (TYPE_TARGET_TYPE (type)); + if (domain == (struct type *)NULL) + { + fprintf_filtered (stream, ""); + return; + } + addr = unpack_pointer (lookup_pointer_type (builtin_type_void), valaddr); + if (METHOD_PTR_IS_VIRTUAL (addr)) + { + offset = METHOD_PTR_TO_VOFFSET (addr); + len = TYPE_NFN_FIELDS (domain); + for (i = 0; i < len; i++) + { + f = TYPE_FN_FIELDLIST1 (domain, i); + len2 = TYPE_FN_FIELDLIST_LENGTH (domain, i); + + for (j = 0; j < len2; j++) + { + QUIT; + if (TYPE_FN_FIELD_VOFFSET (f, j) == offset) + { + kind = "virtual "; + goto common; + } + } + } + } + else + { + sym = find_pc_function (addr); + if (sym == 0) + { + error ("invalid pointer to member function"); + } + len = TYPE_NFN_FIELDS (domain); + for (i = 0; i < len; i++) + { + f = TYPE_FN_FIELDLIST1 (domain, i); + len2 = TYPE_FN_FIELDLIST_LENGTH (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; + } + } + } + } + common: + if (i < len) + { + fprintf_filtered (stream, "&"); + c_type_print_varspec_prefix (TYPE_FN_FIELD_TYPE (f, j), stream, 0, 0); + fprintf (stream, kind); + if (TYPE_FN_FIELD_PHYSNAME (f, j)[0] == '_' + && TYPE_FN_FIELD_PHYSNAME (f, j)[1] == CPLUS_MARKER) + { + cp_type_print_method_args (TYPE_FN_FIELD_ARGS (f, j) + 1, "~", + TYPE_FN_FIELDLIST_NAME (domain, i), + 0, stream); + } + else + { + cp_type_print_method_args (TYPE_FN_FIELD_ARGS (f, j), "", + TYPE_FN_FIELDLIST_NAME (domain, i), + 0, stream); + } + } + else + { + fprintf_filtered (stream, "("); + type_print (type, "", stream, -1); + fprintf_filtered (stream, ") %d", (int) addr >> 3); + } +} + /* Return truth value for assertion that TYPE is of the type "pointer to virtual function". */ @@ -68,10 +167,16 @@ cp_is_vtbl_ptr_type(type) struct type *type; { char *typename = type_name_no_tag (type); - static const char vtbl_ptr_name[] = + /* 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. */ + static const char vtbl_ptr_name[] = + { '_','_','v','t','b','l','_','p','t','r','_','t','y','p','e', 0 }; - return (typename != NULL && !strcmp(typename, vtbl_ptr_name)); + return (typename != NULL + && (STREQ (typename, vtbl_ptr_name) + || STREQ (typename, vtbl_ptr_name_old))); } /* Return truth value for the assertion that TYPE is of the type @@ -169,14 +274,20 @@ cp_print_value_fields (type, valaddr, stream, format, recurse, pretty, fputs_filtered ("\"( ptr \"", stream); else fputs_filtered ("\"( nodef \"", stream); - fprint_symbol (stream, TYPE_FIELD_NAME (type, i)); + fprintf_symbol_filtered (stream, TYPE_FIELD_NAME (type, i), + language_cplus, + DMGL_PARAMS | DMGL_ANSI); fputs_filtered ("\" \"", stream); - fprint_symbol (stream, TYPE_FIELD_NAME (type, i)); + fprintf_symbol_filtered (stream, TYPE_FIELD_NAME (type, i), + language_cplus, + DMGL_PARAMS | DMGL_ANSI); fputs_filtered ("\") \"", stream); } else { - fprint_symbol (stream, TYPE_FIELD_NAME (type, i)); + fprintf_symbol_filtered (stream, TYPE_FIELD_NAME (type, i), + language_cplus, + DMGL_PARAMS | DMGL_ANSI); fputs_filtered (" = ", stream); } if (TYPE_FIELD_PACKED (type, i)) @@ -239,6 +350,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)) { @@ -258,8 +370,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) { @@ -267,10 +379,13 @@ 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, "", baddr); + fprintf_filtered (stream, + "", (unsigned long) baddr); else cp_print_value_fields (TYPE_BASECLASS (type, i), baddr, stream, format, recurse, pretty,