From af35aeb289edbb673349d8ee865140c9bf86263f Mon Sep 17 00:00:00 2001 From: Richard Stallman Date: Mon, 16 Mar 1992 04:38:38 +0000 Subject: [PATCH] *** empty log message *** From-SVN: r497 --- gcc/objc/objc-act.c | 351 +++++++++++++++++++------------------------- 1 file changed, 151 insertions(+), 200 deletions(-) diff --git a/gcc/objc/objc-act.c b/gcc/objc/objc-act.c index 3e525cf3994..558b06492b8 100644 --- a/gcc/objc/objc-act.c +++ b/gcc/objc/objc-act.c @@ -36,7 +36,7 @@ the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */ * * code generation `options': * - * - OBJC_INT_SELECTORS, OBJC_NONUNIQUE_SELECTORS + * - OBJC_INT_SELECTORS, OBJC_NONUNIQUE_SELECTORS, NEXT_OBJC_RUNTIME */ #include @@ -203,13 +203,12 @@ static void dump_interfaces (); /* some commonly used instances of "identifier_node". */ -static tree self_id, _cmd_id, _msg_id, _msgSuper_id; -static tree objc_getClass_id, objc_getMetaClass_id; +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 super_type, selector_type, id_type, class_type; static tree instance_type; static tree interface_chain = NULLT; @@ -267,9 +266,6 @@ static tree objc_symtab_template, objc_module_template; static tree objc_super_template, objc_object_reference; static tree objc_object_id, objc_class_id; -#ifdef OBJC_NONUNIQUE_SELECTORS -static tree _OBJC_SELECTOR_REFERENCES_id; -#endif static tree _OBJC_SUPER_decl; static tree method_context = NULLT; @@ -475,6 +471,27 @@ get_static_reference (interface) return xref_tag (RECORD_TYPE, CLASS_NAME (interface)); } +/* Create and push a decl for a built-in external variable or field NAME. + CODE says which. + TYPE is its data type. */ + +static tree +create_builtin_decl (code, type, name) + enum tree_code code; + char *name; + tree type; +{ + tree decl = build_decl (code, get_identifier (name), type); + if (code == VAR_DECL) + { + TREE_EXTERNAL (decl) = 1; + TREE_PUBLIC (decl) = 1; + make_decl_rtl (decl, 0, 1); + pushdecl (decl); + } + return decl; +} + /* * purpose: "play" parser, creating/installing representations * of the declarations that are required by Objective-C. @@ -490,138 +507,68 @@ get_static_reference (interface) static void synth_module_prologue () { - tree sc_spec, type_spec, decl_specs, expr_decl, parms, record; + tree expr_decl, temp_type; /* defined in `objc.h' */ objc_object_id = get_identifier (TAG_OBJECT); objc_object_reference = xref_tag (RECORD_TYPE, objc_object_id); - id_type = groktypename (build_tree_list ( - build_tree_list (NULLT, objc_object_reference), - build1 (INDIRECT_REF, NULLT, NULLT))); + id_type = build_pointer_type (objc_object_reference); objc_class_id = get_identifier (TAG_CLASS); - class_type = groktypename (build_tree_list - (build_tree_list - (NULLT, xref_tag (RECORD_TYPE, objc_class_id)), - build1 (INDIRECT_REF, NULLT, NULLT))); + class_type = build_pointer_type (xref_tag (RECORD_TYPE, objc_class_id)); -/* Declare SEL type before prototypes for objc_msgSend(), or else those - struct tags are considered local to the prototype and won't match the one - in . */ + /* Declare type of selector-objects that represent an operation name. */ #ifdef OBJC_INT_SELECTORS /* `unsigned int' */ - _selector_type = unsigned_type_node; + selector_type = unsigned_type_node; #else /* `struct objc_selector *' */ - _selector_type = groktypename (build_tree_list ( - build_tree_list (NULLT, - xref_tag (RECORD_TYPE, - get_identifier (TAG_SELECTOR))), - build1 (INDIRECT_REF, NULLT, NULLT))); + selector_type + = build_pointer_type (xref_tag (RECORD_TYPE, + get_identifier (TAG_SELECTOR))); #endif /* not OBJC_INT_SELECTORS */ - /* forward declare type...or else the prototype for `super' will bitch */ - groktypename (build_tree_list (build_tree_list (NULLT, - xref_tag (RECORD_TYPE, get_identifier (TAG_SUPER))), - build1 (INDIRECT_REF, NULLT, NULLT))); - - _msg_id = get_identifier ("objc_msgSend"); - _msgSuper_id = get_identifier ("objc_msgSendSuper"); - objc_getClass_id = get_identifier ("objc_getClass"); - objc_getMetaClass_id = get_identifier ("objc_getMetaClass"); - /* struct objc_object *objc_msgSend (id, SEL, ...); */ - pushlevel (0); - decl_specs = build_tree_list (NULLT, objc_object_reference); - push_parm_decl (build_tree_list (decl_specs, - build1 (INDIRECT_REF, NULLT, NULLT))); - -#ifdef OBJC_INT_SELECTORS - decl_specs = build_tree_list (NULLT, ridpointers[(int) RID_UNSIGNED]); - decl_specs = tree_cons (NULLT, ridpointers[(int) RID_INT], decl_specs); - expr_decl = NULLT; -#else - decl_specs = build_tree_list (NULLT, - xref_tag (RECORD_TYPE, - get_identifier (TAG_SELECTOR))); - expr_decl = build1 (INDIRECT_REF, NULLT, NULLT); -#endif /* not OBJC_INT_SELECTORS */ - push_parm_decl (build_tree_list (decl_specs, expr_decl)); - parms = get_parm_info (0); - poplevel (0, 0, 0); + temp_type + = build_function_type (id_type, + tree_cons (NULL_TREE, id_type, + tree_cons (NULLT, selector_type, NULLT))); - decl_specs = build_tree_list (NULLT, objc_object_reference); - expr_decl = build_nt (CALL_EXPR, _msg_id, parms, NULLT); - expr_decl = build1 (INDIRECT_REF, NULLT, expr_decl); + _msg_decl = builtin_function ("objc_msgSend", temp_type, NOT_BUILT_IN, 0); - _msg_decl = define_decl (expr_decl, decl_specs); + /* struct objc_object *objc_msgSendSuper (void *, SEL, ...); */ - /* struct objc_object *objc_msgSendSuper (struct objc_super *, SEL, ...); */ - pushlevel (0); - decl_specs = build_tree_list (NULLT, xref_tag (RECORD_TYPE, - get_identifier (TAG_SUPER))); - push_parm_decl (build_tree_list (decl_specs, - build1 (INDIRECT_REF, NULLT, NULLT))); + temp_type + = build_function_type (id_type, + tree_cons (NULL_TREE, ptr_type_node, + tree_cons (NULLT, selector_type, NULLT))); -#ifdef OBJC_INT_SELECTORS - decl_specs = build_tree_list (NULLT, ridpointers[(int) RID_UNSIGNED]); - decl_specs = tree_cons (NULLT, ridpointers[(int) RID_INT], decl_specs); - expr_decl = NULLT; -#else /* not OBJC_INT_SELECTORS */ - decl_specs = build_tree_list (NULLT, - xref_tag (RECORD_TYPE, - get_identifier (TAG_SELECTOR))); - expr_decl = build1 (INDIRECT_REF, NULLT, NULLT); -#endif /* not OBJC_INT_SELECTORS */ - - push_parm_decl (build_tree_list (decl_specs, expr_decl)); - parms = get_parm_info (0); - poplevel (0, 0, 0); - - decl_specs = build_tree_list (NULLT, objc_object_reference); - expr_decl = build_nt (CALL_EXPR, _msgSuper_id, parms, NULLT); - expr_decl = build1 (INDIRECT_REF, NULLT, expr_decl); - - _msgSuper_decl = define_decl (expr_decl, decl_specs); + _msgSuper_decl = builtin_function ("objc_msgSendSuper", + temp_type, NOT_BUILT_IN, 0); /* id objc_getClass (); */ - parms = build_tree_list (NULLT, NULLT); - expr_decl = build_nt (CALL_EXPR, objc_getClass_id, parms, NULLT); - expr_decl = build1 (INDIRECT_REF, NULLT, expr_decl); + + temp_type = build_function_type (id_type, NULLT); - objc_getClass_decl = define_decl (expr_decl, decl_specs); + objc_getClass_decl + = builtin_function ("objc_getClass", temp_type, NOT_BUILT_IN, 0); /* id objc_getMetaClass (); */ - parms = build_tree_list (NULLT, NULLT); - expr_decl = build_nt (CALL_EXPR, objc_getMetaClass_id, parms, NULLT); - expr_decl = build1 (INDIRECT_REF, NULLT, expr_decl); - objc_getMetaClass_decl = define_decl (expr_decl, decl_specs); - -#ifdef OBJC_NONUNIQUE_SELECTORS - _OBJC_SELECTOR_REFERENCES_id = get_identifier ("_OBJC_SELECTOR_REFERENCES"); + objc_getMetaClass_decl + = builtin_function ("objc_getMetaClass", temp_type, NOT_BUILT_IN, 0); /* extern SEL _OBJC_SELECTOR_REFERENCES[]; */ - sc_spec = tree_cons (NULLT, ridpointers[(int) RID_EXTERN], NULLT); - -#ifdef OBJC_INT_SELECTORS - decl_specs = tree_cons (NULLT, ridpointers[(int) RID_UNSIGNED], sc_spec); - decl_specs = tree_cons (NULLT, ridpointers[(int) RID_INT], decl_specs); - expr_decl = _OBJC_SELECTOR_REFERENCES_id; -#else /* not OBJC_INT_SELECTORS */ - decl_specs = build_tree_list (NULLT, - xref_tag (RECORD_TYPE, - get_identifier (TAG_SELECTOR))); - expr_decl = build1 (INDIRECT_REF, NULLT, _OBJC_SELECTOR_REFERENCES_id); -#endif /* not OBJC_INT_SELECTORS */ - expr_decl = build_nt (ARRAY_REF, expr_decl, NULLT); - _OBJC_SELECTOR_REFERENCES_decl = define_decl (expr_decl, decl_specs); +#ifdef OBJC_NONUNIQUE_SELECTORS + _OBJC_SELECTOR_REFERENCES_decl + = create_builtin_decl (VAR_DECL, build_array_type (selector_type, NULLT), + "_OBJC_SELECTOR_REFERENCES"); #endif } @@ -650,73 +597,68 @@ my_build_string (len, str) return aString; } + +/* Take care of defining and initializing _OBJC_SYMBOLS. */ + +/* Predefine the following data type: + + struct _objc_symtab { + long sel_ref_cnt; + SEL *refs; + short cls_def_cnt; + short cat_def_cnt; + void *defs[cls_def_cnt + cat_def_cnt]; + }; */ -/* - * struct objc_symtab { - * long sel_ref_cnt; - * char *refs; - * long cls_def_cnt; - * long cat_def_cnt; - * void *defs[cls_def_cnt + cat_def_cnt]; - * }; - */ static void build_objc_symtab_template () { - tree decl_specs, field_decl, field_decl_chain; + tree field_decl, field_decl_chain, index; objc_symtab_template = start_struct (RECORD_TYPE, get_identifier (_TAG_SYMTAB)); /* long sel_ref_cnt; */ - decl_specs = build_tree_list (NULLT, ridpointers[(int) RID_LONG]); - field_decl = get_identifier ("sel_ref_cnt"); - field_decl = grokfield (input_filename, lineno, field_decl, decl_specs, NULLT); + field_decl = create_builtin_decl (FIELD_DECL, + long_integer_type_node, + "sel_ref_cnt"); field_decl_chain = field_decl; -#ifdef OBJC_INT_SELECTORS - /* unsigned int *sel_ref; */ - decl_specs = build_tree_list (NULLT, ridpointers[(int) RID_UNSIGNED]); - decl_specs = tree_cons (NULLT, ridpointers[(int) RID_INT], decl_specs); - field_decl = build1 (INDIRECT_REF, NULLT, get_identifier ("refs")); -#else /* not OBJC_INT_SELECTORS */ - /* struct objc_selector **sel_ref; */ - decl_specs = build_tree_list (NULLT, - xref_tag (RECORD_TYPE, - get_identifier (TAG_SELECTOR))); - field_decl = build1 (INDIRECT_REF, NULLT, get_identifier ("refs")); - field_decl = build1 (INDIRECT_REF, NULLT, field_decl); -#endif /* not OBJC_INT_SELECTORS */ + /* SEL *refs; */ - field_decl = grokfield (input_filename, lineno, field_decl, decl_specs, NULLT); + field_decl = create_builtin_decl (FIELD_DECL, + build_pointer_type (selector_type), + "refs"); chainon (field_decl_chain, field_decl); /* short cls_def_cnt; */ - decl_specs = build_tree_list (NULLT, ridpointers[(int) RID_SHORT]); - field_decl = get_identifier ("cls_def_cnt"); - field_decl = grokfield (input_filename, lineno, field_decl, decl_specs, NULLT); + field_decl = create_builtin_decl (FIELD_DECL, + short_integer_type_node, + "cls_def_cnt"); chainon (field_decl_chain, field_decl); /* short cat_def_cnt; */ - decl_specs = build_tree_list (NULLT, ridpointers[(int) RID_SHORT]); - field_decl = get_identifier ("cat_def_cnt"); - field_decl = grokfield (input_filename, lineno, field_decl, decl_specs, NULLT); + field_decl = create_builtin_decl (FIELD_DECL, + short_integer_type_node, + "cat_def_cnt"); chainon (field_decl_chain, field_decl); /* void *defs[cls_def_cnt + cat_def_cnt]; */ - decl_specs = build_tree_list (NULLT, ridpointers[(int) RID_VOID]); - field_decl = build_nt (ARRAY_REF, get_identifier ("defs"), - build_int_2 (imp_count + cat_count, 0)); - field_decl = build1 (INDIRECT_REF, NULLT, field_decl); - field_decl = grokfield (input_filename, lineno, field_decl, decl_specs, NULLT); + index = build_index_type (build_int_2 (imp_count + cat_count - 1, 0)); + field_decl = create_builtin_decl (FIELD_DECL, + build_array_type (ptr_type_node, index), + "defs"); chainon (field_decl_chain, field_decl); finish_struct (objc_symtab_template, field_decl_chain); } +/* Create the initial value for the `defs' field of _objc_symtab. + This is a CONSTRUCTOR. */ + static tree init_def_list () { @@ -745,15 +687,8 @@ init_def_list () return build_nt (CONSTRUCTOR, NULLT, nreverse (initlist)); } -/* - * struct objc_symtab { - * long sel_ref_cnt; - * char *refs; - * long cls_def_cnt; - * long cat_def_cnt; - * void *defs[cls_def_cnt + cat_def_cnt]; - * }; - */ +/* Construct the initial value for all of _objc_symtab. */ + static tree init_objc_symtab () { @@ -793,6 +728,9 @@ init_objc_symtab () return build_nt (CONSTRUCTOR, NULLT, nreverse (initlist)); } +/* Push forward-declarations of all the categories + so that init_def_list can use them in a CONSTRUCTOR. */ + static void forward_declare_categories () { @@ -802,20 +740,19 @@ forward_declare_categories () { if (TREE_CODE (impent->imp_context) == CATEGORY_TYPE) { - tree sc_spec, decl_specs, decl; - - sc_spec = build_tree_list (NULLT, ridpointers[(int) RID_EXTERN]); - decl_specs = tree_cons (NULLT, objc_category_template, sc_spec); - + /* Set an invisible arg to synth_id_with_class_suffix. */ implementation_context = impent->imp_context; - impent->class_decl = define_decl ( - synth_id_with_class_suffix ("_OBJC_CATEGORY"), - decl_specs); + impent->class_decl + = create_builtin_decl (VAR_DECL, objc_category_template, + synth_id_with_class_suffix ("_OBJC_CATEGORY")); } } implementation_context = sav; } +/* Create the declaration of _OBJC_SYMBOLS, with type `strict _objc_symtab' + and initialized appropriately. */ + static void generate_objc_symtab_decl () { @@ -838,7 +775,7 @@ generate_objc_symtab_decl () finish_decl (_OBJC_SYMBOLS_decl, init_objc_symtab (), NULLT); } - + /* * tree_node------->tree_node----->... * | | @@ -1133,7 +1070,7 @@ build_selector_reference (idx) decl = IDENTIFIER_GLOBAL_VALUE (ident); /* set by pushdecl() */ else { - decl = build_decl (VAR_DECL, ident, _selector_type); + decl = build_decl (VAR_DECL, ident, selector_type); TREE_EXTERNAL (decl) = 1; TREE_PUBLIC (decl) = 1; TREE_USED (decl) = 1; @@ -1153,7 +1090,7 @@ init_selector (offset) int offset; { tree expr = build_msg_pool_reference (offset); - TREE_TYPE (expr) = _selector_type; /* cast */ + TREE_TYPE (expr) = selector_type; /* cast */ return expr; } @@ -1167,7 +1104,9 @@ build_selector_translation_table () tree decl, var_decl; int idx = 0; char buf[256]; -#else/ +#else + tree _OBJC_SELECTOR_REFERENCES_id + = get_identifier ("_OBJC_SELECTOR_REFERENCES"); sc_spec = tree_cons (NULLT, ridpointers[(int) RID_STATIC], NULLT); @@ -2506,19 +2445,14 @@ build_method_decl (code, ret_type, selector, add_args) #define METHOD_DEF 0 #define METHOD_REF 1 -/* - * used by `build_message_expr' and `comp_method_types'. - * - * add_args is a tree_list node the following info on a parameter list: - * - * The TREE_PURPOSE is a chain of decls of those parms. - * The TREE_VALUE is a list of structure, union and enum tags defined. - * The TREE_CHAIN is a list of argument types to go in the FUNCTION_TYPE. - * This tree_list node is later fed to `grokparms'. - * - * VOID_AT_END nonzero means append `void' to the end of the type-list. - * Zero means the parmlist ended with an ellipsis so don't append `void'. - */ +/* Used by `build_message_expr' and `comp_method_types'. + Return an argument list for method METH. + CONTEXT is either METHOD_DEF or METHOD_REF, + saying whether we are trying to define a method or call one. + SUPERFLAG says this is for a send to super; + this makes a difference for the NeXT calling sequence + in which the lookup and the method call are done together. */ + static tree get_arg_type_list (meth, context, superflag) tree meth; @@ -2527,10 +2461,14 @@ get_arg_type_list (meth, context, superflag) { tree arglist, akey; +#ifdef NEXT_OBJC_RUNTIME /* receiver type */ if (superflag) - arglist = build_tree_list (NULLT, super_type); + { + arglist = build_tree_list (NULLT, super_type); + } else +#endif { if (context == METHOD_DEF) arglist = build_tree_list (NULLT, TREE_TYPE (self_decl)); @@ -2539,7 +2477,7 @@ get_arg_type_list (meth, context, superflag) } /* selector type - will eventually change to `int' */ - chainon (arglist, build_tree_list (NULLT, _selector_type)); + chainon (arglist, build_tree_list (NULLT, selector_type)); /* build a list of argument types */ for (akey = METHOD_SEL_ARGS (meth); akey; akey = TREE_CHAIN (akey)) @@ -2616,11 +2554,11 @@ receiver_is_class_object (receiver) if (arg != 0 && TREE_CODE (arg) == TREE_LIST - && arg = TREE_VALUE (arg) + && (arg = TREE_VALUE (arg)) && TREE_CODE (arg) == NOP_EXPR - && arg = TREE_OPERAND (arg, 0) + && (arg = TREE_OPERAND (arg, 0)) && TREE_CODE (arg) == ADDR_EXPR - && arg = TREE_OPERAND (arg, 0) + && (arg = TREE_OPERAND (arg, 0)) && TREE_CODE (arg) == STRING_CST) /* finally, we have the class name */ return get_identifier (TREE_STRING_POINTER (arg)); @@ -4166,7 +4104,7 @@ really_start_method (method, parmlist) { tree sc_spec, ret_spec, ret_decl, decl_specs; tree method_decl, method_id; - char buf[256]; + char *buf; /* synth the storage class & assemble the return type */ sc_spec = tree_cons (NULLT, ridpointers[(int) RID_STATIC], NULLT); @@ -4174,28 +4112,41 @@ really_start_method (method, parmlist) decl_specs = chainon (sc_spec, ret_spec); if (TREE_CODE (implementation_context) == IMPLEMENTATION_TYPE) + { + /* Make sure this is big enough for any plausible method label. */ + buf = (char *) alloca (50 + + strlen (IDENTIFIER_POINTER (METHOD_SEL_NAME (method))) + + strlen (IDENTIFIER_POINTER (CLASS_NAME (implementation_context)))); #ifdef OBJC_GEN_METHOD_LABEL - OBJC_GEN_METHOD_LABEL (buf, - TREE_CODE (method) == INSTANCE_METHOD_DECL, - IDENTIFIER_POINTER (CLASS_NAME (implementation_context)), - NULL, - IDENTIFIER_POINTER (METHOD_SEL_NAME (method))); + OBJC_GEN_METHOD_LABEL (buf, + TREE_CODE (method) == INSTANCE_METHOD_DECL, + IDENTIFIER_POINTER (CLASS_NAME (implementation_context)), + NULL, + IDENTIFIER_POINTER (METHOD_SEL_NAME (method))); #else - sprintf (buf, "_%d_%s", ++method_slot, - IDENTIFIER_POINTER (CLASS_NAME (implementation_context))); + sprintf (buf, "_%d_%s", ++method_slot, + IDENTIFIER_POINTER (CLASS_NAME (implementation_context))); #endif + } else /* we have a category */ + { + /* Make sure this is big enough for any plausible method label. */ + buf = (char *) alloca (50 + + strlen (IDENTIFIER_POINTER (METHOD_SEL_NAME (method))) + + strlen (IDENTIFIER_POINTER (CLASS_SUPER_NAME (implementation_context))) + + strlen (IDENTIFIER_POINTER (CLASS_NAME (implementation_context)))); #ifdef OBJC_GEN_METHOD_LABEL - OBJC_GEN_METHOD_LABEL (buf, - TREE_CODE (method) == INSTANCE_METHOD_DECL, - IDENTIFIER_POINTER (CLASS_NAME (implementation_context)), - IDENTIFIER_POINTER (CLASS_SUPER_NAME (implementation_context)), - IDENTIFIER_POINTER (METHOD_SEL_NAME (method))); + OBJC_GEN_METHOD_LABEL (buf, + TREE_CODE (method) == INSTANCE_METHOD_DECL, + IDENTIFIER_POINTER (CLASS_NAME (implementation_context)), + IDENTIFIER_POINTER (CLASS_SUPER_NAME (implementation_context)), + IDENTIFIER_POINTER (METHOD_SEL_NAME (method))); #else - sprintf (buf, "_%d_%s_%s", ++method_slot, - IDENTIFIER_POINTER (CLASS_NAME (implementation_context)), - IDENTIFIER_POINTER (CLASS_SUPER_NAME (implementation_context))); + sprintf (buf, "_%d_%s_%s", ++method_slot, + IDENTIFIER_POINTER (CLASS_NAME (implementation_context)), + IDENTIFIER_POINTER (CLASS_SUPER_NAME (implementation_context))); #endif + } method_id = get_identifier (buf); -- 2.30.2