?? objc-actions.c
字號:
/* Implement classes and message passing for Objective C. Copyright (C) 1992 Free Software Foundation, Inc. Author: 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, 675 Mass Ave, Cambridge, MA 02139, 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, OBJC_SELECTORS_WITHOUT_LABELS, NEXT_OBJC_RUNTIME */#include <stdio.h>#include "config.h"#include "tree.h"#include "c-tree.h"#include "c-lex.h"#include "flags.h"#include "objc-actions.h"#include "input.h"/* The GNU run time requires the selectors in a vector so it can store the operation numbers in them. */#ifndef NEXT_OBJC_RUNTIME#define OBJC_SELECTORS_WITHOUT_LABELS#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;/* for encode_method_def */#include "rtl.h"#define OBJC_VERSION 2#define NULLT (tree) 0#define OBJC_ENCODE_INLINE_DEFS 0#define OBJC_ENCODE_DONT_INLINE_DEFS 1/*** Private Interface (procedures) ***//* code generation */static void synth_module_prologue ();static char *build_module_descriptor ();static tree init_module_descriptor ();static void build_module_entry ();static tree build_objc_method_call ();static void build_message_selector_pool ();static void build_selector_translation_table ();static tree build_ivar_chain ();static tree build_ivar_template ();static tree build_method_template ();static tree build_private_template ();static void build_class_template ();static void build_category_template ();static tree build_super_template ();static void synth_forward_declarations ();static void generate_ivar_lists ();static void generate_dispatch_tables ();static void generate_shared_structures ();static tree build_msg_pool_reference ();static tree init_selector ();static tree build_keword_selector ();static tree synth_id_with_class_suffix ();/* misc. bookkeeping */typedef struct hashedEntry *hash;typedef struct hashedAttribute *attr;struct hashedAttribute { attr next; tree value;};struct hashedEntry { attr list; hash next; tree key;};static void hash_init ();static void hash_enter ();static hash hash_lookup ();static void hash_add_attr ();static tree lookup_method ();static tree lookup_instance_method_static ();static tree lookup_class_method_static ();static tree add_class ();static int add_selector_reference ();static void add_class_reference ();static int add_objc_string ();/* type encoding */static void encode_aggregate ();static void encode_bitfield ();static void encode_type ();static void encode_field_decl ();static void really_start_method ();static int comp_method_with_proto ();static int comp_proto_with_proto ();static tree get_arg_type_list ();static tree expr_last ();/* utilities for debugging and error diagnostics: */static void warn_with_method ();static void error_with_method ();static void error_with_ivar ();static char *gen_method_decl ();static char *gen_declaration ();static char *gen_declarator ();static int is_complex_decl ();static void adorn_decl ();static void dump_interfaces ();/*** 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 _TAG_CLASS "_objc_class"#define _TAG_IVAR "_objc_ivar"#define _TAG_IVAR_LIST "_objc_ivar_list"#define _TAG_METHOD "_objc_method"#define _TAG_METHOD_LIST "_objc_method_list"#define _TAG_CATEGORY "_objc_category"#define _TAG_MODULE "_objc_module"#define _TAG_SYMTAB "_objc_symtab"#define _TAG_SUPER "_objc_super"/* 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, _cmd_id;static tree self_decl, _msg_decl, _msgSuper_decl;static tree objc_getClass_decl, objc_getMetaClass_decl;static tree super_type, selector_type, id_type, class_type;static tree instance_type;static tree interface_chain = NULLT;/* chains to manage selectors that are referenced and defined in the module */static tree cls_ref_chain = NULLT; /* classes referenced */static tree sel_ref_chain = NULLT; /* selectors referenced */static tree sel_refdef_chain = NULLT; /* selectors references & defined */static int max_selector_index; /* total # of selector referenced *//* hash tables to manage the global pool of method prototypes */static hash *nst_method_hash_list = 0;static hash *cls_method_hash_list = 0;/* the following are used when compiling a class implementation. * * implementation_template will normally be an anInterface, however if * none exists this will be equal to implementation_context...it is * set in start_class. *//* backend data declarations */static tree _OBJC_SYMBOLS_decl;static tree _OBJC_INSTANCE_VARIABLES_decl, _OBJC_CLASS_VARIABLES_decl;static tree _OBJC_INSTANCE_METHODS_decl, _OBJC_CLASS_METHODS_decl;static tree _OBJC_CLASS_decl, _OBJC_METACLASS_decl;#ifdef OBJC_SELECTORS_WITHOUT_LABELSstatic tree _OBJC_SELECTOR_REFERENCES_decl;#endifstatic tree _OBJC_MODULES_decl;static tree _OBJC_STRINGS_decl;static tree implementation_context = NULLT, implementation_template = NULLT;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 struct imp_entry *imp_list = 0;static int imp_count = 0; /* `@implementation' */static int cat_count = 0; /* `@category' */static tree objc_class_template, objc_category_template, _PRIVATE_record;static tree _clsSuper_ref, __clsSuper_ref;static tree objc_method_template, objc_ivar_template;static tree objc_symtab_template, objc_module_template;static tree objc_super_template, objc_object_reference;static tree objc_object_id, objc_class_id;static tree _OBJC_SUPER_decl;static tree method_context = NULLT;static int method_slot = 0; /* used by start_method_def */#define BUFSIZE 512static char *errbuf; /* a buffer for error diagnostics */extern char *strcpy (), *strcat ();extern tree groktypename_in_parm_context ();extern struct obstack permanent_obstack, *current_obstack, *rtl_obstack;/* data imported from toplev.c */extern char *dump_base_name;/* 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;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); /* 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 (doing_objc_thang) init_objc ();}voidobjc_finish (){ if (doing_objc_thang) finish_objc (); /* Objective-C finalization */ if (gen_declaration_file) fclose (gen_declaration_file);}voidlang_finish (){}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 return c_decode_option (p); return 1;}static treedefine_decl (declarator, declspecs) tree declarator; tree declspecs;{ tree decl = start_decl (declarator, declspecs, 0); finish_decl (decl, NULLT, NULLT); return decl;}/* * rules for statically typed objects...called from `c-typeck.comptypes'. * * an assignment of the form `a' = `b' is permitted if: * * - `a' is of type "id". * - `a' and `b' are the same class type. * - `a' and `b' are of class types A and B such that B is a descendant * of A. */intmaybe_objc_comptypes (lhs, rhs) tree lhs, rhs;{ if (doing_objc_thang) return objc_comptypes (lhs, rhs); return 0;}intobjc_comptypes (lhs, rhs) tree lhs; tree rhs;{ /* `id' = `<class> *', `<class> *' = `id' */ if ((TYPE_NAME (lhs) == objc_object_id && TYPED_OBJECT (rhs)) || (TYPED_OBJECT (lhs) && TYPE_NAME (rhs) == objc_object_id)) 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), rname = TYPE_NAME (rhs); if (lname == rname) return 1; else { /* if the left hand side is a super class of the right hand side, allow it... */ tree rinter = lookup_interface (rname); while (rinter) { if (lname == CLASS_SUPER_NAME (rinter)) return 1; rinter = lookup_interface (CLASS_SUPER_NAME (rinter)); } return 0; } } else return 0;}/* Called from c-decl.c before all calls to rest_of_decl_compilation. */voidmaybe_objc_check_decl (decl) tree decl;{ if (doing_objc_thang) objc_check_decl (decl);}voidobjc_check_decl (decl) tree decl;
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -