1 /* Implement classes and message passing for Objective C.
2 Copyright (C) 1992, 1993, 1994, 1995, 1997, 1998, 1999, 2000,
3 2001, 2002, 2003 Free Software Foundation, Inc.
4 Contributed by Steve Naroff.
6 This file is part of GCC.
8 GCC is free software; you can redistribute it and/or modify
9 it under the terms of the GNU General Public License as published by
10 the Free Software Foundation; either version 2, or (at your option)
13 GCC is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 GNU General Public License for more details.
18 You should have received a copy of the GNU General Public License
19 along with GCC; see the file COPYING. If not, write to
20 the Free Software Foundation, 59 Temple Place - Suite 330,
21 Boston, MA 02111-1307, USA. */
23 /* Purpose: This module implements the Objective-C 4.0 language.
25 compatibility issues (with the Stepstone translator):
27 - does not recognize the following 3.3 constructs.
28 @requires, @classes, @messages, = (...)
29 - methods with variable arguments must conform to ANSI standard.
30 - tagged structure definitions that appear in BOTH the interface
31 and implementation are not allowed.
32 - public/private: all instance variables are public within the
33 context of the implementation...I consider this to be a bug in
35 - statically allocated objects are not supported. the user will
36 receive an error if this service is requested.
38 code generation `options':
44 #include "coretypes.h"
62 #include "diagnostic.h"
64 /* This is the default way of generating a method name. */
65 /* I am not sure it is really correct.
66 Perhaps there's a danger that it will make name conflicts
67 if method names contain underscores. -- rms. */
68 #ifndef OBJC_GEN_METHOD_LABEL
69 #define OBJC_GEN_METHOD_LABEL(BUF, IS_INST, CLASS_NAME, CAT_NAME, SEL_NAME, NUM) \
72 sprintf ((BUF), "_%s_%s_%s_%s", \
73 ((IS_INST) ? "i" : "c"), \
75 ((CAT_NAME)? (CAT_NAME) : ""), \
77 for (temp = (BUF); *temp; temp++) \
78 if (*temp == ':') *temp = '_'; \
82 /* These need specifying. */
83 #ifndef OBJC_FORWARDING_STACK_OFFSET
84 #define OBJC_FORWARDING_STACK_OFFSET 0
87 #ifndef OBJC_FORWARDING_MIN_OFFSET
88 #define OBJC_FORWARDING_MIN_OFFSET 0
92 /* Set up for use of obstacks. */
96 /* This obstack is used to accumulate the encoding of a data type. */
97 static struct obstack util_obstack;
98 /* This points to the beginning of obstack contents,
99 so we can free the whole contents. */
102 /* for encode_method_def */
105 /* The version identifies which language generation and runtime
106 the module (file) was compiled for, and is recorded in the
107 module descriptor. */
109 #define OBJC_VERSION (flag_next_runtime ? 5 : 8)
110 #define PROTOCOL_VERSION 2
112 /* (Decide if these can ever be validly changed.) */
113 #define OBJC_ENCODE_INLINE_DEFS 0
114 #define OBJC_ENCODE_DONT_INLINE_DEFS 1
116 /*** Private Interface (procedures) ***/
118 /* Used by compile_file. */
120 static void init_objc PARAMS ((void));
121 static void finish_objc PARAMS ((void));
123 /* Code generation. */
125 static void synth_module_prologue PARAMS ((void));
126 static tree build_constructor PARAMS ((tree, tree));
127 static rtx build_module_descriptor PARAMS ((void));
128 static tree init_module_descriptor PARAMS ((tree));
129 static tree build_objc_method_call PARAMS ((int, tree, tree,
131 static void generate_strings PARAMS ((void));
132 static tree get_proto_encoding PARAMS ((tree));
133 static void build_selector_translation_table PARAMS ((void));
135 static tree objc_add_static_instance PARAMS ((tree, tree));
137 static tree build_ivar_template PARAMS ((void));
138 static tree build_method_template PARAMS ((void));
139 static tree build_private_template PARAMS ((tree));
140 static void build_class_template PARAMS ((void));
141 static void build_selector_template PARAMS ((void));
142 static void build_category_template PARAMS ((void));
143 static tree build_super_template PARAMS ((void));
144 static tree build_category_initializer PARAMS ((tree, tree, tree,
146 static tree build_protocol_initializer PARAMS ((tree, tree, tree,
149 static void synth_forward_declarations PARAMS ((void));
150 static void generate_ivar_lists PARAMS ((void));
151 static void generate_dispatch_tables PARAMS ((void));
152 static void generate_shared_structures PARAMS ((void));
153 static tree generate_protocol_list PARAMS ((tree));
154 static void generate_forward_declaration_to_string_table PARAMS ((void));
155 static void build_protocol_reference PARAMS ((tree));
157 static tree build_keyword_selector PARAMS ((tree));
158 static tree synth_id_with_class_suffix PARAMS ((const char *, tree));
160 static void generate_static_references PARAMS ((void));
161 static int check_methods_accessible PARAMS ((tree, tree,
163 static void encode_aggregate_within PARAMS ((tree, int, int,
165 static const char *objc_demangle PARAMS ((const char *));
166 static void objc_expand_function_end PARAMS ((void));
168 /* Hash tables to manage the global pool of method prototypes. */
170 hash *nst_method_hash_list = 0;
171 hash *cls_method_hash_list = 0;
173 static size_t hash_func PARAMS ((tree));
174 static void hash_init PARAMS ((void));
175 static void hash_enter PARAMS ((hash *, tree));
176 static hash hash_lookup PARAMS ((hash *, tree));
177 static void hash_add_attr PARAMS ((hash, tree));
178 static tree lookup_method PARAMS ((tree, tree));
179 static tree lookup_instance_method_static PARAMS ((tree, tree));
180 static tree lookup_class_method_static PARAMS ((tree, tree));
181 static tree add_class PARAMS ((tree));
182 static void add_category PARAMS ((tree, tree));
186 class_names, /* class, category, protocol, module names */
187 meth_var_names, /* method and variable names */
188 meth_var_types /* method and variable type descriptors */
191 static tree add_objc_string PARAMS ((tree,
192 enum string_section));
193 static tree get_objc_string_decl PARAMS ((tree,
194 enum string_section));
195 static tree build_objc_string_decl PARAMS ((enum string_section));
196 static tree build_selector_reference_decl PARAMS ((void));
198 /* Protocol additions. */
200 static tree add_protocol PARAMS ((tree));
201 static tree lookup_protocol PARAMS ((tree));
202 static void check_protocol_recursively PARAMS ((tree, tree));
203 static tree lookup_and_install_protocols PARAMS ((tree));
207 static void encode_type_qualifiers PARAMS ((tree));
208 static void encode_pointer PARAMS ((tree, int, int));
209 static void encode_array PARAMS ((tree, int, int));
210 static void encode_aggregate PARAMS ((tree, int, int));
211 static void encode_bitfield PARAMS ((int));
212 static void encode_type PARAMS ((tree, int, int));
213 static void encode_field_decl PARAMS ((tree, int, int));
215 static void really_start_method PARAMS ((tree, tree));
216 static int comp_method_with_proto PARAMS ((tree, tree));
217 static int comp_proto_with_proto PARAMS ((tree, tree));
218 static tree get_arg_type_list PARAMS ((tree, int, int));
219 static tree expr_last PARAMS ((tree));
221 /* Utilities for debugging and error diagnostics. */
223 static void warn_with_method PARAMS ((const char *, int, tree));
224 static void error_with_ivar PARAMS ((const char *, tree, tree));
225 static char *gen_method_decl PARAMS ((tree, char *));
226 static char *gen_declaration PARAMS ((tree, char *));
227 static void gen_declaration_1 PARAMS ((tree, char *));
228 static char *gen_declarator PARAMS ((tree, char *,
230 static int is_complex_decl PARAMS ((tree));
231 static void adorn_decl PARAMS ((tree, char *));
232 static void dump_interface PARAMS ((FILE *, tree));
234 /* Everything else. */
236 static tree define_decl PARAMS ((tree, tree));
237 static tree lookup_method_in_protocol_list PARAMS ((tree, tree, int));
238 static tree lookup_protocol_in_reflist PARAMS ((tree, tree));
239 static tree create_builtin_decl PARAMS ((enum tree_code,
240 tree, const char *));
241 static void setup_string_decl PARAMS ((void));
242 static void build_string_class_template PARAMS ((void));
243 static tree my_build_string PARAMS ((int, const char *));
244 static void build_objc_symtab_template PARAMS ((void));
245 static tree init_def_list PARAMS ((tree));
246 static tree init_objc_symtab PARAMS ((tree));
247 static void forward_declare_categories PARAMS ((void));
248 static void generate_objc_symtab_decl PARAMS ((void));
249 static tree build_selector PARAMS ((tree));
250 static tree build_typed_selector_reference PARAMS ((tree, tree));
251 static tree build_selector_reference PARAMS ((tree));
252 static tree build_class_reference_decl PARAMS ((void));
253 static void add_class_reference PARAMS ((tree));
254 static tree build_protocol_template PARAMS ((void));
255 static tree build_descriptor_table_initializer PARAMS ((tree, tree));
256 static tree build_method_prototype_list_template PARAMS ((tree, int));
257 static tree build_method_prototype_template PARAMS ((void));
258 static int forwarding_offset PARAMS ((tree));
259 static tree encode_method_prototype PARAMS ((tree, tree));
260 static tree generate_descriptor_table PARAMS ((tree, const char *,
262 static void generate_method_descriptors PARAMS ((tree));
263 static tree build_tmp_function_decl PARAMS ((void));
264 static void hack_method_prototype PARAMS ((tree, tree));
265 static void generate_protocol_references PARAMS ((tree));
266 static void generate_protocols PARAMS ((void));
267 static void check_ivars PARAMS ((tree, tree));
268 static tree build_ivar_list_template PARAMS ((tree, int));
269 static tree build_method_list_template PARAMS ((tree, int));
270 static tree build_ivar_list_initializer PARAMS ((tree, tree));
271 static tree generate_ivars_list PARAMS ((tree, const char *,
273 static tree build_dispatch_table_initializer PARAMS ((tree, tree));
274 static tree generate_dispatch_table PARAMS ((tree, const char *,
276 static tree build_shared_structure_initializer PARAMS ((tree, tree, tree, tree,
277 tree, int, tree, tree,
279 static void generate_category PARAMS ((tree));
280 static int is_objc_type_qualifier PARAMS ((tree));
281 static tree adjust_type_for_id_default PARAMS ((tree));
282 static tree check_duplicates PARAMS ((hash));
283 static tree receiver_is_class_object PARAMS ((tree));
284 static int check_methods PARAMS ((tree, tree, int));
285 static int conforms_to_protocol PARAMS ((tree, tree));
286 static void check_protocol PARAMS ((tree, const char *,
288 static void check_protocols PARAMS ((tree, const char *,
290 static tree encode_method_def PARAMS ((tree));
291 static void gen_declspecs PARAMS ((tree, char *, int));
292 static void generate_classref_translation_entry PARAMS ((tree));
293 static void handle_class_ref PARAMS ((tree));
294 static void generate_struct_by_value_array PARAMS ((void))
296 static void encode_complete_bitfield PARAMS ((int, tree, int));
298 /*** Private Interface (data) ***/
300 /* Reserved tag definitions. */
303 #define TAG_OBJECT "objc_object"
304 #define TAG_CLASS "objc_class"
305 #define TAG_SUPER "objc_super"
306 #define TAG_SELECTOR "objc_selector"
308 #define UTAG_CLASS "_objc_class"
309 #define UTAG_IVAR "_objc_ivar"
310 #define UTAG_IVAR_LIST "_objc_ivar_list"
311 #define UTAG_METHOD "_objc_method"
312 #define UTAG_METHOD_LIST "_objc_method_list"
313 #define UTAG_CATEGORY "_objc_category"
314 #define UTAG_MODULE "_objc_module"
315 #define UTAG_SYMTAB "_objc_symtab"
316 #define UTAG_SUPER "_objc_super"
317 #define UTAG_SELECTOR "_objc_selector"
319 #define UTAG_PROTOCOL "_objc_protocol"
320 #define UTAG_METHOD_PROTOTYPE "_objc_method_prototype"
321 #define UTAG_METHOD_PROTOTYPE_LIST "_objc__method_prototype_list"
323 /* Note that the string object global name is only needed for the
325 #define STRING_OBJECT_GLOBAL_NAME "_NSConstantStringClassReference"
327 #define PROTOCOL_OBJECT_CLASS_NAME "Protocol"
329 static const char *TAG_GETCLASS;
330 static const char *TAG_GETMETACLASS;
331 static const char *TAG_MSGSEND;
332 static const char *TAG_MSGSENDSUPER;
333 static const char *TAG_EXECCLASS;
334 static const char *default_constant_string_class_name;
336 /* The OCTI_... enumeration itself is in objc/objc-act.h. */
337 tree objc_global_trees[OCTI_MAX];
339 static void handle_impent PARAMS ((struct imp_entry *));
341 struct imp_entry *imp_list = 0;
342 int imp_count = 0; /* `@implementation' */
343 int cat_count = 0; /* `@category' */
345 static int method_slot = 0; /* Used by start_method_def, */
349 static char *errbuf; /* Buffer for error diagnostics */
351 /* Data imported from tree.c. */
353 extern enum debug_info_type write_symbols;
355 /* Data imported from toplev.c. */
357 extern const char *dump_base_name;
359 static int flag_typed_selectors;
361 FILE *gen_declaration_file;
363 /* Tells "encode_pointer/encode_aggregate" whether we are generating
364 type descriptors for instance variables (as opposed to methods).
365 Type descriptors for instance variables contain more information
366 than methods (for static typing and embedded structures). */
368 static int generating_instance_variables = 0;
370 /* Some platforms pass small structures through registers versus
371 through an invisible pointer. Determine at what size structure is
372 the transition point between the two possibilities. */
375 generate_struct_by_value_array ()
378 tree field_decl, field_decl_chain;
380 int aggregate_in_mem[32];
383 /* Presumably no platform passes 32 byte structures in a register. */
384 for (i = 1; i < 32; i++)
388 /* Create an unnamed struct that has `i' character components */
389 type = start_struct (RECORD_TYPE, NULL_TREE);
391 strcpy (buffer, "c1");
392 field_decl = create_builtin_decl (FIELD_DECL,
395 field_decl_chain = field_decl;
397 for (j = 1; j < i; j++)
399 sprintf (buffer, "c%d", j + 1);
400 field_decl = create_builtin_decl (FIELD_DECL,
403 chainon (field_decl_chain, field_decl);
405 finish_struct (type, field_decl_chain, NULL_TREE);
407 aggregate_in_mem[i] = aggregate_value_p (type);
408 if (!aggregate_in_mem[i])
412 /* We found some structures that are returned in registers instead of memory
413 so output the necessary data. */
416 for (i = 31; i >= 0; i--)
417 if (!aggregate_in_mem[i])
419 printf ("#define OBJC_MAX_STRUCT_BY_VALUE %d\n\n", i);
421 /* The first member of the structure is always 0 because we don't handle
422 structures with 0 members */
423 printf ("static int struct_forward_array[] = {\n 0");
425 for (j = 1; j <= i; j++)
426 printf (", %d", aggregate_in_mem[j]);
435 const char *filename;
437 filename = c_objc_common_init (filename);
438 if (filename == NULL)
441 /* Force the line number back to 0; check_newline will have
442 raised it to 1, which will make the builtin functions appear
443 not to be built in. */
446 /* If gen_declaration desired, open the output file. */
447 if (flag_gen_declaration)
449 register char * const dumpname = concat (dump_base_name, ".decl", NULL);
450 gen_declaration_file = fopen (dumpname, "w");
451 if (gen_declaration_file == 0)
452 fatal_io_error ("can't open %s", dumpname);
456 if (flag_next_runtime)
458 TAG_GETCLASS = "objc_getClass";
459 TAG_GETMETACLASS = "objc_getMetaClass";
460 TAG_MSGSEND = "objc_msgSend";
461 TAG_MSGSENDSUPER = "objc_msgSendSuper";
462 TAG_EXECCLASS = "__objc_execClass";
463 default_constant_string_class_name = "NSConstantString";
467 TAG_GETCLASS = "objc_get_class";
468 TAG_GETMETACLASS = "objc_get_meta_class";
469 TAG_MSGSEND = "objc_msg_lookup";
470 TAG_MSGSENDSUPER = "objc_msg_lookup_super";
471 TAG_EXECCLASS = "__objc_exec_class";
472 default_constant_string_class_name = "NXConstantString";
473 flag_typed_selectors = 1;
476 objc_ellipsis_node = make_node (ERROR_MARK);
480 if (print_struct_values)
481 generate_struct_by_value_array ();
489 c_objc_common_finish_file ();
491 /* Finalize Objective-C runtime data. No need to generate tables
492 and code if only checking syntax. */
493 if (!flag_syntax_only)
496 if (gen_declaration_file)
497 fclose (gen_declaration_file);
501 define_decl (declarator, declspecs)
505 tree decl = start_decl (declarator, declspecs, 0, NULL_TREE);
506 finish_decl (decl, NULL_TREE, NULL_TREE);
510 /* Return 1 if LHS and RHS are compatible types for assignment or
511 various other operations. Return 0 if they are incompatible, and
512 return -1 if we choose to not decide. When the operation is
513 REFLEXIVE, check for compatibility in either direction.
515 For statically typed objects, an assignment of the form `a' = `b'
519 `a' and `b' are the same class type, or
520 `a' and `b' are of class types A and B such that B is a descendant of A. */
523 lookup_method_in_protocol_list (rproto_list, sel_name, class_meth)
531 for (rproto = rproto_list; rproto; rproto = TREE_CHAIN (rproto))
533 p = TREE_VALUE (rproto);
535 if (TREE_CODE (p) == PROTOCOL_INTERFACE_TYPE)
537 if ((fnd = lookup_method (class_meth
538 ? PROTOCOL_CLS_METHODS (p)
539 : PROTOCOL_NST_METHODS (p), sel_name)))
541 else if (PROTOCOL_LIST (p))
542 fnd = lookup_method_in_protocol_list (PROTOCOL_LIST (p),
543 sel_name, class_meth);
547 ; /* An identifier...if we could not find a protocol. */
558 lookup_protocol_in_reflist (rproto_list, lproto)
564 /* Make sure the protocol is supported by the object on the rhs. */
565 if (TREE_CODE (lproto) == PROTOCOL_INTERFACE_TYPE)
568 for (rproto = rproto_list; rproto; rproto = TREE_CHAIN (rproto))
570 p = TREE_VALUE (rproto);
572 if (TREE_CODE (p) == PROTOCOL_INTERFACE_TYPE)
577 else if (PROTOCOL_LIST (p))
578 fnd = lookup_protocol_in_reflist (PROTOCOL_LIST (p), lproto);
587 ; /* An identifier...if we could not find a protocol. */
593 /* Return 1 if LHS and RHS are compatible types for assignment or
594 various other operations. Return 0 if they are incompatible, and
595 return -1 if we choose to not decide (because the types are really
596 just C types, not ObjC specific ones). When the operation is
597 REFLEXIVE (typically comparisons), check for compatibility in
598 either direction; when it's not (typically assignments), don't.
600 This function is called in two cases: when both lhs and rhs are
601 pointers to records (in which case we check protocols too), and
602 when both lhs and rhs are records (in which case we check class
605 Warnings about classes/protocols not implementing a protocol are
606 emitted here (multiple of those warnings might be emitted for a
607 single line!); generic warnings about incompatible assignments and
608 lacks of casts in comparisons are/must be emitted by the caller if
613 objc_comptypes (lhs, rhs, reflexive)
618 /* New clause for protocols. */
620 /* Here we manage the case of a POINTER_TYPE = POINTER_TYPE. We only
621 manage the ObjC ones, and leave the rest to the C code. */
622 if (TREE_CODE (lhs) == POINTER_TYPE
623 && TREE_CODE (TREE_TYPE (lhs)) == RECORD_TYPE
624 && TREE_CODE (rhs) == POINTER_TYPE
625 && TREE_CODE (TREE_TYPE (rhs)) == RECORD_TYPE)
627 int lhs_is_proto = IS_PROTOCOL_QUALIFIED_ID (lhs);
628 int rhs_is_proto = IS_PROTOCOL_QUALIFIED_ID (rhs);
632 tree lproto, lproto_list = TYPE_PROTOCOL_LIST (lhs);
633 tree rproto, rproto_list;
636 /* <Protocol> = <Protocol> */
639 rproto_list = TYPE_PROTOCOL_LIST (rhs);
643 /* An assignment between objects of type 'id
644 <Protocol>'; make sure the protocol on the lhs is
645 supported by the object on the rhs. */
646 for (lproto = lproto_list; lproto;
647 lproto = TREE_CHAIN (lproto))
649 p = TREE_VALUE (lproto);
650 rproto = lookup_protocol_in_reflist (rproto_list, p);
654 ("object does not conform to the `%s' protocol",
655 IDENTIFIER_POINTER (PROTOCOL_NAME (p)));
661 /* Obscure case - a comparison between two objects
662 of type 'id <Protocol>'. Check that either the
663 protocol on the lhs is supported by the object on
664 the rhs, or viceversa. */
666 /* Check if the protocol on the lhs is supported by the
667 object on the rhs. */
668 for (lproto = lproto_list; lproto;
669 lproto = TREE_CHAIN (lproto))
671 p = TREE_VALUE (lproto);
672 rproto = lookup_protocol_in_reflist (rproto_list, p);
676 /* Check failed - check if the protocol on the rhs
677 is supported by the object on the lhs. */
678 for (rproto = rproto_list; rproto;
679 rproto = TREE_CHAIN (rproto))
681 p = TREE_VALUE (rproto);
682 lproto = lookup_protocol_in_reflist (lproto_list,
687 /* This check failed too: incompatible */
697 /* <Protocol> = <class> * */
698 else if (TYPED_OBJECT (TREE_TYPE (rhs)))
700 tree rname = TYPE_NAME (TREE_TYPE (rhs));
703 /* Make sure the protocol is supported by the object on
705 for (lproto = lproto_list; lproto; lproto = TREE_CHAIN (lproto))
707 p = TREE_VALUE (lproto);
709 rinter = lookup_interface (rname);
711 while (rinter && !rproto)
715 rproto_list = CLASS_PROTOCOL_LIST (rinter);
716 rproto = lookup_protocol_in_reflist (rproto_list, p);
717 /* If the underlying ObjC class does not have
718 the protocol we're looking for, check for "one-off"
719 protocols (e.g., `NSObject<MyProt> *foo;') attached
723 rproto_list = TYPE_PROTOCOL_LIST (TREE_TYPE (rhs));
724 rproto = lookup_protocol_in_reflist (rproto_list, p);
727 /* Check for protocols adopted by categories. */
728 cat = CLASS_CATEGORY_LIST (rinter);
729 while (cat && !rproto)
731 rproto_list = CLASS_PROTOCOL_LIST (cat);
732 rproto = lookup_protocol_in_reflist (rproto_list, p);
733 cat = CLASS_CATEGORY_LIST (cat);
736 rinter = lookup_interface (CLASS_SUPER_NAME (rinter));
740 warning ("class `%s' does not implement the `%s' protocol",
741 IDENTIFIER_POINTER (TYPE_NAME (TREE_TYPE (rhs))),
742 IDENTIFIER_POINTER (PROTOCOL_NAME (p)));
746 /* <Protocol> = id */
747 else if (TYPE_NAME (TREE_TYPE (rhs)) == objc_object_id)
751 /* <Protocol> = Class */
752 else if (TYPE_NAME (TREE_TYPE (rhs)) == objc_class_id)
756 /* <Protocol> = ?? : let comptypes decide. */
759 else if (rhs_is_proto)
761 /* <class> * = <Protocol> */
762 if (TYPED_OBJECT (TREE_TYPE (lhs)))
766 tree rname = TYPE_NAME (TREE_TYPE (lhs));
768 tree rproto, rproto_list = TYPE_PROTOCOL_LIST (rhs);
770 /* Make sure the protocol is supported by the object on
772 for (rproto = rproto_list; rproto;
773 rproto = TREE_CHAIN (rproto))
775 tree p = TREE_VALUE (rproto);
777 rinter = lookup_interface (rname);
779 while (rinter && !lproto)
783 tree lproto_list = CLASS_PROTOCOL_LIST (rinter);
784 lproto = lookup_protocol_in_reflist (lproto_list, p);
785 /* If the underlying ObjC class does not
786 have the protocol we're looking for,
787 check for "one-off" protocols (e.g.,
788 `NSObject<MyProt> *foo;') attached to the
792 lproto_list = TYPE_PROTOCOL_LIST
794 lproto = lookup_protocol_in_reflist
798 /* Check for protocols adopted by categories. */
799 cat = CLASS_CATEGORY_LIST (rinter);
800 while (cat && !lproto)
802 lproto_list = CLASS_PROTOCOL_LIST (cat);
803 lproto = lookup_protocol_in_reflist (lproto_list,
805 cat = CLASS_CATEGORY_LIST (cat);
808 rinter = lookup_interface (CLASS_SUPER_NAME
813 warning ("class `%s' does not implement the `%s' protocol",
814 IDENTIFIER_POINTER (TYPE_NAME
816 IDENTIFIER_POINTER (PROTOCOL_NAME (p)));
823 /* id = <Protocol> */
824 else if (TYPE_NAME (TREE_TYPE (lhs)) == objc_object_id)
828 /* Class = <Protocol> */
829 else if (TYPE_NAME (TREE_TYPE (lhs)) == objc_class_id)
833 /* ??? = <Protocol> : let comptypes decide */
841 /* Attention: we shouldn't defer to comptypes here. One bad
842 side effect would be that we might loose the REFLEXIVE
845 lhs = TREE_TYPE (lhs);
846 rhs = TREE_TYPE (rhs);
850 if (TREE_CODE (lhs) != RECORD_TYPE || TREE_CODE (rhs) != RECORD_TYPE)
852 /* Nothing to do with ObjC - let immediately comptypes take
853 responsibility for checking. */
857 /* `id' = `<class> *' `<class> *' = `id': always allow it.
859 'Object *o = [[Object alloc] init]; falls
860 in the case <class> * = `id'.
862 if ((TYPE_NAME (lhs) == objc_object_id && TYPED_OBJECT (rhs))
863 || (TYPE_NAME (rhs) == objc_object_id && TYPED_OBJECT (lhs)))
866 /* `id' = `Class', `Class' = `id' */
868 else if ((TYPE_NAME (lhs) == objc_object_id
869 && TYPE_NAME (rhs) == objc_class_id)
870 || (TYPE_NAME (lhs) == objc_class_id
871 && TYPE_NAME (rhs) == objc_object_id))
874 /* `<class> *' = `<class> *' */
876 else if (TYPED_OBJECT (lhs) && TYPED_OBJECT (rhs))
878 tree lname = TYPE_NAME (lhs);
879 tree rname = TYPE_NAME (rhs);
885 /* If the left hand side is a super class of the right hand side,
887 for (inter = lookup_interface (rname); inter;
888 inter = lookup_interface (CLASS_SUPER_NAME (inter)))
889 if (lname == CLASS_SUPER_NAME (inter))
892 /* Allow the reverse when reflexive. */
894 for (inter = lookup_interface (lname); inter;
895 inter = lookup_interface (CLASS_SUPER_NAME (inter)))
896 if (rname == CLASS_SUPER_NAME (inter))
902 /* Not an ObjC type - let comptypes do the check. */
906 /* Called from c-decl.c before all calls to rest_of_decl_compilation. */
909 objc_check_decl (decl)
912 tree type = TREE_TYPE (decl);
914 if (TREE_CODE (type) == RECORD_TYPE
915 && TREE_STATIC_TEMPLATE (type)
916 && type != constant_string_type)
917 error_with_decl (decl, "`%s' cannot be statically allocated");
920 /* Implement static typing. At this point, we know we have an interface. */
923 get_static_reference (interface, protocols)
927 tree type = xref_tag (RECORD_TYPE, interface);
931 tree t, m = TYPE_MAIN_VARIANT (type);
933 t = copy_node (type);
935 /* Add this type to the chain of variants of TYPE. */
936 TYPE_NEXT_VARIANT (t) = TYPE_NEXT_VARIANT (m);
937 TYPE_NEXT_VARIANT (m) = t;
939 /* Look up protocols and install in lang specific list. Note
940 that the protocol list can have a different lifetime than T! */
941 TYPE_PROTOCOL_LIST (t) = lookup_and_install_protocols (protocols);
943 /* This forces a new pointer type to be created later
944 (in build_pointer_type)...so that the new template
945 we just created will actually be used...what a hack! */
946 if (TYPE_POINTER_TO (t))
947 TYPE_POINTER_TO (t) = NULL_TREE;
956 get_object_reference (protocols)
959 tree type_decl = lookup_name (objc_id_id);
962 if (type_decl && TREE_CODE (type_decl) == TYPE_DECL)
964 type = TREE_TYPE (type_decl);
965 if (TYPE_MAIN_VARIANT (type) != id_type)
966 warning ("unexpected type for `id' (%s)",
967 gen_declaration (type, errbuf));
971 error ("undefined type `id', please import <objc/objc.h>");
972 return error_mark_node;
975 /* This clause creates a new pointer type that is qualified with
976 the protocol specification...this info is used later to do more
977 elaborate type checking. */
981 tree t, m = TYPE_MAIN_VARIANT (type);
983 t = copy_node (type);
985 /* Add this type to the chain of variants of TYPE. */
986 TYPE_NEXT_VARIANT (t) = TYPE_NEXT_VARIANT (m);
987 TYPE_NEXT_VARIANT (m) = t;
989 /* Look up protocols...and install in lang specific list */
990 TYPE_PROTOCOL_LIST (t) = lookup_and_install_protocols (protocols);
992 /* This forces a new pointer type to be created later
993 (in build_pointer_type)...so that the new template
994 we just created will actually be used...what a hack! */
995 if (TYPE_POINTER_TO (t))
996 TYPE_POINTER_TO (t) = NULL_TREE;
1003 /* Check for circular dependencies in protocols. The arguments are
1004 PROTO, the protocol to check, and LIST, a list of protocol it
1008 check_protocol_recursively (proto, list)
1014 for (p = list; p; p = TREE_CHAIN (p))
1016 tree pp = TREE_VALUE (p);
1018 if (TREE_CODE (pp) == IDENTIFIER_NODE)
1019 pp = lookup_protocol (pp);
1022 fatal_error ("protocol `%s' has circular dependency",
1023 IDENTIFIER_POINTER (PROTOCOL_NAME (pp)));
1025 check_protocol_recursively (proto, PROTOCOL_LIST (pp));
1030 lookup_and_install_protocols (protocols)
1035 tree return_value = protocols;
1037 for (proto = protocols; proto; proto = TREE_CHAIN (proto))
1039 tree ident = TREE_VALUE (proto);
1040 tree p = lookup_protocol (ident);
1044 error ("cannot find protocol declaration for `%s'",
1045 IDENTIFIER_POINTER (ident));
1047 TREE_CHAIN (prev) = TREE_CHAIN (proto);
1049 return_value = TREE_CHAIN (proto);
1053 /* Replace identifier with actual protocol node. */
1054 TREE_VALUE (proto) = p;
1059 return return_value;
1062 /* Create and push a decl for a built-in external variable or field NAME.
1064 TYPE is its data type. */
1067 create_builtin_decl (code, type, name)
1068 enum tree_code code;
1072 tree decl = build_decl (code, get_identifier (name), type);
1074 if (code == VAR_DECL)
1076 TREE_STATIC (decl) = 1;
1077 make_decl_rtl (decl, 0);
1081 DECL_ARTIFICIAL (decl) = 1;
1085 /* Find the decl for the constant string class. */
1088 setup_string_decl ()
1090 if (!string_class_decl)
1092 if (!constant_string_global_id)
1093 constant_string_global_id = get_identifier (STRING_OBJECT_GLOBAL_NAME);
1094 string_class_decl = lookup_name (constant_string_global_id);
1098 /* Purpose: "play" parser, creating/installing representations
1099 of the declarations that are required by Objective-C.
1103 type_spec--------->sc_spec
1104 (tree_list) (tree_list)
1107 identifier_node identifier_node */
1110 synth_module_prologue ()
1115 /* Defined in `objc.h' */
1116 objc_object_id = get_identifier (TAG_OBJECT);
1118 objc_object_reference = xref_tag (RECORD_TYPE, objc_object_id);
1120 id_type = build_pointer_type (objc_object_reference);
1122 objc_id_id = get_identifier (TYPE_ID);
1123 objc_class_id = get_identifier (TAG_CLASS);
1125 objc_class_type = build_pointer_type (xref_tag (RECORD_TYPE, objc_class_id));
1126 protocol_type = build_pointer_type (xref_tag (RECORD_TYPE,
1127 get_identifier (PROTOCOL_OBJECT_CLASS_NAME)));
1129 /* Declare type of selector-objects that represent an operation name. */
1131 /* `struct objc_selector *' */
1133 = build_pointer_type (xref_tag (RECORD_TYPE,
1134 get_identifier (TAG_SELECTOR)));
1136 /* Forward declare type, or else the prototype for msgSendSuper will
1139 super_p = build_pointer_type (xref_tag (RECORD_TYPE,
1140 get_identifier (TAG_SUPER)));
1143 /* id objc_msgSend (id, SEL, ...); */
1146 = build_function_type (id_type,
1147 tree_cons (NULL_TREE, id_type,
1148 tree_cons (NULL_TREE, selector_type,
1151 if (! flag_next_runtime)
1153 umsg_decl = build_decl (FUNCTION_DECL,
1154 get_identifier (TAG_MSGSEND), temp_type);
1155 DECL_EXTERNAL (umsg_decl) = 1;
1156 TREE_PUBLIC (umsg_decl) = 1;
1157 DECL_INLINE (umsg_decl) = 1;
1158 DECL_ARTIFICIAL (umsg_decl) = 1;
1160 make_decl_rtl (umsg_decl, NULL);
1161 pushdecl (umsg_decl);
1164 umsg_decl = builtin_function (TAG_MSGSEND, temp_type, 0, NOT_BUILT_IN,
1167 /* id objc_msgSendSuper (struct objc_super *, SEL, ...); */
1170 = build_function_type (id_type,
1171 tree_cons (NULL_TREE, super_p,
1172 tree_cons (NULL_TREE, selector_type,
1175 umsg_super_decl = builtin_function (TAG_MSGSENDSUPER,
1176 temp_type, 0, NOT_BUILT_IN,
1179 /* id objc_getClass (const char *); */
1181 temp_type = build_function_type (id_type,
1182 tree_cons (NULL_TREE,
1183 const_string_type_node,
1184 tree_cons (NULL_TREE, void_type_node,
1188 = builtin_function (TAG_GETCLASS, temp_type, 0, NOT_BUILT_IN,
1191 /* id objc_getMetaClass (const char *); */
1193 objc_get_meta_class_decl
1194 = builtin_function (TAG_GETMETACLASS, temp_type, 0, NOT_BUILT_IN,
1197 /* static SEL _OBJC_SELECTOR_TABLE[]; */
1199 if (! flag_next_runtime)
1201 if (flag_typed_selectors)
1203 /* Suppress outputting debug symbols, because
1204 dbxout_init hasn'r been called yet. */
1205 enum debug_info_type save_write_symbols = write_symbols;
1206 const struct gcc_debug_hooks *const save_hooks = debug_hooks;
1207 write_symbols = NO_DEBUG;
1208 debug_hooks = &do_nothing_debug_hooks;
1210 build_selector_template ();
1211 temp_type = build_array_type (objc_selector_template, NULL_TREE);
1213 write_symbols = save_write_symbols;
1214 debug_hooks = save_hooks;
1217 temp_type = build_array_type (selector_type, NULL_TREE);
1219 layout_type (temp_type);
1220 UOBJC_SELECTOR_TABLE_decl
1221 = create_builtin_decl (VAR_DECL, temp_type,
1222 "_OBJC_SELECTOR_TABLE");
1224 /* Avoid warning when not sending messages. */
1225 TREE_USED (UOBJC_SELECTOR_TABLE_decl) = 1;
1228 generate_forward_declaration_to_string_table ();
1230 /* Forward declare constant_string_id and constant_string_type. */
1231 if (!constant_string_class_name)
1232 constant_string_class_name = default_constant_string_class_name;
1234 constant_string_id = get_identifier (constant_string_class_name);
1235 constant_string_type = xref_tag (RECORD_TYPE, constant_string_id);
1238 /* Predefine the following data type:
1240 struct STRING_OBJECT_CLASS_NAME
1244 unsigned int length;
1248 build_string_class_template ()
1250 tree field_decl, field_decl_chain;
1252 field_decl = create_builtin_decl (FIELD_DECL, id_type, "isa");
1253 field_decl_chain = field_decl;
1255 field_decl = create_builtin_decl (FIELD_DECL,
1256 build_pointer_type (char_type_node),
1258 chainon (field_decl_chain, field_decl);
1260 field_decl = create_builtin_decl (FIELD_DECL, unsigned_type_node, "length");
1261 chainon (field_decl_chain, field_decl);
1263 finish_struct (constant_string_type, field_decl_chain, NULL_TREE);
1266 /* Custom build_string which sets TREE_TYPE! */
1269 my_build_string (len, str)
1273 return fix_string_type (build_string (len, str));
1276 /* Given a chain of STRING_CST's, build a static instance of
1277 NXConstantString which points at the concatenation of those strings.
1278 We place the string object in the __string_objects section of the
1279 __OBJC segment. The Objective-C runtime will initialize the isa
1280 pointers of the string objects to point at the NXConstantString
1284 build_objc_string_object (strings)
1287 tree string, initlist, constructor;
1290 if (lookup_interface (constant_string_id) == NULL_TREE)
1292 error ("cannot find interface declaration for `%s'",
1293 IDENTIFIER_POINTER (constant_string_id));
1294 return error_mark_node;
1297 add_class_reference (constant_string_id);
1299 if (TREE_CHAIN (strings))
1301 varray_type vstrings;
1302 VARRAY_TREE_INIT (vstrings, 32, "strings");
1304 for (; strings ; strings = TREE_CHAIN (strings))
1305 VARRAY_PUSH_TREE (vstrings, strings);
1307 string = combine_strings (vstrings);
1312 string = fix_string_type (string);
1314 TREE_SET_CODE (string, STRING_CST);
1315 length = TREE_STRING_LENGTH (string) - 1;
1317 /* We could not properly create NXConstantString in synth_module_prologue,
1318 because that's called before debugging is initialized. Do it now. */
1319 if (TYPE_FIELDS (constant_string_type) == NULL_TREE)
1320 build_string_class_template ();
1322 /* & ((NXConstantString) { NULL, string, length }) */
1324 if (flag_next_runtime)
1326 /* For the NeXT runtime, we can generate a literal reference
1327 to the string class, don't need to run a constructor. */
1328 setup_string_decl ();
1329 if (string_class_decl == NULL_TREE)
1331 error ("cannot find reference tag for class `%s'",
1332 IDENTIFIER_POINTER (constant_string_id));
1333 return error_mark_node;
1335 initlist = build_tree_list
1337 copy_node (build_unary_op (ADDR_EXPR, string_class_decl, 0)));
1341 initlist = build_tree_list (NULL_TREE, build_int_2 (0, 0));
1345 = tree_cons (NULL_TREE, copy_node (build_unary_op (ADDR_EXPR, string, 1)),
1347 initlist = tree_cons (NULL_TREE, build_int_2 (length, 0), initlist);
1348 constructor = build_constructor (constant_string_type, nreverse (initlist));
1350 if (!flag_next_runtime)
1353 = objc_add_static_instance (constructor, constant_string_type);
1356 return (build_unary_op (ADDR_EXPR, constructor, 1));
1359 /* Declare a static instance of CLASS_DECL initialized by CONSTRUCTOR. */
1362 objc_add_static_instance (constructor, class_decl)
1363 tree constructor, class_decl;
1365 static int num_static_inst;
1369 /* Find the list of static instances for the CLASS_DECL. Create one if
1371 for (chain = &objc_static_instances;
1372 *chain && TREE_VALUE (*chain) != class_decl;
1373 chain = &TREE_CHAIN (*chain));
1376 *chain = tree_cons (NULL_TREE, class_decl, NULL_TREE);
1377 add_objc_string (TYPE_NAME (class_decl), class_names);
1380 sprintf (buf, "_OBJC_INSTANCE_%d", num_static_inst++);
1381 decl = build_decl (VAR_DECL, get_identifier (buf), class_decl);
1382 DECL_COMMON (decl) = 1;
1383 TREE_STATIC (decl) = 1;
1384 DECL_ARTIFICIAL (decl) = 1;
1385 DECL_INITIAL (decl) = constructor;
1387 /* We may be writing something else just now.
1388 Postpone till end of input. */
1389 DECL_DEFER_OUTPUT (decl) = 1;
1390 pushdecl_top_level (decl);
1391 rest_of_decl_compilation (decl, 0, 1, 0);
1393 /* Add the DECL to the head of this CLASS' list. */
1394 TREE_PURPOSE (*chain) = tree_cons (NULL_TREE, decl, TREE_PURPOSE (*chain));
1399 /* Build a static constant CONSTRUCTOR
1400 with type TYPE and elements ELTS. */
1403 build_constructor (type, elts)
1406 tree constructor, f, e;
1408 /* ??? Most of the places that we build constructors, we don't fill in
1409 the type of integers properly. Convert them all en masse. */
1410 if (TREE_CODE (type) == ARRAY_TYPE)
1412 f = TREE_TYPE (type);
1413 if (TREE_CODE (f) == POINTER_TYPE || TREE_CODE (f) == INTEGER_TYPE)
1414 for (e = elts; e ; e = TREE_CHAIN (e))
1415 TREE_VALUE (e) = convert (f, TREE_VALUE (e));
1419 f = TYPE_FIELDS (type);
1420 for (e = elts; e && f; e = TREE_CHAIN (e), f = TREE_CHAIN (f))
1421 if (TREE_CODE (TREE_TYPE (f)) == POINTER_TYPE
1422 || TREE_CODE (TREE_TYPE (f)) == INTEGER_TYPE)
1423 TREE_VALUE (e) = convert (TREE_TYPE (f), TREE_VALUE (e));
1426 constructor = build (CONSTRUCTOR, type, NULL_TREE, elts);
1427 TREE_CONSTANT (constructor) = 1;
1428 TREE_STATIC (constructor) = 1;
1429 TREE_READONLY (constructor) = 1;
1434 /* Take care of defining and initializing _OBJC_SYMBOLS. */
1436 /* Predefine the following data type:
1444 void *defs[cls_def_cnt + cat_def_cnt];
1448 build_objc_symtab_template ()
1450 tree field_decl, field_decl_chain, index;
1452 objc_symtab_template
1453 = start_struct (RECORD_TYPE, get_identifier (UTAG_SYMTAB));
1455 /* long sel_ref_cnt; */
1457 field_decl = create_builtin_decl (FIELD_DECL,
1458 long_integer_type_node,
1460 field_decl_chain = field_decl;
1464 field_decl = create_builtin_decl (FIELD_DECL,
1465 build_pointer_type (selector_type),
1467 chainon (field_decl_chain, field_decl);
1469 /* short cls_def_cnt; */
1471 field_decl = create_builtin_decl (FIELD_DECL,
1472 short_integer_type_node,
1474 chainon (field_decl_chain, field_decl);
1476 /* short cat_def_cnt; */
1478 field_decl = create_builtin_decl (FIELD_DECL,
1479 short_integer_type_node,
1481 chainon (field_decl_chain, field_decl);
1483 /* void *defs[cls_def_cnt + cat_def_cnt]; */
1485 if (!flag_next_runtime)
1486 index = build_index_type (build_int_2 (imp_count + cat_count, 0));
1488 index = build_index_type (build_int_2 (imp_count + cat_count - 1,
1489 imp_count == 0 && cat_count == 0
1491 field_decl = create_builtin_decl (FIELD_DECL,
1492 build_array_type (ptr_type_node, index),
1494 chainon (field_decl_chain, field_decl);
1496 finish_struct (objc_symtab_template, field_decl_chain, NULL_TREE);
1499 /* Create the initial value for the `defs' field of _objc_symtab.
1500 This is a CONSTRUCTOR. */
1503 init_def_list (type)
1506 tree expr, initlist = NULL_TREE;
1507 struct imp_entry *impent;
1510 for (impent = imp_list; impent; impent = impent->next)
1512 if (TREE_CODE (impent->imp_context) == CLASS_IMPLEMENTATION_TYPE)
1514 expr = build_unary_op (ADDR_EXPR, impent->class_decl, 0);
1515 initlist = tree_cons (NULL_TREE, expr, initlist);
1520 for (impent = imp_list; impent; impent = impent->next)
1522 if (TREE_CODE (impent->imp_context) == CATEGORY_IMPLEMENTATION_TYPE)
1524 expr = build_unary_op (ADDR_EXPR, impent->class_decl, 0);
1525 initlist = tree_cons (NULL_TREE, expr, initlist);
1529 if (!flag_next_runtime)
1531 /* statics = { ..., _OBJC_STATIC_INSTANCES, ... } */
1534 if (static_instances_decl)
1535 expr = build_unary_op (ADDR_EXPR, static_instances_decl, 0);
1537 expr = build_int_2 (0, 0);
1539 initlist = tree_cons (NULL_TREE, expr, initlist);
1542 return build_constructor (type, nreverse (initlist));
1545 /* Construct the initial value for all of _objc_symtab. */
1548 init_objc_symtab (type)
1553 /* sel_ref_cnt = { ..., 5, ... } */
1555 initlist = build_tree_list (NULL_TREE, build_int_2 (0, 0));
1557 /* refs = { ..., _OBJC_SELECTOR_TABLE, ... } */
1559 if (flag_next_runtime || ! sel_ref_chain)
1560 initlist = tree_cons (NULL_TREE, build_int_2 (0, 0), initlist);
1562 initlist = tree_cons (NULL_TREE,
1563 build_unary_op (ADDR_EXPR,
1564 UOBJC_SELECTOR_TABLE_decl, 1),
1567 /* cls_def_cnt = { ..., 5, ... } */
1569 initlist = tree_cons (NULL_TREE, build_int_2 (imp_count, 0), initlist);
1571 /* cat_def_cnt = { ..., 5, ... } */
1573 initlist = tree_cons (NULL_TREE, build_int_2 (cat_count, 0), initlist);
1575 /* cls_def = { ..., { &Foo, &Bar, ...}, ... } */
1577 if (imp_count || cat_count || static_instances_decl)
1580 tree field = TYPE_FIELDS (type);
1581 field = TREE_CHAIN (TREE_CHAIN (TREE_CHAIN (TREE_CHAIN (field))));
1583 initlist = tree_cons (NULL_TREE, init_def_list (TREE_TYPE (field)),
1587 return build_constructor (type, nreverse (initlist));
1590 /* Push forward-declarations of all the categories so that
1591 init_def_list can use them in a CONSTRUCTOR. */
1594 forward_declare_categories ()
1596 struct imp_entry *impent;
1597 tree sav = objc_implementation_context;
1599 for (impent = imp_list; impent; impent = impent->next)
1601 if (TREE_CODE (impent->imp_context) == CATEGORY_IMPLEMENTATION_TYPE)
1603 /* Set an invisible arg to synth_id_with_class_suffix. */
1604 objc_implementation_context = impent->imp_context;
1606 = create_builtin_decl (VAR_DECL, objc_category_template,
1607 IDENTIFIER_POINTER (synth_id_with_class_suffix ("_OBJC_CATEGORY", objc_implementation_context)));
1610 objc_implementation_context = sav;
1613 /* Create the declaration of _OBJC_SYMBOLS, with type `strict _objc_symtab'
1614 and initialized appropriately. */
1617 generate_objc_symtab_decl ()
1621 if (!objc_category_template)
1622 build_category_template ();
1624 /* forward declare categories */
1626 forward_declare_categories ();
1628 if (!objc_symtab_template)
1629 build_objc_symtab_template ();
1631 sc_spec = build_tree_list (NULL_TREE, ridpointers[(int) RID_STATIC]);
1633 UOBJC_SYMBOLS_decl = start_decl (get_identifier ("_OBJC_SYMBOLS"),
1634 tree_cons (NULL_TREE,
1635 objc_symtab_template, sc_spec),
1639 TREE_USED (UOBJC_SYMBOLS_decl) = 1;
1640 DECL_IGNORED_P (UOBJC_SYMBOLS_decl) = 1;
1641 DECL_ARTIFICIAL (UOBJC_SYMBOLS_decl) = 1;
1642 finish_decl (UOBJC_SYMBOLS_decl,
1643 init_objc_symtab (TREE_TYPE (UOBJC_SYMBOLS_decl)),
1648 init_module_descriptor (type)
1651 tree initlist, expr;
1653 /* version = { 1, ... } */
1655 expr = build_int_2 (OBJC_VERSION, 0);
1656 initlist = build_tree_list (NULL_TREE, expr);
1658 /* size = { ..., sizeof (struct objc_module), ... } */
1660 expr = size_in_bytes (objc_module_template);
1661 initlist = tree_cons (NULL_TREE, expr, initlist);
1663 /* name = { ..., "foo.m", ... } */
1665 expr = add_objc_string (get_identifier (input_filename), class_names);
1666 initlist = tree_cons (NULL_TREE, expr, initlist);
1668 /* symtab = { ..., _OBJC_SYMBOLS, ... } */
1670 if (UOBJC_SYMBOLS_decl)
1671 expr = build_unary_op (ADDR_EXPR, UOBJC_SYMBOLS_decl, 0);
1673 expr = build_int_2 (0, 0);
1674 initlist = tree_cons (NULL_TREE, expr, initlist);
1676 return build_constructor (type, nreverse (initlist));
1679 /* Write out the data structures to describe Objective C classes defined.
1680 If appropriate, compile and output a setup function to initialize them.
1681 Return a symbol_ref to the function to call to initialize the Objective C
1682 data structures for this file (and perhaps for other files also).
1684 struct objc_module { ... } _OBJC_MODULE = { ... }; */
1687 build_module_descriptor ()
1689 tree decl_specs, field_decl, field_decl_chain;
1691 objc_module_template
1692 = start_struct (RECORD_TYPE, get_identifier (UTAG_MODULE));
1696 decl_specs = build_tree_list (NULL_TREE, ridpointers[(int) RID_LONG]);
1697 field_decl = get_identifier ("version");
1699 = grokfield (input_filename, lineno, field_decl, decl_specs, NULL_TREE);
1700 field_decl_chain = field_decl;
1704 decl_specs = build_tree_list (NULL_TREE, ridpointers[(int) RID_LONG]);
1705 field_decl = get_identifier ("size");
1707 = grokfield (input_filename, lineno, field_decl, decl_specs, NULL_TREE);
1708 chainon (field_decl_chain, field_decl);
1712 decl_specs = build_tree_list (NULL_TREE, ridpointers[(int) RID_CHAR]);
1713 field_decl = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("name"));
1715 = grokfield (input_filename, lineno, field_decl, decl_specs, NULL_TREE);
1716 chainon (field_decl_chain, field_decl);
1718 /* struct objc_symtab *symtab; */
1720 decl_specs = get_identifier (UTAG_SYMTAB);
1721 decl_specs = build_tree_list (NULL_TREE, xref_tag (RECORD_TYPE, decl_specs));
1722 field_decl = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("symtab"));
1724 = grokfield (input_filename, lineno, field_decl, decl_specs, NULL_TREE);
1725 chainon (field_decl_chain, field_decl);
1727 finish_struct (objc_module_template, field_decl_chain, NULL_TREE);
1729 /* Create an instance of "objc_module". */
1731 decl_specs = tree_cons (NULL_TREE, objc_module_template,
1732 build_tree_list (NULL_TREE,
1733 ridpointers[(int) RID_STATIC]));
1735 UOBJC_MODULES_decl = start_decl (get_identifier ("_OBJC_MODULES"),
1736 decl_specs, 1, NULL_TREE);
1738 DECL_ARTIFICIAL (UOBJC_MODULES_decl) = 1;
1739 DECL_IGNORED_P (UOBJC_MODULES_decl) = 1;
1740 DECL_CONTEXT (UOBJC_MODULES_decl) = NULL_TREE;
1742 finish_decl (UOBJC_MODULES_decl,
1743 init_module_descriptor (TREE_TYPE (UOBJC_MODULES_decl)),
1746 /* Mark the decl to avoid "defined but not used" warning. */
1747 DECL_IN_SYSTEM_HEADER (UOBJC_MODULES_decl) = 1;
1749 /* Generate a constructor call for the module descriptor.
1750 This code was generated by reading the grammar rules
1751 of c-parse.in; Therefore, it may not be the most efficient
1752 way of generating the requisite code. */
1754 if (flag_next_runtime)
1758 tree parms, execclass_decl, decelerator, void_list_node_1;
1759 tree init_function_name, init_function_decl;
1761 /* Declare void __objc_execClass (void *); */
1763 void_list_node_1 = build_tree_list (NULL_TREE, void_type_node);
1764 execclass_decl = build_decl (FUNCTION_DECL,
1765 get_identifier (TAG_EXECCLASS),
1766 build_function_type (void_type_node,
1767 tree_cons (NULL_TREE, ptr_type_node,
1768 void_list_node_1)));
1769 DECL_EXTERNAL (execclass_decl) = 1;
1770 DECL_ARTIFICIAL (execclass_decl) = 1;
1771 TREE_PUBLIC (execclass_decl) = 1;
1772 pushdecl (execclass_decl);
1773 rest_of_decl_compilation (execclass_decl, 0, 0, 0);
1774 assemble_external (execclass_decl);
1776 /* void _GLOBAL_$I$<gnyf> () {objc_execClass (&L_OBJC_MODULES);} */
1778 init_function_name = get_file_function_name ('I');
1779 start_function (void_list_node_1,
1780 build_nt (CALL_EXPR, init_function_name,
1781 tree_cons (NULL_TREE, NULL_TREE,
1785 store_parm_decls ();
1787 init_function_decl = current_function_decl;
1788 TREE_PUBLIC (init_function_decl) = ! targetm.have_ctors_dtors;
1789 TREE_USED (init_function_decl) = 1;
1790 /* Don't let this one be deferred. */
1791 DECL_INLINE (init_function_decl) = 0;
1792 DECL_UNINLINABLE (init_function_decl) = 1;
1793 current_function_cannot_inline
1794 = "static constructors and destructors cannot be inlined";
1797 = build_tree_list (NULL_TREE,
1798 build_unary_op (ADDR_EXPR, UOBJC_MODULES_decl, 0));
1799 decelerator = build_function_call (execclass_decl, parms);
1801 c_expand_expr_stmt (decelerator);
1803 finish_function (0, 0);
1805 return XEXP (DECL_RTL (init_function_decl), 0);
1809 /* extern const char _OBJC_STRINGS[]; */
1812 generate_forward_declaration_to_string_table ()
1814 tree sc_spec, decl_specs, expr_decl;
1816 sc_spec = tree_cons (NULL_TREE, ridpointers[(int) RID_EXTERN], NULL_TREE);
1817 decl_specs = tree_cons (NULL_TREE, ridpointers[(int) RID_CHAR], sc_spec);
1820 = build_nt (ARRAY_REF, get_identifier ("_OBJC_STRINGS"), NULL_TREE);
1822 UOBJC_STRINGS_decl = define_decl (expr_decl, decl_specs);
1825 /* Return the DECL of the string IDENT in the SECTION. */
1828 get_objc_string_decl (ident, section)
1830 enum string_section section;
1834 if (section == class_names)
1835 chain = class_names_chain;
1836 else if (section == meth_var_names)
1837 chain = meth_var_names_chain;
1838 else if (section == meth_var_types)
1839 chain = meth_var_types_chain;
1843 for (; chain != 0; chain = TREE_CHAIN (chain))
1844 if (TREE_VALUE (chain) == ident)
1845 return (TREE_PURPOSE (chain));
1851 /* Output references to all statically allocated objects. Return the DECL
1852 for the array built. */
1855 generate_static_references ()
1857 tree decls = NULL_TREE, ident, decl_spec, expr_decl, expr = NULL_TREE;
1858 tree class_name, class, decl, initlist;
1859 tree cl_chain, in_chain, type;
1860 int num_inst, num_class;
1863 if (flag_next_runtime)
1866 for (cl_chain = objc_static_instances, num_class = 0;
1867 cl_chain; cl_chain = TREE_CHAIN (cl_chain), num_class++)
1869 for (num_inst = 0, in_chain = TREE_PURPOSE (cl_chain);
1870 in_chain; num_inst++, in_chain = TREE_CHAIN (in_chain));
1872 sprintf (buf, "_OBJC_STATIC_INSTANCES_%d", num_class);
1873 ident = get_identifier (buf);
1875 expr_decl = build_nt (ARRAY_REF, ident, NULL_TREE);
1876 decl_spec = tree_cons (NULL_TREE, build_pointer_type (void_type_node),
1877 build_tree_list (NULL_TREE,
1878 ridpointers[(int) RID_STATIC]));
1879 decl = start_decl (expr_decl, decl_spec, 1, NULL_TREE);
1880 DECL_CONTEXT (decl) = 0;
1881 DECL_ARTIFICIAL (decl) = 1;
1883 /* Output {class_name, ...}. */
1884 class = TREE_VALUE (cl_chain);
1885 class_name = get_objc_string_decl (TYPE_NAME (class), class_names);
1886 initlist = build_tree_list (NULL_TREE,
1887 build_unary_op (ADDR_EXPR, class_name, 1));
1889 /* Output {..., instance, ...}. */
1890 for (in_chain = TREE_PURPOSE (cl_chain);
1891 in_chain; in_chain = TREE_CHAIN (in_chain))
1893 expr = build_unary_op (ADDR_EXPR, TREE_VALUE (in_chain), 1);
1894 initlist = tree_cons (NULL_TREE, expr, initlist);
1897 /* Output {..., NULL}. */
1898 initlist = tree_cons (NULL_TREE, build_int_2 (0, 0), initlist);
1900 expr = build_constructor (TREE_TYPE (decl), nreverse (initlist));
1901 finish_decl (decl, expr, NULL_TREE);
1902 TREE_USED (decl) = 1;
1904 type = build_array_type (build_pointer_type (void_type_node), 0);
1905 decl = build_decl (VAR_DECL, ident, type);
1906 TREE_USED (decl) = 1;
1907 TREE_STATIC (decl) = 1;
1909 = tree_cons (NULL_TREE, build_unary_op (ADDR_EXPR, decl, 1), decls);
1912 decls = tree_cons (NULL_TREE, build_int_2 (0, 0), decls);
1913 ident = get_identifier ("_OBJC_STATIC_INSTANCES");
1914 expr_decl = build_nt (ARRAY_REF, ident, NULL_TREE);
1915 decl_spec = tree_cons (NULL_TREE, build_pointer_type (void_type_node),
1916 build_tree_list (NULL_TREE,
1917 ridpointers[(int) RID_STATIC]));
1918 static_instances_decl
1919 = start_decl (expr_decl, decl_spec, 1, NULL_TREE);
1920 TREE_USED (static_instances_decl) = 1;
1921 DECL_CONTEXT (static_instances_decl) = 0;
1922 DECL_ARTIFICIAL (static_instances_decl) = 1;
1923 expr = build_constructor (TREE_TYPE (static_instances_decl),
1925 finish_decl (static_instances_decl, expr, NULL_TREE);
1928 /* Output all strings. */
1933 tree sc_spec, decl_specs, expr_decl;
1934 tree chain, string_expr;
1937 for (chain = class_names_chain; chain; chain = TREE_CHAIN (chain))
1939 string = TREE_VALUE (chain);
1940 decl = TREE_PURPOSE (chain);
1942 = tree_cons (NULL_TREE, ridpointers[(int) RID_STATIC], NULL_TREE);
1943 decl_specs = tree_cons (NULL_TREE, ridpointers[(int) RID_CHAR], sc_spec);
1944 expr_decl = build_nt (ARRAY_REF, DECL_NAME (decl), NULL_TREE);
1945 decl = start_decl (expr_decl, decl_specs, 1, NULL_TREE);
1946 DECL_CONTEXT (decl) = NULL_TREE;
1947 string_expr = my_build_string (IDENTIFIER_LENGTH (string) + 1,
1948 IDENTIFIER_POINTER (string));
1949 finish_decl (decl, string_expr, NULL_TREE);
1952 for (chain = meth_var_names_chain; chain; chain = TREE_CHAIN (chain))
1954 string = TREE_VALUE (chain);
1955 decl = TREE_PURPOSE (chain);
1957 = tree_cons (NULL_TREE, ridpointers[(int) RID_STATIC], NULL_TREE);
1958 decl_specs = tree_cons (NULL_TREE, ridpointers[(int) RID_CHAR], sc_spec);
1959 expr_decl = build_nt (ARRAY_REF, DECL_NAME (decl), NULL_TREE);
1960 decl = start_decl (expr_decl, decl_specs, 1, NULL_TREE);
1961 DECL_CONTEXT (decl) = NULL_TREE;
1962 string_expr = my_build_string (IDENTIFIER_LENGTH (string) + 1,
1963 IDENTIFIER_POINTER (string));
1964 finish_decl (decl, string_expr, NULL_TREE);
1967 for (chain = meth_var_types_chain; chain; chain = TREE_CHAIN (chain))
1969 string = TREE_VALUE (chain);
1970 decl = TREE_PURPOSE (chain);
1972 = tree_cons (NULL_TREE, ridpointers[(int) RID_STATIC], NULL_TREE);
1973 decl_specs = tree_cons (NULL_TREE, ridpointers[(int) RID_CHAR], sc_spec);
1974 expr_decl = build_nt (ARRAY_REF, DECL_NAME (decl), NULL_TREE);
1975 decl = start_decl (expr_decl, decl_specs, 1, NULL_TREE);
1976 DECL_CONTEXT (decl) = NULL_TREE;
1977 string_expr = my_build_string (IDENTIFIER_LENGTH (string) + 1,
1978 IDENTIFIER_POINTER (string));
1979 finish_decl (decl, string_expr, NULL_TREE);
1984 build_selector_reference_decl ()
1990 sprintf (buf, "_OBJC_SELECTOR_REFERENCES_%d", idx++);
1992 ident = get_identifier (buf);
1994 decl = build_decl (VAR_DECL, ident, selector_type);
1995 DECL_EXTERNAL (decl) = 1;
1996 TREE_PUBLIC (decl) = 1;
1997 TREE_USED (decl) = 1;
1998 TREE_READONLY (decl) = 1;
1999 DECL_ARTIFICIAL (decl) = 1;
2000 DECL_CONTEXT (decl) = 0;
2002 make_decl_rtl (decl, 0);
2003 pushdecl_top_level (decl);
2008 /* Just a handy wrapper for add_objc_string. */
2011 build_selector (ident)
2014 tree expr = add_objc_string (ident, meth_var_names);
2015 if (flag_typed_selectors)
2018 return build_c_cast (selector_type, expr); /* cast! */
2022 build_selector_translation_table ()
2024 tree sc_spec, decl_specs;
2025 tree chain, initlist = NULL_TREE;
2027 tree decl = NULL_TREE, var_decl, name;
2029 for (chain = sel_ref_chain; chain; chain = TREE_CHAIN (chain))
2033 if (warn_selector && objc_implementation_context)
2037 for (method_chain = meth_var_names_chain;
2039 method_chain = TREE_CHAIN (method_chain))
2041 if (TREE_VALUE (method_chain) == TREE_VALUE (chain))
2049 /* Adjust line number for warning message. */
2050 int save_lineno = lineno;
2051 if (flag_next_runtime && TREE_PURPOSE (chain))
2052 lineno = DECL_SOURCE_LINE (TREE_PURPOSE (chain));
2053 warning ("creating selector for non existant method %s",
2054 IDENTIFIER_POINTER (TREE_VALUE (chain)));
2055 lineno = save_lineno;
2059 expr = build_selector (TREE_VALUE (chain));
2061 if (flag_next_runtime)
2063 name = DECL_NAME (TREE_PURPOSE (chain));
2065 sc_spec = build_tree_list (NULL_TREE, ridpointers[(int) RID_STATIC]);
2067 /* static SEL _OBJC_SELECTOR_REFERENCES_n = ...; */
2068 decl_specs = tree_cons (NULL_TREE, selector_type, sc_spec);
2072 /* The `decl' that is returned from start_decl is the one that we
2073 forward declared in `build_selector_reference' */
2074 decl = start_decl (var_decl, decl_specs, 1, NULL_TREE );
2077 /* add one for the '\0' character */
2078 offset += IDENTIFIER_LENGTH (TREE_VALUE (chain)) + 1;
2080 if (flag_next_runtime)
2081 finish_decl (decl, expr, NULL_TREE);
2084 if (flag_typed_selectors)
2086 tree eltlist = NULL_TREE;
2087 tree encoding = get_proto_encoding (TREE_PURPOSE (chain));
2088 eltlist = tree_cons (NULL_TREE, expr, NULL_TREE);
2089 eltlist = tree_cons (NULL_TREE, encoding, eltlist);
2090 expr = build_constructor (objc_selector_template,
2091 nreverse (eltlist));
2093 initlist = tree_cons (NULL_TREE, expr, initlist);
2098 if (! flag_next_runtime)
2100 /* Cause the variable and its initial value to be actually output. */
2101 DECL_EXTERNAL (UOBJC_SELECTOR_TABLE_decl) = 0;
2102 TREE_STATIC (UOBJC_SELECTOR_TABLE_decl) = 1;
2103 /* NULL terminate the list and fix the decl for output. */
2104 initlist = tree_cons (NULL_TREE, build_int_2 (0, 0), initlist);
2105 DECL_INITIAL (UOBJC_SELECTOR_TABLE_decl) = objc_ellipsis_node;
2106 initlist = build_constructor (TREE_TYPE (UOBJC_SELECTOR_TABLE_decl),
2107 nreverse (initlist));
2108 finish_decl (UOBJC_SELECTOR_TABLE_decl, initlist, NULL_TREE);
2109 current_function_decl = NULL_TREE;
2114 get_proto_encoding (proto)
2122 if (! METHOD_ENCODING (proto))
2124 tmp_decl = build_tmp_function_decl ();
2125 hack_method_prototype (proto, tmp_decl);
2126 encoding = encode_method_prototype (proto, tmp_decl);
2127 METHOD_ENCODING (proto) = encoding;
2130 encoding = METHOD_ENCODING (proto);
2132 return add_objc_string (encoding, meth_var_types);
2135 return build_int_2 (0, 0);
2138 /* sel_ref_chain is a list whose "value" fields will be instances of
2139 identifier_node that represent the selector. */
2142 build_typed_selector_reference (ident, prototype)
2143 tree ident, prototype;
2145 tree *chain = &sel_ref_chain;
2151 if (TREE_PURPOSE (*chain) == prototype && TREE_VALUE (*chain) == ident)
2152 goto return_at_index;
2155 chain = &TREE_CHAIN (*chain);
2158 *chain = tree_cons (prototype, ident, NULL_TREE);
2161 expr = build_unary_op (ADDR_EXPR,
2162 build_array_ref (UOBJC_SELECTOR_TABLE_decl,
2163 build_int_2 (index, 0)),
2165 return build_c_cast (selector_type, expr);
2169 build_selector_reference (ident)
2172 tree *chain = &sel_ref_chain;
2178 if (TREE_VALUE (*chain) == ident)
2179 return (flag_next_runtime
2180 ? TREE_PURPOSE (*chain)
2181 : build_array_ref (UOBJC_SELECTOR_TABLE_decl,
2182 build_int_2 (index, 0)));
2185 chain = &TREE_CHAIN (*chain);
2188 expr = build_selector_reference_decl ();
2190 *chain = tree_cons (expr, ident, NULL_TREE);
2192 return (flag_next_runtime
2194 : build_array_ref (UOBJC_SELECTOR_TABLE_decl,
2195 build_int_2 (index, 0)));
2199 build_class_reference_decl ()
2205 sprintf (buf, "_OBJC_CLASS_REFERENCES_%d", idx++);
2207 ident = get_identifier (buf);
2209 decl = build_decl (VAR_DECL, ident, objc_class_type);
2210 DECL_EXTERNAL (decl) = 1;
2211 TREE_PUBLIC (decl) = 1;
2212 TREE_USED (decl) = 1;
2213 TREE_READONLY (decl) = 1;
2214 DECL_CONTEXT (decl) = 0;
2215 DECL_ARTIFICIAL (decl) = 1;
2217 make_decl_rtl (decl, 0);
2218 pushdecl_top_level (decl);
2223 /* Create a class reference, but don't create a variable to reference
2227 add_class_reference (ident)
2232 if ((chain = cls_ref_chain))
2237 if (ident == TREE_VALUE (chain))
2241 chain = TREE_CHAIN (chain);
2245 /* Append to the end of the list */
2246 TREE_CHAIN (tail) = tree_cons (NULL_TREE, ident, NULL_TREE);
2249 cls_ref_chain = tree_cons (NULL_TREE, ident, NULL_TREE);
2252 /* Get a class reference, creating it if necessary. Also create the
2253 reference variable. */
2256 get_class_reference (ident)
2259 if (flag_next_runtime)
2264 for (chain = &cls_ref_chain; *chain; chain = &TREE_CHAIN (*chain))
2265 if (TREE_VALUE (*chain) == ident)
2267 if (! TREE_PURPOSE (*chain))
2268 TREE_PURPOSE (*chain) = build_class_reference_decl ();
2270 return TREE_PURPOSE (*chain);
2273 decl = build_class_reference_decl ();
2274 *chain = tree_cons (decl, ident, NULL_TREE);
2281 add_class_reference (ident);
2283 params = build_tree_list (NULL_TREE,
2284 my_build_string (IDENTIFIER_LENGTH (ident) + 1,
2285 IDENTIFIER_POINTER (ident)));
2287 assemble_external (objc_get_class_decl);
2288 return build_function_call (objc_get_class_decl, params);
2292 /* For each string section we have a chain which maps identifier nodes
2293 to decls for the strings. */
2296 add_objc_string (ident, section)
2298 enum string_section section;
2302 if (section == class_names)
2303 chain = &class_names_chain;
2304 else if (section == meth_var_names)
2305 chain = &meth_var_names_chain;
2306 else if (section == meth_var_types)
2307 chain = &meth_var_types_chain;
2313 if (TREE_VALUE (*chain) == ident)
2314 return build_unary_op (ADDR_EXPR, TREE_PURPOSE (*chain), 1);
2316 chain = &TREE_CHAIN (*chain);
2319 decl = build_objc_string_decl (section);
2321 *chain = tree_cons (decl, ident, NULL_TREE);
2323 return build_unary_op (ADDR_EXPR, decl, 1);
2327 build_objc_string_decl (section)
2328 enum string_section section;
2332 static int class_names_idx = 0;
2333 static int meth_var_names_idx = 0;
2334 static int meth_var_types_idx = 0;
2336 if (section == class_names)
2337 sprintf (buf, "_OBJC_CLASS_NAME_%d", class_names_idx++);
2338 else if (section == meth_var_names)
2339 sprintf (buf, "_OBJC_METH_VAR_NAME_%d", meth_var_names_idx++);
2340 else if (section == meth_var_types)
2341 sprintf (buf, "_OBJC_METH_VAR_TYPE_%d", meth_var_types_idx++);
2343 ident = get_identifier (buf);
2345 decl = build_decl (VAR_DECL, ident, build_array_type (char_type_node, 0));
2346 DECL_EXTERNAL (decl) = 1;
2347 TREE_PUBLIC (decl) = 1;
2348 TREE_USED (decl) = 1;
2349 TREE_READONLY (decl) = 1;
2350 TREE_CONSTANT (decl) = 1;
2351 DECL_CONTEXT (decl) = 0;
2352 DECL_ARTIFICIAL (decl) = 1;
2354 make_decl_rtl (decl, 0);
2355 pushdecl_top_level (decl);
2362 objc_declare_alias (alias_ident, class_ident)
2366 if (is_class_name (class_ident) != class_ident)
2367 warning ("cannot find class `%s'", IDENTIFIER_POINTER (class_ident));
2368 else if (is_class_name (alias_ident))
2369 warning ("class `%s' already exists", IDENTIFIER_POINTER (alias_ident));
2371 alias_chain = tree_cons (class_ident, alias_ident, alias_chain);
2375 objc_declare_class (ident_list)
2380 for (list = ident_list; list; list = TREE_CHAIN (list))
2382 tree ident = TREE_VALUE (list);
2385 if ((decl = lookup_name (ident)))
2387 error ("`%s' redeclared as different kind of symbol",
2388 IDENTIFIER_POINTER (ident));
2389 error_with_decl (decl, "previous declaration of `%s'");
2392 if (! is_class_name (ident))
2394 tree record = xref_tag (RECORD_TYPE, ident);
2395 TREE_STATIC_TEMPLATE (record) = 1;
2396 class_chain = tree_cons (NULL_TREE, ident, class_chain);
2402 is_class_name (ident)
2407 if (lookup_interface (ident))
2410 for (chain = class_chain; chain; chain = TREE_CHAIN (chain))
2412 if (ident == TREE_VALUE (chain))
2416 for (chain = alias_chain; chain; chain = TREE_CHAIN (chain))
2418 if (ident == TREE_VALUE (chain))
2419 return TREE_PURPOSE (chain);
2429 /* NB: This function may be called before the ObjC front-end
2430 has been initialized, in which case ID_TYPE will be NULL. */
2431 return (id_type && ident && TYPE_P (ident) && IS_ID (ident))
2437 lookup_interface (ident)
2442 for (chain = interface_chain; chain; chain = TREE_CHAIN (chain))
2444 if (ident == CLASS_NAME (chain))
2450 /* Used by: build_private_template, continue_class,
2451 and for @defs constructs. */
2454 get_class_ivars (interface)
2457 tree my_name, super_name, ivar_chain;
2459 my_name = CLASS_NAME (interface);
2460 super_name = CLASS_SUPER_NAME (interface);
2461 ivar_chain = CLASS_IVARS (interface);
2463 /* Save off a pristine copy of the leaf ivars (i.e, those not
2464 inherited from a super class). */
2465 if (!CLASS_OWN_IVARS (interface))
2466 CLASS_OWN_IVARS (interface) = copy_list (ivar_chain);
2471 tree super_interface = lookup_interface (super_name);
2473 if (!super_interface)
2475 /* fatal did not work with 2 args...should fix */
2476 error ("cannot find interface declaration for `%s', superclass of `%s'",
2477 IDENTIFIER_POINTER (super_name),
2478 IDENTIFIER_POINTER (my_name));
2479 exit (FATAL_EXIT_CODE);
2482 if (super_interface == interface)
2483 fatal_error ("circular inheritance in interface declaration for `%s'",
2484 IDENTIFIER_POINTER (super_name));
2486 interface = super_interface;
2487 my_name = CLASS_NAME (interface);
2488 super_name = CLASS_SUPER_NAME (interface);
2490 op1 = CLASS_OWN_IVARS (interface);
2493 tree head = copy_list (op1);
2495 /* Prepend super class ivars...make a copy of the list, we
2496 do not want to alter the original. */
2497 chainon (head, ivar_chain);
2504 /* struct <classname> {
2505 struct objc_class *isa;
2510 build_private_template (class)
2515 if (CLASS_STATIC_TEMPLATE (class))
2517 uprivate_record = CLASS_STATIC_TEMPLATE (class);
2518 ivar_context = TYPE_FIELDS (CLASS_STATIC_TEMPLATE (class));
2522 uprivate_record = start_struct (RECORD_TYPE, CLASS_NAME (class));
2524 ivar_context = get_class_ivars (class);
2526 finish_struct (uprivate_record, ivar_context, NULL_TREE);
2528 CLASS_STATIC_TEMPLATE (class) = uprivate_record;
2530 /* mark this record as class template - for class type checking */
2531 TREE_STATIC_TEMPLATE (uprivate_record) = 1;
2535 = groktypename (build_tree_list (build_tree_list (NULL_TREE,
2537 build1 (INDIRECT_REF, NULL_TREE,
2540 return ivar_context;
2543 /* Begin code generation for protocols... */
2545 /* struct objc_protocol {
2546 char *protocol_name;
2547 struct objc_protocol **protocol_list;
2548 struct objc_method_desc *instance_methods;
2549 struct objc_method_desc *class_methods;
2553 build_protocol_template ()
2555 tree decl_specs, field_decl, field_decl_chain;
2558 template = start_struct (RECORD_TYPE, get_identifier (UTAG_PROTOCOL));
2560 /* struct objc_class *isa; */
2562 decl_specs = build_tree_list (NULL_TREE, xref_tag (RECORD_TYPE,
2563 get_identifier (UTAG_CLASS)));
2564 field_decl = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("isa"));
2566 = grokfield (input_filename, lineno, field_decl, decl_specs, NULL_TREE);
2567 field_decl_chain = field_decl;
2569 /* char *protocol_name; */
2571 decl_specs = build_tree_list (NULL_TREE, ridpointers[(int) RID_CHAR]);
2573 = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("protocol_name"));
2575 = grokfield (input_filename, lineno, field_decl, decl_specs, NULL_TREE);
2576 chainon (field_decl_chain, field_decl);
2578 /* struct objc_protocol **protocol_list; */
2580 decl_specs = build_tree_list (NULL_TREE, template);
2582 = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("protocol_list"));
2583 field_decl = build1 (INDIRECT_REF, NULL_TREE, field_decl);
2585 = grokfield (input_filename, lineno, field_decl, decl_specs, NULL_TREE);
2586 chainon (field_decl_chain, field_decl);
2588 /* struct objc_method_list *instance_methods; */
2591 = build_tree_list (NULL_TREE,
2592 xref_tag (RECORD_TYPE,
2593 get_identifier (UTAG_METHOD_PROTOTYPE_LIST)));
2595 = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("instance_methods"));
2597 = grokfield (input_filename, lineno, field_decl, decl_specs, NULL_TREE);
2598 chainon (field_decl_chain, field_decl);
2600 /* struct objc_method_list *class_methods; */
2603 = build_tree_list (NULL_TREE,
2604 xref_tag (RECORD_TYPE,
2605 get_identifier (UTAG_METHOD_PROTOTYPE_LIST)));
2607 = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("class_methods"));
2609 = grokfield (input_filename, lineno, field_decl, decl_specs, NULL_TREE);
2610 chainon (field_decl_chain, field_decl);
2612 return finish_struct (template, field_decl_chain, NULL_TREE);
2616 build_descriptor_table_initializer (type, entries)
2620 tree initlist = NULL_TREE;
2624 tree eltlist = NULL_TREE;
2627 = tree_cons (NULL_TREE,
2628 build_selector (METHOD_SEL_NAME (entries)), NULL_TREE);
2630 = tree_cons (NULL_TREE,
2631 add_objc_string (METHOD_ENCODING (entries),
2636 = tree_cons (NULL_TREE,
2637 build_constructor (type, nreverse (eltlist)), initlist);
2639 entries = TREE_CHAIN (entries);
2643 return build_constructor (build_array_type (type, 0), nreverse (initlist));
2646 /* struct objc_method_prototype_list {
2648 struct objc_method_prototype {
2655 build_method_prototype_list_template (list_type, size)
2659 tree objc_ivar_list_record;
2660 tree decl_specs, field_decl, field_decl_chain;
2662 /* Generate an unnamed struct definition. */
2664 objc_ivar_list_record = start_struct (RECORD_TYPE, NULL_TREE);
2666 /* int method_count; */
2668 decl_specs = build_tree_list (NULL_TREE, ridpointers[(int) RID_INT]);
2669 field_decl = get_identifier ("method_count");
2672 = grokfield (input_filename, lineno, field_decl, decl_specs, NULL_TREE);
2673 field_decl_chain = field_decl;
2675 /* struct objc_method method_list[]; */
2677 decl_specs = build_tree_list (NULL_TREE, list_type);
2678 field_decl = build_nt (ARRAY_REF, get_identifier ("method_list"),
2679 build_int_2 (size, 0));
2682 = grokfield (input_filename, lineno, field_decl, decl_specs, NULL_TREE);
2683 chainon (field_decl_chain, field_decl);
2685 finish_struct (objc_ivar_list_record, field_decl_chain, NULL_TREE);
2687 return objc_ivar_list_record;
2691 build_method_prototype_template ()
2694 tree decl_specs, field_decl, field_decl_chain;
2697 = start_struct (RECORD_TYPE, get_identifier (UTAG_METHOD_PROTOTYPE));
2699 /* struct objc_selector *_cmd; */
2700 decl_specs = tree_cons (NULL_TREE, xref_tag (RECORD_TYPE,
2701 get_identifier (TAG_SELECTOR)), NULL_TREE);
2702 field_decl = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("_cmd"));
2705 = grokfield (input_filename, lineno, field_decl, decl_specs, NULL_TREE);
2706 field_decl_chain = field_decl;
2708 decl_specs = tree_cons (NULL_TREE, ridpointers[(int) RID_CHAR], NULL_TREE);
2710 = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("method_types"));
2712 = grokfield (input_filename, lineno, field_decl, decl_specs, NULL_TREE);
2713 chainon (field_decl_chain, field_decl);
2715 finish_struct (proto_record, field_decl_chain, NULL_TREE);
2717 return proto_record;
2720 /* True if last call to forwarding_offset yielded a register offset. */
2721 static int offset_is_register;
2724 forwarding_offset (parm)
2727 int offset_in_bytes;
2729 if (GET_CODE (DECL_INCOMING_RTL (parm)) == MEM)
2731 rtx addr = XEXP (DECL_INCOMING_RTL (parm), 0);
2733 /* ??? Here we assume that the parm address is indexed
2734 off the frame pointer or arg pointer.
2735 If that is not true, we produce meaningless results,
2736 but do not crash. */
2737 if (GET_CODE (addr) == PLUS
2738 && GET_CODE (XEXP (addr, 1)) == CONST_INT)
2739 offset_in_bytes = INTVAL (XEXP (addr, 1));
2741 offset_in_bytes = 0;
2743 offset_in_bytes += OBJC_FORWARDING_STACK_OFFSET;
2744 offset_is_register = 0;
2746 else if (GET_CODE (DECL_INCOMING_RTL (parm)) == REG)
2748 int regno = REGNO (DECL_INCOMING_RTL (parm));
2749 offset_in_bytes = apply_args_register_offset (regno);
2750 offset_is_register = 1;
2755 /* This is the case where the parm is passed as an int or double
2756 and it is converted to a char, short or float and stored back
2757 in the parmlist. In this case, describe the parm
2758 with the variable's declared type, and adjust the address
2759 if the least significant bytes (which we are using) are not
2761 if (BYTES_BIG_ENDIAN && TREE_TYPE (parm) != DECL_ARG_TYPE (parm))
2762 offset_in_bytes += (GET_MODE_SIZE (TYPE_MODE (DECL_ARG_TYPE (parm)))
2763 - GET_MODE_SIZE (GET_MODE (DECL_RTL (parm))));
2765 return offset_in_bytes;
2769 encode_method_prototype (method_decl, func_decl)
2776 HOST_WIDE_INT max_parm_end = 0;
2780 /* ONEWAY and BYCOPY, for remote object are the only method qualifiers. */
2781 encode_type_qualifiers (TREE_PURPOSE (TREE_TYPE (method_decl)));
2784 encode_type (TREE_TYPE (TREE_TYPE (func_decl)),
2785 obstack_object_size (&util_obstack),
2786 OBJC_ENCODE_INLINE_DEFS);
2789 for (parms = DECL_ARGUMENTS (func_decl); parms;
2790 parms = TREE_CHAIN (parms))
2792 HOST_WIDE_INT parm_end = (forwarding_offset (parms)
2793 + int_size_in_bytes (TREE_TYPE (parms)));
2795 if (!offset_is_register && max_parm_end < parm_end)
2796 max_parm_end = parm_end;
2799 stack_size = max_parm_end - OBJC_FORWARDING_MIN_OFFSET;
2801 sprintf (buf, "%d", stack_size);
2802 obstack_grow (&util_obstack, buf, strlen (buf));
2804 user_args = METHOD_SEL_ARGS (method_decl);
2806 /* Argument types. */
2807 for (parms = DECL_ARGUMENTS (func_decl), i = 0; parms;
2808 parms = TREE_CHAIN (parms), i++)
2810 /* Process argument qualifiers for user supplied arguments. */
2813 encode_type_qualifiers (TREE_PURPOSE (TREE_TYPE (user_args)));
2814 user_args = TREE_CHAIN (user_args);
2818 encode_type (TREE_TYPE (parms),
2819 obstack_object_size (&util_obstack),
2820 OBJC_ENCODE_INLINE_DEFS);
2822 /* Compute offset. */
2823 sprintf (buf, "%d", forwarding_offset (parms));
2825 /* Indicate register. */
2826 if (offset_is_register)
2827 obstack_1grow (&util_obstack, '+');
2829 obstack_grow (&util_obstack, buf, strlen (buf));
2832 obstack_1grow (&util_obstack, '\0');
2833 result = get_identifier (obstack_finish (&util_obstack));
2834 obstack_free (&util_obstack, util_firstobj);
2839 generate_descriptor_table (type, name, size, list, proto)
2846 tree sc_spec, decl_specs, decl, initlist;
2848 sc_spec = tree_cons (NULL_TREE, ridpointers[(int) RID_STATIC], NULL_TREE);
2849 decl_specs = tree_cons (NULL_TREE, type, sc_spec);
2851 decl = start_decl (synth_id_with_class_suffix (name, proto),
2852 decl_specs, 1, NULL_TREE);
2853 DECL_CONTEXT (decl) = NULL_TREE;
2855 initlist = build_tree_list (NULL_TREE, build_int_2 (size, 0));
2856 initlist = tree_cons (NULL_TREE, list, initlist);
2858 finish_decl (decl, build_constructor (type, nreverse (initlist)),
2865 generate_method_descriptors (protocol)
2868 tree initlist, chain, method_list_template;
2869 tree cast, variable_length_type;
2872 if (!objc_method_prototype_template)
2873 objc_method_prototype_template = build_method_prototype_template ();
2875 cast = build_tree_list (build_tree_list (NULL_TREE, xref_tag (RECORD_TYPE,
2876 get_identifier (UTAG_METHOD_PROTOTYPE_LIST))),
2878 variable_length_type = groktypename (cast);
2880 chain = PROTOCOL_CLS_METHODS (protocol);
2883 size = list_length (chain);
2885 method_list_template
2886 = build_method_prototype_list_template (objc_method_prototype_template,
2890 = build_descriptor_table_initializer (objc_method_prototype_template,
2893 UOBJC_CLASS_METHODS_decl
2894 = generate_descriptor_table (method_list_template,
2895 "_OBJC_PROTOCOL_CLASS_METHODS",
2896 size, initlist, protocol);
2897 TREE_TYPE (UOBJC_CLASS_METHODS_decl) = variable_length_type;
2900 UOBJC_CLASS_METHODS_decl = 0;
2902 chain = PROTOCOL_NST_METHODS (protocol);
2905 size = list_length (chain);
2907 method_list_template
2908 = build_method_prototype_list_template (objc_method_prototype_template,
2911 = build_descriptor_table_initializer (objc_method_prototype_template,
2914 UOBJC_INSTANCE_METHODS_decl
2915 = generate_descriptor_table (method_list_template,
2916 "_OBJC_PROTOCOL_INSTANCE_METHODS",
2917 size, initlist, protocol);
2918 TREE_TYPE (UOBJC_INSTANCE_METHODS_decl) = variable_length_type;
2921 UOBJC_INSTANCE_METHODS_decl = 0;
2924 /* Generate a temporary FUNCTION_DECL node to be used in
2925 hack_method_prototype below. */
2928 build_tmp_function_decl ()
2930 tree decl_specs, expr_decl, parms;
2934 /* struct objc_object *objc_xxx (id, SEL, ...); */
2936 decl_specs = build_tree_list (NULL_TREE, objc_object_reference);
2937 push_parm_decl (build_tree_list
2938 (build_tree_list (decl_specs,
2939 build1 (INDIRECT_REF, NULL_TREE,
2943 decl_specs = build_tree_list (NULL_TREE, xref_tag (RECORD_TYPE,
2944 get_identifier (TAG_SELECTOR)));
2945 expr_decl = build1 (INDIRECT_REF, NULL_TREE, NULL_TREE);
2947 push_parm_decl (build_tree_list (build_tree_list (decl_specs, expr_decl),
2949 parms = get_parm_info (0);
2952 decl_specs = build_tree_list (NULL_TREE, objc_object_reference);
2953 sprintf (buffer, "__objc_tmp_%x", xxx++);
2954 expr_decl = build_nt (CALL_EXPR, get_identifier (buffer), parms, NULL_TREE);
2955 expr_decl = build1 (INDIRECT_REF, NULL_TREE, expr_decl);
2957 return define_decl (expr_decl, decl_specs);
2960 /* Generate the prototypes for protocol methods. This is used to
2961 generate method encodings for these.
2963 NST_METHODS is the method to generate a _DECL node for TMP_DECL is
2964 a decl node to be used. This is also where the return value is
2968 hack_method_prototype (nst_methods, tmp_decl)
2975 /* Hack to avoid problem with static typing of self arg. */
2976 TREE_SET_CODE (nst_methods, CLASS_METHOD_DECL);
2977 start_method_def (nst_methods);
2978 TREE_SET_CODE (nst_methods, INSTANCE_METHOD_DECL);
2980 if (METHOD_ADD_ARGS (nst_methods) == objc_ellipsis_node)
2981 parms = get_parm_info (0); /* we have a `, ...' */
2983 parms = get_parm_info (1); /* place a `void_at_end' */
2985 poplevel (0, 0, 0); /* Must be called BEFORE start_function. */
2987 /* Usually called from store_parm_decls -> init_function_start. */
2989 DECL_ARGUMENTS (tmp_decl) = TREE_PURPOSE (parms);
2991 if (current_function_decl)
2993 current_function_decl = tmp_decl;
2996 /* Code taken from start_function. */
2997 tree restype = TREE_TYPE (TREE_TYPE (tmp_decl));
2998 /* Promote the value to int before returning it. */
2999 if (TREE_CODE (restype) == INTEGER_TYPE
3000 && TYPE_PRECISION (restype) < TYPE_PRECISION (integer_type_node))
3001 restype = integer_type_node;
3002 DECL_RESULT (tmp_decl) = build_decl (RESULT_DECL, 0, restype);
3005 for (parm = DECL_ARGUMENTS (tmp_decl); parm; parm = TREE_CHAIN (parm))
3006 DECL_CONTEXT (parm) = tmp_decl;
3008 init_function_start (tmp_decl, "objc-act", 0);
3010 /* Typically called from expand_function_start for function definitions. */
3011 assign_parms (tmp_decl);
3013 /* install return type */
3014 TREE_TYPE (TREE_TYPE (tmp_decl)) = groktypename (TREE_TYPE (nst_methods));
3016 current_function_decl = NULL;
3020 generate_protocol_references (plist)
3025 /* Forward declare protocols referenced. */
3026 for (lproto = plist; lproto; lproto = TREE_CHAIN (lproto))
3028 tree proto = TREE_VALUE (lproto);
3030 if (TREE_CODE (proto) == PROTOCOL_INTERFACE_TYPE
3031 && PROTOCOL_NAME (proto))
3033 if (! PROTOCOL_FORWARD_DECL (proto))
3034 build_protocol_reference (proto);
3036 if (PROTOCOL_LIST (proto))
3037 generate_protocol_references (PROTOCOL_LIST (proto));
3042 /* For each protocol which was referenced either from a @protocol()
3043 expression, or because a class/category implements it (then a
3044 pointer to the protocol is stored in the struct describing the
3045 class/category), we create a statically allocated instance of the
3046 Protocol class. The code is written in such a way as to generate
3047 as few Protocol objects as possible; we generate a unique Protocol
3048 instance for each protocol, and we don't generate a Protocol
3049 instance if the protocol is never referenced (either from a
3050 @protocol() or from a class/category implementation). These
3051 statically allocated objects can be referred to via the static
3052 (that is, private to this module) symbols _OBJC_PROTOCOL_n.
3054 The statically allocated Protocol objects that we generate here
3055 need to be fixed up at runtime in order to be used: the 'isa'
3056 pointer of the objects need to be set up to point to the 'Protocol'
3057 class, as known at runtime.
3059 The NeXT runtime fixes up all protocols at program startup time,
3060 before main() is entered. It uses a low-level trick to look up all
3061 those symbols, then loops on them and fixes them up.
3063 The GNU runtime as well fixes up all protocols before user code
3064 from the module is executed; it requires pointers to those symbols
3065 to be put in the objc_symtab (which is then passed as argument to
3066 the function __objc_exec_class() which the compiler sets up to be
3067 executed automatically when the module is loaded); setup of those
3068 Protocol objects happen in two ways in the GNU runtime: all
3069 Protocol objects referred to by a class or category implementation
3070 are fixed up when the class/category is loaded; all Protocol
3071 objects referred to by a @protocol() expression are added by the
3072 compiler to the list of statically allocated instances to fixup
3073 (the same list holding the statically allocated constant string
3074 objects). Because, as explained above, the compiler generates as
3075 few Protocol objects as possible, some Protocol object might end up
3076 being referenced multiple times when compiled with the GNU runtime,
3077 and end up being fixed up multiple times at runtime inizialization.
3078 But that doesn't hurt, it's just a little inefficient. */
3080 generate_protocols ()
3082 tree p, tmp_decl, encoding;
3083 tree sc_spec, decl_specs, decl;
3084 tree initlist, protocol_name_expr, refs_decl, refs_expr;
3087 tmp_decl = build_tmp_function_decl ();
3089 if (! objc_protocol_template)
3090 objc_protocol_template = build_protocol_template ();
3092 /* If a protocol was directly referenced, pull in indirect references. */
3093 for (p = protocol_chain; p; p = TREE_CHAIN (p))
3094 if (PROTOCOL_FORWARD_DECL (p) && PROTOCOL_LIST (p))
3095 generate_protocol_references (PROTOCOL_LIST (p));
3097 for (p = protocol_chain; p; p = TREE_CHAIN (p))
3099 tree nst_methods = PROTOCOL_NST_METHODS (p);
3100 tree cls_methods = PROTOCOL_CLS_METHODS (p);
3102 /* If protocol wasn't referenced, don't generate any code. */
3103 if (! PROTOCOL_FORWARD_DECL (p))
3106 /* Make sure we link in the Protocol class. */
3107 add_class_reference (get_identifier (PROTOCOL_OBJECT_CLASS_NAME));
3111 if (! METHOD_ENCODING (nst_methods))
3113 hack_method_prototype (nst_methods, tmp_decl);
3114 encoding = encode_method_prototype (nst_methods, tmp_decl);
3115 METHOD_ENCODING (nst_methods) = encoding;
3117 nst_methods = TREE_CHAIN (nst_methods);
3122 if (! METHOD_ENCODING (cls_methods))
3124 hack_method_prototype (cls_methods, tmp_decl);
3125 encoding = encode_method_prototype (cls_methods, tmp_decl);
3126 METHOD_ENCODING (cls_methods) = encoding;
3129 cls_methods = TREE_CHAIN (cls_methods);
3131 generate_method_descriptors (p);
3133 if (PROTOCOL_LIST (p))
3134 refs_decl = generate_protocol_list (p);
3138 /* static struct objc_protocol _OBJC_PROTOCOL_<mumble>; */
3140 sc_spec = tree_cons (NULL_TREE, ridpointers[(int) RID_STATIC],
3142 decl_specs = tree_cons (NULL_TREE, objc_protocol_template, sc_spec);
3144 decl = start_decl (synth_id_with_class_suffix ("_OBJC_PROTOCOL", p),
3145 decl_specs, 1, NULL_TREE);
3147 DECL_CONTEXT (decl) = NULL_TREE;
3149 protocol_name_expr = add_objc_string (PROTOCOL_NAME (p), class_names);
3155 (build_tree_list (build_tree_list (NULL_TREE,
3156 objc_protocol_template),
3157 build1 (INDIRECT_REF, NULL_TREE,
3158 build1 (INDIRECT_REF, NULL_TREE,
3161 refs_expr = build_unary_op (ADDR_EXPR, refs_decl, 0);
3162 TREE_TYPE (refs_expr) = cast_type2;
3165 refs_expr = build_int_2 (0, 0);
3167 /* UOBJC_INSTANCE_METHODS_decl/UOBJC_CLASS_METHODS_decl are set
3168 by generate_method_descriptors, which is called above. */
3169 initlist = build_protocol_initializer (TREE_TYPE (decl),
3170 protocol_name_expr, refs_expr,
3171 UOBJC_INSTANCE_METHODS_decl,
3172 UOBJC_CLASS_METHODS_decl);
3173 finish_decl (decl, initlist, NULL_TREE);
3175 /* Mark the decl as used to avoid "defined but not used" warning. */
3176 TREE_USED (decl) = 1;
3181 build_protocol_initializer (type, protocol_name, protocol_list,
3182 instance_methods, class_methods)
3186 tree instance_methods;
3189 tree initlist = NULL_TREE, expr;
3192 cast_type = groktypename
3194 (build_tree_list (NULL_TREE,
3195 xref_tag (RECORD_TYPE,
3196 get_identifier (UTAG_CLASS))),
3197 build1 (INDIRECT_REF, NULL_TREE, NULL_TREE)));
3199 /* Filling the "isa" in with one allows the runtime system to
3200 detect that the version change...should remove before final release. */
3202 expr = build_int_2 (PROTOCOL_VERSION, 0);
3203 TREE_TYPE (expr) = cast_type;
3204 initlist = tree_cons (NULL_TREE, expr, initlist);
3205 initlist = tree_cons (NULL_TREE, protocol_name, initlist);
3206 initlist = tree_cons (NULL_TREE, protocol_list, initlist);
3208 if (!instance_methods)
3209 initlist = tree_cons (NULL_TREE, build_int_2 (0, 0), initlist);
3212 expr = build_unary_op (ADDR_EXPR, instance_methods, 0);
3213 initlist = tree_cons (NULL_TREE, expr, initlist);
3217 initlist = tree_cons (NULL_TREE, build_int_2 (0, 0), initlist);
3220 expr = build_unary_op (ADDR_EXPR, class_methods, 0);
3221 initlist = tree_cons (NULL_TREE, expr, initlist);
3224 return build_constructor (type, nreverse (initlist));
3227 /* struct objc_category {
3228 char *category_name;
3230 struct objc_method_list *instance_methods;
3231 struct objc_method_list *class_methods;
3232 struct objc_protocol_list *protocols;
3236 build_category_template ()
3238 tree decl_specs, field_decl, field_decl_chain;
3240 objc_category_template = start_struct (RECORD_TYPE,
3241 get_identifier (UTAG_CATEGORY));
3242 /* char *category_name; */
3244 decl_specs = build_tree_list (NULL_TREE, ridpointers[(int) RID_CHAR]);
3246 = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("category_name"));
3248 = grokfield (input_filename, lineno, field_decl, decl_specs, NULL_TREE);
3249 field_decl_chain = field_decl;
3251 /* char *class_name; */
3253 decl_specs = build_tree_list (NULL_TREE, ridpointers[(int) RID_CHAR]);
3254 field_decl = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("class_name"));
3256 = grokfield (input_filename, lineno, field_decl, decl_specs, NULL_TREE);
3257 chainon (field_decl_chain, field_decl);
3259 /* struct objc_method_list *instance_methods; */
3261 decl_specs = build_tree_list (NULL_TREE,
3262 xref_tag (RECORD_TYPE,
3263 get_identifier (UTAG_METHOD_LIST)));
3265 = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("instance_methods"));
3267 = grokfield (input_filename, lineno, field_decl, decl_specs, NULL_TREE);
3268 chainon (field_decl_chain, field_decl);
3270 /* struct objc_method_list *class_methods; */
3272 decl_specs = build_tree_list (NULL_TREE,
3273 xref_tag (RECORD_TYPE,
3274 get_identifier (UTAG_METHOD_LIST)));
3276 = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("class_methods"));
3278 = grokfield (input_filename, lineno, field_decl, decl_specs, NULL_TREE);
3279 chainon (field_decl_chain, field_decl);
3281 /* struct objc_protocol **protocol_list; */
3283 decl_specs = build_tree_list (NULL_TREE,
3284 xref_tag (RECORD_TYPE,
3285 get_identifier (UTAG_PROTOCOL)));
3287 = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("protocol_list"));
3288 field_decl = build1 (INDIRECT_REF, NULL_TREE, field_decl);
3290 = grokfield (input_filename, lineno, field_decl, decl_specs, NULL_TREE);
3291 chainon (field_decl_chain, field_decl);
3293 finish_struct (objc_category_template, field_decl_chain, NULL_TREE);
3296 /* struct objc_selector {
3302 build_selector_template ()
3305 tree decl_specs, field_decl, field_decl_chain;
3307 objc_selector_template
3308 = start_struct (RECORD_TYPE, get_identifier (UTAG_SELECTOR));
3312 decl_specs = build_tree_list (NULL_TREE, ridpointers[(int) RID_VOID]);
3313 field_decl = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("sel_id"));
3315 = grokfield (input_filename, lineno, field_decl, decl_specs, NULL_TREE);
3316 field_decl_chain = field_decl;
3318 /* char *sel_type; */
3320 decl_specs = build_tree_list (NULL_TREE, ridpointers[(int) RID_CHAR]);
3321 field_decl = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("sel_type"));
3323 = grokfield (input_filename, lineno, field_decl, decl_specs, NULL_TREE);
3324 chainon (field_decl_chain, field_decl);
3326 finish_struct (objc_selector_template, field_decl_chain, NULL_TREE);
3329 /* struct objc_class {
3330 struct objc_class *isa;
3331 struct objc_class *super_class;
3336 struct objc_ivar_list *ivars;
3337 struct objc_method_list *methods;
3338 if (flag_next_runtime)
3339 struct objc_cache *cache;
3341 struct sarray *dtable;
3342 struct objc_class *subclass_list;
3343 struct objc_class *sibling_class;
3345 struct objc_protocol_list *protocols;
3346 void *gc_object_type;
3350 build_class_template ()
3352 tree decl_specs, field_decl, field_decl_chain;
3355 = start_struct (RECORD_TYPE, get_identifier (UTAG_CLASS));
3357 /* struct objc_class *isa; */
3359 decl_specs = build_tree_list (NULL_TREE, objc_class_template);
3360 field_decl = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("isa"));
3362 = grokfield (input_filename, lineno, field_decl, decl_specs, NULL_TREE);
3363 field_decl_chain = field_decl;
3365 /* struct objc_class *super_class; */
3367 decl_specs = build_tree_list (NULL_TREE, objc_class_template);
3369 = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("super_class"));
3371 = grokfield (input_filename, lineno, field_decl, decl_specs, NULL_TREE);
3372 chainon (field_decl_chain, field_decl);
3376 decl_specs = build_tree_list (NULL_TREE, ridpointers[(int) RID_CHAR]);
3377 field_decl = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("name"));
3379 = grokfield (input_filename, lineno, field_decl, decl_specs, NULL_TREE);
3380 chainon (field_decl_chain, field_decl);
3384 decl_specs = build_tree_list (NULL_TREE, ridpointers[(int) RID_LONG]);
3385 field_decl = get_identifier ("version");
3387 = grokfield (input_filename, lineno, field_decl, decl_specs, NULL_TREE);
3388 chainon (field_decl_chain, field_decl);
3392 decl_specs = build_tree_list (NULL_TREE, ridpointers[(int) RID_LONG]);
3393 field_decl = get_identifier ("info");
3395 = grokfield (input_filename, lineno, field_decl, decl_specs, NULL_TREE);
3396 chainon (field_decl_chain, field_decl);
3398 /* long instance_size; */
3400 decl_specs = build_tree_list (NULL_TREE, ridpointers[(int) RID_LONG]);
3401 field_decl = get_identifier ("instance_size");
3403 = grokfield (input_filename, lineno, field_decl, decl_specs, NULL_TREE);
3404 chainon (field_decl_chain, field_decl);
3406 /* struct objc_ivar_list *ivars; */
3408 decl_specs = build_tree_list (NULL_TREE,
3409 xref_tag (RECORD_TYPE,
3410 get_identifier (UTAG_IVAR_LIST)));
3411 field_decl = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("ivars"));
3413 = grokfield (input_filename, lineno, field_decl, decl_specs, NULL_TREE);
3414 chainon (field_decl_chain, field_decl);
3416 /* struct objc_method_list *methods; */
3418 decl_specs = build_tree_list (NULL_TREE,
3419 xref_tag (RECORD_TYPE,
3420 get_identifier (UTAG_METHOD_LIST)));
3421 field_decl = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("methods"));
3423 = grokfield (input_filename, lineno, field_decl, decl_specs, NULL_TREE);
3424 chainon (field_decl_chain, field_decl);
3426 if (flag_next_runtime)
3428 /* struct objc_cache *cache; */
3430 decl_specs = build_tree_list (NULL_TREE,
3431 xref_tag (RECORD_TYPE,
3432 get_identifier ("objc_cache")));
3433 field_decl = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("cache"));
3434 field_decl = grokfield (input_filename, lineno, field_decl,
3435 decl_specs, NULL_TREE);
3436 chainon (field_decl_chain, field_decl);
3440 /* struct sarray *dtable; */
3442 decl_specs = build_tree_list (NULL_TREE,
3443 xref_tag (RECORD_TYPE,
3444 get_identifier ("sarray")));
3445 field_decl = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("dtable"));
3446 field_decl = grokfield (input_filename, lineno, field_decl,
3447 decl_specs, NULL_TREE);
3448 chainon (field_decl_chain, field_decl);
3450 /* struct objc_class *subclass_list; */
3452 decl_specs = build_tree_list (NULL_TREE, objc_class_template);
3454 = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("subclass_list"));
3455 field_decl = grokfield (input_filename, lineno, field_decl,
3456 decl_specs, NULL_TREE);
3457 chainon (field_decl_chain, field_decl);
3459 /* struct objc_class *sibling_class; */
3461 decl_specs = build_tree_list (NULL_TREE, objc_class_template);
3463 = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("sibling_class"));
3464 field_decl = grokfield (input_filename, lineno, field_decl,
3465 decl_specs, NULL_TREE);
3466 chainon (field_decl_chain, field_decl);
3469 /* struct objc_protocol **protocol_list; */
3471 decl_specs = build_tree_list (NULL_TREE,
3472 xref_tag (RECORD_TYPE,
3473 get_identifier (UTAG_PROTOCOL)));
3475 = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("protocol_list"));
3477 = build1 (INDIRECT_REF, NULL_TREE, field_decl);
3478 field_decl = grokfield (input_filename, lineno, field_decl,
3479 decl_specs, NULL_TREE);
3480 chainon (field_decl_chain, field_decl);
3484 decl_specs = build_tree_list (NULL_TREE, ridpointers[(int) RID_VOID]);
3485 field_decl = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("sel_id"));
3487 = grokfield (input_filename, lineno, field_decl, decl_specs, NULL_TREE);
3488 chainon (field_decl_chain, field_decl);
3490 /* void *gc_object_type; */
3492 decl_specs = build_tree_list (NULL_TREE, ridpointers[(int) RID_VOID]);
3493 field_decl = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("gc_object_type"));
3495 = grokfield (input_filename, lineno, field_decl, decl_specs, NULL_TREE);
3496 chainon (field_decl_chain, field_decl);
3498 finish_struct (objc_class_template, field_decl_chain, NULL_TREE);
3501 /* Generate appropriate forward declarations for an implementation. */
3504 synth_forward_declarations ()
3506 tree sc_spec, decl_specs, an_id;
3508 /* extern struct objc_class _OBJC_CLASS_<my_name>; */
3510 an_id = synth_id_with_class_suffix ("_OBJC_CLASS", objc_implementation_context);
3512 sc_spec = build_tree_list (NULL_TREE, ridpointers[(int) RID_EXTERN]);
3513 decl_specs = tree_cons (NULL_TREE, objc_class_template, sc_spec);
3514 UOBJC_CLASS_decl = define_decl (an_id, decl_specs);
3515 TREE_USED (UOBJC_CLASS_decl) = 1;
3516 DECL_ARTIFICIAL (UOBJC_CLASS_decl) = 1;
3518 /* extern struct objc_class _OBJC_METACLASS_<my_name>; */
3520 an_id = synth_id_with_class_suffix ("_OBJC_METACLASS",
3521 objc_implementation_context);
3523 UOBJC_METACLASS_decl = define_decl (an_id, decl_specs);
3524 TREE_USED (UOBJC_METACLASS_decl) = 1;
3525 DECL_ARTIFICIAL(UOBJC_METACLASS_decl) = 1;
3527 /* Pre-build the following entities - for speed/convenience. */
3529 an_id = get_identifier ("super_class");
3530 ucls_super_ref = build_component_ref (UOBJC_CLASS_decl, an_id);
3531 uucls_super_ref = build_component_ref (UOBJC_METACLASS_decl, an_id);
3535 error_with_ivar (message, decl, rawdecl)
3536 const char *message;
3540 diagnostic_count_diagnostic (global_dc, DK_ERROR);
3542 diagnostic_report_current_function (global_dc);
3544 error_with_file_and_line (DECL_SOURCE_FILE (decl),
3545 DECL_SOURCE_LINE (decl),
3547 message, gen_declaration (rawdecl, errbuf));
3552 check_ivars (inter, imp)
3556 tree intdecls = CLASS_IVARS (inter);
3557 tree impdecls = CLASS_IVARS (imp);
3558 tree rawintdecls = CLASS_RAW_IVARS (inter);
3559 tree rawimpdecls = CLASS_RAW_IVARS (imp);
3565 if (intdecls == 0 && impdecls == 0)
3567 if (intdecls == 0 || impdecls == 0)
3569 error ("inconsistent instance variable specification");
3573 t1 = TREE_TYPE (intdecls); t2 = TREE_TYPE (impdecls);
3575 if (!comptypes (t1, t2))
3577 if (DECL_NAME (intdecls) == DECL_NAME (impdecls))
3579 error_with_ivar ("conflicting instance variable type",
3580 impdecls, rawimpdecls);
3581 error_with_ivar ("previous declaration of",
3582 intdecls, rawintdecls);
3584 else /* both the type and the name don't match */
3586 error ("inconsistent instance variable specification");
3591 else if (DECL_NAME (intdecls) != DECL_NAME (impdecls))
3593 error_with_ivar ("conflicting instance variable name",
3594 impdecls, rawimpdecls);
3595 error_with_ivar ("previous declaration of",
3596 intdecls, rawintdecls);
3599 intdecls = TREE_CHAIN (intdecls);
3600 impdecls = TREE_CHAIN (impdecls);
3601 rawintdecls = TREE_CHAIN (rawintdecls);
3602 rawimpdecls = TREE_CHAIN (rawimpdecls);
3606 /* Set super_type to the data type node for struct objc_super *,
3607 first defining struct objc_super itself.
3608 This needs to be done just once per compilation. */
3611 build_super_template ()
3613 tree record, decl_specs, field_decl, field_decl_chain;
3615 record = start_struct (RECORD_TYPE, get_identifier (UTAG_SUPER));
3617 /* struct objc_object *self; */
3619 decl_specs = build_tree_list (NULL_TREE, objc_object_reference);
3620 field_decl = get_identifier ("self");
3621 field_decl = build1 (INDIRECT_REF, NULL_TREE, field_decl);
3622 field_decl = grokfield (input_filename, lineno,
3623 field_decl, decl_specs, NULL_TREE);
3624 field_decl_chain = field_decl;
3626 /* struct objc_class *class; */
3628 decl_specs = get_identifier (UTAG_CLASS);
3629 decl_specs = build_tree_list (NULL_TREE, xref_tag (RECORD_TYPE, decl_specs));
3630 field_decl = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("class"));
3632 field_decl = grokfield (input_filename, lineno,
3633 field_decl, decl_specs, NULL_TREE);
3634 chainon (field_decl_chain, field_decl);
3636 finish_struct (record, field_decl_chain, NULL_TREE);
3638 /* `struct objc_super *' */
3639 super_type = groktypename (build_tree_list (build_tree_list (NULL_TREE,
3641 build1 (INDIRECT_REF,
3642 NULL_TREE, NULL_TREE)));
3646 /* struct objc_ivar {
3653 build_ivar_template ()
3655 tree objc_ivar_id, objc_ivar_record;
3656 tree decl_specs, field_decl, field_decl_chain;
3658 objc_ivar_id = get_identifier (UTAG_IVAR);
3659 objc_ivar_record = start_struct (RECORD_TYPE, objc_ivar_id);
3661 /* char *ivar_name; */
3663 decl_specs = build_tree_list (NULL_TREE, ridpointers[(int) RID_CHAR]);
3664 field_decl = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("ivar_name"));
3666 field_decl = grokfield (input_filename, lineno, field_decl,
3667 decl_specs, NULL_TREE);
3668 field_decl_chain = field_decl;
3670 /* char *ivar_type; */
3672 decl_specs = build_tree_list (NULL_TREE, ridpointers[(int) RID_CHAR]);
3673 field_decl = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("ivar_type"));
3675 field_decl = grokfield (input_filename, lineno, field_decl,
3676 decl_specs, NULL_TREE);
3677 chainon (field_decl_chain, field_decl);
3679 /* int ivar_offset; */
3681 decl_specs = build_tree_list (NULL_TREE, ridpointers[(int) RID_INT]);
3682 field_decl = get_identifier ("ivar_offset");
3684 field_decl = grokfield (input_filename, lineno, field_decl,
3685 decl_specs, NULL_TREE);
3686 chainon (field_decl_chain, field_decl);
3688 finish_struct (objc_ivar_record, field_decl_chain, NULL_TREE);
3690 return objc_ivar_record;
3695 struct objc_ivar ivar_list[ivar_count];
3699 build_ivar_list_template (list_type, size)
3703 tree objc_ivar_list_record;
3704 tree decl_specs, field_decl, field_decl_chain;
3706 objc_ivar_list_record = start_struct (RECORD_TYPE, NULL_TREE);
3708 /* int ivar_count; */
3710 decl_specs = build_tree_list (NULL_TREE, ridpointers[(int) RID_INT]);
3711 field_decl = get_identifier ("ivar_count");
3713 field_decl = grokfield (input_filename, lineno, field_decl,
3714 decl_specs, NULL_TREE);
3715 field_decl_chain = field_decl;
3717 /* struct objc_ivar ivar_list[]; */
3719 decl_specs = build_tree_list (NULL_TREE, list_type);
3720 field_decl = build_nt (ARRAY_REF, get_identifier ("ivar_list"),
3721 build_int_2 (size, 0));
3723 field_decl = grokfield (input_filename, lineno,
3724 field_decl, decl_specs, NULL_TREE);
3725 chainon (field_decl_chain, field_decl);
3727 finish_struct (objc_ivar_list_record, field_decl_chain, NULL_TREE);
3729 return objc_ivar_list_record;
3735 struct objc_method method_list[method_count];
3739 build_method_list_template (list_type, size)
3743 tree objc_ivar_list_record;
3744 tree decl_specs, field_decl, field_decl_chain;
3746 objc_ivar_list_record = start_struct (RECORD_TYPE, NULL_TREE);
3748 /* int method_next; */
3753 xref_tag (RECORD_TYPE,
3754 get_identifier (UTAG_METHOD_PROTOTYPE_LIST)));
3756 = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("method_next"));
3757 field_decl = grokfield (input_filename, lineno, field_decl,
3758 decl_specs, NULL_TREE);
3759 field_decl_chain = field_decl;
3761 /* int method_count; */
3763 decl_specs = build_tree_list (NULL_TREE, ridpointers[(int) RID_INT]);
3764 field_decl = get_identifier ("method_count");
3766 field_decl = grokfield (input_filename, lineno,
3767 field_decl, decl_specs, NULL_TREE);
3768 chainon (field_decl_chain, field_decl);
3770 /* struct objc_method method_list[]; */
3772 decl_specs = build_tree_list (NULL_TREE, list_type);
3773 field_decl = build_nt (ARRAY_REF, get_identifier ("method_list"),
3774 build_int_2 (size, 0));
3776 field_decl = grokfield (input_filename, lineno,
3777 field_decl, decl_specs, NULL_TREE);
3778 chainon (field_decl_chain, field_decl);
3780 finish_struct (objc_ivar_list_record, field_decl_chain, NULL_TREE);
3782 return objc_ivar_list_record;
3786 build_ivar_list_initializer (type, field_decl)
3790 tree initlist = NULL_TREE;
3794 tree ivar = NULL_TREE;
3797 if (DECL_NAME (field_decl))
3798 ivar = tree_cons (NULL_TREE,
3799 add_objc_string (DECL_NAME (field_decl),
3803 /* Unnamed bit-field ivar (yuck). */
3804 ivar = tree_cons (NULL_TREE, build_int_2 (0, 0), ivar);
3807 encode_field_decl (field_decl,
3808 obstack_object_size (&util_obstack),
3809 OBJC_ENCODE_DONT_INLINE_DEFS);
3811 /* Null terminate string. */
3812 obstack_1grow (&util_obstack, 0);
3816 add_objc_string (get_identifier (obstack_finish (&util_obstack)),
3819 obstack_free (&util_obstack, util_firstobj);
3822 ivar = tree_cons (NULL_TREE, byte_position (field_decl), ivar);
3823 initlist = tree_cons (NULL_TREE,
3824 build_constructor (type, nreverse (ivar)),
3827 field_decl = TREE_CHAIN (field_decl);
3831 return build_constructor (build_array_type (type, 0), nreverse (initlist));
3835 generate_ivars_list (type, name, size, list)
3841 tree sc_spec, decl_specs, decl, initlist;
3843 sc_spec = tree_cons (NULL_TREE, ridpointers[(int) RID_STATIC], NULL_TREE);
3844 decl_specs = tree_cons (NULL_TREE, type, sc_spec);
3846 decl = start_decl (synth_id_with_class_suffix (name, objc_implementation_context),
3847 decl_specs, 1, NULL_TREE);
3849 initlist = build_tree_list (NULL_TREE, build_int_2 (size, 0));
3850 initlist = tree_cons (NULL_TREE, list, initlist);
3853 build_constructor (TREE_TYPE (decl), nreverse (initlist)),
3860 generate_ivar_lists ()
3862 tree initlist, ivar_list_template, chain;
3863 tree cast, variable_length_type;
3866 generating_instance_variables = 1;
3868 if (!objc_ivar_template)
3869 objc_ivar_template = build_ivar_template ();
3873 (build_tree_list (NULL_TREE, xref_tag (RECORD_TYPE,
3874 get_identifier (UTAG_IVAR_LIST))),
3876 variable_length_type = groktypename (cast);
3878 /* Only generate class variables for the root of the inheritance
3879 hierarchy since these will be the same for every class. */
3881 if (CLASS_SUPER_NAME (implementation_template) == NULL_TREE
3882 && (chain = TYPE_FIELDS (objc_class_template)))
3884 size = list_length (chain);
3886 ivar_list_template = build_ivar_list_template (objc_ivar_template, size);
3887 initlist = build_ivar_list_initializer (objc_ivar_template, chain);
3889 UOBJC_CLASS_VARIABLES_decl
3890 = generate_ivars_list (ivar_list_template, "_OBJC_CLASS_VARIABLES",
3892 TREE_TYPE (UOBJC_CLASS_VARIABLES_decl) = variable_length_type;
3895 UOBJC_CLASS_VARIABLES_decl = 0;
3897 chain = CLASS_IVARS (implementation_template);
3900 size = list_length (chain);
3901 ivar_list_template = build_ivar_list_template (objc_ivar_template, size);
3902 initlist = build_ivar_list_initializer (objc_ivar_template, chain);
3904 UOBJC_INSTANCE_VARIABLES_decl
3905 = generate_ivars_list (ivar_list_template, "_OBJC_INSTANCE_VARIABLES",
3907 TREE_TYPE (UOBJC_INSTANCE_VARIABLES_decl) = variable_length_type;
3910 UOBJC_INSTANCE_VARIABLES_decl = 0;
3912 generating_instance_variables = 0;
3916 build_dispatch_table_initializer (type, entries)
3920 tree initlist = NULL_TREE;
3924 tree elemlist = NULL_TREE;
3926 elemlist = tree_cons (NULL_TREE,
3927 build_selector (METHOD_SEL_NAME (entries)),
3930 /* Generate the method encoding if we don't have one already. */
3931 if (! METHOD_ENCODING (entries))
3932 METHOD_ENCODING (entries) =
3933 encode_method_def (METHOD_DEFINITION (entries));
3935 elemlist = tree_cons (NULL_TREE,
3936 add_objc_string (METHOD_ENCODING (entries),
3940 elemlist = tree_cons (NULL_TREE,
3941 build_unary_op (ADDR_EXPR,
3942 METHOD_DEFINITION (entries), 1),
3945 initlist = tree_cons (NULL_TREE,
3946 build_constructor (type, nreverse (elemlist)),
3949 entries = TREE_CHAIN (entries);
3953 return build_constructor (build_array_type (type, 0), nreverse (initlist));
3956 /* To accomplish method prototyping without generating all kinds of
3957 inane warnings, the definition of the dispatch table entries were
3960 struct objc_method { SEL _cmd; ...; id (*_imp)(); };
3962 struct objc_method { SEL _cmd; ...; void *_imp; }; */
3965 build_method_template ()
3968 tree decl_specs, field_decl, field_decl_chain;
3970 _SLT_record = start_struct (RECORD_TYPE, get_identifier (UTAG_METHOD));
3972 /* struct objc_selector *_cmd; */
3973 decl_specs = tree_cons (NULL_TREE,
3974 xref_tag (RECORD_TYPE,
3975 get_identifier (TAG_SELECTOR)),
3977 field_decl = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("_cmd"));
3979 field_decl = grokfield (input_filename, lineno, field_decl,
3980 decl_specs, NULL_TREE);
3981 field_decl_chain = field_decl;
3983 decl_specs = tree_cons (NULL_TREE, ridpointers[(int) RID_CHAR], NULL_TREE);
3984 field_decl = build1 (INDIRECT_REF, NULL_TREE,
3985 get_identifier ("method_types"));
3986 field_decl = grokfield (input_filename, lineno, field_decl,
3987 decl_specs, NULL_TREE);
3988 chainon (field_decl_chain, field_decl);
3992 decl_specs = tree_cons (NULL_TREE, ridpointers[(int) RID_VOID], NULL_TREE);
3993 field_decl = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("_imp"));
3994 field_decl = grokfield (input_filename, lineno, field_decl,
3995 decl_specs, NULL_TREE);
3996 chainon (field_decl_chain, field_decl);
3998 finish_struct (_SLT_record, field_decl_chain, NULL_TREE);
4005 generate_dispatch_table (type, name, size, list)
4011 tree sc_spec, decl_specs, decl, initlist;
4013 sc_spec = tree_cons (NULL_TREE, ridpointers[(int) RID_STATIC], NULL_TREE);
4014 decl_specs = tree_cons (NULL_TREE, type, sc_spec);
4016 decl = start_decl (synth_id_with_class_suffix (name, objc_implementation_context),
4017 decl_specs, 1, NULL_TREE);
4019 initlist = build_tree_list (NULL_TREE, build_int_2 (0, 0));
4020 initlist = tree_cons (NULL_TREE, build_int_2 (size, 0), initlist);
4021 initlist = tree_cons (NULL_TREE, list, initlist);
4024 build_constructor (TREE_TYPE (decl), nreverse (initlist)),
4031 generate_dispatch_tables ()
4033 tree initlist, chain, method_list_template;
4034 tree cast, variable_length_type;
4037 if (!objc_method_template)
4038 objc_method_template = build_method_template ();
4042 (build_tree_list (NULL_TREE,
4043 xref_tag (RECORD_TYPE,
4044 get_identifier (UTAG_METHOD_LIST))),
4047 variable_length_type = groktypename (cast);
4049 chain = CLASS_CLS_METHODS (objc_implementation_context);
4052 size = list_length (chain);
4054 method_list_template
4055 = build_method_list_template (objc_method_template, size);
4057 = build_dispatch_table_initializer (objc_method_template, chain);
4059 UOBJC_CLASS_METHODS_decl
4060 = generate_dispatch_table (method_list_template,
4061 ((TREE_CODE (objc_implementation_context)
4062 == CLASS_IMPLEMENTATION_TYPE)
4063 ? "_OBJC_CLASS_METHODS"
4064 : "_OBJC_CATEGORY_CLASS_METHODS"),
4066 TREE_TYPE (UOBJC_CLASS_METHODS_decl) = variable_length_type;
4069 UOBJC_CLASS_METHODS_decl = 0;
4071 chain = CLASS_NST_METHODS (objc_implementation_context);
4074 size = list_length (chain);
4076 method_list_template
4077 = build_method_list_template (objc_method_template, size);
4079 = build_dispatch_table_initializer (objc_method_template, chain);
4081 if (TREE_CODE (objc_implementation_context) == CLASS_IMPLEMENTATION_TYPE)
4082 UOBJC_INSTANCE_METHODS_decl
4083 = generate_dispatch_table (method_list_template,
4084 "_OBJC_INSTANCE_METHODS",
4087 /* We have a category. */
4088 UOBJC_INSTANCE_METHODS_decl
4089 = generate_dispatch_table (method_list_template,
4090 "_OBJC_CATEGORY_INSTANCE_METHODS",
4092 TREE_TYPE (UOBJC_INSTANCE_METHODS_decl) = variable_length_type;
4095 UOBJC_INSTANCE_METHODS_decl = 0;
4099 generate_protocol_list (i_or_p)
4102 tree initlist, decl_specs, sc_spec;
4103 tree refs_decl, expr_decl, lproto, e, plist;
4107 if (TREE_CODE (i_or_p) == CLASS_INTERFACE_TYPE
4108 || TREE_CODE (i_or_p) == CATEGORY_INTERFACE_TYPE)
4109 plist = CLASS_PROTOCOL_LIST (i_or_p);
4110 else if (TREE_CODE (i_or_p) == PROTOCOL_INTERFACE_TYPE)
4111 plist = PROTOCOL_LIST (i_or_p);
4115 cast_type = groktypename
4117 (build_tree_list (NULL_TREE,
4118 xref_tag (RECORD_TYPE,
4119 get_identifier (UTAG_PROTOCOL))),
4120 build1 (INDIRECT_REF, NULL_TREE, NULL_TREE)));
4123 for (lproto = plist; lproto; lproto = TREE_CHAIN (lproto))
4124 if (TREE_CODE (TREE_VALUE (lproto)) == PROTOCOL_INTERFACE_TYPE
4125 && PROTOCOL_FORWARD_DECL (TREE_VALUE (lproto)))
4128 /* Build initializer. */
4129 initlist = tree_cons (NULL_TREE, build_int_2 (0, 0), NULL_TREE);
4131 e = build_int_2 (size, 0);
4132 TREE_TYPE (e) = cast_type;
4133 initlist = tree_cons (NULL_TREE, e, initlist);
4135 for (lproto = plist; lproto; lproto = TREE_CHAIN (lproto))
4137 tree pval = TREE_VALUE (lproto);
4139 if (TREE_CODE (pval) == PROTOCOL_INTERFACE_TYPE
4140 && PROTOCOL_FORWARD_DECL (pval))
4142 e = build_unary_op (ADDR_EXPR, PROTOCOL_FORWARD_DECL (pval), 0);
4143 initlist = tree_cons (NULL_TREE, e, initlist);
4147 /* static struct objc_protocol *refs[n]; */
4149 sc_spec = tree_cons (NULL_TREE, ridpointers[(int) RID_STATIC], NULL_TREE);
4150 decl_specs = tree_cons (NULL_TREE, xref_tag (RECORD_TYPE,
4151 get_identifier (UTAG_PROTOCOL)),
4154 if (TREE_CODE (i_or_p) == PROTOCOL_INTERFACE_TYPE)
4155 expr_decl = build_nt (ARRAY_REF,
4156 synth_id_with_class_suffix ("_OBJC_PROTOCOL_REFS",
4158 build_int_2 (size + 2, 0));
4159 else if (TREE_CODE (i_or_p) == CLASS_INTERFACE_TYPE)
4160 expr_decl = build_nt (ARRAY_REF,
4161 synth_id_with_class_suffix ("_OBJC_CLASS_PROTOCOLS",
4163 build_int_2 (size + 2, 0));
4164 else if (TREE_CODE (i_or_p) == CATEGORY_INTERFACE_TYPE)
4166 = build_nt (ARRAY_REF,
4167 synth_id_with_class_suffix ("_OBJC_CATEGORY_PROTOCOLS",
4169 build_int_2 (size + 2, 0));
4173 expr_decl = build1 (INDIRECT_REF, NULL_TREE, expr_decl);
4175 refs_decl = start_decl (expr_decl, decl_specs, 1, NULL_TREE);
4176 DECL_CONTEXT (refs_decl) = NULL_TREE;
4178 finish_decl (refs_decl, build_constructor (TREE_TYPE (refs_decl),
4179 nreverse (initlist)),
4186 build_category_initializer (type, cat_name, class_name,
4187 instance_methods, class_methods, protocol_list)
4191 tree instance_methods;
4195 tree initlist = NULL_TREE, expr;
4197 initlist = tree_cons (NULL_TREE, cat_name, initlist);
4198 initlist = tree_cons (NULL_TREE, class_name, initlist);
4200 if (!instance_methods)
4201 initlist = tree_cons (NULL_TREE, build_int_2 (0, 0), initlist);
4204 expr = build_unary_op (ADDR_EXPR, instance_methods, 0);
4205 initlist = tree_cons (NULL_TREE, expr, initlist);
4208 initlist = tree_cons (NULL_TREE, build_int_2 (0, 0), initlist);
4211 expr = build_unary_op (ADDR_EXPR, class_methods, 0);
4212 initlist = tree_cons (NULL_TREE, expr, initlist);
4215 /* protocol_list = */
4217 initlist = tree_cons (NULL_TREE, build_int_2 (0, 0), initlist);
4220 tree cast_type2 = groktypename
4222 (build_tree_list (NULL_TREE,
4223 xref_tag (RECORD_TYPE,
4224 get_identifier (UTAG_PROTOCOL))),
4225 build1 (INDIRECT_REF, NULL_TREE,
4226 build1 (INDIRECT_REF, NULL_TREE, NULL_TREE))));
4228 expr = build_unary_op (ADDR_EXPR, protocol_list, 0);
4229 TREE_TYPE (expr) = cast_type2;
4230 initlist = tree_cons (NULL_TREE, expr, initlist);
4233 return build_constructor (type, nreverse (initlist));
4236 /* struct objc_class {
4237 struct objc_class *isa;
4238 struct objc_class *super_class;
4243 struct objc_ivar_list *ivars;
4244 struct objc_method_list *methods;
4245 if (flag_next_runtime)
4246 struct objc_cache *cache;
4248 struct sarray *dtable;
4249 struct objc_class *subclass_list;
4250 struct objc_class *sibling_class;
4252 struct objc_protocol_list *protocols;
4253 void *gc_object_type;
4257 build_shared_structure_initializer (type, isa, super, name, size, status,
4258 dispatch_table, ivar_list, protocol_list)
4265 tree dispatch_table;
4269 tree initlist = NULL_TREE, expr;
4272 initlist = tree_cons (NULL_TREE, isa, initlist);
4275 initlist = tree_cons (NULL_TREE, super, initlist);
4278 initlist = tree_cons (NULL_TREE, default_conversion (name), initlist);
4281 initlist = tree_cons (NULL_TREE, build_int_2 (0, 0), initlist);
4284 initlist = tree_cons (NULL_TREE, build_int_2 (status, 0), initlist);
4286 /* instance_size = */
4287 initlist = tree_cons (NULL_TREE, size, initlist);
4289 /* objc_ivar_list = */
4291 initlist = tree_cons (NULL_TREE, build_int_2 (0, 0), initlist);
4294 expr = build_unary_op (ADDR_EXPR, ivar_list, 0);
4295 initlist = tree_cons (NULL_TREE, expr, initlist);
4298 /* objc_method_list = */
4299 if (!dispatch_table)
4300 initlist = tree_cons (NULL_TREE, build_int_2 (0, 0), initlist);
4303 expr = build_unary_op (ADDR_EXPR, dispatch_table, 0);
4304 initlist = tree_cons (NULL_TREE, expr, initlist);
4307 if (flag_next_runtime)
4308 /* method_cache = */
4309 initlist = tree_cons (NULL_TREE, build_int_2 (0, 0), initlist);
4313 initlist = tree_cons (NULL_TREE, build_int_2 (0, 0), initlist);
4315 /* subclass_list = */
4316 initlist = tree_cons (NULL_TREE, build_int_2 (0, 0), initlist);
4318 /* sibling_class = */
4319 initlist = tree_cons (NULL_TREE, build_int_2 (0, 0), initlist);
4322 /* protocol_list = */
4323 if (! protocol_list)
4324 initlist = tree_cons (NULL_TREE, build_int_2 (0, 0), initlist);
4330 (build_tree_list (NULL_TREE,
4331 xref_tag (RECORD_TYPE,
4332 get_identifier (UTAG_PROTOCOL))),
4333 build1 (INDIRECT_REF, NULL_TREE,
4334 build1 (INDIRECT_REF, NULL_TREE, NULL_TREE))));
4336 expr = build_unary_op (ADDR_EXPR, protocol_list, 0);
4337 TREE_TYPE (expr) = cast_type2;
4338 initlist = tree_cons (NULL_TREE, expr, initlist);
4341 /* gc_object_type = NULL */
4342 initlist = tree_cons (NULL_TREE, build_int_2 (0, 0), initlist);
4344 return build_constructor (type, nreverse (initlist));
4347 /* static struct objc_category _OBJC_CATEGORY_<name> = { ... }; */
4350 generate_category (cat)
4353 tree sc_spec, decl_specs, decl;
4354 tree initlist, cat_name_expr, class_name_expr;
4355 tree protocol_decl, category;
4357 add_class_reference (CLASS_NAME (cat));
4358 cat_name_expr = add_objc_string (CLASS_SUPER_NAME (cat), class_names);
4360 class_name_expr = add_objc_string (CLASS_NAME (cat), class_names);
4362 category = CLASS_CATEGORY_LIST (implementation_template);
4364 /* find the category interface from the class it is associated with */
4367 if (CLASS_SUPER_NAME (cat) == CLASS_SUPER_NAME (category))
4369 category = CLASS_CATEGORY_LIST (category);
4372 if (category && CLASS_PROTOCOL_LIST (category))
4374 generate_protocol_references (CLASS_PROTOCOL_LIST (category));
4375 protocol_decl = generate_protocol_list (category);
4380 sc_spec = tree_cons (NULL_TREE, ridpointers[(int) RID_STATIC], NULL_TREE);
4381 decl_specs = tree_cons (NULL_TREE, objc_category_template, sc_spec);
4383 decl = start_decl (synth_id_with_class_suffix ("_OBJC_CATEGORY",
4384 objc_implementation_context),
4385 decl_specs, 1, NULL_TREE);
4387 initlist = build_category_initializer (TREE_TYPE (decl),
4388 cat_name_expr, class_name_expr,
4389 UOBJC_INSTANCE_METHODS_decl,
4390 UOBJC_CLASS_METHODS_decl,
4393 TREE_USED (decl) = 1;
4394 finish_decl (decl, initlist, NULL_TREE);
4397 /* static struct objc_class _OBJC_METACLASS_Foo={ ... };
4398 static struct objc_class _OBJC_CLASS_Foo={ ... }; */
4401 generate_shared_structures ()
4403 tree sc_spec, decl_specs, decl;
4404 tree name_expr, super_expr, root_expr;
4405 tree my_root_id = NULL_TREE, my_super_id = NULL_TREE;
4406 tree cast_type, initlist, protocol_decl;
4408 my_super_id = CLASS_SUPER_NAME (implementation_template);
4411 add_class_reference (my_super_id);
4413 /* Compute "my_root_id" - this is required for code generation.
4414 the "isa" for all meta class structures points to the root of
4415 the inheritance hierarchy (e.g. "__Object")... */
4416 my_root_id = my_super_id;
4419 tree my_root_int = lookup_interface (my_root_id);
4421 if (my_root_int && CLASS_SUPER_NAME (my_root_int))
4422 my_root_id = CLASS_SUPER_NAME (my_root_int);
4429 /* No super class. */
4430 my_root_id = CLASS_NAME (implementation_template);
4433 = groktypename (build_tree_list (build_tree_list (NULL_TREE,
4434 objc_class_template),
4435 build1 (INDIRECT_REF,
4436 NULL_TREE, NULL_TREE)));
4438 name_expr = add_objc_string (CLASS_NAME (implementation_template),
4441 /* Install class `isa' and `super' pointers at runtime. */
4444 super_expr = add_objc_string (my_super_id, class_names);
4445 super_expr = build_c_cast (cast_type, super_expr); /* cast! */
4448 super_expr = build_int_2 (0, 0);
4450 root_expr = add_objc_string (my_root_id, class_names);
4451 root_expr = build_c_cast (cast_type, root_expr); /* cast! */
4453 if (CLASS_PROTOCOL_LIST (implementation_template))
4455 generate_protocol_references
4456 (CLASS_PROTOCOL_LIST (implementation_template));
4457 protocol_decl = generate_protocol_list (implementation_template);
4462 /* static struct objc_class _OBJC_METACLASS_Foo = { ... }; */
4464 sc_spec = build_tree_list (NULL_TREE, ridpointers[(int) RID_STATIC]);
4465 decl_specs = tree_cons (NULL_TREE, objc_class_template, sc_spec);
4467 decl = start_decl (DECL_NAME (UOBJC_METACLASS_decl), decl_specs, 1,
4471 = build_shared_structure_initializer
4473 root_expr, super_expr, name_expr,
4474 convert (integer_type_node, TYPE_SIZE_UNIT (objc_class_template)),
4476 UOBJC_CLASS_METHODS_decl,
4477 UOBJC_CLASS_VARIABLES_decl,
4480 finish_decl (decl, initlist, NULL_TREE);
4482 /* static struct objc_class _OBJC_CLASS_Foo={ ... }; */
4484 decl = start_decl (DECL_NAME (UOBJC_CLASS_decl), decl_specs, 1,
4488 = build_shared_structure_initializer
4490 build_unary_op (ADDR_EXPR, UOBJC_METACLASS_decl, 0),
4491 super_expr, name_expr,
4492 convert (integer_type_node,
4493 TYPE_SIZE_UNIT (CLASS_STATIC_TEMPLATE
4494 (implementation_template))),
4496 UOBJC_INSTANCE_METHODS_decl,
4497 UOBJC_INSTANCE_VARIABLES_decl,
4500 finish_decl (decl, initlist, NULL_TREE);
4504 synth_id_with_class_suffix (preamble, ctxt)
4505 const char *preamble;
4509 if (TREE_CODE (ctxt) == CLASS_IMPLEMENTATION_TYPE
4510 || TREE_CODE (ctxt) == CLASS_INTERFACE_TYPE)
4512 const char *const class_name
4513 = IDENTIFIER_POINTER (CLASS_NAME (objc_implementation_context));
4514 string = (char *) alloca (strlen (preamble) + strlen (class_name) + 3);
4515 sprintf (string, "%s_%s", preamble,
4516 IDENTIFIER_POINTER (CLASS_NAME (ctxt)));
4518 else if (TREE_CODE (ctxt) == CATEGORY_IMPLEMENTATION_TYPE
4519 || TREE_CODE (ctxt) == CATEGORY_INTERFACE_TYPE)
4521 /* We have a category. */
4522 const char *const class_name
4523 = IDENTIFIER_POINTER (CLASS_NAME (objc_implementation_context));
4524 const char *const class_super_name
4525 = IDENTIFIER_POINTER (CLASS_SUPER_NAME (objc_implementation_context));
4526 string = (char *) alloca (strlen (preamble)
4527 + strlen (class_name)
4528 + strlen (class_super_name)
4530 sprintf (string, "%s_%s_%s", preamble, class_name, class_super_name);
4532 else if (TREE_CODE (ctxt) == PROTOCOL_INTERFACE_TYPE)
4534 const char *protocol_name = IDENTIFIER_POINTER (PROTOCOL_NAME (ctxt));
4536 = (char *) alloca (strlen (preamble) + strlen (protocol_name) + 3);
4537 sprintf (string, "%s_%s", preamble, protocol_name);
4542 return get_identifier (string);
4546 is_objc_type_qualifier (node)
4549 return (TREE_CODE (node) == IDENTIFIER_NODE
4550 && (node == ridpointers [(int) RID_CONST]
4551 || node == ridpointers [(int) RID_VOLATILE]
4552 || node == ridpointers [(int) RID_IN]
4553 || node == ridpointers [(int) RID_OUT]
4554 || node == ridpointers [(int) RID_INOUT]
4555 || node == ridpointers [(int) RID_BYCOPY]
4556 || node == ridpointers [(int) RID_BYREF]
4557 || node == ridpointers [(int) RID_ONEWAY]));
4560 /* If type is empty or only type qualifiers are present, add default
4561 type of id (otherwise grokdeclarator will default to int). */
4564 adjust_type_for_id_default (type)
4567 tree declspecs, chain;
4570 return build_tree_list (build_tree_list (NULL_TREE, objc_object_reference),
4571 build1 (INDIRECT_REF, NULL_TREE, NULL_TREE));
4573 declspecs = TREE_PURPOSE (type);
4575 /* Determine if a typespec is present. */
4576 for (chain = declspecs;
4578 chain = TREE_CHAIN (chain))
4580 if (TYPED_OBJECT (TREE_VALUE (chain))
4581 && !(TREE_VALUE (type)
4582 && TREE_CODE (TREE_VALUE (type)) == INDIRECT_REF))
4583 error ("can not use an object as parameter to a method\n");
4584 if (!is_objc_type_qualifier (TREE_VALUE (chain)))
4588 return build_tree_list (tree_cons (NULL_TREE, objc_object_reference,
4590 build1 (INDIRECT_REF, NULL_TREE, NULL_TREE));
4595 selector ':' '(' typename ')' identifier
4598 Transform an Objective-C keyword argument into
4599 the C equivalent parameter declarator.
4601 In: key_name, an "identifier_node" (optional).
4602 arg_type, a "tree_list" (optional).
4603 arg_name, an "identifier_node".
4605 Note: It would be really nice to strongly type the preceding
4606 arguments in the function prototype; however, then I
4607 could not use the "accessor" macros defined in "tree.h".
4609 Out: an instance of "keyword_decl". */
4612 build_keyword_decl (key_name, arg_type, arg_name)
4619 /* If no type is specified, default to "id". */
4620 arg_type = adjust_type_for_id_default (arg_type);
4622 keyword_decl = make_node (KEYWORD_DECL);
4624 TREE_TYPE (keyword_decl) = arg_type;
4625 KEYWORD_ARG_NAME (keyword_decl) = arg_name;
4626 KEYWORD_KEY_NAME (keyword_decl) = key_name;
4628 return keyword_decl;
4631 /* Given a chain of keyword_decl's, synthesize the full keyword selector. */
4634 build_keyword_selector (selector)
4638 tree key_chain, key_name;
4641 /* Scan the selector to see how much space we'll need. */
4642 for (key_chain = selector; key_chain; key_chain = TREE_CHAIN (key_chain))
4644 if (TREE_CODE (selector) == KEYWORD_DECL)
4645 key_name = KEYWORD_KEY_NAME (key_chain);
4646 else if (TREE_CODE (selector) == TREE_LIST)
4647 key_name = TREE_PURPOSE (key_chain);
4652 len += IDENTIFIER_LENGTH (key_name) + 1;
4654 /* Just a ':' arg. */
4658 buf = (char *) alloca (len + 1);
4659 /* Start the buffer out as an empty string. */
4662 for (key_chain = selector; key_chain; key_chain = TREE_CHAIN (key_chain))
4664 if (TREE_CODE (selector) == KEYWORD_DECL)
4665 key_name = KEYWORD_KEY_NAME (key_chain);
4666 else if (TREE_CODE (selector) == TREE_LIST)
4667 key_name = TREE_PURPOSE (key_chain);
4672 strcat (buf, IDENTIFIER_POINTER (key_name));
4676 return get_identifier (buf);
4679 /* Used for declarations and definitions. */
4682 build_method_decl (code, ret_type, selector, add_args)
4683 enum tree_code code;
4690 /* If no type is specified, default to "id". */
4691 ret_type = adjust_type_for_id_default (ret_type);
4693 method_decl = make_node (code);
4694 TREE_TYPE (method_decl) = ret_type;
4696 /* If we have a keyword selector, create an identifier_node that
4697 represents the full selector name (`:' included)... */
4698 if (TREE_CODE (selector) == KEYWORD_DECL)
4700 METHOD_SEL_NAME (method_decl) = build_keyword_selector (selector);
4701 METHOD_SEL_ARGS (method_decl) = selector;
4702 METHOD_ADD_ARGS (method_decl) = add_args;
4706 METHOD_SEL_NAME (method_decl) = selector;
4707 METHOD_SEL_ARGS (method_decl) = NULL_TREE;
4708 METHOD_ADD_ARGS (method_decl) = NULL_TREE;
4714 #define METHOD_DEF 0
4715 #define METHOD_REF 1
4717 /* Used by `build_objc_method_call' and `comp_method_types'. Return
4718 an argument list for method METH. CONTEXT is either METHOD_DEF or
4719 METHOD_REF, saying whether we are trying to define a method or call
4720 one. SUPERFLAG says this is for a send to super; this makes a
4721 difference for the NeXT calling sequence in which the lookup and
4722 the method call are done together. */
4725 get_arg_type_list (meth, context, superflag)
4732 /* Receiver type. */
4733 if (flag_next_runtime && superflag)
4734 arglist = build_tree_list (NULL_TREE, super_type);
4735 else if (context == METHOD_DEF)
4736 arglist = build_tree_list (NULL_TREE, TREE_TYPE (self_decl));
4738 arglist = build_tree_list (NULL_TREE, id_type);
4740 /* Selector type - will eventually change to `int'. */
4741 chainon (arglist, build_tree_list (NULL_TREE, selector_type));
4743 /* Build a list of argument types. */
4744 for (akey = METHOD_SEL_ARGS (meth); akey; akey = TREE_CHAIN (akey))
4746 tree arg_decl = groktypename_in_parm_context (TREE_TYPE (akey));
4747 chainon (arglist, build_tree_list (NULL_TREE, TREE_TYPE (arg_decl)));
4750 if (METHOD_ADD_ARGS (meth) == objc_ellipsis_node)
4751 /* We have a `, ...' immediately following the selector,
4752 finalize the arglist...simulate get_parm_info (0). */
4754 else if (METHOD_ADD_ARGS (meth))
4756 /* we have a variable length selector */
4757 tree add_arg_list = TREE_CHAIN (METHOD_ADD_ARGS (meth));
4758 chainon (arglist, add_arg_list);
4761 /* finalize the arglist...simulate get_parm_info (1) */
4762 chainon (arglist, build_tree_list (NULL_TREE, void_type_node));
4768 check_duplicates (hsh)
4771 tree meth = NULL_TREE;
4779 /* We have two methods with the same name and different types. */
4781 char type = (TREE_CODE (meth) == INSTANCE_METHOD_DECL) ? '-' : '+';
4783 warning ("multiple declarations for method `%s'",
4784 IDENTIFIER_POINTER (METHOD_SEL_NAME (meth)));
4786 warn_with_method ("using", type, meth);
4787 for (loop = hsh->list; loop; loop = loop->next)
4788 warn_with_method ("also found", type, loop->value);
4794 /* If RECEIVER is a class reference, return the identifier node for
4795 the referenced class. RECEIVER is created by get_class_reference,
4796 so we check the exact form created depending on which runtimes are
4800 receiver_is_class_object (receiver)
4803 tree chain, exp, arg;
4805 /* The receiver is 'self' in the context of a class method. */
4806 if (objc_method_context
4807 && receiver == self_decl
4808 && TREE_CODE (objc_method_context) == CLASS_METHOD_DECL)
4810 return CLASS_NAME (objc_implementation_context);
4813 if (flag_next_runtime)
4815 /* The receiver is a variable created by
4816 build_class_reference_decl. */
4817 if (TREE_CODE (receiver) == VAR_DECL
4818 && TREE_TYPE (receiver) == objc_class_type)
4819 /* Look up the identifier. */
4820 for (chain = cls_ref_chain; chain; chain = TREE_CHAIN (chain))
4821 if (TREE_PURPOSE (chain) == receiver)
4822 return TREE_VALUE (chain);
4826 /* The receiver is a function call that returns an id. Check if
4827 it is a call to objc_getClass, if so, pick up the class name. */
4828 if (TREE_CODE (receiver) == CALL_EXPR
4829 && (exp = TREE_OPERAND (receiver, 0))
4830 && TREE_CODE (exp) == ADDR_EXPR
4831 && (exp = TREE_OPERAND (exp, 0))
4832 && TREE_CODE (exp) == FUNCTION_DECL
4833 && exp == objc_get_class_decl
4834 /* We have a call to objc_getClass! */
4835 && (arg = TREE_OPERAND (receiver, 1))
4836 && TREE_CODE (arg) == TREE_LIST
4837 && (arg = TREE_VALUE (arg)))
4840 if (TREE_CODE (arg) == ADDR_EXPR
4841 && (arg = TREE_OPERAND (arg, 0))
4842 && TREE_CODE (arg) == STRING_CST)
4843 /* Finally, we have the class name. */
4844 return get_identifier (TREE_STRING_POINTER (arg));
4850 /* If we are currently building a message expr, this holds
4851 the identifier of the selector of the message. This is
4852 used when printing warnings about argument mismatches. */
4854 static tree current_objc_message_selector = 0;
4857 objc_message_selector ()
4859 return current_objc_message_selector;
4862 /* Construct an expression for sending a message.
4863 MESS has the object to send to in TREE_PURPOSE
4864 and the argument list (including selector) in TREE_VALUE.
4866 (*(<abstract_decl>(*)())_msg)(receiver, selTransTbl[n], ...);
4867 (*(<abstract_decl>(*)())_msgSuper)(receiver, selTransTbl[n], ...); */
4870 build_message_expr (mess)
4873 tree receiver = TREE_PURPOSE (mess);
4875 tree args = TREE_VALUE (mess);
4876 tree method_params = NULL_TREE;
4878 if (TREE_CODE (receiver) == ERROR_MARK)
4879 return error_mark_node;
4881 /* Obtain the full selector name. */
4882 if (TREE_CODE (args) == IDENTIFIER_NODE)
4883 /* A unary selector. */
4885 else if (TREE_CODE (args) == TREE_LIST)
4886 sel_name = build_keyword_selector (args);
4890 /* Build the parameter list to give to the method. */
4891 if (TREE_CODE (args) == TREE_LIST)
4893 tree chain = args, prev = NULL_TREE;
4895 /* We have a keyword selector--check for comma expressions. */
4898 tree element = TREE_VALUE (chain);
4900 /* We have a comma expression, must collapse... */
4901 if (TREE_CODE (element) == TREE_LIST)
4904 TREE_CHAIN (prev) = element;
4909 chain = TREE_CHAIN (chain);
4911 method_params = args;
4914 return finish_message_expr (receiver, sel_name, method_params);
4917 /* The 'finish_message_expr' routine is called from within
4918 'build_message_expr' for non-template functions. In the case of
4919 C++ template functions, it is called from 'build_expr_from_tree'
4920 (in decl2.c) after RECEIVER and METHOD_PARAMS have been expanded. */
4923 finish_message_expr (receiver, sel_name, method_params)
4924 tree receiver, sel_name, method_params;
4926 tree method_prototype = NULL_TREE, class_ident = NULL_TREE;
4927 tree selector, self_object, retval;
4928 int statically_typed = 0, statically_allocated = 0;
4930 /* Determine receiver type. */
4931 tree rtype = TREE_TYPE (receiver);
4932 int super = IS_SUPER (rtype);
4936 if (TREE_STATIC_TEMPLATE (rtype))
4937 statically_allocated = 1;
4938 else if (TREE_CODE (rtype) == POINTER_TYPE
4939 && TREE_STATIC_TEMPLATE (TREE_TYPE (rtype)))
4940 statically_typed = 1;
4941 else if ((flag_next_runtime
4943 && (class_ident = receiver_is_class_object (receiver)))
4945 else if (! IS_ID (rtype)
4946 /* Allow any type that matches objc_class_type. */
4947 && ! comptypes (rtype, objc_class_type))
4949 warning ("invalid receiver type `%s'",
4950 gen_declaration (rtype, errbuf));
4952 if (statically_allocated)
4953 receiver = build_unary_op (ADDR_EXPR, receiver, 0);
4955 /* Don't evaluate the receiver twice. */
4956 receiver = save_expr (receiver);
4957 self_object = receiver;
4960 /* If sending to `super', use current self as the object. */
4961 self_object = self_decl;
4963 /* Determine operation return type. */
4969 if (CLASS_SUPER_NAME (implementation_template))
4972 = lookup_interface (CLASS_SUPER_NAME (implementation_template));
4974 if (TREE_CODE (objc_method_context) == INSTANCE_METHOD_DECL)
4975 method_prototype = lookup_instance_method_static (iface, sel_name);
4977 method_prototype = lookup_class_method_static (iface, sel_name);
4979 if (iface && !method_prototype)
4980 warning ("`%s' does not respond to `%s'",
4981 IDENTIFIER_POINTER (CLASS_SUPER_NAME (implementation_template)),
4982 IDENTIFIER_POINTER (sel_name));
4986 error ("no super class declared in interface for `%s'",
4987 IDENTIFIER_POINTER (CLASS_NAME (implementation_template)));
4988 return error_mark_node;
4992 else if (statically_allocated)
4994 tree ctype = TREE_TYPE (rtype);
4995 tree iface = lookup_interface (TYPE_NAME (rtype));
4998 method_prototype = lookup_instance_method_static (iface, sel_name);
5000 if (! method_prototype && ctype && TYPE_PROTOCOL_LIST (ctype))
5002 = lookup_method_in_protocol_list (TYPE_PROTOCOL_LIST (ctype),
5005 if (!method_prototype)
5006 warning ("`%s' does not respond to `%s'",
5007 IDENTIFIER_POINTER (TYPE_NAME (rtype)),
5008 IDENTIFIER_POINTER (sel_name));
5010 else if (statically_typed)
5012 tree ctype = TREE_TYPE (rtype);
5014 /* `self' is now statically_typed. All methods should be visible
5015 within the context of the implementation. */
5016 if (objc_implementation_context
5017 && CLASS_NAME (objc_implementation_context) == TYPE_NAME (ctype))
5020 = lookup_instance_method_static (implementation_template,
5023 if (! method_prototype && TYPE_PROTOCOL_LIST (ctype))
5025 = lookup_method_in_protocol_list (TYPE_PROTOCOL_LIST (ctype),
5028 if (! method_prototype
5029 && implementation_template != objc_implementation_context)
5030 /* The method is not published in the interface. Check
5033 = lookup_method (CLASS_NST_METHODS (objc_implementation_context),
5040 if ((iface = lookup_interface (TYPE_NAME (ctype))))
5041 method_prototype = lookup_instance_method_static (iface, sel_name);
5043 if (! method_prototype)
5045 tree protocol_list = TYPE_PROTOCOL_LIST (ctype);
5048 = lookup_method_in_protocol_list (protocol_list,
5053 if (!method_prototype)
5054 warning ("`%s' does not respond to `%s'",
5055 IDENTIFIER_POINTER (TYPE_NAME (ctype)),
5056 IDENTIFIER_POINTER (sel_name));
5058 else if (class_ident)
5060 if (objc_implementation_context
5061 && CLASS_NAME (objc_implementation_context) == class_ident)
5064 = lookup_class_method_static (implementation_template, sel_name);
5066 if (!method_prototype
5067 && implementation_template != objc_implementation_context)
5068 /* The method is not published in the interface. Check
5071 = lookup_method (CLASS_CLS_METHODS (objc_implementation_context),
5078 if ((iface = lookup_interface (class_ident)))
5079 method_prototype = lookup_class_method_static (iface, sel_name);
5082 if (!method_prototype)
5084 warning ("cannot find class (factory) method");
5085 warning ("return type for `%s' defaults to id",
5086 IDENTIFIER_POINTER (sel_name));
5089 else if (IS_PROTOCOL_QUALIFIED_ID (rtype))
5091 /* An anonymous object that has been qualified with a protocol. */
5093 tree protocol_list = TYPE_PROTOCOL_LIST (rtype);
5095 method_prototype = lookup_method_in_protocol_list (protocol_list,
5098 if (!method_prototype)
5102 warning ("method `%s' not implemented by protocol",
5103 IDENTIFIER_POINTER (sel_name));
5105 /* Try and find the method signature in the global pools. */
5107 if (!(hsh = hash_lookup (nst_method_hash_list, sel_name)))
5108 hsh = hash_lookup (cls_method_hash_list, sel_name);
5110 if (!(method_prototype = check_duplicates (hsh)))
5111 warning ("return type defaults to id");
5118 /* We think we have an instance...loophole: extern id Object; */
5119 hsh = hash_lookup (nst_method_hash_list, sel_name);
5122 /* For various loopholes */
5123 hsh = hash_lookup (cls_method_hash_list, sel_name);
5125 method_prototype = check_duplicates (hsh);
5126 if (!method_prototype)
5128 warning ("cannot find method");
5129 warning ("return type for `%s' defaults to id",
5130 IDENTIFIER_POINTER (sel_name));
5134 /* Save the selector name for printing error messages. */
5135 current_objc_message_selector = sel_name;
5137 /* Build the parameters list for looking up the method.
5138 These are the object itself and the selector. */
5140 if (flag_typed_selectors)
5141 selector = build_typed_selector_reference (sel_name, method_prototype);
5143 selector = build_selector_reference (sel_name);
5145 retval = build_objc_method_call (super, method_prototype,
5146 receiver, self_object,
5147 selector, method_params);
5149 current_objc_message_selector = 0;
5154 /* Build a tree expression to send OBJECT the operation SELECTOR,
5155 looking up the method on object LOOKUP_OBJECT (often same as OBJECT),
5156 assuming the method has prototype METHOD_PROTOTYPE.
5157 (That is an INSTANCE_METHOD_DECL or CLASS_METHOD_DECL.)
5158 Use METHOD_PARAMS as list of args to pass to the method.
5159 If SUPER_FLAG is nonzero, we look up the superclass's method. */
5162 build_objc_method_call (super_flag, method_prototype, lookup_object, object,
5163 selector, method_params)
5165 tree method_prototype, lookup_object, object, selector, method_params;
5167 tree sender = (super_flag ? umsg_super_decl : umsg_decl);
5168 tree rcv_p = (super_flag
5169 ? build_pointer_type (xref_tag (RECORD_TYPE,
5170 get_identifier (TAG_SUPER)))
5173 if (flag_next_runtime)
5175 if (! method_prototype)
5177 method_params = tree_cons (NULL_TREE, lookup_object,
5178 tree_cons (NULL_TREE, selector,
5180 assemble_external (sender);
5181 return build_function_call (sender, method_params);
5185 /* This is a real kludge, but it is used only for the Next.
5186 Clobber the data type of SENDER temporarily to accept
5187 all the arguments for this operation, and to return
5188 whatever this operation returns. */
5189 tree arglist = NULL_TREE, retval, savarg, savret;
5190 tree ret_type = groktypename (TREE_TYPE (method_prototype));
5192 /* Save the proper contents of SENDER's data type. */
5193 savarg = TYPE_ARG_TYPES (TREE_TYPE (sender));
5194 savret = TREE_TYPE (TREE_TYPE (sender));
5196 /* Install this method's argument types. */
5197 arglist = get_arg_type_list (method_prototype, METHOD_REF,
5199 TYPE_ARG_TYPES (TREE_TYPE (sender)) = arglist;
5201 /* Install this method's return type. */
5202 TREE_TYPE (TREE_TYPE (sender)) = ret_type;
5204 /* Call SENDER with all the parameters. This will do type
5205 checking using the arg types for this method. */
5206 method_params = tree_cons (NULL_TREE, lookup_object,
5207 tree_cons (NULL_TREE, selector,
5209 assemble_external (sender);
5210 retval = build_function_call (sender, method_params);
5212 /* Restore SENDER's return/argument types. */
5213 TYPE_ARG_TYPES (TREE_TYPE (sender)) = savarg;
5214 TREE_TYPE (TREE_TYPE (sender)) = savret;
5220 /* This is the portable way.
5221 First call the lookup function to get a pointer to the method,
5222 then cast the pointer, then call it with the method arguments. */
5225 /* Avoid trouble since we may evaluate each of these twice. */
5226 object = save_expr (object);
5227 selector = save_expr (selector);
5229 lookup_object = build_c_cast (rcv_p, lookup_object);
5231 assemble_external (sender);
5233 = build_function_call (sender,
5234 tree_cons (NULL_TREE, lookup_object,
5235 tree_cons (NULL_TREE, selector,
5238 /* If we have a method prototype, construct the data type this
5239 method needs, and cast what we got from SENDER into a pointer
5241 if (method_prototype)
5243 tree arglist = get_arg_type_list (method_prototype, METHOD_REF,
5245 tree valtype = groktypename (TREE_TYPE (method_prototype));
5246 tree fake_function_type = build_function_type (valtype, arglist);
5247 TREE_TYPE (method) = build_pointer_type (fake_function_type);
5251 = build_pointer_type (build_function_type (ptr_type_node, NULL_TREE));
5253 /* Pass the object to the method. */
5254 assemble_external (method);
5255 return build_function_call (method,
5256 tree_cons (NULL_TREE, object,
5257 tree_cons (NULL_TREE, selector,
5263 build_protocol_reference (p)
5266 tree decl, ident, ptype;
5268 /* extern struct objc_protocol _OBJC_PROTOCOL_<mumble>; */
5270 ident = synth_id_with_class_suffix ("_OBJC_PROTOCOL", p);
5272 = groktypename (build_tree_list (build_tree_list (NULL_TREE,
5273 objc_protocol_template),
5276 if (IDENTIFIER_GLOBAL_VALUE (ident))
5277 decl = IDENTIFIER_GLOBAL_VALUE (ident); /* Set by pushdecl. */
5280 decl = build_decl (VAR_DECL, ident, ptype);
5281 DECL_EXTERNAL (decl) = 1;
5282 TREE_PUBLIC (decl) = 1;
5283 TREE_USED (decl) = 1;
5284 DECL_ARTIFICIAL (decl) = 1;
5286 make_decl_rtl (decl, 0);
5287 pushdecl_top_level (decl);
5290 PROTOCOL_FORWARD_DECL (p) = decl;
5293 /* This function is called by the parser when (and only when) a
5294 @protocol() expression is found, in order to compile it. */
5296 build_protocol_expr (protoname)
5300 tree p = lookup_protocol (protoname);
5304 error ("cannot find protocol declaration for `%s'",
5305 IDENTIFIER_POINTER (protoname));
5306 return error_mark_node;
5309 if (!PROTOCOL_FORWARD_DECL (p))
5310 build_protocol_reference (p);
5312 expr = build_unary_op (ADDR_EXPR, PROTOCOL_FORWARD_DECL (p), 0);
5314 TREE_TYPE (expr) = protocol_type;
5316 /* The @protocol() expression is being compiled into a pointer to a
5317 statically allocated instance of the Protocol class. To become
5318 usable at runtime, the 'isa' pointer of the instance need to be
5319 fixed up at runtime by the runtime library, to point to the
5320 actual 'Protocol' class. */
5322 /* For the GNU runtime, put the static Protocol instance in the list
5323 of statically allocated instances, so that we make sure that its
5324 'isa' pointer is fixed up at runtime by the GNU runtime library
5325 to point to the Protocol class (at runtime, when loading the
5326 module, the GNU runtime library loops on the statically allocated
5327 instances (as found in the defs field in objc_symtab) and fixups
5328 all the 'isa' pointers of those objects). */
5329 if (! flag_next_runtime)
5331 /* This type is a struct containing the fields of a Protocol
5332 object. (Cfr. protocol_type instead is the type of a pointer
5333 to such a struct). */
5334 tree protocol_struct_type = xref_tag
5335 (RECORD_TYPE, get_identifier (PROTOCOL_OBJECT_CLASS_NAME));
5338 /* Look for the list of Protocol statically allocated instances
5339 to fixup at runtime. Create a new list to hold Protocol
5340 statically allocated instances, if the list is not found. At
5341 present there is only another list, holding NSConstantString
5342 static instances to be fixed up at runtime. */
5343 for (chain = &objc_static_instances;
5344 *chain && TREE_VALUE (*chain) != protocol_struct_type;
5345 chain = &TREE_CHAIN (*chain));
5348 *chain = tree_cons (NULL_TREE, protocol_struct_type, NULL_TREE);
5349 add_objc_string (TYPE_NAME (protocol_struct_type),
5353 /* Add this statically allocated instance to the Protocol list. */
5354 TREE_PURPOSE (*chain) = tree_cons (NULL_TREE,
5355 PROTOCOL_FORWARD_DECL (p),
5356 TREE_PURPOSE (*chain));
5363 /* This function is called by the parser when a @selector() expression
5364 is found, in order to compile it. It is only called by the parser
5365 and only to compile a @selector(). */
5367 build_selector_expr (selnamelist)
5372 /* Obtain the full selector name. */
5373 if (TREE_CODE (selnamelist) == IDENTIFIER_NODE)
5374 /* A unary selector. */
5375 selname = selnamelist;
5376 else if (TREE_CODE (selnamelist) == TREE_LIST)
5377 selname = build_keyword_selector (selnamelist);
5381 /* If we are required to check @selector() expressions as they
5382 are found, check that the selector has been declared. */
5383 if (warn_undeclared_selector)
5385 /* Look the selector up in the list of all known class and
5386 instance methods (up to this line) to check that the selector
5390 /* First try with instance methods. */
5391 hsh = hash_lookup (nst_method_hash_list, selname);
5393 /* If not found, try with class methods. */
5396 hsh = hash_lookup (cls_method_hash_list, selname);
5399 /* If still not found, print out a warning. */
5402 warning ("undeclared selector `%s'", IDENTIFIER_POINTER (selname));
5407 if (flag_typed_selectors)
5408 return build_typed_selector_reference (selname, 0);
5410 return build_selector_reference (selname);
5414 build_encode_expr (type)
5420 encode_type (type, obstack_object_size (&util_obstack),
5421 OBJC_ENCODE_INLINE_DEFS);
5422 obstack_1grow (&util_obstack, 0); /* null terminate string */
5423 string = obstack_finish (&util_obstack);
5425 /* Synthesize a string that represents the encoded struct/union. */
5426 result = my_build_string (strlen (string) + 1, string);
5427 obstack_free (&util_obstack, util_firstobj);
5432 build_ivar_reference (id)
5435 if (TREE_CODE (objc_method_context) == CLASS_METHOD_DECL)
5437 /* Historically, a class method that produced objects (factory
5438 method) would assign `self' to the instance that it
5439 allocated. This would effectively turn the class method into
5440 an instance method. Following this assignment, the instance
5441 variables could be accessed. That practice, while safe,
5442 violates the simple rule that a class method should not refer
5443 to an instance variable. It's better to catch the cases
5444 where this is done unknowingly than to support the above
5446 warning ("instance variable `%s' accessed in class method",
5447 IDENTIFIER_POINTER (id));
5448 TREE_TYPE (self_decl) = instance_type; /* cast */
5451 return build_component_ref (build_indirect_ref (self_decl, "->"), id);
5454 /* Compute a hash value for a given method SEL_NAME. */
5457 hash_func (sel_name)
5460 const unsigned char *s
5461 = (const unsigned char *)IDENTIFIER_POINTER (sel_name);
5465 h = h * 67 + *s++ - 113;
5472 nst_method_hash_list = (hash *) ggc_calloc (SIZEHASHTABLE, sizeof (hash));
5473 cls_method_hash_list = (hash *) ggc_calloc (SIZEHASHTABLE, sizeof (hash));
5476 /* WARNING!!!! hash_enter is called with a method, and will peek
5477 inside to find its selector! But hash_lookup is given a selector
5478 directly, and looks for the selector that's inside the found
5479 entry's key (method) for comparison. */
5482 hash_enter (hashlist, method)
5487 int slot = hash_func (METHOD_SEL_NAME (method)) % SIZEHASHTABLE;
5489 obj = (hash) ggc_alloc (sizeof (struct hashed_entry));
5491 obj->next = hashlist[slot];
5494 hashlist[slot] = obj; /* append to front */
5498 hash_lookup (hashlist, sel_name)
5504 target = hashlist[hash_func (sel_name) % SIZEHASHTABLE];
5508 if (sel_name == METHOD_SEL_NAME (target->key))
5511 target = target->next;
5517 hash_add_attr (entry, value)
5523 obj = (attr) ggc_alloc (sizeof (struct hashed_attribute));
5524 obj->next = entry->list;
5527 entry->list = obj; /* append to front */
5531 lookup_method (mchain, method)
5537 if (TREE_CODE (method) == IDENTIFIER_NODE)
5540 key = METHOD_SEL_NAME (method);
5544 if (METHOD_SEL_NAME (mchain) == key)
5547 mchain = TREE_CHAIN (mchain);
5553 lookup_instance_method_static (interface, ident)
5557 tree inter = interface;
5558 tree chain = CLASS_NST_METHODS (inter);
5559 tree meth = NULL_TREE;
5563 if ((meth = lookup_method (chain, ident)))
5566 if (CLASS_CATEGORY_LIST (inter))
5568 tree category = CLASS_CATEGORY_LIST (inter);
5569 chain = CLASS_NST_METHODS (category);
5573 if ((meth = lookup_method (chain, ident)))
5576 /* Check for instance methods in protocols in categories. */
5577 if (CLASS_PROTOCOL_LIST (category))
5579 if ((meth = (lookup_method_in_protocol_list
5580 (CLASS_PROTOCOL_LIST (category), ident, 0))))
5584 if ((category = CLASS_CATEGORY_LIST (category)))
5585 chain = CLASS_NST_METHODS (category);
5590 if (CLASS_PROTOCOL_LIST (inter))
5592 if ((meth = (lookup_method_in_protocol_list
5593 (CLASS_PROTOCOL_LIST (inter), ident, 0))))
5597 if ((inter = lookup_interface (CLASS_SUPER_NAME (inter))))
5598 chain = CLASS_NST_METHODS (inter);
5606 lookup_class_method_static (interface, ident)
5610 tree inter = interface;
5611 tree chain = CLASS_CLS_METHODS (inter);
5612 tree meth = NULL_TREE;
5613 tree root_inter = NULL_TREE;
5617 if ((meth = lookup_method (chain, ident)))
5620 if (CLASS_CATEGORY_LIST (inter))
5622 tree category = CLASS_CATEGORY_LIST (inter);
5623 chain = CLASS_CLS_METHODS (category);
5627 if ((meth = lookup_method (chain, ident)))
5630 /* Check for class methods in protocols in categories. */
5631 if (CLASS_PROTOCOL_LIST (category))
5633 if ((meth = (lookup_method_in_protocol_list
5634 (CLASS_PROTOCOL_LIST (category), ident, 1))))
5638 if ((category = CLASS_CATEGORY_LIST (category)))
5639 chain = CLASS_CLS_METHODS (category);
5644 /* Check for class methods in protocols. */
5645 if (CLASS_PROTOCOL_LIST (inter))
5647 if ((meth = (lookup_method_in_protocol_list
5648 (CLASS_PROTOCOL_LIST (inter), ident, 1))))
5653 if ((inter = lookup_interface (CLASS_SUPER_NAME (inter))))
5654 chain = CLASS_CLS_METHODS (inter);
5658 /* If no class (factory) method was found, check if an _instance_
5659 method of the same name exists in the root class. This is what
5660 the Objective-C runtime will do. */
5661 return lookup_instance_method_static (root_inter, ident);
5665 add_class_method (class, method)
5672 if (!(mth = lookup_method (CLASS_CLS_METHODS (class), method)))
5674 /* put method on list in reverse order */
5675 TREE_CHAIN (method) = CLASS_CLS_METHODS (class);
5676 CLASS_CLS_METHODS (class) = method;
5680 if (TREE_CODE (class) == CLASS_IMPLEMENTATION_TYPE)
5681 error ("duplicate definition of class method `%s'",
5682 IDENTIFIER_POINTER (METHOD_SEL_NAME (mth)));
5685 /* Check types; if different, complain. */
5686 if (!comp_proto_with_proto (method, mth))
5687 error ("duplicate declaration of class method `%s'",
5688 IDENTIFIER_POINTER (METHOD_SEL_NAME (mth)));
5692 if (!(hsh = hash_lookup (cls_method_hash_list, METHOD_SEL_NAME (method))))
5694 /* Install on a global chain. */
5695 hash_enter (cls_method_hash_list, method);
5699 /* Check types; if different, add to a list. */
5700 if (!comp_proto_with_proto (method, hsh->key))
5701 hash_add_attr (hsh, method);
5707 add_instance_method (class, method)
5714 if (!(mth = lookup_method (CLASS_NST_METHODS (class), method)))
5716 /* Put method on list in reverse order. */
5717 TREE_CHAIN (method) = CLASS_NST_METHODS (class);
5718 CLASS_NST_METHODS (class) = method;
5722 if (TREE_CODE (class) == CLASS_IMPLEMENTATION_TYPE)
5723 error ("duplicate definition of instance method `%s'",
5724 IDENTIFIER_POINTER (METHOD_SEL_NAME (mth)));
5727 /* Check types; if different, complain. */
5728 if (!comp_proto_with_proto (method, mth))
5729 error ("duplicate declaration of instance method `%s'",
5730 IDENTIFIER_POINTER (METHOD_SEL_NAME (mth)));
5734 if (!(hsh = hash_lookup (nst_method_hash_list, METHOD_SEL_NAME (method))))
5736 /* Install on a global chain. */
5737 hash_enter (nst_method_hash_list, method);
5741 /* Check types; if different, add to a list. */
5742 if (!comp_proto_with_proto (method, hsh->key))
5743 hash_add_attr (hsh, method);
5752 /* Put interfaces on list in reverse order. */
5753 TREE_CHAIN (class) = interface_chain;
5754 interface_chain = class;
5755 return interface_chain;
5759 add_category (class, category)
5763 /* Put categories on list in reverse order. */
5764 tree cat = CLASS_CATEGORY_LIST (class);
5768 if (CLASS_SUPER_NAME (cat) == CLASS_SUPER_NAME (category))
5769 warning ("duplicate interface declaration for category `%s(%s)'",
5770 IDENTIFIER_POINTER (CLASS_NAME (class)),
5771 IDENTIFIER_POINTER (CLASS_SUPER_NAME (category)));
5772 cat = CLASS_CATEGORY_LIST (cat);
5775 CLASS_CATEGORY_LIST (category) = CLASS_CATEGORY_LIST (class);
5776 CLASS_CATEGORY_LIST (class) = category;
5779 /* Called after parsing each instance variable declaration. Necessary to
5780 preserve typedefs and implement public/private...
5782 PUBLIC is 1 for public, 0 for protected, and 2 for private. */
5785 add_instance_variable (class, public, declarator, declspecs, width)
5792 tree field_decl, raw_decl;
5794 raw_decl = build_tree_list (declspecs, declarator);
5796 if (CLASS_RAW_IVARS (class))
5797 chainon (CLASS_RAW_IVARS (class), raw_decl);
5799 CLASS_RAW_IVARS (class) = raw_decl;
5801 field_decl = grokfield (input_filename, lineno,
5802 declarator, declspecs, width);
5804 /* Overload the public attribute, it is not used for FIELD_DECLs. */
5808 TREE_PUBLIC (field_decl) = 0;
5809 TREE_PRIVATE (field_decl) = 0;
5810 TREE_PROTECTED (field_decl) = 1;
5814 TREE_PUBLIC (field_decl) = 1;
5815 TREE_PRIVATE (field_decl) = 0;
5816 TREE_PROTECTED (field_decl) = 0;
5820 TREE_PUBLIC (field_decl) = 0;
5821 TREE_PRIVATE (field_decl) = 1;
5822 TREE_PROTECTED (field_decl) = 0;
5827 if (CLASS_IVARS (class))
5828 chainon (CLASS_IVARS (class), field_decl);
5830 CLASS_IVARS (class) = field_decl;
5836 is_ivar (decl_chain, ident)
5840 for ( ; decl_chain; decl_chain = TREE_CHAIN (decl_chain))
5841 if (DECL_NAME (decl_chain) == ident)
5846 /* True if the ivar is private and we are not in its implementation. */
5852 if (TREE_PRIVATE (decl)
5853 && ! is_ivar (CLASS_IVARS (implementation_template), DECL_NAME (decl)))
5855 error ("instance variable `%s' is declared private",
5856 IDENTIFIER_POINTER (DECL_NAME (decl)));
5863 /* We have an instance variable reference;, check to see if it is public. */
5866 is_public (expr, identifier)
5870 tree basetype = TREE_TYPE (expr);
5871 enum tree_code code = TREE_CODE (basetype);
5874 if (code == RECORD_TYPE)
5876 if (TREE_STATIC_TEMPLATE (basetype))
5878 if (!lookup_interface (TYPE_NAME (basetype)))
5880 error ("cannot find interface declaration for `%s'",
5881 IDENTIFIER_POINTER (TYPE_NAME (basetype)));
5885 if ((decl = is_ivar (TYPE_FIELDS (basetype), identifier)))
5887 if (TREE_PUBLIC (decl))
5890 /* Important difference between the Stepstone translator:
5891 all instance variables should be public within the context
5892 of the implementation. */
5893 if (objc_implementation_context
5894 && (((TREE_CODE (objc_implementation_context)
5895 == CLASS_IMPLEMENTATION_TYPE)
5896 || (TREE_CODE (objc_implementation_context)
5897 == CATEGORY_IMPLEMENTATION_TYPE))
5898 && (CLASS_NAME (objc_implementation_context)
5899 == TYPE_NAME (basetype))))
5900 return ! is_private (decl);
5902 error ("instance variable `%s' is declared %s",
5903 IDENTIFIER_POINTER (identifier),
5904 TREE_PRIVATE (decl) ? "private" : "protected");
5909 else if (objc_implementation_context && (basetype == objc_object_reference))
5911 TREE_TYPE (expr) = uprivate_record;
5912 warning ("static access to object of type `id'");
5919 /* Make sure all entries in CHAIN are also in LIST. */
5922 check_methods (chain, list, mtype)
5931 if (!lookup_method (list, chain))
5935 if (TREE_CODE (objc_implementation_context)
5936 == CLASS_IMPLEMENTATION_TYPE)
5937 warning ("incomplete implementation of class `%s'",
5938 IDENTIFIER_POINTER (CLASS_NAME (objc_implementation_context)));
5939 else if (TREE_CODE (objc_implementation_context)
5940 == CATEGORY_IMPLEMENTATION_TYPE)
5941 warning ("incomplete implementation of category `%s'",
5942 IDENTIFIER_POINTER (CLASS_SUPER_NAME (objc_implementation_context)));
5946 warning ("method definition for `%c%s' not found",
5947 mtype, IDENTIFIER_POINTER (METHOD_SEL_NAME (chain)));
5950 chain = TREE_CHAIN (chain);
5956 /* Check if CLASS, or its superclasses, explicitly conforms to PROTOCOL. */
5959 conforms_to_protocol (class, protocol)
5963 if (TREE_CODE (protocol) == PROTOCOL_INTERFACE_TYPE)
5965 tree p = CLASS_PROTOCOL_LIST (class);
5966 while (p && TREE_VALUE (p) != protocol)
5971 tree super = (CLASS_SUPER_NAME (class)
5972 ? lookup_interface (CLASS_SUPER_NAME (class))
5974 int tmp = super ? conforms_to_protocol (super, protocol) : 0;
5983 /* Make sure all methods in CHAIN are accessible as MTYPE methods in
5984 CONTEXT. This is one of two mechanisms to check protocol integrity. */
5987 check_methods_accessible (chain, context, mtype)
5994 tree base_context = context;
5998 context = base_context;
6002 list = CLASS_CLS_METHODS (context);
6004 list = CLASS_NST_METHODS (context);
6006 if (lookup_method (list, chain))
6009 else if (TREE_CODE (context) == CLASS_IMPLEMENTATION_TYPE
6010 || TREE_CODE (context) == CLASS_INTERFACE_TYPE)
6011 context = (CLASS_SUPER_NAME (context)
6012 ? lookup_interface (CLASS_SUPER_NAME (context))
6015 else if (TREE_CODE (context) == CATEGORY_IMPLEMENTATION_TYPE
6016 || TREE_CODE (context) == CATEGORY_INTERFACE_TYPE)
6017 context = (CLASS_NAME (context)
6018 ? lookup_interface (CLASS_NAME (context))
6024 if (context == NULL_TREE)
6028 if (TREE_CODE (objc_implementation_context)
6029 == CLASS_IMPLEMENTATION_TYPE)
6030 warning ("incomplete implementation of class `%s'",
6032 (CLASS_NAME (objc_implementation_context)));
6033 else if (TREE_CODE (objc_implementation_context)
6034 == CATEGORY_IMPLEMENTATION_TYPE)
6035 warning ("incomplete implementation of category `%s'",
6037 (CLASS_SUPER_NAME (objc_implementation_context)));
6040 warning ("method definition for `%c%s' not found",
6041 mtype, IDENTIFIER_POINTER (METHOD_SEL_NAME (chain)));
6044 chain = TREE_CHAIN (chain); /* next method... */
6049 /* Check whether the current interface (accessible via
6050 'objc_implementation_context') actually implements protocol P, along
6051 with any protocols that P inherits. */
6054 check_protocol (p, type, name)
6059 if (TREE_CODE (p) == PROTOCOL_INTERFACE_TYPE)
6063 /* Ensure that all protocols have bodies! */
6066 f1 = check_methods (PROTOCOL_CLS_METHODS (p),
6067 CLASS_CLS_METHODS (objc_implementation_context),
6069 f2 = check_methods (PROTOCOL_NST_METHODS (p),
6070 CLASS_NST_METHODS (objc_implementation_context),
6075 f1 = check_methods_accessible (PROTOCOL_CLS_METHODS (p),
6076 objc_implementation_context,
6078 f2 = check_methods_accessible (PROTOCOL_NST_METHODS (p),
6079 objc_implementation_context,
6084 warning ("%s `%s' does not fully implement the `%s' protocol",
6085 type, name, IDENTIFIER_POINTER (PROTOCOL_NAME (p)));
6088 /* Check protocols recursively. */
6089 if (PROTOCOL_LIST (p))
6091 tree subs = PROTOCOL_LIST (p);
6093 lookup_interface (CLASS_SUPER_NAME (implementation_template));
6097 tree sub = TREE_VALUE (subs);
6099 /* If the superclass does not conform to the protocols
6100 inherited by P, then we must! */
6101 if (!super_class || !conforms_to_protocol (super_class, sub))
6102 check_protocol (sub, type, name);
6103 subs = TREE_CHAIN (subs);
6108 /* Check whether the current interface (accessible via
6109 'objc_implementation_context') actually implements the protocols listed
6113 check_protocols (proto_list, type, name)
6118 for ( ; proto_list; proto_list = TREE_CHAIN (proto_list))
6120 tree p = TREE_VALUE (proto_list);
6122 check_protocol (p, type, name);
6126 /* Make sure that the class CLASS_NAME is defined
6127 CODE says which kind of thing CLASS_NAME ought to be.
6128 It can be CLASS_INTERFACE_TYPE, CLASS_IMPLEMENTATION_TYPE,
6129 CATEGORY_INTERFACE_TYPE, or CATEGORY_IMPLEMENTATION_TYPE. */
6132 start_class (code, class_name, super_name, protocol_list)
6133 enum tree_code code;
6140 if (objc_implementation_context)
6142 warning ("`@end' missing in implementation context");
6143 finish_class (objc_implementation_context);
6144 objc_ivar_chain = NULL_TREE;
6145 objc_implementation_context = NULL_TREE;
6148 class = make_node (code);
6149 TYPE_BINFO (class) = make_tree_vec (BINFO_ELTS);
6151 CLASS_NAME (class) = class_name;
6152 CLASS_SUPER_NAME (class) = super_name;
6153 CLASS_CLS_METHODS (class) = NULL_TREE;
6155 if (! is_class_name (class_name) && (decl = lookup_name (class_name)))
6157 error ("`%s' redeclared as different kind of symbol",
6158 IDENTIFIER_POINTER (class_name));
6159 error_with_decl (decl, "previous declaration of `%s'");
6162 if (code == CLASS_IMPLEMENTATION_TYPE)
6167 for (chain = implemented_classes; chain; chain = TREE_CHAIN (chain))
6168 if (TREE_VALUE (chain) == class_name)
6170 error ("reimplementation of class `%s'",
6171 IDENTIFIER_POINTER (class_name));
6172 return error_mark_node;
6174 implemented_classes = tree_cons (NULL_TREE, class_name,
6175 implemented_classes);
6178 /* Pre-build the following entities - for speed/convenience. */
6180 self_id = get_identifier ("self");
6182 ucmd_id = get_identifier ("_cmd");
6185 = build_tree_list (get_identifier ("__unused__"), NULL_TREE);
6186 if (!objc_super_template)
6187 objc_super_template = build_super_template ();
6189 /* Reset for multiple classes per file. */
6192 objc_implementation_context = class;
6194 /* Lookup the interface for this implementation. */
6196 if (!(implementation_template = lookup_interface (class_name)))
6198 warning ("cannot find interface declaration for `%s'",
6199 IDENTIFIER_POINTER (class_name));
6200 add_class (implementation_template = objc_implementation_context);
6203 /* If a super class has been specified in the implementation,
6204 insure it conforms to the one specified in the interface. */
6207 && (super_name != CLASS_SUPER_NAME (implementation_template)))
6209 tree previous_name = CLASS_SUPER_NAME (implementation_template);
6210 const char *const name =
6211 previous_name ? IDENTIFIER_POINTER (previous_name) : "";
6212 error ("conflicting super class name `%s'",
6213 IDENTIFIER_POINTER (super_name));
6214 error ("previous declaration of `%s'", name);
6217 else if (! super_name)
6219 CLASS_SUPER_NAME (objc_implementation_context)
6220 = CLASS_SUPER_NAME (implementation_template);
6224 else if (code == CLASS_INTERFACE_TYPE)
6226 if (lookup_interface (class_name))
6227 warning ("duplicate interface declaration for class `%s'",
6228 IDENTIFIER_POINTER (class_name));
6233 CLASS_PROTOCOL_LIST (class)
6234 = lookup_and_install_protocols (protocol_list);
6237 else if (code == CATEGORY_INTERFACE_TYPE)
6239 tree class_category_is_assoc_with;
6241 /* For a category, class_name is really the name of the class that
6242 the following set of methods will be associated with. We must
6243 find the interface so that can derive the objects template. */
6245 if (!(class_category_is_assoc_with = lookup_interface (class_name)))
6247 error ("cannot find interface declaration for `%s'",
6248 IDENTIFIER_POINTER (class_name));
6249 exit (FATAL_EXIT_CODE);
6252 add_category (class_category_is_assoc_with, class);
6255 CLASS_PROTOCOL_LIST (class)
6256 = lookup_and_install_protocols (protocol_list);
6259 else if (code == CATEGORY_IMPLEMENTATION_TYPE)
6261 /* Pre-build the following entities for speed/convenience. */
6263 self_id = get_identifier ("self");
6265 ucmd_id = get_identifier ("_cmd");
6268 = build_tree_list (get_identifier ("__unused__"), NULL_TREE);
6269 if (!objc_super_template)
6270 objc_super_template = build_super_template ();
6272 /* Reset for multiple classes per file. */
6275 objc_implementation_context = class;
6277 /* For a category, class_name is really the name of the class that
6278 the following set of methods will be associated with. We must
6279 find the interface so that can derive the objects template. */
6281 if (!(implementation_template = lookup_interface (class_name)))
6283 error ("cannot find interface declaration for `%s'",
6284 IDENTIFIER_POINTER (class_name));
6285 exit (FATAL_EXIT_CODE);
6292 continue_class (class)
6295 if (TREE_CODE (class) == CLASS_IMPLEMENTATION_TYPE
6296 || TREE_CODE (class) == CATEGORY_IMPLEMENTATION_TYPE)
6298 struct imp_entry *imp_entry;
6301 /* Check consistency of the instance variables. */
6303 if (CLASS_IVARS (class))
6304 check_ivars (implementation_template, class);
6306 /* code generation */
6308 ivar_context = build_private_template (implementation_template);
6310 if (!objc_class_template)
6311 build_class_template ();
6313 imp_entry = (struct imp_entry *) ggc_alloc (sizeof (struct imp_entry));
6315 imp_entry->next = imp_list;
6316 imp_entry->imp_context = class;
6317 imp_entry->imp_template = implementation_template;
6319 synth_forward_declarations ();
6320 imp_entry->class_decl = UOBJC_CLASS_decl;
6321 imp_entry->meta_decl = UOBJC_METACLASS_decl;
6323 /* Append to front and increment count. */
6324 imp_list = imp_entry;
6325 if (TREE_CODE (class) == CLASS_IMPLEMENTATION_TYPE)
6330 return ivar_context;
6333 else if (TREE_CODE (class) == CLASS_INTERFACE_TYPE)
6335 tree record = xref_tag (RECORD_TYPE, CLASS_NAME (class));
6337 if (!TYPE_FIELDS (record))
6339 finish_struct (record, get_class_ivars (class), NULL_TREE);
6340 CLASS_STATIC_TEMPLATE (class) = record;
6342 /* Mark this record as a class template for static typing. */
6343 TREE_STATIC_TEMPLATE (record) = 1;
6350 return error_mark_node;
6353 /* This is called once we see the "@end" in an interface/implementation. */
6356 finish_class (class)
6359 if (TREE_CODE (class) == CLASS_IMPLEMENTATION_TYPE)
6361 /* All code generation is done in finish_objc. */
6363 if (implementation_template != objc_implementation_context)
6365 /* Ensure that all method listed in the interface contain bodies. */
6366 check_methods (CLASS_CLS_METHODS (implementation_template),
6367 CLASS_CLS_METHODS (objc_implementation_context), '+');
6368 check_methods (CLASS_NST_METHODS (implementation_template),
6369 CLASS_NST_METHODS (objc_implementation_context), '-');
6371 if (CLASS_PROTOCOL_LIST (implementation_template))
6372 check_protocols (CLASS_PROTOCOL_LIST (implementation_template),
6374 IDENTIFIER_POINTER (CLASS_NAME (objc_implementation_context)));
6378 else if (TREE_CODE (class) == CATEGORY_IMPLEMENTATION_TYPE)
6380 tree category = CLASS_CATEGORY_LIST (implementation_template);
6382 /* Find the category interface from the class it is associated with. */
6385 if (CLASS_SUPER_NAME (class) == CLASS_SUPER_NAME (category))
6387 category = CLASS_CATEGORY_LIST (category);
6392 /* Ensure all method listed in the interface contain bodies. */
6393 check_methods (CLASS_CLS_METHODS (category),
6394 CLASS_CLS_METHODS (objc_implementation_context), '+');
6395 check_methods (CLASS_NST_METHODS (category),
6396 CLASS_NST_METHODS (objc_implementation_context), '-');
6398 if (CLASS_PROTOCOL_LIST (category))
6399 check_protocols (CLASS_PROTOCOL_LIST (category),
6401 IDENTIFIER_POINTER (CLASS_SUPER_NAME (objc_implementation_context)));
6405 else if (TREE_CODE (class) == CLASS_INTERFACE_TYPE)
6408 const char *class_name = IDENTIFIER_POINTER (CLASS_NAME (class));
6409 char *string = (char *) alloca (strlen (class_name) + 3);
6411 /* extern struct objc_object *_<my_name>; */
6413 sprintf (string, "_%s", class_name);
6415 decl_specs = build_tree_list (NULL_TREE, ridpointers[(int) RID_EXTERN]);
6416 decl_specs = tree_cons (NULL_TREE, objc_object_reference, decl_specs);
6417 define_decl (build1 (INDIRECT_REF, NULL_TREE, get_identifier (string)),
6423 add_protocol (protocol)
6426 /* Put protocol on list in reverse order. */
6427 TREE_CHAIN (protocol) = protocol_chain;
6428 protocol_chain = protocol;
6429 return protocol_chain;
6433 lookup_protocol (ident)
6438 for (chain = protocol_chain; chain; chain = TREE_CHAIN (chain))
6439 if (ident == PROTOCOL_NAME (chain))
6445 /* This function forward declares the protocols named by NAMES. If
6446 they are already declared or defined, the function has no effect. */
6449 objc_declare_protocols (names)
6454 for (list = names; list; list = TREE_CHAIN (list))
6456 tree name = TREE_VALUE (list);
6458 if (lookup_protocol (name) == NULL_TREE)
6460 tree protocol = make_node (PROTOCOL_INTERFACE_TYPE);
6462 TYPE_BINFO (protocol) = make_tree_vec (2);
6463 PROTOCOL_NAME (protocol) = name;
6464 PROTOCOL_LIST (protocol) = NULL_TREE;
6465 add_protocol (protocol);
6466 PROTOCOL_DEFINED (protocol) = 0;
6467 PROTOCOL_FORWARD_DECL (protocol) = NULL_TREE;
6473 start_protocol (code, name, list)
6474 enum tree_code code;
6480 /* This is as good a place as any. Need to invoke
6481 push_tag_toplevel. */
6482 if (!objc_protocol_template)
6483 objc_protocol_template = build_protocol_template ();
6485 protocol = lookup_protocol (name);
6489 protocol = make_node (code);
6490 TYPE_BINFO (protocol) = make_tree_vec (2);
6492 PROTOCOL_NAME (protocol) = name;
6493 PROTOCOL_LIST (protocol) = lookup_and_install_protocols (list);
6494 add_protocol (protocol);
6495 PROTOCOL_DEFINED (protocol) = 1;
6496 PROTOCOL_FORWARD_DECL (protocol) = NULL_TREE;
6498 check_protocol_recursively (protocol, list);
6500 else if (! PROTOCOL_DEFINED (protocol))
6502 PROTOCOL_DEFINED (protocol) = 1;
6503 PROTOCOL_LIST (protocol) = lookup_and_install_protocols (list);
6505 check_protocol_recursively (protocol, list);
6509 warning ("duplicate declaration for protocol `%s'",
6510 IDENTIFIER_POINTER (name));
6516 finish_protocol (protocol)
6517 tree protocol ATTRIBUTE_UNUSED;
6522 /* "Encode" a data type into a string, which grows in util_obstack.
6523 ??? What is the FORMAT? Someone please document this! */
6526 encode_type_qualifiers (declspecs)
6531 for (spec = declspecs; spec; spec = TREE_CHAIN (spec))
6533 if (ridpointers[(int) RID_CONST] == TREE_VALUE (spec))
6534 obstack_1grow (&util_obstack, 'r');
6535 else if (ridpointers[(int) RID_IN] == TREE_VALUE (spec))
6536 obstack_1grow (&util_obstack, 'n');
6537 else if (ridpointers[(int) RID_INOUT] == TREE_VALUE (spec))
6538 obstack_1grow (&util_obstack, 'N');
6539 else if (ridpointers[(int) RID_OUT] == TREE_VALUE (spec))
6540 obstack_1grow (&util_obstack, 'o');
6541 else if (ridpointers[(int) RID_BYCOPY] == TREE_VALUE (spec))
6542 obstack_1grow (&util_obstack, 'O');
6543 else if (ridpointers[(int) RID_BYREF] == TREE_VALUE (spec))
6544 obstack_1grow (&util_obstack, 'R');
6545 else if (ridpointers[(int) RID_ONEWAY] == TREE_VALUE (spec))
6546 obstack_1grow (&util_obstack, 'V');
6550 /* Encode a pointer type. */
6553 encode_pointer (type, curtype, format)
6558 tree pointer_to = TREE_TYPE (type);
6560 if (TREE_CODE (pointer_to) == RECORD_TYPE)
6562 if (TYPE_NAME (pointer_to)
6563 && TREE_CODE (TYPE_NAME (pointer_to)) == IDENTIFIER_NODE)
6565 const char *name = IDENTIFIER_POINTER (TYPE_NAME (pointer_to));
6567 if (strcmp (name, TAG_OBJECT) == 0) /* '@' */
6569 obstack_1grow (&util_obstack, '@');
6572 else if (TREE_STATIC_TEMPLATE (pointer_to))
6574 if (generating_instance_variables)
6576 obstack_1grow (&util_obstack, '@');
6577 obstack_1grow (&util_obstack, '"');
6578 obstack_grow (&util_obstack, name, strlen (name));
6579 obstack_1grow (&util_obstack, '"');
6584 obstack_1grow (&util_obstack, '@');
6588 else if (strcmp (name, TAG_CLASS) == 0) /* '#' */
6590 obstack_1grow (&util_obstack, '#');
6593 else if (strcmp (name, TAG_SELECTOR) == 0) /* ':' */
6595 obstack_1grow (&util_obstack, ':');
6600 else if (TREE_CODE (pointer_to) == INTEGER_TYPE
6601 && TYPE_MODE (pointer_to) == QImode)
6603 obstack_1grow (&util_obstack, '*');
6607 /* We have a type that does not get special treatment. */
6609 /* NeXT extension */
6610 obstack_1grow (&util_obstack, '^');
6611 encode_type (pointer_to, curtype, format);
6615 encode_array (type, curtype, format)
6620 tree an_int_cst = TYPE_SIZE (type);
6621 tree array_of = TREE_TYPE (type);
6624 /* An incomplete array is treated like a pointer. */
6625 if (an_int_cst == NULL)
6627 encode_pointer (type, curtype, format);
6631 sprintf (buffer, "[%ld",
6632 (long) (TREE_INT_CST_LOW (an_int_cst)
6633 / TREE_INT_CST_LOW (TYPE_SIZE (array_of))));
6635 obstack_grow (&util_obstack, buffer, strlen (buffer));
6636 encode_type (array_of, curtype, format);
6637 obstack_1grow (&util_obstack, ']');
6642 encode_aggregate_within (type, curtype, format, left, right)
6649 /* The RECORD_TYPE may in fact be a typedef! For purposes
6650 of encoding, we need the real underlying enchilada. */
6651 if (TYPE_MAIN_VARIANT (type))
6652 type = TYPE_MAIN_VARIANT (type);
6654 if (obstack_object_size (&util_obstack) > 0
6655 && *(obstack_next_free (&util_obstack) - 1) == '^')
6657 tree name = TYPE_NAME (type);
6659 /* we have a reference; this is a NeXT extension. */
6661 if (obstack_object_size (&util_obstack) - curtype == 1
6662 && format == OBJC_ENCODE_INLINE_DEFS)
6664 /* Output format of struct for first level only. */
6665 tree fields = TYPE_FIELDS (type);
6667 if (name && TREE_CODE (name) == IDENTIFIER_NODE)
6669 obstack_1grow (&util_obstack, left);
6670 obstack_grow (&util_obstack,
6671 IDENTIFIER_POINTER (name),
6672 strlen (IDENTIFIER_POINTER (name)));
6673 obstack_1grow (&util_obstack, '=');
6677 obstack_1grow (&util_obstack, left);
6678 obstack_grow (&util_obstack, "?=", 2);
6681 for ( ; fields; fields = TREE_CHAIN (fields))
6682 encode_field_decl (fields, curtype, format);
6684 obstack_1grow (&util_obstack, right);
6687 else if (name && TREE_CODE (name) == IDENTIFIER_NODE)
6689 obstack_1grow (&util_obstack, left);
6690 obstack_grow (&util_obstack,
6691 IDENTIFIER_POINTER (name),
6692 strlen (IDENTIFIER_POINTER (name)));
6693 obstack_1grow (&util_obstack, right);
6698 /* We have an untagged structure or a typedef. */
6699 obstack_1grow (&util_obstack, left);
6700 obstack_1grow (&util_obstack, '?');
6701 obstack_1grow (&util_obstack, right);
6707 tree name = TYPE_NAME (type);
6708 tree fields = TYPE_FIELDS (type);
6710 if (format == OBJC_ENCODE_INLINE_DEFS
6711 || generating_instance_variables)
6713 obstack_1grow (&util_obstack, left);
6714 if (name && TREE_CODE (name) == IDENTIFIER_NODE)
6715 obstack_grow (&util_obstack,
6716 IDENTIFIER_POINTER (name),
6717 strlen (IDENTIFIER_POINTER (name)));
6719 obstack_1grow (&util_obstack, '?');
6721 obstack_1grow (&util_obstack, '=');
6723 for (; fields; fields = TREE_CHAIN (fields))
6725 if (generating_instance_variables)
6727 tree fname = DECL_NAME (fields);
6729 obstack_1grow (&util_obstack, '"');
6730 if (fname && TREE_CODE (fname) == IDENTIFIER_NODE)
6732 obstack_grow (&util_obstack,
6733 IDENTIFIER_POINTER (fname),
6734 strlen (IDENTIFIER_POINTER (fname)));
6737 obstack_1grow (&util_obstack, '"');
6740 encode_field_decl (fields, curtype, format);
6743 obstack_1grow (&util_obstack, right);
6748 obstack_1grow (&util_obstack, left);
6749 if (name && TREE_CODE (name) == IDENTIFIER_NODE)
6750 obstack_grow (&util_obstack,
6751 IDENTIFIER_POINTER (name),
6752 strlen (IDENTIFIER_POINTER (name)));
6754 /* We have an untagged structure or a typedef. */
6755 obstack_1grow (&util_obstack, '?');
6757 obstack_1grow (&util_obstack, right);
6763 encode_aggregate (type, curtype, format)
6768 enum tree_code code = TREE_CODE (type);
6774 encode_aggregate_within(type, curtype, format, '{', '}');
6779 encode_aggregate_within(type, curtype, format, '(', ')');
6784 obstack_1grow (&util_obstack, 'i');
6792 /* Support bitfields. The current version of Objective-C does not support
6793 them. The string will consist of one or more "b:n"'s where n is an
6794 integer describing the width of the bitfield. Currently, classes in
6795 the kit implement a method "-(char *)describeBitfieldStruct:" that
6796 simulates this. If they do not implement this method, the archiver
6797 assumes the bitfield is 16 bits wide (padded if necessary) and packed
6798 according to the GNU compiler. After looking at the "kit", it appears
6799 that all classes currently rely on this default behavior, rather than
6800 hand generating this string (which is tedious). */
6803 encode_bitfield (width)
6807 sprintf (buffer, "b%d", width);
6808 obstack_grow (&util_obstack, buffer, strlen (buffer));
6811 /* FORMAT will be OBJC_ENCODE_INLINE_DEFS or OBJC_ENCODE_DONT_INLINE_DEFS. */
6814 encode_type (type, curtype, format)
6819 enum tree_code code = TREE_CODE (type);
6821 if (code == INTEGER_TYPE)
6823 if (integer_zerop (TYPE_MIN_VALUE (type)))
6825 /* Unsigned integer types. */
6827 if (TYPE_MODE (type) == QImode)
6828 obstack_1grow (&util_obstack, 'C');
6829 else if (TYPE_MODE (type) == HImode)
6830 obstack_1grow (&util_obstack, 'S');
6831 else if (TYPE_MODE (type) == SImode)
6833 if (type == long_unsigned_type_node)
6834 obstack_1grow (&util_obstack, 'L');
6836 obstack_1grow (&util_obstack, 'I');
6838 else if (TYPE_MODE (type) == DImode)
6839 obstack_1grow (&util_obstack, 'Q');
6843 /* Signed integer types. */
6845 if (TYPE_MODE (type) == QImode)
6846 obstack_1grow (&util_obstack, 'c');
6847 else if (TYPE_MODE (type) == HImode)
6848 obstack_1grow (&util_obstack, 's');
6849 else if (TYPE_MODE (type) == SImode)
6851 if (type == long_integer_type_node)
6852 obstack_1grow (&util_obstack, 'l');
6854 obstack_1grow (&util_obstack, 'i');
6857 else if (TYPE_MODE (type) == DImode)
6858 obstack_1grow (&util_obstack, 'q');
6862 else if (code == REAL_TYPE)
6864 /* Floating point types. */
6866 if (TYPE_MODE (type) == SFmode)
6867 obstack_1grow (&util_obstack, 'f');
6868 else if (TYPE_MODE (type) == DFmode
6869 || TYPE_MODE (type) == TFmode)
6870 obstack_1grow (&util_obstack, 'd');
6873 else if (code == VOID_TYPE)
6874 obstack_1grow (&util_obstack, 'v');
6876 else if (code == ARRAY_TYPE)
6877 encode_array (type, curtype, format);
6879 else if (code == POINTER_TYPE)
6880 encode_pointer (type, curtype, format);
6882 else if (code == RECORD_TYPE || code == UNION_TYPE || code == ENUMERAL_TYPE)
6883 encode_aggregate (type, curtype, format);
6885 else if (code == FUNCTION_TYPE) /* '?' */
6886 obstack_1grow (&util_obstack, '?');
6890 encode_complete_bitfield (position, type, size)
6895 enum tree_code code = TREE_CODE (type);
6897 char charType = '?';
6899 if (code == INTEGER_TYPE)
6901 if (integer_zerop (TYPE_MIN_VALUE (type)))
6903 /* Unsigned integer types. */
6905 if (TYPE_MODE (type) == QImode)
6907 else if (TYPE_MODE (type) == HImode)
6909 else if (TYPE_MODE (type) == SImode)
6911 if (type == long_unsigned_type_node)
6916 else if (TYPE_MODE (type) == DImode)
6921 /* Signed integer types. */
6923 if (TYPE_MODE (type) == QImode)
6925 else if (TYPE_MODE (type) == HImode)
6927 else if (TYPE_MODE (type) == SImode)
6929 if (type == long_integer_type_node)
6935 else if (TYPE_MODE (type) == DImode)
6939 else if (code == ENUMERAL_TYPE)
6944 sprintf (buffer, "b%d%c%d", position, charType, size);
6945 obstack_grow (&util_obstack, buffer, strlen (buffer));
6949 encode_field_decl (field_decl, curtype, format)
6956 type = TREE_TYPE (field_decl);
6958 /* If this field is obviously a bitfield, or is a bitfield that has been
6959 clobbered to look like a ordinary integer mode, go ahead and generate
6960 the bitfield typing information. */
6961 if (flag_next_runtime)
6963 if (DECL_BIT_FIELD_TYPE (field_decl))
6964 encode_bitfield (tree_low_cst (DECL_SIZE (field_decl), 1));
6966 encode_type (TREE_TYPE (field_decl), curtype, format);
6970 if (DECL_BIT_FIELD_TYPE (field_decl))
6971 encode_complete_bitfield (int_bit_position (field_decl),
6972 DECL_BIT_FIELD_TYPE (field_decl),
6973 tree_low_cst (DECL_SIZE (field_decl), 1));
6975 encode_type (TREE_TYPE (field_decl), curtype, format);
6980 expr_last (complex_expr)
6986 while ((next = TREE_OPERAND (complex_expr, 0)))
6987 complex_expr = next;
6989 return complex_expr;
6992 /* Transform a method definition into a function definition as follows:
6993 - synthesize the first two arguments, "self" and "_cmd". */
6996 start_method_def (method)
7001 /* Required to implement _msgSuper. */
7002 objc_method_context = method;
7003 UOBJC_SUPER_decl = NULL_TREE;
7005 /* Must be called BEFORE start_function. */
7008 /* Generate prototype declarations for arguments..."new-style". */
7010 if (TREE_CODE (objc_method_context) == INSTANCE_METHOD_DECL)
7011 decl_specs = build_tree_list (NULL_TREE, uprivate_record);
7013 /* Really a `struct objc_class *'. However, we allow people to
7014 assign to self, which changes its type midstream. */
7015 decl_specs = build_tree_list (NULL_TREE, objc_object_reference);
7017 push_parm_decl (build_tree_list
7018 (build_tree_list (decl_specs,
7019 build1 (INDIRECT_REF, NULL_TREE, self_id)),
7022 decl_specs = build_tree_list (NULL_TREE,
7023 xref_tag (RECORD_TYPE,
7024 get_identifier (TAG_SELECTOR)));
7025 push_parm_decl (build_tree_list
7026 (build_tree_list (decl_specs,
7027 build1 (INDIRECT_REF, NULL_TREE, ucmd_id)),
7030 /* Generate argument declarations if a keyword_decl. */
7031 if (METHOD_SEL_ARGS (method))
7033 tree arglist = METHOD_SEL_ARGS (method);
7036 tree arg_spec = TREE_PURPOSE (TREE_TYPE (arglist));
7037 tree arg_decl = TREE_VALUE (TREE_TYPE (arglist));
7041 tree last_expr = expr_last (arg_decl);
7043 /* Unite the abstract decl with its name. */
7044 TREE_OPERAND (last_expr, 0) = KEYWORD_ARG_NAME (arglist);
7045 push_parm_decl (build_tree_list
7046 (build_tree_list (arg_spec, arg_decl),
7049 /* Unhook: restore the abstract declarator. */
7050 TREE_OPERAND (last_expr, 0) = NULL_TREE;
7054 push_parm_decl (build_tree_list
7055 (build_tree_list (arg_spec,
7056 KEYWORD_ARG_NAME (arglist)),
7059 arglist = TREE_CHAIN (arglist);
7064 if (METHOD_ADD_ARGS (method) != NULL_TREE
7065 && METHOD_ADD_ARGS (method) != objc_ellipsis_node)
7067 /* We have a variable length selector - in "prototype" format. */
7068 tree akey = TREE_PURPOSE (METHOD_ADD_ARGS (method));
7071 /* This must be done prior to calling pushdecl. pushdecl is
7072 going to change our chain on us. */
7073 tree nextkey = TREE_CHAIN (akey);
7081 warn_with_method (message, mtype, method)
7082 const char *message;
7086 if (!diagnostic_count_diagnostic (global_dc, DK_WARNING))
7089 diagnostic_report_current_function (global_dc);
7091 /* Add a readable method name to the warning. */
7092 warning_with_file_and_line (DECL_SOURCE_FILE (method),
7093 DECL_SOURCE_LINE (method),
7096 gen_method_decl (method, errbuf));
7099 /* Return 1 if METHOD is consistent with PROTO. */
7102 comp_method_with_proto (method, proto)
7105 /* Create a function template node at most once. */
7106 if (!function1_template)
7107 function1_template = make_node (FUNCTION_TYPE);
7109 /* Install argument types - normally set by build_function_type. */
7110 TYPE_ARG_TYPES (function1_template) = get_arg_type_list (proto, METHOD_DEF, 0);
7112 /* install return type */
7113 TREE_TYPE (function1_template) = groktypename (TREE_TYPE (proto));
7115 return comptypes (TREE_TYPE (METHOD_DEFINITION (method)), function1_template);
7118 /* Return 1 if PROTO1 is consistent with PROTO2. */
7121 comp_proto_with_proto (proto0, proto1)
7122 tree proto0, proto1;
7124 /* Create a couple of function_template nodes at most once. */
7125 if (!function1_template)
7126 function1_template = make_node (FUNCTION_TYPE);
7127 if (!function2_template)
7128 function2_template = make_node (FUNCTION_TYPE);
7130 /* Install argument types; normally set by build_function_type. */
7131 TYPE_ARG_TYPES (function1_template) = get_arg_type_list (proto0, METHOD_REF, 0);
7132 TYPE_ARG_TYPES (function2_template) = get_arg_type_list (proto1, METHOD_REF, 0);
7134 /* Install return type. */
7135 TREE_TYPE (function1_template) = groktypename (TREE_TYPE (proto0));
7136 TREE_TYPE (function2_template) = groktypename (TREE_TYPE (proto1));
7138 return comptypes (function1_template, function2_template);
7141 /* - Generate an identifier for the function. the format is "_n_cls",
7142 where 1 <= n <= nMethods, and cls is the name the implementation we
7144 - Install the return type from the method declaration.
7145 - If we have a prototype, check for type consistency. */
7148 really_start_method (method, parmlist)
7149 tree method, parmlist;
7151 tree sc_spec, ret_spec, ret_decl, decl_specs;
7152 tree method_decl, method_id;
7153 const char *sel_name, *class_name, *cat_name;
7156 /* Synth the storage class & assemble the return type. */
7157 sc_spec = tree_cons (NULL_TREE, ridpointers[(int) RID_STATIC], NULL_TREE);
7158 ret_spec = TREE_PURPOSE (TREE_TYPE (method));
7159 decl_specs = chainon (sc_spec, ret_spec);
7161 sel_name = IDENTIFIER_POINTER (METHOD_SEL_NAME (method));
7162 class_name = IDENTIFIER_POINTER (CLASS_NAME (objc_implementation_context));
7163 cat_name = ((TREE_CODE (objc_implementation_context)
7164 == CLASS_IMPLEMENTATION_TYPE)
7166 : IDENTIFIER_POINTER (CLASS_SUPER_NAME (objc_implementation_context)));
7169 /* Make sure this is big enough for any plausible method label. */
7170 buf = (char *) alloca (50 + strlen (sel_name) + strlen (class_name)
7171 + (cat_name ? strlen (cat_name) : 0));
7173 OBJC_GEN_METHOD_LABEL (buf, TREE_CODE (method) == INSTANCE_METHOD_DECL,
7174 class_name, cat_name, sel_name, method_slot);
7176 method_id = get_identifier (buf);
7178 method_decl = build_nt (CALL_EXPR, method_id, parmlist, NULL_TREE);
7180 /* Check the declarator portion of the return type for the method. */
7181 if ((ret_decl = TREE_VALUE (TREE_TYPE (method))))
7183 /* Unite the complex decl (specified in the abstract decl) with the
7184 function decl just synthesized..(int *), (int (*)()), (int (*)[]). */
7185 tree save_expr = expr_last (ret_decl);
7187 TREE_OPERAND (save_expr, 0) = method_decl;
7188 method_decl = ret_decl;
7190 /* Fool the parser into thinking it is starting a function. */
7191 start_function (decl_specs, method_decl, NULL_TREE);
7193 /* Unhook: this has the effect of restoring the abstract declarator. */
7194 TREE_OPERAND (save_expr, 0) = NULL_TREE;
7199 TREE_VALUE (TREE_TYPE (method)) = method_decl;
7201 /* Fool the parser into thinking it is starting a function. */
7202 start_function (decl_specs, method_decl, NULL_TREE);
7204 /* Unhook: this has the effect of restoring the abstract declarator. */
7205 TREE_VALUE (TREE_TYPE (method)) = NULL_TREE;
7208 METHOD_DEFINITION (method) = current_function_decl;
7210 /* Check consistency...start_function, pushdecl, duplicate_decls. */
7212 if (implementation_template != objc_implementation_context)
7216 if (TREE_CODE (method) == INSTANCE_METHOD_DECL)
7217 proto = lookup_instance_method_static (implementation_template,
7218 METHOD_SEL_NAME (method));
7220 proto = lookup_class_method_static (implementation_template,
7221 METHOD_SEL_NAME (method));
7223 if (proto && ! comp_method_with_proto (method, proto))
7225 char type = (TREE_CODE (method) == INSTANCE_METHOD_DECL ? '-' : '+');
7227 warn_with_method ("conflicting types for", type, method);
7228 warn_with_method ("previous declaration of", type, proto);
7233 /* The following routine is always called...this "architecture" is to
7234 accommodate "old-style" variable length selectors.
7236 - a:a b:b // prototype ; id c; id d; // old-style. */
7239 continue_method_def ()
7243 if (METHOD_ADD_ARGS (objc_method_context) == objc_ellipsis_node)
7244 /* We have a `, ...' immediately following the selector. */
7245 parmlist = get_parm_info (0);
7247 parmlist = get_parm_info (1); /* place a `void_at_end' */
7249 /* Set self_decl from the first argument...this global is used by
7250 build_ivar_reference calling build_indirect_ref. */
7251 self_decl = TREE_PURPOSE (parmlist);
7254 really_start_method (objc_method_context, parmlist);
7255 store_parm_decls ();
7258 /* Called by the parser, from the `pushlevel' production. */
7263 if (!UOBJC_SUPER_decl)
7265 UOBJC_SUPER_decl = start_decl (get_identifier (UTAG_SUPER),
7266 build_tree_list (NULL_TREE,
7267 objc_super_template),
7270 finish_decl (UOBJC_SUPER_decl, NULL_TREE, NULL_TREE);
7272 /* This prevents `unused variable' warnings when compiling with -Wall. */
7273 TREE_USED (UOBJC_SUPER_decl) = 1;
7274 DECL_ARTIFICIAL (UOBJC_SUPER_decl) = 1;
7278 /* _n_Method (id self, SEL sel, ...)
7280 struct objc_super _S;
7281 _msgSuper ((_S.self = self, _S.class = _cls, &_S), ...);
7285 get_super_receiver ()
7287 if (objc_method_context)
7289 tree super_expr, super_expr_list;
7291 /* Set receiver to self. */
7292 super_expr = build_component_ref (UOBJC_SUPER_decl, self_id);
7293 super_expr = build_modify_expr (super_expr, NOP_EXPR, self_decl);
7294 super_expr_list = build_tree_list (NULL_TREE, super_expr);
7296 /* Set class to begin searching. */
7297 super_expr = build_component_ref (UOBJC_SUPER_decl,
7298 get_identifier ("class"));
7300 if (TREE_CODE (objc_implementation_context) == CLASS_IMPLEMENTATION_TYPE)
7302 /* [_cls, __cls]Super are "pre-built" in
7303 synth_forward_declarations. */
7305 super_expr = build_modify_expr (super_expr, NOP_EXPR,
7306 ((TREE_CODE (objc_method_context)
7307 == INSTANCE_METHOD_DECL)
7309 : uucls_super_ref));
7313 /* We have a category. */
7315 tree super_name = CLASS_SUPER_NAME (implementation_template);
7318 /* Barf if super used in a category of Object. */
7321 error ("no super class declared in interface for `%s'",
7322 IDENTIFIER_POINTER (CLASS_NAME (implementation_template)));
7323 return error_mark_node;
7326 if (flag_next_runtime)
7328 super_class = get_class_reference (super_name);
7329 if (TREE_CODE (objc_method_context) == CLASS_METHOD_DECL)
7330 /* Cast the super class to 'id', since the user may not have
7331 included <objc/objc-class.h>, leaving 'struct objc_class'
7332 an incomplete type. */
7334 = build_component_ref (build_indirect_ref
7335 (build_c_cast (id_type, super_class), "->"),
7336 get_identifier ("isa"));
7340 add_class_reference (super_name);
7341 super_class = (TREE_CODE (objc_method_context) == INSTANCE_METHOD_DECL
7342 ? objc_get_class_decl : objc_get_meta_class_decl);
7343 assemble_external (super_class);
7345 = build_function_call
7349 my_build_string (IDENTIFIER_LENGTH (super_name) + 1,
7350 IDENTIFIER_POINTER (super_name))));
7353 TREE_TYPE (super_class) = TREE_TYPE (ucls_super_ref);
7354 super_expr = build_modify_expr (super_expr, NOP_EXPR, super_class);
7357 chainon (super_expr_list, build_tree_list (NULL_TREE, super_expr));
7359 super_expr = build_unary_op (ADDR_EXPR, UOBJC_SUPER_decl, 0);
7360 chainon (super_expr_list, build_tree_list (NULL_TREE, super_expr));
7362 return build_compound_expr (super_expr_list);
7366 error ("[super ...] must appear in a method context");
7367 return error_mark_node;
7372 encode_method_def (func_decl)
7377 HOST_WIDE_INT max_parm_end = 0;
7382 encode_type (TREE_TYPE (TREE_TYPE (func_decl)),
7383 obstack_object_size (&util_obstack),
7384 OBJC_ENCODE_INLINE_DEFS);
7387 for (parms = DECL_ARGUMENTS (func_decl); parms;
7388 parms = TREE_CHAIN (parms))
7390 HOST_WIDE_INT parm_end = (forwarding_offset (parms)
7391 + int_size_in_bytes (TREE_TYPE (parms)));
7393 if (! offset_is_register && parm_end > max_parm_end)
7394 max_parm_end = parm_end;
7397 stack_size = max_parm_end - OBJC_FORWARDING_MIN_OFFSET;
7399 sprintf (buffer, "%d", stack_size);
7400 obstack_grow (&util_obstack, buffer, strlen (buffer));
7402 /* Argument types. */
7403 for (parms = DECL_ARGUMENTS (func_decl); parms;
7404 parms = TREE_CHAIN (parms))
7407 encode_type (TREE_TYPE (parms),
7408 obstack_object_size (&util_obstack),
7409 OBJC_ENCODE_INLINE_DEFS);
7411 /* Compute offset. */
7412 sprintf (buffer, "%d", forwarding_offset (parms));
7414 /* Indicate register. */
7415 if (offset_is_register)
7416 obstack_1grow (&util_obstack, '+');
7418 obstack_grow (&util_obstack, buffer, strlen (buffer));
7421 /* Null terminate string. */
7422 obstack_1grow (&util_obstack, 0);
7423 result = get_identifier (obstack_finish (&util_obstack));
7424 obstack_free (&util_obstack, util_firstobj);
7429 objc_expand_function_end ()
7431 METHOD_ENCODING (objc_method_context) = encode_method_def (current_function_decl);
7435 finish_method_def ()
7437 lang_expand_function_end = objc_expand_function_end;
7438 finish_function (0, 1);
7439 lang_expand_function_end = NULL;
7441 /* Required to implement _msgSuper. This must be done AFTER finish_function,
7442 since the optimizer may find "may be used before set" errors. */
7443 objc_method_context = NULL_TREE;
7448 lang_report_error_function (decl)
7451 if (objc_method_context)
7453 fprintf (stderr, "In method `%s'\n",
7454 IDENTIFIER_POINTER (METHOD_SEL_NAME (objc_method_context)));
7464 is_complex_decl (type)
7467 return (TREE_CODE (type) == ARRAY_TYPE
7468 || TREE_CODE (type) == FUNCTION_TYPE
7469 || (TREE_CODE (type) == POINTER_TYPE && ! IS_ID (type)));
7473 /* Code to convert a decl node into text for a declaration in C. */
7475 static char tmpbuf[256];
7478 adorn_decl (decl, str)
7482 enum tree_code code = TREE_CODE (decl);
7484 if (code == ARRAY_REF)
7486 tree an_int_cst = TREE_OPERAND (decl, 1);
7488 if (an_int_cst && TREE_CODE (an_int_cst) == INTEGER_CST)
7489 sprintf (str + strlen (str), "[%ld]",
7490 (long) TREE_INT_CST_LOW (an_int_cst));
7495 else if (code == ARRAY_TYPE)
7497 tree an_int_cst = TYPE_SIZE (decl);
7498 tree array_of = TREE_TYPE (decl);
7500 if (an_int_cst && TREE_CODE (an_int_cst) == INTEGER_TYPE)
7501 sprintf (str + strlen (str), "[%ld]",
7502 (long) (TREE_INT_CST_LOW (an_int_cst)
7503 / TREE_INT_CST_LOW (TYPE_SIZE (array_of))));
7508 else if (code == CALL_EXPR)
7510 tree chain = TREE_PURPOSE (TREE_OPERAND (decl, 1));
7515 gen_declaration_1 (chain, str);
7516 chain = TREE_CHAIN (chain);
7523 else if (code == FUNCTION_TYPE)
7525 tree chain = TYPE_ARG_TYPES (decl);
7528 while (chain && TREE_VALUE (chain) != void_type_node)
7530 gen_declaration_1 (TREE_VALUE (chain), str);
7531 chain = TREE_CHAIN (chain);
7532 if (chain && TREE_VALUE (chain) != void_type_node)
7538 else if (code == INDIRECT_REF)
7540 strcpy (tmpbuf, "*");
7541 if (TREE_TYPE (decl) && TREE_CODE (TREE_TYPE (decl)) == TREE_LIST)
7545 for (chain = nreverse (copy_list (TREE_TYPE (decl)));
7547 chain = TREE_CHAIN (chain))
7549 if (TREE_CODE (TREE_VALUE (chain)) == IDENTIFIER_NODE)
7551 strcat (tmpbuf, " ");
7552 strcat (tmpbuf, IDENTIFIER_POINTER (TREE_VALUE (chain)));
7556 strcat (tmpbuf, " ");
7558 strcat (tmpbuf, str);
7559 strcpy (str, tmpbuf);
7562 else if (code == POINTER_TYPE)
7564 strcpy (tmpbuf, "*");
7565 if (TREE_READONLY (decl) || TYPE_VOLATILE (decl))
7567 if (TREE_READONLY (decl))
7568 strcat (tmpbuf, " const");
7569 if (TYPE_VOLATILE (decl))
7570 strcat (tmpbuf, " volatile");
7572 strcat (tmpbuf, " ");
7574 strcat (tmpbuf, str);
7575 strcpy (str, tmpbuf);
7580 gen_declarator (decl, buf, name)
7587 enum tree_code code = TREE_CODE (decl);
7597 op = TREE_OPERAND (decl, 0);
7599 /* We have a pointer to a function or array...(*)(), (*)[] */
7600 if ((code == ARRAY_REF || code == CALL_EXPR)
7601 && op && TREE_CODE (op) == INDIRECT_REF)
7604 str = gen_declarator (op, buf, name);
7608 strcpy (tmpbuf, "(");
7609 strcat (tmpbuf, str);
7610 strcat (tmpbuf, ")");
7611 strcpy (str, tmpbuf);
7614 adorn_decl (decl, str);
7623 /* This clause is done iteratively rather than recursively. */
7626 op = (is_complex_decl (TREE_TYPE (decl))
7627 ? TREE_TYPE (decl) : NULL_TREE);
7629 adorn_decl (decl, str);
7631 /* We have a pointer to a function or array...(*)(), (*)[] */
7632 if (code == POINTER_TYPE
7633 && op && (TREE_CODE (op) == FUNCTION_TYPE
7634 || TREE_CODE (op) == ARRAY_TYPE))
7636 strcpy (tmpbuf, "(");
7637 strcat (tmpbuf, str);
7638 strcat (tmpbuf, ")");
7639 strcpy (str, tmpbuf);
7642 decl = (is_complex_decl (TREE_TYPE (decl))
7643 ? TREE_TYPE (decl) : NULL_TREE);
7646 while (decl && (code = TREE_CODE (decl)))
7651 case IDENTIFIER_NODE:
7652 /* Will only happen if we are processing a "raw" expr-decl. */
7653 strcpy (buf, IDENTIFIER_POINTER (decl));
7664 /* We have an abstract declarator or a _DECL node. */
7672 gen_declspecs (declspecs, buf, raw)
7681 for (chain = nreverse (copy_list (declspecs));
7682 chain; chain = TREE_CHAIN (chain))
7684 tree aspec = TREE_VALUE (chain);
7686 if (TREE_CODE (aspec) == IDENTIFIER_NODE)
7687 strcat (buf, IDENTIFIER_POINTER (aspec));
7688 else if (TREE_CODE (aspec) == RECORD_TYPE)
7690 if (TYPE_NAME (aspec))
7692 tree protocol_list = TYPE_PROTOCOL_LIST (aspec);
7694 if (! TREE_STATIC_TEMPLATE (aspec))
7695 strcat (buf, "struct ");
7696 strcat (buf, IDENTIFIER_POINTER (TYPE_NAME (aspec)));
7701 tree chain = protocol_list;
7708 (PROTOCOL_NAME (TREE_VALUE (chain))));
7709 chain = TREE_CHAIN (chain);
7718 strcat (buf, "untagged struct");
7721 else if (TREE_CODE (aspec) == UNION_TYPE)
7723 if (TYPE_NAME (aspec))
7725 if (! TREE_STATIC_TEMPLATE (aspec))
7726 strcat (buf, "union ");
7727 strcat (buf, IDENTIFIER_POINTER (TYPE_NAME (aspec)));
7730 strcat (buf, "untagged union");
7733 else if (TREE_CODE (aspec) == ENUMERAL_TYPE)
7735 if (TYPE_NAME (aspec))
7737 if (! TREE_STATIC_TEMPLATE (aspec))
7738 strcat (buf, "enum ");
7739 strcat (buf, IDENTIFIER_POINTER (TYPE_NAME (aspec)));
7742 strcat (buf, "untagged enum");
7745 else if (TREE_CODE (aspec) == TYPE_DECL && DECL_NAME (aspec))
7746 strcat (buf, IDENTIFIER_POINTER (DECL_NAME (aspec)));
7748 else if (IS_ID (aspec))
7750 tree protocol_list = TYPE_PROTOCOL_LIST (aspec);
7755 tree chain = protocol_list;
7762 (PROTOCOL_NAME (TREE_VALUE (chain))));
7763 chain = TREE_CHAIN (chain);
7770 if (TREE_CHAIN (chain))
7776 /* Type qualifiers. */
7777 if (TREE_READONLY (declspecs))
7778 strcat (buf, "const ");
7779 if (TYPE_VOLATILE (declspecs))
7780 strcat (buf, "volatile ");
7782 switch (TREE_CODE (declspecs))
7784 /* Type specifiers. */
7787 declspecs = TYPE_MAIN_VARIANT (declspecs);
7789 /* Signed integer types. */
7791 if (declspecs == short_integer_type_node)
7792 strcat (buf, "short int ");
7793 else if (declspecs == integer_type_node)
7794 strcat (buf, "int ");
7795 else if (declspecs == long_integer_type_node)
7796 strcat (buf, "long int ");
7797 else if (declspecs == long_long_integer_type_node)
7798 strcat (buf, "long long int ");
7799 else if (declspecs == signed_char_type_node
7800 || declspecs == char_type_node)
7801 strcat (buf, "char ");
7803 /* Unsigned integer types. */
7805 else if (declspecs == short_unsigned_type_node)
7806 strcat (buf, "unsigned short ");
7807 else if (declspecs == unsigned_type_node)
7808 strcat (buf, "unsigned int ");
7809 else if (declspecs == long_unsigned_type_node)
7810 strcat (buf, "unsigned long ");
7811 else if (declspecs == long_long_unsigned_type_node)
7812 strcat (buf, "unsigned long long ");
7813 else if (declspecs == unsigned_char_type_node)
7814 strcat (buf, "unsigned char ");
7818 declspecs = TYPE_MAIN_VARIANT (declspecs);
7820 if (declspecs == float_type_node)
7821 strcat (buf, "float ");
7822 else if (declspecs == double_type_node)
7823 strcat (buf, "double ");
7824 else if (declspecs == long_double_type_node)
7825 strcat (buf, "long double ");
7829 if (TYPE_NAME (declspecs)
7830 && TREE_CODE (TYPE_NAME (declspecs)) == IDENTIFIER_NODE)
7832 tree protocol_list = TYPE_PROTOCOL_LIST (declspecs);
7834 if (! TREE_STATIC_TEMPLATE (declspecs))
7835 strcat (buf, "struct ");
7836 strcat (buf, IDENTIFIER_POINTER (TYPE_NAME (declspecs)));
7840 tree chain = protocol_list;
7847 (PROTOCOL_NAME (TREE_VALUE (chain))));
7848 chain = TREE_CHAIN (chain);
7857 strcat (buf, "untagged struct");
7863 if (TYPE_NAME (declspecs)
7864 && TREE_CODE (TYPE_NAME (declspecs)) == IDENTIFIER_NODE)
7866 strcat (buf, "union ");
7867 strcat (buf, IDENTIFIER_POINTER (TYPE_NAME (declspecs)));
7872 strcat (buf, "untagged union ");
7876 if (TYPE_NAME (declspecs)
7877 && TREE_CODE (TYPE_NAME (declspecs)) == IDENTIFIER_NODE)
7879 strcat (buf, "enum ");
7880 strcat (buf, IDENTIFIER_POINTER (TYPE_NAME (declspecs)));
7885 strcat (buf, "untagged enum ");
7889 strcat (buf, "void ");
7894 tree protocol_list = TYPE_PROTOCOL_LIST (declspecs);
7899 tree chain = protocol_list;
7906 (PROTOCOL_NAME (TREE_VALUE (chain))));
7907 chain = TREE_CHAIN (chain);
7923 /* Given a tree node, produce a printable description of it in the given
7924 buffer, overwriting the buffer. */
7927 gen_declaration (atype_or_adecl, buf)
7928 tree atype_or_adecl;
7932 gen_declaration_1 (atype_or_adecl, buf);
7936 /* Given a tree node, append a printable description to the end of the
7940 gen_declaration_1 (atype_or_adecl, buf)
7941 tree atype_or_adecl;
7946 if (TREE_CODE (atype_or_adecl) == TREE_LIST)
7948 tree declspecs; /* "identifier_node", "record_type" */
7949 tree declarator; /* "array_ref", "indirect_ref", "call_expr"... */
7951 /* We have a "raw", abstract declarator (typename). */
7952 declarator = TREE_VALUE (atype_or_adecl);
7953 declspecs = TREE_PURPOSE (atype_or_adecl);
7955 gen_declspecs (declspecs, buf, 1);
7959 strcat (buf, gen_declarator (declarator, declbuf, ""));
7966 tree declspecs; /* "integer_type", "real_type", "record_type"... */
7967 tree declarator; /* "array_type", "function_type", "pointer_type". */
7969 if (TREE_CODE (atype_or_adecl) == FIELD_DECL
7970 || TREE_CODE (atype_or_adecl) == PARM_DECL
7971 || TREE_CODE (atype_or_adecl) == FUNCTION_DECL)
7972 atype = TREE_TYPE (atype_or_adecl);
7974 /* Assume we have a *_type node. */
7975 atype = atype_or_adecl;
7977 if (is_complex_decl (atype))
7981 /* Get the declaration specifier; it is at the end of the list. */
7982 declarator = chain = atype;
7984 chain = TREE_TYPE (chain); /* not TREE_CHAIN (chain); */
7985 while (is_complex_decl (chain));
7992 declarator = NULL_TREE;
7995 gen_declspecs (declspecs, buf, 0);
7997 if (TREE_CODE (atype_or_adecl) == FIELD_DECL
7998 || TREE_CODE (atype_or_adecl) == PARM_DECL
7999 || TREE_CODE (atype_or_adecl) == FUNCTION_DECL)
8001 const char *const decl_name =
8002 (DECL_NAME (atype_or_adecl)
8003 ? IDENTIFIER_POINTER (DECL_NAME (atype_or_adecl)) : "");
8008 strcat (buf, gen_declarator (declarator, declbuf, decl_name));
8011 else if (decl_name[0])
8014 strcat (buf, decl_name);
8017 else if (declarator)
8020 strcat (buf, gen_declarator (declarator, declbuf, ""));
8025 #define RAW_TYPESPEC(meth) (TREE_VALUE (TREE_PURPOSE (TREE_TYPE (meth))))
8027 /* Given a method tree, put a printable description into the given
8028 buffer (overwriting) and return a pointer to the buffer. */
8031 gen_method_decl (method, buf)
8038 if (RAW_TYPESPEC (method) != objc_object_reference)
8041 gen_declaration_1 (TREE_TYPE (method), buf);
8045 chain = METHOD_SEL_ARGS (method);
8048 /* We have a chain of keyword_decls. */
8051 if (KEYWORD_KEY_NAME (chain))
8052 strcat (buf, IDENTIFIER_POINTER (KEYWORD_KEY_NAME (chain)));
8055 if (RAW_TYPESPEC (chain) != objc_object_reference)
8058 gen_declaration_1 (TREE_TYPE (chain), buf);
8062 strcat (buf, IDENTIFIER_POINTER (KEYWORD_ARG_NAME (chain)));
8063 if ((chain = TREE_CHAIN (chain)))
8068 if (METHOD_ADD_ARGS (method) == objc_ellipsis_node)
8069 strcat (buf, ", ...");
8070 else if (METHOD_ADD_ARGS (method))
8072 /* We have a tree list node as generate by get_parm_info. */
8073 chain = TREE_PURPOSE (METHOD_ADD_ARGS (method));
8075 /* Know we have a chain of parm_decls. */
8079 gen_declaration_1 (chain, buf);
8080 chain = TREE_CHAIN (chain);
8086 /* We have a unary selector. */
8087 strcat (buf, IDENTIFIER_POINTER (METHOD_SEL_NAME (method)));
8095 /* Dump an @interface declaration of the supplied class CHAIN to the
8096 supplied file FP. Used to implement the -gen-decls option (which
8097 prints out an @interface declaration of all classes compiled in
8098 this run); potentially useful for debugging the compiler too. */
8100 dump_interface (fp, chain)
8104 /* FIXME: A heap overflow here whenever a method (or ivar)
8105 declaration is so long that it doesn't fit in the buffer. The
8106 code and all the related functions should be rewritten to avoid
8107 using fixed size buffers. */
8108 char *buf = (char *) xmalloc (1024 * 10);
8109 const char *my_name = IDENTIFIER_POINTER (CLASS_NAME (chain));
8110 tree ivar_decls = CLASS_RAW_IVARS (chain);
8111 tree nst_methods = CLASS_NST_METHODS (chain);
8112 tree cls_methods = CLASS_CLS_METHODS (chain);
8114 fprintf (fp, "\n@interface %s", my_name);
8116 /* CLASS_SUPER_NAME is used to store the superclass name for
8117 classes, and the category name for categories. */
8118 if (CLASS_SUPER_NAME (chain))
8120 const char *name = IDENTIFIER_POINTER (CLASS_SUPER_NAME (chain));
8122 if (TREE_CODE (chain) == CATEGORY_IMPLEMENTATION_TYPE
8123 || TREE_CODE (chain) == CATEGORY_INTERFACE_TYPE)
8125 fprintf (fp, " (%s)\n", name);
8129 fprintf (fp, " : %s\n", name);
8135 /* FIXME - the following doesn't seem to work at the moment. */
8138 fprintf (fp, "{\n");
8141 fprintf (fp, "\t%s;\n", gen_declaration (ivar_decls, buf));
8142 ivar_decls = TREE_CHAIN (ivar_decls);
8145 fprintf (fp, "}\n");
8150 fprintf (fp, "- %s;\n", gen_method_decl (nst_methods, buf));
8151 nst_methods = TREE_CHAIN (nst_methods);
8156 fprintf (fp, "+ %s;\n", gen_method_decl (cls_methods, buf));
8157 cls_methods = TREE_CHAIN (cls_methods);
8160 fprintf (fp, "@end\n");
8163 /* Demangle function for Objective-C */
8165 objc_demangle (mangled)
8166 const char *mangled;
8168 char *demangled, *cp;
8170 if (mangled[0] == '_' &&
8171 (mangled[1] == 'i' || mangled[1] == 'c') &&
8174 cp = demangled = xmalloc(strlen(mangled) + 2);
8175 if (mangled[1] == 'i')
8176 *cp++ = '-'; /* for instance method */
8178 *cp++ = '+'; /* for class method */
8179 *cp++ = '['; /* opening left brace */
8180 strcpy(cp, mangled+3); /* tack on the rest of the mangled name */
8181 while (*cp && *cp == '_')
8182 cp++; /* skip any initial underbars in class name */
8183 cp = strchr(cp, '_'); /* find first non-initial underbar */
8186 free(demangled); /* not mangled name */
8189 if (cp[1] == '_') /* easy case: no category name */
8191 *cp++ = ' '; /* replace two '_' with one ' ' */
8192 strcpy(cp, mangled + (cp - demangled) + 2);
8196 *cp++ = '('; /* less easy case: category name */
8197 cp = strchr(cp, '_');
8200 free(demangled); /* not mangled name */
8204 *cp++ = ' '; /* overwriting 1st char of method name... */
8205 strcpy(cp, mangled + (cp - demangled)); /* get it back */
8207 while (*cp && *cp == '_')
8208 cp++; /* skip any initial underbars in method name */
8211 *cp = ':'; /* replace remaining '_' with ':' */
8212 *cp++ = ']'; /* closing right brace */
8213 *cp++ = 0; /* string terminator */
8217 return mangled; /* not an objc mangled name */
8221 objc_printable_name (decl, kind)
8223 int kind ATTRIBUTE_UNUSED;
8225 return objc_demangle (IDENTIFIER_POINTER (DECL_NAME (decl)));
8231 gcc_obstack_init (&util_obstack);
8232 util_firstobj = (char *) obstack_finish (&util_obstack);
8234 errbuf = (char *) xmalloc (BUFSIZE);
8236 synth_module_prologue ();
8242 struct imp_entry *impent;
8244 /* The internally generated initializers appear to have missing braces.
8245 Don't warn about this. */
8246 int save_warn_missing_braces = warn_missing_braces;
8247 warn_missing_braces = 0;
8249 /* A missing @end may not be detected by the parser. */
8250 if (objc_implementation_context)
8252 warning ("`@end' missing in implementation context");
8253 finish_class (objc_implementation_context);
8254 objc_ivar_chain = NULL_TREE;
8255 objc_implementation_context = NULL_TREE;
8258 generate_forward_declaration_to_string_table ();
8260 #ifdef OBJC_PROLOGUE
8264 /* Process the static instances here because initialization of objc_symtab
8266 if (objc_static_instances)
8267 generate_static_references ();
8269 if (imp_list || class_names_chain
8270 || meth_var_names_chain || meth_var_types_chain || sel_ref_chain)
8271 generate_objc_symtab_decl ();
8273 for (impent = imp_list; impent; impent = impent->next)
8275 objc_implementation_context = impent->imp_context;
8276 implementation_template = impent->imp_template;
8278 UOBJC_CLASS_decl = impent->class_decl;
8279 UOBJC_METACLASS_decl = impent->meta_decl;
8281 /* Dump the @interface of each class as we compile it, if the
8282 -gen-decls option is in use. TODO: Dump the classes in the
8283 order they were found, rather than in reverse order as we
8285 if (flag_gen_declaration)
8287 dump_interface (gen_declaration_file, objc_implementation_context);
8290 if (TREE_CODE (objc_implementation_context) == CLASS_IMPLEMENTATION_TYPE)
8292 /* all of the following reference the string pool... */
8293 generate_ivar_lists ();
8294 generate_dispatch_tables ();
8295 generate_shared_structures ();
8299 generate_dispatch_tables ();
8300 generate_category (objc_implementation_context);
8304 /* If we are using an array of selectors, we must always
8305 finish up the array decl even if no selectors were used. */
8306 if (! flag_next_runtime || sel_ref_chain)
8307 build_selector_translation_table ();
8310 generate_protocols ();
8312 if (objc_implementation_context || class_names_chain || objc_static_instances
8313 || meth_var_names_chain || meth_var_types_chain || sel_ref_chain)
8315 /* Arrange for ObjC data structures to be initialized at run time. */
8316 rtx init_sym = build_module_descriptor ();
8317 if (init_sym && targetm.have_ctors_dtors)
8318 (* targetm.asm_out.constructor) (init_sym, DEFAULT_INIT_PRIORITY);
8321 /* Dump the class references. This forces the appropriate classes
8322 to be linked into the executable image, preserving unix archive
8323 semantics. This can be removed when we move to a more dynamically
8324 linked environment. */
8326 for (chain = cls_ref_chain; chain; chain = TREE_CHAIN (chain))
8328 handle_class_ref (chain);
8329 if (TREE_PURPOSE (chain))
8330 generate_classref_translation_entry (chain);
8333 for (impent = imp_list; impent; impent = impent->next)
8334 handle_impent (impent);
8336 /* Dump the string table last. */
8338 generate_strings ();
8345 /* Run through the selector hash tables and print a warning for any
8346 selector which has multiple methods. */
8348 for (slot = 0; slot < SIZEHASHTABLE; slot++)
8349 for (hsh = cls_method_hash_list[slot]; hsh; hsh = hsh->next)
8352 tree meth = hsh->key;
8353 char type = (TREE_CODE (meth) == INSTANCE_METHOD_DECL
8357 warning ("potential selector conflict for method `%s'",
8358 IDENTIFIER_POINTER (METHOD_SEL_NAME (meth)));
8359 warn_with_method ("found", type, meth);
8360 for (loop = hsh->list; loop; loop = loop->next)
8361 warn_with_method ("found", type, loop->value);
8364 for (slot = 0; slot < SIZEHASHTABLE; slot++)
8365 for (hsh = nst_method_hash_list[slot]; hsh; hsh = hsh->next)
8368 tree meth = hsh->key;
8369 char type = (TREE_CODE (meth) == INSTANCE_METHOD_DECL
8373 warning ("potential selector conflict for method `%s'",
8374 IDENTIFIER_POINTER (METHOD_SEL_NAME (meth)));
8375 warn_with_method ("found", type, meth);
8376 for (loop = hsh->list; loop; loop = loop->next)
8377 warn_with_method ("found", type, loop->value);
8381 warn_missing_braces = save_warn_missing_braces;
8384 /* Subroutines of finish_objc. */
8387 generate_classref_translation_entry (chain)
8390 tree expr, name, decl_specs, decl, sc_spec;
8393 type = TREE_TYPE (TREE_PURPOSE (chain));
8395 expr = add_objc_string (TREE_VALUE (chain), class_names);
8396 expr = build_c_cast (type, expr); /* cast! */
8398 name = DECL_NAME (TREE_PURPOSE (chain));
8400 sc_spec = build_tree_list (NULL_TREE, ridpointers[(int) RID_STATIC]);
8402 /* static struct objc_class * _OBJC_CLASS_REFERENCES_n = ...; */
8403 decl_specs = tree_cons (NULL_TREE, type, sc_spec);
8405 /* The decl that is returned from start_decl is the one that we
8406 forward declared in build_class_reference. */
8407 decl = start_decl (name, decl_specs, 1, NULL_TREE);
8408 DECL_CONTEXT (decl) = NULL_TREE;
8409 finish_decl (decl, expr, NULL_TREE);
8414 handle_class_ref (chain)
8417 const char *name = IDENTIFIER_POINTER (TREE_VALUE (chain));
8418 char *string = (char *) alloca (strlen (name) + 30);
8422 sprintf (string, "%sobjc_class_name_%s",
8423 (flag_next_runtime ? "." : "__"), name);
8425 #ifdef ASM_DECLARE_UNRESOLVED_REFERENCE
8426 if (flag_next_runtime)
8428 ASM_DECLARE_UNRESOLVED_REFERENCE (asm_out_file, string);
8433 /* Make a decl for this name, so we can use its address in a tree. */
8434 decl = build_decl (VAR_DECL, get_identifier (string), char_type_node);
8435 DECL_EXTERNAL (decl) = 1;
8436 TREE_PUBLIC (decl) = 1;
8439 rest_of_decl_compilation (decl, 0, 0, 0);
8441 /* Make a decl for the address. */
8442 sprintf (string, "%sobjc_class_ref_%s",
8443 (flag_next_runtime ? "." : "__"), name);
8444 exp = build1 (ADDR_EXPR, string_type_node, decl);
8445 decl = build_decl (VAR_DECL, get_identifier (string), string_type_node);
8446 DECL_INITIAL (decl) = exp;
8447 TREE_STATIC (decl) = 1;
8448 TREE_USED (decl) = 1;
8451 rest_of_decl_compilation (decl, 0, 0, 0);
8455 handle_impent (impent)
8456 struct imp_entry *impent;
8460 objc_implementation_context = impent->imp_context;
8461 implementation_template = impent->imp_template;
8463 if (TREE_CODE (impent->imp_context) == CLASS_IMPLEMENTATION_TYPE)
8465 const char *const class_name =
8466 IDENTIFIER_POINTER (CLASS_NAME (impent->imp_context));
8468 string = (char *) alloca (strlen (class_name) + 30);
8470 sprintf (string, "%sobjc_class_name_%s",
8471 (flag_next_runtime ? "." : "__"), class_name);
8473 else if (TREE_CODE (impent->imp_context) == CATEGORY_IMPLEMENTATION_TYPE)
8475 const char *const class_name =
8476 IDENTIFIER_POINTER (CLASS_NAME (impent->imp_context));
8477 const char *const class_super_name =
8478 IDENTIFIER_POINTER (CLASS_SUPER_NAME (impent->imp_context));
8480 string = (char *) alloca (strlen (class_name)
8481 + strlen (class_super_name) + 30);
8483 /* Do the same for categories. Even though no references to
8484 these symbols are generated automatically by the compiler, it
8485 gives you a handle to pull them into an archive by hand. */
8486 sprintf (string, "*%sobjc_category_name_%s_%s",
8487 (flag_next_runtime ? "." : "__"), class_name, class_super_name);
8492 #ifdef ASM_DECLARE_CLASS_REFERENCE
8493 if (flag_next_runtime)
8495 ASM_DECLARE_CLASS_REFERENCE (asm_out_file, string);
8503 init = build_int_2 (0, 0);
8504 TREE_TYPE (init) = c_common_type_for_size (BITS_PER_WORD, 1);
8505 decl = build_decl (VAR_DECL, get_identifier (string), TREE_TYPE (init));
8506 TREE_PUBLIC (decl) = 1;
8507 TREE_READONLY (decl) = 1;
8508 TREE_USED (decl) = 1;
8509 TREE_CONSTANT (decl) = 1;
8510 DECL_CONTEXT (decl) = 0;
8511 DECL_ARTIFICIAL (decl) = 1;
8512 DECL_INITIAL (decl) = init;
8513 assemble_variable (decl, 1, 0, 0);
8517 /* Look up ID as an instance variable. */
8519 lookup_objc_ivar (id)
8524 if (objc_method_context && !strcmp (IDENTIFIER_POINTER (id), "super"))
8525 /* We have a message to super. */
8526 return get_super_receiver ();
8527 else if (objc_method_context && (decl = is_ivar (objc_ivar_chain, id)))
8529 if (is_private (decl))
8530 return error_mark_node;
8532 return build_ivar_reference (id);
8538 #include "gtype-objc.h"