?? objc-act.c
字號(hào):
tree chain; if (section == class_names) chain = class_names_chain; else if (section == meth_var_names) chain = meth_var_names_chain; else if (section == meth_var_types) chain = meth_var_types_chain; else abort (); for (; chain != 0; chain = TREE_VALUE (chain)) if (TREE_VALUE (chain) == ident) return (TREE_PURPOSE (chain)); abort (); return NULL_TREE;}/* Output references to all statically allocated objects. Return the DECL for the array built. */static voidgenerate_static_references (){ tree decls = NULL_TREE, ident, decl_spec, expr_decl, expr = NULL_TREE; tree class_name, class, decl, initlist; tree cl_chain, in_chain, type; int num_inst, num_class; char buf[256]; if (flag_next_runtime) abort (); for (cl_chain = objc_static_instances, num_class = 0; cl_chain; cl_chain = TREE_CHAIN (cl_chain), num_class++) { for (num_inst = 0, in_chain = TREE_PURPOSE (cl_chain); in_chain; num_inst++, in_chain = TREE_CHAIN (in_chain)); sprintf (buf, "_OBJC_STATIC_INSTANCES_%d", num_class); ident = get_identifier (buf); expr_decl = build_nt (ARRAY_REF, ident, NULL_TREE); decl_spec = tree_cons (NULL_TREE, build_pointer_type (void_type_node), build_tree_list (NULL_TREE, ridpointers[(int) RID_STATIC])); decl = start_decl (expr_decl, decl_spec, 1, NULL_TREE, NULL_TREE); DECL_CONTEXT (decl) = 0; DECL_ARTIFICIAL (decl) = 1; /* Output {class_name, ...}. */ class = TREE_VALUE (cl_chain); class_name = get_objc_string_decl (TYPE_NAME (class), class_names); initlist = build_tree_list (NULL_TREE, build_unary_op (ADDR_EXPR, class_name, 1)); /* Output {..., instance, ...}. */ for (in_chain = TREE_PURPOSE (cl_chain); in_chain; in_chain = TREE_CHAIN (in_chain)) { expr = build_unary_op (ADDR_EXPR, TREE_VALUE (in_chain), 1); initlist = tree_cons (NULL_TREE, expr, initlist); } /* Output {..., NULL}. */ initlist = tree_cons (NULL_TREE, build_int_2 (0, 0), initlist); expr = build_constructor (TREE_TYPE (decl), nreverse (initlist)); finish_decl (decl, expr, NULL_TREE); TREE_USED (decl) = 1; type = build_array_type (build_pointer_type (void_type_node), 0); decl = build_decl (VAR_DECL, ident, type); make_decl_rtl (decl, 0, 1); TREE_USED (decl) = 1; decls = tree_cons (NULL_TREE, build_unary_op (ADDR_EXPR, decl, 1), decls); } decls = tree_cons (NULL_TREE, build_int_2 (0, 0), decls); ident = get_identifier ("_OBJC_STATIC_INSTANCES"); expr_decl = build_nt (ARRAY_REF, ident, NULL_TREE); decl_spec = tree_cons (NULL_TREE, build_pointer_type (void_type_node), build_tree_list (NULL_TREE, ridpointers[(int) RID_STATIC])); static_instances_decl = start_decl (expr_decl, decl_spec, 1, NULL_TREE, NULL_TREE); TREE_USED (static_instances_decl) = 1; DECL_CONTEXT (static_instances_decl) = 0; DECL_ARTIFICIAL (static_instances_decl) = 1; end_temporary_allocation (); expr = build_constructor (TREE_TYPE (static_instances_decl), nreverse (decls)); finish_decl (static_instances_decl, expr, NULL_TREE);}/* Output all strings. */static voidgenerate_strings (){ tree sc_spec, decl_specs, expr_decl; tree chain, string_expr; tree string, decl; for (chain = class_names_chain; chain; chain = TREE_CHAIN (chain)) { string = TREE_VALUE (chain); decl = TREE_PURPOSE (chain); sc_spec = tree_cons (NULL_TREE, ridpointers[(int) RID_STATIC], NULL_TREE); decl_specs = tree_cons (NULL_TREE, ridpointers[(int) RID_CHAR], sc_spec); expr_decl = build_nt (ARRAY_REF, DECL_NAME (decl), NULL_TREE); decl = start_decl (expr_decl, decl_specs, 1, NULL_TREE, NULL_TREE); end_temporary_allocation (); string_expr = my_build_string (IDENTIFIER_LENGTH (string) + 1, IDENTIFIER_POINTER (string)); finish_decl (decl, string_expr, NULL_TREE); } for (chain = meth_var_names_chain; chain; chain = TREE_CHAIN (chain)) { string = TREE_VALUE (chain); decl = TREE_PURPOSE (chain); sc_spec = tree_cons (NULL_TREE, ridpointers[(int) RID_STATIC], NULL_TREE); decl_specs = tree_cons (NULL_TREE, ridpointers[(int) RID_CHAR], sc_spec); expr_decl = build_nt (ARRAY_REF, DECL_NAME (decl), NULL_TREE); decl = start_decl (expr_decl, decl_specs, 1, NULL_TREE, NULL_TREE); string_expr = my_build_string (IDENTIFIER_LENGTH (string) + 1, IDENTIFIER_POINTER (string)); finish_decl (decl, string_expr, NULL_TREE); } for (chain = meth_var_types_chain; chain; chain = TREE_CHAIN (chain)) { string = TREE_VALUE (chain); decl = TREE_PURPOSE (chain); sc_spec = tree_cons (NULL_TREE, ridpointers[(int) RID_STATIC], NULL_TREE); decl_specs = tree_cons (NULL_TREE, ridpointers[(int) RID_CHAR], sc_spec); expr_decl = build_nt (ARRAY_REF, DECL_NAME (decl), NULL_TREE); decl = start_decl (expr_decl, decl_specs, 1, NULL_TREE, NULL_TREE); string_expr = my_build_string (IDENTIFIER_LENGTH (string) + 1, IDENTIFIER_POINTER (string)); finish_decl (decl, string_expr, NULL_TREE); }}static treebuild_selector_reference_decl (name) tree name;{ tree decl, ident; char buf[256]; static int idx = 0; sprintf (buf, "_OBJC_SELECTOR_REFERENCES_%d", idx++); push_obstacks_nochange (); end_temporary_allocation (); ident = get_identifier (buf); decl = build_decl (VAR_DECL, ident, selector_type); DECL_EXTERNAL (decl) = 1; TREE_PUBLIC (decl) = 1; TREE_USED (decl) = 1; TREE_READONLY (decl) = 1; DECL_ARTIFICIAL (decl) = 1; DECL_CONTEXT (decl) = 0; make_decl_rtl (decl, 0, 1); pushdecl_top_level (decl); pop_obstacks (); return decl;}/* Just a handy wrapper for add_objc_string. */static treebuild_selector (ident) tree ident;{ tree expr = add_objc_string (ident, meth_var_names); if (flag_typed_selectors) return expr; else return build_c_cast (selector_type, expr); /* cast! */}/* 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. */#if 0static treebuild_msg_pool_reference (offset) int offset;{ tree expr = build_int_2 (offset, 0); tree cast; expr = build_array_ref (UOBJC_STRINGS_decl, expr); expr = build_unary_op (ADDR_EXPR, expr, 0); cast = build_tree_list (build_tree_list (NULL_TREE, ridpointers[(int) RID_CHAR]), build1 (INDIRECT_REF, NULL_TREE, NULL_TREE)); TREE_TYPE (expr) = groktypename (cast); return expr;}static treeinit_selector (offset) int offset;{ tree expr = build_msg_pool_reference (offset); TREE_TYPE (expr) = selector_type; return expr;}#endifstatic voidbuild_selector_translation_table (){ tree sc_spec, decl_specs; tree chain, initlist = NULL_TREE; int offset = 0; tree decl = NULL_TREE, var_decl, name; /* The corresponding pop_obstacks is in finish_decl, called at the end of this function. */ if (! flag_next_runtime) push_obstacks_nochange (); for (chain = sel_ref_chain; chain; chain = TREE_CHAIN (chain)) { tree expr; expr = build_selector (TREE_VALUE (chain)); if (flag_next_runtime) { name = DECL_NAME (TREE_PURPOSE (chain)); sc_spec = build_tree_list (NULL_TREE, ridpointers[(int) RID_STATIC]); /* static SEL _OBJC_SELECTOR_REFERENCES_n = ...; */ decl_specs = tree_cons (NULL_TREE, selector_type, sc_spec); var_decl = name; /* 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, NULL_TREE, NULL_TREE); } /* add one for the '\0' character */ offset += IDENTIFIER_LENGTH (TREE_VALUE (chain)) + 1; if (flag_next_runtime) finish_decl (decl, expr, NULL_TREE); else { if (flag_typed_selectors) { tree eltlist = NULL_TREE; tree encoding = get_proto_encoding (TREE_PURPOSE (chain)); eltlist = tree_cons (NULL_TREE, expr, NULL_TREE); eltlist = tree_cons (NULL_TREE, encoding, eltlist); expr = build_constructor (objc_selector_template, nreverse (eltlist)); } initlist = tree_cons (NULL_TREE, expr, initlist); } } if (! flag_next_runtime) { /* Cause the variable and its initial value to be actually output. */ DECL_EXTERNAL (UOBJC_SELECTOR_TABLE_decl) = 0; TREE_STATIC (UOBJC_SELECTOR_TABLE_decl) = 1; /* NULL terminate the list and fix the decl for output. */ initlist = tree_cons (NULL_TREE, build_int_2 (0, 0), initlist); DECL_INITIAL (UOBJC_SELECTOR_TABLE_decl) = (tree) 1; initlist = build_constructor (TREE_TYPE (UOBJC_SELECTOR_TABLE_decl), nreverse (initlist)); finish_decl (UOBJC_SELECTOR_TABLE_decl, initlist, NULL_TREE); current_function_decl = NULL_TREE; }}static treeget_proto_encoding (proto) tree proto;{ tree encoding; if (proto) { tree tmp_decl; if (! METHOD_ENCODING (proto)) { tmp_decl = build_tmp_function_decl (); hack_method_prototype (proto, tmp_decl); encoding = encode_method_prototype (proto, tmp_decl); METHOD_ENCODING (proto) = encoding; } else encoding = METHOD_ENCODING (proto); return add_objc_string (encoding, meth_var_types); } else return build_int_2 (0, 0);}/* sel_ref_chain is a list whose "value" fields will be instances of identifier_node that represent the selector. */static treebuild_typed_selector_reference (ident, proto) tree ident, proto;{ tree *chain = &sel_ref_chain; tree expr; int index = 0; while (*chain) { if (TREE_PURPOSE (*chain) == ident && TREE_VALUE (*chain) == proto) goto return_at_index; index++; chain = &TREE_CHAIN (*chain); } *chain = perm_tree_cons (proto, ident, NULL_TREE); return_at_index: expr = build_unary_op (ADDR_EXPR, build_array_ref (UOBJC_SELECTOR_TABLE_decl, build_int_2 (index, 0)), 1); return build_c_cast (selector_type, expr);}static treebuild_selector_reference (ident) tree ident;{ tree *chain = &sel_ref_chain; tree expr; int index = 0; while (*chain) { if (TREE_VALUE (*chain) == ident) return (flag_next_runtime ? TREE_PURPOSE (*chain) : build_array_ref (UOBJC_SELECTOR_TABLE_decl, build_int_2 (index, 0))); index++; chain = &TREE_CHAIN (*chain); } expr = build_selector_reference_decl (ident); *chain = perm_tree_cons (expr, ident, NULL_TREE); return (flag_next_runtime ? expr : build_array_ref (UOBJC_SELECTOR_TABLE_decl, build_int_2 (index, 0)));}static treebuild_class_reference_decl (name) tree name;{ tree decl, ident; char buf[256]; static int idx = 0; sprintf (buf, "_OBJC_CLASS_REFERENCES_%d", idx++); push_obstacks_nochange (); end_temporary_allocation (); ident = get_identifier (buf); decl = build_decl (VAR_DECL, ident, objc_class_type); DECL_EXTERNAL (decl) = 1; TREE_PUBLIC (decl) = 1; TREE_USED (decl) = 1; TREE_READONLY (decl) = 1; DECL_CONTEXT (decl) = 0; DECL_ARTIFICIAL (decl) = 1; make_decl_rtl (decl, 0, 1); pushdecl_top_level (decl); pop_obstacks (); return decl;}/* Create a class reference, but don't create a variable to reference it. */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 (NULL_TREE, ident, NULL_TREE); } else cls_ref_chain = perm_tree_cons (NULL_TREE, ident, NULL_TREE);}/* Get a class reference, creating it if necessary. Also create the reference variable. */treeget_class_reference (ident) tree ident;{ if (flag_next_runtime) { tree *chain; tree decl; for (chain = &cls_ref_chain; *chain; chain = &TREE_CHAIN (*chain)) if (TREE_VALUE (*chain) == ident) { if (! TREE_PURPOSE (*chain)) TREE_PURPOSE
?? 快捷鍵說(shuō)明
復(fù)制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號(hào)
Ctrl + =
減小字號(hào)
Ctrl + -