OSDN Git Service

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