From d2e131a198a957499a8d318f8962f4fe75a2b325 Mon Sep 17 00:00:00 2001 From: Per Bothner Date: Tue, 5 Aug 1997 21:59:56 +0000 Subject: [PATCH] * jv-lang.c (get_java_utf8_name): Re-write so it works with implied (missing) data field, as defined by cc1java. (java_link_class_type): Type length and field offset (in interior) now includes object header. Get static fields working. * jv-lang.h (JAVA_OBJECT_SIZE): Update for change in Kaffe. * jv-typeprint.c (java_type_print_derivation_info, java_type_print_base): New functions, for better Java output. * jv-valprint.c: Start to support Java-specific output. --- gdb/ChangeLog | 9 ++ gdb/jv-lang.c | 25 +++-- gdb/jv-lang.h | 2 +- gdb/jv-typeprint.c | 254 ++++++++++++++++++++++++++++++++++++++++++++- gdb/jv-valprint.c | 9 +- 5 files changed, 282 insertions(+), 17 deletions(-) diff --git a/gdb/ChangeLog b/gdb/ChangeLog index 30a9713b9a..2fe53e702e 100644 --- a/gdb/ChangeLog +++ b/gdb/ChangeLog @@ -8,6 +8,15 @@ Tue Aug 5 13:37:14 1997 Per Bothner * value.h, values.c (value_static_field): New function. * cp-valprint.c, valops.c: Modify to use value_static_field. + * jv-lang.c (get_java_utf8_name): Re-write so it works with + implied (missing) data field, as defined by cc1java. + (java_link_class_type): Type length and field offset (in interior) + now includes object header. Get static fields working. + * jv-lang.h (JAVA_OBJECT_SIZE): Update for change in Kaffe. + * jv-typeprint.c (java_type_print_derivation_info, + java_type_print_base): New functions, for better Java output. + * jv-valprint.c: Start to support Java-specific output. + Sun Aug 3 08:18:09 1997 Peter Schauer (pes@regent.e-technik.tu-muenchen.de) * c-valprint.c (c_val_print): Use extract_address to retrieve diff --git a/gdb/jv-lang.c b/gdb/jv-lang.c index 2e722f8d83..22a810af6e 100644 --- a/gdb/jv-lang.c +++ b/gdb/jv-lang.c @@ -197,14 +197,15 @@ get_java_utf8_name (obstack, name) { char *chrs; value_ptr temp = name; - int name_length = (int) value_as_long - (value_struct_elt (&temp, NULL, "length", NULL, "structure")); - temp = name; - temp = value_struct_elt (&temp, NULL, "data", NULL, "structure"); + int name_length; + CORE_ADDR data_addr; + temp = value_struct_elt (&temp, NULL, "length", NULL, "structure"); + name_length = (int) value_as_long (temp); + data_addr = VALUE_ADDRESS (temp) + VALUE_OFFSET (temp) + + TYPE_LENGTH (VALUE_TYPE (temp)); chrs = obstack_alloc (obstack, name_length+1); chrs [name_length] = '\0'; - read_memory_section (VALUE_ADDRESS (temp) + VALUE_OFFSET (temp), - chrs, name_length, NULL); + read_memory_section (data_addr, chrs, name_length, NULL); return chrs; } @@ -378,7 +379,7 @@ java_link_class_type (type, clas) temp = clas; temp = value_struct_elt (&temp, NULL, "bfsize", NULL, "structure"); - TYPE_LENGTH (type) = JAVA_OBJECT_SIZE + value_as_long (temp); + TYPE_LENGTH (type) = value_as_long (temp); fields = NULL; for (i = TYPE_N_BASECLASSES (type); i < nfields; i++) @@ -403,6 +404,8 @@ java_link_class_type (type, clas) temp = field; accflags = value_as_long (value_struct_elt (&temp, NULL, "accflags", NULL, "structure")); + temp = field; + temp = value_struct_elt (&temp, NULL, "info", NULL, "structure"); boffset = value_as_long (value_struct_elt (&temp, NULL, "boffset", NULL, "structure")); if (accflags & 0x0001) /* public access */ @@ -418,13 +421,9 @@ java_link_class_type (type, clas) SET_TYPE_FIELD_PROTECTED (type, i); } if (accflags & 0x0008) /* ACC_STATIC */ - { - TYPE_FIELD_BITPOS (type, i) = -1; - /* Hack for TYPE_FIELD_STATIC_PHYSNAME to prevent a crash. FIXME. */ - type->fields[i].bitsize = (long) "???"; - } + SET_FIELD_PHYSADDR(TYPE_FIELD(type, i), boffset); else - TYPE_FIELD_BITPOS (type, i) = 8 * (JAVA_OBJECT_SIZE + boffset); + TYPE_FIELD_BITPOS (type, i) = 8 * boffset; if (accflags & 0x8000) /* FIELD_UNRESOLVED_FLAG */ { TYPE_FIELD_TYPE (type, i) = get_java_object_type (); /* FIXME */ diff --git a/gdb/jv-lang.h b/gdb/jv-lang.h index 814fb4a0c0..b2417eebb6 100644 --- a/gdb/jv-lang.h +++ b/gdb/jv-lang.h @@ -23,7 +23,7 @@ java_parse PARAMS ((void)); /* Defined in jv-exp.y */ extern void java_error PARAMS ((char *)); /* Defined in jv-exp.y */ -#define JAVA_OBJECT_SIZE (6 * 4) /* sizeof (struct Object) FIXME ! */ +#define JAVA_OBJECT_SIZE (1 * 4) /* sizeof (struct Object) FIXME ! */ extern struct type *java_int_type; extern struct type *java_byte_type; diff --git a/gdb/jv-typeprint.c b/gdb/jv-typeprint.c index 2f31214d60..b3a20cc0ed 100644 --- a/gdb/jv-typeprint.c +++ b/gdb/jv-typeprint.c @@ -21,6 +21,245 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #include "defs.h" #include "symtab.h" #include "gdbtypes.h" +#include "value.h" +#include "demangle.h" +#include "jv-lang.h" +#include "gdb_string.h" + +static void +java_type_print_derivation_info (stream, type) + GDB_FILE *stream; + struct type *type; +{ + char *name; + int i = 0; + int n_bases = TYPE_N_BASECLASSES (type); + int prev = 0; + + for (i = 0; i < n_bases; i++) + { + int kind = BASETYPE_VIA_VIRTUAL(type, i) ? 'I' : 'E'; + fputs_filtered (kind == prev ? ", " + : kind == 'I' ? " implements " + : " extends ", + stream); + prev = kind; + name = type_name_no_tag (TYPE_BASECLASS (type, i)); + fprintf_filtered (stream, "%s", name ? name : "(null)"); + } + if (i > 0) + { + fputs_filtered (" ", stream); + } +} + +/* Print the name of the type (or the ultimate pointer target, + function value or array element), or the description of a + structure or union. + + SHOW positive means print details about the type (e.g. enum values), + and print structure elements passing SHOW - 1 for show. + SHOW negative means just print the type name or struct tag if there is one. + If there is no name, print something sensible but concise like + "struct {...}". + SHOW zero means just print the type name or struct tag if there is one. + If there is no name, print something sensible but not as concise like + "struct {int x; int y;}". + + LEVEL is the number of spaces to indent by. + We increase it for some recursive calls. */ + +void +java_type_print_base (type, stream, show, level) + struct type *type; + GDB_FILE *stream; + int show; + int level; +{ + register int i; + register int len; + char *mangled_name; + char *demangled_name; + QUIT; + + wrap_here (" "); + if (type == NULL) + { + fputs_filtered ("", stream); + return; + } + + /* When SHOW is zero or less, and there is a valid type name, then always + just print the type name directly from the type. */ + + if (show <= 0 + && TYPE_NAME (type) != NULL) + { + fputs_filtered (TYPE_NAME (type), stream); + return; + } + + CHECK_TYPEDEF (type); + + switch (TYPE_CODE (type)) + { + case TYPE_CODE_STRUCT: + fprintf_filtered (stream, "class "); + if (TYPE_TAG_NAME (type) != NULL) + { + fputs_filtered (TYPE_TAG_NAME (type), stream); + if (show > 0) + fputs_filtered (" ", stream); + } + wrap_here (" "); + if (show < 0) + { + /* If we just printed a tag name, no need to print anything else. */ + if (TYPE_TAG_NAME (type) == NULL) + fprintf_filtered (stream, "{...}"); + } + else if (show > 0 || TYPE_TAG_NAME (type) == NULL) + { + java_type_print_derivation_info (stream, type); + + fprintf_filtered (stream, "{\n"); + if ((TYPE_NFIELDS (type) == 0) && (TYPE_NFN_FIELDS (type) == 0)) + { + if (TYPE_FLAGS (type) & TYPE_FLAG_STUB) + fprintfi_filtered (level + 4, stream, "\n"); + else + fprintfi_filtered (level + 4, stream, "\n"); + } + + /* If there is a base class for this type, + do not print the field that it occupies. */ + + len = TYPE_NFIELDS (type); + for (i = TYPE_N_BASECLASSES (type); i < len; i++) + { + QUIT; + /* Don't print out virtual function table. */ + if (STREQN (TYPE_FIELD_NAME (type, i), "_vptr", 5) + && is_cplus_marker ((TYPE_FIELD_NAME (type, i))[5])) + continue; + + /* If this is a C++ class we can print the various C++ section + labels. */ + + print_spaces_filtered (level + 4, stream); + if (HAVE_CPLUS_STRUCT (type)) + { + if (TYPE_FIELD_PROTECTED (type, i)) + fprintf_filtered (stream, "protected "); + else if (TYPE_FIELD_PRIVATE (type, i)) + fprintf_filtered (stream, "private "); + else + fprintf_filtered (stream, "public "); + } + + if (TYPE_FIELD_STATIC (type, i)) + { + fprintf_filtered (stream, "static "); + } + java_print_type (TYPE_FIELD_TYPE (type, i), + TYPE_FIELD_NAME (type, i), + stream, show - 1, level + 4); + fprintf_filtered (stream, ";\n"); + } + + /* If there are both fields and methods, put a space between. */ + len = TYPE_NFN_FIELDS (type); + if (len) + fprintf_filtered (stream, "\n"); + + /* Print out the methods */ + + for (i = 0; i < len; i++) + { + struct fn_field *f = TYPE_FN_FIELDLIST1 (type, i); + int j, len2 = TYPE_FN_FIELDLIST_LENGTH (type, i); + char *method_name = TYPE_FN_FIELDLIST_NAME (type, i); + char *name = type_name_no_tag (type); + int is_constructor = name && STREQ(method_name, name); + for (j = 0; j < len2; j++) + { + char *physname = TYPE_FN_FIELD_PHYSNAME (f, j); + int is_full_physname_constructor = + ((physname[0] == '_' && physname[1] == '_' + && strchr ("0123456789Qt", physname[2])) + || STREQN (physname, "__ct__", 6) + || DESTRUCTOR_PREFIX_P (physname) + || STREQN (physname, "__dt__", 6)); + + QUIT; + print_spaces_filtered (level + 4, stream); + if (TYPE_FN_FIELD_PROTECTED (f, j)) + fprintf_filtered (stream, "protected "); + else if (TYPE_FN_FIELD_PRIVATE (f, j)) + fprintf_filtered (stream, "private "); + else + fprintf_filtered (stream, "public "); + + if (TYPE_FN_FIELD_VIRTUAL_P (f, j)) + fprintf_filtered (stream, "virtual "); + else if (TYPE_FN_FIELD_STATIC_P (f, j)) + fprintf_filtered (stream, "static "); + if (TYPE_TARGET_TYPE (TYPE_FN_FIELD_TYPE (f, j)) == 0) + { + /* Keep GDB from crashing here. */ + fprintf_filtered (stream, " %s;\n", + TYPE_FN_FIELD_PHYSNAME (f, j)); + break; + } + else if (!is_constructor && !is_full_physname_constructor) + { + type_print (TYPE_TARGET_TYPE (TYPE_FN_FIELD_TYPE (f, j)), + "", stream, -1); + fputs_filtered (" ", stream); + } + if (TYPE_FN_FIELD_STUB (f, j)) + /* Build something we can demangle. */ + mangled_name = gdb_mangle_name (type, i, j); + else + mangled_name = TYPE_FN_FIELD_PHYSNAME (f, j); + + demangled_name = + cplus_demangle (mangled_name, + DMGL_ANSI | DMGL_PARAMS | DMGL_JAVA); + if (demangled_name == NULL) + fprintf_filtered (stream, "", + mangled_name); + else + { + char *demangled_no_class = demangled_name; + char *ptr = demangled_name; + for ( ; ; ) + { + char c = *ptr++; + if (c == 0 || c == '(') + break; + if (c == '.') + demangled_no_class = ptr; + } + fputs_filtered (demangled_no_class, stream); + free (demangled_name); + } + + if (TYPE_FN_FIELD_STUB (f, j)) + free (mangled_name); + + fprintf_filtered (stream, ";\n"); + } + } + + fprintfi_filtered (level, stream, "}"); + } + break; + + default: + c_type_print_base (type, stream, show, level); + } +} /* LEVEL is the depth to indent lines by. */ @@ -32,5 +271,18 @@ java_print_type (type, varstring, stream, show, level) int show; int level; { - c_print_type (type, varstring, stream, show, level); + java_type_print_base (type, stream, show, level); + + if (varstring != NULL && *varstring != '\0') + { + fputs_filtered (" ", stream); + fputs_filtered (varstring, stream); + } +#if 0 + /* For demangled function names, we have the arglist as part of the name, + so don't print an additional pair of ()'s */ + + demangled_args = strchr(varstring, '(') != NULL; + c_type_print_varspec_suffix (type, stream, show, 0, demangled_args); +#endif } diff --git a/gdb/jv-valprint.c b/gdb/jv-valprint.c index af60b1754a..06ea084b6b 100644 --- a/gdb/jv-valprint.c +++ b/gdb/jv-valprint.c @@ -59,6 +59,7 @@ java_val_print (type, valaddr, address, stream, format, deref_ref, recurse, int recurse; enum val_prettyprint pretty; { + CHECK_TYPEDEF (type); if (is_object_type (type)) { CORE_ADDR obj_addr = unpack_pointer (type, valaddr); @@ -70,6 +71,10 @@ java_val_print (type, valaddr, address, stream, format, deref_ref, recurse, type = lookup_pointer_type (type); } } - return c_val_print (type, valaddr, address, stream, format, - deref_ref, recurse, pretty); + switch (TYPE_CODE (type)) + { + default: + return c_val_print (type, valaddr, address, stream, format, + deref_ref, recurse, pretty); + } }