X-Git-Url: http://drtracing.org/?a=blobdiff_plain;f=gdb%2Fcp-valprint.c;h=3fbb1f1f3c85f7db28f205d0cea41b1a91a4a5cf;hb=ad3bbd48b65047845b258564db3fd2e64e00c7bc;hp=181b4ffb5b841206155cdb60dea2778370b28fdf;hpb=42ae523077b469c09e83845d30ee137a844aacb8;p=deliverable%2Fbinutils-gdb.git diff --git a/gdb/cp-valprint.c b/gdb/cp-valprint.c index 181b4ffb5b..3fbb1f1f3c 100644 --- a/gdb/cp-valprint.c +++ b/gdb/cp-valprint.c @@ -1,7 +1,7 @@ /* Support for printing C++ values for GDB, the GNU debugger. Copyright (C) 1986, 1988, 1989, 1991, 1992, 1993, 1994, 1995, 1996, 1997, - 2000, 2001, 2002, 2003, 2005, 2006, 2007, 2008, 2009 + 2000, 2001, 2002, 2003, 2005, 2006, 2007, 2008, 2009, 2010 Free Software Foundation, Inc. This file is part of GDB. @@ -36,6 +36,7 @@ #include "valprint.h" #include "cp-support.h" #include "language.h" +#include "python/python.h" /* Controls printing of vtbl's */ static void @@ -70,6 +71,7 @@ show_static_field_print (struct ui_file *file, int from_tty, static struct obstack dont_print_vb_obstack; static struct obstack dont_print_statmem_obstack; +static struct obstack dont_print_stat_array_obstack; extern void _initialize_cp_valprint (void); @@ -153,10 +155,18 @@ cp_print_value_fields (struct type *type, struct type *real_type, struct type **dont_print_vb, int dont_print_statmem) { int i, len, n_baseclasses; - char *last_dont_print = obstack_next_free (&dont_print_statmem_obstack); int fields_seen = 0; + static int last_set_recurse = -1; CHECK_TYPEDEF (type); + + if (recurse == 0) + { + if (obstack_object_size (&dont_print_statmem_obstack) > 0) + obstack_free (&dont_print_statmem_obstack, NULL); + if (obstack_object_size (&dont_print_stat_array_obstack) > 0) + obstack_free (&dont_print_stat_array_obstack, NULL); + } fprintf_filtered (stream, "{"); len = TYPE_NFIELDS (type); @@ -176,14 +186,21 @@ cp_print_value_fields (struct type *type, struct type *real_type, fprintf_filtered (stream, ""); else { - struct obstack tmp_obstack = dont_print_statmem_obstack; - + int statmem_obstack_initial_size = 0; + int stat_array_obstack_initial_size = 0; + if (dont_print_statmem == 0) { - /* If we're at top level, carve out a completely fresh - chunk of the obstack and use that until this particular - invocation returns. */ - obstack_finish (&dont_print_statmem_obstack); + statmem_obstack_initial_size = + obstack_object_size (&dont_print_statmem_obstack); + + if (last_set_recurse != recurse) + { + stat_array_obstack_initial_size = + obstack_object_size (&dont_print_stat_array_obstack); + + last_set_recurse = recurse; + } } for (i = n_baseclasses; i < len; i++) @@ -264,6 +281,7 @@ cp_print_value_fields (struct type *type, struct type *real_type, else { struct value_print_options opts = *options; + opts.deref_ref = 0; v = value_from_longest (TYPE_FIELD_TYPE (type, i), @@ -282,6 +300,7 @@ cp_print_value_fields (struct type *type, struct type *real_type, else if (field_is_static (&TYPE_FIELD (type, i))) { struct value *v = value_static_field (type, i); + if (v == NULL) fputs_filtered ("", stream); else @@ -291,10 +310,11 @@ cp_print_value_fields (struct type *type, struct type *real_type, else { struct value_print_options opts = *options; + opts.deref_ref = 0; val_print (TYPE_FIELD_TYPE (type, i), valaddr, offset + TYPE_FIELD_BITPOS (type, i) / 8, - address + TYPE_FIELD_BITPOS (type, i) / 8, + address, stream, recurse + 1, &opts, current_language); } @@ -304,10 +324,36 @@ cp_print_value_fields (struct type *type, struct type *real_type, if (dont_print_statmem == 0) { - /* Free the space used to deal with the printing - of the members from top level. */ - obstack_free (&dont_print_statmem_obstack, last_dont_print); - dont_print_statmem_obstack = tmp_obstack; + int obstack_final_size = + obstack_object_size (&dont_print_statmem_obstack); + + if (obstack_final_size > statmem_obstack_initial_size) { + /* In effect, a pop of the printed-statics stack. */ + + void *free_to_ptr = + obstack_next_free (&dont_print_statmem_obstack) - + (obstack_final_size - statmem_obstack_initial_size); + + obstack_free (&dont_print_statmem_obstack, + free_to_ptr); + } + + if (last_set_recurse != recurse) + { + int obstack_final_size = + obstack_object_size (&dont_print_stat_array_obstack); + + if (obstack_final_size > stat_array_obstack_initial_size) + { + void *free_to_ptr = + obstack_next_free (&dont_print_stat_array_obstack) - + (obstack_final_size - stat_array_obstack_initial_size); + + obstack_free (&dont_print_stat_array_obstack, + free_to_ptr); + } + last_set_recurse = -1; + } } if (options->pretty) @@ -320,6 +366,40 @@ cp_print_value_fields (struct type *type, struct type *real_type, fprintf_filtered (stream, "}"); } +/* Like cp_print_value_fields, but find the runtime type of the object + and pass it as the `real_type' argument to cp_print_value_fields. + This function is a hack to work around the fact that + common_val_print passes the embedded offset to val_print, but not + the enclosing type. */ + +void +cp_print_value_fields_rtti (struct type *type, + const gdb_byte *valaddr, int offset, + CORE_ADDR address, + struct ui_file *stream, int recurse, + const struct value_print_options *options, + struct type **dont_print_vb, + int dont_print_statmem) +{ + struct value *value; + int full, top, using_enc; + struct type *real_type; + + /* Ugh, we have to convert back to a value here. */ + value = value_from_contents_and_address (type, valaddr + offset, + address + offset); + /* We don't actually care about most of the result here -- just the + type. We already have the correct offset, due to how val_print + was initially called. */ + real_type = value_rtti_type (value, &full, &top, &using_enc); + if (!real_type) + real_type = type; + + cp_print_value_fields (type, real_type, valaddr, offset, + address, stream, recurse, options, + dont_print_vb, dont_print_statmem); +} + /* Special val_print routine to avoid printing multiple copies of virtual baseclasses. */ @@ -372,7 +452,7 @@ cp_print_value (struct type *type, struct type *real_type, thisoffset = offset; thistype = real_type; - boffset = baseclass_offset (type, i, valaddr + offset, address); + boffset = baseclass_offset (type, i, valaddr + offset, address + offset); skip = ((boffset == -1) || (boffset + offset) < 0) ? 1 : -1; if (BASETYPE_VIA_VIRTUAL (type, i)) @@ -383,10 +463,11 @@ cp_print_value (struct type *type, struct type *real_type, if (boffset != -1 && ((boffset + offset) < 0 - || (boffset + offset) >= TYPE_LENGTH (type))) + || (boffset + offset) >= TYPE_LENGTH (real_type))) { /* FIXME (alloca): unsafe if baseclass is really really large. */ gdb_byte *buf = alloca (TYPE_LENGTH (baseclass)); + base_valaddr = buf; if (target_read_memory (address + boffset, buf, TYPE_LENGTH (baseclass)) != 0) @@ -418,12 +499,27 @@ cp_print_value (struct type *type, struct type *real_type, if (skip >= 1) fprintf_filtered (stream, ""); else - cp_print_value_fields (baseclass, thistype, base_valaddr, - thisoffset + boffset, address + boffset, - stream, recurse, options, - ((struct type **) - obstack_base (&dont_print_vb_obstack)), - 0); + { + int result = 0; + + /* Attempt to run the Python pretty-printers on the + baseclass if possible. */ + if (!options->raw) + result = apply_val_pretty_printer (baseclass, base_valaddr, + thisoffset + boffset, + address, + stream, recurse, + options, + current_language); + + if (!result) + cp_print_value_fields (baseclass, thistype, base_valaddr, + thisoffset + boffset, address, + stream, recurse, options, + ((struct type **) + obstack_base (&dont_print_vb_obstack)), + 0); + } fputs_filtered (", ", stream); flush_it: @@ -458,6 +554,7 @@ cp_print_static_field (struct type *type, const struct value_print_options *options) { struct value_print_options opts; + if (TYPE_CODE (type) == TYPE_CODE_STRUCT) { CORE_ADDR *first_dont_print; @@ -466,8 +563,8 @@ cp_print_static_field (struct type *type, first_dont_print = (CORE_ADDR *) obstack_base (&dont_print_statmem_obstack); - i = (CORE_ADDR *) obstack_next_free (&dont_print_statmem_obstack) - - first_dont_print; + i = obstack_object_size (&dont_print_statmem_obstack) + / sizeof (CORE_ADDR); while (--i >= 0) { @@ -483,14 +580,40 @@ cp_print_static_field (struct type *type, addr = value_address (val); obstack_grow (&dont_print_statmem_obstack, (char *) &addr, sizeof (CORE_ADDR)); - CHECK_TYPEDEF (type); - cp_print_value_fields (type, type, value_contents_all (val), + cp_print_value_fields (type, value_enclosing_type (val), + value_contents_all (val), value_embedded_offset (val), addr, stream, recurse, options, NULL, 1); return; } + if (TYPE_CODE (type) == TYPE_CODE_ARRAY) + { + struct type **first_dont_print; + int i; + struct type *target_type = TYPE_TARGET_TYPE (type); + + first_dont_print + = (struct type **) obstack_base (&dont_print_stat_array_obstack); + i = obstack_object_size (&dont_print_stat_array_obstack) + / sizeof (CORE_ADDR); + + while (--i >= 0) + { + if (target_type == first_dont_print[i]) + { + fputs_filtered ("", + stream); + return; + } + } + + obstack_grow (&dont_print_stat_array_obstack, (char *) &target_type, + sizeof (struct type *)); + } + opts = *options; opts.deref_ref = 0; val_print (type, value_contents_all (val), @@ -548,13 +671,17 @@ void cp_print_class_member (const gdb_byte *valaddr, struct type *type, struct ui_file *stream, char *prefix) { + enum bfd_endian byte_order = gdbarch_byte_order (get_type_arch (type)); + /* VAL is a byte offset into the structure type DOMAIN. Find the name of the field for that offset and print it. */ struct type *domain = TYPE_DOMAIN_TYPE (type); - LONGEST val = extract_signed_integer (valaddr, TYPE_LENGTH (type)); + LONGEST val; unsigned int fieldno; + val = extract_signed_integer (valaddr, TYPE_LENGTH (type), byte_order); + /* Pointers to data members are usually byte offsets into an object. Because a data member can have offset zero, and a NULL pointer to member must be distinct from any valid non-NULL pointer to @@ -576,6 +703,7 @@ cp_print_class_member (const gdb_byte *valaddr, struct type *type, if (domain != NULL) { char *name; + fputs_filtered (prefix, stream); name = type_name_no_tag (domain); if (name) @@ -617,8 +745,7 @@ Show printing of object's derived type based on vtable info."), NULL, show_objectprint, &setprintlist, &showprintlist); + obstack_begin (&dont_print_stat_array_obstack, 32 * sizeof (CORE_ADDR)); + obstack_begin (&dont_print_statmem_obstack, 32 * sizeof (CORE_ADDR)); 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, xfree); }