OSDN Git Service

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