OSDN Git Service

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