?? objc-act.c
字號:
tree type_decl = lookup_name (objc_id_id); tree type; if (type_decl && TREE_CODE (type_decl) == TYPE_DECL) { type = TREE_TYPE (type_decl); if (TYPE_MAIN_VARIANT (type) != id_type) warning ("Unexpected type for `id' (%s)", gen_declaration (type, errbuf)); } else fatal ("Undefined type `id', please import <objc/objc.h>"); /* This clause creates a new pointer type that is qualified with the protocol specification...this info is used later to do more elaborate type checking. */ if (protocols) { tree t, m = TYPE_MAIN_VARIANT (type); push_obstacks_nochange (); end_temporary_allocation (); t = copy_node (type); TYPE_BINFO (t) = make_tree_vec (2); pop_obstacks (); /* Add this type to the chain of variants of TYPE. */ TYPE_NEXT_VARIANT (t) = TYPE_NEXT_VARIANT (m); TYPE_NEXT_VARIANT (m) = t; /* Look up protocols...and install in lang specific list */ TYPE_PROTOCOL_LIST (t) = lookup_and_install_protocols (protocols); /* This forces a new pointer type to be created later (in build_pointer_type)...so that the new template we just created will actually be used...what a hack! */ if (TYPE_POINTER_TO (t)) TYPE_POINTER_TO (t) = NULL; type = t; } return type;}static treelookup_and_install_protocols (protocols) tree protocols;{ tree proto; tree prev = NULL; tree return_value = protocols; for (proto = protocols; proto; proto = TREE_CHAIN (proto)) { tree ident = TREE_VALUE (proto); tree p = lookup_protocol (ident); if (!p) { error ("Cannot find protocol declaration for `%s'", IDENTIFIER_POINTER (ident)); if (prev) TREE_CHAIN (prev) = TREE_CHAIN (proto); else return_value = TREE_CHAIN (proto); } else { /* Replace identifier with actual protocol node. */ TREE_VALUE (proto) = p; prev = proto; } } return return_value;}/* Create and push a decl for a built-in external variable or field NAME. CODE says which. TYPE is its data type. */static treecreate_builtin_decl (code, type, name) enum tree_code code; tree type; char *name;{ tree decl = build_decl (code, get_identifier (name), type); if (code == VAR_DECL) { TREE_STATIC (decl) = 1; make_decl_rtl (decl, 0, 1); pushdecl (decl); } DECL_ARTIFICIAL (decl) = 1; return decl;}/* Purpose: "play" parser, creating/installing representations of the declarations that are required by Objective-C. Model: type_spec--------->sc_spec (tree_list) (tree_list) | | | | identifier_node identifier_node */static voidsynth_module_prologue (){ tree temp_type; tree super_p; /* Defined in `objc.h' */ objc_object_id = get_identifier (TAG_OBJECT); objc_object_reference = xref_tag (RECORD_TYPE, objc_object_id); id_type = build_pointer_type (objc_object_reference); objc_id_id = get_identifier (TYPE_ID); objc_class_id = get_identifier (TAG_CLASS); objc_class_type = build_pointer_type (xref_tag (RECORD_TYPE, objc_class_id)); protocol_type = build_pointer_type (xref_tag (RECORD_TYPE, get_identifier (PROTOCOL_OBJECT_CLASS_NAME))); /* Declare type of selector-objects that represent an operation name. */#ifdef OBJC_INT_SELECTORS /* `unsigned int' */ selector_type = unsigned_type_node;#else /* `struct objc_selector *' */ selector_type = build_pointer_type (xref_tag (RECORD_TYPE, get_identifier (TAG_SELECTOR)));#endif /* not OBJC_INT_SELECTORS */ /* Forward declare type, or else the prototype for msgSendSuper will complain. */ super_p = build_pointer_type (xref_tag (RECORD_TYPE, get_identifier (TAG_SUPER))); /* id objc_msgSend (id, SEL, ...); */ temp_type = build_function_type (id_type, tree_cons (NULL_TREE, id_type, tree_cons (NULL_TREE, selector_type, NULL_TREE))); if (! flag_next_runtime) { umsg_decl = build_decl (FUNCTION_DECL, get_identifier (TAG_MSGSEND), temp_type); DECL_EXTERNAL (umsg_decl) = 1; TREE_PUBLIC (umsg_decl) = 1; DECL_INLINE (umsg_decl) = 1; DECL_ARTIFICIAL (umsg_decl) = 1; if (flag_traditional && TAG_MSGSEND[0] != '_') DECL_BUILT_IN_NONANSI (umsg_decl) = 1; make_decl_rtl (umsg_decl, NULL_PTR, 1); pushdecl (umsg_decl); } else umsg_decl = builtin_function (TAG_MSGSEND, temp_type, NOT_BUILT_IN, 0); /* id objc_msgSendSuper (struct objc_super *, SEL, ...); */ temp_type = build_function_type (id_type, tree_cons (NULL_TREE, super_p, tree_cons (NULL_TREE, selector_type, NULL_TREE))); umsg_super_decl = builtin_function (TAG_MSGSENDSUPER, temp_type, NOT_BUILT_IN, 0); /* id objc_getClass (const char *); */ temp_type = build_function_type (id_type, tree_cons (NULL_TREE, const_string_type_node, tree_cons (NULL_TREE, void_type_node, NULL_TREE))); objc_get_class_decl = builtin_function (TAG_GETCLASS, temp_type, NOT_BUILT_IN, 0); /* id objc_getMetaClass (const char *); */ objc_get_meta_class_decl = builtin_function (TAG_GETMETACLASS, temp_type, NOT_BUILT_IN, 0); /* static SEL _OBJC_SELECTOR_TABLE[]; */ if (! flag_next_runtime) { if (flag_typed_selectors) { /* Suppress outputting debug symbols, because dbxout_init hasn'r been called yet. */ enum debug_info_type save_write_symbols = write_symbols; write_symbols = NO_DEBUG; build_selector_template (); temp_type = build_array_type (objc_selector_template, NULL_TREE); write_symbols = save_write_symbols; } else temp_type = build_array_type (selector_type, NULL_TREE); layout_type (temp_type); UOBJC_SELECTOR_TABLE_decl = create_builtin_decl (VAR_DECL, temp_type, "_OBJC_SELECTOR_TABLE"); /* Avoid warning when not sending messages. */ TREE_USED (UOBJC_SELECTOR_TABLE_decl) = 1; } generate_forward_declaration_to_string_table (); /* Forward declare constant_string_id and constant_string_type. */ constant_string_id = get_identifier (STRING_OBJECT_CLASS_NAME); constant_string_type = xref_tag (RECORD_TYPE, constant_string_id);}/* Custom build_string which sets TREE_TYPE! */static treemy_build_string (len, str) int len; char *str;{ int wide_flag = 0; tree a_string = build_string (len, str); /* Some code from combine_strings, which is local to c-parse.y. */ if (TREE_TYPE (a_string) == int_array_type_node) wide_flag = 1; TREE_TYPE (a_string) = build_array_type (wide_flag ? integer_type_node : char_type_node, build_index_type (build_int_2 (len - 1, 0))); TREE_CONSTANT (a_string) = 1; /* Puts string in the readonly segment */ TREE_STATIC (a_string) = 1; return a_string;}/* Return a newly constructed OBJC_STRING_CST node whose value is the LEN characters at STR. The TREE_TYPE is not initialized. */treebuild_objc_string (len, str) int len; char *str;{ tree s = build_string (len, str); TREE_SET_CODE (s, OBJC_STRING_CST); return s;}/* Given a chain of OBJC_STRING_CST's, build a static instance of NXConstanString which points at the concatenation of those strings. We place the string object in the __string_objects section of the __OBJC segment. The Objective-C runtime will initialize the isa pointers of the string objects to point at the NXConstandString class object. */treebuild_objc_string_object (strings) tree strings;{ tree string, initlist, constructor; int length; if (!doing_objc_thang) objc_fatal (); if (lookup_interface (constant_string_id) == NULL_TREE) { error ("Cannot find interface declaration for `%s'", IDENTIFIER_POINTER (constant_string_id)); return error_mark_node; } add_class_reference (constant_string_id); /* Combine_strings will work for OBJC_STRING_CST's too. */ string = combine_strings (strings); TREE_SET_CODE (string, STRING_CST); length = TREE_STRING_LENGTH (string) - 1; if (! flag_next_runtime) { push_obstacks_nochange (); end_temporary_allocation (); if (! TREE_PERMANENT (strings)) string = my_build_string (length + 1, TREE_STRING_POINTER (string)); } /* & ((NXConstantString) {0, string, length}) */ initlist = build_tree_list (NULL_TREE, build_int_2 (0, 0)); initlist = tree_cons (NULL_TREE, copy_node (build_unary_op (ADDR_EXPR, string, 1)), initlist); initlist = tree_cons (NULL_TREE, build_int_2 (length, 0), initlist); constructor = build_constructor (constant_string_type, nreverse (initlist)); if (!flag_next_runtime) { constructor = objc_add_static_instance (constructor, constant_string_type); pop_obstacks (); } return (build_unary_op (ADDR_EXPR, constructor, 1));}/* Declare a static instance of CLASS_DECL initialized by CONSTRUCTOR. */static treeobjc_add_static_instance (constructor, class_decl) tree constructor, class_decl;{ static int num_static_inst; tree *chain, decl, decl_spec, decl_expr; char buf[256]; push_obstacks_nochange (); end_temporary_allocation (); /* Find the list of static instances for the CLASS_DECL. Create one if not found. */ for (chain = &objc_static_instances; *chain && TREE_VALUE (*chain) != class_decl; chain = &TREE_CHAIN (*chain)); if (!*chain) { *chain = tree_cons (NULL_TREE, class_decl, NULL_TREE); add_objc_string (TYPE_NAME (class_decl), class_names); } sprintf (buf, "_OBJC_INSTANCE_%d", num_static_inst++); decl = build_decl (VAR_DECL, get_identifier (buf), class_decl); DECL_COMMON (decl) = 1; TREE_STATIC (decl) = 1; DECL_ARTIFICIAL (decl) = 1; pushdecl_top_level (decl); rest_of_decl_compilation (decl, 0, 1, 0); /* Do this here so it gets output later instead of possibly inside something else we are writing. */ DECL_INITIAL (decl) = constructor; /* Add the DECL to the head of this CLASS' list. */ TREE_PURPOSE (*chain) = tree_cons (NULL_TREE, decl, TREE_PURPOSE (*chain)); pop_obstacks (); return decl;}/* Build a static constant CONSTRUCTOR with type TYPE and elements ELTS. */static treebuild_constructor (type, elts) tree type, elts;{ tree constructor = build (CONSTRUCTOR, type, NULL_TREE, elts); TREE_CONSTANT (constructor) = 1; TREE_STATIC (constructor) = 1; TREE_READONLY (constructor) = 1; return constructor;}/* Take care of defining and initializing _OBJC_SYMBOLS. *//* Predefine the following data type: struct _objc_symtab { long sel_ref_cnt; SEL *refs; short cls_def_cnt; short cat_def_cnt; void *defs[cls_def_cnt + cat_def_cnt]; }; */static voidbuild_objc_symtab_template (){ tree field_decl, field_decl_chain, index; objc_symtab_template = start_struct (RECORD_TYPE, get_identifier (UTAG_SYMTAB)); /* long sel_ref_cnt; */ field_decl = create_builtin_decl (FIELD_DECL, long_integer_type_node, "sel_ref_cnt"); field_decl_chain = field_decl; /* SEL *refs; */ field_decl = create_builtin_decl (FIELD_DECL, build_pointer_type (selector_type), "refs"); chainon (field_decl_chain, field_decl); /* short cls_def_cnt; */ field_decl = create_builtin_decl (FIELD_DECL, short_integer_type_node, "cls_def_cnt"); chainon (field_decl_chain, field_decl); /* short cat_def_cnt; */ field_decl = create_builtin_decl (FIELD_DECL, short_integer_type_node, "cat_def_cnt"); chainon (field_decl_chain, field_decl); /* void *defs[cls_def_cnt + cat_def_cnt]; */ index = build_index_type (build_int_2 (imp_count + cat_count - 1, imp_count == 0 && cat_count == 0 ? -1 : 0)); field_decl = create_builtin_decl (FIELD_DECL, build_array_type (ptr_type_node, index), "defs"); chainon (field_decl_chain, field_decl); finish_struct (objc_symtab_template, field_decl_chain, NULL_TREE);}/* Create the initial value for the `defs' field of _objc_symtab. This is a CONSTRUCTOR. */
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -