?? objc-act.c
字號:
extern enum debug_info_type write_symbols;/* Data imported from toplev.c. */extern char *dump_base_name;/* Generate code for GNU or NeXT runtime environment. */#ifdef NEXT_OBJC_RUNTIMEint flag_next_runtime = 1;#elseint flag_next_runtime = 0;#endifint flag_typed_selectors;/* Open and close the file for outputting class declarations, if requested. */int flag_gen_declaration = 0;FILE *gen_declaration_file;/* Warn if multiple methods are seen for the same selector, but with different argument types. */int warn_selector = 0;/* Warn if methods required by a protocol are not implemented in the class adopting it. When turned off, methods inherited to that class are also considered implemented */int flag_warn_protocol = 1;/* Tells "encode_pointer/encode_aggregate" whether we are generating type descriptors for instance variables (as opposed to methods). Type descriptors for instance variables contain more information than methods (for static typing and embedded structures). This was added to support features being planned for dbkit2. */static int generating_instance_variables = 0;voidlang_init (){ /* The beginning of the file is a new line; check for #. With luck, we discover the real source file's name from that and put it in input_filename. */ ungetc (check_newline (), finput); /* The line number can be -1 if we had -g3 and the input file had a directive specifying line 0. But we want predefined functions to have a line number of 0, not -1. */ if (lineno == -1) lineno = 0; /* If gen_declaration desired, open the output file. */ if (flag_gen_declaration) { int dump_base_name_length = strlen (dump_base_name); register char *dumpname = (char *) xmalloc (dump_base_name_length + 7); strcpy (dumpname, dump_base_name); strcat (dumpname, ".decl"); gen_declaration_file = fopen (dumpname, "w"); if (gen_declaration_file == 0) pfatal_with_name (dumpname); } if (flag_next_runtime) { TAG_GETCLASS = "objc_getClass"; TAG_GETMETACLASS = "objc_getMetaClass"; TAG_MSGSEND = "objc_msgSend"; TAG_MSGSENDSUPER = "objc_msgSendSuper"; TAG_EXECCLASS = "__objc_execClass"; } else { TAG_GETCLASS = "objc_get_class"; TAG_GETMETACLASS = "objc_get_meta_class"; TAG_MSGSEND = "objc_msg_lookup"; TAG_MSGSENDSUPER = "objc_msg_lookup_super"; TAG_EXECCLASS = "__objc_exec_class"; flag_typed_selectors = 1; } if (doing_objc_thang) init_objc ();}static voidobjc_fatal (){ fatal ("Objective-C text in C source file");}voidfinish_file (){ if (doing_objc_thang) finish_objc (); /* Objective-C finalization */ if (gen_declaration_file) fclose (gen_declaration_file);}voidlang_finish (){}char *lang_identify (){ return "objc";}intlang_decode_option (p) char *p;{ if (!strcmp (p, "-lang-objc")) doing_objc_thang = 1; else if (!strcmp (p, "-gen-decls")) flag_gen_declaration = 1; else if (!strcmp (p, "-Wselector")) warn_selector = 1; else if (!strcmp (p, "-Wno-selector")) warn_selector = 0; else if (!strcmp (p, "-Wprotocol")) flag_warn_protocol = 1; else if (!strcmp (p, "-Wno-protocol")) flag_warn_protocol = 0; else if (!strcmp (p, "-fgnu-runtime")) flag_next_runtime = 0; else if (!strcmp (p, "-fno-next-runtime")) flag_next_runtime = 0; else if (!strcmp (p, "-fno-gnu-runtime")) flag_next_runtime = 1; else if (!strcmp (p, "-fnext-runtime")) flag_next_runtime = 1; else return c_decode_option (p); return 1;}static treedefine_decl (declarator, declspecs) tree declarator; tree declspecs;{ tree decl = start_decl (declarator, declspecs, 0, NULL_TREE, NULL_TREE); finish_decl (decl, NULL_TREE, NULL_TREE); return decl;}/* Return 1 if LHS and RHS are compatible types for assignment or various other operations. Return 0 if they are incompatible, and return -1 if we choose to not decide. When the operation is REFLEXIVE, check for compatibility in either direction. For statically typed objects, an assignment of the form `a' = `b' is permitted if: `a' is of type "id", `a' and `b' are the same class type, or `a' and `b' are of class types A and B such that B is a descendant of A. */intmaybe_objc_comptypes (lhs, rhs, reflexive) tree lhs, rhs; int reflexive;{ if (doing_objc_thang) return objc_comptypes (lhs, rhs, reflexive); return -1;}static treelookup_method_in_protocol_list (rproto_list, sel_name, class_meth) tree rproto_list; tree sel_name; int class_meth;{ 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 (class_meth ? 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, class_meth); } else ; /* An identifier...if we could not find a protocol. */ if (fnd) return fnd; } return 0;}static treelookup_protocol_in_reflist (rproto_list, lproto) tree rproto_list; tree lproto;{ tree rproto, p; /* Make sure the protocol is support 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;}/* Return 1 if LHS and RHS are compatible types for assignment or various other operations. Return 0 if they are incompatible, and return -1 if we choose to not decide. When the operation is REFLEXIVE, check for compatibility in either direction. */intobjc_comptypes (lhs, rhs, reflexive) tree lhs; tree rhs; int reflexive;{ /* New clause for protocols. */ if (TREE_CODE (lhs) == POINTER_TYPE && TREE_CODE (TREE_TYPE (lhs)) == RECORD_TYPE && TREE_CODE (rhs) == POINTER_TYPE && TREE_CODE (TREE_TYPE (rhs)) == RECORD_TYPE) { int lhs_is_proto = IS_PROTOCOL_QUALIFIED_ID (lhs); int rhs_is_proto = IS_PROTOCOL_QUALIFIED_ID (rhs); if (lhs_is_proto) { tree lproto, lproto_list = TYPE_PROTOCOL_LIST (lhs); tree rproto, rproto_list; tree p; if (rhs_is_proto) { rproto_list = TYPE_PROTOCOL_LIST (rhs); /* Make sure the protocol is supported by the object on the rhs. */ for (lproto = lproto_list; lproto; lproto = TREE_CHAIN (lproto)) { p = TREE_VALUE (lproto); rproto = lookup_protocol_in_reflist (rproto_list, p); if (!rproto) warning ("object does not conform to the `%s' protocol", IDENTIFIER_POINTER (PROTOCOL_NAME (p))); } } else if (TYPED_OBJECT (TREE_TYPE (rhs))) { tree rname = TYPE_NAME (TREE_TYPE (rhs)); tree rinter; /* Make sure the protocol is supported by the object on the rhs. */ for (lproto = lproto_list; lproto; lproto = TREE_CHAIN (lproto)) { p = TREE_VALUE (lproto); rproto = 0; rinter = lookup_interface (rname); while (rinter && !rproto) { tree cat; rproto_list = CLASS_PROTOCOL_LIST (rinter); rproto = lookup_protocol_in_reflist (rproto_list, p); /* Check for protocols adopted by categories. */ cat = CLASS_CATEGORY_LIST (rinter); while (cat && !rproto) { rproto_list = CLASS_PROTOCOL_LIST (cat); rproto = lookup_protocol_in_reflist (rproto_list, p); cat = CLASS_CATEGORY_LIST (cat); } rinter = lookup_interface (CLASS_SUPER_NAME (rinter)); } if (!rproto) warning ("class `%s' does not implement the `%s' protocol", IDENTIFIER_POINTER (TYPE_NAME (TREE_TYPE (rhs))), IDENTIFIER_POINTER (PROTOCOL_NAME (p))); } } /* May change...based on whether there was any mismatch */ return 1; } else if (rhs_is_proto) /* Lhs is not a protocol...warn if it is statically typed */ return (TYPED_OBJECT (TREE_TYPE (lhs)) != 0); else /* Defer to comptypes .*/ return -1; } else if (TREE_CODE (lhs) == RECORD_TYPE && TREE_CODE (rhs) == RECORD_TYPE) ; /* Fall thru. This is the case we have been handling all along */ else /* Defer to comptypes. */ return -1; /* `id' = `<class> *', `<class> *' = `id' */ if ((TYPE_NAME (lhs) == objc_object_id && TYPED_OBJECT (rhs)) || (TYPE_NAME (rhs) == objc_object_id && TYPED_OBJECT (lhs))) return 1; /* `id' = `Class', `Class' = `id' */ else if ((TYPE_NAME (lhs) == objc_object_id && TYPE_NAME (rhs) == objc_class_id) || (TYPE_NAME (lhs) == objc_class_id && TYPE_NAME (rhs) == objc_object_id)) return 1; /* `<class> *' = `<class> *' */ else if (TYPED_OBJECT (lhs) && TYPED_OBJECT (rhs)) { tree lname = TYPE_NAME (lhs); tree rname = TYPE_NAME (rhs); tree inter; if (lname == rname) return 1; /* If the left hand side is a super class of the right hand side, allow it. */ for (inter = lookup_interface (rname); inter; inter = lookup_interface (CLASS_SUPER_NAME (inter))) if (lname == CLASS_SUPER_NAME (inter)) return 1; /* Allow the reverse when reflexive. */ if (reflexive) for (inter = lookup_interface (lname); inter; inter = lookup_interface (CLASS_SUPER_NAME (inter))) if (rname == CLASS_SUPER_NAME (inter)) return 1; return 0; } else /* Defer to comptypes. */ return -1;}/* Called from c-decl.c before all calls to rest_of_decl_compilation. */voidobjc_check_decl (decl) tree decl;{ tree type = TREE_TYPE (decl); if (TREE_CODE (type) == RECORD_TYPE && TREE_STATIC_TEMPLATE (type) && type != constant_string_type) { error_with_decl (decl, "`%s' cannot be statically allocated"); fatal ("statically allocated objects not supported"); }}voidmaybe_objc_check_decl (decl) tree decl;{ if (doing_objc_thang) objc_check_decl (decl);}/* Implement static typing. At this point, we know we have an interface. */treeget_static_reference (interface, protocols) tree interface; tree protocols;{ tree type = xref_tag (RECORD_TYPE, interface); 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) = 0; type = t; } return type;}treeget_object_reference (protocols) tree protocols;{
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -