From 8d2755a953cfc95a09b19010aa47d9c998079acf Mon Sep 17 00:00:00 2001 From: Per Bothner Date: Fri, 3 Oct 1997 23:05:12 +0000 Subject: * c-lang.h, cp-valprint.c (static_field_print): Make non-static. * parse.c, parser-defs.h (length_of_subexp): Make non-static. * jv-exp.y (FieldAccess): Handle dollar-VARIABLE as primary. (ArrayAccess): Likewise. Also remove warnings. (CastExpression): Implement (typename) UnaryExpression. (push_qualified_expression_name): Fix small bug. * jv-lang.c: Use TYPE_TAG_NAME, not TYPE_NAME for class names. (_initialize_jave_language): Fix typo (jave -> java). (java_language): Java does *not* have C-style arrays. (java_class_from_object): Make more general (and complicated). (java_link_class_type): Fix typo "super" -> "class". Handle arrays. (java_emit_char, java_printchar): New function. (evaluate_subexp_java case BINOP_SUBSCRIPT): Handle Java arrays. * jv-valprint.c (java_value_print): Implement printing of Java arrays. (java_print_value_fields): New function. (java_val_print): Better printing of TYPE_CODE_CHAR, TYPE_CODE_STRUCT. --- gdb/ChangeLog | 19 ++++ gdb/c-lang.h | 2 + gdb/cp-valprint.c | 2 +- gdb/jv-exp.y | 33 +++++- gdb/jv-lang.c | 182 +++++++++++++++++++++++++++++--- gdb/jv-valprint.c | 307 +++++++++++++++++++++++++++++++++++++++++++++++++++++- gdb/parse.c | 5 +- gdb/parser-defs.h | 3 + 8 files changed, 524 insertions(+), 29 deletions(-) diff --git a/gdb/ChangeLog b/gdb/ChangeLog index 0660c4c..7801d17 100644 --- a/gdb/ChangeLog +++ b/gdb/ChangeLog @@ -1,3 +1,22 @@ +Fri Oct 3 15:49:18 1997 Per Bothner + + * c-lang.h, cp-valprint.c (static_field_print): Make non-static. + * parse.c, parser-defs.h (length_of_subexp): Make non-static. + * jv-exp.y (FieldAccess): Handle dollar-VARIABLE as primary. + (ArrayAccess): Likewise. Also remove warnings. + (CastExpression): Implement (typename) UnaryExpression. + (push_qualified_expression_name): Fix small bug. + * jv-lang.c: Use TYPE_TAG_NAME, not TYPE_NAME for class names. + (_initialize_jave_language): Fix typo (jave -> java). + (java_language): Java does *not* have C-style arrays. + (java_class_from_object): Make more general (and complicated). + (java_link_class_type): Fix typo "super" -> "class". Handle arrays. + (java_emit_char, java_printchar): New function. + (evaluate_subexp_java case BINOP_SUBSCRIPT): Handle Java arrays. + * jv-valprint.c (java_value_print): Implement printing of Java arrays. + (java_print_value_fields): New function. + (java_val_print): Better printing of TYPE_CODE_CHAR, TYPE_CODE_STRUCT. + Fri Oct 3 09:52:26 1997 Mark Alexander * config/mips/tm-mips.h (MAKE_MSYMBOL_SPECIAL): Force MIPS16 diff --git a/gdb/c-lang.h b/gdb/c-lang.h index c7b2f55..e38df8e 100644 --- a/gdb/c-lang.h +++ b/gdb/c-lang.h @@ -59,6 +59,8 @@ c_type_print_varspec_prefix PARAMS ((struct type *, GDB_FILE *, int, int)); extern int vtblprint; /* Controls printing of vtbl's */ +extern int static_field_print; + extern void cp_print_class_member PARAMS ((char *, struct type *, GDB_FILE *, char *)); diff --git a/gdb/cp-valprint.c b/gdb/cp-valprint.c index e6790a4..f4edef8 100644 --- a/gdb/cp-valprint.c +++ b/gdb/cp-valprint.c @@ -35,7 +35,7 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ int vtblprint; /* Controls printing of vtbl's */ int objectprint; /* Controls looking up an object's derived type using what we find in its vtables. */ -static int static_field_print; /* Controls printing of static fields. */ +int static_field_print; /* Controls printing of static fields. */ static struct obstack dont_print_vb_obstack; static struct obstack dont_print_statmem_obstack; diff --git a/gdb/jv-exp.y b/gdb/jv-exp.y index 22067a6..9e4c261 100644 --- a/gdb/jv-exp.y +++ b/gdb/jv-exp.y @@ -210,7 +210,7 @@ StringLiteral: } ; -Literal : +Literal: INTEGER_LITERAL { write_exp_elt_opcode (OP_LONG); write_exp_elt_type ($1.type); @@ -426,6 +426,8 @@ Dims_opt: FieldAccess: Primary '.' SimpleName { push_fieldnames ($3); } +| VARIABLE '.' SimpleName + { push_fieldnames ($3); } /*| SUPER '.' SimpleName { FIXME } */ ; @@ -442,10 +444,10 @@ ArrayAccess: Name '[' Expression ']' /* FIXME - This is nasty - need to shuffle expr stack. */ { error ("`Name[Expr]' not implemented yet - try `(Name)[Expr]'"); } +| VARIABLE '[' Expression ']' + { write_exp_elt_opcode (BINOP_SUBSCRIPT); } | PrimaryNoNewArray '[' Expression ']' - { - warning("array subscripts not implemented for Java"); - write_exp_elt_opcode (BINOP_SUBSCRIPT); } + { write_exp_elt_opcode (BINOP_SUBSCRIPT); } ; PostfixExpression: @@ -503,7 +505,27 @@ CastExpression: { write_exp_elt_opcode (UNOP_CAST); write_exp_elt_type (java_array_type ($2, $3)); write_exp_elt_opcode (UNOP_CAST); } -| '(' Expression ')' UnaryExpressionNotPlusMinus /* FIXME */ +| '(' Expression ')' UnaryExpressionNotPlusMinus + { + int exp_size = expout_ptr; + int last_exp_size = length_of_subexp(expout, expout_ptr); + struct type *type; + int i; + int base = expout_ptr - last_exp_size - 3; + if (base < 0 || expout->elts[base+2].opcode != OP_TYPE) + error ("invalid cast expression"); + type = expout->elts[base+1].type; + /* Remove the 'Expression' and slide the + UnaryExpressionNotPlusMinus down to replace it. */ + for (i = 0; i < last_exp_size; i++) + expout->elts[base + i] = expout->elts[base + i + 3]; + expout_ptr -= 3; + if (TYPE_CODE (type) == TYPE_CODE_STRUCT) + type = lookup_pointer_type (type); + write_exp_elt_opcode (UNOP_CAST); + write_exp_elt_type (type); + write_exp_elt_opcode (UNOP_CAST); + } | '(' Name Dims ')' UnaryExpressionNotPlusMinus { write_exp_elt_opcode (UNOP_CAST); write_exp_elt_type (java_array_type (java_type_from_name ($2), $3)); @@ -1277,6 +1299,7 @@ push_qualified_expression_name (name, dot_index) dot_index++; /* Skip '.' */ name.ptr += dot_index; name.length -= dot_index; + dot_index = 0; while (dot_index < name.length && name.ptr[dot_index] != '.') dot_index++; token.ptr = name.ptr; diff --git a/gdb/jv-lang.c b/gdb/jv-lang.c index 2c0f7f1..0aec002 100644 --- a/gdb/jv-lang.c +++ b/gdb/jv-lang.c @@ -143,7 +143,7 @@ add_class_symbol (type, addr) obstack_alloc (&dynamics_objfile->symbol_obstack, sizeof (struct symbol)); memset (sym, 0, sizeof (struct symbol)); SYMBOL_LANGUAGE (sym) = language_java; - SYMBOL_NAME (sym) = TYPE_NAME (type); + SYMBOL_NAME (sym) = TYPE_TAG_NAME (type); SYMBOL_CLASS (sym) = LOC_TYPEDEF; /* SYMBOL_VALUE (sym) = valu;*/ SYMBOL_TYPE (sym) = type; @@ -177,7 +177,7 @@ java_lookup_class (name) type = alloc_type (objfile); TYPE_CODE (type) = TYPE_CODE_STRUCT; INIT_CPLUS_SPECIFIC (type); - TYPE_NAME (type) = obsavestring (name, strlen(name), &objfile->type_obstack); + TYPE_TAG_NAME (type) = obsavestring (name, strlen(name), &objfile->type_obstack); TYPE_FLAGS (type) |= TYPE_FLAG_STUB; TYPE ? = addr; return type; @@ -213,7 +213,22 @@ value_ptr java_class_from_object (obj_val) value_ptr obj_val; { - value_ptr dtable_val = value_struct_elt (&obj_val, NULL, "dtable", NULL, "structure"); + /* This is all rather inefficient, since the offsets of dtable and + class are fixed. FIXME */ + value_ptr dtable_val; + + if (TYPE_CODE (VALUE_TYPE (obj_val)) == TYPE_CODE_PTR + && TYPE_LENGTH (TYPE_TARGET_TYPE (VALUE_TYPE (obj_val))) == 0) + { + struct symbol *sym; + sym = lookup_symbol ("Hjava_lang_Object", NULL, STRUCT_NAMESPACE, + (int *) 0, (struct symtab **) NULL); + if (sym != NULL) + obj_val = value_at (VALUE_TYPE (sym), + value_as_pointer (obj_val), NULL); + } + + dtable_val = value_struct_elt (&obj_val, NULL, "dtable", NULL, "structure"); return value_struct_elt (&dtable_val, NULL, "class", NULL, "structure"); } @@ -303,7 +318,7 @@ type_from_class (clas) } ALLOCATE_CPLUS_STRUCT_TYPE (type); - TYPE_NAME (type) = name; + TYPE_TAG_NAME (type) = name; add_class_symtab_symbol (add_class_symbol (type, addr)); return java_link_class_type (type, clas); @@ -318,7 +333,7 @@ java_link_class_type (type, clas) { value_ptr temp; char *unqualified_name; - char *name = TYPE_NAME (type); + char *name = TYPE_TAG_NAME (type); int ninterfaces, nfields, nmethods; int type_is_object = 0; struct fn_field *fn_fields; @@ -385,15 +400,22 @@ java_link_class_type (type, clas) } - temp = clas; - temp = value_struct_elt (&temp, NULL, "bfsize", NULL, "structure"); - TYPE_LENGTH (type) = value_as_long (temp); + if (name[0] == '[' && tsuper != NULL) + { + TYPE_LENGTH (type) = TYPE_LENGTH (tsuper) + 4; /* size with "length" */ + } + else + { + temp = clas; + temp = value_struct_elt (&temp, NULL, "bfsize", NULL, "structure"); + TYPE_LENGTH (type) = value_as_long (temp); + } fields = NULL; nfields--; /* First set up dummy "class" field. */ SET_FIELD_PHYSADDR (TYPE_FIELD (type, nfields), VALUE_ADDRESS (clas) + VALUE_OFFSET (clas)); - TYPE_FIELD_NAME (type, nfields) = "super"; + TYPE_FIELD_NAME (type, nfields) = "class"; TYPE_FIELD_TYPE (type, nfields) = VALUE_TYPE (clas); SET_TYPE_FIELD_PRIVATE (type, nfields); @@ -556,7 +578,7 @@ is_object_type (type) return 0; while (TYPE_N_BASECLASSES (ttype) > 0) ttype = TYPE_BASECLASS (ttype, 0); - name = TYPE_NAME (ttype); + name = TYPE_TAG_NAME (ttype); if (name != NULL && strcmp (name, "java.lang.Object") == 0) return 1; name = TYPE_NFIELDS (ttype) > 0 ? TYPE_FIELD_NAME (ttype, 0) : (char*)0; @@ -674,6 +696,69 @@ java_value_string (ptr, len) error ("not implemented - java_value_string"); /* FIXME */ } +/* Print the character C on STREAM as part of the contents of a literal + string whose delimiter is QUOTER. Note that that format for printing + characters and strings is language specific. */ + +void +java_emit_char (c, stream, quoter) + register int c; + GDB_FILE *stream; + int quoter; +{ + if (PRINT_LITERAL_FORM (c)) + { + if (c == '\\' || c == quoter) + { + fputs_filtered ("\\", stream); + } + fprintf_filtered (stream, "%c", c); + } + else + { + switch (c) + { + case '\n': + fputs_filtered ("\\n", stream); + break; + case '\b': + fputs_filtered ("\\b", stream); + break; + case '\t': + fputs_filtered ("\\t", stream); + break; + case '\f': + fputs_filtered ("\\f", stream); + break; + case '\r': + fputs_filtered ("\\r", stream); + break; + case '\033': + fputs_filtered ("\\e", stream); + break; + case '\007': + fputs_filtered ("\\a", stream); + break; + default: + if (c < 256) + fprintf_filtered (stream, "\\%.3o", (unsigned int) c); + else + fprintf_filtered (stream, "\\u%.4x", (unsigned int) c); + break; + } + } +} + +void +java_printchar (c, stream) + int c; + GDB_FILE *stream; +{ + fputs_filtered ("'", stream); + java_emit_char (c, stream, '\''); + fputs_filtered ("'", stream); +} + static value_ptr evaluate_subexp_java (expect_type, exp, pos, noside) struct type *expect_type; @@ -683,8 +768,10 @@ evaluate_subexp_java (expect_type, exp, pos, noside) { int pc = *pos; int i; + char *name; enum exp_opcode op = exp->elts[*pos].opcode; - value_ptr arg1; + value_ptr arg1, arg2; + struct type *type; switch (op) { case UNOP_IND: @@ -700,6 +787,70 @@ evaluate_subexp_java (expect_type, exp, pos, noside) if (noside == EVAL_SKIP) goto nosideret; return value_ind (arg1); + + case BINOP_SUBSCRIPT: + (*pos)++; + arg1 = evaluate_subexp_with_coercion (exp, pos, noside); + arg2 = evaluate_subexp_with_coercion (exp, pos, noside); + if (noside == EVAL_SKIP) + goto nosideret; + /* If the user attempts to subscript something that is not an + array or pointer type (like a plain int variable for example), + then report this as an error. */ + + COERCE_REF (arg1); + type = check_typedef (VALUE_TYPE (arg1)); + name = TYPE_NAME (type); + if (TYPE_CODE (type) == TYPE_CODE_PTR) + { + type = check_typedef (TYPE_TARGET_TYPE (type)); + if (TYPE_CODE (type) == TYPE_CODE_STRUCT + && TYPE_TAG_NAME (type) != NULL + && TYPE_TAG_NAME (type)[0] == '[') + { + CORE_ADDR address; + long length, index; + struct type *el_type; + char buf4[4]; + + value_ptr clas = java_class_from_object(arg1); + value_ptr temp = clas; + /* Get CLASS_ELEMENT_TYPE of the array type. */ + temp = value_struct_elt (&temp, NULL, "methods", + NULL, "structure"); + VALUE_TYPE (temp) = VALUE_TYPE (clas); + el_type = type_from_class (temp); + if (TYPE_CODE (el_type) == TYPE_CODE_STRUCT) + el_type = lookup_pointer_type (el_type); + + if (noside == EVAL_AVOID_SIDE_EFFECTS) + return value_zero (el_type, VALUE_LVAL (arg1)); + address = value_as_pointer (arg1); + address += JAVA_OBJECT_SIZE; + read_memory (address, buf4, 4); + length = (long) extract_signed_integer (buf4, 4); + index = (long) value_as_long (arg2); + if (index >= length || index < 0) + error ("array index (%ld) out of bounds (length: %ld)", + index, length); + address = (address + 4) + index * TYPE_LENGTH (el_type); + return value_at (el_type, address, NULL); + } + } + else if (TYPE_CODE (type) == TYPE_CODE_ARRAY) + { + if (noside == EVAL_AVOID_SIDE_EFFECTS) + return value_zero (TYPE_TARGET_TYPE (type), VALUE_LVAL (arg1)); + else + return value_subscript (arg1, arg2); + } + if (name == NULL) + name == TYPE_TAG_NAME (type); + if (name) + error ("cannot subscript something of type `%s'", name); + else + error ("cannot subscript requested type"); + case OP_STRING: (*pos)++; i = longest_to_int (exp->elts[pc + 1].longconst); @@ -707,9 +858,10 @@ evaluate_subexp_java (expect_type, exp, pos, noside) if (noside == EVAL_SKIP) goto nosideret; return java_value_string (&exp->elts[pc + 2].string, i); + case STRUCTOP_STRUCT: arg1 = evaluate_subexp_standard (expect_type, exp, pos, noside); - /* Convert object field (such as .class) to reference. */ + /* Convert object field (such as TYPE.class) to reference. */ if (TYPE_CODE (VALUE_TYPE (arg1)) == TYPE_CODE_STRUCT) arg1 = value_addr (arg1); return arg1; @@ -791,7 +943,7 @@ const struct language_defn java_language_defn = { java_parse, java_error, evaluate_subexp_java, - c_printchar, /* Print a character constant */ + java_printchar, /* Print a character constant */ c_printstr, /* Function to print string constant */ java_create_fundamental_type, /* Create fundamental type in this language */ java_print_type, /* Print a type using appropriate syntax */ @@ -802,14 +954,14 @@ const struct language_defn java_language_defn = { {"%ld", "", "d", ""}, /* Decimal format info */ {"0x%lx", "0x", "x", ""}, /* Hex format info */ java_op_print_tab, /* expression operators for printing */ - 1, /* c-style arrays */ + 0, /* not c-style arrays */ 0, /* String lower bound */ &builtin_type_char, /* Type of string elements */ LANG_MAGIC }; void -_initialize_jave_language () +_initialize_java_language () { java_int_type = init_type (TYPE_CODE_INT, 4, 0, "int", NULL); diff --git a/gdb/jv-valprint.c b/gdb/jv-valprint.c index b4afa1e..d46c4b8 100644 --- a/gdb/jv-valprint.c +++ b/gdb/jv-valprint.c @@ -56,10 +56,95 @@ java_value_print (val, stream, format, pretty) if (TYPE_CODE (type) == TYPE_CODE_STRUCT && TYPE_TAG_NAME (type) != NULL && TYPE_TAG_NAME (type)[0] == '[') { - value_ptr len = value_at (java_int_type, address + JAVA_OBJECT_SIZE, 0); - long length = value_as_long (len); - fprintf_filtered (stream, "{"); - fprintf_filtered (stream, "length = %ld", length); + char buf4[4]; + long length; + unsigned int things_printed = 0; + int i = 0; + int reps; + read_memory (address + JAVA_OBJECT_SIZE, buf4, 4); + length = (long) extract_signed_integer (buf4, 4); + fprintf_filtered (stream, "{length: %ld", length); + if (TYPE_TAG_NAME (type)[1] == 'L' + || TYPE_TAG_NAME (type)[1] == '[') + { + CORE_ADDR element, next_element; + address += JAVA_OBJECT_SIZE + 4; /* Skip object header and length. */ + while (i < length && things_printed < print_max) + { + char buf[TARGET_PTR_BIT / HOST_CHAR_BIT]; + fputs_filtered (", ", stream); + wrap_here (n_spaces (2)); + if (i > 0) + element = next_element; + else + { + read_memory (address, buf, sizeof(buf)); + address += TARGET_PTR_BIT / HOST_CHAR_BIT; + element = extract_address (buf, sizeof(buf)); + } + for (reps = 1; i + reps < length; reps++) + { + read_memory (address, buf, sizeof(buf)); + address += TARGET_PTR_BIT / HOST_CHAR_BIT; + next_element = extract_address (buf, sizeof(buf)); + if (next_element != element) + break; + } + if (reps == 1) + fprintf_filtered (stream, "%d: ", i); + else + fprintf_filtered (stream, "%d..%d: ", i, i + reps - 1); + if (element == 0) + fprintf_filtered (stream, "null"); + else + fprintf_filtered (stream, "@%x", element); + things_printed++; + i += reps; + } + } + else + { + struct type *el_type = java_primitive_type (TYPE_TAG_NAME (type)[1]); + value_ptr v = allocate_value (el_type); + value_ptr next_v = allocate_value (el_type); + VALUE_ADDRESS (v) = address + JAVA_OBJECT_SIZE + 4; + VALUE_ADDRESS (next_v) = VALUE_ADDRESS (v); + + while (i < length && things_printed < print_max) + { + fputs_filtered (", ", stream); + wrap_here (n_spaces (2)); + if (i > 0) + { + value_ptr tmp = next_v; next_v = v; v = tmp; + } + else + { + VALUE_LAZY (v) = 1; + VALUE_OFFSET (v) = 0; + } + VALUE_OFFSET (next_v) = VALUE_OFFSET (v); + for (reps = 1; i + reps < length; reps++) + { + VALUE_LAZY (next_v) = 1; + VALUE_OFFSET (next_v) += TYPE_LENGTH (el_type); + if (memcmp (VALUE_CONTENTS (v), VALUE_CONTENTS (next_v), + TYPE_LENGTH (el_type)) != 0) + break; + } + if (reps == 1) + fprintf_filtered (stream, "%d: ", i); + else + fprintf_filtered (stream, "%d..%d: ", i, i + reps - 1); + val_print (VALUE_TYPE (v), VALUE_CONTENTS (v), 0, + stream, format, 2, 1, pretty); + things_printed++; + i += reps; + } + } + + if (i < length) + fprintf_filtered (stream, "..."); fprintf_filtered (stream, "}"); return 0; } @@ -68,6 +153,206 @@ java_value_print (val, stream, format, pretty) stream, format, 1, 0, pretty)); } +/* TYPE, VALADDR, ADDRESS, STREAM, RECURSE, and PRETTY have the + same meanings as in cp_print_value and c_val_print. + + DONT_PRINT is an array of baseclass types that we + should not print, or zero if called from top level. */ + +void +java_print_value_fields (type, valaddr, address, stream, + format, recurse, pretty) + struct type *type; + char *valaddr; + CORE_ADDR address; + GDB_FILE *stream; + int format; + int recurse; + enum val_prettyprint pretty; +{ + 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)); + char *basename = TYPE_NAME (baseclass); + char *base_valaddr; + + if (BASETYPE_VIA_VIRTUAL (type, i)) + continue; + + if (basename != NULL && strcmp (basename, "java.lang.Object") == 0) + continue; + + boffset = 0; + + if (pretty) + { + 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, address + boffset, + stream, format, recurse+1, pretty); + fputs_filtered (", ", stream); + + flush_it: + ; + } + + } + + if (!len && n_baseclasses == 1) + fprintf_filtered (stream, ""); + else + { + extern int inspect_it; + int fields_seen = 0; + + for (i = n_baseclasses; i < len; i++) + { + /* If requested, skip printing of static fields. */ + if (TYPE_FIELD_STATIC (type, i)) + { + char *name = TYPE_FIELD_NAME (type, i); + if (!static_field_print) + continue; + if (name != NULL && strcmp (name, "class") == 0) + continue; + } + if (fields_seen) + fprintf_filtered (stream, ", "); + else if (n_baseclasses > 0) + { + if (pretty) + { + 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 (pretty) + { + fprintf_filtered (stream, "\n"); + print_spaces_filtered (2 + 2 * recurse, stream); + } + else + { + wrap_here (n_spaces (2 + 2 * recurse)); + } + if (inspect_it) + { + if (TYPE_CODE (TYPE_FIELD_TYPE (type, i)) == TYPE_CODE_PTR) + fputs_filtered ("\"( ptr \"", stream); + else + fputs_filtered ("\"( nodef \"", stream); + if (TYPE_FIELD_STATIC (type, i)) + fputs_filtered ("static ", stream); + fprintf_symbol_filtered (stream, TYPE_FIELD_NAME (type, i), + language_cplus, + DMGL_PARAMS | DMGL_ANSI); + fputs_filtered ("\" \"", stream); + fprintf_symbol_filtered (stream, TYPE_FIELD_NAME (type, i), + language_cplus, + DMGL_PARAMS | DMGL_ANSI); + fputs_filtered ("\") \"", stream); + } + else + { + annotate_field_begin (TYPE_FIELD_TYPE (type, i)); + + if (TYPE_FIELD_STATIC (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 (!TYPE_FIELD_STATIC (type, i) && TYPE_FIELD_PACKED (type, i)) + { + value_ptr v; + + /* Bitfields require special handling, especially due to byte + order problems. */ + if (TYPE_FIELD_IGNORE (type, i)) + { + fputs_filtered ("", stream); + } + else + { + v = value_from_longest (TYPE_FIELD_TYPE (type, i), + unpack_field_as_long (type, valaddr, i)); + + val_print (TYPE_FIELD_TYPE(type, i), VALUE_CONTENTS (v), 0, + stream, format, 0, recurse + 1, pretty); + } + } + else + { + if (TYPE_FIELD_IGNORE (type, i)) + { + fputs_filtered ("", stream); + } + else if (TYPE_FIELD_STATIC (type, i)) + { + value_ptr v = value_static_field (type, i); + if (v == NULL) + fputs_filtered ("", stream); + else + { + struct type *t = check_typedef (VALUE_TYPE (v)); + if (TYPE_CODE (t) == TYPE_CODE_STRUCT) + v = value_addr (v); + val_print (VALUE_TYPE (v), + VALUE_CONTENTS (v), VALUE_ADDRESS (v), + stream, format, 0, recurse+1, pretty); + } + } + else + { + val_print (TYPE_FIELD_TYPE (type, i), + valaddr + TYPE_FIELD_BITPOS (type, i) / 8, + address + TYPE_FIELD_BITPOS (type, i) / 8, + stream, format, 0, recurse + 1, pretty); + } + } + annotate_field_end (); + } + + if (pretty) + { + fprintf_filtered (stream, "\n"); + print_spaces_filtered (2 * recurse, stream); + } + } + fprintf_filtered (stream, "}"); +} + int java_val_print (type, valaddr, address, stream, format, deref_ref, recurse, pretty) @@ -130,6 +415,20 @@ java_val_print (type, valaddr, address, stream, format, deref_ref, recurse, } return i; } + case TYPE_CODE_CHAR: + format = format ? format : output_format; + if (format) + { + print_scalar_formatted (valaddr, type, format, 0, stream); + } + else + { + LA_PRINT_CHAR ((int) unpack_long (type, valaddr), stream); + } + break; + case TYPE_CODE_STRUCT: + java_print_value_fields (type, valaddr, address, stream, format, + recurse, pretty); break; default: return c_val_print (type, valaddr, address, stream, format, diff --git a/gdb/parse.c b/gdb/parse.c index e4ff571..7a9410f 100644 --- a/gdb/parse.c +++ b/gdb/parse.c @@ -59,9 +59,6 @@ free_funcalls PARAMS ((void)); static void prefixify_expression PARAMS ((struct expression *)); -static int -length_of_subexp PARAMS ((struct expression *, int)); - static void prefixify_subexp PARAMS ((struct expression *, struct expression *, int, int)); @@ -525,7 +522,7 @@ prefixify_expression (expr) /* Return the number of exp_elements in the subexpression of EXPR whose last exp_element is at index ENDPOS - 1 in EXPR. */ -static int +int length_of_subexp (expr, endpos) register struct expression *expr; register int endpos; diff --git a/gdb/parser-defs.h b/gdb/parser-defs.h index 60c12e6..fed5411 100644 --- a/gdb/parser-defs.h +++ b/gdb/parser-defs.h @@ -133,6 +133,9 @@ pop_type PARAMS ((void)); extern int pop_type_int PARAMS ((void)); +extern int +length_of_subexp PARAMS ((struct expression *, int)); + extern struct type *follow_types PARAMS ((struct type *)); /* During parsing of a C expression, the pointer to the next character -- cgit v1.1