OSDN Git Service

PR middle-end/24912
[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, 51 Franklin Street, Fifth Floor,
20 Boston, MA 02110-1301, 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 package_name = NULL_TREE, tmp;
448       tree this_class;
449       int j = JPOOL_USHORT1 (jcf, i);
450       /* verify_constant_pool confirmed that j is a CONSTANT_Utf8. */
451       tree class_name = unmangle_classname ((const char *) JPOOL_UTF_DATA (jcf, j),
452                                             JPOOL_UTF_LENGTH (jcf, j));
453       this_class = lookup_class (class_name);
454 #ifdef USE_MAPPED_LOCATION
455       {
456       tree source_name = identifier_subst (class_name, "", '.', '/', ".java");
457       const char *sfname = IDENTIFIER_POINTER (source_name);
458       linemap_add (&line_table, LC_ENTER, false, sfname, 0);
459       input_location = linemap_line_start (&line_table, 0, 1);
460       file_start_location = input_location;
461       DECL_SOURCE_LOCATION (TYPE_NAME (this_class)) = input_location;
462       if (main_input_filename == NULL && jcf == main_jcf)
463         main_input_filename = sfname;
464       }
465 #else
466       input_location = DECL_SOURCE_LOCATION (TYPE_NAME (this_class));
467       if (main_input_filename == NULL && jcf == main_jcf)
468         main_input_filename = input_filename;
469 #endif
470
471       jcf->cpool.data[i].t = this_class;
472       JPOOL_TAG (jcf, i) = CONSTANT_ResolvedClass;
473       split_qualified_name (&package_name, &tmp, 
474                             DECL_NAME (TYPE_NAME (this_class)));
475       TYPE_PACKAGE (this_class) = package_name;
476       return this_class;
477     }
478 }
479
480 /* Get the class of the CONSTANT_Class whose constant pool index is I. */
481
482 tree
483 get_class_constant (JCF *jcf, int i)
484 {
485   tree type;
486   if (i <= 0 || i >= JPOOL_SIZE (jcf)
487       || (JPOOL_TAG (jcf, i) & ~CONSTANT_ResolvedFlag) != CONSTANT_Class)
488     abort ();
489
490   if (JPOOL_TAG (jcf, i) != CONSTANT_ResolvedClass)
491     {
492       int name_index = JPOOL_USHORT1 (jcf, i);
493       /* verify_constant_pool confirmed that name_index is a CONSTANT_Utf8. */
494       const char *name = (const char *) JPOOL_UTF_DATA (jcf, name_index);
495       int nlength = JPOOL_UTF_LENGTH (jcf, name_index);
496
497       if (name[0] == '[')  /* Handle array "classes". */
498           type = TREE_TYPE (parse_signature_string ((const unsigned char *) name, nlength));
499       else
500         { 
501           tree cname = unmangle_classname (name, nlength);
502           type = lookup_class (cname);
503         }
504       jcf->cpool.data[i].t = type;
505       JPOOL_TAG (jcf, i) = CONSTANT_ResolvedClass;
506     }
507   else
508     type = jcf->cpool.data[i].t;
509   return type;
510 }
511
512 /* Read a class with the fully qualified-name NAME.
513    Return 1 iff we read the requested file.
514    (It is still possible we failed if the file did not
515    define the class it is supposed to.) */
516
517 int
518 read_class (tree name)
519 {
520   JCF this_jcf, *jcf;
521   tree icv, class = NULL_TREE;
522   tree save_current_class = current_class;
523   tree save_output_class = output_class;
524   location_t save_location = input_location;
525   JCF *save_current_jcf = current_jcf;
526
527   if ((icv = IDENTIFIER_CLASS_VALUE (name)) != NULL_TREE)
528     {
529       class = TREE_TYPE (icv);
530       jcf = TYPE_JCF (class);
531     }
532   else
533     jcf = NULL;
534
535   if (jcf == NULL)
536     {
537       const char* path_name;
538       this_jcf.zipd = NULL;
539       jcf = &this_jcf;
540       
541       path_name = find_class (IDENTIFIER_POINTER (name),
542                               IDENTIFIER_LENGTH (name),
543                               &this_jcf, 1);
544       if (path_name == 0)
545         return 0;
546       else
547         free((char *) path_name);
548     }
549
550   current_jcf = jcf;
551
552   if (current_jcf->java_source)
553     {
554       const char *filename = current_jcf->filename;
555       char *real_path;
556       tree given_file, real_file;
557       FILE *finput;
558       int generate;
559
560       java_parser_context_save_global ();
561       java_push_parser_context ();
562
563       given_file = get_identifier (filename);
564       filename = IDENTIFIER_POINTER (given_file);
565       real_path = lrealpath (filename);
566       real_file = get_identifier (real_path);
567       free (real_path);
568
569       generate = IS_A_COMMAND_LINE_FILENAME_P (given_file);
570       output_class = current_class = NULL_TREE;
571       current_function_decl = NULL_TREE;
572
573       if (! HAS_BEEN_ALREADY_PARSED_P (real_file))
574         {
575           if (! (finput = fopen (filename, "r")))
576             fatal_error ("can't reopen %s: %m", filename);
577
578           parse_source_file_1 (real_file, filename, finput);
579           parse_source_file_2 ();
580           parse_source_file_3 ();
581
582           if (fclose (finput))
583             fatal_error ("can't close %s: %m", input_filename);
584 #ifdef USE_MAPPED_LOCATION
585           linemap_add (&line_table, LC_LEAVE, false, NULL, 0);
586 #endif
587         }
588       JCF_FINISH (current_jcf);
589       java_pop_parser_context (generate);
590       java_parser_context_restore_global ();
591     }
592   else
593     {
594       if (class == NULL_TREE || ! CLASS_PARSED_P (class))
595         {
596           java_parser_context_save_global ();
597           java_push_parser_context ();
598           output_class = current_class = class;
599           ctxp->save_location = input_location;
600           if (JCF_SEEN_IN_ZIP (current_jcf))
601             read_zip_member(current_jcf,
602                             current_jcf->zipd, current_jcf->zipd->zipf);
603           jcf_parse (current_jcf);
604           /* Parsing might change the class, in which case we have to
605              put it back where we found it.  */
606           if (current_class != class && icv != NULL_TREE)
607             TREE_TYPE (icv) = current_class;
608           class = current_class;
609           java_pop_parser_context (0);
610           java_parser_context_restore_global ();
611         }
612       layout_class (class);
613       load_inner_classes (class);
614     }
615
616   output_class = save_output_class;
617   current_class = save_current_class;
618   input_location = save_location;
619   current_jcf = save_current_jcf;
620   return 1;
621 }
622
623 /* Load CLASS_OR_NAME. CLASS_OR_NAME can be a mere identifier if
624    called from the parser, otherwise it's a RECORD_TYPE node. If
625    VERBOSE is 1, print error message on failure to load a class. */
626 void
627 load_class (tree class_or_name, int verbose)
628 {
629   tree name, saved;
630   int class_loaded = 0;
631   tree class_decl = NULL_TREE;
632   bool is_compiled_class = false;
633
634   /* We've already failed, don't try again.  */
635   if (TREE_CODE (class_or_name) == RECORD_TYPE
636       && TYPE_DUMMY (class_or_name))
637     return;
638
639   /* class_or_name can be the name of the class we want to load */
640   if (TREE_CODE (class_or_name) == IDENTIFIER_NODE)
641     name = class_or_name;
642   /* In some cases, it's a dependency that we process earlier that
643      we though */
644   else if (TREE_CODE (class_or_name) == TREE_LIST)
645     name = TYPE_NAME (TREE_PURPOSE (class_or_name));
646   /* Or it's a type in the making */
647   else
648     name = DECL_NAME (TYPE_NAME (class_or_name));
649
650   class_decl = IDENTIFIER_CLASS_VALUE (name);
651   if (class_decl != NULL_TREE)
652     {
653       tree type = TREE_TYPE (class_decl);
654       is_compiled_class
655         = ((TYPE_JCF (type) && JCF_SEEN_IN_ZIP (TYPE_JCF (type)))
656            || CLASS_FROM_CURRENTLY_COMPILED_P (type));
657     }
658
659   /* If the class is from source code, then it must already be loaded.  */
660   class_decl = IDENTIFIER_CLASS_VALUE (name);
661   if (class_decl && CLASS_FROM_SOURCE_P (TREE_TYPE (class_decl)))
662     return;
663
664   saved = name;
665   
666   /* If flag_verify_invocations is unset, we don't try to load a class
667      unless we're looking for Object (which is fixed by the ABI) or
668      it's a class that we're going to compile.  */
669   if (flag_verify_invocations
670       || class_or_name == object_type_node
671       || is_compiled_class
672       || TREE_CODE (class_or_name) == IDENTIFIER_NODE)
673     {
674       while (1)
675         {
676           char *separator;
677
678           /* We've already loaded it.  */
679           if (IDENTIFIER_CLASS_VALUE (name) != NULL_TREE)
680             {
681               tree tmp_decl = IDENTIFIER_CLASS_VALUE (name);
682               if (CLASS_PARSED_P (TREE_TYPE (tmp_decl)))
683                 break;
684             }
685         
686           if (read_class (name))
687             break;
688
689           /* We failed loading name. Now consider that we might be looking
690              for an inner class.  */
691           if ((separator = strrchr (IDENTIFIER_POINTER (name), '$'))
692               || (separator = strrchr (IDENTIFIER_POINTER (name), '.')))
693             {
694               int c = *separator;
695               *separator = '\0';
696               name = get_identifier (IDENTIFIER_POINTER (name));
697               *separator = c;
698             }
699           /* Otherwise, we failed, we bail. */
700           else
701             break;
702         }
703
704       {
705         /* have we found the class we're looking for?  */
706         tree type_decl = IDENTIFIER_CLASS_VALUE (saved);
707         tree type = type_decl ? TREE_TYPE (type_decl) : NULL;
708         class_loaded = type && CLASS_PARSED_P (type);
709       }       
710     }
711   
712   if (!class_loaded)
713     {
714       if (flag_verify_invocations || ! flag_indirect_dispatch
715           || flag_emit_class_files)
716         {
717           if (verbose)
718             error ("cannot find file for class %s", IDENTIFIER_POINTER (saved));
719         }
720       else if (verbose)
721         {
722           /* This is just a diagnostic during testing, not a real problem.  */
723           if (!quiet_flag)
724             warning (0, "cannot find file for class %s", 
725                      IDENTIFIER_POINTER (saved));
726           
727           /* Fake it.  */
728           if (TREE_CODE (class_or_name) == RECORD_TYPE)
729             {
730               set_super_info (0, class_or_name, object_type_node, 0);
731               TYPE_DUMMY (class_or_name) = 1;
732               /* We won't be able to output any debug info for this class.  */
733               DECL_IGNORED_P (TYPE_NAME (class_or_name)) = 1;
734             }
735         }
736     }
737 }
738
739 /* Parse the .class file JCF. */
740
741 static void
742 jcf_parse (JCF* jcf)
743 {
744   int i, code;
745
746   if (jcf_parse_preamble (jcf) != 0)
747     fatal_error ("not a valid Java .class file");
748   code = jcf_parse_constant_pool (jcf);
749   if (code != 0)
750     fatal_error ("error while parsing constant pool");
751   code = verify_constant_pool (jcf);
752   if (code > 0)
753     fatal_error ("error in constant pool entry #%d\n", code);
754
755   jcf_parse_class (jcf);
756   if (main_class == NULL_TREE)
757     main_class = current_class;
758   if (! quiet_flag && TYPE_NAME (current_class))
759     fprintf (stderr, " %s %s",
760              (jcf->access_flags & ACC_INTERFACE) ? "interface" : "class", 
761              IDENTIFIER_POINTER (DECL_NAME (TYPE_NAME (current_class))));
762   if (CLASS_PARSED_P (current_class))
763     {
764       /* FIXME - where was first time */
765       fatal_error ("reading class %s for the second time from %s",
766                    IDENTIFIER_POINTER (DECL_NAME (TYPE_NAME (current_class))),
767                    jcf->filename);
768     }
769   CLASS_PARSED_P (current_class) = 1;
770
771   for (i = 1; i < JPOOL_SIZE(jcf); i++)
772     {
773       switch (JPOOL_TAG (jcf, i))
774         {
775         case CONSTANT_Class:
776           get_class_constant (jcf, i);
777           break;
778         }
779     }
780   
781   code = jcf_parse_fields (jcf);
782   if (code != 0)
783     fatal_error ("error while parsing fields");
784   code = jcf_parse_methods (jcf);
785   if (code != 0)
786     fatal_error ("error while parsing methods");
787   code = jcf_parse_final_attributes (jcf);
788   if (code != 0)
789     fatal_error ("error while parsing final attributes");
790 #ifdef USE_MAPPED_LOCATION
791   linemap_add (&line_table, LC_LEAVE, false, NULL, 0);
792 #endif
793
794   /* The fields of class_type_node are already in correct order. */
795   if (current_class != class_type_node && current_class != object_type_node)
796     TYPE_FIELDS (current_class) = nreverse (TYPE_FIELDS (current_class));
797
798   if (current_class == object_type_node)
799     {
800       layout_class_methods (object_type_node);
801       /* If we don't have the right archive, emit a verbose warning.
802          If we're generating bytecode, emit the warning only if
803          -fforce-classes-archive-check was specified. */
804       if (!jcf->right_zip
805           && (!flag_emit_class_files || flag_force_classes_archive_check))
806         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);
807     }
808   else
809     all_class_list = tree_cons (NULL_TREE,
810                                 TYPE_NAME (current_class), all_class_list );
811 }
812
813 /* If we came across inner classes, load them now. */
814 static void
815 load_inner_classes (tree cur_class)
816 {
817   tree current;
818   for (current = DECL_INNER_CLASS_LIST (TYPE_NAME (cur_class)); current;
819        current = TREE_CHAIN (current))
820     {
821       tree name = DECL_NAME (TREE_PURPOSE (current));
822       tree decl = IDENTIFIER_GLOBAL_VALUE (name);
823       if (decl && ! CLASS_LOADED_P (TREE_TYPE (decl))
824           && !CLASS_BEING_LAIDOUT (TREE_TYPE (decl)))
825         load_class (name, 1);
826     }
827 }
828
829 static void
830 duplicate_class_warning (const char *filename)
831 {
832   location_t warn_loc;
833 #ifdef USE_MAPPED_LOCATION
834   linemap_add (&line_table, LC_RENAME, 0, filename, 0);
835   warn_loc = linemap_line_start (&line_table, 0, 1);
836 #else
837   warn_loc.file = filename;
838   warn_loc.line = 0;
839 #endif
840   warning (0, "%Hduplicate class will only be compiled once", &warn_loc);
841 }
842
843 static void
844 parse_class_file (void)
845 {
846   tree method;
847   location_t save_location = input_location;
848
849   java_layout_seen_class_methods ();
850
851   input_location = DECL_SOURCE_LOCATION (TYPE_NAME (current_class));
852   file_start_location = input_location;
853   (*debug_hooks->start_source_file) (input_line, input_filename);
854
855   gen_indirect_dispatch_tables (current_class);
856
857   java_mark_class_local (current_class);
858
859   for (method = TYPE_METHODS (current_class);
860        method != NULL_TREE; method = TREE_CHAIN (method))
861     {
862       JCF *jcf = current_jcf;
863
864       if (METHOD_ABSTRACT (method) || METHOD_DUMMY (method))
865         continue;
866
867       if (METHOD_NATIVE (method))
868         {
869           tree arg;
870           int  decl_max_locals;
871
872           if (! flag_jni)
873             continue;
874           /* We need to compute the DECL_MAX_LOCALS. We need to take
875              the wide types into account too. */
876           for (arg = TYPE_ARG_TYPES (TREE_TYPE (method)), decl_max_locals = 0; 
877                arg != end_params_node;
878                arg = TREE_CHAIN (arg), decl_max_locals += 1)
879             {
880               if (TREE_VALUE (arg) && TYPE_IS_WIDE (TREE_VALUE (arg)))
881                 decl_max_locals += 1;
882             }
883           DECL_MAX_LOCALS (method) = decl_max_locals;
884           start_java_method (method);
885           give_name_to_locals (jcf);
886           *get_stmts () = build_jni_stub (method);
887           end_java_method ();
888           continue;
889         }
890
891       if (DECL_CODE_OFFSET (method) == 0)
892         {
893           current_function_decl = method;
894           error ("missing Code attribute");
895           continue;
896         }
897
898       input_location = file_start_location;
899       if (DECL_LINENUMBERS_OFFSET (method))
900         {
901           int i;
902           int min_line = 0;
903           unsigned char *ptr;
904           JCF_SEEK (jcf, DECL_LINENUMBERS_OFFSET (method));
905           linenumber_count = i = JCF_readu2 (jcf);
906           linenumber_table = ptr = jcf->read_ptr;
907
908           for (ptr += 2; --i >= 0; ptr += 4)
909             {
910               int line = GET_u2 (ptr);
911               /* Set initial input_line to smallest linenumber.
912                * Needs to be set before init_function_start. */
913               if (min_line == 0 || line < min_line)
914                 min_line = line;
915             }
916 #ifdef USE_MAPPED_LOCATION
917           if (min_line != 0)
918             input_location = linemap_line_start (&line_table, min_line, 1);
919 #else
920           if (min_line != 0)
921             input_line = min_line;
922 #endif
923         }
924       else
925         {
926           linenumber_table = NULL;
927           linenumber_count = 0;
928         }
929
930       start_java_method (method);
931
932       note_instructions (jcf, method);
933
934       give_name_to_locals (jcf);
935
936       /* Bump up start_label_pc_this_method so we get a unique label number
937          and reset highest_label_pc_this_method. */
938       if (highest_label_pc_this_method >= 0)
939         {
940           /* We adjust to the next multiple of 1000.  This is just a frill
941              so the last 3 digits of the label number match the bytecode
942              offset, which might make debugging marginally more convenient. */
943           start_label_pc_this_method
944             = ((((start_label_pc_this_method + highest_label_pc_this_method)
945                  / 1000)
946                 + 1)
947                * 1000);
948           highest_label_pc_this_method = -1;
949         }
950
951       /* Convert bytecode to trees.  */
952       expand_byte_code (jcf, method);
953
954       end_java_method ();
955     }
956
957   if (flag_emit_class_files)
958     write_classfile (current_class);
959
960   finish_class ();
961
962   (*debug_hooks->end_source_file) (LOCATION_LINE (save_location));
963   input_location = save_location;
964 }
965
966 /* Parse a source file, as pointed by the current value of INPUT_FILENAME. */
967
968 static void
969 parse_source_file_1 (tree real_file, const char *filename, FILE *finput)
970 {
971   int save_error_count = java_error_count;
972
973   /* Mark the file as parsed.  */
974   HAS_BEEN_ALREADY_PARSED_P (real_file) = 1;
975
976   lang_init_source (1);             /* Error msgs have no method prototypes */
977
978   /* There's no point in trying to find the current encoding unless we
979      are going to do something intelligent with it -- hence the test
980      for iconv.  */
981 #if defined (HAVE_LOCALE_H) && defined (HAVE_ICONV) && defined (HAVE_LANGINFO_CODESET)
982   setlocale (LC_CTYPE, "");
983   if (current_encoding == NULL)
984     current_encoding = nl_langinfo (CODESET);
985 #endif 
986   if (current_encoding == NULL || *current_encoding == '\0')
987     current_encoding = DEFAULT_ENCODING;
988
989 #ifdef USE_MAPPED_LOCATION
990   linemap_add (&line_table, LC_ENTER, false, filename, 0);
991   input_location = linemap_line_start (&line_table, 0, 125);
992 #else
993   input_filename = filename;
994   input_line = 0;
995 #endif
996   ctxp->file_start_location = input_location;
997   ctxp->filename = filename;
998
999   jcf_dependency_add_file (input_filename, 0);
1000
1001   /* Initialize the parser */
1002   java_init_lex (finput, current_encoding);
1003   java_parse_abort_on_error ();
1004
1005   java_parse ();                    /* Parse and build partial tree nodes. */
1006   java_parse_abort_on_error ();
1007 }
1008
1009 /* Process a parsed source file, resolving names etc. */
1010
1011 static void
1012 parse_source_file_2 (void)
1013 {
1014   int save_error_count = java_error_count;
1015   flag_verify_invocations = true;
1016   java_complete_class ();           /* Parse unsatisfied class decl. */
1017   java_parse_abort_on_error ();
1018 }
1019
1020 static void
1021 parse_source_file_3 (void)
1022 {
1023   int save_error_count = java_error_count;
1024   java_check_circular_reference (); /* Check on circular references */
1025   java_parse_abort_on_error ();
1026   java_fix_constructors ();         /* Fix the constructors */
1027   java_parse_abort_on_error ();
1028   java_reorder_fields ();           /* Reorder the fields */
1029 }
1030
1031 void
1032 add_predefined_file (tree name)
1033 {
1034   predef_filenames = tree_cons (NULL_TREE, name, predef_filenames);
1035 }
1036
1037 int
1038 predefined_filename_p (tree node)
1039 {
1040   tree iter;
1041
1042   for (iter = predef_filenames; iter != NULL_TREE; iter = TREE_CHAIN (iter))
1043     {
1044       if (TREE_VALUE (iter) == node)
1045         return 1;
1046     }
1047   return 0;
1048 }
1049
1050 /* Generate a function that does all static initialization for this 
1051    translation unit.  */
1052
1053 static void
1054 java_emit_static_constructor (void)
1055 {
1056   tree body = NULL;
1057
1058   emit_register_classes (&body);
1059   write_resource_constructor (&body);
1060
1061   if (body)
1062     cgraph_build_static_cdtor ('I', body, DEFAULT_INIT_PRIORITY);
1063 }
1064
1065 void
1066 java_parse_file (int set_yydebug ATTRIBUTE_UNUSED)
1067 {
1068   int filename_count = 0;
1069   location_t save_location = input_location;
1070   char *file_list = NULL, *list, *next;
1071   tree node;
1072   FILE *finput = NULL;
1073   int in_quotes = 0;
1074  
1075   if (flag_filelist_file)
1076     {
1077       int avail = 2000;
1078       finput = fopen (main_input_filename, "r");
1079       if (finput == NULL)
1080         fatal_error ("can't open %s: %m", input_filename);
1081       list = xmalloc(avail);
1082       next = list;
1083       for (;;)
1084         {
1085           int count;
1086           if (avail < 500)
1087             {
1088               count = next - list;
1089               avail = 2 * (count + avail);
1090               list = xrealloc (list, avail);
1091               next = list + count;
1092               avail = avail - count;
1093             }
1094           /* Subtract to to guarantee space for final '\0'. */
1095           count = fread (next, 1, avail - 1, finput);
1096           if (count == 0)
1097             {
1098               if (! feof (finput))
1099                 fatal_error ("error closing %s: %m", input_filename);
1100               *next = '\0';
1101               break;
1102             }
1103           avail -= count;
1104           next += count;
1105         }
1106       fclose (finput);
1107       finput = NULL;
1108       file_list = list;
1109     }
1110   else
1111     list = (char *) main_input_filename;
1112
1113   while (list)
1114     {
1115       for (next = list; ; )
1116         {
1117           char ch = *next;
1118           if (flag_filelist_file && ! in_quotes
1119               && (ch == '\n' || ch == '\r' || ch == '\t' || ch == ' '
1120                   || ch == '&') /* FIXME */)
1121             {
1122               if (next == list)
1123                 {
1124                   next++;
1125                   list = next;
1126                   continue;
1127                 }
1128               else
1129                 {
1130                   *next++ = '\0';
1131                   break;
1132                 }
1133             }
1134           if (flag_filelist_file && ch == '"')
1135             {
1136               in_quotes = ! in_quotes;
1137               *next++ = '\0';
1138               if (in_quotes) 
1139                 list = next;
1140               else 
1141                 break;
1142             }
1143           if (ch == '\0')
1144             {
1145               next = NULL;
1146               break;
1147             }
1148           next++;
1149         }
1150
1151       if (list[0]) 
1152         {
1153           node = get_identifier (list);
1154
1155           filename_count++;
1156
1157           /* Exclude file that we see twice on the command line. */
1158              
1159           if (IS_A_COMMAND_LINE_FILENAME_P (node))
1160             duplicate_class_warning (IDENTIFIER_POINTER (node));
1161           else
1162             {
1163               tree file_decl = build_decl (TRANSLATION_UNIT_DECL, node, NULL);
1164               TREE_CHAIN (file_decl) = current_file_list;
1165               current_file_list = file_decl;
1166               IS_A_COMMAND_LINE_FILENAME_P (node) = 1;
1167             }
1168         }
1169       list = next;
1170     }
1171
1172   if (file_list != NULL)
1173     free (file_list);
1174
1175   if (filename_count == 0)
1176     warning (0, "no input file specified");
1177
1178   if (resource_name)
1179     {
1180       const char *resource_filename;
1181       
1182       /* Only one resource file may be compiled at a time.  */
1183       assert (TREE_CHAIN (current_file_list) == NULL);
1184
1185       resource_filename = IDENTIFIER_POINTER (DECL_NAME (current_file_list));
1186       compile_resource_file (resource_name, resource_filename);
1187
1188       goto finish;
1189     }
1190
1191   current_jcf = main_jcf;
1192   current_file_list = nreverse (current_file_list);
1193   for (node = current_file_list; node; node = TREE_CHAIN (node))
1194     {
1195       unsigned char magic_string[4];
1196       char *real_path;
1197       uint32 magic = 0;
1198       tree name = DECL_NAME (node);
1199       tree real_file;
1200       const char *filename = IDENTIFIER_POINTER (name);
1201
1202       /* Skip already parsed files */
1203       real_path = lrealpath (filename);
1204       real_file = get_identifier (real_path);
1205       free (real_path);
1206       if (HAS_BEEN_ALREADY_PARSED_P (real_file))
1207         continue;
1208
1209       /* Close previous descriptor, if any */
1210       if (finput && fclose (finput))
1211         fatal_error ("can't close input file %s: %m", main_input_filename);
1212       
1213       finput = fopen (filename, "rb");
1214       if (finput == NULL)
1215         fatal_error ("can't open %s: %m", filename);
1216
1217 #ifdef IO_BUFFER_SIZE
1218       setvbuf (finput, xmalloc (IO_BUFFER_SIZE),
1219                _IOFBF, IO_BUFFER_SIZE);
1220 #endif
1221
1222       /* Figure what kind of file we're dealing with */
1223       if (fread (magic_string, 1, 4, finput) == 4)
1224         {
1225           fseek (finput, 0L, SEEK_SET);
1226           magic = GET_u4 (magic_string);
1227         }
1228       if (magic == 0xcafebabe)
1229         {
1230           CLASS_FILE_P (node) = 1;
1231           current_jcf = ggc_alloc (sizeof (JCF));
1232           JCF_ZERO (current_jcf);
1233           current_jcf->read_state = finput;
1234           current_jcf->filbuf = jcf_filbuf_from_stdio;
1235           jcf_parse (current_jcf);
1236           DECL_SOURCE_LOCATION (node) = file_start_location;
1237           TYPE_JCF (current_class) = current_jcf;
1238           if (CLASS_FROM_CURRENTLY_COMPILED_P (current_class))
1239             {
1240               /* We've already compiled this class.  */
1241               duplicate_class_warning (filename);
1242               continue;
1243             }
1244           CLASS_FROM_CURRENTLY_COMPILED_P (current_class) = 1;
1245           TREE_TYPE (node) = current_class;
1246         }
1247       else if (magic == (JCF_u4)ZIPMAGIC)
1248         {
1249           main_jcf = ggc_alloc (sizeof (JCF));
1250           JCF_ZERO (main_jcf);
1251           main_jcf->read_state = finput;
1252           main_jcf->filbuf = jcf_filbuf_from_stdio;
1253 #ifdef USE_MAPPED_LOCATION
1254           linemap_add (&line_table, LC_ENTER, false, filename, 0);
1255           input_location = linemap_line_start (&line_table, 0, 1);
1256 #endif
1257           if (open_in_zip (main_jcf, filename, NULL, 0) <  0)
1258             fatal_error ("bad zip/jar file %s", filename);
1259           localToFile = SeenZipFiles;
1260           /* Register all the classes defined there.  */
1261           process_zip_dir (main_jcf->read_state);
1262 #ifdef USE_MAPPED_LOCATION
1263           linemap_add (&line_table, LC_LEAVE, false, NULL, 0);
1264 #endif
1265           parse_zip_file_entries ();
1266         }
1267       else
1268         {
1269           java_push_parser_context ();
1270           java_parser_context_save_global ();
1271
1272           parse_source_file_1 (real_file, filename, finput);
1273           java_parser_context_restore_global ();
1274           java_pop_parser_context (1);
1275 #ifdef USE_MAPPED_LOCATION
1276           linemap_add (&line_table, LC_LEAVE, false, NULL, 0);
1277 #endif
1278         }
1279     }
1280
1281   for (ctxp = ctxp_for_generation;  ctxp;  ctxp = ctxp->next)
1282     {
1283       input_location = ctxp->file_start_location;
1284       parse_source_file_2 ();
1285     }
1286
1287   for (ctxp = ctxp_for_generation; ctxp; ctxp = ctxp->next)
1288     {
1289       input_location = ctxp->file_start_location;
1290       parse_source_file_3 ();
1291     }
1292
1293   for (node = current_file_list; node; node = TREE_CHAIN (node))
1294     {
1295       input_location = DECL_SOURCE_LOCATION (node);
1296       if (CLASS_FILE_P (node))
1297         {
1298           /* FIXME: These two flags really should be independent.  We
1299              should be able to compile fully binary compatible, but
1300              with flag_verify_invocations on.  */
1301           flag_verify_invocations = ! flag_indirect_dispatch;
1302           output_class = current_class = TREE_TYPE (node);
1303
1304           current_jcf = TYPE_JCF (current_class);
1305           layout_class (current_class);
1306           load_inner_classes (current_class);
1307           parse_class_file ();
1308           JCF_FINISH (current_jcf);
1309         }
1310     }
1311   input_location = save_location;
1312
1313   java_expand_classes ();
1314   if (java_report_errors () || flag_syntax_only)
1315     return;
1316     
1317   /* Expand all classes compiled from source.  */
1318   java_finish_classes ();
1319
1320  finish:
1321   /* Arrange for any necessary initialization to happen.  */
1322   java_emit_static_constructor ();
1323
1324   /* Only finalize the compilation unit after we've told cgraph which
1325      functions have their addresses stored.  */
1326   cgraph_finalize_compilation_unit ();
1327   cgraph_optimize ();
1328 }
1329
1330
1331 /* Return the name of the class corresponding to the name of the file
1332    in this zip entry.  The result is newly allocated using ALLOC.  */
1333 static char *
1334 compute_class_name (struct ZipDirectory *zdir)
1335 {
1336   char *class_name_in_zip_dir = ZIPDIR_FILENAME (zdir);
1337   char *class_name;
1338   int i;
1339   int filename_length = zdir->filename_length;
1340
1341   while (filename_length > 2 && strncmp (class_name_in_zip_dir, "./", 2) == 0)
1342     {
1343       class_name_in_zip_dir += 2;
1344       filename_length -= 2;
1345     }
1346
1347   filename_length -= strlen (".class");
1348   class_name = ALLOC (filename_length + 1);
1349   memcpy (class_name, class_name_in_zip_dir, filename_length);
1350   class_name [filename_length] = '\0';
1351
1352   for (i = 0; i < filename_length; i++)
1353     if (class_name[i] == '/')
1354       class_name[i] = '.';
1355
1356   return class_name;
1357 }
1358
1359 /* Return 0 if we should skip this entry, 1 if it is a .class file, 2
1360    if it is a property file of some sort.  */
1361 static int
1362 classify_zip_file (struct ZipDirectory *zdir)
1363 {
1364   char *class_name_in_zip_dir = ZIPDIR_FILENAME (zdir);
1365
1366   if (zdir->filename_length > 6
1367       && !strncmp (&class_name_in_zip_dir[zdir->filename_length - 6],
1368                    ".class", 6))
1369     return 1;
1370
1371   /* For now we drop the manifest, but not other information.  */
1372   if (zdir->filename_length == 20
1373       && !strncmp (class_name_in_zip_dir, "META-INF/MANIFEST.MF", 20))
1374     return 0;
1375
1376   /* Drop directory entries.  */
1377   if (zdir->filename_length > 0
1378       && class_name_in_zip_dir[zdir->filename_length - 1] == '/')
1379     return 0;
1380
1381   return 2;
1382 }
1383
1384 /* Process all class entries found in the zip file.  */
1385 static void
1386 parse_zip_file_entries (void)
1387 {
1388   struct ZipDirectory *zdir;
1389   int i;
1390
1391   for (i = 0, zdir = (ZipDirectory *)localToFile->central_directory;
1392        i < localToFile->count; i++, zdir = ZIPDIR_NEXT (zdir))
1393     {
1394       tree class;
1395
1396       switch (classify_zip_file (zdir))
1397         {
1398         case 0:
1399           continue;
1400
1401         case 1:
1402           {
1403             char *class_name = compute_class_name (zdir);
1404             class = lookup_class (get_identifier (class_name));
1405             FREE (class_name);
1406             current_jcf = TYPE_JCF (class);
1407             output_class = current_class = class;
1408
1409             if (CLASS_FROM_CURRENTLY_COMPILED_P (current_class))
1410               {
1411                 /* We've already compiled this class.  */
1412                 duplicate_class_warning (current_jcf->filename);
1413                 break;
1414               }
1415             
1416             CLASS_FROM_CURRENTLY_COMPILED_P (current_class) = 1;
1417
1418             if (TYPE_DUMMY (class))
1419               {
1420                 /* This is a dummy class, and now we're compiling it
1421                    for real.  */
1422                 abort ();
1423               }
1424
1425             /* This is for a corner case where we have a superclass
1426                but no superclass fields.  
1427
1428                This can happen if we earlier failed to lay out this
1429                class because its superclass was still in the process
1430                of being laid out; this occurs when we have recursive
1431                class dependencies via inner classes.  Setting
1432                TYPE_SIZE to null here causes CLASS_LOADED_P to return
1433                false, so layout_class() will be called again.  */
1434             if (TYPE_SIZE (class) && CLASSTYPE_SUPER (class)
1435                 && integer_zerop (TYPE_SIZE (class)))
1436               TYPE_SIZE (class) = NULL_TREE;
1437
1438             if (! CLASS_LOADED_P (class))
1439               {
1440                 if (! CLASS_PARSED_P (class))
1441                   {
1442                     read_zip_member (current_jcf, zdir, localToFile);
1443                     jcf_parse (current_jcf);
1444                   }
1445                 layout_class (current_class);
1446                 load_inner_classes (current_class);
1447               }
1448
1449             if (TYPE_SIZE (current_class) != error_mark_node)
1450               {
1451                 parse_class_file ();
1452                 FREE (current_jcf->buffer); /* No longer necessary */
1453                 /* Note: there is a way to free this buffer right after a
1454                    class seen in a zip file has been parsed. The idea is the
1455                    set its jcf in such a way that buffer will be reallocated
1456                    the time the code for the class will be generated. FIXME. */
1457               }
1458           }
1459           break;
1460
1461         case 2:
1462           {
1463             char *file_name, *class_name_in_zip_dir, *buffer;
1464             JCF *jcf;
1465             file_name = ALLOC (zdir->filename_length + 1);
1466             class_name_in_zip_dir = ZIPDIR_FILENAME (zdir);
1467             strncpy (file_name, class_name_in_zip_dir, zdir->filename_length);
1468             file_name[zdir->filename_length] = '\0';
1469             jcf = ALLOC (sizeof (JCF));
1470             JCF_ZERO (jcf);
1471             jcf->read_state  = finput;
1472             jcf->filbuf      = jcf_filbuf_from_stdio;
1473             jcf->java_source = 0;
1474             jcf->classname   = NULL;
1475             jcf->filename    = file_name;
1476             jcf->zipd        = zdir;
1477
1478             if (read_zip_member (jcf, zdir, localToFile) < 0)
1479               fatal_error ("error while reading %s from zip file", file_name);
1480
1481             buffer = ALLOC (zdir->filename_length + 1 +
1482                             (jcf->buffer_end - jcf->buffer));
1483             strcpy (buffer, file_name);
1484             /* This is not a typo: we overwrite the trailing \0 of the
1485                file name; this is just how the data is laid out.  */
1486             memcpy (buffer + zdir->filename_length,
1487                     jcf->buffer, jcf->buffer_end - jcf->buffer);
1488
1489             compile_resource_data (file_name, buffer,
1490                                    jcf->buffer_end - jcf->buffer);
1491             JCF_FINISH (jcf);
1492             FREE (jcf);
1493             FREE (buffer);
1494           }
1495           break;
1496
1497         default:
1498           abort ();
1499         }
1500     }
1501 }
1502
1503 /* Read all the entries of the zip file, creates a class and a JCF. Sets the
1504    jcf up for further processing and link it to the created class.  */
1505
1506 static void
1507 process_zip_dir (FILE *finput)
1508 {
1509   int i;
1510   ZipDirectory *zdir;
1511
1512   for (i = 0, zdir = (ZipDirectory *)localToFile->central_directory;
1513        i < localToFile->count; i++, zdir = ZIPDIR_NEXT (zdir))
1514     {
1515       char *class_name, *file_name, *class_name_in_zip_dir;
1516       tree class;
1517       JCF  *jcf;
1518
1519       class_name_in_zip_dir = ZIPDIR_FILENAME (zdir);
1520
1521       /* Here we skip non-class files; we handle them later.  */
1522       if (classify_zip_file (zdir) != 1)
1523         continue;
1524
1525       class_name = compute_class_name (zdir);
1526       file_name  = ALLOC (zdir->filename_length+1);
1527       jcf = ggc_alloc (sizeof (JCF));
1528       JCF_ZERO (jcf);
1529
1530       strncpy (file_name, class_name_in_zip_dir, zdir->filename_length);
1531       file_name [zdir->filename_length] = '\0';
1532
1533       class = lookup_class (get_identifier (class_name));
1534
1535       jcf->read_state  = finput;
1536       jcf->filbuf      = jcf_filbuf_from_stdio;
1537       jcf->java_source = 0;
1538       jcf->classname   = class_name;
1539       jcf->filename    = file_name;
1540       jcf->zipd        = zdir;
1541
1542       TYPE_JCF (class) = jcf;
1543     }
1544 }
1545
1546 /* Initialization.  */
1547
1548 void
1549 init_jcf_parse (void)
1550 {
1551   init_src_parse ();
1552 }
1553
1554 #include "gt-java-jcf-parse.h"