Remove old autovect-branch by moving to "dead" directory.
[official-gcc.git] / old-autovect-branch / gcc / java / jcf-parse.c
blob4bc12f4d98a69aaf73533a27effb134c1eb3922f
1 /* Parser for Java(TM) .class files.
2 Copyright (C) 1996, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005
3 Free Software Foundation, Inc.
5 This file is part of GCC.
7 GCC is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 2, or (at your option)
10 any later version.
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.
17 You should have received a copy of the GNU General Public License
18 along with GCC; see the file COPYING. If not, write to
19 the Free Software Foundation, 51 Franklin Street, Fifth Floor,
20 Boston, MA 02110-1301, USA.
22 Java and all Java-based marks are trademarks or registered trademarks
23 of Sun Microsystems, Inc. in the United States and other countries.
24 The Free Software Foundation is independent of Sun Microsystems, Inc. */
26 /* Written by Per Bothner <bothner@cygnus.com> */
28 #include "config.h"
29 #include "system.h"
30 #include "coretypes.h"
31 #include "tm.h"
32 #include "tree.h"
33 #include "real.h"
34 #include "obstack.h"
35 #include "flags.h"
36 #include "java-except.h"
37 #include "input.h"
38 #include "java-tree.h"
39 #include "toplev.h"
40 #include "parse.h"
41 #include "ggc.h"
42 #include "debug.h"
43 #include "assert.h"
44 #include "tm_p.h"
45 #include "cgraph.h"
47 #ifdef HAVE_LOCALE_H
48 #include <locale.h>
49 #endif
51 #ifdef HAVE_LANGINFO_CODESET
52 #include <langinfo.h>
53 #endif
55 /* A CONSTANT_Utf8 element is converted to an IDENTIFIER_NODE at parse time. */
56 #define JPOOL_UTF(JCF, INDEX) CPOOL_UTF(&(JCF)->cpool, INDEX)
57 #define JPOOL_UTF_LENGTH(JCF, INDEX) IDENTIFIER_LENGTH (JPOOL_UTF (JCF, INDEX))
58 #define JPOOL_UTF_DATA(JCF, INDEX) \
59 ((const unsigned char *) IDENTIFIER_POINTER (JPOOL_UTF (JCF, INDEX)))
60 #define HANDLE_CONSTANT_Utf8(JCF, INDEX, LENGTH) \
61 do { \
62 unsigned char save; unsigned char *text; \
63 JCF_FILL (JCF, (LENGTH)+1); /* Make sure we read 1 byte beyond string. */ \
64 text = (JCF)->read_ptr; \
65 save = text[LENGTH]; \
66 text[LENGTH] = 0; \
67 (JCF)->cpool.data[INDEX].t = get_identifier ((const char *) text); \
68 text[LENGTH] = save; \
69 JCF_SKIP (JCF, LENGTH); } while (0)
71 #include "jcf.h"
73 extern struct obstack temporary_obstack;
75 static GTY(()) tree parse_roots[3];
77 /* The FIELD_DECL for the current field. */
78 #define current_field parse_roots[0]
80 /* The METHOD_DECL for the current method. */
81 #define current_method parse_roots[1]
83 /* A list of TRANSLATION_UNIT_DECLs for the files to be compiled. */
84 #define current_file_list parse_roots[2]
86 /* Line 0 in current file, if compiling from bytecode. */
87 static location_t file_start_location;
89 /* The Java archive that provides main_class; the main input file. */
90 static GTY(()) struct JCF * main_jcf;
92 static struct ZipFile *localToFile;
94 /* Declarations of some functions used here. */
95 static void handle_innerclass_attribute (int count, JCF *);
96 static tree give_name_to_class (JCF *jcf, int index);
97 static char *compute_class_name (struct ZipDirectory *zdir);
98 static int classify_zip_file (struct ZipDirectory *zdir);
99 static void parse_zip_file_entries (void);
100 static void process_zip_dir (FILE *);
101 static void parse_source_file_1 (tree, const char *, FILE *);
102 static void parse_source_file_2 (void);
103 static void parse_source_file_3 (void);
104 static void parse_class_file (void);
105 static void handle_deprecated (void);
106 static void set_source_filename (JCF *, int);
107 static void jcf_parse (struct JCF*);
108 static void load_inner_classes (tree);
110 /* Handle "Deprecated" attribute. */
111 static void
112 handle_deprecated (void)
114 if (current_field != NULL_TREE)
115 FIELD_DEPRECATED (current_field) = 1;
116 else if (current_method != NULL_TREE)
117 METHOD_DEPRECATED (current_method) = 1;
118 else if (current_class != NULL_TREE)
119 CLASS_DEPRECATED (TYPE_NAME (current_class)) = 1;
120 else
122 /* Shouldn't happen. */
123 abort ();
127 /* Handle "SourceFile" attribute. */
129 static void
130 set_source_filename (JCF *jcf, int index)
132 tree sfname_id = get_name_constant (jcf, index);
133 const char *sfname = IDENTIFIER_POINTER (sfname_id);
134 const char *old_filename = input_filename;
135 int new_len = IDENTIFIER_LENGTH (sfname_id);
136 if (old_filename != NULL)
138 int old_len = strlen (old_filename);
139 /* Use the current input_filename (derived from the class name)
140 if it has a directory prefix, but otherwise matches sfname. */
141 if (old_len > new_len
142 && strcmp (sfname, old_filename + old_len - new_len) == 0
143 && (old_filename[old_len - new_len - 1] == '/'
144 || old_filename[old_len - new_len - 1] == '\\'))
146 #ifndef USE_MAPPED_LOCATION
147 DECL_SOURCE_LOCATION (TYPE_NAME (current_class)) = input_location;
148 file_start_location = input_location;
149 #endif
150 return;
153 if (strchr (sfname, '/') == NULL && strchr (sfname, '\\') == NULL)
155 const char *class_name
156 = IDENTIFIER_POINTER (DECL_NAME (TYPE_NAME (current_class)));
157 char *dot = strrchr (class_name, '.');
158 if (dot != NULL)
160 /* Length of prefix, not counting final dot. */
161 int i = dot - class_name;
162 /* Concatenate current package prefix with new sfname. */
163 char *buf = xmalloc (i + new_len + 2); /* Space for '.' and '\0'. */
164 strcpy (buf + i + 1, sfname);
165 /* Copy package from class_name, replacing '.' by DIR_SEPARATOR.
166 Note we start at the end with the final package dot. */
167 for (; i >= 0; i--)
169 char c = class_name[i];
170 if (c == '.')
171 c = DIR_SEPARATOR;
172 buf[i] = c;
174 sfname_id = get_identifier (buf);
175 free (buf);
176 sfname = IDENTIFIER_POINTER (sfname_id);
180 #ifdef USE_MAPPED_LOCATION
181 line_table.maps[line_table.used-1].to_file = sfname;
182 #else
183 input_filename = sfname;
184 DECL_SOURCE_LOCATION (TYPE_NAME (current_class)) = input_location;
185 file_start_location = input_location;
186 #endif
187 if (current_class == main_class) main_input_filename = sfname;
190 #define HANDLE_SOURCEFILE(INDEX) set_source_filename (jcf, INDEX)
192 #define HANDLE_CLASS_INFO(ACCESS_FLAGS, THIS, SUPER, INTERFACES_COUNT) \
193 { tree super_class = SUPER==0 ? NULL_TREE : get_class_constant (jcf, SUPER); \
194 output_class = current_class = give_name_to_class (jcf, THIS); \
195 set_super_info (ACCESS_FLAGS, current_class, super_class, INTERFACES_COUNT);}
197 #define HANDLE_CLASS_INTERFACE(INDEX) \
198 add_interface (current_class, get_class_constant (jcf, INDEX))
200 #define HANDLE_START_FIELD(ACCESS_FLAGS, NAME, SIGNATURE, ATTRIBUTE_COUNT) \
201 { int sig_index = SIGNATURE; \
202 current_field = add_field (current_class, get_name_constant (jcf, NAME), \
203 parse_signature (jcf, sig_index), ACCESS_FLAGS); \
204 set_java_signature (TREE_TYPE (current_field), JPOOL_UTF (jcf, sig_index)); \
205 if ((ACCESS_FLAGS) & ACC_FINAL) \
206 MAYBE_CREATE_VAR_LANG_DECL_SPECIFIC (current_field); \
209 #define HANDLE_END_FIELDS() \
210 (current_field = NULL_TREE)
212 #define HANDLE_CONSTANTVALUE(INDEX) \
213 { tree constant; int index = INDEX; \
214 if (! flag_emit_class_files && JPOOL_TAG (jcf, index) == CONSTANT_String) { \
215 tree name = get_name_constant (jcf, JPOOL_USHORT1 (jcf, index)); \
216 constant = build_utf8_ref (name); \
218 else \
219 constant = get_constant (jcf, index); \
220 set_constant_value (current_field, constant); }
222 #define HANDLE_METHOD(ACCESS_FLAGS, NAME, SIGNATURE, ATTRIBUTE_COUNT) \
223 (current_method = add_method (current_class, ACCESS_FLAGS, \
224 get_name_constant (jcf, NAME), \
225 get_name_constant (jcf, SIGNATURE)), \
226 DECL_LOCALVARIABLES_OFFSET (current_method) = 0, \
227 DECL_LINENUMBERS_OFFSET (current_method) = 0)
229 #define HANDLE_END_METHODS() \
230 { current_method = NULL_TREE; }
232 #define HANDLE_CODE_ATTRIBUTE(MAX_STACK, MAX_LOCALS, CODE_LENGTH) \
233 { DECL_MAX_STACK (current_method) = (MAX_STACK); \
234 DECL_MAX_LOCALS (current_method) = (MAX_LOCALS); \
235 DECL_CODE_LENGTH (current_method) = (CODE_LENGTH); \
236 DECL_CODE_OFFSET (current_method) = JCF_TELL (jcf); }
238 #define HANDLE_LOCALVARIABLETABLE_ATTRIBUTE(COUNT) \
239 { int n = (COUNT); \
240 DECL_LOCALVARIABLES_OFFSET (current_method) = JCF_TELL (jcf) - 2; \
241 JCF_SKIP (jcf, n * 10); }
243 #define HANDLE_LINENUMBERTABLE_ATTRIBUTE(COUNT) \
244 { int n = (COUNT); \
245 DECL_LINENUMBERS_OFFSET (current_method) = JCF_TELL (jcf) - 2; \
246 JCF_SKIP (jcf, n * 4); }
248 #define HANDLE_EXCEPTIONS_ATTRIBUTE(COUNT) \
250 int n = COUNT; \
251 tree list = DECL_FUNCTION_THROWS (current_method); \
252 while (--n >= 0) \
254 tree thrown_class = get_class_constant (jcf, JCF_readu2 (jcf)); \
255 list = tree_cons (NULL_TREE, thrown_class, list); \
257 DECL_FUNCTION_THROWS (current_method) = nreverse (list); \
260 #define HANDLE_DEPRECATED_ATTRIBUTE() handle_deprecated ()
262 /* Link seen inner classes to their outer context and register the
263 inner class to its outer context. They will be later loaded. */
264 #define HANDLE_INNERCLASSES_ATTRIBUTE(COUNT) \
265 handle_innerclass_attribute (COUNT, jcf)
267 #define HANDLE_SYNTHETIC_ATTRIBUTE() \
269 /* Irrelevant decls should have been nullified by the END macros. \
270 We only handle the `Synthetic' attribute on method DECLs. \
271 DECL_ARTIFICIAL on fields is used for something else (See \
272 PUSH_FIELD in java-tree.h) */ \
273 if (current_method) \
274 DECL_ARTIFICIAL (current_method) = 1; \
277 #define HANDLE_GCJCOMPILED_ATTRIBUTE() \
279 if (current_class == object_type_node) \
280 jcf->right_zip = 1; \
283 #include "jcf-reader.c"
285 tree
286 parse_signature (JCF *jcf, int sig_index)
288 if (sig_index <= 0 || sig_index >= JPOOL_SIZE (jcf)
289 || JPOOL_TAG (jcf, sig_index) != CONSTANT_Utf8)
290 abort ();
291 else
292 return parse_signature_string (JPOOL_UTF_DATA (jcf, sig_index),
293 JPOOL_UTF_LENGTH (jcf, sig_index));
296 tree
297 get_constant (JCF *jcf, int index)
299 tree value;
300 int tag;
301 if (index <= 0 || index >= JPOOL_SIZE(jcf))
302 goto bad;
303 tag = JPOOL_TAG (jcf, index);
304 if ((tag & CONSTANT_ResolvedFlag) || tag == CONSTANT_Utf8)
305 return jcf->cpool.data[index].t;
306 switch (tag)
308 case CONSTANT_Integer:
310 jint num = JPOOL_INT(jcf, index);
311 value = build_int_cst (int_type_node, num);
312 break;
314 case CONSTANT_Long:
316 unsigned HOST_WIDE_INT num = JPOOL_UINT (jcf, index);
317 unsigned HOST_WIDE_INT lo;
318 HOST_WIDE_INT hi;
320 lshift_double (num, 0, 32, 64, &lo, &hi, 0);
321 num = JPOOL_UINT (jcf, index+1);
322 add_double (lo, hi, num, 0, &lo, &hi);
323 value = build_int_cst_wide (long_type_node, lo, hi);
324 value = force_fit_type (value, 0, false, false);
325 break;
328 case CONSTANT_Float:
330 jint num = JPOOL_INT(jcf, index);
331 long buf = num;
332 REAL_VALUE_TYPE d;
334 real_from_target_fmt (&d, &buf, &ieee_single_format);
335 value = build_real (float_type_node, d);
336 break;
339 case CONSTANT_Double:
341 long buf[2], lo, hi;
342 REAL_VALUE_TYPE d;
344 hi = JPOOL_UINT (jcf, index);
345 lo = JPOOL_UINT (jcf, index+1);
347 if (FLOAT_WORDS_BIG_ENDIAN)
348 buf[0] = hi, buf[1] = lo;
349 else
350 buf[0] = lo, buf[1] = hi;
352 real_from_target_fmt (&d, buf, &ieee_double_format);
353 value = build_real (double_type_node, d);
354 break;
357 case CONSTANT_String:
359 tree name = get_name_constant (jcf, JPOOL_USHORT1 (jcf, index));
360 const char *utf8_ptr = IDENTIFIER_POINTER (name);
361 int utf8_len = IDENTIFIER_LENGTH (name);
362 const unsigned char *utf8;
363 int i;
365 /* Check for a malformed Utf8 string. */
366 utf8 = (const unsigned char *) utf8_ptr;
367 i = utf8_len;
368 while (i > 0)
370 int char_len = UT8_CHAR_LENGTH (*utf8);
371 if (char_len < 0 || char_len > 3 || char_len > i)
372 fatal_error ("bad string constant");
374 utf8 += char_len;
375 i -= char_len;
378 /* Allocate a new string value. */
379 value = build_string (utf8_len, utf8_ptr);
380 TREE_TYPE (value) = build_pointer_type (string_type_node);
382 break;
383 default:
384 goto bad;
386 JPOOL_TAG (jcf, index) = tag | CONSTANT_ResolvedFlag;
387 jcf->cpool.data[index].t = value;
388 return value;
389 bad:
390 internal_error ("bad value constant type %d, index %d",
391 JPOOL_TAG (jcf, index), index);
394 tree
395 get_name_constant (JCF *jcf, int index)
397 tree name = get_constant (jcf, index);
399 if (TREE_CODE (name) != IDENTIFIER_NODE)
400 abort ();
402 return name;
405 /* Handle reading innerclass attributes. If a nonzero entry (denoting
406 a non anonymous entry) is found, We augment the inner class list of
407 the outer context with the newly resolved innerclass. */
409 static void
410 handle_innerclass_attribute (int count, JCF *jcf)
412 int c = (count);
413 while (c--)
415 /* Read inner_class_info_index. This may be 0 */
416 int icii = JCF_readu2 (jcf);
417 /* Read outer_class_info_index. If the innerclasses attribute
418 entry isn't a member (like an inner class) the value is 0. */
419 int ocii = JCF_readu2 (jcf);
420 /* Read inner_name_index. If the class we're dealing with is
421 an anonymous class, it must be 0. */
422 int ini = JCF_readu2 (jcf);
423 /* Read the access flag. */
424 int acc = JCF_readu2 (jcf);
425 /* If icii is 0, don't try to read the class. */
426 if (icii >= 0)
428 tree class = get_class_constant (jcf, icii);
429 tree decl = TYPE_NAME (class);
430 /* Skip reading further if ocii is null */
431 if (DECL_P (decl) && !CLASS_COMPLETE_P (decl) && ocii)
433 tree outer = TYPE_NAME (get_class_constant (jcf, ocii));
434 tree alias = (ini ? get_name_constant (jcf, ini) : NULL_TREE);
435 set_class_decl_access_flags (acc, decl);
436 DECL_CONTEXT (decl) = outer;
437 DECL_INNER_CLASS_LIST (outer) =
438 tree_cons (decl, alias, DECL_INNER_CLASS_LIST (outer));
439 CLASS_COMPLETE_P (decl) = 1;
445 static tree
446 give_name_to_class (JCF *jcf, int i)
448 if (i <= 0 || i >= JPOOL_SIZE (jcf)
449 || JPOOL_TAG (jcf, i) != CONSTANT_Class)
450 abort ();
451 else
453 tree package_name = NULL_TREE, tmp;
454 tree this_class;
455 int j = JPOOL_USHORT1 (jcf, i);
456 /* verify_constant_pool confirmed that j is a CONSTANT_Utf8. */
457 tree class_name = unmangle_classname ((const char *) JPOOL_UTF_DATA (jcf, j),
458 JPOOL_UTF_LENGTH (jcf, j));
459 this_class = lookup_class (class_name);
460 #ifdef USE_MAPPED_LOCATION
462 tree source_name = identifier_subst (class_name, "", '.', '/', ".java");
463 const char *sfname = IDENTIFIER_POINTER (source_name);
464 linemap_add (&line_table, LC_ENTER, false, sfname, 0);
465 input_location = linemap_line_start (&line_table, 0, 1);
466 file_start_location = input_location;
467 DECL_SOURCE_LOCATION (TYPE_NAME (this_class)) = input_location;
468 if (main_input_filename == NULL && jcf == main_jcf)
469 main_input_filename = sfname;
471 #else
472 input_location = DECL_SOURCE_LOCATION (TYPE_NAME (this_class));
473 if (main_input_filename == NULL && jcf == main_jcf)
474 main_input_filename = input_filename;
475 #endif
477 jcf->cpool.data[i].t = this_class;
478 JPOOL_TAG (jcf, i) = CONSTANT_ResolvedClass;
479 split_qualified_name (&package_name, &tmp,
480 DECL_NAME (TYPE_NAME (this_class)));
481 TYPE_PACKAGE (this_class) = package_name;
482 return this_class;
486 /* Get the class of the CONSTANT_Class whose constant pool index is I. */
488 tree
489 get_class_constant (JCF *jcf, int i)
491 tree type;
492 if (i <= 0 || i >= JPOOL_SIZE (jcf)
493 || (JPOOL_TAG (jcf, i) & ~CONSTANT_ResolvedFlag) != CONSTANT_Class)
494 abort ();
496 if (JPOOL_TAG (jcf, i) != CONSTANT_ResolvedClass)
498 int name_index = JPOOL_USHORT1 (jcf, i);
499 /* verify_constant_pool confirmed that name_index is a CONSTANT_Utf8. */
500 const char *name = (const char *) JPOOL_UTF_DATA (jcf, name_index);
501 int nlength = JPOOL_UTF_LENGTH (jcf, name_index);
503 if (name[0] == '[') /* Handle array "classes". */
504 type = TREE_TYPE (parse_signature_string ((const unsigned char *) name, nlength));
505 else
507 tree cname = unmangle_classname (name, nlength);
508 type = lookup_class (cname);
510 jcf->cpool.data[i].t = type;
511 JPOOL_TAG (jcf, i) = CONSTANT_ResolvedClass;
513 else
514 type = jcf->cpool.data[i].t;
515 return type;
518 /* Read a class with the fully qualified-name NAME.
519 Return 1 iff we read the requested file.
520 (It is still possible we failed if the file did not
521 define the class it is supposed to.) */
524 read_class (tree name)
526 JCF this_jcf, *jcf;
527 tree icv, class = NULL_TREE;
528 tree save_current_class = current_class;
529 tree save_output_class = output_class;
530 location_t save_location = input_location;
531 JCF *save_current_jcf = current_jcf;
533 if ((icv = IDENTIFIER_CLASS_VALUE (name)) != NULL_TREE)
535 class = TREE_TYPE (icv);
536 jcf = TYPE_JCF (class);
538 else
539 jcf = NULL;
541 if (jcf == NULL)
543 const char* path_name;
544 this_jcf.zipd = NULL;
545 jcf = &this_jcf;
547 path_name = find_class (IDENTIFIER_POINTER (name),
548 IDENTIFIER_LENGTH (name),
549 &this_jcf, 1);
550 if (path_name == 0)
551 return 0;
552 else
553 free((char *) path_name);
556 current_jcf = jcf;
558 if (current_jcf->java_source)
560 const char *filename = current_jcf->filename;
561 char *real_path;
562 tree given_file, real_file;
563 FILE *finput;
564 int generate;
566 java_parser_context_save_global ();
567 java_push_parser_context ();
569 given_file = get_identifier (filename);
570 filename = IDENTIFIER_POINTER (given_file);
571 real_path = lrealpath (filename);
572 real_file = get_identifier (real_path);
573 free (real_path);
575 generate = IS_A_COMMAND_LINE_FILENAME_P (given_file);
576 output_class = current_class = NULL_TREE;
577 current_function_decl = NULL_TREE;
579 if (! HAS_BEEN_ALREADY_PARSED_P (real_file))
581 if (! (finput = fopen (filename, "r")))
582 fatal_error ("can't reopen %s: %m", filename);
584 parse_source_file_1 (real_file, filename, finput);
585 parse_source_file_2 ();
586 parse_source_file_3 ();
588 if (fclose (finput))
589 fatal_error ("can't close %s: %m", input_filename);
590 #ifdef USE_MAPPED_LOCATION
591 linemap_add (&line_table, LC_LEAVE, false, NULL, 0);
592 #endif
594 JCF_FINISH (current_jcf);
595 java_pop_parser_context (generate);
596 java_parser_context_restore_global ();
598 else
600 if (class == NULL_TREE || ! CLASS_PARSED_P (class))
602 java_parser_context_save_global ();
603 java_push_parser_context ();
604 output_class = current_class = class;
605 ctxp->save_location = input_location;
606 if (JCF_SEEN_IN_ZIP (current_jcf))
607 read_zip_member(current_jcf,
608 current_jcf->zipd, current_jcf->zipd->zipf);
609 jcf_parse (current_jcf);
610 /* Parsing might change the class, in which case we have to
611 put it back where we found it. */
612 if (current_class != class && icv != NULL_TREE)
613 TREE_TYPE (icv) = current_class;
614 class = current_class;
615 java_pop_parser_context (0);
616 java_parser_context_restore_global ();
618 layout_class (class);
619 load_inner_classes (class);
622 output_class = save_output_class;
623 current_class = save_current_class;
624 input_location = save_location;
625 current_jcf = save_current_jcf;
626 return 1;
629 /* Load CLASS_OR_NAME. CLASS_OR_NAME can be a mere identifier if
630 called from the parser, otherwise it's a RECORD_TYPE node. If
631 VERBOSE is 1, print error message on failure to load a class. */
632 void
633 load_class (tree class_or_name, int verbose)
635 tree name, saved;
636 int class_loaded = 0;
637 tree class_decl = NULL_TREE;
638 bool is_compiled_class = false;
640 /* We've already failed, don't try again. */
641 if (TREE_CODE (class_or_name) == RECORD_TYPE
642 && TYPE_DUMMY (class_or_name))
643 return;
645 /* class_or_name can be the name of the class we want to load */
646 if (TREE_CODE (class_or_name) == IDENTIFIER_NODE)
647 name = class_or_name;
648 /* In some cases, it's a dependency that we process earlier that
649 we though */
650 else if (TREE_CODE (class_or_name) == TREE_LIST)
651 name = TYPE_NAME (TREE_PURPOSE (class_or_name));
652 /* Or it's a type in the making */
653 else
654 name = DECL_NAME (TYPE_NAME (class_or_name));
656 class_decl = IDENTIFIER_CLASS_VALUE (name);
657 if (class_decl != NULL_TREE)
659 tree type = TREE_TYPE (class_decl);
660 is_compiled_class
661 = ((TYPE_JCF (type) && JCF_SEEN_IN_ZIP (TYPE_JCF (type)))
662 || CLASS_FROM_CURRENTLY_COMPILED_P (type));
665 /* If the class is from source code, then it must already be loaded. */
666 class_decl = IDENTIFIER_CLASS_VALUE (name);
667 if (class_decl && CLASS_FROM_SOURCE_P (TREE_TYPE (class_decl)))
668 return;
670 saved = name;
672 /* If flag_verify_invocations is unset, we don't try to load a class
673 unless we're looking for Object (which is fixed by the ABI) or
674 it's a class that we're going to compile. */
675 if (flag_verify_invocations
676 || class_or_name == object_type_node
677 || is_compiled_class
678 || TREE_CODE (class_or_name) == IDENTIFIER_NODE)
680 while (1)
682 char *separator;
684 /* We've already loaded it. */
685 if (IDENTIFIER_CLASS_VALUE (name) != NULL_TREE)
687 tree tmp_decl = IDENTIFIER_CLASS_VALUE (name);
688 if (CLASS_PARSED_P (TREE_TYPE (tmp_decl)))
689 break;
692 if (read_class (name))
693 break;
695 /* We failed loading name. Now consider that we might be looking
696 for an inner class. */
697 if ((separator = strrchr (IDENTIFIER_POINTER (name), '$'))
698 || (separator = strrchr (IDENTIFIER_POINTER (name), '.')))
700 int c = *separator;
701 *separator = '\0';
702 name = get_identifier (IDENTIFIER_POINTER (name));
703 *separator = c;
705 /* Otherwise, we failed, we bail. */
706 else
707 break;
711 /* have we found the class we're looking for? */
712 tree type_decl = IDENTIFIER_CLASS_VALUE (saved);
713 tree type = type_decl ? TREE_TYPE (type_decl) : NULL;
714 class_loaded = type && CLASS_PARSED_P (type);
718 if (!class_loaded)
720 if (flag_verify_invocations || ! flag_indirect_dispatch
721 || flag_emit_class_files)
723 if (verbose)
724 error ("cannot find file for class %s", IDENTIFIER_POINTER (saved));
726 else if (verbose)
728 /* This is just a diagnostic during testing, not a real problem. */
729 if (!quiet_flag)
730 warning (0, "cannot find file for class %s",
731 IDENTIFIER_POINTER (saved));
733 /* Fake it. */
734 if (TREE_CODE (class_or_name) == RECORD_TYPE)
736 set_super_info (0, class_or_name, object_type_node, 0);
737 TYPE_DUMMY (class_or_name) = 1;
738 /* We won't be able to output any debug info for this class. */
739 DECL_IGNORED_P (TYPE_NAME (class_or_name)) = 1;
745 /* Parse the .class file JCF. */
747 static void
748 jcf_parse (JCF* jcf)
750 int i, code;
752 if (jcf_parse_preamble (jcf) != 0)
753 fatal_error ("not a valid Java .class file");
754 code = jcf_parse_constant_pool (jcf);
755 if (code != 0)
756 fatal_error ("error while parsing constant pool");
757 code = verify_constant_pool (jcf);
758 if (code > 0)
759 fatal_error ("error in constant pool entry #%d\n", code);
761 jcf_parse_class (jcf);
762 if (main_class == NULL_TREE)
763 main_class = current_class;
764 if (! quiet_flag && TYPE_NAME (current_class))
765 fprintf (stderr, " %s %s",
766 (jcf->access_flags & ACC_INTERFACE) ? "interface" : "class",
767 IDENTIFIER_POINTER (DECL_NAME (TYPE_NAME (current_class))));
768 if (CLASS_PARSED_P (current_class))
770 /* FIXME - where was first time */
771 fatal_error ("reading class %s for the second time from %s",
772 IDENTIFIER_POINTER (DECL_NAME (TYPE_NAME (current_class))),
773 jcf->filename);
775 CLASS_PARSED_P (current_class) = 1;
777 for (i = 1; i < JPOOL_SIZE(jcf); i++)
779 switch (JPOOL_TAG (jcf, i))
781 case CONSTANT_Class:
782 get_class_constant (jcf, i);
783 break;
787 code = jcf_parse_fields (jcf);
788 if (code != 0)
789 fatal_error ("error while parsing fields");
790 code = jcf_parse_methods (jcf);
791 if (code != 0)
792 fatal_error ("error while parsing methods");
793 code = jcf_parse_final_attributes (jcf);
794 if (code != 0)
795 fatal_error ("error while parsing final attributes");
796 #ifdef USE_MAPPED_LOCATION
797 linemap_add (&line_table, LC_LEAVE, false, NULL, 0);
798 #endif
800 /* The fields of class_type_node are already in correct order. */
801 if (current_class != class_type_node && current_class != object_type_node)
802 TYPE_FIELDS (current_class) = nreverse (TYPE_FIELDS (current_class));
804 if (current_class == object_type_node)
806 layout_class_methods (object_type_node);
807 /* If we don't have the right archive, emit a verbose warning.
808 If we're generating bytecode, emit the warning only if
809 -fforce-classes-archive-check was specified. */
810 if (!jcf->right_zip
811 && (!flag_emit_class_files || flag_force_classes_archive_check))
812 fatal_error ("the %<java.lang.Object%> that was found in %qs didn't have the special zero-length %<gnu.gcj.gcj-compiled%> attribute. This generally means that your classpath is incorrectly set. Use %<info gcj \"Input Options\"%> to see the info page describing how to set the classpath", jcf->filename);
814 else
815 all_class_list = tree_cons (NULL_TREE,
816 TYPE_NAME (current_class), all_class_list );
819 /* If we came across inner classes, load them now. */
820 static void
821 load_inner_classes (tree cur_class)
823 tree current;
824 for (current = DECL_INNER_CLASS_LIST (TYPE_NAME (cur_class)); current;
825 current = TREE_CHAIN (current))
827 tree name = DECL_NAME (TREE_PURPOSE (current));
828 tree decl = IDENTIFIER_GLOBAL_VALUE (name);
829 if (decl && ! CLASS_LOADED_P (TREE_TYPE (decl))
830 && !CLASS_BEING_LAIDOUT (TREE_TYPE (decl)))
831 load_class (name, 1);
835 static void
836 duplicate_class_warning (const char *filename)
838 location_t warn_loc;
839 #ifdef USE_MAPPED_LOCATION
840 linemap_add (&line_table, LC_RENAME, 0, filename, 0);
841 warn_loc = linemap_line_start (&line_table, 0, 1);
842 #else
843 warn_loc.file = filename;
844 warn_loc.line = 0;
845 #endif
846 warning (0, "%Hduplicate class will only be compiled once", &warn_loc);
849 static void
850 parse_class_file (void)
852 tree method;
853 location_t save_location = input_location;
855 java_layout_seen_class_methods ();
857 input_location = DECL_SOURCE_LOCATION (TYPE_NAME (current_class));
858 file_start_location = input_location;
859 (*debug_hooks->start_source_file) (input_line, input_filename);
861 gen_indirect_dispatch_tables (current_class);
863 java_mark_class_local (current_class);
865 for (method = TYPE_METHODS (current_class);
866 method != NULL_TREE; method = TREE_CHAIN (method))
868 JCF *jcf = current_jcf;
870 if (METHOD_ABSTRACT (method) || METHOD_DUMMY (method))
871 continue;
873 if (METHOD_NATIVE (method))
875 tree arg;
876 int decl_max_locals;
878 if (! flag_jni)
879 continue;
880 /* We need to compute the DECL_MAX_LOCALS. We need to take
881 the wide types into account too. */
882 for (arg = TYPE_ARG_TYPES (TREE_TYPE (method)), decl_max_locals = 0;
883 arg != end_params_node;
884 arg = TREE_CHAIN (arg), decl_max_locals += 1)
886 if (TREE_VALUE (arg) && TYPE_IS_WIDE (TREE_VALUE (arg)))
887 decl_max_locals += 1;
889 DECL_MAX_LOCALS (method) = decl_max_locals;
890 start_java_method (method);
891 give_name_to_locals (jcf);
892 *get_stmts () = build_jni_stub (method);
893 end_java_method ();
894 continue;
897 if (DECL_CODE_OFFSET (method) == 0)
899 current_function_decl = method;
900 error ("missing Code attribute");
901 continue;
904 input_location = file_start_location;
905 if (DECL_LINENUMBERS_OFFSET (method))
907 int i;
908 int min_line = 0;
909 unsigned char *ptr;
910 JCF_SEEK (jcf, DECL_LINENUMBERS_OFFSET (method));
911 linenumber_count = i = JCF_readu2 (jcf);
912 linenumber_table = ptr = jcf->read_ptr;
914 for (ptr += 2; --i >= 0; ptr += 4)
916 int line = GET_u2 (ptr);
917 /* Set initial input_line to smallest linenumber.
918 * Needs to be set before init_function_start. */
919 if (min_line == 0 || line < min_line)
920 min_line = line;
922 #ifdef USE_MAPPED_LOCATION
923 if (min_line != 0)
924 input_location = linemap_line_start (&line_table, min_line, 1);
925 #else
926 if (min_line != 0)
927 input_line = min_line;
928 #endif
930 else
932 linenumber_table = NULL;
933 linenumber_count = 0;
936 start_java_method (method);
938 note_instructions (jcf, method);
940 give_name_to_locals (jcf);
942 /* Bump up start_label_pc_this_method so we get a unique label number
943 and reset highest_label_pc_this_method. */
944 if (highest_label_pc_this_method >= 0)
946 /* We adjust to the next multiple of 1000. This is just a frill
947 so the last 3 digits of the label number match the bytecode
948 offset, which might make debugging marginally more convenient. */
949 start_label_pc_this_method
950 = ((((start_label_pc_this_method + highest_label_pc_this_method)
951 / 1000)
952 + 1)
953 * 1000);
954 highest_label_pc_this_method = -1;
957 /* Convert bytecode to trees. */
958 expand_byte_code (jcf, method);
960 end_java_method ();
963 if (flag_emit_class_files)
964 write_classfile (current_class);
966 finish_class ();
968 (*debug_hooks->end_source_file) (LOCATION_LINE (save_location));
969 input_location = save_location;
972 /* Parse a source file, as pointed by the current value of INPUT_FILENAME. */
974 static void
975 parse_source_file_1 (tree real_file, const char *filename, FILE *finput)
977 int save_error_count = java_error_count;
979 /* Mark the file as parsed. */
980 HAS_BEEN_ALREADY_PARSED_P (real_file) = 1;
982 lang_init_source (1); /* Error msgs have no method prototypes */
984 /* There's no point in trying to find the current encoding unless we
985 are going to do something intelligent with it -- hence the test
986 for iconv. */
987 #if defined (HAVE_LOCALE_H) && defined (HAVE_ICONV) && defined (HAVE_LANGINFO_CODESET)
988 setlocale (LC_CTYPE, "");
989 if (current_encoding == NULL)
990 current_encoding = nl_langinfo (CODESET);
991 #endif
992 if (current_encoding == NULL || *current_encoding == '\0')
993 current_encoding = DEFAULT_ENCODING;
995 #ifdef USE_MAPPED_LOCATION
996 linemap_add (&line_table, LC_ENTER, false, filename, 0);
997 input_location = linemap_line_start (&line_table, 0, 125);
998 #else
999 input_filename = filename;
1000 input_line = 0;
1001 #endif
1002 ctxp->file_start_location = input_location;
1003 ctxp->filename = filename;
1005 jcf_dependency_add_file (input_filename, 0);
1007 /* Initialize the parser */
1008 java_init_lex (finput, current_encoding);
1009 java_parse_abort_on_error ();
1011 java_parse (); /* Parse and build partial tree nodes. */
1012 java_parse_abort_on_error ();
1015 /* Process a parsed source file, resolving names etc. */
1017 static void
1018 parse_source_file_2 (void)
1020 int save_error_count = java_error_count;
1021 flag_verify_invocations = true;
1022 java_complete_class (); /* Parse unsatisfied class decl. */
1023 java_parse_abort_on_error ();
1026 static void
1027 parse_source_file_3 (void)
1029 int save_error_count = java_error_count;
1030 java_check_circular_reference (); /* Check on circular references */
1031 java_parse_abort_on_error ();
1032 java_fix_constructors (); /* Fix the constructors */
1033 java_parse_abort_on_error ();
1034 java_reorder_fields (); /* Reorder the fields */
1037 void
1038 add_predefined_file (tree name)
1040 predef_filenames = tree_cons (NULL_TREE, name, predef_filenames);
1044 predefined_filename_p (tree node)
1046 tree iter;
1048 for (iter = predef_filenames; iter != NULL_TREE; iter = TREE_CHAIN (iter))
1050 if (TREE_VALUE (iter) == node)
1051 return 1;
1053 return 0;
1056 /* Generate a function that does all static initialization for this
1057 translation unit. */
1059 static void
1060 java_emit_static_constructor (void)
1062 tree body = NULL;
1064 emit_register_classes (&body);
1065 write_resource_constructor (&body);
1067 if (body)
1068 cgraph_build_static_cdtor ('I', body, DEFAULT_INIT_PRIORITY);
1071 void
1072 java_parse_file (int set_yydebug ATTRIBUTE_UNUSED)
1074 int filename_count = 0;
1075 location_t save_location = input_location;
1076 char *file_list = NULL, *list, *next;
1077 tree node;
1078 FILE *finput = NULL;
1079 int in_quotes = 0;
1081 if (flag_filelist_file)
1083 int avail = 2000;
1084 finput = fopen (main_input_filename, "r");
1085 if (finput == NULL)
1086 fatal_error ("can't open %s: %m", input_filename);
1087 list = xmalloc(avail);
1088 next = list;
1089 for (;;)
1091 int count;
1092 if (avail < 500)
1094 count = next - list;
1095 avail = 2 * (count + avail);
1096 list = xrealloc (list, avail);
1097 next = list + count;
1098 avail = avail - count;
1100 /* Subtract to to guarantee space for final '\0'. */
1101 count = fread (next, 1, avail - 1, finput);
1102 if (count == 0)
1104 if (! feof (finput))
1105 fatal_error ("error closing %s: %m", input_filename);
1106 *next = '\0';
1107 break;
1109 avail -= count;
1110 next += count;
1112 fclose (finput);
1113 finput = NULL;
1114 file_list = list;
1116 else
1117 list = (char *) main_input_filename;
1119 while (list)
1121 for (next = list; ; )
1123 char ch = *next;
1124 if (flag_filelist_file && ! in_quotes
1125 && (ch == '\n' || ch == '\r' || ch == '\t' || ch == ' '
1126 || ch == '&') /* FIXME */)
1128 if (next == list)
1130 next++;
1131 list = next;
1132 continue;
1134 else
1136 *next++ = '\0';
1137 break;
1140 if (flag_filelist_file && ch == '"')
1142 in_quotes = ! in_quotes;
1143 *next++ = '\0';
1144 if (in_quotes)
1145 list = next;
1146 else
1147 break;
1149 if (ch == '\0')
1151 next = NULL;
1152 break;
1154 next++;
1157 if (list[0])
1159 node = get_identifier (list);
1161 filename_count++;
1163 /* Exclude file that we see twice on the command line. */
1165 if (IS_A_COMMAND_LINE_FILENAME_P (node))
1166 duplicate_class_warning (IDENTIFIER_POINTER (node));
1167 else
1169 tree file_decl = build_decl (TRANSLATION_UNIT_DECL, node, NULL);
1170 TREE_CHAIN (file_decl) = current_file_list;
1171 current_file_list = file_decl;
1172 IS_A_COMMAND_LINE_FILENAME_P (node) = 1;
1175 list = next;
1178 if (file_list != NULL)
1179 free (file_list);
1181 if (filename_count == 0)
1182 warning (0, "no input file specified");
1184 if (resource_name)
1186 const char *resource_filename;
1188 /* Only one resource file may be compiled at a time. */
1189 assert (TREE_CHAIN (current_file_list) == NULL);
1191 resource_filename = IDENTIFIER_POINTER (DECL_NAME (current_file_list));
1192 compile_resource_file (resource_name, resource_filename);
1194 goto finish;
1197 current_jcf = main_jcf;
1198 current_file_list = nreverse (current_file_list);
1199 for (node = current_file_list; node; node = TREE_CHAIN (node))
1201 unsigned char magic_string[4];
1202 char *real_path;
1203 uint32 magic = 0;
1204 tree name = DECL_NAME (node);
1205 tree real_file;
1206 const char *filename = IDENTIFIER_POINTER (name);
1208 /* Skip already parsed files */
1209 real_path = lrealpath (filename);
1210 real_file = get_identifier (real_path);
1211 free (real_path);
1212 if (HAS_BEEN_ALREADY_PARSED_P (real_file))
1213 continue;
1215 /* Close previous descriptor, if any */
1216 if (finput && fclose (finput))
1217 fatal_error ("can't close input file %s: %m", main_input_filename);
1219 finput = fopen (filename, "rb");
1220 if (finput == NULL)
1221 fatal_error ("can't open %s: %m", filename);
1223 #ifdef IO_BUFFER_SIZE
1224 setvbuf (finput, xmalloc (IO_BUFFER_SIZE),
1225 _IOFBF, IO_BUFFER_SIZE);
1226 #endif
1228 /* Figure what kind of file we're dealing with */
1229 if (fread (magic_string, 1, 4, finput) == 4)
1231 fseek (finput, 0L, SEEK_SET);
1232 magic = GET_u4 (magic_string);
1234 if (magic == 0xcafebabe)
1236 CLASS_FILE_P (node) = 1;
1237 current_jcf = ggc_alloc (sizeof (JCF));
1238 JCF_ZERO (current_jcf);
1239 current_jcf->read_state = finput;
1240 current_jcf->filbuf = jcf_filbuf_from_stdio;
1241 jcf_parse (current_jcf);
1242 DECL_SOURCE_LOCATION (node) = file_start_location;
1243 TYPE_JCF (current_class) = current_jcf;
1244 if (CLASS_FROM_CURRENTLY_COMPILED_P (current_class))
1246 /* We've already compiled this class. */
1247 duplicate_class_warning (filename);
1248 continue;
1250 CLASS_FROM_CURRENTLY_COMPILED_P (current_class) = 1;
1251 TREE_TYPE (node) = current_class;
1253 else if (magic == (JCF_u4)ZIPMAGIC)
1255 main_jcf = ggc_alloc (sizeof (JCF));
1256 JCF_ZERO (main_jcf);
1257 main_jcf->read_state = finput;
1258 main_jcf->filbuf = jcf_filbuf_from_stdio;
1259 #ifdef USE_MAPPED_LOCATION
1260 linemap_add (&line_table, LC_ENTER, false, filename, 0);
1261 input_location = linemap_line_start (&line_table, 0, 1);
1262 #endif
1263 if (open_in_zip (main_jcf, filename, NULL, 0) < 0)
1264 fatal_error ("bad zip/jar file %s", filename);
1265 localToFile = SeenZipFiles;
1266 /* Register all the classes defined there. */
1267 process_zip_dir (main_jcf->read_state);
1268 #ifdef USE_MAPPED_LOCATION
1269 linemap_add (&line_table, LC_LEAVE, false, NULL, 0);
1270 #endif
1271 parse_zip_file_entries ();
1273 else
1275 java_push_parser_context ();
1276 java_parser_context_save_global ();
1278 parse_source_file_1 (real_file, filename, finput);
1279 java_parser_context_restore_global ();
1280 java_pop_parser_context (1);
1281 #ifdef USE_MAPPED_LOCATION
1282 linemap_add (&line_table, LC_LEAVE, false, NULL, 0);
1283 #endif
1287 for (ctxp = ctxp_for_generation; ctxp; ctxp = ctxp->next)
1289 input_location = ctxp->file_start_location;
1290 parse_source_file_2 ();
1293 for (ctxp = ctxp_for_generation; ctxp; ctxp = ctxp->next)
1295 input_location = ctxp->file_start_location;
1296 parse_source_file_3 ();
1299 for (node = current_file_list; node; node = TREE_CHAIN (node))
1301 input_location = DECL_SOURCE_LOCATION (node);
1302 if (CLASS_FILE_P (node))
1304 /* FIXME: These two flags really should be independent. We
1305 should be able to compile fully binary compatible, but
1306 with flag_verify_invocations on. */
1307 flag_verify_invocations = ! flag_indirect_dispatch;
1308 output_class = current_class = TREE_TYPE (node);
1310 current_jcf = TYPE_JCF (current_class);
1311 layout_class (current_class);
1312 load_inner_classes (current_class);
1313 parse_class_file ();
1314 JCF_FINISH (current_jcf);
1317 input_location = save_location;
1319 java_expand_classes ();
1320 if (java_report_errors () || flag_syntax_only)
1321 return;
1323 /* Expand all classes compiled from source. */
1324 java_finish_classes ();
1326 finish:
1327 /* Arrange for any necessary initialization to happen. */
1328 java_emit_static_constructor ();
1330 /* Only finalize the compilation unit after we've told cgraph which
1331 functions have their addresses stored. */
1332 cgraph_finalize_compilation_unit ();
1333 cgraph_optimize ();
1337 /* Return the name of the class corresponding to the name of the file
1338 in this zip entry. The result is newly allocated using ALLOC. */
1339 static char *
1340 compute_class_name (struct ZipDirectory *zdir)
1342 char *class_name_in_zip_dir = ZIPDIR_FILENAME (zdir);
1343 char *class_name;
1344 int i;
1345 int filename_length = zdir->filename_length;
1347 while (filename_length > 2 && strncmp (class_name_in_zip_dir, "./", 2) == 0)
1349 class_name_in_zip_dir += 2;
1350 filename_length -= 2;
1353 filename_length -= strlen (".class");
1354 class_name = ALLOC (filename_length + 1);
1355 memcpy (class_name, class_name_in_zip_dir, filename_length);
1356 class_name [filename_length] = '\0';
1358 for (i = 0; i < filename_length; i++)
1359 if (class_name[i] == '/')
1360 class_name[i] = '.';
1362 return class_name;
1365 /* Return 0 if we should skip this entry, 1 if it is a .class file, 2
1366 if it is a property file of some sort. */
1367 static int
1368 classify_zip_file (struct ZipDirectory *zdir)
1370 char *class_name_in_zip_dir = ZIPDIR_FILENAME (zdir);
1372 if (zdir->filename_length > 6
1373 && !strncmp (&class_name_in_zip_dir[zdir->filename_length - 6],
1374 ".class", 6))
1375 return 1;
1377 /* For now we drop the manifest, but not other information. */
1378 if (zdir->filename_length == 20
1379 && !strncmp (class_name_in_zip_dir, "META-INF/MANIFEST.MF", 20))
1380 return 0;
1382 /* Drop directory entries. */
1383 if (zdir->filename_length > 0
1384 && class_name_in_zip_dir[zdir->filename_length - 1] == '/')
1385 return 0;
1387 return 2;
1390 /* Process all class entries found in the zip file. */
1391 static void
1392 parse_zip_file_entries (void)
1394 struct ZipDirectory *zdir;
1395 int i;
1397 for (i = 0, zdir = (ZipDirectory *)localToFile->central_directory;
1398 i < localToFile->count; i++, zdir = ZIPDIR_NEXT (zdir))
1400 tree class;
1402 switch (classify_zip_file (zdir))
1404 case 0:
1405 continue;
1407 case 1:
1409 char *class_name = compute_class_name (zdir);
1410 class = lookup_class (get_identifier (class_name));
1411 FREE (class_name);
1412 current_jcf = TYPE_JCF (class);
1413 output_class = current_class = class;
1415 if (CLASS_FROM_CURRENTLY_COMPILED_P (current_class))
1417 /* We've already compiled this class. */
1418 duplicate_class_warning (current_jcf->filename);
1419 break;
1422 CLASS_FROM_CURRENTLY_COMPILED_P (current_class) = 1;
1424 if (TYPE_DUMMY (class))
1426 /* This is a dummy class, and now we're compiling it
1427 for real. */
1428 abort ();
1431 /* This is for a corner case where we have a superclass
1432 but no superclass fields.
1434 This can happen if we earlier failed to lay out this
1435 class because its superclass was still in the process
1436 of being laid out; this occurs when we have recursive
1437 class dependencies via inner classes. Setting
1438 TYPE_SIZE to null here causes CLASS_LOADED_P to return
1439 false, so layout_class() will be called again. */
1440 if (TYPE_SIZE (class) && CLASSTYPE_SUPER (class)
1441 && integer_zerop (TYPE_SIZE (class)))
1442 TYPE_SIZE (class) = NULL_TREE;
1444 if (! CLASS_LOADED_P (class))
1446 if (! CLASS_PARSED_P (class))
1448 read_zip_member (current_jcf, zdir, localToFile);
1449 jcf_parse (current_jcf);
1451 layout_class (current_class);
1452 load_inner_classes (current_class);
1455 if (TYPE_SIZE (current_class) != error_mark_node)
1457 parse_class_file ();
1458 FREE (current_jcf->buffer); /* No longer necessary */
1459 /* Note: there is a way to free this buffer right after a
1460 class seen in a zip file has been parsed. The idea is the
1461 set its jcf in such a way that buffer will be reallocated
1462 the time the code for the class will be generated. FIXME. */
1465 break;
1467 case 2:
1469 char *file_name, *class_name_in_zip_dir, *buffer;
1470 JCF *jcf;
1471 file_name = ALLOC (zdir->filename_length + 1);
1472 class_name_in_zip_dir = ZIPDIR_FILENAME (zdir);
1473 strncpy (file_name, class_name_in_zip_dir, zdir->filename_length);
1474 file_name[zdir->filename_length] = '\0';
1475 jcf = ALLOC (sizeof (JCF));
1476 JCF_ZERO (jcf);
1477 jcf->read_state = finput;
1478 jcf->filbuf = jcf_filbuf_from_stdio;
1479 jcf->java_source = 0;
1480 jcf->classname = NULL;
1481 jcf->filename = file_name;
1482 jcf->zipd = zdir;
1484 if (read_zip_member (jcf, zdir, localToFile) < 0)
1485 fatal_error ("error while reading %s from zip file", file_name);
1487 buffer = ALLOC (zdir->filename_length + 1 +
1488 (jcf->buffer_end - jcf->buffer));
1489 strcpy (buffer, file_name);
1490 /* This is not a typo: we overwrite the trailing \0 of the
1491 file name; this is just how the data is laid out. */
1492 memcpy (buffer + zdir->filename_length,
1493 jcf->buffer, jcf->buffer_end - jcf->buffer);
1495 compile_resource_data (file_name, buffer,
1496 jcf->buffer_end - jcf->buffer);
1497 JCF_FINISH (jcf);
1498 FREE (jcf);
1499 FREE (buffer);
1501 break;
1503 default:
1504 abort ();
1509 /* Read all the entries of the zip file, creates a class and a JCF. Sets the
1510 jcf up for further processing and link it to the created class. */
1512 static void
1513 process_zip_dir (FILE *finput)
1515 int i;
1516 ZipDirectory *zdir;
1518 for (i = 0, zdir = (ZipDirectory *)localToFile->central_directory;
1519 i < localToFile->count; i++, zdir = ZIPDIR_NEXT (zdir))
1521 char *class_name, *file_name, *class_name_in_zip_dir;
1522 tree class;
1523 JCF *jcf;
1525 class_name_in_zip_dir = ZIPDIR_FILENAME (zdir);
1527 /* Here we skip non-class files; we handle them later. */
1528 if (classify_zip_file (zdir) != 1)
1529 continue;
1531 class_name = compute_class_name (zdir);
1532 file_name = ALLOC (zdir->filename_length+1);
1533 jcf = ggc_alloc (sizeof (JCF));
1534 JCF_ZERO (jcf);
1536 strncpy (file_name, class_name_in_zip_dir, zdir->filename_length);
1537 file_name [zdir->filename_length] = '\0';
1539 class = lookup_class (get_identifier (class_name));
1541 jcf->read_state = finput;
1542 jcf->filbuf = jcf_filbuf_from_stdio;
1543 jcf->java_source = 0;
1544 jcf->classname = class_name;
1545 jcf->filename = file_name;
1546 jcf->zipd = zdir;
1548 TYPE_JCF (class) = jcf;
1552 /* Initialization. */
1554 void
1555 init_jcf_parse (void)
1557 init_src_parse ();
1560 #include "gt-java-jcf-parse.h"