OSDN Git Service

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