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