OSDN Git Service

e6dc44c1d0ffef91ab4ce678dd43cf4fd71d2e30
[pf3gnuchains/gcc-fork.git] / gcc / java / jcf-parse.c
1 /* Parser for Java(TM) .class files.
2    Copyright (C) 1996, 1998, 1999, 2000, 2001, 2002, 2003, 2004,
3    2005, 2006, 2007, 2008, 2009, 2010 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 3, 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 COPYING3.  If not see
19 <http://www.gnu.org/licenses/>.
20
21 Java and all Java-based marks are trademarks or registered trademarks
22 of Sun Microsystems, Inc. in the United States and other countries.
23 The Free Software Foundation is independent of Sun Microsystems, Inc.  */
24
25 /* Written by Per Bothner <bothner@cygnus.com> */
26
27 #include "config.h"
28 #include "system.h"
29 #include "coretypes.h"
30 #include "tree.h"
31 #include "obstack.h"
32 #include "flags.h"
33 #include "java-except.h"
34 #include "input.h"
35 #include "javaop.h"
36 #include "java-tree.h"
37 #include "diagnostic-core.h"
38 #include "toplev.h"
39 #include "parse.h"
40 #include "ggc.h"
41 #include "debug.h"
42 #include "assert.h"
43 #include "cgraph.h"
44 #include "vecprim.h"
45 #include "bitmap.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[2];
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 /* Line 0 in current file, if compiling from bytecode. */
84 static location_t file_start_location;
85
86 /* The Java archive that provides main_class;  the main input file. */
87 static GTY(()) struct JCF * main_jcf;
88
89 /* A list of all the class DECLs seen so far.  */
90 static GTY(()) VEC(tree,gc) *all_class_list;
91
92 /* The number of source files passed to us by -fsource-filename and an
93    array of pointers to each name.  Used by find_sourcefile().  */
94 static int num_files = 0;
95 static char **filenames;
96
97 static struct ZipFile *localToFile;
98
99 /* A map of byte offsets in the reflection data that are fields which
100    need renumbering.  */
101 bitmap field_offsets;
102 bitmap_obstack bit_obstack;
103
104 /* Declarations of some functions used here.  */
105 static void handle_innerclass_attribute (int count, JCF *, int len);
106 static tree give_name_to_class (JCF *jcf, int index);
107 static char *compute_class_name (struct ZipDirectory *zdir);
108 static int classify_zip_file (struct ZipDirectory *zdir);
109 static void parse_zip_file_entries (void);
110 static void process_zip_dir (FILE *);
111 static void parse_class_file (void);
112 static void handle_deprecated (void);
113 static void set_source_filename (JCF *, int);
114 static void jcf_parse (struct JCF*);
115 static void load_inner_classes (tree);
116 static void handle_annotation (JCF *jcf, int level);
117 static void java_layout_seen_class_methods (void);
118
119 /* Handle "Deprecated" attribute.  */
120 static void
121 handle_deprecated (void)
122 {
123   if (current_field != NULL_TREE)
124     FIELD_DEPRECATED (current_field) = 1;
125   else if (current_method != NULL_TREE)
126     METHOD_DEPRECATED (current_method) = 1;
127   else if (current_class != NULL_TREE)
128     CLASS_DEPRECATED (TYPE_NAME (current_class)) = 1;
129   else
130     {
131       /* Shouldn't happen.  */
132       gcc_unreachable ();
133     }
134 }
135
136 \f
137
138 /* Reverse a string.  */
139 static char *
140 reverse (const char *s)
141 {
142   if (s == NULL)
143     return NULL;
144   else
145     {
146       int len = strlen (s);
147       char *d = XNEWVAR (char, len + 1);
148       const char *sp;
149       char *dp;
150       
151       d[len] = 0;
152       for (dp = &d[0], sp = &s[len-1]; sp >= s; dp++, sp--)
153         *dp = *sp;
154
155       return d;
156     }
157 }
158
159 /* Compare two strings for qsort().  */
160 static int
161 cmpstringp (const void *p1, const void *p2)
162 {
163   /* The arguments to this function are "pointers to
164      pointers to char", but strcmp() arguments are "pointers
165      to char", hence the following cast plus dereference */
166
167   return strcmp(*(const char *const*) p1, *(const char *const*) p2);
168 }
169
170 /* Create an array of strings, one for each source file that we've
171    seen.  fsource_filename can either be the name of a single .java
172    file or a file that contains a list of filenames separated by
173    newlines.  */
174 void 
175 java_read_sourcefilenames (const char *fsource_filename)
176 {
177   if (fsource_filename 
178       && filenames == 0
179       && strlen (fsource_filename) > strlen (".java")
180       && strcmp ((fsource_filename 
181                   + strlen (fsource_filename)
182                   - strlen (".java")),
183                  ".java") != 0)
184     {
185 /*       fsource_filename isn't a .java file but a list of filenames
186        separated by newlines */
187       FILE *finput = fopen (fsource_filename, "r");
188       int len = 0;
189       int longest_line = 0;
190
191       gcc_assert (finput);
192
193       /* Find out how many files there are, and how long the filenames are.  */
194       while (! feof (finput))
195         {
196           int ch = getc (finput);
197           if (ch == '\n')
198             {
199               num_files++;
200               if (len > longest_line)
201                 longest_line = len;
202               len = 0;
203               continue;
204             }
205           if (ch == EOF)
206             break;
207           len++;
208         }
209
210       rewind (finput);
211
212       /* Read the filenames.  Put a pointer to each filename into the
213          array FILENAMES.  */
214       {
215         char *linebuf = (char *) alloca (longest_line + 1);
216         int i = 0;
217         int charpos;
218
219         filenames = XNEWVEC (char *, num_files);
220
221         charpos = 0;
222         for (;;)
223           {
224             int ch = getc (finput);
225             if (ch == EOF)
226               break;
227             if (ch == '\n')
228               {
229                 linebuf[charpos] = 0;
230                 gcc_assert (i < num_files);             
231                 /* ???  Perhaps we should use lrealpath() here.  Doing
232                    so would tidy up things like /../ but the rest of
233                    gcc seems to assume relative pathnames, not
234                    absolute pathnames.  */
235 /*              realname = lrealpath (linebuf); */
236                 filenames[i++] = reverse (linebuf);
237                 charpos = 0;
238                 continue;
239               }
240             gcc_assert (charpos < longest_line);
241             linebuf[charpos++] = ch;
242           }
243
244         if (num_files > 1)
245           qsort (filenames, num_files, sizeof (char *), cmpstringp);
246       }
247       fclose (finput);
248     }
249   else
250     {
251       filenames = XNEWVEC (char *, 1);      
252       filenames[0] = reverse (fsource_filename);
253       num_files = 1;
254     }
255 }
256
257 /* Given a relative pathname such as foo/bar.java, attempt to find a
258    longer pathname with the same suffix.  
259
260    This is a best guess heuristic; with some weird class hierarchies we
261    may fail to pick the correct source file.  For example, if we have
262    the filenames foo/bar.java and also foo/foo/bar.java, we do not
263    have enough information to know which one is the right match for
264    foo/bar.java.  */
265
266 static const char *
267 find_sourcefile (const char *name)
268 {
269   int i = 0, j = num_files-1;
270   char *found = NULL;
271   
272   if (filenames)
273     {
274       char *revname = reverse (name);
275
276       do
277         {
278           int k = (i+j) / 2;
279           int cmp = strncmp (revname, filenames[k], strlen (revname));
280           if (cmp == 0)
281             {
282               /*  OK, so we found one.  But is it a unique match?  */
283               if ((k > i
284                    && strncmp (revname, filenames[k-1], strlen (revname)) == 0)
285                   || (k < j
286                       && (strncmp (revname, filenames[k+1], strlen (revname)) 
287                           == 0)))
288                 ;
289               else
290                 found = filenames[k];
291               break;
292             }
293           if (cmp > 0)
294             i = k+1;
295           else
296             j = k-1;
297         }
298       while (i <= j);
299
300       free (revname);
301     }
302
303   if (found && strlen (found) > strlen (name))
304     return reverse (found);
305   else
306     return name;
307 }
308
309 \f
310
311 /* Handle "SourceFile" attribute. */
312
313 static void
314 set_source_filename (JCF *jcf, int index)
315 {
316   tree sfname_id = get_name_constant (jcf, index);
317   const char *sfname = IDENTIFIER_POINTER (sfname_id);
318   const char *old_filename = input_filename;
319   int new_len = IDENTIFIER_LENGTH (sfname_id);
320   if (old_filename != NULL)
321     {
322       int old_len = strlen (old_filename);
323       /* Use the current input_filename (derived from the class name)
324          if it has a directory prefix, but otherwise matches sfname. */
325       if (old_len > new_len
326           && strcmp (sfname, old_filename + old_len - new_len) == 0
327           && (old_filename[old_len - new_len - 1] == '/'
328               || old_filename[old_len - new_len - 1] == '\\'))
329         return;
330     }
331   if (strchr (sfname, '/') == NULL && strchr (sfname, '\\') == NULL)
332     {
333       const char *class_name
334         = IDENTIFIER_POINTER (DECL_NAME (TYPE_NAME (current_class)));
335       const char *dot = strrchr (class_name, '.');
336       if (dot != NULL)
337         {
338           /* Length of prefix, not counting final dot. */
339           int i = dot - class_name;
340           /* Concatenate current package prefix with new sfname. */
341           char *buf = XNEWVEC (char, i + new_len + 2); /* Space for '.' and '\0'. */
342           strcpy (buf + i + 1, sfname);
343           /* Copy package from class_name, replacing '.' by DIR_SEPARATOR.
344              Note we start at the end with the final package dot. */
345           for (; i >= 0;  i--)
346             {
347               char c = class_name[i];
348               if (c == '.')
349                 c = DIR_SEPARATOR;
350               buf[i] = c;
351             }
352           sfname_id = get_identifier (buf);
353           free (buf);
354           sfname = IDENTIFIER_POINTER (sfname_id);
355         }
356     }
357       
358   sfname = find_sourcefile (sfname);
359   line_table->maps[line_table->used-1].to_file = sfname;
360   if (current_class == main_class) main_input_filename = sfname;
361 }
362
363
364 \f
365
366 /* Annotation handling.  
367
368    The technique we use here is to copy the annotation data directly
369    from the input class file into the output file.  We don't decode the
370    data at all, merely rewriting constant indexes whenever we come
371    across them: this is necessary because the constant pool in the
372    output file isn't the same as the constant pool in in the input.
373
374    The main advantage of this technique is that the resulting
375    annotation data is pointer-free, so it doesn't have to be relocated
376    at startup time.  As a consequence of this, annotations have no
377    performance impact unless they are used.  Also, this representation
378    is very dense.  */
379
380
381 /* Expand TYPE_REFLECTION_DATA by DELTA bytes.  Return the address of
382    the start of the newly allocated region.  */
383
384 static unsigned char*
385 annotation_grow (int delta)
386 {
387   unsigned char **data = &TYPE_REFLECTION_DATA (current_class);
388   long *datasize = &TYPE_REFLECTION_DATASIZE (current_class);
389   long len = *datasize;
390
391   if (*data == NULL)
392     {
393       *data = XNEWVAR (unsigned char, delta);
394     }
395   else
396     {
397       int newlen = *datasize + delta;
398       if (floor_log2 (newlen) != floor_log2 (*datasize))
399         *data = XRESIZEVAR (unsigned char, *data,  2 << (floor_log2 (newlen)));
400     }
401   *datasize += delta;
402   return *data + len;
403 }
404
405 /* annotation_rewrite_TYPE.  Rewrite various int types at p.  Use Java
406    byte order (i.e. big endian.)  */
407
408 static void
409 annotation_rewrite_byte (unsigned int n, unsigned char *p)
410 {
411   p[0] = n;
412 }
413
414 static void
415 annotation_rewrite_short (unsigned int n, unsigned char *p)
416 {
417   p[0] = n>>8;
418   p[1] = n;
419 }
420
421 static void
422 annotation_rewrite_int (unsigned int n, unsigned char *p)
423 {
424   p[0] = n>>24;
425   p[1] = n>>16;
426   p[2] = n>>8;
427   p[3] = n;
428 }
429
430 /* Read a 16-bit unsigned int in Java byte order (i.e. big
431    endian.)  */
432
433 static uint16
434 annotation_read_short (unsigned char *p)
435 {
436   uint16 tmp = p[0];
437   tmp = (tmp << 8) | p[1];
438   return tmp;
439 }
440
441 /* annotation_write_TYPE.  Rewrite various int types, appending them
442    to TYPE_REFLECTION_DATA.  Use Java byte order (i.e. big
443    endian.)  */
444
445 static void
446 annotation_write_byte (unsigned int n)
447 {
448   annotation_rewrite_byte (n, annotation_grow (1));
449 }
450
451 static void
452 annotation_write_short (unsigned int n)
453 {
454   annotation_rewrite_short (n, annotation_grow (2));
455 }
456
457 static void
458 annotation_write_int (unsigned int n)
459 {
460   annotation_rewrite_int (n, annotation_grow (4));
461 }
462
463 /* Create a 64-bit constant in the constant pool.
464
465    This is used for both integer and floating-point types.  As a
466    consequence, it will not work if the target floating-point format
467    is anything other than IEEE-754.  While this is arguably a bug, the
468    runtime library makes exactly the same assumption and it's unlikely
469    that Java will ever run on a non-IEEE machine.  */
470
471 static int 
472 handle_long_constant (JCF *jcf, CPool *cpool, enum cpool_tag kind,
473                     int index, bool big_endian)
474 {
475   /* If we're on a 64-bit platform we can fit a long or double
476      into the same space as a jword.  */
477   if (POINTER_SIZE >= 64)
478     index = find_constant1 (cpool, kind, JPOOL_LONG (jcf, index));
479
480   /* In a compiled program the constant pool is in native word
481      order.  How weird is that???  */
482   else if (big_endian)
483     index = find_constant2 (cpool, kind,
484                             JPOOL_INT (jcf, index), 
485                             JPOOL_INT (jcf, index+1));
486   else
487     index = find_constant2 (cpool, kind,
488                             JPOOL_INT (jcf, index+1), 
489                             JPOOL_INT (jcf, index));
490   
491   return index;
492 }
493
494 /* Given a class file and an index into its constant pool, create an
495    entry in the outgoing constant pool for the same item.  */
496
497 static uint16
498 handle_constant (JCF *jcf, int index, enum cpool_tag purpose)
499 {
500   unsigned int kind;
501   CPool *cpool = cpool_for_class (output_class);
502   
503   if (index == 0)
504     return 0;
505
506   if (! CPOOL_INDEX_IN_RANGE (&jcf->cpool, index))
507     error ("<constant pool index %d not in range>", index);
508   
509   kind = JPOOL_TAG (jcf, index);
510
511   if ((kind & ~CONSTANT_ResolvedFlag) != purpose)
512     {
513       if (purpose == CONSTANT_Class
514           && kind == CONSTANT_Utf8)
515         ;
516       else
517         error ("<constant pool index %d unexpected type", index);
518     }
519
520   switch (kind)
521     {
522     case CONSTANT_Class:
523     case CONSTANT_ResolvedClass:
524       {
525         /* For some reason I know not the what of, class names in
526            annotations are UTF-8 strings in the constant pool but
527            class names in EnclosingMethod attributes are real class
528            references.  Set CONSTANT_LazyFlag here so that the VM
529            doesn't attempt to resolve them at class initialization
530            time.  */
531         tree resolved_class, class_name;
532         resolved_class = get_class_constant (jcf, index);
533         class_name = build_internal_class_name (resolved_class);
534         index = alloc_name_constant (CONSTANT_Class | CONSTANT_LazyFlag,
535                                      (unmangle_classname 
536                                       (IDENTIFIER_POINTER(class_name),
537                                        IDENTIFIER_LENGTH(class_name))));
538         break;
539       }
540     case CONSTANT_Utf8:
541       {
542         tree utf8 = get_constant (jcf, index);
543         if (purpose == CONSTANT_Class)
544           /* Create a constant pool entry for a type signature.  This
545              one has '.' rather than '/' because it isn't going into a
546              class file, it's going into a compiled object.
547              
548              This has to match the logic in
549              _Jv_ClassReader::prepare_pool_entry().  */
550           utf8 = unmangle_classname (IDENTIFIER_POINTER(utf8),
551                                      IDENTIFIER_LENGTH(utf8));
552         index = alloc_name_constant (kind, utf8);
553       }
554       break;
555
556     case CONSTANT_Long:
557       index = handle_long_constant (jcf, cpool, CONSTANT_Long, index,
558                                     WORDS_BIG_ENDIAN);
559       break;
560       
561     case CONSTANT_Double:
562       index = handle_long_constant (jcf, cpool, CONSTANT_Double, index,
563                                     FLOAT_WORDS_BIG_ENDIAN);
564       break;
565
566     case CONSTANT_Float:
567     case CONSTANT_Integer:
568       index = find_constant1 (cpool, kind, JPOOL_INT (jcf, index));
569       break;
570       
571     case CONSTANT_NameAndType:
572       {
573         uint16 name = JPOOL_USHORT1 (jcf, index);
574         uint16 sig = JPOOL_USHORT2 (jcf, index);
575         uint32 name_index = handle_constant (jcf, name, CONSTANT_Utf8);
576         uint32 sig_index = handle_constant (jcf, sig, CONSTANT_Class);
577         jword new_index = (name_index << 16) | sig_index;
578         index = find_constant1 (cpool, kind, new_index);
579       }
580       break;
581
582     default:
583       abort ();
584     }
585   
586   return index;
587 }
588
589 /* Read an element_value structure from an annotation in JCF.  Return
590    the constant pool index for the resulting constant pool entry.  */
591
592 static int
593 handle_element_value (JCF *jcf, int level)
594 {
595   uint8 tag = JCF_readu (jcf);
596   int index = 0;
597
598   annotation_write_byte (tag);
599   switch (tag)
600     {
601     case 'B':
602     case 'C':
603     case 'S':
604     case 'Z':
605     case 'I':
606       {
607         uint16 cindex = JCF_readu2 (jcf);
608         index = handle_constant (jcf, cindex,
609                                  CONSTANT_Integer);
610         annotation_write_short (index);
611       }
612       break;
613     case 'D':
614       {
615         uint16 cindex = JCF_readu2 (jcf);
616         index = handle_constant (jcf, cindex,
617                                  CONSTANT_Double);
618         annotation_write_short (index);
619       }
620       break;
621     case 'F':
622       {
623         uint16 cindex = JCF_readu2 (jcf);
624         index = handle_constant (jcf, cindex,
625                                  CONSTANT_Float);
626         annotation_write_short (index);
627       }
628       break;
629     case 'J':
630       {
631         uint16 cindex = JCF_readu2 (jcf);
632         index = handle_constant (jcf, cindex,
633                                  CONSTANT_Long);
634         annotation_write_short (index);
635       }
636       break;
637     case 's':
638       {
639         uint16 cindex = JCF_readu2 (jcf);
640         /* Despite what the JVM spec says, compilers generate a Utf8
641            constant here, not a String.  */
642         index = handle_constant (jcf, cindex,
643                                  CONSTANT_Utf8);
644         annotation_write_short (index);
645       }
646       break;
647
648     case 'e':
649       {
650         uint16 type_name_index = JCF_readu2 (jcf);
651         uint16 const_name_index = JCF_readu2 (jcf);
652         index = handle_constant (jcf, type_name_index,
653                                  CONSTANT_Class);
654         annotation_write_short (index);
655         index = handle_constant (jcf, const_name_index,
656                                  CONSTANT_Utf8);
657         annotation_write_short (index);
658      }
659       break;
660     case 'c':
661       {
662         uint16 class_info_index = JCF_readu2 (jcf);
663         index = handle_constant (jcf, class_info_index,
664                                  CONSTANT_Class);
665         annotation_write_short (index);
666       }
667       break;
668     case '@':
669       {
670         handle_annotation (jcf, level + 1);
671       }
672       break;
673     case '[':
674       {
675         uint16 n_array_elts = JCF_readu2 (jcf);
676         annotation_write_short (n_array_elts);
677         while (n_array_elts--)
678           handle_element_value (jcf, level + 1);
679       }
680       break;
681     default:
682       abort();
683       break;
684     }
685   return index;
686 }
687
688 /* Read an annotation structure from JCF.  Write it to the
689    reflection_data field of the outgoing class.  */
690
691 static void
692 handle_annotation (JCF *jcf, int level)
693 {
694   uint16 type_index = JCF_readu2 (jcf);
695   uint16 npairs = JCF_readu2 (jcf);
696   int index = handle_constant (jcf, type_index,
697                                CONSTANT_Class);
698   annotation_write_short (index);
699   annotation_write_short (npairs);
700   while (npairs--)
701     {
702       uint16 name_index = JCF_readu2 (jcf);
703       index = handle_constant (jcf, name_index,
704                                CONSTANT_Utf8);
705       annotation_write_short (index);
706       handle_element_value (jcf, level + 2);
707     }
708 }
709
710 /* Read an annotation count from JCF, and write the following
711    annotations to the reflection_data field of the outgoing class.  */
712
713 static void
714 handle_annotations (JCF *jcf, int level)
715 {
716   uint16 num = JCF_readu2 (jcf);
717   annotation_write_short (num);
718   while (num--)
719     handle_annotation (jcf, level);
720 }
721
722 /* As handle_annotations(), but perform a sanity check that we write
723    the same number of bytes that we were expecting.  */
724
725 static void
726 handle_annotation_attribute (int ATTRIBUTE_UNUSED index, JCF *jcf, 
727                              long length)
728 {
729   long old_datasize = TYPE_REFLECTION_DATASIZE (current_class);
730
731   handle_annotations (jcf, 0);
732
733   gcc_assert (old_datasize + length
734               == TYPE_REFLECTION_DATASIZE (current_class));
735 }
736
737 /* gcj permutes its fields array after generating annotation_data, so
738    we have to fixup field indexes for fields that have moved.  Given
739    ARG, a VEC_int, fixup the field indexes in the reflection_data of
740    the outgoing class.  We use field_offsets to tell us where the
741    fixups must go.  */
742
743 void
744 rewrite_reflection_indexes (void *arg)
745 {
746   bitmap_iterator bi;
747   unsigned int offset;
748   VEC(int, heap) *map = (VEC(int, heap) *) arg;
749   unsigned char *data = TYPE_REFLECTION_DATA (current_class);
750
751   if (map)
752     {
753       EXECUTE_IF_SET_IN_BITMAP (field_offsets, 0, offset, bi)
754         {
755           uint16 index = annotation_read_short (data + offset);
756           annotation_rewrite_short 
757             (VEC_index (int, map, index), data + offset);
758         }
759     }
760 }
761
762 /* Read the RuntimeVisibleAnnotations from JCF and write them to the
763    reflection_data of the outgoing class.  */
764
765 static void
766 handle_member_annotations (int member_index, JCF *jcf, 
767                            const unsigned char *name ATTRIBUTE_UNUSED, 
768                            long len, jv_attr_type member_type)
769 {
770   int new_len = len + 1;
771   annotation_write_byte (member_type);
772   if (member_type != JV_CLASS_ATTR)
773     new_len += 2;
774   annotation_write_int (new_len);
775   annotation_write_byte (JV_ANNOTATIONS_KIND);
776   if (member_type == JV_FIELD_ATTR)
777     bitmap_set_bit (field_offsets, TYPE_REFLECTION_DATASIZE (current_class));
778   if (member_type != JV_CLASS_ATTR)
779     annotation_write_short (member_index);
780   handle_annotation_attribute (member_index, jcf, len);
781 }
782
783 /* Read the RuntimeVisibleParameterAnnotations from JCF and write them
784    to the reflection_data of the outgoing class.  */
785
786 static void
787 handle_parameter_annotations (int member_index, JCF *jcf, 
788                               const unsigned char *name ATTRIBUTE_UNUSED, 
789                               long len, jv_attr_type member_type)
790 {
791   int new_len = len + 1;
792   uint8 num;
793   annotation_write_byte (member_type);
794   if (member_type != JV_CLASS_ATTR)
795     new_len += 2;
796   annotation_write_int (new_len);
797   annotation_write_byte (JV_PARAMETER_ANNOTATIONS_KIND);
798   if (member_type != JV_CLASS_ATTR)
799     annotation_write_short (member_index);
800   num = JCF_readu (jcf);
801   annotation_write_byte (num);
802   while (num--)
803     handle_annotations (jcf, 0);
804 }
805
806
807 /* Read the AnnotationDefault data from JCF and write them to the
808    reflection_data of the outgoing class.  */
809
810 static void
811 handle_default_annotation (int member_index, JCF *jcf, 
812                            const unsigned char *name ATTRIBUTE_UNUSED, 
813                            long len, jv_attr_type member_type)
814 {
815   int new_len = len + 1;
816   annotation_write_byte (member_type);
817   if (member_type != JV_CLASS_ATTR)
818     new_len += 2;
819   annotation_write_int (new_len);
820   annotation_write_byte (JV_ANNOTATION_DEFAULT_KIND);
821   if (member_type != JV_CLASS_ATTR)
822     annotation_write_short (member_index);
823   handle_element_value (jcf, 0);
824 }
825
826 /* As above, for the EnclosingMethod attribute.  */
827
828 static void
829 handle_enclosingmethod_attribute (int member_index, JCF *jcf, 
830                            const unsigned char *name ATTRIBUTE_UNUSED, 
831                            long len, jv_attr_type member_type)
832 {
833   int new_len = len + 1;
834   uint16 index;
835   annotation_write_byte (member_type);
836   if (member_type != JV_CLASS_ATTR)
837     new_len += 2;
838   annotation_write_int (new_len);
839   annotation_write_byte (JV_ENCLOSING_METHOD_KIND);
840   if (member_type != JV_CLASS_ATTR)
841     annotation_write_short (member_index);
842
843   index = JCF_readu2 (jcf);
844   index = handle_constant (jcf, index, CONSTANT_Class);
845   annotation_write_short (index);
846
847   index = JCF_readu2 (jcf);
848   index = handle_constant (jcf, index, CONSTANT_NameAndType);
849   annotation_write_short (index);
850 }
851
852 /* As above, for the Signature attribute.  */
853
854 static void
855 handle_signature_attribute (int member_index, JCF *jcf, 
856                            const unsigned char *name ATTRIBUTE_UNUSED, 
857                            long len, jv_attr_type member_type)
858 {
859   int new_len = len + 1;
860   uint16 index;
861   annotation_write_byte (member_type);
862   if (member_type != JV_CLASS_ATTR)
863     new_len += 2;
864   annotation_write_int (new_len);
865   annotation_write_byte (JV_SIGNATURE_KIND);
866   if (member_type != JV_CLASS_ATTR)
867     annotation_write_short (member_index);
868
869   index = JCF_readu2 (jcf);
870   index = handle_constant (jcf, index, CONSTANT_Utf8);
871   annotation_write_short (index);
872 }
873   
874 \f
875
876 #define HANDLE_SOURCEFILE(INDEX) set_source_filename (jcf, INDEX)
877
878 #define HANDLE_CLASS_INFO(ACCESS_FLAGS, THIS, SUPER, INTERFACES_COUNT) \
879 { tree super_class = SUPER==0 ? NULL_TREE : get_class_constant (jcf, SUPER); \
880   output_class = current_class = give_name_to_class (jcf, THIS); \
881   set_super_info (ACCESS_FLAGS, current_class, super_class, INTERFACES_COUNT);}
882
883 #define HANDLE_CLASS_INTERFACE(INDEX) \
884   add_interface (current_class, get_class_constant (jcf, INDEX))
885
886 #define HANDLE_START_FIELD(ACCESS_FLAGS, NAME, SIGNATURE, ATTRIBUTE_COUNT) \
887 { int sig_index = SIGNATURE; \
888   current_field = add_field (current_class, get_name_constant (jcf, NAME), \
889                              parse_signature (jcf, sig_index), ACCESS_FLAGS); \
890  set_java_signature (TREE_TYPE (current_field), JPOOL_UTF (jcf, sig_index)); \
891  if ((ACCESS_FLAGS) & ACC_FINAL) \
892    MAYBE_CREATE_VAR_LANG_DECL_SPECIFIC (current_field); \
893 }
894
895 #define HANDLE_END_FIELDS() \
896   (current_field = NULL_TREE)
897
898 #define HANDLE_CONSTANTVALUE(INDEX) \
899 { tree constant;  int index = INDEX; \
900   if (JPOOL_TAG (jcf, index) == CONSTANT_String) { \
901     tree name = get_name_constant (jcf, JPOOL_USHORT1 (jcf, index)); \
902     constant = build_utf8_ref (name); \
903   } \
904   else \
905     constant = get_constant (jcf, index); \
906   set_constant_value (current_field, constant); }
907
908 #define HANDLE_METHOD(ACCESS_FLAGS, NAME, SIGNATURE, ATTRIBUTE_COUNT) \
909  (current_method = add_method (current_class, ACCESS_FLAGS, \
910                                get_name_constant (jcf, NAME), \
911                                get_name_constant (jcf, SIGNATURE)), \
912   DECL_LOCALVARIABLES_OFFSET (current_method) = 0, \
913   DECL_LINENUMBERS_OFFSET (current_method) = 0)
914
915 #define HANDLE_END_METHODS() \
916 { current_method = NULL_TREE; }
917
918 #define HANDLE_CODE_ATTRIBUTE(MAX_STACK, MAX_LOCALS, CODE_LENGTH) \
919 { DECL_MAX_STACK (current_method) = (MAX_STACK); \
920   DECL_MAX_LOCALS (current_method) = (MAX_LOCALS); \
921   DECL_CODE_LENGTH (current_method) = (CODE_LENGTH); \
922   DECL_CODE_OFFSET (current_method) = JCF_TELL (jcf); }
923
924 #define HANDLE_LOCALVARIABLETABLE_ATTRIBUTE(COUNT) \
925 { int n = (COUNT); \
926   DECL_LOCALVARIABLES_OFFSET (current_method) = JCF_TELL (jcf) - 2; \
927   JCF_SKIP (jcf, n * 10); }
928
929 #define HANDLE_LINENUMBERTABLE_ATTRIBUTE(COUNT) \
930 { int n = (COUNT); \
931   DECL_LINENUMBERS_OFFSET (current_method) = JCF_TELL (jcf) - 2; \
932   JCF_SKIP (jcf, n * 4); }
933
934 #define HANDLE_EXCEPTIONS_ATTRIBUTE(COUNT) \
935 { \
936   int n = COUNT; \
937   VEC (tree,gc) *v = VEC_alloc (tree, gc, n); \
938   gcc_assert (DECL_FUNCTION_THROWS (current_method) == NULL); \
939   while (--n >= 0) \
940     { \
941       tree thrown_class = get_class_constant (jcf, JCF_readu2 (jcf)); \
942       VEC_quick_push (tree, v, thrown_class); \
943     } \
944   DECL_FUNCTION_THROWS (current_method) = v; \
945 }
946
947 #define HANDLE_DEPRECATED_ATTRIBUTE()  handle_deprecated ()
948
949 /* Link seen inner classes to their outer context and register the
950    inner class to its outer context. They will be later loaded.  */
951 #define HANDLE_INNERCLASSES_ATTRIBUTE(COUNT) \
952   handle_innerclass_attribute (COUNT, jcf, attribute_length)
953
954 #define HANDLE_SYNTHETIC_ATTRIBUTE()                                    \
955 {                                                                       \
956   /* Irrelevant decls should have been nullified by the END macros.     \
957      DECL_ARTIFICIAL on fields is used for something else (See          \
958      PUSH_FIELD in java-tree.h) */                                      \
959   if (current_method)                                                   \
960     DECL_ARTIFICIAL (current_method) = 1;                               \
961   else if (current_field)                                               \
962     FIELD_SYNTHETIC (current_field) = 1;                                \
963   else                                                                  \
964     TYPE_SYNTHETIC (current_class) = 1;                                 \
965 }
966
967 #define HANDLE_GCJCOMPILED_ATTRIBUTE()          \
968 {                                               \
969   if (current_class == object_type_node)        \
970     jcf->right_zip = 1;                         \
971 }
972
973 #define HANDLE_RUNTIMEVISIBLEANNOTATIONS_ATTRIBUTE()                    \
974 {                                                                       \
975   handle_member_annotations (index, jcf, name_data, attribute_length, attr_type); \
976 }
977
978 #define HANDLE_RUNTIMEINVISIBLEANNOTATIONS_ATTRIBUTE()  \
979 {                                                       \
980   JCF_SKIP(jcf, attribute_length);                      \
981 }
982
983 #define HANDLE_RUNTIMEVISIBLEPARAMETERANNOTATIONS_ATTRIBUTE()           \
984 {                                                                       \
985   handle_parameter_annotations (index, jcf, name_data, attribute_length, attr_type); \
986 }
987
988 #define HANDLE_RUNTIMEINVISIBLEPARAMETERANNOTATIONS_ATTRIBUTE() \
989 {                                                               \
990   JCF_SKIP(jcf, attribute_length);                              \
991 }
992
993 #define HANDLE_ANNOTATIONDEFAULT_ATTRIBUTE()                            \
994 {                                                                       \
995   handle_default_annotation (index, jcf, name_data, attribute_length, attr_type); \
996 }
997
998 #define HANDLE_ENCLOSINGMETHOD_ATTRIBUTE()                              \
999 {                                                                       \
1000   handle_enclosingmethod_attribute (index, jcf, name_data,              \
1001                                     attribute_length, attr_type);       \
1002 }
1003
1004 #define HANDLE_SIGNATURE_ATTRIBUTE()                            \
1005 {                                                               \
1006   handle_signature_attribute (index, jcf, name_data,            \
1007                               attribute_length, attr_type);     \
1008 }
1009
1010 #include "jcf-reader.c"
1011
1012 tree
1013 parse_signature (JCF *jcf, int sig_index)
1014 {
1015   gcc_assert (sig_index > 0
1016               && sig_index < JPOOL_SIZE (jcf)
1017               && JPOOL_TAG (jcf, sig_index) == CONSTANT_Utf8);
1018
1019   return parse_signature_string (JPOOL_UTF_DATA (jcf, sig_index),
1020                                  JPOOL_UTF_LENGTH (jcf, sig_index));
1021 }
1022
1023 tree
1024 get_constant (JCF *jcf, int index)
1025 {
1026   tree value;
1027   int tag;
1028   if (index <= 0 || index >= JPOOL_SIZE(jcf))
1029     goto bad;
1030   tag = JPOOL_TAG (jcf, index);
1031   if ((tag & CONSTANT_ResolvedFlag) || tag == CONSTANT_Utf8)
1032     return jcf->cpool.data[index].t;
1033   switch (tag)
1034     {
1035     case CONSTANT_Integer:
1036       {
1037         jint num = JPOOL_INT(jcf, index);
1038         value = build_int_cst (int_type_node, num);
1039         break;
1040       }
1041     case CONSTANT_Long:
1042       {
1043         unsigned HOST_WIDE_INT num;
1044         double_int val;
1045
1046         num = JPOOL_UINT (jcf, index);
1047         val = double_int_lshift (uhwi_to_double_int (num), 32, 64, false);
1048         num = JPOOL_UINT (jcf, index + 1);
1049         val = double_int_ior (val, uhwi_to_double_int (num));
1050
1051         value = double_int_to_tree (long_type_node, val);
1052         break;
1053       }
1054
1055     case CONSTANT_Float:
1056       {
1057         jint num = JPOOL_INT(jcf, index);
1058         long buf = num;
1059         REAL_VALUE_TYPE d;
1060
1061         real_from_target_fmt (&d, &buf, &ieee_single_format);
1062         value = build_real (float_type_node, d);
1063         break;
1064       }
1065
1066     case CONSTANT_Double:
1067       {
1068         long buf[2], lo, hi;
1069         REAL_VALUE_TYPE d;
1070
1071         hi = JPOOL_UINT (jcf, index);
1072         lo = JPOOL_UINT (jcf, index+1);
1073
1074         if (FLOAT_WORDS_BIG_ENDIAN)
1075           buf[0] = hi, buf[1] = lo;
1076         else
1077           buf[0] = lo, buf[1] = hi;
1078
1079         real_from_target_fmt (&d, buf, &ieee_double_format);
1080         value = build_real (double_type_node, d);
1081         break;
1082       }
1083
1084     case CONSTANT_String:
1085       {
1086         tree name = get_name_constant (jcf, JPOOL_USHORT1 (jcf, index));
1087         const char *utf8_ptr = IDENTIFIER_POINTER (name);
1088         int utf8_len = IDENTIFIER_LENGTH (name);
1089         const unsigned char *utf8;
1090         int i;
1091
1092         /* Check for a malformed Utf8 string.  */
1093         utf8 = (const unsigned char *) utf8_ptr;
1094         i = utf8_len;
1095         while (i > 0)
1096           {
1097             int char_len = UT8_CHAR_LENGTH (*utf8);
1098             if (char_len < 0 || char_len > 3 || char_len > i)
1099               fatal_error ("bad string constant");
1100
1101             utf8 += char_len;
1102             i -= char_len;
1103           }
1104
1105         /* Allocate a new string value.  */
1106         value = build_string (utf8_len, utf8_ptr);
1107         TREE_TYPE (value) = build_pointer_type (string_type_node);
1108       }
1109       break;
1110     default:
1111       goto bad;
1112     }
1113   JPOOL_TAG (jcf, index) = tag | CONSTANT_ResolvedFlag;
1114   jcf->cpool.data[index].t = value;
1115   return value;
1116  bad:
1117   internal_error ("bad value constant type %d, index %d", 
1118                   JPOOL_TAG (jcf, index), index);
1119 }
1120
1121 tree
1122 get_name_constant (JCF *jcf, int index)
1123 {
1124   tree name = get_constant (jcf, index);
1125   gcc_assert (TREE_CODE (name) == IDENTIFIER_NODE);
1126   return name;
1127 }
1128
1129 /* Handle reading innerclass attributes. If a nonzero entry (denoting
1130    a non anonymous entry) is found, We augment the inner class list of
1131    the outer context with the newly resolved innerclass.  */
1132
1133 static void
1134 handle_innerclass_attribute (int count, JCF *jcf, int attribute_length)
1135 {
1136   int c = count;
1137
1138   annotation_write_byte (JV_CLASS_ATTR);
1139   annotation_write_int (attribute_length+1);
1140   annotation_write_byte (JV_INNER_CLASSES_KIND);
1141   annotation_write_short (count);
1142
1143   while (c--)
1144     {
1145       /* Read inner_class_info_index. This may be 0 */
1146       int icii = JCF_readu2 (jcf);
1147       /* Read outer_class_info_index. If the innerclasses attribute
1148          entry isn't a member (like an inner class) the value is 0. */
1149       int ocii = JCF_readu2 (jcf);
1150       /* Read inner_name_index. If the class we're dealing with is
1151          an anonymous class, it must be 0. */
1152       int ini = JCF_readu2 (jcf);
1153       /* Read the access flag. */
1154       int acc = JCF_readu2 (jcf);
1155
1156       annotation_write_short (handle_constant (jcf, icii, CONSTANT_Class));
1157       annotation_write_short (handle_constant (jcf, ocii, CONSTANT_Class));
1158       annotation_write_short (handle_constant (jcf, ini, CONSTANT_Utf8));
1159       annotation_write_short (acc);
1160
1161       /* If icii is 0, don't try to read the class. */
1162       if (icii >= 0)
1163         {
1164           tree klass = get_class_constant (jcf, icii);
1165           tree decl = TYPE_NAME (klass);
1166           /* Skip reading further if ocii is null */
1167           if (DECL_P (decl) && !CLASS_COMPLETE_P (decl) && ocii)
1168             {
1169               tree outer = TYPE_NAME (get_class_constant (jcf, ocii));
1170               tree alias = (ini ? get_name_constant (jcf, ini) : NULL_TREE);
1171               set_class_decl_access_flags (acc, decl);
1172               DECL_CONTEXT (decl) = outer;
1173               DECL_INNER_CLASS_LIST (outer) =
1174                 tree_cons (decl, alias, DECL_INNER_CLASS_LIST (outer));
1175               CLASS_COMPLETE_P (decl) = 1;
1176             }
1177         }
1178     }
1179 }
1180
1181 static tree
1182 give_name_to_class (JCF *jcf, int i)
1183 {
1184   gcc_assert (i > 0
1185               && i < JPOOL_SIZE (jcf)
1186               && JPOOL_TAG (jcf, i) == CONSTANT_Class);
1187
1188     {
1189       tree package_name = NULL_TREE, tmp;
1190       tree this_class;
1191       int j = JPOOL_USHORT1 (jcf, i);
1192       /* verify_constant_pool confirmed that j is a CONSTANT_Utf8. */
1193       tree class_name = unmangle_classname ((const char *) JPOOL_UTF_DATA (jcf, j),
1194                                             JPOOL_UTF_LENGTH (jcf, j));
1195       this_class = lookup_class (class_name);
1196       {
1197       tree source_name = identifier_subst (class_name, "", '.', '/', ".java");
1198       const char *sfname = find_sourcefile (IDENTIFIER_POINTER (source_name));
1199       linemap_add (line_table, LC_ENTER, false, sfname, 0);
1200       input_location = linemap_line_start (line_table, 0, 1);
1201       file_start_location = input_location;
1202       DECL_SOURCE_LOCATION (TYPE_NAME (this_class)) = input_location;
1203       if (main_input_filename == NULL && jcf == main_jcf)
1204         main_input_filename = sfname;
1205       }
1206
1207       jcf->cpool.data[i].t = this_class;
1208       JPOOL_TAG (jcf, i) = CONSTANT_ResolvedClass;
1209       split_qualified_name (&package_name, &tmp, 
1210                             DECL_NAME (TYPE_NAME (this_class)));
1211       TYPE_PACKAGE (this_class) = package_name;
1212       return this_class;
1213     }
1214 }
1215
1216 /* Get the class of the CONSTANT_Class whose constant pool index is I. */
1217
1218 tree
1219 get_class_constant (JCF *jcf, int i)
1220 {
1221   tree type;
1222   gcc_assert (i > 0
1223               && i < JPOOL_SIZE (jcf)
1224               && (JPOOL_TAG (jcf, i) & ~CONSTANT_ResolvedFlag) == CONSTANT_Class);
1225
1226   if (JPOOL_TAG (jcf, i) != CONSTANT_ResolvedClass)
1227     {
1228       int name_index = JPOOL_USHORT1 (jcf, i);
1229       /* verify_constant_pool confirmed that name_index is a CONSTANT_Utf8. */
1230       const char *name = (const char *) JPOOL_UTF_DATA (jcf, name_index);
1231       int nlength = JPOOL_UTF_LENGTH (jcf, name_index);
1232
1233       if (name[0] == '[')  /* Handle array "classes". */
1234           type = TREE_TYPE (parse_signature_string ((const unsigned char *) name, nlength));
1235       else
1236         { 
1237           tree cname = unmangle_classname (name, nlength);
1238           type = lookup_class (cname);
1239         }
1240       jcf->cpool.data[i].t = type;
1241       JPOOL_TAG (jcf, i) = CONSTANT_ResolvedClass;
1242     }
1243   else
1244     type = jcf->cpool.data[i].t;
1245   return type;
1246 }
1247
1248 /* Read a class with the fully qualified-name NAME.
1249    Return 1 iff we read the requested file.
1250    (It is still possible we failed if the file did not
1251    define the class it is supposed to.) */
1252
1253 int
1254 read_class (tree name)
1255 {
1256   JCF this_jcf, *jcf;
1257   tree icv, klass = NULL_TREE;
1258   tree save_current_class = current_class;
1259   tree save_output_class = output_class;
1260   location_t save_location = input_location;
1261   JCF *save_current_jcf = current_jcf;
1262
1263   if ((icv = IDENTIFIER_CLASS_VALUE (name)) != NULL_TREE)
1264     {
1265       klass = TREE_TYPE (icv);
1266       jcf = TYPE_JCF (klass);
1267     }
1268   else
1269     jcf = NULL;
1270
1271   if (jcf == NULL)
1272     {
1273       const char* path_name;
1274       this_jcf.zipd = NULL;
1275       jcf = &this_jcf;
1276       
1277       path_name = find_class (IDENTIFIER_POINTER (name),
1278                               IDENTIFIER_LENGTH (name),
1279                               &this_jcf);
1280       if (path_name == 0)
1281         return 0;
1282       else
1283         free(CONST_CAST (char *, path_name));
1284     }
1285
1286   current_jcf = jcf;
1287
1288   if (klass == NULL_TREE || ! CLASS_PARSED_P (klass))
1289     {
1290       output_class = current_class = klass;
1291       if (JCF_SEEN_IN_ZIP (current_jcf))
1292         read_zip_member(current_jcf,
1293                         current_jcf->zipd, current_jcf->zipd->zipf);
1294       jcf_parse (current_jcf);
1295       /* Parsing might change the class, in which case we have to
1296          put it back where we found it.  */
1297       if (current_class != klass && icv != NULL_TREE)
1298         TREE_TYPE (icv) = current_class;
1299       klass = current_class;
1300     }
1301   layout_class (klass);
1302   load_inner_classes (klass);
1303
1304   output_class = save_output_class;
1305   current_class = save_current_class;
1306   input_location = save_location;
1307   current_jcf = save_current_jcf;
1308   return 1;
1309 }
1310
1311 /* Load CLASS_OR_NAME. CLASS_OR_NAME can be a mere identifier if
1312    called from the parser, otherwise it's a RECORD_TYPE node. If
1313    VERBOSE is 1, print error message on failure to load a class. */
1314 void
1315 load_class (tree class_or_name, int verbose)
1316 {
1317   tree name, saved;
1318   int class_loaded = 0;
1319   tree class_decl = NULL_TREE;
1320   bool is_compiled_class = false;
1321
1322   /* We've already failed, don't try again.  */
1323   if (TREE_CODE (class_or_name) == RECORD_TYPE
1324       && TYPE_DUMMY (class_or_name))
1325     return;
1326
1327   /* class_or_name can be the name of the class we want to load */
1328   if (TREE_CODE (class_or_name) == IDENTIFIER_NODE)
1329     name = class_or_name;
1330   /* In some cases, it's a dependency that we process earlier that
1331      we though */
1332   else if (TREE_CODE (class_or_name) == TREE_LIST)
1333     name = TYPE_NAME (TREE_PURPOSE (class_or_name));
1334   /* Or it's a type in the making */
1335   else
1336     name = DECL_NAME (TYPE_NAME (class_or_name));
1337
1338   class_decl = IDENTIFIER_CLASS_VALUE (name);
1339   if (class_decl != NULL_TREE)
1340     {
1341       tree type = TREE_TYPE (class_decl);
1342       is_compiled_class
1343         = ((TYPE_JCF (type) && JCF_SEEN_IN_ZIP (TYPE_JCF (type)))
1344            || CLASS_FROM_CURRENTLY_COMPILED_P (type));
1345     }
1346
1347   saved = name;
1348   
1349   /* If flag_verify_invocations is unset, we don't try to load a class
1350      unless we're looking for Object (which is fixed by the ABI) or
1351      it's a class that we're going to compile.  */
1352   if (flag_verify_invocations
1353       || class_or_name == object_type_node
1354       || is_compiled_class
1355       || TREE_CODE (class_or_name) == IDENTIFIER_NODE)
1356     {
1357       while (1)
1358         {
1359           const char *separator;
1360
1361           /* We've already loaded it.  */
1362           if (IDENTIFIER_CLASS_VALUE (name) != NULL_TREE)
1363             {
1364               tree tmp_decl = IDENTIFIER_CLASS_VALUE (name);
1365               if (CLASS_PARSED_P (TREE_TYPE (tmp_decl)))
1366                 break;
1367             }
1368         
1369           if (read_class (name))
1370             break;
1371
1372           /* We failed loading name. Now consider that we might be looking
1373              for an inner class.  */
1374           if ((separator = strrchr (IDENTIFIER_POINTER (name), '$'))
1375               || (separator = strrchr (IDENTIFIER_POINTER (name), '.')))
1376             name = get_identifier_with_length (IDENTIFIER_POINTER (name),
1377                                                (separator
1378                                                 - IDENTIFIER_POINTER (name)));
1379           /* Otherwise, we failed, we bail. */
1380           else
1381             break;
1382         }
1383
1384       {
1385         /* have we found the class we're looking for?  */
1386         tree type_decl = IDENTIFIER_CLASS_VALUE (saved);
1387         tree type = type_decl ? TREE_TYPE (type_decl) : NULL;
1388         class_loaded = type && CLASS_PARSED_P (type);
1389       }       
1390     }
1391   
1392   if (!class_loaded)
1393     {
1394       if (flag_verify_invocations || ! flag_indirect_dispatch)
1395         {
1396           if (verbose)
1397             error ("cannot find file for class %s", IDENTIFIER_POINTER (saved));
1398         }
1399       else if (verbose)
1400         {
1401           /* This is just a diagnostic during testing, not a real problem.  */
1402           if (!quiet_flag)
1403             warning (0, "cannot find file for class %s", 
1404                      IDENTIFIER_POINTER (saved));
1405           
1406           /* Fake it.  */
1407           if (TREE_CODE (class_or_name) == RECORD_TYPE)
1408             {
1409               set_super_info (0, class_or_name, object_type_node, 0);
1410               TYPE_DUMMY (class_or_name) = 1;
1411               /* We won't be able to output any debug info for this class.  */
1412               DECL_IGNORED_P (TYPE_NAME (class_or_name)) = 1;
1413             }
1414         }
1415     }
1416 }
1417
1418 /* Parse the .class file JCF. */
1419
1420 static void
1421 jcf_parse (JCF* jcf)
1422 {
1423   int i, code;
1424
1425   bitmap_clear (field_offsets);
1426
1427   if (jcf_parse_preamble (jcf) != 0)
1428     fatal_error ("not a valid Java .class file");
1429   code = jcf_parse_constant_pool (jcf);
1430   if (code != 0)
1431     fatal_error ("error while parsing constant pool");
1432   code = verify_constant_pool (jcf);
1433   if (code > 0)
1434     fatal_error ("error in constant pool entry #%d\n", code);
1435
1436   jcf_parse_class (jcf);
1437   if (main_class == NULL_TREE)
1438     main_class = current_class;
1439   if (! quiet_flag && TYPE_NAME (current_class))
1440     fprintf (stderr, " %s %s",
1441              (jcf->access_flags & ACC_INTERFACE) ? "interface" : "class", 
1442              IDENTIFIER_POINTER (DECL_NAME (TYPE_NAME (current_class))));
1443   if (CLASS_PARSED_P (current_class))
1444     {
1445       /* FIXME - where was first time */
1446       fatal_error ("reading class %s for the second time from %s",
1447                    IDENTIFIER_POINTER (DECL_NAME (TYPE_NAME (current_class))),
1448                    jcf->filename);
1449     }
1450   CLASS_PARSED_P (current_class) = 1;
1451
1452   for (i = 1; i < JPOOL_SIZE(jcf); i++)
1453     {
1454       switch (JPOOL_TAG (jcf, i))
1455         {
1456         case CONSTANT_Class:
1457           get_class_constant (jcf, i);
1458           break;
1459         }
1460     }
1461   
1462   code = jcf_parse_fields (jcf);
1463   if (code != 0)
1464     fatal_error ("error while parsing fields");
1465   code = jcf_parse_methods (jcf);
1466   if (code != 0)
1467     fatal_error ("error while parsing methods");
1468   code = jcf_parse_final_attributes (jcf);
1469   if (code != 0)
1470     fatal_error ("error while parsing final attributes");
1471
1472   if (TYPE_REFLECTION_DATA (current_class))
1473     annotation_write_byte (JV_DONE_ATTR);
1474
1475   linemap_add (line_table, LC_LEAVE, false, NULL, 0);
1476
1477   /* The fields of class_type_node are already in correct order. */
1478   if (current_class != class_type_node && current_class != object_type_node)
1479     TYPE_FIELDS (current_class) = nreverse (TYPE_FIELDS (current_class));
1480
1481   if (current_class == object_type_node)
1482     layout_class_methods (object_type_node);
1483   else
1484     VEC_safe_push (tree, gc, all_class_list, TYPE_NAME (current_class));
1485 }
1486
1487 /* If we came across inner classes, load them now. */
1488 static void
1489 load_inner_classes (tree cur_class)
1490 {
1491   tree current;
1492   for (current = DECL_INNER_CLASS_LIST (TYPE_NAME (cur_class)); current;
1493        current = TREE_CHAIN (current))
1494     {
1495       tree name = DECL_NAME (TREE_PURPOSE (current));
1496       tree decl = IDENTIFIER_GLOBAL_VALUE (name);
1497       if (decl && ! CLASS_LOADED_P (TREE_TYPE (decl))
1498           && !CLASS_BEING_LAIDOUT (TREE_TYPE (decl)))
1499         load_class (name, 1);
1500     }
1501 }
1502
1503 static void
1504 duplicate_class_warning (const char *filename)
1505 {
1506   location_t warn_loc;
1507   linemap_add (line_table, LC_RENAME, 0, filename, 0);
1508   warn_loc = linemap_line_start (line_table, 0, 1);
1509   warning_at (warn_loc, 0, "duplicate class will only be compiled once");
1510 }
1511
1512 static void
1513 java_layout_seen_class_methods (void)
1514 {
1515   unsigned start = 0;
1516   unsigned end = VEC_length (tree, all_class_list);
1517
1518   while (1)
1519     {
1520       unsigned ix;
1521       unsigned new_length;
1522
1523       for (ix = start; ix != end; ix++)
1524         {
1525           tree decl = VEC_index (tree, all_class_list, ix);
1526           tree cls = TREE_TYPE (decl);
1527
1528           input_location = DECL_SOURCE_LOCATION (decl);
1529
1530           if (! CLASS_LOADED_P (cls))
1531             load_class (cls, 0);
1532
1533           layout_class_methods (cls);
1534         }
1535
1536       /* Note that new classes might have been added while laying out
1537          methods, changing the value of all_class_list.  */
1538       new_length = VEC_length (tree, all_class_list);
1539       if (end != new_length)
1540         {
1541           start = end;
1542           end = new_length;
1543         }
1544       else
1545         break;
1546     }
1547 }
1548
1549 static void
1550 parse_class_file (void)
1551 {
1552   tree method;
1553   location_t save_location = input_location;
1554
1555   java_layout_seen_class_methods ();
1556
1557   input_location = DECL_SOURCE_LOCATION (TYPE_NAME (current_class));
1558   {
1559     /* Re-enter the current file.  */
1560     expanded_location loc = expand_location (input_location);
1561     linemap_add (line_table, LC_ENTER, 0, loc.file, loc.line);
1562   }
1563   file_start_location = input_location;
1564   (*debug_hooks->start_source_file) (input_line, input_filename);
1565
1566   java_mark_class_local (current_class);
1567
1568   gen_indirect_dispatch_tables (current_class);
1569
1570   for (method = TYPE_METHODS (current_class);
1571        method != NULL_TREE; method = DECL_CHAIN (method))
1572     {
1573       JCF *jcf = current_jcf;
1574
1575       if (METHOD_ABSTRACT (method) || METHOD_DUMMY (method))
1576         continue;
1577
1578       if (METHOD_NATIVE (method))
1579         {
1580           tree arg;
1581           int  decl_max_locals;
1582
1583           if (! flag_jni)
1584             continue;
1585           /* We need to compute the DECL_MAX_LOCALS. We need to take
1586              the wide types into account too. */
1587           for (arg = TYPE_ARG_TYPES (TREE_TYPE (method)), decl_max_locals = 0; 
1588                arg != end_params_node;
1589                arg = TREE_CHAIN (arg), decl_max_locals += 1)
1590             {
1591               if (TREE_VALUE (arg) && TYPE_IS_WIDE (TREE_VALUE (arg)))
1592                 decl_max_locals += 1;
1593             }
1594           DECL_MAX_LOCALS (method) = decl_max_locals;
1595           start_java_method (method);
1596           give_name_to_locals (jcf);
1597           *get_stmts () = build_jni_stub (method);
1598           end_java_method ();
1599           continue;
1600         }
1601
1602       if (DECL_CODE_OFFSET (method) == 0)
1603         {
1604           current_function_decl = method;
1605           error ("missing Code attribute");
1606           continue;
1607         }
1608
1609       input_location = DECL_SOURCE_LOCATION (TYPE_NAME (current_class));
1610       if (DECL_LINENUMBERS_OFFSET (method))
1611         {
1612           int i;
1613           int min_line = 0;
1614           unsigned char *ptr;
1615           JCF_SEEK (jcf, DECL_LINENUMBERS_OFFSET (method));
1616           linenumber_count = i = JCF_readu2 (jcf);
1617           linenumber_table = ptr = jcf->read_ptr;
1618
1619           for (ptr += 2; --i >= 0; ptr += 4)
1620             {
1621               int line = GET_u2 (ptr);
1622               /* Set initial input_line to smallest linenumber.
1623                * Needs to be set before init_function_start. */
1624               if (min_line == 0 || line < min_line)
1625                 min_line = line;
1626             }
1627           if (min_line != 0)
1628             input_location = linemap_line_start (line_table, min_line, 1);
1629         }
1630       else
1631         {
1632           linenumber_table = NULL;
1633           linenumber_count = 0;
1634         }
1635
1636       start_java_method (method);
1637
1638       note_instructions (jcf, method);
1639
1640       give_name_to_locals (jcf);
1641
1642       /* Bump up start_label_pc_this_method so we get a unique label number
1643          and reset highest_label_pc_this_method. */
1644       if (highest_label_pc_this_method >= 0)
1645         {
1646           /* We adjust to the next multiple of 1000.  This is just a frill
1647              so the last 3 digits of the label number match the bytecode
1648              offset, which might make debugging marginally more convenient. */
1649           start_label_pc_this_method
1650             = ((((start_label_pc_this_method + highest_label_pc_this_method)
1651                  / 1000)
1652                 + 1)
1653                * 1000);
1654           highest_label_pc_this_method = -1;
1655         }
1656
1657       /* Convert bytecode to trees.  */
1658       expand_byte_code (jcf, method);
1659
1660       end_java_method ();
1661     }
1662
1663   finish_class ();
1664
1665   (*debug_hooks->end_source_file) (LOCATION_LINE (save_location));
1666   input_location = save_location;
1667 }
1668
1669 static VEC(tree,gc) *predefined_filenames;
1670
1671 void
1672 add_predefined_file (tree name)
1673 {
1674   VEC_safe_push (tree, gc, predefined_filenames, name);
1675 }
1676
1677 int
1678 predefined_filename_p (tree node)
1679 {
1680   unsigned ix;
1681   tree f;
1682
1683   FOR_EACH_VEC_ELT (tree, predefined_filenames, ix, f)
1684     if (f == node)
1685       return 1;
1686
1687   return 0;
1688 }
1689
1690 /* Generate a function that does all static initialization for this 
1691    translation unit.  */
1692
1693 static void
1694 java_emit_static_constructor (void)
1695 {
1696   tree body = NULL;
1697
1698   emit_register_classes (&body);
1699   write_resource_constructor (&body);
1700
1701   if (body)
1702     {
1703       tree name = get_identifier ("_Jv_global_static_constructor");
1704
1705       tree decl 
1706         = build_decl (input_location, FUNCTION_DECL, name,
1707                       build_function_type_list (void_type_node, NULL_TREE));
1708
1709       tree resdecl = build_decl (input_location,
1710                                  RESULT_DECL, NULL_TREE, void_type_node);
1711       DECL_ARTIFICIAL (resdecl) = 1;
1712       DECL_RESULT (decl) = resdecl;
1713       current_function_decl = decl;
1714       allocate_struct_function (decl, false);
1715
1716       TREE_STATIC (decl) = 1;
1717       TREE_USED (decl) = 1;
1718       DECL_ARTIFICIAL (decl) = 1;
1719       DECL_NO_INSTRUMENT_FUNCTION_ENTRY_EXIT (decl) = 1;
1720       DECL_SAVED_TREE (decl) = body;
1721       DECL_UNINLINABLE (decl) = 1;
1722
1723       DECL_INITIAL (decl) = make_node (BLOCK);
1724       TREE_USED (DECL_INITIAL (decl)) = 1;
1725
1726       DECL_STATIC_CONSTRUCTOR (decl) = 1;
1727       java_genericize (decl);
1728       cgraph_finalize_function (decl, false);
1729     }
1730 }
1731
1732
1733 void
1734 java_parse_file (int set_yydebug ATTRIBUTE_UNUSED)
1735 {
1736   int filename_count = 0;
1737   location_t save_location = input_location;
1738   char *file_list = NULL, *list, *next;
1739   tree node;
1740   FILE *finput = NULL;
1741   int in_quotes = 0;
1742   unsigned ix;
1743  
1744   bitmap_obstack_initialize (&bit_obstack);
1745   field_offsets = BITMAP_ALLOC (&bit_obstack);
1746
1747   if (flag_filelist_file)
1748     {
1749       int avail = 2000;
1750       finput = fopen (main_input_filename, "r");
1751       if (finput == NULL)
1752         fatal_error ("can't open %s: %m", input_filename);
1753       list = XNEWVEC (char, avail);
1754       next = list;
1755       for (;;)
1756         {
1757           int count;
1758           if (avail < 500)
1759             {
1760               count = next - list;
1761               avail = 2 * (count + avail);
1762               list = XRESIZEVEC (char, list, avail);
1763               next = list + count;
1764               avail = avail - count;
1765             }
1766           /* Subtract to to guarantee space for final '\0'. */
1767           count = fread (next, 1, avail - 1, finput);
1768           if (count == 0)
1769             {
1770               if (! feof (finput))
1771                 fatal_error ("error closing %s: %m", input_filename);
1772               *next = '\0';
1773               break;
1774             }
1775           avail -= count;
1776           next += count;
1777         }
1778       fclose (finput);
1779       finput = NULL;
1780       file_list = list;
1781     }
1782   else
1783     list = CONST_CAST (char *, main_input_filename);
1784
1785   while (list)
1786     {
1787       for (next = list; ; )
1788         {
1789           char ch = *next;
1790           if (flag_filelist_file && ! in_quotes
1791               && (ch == '\n' || ch == '\r' || ch == '\t' || ch == ' '
1792                   || ch == '&') /* FIXME */)
1793             {
1794               if (next == list)
1795                 {
1796                   next++;
1797                   list = next;
1798                   continue;
1799                 }
1800               else
1801                 {
1802                   *next++ = '\0';
1803                   break;
1804                 }
1805             }
1806           if (flag_filelist_file && ch == '"')
1807             {
1808               in_quotes = ! in_quotes;
1809               *next++ = '\0';
1810               if (in_quotes) 
1811                 list = next;
1812               else 
1813                 break;
1814             }
1815           if (ch == '\0')
1816             {
1817               next = NULL;
1818               break;
1819             }
1820           next++;
1821         }
1822
1823       /* Exclude .java files.  */
1824       if (strlen (list) > 5 && ! strcmp (list + strlen (list) - 5, ".java"))
1825         {
1826           /* Nothing. */
1827         }
1828       else if (list[0]) 
1829         {
1830           node = get_identifier (list);
1831
1832           filename_count++;
1833
1834           /* Exclude file that we see twice on the command line. */
1835              
1836           if (IS_A_COMMAND_LINE_FILENAME_P (node))
1837             duplicate_class_warning (IDENTIFIER_POINTER (node));
1838           else
1839             {
1840               build_translation_unit_decl (node);
1841               IS_A_COMMAND_LINE_FILENAME_P (node) = 1;
1842             }
1843         }
1844       list = next;
1845     }
1846
1847   if (file_list != NULL)
1848     free (file_list);
1849
1850   if (filename_count == 0)
1851     warning (0, "no input file specified");
1852
1853   if (resource_name)
1854     {
1855       const char *resource_filename;
1856       
1857       /* Only one resource file may be compiled at a time.  */
1858       assert (VEC_length (tree, all_translation_units) == 1);
1859
1860       resource_filename
1861         = IDENTIFIER_POINTER
1862             (DECL_NAME (VEC_index (tree, all_translation_units, 0)));
1863       compile_resource_file (resource_name, resource_filename);
1864
1865       goto finish;
1866     }
1867
1868   current_jcf = main_jcf;
1869   FOR_EACH_VEC_ELT (tree, all_translation_units, ix, node)
1870     {
1871       unsigned char magic_string[4];
1872       char *real_path;
1873       uint32 magic = 0;
1874       tree name = DECL_NAME (node);
1875       tree real_file;
1876       const char *filename = IDENTIFIER_POINTER (name);
1877
1878       /* Skip already parsed files */
1879       real_path = lrealpath (filename);
1880       real_file = get_identifier (real_path);
1881       free (real_path);
1882       if (HAS_BEEN_ALREADY_PARSED_P (real_file))
1883         continue;
1884
1885       /* Close previous descriptor, if any */
1886       if (finput && fclose (finput))
1887         fatal_error ("can't close input file %s: %m", main_input_filename);
1888       
1889       finput = fopen (filename, "rb");
1890       if (finput == NULL)
1891         fatal_error ("can't open %s: %m", filename);
1892
1893 #ifdef IO_BUFFER_SIZE
1894       setvbuf (finput, xmalloc (IO_BUFFER_SIZE),
1895                _IOFBF, IO_BUFFER_SIZE);
1896 #endif
1897
1898       /* Figure what kind of file we're dealing with */
1899       if (fread (magic_string, 1, 4, finput) == 4)
1900         {
1901           fseek (finput, 0L, SEEK_SET);
1902           magic = GET_u4 (magic_string);
1903         }
1904       if (magic == 0xcafebabe)
1905         {
1906           CLASS_FILE_P (node) = 1;
1907           current_jcf = ggc_alloc_cleared_JCF ();
1908           current_jcf->read_state = finput;
1909           current_jcf->filbuf = jcf_filbuf_from_stdio;
1910           jcf_parse (current_jcf);
1911           DECL_SOURCE_LOCATION (node) = file_start_location;
1912           TYPE_JCF (current_class) = current_jcf;
1913           if (CLASS_FROM_CURRENTLY_COMPILED_P (current_class))
1914             {
1915               /* We've already compiled this class.  */
1916               duplicate_class_warning (filename);
1917               continue;
1918             }
1919           CLASS_FROM_CURRENTLY_COMPILED_P (current_class) = 1;
1920           TREE_TYPE (node) = current_class;
1921         }
1922       else if (magic == (JCF_u4)ZIPMAGIC)
1923         {
1924           main_jcf = ggc_alloc_cleared_JCF ();
1925           main_jcf->read_state = finput;
1926           main_jcf->filbuf = jcf_filbuf_from_stdio;
1927           linemap_add (line_table, LC_ENTER, false, filename, 0);
1928           input_location = linemap_line_start (line_table, 0, 1);
1929           if (open_in_zip (main_jcf, filename, NULL, 0) <  0)
1930             fatal_error ("bad zip/jar file %s", filename);
1931           localToFile = SeenZipFiles;
1932           /* Register all the classes defined there.  */
1933           process_zip_dir ((FILE *) main_jcf->read_state);
1934           linemap_add (line_table, LC_LEAVE, false, NULL, 0);
1935           parse_zip_file_entries ();
1936         }
1937       else if (magic == (JCF_u4) ZIPEMPTYMAGIC)
1938         {
1939           /* Ignore an empty input jar.  */
1940         }
1941       else
1942         {
1943           gcc_unreachable ();
1944 #if 0
1945           java_push_parser_context ();
1946           java_parser_context_save_global ();
1947
1948           parse_source_file_1 (real_file, filename, finput);
1949           java_parser_context_restore_global ();
1950           java_pop_parser_context (1);
1951           linemap_add (line_table, LC_LEAVE, false, NULL, 0);
1952 #endif
1953         }
1954     }
1955
1956   FOR_EACH_VEC_ELT (tree, all_translation_units, ix, node)
1957     {
1958       input_location = DECL_SOURCE_LOCATION (node);
1959       if (CLASS_FILE_P (node))
1960         {
1961           /* FIXME: These two flags really should be independent.  We
1962              should be able to compile fully binary compatible, but
1963              with flag_verify_invocations on.  */
1964           flag_verify_invocations = ! flag_indirect_dispatch;
1965           output_class = current_class = TREE_TYPE (node);
1966
1967           current_jcf = TYPE_JCF (current_class);
1968           layout_class (current_class);
1969           load_inner_classes (current_class);
1970           parse_class_file ();
1971           JCF_FINISH (current_jcf);
1972         }
1973     }
1974   input_location = save_location;
1975
1976   bitmap_obstack_release (&bit_obstack);
1977
1978  finish:
1979   /* Arrange for any necessary initialization to happen.  */
1980   java_emit_static_constructor ();
1981   gcc_assert (global_bindings_p ());
1982 }
1983
1984
1985 /* Return the name of the class corresponding to the name of the file
1986    in this zip entry.  The result is newly allocated using ALLOC.  */
1987 static char *
1988 compute_class_name (struct ZipDirectory *zdir)
1989 {
1990   char *class_name_in_zip_dir = ZIPDIR_FILENAME (zdir);
1991   char *class_name;
1992   int i;
1993   int filename_length = zdir->filename_length;
1994
1995   while (filename_length > 2 && strncmp (class_name_in_zip_dir, "./", 2) == 0)
1996     {
1997       class_name_in_zip_dir += 2;
1998       filename_length -= 2;
1999     }
2000
2001   filename_length -= strlen (".class");
2002   class_name = XNEWVEC (char, filename_length + 1);
2003   memcpy (class_name, class_name_in_zip_dir, filename_length);
2004   class_name [filename_length] = '\0';
2005
2006   for (i = 0; i < filename_length; i++)
2007     if (class_name[i] == '/')
2008       class_name[i] = '.';
2009
2010   return class_name;
2011 }
2012
2013 /* Return 0 if we should skip this entry, 1 if it is a .class file, 2
2014    if it is a property file of some sort.  */
2015 static int
2016 classify_zip_file (struct ZipDirectory *zdir)
2017 {
2018   char *class_name_in_zip_dir = ZIPDIR_FILENAME (zdir);
2019
2020   if (zdir->filename_length > 6
2021       && !strncmp (&class_name_in_zip_dir[zdir->filename_length - 6],
2022                    ".class", 6))
2023     return 1;
2024
2025   /* For now we drop the manifest, but not other information.  */
2026   if (zdir->filename_length == 20
2027       && !strncmp (class_name_in_zip_dir, "META-INF/MANIFEST.MF", 20))
2028     return 0;
2029
2030   /* Drop directory entries.  */
2031   if (zdir->filename_length > 0
2032       && class_name_in_zip_dir[zdir->filename_length - 1] == '/')
2033     return 0;
2034
2035   return 2;
2036 }
2037
2038 /* Process all class entries found in the zip file.  */
2039 static void
2040 parse_zip_file_entries (void)
2041 {
2042   struct ZipDirectory *zdir;
2043   int i;
2044
2045   for (i = 0, zdir = (ZipDirectory *)localToFile->central_directory;
2046        i < localToFile->count; i++, zdir = ZIPDIR_NEXT (zdir))
2047     {
2048       tree klass;
2049
2050       switch (classify_zip_file (zdir))
2051         {
2052         case 0:
2053           continue;
2054
2055         case 1:
2056           {
2057             char *class_name = compute_class_name (zdir);
2058             int previous_alias_set = -1;
2059             klass = lookup_class (get_identifier (class_name));
2060             FREE (class_name);
2061             current_jcf = TYPE_JCF (klass);
2062             output_class = current_class = klass;
2063
2064             /* This is a dummy class, and now we're compiling it for
2065                real.  */
2066             gcc_assert (! TYPE_DUMMY (klass));
2067
2068             /* This is for a corner case where we have a superclass
2069                but no superclass fields.
2070
2071                This can happen if we earlier failed to lay out this
2072                class because its superclass was still in the process
2073                of being laid out; this occurs when we have recursive
2074                class dependencies via inner classes.  We must record
2075                the previous alias set and restore it after laying out
2076                the class.
2077
2078                FIXME: this really is a kludge.  We should figure out a
2079                way to lay out the class properly before this
2080                happens.  */
2081             if (TYPE_SIZE (klass) && CLASSTYPE_SUPER (klass)
2082                 && integer_zerop (TYPE_SIZE (klass)))
2083               {
2084                 TYPE_SIZE (klass) = NULL_TREE;
2085                 previous_alias_set = TYPE_ALIAS_SET (klass);
2086                 TYPE_ALIAS_SET (klass) = -1;
2087               }
2088
2089             if (! CLASS_LOADED_P (klass))
2090               {
2091                 if (! CLASS_PARSED_P (klass))
2092                   {
2093                     read_zip_member (current_jcf, zdir, localToFile);
2094                     jcf_parse (current_jcf);
2095                   }
2096                 layout_class (current_class);
2097                 load_inner_classes (current_class);
2098               }
2099
2100             if (previous_alias_set != -1)
2101               TYPE_ALIAS_SET (klass) = previous_alias_set;
2102
2103             if (TYPE_SIZE (current_class) != error_mark_node)
2104               {
2105                 parse_class_file ();
2106                 free (current_jcf->buffer); /* No longer necessary */
2107                 /* Note: there is a way to free this buffer right after a
2108                    class seen in a zip file has been parsed. The idea is the
2109                    set its jcf in such a way that buffer will be reallocated
2110                    the time the code for the class will be generated. FIXME. */
2111               }
2112           }
2113           break;
2114
2115         case 2:
2116           {
2117             char *file_name, *class_name_in_zip_dir, *buffer;
2118             JCF *jcf;
2119             file_name = XNEWVEC (char, zdir->filename_length + 1);
2120             class_name_in_zip_dir = ZIPDIR_FILENAME (zdir);
2121             strncpy (file_name, class_name_in_zip_dir, zdir->filename_length);
2122             file_name[zdir->filename_length] = '\0';
2123             jcf = XNEW (JCF);
2124             JCF_ZERO (jcf);
2125             jcf->read_state  = finput;
2126             jcf->filbuf      = jcf_filbuf_from_stdio;
2127             jcf->classname   = NULL;
2128             jcf->filename    = file_name;
2129             jcf->zipd        = zdir;
2130
2131             if (read_zip_member (jcf, zdir, localToFile) < 0)
2132               fatal_error ("error while reading %s from zip file", file_name);
2133
2134             buffer = XNEWVEC (char, zdir->filename_length + 1 +
2135                             (jcf->buffer_end - jcf->buffer));
2136             strcpy (buffer, file_name);
2137             /* This is not a typo: we overwrite the trailing \0 of the
2138                file name; this is just how the data is laid out.  */
2139             memcpy (buffer + zdir->filename_length,
2140                     jcf->buffer, jcf->buffer_end - jcf->buffer);
2141
2142             compile_resource_data (file_name, buffer,
2143                                    jcf->buffer_end - jcf->buffer);
2144             JCF_FINISH (jcf);
2145             free (jcf);
2146             free (buffer);
2147           }
2148           break;
2149
2150         default:
2151           gcc_unreachable ();
2152         }
2153     }
2154 }
2155
2156 /* Read all the entries of the zip file, creates a class and a JCF. Sets the
2157    jcf up for further processing and link it to the created class.  */
2158
2159 static void
2160 process_zip_dir (FILE *finput)
2161 {
2162   int i;
2163   ZipDirectory *zdir;
2164
2165   for (i = 0, zdir = (ZipDirectory *)localToFile->central_directory;
2166        i < localToFile->count; i++, zdir = ZIPDIR_NEXT (zdir))
2167     {
2168       char *class_name, *file_name, *class_name_in_zip_dir;
2169       tree klass;
2170       JCF  *jcf;
2171
2172       class_name_in_zip_dir = ZIPDIR_FILENAME (zdir);
2173
2174       /* Here we skip non-class files; we handle them later.  */
2175       if (classify_zip_file (zdir) != 1)
2176         continue;
2177
2178       class_name = compute_class_name (zdir);
2179       file_name  = XNEWVEC (char, zdir->filename_length+1);
2180       jcf = ggc_alloc_cleared_JCF ();
2181
2182       strncpy (file_name, class_name_in_zip_dir, zdir->filename_length);
2183       file_name [zdir->filename_length] = '\0';
2184
2185       klass = lookup_class (get_identifier (class_name));
2186
2187       if (CLASS_FROM_CURRENTLY_COMPILED_P (klass))
2188         {
2189           /* We've already compiled this class.  */
2190           duplicate_class_warning (file_name);
2191           continue;
2192         }
2193       /* This function is only called when processing a zip file seen
2194          on the command line.  */
2195       CLASS_FROM_CURRENTLY_COMPILED_P (klass) = 1;
2196
2197       jcf->read_state  = finput;
2198       jcf->filbuf      = jcf_filbuf_from_stdio;
2199       jcf->classname   = class_name;
2200       jcf->filename    = file_name;
2201       jcf->zipd        = zdir;
2202
2203       TYPE_JCF (klass) = jcf;
2204     }
2205 }
2206
2207 #include "gt-java-jcf-parse.h"
2208 #include "gtype-java.h"