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