OSDN Git Service

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