?? objc-actions.c
字號:
*q = 0; } /* Make the constructor name from the name we have found. */ buf = (char *) xmalloc (sizeof (CONSTRUCTOR_NAME_FORMAT) + strlen (global_object_name)); sprintf (buf, CONSTRUCTOR_NAME_FORMAT, global_object_name); /* Declare void __objc_execClass (void*); */ void_list_node = build_tree_list (NULL_TREE, void_type_node); function_type = build_function_type (void_type_node, tree_cons (NULL_TREE, ptr_type_node, void_list_node)); function_decl = build_decl (FUNCTION_DECL, get_identifier ("__objc_execClass"), function_type); DECL_EXTERNAL (function_decl) = 1; TREE_PUBLIC (function_decl) = 1; pushdecl (function_decl); rest_of_decl_compilation (function_decl, 0, 0, 0); parms = build_tree_list (NULLT, build_unary_op (ADDR_EXPR, _OBJC_MODULES_decl, 0)); decelerator = build_function_call (function_decl, parms); /* void __objc_file_init () {objc_execClass(&L_OBJC_MODULES);} */ start_function (void_list_node, build_parse_node (CALL_EXPR, get_identifier (buf), /* This has the format of the output of get_parm_info. */ tree_cons (NULL_TREE, NULL_TREE, void_list_node), NULL_TREE), 0, 0);#if 0 /* This should be turned back on later for the systems where collect is not needed. */ /* Make these functions nonglobal so each file can use the same name. */ TREE_PUBLIC (current_function_decl) = 0;#endif TREE_USED (current_function_decl) = 1; store_parm_decls (); assemble_external (function_decl); c_expand_expr_stmt (decelerator); finish_function (0); /* Return the name of the constructor function. */ return buf; }#else /* NEXT_OBJC_RUNTIME */ return 0;#endif /* NEXT_OBJC_RUNTIME */}/* extern const char _OBJC_STRINGS[]; */static voidgenerate_forward_declaration_to_string_table (){ tree sc_spec, decl_specs, expr_decl; sc_spec = tree_cons (NULLT, ridpointers[(int) RID_EXTERN], NULLT); decl_specs = tree_cons (NULLT, ridpointers[(int) RID_CHAR], sc_spec); expr_decl = build_nt (ARRAY_REF, get_identifier ("_OBJC_STRINGS"), NULLT); _OBJC_STRINGS_decl = define_decl (expr_decl, decl_specs);}/* static char _OBJC_STRINGS[] = "..."; */static voidbuild_message_selector_pool (){ tree sc_spec, decl_specs, expr_decl; tree chain, string_expr; int goolengthtmp = 0, msg_pool_size = 0; char *string_goo; sc_spec = tree_cons (NULLT, ridpointers[(int) RID_STATIC], NULLT); decl_specs = tree_cons (NULLT, ridpointers[(int) RID_CHAR], sc_spec); expr_decl = build_nt (ARRAY_REF, get_identifier ("_OBJC_STRINGS"), NULLT); _OBJC_STRINGS_decl = start_decl (expr_decl, decl_specs, 1); for (chain = sel_refdef_chain; chain; chain = TREE_CHAIN (chain)) msg_pool_size += IDENTIFIER_LENGTH (TREE_VALUE (chain)) + 1; msg_pool_size++; string_goo = (char *)xmalloc (msg_pool_size); bzero (string_goo, msg_pool_size); for (chain = sel_refdef_chain; chain; chain = TREE_CHAIN (chain)) { strcpy (string_goo + goolengthtmp, IDENTIFIER_POINTER (TREE_VALUE (chain))); goolengthtmp += IDENTIFIER_LENGTH (TREE_VALUE (chain)) + 1; } string_expr = my_build_string (msg_pool_size, string_goo); finish_decl (_OBJC_STRINGS_decl, string_expr, NULLT);}/* * synthesize the following expr: (char *)&_OBJC_STRINGS[<offset>] * * the cast stops the compiler from issuing the following message: * * grok.m: warning: initialization of non-const * pointer from const * * grok.m: warning: initialization between incompatible pointer types */static treebuild_msg_pool_reference (offset) int offset;{ tree expr = build_int_2 (offset, 0); tree cast; expr = build_array_ref (_OBJC_STRINGS_decl, expr); expr = build_unary_op (ADDR_EXPR, expr, 0); cast = build_tree_list (build_tree_list (NULLT, ridpointers[(int) RID_CHAR]), build1 (INDIRECT_REF, NULLT, NULLT)); TREE_TYPE (expr) = groktypename (cast); return expr;}#ifndef OBJC_SELECTORS_WITHOUT_LABELSstatic treebuild_selector_reference (idx) int idx;{ tree ref, decl, name, ident; char buf[256]; struct obstack *save_current_obstack = current_obstack; struct obstack *save_rtl_obstack = rtl_obstack; sprintf (buf, "_OBJC_SELECTOR_REFERENCES_%d", idx); /* new stuff */ rtl_obstack = current_obstack = &permanent_obstack; ident = get_identifier (buf); if (IDENTIFIER_GLOBAL_VALUE (ident)) decl = IDENTIFIER_GLOBAL_VALUE (ident); /* set by pushdecl() */ else { decl = build_decl (VAR_DECL, ident, selector_type); DECL_EXTERNAL (decl) = 1; TREE_PUBLIC (decl) = 1; TREE_USED (decl) = 1; make_decl_rtl (decl, 0, 1); /* usually called from `rest_of_decl_compilation' */ pushdecl_top_level (decl); /* our `extended/custom' pushdecl in c-decl.c */ } current_obstack = save_current_obstack; rtl_obstack = save_rtl_obstack; return decl;}#endifstatic treeinit_selector (offset) int offset;{ tree expr = build_msg_pool_reference (offset); TREE_TYPE (expr) = selector_type; /* cast */ return expr;}static voidbuild_selector_translation_table (){ tree sc_spec, decl_specs, expr_decl; tree chain, initlist = NULLT; int offset = 0;#ifndef OBJC_SELECTORS_WITHOUT_LABELS tree decl, var_decl; int idx = 0; char buf[256];#else /* The corresponding pop_obstacks is in finish_decl, called at the end of this function. */ push_obstacks_nochange ();#endif for (chain = sel_ref_chain; chain; chain = TREE_CHAIN (chain)) { tree expr;#ifndef OBJC_SELECTORS_WITHOUT_LABELS sprintf (buf, "_OBJC_SELECTOR_REFERENCES_%d", idx); sc_spec = build_tree_list (NULLT, ridpointers[(int) RID_STATIC]); /* static SEL _OBJC_SELECTOR_REFERENCES_n = ...; */ decl_specs = tree_cons (NULLT, selector_type, sc_spec); var_decl = get_identifier (buf); /* the `decl' that is returned from start_decl is the one that we * forward declared in `build_selector_reference()' */ decl = start_decl (var_decl, decl_specs, 1); #endif expr = init_selector (offset); /* add one for the '\0' character */ offset += IDENTIFIER_LENGTH (TREE_VALUE (chain)) + 1;#ifndef OBJC_SELECTORS_WITHOUT_LABELS finish_decl (decl, expr, NULLT); idx++;#else initlist = tree_cons (NULLT, expr, initlist);#endif }#ifdef OBJC_SELECTORS_WITHOUT_LABELS /* Cause the variable and its initial value to be actually output. */ DECL_EXTERNAL (_OBJC_SELECTOR_REFERENCES_decl) = 0; TREE_STATIC (_OBJC_SELECTOR_REFERENCES_decl) = 1; /* NULL terminate the list and fix the decl for output. */ initlist = tree_cons (NULLT, build_int_2 (0, 0), initlist); DECL_INITIAL (_OBJC_SELECTOR_REFERENCES_decl) = (tree) 1; initlist = build_nt (CONSTRUCTOR, NULLT, nreverse (initlist)); finish_decl (_OBJC_SELECTOR_REFERENCES_decl, initlist, NULLT);#endif}static voidadd_class_reference (ident) tree ident;{ tree chain; if (chain = cls_ref_chain) { tree tail; do { if (ident == TREE_VALUE (chain)) return; tail = chain; chain = TREE_CHAIN (chain); } while (chain); /* append to the end of the list */ TREE_CHAIN (tail) = perm_tree_cons (NULLT, ident, NULLT); } else cls_ref_chain = perm_tree_cons (NULLT, ident, NULLT);}/* * sel_ref_chain is a list whose "value" fields will be instances of * identifier_node that represent the selector. */static intadd_selector_reference (ident) tree ident;{ tree chain; int index = 0; /* this adds it to sel_refdef_chain, the global pool of selectors */ add_objc_string (ident); if (chain = sel_ref_chain) { tree tail; do { if (ident == TREE_VALUE (chain)) return index; index++; tail = chain; chain = TREE_CHAIN (chain); } while (chain); /* append to the end of the list */ TREE_CHAIN (tail) = perm_tree_cons (NULLT, ident, NULLT); } else sel_ref_chain = perm_tree_cons (NULLT, ident, NULLT); max_selector_index++; return index;}/* * sel_refdef_chain is a list whose "value" fields will be instances of * identifier_node that represent the selector. It returns the offset of * the selector from the beginning of the _OBJC_STRINGS pool. This offset * is typically used by "init_selector ()" during code generation. */static intadd_objc_string (ident) tree ident;{ tree chain; int offset = 0; if (chain = sel_refdef_chain) { tree tail; do { if (ident == TREE_VALUE (chain)) return offset; /* add one for the '\0' character */ offset += IDENTIFIER_LENGTH (TREE_VALUE (chain)) + 1; tail = chain; chain = TREE_CHAIN (chain); } while (chain); /* append to the end of the list */ TREE_CHAIN (tail) = perm_tree_cons (NULLT, ident, NULLT); } else sel_refdef_chain = perm_tree_cons (NULLT, ident, NULLT); return offset;}treelookup_interface (ident) tree ident;{ tree chain; for (chain = interface_chain; chain; chain = TREE_CHAIN (chain)) { if (ident == CLASS_NAME (chain)) return chain; } return NULLT;}static treeobjc_copy_list (list, head) tree list; tree *head;{ tree newlist = NULL_TREE, tail = NULL_TREE; while (list) { tail = copy_node (list); /* the following statement fixes a bug when inheriting instance variables that are declared to be bitfields. finish_struct () expects to find the width of the bitfield in DECL_INITIAL (), which it nulls out after processing the decl of the super class...rather than change the way finish_struct () works (which is risky), I create the situation it expects...s.naroff (7/23/89). */ if (DECL_BIT_FIELD (tail) && DECL_INITIAL (tail) == 0) DECL_INITIAL (tail) = build_int_2 (DECL_FIELD_SIZE (tail), 0); newlist = chainon (newlist, tail); list = TREE_CHAIN (list); } *head = newlist; return tail;}/* used by: * build_private_template (), get_class_ivars (), and get_static_reference (). */static treebuild_ivar_chain (interface) tree interface;{ tree my_name, super_name, ivar_chain; my_name = CLASS_NAME (interface); super_name = CLASS_SUPER_NAME (interface); /* "leaf" ivars never get copied...there is no reason to. */ ivar_chain = CLASS_IVARS (interface); while (super_name) { tree op1; tree super_interface = lookup_interface (super_name); if (!super_interface) { /* fatal did not work with 2 args...should fix */ error ("Cannot find interface declaration for `%s', superclass of `%s'", IDENTIFIER_POINTER (super_name), IDENTIFIER_POINTER (my_name)); exit (34); } if (super_interface == interface) { fatal ("Circular inheritance in interface declaration for `%s'", IDENTIFIER_POINTER (super_name)); } interface = super_interface; my_name = CLASS_NAME (interface); super_name = CLASS_SUPER_NAME (interface); op1 = CLASS_IVARS (interface); if (op1) { tree head, tail = objc_copy_list (op1, &head); /* prepend super class ivars...make a copy of the list, we * do not want to alter the original. */ TREE_CHAIN (tail) = ivar_chain; ivar_chain = head; } } return ivar_chain;}/* * struct <classname> { * struct objc_class *isa; * ... * }; */static treebuild_private_template (class) tree class;{ tree ivar_context; if (CLASS_STATIC_TEMPLATE (class)) { _PRIVATE_record = CLASS_STATIC_TEMPLATE (class); ivar_context = TYPE_FIELDS (CLASS_STATIC_TEMPLATE (class)); } else { _PRIVATE_record = start_struct (RECORD_TYPE, CLASS_NAME (class)); ivar_context = build_ivar_chain (class); finish_struct (_PRIVATE_record, ivar_context); CLASS_STATIC_TEMPLATE (class) = _PRIVATE_record; /* mark this record as class template - for class type checking */ TREE_STATIC_TEMPLATE (_PRIVATE_record) = 1; } instance_type = groktypename ( build_tree_list (build_tree_list (NULLT, _PRIVATE_record), build1 (INDIRECT_REF, NULLT, NULLT))); return ivar_context;}
?? 快捷鍵說明
復(fù)制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -