OSDN Git Service

21232e7f2d2e41234534814232b3245a77f5067f
[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 }
404
405 /* Return length of inheritance chain of CLAS, where java.lang.Object is 0,
406    direct sub-classes of Object are 1, and so on. */
407
408 int
409 class_depth (clas)
410      tree clas;
411 {
412   int depth = 0;
413   if (! CLASS_LOADED_P (clas))
414     load_class (clas, 1);
415   if (TYPE_SIZE (clas) == error_mark_node)
416     return -1;
417   while (clas != object_type_node)
418     {
419       depth++;
420       clas = TYPE_BINFO_BASETYPE (clas, 0);
421     }
422   return depth;
423 }
424
425 /* Return true iff TYPE2 is an interface that extends interface TYPE1 */
426
427 int
428 interface_of_p (type1, type2)
429      tree type1, type2;
430 {
431   int n, i;
432   tree basetype_vec;
433
434   if (!(basetype_vec = TYPE_BINFO_BASETYPES (type2)))
435     return 0;
436   n = TREE_VEC_LENGTH (basetype_vec);
437   for (i = 0; i < n; i++)
438     {
439       tree vec_elt = TREE_VEC_ELT (basetype_vec, i);
440       if (vec_elt && BINFO_TYPE (vec_elt) == type1)
441         return 1;
442     }
443   for (i = 0; i < n; i++)
444     {
445       tree vec_elt = TREE_VEC_ELT (basetype_vec, i);
446       if (vec_elt && BINFO_TYPE (vec_elt) 
447           && interface_of_p (type1, BINFO_TYPE (vec_elt)))
448         return 1;
449     }
450   return 0;
451 }
452
453 /* Return true iff TYPE1 inherits from TYPE2. */
454
455 int
456 inherits_from_p (type1, type2)
457      tree type1, type2;
458 {
459   while (type1 != NULL_TREE && TREE_CODE (type1) == RECORD_TYPE)
460     {
461       if (type1 == type2)
462         return 1;
463       type1 = CLASSTYPE_SUPER (type1);
464     }
465   return 0;
466 }
467
468 /* Return a 1 iff TYPE1 is an enclosing context for TYPE2 */
469
470 int
471 enclosing_context_p (type1, type2)
472      tree type1, type2;
473 {
474   if (!INNER_CLASS_TYPE_P (type2))
475     return 0;
476
477   for (type2 = TREE_TYPE (DECL_CONTEXT (TYPE_NAME (type2)));
478        type2; 
479        type2 = (INNER_CLASS_TYPE_P (type2) ?
480                 TREE_TYPE (DECL_CONTEXT (TYPE_NAME (type2))) : NULL_TREE))
481     {
482       if (type2 == type1)
483         return 1;
484     }
485
486   return 0;
487 }
488
489 static void
490 add_interface_do (basetype_vec, interface_class, i)
491      tree basetype_vec, interface_class;
492      int i;
493 {
494   tree interface_binfo = make_tree_vec (6);
495   BINFO_TYPE (interface_binfo) = interface_class;
496   BINFO_OFFSET (interface_binfo) = integer_zero_node;
497   TREE_VIA_VIRTUAL (interface_binfo) = 1;
498   TREE_VIA_PUBLIC (interface_binfo) = 1;
499   TREE_VEC_ELT (basetype_vec, i) = interface_binfo;
500 }
501
502 /* Add INTERFACE_CLASS to THIS_CLASS iff INTERFACE_CLASS can't be
503    found in THIS_CLASS. Returns NULL_TREE upon success, INTERFACE_CLASS
504    if attempt is made to add it twice. */
505
506 tree
507 maybe_add_interface (this_class, interface_class)
508      tree this_class, interface_class;
509 {
510   tree basetype_vec = TYPE_BINFO_BASETYPES (this_class);
511   int i;
512   int n = TREE_VEC_LENGTH (basetype_vec);
513   for (i = 0; ; i++)
514     {
515       if (i >= n)
516         {
517           error ("internal error - too many interface type");
518           return NULL_TREE;
519         }
520       else if (TREE_VEC_ELT (basetype_vec, i) == NULL_TREE)
521         break;
522       else if (BINFO_TYPE (TREE_VEC_ELT (basetype_vec, i)) == interface_class)
523         return interface_class;
524     } 
525   add_interface_do (basetype_vec, interface_class, i);
526   return NULL_TREE;
527 }
528
529 /* Add the INTERFACE_CLASS as one of the interfaces of THIS_CLASS. */
530
531 void
532 add_interface (this_class, interface_class)
533      tree this_class, interface_class;
534 {
535   tree basetype_vec = TYPE_BINFO_BASETYPES (this_class);
536   int i;
537   int n = TREE_VEC_LENGTH (basetype_vec);
538   for (i = 0; ; i++)
539     {
540       if (i >= n)
541         {
542           error ("internal error - too many interface type");
543           return;
544         }
545       else if (TREE_VEC_ELT (basetype_vec, i) == NULL_TREE)
546         break;
547     }
548   add_interface_do (basetype_vec, interface_class, i);
549 }
550
551 #if 0
552 /* Return the address of a pointer to the first FUNCTION_DECL
553    in the list (*LIST) whose DECL_NAME is NAME. */
554
555 static tree *
556 find_named_method (list, name)
557      tree *list;
558      tree name;
559 {
560   while (*list && DECL_NAME (*list) != name)
561     list = &TREE_CHAIN (*list);
562   return list;
563 }
564 #endif
565
566 static tree
567 build_java_method_type (fntype, this_class, access_flags)
568      tree fntype;
569      tree this_class;
570      int access_flags;
571 {
572   if (access_flags & ACC_STATIC)
573     return fntype;
574   return build_method_type (CLASS_TO_HANDLE_TYPE (this_class), fntype);
575 }
576
577 static struct hash_entry *
578 init_test_hash_newfunc (entry, table, string)
579      struct hash_entry *entry;
580      struct hash_table *table;
581      hash_table_key string ATTRIBUTE_UNUSED;
582 {
583   struct init_test_hash_entry *ret = (struct init_test_hash_entry *) entry;
584   if (ret == NULL)
585     {
586       ret = ((struct init_test_hash_entry *)
587              hash_allocate (table, sizeof (struct init_test_hash_entry)));
588       if (ret == NULL)
589         return NULL;
590     }
591   ret->init_test_decl = 0;
592   return (struct hash_entry *) ret;
593 }
594
595 /* Hash table helpers. Also reused in find_applicable_accessible_methods_list
596    (parse.y). The hash of a tree node is it's pointer value,
597    comparison is direct. */
598
599 unsigned long
600 java_hash_hash_tree_node (k)
601      hash_table_key k;
602 {
603   return (long) k;
604 }
605
606 boolean
607 java_hash_compare_tree_node (k1, k2)
608      hash_table_key k1;
609      hash_table_key k2;
610 {
611   return ((char*) k1 == (char*) k2);
612 }
613
614 tree
615 add_method_1 (handle_class, access_flags, name, function_type)
616      tree handle_class;
617      int access_flags;
618      tree name;
619      tree function_type;
620 {
621   tree method_type, fndecl;
622   push_obstacks (&permanent_obstack, &permanent_obstack);
623
624   method_type = build_java_method_type (function_type,
625                                         handle_class, access_flags);
626
627   fndecl = build_decl (FUNCTION_DECL, name, method_type);
628   DECL_CONTEXT (fndecl) = handle_class;
629
630   DECL_LANG_SPECIFIC (fndecl)
631     = (struct lang_decl *) permalloc (sizeof (struct lang_decl));
632   bzero ((PTR) DECL_LANG_SPECIFIC (fndecl), sizeof (struct lang_decl));
633
634   /* Initialize the static initializer test table.  */
635   hash_table_init (&DECL_FUNCTION_INIT_TEST_TABLE (fndecl),
636                    init_test_hash_newfunc, java_hash_hash_tree_node, 
637                    java_hash_compare_tree_node);
638
639   TREE_CHAIN (fndecl) = TYPE_METHODS (handle_class);
640   TYPE_METHODS (handle_class) = fndecl;
641   pop_obstacks ();
642
643   if (access_flags & ACC_PUBLIC) METHOD_PUBLIC (fndecl) = 1;
644   if (access_flags & ACC_PROTECTED) METHOD_PROTECTED (fndecl) = 1;
645   if (access_flags & ACC_PRIVATE)
646     METHOD_PRIVATE (fndecl) = DECL_INLINE (fndecl) = 1;
647   if (access_flags & ACC_NATIVE)
648     {
649       METHOD_NATIVE (fndecl) = 1;
650       DECL_EXTERNAL (fndecl) = 1;
651     }
652   if (access_flags & ACC_STATIC) 
653     METHOD_STATIC (fndecl) = DECL_INLINE (fndecl) = 1;
654   if (access_flags & ACC_FINAL) 
655     METHOD_FINAL (fndecl) = DECL_INLINE (fndecl) = 1;
656   if (access_flags & ACC_SYNCHRONIZED) METHOD_SYNCHRONIZED (fndecl) = 1;
657   if (access_flags & ACC_ABSTRACT) METHOD_ABSTRACT (fndecl) = 1;
658   if (access_flags & ACC_TRANSIENT) METHOD_TRANSIENT (fndecl) = 1;
659   return fndecl;
660 }
661
662 /* Add a method to THIS_CLASS.
663    The method's name is NAME.
664    Its signature (mangled type) is METHOD_SIG (an IDENTIFIER_NODE). */
665
666 tree
667 add_method (this_class, access_flags, name, method_sig)
668      tree this_class;
669      int access_flags;
670      tree name;
671      tree method_sig;
672 {
673   tree handle_class = CLASS_TO_HANDLE_TYPE (this_class);
674   tree function_type, fndecl;
675   const unsigned char *sig = (const unsigned char*)IDENTIFIER_POINTER (method_sig);
676   push_obstacks (&permanent_obstack, &permanent_obstack);
677   if (sig[0] != '(')
678     fatal ("bad method signature");
679   function_type = get_type_from_signature (method_sig);
680   fndecl = add_method_1 (handle_class, access_flags, name, function_type);
681   set_java_signature (TREE_TYPE (fndecl), method_sig);
682   pop_obstacks ();
683   return fndecl;
684 }
685
686 tree
687 add_field (class, name, field_type, flags)
688      tree class;
689      tree name;
690      tree field_type;
691      int flags;
692 {
693   int is_static = (flags & ACC_STATIC) != 0;
694   tree field;
695   /* Push the obstack of field_type ? FIXME */
696   push_obstacks (&permanent_obstack, &permanent_obstack);
697   field = build_decl (is_static ? VAR_DECL : FIELD_DECL, name, field_type);
698   pop_obstacks ();
699   TREE_CHAIN (field) = TYPE_FIELDS (class);
700   TYPE_FIELDS (class) = field;
701   DECL_CONTEXT (field) = class;
702
703   if (flags & ACC_PUBLIC) FIELD_PUBLIC (field) = 1;
704   if (flags & ACC_PROTECTED) FIELD_PROTECTED (field) = 1;
705   if (flags & ACC_PRIVATE) FIELD_PRIVATE (field) = 1;
706   if (flags & ACC_FINAL) FIELD_FINAL (field) = 1;
707   if (flags & ACC_VOLATILE) FIELD_VOLATILE (field) = 1;
708   if (flags & ACC_TRANSIENT) FIELD_TRANSIENT (field) = 1;
709   if (is_static)
710     {
711       FIELD_STATIC (field) = 1;
712       /* Always make field externally visible.  This is required so
713          that native methods can always access the field.  */
714       TREE_PUBLIC (field) = 1;
715     }
716   return field;
717 }
718
719 /* Associate a constant value CONSTANT with VAR_DECL FIELD. */
720
721 void
722 set_constant_value (field, constant)
723      tree field, constant;
724 {
725   if (field == NULL_TREE)
726     warning ("misplaced ConstantValue attribute (not in any field)");
727   else if (DECL_INITIAL (field) != NULL_TREE)
728     warning ("duplicate ConstanValue atribute for field '%s'",
729              IDENTIFIER_POINTER (DECL_NAME (field)));
730   else
731     DECL_INITIAL (field) = constant;
732 }
733
734 /* Count the number of Unicode chars encoded in a given Ut8 string. */
735
736 #if 0
737 int
738 strLengthUtf8 (str, len)
739      char *str;
740      int len;
741 {
742   register unsigned char* ptr = (unsigned char*) str;
743   register unsigned char *limit = ptr + len;
744   int str_length = 0;
745   for (; ptr < limit; str_length++) {
746     if (UTF8_GET (ptr, limit) < 0)
747       return -1;
748   }
749   return str_length;
750 }
751 #endif
752
753
754 /* Calculate a hash value for a string encoded in Utf8 format.
755  * This returns the same hash value as specified for java.lang.String.hashCode.
756  */
757
758 static int32
759 hashUtf8String (str, len)
760      const char *str;
761      int len;
762 {
763   register const unsigned char* ptr = (const unsigned char*) str;
764   register const unsigned char *limit = ptr + len;
765   int32 hash = 0;
766   for (; ptr < limit;)
767     {
768       int ch = UTF8_GET (ptr, limit);
769       /* Updated specification from
770          http://www.javasoft.com/docs/books/jls/clarify.html. */
771       hash = (31 * hash) + ch;
772     }
773   return hash;
774 }
775
776 tree utf8_decl_list = NULL_TREE;
777
778 tree
779 build_utf8_ref (name)
780      tree name;
781 {
782   const char * name_ptr = IDENTIFIER_POINTER(name);
783   int name_len = IDENTIFIER_LENGTH(name);
784   char buf[60];
785   char *buf_ptr;
786   tree ctype, field = NULL_TREE, str_type, cinit, string;
787   static int utf8_count = 0;
788   int name_hash;
789   tree ref = IDENTIFIER_UTF8_REF (name);
790   tree decl;
791   if (ref != NULL_TREE)
792     return ref;
793
794   push_obstacks (&permanent_obstack, &permanent_obstack);
795   ctype = make_node (RECORD_TYPE);
796   str_type = build_prim_array_type (unsigned_byte_type_node,
797                                     name_len + 1); /* Allow for final '\0'. */
798   PUSH_FIELD (ctype, field, "hash", unsigned_short_type_node);
799   PUSH_FIELD (ctype, field, "length", unsigned_short_type_node);
800   PUSH_FIELD (ctype, field, "data", str_type);
801   FINISH_RECORD (ctype);
802   START_RECORD_CONSTRUCTOR (cinit, ctype);
803   name_hash = hashUtf8String (name_ptr, name_len) & 0xFFFF;
804   PUSH_FIELD_VALUE (cinit, "hash", build_int_2 (name_hash, 0));
805   PUSH_FIELD_VALUE (cinit, "length", build_int_2 (name_len, 0));
806   string = build_string (name_len, name_ptr);
807   TREE_TYPE (string) = str_type;
808   PUSH_FIELD_VALUE (cinit, "data", string);
809   FINISH_RECORD_CONSTRUCTOR (cinit);
810   TREE_CONSTANT (cinit) = 1;
811
812   /* Build a unique identifier based on buf. */
813   sprintf(buf, "_Utf%d", ++utf8_count);
814   buf_ptr = &buf[strlen (buf)];
815   if (name_len > 0 && name_ptr[0] >= '0' && name_ptr[0] <= '9')
816     *buf_ptr++ = '_';
817   while (--name_len >= 0)
818     {
819       unsigned char c = *name_ptr++;
820       if (c & 0x80)
821         continue;
822       if (!ISALPHA(c) && !ISDIGIT(c))
823         c = '_';
824       *buf_ptr++ = c;
825       if (buf_ptr >= buf + 50)
826         break;
827     }
828   *buf_ptr = '\0';
829
830   decl = build_decl (VAR_DECL, get_identifier (buf), utf8const_type);
831   /* FIXME get some way to force this into .text, not .data. */
832   TREE_STATIC (decl) = 1;
833   DECL_ARTIFICIAL (decl) = 1;
834   DECL_IGNORED_P (decl) = 1;
835   TREE_READONLY (decl) = 1;
836   TREE_THIS_VOLATILE (decl) = 0;
837   DECL_INITIAL (decl) = cinit;
838   TREE_CHAIN (decl) = utf8_decl_list;
839   layout_decl (decl, 0);
840   pushdecl (decl);
841   rest_of_decl_compilation (decl, (char*) 0, global_bindings_p (), 0);
842   utf8_decl_list = decl;
843   make_decl_rtl (decl, (char*) 0, 1);
844   ref = build1 (ADDR_EXPR, utf8const_ptr_type, decl);
845   IDENTIFIER_UTF8_REF (name) = ref;
846   pop_obstacks ();
847   return ref;
848 }
849
850 /* Build a reference to the class TYPE.
851    Also handles primitive types and array types. */
852
853 tree
854 build_class_ref (type)
855      tree type;
856 {
857   int is_compiled = is_compiled_class (type);
858   if (is_compiled)
859     {
860       tree ref, decl_name, decl;
861       if (TREE_CODE (type) == POINTER_TYPE)
862         type = TREE_TYPE (type);
863       if (TREE_CODE (type) == RECORD_TYPE)
864         {
865           if (TYPE_SIZE (type) == error_mark_node)
866             return null_pointer_node;
867           decl_name = identifier_subst (DECL_NAME (TYPE_NAME (type)),
868                                         "", '/', '/', ".class");
869           decl = IDENTIFIER_GLOBAL_VALUE (decl_name);
870           if (decl == NULL_TREE)
871             {
872               push_obstacks (&permanent_obstack, &permanent_obstack);
873               decl = build_decl (VAR_DECL, decl_name, class_type_node);
874               DECL_SIZE (decl) = TYPE_SIZE (class_type_node);
875               DECL_SIZE_UNIT (decl) = TYPE_SIZE_UNIT (class_type_node);
876               TREE_STATIC (decl) = 1;
877               TREE_PUBLIC (decl) = 1;
878               DECL_IGNORED_P (decl) = 1;
879               DECL_ARTIFICIAL (decl) = 1;
880               DECL_ASSEMBLER_NAME (decl) = mangle_class_field (type);
881               make_decl_rtl (decl, NULL, 1);
882               pushdecl_top_level (decl);
883               if (is_compiled == 1)
884                 DECL_EXTERNAL (decl) = 1;
885               pop_obstacks ();
886             }
887         }
888       else
889         {
890           const char *name;
891           char buffer[25];
892           if (flag_emit_class_files)
893             {
894               const char *prim_class_name;
895               tree prim_class;
896               if (type == char_type_node)
897                 prim_class_name = "java.lang.Character";
898               else if (type == boolean_type_node)
899                 prim_class_name = "java.lang.Boolean";
900               else if (type == byte_type_node)
901                 prim_class_name = "java.lang.Byte";
902               else if (type == short_type_node)
903                 prim_class_name = "java.lang.Short";
904               else if (type == int_type_node)
905                 prim_class_name = "java.lang.Integer";
906               else if (type == long_type_node)
907                 prim_class_name = "java.lang.Long";
908               else if (type == float_type_node)
909                 prim_class_name = "java.lang.Float";
910               else if (type == double_type_node)
911                 prim_class_name = "java.lang.Double";
912               else if (type == void_type_node)
913                 prim_class_name = "java.lang.Void";
914               else
915                 fatal ("internal error - bad type to build_class_ref");
916               prim_class = lookup_class (get_identifier (prim_class_name));
917               return build (COMPONENT_REF, NULL_TREE,
918                             prim_class, TYPE_identifier_node);
919             }
920           decl_name = TYPE_NAME (type);
921           if (TREE_CODE (decl_name) == TYPE_DECL)
922             decl_name = DECL_NAME (decl_name);
923           name = IDENTIFIER_POINTER (decl_name);
924           if (strncmp (name, "promoted_", 9) == 0)
925             name += 9;
926           sprintf (buffer, "_Jv_%sClass", name);
927           decl_name = get_identifier (buffer);
928           decl = IDENTIFIER_GLOBAL_VALUE (decl_name);
929           if (decl == NULL_TREE)
930             {
931               push_obstacks (&permanent_obstack, &permanent_obstack);
932               decl = build_decl (VAR_DECL, decl_name, class_type_node);
933               TREE_STATIC (decl) = 1;
934               TREE_PUBLIC (decl) = 1;
935               make_decl_rtl (decl, NULL, 1);
936               pushdecl_top_level (decl);
937               if (is_compiled == 1)
938                 DECL_EXTERNAL (decl) = 1;
939               pop_obstacks ();
940             }
941         }
942
943       ref = build1 (ADDR_EXPR, class_ptr_type, decl);
944       return ref;
945     }
946   else
947     {
948       int index;
949       tree cl;
950       push_obstacks (&permanent_obstack, &permanent_obstack);
951       index = alloc_class_constant (type);
952       cl = build_ref_from_constant_pool (index); 
953       TREE_TYPE (cl) = promote_type (class_ptr_type);
954       pop_obstacks ();
955       return cl;
956     }
957 }
958
959 tree
960 build_static_field_ref (fdecl)
961      tree fdecl;
962 {
963   tree fclass = DECL_CONTEXT (fdecl);
964   int is_compiled = is_compiled_class (fclass);
965   if (is_compiled)
966     {
967       if (DECL_RTL (fdecl) == 0)
968         {
969           push_obstacks (&permanent_obstack, &permanent_obstack);
970           make_decl_rtl (fdecl, NULL, 1);
971           pop_obstacks ();
972           if (is_compiled == 1)
973             DECL_EXTERNAL (fdecl) = 1;
974         }
975       return fdecl;
976     }
977   else
978     {
979       /* Compile as:
980        * *(FTYPE*)build_class_ref(FCLASS)->fields[INDEX].info.addr */
981       static tree fields_ident = NULL_TREE;
982       static tree info_ident = NULL_TREE;
983       tree ref = build_class_ref (fclass);
984       tree fld;
985       int field_index = 0;
986       ref = build1 (INDIRECT_REF, class_type_node, ref);
987       if (fields_ident == NULL_TREE)
988         fields_ident = get_identifier ("fields");
989       if (info_ident == NULL_TREE)
990         info_ident = get_identifier ("info");
991       ref = build (COMPONENT_REF, field_ptr_type_node, ref,
992                    lookup_field (&class_type_node, fields_ident));
993
994       for (fld = TYPE_FIELDS (fclass); ; fld = TREE_CHAIN (fld))
995         {
996           if (fld == fdecl)
997             break;
998           if (fld == NULL_TREE)
999             fatal ("field '%s' not found in class",
1000                    IDENTIFIER_POINTER (DECL_NAME (fdecl)));
1001           if (FIELD_STATIC (fld))
1002             field_index++;
1003         }
1004       field_index *= int_size_in_bytes (field_type_node);
1005       ref = fold (build (PLUS_EXPR, field_ptr_type_node,
1006                          ref, build_int_2 (field_index, 0)));
1007       ref = build1 (INDIRECT_REF, field_type_node, ref);
1008       ref = build (COMPONENT_REF, field_info_union_node,
1009                    ref, lookup_field (&field_type_node, info_ident));
1010       ref = build (COMPONENT_REF, ptr_type_node,
1011                    ref, TREE_CHAIN (TYPE_FIELDS (field_info_union_node)));
1012       return fold (build1 (INDIRECT_REF, TREE_TYPE(fdecl), ref));
1013     }
1014 }
1015
1016 int
1017 get_access_flags_from_decl (decl)
1018      tree decl;
1019 {
1020   int access_flags = 0;
1021   if (TREE_CODE (decl) == FIELD_DECL || TREE_CODE (decl) == VAR_DECL)
1022     {
1023       if (FIELD_STATIC (decl))
1024         access_flags |= ACC_STATIC;
1025       if (FIELD_PUBLIC (decl))
1026         access_flags |= ACC_PUBLIC;
1027       if (FIELD_PROTECTED (decl))
1028         access_flags |= ACC_PROTECTED;
1029       if (FIELD_PRIVATE (decl))
1030         access_flags |= ACC_PRIVATE;
1031       if (FIELD_FINAL (decl))
1032         access_flags |= ACC_FINAL;
1033       if (FIELD_VOLATILE (decl))
1034         access_flags |= ACC_VOLATILE;
1035       if (FIELD_TRANSIENT (decl))
1036         access_flags |= ACC_TRANSIENT;
1037       return access_flags;
1038     }
1039   if (TREE_CODE (decl) == TYPE_DECL)
1040     {
1041       if (CLASS_PUBLIC (decl))
1042         access_flags |= ACC_PUBLIC;
1043       if (CLASS_FINAL (decl))
1044         access_flags |= ACC_FINAL;
1045       if (CLASS_SUPER (decl))
1046         access_flags |= ACC_SUPER;
1047       if (CLASS_INTERFACE (decl))
1048         access_flags |= ACC_INTERFACE;
1049       if (CLASS_ABSTRACT (decl))
1050         access_flags |= ACC_ABSTRACT;
1051       if (CLASS_STATIC (decl))
1052         access_flags |= ACC_STATIC;
1053       return access_flags;
1054     }
1055   if (TREE_CODE (decl) == FUNCTION_DECL)
1056     {
1057       if (METHOD_PUBLIC (decl))
1058         access_flags |= ACC_PUBLIC;
1059       if (METHOD_PRIVATE (decl))
1060         access_flags |= ACC_PRIVATE;
1061       if (METHOD_PROTECTED (decl))
1062         access_flags |= ACC_PROTECTED;
1063       if (METHOD_STATIC (decl))
1064         access_flags |= ACC_STATIC;
1065       if (METHOD_FINAL (decl))
1066         access_flags |= ACC_FINAL;
1067       if (METHOD_SYNCHRONIZED (decl))
1068         access_flags |= ACC_SYNCHRONIZED;
1069       if (METHOD_NATIVE (decl))
1070         access_flags |= ACC_NATIVE;
1071       if (METHOD_ABSTRACT (decl))
1072         access_flags |= ACC_ABSTRACT;
1073       if (METHOD_TRANSIENT (decl))
1074         access_flags |= ACC_TRANSIENT;
1075       return access_flags;
1076     }
1077   abort ();
1078 }
1079
1080 static tree
1081 make_field_value (fdecl)
1082   tree fdecl;
1083 {
1084   tree finit;
1085   int flags;
1086   tree type = TREE_TYPE (fdecl);
1087   int resolved = is_compiled_class (type);
1088
1089   START_RECORD_CONSTRUCTOR (finit, field_type_node);
1090   PUSH_FIELD_VALUE (finit, "name", build_utf8_ref (DECL_NAME (fdecl)));
1091   if (resolved)
1092     type = build_class_ref (type);
1093   else
1094     {
1095       tree signature = build_java_signature (type);
1096
1097       type = build_utf8_ref (unmangle_classname 
1098                              (IDENTIFIER_POINTER (signature),
1099                               IDENTIFIER_LENGTH (signature)));
1100     }
1101   PUSH_FIELD_VALUE (finit, "type", type);
1102
1103   flags = get_access_flags_from_decl (fdecl);
1104   if (! resolved)
1105     flags |= 0x8000 /* FIELD_UNRESOLVED_FLAG */;
1106
1107   PUSH_FIELD_VALUE (finit, "accflags", build_int_2 (flags, 0));
1108   PUSH_FIELD_VALUE (finit, "bsize", TYPE_SIZE_UNIT (TREE_TYPE (fdecl)));
1109
1110   PUSH_FIELD_VALUE
1111     (finit, "info",
1112      build (CONSTRUCTOR, field_info_union_node, NULL_TREE,
1113             build_tree_list
1114             ((FIELD_STATIC (fdecl)
1115               ? TREE_CHAIN (TYPE_FIELDS (field_info_union_node))
1116               : TYPE_FIELDS (field_info_union_node)),
1117              (FIELD_STATIC (fdecl)
1118               ? build_address_of (build_static_field_ref (fdecl))
1119               : byte_position (fdecl)))));
1120
1121   FINISH_RECORD_CONSTRUCTOR (finit);
1122   return finit;
1123 }
1124
1125 static tree
1126 make_method_value (mdecl)
1127      tree mdecl;
1128 {
1129   tree minit;
1130   tree code;
1131 #define ACC_TRANSLATED          0x4000
1132   int accflags = get_access_flags_from_decl (mdecl) | ACC_TRANSLATED;
1133   code = null_pointer_node;
1134   if (DECL_RTL (mdecl))
1135     code = build1 (ADDR_EXPR, nativecode_ptr_type_node, mdecl);
1136   START_RECORD_CONSTRUCTOR (minit, method_type_node);
1137   PUSH_FIELD_VALUE (minit, "name",
1138                     build_utf8_ref (DECL_CONSTRUCTOR_P (mdecl) ?
1139                                     init_identifier_node
1140                                     : DECL_NAME (mdecl)));
1141   {
1142     tree signature = build_java_signature (TREE_TYPE (mdecl));
1143     PUSH_FIELD_VALUE (minit, "signature", 
1144                       (build_utf8_ref 
1145                        (unmangle_classname 
1146                         (IDENTIFIER_POINTER(signature),
1147                          IDENTIFIER_LENGTH(signature)))));
1148   }
1149   PUSH_FIELD_VALUE (minit, "accflags", build_int_2 (accflags, 0));
1150   PUSH_FIELD_VALUE (minit, "ncode", code);
1151   FINISH_RECORD_CONSTRUCTOR (minit);
1152   return minit;
1153 }
1154
1155 static tree
1156 get_dispatch_vector (type)
1157      tree type;
1158 {
1159   tree vtable = TYPE_VTABLE (type);
1160   if (vtable == NULL)
1161     {
1162       HOST_WIDE_INT i;
1163       tree method;
1164       tree super = CLASSTYPE_SUPER (type);
1165       HOST_WIDE_INT nvirtuals = tree_low_cst (TYPE_NVIRTUALS (type), 0);
1166       vtable = make_tree_vec (nvirtuals);
1167       TYPE_VTABLE (type) = vtable;
1168       if (super != NULL_TREE)
1169         {
1170           tree super_vtable = get_dispatch_vector (super);
1171
1172           for (i = tree_low_cst (TYPE_NVIRTUALS (super), 0); --i >= 0; )
1173             TREE_VEC_ELT (vtable, i) = TREE_VEC_ELT (super_vtable, i);
1174         }
1175
1176       for (method = TYPE_METHODS (type);  method != NULL_TREE;
1177            method = TREE_CHAIN (method))
1178         if (DECL_VINDEX (method) != NULL_TREE
1179             && host_integerp (DECL_VINDEX (method), 0))
1180           TREE_VEC_ELT (vtable, tree_low_cst (DECL_VINDEX (method), 0))
1181             = method;
1182     }
1183
1184   return vtable;
1185 }
1186
1187 static tree
1188 get_dispatch_table (type, this_class_addr)
1189      tree type, this_class_addr;
1190 {
1191   tree vtable = get_dispatch_vector (type);
1192   int i;
1193   tree list = NULL_TREE;
1194   int nvirtuals = TREE_VEC_LENGTH (vtable);
1195   for (i = nvirtuals;  --i >= 0; )
1196     {
1197       tree method = TREE_VEC_ELT (vtable, i);
1198       if (METHOD_ABSTRACT (method))
1199         warning_with_decl (method, "abstract method in non-abstract class");
1200       if (DECL_RTL (method) == 0)
1201         make_decl_rtl (method, NULL, 1);
1202       list = tree_cons (NULL_TREE /*DECL_VINDEX (method) + 2*/,
1203                         build1 (ADDR_EXPR, nativecode_ptr_type_node, method),
1204                         list);
1205     }
1206   /* Dummy entry for compatibility with G++ -fvtable-thunks.  When
1207      using the Boehm GC we sometimes stash a GC type descriptor
1208      there.  */
1209   list = tree_cons (integer_zero_node, get_boehm_type_descriptor (type),
1210                     list);
1211   list = tree_cons (integer_zero_node, this_class_addr, list);
1212   return build (CONSTRUCTOR, build_prim_array_type (nativecode_ptr_type_node,
1213                                                     nvirtuals + 2),
1214                  NULL_TREE, list);
1215 }
1216
1217 void
1218 make_class_data (type)
1219      tree type;
1220 {
1221   tree decl, cons, temp;
1222   tree field, fields_decl;
1223   tree static_fields = NULL_TREE;
1224   tree instance_fields = NULL_TREE;
1225   HOST_WIDE_INT static_field_count = 0;
1226   HOST_WIDE_INT instance_field_count = 0;
1227   HOST_WIDE_INT field_count;
1228   tree field_array_type;
1229   tree method;
1230   tree methods = NULL_TREE;
1231   tree dtable_decl = NULL_TREE;
1232   HOST_WIDE_INT method_count = 0;
1233   tree method_array_type;
1234   tree methods_decl;
1235   tree super;
1236   tree this_class_addr;
1237   tree constant_pool_constructor;
1238   tree interfaces = null_pointer_node;
1239   int interface_len = 0;
1240   tree type_decl = TYPE_NAME (type);
1241
1242   this_class_addr = build_class_ref (type);
1243   decl = TREE_OPERAND (this_class_addr, 0);
1244
1245   /* Build Field array. */
1246   field = TYPE_FIELDS (type);
1247   if (DECL_NAME (field) == NULL_TREE)
1248     field = TREE_CHAIN (field);  /* Skip dummy field for inherited data. */
1249   for ( ;  field != NULL_TREE;  field = TREE_CHAIN (field))
1250     {
1251       if (! DECL_ARTIFICIAL (field))
1252         {
1253           tree init = make_field_value (field);
1254           if (FIELD_STATIC (field))
1255             {
1256               tree initial = DECL_INITIAL (field);
1257               static_field_count++;
1258               static_fields = tree_cons (NULL_TREE, init, static_fields);
1259               /* If the initial value is a string constant,
1260                  prevent output_constant from trying to assemble the value. */
1261               if (initial != NULL_TREE
1262                   && TREE_TYPE (initial) == string_ptr_type_node)
1263                 DECL_INITIAL (field) = NULL_TREE;
1264               rest_of_decl_compilation (field, (char*) 0, 1, 1);
1265               DECL_INITIAL (field) = initial;
1266             }
1267           else
1268             {
1269               instance_field_count++;
1270               instance_fields = tree_cons (NULL_TREE, init, instance_fields);
1271             }
1272         }
1273     }
1274   field_count = static_field_count + instance_field_count;
1275   if (field_count > 0)
1276     {
1277       static_fields = nreverse (static_fields);
1278       instance_fields = nreverse (instance_fields);
1279       static_fields = chainon (static_fields, instance_fields);
1280       field_array_type = build_prim_array_type (field_type_node, field_count);
1281       fields_decl = build_decl (VAR_DECL, mangled_classname ("_FL_", type),
1282                                 field_array_type);
1283       DECL_INITIAL (fields_decl) = build (CONSTRUCTOR, field_array_type,
1284                                           NULL_TREE, static_fields);
1285       TREE_STATIC (fields_decl) = 1;
1286       DECL_ARTIFICIAL (fields_decl) = 1;
1287       DECL_IGNORED_P (fields_decl) = 1;
1288       rest_of_decl_compilation (fields_decl, (char*) 0, 1, 0);
1289     }
1290   else
1291     fields_decl = NULL_TREE;
1292
1293   /* Build Method array. */
1294   for (method = TYPE_METHODS (CLASS_TO_HANDLE_TYPE (type));
1295        method != NULL_TREE; method = TREE_CHAIN (method))
1296     {
1297       tree init;
1298       if (METHOD_PRIVATE (method)
1299           && ! flag_keep_inline_functions
1300           && (flag_inline_functions || optimize))
1301         continue;
1302       init = make_method_value (method);
1303       method_count++;
1304       methods = tree_cons (NULL_TREE, init, methods);
1305     }
1306   method_array_type = build_prim_array_type (method_type_node, method_count);
1307   methods_decl = build_decl (VAR_DECL, mangled_classname ("_MT_", type),
1308                              method_array_type);
1309   DECL_INITIAL (methods_decl) = build (CONSTRUCTOR, method_array_type,
1310                                        NULL_TREE, nreverse (methods));
1311   TREE_STATIC (methods_decl) = 1;
1312   DECL_ARTIFICIAL (methods_decl) = 1;
1313   DECL_IGNORED_P (methods_decl) = 1;
1314   rest_of_decl_compilation (methods_decl, (char*) 0, 1, 0);
1315
1316   if (assume_compiled (IDENTIFIER_POINTER (DECL_NAME (type_decl)))
1317       && ! CLASS_ABSTRACT (type_decl) && ! CLASS_INTERFACE (type_decl))
1318     {
1319       tree dtable = get_dispatch_table (type, this_class_addr);
1320       dtable_decl = build_dtable_decl (type);
1321       DECL_INITIAL (dtable_decl) = dtable;
1322       TREE_STATIC (dtable_decl) = 1;
1323       DECL_ARTIFICIAL (dtable_decl) = 1;
1324       DECL_IGNORED_P (dtable_decl) = 1;
1325       TREE_PUBLIC (dtable_decl) = 1;
1326       rest_of_decl_compilation (dtable_decl, (char*) 0, 1, 0);
1327     }
1328
1329   super = CLASSTYPE_SUPER (type);
1330   if (super == NULL_TREE)
1331     super = null_pointer_node;
1332   else if (assume_compiled (IDENTIFIER_POINTER (DECL_NAME (type_decl))))
1333     super = build_class_ref (super);
1334   else
1335     {
1336       int super_index = alloc_class_constant (super);
1337       super = build_int_2 (super_index, 0);
1338       TREE_TYPE (super) = ptr_type_node;
1339     }
1340
1341   /* Build and emit the array of implemented interfaces. */
1342   if (type != object_type_node)
1343       interface_len = TREE_VEC_LENGTH (TYPE_BINFO_BASETYPES (type)) - 1;
1344   if (interface_len > 0)
1345     {
1346       tree init = NULL_TREE;
1347       int i;
1348       tree interface_array_type, idecl;
1349       interface_array_type
1350         = build_prim_array_type (class_ptr_type, interface_len);
1351       idecl = build_decl (VAR_DECL, mangled_classname ("_IF_", type),
1352                           interface_array_type);
1353       for (i = interface_len;  i > 0; i--)
1354         {
1355           tree child = TREE_VEC_ELT (TYPE_BINFO_BASETYPES (type), i);
1356           tree iclass = BINFO_TYPE (child);
1357           tree index;
1358           if (assume_compiled (IDENTIFIER_POINTER (DECL_NAME (TYPE_NAME (iclass)))))
1359             index = build_class_ref (iclass);
1360           else
1361             {
1362                 int int_index = alloc_class_constant (iclass);
1363                 index = build_int_2 (int_index, 0);
1364                 TREE_TYPE (index) = ptr_type_node;
1365             }
1366           init = tree_cons (NULL_TREE, index, init); 
1367         }
1368       DECL_INITIAL (idecl) = build (CONSTRUCTOR, interface_array_type,
1369                                     NULL_TREE, init);
1370       TREE_STATIC (idecl) = 1;
1371       DECL_ARTIFICIAL (idecl) = 1;
1372       DECL_IGNORED_P (idecl) = 1;
1373       interfaces = build1 (ADDR_EXPR, ptr_type_node, idecl);
1374       rest_of_decl_compilation (idecl,  (char*) 0, 1, 0);
1375     }
1376
1377   constant_pool_constructor = build_constants_constructor ();
1378
1379   START_RECORD_CONSTRUCTOR (temp, object_type_node);
1380   PUSH_FIELD_VALUE (temp, "vtable",
1381                     build1 (ADDR_EXPR, dtable_ptr_type, class_dtable_decl));
1382   if (! flag_hash_synchronization)
1383     PUSH_FIELD_VALUE (temp, "sync_info", null_pointer_node);
1384   FINISH_RECORD_CONSTRUCTOR (temp);
1385   START_RECORD_CONSTRUCTOR (cons, class_type_node);
1386   PUSH_SUPER_VALUE (cons, temp);
1387   PUSH_FIELD_VALUE (cons, "next", null_pointer_node);
1388   PUSH_FIELD_VALUE (cons, "name", build_utf8_ref (DECL_NAME (type_decl)));
1389   PUSH_FIELD_VALUE (cons, "accflags",
1390                     build_int_2 (get_access_flags_from_decl (type_decl), 0));
1391
1392   PUSH_FIELD_VALUE (cons, "superclass", 
1393                     CLASS_INTERFACE (type_decl) ? null_pointer_node : super);
1394   PUSH_FIELD_VALUE (cons, "constants", constant_pool_constructor);
1395   PUSH_FIELD_VALUE (cons, "methods",
1396                     build1 (ADDR_EXPR, method_ptr_type_node, methods_decl));
1397   PUSH_FIELD_VALUE (cons, "method_count",  build_int_2 (method_count, 0));
1398   PUSH_FIELD_VALUE (cons, "vtable_method_count", TYPE_NVIRTUALS (type));
1399   PUSH_FIELD_VALUE (cons, "fields",
1400                     fields_decl == NULL_TREE ? null_pointer_node
1401                     : build1 (ADDR_EXPR, field_ptr_type_node, fields_decl));
1402   PUSH_FIELD_VALUE (cons, "size_in_bytes", size_in_bytes (type));
1403   PUSH_FIELD_VALUE (cons, "field_count", build_int_2 (field_count, 0));
1404   PUSH_FIELD_VALUE (cons, "static_field_count",
1405                     build_int_2 (static_field_count, 0));
1406   PUSH_FIELD_VALUE (cons, "vtable",
1407                     dtable_decl == NULL_TREE ? null_pointer_node
1408                     : build1 (ADDR_EXPR, dtable_ptr_type, dtable_decl));
1409   PUSH_FIELD_VALUE (cons, "interfaces", interfaces);
1410   PUSH_FIELD_VALUE (cons, "loader", null_pointer_node);
1411   PUSH_FIELD_VALUE (cons, "interface_count", build_int_2 (interface_len, 0));
1412   PUSH_FIELD_VALUE (cons, "state", integer_zero_node);
1413
1414   PUSH_FIELD_VALUE (cons, "thread", null_pointer_node);
1415   PUSH_FIELD_VALUE (cons, "depth", integer_zero_node);
1416   PUSH_FIELD_VALUE (cons, "ancestors", null_pointer_node);
1417   PUSH_FIELD_VALUE (cons, "idt", null_pointer_node);
1418
1419   FINISH_RECORD_CONSTRUCTOR (cons);
1420
1421   DECL_INITIAL (decl) = cons;
1422   rest_of_decl_compilation (decl, (char*) 0, 1, 0);
1423 }
1424
1425 void
1426 finish_class ()
1427 {
1428   tree method;
1429   tree type_methods = TYPE_METHODS (CLASS_TO_HANDLE_TYPE (current_class));
1430   int saw_native_method = 0;
1431
1432   /* Find out if we have any native methods.  We use this information
1433      later.  */
1434   for (method = type_methods;
1435        method != NULL_TREE;
1436        method = TREE_CHAIN (method))
1437     {
1438       if (METHOD_NATIVE (method))
1439         {
1440           saw_native_method = 1;
1441           break;
1442         }
1443     }
1444
1445   /* Emit deferred inline methods. */  
1446   for (method = type_methods; method != NULL_TREE; )
1447     {
1448       if (! TREE_ASM_WRITTEN (method) && DECL_SAVED_INSNS (method) != 0)
1449         {
1450           /* It's a deferred inline method.  Decide if we need to emit it. */
1451           if (flag_keep_inline_functions
1452               || TREE_SYMBOL_REFERENCED (DECL_ASSEMBLER_NAME (method))
1453               || ! METHOD_PRIVATE (method)
1454               || saw_native_method)
1455             {
1456               temporary_allocation ();
1457               output_inline_function (method);
1458               permanent_allocation (1);
1459               /* Scan the list again to see if there are any earlier
1460                  methods to emit. */
1461               method = type_methods;
1462               continue;
1463             }
1464         }
1465       method = TREE_CHAIN (method);
1466     }
1467
1468   current_function_decl = NULL_TREE;
1469   make_class_data (current_class);
1470   register_class ();
1471   rest_of_decl_compilation (TYPE_NAME (current_class), (char*) 0, 1, 0);
1472 }
1473
1474 /* Return 2 if CLASS is compiled by this compilation job;
1475    return 1 if CLASS can otherwise be assumed to be compiled;
1476    return 0 if we cannot assume that CLASS is compiled.
1477    Returns 1 for primitive and 0 for array types.  */
1478 int
1479 is_compiled_class (class)
1480      tree class;
1481 {
1482   int seen_in_zip;
1483   if (TREE_CODE (class) == POINTER_TYPE)
1484     class = TREE_TYPE (class);
1485   if (TREE_CODE (class) != RECORD_TYPE)  /* Primitive types are static. */
1486     return 1;
1487   if (TYPE_ARRAY_P (class))
1488     return 0;
1489   if (class == current_class)
1490     return 2;
1491
1492   seen_in_zip = (TYPE_JCF (class) && TYPE_JCF (class)->seen_in_zip);
1493   if (CLASS_FROM_CURRENTLY_COMPILED_SOURCE_P (class) || seen_in_zip)
1494     {
1495       /* The class was seen in the current ZIP file and will be
1496          available as a compiled class in the future but may not have
1497          been loaded already. Load it if necessary. This prevent
1498          build_class_ref () from crashing. */
1499
1500       if (seen_in_zip && !CLASS_LOADED_P (class))
1501         load_class (class, 1);
1502
1503       /* We return 2 for class seen in ZIP and class from files
1504          belonging to the same compilation unit */
1505       return 2;
1506     }
1507
1508   if (assume_compiled (IDENTIFIER_POINTER (DECL_NAME (TYPE_NAME (class)))))
1509     {
1510       if (!CLASS_LOADED_P (class))
1511         {
1512           if (CLASS_FROM_SOURCE_P (class))
1513             safe_layout_class (class);
1514           else
1515             load_class (class, 1);
1516         }
1517       return 1;
1518     }
1519
1520   return 0;
1521 }
1522
1523 /* Append the mangled name of TYPE onto OBSTACK. */
1524
1525 static void
1526 append_gpp_mangled_type (obstack, type)
1527      struct obstack *obstack;
1528      tree type;
1529 {
1530   switch (TREE_CODE (type))
1531     {
1532       char code;
1533     case BOOLEAN_TYPE: code = 'b';  goto primitive;
1534     case CHAR_TYPE:    code = 'w';  goto primitive;
1535     case VOID_TYPE:    code = 'v';  goto primitive;
1536     case INTEGER_TYPE:
1537       /* Get the original type instead of the arguments promoted type.
1538          Avoid symbol name clashes. Should call a function to do that.
1539          FIXME.  */
1540       if (type == promoted_short_type_node)
1541         type = short_type_node;
1542       if (type == promoted_byte_type_node)
1543         type = byte_type_node;
1544       switch (TYPE_PRECISION (type))
1545         {
1546         case  8:       code = 'c';  goto primitive;
1547         case 16:       code = 's';  goto primitive;
1548         case 32:       code = 'i';  goto primitive;
1549         case 64:       code = 'x';  goto primitive;
1550         default:  goto bad_type;
1551         }
1552     primitive:
1553       obstack_1grow (obstack, code);
1554       break;
1555     case REAL_TYPE:
1556       switch (TYPE_PRECISION (type))
1557         {
1558         case 32:       code = 'f';  goto primitive;
1559         case 64:       code = 'd';  goto primitive;
1560         default:  goto bad_type;
1561         }
1562     case POINTER_TYPE:
1563       type = TREE_TYPE (type);
1564       obstack_1grow (obstack, 'P');
1565     case RECORD_TYPE:
1566       if (TYPE_ARRAY_P (type))
1567         {
1568           obstack_grow (obstack, "t6JArray1Z", sizeof("t6JArray1Z")-1);
1569           append_gpp_mangled_type (obstack, TYPE_ARRAY_ELEMENT (type));
1570         }
1571       else
1572         {
1573           const char *class_name = IDENTIFIER_POINTER (DECL_NAME (TYPE_NAME (type)));
1574           append_gpp_mangled_classtype (obstack, class_name);
1575         }
1576       break;
1577     bad_type:
1578     default:
1579       fatal ("internal error - trying to mangle unknown type");
1580     }
1581 }
1582
1583 /* Build the mangled name of the `class' field.  */
1584
1585 static tree
1586 mangle_class_field (class)
1587      tree class;
1588 {
1589   tree name;
1590   obstack_grow (&temporary_obstack, "_CL_", 4);
1591   append_gpp_mangled_type (&temporary_obstack, class);
1592   obstack_1grow (&temporary_obstack, '\0');
1593   name = get_identifier (obstack_base (&temporary_obstack));
1594   obstack_free (&temporary_obstack, obstack_base (&temporary_obstack));
1595   return name;
1596 }
1597
1598 /* Build the mangled (assembly-level) name of the static field FIELD. */
1599
1600 static tree
1601 mangle_static_field (field)
1602      tree field;
1603 {
1604   tree class = DECL_CONTEXT (field);
1605   tree name = DECL_NAME (field);
1606   int encoded_len;
1607 #if ! defined (NO_DOLLAR_IN_LABEL) || ! defined (NO_DOT_IN_LABEL)
1608   obstack_1grow (&temporary_obstack, '_');
1609 #else
1610   obstack_grow (&temporary_obstack, "__static_", 9);
1611 #endif
1612   append_gpp_mangled_type (&temporary_obstack, class);
1613   encoded_len = unicode_mangling_length (IDENTIFIER_POINTER (name),
1614                                          IDENTIFIER_LENGTH (name));
1615   if (encoded_len > 0)
1616     {
1617       obstack_1grow (&temporary_obstack, 'U');
1618     }
1619 #ifndef NO_DOLLAR_IN_LABEL
1620   obstack_1grow (&temporary_obstack, '$');
1621 #else /* NO_DOLLAR_IN_LABEL */
1622 #ifndef NO_DOT_IN_LABEL
1623   obstack_1grow (&temporary_obstack, '.');
1624 #else /* NO_DOT_IN_LABEL */
1625   obstack_1grow (&temporary_obstack, '_');
1626 #endif  /* NO_DOT_IN_LABEL */
1627 #endif  /* NO_DOLLAR_IN_LABEL */
1628   if (encoded_len > 0)
1629     {
1630       emit_unicode_mangled_name (&temporary_obstack,
1631                                  IDENTIFIER_POINTER (name), 
1632                                  IDENTIFIER_LENGTH (name));
1633     }
1634   else
1635     {
1636       obstack_grow (&temporary_obstack,
1637                     IDENTIFIER_POINTER (name),
1638                     IDENTIFIER_LENGTH (name));
1639     }
1640   obstack_1grow (&temporary_obstack, '\0');
1641   name = get_identifier (obstack_base (&temporary_obstack));
1642   obstack_free (&temporary_obstack, obstack_base (&temporary_obstack));
1643   return name;
1644 }
1645
1646 /* Build a VAR_DECL for the dispatch table (vtable) for class TYPE. */
1647
1648 tree
1649 build_dtable_decl (type)
1650      tree type;
1651 {
1652   tree name;
1653   obstack_grow (&temporary_obstack, "__vt_", 5);
1654   append_gpp_mangled_type (&temporary_obstack, type);
1655   obstack_1grow (&temporary_obstack, '\0');
1656   name = get_identifier (obstack_base (&temporary_obstack));
1657   obstack_free (&temporary_obstack, obstack_base (&temporary_obstack));
1658   return build_decl (VAR_DECL, name, dtable_type);
1659 }
1660
1661 /* Pre-pend the TYPE_FIELDS of THIS_CLASS with a dummy FIELD_DECL for the
1662    fields inherited from SUPER_CLASS. */
1663
1664 void
1665 push_super_field (this_class, super_class)
1666      tree this_class, super_class;
1667 {
1668   tree base_decl;
1669   /* Don't insert the field if we're just re-laying the class out. */ 
1670   if (TYPE_FIELDS (this_class) && !DECL_NAME (TYPE_FIELDS (this_class)))
1671     return;
1672   push_obstacks (&permanent_obstack, &permanent_obstack);
1673   base_decl = build_decl (FIELD_DECL, NULL_TREE, super_class);
1674   pop_obstacks ();
1675   DECL_IGNORED_P (base_decl) = 1;
1676   TREE_CHAIN (base_decl) = TYPE_FIELDS (this_class);
1677   TYPE_FIELDS (this_class) = base_decl;
1678   DECL_SIZE (base_decl) = TYPE_SIZE (super_class);
1679   DECL_SIZE_UNIT (base_decl) = TYPE_SIZE_UNIT (super_class);
1680 }
1681
1682 /* Handle the different manners we may have to lay out a super class.  */
1683
1684 static tree
1685 maybe_layout_super_class (super_class, this_class)
1686      tree super_class;
1687      tree this_class;
1688 {
1689   if (TREE_CODE (super_class) == RECORD_TYPE)
1690     {
1691       if (!CLASS_LOADED_P (super_class) 
1692           && CLASS_FROM_SOURCE_P (super_class))
1693         safe_layout_class (super_class);
1694       if (!CLASS_LOADED_P (super_class))
1695         load_class (super_class, 1);
1696     }
1697   /* We might have to layout the class before its dependency on
1698      the super class gets resolved by java_complete_class  */
1699   else if (TREE_CODE (super_class) == POINTER_TYPE)
1700     {
1701       if (TREE_TYPE (super_class) != NULL_TREE)
1702         super_class = TREE_TYPE (super_class);
1703       else
1704         {
1705           super_class = do_resolve_class (NULL_TREE, /* FIXME? */
1706                                           super_class, NULL_TREE, this_class);
1707           if (!super_class)
1708             return NULL_TREE;   /* FIXME, NULL_TREE not checked by caller. */
1709           super_class = TREE_TYPE (super_class);
1710         }
1711     }
1712   if (!TYPE_SIZE (super_class))
1713     safe_layout_class (super_class);
1714
1715   return super_class;
1716 }
1717
1718 void
1719 layout_class (this_class)
1720      tree this_class;
1721 {
1722   static tree list = NULL_TREE;
1723   tree super_class = CLASSTYPE_SUPER (this_class);
1724   tree field;
1725   
1726   list = tree_cons (this_class, NULL_TREE, list);
1727   if (CLASS_BEING_LAIDOUT (this_class))
1728     {
1729       char buffer [1024];
1730       tree current;
1731       
1732       sprintf (buffer, " with `%s'",
1733                IDENTIFIER_POINTER (DECL_NAME (TYPE_NAME (this_class))));
1734       obstack_grow (&temporary_obstack, buffer, strlen (buffer));
1735
1736       for (current = TREE_CHAIN (list); current; 
1737            current = TREE_CHAIN (current))
1738         {
1739           tree decl = TYPE_NAME (TREE_PURPOSE (current));
1740           sprintf (buffer, "\n  which inherits from `%s' (%s:%d)",
1741                    IDENTIFIER_POINTER (DECL_NAME (decl)),
1742                    DECL_SOURCE_FILE (decl),
1743                    DECL_SOURCE_LINE (decl));
1744           obstack_grow (&temporary_obstack, buffer, strlen (buffer));
1745         }
1746       obstack_1grow (&temporary_obstack, '\0');
1747       cyclic_inheritance_report = obstack_finish (&temporary_obstack);
1748       TYPE_SIZE (this_class) = error_mark_node;
1749       return;
1750     }
1751   CLASS_BEING_LAIDOUT (this_class) = 1;
1752
1753   if (super_class)
1754     {
1755       super_class = maybe_layout_super_class (super_class, this_class);
1756       if (TREE_CODE (TYPE_SIZE (super_class)) == ERROR_MARK)
1757         {
1758           TYPE_SIZE (this_class) = error_mark_node;
1759           CLASS_BEING_LAIDOUT (this_class) = 0;
1760           list = TREE_CHAIN (list);
1761           return;
1762         }
1763       if (TYPE_SIZE (this_class) == NULL_TREE)
1764         push_super_field (this_class, super_class);
1765     }
1766
1767   for (field = TYPE_FIELDS (this_class);
1768        field != NULL_TREE;  field = TREE_CHAIN (field))
1769     {
1770       if (FIELD_STATIC (field))
1771         {
1772           /* Set DECL_ASSEMBLER_NAME to something suitably mangled. */
1773           DECL_ASSEMBLER_NAME (field) = mangle_static_field (field);
1774         }
1775     }
1776
1777   layout_type (this_class);
1778
1779   /* Convert the size back to an SI integer value */
1780   TYPE_SIZE_UNIT (this_class) = 
1781     fold (convert (int_type_node, TYPE_SIZE_UNIT (this_class)));
1782
1783   CLASS_BEING_LAIDOUT (this_class) = 0;
1784   list = TREE_CHAIN (list);
1785 }
1786
1787 void
1788 layout_class_methods (this_class)
1789      tree this_class;
1790 {
1791   tree method_decl, dtable_count;
1792   tree super_class, handle_type;
1793
1794   if (TYPE_NVIRTUALS (this_class))
1795     return;
1796
1797   push_obstacks (&permanent_obstack, &permanent_obstack);
1798   super_class = CLASSTYPE_SUPER (this_class);
1799   handle_type = CLASS_TO_HANDLE_TYPE (this_class);
1800
1801   if (super_class)
1802     {
1803       super_class = maybe_layout_super_class (super_class, this_class);
1804       if (!TYPE_NVIRTUALS (super_class))
1805         layout_class_methods (super_class);
1806       dtable_count = TYPE_NVIRTUALS (super_class);
1807     }
1808   else
1809     dtable_count = integer_zero_node;
1810   
1811   TYPE_METHODS (handle_type) = nreverse (TYPE_METHODS (handle_type));
1812
1813   for (method_decl = TYPE_METHODS (handle_type);
1814        method_decl; method_decl = TREE_CHAIN (method_decl))
1815     dtable_count = layout_class_method (this_class, super_class, 
1816                                         method_decl, dtable_count);
1817
1818   TYPE_NVIRTUALS (this_class) = dtable_count;
1819
1820 #ifdef JAVA_USE_HANDLES
1821   layout_type (handle_type);
1822 #endif
1823   pop_obstacks ();
1824 }
1825
1826 /* Lay METHOD_DECL out, returning a possibly new value of
1827    DTABLE_COUNT.  */
1828
1829 tree
1830 layout_class_method (this_class, super_class, method_decl, dtable_count)
1831      tree this_class, super_class, method_decl, dtable_count;
1832 {
1833   const char *ptr;
1834   char *asm_name;
1835   tree arg, arglist, t;
1836   int method_name_needs_escapes = 0;
1837   tree method_name = DECL_NAME (method_decl);
1838   int method_name_is_wfl = 
1839     (TREE_CODE (method_name) == EXPR_WITH_FILE_LOCATION);
1840   if (method_name_is_wfl)
1841     method_name = java_get_real_method_name (method_decl);
1842
1843   if (!ID_INIT_P (method_name) && !ID_FINIT_P (method_name))
1844     {
1845       int encoded_len
1846         = unicode_mangling_length (IDENTIFIER_POINTER (method_name), 
1847                                    IDENTIFIER_LENGTH (method_name));
1848       if (encoded_len > 0)
1849         {
1850           method_name_needs_escapes = 1;
1851           emit_unicode_mangled_name (&temporary_obstack,
1852                                      IDENTIFIER_POINTER (method_name), 
1853                                      IDENTIFIER_LENGTH (method_name));
1854         }
1855       else
1856         {
1857           obstack_grow (&temporary_obstack,
1858                         IDENTIFIER_POINTER (method_name),
1859                         IDENTIFIER_LENGTH (method_name));
1860         }
1861     }
1862       
1863   obstack_grow (&temporary_obstack, "__", 2);
1864   if (ID_FINIT_P (method_name))
1865     obstack_grow (&temporary_obstack, "finit", 5);
1866   append_gpp_mangled_type (&temporary_obstack, this_class);
1867   TREE_PUBLIC (method_decl) = 1;
1868
1869   t = TREE_TYPE (method_decl);
1870   arglist = TYPE_ARG_TYPES (t);
1871   if (TREE_CODE (t) == METHOD_TYPE)
1872     arglist = TREE_CHAIN (arglist);
1873   for (arg = arglist; arg != end_params_node;  )
1874     {
1875       tree a = arglist;
1876       tree argtype = TREE_VALUE (arg);
1877       int tindex = 1;
1878       if (TREE_CODE (argtype) == POINTER_TYPE)
1879         {
1880           /* This is O(N**2).  Do we care?  Cfr gcc/cp/method.c. */
1881           while (a != arg && argtype != TREE_VALUE (a))
1882             a = TREE_CHAIN (a), tindex++;
1883         }
1884       else
1885         a = arg;
1886       if (a != arg)
1887         {
1888           char buf[12];
1889           int nrepeats = 0;
1890           do
1891             {
1892               arg = TREE_CHAIN (arg); nrepeats++;
1893             }
1894           while (arg != end_params_node && argtype == TREE_VALUE (arg));
1895           if (nrepeats > 1)
1896             {
1897               obstack_1grow (&temporary_obstack, 'N');
1898               sprintf (buf, "%d", nrepeats);
1899               obstack_grow (&temporary_obstack, buf, strlen (buf));
1900               if (nrepeats > 9)
1901                 obstack_1grow (&temporary_obstack, '_');
1902             }
1903           else
1904             obstack_1grow (&temporary_obstack, 'T');
1905           sprintf (buf, "%d", tindex);
1906           obstack_grow (&temporary_obstack, buf, strlen (buf));
1907           if (tindex > 9)
1908             obstack_1grow (&temporary_obstack, '_');
1909         }
1910       else
1911         {
1912           append_gpp_mangled_type (&temporary_obstack, argtype);
1913           arg = TREE_CHAIN (arg);
1914         }
1915     }
1916   if (method_name_needs_escapes)
1917     obstack_1grow (&temporary_obstack, 'U');
1918
1919   obstack_1grow (&temporary_obstack, '\0');
1920   asm_name = obstack_finish (&temporary_obstack);
1921   DECL_ASSEMBLER_NAME (method_decl) = get_identifier (asm_name);
1922   /* We don't generate a RTL for the method if it's abstract, or if
1923      it's an interface method that isn't clinit. */
1924   if (! METHOD_ABSTRACT (method_decl) 
1925       || (CLASS_INTERFACE (TYPE_NAME (this_class)) 
1926           && (DECL_CLINIT_P (method_decl))))
1927     make_function_rtl (method_decl);
1928   obstack_free (&temporary_obstack, asm_name);
1929
1930   if (ID_INIT_P (method_name))
1931     {
1932       const char *p = IDENTIFIER_POINTER (DECL_NAME (TYPE_NAME (this_class)));
1933       for (ptr = p; *ptr; )
1934         {
1935           if (*ptr++ == '.')
1936             p = ptr;
1937         }
1938       if (method_name_is_wfl)
1939         EXPR_WFL_NODE (DECL_NAME (method_decl)) = get_identifier (p);
1940       else
1941         DECL_NAME (method_decl) = get_identifier (p);
1942       DECL_CONSTRUCTOR_P (method_decl) = 1;
1943       build_java_argument_signature (TREE_TYPE (method_decl));
1944     }
1945   else if (! METHOD_STATIC (method_decl) && !DECL_ARTIFICIAL (method_decl))
1946     {
1947       tree method_sig = 
1948         build_java_argument_signature (TREE_TYPE (method_decl));
1949       tree super_method = lookup_argument_method (super_class, method_name,
1950                                                   method_sig);
1951       if (super_method != NULL_TREE && ! METHOD_PRIVATE (super_method))
1952         {
1953           DECL_VINDEX (method_decl) = DECL_VINDEX (super_method);
1954           if (DECL_VINDEX (method_decl) == NULL_TREE 
1955               && !CLASS_FROM_SOURCE_P (this_class))
1956             error_with_decl (method_decl,
1957                              "non-static method '%s' overrides static method");
1958 #if 0
1959           else if (TREE_TYPE (TREE_TYPE (method_decl))
1960                    != TREE_TYPE (TREE_TYPE (super_method)))
1961             {
1962               error_with_decl (method_decl,
1963                                "Method `%s' redefined with different return type");  
1964               error_with_decl (super_method,
1965                                "Overridden decl is here");
1966             }
1967 #endif
1968         }
1969       else if (! METHOD_FINAL (method_decl)
1970                && ! METHOD_PRIVATE (method_decl)
1971                && ! CLASS_FINAL (TYPE_NAME (this_class))
1972                && dtable_count)
1973         {
1974           DECL_VINDEX (method_decl) = dtable_count;
1975           dtable_count = fold (build (PLUS_EXPR, integer_type_node,
1976                                       dtable_count, integer_one_node));
1977         }
1978     }
1979
1980   return dtable_count;
1981 }
1982
1983 static tree registered_class = NULL_TREE;
1984
1985 void
1986 register_class ()
1987 {
1988   static tree end;
1989   tree node    = TREE_OPERAND (build_class_ref (current_class), 0);
1990   tree current = copy_node (node);
1991
1992   XEXP (DECL_RTL (current), 0) = copy_rtx (XEXP (DECL_RTL(node), 0));
1993   if (!registered_class)
1994     registered_class = current;
1995   else
1996     TREE_CHAIN (end) = current;
1997
1998   end = current;
1999 }
2000
2001 /* Generate a function that gets called at start-up (static contructor) time,
2002    which calls registerClass for all the compiled classes. */
2003
2004 void
2005 emit_register_classes ()
2006 {
2007   extern tree get_file_function_name PARAMS ((int));
2008   tree init_name = get_file_function_name ('I');
2009   tree init_type = build_function_type (void_type_node, end_params_node);
2010   tree init_decl;
2011   tree t;
2012
2013   init_decl = build_decl (FUNCTION_DECL, init_name, init_type);
2014   DECL_ASSEMBLER_NAME (init_decl) = init_name;
2015   TREE_STATIC (init_decl) = 1;
2016   current_function_decl = init_decl;
2017   DECL_RESULT (init_decl) = build_decl(RESULT_DECL, NULL_TREE, void_type_node);
2018   /*  DECL_EXTERNAL (init_decl) = 1;*/
2019   TREE_PUBLIC (init_decl) = 1;
2020   pushlevel (0);
2021   make_function_rtl (init_decl);
2022   init_function_start (init_decl, input_filename, 0);
2023   expand_function_start (init_decl, 0);
2024
2025   for ( t = registered_class; t; t = TREE_CHAIN (t))
2026     emit_library_call (registerClass_libfunc, 0, VOIDmode, 1,
2027                        XEXP (DECL_RTL (t), 0), Pmode);
2028
2029   expand_function_end (input_filename, 0, 0);
2030   poplevel (1, 0, 1);
2031   { 
2032     /* Force generation, even with -O3 or deeper. Gross hack. FIXME */
2033     int saved_flag = flag_inline_functions;
2034     flag_inline_functions = 0;  
2035     rest_of_compilation (init_decl);
2036     flag_inline_functions = saved_flag;
2037   }
2038   current_function_decl = NULL_TREE;
2039   assemble_constructor (IDENTIFIER_POINTER (init_name));
2040 }
2041
2042 void
2043 init_class_processing ()
2044 {
2045   registerClass_libfunc = gen_rtx (SYMBOL_REF, Pmode, "_Jv_RegisterClass");
2046 }