📄 class.c
字号:
{ obstack_grow (obstack, "t6JArray1Z", sizeof("t6JArray1Z")-1); append_gpp_mangled_type (obstack, TYPE_ARRAY_ELEMENT (type)); } else { char *class_name = IDENTIFIER_POINTER (DECL_NAME (TYPE_NAME (type))); append_gpp_mangled_classtype (obstack, class_name); } break; bad_type: default: fatal ("internal error - trying to mangle unknown type"); }}/* Build the mangled name of the `class' field. */static treemangle_class_field (class) tree class;{ tree name; obstack_grow (&temporary_obstack, "_CL_", 4); append_gpp_mangled_type (&temporary_obstack, class); obstack_1grow (&temporary_obstack, '\0'); name = get_identifier (obstack_base (&temporary_obstack)); obstack_free (&temporary_obstack, obstack_base (&temporary_obstack)); return name;}/* Build the mangled (assembly-level) name of the static field FIELD. */static treemangle_static_field (field) tree field;{ tree class = DECL_CONTEXT (field); tree name = DECL_NAME (field); int encoded_len;#if ! defined (NO_DOLLAR_IN_LABEL) || ! defined (NO_DOT_IN_LABEL) obstack_1grow (&temporary_obstack, '_');#else obstack_grow (&temporary_obstack, "__static_", 9);#endif append_gpp_mangled_type (&temporary_obstack, class); encoded_len = unicode_mangling_length (IDENTIFIER_POINTER (name), IDENTIFIER_LENGTH (name)); if (encoded_len > 0) { obstack_1grow (&temporary_obstack, 'U'); }#ifndef NO_DOLLAR_IN_LABEL obstack_1grow (&temporary_obstack, '$');#else /* NO_DOLLAR_IN_LABEL */#ifndef NO_DOT_IN_LABEL obstack_1grow (&temporary_obstack, '.');#else /* NO_DOT_IN_LABEL */ obstack_1grow (&temporary_obstack, '_');#endif /* NO_DOT_IN_LABEL */#endif /* NO_DOLLAR_IN_LABEL */ if (encoded_len > 0) { emit_unicode_mangled_name (&temporary_obstack, IDENTIFIER_POINTER (name), IDENTIFIER_LENGTH (name)); } else { obstack_grow (&temporary_obstack, IDENTIFIER_POINTER (name), IDENTIFIER_LENGTH (name)); } obstack_1grow (&temporary_obstack, '\0'); name = get_identifier (obstack_base (&temporary_obstack)); obstack_free (&temporary_obstack, obstack_base (&temporary_obstack)); return name;}/* Build a VAR_DECL for the dispatch table (vtable) for class TYPE. */treebuild_dtable_decl (type) tree type;{ tree name; obstack_grow (&temporary_obstack, "__vt_", 5); append_gpp_mangled_type (&temporary_obstack, type); obstack_1grow (&temporary_obstack, '\0'); name = get_identifier (obstack_base (&temporary_obstack)); obstack_free (&temporary_obstack, obstack_base (&temporary_obstack)); return build_decl (VAR_DECL, name, dtable_type);}/* Pre-pend the TYPE_FIELDS of THIS_CLASS with a dummy FIELD_DECL for the fields inherited from SUPER_CLASS. */voidpush_super_field (this_class, super_class) tree this_class, super_class;{ tree base_decl; push_obstacks (&permanent_obstack, &permanent_obstack); base_decl = build_decl (FIELD_DECL, NULL_TREE, super_class); pop_obstacks (); DECL_IGNORED_P (base_decl) = 1; TREE_CHAIN (base_decl) = TYPE_FIELDS (this_class); TYPE_FIELDS (this_class) = base_decl; DECL_SIZE (base_decl) = TYPE_SIZE (super_class);}/* Handle the different manners we may have to lay out a super class. */static treemaybe_layout_super_class (super_class, this_class) tree super_class; tree this_class;{ 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); } /* We might have to layout the class before its dependency on the super class gets resolved by java_complete_class */ else if (TREE_CODE (super_class) == POINTER_TYPE) { if (TREE_TYPE (super_class) != NULL_TREE) super_class = TREE_TYPE (super_class); else { super_class = do_resolve_class (super_class, NULL_TREE, this_class); if (!super_class) return NULL_TREE; /* FIXME, NULL_TREE not checked by caller. */ super_class = TREE_TYPE (super_class); } } if (!TYPE_SIZE (super_class)) safe_layout_class (super_class); return super_class;}voidlayout_class (this_class) tree this_class;{ tree super_class = CLASSTYPE_SUPER (this_class); tree field; if (super_class) { super_class = maybe_layout_super_class (super_class, this_class); if (TREE_CODE (TYPE_SIZE (super_class)) == ERROR_MARK) { TYPE_SIZE (this_class) = error_mark_node; return; } if (TYPE_SIZE (this_class) == NULL_TREE) push_super_field (this_class, super_class); } for (field = TYPE_FIELDS (this_class); field != NULL_TREE; field = TREE_CHAIN (field)) { if (FIELD_STATIC (field)) { /* Set DECL_ASSEMBLER_NAME to something suitably mangled. */ DECL_ASSEMBLER_NAME (field) = mangle_static_field (field); } } layout_type (this_class);}voidlayout_class_methods (this_class) tree this_class;{ tree method_decl, dtable_count; tree super_class, handle_type; if (TYPE_NVIRTUALS (this_class)) return; push_obstacks (&permanent_obstack, &permanent_obstack); super_class = CLASSTYPE_SUPER (this_class); handle_type = CLASS_TO_HANDLE_TYPE (this_class); if (super_class) { super_class = maybe_layout_super_class (super_class, this_class); if (!TYPE_NVIRTUALS (super_class)) layout_class_methods (super_class); dtable_count = TYPE_NVIRTUALS (super_class); } else dtable_count = integer_zero_node; TYPE_METHODS (handle_type) = nreverse (TYPE_METHODS (handle_type)); for (method_decl = TYPE_METHODS (handle_type); method_decl; method_decl = TREE_CHAIN (method_decl)) dtable_count = layout_class_method (this_class, super_class, method_decl, dtable_count); TYPE_NVIRTUALS (this_class) = dtable_count;#ifdef JAVA_USE_HANDLES layout_type (handle_type);#endif pop_obstacks ();}/* Lay METHOD_DECL out, returning a possibly new value of DTABLE_COUNT. */treelayout_class_method (this_class, super_class, method_decl, dtable_count) tree this_class, super_class, method_decl, dtable_count;{ char *ptr; char *asm_name; tree arg, arglist, t; int method_name_needs_escapes = 0; tree method_name = DECL_NAME (method_decl); int method_name_is_wfl = (TREE_CODE (method_name) == EXPR_WITH_FILE_LOCATION); if (method_name_is_wfl) method_name = java_get_real_method_name (method_decl); if (method_name != init_identifier_node && method_name != finit_identifier_node) { int encoded_len = unicode_mangling_length (IDENTIFIER_POINTER (method_name), IDENTIFIER_LENGTH (method_name)); if (encoded_len > 0) { method_name_needs_escapes = 1; emit_unicode_mangled_name (&temporary_obstack, IDENTIFIER_POINTER (method_name), IDENTIFIER_LENGTH (method_name)); } else { obstack_grow (&temporary_obstack, IDENTIFIER_POINTER (method_name), IDENTIFIER_LENGTH (method_name)); } } obstack_grow (&temporary_obstack, "__", 2); if (method_name == finit_identifier_node) obstack_grow (&temporary_obstack, "finit", 5); append_gpp_mangled_type (&temporary_obstack, this_class); TREE_PUBLIC (method_decl) = 1; t = TREE_TYPE (method_decl); arglist = TYPE_ARG_TYPES (t); if (TREE_CODE (t) == METHOD_TYPE) arglist = TREE_CHAIN (arglist); for (arg = arglist; arg != end_params_node; ) { tree a = arglist; tree argtype = TREE_VALUE (arg); int tindex = 1; if (TREE_CODE (argtype) == POINTER_TYPE) { /* This is O(N**2). Do we care? Cfr gcc/cp/method.c. */ while (a != arg && argtype != TREE_VALUE (a)) a = TREE_CHAIN (a), tindex++; } else a = arg; if (a != arg) { char buf[12]; int nrepeats = 0; do { arg = TREE_CHAIN (arg); nrepeats++; } while (arg != end_params_node && argtype == TREE_VALUE (arg)); if (nrepeats > 1) { obstack_1grow (&temporary_obstack, 'N'); sprintf (buf, "%d", nrepeats); obstack_grow (&temporary_obstack, buf, strlen (buf)); if (nrepeats > 9) obstack_1grow (&temporary_obstack, '_'); } else obstack_1grow (&temporary_obstack, 'T'); sprintf (buf, "%d", tindex); obstack_grow (&temporary_obstack, buf, strlen (buf)); if (tindex > 9) obstack_1grow (&temporary_obstack, '_'); } else { append_gpp_mangled_type (&temporary_obstack, argtype); arg = TREE_CHAIN (arg); } } if (method_name_needs_escapes) obstack_1grow (&temporary_obstack, 'U'); obstack_1grow (&temporary_obstack, '\0'); asm_name = obstack_finish (&temporary_obstack); DECL_ASSEMBLER_NAME (method_decl) = get_identifier (asm_name); /* We don't generate a RTL for the method if it's abstract, or if it's an interface method that isn't clinit. */ if (! METHOD_ABSTRACT (method_decl) || (CLASS_INTERFACE (TYPE_NAME (this_class)) && (IS_CLINIT (method_decl)))) make_function_rtl (method_decl); obstack_free (&temporary_obstack, asm_name); if (method_name == init_identifier_node) { char *p = IDENTIFIER_POINTER (DECL_NAME (TYPE_NAME (this_class))); for (ptr = p; *ptr; ) { if (*ptr++ == '.') p = ptr; } if (method_name_is_wfl) EXPR_WFL_NODE (DECL_NAME (method_decl)) = get_identifier (p); else DECL_NAME (method_decl) = get_identifier (p); DECL_CONSTRUCTOR_P (method_decl) = 1; build_java_argument_signature (TREE_TYPE (method_decl)); } else if (! METHOD_STATIC (method_decl) && !DECL_ARTIFICIAL (method_decl)) { tree method_sig = build_java_argument_signature (TREE_TYPE (method_decl)); tree super_method = lookup_argument_method (super_class, method_name, method_sig); if (super_method != NULL_TREE && ! METHOD_PRIVATE (super_method)) { DECL_VINDEX (method_decl) = DECL_VINDEX (super_method); if (DECL_VINDEX (method_decl) == NULL_TREE && !CLASS_FROM_SOURCE_P (this_class)) error_with_decl (method_decl, "non-static method '%s' overrides static method");#if 0 else if (TREE_TYPE (TREE_TYPE (method_decl)) != TREE_TYPE (TREE_TYPE (super_method))) { error_with_decl (method_decl, "Method `%s' redefined with different return type"); error_with_decl (super_method, "Overridden decl is here"); }#endif } else if (! METHOD_FINAL (method_decl) && ! METHOD_PRIVATE (method_decl) && ! CLASS_FINAL (TYPE_NAME (this_class)) && dtable_count) { DECL_VINDEX (method_decl) = dtable_count; dtable_count = build_int_2 (1+TREE_INT_CST_LOW (dtable_count), 0); } } return dtable_count;}static tree registered_class = NULL_TREE;voidregister_class (){ static tree end; tree node = TREE_OPERAND (build_class_ref (current_class), 0); tree current = copy_node (node); XEXP (DECL_RTL (current), 0) = copy_rtx (XEXP (DECL_RTL(node), 0)); if (!registered_class) registered_class = current; else TREE_CHAIN (end) = current; end = current;}/* Generate a function that gets called at start-up (static contructor) time, which calls registerClass for all the compiled classes. */voidemit_register_classes (){ extern tree get_file_function_name PROTO((int)); tree init_name = get_file_function_name ('I'); tree init_type = build_function_type (void_type_node, end_params_node); tree init_decl; tree t; start_sequence (); init_decl = build_decl (FUNCTION_DECL, init_name, init_type); DECL_ASSEMBLER_NAME (init_decl) = init_name; TREE_STATIC (init_decl) = 1; current_function_decl = init_decl; DECL_RESULT (init_decl) = build_decl(RESULT_DECL, NULL_TREE, void_type_node); /* DECL_EXTERNAL (init_decl) = 1;*/ TREE_PUBLIC (init_decl) = 1; pushlevel (0); make_function_rtl (init_decl); init_function_start (init_decl, input_filename, 0); expand_function_start (init_decl, 0); for ( t = registered_class; t; t = TREE_CHAIN (t)) emit_library_call (registerClass_libfunc, 0, VOIDmode, 1, XEXP (DECL_RTL (t), 0), Pmode); expand_function_end (input_filename, 0, 0); poplevel (1, 0, 1); { /* Force generation, even with -O3 or deeper. Gross hack. FIXME */ int saved_flag = flag_inline_functions; flag_inline_functions = 0; rest_of_compilation (init_decl); flag_inline_functions = saved_flag; } current_function_decl = NULL_TREE; assemble_constructor (IDENTIFIER_POINTER (init_name));}voidinit_class_processing (){ registerClass_libfunc = gen_rtx (SYMBOL_REF, Pmode, "_Jv_RegisterClass");}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -