xref: /dflybsd-src/contrib/gdb-7/gdb/jv-lang.c (revision de8e141f24382815c10a4012d209bbbf7abf1112)
15796c8dcSSimon Schubert /* Java language support routines for GDB, the GNU debugger.
25796c8dcSSimon Schubert 
3*ef5ccd6cSJohn Marino    Copyright (C) 1997-2013 Free Software Foundation, Inc.
45796c8dcSSimon Schubert 
55796c8dcSSimon Schubert    This file is part of GDB.
65796c8dcSSimon Schubert 
75796c8dcSSimon Schubert    This program is free software; you can redistribute it and/or modify
85796c8dcSSimon Schubert    it under the terms of the GNU General Public License as published by
95796c8dcSSimon Schubert    the Free Software Foundation; either version 3 of the License, or
105796c8dcSSimon Schubert    (at your option) any later version.
115796c8dcSSimon Schubert 
125796c8dcSSimon Schubert    This program is distributed in the hope that it will be useful,
135796c8dcSSimon Schubert    but WITHOUT ANY WARRANTY; without even the implied warranty of
145796c8dcSSimon Schubert    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
155796c8dcSSimon Schubert    GNU General Public License for more details.
165796c8dcSSimon Schubert 
175796c8dcSSimon Schubert    You should have received a copy of the GNU General Public License
185796c8dcSSimon Schubert    along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
195796c8dcSSimon Schubert 
205796c8dcSSimon Schubert #include "defs.h"
215796c8dcSSimon Schubert #include "symtab.h"
225796c8dcSSimon Schubert #include "gdbtypes.h"
235796c8dcSSimon Schubert #include "expression.h"
245796c8dcSSimon Schubert #include "parser-defs.h"
255796c8dcSSimon Schubert #include "language.h"
265796c8dcSSimon Schubert #include "gdbtypes.h"
275796c8dcSSimon Schubert #include "symtab.h"
285796c8dcSSimon Schubert #include "symfile.h"
295796c8dcSSimon Schubert #include "objfiles.h"
305796c8dcSSimon Schubert #include "gdb_string.h"
315796c8dcSSimon Schubert #include "value.h"
325796c8dcSSimon Schubert #include "c-lang.h"
335796c8dcSSimon Schubert #include "jv-lang.h"
345796c8dcSSimon Schubert #include "gdbcore.h"
355796c8dcSSimon Schubert #include "block.h"
365796c8dcSSimon Schubert #include "demangle.h"
375796c8dcSSimon Schubert #include "dictionary.h"
385796c8dcSSimon Schubert #include <ctype.h>
395796c8dcSSimon Schubert #include "gdb_assert.h"
40a45ae5f8SJohn Marino #include "charset.h"
41a45ae5f8SJohn Marino #include "valprint.h"
425796c8dcSSimon Schubert 
435796c8dcSSimon Schubert /* Local functions */
445796c8dcSSimon Schubert 
455796c8dcSSimon Schubert extern void _initialize_java_language (void);
465796c8dcSSimon Schubert 
47*ef5ccd6cSJohn Marino static int java_demangled_signature_length (const char *);
48*ef5ccd6cSJohn Marino static void java_demangled_signature_copy (char *, const char *);
495796c8dcSSimon Schubert 
50cf7f2e2dSJohn Marino static struct symtab *get_java_class_symtab (struct gdbarch *gdbarch);
515796c8dcSSimon Schubert static char *get_java_utf8_name (struct obstack *obstack, struct value *name);
525796c8dcSSimon Schubert static int java_class_is_primitive (struct value *clas);
535796c8dcSSimon Schubert static struct value *java_value_string (char *ptr, int len);
545796c8dcSSimon Schubert 
555796c8dcSSimon Schubert static void java_emit_char (int c, struct type *type,
565796c8dcSSimon Schubert 			    struct ui_file * stream, int quoter);
575796c8dcSSimon Schubert 
585796c8dcSSimon Schubert static char *java_class_name_from_physname (const char *physname);
595796c8dcSSimon Schubert 
60cf7f2e2dSJohn Marino static const struct objfile_data *jv_dynamics_objfile_data_key;
61cf7f2e2dSJohn Marino 
62a45ae5f8SJohn Marino /* The dynamic objfile is kept per-program-space.  This key lets us
63a45ae5f8SJohn Marino    associate the objfile with the program space.  */
645796c8dcSSimon Schubert 
65a45ae5f8SJohn Marino static const struct program_space_data *jv_dynamics_progspace_key;
66cf7f2e2dSJohn Marino 
675796c8dcSSimon Schubert static struct type *java_link_class_type (struct gdbarch *,
685796c8dcSSimon Schubert 					  struct type *, struct value *);
695796c8dcSSimon Schubert 
70a45ae5f8SJohn Marino /* An instance of this structure is used to store some data that must
71a45ae5f8SJohn Marino    be freed.  */
72a45ae5f8SJohn Marino 
73a45ae5f8SJohn Marino struct jv_per_objfile_data
74a45ae5f8SJohn Marino {
75a45ae5f8SJohn Marino   /* The expandable dictionary we use.  */
76a45ae5f8SJohn Marino   struct dictionary *dict;
77a45ae5f8SJohn Marino };
78a45ae5f8SJohn Marino 
79cf7f2e2dSJohn Marino /* A function called when the dynamics_objfile is freed.  We use this
80cf7f2e2dSJohn Marino    to clean up some internal state.  */
81cf7f2e2dSJohn Marino static void
jv_per_objfile_free(struct objfile * objfile,void * data)82a45ae5f8SJohn Marino jv_per_objfile_free (struct objfile *objfile, void *data)
83cf7f2e2dSJohn Marino {
84a45ae5f8SJohn Marino   struct jv_per_objfile_data *jv_data = data;
85a45ae5f8SJohn Marino   struct objfile *dynamics_objfile;
86a45ae5f8SJohn Marino 
87a45ae5f8SJohn Marino   dynamics_objfile = program_space_data (current_program_space,
88a45ae5f8SJohn Marino 					 jv_dynamics_progspace_key);
89cf7f2e2dSJohn Marino   gdb_assert (objfile == dynamics_objfile);
90a45ae5f8SJohn Marino 
91a45ae5f8SJohn Marino   if (jv_data->dict)
92a45ae5f8SJohn Marino     dict_free (jv_data->dict);
93a45ae5f8SJohn Marino   xfree (jv_data);
94a45ae5f8SJohn Marino 
95a45ae5f8SJohn Marino   set_program_space_data (current_program_space,
96a45ae5f8SJohn Marino 			  jv_dynamics_progspace_key,
97a45ae5f8SJohn Marino 			  NULL);
98cf7f2e2dSJohn Marino }
99cf7f2e2dSJohn Marino 
1005796c8dcSSimon Schubert /* FIXME: carlton/2003-02-04: This is the main or only caller of
1015796c8dcSSimon Schubert    allocate_objfile with first argument NULL; as a result, this code
1025796c8dcSSimon Schubert    breaks every so often.  Somebody should write a test case that
1035796c8dcSSimon Schubert    exercises GDB in various ways (e.g. something involving loading a
1045796c8dcSSimon Schubert    dynamic library) after this code has been called.  */
1055796c8dcSSimon Schubert 
1065796c8dcSSimon Schubert static struct objfile *
get_dynamics_objfile(struct gdbarch * gdbarch)107cf7f2e2dSJohn Marino get_dynamics_objfile (struct gdbarch *gdbarch)
1085796c8dcSSimon Schubert {
109a45ae5f8SJohn Marino   struct objfile *dynamics_objfile;
110a45ae5f8SJohn Marino 
111a45ae5f8SJohn Marino   dynamics_objfile = program_space_data (current_program_space,
112a45ae5f8SJohn Marino 					 jv_dynamics_progspace_key);
113a45ae5f8SJohn Marino 
1145796c8dcSSimon Schubert   if (dynamics_objfile == NULL)
1155796c8dcSSimon Schubert     {
116a45ae5f8SJohn Marino       struct jv_per_objfile_data *data;
117a45ae5f8SJohn Marino 
118cf7f2e2dSJohn Marino       /* Mark it as shared so that it is cleared when the inferior is
119cf7f2e2dSJohn Marino 	 re-run.  */
120cf7f2e2dSJohn Marino       dynamics_objfile = allocate_objfile (NULL, OBJF_SHARED);
121cf7f2e2dSJohn Marino       dynamics_objfile->gdbarch = gdbarch;
122a45ae5f8SJohn Marino 
123a45ae5f8SJohn Marino       data = XCNEW (struct jv_per_objfile_data);
124a45ae5f8SJohn Marino       set_objfile_data (dynamics_objfile, jv_dynamics_objfile_data_key, data);
125a45ae5f8SJohn Marino 
126a45ae5f8SJohn Marino       set_program_space_data (current_program_space,
127a45ae5f8SJohn Marino 			      jv_dynamics_progspace_key,
128a45ae5f8SJohn Marino 			      dynamics_objfile);
1295796c8dcSSimon Schubert     }
1305796c8dcSSimon Schubert   return dynamics_objfile;
1315796c8dcSSimon Schubert }
1325796c8dcSSimon Schubert 
1335796c8dcSSimon Schubert static struct symtab *
get_java_class_symtab(struct gdbarch * gdbarch)134cf7f2e2dSJohn Marino get_java_class_symtab (struct gdbarch *gdbarch)
1355796c8dcSSimon Schubert {
136a45ae5f8SJohn Marino   struct objfile *objfile = get_dynamics_objfile (gdbarch);
137a45ae5f8SJohn Marino   struct symtab *class_symtab = objfile->symtabs;
138a45ae5f8SJohn Marino 
1395796c8dcSSimon Schubert   if (class_symtab == NULL)
1405796c8dcSSimon Schubert     {
1415796c8dcSSimon Schubert       struct blockvector *bv;
1425796c8dcSSimon Schubert       struct block *bl;
143a45ae5f8SJohn Marino       struct jv_per_objfile_data *jv_data;
144cf7f2e2dSJohn Marino 
1455796c8dcSSimon Schubert       class_symtab = allocate_symtab ("<java-classes>", objfile);
1465796c8dcSSimon Schubert       class_symtab->language = language_java;
1475796c8dcSSimon Schubert       bv = (struct blockvector *)
1485796c8dcSSimon Schubert 	obstack_alloc (&objfile->objfile_obstack,
1495796c8dcSSimon Schubert 		       sizeof (struct blockvector) + sizeof (struct block *));
1505796c8dcSSimon Schubert       BLOCKVECTOR_NBLOCKS (bv) = 1;
1515796c8dcSSimon Schubert       BLOCKVECTOR (class_symtab) = bv;
1525796c8dcSSimon Schubert 
1535796c8dcSSimon Schubert       /* Allocate dummy STATIC_BLOCK.  */
1545796c8dcSSimon Schubert       bl = allocate_block (&objfile->objfile_obstack);
1555796c8dcSSimon Schubert       BLOCK_DICT (bl) = dict_create_linear (&objfile->objfile_obstack,
1565796c8dcSSimon Schubert 					    NULL);
1575796c8dcSSimon Schubert       BLOCKVECTOR_BLOCK (bv, STATIC_BLOCK) = bl;
1585796c8dcSSimon Schubert 
1595796c8dcSSimon Schubert       /* Allocate GLOBAL_BLOCK.  */
160*ef5ccd6cSJohn Marino       bl = allocate_global_block (&objfile->objfile_obstack);
1615796c8dcSSimon Schubert       BLOCK_DICT (bl) = dict_create_hashed_expandable ();
162*ef5ccd6cSJohn Marino       set_block_symtab (bl, class_symtab);
1635796c8dcSSimon Schubert       BLOCKVECTOR_BLOCK (bv, GLOBAL_BLOCK) = bl;
164a45ae5f8SJohn Marino 
165a45ae5f8SJohn Marino       /* Arrange to free the dict.  */
166a45ae5f8SJohn Marino       jv_data = objfile_data (objfile, jv_dynamics_objfile_data_key);
167a45ae5f8SJohn Marino       jv_data->dict = BLOCK_DICT (bl);
1685796c8dcSSimon Schubert     }
1695796c8dcSSimon Schubert   return class_symtab;
1705796c8dcSSimon Schubert }
1715796c8dcSSimon Schubert 
1725796c8dcSSimon Schubert static void
add_class_symtab_symbol(struct symbol * sym)1735796c8dcSSimon Schubert add_class_symtab_symbol (struct symbol *sym)
1745796c8dcSSimon Schubert {
175cf7f2e2dSJohn Marino   struct symtab *symtab
176cf7f2e2dSJohn Marino     = get_java_class_symtab (get_objfile_arch (SYMBOL_SYMTAB (sym)->objfile));
1775796c8dcSSimon Schubert   struct blockvector *bv = BLOCKVECTOR (symtab);
178cf7f2e2dSJohn Marino 
1795796c8dcSSimon Schubert   dict_add_symbol (BLOCK_DICT (BLOCKVECTOR_BLOCK (bv, GLOBAL_BLOCK)), sym);
1805796c8dcSSimon Schubert }
1815796c8dcSSimon Schubert 
1825796c8dcSSimon Schubert static struct symbol *
add_class_symbol(struct type * type,CORE_ADDR addr)1835796c8dcSSimon Schubert add_class_symbol (struct type *type, CORE_ADDR addr)
1845796c8dcSSimon Schubert {
1855796c8dcSSimon Schubert   struct symbol *sym;
186a45ae5f8SJohn Marino   struct objfile *objfile = get_dynamics_objfile (get_type_arch (type));
187cf7f2e2dSJohn Marino 
1885796c8dcSSimon Schubert   sym = (struct symbol *)
189a45ae5f8SJohn Marino     obstack_alloc (&objfile->objfile_obstack, sizeof (struct symbol));
1905796c8dcSSimon Schubert   memset (sym, 0, sizeof (struct symbol));
191c50c785cSJohn Marino   SYMBOL_SET_LANGUAGE (sym, language_java);
1925796c8dcSSimon Schubert   SYMBOL_SET_LINKAGE_NAME (sym, TYPE_TAG_NAME (type));
1935796c8dcSSimon Schubert   SYMBOL_CLASS (sym) = LOC_TYPEDEF;
1945796c8dcSSimon Schubert   /*  SYMBOL_VALUE (sym) = valu; */
1955796c8dcSSimon Schubert   SYMBOL_TYPE (sym) = type;
1965796c8dcSSimon Schubert   SYMBOL_DOMAIN (sym) = STRUCT_DOMAIN;
1975796c8dcSSimon Schubert   SYMBOL_VALUE_ADDRESS (sym) = addr;
1985796c8dcSSimon Schubert   return sym;
1995796c8dcSSimon Schubert }
2005796c8dcSSimon Schubert 
2015796c8dcSSimon Schubert struct type *
java_lookup_class(char * name)2025796c8dcSSimon Schubert java_lookup_class (char *name)
2035796c8dcSSimon Schubert {
2045796c8dcSSimon Schubert   struct symbol *sym;
205cf7f2e2dSJohn Marino 
2065796c8dcSSimon Schubert   sym = lookup_symbol (name, expression_context_block, STRUCT_DOMAIN, NULL);
2075796c8dcSSimon Schubert   if (sym != NULL)
2085796c8dcSSimon Schubert     return SYMBOL_TYPE (sym);
2095796c8dcSSimon Schubert   /* FIXME - should search inferior's symbol table.  */
2105796c8dcSSimon Schubert   return NULL;
2115796c8dcSSimon Schubert }
2125796c8dcSSimon Schubert 
2135796c8dcSSimon Schubert /* Return a nul-terminated string (allocated on OBSTACK) for
2145796c8dcSSimon Schubert    a name given by NAME (which has type Utf8Const*).  */
2155796c8dcSSimon Schubert 
2165796c8dcSSimon Schubert char *
get_java_utf8_name(struct obstack * obstack,struct value * name)2175796c8dcSSimon Schubert get_java_utf8_name (struct obstack *obstack, struct value *name)
2185796c8dcSSimon Schubert {
2195796c8dcSSimon Schubert   char *chrs;
2205796c8dcSSimon Schubert   struct value *temp = name;
2215796c8dcSSimon Schubert   int name_length;
2225796c8dcSSimon Schubert   CORE_ADDR data_addr;
223cf7f2e2dSJohn Marino 
2245796c8dcSSimon Schubert   temp = value_struct_elt (&temp, NULL, "length", NULL, "structure");
2255796c8dcSSimon Schubert   name_length = (int) value_as_long (temp);
2265796c8dcSSimon Schubert   data_addr = value_address (temp) + TYPE_LENGTH (value_type (temp));
2275796c8dcSSimon Schubert   chrs = obstack_alloc (obstack, name_length + 1);
2285796c8dcSSimon Schubert   chrs[name_length] = '\0';
2295796c8dcSSimon Schubert   read_memory (data_addr, (gdb_byte *) chrs, name_length);
2305796c8dcSSimon Schubert   return chrs;
2315796c8dcSSimon Schubert }
2325796c8dcSSimon Schubert 
2335796c8dcSSimon Schubert struct value *
java_class_from_object(struct value * obj_val)2345796c8dcSSimon Schubert java_class_from_object (struct value *obj_val)
2355796c8dcSSimon Schubert {
2365796c8dcSSimon Schubert   /* This is all rather inefficient, since the offsets of vtable and
2375796c8dcSSimon Schubert      class are fixed.  FIXME */
2385796c8dcSSimon Schubert   struct value *vtable_val;
2395796c8dcSSimon Schubert 
2405796c8dcSSimon Schubert   if (TYPE_CODE (value_type (obj_val)) == TYPE_CODE_PTR
2415796c8dcSSimon Schubert       && TYPE_LENGTH (TYPE_TARGET_TYPE (value_type (obj_val))) == 0)
2425796c8dcSSimon Schubert     obj_val = value_at (get_java_object_type (),
2435796c8dcSSimon Schubert 			value_as_address (obj_val));
2445796c8dcSSimon Schubert 
2455796c8dcSSimon Schubert   vtable_val = value_struct_elt (&obj_val, NULL, "vtable", NULL, "structure");
2465796c8dcSSimon Schubert   return value_struct_elt (&vtable_val, NULL, "class", NULL, "structure");
2475796c8dcSSimon Schubert }
2485796c8dcSSimon Schubert 
2495796c8dcSSimon Schubert /* Check if CLASS_IS_PRIMITIVE(value of clas): */
2505796c8dcSSimon Schubert static int
java_class_is_primitive(struct value * clas)2515796c8dcSSimon Schubert java_class_is_primitive (struct value *clas)
2525796c8dcSSimon Schubert {
253c50c785cSJohn Marino   struct value *vtable = value_struct_elt (&clas, NULL, "vtable",
254c50c785cSJohn Marino 					   NULL, "struct");
2555796c8dcSSimon Schubert   CORE_ADDR i = value_as_address (vtable);
256cf7f2e2dSJohn Marino 
2575796c8dcSSimon Schubert   return (int) (i & 0x7fffffff) == (int) 0x7fffffff;
2585796c8dcSSimon Schubert }
2595796c8dcSSimon Schubert 
2605796c8dcSSimon Schubert /* Read a GCJ Class object, and generated a gdb (TYPE_CODE_STRUCT) type.  */
2615796c8dcSSimon Schubert 
2625796c8dcSSimon Schubert struct type *
type_from_class(struct gdbarch * gdbarch,struct value * clas)2635796c8dcSSimon Schubert type_from_class (struct gdbarch *gdbarch, struct value *clas)
2645796c8dcSSimon Schubert {
2655796c8dcSSimon Schubert   struct type *type;
2665796c8dcSSimon Schubert   char *name;
2675796c8dcSSimon Schubert   struct value *temp;
2685796c8dcSSimon Schubert   struct objfile *objfile;
2695796c8dcSSimon Schubert   struct value *utf8_name;
2705796c8dcSSimon Schubert   char *nptr;
2715796c8dcSSimon Schubert   CORE_ADDR addr;
2725796c8dcSSimon Schubert 
2735796c8dcSSimon Schubert   type = check_typedef (value_type (clas));
2745796c8dcSSimon Schubert   if (TYPE_CODE (type) == TYPE_CODE_PTR)
2755796c8dcSSimon Schubert     {
2765796c8dcSSimon Schubert       if (value_logical_not (clas))
2775796c8dcSSimon Schubert 	return NULL;
2785796c8dcSSimon Schubert       clas = value_ind (clas);
2795796c8dcSSimon Schubert     }
2805796c8dcSSimon Schubert   addr = value_address (clas);
2815796c8dcSSimon Schubert 
282cf7f2e2dSJohn Marino   objfile = get_dynamics_objfile (gdbarch);
2835796c8dcSSimon Schubert   if (java_class_is_primitive (clas))
2845796c8dcSSimon Schubert     {
2855796c8dcSSimon Schubert       struct value *sig;
286cf7f2e2dSJohn Marino 
2875796c8dcSSimon Schubert       temp = clas;
2885796c8dcSSimon Schubert       sig = value_struct_elt (&temp, NULL, "method_count", NULL, "structure");
2895796c8dcSSimon Schubert       return java_primitive_type (gdbarch, value_as_long (sig));
2905796c8dcSSimon Schubert     }
2915796c8dcSSimon Schubert 
2925796c8dcSSimon Schubert   /* Get Class name.  */
293c50c785cSJohn Marino   /* If clasloader non-null, prepend loader address.  FIXME */
2945796c8dcSSimon Schubert   temp = clas;
2955796c8dcSSimon Schubert   utf8_name = value_struct_elt (&temp, NULL, "name", NULL, "structure");
2965796c8dcSSimon Schubert   name = get_java_utf8_name (&objfile->objfile_obstack, utf8_name);
2975796c8dcSSimon Schubert   for (nptr = name; *nptr != 0; nptr++)
2985796c8dcSSimon Schubert     {
2995796c8dcSSimon Schubert       if (*nptr == '/')
3005796c8dcSSimon Schubert 	*nptr = '.';
3015796c8dcSSimon Schubert     }
3025796c8dcSSimon Schubert 
3035796c8dcSSimon Schubert   type = java_lookup_class (name);
3045796c8dcSSimon Schubert   if (type != NULL)
3055796c8dcSSimon Schubert     return type;
3065796c8dcSSimon Schubert 
307cf7f2e2dSJohn Marino   type = alloc_type (objfile);
3085796c8dcSSimon Schubert   TYPE_CODE (type) = TYPE_CODE_STRUCT;
3095796c8dcSSimon Schubert   INIT_CPLUS_SPECIFIC (type);
3105796c8dcSSimon Schubert 
3115796c8dcSSimon Schubert   if (name[0] == '[')
3125796c8dcSSimon Schubert     {
3135796c8dcSSimon Schubert       char *signature = name;
3145796c8dcSSimon Schubert       int namelen = java_demangled_signature_length (signature);
315cf7f2e2dSJohn Marino 
3165796c8dcSSimon Schubert       if (namelen > strlen (name))
3175796c8dcSSimon Schubert 	name = obstack_alloc (&objfile->objfile_obstack, namelen + 1);
3185796c8dcSSimon Schubert       java_demangled_signature_copy (name, signature);
3195796c8dcSSimon Schubert       name[namelen] = '\0';
3205796c8dcSSimon Schubert       temp = clas;
3215796c8dcSSimon Schubert       /* Set array element type.  */
3225796c8dcSSimon Schubert       temp = value_struct_elt (&temp, NULL, "methods", NULL, "structure");
323c50c785cSJohn Marino       deprecated_set_value_type (temp,
324c50c785cSJohn Marino 				 lookup_pointer_type (value_type (clas)));
3255796c8dcSSimon Schubert       TYPE_TARGET_TYPE (type) = type_from_class (gdbarch, temp);
3265796c8dcSSimon Schubert     }
3275796c8dcSSimon Schubert 
3285796c8dcSSimon Schubert   ALLOCATE_CPLUS_STRUCT_TYPE (type);
3295796c8dcSSimon Schubert   TYPE_TAG_NAME (type) = name;
3305796c8dcSSimon Schubert 
3315796c8dcSSimon Schubert   add_class_symtab_symbol (add_class_symbol (type, addr));
3325796c8dcSSimon Schubert   return java_link_class_type (gdbarch, type, clas);
3335796c8dcSSimon Schubert }
3345796c8dcSSimon Schubert 
3355796c8dcSSimon Schubert /* Fill in class TYPE with data from the CLAS value.  */
3365796c8dcSSimon Schubert 
337cf7f2e2dSJohn Marino static struct type *
java_link_class_type(struct gdbarch * gdbarch,struct type * type,struct value * clas)3385796c8dcSSimon Schubert java_link_class_type (struct gdbarch *gdbarch,
3395796c8dcSSimon Schubert 		      struct type *type, struct value *clas)
3405796c8dcSSimon Schubert {
3415796c8dcSSimon Schubert   struct value *temp;
342*ef5ccd6cSJohn Marino   const char *unqualified_name;
343*ef5ccd6cSJohn Marino   const char *name = TYPE_TAG_NAME (type);
3445796c8dcSSimon Schubert   int ninterfaces, nfields, nmethods;
3455796c8dcSSimon Schubert   int type_is_object = 0;
3465796c8dcSSimon Schubert   struct fn_field *fn_fields;
3475796c8dcSSimon Schubert   struct fn_fieldlist *fn_fieldlists;
3485796c8dcSSimon Schubert   struct value *fields;
3495796c8dcSSimon Schubert   struct value *methods;
3505796c8dcSSimon Schubert   struct value *method = NULL;
3515796c8dcSSimon Schubert   struct value *field = NULL;
3525796c8dcSSimon Schubert   int i, j;
353cf7f2e2dSJohn Marino   struct objfile *objfile = get_dynamics_objfile (gdbarch);
3545796c8dcSSimon Schubert   struct type *tsuper;
3555796c8dcSSimon Schubert 
3565796c8dcSSimon Schubert   gdb_assert (name != NULL);
3575796c8dcSSimon Schubert   unqualified_name = strrchr (name, '.');
3585796c8dcSSimon Schubert   if (unqualified_name == NULL)
3595796c8dcSSimon Schubert     unqualified_name = name;
3605796c8dcSSimon Schubert 
3615796c8dcSSimon Schubert   temp = clas;
3625796c8dcSSimon Schubert   temp = value_struct_elt (&temp, NULL, "superclass", NULL, "structure");
3635796c8dcSSimon Schubert   if (strcmp (name, "java.lang.Object") == 0)
3645796c8dcSSimon Schubert     {
3655796c8dcSSimon Schubert       tsuper = get_java_object_type ();
3665796c8dcSSimon Schubert       if (tsuper && TYPE_CODE (tsuper) == TYPE_CODE_PTR)
3675796c8dcSSimon Schubert 	tsuper = TYPE_TARGET_TYPE (tsuper);
3685796c8dcSSimon Schubert       type_is_object = 1;
3695796c8dcSSimon Schubert     }
3705796c8dcSSimon Schubert   else
3715796c8dcSSimon Schubert     tsuper = type_from_class (gdbarch, temp);
3725796c8dcSSimon Schubert 
3735796c8dcSSimon Schubert #if 1
3745796c8dcSSimon Schubert   ninterfaces = 0;
3755796c8dcSSimon Schubert #else
3765796c8dcSSimon Schubert   temp = clas;
377c50c785cSJohn Marino   ninterfaces = value_as_long (value_struct_elt (&temp, NULL, "interface_len",
378c50c785cSJohn Marino 						 NULL, "structure"));
3795796c8dcSSimon Schubert #endif
3805796c8dcSSimon Schubert   TYPE_N_BASECLASSES (type) = (tsuper == NULL ? 0 : 1) + ninterfaces;
3815796c8dcSSimon Schubert   temp = clas;
382c50c785cSJohn Marino   nfields = value_as_long (value_struct_elt (&temp, NULL, "field_count",
383c50c785cSJohn Marino 					     NULL, "structure"));
3845796c8dcSSimon Schubert   nfields += TYPE_N_BASECLASSES (type);
3855796c8dcSSimon Schubert   nfields++;			/* Add one for dummy "class" field.  */
3865796c8dcSSimon Schubert   TYPE_NFIELDS (type) = nfields;
3875796c8dcSSimon Schubert   TYPE_FIELDS (type) = (struct field *)
3885796c8dcSSimon Schubert     TYPE_ALLOC (type, sizeof (struct field) * nfields);
3895796c8dcSSimon Schubert 
3905796c8dcSSimon Schubert   memset (TYPE_FIELDS (type), 0, sizeof (struct field) * nfields);
3915796c8dcSSimon Schubert 
3925796c8dcSSimon Schubert   TYPE_FIELD_PRIVATE_BITS (type) =
3935796c8dcSSimon Schubert     (B_TYPE *) TYPE_ALLOC (type, B_BYTES (nfields));
3945796c8dcSSimon Schubert   B_CLRALL (TYPE_FIELD_PRIVATE_BITS (type), nfields);
3955796c8dcSSimon Schubert 
3965796c8dcSSimon Schubert   TYPE_FIELD_PROTECTED_BITS (type) =
3975796c8dcSSimon Schubert     (B_TYPE *) TYPE_ALLOC (type, B_BYTES (nfields));
3985796c8dcSSimon Schubert   B_CLRALL (TYPE_FIELD_PROTECTED_BITS (type), nfields);
3995796c8dcSSimon Schubert 
4005796c8dcSSimon Schubert   TYPE_FIELD_IGNORE_BITS (type) =
4015796c8dcSSimon Schubert     (B_TYPE *) TYPE_ALLOC (type, B_BYTES (nfields));
4025796c8dcSSimon Schubert   B_CLRALL (TYPE_FIELD_IGNORE_BITS (type), nfields);
4035796c8dcSSimon Schubert 
4045796c8dcSSimon Schubert   TYPE_FIELD_VIRTUAL_BITS (type) = (B_TYPE *)
4055796c8dcSSimon Schubert     TYPE_ALLOC (type, B_BYTES (TYPE_N_BASECLASSES (type)));
4065796c8dcSSimon Schubert   B_CLRALL (TYPE_FIELD_VIRTUAL_BITS (type), TYPE_N_BASECLASSES (type));
4075796c8dcSSimon Schubert 
4085796c8dcSSimon Schubert   if (tsuper != NULL)
4095796c8dcSSimon Schubert     {
4105796c8dcSSimon Schubert       TYPE_BASECLASS (type, 0) = tsuper;
4115796c8dcSSimon Schubert       if (type_is_object)
4125796c8dcSSimon Schubert 	SET_TYPE_FIELD_PRIVATE (type, 0);
4135796c8dcSSimon Schubert     }
4145796c8dcSSimon Schubert 
4155796c8dcSSimon Schubert   i = strlen (name);
4165796c8dcSSimon Schubert   if (i > 2 && name[i - 1] == ']' && tsuper != NULL)
4175796c8dcSSimon Schubert     {
4185796c8dcSSimon Schubert       /* FIXME */
4195796c8dcSSimon Schubert       TYPE_LENGTH (type) = TYPE_LENGTH (tsuper) + 4;   /* size with "length" */
4205796c8dcSSimon Schubert     }
4215796c8dcSSimon Schubert   else
4225796c8dcSSimon Schubert     {
4235796c8dcSSimon Schubert       temp = clas;
424c50c785cSJohn Marino       temp = value_struct_elt (&temp, NULL, "size_in_bytes",
425c50c785cSJohn Marino 			       NULL, "structure");
4265796c8dcSSimon Schubert       TYPE_LENGTH (type) = value_as_long (temp);
4275796c8dcSSimon Schubert     }
4285796c8dcSSimon Schubert 
4295796c8dcSSimon Schubert   fields = NULL;
4305796c8dcSSimon Schubert   nfields--;			/* First set up dummy "class" field.  */
4315796c8dcSSimon Schubert   SET_FIELD_PHYSADDR (TYPE_FIELD (type, nfields), value_address (clas));
4325796c8dcSSimon Schubert   TYPE_FIELD_NAME (type, nfields) = "class";
4335796c8dcSSimon Schubert   TYPE_FIELD_TYPE (type, nfields) = value_type (clas);
4345796c8dcSSimon Schubert   SET_TYPE_FIELD_PRIVATE (type, nfields);
4355796c8dcSSimon Schubert 
4365796c8dcSSimon Schubert   for (i = TYPE_N_BASECLASSES (type); i < nfields; i++)
4375796c8dcSSimon Schubert     {
4385796c8dcSSimon Schubert       int accflags;
4395796c8dcSSimon Schubert       int boffset;
440cf7f2e2dSJohn Marino 
4415796c8dcSSimon Schubert       if (fields == NULL)
4425796c8dcSSimon Schubert 	{
4435796c8dcSSimon Schubert 	  temp = clas;
4445796c8dcSSimon Schubert 	  fields = value_struct_elt (&temp, NULL, "fields", NULL, "structure");
4455796c8dcSSimon Schubert 	  field = value_ind (fields);
4465796c8dcSSimon Schubert 	}
4475796c8dcSSimon Schubert       else
4485796c8dcSSimon Schubert 	{			/* Re-use field value for next field.  */
4495796c8dcSSimon Schubert 	  CORE_ADDR addr
4505796c8dcSSimon Schubert 	    = value_address (field) + TYPE_LENGTH (value_type (field));
451cf7f2e2dSJohn Marino 
4525796c8dcSSimon Schubert 	  set_value_address (field, addr);
4535796c8dcSSimon Schubert 	  set_value_lazy (field, 1);
4545796c8dcSSimon Schubert 	}
4555796c8dcSSimon Schubert       temp = field;
4565796c8dcSSimon Schubert       temp = value_struct_elt (&temp, NULL, "name", NULL, "structure");
4575796c8dcSSimon Schubert       TYPE_FIELD_NAME (type, i) =
4585796c8dcSSimon Schubert 	get_java_utf8_name (&objfile->objfile_obstack, temp);
4595796c8dcSSimon Schubert       temp = field;
4605796c8dcSSimon Schubert       accflags = value_as_long (value_struct_elt (&temp, NULL, "accflags",
4615796c8dcSSimon Schubert 						  NULL, "structure"));
4625796c8dcSSimon Schubert       temp = field;
4635796c8dcSSimon Schubert       temp = value_struct_elt (&temp, NULL, "info", NULL, "structure");
4645796c8dcSSimon Schubert       boffset = value_as_long (value_struct_elt (&temp, NULL, "boffset",
4655796c8dcSSimon Schubert 						 NULL, "structure"));
4665796c8dcSSimon Schubert       if (accflags & 0x0001)	/* public access */
4675796c8dcSSimon Schubert 	{
4685796c8dcSSimon Schubert 	  /* ??? */
4695796c8dcSSimon Schubert 	}
4705796c8dcSSimon Schubert       if (accflags & 0x0002)	/* private access */
4715796c8dcSSimon Schubert 	{
4725796c8dcSSimon Schubert 	  SET_TYPE_FIELD_PRIVATE (type, i);
4735796c8dcSSimon Schubert 	}
4745796c8dcSSimon Schubert       if (accflags & 0x0004)	/* protected access */
4755796c8dcSSimon Schubert 	{
4765796c8dcSSimon Schubert 	  SET_TYPE_FIELD_PROTECTED (type, i);
4775796c8dcSSimon Schubert 	}
4785796c8dcSSimon Schubert       if (accflags & 0x0008)	/* ACC_STATIC */
4795796c8dcSSimon Schubert 	SET_FIELD_PHYSADDR (TYPE_FIELD (type, i), boffset);
4805796c8dcSSimon Schubert       else
481*ef5ccd6cSJohn Marino 	SET_FIELD_BITPOS (TYPE_FIELD (type, i), 8 * boffset);
4825796c8dcSSimon Schubert       if (accflags & 0x8000)	/* FIELD_UNRESOLVED_FLAG */
4835796c8dcSSimon Schubert 	{
4845796c8dcSSimon Schubert 	  TYPE_FIELD_TYPE (type, i) = get_java_object_type ();	/* FIXME */
4855796c8dcSSimon Schubert 	}
4865796c8dcSSimon Schubert       else
4875796c8dcSSimon Schubert 	{
4885796c8dcSSimon Schubert 	  struct type *ftype;
489cf7f2e2dSJohn Marino 
4905796c8dcSSimon Schubert 	  temp = field;
4915796c8dcSSimon Schubert 	  temp = value_struct_elt (&temp, NULL, "type", NULL, "structure");
4925796c8dcSSimon Schubert 	  ftype = type_from_class (gdbarch, temp);
4935796c8dcSSimon Schubert 	  if (TYPE_CODE (ftype) == TYPE_CODE_STRUCT)
4945796c8dcSSimon Schubert 	    ftype = lookup_pointer_type (ftype);
4955796c8dcSSimon Schubert 	  TYPE_FIELD_TYPE (type, i) = ftype;
4965796c8dcSSimon Schubert 	}
4975796c8dcSSimon Schubert     }
4985796c8dcSSimon Schubert 
4995796c8dcSSimon Schubert   temp = clas;
5005796c8dcSSimon Schubert   nmethods = value_as_long (value_struct_elt (&temp, NULL, "method_count",
5015796c8dcSSimon Schubert 					      NULL, "structure"));
5025796c8dcSSimon Schubert   j = nmethods * sizeof (struct fn_field);
5035796c8dcSSimon Schubert   fn_fields = (struct fn_field *)
504a45ae5f8SJohn Marino     obstack_alloc (&objfile->objfile_obstack, j);
5055796c8dcSSimon Schubert   memset (fn_fields, 0, j);
5065796c8dcSSimon Schubert   fn_fieldlists = (struct fn_fieldlist *)
5075796c8dcSSimon Schubert     alloca (nmethods * sizeof (struct fn_fieldlist));
5085796c8dcSSimon Schubert 
5095796c8dcSSimon Schubert   methods = NULL;
5105796c8dcSSimon Schubert   for (i = 0; i < nmethods; i++)
5115796c8dcSSimon Schubert     {
512*ef5ccd6cSJohn Marino       const char *mname;
5135796c8dcSSimon Schubert       int k;
514cf7f2e2dSJohn Marino 
5155796c8dcSSimon Schubert       if (methods == NULL)
5165796c8dcSSimon Schubert 	{
5175796c8dcSSimon Schubert 	  temp = clas;
518c50c785cSJohn Marino 	  methods = value_struct_elt (&temp, NULL, "methods",
519c50c785cSJohn Marino 				      NULL, "structure");
5205796c8dcSSimon Schubert 	  method = value_ind (methods);
5215796c8dcSSimon Schubert 	}
5225796c8dcSSimon Schubert       else
5235796c8dcSSimon Schubert 	{			/* Re-use method value for next method.  */
5245796c8dcSSimon Schubert 	  CORE_ADDR addr
5255796c8dcSSimon Schubert 	    = value_address (method) + TYPE_LENGTH (value_type (method));
526cf7f2e2dSJohn Marino 
5275796c8dcSSimon Schubert 	  set_value_address (method, addr);
5285796c8dcSSimon Schubert 	  set_value_lazy (method, 1);
5295796c8dcSSimon Schubert 	}
5305796c8dcSSimon Schubert 
5315796c8dcSSimon Schubert       /* Get method name.  */
5325796c8dcSSimon Schubert       temp = method;
5335796c8dcSSimon Schubert       temp = value_struct_elt (&temp, NULL, "name", NULL, "structure");
5345796c8dcSSimon Schubert       mname = get_java_utf8_name (&objfile->objfile_obstack, temp);
5355796c8dcSSimon Schubert       if (strcmp (mname, "<init>") == 0)
5365796c8dcSSimon Schubert 	mname = unqualified_name;
5375796c8dcSSimon Schubert 
5385796c8dcSSimon Schubert       /* Check for an existing method with the same name.
5395796c8dcSSimon Schubert        * This makes building the fn_fieldslists an O(nmethods**2)
5405796c8dcSSimon Schubert        * operation.  That could be using hashing, but I doubt it
5415796c8dcSSimon Schubert        * is worth it.  Note that we do maintain the order of methods
5425796c8dcSSimon Schubert        * in the inferior's Method table (as long as that is grouped
5435796c8dcSSimon Schubert        * by method name), which I think is desirable.  --PB */
5445796c8dcSSimon Schubert       for (k = 0, j = TYPE_NFN_FIELDS (type);;)
5455796c8dcSSimon Schubert 	{
5465796c8dcSSimon Schubert 	  if (--j < 0)
5475796c8dcSSimon Schubert 	    {			/* No match - new method name.  */
5485796c8dcSSimon Schubert 	      j = TYPE_NFN_FIELDS (type)++;
5495796c8dcSSimon Schubert 	      fn_fieldlists[j].name = mname;
5505796c8dcSSimon Schubert 	      fn_fieldlists[j].length = 1;
5515796c8dcSSimon Schubert 	      fn_fieldlists[j].fn_fields = &fn_fields[i];
5525796c8dcSSimon Schubert 	      k = i;
5535796c8dcSSimon Schubert 	      break;
5545796c8dcSSimon Schubert 	    }
5555796c8dcSSimon Schubert 	  if (strcmp (mname, fn_fieldlists[j].name) == 0)
5565796c8dcSSimon Schubert 	    {		/* Found an existing method with the same name.  */
5575796c8dcSSimon Schubert 	      int l;
558cf7f2e2dSJohn Marino 
5595796c8dcSSimon Schubert 	      if (mname != unqualified_name)
5605796c8dcSSimon Schubert 		obstack_free (&objfile->objfile_obstack, mname);
5615796c8dcSSimon Schubert 	      mname = fn_fieldlists[j].name;
5625796c8dcSSimon Schubert 	      fn_fieldlists[j].length++;
5635796c8dcSSimon Schubert 	      k = i - k;	/* Index of new slot.  */
5645796c8dcSSimon Schubert 	      /* Shift intervening fn_fields (between k and i) down.  */
5655796c8dcSSimon Schubert 	      for (l = i; l > k; l--)
5665796c8dcSSimon Schubert 		fn_fields[l] = fn_fields[l - 1];
5675796c8dcSSimon Schubert 	      for (l = TYPE_NFN_FIELDS (type); --l > j;)
5685796c8dcSSimon Schubert 		fn_fieldlists[l].fn_fields++;
5695796c8dcSSimon Schubert 	      break;
5705796c8dcSSimon Schubert 	    }
5715796c8dcSSimon Schubert 	  k += fn_fieldlists[j].length;
5725796c8dcSSimon Schubert 	}
5735796c8dcSSimon Schubert       fn_fields[k].physname = "";
5745796c8dcSSimon Schubert       fn_fields[k].is_stub = 1;
5755796c8dcSSimon Schubert       /* FIXME */
5765796c8dcSSimon Schubert       fn_fields[k].type = lookup_function_type
5775796c8dcSSimon Schubert 			   (builtin_java_type (gdbarch)->builtin_void);
5785796c8dcSSimon Schubert       TYPE_CODE (fn_fields[k].type) = TYPE_CODE_METHOD;
5795796c8dcSSimon Schubert     }
5805796c8dcSSimon Schubert 
5815796c8dcSSimon Schubert   j = TYPE_NFN_FIELDS (type) * sizeof (struct fn_fieldlist);
5825796c8dcSSimon Schubert   TYPE_FN_FIELDLISTS (type) = (struct fn_fieldlist *)
583a45ae5f8SJohn Marino     obstack_alloc (&objfile->objfile_obstack, j);
5845796c8dcSSimon Schubert   memcpy (TYPE_FN_FIELDLISTS (type), fn_fieldlists, j);
5855796c8dcSSimon Schubert 
5865796c8dcSSimon Schubert   return type;
5875796c8dcSSimon Schubert }
5885796c8dcSSimon Schubert 
5895796c8dcSSimon Schubert struct type *
get_java_object_type(void)5905796c8dcSSimon Schubert get_java_object_type (void)
5915796c8dcSSimon Schubert {
5925796c8dcSSimon Schubert   struct symbol *sym;
593cf7f2e2dSJohn Marino 
5945796c8dcSSimon Schubert   sym = lookup_symbol ("java.lang.Object", NULL, STRUCT_DOMAIN, NULL);
5955796c8dcSSimon Schubert   if (sym == NULL)
5965796c8dcSSimon Schubert     error (_("cannot find java.lang.Object"));
597a45ae5f8SJohn Marino   return SYMBOL_TYPE (sym);
5985796c8dcSSimon Schubert }
5995796c8dcSSimon Schubert 
6005796c8dcSSimon Schubert int
get_java_object_header_size(struct gdbarch * gdbarch)6015796c8dcSSimon Schubert get_java_object_header_size (struct gdbarch *gdbarch)
6025796c8dcSSimon Schubert {
6035796c8dcSSimon Schubert   struct type *objtype = get_java_object_type ();
604cf7f2e2dSJohn Marino 
6055796c8dcSSimon Schubert   if (objtype == NULL)
6065796c8dcSSimon Schubert     return (2 * gdbarch_ptr_bit (gdbarch) / TARGET_CHAR_BIT);
6075796c8dcSSimon Schubert   else
6085796c8dcSSimon Schubert     return TYPE_LENGTH (objtype);
6095796c8dcSSimon Schubert }
6105796c8dcSSimon Schubert 
6115796c8dcSSimon Schubert int
is_object_type(struct type * type)6125796c8dcSSimon Schubert is_object_type (struct type *type)
6135796c8dcSSimon Schubert {
6145796c8dcSSimon Schubert   CHECK_TYPEDEF (type);
6155796c8dcSSimon Schubert   if (TYPE_CODE (type) == TYPE_CODE_PTR)
6165796c8dcSSimon Schubert     {
6175796c8dcSSimon Schubert       struct type *ttype = check_typedef (TYPE_TARGET_TYPE (type));
618*ef5ccd6cSJohn Marino       const char *name;
6195796c8dcSSimon Schubert       if (TYPE_CODE (ttype) != TYPE_CODE_STRUCT)
6205796c8dcSSimon Schubert 	return 0;
6215796c8dcSSimon Schubert       while (TYPE_N_BASECLASSES (ttype) > 0)
6225796c8dcSSimon Schubert 	ttype = TYPE_BASECLASS (ttype, 0);
6235796c8dcSSimon Schubert       name = TYPE_TAG_NAME (ttype);
6245796c8dcSSimon Schubert       if (name != NULL && strcmp (name, "java.lang.Object") == 0)
6255796c8dcSSimon Schubert 	return 1;
626c50c785cSJohn Marino       name
627c50c785cSJohn Marino 	= TYPE_NFIELDS (ttype) > 0 ? TYPE_FIELD_NAME (ttype, 0) : (char *) 0;
6285796c8dcSSimon Schubert       if (name != NULL && strcmp (name, "vtable") == 0)
6295796c8dcSSimon Schubert 	return 1;
6305796c8dcSSimon Schubert     }
6315796c8dcSSimon Schubert   return 0;
6325796c8dcSSimon Schubert }
6335796c8dcSSimon Schubert 
6345796c8dcSSimon Schubert struct type *
java_primitive_type(struct gdbarch * gdbarch,int signature)6355796c8dcSSimon Schubert java_primitive_type (struct gdbarch *gdbarch, int signature)
6365796c8dcSSimon Schubert {
6375796c8dcSSimon Schubert   const struct builtin_java_type *builtin = builtin_java_type (gdbarch);
6385796c8dcSSimon Schubert 
6395796c8dcSSimon Schubert   switch (signature)
6405796c8dcSSimon Schubert     {
6415796c8dcSSimon Schubert     case 'B':
6425796c8dcSSimon Schubert       return builtin->builtin_byte;
6435796c8dcSSimon Schubert     case 'S':
6445796c8dcSSimon Schubert       return builtin->builtin_short;
6455796c8dcSSimon Schubert     case 'I':
6465796c8dcSSimon Schubert       return builtin->builtin_int;
6475796c8dcSSimon Schubert     case 'J':
6485796c8dcSSimon Schubert       return builtin->builtin_long;
6495796c8dcSSimon Schubert     case 'Z':
6505796c8dcSSimon Schubert       return builtin->builtin_boolean;
6515796c8dcSSimon Schubert     case 'C':
6525796c8dcSSimon Schubert       return builtin->builtin_char;
6535796c8dcSSimon Schubert     case 'F':
6545796c8dcSSimon Schubert       return builtin->builtin_float;
6555796c8dcSSimon Schubert     case 'D':
6565796c8dcSSimon Schubert       return builtin->builtin_double;
6575796c8dcSSimon Schubert     case 'V':
6585796c8dcSSimon Schubert       return builtin->builtin_void;
6595796c8dcSSimon Schubert     }
6605796c8dcSSimon Schubert   error (_("unknown signature '%c' for primitive type"), (char) signature);
6615796c8dcSSimon Schubert }
6625796c8dcSSimon Schubert 
6635796c8dcSSimon Schubert /* If name[0 .. namelen-1] is the name of a primitive Java type,
6645796c8dcSSimon Schubert    return that type.  Otherwise, return NULL.  */
6655796c8dcSSimon Schubert 
6665796c8dcSSimon Schubert struct type *
java_primitive_type_from_name(struct gdbarch * gdbarch,const char * name,int namelen)6675796c8dcSSimon Schubert java_primitive_type_from_name (struct gdbarch *gdbarch,
668*ef5ccd6cSJohn Marino 			       const char *name, int namelen)
6695796c8dcSSimon Schubert {
6705796c8dcSSimon Schubert   const struct builtin_java_type *builtin = builtin_java_type (gdbarch);
6715796c8dcSSimon Schubert 
6725796c8dcSSimon Schubert   switch (name[0])
6735796c8dcSSimon Schubert     {
6745796c8dcSSimon Schubert     case 'b':
6755796c8dcSSimon Schubert       if (namelen == 4 && memcmp (name, "byte", 4) == 0)
6765796c8dcSSimon Schubert 	return builtin->builtin_byte;
6775796c8dcSSimon Schubert       if (namelen == 7 && memcmp (name, "boolean", 7) == 0)
6785796c8dcSSimon Schubert 	return builtin->builtin_boolean;
6795796c8dcSSimon Schubert       break;
6805796c8dcSSimon Schubert     case 'c':
6815796c8dcSSimon Schubert       if (namelen == 4 && memcmp (name, "char", 4) == 0)
6825796c8dcSSimon Schubert 	return builtin->builtin_char;
683c50c785cSJohn Marino       break;
6845796c8dcSSimon Schubert     case 'd':
6855796c8dcSSimon Schubert       if (namelen == 6 && memcmp (name, "double", 6) == 0)
6865796c8dcSSimon Schubert 	return builtin->builtin_double;
6875796c8dcSSimon Schubert       break;
6885796c8dcSSimon Schubert     case 'f':
6895796c8dcSSimon Schubert       if (namelen == 5 && memcmp (name, "float", 5) == 0)
6905796c8dcSSimon Schubert 	return builtin->builtin_float;
6915796c8dcSSimon Schubert       break;
6925796c8dcSSimon Schubert     case 'i':
6935796c8dcSSimon Schubert       if (namelen == 3 && memcmp (name, "int", 3) == 0)
6945796c8dcSSimon Schubert 	return builtin->builtin_int;
6955796c8dcSSimon Schubert       break;
6965796c8dcSSimon Schubert     case 'l':
6975796c8dcSSimon Schubert       if (namelen == 4 && memcmp (name, "long", 4) == 0)
6985796c8dcSSimon Schubert 	return builtin->builtin_long;
6995796c8dcSSimon Schubert       break;
7005796c8dcSSimon Schubert     case 's':
7015796c8dcSSimon Schubert       if (namelen == 5 && memcmp (name, "short", 5) == 0)
7025796c8dcSSimon Schubert 	return builtin->builtin_short;
7035796c8dcSSimon Schubert       break;
7045796c8dcSSimon Schubert     case 'v':
7055796c8dcSSimon Schubert       if (namelen == 4 && memcmp (name, "void", 4) == 0)
7065796c8dcSSimon Schubert 	return builtin->builtin_void;
7075796c8dcSSimon Schubert       break;
7085796c8dcSSimon Schubert     }
7095796c8dcSSimon Schubert   return NULL;
7105796c8dcSSimon Schubert }
7115796c8dcSSimon Schubert 
7125796c8dcSSimon Schubert static char *
java_primitive_type_name(int signature)7135796c8dcSSimon Schubert java_primitive_type_name (int signature)
7145796c8dcSSimon Schubert {
7155796c8dcSSimon Schubert   switch (signature)
7165796c8dcSSimon Schubert     {
7175796c8dcSSimon Schubert     case 'B':
7185796c8dcSSimon Schubert       return "byte";
7195796c8dcSSimon Schubert     case 'S':
7205796c8dcSSimon Schubert       return "short";
7215796c8dcSSimon Schubert     case 'I':
7225796c8dcSSimon Schubert       return "int";
7235796c8dcSSimon Schubert     case 'J':
7245796c8dcSSimon Schubert       return "long";
7255796c8dcSSimon Schubert     case 'Z':
7265796c8dcSSimon Schubert       return "boolean";
7275796c8dcSSimon Schubert     case 'C':
7285796c8dcSSimon Schubert       return "char";
7295796c8dcSSimon Schubert     case 'F':
7305796c8dcSSimon Schubert       return "float";
7315796c8dcSSimon Schubert     case 'D':
7325796c8dcSSimon Schubert       return "double";
7335796c8dcSSimon Schubert     case 'V':
7345796c8dcSSimon Schubert       return "void";
7355796c8dcSSimon Schubert     }
7365796c8dcSSimon Schubert   error (_("unknown signature '%c' for primitive type"), (char) signature);
7375796c8dcSSimon Schubert }
7385796c8dcSSimon Schubert 
7395796c8dcSSimon Schubert /* Return the length (in bytes) of demangled name of the Java type
7405796c8dcSSimon Schubert    signature string SIGNATURE.  */
7415796c8dcSSimon Schubert 
7425796c8dcSSimon Schubert static int
java_demangled_signature_length(const char * signature)743*ef5ccd6cSJohn Marino java_demangled_signature_length (const char *signature)
7445796c8dcSSimon Schubert {
7455796c8dcSSimon Schubert   int array = 0;
746cf7f2e2dSJohn Marino 
7475796c8dcSSimon Schubert   for (; *signature == '['; signature++)
7485796c8dcSSimon Schubert     array += 2;			/* Two chars for "[]".  */
7495796c8dcSSimon Schubert   switch (signature[0])
7505796c8dcSSimon Schubert     {
7515796c8dcSSimon Schubert     case 'L':
7525796c8dcSSimon Schubert       /* Subtract 2 for 'L' and ';'.  */
7535796c8dcSSimon Schubert       return strlen (signature) - 2 + array;
7545796c8dcSSimon Schubert     default:
7555796c8dcSSimon Schubert       return strlen (java_primitive_type_name (signature[0])) + array;
7565796c8dcSSimon Schubert     }
7575796c8dcSSimon Schubert }
7585796c8dcSSimon Schubert 
759c50c785cSJohn Marino /* Demangle the Java type signature SIGNATURE, leaving the result in
760c50c785cSJohn Marino    RESULT.  */
7615796c8dcSSimon Schubert 
7625796c8dcSSimon Schubert static void
java_demangled_signature_copy(char * result,const char * signature)763*ef5ccd6cSJohn Marino java_demangled_signature_copy (char *result, const char *signature)
7645796c8dcSSimon Schubert {
7655796c8dcSSimon Schubert   int array = 0;
7665796c8dcSSimon Schubert   char *ptr;
7675796c8dcSSimon Schubert   int i;
768cf7f2e2dSJohn Marino 
7695796c8dcSSimon Schubert   while (*signature == '[')
7705796c8dcSSimon Schubert     {
7715796c8dcSSimon Schubert       array++;
7725796c8dcSSimon Schubert       signature++;
7735796c8dcSSimon Schubert     }
7745796c8dcSSimon Schubert   switch (signature[0])
7755796c8dcSSimon Schubert     {
7765796c8dcSSimon Schubert     case 'L':
7775796c8dcSSimon Schubert       /* Subtract 2 for 'L' and ';', but add 1 for final nul.  */
7785796c8dcSSimon Schubert       signature++;
7795796c8dcSSimon Schubert       ptr = result;
7805796c8dcSSimon Schubert       for (; *signature != ';' && *signature != '\0'; signature++)
7815796c8dcSSimon Schubert 	{
7825796c8dcSSimon Schubert 	  if (*signature == '/')
7835796c8dcSSimon Schubert 	    *ptr++ = '.';
7845796c8dcSSimon Schubert 	  else
7855796c8dcSSimon Schubert 	    *ptr++ = *signature;
7865796c8dcSSimon Schubert 	}
7875796c8dcSSimon Schubert       break;
7885796c8dcSSimon Schubert     default:
7895796c8dcSSimon Schubert       ptr = java_primitive_type_name (signature[0]);
7905796c8dcSSimon Schubert       i = strlen (ptr);
7915796c8dcSSimon Schubert       strcpy (result, ptr);
7925796c8dcSSimon Schubert       ptr = result + i;
7935796c8dcSSimon Schubert       break;
7945796c8dcSSimon Schubert     }
7955796c8dcSSimon Schubert   while (--array >= 0)
7965796c8dcSSimon Schubert     {
7975796c8dcSSimon Schubert       *ptr++ = '[';
7985796c8dcSSimon Schubert       *ptr++ = ']';
7995796c8dcSSimon Schubert     }
8005796c8dcSSimon Schubert }
8015796c8dcSSimon Schubert 
8025796c8dcSSimon Schubert /* Return the demangled name of the Java type signature string SIGNATURE,
8035796c8dcSSimon Schubert    as a freshly allocated copy.  */
8045796c8dcSSimon Schubert 
8055796c8dcSSimon Schubert char *
java_demangle_type_signature(const char * signature)806*ef5ccd6cSJohn Marino java_demangle_type_signature (const char *signature)
8075796c8dcSSimon Schubert {
8085796c8dcSSimon Schubert   int length = java_demangled_signature_length (signature);
8095796c8dcSSimon Schubert   char *result = xmalloc (length + 1);
810cf7f2e2dSJohn Marino 
8115796c8dcSSimon Schubert   java_demangled_signature_copy (result, signature);
8125796c8dcSSimon Schubert   result[length] = '\0';
8135796c8dcSSimon Schubert   return result;
8145796c8dcSSimon Schubert }
8155796c8dcSSimon Schubert 
8165796c8dcSSimon Schubert /* Return the type of TYPE followed by DIMS pairs of [ ].
8175796c8dcSSimon Schubert    If DIMS == 0, TYPE is returned.  */
8185796c8dcSSimon Schubert 
8195796c8dcSSimon Schubert struct type *
java_array_type(struct type * type,int dims)8205796c8dcSSimon Schubert java_array_type (struct type *type, int dims)
8215796c8dcSSimon Schubert {
8225796c8dcSSimon Schubert   while (dims-- > 0)
8235796c8dcSSimon Schubert     {
8245796c8dcSSimon Schubert       /* FIXME  This is bogus!  Java arrays are not gdb arrays!  */
8255796c8dcSSimon Schubert       type = lookup_array_range_type (type, 0, 0);
8265796c8dcSSimon Schubert     }
8275796c8dcSSimon Schubert 
8285796c8dcSSimon Schubert   return type;
8295796c8dcSSimon Schubert }
8305796c8dcSSimon Schubert 
8315796c8dcSSimon Schubert /* Create a Java string in the inferior from a (Utf8) literal.  */
8325796c8dcSSimon Schubert 
8335796c8dcSSimon Schubert static struct value *
java_value_string(char * ptr,int len)8345796c8dcSSimon Schubert java_value_string (char *ptr, int len)
8355796c8dcSSimon Schubert {
8365796c8dcSSimon Schubert   error (_("not implemented - java_value_string"));	/* FIXME */
8375796c8dcSSimon Schubert }
8385796c8dcSSimon Schubert 
839a45ae5f8SJohn Marino /* Return the encoding that should be used for the character type
840a45ae5f8SJohn Marino    TYPE.  */
841a45ae5f8SJohn Marino 
842a45ae5f8SJohn Marino static const char *
java_get_encoding(struct type * type)843a45ae5f8SJohn Marino java_get_encoding (struct type *type)
844a45ae5f8SJohn Marino {
845a45ae5f8SJohn Marino   struct gdbarch *arch = get_type_arch (type);
846a45ae5f8SJohn Marino   const char *encoding;
847a45ae5f8SJohn Marino 
848a45ae5f8SJohn Marino   if (type == builtin_java_type (arch)->builtin_char)
849a45ae5f8SJohn Marino     {
850a45ae5f8SJohn Marino       if (gdbarch_byte_order (arch) == BFD_ENDIAN_BIG)
851a45ae5f8SJohn Marino 	encoding = "UTF-16BE";
852a45ae5f8SJohn Marino       else
853a45ae5f8SJohn Marino 	encoding = "UTF-16LE";
854a45ae5f8SJohn Marino     }
855a45ae5f8SJohn Marino   else
856a45ae5f8SJohn Marino     encoding = target_charset (arch);
857a45ae5f8SJohn Marino 
858a45ae5f8SJohn Marino   return encoding;
859a45ae5f8SJohn Marino }
860a45ae5f8SJohn Marino 
8615796c8dcSSimon Schubert /* Print the character C on STREAM as part of the contents of a literal
8625796c8dcSSimon Schubert    string whose delimiter is QUOTER.  Note that that format for printing
8635796c8dcSSimon Schubert    characters and strings is language specific.  */
8645796c8dcSSimon Schubert 
8655796c8dcSSimon Schubert static void
java_emit_char(int c,struct type * type,struct ui_file * stream,int quoter)8665796c8dcSSimon Schubert java_emit_char (int c, struct type *type, struct ui_file *stream, int quoter)
8675796c8dcSSimon Schubert {
868a45ae5f8SJohn Marino   const char *encoding = java_get_encoding (type);
869a45ae5f8SJohn Marino 
870a45ae5f8SJohn Marino   generic_emit_char (c, type, stream, quoter, encoding);
8715796c8dcSSimon Schubert }
872a45ae5f8SJohn Marino 
873a45ae5f8SJohn Marino /* Implementation of la_printchar method.  */
874a45ae5f8SJohn Marino 
875a45ae5f8SJohn Marino static void
java_printchar(int c,struct type * type,struct ui_file * stream)876a45ae5f8SJohn Marino java_printchar (int c, struct type *type, struct ui_file *stream)
877a45ae5f8SJohn Marino {
878a45ae5f8SJohn Marino   fputs_filtered ("'", stream);
879a45ae5f8SJohn Marino   LA_EMIT_CHAR (c, type, stream, '\'');
880a45ae5f8SJohn Marino   fputs_filtered ("'", stream);
881a45ae5f8SJohn Marino }
882a45ae5f8SJohn Marino 
883a45ae5f8SJohn Marino /* Implementation of la_printstr method.  */
884a45ae5f8SJohn Marino 
885a45ae5f8SJohn Marino static void
java_printstr(struct ui_file * stream,struct type * type,const gdb_byte * string,unsigned int length,const char * encoding,int force_ellipses,const struct value_print_options * options)886a45ae5f8SJohn Marino java_printstr (struct ui_file *stream, struct type *type,
887a45ae5f8SJohn Marino 	       const gdb_byte *string,
888a45ae5f8SJohn Marino 	       unsigned int length, const char *encoding, int force_ellipses,
889a45ae5f8SJohn Marino 	       const struct value_print_options *options)
890a45ae5f8SJohn Marino {
891a45ae5f8SJohn Marino   const char *type_encoding = java_get_encoding (type);
892a45ae5f8SJohn Marino 
893a45ae5f8SJohn Marino   if (!encoding || !*encoding)
894a45ae5f8SJohn Marino     encoding = type_encoding;
895a45ae5f8SJohn Marino 
896a45ae5f8SJohn Marino   generic_printstr (stream, type, string, length, encoding,
897a45ae5f8SJohn Marino 		    force_ellipses, '"', 0, options);
8985796c8dcSSimon Schubert }
8995796c8dcSSimon Schubert 
9005796c8dcSSimon Schubert static struct value *
evaluate_subexp_java(struct type * expect_type,struct expression * exp,int * pos,enum noside noside)9015796c8dcSSimon Schubert evaluate_subexp_java (struct type *expect_type, struct expression *exp,
9025796c8dcSSimon Schubert 		      int *pos, enum noside noside)
9035796c8dcSSimon Schubert {
9045796c8dcSSimon Schubert   int pc = *pos;
9055796c8dcSSimon Schubert   int i;
906*ef5ccd6cSJohn Marino   const char *name;
9075796c8dcSSimon Schubert   enum exp_opcode op = exp->elts[*pos].opcode;
9085796c8dcSSimon Schubert   struct value *arg1;
9095796c8dcSSimon Schubert   struct value *arg2;
9105796c8dcSSimon Schubert   struct type *type;
911cf7f2e2dSJohn Marino 
9125796c8dcSSimon Schubert   switch (op)
9135796c8dcSSimon Schubert     {
9145796c8dcSSimon Schubert     case UNOP_IND:
9155796c8dcSSimon Schubert       if (noside == EVAL_SKIP)
9165796c8dcSSimon Schubert 	goto standard;
9175796c8dcSSimon Schubert       (*pos)++;
9185796c8dcSSimon Schubert       arg1 = evaluate_subexp_java (NULL_TYPE, exp, pos, EVAL_NORMAL);
9195796c8dcSSimon Schubert       if (is_object_type (value_type (arg1)))
9205796c8dcSSimon Schubert 	{
9215796c8dcSSimon Schubert 	  struct type *type;
9225796c8dcSSimon Schubert 
9235796c8dcSSimon Schubert 	  type = type_from_class (exp->gdbarch, java_class_from_object (arg1));
9245796c8dcSSimon Schubert 	  arg1 = value_cast (lookup_pointer_type (type), arg1);
9255796c8dcSSimon Schubert 	}
9265796c8dcSSimon Schubert       return value_ind (arg1);
9275796c8dcSSimon Schubert 
9285796c8dcSSimon Schubert     case BINOP_SUBSCRIPT:
9295796c8dcSSimon Schubert       (*pos)++;
9305796c8dcSSimon Schubert       arg1 = evaluate_subexp_with_coercion (exp, pos, noside);
9315796c8dcSSimon Schubert       arg2 = evaluate_subexp_with_coercion (exp, pos, noside);
9325796c8dcSSimon Schubert       if (noside == EVAL_SKIP)
9335796c8dcSSimon Schubert 	goto nosideret;
9345796c8dcSSimon Schubert       /* If the user attempts to subscript something that is not an
9355796c8dcSSimon Schubert          array or pointer type (like a plain int variable for example),
9365796c8dcSSimon Schubert          then report this as an error.  */
9375796c8dcSSimon Schubert 
9385796c8dcSSimon Schubert       arg1 = coerce_ref (arg1);
9395796c8dcSSimon Schubert       type = check_typedef (value_type (arg1));
9405796c8dcSSimon Schubert       if (TYPE_CODE (type) == TYPE_CODE_PTR)
9415796c8dcSSimon Schubert 	type = check_typedef (TYPE_TARGET_TYPE (type));
9425796c8dcSSimon Schubert       name = TYPE_NAME (type);
9435796c8dcSSimon Schubert       if (name == NULL)
9445796c8dcSSimon Schubert 	name = TYPE_TAG_NAME (type);
9455796c8dcSSimon Schubert       i = name == NULL ? 0 : strlen (name);
9465796c8dcSSimon Schubert       if (TYPE_CODE (type) == TYPE_CODE_STRUCT
9475796c8dcSSimon Schubert 	  && i > 2 && name[i - 1] == ']')
9485796c8dcSSimon Schubert 	{
9495796c8dcSSimon Schubert 	  enum bfd_endian byte_order = gdbarch_byte_order (exp->gdbarch);
9505796c8dcSSimon Schubert 	  CORE_ADDR address;
9515796c8dcSSimon Schubert 	  long length, index;
9525796c8dcSSimon Schubert 	  struct type *el_type;
9535796c8dcSSimon Schubert 	  gdb_byte buf4[4];
9545796c8dcSSimon Schubert 
9555796c8dcSSimon Schubert 	  struct value *clas = java_class_from_object (arg1);
9565796c8dcSSimon Schubert 	  struct value *temp = clas;
9575796c8dcSSimon Schubert 	  /* Get CLASS_ELEMENT_TYPE of the array type.  */
9585796c8dcSSimon Schubert 	  temp = value_struct_elt (&temp, NULL, "methods",
9595796c8dcSSimon Schubert 				   NULL, "structure");
9605796c8dcSSimon Schubert 	  deprecated_set_value_type (temp, value_type (clas));
9615796c8dcSSimon Schubert 	  el_type = type_from_class (exp->gdbarch, temp);
9625796c8dcSSimon Schubert 	  if (TYPE_CODE (el_type) == TYPE_CODE_STRUCT)
9635796c8dcSSimon Schubert 	    el_type = lookup_pointer_type (el_type);
9645796c8dcSSimon Schubert 
9655796c8dcSSimon Schubert 	  if (noside == EVAL_AVOID_SIDE_EFFECTS)
9665796c8dcSSimon Schubert 	    return value_zero (el_type, VALUE_LVAL (arg1));
9675796c8dcSSimon Schubert 	  address = value_as_address (arg1);
9685796c8dcSSimon Schubert 	  address += get_java_object_header_size (exp->gdbarch);
9695796c8dcSSimon Schubert 	  read_memory (address, buf4, 4);
9705796c8dcSSimon Schubert 	  length = (long) extract_signed_integer (buf4, 4, byte_order);
9715796c8dcSSimon Schubert 	  index = (long) value_as_long (arg2);
9725796c8dcSSimon Schubert 	  if (index >= length || index < 0)
9735796c8dcSSimon Schubert 	    error (_("array index (%ld) out of bounds (length: %ld)"),
9745796c8dcSSimon Schubert 		   index, length);
9755796c8dcSSimon Schubert 	  address = (address + 4) + index * TYPE_LENGTH (el_type);
9765796c8dcSSimon Schubert 	  return value_at (el_type, address);
9775796c8dcSSimon Schubert 	}
9785796c8dcSSimon Schubert       else if (TYPE_CODE (type) == TYPE_CODE_ARRAY)
9795796c8dcSSimon Schubert 	{
9805796c8dcSSimon Schubert 	  if (noside == EVAL_AVOID_SIDE_EFFECTS)
9815796c8dcSSimon Schubert 	    return value_zero (TYPE_TARGET_TYPE (type), VALUE_LVAL (arg1));
9825796c8dcSSimon Schubert 	  else
9835796c8dcSSimon Schubert 	    return value_subscript (arg1, value_as_long (arg2));
9845796c8dcSSimon Schubert 	}
9855796c8dcSSimon Schubert       if (name)
9865796c8dcSSimon Schubert 	error (_("cannot subscript something of type `%s'"), name);
9875796c8dcSSimon Schubert       else
9885796c8dcSSimon Schubert 	error (_("cannot subscript requested type"));
9895796c8dcSSimon Schubert 
9905796c8dcSSimon Schubert     case OP_STRING:
9915796c8dcSSimon Schubert       (*pos)++;
9925796c8dcSSimon Schubert       i = longest_to_int (exp->elts[pc + 1].longconst);
9935796c8dcSSimon Schubert       (*pos) += 3 + BYTES_TO_EXP_ELEM (i + 1);
9945796c8dcSSimon Schubert       if (noside == EVAL_SKIP)
9955796c8dcSSimon Schubert 	goto nosideret;
9965796c8dcSSimon Schubert       return java_value_string (&exp->elts[pc + 2].string, i);
9975796c8dcSSimon Schubert 
9985796c8dcSSimon Schubert     case STRUCTOP_PTR:
9995796c8dcSSimon Schubert       arg1 = evaluate_subexp_standard (expect_type, exp, pos, noside);
10005796c8dcSSimon Schubert       /* Convert object field (such as TYPE.class) to reference.  */
10015796c8dcSSimon Schubert       if (TYPE_CODE (value_type (arg1)) == TYPE_CODE_STRUCT)
10025796c8dcSSimon Schubert 	arg1 = value_addr (arg1);
10035796c8dcSSimon Schubert       return arg1;
10045796c8dcSSimon Schubert     default:
10055796c8dcSSimon Schubert       break;
10065796c8dcSSimon Schubert     }
10075796c8dcSSimon Schubert standard:
10085796c8dcSSimon Schubert   return evaluate_subexp_standard (expect_type, exp, pos, noside);
10095796c8dcSSimon Schubert nosideret:
10105796c8dcSSimon Schubert   return value_from_longest (builtin_type (exp->gdbarch)->builtin_int, 1);
10115796c8dcSSimon Schubert }
10125796c8dcSSimon Schubert 
java_demangle(const char * mangled,int options)10135796c8dcSSimon Schubert static char *java_demangle (const char *mangled, int options)
10145796c8dcSSimon Schubert {
10155796c8dcSSimon Schubert   return cplus_demangle (mangled, options | DMGL_JAVA);
10165796c8dcSSimon Schubert }
10175796c8dcSSimon Schubert 
10185796c8dcSSimon Schubert /* Find the member function name of the demangled name NAME.  NAME
10195796c8dcSSimon Schubert    must be a method name including arguments, in order to correctly
10205796c8dcSSimon Schubert    locate the last component.
10215796c8dcSSimon Schubert 
10225796c8dcSSimon Schubert    This function return a pointer to the first dot before the
10235796c8dcSSimon Schubert    member function name, or NULL if the name was not of the
10245796c8dcSSimon Schubert    expected form.  */
10255796c8dcSSimon Schubert 
10265796c8dcSSimon Schubert static const char *
java_find_last_component(const char * name)10275796c8dcSSimon Schubert java_find_last_component (const char *name)
10285796c8dcSSimon Schubert {
10295796c8dcSSimon Schubert   const char *p;
10305796c8dcSSimon Schubert 
10315796c8dcSSimon Schubert   /* Find argument list.  */
10325796c8dcSSimon Schubert   p = strchr (name, '(');
10335796c8dcSSimon Schubert 
10345796c8dcSSimon Schubert   if (p == NULL)
10355796c8dcSSimon Schubert     return NULL;
10365796c8dcSSimon Schubert 
10375796c8dcSSimon Schubert   /* Back up and find first dot prior to argument list.  */
10385796c8dcSSimon Schubert   while (p > name && *p != '.')
10395796c8dcSSimon Schubert     p--;
10405796c8dcSSimon Schubert 
10415796c8dcSSimon Schubert   if (p == name)
10425796c8dcSSimon Schubert     return NULL;
10435796c8dcSSimon Schubert 
10445796c8dcSSimon Schubert   return p;
10455796c8dcSSimon Schubert }
10465796c8dcSSimon Schubert 
10475796c8dcSSimon Schubert /* Return the name of the class containing method PHYSNAME.  */
10485796c8dcSSimon Schubert 
10495796c8dcSSimon Schubert static char *
java_class_name_from_physname(const char * physname)10505796c8dcSSimon Schubert java_class_name_from_physname (const char *physname)
10515796c8dcSSimon Schubert {
10525796c8dcSSimon Schubert   char *ret = NULL;
10535796c8dcSSimon Schubert   const char *end;
10545796c8dcSSimon Schubert   char *demangled_name = java_demangle (physname, DMGL_PARAMS | DMGL_ANSI);
10555796c8dcSSimon Schubert 
10565796c8dcSSimon Schubert   if (demangled_name == NULL)
10575796c8dcSSimon Schubert     return NULL;
10585796c8dcSSimon Schubert 
10595796c8dcSSimon Schubert   end = java_find_last_component (demangled_name);
10605796c8dcSSimon Schubert   if (end != NULL)
10615796c8dcSSimon Schubert     {
10625796c8dcSSimon Schubert       ret = xmalloc (end - demangled_name + 1);
10635796c8dcSSimon Schubert       memcpy (ret, demangled_name, end - demangled_name);
10645796c8dcSSimon Schubert       ret[end - demangled_name] = '\0';
10655796c8dcSSimon Schubert     }
10665796c8dcSSimon Schubert 
10675796c8dcSSimon Schubert   xfree (demangled_name);
10685796c8dcSSimon Schubert   return ret;
10695796c8dcSSimon Schubert }
10705796c8dcSSimon Schubert 
10715796c8dcSSimon Schubert /* Table mapping opcodes into strings for printing operators
10725796c8dcSSimon Schubert    and precedences of the operators.  */
10735796c8dcSSimon Schubert 
10745796c8dcSSimon Schubert const struct op_print java_op_print_tab[] =
10755796c8dcSSimon Schubert {
10765796c8dcSSimon Schubert   {",", BINOP_COMMA, PREC_COMMA, 0},
10775796c8dcSSimon Schubert   {"=", BINOP_ASSIGN, PREC_ASSIGN, 1},
10785796c8dcSSimon Schubert   {"||", BINOP_LOGICAL_OR, PREC_LOGICAL_OR, 0},
10795796c8dcSSimon Schubert   {"&&", BINOP_LOGICAL_AND, PREC_LOGICAL_AND, 0},
10805796c8dcSSimon Schubert   {"|", BINOP_BITWISE_IOR, PREC_BITWISE_IOR, 0},
10815796c8dcSSimon Schubert   {"^", BINOP_BITWISE_XOR, PREC_BITWISE_XOR, 0},
10825796c8dcSSimon Schubert   {"&", BINOP_BITWISE_AND, PREC_BITWISE_AND, 0},
10835796c8dcSSimon Schubert   {"==", BINOP_EQUAL, PREC_EQUAL, 0},
10845796c8dcSSimon Schubert   {"!=", BINOP_NOTEQUAL, PREC_EQUAL, 0},
10855796c8dcSSimon Schubert   {"<=", BINOP_LEQ, PREC_ORDER, 0},
10865796c8dcSSimon Schubert   {">=", BINOP_GEQ, PREC_ORDER, 0},
10875796c8dcSSimon Schubert   {">", BINOP_GTR, PREC_ORDER, 0},
10885796c8dcSSimon Schubert   {"<", BINOP_LESS, PREC_ORDER, 0},
10895796c8dcSSimon Schubert   {">>", BINOP_RSH, PREC_SHIFT, 0},
10905796c8dcSSimon Schubert   {"<<", BINOP_LSH, PREC_SHIFT, 0},
10915796c8dcSSimon Schubert   {"+", BINOP_ADD, PREC_ADD, 0},
10925796c8dcSSimon Schubert   {"-", BINOP_SUB, PREC_ADD, 0},
10935796c8dcSSimon Schubert   {"*", BINOP_MUL, PREC_MUL, 0},
10945796c8dcSSimon Schubert   {"/", BINOP_DIV, PREC_MUL, 0},
10955796c8dcSSimon Schubert   {"%", BINOP_REM, PREC_MUL, 0},
10965796c8dcSSimon Schubert   {"-", UNOP_NEG, PREC_PREFIX, 0},
10975796c8dcSSimon Schubert   {"!", UNOP_LOGICAL_NOT, PREC_PREFIX, 0},
10985796c8dcSSimon Schubert   {"~", UNOP_COMPLEMENT, PREC_PREFIX, 0},
10995796c8dcSSimon Schubert   {"*", UNOP_IND, PREC_PREFIX, 0},
11005796c8dcSSimon Schubert   {"++", UNOP_PREINCREMENT, PREC_PREFIX, 0},
11015796c8dcSSimon Schubert   {"--", UNOP_PREDECREMENT, PREC_PREFIX, 0},
11025796c8dcSSimon Schubert   {NULL, 0, 0, 0}
11035796c8dcSSimon Schubert };
11045796c8dcSSimon Schubert 
11055796c8dcSSimon Schubert enum java_primitive_types
11065796c8dcSSimon Schubert {
11075796c8dcSSimon Schubert   java_primitive_type_int,
11085796c8dcSSimon Schubert   java_primitive_type_short,
11095796c8dcSSimon Schubert   java_primitive_type_long,
11105796c8dcSSimon Schubert   java_primitive_type_byte,
11115796c8dcSSimon Schubert   java_primitive_type_boolean,
11125796c8dcSSimon Schubert   java_primitive_type_char,
11135796c8dcSSimon Schubert   java_primitive_type_float,
11145796c8dcSSimon Schubert   java_primitive_type_double,
11155796c8dcSSimon Schubert   java_primitive_type_void,
11165796c8dcSSimon Schubert   nr_java_primitive_types
11175796c8dcSSimon Schubert };
11185796c8dcSSimon Schubert 
11195796c8dcSSimon Schubert static void
java_language_arch_info(struct gdbarch * gdbarch,struct language_arch_info * lai)11205796c8dcSSimon Schubert java_language_arch_info (struct gdbarch *gdbarch,
11215796c8dcSSimon Schubert 			 struct language_arch_info *lai)
11225796c8dcSSimon Schubert {
11235796c8dcSSimon Schubert   const struct builtin_java_type *builtin = builtin_java_type (gdbarch);
11245796c8dcSSimon Schubert 
11255796c8dcSSimon Schubert   lai->string_char_type = builtin->builtin_char;
11265796c8dcSSimon Schubert   lai->primitive_type_vector
11275796c8dcSSimon Schubert     = GDBARCH_OBSTACK_CALLOC (gdbarch, nr_java_primitive_types + 1,
11285796c8dcSSimon Schubert                               struct type *);
11295796c8dcSSimon Schubert   lai->primitive_type_vector [java_primitive_type_int]
11305796c8dcSSimon Schubert     = builtin->builtin_int;
11315796c8dcSSimon Schubert   lai->primitive_type_vector [java_primitive_type_short]
11325796c8dcSSimon Schubert     = builtin->builtin_short;
11335796c8dcSSimon Schubert   lai->primitive_type_vector [java_primitive_type_long]
11345796c8dcSSimon Schubert     = builtin->builtin_long;
11355796c8dcSSimon Schubert   lai->primitive_type_vector [java_primitive_type_byte]
11365796c8dcSSimon Schubert     = builtin->builtin_byte;
11375796c8dcSSimon Schubert   lai->primitive_type_vector [java_primitive_type_boolean]
11385796c8dcSSimon Schubert     = builtin->builtin_boolean;
11395796c8dcSSimon Schubert   lai->primitive_type_vector [java_primitive_type_char]
11405796c8dcSSimon Schubert     = builtin->builtin_char;
11415796c8dcSSimon Schubert   lai->primitive_type_vector [java_primitive_type_float]
11425796c8dcSSimon Schubert     = builtin->builtin_float;
11435796c8dcSSimon Schubert   lai->primitive_type_vector [java_primitive_type_double]
11445796c8dcSSimon Schubert     = builtin->builtin_double;
11455796c8dcSSimon Schubert   lai->primitive_type_vector [java_primitive_type_void]
11465796c8dcSSimon Schubert     = builtin->builtin_void;
11475796c8dcSSimon Schubert 
11485796c8dcSSimon Schubert   lai->bool_type_symbol = "boolean";
11495796c8dcSSimon Schubert   lai->bool_type_default = builtin->builtin_boolean;
11505796c8dcSSimon Schubert }
11515796c8dcSSimon Schubert 
11525796c8dcSSimon Schubert const struct exp_descriptor exp_descriptor_java =
11535796c8dcSSimon Schubert {
11545796c8dcSSimon Schubert   print_subexp_standard,
11555796c8dcSSimon Schubert   operator_length_standard,
1156cf7f2e2dSJohn Marino   operator_check_standard,
11575796c8dcSSimon Schubert   op_name_standard,
11585796c8dcSSimon Schubert   dump_subexp_body_standard,
11595796c8dcSSimon Schubert   evaluate_subexp_java
11605796c8dcSSimon Schubert };
11615796c8dcSSimon Schubert 
11625796c8dcSSimon Schubert const struct language_defn java_language_defn =
11635796c8dcSSimon Schubert {
11645796c8dcSSimon Schubert   "java",			/* Language name */
11655796c8dcSSimon Schubert   language_java,
11665796c8dcSSimon Schubert   range_check_off,
11675796c8dcSSimon Schubert   case_sensitive_on,
11685796c8dcSSimon Schubert   array_row_major,
11695796c8dcSSimon Schubert   macro_expansion_no,
11705796c8dcSSimon Schubert   &exp_descriptor_java,
11715796c8dcSSimon Schubert   java_parse,
11725796c8dcSSimon Schubert   java_error,
11735796c8dcSSimon Schubert   null_post_parser,
1174a45ae5f8SJohn Marino   java_printchar,		/* Print a character constant */
1175a45ae5f8SJohn Marino   java_printstr,		/* Function to print string constant */
11765796c8dcSSimon Schubert   java_emit_char,		/* Function to print a single character */
11775796c8dcSSimon Schubert   java_print_type,		/* Print a type using appropriate syntax */
11785796c8dcSSimon Schubert   default_print_typedef,	/* Print a typedef using appropriate syntax */
11795796c8dcSSimon Schubert   java_val_print,		/* Print a value using appropriate syntax */
11805796c8dcSSimon Schubert   java_value_print,		/* Print a top-level value */
1181*ef5ccd6cSJohn Marino   default_read_var_value,	/* la_read_var_value */
11825796c8dcSSimon Schubert   NULL,				/* Language specific skip_trampoline */
11835796c8dcSSimon Schubert   "this",	                /* name_of_this */
11845796c8dcSSimon Schubert   basic_lookup_symbol_nonlocal,	/* lookup_symbol_nonlocal */
11855796c8dcSSimon Schubert   basic_lookup_transparent_type,/* lookup_transparent_type */
11865796c8dcSSimon Schubert   java_demangle,		/* Language specific symbol demangler */
11875796c8dcSSimon Schubert   java_class_name_from_physname,/* Language specific class name */
11885796c8dcSSimon Schubert   java_op_print_tab,		/* expression operators for printing */
11895796c8dcSSimon Schubert   0,				/* not c-style arrays */
11905796c8dcSSimon Schubert   0,				/* String lower bound */
11915796c8dcSSimon Schubert   default_word_break_characters,
11925796c8dcSSimon Schubert   default_make_symbol_completion_list,
11935796c8dcSSimon Schubert   java_language_arch_info,
11945796c8dcSSimon Schubert   default_print_array_index,
11955796c8dcSSimon Schubert   default_pass_by_reference,
11965796c8dcSSimon Schubert   default_get_string,
1197*ef5ccd6cSJohn Marino   NULL,				/* la_get_symbol_name_cmp */
1198a45ae5f8SJohn Marino   iterate_over_symbols,
11995796c8dcSSimon Schubert   LANG_MAGIC
12005796c8dcSSimon Schubert };
12015796c8dcSSimon Schubert 
12025796c8dcSSimon Schubert static void *
build_java_types(struct gdbarch * gdbarch)12035796c8dcSSimon Schubert build_java_types (struct gdbarch *gdbarch)
12045796c8dcSSimon Schubert {
12055796c8dcSSimon Schubert   struct builtin_java_type *builtin_java_type
12065796c8dcSSimon Schubert     = GDBARCH_OBSTACK_ZALLOC (gdbarch, struct builtin_java_type);
12075796c8dcSSimon Schubert 
12085796c8dcSSimon Schubert   builtin_java_type->builtin_int
12095796c8dcSSimon Schubert     = arch_integer_type (gdbarch, 32, 0, "int");
12105796c8dcSSimon Schubert   builtin_java_type->builtin_short
12115796c8dcSSimon Schubert     = arch_integer_type (gdbarch, 16, 0, "short");
12125796c8dcSSimon Schubert   builtin_java_type->builtin_long
12135796c8dcSSimon Schubert     = arch_integer_type (gdbarch, 64, 0, "long");
12145796c8dcSSimon Schubert   builtin_java_type->builtin_byte
12155796c8dcSSimon Schubert     = arch_integer_type (gdbarch, 8, 0, "byte");
12165796c8dcSSimon Schubert   builtin_java_type->builtin_boolean
12175796c8dcSSimon Schubert     = arch_boolean_type (gdbarch, 8, 0, "boolean");
12185796c8dcSSimon Schubert   builtin_java_type->builtin_char
12195796c8dcSSimon Schubert     = arch_character_type (gdbarch, 16, 1, "char");
12205796c8dcSSimon Schubert   builtin_java_type->builtin_float
12215796c8dcSSimon Schubert     = arch_float_type (gdbarch, 32, "float", NULL);
12225796c8dcSSimon Schubert   builtin_java_type->builtin_double
12235796c8dcSSimon Schubert     = arch_float_type (gdbarch, 64, "double", NULL);
12245796c8dcSSimon Schubert   builtin_java_type->builtin_void
12255796c8dcSSimon Schubert     = arch_type (gdbarch, TYPE_CODE_VOID, 1, "void");
12265796c8dcSSimon Schubert 
12275796c8dcSSimon Schubert   return builtin_java_type;
12285796c8dcSSimon Schubert }
12295796c8dcSSimon Schubert 
12305796c8dcSSimon Schubert static struct gdbarch_data *java_type_data;
12315796c8dcSSimon Schubert 
12325796c8dcSSimon Schubert const struct builtin_java_type *
builtin_java_type(struct gdbarch * gdbarch)12335796c8dcSSimon Schubert builtin_java_type (struct gdbarch *gdbarch)
12345796c8dcSSimon Schubert {
12355796c8dcSSimon Schubert   return gdbarch_data (gdbarch, java_type_data);
12365796c8dcSSimon Schubert }
12375796c8dcSSimon Schubert 
12385796c8dcSSimon Schubert void
_initialize_java_language(void)12395796c8dcSSimon Schubert _initialize_java_language (void)
12405796c8dcSSimon Schubert {
1241cf7f2e2dSJohn Marino   jv_dynamics_objfile_data_key
1242cf7f2e2dSJohn Marino     = register_objfile_data_with_cleanup (NULL, jv_per_objfile_free);
1243a45ae5f8SJohn Marino   jv_dynamics_progspace_key = register_program_space_data ();
1244cf7f2e2dSJohn Marino 
12455796c8dcSSimon Schubert   java_type_data = gdbarch_data_register_post_init (build_java_types);
12465796c8dcSSimon Schubert 
12475796c8dcSSimon Schubert   add_language (&java_language_defn);
12485796c8dcSSimon Schubert }
1249