OSDN Git Service

0f8d488d1db8f0937da8a48805607b1a30ade400
[pf3gnuchains/gcc-fork.git] / gcc / java / class.c
1 /* Functions related to building classes and their related objects.
2    Copyright (C) 1996, 1997, 1998 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 "java-tree.h"
32 #include "jcf.h"
33 #include "obstack.h"
34 #include "toplev.h"
35
36 static tree mangle_class_field PROTO ((tree class));
37
38 static rtx registerClass_libfunc;
39
40 extern struct obstack permanent_obstack;
41 extern struct obstack temporary_obstack;
42
43 /* Return an IDENTIFIER_NODE the same as (OLD_NAME, OLD_LENGTH).
44    except that characters matching OLD_CHAR are substituted by NEW_CHAR.
45    Also, PREFIX is prepended, and SUFFIX is appended. */
46
47 tree
48 ident_subst (old_name, old_length, prefix, old_char, new_char, suffix)
49      const char* old_name;
50      int old_length;
51      const char *prefix;
52      int old_char;
53      int new_char;
54      const char *suffix;
55 {
56   int prefix_len = strlen (prefix);
57   int suffix_len = strlen (suffix);
58   int i = prefix_len + old_length + suffix_len + 1;
59 #ifdef __GNUC__
60   char buffer[i];
61 #else
62   char *buffer = (char *)alloca  (i);
63 #endif
64   strcpy (buffer, prefix);
65   for (i = 0; i < old_length; i++)
66     {
67       char ch = old_name[i];
68       if (ch == old_char)
69         ch = new_char;
70       buffer[prefix_len + i] = ch;
71     }
72   strcpy (buffer + prefix_len + old_length, suffix);
73   return get_identifier (buffer);
74 }
75
76 /* Return an IDENTIFIER_NODE the same as OLD_ID,
77    except that characters matching OLD_CHAR are substituted by NEW_CHAR.
78    Also, PREFIX is prepended, and SUFFIX is appended. */
79
80 tree
81 identifier_subst (old_id, prefix, old_char, new_char, suffix)
82      const tree old_id;
83      const char *prefix;
84      int old_char;
85      int new_char;
86      const char *suffix;
87 {
88   return ident_subst (IDENTIFIER_POINTER (old_id), IDENTIFIER_LENGTH (old_id),
89                       prefix, old_char, new_char, suffix);
90 }
91
92 /* Generate a valid C identifier from the name of the class TYPE,
93    prefixed by PREFIX. */
94
95 tree
96 mangled_classname (prefix, type)
97      char *prefix;
98      tree type;
99 {
100   tree ident = TYPE_NAME (type);
101   if (TREE_CODE (ident) != IDENTIFIER_NODE)
102     ident = DECL_NAME (ident);
103   return identifier_subst (ident, prefix, '/', '_', "");
104 }
105
106 tree
107 make_class ()
108 {
109   tree type;
110   push_obstacks (&permanent_obstack, &permanent_obstack);
111   type = make_node (RECORD_TYPE);
112 #ifdef JAVA_USE_HANDLES
113   tree field1 = build_decl (FIELD_DECL, get_identifier ("obj"),
114                             build_pointer_type (type));
115   tree field2 = build_decl (FIELD_DECL, get_identifier ("methods"),
116                             methodtable_ptr_type);
117   tree handle_type = make_node (RECORD_TYPE);
118   TREE_CHAIN (field1) = field2;
119   TYPE_FIELDS (handle_type) = field1;
120   TYPE_BINFO (type) = make_tree_vec (7);
121   TYPE_BINFO (handle_type) = make_tree_vec (7);
122   BINFO_HANDLE (TYPE_BINFO (handle_type)) = type;
123   BINFO_HANDLE (TYPE_BINFO (type)) = handle_type;
124 #else
125   TYPE_BINFO (type) = make_tree_vec (6);
126 #endif
127   CLASS_P (type) = 1;
128   pop_obstacks ();
129
130   return type;
131 }
132
133 /* Given a fully-qualified classname in NAME (whose length is NAME_LENGTH),
134    and where each of the constituents is separated by '/',
135    return a corresponding IDENTIFIER_NODE, except using '.' as separator. */
136
137 tree
138 unmangle_classname (name, name_length)
139      const char *name;  int name_length;
140 {
141   tree to_return = ident_subst (name, name_length, "", '/', '.', "");
142   if (to_return != get_identifier ((char *)name))
143     QUALIFIED_P (to_return) = 1;
144   return to_return;
145 }
146
147 tree
148 push_class (class_type, class_name)
149      tree class_type, class_name;
150 {
151   tree decl, signature;
152   char *save_input_filename = input_filename;
153   int save_lineno = lineno;
154   tree source_name = identifier_subst (class_name, "", '.', '/', ".java");
155   push_obstacks (&permanent_obstack, &permanent_obstack);
156   input_filename = IDENTIFIER_POINTER (source_name);
157   lineno = 0;
158   decl = build_decl (TYPE_DECL, class_name, class_type);
159   input_filename = save_input_filename;
160   lineno = save_lineno;
161   signature = identifier_subst (class_name, "L", '.', '/', ";");
162   IDENTIFIER_SIGNATURE_TYPE (signature) = build_pointer_type (class_type);
163
164   /* Setting DECL_ARTIFICAL forces dbxout.c to specific the type is
165      both a typedef and in the struct name-space.  We may want to re-visit
166      this later, but for now it reduces the changes needed for gdb. */
167   DECL_ARTIFICIAL (decl) = 1;
168
169   pushdecl_top_level (decl);
170 #ifdef JAVA_USE_HANDLES
171   {
172     tree handle_name = identifier_subst (class_name,
173                                          "Handle$", '.', '.', "");
174     tree handle_decl = build_decl (TYPE_DECL, handle_name,
175                                    CLASS_TO_HANDLE_TYPE (class_type));
176     pushdecl (handle_decl);
177   }
178 #endif
179
180   pop_obstacks ();
181   return decl;
182 }
183
184 /* Finds the (global) class named NAME.  Creates the class if not found.
185    Also creates associated TYPE_DECL.
186    Does not check if the class actually exists, load the class,
187    fill in field or methods, or do layout_type. */
188
189 tree
190 lookup_class (name)
191      tree name;
192 {
193   tree decl = IDENTIFIER_CLASS_VALUE (name);
194   if (decl == NULL_TREE)
195     decl = push_class (make_class (), name);
196   return TREE_TYPE (decl);
197 }
198
199 void
200 set_super_info (access_flags, this_class, super_class, interfaces_count)
201      int access_flags;
202      tree this_class;
203      tree super_class;
204      int interfaces_count;
205 {
206   int total_supers = interfaces_count;
207   tree class_decl = TYPE_NAME (this_class);
208   if (super_class)
209     total_supers++;
210
211   push_obstacks (&permanent_obstack, &permanent_obstack);
212   TYPE_BINFO_BASETYPES (this_class) = make_tree_vec (total_supers);
213   if (super_class)
214     {
215       tree super_binfo = make_tree_vec (6);
216       BINFO_TYPE (super_binfo) = super_class;
217       BINFO_OFFSET (super_binfo) = integer_zero_node;
218       TREE_VIA_PUBLIC (super_binfo) = 1;
219       TREE_VEC_ELT (BINFO_BASETYPES (TYPE_BINFO (this_class)), 0)
220         = super_binfo;
221       CLASS_HAS_SUPER (this_class) = 1;
222     }
223   pop_obstacks ();
224   
225   if (access_flags & ACC_PUBLIC)    CLASS_PUBLIC (class_decl) = 1;
226   if (access_flags & ACC_FINAL)     CLASS_FINAL (class_decl) = 1;
227   if (access_flags & ACC_SUPER)     CLASS_SUPER (class_decl) = 1;
228   if (access_flags & ACC_INTERFACE) CLASS_INTERFACE (class_decl) = 1;
229   if (access_flags & ACC_ABSTRACT)  CLASS_ABSTRACT (class_decl) = 1;
230 }
231
232 /* Return length of inheritance chain of CLAS, where java.lang.Object is 0,
233    direct sub-classes of Object are 1, and so on. */
234
235 int
236 class_depth (clas)
237      tree clas;
238 {
239   int depth = 0;
240   if (! CLASS_LOADED_P (clas))
241     load_class (clas, 1);
242   while (clas != object_type_node)
243     {
244       depth++;
245       clas = TYPE_BINFO_BASETYPE (clas, 0);
246     }
247   return depth;
248 }
249
250 /* Return true iff TYPE2 is an interface that extends interface TYPE1 */
251
252 int
253 interface_of_p (type1, type2)
254      tree type1, type2;
255 {
256   int n, i;
257   tree basetype_vec;
258
259   if (!(basetype_vec = TYPE_BINFO_BASETYPES (type2)))
260     return 0;
261   n = TREE_VEC_LENGTH (basetype_vec);
262   for (i = 0; i < n; i++)
263     {
264       tree vec_elt = TREE_VEC_ELT (basetype_vec, i);
265       if (vec_elt && BINFO_TYPE (vec_elt) == type1)
266         return 1;
267     }
268   for (i = 0; i < n; i++)
269     {
270       tree vec_elt = TREE_VEC_ELT (basetype_vec, i);
271       if (vec_elt && BINFO_TYPE (vec_elt) 
272           && interface_of_p (type1, BINFO_TYPE (vec_elt)))
273         return 1;
274     }
275   return 0;
276 }
277
278 /* Return true iff TYPE1 inherits from TYPE2. */
279
280 int
281 inherits_from_p (type1, type2)
282      tree type1, type2;
283 {
284   while (type1 != NULL_TREE && TREE_CODE (type1) == RECORD_TYPE)
285     {
286       if (type1 == type2)
287         return 1;
288       type1 = CLASSTYPE_SUPER (type1);
289     }
290   return 0;
291 }
292
293 static void
294 add_interface_do (basetype_vec, interface_class, i)
295      tree basetype_vec, interface_class;
296      int i;
297 {
298   tree interface_binfo = make_tree_vec (6);
299   BINFO_TYPE (interface_binfo) = interface_class;
300   BINFO_OFFSET (interface_binfo) = integer_zero_node;
301   TREE_VIA_VIRTUAL (interface_binfo) = 1;
302   TREE_VIA_PUBLIC (interface_binfo) = 1;
303   TREE_VEC_ELT (basetype_vec, i) = interface_binfo;
304 }
305
306 /* Add INTERFACE_CLASS to THIS_CLASS iff INTERFACE_CLASS can't be
307    found in THIS_CLASS. Returns NULL_TREE upon success, INTERFACE_CLASS
308    if attempt is made to add it twice. */
309
310 tree
311 maybe_add_interface (this_class, interface_class)
312      tree this_class, interface_class;
313 {
314   tree basetype_vec = TYPE_BINFO_BASETYPES (this_class);
315   tree interface_binfo = make_tree_vec (6);
316   int i;
317   int n = TREE_VEC_LENGTH (basetype_vec);
318   for (i = 0; ; i++)
319     {
320       if (i >= n)
321         {
322           error ("internal error - too many interface type");
323           return NULL_TREE;
324         }
325       else if (TREE_VEC_ELT (basetype_vec, i) == NULL_TREE)
326         break;
327       else if (BINFO_TYPE (TREE_VEC_ELT (basetype_vec, i)) == interface_class)
328         return interface_class;
329     } 
330   add_interface_do (basetype_vec, interface_class, i);
331   return NULL_TREE;
332 }
333
334 /* Add the INTERFACE_CLASS as one of the interfaces of THIS_CLASS. */
335
336 void
337 add_interface (this_class, interface_class)
338      tree this_class, interface_class;
339 {
340   tree basetype_vec = TYPE_BINFO_BASETYPES (this_class);
341   int i;
342   int n = TREE_VEC_LENGTH (basetype_vec);
343   for (i = 0; ; i++)
344     {
345       if (i >= n)
346         {
347           error ("internal error - too many interface type");
348           return;
349         }
350       else if (TREE_VEC_ELT (basetype_vec, i) == NULL_TREE)
351         break;
352     }
353   add_interface_do (basetype_vec, interface_class, i);
354 }
355
356 /* Return the address of a pointer to the first FUNCTION_DECL
357    in the list (*LIST) whose DECL_NAME is NAME. */
358
359 static tree *
360 find_named_method (list, name)
361      tree *list;
362      tree name;
363 {
364   while (*list && DECL_NAME (*list) != name)
365     list = &TREE_CHAIN (*list);
366   return list;
367 }
368
369 tree
370 build_java_method_type (fntype, this_class, access_flags)
371      tree fntype;
372      tree this_class;
373      int access_flags;
374 {
375   if (access_flags & ACC_STATIC)
376     return fntype;
377   return build_method_type (CLASS_TO_HANDLE_TYPE (this_class), fntype);
378 }
379
380 tree
381 add_method_1 (handle_class, access_flags, name, function_type)
382      tree handle_class;
383      int access_flags;
384      tree name;
385      tree function_type;
386 {
387   tree method_type, fndecl;
388   push_obstacks (&permanent_obstack, &permanent_obstack);
389
390   method_type = build_java_method_type (function_type,
391                                         handle_class, access_flags);
392
393   fndecl = build_decl (FUNCTION_DECL, name, method_type);
394   DECL_CONTEXT (fndecl) = handle_class;
395
396   DECL_LANG_SPECIFIC (fndecl)
397     = (struct lang_decl *) permalloc (sizeof (struct lang_decl));
398   bzero (DECL_LANG_SPECIFIC (fndecl), sizeof (struct lang_decl));
399
400   TREE_CHAIN (fndecl) = TYPE_METHODS (handle_class);
401   TYPE_METHODS (handle_class) = fndecl;
402   pop_obstacks ();
403
404   if (access_flags & ACC_PUBLIC) METHOD_PUBLIC (fndecl) = 1;
405   if (access_flags & ACC_PROTECTED) METHOD_PROTECTED (fndecl) = 1;
406   if (access_flags & ACC_PRIVATE) METHOD_PRIVATE (fndecl) = 1;
407   if (access_flags & ACC_NATIVE) METHOD_NATIVE (fndecl) = 1;
408   if (access_flags & ACC_STATIC) METHOD_STATIC (fndecl) = 1;
409   if (access_flags & ACC_FINAL) METHOD_FINAL (fndecl) = 1;
410   if (access_flags & ACC_SYNCHRONIZED) METHOD_SYNCHRONIZED (fndecl) = 1;
411   if (access_flags & ACC_ABSTRACT) METHOD_ABSTRACT (fndecl) = 1;
412   if (access_flags & ACC_TRANSIENT) METHOD_TRANSIENT (fndecl) = 1;
413   return fndecl;
414 }
415
416 /* Add a method to THIS_CLASS.
417    The method's name is NAME.
418    Its signature (mangled type) is METHOD_SIG (an IDENTIFIER_NODE). */
419
420 tree
421 add_method (this_class, access_flags, name, method_sig)
422      tree this_class;
423      int access_flags;
424      tree name;
425      tree method_sig;
426 {
427   tree handle_class = CLASS_TO_HANDLE_TYPE (this_class);
428   tree function_type, fndecl;
429   unsigned char *sig = (unsigned char*)IDENTIFIER_POINTER (method_sig);
430   push_obstacks (&permanent_obstack, &permanent_obstack);
431   if (sig[0] != '(')
432     fatal ("bad method signature");
433   function_type = get_type_from_signature (method_sig);
434   fndecl = add_method_1 (handle_class, access_flags, name, function_type);
435   set_java_signature (TREE_TYPE (fndecl), method_sig);
436   pop_obstacks ();
437   return fndecl;
438 }
439
440 tree
441 add_field (class, name, field_type, flags)
442      tree class;
443      tree name;
444      tree field_type;
445      int flags;
446 {
447   int is_static = (flags & ACC_STATIC) != 0;
448   tree field;
449   /* Push the obstack of field_type ? FIXME */
450   push_obstacks (&permanent_obstack, &permanent_obstack);
451   field = build_decl (is_static ? VAR_DECL : FIELD_DECL, name, field_type);
452   pop_obstacks ();
453   TREE_CHAIN (field) = TYPE_FIELDS (class);
454   TYPE_FIELDS (class) = field;
455   DECL_CONTEXT (field) = class;
456
457   if (flags & ACC_PUBLIC) FIELD_PUBLIC (field) = 1;
458   if (flags & ACC_PROTECTED) FIELD_PROTECTED (field) = 1;
459   if (flags & ACC_PRIVATE) FIELD_PRIVATE (field) = 1;
460   if (flags & ACC_FINAL) FIELD_FINAL (field) = 1;
461   if (flags & ACC_VOLATILE) FIELD_VOLATILE (field) = 1;
462   if (flags & ACC_TRANSIENT) FIELD_TRANSIENT (field) = 1;
463   if (is_static)
464     {
465       FIELD_STATIC (field) = 1;
466       /* Always make field externally visible.  This is required so
467          that native methods can always access the field.  */
468       TREE_PUBLIC (field) = 1;
469     }
470   return field;
471 }
472
473 /* Associate a constant value CONSTANT with VAR_DECL FIELD. */
474
475 void
476 set_constant_value (field, constant)
477      tree field, constant;
478 {
479   if (field == NULL_TREE)
480     warning ("misplaced ConstantValue attribute (not in any field)");
481   else if (DECL_INITIAL (field) != NULL_TREE)
482     warning ("duplicate ConstanValue atribute for field '%s'",
483              IDENTIFIER_POINTER (DECL_NAME (field)));
484   else
485     DECL_INITIAL (field) = constant;
486 }
487
488 /* Count the number of Unicode chars encoded in a given Ut8 string. */
489
490 int
491 strLengthUtf8 (str, len)
492      char *str;
493      int len;
494 {
495   register unsigned char* ptr = (unsigned char*) str;
496   register unsigned char *limit = ptr + len;
497   int str_length = 0;
498   for (; ptr < limit; str_length++) {
499     if (UTF8_GET (ptr, limit) < 0)
500       return -1;
501   }
502   return str_length;
503 }
504
505
506 /* Calculate a hash value for a string encoded in Utf8 format.
507  * This returns the same hash value as specified for java.lang.String.hashCode.
508  */
509
510 int32
511 hashUtf8String (str, len)
512      char *str;
513      int len;
514 {
515   register unsigned char* ptr = (unsigned char*) str;
516   register unsigned char *limit = ptr + len;
517   int32 hash = 0;
518   for (; ptr < limit;)
519     {
520       int ch = UTF8_GET (ptr, limit);
521       /* Updated specification from
522          http://www.javasoft.com/docs/books/jls/clarify.html. */
523       hash = (31 * hash) + ch;
524     }
525   return hash;
526 }
527
528 tree utf8_decl_list = NULL_TREE;
529
530 tree
531 build_utf8_ref (name)
532      tree name;
533 {
534   char* name_ptr = IDENTIFIER_POINTER(name);
535   int name_len = IDENTIFIER_LENGTH(name);
536   char buf[60];
537   char *buf_ptr;
538   tree ctype, field, str_type, cinit, string;
539   static int utf8_count = 0;
540   int name_hash;
541   tree ref = IDENTIFIER_UTF8_REF (name);
542   tree decl;
543   if (ref != NULL_TREE)
544     return ref;
545
546   push_obstacks (&permanent_obstack, &permanent_obstack);
547   ctype = make_node (RECORD_TYPE);
548   str_type = build_prim_array_type (unsigned_byte_type_node,
549                                     name_len + 1); /* Allow for final '\0'. */
550   PUSH_FIELD (ctype, field, "hash", unsigned_short_type_node);
551   PUSH_FIELD (ctype, field, "length", unsigned_short_type_node);
552   PUSH_FIELD (ctype, field, "data", str_type);
553   FINISH_RECORD (ctype);
554   START_RECORD_CONSTRUCTOR (cinit, ctype);
555   name_hash = hashUtf8String (name_ptr, name_len) & 0xFFFF;
556   PUSH_FIELD_VALUE (cinit, "hash", build_int_2 (name_hash, 0));
557   PUSH_FIELD_VALUE (cinit, "length", build_int_2 (name_len, 0));
558   string = build_string (name_len, name_ptr);
559   TREE_TYPE (string) = str_type;
560   PUSH_FIELD_VALUE (cinit, "data", string);
561   FINISH_RECORD_CONSTRUCTOR (cinit);
562
563   /* Build a unique identifier based on buf. */
564   sprintf(buf, "_Utf%d", ++utf8_count);
565   buf_ptr = &buf[strlen (buf)];
566   while (--name_len >= 0)
567     {
568       char c = *name_ptr++;
569       if (c & 0x80)
570         continue;
571       if (!isalpha(c) && !isdigit(c))
572         c = '_';
573       *buf_ptr++ = c;
574       if (buf_ptr >= buf + 50)
575         break;
576     }
577   *buf_ptr = '\0';
578
579   decl = build_decl (VAR_DECL, get_identifier (buf), utf8const_type);
580   /* FIXME get some way to force this into .text, not .data. */
581   TREE_STATIC (decl) = 1;
582   DECL_ARTIFICIAL (decl) = 1;
583   DECL_IGNORED_P (decl) = 1;
584   TREE_READONLY (decl) = 1;
585   DECL_INITIAL (decl) = cinit;
586   TREE_CHAIN (decl) = utf8_decl_list;
587   layout_decl (decl, 0);
588   pushdecl (decl);
589   rest_of_decl_compilation (decl, (char*) 0, global_bindings_p (), 0);
590   utf8_decl_list = decl;
591   make_decl_rtl (decl, (char*) 0, 1);
592   ref = build1 (ADDR_EXPR, utf8const_ptr_type, decl);
593   IDENTIFIER_UTF8_REF (name) = ref;
594   pop_obstacks ();
595   return ref;
596 }
597
598 /* Build a reference to the class TYPE.
599    Also handles primitive types and array types. */
600
601 tree
602 build_class_ref (type)
603      tree type;
604 {
605   int is_compiled = is_compiled_class (type);
606   if (is_compiled)
607     {
608       tree ref, decl_name, decl;
609       if (TREE_CODE (type) == POINTER_TYPE)
610         type = TREE_TYPE (type);
611       if (TREE_CODE (type) == RECORD_TYPE)
612         {
613           if (TYPE_SIZE (type) == error_mark_node)
614             return null_pointer_node;
615           decl_name = identifier_subst (DECL_NAME (TYPE_NAME (type)),
616                                         "", '/', '/', ".class");
617           decl = IDENTIFIER_GLOBAL_VALUE (decl_name);
618           if (decl == NULL_TREE)
619             {
620               push_obstacks (&permanent_obstack, &permanent_obstack);
621               decl = build_decl (VAR_DECL, decl_name, class_type_node);
622               DECL_SIZE (decl) = TYPE_SIZE (class_type_node);
623               TREE_STATIC (decl) = 1;
624               TREE_PUBLIC (decl) = 1;
625               DECL_IGNORED_P (decl) = 1;
626               DECL_ARTIFICIAL (decl) = 1;
627               DECL_ASSEMBLER_NAME (decl) = mangle_class_field (type);
628               make_decl_rtl (decl, NULL, 1);
629               pushdecl_top_level (decl);
630               if (is_compiled == 1)
631                 DECL_EXTERNAL (decl) = 1;
632               pop_obstacks ();
633             }
634         }
635       else
636         {
637           char *name;
638           char buffer[25];
639           decl_name = TYPE_NAME (type);
640           if (TREE_CODE (decl_name) == TYPE_DECL)
641             decl_name = DECL_NAME (decl_name);
642           name = IDENTIFIER_POINTER (decl_name);
643           if (strncmp (name, "promoted_", 9) == 0)
644             name += 9;
645           sprintf (buffer, "_Jv_%sClass", name);
646           decl_name = get_identifier (buffer);
647           decl = IDENTIFIER_GLOBAL_VALUE (decl_name);
648           if (decl == NULL_TREE)
649             {
650               push_obstacks (&permanent_obstack, &permanent_obstack);
651               decl = build_decl (VAR_DECL, decl_name, class_type_node);
652               TREE_STATIC (decl) = 1;
653               TREE_PUBLIC (decl) = 1;
654               make_decl_rtl (decl, NULL, 1);
655               pushdecl_top_level (decl);
656               if (is_compiled == 1)
657                 DECL_EXTERNAL (decl) = 1;
658               pop_obstacks ();
659             }
660         }
661
662       ref = build1 (ADDR_EXPR, class_ptr_type, decl);
663       return ref;
664     }
665   else
666     {
667       int index;
668       tree cl;
669       push_obstacks (&permanent_obstack, &permanent_obstack);
670       index = alloc_class_constant (type);
671       cl = build_ref_from_constant_pool (index); 
672       TREE_TYPE (cl) = promote_type (class_ptr_type);
673       pop_obstacks ();
674       return cl;
675     }
676 }
677
678 tree
679 build_static_field_ref (fdecl)
680      tree fdecl;
681 {
682   tree fclass = DECL_CONTEXT (fdecl);
683   int is_compiled = is_compiled_class (fclass);
684   if (is_compiled)
685     {
686       if (DECL_RTL (fdecl) == 0)
687         {
688           push_obstacks (&permanent_obstack, &permanent_obstack);
689           make_decl_rtl (fdecl, NULL, 1);
690           pop_obstacks ();
691           if (is_compiled == 1)
692             DECL_EXTERNAL (fdecl) = 1;
693         }
694       return fdecl;
695     }
696   else
697     {
698       /* Compile as:
699        * *(FTYPE*)build_class_ref(FCLASS)->fields[INDEX].info.addr
700        */
701       static tree fields_ident = NULL_TREE;
702       static tree info_ident = NULL_TREE;
703       tree ref = build_class_ref (fclass);
704       tree fld;
705       int field_index = 0;
706       ref = build1 (INDIRECT_REF, class_type_node, ref);
707       if (fields_ident == NULL_TREE)
708         fields_ident = get_identifier ("fields");
709       if (info_ident == NULL_TREE)
710         info_ident = get_identifier ("info");
711       ref = build (COMPONENT_REF, field_ptr_type_node, ref,
712                    lookup_field (&class_type_node, fields_ident));
713
714       for (fld = TYPE_FIELDS (fclass); ; fld = TREE_CHAIN (fld))
715         {
716           if (fld == fdecl)
717             break;
718           if (fld == NULL_TREE)
719             fatal ("field '%s' not found in class",
720                    IDENTIFIER_POINTER (DECL_NAME (fdecl)));
721           if (FIELD_STATIC (fld))
722             field_index++;
723         }
724       field_index *= int_size_in_bytes (field_type_node);
725       ref = fold (build (PLUS_EXPR, field_ptr_type_node,
726                          ref, build_int_2 (field_index, 0)));
727       ref = build1 (INDIRECT_REF, field_type_node, ref);
728       ref = build (COMPONENT_REF, field_info_union_node,
729                    ref, lookup_field (&field_type_node, info_ident));
730       ref = build (COMPONENT_REF, ptr_type_node,
731                    ref, TREE_CHAIN (TYPE_FIELDS (field_info_union_node)));
732       return fold (build1 (INDIRECT_REF, TREE_TYPE(fdecl), ref));
733     }
734 }
735
736 int
737 get_access_flags_from_decl (decl)
738      tree decl;
739 {
740   int access_flags = 0;
741   if (TREE_CODE (decl) == FIELD_DECL || TREE_CODE (decl) == VAR_DECL)
742     {
743       if (FIELD_STATIC (decl))
744         access_flags |= ACC_STATIC;
745       if (FIELD_PUBLIC (decl))
746         access_flags |= ACC_PUBLIC;
747       if (FIELD_PROTECTED (decl))
748         access_flags |= ACC_PROTECTED;
749       if (FIELD_PRIVATE (decl))
750         access_flags |= ACC_PRIVATE;
751       if (FIELD_FINAL (decl))
752         access_flags |= ACC_FINAL;
753       if (FIELD_VOLATILE (decl))
754         access_flags |= ACC_VOLATILE;
755       if (FIELD_TRANSIENT (decl))
756         access_flags |= ACC_TRANSIENT;
757       return access_flags;
758     }
759   if (TREE_CODE (decl) == TYPE_DECL)
760     {
761       if (CLASS_PUBLIC (decl))
762         access_flags |= ACC_PUBLIC;
763       if (CLASS_FINAL (decl))
764         access_flags |= ACC_FINAL;
765       if (CLASS_SUPER (decl))
766         access_flags |= ACC_SUPER;
767       if (CLASS_INTERFACE (decl))
768         access_flags |= ACC_INTERFACE;
769       if (CLASS_ABSTRACT (decl))
770         access_flags |= ACC_ABSTRACT;
771       return access_flags;
772     }
773   if (TREE_CODE (decl) == FUNCTION_DECL)
774     {
775       if (METHOD_PUBLIC (decl))
776         access_flags |= ACC_PUBLIC;
777       if (METHOD_PRIVATE (decl))
778         access_flags |= ACC_PRIVATE;
779       if (METHOD_PROTECTED (decl))
780         access_flags |= ACC_PROTECTED;
781       if (METHOD_STATIC (decl))
782         access_flags |= ACC_STATIC;
783       if (METHOD_FINAL (decl))
784         access_flags |= ACC_FINAL;
785       if (METHOD_SYNCHRONIZED (decl))
786         access_flags |= ACC_SYNCHRONIZED;
787       if (METHOD_NATIVE (decl))
788         access_flags |= ACC_NATIVE;
789       if (METHOD_ABSTRACT (decl))
790         access_flags |= ACC_ABSTRACT;
791       if (METHOD_TRANSIENT (decl))
792         access_flags |= ACC_TRANSIENT;
793       return access_flags;
794     }
795   abort ();
796 }
797
798 tree
799 make_field_value (tree fdecl)
800 {
801   tree finit, info;
802   int bsize, flags;
803   tree type = TREE_TYPE (fdecl);
804   int resolved = is_compiled_class (type);
805   START_RECORD_CONSTRUCTOR (finit, field_type_node);
806   PUSH_FIELD_VALUE (finit, "name", build_utf8_ref (DECL_NAME (fdecl)));
807   if (resolved)
808     type = build_class_ref (type);
809   else
810     type = build_utf8_ref (build_java_signature (type));
811   PUSH_FIELD_VALUE (finit, "type", type);
812   flags = get_access_flags_from_decl (fdecl);
813   if (! resolved)
814     flags |= 0x8000 /* FIELD_UNRESOLVED_FLAG */;
815   PUSH_FIELD_VALUE (finit, "accflags", build_int_2 (flags, 0));
816   bsize = TREE_INT_CST_LOW (TYPE_SIZE (TREE_TYPE (fdecl))) / BITS_PER_UNIT;
817   PUSH_FIELD_VALUE (finit, "bsize", build_int_2 (bsize, 0));
818   if (FIELD_STATIC (fdecl))
819     {
820       tree cfield = TREE_CHAIN (TYPE_FIELDS(field_info_union_node));
821       tree faddr = build_address_of (build_static_field_ref (fdecl));
822       info = build (CONSTRUCTOR, field_info_union_node, NULL_TREE,
823                     build_tree_list (cfield, faddr));
824     }
825   else
826     {
827       int boffset
828         = TREE_INT_CST_LOW (DECL_FIELD_BITPOS (fdecl)) / BITS_PER_UNIT;
829       info = build (CONSTRUCTOR, field_info_union_node, NULL_TREE,
830                     build_tree_list (TYPE_FIELDS(field_info_union_node),
831                                      build_int_2 (boffset, 0)));
832     }
833   PUSH_FIELD_VALUE (finit, "info", info);
834
835   FINISH_RECORD_CONSTRUCTOR (finit);
836   return finit;
837 }
838
839 tree
840 make_method_value (mdecl, this_class_addr)
841      tree mdecl;
842      tree this_class_addr;
843 {
844   tree minit;
845   tree code;
846 #define ACC_TRANSLATED          0x4000
847   int accflags = get_access_flags_from_decl (mdecl) | ACC_TRANSLATED;
848   code = null_pointer_node;
849   if (DECL_RTL (mdecl))
850     code = build1 (ADDR_EXPR, nativecode_ptr_type_node, mdecl);
851   START_RECORD_CONSTRUCTOR (minit, method_type_node);
852   PUSH_FIELD_VALUE (minit, "name",
853                     build_utf8_ref (DECL_CONSTRUCTOR_P (mdecl) ?
854                                     init_identifier_node
855                                     : DECL_NAME (mdecl)));
856   PUSH_FIELD_VALUE (minit, "signature",
857                     build_utf8_ref (build_java_signature (TREE_TYPE (mdecl))));
858   PUSH_FIELD_VALUE (minit, "accflags", build_int_2 (accflags, 0));
859   PUSH_FIELD_VALUE (minit, "ncode", code);
860   FINISH_RECORD_CONSTRUCTOR (minit);
861   return minit;
862 }
863
864 tree
865 get_dispatch_vector (type)
866      tree type;
867 {
868   tree vtable = TYPE_VTABLE (type);
869   if (vtable == NULL)
870     {
871       int i;
872       tree method;
873       tree super = CLASSTYPE_SUPER (type);
874       int nvirtuals = TREE_INT_CST_LOW (TYPE_NVIRTUALS (type));
875       vtable = make_tree_vec (nvirtuals);
876       TYPE_VTABLE (type) = vtable;
877       if (super != NULL_TREE)
878         {
879           tree super_vtable = get_dispatch_vector (super);
880           for ( i = TREE_INT_CST_LOW (TYPE_NVIRTUALS (super));  --i >= 0; )
881             TREE_VEC_ELT (vtable, i) = TREE_VEC_ELT (super_vtable, i);
882         }
883       for (method = TYPE_METHODS (type);  method != NULL_TREE;
884            method = TREE_CHAIN (method))
885         {
886           if (DECL_VINDEX (method) != NULL_TREE
887               && TREE_CODE (DECL_VINDEX (method)) == INTEGER_CST)
888             {
889               TREE_VEC_ELT (vtable, TREE_INT_CST_LOW (DECL_VINDEX (method)))
890                 = method;
891             }
892         }
893     }
894   return vtable;
895 }
896
897 tree
898 get_dispatch_table (type, this_class_addr)
899      tree type, this_class_addr;
900 {
901   tree vtable = get_dispatch_vector (type);
902   int i;
903   tree list = NULL_TREE;
904   int nvirtuals = TREE_VEC_LENGTH (vtable);
905   for (i = nvirtuals;  --i >= 0; )
906     {
907       tree method = TREE_VEC_ELT (vtable, i);
908       if (METHOD_ABSTRACT (method))
909         warning_with_decl (method, "abstract method in non-abstract class");
910       if (DECL_RTL (method) == 0)
911         make_decl_rtl (method, NULL, 1);
912       list = tree_cons (NULL_TREE /*DECL_VINDEX (method) + 2*/,
913                         build1 (ADDR_EXPR, nativecode_ptr_type_node, method),
914                         list);
915     }
916   /* Dummy entry for compatibility with G++ -fvtable-thunks. */
917   list = tree_cons (integer_zero_node, null_pointer_node, list);
918   list = tree_cons (integer_zero_node, this_class_addr, list);
919   return build (CONSTRUCTOR, build_prim_array_type (nativecode_ptr_type_node,
920                                                     nvirtuals + 2),
921                  NULL_TREE, list);
922 }
923
924 void
925 make_class_data (type)
926      tree type;
927 {
928   tree decl, cons, temp;
929   tree field, fields_decl;
930   tree static_fields = NULL_TREE;
931   tree instance_fields = NULL_TREE;
932   HOST_WIDE_INT static_field_count = 0;
933   HOST_WIDE_INT instance_field_count = 0;
934   HOST_WIDE_INT field_count;
935   tree field_array_type;
936   tree method;
937   tree methods = NULL_TREE;
938   tree dtable_decl = NULL_TREE;
939   HOST_WIDE_INT method_count = 0;
940   tree method_array_type;
941   tree methods_decl;
942   tree super;
943   tree this_class_addr;
944   tree constant_pool_constructor;
945   tree interfaces = null_pointer_node;
946   int interface_len = 0;
947   tree type_decl = TYPE_NAME (type);
948
949   this_class_addr = build_class_ref (type);
950   decl = TREE_OPERAND (this_class_addr, 0);
951
952   /* Build Field array. */
953   field = TYPE_FIELDS (type);
954   if (DECL_NAME (field) == NULL_TREE)
955     field = TREE_CHAIN (field);  /* Skip dummy field for inherited data. */
956   for ( ;  field != NULL_TREE;  field = TREE_CHAIN (field))
957     {
958       if (! DECL_ARTIFICIAL (field))
959         {
960           tree init = make_field_value (field);
961           if (FIELD_STATIC (field))
962             {
963               static_field_count++;
964               static_fields = tree_cons (NULL_TREE, init, static_fields);
965               rest_of_decl_compilation (field, (char*) 0, 1, 1);
966             }
967           else
968             {
969               instance_field_count++;
970               instance_fields = tree_cons (NULL_TREE, init, instance_fields);
971             }
972         }
973     }
974   field_count = static_field_count + instance_field_count;
975   if (field_count > 0)
976     {
977       static_fields = nreverse (static_fields);
978       instance_fields = nreverse (instance_fields);
979       static_fields = chainon (static_fields, instance_fields);
980       field_array_type = build_prim_array_type (field_type_node, field_count);
981       fields_decl = build_decl (VAR_DECL, mangled_classname ("_FL_", type),
982                                 field_array_type);
983       DECL_INITIAL (fields_decl) = build (CONSTRUCTOR, field_array_type,
984                                           NULL_TREE, static_fields);
985       TREE_STATIC (fields_decl) = 1;
986       DECL_ARTIFICIAL (fields_decl) = 1;
987       DECL_IGNORED_P (fields_decl) = 1;
988       rest_of_decl_compilation (fields_decl, (char*) 0, 1, 0);
989     }
990   else
991     fields_decl = NULL_TREE;
992
993   /* Build Method array. */
994   for (method = TYPE_METHODS (CLASS_TO_HANDLE_TYPE (type));
995        method != NULL_TREE; method = TREE_CHAIN (method))
996     {
997       tree init = make_method_value (method, this_class_addr);
998       method_count++;
999       methods = tree_cons (NULL_TREE, init, methods);
1000     }
1001   method_array_type = build_prim_array_type (method_type_node, method_count);
1002   methods_decl = build_decl (VAR_DECL, mangled_classname ("_MT_", type),
1003                              method_array_type);
1004   DECL_INITIAL (methods_decl) = build (CONSTRUCTOR, method_array_type,
1005                                        NULL_TREE, nreverse (methods));
1006   TREE_STATIC (methods_decl) = 1;
1007   DECL_ARTIFICIAL (methods_decl) = 1;
1008   DECL_IGNORED_P (methods_decl) = 1;
1009   rest_of_decl_compilation (methods_decl, (char*) 0, 1, 0);
1010
1011   if (flag_assume_compiled
1012       && ! CLASS_ABSTRACT (type_decl) && ! CLASS_INTERFACE (type_decl))
1013     {
1014       tree dtable = get_dispatch_table (type, this_class_addr);
1015       dtable_decl = build_dtable_decl (type);
1016       DECL_INITIAL (dtable_decl) = dtable;
1017       TREE_STATIC (dtable_decl) = 1;
1018       DECL_ARTIFICIAL (dtable_decl) = 1;
1019       DECL_IGNORED_P (dtable_decl) = 1;
1020       TREE_PUBLIC (dtable_decl) = 1;
1021       rest_of_decl_compilation (dtable_decl, (char*) 0, 1, 0);
1022     }
1023
1024   super = CLASSTYPE_SUPER (type);
1025   if (super == NULL_TREE)
1026     super = null_pointer_node;
1027   else if (flag_assume_compiled)
1028     super = build_class_ref (super);
1029   else
1030     {
1031       int super_index = alloc_class_constant (super);
1032       super = build_int_2 (super_index, 0);
1033       TREE_TYPE (super) == ptr_type_node;
1034     }
1035
1036   /* Build and emit the array of implemented interfaces. */
1037   if (type != object_type_node)
1038       interface_len = TREE_VEC_LENGTH (TYPE_BINFO_BASETYPES (type)) - 1;
1039   if (interface_len > 0)
1040     {
1041       tree init = NULL_TREE;
1042       int i;
1043       tree interface_array_type, idecl;
1044       interface_array_type
1045         = build_prim_array_type (class_ptr_type, interface_len);
1046       idecl = build_decl (VAR_DECL, mangled_classname ("_IF_", type),
1047                           interface_array_type);
1048       for (i = interface_len;  i > 0; i--)
1049         {
1050           tree child = TREE_VEC_ELT (TYPE_BINFO_BASETYPES (type), i);
1051           tree iclass = BINFO_TYPE (child);
1052           tree index;
1053           if (flag_assume_compiled)
1054             index = build_class_ref (iclass);
1055           else
1056             {
1057                 int int_index = alloc_class_constant (iclass);
1058                 index = build_int_2 (int_index, 0);
1059                 TREE_TYPE (index) == ptr_type_node;
1060             }
1061           init = tree_cons (NULL_TREE, index, init); 
1062         }
1063       DECL_INITIAL (idecl) = build (CONSTRUCTOR, interface_array_type,
1064                                     NULL_TREE, init);
1065       TREE_STATIC (idecl) = 1;
1066       DECL_ARTIFICIAL (idecl) = 1;
1067       DECL_IGNORED_P (idecl) = 1;
1068       interfaces = build1 (ADDR_EXPR, ptr_type_node, idecl);
1069       rest_of_decl_compilation (idecl,  (char*) 0, 1, 0);
1070     }
1071
1072   constant_pool_constructor = build_constants_constructor ();
1073
1074   START_RECORD_CONSTRUCTOR (temp, object_type_node);
1075 #if 0
1076   PUSH_FIELD_VALUE (temp, "dtable", NULL_TREE);
1077 #else
1078   PUSH_FIELD_VALUE (temp, "dtable",
1079                     build1 (ADDR_EXPR, dtable_ptr_type, class_dtable_decl));
1080 #endif
1081   PUSH_FIELD_VALUE (temp, "sync_info", null_pointer_node);
1082   FINISH_RECORD_CONSTRUCTOR (temp);
1083   START_RECORD_CONSTRUCTOR (cons, class_type_node);
1084   PUSH_SUPER_VALUE (cons, temp);
1085   PUSH_FIELD_VALUE (cons, "next", null_pointer_node);
1086   PUSH_FIELD_VALUE (cons, "name",
1087                     build_utf8_ref (build_internal_class_name (type)));
1088   PUSH_FIELD_VALUE (cons, "accflags",
1089                     build_int_2 (get_access_flags_from_decl (type_decl), 0));
1090
1091   PUSH_FIELD_VALUE (cons, "superclass", super);
1092   PUSH_FIELD_VALUE (cons, "constants", constant_pool_constructor);
1093   PUSH_FIELD_VALUE (cons, "methods",
1094                     build1 (ADDR_EXPR, method_ptr_type_node, methods_decl));
1095   PUSH_FIELD_VALUE (cons, "method_count",  build_int_2 (method_count, 0));
1096   PUSH_FIELD_VALUE (cons, "dtable_method_count", TYPE_NVIRTUALS (type));
1097   PUSH_FIELD_VALUE (cons, "fields",
1098                     fields_decl == NULL_TREE ? null_pointer_node
1099                     : build1 (ADDR_EXPR, field_ptr_type_node, fields_decl));
1100   PUSH_FIELD_VALUE (cons, "size_in_bytes", size_in_bytes (type));
1101   PUSH_FIELD_VALUE (cons, "field_count", build_int_2 (field_count, 0));
1102   PUSH_FIELD_VALUE (cons, "static_field_count",
1103                     build_int_2 (static_field_count, 0));
1104   /* For now, we let Kaffe fill in the dtable.  */
1105   PUSH_FIELD_VALUE (cons, "dtable",
1106                     dtable_decl == NULL_TREE ? null_pointer_node
1107                     : build1 (ADDR_EXPR, dtable_ptr_type, dtable_decl));
1108   PUSH_FIELD_VALUE (cons, "interfaces", interfaces);
1109   PUSH_FIELD_VALUE (cons, "loader", null_pointer_node);
1110   PUSH_FIELD_VALUE (cons, "interface_count", build_int_2 (interface_len, 0));
1111   PUSH_FIELD_VALUE (cons, "state", integer_zero_node);
1112
1113   PUSH_FIELD_VALUE (cons, "thread", null_pointer_node);
1114
1115   FINISH_RECORD_CONSTRUCTOR (cons);
1116
1117   DECL_INITIAL (decl) = cons;
1118   rest_of_decl_compilation (decl, (char*) 0, 1, 0);
1119 }
1120
1121 /* Return 2 if CLASS is compiled by this compilation job;
1122    return 1 if CLASS can otherwise be assumed to be compiled;
1123    return 0 if we cannot assume that CLASS is compiled.
1124    Returns 1 for primitive and 0 for array types.  */
1125 int
1126 is_compiled_class (class)
1127      tree class;
1128 {
1129   int seen_in_zip;
1130   if (TREE_CODE (class) == POINTER_TYPE)
1131     class = TREE_TYPE (class);
1132   if (TREE_CODE (class) != RECORD_TYPE)  /* Primitive types are static. */
1133     return 1;
1134   if (TYPE_ARRAY_P (class))
1135     return 0;
1136   if (class == current_class)
1137     return 2;
1138
1139   seen_in_zip = (TYPE_LANG_SPECIFIC (class) && TYPE_LANG_SPECIFIC (class)->jcf
1140                  && TYPE_LANG_SPECIFIC (class)->jcf->seen_in_zip);
1141   if (CLASS_FROM_CURRENTLY_COMPILED_SOURCE_P (class) || seen_in_zip)
1142     {
1143       /* The class was seen in the current ZIP file and will be
1144          available as a compiled class in the future but may not have
1145          been loaded already. Load it if necessary. This prevent
1146          build_class_ref () from crashing. */
1147
1148       if (seen_in_zip && !CLASS_LOADED_P (class))
1149         load_class (class, 1);
1150
1151       /* We return 2 for class seen in ZIP and class from files
1152          belonging to the same compilation unit */
1153       return 2;
1154     }
1155
1156   if (flag_assume_compiled)
1157     {
1158       if (!CLASS_LOADED_P (class))
1159         {
1160           if (CLASS_FROM_SOURCE_P (class))
1161             safe_layout_class (class);
1162           else
1163             load_class (class, 1);
1164         }
1165       return 1;
1166     }
1167
1168   return 0;
1169 }
1170
1171 /* Append the mangled name of TYPE onto OBSTACK. */
1172
1173 void
1174 append_gpp_mangled_type (obstack, type)
1175      struct obstack *obstack;
1176      tree type;
1177 {
1178   switch (TREE_CODE (type))
1179     {
1180       char code;
1181     case BOOLEAN_TYPE: code = 'b';  goto primitive;
1182     case CHAR_TYPE:    code = 'w';  goto primitive;
1183     case VOID_TYPE:    code = 'v';  goto primitive;
1184     case INTEGER_TYPE:
1185       /* Get the original type instead of the arguments promoted type.
1186          Avoid symbol name clashes. Should call a function to do that.
1187          FIXME.  */
1188       if (type == promoted_short_type_node)
1189         type = short_type_node;
1190       if (type == promoted_byte_type_node)
1191         type = byte_type_node;
1192       switch (TYPE_PRECISION (type))
1193         {
1194         case  8:       code = 'c';  goto primitive;
1195         case 16:       code = 's';  goto primitive;
1196         case 32:       code = 'i';  goto primitive;
1197         case 64:       code = 'x';  goto primitive;
1198         default:  goto bad_type;
1199         }
1200     primitive:
1201       obstack_1grow (obstack, code);
1202       break;
1203     case REAL_TYPE:
1204       switch (TYPE_PRECISION (type))
1205         {
1206         case 32:       code = 'f';  goto primitive;
1207         case 64:       code = 'd';  goto primitive;
1208         default:  goto bad_type;
1209         }
1210     case POINTER_TYPE:
1211       type = TREE_TYPE (type);
1212       obstack_1grow (obstack, 'P');
1213     case RECORD_TYPE:
1214       if (TYPE_ARRAY_P (type))
1215         {
1216           obstack_grow (obstack, "t6JArray1Z", sizeof("t6JArray1Z")-1);
1217           append_gpp_mangled_type (obstack, TYPE_ARRAY_ELEMENT (type));
1218         }
1219       else
1220         {
1221           char *class_name = IDENTIFIER_POINTER (DECL_NAME (TYPE_NAME (type)));
1222           append_gpp_mangled_classtype (obstack, class_name);
1223         }
1224       break;
1225     bad_type:
1226     default:
1227       fatal ("internal error - trying to mangle unknown type");
1228     }
1229 }
1230
1231 /* Build the mangled name of the `class' field.  */
1232
1233 static tree
1234 mangle_class_field (class)
1235      tree class;
1236 {
1237   tree name;
1238   obstack_grow (&temporary_obstack, "_CL_", 4);
1239   append_gpp_mangled_type (&temporary_obstack, class);
1240   obstack_1grow (&temporary_obstack, '\0');
1241   name = get_identifier (obstack_base (&temporary_obstack));
1242   obstack_free (&temporary_obstack, obstack_base (&temporary_obstack));
1243   return name;
1244 }
1245
1246 /* Build the mangled (assembly-level) name of the static field FIELD. */
1247
1248 tree
1249 mangle_static_field (field)
1250      tree field;
1251 {
1252   tree class = DECL_CONTEXT (field);
1253   tree name = DECL_NAME (field);
1254   int encoded_len;
1255 #if ! defined (NO_DOLLAR_IN_LABEL) || ! defined (NO_DOT_IN_LABEL)
1256   obstack_1grow (&temporary_obstack, '_');
1257 #else
1258   obstack_grow (&temporary_obstack, "__static_", 9);
1259 #endif
1260   append_gpp_mangled_type (&temporary_obstack, class);
1261   encoded_len = unicode_mangling_length (IDENTIFIER_POINTER (name),
1262                                          IDENTIFIER_LENGTH (name));
1263   if (encoded_len > 0)
1264     {
1265       obstack_1grow (&temporary_obstack, 'U');
1266     }
1267 #ifndef NO_DOLLAR_IN_LABEL
1268   obstack_1grow (&temporary_obstack, '$');
1269 #else /* NO_DOLLAR_IN_LABEL */
1270 #ifndef NO_DOT_IN_LABEL
1271   obstack_1grow (&temporary_obstack, '.');
1272 #else /* NO_DOT_IN_LABEL */
1273   obstack_1grow (&temporary_obstack, '_');
1274 #endif  /* NO_DOT_IN_LABEL */
1275 #endif  /* NO_DOLLAR_IN_LABEL */
1276   if (encoded_len > 0)
1277     {
1278       emit_unicode_mangled_name (&temporary_obstack,
1279                                  IDENTIFIER_POINTER (name), 
1280                                  IDENTIFIER_LENGTH (name));
1281     }
1282   else
1283     {
1284       obstack_grow (&temporary_obstack,
1285                     IDENTIFIER_POINTER (name),
1286                     IDENTIFIER_LENGTH (name));
1287     }
1288   obstack_1grow (&temporary_obstack, '\0');
1289   name = get_identifier (obstack_base (&temporary_obstack));
1290   obstack_free (&temporary_obstack, obstack_base (&temporary_obstack));
1291   return name;
1292 }
1293
1294 /* Build a VAR_DECL for the dispatch table (vtable) for class TYPE. */
1295
1296 tree
1297 build_dtable_decl (type)
1298      tree type;
1299 {
1300   tree name;
1301   obstack_grow (&temporary_obstack, "__vt_", 5);
1302   append_gpp_mangled_type (&temporary_obstack, type);
1303   obstack_1grow (&temporary_obstack, '\0');
1304   name = get_identifier (obstack_base (&temporary_obstack));
1305   obstack_free (&temporary_obstack, obstack_base (&temporary_obstack));
1306   return build_decl (VAR_DECL, name, dtable_type);
1307 }
1308
1309 /* Pre-pend the TYPE_FIELDS of THIS_CLASS with a dummy FIELD_DECL for the
1310    fields inherited from SUPER_CLASS. */
1311
1312 void
1313 push_super_field (this_class, super_class)
1314      tree this_class, super_class;
1315 {
1316   tree base_decl;
1317   push_obstacks (&permanent_obstack, &permanent_obstack);
1318   base_decl = build_decl (FIELD_DECL, NULL_TREE, super_class);
1319   pop_obstacks ();
1320   DECL_IGNORED_P (base_decl) = 1;
1321   TREE_CHAIN (base_decl) = TYPE_FIELDS (this_class);
1322   TYPE_FIELDS (this_class) = base_decl;
1323   DECL_SIZE (base_decl) = TYPE_SIZE (super_class);
1324 }
1325
1326 void
1327 layout_class (this_class)
1328      tree this_class;
1329 {
1330   tree super_class = CLASSTYPE_SUPER (this_class);
1331   tree handle_type = CLASS_TO_HANDLE_TYPE (this_class);
1332   tree method_decl, field;
1333   tree dtable_count;
1334   int i;
1335
1336   if (super_class)
1337     {
1338       /* Class seen in source are now complete and can be layed out.
1339          Once layed out, a class seen in the source has its
1340          CLASS_LOADED_P flag set */
1341       if (CLASS_FROM_SOURCE_P (super_class) && !CLASS_LOADED_P (super_class))
1342         safe_layout_class (super_class);
1343       if (! CLASS_LOADED_P (super_class))
1344         load_class (super_class, 1);
1345       if (TREE_CODE (TYPE_SIZE (super_class)) == ERROR_MARK)
1346         {
1347           TYPE_SIZE (this_class) = error_mark_node;
1348           return;
1349         }
1350       dtable_count = TYPE_NVIRTUALS (super_class);
1351
1352       if (TYPE_SIZE (this_class) == NULL_TREE)
1353         push_super_field (this_class, super_class);
1354     }
1355   else
1356     {
1357       dtable_count = integer_zero_node;
1358     }
1359
1360   for (field = TYPE_FIELDS (this_class);
1361        field != NULL_TREE;  field = TREE_CHAIN (field))
1362     {
1363       if (FIELD_STATIC (field))
1364         {
1365           /* Set DECL_ASSEMBLER_NAME to something suitably mangled. */
1366           DECL_ASSEMBLER_NAME (field) = mangle_static_field (field);
1367         }
1368     }
1369
1370   layout_type (this_class);
1371
1372   TYPE_METHODS (handle_type) = nreverse (TYPE_METHODS (handle_type));
1373
1374   for (method_decl = TYPE_METHODS (handle_type), i = 0;
1375        method_decl; method_decl = TREE_CHAIN (method_decl), i++)
1376     {
1377       char *ptr;
1378       char buf[8];
1379       char *asm_name;
1380       tree method_name = DECL_NAME (method_decl);
1381       int method_name_is_wfl = 
1382         (TREE_CODE (method_name) == EXPR_WITH_FILE_LOCATION);
1383       if (method_name_is_wfl)
1384         method_name = java_get_real_method_name (method_decl);
1385 #if 1
1386       /* Remove this once we no longer need old (Kaffe / JDK 1.0)  mangling. */
1387       if (! flag_assume_compiled && METHOD_NATIVE (method_decl))
1388         {
1389           for (ptr = IDENTIFIER_POINTER (DECL_NAME (TYPE_NAME (this_class)));
1390                *ptr; )
1391             {
1392               int ch = *ptr++;
1393               if (ch == '.')
1394                 ch = '_';
1395               obstack_1grow (&temporary_obstack, (char) ch);
1396             }
1397           obstack_1grow (&temporary_obstack, (char) '_');
1398           if (method_name == init_identifier_node)
1399             obstack_grow (&temporary_obstack, "INIT", 4);
1400           else
1401             obstack_grow (&temporary_obstack,
1402                           IDENTIFIER_POINTER (method_name),
1403                           IDENTIFIER_LENGTH (method_name));
1404         }
1405       else
1406 #endif
1407         {
1408           int len;  tree arg, arglist, t;
1409           int method_name_needs_escapes = 0;
1410           if (method_name != init_identifier_node 
1411               && method_name != finit_identifier_node)
1412             {
1413               int encoded_len
1414                 = unicode_mangling_length (IDENTIFIER_POINTER (method_name), 
1415                                            IDENTIFIER_LENGTH (method_name));
1416               if (encoded_len > 0)
1417                 {
1418                   method_name_needs_escapes = 1;
1419                   emit_unicode_mangled_name (&temporary_obstack,
1420                                              IDENTIFIER_POINTER (method_name), 
1421                                              IDENTIFIER_LENGTH (method_name));
1422                 }
1423               else
1424                 {
1425                   obstack_grow (&temporary_obstack,
1426                                 IDENTIFIER_POINTER (method_name),
1427                                 IDENTIFIER_LENGTH (method_name));
1428                 }
1429             }
1430
1431           obstack_grow (&temporary_obstack, "__", 2);
1432           if (method_name == finit_identifier_node)
1433             obstack_grow (&temporary_obstack, "finit", 5);
1434           append_gpp_mangled_type (&temporary_obstack, this_class);
1435           TREE_PUBLIC (method_decl) = 1;
1436
1437           t = TREE_TYPE (method_decl);
1438           arglist = TYPE_ARG_TYPES (t);
1439           if (TREE_CODE (t) == METHOD_TYPE)
1440             arglist = TREE_CHAIN (arglist);
1441           for (arg = arglist; arg != NULL_TREE;  )
1442             {
1443               tree a = arglist;
1444               tree argtype = TREE_VALUE (arg);
1445               int tindex = 1;
1446               if (TREE_CODE (argtype) == POINTER_TYPE)
1447                 {
1448                   /* This is O(N**2).  Do we care?  Cfr gcc/cp/method.c. */
1449                   while (a != arg && argtype != TREE_VALUE (a))
1450                     a = TREE_CHAIN (a), tindex++;
1451                 }
1452               else
1453                 a = arg;
1454               if (a != arg)
1455                 {
1456                   char buf[12];
1457                   int nrepeats = 0;
1458                   do
1459                     {
1460                       arg = TREE_CHAIN (arg); nrepeats++;
1461                     }
1462                   while (arg != NULL_TREE && argtype == TREE_VALUE (arg));
1463                   if (nrepeats > 1)
1464                     {
1465                       obstack_1grow (&temporary_obstack, 'N');
1466                       sprintf (buf, "%d", nrepeats);
1467                       obstack_grow (&temporary_obstack, buf, strlen (buf));
1468                       if (nrepeats > 9)
1469                         obstack_1grow (&temporary_obstack, '_');
1470                     }
1471                   else
1472                     obstack_1grow (&temporary_obstack, 'T');
1473                   sprintf (buf, "%d", tindex);
1474                   obstack_grow (&temporary_obstack, buf, strlen (buf));
1475                   if (tindex > 9)
1476                     obstack_1grow (&temporary_obstack, '_');
1477                 }
1478               else
1479                 {
1480                   append_gpp_mangled_type (&temporary_obstack, argtype);
1481                   arg = TREE_CHAIN (arg);
1482                 }
1483             }
1484           if (method_name_needs_escapes)
1485             obstack_1grow (&temporary_obstack, 'U');
1486         }
1487       obstack_1grow (&temporary_obstack, '\0');
1488       asm_name = obstack_finish (&temporary_obstack);
1489       DECL_ASSEMBLER_NAME (method_decl) = get_identifier (asm_name);
1490       if (! METHOD_ABSTRACT (method_decl))
1491         make_function_rtl (method_decl);
1492       obstack_free (&temporary_obstack, asm_name);
1493
1494       if (method_name == init_identifier_node)
1495         {
1496           char *p = IDENTIFIER_POINTER (DECL_NAME (TYPE_NAME (this_class)));
1497           for (ptr = p; *ptr; )
1498             {
1499               if (*ptr++ == '.')
1500                 p = ptr;
1501             }
1502           if (method_name_is_wfl)
1503             EXPR_WFL_NODE (DECL_NAME (method_decl)) = get_identifier (p);
1504           else
1505             DECL_NAME (method_decl) = get_identifier (p);
1506           DECL_CONSTRUCTOR_P (method_decl) = 1;
1507         }
1508       else if (! METHOD_STATIC (method_decl) && !DECL_ARTIFICIAL (method_decl))
1509         {
1510           tree method_sig = build_java_argument_signature (TREE_TYPE (method_decl));
1511           tree super_method = lookup_argument_method (super_class, method_name,
1512                                                   method_sig);
1513           if (super_method != NULL_TREE)
1514             {
1515               DECL_VINDEX (method_decl) = DECL_VINDEX (super_method);
1516               if (DECL_VINDEX (method_decl) == NULL_TREE)
1517                 error_with_decl (method_decl,
1518                          "non-static method '%s' overrides static method");
1519 #if 0
1520               else if (TREE_TYPE (TREE_TYPE (method_decl))
1521                        != TREE_TYPE (TREE_TYPE (super_method)))
1522                 {
1523                   error_with_decl (method_decl,
1524                                  "Method `%s' redefined with different return type");  
1525                   error_with_decl (super_method,
1526                                  "Overridden decl is here");
1527                 }
1528 #endif
1529             }
1530           else if (! METHOD_FINAL (method_decl)
1531                    && ! CLASS_FINAL (TYPE_NAME (this_class)))
1532             {
1533               DECL_VINDEX (method_decl) = dtable_count;
1534               dtable_count = build_int_2 (1+TREE_INT_CST_LOW (dtable_count), 0);
1535             }
1536         }
1537     }
1538   TYPE_NVIRTUALS (this_class) = dtable_count;
1539
1540 #ifdef JAVA_USE_HANDLES
1541   layout_type (handle_type);
1542 #endif
1543 }
1544
1545 static tree registered_class = NULL_TREE;
1546
1547 void
1548 register_class ()
1549 {
1550   static tree end;
1551   tree node    = TREE_OPERAND (build_class_ref (current_class), 0);
1552   tree current = copy_node (node);
1553
1554   XEXP (DECL_RTL (current), 0) = copy_rtx (XEXP (DECL_RTL(node), 0));
1555   if (!registered_class)
1556     registered_class = current;
1557   else
1558     TREE_CHAIN (end) = current;
1559
1560   end = current;
1561 }
1562
1563 /* Generate a function that gets called at start-up (static contructor) time,
1564    which calls registerClass for all the compiled classes. */
1565
1566 void
1567 emit_register_classes ()
1568 {
1569   tree decl = getdecls ();
1570
1571   extern tree get_file_function_name PROTO((int));
1572   tree init_name = get_file_function_name ('I');
1573   tree init_type = build_function_type (void_type_node, NULL_TREE);
1574   tree init_decl;
1575   tree t;
1576
1577   start_sequence ();
1578   init_decl = build_decl (FUNCTION_DECL, init_name, init_type);
1579   DECL_ASSEMBLER_NAME (init_decl) = init_name;
1580   TREE_STATIC (init_decl) = 1;
1581   current_function_decl = init_decl;
1582   DECL_RESULT (init_decl) = build_decl(RESULT_DECL, NULL_TREE, void_type_node);
1583   /*  DECL_EXTERNAL (init_decl) = 1;*/
1584   TREE_PUBLIC (init_decl) = 1;
1585   pushlevel (0);
1586   make_function_rtl (init_decl);
1587   init_function_start (init_decl, input_filename, 0);
1588   expand_function_start (init_decl, 0);
1589
1590   for ( t = registered_class; t; t = TREE_CHAIN (t))
1591     emit_library_call (registerClass_libfunc, 0, VOIDmode, 1,
1592                        XEXP (DECL_RTL (t), 0), Pmode);
1593
1594   expand_function_end (input_filename, 0, 0);
1595   poplevel (1, 0, 1);
1596   { 
1597     /* Force generation, even with -O3 or deeper. Gross hack. FIXME */
1598     extern int flag_inline_functions;
1599     int saved_flag = flag_inline_functions;
1600     flag_inline_functions = 0;  
1601     rest_of_compilation (init_decl);
1602     flag_inline_functions = saved_flag;
1603   }
1604   current_function_decl = NULL_TREE;
1605   assemble_constructor (IDENTIFIER_POINTER (init_name));
1606 }
1607
1608 void
1609 init_class_processing ()
1610 {
1611   registerClass_libfunc = gen_rtx (SYMBOL_REF, Pmode, "_Jv_RegisterClass");
1612 }