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