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