OSDN Git Service

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