OSDN Git Service

In gcc/java:
[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   PUSH_FIELD_VALUE (cons, "arrayclass", null_pointer_node);
1445
1446   FINISH_RECORD_CONSTRUCTOR (cons);
1447
1448   DECL_INITIAL (decl) = cons;
1449   rest_of_decl_compilation (decl, (char*) 0, 1, 0);
1450 }
1451
1452 void
1453 finish_class ()
1454 {
1455   tree method;
1456   tree type_methods = TYPE_METHODS (CLASS_TO_HANDLE_TYPE (current_class));
1457   int saw_native_method = 0;
1458
1459   /* Find out if we have any native methods.  We use this information
1460      later.  */
1461   for (method = type_methods;
1462        method != NULL_TREE;
1463        method = TREE_CHAIN (method))
1464     {
1465       if (METHOD_NATIVE (method))
1466         {
1467           saw_native_method = 1;
1468           break;
1469         }
1470     }
1471
1472   /* Emit deferred inline methods. */  
1473   for (method = type_methods; method != NULL_TREE; )
1474     {
1475       if (! TREE_ASM_WRITTEN (method) && DECL_SAVED_INSNS (method) != 0)
1476         {
1477           /* It's a deferred inline method.  Decide if we need to emit it. */
1478           if (flag_keep_inline_functions
1479               || TREE_SYMBOL_REFERENCED (DECL_ASSEMBLER_NAME (method))
1480               || ! METHOD_PRIVATE (method)
1481               || saw_native_method)
1482             {
1483               output_inline_function (method);
1484               /* Scan the list again to see if there are any earlier
1485                  methods to emit. */
1486               method = type_methods;
1487               continue;
1488             }
1489         }
1490       method = TREE_CHAIN (method);
1491     }
1492
1493   current_function_decl = NULL_TREE;
1494   make_class_data (current_class);
1495   register_class ();
1496   rest_of_decl_compilation (TYPE_NAME (current_class), (char*) 0, 1, 0);
1497 }
1498
1499 /* Return 2 if CLASS is compiled by this compilation job;
1500    return 1 if CLASS can otherwise be assumed to be compiled;
1501    return 0 if we cannot assume that CLASS is compiled.
1502    Returns 1 for primitive and 0 for array types.  */
1503 int
1504 is_compiled_class (class)
1505      tree class;
1506 {
1507   int seen_in_zip;
1508   if (TREE_CODE (class) == POINTER_TYPE)
1509     class = TREE_TYPE (class);
1510   if (TREE_CODE (class) != RECORD_TYPE)  /* Primitive types are static. */
1511     return 1;
1512   if (TYPE_ARRAY_P (class))
1513     return 0;
1514   if (class == current_class)
1515     return 2;
1516
1517   seen_in_zip = (TYPE_JCF (class) && TYPE_JCF (class)->seen_in_zip);
1518   if (CLASS_FROM_CURRENTLY_COMPILED_SOURCE_P (class) || seen_in_zip)
1519     {
1520       /* The class was seen in the current ZIP file and will be
1521          available as a compiled class in the future but may not have
1522          been loaded already. Load it if necessary. This prevent
1523          build_class_ref () from crashing. */
1524
1525       if (seen_in_zip && !CLASS_LOADED_P (class))
1526         load_class (class, 1);
1527
1528       /* We return 2 for class seen in ZIP and class from files
1529          belonging to the same compilation unit */
1530       return 2;
1531     }
1532
1533   if (assume_compiled (IDENTIFIER_POINTER (DECL_NAME (TYPE_NAME (class)))))
1534     {
1535       if (!CLASS_LOADED_P (class))
1536         {
1537           if (CLASS_FROM_SOURCE_P (class))
1538             safe_layout_class (class);
1539           else
1540             load_class (class, 1);
1541         }
1542       return 1;
1543     }
1544
1545   return 0;
1546 }
1547
1548 /* Append the mangled name of TYPE onto OBSTACK. */
1549
1550 static void
1551 append_gpp_mangled_type (obstack, type)
1552      struct obstack *obstack;
1553      tree type;
1554 {
1555   switch (TREE_CODE (type))
1556     {
1557       char code;
1558     case BOOLEAN_TYPE: code = 'b';  goto primitive;
1559     case CHAR_TYPE:    code = 'w';  goto primitive;
1560     case VOID_TYPE:    code = 'v';  goto primitive;
1561     case INTEGER_TYPE:
1562       /* Get the original type instead of the arguments promoted type.
1563          Avoid symbol name clashes. Should call a function to do that.
1564          FIXME.  */
1565       if (type == promoted_short_type_node)
1566         type = short_type_node;
1567       if (type == promoted_byte_type_node)
1568         type = byte_type_node;
1569       switch (TYPE_PRECISION (type))
1570         {
1571         case  8:       code = 'c';  goto primitive;
1572         case 16:       code = 's';  goto primitive;
1573         case 32:       code = 'i';  goto primitive;
1574         case 64:       code = 'x';  goto primitive;
1575         default:  goto bad_type;
1576         }
1577     primitive:
1578       obstack_1grow (obstack, code);
1579       break;
1580     case REAL_TYPE:
1581       switch (TYPE_PRECISION (type))
1582         {
1583         case 32:       code = 'f';  goto primitive;
1584         case 64:       code = 'd';  goto primitive;
1585         default:  goto bad_type;
1586         }
1587     case POINTER_TYPE:
1588       type = TREE_TYPE (type);
1589       obstack_1grow (obstack, 'P');
1590     case RECORD_TYPE:
1591       if (TYPE_ARRAY_P (type))
1592         {
1593           obstack_grow (obstack, "t6JArray1Z", sizeof("t6JArray1Z")-1);
1594           append_gpp_mangled_type (obstack, TYPE_ARRAY_ELEMENT (type));
1595         }
1596       else
1597         {
1598           const char *class_name = IDENTIFIER_POINTER (DECL_NAME (TYPE_NAME (type)));
1599           append_gpp_mangled_classtype (obstack, class_name);
1600         }
1601       break;
1602     bad_type:
1603     default:
1604       fatal ("internal error - trying to mangle unknown type");
1605     }
1606 }
1607
1608 /* Build the mangled name of a field, given the class name and the
1609    field name.  */
1610
1611 static tree
1612 mangle_field (class, name)
1613      tree class, name;
1614 {
1615   int encoded_len;
1616 #if ! defined (NO_DOLLAR_IN_LABEL) || ! defined (NO_DOT_IN_LABEL)
1617   obstack_1grow (&temporary_obstack, '_');
1618 #else
1619   obstack_grow (&temporary_obstack, "__static_", 9);
1620 #endif
1621   append_gpp_mangled_type (&temporary_obstack, class);
1622   encoded_len = unicode_mangling_length (IDENTIFIER_POINTER (name),
1623                                          IDENTIFIER_LENGTH (name));
1624   if (encoded_len > 0)
1625     {
1626       obstack_1grow (&temporary_obstack, 'U');
1627     }
1628 #ifndef NO_DOLLAR_IN_LABEL
1629   obstack_1grow (&temporary_obstack, '$');
1630 #else /* NO_DOLLAR_IN_LABEL */
1631 #ifndef NO_DOT_IN_LABEL
1632   obstack_1grow (&temporary_obstack, '.');
1633 #else /* NO_DOT_IN_LABEL */
1634   obstack_1grow (&temporary_obstack, '_');
1635 #endif  /* NO_DOT_IN_LABEL */
1636 #endif  /* NO_DOLLAR_IN_LABEL */
1637   if (encoded_len > 0)
1638     {
1639       emit_unicode_mangled_name (&temporary_obstack,
1640                                  IDENTIFIER_POINTER (name), 
1641                                  IDENTIFIER_LENGTH (name));
1642     }
1643   else
1644     {
1645       obstack_grow (&temporary_obstack,
1646                     IDENTIFIER_POINTER (name),
1647                     IDENTIFIER_LENGTH (name));
1648     }
1649
1650   /* Mangle C++ keywords by appending a `$'.  */
1651   /* FIXME: NO_DOLLAR_IN_LABEL */
1652   if (cxx_keyword_p (IDENTIFIER_POINTER (name), IDENTIFIER_LENGTH (name)))
1653     obstack_grow (&temporary_obstack, "$", 1);
1654
1655   obstack_1grow (&temporary_obstack, '\0');
1656   name = get_identifier (obstack_base (&temporary_obstack));
1657   obstack_free (&temporary_obstack, obstack_base (&temporary_obstack));
1658   return name;
1659 }
1660
1661 /* Build the mangled name of the `class' field.  */
1662
1663 static tree
1664 mangle_class_field (class)
1665      tree class;
1666 {
1667   /* We know that we can use `class$' to mangle the class object,
1668      because `class' is a reserved word in Java and thus can't appear
1669      as a field or method name.  */
1670   return mangle_field (class, get_identifier ("class$"));
1671 }
1672
1673 /* Build the mangled (assembly-level) name of the static field FIELD. */
1674
1675 static tree
1676 mangle_static_field (field)
1677      tree field;
1678 {
1679   return mangle_field (DECL_CONTEXT (field), DECL_NAME (field));
1680 }
1681
1682 /* Build a VAR_DECL for the dispatch table (vtable) for class TYPE. */
1683
1684 tree
1685 build_dtable_decl (type)
1686      tree type;
1687 {
1688   tree name, dtype;
1689
1690   /* We need to build a new dtable type so that its size is uniquely
1691      computed when we're dealing with the class for real and not just
1692      faking it (like java.lang.Class during the initialization of the
1693      compiler.) We now we're not faking a class when CURRENT_CLASS is
1694      TYPE. */
1695   if (current_class == type)
1696     {
1697       tree dummy = NULL_TREE, aomt, n;
1698
1699       dtype = make_node (RECORD_TYPE);
1700       PUSH_FIELD (dtype, dummy, "class", class_ptr_type);
1701       n = build_int_2 (TREE_VEC_LENGTH (get_dispatch_vector (type)), 0);
1702       aomt = build_array_type (ptr_type_node, build_index_type (n));
1703       PUSH_FIELD (dtype, dummy, "methods", aomt);
1704       layout_type (dtype);
1705     }
1706   else
1707     dtype = dtable_type;
1708
1709   obstack_grow (&temporary_obstack, "__vt_", 5);
1710   append_gpp_mangled_type (&temporary_obstack, type);
1711   obstack_1grow (&temporary_obstack, '\0');
1712   name = get_identifier (obstack_base (&temporary_obstack));
1713   obstack_free (&temporary_obstack, obstack_base (&temporary_obstack));
1714   return build_decl (VAR_DECL, name, dtype);
1715 }
1716
1717 /* Pre-pend the TYPE_FIELDS of THIS_CLASS with a dummy FIELD_DECL for the
1718    fields inherited from SUPER_CLASS. */
1719
1720 void
1721 push_super_field (this_class, super_class)
1722      tree this_class, super_class;
1723 {
1724   tree base_decl;
1725   /* Don't insert the field if we're just re-laying the class out. */ 
1726   if (TYPE_FIELDS (this_class) && !DECL_NAME (TYPE_FIELDS (this_class)))
1727     return;
1728   base_decl = build_decl (FIELD_DECL, NULL_TREE, super_class);
1729   DECL_IGNORED_P (base_decl) = 1;
1730   TREE_CHAIN (base_decl) = TYPE_FIELDS (this_class);
1731   TYPE_FIELDS (this_class) = base_decl;
1732   DECL_SIZE (base_decl) = TYPE_SIZE (super_class);
1733   DECL_SIZE_UNIT (base_decl) = TYPE_SIZE_UNIT (super_class);
1734 }
1735
1736 /* Handle the different manners we may have to lay out a super class.  */
1737
1738 static tree
1739 maybe_layout_super_class (super_class, this_class)
1740      tree super_class;
1741      tree this_class;
1742 {
1743   if (TREE_CODE (super_class) == RECORD_TYPE)
1744     {
1745       if (!CLASS_LOADED_P (super_class) && CLASS_FROM_SOURCE_P (super_class))
1746         safe_layout_class (super_class);
1747       if (!CLASS_LOADED_P (super_class))
1748         load_class (super_class, 1);
1749     }
1750   /* We might have to layout the class before its dependency on
1751      the super class gets resolved by java_complete_class  */
1752   else if (TREE_CODE (super_class) == POINTER_TYPE)
1753     {
1754       if (TREE_TYPE (super_class) != NULL_TREE)
1755         super_class = TREE_TYPE (super_class);
1756       else
1757         {
1758           super_class = do_resolve_class (NULL_TREE, /* FIXME? */
1759                                           super_class, NULL_TREE, this_class);
1760           if (!super_class)
1761             return NULL_TREE;   /* FIXME, NULL_TREE not checked by caller. */
1762           super_class = TREE_TYPE (super_class);
1763         }
1764     }
1765   if (!TYPE_SIZE (super_class))
1766     safe_layout_class (super_class);
1767
1768   return super_class;
1769 }
1770
1771 void
1772 layout_class (this_class)
1773      tree this_class;
1774 {
1775   static tree list = NULL_TREE;
1776   static int initialized_p;
1777   tree super_class = CLASSTYPE_SUPER (this_class);
1778   tree field;
1779   
1780   /* Register LIST with the garbage collector.  */
1781   if (!initialized_p)
1782     {
1783       ggc_add_tree_root (&list, 1);
1784       initialized_p = 1;
1785     }
1786
1787   list = tree_cons (this_class, NULL_TREE, list);
1788   if (CLASS_BEING_LAIDOUT (this_class))
1789     {
1790       char buffer [1024];
1791       char *report;
1792       tree current;
1793       
1794       sprintf (buffer, " with `%s'",
1795                IDENTIFIER_POINTER (DECL_NAME (TYPE_NAME (this_class))));
1796       obstack_grow (&temporary_obstack, buffer, strlen (buffer));
1797
1798       for (current = TREE_CHAIN (list); current; 
1799            current = TREE_CHAIN (current))
1800         {
1801           tree decl = TYPE_NAME (TREE_PURPOSE (current));
1802           sprintf (buffer, "\n  which inherits from `%s' (%s:%d)",
1803                    IDENTIFIER_POINTER (DECL_NAME (decl)),
1804                    DECL_SOURCE_FILE (decl),
1805                    DECL_SOURCE_LINE (decl));
1806           obstack_grow (&temporary_obstack, buffer, strlen (buffer));
1807         }
1808       obstack_1grow (&temporary_obstack, '\0');
1809       report = obstack_finish (&temporary_obstack);
1810       cyclic_inheritance_report = ggc_strdup (report);
1811       obstack_free (&temporary_obstack, report);
1812       TYPE_SIZE (this_class) = error_mark_node;
1813       return;
1814     }
1815   CLASS_BEING_LAIDOUT (this_class) = 1;
1816
1817   if (super_class)
1818     {
1819       tree maybe_super_class 
1820         = maybe_layout_super_class (super_class, this_class);
1821       if (maybe_super_class == NULL
1822           || TREE_CODE (TYPE_SIZE (maybe_super_class)) == ERROR_MARK)
1823         {
1824           TYPE_SIZE (this_class) = error_mark_node;
1825           CLASS_BEING_LAIDOUT (this_class) = 0;
1826           list = TREE_CHAIN (list);
1827           return;
1828         }
1829       if (TYPE_SIZE (this_class) == NULL_TREE)
1830         push_super_field (this_class, super_class);
1831     }
1832
1833   for (field = TYPE_FIELDS (this_class);
1834        field != NULL_TREE;  field = TREE_CHAIN (field))
1835     {
1836       if (FIELD_STATIC (field))
1837         {
1838           /* Set DECL_ASSEMBLER_NAME to something suitably mangled. */
1839           DECL_ASSEMBLER_NAME (field) = mangle_static_field (field);
1840         }
1841     }
1842
1843   layout_type (this_class);
1844
1845   /* Also recursively load/layout any superinterfaces, but only if class was
1846   loaded from bytecode. The source parser will take care of this itself. */
1847   if (!CLASS_FROM_SOURCE_P (this_class))
1848     {
1849       tree basetype_vec = TYPE_BINFO_BASETYPES (this_class);
1850
1851       if (basetype_vec)
1852         {
1853           int n = TREE_VEC_LENGTH (basetype_vec) - 1;
1854           int i;
1855           for (i = n; i > 0; i--)
1856             {
1857               tree vec_elt = TREE_VEC_ELT (basetype_vec, i);
1858               tree super_interface = BINFO_TYPE (vec_elt);
1859
1860               tree maybe_super_interface 
1861                 = maybe_layout_super_class (super_interface, NULL_TREE);
1862               if (maybe_super_interface == NULL
1863                   || TREE_CODE (TYPE_SIZE (maybe_super_interface)) == ERROR_MARK)
1864                 {
1865                   TYPE_SIZE (this_class) = error_mark_node;
1866                   CLASS_BEING_LAIDOUT (this_class) = 0;
1867                   list = TREE_CHAIN (list);
1868                   return;
1869                 }
1870             }
1871         }
1872     }
1873
1874   /* Convert the size back to an SI integer value */
1875   TYPE_SIZE_UNIT (this_class) = 
1876     fold (convert (int_type_node, TYPE_SIZE_UNIT (this_class)));
1877
1878   CLASS_BEING_LAIDOUT (this_class) = 0;
1879   list = TREE_CHAIN (list);
1880 }
1881
1882 void
1883 layout_class_methods (this_class)
1884      tree this_class;
1885 {
1886   tree method_decl, dtable_count;
1887   tree super_class, handle_type;
1888
1889   if (TYPE_NVIRTUALS (this_class))
1890     return;
1891
1892   super_class = CLASSTYPE_SUPER (this_class);
1893   handle_type = CLASS_TO_HANDLE_TYPE (this_class);
1894
1895   if (super_class)
1896     {
1897       super_class = maybe_layout_super_class (super_class, this_class);
1898       if (!TYPE_NVIRTUALS (super_class))
1899         layout_class_methods (super_class);
1900       dtable_count = TYPE_NVIRTUALS (super_class);
1901     }
1902   else
1903     dtable_count = integer_zero_node;
1904
1905   TYPE_METHODS (handle_type) = nreverse (TYPE_METHODS (handle_type));
1906
1907   for (method_decl = TYPE_METHODS (handle_type);
1908        method_decl; method_decl = TREE_CHAIN (method_decl))
1909     dtable_count = layout_class_method (this_class, super_class, 
1910                                         method_decl, dtable_count);
1911
1912   TYPE_NVIRTUALS (this_class) = dtable_count;
1913
1914 #ifdef JAVA_USE_HANDLES
1915   layout_type (handle_type);
1916 #endif
1917 }
1918
1919 /* A sorted list of all C++ keywords.  */
1920
1921 static const char *cxx_keywords[] =
1922 {
1923   "asm",
1924   "auto",
1925   "bool",
1926   "const_cast",
1927   "delete",
1928   "dynamic_cast",
1929   "enum",
1930   "explicit",
1931   "extern",
1932   "friend",
1933   "inline",
1934   "mutable",
1935   "namespace",
1936   "overload",
1937   "register",
1938   "reinterpret_cast",
1939   "signed",
1940   "sizeof",
1941   "static_cast",
1942   "struct",
1943   "template",
1944   "typedef",
1945   "typeid",
1946   "typename",
1947   "typenameopt",
1948   "union",
1949   "unsigned",
1950   "using",
1951   "virtual",
1952   "volatile",
1953   "wchar_t"
1954 };
1955
1956 /* Return 0 if NAME is equal to STR, -1 if STR is "less" than NAME,
1957    and 1 if STR is "greater" than NAME.  */
1958
1959 static int
1960 utf8_cmp (str, length, name)
1961      const unsigned char *str;
1962      int length;
1963      const char *name;
1964 {
1965   const unsigned char *limit = str + length;
1966   int i;
1967
1968   for (i = 0; name[i]; ++i)
1969     {
1970       int ch = UTF8_GET (str, limit);
1971       if (ch != name[i])
1972         return ch - name[i];
1973     }
1974
1975   return str == limit ? 0 : 1;
1976 }
1977
1978 /* Return true if NAME is a C++ keyword.  */
1979
1980 static int
1981 cxx_keyword_p (name, length)
1982      const char *name;
1983      int length;
1984 {
1985   int last = ARRAY_SIZE (cxx_keywords);
1986   int first = 0;
1987   int mid = (last + first) / 2;
1988   int old = -1;
1989
1990   for (mid = (last + first) / 2;
1991        mid != old;
1992        old = mid, mid = (last + first) / 2)
1993     {
1994       int kwl = strlen (cxx_keywords[mid]);
1995       int min_length = kwl > length ? length : kwl;
1996       int r = utf8_cmp (name, min_length, cxx_keywords[mid]);
1997
1998       if (r == 0)
1999         {
2000           int i;
2001           /* We've found a match if all the remaining characters are
2002              `$'.  */
2003           for (i = min_length; i < length && name[i] == '$'; ++i)
2004             ;
2005           if (i == length)
2006             return 1;
2007           r = 1;
2008         }
2009
2010       if (r < 0)
2011         last = mid;
2012       else
2013         first = mid;
2014     }
2015   return 0;
2016 }
2017
2018 /* Lay METHOD_DECL out, returning a possibly new value of
2019    DTABLE_COUNT.  */
2020
2021 tree
2022 layout_class_method (this_class, super_class, method_decl, dtable_count)
2023      tree this_class, super_class, method_decl, dtable_count;
2024 {
2025   const char *ptr;
2026   char *asm_name;
2027   tree arg, arglist, t;
2028   int method_name_needs_escapes = 0;
2029   tree method_name = DECL_NAME (method_decl);
2030   int method_name_is_wfl = 
2031     (TREE_CODE (method_name) == EXPR_WITH_FILE_LOCATION);
2032   if (method_name_is_wfl)
2033     method_name = java_get_real_method_name (method_decl);
2034
2035   if (!ID_INIT_P (method_name) && !ID_FINIT_P (method_name))
2036     {
2037       int encoded_len
2038         = unicode_mangling_length (IDENTIFIER_POINTER (method_name), 
2039                                    IDENTIFIER_LENGTH (method_name));
2040       if (encoded_len > 0)
2041         {
2042           method_name_needs_escapes = 1;
2043           emit_unicode_mangled_name (&temporary_obstack,
2044                                      IDENTIFIER_POINTER (method_name), 
2045                                      IDENTIFIER_LENGTH (method_name));
2046         }
2047       else
2048         {
2049           obstack_grow (&temporary_obstack,
2050                         IDENTIFIER_POINTER (method_name),
2051                         IDENTIFIER_LENGTH (method_name));
2052         }
2053
2054       /* Mangle C++ keywords by appending a `$'.  */
2055       /* FIXME: NO_DOLLAR_IN_LABEL */
2056       if (cxx_keyword_p (IDENTIFIER_POINTER (method_name),
2057                          IDENTIFIER_LENGTH (method_name)))
2058         obstack_grow (&temporary_obstack, "$", 1);
2059     }
2060
2061   obstack_grow (&temporary_obstack, "__", 2);
2062   if (ID_FINIT_P (method_name))
2063     obstack_grow (&temporary_obstack, "finit", 5);
2064   append_gpp_mangled_type (&temporary_obstack, this_class);
2065   TREE_PUBLIC (method_decl) = 1;
2066
2067   t = TREE_TYPE (method_decl);
2068   arglist = TYPE_ARG_TYPES (t);
2069   if (TREE_CODE (t) == METHOD_TYPE)
2070     arglist = TREE_CHAIN (arglist);
2071   for (arg = arglist; arg != end_params_node;  )
2072     {
2073       tree a = arglist;
2074       tree argtype = TREE_VALUE (arg);
2075       int tindex = 1;
2076       if (TREE_CODE (argtype) == POINTER_TYPE)
2077         {
2078           /* This is O(N**2).  Do we care?  Cfr gcc/cp/method.c. */
2079           while (a != arg && argtype != TREE_VALUE (a))
2080             a = TREE_CHAIN (a), tindex++;
2081         }
2082       else
2083         a = arg;
2084       if (a != arg)
2085         {
2086           char buf[12];
2087           int nrepeats = 0;
2088           do
2089             {
2090               arg = TREE_CHAIN (arg); nrepeats++;
2091             }
2092           while (arg != end_params_node && argtype == TREE_VALUE (arg));
2093           if (nrepeats > 1)
2094             {
2095               obstack_1grow (&temporary_obstack, 'N');
2096               sprintf (buf, "%d", nrepeats);
2097               obstack_grow (&temporary_obstack, buf, strlen (buf));
2098               if (nrepeats > 9)
2099                 obstack_1grow (&temporary_obstack, '_');
2100             }
2101           else
2102             obstack_1grow (&temporary_obstack, 'T');
2103           sprintf (buf, "%d", tindex);
2104           obstack_grow (&temporary_obstack, buf, strlen (buf));
2105           if (tindex > 9)
2106             obstack_1grow (&temporary_obstack, '_');
2107         }
2108       else
2109         {
2110           append_gpp_mangled_type (&temporary_obstack, argtype);
2111           arg = TREE_CHAIN (arg);
2112         }
2113     }
2114   if (method_name_needs_escapes)
2115     obstack_1grow (&temporary_obstack, 'U');
2116
2117   obstack_1grow (&temporary_obstack, '\0');
2118   asm_name = obstack_finish (&temporary_obstack);
2119   DECL_ASSEMBLER_NAME (method_decl) = get_identifier (asm_name);
2120   /* We don't generate a RTL for the method if it's abstract, or if
2121      it's an interface method that isn't clinit. */
2122   if (! METHOD_ABSTRACT (method_decl) 
2123       || (CLASS_INTERFACE (TYPE_NAME (this_class)) 
2124           && (DECL_CLINIT_P (method_decl))))
2125     make_function_rtl (method_decl);
2126   obstack_free (&temporary_obstack, asm_name);
2127
2128   if (ID_INIT_P (method_name))
2129     {
2130       const char *p = IDENTIFIER_POINTER (DECL_NAME (TYPE_NAME (this_class)));
2131       for (ptr = p; *ptr; )
2132         {
2133           if (*ptr++ == '.')
2134             p = ptr;
2135         }
2136       if (method_name_is_wfl)
2137         EXPR_WFL_NODE (DECL_NAME (method_decl)) = get_identifier (p);
2138       else
2139         DECL_NAME (method_decl) = get_identifier (p);
2140       DECL_CONSTRUCTOR_P (method_decl) = 1;
2141       build_java_argument_signature (TREE_TYPE (method_decl));
2142     }
2143   else if (! METHOD_STATIC (method_decl) && !DECL_ARTIFICIAL (method_decl))
2144     {
2145       tree method_sig = 
2146         build_java_argument_signature (TREE_TYPE (method_decl));
2147       tree super_method = lookup_argument_method (super_class, method_name,
2148                                                   method_sig);
2149       if (super_method != NULL_TREE && ! METHOD_PRIVATE (super_method))
2150         {
2151           DECL_VINDEX (method_decl) = DECL_VINDEX (super_method);
2152           if (DECL_VINDEX (method_decl) == NULL_TREE 
2153               && !CLASS_FROM_SOURCE_P (this_class))
2154             error_with_decl (method_decl,
2155                              "non-static method '%s' overrides static method");
2156 #if 0
2157           else if (TREE_TYPE (TREE_TYPE (method_decl))
2158                    != TREE_TYPE (TREE_TYPE (super_method)))
2159             {
2160               error_with_decl (method_decl,
2161                                "Method `%s' redefined with different return type");  
2162               error_with_decl (super_method,
2163                                "Overridden decl is here");
2164             }
2165 #endif
2166         }
2167       else if (! METHOD_FINAL (method_decl)
2168                && ! METHOD_PRIVATE (method_decl)
2169                && ! CLASS_FINAL (TYPE_NAME (this_class))
2170                && dtable_count)
2171         {
2172           DECL_VINDEX (method_decl) = dtable_count;
2173           dtable_count = fold (build (PLUS_EXPR, integer_type_node,
2174                                       dtable_count, integer_one_node));
2175         }
2176     }
2177
2178   return dtable_count;
2179 }
2180
2181 static tree registered_class = NULL_TREE;
2182
2183 void
2184 register_class ()
2185 {
2186   /* END does not need to be registered with the garbage collector
2187      because it always points into the list given by REGISTERED_CLASS,
2188      and that variable is registered with the collector.  */
2189   static tree end;
2190   tree node    = TREE_OPERAND (build_class_ref (current_class), 0);
2191   tree current = copy_node (node);
2192
2193   XEXP (DECL_RTL (current), 0) = copy_rtx (XEXP (DECL_RTL(node), 0));
2194   if (!registered_class)
2195     registered_class = current;
2196   else
2197     TREE_CHAIN (end) = current;
2198
2199   end = current;
2200 }
2201
2202 /* Generate a function that gets called at start-up (static contructor) time,
2203    which calls registerClass for all the compiled classes. */
2204
2205 void
2206 emit_register_classes ()
2207 {
2208   extern tree get_file_function_name PARAMS ((int));
2209   tree init_name = get_file_function_name ('I');
2210   tree init_type = build_function_type (void_type_node, end_params_node);
2211   tree init_decl;
2212   tree t;
2213
2214   init_decl = build_decl (FUNCTION_DECL, init_name, init_type);
2215   DECL_ASSEMBLER_NAME (init_decl) = init_name;
2216   TREE_STATIC (init_decl) = 1;
2217   current_function_decl = init_decl;
2218   DECL_RESULT (init_decl) = build_decl(RESULT_DECL, NULL_TREE, void_type_node);
2219   /*  DECL_EXTERNAL (init_decl) = 1;*/
2220   TREE_PUBLIC (init_decl) = 1;
2221   pushlevel (0);
2222   make_function_rtl (init_decl);
2223   init_function_start (init_decl, input_filename, 0);
2224   expand_function_start (init_decl, 0);
2225
2226   for ( t = registered_class; t; t = TREE_CHAIN (t))
2227     emit_library_call (registerClass_libfunc, 0, VOIDmode, 1,
2228                        XEXP (DECL_RTL (t), 0), Pmode);
2229
2230   expand_function_end (input_filename, 0, 0);
2231   poplevel (1, 0, 1);
2232   { 
2233     /* Force generation, even with -O3 or deeper. Gross hack. FIXME */
2234     int saved_flag = flag_inline_functions;
2235     flag_inline_functions = 0;  
2236     rest_of_compilation (init_decl);
2237     flag_inline_functions = saved_flag;
2238   }
2239   current_function_decl = NULL_TREE;
2240   assemble_constructor (IDENTIFIER_POINTER (init_name));
2241 }
2242
2243 void
2244 init_class_processing ()
2245 {
2246   registerClass_libfunc = gen_rtx (SYMBOL_REF, Pmode, "_Jv_RegisterClass");
2247   ggc_add_tree_root (&registered_class, 1);
2248   ggc_add_rtx_root (&registerClass_libfunc, 1);
2249   gcc_obstack_init (&temporary_obstack);
2250 }