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