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