OSDN Git Service

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