2006-08-07 Andrew John Hughes <gnu_andrew@member.fsf.org>
[official-gcc.git] / gcc / java / jcf-parse.c
blobf1ceb38593fcaaf4d469e42e33e34ac23dd63e8c
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)
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 /* 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. */
116 static void
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;
125 else
127 /* Shouldn't happen. */
128 gcc_unreachable ();
134 /* Reverse a string. */
135 static char *
136 reverse (const char *s)
138 if (s == NULL)
139 return NULL;
140 else
142 int len = strlen (s);
143 char *d = xmalloc (len + 1);
144 const char *sp;
145 char *dp;
147 d[len] = 0;
148 for (dp = &d[0], sp = &s[len-1]; sp >= s; dp++, sp--)
149 *dp = *sp;
151 return d;
155 /* Compare two strings for qsort(). */
156 static int
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
169 newlines. */
170 void
171 java_read_sourcefilenames (const char *fsource_filename)
173 if (fsource_filename
174 && filenames == 0
175 && strlen (fsource_filename) > strlen (".java")
176 && strcmp ((fsource_filename
177 + strlen (fsource_filename)
178 - strlen (".java")),
179 ".java") != 0)
181 /* fsource_filename isn't a .java file but a list of filenames
182 separated by newlines */
183 FILE *finput = fopen (fsource_filename, "r");
184 int len = 0;
185 int longest_line = 0;
187 gcc_assert (finput);
189 /* Find out how many files there are, and how long the filenames are. */
190 while (! feof (finput))
192 int ch = getc (finput);
193 if (ch == '\n')
195 num_files++;
196 if (len > longest_line)
197 longest_line = len;
198 len = 0;
199 continue;
201 if (ch == EOF)
202 break;
203 len++;
206 rewind (finput);
208 /* Read the filenames. Put a pointer to each filename into the
209 array FILENAMES. */
211 char *linebuf = alloca (longest_line + 1);
212 int i = 0;
213 int charpos;
215 filenames = xmalloc (num_files * sizeof (char*));
217 charpos = 0;
218 for (;;)
220 int ch = getc (finput);
221 if (ch == EOF)
222 break;
223 if (ch == '\n')
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);
233 charpos = 0;
234 continue;
236 gcc_assert (charpos < longest_line);
237 linebuf[charpos++] = ch;
240 if (num_files > 1)
241 qsort (filenames, num_files, sizeof (char *), cmpstringp);
243 fclose (finput);
245 else
247 filenames = xmalloc (sizeof (char*));
248 filenames[0] = reverse (fsource_filename);
249 num_files = 1;
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
260 foo/bar.java. */
262 static const char *
263 find_sourcefile (const char *name)
265 int i = 0, j = num_files-1;
266 char *found = NULL;
268 if (filenames)
270 char *revname = reverse (name);
274 int k = (i+j) / 2;
275 int cmp = strncmp (revname, filenames[k], strlen (revname));
276 if (cmp == 0)
278 /* OK, so we found one. But is it a unique match? */
279 if ((k > i
280 && strncmp (revname, filenames[k-1], strlen (revname)) == 0)
281 || (k < j
282 && (strncmp (revname, filenames[k+1], strlen (revname))
283 == 0)))
285 else
286 found = filenames[k];
287 break;
289 if (cmp > 0)
290 i = k+1;
291 else
292 j = k-1;
294 while (i <= j);
296 free (revname);
299 if (found && strlen (found) > strlen (name))
300 return reverse (found);
301 else
302 return name;
307 /* Handle "SourceFile" attribute. */
309 static void
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;
330 #endif
331 return;
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, '.');
339 if (dot != NULL)
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. */
348 for (; i >= 0; i--)
350 char c = class_name[i];
351 if (c == '.')
352 c = DIR_SEPARATOR;
353 buf[i] = c;
355 sfname_id = get_identifier (buf);
356 free (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;
364 #else
365 input_filename = sfname;
366 DECL_SOURCE_LOCATION (TYPE_NAME (current_class)) = input_location;
367 file_start_location = input_location;
368 #endif
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); \
400 else \
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) \
421 { int n = (COUNT); \
422 DECL_LOCALVARIABLES_OFFSET (current_method) = JCF_TELL (jcf) - 2; \
423 JCF_SKIP (jcf, n * 10); }
425 #define HANDLE_LINENUMBERTABLE_ATTRIBUTE(COUNT) \
426 { int n = (COUNT); \
427 DECL_LINENUMBERS_OFFSET (current_method) = JCF_TELL (jcf) - 2; \
428 JCF_SKIP (jcf, n * 4); }
430 #define HANDLE_EXCEPTIONS_ATTRIBUTE(COUNT) \
432 int n = COUNT; \
433 tree list = DECL_FUNCTION_THROWS (current_method); \
434 while (--n >= 0) \
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"
467 tree
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));
478 tree
479 get_constant (JCF *jcf, int index)
481 tree value;
482 int tag;
483 if (index <= 0 || index >= JPOOL_SIZE(jcf))
484 goto bad;
485 tag = JPOOL_TAG (jcf, index);
486 if ((tag & CONSTANT_ResolvedFlag) || tag == CONSTANT_Utf8)
487 return jcf->cpool.data[index].t;
488 switch (tag)
490 case CONSTANT_Integer:
492 jint num = JPOOL_INT(jcf, index);
493 value = build_int_cst (int_type_node, num);
494 break;
496 case CONSTANT_Long:
498 unsigned HOST_WIDE_INT num = JPOOL_UINT (jcf, index);
499 unsigned HOST_WIDE_INT lo;
500 HOST_WIDE_INT hi;
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);
507 break;
510 case CONSTANT_Float:
512 jint num = JPOOL_INT(jcf, index);
513 long buf = num;
514 REAL_VALUE_TYPE d;
516 real_from_target_fmt (&d, &buf, &ieee_single_format);
517 value = build_real (float_type_node, d);
518 break;
521 case CONSTANT_Double:
523 long buf[2], lo, hi;
524 REAL_VALUE_TYPE d;
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;
531 else
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);
536 break;
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;
545 int i;
547 /* Check for a malformed Utf8 string. */
548 utf8 = (const unsigned char *) utf8_ptr;
549 i = utf8_len;
550 while (i > 0)
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");
556 utf8 += char_len;
557 i -= char_len;
560 /* Allocate a new string value. */
561 value = build_string (utf8_len, utf8_ptr);
562 TREE_TYPE (value) = build_pointer_type (string_type_node);
564 break;
565 default:
566 goto bad;
568 JPOOL_TAG (jcf, index) = tag | CONSTANT_ResolvedFlag;
569 jcf->cpool.data[index].t = value;
570 return value;
571 bad:
572 internal_error ("bad value constant type %d, index %d",
573 JPOOL_TAG (jcf, index), index);
576 tree
577 get_name_constant (JCF *jcf, int index)
579 tree name = get_constant (jcf, index);
580 gcc_assert (TREE_CODE (name) == IDENTIFIER_NODE);
581 return name;
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. */
588 static void
589 handle_innerclass_attribute (int count, JCF *jcf)
591 int c = (count);
592 while (c--)
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. */
605 if (icii >= 0)
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;
624 static tree
625 give_name_to_class (JCF *jcf, int i)
627 gcc_assert (i > 0
628 && i < JPOOL_SIZE (jcf)
629 && JPOOL_TAG (jcf, i) == CONSTANT_Class);
632 tree package_name = NULL_TREE, tmp;
633 tree this_class;
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;
650 #else
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;
654 #endif
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;
661 return this_class;
665 /* Get the class of the CONSTANT_Class whose constant pool index is I. */
667 tree
668 get_class_constant (JCF *jcf, int i)
670 tree type;
671 gcc_assert (i > 0
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));
684 else
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;
692 else
693 type = jcf->cpool.data[i].t;
694 return type;
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)
705 JCF this_jcf, *jcf;
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);
717 else
718 jcf = NULL;
720 if (jcf == NULL)
722 const char* path_name;
723 this_jcf.zipd = NULL;
724 jcf = &this_jcf;
726 path_name = find_class (IDENTIFIER_POINTER (name),
727 IDENTIFIER_LENGTH (name),
728 &this_jcf, 1);
729 if (path_name == 0)
730 return 0;
731 else
732 free((char *) path_name);
735 current_jcf = jcf;
737 if (current_jcf->java_source)
739 const char *filename = current_jcf->filename;
740 char *real_path;
741 tree given_file, real_file;
742 FILE *finput;
743 int generate;
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);
752 free (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 ();
767 if (fclose (finput))
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);
771 #endif
773 JCF_FINISH (current_jcf);
774 java_pop_parser_context (generate);
775 java_parser_context_restore_global ();
777 else
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;
805 return 1;
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. */
811 void
812 load_class (tree class_or_name, int verbose)
814 tree name, saved;
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))
822 return;
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
828 we though */
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 */
832 else
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);
839 is_compiled_class
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)))
847 return;
849 saved = name;
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
856 || is_compiled_class
857 || TREE_CODE (class_or_name) == IDENTIFIER_NODE)
859 while (1)
861 char *separator;
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)))
868 break;
871 if (read_class (name))
872 break;
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), '.')))
879 int c = *separator;
880 *separator = '\0';
881 name = get_identifier (IDENTIFIER_POINTER (name));
882 *separator = c;
884 /* Otherwise, we failed, we bail. */
885 else
886 break;
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);
897 if (!class_loaded)
899 if (flag_verify_invocations || ! flag_indirect_dispatch
900 || flag_emit_class_files)
902 if (verbose)
903 error ("cannot find file for class %s", IDENTIFIER_POINTER (saved));
905 else if (verbose)
907 /* This is just a diagnostic during testing, not a real problem. */
908 if (!quiet_flag)
909 warning (0, "cannot find file for class %s",
910 IDENTIFIER_POINTER (saved));
912 /* Fake it. */
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. */
926 static void
927 jcf_parse (JCF* jcf)
929 int i, code;
931 if (jcf_parse_preamble (jcf) != 0)
932 fatal_error ("not a valid Java .class file");
933 code = jcf_parse_constant_pool (jcf);
934 if (code != 0)
935 fatal_error ("error while parsing constant pool");
936 code = verify_constant_pool (jcf);
937 if (code > 0)
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))),
952 jcf->filename);
954 CLASS_PARSED_P (current_class) = 1;
956 for (i = 1; i < JPOOL_SIZE(jcf); i++)
958 switch (JPOOL_TAG (jcf, i))
960 case CONSTANT_Class:
961 get_class_constant (jcf, i);
962 break;
966 code = jcf_parse_fields (jcf);
967 if (code != 0)
968 fatal_error ("error while parsing fields");
969 code = jcf_parse_methods (jcf);
970 if (code != 0)
971 fatal_error ("error while parsing methods");
972 code = jcf_parse_final_attributes (jcf);
973 if (code != 0)
974 fatal_error ("error while parsing final attributes");
975 #ifdef USE_MAPPED_LOCATION
976 linemap_add (&line_table, LC_LEAVE, false, NULL, 0);
977 #endif
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. */
989 #if 0
990 /* ECJ HACK: ignore this. */
991 if (!jcf->right_zip
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);
994 #endif
996 else
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. */
1002 static void
1003 load_inner_classes (tree cur_class)
1005 tree current;
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);
1017 static void
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);
1024 #else
1025 warn_loc.file = filename;
1026 warn_loc.line = 0;
1027 #endif
1028 warning (0, "%Hduplicate class will only be compiled once", &warn_loc);
1031 static void
1032 parse_class_file (void)
1034 tree method;
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))
1051 continue;
1053 if (METHOD_NATIVE (method))
1055 tree arg;
1056 int decl_max_locals;
1058 if (! flag_jni)
1059 continue;
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);
1073 end_java_method ();
1074 continue;
1077 if (DECL_CODE_OFFSET (method) == 0)
1079 current_function_decl = method;
1080 error ("missing Code attribute");
1081 continue;
1084 input_location = DECL_SOURCE_LOCATION (TYPE_NAME (current_class));
1085 if (DECL_LINENUMBERS_OFFSET (method))
1087 int i;
1088 int min_line = 0;
1089 unsigned char *ptr;
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)
1100 min_line = line;
1102 #ifdef USE_MAPPED_LOCATION
1103 if (min_line != 0)
1104 input_location = linemap_line_start (&line_table, min_line, 1);
1105 #else
1106 if (min_line != 0)
1107 input_line = min_line;
1108 #endif
1110 else
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)
1131 / 1000)
1132 + 1)
1133 * 1000);
1134 highest_label_pc_this_method = -1;
1137 /* Convert bytecode to trees. */
1138 expand_byte_code (jcf, method);
1140 end_java_method ();
1143 if (flag_emit_class_files)
1144 write_classfile (current_class);
1146 finish_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. */
1154 static void
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
1166 for iconv. */
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);
1171 #endif
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);
1178 #else
1179 input_filename = filename;
1180 input_line = 0;
1181 #endif
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. */
1197 static void
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 ();
1206 static void
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 */
1217 void
1218 add_predefined_file (tree name)
1220 predef_filenames = tree_cons (NULL_TREE, name, predef_filenames);
1224 predefined_filename_p (tree node)
1226 tree iter;
1228 for (iter = predef_filenames; iter != NULL_TREE; iter = TREE_CHAIN (iter))
1230 if (TREE_VALUE (iter) == node)
1231 return 1;
1233 return 0;
1236 /* Generate a function that does all static initialization for this
1237 translation unit. */
1239 static void
1240 java_emit_static_constructor (void)
1242 tree body = NULL;
1244 emit_register_classes (&body);
1245 write_resource_constructor (&body);
1247 if (body)
1248 cgraph_build_static_cdtor ('I', body, DEFAULT_INIT_PRIORITY);
1251 void
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;
1257 tree node;
1258 FILE *finput = NULL;
1259 int in_quotes = 0;
1261 if (flag_filelist_file)
1263 int avail = 2000;
1264 finput = fopen (main_input_filename, "r");
1265 if (finput == NULL)
1266 fatal_error ("can't open %s: %m", input_filename);
1267 list = XNEWVEC (char, avail);
1268 next = list;
1269 for (;;)
1271 int count;
1272 if (avail < 500)
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);
1282 if (count == 0)
1284 if (! feof (finput))
1285 fatal_error ("error closing %s: %m", input_filename);
1286 *next = '\0';
1287 break;
1289 avail -= count;
1290 next += count;
1292 fclose (finput);
1293 finput = NULL;
1294 file_list = list;
1296 else
1297 list = (char *) main_input_filename;
1299 while (list)
1301 for (next = list; ; )
1303 char ch = *next;
1304 if (flag_filelist_file && ! in_quotes
1305 && (ch == '\n' || ch == '\r' || ch == '\t' || ch == ' '
1306 || ch == '&') /* FIXME */)
1308 if (next == list)
1310 next++;
1311 list = next;
1312 continue;
1314 else
1316 *next++ = '\0';
1317 break;
1320 if (flag_filelist_file && ch == '"')
1322 in_quotes = ! in_quotes;
1323 *next++ = '\0';
1324 if (in_quotes)
1325 list = next;
1326 else
1327 break;
1329 if (ch == '\0')
1331 next = NULL;
1332 break;
1334 next++;
1337 /* Exclude .java files. */
1338 if (strlen (list) > 5 && ! strcmp (list + strlen (list) - 5, ".java"))
1340 /* Nothing. */
1342 else if (list[0])
1344 node = get_identifier (list);
1346 filename_count++;
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));
1352 else
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;
1360 list = next;
1363 if (file_list != NULL)
1364 free (file_list);
1366 if (filename_count == 0)
1367 warning (0, "no input file specified");
1369 if (resource_name)
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);
1379 goto finish;
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];
1387 char *real_path;
1388 uint32 magic = 0;
1389 tree name = DECL_NAME (node);
1390 tree real_file;
1391 const char *filename = IDENTIFIER_POINTER (name);
1393 /* Skip already parsed files */
1394 real_path = lrealpath (filename);
1395 real_file = get_identifier (real_path);
1396 free (real_path);
1397 if (HAS_BEEN_ALREADY_PARSED_P (real_file))
1398 continue;
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");
1405 if (finput == NULL)
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);
1411 #endif
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);
1433 continue;
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);
1447 #endif
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);
1455 #endif
1456 parse_zip_file_entries ();
1458 else
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);
1468 #endif
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)
1513 return;
1515 /* Expand all classes compiled from source. */
1516 java_finish_classes ();
1518 finish:
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 ();
1525 cgraph_optimize ();
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. */
1531 static char *
1532 compute_class_name (struct ZipDirectory *zdir)
1534 char *class_name_in_zip_dir = ZIPDIR_FILENAME (zdir);
1535 char *class_name;
1536 int i;
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] = '.';
1554 return class_name;
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. */
1559 static int
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],
1566 ".class", 6))
1567 return 1;
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))
1572 return 0;
1574 /* Drop directory entries. */
1575 if (zdir->filename_length > 0
1576 && class_name_in_zip_dir[zdir->filename_length - 1] == '/')
1577 return 0;
1579 return 2;
1582 /* Process all class entries found in the zip file. */
1583 static void
1584 parse_zip_file_entries (void)
1586 struct ZipDirectory *zdir;
1587 int i;
1589 for (i = 0, zdir = (ZipDirectory *)localToFile->central_directory;
1590 i < localToFile->count; i++, zdir = ZIPDIR_NEXT (zdir))
1592 tree class;
1594 switch (classify_zip_file (zdir))
1596 case 0:
1597 continue;
1599 case 1:
1601 char *class_name = compute_class_name (zdir);
1602 class = lookup_class (get_identifier (class_name));
1603 FREE (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
1608 real. */
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. */
1645 break;
1647 case 2:
1649 char *file_name, *class_name_in_zip_dir, *buffer;
1650 JCF *jcf;
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';
1655 jcf = XNEW (JCF);
1656 JCF_ZERO (jcf);
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;
1662 jcf->zipd = zdir;
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);
1677 JCF_FINISH (jcf);
1678 free (jcf);
1679 free (buffer);
1681 break;
1683 default:
1684 gcc_unreachable ();
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. */
1692 static void
1693 process_zip_dir (FILE *finput)
1695 int i;
1696 ZipDirectory *zdir;
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;
1702 tree class;
1703 JCF *jcf;
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)
1709 continue;
1711 class_name = compute_class_name (zdir);
1712 file_name = XNEWVEC (char, zdir->filename_length+1);
1713 jcf = ggc_alloc (sizeof (JCF));
1714 JCF_ZERO (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);
1725 continue;
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;
1736 jcf->zipd = zdir;
1738 TYPE_JCF (class) = jcf;
1742 /* Initialization. */
1744 void
1745 init_jcf_parse (void)
1747 init_src_parse ();
1750 #include "gt-java-jcf-parse.h"