]> gcc.gnu.org Git - gcc.git/blob - gcc/java/class.c
f05cf16099c06d0a490ae2014b4cb19875114167
[gcc.git] / gcc / java / class.c
1 /* Functions related to building classes and their related objects.
2 Copyright (C) 1996, 97-98, 1999 Free Software Foundation, Inc.
3
4 This file is part of GNU CC.
5
6 GNU CC is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 2, or (at your option)
9 any later version.
10
11 GNU CC is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
15
16 You should have received a copy of the GNU General Public License
17 along with GNU CC; see the file COPYING. If not, write to
18 the Free Software Foundation, 59 Temple Place - Suite 330,
19 Boston, MA 02111-1307, USA.
20
21 Java and all Java-based marks are trademarks or registered trademarks
22 of Sun Microsystems, Inc. in the United States and other countries.
23 The Free Software Foundation is independent of Sun Microsystems, Inc. */
24
25 /* Written by Per Bothner <bothner@cygnus.com> */
26
27 #include "config.h"
28 #include "system.h"
29 #include "tree.h"
30 #include "rtl.h"
31 #include "flags.h"
32 #include "java-tree.h"
33 #include "jcf.h"
34 #include "obstack.h"
35 #include "toplev.h"
36 #include "output.h"
37 #include "parse.h"
38
39 static tree mangle_class_field PROTO ((tree class));
40 static tree make_method_value PROTO ((tree));
41
42 static rtx registerClass_libfunc;
43
44 extern struct obstack permanent_obstack;
45 extern struct obstack temporary_obstack;
46
47 /* Return an IDENTIFIER_NODE the same as (OLD_NAME, OLD_LENGTH).
48 except that characters matching OLD_CHAR are substituted by NEW_CHAR.
49 Also, PREFIX is prepended, and SUFFIX is appended. */
50
51 tree
52 ident_subst (old_name, old_length, prefix, old_char, new_char, suffix)
53 const char* old_name;
54 int old_length;
55 const char *prefix;
56 int old_char;
57 int new_char;
58 const char *suffix;
59 {
60 int prefix_len = strlen (prefix);
61 int suffix_len = strlen (suffix);
62 int i = prefix_len + old_length + suffix_len + 1;
63 #ifdef __GNUC__
64 char buffer[i];
65 #else
66 char *buffer = (char *)alloca (i);
67 #endif
68 strcpy (buffer, prefix);
69 for (i = 0; i < old_length; i++)
70 {
71 char ch = old_name[i];
72 if (ch == old_char)
73 ch = new_char;
74 buffer[prefix_len + i] = ch;
75 }
76 strcpy (buffer + prefix_len + old_length, suffix);
77 return get_identifier (buffer);
78 }
79
80 /* Return an IDENTIFIER_NODE the same as OLD_ID,
81 except that characters matching OLD_CHAR are substituted by NEW_CHAR.
82 Also, PREFIX is prepended, and SUFFIX is appended. */
83
84 tree
85 identifier_subst (old_id, prefix, old_char, new_char, suffix)
86 const tree old_id;
87 const char *prefix;
88 int old_char;
89 int new_char;
90 const char *suffix;
91 {
92 return ident_subst (IDENTIFIER_POINTER (old_id), IDENTIFIER_LENGTH (old_id),
93 prefix, old_char, new_char, suffix);
94 }
95
96 /* Generate a valid C identifier from the name of the class TYPE,
97 prefixed by PREFIX. */
98
99 tree
100 mangled_classname (prefix, type)
101 const char *prefix;
102 tree type;
103 {
104 tree ident = TYPE_NAME (type);
105 if (TREE_CODE (ident) != IDENTIFIER_NODE)
106 ident = DECL_NAME (ident);
107 return identifier_subst (ident, prefix, '.', '_', "");
108 }
109
110 tree
111 make_class ()
112 {
113 tree type;
114 push_obstacks (&permanent_obstack, &permanent_obstack);
115 type = make_node (RECORD_TYPE);
116 #ifdef JAVA_USE_HANDLES
117 tree field1 = build_decl (FIELD_DECL, get_identifier ("obj"),
118 build_pointer_type (type));
119 tree field2 = build_decl (FIELD_DECL, get_identifier ("methods"),
120 methodtable_ptr_type);
121 tree handle_type = make_node (RECORD_TYPE);
122 TREE_CHAIN (field1) = field2;
123 TYPE_FIELDS (handle_type) = field1;
124 TYPE_BINFO (type) = make_tree_vec (7);
125 TYPE_BINFO (handle_type) = make_tree_vec (7);
126 BINFO_HANDLE (TYPE_BINFO (handle_type)) = type;
127 BINFO_HANDLE (TYPE_BINFO (type)) = handle_type;
128 #else
129 TYPE_BINFO (type) = make_tree_vec (6);
130 #endif
131 CLASS_P (type) = 1;
132 pop_obstacks ();
133
134 return type;
135 }
136
137 /* Given a fully-qualified classname in NAME (whose length is NAME_LENGTH),
138 and where each of the constituents is separated by '/',
139 return a corresponding IDENTIFIER_NODE, except using '.' as separator. */
140
141 tree
142 unmangle_classname (name, name_length)
143 const char *name; int name_length;
144 {
145 tree to_return = ident_subst (name, name_length, "", '/', '.', "");
146 if (to_return != get_identifier ((char *)name))
147 QUALIFIED_P (to_return) = 1;
148 return to_return;
149 }
150
151 tree
152 push_class (class_type, class_name)
153 tree class_type, class_name;
154 {
155 tree decl, signature;
156 char *save_input_filename = input_filename;
157 int save_lineno = lineno;
158 tree source_name = identifier_subst (class_name, "", '.', '/', ".java");
159 push_obstacks (&permanent_obstack, &permanent_obstack);
160 input_filename = IDENTIFIER_POINTER (source_name);
161 lineno = 0;
162 decl = build_decl (TYPE_DECL, class_name, class_type);
163 input_filename = save_input_filename;
164 lineno = save_lineno;
165 signature = identifier_subst (class_name, "L", '.', '/', ";");
166 IDENTIFIER_SIGNATURE_TYPE (signature) = build_pointer_type (class_type);
167
168 /* Setting DECL_ARTIFICAL forces dbxout.c to specific the type is
169 both a typedef and in the struct name-space. We may want to re-visit
170 this later, but for now it reduces the changes needed for gdb. */
171 DECL_ARTIFICIAL (decl) = 1;
172
173 pushdecl_top_level (decl);
174 #ifdef JAVA_USE_HANDLES
175 {
176 tree handle_name = identifier_subst (class_name,
177 "Handle$", '.', '.', "");
178 tree handle_decl = build_decl (TYPE_DECL, handle_name,
179 CLASS_TO_HANDLE_TYPE (class_type));
180 pushdecl (handle_decl);
181 }
182 #endif
183
184 pop_obstacks ();
185 return decl;
186 }
187
188 /* Finds the (global) class named NAME. Creates the class if not found.
189 Also creates associated TYPE_DECL.
190 Does not check if the class actually exists, load the class,
191 fill in field or methods, or do layout_type. */
192
193 tree
194 lookup_class (name)
195 tree name;
196 {
197 tree decl = IDENTIFIER_CLASS_VALUE (name);
198 if (decl == NULL_TREE)
199 decl = push_class (make_class (), name);
200 return TREE_TYPE (decl);
201 }
202
203 void
204 set_super_info (access_flags, this_class, super_class, interfaces_count)
205 int access_flags;
206 tree this_class;
207 tree super_class;
208 int interfaces_count;
209 {
210 int total_supers = interfaces_count;
211 tree class_decl = TYPE_NAME (this_class);
212 if (super_class)
213 total_supers++;
214
215 push_obstacks (&permanent_obstack, &permanent_obstack);
216 TYPE_BINFO_BASETYPES (this_class) = make_tree_vec (total_supers);
217 if (super_class)
218 {
219 tree super_binfo = make_tree_vec (6);
220 BINFO_TYPE (super_binfo) = super_class;
221 BINFO_OFFSET (super_binfo) = integer_zero_node;
222 TREE_VIA_PUBLIC (super_binfo) = 1;
223 TREE_VEC_ELT (BINFO_BASETYPES (TYPE_BINFO (this_class)), 0)
224 = super_binfo;
225 CLASS_HAS_SUPER (this_class) = 1;
226 }
227 pop_obstacks ();
228
229 if (access_flags & ACC_PUBLIC) CLASS_PUBLIC (class_decl) = 1;
230 if (access_flags & ACC_FINAL) CLASS_FINAL (class_decl) = 1;
231 if (access_flags & ACC_SUPER) CLASS_SUPER (class_decl) = 1;
232 if (access_flags & ACC_INTERFACE) CLASS_INTERFACE (class_decl) = 1;
233 if (access_flags & ACC_ABSTRACT) CLASS_ABSTRACT (class_decl) = 1;
234 }
235
236 /* Return length of inheritance chain of CLAS, where java.lang.Object is 0,
237 direct sub-classes of Object are 1, and so on. */
238
239 int
240 class_depth (clas)
241 tree clas;
242 {
243 int depth = 0;
244 if (! CLASS_LOADED_P (clas))
245 load_class (clas, 1);
246 while (clas != object_type_node)
247 {
248 depth++;
249 clas = TYPE_BINFO_BASETYPE (clas, 0);
250 }
251 return depth;
252 }
253
254 /* Return true iff TYPE2 is an interface that extends interface TYPE1 */
255
256 int
257 interface_of_p (type1, type2)
258 tree type1, type2;
259 {
260 int n, i;
261 tree basetype_vec;
262
263 if (!(basetype_vec = TYPE_BINFO_BASETYPES (type2)))
264 return 0;
265 n = TREE_VEC_LENGTH (basetype_vec);
266 for (i = 0; i < n; i++)
267 {
268 tree vec_elt = TREE_VEC_ELT (basetype_vec, i);
269 if (vec_elt && BINFO_TYPE (vec_elt) == type1)
270 return 1;
271 }
272 for (i = 0; i < n; i++)
273 {
274 tree vec_elt = TREE_VEC_ELT (basetype_vec, i);
275 if (vec_elt && BINFO_TYPE (vec_elt)
276 && interface_of_p (type1, BINFO_TYPE (vec_elt)))
277 return 1;
278 }
279 return 0;
280 }
281
282 /* Return true iff TYPE1 inherits from TYPE2. */
283
284 int
285 inherits_from_p (type1, type2)
286 tree type1, type2;
287 {
288 while (type1 != NULL_TREE && TREE_CODE (type1) == RECORD_TYPE)
289 {
290 if (type1 == type2)
291 return 1;
292 type1 = CLASSTYPE_SUPER (type1);
293 }
294 return 0;
295 }
296
297 static void
298 add_interface_do (basetype_vec, interface_class, i)
299 tree basetype_vec, interface_class;
300 int i;
301 {
302 tree interface_binfo = make_tree_vec (6);
303 BINFO_TYPE (interface_binfo) = interface_class;
304 BINFO_OFFSET (interface_binfo) = integer_zero_node;
305 TREE_VIA_VIRTUAL (interface_binfo) = 1;
306 TREE_VIA_PUBLIC (interface_binfo) = 1;
307 TREE_VEC_ELT (basetype_vec, i) = interface_binfo;
308 }
309
310 /* Add INTERFACE_CLASS to THIS_CLASS iff INTERFACE_CLASS can't be
311 found in THIS_CLASS. Returns NULL_TREE upon success, INTERFACE_CLASS
312 if attempt is made to add it twice. */
313
314 tree
315 maybe_add_interface (this_class, interface_class)
316 tree this_class, interface_class;
317 {
318 tree basetype_vec = TYPE_BINFO_BASETYPES (this_class);
319 tree interface_binfo = make_tree_vec (6);
320 int i;
321 int n = TREE_VEC_LENGTH (basetype_vec);
322 for (i = 0; ; i++)
323 {
324 if (i >= n)
325 {
326 error ("internal error - too many interface type");
327 return NULL_TREE;
328 }
329 else if (TREE_VEC_ELT (basetype_vec, i) == NULL_TREE)
330 break;
331 else if (BINFO_TYPE (TREE_VEC_ELT (basetype_vec, i)) == interface_class)
332 return interface_class;
333 }
334 add_interface_do (basetype_vec, interface_class, i);
335 return NULL_TREE;
336 }
337
338 /* Add the INTERFACE_CLASS as one of the interfaces of THIS_CLASS. */
339
340 void
341 add_interface (this_class, interface_class)
342 tree this_class, interface_class;
343 {
344 tree basetype_vec = TYPE_BINFO_BASETYPES (this_class);
345 int i;
346 int n = TREE_VEC_LENGTH (basetype_vec);
347 for (i = 0; ; i++)
348 {
349 if (i >= n)
350 {
351 error ("internal error - too many interface type");
352 return;
353 }
354 else if (TREE_VEC_ELT (basetype_vec, i) == NULL_TREE)
355 break;
356 }
357 add_interface_do (basetype_vec, interface_class, i);
358 }
359
360 #if 0
361 /* Return the address of a pointer to the first FUNCTION_DECL
362 in the list (*LIST) whose DECL_NAME is NAME. */
363
364 static tree *
365 find_named_method (list, name)
366 tree *list;
367 tree name;
368 {
369 while (*list && DECL_NAME (*list) != name)
370 list = &TREE_CHAIN (*list);
371 return list;
372 }
373 #endif
374
375 tree
376 build_java_method_type (fntype, this_class, access_flags)
377 tree fntype;
378 tree this_class;
379 int access_flags;
380 {
381 if (access_flags & ACC_STATIC)
382 return fntype;
383 return build_method_type (CLASS_TO_HANDLE_TYPE (this_class), fntype);
384 }
385
386 tree
387 add_method_1 (handle_class, access_flags, name, function_type)
388 tree handle_class;
389 int access_flags;
390 tree name;
391 tree function_type;
392 {
393 tree method_type, fndecl;
394 push_obstacks (&permanent_obstack, &permanent_obstack);
395
396 method_type = build_java_method_type (function_type,
397 handle_class, access_flags);
398
399 fndecl = build_decl (FUNCTION_DECL, name, method_type);
400 DECL_CONTEXT (fndecl) = handle_class;
401
402 DECL_LANG_SPECIFIC (fndecl)
403 = (struct lang_decl *) permalloc (sizeof (struct lang_decl));
404 bzero (DECL_LANG_SPECIFIC (fndecl), sizeof (struct lang_decl));
405
406 TREE_CHAIN (fndecl) = TYPE_METHODS (handle_class);
407 TYPE_METHODS (handle_class) = fndecl;
408 pop_obstacks ();
409
410 if (access_flags & ACC_PUBLIC) METHOD_PUBLIC (fndecl) = 1;
411 if (access_flags & ACC_PROTECTED) METHOD_PROTECTED (fndecl) = 1;
412 if (access_flags & ACC_PRIVATE) METHOD_PRIVATE (fndecl) = 1;
413 if (access_flags & ACC_NATIVE) METHOD_NATIVE (fndecl) = 1;
414 if (access_flags & ACC_STATIC) METHOD_STATIC (fndecl) = 1;
415 if (access_flags & ACC_FINAL) METHOD_FINAL (fndecl) = 1;
416 if (access_flags & ACC_SYNCHRONIZED) METHOD_SYNCHRONIZED (fndecl) = 1;
417 if (access_flags & ACC_ABSTRACT) METHOD_ABSTRACT (fndecl) = 1;
418 if (access_flags & ACC_TRANSIENT) METHOD_TRANSIENT (fndecl) = 1;
419 return fndecl;
420 }
421
422 /* Add a method to THIS_CLASS.
423 The method's name is NAME.
424 Its signature (mangled type) is METHOD_SIG (an IDENTIFIER_NODE). */
425
426 tree
427 add_method (this_class, access_flags, name, method_sig)
428 tree this_class;
429 int access_flags;
430 tree name;
431 tree method_sig;
432 {
433 tree handle_class = CLASS_TO_HANDLE_TYPE (this_class);
434 tree function_type, fndecl;
435 unsigned char *sig = (unsigned char*)IDENTIFIER_POINTER (method_sig);
436 push_obstacks (&permanent_obstack, &permanent_obstack);
437 if (sig[0] != '(')
438 fatal ("bad method signature");
439 function_type = get_type_from_signature (method_sig);
440 fndecl = add_method_1 (handle_class, access_flags, name, function_type);
441 set_java_signature (TREE_TYPE (fndecl), method_sig);
442 pop_obstacks ();
443 return fndecl;
444 }
445
446 tree
447 add_field (class, name, field_type, flags)
448 tree class;
449 tree name;
450 tree field_type;
451 int flags;
452 {
453 int is_static = (flags & ACC_STATIC) != 0;
454 tree field;
455 /* Push the obstack of field_type ? FIXME */
456 push_obstacks (&permanent_obstack, &permanent_obstack);
457 field = build_decl (is_static ? VAR_DECL : FIELD_DECL, name, field_type);
458 pop_obstacks ();
459 TREE_CHAIN (field) = TYPE_FIELDS (class);
460 TYPE_FIELDS (class) = field;
461 DECL_CONTEXT (field) = class;
462
463 if (flags & ACC_PUBLIC) FIELD_PUBLIC (field) = 1;
464 if (flags & ACC_PROTECTED) FIELD_PROTECTED (field) = 1;
465 if (flags & ACC_PRIVATE) FIELD_PRIVATE (field) = 1;
466 if (flags & ACC_FINAL) FIELD_FINAL (field) = 1;
467 if (flags & ACC_VOLATILE) FIELD_VOLATILE (field) = 1;
468 if (flags & ACC_TRANSIENT) FIELD_TRANSIENT (field) = 1;
469 if (is_static)
470 {
471 FIELD_STATIC (field) = 1;
472 /* Always make field externally visible. This is required so
473 that native methods can always access the field. */
474 TREE_PUBLIC (field) = 1;
475 }
476 return field;
477 }
478
479 /* Associate a constant value CONSTANT with VAR_DECL FIELD. */
480
481 void
482 set_constant_value (field, constant)
483 tree field, constant;
484 {
485 if (field == NULL_TREE)
486 warning ("misplaced ConstantValue attribute (not in any field)");
487 else if (DECL_INITIAL (field) != NULL_TREE)
488 warning ("duplicate ConstanValue atribute for field '%s'",
489 IDENTIFIER_POINTER (DECL_NAME (field)));
490 else
491 DECL_INITIAL (field) = constant;
492 }
493
494 /* Count the number of Unicode chars encoded in a given Ut8 string. */
495
496 int
497 strLengthUtf8 (str, len)
498 char *str;
499 int len;
500 {
501 register unsigned char* ptr = (unsigned char*) str;
502 register unsigned char *limit = ptr + len;
503 int str_length = 0;
504 for (; ptr < limit; str_length++) {
505 if (UTF8_GET (ptr, limit) < 0)
506 return -1;
507 }
508 return str_length;
509 }
510
511
512 /* Calculate a hash value for a string encoded in Utf8 format.
513 * This returns the same hash value as specified for java.lang.String.hashCode.
514 */
515
516 int32
517 hashUtf8String (str, len)
518 char *str;
519 int len;
520 {
521 register unsigned char* ptr = (unsigned char*) str;
522 register unsigned char *limit = ptr + len;
523 int32 hash = 0;
524 for (; ptr < limit;)
525 {
526 int ch = UTF8_GET (ptr, limit);
527 /* Updated specification from
528 http://www.javasoft.com/docs/books/jls/clarify.html. */
529 hash = (31 * hash) + ch;
530 }
531 return hash;
532 }
533
534 tree utf8_decl_list = NULL_TREE;
535
536 tree
537 build_utf8_ref (name)
538 tree name;
539 {
540 char* name_ptr = IDENTIFIER_POINTER(name);
541 int name_len = IDENTIFIER_LENGTH(name);
542 char buf[60];
543 char *buf_ptr;
544 tree ctype, field, str_type, cinit, string;
545 static int utf8_count = 0;
546 int name_hash;
547 tree ref = IDENTIFIER_UTF8_REF (name);
548 tree decl;
549 if (ref != NULL_TREE)
550 return ref;
551
552 push_obstacks (&permanent_obstack, &permanent_obstack);
553 ctype = make_node (RECORD_TYPE);
554 str_type = build_prim_array_type (unsigned_byte_type_node,
555 name_len + 1); /* Allow for final '\0'. */
556 PUSH_FIELD (ctype, field, "hash", unsigned_short_type_node);
557 PUSH_FIELD (ctype, field, "length", unsigned_short_type_node);
558 PUSH_FIELD (ctype, field, "data", str_type);
559 FINISH_RECORD (ctype);
560 START_RECORD_CONSTRUCTOR (cinit, ctype);
561 name_hash = hashUtf8String (name_ptr, name_len) & 0xFFFF;
562 PUSH_FIELD_VALUE (cinit, "hash", build_int_2 (name_hash, 0));
563 PUSH_FIELD_VALUE (cinit, "length", build_int_2 (name_len, 0));
564 string = build_string (name_len, name_ptr);
565 TREE_TYPE (string) = str_type;
566 PUSH_FIELD_VALUE (cinit, "data", string);
567 FINISH_RECORD_CONSTRUCTOR (cinit);
568
569 /* Build a unique identifier based on buf. */
570 sprintf(buf, "_Utf%d", ++utf8_count);
571 buf_ptr = &buf[strlen (buf)];
572 if (name_len > 0 && name_ptr[0] >= '0' && name_ptr[0] <= '9')
573 *buf_ptr++ = '_';
574 while (--name_len >= 0)
575 {
576 unsigned char c = *name_ptr++;
577 if (c & 0x80)
578 continue;
579 if (!ISALPHA(c) && !ISDIGIT(c))
580 c = '_';
581 *buf_ptr++ = c;
582 if (buf_ptr >= buf + 50)
583 break;
584 }
585 *buf_ptr = '\0';
586
587 decl = build_decl (VAR_DECL, get_identifier (buf), utf8const_type);
588 /* FIXME get some way to force this into .text, not .data. */
589 TREE_STATIC (decl) = 1;
590 DECL_ARTIFICIAL (decl) = 1;
591 DECL_IGNORED_P (decl) = 1;
592 TREE_READONLY (decl) = 1;
593 DECL_INITIAL (decl) = cinit;
594 TREE_CHAIN (decl) = utf8_decl_list;
595 layout_decl (decl, 0);
596 pushdecl (decl);
597 rest_of_decl_compilation (decl, (char*) 0, global_bindings_p (), 0);
598 utf8_decl_list = decl;
599 make_decl_rtl (decl, (char*) 0, 1);
600 ref = build1 (ADDR_EXPR, utf8const_ptr_type, decl);
601 IDENTIFIER_UTF8_REF (name) = ref;
602 pop_obstacks ();
603 return ref;
604 }
605
606 /* Build a reference to the class TYPE.
607 Also handles primitive types and array types. */
608
609 tree
610 build_class_ref (type)
611 tree type;
612 {
613 int is_compiled = is_compiled_class (type);
614 if (is_compiled)
615 {
616 tree ref, decl_name, decl;
617 if (TREE_CODE (type) == POINTER_TYPE)
618 type = TREE_TYPE (type);
619 if (TREE_CODE (type) == RECORD_TYPE)
620 {
621 if (TYPE_SIZE (type) == error_mark_node)
622 return null_pointer_node;
623 decl_name = identifier_subst (DECL_NAME (TYPE_NAME (type)),
624 "", '/', '/', ".class");
625 decl = IDENTIFIER_GLOBAL_VALUE (decl_name);
626 if (decl == NULL_TREE)
627 {
628 push_obstacks (&permanent_obstack, &permanent_obstack);
629 decl = build_decl (VAR_DECL, decl_name, class_type_node);
630 DECL_SIZE (decl) = TYPE_SIZE (class_type_node);
631 TREE_STATIC (decl) = 1;
632 TREE_PUBLIC (decl) = 1;
633 DECL_IGNORED_P (decl) = 1;
634 DECL_ARTIFICIAL (decl) = 1;
635 DECL_ASSEMBLER_NAME (decl) = mangle_class_field (type);
636 make_decl_rtl (decl, NULL, 1);
637 pushdecl_top_level (decl);
638 if (is_compiled == 1)
639 DECL_EXTERNAL (decl) = 1;
640 pop_obstacks ();
641 }
642 }
643 else
644 {
645 char *name;
646 char buffer[25];
647 if (flag_emit_class_files)
648 {
649 const char *prim_class_name;
650 tree prim_class;
651 if (type == char_type_node)
652 prim_class_name = "java.lang.Character";
653 else if (type == boolean_type_node)
654 prim_class_name = "java.lang.Boolean";
655 else if (type == byte_type_node)
656 prim_class_name = "java.lang.Byte";
657 else if (type == short_type_node)
658 prim_class_name = "java.lang.Short";
659 else if (type == int_type_node)
660 prim_class_name = "java.lang.Integer";
661 else if (type == long_type_node)
662 prim_class_name = "java.lang.Long";
663 else if (type == float_type_node)
664 prim_class_name = "java.lang.Float";
665 else if (type == double_type_node)
666 prim_class_name = "java.lang.Double";
667 else if (type == void_type_node)
668 prim_class_name = "java.lang.Void";
669 else
670 fatal ("internal error - bad type to build_class_ref");
671 prim_class = lookup_class (get_identifier (prim_class_name));
672 return build (COMPONENT_REF, NULL_TREE,
673 prim_class, TYPE_identifier_node);
674 }
675 decl_name = TYPE_NAME (type);
676 if (TREE_CODE (decl_name) == TYPE_DECL)
677 decl_name = DECL_NAME (decl_name);
678 name = IDENTIFIER_POINTER (decl_name);
679 if (strncmp (name, "promoted_", 9) == 0)
680 name += 9;
681 sprintf (buffer, "_Jv_%sClass", name);
682 decl_name = get_identifier (buffer);
683 decl = IDENTIFIER_GLOBAL_VALUE (decl_name);
684 if (decl == NULL_TREE)
685 {
686 push_obstacks (&permanent_obstack, &permanent_obstack);
687 decl = build_decl (VAR_DECL, decl_name, class_type_node);
688 TREE_STATIC (decl) = 1;
689 TREE_PUBLIC (decl) = 1;
690 make_decl_rtl (decl, NULL, 1);
691 pushdecl_top_level (decl);
692 if (is_compiled == 1)
693 DECL_EXTERNAL (decl) = 1;
694 pop_obstacks ();
695 }
696 }
697
698 ref = build1 (ADDR_EXPR, class_ptr_type, decl);
699 return ref;
700 }
701 else
702 {
703 int index;
704 tree cl;
705 push_obstacks (&permanent_obstack, &permanent_obstack);
706 index = alloc_class_constant (type);
707 cl = build_ref_from_constant_pool (index);
708 TREE_TYPE (cl) = promote_type (class_ptr_type);
709 pop_obstacks ();
710 return cl;
711 }
712 }
713
714 tree
715 build_static_field_ref (fdecl)
716 tree fdecl;
717 {
718 tree fclass = DECL_CONTEXT (fdecl);
719 int is_compiled = is_compiled_class (fclass);
720 if (is_compiled)
721 {
722 if (DECL_RTL (fdecl) == 0)
723 {
724 push_obstacks (&permanent_obstack, &permanent_obstack);
725 make_decl_rtl (fdecl, NULL, 1);
726 pop_obstacks ();
727 if (is_compiled == 1)
728 DECL_EXTERNAL (fdecl) = 1;
729 }
730 return fdecl;
731 }
732 else
733 {
734 /* Compile as:
735 * *(FTYPE*)build_class_ref(FCLASS)->fields[INDEX].info.addr
736 */
737 static tree fields_ident = NULL_TREE;
738 static tree info_ident = NULL_TREE;
739 tree ref = build_class_ref (fclass);
740 tree fld;
741 int field_index = 0;
742 ref = build1 (INDIRECT_REF, class_type_node, ref);
743 if (fields_ident == NULL_TREE)
744 fields_ident = get_identifier ("fields");
745 if (info_ident == NULL_TREE)
746 info_ident = get_identifier ("info");
747 ref = build (COMPONENT_REF, field_ptr_type_node, ref,
748 lookup_field (&class_type_node, fields_ident));
749
750 for (fld = TYPE_FIELDS (fclass); ; fld = TREE_CHAIN (fld))
751 {
752 if (fld == fdecl)
753 break;
754 if (fld == NULL_TREE)
755 fatal ("field '%s' not found in class",
756 IDENTIFIER_POINTER (DECL_NAME (fdecl)));
757 if (FIELD_STATIC (fld))
758 field_index++;
759 }
760 field_index *= int_size_in_bytes (field_type_node);
761 ref = fold (build (PLUS_EXPR, field_ptr_type_node,
762 ref, build_int_2 (field_index, 0)));
763 ref = build1 (INDIRECT_REF, field_type_node, ref);
764 ref = build (COMPONENT_REF, field_info_union_node,
765 ref, lookup_field (&field_type_node, info_ident));
766 ref = build (COMPONENT_REF, ptr_type_node,
767 ref, TREE_CHAIN (TYPE_FIELDS (field_info_union_node)));
768 return fold (build1 (INDIRECT_REF, TREE_TYPE(fdecl), ref));
769 }
770 }
771
772 int
773 get_access_flags_from_decl (decl)
774 tree decl;
775 {
776 int access_flags = 0;
777 if (TREE_CODE (decl) == FIELD_DECL || TREE_CODE (decl) == VAR_DECL)
778 {
779 if (FIELD_STATIC (decl))
780 access_flags |= ACC_STATIC;
781 if (FIELD_PUBLIC (decl))
782 access_flags |= ACC_PUBLIC;
783 if (FIELD_PROTECTED (decl))
784 access_flags |= ACC_PROTECTED;
785 if (FIELD_PRIVATE (decl))
786 access_flags |= ACC_PRIVATE;
787 if (FIELD_FINAL (decl))
788 access_flags |= ACC_FINAL;
789 if (FIELD_VOLATILE (decl))
790 access_flags |= ACC_VOLATILE;
791 if (FIELD_TRANSIENT (decl))
792 access_flags |= ACC_TRANSIENT;
793 return access_flags;
794 }
795 if (TREE_CODE (decl) == TYPE_DECL)
796 {
797 if (CLASS_PUBLIC (decl))
798 access_flags |= ACC_PUBLIC;
799 if (CLASS_FINAL (decl))
800 access_flags |= ACC_FINAL;
801 if (CLASS_SUPER (decl))
802 access_flags |= ACC_SUPER;
803 if (CLASS_INTERFACE (decl))
804 access_flags |= ACC_INTERFACE;
805 if (CLASS_ABSTRACT (decl))
806 access_flags |= ACC_ABSTRACT;
807 return access_flags;
808 }
809 if (TREE_CODE (decl) == FUNCTION_DECL)
810 {
811 if (METHOD_PUBLIC (decl))
812 access_flags |= ACC_PUBLIC;
813 if (METHOD_PRIVATE (decl))
814 access_flags |= ACC_PRIVATE;
815 if (METHOD_PROTECTED (decl))
816 access_flags |= ACC_PROTECTED;
817 if (METHOD_STATIC (decl))
818 access_flags |= ACC_STATIC;
819 if (METHOD_FINAL (decl))
820 access_flags |= ACC_FINAL;
821 if (METHOD_SYNCHRONIZED (decl))
822 access_flags |= ACC_SYNCHRONIZED;
823 if (METHOD_NATIVE (decl))
824 access_flags |= ACC_NATIVE;
825 if (METHOD_ABSTRACT (decl))
826 access_flags |= ACC_ABSTRACT;
827 if (METHOD_TRANSIENT (decl))
828 access_flags |= ACC_TRANSIENT;
829 return access_flags;
830 }
831 abort ();
832 }
833
834 tree
835 make_field_value (tree fdecl)
836 {
837 tree finit, info;
838 int bsize, flags;
839 tree type = TREE_TYPE (fdecl);
840 int resolved = is_compiled_class (type);
841 START_RECORD_CONSTRUCTOR (finit, field_type_node);
842 PUSH_FIELD_VALUE (finit, "name", build_utf8_ref (DECL_NAME (fdecl)));
843 if (resolved)
844 type = build_class_ref (type);
845 else
846 {
847 tree signature = build_java_signature (type);
848 type = build_utf8_ref (unmangle_classname
849 (IDENTIFIER_POINTER(signature),
850 IDENTIFIER_LENGTH(signature)));
851 }
852 PUSH_FIELD_VALUE (finit, "type", type);
853 flags = get_access_flags_from_decl (fdecl);
854 if (! resolved)
855 flags |= 0x8000 /* FIELD_UNRESOLVED_FLAG */;
856 PUSH_FIELD_VALUE (finit, "accflags", build_int_2 (flags, 0));
857 bsize = TREE_INT_CST_LOW (TYPE_SIZE (TREE_TYPE (fdecl))) / BITS_PER_UNIT;
858 PUSH_FIELD_VALUE (finit, "bsize", build_int_2 (bsize, 0));
859 if (FIELD_STATIC (fdecl))
860 {
861 tree cfield = TREE_CHAIN (TYPE_FIELDS(field_info_union_node));
862 tree faddr = build_address_of (build_static_field_ref (fdecl));
863 info = build (CONSTRUCTOR, field_info_union_node, NULL_TREE,
864 build_tree_list (cfield, faddr));
865 }
866 else
867 {
868 int boffset
869 = TREE_INT_CST_LOW (DECL_FIELD_BITPOS (fdecl)) / BITS_PER_UNIT;
870 info = build (CONSTRUCTOR, field_info_union_node, NULL_TREE,
871 build_tree_list (TYPE_FIELDS(field_info_union_node),
872 build_int_2 (boffset, 0)));
873 }
874 PUSH_FIELD_VALUE (finit, "info", info);
875
876 FINISH_RECORD_CONSTRUCTOR (finit);
877 return finit;
878 }
879
880 static tree
881 make_method_value (mdecl)
882 tree mdecl;
883 {
884 tree minit;
885 tree code;
886 #define ACC_TRANSLATED 0x4000
887 int accflags = get_access_flags_from_decl (mdecl) | ACC_TRANSLATED;
888 code = null_pointer_node;
889 if (DECL_RTL (mdecl))
890 code = build1 (ADDR_EXPR, nativecode_ptr_type_node, mdecl);
891 START_RECORD_CONSTRUCTOR (minit, method_type_node);
892 PUSH_FIELD_VALUE (minit, "name",
893 build_utf8_ref (DECL_CONSTRUCTOR_P (mdecl) ?
894 init_identifier_node
895 : DECL_NAME (mdecl)));
896 {
897 tree signature = build_java_signature (TREE_TYPE (mdecl));
898 PUSH_FIELD_VALUE (minit, "signature",
899 (build_utf8_ref
900 (unmangle_classname
901 (IDENTIFIER_POINTER(signature),
902 IDENTIFIER_LENGTH(signature)))));
903 }
904 PUSH_FIELD_VALUE (minit, "accflags", build_int_2 (accflags, 0));
905 PUSH_FIELD_VALUE (minit, "ncode", code);
906 FINISH_RECORD_CONSTRUCTOR (minit);
907 return minit;
908 }
909
910 tree
911 get_dispatch_vector (type)
912 tree type;
913 {
914 tree vtable = TYPE_VTABLE (type);
915 if (vtable == NULL)
916 {
917 int i;
918 tree method;
919 tree super = CLASSTYPE_SUPER (type);
920 int nvirtuals = TREE_INT_CST_LOW (TYPE_NVIRTUALS (type));
921 vtable = make_tree_vec (nvirtuals);
922 TYPE_VTABLE (type) = vtable;
923 if (super != NULL_TREE)
924 {
925 tree super_vtable = get_dispatch_vector (super);
926 for ( i = TREE_INT_CST_LOW (TYPE_NVIRTUALS (super)); --i >= 0; )
927 TREE_VEC_ELT (vtable, i) = TREE_VEC_ELT (super_vtable, i);
928 }
929 for (method = TYPE_METHODS (type); method != NULL_TREE;
930 method = TREE_CHAIN (method))
931 {
932 if (DECL_VINDEX (method) != NULL_TREE
933 && TREE_CODE (DECL_VINDEX (method)) == INTEGER_CST)
934 {
935 TREE_VEC_ELT (vtable, TREE_INT_CST_LOW (DECL_VINDEX (method)))
936 = method;
937 }
938 }
939 }
940 return vtable;
941 }
942
943 tree
944 get_dispatch_table (type, this_class_addr)
945 tree type, this_class_addr;
946 {
947 tree vtable = get_dispatch_vector (type);
948 int i;
949 tree list = NULL_TREE;
950 int nvirtuals = TREE_VEC_LENGTH (vtable);
951 for (i = nvirtuals; --i >= 0; )
952 {
953 tree method = TREE_VEC_ELT (vtable, i);
954 if (METHOD_ABSTRACT (method))
955 warning_with_decl (method, "abstract method in non-abstract class");
956 if (DECL_RTL (method) == 0)
957 make_decl_rtl (method, NULL, 1);
958 list = tree_cons (NULL_TREE /*DECL_VINDEX (method) + 2*/,
959 build1 (ADDR_EXPR, nativecode_ptr_type_node, method),
960 list);
961 }
962 /* Dummy entry for compatibility with G++ -fvtable-thunks. */
963 list = tree_cons (integer_zero_node, null_pointer_node, list);
964 list = tree_cons (integer_zero_node, this_class_addr, list);
965 return build (CONSTRUCTOR, build_prim_array_type (nativecode_ptr_type_node,
966 nvirtuals + 2),
967 NULL_TREE, list);
968 }
969
970 void
971 make_class_data (type)
972 tree type;
973 {
974 tree decl, cons, temp;
975 tree field, fields_decl;
976 tree static_fields = NULL_TREE;
977 tree instance_fields = NULL_TREE;
978 HOST_WIDE_INT static_field_count = 0;
979 HOST_WIDE_INT instance_field_count = 0;
980 HOST_WIDE_INT field_count;
981 tree field_array_type;
982 tree method;
983 tree methods = NULL_TREE;
984 tree dtable_decl = NULL_TREE;
985 HOST_WIDE_INT method_count = 0;
986 tree method_array_type;
987 tree methods_decl;
988 tree super;
989 tree this_class_addr;
990 tree constant_pool_constructor;
991 tree interfaces = null_pointer_node;
992 int interface_len = 0;
993 tree type_decl = TYPE_NAME (type);
994
995 this_class_addr = build_class_ref (type);
996 decl = TREE_OPERAND (this_class_addr, 0);
997
998 /* Build Field array. */
999 field = TYPE_FIELDS (type);
1000 if (DECL_NAME (field) == NULL_TREE)
1001 field = TREE_CHAIN (field); /* Skip dummy field for inherited data. */
1002 for ( ; field != NULL_TREE; field = TREE_CHAIN (field))
1003 {
1004 if (! DECL_ARTIFICIAL (field))
1005 {
1006 tree init = make_field_value (field);
1007 if (FIELD_STATIC (field))
1008 {
1009 static_field_count++;
1010 static_fields = tree_cons (NULL_TREE, init, static_fields);
1011 rest_of_decl_compilation (field, (char*) 0, 1, 1);
1012 }
1013 else
1014 {
1015 instance_field_count++;
1016 instance_fields = tree_cons (NULL_TREE, init, instance_fields);
1017 }
1018 }
1019 }
1020 field_count = static_field_count + instance_field_count;
1021 if (field_count > 0)
1022 {
1023 static_fields = nreverse (static_fields);
1024 instance_fields = nreverse (instance_fields);
1025 static_fields = chainon (static_fields, instance_fields);
1026 field_array_type = build_prim_array_type (field_type_node, field_count);
1027 fields_decl = build_decl (VAR_DECL, mangled_classname ("_FL_", type),
1028 field_array_type);
1029 DECL_INITIAL (fields_decl) = build (CONSTRUCTOR, field_array_type,
1030 NULL_TREE, static_fields);
1031 TREE_STATIC (fields_decl) = 1;
1032 DECL_ARTIFICIAL (fields_decl) = 1;
1033 DECL_IGNORED_P (fields_decl) = 1;
1034 rest_of_decl_compilation (fields_decl, (char*) 0, 1, 0);
1035 }
1036 else
1037 fields_decl = NULL_TREE;
1038
1039 /* Build Method array. */
1040 for (method = TYPE_METHODS (CLASS_TO_HANDLE_TYPE (type));
1041 method != NULL_TREE; method = TREE_CHAIN (method))
1042 {
1043 tree init;
1044 if (METHOD_PRIVATE (method)
1045 && (flag_inline_functions || optimize))
1046 continue;
1047 init = make_method_value (method);
1048 method_count++;
1049 methods = tree_cons (NULL_TREE, init, methods);
1050 }
1051 method_array_type = build_prim_array_type (method_type_node, method_count);
1052 methods_decl = build_decl (VAR_DECL, mangled_classname ("_MT_", type),
1053 method_array_type);
1054 DECL_INITIAL (methods_decl) = build (CONSTRUCTOR, method_array_type,
1055 NULL_TREE, nreverse (methods));
1056 TREE_STATIC (methods_decl) = 1;
1057 DECL_ARTIFICIAL (methods_decl) = 1;
1058 DECL_IGNORED_P (methods_decl) = 1;
1059 rest_of_decl_compilation (methods_decl, (char*) 0, 1, 0);
1060
1061 if (flag_assume_compiled
1062 && ! CLASS_ABSTRACT (type_decl) && ! CLASS_INTERFACE (type_decl))
1063 {
1064 tree dtable = get_dispatch_table (type, this_class_addr);
1065 dtable_decl = build_dtable_decl (type);
1066 DECL_INITIAL (dtable_decl) = dtable;
1067 TREE_STATIC (dtable_decl) = 1;
1068 DECL_ARTIFICIAL (dtable_decl) = 1;
1069 DECL_IGNORED_P (dtable_decl) = 1;
1070 TREE_PUBLIC (dtable_decl) = 1;
1071 rest_of_decl_compilation (dtable_decl, (char*) 0, 1, 0);
1072 }
1073
1074 super = CLASSTYPE_SUPER (type);
1075 if (super == NULL_TREE)
1076 super = null_pointer_node;
1077 else if (flag_assume_compiled)
1078 super = build_class_ref (super);
1079 else
1080 {
1081 int super_index = alloc_class_constant (super);
1082 super = build_int_2 (super_index, 0);
1083 TREE_TYPE (super) == ptr_type_node;
1084 }
1085
1086 /* Build and emit the array of implemented interfaces. */
1087 if (type != object_type_node)
1088 interface_len = TREE_VEC_LENGTH (TYPE_BINFO_BASETYPES (type)) - 1;
1089 if (interface_len > 0)
1090 {
1091 tree init = NULL_TREE;
1092 int i;
1093 tree interface_array_type, idecl;
1094 interface_array_type
1095 = build_prim_array_type (class_ptr_type, interface_len);
1096 idecl = build_decl (VAR_DECL, mangled_classname ("_IF_", type),
1097 interface_array_type);
1098 for (i = interface_len; i > 0; i--)
1099 {
1100 tree child = TREE_VEC_ELT (TYPE_BINFO_BASETYPES (type), i);
1101 tree iclass = BINFO_TYPE (child);
1102 tree index;
1103 if (flag_assume_compiled)
1104 index = build_class_ref (iclass);
1105 else
1106 {
1107 int int_index = alloc_class_constant (iclass);
1108 index = build_int_2 (int_index, 0);
1109 TREE_TYPE (index) == ptr_type_node;
1110 }
1111 init = tree_cons (NULL_TREE, index, init);
1112 }
1113 DECL_INITIAL (idecl) = build (CONSTRUCTOR, interface_array_type,
1114 NULL_TREE, init);
1115 TREE_STATIC (idecl) = 1;
1116 DECL_ARTIFICIAL (idecl) = 1;
1117 DECL_IGNORED_P (idecl) = 1;
1118 interfaces = build1 (ADDR_EXPR, ptr_type_node, idecl);
1119 rest_of_decl_compilation (idecl, (char*) 0, 1, 0);
1120 }
1121
1122 constant_pool_constructor = build_constants_constructor ();
1123
1124 START_RECORD_CONSTRUCTOR (temp, object_type_node);
1125 #if 0
1126 PUSH_FIELD_VALUE (temp, "vtable", NULL_TREE);
1127 #else
1128 PUSH_FIELD_VALUE (temp, "vtable",
1129 build1 (ADDR_EXPR, dtable_ptr_type, class_dtable_decl));
1130 #endif
1131 PUSH_FIELD_VALUE (temp, "sync_info", null_pointer_node);
1132 FINISH_RECORD_CONSTRUCTOR (temp);
1133 START_RECORD_CONSTRUCTOR (cons, class_type_node);
1134 PUSH_SUPER_VALUE (cons, temp);
1135 PUSH_FIELD_VALUE (cons, "next", null_pointer_node);
1136 PUSH_FIELD_VALUE (cons, "name", build_utf8_ref (DECL_NAME (type_decl)));
1137 PUSH_FIELD_VALUE (cons, "accflags",
1138 build_int_2 (get_access_flags_from_decl (type_decl), 0));
1139
1140 PUSH_FIELD_VALUE (cons, "superclass",
1141 CLASS_INTERFACE (type_decl) ? null_pointer_node : super);
1142 PUSH_FIELD_VALUE (cons, "constants", constant_pool_constructor);
1143 PUSH_FIELD_VALUE (cons, "methods",
1144 build1 (ADDR_EXPR, method_ptr_type_node, methods_decl));
1145 PUSH_FIELD_VALUE (cons, "method_count", build_int_2 (method_count, 0));
1146 PUSH_FIELD_VALUE (cons, "vtable_method_count", TYPE_NVIRTUALS (type));
1147 PUSH_FIELD_VALUE (cons, "fields",
1148 fields_decl == NULL_TREE ? null_pointer_node
1149 : build1 (ADDR_EXPR, field_ptr_type_node, fields_decl));
1150 PUSH_FIELD_VALUE (cons, "size_in_bytes", size_in_bytes (type));
1151 PUSH_FIELD_VALUE (cons, "field_count", build_int_2 (field_count, 0));
1152 PUSH_FIELD_VALUE (cons, "static_field_count",
1153 build_int_2 (static_field_count, 0));
1154 PUSH_FIELD_VALUE (cons, "vtable",
1155 dtable_decl == NULL_TREE ? null_pointer_node
1156 : build1 (ADDR_EXPR, dtable_ptr_type, dtable_decl));
1157 PUSH_FIELD_VALUE (cons, "interfaces", interfaces);
1158 PUSH_FIELD_VALUE (cons, "loader", null_pointer_node);
1159 PUSH_FIELD_VALUE (cons, "interface_count", build_int_2 (interface_len, 0));
1160 PUSH_FIELD_VALUE (cons, "state", integer_zero_node);
1161
1162 PUSH_FIELD_VALUE (cons, "thread", null_pointer_node);
1163
1164 FINISH_RECORD_CONSTRUCTOR (cons);
1165
1166 DECL_INITIAL (decl) = cons;
1167 rest_of_decl_compilation (decl, (char*) 0, 1, 0);
1168 }
1169
1170 void
1171 finish_class (cl)
1172 tree cl;
1173 {
1174 tree method;
1175
1176 /* Emit deferred inline methods. */
1177 for ( method = TYPE_METHODS (CLASS_TO_HANDLE_TYPE (current_class));
1178 method != NULL_TREE; method = TREE_CHAIN (method))
1179 {
1180 if (! TREE_ASM_WRITTEN (method) && DECL_SAVED_INSNS (method) != 0)
1181 {
1182 /* It's a deferred inline method. Decide if we need to emit it. */
1183 if (flag_keep_inline_functions
1184 || TREE_SYMBOL_REFERENCED (DECL_ASSEMBLER_NAME (method))
1185 || ! METHOD_PRIVATE (method))
1186 {
1187 temporary_allocation ();
1188 output_inline_function (method);
1189 permanent_allocation (1);
1190 }
1191 }
1192 }
1193
1194 make_class_data (current_class);
1195 register_class ();
1196 rest_of_decl_compilation (TYPE_NAME (current_class), (char*) 0, 1, 0);
1197 }
1198
1199 /* Return 2 if CLASS is compiled by this compilation job;
1200 return 1 if CLASS can otherwise be assumed to be compiled;
1201 return 0 if we cannot assume that CLASS is compiled.
1202 Returns 1 for primitive and 0 for array types. */
1203 int
1204 is_compiled_class (class)
1205 tree class;
1206 {
1207 int seen_in_zip;
1208 if (TREE_CODE (class) == POINTER_TYPE)
1209 class = TREE_TYPE (class);
1210 if (TREE_CODE (class) != RECORD_TYPE) /* Primitive types are static. */
1211 return 1;
1212 if (TYPE_ARRAY_P (class))
1213 return 0;
1214 if (class == current_class)
1215 return 2;
1216
1217 seen_in_zip = (TYPE_LANG_SPECIFIC (class) && TYPE_LANG_SPECIFIC (class)->jcf
1218 && TYPE_LANG_SPECIFIC (class)->jcf->seen_in_zip);
1219 if (CLASS_FROM_CURRENTLY_COMPILED_SOURCE_P (class) || seen_in_zip)
1220 {
1221 /* The class was seen in the current ZIP file and will be
1222 available as a compiled class in the future but may not have
1223 been loaded already. Load it if necessary. This prevent
1224 build_class_ref () from crashing. */
1225
1226 if (seen_in_zip && !CLASS_LOADED_P (class))
1227 load_class (class, 1);
1228
1229 /* We return 2 for class seen in ZIP and class from files
1230 belonging to the same compilation unit */
1231 return 2;
1232 }
1233
1234 if (flag_assume_compiled)
1235 {
1236 if (!CLASS_LOADED_P (class))
1237 {
1238 if (CLASS_FROM_SOURCE_P (class))
1239 safe_layout_class (class);
1240 else
1241 load_class (class, 1);
1242 }
1243 return 1;
1244 }
1245
1246 return 0;
1247 }
1248
1249 /* Append the mangled name of TYPE onto OBSTACK. */
1250
1251 void
1252 append_gpp_mangled_type (obstack, type)
1253 struct obstack *obstack;
1254 tree type;
1255 {
1256 switch (TREE_CODE (type))
1257 {
1258 char code;
1259 case BOOLEAN_TYPE: code = 'b'; goto primitive;
1260 case CHAR_TYPE: code = 'w'; goto primitive;
1261 case VOID_TYPE: code = 'v'; goto primitive;
1262 case INTEGER_TYPE:
1263 /* Get the original type instead of the arguments promoted type.
1264 Avoid symbol name clashes. Should call a function to do that.
1265 FIXME. */
1266 if (type == promoted_short_type_node)
1267 type = short_type_node;
1268 if (type == promoted_byte_type_node)
1269 type = byte_type_node;
1270 switch (TYPE_PRECISION (type))
1271 {
1272 case 8: code = 'c'; goto primitive;
1273 case 16: code = 's'; goto primitive;
1274 case 32: code = 'i'; goto primitive;
1275 case 64: code = 'x'; goto primitive;
1276 default: goto bad_type;
1277 }
1278 primitive:
1279 obstack_1grow (obstack, code);
1280 break;
1281 case REAL_TYPE:
1282 switch (TYPE_PRECISION (type))
1283 {
1284 case 32: code = 'f'; goto primitive;
1285 case 64: code = 'd'; goto primitive;
1286 default: goto bad_type;
1287 }
1288 case POINTER_TYPE:
1289 type = TREE_TYPE (type);
1290 obstack_1grow (obstack, 'P');
1291 case RECORD_TYPE:
1292 if (TYPE_ARRAY_P (type))
1293 {
1294 obstack_grow (obstack, "t6JArray1Z", sizeof("t6JArray1Z")-1);
1295 append_gpp_mangled_type (obstack, TYPE_ARRAY_ELEMENT (type));
1296 }
1297 else
1298 {
1299 char *class_name = IDENTIFIER_POINTER (DECL_NAME (TYPE_NAME (type)));
1300 append_gpp_mangled_classtype (obstack, class_name);
1301 }
1302 break;
1303 bad_type:
1304 default:
1305 fatal ("internal error - trying to mangle unknown type");
1306 }
1307 }
1308
1309 /* Build the mangled name of the `class' field. */
1310
1311 static tree
1312 mangle_class_field (class)
1313 tree class;
1314 {
1315 tree name;
1316 obstack_grow (&temporary_obstack, "_CL_", 4);
1317 append_gpp_mangled_type (&temporary_obstack, class);
1318 obstack_1grow (&temporary_obstack, '\0');
1319 name = get_identifier (obstack_base (&temporary_obstack));
1320 obstack_free (&temporary_obstack, obstack_base (&temporary_obstack));
1321 return name;
1322 }
1323
1324 /* Build the mangled (assembly-level) name of the static field FIELD. */
1325
1326 tree
1327 mangle_static_field (field)
1328 tree field;
1329 {
1330 tree class = DECL_CONTEXT (field);
1331 tree name = DECL_NAME (field);
1332 int encoded_len;
1333 #if ! defined (NO_DOLLAR_IN_LABEL) || ! defined (NO_DOT_IN_LABEL)
1334 obstack_1grow (&temporary_obstack, '_');
1335 #else
1336 obstack_grow (&temporary_obstack, "__static_", 9);
1337 #endif
1338 append_gpp_mangled_type (&temporary_obstack, class);
1339 encoded_len = unicode_mangling_length (IDENTIFIER_POINTER (name),
1340 IDENTIFIER_LENGTH (name));
1341 if (encoded_len > 0)
1342 {
1343 obstack_1grow (&temporary_obstack, 'U');
1344 }
1345 #ifndef NO_DOLLAR_IN_LABEL
1346 obstack_1grow (&temporary_obstack, '$');
1347 #else /* NO_DOLLAR_IN_LABEL */
1348 #ifndef NO_DOT_IN_LABEL
1349 obstack_1grow (&temporary_obstack, '.');
1350 #else /* NO_DOT_IN_LABEL */
1351 obstack_1grow (&temporary_obstack, '_');
1352 #endif /* NO_DOT_IN_LABEL */
1353 #endif /* NO_DOLLAR_IN_LABEL */
1354 if (encoded_len > 0)
1355 {
1356 emit_unicode_mangled_name (&temporary_obstack,
1357 IDENTIFIER_POINTER (name),
1358 IDENTIFIER_LENGTH (name));
1359 }
1360 else
1361 {
1362 obstack_grow (&temporary_obstack,
1363 IDENTIFIER_POINTER (name),
1364 IDENTIFIER_LENGTH (name));
1365 }
1366 obstack_1grow (&temporary_obstack, '\0');
1367 name = get_identifier (obstack_base (&temporary_obstack));
1368 obstack_free (&temporary_obstack, obstack_base (&temporary_obstack));
1369 return name;
1370 }
1371
1372 /* Build a VAR_DECL for the dispatch table (vtable) for class TYPE. */
1373
1374 tree
1375 build_dtable_decl (type)
1376 tree type;
1377 {
1378 tree name;
1379 obstack_grow (&temporary_obstack, "__vt_", 5);
1380 append_gpp_mangled_type (&temporary_obstack, type);
1381 obstack_1grow (&temporary_obstack, '\0');
1382 name = get_identifier (obstack_base (&temporary_obstack));
1383 obstack_free (&temporary_obstack, obstack_base (&temporary_obstack));
1384 return build_decl (VAR_DECL, name, dtable_type);
1385 }
1386
1387 /* Pre-pend the TYPE_FIELDS of THIS_CLASS with a dummy FIELD_DECL for the
1388 fields inherited from SUPER_CLASS. */
1389
1390 void
1391 push_super_field (this_class, super_class)
1392 tree this_class, super_class;
1393 {
1394 tree base_decl;
1395 push_obstacks (&permanent_obstack, &permanent_obstack);
1396 base_decl = build_decl (FIELD_DECL, NULL_TREE, super_class);
1397 pop_obstacks ();
1398 DECL_IGNORED_P (base_decl) = 1;
1399 TREE_CHAIN (base_decl) = TYPE_FIELDS (this_class);
1400 TYPE_FIELDS (this_class) = base_decl;
1401 DECL_SIZE (base_decl) = TYPE_SIZE (super_class);
1402 }
1403
1404 /* Handle the different manners we may have to lay out a super class. */
1405
1406 static tree
1407 maybe_layout_super_class (super_class, this_class)
1408 tree super_class;
1409 tree this_class;
1410 {
1411 if (TREE_CODE (super_class) == RECORD_TYPE)
1412 {
1413 if (!CLASS_LOADED_P (super_class)
1414 && CLASS_FROM_SOURCE_P (super_class))
1415 safe_layout_class (super_class);
1416 if (!CLASS_LOADED_P (super_class))
1417 load_class (super_class, 1);
1418 }
1419 /* We might have to layout the class before its dependency on
1420 the super class gets resolved by java_complete_class */
1421 else if (TREE_CODE (super_class) == POINTER_TYPE)
1422 {
1423 if (TREE_TYPE (super_class) != NULL_TREE)
1424 super_class = TREE_TYPE (super_class);
1425 else
1426 {
1427 super_class = do_resolve_class (super_class, NULL_TREE, this_class);
1428 if (!super_class)
1429 return NULL_TREE; /* FIXME, NULL_TREE not checked by caller. */
1430 super_class = TREE_TYPE (super_class);
1431 }
1432 }
1433 if (!TYPE_SIZE (super_class))
1434 safe_layout_class (super_class);
1435
1436 return super_class;
1437 }
1438
1439 void
1440 layout_class (this_class)
1441 tree this_class;
1442 {
1443 tree super_class = CLASSTYPE_SUPER (this_class);
1444 tree field;
1445
1446 if (super_class)
1447 {
1448 super_class = maybe_layout_super_class (super_class, this_class);
1449 if (TREE_CODE (TYPE_SIZE (super_class)) == ERROR_MARK)
1450 {
1451 TYPE_SIZE (this_class) = error_mark_node;
1452 return;
1453 }
1454 if (TYPE_SIZE (this_class) == NULL_TREE)
1455 push_super_field (this_class, super_class);
1456 }
1457
1458 for (field = TYPE_FIELDS (this_class);
1459 field != NULL_TREE; field = TREE_CHAIN (field))
1460 {
1461 if (FIELD_STATIC (field))
1462 {
1463 /* Set DECL_ASSEMBLER_NAME to something suitably mangled. */
1464 DECL_ASSEMBLER_NAME (field) = mangle_static_field (field);
1465 }
1466 }
1467
1468 layout_type (this_class);
1469 }
1470
1471 void
1472 layout_class_methods (this_class)
1473 tree this_class;
1474 {
1475 tree method_decl, dtable_count;
1476 tree super_class, handle_type;
1477
1478 if (TYPE_NVIRTUALS (this_class))
1479 return;
1480
1481 push_obstacks (&permanent_obstack, &permanent_obstack);
1482 super_class = CLASSTYPE_SUPER (this_class);
1483 handle_type = CLASS_TO_HANDLE_TYPE (this_class);
1484
1485 if (super_class)
1486 {
1487 super_class = maybe_layout_super_class (super_class, this_class);
1488 if (!TYPE_NVIRTUALS (super_class))
1489 layout_class_methods (super_class);
1490 dtable_count = TYPE_NVIRTUALS (super_class);
1491 }
1492 else
1493 dtable_count = integer_zero_node;
1494
1495 TYPE_METHODS (handle_type) = nreverse (TYPE_METHODS (handle_type));
1496
1497 for (method_decl = TYPE_METHODS (handle_type);
1498 method_decl; method_decl = TREE_CHAIN (method_decl))
1499 dtable_count = layout_class_method (this_class, super_class,
1500 method_decl, dtable_count);
1501
1502 TYPE_NVIRTUALS (this_class) = dtable_count;
1503
1504 #ifdef JAVA_USE_HANDLES
1505 layout_type (handle_type);
1506 #endif
1507 pop_obstacks ();
1508 }
1509
1510 /* Lay METHOD_DECL out, returning a possibly new value of
1511 DTABLE_COUNT. */
1512
1513 tree
1514 layout_class_method (this_class, super_class, method_decl, dtable_count)
1515 tree this_class, super_class, method_decl, dtable_count;
1516 {
1517 char *ptr;
1518 char *asm_name;
1519 tree arg, arglist, t;
1520 int method_name_needs_escapes = 0;
1521 tree method_name = DECL_NAME (method_decl);
1522 int method_name_is_wfl =
1523 (TREE_CODE (method_name) == EXPR_WITH_FILE_LOCATION);
1524 if (method_name_is_wfl)
1525 method_name = java_get_real_method_name (method_decl);
1526
1527 if (method_name != init_identifier_node
1528 && method_name != finit_identifier_node)
1529 {
1530 int encoded_len
1531 = unicode_mangling_length (IDENTIFIER_POINTER (method_name),
1532 IDENTIFIER_LENGTH (method_name));
1533 if (encoded_len > 0)
1534 {
1535 method_name_needs_escapes = 1;
1536 emit_unicode_mangled_name (&temporary_obstack,
1537 IDENTIFIER_POINTER (method_name),
1538 IDENTIFIER_LENGTH (method_name));
1539 }
1540 else
1541 {
1542 obstack_grow (&temporary_obstack,
1543 IDENTIFIER_POINTER (method_name),
1544 IDENTIFIER_LENGTH (method_name));
1545 }
1546 }
1547
1548 obstack_grow (&temporary_obstack, "__", 2);
1549 if (method_name == finit_identifier_node)
1550 obstack_grow (&temporary_obstack, "finit", 5);
1551 append_gpp_mangled_type (&temporary_obstack, this_class);
1552 TREE_PUBLIC (method_decl) = 1;
1553
1554 t = TREE_TYPE (method_decl);
1555 arglist = TYPE_ARG_TYPES (t);
1556 if (TREE_CODE (t) == METHOD_TYPE)
1557 arglist = TREE_CHAIN (arglist);
1558 for (arg = arglist; arg != end_params_node; )
1559 {
1560 tree a = arglist;
1561 tree argtype = TREE_VALUE (arg);
1562 int tindex = 1;
1563 if (TREE_CODE (argtype) == POINTER_TYPE)
1564 {
1565 /* This is O(N**2). Do we care? Cfr gcc/cp/method.c. */
1566 while (a != arg && argtype != TREE_VALUE (a))
1567 a = TREE_CHAIN (a), tindex++;
1568 }
1569 else
1570 a = arg;
1571 if (a != arg)
1572 {
1573 char buf[12];
1574 int nrepeats = 0;
1575 do
1576 {
1577 arg = TREE_CHAIN (arg); nrepeats++;
1578 }
1579 while (arg != end_params_node && argtype == TREE_VALUE (arg));
1580 if (nrepeats > 1)
1581 {
1582 obstack_1grow (&temporary_obstack, 'N');
1583 sprintf (buf, "%d", nrepeats);
1584 obstack_grow (&temporary_obstack, buf, strlen (buf));
1585 if (nrepeats > 9)
1586 obstack_1grow (&temporary_obstack, '_');
1587 }
1588 else
1589 obstack_1grow (&temporary_obstack, 'T');
1590 sprintf (buf, "%d", tindex);
1591 obstack_grow (&temporary_obstack, buf, strlen (buf));
1592 if (tindex > 9)
1593 obstack_1grow (&temporary_obstack, '_');
1594 }
1595 else
1596 {
1597 append_gpp_mangled_type (&temporary_obstack, argtype);
1598 arg = TREE_CHAIN (arg);
1599 }
1600 }
1601 if (method_name_needs_escapes)
1602 obstack_1grow (&temporary_obstack, 'U');
1603
1604 obstack_1grow (&temporary_obstack, '\0');
1605 asm_name = obstack_finish (&temporary_obstack);
1606 DECL_ASSEMBLER_NAME (method_decl) = get_identifier (asm_name);
1607 if (! METHOD_ABSTRACT (method_decl)
1608 && ! CLASS_INTERFACE (TYPE_NAME (this_class)))
1609 make_function_rtl (method_decl);
1610 obstack_free (&temporary_obstack, asm_name);
1611
1612 if (method_name == init_identifier_node)
1613 {
1614 char *p = IDENTIFIER_POINTER (DECL_NAME (TYPE_NAME (this_class)));
1615 for (ptr = p; *ptr; )
1616 {
1617 if (*ptr++ == '.')
1618 p = ptr;
1619 }
1620 if (method_name_is_wfl)
1621 EXPR_WFL_NODE (DECL_NAME (method_decl)) = get_identifier (p);
1622 else
1623 DECL_NAME (method_decl) = get_identifier (p);
1624 DECL_CONSTRUCTOR_P (method_decl) = 1;
1625 build_java_argument_signature (TREE_TYPE (method_decl));
1626 }
1627 else if (! METHOD_STATIC (method_decl) && !DECL_ARTIFICIAL (method_decl))
1628 {
1629 tree method_sig =
1630 build_java_argument_signature (TREE_TYPE (method_decl));
1631 tree super_method = lookup_argument_method (super_class, method_name,
1632 method_sig);
1633 if (super_method != NULL_TREE && ! METHOD_PRIVATE (super_method))
1634 {
1635 DECL_VINDEX (method_decl) = DECL_VINDEX (super_method);
1636 if (DECL_VINDEX (method_decl) == NULL_TREE)
1637 error_with_decl (method_decl,
1638 "non-static method '%s' overrides static method");
1639 #if 0
1640 else if (TREE_TYPE (TREE_TYPE (method_decl))
1641 != TREE_TYPE (TREE_TYPE (super_method)))
1642 {
1643 error_with_decl (method_decl,
1644 "Method `%s' redefined with different return type");
1645 error_with_decl (super_method,
1646 "Overridden decl is here");
1647 }
1648 #endif
1649 }
1650 else if (! METHOD_FINAL (method_decl)
1651 && ! METHOD_PRIVATE (method_decl)
1652 && ! CLASS_FINAL (TYPE_NAME (this_class))
1653 && dtable_count)
1654 {
1655 DECL_VINDEX (method_decl) = dtable_count;
1656 dtable_count = build_int_2 (1+TREE_INT_CST_LOW (dtable_count), 0);
1657 }
1658 }
1659 return dtable_count;
1660 }
1661
1662 static tree registered_class = NULL_TREE;
1663
1664 void
1665 register_class ()
1666 {
1667 static tree end;
1668 tree node = TREE_OPERAND (build_class_ref (current_class), 0);
1669 tree current = copy_node (node);
1670
1671 XEXP (DECL_RTL (current), 0) = copy_rtx (XEXP (DECL_RTL(node), 0));
1672 if (!registered_class)
1673 registered_class = current;
1674 else
1675 TREE_CHAIN (end) = current;
1676
1677 end = current;
1678 }
1679
1680 /* Generate a function that gets called at start-up (static contructor) time,
1681 which calls registerClass for all the compiled classes. */
1682
1683 void
1684 emit_register_classes ()
1685 {
1686 tree decl = getdecls ();
1687
1688 extern tree get_file_function_name PROTO((int));
1689 tree init_name = get_file_function_name ('I');
1690 tree init_type = build_function_type (void_type_node, end_params_node);
1691 tree init_decl;
1692 tree t;
1693
1694 start_sequence ();
1695 init_decl = build_decl (FUNCTION_DECL, init_name, init_type);
1696 DECL_ASSEMBLER_NAME (init_decl) = init_name;
1697 TREE_STATIC (init_decl) = 1;
1698 current_function_decl = init_decl;
1699 DECL_RESULT (init_decl) = build_decl(RESULT_DECL, NULL_TREE, void_type_node);
1700 /* DECL_EXTERNAL (init_decl) = 1;*/
1701 TREE_PUBLIC (init_decl) = 1;
1702 pushlevel (0);
1703 make_function_rtl (init_decl);
1704 init_function_start (init_decl, input_filename, 0);
1705 expand_function_start (init_decl, 0);
1706
1707 for ( t = registered_class; t; t = TREE_CHAIN (t))
1708 emit_library_call (registerClass_libfunc, 0, VOIDmode, 1,
1709 XEXP (DECL_RTL (t), 0), Pmode);
1710
1711 expand_function_end (input_filename, 0, 0);
1712 poplevel (1, 0, 1);
1713 {
1714 /* Force generation, even with -O3 or deeper. Gross hack. FIXME */
1715 int saved_flag = flag_inline_functions;
1716 flag_inline_functions = 0;
1717 rest_of_compilation (init_decl);
1718 flag_inline_functions = saved_flag;
1719 }
1720 current_function_decl = NULL_TREE;
1721 assemble_constructor (IDENTIFIER_POINTER (init_name));
1722 }
1723
1724 void
1725 init_class_processing ()
1726 {
1727 registerClass_libfunc = gen_rtx (SYMBOL_REF, Pmode, "_Jv_RegisterClass");
1728 }
This page took 0.102428 seconds and 4 git commands to generate.