OSDN Git Service

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