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