static void java_print_value_fields (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) { int i, len, n_baseclasses; CHECK_TYPEDEF (type); fprintf_filtered (stream, "{"); len = TYPE_NFIELDS (type); n_baseclasses = TYPE_N_BASECLASSES (type); if (n_baseclasses > 0) { int i, n_baseclasses = TYPE_N_BASECLASSES (type); for (i = 0; i < n_baseclasses; i++) { int boffset; struct type *baseclass = check_typedef (TYPE_BASECLASS (type, i)); const char *basename = TYPE_NAME (baseclass); const gdb_byte *base_valaddr; if (BASETYPE_VIA_VIRTUAL (type, i)) continue; if (basename != NULL && strcmp (basename, "java.lang.Object") == 0) continue; boffset = 0; if (options->prettyformat) { fprintf_filtered (stream, "\n"); print_spaces_filtered (2 * (recurse + 1), stream); } fputs_filtered ("<", 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); base_valaddr = valaddr; java_print_value_fields (baseclass, base_valaddr, offset + boffset, address, stream, recurse + 1, val, options); fputs_filtered (", ", stream); } } if (!len && n_baseclasses == 1) fprintf_filtered (stream, "<No data fields>"); else { int fields_seen = 0; for (i = n_baseclasses; i < len; i++) { /* If requested, skip printing of static fields. */ if (field_is_static (&TYPE_FIELD (type, i))) { const char *name = TYPE_FIELD_NAME (type, i); if (!options->static_field_print) continue; if (name != NULL && strcmp (name, "class") == 0) 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), language_cplus, DMGL_PARAMS | DMGL_ANSI); annotate_field_name_end (); fputs_filtered (": ", stream); annotate_field_value (); if (!field_is_static (&TYPE_FIELD (type, i)) && TYPE_FIELD_PACKED (type, i)) { struct value *v; /* Bitfields require special handling, especially due to byte order problems. */ 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 if (!value_bits_valid (val, TYPE_FIELD_BITPOS (type, i), TYPE_FIELD_BITSIZE (type, i))) { val_print_optimized_out (val, stream); } else { struct value_print_options opts; v = value_field_bitfield (type, i, valaddr, offset, val); opts = *options; opts.deref_ref = 0; 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))) { struct value_print_options opts; struct value *v = value_static_field (type, i); struct type *t = check_typedef (value_type (v)); if (TYPE_CODE (t) == TYPE_CODE_STRUCT) v = value_addr (v); opts = *options; opts.deref_ref = 0; common_val_print (v, stream, recurse + 1, &opts, current_language); } else if (TYPE_FIELD_TYPE (type, i) == NULL) fputs_filtered ("<unknown type>", 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 (options->prettyformat) { fprintf_filtered (stream, "\n"); print_spaces_filtered (2 * recurse, stream); } } fprintf_filtered (stream, "}"); }
void pascal_object_print_value_fields (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) { int i, len, n_baseclasses; char *last_dont_print = (char *) obstack_next_free (&dont_print_statmem_obstack); type = check_typedef (type); fprintf_filtered (stream, "{"); len = TYPE_NFIELDS (type); n_baseclasses = TYPE_N_BASECLASSES (type); /* Print out baseclasses such that we don't print duplicates of virtual baseclasses. */ if (n_baseclasses > 0) pascal_object_print_value (type, valaddr, offset, address, stream, recurse + 1, val, options, dont_print_vb); if (!len && n_baseclasses == 1) fprintf_filtered (stream, "<No data fields>"); else { struct obstack tmp_obstack = dont_print_statmem_obstack; int fields_seen = 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); } for (i = n_baseclasses; i < len; i++) { /* If requested, skip printing of static fields. */ if (!options->pascal_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), language_cplus, DMGL_PARAMS | DMGL_ANSI); annotate_field_name_end (); fputs_filtered (" = ", stream); annotate_field_value (); if (!field_is_static (&TYPE_FIELD (type, i)) && TYPE_FIELD_PACKED (type, i)) { struct value *v; /* Bitfields require special handling, especially due to byte order problems. */ 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; v = value_field_bitfield (type, i, valaddr, offset, val); opts.deref_ref = 0; 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))) { /* struct value *v = value_static_field (type, i); v4.17 specific. */ struct value *v; v = value_field_bitfield (type, i, valaddr, offset, val); if (v == NULL) val_print_optimized_out (NULL, stream); else pascal_object_print_static_field (v, stream, recurse + 1, options); } else { struct value_print_options opts = *options; opts.deref_ref = 0; /* val_print (TYPE_FIELD_TYPE (type, i), valaddr + TYPE_FIELD_BITPOS (type, i) / 8, address + TYPE_FIELD_BITPOS (type, i) / 8, 0, stream, format, 0, recurse + 1, pretty); */ 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) { /* 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; } if (options->prettyformat) { fprintf_filtered (stream, "\n"); print_spaces_filtered (2 * recurse, stream); } } fprintf_filtered (stream, "}"); }
extern "C" void monda_val_print (struct type* type, struct frame_info* frame, int embedded_offset, CORE_ADDR address, struct ui_file* stream, int recurse, struct value* val, const struct value_print_options* options, int depth, int max_string_length, int only_print_short_type, int only_print_short_value) { CAMLparam0(); CAMLlocal4(v_type, v_stream, v_value, v_search_path); CAMLlocal2(v_val, v_frame); CAMLlocalN(args, 12); static caml_value* callback = NULL; int is_synthetic_pointer; const gdb_byte* valaddr; /* The try/catch is required so we don't leave local roots incorrectly registered in the case of an exception. We also ensure that any GDB function we call from the OCaml code invoked below (via [caml_callbackN]) never throws any exceptions across the OCaml -> C boundary. If it were to, then we would fail to run the second part of the [caml_start_program] code, causing global variables (e.g. [caml_last_return_address]) to be set incorrectly. */ TRY { if (callback == NULL) { callback = caml_named_value("From_gdb_ocaml.print_value"); assert (callback != NULL); } valaddr = value_contents_for_printing(val); v_value = (valaddr == NULL) ? caml_copy_nativeint(0) : caml_copy_nativeint(*(intnat*) valaddr); /* Determine whether the value is actually a construction made up in the debugger's address space by virtue of interpreting DW_OP_implicit_pointer. The second part of this conditional is really just a sanity check. */ is_synthetic_pointer = (value_lval_const(val) == lval_computed && value_bits_synthetic_pointer(val, 0, sizeof(CORE_ADDR) * 8)); /* fprintf(stderr, "monda_val_print. SP %d *valaddr=%p v_value=%p value_lval_const=%d lval_funcs=%p lazy=%d\n", is_synthetic_pointer, (void*) *(intnat*) valaddr, (void*) v_value, (int) (value_lval_const(val)), value_lval_const(val) == lval_computed ? value_computed_funcs(val) : NULL, value_lazy(val)); */ /* CR mshinwell: improve this test */ #if 0 if ((TYPE_NAME(type) == NULL && !is_synthetic_pointer) || (is_synthetic_pointer && TYPE_CODE(type) != TYPE_CODE_PTR)) { /* fprintf(stderr, "monda_val_print -> c_val_print (1)\n"); fflush(stderr); */ c_val_print(type, frame, valaddr, embedded_offset, address, stream, recurse, val, options, depth); } else #endif { v_type = caml_copy_string(TYPE_NAME(type) == NULL ? "" : TYPE_NAME(type)); v_stream = caml_copy_int64((uint64_t) stream); v_search_path = caml_copy_string(""); /* CR mshinwell: remove */ v_val = caml_copy_nativeint((intnat) val); v_frame = caml_copy_nativeint((intnat) frame); /* N.B. [Store_field] must not be used on [args]! */ args[0] = Val_bool(is_synthetic_pointer); args[1] = v_value; args[2] = v_val; args[3] = v_stream; args[4] = v_type; args[5] = Val_bool(options->summary); args[6] = Val_long(depth); args[7] = Val_long(max_string_length); args[8] = v_search_path; args[9] = Val_bool(only_print_short_type); args[10] = Val_bool(only_print_short_value); args[11] = v_frame; /* fprintf(stderr, "monda_val_print -> OCaml printer. Type '%s'\n", TYPE_NAME(type)); fflush(stderr); */ /* CR mshinwell: This should catch any OCaml exceptions. */ if (caml_callbackN(*callback, 12, args) == Val_false) { /* fprintf(stderr, "monda_val_print -> c_val_print (2)\n"); fflush(stderr); */ c_val_print (type, frame, embedded_offset, address, stream, recurse, val, options); } } } CATCH (exn, RETURN_MASK_ALL) { fprintf(stderr, "monda_val_print: exception: %s\n", exn.message ? exn.message : "<no message>"); CAMLdrop; throw_exception(exn); }