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