1 /* Parser for Java(TM) .class files.
2 Copyright (C) 1996, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006
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)
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> */
30 #include "coretypes.h"
36 #include "java-except.h"
38 #include "java-tree.h"
51 #ifdef HAVE_LANGINFO_CODESET
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) \
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]; \
67 (JCF)->cpool.data[INDEX].t = get_identifier ((const char *) text); \
68 text[LENGTH] = save; \
69 JCF_SKIP (JCF, LENGTH); } while (0)
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 /* The number of source files passd to us by -fsource-filename and an
93 array of pointers to each name. Used by find_sourcefile(). */
94 static int num_files
= 0;
95 static char **filenames
;
97 static struct ZipFile
*localToFile
;
99 /* Declarations of some functions used here. */
100 static void handle_innerclass_attribute (int count
, JCF
*);
101 static tree
give_name_to_class (JCF
*jcf
, int index
);
102 static char *compute_class_name (struct ZipDirectory
*zdir
);
103 static int classify_zip_file (struct ZipDirectory
*zdir
);
104 static void parse_zip_file_entries (void);
105 static void process_zip_dir (FILE *);
106 static void parse_source_file_1 (tree
, const char *, FILE *);
107 static void parse_source_file_2 (void);
108 static void parse_source_file_3 (void);
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
);
115 /* Handle "Deprecated" attribute. */
117 handle_deprecated (void)
119 if (current_field
!= NULL_TREE
)
120 FIELD_DEPRECATED (current_field
) = 1;
121 else if (current_method
!= NULL_TREE
)
122 METHOD_DEPRECATED (current_method
) = 1;
123 else if (current_class
!= NULL_TREE
)
124 CLASS_DEPRECATED (TYPE_NAME (current_class
)) = 1;
127 /* Shouldn't happen. */
134 /* Reverse a string. */
136 reverse (const char *s
)
142 int len
= strlen (s
);
143 char *d
= xmalloc (len
+ 1);
148 for (dp
= &d
[0], sp
= &s
[len
-1]; sp
>= s
; dp
++, sp
--)
155 /* Compare two strings for qsort(). */
157 cmpstringp (const void *p1
, const void *p2
)
159 /* The arguments to this function are "pointers to
160 pointers to char", but strcmp() arguments are "pointers
161 to char", hence the following cast plus dereference */
163 return strcmp(*(char **) p1
, *(char **) p2
);
166 /* Create an array of strings, one for each source file that we've
167 seen. fsource_filename can either be the name of a single .java
168 file or a file that contains a list of filenames separated by
171 java_read_sourcefilenames (const char *fsource_filename
)
175 && strlen (fsource_filename
) > strlen (".java")
176 && strcmp ((fsource_filename
177 + strlen (fsource_filename
)
181 /* fsource_filename isn't a .java file but a list of filenames
182 separated by newlines */
183 FILE *finput
= fopen (fsource_filename
, "r");
185 int longest_line
= 0;
189 /* Find out how many files there are, and how long the filenames are. */
190 while (! feof (finput
))
192 int ch
= getc (finput
);
196 if (len
> longest_line
)
208 /* Read the filenames. Put a pointer to each filename into the
211 char *linebuf
= alloca (longest_line
+ 1);
215 filenames
= xmalloc (num_files
* sizeof (char*));
220 int ch
= getc (finput
);
225 linebuf
[charpos
] = 0;
226 gcc_assert (i
< num_files
);
227 /* ??? Perhaps we should use lrealpath() here. Doing
228 so would tidy up things like /../ but the rest of
229 gcc seems to assume relative pathnames, not
230 absolute pathnames. */
231 /* realname = lrealpath (linebuf); */
232 filenames
[i
++] = reverse (linebuf
);
236 gcc_assert (charpos
< longest_line
);
237 linebuf
[charpos
++] = ch
;
241 qsort (filenames
, num_files
, sizeof (char *), cmpstringp
);
247 filenames
= xmalloc (sizeof (char*));
248 filenames
[0] = reverse (fsource_filename
);
253 /* Given a relative pathname such as foo/bar.java, attempt to find a
254 longer pathname with the same suffix.
256 This is a best guess heuristic; with some weird class hierarcies we
257 may fail to pick the correct source file. For example, if we have
258 the filenames foo/bar.java and also foo/foo/bar.java, we do not
259 have enough information to know which one is the right match for
263 find_sourcefile (const char *name
)
265 int i
= 0, j
= num_files
-1;
270 char *revname
= reverse (name
);
275 int cmp
= strncmp (revname
, filenames
[k
], strlen (revname
));
278 /* OK, so we found one. But is it a unique match? */
280 && strncmp (revname
, filenames
[k
-1], strlen (revname
)) == 0)
282 && (strncmp (revname
, filenames
[k
+1], strlen (revname
))
286 found
= filenames
[k
];
299 if (found
&& strlen (found
) > strlen (name
))
300 return reverse (found
);
307 /* Handle "SourceFile" attribute. */
310 set_source_filename (JCF
*jcf
, int index
)
312 tree sfname_id
= get_name_constant (jcf
, index
);
313 const char *sfname
= IDENTIFIER_POINTER (sfname_id
);
314 const char *old_filename
= input_filename
;
315 int new_len
= IDENTIFIER_LENGTH (sfname_id
);
316 if (old_filename
!= NULL
)
318 int old_len
= strlen (old_filename
);
319 /* Use the current input_filename (derived from the class name)
320 if it has a directory prefix, but otherwise matches sfname. */
321 if (old_len
> new_len
322 && strcmp (sfname
, old_filename
+ old_len
- new_len
) == 0
323 && (old_filename
[old_len
- new_len
- 1] == '/'
324 || old_filename
[old_len
- new_len
- 1] == '\\'))
326 #ifndef USE_MAPPED_LOCATION
327 input_filename
= find_sourcefile (input_filename
);
328 DECL_SOURCE_LOCATION (TYPE_NAME (current_class
)) = input_location
;
329 file_start_location
= input_location
;
334 if (strchr (sfname
, '/') == NULL
&& strchr (sfname
, '\\') == NULL
)
336 const char *class_name
337 = IDENTIFIER_POINTER (DECL_NAME (TYPE_NAME (current_class
)));
338 char *dot
= strrchr (class_name
, '.');
341 /* Length of prefix, not counting final dot. */
342 int i
= dot
- class_name
;
343 /* Concatenate current package prefix with new sfname. */
344 char *buf
= XNEWVEC (char, i
+ new_len
+ 2); /* Space for '.' and '\0'. */
345 strcpy (buf
+ i
+ 1, sfname
);
346 /* Copy package from class_name, replacing '.' by DIR_SEPARATOR.
347 Note we start at the end with the final package dot. */
350 char c
= class_name
[i
];
355 sfname_id
= get_identifier (buf
);
357 sfname
= IDENTIFIER_POINTER (sfname_id
);
361 sfname
= find_sourcefile (sfname
);
362 #ifdef USE_MAPPED_LOCATION
363 line_table
.maps
[line_table
.used
-1].to_file
= sfname
;
365 input_filename
= sfname
;
366 DECL_SOURCE_LOCATION (TYPE_NAME (current_class
)) = input_location
;
367 file_start_location
= input_location
;
369 if (current_class
== main_class
) main_input_filename
= sfname
;
372 #define HANDLE_SOURCEFILE(INDEX) set_source_filename (jcf, INDEX)
374 #define HANDLE_CLASS_INFO(ACCESS_FLAGS, THIS, SUPER, INTERFACES_COUNT) \
375 { tree super_class = SUPER==0 ? NULL_TREE : get_class_constant (jcf, SUPER); \
376 output_class = current_class = give_name_to_class (jcf, THIS); \
377 set_super_info (ACCESS_FLAGS, current_class, super_class, INTERFACES_COUNT);}
379 #define HANDLE_CLASS_INTERFACE(INDEX) \
380 add_interface (current_class, get_class_constant (jcf, INDEX))
382 #define HANDLE_START_FIELD(ACCESS_FLAGS, NAME, SIGNATURE, ATTRIBUTE_COUNT) \
383 { int sig_index = SIGNATURE; \
384 current_field = add_field (current_class, get_name_constant (jcf, NAME), \
385 parse_signature (jcf, sig_index), ACCESS_FLAGS); \
386 set_java_signature (TREE_TYPE (current_field), JPOOL_UTF (jcf, sig_index)); \
387 if ((ACCESS_FLAGS) & ACC_FINAL) \
388 MAYBE_CREATE_VAR_LANG_DECL_SPECIFIC (current_field); \
391 #define HANDLE_END_FIELDS() \
392 (current_field = NULL_TREE)
394 #define HANDLE_CONSTANTVALUE(INDEX) \
395 { tree constant; int index = INDEX; \
396 if (! flag_emit_class_files && JPOOL_TAG (jcf, index) == CONSTANT_String) { \
397 tree name = get_name_constant (jcf, JPOOL_USHORT1 (jcf, index)); \
398 constant = build_utf8_ref (name); \
401 constant = get_constant (jcf, index); \
402 set_constant_value (current_field, constant); }
404 #define HANDLE_METHOD(ACCESS_FLAGS, NAME, SIGNATURE, ATTRIBUTE_COUNT) \
405 (current_method = add_method (current_class, ACCESS_FLAGS, \
406 get_name_constant (jcf, NAME), \
407 get_name_constant (jcf, SIGNATURE)), \
408 DECL_LOCALVARIABLES_OFFSET (current_method) = 0, \
409 DECL_LINENUMBERS_OFFSET (current_method) = 0)
411 #define HANDLE_END_METHODS() \
412 { current_method = NULL_TREE; }
414 #define HANDLE_CODE_ATTRIBUTE(MAX_STACK, MAX_LOCALS, CODE_LENGTH) \
415 { DECL_MAX_STACK (current_method) = (MAX_STACK); \
416 DECL_MAX_LOCALS (current_method) = (MAX_LOCALS); \
417 DECL_CODE_LENGTH (current_method) = (CODE_LENGTH); \
418 DECL_CODE_OFFSET (current_method) = JCF_TELL (jcf); }
420 #define HANDLE_LOCALVARIABLETABLE_ATTRIBUTE(COUNT) \
422 DECL_LOCALVARIABLES_OFFSET (current_method) = JCF_TELL (jcf) - 2; \
423 JCF_SKIP (jcf, n * 10); }
425 #define HANDLE_LINENUMBERTABLE_ATTRIBUTE(COUNT) \
427 DECL_LINENUMBERS_OFFSET (current_method) = JCF_TELL (jcf) - 2; \
428 JCF_SKIP (jcf, n * 4); }
430 #define HANDLE_EXCEPTIONS_ATTRIBUTE(COUNT) \
433 tree list = DECL_FUNCTION_THROWS (current_method); \
436 tree thrown_class = get_class_constant (jcf, JCF_readu2 (jcf)); \
437 list = tree_cons (NULL_TREE, thrown_class, list); \
439 DECL_FUNCTION_THROWS (current_method) = nreverse (list); \
442 #define HANDLE_DEPRECATED_ATTRIBUTE() handle_deprecated ()
444 /* Link seen inner classes to their outer context and register the
445 inner class to its outer context. They will be later loaded. */
446 #define HANDLE_INNERCLASSES_ATTRIBUTE(COUNT) \
447 handle_innerclass_attribute (COUNT, jcf)
449 #define HANDLE_SYNTHETIC_ATTRIBUTE() \
451 /* Irrelevant decls should have been nullified by the END macros. \
452 We only handle the `Synthetic' attribute on method DECLs. \
453 DECL_ARTIFICIAL on fields is used for something else (See \
454 PUSH_FIELD in java-tree.h) */ \
455 if (current_method) \
456 DECL_ARTIFICIAL (current_method) = 1; \
459 #define HANDLE_GCJCOMPILED_ATTRIBUTE() \
461 if (current_class == object_type_node) \
462 jcf->right_zip = 1; \
465 #include "jcf-reader.c"
468 parse_signature (JCF
*jcf
, int sig_index
)
470 gcc_assert (sig_index
> 0
471 && sig_index
< JPOOL_SIZE (jcf
)
472 && JPOOL_TAG (jcf
, sig_index
) == CONSTANT_Utf8
);
474 return parse_signature_string (JPOOL_UTF_DATA (jcf
, sig_index
),
475 JPOOL_UTF_LENGTH (jcf
, sig_index
));
479 get_constant (JCF
*jcf
, int index
)
483 if (index
<= 0 || index
>= JPOOL_SIZE(jcf
))
485 tag
= JPOOL_TAG (jcf
, index
);
486 if ((tag
& CONSTANT_ResolvedFlag
) || tag
== CONSTANT_Utf8
)
487 return jcf
->cpool
.data
[index
].t
;
490 case CONSTANT_Integer
:
492 jint num
= JPOOL_INT(jcf
, index
);
493 value
= build_int_cst (int_type_node
, num
);
498 unsigned HOST_WIDE_INT num
= JPOOL_UINT (jcf
, index
);
499 unsigned HOST_WIDE_INT lo
;
502 lshift_double (num
, 0, 32, 64, &lo
, &hi
, 0);
503 num
= JPOOL_UINT (jcf
, index
+1);
504 add_double (lo
, hi
, num
, 0, &lo
, &hi
);
505 value
= build_int_cst_wide (long_type_node
, lo
, hi
);
506 value
= force_fit_type (value
, 0, false, false);
512 jint num
= JPOOL_INT(jcf
, index
);
516 real_from_target_fmt (&d
, &buf
, &ieee_single_format
);
517 value
= build_real (float_type_node
, d
);
521 case CONSTANT_Double
:
526 hi
= JPOOL_UINT (jcf
, index
);
527 lo
= JPOOL_UINT (jcf
, index
+1);
529 if (FLOAT_WORDS_BIG_ENDIAN
)
530 buf
[0] = hi
, buf
[1] = lo
;
532 buf
[0] = lo
, buf
[1] = hi
;
534 real_from_target_fmt (&d
, buf
, &ieee_double_format
);
535 value
= build_real (double_type_node
, d
);
539 case CONSTANT_String
:
541 tree name
= get_name_constant (jcf
, JPOOL_USHORT1 (jcf
, index
));
542 const char *utf8_ptr
= IDENTIFIER_POINTER (name
);
543 int utf8_len
= IDENTIFIER_LENGTH (name
);
544 const unsigned char *utf8
;
547 /* Check for a malformed Utf8 string. */
548 utf8
= (const unsigned char *) utf8_ptr
;
552 int char_len
= UT8_CHAR_LENGTH (*utf8
);
553 if (char_len
< 0 || char_len
> 3 || char_len
> i
)
554 fatal_error ("bad string constant");
560 /* Allocate a new string value. */
561 value
= build_string (utf8_len
, utf8_ptr
);
562 TREE_TYPE (value
) = build_pointer_type (string_type_node
);
568 JPOOL_TAG (jcf
, index
) = tag
| CONSTANT_ResolvedFlag
;
569 jcf
->cpool
.data
[index
].t
= value
;
572 internal_error ("bad value constant type %d, index %d",
573 JPOOL_TAG (jcf
, index
), index
);
577 get_name_constant (JCF
*jcf
, int index
)
579 tree name
= get_constant (jcf
, index
);
580 gcc_assert (TREE_CODE (name
) == IDENTIFIER_NODE
);
584 /* Handle reading innerclass attributes. If a nonzero entry (denoting
585 a non anonymous entry) is found, We augment the inner class list of
586 the outer context with the newly resolved innerclass. */
589 handle_innerclass_attribute (int count
, JCF
*jcf
)
594 /* Read inner_class_info_index. This may be 0 */
595 int icii
= JCF_readu2 (jcf
);
596 /* Read outer_class_info_index. If the innerclasses attribute
597 entry isn't a member (like an inner class) the value is 0. */
598 int ocii
= JCF_readu2 (jcf
);
599 /* Read inner_name_index. If the class we're dealing with is
600 an anonymous class, it must be 0. */
601 int ini
= JCF_readu2 (jcf
);
602 /* Read the access flag. */
603 int acc
= JCF_readu2 (jcf
);
604 /* If icii is 0, don't try to read the class. */
607 tree
class = get_class_constant (jcf
, icii
);
608 tree decl
= TYPE_NAME (class);
609 /* Skip reading further if ocii is null */
610 if (DECL_P (decl
) && !CLASS_COMPLETE_P (decl
) && ocii
)
612 tree outer
= TYPE_NAME (get_class_constant (jcf
, ocii
));
613 tree alias
= (ini
? get_name_constant (jcf
, ini
) : NULL_TREE
);
614 set_class_decl_access_flags (acc
, decl
);
615 DECL_CONTEXT (decl
) = outer
;
616 DECL_INNER_CLASS_LIST (outer
) =
617 tree_cons (decl
, alias
, DECL_INNER_CLASS_LIST (outer
));
618 CLASS_COMPLETE_P (decl
) = 1;
625 give_name_to_class (JCF
*jcf
, int i
)
628 && i
< JPOOL_SIZE (jcf
)
629 && JPOOL_TAG (jcf
, i
) == CONSTANT_Class
);
632 tree package_name
= NULL_TREE
, tmp
;
634 int j
= JPOOL_USHORT1 (jcf
, i
);
635 /* verify_constant_pool confirmed that j is a CONSTANT_Utf8. */
636 tree class_name
= unmangle_classname ((const char *) JPOOL_UTF_DATA (jcf
, j
),
637 JPOOL_UTF_LENGTH (jcf
, j
));
638 this_class
= lookup_class (class_name
);
639 #ifdef USE_MAPPED_LOCATION
641 tree source_name
= identifier_subst (class_name
, "", '.', '/', ".java");
642 const char *sfname
= IDENTIFIER_POINTER (source_name
);
643 linemap_add (&line_table
, LC_ENTER
, false, sfname
, 0);
644 input_location
= linemap_line_start (&line_table
, 0, 1);
645 file_start_location
= input_location
;
646 DECL_SOURCE_LOCATION (TYPE_NAME (this_class
)) = input_location
;
647 if (main_input_filename
== NULL
&& jcf
== main_jcf
)
648 main_input_filename
= sfname
;
651 input_location
= DECL_SOURCE_LOCATION (TYPE_NAME (this_class
));
652 if (main_input_filename
== NULL
&& jcf
== main_jcf
)
653 main_input_filename
= input_filename
;
656 jcf
->cpool
.data
[i
].t
= this_class
;
657 JPOOL_TAG (jcf
, i
) = CONSTANT_ResolvedClass
;
658 split_qualified_name (&package_name
, &tmp
,
659 DECL_NAME (TYPE_NAME (this_class
)));
660 TYPE_PACKAGE (this_class
) = package_name
;
665 /* Get the class of the CONSTANT_Class whose constant pool index is I. */
668 get_class_constant (JCF
*jcf
, int i
)
672 && i
< JPOOL_SIZE (jcf
)
673 && (JPOOL_TAG (jcf
, i
) & ~CONSTANT_ResolvedFlag
) == CONSTANT_Class
);
675 if (JPOOL_TAG (jcf
, i
) != CONSTANT_ResolvedClass
)
677 int name_index
= JPOOL_USHORT1 (jcf
, i
);
678 /* verify_constant_pool confirmed that name_index is a CONSTANT_Utf8. */
679 const char *name
= (const char *) JPOOL_UTF_DATA (jcf
, name_index
);
680 int nlength
= JPOOL_UTF_LENGTH (jcf
, name_index
);
682 if (name
[0] == '[') /* Handle array "classes". */
683 type
= TREE_TYPE (parse_signature_string ((const unsigned char *) name
, nlength
));
686 tree cname
= unmangle_classname (name
, nlength
);
687 type
= lookup_class (cname
);
689 jcf
->cpool
.data
[i
].t
= type
;
690 JPOOL_TAG (jcf
, i
) = CONSTANT_ResolvedClass
;
693 type
= jcf
->cpool
.data
[i
].t
;
697 /* Read a class with the fully qualified-name NAME.
698 Return 1 iff we read the requested file.
699 (It is still possible we failed if the file did not
700 define the class it is supposed to.) */
703 read_class (tree name
)
706 tree icv
, class = NULL_TREE
;
707 tree save_current_class
= current_class
;
708 tree save_output_class
= output_class
;
709 location_t save_location
= input_location
;
710 JCF
*save_current_jcf
= current_jcf
;
712 if ((icv
= IDENTIFIER_CLASS_VALUE (name
)) != NULL_TREE
)
714 class = TREE_TYPE (icv
);
715 jcf
= TYPE_JCF (class);
722 const char* path_name
;
723 this_jcf
.zipd
= NULL
;
726 path_name
= find_class (IDENTIFIER_POINTER (name
),
727 IDENTIFIER_LENGTH (name
),
732 free((char *) path_name
);
737 if (current_jcf
->java_source
)
739 const char *filename
= current_jcf
->filename
;
741 tree given_file
, real_file
;
745 java_parser_context_save_global ();
746 java_push_parser_context ();
748 given_file
= get_identifier (filename
);
749 filename
= IDENTIFIER_POINTER (given_file
);
750 real_path
= lrealpath (filename
);
751 real_file
= get_identifier (real_path
);
754 generate
= IS_A_COMMAND_LINE_FILENAME_P (given_file
);
755 output_class
= current_class
= NULL_TREE
;
756 current_function_decl
= NULL_TREE
;
758 if (! HAS_BEEN_ALREADY_PARSED_P (real_file
))
760 if (! (finput
= fopen (filename
, "r")))
761 fatal_error ("can't reopen %s: %m", filename
);
763 parse_source_file_1 (real_file
, filename
, finput
);
764 parse_source_file_2 ();
765 parse_source_file_3 ();
768 fatal_error ("can't close %s: %m", input_filename
);
769 #ifdef USE_MAPPED_LOCATION
770 linemap_add (&line_table
, LC_LEAVE
, false, NULL
, 0);
773 JCF_FINISH (current_jcf
);
774 java_pop_parser_context (generate
);
775 java_parser_context_restore_global ();
779 if (class == NULL_TREE
|| ! CLASS_PARSED_P (class))
781 java_parser_context_save_global ();
782 java_push_parser_context ();
783 output_class
= current_class
= class;
784 ctxp
->save_location
= input_location
;
785 if (JCF_SEEN_IN_ZIP (current_jcf
))
786 read_zip_member(current_jcf
,
787 current_jcf
->zipd
, current_jcf
->zipd
->zipf
);
788 jcf_parse (current_jcf
);
789 /* Parsing might change the class, in which case we have to
790 put it back where we found it. */
791 if (current_class
!= class && icv
!= NULL_TREE
)
792 TREE_TYPE (icv
) = current_class
;
793 class = current_class
;
794 java_pop_parser_context (0);
795 java_parser_context_restore_global ();
797 layout_class (class);
798 load_inner_classes (class);
801 output_class
= save_output_class
;
802 current_class
= save_current_class
;
803 input_location
= save_location
;
804 current_jcf
= save_current_jcf
;
808 /* Load CLASS_OR_NAME. CLASS_OR_NAME can be a mere identifier if
809 called from the parser, otherwise it's a RECORD_TYPE node. If
810 VERBOSE is 1, print error message on failure to load a class. */
812 load_class (tree class_or_name
, int verbose
)
815 int class_loaded
= 0;
816 tree class_decl
= NULL_TREE
;
817 bool is_compiled_class
= false;
819 /* We've already failed, don't try again. */
820 if (TREE_CODE (class_or_name
) == RECORD_TYPE
821 && TYPE_DUMMY (class_or_name
))
824 /* class_or_name can be the name of the class we want to load */
825 if (TREE_CODE (class_or_name
) == IDENTIFIER_NODE
)
826 name
= class_or_name
;
827 /* In some cases, it's a dependency that we process earlier that
829 else if (TREE_CODE (class_or_name
) == TREE_LIST
)
830 name
= TYPE_NAME (TREE_PURPOSE (class_or_name
));
831 /* Or it's a type in the making */
833 name
= DECL_NAME (TYPE_NAME (class_or_name
));
835 class_decl
= IDENTIFIER_CLASS_VALUE (name
);
836 if (class_decl
!= NULL_TREE
)
838 tree type
= TREE_TYPE (class_decl
);
840 = ((TYPE_JCF (type
) && JCF_SEEN_IN_ZIP (TYPE_JCF (type
)))
841 || CLASS_FROM_CURRENTLY_COMPILED_P (type
));
844 /* If the class is from source code, then it must already be loaded. */
845 class_decl
= IDENTIFIER_CLASS_VALUE (name
);
846 if (class_decl
&& CLASS_FROM_SOURCE_P (TREE_TYPE (class_decl
)))
851 /* If flag_verify_invocations is unset, we don't try to load a class
852 unless we're looking for Object (which is fixed by the ABI) or
853 it's a class that we're going to compile. */
854 if (flag_verify_invocations
855 || class_or_name
== object_type_node
857 || TREE_CODE (class_or_name
) == IDENTIFIER_NODE
)
863 /* We've already loaded it. */
864 if (IDENTIFIER_CLASS_VALUE (name
) != NULL_TREE
)
866 tree tmp_decl
= IDENTIFIER_CLASS_VALUE (name
);
867 if (CLASS_PARSED_P (TREE_TYPE (tmp_decl
)))
871 if (read_class (name
))
874 /* We failed loading name. Now consider that we might be looking
875 for an inner class. */
876 if ((separator
= strrchr (IDENTIFIER_POINTER (name
), '$'))
877 || (separator
= strrchr (IDENTIFIER_POINTER (name
), '.')))
881 name
= get_identifier (IDENTIFIER_POINTER (name
));
884 /* Otherwise, we failed, we bail. */
890 /* have we found the class we're looking for? */
891 tree type_decl
= IDENTIFIER_CLASS_VALUE (saved
);
892 tree type
= type_decl
? TREE_TYPE (type_decl
) : NULL
;
893 class_loaded
= type
&& CLASS_PARSED_P (type
);
899 if (flag_verify_invocations
|| ! flag_indirect_dispatch
900 || flag_emit_class_files
)
903 error ("cannot find file for class %s", IDENTIFIER_POINTER (saved
));
907 /* This is just a diagnostic during testing, not a real problem. */
909 warning (0, "cannot find file for class %s",
910 IDENTIFIER_POINTER (saved
));
913 if (TREE_CODE (class_or_name
) == RECORD_TYPE
)
915 set_super_info (0, class_or_name
, object_type_node
, 0);
916 TYPE_DUMMY (class_or_name
) = 1;
917 /* We won't be able to output any debug info for this class. */
918 DECL_IGNORED_P (TYPE_NAME (class_or_name
)) = 1;
924 /* Parse the .class file JCF. */
931 if (jcf_parse_preamble (jcf
) != 0)
932 fatal_error ("not a valid Java .class file");
933 code
= jcf_parse_constant_pool (jcf
);
935 fatal_error ("error while parsing constant pool");
936 code
= verify_constant_pool (jcf
);
938 fatal_error ("error in constant pool entry #%d\n", code
);
940 jcf_parse_class (jcf
);
941 if (main_class
== NULL_TREE
)
942 main_class
= current_class
;
943 if (! quiet_flag
&& TYPE_NAME (current_class
))
944 fprintf (stderr
, " %s %s",
945 (jcf
->access_flags
& ACC_INTERFACE
) ? "interface" : "class",
946 IDENTIFIER_POINTER (DECL_NAME (TYPE_NAME (current_class
))));
947 if (CLASS_PARSED_P (current_class
))
949 /* FIXME - where was first time */
950 fatal_error ("reading class %s for the second time from %s",
951 IDENTIFIER_POINTER (DECL_NAME (TYPE_NAME (current_class
))),
954 CLASS_PARSED_P (current_class
) = 1;
956 for (i
= 1; i
< JPOOL_SIZE(jcf
); i
++)
958 switch (JPOOL_TAG (jcf
, i
))
961 get_class_constant (jcf
, i
);
966 code
= jcf_parse_fields (jcf
);
968 fatal_error ("error while parsing fields");
969 code
= jcf_parse_methods (jcf
);
971 fatal_error ("error while parsing methods");
972 code
= jcf_parse_final_attributes (jcf
);
974 fatal_error ("error while parsing final attributes");
975 #ifdef USE_MAPPED_LOCATION
976 linemap_add (&line_table
, LC_LEAVE
, false, NULL
, 0);
979 /* The fields of class_type_node are already in correct order. */
980 if (current_class
!= class_type_node
&& current_class
!= object_type_node
)
981 TYPE_FIELDS (current_class
) = nreverse (TYPE_FIELDS (current_class
));
983 if (current_class
== object_type_node
)
985 layout_class_methods (object_type_node
);
986 /* If we don't have the right archive, emit a verbose warning.
987 If we're generating bytecode, emit the warning only if
988 -fforce-classes-archive-check was specified. */
990 /* ECJ HACK: ignore this. */
992 && (!flag_emit_class_files
|| flag_force_classes_archive_check
))
993 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
);
997 all_class_list
= tree_cons (NULL_TREE
,
998 TYPE_NAME (current_class
), all_class_list
);
1001 /* If we came across inner classes, load them now. */
1003 load_inner_classes (tree cur_class
)
1006 for (current
= DECL_INNER_CLASS_LIST (TYPE_NAME (cur_class
)); current
;
1007 current
= TREE_CHAIN (current
))
1009 tree name
= DECL_NAME (TREE_PURPOSE (current
));
1010 tree decl
= IDENTIFIER_GLOBAL_VALUE (name
);
1011 if (decl
&& ! CLASS_LOADED_P (TREE_TYPE (decl
))
1012 && !CLASS_BEING_LAIDOUT (TREE_TYPE (decl
)))
1013 load_class (name
, 1);
1018 duplicate_class_warning (const char *filename
)
1020 location_t warn_loc
;
1021 #ifdef USE_MAPPED_LOCATION
1022 linemap_add (&line_table
, LC_RENAME
, 0, filename
, 0);
1023 warn_loc
= linemap_line_start (&line_table
, 0, 1);
1025 warn_loc
.file
= filename
;
1028 warning (0, "%Hduplicate class will only be compiled once", &warn_loc
);
1032 parse_class_file (void)
1035 location_t save_location
= input_location
;
1037 java_layout_seen_class_methods ();
1039 input_location
= DECL_SOURCE_LOCATION (TYPE_NAME (current_class
));
1040 file_start_location
= input_location
;
1041 (*debug_hooks
->start_source_file
) (input_line
, input_filename
);
1043 gen_indirect_dispatch_tables (current_class
);
1045 for (method
= TYPE_METHODS (current_class
);
1046 method
!= NULL_TREE
; method
= TREE_CHAIN (method
))
1048 JCF
*jcf
= current_jcf
;
1050 if (METHOD_ABSTRACT (method
) || METHOD_DUMMY (method
))
1053 if (METHOD_NATIVE (method
))
1056 int decl_max_locals
;
1060 /* We need to compute the DECL_MAX_LOCALS. We need to take
1061 the wide types into account too. */
1062 for (arg
= TYPE_ARG_TYPES (TREE_TYPE (method
)), decl_max_locals
= 0;
1063 arg
!= end_params_node
;
1064 arg
= TREE_CHAIN (arg
), decl_max_locals
+= 1)
1066 if (TREE_VALUE (arg
) && TYPE_IS_WIDE (TREE_VALUE (arg
)))
1067 decl_max_locals
+= 1;
1069 DECL_MAX_LOCALS (method
) = decl_max_locals
;
1070 start_java_method (method
);
1071 give_name_to_locals (jcf
);
1072 *get_stmts () = build_jni_stub (method
);
1077 if (DECL_CODE_OFFSET (method
) == 0)
1079 current_function_decl
= method
;
1080 error ("missing Code attribute");
1084 input_location
= DECL_SOURCE_LOCATION (TYPE_NAME (current_class
));
1085 if (DECL_LINENUMBERS_OFFSET (method
))
1090 JCF_SEEK (jcf
, DECL_LINENUMBERS_OFFSET (method
));
1091 linenumber_count
= i
= JCF_readu2 (jcf
);
1092 linenumber_table
= ptr
= jcf
->read_ptr
;
1094 for (ptr
+= 2; --i
>= 0; ptr
+= 4)
1096 int line
= GET_u2 (ptr
);
1097 /* Set initial input_line to smallest linenumber.
1098 * Needs to be set before init_function_start. */
1099 if (min_line
== 0 || line
< min_line
)
1102 #ifdef USE_MAPPED_LOCATION
1104 input_location
= linemap_line_start (&line_table
, min_line
, 1);
1107 input_line
= min_line
;
1112 linenumber_table
= NULL
;
1113 linenumber_count
= 0;
1116 start_java_method (method
);
1118 note_instructions (jcf
, method
);
1120 give_name_to_locals (jcf
);
1122 /* Bump up start_label_pc_this_method so we get a unique label number
1123 and reset highest_label_pc_this_method. */
1124 if (highest_label_pc_this_method
>= 0)
1126 /* We adjust to the next multiple of 1000. This is just a frill
1127 so the last 3 digits of the label number match the bytecode
1128 offset, which might make debugging marginally more convenient. */
1129 start_label_pc_this_method
1130 = ((((start_label_pc_this_method
+ highest_label_pc_this_method
)
1134 highest_label_pc_this_method
= -1;
1137 /* Convert bytecode to trees. */
1138 expand_byte_code (jcf
, method
);
1143 if (flag_emit_class_files
)
1144 write_classfile (current_class
);
1148 (*debug_hooks
->end_source_file
) (LOCATION_LINE (save_location
));
1149 input_location
= save_location
;
1152 /* Parse a source file, as pointed by the current value of INPUT_FILENAME. */
1155 parse_source_file_1 (tree real_file
, const char *filename
, FILE *finput
)
1157 int save_error_count
= java_error_count
;
1159 /* Mark the file as parsed. */
1160 HAS_BEEN_ALREADY_PARSED_P (real_file
) = 1;
1162 lang_init_source (1); /* Error msgs have no method prototypes */
1164 /* There's no point in trying to find the current encoding unless we
1165 are going to do something intelligent with it -- hence the test
1167 #if defined (HAVE_LOCALE_H) && defined (HAVE_ICONV) && defined (HAVE_LANGINFO_CODESET)
1168 setlocale (LC_CTYPE
, "");
1169 if (current_encoding
== NULL
)
1170 current_encoding
= nl_langinfo (CODESET
);
1172 if (current_encoding
== NULL
|| *current_encoding
== '\0')
1173 current_encoding
= DEFAULT_ENCODING
;
1175 #ifdef USE_MAPPED_LOCATION
1176 linemap_add (&line_table
, LC_ENTER
, false, filename
, 0);
1177 input_location
= linemap_line_start (&line_table
, 0, 125);
1179 input_filename
= filename
;
1182 ctxp
->file_start_location
= input_location
;
1183 ctxp
->filename
= filename
;
1185 jcf_dependency_add_file (input_filename
, 0);
1187 /* Initialize the parser */
1188 java_init_lex (finput
, current_encoding
);
1189 java_parse_abort_on_error ();
1191 java_parse (); /* Parse and build partial tree nodes. */
1192 java_parse_abort_on_error ();
1195 /* Process a parsed source file, resolving names etc. */
1198 parse_source_file_2 (void)
1200 int save_error_count
= java_error_count
;
1201 flag_verify_invocations
= true;
1202 java_complete_class (); /* Parse unsatisfied class decl. */
1203 java_parse_abort_on_error ();
1207 parse_source_file_3 (void)
1209 int save_error_count
= java_error_count
;
1210 java_check_circular_reference (); /* Check on circular references */
1211 java_parse_abort_on_error ();
1212 java_fix_constructors (); /* Fix the constructors */
1213 java_parse_abort_on_error ();
1214 java_reorder_fields (); /* Reorder the fields */
1218 add_predefined_file (tree name
)
1220 predef_filenames
= tree_cons (NULL_TREE
, name
, predef_filenames
);
1224 predefined_filename_p (tree node
)
1228 for (iter
= predef_filenames
; iter
!= NULL_TREE
; iter
= TREE_CHAIN (iter
))
1230 if (TREE_VALUE (iter
) == node
)
1236 /* Generate a function that does all static initialization for this
1237 translation unit. */
1240 java_emit_static_constructor (void)
1244 emit_register_classes (&body
);
1245 write_resource_constructor (&body
);
1248 cgraph_build_static_cdtor ('I', body
, DEFAULT_INIT_PRIORITY
);
1252 java_parse_file (int set_yydebug ATTRIBUTE_UNUSED
)
1254 int filename_count
= 0;
1255 location_t save_location
= input_location
;
1256 char *file_list
= NULL
, *list
, *next
;
1258 FILE *finput
= NULL
;
1261 if (flag_filelist_file
)
1264 finput
= fopen (main_input_filename
, "r");
1266 fatal_error ("can't open %s: %m", input_filename
);
1267 list
= XNEWVEC (char, avail
);
1274 count
= next
- list
;
1275 avail
= 2 * (count
+ avail
);
1276 list
= xrealloc (list
, avail
);
1277 next
= list
+ count
;
1278 avail
= avail
- count
;
1280 /* Subtract to to guarantee space for final '\0'. */
1281 count
= fread (next
, 1, avail
- 1, finput
);
1284 if (! feof (finput
))
1285 fatal_error ("error closing %s: %m", input_filename
);
1297 list
= (char *) main_input_filename
;
1301 for (next
= list
; ; )
1304 if (flag_filelist_file
&& ! in_quotes
1305 && (ch
== '\n' || ch
== '\r' || ch
== '\t' || ch
== ' '
1306 || ch
== '&') /* FIXME */)
1320 if (flag_filelist_file
&& ch
== '"')
1322 in_quotes
= ! in_quotes
;
1337 /* Exclude .java files. */
1338 if (strlen (list
) > 5 && ! strcmp (list
+ strlen (list
) - 5, ".java"))
1344 node
= get_identifier (list
);
1348 /* Exclude file that we see twice on the command line. */
1350 if (IS_A_COMMAND_LINE_FILENAME_P (node
))
1351 duplicate_class_warning (IDENTIFIER_POINTER (node
));
1354 tree file_decl
= build_decl (TRANSLATION_UNIT_DECL
, node
, NULL
);
1355 TREE_CHAIN (file_decl
) = current_file_list
;
1356 current_file_list
= file_decl
;
1357 IS_A_COMMAND_LINE_FILENAME_P (node
) = 1;
1363 if (file_list
!= NULL
)
1366 if (filename_count
== 0)
1367 warning (0, "no input file specified");
1371 const char *resource_filename
;
1373 /* Only one resource file may be compiled at a time. */
1374 assert (TREE_CHAIN (current_file_list
) == NULL
);
1376 resource_filename
= IDENTIFIER_POINTER (DECL_NAME (current_file_list
));
1377 compile_resource_file (resource_name
, resource_filename
);
1382 current_jcf
= main_jcf
;
1383 current_file_list
= nreverse (current_file_list
);
1384 for (node
= current_file_list
; node
; node
= TREE_CHAIN (node
))
1386 unsigned char magic_string
[4];
1389 tree name
= DECL_NAME (node
);
1391 const char *filename
= IDENTIFIER_POINTER (name
);
1393 /* Skip already parsed files */
1394 real_path
= lrealpath (filename
);
1395 real_file
= get_identifier (real_path
);
1397 if (HAS_BEEN_ALREADY_PARSED_P (real_file
))
1400 /* Close previous descriptor, if any */
1401 if (finput
&& fclose (finput
))
1402 fatal_error ("can't close input file %s: %m", main_input_filename
);
1404 finput
= fopen (filename
, "rb");
1406 fatal_error ("can't open %s: %m", filename
);
1408 #ifdef IO_BUFFER_SIZE
1409 setvbuf (finput
, xmalloc (IO_BUFFER_SIZE
),
1410 _IOFBF
, IO_BUFFER_SIZE
);
1413 /* Figure what kind of file we're dealing with */
1414 if (fread (magic_string
, 1, 4, finput
) == 4)
1416 fseek (finput
, 0L, SEEK_SET
);
1417 magic
= GET_u4 (magic_string
);
1419 if (magic
== 0xcafebabe)
1421 CLASS_FILE_P (node
) = 1;
1422 current_jcf
= ggc_alloc (sizeof (JCF
));
1423 JCF_ZERO (current_jcf
);
1424 current_jcf
->read_state
= finput
;
1425 current_jcf
->filbuf
= jcf_filbuf_from_stdio
;
1426 jcf_parse (current_jcf
);
1427 DECL_SOURCE_LOCATION (node
) = file_start_location
;
1428 TYPE_JCF (current_class
) = current_jcf
;
1429 if (CLASS_FROM_CURRENTLY_COMPILED_P (current_class
))
1431 /* We've already compiled this class. */
1432 duplicate_class_warning (filename
);
1435 CLASS_FROM_CURRENTLY_COMPILED_P (current_class
) = 1;
1436 TREE_TYPE (node
) = current_class
;
1438 else if (magic
== (JCF_u4
)ZIPMAGIC
)
1440 main_jcf
= ggc_alloc (sizeof (JCF
));
1441 JCF_ZERO (main_jcf
);
1442 main_jcf
->read_state
= finput
;
1443 main_jcf
->filbuf
= jcf_filbuf_from_stdio
;
1444 #ifdef USE_MAPPED_LOCATION
1445 linemap_add (&line_table
, LC_ENTER
, false, filename
, 0);
1446 input_location
= linemap_line_start (&line_table
, 0, 1);
1448 if (open_in_zip (main_jcf
, filename
, NULL
, 0) < 0)
1449 fatal_error ("bad zip/jar file %s", filename
);
1450 localToFile
= SeenZipFiles
;
1451 /* Register all the classes defined there. */
1452 process_zip_dir (main_jcf
->read_state
);
1453 #ifdef USE_MAPPED_LOCATION
1454 linemap_add (&line_table
, LC_LEAVE
, false, NULL
, 0);
1456 parse_zip_file_entries ();
1460 java_push_parser_context ();
1461 java_parser_context_save_global ();
1463 parse_source_file_1 (real_file
, filename
, finput
);
1464 java_parser_context_restore_global ();
1465 java_pop_parser_context (1);
1466 #ifdef USE_MAPPED_LOCATION
1467 linemap_add (&line_table
, LC_LEAVE
, false, NULL
, 0);
1472 for (ctxp
= ctxp_for_generation
; ctxp
; ctxp
= ctxp
->next
)
1474 input_location
= ctxp
->file_start_location
;
1475 parse_source_file_2 ();
1478 for (ctxp
= ctxp_for_generation
; ctxp
; ctxp
= ctxp
->next
)
1480 input_location
= ctxp
->file_start_location
;
1481 parse_source_file_3 ();
1484 /* Do this before lowering any code. */
1485 for (node
= current_file_list
; node
; node
= TREE_CHAIN (node
))
1487 if (CLASS_FILE_P (node
))
1488 java_mark_class_local (TREE_TYPE (node
));
1491 for (node
= current_file_list
; node
; node
= TREE_CHAIN (node
))
1493 input_location
= DECL_SOURCE_LOCATION (node
);
1494 if (CLASS_FILE_P (node
))
1496 /* FIXME: These two flags really should be independent. We
1497 should be able to compile fully binary compatible, but
1498 with flag_verify_invocations on. */
1499 flag_verify_invocations
= ! flag_indirect_dispatch
;
1500 output_class
= current_class
= TREE_TYPE (node
);
1502 current_jcf
= TYPE_JCF (current_class
);
1503 layout_class (current_class
);
1504 load_inner_classes (current_class
);
1505 parse_class_file ();
1506 JCF_FINISH (current_jcf
);
1509 input_location
= save_location
;
1511 java_expand_classes ();
1512 if (java_report_errors () || flag_syntax_only
)
1515 /* Expand all classes compiled from source. */
1516 java_finish_classes ();
1519 /* Arrange for any necessary initialization to happen. */
1520 java_emit_static_constructor ();
1522 /* Only finalize the compilation unit after we've told cgraph which
1523 functions have their addresses stored. */
1524 cgraph_finalize_compilation_unit ();
1529 /* Return the name of the class corresponding to the name of the file
1530 in this zip entry. The result is newly allocated using ALLOC. */
1532 compute_class_name (struct ZipDirectory
*zdir
)
1534 char *class_name_in_zip_dir
= ZIPDIR_FILENAME (zdir
);
1537 int filename_length
= zdir
->filename_length
;
1539 while (filename_length
> 2 && strncmp (class_name_in_zip_dir
, "./", 2) == 0)
1541 class_name_in_zip_dir
+= 2;
1542 filename_length
-= 2;
1545 filename_length
-= strlen (".class");
1546 class_name
= XNEWVEC (char, filename_length
+ 1);
1547 memcpy (class_name
, class_name_in_zip_dir
, filename_length
);
1548 class_name
[filename_length
] = '\0';
1550 for (i
= 0; i
< filename_length
; i
++)
1551 if (class_name
[i
] == '/')
1552 class_name
[i
] = '.';
1557 /* Return 0 if we should skip this entry, 1 if it is a .class file, 2
1558 if it is a property file of some sort. */
1560 classify_zip_file (struct ZipDirectory
*zdir
)
1562 char *class_name_in_zip_dir
= ZIPDIR_FILENAME (zdir
);
1564 if (zdir
->filename_length
> 6
1565 && !strncmp (&class_name_in_zip_dir
[zdir
->filename_length
- 6],
1569 /* For now we drop the manifest, but not other information. */
1570 if (zdir
->filename_length
== 20
1571 && !strncmp (class_name_in_zip_dir
, "META-INF/MANIFEST.MF", 20))
1574 /* Drop directory entries. */
1575 if (zdir
->filename_length
> 0
1576 && class_name_in_zip_dir
[zdir
->filename_length
- 1] == '/')
1582 /* Process all class entries found in the zip file. */
1584 parse_zip_file_entries (void)
1586 struct ZipDirectory
*zdir
;
1589 for (i
= 0, zdir
= (ZipDirectory
*)localToFile
->central_directory
;
1590 i
< localToFile
->count
; i
++, zdir
= ZIPDIR_NEXT (zdir
))
1594 switch (classify_zip_file (zdir
))
1601 char *class_name
= compute_class_name (zdir
);
1602 class = lookup_class (get_identifier (class_name
));
1604 current_jcf
= TYPE_JCF (class);
1605 output_class
= current_class
= class;
1607 /* This is a dummy class, and now we're compiling it for
1609 gcc_assert (! TYPE_DUMMY (class));
1611 /* This is for a corner case where we have a superclass
1612 but no superclass fields.
1614 This can happen if we earlier failed to lay out this
1615 class because its superclass was still in the process
1616 of being laid out; this occurs when we have recursive
1617 class dependencies via inner classes. Setting
1618 TYPE_SIZE to null here causes CLASS_LOADED_P to return
1619 false, so layout_class() will be called again. */
1620 if (TYPE_SIZE (class) && CLASSTYPE_SUPER (class)
1621 && integer_zerop (TYPE_SIZE (class)))
1622 TYPE_SIZE (class) = NULL_TREE
;
1624 if (! CLASS_LOADED_P (class))
1626 if (! CLASS_PARSED_P (class))
1628 read_zip_member (current_jcf
, zdir
, localToFile
);
1629 jcf_parse (current_jcf
);
1631 layout_class (current_class
);
1632 load_inner_classes (current_class
);
1635 if (TYPE_SIZE (current_class
) != error_mark_node
)
1637 parse_class_file ();
1638 free (current_jcf
->buffer
); /* No longer necessary */
1639 /* Note: there is a way to free this buffer right after a
1640 class seen in a zip file has been parsed. The idea is the
1641 set its jcf in such a way that buffer will be reallocated
1642 the time the code for the class will be generated. FIXME. */
1649 char *file_name
, *class_name_in_zip_dir
, *buffer
;
1651 file_name
= XNEWVEC (char, zdir
->filename_length
+ 1);
1652 class_name_in_zip_dir
= ZIPDIR_FILENAME (zdir
);
1653 strncpy (file_name
, class_name_in_zip_dir
, zdir
->filename_length
);
1654 file_name
[zdir
->filename_length
] = '\0';
1657 jcf
->read_state
= finput
;
1658 jcf
->filbuf
= jcf_filbuf_from_stdio
;
1659 jcf
->java_source
= 0;
1660 jcf
->classname
= NULL
;
1661 jcf
->filename
= file_name
;
1664 if (read_zip_member (jcf
, zdir
, localToFile
) < 0)
1665 fatal_error ("error while reading %s from zip file", file_name
);
1667 buffer
= XNEWVEC (char, zdir
->filename_length
+ 1 +
1668 (jcf
->buffer_end
- jcf
->buffer
));
1669 strcpy (buffer
, file_name
);
1670 /* This is not a typo: we overwrite the trailing \0 of the
1671 file name; this is just how the data is laid out. */
1672 memcpy (buffer
+ zdir
->filename_length
,
1673 jcf
->buffer
, jcf
->buffer_end
- jcf
->buffer
);
1675 compile_resource_data (file_name
, buffer
,
1676 jcf
->buffer_end
- jcf
->buffer
);
1689 /* Read all the entries of the zip file, creates a class and a JCF. Sets the
1690 jcf up for further processing and link it to the created class. */
1693 process_zip_dir (FILE *finput
)
1698 for (i
= 0, zdir
= (ZipDirectory
*)localToFile
->central_directory
;
1699 i
< localToFile
->count
; i
++, zdir
= ZIPDIR_NEXT (zdir
))
1701 char *class_name
, *file_name
, *class_name_in_zip_dir
;
1705 class_name_in_zip_dir
= ZIPDIR_FILENAME (zdir
);
1707 /* Here we skip non-class files; we handle them later. */
1708 if (classify_zip_file (zdir
) != 1)
1711 class_name
= compute_class_name (zdir
);
1712 file_name
= XNEWVEC (char, zdir
->filename_length
+1);
1713 jcf
= ggc_alloc (sizeof (JCF
));
1716 strncpy (file_name
, class_name_in_zip_dir
, zdir
->filename_length
);
1717 file_name
[zdir
->filename_length
] = '\0';
1719 class = lookup_class (get_identifier (class_name
));
1721 if (CLASS_FROM_CURRENTLY_COMPILED_P (class))
1723 /* We've already compiled this class. */
1724 duplicate_class_warning (file_name
);
1727 /* This function is only called when processing a zip file seen
1728 on the command line. */
1729 CLASS_FROM_CURRENTLY_COMPILED_P (class) = 1;
1731 jcf
->read_state
= finput
;
1732 jcf
->filbuf
= jcf_filbuf_from_stdio
;
1733 jcf
->java_source
= 0;
1734 jcf
->classname
= class_name
;
1735 jcf
->filename
= file_name
;
1738 TYPE_JCF (class) = jcf
;
1742 /* Initialization. */
1745 init_jcf_parse (void)
1750 #include "gt-java-jcf-parse.h"