X-Git-Url: http://git.sourceforge.jp/view?a=blobdiff_plain;f=gcc%2Fjava%2Fclass.c;h=edd16f0ad618b7569b6d3b764022b6c3e55e67e6;hb=cfaf579ddfaec5cb9bc5d220eadd212786138f3d;hp=804c239fcfabc61da6a5dd21227cf2dc644e910e;hpb=0ab206a123dabe894de40f135233f4d657794b85;p=pf3gnuchains%2Fgcc-fork.git diff --git a/gcc/java/class.c b/gcc/java/class.c index 804c239fcfa..edd16f0ad61 100644 --- a/gcc/java/class.c +++ b/gcc/java/class.c @@ -1,12 +1,12 @@ /* Functions related to building classes and their related objects. Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, - 2005, 2006, 2007 Free Software Foundation, Inc. + 2005, 2006, 2007, 2008 Free Software Foundation, Inc. This file is part of GCC. GCC is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by -the Free Software Foundation; either version 2, or (at your option) +the Free Software Foundation; either version 3, or (at your option) any later version. GCC is distributed in the hope that it will be useful, @@ -15,9 +15,8 @@ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License -along with GCC; see the file COPYING. If not, write to -the Free Software Foundation, 51 Franklin Street, Fifth Floor, -Boston, MA 02110-1301, USA. +along with GCC; see the file COPYING3. If not see +. Java and all Java-based marks are trademarks or registered trademarks of Sun Microsystems, Inc. in the United States and other countries. @@ -39,6 +38,7 @@ The Free Software Foundation is independent of Sun Microsystems, Inc. */ #include "output.h" #include "parse.h" #include "function.h" +#include "tm_p.h" #include "ggc.h" #include "stdio.h" #include "target.h" @@ -280,7 +280,7 @@ ident_subst (const char* old_name, int prefix_len = strlen (prefix); int suffix_len = strlen (suffix); int i = prefix_len + old_length + suffix_len + 1; - char *buffer = alloca (i); + char *buffer = (char *) alloca (i); strcpy (buffer, prefix); for (i = 0; i < old_length; i++) @@ -315,10 +315,63 @@ identifier_subst (const tree old_id, tree mangled_classname (const char *prefix, tree type) { + tree result; tree ident = TYPE_NAME (type); if (TREE_CODE (ident) != IDENTIFIER_NODE) ident = DECL_NAME (ident); - return identifier_subst (ident, prefix, '.', '_', ""); + result = identifier_subst (ident, prefix, '.', '_', ""); + + /* Replace any characters that aren't in the set [0-9a-zA-Z_$] with + "_0xXX". Class names containing such chracters are uncommon, but + they do sometimes occur in class files. Without this check, + these names cause assembly errors. + + There is a possibility that a real class name could conflict with + the identifier we generate, but it is unlikely and will + immediately be detected as an assembler error. At some point we + should do something more elaborate (perhaps using the full + unicode mangling scheme) in order to prevent such a conflict. */ + { + int i; + const int len = IDENTIFIER_LENGTH (result); + const char *p = IDENTIFIER_POINTER (result); + int illegal_chars = 0; + + /* Make two passes over the identifier. The first pass is merely + to count illegal characters; we need to do this in order to + allocate a buffer. */ + for (i = 0; i < len; i++) + { + char c = p[i]; + illegal_chars += (! ISALNUM (c) && c != '_' && c != '$'); + } + + /* And the second pass, which is rarely executed, does the + rewriting. */ + if (illegal_chars != 0) + { + char *buffer = (char *) alloca (illegal_chars * 4 + len + 1); + int j; + + for (i = 0, j = 0; i < len; i++) + { + char c = p[i]; + if (! ISALNUM (c) && c != '_' && c != '$') + { + buffer[j++] = '_'; + sprintf (&buffer[j], "0x%02x", c); + j += 4; + } + else + buffer[j++] = c; + } + + buffer[j] = 0; + result = get_identifier (buffer); + } + } + + return result; } tree @@ -360,11 +413,12 @@ unmangle_classname (const char *name, int name_length) #define GEN_TABLE(TABLE, NAME, TABLE_TYPE, TYPE) \ do \ { \ - const char *typename = IDENTIFIER_POINTER (mangled_classname ("", TYPE)); \ - char *buf = alloca (strlen (typename) + strlen (#NAME "_syms_") + 1); \ + const char *type_name = IDENTIFIER_POINTER (mangled_classname ("", TYPE)); \ + char *buf = (char *) alloca (strlen (type_name) \ + + strlen (#NAME "_syms_") + 1); \ tree decl; \ \ - sprintf (buf, #NAME "_%s", typename); \ + sprintf (buf, #NAME "_%s", type_name); \ TYPE_## TABLE ##_DECL (type) = decl = \ build_decl (VAR_DECL, get_identifier (buf), TABLE_TYPE); \ DECL_EXTERNAL (decl) = 1; \ @@ -376,7 +430,7 @@ do \ pushdecl (decl); \ MAYBE_CREATE_VAR_LANG_DECL_SPECIFIC (decl); \ DECL_OWNER (decl) = TYPE; \ - sprintf (buf, #NAME "_syms_%s", typename); \ + sprintf (buf, #NAME "_syms_%s", type_name); \ TYPE_## TABLE ##_SYMS_DECL (TYPE) = \ build_decl (VAR_DECL, get_identifier (buf), symbols_array_type); \ TREE_STATIC (TYPE_## TABLE ##_SYMS_DECL (TYPE)) = 1; \ @@ -390,13 +444,14 @@ while (0) void gen_indirect_dispatch_tables (tree type) { - const char *typename = IDENTIFIER_POINTER (DECL_NAME (TYPE_NAME (type))); + const char *type_name = IDENTIFIER_POINTER (mangled_classname ("", type)); { tree field = NULL; - char *buf = alloca (strlen (typename) + strlen ("_catch_classes_") + 1); + char *buf = (char *) alloca (strlen (type_name) + + strlen ("_catch_classes_") + 1); tree catch_class_type = make_node (RECORD_TYPE); - sprintf (buf, "_catch_classes_%s", typename); + sprintf (buf, "_catch_classes_%s", type_name); PUSH_FIELD (catch_class_type, field, "address", utf8const_ptr_type); PUSH_FIELD (catch_class_type, field, "classname", ptr_type_node); FINISH_RECORD (catch_class_type); @@ -427,11 +482,6 @@ push_class (tree class_type, tree class_name) { tree decl, signature; location_t saved_loc = input_location; -#ifndef USE_MAPPED_LOCATION - tree source_name = identifier_subst (class_name, "", '.', '/', ".java"); - input_filename = IDENTIFIER_POINTER (source_name); - input_line = 0; -#endif CLASS_P (class_type) = 1; decl = build_decl (TYPE_DECL, class_name, class_type); TYPE_DECL_SUPPRESS_DEBUG (decl) = 1; @@ -691,6 +741,15 @@ build_java_method_type (tree fntype, tree this_class, int access_flags) return fntype; } +void +java_hide_decl (tree decl ATTRIBUTE_UNUSED) +{ +#ifdef HAVE_GAS_HIDDEN + DECL_VISIBILITY (decl) = VISIBILITY_HIDDEN; + DECL_VISIBILITY_SPECIFIED (decl) = 1; +#endif +} + tree add_method_1 (tree this_class, int access_flags, tree name, tree function_type) { @@ -703,7 +762,7 @@ add_method_1 (tree this_class, int access_flags, tree name, tree function_type) DECL_CONTEXT (fndecl) = this_class; DECL_LANG_SPECIFIC (fndecl) - = ggc_alloc_cleared (sizeof (struct lang_decl)); + = GGC_CNEW (struct lang_decl); DECL_LANG_SPECIFIC (fndecl)->desc = LANG_DECL_FUNC; /* Initialize the static initializer test table. */ @@ -719,6 +778,14 @@ add_method_1 (tree this_class, int access_flags, tree name, tree function_type) TREE_CHAIN (fndecl) = TYPE_METHODS (this_class); TYPE_METHODS (this_class) = fndecl; + /* If pointers to member functions use the least significant bit to + indicate whether a function is virtual, ensure a pointer + to this function will have that bit clear. */ + if (TARGET_PTRMEMFUNC_VBIT_LOCATION == ptrmemfunc_vbit_in_pfn + && !(access_flags & ACC_STATIC) + && DECL_ALIGN (fndecl) < 2 * BITS_PER_UNIT) + DECL_ALIGN (fndecl) = 2 * BITS_PER_UNIT; + /* Notice that this is a finalizer and update the class type accordingly. This is used to optimize instance allocation. */ if (name == finalize_identifier_node @@ -729,7 +796,7 @@ add_method_1 (tree this_class, int access_flags, tree name, tree function_type) if (access_flags & ACC_PUBLIC) METHOD_PUBLIC (fndecl) = 1; if (access_flags & ACC_PROTECTED) METHOD_PROTECTED (fndecl) = 1; if (access_flags & ACC_PRIVATE) - METHOD_PRIVATE (fndecl) = DECL_INLINE (fndecl) = 1; + METHOD_PRIVATE (fndecl) = 1; if (access_flags & ACC_NATIVE) { METHOD_NATIVE (fndecl) = 1; @@ -740,9 +807,9 @@ add_method_1 (tree this_class, int access_flags, tree name, tree function_type) file. */ DECL_EXTERNAL (fndecl) = CLASS_FROM_CURRENTLY_COMPILED_P (this_class) == 0; if (access_flags & ACC_STATIC) - METHOD_STATIC (fndecl) = DECL_INLINE (fndecl) = 1; + METHOD_STATIC (fndecl) = 1; if (access_flags & ACC_FINAL) - METHOD_FINAL (fndecl) = DECL_INLINE (fndecl) = 1; + METHOD_FINAL (fndecl) = 1; if (access_flags & ACC_SYNCHRONIZED) METHOD_SYNCHRONIZED (fndecl) = 1; if (access_flags & ACC_ABSTRACT) METHOD_ABSTRACT (fndecl) = 1; if (access_flags & ACC_STRICT) METHOD_STRICTFP (fndecl) = 1; @@ -773,14 +840,14 @@ add_method (tree this_class, int access_flags, tree name, tree method_sig) } tree -add_field (tree class, tree name, tree field_type, int flags) +add_field (tree klass, tree name, tree field_type, int flags) { int is_static = (flags & ACC_STATIC) != 0; tree field; field = build_decl (is_static ? VAR_DECL : FIELD_DECL, name, field_type); - TREE_CHAIN (field) = TYPE_FIELDS (class); - TYPE_FIELDS (class) = field; - DECL_CONTEXT (field) = class; + TREE_CHAIN (field) = TYPE_FIELDS (klass); + TYPE_FIELDS (klass) = field; + DECL_CONTEXT (field) = klass; MAYBE_CREATE_VAR_LANG_DECL_SPECIFIC (field); if (flags & ACC_PUBLIC) FIELD_PUBLIC (field) = 1; @@ -801,9 +868,13 @@ add_field (tree class, tree name, tree field_type, int flags) /* Always make field externally visible. This is required so that native methods can always access the field. */ TREE_PUBLIC (field) = 1; + /* Hide everything that shouldn't be visible outside a DSO. */ + if (flag_indirect_classes + || (FIELD_PRIVATE (field))) + java_hide_decl (field); /* Considered external unless we are compiling it into this object file. */ - DECL_EXTERNAL (field) = (is_compiled_class (class) != 2); + DECL_EXTERNAL (field) = (is_compiled_class (klass) != 2); } return field; @@ -832,8 +903,6 @@ set_constant_value (tree field, tree constant) && TREE_TYPE (field) == string_ptr_type_node)) error ("ConstantValue attribute of field '%s' has wrong type", IDENTIFIER_POINTER (DECL_NAME (field))); - if (FIELD_FINAL (field)) - DECL_FIELD_FINAL_IUD (field) = 1; } } @@ -862,8 +931,8 @@ static GTY(()) tree utf8_decl_list = NULL_TREE; tree build_utf8_ref (tree name) { - const char * name_ptr = IDENTIFIER_POINTER(name); - int name_len = IDENTIFIER_LENGTH(name); + const char * name_ptr = IDENTIFIER_POINTER (name); + int name_len = IDENTIFIER_LENGTH (name), name_pad; char buf[60]; tree ctype, field = NULL_TREE, str_type, cinit, string; static int utf8_count = 0; @@ -874,8 +943,11 @@ build_utf8_ref (tree name) return ref; ctype = make_node (RECORD_TYPE); + /* '\0' byte plus padding to utf8const_type's alignment. */ + name_pad = TYPE_ALIGN_UNIT (utf8const_type) + - (name_len & (TYPE_ALIGN_UNIT (utf8const_type) - 1)); str_type = build_prim_array_type (unsigned_byte_type_node, - name_len + 1); /* Allow for final '\0'. */ + name_len + name_pad); PUSH_FIELD (ctype, field, "hash", unsigned_short_type_node); PUSH_FIELD (ctype, field, "length", unsigned_short_type_node); PUSH_FIELD (ctype, field, "data", str_type); @@ -889,7 +961,6 @@ build_utf8_ref (tree name) PUSH_FIELD_VALUE (cinit, "data", string); FINISH_RECORD_CONSTRUCTOR (cinit); TREE_CONSTANT (cinit) = 1; - TREE_INVARIANT (cinit) = 1; /* Generate a unique-enough identifier. */ sprintf(buf, "_Utf%d", ++utf8_count); @@ -906,8 +977,7 @@ build_utf8_ref (tree name) { int decl_size; /* Ensure decl_size is a multiple of utf8const_type's alignment. */ - decl_size = (name_len + 5 + TYPE_ALIGN_UNIT (utf8const_type) - 1) - & ~(TYPE_ALIGN_UNIT (utf8const_type) - 1); + decl_size = name_len + 4 + name_pad; if (flag_merge_constants && decl_size < 256) { char buf[32]; @@ -921,6 +991,8 @@ build_utf8_ref (tree name) TREE_CHAIN (decl) = utf8_decl_list; layout_decl (decl, 0); + DECL_SIZE (decl) = TYPE_SIZE (ctype); + DECL_SIZE_UNIT (decl) = TYPE_SIZE_UNIT (ctype); pushdecl (decl); rest_of_decl_compilation (decl, global_bindings_p (), 0); varpool_mark_needed_node (varpool_node (decl)); @@ -958,7 +1030,11 @@ build_static_class_ref (tree type) decl = build_decl (VAR_DECL, decl_name, class_type_node); TREE_STATIC (decl) = 1; if (! flag_indirect_classes) - TREE_PUBLIC (decl) = 1; + { + TREE_PUBLIC (decl) = 1; + if (CLASS_PRIVATE (TYPE_NAME (type))) + java_hide_decl (decl); + } DECL_IGNORED_P (decl) = 1; DECL_ARTIFICIAL (decl) = 1; if (is_compiled_class (type) == 1) @@ -993,10 +1069,10 @@ build_classdollar_field (tree type) /* const */ 1, 0)), /* const */ 1, 0))); TREE_STATIC (decl) = 1; - TREE_INVARIANT (decl) = 1; TREE_CONSTANT (decl) = 1; TREE_READONLY (decl) = 1; TREE_PUBLIC (decl) = 1; + java_hide_decl (decl); DECL_IGNORED_P (decl) = 1; DECL_ARTIFICIAL (decl) = 1; MAYBE_CREATE_VAR_LANG_DECL_SPECIFIC (decl); @@ -1008,7 +1084,7 @@ build_classdollar_field (tree type) return decl; } -/* Create a local variable that holds the the current class$. */ +/* Create a local variable that holds the current class$. */ void cache_this_class_ref (tree fndecl) @@ -1039,10 +1115,8 @@ cache_this_class_ref (tree fndecl) && ! DECL_CLINIT_P (fndecl) && ! CLASS_INTERFACE (TYPE_NAME (DECL_CONTEXT (fndecl)))) { - tree init = build3 (CALL_EXPR, void_type_node, - build_address_of (soft_initclass_node), - build_tree_list (NULL_TREE, this_classdollar), - NULL_TREE); + tree init = build_call_expr (soft_initclass_node, 1, + this_classdollar); java_add_stmt (init); } } @@ -1075,7 +1149,13 @@ build_class_ref (tree type) return build_indirect_class_ref (type); if (type == output_class && flag_indirect_classes) - return this_classdollar; + { + /* This can be NULL if we see a JNI stub before we see any + other method. */ + if (! this_classdollar) + this_classdollar = build_classdollar_field (output_class); + return this_classdollar; + } if (TREE_CODE (type) == RECORD_TYPE) return build_static_class_ref (type); @@ -1119,7 +1199,7 @@ build_fieldref_cache_entry (int index, tree fdecl ATTRIBUTE_UNUSED) { tree decl, decl_name; const char *name = IDENTIFIER_POINTER (mangled_classname ("_cpool_", output_class)); - char *buf = alloca (strlen (name) + 20); + char *buf = (char *) alloca (strlen (name) + 20); sprintf (buf, "%s_%d_ref", name, index); decl_name = get_identifier (buf); decl = IDENTIFIER_GLOBAL_VALUE (decl_name); @@ -1141,13 +1221,12 @@ build_static_field_ref (tree fdecl) { tree fclass = DECL_CONTEXT (fdecl); int is_compiled = is_compiled_class (fclass); - int from_class = ! CLASS_FROM_SOURCE_P (current_class); /* Allow static final fields to fold to a constant. When using -findirect-dispatch, we simply never do this folding if compiling from .class; in the .class file constants will be referred to via the constant pool. */ - if ((!flag_indirect_dispatch || !from_class) + if (!flag_indirect_dispatch && (is_compiled || (FIELD_FINAL (fdecl) && DECL_INITIAL (fdecl) != NULL_TREE && (JSTRING_TYPE_P (TREE_TYPE (fdecl)) @@ -1177,20 +1256,16 @@ build_static_field_ref (tree fdecl) int cpool_index = alloc_constant_fieldref (output_class, fdecl); tree cache_entry = build_fieldref_cache_entry (cpool_index, fdecl); - tree test - = build3 (CALL_EXPR, boolean_type_node, - build_address_of (built_in_decls[BUILT_IN_EXPECT]), - tree_cons (NULL_TREE, build2 (EQ_EXPR, boolean_type_node, - cache_entry, null_pointer_node), - build_tree_list (NULL_TREE, boolean_false_node)), - NULL_TREE); + tree test + = build_call_expr (built_in_decls[BUILT_IN_EXPECT], 2, + build2 (EQ_EXPR, boolean_type_node, + cache_entry, null_pointer_node), + boolean_false_node); tree cpool_index_cst = build_int_cst (NULL_TREE, cpool_index); tree init - = build3 (CALL_EXPR, ptr_type_node, - build_address_of (soft_resolvepoolentry_node), - tree_cons (NULL_TREE, build_class_ref (output_class), - build_tree_list (NULL_TREE, cpool_index_cst)), - NULL_TREE); + = build_call_expr (soft_resolvepoolentry_node, 2, + build_class_ref (output_class), + cpool_index_cst); init = build2 (MODIFY_EXPR, ptr_type_node, cache_entry, init); init = build3 (COND_EXPR, ptr_type_node, test, init, cache_entry); init = fold_convert (build_pointer_type (TREE_TYPE (fdecl)), init); @@ -1299,8 +1374,8 @@ make_local_function_alias (tree method) tree alias; const char *method_name = IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (method)); - char *name = alloca (strlen (method_name) + 2); - char *buf = alloca (strlen (method_name) + 128); + char *name = (char *) alloca (strlen (method_name) + 2); + char *buf = (char *) alloca (strlen (method_name) + 128); /* Only create aliases for local functions. */ if (DECL_EXTERNAL (method)) @@ -1319,7 +1394,6 @@ make_local_function_alias (tree method) TREE_PUBLIC (alias) = 0; DECL_EXTERNAL (alias) = 0; DECL_ARTIFICIAL (alias) = 1; - DECL_INLINE (alias) = 0; DECL_INITIAL (alias) = error_mark_node; TREE_ADDRESSABLE (alias) = 1; TREE_USED (alias) = 1; @@ -1540,7 +1614,6 @@ get_dispatch_table (tree type, tree this_class_addr) tree fdesc = build2 (FDESC_EXPR, nativecode_ptr_type_node, method, build_int_cst (NULL_TREE, j)); TREE_CONSTANT (fdesc) = 1; - TREE_INVARIANT (fdesc) = 1; list = tree_cons (NULL_TREE, fdesc, list); } else @@ -1660,8 +1733,7 @@ make_class_data (tree type) tree id_class = get_identifier("java.lang.Class"); /** Offset from start of virtual function table declaration to where objects actually point at, following new g++ ABI. */ - tree dtable_start_offset = build_int_cst (NULL_TREE, - 2 * POINTER_SIZE / BITS_PER_UNIT); + tree dtable_start_offset = size_int (2 * POINTER_SIZE / BITS_PER_UNIT); VEC(int, heap) *field_indexes; tree first_real_field; @@ -1690,6 +1762,10 @@ make_class_data (tree type) TREE_PUBLIC (dtable_decl) = 1; DECL_INITIAL (dtable_decl) = dtable; + /* The only dispatch table exported from a DSO is the dispatch + table for java.lang.Class. */ + if (DECL_NAME (type_decl) != id_class) + java_hide_decl (dtable_decl); if (! flag_indirect_classes) rest_of_decl_compilation (dtable_decl, 1, 0); /* Maybe we're compiling Class as the first class. If so, set @@ -1745,6 +1821,8 @@ make_class_data (tree type) field_index = static_count++; else if (uses_jv_markobj || !flag_reduced_reflection) field_index = instance_count++; + else + continue; VEC_quick_push (int, field_indexes, field_index); } } @@ -1832,8 +1910,7 @@ make_class_data (tree type) || DECL_CLINIT_P (method) || DECL_NAME (type_decl) == id_class || DECL_NAME (method) == id_main - || (METHOD_PUBLIC (method) && !METHOD_STATIC (method)) - || TYPE_DOT_CLASS (type) == method) + || (METHOD_PUBLIC (method) && !METHOD_STATIC (method))) { init = make_method_value (method); method_count++; @@ -1944,7 +2021,7 @@ make_class_data (tree type) PUSH_FIELD_VALUE (temp, "vtable", (flag_indirect_classes ? null_pointer_node - : build2 (PLUS_EXPR, dtable_ptr_type, + : build2 (POINTER_PLUS_EXPR, dtable_ptr_type, build1 (ADDR_EXPR, dtable_ptr_type, class_dtable_decl), dtable_start_offset))); @@ -1992,7 +2069,7 @@ make_class_data (tree type) else PUSH_FIELD_VALUE (cons, "vtable", dtable_decl == NULL_TREE ? null_pointer_node - : build2 (PLUS_EXPR, dtable_ptr_type, + : build2 (POINTER_PLUS_EXPR, dtable_ptr_type, build1 (ADDR_EXPR, dtable_ptr_type, dtable_decl), dtable_start_offset)); @@ -2010,7 +2087,6 @@ make_class_data (tree type) build1 (ADDR_EXPR, symbols_array_ptr_type, TYPE_OTABLE_SYMS_DECL (type))); TREE_CONSTANT (TYPE_OTABLE_DECL (type)) = 1; - TREE_INVARIANT (TYPE_OTABLE_DECL (type)) = 1; } if (TYPE_ATABLE_METHODS(type) == NULL_TREE) { @@ -2026,7 +2102,6 @@ make_class_data (tree type) build1 (ADDR_EXPR, symbols_array_ptr_type, TYPE_ATABLE_SYMS_DECL (type))); TREE_CONSTANT (TYPE_ATABLE_DECL (type)) = 1; - TREE_INVARIANT (TYPE_ATABLE_DECL (type)) = 1; } if (TYPE_ITABLE_METHODS(type) == NULL_TREE) { @@ -2042,7 +2117,6 @@ make_class_data (tree type) build1 (ADDR_EXPR, symbols_array_ptr_type, TYPE_ITABLE_SYMS_DECL (type))); TREE_CONSTANT (TYPE_ITABLE_DECL (type)) = 1; - TREE_INVARIANT (TYPE_ITABLE_DECL (type)) = 1; } PUSH_FIELD_VALUE (cons, "catch_classes", @@ -2152,17 +2226,6 @@ make_class_data (tree type) void finish_class (void) { - if (TYPE_VERIFY_METHOD (output_class)) - { - tree verify_method = TYPE_VERIFY_METHOD (output_class); - DECL_SAVED_TREE (verify_method) - = add_stmt_to_compound (DECL_SAVED_TREE (verify_method), void_type_node, - build1 (RETURN_EXPR, void_type_node, NULL)); - java_genericize (verify_method); - cgraph_finalize_function (verify_method, false); - TYPE_ASSERTIONS (current_class) = NULL; - } - java_expand_catch_classes (current_class); current_function_decl = NULL_TREE; @@ -2172,45 +2235,43 @@ finish_class (void) rest_of_decl_compilation (TYPE_NAME (current_class), 1, 0); } -/* Return 2 if CLASS is compiled by this compilation job; - return 1 if CLASS can otherwise be assumed to be compiled; - return 0 if we cannot assume that CLASS is compiled. +/* Return 2 if KLASS is compiled by this compilation job; + return 1 if KLASS can otherwise be assumed to be compiled; + return 0 if we cannot assume that KLASS is compiled. Returns 1 for primitive and 0 for array types. */ int -is_compiled_class (tree class) +is_compiled_class (tree klass) { int seen_in_zip; - if (TREE_CODE (class) == POINTER_TYPE) - class = TREE_TYPE (class); - if (TREE_CODE (class) != RECORD_TYPE) /* Primitive types are static. */ + if (TREE_CODE (klass) == POINTER_TYPE) + klass = TREE_TYPE (klass); + if (TREE_CODE (klass) != RECORD_TYPE) /* Primitive types are static. */ return 1; - if (TYPE_ARRAY_P (class)) + if (TYPE_ARRAY_P (klass)) return 0; - seen_in_zip = (TYPE_JCF (class) && JCF_SEEN_IN_ZIP (TYPE_JCF (class))); - if (CLASS_FROM_CURRENTLY_COMPILED_P (class)) + seen_in_zip = (TYPE_JCF (klass) && JCF_SEEN_IN_ZIP (TYPE_JCF (klass))); + if (CLASS_FROM_CURRENTLY_COMPILED_P (klass)) { /* The class was seen in the current ZIP file and will be available as a compiled class in the future but may not have been loaded already. Load it if necessary. This prevent build_class_ref () from crashing. */ - if (seen_in_zip && !CLASS_LOADED_P (class) && (class != current_class)) - load_class (class, 1); + if (seen_in_zip && !CLASS_LOADED_P (klass) && (klass != current_class)) + load_class (klass, 1); /* We return 2 for class seen in ZIP and class from files belonging to the same compilation unit */ return 2; } - if (assume_compiled (IDENTIFIER_POINTER (DECL_NAME (TYPE_NAME (class))))) + if (assume_compiled (IDENTIFIER_POINTER (DECL_NAME (TYPE_NAME (klass))))) { - if (!CLASS_LOADED_P (class)) + if (!CLASS_LOADED_P (klass)) { - if (CLASS_FROM_SOURCE_P (class)) - safe_layout_class (class); - else if (class != current_class) - load_class (class, 1); + if (klass != current_class) + load_class (klass, 1); } return 1; } @@ -2306,8 +2367,6 @@ maybe_layout_super_class (tree super_class, tree this_class ATTRIBUTE_UNUSED) return NULL_TREE; else if (TREE_CODE (super_class) == RECORD_TYPE) { - if (!CLASS_LOADED_P (super_class) && CLASS_FROM_SOURCE_P (super_class)) - safe_layout_class (super_class); if (!CLASS_LOADED_P (super_class)) load_class (super_class, 1); } @@ -2331,12 +2390,12 @@ maybe_layout_super_class (tree super_class, tree this_class ATTRIBUTE_UNUSED) about the class processed currently. */ void -safe_layout_class (tree class) +safe_layout_class (tree klass) { tree save_current_class = current_class; location_t save_location = input_location; - layout_class (class); + layout_class (klass); current_class = save_current_class; input_location = save_location; @@ -2345,6 +2404,7 @@ safe_layout_class (tree class) void layout_class (tree this_class) { + int i; tree super_class = CLASSTYPE_SUPER (this_class); class_list = tree_cons (this_class, NULL_TREE, class_list); @@ -2369,7 +2429,7 @@ layout_class (tree this_class) obstack_grow (&temporary_obstack, buffer, strlen (buffer)); } obstack_1grow (&temporary_obstack, '\0'); - report = obstack_finish (&temporary_obstack); + report = XOBFINISH (&temporary_obstack, char *); cyclic_inheritance_report = ggc_strdup (report); obstack_free (&temporary_obstack, report); TYPE_SIZE (this_class) = error_mark_node; @@ -2395,28 +2455,22 @@ layout_class (tree this_class) layout_type (this_class); - /* Also recursively load/layout any superinterfaces, but only if - class was loaded from bytecode. The source parser will take care - of this itself. */ - if (!CLASS_FROM_SOURCE_P (this_class)) + /* Also recursively load/layout any superinterfaces. */ + if (TYPE_BINFO (this_class)) { - int i; - if (TYPE_BINFO (this_class)) + for (i = BINFO_N_BASE_BINFOS (TYPE_BINFO (this_class)) - 1; i > 0; i--) { - for (i = BINFO_N_BASE_BINFOS (TYPE_BINFO (this_class)) - 1; i > 0; i--) + tree binfo = BINFO_BASE_BINFO (TYPE_BINFO (this_class), i); + tree super_interface = BINFO_TYPE (binfo); + tree maybe_super_interface + = maybe_layout_super_class (super_interface, NULL_TREE); + if (maybe_super_interface == NULL + || TREE_CODE (TYPE_SIZE (maybe_super_interface)) == ERROR_MARK) { - tree binfo = BINFO_BASE_BINFO (TYPE_BINFO (this_class), i); - tree super_interface = BINFO_TYPE (binfo); - tree maybe_super_interface - = maybe_layout_super_class (super_interface, NULL_TREE); - if (maybe_super_interface == NULL - || TREE_CODE (TYPE_SIZE (maybe_super_interface)) == ERROR_MARK) - { - TYPE_SIZE (this_class) = error_mark_node; - CLASS_BEING_LAIDOUT (this_class) = 0; - class_list = TREE_CHAIN (class_list); - return; - } + TYPE_SIZE (this_class) = error_mark_node; + CLASS_BEING_LAIDOUT (this_class) = 0; + class_list = TREE_CHAIN (class_list); + return; } } } @@ -2559,6 +2613,12 @@ layout_class_method (tree this_class, tree super_class, TREE_PUBLIC (method_decl) = 1; + if (flag_indirect_classes + || (METHOD_PRIVATE (method_decl) && METHOD_STATIC (method_decl) + && ! METHOD_NATIVE (method_decl) + && ! special_method_p (method_decl))) + java_hide_decl (method_decl); + /* Considered external unless it is being compiled into this object file, or it was already flagged as external. */ if (!DECL_EXTERNAL (method_decl)) @@ -2605,7 +2665,6 @@ layout_class_method (tree this_class, tree super_class, set_method_index (method_decl, method_index); if (method_index == NULL_TREE && ! flag_indirect_dispatch - && !CLASS_FROM_SOURCE_P (this_class) && ! DECL_ARTIFICIAL (super_method)) error ("non-static method %q+D overrides static method", method_decl); @@ -2693,8 +2752,7 @@ emit_indirect_register_classes (tree *list_p) TREE_PUBLIC (t) = 1; DECL_EXTERNAL (t) = 1; register_class_fn = t; - t = tree_cons (NULL, reg_class_list, NULL); - t = build_function_call_expr (register_class_fn, t); + t = build_call_expr (register_class_fn, 1, reg_class_list); append_to_statement_list (t, list_p); } @@ -2759,8 +2817,7 @@ emit_register_classes (tree *list_p) for (i = 0; VEC_iterate (tree, registered_class, i, klass); ++i) { t = build_fold_addr_expr (klass); - t = tree_cons (NULL, t, NULL); - t = build_function_call_expr (register_class_fn, t); + t = build_call_expr (register_class_fn, 1, t); append_to_statement_list (t, list_p); } } @@ -2790,7 +2847,8 @@ build_symbol_entry (tree decl, tree special) system that this is a "special" symbol, i.e. one that should bypass access controls. */ if (special != NULL_TREE) - signature = build2 (PLUS_EXPR, TREE_TYPE (signature), signature, special); + signature = build2 (POINTER_PLUS_EXPR, TREE_TYPE (signature), signature, + fold_convert (sizetype, special)); START_RECORD_CONSTRUCTOR (sym, symbol_type); PUSH_FIELD_VALUE (sym, "clname", clname); @@ -2798,7 +2856,6 @@ build_symbol_entry (tree decl, tree special) PUSH_FIELD_VALUE (sym, "signature", signature); FINISH_RECORD_CONSTRUCTOR (sym); TREE_CONSTANT (sym) = 1; - TREE_INVARIANT (sym) = 1; return sym; } @@ -2839,7 +2896,6 @@ emit_symbol_table (tree name, tree the_table, tree decl_list, PUSH_FIELD_VALUE (null_symbol, "signature", null_pointer_node); FINISH_RECORD_CONSTRUCTOR (null_symbol); TREE_CONSTANT (null_symbol) = 1; - TREE_INVARIANT (null_symbol) = 1; list = tree_cons (NULL_TREE, null_symbol, list); /* Put the list in the right order and make it a constructor. */ @@ -2962,14 +3018,14 @@ add_assertion_table_entry (void **htab_entry, void *ptr) return true; } -/* Generate the type assertion table for CLASS, and return its DECL. */ +/* Generate the type assertion table for KLASS, and return its DECL. */ static tree -emit_assertion_table (tree class) +emit_assertion_table (tree klass) { tree null_entry, ctor, table_decl; tree list = NULL_TREE; - htab_t assertions_htab = TYPE_ASSERTIONS (class); + htab_t assertions_htab = TYPE_ASSERTIONS (klass); /* Iterate through the hash table. */ htab_traverse (assertions_htab, add_assertion_table_entry, &list); @@ -2987,7 +3043,7 @@ emit_assertion_table (tree class) list = nreverse (list); ctor = build_constructor_from_list (assertion_table_type, list); - table_decl = build_decl (VAR_DECL, mangled_classname ("_type_assert_", class), + table_decl = build_decl (VAR_DECL, mangled_classname ("_type_assert_", klass), assertion_table_type); TREE_STATIC (table_decl) = 1; @@ -3016,20 +3072,22 @@ static int java_treetreehash_compare (const void *, const void *); /* A hash table mapping trees to trees. Used generally. */ -#define JAVA_TREEHASHHASH_H(t) (htab_hash_pointer (t)) +#define JAVA_TREEHASHHASH_H(t) ((hashval_t)TYPE_UID (t)) static hashval_t java_treetreehash_hash (const void *k_p) { - struct treetreehash_entry *k = (struct treetreehash_entry *) k_p; + const struct treetreehash_entry *const k + = (const struct treetreehash_entry *) k_p; return JAVA_TREEHASHHASH_H (k->key); } static int java_treetreehash_compare (const void * k1_p, const void * k2_p) { - struct treetreehash_entry * k1 = (struct treetreehash_entry *) k1_p; - tree k2 = (tree) k2_p; + const struct treetreehash_entry *const k1 + = (const struct treetreehash_entry *) k1_p; + const_tree const k2 = (const_tree) k2_p; return (k1->key == k2); } @@ -3038,7 +3096,7 @@ java_treetreehash_find (htab_t ht, tree t) { struct treetreehash_entry *e; hashval_t hv = JAVA_TREEHASHHASH_H (t); - e = htab_find_with_hash (ht, t, hv); + e = (struct treetreehash_entry *) htab_find_with_hash (ht, t, hv); if (e == NULL) return NULL; else @@ -3055,7 +3113,7 @@ java_treetreehash_new (htab_t ht, tree t) e = htab_find_slot_with_hash (ht, t, hv, INSERT); if (*e == NULL) { - tthe = (*ht->alloc_f) (1, sizeof (*tthe)); + tthe = (struct treetreehash_entry *) (*ht->alloc_f) (1, sizeof (*tthe)); tthe->key = t; *e = tthe; } @@ -3085,7 +3143,7 @@ split_qualified_name (tree *left, tree *right, tree source) char *p, *base; int l = IDENTIFIER_LENGTH (source); - base = alloca (l + 1); + base = (char *) alloca (l + 1); memcpy (base, IDENTIFIER_POINTER (source), l + 1); /* Breakdown NAME into REMAINDER . IDENTIFIER. */