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