xref: /openbsd-src/gnu/usr.bin/binutils/gdb/jv-lang.c (revision 11efff7f3ac2b3cfeff0c0cddc14294d9b3aca4f)
1b725ae77Skettenis /* Java language support routines for GDB, the GNU debugger.
2b725ae77Skettenis    Copyright 1997, 1998, 1999, 2000, 2003, 2004 Free Software Foundation, Inc.
3b725ae77Skettenis 
4b725ae77Skettenis    This file is part of GDB.
5b725ae77Skettenis 
6b725ae77Skettenis    This program is free software; you can redistribute it and/or modify
7b725ae77Skettenis    it under the terms of the GNU General Public License as published by
8b725ae77Skettenis    the Free Software Foundation; either version 2 of the License, or
9b725ae77Skettenis    (at your option) any later version.
10b725ae77Skettenis 
11b725ae77Skettenis    This program is distributed in the hope that it will be useful,
12b725ae77Skettenis    but WITHOUT ANY WARRANTY; without even the implied warranty of
13b725ae77Skettenis    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14b725ae77Skettenis    GNU General Public License for more details.
15b725ae77Skettenis 
16b725ae77Skettenis    You should have received a copy of the GNU General Public License
17b725ae77Skettenis    along with this program; if not, write to the Free Software
18b725ae77Skettenis    Foundation, Inc., 59 Temple Place - Suite 330,
19b725ae77Skettenis    Boston, MA 02111-1307, USA.  */
20b725ae77Skettenis 
21b725ae77Skettenis #include "defs.h"
22b725ae77Skettenis #include "symtab.h"
23b725ae77Skettenis #include "gdbtypes.h"
24b725ae77Skettenis #include "expression.h"
25b725ae77Skettenis #include "parser-defs.h"
26b725ae77Skettenis #include "language.h"
27b725ae77Skettenis #include "gdbtypes.h"
28b725ae77Skettenis #include "symtab.h"
29b725ae77Skettenis #include "symfile.h"
30b725ae77Skettenis #include "objfiles.h"
31b725ae77Skettenis #include "gdb_string.h"
32b725ae77Skettenis #include "value.h"
33b725ae77Skettenis #include "c-lang.h"
34b725ae77Skettenis #include "jv-lang.h"
35b725ae77Skettenis #include "gdbcore.h"
36b725ae77Skettenis #include "block.h"
37b725ae77Skettenis #include "demangle.h"
38b725ae77Skettenis #include "dictionary.h"
39b725ae77Skettenis #include <ctype.h>
40b725ae77Skettenis 
41b725ae77Skettenis struct type *java_int_type;
42b725ae77Skettenis struct type *java_byte_type;
43b725ae77Skettenis struct type *java_short_type;
44b725ae77Skettenis struct type *java_long_type;
45b725ae77Skettenis struct type *java_boolean_type;
46b725ae77Skettenis struct type *java_char_type;
47b725ae77Skettenis struct type *java_float_type;
48b725ae77Skettenis struct type *java_double_type;
49b725ae77Skettenis struct type *java_void_type;
50b725ae77Skettenis 
51b725ae77Skettenis /* Local functions */
52b725ae77Skettenis 
53b725ae77Skettenis extern void _initialize_java_language (void);
54b725ae77Skettenis 
55b725ae77Skettenis static int java_demangled_signature_length (char *);
56b725ae77Skettenis static void java_demangled_signature_copy (char *, char *);
57b725ae77Skettenis 
58b725ae77Skettenis static struct symtab *get_java_class_symtab (void);
59b725ae77Skettenis static char *get_java_utf8_name (struct obstack *obstack, struct value *name);
60b725ae77Skettenis static int java_class_is_primitive (struct value *clas);
61b725ae77Skettenis static struct value *java_value_string (char *ptr, int len);
62b725ae77Skettenis 
63b725ae77Skettenis static void java_emit_char (int c, struct ui_file * stream, int quoter);
64b725ae77Skettenis 
65*11efff7fSkettenis static char *java_class_name_from_physname (const char *physname);
66*11efff7fSkettenis 
67b725ae77Skettenis /* This objfile contains symtabs that have been dynamically created
68b725ae77Skettenis    to record dynamically loaded Java classes and dynamically
69b725ae77Skettenis    compiled java methods. */
70b725ae77Skettenis 
71b725ae77Skettenis static struct objfile *dynamics_objfile = NULL;
72b725ae77Skettenis 
73b725ae77Skettenis static struct type *java_link_class_type (struct type *, struct value *);
74b725ae77Skettenis 
75b725ae77Skettenis /* FIXME: carlton/2003-02-04: This is the main or only caller of
76b725ae77Skettenis    allocate_objfile with first argument NULL; as a result, this code
77b725ae77Skettenis    breaks every so often.  Somebody should write a test case that
78b725ae77Skettenis    exercises GDB in various ways (e.g. something involving loading a
79b725ae77Skettenis    dynamic library) after this code has been called.  */
80b725ae77Skettenis 
81b725ae77Skettenis static struct objfile *
get_dynamics_objfile(void)82b725ae77Skettenis get_dynamics_objfile (void)
83b725ae77Skettenis {
84b725ae77Skettenis   if (dynamics_objfile == NULL)
85b725ae77Skettenis     {
86b725ae77Skettenis       dynamics_objfile = allocate_objfile (NULL, 0);
87b725ae77Skettenis     }
88b725ae77Skettenis   return dynamics_objfile;
89b725ae77Skettenis }
90b725ae77Skettenis 
91b725ae77Skettenis #if 1
92b725ae77Skettenis /* symtab contains classes read from the inferior. */
93b725ae77Skettenis 
94b725ae77Skettenis static struct symtab *class_symtab = NULL;
95b725ae77Skettenis 
96b725ae77Skettenis static void free_class_block (struct symtab *symtab);
97b725ae77Skettenis 
98b725ae77Skettenis static struct symtab *
get_java_class_symtab(void)99b725ae77Skettenis get_java_class_symtab (void)
100b725ae77Skettenis {
101b725ae77Skettenis   if (class_symtab == NULL)
102b725ae77Skettenis     {
103b725ae77Skettenis       struct objfile *objfile = get_dynamics_objfile ();
104b725ae77Skettenis       struct blockvector *bv;
105b725ae77Skettenis       struct block *bl;
106b725ae77Skettenis       class_symtab = allocate_symtab ("<java-classes>", objfile);
107b725ae77Skettenis       class_symtab->language = language_java;
108b725ae77Skettenis       bv = (struct blockvector *)
109b725ae77Skettenis 	obstack_alloc (&objfile->objfile_obstack,
110b725ae77Skettenis 		       sizeof (struct blockvector) + sizeof (struct block *));
111b725ae77Skettenis       BLOCKVECTOR_NBLOCKS (bv) = 1;
112b725ae77Skettenis       BLOCKVECTOR (class_symtab) = bv;
113b725ae77Skettenis 
114b725ae77Skettenis       /* Allocate dummy STATIC_BLOCK. */
115b725ae77Skettenis       bl = allocate_block (&objfile->objfile_obstack);
116b725ae77Skettenis       BLOCK_DICT (bl) = dict_create_linear (&objfile->objfile_obstack,
117b725ae77Skettenis 					    NULL);
118b725ae77Skettenis       BLOCKVECTOR_BLOCK (bv, STATIC_BLOCK) = bl;
119b725ae77Skettenis 
120b725ae77Skettenis       /* Allocate GLOBAL_BLOCK.  */
121b725ae77Skettenis       bl = allocate_block (&objfile->objfile_obstack);
122b725ae77Skettenis       BLOCK_DICT (bl) = dict_create_hashed_expandable ();
123b725ae77Skettenis       BLOCKVECTOR_BLOCK (bv, GLOBAL_BLOCK) = bl;
124b725ae77Skettenis       class_symtab->free_func = free_class_block;
125b725ae77Skettenis     }
126b725ae77Skettenis   return class_symtab;
127b725ae77Skettenis }
128b725ae77Skettenis 
129b725ae77Skettenis static void
add_class_symtab_symbol(struct symbol * sym)130b725ae77Skettenis add_class_symtab_symbol (struct symbol *sym)
131b725ae77Skettenis {
132b725ae77Skettenis   struct symtab *symtab = get_java_class_symtab ();
133b725ae77Skettenis   struct blockvector *bv = BLOCKVECTOR (symtab);
134b725ae77Skettenis   dict_add_symbol (BLOCK_DICT (BLOCKVECTOR_BLOCK (bv, GLOBAL_BLOCK)), sym);
135b725ae77Skettenis }
136b725ae77Skettenis 
137b725ae77Skettenis static struct symbol *add_class_symbol (struct type *type, CORE_ADDR addr);
138b725ae77Skettenis 
139b725ae77Skettenis static struct symbol *
add_class_symbol(struct type * type,CORE_ADDR addr)140b725ae77Skettenis add_class_symbol (struct type *type, CORE_ADDR addr)
141b725ae77Skettenis {
142b725ae77Skettenis   struct symbol *sym;
143b725ae77Skettenis   sym = (struct symbol *)
144b725ae77Skettenis     obstack_alloc (&dynamics_objfile->objfile_obstack, sizeof (struct symbol));
145b725ae77Skettenis   memset (sym, 0, sizeof (struct symbol));
146b725ae77Skettenis   SYMBOL_LANGUAGE (sym) = language_java;
147b725ae77Skettenis   DEPRECATED_SYMBOL_NAME (sym) = TYPE_TAG_NAME (type);
148b725ae77Skettenis   SYMBOL_CLASS (sym) = LOC_TYPEDEF;
149b725ae77Skettenis   /*  SYMBOL_VALUE (sym) = valu; */
150b725ae77Skettenis   SYMBOL_TYPE (sym) = type;
151b725ae77Skettenis   SYMBOL_DOMAIN (sym) = STRUCT_DOMAIN;
152b725ae77Skettenis   SYMBOL_VALUE_ADDRESS (sym) = addr;
153b725ae77Skettenis   return sym;
154b725ae77Skettenis }
155b725ae77Skettenis 
156b725ae77Skettenis /* Free the dynamic symbols block.  */
157b725ae77Skettenis static void
free_class_block(struct symtab * symtab)158b725ae77Skettenis free_class_block (struct symtab *symtab)
159b725ae77Skettenis {
160b725ae77Skettenis   struct blockvector *bv = BLOCKVECTOR (symtab);
161b725ae77Skettenis   struct block *bl = BLOCKVECTOR_BLOCK (bv, GLOBAL_BLOCK);
162b725ae77Skettenis 
163b725ae77Skettenis   dict_free (BLOCK_DICT (bl));
164b725ae77Skettenis }
165b725ae77Skettenis #endif
166b725ae77Skettenis 
167b725ae77Skettenis struct type *
java_lookup_class(char * name)168b725ae77Skettenis java_lookup_class (char *name)
169b725ae77Skettenis {
170b725ae77Skettenis   struct symbol *sym;
171b725ae77Skettenis   sym = lookup_symbol (name, expression_context_block, STRUCT_DOMAIN,
172b725ae77Skettenis 		       (int *) 0, (struct symtab **) NULL);
173b725ae77Skettenis   if (sym != NULL)
174b725ae77Skettenis     return SYMBOL_TYPE (sym);
175b725ae77Skettenis #if 0
176b725ae77Skettenis   CORE_ADDR addr;
177b725ae77Skettenis   if (called from parser)
178b725ae77Skettenis     {
179b725ae77Skettenis       call lookup_class (or similar) in inferior;
180b725ae77Skettenis       if not
181b725ae77Skettenis       found:
182b725ae77Skettenis 	return NULL;
183b725ae77Skettenis       addr = found in inferior;
184b725ae77Skettenis     }
185b725ae77Skettenis   else
186b725ae77Skettenis     addr = 0;
187b725ae77Skettenis   struct type *type;
188b725ae77Skettenis   type = alloc_type (objfile);
189b725ae77Skettenis   TYPE_CODE (type) = TYPE_CODE_STRUCT;
190b725ae77Skettenis   INIT_CPLUS_SPECIFIC (type);
191b725ae77Skettenis   TYPE_TAG_NAME (type) = obsavestring (name, strlen (name), &objfile->objfile_obstack);
192b725ae77Skettenis   TYPE_FLAGS (type) |= TYPE_FLAG_STUB;
193b725ae77Skettenis   TYPE ? = addr;
194b725ae77Skettenis   return type;
195b725ae77Skettenis #else
196b725ae77Skettenis   /* FIXME - should search inferior's symbol table. */
197b725ae77Skettenis   return NULL;
198b725ae77Skettenis #endif
199b725ae77Skettenis }
200b725ae77Skettenis 
201b725ae77Skettenis /* Return a nul-terminated string (allocated on OBSTACK) for
202b725ae77Skettenis    a name given by NAME (which has type Utf8Const*). */
203b725ae77Skettenis 
204b725ae77Skettenis char *
get_java_utf8_name(struct obstack * obstack,struct value * name)205b725ae77Skettenis get_java_utf8_name (struct obstack *obstack, struct value *name)
206b725ae77Skettenis {
207b725ae77Skettenis   char *chrs;
208b725ae77Skettenis   struct value *temp = name;
209b725ae77Skettenis   int name_length;
210b725ae77Skettenis   CORE_ADDR data_addr;
211b725ae77Skettenis   temp = value_struct_elt (&temp, NULL, "length", NULL, "structure");
212b725ae77Skettenis   name_length = (int) value_as_long (temp);
213b725ae77Skettenis   data_addr = VALUE_ADDRESS (temp) + VALUE_OFFSET (temp)
214b725ae77Skettenis     + TYPE_LENGTH (VALUE_TYPE (temp));
215b725ae77Skettenis   chrs = obstack_alloc (obstack, name_length + 1);
216b725ae77Skettenis   chrs[name_length] = '\0';
217b725ae77Skettenis   read_memory (data_addr, chrs, name_length);
218b725ae77Skettenis   return chrs;
219b725ae77Skettenis }
220b725ae77Skettenis 
221b725ae77Skettenis struct value *
java_class_from_object(struct value * obj_val)222b725ae77Skettenis java_class_from_object (struct value *obj_val)
223b725ae77Skettenis {
224b725ae77Skettenis   /* This is all rather inefficient, since the offsets of vtable and
225b725ae77Skettenis      class are fixed.  FIXME */
226b725ae77Skettenis   struct value *vtable_val;
227b725ae77Skettenis 
228b725ae77Skettenis   if (TYPE_CODE (VALUE_TYPE (obj_val)) == TYPE_CODE_PTR
229b725ae77Skettenis       && TYPE_LENGTH (TYPE_TARGET_TYPE (VALUE_TYPE (obj_val))) == 0)
230b725ae77Skettenis     obj_val = value_at (get_java_object_type (),
231b725ae77Skettenis 			value_as_address (obj_val), NULL);
232b725ae77Skettenis 
233b725ae77Skettenis   vtable_val = value_struct_elt (&obj_val, NULL, "vtable", NULL, "structure");
234b725ae77Skettenis   return value_struct_elt (&vtable_val, NULL, "class", NULL, "structure");
235b725ae77Skettenis }
236b725ae77Skettenis 
237b725ae77Skettenis /* Check if CLASS_IS_PRIMITIVE(value of clas): */
238b725ae77Skettenis static int
java_class_is_primitive(struct value * clas)239b725ae77Skettenis java_class_is_primitive (struct value *clas)
240b725ae77Skettenis {
241b725ae77Skettenis   struct value *vtable = value_struct_elt (&clas, NULL, "vtable", NULL, "struct");
242b725ae77Skettenis   CORE_ADDR i = value_as_address (vtable);
243b725ae77Skettenis   return (int) (i & 0x7fffffff) == (int) 0x7fffffff;
244b725ae77Skettenis }
245b725ae77Skettenis 
246b725ae77Skettenis /* Read a GCJ Class object, and generated a gdb (TYPE_CODE_STRUCT) type. */
247b725ae77Skettenis 
248b725ae77Skettenis struct type *
type_from_class(struct value * clas)249b725ae77Skettenis type_from_class (struct value *clas)
250b725ae77Skettenis {
251b725ae77Skettenis   struct type *type;
252b725ae77Skettenis   char *name;
253b725ae77Skettenis   struct value *temp;
254b725ae77Skettenis   struct objfile *objfile;
255b725ae77Skettenis   struct value *utf8_name;
256b725ae77Skettenis   char *nptr;
257b725ae77Skettenis   CORE_ADDR addr;
258b725ae77Skettenis   struct block *bl;
259b725ae77Skettenis   struct dict_iterator iter;
260b725ae77Skettenis   int is_array = 0;
261b725ae77Skettenis 
262b725ae77Skettenis   type = check_typedef (VALUE_TYPE (clas));
263b725ae77Skettenis   if (TYPE_CODE (type) == TYPE_CODE_PTR)
264b725ae77Skettenis     {
265b725ae77Skettenis       if (value_logical_not (clas))
266b725ae77Skettenis 	return NULL;
267b725ae77Skettenis       clas = value_ind (clas);
268b725ae77Skettenis     }
269b725ae77Skettenis   addr = VALUE_ADDRESS (clas) + VALUE_OFFSET (clas);
270b725ae77Skettenis 
271b725ae77Skettenis #if 0
272b725ae77Skettenis   get_java_class_symtab ();
273b725ae77Skettenis   bl = BLOCKVECTOR_BLOCK (BLOCKVECTOR (class_symtab), GLOBAL_BLOCK);
274b725ae77Skettenis   ALL_BLOCK_SYMBOLS (block, iter, sym)
275b725ae77Skettenis     {
276b725ae77Skettenis       if (SYMBOL_VALUE_ADDRESS (sym) == addr)
277b725ae77Skettenis 	return SYMBOL_TYPE (sym);
278b725ae77Skettenis     }
279b725ae77Skettenis #endif
280b725ae77Skettenis 
281b725ae77Skettenis   objfile = get_dynamics_objfile ();
282b725ae77Skettenis   if (java_class_is_primitive (clas))
283b725ae77Skettenis     {
284b725ae77Skettenis       struct value *sig;
285b725ae77Skettenis       temp = clas;
286b725ae77Skettenis       sig = value_struct_elt (&temp, NULL, "method_count", NULL, "structure");
287b725ae77Skettenis       return java_primitive_type (value_as_long (sig));
288b725ae77Skettenis     }
289b725ae77Skettenis 
290b725ae77Skettenis   /* Get Class name. */
291b725ae77Skettenis   /* if clasloader non-null, prepend loader address. FIXME */
292b725ae77Skettenis   temp = clas;
293b725ae77Skettenis   utf8_name = value_struct_elt (&temp, NULL, "name", NULL, "structure");
294b725ae77Skettenis   name = get_java_utf8_name (&objfile->objfile_obstack, utf8_name);
295b725ae77Skettenis   for (nptr = name; *nptr != 0; nptr++)
296b725ae77Skettenis     {
297b725ae77Skettenis       if (*nptr == '/')
298b725ae77Skettenis 	*nptr = '.';
299b725ae77Skettenis     }
300b725ae77Skettenis 
301b725ae77Skettenis   type = java_lookup_class (name);
302b725ae77Skettenis   if (type != NULL)
303b725ae77Skettenis     return type;
304b725ae77Skettenis 
305b725ae77Skettenis   type = alloc_type (objfile);
306b725ae77Skettenis   TYPE_CODE (type) = TYPE_CODE_STRUCT;
307b725ae77Skettenis   INIT_CPLUS_SPECIFIC (type);
308b725ae77Skettenis 
309b725ae77Skettenis   if (name[0] == '[')
310b725ae77Skettenis     {
311b725ae77Skettenis       char *signature = name;
312b725ae77Skettenis       int namelen = java_demangled_signature_length (signature);
313b725ae77Skettenis       if (namelen > strlen (name))
314b725ae77Skettenis 	name = obstack_alloc (&objfile->objfile_obstack, namelen + 1);
315b725ae77Skettenis       java_demangled_signature_copy (name, signature);
316b725ae77Skettenis       name[namelen] = '\0';
317b725ae77Skettenis       is_array = 1;
318b725ae77Skettenis       temp = clas;
319b725ae77Skettenis       /* Set array element type. */
320b725ae77Skettenis       temp = value_struct_elt (&temp, NULL, "methods", NULL, "structure");
321b725ae77Skettenis       VALUE_TYPE (temp) = lookup_pointer_type (VALUE_TYPE (clas));
322b725ae77Skettenis       TYPE_TARGET_TYPE (type) = type_from_class (temp);
323b725ae77Skettenis     }
324b725ae77Skettenis 
325b725ae77Skettenis   ALLOCATE_CPLUS_STRUCT_TYPE (type);
326b725ae77Skettenis   TYPE_TAG_NAME (type) = name;
327b725ae77Skettenis 
328b725ae77Skettenis   add_class_symtab_symbol (add_class_symbol (type, addr));
329b725ae77Skettenis   return java_link_class_type (type, clas);
330b725ae77Skettenis }
331b725ae77Skettenis 
332b725ae77Skettenis /* Fill in class TYPE with data from the CLAS value. */
333b725ae77Skettenis 
334b725ae77Skettenis struct type *
java_link_class_type(struct type * type,struct value * clas)335b725ae77Skettenis java_link_class_type (struct type *type, struct value *clas)
336b725ae77Skettenis {
337b725ae77Skettenis   struct value *temp;
338b725ae77Skettenis   char *unqualified_name;
339b725ae77Skettenis   char *name = TYPE_TAG_NAME (type);
340b725ae77Skettenis   int ninterfaces, nfields, nmethods;
341b725ae77Skettenis   int type_is_object = 0;
342b725ae77Skettenis   struct fn_field *fn_fields;
343b725ae77Skettenis   struct fn_fieldlist *fn_fieldlists;
344b725ae77Skettenis   struct value *fields;
345b725ae77Skettenis   struct value *methods;
346b725ae77Skettenis   struct value *method = NULL;
347b725ae77Skettenis   struct value *field = NULL;
348b725ae77Skettenis   int i, j;
349b725ae77Skettenis   struct objfile *objfile = get_dynamics_objfile ();
350b725ae77Skettenis   struct type *tsuper;
351b725ae77Skettenis 
352b725ae77Skettenis   unqualified_name = strrchr (name, '.');
353b725ae77Skettenis   if (unqualified_name == NULL)
354b725ae77Skettenis     unqualified_name = name;
355b725ae77Skettenis 
356b725ae77Skettenis   temp = clas;
357b725ae77Skettenis   temp = value_struct_elt (&temp, NULL, "superclass", NULL, "structure");
358b725ae77Skettenis   if (name != NULL && strcmp (name, "java.lang.Object") == 0)
359b725ae77Skettenis     {
360b725ae77Skettenis       tsuper = get_java_object_type ();
361b725ae77Skettenis       if (tsuper && TYPE_CODE (tsuper) == TYPE_CODE_PTR)
362b725ae77Skettenis 	tsuper = TYPE_TARGET_TYPE (tsuper);
363b725ae77Skettenis       type_is_object = 1;
364b725ae77Skettenis     }
365b725ae77Skettenis   else
366b725ae77Skettenis     tsuper = type_from_class (temp);
367b725ae77Skettenis 
368b725ae77Skettenis #if 1
369b725ae77Skettenis   ninterfaces = 0;
370b725ae77Skettenis #else
371b725ae77Skettenis   temp = clas;
372b725ae77Skettenis   ninterfaces = value_as_long (value_struct_elt (&temp, NULL, "interface_len", NULL, "structure"));
373b725ae77Skettenis #endif
374b725ae77Skettenis   TYPE_N_BASECLASSES (type) = (tsuper == NULL ? 0 : 1) + ninterfaces;
375b725ae77Skettenis   temp = clas;
376b725ae77Skettenis   nfields = value_as_long (value_struct_elt (&temp, NULL, "field_count", NULL, "structure"));
377b725ae77Skettenis   nfields += TYPE_N_BASECLASSES (type);
378b725ae77Skettenis   nfields++;			/* Add one for dummy "class" field. */
379b725ae77Skettenis   TYPE_NFIELDS (type) = nfields;
380b725ae77Skettenis   TYPE_FIELDS (type) = (struct field *)
381b725ae77Skettenis     TYPE_ALLOC (type, sizeof (struct field) * nfields);
382b725ae77Skettenis 
383b725ae77Skettenis   memset (TYPE_FIELDS (type), 0, sizeof (struct field) * nfields);
384b725ae77Skettenis 
385b725ae77Skettenis   TYPE_FIELD_PRIVATE_BITS (type) =
386b725ae77Skettenis     (B_TYPE *) TYPE_ALLOC (type, B_BYTES (nfields));
387b725ae77Skettenis   B_CLRALL (TYPE_FIELD_PRIVATE_BITS (type), nfields);
388b725ae77Skettenis 
389b725ae77Skettenis   TYPE_FIELD_PROTECTED_BITS (type) =
390b725ae77Skettenis     (B_TYPE *) TYPE_ALLOC (type, B_BYTES (nfields));
391b725ae77Skettenis   B_CLRALL (TYPE_FIELD_PROTECTED_BITS (type), nfields);
392b725ae77Skettenis 
393b725ae77Skettenis   TYPE_FIELD_IGNORE_BITS (type) =
394b725ae77Skettenis     (B_TYPE *) TYPE_ALLOC (type, B_BYTES (nfields));
395b725ae77Skettenis   B_CLRALL (TYPE_FIELD_IGNORE_BITS (type), nfields);
396b725ae77Skettenis 
397b725ae77Skettenis   TYPE_FIELD_VIRTUAL_BITS (type) = (B_TYPE *)
398b725ae77Skettenis     TYPE_ALLOC (type, B_BYTES (TYPE_N_BASECLASSES (type)));
399b725ae77Skettenis   B_CLRALL (TYPE_FIELD_VIRTUAL_BITS (type), TYPE_N_BASECLASSES (type));
400b725ae77Skettenis 
401b725ae77Skettenis   if (tsuper != NULL)
402b725ae77Skettenis     {
403b725ae77Skettenis       TYPE_BASECLASS (type, 0) = tsuper;
404b725ae77Skettenis       if (type_is_object)
405b725ae77Skettenis 	SET_TYPE_FIELD_PRIVATE (type, 0);
406b725ae77Skettenis     }
407b725ae77Skettenis 
408b725ae77Skettenis   i = strlen (name);
409b725ae77Skettenis   if (i > 2 && name[i - 1] == ']' && tsuper != NULL)
410b725ae77Skettenis     {
411b725ae77Skettenis       /* FIXME */
412b725ae77Skettenis       TYPE_LENGTH (type) = TYPE_LENGTH (tsuper) + 4;	/* size with "length" */
413b725ae77Skettenis     }
414b725ae77Skettenis   else
415b725ae77Skettenis     {
416b725ae77Skettenis       temp = clas;
417b725ae77Skettenis       temp = value_struct_elt (&temp, NULL, "size_in_bytes", NULL, "structure");
418b725ae77Skettenis       TYPE_LENGTH (type) = value_as_long (temp);
419b725ae77Skettenis     }
420b725ae77Skettenis 
421b725ae77Skettenis   fields = NULL;
422b725ae77Skettenis   nfields--;			/* First set up dummy "class" field. */
423b725ae77Skettenis   SET_FIELD_PHYSADDR (TYPE_FIELD (type, nfields),
424b725ae77Skettenis 		      VALUE_ADDRESS (clas) + VALUE_OFFSET (clas));
425b725ae77Skettenis   TYPE_FIELD_NAME (type, nfields) = "class";
426b725ae77Skettenis   TYPE_FIELD_TYPE (type, nfields) = VALUE_TYPE (clas);
427b725ae77Skettenis   SET_TYPE_FIELD_PRIVATE (type, nfields);
428b725ae77Skettenis 
429b725ae77Skettenis   for (i = TYPE_N_BASECLASSES (type); i < nfields; i++)
430b725ae77Skettenis     {
431b725ae77Skettenis       int accflags;
432b725ae77Skettenis       int boffset;
433b725ae77Skettenis       if (fields == NULL)
434b725ae77Skettenis 	{
435b725ae77Skettenis 	  temp = clas;
436b725ae77Skettenis 	  fields = value_struct_elt (&temp, NULL, "fields", NULL, "structure");
437b725ae77Skettenis 	  field = value_ind (fields);
438b725ae77Skettenis 	}
439b725ae77Skettenis       else
440b725ae77Skettenis 	{			/* Re-use field value for next field. */
441b725ae77Skettenis 	  VALUE_ADDRESS (field) += TYPE_LENGTH (VALUE_TYPE (field));
442b725ae77Skettenis 	  VALUE_LAZY (field) = 1;
443b725ae77Skettenis 	}
444b725ae77Skettenis       temp = field;
445b725ae77Skettenis       temp = value_struct_elt (&temp, NULL, "name", NULL, "structure");
446b725ae77Skettenis       TYPE_FIELD_NAME (type, i) =
447b725ae77Skettenis 	get_java_utf8_name (&objfile->objfile_obstack, temp);
448b725ae77Skettenis       temp = field;
449b725ae77Skettenis       accflags = value_as_long (value_struct_elt (&temp, NULL, "accflags",
450b725ae77Skettenis 						  NULL, "structure"));
451b725ae77Skettenis       temp = field;
452b725ae77Skettenis       temp = value_struct_elt (&temp, NULL, "info", NULL, "structure");
453b725ae77Skettenis       boffset = value_as_long (value_struct_elt (&temp, NULL, "boffset",
454b725ae77Skettenis 						 NULL, "structure"));
455b725ae77Skettenis       if (accflags & 0x0001)	/* public access */
456b725ae77Skettenis 	{
457b725ae77Skettenis 	  /* ??? */
458b725ae77Skettenis 	}
459b725ae77Skettenis       if (accflags & 0x0002)	/* private access */
460b725ae77Skettenis 	{
461b725ae77Skettenis 	  SET_TYPE_FIELD_PRIVATE (type, i);
462b725ae77Skettenis 	}
463b725ae77Skettenis       if (accflags & 0x0004)	/* protected access */
464b725ae77Skettenis 	{
465b725ae77Skettenis 	  SET_TYPE_FIELD_PROTECTED (type, i);
466b725ae77Skettenis 	}
467b725ae77Skettenis       if (accflags & 0x0008)	/* ACC_STATIC */
468b725ae77Skettenis 	SET_FIELD_PHYSADDR (TYPE_FIELD (type, i), boffset);
469b725ae77Skettenis       else
470b725ae77Skettenis 	TYPE_FIELD_BITPOS (type, i) = 8 * boffset;
471b725ae77Skettenis       if (accflags & 0x8000)	/* FIELD_UNRESOLVED_FLAG */
472b725ae77Skettenis 	{
473b725ae77Skettenis 	  TYPE_FIELD_TYPE (type, i) = get_java_object_type ();	/* FIXME */
474b725ae77Skettenis 	}
475b725ae77Skettenis       else
476b725ae77Skettenis 	{
477b725ae77Skettenis 	  struct type *ftype;
478b725ae77Skettenis 	  temp = field;
479b725ae77Skettenis 	  temp = value_struct_elt (&temp, NULL, "type", NULL, "structure");
480b725ae77Skettenis 	  ftype = type_from_class (temp);
481b725ae77Skettenis 	  if (TYPE_CODE (ftype) == TYPE_CODE_STRUCT)
482b725ae77Skettenis 	    ftype = lookup_pointer_type (ftype);
483b725ae77Skettenis 	  TYPE_FIELD_TYPE (type, i) = ftype;
484b725ae77Skettenis 	}
485b725ae77Skettenis     }
486b725ae77Skettenis 
487b725ae77Skettenis   temp = clas;
488b725ae77Skettenis   nmethods = value_as_long (value_struct_elt (&temp, NULL, "method_count",
489b725ae77Skettenis 					      NULL, "structure"));
490b725ae77Skettenis   TYPE_NFN_FIELDS_TOTAL (type) = nmethods;
491b725ae77Skettenis   j = nmethods * sizeof (struct fn_field);
492b725ae77Skettenis   fn_fields = (struct fn_field *)
493b725ae77Skettenis     obstack_alloc (&dynamics_objfile->objfile_obstack, j);
494b725ae77Skettenis   memset (fn_fields, 0, j);
495b725ae77Skettenis   fn_fieldlists = (struct fn_fieldlist *)
496b725ae77Skettenis     alloca (nmethods * sizeof (struct fn_fieldlist));
497b725ae77Skettenis 
498b725ae77Skettenis   methods = NULL;
499b725ae77Skettenis   for (i = 0; i < nmethods; i++)
500b725ae77Skettenis     {
501b725ae77Skettenis       char *mname;
502b725ae77Skettenis       int k;
503b725ae77Skettenis       if (methods == NULL)
504b725ae77Skettenis 	{
505b725ae77Skettenis 	  temp = clas;
506b725ae77Skettenis 	  methods = value_struct_elt (&temp, NULL, "methods", NULL, "structure");
507b725ae77Skettenis 	  method = value_ind (methods);
508b725ae77Skettenis 	}
509b725ae77Skettenis       else
510b725ae77Skettenis 	{			/* Re-use method value for next method. */
511b725ae77Skettenis 	  VALUE_ADDRESS (method) += TYPE_LENGTH (VALUE_TYPE (method));
512b725ae77Skettenis 	  VALUE_LAZY (method) = 1;
513b725ae77Skettenis 	}
514b725ae77Skettenis 
515b725ae77Skettenis       /* Get method name. */
516b725ae77Skettenis       temp = method;
517b725ae77Skettenis       temp = value_struct_elt (&temp, NULL, "name", NULL, "structure");
518b725ae77Skettenis       mname = get_java_utf8_name (&objfile->objfile_obstack, temp);
519b725ae77Skettenis       if (strcmp (mname, "<init>") == 0)
520b725ae77Skettenis 	mname = unqualified_name;
521b725ae77Skettenis 
522b725ae77Skettenis       /* Check for an existing method with the same name.
523b725ae77Skettenis        * This makes building the fn_fieldslists an O(nmethods**2)
524b725ae77Skettenis        * operation.  That could be using hashing, but I doubt it
525b725ae77Skettenis        * is worth it.  Note that we do maintain the order of methods
526b725ae77Skettenis        * in the inferior's Method table (as long as that is grouped
527b725ae77Skettenis        * by method name), which I think is desirable.  --PB */
528b725ae77Skettenis       for (k = 0, j = TYPE_NFN_FIELDS (type);;)
529b725ae77Skettenis 	{
530b725ae77Skettenis 	  if (--j < 0)
531b725ae77Skettenis 	    {			/* No match - new method name. */
532b725ae77Skettenis 	      j = TYPE_NFN_FIELDS (type)++;
533b725ae77Skettenis 	      fn_fieldlists[j].name = mname;
534b725ae77Skettenis 	      fn_fieldlists[j].length = 1;
535b725ae77Skettenis 	      fn_fieldlists[j].fn_fields = &fn_fields[i];
536b725ae77Skettenis 	      k = i;
537b725ae77Skettenis 	      break;
538b725ae77Skettenis 	    }
539b725ae77Skettenis 	  if (strcmp (mname, fn_fieldlists[j].name) == 0)
540b725ae77Skettenis 	    {			/* Found an existing method with the same name. */
541b725ae77Skettenis 	      int l;
542b725ae77Skettenis 	      if (mname != unqualified_name)
543b725ae77Skettenis 		obstack_free (&objfile->objfile_obstack, mname);
544b725ae77Skettenis 	      mname = fn_fieldlists[j].name;
545b725ae77Skettenis 	      fn_fieldlists[j].length++;
546b725ae77Skettenis 	      k = i - k;	/* Index of new slot. */
547b725ae77Skettenis 	      /* Shift intervening fn_fields (between k and i) down. */
548b725ae77Skettenis 	      for (l = i; l > k; l--)
549b725ae77Skettenis 		fn_fields[l] = fn_fields[l - 1];
550b725ae77Skettenis 	      for (l = TYPE_NFN_FIELDS (type); --l > j;)
551b725ae77Skettenis 		fn_fieldlists[l].fn_fields++;
552b725ae77Skettenis 	      break;
553b725ae77Skettenis 	    }
554b725ae77Skettenis 	  k += fn_fieldlists[j].length;
555b725ae77Skettenis 	}
556b725ae77Skettenis       fn_fields[k].physname = "";
557b725ae77Skettenis       fn_fields[k].is_stub = 1;
558b725ae77Skettenis       fn_fields[k].type = make_function_type (java_void_type, NULL);	/* FIXME */
559b725ae77Skettenis       TYPE_CODE (fn_fields[k].type) = TYPE_CODE_METHOD;
560b725ae77Skettenis     }
561b725ae77Skettenis 
562b725ae77Skettenis   j = TYPE_NFN_FIELDS (type) * sizeof (struct fn_fieldlist);
563b725ae77Skettenis   TYPE_FN_FIELDLISTS (type) = (struct fn_fieldlist *)
564b725ae77Skettenis     obstack_alloc (&dynamics_objfile->objfile_obstack, j);
565b725ae77Skettenis   memcpy (TYPE_FN_FIELDLISTS (type), fn_fieldlists, j);
566b725ae77Skettenis 
567b725ae77Skettenis   return type;
568b725ae77Skettenis }
569b725ae77Skettenis 
570b725ae77Skettenis static struct type *java_object_type;
571b725ae77Skettenis 
572b725ae77Skettenis struct type *
get_java_object_type(void)573b725ae77Skettenis get_java_object_type (void)
574b725ae77Skettenis {
575b725ae77Skettenis   if (java_object_type == NULL)
576b725ae77Skettenis     {
577b725ae77Skettenis       struct symbol *sym;
578b725ae77Skettenis       sym = lookup_symbol ("java.lang.Object", NULL, STRUCT_DOMAIN,
579b725ae77Skettenis 			   (int *) 0, (struct symtab **) NULL);
580b725ae77Skettenis       if (sym == NULL)
581b725ae77Skettenis 	error ("cannot find java.lang.Object");
582b725ae77Skettenis       java_object_type = SYMBOL_TYPE (sym);
583b725ae77Skettenis     }
584b725ae77Skettenis   return java_object_type;
585b725ae77Skettenis }
586b725ae77Skettenis 
587b725ae77Skettenis int
get_java_object_header_size(void)588b725ae77Skettenis get_java_object_header_size (void)
589b725ae77Skettenis {
590b725ae77Skettenis   struct type *objtype = get_java_object_type ();
591b725ae77Skettenis   if (objtype == NULL)
592b725ae77Skettenis     return (2 * TARGET_PTR_BIT / TARGET_CHAR_BIT);
593b725ae77Skettenis   else
594b725ae77Skettenis     return TYPE_LENGTH (objtype);
595b725ae77Skettenis }
596b725ae77Skettenis 
597b725ae77Skettenis int
is_object_type(struct type * type)598b725ae77Skettenis is_object_type (struct type *type)
599b725ae77Skettenis {
600b725ae77Skettenis   CHECK_TYPEDEF (type);
601b725ae77Skettenis   if (TYPE_CODE (type) == TYPE_CODE_PTR)
602b725ae77Skettenis     {
603b725ae77Skettenis       struct type *ttype = check_typedef (TYPE_TARGET_TYPE (type));
604b725ae77Skettenis       char *name;
605b725ae77Skettenis       if (TYPE_CODE (ttype) != TYPE_CODE_STRUCT)
606b725ae77Skettenis 	return 0;
607b725ae77Skettenis       while (TYPE_N_BASECLASSES (ttype) > 0)
608b725ae77Skettenis 	ttype = TYPE_BASECLASS (ttype, 0);
609b725ae77Skettenis       name = TYPE_TAG_NAME (ttype);
610b725ae77Skettenis       if (name != NULL && strcmp (name, "java.lang.Object") == 0)
611b725ae77Skettenis 	return 1;
612b725ae77Skettenis       name = TYPE_NFIELDS (ttype) > 0 ? TYPE_FIELD_NAME (ttype, 0) : (char *) 0;
613b725ae77Skettenis       if (name != NULL && strcmp (name, "vtable") == 0)
614b725ae77Skettenis 	{
615b725ae77Skettenis 	  if (java_object_type == NULL)
616b725ae77Skettenis 	    java_object_type = type;
617b725ae77Skettenis 	  return 1;
618b725ae77Skettenis 	}
619b725ae77Skettenis     }
620b725ae77Skettenis   return 0;
621b725ae77Skettenis }
622b725ae77Skettenis 
623b725ae77Skettenis struct type *
java_primitive_type(int signature)624b725ae77Skettenis java_primitive_type (int signature)
625b725ae77Skettenis {
626b725ae77Skettenis   switch (signature)
627b725ae77Skettenis     {
628b725ae77Skettenis     case 'B':
629b725ae77Skettenis       return java_byte_type;
630b725ae77Skettenis     case 'S':
631b725ae77Skettenis       return java_short_type;
632b725ae77Skettenis     case 'I':
633b725ae77Skettenis       return java_int_type;
634b725ae77Skettenis     case 'J':
635b725ae77Skettenis       return java_long_type;
636b725ae77Skettenis     case 'Z':
637b725ae77Skettenis       return java_boolean_type;
638b725ae77Skettenis     case 'C':
639b725ae77Skettenis       return java_char_type;
640b725ae77Skettenis     case 'F':
641b725ae77Skettenis       return java_float_type;
642b725ae77Skettenis     case 'D':
643b725ae77Skettenis       return java_double_type;
644b725ae77Skettenis     case 'V':
645b725ae77Skettenis       return java_void_type;
646b725ae77Skettenis     }
647b725ae77Skettenis   error ("unknown signature '%c' for primitive type", (char) signature);
648b725ae77Skettenis }
649b725ae77Skettenis 
650b725ae77Skettenis /* If name[0 .. namelen-1] is the name of a primitive Java type,
651b725ae77Skettenis    return that type.  Otherwise, return NULL. */
652b725ae77Skettenis 
653b725ae77Skettenis struct type *
java_primitive_type_from_name(char * name,int namelen)654b725ae77Skettenis java_primitive_type_from_name (char *name, int namelen)
655b725ae77Skettenis {
656b725ae77Skettenis   switch (name[0])
657b725ae77Skettenis     {
658b725ae77Skettenis     case 'b':
659b725ae77Skettenis       if (namelen == 4 && memcmp (name, "byte", 4) == 0)
660b725ae77Skettenis 	return java_byte_type;
661b725ae77Skettenis       if (namelen == 7 && memcmp (name, "boolean", 7) == 0)
662b725ae77Skettenis 	return java_boolean_type;
663b725ae77Skettenis       break;
664b725ae77Skettenis     case 'c':
665b725ae77Skettenis       if (namelen == 4 && memcmp (name, "char", 4) == 0)
666b725ae77Skettenis 	return java_char_type;
667b725ae77Skettenis     case 'd':
668b725ae77Skettenis       if (namelen == 6 && memcmp (name, "double", 6) == 0)
669b725ae77Skettenis 	return java_double_type;
670b725ae77Skettenis       break;
671b725ae77Skettenis     case 'f':
672b725ae77Skettenis       if (namelen == 5 && memcmp (name, "float", 5) == 0)
673b725ae77Skettenis 	return java_float_type;
674b725ae77Skettenis       break;
675b725ae77Skettenis     case 'i':
676b725ae77Skettenis       if (namelen == 3 && memcmp (name, "int", 3) == 0)
677b725ae77Skettenis 	return java_int_type;
678b725ae77Skettenis       break;
679b725ae77Skettenis     case 'l':
680b725ae77Skettenis       if (namelen == 4 && memcmp (name, "long", 4) == 0)
681b725ae77Skettenis 	return java_long_type;
682b725ae77Skettenis       break;
683b725ae77Skettenis     case 's':
684b725ae77Skettenis       if (namelen == 5 && memcmp (name, "short", 5) == 0)
685b725ae77Skettenis 	return java_short_type;
686b725ae77Skettenis       break;
687b725ae77Skettenis     case 'v':
688b725ae77Skettenis       if (namelen == 4 && memcmp (name, "void", 4) == 0)
689b725ae77Skettenis 	return java_void_type;
690b725ae77Skettenis       break;
691b725ae77Skettenis     }
692b725ae77Skettenis   return NULL;
693b725ae77Skettenis }
694b725ae77Skettenis 
695b725ae77Skettenis /* Return the length (in bytes) of demangled name of the Java type
696b725ae77Skettenis    signature string SIGNATURE. */
697b725ae77Skettenis 
698b725ae77Skettenis static int
java_demangled_signature_length(char * signature)699b725ae77Skettenis java_demangled_signature_length (char *signature)
700b725ae77Skettenis {
701b725ae77Skettenis   int array = 0;
702b725ae77Skettenis   for (; *signature == '['; signature++)
703b725ae77Skettenis     array += 2;			/* Two chars for "[]". */
704b725ae77Skettenis   switch (signature[0])
705b725ae77Skettenis     {
706b725ae77Skettenis     case 'L':
707b725ae77Skettenis       /* Subtract 2 for 'L' and ';'. */
708b725ae77Skettenis       return strlen (signature) - 2 + array;
709b725ae77Skettenis     default:
710b725ae77Skettenis       return strlen (TYPE_NAME (java_primitive_type (signature[0]))) + array;
711b725ae77Skettenis     }
712b725ae77Skettenis }
713b725ae77Skettenis 
714b725ae77Skettenis /* Demangle the Java type signature SIGNATURE, leaving the result in RESULT. */
715b725ae77Skettenis 
716b725ae77Skettenis static void
java_demangled_signature_copy(char * result,char * signature)717b725ae77Skettenis java_demangled_signature_copy (char *result, char *signature)
718b725ae77Skettenis {
719b725ae77Skettenis   int array = 0;
720b725ae77Skettenis   char *ptr;
721b725ae77Skettenis   int i;
722b725ae77Skettenis   while (*signature == '[')
723b725ae77Skettenis     {
724b725ae77Skettenis       array++;
725b725ae77Skettenis       signature++;
726b725ae77Skettenis     }
727b725ae77Skettenis   switch (signature[0])
728b725ae77Skettenis     {
729b725ae77Skettenis     case 'L':
730b725ae77Skettenis       /* Subtract 2 for 'L' and ';', but add 1 for final nul. */
731b725ae77Skettenis       signature++;
732b725ae77Skettenis       ptr = result;
733b725ae77Skettenis       for (; *signature != ';' && *signature != '\0'; signature++)
734b725ae77Skettenis 	{
735b725ae77Skettenis 	  if (*signature == '/')
736b725ae77Skettenis 	    *ptr++ = '.';
737b725ae77Skettenis 	  else
738b725ae77Skettenis 	    *ptr++ = *signature;
739b725ae77Skettenis 	}
740b725ae77Skettenis       break;
741b725ae77Skettenis     default:
742b725ae77Skettenis       ptr = TYPE_NAME (java_primitive_type (signature[0]));
743b725ae77Skettenis       i = strlen (ptr);
744b725ae77Skettenis       strcpy (result, ptr);
745b725ae77Skettenis       ptr = result + i;
746b725ae77Skettenis       break;
747b725ae77Skettenis     }
748b725ae77Skettenis   while (--array >= 0)
749b725ae77Skettenis     {
750b725ae77Skettenis       *ptr++ = '[';
751b725ae77Skettenis       *ptr++ = ']';
752b725ae77Skettenis     }
753b725ae77Skettenis }
754b725ae77Skettenis 
755b725ae77Skettenis /* Return the demangled name of the Java type signature string SIGNATURE,
756b725ae77Skettenis    as a freshly allocated copy. */
757b725ae77Skettenis 
758b725ae77Skettenis char *
java_demangle_type_signature(char * signature)759b725ae77Skettenis java_demangle_type_signature (char *signature)
760b725ae77Skettenis {
761b725ae77Skettenis   int length = java_demangled_signature_length (signature);
762b725ae77Skettenis   char *result = xmalloc (length + 1);
763b725ae77Skettenis   java_demangled_signature_copy (result, signature);
764b725ae77Skettenis   result[length] = '\0';
765b725ae77Skettenis   return result;
766b725ae77Skettenis }
767b725ae77Skettenis 
768b725ae77Skettenis /* Return the type of TYPE followed by DIMS pairs of [ ].
769b725ae77Skettenis    If DIMS == 0, TYPE is returned. */
770b725ae77Skettenis 
771b725ae77Skettenis struct type *
java_array_type(struct type * type,int dims)772b725ae77Skettenis java_array_type (struct type *type, int dims)
773b725ae77Skettenis {
774b725ae77Skettenis   struct type *range_type;
775b725ae77Skettenis 
776b725ae77Skettenis   while (dims-- > 0)
777b725ae77Skettenis     {
778b725ae77Skettenis       range_type = create_range_type (NULL, builtin_type_int, 0, 0);
779b725ae77Skettenis       /* FIXME  This is bogus!  Java arrays are not gdb arrays! */
780b725ae77Skettenis       type = create_array_type (NULL, type, range_type);
781b725ae77Skettenis     }
782b725ae77Skettenis 
783b725ae77Skettenis   return type;
784b725ae77Skettenis }
785b725ae77Skettenis 
786b725ae77Skettenis /* Create a Java string in the inferior from a (Utf8) literal. */
787b725ae77Skettenis 
788b725ae77Skettenis static struct value *
java_value_string(char * ptr,int len)789b725ae77Skettenis java_value_string (char *ptr, int len)
790b725ae77Skettenis {
791b725ae77Skettenis   error ("not implemented - java_value_string");	/* FIXME */
792b725ae77Skettenis }
793b725ae77Skettenis 
794b725ae77Skettenis /* Print the character C on STREAM as part of the contents of a literal
795b725ae77Skettenis    string whose delimiter is QUOTER.  Note that that format for printing
796b725ae77Skettenis    characters and strings is language specific. */
797b725ae77Skettenis 
798b725ae77Skettenis static void
java_emit_char(int c,struct ui_file * stream,int quoter)799b725ae77Skettenis java_emit_char (int c, struct ui_file *stream, int quoter)
800b725ae77Skettenis {
801b725ae77Skettenis   switch (c)
802b725ae77Skettenis     {
803b725ae77Skettenis     case '\\':
804b725ae77Skettenis     case '\'':
805b725ae77Skettenis       fprintf_filtered (stream, "\\%c", c);
806b725ae77Skettenis       break;
807b725ae77Skettenis     case '\b':
808b725ae77Skettenis       fputs_filtered ("\\b", stream);
809b725ae77Skettenis       break;
810b725ae77Skettenis     case '\t':
811b725ae77Skettenis       fputs_filtered ("\\t", stream);
812b725ae77Skettenis       break;
813b725ae77Skettenis     case '\n':
814b725ae77Skettenis       fputs_filtered ("\\n", stream);
815b725ae77Skettenis       break;
816b725ae77Skettenis     case '\f':
817b725ae77Skettenis       fputs_filtered ("\\f", stream);
818b725ae77Skettenis       break;
819b725ae77Skettenis     case '\r':
820b725ae77Skettenis       fputs_filtered ("\\r", stream);
821b725ae77Skettenis       break;
822b725ae77Skettenis     default:
823b725ae77Skettenis       if (isprint (c))
824b725ae77Skettenis 	fputc_filtered (c, stream);
825b725ae77Skettenis       else
826b725ae77Skettenis 	fprintf_filtered (stream, "\\u%.4x", (unsigned int) c);
827b725ae77Skettenis       break;
828b725ae77Skettenis     }
829b725ae77Skettenis }
830b725ae77Skettenis 
831b725ae77Skettenis static struct value *
evaluate_subexp_java(struct type * expect_type,struct expression * exp,int * pos,enum noside noside)832b725ae77Skettenis evaluate_subexp_java (struct type *expect_type, struct expression *exp,
833b725ae77Skettenis 		      int *pos, enum noside noside)
834b725ae77Skettenis {
835b725ae77Skettenis   int pc = *pos;
836b725ae77Skettenis   int i;
837b725ae77Skettenis   char *name;
838b725ae77Skettenis   enum exp_opcode op = exp->elts[*pos].opcode;
839b725ae77Skettenis   struct value *arg1;
840b725ae77Skettenis   struct value *arg2;
841b725ae77Skettenis   struct type *type;
842b725ae77Skettenis   switch (op)
843b725ae77Skettenis     {
844b725ae77Skettenis     case UNOP_IND:
845b725ae77Skettenis       if (noside == EVAL_SKIP)
846b725ae77Skettenis 	goto standard;
847b725ae77Skettenis       (*pos)++;
848b725ae77Skettenis       arg1 = evaluate_subexp_java (NULL_TYPE, exp, pos, EVAL_NORMAL);
849b725ae77Skettenis       if (is_object_type (VALUE_TYPE (arg1)))
850b725ae77Skettenis 	{
851b725ae77Skettenis 	  struct type *type;
852b725ae77Skettenis 
853b725ae77Skettenis 	  type = type_from_class (java_class_from_object (arg1));
854b725ae77Skettenis 	  arg1 = value_cast (lookup_pointer_type (type), arg1);
855b725ae77Skettenis 	}
856b725ae77Skettenis       if (noside == EVAL_SKIP)
857b725ae77Skettenis 	goto nosideret;
858b725ae77Skettenis       return value_ind (arg1);
859b725ae77Skettenis 
860b725ae77Skettenis     case BINOP_SUBSCRIPT:
861b725ae77Skettenis       (*pos)++;
862b725ae77Skettenis       arg1 = evaluate_subexp_with_coercion (exp, pos, noside);
863b725ae77Skettenis       arg2 = evaluate_subexp_with_coercion (exp, pos, noside);
864b725ae77Skettenis       if (noside == EVAL_SKIP)
865b725ae77Skettenis 	goto nosideret;
866b725ae77Skettenis       /* If the user attempts to subscript something that is not an
867b725ae77Skettenis          array or pointer type (like a plain int variable for example),
868b725ae77Skettenis          then report this as an error. */
869b725ae77Skettenis 
870b725ae77Skettenis       COERCE_REF (arg1);
871b725ae77Skettenis       type = check_typedef (VALUE_TYPE (arg1));
872b725ae77Skettenis       if (TYPE_CODE (type) == TYPE_CODE_PTR)
873b725ae77Skettenis 	type = check_typedef (TYPE_TARGET_TYPE (type));
874b725ae77Skettenis       name = TYPE_NAME (type);
875b725ae77Skettenis       if (name == NULL)
876b725ae77Skettenis 	name = TYPE_TAG_NAME (type);
877b725ae77Skettenis       i = name == NULL ? 0 : strlen (name);
878b725ae77Skettenis       if (TYPE_CODE (type) == TYPE_CODE_STRUCT
879b725ae77Skettenis 	  && i > 2 && name[i - 1] == ']')
880b725ae77Skettenis 	{
881b725ae77Skettenis 	  CORE_ADDR address;
882b725ae77Skettenis 	  long length, index;
883b725ae77Skettenis 	  struct type *el_type;
884b725ae77Skettenis 	  char buf4[4];
885b725ae77Skettenis 
886b725ae77Skettenis 	  struct value *clas = java_class_from_object (arg1);
887b725ae77Skettenis 	  struct value *temp = clas;
888b725ae77Skettenis 	  /* Get CLASS_ELEMENT_TYPE of the array type. */
889b725ae77Skettenis 	  temp = value_struct_elt (&temp, NULL, "methods",
890b725ae77Skettenis 				   NULL, "structure");
891b725ae77Skettenis 	  VALUE_TYPE (temp) = VALUE_TYPE (clas);
892b725ae77Skettenis 	  el_type = type_from_class (temp);
893b725ae77Skettenis 	  if (TYPE_CODE (el_type) == TYPE_CODE_STRUCT)
894b725ae77Skettenis 	    el_type = lookup_pointer_type (el_type);
895b725ae77Skettenis 
896b725ae77Skettenis 	  if (noside == EVAL_AVOID_SIDE_EFFECTS)
897b725ae77Skettenis 	    return value_zero (el_type, VALUE_LVAL (arg1));
898b725ae77Skettenis 	  address = value_as_address (arg1);
899b725ae77Skettenis 	  address += JAVA_OBJECT_SIZE;
900b725ae77Skettenis 	  read_memory (address, buf4, 4);
901b725ae77Skettenis 	  length = (long) extract_signed_integer (buf4, 4);
902b725ae77Skettenis 	  index = (long) value_as_long (arg2);
903b725ae77Skettenis 	  if (index >= length || index < 0)
904b725ae77Skettenis 	    error ("array index (%ld) out of bounds (length: %ld)",
905b725ae77Skettenis 		   index, length);
906b725ae77Skettenis 	  address = (address + 4) + index * TYPE_LENGTH (el_type);
907b725ae77Skettenis 	  return value_at (el_type, address, NULL);
908b725ae77Skettenis 	}
909b725ae77Skettenis       else if (TYPE_CODE (type) == TYPE_CODE_ARRAY)
910b725ae77Skettenis 	{
911b725ae77Skettenis 	  if (noside == EVAL_AVOID_SIDE_EFFECTS)
912b725ae77Skettenis 	    return value_zero (TYPE_TARGET_TYPE (type), VALUE_LVAL (arg1));
913b725ae77Skettenis 	  else
914b725ae77Skettenis 	    return value_subscript (arg1, arg2);
915b725ae77Skettenis 	}
916b725ae77Skettenis       if (name)
917b725ae77Skettenis 	error ("cannot subscript something of type `%s'", name);
918b725ae77Skettenis       else
919b725ae77Skettenis 	error ("cannot subscript requested type");
920b725ae77Skettenis 
921b725ae77Skettenis     case OP_STRING:
922b725ae77Skettenis       (*pos)++;
923b725ae77Skettenis       i = longest_to_int (exp->elts[pc + 1].longconst);
924b725ae77Skettenis       (*pos) += 3 + BYTES_TO_EXP_ELEM (i + 1);
925b725ae77Skettenis       if (noside == EVAL_SKIP)
926b725ae77Skettenis 	goto nosideret;
927b725ae77Skettenis       return java_value_string (&exp->elts[pc + 2].string, i);
928b725ae77Skettenis 
929b725ae77Skettenis     case STRUCTOP_STRUCT:
930b725ae77Skettenis       arg1 = evaluate_subexp_standard (expect_type, exp, pos, noside);
931b725ae77Skettenis       /* Convert object field (such as TYPE.class) to reference. */
932b725ae77Skettenis       if (TYPE_CODE (VALUE_TYPE (arg1)) == TYPE_CODE_STRUCT)
933b725ae77Skettenis 	arg1 = value_addr (arg1);
934b725ae77Skettenis       return arg1;
935b725ae77Skettenis     default:
936b725ae77Skettenis       break;
937b725ae77Skettenis     }
938b725ae77Skettenis standard:
939b725ae77Skettenis   return evaluate_subexp_standard (expect_type, exp, pos, noside);
940b725ae77Skettenis nosideret:
941b725ae77Skettenis   return value_from_longest (builtin_type_long, (LONGEST) 1);
942b725ae77Skettenis }
943b725ae77Skettenis 
944b725ae77Skettenis static struct type *
java_create_fundamental_type(struct objfile * objfile,int typeid)945b725ae77Skettenis java_create_fundamental_type (struct objfile *objfile, int typeid)
946b725ae77Skettenis {
947b725ae77Skettenis   switch (typeid)
948b725ae77Skettenis     {
949b725ae77Skettenis     case FT_VOID:
950b725ae77Skettenis       return java_void_type;
951b725ae77Skettenis     case FT_BOOLEAN:
952b725ae77Skettenis       return java_boolean_type;
953b725ae77Skettenis     case FT_CHAR:
954b725ae77Skettenis       return java_char_type;
955b725ae77Skettenis     case FT_FLOAT:
956b725ae77Skettenis       return java_float_type;
957b725ae77Skettenis     case FT_DBL_PREC_FLOAT:
958b725ae77Skettenis       return java_double_type;
959b725ae77Skettenis     case FT_BYTE:
960b725ae77Skettenis     case FT_SIGNED_CHAR:
961b725ae77Skettenis       return java_byte_type;
962b725ae77Skettenis     case FT_SHORT:
963b725ae77Skettenis     case FT_SIGNED_SHORT:
964b725ae77Skettenis       return java_short_type;
965b725ae77Skettenis     case FT_INTEGER:
966b725ae77Skettenis     case FT_SIGNED_INTEGER:
967b725ae77Skettenis       return java_int_type;
968b725ae77Skettenis     case FT_LONG:
969b725ae77Skettenis     case FT_SIGNED_LONG:
970b725ae77Skettenis       return java_long_type;
971b725ae77Skettenis     }
972b725ae77Skettenis   return c_create_fundamental_type (objfile, typeid);
973b725ae77Skettenis }
974b725ae77Skettenis 
java_demangle(const char * mangled,int options)975b725ae77Skettenis static char *java_demangle (const char *mangled, int options)
976b725ae77Skettenis {
977b725ae77Skettenis   return cplus_demangle (mangled, options | DMGL_JAVA);
978b725ae77Skettenis }
979b725ae77Skettenis 
980*11efff7fSkettenis /* Find the member function name of the demangled name NAME.  NAME
981*11efff7fSkettenis    must be a method name including arguments, in order to correctly
982*11efff7fSkettenis    locate the last component.
983*11efff7fSkettenis 
984*11efff7fSkettenis    This function return a pointer to the first dot before the
985*11efff7fSkettenis    member function name, or NULL if the name was not of the
986*11efff7fSkettenis    expected form.  */
987*11efff7fSkettenis 
988*11efff7fSkettenis static const char *
java_find_last_component(const char * name)989*11efff7fSkettenis java_find_last_component (const char *name)
990*11efff7fSkettenis {
991*11efff7fSkettenis   const char *p;
992*11efff7fSkettenis 
993*11efff7fSkettenis   /* Find argument list.  */
994*11efff7fSkettenis   p = strchr (name, '(');
995*11efff7fSkettenis 
996*11efff7fSkettenis   if (p == NULL)
997*11efff7fSkettenis     return NULL;
998*11efff7fSkettenis 
999*11efff7fSkettenis   /* Back up and find first dot prior to argument list.  */
1000*11efff7fSkettenis   while (p > name && *p != '.')
1001*11efff7fSkettenis     p--;
1002*11efff7fSkettenis 
1003*11efff7fSkettenis   if (p == name)
1004*11efff7fSkettenis     return NULL;
1005*11efff7fSkettenis 
1006*11efff7fSkettenis   return p;
1007*11efff7fSkettenis }
1008*11efff7fSkettenis 
1009*11efff7fSkettenis /* Return the name of the class containing method PHYSNAME.  */
1010*11efff7fSkettenis 
1011*11efff7fSkettenis static char *
java_class_name_from_physname(const char * physname)1012*11efff7fSkettenis java_class_name_from_physname (const char *physname)
1013*11efff7fSkettenis {
1014*11efff7fSkettenis   char *ret = NULL;
1015*11efff7fSkettenis   const char *end;
1016*11efff7fSkettenis   int depth = 0;
1017*11efff7fSkettenis   char *demangled_name = java_demangle (physname, DMGL_PARAMS | DMGL_ANSI);
1018*11efff7fSkettenis 
1019*11efff7fSkettenis   if (demangled_name == NULL)
1020*11efff7fSkettenis     return NULL;
1021*11efff7fSkettenis 
1022*11efff7fSkettenis   end = java_find_last_component (demangled_name);
1023*11efff7fSkettenis   if (end != NULL)
1024*11efff7fSkettenis     {
1025*11efff7fSkettenis       ret = xmalloc (end - demangled_name + 1);
1026*11efff7fSkettenis       memcpy (ret, demangled_name, end - demangled_name);
1027*11efff7fSkettenis       ret[end - demangled_name] = '\0';
1028*11efff7fSkettenis     }
1029*11efff7fSkettenis 
1030*11efff7fSkettenis   xfree (demangled_name);
1031*11efff7fSkettenis   return ret;
1032*11efff7fSkettenis }
1033b725ae77Skettenis 
1034b725ae77Skettenis /* Table mapping opcodes into strings for printing operators
1035b725ae77Skettenis    and precedences of the operators.  */
1036b725ae77Skettenis 
1037b725ae77Skettenis const struct op_print java_op_print_tab[] =
1038b725ae77Skettenis {
1039b725ae77Skettenis   {",", BINOP_COMMA, PREC_COMMA, 0},
1040b725ae77Skettenis   {"=", BINOP_ASSIGN, PREC_ASSIGN, 1},
1041b725ae77Skettenis   {"||", BINOP_LOGICAL_OR, PREC_LOGICAL_OR, 0},
1042b725ae77Skettenis   {"&&", BINOP_LOGICAL_AND, PREC_LOGICAL_AND, 0},
1043b725ae77Skettenis   {"|", BINOP_BITWISE_IOR, PREC_BITWISE_IOR, 0},
1044b725ae77Skettenis   {"^", BINOP_BITWISE_XOR, PREC_BITWISE_XOR, 0},
1045b725ae77Skettenis   {"&", BINOP_BITWISE_AND, PREC_BITWISE_AND, 0},
1046b725ae77Skettenis   {"==", BINOP_EQUAL, PREC_EQUAL, 0},
1047b725ae77Skettenis   {"!=", BINOP_NOTEQUAL, PREC_EQUAL, 0},
1048b725ae77Skettenis   {"<=", BINOP_LEQ, PREC_ORDER, 0},
1049b725ae77Skettenis   {">=", BINOP_GEQ, PREC_ORDER, 0},
1050b725ae77Skettenis   {">", BINOP_GTR, PREC_ORDER, 0},
1051b725ae77Skettenis   {"<", BINOP_LESS, PREC_ORDER, 0},
1052b725ae77Skettenis   {">>", BINOP_RSH, PREC_SHIFT, 0},
1053b725ae77Skettenis   {"<<", BINOP_LSH, PREC_SHIFT, 0},
1054b725ae77Skettenis #if 0
1055b725ae77Skettenis   {">>>", BINOP_ ? ? ?, PREC_SHIFT, 0},
1056b725ae77Skettenis #endif
1057b725ae77Skettenis   {"+", BINOP_ADD, PREC_ADD, 0},
1058b725ae77Skettenis   {"-", BINOP_SUB, PREC_ADD, 0},
1059b725ae77Skettenis   {"*", BINOP_MUL, PREC_MUL, 0},
1060b725ae77Skettenis   {"/", BINOP_DIV, PREC_MUL, 0},
1061b725ae77Skettenis   {"%", BINOP_REM, PREC_MUL, 0},
1062b725ae77Skettenis   {"-", UNOP_NEG, PREC_PREFIX, 0},
1063b725ae77Skettenis   {"!", UNOP_LOGICAL_NOT, PREC_PREFIX, 0},
1064b725ae77Skettenis   {"~", UNOP_COMPLEMENT, PREC_PREFIX, 0},
1065b725ae77Skettenis   {"*", UNOP_IND, PREC_PREFIX, 0},
1066b725ae77Skettenis #if 0
1067b725ae77Skettenis   {"instanceof", ? ? ?, ? ? ?, 0},
1068b725ae77Skettenis #endif
1069b725ae77Skettenis   {"++", UNOP_PREINCREMENT, PREC_PREFIX, 0},
1070b725ae77Skettenis   {"--", UNOP_PREDECREMENT, PREC_PREFIX, 0},
1071b725ae77Skettenis   {NULL, 0, 0, 0}
1072b725ae77Skettenis };
1073b725ae77Skettenis 
1074b725ae77Skettenis const struct exp_descriptor exp_descriptor_java =
1075b725ae77Skettenis {
1076b725ae77Skettenis   print_subexp_standard,
1077b725ae77Skettenis   operator_length_standard,
1078b725ae77Skettenis   op_name_standard,
1079b725ae77Skettenis   dump_subexp_body_standard,
1080b725ae77Skettenis   evaluate_subexp_java
1081b725ae77Skettenis };
1082b725ae77Skettenis 
1083b725ae77Skettenis const struct language_defn java_language_defn =
1084b725ae77Skettenis {
1085b725ae77Skettenis   "java",			/* Language name */
1086b725ae77Skettenis   language_java,
1087*11efff7fSkettenis   NULL,
1088b725ae77Skettenis   range_check_off,
1089b725ae77Skettenis   type_check_off,
1090b725ae77Skettenis   case_sensitive_on,
1091*11efff7fSkettenis   array_row_major,
1092b725ae77Skettenis   &exp_descriptor_java,
1093b725ae77Skettenis   java_parse,
1094b725ae77Skettenis   java_error,
1095*11efff7fSkettenis   null_post_parser,
1096b725ae77Skettenis   c_printchar,			/* Print a character constant */
1097b725ae77Skettenis   c_printstr,			/* Function to print string constant */
1098b725ae77Skettenis   java_emit_char,		/* Function to print a single character */
1099b725ae77Skettenis   java_create_fundamental_type,	/* Create fundamental type in this language */
1100b725ae77Skettenis   java_print_type,		/* Print a type using appropriate syntax */
1101b725ae77Skettenis   java_val_print,		/* Print a value using appropriate syntax */
1102b725ae77Skettenis   java_value_print,		/* Print a top-level value */
1103b725ae77Skettenis   NULL,				/* Language specific skip_trampoline */
1104b725ae77Skettenis   value_of_this,		/* value_of_this */
1105b725ae77Skettenis   basic_lookup_symbol_nonlocal,	/* lookup_symbol_nonlocal */
1106b725ae77Skettenis   basic_lookup_transparent_type,/* lookup_transparent_type */
1107b725ae77Skettenis   java_demangle,		/* Language specific symbol demangler */
1108*11efff7fSkettenis   java_class_name_from_physname,/* Language specific class name */
1109b725ae77Skettenis   java_op_print_tab,		/* expression operators for printing */
1110b725ae77Skettenis   0,				/* not c-style arrays */
1111b725ae77Skettenis   0,				/* String lower bound */
1112*11efff7fSkettenis   NULL,
1113b725ae77Skettenis   default_word_break_characters,
1114*11efff7fSkettenis   c_language_arch_info,
1115b725ae77Skettenis   LANG_MAGIC
1116b725ae77Skettenis };
1117b725ae77Skettenis 
1118b725ae77Skettenis void
_initialize_java_language(void)1119b725ae77Skettenis _initialize_java_language (void)
1120b725ae77Skettenis {
1121b725ae77Skettenis 
1122b725ae77Skettenis   java_int_type = init_type (TYPE_CODE_INT, 4, 0, "int", NULL);
1123b725ae77Skettenis   java_short_type = init_type (TYPE_CODE_INT, 2, 0, "short", NULL);
1124b725ae77Skettenis   java_long_type = init_type (TYPE_CODE_INT, 8, 0, "long", NULL);
1125b725ae77Skettenis   java_byte_type = init_type (TYPE_CODE_INT, 1, 0, "byte", NULL);
1126b725ae77Skettenis   java_boolean_type = init_type (TYPE_CODE_BOOL, 1, 0, "boolean", NULL);
1127b725ae77Skettenis   java_char_type = init_type (TYPE_CODE_CHAR, 2, TYPE_FLAG_UNSIGNED, "char", NULL);
1128b725ae77Skettenis   java_float_type = init_type (TYPE_CODE_FLT, 4, 0, "float", NULL);
1129b725ae77Skettenis   java_double_type = init_type (TYPE_CODE_FLT, 8, 0, "double", NULL);
1130b725ae77Skettenis   java_void_type = init_type (TYPE_CODE_VOID, 1, 0, "void", NULL);
1131b725ae77Skettenis 
1132b725ae77Skettenis   add_language (&java_language_defn);
1133b725ae77Skettenis }
1134b725ae77Skettenis 
1135b725ae77Skettenis /* Cleanup code that should be run on every "run".
1136b725ae77Skettenis    We should use make_run_cleanup to have this be called.
1137b725ae77Skettenis    But will that mess up values in value histry?  FIXME */
1138b725ae77Skettenis 
1139b725ae77Skettenis extern void java_rerun_cleanup (void);
1140b725ae77Skettenis void
java_rerun_cleanup(void)1141b725ae77Skettenis java_rerun_cleanup (void)
1142b725ae77Skettenis {
1143b725ae77Skettenis   if (class_symtab != NULL)
1144b725ae77Skettenis     {
1145b725ae77Skettenis       free_symtab (class_symtab);	/* ??? */
1146b725ae77Skettenis       class_symtab = NULL;
1147b725ae77Skettenis     }
1148b725ae77Skettenis   if (dynamics_objfile != NULL)
1149b725ae77Skettenis     {
1150b725ae77Skettenis       free_objfile (dynamics_objfile);
1151b725ae77Skettenis       dynamics_objfile = NULL;
1152b725ae77Skettenis     }
1153b725ae77Skettenis 
1154b725ae77Skettenis   java_object_type = NULL;
1155b725ae77Skettenis }
1156