OSDN Git Service

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