diff options
author | tromey <tromey@138bc75d-0d04-0410-961f-82ee72b054a4> | 2004-11-25 03:47:08 +0000 |
---|---|---|
committer | tromey <tromey@138bc75d-0d04-0410-961f-82ee72b054a4> | 2004-11-25 03:47:08 +0000 |
commit | a4ccc41f9a5f050d518b8c30739a647f67756f9e (patch) | |
tree | 477abdf83653e20b0e74447d6ca47eb67b0511b8 /gcc/java/jcf-parse.c | |
parent | 2f3c6e08b9d664df3e416a186fd2938de188e706 (diff) | |
download | gcc-a4ccc41f9a5f050d518b8c30739a647f67756f9e.tar.gz |
* Merged gcj-abi-2-dev-branch to trunk.
(Actual changes too large to list in the commit message;
see ChangeLog.)
git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@91270 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'gcc/java/jcf-parse.c')
-rw-r--r-- | gcc/java/jcf-parse.c | 142 |
1 files changed, 111 insertions, 31 deletions
diff --git a/gcc/java/jcf-parse.c b/gcc/java/jcf-parse.c index f04b9f958d9..a7cd57a6d77 100644 --- a/gcc/java/jcf-parse.c +++ b/gcc/java/jcf-parse.c @@ -610,8 +610,14 @@ void load_class (tree class_or_name, int verbose) { tree name, saved; - int class_loaded; - tree class_decl; + int class_loaded = 0; + tree class_decl = NULL_TREE; + bool is_compiled_class = false; + + /* We've already failed, don't try again. */ + if (TREE_CODE (class_or_name) == RECORD_TYPE + && TYPE_DUMMY (class_or_name)) + return; /* class_or_name can be the name of the class we want to load */ if (TREE_CODE (class_or_name) == IDENTIFIER_NODE) @@ -624,41 +630,99 @@ load_class (tree class_or_name, int verbose) else name = DECL_NAME (TYPE_NAME (class_or_name)); + class_decl = IDENTIFIER_CLASS_VALUE (name); + if (class_decl != NULL_TREE) + { + tree type = TREE_TYPE (class_decl); + is_compiled_class + = ((TYPE_JCF (type) && JCF_SEEN_IN_ZIP (TYPE_JCF (type))) + || CLASS_FROM_CURRENTLY_COMPILED_P (type)); + } + /* If the class is from source code, then it must already be loaded. */ class_decl = IDENTIFIER_CLASS_VALUE (name); if (class_decl && CLASS_FROM_SOURCE_P (TREE_TYPE (class_decl))) return; saved = name; - while (1) + + /* If flag_verify_invocations is unset, we don't try to load a class + unless we're looking for Object (which is fixed by the ABI) or + it's a class that we're going to compile. */ + if (flag_verify_invocations + || class_or_name == object_type_node + || is_compiled_class + || TREE_CODE (class_or_name) == IDENTIFIER_NODE) { - char *separator; + while (1) + { + char *separator; - if ((class_loaded = read_class (name))) - break; + /* We've already loaded it. */ + if (IDENTIFIER_CLASS_VALUE (name) != NULL_TREE) + { + tree tmp_decl = IDENTIFIER_CLASS_VALUE (name); + if (CLASS_PARSED_P (TREE_TYPE (tmp_decl))) + break; + } + + if (read_class (name)) + break; - /* We failed loading name. Now consider that we might be looking - for a inner class. */ - if ((separator = strrchr (IDENTIFIER_POINTER (name), '$')) - || (separator = strrchr (IDENTIFIER_POINTER (name), '.'))) - { - int c = *separator; - *separator = '\0'; - name = get_identifier (IDENTIFIER_POINTER (name)); - *separator = c; - - /* Otherwise we might get infinite recursion, if say we have - String.class but not String$CaseInsensitiveComparator.class. */ - if (current_jcf && current_jcf->java_source == 0) + /* We failed loading name. Now consider that we might be looking + for a inner class. */ + if ((separator = strrchr (IDENTIFIER_POINTER (name), '$')) + || (separator = strrchr (IDENTIFIER_POINTER (name), '.'))) + { + int c = *separator; + *separator = '\0'; + name = get_identifier (IDENTIFIER_POINTER (name)); + *separator = c; + + /* Otherwise we might get infinite recursion, if say we + have String.class but not + String$CaseInsensitiveComparator.class. */ + if (current_jcf && current_jcf->java_source == 0) + break; + } + /* Otherwise, we failed, we bail. */ + else break; } - /* Otherwise, we failed, we bail. */ - else - break; - } - if (!class_loaded && verbose) - error ("cannot find file for class %s", IDENTIFIER_POINTER (saved)); + { + /* have we found the class we're looking for? */ + tree type_decl = IDENTIFIER_CLASS_VALUE (saved); + tree type = type_decl ? TREE_TYPE (type_decl) : NULL; + class_loaded = type && CLASS_PARSED_P (type); + } + } + + if (!class_loaded) + { + if (flag_verify_invocations || ! flag_indirect_dispatch + || flag_emit_class_files) + { + if (verbose) + error ("cannot find file for class %s", IDENTIFIER_POINTER (saved)); + } + else if (verbose) + { + /* This is just a diagnostic during testing, not a real problem. */ + if (!quiet_flag) + warning("cannot find file for class %s", + IDENTIFIER_POINTER (saved)); + + /* Fake it. */ + if (TREE_CODE (class_or_name) == RECORD_TYPE) + { + set_super_info (0, class_or_name, object_type_node, 0); + TYPE_DUMMY (class_or_name) = 1; + /* We won't be able to output any debug info for this class. */ + DECL_IGNORED_P (TYPE_NAME (class_or_name)) = 1; + } + } + } } /* Parse the .class file JCF. */ @@ -760,6 +824,7 @@ parse_class_file (void) java_layout_seen_class_methods (); input_location = DECL_SOURCE_LOCATION (TYPE_NAME (current_class)); + file_start_location = input_location; (*debug_hooks->start_source_file) (input_line, input_filename); /* Currently we always have to emit calls to _Jv_InitClass when @@ -775,7 +840,7 @@ parse_class_file (void) { JCF *jcf = current_jcf; - if (METHOD_ABSTRACT (method)) + if (METHOD_ABSTRACT (method) || METHOD_DUMMY (method)) continue; if (METHOD_NATIVE (method)) @@ -911,6 +976,7 @@ static void parse_source_file_2 (void) { int save_error_count = java_error_count; + flag_verify_invocations = true; java_complete_class (); /* Parse unsatisfied class decl. */ java_parse_abort_on_error (); } @@ -1196,7 +1262,12 @@ java_parse_file (int set_yydebug ATTRIBUTE_UNUSED) input_location = DECL_SOURCE_LOCATION (node); if (CLASS_FILE_P (node)) { + /* FIXME: These two flags really should be independent. We + should be able to compile fully binary compatible, but + with flag_verify_invocations on. */ + flag_verify_invocations = ! flag_indirect_dispatch; output_class = current_class = TREE_TYPE (node); + current_jcf = TYPE_JCF (current_class); layout_class (current_class); load_inner_classes (current_class); @@ -1232,13 +1303,15 @@ compute_class_name (struct ZipDirectory *zdir) char *class_name_in_zip_dir = ZIPDIR_FILENAME (zdir); char *class_name; int i; - int filename_length; + int filename_length = zdir->filename_length; - while (strncmp (class_name_in_zip_dir, "./", 2) == 0) - class_name_in_zip_dir += 2; + while (filename_length > 2 && strncmp (class_name_in_zip_dir, "./", 2) == 0) + { + class_name_in_zip_dir += 2; + filename_length -= 2; + } - filename_length = (strlen (class_name_in_zip_dir) - - strlen (".class")); + filename_length -= strlen (".class"); class_name = ALLOC (filename_length + 1); memcpy (class_name, class_name_in_zip_dir, filename_length); class_name [filename_length] = '\0'; @@ -1300,6 +1373,13 @@ parse_zip_file_entries (void) current_jcf = TYPE_JCF (class); output_class = current_class = class; + if (TYPE_DUMMY (class)) + { + /* This is a dummy class, and now we're compiling it + for real. */ + abort (); + } + /* This is for a corner case where we have a superclass but no superclass fields. |