xref: /dflybsd-src/contrib/gdb-7/gdb/jv-lang.c (revision cf7f2e2d389e8012d562650bd94d7e433f449d6e)
15796c8dcSSimon Schubert /* Java language support routines for GDB, the GNU debugger.
25796c8dcSSimon Schubert 
3*cf7f2e2dSJohn Marino    Copyright (C) 1997, 1998, 1999, 2000, 2003, 2004, 2005, 2007, 2008, 2009,
4*cf7f2e2dSJohn Marino    2010 Free Software Foundation, Inc.
55796c8dcSSimon Schubert 
65796c8dcSSimon Schubert    This file is part of GDB.
75796c8dcSSimon Schubert 
85796c8dcSSimon Schubert    This program is free software; you can redistribute it and/or modify
95796c8dcSSimon Schubert    it under the terms of the GNU General Public License as published by
105796c8dcSSimon Schubert    the Free Software Foundation; either version 3 of the License, or
115796c8dcSSimon Schubert    (at your option) any later version.
125796c8dcSSimon Schubert 
135796c8dcSSimon Schubert    This program is distributed in the hope that it will be useful,
145796c8dcSSimon Schubert    but WITHOUT ANY WARRANTY; without even the implied warranty of
155796c8dcSSimon Schubert    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
165796c8dcSSimon Schubert    GNU General Public License for more details.
175796c8dcSSimon Schubert 
185796c8dcSSimon Schubert    You should have received a copy of the GNU General Public License
195796c8dcSSimon Schubert    along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
205796c8dcSSimon Schubert 
215796c8dcSSimon Schubert #include "defs.h"
225796c8dcSSimon Schubert #include "symtab.h"
235796c8dcSSimon Schubert #include "gdbtypes.h"
245796c8dcSSimon Schubert #include "expression.h"
255796c8dcSSimon Schubert #include "parser-defs.h"
265796c8dcSSimon Schubert #include "language.h"
275796c8dcSSimon Schubert #include "gdbtypes.h"
285796c8dcSSimon Schubert #include "symtab.h"
295796c8dcSSimon Schubert #include "symfile.h"
305796c8dcSSimon Schubert #include "objfiles.h"
315796c8dcSSimon Schubert #include "gdb_string.h"
325796c8dcSSimon Schubert #include "value.h"
335796c8dcSSimon Schubert #include "c-lang.h"
345796c8dcSSimon Schubert #include "jv-lang.h"
355796c8dcSSimon Schubert #include "gdbcore.h"
365796c8dcSSimon Schubert #include "block.h"
375796c8dcSSimon Schubert #include "demangle.h"
385796c8dcSSimon Schubert #include "dictionary.h"
395796c8dcSSimon Schubert #include <ctype.h>
405796c8dcSSimon Schubert #include "gdb_assert.h"
415796c8dcSSimon Schubert 
425796c8dcSSimon Schubert /* Local functions */
435796c8dcSSimon Schubert 
445796c8dcSSimon Schubert extern void _initialize_java_language (void);
455796c8dcSSimon Schubert 
465796c8dcSSimon Schubert static int java_demangled_signature_length (char *);
475796c8dcSSimon Schubert static void java_demangled_signature_copy (char *, char *);
485796c8dcSSimon Schubert 
49*cf7f2e2dSJohn Marino static struct symtab *get_java_class_symtab (struct gdbarch *gdbarch);
505796c8dcSSimon Schubert static char *get_java_utf8_name (struct obstack *obstack, struct value *name);
515796c8dcSSimon Schubert static int java_class_is_primitive (struct value *clas);
525796c8dcSSimon Schubert static struct value *java_value_string (char *ptr, int len);
535796c8dcSSimon Schubert 
545796c8dcSSimon Schubert static void java_emit_char (int c, struct type *type,
555796c8dcSSimon Schubert 			    struct ui_file * stream, int quoter);
565796c8dcSSimon Schubert 
575796c8dcSSimon Schubert static char *java_class_name_from_physname (const char *physname);
585796c8dcSSimon Schubert 
59*cf7f2e2dSJohn Marino static const struct objfile_data *jv_dynamics_objfile_data_key;
60*cf7f2e2dSJohn Marino static const struct objfile_data *jv_type_objfile_data_key;
61*cf7f2e2dSJohn Marino 
625796c8dcSSimon Schubert /* This objfile contains symtabs that have been dynamically created
635796c8dcSSimon Schubert    to record dynamically loaded Java classes and dynamically
645796c8dcSSimon Schubert    compiled java methods. */
655796c8dcSSimon Schubert 
665796c8dcSSimon Schubert static struct objfile *dynamics_objfile = NULL;
675796c8dcSSimon Schubert 
68*cf7f2e2dSJohn Marino /* symtab contains classes read from the inferior. */
69*cf7f2e2dSJohn Marino 
70*cf7f2e2dSJohn Marino static struct symtab *class_symtab = NULL;
71*cf7f2e2dSJohn Marino 
725796c8dcSSimon Schubert static struct type *java_link_class_type (struct gdbarch *,
735796c8dcSSimon Schubert 					  struct type *, struct value *);
745796c8dcSSimon Schubert 
75*cf7f2e2dSJohn Marino /* A function called when the dynamics_objfile is freed.  We use this
76*cf7f2e2dSJohn Marino    to clean up some internal state.  */
77*cf7f2e2dSJohn Marino static void
78*cf7f2e2dSJohn Marino jv_per_objfile_free (struct objfile *objfile, void *ignore)
79*cf7f2e2dSJohn Marino {
80*cf7f2e2dSJohn Marino   gdb_assert (objfile == dynamics_objfile);
81*cf7f2e2dSJohn Marino   /* Clean up all our cached state.  These objects are all allocated
82*cf7f2e2dSJohn Marino      in the dynamics_objfile, so we don't need to actually free
83*cf7f2e2dSJohn Marino      anything.  */
84*cf7f2e2dSJohn Marino   dynamics_objfile = NULL;
85*cf7f2e2dSJohn Marino   class_symtab = NULL;
86*cf7f2e2dSJohn Marino }
87*cf7f2e2dSJohn Marino 
885796c8dcSSimon Schubert /* FIXME: carlton/2003-02-04: This is the main or only caller of
895796c8dcSSimon Schubert    allocate_objfile with first argument NULL; as a result, this code
905796c8dcSSimon Schubert    breaks every so often.  Somebody should write a test case that
915796c8dcSSimon Schubert    exercises GDB in various ways (e.g. something involving loading a
925796c8dcSSimon Schubert    dynamic library) after this code has been called.  */
935796c8dcSSimon Schubert 
945796c8dcSSimon Schubert static struct objfile *
95*cf7f2e2dSJohn Marino get_dynamics_objfile (struct gdbarch *gdbarch)
965796c8dcSSimon Schubert {
975796c8dcSSimon Schubert   if (dynamics_objfile == NULL)
985796c8dcSSimon Schubert     {
99*cf7f2e2dSJohn Marino       /* Mark it as shared so that it is cleared when the inferior is
100*cf7f2e2dSJohn Marino 	 re-run.  */
101*cf7f2e2dSJohn Marino       dynamics_objfile = allocate_objfile (NULL, OBJF_SHARED);
102*cf7f2e2dSJohn Marino       dynamics_objfile->gdbarch = gdbarch;
103*cf7f2e2dSJohn Marino       /* We don't have any data to store, but this lets us get a
104*cf7f2e2dSJohn Marino 	 notification when the objfile is destroyed.  Since we have to
105*cf7f2e2dSJohn Marino 	 store a non-NULL value, we just pick something arbitrary and
106*cf7f2e2dSJohn Marino 	 safe.  */
107*cf7f2e2dSJohn Marino       set_objfile_data (dynamics_objfile, jv_dynamics_objfile_data_key,
108*cf7f2e2dSJohn Marino 			&dynamics_objfile);
1095796c8dcSSimon Schubert     }
1105796c8dcSSimon Schubert   return dynamics_objfile;
1115796c8dcSSimon Schubert }
1125796c8dcSSimon Schubert 
1135796c8dcSSimon Schubert static void free_class_block (struct symtab *symtab);
1145796c8dcSSimon Schubert 
1155796c8dcSSimon Schubert static struct symtab *
116*cf7f2e2dSJohn Marino get_java_class_symtab (struct gdbarch *gdbarch)
1175796c8dcSSimon Schubert {
1185796c8dcSSimon Schubert   if (class_symtab == NULL)
1195796c8dcSSimon Schubert     {
120*cf7f2e2dSJohn Marino       struct objfile *objfile = get_dynamics_objfile (gdbarch);
1215796c8dcSSimon Schubert       struct blockvector *bv;
1225796c8dcSSimon Schubert       struct block *bl;
123*cf7f2e2dSJohn Marino 
1245796c8dcSSimon Schubert       class_symtab = allocate_symtab ("<java-classes>", objfile);
1255796c8dcSSimon Schubert       class_symtab->language = language_java;
1265796c8dcSSimon Schubert       bv = (struct blockvector *)
1275796c8dcSSimon Schubert 	obstack_alloc (&objfile->objfile_obstack,
1285796c8dcSSimon Schubert 		       sizeof (struct blockvector) + sizeof (struct block *));
1295796c8dcSSimon Schubert       BLOCKVECTOR_NBLOCKS (bv) = 1;
1305796c8dcSSimon Schubert       BLOCKVECTOR (class_symtab) = bv;
1315796c8dcSSimon Schubert 
1325796c8dcSSimon Schubert       /* Allocate dummy STATIC_BLOCK. */
1335796c8dcSSimon Schubert       bl = allocate_block (&objfile->objfile_obstack);
1345796c8dcSSimon Schubert       BLOCK_DICT (bl) = dict_create_linear (&objfile->objfile_obstack,
1355796c8dcSSimon Schubert 					    NULL);
1365796c8dcSSimon Schubert       BLOCKVECTOR_BLOCK (bv, STATIC_BLOCK) = bl;
1375796c8dcSSimon Schubert 
1385796c8dcSSimon Schubert       /* Allocate GLOBAL_BLOCK.  */
1395796c8dcSSimon Schubert       bl = allocate_block (&objfile->objfile_obstack);
1405796c8dcSSimon Schubert       BLOCK_DICT (bl) = dict_create_hashed_expandable ();
1415796c8dcSSimon Schubert       BLOCKVECTOR_BLOCK (bv, GLOBAL_BLOCK) = bl;
1425796c8dcSSimon Schubert       class_symtab->free_func = free_class_block;
1435796c8dcSSimon Schubert     }
1445796c8dcSSimon Schubert   return class_symtab;
1455796c8dcSSimon Schubert }
1465796c8dcSSimon Schubert 
1475796c8dcSSimon Schubert static void
1485796c8dcSSimon Schubert add_class_symtab_symbol (struct symbol *sym)
1495796c8dcSSimon Schubert {
150*cf7f2e2dSJohn Marino   struct symtab *symtab
151*cf7f2e2dSJohn Marino     = get_java_class_symtab (get_objfile_arch (SYMBOL_SYMTAB (sym)->objfile));
1525796c8dcSSimon Schubert   struct blockvector *bv = BLOCKVECTOR (symtab);
153*cf7f2e2dSJohn Marino 
1545796c8dcSSimon Schubert   dict_add_symbol (BLOCK_DICT (BLOCKVECTOR_BLOCK (bv, GLOBAL_BLOCK)), sym);
1555796c8dcSSimon Schubert }
1565796c8dcSSimon Schubert 
1575796c8dcSSimon Schubert static struct symbol *
1585796c8dcSSimon Schubert add_class_symbol (struct type *type, CORE_ADDR addr)
1595796c8dcSSimon Schubert {
1605796c8dcSSimon Schubert   struct symbol *sym;
161*cf7f2e2dSJohn Marino 
1625796c8dcSSimon Schubert   sym = (struct symbol *)
1635796c8dcSSimon Schubert     obstack_alloc (&dynamics_objfile->objfile_obstack, sizeof (struct symbol));
1645796c8dcSSimon Schubert   memset (sym, 0, sizeof (struct symbol));
1655796c8dcSSimon Schubert   SYMBOL_LANGUAGE (sym) = language_java;
1665796c8dcSSimon Schubert   SYMBOL_SET_LINKAGE_NAME (sym, TYPE_TAG_NAME (type));
1675796c8dcSSimon Schubert   SYMBOL_CLASS (sym) = LOC_TYPEDEF;
1685796c8dcSSimon Schubert   /*  SYMBOL_VALUE (sym) = valu; */
1695796c8dcSSimon Schubert   SYMBOL_TYPE (sym) = type;
1705796c8dcSSimon Schubert   SYMBOL_DOMAIN (sym) = STRUCT_DOMAIN;
1715796c8dcSSimon Schubert   SYMBOL_VALUE_ADDRESS (sym) = addr;
1725796c8dcSSimon Schubert   return sym;
1735796c8dcSSimon Schubert }
1745796c8dcSSimon Schubert 
1755796c8dcSSimon Schubert /* Free the dynamic symbols block.  */
1765796c8dcSSimon Schubert static void
1775796c8dcSSimon Schubert free_class_block (struct symtab *symtab)
1785796c8dcSSimon Schubert {
1795796c8dcSSimon Schubert   struct blockvector *bv = BLOCKVECTOR (symtab);
1805796c8dcSSimon Schubert   struct block *bl = BLOCKVECTOR_BLOCK (bv, GLOBAL_BLOCK);
1815796c8dcSSimon Schubert 
1825796c8dcSSimon Schubert   dict_free (BLOCK_DICT (bl));
1835796c8dcSSimon Schubert }
1845796c8dcSSimon Schubert 
1855796c8dcSSimon Schubert struct type *
1865796c8dcSSimon Schubert java_lookup_class (char *name)
1875796c8dcSSimon Schubert {
1885796c8dcSSimon Schubert   struct symbol *sym;
189*cf7f2e2dSJohn Marino 
1905796c8dcSSimon Schubert   sym = lookup_symbol (name, expression_context_block, STRUCT_DOMAIN, NULL);
1915796c8dcSSimon Schubert   if (sym != NULL)
1925796c8dcSSimon Schubert     return SYMBOL_TYPE (sym);
1935796c8dcSSimon Schubert   /* FIXME - should search inferior's symbol table. */
1945796c8dcSSimon Schubert   return NULL;
1955796c8dcSSimon Schubert }
1965796c8dcSSimon Schubert 
1975796c8dcSSimon Schubert /* Return a nul-terminated string (allocated on OBSTACK) for
1985796c8dcSSimon Schubert    a name given by NAME (which has type Utf8Const*). */
1995796c8dcSSimon Schubert 
2005796c8dcSSimon Schubert char *
2015796c8dcSSimon Schubert get_java_utf8_name (struct obstack *obstack, struct value *name)
2025796c8dcSSimon Schubert {
2035796c8dcSSimon Schubert   char *chrs;
2045796c8dcSSimon Schubert   struct value *temp = name;
2055796c8dcSSimon Schubert   int name_length;
2065796c8dcSSimon Schubert   CORE_ADDR data_addr;
207*cf7f2e2dSJohn Marino 
2085796c8dcSSimon Schubert   temp = value_struct_elt (&temp, NULL, "length", NULL, "structure");
2095796c8dcSSimon Schubert   name_length = (int) value_as_long (temp);
2105796c8dcSSimon Schubert   data_addr = value_address (temp) + TYPE_LENGTH (value_type (temp));
2115796c8dcSSimon Schubert   chrs = obstack_alloc (obstack, name_length + 1);
2125796c8dcSSimon Schubert   chrs[name_length] = '\0';
2135796c8dcSSimon Schubert   read_memory (data_addr, (gdb_byte *) chrs, name_length);
2145796c8dcSSimon Schubert   return chrs;
2155796c8dcSSimon Schubert }
2165796c8dcSSimon Schubert 
2175796c8dcSSimon Schubert struct value *
2185796c8dcSSimon Schubert java_class_from_object (struct value *obj_val)
2195796c8dcSSimon Schubert {
2205796c8dcSSimon Schubert   /* This is all rather inefficient, since the offsets of vtable and
2215796c8dcSSimon Schubert      class are fixed.  FIXME */
2225796c8dcSSimon Schubert   struct value *vtable_val;
2235796c8dcSSimon Schubert 
2245796c8dcSSimon Schubert   if (TYPE_CODE (value_type (obj_val)) == TYPE_CODE_PTR
2255796c8dcSSimon Schubert       && TYPE_LENGTH (TYPE_TARGET_TYPE (value_type (obj_val))) == 0)
2265796c8dcSSimon Schubert     obj_val = value_at (get_java_object_type (),
2275796c8dcSSimon Schubert 			value_as_address (obj_val));
2285796c8dcSSimon Schubert 
2295796c8dcSSimon Schubert   vtable_val = value_struct_elt (&obj_val, NULL, "vtable", NULL, "structure");
2305796c8dcSSimon Schubert   return value_struct_elt (&vtable_val, NULL, "class", NULL, "structure");
2315796c8dcSSimon Schubert }
2325796c8dcSSimon Schubert 
2335796c8dcSSimon Schubert /* Check if CLASS_IS_PRIMITIVE(value of clas): */
2345796c8dcSSimon Schubert static int
2355796c8dcSSimon Schubert java_class_is_primitive (struct value *clas)
2365796c8dcSSimon Schubert {
2375796c8dcSSimon Schubert   struct value *vtable = value_struct_elt (&clas, NULL, "vtable", NULL, "struct");
2385796c8dcSSimon Schubert   CORE_ADDR i = value_as_address (vtable);
239*cf7f2e2dSJohn Marino 
2405796c8dcSSimon Schubert   return (int) (i & 0x7fffffff) == (int) 0x7fffffff;
2415796c8dcSSimon Schubert }
2425796c8dcSSimon Schubert 
2435796c8dcSSimon Schubert /* Read a GCJ Class object, and generated a gdb (TYPE_CODE_STRUCT) type. */
2445796c8dcSSimon Schubert 
2455796c8dcSSimon Schubert struct type *
2465796c8dcSSimon Schubert type_from_class (struct gdbarch *gdbarch, struct value *clas)
2475796c8dcSSimon Schubert {
2485796c8dcSSimon Schubert   struct type *type;
2495796c8dcSSimon Schubert   char *name;
2505796c8dcSSimon Schubert   struct value *temp;
2515796c8dcSSimon Schubert   struct objfile *objfile;
2525796c8dcSSimon Schubert   struct value *utf8_name;
2535796c8dcSSimon Schubert   char *nptr;
2545796c8dcSSimon Schubert   CORE_ADDR addr;
2555796c8dcSSimon Schubert   int is_array = 0;
2565796c8dcSSimon Schubert 
2575796c8dcSSimon Schubert   type = check_typedef (value_type (clas));
2585796c8dcSSimon Schubert   if (TYPE_CODE (type) == TYPE_CODE_PTR)
2595796c8dcSSimon Schubert     {
2605796c8dcSSimon Schubert       if (value_logical_not (clas))
2615796c8dcSSimon Schubert 	return NULL;
2625796c8dcSSimon Schubert       clas = value_ind (clas);
2635796c8dcSSimon Schubert     }
2645796c8dcSSimon Schubert   addr = value_address (clas);
2655796c8dcSSimon Schubert 
266*cf7f2e2dSJohn Marino   objfile = get_dynamics_objfile (gdbarch);
2675796c8dcSSimon Schubert   if (java_class_is_primitive (clas))
2685796c8dcSSimon Schubert     {
2695796c8dcSSimon Schubert       struct value *sig;
270*cf7f2e2dSJohn Marino 
2715796c8dcSSimon Schubert       temp = clas;
2725796c8dcSSimon Schubert       sig = value_struct_elt (&temp, NULL, "method_count", NULL, "structure");
2735796c8dcSSimon Schubert       return java_primitive_type (gdbarch, value_as_long (sig));
2745796c8dcSSimon Schubert     }
2755796c8dcSSimon Schubert 
2765796c8dcSSimon Schubert   /* Get Class name. */
2775796c8dcSSimon Schubert   /* if clasloader non-null, prepend loader address. FIXME */
2785796c8dcSSimon Schubert   temp = clas;
2795796c8dcSSimon Schubert   utf8_name = value_struct_elt (&temp, NULL, "name", NULL, "structure");
2805796c8dcSSimon Schubert   name = get_java_utf8_name (&objfile->objfile_obstack, utf8_name);
2815796c8dcSSimon Schubert   for (nptr = name; *nptr != 0; nptr++)
2825796c8dcSSimon Schubert     {
2835796c8dcSSimon Schubert       if (*nptr == '/')
2845796c8dcSSimon Schubert 	*nptr = '.';
2855796c8dcSSimon Schubert     }
2865796c8dcSSimon Schubert 
2875796c8dcSSimon Schubert   type = java_lookup_class (name);
2885796c8dcSSimon Schubert   if (type != NULL)
2895796c8dcSSimon Schubert     return type;
2905796c8dcSSimon Schubert 
291*cf7f2e2dSJohn Marino   type = alloc_type (objfile);
2925796c8dcSSimon Schubert   TYPE_CODE (type) = TYPE_CODE_STRUCT;
2935796c8dcSSimon Schubert   INIT_CPLUS_SPECIFIC (type);
2945796c8dcSSimon Schubert 
2955796c8dcSSimon Schubert   if (name[0] == '[')
2965796c8dcSSimon Schubert     {
2975796c8dcSSimon Schubert       char *signature = name;
2985796c8dcSSimon Schubert       int namelen = java_demangled_signature_length (signature);
299*cf7f2e2dSJohn Marino 
3005796c8dcSSimon Schubert       if (namelen > strlen (name))
3015796c8dcSSimon Schubert 	name = obstack_alloc (&objfile->objfile_obstack, namelen + 1);
3025796c8dcSSimon Schubert       java_demangled_signature_copy (name, signature);
3035796c8dcSSimon Schubert       name[namelen] = '\0';
3045796c8dcSSimon Schubert       is_array = 1;
3055796c8dcSSimon Schubert       temp = clas;
3065796c8dcSSimon Schubert       /* Set array element type. */
3075796c8dcSSimon Schubert       temp = value_struct_elt (&temp, NULL, "methods", NULL, "structure");
3085796c8dcSSimon Schubert       deprecated_set_value_type (temp, lookup_pointer_type (value_type (clas)));
3095796c8dcSSimon Schubert       TYPE_TARGET_TYPE (type) = type_from_class (gdbarch, temp);
3105796c8dcSSimon Schubert     }
3115796c8dcSSimon Schubert 
3125796c8dcSSimon Schubert   ALLOCATE_CPLUS_STRUCT_TYPE (type);
3135796c8dcSSimon Schubert   TYPE_TAG_NAME (type) = name;
3145796c8dcSSimon Schubert 
3155796c8dcSSimon Schubert   add_class_symtab_symbol (add_class_symbol (type, addr));
3165796c8dcSSimon Schubert   return java_link_class_type (gdbarch, type, clas);
3175796c8dcSSimon Schubert }
3185796c8dcSSimon Schubert 
3195796c8dcSSimon Schubert /* Fill in class TYPE with data from the CLAS value. */
3205796c8dcSSimon Schubert 
321*cf7f2e2dSJohn Marino static struct type *
3225796c8dcSSimon Schubert java_link_class_type (struct gdbarch *gdbarch,
3235796c8dcSSimon Schubert 		      struct type *type, struct value *clas)
3245796c8dcSSimon Schubert {
3255796c8dcSSimon Schubert   struct value *temp;
3265796c8dcSSimon Schubert   char *unqualified_name;
3275796c8dcSSimon Schubert   char *name = TYPE_TAG_NAME (type);
3285796c8dcSSimon Schubert   int ninterfaces, nfields, nmethods;
3295796c8dcSSimon Schubert   int type_is_object = 0;
3305796c8dcSSimon Schubert   struct fn_field *fn_fields;
3315796c8dcSSimon Schubert   struct fn_fieldlist *fn_fieldlists;
3325796c8dcSSimon Schubert   struct value *fields;
3335796c8dcSSimon Schubert   struct value *methods;
3345796c8dcSSimon Schubert   struct value *method = NULL;
3355796c8dcSSimon Schubert   struct value *field = NULL;
3365796c8dcSSimon Schubert   int i, j;
337*cf7f2e2dSJohn Marino   struct objfile *objfile = get_dynamics_objfile (gdbarch);
3385796c8dcSSimon Schubert   struct type *tsuper;
3395796c8dcSSimon Schubert 
3405796c8dcSSimon Schubert   gdb_assert (name != NULL);
3415796c8dcSSimon Schubert   unqualified_name = strrchr (name, '.');
3425796c8dcSSimon Schubert   if (unqualified_name == NULL)
3435796c8dcSSimon Schubert     unqualified_name = name;
3445796c8dcSSimon Schubert 
3455796c8dcSSimon Schubert   temp = clas;
3465796c8dcSSimon Schubert   temp = value_struct_elt (&temp, NULL, "superclass", NULL, "structure");
3475796c8dcSSimon Schubert   if (strcmp (name, "java.lang.Object") == 0)
3485796c8dcSSimon Schubert     {
3495796c8dcSSimon Schubert       tsuper = get_java_object_type ();
3505796c8dcSSimon Schubert       if (tsuper && TYPE_CODE (tsuper) == TYPE_CODE_PTR)
3515796c8dcSSimon Schubert 	tsuper = TYPE_TARGET_TYPE (tsuper);
3525796c8dcSSimon Schubert       type_is_object = 1;
3535796c8dcSSimon Schubert     }
3545796c8dcSSimon Schubert   else
3555796c8dcSSimon Schubert     tsuper = type_from_class (gdbarch, temp);
3565796c8dcSSimon Schubert 
3575796c8dcSSimon Schubert #if 1
3585796c8dcSSimon Schubert   ninterfaces = 0;
3595796c8dcSSimon Schubert #else
3605796c8dcSSimon Schubert   temp = clas;
3615796c8dcSSimon Schubert   ninterfaces = value_as_long (value_struct_elt (&temp, NULL, "interface_len", NULL, "structure"));
3625796c8dcSSimon Schubert #endif
3635796c8dcSSimon Schubert   TYPE_N_BASECLASSES (type) = (tsuper == NULL ? 0 : 1) + ninterfaces;
3645796c8dcSSimon Schubert   temp = clas;
3655796c8dcSSimon Schubert   nfields = value_as_long (value_struct_elt (&temp, NULL, "field_count", NULL, "structure"));
3665796c8dcSSimon Schubert   nfields += TYPE_N_BASECLASSES (type);
3675796c8dcSSimon Schubert   nfields++;			/* Add one for dummy "class" field. */
3685796c8dcSSimon Schubert   TYPE_NFIELDS (type) = nfields;
3695796c8dcSSimon Schubert   TYPE_FIELDS (type) = (struct field *)
3705796c8dcSSimon Schubert     TYPE_ALLOC (type, sizeof (struct field) * nfields);
3715796c8dcSSimon Schubert 
3725796c8dcSSimon Schubert   memset (TYPE_FIELDS (type), 0, sizeof (struct field) * nfields);
3735796c8dcSSimon Schubert 
3745796c8dcSSimon Schubert   TYPE_FIELD_PRIVATE_BITS (type) =
3755796c8dcSSimon Schubert     (B_TYPE *) TYPE_ALLOC (type, B_BYTES (nfields));
3765796c8dcSSimon Schubert   B_CLRALL (TYPE_FIELD_PRIVATE_BITS (type), nfields);
3775796c8dcSSimon Schubert 
3785796c8dcSSimon Schubert   TYPE_FIELD_PROTECTED_BITS (type) =
3795796c8dcSSimon Schubert     (B_TYPE *) TYPE_ALLOC (type, B_BYTES (nfields));
3805796c8dcSSimon Schubert   B_CLRALL (TYPE_FIELD_PROTECTED_BITS (type), nfields);
3815796c8dcSSimon Schubert 
3825796c8dcSSimon Schubert   TYPE_FIELD_IGNORE_BITS (type) =
3835796c8dcSSimon Schubert     (B_TYPE *) TYPE_ALLOC (type, B_BYTES (nfields));
3845796c8dcSSimon Schubert   B_CLRALL (TYPE_FIELD_IGNORE_BITS (type), nfields);
3855796c8dcSSimon Schubert 
3865796c8dcSSimon Schubert   TYPE_FIELD_VIRTUAL_BITS (type) = (B_TYPE *)
3875796c8dcSSimon Schubert     TYPE_ALLOC (type, B_BYTES (TYPE_N_BASECLASSES (type)));
3885796c8dcSSimon Schubert   B_CLRALL (TYPE_FIELD_VIRTUAL_BITS (type), TYPE_N_BASECLASSES (type));
3895796c8dcSSimon Schubert 
3905796c8dcSSimon Schubert   if (tsuper != NULL)
3915796c8dcSSimon Schubert     {
3925796c8dcSSimon Schubert       TYPE_BASECLASS (type, 0) = tsuper;
3935796c8dcSSimon Schubert       if (type_is_object)
3945796c8dcSSimon Schubert 	SET_TYPE_FIELD_PRIVATE (type, 0);
3955796c8dcSSimon Schubert     }
3965796c8dcSSimon Schubert 
3975796c8dcSSimon Schubert   i = strlen (name);
3985796c8dcSSimon Schubert   if (i > 2 && name[i - 1] == ']' && tsuper != NULL)
3995796c8dcSSimon Schubert     {
4005796c8dcSSimon Schubert       /* FIXME */
4015796c8dcSSimon Schubert       TYPE_LENGTH (type) = TYPE_LENGTH (tsuper) + 4;	/* size with "length" */
4025796c8dcSSimon Schubert     }
4035796c8dcSSimon Schubert   else
4045796c8dcSSimon Schubert     {
4055796c8dcSSimon Schubert       temp = clas;
4065796c8dcSSimon Schubert       temp = value_struct_elt (&temp, NULL, "size_in_bytes", NULL, "structure");
4075796c8dcSSimon Schubert       TYPE_LENGTH (type) = value_as_long (temp);
4085796c8dcSSimon Schubert     }
4095796c8dcSSimon Schubert 
4105796c8dcSSimon Schubert   fields = NULL;
4115796c8dcSSimon Schubert   nfields--;			/* First set up dummy "class" field. */
4125796c8dcSSimon Schubert   SET_FIELD_PHYSADDR (TYPE_FIELD (type, nfields), value_address (clas));
4135796c8dcSSimon Schubert   TYPE_FIELD_NAME (type, nfields) = "class";
4145796c8dcSSimon Schubert   TYPE_FIELD_TYPE (type, nfields) = value_type (clas);
4155796c8dcSSimon Schubert   SET_TYPE_FIELD_PRIVATE (type, nfields);
4165796c8dcSSimon Schubert 
4175796c8dcSSimon Schubert   for (i = TYPE_N_BASECLASSES (type); i < nfields; i++)
4185796c8dcSSimon Schubert     {
4195796c8dcSSimon Schubert       int accflags;
4205796c8dcSSimon Schubert       int boffset;
421*cf7f2e2dSJohn Marino 
4225796c8dcSSimon Schubert       if (fields == NULL)
4235796c8dcSSimon Schubert 	{
4245796c8dcSSimon Schubert 	  temp = clas;
4255796c8dcSSimon Schubert 	  fields = value_struct_elt (&temp, NULL, "fields", NULL, "structure");
4265796c8dcSSimon Schubert 	  field = value_ind (fields);
4275796c8dcSSimon Schubert 	}
4285796c8dcSSimon Schubert       else
4295796c8dcSSimon Schubert 	{			/* Re-use field value for next field. */
4305796c8dcSSimon Schubert 	  CORE_ADDR addr
4315796c8dcSSimon Schubert 	    = value_address (field) + TYPE_LENGTH (value_type (field));
432*cf7f2e2dSJohn Marino 
4335796c8dcSSimon Schubert 	  set_value_address (field, addr);
4345796c8dcSSimon Schubert 	  set_value_lazy (field, 1);
4355796c8dcSSimon Schubert 	}
4365796c8dcSSimon Schubert       temp = field;
4375796c8dcSSimon Schubert       temp = value_struct_elt (&temp, NULL, "name", NULL, "structure");
4385796c8dcSSimon Schubert       TYPE_FIELD_NAME (type, i) =
4395796c8dcSSimon Schubert 	get_java_utf8_name (&objfile->objfile_obstack, temp);
4405796c8dcSSimon Schubert       temp = field;
4415796c8dcSSimon Schubert       accflags = value_as_long (value_struct_elt (&temp, NULL, "accflags",
4425796c8dcSSimon Schubert 						  NULL, "structure"));
4435796c8dcSSimon Schubert       temp = field;
4445796c8dcSSimon Schubert       temp = value_struct_elt (&temp, NULL, "info", NULL, "structure");
4455796c8dcSSimon Schubert       boffset = value_as_long (value_struct_elt (&temp, NULL, "boffset",
4465796c8dcSSimon Schubert 						 NULL, "structure"));
4475796c8dcSSimon Schubert       if (accflags & 0x0001)	/* public access */
4485796c8dcSSimon Schubert 	{
4495796c8dcSSimon Schubert 	  /* ??? */
4505796c8dcSSimon Schubert 	}
4515796c8dcSSimon Schubert       if (accflags & 0x0002)	/* private access */
4525796c8dcSSimon Schubert 	{
4535796c8dcSSimon Schubert 	  SET_TYPE_FIELD_PRIVATE (type, i);
4545796c8dcSSimon Schubert 	}
4555796c8dcSSimon Schubert       if (accflags & 0x0004)	/* protected access */
4565796c8dcSSimon Schubert 	{
4575796c8dcSSimon Schubert 	  SET_TYPE_FIELD_PROTECTED (type, i);
4585796c8dcSSimon Schubert 	}
4595796c8dcSSimon Schubert       if (accflags & 0x0008)	/* ACC_STATIC */
4605796c8dcSSimon Schubert 	SET_FIELD_PHYSADDR (TYPE_FIELD (type, i), boffset);
4615796c8dcSSimon Schubert       else
4625796c8dcSSimon Schubert 	TYPE_FIELD_BITPOS (type, i) = 8 * boffset;
4635796c8dcSSimon Schubert       if (accflags & 0x8000)	/* FIELD_UNRESOLVED_FLAG */
4645796c8dcSSimon Schubert 	{
4655796c8dcSSimon Schubert 	  TYPE_FIELD_TYPE (type, i) = get_java_object_type ();	/* FIXME */
4665796c8dcSSimon Schubert 	}
4675796c8dcSSimon Schubert       else
4685796c8dcSSimon Schubert 	{
4695796c8dcSSimon Schubert 	  struct type *ftype;
470*cf7f2e2dSJohn Marino 
4715796c8dcSSimon Schubert 	  temp = field;
4725796c8dcSSimon Schubert 	  temp = value_struct_elt (&temp, NULL, "type", NULL, "structure");
4735796c8dcSSimon Schubert 	  ftype = type_from_class (gdbarch, temp);
4745796c8dcSSimon Schubert 	  if (TYPE_CODE (ftype) == TYPE_CODE_STRUCT)
4755796c8dcSSimon Schubert 	    ftype = lookup_pointer_type (ftype);
4765796c8dcSSimon Schubert 	  TYPE_FIELD_TYPE (type, i) = ftype;
4775796c8dcSSimon Schubert 	}
4785796c8dcSSimon Schubert     }
4795796c8dcSSimon Schubert 
4805796c8dcSSimon Schubert   temp = clas;
4815796c8dcSSimon Schubert   nmethods = value_as_long (value_struct_elt (&temp, NULL, "method_count",
4825796c8dcSSimon Schubert 					      NULL, "structure"));
4835796c8dcSSimon Schubert   TYPE_NFN_FIELDS_TOTAL (type) = nmethods;
4845796c8dcSSimon Schubert   j = nmethods * sizeof (struct fn_field);
4855796c8dcSSimon Schubert   fn_fields = (struct fn_field *)
4865796c8dcSSimon Schubert     obstack_alloc (&dynamics_objfile->objfile_obstack, j);
4875796c8dcSSimon Schubert   memset (fn_fields, 0, j);
4885796c8dcSSimon Schubert   fn_fieldlists = (struct fn_fieldlist *)
4895796c8dcSSimon Schubert     alloca (nmethods * sizeof (struct fn_fieldlist));
4905796c8dcSSimon Schubert 
4915796c8dcSSimon Schubert   methods = NULL;
4925796c8dcSSimon Schubert   for (i = 0; i < nmethods; i++)
4935796c8dcSSimon Schubert     {
4945796c8dcSSimon Schubert       char *mname;
4955796c8dcSSimon Schubert       int k;
496*cf7f2e2dSJohn Marino 
4975796c8dcSSimon Schubert       if (methods == NULL)
4985796c8dcSSimon Schubert 	{
4995796c8dcSSimon Schubert 	  temp = clas;
5005796c8dcSSimon Schubert 	  methods = value_struct_elt (&temp, NULL, "methods", NULL, "structure");
5015796c8dcSSimon Schubert 	  method = value_ind (methods);
5025796c8dcSSimon Schubert 	}
5035796c8dcSSimon Schubert       else
5045796c8dcSSimon Schubert 	{			/* Re-use method value for next method. */
5055796c8dcSSimon Schubert 	  CORE_ADDR addr
5065796c8dcSSimon Schubert 	    = value_address (method) + TYPE_LENGTH (value_type (method));
507*cf7f2e2dSJohn Marino 
5085796c8dcSSimon Schubert 	  set_value_address (method, addr);
5095796c8dcSSimon Schubert 	  set_value_lazy (method, 1);
5105796c8dcSSimon Schubert 	}
5115796c8dcSSimon Schubert 
5125796c8dcSSimon Schubert       /* Get method name. */
5135796c8dcSSimon Schubert       temp = method;
5145796c8dcSSimon Schubert       temp = value_struct_elt (&temp, NULL, "name", NULL, "structure");
5155796c8dcSSimon Schubert       mname = get_java_utf8_name (&objfile->objfile_obstack, temp);
5165796c8dcSSimon Schubert       if (strcmp (mname, "<init>") == 0)
5175796c8dcSSimon Schubert 	mname = unqualified_name;
5185796c8dcSSimon Schubert 
5195796c8dcSSimon Schubert       /* Check for an existing method with the same name.
5205796c8dcSSimon Schubert        * This makes building the fn_fieldslists an O(nmethods**2)
5215796c8dcSSimon Schubert        * operation.  That could be using hashing, but I doubt it
5225796c8dcSSimon Schubert        * is worth it.  Note that we do maintain the order of methods
5235796c8dcSSimon Schubert        * in the inferior's Method table (as long as that is grouped
5245796c8dcSSimon Schubert        * by method name), which I think is desirable.  --PB */
5255796c8dcSSimon Schubert       for (k = 0, j = TYPE_NFN_FIELDS (type);;)
5265796c8dcSSimon Schubert 	{
5275796c8dcSSimon Schubert 	  if (--j < 0)
5285796c8dcSSimon Schubert 	    {			/* No match - new method name. */
5295796c8dcSSimon Schubert 	      j = TYPE_NFN_FIELDS (type)++;
5305796c8dcSSimon Schubert 	      fn_fieldlists[j].name = mname;
5315796c8dcSSimon Schubert 	      fn_fieldlists[j].length = 1;
5325796c8dcSSimon Schubert 	      fn_fieldlists[j].fn_fields = &fn_fields[i];
5335796c8dcSSimon Schubert 	      k = i;
5345796c8dcSSimon Schubert 	      break;
5355796c8dcSSimon Schubert 	    }
5365796c8dcSSimon Schubert 	  if (strcmp (mname, fn_fieldlists[j].name) == 0)
5375796c8dcSSimon Schubert 	    {			/* Found an existing method with the same name. */
5385796c8dcSSimon Schubert 	      int l;
539*cf7f2e2dSJohn Marino 
5405796c8dcSSimon Schubert 	      if (mname != unqualified_name)
5415796c8dcSSimon Schubert 		obstack_free (&objfile->objfile_obstack, mname);
5425796c8dcSSimon Schubert 	      mname = fn_fieldlists[j].name;
5435796c8dcSSimon Schubert 	      fn_fieldlists[j].length++;
5445796c8dcSSimon Schubert 	      k = i - k;	/* Index of new slot. */
5455796c8dcSSimon Schubert 	      /* Shift intervening fn_fields (between k and i) down. */
5465796c8dcSSimon Schubert 	      for (l = i; l > k; l--)
5475796c8dcSSimon Schubert 		fn_fields[l] = fn_fields[l - 1];
5485796c8dcSSimon Schubert 	      for (l = TYPE_NFN_FIELDS (type); --l > j;)
5495796c8dcSSimon Schubert 		fn_fieldlists[l].fn_fields++;
5505796c8dcSSimon Schubert 	      break;
5515796c8dcSSimon Schubert 	    }
5525796c8dcSSimon Schubert 	  k += fn_fieldlists[j].length;
5535796c8dcSSimon Schubert 	}
5545796c8dcSSimon Schubert       fn_fields[k].physname = "";
5555796c8dcSSimon Schubert       fn_fields[k].is_stub = 1;
5565796c8dcSSimon Schubert       /* FIXME */
5575796c8dcSSimon Schubert       fn_fields[k].type = lookup_function_type
5585796c8dcSSimon Schubert 			   (builtin_java_type (gdbarch)->builtin_void);
5595796c8dcSSimon Schubert       TYPE_CODE (fn_fields[k].type) = TYPE_CODE_METHOD;
5605796c8dcSSimon Schubert     }
5615796c8dcSSimon Schubert 
5625796c8dcSSimon Schubert   j = TYPE_NFN_FIELDS (type) * sizeof (struct fn_fieldlist);
5635796c8dcSSimon Schubert   TYPE_FN_FIELDLISTS (type) = (struct fn_fieldlist *)
5645796c8dcSSimon Schubert     obstack_alloc (&dynamics_objfile->objfile_obstack, j);
5655796c8dcSSimon Schubert   memcpy (TYPE_FN_FIELDLISTS (type), fn_fieldlists, j);
5665796c8dcSSimon Schubert 
5675796c8dcSSimon Schubert   return type;
5685796c8dcSSimon Schubert }
5695796c8dcSSimon Schubert 
5705796c8dcSSimon Schubert static struct type *java_object_type;
5715796c8dcSSimon Schubert 
572*cf7f2e2dSJohn Marino /* A free function that is attached to the objfile defining
573*cf7f2e2dSJohn Marino    java_object_type.  This is used to clear the cached type whenever
574*cf7f2e2dSJohn Marino    its owning objfile is destroyed.  */
575*cf7f2e2dSJohn Marino static void
576*cf7f2e2dSJohn Marino jv_clear_object_type (struct objfile *objfile, void *ignore)
577*cf7f2e2dSJohn Marino {
578*cf7f2e2dSJohn Marino   java_object_type = NULL;
579*cf7f2e2dSJohn Marino }
580*cf7f2e2dSJohn Marino 
581*cf7f2e2dSJohn Marino static void
582*cf7f2e2dSJohn Marino set_java_object_type (struct type *type)
583*cf7f2e2dSJohn Marino {
584*cf7f2e2dSJohn Marino   struct objfile *owner;
585*cf7f2e2dSJohn Marino 
586*cf7f2e2dSJohn Marino   gdb_assert (java_object_type == NULL);
587*cf7f2e2dSJohn Marino 
588*cf7f2e2dSJohn Marino   owner = TYPE_OBJFILE (type);
589*cf7f2e2dSJohn Marino   if (owner)
590*cf7f2e2dSJohn Marino     set_objfile_data (owner, jv_type_objfile_data_key, &java_object_type);
591*cf7f2e2dSJohn Marino   java_object_type = type;
592*cf7f2e2dSJohn Marino }
593*cf7f2e2dSJohn Marino 
5945796c8dcSSimon Schubert struct type *
5955796c8dcSSimon Schubert get_java_object_type (void)
5965796c8dcSSimon Schubert {
5975796c8dcSSimon Schubert   if (java_object_type == NULL)
5985796c8dcSSimon Schubert     {
5995796c8dcSSimon Schubert       struct symbol *sym;
600*cf7f2e2dSJohn Marino 
6015796c8dcSSimon Schubert       sym = lookup_symbol ("java.lang.Object", NULL, STRUCT_DOMAIN, NULL);
6025796c8dcSSimon Schubert       if (sym == NULL)
6035796c8dcSSimon Schubert 	error (_("cannot find java.lang.Object"));
604*cf7f2e2dSJohn Marino       set_java_object_type (SYMBOL_TYPE (sym));
6055796c8dcSSimon Schubert     }
6065796c8dcSSimon Schubert   return java_object_type;
6075796c8dcSSimon Schubert }
6085796c8dcSSimon Schubert 
6095796c8dcSSimon Schubert int
6105796c8dcSSimon Schubert get_java_object_header_size (struct gdbarch *gdbarch)
6115796c8dcSSimon Schubert {
6125796c8dcSSimon Schubert   struct type *objtype = get_java_object_type ();
613*cf7f2e2dSJohn Marino 
6145796c8dcSSimon Schubert   if (objtype == NULL)
6155796c8dcSSimon Schubert     return (2 * gdbarch_ptr_bit (gdbarch) / TARGET_CHAR_BIT);
6165796c8dcSSimon Schubert   else
6175796c8dcSSimon Schubert     return TYPE_LENGTH (objtype);
6185796c8dcSSimon Schubert }
6195796c8dcSSimon Schubert 
6205796c8dcSSimon Schubert int
6215796c8dcSSimon Schubert is_object_type (struct type *type)
6225796c8dcSSimon Schubert {
6235796c8dcSSimon Schubert   CHECK_TYPEDEF (type);
6245796c8dcSSimon Schubert   if (TYPE_CODE (type) == TYPE_CODE_PTR)
6255796c8dcSSimon Schubert     {
6265796c8dcSSimon Schubert       struct type *ttype = check_typedef (TYPE_TARGET_TYPE (type));
6275796c8dcSSimon Schubert       char *name;
6285796c8dcSSimon Schubert       if (TYPE_CODE (ttype) != TYPE_CODE_STRUCT)
6295796c8dcSSimon Schubert 	return 0;
6305796c8dcSSimon Schubert       while (TYPE_N_BASECLASSES (ttype) > 0)
6315796c8dcSSimon Schubert 	ttype = TYPE_BASECLASS (ttype, 0);
6325796c8dcSSimon Schubert       name = TYPE_TAG_NAME (ttype);
6335796c8dcSSimon Schubert       if (name != NULL && strcmp (name, "java.lang.Object") == 0)
6345796c8dcSSimon Schubert 	return 1;
6355796c8dcSSimon Schubert       name = TYPE_NFIELDS (ttype) > 0 ? TYPE_FIELD_NAME (ttype, 0) : (char *) 0;
6365796c8dcSSimon Schubert       if (name != NULL && strcmp (name, "vtable") == 0)
6375796c8dcSSimon Schubert 	{
6385796c8dcSSimon Schubert 	  if (java_object_type == NULL)
639*cf7f2e2dSJohn Marino 	    set_java_object_type (type);
6405796c8dcSSimon Schubert 	  return 1;
6415796c8dcSSimon Schubert 	}
6425796c8dcSSimon Schubert     }
6435796c8dcSSimon Schubert   return 0;
6445796c8dcSSimon Schubert }
6455796c8dcSSimon Schubert 
6465796c8dcSSimon Schubert struct type *
6475796c8dcSSimon Schubert java_primitive_type (struct gdbarch *gdbarch, int signature)
6485796c8dcSSimon Schubert {
6495796c8dcSSimon Schubert   const struct builtin_java_type *builtin = builtin_java_type (gdbarch);
6505796c8dcSSimon Schubert 
6515796c8dcSSimon Schubert   switch (signature)
6525796c8dcSSimon Schubert     {
6535796c8dcSSimon Schubert     case 'B':
6545796c8dcSSimon Schubert       return builtin->builtin_byte;
6555796c8dcSSimon Schubert     case 'S':
6565796c8dcSSimon Schubert       return builtin->builtin_short;
6575796c8dcSSimon Schubert     case 'I':
6585796c8dcSSimon Schubert       return builtin->builtin_int;
6595796c8dcSSimon Schubert     case 'J':
6605796c8dcSSimon Schubert       return builtin->builtin_long;
6615796c8dcSSimon Schubert     case 'Z':
6625796c8dcSSimon Schubert       return builtin->builtin_boolean;
6635796c8dcSSimon Schubert     case 'C':
6645796c8dcSSimon Schubert       return builtin->builtin_char;
6655796c8dcSSimon Schubert     case 'F':
6665796c8dcSSimon Schubert       return builtin->builtin_float;
6675796c8dcSSimon Schubert     case 'D':
6685796c8dcSSimon Schubert       return builtin->builtin_double;
6695796c8dcSSimon Schubert     case 'V':
6705796c8dcSSimon Schubert       return builtin->builtin_void;
6715796c8dcSSimon Schubert     }
6725796c8dcSSimon Schubert   error (_("unknown signature '%c' for primitive type"), (char) signature);
6735796c8dcSSimon Schubert }
6745796c8dcSSimon Schubert 
6755796c8dcSSimon Schubert /* If name[0 .. namelen-1] is the name of a primitive Java type,
6765796c8dcSSimon Schubert    return that type.  Otherwise, return NULL. */
6775796c8dcSSimon Schubert 
6785796c8dcSSimon Schubert struct type *
6795796c8dcSSimon Schubert java_primitive_type_from_name (struct gdbarch *gdbarch,
6805796c8dcSSimon Schubert 			       char *name, int namelen)
6815796c8dcSSimon Schubert {
6825796c8dcSSimon Schubert   const struct builtin_java_type *builtin = builtin_java_type (gdbarch);
6835796c8dcSSimon Schubert 
6845796c8dcSSimon Schubert   switch (name[0])
6855796c8dcSSimon Schubert     {
6865796c8dcSSimon Schubert     case 'b':
6875796c8dcSSimon Schubert       if (namelen == 4 && memcmp (name, "byte", 4) == 0)
6885796c8dcSSimon Schubert 	return builtin->builtin_byte;
6895796c8dcSSimon Schubert       if (namelen == 7 && memcmp (name, "boolean", 7) == 0)
6905796c8dcSSimon Schubert 	return builtin->builtin_boolean;
6915796c8dcSSimon Schubert       break;
6925796c8dcSSimon Schubert     case 'c':
6935796c8dcSSimon Schubert       if (namelen == 4 && memcmp (name, "char", 4) == 0)
6945796c8dcSSimon Schubert 	return builtin->builtin_char;
6955796c8dcSSimon Schubert     case 'd':
6965796c8dcSSimon Schubert       if (namelen == 6 && memcmp (name, "double", 6) == 0)
6975796c8dcSSimon Schubert 	return builtin->builtin_double;
6985796c8dcSSimon Schubert       break;
6995796c8dcSSimon Schubert     case 'f':
7005796c8dcSSimon Schubert       if (namelen == 5 && memcmp (name, "float", 5) == 0)
7015796c8dcSSimon Schubert 	return builtin->builtin_float;
7025796c8dcSSimon Schubert       break;
7035796c8dcSSimon Schubert     case 'i':
7045796c8dcSSimon Schubert       if (namelen == 3 && memcmp (name, "int", 3) == 0)
7055796c8dcSSimon Schubert 	return builtin->builtin_int;
7065796c8dcSSimon Schubert       break;
7075796c8dcSSimon Schubert     case 'l':
7085796c8dcSSimon Schubert       if (namelen == 4 && memcmp (name, "long", 4) == 0)
7095796c8dcSSimon Schubert 	return builtin->builtin_long;
7105796c8dcSSimon Schubert       break;
7115796c8dcSSimon Schubert     case 's':
7125796c8dcSSimon Schubert       if (namelen == 5 && memcmp (name, "short", 5) == 0)
7135796c8dcSSimon Schubert 	return builtin->builtin_short;
7145796c8dcSSimon Schubert       break;
7155796c8dcSSimon Schubert     case 'v':
7165796c8dcSSimon Schubert       if (namelen == 4 && memcmp (name, "void", 4) == 0)
7175796c8dcSSimon Schubert 	return builtin->builtin_void;
7185796c8dcSSimon Schubert       break;
7195796c8dcSSimon Schubert     }
7205796c8dcSSimon Schubert   return NULL;
7215796c8dcSSimon Schubert }
7225796c8dcSSimon Schubert 
7235796c8dcSSimon Schubert static char *
7245796c8dcSSimon Schubert java_primitive_type_name (int signature)
7255796c8dcSSimon Schubert {
7265796c8dcSSimon Schubert   switch (signature)
7275796c8dcSSimon Schubert     {
7285796c8dcSSimon Schubert     case 'B':
7295796c8dcSSimon Schubert       return "byte";
7305796c8dcSSimon Schubert     case 'S':
7315796c8dcSSimon Schubert       return "short";
7325796c8dcSSimon Schubert     case 'I':
7335796c8dcSSimon Schubert       return "int";
7345796c8dcSSimon Schubert     case 'J':
7355796c8dcSSimon Schubert       return "long";
7365796c8dcSSimon Schubert     case 'Z':
7375796c8dcSSimon Schubert       return "boolean";
7385796c8dcSSimon Schubert     case 'C':
7395796c8dcSSimon Schubert       return "char";
7405796c8dcSSimon Schubert     case 'F':
7415796c8dcSSimon Schubert       return "float";
7425796c8dcSSimon Schubert     case 'D':
7435796c8dcSSimon Schubert       return "double";
7445796c8dcSSimon Schubert     case 'V':
7455796c8dcSSimon Schubert       return "void";
7465796c8dcSSimon Schubert     }
7475796c8dcSSimon Schubert   error (_("unknown signature '%c' for primitive type"), (char) signature);
7485796c8dcSSimon Schubert }
7495796c8dcSSimon Schubert 
7505796c8dcSSimon Schubert /* Return the length (in bytes) of demangled name of the Java type
7515796c8dcSSimon Schubert    signature string SIGNATURE. */
7525796c8dcSSimon Schubert 
7535796c8dcSSimon Schubert static int
7545796c8dcSSimon Schubert java_demangled_signature_length (char *signature)
7555796c8dcSSimon Schubert {
7565796c8dcSSimon Schubert   int array = 0;
757*cf7f2e2dSJohn Marino 
7585796c8dcSSimon Schubert   for (; *signature == '['; signature++)
7595796c8dcSSimon Schubert     array += 2;			/* Two chars for "[]". */
7605796c8dcSSimon Schubert   switch (signature[0])
7615796c8dcSSimon Schubert     {
7625796c8dcSSimon Schubert     case 'L':
7635796c8dcSSimon Schubert       /* Subtract 2 for 'L' and ';'. */
7645796c8dcSSimon Schubert       return strlen (signature) - 2 + array;
7655796c8dcSSimon Schubert     default:
7665796c8dcSSimon Schubert       return strlen (java_primitive_type_name (signature[0])) + array;
7675796c8dcSSimon Schubert     }
7685796c8dcSSimon Schubert }
7695796c8dcSSimon Schubert 
7705796c8dcSSimon Schubert /* Demangle the Java type signature SIGNATURE, leaving the result in RESULT. */
7715796c8dcSSimon Schubert 
7725796c8dcSSimon Schubert static void
7735796c8dcSSimon Schubert java_demangled_signature_copy (char *result, char *signature)
7745796c8dcSSimon Schubert {
7755796c8dcSSimon Schubert   int array = 0;
7765796c8dcSSimon Schubert   char *ptr;
7775796c8dcSSimon Schubert   int i;
778*cf7f2e2dSJohn Marino 
7795796c8dcSSimon Schubert   while (*signature == '[')
7805796c8dcSSimon Schubert     {
7815796c8dcSSimon Schubert       array++;
7825796c8dcSSimon Schubert       signature++;
7835796c8dcSSimon Schubert     }
7845796c8dcSSimon Schubert   switch (signature[0])
7855796c8dcSSimon Schubert     {
7865796c8dcSSimon Schubert     case 'L':
7875796c8dcSSimon Schubert       /* Subtract 2 for 'L' and ';', but add 1 for final nul. */
7885796c8dcSSimon Schubert       signature++;
7895796c8dcSSimon Schubert       ptr = result;
7905796c8dcSSimon Schubert       for (; *signature != ';' && *signature != '\0'; signature++)
7915796c8dcSSimon Schubert 	{
7925796c8dcSSimon Schubert 	  if (*signature == '/')
7935796c8dcSSimon Schubert 	    *ptr++ = '.';
7945796c8dcSSimon Schubert 	  else
7955796c8dcSSimon Schubert 	    *ptr++ = *signature;
7965796c8dcSSimon Schubert 	}
7975796c8dcSSimon Schubert       break;
7985796c8dcSSimon Schubert     default:
7995796c8dcSSimon Schubert       ptr = java_primitive_type_name (signature[0]);
8005796c8dcSSimon Schubert       i = strlen (ptr);
8015796c8dcSSimon Schubert       strcpy (result, ptr);
8025796c8dcSSimon Schubert       ptr = result + i;
8035796c8dcSSimon Schubert       break;
8045796c8dcSSimon Schubert     }
8055796c8dcSSimon Schubert   while (--array >= 0)
8065796c8dcSSimon Schubert     {
8075796c8dcSSimon Schubert       *ptr++ = '[';
8085796c8dcSSimon Schubert       *ptr++ = ']';
8095796c8dcSSimon Schubert     }
8105796c8dcSSimon Schubert }
8115796c8dcSSimon Schubert 
8125796c8dcSSimon Schubert /* Return the demangled name of the Java type signature string SIGNATURE,
8135796c8dcSSimon Schubert    as a freshly allocated copy. */
8145796c8dcSSimon Schubert 
8155796c8dcSSimon Schubert char *
8165796c8dcSSimon Schubert java_demangle_type_signature (char *signature)
8175796c8dcSSimon Schubert {
8185796c8dcSSimon Schubert   int length = java_demangled_signature_length (signature);
8195796c8dcSSimon Schubert   char *result = xmalloc (length + 1);
820*cf7f2e2dSJohn Marino 
8215796c8dcSSimon Schubert   java_demangled_signature_copy (result, signature);
8225796c8dcSSimon Schubert   result[length] = '\0';
8235796c8dcSSimon Schubert   return result;
8245796c8dcSSimon Schubert }
8255796c8dcSSimon Schubert 
8265796c8dcSSimon Schubert /* Return the type of TYPE followed by DIMS pairs of [ ].
8275796c8dcSSimon Schubert    If DIMS == 0, TYPE is returned. */
8285796c8dcSSimon Schubert 
8295796c8dcSSimon Schubert struct type *
8305796c8dcSSimon Schubert java_array_type (struct type *type, int dims)
8315796c8dcSSimon Schubert {
8325796c8dcSSimon Schubert   while (dims-- > 0)
8335796c8dcSSimon Schubert     {
8345796c8dcSSimon Schubert       /* FIXME  This is bogus!  Java arrays are not gdb arrays! */
8355796c8dcSSimon Schubert       type = lookup_array_range_type (type, 0, 0);
8365796c8dcSSimon Schubert     }
8375796c8dcSSimon Schubert 
8385796c8dcSSimon Schubert   return type;
8395796c8dcSSimon Schubert }
8405796c8dcSSimon Schubert 
8415796c8dcSSimon Schubert /* Create a Java string in the inferior from a (Utf8) literal. */
8425796c8dcSSimon Schubert 
8435796c8dcSSimon Schubert static struct value *
8445796c8dcSSimon Schubert java_value_string (char *ptr, int len)
8455796c8dcSSimon Schubert {
8465796c8dcSSimon Schubert   error (_("not implemented - java_value_string"));	/* FIXME */
8475796c8dcSSimon Schubert }
8485796c8dcSSimon Schubert 
8495796c8dcSSimon Schubert /* Print the character C on STREAM as part of the contents of a literal
8505796c8dcSSimon Schubert    string whose delimiter is QUOTER.  Note that that format for printing
8515796c8dcSSimon Schubert    characters and strings is language specific. */
8525796c8dcSSimon Schubert 
8535796c8dcSSimon Schubert static void
8545796c8dcSSimon Schubert java_emit_char (int c, struct type *type, struct ui_file *stream, int quoter)
8555796c8dcSSimon Schubert {
8565796c8dcSSimon Schubert   switch (c)
8575796c8dcSSimon Schubert     {
8585796c8dcSSimon Schubert     case '\\':
8595796c8dcSSimon Schubert     case '\'':
8605796c8dcSSimon Schubert       fprintf_filtered (stream, "\\%c", c);
8615796c8dcSSimon Schubert       break;
8625796c8dcSSimon Schubert     case '\b':
8635796c8dcSSimon Schubert       fputs_filtered ("\\b", stream);
8645796c8dcSSimon Schubert       break;
8655796c8dcSSimon Schubert     case '\t':
8665796c8dcSSimon Schubert       fputs_filtered ("\\t", stream);
8675796c8dcSSimon Schubert       break;
8685796c8dcSSimon Schubert     case '\n':
8695796c8dcSSimon Schubert       fputs_filtered ("\\n", stream);
8705796c8dcSSimon Schubert       break;
8715796c8dcSSimon Schubert     case '\f':
8725796c8dcSSimon Schubert       fputs_filtered ("\\f", stream);
8735796c8dcSSimon Schubert       break;
8745796c8dcSSimon Schubert     case '\r':
8755796c8dcSSimon Schubert       fputs_filtered ("\\r", stream);
8765796c8dcSSimon Schubert       break;
8775796c8dcSSimon Schubert     default:
8785796c8dcSSimon Schubert       if (isprint (c))
8795796c8dcSSimon Schubert 	fputc_filtered (c, stream);
8805796c8dcSSimon Schubert       else
8815796c8dcSSimon Schubert 	fprintf_filtered (stream, "\\u%.4x", (unsigned int) c);
8825796c8dcSSimon Schubert       break;
8835796c8dcSSimon Schubert     }
8845796c8dcSSimon Schubert }
8855796c8dcSSimon Schubert 
8865796c8dcSSimon Schubert static struct value *
8875796c8dcSSimon Schubert evaluate_subexp_java (struct type *expect_type, struct expression *exp,
8885796c8dcSSimon Schubert 		      int *pos, enum noside noside)
8895796c8dcSSimon Schubert {
8905796c8dcSSimon Schubert   int pc = *pos;
8915796c8dcSSimon Schubert   int i;
8925796c8dcSSimon Schubert   char *name;
8935796c8dcSSimon Schubert   enum exp_opcode op = exp->elts[*pos].opcode;
8945796c8dcSSimon Schubert   struct value *arg1;
8955796c8dcSSimon Schubert   struct value *arg2;
8965796c8dcSSimon Schubert   struct type *type;
897*cf7f2e2dSJohn Marino 
8985796c8dcSSimon Schubert   switch (op)
8995796c8dcSSimon Schubert     {
9005796c8dcSSimon Schubert     case UNOP_IND:
9015796c8dcSSimon Schubert       if (noside == EVAL_SKIP)
9025796c8dcSSimon Schubert 	goto standard;
9035796c8dcSSimon Schubert       (*pos)++;
9045796c8dcSSimon Schubert       arg1 = evaluate_subexp_java (NULL_TYPE, exp, pos, EVAL_NORMAL);
9055796c8dcSSimon Schubert       if (is_object_type (value_type (arg1)))
9065796c8dcSSimon Schubert 	{
9075796c8dcSSimon Schubert 	  struct type *type;
9085796c8dcSSimon Schubert 
9095796c8dcSSimon Schubert 	  type = type_from_class (exp->gdbarch, java_class_from_object (arg1));
9105796c8dcSSimon Schubert 	  arg1 = value_cast (lookup_pointer_type (type), arg1);
9115796c8dcSSimon Schubert 	}
9125796c8dcSSimon Schubert       if (noside == EVAL_SKIP)
9135796c8dcSSimon Schubert 	goto nosideret;
9145796c8dcSSimon Schubert       return value_ind (arg1);
9155796c8dcSSimon Schubert 
9165796c8dcSSimon Schubert     case BINOP_SUBSCRIPT:
9175796c8dcSSimon Schubert       (*pos)++;
9185796c8dcSSimon Schubert       arg1 = evaluate_subexp_with_coercion (exp, pos, noside);
9195796c8dcSSimon Schubert       arg2 = evaluate_subexp_with_coercion (exp, pos, noside);
9205796c8dcSSimon Schubert       if (noside == EVAL_SKIP)
9215796c8dcSSimon Schubert 	goto nosideret;
9225796c8dcSSimon Schubert       /* If the user attempts to subscript something that is not an
9235796c8dcSSimon Schubert          array or pointer type (like a plain int variable for example),
9245796c8dcSSimon Schubert          then report this as an error. */
9255796c8dcSSimon Schubert 
9265796c8dcSSimon Schubert       arg1 = coerce_ref (arg1);
9275796c8dcSSimon Schubert       type = check_typedef (value_type (arg1));
9285796c8dcSSimon Schubert       if (TYPE_CODE (type) == TYPE_CODE_PTR)
9295796c8dcSSimon Schubert 	type = check_typedef (TYPE_TARGET_TYPE (type));
9305796c8dcSSimon Schubert       name = TYPE_NAME (type);
9315796c8dcSSimon Schubert       if (name == NULL)
9325796c8dcSSimon Schubert 	name = TYPE_TAG_NAME (type);
9335796c8dcSSimon Schubert       i = name == NULL ? 0 : strlen (name);
9345796c8dcSSimon Schubert       if (TYPE_CODE (type) == TYPE_CODE_STRUCT
9355796c8dcSSimon Schubert 	  && i > 2 && name[i - 1] == ']')
9365796c8dcSSimon Schubert 	{
9375796c8dcSSimon Schubert 	  enum bfd_endian byte_order = gdbarch_byte_order (exp->gdbarch);
9385796c8dcSSimon Schubert 	  CORE_ADDR address;
9395796c8dcSSimon Schubert 	  long length, index;
9405796c8dcSSimon Schubert 	  struct type *el_type;
9415796c8dcSSimon Schubert 	  gdb_byte buf4[4];
9425796c8dcSSimon Schubert 
9435796c8dcSSimon Schubert 	  struct value *clas = java_class_from_object (arg1);
9445796c8dcSSimon Schubert 	  struct value *temp = clas;
9455796c8dcSSimon Schubert 	  /* Get CLASS_ELEMENT_TYPE of the array type. */
9465796c8dcSSimon Schubert 	  temp = value_struct_elt (&temp, NULL, "methods",
9475796c8dcSSimon Schubert 				   NULL, "structure");
9485796c8dcSSimon Schubert 	  deprecated_set_value_type (temp, value_type (clas));
9495796c8dcSSimon Schubert 	  el_type = type_from_class (exp->gdbarch, temp);
9505796c8dcSSimon Schubert 	  if (TYPE_CODE (el_type) == TYPE_CODE_STRUCT)
9515796c8dcSSimon Schubert 	    el_type = lookup_pointer_type (el_type);
9525796c8dcSSimon Schubert 
9535796c8dcSSimon Schubert 	  if (noside == EVAL_AVOID_SIDE_EFFECTS)
9545796c8dcSSimon Schubert 	    return value_zero (el_type, VALUE_LVAL (arg1));
9555796c8dcSSimon Schubert 	  address = value_as_address (arg1);
9565796c8dcSSimon Schubert 	  address += get_java_object_header_size (exp->gdbarch);
9575796c8dcSSimon Schubert 	  read_memory (address, buf4, 4);
9585796c8dcSSimon Schubert 	  length = (long) extract_signed_integer (buf4, 4, byte_order);
9595796c8dcSSimon Schubert 	  index = (long) value_as_long (arg2);
9605796c8dcSSimon Schubert 	  if (index >= length || index < 0)
9615796c8dcSSimon Schubert 	    error (_("array index (%ld) out of bounds (length: %ld)"),
9625796c8dcSSimon Schubert 		   index, length);
9635796c8dcSSimon Schubert 	  address = (address + 4) + index * TYPE_LENGTH (el_type);
9645796c8dcSSimon Schubert 	  return value_at (el_type, address);
9655796c8dcSSimon Schubert 	}
9665796c8dcSSimon Schubert       else if (TYPE_CODE (type) == TYPE_CODE_ARRAY)
9675796c8dcSSimon Schubert 	{
9685796c8dcSSimon Schubert 	  if (noside == EVAL_AVOID_SIDE_EFFECTS)
9695796c8dcSSimon Schubert 	    return value_zero (TYPE_TARGET_TYPE (type), VALUE_LVAL (arg1));
9705796c8dcSSimon Schubert 	  else
9715796c8dcSSimon Schubert 	    return value_subscript (arg1, value_as_long (arg2));
9725796c8dcSSimon Schubert 	}
9735796c8dcSSimon Schubert       if (name)
9745796c8dcSSimon Schubert 	error (_("cannot subscript something of type `%s'"), name);
9755796c8dcSSimon Schubert       else
9765796c8dcSSimon Schubert 	error (_("cannot subscript requested type"));
9775796c8dcSSimon Schubert 
9785796c8dcSSimon Schubert     case OP_STRING:
9795796c8dcSSimon Schubert       (*pos)++;
9805796c8dcSSimon Schubert       i = longest_to_int (exp->elts[pc + 1].longconst);
9815796c8dcSSimon Schubert       (*pos) += 3 + BYTES_TO_EXP_ELEM (i + 1);
9825796c8dcSSimon Schubert       if (noside == EVAL_SKIP)
9835796c8dcSSimon Schubert 	goto nosideret;
9845796c8dcSSimon Schubert       return java_value_string (&exp->elts[pc + 2].string, i);
9855796c8dcSSimon Schubert 
9865796c8dcSSimon Schubert     case STRUCTOP_PTR:
9875796c8dcSSimon Schubert       arg1 = evaluate_subexp_standard (expect_type, exp, pos, noside);
9885796c8dcSSimon Schubert       /* Convert object field (such as TYPE.class) to reference. */
9895796c8dcSSimon Schubert       if (TYPE_CODE (value_type (arg1)) == TYPE_CODE_STRUCT)
9905796c8dcSSimon Schubert 	arg1 = value_addr (arg1);
9915796c8dcSSimon Schubert       return arg1;
9925796c8dcSSimon Schubert     default:
9935796c8dcSSimon Schubert       break;
9945796c8dcSSimon Schubert     }
9955796c8dcSSimon Schubert standard:
9965796c8dcSSimon Schubert   return evaluate_subexp_standard (expect_type, exp, pos, noside);
9975796c8dcSSimon Schubert nosideret:
9985796c8dcSSimon Schubert   return value_from_longest (builtin_type (exp->gdbarch)->builtin_int, 1);
9995796c8dcSSimon Schubert }
10005796c8dcSSimon Schubert 
10015796c8dcSSimon Schubert static char *java_demangle (const char *mangled, int options)
10025796c8dcSSimon Schubert {
10035796c8dcSSimon Schubert   return cplus_demangle (mangled, options | DMGL_JAVA);
10045796c8dcSSimon Schubert }
10055796c8dcSSimon Schubert 
10065796c8dcSSimon Schubert /* Find the member function name of the demangled name NAME.  NAME
10075796c8dcSSimon Schubert    must be a method name including arguments, in order to correctly
10085796c8dcSSimon Schubert    locate the last component.
10095796c8dcSSimon Schubert 
10105796c8dcSSimon Schubert    This function return a pointer to the first dot before the
10115796c8dcSSimon Schubert    member function name, or NULL if the name was not of the
10125796c8dcSSimon Schubert    expected form.  */
10135796c8dcSSimon Schubert 
10145796c8dcSSimon Schubert static const char *
10155796c8dcSSimon Schubert java_find_last_component (const char *name)
10165796c8dcSSimon Schubert {
10175796c8dcSSimon Schubert   const char *p;
10185796c8dcSSimon Schubert 
10195796c8dcSSimon Schubert   /* Find argument list.  */
10205796c8dcSSimon Schubert   p = strchr (name, '(');
10215796c8dcSSimon Schubert 
10225796c8dcSSimon Schubert   if (p == NULL)
10235796c8dcSSimon Schubert     return NULL;
10245796c8dcSSimon Schubert 
10255796c8dcSSimon Schubert   /* Back up and find first dot prior to argument list.  */
10265796c8dcSSimon Schubert   while (p > name && *p != '.')
10275796c8dcSSimon Schubert     p--;
10285796c8dcSSimon Schubert 
10295796c8dcSSimon Schubert   if (p == name)
10305796c8dcSSimon Schubert     return NULL;
10315796c8dcSSimon Schubert 
10325796c8dcSSimon Schubert   return p;
10335796c8dcSSimon Schubert }
10345796c8dcSSimon Schubert 
10355796c8dcSSimon Schubert /* Return the name of the class containing method PHYSNAME.  */
10365796c8dcSSimon Schubert 
10375796c8dcSSimon Schubert static char *
10385796c8dcSSimon Schubert java_class_name_from_physname (const char *physname)
10395796c8dcSSimon Schubert {
10405796c8dcSSimon Schubert   char *ret = NULL;
10415796c8dcSSimon Schubert   const char *end;
10425796c8dcSSimon Schubert   char *demangled_name = java_demangle (physname, DMGL_PARAMS | DMGL_ANSI);
10435796c8dcSSimon Schubert 
10445796c8dcSSimon Schubert   if (demangled_name == NULL)
10455796c8dcSSimon Schubert     return NULL;
10465796c8dcSSimon Schubert 
10475796c8dcSSimon Schubert   end = java_find_last_component (demangled_name);
10485796c8dcSSimon Schubert   if (end != NULL)
10495796c8dcSSimon Schubert     {
10505796c8dcSSimon Schubert       ret = xmalloc (end - demangled_name + 1);
10515796c8dcSSimon Schubert       memcpy (ret, demangled_name, end - demangled_name);
10525796c8dcSSimon Schubert       ret[end - demangled_name] = '\0';
10535796c8dcSSimon Schubert     }
10545796c8dcSSimon Schubert 
10555796c8dcSSimon Schubert   xfree (demangled_name);
10565796c8dcSSimon Schubert   return ret;
10575796c8dcSSimon Schubert }
10585796c8dcSSimon Schubert 
10595796c8dcSSimon Schubert /* Table mapping opcodes into strings for printing operators
10605796c8dcSSimon Schubert    and precedences of the operators.  */
10615796c8dcSSimon Schubert 
10625796c8dcSSimon Schubert const struct op_print java_op_print_tab[] =
10635796c8dcSSimon Schubert {
10645796c8dcSSimon Schubert   {",", BINOP_COMMA, PREC_COMMA, 0},
10655796c8dcSSimon Schubert   {"=", BINOP_ASSIGN, PREC_ASSIGN, 1},
10665796c8dcSSimon Schubert   {"||", BINOP_LOGICAL_OR, PREC_LOGICAL_OR, 0},
10675796c8dcSSimon Schubert   {"&&", BINOP_LOGICAL_AND, PREC_LOGICAL_AND, 0},
10685796c8dcSSimon Schubert   {"|", BINOP_BITWISE_IOR, PREC_BITWISE_IOR, 0},
10695796c8dcSSimon Schubert   {"^", BINOP_BITWISE_XOR, PREC_BITWISE_XOR, 0},
10705796c8dcSSimon Schubert   {"&", BINOP_BITWISE_AND, PREC_BITWISE_AND, 0},
10715796c8dcSSimon Schubert   {"==", BINOP_EQUAL, PREC_EQUAL, 0},
10725796c8dcSSimon Schubert   {"!=", BINOP_NOTEQUAL, PREC_EQUAL, 0},
10735796c8dcSSimon Schubert   {"<=", BINOP_LEQ, PREC_ORDER, 0},
10745796c8dcSSimon Schubert   {">=", BINOP_GEQ, PREC_ORDER, 0},
10755796c8dcSSimon Schubert   {">", BINOP_GTR, PREC_ORDER, 0},
10765796c8dcSSimon Schubert   {"<", BINOP_LESS, PREC_ORDER, 0},
10775796c8dcSSimon Schubert   {">>", BINOP_RSH, PREC_SHIFT, 0},
10785796c8dcSSimon Schubert   {"<<", BINOP_LSH, PREC_SHIFT, 0},
10795796c8dcSSimon Schubert   {"+", BINOP_ADD, PREC_ADD, 0},
10805796c8dcSSimon Schubert   {"-", BINOP_SUB, PREC_ADD, 0},
10815796c8dcSSimon Schubert   {"*", BINOP_MUL, PREC_MUL, 0},
10825796c8dcSSimon Schubert   {"/", BINOP_DIV, PREC_MUL, 0},
10835796c8dcSSimon Schubert   {"%", BINOP_REM, PREC_MUL, 0},
10845796c8dcSSimon Schubert   {"-", UNOP_NEG, PREC_PREFIX, 0},
10855796c8dcSSimon Schubert   {"!", UNOP_LOGICAL_NOT, PREC_PREFIX, 0},
10865796c8dcSSimon Schubert   {"~", UNOP_COMPLEMENT, PREC_PREFIX, 0},
10875796c8dcSSimon Schubert   {"*", UNOP_IND, PREC_PREFIX, 0},
10885796c8dcSSimon Schubert   {"++", UNOP_PREINCREMENT, PREC_PREFIX, 0},
10895796c8dcSSimon Schubert   {"--", UNOP_PREDECREMENT, PREC_PREFIX, 0},
10905796c8dcSSimon Schubert   {NULL, 0, 0, 0}
10915796c8dcSSimon Schubert };
10925796c8dcSSimon Schubert 
10935796c8dcSSimon Schubert enum java_primitive_types
10945796c8dcSSimon Schubert {
10955796c8dcSSimon Schubert   java_primitive_type_int,
10965796c8dcSSimon Schubert   java_primitive_type_short,
10975796c8dcSSimon Schubert   java_primitive_type_long,
10985796c8dcSSimon Schubert   java_primitive_type_byte,
10995796c8dcSSimon Schubert   java_primitive_type_boolean,
11005796c8dcSSimon Schubert   java_primitive_type_char,
11015796c8dcSSimon Schubert   java_primitive_type_float,
11025796c8dcSSimon Schubert   java_primitive_type_double,
11035796c8dcSSimon Schubert   java_primitive_type_void,
11045796c8dcSSimon Schubert   nr_java_primitive_types
11055796c8dcSSimon Schubert };
11065796c8dcSSimon Schubert 
11075796c8dcSSimon Schubert static void
11085796c8dcSSimon Schubert java_language_arch_info (struct gdbarch *gdbarch,
11095796c8dcSSimon Schubert 			 struct language_arch_info *lai)
11105796c8dcSSimon Schubert {
11115796c8dcSSimon Schubert   const struct builtin_java_type *builtin = builtin_java_type (gdbarch);
11125796c8dcSSimon Schubert 
11135796c8dcSSimon Schubert   lai->string_char_type = builtin->builtin_char;
11145796c8dcSSimon Schubert   lai->primitive_type_vector
11155796c8dcSSimon Schubert     = GDBARCH_OBSTACK_CALLOC (gdbarch, nr_java_primitive_types + 1,
11165796c8dcSSimon Schubert                               struct type *);
11175796c8dcSSimon Schubert   lai->primitive_type_vector [java_primitive_type_int]
11185796c8dcSSimon Schubert     = builtin->builtin_int;
11195796c8dcSSimon Schubert   lai->primitive_type_vector [java_primitive_type_short]
11205796c8dcSSimon Schubert     = builtin->builtin_short;
11215796c8dcSSimon Schubert   lai->primitive_type_vector [java_primitive_type_long]
11225796c8dcSSimon Schubert     = builtin->builtin_long;
11235796c8dcSSimon Schubert   lai->primitive_type_vector [java_primitive_type_byte]
11245796c8dcSSimon Schubert     = builtin->builtin_byte;
11255796c8dcSSimon Schubert   lai->primitive_type_vector [java_primitive_type_boolean]
11265796c8dcSSimon Schubert     = builtin->builtin_boolean;
11275796c8dcSSimon Schubert   lai->primitive_type_vector [java_primitive_type_char]
11285796c8dcSSimon Schubert     = builtin->builtin_char;
11295796c8dcSSimon Schubert   lai->primitive_type_vector [java_primitive_type_float]
11305796c8dcSSimon Schubert     = builtin->builtin_float;
11315796c8dcSSimon Schubert   lai->primitive_type_vector [java_primitive_type_double]
11325796c8dcSSimon Schubert     = builtin->builtin_double;
11335796c8dcSSimon Schubert   lai->primitive_type_vector [java_primitive_type_void]
11345796c8dcSSimon Schubert     = builtin->builtin_void;
11355796c8dcSSimon Schubert 
11365796c8dcSSimon Schubert   lai->bool_type_symbol = "boolean";
11375796c8dcSSimon Schubert   lai->bool_type_default = builtin->builtin_boolean;
11385796c8dcSSimon Schubert }
11395796c8dcSSimon Schubert 
11405796c8dcSSimon Schubert const struct exp_descriptor exp_descriptor_java =
11415796c8dcSSimon Schubert {
11425796c8dcSSimon Schubert   print_subexp_standard,
11435796c8dcSSimon Schubert   operator_length_standard,
1144*cf7f2e2dSJohn Marino   operator_check_standard,
11455796c8dcSSimon Schubert   op_name_standard,
11465796c8dcSSimon Schubert   dump_subexp_body_standard,
11475796c8dcSSimon Schubert   evaluate_subexp_java
11485796c8dcSSimon Schubert };
11495796c8dcSSimon Schubert 
11505796c8dcSSimon Schubert const struct language_defn java_language_defn =
11515796c8dcSSimon Schubert {
11525796c8dcSSimon Schubert   "java",			/* Language name */
11535796c8dcSSimon Schubert   language_java,
11545796c8dcSSimon Schubert   range_check_off,
11555796c8dcSSimon Schubert   type_check_off,
11565796c8dcSSimon Schubert   case_sensitive_on,
11575796c8dcSSimon Schubert   array_row_major,
11585796c8dcSSimon Schubert   macro_expansion_no,
11595796c8dcSSimon Schubert   &exp_descriptor_java,
11605796c8dcSSimon Schubert   java_parse,
11615796c8dcSSimon Schubert   java_error,
11625796c8dcSSimon Schubert   null_post_parser,
11635796c8dcSSimon Schubert   c_printchar,			/* Print a character constant */
11645796c8dcSSimon Schubert   c_printstr,			/* Function to print string constant */
11655796c8dcSSimon Schubert   java_emit_char,		/* Function to print a single character */
11665796c8dcSSimon Schubert   java_print_type,		/* Print a type using appropriate syntax */
11675796c8dcSSimon Schubert   default_print_typedef,	/* Print a typedef using appropriate syntax */
11685796c8dcSSimon Schubert   java_val_print,		/* Print a value using appropriate syntax */
11695796c8dcSSimon Schubert   java_value_print,		/* Print a top-level value */
11705796c8dcSSimon Schubert   NULL,				/* Language specific skip_trampoline */
11715796c8dcSSimon Schubert   "this",	                /* name_of_this */
11725796c8dcSSimon Schubert   basic_lookup_symbol_nonlocal,	/* lookup_symbol_nonlocal */
11735796c8dcSSimon Schubert   basic_lookup_transparent_type,/* lookup_transparent_type */
11745796c8dcSSimon Schubert   java_demangle,		/* Language specific symbol demangler */
11755796c8dcSSimon Schubert   java_class_name_from_physname,/* Language specific class name */
11765796c8dcSSimon Schubert   java_op_print_tab,		/* expression operators for printing */
11775796c8dcSSimon Schubert   0,				/* not c-style arrays */
11785796c8dcSSimon Schubert   0,				/* String lower bound */
11795796c8dcSSimon Schubert   default_word_break_characters,
11805796c8dcSSimon Schubert   default_make_symbol_completion_list,
11815796c8dcSSimon Schubert   java_language_arch_info,
11825796c8dcSSimon Schubert   default_print_array_index,
11835796c8dcSSimon Schubert   default_pass_by_reference,
11845796c8dcSSimon Schubert   default_get_string,
11855796c8dcSSimon Schubert   LANG_MAGIC
11865796c8dcSSimon Schubert };
11875796c8dcSSimon Schubert 
11885796c8dcSSimon Schubert static void *
11895796c8dcSSimon Schubert build_java_types (struct gdbarch *gdbarch)
11905796c8dcSSimon Schubert {
11915796c8dcSSimon Schubert   struct builtin_java_type *builtin_java_type
11925796c8dcSSimon Schubert     = GDBARCH_OBSTACK_ZALLOC (gdbarch, struct builtin_java_type);
11935796c8dcSSimon Schubert 
11945796c8dcSSimon Schubert   builtin_java_type->builtin_int
11955796c8dcSSimon Schubert     = arch_integer_type (gdbarch, 32, 0, "int");
11965796c8dcSSimon Schubert   builtin_java_type->builtin_short
11975796c8dcSSimon Schubert     = arch_integer_type (gdbarch, 16, 0, "short");
11985796c8dcSSimon Schubert   builtin_java_type->builtin_long
11995796c8dcSSimon Schubert     = arch_integer_type (gdbarch, 64, 0, "long");
12005796c8dcSSimon Schubert   builtin_java_type->builtin_byte
12015796c8dcSSimon Schubert     = arch_integer_type (gdbarch, 8, 0, "byte");
12025796c8dcSSimon Schubert   builtin_java_type->builtin_boolean
12035796c8dcSSimon Schubert     = arch_boolean_type (gdbarch, 8, 0, "boolean");
12045796c8dcSSimon Schubert   builtin_java_type->builtin_char
12055796c8dcSSimon Schubert     = arch_character_type (gdbarch, 16, 1, "char");
12065796c8dcSSimon Schubert   builtin_java_type->builtin_float
12075796c8dcSSimon Schubert     = arch_float_type (gdbarch, 32, "float", NULL);
12085796c8dcSSimon Schubert   builtin_java_type->builtin_double
12095796c8dcSSimon Schubert     = arch_float_type (gdbarch, 64, "double", NULL);
12105796c8dcSSimon Schubert   builtin_java_type->builtin_void
12115796c8dcSSimon Schubert     = arch_type (gdbarch, TYPE_CODE_VOID, 1, "void");
12125796c8dcSSimon Schubert 
12135796c8dcSSimon Schubert   return builtin_java_type;
12145796c8dcSSimon Schubert }
12155796c8dcSSimon Schubert 
12165796c8dcSSimon Schubert static struct gdbarch_data *java_type_data;
12175796c8dcSSimon Schubert 
12185796c8dcSSimon Schubert const struct builtin_java_type *
12195796c8dcSSimon Schubert builtin_java_type (struct gdbarch *gdbarch)
12205796c8dcSSimon Schubert {
12215796c8dcSSimon Schubert   return gdbarch_data (gdbarch, java_type_data);
12225796c8dcSSimon Schubert }
12235796c8dcSSimon Schubert 
12245796c8dcSSimon Schubert void
12255796c8dcSSimon Schubert _initialize_java_language (void)
12265796c8dcSSimon Schubert {
1227*cf7f2e2dSJohn Marino   jv_dynamics_objfile_data_key
1228*cf7f2e2dSJohn Marino     = register_objfile_data_with_cleanup (NULL, jv_per_objfile_free);
1229*cf7f2e2dSJohn Marino   jv_type_objfile_data_key
1230*cf7f2e2dSJohn Marino     = register_objfile_data_with_cleanup (NULL, jv_clear_object_type);
1231*cf7f2e2dSJohn Marino 
12325796c8dcSSimon Schubert   java_type_data = gdbarch_data_register_post_init (build_java_types);
12335796c8dcSSimon Schubert 
12345796c8dcSSimon Schubert   add_language (&java_language_defn);
12355796c8dcSSimon Schubert }
1236