OSDN Git Service

Daily bump.
[pf3gnuchains/gcc-fork.git] / gcc / java / jcf-parse.c
1 /* Parser for Java(TM) .class files.
2    Copyright (C) 1996, 1998, 1999, 2000, 2001, 2002
3    Free Software Foundation, Inc.
4
5 This file is part of GNU CC.
6
7 GNU CC is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 2, or (at your option)
10 any later version.
11
12 GNU CC is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15 GNU General Public License for more details.
16
17 You should have received a copy of the GNU General Public License
18 along with GNU CC; see the file COPYING.  If not, write to
19 the Free Software Foundation, 59 Temple Place - Suite 330,
20 Boston, MA 02111-1307, USA.
21
22 Java and all Java-based marks are trademarks or registered trademarks
23 of Sun Microsystems, Inc. in the United States and other countries.
24 The Free Software Foundation is independent of Sun Microsystems, Inc.  */
25
26 /* Written by Per Bothner <bothner@cygnus.com> */
27
28 #include "config.h"
29 #include "system.h"
30 #include "tree.h"
31 #include "obstack.h"
32 #include "flags.h"
33 #include "java-except.h"
34 #include "input.h"
35 #include "java-tree.h"
36 #include "toplev.h"
37 #include "parse.h"
38 #include "ggc.h"
39 #include "debug.h"
40 #include "assert.h"
41
42 #ifdef HAVE_LOCALE_H
43 #include <locale.h>
44 #endif
45
46 #ifdef HAVE_NL_LANGINFO
47 #include <langinfo.h>
48 #endif
49
50 /* A CONSTANT_Utf8 element is converted to an IDENTIFIER_NODE at parse time. */
51 #define JPOOL_UTF(JCF, INDEX) CPOOL_UTF(&(JCF)->cpool, INDEX)
52 #define JPOOL_UTF_LENGTH(JCF, INDEX) IDENTIFIER_LENGTH (JPOOL_UTF (JCF, INDEX))
53 #define JPOOL_UTF_DATA(JCF, INDEX) \
54   ((const unsigned char *) IDENTIFIER_POINTER (JPOOL_UTF (JCF, INDEX)))
55 #define HANDLE_CONSTANT_Utf8(JCF, INDEX, LENGTH) \
56   do { \
57     unsigned char save;  unsigned char *text; \
58     JCF_FILL (JCF, (LENGTH)+1); /* Make sure we read 1 byte beyond string. */ \
59     text = (JCF)->read_ptr; \
60     save = text[LENGTH]; \
61     text[LENGTH] = 0; \
62     (JCF)->cpool.data[INDEX] = (jword) get_identifier (text); \
63     text[LENGTH] = save; \
64     JCF_SKIP (JCF, LENGTH); } while (0)
65
66 #include "jcf.h"
67
68 extern struct obstack *saveable_obstack;
69 extern struct obstack temporary_obstack;
70 extern struct obstack permanent_obstack;
71
72 /* Set to non-zero value in order to emit class initilization code
73    before static field references.  */
74 extern int always_initialize_class_p;
75
76 static tree parse_roots[3] = { NULL_TREE, NULL_TREE, NULL_TREE };
77
78 /* The FIELD_DECL for the current field.  */
79 #define current_field parse_roots[0]
80
81 /* The METHOD_DECL for the current method.  */
82 #define current_method parse_roots[1]
83
84 /* A list of file names.  */
85 #define current_file_list parse_roots[2]
86
87 /* The Java archive that provides main_class;  the main input file. */
88 static struct JCF main_jcf[1];
89
90 static struct ZipFile *localToFile;
91
92 /* Declarations of some functions used here.  */
93 static void handle_innerclass_attribute PARAMS ((int count, JCF *));
94 static tree give_name_to_class PARAMS ((JCF *jcf, int index));
95 static void parse_zip_file_entries PARAMS ((void));
96 static void process_zip_dir PARAMS ((FILE *));
97 static void parse_source_file_1 PARAMS ((tree, FILE *));
98 static void parse_source_file_2 PARAMS ((void));
99 static void parse_source_file_3 PARAMS ((void));
100 static void parse_class_file PARAMS ((void));
101 static void set_source_filename PARAMS ((JCF *, int));
102 static void ggc_mark_jcf PARAMS ((void**));
103 static void jcf_parse PARAMS ((struct JCF*));
104 static void load_inner_classes PARAMS ((tree));
105
106 /* Mark (for garbage collection) all the tree nodes that are
107    referenced from JCF's constant pool table. Do that only if the JCF
108    hasn't been marked finished.  */
109
110 static void
111 ggc_mark_jcf (elt)
112      void **elt;
113 {
114   JCF *jcf = *(JCF**) elt;
115   if (jcf != NULL && !jcf->finished)
116     {
117       CPool *cpool = &jcf->cpool;
118       int size = CPOOL_COUNT(cpool);
119       int index;
120       for (index = 1; index < size;  index++)
121         {
122           int tag = JPOOL_TAG (jcf, index);
123           if ((tag & CONSTANT_ResolvedFlag) || tag == CONSTANT_Utf8)
124             ggc_mark_tree ((tree) cpool->data[index]);
125         }
126     }
127 }
128
129 /* Handle "SourceFile" attribute. */
130
131 static void
132 set_source_filename (jcf, index)
133      JCF *jcf;
134      int index;
135 {
136   tree sfname_id = get_name_constant (jcf, index);
137   const char *sfname = IDENTIFIER_POINTER (sfname_id);
138   if (input_filename != NULL)
139     {
140       int old_len = strlen (input_filename);
141       int new_len = IDENTIFIER_LENGTH (sfname_id);
142       /* Use the current input_filename (derived from the class name)
143          if it has a directory prefix, but otherwise matches sfname. */
144       if (old_len > new_len
145           && strcmp (sfname, input_filename + old_len - new_len) == 0
146           && (input_filename[old_len - new_len - 1] == '/'
147               || input_filename[old_len - new_len - 1] == '\\'))
148         return;
149     }
150   input_filename = sfname;
151   DECL_SOURCE_FILE (TYPE_NAME (current_class)) = sfname;
152   if (current_class == main_class) main_input_filename = input_filename;
153 }
154
155 #define HANDLE_SOURCEFILE(INDEX) set_source_filename (jcf, INDEX)
156
157 #define HANDLE_CLASS_INFO(ACCESS_FLAGS, THIS, SUPER, INTERFACES_COUNT) \
158 { tree super_class = SUPER==0 ? NULL_TREE : get_class_constant (jcf, SUPER); \
159   current_class = give_name_to_class (jcf, THIS); \
160   set_super_info (ACCESS_FLAGS, current_class, super_class, INTERFACES_COUNT);}
161
162 #define HANDLE_CLASS_INTERFACE(INDEX) \
163   add_interface (current_class, get_class_constant (jcf, INDEX))
164
165 #define HANDLE_START_FIELD(ACCESS_FLAGS, NAME, SIGNATURE, ATTRIBUTE_COUNT) \
166 { int sig_index = SIGNATURE; \
167   current_field = add_field (current_class, get_name_constant (jcf, NAME), \
168                              parse_signature (jcf, sig_index), ACCESS_FLAGS); \
169  set_java_signature (TREE_TYPE (current_field), JPOOL_UTF (jcf, sig_index)); \
170  if ((ACCESS_FLAGS) & ACC_FINAL) \
171    MAYBE_CREATE_VAR_LANG_DECL_SPECIFIC (current_field); \
172 }
173
174 #define HANDLE_END_FIELDS() \
175   (current_field = NULL_TREE)
176
177 #define HANDLE_CONSTANTVALUE(INDEX) \
178 { tree constant;  int index = INDEX; \
179   if (! flag_emit_class_files && JPOOL_TAG (jcf, index) == CONSTANT_String) { \
180     tree name = get_name_constant (jcf, JPOOL_USHORT1 (jcf, index)); \
181     constant = build_utf8_ref (name); \
182   } \
183   else \
184     constant = get_constant (jcf, index); \
185   set_constant_value (current_field, constant); }
186
187 #define HANDLE_METHOD(ACCESS_FLAGS, NAME, SIGNATURE, ATTRIBUTE_COUNT) \
188  (current_method = add_method (current_class, ACCESS_FLAGS, \
189                                get_name_constant (jcf, NAME), \
190                                get_name_constant (jcf, SIGNATURE)), \
191   DECL_LOCALVARIABLES_OFFSET (current_method) = 0, \
192   DECL_LINENUMBERS_OFFSET (current_method) = 0)
193
194 #define HANDLE_END_METHODS() \
195 { tree handle_type = CLASS_TO_HANDLE_TYPE (current_class); \
196   if (handle_type != current_class) layout_type (handle_type); \
197   current_method = NULL_TREE; }
198
199 #define HANDLE_CODE_ATTRIBUTE(MAX_STACK, MAX_LOCALS, CODE_LENGTH) \
200 { DECL_MAX_STACK (current_method) = (MAX_STACK); \
201   DECL_MAX_LOCALS (current_method) = (MAX_LOCALS); \
202   DECL_CODE_LENGTH (current_method) = (CODE_LENGTH); \
203   DECL_CODE_OFFSET (current_method) = JCF_TELL (jcf); }
204
205 #define HANDLE_LOCALVARIABLETABLE_ATTRIBUTE(COUNT) \
206 { int n = (COUNT); \
207   DECL_LOCALVARIABLES_OFFSET (current_method) = JCF_TELL (jcf) - 2; \
208   JCF_SKIP (jcf, n * 10); }
209
210 #define HANDLE_LINENUMBERTABLE_ATTRIBUTE(COUNT) \
211 { int n = (COUNT); \
212   DECL_LINENUMBERS_OFFSET (current_method) = JCF_TELL (jcf) - 2; \
213   JCF_SKIP (jcf, n * 4); }
214
215 #define HANDLE_EXCEPTIONS_ATTRIBUTE(COUNT) \
216 { \
217   int n = COUNT; \
218   tree list = DECL_FUNCTION_THROWS (current_method); \
219   while (--n >= 0) \
220     { \
221       tree thrown_class = get_class_constant (jcf, JCF_readu2 (jcf)); \
222       list = tree_cons (NULL_TREE, thrown_class, list); \
223     } \
224   DECL_FUNCTION_THROWS (current_method) = nreverse (list); \
225 }
226
227 /* Link seen inner classes to their outer context and register the
228    inner class to its outer context. They will be later loaded.  */
229 #define HANDLE_INNERCLASSES_ATTRIBUTE(COUNT) \
230   handle_innerclass_attribute (COUNT, jcf)
231
232 #define HANDLE_SYNTHETIC_ATTRIBUTE()                                    \
233 {                                                                       \
234   /* Irrelevant decls should have been nullified by the END macros.     \
235      We only handle the `Synthetic' attribute on method DECLs.          \
236      DECL_ARTIFICIAL on fields is used for something else (See          \
237      PUSH_FIELD in java-tree.h) */                                      \
238   if (current_method)                                                   \
239     DECL_ARTIFICIAL (current_method) = 1;                               \
240 }
241
242 #define HANDLE_GCJCOMPILED_ATTRIBUTE()          \
243 {                                               \
244   if (current_class == object_type_node)        \
245     jcf->right_zip = 1;                         \
246 }
247
248 #include "jcf-reader.c"
249
250 tree
251 parse_signature (jcf, sig_index)
252      JCF *jcf;
253      int sig_index;
254 {
255   if (sig_index <= 0 || sig_index >= JPOOL_SIZE (jcf)
256       || JPOOL_TAG (jcf, sig_index) != CONSTANT_Utf8)
257     abort ();
258   else
259     return parse_signature_string (JPOOL_UTF_DATA (jcf, sig_index),
260                                    JPOOL_UTF_LENGTH (jcf, sig_index));
261 }
262
263 tree
264 get_constant (jcf, index)
265   JCF *jcf;
266   int index;
267 {
268   tree value;
269   int tag;
270   if (index <= 0 || index >= JPOOL_SIZE(jcf))
271     goto bad;
272   tag = JPOOL_TAG (jcf, index);
273   if ((tag & CONSTANT_ResolvedFlag) || tag == CONSTANT_Utf8)
274     return (tree) jcf->cpool.data[index];
275   switch (tag)
276     {
277     case CONSTANT_Integer:
278       {
279         jint num = JPOOL_INT(jcf, index);
280         value = build_int_2 (num, num < 0 ? -1 : 0);
281         TREE_TYPE (value) = int_type_node;
282         break;
283       }
284     case CONSTANT_Long:
285       {
286         unsigned HOST_WIDE_INT num = JPOOL_UINT (jcf, index);
287         HOST_WIDE_INT lo, hi;
288         lshift_double (num, 0, 32, 64, &lo, &hi, 0);
289         num = JPOOL_UINT (jcf, index+1);
290         add_double (lo, hi, num, 0, &lo, &hi);
291         value = build_int_2 (lo, hi);
292         TREE_TYPE (value) = long_type_node;
293         force_fit_type (value, 0);
294         break;
295       }
296 #if TARGET_FLOAT_FORMAT == IEEE_FLOAT_FORMAT
297     case CONSTANT_Float:
298       {
299         jint num = JPOOL_INT(jcf, index);
300         REAL_VALUE_TYPE d;
301         d = REAL_VALUE_FROM_TARGET_SINGLE (num);
302         value = build_real (float_type_node, d);
303         break;
304       }
305     case CONSTANT_Double:
306       {
307         HOST_WIDE_INT num[2];
308         REAL_VALUE_TYPE d;
309         HOST_WIDE_INT lo, hi;
310         num[0] = JPOOL_UINT (jcf, index);
311         lshift_double (num[0], 0, 32, 64, &lo, &hi, 0);
312         num[0] = JPOOL_UINT (jcf, index+1);
313         add_double (lo, hi, num[0], 0, &lo, &hi);
314
315         /* Since ereal_from_double expects an array of HOST_WIDE_INT
316            in the target's format, we swap the elements for big endian
317            targets, unless HOST_WIDE_INT is sufficiently large to
318            contain a target double, in which case the 2nd element
319            is ignored.
320
321            FIXME: Is this always right for cross targets? */
322         if (FLOAT_WORDS_BIG_ENDIAN && sizeof(num[0]) < 8)
323           {
324             num[0] = hi;
325             num[1] = lo;
326           }
327         else
328           {
329             num[0] = lo;
330             num[1] = hi;
331           }
332         d = REAL_VALUE_FROM_TARGET_DOUBLE (num);
333         value = build_real (double_type_node, d);
334         break;
335       }
336 #endif /* TARGET_FLOAT_FORMAT == IEEE_FLOAT_FORMAT */
337     case CONSTANT_String:
338       {
339         tree name = get_name_constant (jcf, JPOOL_USHORT1 (jcf, index));
340         const char *utf8_ptr = IDENTIFIER_POINTER (name);
341         int utf8_len = IDENTIFIER_LENGTH (name);
342         const unsigned char *utf8;
343         int i;
344
345         /* Check for a malformed Utf8 string.  */
346         utf8 = (const unsigned char *) utf8_ptr;
347         i = utf8_len;
348         while (i > 0)
349           {
350             int char_len = UT8_CHAR_LENGTH (*utf8);
351             if (char_len < 0 || char_len > 3 || char_len > i)
352               fatal_error ("bad string constant");
353
354             utf8 += char_len;
355             i -= char_len;
356           }
357
358         /* Allocate a new string value.  */
359         value = build_string (utf8_len, utf8_ptr);
360         TREE_TYPE (value) = build_pointer_type (string_type_node);
361       }
362       break;
363     default:
364       goto bad;
365     }
366   JPOOL_TAG (jcf, index) = tag | CONSTANT_ResolvedFlag;
367   jcf->cpool.data [index] = (jword) value;
368   return value;
369  bad:
370   internal_error ("bad value constant type %d, index %d", 
371                   JPOOL_TAG (jcf, index), index);
372 }
373
374 tree
375 get_name_constant (jcf, index)
376   JCF *jcf;
377   int index;
378 {
379   tree name = get_constant (jcf, index);
380
381   if (TREE_CODE (name) != IDENTIFIER_NODE)
382     abort ();
383
384   return name;
385 }
386
387 /* Handle reading innerclass attributes. If a non zero entry (denoting
388    a non anonymous entry) is found, We augment the inner class list of
389    the outer context with the newly resolved innerclass.  */
390
391 static void
392 handle_innerclass_attribute (count, jcf)
393      int count;
394      JCF *jcf;
395 {
396   int c = (count);
397   while (c--)
398     {
399       /* Read inner_class_info_index. This may be 0 */
400       int icii = JCF_readu2 (jcf);
401       /* Read outer_class_info_index. If the innerclasses attribute
402          entry isn't a member (like an inner class) the value is 0. */
403       int ocii = JCF_readu2 (jcf);
404       /* Read inner_name_index. If the class we're dealing with is
405          an annonymous class, it must be 0. */
406       int ini = JCF_readu2 (jcf);
407       /* Read the access flag. */
408       int acc = JCF_readu2 (jcf);
409       /* If icii is 0, don't try to read the class. */
410       if (icii >= 0)
411         {
412           tree class = get_class_constant (jcf, icii);
413           tree decl = TYPE_NAME (class);
414           /* Skip reading further if ocii is null */
415           if (DECL_P (decl) && !CLASS_COMPLETE_P (decl) && ocii)
416             {
417               tree outer = TYPE_NAME (get_class_constant (jcf, ocii));
418               tree alias = (ini ? get_name_constant (jcf, ini) : NULL_TREE);
419               set_class_decl_access_flags (acc, decl);
420               DECL_CONTEXT (decl) = outer;
421               DECL_INNER_CLASS_LIST (outer) =
422                 tree_cons (decl, alias, DECL_INNER_CLASS_LIST (outer));
423               CLASS_COMPLETE_P (decl) = 1;
424             }
425         }
426     }
427 }
428
429 static tree
430 give_name_to_class (jcf, i)
431      JCF *jcf;
432      int i;
433 {
434   if (i <= 0 || i >= JPOOL_SIZE (jcf)
435       || JPOOL_TAG (jcf, i) != CONSTANT_Class)
436     abort ();
437   else
438     {
439       tree this_class;
440       int j = JPOOL_USHORT1 (jcf, i);
441       /* verify_constant_pool confirmed that j is a CONSTANT_Utf8. */
442       tree class_name = unmangle_classname (JPOOL_UTF_DATA (jcf, j),
443                                             JPOOL_UTF_LENGTH (jcf, j));
444       this_class = lookup_class (class_name);
445       input_filename = DECL_SOURCE_FILE (TYPE_NAME (this_class));
446       lineno = 0;
447       if (main_input_filename == NULL && jcf == main_jcf)
448         main_input_filename = input_filename;
449
450       jcf->cpool.data[i] = (jword) this_class;
451       JPOOL_TAG (jcf, i) = CONSTANT_ResolvedClass;
452       return this_class;
453     }
454 }
455
456 /* Get the class of the CONSTANT_Class whose constant pool index is I. */
457
458 tree
459 get_class_constant (JCF *jcf , int i)
460 {
461   tree type;
462   if (i <= 0 || i >= JPOOL_SIZE (jcf)
463       || (JPOOL_TAG (jcf, i) & ~CONSTANT_ResolvedFlag) != CONSTANT_Class)
464     abort ();
465
466   if (JPOOL_TAG (jcf, i) != CONSTANT_ResolvedClass)
467     {
468       int name_index = JPOOL_USHORT1 (jcf, i);
469       /* verify_constant_pool confirmed that name_index is a CONSTANT_Utf8. */
470       const char *name = JPOOL_UTF_DATA (jcf, name_index);
471       int nlength = JPOOL_UTF_LENGTH (jcf, name_index);
472
473       if (name[0] == '[')  /* Handle array "classes". */
474           type = TREE_TYPE (parse_signature_string (name, nlength));
475       else
476         { 
477           tree cname = unmangle_classname (name, nlength);
478           type = lookup_class (cname);
479         }
480       jcf->cpool.data[i] = (jword) type;
481       JPOOL_TAG (jcf, i) = CONSTANT_ResolvedClass;
482     }
483   else
484     type = (tree) jcf->cpool.data[i];
485   return type;
486 }
487
488 /* Read a class with the fully qualified-name NAME.
489    Return 1 iff we read the requested file.
490    (It is still possible we failed if the file did not
491    define the class it is supposed to.) */
492
493 int
494 read_class (name)
495      tree name;
496 {
497   JCF this_jcf, *jcf;
498   tree icv, class = NULL_TREE;
499   tree save_current_class = current_class;
500   const char *save_input_filename = input_filename;
501   JCF *save_current_jcf = current_jcf;
502
503   if ((icv = IDENTIFIER_CLASS_VALUE (name)) != NULL_TREE)
504     {
505       class = TREE_TYPE (icv);
506       jcf = TYPE_JCF (class);
507     }
508   else
509     jcf = NULL;
510
511   if (jcf == NULL)
512     {
513       this_jcf.zipd = NULL;
514       jcf = &this_jcf;
515       if (find_class (IDENTIFIER_POINTER (name), IDENTIFIER_LENGTH (name),
516                       &this_jcf, 1) == 0)
517         return 0;
518     }
519
520   current_jcf = jcf;
521
522   if (current_jcf->java_source)
523     {
524       const char *filename = current_jcf->filename;
525       tree file;
526       FILE *finput;
527       int generate;
528
529       java_parser_context_save_global ();
530       java_push_parser_context ();
531       BUILD_FILENAME_IDENTIFIER_NODE (file, filename);
532       generate = IS_A_COMMAND_LINE_FILENAME_P (file);
533       if (wfl_operator == NULL_TREE)
534         wfl_operator = build_expr_wfl (NULL_TREE, NULL, 0, 0);
535       EXPR_WFL_FILENAME_NODE (wfl_operator) = file;
536       input_filename = ggc_strdup (filename);
537       current_class = NULL_TREE;
538       current_function_decl = NULL_TREE;
539       if (!HAS_BEEN_ALREADY_PARSED_P (file))
540         {
541           if (!(finput = fopen (input_filename, "r")))
542             fatal_io_error ("can't reopen %s", input_filename);
543           parse_source_file_1 (file, finput);
544           parse_source_file_2 ();
545           parse_source_file_3 ();
546           if (fclose (finput))
547             fatal_io_error ("can't close %s", input_filename);
548         }
549       JCF_FINISH (current_jcf);
550       java_pop_parser_context (generate);
551       java_parser_context_restore_global ();
552     }
553   else
554     {
555       if (class == NULL_TREE || ! CLASS_PARSED_P (class))
556         {
557           java_parser_context_save_global ();
558           java_push_parser_context ();
559           current_class = class;
560           input_filename = current_jcf->filename;
561           if (JCF_SEEN_IN_ZIP (current_jcf))
562             read_zip_member(current_jcf,
563                             current_jcf->zipd, current_jcf->zipd->zipf);
564           jcf_parse (current_jcf);
565           class = current_class;
566           java_pop_parser_context (0);
567           java_parser_context_restore_global ();
568         }
569       layout_class (class);
570       load_inner_classes (class);
571     }
572
573   current_class = save_current_class;
574   input_filename = save_input_filename;
575   current_jcf = save_current_jcf;
576   return 1;
577 }
578
579 /* Load CLASS_OR_NAME. CLASS_OR_NAME can be a mere identifier if
580    called from the parser, otherwise it's a RECORD_TYPE node. If
581    VERBOSE is 1, print error message on failure to load a class. */
582
583 /* Replace calls to load_class by having callers call read_class directly
584    - and then perhaps rename read_class to load_class.  FIXME */
585
586 void
587 load_class (class_or_name, verbose)
588      tree class_or_name;
589      int verbose;
590 {
591   tree name, saved;
592   int class_loaded;
593
594   /* class_or_name can be the name of the class we want to load */
595   if (TREE_CODE (class_or_name) == IDENTIFIER_NODE)
596     name = class_or_name;
597   /* In some cases, it's a dependency that we process earlier that
598      we though */
599   else if (TREE_CODE (class_or_name) == TREE_LIST)
600     name = TYPE_NAME (TREE_PURPOSE (class_or_name));
601   /* Or it's a type in the making */
602   else
603     name = DECL_NAME (TYPE_NAME (class_or_name));
604
605   saved = name;
606   while (1)
607     {
608       char *separator;
609
610       if ((class_loaded = read_class (name)))
611         break;
612
613       /* We failed loading name. Now consider that we might be looking
614          for a inner class. */
615       if ((separator = strrchr (IDENTIFIER_POINTER (name), '$'))
616           || (separator = strrchr (IDENTIFIER_POINTER (name), '.')))
617         {
618           int c = *separator;
619           *separator = '\0';
620           name = get_identifier (IDENTIFIER_POINTER (name));
621           *separator = c;
622         }
623       /* Otherwise, we failed, we bail. */
624       else
625         break;
626     }
627
628   if (!class_loaded && verbose)
629     error ("cannot find file for class %s", IDENTIFIER_POINTER (saved));
630 }
631
632 /* Parse the .class file JCF. */
633
634 void
635 jcf_parse (jcf)
636      JCF* jcf;
637 {
638   int i, code;
639
640   if (jcf_parse_preamble (jcf) != 0)
641     fatal_error ("not a valid Java .class file");
642   code = jcf_parse_constant_pool (jcf);
643   if (code != 0)
644     fatal_error ("error while parsing constant pool");
645   code = verify_constant_pool (jcf);
646   if (code > 0)
647     fatal_error ("error in constant pool entry #%d\n", code);
648
649   jcf_parse_class (jcf);
650   if (main_class == NULL_TREE)
651     main_class = current_class;
652   if (! quiet_flag && TYPE_NAME (current_class))
653     fprintf (stderr, " %s %s",
654              (jcf->access_flags & ACC_INTERFACE) ? "interface" : "class", 
655              IDENTIFIER_POINTER (DECL_NAME (TYPE_NAME (current_class))));
656   if (CLASS_PARSED_P (current_class))
657     {
658       /* FIXME - where was first time */
659       fatal_error ("reading class %s for the second time from %s",
660                    IDENTIFIER_POINTER (DECL_NAME (TYPE_NAME (current_class))),
661                    jcf->filename);
662     }
663   CLASS_PARSED_P (current_class) = 1;
664
665   for (i = 1; i < JPOOL_SIZE(jcf); i++)
666     {
667       switch (JPOOL_TAG (jcf, i))
668         {
669         case CONSTANT_Class:
670           get_class_constant (jcf, i);
671           break;
672         }
673     }
674   
675   code = jcf_parse_fields (jcf);
676   if (code != 0)
677     fatal_error ("error while parsing fields");
678   code = jcf_parse_methods (jcf);
679   if (code != 0)
680     fatal_error ("error while parsing methods");
681   code = jcf_parse_final_attributes (jcf);
682   if (code != 0)
683     fatal_error ("error while parsing final attributes");
684
685   /* The fields of class_type_node are already in correct order. */
686   if (current_class != class_type_node && current_class != object_type_node)
687     TYPE_FIELDS (current_class) = nreverse (TYPE_FIELDS (current_class));
688
689   if (current_class == object_type_node)
690     {
691       layout_class_methods (object_type_node);
692       /* If we don't have the right archive, emit a verbose warning.
693          If we're generating bytecode, emit the warning only if
694          -fforce-classes-archive-check was specified. */
695       if (!jcf->right_zip
696           && (!flag_emit_class_files || flag_force_classes_archive_check))
697         fatal_error ("the `java.lang.Object' that was found in `%s' didn't have the special zero-length `gnu.gcj.gcj-compiled' attribute.  This generally means that your classpath is incorrectly set.  Use `info gcj \"Input Options\"' to see the info page describing how to set the classpath", jcf->filename);
698     }
699   else
700     all_class_list = tree_cons (NULL_TREE,
701                                 TYPE_NAME (current_class), all_class_list );
702 }
703
704 /* If we came across inner classes, load them now. */
705 static void
706 load_inner_classes (cur_class)
707      tree cur_class;
708 {
709   tree current;
710   for (current = DECL_INNER_CLASS_LIST (TYPE_NAME (cur_class)); current;
711        current = TREE_CHAIN (current))
712     {
713       tree name = DECL_NAME (TREE_PURPOSE (current));
714       tree decl = IDENTIFIER_GLOBAL_VALUE (name);
715       if (decl && ! CLASS_LOADED_P (TREE_TYPE (decl))
716           && !CLASS_BEING_LAIDOUT (TREE_TYPE (decl)))
717         load_class (name, 1);
718     }
719 }
720
721 void
722 init_outgoing_cpool ()
723 {
724   current_constant_pool_data_ref = NULL_TREE;
725   outgoing_cpool = (struct CPool *)xmalloc (sizeof (struct CPool));
726   memset (outgoing_cpool, 0, sizeof (struct CPool));
727 }
728
729 static void
730 parse_class_file ()
731 {
732   tree method, field;
733   const char *save_input_filename = input_filename;
734   int save_lineno = lineno;
735
736   java_layout_seen_class_methods ();
737
738   input_filename = DECL_SOURCE_FILE (TYPE_NAME (current_class));
739   lineno = 0;
740   (*debug_hooks->start_source_file) (lineno, input_filename);
741   init_outgoing_cpool ();
742
743   /* Currently we always have to emit calls to _Jv_InitClass when
744      compiling from class files.  */
745   always_initialize_class_p = 1;
746
747   for (field = TYPE_FIELDS (CLASS_TO_HANDLE_TYPE (current_class));
748        field != NULL_TREE; field = TREE_CHAIN (field))
749     if (FIELD_STATIC (field))
750       DECL_EXTERNAL (field) = 0;
751
752   for (method = TYPE_METHODS (CLASS_TO_HANDLE_TYPE (current_class));
753        method != NULL_TREE; method = TREE_CHAIN (method))
754     {
755       JCF *jcf = current_jcf;
756
757       if (METHOD_ABSTRACT (method))
758         continue;
759
760       if (METHOD_NATIVE (method))
761         {
762           tree arg;
763           int  decl_max_locals;
764
765           if (! flag_jni)
766             continue;
767           /* We need to compute the DECL_MAX_LOCALS. We need to take
768              the wide types into account too. */
769           for (arg = TYPE_ARG_TYPES (TREE_TYPE (method)), decl_max_locals = 0; 
770                arg != end_params_node;
771                arg = TREE_CHAIN (arg), decl_max_locals += 1)
772             {
773               if (TREE_VALUE (arg) && TYPE_IS_WIDE (TREE_VALUE (arg)))
774                 decl_max_locals += 1;
775             }
776           DECL_MAX_LOCALS (method) = decl_max_locals;
777           start_java_method (method);
778           give_name_to_locals (jcf);
779           expand_expr_stmt (build_jni_stub (method));
780           end_java_method ();
781           continue;
782         }
783
784       if (DECL_CODE_OFFSET (method) == 0)
785         {
786           current_function_decl = method;
787           error ("missing Code attribute");
788           continue;
789         }
790
791       lineno = 0;
792       if (DECL_LINENUMBERS_OFFSET (method))
793         {
794           register int i;
795           register unsigned char *ptr;
796           JCF_SEEK (jcf, DECL_LINENUMBERS_OFFSET (method));
797           linenumber_count = i = JCF_readu2 (jcf);
798           linenumber_table = ptr = jcf->read_ptr;
799
800           for (ptr += 2; --i >= 0; ptr += 4)
801             {
802               int line = GET_u2 (ptr);
803               /* Set initial lineno lineno to smallest linenumber.
804                * Needs to be set before init_function_start. */
805               if (lineno == 0 || line < lineno)
806                 lineno = line;
807             }  
808         }
809       else
810         {
811           linenumber_table = NULL;
812           linenumber_count = 0;
813         }
814
815       start_java_method (method);
816
817       note_instructions (jcf, method);
818
819       give_name_to_locals (jcf);
820
821       /* Actually generate code. */
822       expand_byte_code (jcf, method);
823
824       end_java_method ();
825     }
826
827   if (flag_emit_class_files)
828     write_classfile (current_class);
829
830   finish_class ();
831
832   (*debug_hooks->end_source_file) (save_lineno);
833   input_filename = save_input_filename;
834   lineno = save_lineno;
835 }
836
837 /* Parse a source file, as pointed by the current value of INPUT_FILENAME. */
838
839 static void
840 parse_source_file_1 (file, finput)
841      tree file;
842      FILE *finput;
843 {
844   int save_error_count = java_error_count;
845   /* Mark the file as parsed */
846   HAS_BEEN_ALREADY_PARSED_P (file) = 1;
847
848   jcf_dependency_add_file (input_filename, 0);
849
850   lang_init_source (1);             /* Error msgs have no method prototypes */
851
852   /* There's no point in trying to find the current encoding unless we
853      are going to do something intelligent with it -- hence the test
854      for iconv.  */
855 #if defined (HAVE_LOCALE_H) && defined (HAVE_ICONV) && defined (HAVE_NL_LANGINFO)
856   setlocale (LC_CTYPE, "");
857   if (current_encoding == NULL)
858     current_encoding = nl_langinfo (CODESET);
859 #endif 
860   if (current_encoding == NULL || *current_encoding == '\0')
861     current_encoding = DEFAULT_ENCODING;
862
863   /* Initialize the parser */
864   java_init_lex (finput, current_encoding);
865   java_parse_abort_on_error ();
866
867   java_parse ();                    /* Parse and build partial tree nodes. */
868   java_parse_abort_on_error ();
869 }
870
871 /* Process a parsed source file, resolving names etc. */
872
873 static void
874 parse_source_file_2 ()
875 {
876   int save_error_count = java_error_count;
877   java_complete_class ();           /* Parse unsatisfied class decl. */
878   java_parse_abort_on_error ();
879 }
880
881 static void
882 parse_source_file_3 ()
883 {
884   int save_error_count = java_error_count;
885   java_check_circular_reference (); /* Check on circular references */
886   java_parse_abort_on_error ();
887   java_fix_constructors ();         /* Fix the constructors */
888   java_parse_abort_on_error ();
889   java_reorder_fields ();           /* Reorder the fields */
890 }
891
892 void
893 add_predefined_file (name)
894      tree name;
895 {
896   predef_filenames = tree_cons (NULL_TREE, name, predef_filenames);
897 }
898
899 int
900 predefined_filename_p (node)
901      tree node;
902 {
903   tree iter;
904
905   for (iter = predef_filenames; iter != NULL_TREE; iter = TREE_CHAIN (iter))
906     {
907       if (TREE_VALUE (iter) == node)
908         return 1;
909     }
910   return 0;
911 }
912
913 void
914 java_parse_file (set_yydebug)
915      int set_yydebug ATTRIBUTE_UNUSED;
916 {
917   int filename_count = 0;
918   char *list, *next;
919   tree node;
920   FILE *finput = NULL;
921
922   if (flag_filelist_file)
923     {
924       int avail = 2000;
925       finput = fopen (input_filename, "r");
926       if (finput == NULL)
927         fatal_io_error ("can't open %s", input_filename);
928       list = xmalloc(avail);
929       next = list;
930       for (;;)
931         {
932           int count;
933           if (avail < 500)
934             {
935               count = next - list;
936               avail = 2 * (count + avail);
937               list = xrealloc (list, avail);
938               next = list + count;
939               avail = avail - count;
940             }
941           /* Subtract to to guarantee space for final '\0'. */
942           count = fread (next, 1, avail - 1, finput);
943           if (count == 0)
944             {
945               if (! feof (finput))
946                 fatal_io_error ("error closing %s", input_filename);
947               *next = '\0';
948               break;
949             }
950           avail -= count;
951           next += count;
952         }
953       fclose (finput);
954       finput = NULL;
955     }
956   else
957     list = xstrdup (input_filename);
958
959   do 
960     {
961       for (next = list; ; )
962         {
963           char ch = *next;
964           if (ch == '\n' || ch == '\r' || ch == '\t' || ch == ' '
965               || ch == '&' /* FIXME */)
966             {
967               if (next == list)
968                 {
969                   next++;
970                   list = next;
971                   continue;
972                 }
973               else
974                 {
975                   *next++ = '\0';
976                   break;
977                 }
978             }
979           if (ch == '\0')
980             {
981               next = NULL;
982               break;
983             }
984           next++;
985         }
986
987       if (list[0]) 
988         {
989           char *value;
990           tree id;
991           int twice = 0;
992
993           int len = strlen (list);
994
995           obstack_grow0 (&temporary_obstack, list, len);
996           value = obstack_finish (&temporary_obstack);
997
998           filename_count++;
999
1000           /* Exclude file that we see twice on the command line. For
1001              all files except {Class,Error,Object,RuntimeException,String,
1002              Throwable}.java we can rely on maybe_get_identifier. For
1003              these files, we need to do a linear search of
1004              current_file_list. This search happens only for these
1005              files, presumably only when we're recompiling libgcj. */
1006              
1007           if ((id = maybe_get_identifier (value)))
1008             {
1009               if (predefined_filename_p (id))
1010                 {
1011                   tree c;
1012                   for (c = current_file_list; c; c = TREE_CHAIN (c))
1013                     if (TREE_VALUE (c) == id)
1014                       twice = 1;
1015                 }
1016               else
1017                 twice = 1;
1018             }
1019
1020           if (twice)
1021             {
1022               const char *saved_input_filename = input_filename;
1023               input_filename = value;
1024               warning ("source file seen twice on command line and will be compiled only once");
1025               input_filename = saved_input_filename;
1026             }
1027           else
1028             {
1029               BUILD_FILENAME_IDENTIFIER_NODE (node, value);
1030               IS_A_COMMAND_LINE_FILENAME_P (node) = 1;
1031               current_file_list = tree_cons (NULL_TREE, node, 
1032                                              current_file_list);
1033             }
1034         }
1035       list = next;
1036     }
1037   while (next);
1038
1039   if (filename_count == 0)
1040     warning ("no input file specified");
1041
1042   if (resource_name)
1043     {
1044       const char *resource_filename;
1045       
1046       /* Only one resource file may be compiled at a time.  */
1047       assert (TREE_CHAIN (current_file_list) == NULL);
1048
1049       resource_filename = IDENTIFIER_POINTER (TREE_VALUE (current_file_list));
1050       compile_resource_file (resource_name, resource_filename);
1051
1052       return;
1053     }
1054
1055   current_jcf = main_jcf;
1056   current_file_list = nreverse (current_file_list);
1057   for (node = current_file_list; node; node = TREE_CHAIN (node))
1058     {
1059       unsigned char magic_string[4];
1060       uint32 magic = 0;
1061       tree name = TREE_VALUE (node);
1062
1063       /* Skip already parsed files */
1064       if (HAS_BEEN_ALREADY_PARSED_P (name))
1065         continue;
1066       
1067       /* Close previous descriptor, if any */
1068       if (finput && fclose (finput))
1069         fatal_io_error ("can't close input file %s", main_input_filename);
1070       
1071       finput = fopen (IDENTIFIER_POINTER (name), "rb");
1072       if (finput == NULL)
1073         fatal_io_error ("can't open %s", IDENTIFIER_POINTER (name));
1074       
1075 #ifdef IO_BUFFER_SIZE
1076       setvbuf (finput, (char *) xmalloc (IO_BUFFER_SIZE),
1077                _IOFBF, IO_BUFFER_SIZE);
1078 #endif
1079       input_filename = IDENTIFIER_POINTER (name);
1080
1081       /* Figure what kind of file we're dealing with */
1082       if (fread (magic_string, 1, 4, finput) == 4)
1083         {
1084           fseek (finput, 0L, SEEK_SET);
1085           magic = GET_u4 (magic_string);
1086         }
1087       if (magic == 0xcafebabe)
1088         {
1089           CLASS_FILE_P (node) = 1;
1090           current_jcf = ALLOC (sizeof (JCF));
1091           JCF_ZERO (current_jcf);
1092           current_jcf->read_state = finput;
1093           current_jcf->filbuf = jcf_filbuf_from_stdio;
1094           jcf_parse (current_jcf);
1095           TYPE_JCF (current_class) = current_jcf;
1096           CLASS_FROM_CURRENTLY_COMPILED_P (current_class) = 1;
1097           TREE_PURPOSE (node) = current_class;
1098         }
1099       else if (magic == (JCF_u4)ZIPMAGIC)
1100         {
1101           ZIP_FILE_P (node) = 1;
1102           JCF_ZERO (main_jcf);
1103           main_jcf->read_state = finput;
1104           main_jcf->filbuf = jcf_filbuf_from_stdio;
1105           if (open_in_zip (main_jcf, input_filename, NULL, 0) <  0)
1106             fatal_error ("bad zip/jar file %s", IDENTIFIER_POINTER (name));
1107           localToFile = SeenZipFiles;
1108           /* Register all the class defined there.  */
1109           process_zip_dir (main_jcf->read_state);
1110           parse_zip_file_entries ();
1111           /*
1112           for (each entry)
1113             CLASS_FROM_CURRENTLY_COMPILED_P (current_class) = 1;
1114           */
1115         }
1116       else
1117         {
1118           JAVA_FILE_P (node) = 1;
1119           java_push_parser_context ();
1120           java_parser_context_save_global ();
1121           parse_source_file_1 (name, finput);
1122           java_parser_context_restore_global ();
1123           java_pop_parser_context (1);
1124         }
1125     }
1126
1127   for (ctxp = ctxp_for_generation;  ctxp;  ctxp = ctxp->next)
1128     {
1129       input_filename = ctxp->filename;
1130       parse_source_file_2 ();
1131     }
1132
1133   for (ctxp = ctxp_for_generation; ctxp; ctxp = ctxp->next)
1134     {
1135       input_filename = ctxp->filename;
1136       parse_source_file_3 ();
1137     }
1138
1139   for (node = current_file_list; node; node = TREE_CHAIN (node))
1140     {
1141       input_filename = IDENTIFIER_POINTER (TREE_VALUE (node));
1142       if (CLASS_FILE_P (node))
1143         {
1144           current_class = TREE_PURPOSE (node);
1145           current_jcf = TYPE_JCF (current_class);
1146           layout_class (current_class);
1147           load_inner_classes (current_class);
1148           parse_class_file ();
1149           JCF_FINISH (current_jcf);
1150         }
1151     }
1152   input_filename = main_input_filename;
1153
1154   java_expand_classes ();
1155   if (!java_report_errors () && !flag_syntax_only)
1156     {
1157       emit_register_classes ();
1158       if (flag_indirect_dispatch)
1159         emit_offset_symbol_table ();
1160     }
1161 }
1162
1163 /* Process all class entries found in the zip file.  */
1164 static void
1165 parse_zip_file_entries (void)
1166 {
1167   struct ZipDirectory *zdir;
1168   int i;
1169
1170   for (i = 0, zdir = (ZipDirectory *)localToFile->central_directory;
1171        i < localToFile->count; i++, zdir = ZIPDIR_NEXT (zdir))
1172     {
1173       tree class;
1174       
1175       /* We don't need to consider those files.  */
1176       if (!zdir->size || !zdir->filename_offset)
1177         continue;
1178
1179       class = lookup_class (get_identifier (ZIPDIR_FILENAME (zdir)));
1180       current_jcf = TYPE_JCF (class);
1181       current_class = class;
1182
1183       if ( !CLASS_LOADED_P (class))
1184         {
1185           if (! CLASS_PARSED_P (class))
1186             {
1187               read_zip_member(current_jcf, zdir, localToFile);
1188               jcf_parse (current_jcf);
1189             }
1190           layout_class (current_class);
1191           load_inner_classes (current_class);
1192         }
1193
1194       if (TYPE_SIZE (current_class) != error_mark_node)
1195         {
1196           input_filename = current_jcf->filename;
1197           parse_class_file ();
1198           FREE (current_jcf->buffer); /* No longer necessary */
1199           /* Note: there is a way to free this buffer right after a
1200              class seen in a zip file has been parsed. The idea is the
1201              set its jcf in such a way that buffer will be reallocated
1202              the time the code for the class will be generated. FIXME. */
1203         }
1204     }
1205 }
1206
1207 /* Read all the entries of the zip file, creates a class and a JCF. Sets the
1208    jcf up for further processing and link it to the created class.  */
1209
1210 static void
1211 process_zip_dir (FILE *finput)
1212 {
1213   int i;
1214   ZipDirectory *zdir;
1215
1216   for (i = 0, zdir = (ZipDirectory *)localToFile->central_directory;
1217        i < localToFile->count; i++, zdir = ZIPDIR_NEXT (zdir))
1218     {
1219       char *class_name, *file_name, *class_name_in_zip_dir;
1220       tree class;
1221       JCF  *jcf;
1222       int   j;
1223
1224       class_name_in_zip_dir = ZIPDIR_FILENAME (zdir);
1225
1226       /* We choose to not to process entries with a zero size or entries
1227          not bearing the .class extension.  */
1228       if (!zdir->size || !zdir->filename_offset ||
1229           strncmp (&class_name_in_zip_dir[zdir->filename_length-6], 
1230                    ".class", 6))
1231         {
1232           /* So it will be skipped in parse_zip_file_entries  */
1233           zdir->size = 0;  
1234           continue;
1235         }
1236
1237       class_name = ALLOC (zdir->filename_length+1-6);
1238       file_name  = ALLOC (zdir->filename_length+1);
1239       jcf = ALLOC (sizeof (JCF));
1240       JCF_ZERO (jcf);
1241
1242       strncpy (class_name, class_name_in_zip_dir, zdir->filename_length-6);
1243       class_name [zdir->filename_length-6] = '\0';
1244       strncpy (file_name, class_name_in_zip_dir, zdir->filename_length);
1245       file_name [zdir->filename_length] = '\0';
1246
1247       for (j=0; class_name[j]; j++)
1248         class_name [j] = (class_name [j] == '/' ? '.' : class_name [j]);
1249
1250       /* Yes, we write back the true class name into the zip directory.  */
1251       strcpy (class_name_in_zip_dir, class_name);
1252       zdir->filename_length = j;
1253       class = lookup_class (get_identifier (class_name));
1254
1255       jcf->read_state  = finput;
1256       jcf->filbuf      = jcf_filbuf_from_stdio;
1257       jcf->java_source = 0;
1258       jcf->classname   = class_name;
1259       jcf->filename    = file_name;
1260       jcf->zipd        = zdir;
1261
1262       TYPE_JCF (class) = jcf;
1263     }
1264 }
1265
1266 /* Initialization.  */
1267
1268 void
1269 init_jcf_parse ()
1270 {
1271   /* Register roots with the garbage collector.  */
1272   ggc_add_tree_root (parse_roots, ARRAY_SIZE (parse_roots));
1273
1274   ggc_add_root (&current_jcf, 1, sizeof (JCF), (void (*)(void *))ggc_mark_jcf);
1275
1276   init_src_parse ();
1277 }