📄 objc-act.c
字号:
found = 1; } /* We found some structures that are returned in registers instead of memory so output the necessary data. */ if (found) { for (i = 31; i >= 0; i--) if (!aggregate_in_mem[i]) break; printf ("#define OBJC_MAX_STRUCT_BY_VALUE %d\n\n", i); /* The first member of the structure is always 0 because we don't handle structures with 0 members */ printf ("static int struct_forward_array[] = {\n 0"); for (j = 1; j <= i; j++) printf (", %d", aggregate_in_mem[j]); printf ("\n};\n"); } exit (0);}boolobjc_init (void){#ifdef OBJCPLUS if (cxx_init () == false)#else if (c_objc_common_init () == false)#endif return false;#ifndef USE_MAPPED_LOCATION /* Force the line number back to 0; check_newline will have raised it to 1, which will make the builtin functions appear not to be built in. */ input_line = 0;#endif /* If gen_declaration desired, open the output file. */ if (flag_gen_declaration) { register char * const dumpname = concat (dump_base_name, ".decl", NULL); gen_declaration_file = fopen (dumpname, "w"); if (gen_declaration_file == 0) fatal_error ("can't open %s: %m", dumpname); free (dumpname); } if (flag_next_runtime) { TAG_GETCLASS = "objc_getClass"; TAG_GETMETACLASS = "objc_getMetaClass"; TAG_MSGSEND = "objc_msgSend"; TAG_MSGSENDSUPER = "objc_msgSendSuper"; TAG_MSGSEND_STRET = "objc_msgSend_stret"; TAG_MSGSENDSUPER_STRET = "objc_msgSendSuper_stret"; default_constant_string_class_name = "NSConstantString"; } else { TAG_GETCLASS = "objc_get_class"; TAG_GETMETACLASS = "objc_get_meta_class"; TAG_MSGSEND = "objc_msg_lookup"; TAG_MSGSENDSUPER = "objc_msg_lookup_super"; /* GNU runtime does not provide special functions to support structure-returning methods. */ default_constant_string_class_name = "NXConstantString"; flag_typed_selectors = 1; } init_objc (); if (print_struct_values) generate_struct_by_value_array (); return true;}voidobjc_finish_file (void){ mark_referenced_methods ();#ifdef OBJCPLUS /* We need to instantiate templates _before_ we emit ObjC metadata; if we do not, some metadata (such as selectors) may go missing. */ at_eof = 1; instantiate_pending_templates (0);#endif /* Finalize Objective-C runtime data. No need to generate tables and code if only checking syntax, or if generating a PCH file. */ if (!flag_syntax_only && !pch_file) finish_objc (); if (gen_declaration_file) fclose (gen_declaration_file);#ifdef OBJCPLUS cp_finish_file ();#endif}/* Return the first occurrence of a method declaration corresponding to sel_name in rproto_list. Search rproto_list recursively. If is_class is 0, search for instance methods, otherwise for class methods. */static treelookup_method_in_protocol_list (tree rproto_list, tree sel_name, int is_class){ tree rproto, p; tree fnd = 0; for (rproto = rproto_list; rproto; rproto = TREE_CHAIN (rproto)) { p = TREE_VALUE (rproto); if (TREE_CODE (p) == PROTOCOL_INTERFACE_TYPE) { if ((fnd = lookup_method (is_class ? PROTOCOL_CLS_METHODS (p) : PROTOCOL_NST_METHODS (p), sel_name))) ; else if (PROTOCOL_LIST (p)) fnd = lookup_method_in_protocol_list (PROTOCOL_LIST (p), sel_name, is_class); } else { ; /* An identifier...if we could not find a protocol. */ } if (fnd) return fnd; } return 0;}static treelookup_protocol_in_reflist (tree rproto_list, tree lproto){ tree rproto, p; /* Make sure the protocol is supported by the object on the rhs. */ if (TREE_CODE (lproto) == PROTOCOL_INTERFACE_TYPE) { tree fnd = 0; for (rproto = rproto_list; rproto; rproto = TREE_CHAIN (rproto)) { p = TREE_VALUE (rproto); if (TREE_CODE (p) == PROTOCOL_INTERFACE_TYPE) { if (lproto == p) fnd = lproto; else if (PROTOCOL_LIST (p)) fnd = lookup_protocol_in_reflist (PROTOCOL_LIST (p), lproto); } if (fnd) return fnd; } } else { ; /* An identifier...if we could not find a protocol. */ } return 0;}voidobjc_start_class_interface (tree class, tree super_class, tree protos){ objc_interface_context = objc_ivar_context = start_class (CLASS_INTERFACE_TYPE, class, super_class, protos); objc_public_flag = 0;}voidobjc_start_category_interface (tree class, tree categ, tree protos){ objc_interface_context = start_class (CATEGORY_INTERFACE_TYPE, class, categ, protos); objc_ivar_chain = continue_class (objc_interface_context);}voidobjc_start_protocol (tree name, tree protos){ objc_interface_context = start_protocol (PROTOCOL_INTERFACE_TYPE, name, protos);}voidobjc_continue_interface (void){ objc_ivar_chain = continue_class (objc_interface_context);}voidobjc_finish_interface (void){ finish_class (objc_interface_context); objc_interface_context = NULL_TREE;}voidobjc_start_class_implementation (tree class, tree super_class){ objc_implementation_context = objc_ivar_context = start_class (CLASS_IMPLEMENTATION_TYPE, class, super_class, NULL_TREE); objc_public_flag = 0;}voidobjc_start_category_implementation (tree class, tree categ){ objc_implementation_context = start_class (CATEGORY_IMPLEMENTATION_TYPE, class, categ, NULL_TREE); objc_ivar_chain = continue_class (objc_implementation_context);}voidobjc_continue_implementation (void){ objc_ivar_chain = continue_class (objc_implementation_context);}voidobjc_finish_implementation (void){#ifdef OBJCPLUS if (flag_objc_call_cxx_cdtors) objc_generate_cxx_cdtors ();#endif if (objc_implementation_context) { finish_class (objc_implementation_context); objc_ivar_chain = NULL_TREE; objc_implementation_context = NULL_TREE; } else warning (0, "%<@end%> must appear in an @implementation context");}voidobjc_set_visibility (int visibility){ objc_public_flag = visibility;}voidobjc_set_method_type (enum tree_code type){ objc_inherit_code = (type == PLUS_EXPR ? CLASS_METHOD_DECL : INSTANCE_METHOD_DECL);}treeobjc_build_method_signature (tree rettype, tree selector, tree optparms, bool ellipsis){ return build_method_decl (objc_inherit_code, rettype, selector, optparms, ellipsis);}voidobjc_add_method_declaration (tree decl){ if (!objc_interface_context) fatal_error ("method declaration not in @interface context"); objc_add_method (objc_interface_context, decl, objc_inherit_code == CLASS_METHOD_DECL);}voidobjc_start_method_definition (tree decl){ if (!objc_implementation_context) fatal_error ("method definition not in @implementation context"); objc_add_method (objc_implementation_context, decl, objc_inherit_code == CLASS_METHOD_DECL); start_method_def (decl);}voidobjc_add_instance_variable (tree decl){ (void) add_instance_variable (objc_ivar_context, objc_public_flag, decl);}/* Return 1 if IDENT is an ObjC/ObjC++ reserved keyword in the context of an '@'. */intobjc_is_reserved_word (tree ident){ unsigned char code = C_RID_CODE (ident); return (OBJC_IS_AT_KEYWORD (code)#ifdef OBJCPLUS || code == RID_CLASS || code == RID_PUBLIC || code == RID_PROTECTED || code == RID_PRIVATE || code == RID_TRY || code == RID_THROW || code == RID_CATCH#endif );}/* Return true if TYPE is 'id'. */static boolobjc_is_object_id (tree type){ return OBJC_TYPE_NAME (type) == objc_object_id;}static boolobjc_is_class_id (tree type){ return OBJC_TYPE_NAME (type) == objc_class_id;}/* Construct a C struct with same name as CLASS, a base struct with tag SUPER_NAME (if any), and FIELDS indicated. */static treeobjc_build_struct (tree class, tree fields, tree super_name){ tree name = CLASS_NAME (class); tree s = start_struct (RECORD_TYPE, name); tree super = (super_name ? xref_tag (RECORD_TYPE, super_name) : NULL_TREE); tree t, objc_info = NULL_TREE; if (super) { /* Prepend a packed variant of the base class into the layout. This is necessary to preserve ObjC ABI compatibility. */ tree base = build_decl (FIELD_DECL, NULL_TREE, super); tree field = TYPE_FIELDS (super); while (field && TREE_CHAIN (field) && TREE_CODE (TREE_CHAIN (field)) == FIELD_DECL) field = TREE_CHAIN (field); /* For ObjC ABI purposes, the "packed" size of a base class is the the sum of the offset and the size (in bits) of the last field in the class. */ DECL_SIZE (base) = (field && TREE_CODE (field) == FIELD_DECL ? size_binop (PLUS_EXPR, size_binop (PLUS_EXPR, size_binop (MULT_EXPR, convert (bitsizetype, DECL_FIELD_OFFSET (field)), bitsize_int (BITS_PER_UNIT)), DECL_FIELD_BIT_OFFSET (field)), DECL_SIZE (field)) : bitsize_zero_node); DECL_SIZE_UNIT (base) = size_binop (FLOOR_DIV_EXPR, convert (sizetype, DECL_SIZE (base)), size_int (BITS_PER_UNIT)); DECL_ARTIFICIAL (base) = 1; DECL_ALIGN (base) = 1; DECL_FIELD_CONTEXT (base) = s;#ifdef OBJCPLUS DECL_FIELD_IS_BASE (base) = 1; if (fields) TREE_NO_WARNING (fields) = 1; /* Suppress C++ ABI warnings -- we */#endif /* are following the ObjC ABI here. */ TREE_CHAIN (base) = fields; fields = base; } /* NB: Calling finish_struct() may cause type TYPE_LANG_SPECIFIC fields in all variants of this RECORD_TYPE to be clobbered, but it is therein that we store protocol conformance info (e.g., 'NSObject <MyProtocol>'). Hence, we must squirrel away the ObjC-specific information before calling finish_struct(), and then reinstate it afterwards. */ for (t = TYPE_NEXT_VARIANT (s); t; t = TYPE_NEXT_VARIANT (t)) objc_info = chainon (objc_info, build_tree_list (NULL_TREE, TYPE_OBJC_INFO (t))); /* Point the struct at its related Objective-C class. */ INIT_TYPE_OBJC_INFO (s); TYPE_OBJC_INTERFACE (s) = class; s = finish_struct (s, fields, NULL_TREE); for (t = TYPE_NEXT_VARIANT (s); t; t = TYPE_NEXT_VARIANT (t), objc_info = TREE_CHAIN (objc_info)) { TYPE_OBJC_INFO (t) = TREE_VALUE (objc_info); /* Replace the IDENTIFIER_NODE with an actual @interface. */ TYPE_OBJC_INTERFACE (t) = class; } /* Use TYPE_BINFO structures to point at the super class, if any. */ objc_xref_basetypes (s, super); /* Mark this struct as a class template. */ CLASS_STATIC_TEMPLATE (class) = s; return s;}/* Build a type differing from TYPE only in that TYPE_VOLATILE is set. Unlike tree.c:build_qualified_type(), preserve TYPE_LANG_SPECIFIC in the process. */static treeobjc_build_volatilized_type (tree type){ tree t; /* Check if we have not constructed the desired variant already. */ for (t = TYPE_MAIN_VARIANT (type); t; t = TYPE_NEXT_VARIANT (t)) { /* The type qualifiers must (obviously) match up. */ if (!TYPE_VOLATILE (t) || (TYPE_READONLY (t) != TYPE_READONLY (type)) || (TYPE_RESTRICT (t) != TYPE_RESTRICT (type))) continue; /* For pointer types, the pointees (and hence their TYPE_LANG_SPECIFIC info, if any) must match up. */ if (POINTER_TYPE_P (t) && (TREE_TYPE (t) != TREE_TYPE (type))) continue;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -