* c-lang.h, cp-valprint.c (static_field_print): Make non-static.
authorPer Bothner <per@bothner.com>
Fri, 3 Oct 1997 23:05:12 +0000 (23:05 +0000)
committerPer Bothner <per@bothner.com>
Fri, 3 Oct 1997 23:05:12 +0000 (23:05 +0000)
* 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
gdb/c-lang.h
gdb/cp-valprint.c
gdb/jv-exp.y
gdb/jv-lang.c
gdb/jv-valprint.c
gdb/parse.c
gdb/parser-defs.h

index 0660c4c..7801d17 100644 (file)
@@ -1,3 +1,22 @@
+Fri Oct  3 15:49:18 1997  Per Bothner  <bothner@cygnus.com>
+
+       * 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  <marka@cygnus.com>
 
        * config/mips/tm-mips.h (MAKE_MSYMBOL_SPECIAL): Force MIPS16
index c7b2f55..e38df8e 100644 (file)
@@ -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 *));
 
index e6790a4..f4edef8 100644 (file)
@@ -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;
index 22067a6..9e4c261 100644 (file)
@@ -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;
index 2c0f7f1..0aec002 100644 (file)
@@ -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);
index b4afa1e..d46c4b8 100644 (file)
@@ -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, "<No data fields>");
+  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 ("<optimized out or zero length>", 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 ("<optimized out or zero length>", stream);
+               }
+             else if (TYPE_FIELD_STATIC (type, i))
+               {
+                 value_ptr v = value_static_field (type, i);
+                 if (v == NULL)
+                   fputs_filtered ("<optimized out>", 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,
index e4ff571..7a9410f 100644 (file)
@@ -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;
index 60c12e6..fed5411 100644 (file)
@@ -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