OSDN Git Service

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