00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028 #include "config.h"
00029 #include "system.h"
00030 #include "tree.h"
00031 #include "rtl.h"
00032 #include "flags.h"
00033 #include "java-tree.h"
00034 #include "jcf.h"
00035 #include "obstack.h"
00036 #include "toplev.h"
00037 #include "output.h"
00038 #include "parse.h"
00039 #include "function.h"
00040 #include "ggc.h"
00041 #include "stdio.h"
00042 #include "target.h"
00043
00044
00045 #ifndef O_BINARY
00046 #define O_BINARY 0
00047 #endif
00048
00049 static tree make_method_value PARAMS ((tree));
00050 static tree build_java_method_type PARAMS ((tree, tree, int));
00051 static int32 hashUtf8String PARAMS ((const char *, int));
00052 static tree make_field_value PARAMS ((tree));
00053 static tree get_dispatch_vector PARAMS ((tree));
00054 static tree get_dispatch_table PARAMS ((tree, tree));
00055 static void add_interface_do PARAMS ((tree, tree, int));
00056 static tree maybe_layout_super_class PARAMS ((tree, tree));
00057 static int assume_compiled PARAMS ((const char *));
00058 static struct hash_entry *init_test_hash_newfunc PARAMS ((struct hash_entry *,
00059 struct hash_table *,
00060 hash_table_key));
00061 static tree build_method_symbols_entry PARAMS ((tree));
00062
00063 static rtx registerClass_libfunc;
00064 static rtx registerResource_libfunc;
00065
00066 extern struct obstack permanent_obstack;
00067 struct obstack temporary_obstack;
00068
00069
00070
00071
00072
00073
00074
00075
00076
00077 typedef struct assume_compiled_node_struct
00078 {
00079
00080 const char *ident;
00081
00082
00083 int excludep;
00084
00085
00086 struct assume_compiled_node_struct *parent;
00087 struct assume_compiled_node_struct *sibling;
00088 struct assume_compiled_node_struct *child;
00089 } assume_compiled_node;
00090
00091 static assume_compiled_node *find_assume_compiled_node
00092 PARAMS ((assume_compiled_node *, const char *));
00093
00094
00095
00096 static assume_compiled_node *assume_compiled_tree;
00097
00098 static tree class_roots[5]
00099 = { NULL_TREE, NULL_TREE, NULL_TREE, NULL_TREE, NULL_TREE };
00100 #define registered_class class_roots[0]
00101 #define fields_ident class_roots[1]
00102 #define info_ident class_roots[2]
00103 #define class_list class_roots[3]
00104 #define class_dtable_decl class_roots[4]
00105
00106
00107
00108
00109
00110 static assume_compiled_node *
00111 find_assume_compiled_node (node, ident)
00112 assume_compiled_node *node;
00113 const char *ident;
00114 {
00115 while (node)
00116 {
00117 size_t node_ident_length = strlen (node->ident);
00118
00119
00120
00121
00122
00123
00124 if (node_ident_length == 0
00125 || (strncmp (ident, node->ident, node_ident_length) == 0
00126 && (strlen (ident) == node_ident_length
00127 || ident[node_ident_length] == '.')))
00128 {
00129
00130
00131
00132 assume_compiled_node *found = find_assume_compiled_node (node->child,
00133 ident);
00134 if (found)
00135 return found;
00136 else
00137 return node;
00138 }
00139
00140
00141 node = node->sibling;
00142 }
00143
00144
00145 return NULL;
00146 }
00147
00148
00149
00150
00151 void
00152 add_assume_compiled (ident, excludep)
00153 const char *ident;
00154 int excludep;
00155 {
00156 assume_compiled_node *parent;
00157 assume_compiled_node *node =
00158 (assume_compiled_node *) xmalloc (sizeof (assume_compiled_node));
00159
00160 node->ident = xstrdup (ident);
00161 node->excludep = excludep;
00162 node->child = NULL;
00163
00164
00165
00166 if (NULL == assume_compiled_tree)
00167 {
00168 assume_compiled_tree =
00169 (assume_compiled_node *) xmalloc (sizeof (assume_compiled_node));
00170 assume_compiled_tree->ident = "";
00171 assume_compiled_tree->excludep = 0;
00172 assume_compiled_tree->sibling = NULL;
00173 assume_compiled_tree->child = NULL;
00174 assume_compiled_tree->parent = NULL;
00175 }
00176
00177
00178
00179
00180 if (0 == ident[0])
00181 {
00182 assume_compiled_tree->excludep = excludep;
00183 return;
00184 }
00185
00186
00187
00188
00189 parent = find_assume_compiled_node (assume_compiled_tree, ident);
00190 if (ident[strlen (parent->ident)] != '.')
00191 parent = parent->parent;
00192
00193
00194
00195 node->parent = parent;
00196 node->sibling = parent->child;
00197 parent->child = node;
00198 }
00199
00200
00201
00202
00203 static int
00204 assume_compiled (ident)
00205 const char *ident;
00206 {
00207 assume_compiled_node *i;
00208 int result;
00209
00210 if (NULL == assume_compiled_tree)
00211 return 1;
00212
00213 i = find_assume_compiled_node (assume_compiled_tree,
00214 ident);
00215
00216 result = ! i->excludep;
00217
00218 return (result);
00219 }
00220
00221
00222
00223
00224
00225 tree
00226 ident_subst (old_name, old_length, prefix, old_char, new_char, suffix)
00227 const char* old_name;
00228 int old_length;
00229 const char *prefix;
00230 int old_char;
00231 int new_char;
00232 const char *suffix;
00233 {
00234 int prefix_len = strlen (prefix);
00235 int suffix_len = strlen (suffix);
00236 int i = prefix_len + old_length + suffix_len + 1;
00237 #ifdef __GNUC__
00238 char buffer[i];
00239 #else
00240 char *buffer = (char *)alloca (i);
00241 #endif
00242 strcpy (buffer, prefix);
00243 for (i = 0; i < old_length; i++)
00244 {
00245 char ch = old_name[i];
00246 if (ch == old_char)
00247 ch = new_char;
00248 buffer[prefix_len + i] = ch;
00249 }
00250 strcpy (buffer + prefix_len + old_length, suffix);
00251 return get_identifier (buffer);
00252 }
00253
00254
00255
00256
00257
00258 tree
00259 identifier_subst (old_id, prefix, old_char, new_char, suffix)
00260 const tree old_id;
00261 const char *prefix;
00262 int old_char;
00263 int new_char;
00264 const char *suffix;
00265 {
00266 return ident_subst (IDENTIFIER_POINTER (old_id), IDENTIFIER_LENGTH (old_id),
00267 prefix, old_char, new_char, suffix);
00268 }
00269
00270
00271
00272
00273 tree
00274 mangled_classname (prefix, type)
00275 const char *prefix;
00276 tree type;
00277 {
00278 tree ident = TYPE_NAME (type);
00279 if (TREE_CODE (ident) != IDENTIFIER_NODE)
00280 ident = DECL_NAME (ident);
00281 return identifier_subst (ident, prefix, '.', '_', "");
00282 }
00283
00284 tree
00285 make_class ()
00286 {
00287 tree type;
00288 type = make_node (RECORD_TYPE);
00289 #ifdef JAVA_USE_HANDLES
00290 tree field1 = build_decl (FIELD_DECL, get_identifier ("obj"),
00291 build_pointer_type (type));
00292 tree field2 = build_decl (FIELD_DECL, get_identifier ("methods"),
00293 methodtable_ptr_type);
00294 tree handle_type = make_node (RECORD_TYPE);
00295 TREE_CHAIN (field1) = field2;
00296 TYPE_FIELDS (handle_type) = field1;
00297 TYPE_BINFO (type) = make_tree_vec (7);
00298 TYPE_BINFO (handle_type) = make_tree_vec (7);
00299 BINFO_HANDLE (TYPE_BINFO (handle_type)) = type;
00300 BINFO_HANDLE (TYPE_BINFO (type)) = handle_type;
00301 #else
00302 TYPE_BINFO (type) = make_tree_vec (6);
00303 #endif
00304 MAYBE_CREATE_TYPE_TYPE_LANG_SPECIFIC (type);
00305
00306 return type;
00307 }
00308
00309
00310
00311
00312
00313 tree
00314 unmangle_classname (name, name_length)
00315 const char *name; int name_length;
00316 {
00317 tree to_return = ident_subst (name, name_length, "", '/', '.', "");
00318
00319
00320
00321
00322 name = IDENTIFIER_POINTER (to_return);
00323 while (*name)
00324 if (*name++ == '.')
00325 {
00326 QUALIFIED_P (to_return) = 1;
00327 break;
00328 }
00329
00330 return to_return;
00331 }
00332
00333 tree
00334 push_class (class_type, class_name)
00335 tree class_type, class_name;
00336 {
00337 tree decl, signature;
00338 const char *save_input_filename = input_filename;
00339 int save_lineno = lineno;
00340 tree source_name = identifier_subst (class_name, "", '.', '/', ".java");
00341 CLASS_P (class_type) = 1;
00342 input_filename = IDENTIFIER_POINTER (source_name);
00343 lineno = 0;
00344 decl = build_decl (TYPE_DECL, class_name, class_type);
00345
00346
00347 DECL_SIZE (decl) = integer_zero_node;
00348
00349 input_filename = save_input_filename;
00350 lineno = save_lineno;
00351 signature = identifier_subst (class_name, "L", '.', '/', ";");
00352 IDENTIFIER_SIGNATURE_TYPE (signature) = build_pointer_type (class_type);
00353
00354
00355
00356
00357 DECL_ARTIFICIAL (decl) = 1;
00358
00359 pushdecl_top_level (decl);
00360 #ifdef JAVA_USE_HANDLES
00361 {
00362 tree handle_name = identifier_subst (class_name,
00363 "Handle$", '.', '.', "");
00364 tree handle_decl = build_decl (TYPE_DECL, handle_name,
00365 CLASS_TO_HANDLE_TYPE (class_type));
00366 pushdecl (handle_decl);
00367 }
00368 #endif
00369
00370 return decl;
00371 }
00372
00373
00374
00375
00376
00377
00378 tree
00379 lookup_class (name)
00380 tree name;
00381 {
00382 tree decl = IDENTIFIER_CLASS_VALUE (name);
00383 if (decl == NULL_TREE)
00384 decl = push_class (make_class (), name);
00385 return TREE_TYPE (decl);
00386 }
00387
00388 void
00389 set_super_info (access_flags, this_class, super_class, interfaces_count)
00390 int access_flags;
00391 tree this_class;
00392 tree super_class;
00393 int interfaces_count;
00394 {
00395 int total_supers = interfaces_count;
00396 tree class_decl = TYPE_NAME (this_class);
00397 if (super_class)
00398 total_supers++;
00399
00400 TYPE_BINFO_BASETYPES (this_class) = make_tree_vec (total_supers);
00401 if (super_class)
00402 {
00403 tree super_binfo = make_tree_vec (6);
00404 BINFO_TYPE (super_binfo) = super_class;
00405 BINFO_OFFSET (super_binfo) = integer_zero_node;
00406 TREE_VIA_PUBLIC (super_binfo) = 1;
00407 TREE_VEC_ELT (BINFO_BASETYPES (TYPE_BINFO (this_class)), 0)
00408 = super_binfo;
00409 CLASS_HAS_SUPER (this_class) = 1;
00410 }
00411
00412 set_class_decl_access_flags (access_flags, class_decl);
00413 }
00414
00415 void
00416 set_class_decl_access_flags (access_flags, class_decl)
00417 int access_flags;
00418 tree class_decl;
00419 {
00420 if (access_flags & ACC_PUBLIC) CLASS_PUBLIC (class_decl) = 1;
00421 if (access_flags & ACC_FINAL) CLASS_FINAL (class_decl) = 1;
00422 if (access_flags & ACC_SUPER) CLASS_SUPER (class_decl) = 1;
00423 if (access_flags & ACC_INTERFACE) CLASS_INTERFACE (class_decl) = 1;
00424 if (access_flags & ACC_ABSTRACT) CLASS_ABSTRACT (class_decl) = 1;
00425 if (access_flags & ACC_STATIC) CLASS_STATIC (class_decl) = 1;
00426 if (access_flags & ACC_PRIVATE) CLASS_PRIVATE (class_decl) = 1;
00427 if (access_flags & ACC_PROTECTED) CLASS_PROTECTED (class_decl) = 1;
00428 if (access_flags & ACC_STRICT) CLASS_STRICTFP (class_decl) = 1;
00429 }
00430
00431
00432
00433
00434 int
00435 class_depth (clas)
00436 tree clas;
00437 {
00438 int depth = 0;
00439 if (! CLASS_LOADED_P (clas))
00440 load_class (clas, 1);
00441 if (TYPE_SIZE (clas) == error_mark_node)
00442 return -1;
00443 while (clas != object_type_node)
00444 {
00445 depth++;
00446 clas = TYPE_BINFO_BASETYPE (clas, 0);
00447 }
00448 return depth;
00449 }
00450
00451
00452
00453 int
00454 interface_of_p (type1, type2)
00455 tree type1, type2;
00456 {
00457 int n, i;
00458 tree basetype_vec;
00459
00460 if (!(basetype_vec = TYPE_BINFO_BASETYPES (type2)))
00461 return 0;
00462 n = TREE_VEC_LENGTH (basetype_vec);
00463 for (i = 0; i < n; i++)
00464 {
00465 tree vec_elt = TREE_VEC_ELT (basetype_vec, i);
00466 if (vec_elt && BINFO_TYPE (vec_elt) == type1)
00467 return 1;
00468 }
00469 for (i = 0; i < n; i++)
00470 {
00471 tree vec_elt = TREE_VEC_ELT (basetype_vec, i);
00472 if (vec_elt && BINFO_TYPE (vec_elt)
00473 && interface_of_p (type1, BINFO_TYPE (vec_elt)))
00474 return 1;
00475 }
00476 return 0;
00477 }
00478
00479
00480
00481 int
00482 inherits_from_p (type1, type2)
00483 tree type1, type2;
00484 {
00485 while (type1 != NULL_TREE && TREE_CODE (type1) == RECORD_TYPE)
00486 {
00487 if (type1 == type2)
00488 return 1;
00489 type1 = CLASSTYPE_SUPER (type1);
00490 }
00491 return 0;
00492 }
00493
00494
00495
00496 int
00497 enclosing_context_p (type1, type2)
00498 tree type1, type2;
00499 {
00500 if (!INNER_CLASS_TYPE_P (type2))
00501 return 0;
00502
00503 for (type2 = TREE_TYPE (DECL_CONTEXT (TYPE_NAME (type2)));
00504 type2;
00505 type2 = (INNER_CLASS_TYPE_P (type2) ?
00506 TREE_TYPE (DECL_CONTEXT (TYPE_NAME (type2))) : NULL_TREE))
00507 {
00508 if (type2 == type1)
00509 return 1;
00510 }
00511
00512 return 0;
00513 }
00514
00515
00516
00517
00518 int common_enclosing_context_p (type1, type2)
00519 tree type1, type2;
00520 {
00521 if (!PURE_INNER_CLASS_TYPE_P (type1) || !PURE_INNER_CLASS_TYPE_P (type2))
00522 return 0;
00523
00524 for (type1 = TREE_TYPE (DECL_CONTEXT (TYPE_NAME (type1))); type1;
00525 type1 = (PURE_INNER_CLASS_TYPE_P (type1) ?
00526 TREE_TYPE (DECL_CONTEXT (TYPE_NAME (type1))) : NULL_TREE))
00527 {
00528 tree current;
00529 for (current = TREE_TYPE (DECL_CONTEXT (TYPE_NAME (type2))); current;
00530 current = (PURE_INNER_CLASS_TYPE_P (current) ?
00531 TREE_TYPE (DECL_CONTEXT (TYPE_NAME (current))) :
00532 NULL_TREE))
00533 if (type1 == current)
00534 return 1;
00535 }
00536 return 0;
00537 }
00538
00539 static void
00540 add_interface_do (basetype_vec, interface_class, i)
00541 tree basetype_vec, interface_class;
00542 int i;
00543 {
00544 tree interface_binfo = make_tree_vec (6);
00545 BINFO_TYPE (interface_binfo) = interface_class;
00546 BINFO_OFFSET (interface_binfo) = integer_zero_node;
00547 BINFO_VPTR_FIELD (interface_binfo) = integer_zero_node;
00548 TREE_VIA_VIRTUAL (interface_binfo) = 1;
00549 TREE_VIA_PUBLIC (interface_binfo) = 1;
00550 TREE_VEC_ELT (basetype_vec, i) = interface_binfo;
00551 }
00552
00553
00554
00555
00556
00557 tree
00558 maybe_add_interface (this_class, interface_class)
00559 tree this_class, interface_class;
00560 {
00561 tree basetype_vec = TYPE_BINFO_BASETYPES (this_class);
00562 int i;
00563 int n = TREE_VEC_LENGTH (basetype_vec);
00564 for (i = 0; ; i++)
00565 {
00566 if (i >= n)
00567 {
00568 error ("internal error - too many interface type");
00569 return NULL_TREE;
00570 }
00571 else if (TREE_VEC_ELT (basetype_vec, i) == NULL_TREE)
00572 break;
00573 else if (BINFO_TYPE (TREE_VEC_ELT (basetype_vec, i)) == interface_class)
00574 return interface_class;
00575 }
00576 add_interface_do (basetype_vec, interface_class, i);
00577 return NULL_TREE;
00578 }
00579
00580
00581
00582 void
00583 add_interface (this_class, interface_class)
00584 tree this_class, interface_class;
00585 {
00586 tree basetype_vec = TYPE_BINFO_BASETYPES (this_class);
00587 int i;
00588 int n = TREE_VEC_LENGTH (basetype_vec);
00589 for (i = 0; ; i++)
00590 {
00591 if (i >= n)
00592 {
00593 error ("internal error - too many interface type");
00594 return;
00595 }
00596 else if (TREE_VEC_ELT (basetype_vec, i) == NULL_TREE)
00597 break;
00598 }
00599 add_interface_do (basetype_vec, interface_class, i);
00600 }
00601
00602 #if 0
00603
00604
00605
00606 static tree *
00607 find_named_method (list, name)
00608 tree *list;
00609 tree name;
00610 {
00611 while (*list && DECL_NAME (*list) != name)
00612 list = &TREE_CHAIN (*list);
00613 return list;
00614 }
00615 #endif
00616
00617 static tree
00618 build_java_method_type (fntype, this_class, access_flags)
00619 tree fntype;
00620 tree this_class;
00621 int access_flags;
00622 {
00623 if (access_flags & ACC_STATIC)
00624 return fntype;
00625 return build_method_type (CLASS_TO_HANDLE_TYPE (this_class), fntype);
00626 }
00627
00628 static struct hash_entry *
00629 init_test_hash_newfunc (entry, table, string)
00630 struct hash_entry *entry;
00631 struct hash_table *table;
00632 hash_table_key string ATTRIBUTE_UNUSED;
00633 {
00634 struct init_test_hash_entry *ret = (struct init_test_hash_entry *) entry;
00635 if (ret == NULL)
00636 {
00637 ret = ((struct init_test_hash_entry *)
00638 hash_allocate (table, sizeof (struct init_test_hash_entry)));
00639 if (ret == NULL)
00640 return NULL;
00641 }
00642 ret->init_test_decl = 0;
00643 return (struct hash_entry *) ret;
00644 }
00645
00646
00647
00648
00649
00650 unsigned long
00651 java_hash_hash_tree_node (k)
00652 hash_table_key k;
00653 {
00654 return (long) k;
00655 }
00656
00657 bool
00658 java_hash_compare_tree_node (k1, k2)
00659 hash_table_key k1;
00660 hash_table_key k2;
00661 {
00662 return ((tree) k1 == (tree) k2);
00663 }
00664
00665 tree
00666 add_method_1 (handle_class, access_flags, name, function_type)
00667 tree handle_class;
00668 int access_flags;
00669 tree name;
00670 tree function_type;
00671 {
00672 tree method_type, fndecl;
00673
00674 method_type = build_java_method_type (function_type,
00675 handle_class, access_flags);
00676
00677 fndecl = build_decl (FUNCTION_DECL, name, method_type);
00678 DECL_CONTEXT (fndecl) = handle_class;
00679
00680 DECL_LANG_SPECIFIC (fndecl)
00681 = (struct lang_decl *) ggc_alloc_cleared (sizeof (struct lang_decl));
00682
00683
00684 hash_table_init (&DECL_FUNCTION_INIT_TEST_TABLE (fndecl),
00685 init_test_hash_newfunc, java_hash_hash_tree_node,
00686 java_hash_compare_tree_node);
00687
00688
00689 if (access_flags & ACC_STATIC)
00690 hash_table_init (&DECL_FUNCTION_INITIALIZED_CLASS_TABLE (fndecl),
00691 init_test_hash_newfunc, java_hash_hash_tree_node,
00692 java_hash_compare_tree_node);
00693
00694
00695 DECL_FUNCTION_STATIC_METHOD_INVOCATION_COMPOUND (fndecl) = NULL_TREE;
00696
00697 TREE_CHAIN (fndecl) = TYPE_METHODS (handle_class);
00698 TYPE_METHODS (handle_class) = fndecl;
00699
00700
00701
00702 if (name == finalize_identifier_node
00703 && TREE_TYPE (function_type) == void_type_node
00704 && TREE_VALUE (TYPE_ARG_TYPES (function_type)) == void_type_node)
00705 HAS_FINALIZER_P (handle_class) = 1;
00706
00707 if (access_flags & ACC_PUBLIC) METHOD_PUBLIC (fndecl) = 1;
00708 if (access_flags & ACC_PROTECTED) METHOD_PROTECTED (fndecl) = 1;
00709 if (access_flags & ACC_PRIVATE)
00710 METHOD_PRIVATE (fndecl) = DECL_INLINE (fndecl) = 1;
00711 if (access_flags & ACC_NATIVE)
00712 {
00713 METHOD_NATIVE (fndecl) = 1;
00714 DECL_EXTERNAL (fndecl) = 1;
00715 }
00716 if (access_flags & ACC_STATIC)
00717 METHOD_STATIC (fndecl) = DECL_INLINE (fndecl) = 1;
00718 if (access_flags & ACC_FINAL)
00719 METHOD_FINAL (fndecl) = DECL_INLINE (fndecl) = 1;
00720 if (access_flags & ACC_SYNCHRONIZED) METHOD_SYNCHRONIZED (fndecl) = 1;
00721 if (access_flags & ACC_ABSTRACT) METHOD_ABSTRACT (fndecl) = 1;
00722 if (access_flags & ACC_TRANSIENT) METHOD_TRANSIENT (fndecl) = 1;
00723 if (access_flags & ACC_STRICT) METHOD_STRICTFP (fndecl) = 1;
00724 return fndecl;
00725 }
00726
00727
00728
00729
00730
00731 tree
00732 add_method (this_class, access_flags, name, method_sig)
00733 tree this_class;
00734 int access_flags;
00735 tree name;
00736 tree method_sig;
00737 {
00738 tree handle_class = CLASS_TO_HANDLE_TYPE (this_class);
00739 tree function_type, fndecl;
00740 const unsigned char *sig
00741 = (const unsigned char *) IDENTIFIER_POINTER (method_sig);
00742
00743 if (sig[0] != '(')
00744 fatal_error ("bad method signature");
00745
00746 function_type = get_type_from_signature (method_sig);
00747 fndecl = add_method_1 (handle_class, access_flags, name, function_type);
00748 set_java_signature (TREE_TYPE (fndecl), method_sig);
00749 return fndecl;
00750 }
00751
00752 tree
00753 add_field (class, name, field_type, flags)
00754 tree class;
00755 tree name;
00756 tree field_type;
00757 int flags;
00758 {
00759 int is_static = (flags & ACC_STATIC) != 0;
00760 tree field;
00761 field = build_decl (is_static ? VAR_DECL : FIELD_DECL, name, field_type);
00762 TREE_CHAIN (field) = TYPE_FIELDS (class);
00763 TYPE_FIELDS (class) = field;
00764 DECL_CONTEXT (field) = class;
00765
00766 if (flags & ACC_PUBLIC) FIELD_PUBLIC (field) = 1;
00767 if (flags & ACC_PROTECTED) FIELD_PROTECTED (field) = 1;
00768 if (flags & ACC_PRIVATE) FIELD_PRIVATE (field) = 1;
00769 if (flags & ACC_FINAL) FIELD_FINAL (field) = 1;
00770 if (flags & ACC_VOLATILE) FIELD_VOLATILE (field) = 1;
00771 if (flags & ACC_TRANSIENT) FIELD_TRANSIENT (field) = 1;
00772 if (is_static)
00773 {
00774 FIELD_STATIC (field) = 1;
00775
00776
00777 TREE_PUBLIC (field) = 1;
00778
00779
00780 DECL_EXTERNAL (field) = 1;
00781 }
00782
00783 return field;
00784 }
00785
00786
00787
00788 void
00789 set_constant_value (field, constant)
00790 tree field, constant;
00791 {
00792 if (field == NULL_TREE)
00793 warning ("misplaced ConstantValue attribute (not in any field)");
00794 else if (DECL_INITIAL (field) != NULL_TREE)
00795 warning ("duplicate ConstantValue attribute for field '%s'",
00796 IDENTIFIER_POINTER (DECL_NAME (field)));
00797 else
00798 {
00799 DECL_INITIAL (field) = constant;
00800 if (TREE_TYPE (constant) != TREE_TYPE (field)
00801 && ! (TREE_TYPE (constant) == int_type_node
00802 && INTEGRAL_TYPE_P (TREE_TYPE (field))
00803 && TYPE_PRECISION (TREE_TYPE (field)) <= 32)
00804 && ! (TREE_TYPE (constant) == utf8const_ptr_type
00805 && TREE_TYPE (field) == string_ptr_type_node))
00806 error ("ConstantValue attribute of field '%s' has wrong type",
00807 IDENTIFIER_POINTER (DECL_NAME (field)));
00808 if (FIELD_FINAL (field))
00809 DECL_FIELD_FINAL_IUD (field) = 1;
00810 }
00811 }
00812
00813
00814
00815 #if 0
00816 int
00817 strLengthUtf8 (str, len)
00818 char *str;
00819 int len;
00820 {
00821 register unsigned char* ptr = (unsigned char*) str;
00822 register unsigned char *limit = ptr + len;
00823 int str_length = 0;
00824 for (; ptr < limit; str_length++) {
00825 if (UTF8_GET (ptr, limit) < 0)
00826 return -1;
00827 }
00828 return str_length;
00829 }
00830 #endif
00831
00832
00833
00834
00835
00836
00837 static int32
00838 hashUtf8String (str, len)
00839 const char *str;
00840 int len;
00841 {
00842 register const unsigned char* ptr = (const unsigned char*) str;
00843 register const unsigned char *limit = ptr + len;
00844 int32 hash = 0;
00845 for (; ptr < limit;)
00846 {
00847 int ch = UTF8_GET (ptr, limit);
00848
00849
00850 hash = (31 * hash) + ch;
00851 }
00852 return hash;
00853 }
00854
00855
00856
00857
00858
00859 void
00860 compile_resource_file (name, filename)
00861 char *name;
00862 const char *filename;
00863 {
00864 struct stat stat_buf;
00865 int fd;
00866 char *buffer;
00867 char buf[60];
00868 tree rtype, field = NULL_TREE, data_type, rinit, data, decl;
00869 static int Jr_count = 0;
00870
00871 fd = open (filename, O_RDONLY | O_BINARY);
00872 if (fd < 0)
00873 {
00874 perror ("Failed to read resource file");
00875 return;
00876 }
00877 if (fstat (fd, &stat_buf) != 0
00878 || ! S_ISREG (stat_buf.st_mode))
00879 {
00880 perror ("Could not figure length of resource file");
00881 return;
00882 }
00883 buffer = xmalloc (strlen (name) + stat_buf.st_size);
00884 strcpy (buffer, name);
00885 read (fd, buffer + strlen (name), stat_buf.st_size);
00886 close (fd);
00887 data_type = build_prim_array_type (unsigned_byte_type_node,
00888 strlen (name) + stat_buf.st_size);
00889 rtype = make_node (RECORD_TYPE);
00890 PUSH_FIELD (rtype, field, "name_length", unsigned_int_type_node);
00891 PUSH_FIELD (rtype, field, "resource_length", unsigned_int_type_node);
00892 PUSH_FIELD (rtype, field, "data", data_type);
00893 FINISH_RECORD (rtype);
00894 START_RECORD_CONSTRUCTOR (rinit, rtype);
00895 PUSH_FIELD_VALUE (rinit, "name_length",
00896 build_int_2 (strlen (name), 0));
00897 PUSH_FIELD_VALUE (rinit, "resource_length",
00898 build_int_2 (stat_buf.st_size, 0));
00899 data = build_string (strlen(name) + stat_buf.st_size, buffer);
00900 TREE_TYPE (data) = data_type;
00901 PUSH_FIELD_VALUE (rinit, "data", data);
00902 FINISH_RECORD_CONSTRUCTOR (rinit);
00903 TREE_CONSTANT (rinit) = 1;
00904
00905
00906 sprintf(buf, "_Jr%d", ++Jr_count);
00907
00908 decl = build_decl (VAR_DECL, get_identifier (buf), rtype);
00909 TREE_STATIC (decl) = 1;
00910 DECL_ARTIFICIAL (decl) = 1;
00911 DECL_IGNORED_P (decl) = 1;
00912 TREE_READONLY (decl) = 1;
00913 TREE_THIS_VOLATILE (decl) = 0;
00914 DECL_INITIAL (decl) = rinit;
00915 layout_decl (decl, 0);
00916 pushdecl (decl);
00917 rest_of_decl_compilation (decl, (char*) 0, global_bindings_p (), 0);
00918 make_decl_rtl (decl, (char*) 0);
00919 assemble_variable (decl, 1, 0, 0);
00920
00921 {
00922 tree init_name = get_file_function_name ('I');
00923 tree init_type = build_function_type (void_type_node, end_params_node);
00924 tree init_decl;
00925
00926 init_decl = build_decl (FUNCTION_DECL, init_name, init_type);
00927 SET_DECL_ASSEMBLER_NAME (init_decl, init_name);
00928 TREE_STATIC (init_decl) = 1;
00929 current_function_decl = init_decl;
00930 DECL_RESULT (init_decl) = build_decl (RESULT_DECL,
00931 NULL_TREE, void_type_node);
00932
00933
00934
00935 TREE_PUBLIC (init_decl) = ! targetm.have_ctors_dtors;
00936
00937 pushlevel (0);
00938 make_decl_rtl (init_decl, NULL);
00939 init_function_start (init_decl, input_filename, 0);
00940 expand_function_start (init_decl, 0);
00941
00942 emit_library_call (registerResource_libfunc, 0, VOIDmode, 1,
00943 gen_rtx (SYMBOL_REF, Pmode, buf),
00944 Pmode);
00945
00946 expand_function_end (input_filename, 0, 0);
00947 poplevel (1, 0, 1);
00948 {
00949
00950 int saved_flag = flag_inline_functions;
00951 flag_inline_functions = 0;
00952 rest_of_compilation (init_decl);
00953 flag_inline_functions = saved_flag;
00954 }
00955 current_function_decl = NULL_TREE;
00956 (* targetm.asm_out.constructor) (XEXP (DECL_RTL (init_decl), 0),
00957 DEFAULT_INIT_PRIORITY);
00958 }
00959 }
00960
00961 tree utf8_decl_list = NULL_TREE;
00962
00963 tree
00964 build_utf8_ref (name)
00965 tree name;
00966 {
00967 const char * name_ptr = IDENTIFIER_POINTER(name);
00968 int name_len = IDENTIFIER_LENGTH(name);
00969 char buf[60];
00970 tree ctype, field = NULL_TREE, str_type, cinit, string;
00971 static int utf8_count = 0;
00972 int name_hash;
00973 tree ref = IDENTIFIER_UTF8_REF (name);
00974 tree decl;
00975 if (ref != NULL_TREE)
00976 return ref;
00977
00978 ctype = make_node (RECORD_TYPE);
00979 str_type = build_prim_array_type (unsigned_byte_type_node,
00980 name_len + 1);
00981 PUSH_FIELD (ctype, field, "hash", unsigned_short_type_node);
00982 PUSH_FIELD (ctype, field, "length", unsigned_short_type_node);
00983 PUSH_FIELD (ctype, field, "data", str_type);
00984 FINISH_RECORD (ctype);
00985 START_RECORD_CONSTRUCTOR (cinit, ctype);
00986 name_hash = hashUtf8String (name_ptr, name_len) & 0xFFFF;
00987 PUSH_FIELD_VALUE (cinit, "hash", build_int_2 (name_hash, 0));
00988 PUSH_FIELD_VALUE (cinit, "length", build_int_2 (name_len, 0));
00989 string = build_string (name_len, name_ptr);
00990 TREE_TYPE (string) = str_type;
00991 PUSH_FIELD_VALUE (cinit, "data", string);
00992 FINISH_RECORD_CONSTRUCTOR (cinit);
00993 TREE_CONSTANT (cinit) = 1;
00994
00995
00996 sprintf(buf, "_Utf%d", ++utf8_count);
00997
00998 decl = build_decl (VAR_DECL, get_identifier (buf), utf8const_type);
00999 TREE_STATIC (decl) = 1;
01000 DECL_ARTIFICIAL (decl) = 1;
01001 DECL_IGNORED_P (decl) = 1;
01002 TREE_READONLY (decl) = 1;
01003 TREE_THIS_VOLATILE (decl) = 0;
01004 DECL_INITIAL (decl) = cinit;
01005 #ifdef HAVE_GAS_SHF_MERGE
01006 {
01007 int decl_size;
01008
01009 decl_size = (name_len + 5 + TYPE_ALIGN_UNIT (utf8const_type) - 1)
01010 & ~(TYPE_ALIGN_UNIT (utf8const_type) - 1);
01011 if (flag_merge_constants && decl_size < 256)
01012 {
01013 char buf[32];
01014 int flags = (SECTION_OVERRIDE
01015 | SECTION_MERGE | (SECTION_ENTSIZE & decl_size));
01016 sprintf (buf, ".rodata.jutf8.%d", decl_size);
01017 named_section_flags (buf, flags);
01018 DECL_SECTION_NAME (decl) = build_string (strlen (buf), buf);
01019 }
01020 }
01021 #endif
01022 TREE_CHAIN (decl) = utf8_decl_list;
01023 layout_decl (decl, 0);
01024 pushdecl (decl);
01025 rest_of_decl_compilation (decl, (char*) 0, global_bindings_p (), 0);
01026 utf8_decl_list = decl;
01027 make_decl_rtl (decl, (char*) 0);
01028 ref = build1 (ADDR_EXPR, utf8const_ptr_type, decl);
01029 IDENTIFIER_UTF8_REF (name) = ref;
01030 return ref;
01031 }
01032
01033
01034
01035
01036 tree
01037 build_class_ref (type)
01038 tree type;
01039 {
01040 int is_compiled = is_compiled_class (type);
01041 if (is_compiled)
01042 {
01043 tree ref, decl_name, decl;
01044 if (TREE_CODE (type) == POINTER_TYPE)
01045 type = TREE_TYPE (type);
01046 if (TREE_CODE (type) == RECORD_TYPE)
01047 {
01048 if (TYPE_SIZE (type) == error_mark_node)
01049 return null_pointer_node;
01050 decl_name = identifier_subst (DECL_NAME (TYPE_NAME (type)),
01051 "", '/', '/', ".class");
01052 decl = IDENTIFIER_GLOBAL_VALUE (decl_name);
01053 if (decl == NULL_TREE)
01054 {
01055 decl = build_decl (VAR_DECL, decl_name, class_type_node);
01056 DECL_SIZE (decl) = TYPE_SIZE (class_type_node);
01057 DECL_SIZE_UNIT (decl) = TYPE_SIZE_UNIT (class_type_node);
01058 TREE_STATIC (decl) = 1;
01059 TREE_PUBLIC (decl) = 1;
01060 DECL_IGNORED_P (decl) = 1;
01061 DECL_ARTIFICIAL (decl) = 1;
01062 if (is_compiled == 1)
01063 DECL_EXTERNAL (decl) = 1;
01064 SET_DECL_ASSEMBLER_NAME (decl,
01065 java_mangle_class_field
01066 (&temporary_obstack, type));
01067 make_decl_rtl (decl, NULL);
01068 pushdecl_top_level (decl);
01069 }
01070 }
01071 else
01072 {
01073 const char *name;
01074 char buffer[25];
01075 if (flag_emit_class_files)
01076 {
01077 const char *prim_class_name;
01078 tree prim_class;
01079 if (type == char_type_node)
01080 prim_class_name = "java.lang.Character";
01081 else if (type == boolean_type_node)
01082 prim_class_name = "java.lang.Boolean";
01083 else if (type == byte_type_node)
01084 prim_class_name = "java.lang.Byte";
01085 else if (type == short_type_node)
01086 prim_class_name = "java.lang.Short";
01087 else if (type == int_type_node)
01088 prim_class_name = "java.lang.Integer";
01089 else if (type == long_type_node)
01090 prim_class_name = "java.lang.Long";
01091 else if (type == float_type_node)
01092 prim_class_name = "java.lang.Float";
01093 else if (type == double_type_node)
01094 prim_class_name = "java.lang.Double";
01095 else if (type == void_type_node)
01096 prim_class_name = "java.lang.Void";
01097 else
01098 abort ();
01099
01100 prim_class = lookup_class (get_identifier (prim_class_name));
01101 return build (COMPONENT_REF, NULL_TREE,
01102 prim_class, TYPE_identifier_node);
01103 }
01104 decl_name = TYPE_NAME (type);
01105 if (TREE_CODE (decl_name) == TYPE_DECL)
01106 decl_name = DECL_NAME (decl_name);
01107 name = IDENTIFIER_POINTER (decl_name);
01108 if (strncmp (name, "promoted_", 9) == 0)
01109 name += 9;
01110 sprintf (buffer, "_Jv_%sClass", name);
01111 decl_name = get_identifier (buffer);
01112 decl = IDENTIFIER_GLOBAL_VALUE (decl_name);
01113 if (decl == NULL_TREE)
01114 {
01115 decl = build_decl (VAR_DECL, decl_name, class_type_node);
01116 TREE_STATIC (decl) = 1;
01117 TREE_PUBLIC (decl) = 1;
01118 DECL_EXTERNAL (decl) = 1;
01119 make_decl_rtl (decl, NULL);
01120 pushdecl_top_level (decl);
01121 }
01122 }
01123
01124 ref = build1 (ADDR_EXPR, class_ptr_type, decl);
01125 return ref;
01126 }
01127 else
01128 {
01129 int index;
01130 tree cl;
01131 index = alloc_class_constant (type);
01132 cl = build_ref_from_constant_pool (index);
01133 TREE_TYPE (cl) = promote_type (class_ptr_type);
01134 return cl;
01135 }
01136 }
01137
01138 tree
01139 build_static_field_ref (fdecl)
01140 tree fdecl;
01141 {
01142 tree fclass = DECL_CONTEXT (fdecl);
01143 int is_compiled = is_compiled_class (fclass);
01144 if (is_compiled)
01145 {
01146 if (!DECL_RTL_SET_P (fdecl))
01147 {
01148 if (is_compiled == 1)
01149 DECL_EXTERNAL (fdecl) = 1;
01150 make_decl_rtl (fdecl, NULL);
01151 }
01152 return fdecl;
01153 }
01154 else
01155 {
01156
01157
01158 tree ref = build_class_ref (fclass);
01159 tree fld;
01160 int field_index = 0;
01161 ref = build1 (INDIRECT_REF, class_type_node, ref);
01162 ref = build (COMPONENT_REF, field_ptr_type_node, ref,
01163 lookup_field (&class_type_node, fields_ident));
01164
01165 for (fld = TYPE_FIELDS (fclass); ; fld = TREE_CHAIN (fld))
01166 {
01167 if (fld == fdecl)
01168 break;
01169 if (fld == NULL_TREE)
01170 fatal_error ("field '%s' not found in class",
01171 IDENTIFIER_POINTER (DECL_NAME (fdecl)));
01172 if (FIELD_STATIC (fld))
01173 field_index++;
01174 }
01175 field_index *= int_size_in_bytes (field_type_node);
01176 ref = fold (build (PLUS_EXPR, field_ptr_type_node,
01177 ref, build_int_2 (field_index, 0)));
01178 ref = build1 (INDIRECT_REF, field_type_node, ref);
01179 ref = build (COMPONENT_REF, field_info_union_node,
01180 ref, lookup_field (&field_type_node, info_ident));
01181 ref = build (COMPONENT_REF, ptr_type_node,
01182 ref, TREE_CHAIN (TYPE_FIELDS (field_info_union_node)));
01183 return fold (build1 (INDIRECT_REF, TREE_TYPE(fdecl), ref));
01184 }
01185 }
01186
01187 int
01188 get_access_flags_from_decl (decl)
01189 tree decl;
01190 {
01191 int access_flags = 0;
01192 if (TREE_CODE (decl) == FIELD_DECL || TREE_CODE (decl) == VAR_DECL)
01193 {
01194 if (FIELD_STATIC (decl))
01195 access_flags |= ACC_STATIC;
01196 if (FIELD_PUBLIC (decl))
01197 access_flags |= ACC_PUBLIC;
01198 if (FIELD_PROTECTED (decl))
01199 access_flags |= ACC_PROTECTED;
01200 if (FIELD_PRIVATE (decl))
01201 access_flags |= ACC_PRIVATE;
01202 if (FIELD_FINAL (decl))
01203 access_flags |= ACC_FINAL;
01204 if (FIELD_VOLATILE (decl))
01205 access_flags |= ACC_VOLATILE;
01206 if (FIELD_TRANSIENT (decl))
01207 access_flags |= ACC_TRANSIENT;
01208 return access_flags;
01209 }
01210 if (TREE_CODE (decl) == TYPE_DECL)
01211 {
01212 if (CLASS_PUBLIC (decl))
01213 access_flags |= ACC_PUBLIC;
01214 if (CLASS_FINAL (decl))
01215 access_flags |= ACC_FINAL;
01216 if (CLASS_SUPER (decl))
01217 access_flags |= ACC_SUPER;
01218 if (CLASS_INTERFACE (decl))
01219 access_flags |= ACC_INTERFACE;
01220 if (CLASS_ABSTRACT (decl))
01221 access_flags |= ACC_ABSTRACT;
01222 if (CLASS_STATIC (decl))
01223 access_flags |= ACC_STATIC;
01224 if (CLASS_PRIVATE (decl))
01225 access_flags |= ACC_PRIVATE;
01226 if (CLASS_PROTECTED (decl))
01227 access_flags |= ACC_PROTECTED;
01228 if (CLASS_STRICTFP (decl))
01229 access_flags |= ACC_STRICT;
01230 return access_flags;
01231 }
01232 if (TREE_CODE (decl) == FUNCTION_DECL)
01233 {
01234 if (METHOD_PUBLIC (decl))
01235 access_flags |= ACC_PUBLIC;
01236 if (METHOD_PRIVATE (decl))
01237 access_flags |= ACC_PRIVATE;
01238 if (METHOD_PROTECTED (decl))
01239 access_flags |= ACC_PROTECTED;
01240 if (METHOD_STATIC (decl))
01241 access_flags |= ACC_STATIC;
01242 if (METHOD_FINAL (decl))
01243 access_flags |= ACC_FINAL;
01244 if (METHOD_SYNCHRONIZED (decl))
01245 access_flags |= ACC_SYNCHRONIZED;
01246 if (METHOD_NATIVE (decl))
01247 access_flags |= ACC_NATIVE;
01248 if (METHOD_ABSTRACT (decl))
01249 access_flags |= ACC_ABSTRACT;
01250 if (METHOD_TRANSIENT (decl))
01251 access_flags |= ACC_TRANSIENT;
01252 if (METHOD_STRICTFP (decl))
01253 access_flags |= ACC_STRICT;
01254 return access_flags;
01255 }
01256 abort ();
01257 }
01258
01259 static tree
01260 make_field_value (fdecl)
01261 tree fdecl;
01262 {
01263 tree finit;
01264 int flags;
01265 tree type = TREE_TYPE (fdecl);
01266 int resolved = is_compiled_class (type);
01267
01268 START_RECORD_CONSTRUCTOR (finit, field_type_node);
01269 PUSH_FIELD_VALUE (finit, "name", build_utf8_ref (DECL_NAME (fdecl)));
01270 if (resolved)
01271 type = build_class_ref (type);
01272 else
01273 {
01274 tree signature = build_java_signature (type);
01275
01276 type = build_utf8_ref (unmangle_classname
01277 (IDENTIFIER_POINTER (signature),
01278 IDENTIFIER_LENGTH (signature)));
01279 }
01280 PUSH_FIELD_VALUE (finit, "type", type);
01281
01282 flags = get_access_flags_from_decl (fdecl);
01283 if (! resolved)
01284 flags |= 0x8000 ;
01285
01286 PUSH_FIELD_VALUE (finit, "accflags", build_int_2 (flags, 0));
01287 PUSH_FIELD_VALUE (finit, "bsize", TYPE_SIZE_UNIT (TREE_TYPE (fdecl)));
01288
01289 PUSH_FIELD_VALUE
01290 (finit, "info",
01291 build (CONSTRUCTOR, field_info_union_node, NULL_TREE,
01292 build_tree_list
01293 ((FIELD_STATIC (fdecl)
01294 ? TREE_CHAIN (TYPE_FIELDS (field_info_union_node))
01295 : TYPE_FIELDS (field_info_union_node)),
01296 (FIELD_STATIC (fdecl)
01297 ? build_address_of (build_static_field_ref (fdecl))
01298 : byte_position (fdecl)))));
01299
01300 FINISH_RECORD_CONSTRUCTOR (finit);
01301 return finit;
01302 }
01303
01304 static tree
01305 make_method_value (mdecl)
01306 tree mdecl;
01307 {
01308 static int method_name_count = 0;
01309 tree minit;
01310 tree index;
01311 tree code;
01312 #define ACC_TRANSLATED 0x4000
01313 int accflags = get_access_flags_from_decl (mdecl) | ACC_TRANSLATED;
01314
01315 if (!flag_indirect_dispatch && DECL_VINDEX (mdecl) != NULL_TREE)
01316 index = DECL_VINDEX (mdecl);
01317 else
01318 index = integer_minus_one_node;
01319
01320 code = null_pointer_node;
01321 if (DECL_RTL_SET_P (mdecl))
01322 code = build1 (ADDR_EXPR, nativecode_ptr_type_node, mdecl);
01323 START_RECORD_CONSTRUCTOR (minit, method_type_node);
01324 PUSH_FIELD_VALUE (minit, "name",
01325 build_utf8_ref (DECL_CONSTRUCTOR_P (mdecl) ?
01326 init_identifier_node
01327 : DECL_NAME (mdecl)));
01328 {
01329 tree signature = build_java_signature (TREE_TYPE (mdecl));
01330 PUSH_FIELD_VALUE (minit, "signature",
01331 (build_utf8_ref
01332 (unmangle_classname
01333 (IDENTIFIER_POINTER(signature),
01334 IDENTIFIER_LENGTH(signature)))));
01335 }
01336 PUSH_FIELD_VALUE (minit, "accflags", build_int_2 (accflags, 0));
01337 PUSH_FIELD_VALUE (minit, "index", index);
01338 PUSH_FIELD_VALUE (minit, "ncode", code);
01339
01340 {
01341
01342 tree table = null_pointer_node;
01343 if (DECL_FUNCTION_THROWS (mdecl) != NULL_TREE)
01344 {
01345 int length = 1 + list_length (DECL_FUNCTION_THROWS (mdecl));
01346 tree iter, type, array;
01347 char buf[60];
01348
01349 table = tree_cons (NULL_TREE, table, NULL_TREE);
01350 for (iter = DECL_FUNCTION_THROWS (mdecl);
01351 iter != NULL_TREE;
01352 iter = TREE_CHAIN (iter))
01353 {
01354 tree sig = build_java_signature (TREE_VALUE (iter));
01355 tree utf8
01356 = build_utf8_ref (unmangle_classname (IDENTIFIER_POINTER (sig),
01357 IDENTIFIER_LENGTH (sig)));
01358 table = tree_cons (NULL_TREE, utf8, table);
01359 }
01360 type = build_prim_array_type (ptr_type_node, length);
01361 table = build (CONSTRUCTOR, type, NULL_TREE, table);
01362
01363 sprintf (buf, "_methods%d", method_name_count++);
01364 array = build_decl (VAR_DECL, get_identifier (buf), type);
01365 DECL_INITIAL (array) = table;
01366 TREE_STATIC (array) = 1;
01367 DECL_ARTIFICIAL (array) = 1;
01368 DECL_IGNORED_P (array) = 1;
01369 rest_of_decl_compilation (array, (char*) 0, 1, 0);
01370
01371 table = build1 (ADDR_EXPR, ptr_type_node, array);
01372 }
01373
01374 PUSH_FIELD_VALUE (minit, "throws", table);
01375 }
01376
01377 FINISH_RECORD_CONSTRUCTOR (minit);
01378 return minit;
01379 }
01380
01381 static tree
01382 get_dispatch_vector (type)
01383 tree type;
01384 {
01385 tree vtable = TYPE_VTABLE (type);
01386 if (vtable == NULL)
01387 {
01388 HOST_WIDE_INT i;
01389 tree method;
01390 tree super = CLASSTYPE_SUPER (type);
01391 HOST_WIDE_INT nvirtuals = tree_low_cst (TYPE_NVIRTUALS (type), 0);
01392 vtable = make_tree_vec (nvirtuals);
01393 TYPE_VTABLE (type) = vtable;
01394 if (super != NULL_TREE)
01395 {
01396 tree super_vtable = get_dispatch_vector (super);
01397
01398 for (i = tree_low_cst (TYPE_NVIRTUALS (super), 0); --i >= 0; )
01399 TREE_VEC_ELT (vtable, i) = TREE_VEC_ELT (super_vtable, i);
01400 }
01401
01402 for (method = TYPE_METHODS (type); method != NULL_TREE;
01403 method = TREE_CHAIN (method))
01404 if (DECL_VINDEX (method) != NULL_TREE
01405 && host_integerp (DECL_VINDEX (method), 0))
01406 TREE_VEC_ELT (vtable, tree_low_cst (DECL_VINDEX (method), 0))
01407 = method;
01408 }
01409
01410 return vtable;
01411 }
01412
01413 static tree
01414 get_dispatch_table (type, this_class_addr)
01415 tree type, this_class_addr;
01416 {
01417 int abstract_p = CLASS_ABSTRACT (TYPE_NAME (type));
01418 tree vtable = get_dispatch_vector (type);
01419 int i, j;
01420 tree list = NULL_TREE;
01421 int nvirtuals = TREE_VEC_LENGTH (vtable);
01422 int arraysize;
01423 tree gc_descr;
01424
01425 for (i = nvirtuals; --i >= 0; )
01426 {
01427 tree method = TREE_VEC_ELT (vtable, i);
01428 if (METHOD_ABSTRACT (method))
01429 {
01430 if (! abstract_p)
01431 warning_with_decl (method,
01432 "abstract method in non-abstract class");
01433
01434 if (TARGET_VTABLE_USES_DESCRIPTORS)
01435 for (j = 0; j < TARGET_VTABLE_USES_DESCRIPTORS; ++j)
01436 list = tree_cons (NULL_TREE, null_pointer_node, list);
01437 else
01438 list = tree_cons (NULL_TREE, null_pointer_node, list);
01439 }
01440 else
01441 {
01442 if (!DECL_RTL_SET_P (method))
01443 make_decl_rtl (method, NULL);
01444
01445 if (TARGET_VTABLE_USES_DESCRIPTORS)
01446 for (j = 0; j < TARGET_VTABLE_USES_DESCRIPTORS; ++j)
01447 {
01448 tree fdesc = build (FDESC_EXPR, nativecode_ptr_type_node,
01449 method, build_int_2 (j, 0));
01450 TREE_CONSTANT (fdesc) = 1;
01451 list = tree_cons (NULL_TREE, fdesc, list);
01452 }
01453 else
01454 list = tree_cons (NULL_TREE,
01455 build1 (ADDR_EXPR, nativecode_ptr_type_node,
01456 method),
01457 list);
01458 }
01459 }
01460
01461
01462
01463
01464
01465
01466
01467
01468
01469 gc_descr = get_boehm_type_descriptor (type);
01470 list = tree_cons (NULL_TREE, gc_descr, list);
01471 for (j = 1; j < TARGET_VTABLE_USES_DESCRIPTORS-1; ++j)
01472 list = tree_cons (NULL_TREE, gc_descr, list);
01473 list = tree_cons (NULL_TREE, this_class_addr, list);
01474
01476 list = tree_cons (NULL_TREE, null_pointer_node, list);
01478 list = tree_cons (integer_zero_node, null_pointer_node, list);
01479
01480 arraysize = (TARGET_VTABLE_USES_DESCRIPTORS? nvirtuals + 1 : nvirtuals + 2);
01481 if (TARGET_VTABLE_USES_DESCRIPTORS)
01482 arraysize *= TARGET_VTABLE_USES_DESCRIPTORS;
01483 arraysize += 2;
01484 return build (CONSTRUCTOR,
01485 build_prim_array_type (nativecode_ptr_type_node, arraysize),
01486 NULL_TREE, list);
01487 }
01488
01489 void
01490 make_class_data (type)
01491 tree type;
01492 {
01493 tree decl, cons, temp;
01494 tree field, fields_decl;
01495 tree static_fields = NULL_TREE;
01496 tree instance_fields = NULL_TREE;
01497 HOST_WIDE_INT static_field_count = 0;
01498 HOST_WIDE_INT instance_field_count = 0;
01499 HOST_WIDE_INT field_count;
01500 tree field_array_type;
01501 tree method;
01502 tree methods = NULL_TREE;
01503 tree dtable_decl = NULL_TREE;
01504 HOST_WIDE_INT method_count = 0;
01505 tree method_array_type;
01506 tree methods_decl;
01507 tree super;
01508 tree this_class_addr;
01509 tree constant_pool_constructor;
01510 tree interfaces = null_pointer_node;
01511 int interface_len = 0;
01512 tree type_decl = TYPE_NAME (type);
01515 tree dtable_start_offset = build_int_2 (2 * POINTER_SIZE / BITS_PER_UNIT, 0);
01516
01517 this_class_addr = build_class_ref (type);
01518 decl = TREE_OPERAND (this_class_addr, 0);
01519
01520
01521 field = TYPE_FIELDS (type);
01522 if (DECL_NAME (field) == NULL_TREE)
01523 field = TREE_CHAIN (field);
01524 for ( ; field != NULL_TREE; field = TREE_CHAIN (field))
01525 {
01526 if (! DECL_ARTIFICIAL (field))
01527 {
01528 tree init = make_field_value (field);
01529 if (FIELD_STATIC (field))
01530 {
01531 tree initial = DECL_INITIAL (field);
01532 static_field_count++;
01533 static_fields = tree_cons (NULL_TREE, init, static_fields);
01534
01535
01536 if (initial != NULL_TREE
01537 && TREE_TYPE (initial) == string_ptr_type_node)
01538 DECL_INITIAL (field) = NULL_TREE;
01539 rest_of_decl_compilation (field, (char*) 0, 1, 1);
01540 DECL_INITIAL (field) = initial;
01541 }
01542 else
01543 {
01544 instance_field_count++;
01545 instance_fields = tree_cons (NULL_TREE, init, instance_fields);
01546 }
01547 }
01548 }
01549 field_count = static_field_count + instance_field_count;
01550 if (field_count > 0)
01551 {
01552 static_fields = nreverse (static_fields);
01553 instance_fields = nreverse (instance_fields);
01554 static_fields = chainon (static_fields, instance_fields);
01555 field_array_type = build_prim_array_type (field_type_node, field_count);
01556 fields_decl = build_decl (VAR_DECL, mangled_classname ("_FL_", type),
01557 field_array_type);
01558 DECL_INITIAL (fields_decl) = build (CONSTRUCTOR, field_array_type,
01559 NULL_TREE, static_fields);
01560 TREE_STATIC (fields_decl) = 1;
01561 DECL_ARTIFICIAL (fields_decl) = 1;
01562 DECL_IGNORED_P (fields_decl) = 1;
01563 rest_of_decl_compilation (fields_decl, (char*) 0, 1, 0);
01564 }
01565 else
01566 fields_decl = NULL_TREE;
01567
01568
01569 for (method = TYPE_METHODS (CLASS_TO_HANDLE_TYPE (type));
01570 method != NULL_TREE; method = TREE_CHAIN (method))
01571 {
01572 tree init;
01573 if (METHOD_PRIVATE (method)
01574 && ! flag_keep_inline_functions
01575 && (flag_inline_functions || optimize))
01576 continue;
01577 init = make_method_value (method);
01578 method_count++;
01579 methods = tree_cons (NULL_TREE, init, methods);
01580 }
01581 method_array_type = build_prim_array_type (method_type_node, method_count);
01582 methods_decl = build_decl (VAR_DECL, mangled_classname ("_MT_", type),
01583 method_array_type);
01584 DECL_INITIAL (methods_decl) = build (CONSTRUCTOR, method_array_type,
01585 NULL_TREE, nreverse (methods));
01586 TREE_STATIC (methods_decl) = 1;
01587 DECL_ARTIFICIAL (methods_decl) = 1;
01588 DECL_IGNORED_P (methods_decl) = 1;
01589 rest_of_decl_compilation (methods_decl, (char*) 0, 1, 0);
01590
01591 if (assume_compiled (IDENTIFIER_POINTER (DECL_NAME (type_decl)))
01592 && ! CLASS_INTERFACE (type_decl) && !flag_indirect_dispatch)
01593 {
01594 tree dtable = get_dispatch_table (type, this_class_addr);
01595 dtable_decl = build_dtable_decl (type);
01596 DECL_INITIAL (dtable_decl) = dtable;
01597 TREE_STATIC (dtable_decl) = 1;
01598 DECL_ARTIFICIAL (dtable_decl) = 1;
01599 DECL_IGNORED_P (dtable_decl) = 1;
01600 TREE_PUBLIC (dtable_decl) = 1;
01601 rest_of_decl_compilation (dtable_decl, (char*) 0, 1, 0);
01602 if (type == class_type_node)
01603 class_dtable_decl = dtable_decl;
01604 }
01605
01606 if (class_dtable_decl == NULL_TREE)
01607 {
01608 class_dtable_decl = build_dtable_decl (class_type_node);
01609 TREE_STATIC (class_dtable_decl) = 1;
01610 DECL_ARTIFICIAL (class_dtable_decl) = 1;
01611 DECL_IGNORED_P (class_dtable_decl) = 1;
01612 if (is_compiled_class (class_type_node) != 2)
01613 DECL_EXTERNAL (class_dtable_decl) = 1;
01614 rest_of_decl_compilation (class_dtable_decl, (char*) 0, 1, 0);
01615 }
01616
01617 super = CLASSTYPE_SUPER (type);
01618 if (super == NULL_TREE)
01619 super = null_pointer_node;
01620 else if (assume_compiled (IDENTIFIER_POINTER (DECL_NAME (type_decl))))
01621 super = build_class_ref (super);
01622 else
01623 {
01624 int super_index = alloc_class_constant (super);
01625 super = build_int_2 (super_index, 0);
01626 TREE_TYPE (super) = ptr_type_node;
01627 }
01628
01629
01630 if (type != object_type_node)
01631 interface_len = TREE_VEC_LENGTH (TYPE_BINFO_BASETYPES (type)) - 1;
01632 if (interface_len > 0)
01633 {
01634 tree init = NULL_TREE;
01635 int i;
01636 tree interface_array_type, idecl;
01637 interface_array_type
01638 = build_prim_array_type (class_ptr_type, interface_len);
01639 idecl = build_decl (VAR_DECL, mangled_classname ("_IF_", type),
01640 interface_array_type);
01641 for (i = interface_len; i > 0; i--)
01642 {
01643 tree child = TREE_VEC_ELT (TYPE_BINFO_BASETYPES (type), i);
01644 tree iclass = BINFO_TYPE (child);
01645 tree index;
01646 if (assume_compiled (IDENTIFIER_POINTER (DECL_NAME (TYPE_NAME (iclass)))))
01647 index = build_class_ref (iclass);
01648 else
01649 {
01650 int int_index = alloc_class_constant (iclass);
01651 index = build_int_2 (int_index, 0);
01652 TREE_TYPE (index) = ptr_type_node;
01653 }
01654 init = tree_cons (NULL_TREE, index, init);
01655 }
01656 DECL_INITIAL (idecl) = build (CONSTRUCTOR, interface_array_type,
01657 NULL_TREE, init);
01658 TREE_STATIC (idecl) = 1;
01659 DECL_ARTIFICIAL (idecl) = 1;
01660 DECL_IGNORED_P (idecl) = 1;
01661 interfaces = build1 (ADDR_EXPR, ptr_type_node, idecl);
01662 rest_of_decl_compilation (idecl, (char*) 0, 1, 0);
01663 }
01664
01665 constant_pool_constructor = build_constants_constructor ();
01666
01667 START_RECORD_CONSTRUCTOR (temp, object_type_node);
01668 PUSH_FIELD_VALUE (temp, "vtable",
01669 build (PLUS_EXPR, dtable_ptr_type,
01670 build1 (ADDR_EXPR, dtable_ptr_type, class_dtable_decl),
01671 dtable_start_offset));
01672 if (! flag_hash_synchronization)
01673 PUSH_FIELD_VALUE (temp, "sync_info", null_pointer_node);
01674 FINISH_RECORD_CONSTRUCTOR (temp);
01675 START_RECORD_CONSTRUCTOR (cons, class_type_node);
01676 PUSH_SUPER_VALUE (cons, temp);
01677 PUSH_FIELD_VALUE (cons, "next", null_pointer_node);
01678 PUSH_FIELD_VALUE (cons, "name", build_utf8_ref (DECL_NAME (type_decl)));
01679 PUSH_FIELD_VALUE (cons, "accflags",
01680 build_int_2 (get_access_flags_from_decl (type_decl), 0));
01681
01682 PUSH_FIELD_VALUE (cons, "superclass",
01683 CLASS_INTERFACE (type_decl) ? null_pointer_node : super);
01684 PUSH_FIELD_VALUE (cons, "constants", constant_pool_constructor);
01685 PUSH_FIELD_VALUE (cons, "methods",
01686 build1 (ADDR_EXPR, method_ptr_type_node, methods_decl));
01687 PUSH_FIELD_VALUE (cons, "method_count", build_int_2 (method_count, 0));
01688
01689 if (flag_indirect_dispatch)
01690 PUSH_FIELD_VALUE (cons, "vtable_method_count", integer_minus_one_node)
01691 else
01692 PUSH_FIELD_VALUE (cons, "vtable_method_count", TYPE_NVIRTUALS (type));
01693
01694 PUSH_FIELD_VALUE (cons, "fields",
01695 fields_decl == NULL_TREE ? null_pointer_node
01696 : build1 (ADDR_EXPR, field_ptr_type_node, fields_decl));
01697 PUSH_FIELD_VALUE (cons, "size_in_bytes", size_in_bytes (type));
01698 PUSH_FIELD_VALUE (cons, "field_count", build_int_2 (field_count, 0));
01699 PUSH_FIELD_VALUE (cons, "static_field_count",
01700 build_int_2 (static_field_count, 0));
01701
01702 if (flag_indirect_dispatch)
01703 PUSH_FIELD_VALUE (cons, "vtable", null_pointer_node)
01704 else
01705 PUSH_FIELD_VALUE (cons, "vtable",
01706 dtable_decl == NULL_TREE ? null_pointer_node
01707 : build (PLUS_EXPR, dtable_ptr_type,
01708 build1 (ADDR_EXPR, dtable_ptr_type, dtable_decl),
01709 dtable_start_offset));
01710
01711 if (otable_methods == NULL_TREE)
01712 {
01713 PUSH_FIELD_VALUE (cons, "otable", null_pointer_node);
01714 PUSH_FIELD_VALUE (cons, "otable_syms", null_pointer_node);
01715 }
01716 else
01717 {
01718 PUSH_FIELD_VALUE (cons, "otable",
01719 build1 (ADDR_EXPR, otable_ptr_type, otable_decl));
01720 PUSH_FIELD_VALUE (cons, "otable_syms",
01721 build1 (ADDR_EXPR, method_symbols_array_ptr_type,
01722 otable_syms_decl));
01723 }
01724 PUSH_FIELD_VALUE (cons, "interfaces", interfaces);
01725 PUSH_FIELD_VALUE (cons, "loader", null_pointer_node);
01726 PUSH_FIELD_VALUE (cons, "interface_count", build_int_2 (interface_len, 0));
01727 PUSH_FIELD_VALUE (cons, "state", integer_zero_node);
01728
01729 PUSH_FIELD_VALUE (cons, "thread", null_pointer_node);
01730 PUSH_FIELD_VALUE (cons, "depth", integer_zero_node);
01731 PUSH_FIELD_VALUE (cons, "ancestors", null_pointer_node);
01732 PUSH_FIELD_VALUE (cons, "idt", null_pointer_node);
01733 PUSH_FIELD_VALUE (cons, "arrayclass", null_pointer_node);
01734 PUSH_FIELD_VALUE (cons, "protectionDomain", null_pointer_node);
01735
01736 FINISH_RECORD_CONSTRUCTOR (cons);
01737
01738 DECL_INITIAL (decl) = cons;
01739
01740
01741 if (flag_hash_synchronization && POINTER_SIZE < 64)
01742 DECL_ALIGN (decl) = 64;
01743
01744 rest_of_decl_compilation (decl, (char*) 0, 1, 0);
01745 }
01746
01747 void
01748 finish_class ()
01749 {
01750 tree method;
01751 tree type_methods = TYPE_METHODS (CLASS_TO_HANDLE_TYPE (current_class));
01752 int saw_native_method = 0;
01753
01754
01755
01756 for (method = type_methods;
01757 method != NULL_TREE;
01758 method = TREE_CHAIN (method))
01759 {
01760 if (METHOD_NATIVE (method))
01761 {
01762 saw_native_method = 1;
01763 break;
01764 }
01765 }
01766
01767
01768 for (method = type_methods; method != NULL_TREE; )
01769 {
01770 if (! TREE_ASM_WRITTEN (method) && DECL_SAVED_INSNS (method) != 0)
01771 {
01772 output_inline_function (method);
01773
01774
01775 method = type_methods;
01776 continue;
01777 }
01778 method = TREE_CHAIN (method);
01779 }
01780
01781 current_function_decl = NULL_TREE;
01782 make_class_data (current_class);
01783 register_class ();
01784 rest_of_decl_compilation (TYPE_NAME (current_class), (char*) 0, 1, 0);
01785 }
01786
01787
01788
01789
01790
01791 int
01792 is_compiled_class (class)
01793 tree class;
01794 {
01795 int seen_in_zip;
01796 if (TREE_CODE (class) == POINTER_TYPE)
01797 class = TREE_TYPE (class);
01798 if (TREE_CODE (class) != RECORD_TYPE)
01799 return 1;
01800 if (TYPE_ARRAY_P (class))
01801 return 0;
01802 if (class == current_class)
01803 return 2;
01804
01805 seen_in_zip = (TYPE_JCF (class) && JCF_SEEN_IN_ZIP (TYPE_JCF (class)));
01806 if (CLASS_FROM_CURRENTLY_COMPILED_P (class) || seen_in_zip)
01807 {
01808
01809
01810
01811
01812
01813 if (seen_in_zip && !CLASS_LOADED_P (class))
01814 load_class (class, 1);
01815
01816
01817
01818 return 2;
01819 }
01820
01821 if (assume_compiled (IDENTIFIER_POINTER (DECL_NAME (TYPE_NAME (class)))))
01822 {
01823 if (!CLASS_LOADED_P (class))
01824 {
01825 if (CLASS_FROM_SOURCE_P (class))
01826 safe_layout_class (class);
01827 else
01828 load_class (class, 1);
01829 }
01830 return 1;
01831 }
01832
01833 return 0;
01834 }
01835
01836
01837
01838 tree
01839 build_dtable_decl (type)
01840 tree type;
01841 {
01842 tree dtype;
01843
01844
01845
01846
01847
01848
01849 if (current_class == type)
01850 {
01851 tree dummy = NULL_TREE;
01852 int n;
01853
01854 dtype = make_node (RECORD_TYPE);
01855
01856 PUSH_FIELD (dtype, dummy, "top_offset", ptr_type_node);
01857 PUSH_FIELD (dtype, dummy, "type_info", ptr_type_node);
01858
01859 PUSH_FIELD (dtype, dummy, "class", class_ptr_type);
01860 for (n = 1; n < TARGET_VTABLE_USES_DESCRIPTORS; ++n)
01861 {
01862 tree tmp_field = build_decl (FIELD_DECL, NULL_TREE, ptr_type_node);
01863 TREE_CHAIN (dummy) = tmp_field;
01864 DECL_CONTEXT (tmp_field) = dtype;
01865 DECL_ARTIFICIAL (tmp_field) = 1;
01866 dummy = tmp_field;
01867 }
01868
01869 PUSH_FIELD (dtype, dummy, "gc_descr", ptr_type_node);
01870 for (n = 1; n < TARGET_VTABLE_USES_DESCRIPTORS; ++n)
01871 {
01872 tree tmp_field = build_decl (FIELD_DECL, NULL_TREE, ptr_type_node);
01873 TREE_CHAIN (dummy) = tmp_field;
01874 DECL_CONTEXT (tmp_field) = dtype;
01875 DECL_ARTIFICIAL (tmp_field) = 1;
01876 dummy = tmp_field;
01877 }
01878
01879 n = TREE_VEC_LENGTH (get_dispatch_vector (type));
01880 if (TARGET_VTABLE_USES_DESCRIPTORS)
01881 n *= TARGET_VTABLE_USES_DESCRIPTORS;
01882
01883 PUSH_FIELD (dtype, dummy, "methods",
01884 build_prim_array_type (nativecode_ptr_type_node, n));
01885 layout_type (dtype);
01886 }
01887 else
01888 dtype = dtable_type;
01889
01890 return build_decl (VAR_DECL,
01891 java_mangle_vtable (&temporary_obstack, type), dtype);
01892 }
01893
01894
01895
01896
01897 void
01898 push_super_field (this_class, super_class)
01899 tree this_class, super_class;
01900 {
01901 tree base_decl;
01902
01903 if (TYPE_FIELDS (this_class) && !DECL_NAME (TYPE_FIELDS (this_class)))
01904 return;
01905 base_decl = build_decl (FIELD_DECL, NULL_TREE, super_class);
01906 DECL_IGNORED_P (base_decl) = 1;
01907 TREE_CHAIN (base_decl) = TYPE_FIELDS (this_class);
01908 TYPE_FIELDS (this_class) = base_decl;
01909 DECL_SIZE (base_decl) = TYPE_SIZE (super_class);
01910 DECL_SIZE_UNIT (base_decl) = TYPE_SIZE_UNIT (super_class);
01911 }
01912
01913
01914
01915 static tree
01916 maybe_layout_super_class (super_class, this_class)
01917 tree super_class;
01918 tree this_class;
01919 {
01920 if (TREE_CODE (super_class) == RECORD_TYPE)
01921 {
01922 if (!CLASS_LOADED_P (super_class) && CLASS_FROM_SOURCE_P (super_class))
01923 safe_layout_class (super_class);
01924 if (!CLASS_LOADED_P (super_class))
01925 load_class (super_class, 1);
01926 }
01927
01928
01929 else if (TREE_CODE (super_class) == POINTER_TYPE)
01930 {
01931 if (TREE_TYPE (super_class) != NULL_TREE)
01932 super_class = TREE_TYPE (super_class);
01933 else
01934 {
01935 super_class = do_resolve_class (NULL_TREE,
01936 super_class, NULL_TREE, this_class);
01937 if (!super_class)
01938 return NULL_TREE;
01939 super_class = TREE_TYPE (super_class);
01940 }
01941 }
01942 if (!TYPE_SIZE (super_class))
01943 safe_layout_class (super_class);
01944
01945 return super_class;
01946 }
01947
01948 void
01949 layout_class (this_class)
01950 tree this_class;
01951 {
01952 tree super_class = CLASSTYPE_SUPER (this_class);
01953 tree field;
01954
01955 class_list = tree_cons (this_class, NULL_TREE, class_list);
01956 if (CLASS_BEING_LAIDOUT (this_class))
01957 {
01958 char buffer [1024];
01959 char *report;
01960 tree current;
01961
01962 sprintf (buffer, " with `%s'",
01963 IDENTIFIER_POINTER (DECL_NAME (TYPE_NAME (this_class))));
01964 obstack_grow (&temporary_obstack, buffer, strlen (buffer));
01965
01966 for (current = TREE_CHAIN (class_list); current;
01967 current = TREE_CHAIN (current))
01968 {
01969 tree decl = TYPE_NAME (TREE_PURPOSE (current));
01970 sprintf (buffer, "\n which inherits from `%s' (%s:%d)",
01971 IDENTIFIER_POINTER (DECL_NAME (decl)),
01972 DECL_SOURCE_FILE (decl),
01973 DECL_SOURCE_LINE (decl));
01974 obstack_grow (&temporary_obstack, buffer, strlen (buffer));
01975 }
01976 obstack_1grow (&temporary_obstack, '\0');
01977 report = obstack_finish (&temporary_obstack);
01978 cyclic_inheritance_report = ggc_strdup (report);
01979 obstack_free (&temporary_obstack, report);
01980 TYPE_SIZE (this_class) = error_mark_node;
01981 return;
01982 }
01983 CLASS_BEING_LAIDOUT (this_class) = 1;
01984
01985 if (super_class && !CLASS_BEING_LAIDOUT (super_class))
01986 {
01987 tree maybe_super_class
01988 = maybe_layout_super_class (super_class, this_class);
01989 if (maybe_super_class == NULL
01990 || TREE_CODE (TYPE_SIZE (maybe_super_class)) == ERROR_MARK)
01991 {
01992 TYPE_SIZE (this_class) = error_mark_node;
01993 CLASS_BEING_LAIDOUT (this_class) = 0;
01994 class_list = TREE_CHAIN (class_list);
01995 return;
01996 }
01997 if (TYPE_SIZE (this_class) == NULL_TREE)
01998 push_super_field (this_class, maybe_super_class);
01999 }
02000
02001 for (field = TYPE_FIELDS (this_class);
02002 field != NULL_TREE; field = TREE_CHAIN (field))
02003 {
02004 if (FIELD_STATIC (field))
02005 {
02006
02007 SET_DECL_ASSEMBLER_NAME (field,
02008 java_mangle_decl
02009 (&temporary_obstack, field));
02010 }
02011 }
02012
02013 layout_type (this_class);
02014
02015
02016
02017 if (!CLASS_FROM_SOURCE_P (this_class))
02018 {
02019 tree basetype_vec = TYPE_BINFO_BASETYPES (this_class);
02020
02021 if (basetype_vec)
02022 {
02023 int n = TREE_VEC_LENGTH (basetype_vec) - 1;
02024 int i;
02025 for (i = n; i > 0; i--)
02026 {
02027 tree vec_elt = TREE_VEC_ELT (basetype_vec, i);
02028 tree super_interface = BINFO_TYPE (vec_elt);
02029
02030 tree maybe_super_interface
02031 = maybe_layout_super_class (super_interface, NULL_TREE);
02032 if (maybe_super_interface == NULL
02033 || TREE_CODE (TYPE_SIZE (maybe_super_interface)) == ERROR_MARK)
02034 {
02035 TYPE_SIZE (this_class) = error_mark_node;
02036 CLASS_BEING_LAIDOUT (this_class) = 0;
02037 class_list = TREE_CHAIN (class_list);
02038 return;
02039 }
02040 }
02041 }
02042 }
02043
02044
02045 TYPE_SIZE_UNIT (this_class) =
02046 fold (convert (int_type_node, TYPE_SIZE_UNIT (this_class)));
02047
02048 CLASS_BEING_LAIDOUT (this_class) = 0;
02049 class_list = TREE_CHAIN (class_list);
02050 }
02051
02052 void
02053 layout_class_methods (this_class)
02054 tree this_class;
02055 {
02056 tree method_decl, dtable_count;
02057 tree super_class, handle_type;
02058
02059 if (TYPE_NVIRTUALS (this_class))
02060 return;
02061
02062 super_class = CLASSTYPE_SUPER (this_class);
02063 handle_type = CLASS_TO_HANDLE_TYPE (this_class);
02064
02065 if (super_class)
02066 {
02067 super_class = maybe_layout_super_class (super_class, this_class);
02068 if (!TYPE_NVIRTUALS (super_class))
02069 layout_class_methods (super_class);
02070 dtable_count = TYPE_NVIRTUALS (super_class);
02071 }
02072 else
02073 dtable_count = integer_zero_node;
02074
02075 TYPE_METHODS (handle_type) = nreverse (TYPE_METHODS (handle_type));
02076
02077 for (method_decl = TYPE_METHODS (handle_type);
02078 method_decl; method_decl = TREE_CHAIN (method_decl))
02079 dtable_count = layout_class_method (this_class, super_class,
02080 method_decl, dtable_count);
02081
02082 TYPE_NVIRTUALS (this_class) = dtable_count;
02083
02084 #ifdef JAVA_USE_HANDLES
02085 layout_type (handle_type);
02086 #endif
02087 }
02088
02089
02090
02091
02092
02093
02094
02095 tree
02096 layout_class_method (this_class, super_class, method_decl, dtable_count)
02097 tree this_class, super_class, method_decl, dtable_count;
02098 {
02099 tree method_name = DECL_NAME (method_decl);
02100
02101 TREE_PUBLIC (method_decl) = 1;
02102
02103
02104 SET_DECL_ASSEMBLER_NAME (method_decl,
02105 java_mangle_decl (&temporary_obstack,
02106 method_decl));
02107
02108
02109 if (! METHOD_ABSTRACT (method_decl)
02110 || (CLASS_INTERFACE (TYPE_NAME (this_class))
02111 && (DECL_CLINIT_P (method_decl))))
02112 make_decl_rtl (method_decl, NULL);
02113
02114 if (ID_INIT_P (method_name))
02115 {
02116 const char *p = IDENTIFIER_POINTER (DECL_NAME (TYPE_NAME (this_class)));
02117 const char *ptr;
02118 for (ptr = p; *ptr; )
02119 {
02120 if (*ptr++ == '.')
02121 p = ptr;
02122 }
02123 DECL_CONSTRUCTOR_P (method_decl) = 1;
02124 build_java_argument_signature (TREE_TYPE (method_decl));
02125 }
02126 else if (! METHOD_STATIC (method_decl) && !DECL_ARTIFICIAL (method_decl))
02127 {
02128 tree method_sig =
02129 build_java_argument_signature (TREE_TYPE (method_decl));
02130 tree super_method = lookup_argument_method (super_class, method_name,
02131 method_sig);
02132 if (super_method != NULL_TREE && ! METHOD_PRIVATE (super_method))
02133 {
02134 DECL_VINDEX (method_decl) = DECL_VINDEX (super_method);
02135 if (DECL_VINDEX (method_decl) == NULL_TREE
02136 && !CLASS_FROM_SOURCE_P (this_class))
02137 error_with_decl (method_decl,
02138 "non-static method '%s' overrides static method");
02139 }
02140 else if (! METHOD_FINAL (method_decl)
02141 && ! METHOD_PRIVATE (method_decl)
02142 && ! CLASS_FINAL (TYPE_NAME (this_class))
02143 && dtable_count)
02144 {
02145 DECL_VINDEX (method_decl) = dtable_count;
02146 dtable_count = fold (build (PLUS_EXPR, integer_type_node,
02147 dtable_count, integer_one_node));
02148 }
02149 }
02150
02151 return dtable_count;
02152 }
02153
02154 void
02155 register_class ()
02156 {
02157
02158
02159
02160 static tree end;
02161 tree node = TREE_OPERAND (build_class_ref (current_class), 0);
02162 tree current = copy_node (node);
02163
02164 XEXP (DECL_RTL (current), 0) = copy_rtx (XEXP (DECL_RTL(node), 0));
02165 if (!registered_class)
02166 registered_class = current;
02167 else
02168 TREE_CHAIN (end) = current;
02169
02170 end = current;
02171 }
02172
02173
02174
02175
02176
02177
02178
02179
02180
02181 void
02182 emit_register_classes ()
02183 {
02184
02185
02186
02187 if (SUPPORTS_WEAK && targetm.have_named_sections)
02188 {
02189 #ifdef JCR_SECTION_NAME
02190 tree t;
02191 named_section_flags (JCR_SECTION_NAME, SECTION_WRITE);
02192 assemble_align (POINTER_SIZE);
02193 for (t = registered_class; t; t = TREE_CHAIN (t))
02194 assemble_integer (XEXP (DECL_RTL (t), 0),
02195 POINTER_SIZE / BITS_PER_UNIT, POINTER_SIZE, 1);
02196 #else
02197 abort ();
02198 #endif
02199 }
02200 else
02201 {
02202 extern tree get_file_function_name PARAMS ((int));
02203 tree init_name = get_file_function_name ('I');
02204 tree init_type = build_function_type (void_type_node, end_params_node);
02205 tree init_decl;
02206 tree t;
02207
02208 init_decl = build_decl (FUNCTION_DECL, init_name, init_type);
02209 SET_DECL_ASSEMBLER_NAME (init_decl, init_name);
02210 TREE_STATIC (init_decl) = 1;
02211 current_function_decl = init_decl;
02212 DECL_RESULT (init_decl) = build_decl (RESULT_DECL, NULL_TREE,
02213 void_type_node);
02214
02215
02216
02217 TREE_PUBLIC (init_decl) = ! targetm.have_ctors_dtors;
02218
02219
02220 TREE_USED (init_decl) = 1;
02221
02222 pushlevel (0);
02223 make_decl_rtl (init_decl, NULL);
02224 init_function_start (init_decl, input_filename, 0);
02225 expand_function_start (init_decl, 0);
02226
02227
02228 current_function_cannot_inline
02229 = "static constructors and destructors cannot be inlined";
02230
02231 for ( t = registered_class; t; t = TREE_CHAIN (t))
02232 emit_library_call (registerClass_libfunc, 0, VOIDmode, 1,
02233 XEXP (DECL_RTL (t), 0), Pmode);
02234
02235 expand_function_end (input_filename, 0, 0);
02236 poplevel (1, 0, 1);
02237 rest_of_compilation (init_decl);
02238 current_function_decl = NULL_TREE;
02239
02240 if (targetm.have_ctors_dtors)
02241 (* targetm.asm_out.constructor) (XEXP (DECL_RTL (init_decl), 0),
02242 DEFAULT_INIT_PRIORITY);
02243 }
02244 }
02245
02246
02247
02248 tree
02249 build_method_symbols_entry (tree method)
02250 {
02251 tree clname, name, signature, method_symbol;
02252
02253 clname = build_utf8_ref (DECL_NAME (TYPE_NAME (DECL_CONTEXT (method))));
02254 name = build_utf8_ref (DECL_NAME (method));
02255 signature = build_java_signature (TREE_TYPE (method));
02256 signature = build_utf8_ref (unmangle_classname
02257 (IDENTIFIER_POINTER (signature),
02258 IDENTIFIER_LENGTH (signature)));
02259
02260 START_RECORD_CONSTRUCTOR (method_symbol, method_symbol_type);
02261 PUSH_FIELD_VALUE (method_symbol, "clname", clname);
02262 PUSH_FIELD_VALUE (method_symbol, "name", name);
02263 PUSH_FIELD_VALUE (method_symbol, "signature", signature);
02264 FINISH_RECORD_CONSTRUCTOR (method_symbol);
02265 TREE_CONSTANT (method_symbol) = 1;
02266
02267 return method_symbol;
02268 }
02269
02270
02271
02272 void
02273 emit_offset_symbol_table ()
02274 {
02275 tree method_list, method, table, list, null_symbol;
02276 tree otable_bound, otable_array_type;
02277 int index;
02278
02279
02280
02281 if (otable_methods == NULL_TREE)
02282 return;
02283
02284
02285 index = 0;
02286 method_list = otable_methods;
02287 list = NULL_TREE;
02288 while (method_list != NULL_TREE)
02289 {
02290 method = TREE_VALUE (method_list);
02291 list = tree_cons (NULL_TREE, build_method_symbols_entry (method), list);
02292 method_list = TREE_CHAIN (method_list);
02293 index++;
02294 }
02295
02296
02297 START_RECORD_CONSTRUCTOR (null_symbol, method_symbol_type);
02298 PUSH_FIELD_VALUE (null_symbol, "clname", null_pointer_node);
02299 PUSH_FIELD_VALUE (null_symbol, "name", null_pointer_node);
02300 PUSH_FIELD_VALUE (null_symbol, "signature", null_pointer_node);
02301 FINISH_RECORD_CONSTRUCTOR (null_symbol);
02302 TREE_CONSTANT (null_symbol) = 1;
02303 list = tree_cons (NULL_TREE, null_symbol, list);
02304
02305
02306 list = nreverse (list);
02307 table = build (CONSTRUCTOR, method_symbols_array_type, NULL_TREE, list);
02308
02309
02310 DECL_INITIAL (otable_syms_decl) = table;
02311 DECL_ARTIFICIAL (otable_syms_decl) = 1;
02312 DECL_IGNORED_P (otable_syms_decl) = 1;
02313 rest_of_decl_compilation (otable_syms_decl, NULL, 1, 0);
02314
02315
02316
02317
02318 otable_bound = build_index_type (build_int_2 (index, 0));
02319 otable_array_type = build_array_type (integer_type_node, otable_bound);
02320 otable_decl = build_decl (VAR_DECL, get_identifier ("otable"),
02321 otable_array_type);
02322 TREE_STATIC (otable_decl) = 1;
02323 TREE_READONLY (otable_decl) = 1;
02324 rest_of_decl_compilation (otable_decl, NULL, 1, 0);
02325 }
02326
02327 void
02328 init_class_processing ()
02329 {
02330 registerClass_libfunc = gen_rtx (SYMBOL_REF, Pmode, "_Jv_RegisterClass");
02331 registerResource_libfunc =
02332 gen_rtx (SYMBOL_REF, Pmode, "_Jv_RegisterResource");
02333 ggc_add_tree_root (class_roots, sizeof (class_roots) / sizeof (tree));
02334 fields_ident = get_identifier ("fields");
02335 info_ident = get_identifier ("info");
02336 ggc_add_rtx_root (®isterClass_libfunc, 1);
02337 gcc_obstack_init (&temporary_obstack);
02338 }