gdb/cp-valprint.c - gdb
Global variables defined
Functions defined
Source code
- #include "defs.h"
- #include "gdb_obstack.h"
- #include "symtab.h"
- #include "gdbtypes.h"
- #include "expression.h"
- #include "value.h"
- #include "command.h"
- #include "gdbcmd.h"
- #include "demangle.h"
- #include "annotate.h"
- #include "c-lang.h"
- #include "target.h"
- #include "cp-abi.h"
- #include "valprint.h"
- #include "cp-support.h"
- #include "language.h"
- #include "extension.h"
- #include "typeprint.h"
- static void
- show_vtblprint (struct ui_file *file, int from_tty,
- struct cmd_list_element *c, const char *value)
- {
- fprintf_filtered (file, _("\
- Printing of C++ virtual function tables is %s.\n"),
- value);
- }
- static void
- show_objectprint (struct ui_file *file, int from_tty,
- struct cmd_list_element *c,
- const char *value)
- {
- fprintf_filtered (file, _("\
- Printing of object's derived type based on vtable info is %s.\n"),
- value);
- }
- static void
- show_static_field_print (struct ui_file *file, int from_tty,
- struct cmd_list_element *c,
- const char *value)
- {
- fprintf_filtered (file,
- _("Printing of C++ static members is %s.\n"),
- value);
- }
- 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);
- static void cp_print_static_field (struct type *, struct value *,
- struct ui_file *, int,
- const struct value_print_options *);
- static void cp_print_value (struct type *, struct type *,
- const gdb_byte *, int,
- CORE_ADDR, struct ui_file *,
- int, const struct value *,
- const struct value_print_options *,
- struct type **);
- const char vtbl_ptr_name[] = "__vtbl_ptr_type";
- int
- cp_is_vtbl_ptr_type (struct type *type)
- {
- const char *typename = type_name_no_tag (type);
- return (typename != NULL && !strcmp (typename, vtbl_ptr_name));
- }
- int
- cp_is_vtbl_member (struct type *type)
- {
-
- if (TYPE_CODE (type) == TYPE_CODE_PTR)
- {
- type = TYPE_TARGET_TYPE (type);
- if (TYPE_CODE (type) == TYPE_CODE_ARRAY)
- {
- type = TYPE_TARGET_TYPE (type);
- if (TYPE_CODE (type) == TYPE_CODE_STRUCT
- || TYPE_CODE (type) == TYPE_CODE_PTR)
- {
-
- return cp_is_vtbl_ptr_type (type);
- }
- }
- else if (TYPE_CODE (type) == TYPE_CODE_STRUCT)
- {
- return cp_is_vtbl_ptr_type (type);
- }
- else if (TYPE_CODE (type) == TYPE_CODE_PTR)
- {
-
- return cp_is_vtbl_ptr_type (type);
- }
- }
- return 0;
- }
- void
- cp_print_value_fields (struct type *type, struct type *real_type,
- const gdb_byte *valaddr, int offset,
- CORE_ADDR address, struct ui_file *stream,
- int recurse, const struct value *val,
- const struct value_print_options *options,
- struct type **dont_print_vb,
- int dont_print_statmem)
- {
- int i, len, n_baseclasses;
- 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);
- obstack_begin (&dont_print_statmem_obstack,
- 32 * sizeof (CORE_ADDR));
- }
- if (obstack_object_size (&dont_print_stat_array_obstack) > 0)
- {
- obstack_free (&dont_print_stat_array_obstack, NULL);
- obstack_begin (&dont_print_stat_array_obstack,
- 32 * sizeof (struct type *));
- }
- }
- fprintf_filtered (stream, "{");
- len = TYPE_NFIELDS (type);
- n_baseclasses = TYPE_N_BASECLASSES (type);
-
- if (n_baseclasses > 0)
- cp_print_value (type, real_type, valaddr,
- offset, address, stream,
- recurse + 1, val, options,
- dont_print_vb);
-
-
- if (len == n_baseclasses || !len)
- fprintf_filtered (stream, "<No data fields>");
- else
- {
- size_t statmem_obstack_initial_size = 0;
- size_t stat_array_obstack_initial_size = 0;
- struct type *vptr_basetype = NULL;
- int vptr_fieldno;
- if (dont_print_statmem == 0)
- {
- 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;
- }
- }
- vptr_fieldno = get_vptr_fieldno (type, &vptr_basetype);
- for (i = n_baseclasses; i < len; i++)
- {
-
- if (!options->static_field_print
- && field_is_static (&TYPE_FIELD (type, i)))
- continue;
- if (fields_seen)
- fprintf_filtered (stream, ", ");
- else if (n_baseclasses > 0)
- {
- if (options->prettyformat)
- {
- fprintf_filtered (stream, "\n");
- print_spaces_filtered (2 + 2 * recurse, stream);
- fputs_filtered ("members of ", stream);
- fputs_filtered (type_name_no_tag (type), stream);
- fputs_filtered (": ", stream);
- }
- }
- fields_seen = 1;
- if (options->prettyformat)
- {
- fprintf_filtered (stream, "\n");
- print_spaces_filtered (2 + 2 * recurse, stream);
- }
- else
- {
- wrap_here (n_spaces (2 + 2 * recurse));
- }
- annotate_field_begin (TYPE_FIELD_TYPE (type, i));
- if (field_is_static (&TYPE_FIELD (type, i)))
- fputs_filtered ("static ", stream);
- fprintf_symbol_filtered (stream,
- TYPE_FIELD_NAME (type, i),
- current_language->la_language,
- DMGL_PARAMS | DMGL_ANSI);
- annotate_field_name_end ();
-
- if (strcmp (TYPE_FIELD_NAME (type, i), ""))
- fputs_filtered (" = ", stream);
- annotate_field_value ();
- if (!field_is_static (&TYPE_FIELD (type, i))
- && TYPE_FIELD_PACKED (type, i))
- {
- struct value *v;
-
- if (TYPE_FIELD_IGNORE (type, i))
- {
- fputs_filtered ("<optimized out or zero length>", stream);
- }
- else if (value_bits_synthetic_pointer (val,
- TYPE_FIELD_BITPOS (type,
- i),
- TYPE_FIELD_BITSIZE (type,
- i)))
- {
- fputs_filtered (_("<synthetic pointer>"), stream);
- }
- else
- {
- struct value_print_options opts = *options;
- opts.deref_ref = 0;
- v = value_field_bitfield (type, i, valaddr, offset, val);
- common_val_print (v, stream, recurse + 1, &opts,
- current_language);
- }
- }
- else
- {
- if (TYPE_FIELD_IGNORE (type, i))
- {
- fputs_filtered ("<optimized out or zero length>",
- stream);
- }
- else if (field_is_static (&TYPE_FIELD (type, i)))
- {
- volatile struct gdb_exception ex;
- struct value *v = NULL;
- TRY_CATCH (ex, RETURN_MASK_ERROR)
- {
- v = value_static_field (type, i);
- }
- if (ex.reason < 0)
- fprintf_filtered (stream,
- _("<error reading variable: %s>"),
- ex.message);
- cp_print_static_field (TYPE_FIELD_TYPE (type, i),
- v, stream, recurse + 1,
- options);
- }
- else if (i == vptr_fieldno && type == vptr_basetype)
- {
- int i_offset = offset + TYPE_FIELD_BITPOS (type, i) / 8;
- struct type *i_type = TYPE_FIELD_TYPE (type, i);
- if (valprint_check_validity (stream, i_type, i_offset, val))
- {
- CORE_ADDR addr;
- addr = extract_typed_address (valaddr + i_offset, i_type);
- print_function_pointer_address (options,
- get_type_arch (type),
- addr, stream);
- }
- }
- 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,
- stream, recurse + 1, val, &opts,
- current_language);
- }
- }
- annotate_field_end ();
- }
- if (dont_print_statmem == 0)
- {
- size_t obstack_final_size =
- obstack_object_size (&dont_print_statmem_obstack);
- if (obstack_final_size > statmem_obstack_initial_size)
- {
-
- void *free_to_ptr =
- (char *) 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)
- {
- size_t obstack_final_size =
- obstack_object_size (&dont_print_stat_array_obstack);
- if (obstack_final_size > stat_array_obstack_initial_size)
- {
- void *free_to_ptr =
- (char *) 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->prettyformat)
- {
- fprintf_filtered (stream, "\n");
- print_spaces_filtered (2 * recurse, stream);
- }
- }
- fprintf_filtered (stream, "}");
- }
- 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 *val,
- const struct value_print_options *options,
- struct type **dont_print_vb,
- int dont_print_statmem)
- {
- struct type *real_type = NULL;
-
- if (!value_bits_any_optimized_out (val,
- TARGET_CHAR_BIT * offset,
- TARGET_CHAR_BIT * TYPE_LENGTH (type)))
- {
- struct value *value;
- int full, top, using_enc;
-
- value = value_from_contents_and_address (type, valaddr + offset,
- address + offset);
- type = value_type (value);
-
- 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, val, options,
- dont_print_vb, dont_print_statmem);
- }
- static void
- cp_print_value (struct type *type, struct type *real_type,
- const gdb_byte *valaddr, int offset,
- CORE_ADDR address, struct ui_file *stream,
- int recurse, const struct value *val,
- const struct value_print_options *options,
- struct type **dont_print_vb)
- {
- struct type **last_dont_print
- = (struct type **) obstack_next_free (&dont_print_vb_obstack);
- struct obstack tmp_obstack = dont_print_vb_obstack;
- int i, n_baseclasses = TYPE_N_BASECLASSES (type);
- int thisoffset;
- struct type *thistype;
- if (dont_print_vb == 0)
- {
-
-
- obstack_finish (&dont_print_vb_obstack);
- }
- for (i = 0; i < n_baseclasses; i++)
- {
- int boffset = 0;
- int skip;
- struct type *baseclass = check_typedef (TYPE_BASECLASS (type, i));
- const char *basename = TYPE_NAME (baseclass);
- const gdb_byte *base_valaddr = NULL;
- const struct value *base_val = NULL;
- volatile struct gdb_exception ex;
- if (BASETYPE_VIA_VIRTUAL (type, i))
- {
- struct type **first_dont_print
- = (struct type **) obstack_base (&dont_print_vb_obstack);
- int j = (struct type **)
- obstack_next_free (&dont_print_vb_obstack) - first_dont_print;
- while (--j >= 0)
- if (baseclass == first_dont_print[j])
- goto flush_it;
- obstack_ptr_grow (&dont_print_vb_obstack, baseclass);
- }
- thisoffset = offset;
- thistype = real_type;
- TRY_CATCH (ex, RETURN_MASK_ERROR)
- {
- boffset = baseclass_offset (type, i, valaddr, offset, address, val);
- }
- if (ex.reason < 0 && ex.error == NOT_AVAILABLE_ERROR)
- skip = -1;
- else if (ex.reason < 0)
- skip = 1;
- else
- {
- skip = 0;
- if (BASETYPE_VIA_VIRTUAL (type, i))
- {
-
- if ((boffset + offset) < 0
- || (boffset + offset) >= TYPE_LENGTH (real_type))
- {
- gdb_byte *buf;
- struct cleanup *back_to;
- buf = xmalloc (TYPE_LENGTH (baseclass));
- back_to = make_cleanup (xfree, buf);
- if (target_read_memory (address + boffset, buf,
- TYPE_LENGTH (baseclass)) != 0)
- skip = 1;
- base_val = value_from_contents_and_address (baseclass,
- buf,
- address + boffset);
- baseclass = value_type (base_val);
- thisoffset = 0;
- boffset = 0;
- thistype = baseclass;
- base_valaddr = value_contents_for_printing_const (base_val);
- do_cleanups (back_to);
- }
- else
- {
- base_valaddr = valaddr;
- base_val = val;
- }
- }
- else
- {
- base_valaddr = valaddr;
- base_val = val;
- }
- }
-
- if (options->prettyformat)
- {
- fprintf_filtered (stream, "\n");
- print_spaces_filtered (2 * recurse, stream);
- }
- fputs_filtered ("<", stream);
-
- fputs_filtered (basename ? basename : "", stream);
- fputs_filtered ("> = ", stream);
- if (skip < 0)
- val_print_unavailable (stream);
- else if (skip > 0)
- val_print_invalid_address (stream);
- else
- {
- int result = 0;
-
- if (!options->raw)
- result
- = apply_ext_lang_val_pretty_printer (baseclass, base_valaddr,
- thisoffset + boffset,
- value_address (base_val),
- stream, recurse,
- base_val, options,
- current_language);
- if (!result)
- cp_print_value_fields (baseclass, thistype, base_valaddr,
- thisoffset + boffset,
- value_address (base_val),
- stream, recurse, base_val, options,
- ((struct type **)
- obstack_base (&dont_print_vb_obstack)),
- 0);
- }
- fputs_filtered (", ", stream);
- flush_it:
- ;
- }
- if (dont_print_vb == 0)
- {
-
- obstack_free (&dont_print_vb_obstack, last_dont_print);
-
- dont_print_vb_obstack = tmp_obstack;
- }
- }
- static void
- cp_print_static_field (struct type *type,
- struct value *val,
- struct ui_file *stream,
- int recurse,
- const struct value_print_options *options)
- {
- struct value_print_options opts;
- if (value_entirely_optimized_out (val))
- {
- val_print_optimized_out (val, stream);
- return;
- }
- if (TYPE_CODE (type) == TYPE_CODE_STRUCT)
- {
- CORE_ADDR *first_dont_print;
- CORE_ADDR addr;
- int i;
- first_dont_print
- = (CORE_ADDR *) obstack_base (&dont_print_statmem_obstack);
- i = obstack_object_size (&dont_print_statmem_obstack)
- / sizeof (CORE_ADDR);
- while (--i >= 0)
- {
- if (value_address (val) == first_dont_print[i])
- {
- fputs_filtered ("<same as static member of an already"
- " seen type>",
- stream);
- return;
- }
- }
- addr = value_address (val);
- obstack_grow (&dont_print_statmem_obstack, (char *) &addr,
- sizeof (CORE_ADDR));
- CHECK_TYPEDEF (type);
- cp_print_value_fields (type, value_enclosing_type (val),
- value_contents_for_printing (val),
- value_embedded_offset (val), addr,
- stream, recurse, val,
- 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 (struct type *);
- while (--i >= 0)
- {
- if (target_type == first_dont_print[i])
- {
- fputs_filtered ("<same as static member of an already"
- " seen type>",
- 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_for_printing (val),
- value_embedded_offset (val),
- value_address (val),
- stream, recurse, val,
- &opts, current_language);
- }
- static void
- cp_find_class_member (struct type **domain_p, int *fieldno,
- LONGEST offset)
- {
- struct type *domain;
- unsigned int i;
- unsigned len;
- *domain_p = check_typedef (*domain_p);
- domain = *domain_p;
- len = TYPE_NFIELDS (domain);
- for (i = TYPE_N_BASECLASSES (domain); i < len; i++)
- {
- LONGEST bitpos = TYPE_FIELD_BITPOS (domain, i);
- QUIT;
- if (offset == bitpos)
- {
- *fieldno = i;
- return;
- }
- }
- for (i = 0; i < TYPE_N_BASECLASSES (domain); i++)
- {
- LONGEST bitpos = TYPE_FIELD_BITPOS (domain, i);
- LONGEST bitsize = 8 * TYPE_LENGTH (TYPE_FIELD_TYPE (domain, i));
- if (offset >= bitpos && offset < bitpos + bitsize)
- {
- *domain_p = TYPE_FIELD_TYPE (domain, i);
- cp_find_class_member (domain_p, fieldno, offset - bitpos);
- return;
- }
- }
- *domain_p = NULL;
- }
- 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));
-
- struct type *domain = TYPE_DOMAIN_TYPE (type);
- LONGEST val;
- int fieldno;
- val = extract_signed_integer (valaddr,
- TYPE_LENGTH (type),
- byte_order);
-
- if (val == -1)
- {
- fprintf_filtered (stream, "NULL");
- return;
- }
- cp_find_class_member (&domain, &fieldno, val << 3);
- if (domain != NULL)
- {
- const char *name;
- fputs_filtered (prefix, stream);
- name = type_name_no_tag (domain);
- if (name)
- fputs_filtered (name, stream);
- else
- c_type_print_base (domain, stream, 0, 0, &type_print_raw_options);
- fprintf_filtered (stream, "::");
- fputs_filtered (TYPE_FIELD_NAME (domain, fieldno), stream);
- }
- else
- fprintf_filtered (stream, "%ld", (long) val);
- }
- void
- _initialize_cp_valprint (void)
- {
- add_setshow_boolean_cmd ("static-members", class_support,
- &user_print_options.static_field_print, _("\
- Set printing of C++ static members."), _("\
- Show printing of C++ static members."), NULL,
- NULL,
- show_static_field_print,
- &setprintlist, &showprintlist);
- add_setshow_boolean_cmd ("vtbl", class_support,
- &user_print_options.vtblprint, _("\
- Set printing of C++ virtual function tables."), _("\
- Show printing of C++ virtual function tables."), NULL,
- NULL,
- show_vtblprint,
- &setprintlist, &showprintlist);
- add_setshow_boolean_cmd ("object", class_support,
- &user_print_options.objectprint, _("\
- Set printing of object's derived type based on vtable info."), _("\
- Show printing of object's derived type based on vtable info."), NULL,
- NULL,
- show_objectprint,
- &setprintlist, &showprintlist);
- obstack_begin (&dont_print_stat_array_obstack,
- 32 * sizeof (struct type *));
- obstack_begin (&dont_print_statmem_obstack,
- 32 * sizeof (CORE_ADDR));
- obstack_begin (&dont_print_vb_obstack,
- 32 * sizeof (struct type *));
- }