]> git.ipfire.org Git - thirdparty/gcc.git/blame - gcc/java/class.c
c-common.h: Prototype min_precision and c_build_qualified_type here...
[thirdparty/gcc.git] / gcc / java / class.c
CommitLineData
e04a16fb 1/* Functions related to building classes and their related objects.
06ceef4e 2 Copyright (C) 1996, 1997, 1998, 1999, 2000 Free Software Foundation, Inc.
e04a16fb
AG
3
4This file is part of GNU CC.
5
6GNU CC is free software; you can redistribute it and/or modify
7it under the terms of the GNU General Public License as published by
8the Free Software Foundation; either version 2, or (at your option)
9any later version.
10
11GNU CC is distributed in the hope that it will be useful,
12but WITHOUT ANY WARRANTY; without even the implied warranty of
13MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14GNU General Public License for more details.
15
16You should have received a copy of the GNU General Public License
17along with GNU CC; see the file COPYING. If not, write to
18the Free Software Foundation, 59 Temple Place - Suite 330,
19Boston, MA 02111-1307, USA.
20
21Java and all Java-based marks are trademarks or registered trademarks
22of Sun Microsystems, Inc. in the United States and other countries.
23The Free Software Foundation is independent of Sun Microsystems, Inc. */
24
25/* Written by Per Bothner <bothner@cygnus.com> */
26
e04a16fb 27#include "config.h"
1f43f4b4 28#include "system.h"
e04a16fb
AG
29#include "tree.h"
30#include "rtl.h"
75d01ad7 31#include "flags.h"
e04a16fb
AG
32#include "java-tree.h"
33#include "jcf.h"
34#include "obstack.h"
1f43f4b4 35#include "toplev.h"
d4476be2
KG
36#include "output.h"
37#include "parse.h"
e04a16fb 38
df32d2ce
KG
39static tree mangle_class_field PARAMS ((tree class));
40static tree make_method_value PARAMS ((tree));
41static tree build_java_method_type PARAMS ((tree, tree, int));
42static int32 hashUtf8String PARAMS ((const char *, int));
43static tree make_field_value PARAMS ((tree));
44static tree get_dispatch_vector PARAMS ((tree));
45static tree get_dispatch_table PARAMS ((tree, tree));
46static void append_gpp_mangled_type PARAMS ((struct obstack *, tree));
47static tree mangle_static_field PARAMS ((tree));
48static void add_interface_do PARAMS ((tree, tree, int));
49static tree maybe_layout_super_class PARAMS ((tree, tree));
50static int assume_compiled PARAMS ((const char *));
c0b864fc
KG
51static struct hash_entry *init_test_hash_newfunc PARAMS ((struct hash_entry *,
52 struct hash_table *,
53 hash_table_key));
e04a16fb
AG
54
55static rtx registerClass_libfunc;
56
57extern struct obstack permanent_obstack;
58extern struct obstack temporary_obstack;
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
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
c63b98cd 93static assume_compiled_node *
48aedbca
AG
94find_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
134void
135add_assume_compiled (ident, excludep)
136 const char *ident;
137 int excludep;
138{
139 assume_compiled_node *parent;
140 assume_compiled_node *node =
c63b98cd 141 (assume_compiled_node *) xmalloc (sizeof (assume_compiled_node));
48aedbca 142
c63b98cd 143 node->ident = xstrdup (ident);
48aedbca
AG
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 =
c63b98cd 152 (assume_compiled_node *) xmalloc (sizeof (assume_compiled_node));
48aedbca
AG
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
c63b98cd 186static int
48aedbca
AG
187assume_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
e04a16fb
AG
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
208tree
209ident_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
241tree
242identifier_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
256tree
257mangled_classname (prefix, type)
d4476be2
KG
258 const char *prefix;
259 tree type;
e04a16fb
AG
260{
261 tree ident = TYPE_NAME (type);
262 if (TREE_CODE (ident) != IDENTIFIER_NODE)
263 ident = DECL_NAME (ident);
7e57923c 264 return identifier_subst (ident, prefix, '.', '_', "");
e04a16fb
AG
265}
266
267tree
268make_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
c2952b01 288 MAYBE_CREATE_TYPE_TYPE_LANG_SPECIFIC (type);
e04a16fb
AG
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
298tree
299unmangle_classname (name, name_length)
300 const char *name; int name_length;
301{
c877974e 302 tree to_return = ident_subst (name, name_length, "", '/', '.', "");
1982388a
APB
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
c877974e 315 return to_return;
e04a16fb
AG
316}
317
318tree
319push_class (class_type, class_name)
320 tree class_type, class_name;
321{
322 tree decl, signature;
3b304f5b 323 const char *save_input_filename = input_filename;
e04a16fb
AG
324 int save_lineno = lineno;
325 tree source_name = identifier_subst (class_name, "", '.', '/', ".java");
326 push_obstacks (&permanent_obstack, &permanent_obstack);
10919149 327 CLASS_P (class_type) = 1;
e04a16fb
AG
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", '.', '/', ";");
a7303141 334 IDENTIFIER_SIGNATURE_TYPE (signature) = build_pointer_type (class_type);
e04a16fb
AG
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
361tree
362lookup_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
371void
372set_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 ();
3ff9925c 396
e04a16fb
AG
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;
c2952b01 402 if (access_flags & ACC_STATIC) CLASS_STATIC (class_decl) = 1;
cf1748bf 403 if (access_flags & ACC_PRIVATE) CLASS_PRIVATE (class_decl) = 1;
4dbf4496 404 if (access_flags & ACC_PROTECTED) CLASS_PROTECTED (class_decl) = 1;
e04a16fb
AG
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
410int
411class_depth (clas)
412 tree clas;
413{
414 int depth = 0;
415 if (! CLASS_LOADED_P (clas))
416 load_class (clas, 1);
e920ebc9
APB
417 if (TYPE_SIZE (clas) == error_mark_node)
418 return -1;
e04a16fb
AG
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
429int
430interface_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
457int
458inherits_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
c2952b01
APB
470/* Return a 1 iff TYPE1 is an enclosing context for TYPE2 */
471
472int
473enclosing_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
152de068
APB
491/* Return 1 iff there exists a common enclosing context between TYPE1
492 and TYPE2. */
493
494int common_enclosing_context_p (type1, type2)
495 tree type1, type2;
496{
4dbf4496 497 if (!PURE_INNER_CLASS_TYPE_P (type1) || !PURE_INNER_CLASS_TYPE_P (type2))
152de068
APB
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
e04a16fb
AG
515static void
516add_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
532tree
533maybe_add_interface (this_class, interface_class)
534 tree this_class, interface_class;
535{
536 tree basetype_vec = TYPE_BINFO_BASETYPES (this_class);
e04a16fb
AG
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
557void
558add_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
d4476be2 577#if 0
e04a16fb
AG
578/* Return the address of a pointer to the first FUNCTION_DECL
579 in the list (*LIST) whose DECL_NAME is NAME. */
580
581static tree *
582find_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}
d4476be2 590#endif
e04a16fb 591
4bcde32e 592static tree
e04a16fb
AG
593build_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
3ff9925c
AG
603static struct hash_entry *
604init_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
e0422ed0
APB
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
625unsigned long
626java_hash_hash_tree_node (k)
3ff9925c
AG
627 hash_table_key k;
628{
629 return (long) k;
630}
631
e0422ed0
APB
632boolean
633java_hash_compare_tree_node (k1, k2)
3ff9925c
AG
634 hash_table_key k1;
635 hash_table_key k2;
636{
637 return ((char*) k1 == (char*) k2);
638}
639
e04a16fb
AG
640tree
641add_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));
4504ead1 658 bzero ((PTR) DECL_LANG_SPECIFIC (fndecl), sizeof (struct lang_decl));
e04a16fb 659
3ff9925c
AG
660 /* Initialize the static initializer test table. */
661 hash_table_init (&DECL_FUNCTION_INIT_TEST_TABLE (fndecl),
e0422ed0
APB
662 init_test_hash_newfunc, java_hash_hash_tree_node,
663 java_hash_compare_tree_node);
3ff9925c 664
e04a16fb
AG
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;
8119c720
APB
671 if (access_flags & ACC_PRIVATE)
672 METHOD_PRIVATE (fndecl) = DECL_INLINE (fndecl) = 1;
7145d9fe
TT
673 if (access_flags & ACC_NATIVE)
674 {
675 METHOD_NATIVE (fndecl) = 1;
676 DECL_EXTERNAL (fndecl) = 1;
677 }
8119c720
APB
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;
e04a16fb
AG
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
692tree
693add_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);
d640220c 700 tree function_type, fndecl;
c8e7d2e6 701 const unsigned char *sig = (const unsigned char*)IDENTIFIER_POINTER (method_sig);
e04a16fb
AG
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
712tree
713add_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);
e04a16fb
AG
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;
a7303141
PB
738 /* Always make field externally visible. This is required so
739 that native methods can always access the field. */
740 TREE_PUBLIC (field) = 1;
e04a16fb
AG
741 }
742 return field;
743}
744
745/* Associate a constant value CONSTANT with VAR_DECL FIELD. */
746
747void
748set_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
4bcde32e 762#if 0
e04a16fb
AG
763int
764strLengthUtf8 (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}
4bcde32e 777#endif
e04a16fb
AG
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
4bcde32e 784static int32
e04a16fb 785hashUtf8String (str, len)
4bcde32e 786 const char *str;
e04a16fb
AG
787 int len;
788{
4bcde32e
KG
789 register const unsigned char* ptr = (const unsigned char*) str;
790 register const unsigned char *limit = ptr + len;
e04a16fb
AG
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
802tree utf8_decl_list = NULL_TREE;
803
804tree
805build_utf8_ref (name)
806 tree name;
807{
c8e7d2e6 808 const char * name_ptr = IDENTIFIER_POINTER(name);
e04a16fb
AG
809 int name_len = IDENTIFIER_LENGTH(name);
810 char buf[60];
811 char *buf_ptr;
ab3a6dd6 812 tree ctype, field = NULL_TREE, str_type, cinit, string;
e04a16fb
AG
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);
7e57923c
AH
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);
e04a16fb
AG
833 TREE_TYPE (string) = str_type;
834 PUSH_FIELD_VALUE (cinit, "data", string);
835 FINISH_RECORD_CONSTRUCTOR (cinit);
99fd3aa5 836 TREE_CONSTANT (cinit) = 1;
e04a16fb
AG
837
838 /* Build a unique identifier based on buf. */
839 sprintf(buf, "_Utf%d", ++utf8_count);
840 buf_ptr = &buf[strlen (buf)];
30ca27b4
PB
841 if (name_len > 0 && name_ptr[0] >= '0' && name_ptr[0] <= '9')
842 *buf_ptr++ = '_';
e04a16fb
AG
843 while (--name_len >= 0)
844 {
d4476be2 845 unsigned char c = *name_ptr++;
e04a16fb
AG
846 if (c & 0x80)
847 continue;
d4476be2 848 if (!ISALPHA(c) && !ISDIGIT(c))
e04a16fb
AG
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;
99fd3aa5 862 TREE_THIS_VOLATILE (decl) = 0;
e04a16fb
AG
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
879tree
880build_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);
06ceef4e 901 DECL_SIZE_UNIT (decl) = TYPE_SIZE_UNIT (class_type_node);
e04a16fb
AG
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 {
c8e7d2e6 916 const char *name;
66d88624 917 char buffer[25];
091c8dfd
PB
918 if (flag_emit_class_files)
919 {
d4476be2 920 const char *prim_class_name;
091c8dfd
PB
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 }
e04a16fb
AG
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;
66d88624 952 sprintf (buffer, "_Jv_%sClass", name);
e04a16fb
AG
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
985tree
986build_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:
165f37bc 1006 * *(FTYPE*)build_class_ref(FCLASS)->fields[INDEX].info.addr */
e04a16fb
AG
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
1042int
1043get_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;
c2952b01
APB
1077 if (CLASS_STATIC (decl))
1078 access_flags |= ACC_STATIC;
4dbf4496
APB
1079 if (CLASS_PRIVATE (decl))
1080 access_flags |= ACC_PRIVATE;
1081 if (CLASS_PROTECTED (decl))
1082 access_flags |= ACC_PROTECTED;
e04a16fb
AG
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
4bcde32e
KG
1110static tree
1111make_field_value (fdecl)
1112 tree fdecl;
e04a16fb 1113{
770ae6cc 1114 tree finit;
665f2503 1115 int flags;
e04a16fb
AG
1116 tree type = TREE_TYPE (fdecl);
1117 int resolved = is_compiled_class (type);
665f2503 1118
e04a16fb
AG
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
7e57923c
AH
1124 {
1125 tree signature = build_java_signature (type);
770ae6cc 1126
7e57923c 1127 type = build_utf8_ref (unmangle_classname
770ae6cc
RK
1128 (IDENTIFIER_POINTER (signature),
1129 IDENTIFIER_LENGTH (signature)));
7e57923c 1130 }
e04a16fb 1131 PUSH_FIELD_VALUE (finit, "type", type);
770ae6cc 1132
e04a16fb
AG
1133 flags = get_access_flags_from_decl (fdecl);
1134 if (! resolved)
1135 flags |= 0x8000 /* FIELD_UNRESOLVED_FLAG */;
665f2503 1136
e04a16fb 1137 PUSH_FIELD_VALUE (finit, "accflags", build_int_2 (flags, 0));
665f2503 1138 PUSH_FIELD_VALUE (finit, "bsize", TYPE_SIZE_UNIT (TREE_TYPE (fdecl)));
665f2503 1139
770ae6cc
RK
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)))));
e04a16fb
AG
1150
1151 FINISH_RECORD_CONSTRUCTOR (finit);
1152 return finit;
1153}
1154
8e1f2d4c
KG
1155static tree
1156make_method_value (mdecl)
e04a16fb 1157 tree mdecl;
e04a16fb
AG
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)));
7e57923c
AH
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 }
e04a16fb
AG
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
4bcde32e 1185static tree
e04a16fb
AG
1186get_dispatch_vector (type)
1187 tree type;
1188{
1189 tree vtable = TYPE_VTABLE (type);
1190 if (vtable == NULL)
1191 {
665f2503 1192 HOST_WIDE_INT i;
e04a16fb
AG
1193 tree method;
1194 tree super = CLASSTYPE_SUPER (type);
665f2503 1195 HOST_WIDE_INT nvirtuals = tree_low_cst (TYPE_NVIRTUALS (type), 0);
e04a16fb
AG
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);
665f2503
RK
1201
1202 for (i = tree_low_cst (TYPE_NVIRTUALS (super), 0); --i >= 0; )
e04a16fb
AG
1203 TREE_VEC_ELT (vtable, i) = TREE_VEC_ELT (super_vtable, i);
1204 }
665f2503 1205
e04a16fb
AG
1206 for (method = TYPE_METHODS (type); method != NULL_TREE;
1207 method = TREE_CHAIN (method))
665f2503
RK
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;
e04a16fb 1212 }
665f2503 1213
e04a16fb
AG
1214 return vtable;
1215}
1216
4bcde32e 1217static tree
e04a16fb
AG
1218get_dispatch_table (type, this_class_addr)
1219 tree type, this_class_addr;
1220{
13107ec0 1221 int abstract_p = CLASS_ABSTRACT (TYPE_NAME (type));
e04a16fb
AG
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))
13107ec0
TT
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 }
e04a16fb 1242 list = tree_cons (NULL_TREE /*DECL_VINDEX (method) + 2*/,
13107ec0 1243 method, list);
e04a16fb 1244 }
5830574a
TT
1245 /* Dummy entry for compatibility with G++ -fvtable-thunks. When
1246 using the Boehm GC we sometimes stash a GC type descriptor
8f975c18
APB
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),
5830574a 1250 list);
e04a16fb
AG
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
1257void
1258make_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 {
cd9643f7 1296 tree initial = DECL_INITIAL (field);
e04a16fb
AG
1297 static_field_count++;
1298 static_fields = tree_cons (NULL_TREE, init, static_fields);
cd9643f7
PB
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;
e04a16fb 1304 rest_of_decl_compilation (field, (char*) 0, 1, 1);
cd9643f7 1305 DECL_INITIAL (field) = initial;
e04a16fb
AG
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 {
75d01ad7
PB
1337 tree init;
1338 if (METHOD_PRIVATE (method)
cf69bfbf 1339 && ! flag_keep_inline_functions
75d01ad7
PB
1340 && (flag_inline_functions || optimize))
1341 continue;
8e1f2d4c 1342 init = make_method_value (method);
e04a16fb
AG
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
48aedbca 1356 if (assume_compiled (IDENTIFIER_POINTER (DECL_NAME (type_decl)))
13107ec0 1357 && ! CLASS_INTERFACE (type_decl))
e04a16fb
AG
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;
48aedbca 1372 else if (assume_compiled (IDENTIFIER_POINTER (DECL_NAME (type_decl))))
e04a16fb
AG
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);
152f94fc 1378 TREE_TYPE (super) = ptr_type_node;
e04a16fb
AG
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;
48aedbca 1398 if (assume_compiled (IDENTIFIER_POINTER (DECL_NAME (TYPE_NAME (iclass)))))
e04a16fb
AG
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);
152f94fc 1404 TREE_TYPE (index) = ptr_type_node;
e04a16fb
AG
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);
78857b4e 1420 PUSH_FIELD_VALUE (temp, "vtable",
e04a16fb 1421 build1 (ADDR_EXPR, dtable_ptr_type, class_dtable_decl));
64aa33dd
TT
1422 if (! flag_hash_synchronization)
1423 PUSH_FIELD_VALUE (temp, "sync_info", null_pointer_node);
e04a16fb
AG
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);
75d01ad7 1428 PUSH_FIELD_VALUE (cons, "name", build_utf8_ref (DECL_NAME (type_decl)));
e04a16fb
AG
1429 PUSH_FIELD_VALUE (cons, "accflags",
1430 build_int_2 (get_access_flags_from_decl (type_decl), 0));
1431
93089423
AH
1432 PUSH_FIELD_VALUE (cons, "superclass",
1433 CLASS_INTERFACE (type_decl) ? null_pointer_node : super);
e04a16fb
AG
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));
9cfceb60 1437 PUSH_FIELD_VALUE (cons, "method_count", build_int_2 (method_count, 0));
78857b4e 1438 PUSH_FIELD_VALUE (cons, "vtable_method_count", TYPE_NVIRTUALS (type));
e04a16fb
AG
1439 PUSH_FIELD_VALUE (cons, "fields",
1440 fields_decl == NULL_TREE ? null_pointer_node
1441 : build1 (ADDR_EXPR, field_ptr_type_node, fields_decl));
571d54d5
TT
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));
78857b4e 1446 PUSH_FIELD_VALUE (cons, "vtable",
e04a16fb
AG
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);
571d54d5 1451 PUSH_FIELD_VALUE (cons, "interface_count", build_int_2 (interface_len, 0));
9cfceb60 1452 PUSH_FIELD_VALUE (cons, "state", integer_zero_node);
e04a16fb 1453
a7303141 1454 PUSH_FIELD_VALUE (cons, "thread", null_pointer_node);
173f556c
BM
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);
a7303141 1458
e04a16fb
AG
1459 FINISH_RECORD_CONSTRUCTOR (cons);
1460
1461 DECL_INITIAL (decl) = cons;
1462 rest_of_decl_compilation (decl, (char*) 0, 1, 0);
1463}
1464
75d01ad7 1465void
d593dd8c 1466finish_class ()
75d01ad7
PB
1467{
1468 tree method;
ac8f5d48 1469 tree type_methods = TYPE_METHODS (CLASS_TO_HANDLE_TYPE (current_class));
09e7d04a
TT
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
ac8f5d48
AH
1485 /* Emit deferred inline methods. */
1486 for (method = type_methods; method != NULL_TREE; )
75d01ad7
PB
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))
09e7d04a
TT
1493 || ! METHOD_PRIVATE (method)
1494 || saw_native_method)
75d01ad7
PB
1495 {
1496 temporary_allocation ();
1497 output_inline_function (method);
1498 permanent_allocation (1);
ac8f5d48
AH
1499 /* Scan the list again to see if there are any earlier
1500 methods to emit. */
1501 method = type_methods;
1502 continue;
75d01ad7
PB
1503 }
1504 }
ac8f5d48 1505 method = TREE_CHAIN (method);
75d01ad7
PB
1506 }
1507
fcf6eeb6 1508 current_function_decl = NULL_TREE;
75d01ad7
PB
1509 make_class_data (current_class);
1510 register_class ();
1511 rest_of_decl_compilation (TYPE_NAME (current_class), (char*) 0, 1, 0);
1512}
1513
e04a16fb
AG
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. */
1518int
1519is_compiled_class (class)
1520 tree class;
1521{
b351b287 1522 int seen_in_zip;
e04a16fb
AG
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;
b351b287 1531
c2952b01 1532 seen_in_zip = (TYPE_JCF (class) && TYPE_JCF (class)->seen_in_zip);
b351b287 1533 if (CLASS_FROM_CURRENTLY_COMPILED_SOURCE_P (class) || seen_in_zip)
e04a16fb
AG
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
b351b287 1538 build_class_ref () from crashing. */
e04a16fb 1539
b351b287 1540 if (seen_in_zip && !CLASS_LOADED_P (class))
e04a16fb 1541 load_class (class, 1);
b351b287
APB
1542
1543 /* We return 2 for class seen in ZIP and class from files
1544 belonging to the same compilation unit */
e04a16fb
AG
1545 return 2;
1546 }
1547
48aedbca 1548 if (assume_compiled (IDENTIFIER_POINTER (DECL_NAME (TYPE_NAME (class)))))
e04a16fb
AG
1549 {
1550 if (!CLASS_LOADED_P (class))
5e942c50
APB
1551 {
1552 if (CLASS_FROM_SOURCE_P (class))
1553 safe_layout_class (class);
1554 else
1555 load_class (class, 1);
1556 }
e04a16fb
AG
1557 return 1;
1558 }
1559
1560 return 0;
1561}
1562
1563/* Append the mangled name of TYPE onto OBSTACK. */
1564
4bcde32e 1565static void
e04a16fb
AG
1566append_gpp_mangled_type (obstack, type)
1567 struct obstack *obstack;
1568 tree type;
1569{
e04a16fb
AG
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 {
c8e7d2e6 1613 const char *class_name = IDENTIFIER_POINTER (DECL_NAME (TYPE_NAME (type)));
e04a16fb
AG
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
1625static tree
1626mangle_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
4bcde32e 1640static tree
e04a16fb
AG
1641mangle_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
1688tree
1689build_dtable_decl (type)
1690 tree type;
1691{
8f975c18
APB
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 {
50e60bc3 1701 tree dummy = NULL_TREE, aomt, n;
8f975c18
APB
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
e04a16fb
AG
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));
8f975c18 1718 return build_decl (VAR_DECL, name, dtype);
e04a16fb
AG
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
1724void
1725push_super_field (this_class, super_class)
1726 tree this_class, super_class;
1727{
1728 tree base_decl;
c2952b01
APB
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;
e04a16fb
AG
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);
06ceef4e 1739 DECL_SIZE_UNIT (base_decl) = TYPE_SIZE_UNIT (super_class);
e04a16fb
AG
1740}
1741
23a79c61
APB
1742/* Handle the different manners we may have to lay out a super class. */
1743
1744static tree
846b0eb8 1745maybe_layout_super_class (super_class, this_class)
23a79c61 1746 tree super_class;
846b0eb8 1747 tree this_class;
23a79c61
APB
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 */
846b0eb8 1759 else if (TREE_CODE (super_class) == POINTER_TYPE)
23a79c61 1760 {
846b0eb8
PB
1761 if (TREE_TYPE (super_class) != NULL_TREE)
1762 super_class = TREE_TYPE (super_class);
1763 else
1764 {
c2952b01
APB
1765 super_class = do_resolve_class (NULL_TREE, /* FIXME? */
1766 super_class, NULL_TREE, this_class);
846b0eb8
PB
1767 if (!super_class)
1768 return NULL_TREE; /* FIXME, NULL_TREE not checked by caller. */
1769 super_class = TREE_TYPE (super_class);
1770 }
23a79c61
APB
1771 }
1772 if (!TYPE_SIZE (super_class))
1773 safe_layout_class (super_class);
1774
1775 return super_class;
1776}
1777
e04a16fb
AG
1778void
1779layout_class (this_class)
1780 tree this_class;
1781{
c2952b01 1782 static tree list = NULL_TREE;
e04a16fb 1783 tree super_class = CLASSTYPE_SUPER (this_class);
23a79c61 1784 tree field;
c2952b01
APB
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;
e04a16fb
AG
1812
1813 if (super_class)
1814 {
846b0eb8 1815 super_class = maybe_layout_super_class (super_class, this_class);
e04a16fb
AG
1816 if (TREE_CODE (TYPE_SIZE (super_class)) == ERROR_MARK)
1817 {
1818 TYPE_SIZE (this_class) = error_mark_node;
c2952b01
APB
1819 CLASS_BEING_LAIDOUT (this_class) = 0;
1820 list = TREE_CHAIN (list);
e04a16fb
AG
1821 return;
1822 }
e04a16fb
AG
1823 if (TYPE_SIZE (this_class) == NULL_TREE)
1824 push_super_field (this_class, super_class);
1825 }
e04a16fb
AG
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);
4832340c
APB
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)));
c2952b01
APB
1842
1843 CLASS_BEING_LAIDOUT (this_class) = 0;
1844 list = TREE_CHAIN (list);
23a79c61 1845}
e04a16fb 1846
23a79c61
APB
1847void
1848layout_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);
e04a16fb 1860
23a79c61 1861 if (super_class)
e04a16fb 1862 {
846b0eb8 1863 super_class = maybe_layout_super_class (super_class, this_class);
23a79c61
APB
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
1889tree
1890layout_class_method (this_class, super_class, method_decl, dtable_count)
1891 tree this_class, super_class, method_decl, dtable_count;
1892{
c8e7d2e6 1893 const char *ptr;
23a79c61 1894 char *asm_name;
75d01ad7
PB
1895 tree arg, arglist, t;
1896 int method_name_needs_escapes = 0;
23a79c61
APB
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);
75d01ad7 1902
c2952b01 1903 if (!ID_INIT_P (method_name) && !ID_FINIT_P (method_name))
23a79c61 1904 {
75d01ad7
PB
1905 int encoded_len
1906 = unicode_mangling_length (IDENTIFIER_POINTER (method_name),
1907 IDENTIFIER_LENGTH (method_name));
1908 if (encoded_len > 0)
23a79c61 1909 {
75d01ad7
PB
1910 method_name_needs_escapes = 1;
1911 emit_unicode_mangled_name (&temporary_obstack,
1912 IDENTIFIER_POINTER (method_name),
1913 IDENTIFIER_LENGTH (method_name));
23a79c61 1914 }
23a79c61 1915 else
75d01ad7
PB
1916 {
1917 obstack_grow (&temporary_obstack,
1918 IDENTIFIER_POINTER (method_name),
1919 IDENTIFIER_LENGTH (method_name));
1920 }
23a79c61 1921 }
75d01ad7
PB
1922
1923 obstack_grow (&temporary_obstack, "__", 2);
c2952b01 1924 if (ID_FINIT_P (method_name))
75d01ad7
PB
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; )
23a79c61 1934 {
75d01ad7
PB
1935 tree a = arglist;
1936 tree argtype = TREE_VALUE (arg);
1937 int tindex = 1;
1938 if (TREE_CODE (argtype) == POINTER_TYPE)
e04a16fb 1939 {
75d01ad7
PB
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++;
e04a16fb 1943 }
75d01ad7
PB
1944 else
1945 a = arg;
1946 if (a != arg)
e04a16fb 1947 {
75d01ad7
PB
1948 char buf[12];
1949 int nrepeats = 0;
1950 do
e04a16fb 1951 {
75d01ad7 1952 arg = TREE_CHAIN (arg); nrepeats++;
e04a16fb 1953 }
75d01ad7
PB
1954 while (arg != end_params_node && argtype == TREE_VALUE (arg));
1955 if (nrepeats > 1)
e04a16fb 1956 {
75d01ad7
PB
1957 obstack_1grow (&temporary_obstack, 'N');
1958 sprintf (buf, "%d", nrepeats);
23a79c61 1959 obstack_grow (&temporary_obstack, buf, strlen (buf));
75d01ad7 1960 if (nrepeats > 9)
23a79c61 1961 obstack_1grow (&temporary_obstack, '_');
e04a16fb 1962 }
23a79c61 1963 else
75d01ad7
PB
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);
e04a16fb 1974 }
23a79c61 1975 }
75d01ad7
PB
1976 if (method_name_needs_escapes)
1977 obstack_1grow (&temporary_obstack, 'U');
1978
23a79c61
APB
1979 obstack_1grow (&temporary_obstack, '\0');
1980 asm_name = obstack_finish (&temporary_obstack);
1981 DECL_ASSEMBLER_NAME (method_decl) = get_identifier (asm_name);
7f1d4866
APB
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. */
2aa11e97 1984 if (! METHOD_ABSTRACT (method_decl)
7f1d4866 1985 || (CLASS_INTERFACE (TYPE_NAME (this_class))
c2952b01 1986 && (DECL_CLINIT_P (method_decl))))
23a79c61
APB
1987 make_function_rtl (method_decl);
1988 obstack_free (&temporary_obstack, asm_name);
7f1d4866 1989
c2952b01 1990 if (ID_INIT_P (method_name))
23a79c61 1991 {
c8e7d2e6 1992 const char *p = IDENTIFIER_POINTER (DECL_NAME (TYPE_NAME (this_class)));
23a79c61 1993 for (ptr = p; *ptr; )
e04a16fb 1994 {
23a79c61
APB
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;
c3f2a476 2003 build_java_argument_signature (TREE_TYPE (method_decl));
23a79c61
APB
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,
e04a16fb 2010 method_sig);
30ca27b4 2011 if (super_method != NULL_TREE && ! METHOD_PRIVATE (super_method))
23a79c61
APB
2012 {
2013 DECL_VINDEX (method_decl) = DECL_VINDEX (super_method);
7f10c2e2
APB
2014 if (DECL_VINDEX (method_decl) == NULL_TREE
2015 && !CLASS_FROM_SOURCE_P (this_class))
23a79c61
APB
2016 error_with_decl (method_decl,
2017 "non-static method '%s' overrides static method");
e04a16fb 2018#if 0
75d01ad7
PB
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 }
e04a16fb 2027#endif
23a79c61
APB
2028 }
2029 else if (! METHOD_FINAL (method_decl)
75d01ad7 2030 && ! METHOD_PRIVATE (method_decl)
23a79c61
APB
2031 && ! CLASS_FINAL (TYPE_NAME (this_class))
2032 && dtable_count)
2033 {
2034 DECL_VINDEX (method_decl) = dtable_count;
665f2503
RK
2035 dtable_count = fold (build (PLUS_EXPR, integer_type_node,
2036 dtable_count, integer_one_node));
e04a16fb
AG
2037 }
2038 }
665f2503 2039
23a79c61 2040 return dtable_count;
e04a16fb
AG
2041}
2042
2043static tree registered_class = NULL_TREE;
2044
2045void
2046register_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
2064void
866e9df8 2065emit_register_classes ()
e04a16fb 2066{
df32d2ce 2067 extern tree get_file_function_name PARAMS ((int));
e04a16fb 2068 tree init_name = get_file_function_name ('I');
75d01ad7 2069 tree init_type = build_function_type (void_type_node, end_params_node);
e04a16fb
AG
2070 tree init_decl;
2071 tree t;
2072
e04a16fb
AG
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 */
e04a16fb
AG
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
2102void
2103init_class_processing ()
2104{
a7303141 2105 registerClass_libfunc = gen_rtx (SYMBOL_REF, Pmode, "_Jv_RegisterClass");
e04a16fb 2106}