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