OSDN Git Service

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