1 /* Parser for Java(TM) .class files.
2 Copyright (C) 1996, 1998, 1999, 2000, 2001, 2002
3 Free Software Foundation, Inc.
5 This file is part of GNU CC.
7 GNU CC 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)
12 GNU CC 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 GNU CC; see the file COPYING. If not, write to
19 the Free Software Foundation, 59 Temple Place - Suite 330,
20 Boston, MA 02111-1307, 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> */
34 #include "java-except.h"
36 #include "java-tree.h"
47 #ifdef HAVE_NL_LANGINFO
51 /* A CONSTANT_Utf8 element is converted to an IDENTIFIER_NODE at parse time. */
52 #define JPOOL_UTF(JCF, INDEX) CPOOL_UTF(&(JCF)->cpool, INDEX)
53 #define JPOOL_UTF_LENGTH(JCF, INDEX) IDENTIFIER_LENGTH (JPOOL_UTF (JCF, INDEX))
54 #define JPOOL_UTF_DATA(JCF, INDEX) \
55 ((const unsigned char *) IDENTIFIER_POINTER (JPOOL_UTF (JCF, INDEX)))
56 #define HANDLE_CONSTANT_Utf8(JCF, INDEX, LENGTH) \
58 unsigned char save; unsigned char *text; \
59 JCF_FILL (JCF, (LENGTH)+1); /* Make sure we read 1 byte beyond string. */ \
60 text = (JCF)->read_ptr; \
61 save = text[LENGTH]; \
63 (JCF)->cpool.data[INDEX] = (jword) get_identifier (text); \
64 text[LENGTH] = save; \
65 JCF_SKIP (JCF, LENGTH); } while (0)
69 extern struct obstack temporary_obstack;
71 /* Set to nonzero value in order to emit class initilization code
72 before static field references. */
73 extern int always_initialize_class_p;
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 file names. */
84 #define current_file_list parse_roots[2]
86 /* The Java archive that provides main_class; the main input file. */
87 static struct JCF main_jcf[1];
89 static struct ZipFile *localToFile;
91 /* Declarations of some functions used here. */
92 static void handle_innerclass_attribute PARAMS ((int count, JCF *));
93 static tree give_name_to_class PARAMS ((JCF *jcf, int index));
94 static void parse_zip_file_entries PARAMS ((void));
95 static void process_zip_dir PARAMS ((FILE *));
96 static void parse_source_file_1 PARAMS ((tree, FILE *));
97 static void parse_source_file_2 PARAMS ((void));
98 static void parse_source_file_3 PARAMS ((void));
99 static void parse_class_file PARAMS ((void));
100 static void set_source_filename PARAMS ((JCF *, int));
101 static void ggc_mark_jcf PARAMS ((void**));
102 static void jcf_parse PARAMS ((struct JCF*));
103 static void load_inner_classes PARAMS ((tree));
105 /* Mark (for garbage collection) all the tree nodes that are
106 referenced from JCF's constant pool table. Do that only if the JCF
107 hasn't been marked finished. */
113 JCF *jcf = *(JCF**) elt;
114 if (jcf != NULL && !jcf->finished)
116 CPool *cpool = &jcf->cpool;
117 int size = CPOOL_COUNT(cpool);
119 for (index = 1; index < size; index++)
121 int tag = JPOOL_TAG (jcf, index);
122 if ((tag & CONSTANT_ResolvedFlag) || tag == CONSTANT_Utf8)
123 ggc_mark_tree ((tree) cpool->data[index]);
128 /* Handle "SourceFile" attribute. */
131 set_source_filename (jcf, index)
135 tree sfname_id = get_name_constant (jcf, index);
136 const char *sfname = IDENTIFIER_POINTER (sfname_id);
137 if (input_filename != NULL)
139 int old_len = strlen (input_filename);
140 int new_len = IDENTIFIER_LENGTH (sfname_id);
141 /* Use the current input_filename (derived from the class name)
142 if it has a directory prefix, but otherwise matches sfname. */
143 if (old_len > new_len
144 && strcmp (sfname, input_filename + old_len - new_len) == 0
145 && (input_filename[old_len - new_len - 1] == '/'
146 || input_filename[old_len - new_len - 1] == '\\'))
149 input_filename = sfname;
150 DECL_SOURCE_FILE (TYPE_NAME (current_class)) = sfname;
151 if (current_class == main_class) main_input_filename = input_filename;
154 #define HANDLE_SOURCEFILE(INDEX) set_source_filename (jcf, INDEX)
156 #define HANDLE_CLASS_INFO(ACCESS_FLAGS, THIS, SUPER, INTERFACES_COUNT) \
157 { tree super_class = SUPER==0 ? NULL_TREE : get_class_constant (jcf, SUPER); \
158 current_class = give_name_to_class (jcf, THIS); \
159 set_super_info (ACCESS_FLAGS, current_class, super_class, INTERFACES_COUNT);}
161 #define HANDLE_CLASS_INTERFACE(INDEX) \
162 add_interface (current_class, get_class_constant (jcf, INDEX))
164 #define HANDLE_START_FIELD(ACCESS_FLAGS, NAME, SIGNATURE, ATTRIBUTE_COUNT) \
165 { int sig_index = SIGNATURE; \
166 current_field = add_field (current_class, get_name_constant (jcf, NAME), \
167 parse_signature (jcf, sig_index), ACCESS_FLAGS); \
168 set_java_signature (TREE_TYPE (current_field), JPOOL_UTF (jcf, sig_index)); \
169 if ((ACCESS_FLAGS) & ACC_FINAL) \
170 MAYBE_CREATE_VAR_LANG_DECL_SPECIFIC (current_field); \
173 #define HANDLE_END_FIELDS() \
174 (current_field = NULL_TREE)
176 #define HANDLE_CONSTANTVALUE(INDEX) \
177 { tree constant; int index = INDEX; \
178 if (! flag_emit_class_files && JPOOL_TAG (jcf, index) == CONSTANT_String) { \
179 tree name = get_name_constant (jcf, JPOOL_USHORT1 (jcf, index)); \
180 constant = build_utf8_ref (name); \
183 constant = get_constant (jcf, index); \
184 set_constant_value (current_field, constant); }
186 #define HANDLE_METHOD(ACCESS_FLAGS, NAME, SIGNATURE, ATTRIBUTE_COUNT) \
187 (current_method = add_method (current_class, ACCESS_FLAGS, \
188 get_name_constant (jcf, NAME), \
189 get_name_constant (jcf, SIGNATURE)), \
190 DECL_LOCALVARIABLES_OFFSET (current_method) = 0, \
191 DECL_LINENUMBERS_OFFSET (current_method) = 0)
193 #define HANDLE_END_METHODS() \
194 { current_method = NULL_TREE; }
196 #define HANDLE_CODE_ATTRIBUTE(MAX_STACK, MAX_LOCALS, CODE_LENGTH) \
197 { DECL_MAX_STACK (current_method) = (MAX_STACK); \
198 DECL_MAX_LOCALS (current_method) = (MAX_LOCALS); \
199 DECL_CODE_LENGTH (current_method) = (CODE_LENGTH); \
200 DECL_CODE_OFFSET (current_method) = JCF_TELL (jcf); }
202 #define HANDLE_LOCALVARIABLETABLE_ATTRIBUTE(COUNT) \
204 DECL_LOCALVARIABLES_OFFSET (current_method) = JCF_TELL (jcf) - 2; \
205 JCF_SKIP (jcf, n * 10); }
207 #define HANDLE_LINENUMBERTABLE_ATTRIBUTE(COUNT) \
209 DECL_LINENUMBERS_OFFSET (current_method) = JCF_TELL (jcf) - 2; \
210 JCF_SKIP (jcf, n * 4); }
212 #define HANDLE_EXCEPTIONS_ATTRIBUTE(COUNT) \
215 tree list = DECL_FUNCTION_THROWS (current_method); \
218 tree thrown_class = get_class_constant (jcf, JCF_readu2 (jcf)); \
219 list = tree_cons (NULL_TREE, thrown_class, list); \
221 DECL_FUNCTION_THROWS (current_method) = nreverse (list); \
224 /* Link seen inner classes to their outer context and register the
225 inner class to its outer context. They will be later loaded. */
226 #define HANDLE_INNERCLASSES_ATTRIBUTE(COUNT) \
227 handle_innerclass_attribute (COUNT, jcf)
229 #define HANDLE_SYNTHETIC_ATTRIBUTE() \
231 /* Irrelevant decls should have been nullified by the END macros. \
232 We only handle the `Synthetic' attribute on method DECLs. \
233 DECL_ARTIFICIAL on fields is used for something else (See \
234 PUSH_FIELD in java-tree.h) */ \
235 if (current_method) \
236 DECL_ARTIFICIAL (current_method) = 1; \
239 #define HANDLE_GCJCOMPILED_ATTRIBUTE() \
241 if (current_class == object_type_node) \
242 jcf->right_zip = 1; \
245 #include "jcf-reader.c"
248 parse_signature (jcf, sig_index)
252 if (sig_index <= 0 || sig_index >= JPOOL_SIZE (jcf)
253 || JPOOL_TAG (jcf, sig_index) != CONSTANT_Utf8)
256 return parse_signature_string (JPOOL_UTF_DATA (jcf, sig_index),
257 JPOOL_UTF_LENGTH (jcf, sig_index));
261 get_constant (jcf, index)
267 if (index <= 0 || index >= JPOOL_SIZE(jcf))
269 tag = JPOOL_TAG (jcf, index);
270 if ((tag & CONSTANT_ResolvedFlag) || tag == CONSTANT_Utf8)
271 return (tree) jcf->cpool.data[index];
274 case CONSTANT_Integer:
276 jint num = JPOOL_INT(jcf, index);
277 value = build_int_2 (num, num < 0 ? -1 : 0);
278 TREE_TYPE (value) = int_type_node;
283 unsigned HOST_WIDE_INT num = JPOOL_UINT (jcf, index);
284 HOST_WIDE_INT lo, hi;
285 lshift_double (num, 0, 32, 64, &lo, &hi, 0);
286 num = JPOOL_UINT (jcf, index+1);
287 add_double (lo, hi, num, 0, &lo, &hi);
288 value = build_int_2 (lo, hi);
289 TREE_TYPE (value) = long_type_node;
290 force_fit_type (value, 0);
295 /* ??? Even more ideal would be to import the number using the
296 IEEE decode routines, then use whatever format the target
297 actually uses. This would enable Java on VAX to kind work. */
298 if (TARGET_FLOAT_FORMAT == IEEE_FLOAT_FORMAT)
300 jint num = JPOOL_INT(jcf, index);
303 real_from_target (&d, &buf, SFmode);
304 value = build_real (float_type_node, d);
310 case CONSTANT_Double:
311 if (TARGET_FLOAT_FORMAT == IEEE_FLOAT_FORMAT)
316 hi = JPOOL_UINT (jcf, index);
317 lo = JPOOL_UINT (jcf, index+1);
319 if (FLOAT_WORDS_BIG_ENDIAN)
320 buf[0] = hi, buf[1] = lo;
322 buf[0] = lo, buf[1] = hi;
324 real_from_target (&d, buf, DFmode);
325 value = build_real (double_type_node, d);
331 case CONSTANT_String:
333 tree name = get_name_constant (jcf, JPOOL_USHORT1 (jcf, index));
334 const char *utf8_ptr = IDENTIFIER_POINTER (name);
335 int utf8_len = IDENTIFIER_LENGTH (name);
336 const unsigned char *utf8;
339 /* Check for a malformed Utf8 string. */
340 utf8 = (const unsigned char *) utf8_ptr;
344 int char_len = UT8_CHAR_LENGTH (*utf8);
345 if (char_len < 0 || char_len > 3 || char_len > i)
346 fatal_error ("bad string constant");
352 /* Allocate a new string value. */
353 value = build_string (utf8_len, utf8_ptr);
354 TREE_TYPE (value) = build_pointer_type (string_type_node);
360 JPOOL_TAG (jcf, index) = tag | CONSTANT_ResolvedFlag;
361 jcf->cpool.data [index] = (jword) value;
364 internal_error ("bad value constant type %d, index %d",
365 JPOOL_TAG (jcf, index), index);
369 get_name_constant (jcf, index)
373 tree name = get_constant (jcf, index);
375 if (TREE_CODE (name) != IDENTIFIER_NODE)
381 /* Handle reading innerclass attributes. If a nonzero entry (denoting
382 a non anonymous entry) is found, We augment the inner class list of
383 the outer context with the newly resolved innerclass. */
386 handle_innerclass_attribute (count, jcf)
393 /* Read inner_class_info_index. This may be 0 */
394 int icii = JCF_readu2 (jcf);
395 /* Read outer_class_info_index. If the innerclasses attribute
396 entry isn't a member (like an inner class) the value is 0. */
397 int ocii = JCF_readu2 (jcf);
398 /* Read inner_name_index. If the class we're dealing with is
399 an annonymous class, it must be 0. */
400 int ini = JCF_readu2 (jcf);
401 /* Read the access flag. */
402 int acc = JCF_readu2 (jcf);
403 /* If icii is 0, don't try to read the class. */
406 tree class = get_class_constant (jcf, icii);
407 tree decl = TYPE_NAME (class);
408 /* Skip reading further if ocii is null */
409 if (DECL_P (decl) && !CLASS_COMPLETE_P (decl) && ocii)
411 tree outer = TYPE_NAME (get_class_constant (jcf, ocii));
412 tree alias = (ini ? get_name_constant (jcf, ini) : NULL_TREE);
413 set_class_decl_access_flags (acc, decl);
414 DECL_CONTEXT (decl) = outer;
415 DECL_INNER_CLASS_LIST (outer) =
416 tree_cons (decl, alias, DECL_INNER_CLASS_LIST (outer));
417 CLASS_COMPLETE_P (decl) = 1;
424 give_name_to_class (jcf, i)
428 if (i <= 0 || i >= JPOOL_SIZE (jcf)
429 || JPOOL_TAG (jcf, i) != CONSTANT_Class)
434 int j = JPOOL_USHORT1 (jcf, i);
435 /* verify_constant_pool confirmed that j is a CONSTANT_Utf8. */
436 tree class_name = unmangle_classname (JPOOL_UTF_DATA (jcf, j),
437 JPOOL_UTF_LENGTH (jcf, j));
438 this_class = lookup_class (class_name);
439 input_filename = DECL_SOURCE_FILE (TYPE_NAME (this_class));
441 if (main_input_filename == NULL && jcf == main_jcf)
442 main_input_filename = input_filename;
444 jcf->cpool.data[i] = (jword) this_class;
445 JPOOL_TAG (jcf, i) = CONSTANT_ResolvedClass;
450 /* Get the class of the CONSTANT_Class whose constant pool index is I. */
453 get_class_constant (JCF *jcf , int i)
456 if (i <= 0 || i >= JPOOL_SIZE (jcf)
457 || (JPOOL_TAG (jcf, i) & ~CONSTANT_ResolvedFlag) != CONSTANT_Class)
460 if (JPOOL_TAG (jcf, i) != CONSTANT_ResolvedClass)
462 int name_index = JPOOL_USHORT1 (jcf, i);
463 /* verify_constant_pool confirmed that name_index is a CONSTANT_Utf8. */
464 const char *name = JPOOL_UTF_DATA (jcf, name_index);
465 int nlength = JPOOL_UTF_LENGTH (jcf, name_index);
467 if (name[0] == '[') /* Handle array "classes". */
468 type = TREE_TYPE (parse_signature_string (name, nlength));
471 tree cname = unmangle_classname (name, nlength);
472 type = lookup_class (cname);
474 jcf->cpool.data[i] = (jword) type;
475 JPOOL_TAG (jcf, i) = CONSTANT_ResolvedClass;
478 type = (tree) jcf->cpool.data[i];
482 /* Read a class with the fully qualified-name NAME.
483 Return 1 iff we read the requested file.
484 (It is still possible we failed if the file did not
485 define the class it is supposed to.) */
492 tree icv, class = NULL_TREE;
493 tree save_current_class = current_class;
494 const char *save_input_filename = input_filename;
495 JCF *save_current_jcf = current_jcf;
497 if ((icv = IDENTIFIER_CLASS_VALUE (name)) != NULL_TREE)
499 class = TREE_TYPE (icv);
500 jcf = TYPE_JCF (class);
507 this_jcf.zipd = NULL;
509 if (find_class (IDENTIFIER_POINTER (name), IDENTIFIER_LENGTH (name),
516 if (current_jcf->java_source)
518 const char *filename = current_jcf->filename;
523 java_parser_context_save_global ();
524 java_push_parser_context ();
525 BUILD_FILENAME_IDENTIFIER_NODE (file, filename);
526 generate = IS_A_COMMAND_LINE_FILENAME_P (file);
527 if (wfl_operator == NULL_TREE)
528 wfl_operator = build_expr_wfl (NULL_TREE, NULL, 0, 0);
529 EXPR_WFL_FILENAME_NODE (wfl_operator) = file;
530 input_filename = ggc_strdup (filename);
531 current_class = NULL_TREE;
532 current_function_decl = NULL_TREE;
533 if (!HAS_BEEN_ALREADY_PARSED_P (file))
535 if (!(finput = fopen (input_filename, "r")))
536 fatal_io_error ("can't reopen %s", input_filename);
537 parse_source_file_1 (file, finput);
538 parse_source_file_2 ();
539 parse_source_file_3 ();
541 fatal_io_error ("can't close %s", input_filename);
543 JCF_FINISH (current_jcf);
544 java_pop_parser_context (generate);
545 java_parser_context_restore_global ();
549 if (class == NULL_TREE || ! CLASS_PARSED_P (class))
551 java_parser_context_save_global ();
552 java_push_parser_context ();
553 current_class = class;
554 input_filename = current_jcf->filename;
555 if (JCF_SEEN_IN_ZIP (current_jcf))
556 read_zip_member(current_jcf,
557 current_jcf->zipd, current_jcf->zipd->zipf);
558 jcf_parse (current_jcf);
559 class = current_class;
560 java_pop_parser_context (0);
561 java_parser_context_restore_global ();
563 layout_class (class);
564 load_inner_classes (class);
567 current_class = save_current_class;
568 input_filename = save_input_filename;
569 current_jcf = save_current_jcf;
573 /* Load CLASS_OR_NAME. CLASS_OR_NAME can be a mere identifier if
574 called from the parser, otherwise it's a RECORD_TYPE node. If
575 VERBOSE is 1, print error message on failure to load a class. */
577 /* Replace calls to load_class by having callers call read_class directly
578 - and then perhaps rename read_class to load_class. FIXME */
581 load_class (class_or_name, verbose)
588 /* class_or_name can be the name of the class we want to load */
589 if (TREE_CODE (class_or_name) == IDENTIFIER_NODE)
590 name = class_or_name;
591 /* In some cases, it's a dependency that we process earlier that
593 else if (TREE_CODE (class_or_name) == TREE_LIST)
594 name = TYPE_NAME (TREE_PURPOSE (class_or_name));
595 /* Or it's a type in the making */
597 name = DECL_NAME (TYPE_NAME (class_or_name));
604 if ((class_loaded = read_class (name)))
607 /* We failed loading name. Now consider that we might be looking
608 for a inner class. */
609 if ((separator = strrchr (IDENTIFIER_POINTER (name), '$'))
610 || (separator = strrchr (IDENTIFIER_POINTER (name), '.')))
614 name = get_identifier (IDENTIFIER_POINTER (name));
617 /* Otherwise, we failed, we bail. */
622 if (!class_loaded && verbose)
623 error ("cannot find file for class %s", IDENTIFIER_POINTER (saved));
626 /* Parse the .class file JCF. */
634 if (jcf_parse_preamble (jcf) != 0)
635 fatal_error ("not a valid Java .class file");
636 code = jcf_parse_constant_pool (jcf);
638 fatal_error ("error while parsing constant pool");
639 code = verify_constant_pool (jcf);
641 fatal_error ("error in constant pool entry #%d\n", code);
643 jcf_parse_class (jcf);
644 if (main_class == NULL_TREE)
645 main_class = current_class;
646 if (! quiet_flag && TYPE_NAME (current_class))
647 fprintf (stderr, " %s %s",
648 (jcf->access_flags & ACC_INTERFACE) ? "interface" : "class",
649 IDENTIFIER_POINTER (DECL_NAME (TYPE_NAME (current_class))));
650 if (CLASS_PARSED_P (current_class))
652 /* FIXME - where was first time */
653 fatal_error ("reading class %s for the second time from %s",
654 IDENTIFIER_POINTER (DECL_NAME (TYPE_NAME (current_class))),
657 CLASS_PARSED_P (current_class) = 1;
659 for (i = 1; i < JPOOL_SIZE(jcf); i++)
661 switch (JPOOL_TAG (jcf, i))
664 get_class_constant (jcf, i);
669 code = jcf_parse_fields (jcf);
671 fatal_error ("error while parsing fields");
672 code = jcf_parse_methods (jcf);
674 fatal_error ("error while parsing methods");
675 code = jcf_parse_final_attributes (jcf);
677 fatal_error ("error while parsing final attributes");
679 /* The fields of class_type_node are already in correct order. */
680 if (current_class != class_type_node && current_class != object_type_node)
681 TYPE_FIELDS (current_class) = nreverse (TYPE_FIELDS (current_class));
683 if (current_class == object_type_node)
685 layout_class_methods (object_type_node);
686 /* If we don't have the right archive, emit a verbose warning.
687 If we're generating bytecode, emit the warning only if
688 -fforce-classes-archive-check was specified. */
690 && (!flag_emit_class_files || flag_force_classes_archive_check))
691 fatal_error ("the `java.lang.Object' that was found in `%s' 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);
694 all_class_list = tree_cons (NULL_TREE,
695 TYPE_NAME (current_class), all_class_list );
698 /* If we came across inner classes, load them now. */
700 load_inner_classes (cur_class)
704 for (current = DECL_INNER_CLASS_LIST (TYPE_NAME (cur_class)); current;
705 current = TREE_CHAIN (current))
707 tree name = DECL_NAME (TREE_PURPOSE (current));
708 tree decl = IDENTIFIER_GLOBAL_VALUE (name);
709 if (decl && ! CLASS_LOADED_P (TREE_TYPE (decl))
710 && !CLASS_BEING_LAIDOUT (TREE_TYPE (decl)))
711 load_class (name, 1);
716 init_outgoing_cpool ()
718 current_constant_pool_data_ref = NULL_TREE;
719 outgoing_cpool = (struct CPool *)xmalloc (sizeof (struct CPool));
720 memset (outgoing_cpool, 0, sizeof (struct CPool));
727 const char *save_input_filename = input_filename;
728 int save_lineno = lineno;
730 java_layout_seen_class_methods ();
732 input_filename = DECL_SOURCE_FILE (TYPE_NAME (current_class));
734 (*debug_hooks->start_source_file) (lineno, input_filename);
735 init_outgoing_cpool ();
737 /* Currently we always have to emit calls to _Jv_InitClass when
738 compiling from class files. */
739 always_initialize_class_p = 1;
741 for (field = TYPE_FIELDS (current_class);
742 field != NULL_TREE; field = TREE_CHAIN (field))
743 if (FIELD_STATIC (field))
744 DECL_EXTERNAL (field) = 0;
746 for (method = TYPE_METHODS (current_class);
747 method != NULL_TREE; method = TREE_CHAIN (method))
749 JCF *jcf = current_jcf;
751 if (METHOD_ABSTRACT (method))
754 if (METHOD_NATIVE (method))
761 /* We need to compute the DECL_MAX_LOCALS. We need to take
762 the wide types into account too. */
763 for (arg = TYPE_ARG_TYPES (TREE_TYPE (method)), decl_max_locals = 0;
764 arg != end_params_node;
765 arg = TREE_CHAIN (arg), decl_max_locals += 1)
767 if (TREE_VALUE (arg) && TYPE_IS_WIDE (TREE_VALUE (arg)))
768 decl_max_locals += 1;
770 DECL_MAX_LOCALS (method) = decl_max_locals;
771 start_java_method (method);
772 give_name_to_locals (jcf);
773 expand_expr_stmt (build_jni_stub (method));
778 if (DECL_CODE_OFFSET (method) == 0)
780 current_function_decl = method;
781 error ("missing Code attribute");
786 if (DECL_LINENUMBERS_OFFSET (method))
789 register unsigned char *ptr;
790 JCF_SEEK (jcf, DECL_LINENUMBERS_OFFSET (method));
791 linenumber_count = i = JCF_readu2 (jcf);
792 linenumber_table = ptr = jcf->read_ptr;
794 for (ptr += 2; --i >= 0; ptr += 4)
796 int line = GET_u2 (ptr);
797 /* Set initial lineno lineno to smallest linenumber.
798 * Needs to be set before init_function_start. */
799 if (lineno == 0 || line < lineno)
805 linenumber_table = NULL;
806 linenumber_count = 0;
809 start_java_method (method);
811 note_instructions (jcf, method);
813 give_name_to_locals (jcf);
815 /* Actually generate code. */
816 expand_byte_code (jcf, method);
821 if (flag_emit_class_files)
822 write_classfile (current_class);
826 (*debug_hooks->end_source_file) (save_lineno);
827 input_filename = save_input_filename;
828 lineno = save_lineno;
831 /* Parse a source file, as pointed by the current value of INPUT_FILENAME. */
834 parse_source_file_1 (file, finput)
838 int save_error_count = java_error_count;
839 /* Mark the file as parsed */
840 HAS_BEEN_ALREADY_PARSED_P (file) = 1;
842 jcf_dependency_add_file (input_filename, 0);
844 lang_init_source (1); /* Error msgs have no method prototypes */
846 /* There's no point in trying to find the current encoding unless we
847 are going to do something intelligent with it -- hence the test
849 #if defined (HAVE_LOCALE_H) && defined (HAVE_ICONV) && defined (HAVE_NL_LANGINFO)
850 setlocale (LC_CTYPE, "");
851 if (current_encoding == NULL)
852 current_encoding = nl_langinfo (CODESET);
854 if (current_encoding == NULL || *current_encoding == '\0')
855 current_encoding = DEFAULT_ENCODING;
857 /* Initialize the parser */
858 java_init_lex (finput, current_encoding);
859 java_parse_abort_on_error ();
861 java_parse (); /* Parse and build partial tree nodes. */
862 java_parse_abort_on_error ();
865 /* Process a parsed source file, resolving names etc. */
868 parse_source_file_2 ()
870 int save_error_count = java_error_count;
871 java_complete_class (); /* Parse unsatisfied class decl. */
872 java_parse_abort_on_error ();
876 parse_source_file_3 ()
878 int save_error_count = java_error_count;
879 java_check_circular_reference (); /* Check on circular references */
880 java_parse_abort_on_error ();
881 java_fix_constructors (); /* Fix the constructors */
882 java_parse_abort_on_error ();
883 java_reorder_fields (); /* Reorder the fields */
887 add_predefined_file (name)
890 predef_filenames = tree_cons (NULL_TREE, name, predef_filenames);
894 predefined_filename_p (node)
899 for (iter = predef_filenames; iter != NULL_TREE; iter = TREE_CHAIN (iter))
901 if (TREE_VALUE (iter) == node)
908 java_parse_file (set_yydebug)
909 int set_yydebug ATTRIBUTE_UNUSED;
911 int filename_count = 0;
916 if (flag_filelist_file)
919 finput = fopen (input_filename, "r");
921 fatal_io_error ("can't open %s", input_filename);
922 list = xmalloc(avail);
930 avail = 2 * (count + avail);
931 list = xrealloc (list, avail);
933 avail = avail - count;
935 /* Subtract to to guarantee space for final '\0'. */
936 count = fread (next, 1, avail - 1, finput);
940 fatal_io_error ("error closing %s", input_filename);
951 list = xstrdup (input_filename);
955 for (next = list; ; )
958 if (ch == '\n' || ch == '\r' || ch == '\t' || ch == ' '
959 || ch == '&' /* FIXME */)
987 int len = strlen (list);
989 obstack_grow0 (&temporary_obstack, list, len);
990 value = obstack_finish (&temporary_obstack);
994 /* Exclude file that we see twice on the command line. For
995 all files except {Class,Error,Object,RuntimeException,String,
996 Throwable}.java we can rely on maybe_get_identifier. For
997 these files, we need to do a linear search of
998 current_file_list. This search happens only for these
999 files, presumably only when we're recompiling libgcj. */
1001 if ((id = maybe_get_identifier (value)))
1003 if (predefined_filename_p (id))
1006 for (c = current_file_list; c; c = TREE_CHAIN (c))
1007 if (TREE_VALUE (c) == id)
1016 const char *saved_input_filename = input_filename;
1017 input_filename = value;
1018 warning ("source file seen twice on command line and will be compiled only once");
1019 input_filename = saved_input_filename;
1023 BUILD_FILENAME_IDENTIFIER_NODE (node, value);
1024 IS_A_COMMAND_LINE_FILENAME_P (node) = 1;
1025 current_file_list = tree_cons (NULL_TREE, node,
1033 if (filename_count == 0)
1034 warning ("no input file specified");
1038 const char *resource_filename;
1040 /* Only one resource file may be compiled at a time. */
1041 assert (TREE_CHAIN (current_file_list) == NULL);
1043 resource_filename = IDENTIFIER_POINTER (TREE_VALUE (current_file_list));
1044 compile_resource_file (resource_name, resource_filename);
1049 current_jcf = main_jcf;
1050 current_file_list = nreverse (current_file_list);
1051 for (node = current_file_list; node; node = TREE_CHAIN (node))
1053 unsigned char magic_string[4];
1055 tree name = TREE_VALUE (node);
1057 /* Skip already parsed files */
1058 if (HAS_BEEN_ALREADY_PARSED_P (name))
1061 /* Close previous descriptor, if any */
1062 if (finput && fclose (finput))
1063 fatal_io_error ("can't close input file %s", main_input_filename);
1065 finput = fopen (IDENTIFIER_POINTER (name), "rb");
1067 fatal_io_error ("can't open %s", IDENTIFIER_POINTER (name));
1069 #ifdef IO_BUFFER_SIZE
1070 setvbuf (finput, (char *) xmalloc (IO_BUFFER_SIZE),
1071 _IOFBF, IO_BUFFER_SIZE);
1073 input_filename = IDENTIFIER_POINTER (name);
1075 /* Figure what kind of file we're dealing with */
1076 if (fread (magic_string, 1, 4, finput) == 4)
1078 fseek (finput, 0L, SEEK_SET);
1079 magic = GET_u4 (magic_string);
1081 if (magic == 0xcafebabe)
1083 CLASS_FILE_P (node) = 1;
1084 current_jcf = ALLOC (sizeof (JCF));
1085 JCF_ZERO (current_jcf);
1086 current_jcf->read_state = finput;
1087 current_jcf->filbuf = jcf_filbuf_from_stdio;
1088 jcf_parse (current_jcf);
1089 TYPE_JCF (current_class) = current_jcf;
1090 CLASS_FROM_CURRENTLY_COMPILED_P (current_class) = 1;
1091 TREE_PURPOSE (node) = current_class;
1093 else if (magic == (JCF_u4)ZIPMAGIC)
1095 ZIP_FILE_P (node) = 1;
1096 JCF_ZERO (main_jcf);
1097 main_jcf->read_state = finput;
1098 main_jcf->filbuf = jcf_filbuf_from_stdio;
1099 if (open_in_zip (main_jcf, input_filename, NULL, 0) < 0)
1100 fatal_error ("bad zip/jar file %s", IDENTIFIER_POINTER (name));
1101 localToFile = SeenZipFiles;
1102 /* Register all the class defined there. */
1103 process_zip_dir (main_jcf->read_state);
1104 parse_zip_file_entries ();
1107 CLASS_FROM_CURRENTLY_COMPILED_P (current_class) = 1;
1112 JAVA_FILE_P (node) = 1;
1113 java_push_parser_context ();
1114 java_parser_context_save_global ();
1115 parse_source_file_1 (name, finput);
1116 java_parser_context_restore_global ();
1117 java_pop_parser_context (1);
1121 for (ctxp = ctxp_for_generation; ctxp; ctxp = ctxp->next)
1123 input_filename = ctxp->filename;
1124 parse_source_file_2 ();
1127 for (ctxp = ctxp_for_generation; ctxp; ctxp = ctxp->next)
1129 input_filename = ctxp->filename;
1130 parse_source_file_3 ();
1133 for (node = current_file_list; node; node = TREE_CHAIN (node))
1135 input_filename = IDENTIFIER_POINTER (TREE_VALUE (node));
1136 if (CLASS_FILE_P (node))
1138 current_class = TREE_PURPOSE (node);
1139 current_jcf = TYPE_JCF (current_class);
1140 layout_class (current_class);
1141 load_inner_classes (current_class);
1142 parse_class_file ();
1143 JCF_FINISH (current_jcf);
1146 input_filename = main_input_filename;
1148 java_expand_classes ();
1149 if (!java_report_errors () && !flag_syntax_only)
1151 emit_register_classes ();
1152 if (flag_indirect_dispatch)
1153 emit_offset_symbol_table ();
1157 /* Process all class entries found in the zip file. */
1159 parse_zip_file_entries (void)
1161 struct ZipDirectory *zdir;
1164 for (i = 0, zdir = (ZipDirectory *)localToFile->central_directory;
1165 i < localToFile->count; i++, zdir = ZIPDIR_NEXT (zdir))
1169 /* We don't need to consider those files. */
1170 if (!zdir->size || !zdir->filename_offset)
1173 class = lookup_class (get_identifier (ZIPDIR_FILENAME (zdir)));
1174 current_jcf = TYPE_JCF (class);
1175 current_class = class;
1177 if ( !CLASS_LOADED_P (class))
1179 if (! CLASS_PARSED_P (class))
1181 read_zip_member(current_jcf, zdir, localToFile);
1182 jcf_parse (current_jcf);
1184 layout_class (current_class);
1185 load_inner_classes (current_class);
1188 if (TYPE_SIZE (current_class) != error_mark_node)
1190 input_filename = current_jcf->filename;
1191 parse_class_file ();
1192 FREE (current_jcf->buffer); /* No longer necessary */
1193 /* Note: there is a way to free this buffer right after a
1194 class seen in a zip file has been parsed. The idea is the
1195 set its jcf in such a way that buffer will be reallocated
1196 the time the code for the class will be generated. FIXME. */
1201 /* Read all the entries of the zip file, creates a class and a JCF. Sets the
1202 jcf up for further processing and link it to the created class. */
1205 process_zip_dir (FILE *finput)
1210 for (i = 0, zdir = (ZipDirectory *)localToFile->central_directory;
1211 i < localToFile->count; i++, zdir = ZIPDIR_NEXT (zdir))
1213 char *class_name, *file_name, *class_name_in_zip_dir;
1218 class_name_in_zip_dir = ZIPDIR_FILENAME (zdir);
1220 /* We choose to not to process entries with a zero size or entries
1221 not bearing the .class extension. */
1222 if (!zdir->size || !zdir->filename_offset ||
1223 strncmp (&class_name_in_zip_dir[zdir->filename_length-6],
1226 /* So it will be skipped in parse_zip_file_entries */
1231 class_name = ALLOC (zdir->filename_length+1-6);
1232 file_name = ALLOC (zdir->filename_length+1);
1233 jcf = ALLOC (sizeof (JCF));
1236 strncpy (class_name, class_name_in_zip_dir, zdir->filename_length-6);
1237 class_name [zdir->filename_length-6] = '\0';
1238 strncpy (file_name, class_name_in_zip_dir, zdir->filename_length);
1239 file_name [zdir->filename_length] = '\0';
1241 for (j=0; class_name[j]; j++)
1242 class_name [j] = (class_name [j] == '/' ? '.' : class_name [j]);
1244 /* Yes, we write back the true class name into the zip directory. */
1245 strcpy (class_name_in_zip_dir, class_name);
1246 zdir->filename_length = j;
1247 class = lookup_class (get_identifier (class_name));
1249 jcf->read_state = finput;
1250 jcf->filbuf = jcf_filbuf_from_stdio;
1251 jcf->java_source = 0;
1252 jcf->classname = class_name;
1253 jcf->filename = file_name;
1256 TYPE_JCF (class) = jcf;
1260 /* Initialization. */
1265 /* Register roots with the garbage collector. */
1266 ggc_add_root (¤t_jcf, 1, sizeof (JCF), (void (*)(void *))ggc_mark_jcf);
1271 #include "gt-java-jcf-parse.h"