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