OSDN Git Service

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