?? objc-act.c
字號:
/* Implement classes and message passing for Objective C. Copyright (C) 1992, 93-95, 97, 1998 Free Software Foundation, Inc. Contributed by Steve Naroff.This file is part of GNU CC.GNU CC is free software; you can redistribute it and/or modifyit under the terms of the GNU General Public License as published bythe Free Software Foundation; either version 2, or (at your option)any later version.GNU CC is distributed in the hope that it will be useful,but WITHOUT ANY WARRANTY; without even the implied warranty ofMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See theGNU General Public License for more details.You should have received a copy of the GNU General Public Licensealong with GNU CC; see the file COPYING. If not, write tothe Free Software Foundation, 59 Temple Place - Suite 330,Boston, MA 02111-1307, USA. *//* Purpose: This module implements the Objective-C 4.0 language. compatibility issues (with the Stepstone translator): - does not recognize the following 3.3 constructs. @requires, @classes, @messages, = (...) - methods with variable arguments must conform to ANSI standard. - tagged structure definitions that appear in BOTH the interface and implementation are not allowed. - public/private: all instance variables are public within the context of the implementation...I consider this to be a bug in the translator. - statically allocated objects are not supported. the user will receive an error if this service is requested. code generation `options': - OBJC_INT_SELECTORS */#include "config.h"#include "system.h"#include "tree.h"#include "c-tree.h"#include "c-lex.h"#include "flags.h"#include "objc-act.h"#include "input.h"#include "except.h"#include "function.h"#include "output.h"#include "toplev.h"#if USE_CPPLIB#include "cpplib.h"extern cpp_reader parse_in;extern cpp_options parse_options;#endif/* This is the default way of generating a method name. *//* I am not sure it is really correct. Perhaps there's a danger that it will make name conflicts if method names contain underscores. -- rms. */#ifndef OBJC_GEN_METHOD_LABEL#define OBJC_GEN_METHOD_LABEL(BUF, IS_INST, CLASS_NAME, CAT_NAME, SEL_NAME, NUM) \ do { \ char *temp; \ sprintf ((BUF), "_%s_%s_%s_%s", \ ((IS_INST) ? "i" : "c"), \ (CLASS_NAME), \ ((CAT_NAME)? (CAT_NAME) : ""), \ (SEL_NAME)); \ for (temp = (BUF); *temp; temp++) \ if (*temp == ':') *temp = '_'; \ } while (0)#endif/* These need specifying. */#ifndef OBJC_FORWARDING_STACK_OFFSET#define OBJC_FORWARDING_STACK_OFFSET 0#endif#ifndef OBJC_FORWARDING_MIN_OFFSET#define OBJC_FORWARDING_MIN_OFFSET 0#endif/* Define the special tree codes that we use. *//* Table indexed by tree code giving a string containing a character classifying the tree code. Possibilities are t, d, s, c, r, <, 1 and 2. See objc-tree.def for details. */#define DEFTREECODE(SYM, NAME, TYPE, LENGTH) TYPE,char objc_tree_code_type[] = { 'x',#include "objc-tree.def"};#undef DEFTREECODE/* Table indexed by tree code giving number of expression operands beyond the fixed part of the node structure. Not used for types or decls. */#define DEFTREECODE(SYM, NAME, TYPE, LENGTH) LENGTH,int objc_tree_code_length[] = { 0,#include "objc-tree.def"};#undef DEFTREECODE/* Names of tree components. Used for printing out the tree and error messages. */#define DEFTREECODE(SYM, NAME, TYPE, LEN) NAME,char *objc_tree_code_name[] = { "@@dummy",#include "objc-tree.def"};#undef DEFTREECODE/* Set up for use of obstacks. */#include "obstack.h"#define obstack_chunk_alloc xmalloc#define obstack_chunk_free free/* This obstack is used to accumulate the encoding of a data type. */static struct obstack util_obstack;/* This points to the beginning of obstack contents, so we can free the whole contents. */char *util_firstobj;/* List of classes with list of their static instances. */static tree objc_static_instances = NULL_TREE;/* The declaration of the array administrating the static instances. */static tree static_instances_decl = NULL_TREE;/* for encode_method_def */#include "rtl.h"#include "c-parse.h"#define OBJC_VERSION (flag_next_runtime ? 5 : 8)#define PROTOCOL_VERSION 2#define OBJC_ENCODE_INLINE_DEFS 0#define OBJC_ENCODE_DONT_INLINE_DEFS 1/*** Private Interface (procedures) ***//* Used by compile_file. */static void init_objc PROTO((void));static void finish_objc PROTO((void));/* Code generation. */static void synth_module_prologue PROTO((void));static tree build_constructor PROTO((tree, tree));static char *build_module_descriptor PROTO((void));static tree init_module_descriptor PROTO((tree));static tree build_objc_method_call PROTO((int, tree, tree, tree, tree, tree));static void generate_strings PROTO((void));static tree get_proto_encoding PROTO((tree));static void build_selector_translation_table PROTO((void));static tree build_ivar_chain PROTO((tree, int));static tree objc_add_static_instance PROTO((tree, tree));static tree build_ivar_template PROTO((void));static tree build_method_template PROTO((void));static tree build_private_template PROTO((tree));static void build_class_template PROTO((void));static void build_selector_template PROTO((void));static void build_category_template PROTO((void));static tree build_super_template PROTO((void));static tree build_category_initializer PROTO((tree, tree, tree, tree, tree, tree));static tree build_protocol_initializer PROTO((tree, tree, tree, tree, tree));static void synth_forward_declarations PROTO((void));static void generate_ivar_lists PROTO((void));static void generate_dispatch_tables PROTO((void));static void generate_shared_structures PROTO((void));static tree generate_protocol_list PROTO((tree));static void generate_forward_declaration_to_string_table PROTO((void));static void build_protocol_reference PROTO((tree));#if 0static tree init_selector PROTO((int));#endifstatic tree build_keyword_selector PROTO((tree));static tree synth_id_with_class_suffix PROTO((char *, tree));static void generate_static_references PROTO((void));static int check_methods_accessible PROTO((tree, tree, int));static void encode_aggregate_within PROTO((tree, int, int, int, int));/* We handle printing method names ourselves for ObjC */extern char *(*decl_printable_name) ();/* Misc. bookkeeping */typedef struct hashed_entry *hash;typedef struct hashed_attribute *attr;struct hashed_attribute{ attr next; tree value;};struct hashed_entry{ attr list; hash next; tree key;};static void hash_init PROTO((void));static void hash_enter PROTO((hash *, tree));static hash hash_lookup PROTO((hash *, tree));static void hash_add_attr PROTO((hash, tree));static tree lookup_method PROTO((tree, tree));static tree lookup_instance_method_static PROTO((tree, tree));static tree lookup_class_method_static PROTO((tree, tree));static tree add_class PROTO((tree));static void add_category PROTO((tree, tree));enum string_section{ class_names, /* class, category, protocol, module names */ meth_var_names, /* method and variable names */ meth_var_types /* method and variable type descriptors */};static tree add_objc_string PROTO((tree, enum string_section));static tree get_objc_string_decl PROTO((tree, enum string_section));static tree build_objc_string_decl PROTO((tree, enum string_section));static tree build_selector_reference_decl PROTO((tree));/* Protocol additions. */static tree add_protocol PROTO((tree));static tree lookup_protocol PROTO((tree));static tree lookup_and_install_protocols PROTO((tree));/* Type encoding. */static void encode_type_qualifiers PROTO((tree));static void encode_pointer PROTO((tree, int, int));static void encode_array PROTO((tree, int, int));static void encode_aggregate PROTO((tree, int, int));static void encode_bitfield PROTO((int, int));static void encode_type PROTO((tree, int, int));static void encode_field_decl PROTO((tree, int, int));static void really_start_method PROTO((tree, tree));static int comp_method_with_proto PROTO((tree, tree));static int comp_proto_with_proto PROTO((tree, tree));static tree get_arg_type_list PROTO((tree, int, int));static tree expr_last PROTO((tree));/* Utilities for debugging and error diagnostics. */static void warn_with_method PROTO((char *, int, tree));static void error_with_ivar PROTO((char *, tree, tree));static char *gen_method_decl PROTO((tree, char *));static char *gen_declaration PROTO((tree, char *));static char *gen_declarator PROTO((tree, char *, char *));static int is_complex_decl PROTO((tree));static void adorn_decl PROTO((tree, char *));static void dump_interface PROTO((FILE *, tree));/* Everything else. */static void objc_fatal PROTO((void)) ATTRIBUTE_NORETURN;static tree define_decl PROTO((tree, tree));static tree lookup_method_in_protocol_list PROTO((tree, tree, int));static tree lookup_protocol_in_reflist PROTO((tree, tree));static tree create_builtin_decl PROTO((enum tree_code, tree, char *));static tree my_build_string PROTO((int, char *));static void build_objc_symtab_template PROTO((void));static tree init_def_list PROTO((tree));static tree init_objc_symtab PROTO((tree));static void forward_declare_categories PROTO((void));static void generate_objc_symtab_decl PROTO((void));static tree build_selector PROTO((tree));#if 0static tree build_msg_pool_reference PROTO((int));#endifstatic tree build_typed_selector_reference PROTO((tree, tree));static tree build_selector_reference PROTO((tree));static tree build_class_reference_decl PROTO((tree));static void add_class_reference PROTO((tree));static tree objc_copy_list PROTO((tree, tree *));static tree build_protocol_template PROTO((void));static tree build_descriptor_table_initializer PROTO((tree, tree));static tree build_method_prototype_list_template PROTO((tree, int));static tree build_method_prototype_template PROTO((void));static int forwarding_offset PROTO((tree));static tree encode_method_prototype PROTO((tree, tree));static tree generate_descriptor_table PROTO((tree, char *, int, tree, tree));static void generate_method_descriptors PROTO((tree));static tree build_tmp_function_decl PROTO((void));static void hack_method_prototype PROTO((tree, tree));static void generate_protocol_references PROTO((tree));static void generate_protocols PROTO((void));static void check_ivars PROTO((tree, tree));static tree build_ivar_list_template PROTO((tree, int));static tree build_method_list_template PROTO((tree, int));static tree build_ivar_list_initializer PROTO((tree, tree));static tree generate_ivars_list PROTO((tree, char *, int, tree));static tree build_dispatch_table_initializer PROTO((tree, tree));static tree generate_dispatch_table PROTO((tree, char *, int, tree));static tree build_shared_structure_initializer PROTO((tree, tree, tree, tree, tree, int, tree, tree, tree));static void generate_category PROTO((tree));static int is_objc_type_qualifier PROTO((tree));static tree adjust_type_for_id_default PROTO((tree));static tree check_duplicates PROTO((hash));static tree receiver_is_class_object PROTO((tree));static int check_methods PROTO((tree, tree, int));static int conforms_to_protocol PROTO((tree, tree));static void check_protocols PROTO((tree, char *, char *));static tree encode_method_def PROTO((tree));static void gen_declspecs PROTO((tree, char *, int));static void generate_classref_translation_entry PROTO((tree));static void handle_class_ref PROTO((tree));/*** Private Interface (data) ***//* Reserved tag definitions. */#define TYPE_ID "id"#define TAG_OBJECT "objc_object"#define TAG_CLASS "objc_class"#define TAG_SUPER "objc_super"#define TAG_SELECTOR "objc_selector"#define UTAG_CLASS "_objc_class"#define UTAG_IVAR "_objc_ivar"#define UTAG_IVAR_LIST "_objc_ivar_list"#define UTAG_METHOD "_objc_method"#define UTAG_METHOD_LIST "_objc_method_list"#define UTAG_CATEGORY "_objc_category"#define UTAG_MODULE "_objc_module"#define UTAG_STATICS "_objc_statics"#define UTAG_SYMTAB "_objc_symtab"#define UTAG_SUPER "_objc_super"#define UTAG_SELECTOR "_objc_selector"#define UTAG_PROTOCOL "_objc_protocol"#define UTAG_PROTOCOL_LIST "_objc_protocol_list"#define UTAG_METHOD_PROTOTYPE "_objc_method_prototype"#define UTAG_METHOD_PROTOTYPE_LIST "_objc__method_prototype_list"#define STRING_OBJECT_CLASS_NAME "NXConstantString"#define PROTOCOL_OBJECT_CLASS_NAME "Protocol"static char *TAG_GETCLASS;static char *TAG_GETMETACLASS;static char *TAG_MSGSEND;static char *TAG_MSGSENDSUPER;static char *TAG_EXECCLASS;/* Set by `continue_class' and checked by `is_public'. */#define TREE_STATIC_TEMPLATE(record_type) (TREE_PUBLIC (record_type))#define TYPED_OBJECT(type) \ (TREE_CODE (type) == RECORD_TYPE && TREE_STATIC_TEMPLATE (type))/* Some commonly used instances of "identifier_node". */static tree self_id, ucmd_id;static tree unused_list;static tree self_decl, umsg_decl, umsg_super_decl;static tree objc_get_class_decl, objc_get_meta_class_decl;static tree super_type, selector_type, id_type, objc_class_type;static tree instance_type, protocol_type;/* Type checking macros. */#define IS_ID(TYPE) \ (TYPE_MAIN_VARIANT (TYPE) == TYPE_MAIN_VARIANT (id_type))#define IS_PROTOCOL_QUALIFIED_ID(TYPE) \ (IS_ID (TYPE) && TYPE_PROTOCOL_LIST (TYPE))#define IS_SUPER(TYPE) \ (super_type && TYPE_MAIN_VARIANT (TYPE) == TYPE_MAIN_VARIANT (super_type))static tree class_chain = NULL_TREE;static tree alias_chain = NULL_TREE;static tree interface_chain = NULL_TREE;static tree protocol_chain = NULL_TREE;/* Chains to manage selectors that are referenced and defined in the module. */static tree cls_ref_chain = NULL_TREE; /* Classes referenced. */static tree sel_ref_chain = NULL_TREE; /* Selectors referenced. *//* Chains to manage uniquing of strings. */static tree class_names_chain = NULL_TREE;static tree meth_var_names_chain = NULL_TREE;static tree meth_var_types_chain = NULL_TREE;/* Hash tables to manage the global pool of method prototypes. */static hash *nst_method_hash_list = 0;static hash *cls_method_hash_list = 0;/* Backend data declarations. */static tree UOBJC_SYMBOLS_decl;static tree UOBJC_INSTANCE_VARIABLES_decl, UOBJC_CLASS_VARIABLES_decl;static tree UOBJC_INSTANCE_METHODS_decl, UOBJC_CLASS_METHODS_decl;static tree UOBJC_CLASS_decl, UOBJC_METACLASS_decl;static tree UOBJC_SELECTOR_TABLE_decl;static tree UOBJC_MODULES_decl;static tree UOBJC_STRINGS_decl;/* The following are used when compiling a class implementation. implementation_template will normally be an interface, however if none exists this will be equal to implementation_context...it is set in start_class. */static tree implementation_context = NULL_TREE;static tree implementation_template = NULL_TREE;struct imp_entry{ struct imp_entry *next; tree imp_context; tree imp_template; tree class_decl; /* _OBJC_CLASS_<my_name>; */ tree meta_decl; /* _OBJC_METACLASS_<my_name>; */};static void handle_impent PROTO((struct imp_entry *));static int imp_count = 0; /* `@implementation' */static int cat_count = 0; /* `@category' */static tree objc_class_template, objc_category_template, uprivate_record;static tree objc_protocol_template, objc_selector_template;
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -