1 /* Implement classes and message passing for Objective C.
2 Copyright (C) 1992, 1993, 1994, 1995, 1997, 1998, 1999, 2000, 2001, 2002
3 Free Software Foundation, Inc.
4 Contributed by Steve Naroff.
6 This file is part of GNU CC.
8 GNU CC 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 GNU CC 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 GNU CC; 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':
59 #include "diagnostic.h"
61 /* This is the default way of generating a method name. */
62 /* I am not sure it is really correct.
63 Perhaps there's a danger that it will make name conflicts
64 if method names contain underscores. -- rms. */
65 #ifndef OBJC_GEN_METHOD_LABEL
66 #define OBJC_GEN_METHOD_LABEL(BUF, IS_INST, CLASS_NAME, CAT_NAME, SEL_NAME, NUM) \
69 sprintf ((BUF), "_%s_%s_%s_%s", \
70 ((IS_INST) ? "i" : "c"), \
72 ((CAT_NAME)? (CAT_NAME) : ""), \
74 for (temp = (BUF); *temp; temp++) \
75 if (*temp == ':') *temp = '_'; \
79 /* These need specifying. */
80 #ifndef OBJC_FORWARDING_STACK_OFFSET
81 #define OBJC_FORWARDING_STACK_OFFSET 0
84 #ifndef OBJC_FORWARDING_MIN_OFFSET
85 #define OBJC_FORWARDING_MIN_OFFSET 0
89 /* Set up for use of obstacks. */
93 /* This obstack is used to accumulate the encoding of a data type. */
94 static struct obstack util_obstack;
95 /* This points to the beginning of obstack contents,
96 so we can free the whole contents. */
99 /* for encode_method_def */
102 /* The version identifies which language generation and runtime
103 the module (file) was compiled for, and is recorded in the
104 module descriptor. */
106 #define OBJC_VERSION (flag_next_runtime ? 5 : 8)
107 #define PROTOCOL_VERSION 2
109 /* (Decide if these can ever be validly changed.) */
110 #define OBJC_ENCODE_INLINE_DEFS 0
111 #define OBJC_ENCODE_DONT_INLINE_DEFS 1
113 /*** Private Interface (procedures) ***/
115 /* Used by compile_file. */
117 static void init_objc PARAMS ((void));
118 static void finish_objc PARAMS ((void));
120 /* Code generation. */
122 static void synth_module_prologue PARAMS ((void));
123 static tree build_constructor PARAMS ((tree, tree));
124 static rtx build_module_descriptor PARAMS ((void));
125 static tree init_module_descriptor PARAMS ((tree));
126 static tree build_objc_method_call PARAMS ((int, tree, tree,
128 static void generate_strings PARAMS ((void));
129 static tree get_proto_encoding PARAMS ((tree));
130 static void build_selector_translation_table PARAMS ((void));
132 static tree objc_add_static_instance PARAMS ((tree, tree));
134 static tree build_ivar_template PARAMS ((void));
135 static tree build_method_template PARAMS ((void));
136 static tree build_private_template PARAMS ((tree));
137 static void build_class_template PARAMS ((void));
138 static void build_selector_template PARAMS ((void));
139 static void build_category_template PARAMS ((void));
140 static tree build_super_template PARAMS ((void));
141 static tree build_category_initializer PARAMS ((tree, tree, tree,
143 static tree build_protocol_initializer PARAMS ((tree, tree, tree,
146 static void synth_forward_declarations PARAMS ((void));
147 static void generate_ivar_lists PARAMS ((void));
148 static void generate_dispatch_tables PARAMS ((void));
149 static void generate_shared_structures PARAMS ((void));
150 static tree generate_protocol_list PARAMS ((tree));
151 static void generate_forward_declaration_to_string_table PARAMS ((void));
152 static void build_protocol_reference PARAMS ((tree));
154 static tree build_keyword_selector PARAMS ((tree));
155 static tree synth_id_with_class_suffix PARAMS ((const char *, tree));
157 static void generate_static_references PARAMS ((void));
158 static int check_methods_accessible PARAMS ((tree, tree,
160 static void encode_aggregate_within PARAMS ((tree, int, int,
162 static const char *objc_demangle PARAMS ((const char *));
163 static void objc_expand_function_end PARAMS ((void));
165 /* Hash tables to manage the global pool of method prototypes. */
167 hash *nst_method_hash_list = 0;
168 hash *cls_method_hash_list = 0;
170 static size_t hash_func PARAMS ((tree));
171 static void hash_init PARAMS ((void));
172 static void hash_enter PARAMS ((hash *, tree));
173 static hash hash_lookup PARAMS ((hash *, tree));
174 static void hash_add_attr PARAMS ((hash, tree));
175 static tree lookup_method PARAMS ((tree, tree));
176 static tree lookup_instance_method_static PARAMS ((tree, tree));
177 static tree lookup_class_method_static PARAMS ((tree, tree));
178 static tree add_class PARAMS ((tree));
179 static void add_category PARAMS ((tree, tree));
183 class_names, /* class, category, protocol, module names */
184 meth_var_names, /* method and variable names */
185 meth_var_types /* method and variable type descriptors */
188 static tree add_objc_string PARAMS ((tree,
189 enum string_section));
190 static tree get_objc_string_decl PARAMS ((tree,
191 enum string_section));
192 static tree build_objc_string_decl PARAMS ((enum string_section));
193 static tree build_selector_reference_decl PARAMS ((void));
195 /* Protocol additions. */
197 static tree add_protocol PARAMS ((tree));
198 static tree lookup_protocol PARAMS ((tree));
199 static void check_protocol_recursively PARAMS ((tree, tree));
200 static tree lookup_and_install_protocols PARAMS ((tree));
204 static void encode_type_qualifiers PARAMS ((tree));
205 static void encode_pointer PARAMS ((tree, int, int));
206 static void encode_array PARAMS ((tree, int, int));
207 static void encode_aggregate PARAMS ((tree, int, int));
208 static void encode_bitfield PARAMS ((int));
209 static void encode_type PARAMS ((tree, int, int));
210 static void encode_field_decl PARAMS ((tree, int, int));
212 static void really_start_method PARAMS ((tree, tree));
213 static int comp_method_with_proto PARAMS ((tree, tree));
214 static int comp_proto_with_proto PARAMS ((tree, tree));
215 static tree get_arg_type_list PARAMS ((tree, int, int));
216 static tree expr_last PARAMS ((tree));
218 /* Utilities for debugging and error diagnostics. */
220 static void warn_with_method PARAMS ((const char *, int, tree));
221 static void error_with_ivar PARAMS ((const char *, tree, tree));
222 static char *gen_method_decl PARAMS ((tree, char *));
223 static char *gen_declaration PARAMS ((tree, char *));
224 static void gen_declaration_1 PARAMS ((tree, char *));
225 static char *gen_declarator PARAMS ((tree, char *,
227 static int is_complex_decl PARAMS ((tree));
228 static void adorn_decl PARAMS ((tree, char *));
229 static void dump_interface PARAMS ((FILE *, tree));
231 /* Everything else. */
233 static tree define_decl PARAMS ((tree, tree));
234 static tree lookup_method_in_protocol_list PARAMS ((tree, tree, int));
235 static tree lookup_protocol_in_reflist PARAMS ((tree, tree));
236 static tree create_builtin_decl PARAMS ((enum tree_code,
237 tree, const char *));
238 static void setup_string_decl PARAMS ((void));
239 static void build_string_class_template PARAMS ((void));
240 static tree my_build_string PARAMS ((int, const char *));
241 static void build_objc_symtab_template PARAMS ((void));
242 static tree init_def_list PARAMS ((tree));
243 static tree init_objc_symtab PARAMS ((tree));
244 static void forward_declare_categories PARAMS ((void));
245 static void generate_objc_symtab_decl PARAMS ((void));
246 static tree build_selector PARAMS ((tree));
247 static tree build_typed_selector_reference PARAMS ((tree, tree));
248 static tree build_selector_reference PARAMS ((tree));
249 static tree build_class_reference_decl PARAMS ((void));
250 static void add_class_reference PARAMS ((tree));
251 static tree build_protocol_template PARAMS ((void));
252 static tree build_descriptor_table_initializer PARAMS ((tree, tree));
253 static tree build_method_prototype_list_template PARAMS ((tree, int));
254 static tree build_method_prototype_template PARAMS ((void));
255 static int forwarding_offset PARAMS ((tree));
256 static tree encode_method_prototype PARAMS ((tree, tree));
257 static tree generate_descriptor_table PARAMS ((tree, const char *,
259 static void generate_method_descriptors PARAMS ((tree));
260 static tree build_tmp_function_decl PARAMS ((void));
261 static void hack_method_prototype PARAMS ((tree, tree));
262 static void generate_protocol_references PARAMS ((tree));
263 static void generate_protocols PARAMS ((void));
264 static void check_ivars PARAMS ((tree, tree));
265 static tree build_ivar_list_template PARAMS ((tree, int));
266 static tree build_method_list_template PARAMS ((tree, int));
267 static tree build_ivar_list_initializer PARAMS ((tree, tree));
268 static tree generate_ivars_list PARAMS ((tree, const char *,
270 static tree build_dispatch_table_initializer PARAMS ((tree, tree));
271 static tree generate_dispatch_table PARAMS ((tree, const char *,
273 static tree build_shared_structure_initializer PARAMS ((tree, tree, tree, tree,
274 tree, int, tree, tree,
276 static void generate_category PARAMS ((tree));
277 static int is_objc_type_qualifier PARAMS ((tree));
278 static tree adjust_type_for_id_default PARAMS ((tree));
279 static tree check_duplicates PARAMS ((hash));
280 static tree receiver_is_class_object PARAMS ((tree));
281 static int check_methods PARAMS ((tree, tree, int));
282 static int conforms_to_protocol PARAMS ((tree, tree));
283 static void check_protocol PARAMS ((tree, const char *,
285 static void check_protocols PARAMS ((tree, const char *,
287 static tree encode_method_def PARAMS ((tree));
288 static void gen_declspecs PARAMS ((tree, char *, int));
289 static void generate_classref_translation_entry PARAMS ((tree));
290 static void handle_class_ref PARAMS ((tree));
291 static void generate_struct_by_value_array PARAMS ((void))
293 static void encode_complete_bitfield PARAMS ((int, tree, int));
295 /*** Private Interface (data) ***/
297 /* Reserved tag definitions. */
300 #define TAG_OBJECT "objc_object"
301 #define TAG_CLASS "objc_class"
302 #define TAG_SUPER "objc_super"
303 #define TAG_SELECTOR "objc_selector"
305 #define UTAG_CLASS "_objc_class"
306 #define UTAG_IVAR "_objc_ivar"
307 #define UTAG_IVAR_LIST "_objc_ivar_list"
308 #define UTAG_METHOD "_objc_method"
309 #define UTAG_METHOD_LIST "_objc_method_list"
310 #define UTAG_CATEGORY "_objc_category"
311 #define UTAG_MODULE "_objc_module"
312 #define UTAG_SYMTAB "_objc_symtab"
313 #define UTAG_SUPER "_objc_super"
314 #define UTAG_SELECTOR "_objc_selector"
316 #define UTAG_PROTOCOL "_objc_protocol"
317 #define UTAG_METHOD_PROTOTYPE "_objc_method_prototype"
318 #define UTAG_METHOD_PROTOTYPE_LIST "_objc__method_prototype_list"
320 /* Note that the string object global name is only needed for the
322 #define STRING_OBJECT_GLOBAL_NAME "_NSConstantStringClassReference"
324 #define PROTOCOL_OBJECT_CLASS_NAME "Protocol"
326 static const char *TAG_GETCLASS;
327 static const char *TAG_GETMETACLASS;
328 static const char *TAG_MSGSEND;
329 static const char *TAG_MSGSENDSUPER;
330 static const char *TAG_EXECCLASS;
331 static const char *default_constant_string_class_name;
333 /* The OCTI_... enumeration itself is in objc/objc-act.h. */
334 tree objc_global_trees[OCTI_MAX];
336 static void handle_impent PARAMS ((struct imp_entry *));
338 struct imp_entry *imp_list = 0;
339 int imp_count = 0; /* `@implementation' */
340 int cat_count = 0; /* `@category' */
342 static int method_slot = 0; /* Used by start_method_def, */
346 static char *errbuf; /* Buffer for error diagnostics */
348 /* Data imported from tree.c. */
350 extern enum debug_info_type write_symbols;
352 /* Data imported from toplev.c. */
354 extern const char *dump_base_name;
356 static int flag_typed_selectors;
358 FILE *gen_declaration_file;
360 /* Tells "encode_pointer/encode_aggregate" whether we are generating
361 type descriptors for instance variables (as opposed to methods).
362 Type descriptors for instance variables contain more information
363 than methods (for static typing and embedded structures). */
365 static int generating_instance_variables = 0;
367 /* Some platforms pass small structures through registers versus
368 through an invisible pointer. Determine at what size structure is
369 the transition point between the two possibilities. */
372 generate_struct_by_value_array ()
375 tree field_decl, field_decl_chain;
377 int aggregate_in_mem[32];
380 /* Presumably no platform passes 32 byte structures in a register. */
381 for (i = 1; i < 32; i++)
385 /* Create an unnamed struct that has `i' character components */
386 type = start_struct (RECORD_TYPE, NULL_TREE);
388 strcpy (buffer, "c1");
389 field_decl = create_builtin_decl (FIELD_DECL,
392 field_decl_chain = field_decl;
394 for (j = 1; j < i; j++)
396 sprintf (buffer, "c%d", j + 1);
397 field_decl = create_builtin_decl (FIELD_DECL,
400 chainon (field_decl_chain, field_decl);
402 finish_struct (type, field_decl_chain, NULL_TREE);
404 aggregate_in_mem[i] = aggregate_value_p (type);
405 if (!aggregate_in_mem[i])
409 /* We found some structures that are returned in registers instead of memory
410 so output the necessary data. */
413 for (i = 31; i >= 0; i--)
414 if (!aggregate_in_mem[i])
416 printf ("#define OBJC_MAX_STRUCT_BY_VALUE %d\n\n", i);
418 /* The first member of the structure is always 0 because we don't handle
419 structures with 0 members */
420 printf ("static int struct_forward_array[] = {\n 0");
422 for (j = 1; j <= i; j++)
423 printf (", %d", aggregate_in_mem[j]);
432 const char *filename;
434 filename = c_objc_common_init (filename);
435 if (filename == NULL)
438 /* Force the line number back to 0; check_newline will have
439 raised it to 1, which will make the builtin functions appear
440 not to be built in. */
443 /* If gen_declaration desired, open the output file. */
444 if (flag_gen_declaration)
446 register char * const dumpname = concat (dump_base_name, ".decl", NULL);
447 gen_declaration_file = fopen (dumpname, "w");
448 if (gen_declaration_file == 0)
449 fatal_io_error ("can't open %s", dumpname);
453 if (flag_next_runtime)
455 TAG_GETCLASS = "objc_getClass";
456 TAG_GETMETACLASS = "objc_getMetaClass";
457 TAG_MSGSEND = "objc_msgSend";
458 TAG_MSGSENDSUPER = "objc_msgSendSuper";
459 TAG_EXECCLASS = "__objc_execClass";
460 default_constant_string_class_name = "NSConstantString";
464 TAG_GETCLASS = "objc_get_class";
465 TAG_GETMETACLASS = "objc_get_meta_class";
466 TAG_MSGSEND = "objc_msg_lookup";
467 TAG_MSGSENDSUPER = "objc_msg_lookup_super";
468 TAG_EXECCLASS = "__objc_exec_class";
469 default_constant_string_class_name = "NXConstantString";
470 flag_typed_selectors = 1;
473 objc_ellipsis_node = make_node (ERROR_MARK);
477 if (print_struct_values)
478 generate_struct_by_value_array ();
486 c_objc_common_finish_file ();
488 /* Finalize Objective-C runtime data. No need to generate tables
489 and code if only checking syntax. */
490 if (!flag_syntax_only)
493 if (gen_declaration_file)
494 fclose (gen_declaration_file);
498 define_decl (declarator, declspecs)
502 tree decl = start_decl (declarator, declspecs, 0, NULL_TREE);
503 finish_decl (decl, NULL_TREE, NULL_TREE);
507 /* Return 1 if LHS and RHS are compatible types for assignment or
508 various other operations. Return 0 if they are incompatible, and
509 return -1 if we choose to not decide. When the operation is
510 REFLEXIVE, check for compatibility in either direction.
512 For statically typed objects, an assignment of the form `a' = `b'
516 `a' and `b' are the same class type, or
517 `a' and `b' are of class types A and B such that B is a descendant of A. */
520 lookup_method_in_protocol_list (rproto_list, sel_name, class_meth)
528 for (rproto = rproto_list; rproto; rproto = TREE_CHAIN (rproto))
530 p = TREE_VALUE (rproto);
532 if (TREE_CODE (p) == PROTOCOL_INTERFACE_TYPE)
534 if ((fnd = lookup_method (class_meth
535 ? PROTOCOL_CLS_METHODS (p)
536 : PROTOCOL_NST_METHODS (p), sel_name)))
538 else if (PROTOCOL_LIST (p))
539 fnd = lookup_method_in_protocol_list (PROTOCOL_LIST (p),
540 sel_name, class_meth);
544 ; /* An identifier...if we could not find a protocol. */
555 lookup_protocol_in_reflist (rproto_list, lproto)
561 /* Make sure the protocol is supported by the object on the rhs. */
562 if (TREE_CODE (lproto) == PROTOCOL_INTERFACE_TYPE)
565 for (rproto = rproto_list; rproto; rproto = TREE_CHAIN (rproto))
567 p = TREE_VALUE (rproto);
569 if (TREE_CODE (p) == PROTOCOL_INTERFACE_TYPE)
574 else if (PROTOCOL_LIST (p))
575 fnd = lookup_protocol_in_reflist (PROTOCOL_LIST (p), lproto);
584 ; /* An identifier...if we could not find a protocol. */
590 /* Return 1 if LHS and RHS are compatible types for assignment
591 or various other operations. Return 0 if they are incompatible,
592 and return -1 if we choose to not decide. When the operation
593 is REFLEXIVE, check for compatibility in either direction. */
596 objc_comptypes (lhs, rhs, reflexive)
601 /* New clause for protocols. */
603 if (TREE_CODE (lhs) == POINTER_TYPE
604 && TREE_CODE (TREE_TYPE (lhs)) == RECORD_TYPE
605 && TREE_CODE (rhs) == POINTER_TYPE
606 && TREE_CODE (TREE_TYPE (rhs)) == RECORD_TYPE)
608 int lhs_is_proto = IS_PROTOCOL_QUALIFIED_ID (lhs);
609 int rhs_is_proto = IS_PROTOCOL_QUALIFIED_ID (rhs);
613 tree lproto, lproto_list = TYPE_PROTOCOL_LIST (lhs);
614 tree rproto, rproto_list;
619 rproto_list = TYPE_PROTOCOL_LIST (rhs);
621 /* Make sure the protocol is supported by the object
623 for (lproto = lproto_list; lproto; lproto = TREE_CHAIN (lproto))
625 p = TREE_VALUE (lproto);
626 rproto = lookup_protocol_in_reflist (rproto_list, p);
629 warning ("object does not conform to the `%s' protocol",
630 IDENTIFIER_POINTER (PROTOCOL_NAME (p)));
633 else if (TYPED_OBJECT (TREE_TYPE (rhs)))
635 tree rname = TYPE_NAME (TREE_TYPE (rhs));
638 /* Make sure the protocol is supported by the object
640 for (lproto = lproto_list; lproto; lproto = TREE_CHAIN (lproto))
642 p = TREE_VALUE (lproto);
644 rinter = lookup_interface (rname);
646 while (rinter && !rproto)
650 rproto_list = CLASS_PROTOCOL_LIST (rinter);
651 /* If the underlying ObjC class does not have
652 protocols attached to it, perhaps there are
653 "one-off" protocols attached to the rhs?
654 E.g., 'id<MyProt> foo;'. */
656 rproto_list = TYPE_PROTOCOL_LIST (TREE_TYPE (rhs));
657 rproto = lookup_protocol_in_reflist (rproto_list, p);
659 /* Check for protocols adopted by categories. */
660 cat = CLASS_CATEGORY_LIST (rinter);
661 while (cat && !rproto)
663 rproto_list = CLASS_PROTOCOL_LIST (cat);
664 rproto = lookup_protocol_in_reflist (rproto_list, p);
666 cat = CLASS_CATEGORY_LIST (cat);
669 rinter = lookup_interface (CLASS_SUPER_NAME (rinter));
673 warning ("class `%s' does not implement the `%s' protocol",
674 IDENTIFIER_POINTER (TYPE_NAME (TREE_TYPE (rhs))),
675 IDENTIFIER_POINTER (PROTOCOL_NAME (p)));
679 /* May change...based on whether there was any mismatch */
682 else if (rhs_is_proto)
683 /* Lhs is not a protocol...warn if it is statically typed */
684 return (TYPED_OBJECT (TREE_TYPE (lhs)) != 0);
687 /* Defer to comptypes. */
691 else if (TREE_CODE (lhs) == RECORD_TYPE && TREE_CODE (rhs) == RECORD_TYPE)
692 ; /* Fall thru. This is the case we have been handling all along */
694 /* Defer to comptypes. */
697 /* `id' = `<class> *', `<class> *' = `id' */
699 if ((TYPE_NAME (lhs) == objc_object_id && TYPED_OBJECT (rhs))
700 || (TYPE_NAME (rhs) == objc_object_id && TYPED_OBJECT (lhs)))
703 /* `id' = `Class', `Class' = `id' */
705 else if ((TYPE_NAME (lhs) == objc_object_id
706 && TYPE_NAME (rhs) == objc_class_id)
707 || (TYPE_NAME (lhs) == objc_class_id
708 && TYPE_NAME (rhs) == objc_object_id))
711 /* `<class> *' = `<class> *' */
713 else if (TYPED_OBJECT (lhs) && TYPED_OBJECT (rhs))
715 tree lname = TYPE_NAME (lhs);
716 tree rname = TYPE_NAME (rhs);
722 /* If the left hand side is a super class of the right hand side,
724 for (inter = lookup_interface (rname); inter;
725 inter = lookup_interface (CLASS_SUPER_NAME (inter)))
726 if (lname == CLASS_SUPER_NAME (inter))
729 /* Allow the reverse when reflexive. */
731 for (inter = lookup_interface (lname); inter;
732 inter = lookup_interface (CLASS_SUPER_NAME (inter)))
733 if (rname == CLASS_SUPER_NAME (inter))
739 /* Defer to comptypes. */
743 /* Called from c-decl.c before all calls to rest_of_decl_compilation. */
746 objc_check_decl (decl)
749 tree type = TREE_TYPE (decl);
751 if (TREE_CODE (type) == RECORD_TYPE
752 && TREE_STATIC_TEMPLATE (type)
753 && type != constant_string_type)
754 error_with_decl (decl, "`%s' cannot be statically allocated");
757 /* Implement static typing. At this point, we know we have an interface. */
760 get_static_reference (interface, protocols)
764 tree type = xref_tag (RECORD_TYPE, interface);
768 tree t, m = TYPE_MAIN_VARIANT (type);
770 t = copy_node (type);
771 TYPE_BINFO (t) = make_tree_vec (2);
773 /* Add this type to the chain of variants of TYPE. */
774 TYPE_NEXT_VARIANT (t) = TYPE_NEXT_VARIANT (m);
775 TYPE_NEXT_VARIANT (m) = t;
777 /* Look up protocols and install in lang specific list. Note
778 that the protocol list can have a different lifetime than T! */
779 TYPE_PROTOCOL_LIST (t) = lookup_and_install_protocols (protocols);
781 /* This forces a new pointer type to be created later
782 (in build_pointer_type)...so that the new template
783 we just created will actually be used...what a hack! */
784 if (TYPE_POINTER_TO (t))
785 TYPE_POINTER_TO (t) = NULL_TREE;
794 get_object_reference (protocols)
797 tree type_decl = lookup_name (objc_id_id);
800 if (type_decl && TREE_CODE (type_decl) == TYPE_DECL)
802 type = TREE_TYPE (type_decl);
803 if (TYPE_MAIN_VARIANT (type) != id_type)
804 warning ("unexpected type for `id' (%s)",
805 gen_declaration (type, errbuf));
809 error ("undefined type `id', please import <objc/objc.h>");
810 return error_mark_node;
813 /* This clause creates a new pointer type that is qualified with
814 the protocol specification...this info is used later to do more
815 elaborate type checking. */
819 tree t, m = TYPE_MAIN_VARIANT (type);
821 t = copy_node (type);
822 TYPE_BINFO (t) = make_tree_vec (2);
824 /* Add this type to the chain of variants of TYPE. */
825 TYPE_NEXT_VARIANT (t) = TYPE_NEXT_VARIANT (m);
826 TYPE_NEXT_VARIANT (m) = t;
828 /* Look up protocols...and install in lang specific list */
829 TYPE_PROTOCOL_LIST (t) = lookup_and_install_protocols (protocols);
831 /* This forces a new pointer type to be created later
832 (in build_pointer_type)...so that the new template
833 we just created will actually be used...what a hack! */
834 if (TYPE_POINTER_TO (t))
835 TYPE_POINTER_TO (t) = NULL_TREE;
842 /* Check for circular dependencies in protocols. The arguments are
843 PROTO, the protocol to check, and LIST, a list of protocol it
847 check_protocol_recursively (proto, list)
853 for (p = list; p; p = TREE_CHAIN (p))
855 tree pp = TREE_VALUE (p);
857 if (TREE_CODE (pp) == IDENTIFIER_NODE)
858 pp = lookup_protocol (pp);
861 fatal_error ("protocol `%s' has circular dependency",
862 IDENTIFIER_POINTER (PROTOCOL_NAME (pp)));
864 check_protocol_recursively (proto, PROTOCOL_LIST (pp));
869 lookup_and_install_protocols (protocols)
874 tree return_value = protocols;
876 for (proto = protocols; proto; proto = TREE_CHAIN (proto))
878 tree ident = TREE_VALUE (proto);
879 tree p = lookup_protocol (ident);
883 error ("cannot find protocol declaration for `%s'",
884 IDENTIFIER_POINTER (ident));
886 TREE_CHAIN (prev) = TREE_CHAIN (proto);
888 return_value = TREE_CHAIN (proto);
892 /* Replace identifier with actual protocol node. */
893 TREE_VALUE (proto) = p;
901 /* Create and push a decl for a built-in external variable or field NAME.
903 TYPE is its data type. */
906 create_builtin_decl (code, type, name)
911 tree decl = build_decl (code, get_identifier (name), type);
913 if (code == VAR_DECL)
915 TREE_STATIC (decl) = 1;
916 make_decl_rtl (decl, 0);
920 DECL_ARTIFICIAL (decl) = 1;
924 /* Find the decl for the constant string class. */
929 if (!string_class_decl)
931 if (!constant_string_global_id)
932 constant_string_global_id = get_identifier (STRING_OBJECT_GLOBAL_NAME);
933 string_class_decl = lookup_name (constant_string_global_id);
937 /* Purpose: "play" parser, creating/installing representations
938 of the declarations that are required by Objective-C.
942 type_spec--------->sc_spec
943 (tree_list) (tree_list)
946 identifier_node identifier_node */
949 synth_module_prologue ()
954 /* Defined in `objc.h' */
955 objc_object_id = get_identifier (TAG_OBJECT);
957 objc_object_reference = xref_tag (RECORD_TYPE, objc_object_id);
959 id_type = build_pointer_type (objc_object_reference);
961 objc_id_id = get_identifier (TYPE_ID);
962 objc_class_id = get_identifier (TAG_CLASS);
964 objc_class_type = build_pointer_type (xref_tag (RECORD_TYPE, objc_class_id));
965 protocol_type = build_pointer_type (xref_tag (RECORD_TYPE,
966 get_identifier (PROTOCOL_OBJECT_CLASS_NAME)));
968 /* Declare type of selector-objects that represent an operation name. */
970 /* `struct objc_selector *' */
972 = build_pointer_type (xref_tag (RECORD_TYPE,
973 get_identifier (TAG_SELECTOR)));
975 /* Forward declare type, or else the prototype for msgSendSuper will
978 super_p = build_pointer_type (xref_tag (RECORD_TYPE,
979 get_identifier (TAG_SUPER)));
982 /* id objc_msgSend (id, SEL, ...); */
985 = build_function_type (id_type,
986 tree_cons (NULL_TREE, id_type,
987 tree_cons (NULL_TREE, selector_type,
990 if (! flag_next_runtime)
992 umsg_decl = build_decl (FUNCTION_DECL,
993 get_identifier (TAG_MSGSEND), temp_type);
994 DECL_EXTERNAL (umsg_decl) = 1;
995 TREE_PUBLIC (umsg_decl) = 1;
996 DECL_INLINE (umsg_decl) = 1;
997 DECL_ARTIFICIAL (umsg_decl) = 1;
999 make_decl_rtl (umsg_decl, NULL);
1000 pushdecl (umsg_decl);
1003 umsg_decl = builtin_function (TAG_MSGSEND, temp_type, 0, NOT_BUILT_IN,
1006 /* id objc_msgSendSuper (struct objc_super *, SEL, ...); */
1009 = build_function_type (id_type,
1010 tree_cons (NULL_TREE, super_p,
1011 tree_cons (NULL_TREE, selector_type,
1014 umsg_super_decl = builtin_function (TAG_MSGSENDSUPER,
1015 temp_type, 0, NOT_BUILT_IN,
1018 /* id objc_getClass (const char *); */
1020 temp_type = build_function_type (id_type,
1021 tree_cons (NULL_TREE,
1022 const_string_type_node,
1023 tree_cons (NULL_TREE, void_type_node,
1027 = builtin_function (TAG_GETCLASS, temp_type, 0, NOT_BUILT_IN,
1030 /* id objc_getMetaClass (const char *); */
1032 objc_get_meta_class_decl
1033 = builtin_function (TAG_GETMETACLASS, temp_type, 0, NOT_BUILT_IN,
1036 /* static SEL _OBJC_SELECTOR_TABLE[]; */
1038 if (! flag_next_runtime)
1040 if (flag_typed_selectors)
1042 /* Suppress outputting debug symbols, because
1043 dbxout_init hasn'r been called yet. */
1044 enum debug_info_type save_write_symbols = write_symbols;
1045 const struct gcc_debug_hooks *const save_hooks = debug_hooks;
1046 write_symbols = NO_DEBUG;
1047 debug_hooks = &do_nothing_debug_hooks;
1049 build_selector_template ();
1050 temp_type = build_array_type (objc_selector_template, NULL_TREE);
1052 write_symbols = save_write_symbols;
1053 debug_hooks = save_hooks;
1056 temp_type = build_array_type (selector_type, NULL_TREE);
1058 layout_type (temp_type);
1059 UOBJC_SELECTOR_TABLE_decl
1060 = create_builtin_decl (VAR_DECL, temp_type,
1061 "_OBJC_SELECTOR_TABLE");
1063 /* Avoid warning when not sending messages. */
1064 TREE_USED (UOBJC_SELECTOR_TABLE_decl) = 1;
1067 generate_forward_declaration_to_string_table ();
1069 /* Forward declare constant_string_id and constant_string_type. */
1070 if (!constant_string_class_name)
1071 constant_string_class_name = default_constant_string_class_name;
1073 constant_string_id = get_identifier (constant_string_class_name);
1074 constant_string_type = xref_tag (RECORD_TYPE, constant_string_id);
1077 /* Predefine the following data type:
1079 struct STRING_OBJECT_CLASS_NAME
1083 unsigned int length;
1087 build_string_class_template ()
1089 tree field_decl, field_decl_chain;
1091 field_decl = create_builtin_decl (FIELD_DECL, id_type, "isa");
1092 field_decl_chain = field_decl;
1094 field_decl = create_builtin_decl (FIELD_DECL,
1095 build_pointer_type (char_type_node),
1097 chainon (field_decl_chain, field_decl);
1099 field_decl = create_builtin_decl (FIELD_DECL, unsigned_type_node, "length");
1100 chainon (field_decl_chain, field_decl);
1102 finish_struct (constant_string_type, field_decl_chain, NULL_TREE);
1105 /* Custom build_string which sets TREE_TYPE! */
1108 my_build_string (len, str)
1112 return fix_string_type (build_string (len, str));
1115 /* Given a chain of STRING_CST's, build a static instance of
1116 NXConstantString which points at the concatenation of those strings.
1117 We place the string object in the __string_objects section of the
1118 __OBJC segment. The Objective-C runtime will initialize the isa
1119 pointers of the string objects to point at the NXConstantString
1123 build_objc_string_object (strings)
1126 tree string, initlist, constructor;
1129 if (lookup_interface (constant_string_id) == NULL_TREE)
1131 error ("cannot find interface declaration for `%s'",
1132 IDENTIFIER_POINTER (constant_string_id));
1133 return error_mark_node;
1136 add_class_reference (constant_string_id);
1138 if (TREE_CHAIN (strings))
1140 varray_type vstrings;
1141 VARRAY_TREE_INIT (vstrings, 32, "strings");
1143 for (; strings ; strings = TREE_CHAIN (strings))
1144 VARRAY_PUSH_TREE (vstrings, strings);
1146 string = combine_strings (vstrings);
1151 string = fix_string_type (string);
1153 TREE_SET_CODE (string, STRING_CST);
1154 length = TREE_STRING_LENGTH (string) - 1;
1156 /* We could not properly create NXConstantString in synth_module_prologue,
1157 because that's called before debugging is initialized. Do it now. */
1158 if (TYPE_FIELDS (constant_string_type) == NULL_TREE)
1159 build_string_class_template ();
1161 /* & ((NXConstantString) { NULL, string, length }) */
1163 if (flag_next_runtime)
1165 /* For the NeXT runtime, we can generate a literal reference
1166 to the string class, don't need to run a constructor. */
1167 setup_string_decl ();
1168 if (string_class_decl == NULL_TREE)
1170 error ("cannot find reference tag for class `%s'",
1171 IDENTIFIER_POINTER (constant_string_id));
1172 return error_mark_node;
1174 initlist = build_tree_list
1176 copy_node (build_unary_op (ADDR_EXPR, string_class_decl, 0)));
1180 initlist = build_tree_list (NULL_TREE, build_int_2 (0, 0));
1184 = tree_cons (NULL_TREE, copy_node (build_unary_op (ADDR_EXPR, string, 1)),
1186 initlist = tree_cons (NULL_TREE, build_int_2 (length, 0), initlist);
1187 constructor = build_constructor (constant_string_type, nreverse (initlist));
1189 if (!flag_next_runtime)
1192 = objc_add_static_instance (constructor, constant_string_type);
1195 return (build_unary_op (ADDR_EXPR, constructor, 1));
1198 /* Declare a static instance of CLASS_DECL initialized by CONSTRUCTOR. */
1201 objc_add_static_instance (constructor, class_decl)
1202 tree constructor, class_decl;
1204 static int num_static_inst;
1208 /* Find the list of static instances for the CLASS_DECL. Create one if
1210 for (chain = &objc_static_instances;
1211 *chain && TREE_VALUE (*chain) != class_decl;
1212 chain = &TREE_CHAIN (*chain));
1215 *chain = tree_cons (NULL_TREE, class_decl, NULL_TREE);
1216 add_objc_string (TYPE_NAME (class_decl), class_names);
1219 sprintf (buf, "_OBJC_INSTANCE_%d", num_static_inst++);
1220 decl = build_decl (VAR_DECL, get_identifier (buf), class_decl);
1221 DECL_COMMON (decl) = 1;
1222 TREE_STATIC (decl) = 1;
1223 DECL_ARTIFICIAL (decl) = 1;
1224 DECL_INITIAL (decl) = constructor;
1226 /* We may be writing something else just now.
1227 Postpone till end of input. */
1228 DECL_DEFER_OUTPUT (decl) = 1;
1229 pushdecl_top_level (decl);
1230 rest_of_decl_compilation (decl, 0, 1, 0);
1232 /* Add the DECL to the head of this CLASS' list. */
1233 TREE_PURPOSE (*chain) = tree_cons (NULL_TREE, decl, TREE_PURPOSE (*chain));
1238 /* Build a static constant CONSTRUCTOR
1239 with type TYPE and elements ELTS. */
1242 build_constructor (type, elts)
1245 tree constructor, f, e;
1247 /* ??? Most of the places that we build constructors, we don't fill in
1248 the type of integers properly. Convert them all en masse. */
1249 if (TREE_CODE (type) == ARRAY_TYPE)
1251 f = TREE_TYPE (type);
1252 if (TREE_CODE (f) == POINTER_TYPE || TREE_CODE (f) == INTEGER_TYPE)
1253 for (e = elts; e ; e = TREE_CHAIN (e))
1254 TREE_VALUE (e) = convert (f, TREE_VALUE (e));
1258 f = TYPE_FIELDS (type);
1259 for (e = elts; e ; e = TREE_CHAIN (e), f = TREE_CHAIN (f))
1260 if (TREE_CODE (TREE_TYPE (f)) == POINTER_TYPE
1261 || TREE_CODE (TREE_TYPE (f)) == INTEGER_TYPE)
1262 TREE_VALUE (e) = convert (TREE_TYPE (f), TREE_VALUE (e));
1265 constructor = build (CONSTRUCTOR, type, NULL_TREE, elts);
1266 TREE_CONSTANT (constructor) = 1;
1267 TREE_STATIC (constructor) = 1;
1268 TREE_READONLY (constructor) = 1;
1273 /* Take care of defining and initializing _OBJC_SYMBOLS. */
1275 /* Predefine the following data type:
1283 void *defs[cls_def_cnt + cat_def_cnt];
1287 build_objc_symtab_template ()
1289 tree field_decl, field_decl_chain, index;
1291 objc_symtab_template
1292 = start_struct (RECORD_TYPE, get_identifier (UTAG_SYMTAB));
1294 /* long sel_ref_cnt; */
1296 field_decl = create_builtin_decl (FIELD_DECL,
1297 long_integer_type_node,
1299 field_decl_chain = field_decl;
1303 field_decl = create_builtin_decl (FIELD_DECL,
1304 build_pointer_type (selector_type),
1306 chainon (field_decl_chain, field_decl);
1308 /* short cls_def_cnt; */
1310 field_decl = create_builtin_decl (FIELD_DECL,
1311 short_integer_type_node,
1313 chainon (field_decl_chain, field_decl);
1315 /* short cat_def_cnt; */
1317 field_decl = create_builtin_decl (FIELD_DECL,
1318 short_integer_type_node,
1320 chainon (field_decl_chain, field_decl);
1322 /* void *defs[cls_def_cnt + cat_def_cnt]; */
1324 if (!flag_next_runtime)
1325 index = build_index_type (build_int_2 (imp_count + cat_count, 0));
1327 index = build_index_type (build_int_2 (imp_count + cat_count - 1,
1328 imp_count == 0 && cat_count == 0
1330 field_decl = create_builtin_decl (FIELD_DECL,
1331 build_array_type (ptr_type_node, index),
1333 chainon (field_decl_chain, field_decl);
1335 finish_struct (objc_symtab_template, field_decl_chain, NULL_TREE);
1338 /* Create the initial value for the `defs' field of _objc_symtab.
1339 This is a CONSTRUCTOR. */
1342 init_def_list (type)
1345 tree expr, initlist = NULL_TREE;
1346 struct imp_entry *impent;
1349 for (impent = imp_list; impent; impent = impent->next)
1351 if (TREE_CODE (impent->imp_context) == CLASS_IMPLEMENTATION_TYPE)
1353 expr = build_unary_op (ADDR_EXPR, impent->class_decl, 0);
1354 initlist = tree_cons (NULL_TREE, expr, initlist);
1359 for (impent = imp_list; impent; impent = impent->next)
1361 if (TREE_CODE (impent->imp_context) == CATEGORY_IMPLEMENTATION_TYPE)
1363 expr = build_unary_op (ADDR_EXPR, impent->class_decl, 0);
1364 initlist = tree_cons (NULL_TREE, expr, initlist);
1368 if (!flag_next_runtime)
1370 /* statics = { ..., _OBJC_STATIC_INSTANCES, ... } */
1373 if (static_instances_decl)
1374 expr = build_unary_op (ADDR_EXPR, static_instances_decl, 0);
1376 expr = build_int_2 (0, 0);
1378 initlist = tree_cons (NULL_TREE, expr, initlist);
1381 return build_constructor (type, nreverse (initlist));
1384 /* Construct the initial value for all of _objc_symtab. */
1387 init_objc_symtab (type)
1392 /* sel_ref_cnt = { ..., 5, ... } */
1394 initlist = build_tree_list (NULL_TREE, build_int_2 (0, 0));
1396 /* refs = { ..., _OBJC_SELECTOR_TABLE, ... } */
1398 if (flag_next_runtime || ! sel_ref_chain)
1399 initlist = tree_cons (NULL_TREE, build_int_2 (0, 0), initlist);
1401 initlist = tree_cons (NULL_TREE,
1402 build_unary_op (ADDR_EXPR,
1403 UOBJC_SELECTOR_TABLE_decl, 1),
1406 /* cls_def_cnt = { ..., 5, ... } */
1408 initlist = tree_cons (NULL_TREE, build_int_2 (imp_count, 0), initlist);
1410 /* cat_def_cnt = { ..., 5, ... } */
1412 initlist = tree_cons (NULL_TREE, build_int_2 (cat_count, 0), initlist);
1414 /* cls_def = { ..., { &Foo, &Bar, ...}, ... } */
1416 if (imp_count || cat_count || static_instances_decl)
1419 tree field = TYPE_FIELDS (type);
1420 field = TREE_CHAIN (TREE_CHAIN (TREE_CHAIN (TREE_CHAIN (field))));
1422 initlist = tree_cons (NULL_TREE, init_def_list (TREE_TYPE (field)),
1426 return build_constructor (type, nreverse (initlist));
1429 /* Push forward-declarations of all the categories so that
1430 init_def_list can use them in a CONSTRUCTOR. */
1433 forward_declare_categories ()
1435 struct imp_entry *impent;
1436 tree sav = objc_implementation_context;
1438 for (impent = imp_list; impent; impent = impent->next)
1440 if (TREE_CODE (impent->imp_context) == CATEGORY_IMPLEMENTATION_TYPE)
1442 /* Set an invisible arg to synth_id_with_class_suffix. */
1443 objc_implementation_context = impent->imp_context;
1445 = create_builtin_decl (VAR_DECL, objc_category_template,
1446 IDENTIFIER_POINTER (synth_id_with_class_suffix ("_OBJC_CATEGORY", objc_implementation_context)));
1449 objc_implementation_context = sav;
1452 /* Create the declaration of _OBJC_SYMBOLS, with type `strict _objc_symtab'
1453 and initialized appropriately. */
1456 generate_objc_symtab_decl ()
1460 if (!objc_category_template)
1461 build_category_template ();
1463 /* forward declare categories */
1465 forward_declare_categories ();
1467 if (!objc_symtab_template)
1468 build_objc_symtab_template ();
1470 sc_spec = build_tree_list (NULL_TREE, ridpointers[(int) RID_STATIC]);
1472 UOBJC_SYMBOLS_decl = start_decl (get_identifier ("_OBJC_SYMBOLS"),
1473 tree_cons (NULL_TREE,
1474 objc_symtab_template, sc_spec),
1478 TREE_USED (UOBJC_SYMBOLS_decl) = 1;
1479 DECL_IGNORED_P (UOBJC_SYMBOLS_decl) = 1;
1480 DECL_ARTIFICIAL (UOBJC_SYMBOLS_decl) = 1;
1481 finish_decl (UOBJC_SYMBOLS_decl,
1482 init_objc_symtab (TREE_TYPE (UOBJC_SYMBOLS_decl)),
1487 init_module_descriptor (type)
1490 tree initlist, expr;
1492 /* version = { 1, ... } */
1494 expr = build_int_2 (OBJC_VERSION, 0);
1495 initlist = build_tree_list (NULL_TREE, expr);
1497 /* size = { ..., sizeof (struct objc_module), ... } */
1499 expr = size_in_bytes (objc_module_template);
1500 initlist = tree_cons (NULL_TREE, expr, initlist);
1502 /* name = { ..., "foo.m", ... } */
1504 expr = add_objc_string (get_identifier (input_filename), class_names);
1505 initlist = tree_cons (NULL_TREE, expr, initlist);
1507 /* symtab = { ..., _OBJC_SYMBOLS, ... } */
1509 if (UOBJC_SYMBOLS_decl)
1510 expr = build_unary_op (ADDR_EXPR, UOBJC_SYMBOLS_decl, 0);
1512 expr = build_int_2 (0, 0);
1513 initlist = tree_cons (NULL_TREE, expr, initlist);
1515 return build_constructor (type, nreverse (initlist));
1518 /* Write out the data structures to describe Objective C classes defined.
1519 If appropriate, compile and output a setup function to initialize them.
1520 Return a symbol_ref to the function to call to initialize the Objective C
1521 data structures for this file (and perhaps for other files also).
1523 struct objc_module { ... } _OBJC_MODULE = { ... }; */
1526 build_module_descriptor ()
1528 tree decl_specs, field_decl, field_decl_chain;
1530 objc_module_template
1531 = start_struct (RECORD_TYPE, get_identifier (UTAG_MODULE));
1535 decl_specs = build_tree_list (NULL_TREE, ridpointers[(int) RID_LONG]);
1536 field_decl = get_identifier ("version");
1538 = grokfield (input_filename, lineno, field_decl, decl_specs, NULL_TREE);
1539 field_decl_chain = field_decl;
1543 decl_specs = build_tree_list (NULL_TREE, ridpointers[(int) RID_LONG]);
1544 field_decl = get_identifier ("size");
1546 = grokfield (input_filename, lineno, field_decl, decl_specs, NULL_TREE);
1547 chainon (field_decl_chain, field_decl);
1551 decl_specs = build_tree_list (NULL_TREE, ridpointers[(int) RID_CHAR]);
1552 field_decl = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("name"));
1554 = grokfield (input_filename, lineno, field_decl, decl_specs, NULL_TREE);
1555 chainon (field_decl_chain, field_decl);
1557 /* struct objc_symtab *symtab; */
1559 decl_specs = get_identifier (UTAG_SYMTAB);
1560 decl_specs = build_tree_list (NULL_TREE, xref_tag (RECORD_TYPE, decl_specs));
1561 field_decl = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("symtab"));
1563 = grokfield (input_filename, lineno, field_decl, decl_specs, NULL_TREE);
1564 chainon (field_decl_chain, field_decl);
1566 finish_struct (objc_module_template, field_decl_chain, NULL_TREE);
1568 /* Create an instance of "objc_module". */
1570 decl_specs = tree_cons (NULL_TREE, objc_module_template,
1571 build_tree_list (NULL_TREE,
1572 ridpointers[(int) RID_STATIC]));
1574 UOBJC_MODULES_decl = start_decl (get_identifier ("_OBJC_MODULES"),
1575 decl_specs, 1, NULL_TREE);
1577 DECL_ARTIFICIAL (UOBJC_MODULES_decl) = 1;
1578 DECL_IGNORED_P (UOBJC_MODULES_decl) = 1;
1579 DECL_CONTEXT (UOBJC_MODULES_decl) = NULL_TREE;
1581 finish_decl (UOBJC_MODULES_decl,
1582 init_module_descriptor (TREE_TYPE (UOBJC_MODULES_decl)),
1585 /* Mark the decl to avoid "defined but not used" warning. */
1586 DECL_IN_SYSTEM_HEADER (UOBJC_MODULES_decl) = 1;
1588 /* Generate a constructor call for the module descriptor.
1589 This code was generated by reading the grammar rules
1590 of c-parse.in; Therefore, it may not be the most efficient
1591 way of generating the requisite code. */
1593 if (flag_next_runtime)
1597 tree parms, execclass_decl, decelerator, void_list_node_1;
1598 tree init_function_name, init_function_decl;
1600 /* Declare void __objc_execClass (void *); */
1602 void_list_node_1 = build_tree_list (NULL_TREE, void_type_node);
1603 execclass_decl = build_decl (FUNCTION_DECL,
1604 get_identifier (TAG_EXECCLASS),
1605 build_function_type (void_type_node,
1606 tree_cons (NULL_TREE, ptr_type_node,
1607 void_list_node_1)));
1608 DECL_EXTERNAL (execclass_decl) = 1;
1609 DECL_ARTIFICIAL (execclass_decl) = 1;
1610 TREE_PUBLIC (execclass_decl) = 1;
1611 pushdecl (execclass_decl);
1612 rest_of_decl_compilation (execclass_decl, 0, 0, 0);
1613 assemble_external (execclass_decl);
1615 /* void _GLOBAL_$I$<gnyf> () {objc_execClass (&L_OBJC_MODULES);} */
1617 init_function_name = get_file_function_name ('I');
1618 start_function (void_list_node_1,
1619 build_nt (CALL_EXPR, init_function_name,
1620 tree_cons (NULL_TREE, NULL_TREE,
1624 store_parm_decls ();
1626 init_function_decl = current_function_decl;
1627 TREE_PUBLIC (init_function_decl) = ! targetm.have_ctors_dtors;
1628 TREE_USED (init_function_decl) = 1;
1629 /* Don't let this one be deferred. */
1630 DECL_INLINE (init_function_decl) = 0;
1631 DECL_UNINLINABLE (init_function_decl) = 1;
1632 current_function_cannot_inline
1633 = "static constructors and destructors cannot be inlined";
1636 = build_tree_list (NULL_TREE,
1637 build_unary_op (ADDR_EXPR, UOBJC_MODULES_decl, 0));
1638 decelerator = build_function_call (execclass_decl, parms);
1640 c_expand_expr_stmt (decelerator);
1642 finish_function (0, 0);
1644 return XEXP (DECL_RTL (init_function_decl), 0);
1648 /* extern const char _OBJC_STRINGS[]; */
1651 generate_forward_declaration_to_string_table ()
1653 tree sc_spec, decl_specs, expr_decl;
1655 sc_spec = tree_cons (NULL_TREE, ridpointers[(int) RID_EXTERN], NULL_TREE);
1656 decl_specs = tree_cons (NULL_TREE, ridpointers[(int) RID_CHAR], sc_spec);
1659 = build_nt (ARRAY_REF, get_identifier ("_OBJC_STRINGS"), NULL_TREE);
1661 UOBJC_STRINGS_decl = define_decl (expr_decl, decl_specs);
1664 /* Return the DECL of the string IDENT in the SECTION. */
1667 get_objc_string_decl (ident, section)
1669 enum string_section section;
1673 if (section == class_names)
1674 chain = class_names_chain;
1675 else if (section == meth_var_names)
1676 chain = meth_var_names_chain;
1677 else if (section == meth_var_types)
1678 chain = meth_var_types_chain;
1682 for (; chain != 0; chain = TREE_CHAIN (chain))
1683 if (TREE_VALUE (chain) == ident)
1684 return (TREE_PURPOSE (chain));
1690 /* Output references to all statically allocated objects. Return the DECL
1691 for the array built. */
1694 generate_static_references ()
1696 tree decls = NULL_TREE, ident, decl_spec, expr_decl, expr = NULL_TREE;
1697 tree class_name, class, decl, initlist;
1698 tree cl_chain, in_chain, type;
1699 int num_inst, num_class;
1702 if (flag_next_runtime)
1705 for (cl_chain = objc_static_instances, num_class = 0;
1706 cl_chain; cl_chain = TREE_CHAIN (cl_chain), num_class++)
1708 for (num_inst = 0, in_chain = TREE_PURPOSE (cl_chain);
1709 in_chain; num_inst++, in_chain = TREE_CHAIN (in_chain));
1711 sprintf (buf, "_OBJC_STATIC_INSTANCES_%d", num_class);
1712 ident = get_identifier (buf);
1714 expr_decl = build_nt (ARRAY_REF, ident, NULL_TREE);
1715 decl_spec = tree_cons (NULL_TREE, build_pointer_type (void_type_node),
1716 build_tree_list (NULL_TREE,
1717 ridpointers[(int) RID_STATIC]));
1718 decl = start_decl (expr_decl, decl_spec, 1, NULL_TREE);
1719 DECL_CONTEXT (decl) = 0;
1720 DECL_ARTIFICIAL (decl) = 1;
1722 /* Output {class_name, ...}. */
1723 class = TREE_VALUE (cl_chain);
1724 class_name = get_objc_string_decl (TYPE_NAME (class), class_names);
1725 initlist = build_tree_list (NULL_TREE,
1726 build_unary_op (ADDR_EXPR, class_name, 1));
1728 /* Output {..., instance, ...}. */
1729 for (in_chain = TREE_PURPOSE (cl_chain);
1730 in_chain; in_chain = TREE_CHAIN (in_chain))
1732 expr = build_unary_op (ADDR_EXPR, TREE_VALUE (in_chain), 1);
1733 initlist = tree_cons (NULL_TREE, expr, initlist);
1736 /* Output {..., NULL}. */
1737 initlist = tree_cons (NULL_TREE, build_int_2 (0, 0), initlist);
1739 expr = build_constructor (TREE_TYPE (decl), nreverse (initlist));
1740 finish_decl (decl, expr, NULL_TREE);
1741 TREE_USED (decl) = 1;
1743 type = build_array_type (build_pointer_type (void_type_node), 0);
1744 decl = build_decl (VAR_DECL, ident, type);
1745 TREE_USED (decl) = 1;
1746 TREE_STATIC (decl) = 1;
1748 = tree_cons (NULL_TREE, build_unary_op (ADDR_EXPR, decl, 1), decls);
1751 decls = tree_cons (NULL_TREE, build_int_2 (0, 0), decls);
1752 ident = get_identifier ("_OBJC_STATIC_INSTANCES");
1753 expr_decl = build_nt (ARRAY_REF, ident, NULL_TREE);
1754 decl_spec = tree_cons (NULL_TREE, build_pointer_type (void_type_node),
1755 build_tree_list (NULL_TREE,
1756 ridpointers[(int) RID_STATIC]));
1757 static_instances_decl
1758 = start_decl (expr_decl, decl_spec, 1, NULL_TREE);
1759 TREE_USED (static_instances_decl) = 1;
1760 DECL_CONTEXT (static_instances_decl) = 0;
1761 DECL_ARTIFICIAL (static_instances_decl) = 1;
1762 expr = build_constructor (TREE_TYPE (static_instances_decl),
1764 finish_decl (static_instances_decl, expr, NULL_TREE);
1767 /* Output all strings. */
1772 tree sc_spec, decl_specs, expr_decl;
1773 tree chain, string_expr;
1776 for (chain = class_names_chain; chain; chain = TREE_CHAIN (chain))
1778 string = TREE_VALUE (chain);
1779 decl = TREE_PURPOSE (chain);
1781 = tree_cons (NULL_TREE, ridpointers[(int) RID_STATIC], NULL_TREE);
1782 decl_specs = tree_cons (NULL_TREE, ridpointers[(int) RID_CHAR], sc_spec);
1783 expr_decl = build_nt (ARRAY_REF, DECL_NAME (decl), NULL_TREE);
1784 decl = start_decl (expr_decl, decl_specs, 1, NULL_TREE);
1785 DECL_CONTEXT (decl) = NULL_TREE;
1786 string_expr = my_build_string (IDENTIFIER_LENGTH (string) + 1,
1787 IDENTIFIER_POINTER (string));
1788 finish_decl (decl, string_expr, NULL_TREE);
1791 for (chain = meth_var_names_chain; chain; chain = TREE_CHAIN (chain))
1793 string = TREE_VALUE (chain);
1794 decl = TREE_PURPOSE (chain);
1796 = tree_cons (NULL_TREE, ridpointers[(int) RID_STATIC], NULL_TREE);
1797 decl_specs = tree_cons (NULL_TREE, ridpointers[(int) RID_CHAR], sc_spec);
1798 expr_decl = build_nt (ARRAY_REF, DECL_NAME (decl), NULL_TREE);
1799 decl = start_decl (expr_decl, decl_specs, 1, NULL_TREE);
1800 DECL_CONTEXT (decl) = NULL_TREE;
1801 string_expr = my_build_string (IDENTIFIER_LENGTH (string) + 1,
1802 IDENTIFIER_POINTER (string));
1803 finish_decl (decl, string_expr, NULL_TREE);
1806 for (chain = meth_var_types_chain; chain; chain = TREE_CHAIN (chain))
1808 string = TREE_VALUE (chain);
1809 decl = TREE_PURPOSE (chain);
1811 = tree_cons (NULL_TREE, ridpointers[(int) RID_STATIC], NULL_TREE);
1812 decl_specs = tree_cons (NULL_TREE, ridpointers[(int) RID_CHAR], sc_spec);
1813 expr_decl = build_nt (ARRAY_REF, DECL_NAME (decl), NULL_TREE);
1814 decl = start_decl (expr_decl, decl_specs, 1, NULL_TREE);
1815 DECL_CONTEXT (decl) = NULL_TREE;
1816 string_expr = my_build_string (IDENTIFIER_LENGTH (string) + 1,
1817 IDENTIFIER_POINTER (string));
1818 finish_decl (decl, string_expr, NULL_TREE);
1823 build_selector_reference_decl ()
1829 sprintf (buf, "_OBJC_SELECTOR_REFERENCES_%d", idx++);
1831 ident = get_identifier (buf);
1833 decl = build_decl (VAR_DECL, ident, selector_type);
1834 DECL_EXTERNAL (decl) = 1;
1835 TREE_PUBLIC (decl) = 1;
1836 TREE_USED (decl) = 1;
1837 TREE_READONLY (decl) = 1;
1838 DECL_ARTIFICIAL (decl) = 1;
1839 DECL_CONTEXT (decl) = 0;
1841 make_decl_rtl (decl, 0);
1842 pushdecl_top_level (decl);
1847 /* Just a handy wrapper for add_objc_string. */
1850 build_selector (ident)
1853 tree expr = add_objc_string (ident, meth_var_names);
1854 if (flag_typed_selectors)
1857 return build_c_cast (selector_type, expr); /* cast! */
1861 build_selector_translation_table ()
1863 tree sc_spec, decl_specs;
1864 tree chain, initlist = NULL_TREE;
1866 tree decl = NULL_TREE, var_decl, name;
1868 for (chain = sel_ref_chain; chain; chain = TREE_CHAIN (chain))
1872 if (warn_selector && objc_implementation_context)
1876 for (method_chain = meth_var_names_chain;
1878 method_chain = TREE_CHAIN (method_chain))
1880 if (TREE_VALUE (method_chain) == TREE_VALUE (chain))
1888 /* Adjust line number for warning message. */
1889 int save_lineno = lineno;
1890 if (flag_next_runtime && TREE_PURPOSE (chain))
1891 lineno = DECL_SOURCE_LINE (TREE_PURPOSE (chain));
1892 warning ("creating selector for non existant method %s",
1893 IDENTIFIER_POINTER (TREE_VALUE (chain)));
1894 lineno = save_lineno;
1898 expr = build_selector (TREE_VALUE (chain));
1900 if (flag_next_runtime)
1902 name = DECL_NAME (TREE_PURPOSE (chain));
1904 sc_spec = build_tree_list (NULL_TREE, ridpointers[(int) RID_STATIC]);
1906 /* static SEL _OBJC_SELECTOR_REFERENCES_n = ...; */
1907 decl_specs = tree_cons (NULL_TREE, selector_type, sc_spec);
1911 /* The `decl' that is returned from start_decl is the one that we
1912 forward declared in `build_selector_reference' */
1913 decl = start_decl (var_decl, decl_specs, 1, NULL_TREE );
1916 /* add one for the '\0' character */
1917 offset += IDENTIFIER_LENGTH (TREE_VALUE (chain)) + 1;
1919 if (flag_next_runtime)
1920 finish_decl (decl, expr, NULL_TREE);
1923 if (flag_typed_selectors)
1925 tree eltlist = NULL_TREE;
1926 tree encoding = get_proto_encoding (TREE_PURPOSE (chain));
1927 eltlist = tree_cons (NULL_TREE, expr, NULL_TREE);
1928 eltlist = tree_cons (NULL_TREE, encoding, eltlist);
1929 expr = build_constructor (objc_selector_template,
1930 nreverse (eltlist));
1932 initlist = tree_cons (NULL_TREE, expr, initlist);
1937 if (! flag_next_runtime)
1939 /* Cause the variable and its initial value to be actually output. */
1940 DECL_EXTERNAL (UOBJC_SELECTOR_TABLE_decl) = 0;
1941 TREE_STATIC (UOBJC_SELECTOR_TABLE_decl) = 1;
1942 /* NULL terminate the list and fix the decl for output. */
1943 initlist = tree_cons (NULL_TREE, build_int_2 (0, 0), initlist);
1944 DECL_INITIAL (UOBJC_SELECTOR_TABLE_decl) = objc_ellipsis_node;
1945 initlist = build_constructor (TREE_TYPE (UOBJC_SELECTOR_TABLE_decl),
1946 nreverse (initlist));
1947 finish_decl (UOBJC_SELECTOR_TABLE_decl, initlist, NULL_TREE);
1948 current_function_decl = NULL_TREE;
1953 get_proto_encoding (proto)
1961 if (! METHOD_ENCODING (proto))
1963 tmp_decl = build_tmp_function_decl ();
1964 hack_method_prototype (proto, tmp_decl);
1965 encoding = encode_method_prototype (proto, tmp_decl);
1966 METHOD_ENCODING (proto) = encoding;
1969 encoding = METHOD_ENCODING (proto);
1971 return add_objc_string (encoding, meth_var_types);
1974 return build_int_2 (0, 0);
1977 /* sel_ref_chain is a list whose "value" fields will be instances of
1978 identifier_node that represent the selector. */
1981 build_typed_selector_reference (ident, prototype)
1982 tree ident, prototype;
1984 tree *chain = &sel_ref_chain;
1990 if (TREE_PURPOSE (*chain) == prototype && TREE_VALUE (*chain) == ident)
1991 goto return_at_index;
1994 chain = &TREE_CHAIN (*chain);
1997 *chain = tree_cons (prototype, ident, NULL_TREE);
2000 expr = build_unary_op (ADDR_EXPR,
2001 build_array_ref (UOBJC_SELECTOR_TABLE_decl,
2002 build_int_2 (index, 0)),
2004 return build_c_cast (selector_type, expr);
2008 build_selector_reference (ident)
2011 tree *chain = &sel_ref_chain;
2017 if (TREE_VALUE (*chain) == ident)
2018 return (flag_next_runtime
2019 ? TREE_PURPOSE (*chain)
2020 : build_array_ref (UOBJC_SELECTOR_TABLE_decl,
2021 build_int_2 (index, 0)));
2024 chain = &TREE_CHAIN (*chain);
2027 expr = build_selector_reference_decl ();
2029 *chain = tree_cons (expr, ident, NULL_TREE);
2031 return (flag_next_runtime
2033 : build_array_ref (UOBJC_SELECTOR_TABLE_decl,
2034 build_int_2 (index, 0)));
2038 build_class_reference_decl ()
2044 sprintf (buf, "_OBJC_CLASS_REFERENCES_%d", idx++);
2046 ident = get_identifier (buf);
2048 decl = build_decl (VAR_DECL, ident, objc_class_type);
2049 DECL_EXTERNAL (decl) = 1;
2050 TREE_PUBLIC (decl) = 1;
2051 TREE_USED (decl) = 1;
2052 TREE_READONLY (decl) = 1;
2053 DECL_CONTEXT (decl) = 0;
2054 DECL_ARTIFICIAL (decl) = 1;
2056 make_decl_rtl (decl, 0);
2057 pushdecl_top_level (decl);
2062 /* Create a class reference, but don't create a variable to reference
2066 add_class_reference (ident)
2071 if ((chain = cls_ref_chain))
2076 if (ident == TREE_VALUE (chain))
2080 chain = TREE_CHAIN (chain);
2084 /* Append to the end of the list */
2085 TREE_CHAIN (tail) = tree_cons (NULL_TREE, ident, NULL_TREE);
2088 cls_ref_chain = tree_cons (NULL_TREE, ident, NULL_TREE);
2091 /* Get a class reference, creating it if necessary. Also create the
2092 reference variable. */
2095 get_class_reference (ident)
2098 if (flag_next_runtime)
2103 for (chain = &cls_ref_chain; *chain; chain = &TREE_CHAIN (*chain))
2104 if (TREE_VALUE (*chain) == ident)
2106 if (! TREE_PURPOSE (*chain))
2107 TREE_PURPOSE (*chain) = build_class_reference_decl ();
2109 return TREE_PURPOSE (*chain);
2112 decl = build_class_reference_decl ();
2113 *chain = tree_cons (decl, ident, NULL_TREE);
2120 add_class_reference (ident);
2122 params = build_tree_list (NULL_TREE,
2123 my_build_string (IDENTIFIER_LENGTH (ident) + 1,
2124 IDENTIFIER_POINTER (ident)));
2126 assemble_external (objc_get_class_decl);
2127 return build_function_call (objc_get_class_decl, params);
2131 /* For each string section we have a chain which maps identifier nodes
2132 to decls for the strings. */
2135 add_objc_string (ident, section)
2137 enum string_section section;
2141 if (section == class_names)
2142 chain = &class_names_chain;
2143 else if (section == meth_var_names)
2144 chain = &meth_var_names_chain;
2145 else if (section == meth_var_types)
2146 chain = &meth_var_types_chain;
2152 if (TREE_VALUE (*chain) == ident)
2153 return build_unary_op (ADDR_EXPR, TREE_PURPOSE (*chain), 1);
2155 chain = &TREE_CHAIN (*chain);
2158 decl = build_objc_string_decl (section);
2160 *chain = tree_cons (decl, ident, NULL_TREE);
2162 return build_unary_op (ADDR_EXPR, decl, 1);
2166 build_objc_string_decl (section)
2167 enum string_section section;
2171 static int class_names_idx = 0;
2172 static int meth_var_names_idx = 0;
2173 static int meth_var_types_idx = 0;
2175 if (section == class_names)
2176 sprintf (buf, "_OBJC_CLASS_NAME_%d", class_names_idx++);
2177 else if (section == meth_var_names)
2178 sprintf (buf, "_OBJC_METH_VAR_NAME_%d", meth_var_names_idx++);
2179 else if (section == meth_var_types)
2180 sprintf (buf, "_OBJC_METH_VAR_TYPE_%d", meth_var_types_idx++);
2182 ident = get_identifier (buf);
2184 decl = build_decl (VAR_DECL, ident, build_array_type (char_type_node, 0));
2185 DECL_EXTERNAL (decl) = 1;
2186 TREE_PUBLIC (decl) = 1;
2187 TREE_USED (decl) = 1;
2188 TREE_READONLY (decl) = 1;
2189 TREE_CONSTANT (decl) = 1;
2190 DECL_CONTEXT (decl) = 0;
2191 DECL_ARTIFICIAL (decl) = 1;
2193 make_decl_rtl (decl, 0);
2194 pushdecl_top_level (decl);
2201 objc_declare_alias (alias_ident, class_ident)
2205 if (is_class_name (class_ident) != class_ident)
2206 warning ("cannot find class `%s'", IDENTIFIER_POINTER (class_ident));
2207 else if (is_class_name (alias_ident))
2208 warning ("class `%s' already exists", IDENTIFIER_POINTER (alias_ident));
2210 alias_chain = tree_cons (class_ident, alias_ident, alias_chain);
2214 objc_declare_class (ident_list)
2219 for (list = ident_list; list; list = TREE_CHAIN (list))
2221 tree ident = TREE_VALUE (list);
2224 if ((decl = lookup_name (ident)))
2226 error ("`%s' redeclared as different kind of symbol",
2227 IDENTIFIER_POINTER (ident));
2228 error_with_decl (decl, "previous declaration of `%s'");
2231 if (! is_class_name (ident))
2233 tree record = xref_tag (RECORD_TYPE, ident);
2234 TREE_STATIC_TEMPLATE (record) = 1;
2235 class_chain = tree_cons (NULL_TREE, ident, class_chain);
2241 is_class_name (ident)
2246 if (lookup_interface (ident))
2249 for (chain = class_chain; chain; chain = TREE_CHAIN (chain))
2251 if (ident == TREE_VALUE (chain))
2255 for (chain = alias_chain; chain; chain = TREE_CHAIN (chain))
2257 if (ident == TREE_VALUE (chain))
2258 return TREE_PURPOSE (chain);
2265 lookup_interface (ident)
2270 for (chain = interface_chain; chain; chain = TREE_CHAIN (chain))
2272 if (ident == CLASS_NAME (chain))
2278 /* Used by: build_private_template, continue_class,
2279 and for @defs constructs. */
2282 get_class_ivars (interface)
2285 tree my_name, super_name, ivar_chain;
2287 my_name = CLASS_NAME (interface);
2288 super_name = CLASS_SUPER_NAME (interface);
2289 ivar_chain = CLASS_IVARS (interface);
2291 /* Save off a pristine copy of the leaf ivars (i.e, those not
2292 inherited from a super class). */
2293 if (!CLASS_OWN_IVARS (interface))
2294 CLASS_OWN_IVARS (interface) = copy_list (ivar_chain);
2299 tree super_interface = lookup_interface (super_name);
2301 if (!super_interface)
2303 /* fatal did not work with 2 args...should fix */
2304 error ("cannot find interface declaration for `%s', superclass of `%s'",
2305 IDENTIFIER_POINTER (super_name),
2306 IDENTIFIER_POINTER (my_name));
2307 exit (FATAL_EXIT_CODE);
2310 if (super_interface == interface)
2311 fatal_error ("circular inheritance in interface declaration for `%s'",
2312 IDENTIFIER_POINTER (super_name));
2314 interface = super_interface;
2315 my_name = CLASS_NAME (interface);
2316 super_name = CLASS_SUPER_NAME (interface);
2318 op1 = CLASS_OWN_IVARS (interface);
2321 tree head = copy_list (op1);
2323 /* Prepend super class ivars...make a copy of the list, we
2324 do not want to alter the original. */
2325 chainon (head, ivar_chain);
2332 /* struct <classname> {
2333 struct objc_class *isa;
2338 build_private_template (class)
2343 if (CLASS_STATIC_TEMPLATE (class))
2345 uprivate_record = CLASS_STATIC_TEMPLATE (class);
2346 ivar_context = TYPE_FIELDS (CLASS_STATIC_TEMPLATE (class));
2350 uprivate_record = start_struct (RECORD_TYPE, CLASS_NAME (class));
2352 ivar_context = get_class_ivars (class);
2354 finish_struct (uprivate_record, ivar_context, NULL_TREE);
2356 CLASS_STATIC_TEMPLATE (class) = uprivate_record;
2358 /* mark this record as class template - for class type checking */
2359 TREE_STATIC_TEMPLATE (uprivate_record) = 1;
2363 = groktypename (build_tree_list (build_tree_list (NULL_TREE,
2365 build1 (INDIRECT_REF, NULL_TREE,
2368 return ivar_context;
2371 /* Begin code generation for protocols... */
2373 /* struct objc_protocol {
2374 char *protocol_name;
2375 struct objc_protocol **protocol_list;
2376 struct objc_method_desc *instance_methods;
2377 struct objc_method_desc *class_methods;
2381 build_protocol_template ()
2383 tree decl_specs, field_decl, field_decl_chain;
2386 template = start_struct (RECORD_TYPE, get_identifier (UTAG_PROTOCOL));
2388 /* struct objc_class *isa; */
2390 decl_specs = build_tree_list (NULL_TREE, xref_tag (RECORD_TYPE,
2391 get_identifier (UTAG_CLASS)));
2392 field_decl = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("isa"));
2394 = grokfield (input_filename, lineno, field_decl, decl_specs, NULL_TREE);
2395 field_decl_chain = field_decl;
2397 /* char *protocol_name; */
2399 decl_specs = build_tree_list (NULL_TREE, ridpointers[(int) RID_CHAR]);
2401 = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("protocol_name"));
2403 = grokfield (input_filename, lineno, field_decl, decl_specs, NULL_TREE);
2404 chainon (field_decl_chain, field_decl);
2406 /* struct objc_protocol **protocol_list; */
2408 decl_specs = build_tree_list (NULL_TREE, template);
2410 = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("protocol_list"));
2411 field_decl = build1 (INDIRECT_REF, NULL_TREE, field_decl);
2413 = grokfield (input_filename, lineno, field_decl, decl_specs, NULL_TREE);
2414 chainon (field_decl_chain, field_decl);
2416 /* struct objc_method_list *instance_methods; */
2419 = build_tree_list (NULL_TREE,
2420 xref_tag (RECORD_TYPE,
2421 get_identifier (UTAG_METHOD_PROTOTYPE_LIST)));
2423 = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("instance_methods"));
2425 = grokfield (input_filename, lineno, field_decl, decl_specs, NULL_TREE);
2426 chainon (field_decl_chain, field_decl);
2428 /* struct objc_method_list *class_methods; */
2431 = build_tree_list (NULL_TREE,
2432 xref_tag (RECORD_TYPE,
2433 get_identifier (UTAG_METHOD_PROTOTYPE_LIST)));
2435 = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("class_methods"));
2437 = grokfield (input_filename, lineno, field_decl, decl_specs, NULL_TREE);
2438 chainon (field_decl_chain, field_decl);
2440 return finish_struct (template, field_decl_chain, NULL_TREE);
2444 build_descriptor_table_initializer (type, entries)
2448 tree initlist = NULL_TREE;
2452 tree eltlist = NULL_TREE;
2455 = tree_cons (NULL_TREE,
2456 build_selector (METHOD_SEL_NAME (entries)), NULL_TREE);
2458 = tree_cons (NULL_TREE,
2459 add_objc_string (METHOD_ENCODING (entries),
2464 = tree_cons (NULL_TREE,
2465 build_constructor (type, nreverse (eltlist)), initlist);
2467 entries = TREE_CHAIN (entries);
2471 return build_constructor (build_array_type (type, 0), nreverse (initlist));
2474 /* struct objc_method_prototype_list {
2476 struct objc_method_prototype {
2483 build_method_prototype_list_template (list_type, size)
2487 tree objc_ivar_list_record;
2488 tree decl_specs, field_decl, field_decl_chain;
2490 /* Generate an unnamed struct definition. */
2492 objc_ivar_list_record = start_struct (RECORD_TYPE, NULL_TREE);
2494 /* int method_count; */
2496 decl_specs = build_tree_list (NULL_TREE, ridpointers[(int) RID_INT]);
2497 field_decl = get_identifier ("method_count");
2500 = grokfield (input_filename, lineno, field_decl, decl_specs, NULL_TREE);
2501 field_decl_chain = field_decl;
2503 /* struct objc_method method_list[]; */
2505 decl_specs = build_tree_list (NULL_TREE, list_type);
2506 field_decl = build_nt (ARRAY_REF, get_identifier ("method_list"),
2507 build_int_2 (size, 0));
2510 = grokfield (input_filename, lineno, field_decl, decl_specs, NULL_TREE);
2511 chainon (field_decl_chain, field_decl);
2513 finish_struct (objc_ivar_list_record, field_decl_chain, NULL_TREE);
2515 return objc_ivar_list_record;
2519 build_method_prototype_template ()
2522 tree decl_specs, field_decl, field_decl_chain;
2525 = start_struct (RECORD_TYPE, get_identifier (UTAG_METHOD_PROTOTYPE));
2527 /* struct objc_selector *_cmd; */
2528 decl_specs = tree_cons (NULL_TREE, xref_tag (RECORD_TYPE,
2529 get_identifier (TAG_SELECTOR)), NULL_TREE);
2530 field_decl = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("_cmd"));
2533 = grokfield (input_filename, lineno, field_decl, decl_specs, NULL_TREE);
2534 field_decl_chain = field_decl;
2536 decl_specs = tree_cons (NULL_TREE, ridpointers[(int) RID_CHAR], NULL_TREE);
2538 = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("method_types"));
2540 = grokfield (input_filename, lineno, field_decl, decl_specs, NULL_TREE);
2541 chainon (field_decl_chain, field_decl);
2543 finish_struct (proto_record, field_decl_chain, NULL_TREE);
2545 return proto_record;
2548 /* True if last call to forwarding_offset yielded a register offset. */
2549 static int offset_is_register;
2552 forwarding_offset (parm)
2555 int offset_in_bytes;
2557 if (GET_CODE (DECL_INCOMING_RTL (parm)) == MEM)
2559 rtx addr = XEXP (DECL_INCOMING_RTL (parm), 0);
2561 /* ??? Here we assume that the parm address is indexed
2562 off the frame pointer or arg pointer.
2563 If that is not true, we produce meaningless results,
2564 but do not crash. */
2565 if (GET_CODE (addr) == PLUS
2566 && GET_CODE (XEXP (addr, 1)) == CONST_INT)
2567 offset_in_bytes = INTVAL (XEXP (addr, 1));
2569 offset_in_bytes = 0;
2571 offset_in_bytes += OBJC_FORWARDING_STACK_OFFSET;
2572 offset_is_register = 0;
2574 else if (GET_CODE (DECL_INCOMING_RTL (parm)) == REG)
2576 int regno = REGNO (DECL_INCOMING_RTL (parm));
2577 offset_in_bytes = apply_args_register_offset (regno);
2578 offset_is_register = 1;
2583 /* This is the case where the parm is passed as an int or double
2584 and it is converted to a char, short or float and stored back
2585 in the parmlist. In this case, describe the parm
2586 with the variable's declared type, and adjust the address
2587 if the least significant bytes (which we are using) are not
2589 if (BYTES_BIG_ENDIAN && TREE_TYPE (parm) != DECL_ARG_TYPE (parm))
2590 offset_in_bytes += (GET_MODE_SIZE (TYPE_MODE (DECL_ARG_TYPE (parm)))
2591 - GET_MODE_SIZE (GET_MODE (DECL_RTL (parm))));
2593 return offset_in_bytes;
2597 encode_method_prototype (method_decl, func_decl)
2604 HOST_WIDE_INT max_parm_end = 0;
2608 /* ONEWAY and BYCOPY, for remote object are the only method qualifiers. */
2609 encode_type_qualifiers (TREE_PURPOSE (TREE_TYPE (method_decl)));
2612 encode_type (TREE_TYPE (TREE_TYPE (func_decl)),
2613 obstack_object_size (&util_obstack),
2614 OBJC_ENCODE_INLINE_DEFS);
2617 for (parms = DECL_ARGUMENTS (func_decl); parms;
2618 parms = TREE_CHAIN (parms))
2620 HOST_WIDE_INT parm_end = (forwarding_offset (parms)
2621 + int_size_in_bytes (TREE_TYPE (parms)));
2623 if (!offset_is_register && max_parm_end < parm_end)
2624 max_parm_end = parm_end;
2627 stack_size = max_parm_end - OBJC_FORWARDING_MIN_OFFSET;
2629 sprintf (buf, "%d", stack_size);
2630 obstack_grow (&util_obstack, buf, strlen (buf));
2632 user_args = METHOD_SEL_ARGS (method_decl);
2634 /* Argument types. */
2635 for (parms = DECL_ARGUMENTS (func_decl), i = 0; parms;
2636 parms = TREE_CHAIN (parms), i++)
2638 /* Process argument qualifiers for user supplied arguments. */
2641 encode_type_qualifiers (TREE_PURPOSE (TREE_TYPE (user_args)));
2642 user_args = TREE_CHAIN (user_args);
2646 encode_type (TREE_TYPE (parms),
2647 obstack_object_size (&util_obstack),
2648 OBJC_ENCODE_INLINE_DEFS);
2650 /* Compute offset. */
2651 sprintf (buf, "%d", forwarding_offset (parms));
2653 /* Indicate register. */
2654 if (offset_is_register)
2655 obstack_1grow (&util_obstack, '+');
2657 obstack_grow (&util_obstack, buf, strlen (buf));
2660 obstack_1grow (&util_obstack, '\0');
2661 result = get_identifier (obstack_finish (&util_obstack));
2662 obstack_free (&util_obstack, util_firstobj);
2667 generate_descriptor_table (type, name, size, list, proto)
2674 tree sc_spec, decl_specs, decl, initlist;
2676 sc_spec = tree_cons (NULL_TREE, ridpointers[(int) RID_STATIC], NULL_TREE);
2677 decl_specs = tree_cons (NULL_TREE, type, sc_spec);
2679 decl = start_decl (synth_id_with_class_suffix (name, proto),
2680 decl_specs, 1, NULL_TREE);
2681 DECL_CONTEXT (decl) = NULL_TREE;
2683 initlist = build_tree_list (NULL_TREE, build_int_2 (size, 0));
2684 initlist = tree_cons (NULL_TREE, list, initlist);
2686 finish_decl (decl, build_constructor (type, nreverse (initlist)),
2693 generate_method_descriptors (protocol)
2696 tree initlist, chain, method_list_template;
2697 tree cast, variable_length_type;
2700 if (!objc_method_prototype_template)
2701 objc_method_prototype_template = build_method_prototype_template ();
2703 cast = build_tree_list (build_tree_list (NULL_TREE, xref_tag (RECORD_TYPE,
2704 get_identifier (UTAG_METHOD_PROTOTYPE_LIST))),
2706 variable_length_type = groktypename (cast);
2708 chain = PROTOCOL_CLS_METHODS (protocol);
2711 size = list_length (chain);
2713 method_list_template
2714 = build_method_prototype_list_template (objc_method_prototype_template,
2718 = build_descriptor_table_initializer (objc_method_prototype_template,
2721 UOBJC_CLASS_METHODS_decl
2722 = generate_descriptor_table (method_list_template,
2723 "_OBJC_PROTOCOL_CLASS_METHODS",
2724 size, initlist, protocol);
2725 TREE_TYPE (UOBJC_CLASS_METHODS_decl) = variable_length_type;
2728 UOBJC_CLASS_METHODS_decl = 0;
2730 chain = PROTOCOL_NST_METHODS (protocol);
2733 size = list_length (chain);
2735 method_list_template
2736 = build_method_prototype_list_template (objc_method_prototype_template,
2739 = build_descriptor_table_initializer (objc_method_prototype_template,
2742 UOBJC_INSTANCE_METHODS_decl
2743 = generate_descriptor_table (method_list_template,
2744 "_OBJC_PROTOCOL_INSTANCE_METHODS",
2745 size, initlist, protocol);
2746 TREE_TYPE (UOBJC_INSTANCE_METHODS_decl) = variable_length_type;
2749 UOBJC_INSTANCE_METHODS_decl = 0;
2752 /* Generate a temporary FUNCTION_DECL node to be used in
2753 hack_method_prototype below. */
2756 build_tmp_function_decl ()
2758 tree decl_specs, expr_decl, parms;
2762 /* struct objc_object *objc_xxx (id, SEL, ...); */
2764 decl_specs = build_tree_list (NULL_TREE, objc_object_reference);
2765 push_parm_decl (build_tree_list
2766 (build_tree_list (decl_specs,
2767 build1 (INDIRECT_REF, NULL_TREE,
2771 decl_specs = build_tree_list (NULL_TREE, xref_tag (RECORD_TYPE,
2772 get_identifier (TAG_SELECTOR)));
2773 expr_decl = build1 (INDIRECT_REF, NULL_TREE, NULL_TREE);
2775 push_parm_decl (build_tree_list (build_tree_list (decl_specs, expr_decl),
2777 parms = get_parm_info (0);
2780 decl_specs = build_tree_list (NULL_TREE, objc_object_reference);
2781 sprintf (buffer, "__objc_tmp_%x", xxx++);
2782 expr_decl = build_nt (CALL_EXPR, get_identifier (buffer), parms, NULL_TREE);
2783 expr_decl = build1 (INDIRECT_REF, NULL_TREE, expr_decl);
2785 return define_decl (expr_decl, decl_specs);
2788 /* Generate the prototypes for protocol methods. This is used to
2789 generate method encodings for these.
2791 NST_METHODS is the method to generate a _DECL node for TMP_DECL is
2792 a decl node to be used. This is also where the return value is
2796 hack_method_prototype (nst_methods, tmp_decl)
2803 /* Hack to avoid problem with static typing of self arg. */
2804 TREE_SET_CODE (nst_methods, CLASS_METHOD_DECL);
2805 start_method_def (nst_methods);
2806 TREE_SET_CODE (nst_methods, INSTANCE_METHOD_DECL);
2808 if (METHOD_ADD_ARGS (nst_methods) == objc_ellipsis_node)
2809 parms = get_parm_info (0); /* we have a `, ...' */
2811 parms = get_parm_info (1); /* place a `void_at_end' */
2813 poplevel (0, 0, 0); /* Must be called BEFORE start_function. */
2815 /* Usually called from store_parm_decls -> init_function_start. */
2817 DECL_ARGUMENTS (tmp_decl) = TREE_PURPOSE (parms);
2819 if (current_function_decl)
2821 current_function_decl = tmp_decl;
2824 /* Code taken from start_function. */
2825 tree restype = TREE_TYPE (TREE_TYPE (tmp_decl));
2826 /* Promote the value to int before returning it. */
2827 if (TREE_CODE (restype) == INTEGER_TYPE
2828 && TYPE_PRECISION (restype) < TYPE_PRECISION (integer_type_node))
2829 restype = integer_type_node;
2830 DECL_RESULT (tmp_decl) = build_decl (RESULT_DECL, 0, restype);
2833 for (parm = DECL_ARGUMENTS (tmp_decl); parm; parm = TREE_CHAIN (parm))
2834 DECL_CONTEXT (parm) = tmp_decl;
2836 init_function_start (tmp_decl, "objc-act", 0);
2838 /* Typically called from expand_function_start for function definitions. */
2839 assign_parms (tmp_decl);
2841 /* install return type */
2842 TREE_TYPE (TREE_TYPE (tmp_decl)) = groktypename (TREE_TYPE (nst_methods));
2844 current_function_decl = NULL;
2848 generate_protocol_references (plist)
2853 /* Forward declare protocols referenced. */
2854 for (lproto = plist; lproto; lproto = TREE_CHAIN (lproto))
2856 tree proto = TREE_VALUE (lproto);
2858 if (TREE_CODE (proto) == PROTOCOL_INTERFACE_TYPE
2859 && PROTOCOL_NAME (proto))
2861 if (! PROTOCOL_FORWARD_DECL (proto))
2862 build_protocol_reference (proto);
2864 if (PROTOCOL_LIST (proto))
2865 generate_protocol_references (PROTOCOL_LIST (proto));
2870 /* For each protocol which was referenced either from a @protocol()
2871 expression, or because a class/category implements it (then a
2872 pointer to the protocol is stored in the struct describing the
2873 class/category), we create a statically allocated instance of the
2874 Protocol class. The code is written in such a way as to generate
2875 as few Protocol objects as possible; we generate a unique Protocol
2876 instance for each protocol, and we don't generate a Protocol
2877 instance if the protocol is never referenced (either from a
2878 @protocol() or from a class/category implementation). These
2879 statically allocated objects can be referred to via the static
2880 (that is, private to this module) symbols _OBJC_PROTOCOL_n.
2882 The statically allocated Protocol objects that we generate here
2883 need to be fixed up at runtime in order to be used: the 'isa'
2884 pointer of the objects need to be set up to point to the 'Protocol'
2885 class, as known at runtime.
2887 The NeXT runtime fixes up all protocols at program startup time,
2888 before main() is entered. It uses a low-level trick to look up all
2889 those symbols, then loops on them and fixes them up.
2891 The GNU runtime as well fixes up all protocols before user code
2892 from the module is executed; it requires pointers to those symbols
2893 to be put in the objc_symtab (which is then passed as argument to
2894 the function __objc_exec_class() which the compiler sets up to be
2895 executed automatically when the module is loaded); setup of those
2896 Protocol objects happen in two ways in the GNU runtime: all
2897 Protocol objects referred to by a class or category implementation
2898 are fixed up when the class/category is loaded; all Protocol
2899 objects referred to by a @protocol() expression are added by the
2900 compiler to the list of statically allocated instances to fixup
2901 (the same list holding the statically allocated constant string
2902 objects). Because, as explained above, the compiler generates as
2903 few Protocol objects as possible, some Protocol object might end up
2904 being referenced multiple times when compiled with the GNU runtime,
2905 and end up being fixed up multiple times at runtime inizialization.
2906 But that doesn't hurt, it's just a little inefficient. */
2908 generate_protocols ()
2910 tree p, tmp_decl, encoding;
2911 tree sc_spec, decl_specs, decl;
2912 tree initlist, protocol_name_expr, refs_decl, refs_expr;
2915 tmp_decl = build_tmp_function_decl ();
2917 if (! objc_protocol_template)
2918 objc_protocol_template = build_protocol_template ();
2920 /* If a protocol was directly referenced, pull in indirect references. */
2921 for (p = protocol_chain; p; p = TREE_CHAIN (p))
2922 if (PROTOCOL_FORWARD_DECL (p) && PROTOCOL_LIST (p))
2923 generate_protocol_references (PROTOCOL_LIST (p));
2925 for (p = protocol_chain; p; p = TREE_CHAIN (p))
2927 tree nst_methods = PROTOCOL_NST_METHODS (p);
2928 tree cls_methods = PROTOCOL_CLS_METHODS (p);
2930 /* If protocol wasn't referenced, don't generate any code. */
2931 if (! PROTOCOL_FORWARD_DECL (p))
2934 /* Make sure we link in the Protocol class. */
2935 add_class_reference (get_identifier (PROTOCOL_OBJECT_CLASS_NAME));
2939 if (! METHOD_ENCODING (nst_methods))
2941 hack_method_prototype (nst_methods, tmp_decl);
2942 encoding = encode_method_prototype (nst_methods, tmp_decl);
2943 METHOD_ENCODING (nst_methods) = encoding;
2945 nst_methods = TREE_CHAIN (nst_methods);
2950 if (! METHOD_ENCODING (cls_methods))
2952 hack_method_prototype (cls_methods, tmp_decl);
2953 encoding = encode_method_prototype (cls_methods, tmp_decl);
2954 METHOD_ENCODING (cls_methods) = encoding;
2957 cls_methods = TREE_CHAIN (cls_methods);
2959 generate_method_descriptors (p);
2961 if (PROTOCOL_LIST (p))
2962 refs_decl = generate_protocol_list (p);
2966 /* static struct objc_protocol _OBJC_PROTOCOL_<mumble>; */
2968 sc_spec = tree_cons (NULL_TREE, ridpointers[(int) RID_STATIC],
2970 decl_specs = tree_cons (NULL_TREE, objc_protocol_template, sc_spec);
2972 decl = start_decl (synth_id_with_class_suffix ("_OBJC_PROTOCOL", p),
2973 decl_specs, 1, NULL_TREE);
2975 DECL_CONTEXT (decl) = NULL_TREE;
2977 protocol_name_expr = add_objc_string (PROTOCOL_NAME (p), class_names);
2983 (build_tree_list (build_tree_list (NULL_TREE,
2984 objc_protocol_template),
2985 build1 (INDIRECT_REF, NULL_TREE,
2986 build1 (INDIRECT_REF, NULL_TREE,
2989 refs_expr = build_unary_op (ADDR_EXPR, refs_decl, 0);
2990 TREE_TYPE (refs_expr) = cast_type2;
2993 refs_expr = build_int_2 (0, 0);
2995 /* UOBJC_INSTANCE_METHODS_decl/UOBJC_CLASS_METHODS_decl are set
2996 by generate_method_descriptors, which is called above. */
2997 initlist = build_protocol_initializer (TREE_TYPE (decl),
2998 protocol_name_expr, refs_expr,
2999 UOBJC_INSTANCE_METHODS_decl,
3000 UOBJC_CLASS_METHODS_decl);
3001 finish_decl (decl, initlist, NULL_TREE);
3003 /* Mark the decl as used to avoid "defined but not used" warning. */
3004 TREE_USED (decl) = 1;
3009 build_protocol_initializer (type, protocol_name, protocol_list,
3010 instance_methods, class_methods)
3014 tree instance_methods;
3017 tree initlist = NULL_TREE, expr;
3020 cast_type = groktypename
3022 (build_tree_list (NULL_TREE,
3023 xref_tag (RECORD_TYPE,
3024 get_identifier (UTAG_CLASS))),
3025 build1 (INDIRECT_REF, NULL_TREE, NULL_TREE)));
3027 /* Filling the "isa" in with one allows the runtime system to
3028 detect that the version change...should remove before final release. */
3030 expr = build_int_2 (PROTOCOL_VERSION, 0);
3031 TREE_TYPE (expr) = cast_type;
3032 initlist = tree_cons (NULL_TREE, expr, initlist);
3033 initlist = tree_cons (NULL_TREE, protocol_name, initlist);
3034 initlist = tree_cons (NULL_TREE, protocol_list, initlist);
3036 if (!instance_methods)
3037 initlist = tree_cons (NULL_TREE, build_int_2 (0, 0), initlist);
3040 expr = build_unary_op (ADDR_EXPR, instance_methods, 0);
3041 initlist = tree_cons (NULL_TREE, expr, initlist);
3045 initlist = tree_cons (NULL_TREE, build_int_2 (0, 0), initlist);
3048 expr = build_unary_op (ADDR_EXPR, class_methods, 0);
3049 initlist = tree_cons (NULL_TREE, expr, initlist);
3052 return build_constructor (type, nreverse (initlist));
3055 /* struct objc_category {
3056 char *category_name;
3058 struct objc_method_list *instance_methods;
3059 struct objc_method_list *class_methods;
3060 struct objc_protocol_list *protocols;
3064 build_category_template ()
3066 tree decl_specs, field_decl, field_decl_chain;
3068 objc_category_template = start_struct (RECORD_TYPE,
3069 get_identifier (UTAG_CATEGORY));
3070 /* char *category_name; */
3072 decl_specs = build_tree_list (NULL_TREE, ridpointers[(int) RID_CHAR]);
3074 = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("category_name"));
3076 = grokfield (input_filename, lineno, field_decl, decl_specs, NULL_TREE);
3077 field_decl_chain = field_decl;
3079 /* char *class_name; */
3081 decl_specs = build_tree_list (NULL_TREE, ridpointers[(int) RID_CHAR]);
3082 field_decl = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("class_name"));
3084 = grokfield (input_filename, lineno, field_decl, decl_specs, NULL_TREE);
3085 chainon (field_decl_chain, field_decl);
3087 /* struct objc_method_list *instance_methods; */
3089 decl_specs = build_tree_list (NULL_TREE,
3090 xref_tag (RECORD_TYPE,
3091 get_identifier (UTAG_METHOD_LIST)));
3093 = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("instance_methods"));
3095 = grokfield (input_filename, lineno, field_decl, decl_specs, NULL_TREE);
3096 chainon (field_decl_chain, field_decl);
3098 /* struct objc_method_list *class_methods; */
3100 decl_specs = build_tree_list (NULL_TREE,
3101 xref_tag (RECORD_TYPE,
3102 get_identifier (UTAG_METHOD_LIST)));
3104 = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("class_methods"));
3106 = grokfield (input_filename, lineno, field_decl, decl_specs, NULL_TREE);
3107 chainon (field_decl_chain, field_decl);
3109 /* struct objc_protocol **protocol_list; */
3111 decl_specs = build_tree_list (NULL_TREE,
3112 xref_tag (RECORD_TYPE,
3113 get_identifier (UTAG_PROTOCOL)));
3115 = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("protocol_list"));
3116 field_decl = build1 (INDIRECT_REF, NULL_TREE, field_decl);
3118 = grokfield (input_filename, lineno, field_decl, decl_specs, NULL_TREE);
3119 chainon (field_decl_chain, field_decl);
3121 finish_struct (objc_category_template, field_decl_chain, NULL_TREE);
3124 /* struct objc_selector {
3130 build_selector_template ()
3133 tree decl_specs, field_decl, field_decl_chain;
3135 objc_selector_template
3136 = start_struct (RECORD_TYPE, get_identifier (UTAG_SELECTOR));
3140 decl_specs = build_tree_list (NULL_TREE, ridpointers[(int) RID_VOID]);
3141 field_decl = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("sel_id"));
3143 = grokfield (input_filename, lineno, field_decl, decl_specs, NULL_TREE);
3144 field_decl_chain = field_decl;
3146 /* char *sel_type; */
3148 decl_specs = build_tree_list (NULL_TREE, ridpointers[(int) RID_CHAR]);
3149 field_decl = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("sel_type"));
3151 = grokfield (input_filename, lineno, field_decl, decl_specs, NULL_TREE);
3152 chainon (field_decl_chain, field_decl);
3154 finish_struct (objc_selector_template, field_decl_chain, NULL_TREE);
3157 /* struct objc_class {
3158 struct objc_class *isa;
3159 struct objc_class *super_class;
3164 struct objc_ivar_list *ivars;
3165 struct objc_method_list *methods;
3166 if (flag_next_runtime)
3167 struct objc_cache *cache;
3169 struct sarray *dtable;
3170 struct objc_class *subclass_list;
3171 struct objc_class *sibling_class;
3173 struct objc_protocol_list *protocols;
3174 void *gc_object_type;
3178 build_class_template ()
3180 tree decl_specs, field_decl, field_decl_chain;
3183 = start_struct (RECORD_TYPE, get_identifier (UTAG_CLASS));
3185 /* struct objc_class *isa; */
3187 decl_specs = build_tree_list (NULL_TREE, objc_class_template);
3188 field_decl = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("isa"));
3190 = grokfield (input_filename, lineno, field_decl, decl_specs, NULL_TREE);
3191 field_decl_chain = field_decl;
3193 /* struct objc_class *super_class; */
3195 decl_specs = build_tree_list (NULL_TREE, objc_class_template);
3197 = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("super_class"));
3199 = grokfield (input_filename, lineno, field_decl, decl_specs, NULL_TREE);
3200 chainon (field_decl_chain, field_decl);
3204 decl_specs = build_tree_list (NULL_TREE, ridpointers[(int) RID_CHAR]);
3205 field_decl = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("name"));
3207 = grokfield (input_filename, lineno, field_decl, decl_specs, NULL_TREE);
3208 chainon (field_decl_chain, field_decl);
3212 decl_specs = build_tree_list (NULL_TREE, ridpointers[(int) RID_LONG]);
3213 field_decl = get_identifier ("version");
3215 = grokfield (input_filename, lineno, field_decl, decl_specs, NULL_TREE);
3216 chainon (field_decl_chain, field_decl);
3220 decl_specs = build_tree_list (NULL_TREE, ridpointers[(int) RID_LONG]);
3221 field_decl = get_identifier ("info");
3223 = grokfield (input_filename, lineno, field_decl, decl_specs, NULL_TREE);
3224 chainon (field_decl_chain, field_decl);
3226 /* long instance_size; */
3228 decl_specs = build_tree_list (NULL_TREE, ridpointers[(int) RID_LONG]);
3229 field_decl = get_identifier ("instance_size");
3231 = grokfield (input_filename, lineno, field_decl, decl_specs, NULL_TREE);
3232 chainon (field_decl_chain, field_decl);
3234 /* struct objc_ivar_list *ivars; */
3236 decl_specs = build_tree_list (NULL_TREE,
3237 xref_tag (RECORD_TYPE,
3238 get_identifier (UTAG_IVAR_LIST)));
3239 field_decl = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("ivars"));
3241 = grokfield (input_filename, lineno, field_decl, decl_specs, NULL_TREE);
3242 chainon (field_decl_chain, field_decl);
3244 /* struct objc_method_list *methods; */
3246 decl_specs = build_tree_list (NULL_TREE,
3247 xref_tag (RECORD_TYPE,
3248 get_identifier (UTAG_METHOD_LIST)));
3249 field_decl = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("methods"));
3251 = grokfield (input_filename, lineno, field_decl, decl_specs, NULL_TREE);
3252 chainon (field_decl_chain, field_decl);
3254 if (flag_next_runtime)
3256 /* struct objc_cache *cache; */
3258 decl_specs = build_tree_list (NULL_TREE,
3259 xref_tag (RECORD_TYPE,
3260 get_identifier ("objc_cache")));
3261 field_decl = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("cache"));
3262 field_decl = grokfield (input_filename, lineno, field_decl,
3263 decl_specs, NULL_TREE);
3264 chainon (field_decl_chain, field_decl);
3268 /* struct sarray *dtable; */
3270 decl_specs = build_tree_list (NULL_TREE,
3271 xref_tag (RECORD_TYPE,
3272 get_identifier ("sarray")));
3273 field_decl = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("dtable"));
3274 field_decl = grokfield (input_filename, lineno, field_decl,
3275 decl_specs, NULL_TREE);
3276 chainon (field_decl_chain, field_decl);
3278 /* struct objc_class *subclass_list; */
3280 decl_specs = build_tree_list (NULL_TREE, objc_class_template);
3282 = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("subclass_list"));
3283 field_decl = grokfield (input_filename, lineno, field_decl,
3284 decl_specs, NULL_TREE);
3285 chainon (field_decl_chain, field_decl);
3287 /* struct objc_class *sibling_class; */
3289 decl_specs = build_tree_list (NULL_TREE, objc_class_template);
3291 = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("sibling_class"));
3292 field_decl = grokfield (input_filename, lineno, field_decl,
3293 decl_specs, NULL_TREE);
3294 chainon (field_decl_chain, field_decl);
3297 /* struct objc_protocol **protocol_list; */
3299 decl_specs = build_tree_list (NULL_TREE,
3300 xref_tag (RECORD_TYPE,
3301 get_identifier (UTAG_PROTOCOL)));
3303 = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("protocol_list"));
3305 = build1 (INDIRECT_REF, NULL_TREE, field_decl);
3306 field_decl = grokfield (input_filename, lineno, field_decl,
3307 decl_specs, NULL_TREE);
3308 chainon (field_decl_chain, field_decl);
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 chainon (field_decl_chain, field_decl);
3318 /* void *gc_object_type; */
3320 decl_specs = build_tree_list (NULL_TREE, ridpointers[(int) RID_VOID]);
3321 field_decl = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("gc_object_type"));
3323 = grokfield (input_filename, lineno, field_decl, decl_specs, NULL_TREE);
3324 chainon (field_decl_chain, field_decl);
3326 finish_struct (objc_class_template, field_decl_chain, NULL_TREE);
3329 /* Generate appropriate forward declarations for an implementation. */
3332 synth_forward_declarations ()
3334 tree sc_spec, decl_specs, an_id;
3336 /* extern struct objc_class _OBJC_CLASS_<my_name>; */
3338 an_id = synth_id_with_class_suffix ("_OBJC_CLASS", objc_implementation_context);
3340 sc_spec = build_tree_list (NULL_TREE, ridpointers[(int) RID_EXTERN]);
3341 decl_specs = tree_cons (NULL_TREE, objc_class_template, sc_spec);
3342 UOBJC_CLASS_decl = define_decl (an_id, decl_specs);
3343 TREE_USED (UOBJC_CLASS_decl) = 1;
3344 DECL_ARTIFICIAL (UOBJC_CLASS_decl) = 1;
3346 /* extern struct objc_class _OBJC_METACLASS_<my_name>; */
3348 an_id = synth_id_with_class_suffix ("_OBJC_METACLASS",
3349 objc_implementation_context);
3351 UOBJC_METACLASS_decl = define_decl (an_id, decl_specs);
3352 TREE_USED (UOBJC_METACLASS_decl) = 1;
3353 DECL_ARTIFICIAL(UOBJC_METACLASS_decl) = 1;
3355 /* Pre-build the following entities - for speed/convenience. */
3357 an_id = get_identifier ("super_class");
3358 ucls_super_ref = build_component_ref (UOBJC_CLASS_decl, an_id);
3359 uucls_super_ref = build_component_ref (UOBJC_METACLASS_decl, an_id);
3363 error_with_ivar (message, decl, rawdecl)
3364 const char *message;
3368 diagnostic_count_diagnostic (global_dc, DK_ERROR);
3370 diagnostic_report_current_function (global_dc);
3372 error_with_file_and_line (DECL_SOURCE_FILE (decl),
3373 DECL_SOURCE_LINE (decl),
3375 message, gen_declaration (rawdecl, errbuf));
3380 check_ivars (inter, imp)
3384 tree intdecls = CLASS_IVARS (inter);
3385 tree impdecls = CLASS_IVARS (imp);
3386 tree rawintdecls = CLASS_RAW_IVARS (inter);
3387 tree rawimpdecls = CLASS_RAW_IVARS (imp);
3393 if (intdecls == 0 && impdecls == 0)
3395 if (intdecls == 0 || impdecls == 0)
3397 error ("inconsistent instance variable specification");
3401 t1 = TREE_TYPE (intdecls); t2 = TREE_TYPE (impdecls);
3403 if (!comptypes (t1, t2))
3405 if (DECL_NAME (intdecls) == DECL_NAME (impdecls))
3407 error_with_ivar ("conflicting instance variable type",
3408 impdecls, rawimpdecls);
3409 error_with_ivar ("previous declaration of",
3410 intdecls, rawintdecls);
3412 else /* both the type and the name don't match */
3414 error ("inconsistent instance variable specification");
3419 else if (DECL_NAME (intdecls) != DECL_NAME (impdecls))
3421 error_with_ivar ("conflicting instance variable name",
3422 impdecls, rawimpdecls);
3423 error_with_ivar ("previous declaration of",
3424 intdecls, rawintdecls);
3427 intdecls = TREE_CHAIN (intdecls);
3428 impdecls = TREE_CHAIN (impdecls);
3429 rawintdecls = TREE_CHAIN (rawintdecls);
3430 rawimpdecls = TREE_CHAIN (rawimpdecls);
3434 /* Set super_type to the data type node for struct objc_super *,
3435 first defining struct objc_super itself.
3436 This needs to be done just once per compilation. */
3439 build_super_template ()
3441 tree record, decl_specs, field_decl, field_decl_chain;
3443 record = start_struct (RECORD_TYPE, get_identifier (UTAG_SUPER));
3445 /* struct objc_object *self; */
3447 decl_specs = build_tree_list (NULL_TREE, objc_object_reference);
3448 field_decl = get_identifier ("self");
3449 field_decl = build1 (INDIRECT_REF, NULL_TREE, field_decl);
3450 field_decl = grokfield (input_filename, lineno,
3451 field_decl, decl_specs, NULL_TREE);
3452 field_decl_chain = field_decl;
3454 /* struct objc_class *class; */
3456 decl_specs = get_identifier (UTAG_CLASS);
3457 decl_specs = build_tree_list (NULL_TREE, xref_tag (RECORD_TYPE, decl_specs));
3458 field_decl = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("class"));
3460 field_decl = grokfield (input_filename, lineno,
3461 field_decl, decl_specs, NULL_TREE);
3462 chainon (field_decl_chain, field_decl);
3464 finish_struct (record, field_decl_chain, NULL_TREE);
3466 /* `struct objc_super *' */
3467 super_type = groktypename (build_tree_list (build_tree_list (NULL_TREE,
3469 build1 (INDIRECT_REF,
3470 NULL_TREE, NULL_TREE)));
3474 /* struct objc_ivar {
3481 build_ivar_template ()
3483 tree objc_ivar_id, objc_ivar_record;
3484 tree decl_specs, field_decl, field_decl_chain;
3486 objc_ivar_id = get_identifier (UTAG_IVAR);
3487 objc_ivar_record = start_struct (RECORD_TYPE, objc_ivar_id);
3489 /* char *ivar_name; */
3491 decl_specs = build_tree_list (NULL_TREE, ridpointers[(int) RID_CHAR]);
3492 field_decl = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("ivar_name"));
3494 field_decl = grokfield (input_filename, lineno, field_decl,
3495 decl_specs, NULL_TREE);
3496 field_decl_chain = field_decl;
3498 /* char *ivar_type; */
3500 decl_specs = build_tree_list (NULL_TREE, ridpointers[(int) RID_CHAR]);
3501 field_decl = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("ivar_type"));
3503 field_decl = grokfield (input_filename, lineno, field_decl,
3504 decl_specs, NULL_TREE);
3505 chainon (field_decl_chain, field_decl);
3507 /* int ivar_offset; */
3509 decl_specs = build_tree_list (NULL_TREE, ridpointers[(int) RID_INT]);
3510 field_decl = get_identifier ("ivar_offset");
3512 field_decl = grokfield (input_filename, lineno, field_decl,
3513 decl_specs, NULL_TREE);
3514 chainon (field_decl_chain, field_decl);
3516 finish_struct (objc_ivar_record, field_decl_chain, NULL_TREE);
3518 return objc_ivar_record;
3523 struct objc_ivar ivar_list[ivar_count];
3527 build_ivar_list_template (list_type, size)
3531 tree objc_ivar_list_record;
3532 tree decl_specs, field_decl, field_decl_chain;
3534 objc_ivar_list_record = start_struct (RECORD_TYPE, NULL_TREE);
3536 /* int ivar_count; */
3538 decl_specs = build_tree_list (NULL_TREE, ridpointers[(int) RID_INT]);
3539 field_decl = get_identifier ("ivar_count");
3541 field_decl = grokfield (input_filename, lineno, field_decl,
3542 decl_specs, NULL_TREE);
3543 field_decl_chain = field_decl;
3545 /* struct objc_ivar ivar_list[]; */
3547 decl_specs = build_tree_list (NULL_TREE, list_type);
3548 field_decl = build_nt (ARRAY_REF, get_identifier ("ivar_list"),
3549 build_int_2 (size, 0));
3551 field_decl = grokfield (input_filename, lineno,
3552 field_decl, decl_specs, NULL_TREE);
3553 chainon (field_decl_chain, field_decl);
3555 finish_struct (objc_ivar_list_record, field_decl_chain, NULL_TREE);
3557 return objc_ivar_list_record;
3563 struct objc_method method_list[method_count];
3567 build_method_list_template (list_type, size)
3571 tree objc_ivar_list_record;
3572 tree decl_specs, field_decl, field_decl_chain;
3574 objc_ivar_list_record = start_struct (RECORD_TYPE, NULL_TREE);
3576 /* int method_next; */
3581 xref_tag (RECORD_TYPE,
3582 get_identifier (UTAG_METHOD_PROTOTYPE_LIST)));
3584 = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("method_next"));
3585 field_decl = grokfield (input_filename, lineno, field_decl,
3586 decl_specs, NULL_TREE);
3587 field_decl_chain = field_decl;
3589 /* int method_count; */
3591 decl_specs = build_tree_list (NULL_TREE, ridpointers[(int) RID_INT]);
3592 field_decl = get_identifier ("method_count");
3594 field_decl = grokfield (input_filename, lineno,
3595 field_decl, decl_specs, NULL_TREE);
3596 chainon (field_decl_chain, field_decl);
3598 /* struct objc_method method_list[]; */
3600 decl_specs = build_tree_list (NULL_TREE, list_type);
3601 field_decl = build_nt (ARRAY_REF, get_identifier ("method_list"),
3602 build_int_2 (size, 0));
3604 field_decl = grokfield (input_filename, lineno,
3605 field_decl, decl_specs, NULL_TREE);
3606 chainon (field_decl_chain, field_decl);
3608 finish_struct (objc_ivar_list_record, field_decl_chain, NULL_TREE);
3610 return objc_ivar_list_record;
3614 build_ivar_list_initializer (type, field_decl)
3618 tree initlist = NULL_TREE;
3622 tree ivar = NULL_TREE;
3625 if (DECL_NAME (field_decl))
3626 ivar = tree_cons (NULL_TREE,
3627 add_objc_string (DECL_NAME (field_decl),
3631 /* Unnamed bit-field ivar (yuck). */
3632 ivar = tree_cons (NULL_TREE, build_int_2 (0, 0), ivar);
3635 encode_field_decl (field_decl,
3636 obstack_object_size (&util_obstack),
3637 OBJC_ENCODE_DONT_INLINE_DEFS);
3639 /* Null terminate string. */
3640 obstack_1grow (&util_obstack, 0);
3644 add_objc_string (get_identifier (obstack_finish (&util_obstack)),
3647 obstack_free (&util_obstack, util_firstobj);
3650 ivar = tree_cons (NULL_TREE, byte_position (field_decl), ivar);
3651 initlist = tree_cons (NULL_TREE,
3652 build_constructor (type, nreverse (ivar)),
3655 field_decl = TREE_CHAIN (field_decl);
3659 return build_constructor (build_array_type (type, 0), nreverse (initlist));
3663 generate_ivars_list (type, name, size, list)
3669 tree sc_spec, decl_specs, decl, initlist;
3671 sc_spec = tree_cons (NULL_TREE, ridpointers[(int) RID_STATIC], NULL_TREE);
3672 decl_specs = tree_cons (NULL_TREE, type, sc_spec);
3674 decl = start_decl (synth_id_with_class_suffix (name, objc_implementation_context),
3675 decl_specs, 1, NULL_TREE);
3677 initlist = build_tree_list (NULL_TREE, build_int_2 (size, 0));
3678 initlist = tree_cons (NULL_TREE, list, initlist);
3681 build_constructor (TREE_TYPE (decl), nreverse (initlist)),
3688 generate_ivar_lists ()
3690 tree initlist, ivar_list_template, chain;
3691 tree cast, variable_length_type;
3694 generating_instance_variables = 1;
3696 if (!objc_ivar_template)
3697 objc_ivar_template = build_ivar_template ();
3701 (build_tree_list (NULL_TREE, xref_tag (RECORD_TYPE,
3702 get_identifier (UTAG_IVAR_LIST))),
3704 variable_length_type = groktypename (cast);
3706 /* Only generate class variables for the root of the inheritance
3707 hierarchy since these will be the same for every class. */
3709 if (CLASS_SUPER_NAME (implementation_template) == NULL_TREE
3710 && (chain = TYPE_FIELDS (objc_class_template)))
3712 size = list_length (chain);
3714 ivar_list_template = build_ivar_list_template (objc_ivar_template, size);
3715 initlist = build_ivar_list_initializer (objc_ivar_template, chain);
3717 UOBJC_CLASS_VARIABLES_decl
3718 = generate_ivars_list (ivar_list_template, "_OBJC_CLASS_VARIABLES",
3720 TREE_TYPE (UOBJC_CLASS_VARIABLES_decl) = variable_length_type;
3723 UOBJC_CLASS_VARIABLES_decl = 0;
3725 chain = CLASS_IVARS (implementation_template);
3728 size = list_length (chain);
3729 ivar_list_template = build_ivar_list_template (objc_ivar_template, size);
3730 initlist = build_ivar_list_initializer (objc_ivar_template, chain);
3732 UOBJC_INSTANCE_VARIABLES_decl
3733 = generate_ivars_list (ivar_list_template, "_OBJC_INSTANCE_VARIABLES",
3735 TREE_TYPE (UOBJC_INSTANCE_VARIABLES_decl) = variable_length_type;
3738 UOBJC_INSTANCE_VARIABLES_decl = 0;
3740 generating_instance_variables = 0;
3744 build_dispatch_table_initializer (type, entries)
3748 tree initlist = NULL_TREE;
3752 tree elemlist = NULL_TREE;
3754 elemlist = tree_cons (NULL_TREE,
3755 build_selector (METHOD_SEL_NAME (entries)),
3758 /* Generate the method encoding if we don't have one already. */
3759 if (! METHOD_ENCODING (entries))
3760 METHOD_ENCODING (entries) =
3761 encode_method_def (METHOD_DEFINITION (entries));
3763 elemlist = tree_cons (NULL_TREE,
3764 add_objc_string (METHOD_ENCODING (entries),
3768 elemlist = tree_cons (NULL_TREE,
3769 build_unary_op (ADDR_EXPR,
3770 METHOD_DEFINITION (entries), 1),
3773 initlist = tree_cons (NULL_TREE,
3774 build_constructor (type, nreverse (elemlist)),
3777 entries = TREE_CHAIN (entries);
3781 return build_constructor (build_array_type (type, 0), nreverse (initlist));
3784 /* To accomplish method prototyping without generating all kinds of
3785 inane warnings, the definition of the dispatch table entries were
3788 struct objc_method { SEL _cmd; ...; id (*_imp)(); };
3790 struct objc_method { SEL _cmd; ...; void *_imp; }; */
3793 build_method_template ()
3796 tree decl_specs, field_decl, field_decl_chain;
3798 _SLT_record = start_struct (RECORD_TYPE, get_identifier (UTAG_METHOD));
3800 /* struct objc_selector *_cmd; */
3801 decl_specs = tree_cons (NULL_TREE,
3802 xref_tag (RECORD_TYPE,
3803 get_identifier (TAG_SELECTOR)),
3805 field_decl = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("_cmd"));
3807 field_decl = grokfield (input_filename, lineno, field_decl,
3808 decl_specs, NULL_TREE);
3809 field_decl_chain = field_decl;
3811 decl_specs = tree_cons (NULL_TREE, ridpointers[(int) RID_CHAR], NULL_TREE);
3812 field_decl = build1 (INDIRECT_REF, NULL_TREE,
3813 get_identifier ("method_types"));
3814 field_decl = grokfield (input_filename, lineno, field_decl,
3815 decl_specs, NULL_TREE);
3816 chainon (field_decl_chain, field_decl);
3820 decl_specs = tree_cons (NULL_TREE, ridpointers[(int) RID_VOID], NULL_TREE);
3821 field_decl = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("_imp"));
3822 field_decl = grokfield (input_filename, lineno, field_decl,
3823 decl_specs, NULL_TREE);
3824 chainon (field_decl_chain, field_decl);
3826 finish_struct (_SLT_record, field_decl_chain, NULL_TREE);
3833 generate_dispatch_table (type, name, size, list)
3839 tree sc_spec, decl_specs, decl, initlist;
3841 sc_spec = tree_cons (NULL_TREE, ridpointers[(int) RID_STATIC], NULL_TREE);
3842 decl_specs = tree_cons (NULL_TREE, type, sc_spec);
3844 decl = start_decl (synth_id_with_class_suffix (name, objc_implementation_context),
3845 decl_specs, 1, NULL_TREE);
3847 initlist = build_tree_list (NULL_TREE, build_int_2 (0, 0));
3848 initlist = tree_cons (NULL_TREE, build_int_2 (size, 0), initlist);
3849 initlist = tree_cons (NULL_TREE, list, initlist);
3852 build_constructor (TREE_TYPE (decl), nreverse (initlist)),
3859 generate_dispatch_tables ()
3861 tree initlist, chain, method_list_template;
3862 tree cast, variable_length_type;
3865 if (!objc_method_template)
3866 objc_method_template = build_method_template ();
3870 (build_tree_list (NULL_TREE,
3871 xref_tag (RECORD_TYPE,
3872 get_identifier (UTAG_METHOD_LIST))),
3875 variable_length_type = groktypename (cast);
3877 chain = CLASS_CLS_METHODS (objc_implementation_context);
3880 size = list_length (chain);
3882 method_list_template
3883 = build_method_list_template (objc_method_template, size);
3885 = build_dispatch_table_initializer (objc_method_template, chain);
3887 UOBJC_CLASS_METHODS_decl
3888 = generate_dispatch_table (method_list_template,
3889 ((TREE_CODE (objc_implementation_context)
3890 == CLASS_IMPLEMENTATION_TYPE)
3891 ? "_OBJC_CLASS_METHODS"
3892 : "_OBJC_CATEGORY_CLASS_METHODS"),
3894 TREE_TYPE (UOBJC_CLASS_METHODS_decl) = variable_length_type;
3897 UOBJC_CLASS_METHODS_decl = 0;
3899 chain = CLASS_NST_METHODS (objc_implementation_context);
3902 size = list_length (chain);
3904 method_list_template
3905 = build_method_list_template (objc_method_template, size);
3907 = build_dispatch_table_initializer (objc_method_template, chain);
3909 if (TREE_CODE (objc_implementation_context) == CLASS_IMPLEMENTATION_TYPE)
3910 UOBJC_INSTANCE_METHODS_decl
3911 = generate_dispatch_table (method_list_template,
3912 "_OBJC_INSTANCE_METHODS",
3915 /* We have a category. */
3916 UOBJC_INSTANCE_METHODS_decl
3917 = generate_dispatch_table (method_list_template,
3918 "_OBJC_CATEGORY_INSTANCE_METHODS",
3920 TREE_TYPE (UOBJC_INSTANCE_METHODS_decl) = variable_length_type;
3923 UOBJC_INSTANCE_METHODS_decl = 0;
3927 generate_protocol_list (i_or_p)
3930 tree initlist, decl_specs, sc_spec;
3931 tree refs_decl, expr_decl, lproto, e, plist;
3935 if (TREE_CODE (i_or_p) == CLASS_INTERFACE_TYPE
3936 || TREE_CODE (i_or_p) == CATEGORY_INTERFACE_TYPE)
3937 plist = CLASS_PROTOCOL_LIST (i_or_p);
3938 else if (TREE_CODE (i_or_p) == PROTOCOL_INTERFACE_TYPE)
3939 plist = PROTOCOL_LIST (i_or_p);
3943 cast_type = groktypename
3945 (build_tree_list (NULL_TREE,
3946 xref_tag (RECORD_TYPE,
3947 get_identifier (UTAG_PROTOCOL))),
3948 build1 (INDIRECT_REF, NULL_TREE, NULL_TREE)));
3951 for (lproto = plist; lproto; lproto = TREE_CHAIN (lproto))
3952 if (TREE_CODE (TREE_VALUE (lproto)) == PROTOCOL_INTERFACE_TYPE
3953 && PROTOCOL_FORWARD_DECL (TREE_VALUE (lproto)))
3956 /* Build initializer. */
3957 initlist = tree_cons (NULL_TREE, build_int_2 (0, 0), NULL_TREE);
3959 e = build_int_2 (size, 0);
3960 TREE_TYPE (e) = cast_type;
3961 initlist = tree_cons (NULL_TREE, e, initlist);
3963 for (lproto = plist; lproto; lproto = TREE_CHAIN (lproto))
3965 tree pval = TREE_VALUE (lproto);
3967 if (TREE_CODE (pval) == PROTOCOL_INTERFACE_TYPE
3968 && PROTOCOL_FORWARD_DECL (pval))
3970 e = build_unary_op (ADDR_EXPR, PROTOCOL_FORWARD_DECL (pval), 0);
3971 initlist = tree_cons (NULL_TREE, e, initlist);
3975 /* static struct objc_protocol *refs[n]; */
3977 sc_spec = tree_cons (NULL_TREE, ridpointers[(int) RID_STATIC], NULL_TREE);
3978 decl_specs = tree_cons (NULL_TREE, xref_tag (RECORD_TYPE,
3979 get_identifier (UTAG_PROTOCOL)),
3982 if (TREE_CODE (i_or_p) == PROTOCOL_INTERFACE_TYPE)
3983 expr_decl = build_nt (ARRAY_REF,
3984 synth_id_with_class_suffix ("_OBJC_PROTOCOL_REFS",
3986 build_int_2 (size + 2, 0));
3987 else if (TREE_CODE (i_or_p) == CLASS_INTERFACE_TYPE)
3988 expr_decl = build_nt (ARRAY_REF,
3989 synth_id_with_class_suffix ("_OBJC_CLASS_PROTOCOLS",
3991 build_int_2 (size + 2, 0));
3992 else if (TREE_CODE (i_or_p) == CATEGORY_INTERFACE_TYPE)
3994 = build_nt (ARRAY_REF,
3995 synth_id_with_class_suffix ("_OBJC_CATEGORY_PROTOCOLS",
3997 build_int_2 (size + 2, 0));
4001 expr_decl = build1 (INDIRECT_REF, NULL_TREE, expr_decl);
4003 refs_decl = start_decl (expr_decl, decl_specs, 1, NULL_TREE);
4004 DECL_CONTEXT (refs_decl) = NULL_TREE;
4006 finish_decl (refs_decl, build_constructor (TREE_TYPE (refs_decl),
4007 nreverse (initlist)),
4014 build_category_initializer (type, cat_name, class_name,
4015 instance_methods, class_methods, protocol_list)
4019 tree instance_methods;
4023 tree initlist = NULL_TREE, expr;
4025 initlist = tree_cons (NULL_TREE, cat_name, initlist);
4026 initlist = tree_cons (NULL_TREE, class_name, initlist);
4028 if (!instance_methods)
4029 initlist = tree_cons (NULL_TREE, build_int_2 (0, 0), initlist);
4032 expr = build_unary_op (ADDR_EXPR, instance_methods, 0);
4033 initlist = tree_cons (NULL_TREE, expr, initlist);
4036 initlist = tree_cons (NULL_TREE, build_int_2 (0, 0), initlist);
4039 expr = build_unary_op (ADDR_EXPR, class_methods, 0);
4040 initlist = tree_cons (NULL_TREE, expr, initlist);
4043 /* protocol_list = */
4045 initlist = tree_cons (NULL_TREE, build_int_2 (0, 0), initlist);
4048 tree cast_type2 = groktypename
4050 (build_tree_list (NULL_TREE,
4051 xref_tag (RECORD_TYPE,
4052 get_identifier (UTAG_PROTOCOL))),
4053 build1 (INDIRECT_REF, NULL_TREE,
4054 build1 (INDIRECT_REF, NULL_TREE, NULL_TREE))));
4056 expr = build_unary_op (ADDR_EXPR, protocol_list, 0);
4057 TREE_TYPE (expr) = cast_type2;
4058 initlist = tree_cons (NULL_TREE, expr, initlist);
4061 return build_constructor (type, nreverse (initlist));
4064 /* struct objc_class {
4065 struct objc_class *isa;
4066 struct objc_class *super_class;
4071 struct objc_ivar_list *ivars;
4072 struct objc_method_list *methods;
4073 if (flag_next_runtime)
4074 struct objc_cache *cache;
4076 struct sarray *dtable;
4077 struct objc_class *subclass_list;
4078 struct objc_class *sibling_class;
4080 struct objc_protocol_list *protocols;
4081 void *gc_object_type;
4085 build_shared_structure_initializer (type, isa, super, name, size, status,
4086 dispatch_table, ivar_list, protocol_list)
4093 tree dispatch_table;
4097 tree initlist = NULL_TREE, expr;
4100 initlist = tree_cons (NULL_TREE, isa, initlist);
4103 initlist = tree_cons (NULL_TREE, super, initlist);
4106 initlist = tree_cons (NULL_TREE, default_conversion (name), initlist);
4109 initlist = tree_cons (NULL_TREE, build_int_2 (0, 0), initlist);
4112 initlist = tree_cons (NULL_TREE, build_int_2 (status, 0), initlist);
4114 /* instance_size = */
4115 initlist = tree_cons (NULL_TREE, size, initlist);
4117 /* objc_ivar_list = */
4119 initlist = tree_cons (NULL_TREE, build_int_2 (0, 0), initlist);
4122 expr = build_unary_op (ADDR_EXPR, ivar_list, 0);
4123 initlist = tree_cons (NULL_TREE, expr, initlist);
4126 /* objc_method_list = */
4127 if (!dispatch_table)
4128 initlist = tree_cons (NULL_TREE, build_int_2 (0, 0), initlist);
4131 expr = build_unary_op (ADDR_EXPR, dispatch_table, 0);
4132 initlist = tree_cons (NULL_TREE, expr, initlist);
4135 if (flag_next_runtime)
4136 /* method_cache = */
4137 initlist = tree_cons (NULL_TREE, build_int_2 (0, 0), initlist);
4141 initlist = tree_cons (NULL_TREE, build_int_2 (0, 0), initlist);
4143 /* subclass_list = */
4144 initlist = tree_cons (NULL_TREE, build_int_2 (0, 0), initlist);
4146 /* sibling_class = */
4147 initlist = tree_cons (NULL_TREE, build_int_2 (0, 0), initlist);
4150 /* protocol_list = */
4151 if (! protocol_list)
4152 initlist = tree_cons (NULL_TREE, build_int_2 (0, 0), initlist);
4158 (build_tree_list (NULL_TREE,
4159 xref_tag (RECORD_TYPE,
4160 get_identifier (UTAG_PROTOCOL))),
4161 build1 (INDIRECT_REF, NULL_TREE,
4162 build1 (INDIRECT_REF, NULL_TREE, NULL_TREE))));
4164 expr = build_unary_op (ADDR_EXPR, protocol_list, 0);
4165 TREE_TYPE (expr) = cast_type2;
4166 initlist = tree_cons (NULL_TREE, expr, initlist);
4169 /* gc_object_type = NULL */
4170 initlist = tree_cons (NULL_TREE, build_int_2 (0, 0), initlist);
4172 return build_constructor (type, nreverse (initlist));
4175 /* static struct objc_category _OBJC_CATEGORY_<name> = { ... }; */
4178 generate_category (cat)
4181 tree sc_spec, decl_specs, decl;
4182 tree initlist, cat_name_expr, class_name_expr;
4183 tree protocol_decl, category;
4185 add_class_reference (CLASS_NAME (cat));
4186 cat_name_expr = add_objc_string (CLASS_SUPER_NAME (cat), class_names);
4188 class_name_expr = add_objc_string (CLASS_NAME (cat), class_names);
4190 category = CLASS_CATEGORY_LIST (implementation_template);
4192 /* find the category interface from the class it is associated with */
4195 if (CLASS_SUPER_NAME (cat) == CLASS_SUPER_NAME (category))
4197 category = CLASS_CATEGORY_LIST (category);
4200 if (category && CLASS_PROTOCOL_LIST (category))
4202 generate_protocol_references (CLASS_PROTOCOL_LIST (category));
4203 protocol_decl = generate_protocol_list (category);
4208 sc_spec = tree_cons (NULL_TREE, ridpointers[(int) RID_STATIC], NULL_TREE);
4209 decl_specs = tree_cons (NULL_TREE, objc_category_template, sc_spec);
4211 decl = start_decl (synth_id_with_class_suffix ("_OBJC_CATEGORY",
4212 objc_implementation_context),
4213 decl_specs, 1, NULL_TREE);
4215 initlist = build_category_initializer (TREE_TYPE (decl),
4216 cat_name_expr, class_name_expr,
4217 UOBJC_INSTANCE_METHODS_decl,
4218 UOBJC_CLASS_METHODS_decl,
4221 TREE_USED (decl) = 1;
4222 finish_decl (decl, initlist, NULL_TREE);
4225 /* static struct objc_class _OBJC_METACLASS_Foo={ ... };
4226 static struct objc_class _OBJC_CLASS_Foo={ ... }; */
4229 generate_shared_structures ()
4231 tree sc_spec, decl_specs, decl;
4232 tree name_expr, super_expr, root_expr;
4233 tree my_root_id = NULL_TREE, my_super_id = NULL_TREE;
4234 tree cast_type, initlist, protocol_decl;
4236 my_super_id = CLASS_SUPER_NAME (implementation_template);
4239 add_class_reference (my_super_id);
4241 /* Compute "my_root_id" - this is required for code generation.
4242 the "isa" for all meta class structures points to the root of
4243 the inheritance hierarchy (e.g. "__Object")... */
4244 my_root_id = my_super_id;
4247 tree my_root_int = lookup_interface (my_root_id);
4249 if (my_root_int && CLASS_SUPER_NAME (my_root_int))
4250 my_root_id = CLASS_SUPER_NAME (my_root_int);
4257 /* No super class. */
4258 my_root_id = CLASS_NAME (implementation_template);
4261 = groktypename (build_tree_list (build_tree_list (NULL_TREE,
4262 objc_class_template),
4263 build1 (INDIRECT_REF,
4264 NULL_TREE, NULL_TREE)));
4266 name_expr = add_objc_string (CLASS_NAME (implementation_template),
4269 /* Install class `isa' and `super' pointers at runtime. */
4272 super_expr = add_objc_string (my_super_id, class_names);
4273 super_expr = build_c_cast (cast_type, super_expr); /* cast! */
4276 super_expr = build_int_2 (0, 0);
4278 root_expr = add_objc_string (my_root_id, class_names);
4279 root_expr = build_c_cast (cast_type, root_expr); /* cast! */
4281 if (CLASS_PROTOCOL_LIST (implementation_template))
4283 generate_protocol_references
4284 (CLASS_PROTOCOL_LIST (implementation_template));
4285 protocol_decl = generate_protocol_list (implementation_template);
4290 /* static struct objc_class _OBJC_METACLASS_Foo = { ... }; */
4292 sc_spec = build_tree_list (NULL_TREE, ridpointers[(int) RID_STATIC]);
4293 decl_specs = tree_cons (NULL_TREE, objc_class_template, sc_spec);
4295 decl = start_decl (DECL_NAME (UOBJC_METACLASS_decl), decl_specs, 1,
4299 = build_shared_structure_initializer
4301 root_expr, super_expr, name_expr,
4302 convert (integer_type_node, TYPE_SIZE_UNIT (objc_class_template)),
4304 UOBJC_CLASS_METHODS_decl,
4305 UOBJC_CLASS_VARIABLES_decl,
4308 finish_decl (decl, initlist, NULL_TREE);
4310 /* static struct objc_class _OBJC_CLASS_Foo={ ... }; */
4312 decl = start_decl (DECL_NAME (UOBJC_CLASS_decl), decl_specs, 1,
4316 = build_shared_structure_initializer
4318 build_unary_op (ADDR_EXPR, UOBJC_METACLASS_decl, 0),
4319 super_expr, name_expr,
4320 convert (integer_type_node,
4321 TYPE_SIZE_UNIT (CLASS_STATIC_TEMPLATE
4322 (implementation_template))),
4324 UOBJC_INSTANCE_METHODS_decl,
4325 UOBJC_INSTANCE_VARIABLES_decl,
4328 finish_decl (decl, initlist, NULL_TREE);
4332 synth_id_with_class_suffix (preamble, ctxt)
4333 const char *preamble;
4337 if (TREE_CODE (ctxt) == CLASS_IMPLEMENTATION_TYPE
4338 || TREE_CODE (ctxt) == CLASS_INTERFACE_TYPE)
4340 const char *const class_name
4341 = IDENTIFIER_POINTER (CLASS_NAME (objc_implementation_context));
4342 string = (char *) alloca (strlen (preamble) + strlen (class_name) + 3);
4343 sprintf (string, "%s_%s", preamble,
4344 IDENTIFIER_POINTER (CLASS_NAME (ctxt)));
4346 else if (TREE_CODE (ctxt) == CATEGORY_IMPLEMENTATION_TYPE
4347 || TREE_CODE (ctxt) == CATEGORY_INTERFACE_TYPE)
4349 /* We have a category. */
4350 const char *const class_name
4351 = IDENTIFIER_POINTER (CLASS_NAME (objc_implementation_context));
4352 const char *const class_super_name
4353 = IDENTIFIER_POINTER (CLASS_SUPER_NAME (objc_implementation_context));
4354 string = (char *) alloca (strlen (preamble)
4355 + strlen (class_name)
4356 + strlen (class_super_name)
4358 sprintf (string, "%s_%s_%s", preamble, class_name, class_super_name);
4360 else if (TREE_CODE (ctxt) == PROTOCOL_INTERFACE_TYPE)
4362 const char *protocol_name = IDENTIFIER_POINTER (PROTOCOL_NAME (ctxt));
4364 = (char *) alloca (strlen (preamble) + strlen (protocol_name) + 3);
4365 sprintf (string, "%s_%s", preamble, protocol_name);
4370 return get_identifier (string);
4374 is_objc_type_qualifier (node)
4377 return (TREE_CODE (node) == IDENTIFIER_NODE
4378 && (node == ridpointers [(int) RID_CONST]
4379 || node == ridpointers [(int) RID_VOLATILE]
4380 || node == ridpointers [(int) RID_IN]
4381 || node == ridpointers [(int) RID_OUT]
4382 || node == ridpointers [(int) RID_INOUT]
4383 || node == ridpointers [(int) RID_BYCOPY]
4384 || node == ridpointers [(int) RID_BYREF]
4385 || node == ridpointers [(int) RID_ONEWAY]));
4388 /* If type is empty or only type qualifiers are present, add default
4389 type of id (otherwise grokdeclarator will default to int). */
4392 adjust_type_for_id_default (type)
4395 tree declspecs, chain;
4398 return build_tree_list (build_tree_list (NULL_TREE, objc_object_reference),
4399 build1 (INDIRECT_REF, NULL_TREE, NULL_TREE));
4401 declspecs = TREE_PURPOSE (type);
4403 /* Determine if a typespec is present. */
4404 for (chain = declspecs;
4406 chain = TREE_CHAIN (chain))
4408 if (TYPED_OBJECT (TREE_VALUE (chain))
4409 && !(TREE_VALUE (type)
4410 && TREE_CODE (TREE_VALUE (type)) == INDIRECT_REF))
4411 error ("can not use an object as parameter to a method\n");
4412 if (!is_objc_type_qualifier (TREE_VALUE (chain)))
4416 return build_tree_list (tree_cons (NULL_TREE, objc_object_reference,
4418 build1 (INDIRECT_REF, NULL_TREE, NULL_TREE));
4423 selector ':' '(' typename ')' identifier
4426 Transform an Objective-C keyword argument into
4427 the C equivalent parameter declarator.
4429 In: key_name, an "identifier_node" (optional).
4430 arg_type, a "tree_list" (optional).
4431 arg_name, an "identifier_node".
4433 Note: It would be really nice to strongly type the preceding
4434 arguments in the function prototype; however, then I
4435 could not use the "accessor" macros defined in "tree.h".
4437 Out: an instance of "keyword_decl". */
4440 build_keyword_decl (key_name, arg_type, arg_name)
4447 /* If no type is specified, default to "id". */
4448 arg_type = adjust_type_for_id_default (arg_type);
4450 keyword_decl = make_node (KEYWORD_DECL);
4452 TREE_TYPE (keyword_decl) = arg_type;
4453 KEYWORD_ARG_NAME (keyword_decl) = arg_name;
4454 KEYWORD_KEY_NAME (keyword_decl) = key_name;
4456 return keyword_decl;
4459 /* Given a chain of keyword_decl's, synthesize the full keyword selector. */
4462 build_keyword_selector (selector)
4466 tree key_chain, key_name;
4469 /* Scan the selector to see how much space we'll need. */
4470 for (key_chain = selector; key_chain; key_chain = TREE_CHAIN (key_chain))
4472 if (TREE_CODE (selector) == KEYWORD_DECL)
4473 key_name = KEYWORD_KEY_NAME (key_chain);
4474 else if (TREE_CODE (selector) == TREE_LIST)
4475 key_name = TREE_PURPOSE (key_chain);
4480 len += IDENTIFIER_LENGTH (key_name) + 1;
4482 /* Just a ':' arg. */
4486 buf = (char *) alloca (len + 1);
4487 /* Start the buffer out as an empty string. */
4490 for (key_chain = selector; key_chain; key_chain = TREE_CHAIN (key_chain))
4492 if (TREE_CODE (selector) == KEYWORD_DECL)
4493 key_name = KEYWORD_KEY_NAME (key_chain);
4494 else if (TREE_CODE (selector) == TREE_LIST)
4495 key_name = TREE_PURPOSE (key_chain);
4500 strcat (buf, IDENTIFIER_POINTER (key_name));
4504 return get_identifier (buf);
4507 /* Used for declarations and definitions. */
4510 build_method_decl (code, ret_type, selector, add_args)
4511 enum tree_code code;
4518 /* If no type is specified, default to "id". */
4519 ret_type = adjust_type_for_id_default (ret_type);
4521 method_decl = make_node (code);
4522 TREE_TYPE (method_decl) = ret_type;
4524 /* If we have a keyword selector, create an identifier_node that
4525 represents the full selector name (`:' included)... */
4526 if (TREE_CODE (selector) == KEYWORD_DECL)
4528 METHOD_SEL_NAME (method_decl) = build_keyword_selector (selector);
4529 METHOD_SEL_ARGS (method_decl) = selector;
4530 METHOD_ADD_ARGS (method_decl) = add_args;
4534 METHOD_SEL_NAME (method_decl) = selector;
4535 METHOD_SEL_ARGS (method_decl) = NULL_TREE;
4536 METHOD_ADD_ARGS (method_decl) = NULL_TREE;
4542 #define METHOD_DEF 0
4543 #define METHOD_REF 1
4545 /* Used by `build_objc_method_call' and `comp_method_types'. Return
4546 an argument list for method METH. CONTEXT is either METHOD_DEF or
4547 METHOD_REF, saying whether we are trying to define a method or call
4548 one. SUPERFLAG says this is for a send to super; this makes a
4549 difference for the NeXT calling sequence in which the lookup and
4550 the method call are done together. */
4553 get_arg_type_list (meth, context, superflag)
4560 /* Receiver type. */
4561 if (flag_next_runtime && superflag)
4562 arglist = build_tree_list (NULL_TREE, super_type);
4563 else if (context == METHOD_DEF)
4564 arglist = build_tree_list (NULL_TREE, TREE_TYPE (self_decl));
4566 arglist = build_tree_list (NULL_TREE, id_type);
4568 /* Selector type - will eventually change to `int'. */
4569 chainon (arglist, build_tree_list (NULL_TREE, selector_type));
4571 /* Build a list of argument types. */
4572 for (akey = METHOD_SEL_ARGS (meth); akey; akey = TREE_CHAIN (akey))
4574 tree arg_decl = groktypename_in_parm_context (TREE_TYPE (akey));
4575 chainon (arglist, build_tree_list (NULL_TREE, TREE_TYPE (arg_decl)));
4578 if (METHOD_ADD_ARGS (meth) == objc_ellipsis_node)
4579 /* We have a `, ...' immediately following the selector,
4580 finalize the arglist...simulate get_parm_info (0). */
4582 else if (METHOD_ADD_ARGS (meth))
4584 /* we have a variable length selector */
4585 tree add_arg_list = TREE_CHAIN (METHOD_ADD_ARGS (meth));
4586 chainon (arglist, add_arg_list);
4589 /* finalize the arglist...simulate get_parm_info (1) */
4590 chainon (arglist, build_tree_list (NULL_TREE, void_type_node));
4596 check_duplicates (hsh)
4599 tree meth = NULL_TREE;
4607 /* We have two methods with the same name and different types. */
4609 char type = (TREE_CODE (meth) == INSTANCE_METHOD_DECL) ? '-' : '+';
4611 warning ("multiple declarations for method `%s'",
4612 IDENTIFIER_POINTER (METHOD_SEL_NAME (meth)));
4614 warn_with_method ("using", type, meth);
4615 for (loop = hsh->list; loop; loop = loop->next)
4616 warn_with_method ("also found", type, loop->value);
4622 /* If RECEIVER is a class reference, return the identifier node for
4623 the referenced class. RECEIVER is created by get_class_reference,
4624 so we check the exact form created depending on which runtimes are
4628 receiver_is_class_object (receiver)
4631 tree chain, exp, arg;
4633 /* The receiver is 'self' in the context of a class method. */
4634 if (objc_method_context
4635 && receiver == self_decl
4636 && TREE_CODE (objc_method_context) == CLASS_METHOD_DECL)
4638 return CLASS_NAME (objc_implementation_context);
4641 if (flag_next_runtime)
4643 /* The receiver is a variable created by
4644 build_class_reference_decl. */
4645 if (TREE_CODE (receiver) == VAR_DECL
4646 && TREE_TYPE (receiver) == objc_class_type)
4647 /* Look up the identifier. */
4648 for (chain = cls_ref_chain; chain; chain = TREE_CHAIN (chain))
4649 if (TREE_PURPOSE (chain) == receiver)
4650 return TREE_VALUE (chain);
4654 /* The receiver is a function call that returns an id. Check if
4655 it is a call to objc_getClass, if so, pick up the class name. */
4656 if (TREE_CODE (receiver) == CALL_EXPR
4657 && (exp = TREE_OPERAND (receiver, 0))
4658 && TREE_CODE (exp) == ADDR_EXPR
4659 && (exp = TREE_OPERAND (exp, 0))
4660 && TREE_CODE (exp) == FUNCTION_DECL
4661 && exp == objc_get_class_decl
4662 /* We have a call to objc_getClass! */
4663 && (arg = TREE_OPERAND (receiver, 1))
4664 && TREE_CODE (arg) == TREE_LIST
4665 && (arg = TREE_VALUE (arg)))
4668 if (TREE_CODE (arg) == ADDR_EXPR
4669 && (arg = TREE_OPERAND (arg, 0))
4670 && TREE_CODE (arg) == STRING_CST)
4671 /* Finally, we have the class name. */
4672 return get_identifier (TREE_STRING_POINTER (arg));
4678 /* If we are currently building a message expr, this holds
4679 the identifier of the selector of the message. This is
4680 used when printing warnings about argument mismatches. */
4682 static tree current_objc_message_selector = 0;
4685 objc_message_selector ()
4687 return current_objc_message_selector;
4690 /* Construct an expression for sending a message.
4691 MESS has the object to send to in TREE_PURPOSE
4692 and the argument list (including selector) in TREE_VALUE.
4694 (*(<abstract_decl>(*)())_msg)(receiver, selTransTbl[n], ...);
4695 (*(<abstract_decl>(*)())_msgSuper)(receiver, selTransTbl[n], ...); */
4698 build_message_expr (mess)
4701 tree receiver = TREE_PURPOSE (mess);
4703 tree args = TREE_VALUE (mess);
4704 tree method_params = NULL_TREE;
4706 if (TREE_CODE (receiver) == ERROR_MARK)
4707 return error_mark_node;
4709 /* Obtain the full selector name. */
4710 if (TREE_CODE (args) == IDENTIFIER_NODE)
4711 /* A unary selector. */
4713 else if (TREE_CODE (args) == TREE_LIST)
4714 sel_name = build_keyword_selector (args);
4718 /* Build the parameter list to give to the method. */
4719 if (TREE_CODE (args) == TREE_LIST)
4721 tree chain = args, prev = NULL_TREE;
4723 /* We have a keyword selector--check for comma expressions. */
4726 tree element = TREE_VALUE (chain);
4728 /* We have a comma expression, must collapse... */
4729 if (TREE_CODE (element) == TREE_LIST)
4732 TREE_CHAIN (prev) = element;
4737 chain = TREE_CHAIN (chain);
4739 method_params = args;
4742 return finish_message_expr (receiver, sel_name, method_params);
4745 /* The 'finish_message_expr' routine is called from within
4746 'build_message_expr' for non-template functions. In the case of
4747 C++ template functions, it is called from 'build_expr_from_tree'
4748 (in decl2.c) after RECEIVER and METHOD_PARAMS have been expanded. */
4751 finish_message_expr (receiver, sel_name, method_params)
4752 tree receiver, sel_name, method_params;
4754 tree method_prototype = NULL_TREE, class_ident = NULL_TREE;
4755 tree selector, self_object, retval;
4756 int statically_typed = 0, statically_allocated = 0;
4758 /* Determine receiver type. */
4759 tree rtype = TREE_TYPE (receiver);
4760 int super = IS_SUPER (rtype);
4764 if (TREE_STATIC_TEMPLATE (rtype))
4765 statically_allocated = 1;
4766 else if (TREE_CODE (rtype) == POINTER_TYPE
4767 && TREE_STATIC_TEMPLATE (TREE_TYPE (rtype)))
4768 statically_typed = 1;
4769 else if ((flag_next_runtime
4771 && (class_ident = receiver_is_class_object (receiver)))
4773 else if (! IS_ID (rtype)
4774 /* Allow any type that matches objc_class_type. */
4775 && ! comptypes (rtype, objc_class_type))
4777 warning ("invalid receiver type `%s'",
4778 gen_declaration (rtype, errbuf));
4780 if (statically_allocated)
4781 receiver = build_unary_op (ADDR_EXPR, receiver, 0);
4783 /* Don't evaluate the receiver twice. */
4784 receiver = save_expr (receiver);
4785 self_object = receiver;
4788 /* If sending to `super', use current self as the object. */
4789 self_object = self_decl;
4791 /* Determine operation return type. */
4797 if (CLASS_SUPER_NAME (implementation_template))
4800 = lookup_interface (CLASS_SUPER_NAME (implementation_template));
4802 if (TREE_CODE (objc_method_context) == INSTANCE_METHOD_DECL)
4803 method_prototype = lookup_instance_method_static (iface, sel_name);
4805 method_prototype = lookup_class_method_static (iface, sel_name);
4807 if (iface && !method_prototype)
4808 warning ("`%s' does not respond to `%s'",
4809 IDENTIFIER_POINTER (CLASS_SUPER_NAME (implementation_template)),
4810 IDENTIFIER_POINTER (sel_name));
4814 error ("no super class declared in interface for `%s'",
4815 IDENTIFIER_POINTER (CLASS_NAME (implementation_template)));
4816 return error_mark_node;
4820 else if (statically_allocated)
4822 tree ctype = TREE_TYPE (rtype);
4823 tree iface = lookup_interface (TYPE_NAME (rtype));
4826 method_prototype = lookup_instance_method_static (iface, sel_name);
4828 if (! method_prototype && TYPE_PROTOCOL_LIST (ctype))
4830 = lookup_method_in_protocol_list (TYPE_PROTOCOL_LIST (ctype),
4833 if (!method_prototype)
4834 warning ("`%s' does not respond to `%s'",
4835 IDENTIFIER_POINTER (TYPE_NAME (rtype)),
4836 IDENTIFIER_POINTER (sel_name));
4838 else if (statically_typed)
4840 tree ctype = TREE_TYPE (rtype);
4842 /* `self' is now statically_typed. All methods should be visible
4843 within the context of the implementation. */
4844 if (objc_implementation_context
4845 && CLASS_NAME (objc_implementation_context) == TYPE_NAME (ctype))
4848 = lookup_instance_method_static (implementation_template,
4851 if (! method_prototype && TYPE_PROTOCOL_LIST (ctype))
4853 = lookup_method_in_protocol_list (TYPE_PROTOCOL_LIST (ctype),
4856 if (! method_prototype
4857 && implementation_template != objc_implementation_context)
4858 /* The method is not published in the interface. Check
4861 = lookup_method (CLASS_NST_METHODS (objc_implementation_context),
4868 if ((iface = lookup_interface (TYPE_NAME (ctype))))
4869 method_prototype = lookup_instance_method_static (iface, sel_name);
4871 if (! method_prototype)
4873 tree protocol_list = TYPE_PROTOCOL_LIST (ctype);
4876 = lookup_method_in_protocol_list (protocol_list,
4881 if (!method_prototype)
4882 warning ("`%s' does not respond to `%s'",
4883 IDENTIFIER_POINTER (TYPE_NAME (ctype)),
4884 IDENTIFIER_POINTER (sel_name));
4886 else if (class_ident)
4888 if (objc_implementation_context
4889 && CLASS_NAME (objc_implementation_context) == class_ident)
4892 = lookup_class_method_static (implementation_template, sel_name);
4894 if (!method_prototype
4895 && implementation_template != objc_implementation_context)
4896 /* The method is not published in the interface. Check
4899 = lookup_method (CLASS_CLS_METHODS (objc_implementation_context),
4906 if ((iface = lookup_interface (class_ident)))
4907 method_prototype = lookup_class_method_static (iface, sel_name);
4910 if (!method_prototype)
4912 warning ("cannot find class (factory) method");
4913 warning ("return type for `%s' defaults to id",
4914 IDENTIFIER_POINTER (sel_name));
4917 else if (IS_PROTOCOL_QUALIFIED_ID (rtype))
4919 /* An anonymous object that has been qualified with a protocol. */
4921 tree protocol_list = TYPE_PROTOCOL_LIST (rtype);
4923 method_prototype = lookup_method_in_protocol_list (protocol_list,
4926 if (!method_prototype)
4930 warning ("method `%s' not implemented by protocol",
4931 IDENTIFIER_POINTER (sel_name));
4933 /* Try and find the method signature in the global pools. */
4935 if (!(hsh = hash_lookup (nst_method_hash_list, sel_name)))
4936 hsh = hash_lookup (cls_method_hash_list, sel_name);
4938 if (!(method_prototype = check_duplicates (hsh)))
4939 warning ("return type defaults to id");
4946 /* We think we have an instance...loophole: extern id Object; */
4947 hsh = hash_lookup (nst_method_hash_list, sel_name);
4950 /* For various loopholes */
4951 hsh = hash_lookup (cls_method_hash_list, sel_name);
4953 method_prototype = check_duplicates (hsh);
4954 if (!method_prototype)
4956 warning ("cannot find method");
4957 warning ("return type for `%s' defaults to id",
4958 IDENTIFIER_POINTER (sel_name));
4962 /* Save the selector name for printing error messages. */
4963 current_objc_message_selector = sel_name;
4965 /* Build the parameters list for looking up the method.
4966 These are the object itself and the selector. */
4968 if (flag_typed_selectors)
4969 selector = build_typed_selector_reference (sel_name, method_prototype);
4971 selector = build_selector_reference (sel_name);
4973 retval = build_objc_method_call (super, method_prototype,
4974 receiver, self_object,
4975 selector, method_params);
4977 current_objc_message_selector = 0;
4982 /* Build a tree expression to send OBJECT the operation SELECTOR,
4983 looking up the method on object LOOKUP_OBJECT (often same as OBJECT),
4984 assuming the method has prototype METHOD_PROTOTYPE.
4985 (That is an INSTANCE_METHOD_DECL or CLASS_METHOD_DECL.)
4986 Use METHOD_PARAMS as list of args to pass to the method.
4987 If SUPER_FLAG is nonzero, we look up the superclass's method. */
4990 build_objc_method_call (super_flag, method_prototype, lookup_object, object,
4991 selector, method_params)
4993 tree method_prototype, lookup_object, object, selector, method_params;
4995 tree sender = (super_flag ? umsg_super_decl : umsg_decl);
4996 tree rcv_p = (super_flag
4997 ? build_pointer_type (xref_tag (RECORD_TYPE,
4998 get_identifier (TAG_SUPER)))
5001 if (flag_next_runtime)
5003 if (! method_prototype)
5005 method_params = tree_cons (NULL_TREE, lookup_object,
5006 tree_cons (NULL_TREE, selector,
5008 assemble_external (sender);
5009 return build_function_call (sender, method_params);
5013 /* This is a real kludge, but it is used only for the Next.
5014 Clobber the data type of SENDER temporarily to accept
5015 all the arguments for this operation, and to return
5016 whatever this operation returns. */
5017 tree arglist = NULL_TREE, retval, savarg, savret;
5018 tree ret_type = groktypename (TREE_TYPE (method_prototype));
5020 /* Save the proper contents of SENDER's data type. */
5021 savarg = TYPE_ARG_TYPES (TREE_TYPE (sender));
5022 savret = TREE_TYPE (TREE_TYPE (sender));
5024 /* Install this method's argument types. */
5025 arglist = get_arg_type_list (method_prototype, METHOD_REF,
5027 TYPE_ARG_TYPES (TREE_TYPE (sender)) = arglist;
5029 /* Install this method's return type. */
5030 TREE_TYPE (TREE_TYPE (sender)) = ret_type;
5032 /* Call SENDER with all the parameters. This will do type
5033 checking using the arg types for this method. */
5034 method_params = tree_cons (NULL_TREE, lookup_object,
5035 tree_cons (NULL_TREE, selector,
5037 assemble_external (sender);
5038 retval = build_function_call (sender, method_params);
5040 /* Restore SENDER's return/argument types. */
5041 TYPE_ARG_TYPES (TREE_TYPE (sender)) = savarg;
5042 TREE_TYPE (TREE_TYPE (sender)) = savret;
5048 /* This is the portable way.
5049 First call the lookup function to get a pointer to the method,
5050 then cast the pointer, then call it with the method arguments. */
5053 /* Avoid trouble since we may evaluate each of these twice. */
5054 object = save_expr (object);
5055 selector = save_expr (selector);
5057 lookup_object = build_c_cast (rcv_p, lookup_object);
5059 assemble_external (sender);
5061 = build_function_call (sender,
5062 tree_cons (NULL_TREE, lookup_object,
5063 tree_cons (NULL_TREE, selector,
5066 /* If we have a method prototype, construct the data type this
5067 method needs, and cast what we got from SENDER into a pointer
5069 if (method_prototype)
5071 tree arglist = get_arg_type_list (method_prototype, METHOD_REF,
5073 tree valtype = groktypename (TREE_TYPE (method_prototype));
5074 tree fake_function_type = build_function_type (valtype, arglist);
5075 TREE_TYPE (method) = build_pointer_type (fake_function_type);
5079 = build_pointer_type (build_function_type (ptr_type_node, NULL_TREE));
5081 /* Pass the object to the method. */
5082 assemble_external (method);
5083 return build_function_call (method,
5084 tree_cons (NULL_TREE, object,
5085 tree_cons (NULL_TREE, selector,
5091 build_protocol_reference (p)
5094 tree decl, ident, ptype;
5096 /* extern struct objc_protocol _OBJC_PROTOCOL_<mumble>; */
5098 ident = synth_id_with_class_suffix ("_OBJC_PROTOCOL", p);
5100 = groktypename (build_tree_list (build_tree_list (NULL_TREE,
5101 objc_protocol_template),
5104 if (IDENTIFIER_GLOBAL_VALUE (ident))
5105 decl = IDENTIFIER_GLOBAL_VALUE (ident); /* Set by pushdecl. */
5108 decl = build_decl (VAR_DECL, ident, ptype);
5109 DECL_EXTERNAL (decl) = 1;
5110 TREE_PUBLIC (decl) = 1;
5111 TREE_USED (decl) = 1;
5112 DECL_ARTIFICIAL (decl) = 1;
5114 make_decl_rtl (decl, 0);
5115 pushdecl_top_level (decl);
5118 PROTOCOL_FORWARD_DECL (p) = decl;
5121 /* This function is called by the parser when (and only when) a
5122 @protocol() expression is found, in order to compile it. */
5124 build_protocol_expr (protoname)
5128 tree p = lookup_protocol (protoname);
5132 error ("cannot find protocol declaration for `%s'",
5133 IDENTIFIER_POINTER (protoname));
5134 return error_mark_node;
5137 if (!PROTOCOL_FORWARD_DECL (p))
5138 build_protocol_reference (p);
5140 expr = build_unary_op (ADDR_EXPR, PROTOCOL_FORWARD_DECL (p), 0);
5142 TREE_TYPE (expr) = protocol_type;
5144 /* The @protocol() expression is being compiled into a pointer to a
5145 statically allocated instance of the Protocol class. To become
5146 usable at runtime, the 'isa' pointer of the instance need to be
5147 fixed up at runtime by the runtime library, to point to the
5148 actual 'Protocol' class. */
5150 /* For the GNU runtime, put the static Protocol instance in the list
5151 of statically allocated instances, so that we make sure that its
5152 'isa' pointer is fixed up at runtime by the GNU runtime library
5153 to point to the Protocol class (at runtime, when loading the
5154 module, the GNU runtime library loops on the statically allocated
5155 instances (as found in the defs field in objc_symtab) and fixups
5156 all the 'isa' pointers of those objects). */
5157 if (! flag_next_runtime)
5159 /* This type is a struct containing the fields of a Protocol
5160 object. (Cfr. protocol_type instead is the type of a pointer
5161 to such a struct). */
5162 tree protocol_struct_type = xref_tag
5163 (RECORD_TYPE, get_identifier (PROTOCOL_OBJECT_CLASS_NAME));
5166 /* Look for the list of Protocol statically allocated instances
5167 to fixup at runtime. Create a new list to hold Protocol
5168 statically allocated instances, if the list is not found. At
5169 present there is only another list, holding NSConstantString
5170 static instances to be fixed up at runtime. */
5171 for (chain = &objc_static_instances;
5172 *chain && TREE_VALUE (*chain) != protocol_struct_type;
5173 chain = &TREE_CHAIN (*chain));
5176 *chain = tree_cons (NULL_TREE, protocol_struct_type, NULL_TREE);
5177 add_objc_string (TYPE_NAME (protocol_struct_type),
5181 /* Add this statically allocated instance to the Protocol list. */
5182 TREE_PURPOSE (*chain) = tree_cons (NULL_TREE,
5183 PROTOCOL_FORWARD_DECL (p),
5184 TREE_PURPOSE (*chain));
5191 /* This function is called by the parser when a @selector() expression
5192 is found, in order to compile it. It is only called by the parser
5193 and only to compile a @selector(). */
5195 build_selector_expr (selnamelist)
5200 /* Obtain the full selector name. */
5201 if (TREE_CODE (selnamelist) == IDENTIFIER_NODE)
5202 /* A unary selector. */
5203 selname = selnamelist;
5204 else if (TREE_CODE (selnamelist) == TREE_LIST)
5205 selname = build_keyword_selector (selnamelist);
5209 /* If we are required to check @selector() expressions as they
5210 are found, check that the selector has been declared. */
5211 if (warn_undeclared_selector)
5213 /* Look the selector up in the list of all known class and
5214 instance methods (up to this line) to check that the selector
5218 /* First try with instance methods. */
5219 hsh = hash_lookup (nst_method_hash_list, selname);
5221 /* If not found, try with class methods. */
5224 hsh = hash_lookup (cls_method_hash_list, selname);
5227 /* If still not found, print out a warning. */
5230 warning ("undeclared selector `%s'", IDENTIFIER_POINTER (selname));
5235 if (flag_typed_selectors)
5236 return build_typed_selector_reference (selname, 0);
5238 return build_selector_reference (selname);
5242 build_encode_expr (type)
5248 encode_type (type, obstack_object_size (&util_obstack),
5249 OBJC_ENCODE_INLINE_DEFS);
5250 obstack_1grow (&util_obstack, 0); /* null terminate string */
5251 string = obstack_finish (&util_obstack);
5253 /* Synthesize a string that represents the encoded struct/union. */
5254 result = my_build_string (strlen (string) + 1, string);
5255 obstack_free (&util_obstack, util_firstobj);
5260 build_ivar_reference (id)
5263 if (TREE_CODE (objc_method_context) == CLASS_METHOD_DECL)
5265 /* Historically, a class method that produced objects (factory
5266 method) would assign `self' to the instance that it
5267 allocated. This would effectively turn the class method into
5268 an instance method. Following this assignment, the instance
5269 variables could be accessed. That practice, while safe,
5270 violates the simple rule that a class method should not refer
5271 to an instance variable. It's better to catch the cases
5272 where this is done unknowingly than to support the above
5274 warning ("instance variable `%s' accessed in class method",
5275 IDENTIFIER_POINTER (id));
5276 TREE_TYPE (self_decl) = instance_type; /* cast */
5279 return build_component_ref (build_indirect_ref (self_decl, "->"), id);
5282 /* Compute a hash value for a given method SEL_NAME. */
5285 hash_func (sel_name)
5288 const unsigned char *s
5289 = (const unsigned char *)IDENTIFIER_POINTER (sel_name);
5293 h = h * 67 + *s++ - 113;
5300 nst_method_hash_list = (hash *) ggc_calloc (SIZEHASHTABLE, sizeof (hash));
5301 cls_method_hash_list = (hash *) ggc_calloc (SIZEHASHTABLE, sizeof (hash));
5304 /* WARNING!!!! hash_enter is called with a method, and will peek
5305 inside to find its selector! But hash_lookup is given a selector
5306 directly, and looks for the selector that's inside the found
5307 entry's key (method) for comparison. */
5310 hash_enter (hashlist, method)
5315 int slot = hash_func (METHOD_SEL_NAME (method)) % SIZEHASHTABLE;
5317 obj = (hash) ggc_alloc (sizeof (struct hashed_entry));
5319 obj->next = hashlist[slot];
5322 hashlist[slot] = obj; /* append to front */
5326 hash_lookup (hashlist, sel_name)
5332 target = hashlist[hash_func (sel_name) % SIZEHASHTABLE];
5336 if (sel_name == METHOD_SEL_NAME (target->key))
5339 target = target->next;
5345 hash_add_attr (entry, value)
5351 obj = (attr) ggc_alloc (sizeof (struct hashed_attribute));
5352 obj->next = entry->list;
5355 entry->list = obj; /* append to front */
5359 lookup_method (mchain, method)
5365 if (TREE_CODE (method) == IDENTIFIER_NODE)
5368 key = METHOD_SEL_NAME (method);
5372 if (METHOD_SEL_NAME (mchain) == key)
5375 mchain = TREE_CHAIN (mchain);
5381 lookup_instance_method_static (interface, ident)
5385 tree inter = interface;
5386 tree chain = CLASS_NST_METHODS (inter);
5387 tree meth = NULL_TREE;
5391 if ((meth = lookup_method (chain, ident)))
5394 if (CLASS_CATEGORY_LIST (inter))
5396 tree category = CLASS_CATEGORY_LIST (inter);
5397 chain = CLASS_NST_METHODS (category);
5401 if ((meth = lookup_method (chain, ident)))
5404 /* Check for instance methods in protocols in categories. */
5405 if (CLASS_PROTOCOL_LIST (category))
5407 if ((meth = (lookup_method_in_protocol_list
5408 (CLASS_PROTOCOL_LIST (category), ident, 0))))
5412 if ((category = CLASS_CATEGORY_LIST (category)))
5413 chain = CLASS_NST_METHODS (category);
5418 if (CLASS_PROTOCOL_LIST (inter))
5420 if ((meth = (lookup_method_in_protocol_list
5421 (CLASS_PROTOCOL_LIST (inter), ident, 0))))
5425 if ((inter = lookup_interface (CLASS_SUPER_NAME (inter))))
5426 chain = CLASS_NST_METHODS (inter);
5434 lookup_class_method_static (interface, ident)
5438 tree inter = interface;
5439 tree chain = CLASS_CLS_METHODS (inter);
5440 tree meth = NULL_TREE;
5441 tree root_inter = NULL_TREE;
5445 if ((meth = lookup_method (chain, ident)))
5448 if (CLASS_CATEGORY_LIST (inter))
5450 tree category = CLASS_CATEGORY_LIST (inter);
5451 chain = CLASS_CLS_METHODS (category);
5455 if ((meth = lookup_method (chain, ident)))
5458 /* Check for class methods in protocols in categories. */
5459 if (CLASS_PROTOCOL_LIST (category))
5461 if ((meth = (lookup_method_in_protocol_list
5462 (CLASS_PROTOCOL_LIST (category), ident, 1))))
5466 if ((category = CLASS_CATEGORY_LIST (category)))
5467 chain = CLASS_CLS_METHODS (category);
5472 /* Check for class methods in protocols. */
5473 if (CLASS_PROTOCOL_LIST (inter))
5475 if ((meth = (lookup_method_in_protocol_list
5476 (CLASS_PROTOCOL_LIST (inter), ident, 1))))
5481 if ((inter = lookup_interface (CLASS_SUPER_NAME (inter))))
5482 chain = CLASS_CLS_METHODS (inter);
5486 /* If no class (factory) method was found, check if an _instance_
5487 method of the same name exists in the root class. This is what
5488 the Objective-C runtime will do. */
5489 return lookup_instance_method_static (root_inter, ident);
5493 add_class_method (class, method)
5500 if (!(mth = lookup_method (CLASS_CLS_METHODS (class), method)))
5502 /* put method on list in reverse order */
5503 TREE_CHAIN (method) = CLASS_CLS_METHODS (class);
5504 CLASS_CLS_METHODS (class) = method;
5508 if (TREE_CODE (class) == CLASS_IMPLEMENTATION_TYPE)
5509 error ("duplicate definition of class method `%s'",
5510 IDENTIFIER_POINTER (METHOD_SEL_NAME (mth)));
5513 /* Check types; if different, complain. */
5514 if (!comp_proto_with_proto (method, mth))
5515 error ("duplicate declaration of class method `%s'",
5516 IDENTIFIER_POINTER (METHOD_SEL_NAME (mth)));
5520 if (!(hsh = hash_lookup (cls_method_hash_list, METHOD_SEL_NAME (method))))
5522 /* Install on a global chain. */
5523 hash_enter (cls_method_hash_list, method);
5527 /* Check types; if different, add to a list. */
5528 if (!comp_proto_with_proto (method, hsh->key))
5529 hash_add_attr (hsh, method);
5535 add_instance_method (class, method)
5542 if (!(mth = lookup_method (CLASS_NST_METHODS (class), method)))
5544 /* Put method on list in reverse order. */
5545 TREE_CHAIN (method) = CLASS_NST_METHODS (class);
5546 CLASS_NST_METHODS (class) = method;
5550 if (TREE_CODE (class) == CLASS_IMPLEMENTATION_TYPE)
5551 error ("duplicate definition of instance method `%s'",
5552 IDENTIFIER_POINTER (METHOD_SEL_NAME (mth)));
5555 /* Check types; if different, complain. */
5556 if (!comp_proto_with_proto (method, mth))
5557 error ("duplicate declaration of instance method `%s'",
5558 IDENTIFIER_POINTER (METHOD_SEL_NAME (mth)));
5562 if (!(hsh = hash_lookup (nst_method_hash_list, METHOD_SEL_NAME (method))))
5564 /* Install on a global chain. */
5565 hash_enter (nst_method_hash_list, method);
5569 /* Check types; if different, add to a list. */
5570 if (!comp_proto_with_proto (method, hsh->key))
5571 hash_add_attr (hsh, method);
5580 /* Put interfaces on list in reverse order. */
5581 TREE_CHAIN (class) = interface_chain;
5582 interface_chain = class;
5583 return interface_chain;
5587 add_category (class, category)
5591 /* Put categories on list in reverse order. */
5592 tree cat = CLASS_CATEGORY_LIST (class);
5596 if (CLASS_SUPER_NAME (cat) == CLASS_SUPER_NAME (category))
5597 warning ("duplicate interface declaration for category `%s(%s)'",
5598 IDENTIFIER_POINTER (CLASS_NAME (class)),
5599 IDENTIFIER_POINTER (CLASS_SUPER_NAME (category)));
5600 cat = CLASS_CATEGORY_LIST (cat);
5603 CLASS_CATEGORY_LIST (category) = CLASS_CATEGORY_LIST (class);
5604 CLASS_CATEGORY_LIST (class) = category;
5607 /* Called after parsing each instance variable declaration. Necessary to
5608 preserve typedefs and implement public/private...
5610 PUBLIC is 1 for public, 0 for protected, and 2 for private. */
5613 add_instance_variable (class, public, declarator, declspecs, width)
5620 tree field_decl, raw_decl;
5622 raw_decl = build_tree_list (declspecs, declarator);
5624 if (CLASS_RAW_IVARS (class))
5625 chainon (CLASS_RAW_IVARS (class), raw_decl);
5627 CLASS_RAW_IVARS (class) = raw_decl;
5629 field_decl = grokfield (input_filename, lineno,
5630 declarator, declspecs, width);
5632 /* Overload the public attribute, it is not used for FIELD_DECLs. */
5636 TREE_PUBLIC (field_decl) = 0;
5637 TREE_PRIVATE (field_decl) = 0;
5638 TREE_PROTECTED (field_decl) = 1;
5642 TREE_PUBLIC (field_decl) = 1;
5643 TREE_PRIVATE (field_decl) = 0;
5644 TREE_PROTECTED (field_decl) = 0;
5648 TREE_PUBLIC (field_decl) = 0;
5649 TREE_PRIVATE (field_decl) = 1;
5650 TREE_PROTECTED (field_decl) = 0;
5655 if (CLASS_IVARS (class))
5656 chainon (CLASS_IVARS (class), field_decl);
5658 CLASS_IVARS (class) = field_decl;
5664 is_ivar (decl_chain, ident)
5668 for ( ; decl_chain; decl_chain = TREE_CHAIN (decl_chain))
5669 if (DECL_NAME (decl_chain) == ident)
5674 /* True if the ivar is private and we are not in its implementation. */
5680 if (TREE_PRIVATE (decl)
5681 && ! is_ivar (CLASS_IVARS (implementation_template), DECL_NAME (decl)))
5683 error ("instance variable `%s' is declared private",
5684 IDENTIFIER_POINTER (DECL_NAME (decl)));
5691 /* We have an instance variable reference;, check to see if it is public. */
5694 is_public (expr, identifier)
5698 tree basetype = TREE_TYPE (expr);
5699 enum tree_code code = TREE_CODE (basetype);
5702 if (code == RECORD_TYPE)
5704 if (TREE_STATIC_TEMPLATE (basetype))
5706 if (!lookup_interface (TYPE_NAME (basetype)))
5708 error ("cannot find interface declaration for `%s'",
5709 IDENTIFIER_POINTER (TYPE_NAME (basetype)));
5713 if ((decl = is_ivar (TYPE_FIELDS (basetype), identifier)))
5715 if (TREE_PUBLIC (decl))
5718 /* Important difference between the Stepstone translator:
5719 all instance variables should be public within the context
5720 of the implementation. */
5721 if (objc_implementation_context
5722 && (((TREE_CODE (objc_implementation_context)
5723 == CLASS_IMPLEMENTATION_TYPE)
5724 || (TREE_CODE (objc_implementation_context)
5725 == CATEGORY_IMPLEMENTATION_TYPE))
5726 && (CLASS_NAME (objc_implementation_context)
5727 == TYPE_NAME (basetype))))
5728 return ! is_private (decl);
5730 error ("instance variable `%s' is declared %s",
5731 IDENTIFIER_POINTER (identifier),
5732 TREE_PRIVATE (decl) ? "private" : "protected");
5737 else if (objc_implementation_context && (basetype == objc_object_reference))
5739 TREE_TYPE (expr) = uprivate_record;
5740 warning ("static access to object of type `id'");
5747 /* Make sure all entries in CHAIN are also in LIST. */
5750 check_methods (chain, list, mtype)
5759 if (!lookup_method (list, chain))
5763 if (TREE_CODE (objc_implementation_context)
5764 == CLASS_IMPLEMENTATION_TYPE)
5765 warning ("incomplete implementation of class `%s'",
5766 IDENTIFIER_POINTER (CLASS_NAME (objc_implementation_context)));
5767 else if (TREE_CODE (objc_implementation_context)
5768 == CATEGORY_IMPLEMENTATION_TYPE)
5769 warning ("incomplete implementation of category `%s'",
5770 IDENTIFIER_POINTER (CLASS_SUPER_NAME (objc_implementation_context)));
5774 warning ("method definition for `%c%s' not found",
5775 mtype, IDENTIFIER_POINTER (METHOD_SEL_NAME (chain)));
5778 chain = TREE_CHAIN (chain);
5784 /* Check if CLASS, or its superclasses, explicitly conforms to PROTOCOL. */
5787 conforms_to_protocol (class, protocol)
5791 if (TREE_CODE (protocol) == PROTOCOL_INTERFACE_TYPE)
5793 tree p = CLASS_PROTOCOL_LIST (class);
5794 while (p && TREE_VALUE (p) != protocol)
5799 tree super = (CLASS_SUPER_NAME (class)
5800 ? lookup_interface (CLASS_SUPER_NAME (class))
5802 int tmp = super ? conforms_to_protocol (super, protocol) : 0;
5811 /* Make sure all methods in CHAIN are accessible as MTYPE methods in
5812 CONTEXT. This is one of two mechanisms to check protocol integrity. */
5815 check_methods_accessible (chain, context, mtype)
5822 tree base_context = context;
5826 context = base_context;
5830 list = CLASS_CLS_METHODS (context);
5832 list = CLASS_NST_METHODS (context);
5834 if (lookup_method (list, chain))
5837 else if (TREE_CODE (context) == CLASS_IMPLEMENTATION_TYPE
5838 || TREE_CODE (context) == CLASS_INTERFACE_TYPE)
5839 context = (CLASS_SUPER_NAME (context)
5840 ? lookup_interface (CLASS_SUPER_NAME (context))
5843 else if (TREE_CODE (context) == CATEGORY_IMPLEMENTATION_TYPE
5844 || TREE_CODE (context) == CATEGORY_INTERFACE_TYPE)
5845 context = (CLASS_NAME (context)
5846 ? lookup_interface (CLASS_NAME (context))
5852 if (context == NULL_TREE)
5856 if (TREE_CODE (objc_implementation_context)
5857 == CLASS_IMPLEMENTATION_TYPE)
5858 warning ("incomplete implementation of class `%s'",
5860 (CLASS_NAME (objc_implementation_context)));
5861 else if (TREE_CODE (objc_implementation_context)
5862 == CATEGORY_IMPLEMENTATION_TYPE)
5863 warning ("incomplete implementation of category `%s'",
5865 (CLASS_SUPER_NAME (objc_implementation_context)));
5868 warning ("method definition for `%c%s' not found",
5869 mtype, IDENTIFIER_POINTER (METHOD_SEL_NAME (chain)));
5872 chain = TREE_CHAIN (chain); /* next method... */
5877 /* Check whether the current interface (accessible via
5878 'objc_implementation_context') actually implements protocol P, along
5879 with any protocols that P inherits. */
5882 check_protocol (p, type, name)
5887 if (TREE_CODE (p) == PROTOCOL_INTERFACE_TYPE)
5891 /* Ensure that all protocols have bodies! */
5894 f1 = check_methods (PROTOCOL_CLS_METHODS (p),
5895 CLASS_CLS_METHODS (objc_implementation_context),
5897 f2 = check_methods (PROTOCOL_NST_METHODS (p),
5898 CLASS_NST_METHODS (objc_implementation_context),
5903 f1 = check_methods_accessible (PROTOCOL_CLS_METHODS (p),
5904 objc_implementation_context,
5906 f2 = check_methods_accessible (PROTOCOL_NST_METHODS (p),
5907 objc_implementation_context,
5912 warning ("%s `%s' does not fully implement the `%s' protocol",
5913 type, name, IDENTIFIER_POINTER (PROTOCOL_NAME (p)));
5916 /* Check protocols recursively. */
5917 if (PROTOCOL_LIST (p))
5919 tree subs = PROTOCOL_LIST (p);
5921 lookup_interface (CLASS_SUPER_NAME (implementation_template));
5925 tree sub = TREE_VALUE (subs);
5927 /* If the superclass does not conform to the protocols
5928 inherited by P, then we must! */
5929 if (!super_class || !conforms_to_protocol (super_class, sub))
5930 check_protocol (sub, type, name);
5931 subs = TREE_CHAIN (subs);
5936 /* Check whether the current interface (accessible via
5937 'objc_implementation_context') actually implements the protocols listed
5941 check_protocols (proto_list, type, name)
5946 for ( ; proto_list; proto_list = TREE_CHAIN (proto_list))
5948 tree p = TREE_VALUE (proto_list);
5950 check_protocol (p, type, name);
5954 /* Make sure that the class CLASS_NAME is defined
5955 CODE says which kind of thing CLASS_NAME ought to be.
5956 It can be CLASS_INTERFACE_TYPE, CLASS_IMPLEMENTATION_TYPE,
5957 CATEGORY_INTERFACE_TYPE, or CATEGORY_IMPLEMENTATION_TYPE. */
5960 start_class (code, class_name, super_name, protocol_list)
5961 enum tree_code code;
5968 if (objc_implementation_context)
5970 warning ("`@end' missing in implementation context");
5971 finish_class (objc_implementation_context);
5972 objc_ivar_chain = NULL_TREE;
5973 objc_implementation_context = NULL_TREE;
5976 class = make_node (code);
5977 TYPE_BINFO (class) = make_tree_vec (6);
5979 CLASS_NAME (class) = class_name;
5980 CLASS_SUPER_NAME (class) = super_name;
5981 CLASS_CLS_METHODS (class) = NULL_TREE;
5983 if (! is_class_name (class_name) && (decl = lookup_name (class_name)))
5985 error ("`%s' redeclared as different kind of symbol",
5986 IDENTIFIER_POINTER (class_name));
5987 error_with_decl (decl, "previous declaration of `%s'");
5990 if (code == CLASS_IMPLEMENTATION_TYPE)
5995 for (chain = implemented_classes; chain; chain = TREE_CHAIN (chain))
5996 if (TREE_VALUE (chain) == class_name)
5998 error ("reimplementation of class `%s'",
5999 IDENTIFIER_POINTER (class_name));
6000 return error_mark_node;
6002 implemented_classes = tree_cons (NULL_TREE, class_name,
6003 implemented_classes);
6006 /* Pre-build the following entities - for speed/convenience. */
6008 self_id = get_identifier ("self");
6010 ucmd_id = get_identifier ("_cmd");
6013 = build_tree_list (get_identifier ("__unused__"), NULL_TREE);
6014 if (!objc_super_template)
6015 objc_super_template = build_super_template ();
6017 /* Reset for multiple classes per file. */
6020 objc_implementation_context = class;
6022 /* Lookup the interface for this implementation. */
6024 if (!(implementation_template = lookup_interface (class_name)))
6026 warning ("cannot find interface declaration for `%s'",
6027 IDENTIFIER_POINTER (class_name));
6028 add_class (implementation_template = objc_implementation_context);
6031 /* If a super class has been specified in the implementation,
6032 insure it conforms to the one specified in the interface. */
6035 && (super_name != CLASS_SUPER_NAME (implementation_template)))
6037 tree previous_name = CLASS_SUPER_NAME (implementation_template);
6038 const char *const name =
6039 previous_name ? IDENTIFIER_POINTER (previous_name) : "";
6040 error ("conflicting super class name `%s'",
6041 IDENTIFIER_POINTER (super_name));
6042 error ("previous declaration of `%s'", name);
6045 else if (! super_name)
6047 CLASS_SUPER_NAME (objc_implementation_context)
6048 = CLASS_SUPER_NAME (implementation_template);
6052 else if (code == CLASS_INTERFACE_TYPE)
6054 if (lookup_interface (class_name))
6055 warning ("duplicate interface declaration for class `%s'",
6056 IDENTIFIER_POINTER (class_name));
6061 CLASS_PROTOCOL_LIST (class)
6062 = lookup_and_install_protocols (protocol_list);
6065 else if (code == CATEGORY_INTERFACE_TYPE)
6067 tree class_category_is_assoc_with;
6069 /* For a category, class_name is really the name of the class that
6070 the following set of methods will be associated with. We must
6071 find the interface so that can derive the objects template. */
6073 if (!(class_category_is_assoc_with = lookup_interface (class_name)))
6075 error ("cannot find interface declaration for `%s'",
6076 IDENTIFIER_POINTER (class_name));
6077 exit (FATAL_EXIT_CODE);
6080 add_category (class_category_is_assoc_with, class);
6083 CLASS_PROTOCOL_LIST (class)
6084 = lookup_and_install_protocols (protocol_list);
6087 else if (code == CATEGORY_IMPLEMENTATION_TYPE)
6089 /* Pre-build the following entities for speed/convenience. */
6091 self_id = get_identifier ("self");
6093 ucmd_id = get_identifier ("_cmd");
6096 = build_tree_list (get_identifier ("__unused__"), NULL_TREE);
6097 if (!objc_super_template)
6098 objc_super_template = build_super_template ();
6100 /* Reset for multiple classes per file. */
6103 objc_implementation_context = class;
6105 /* For a category, class_name is really the name of the class that
6106 the following set of methods will be associated with. We must
6107 find the interface so that can derive the objects template. */
6109 if (!(implementation_template = lookup_interface (class_name)))
6111 error ("cannot find interface declaration for `%s'",
6112 IDENTIFIER_POINTER (class_name));
6113 exit (FATAL_EXIT_CODE);
6120 continue_class (class)
6123 if (TREE_CODE (class) == CLASS_IMPLEMENTATION_TYPE
6124 || TREE_CODE (class) == CATEGORY_IMPLEMENTATION_TYPE)
6126 struct imp_entry *imp_entry;
6129 /* Check consistency of the instance variables. */
6131 if (CLASS_IVARS (class))
6132 check_ivars (implementation_template, class);
6134 /* code generation */
6136 ivar_context = build_private_template (implementation_template);
6138 if (!objc_class_template)
6139 build_class_template ();
6141 imp_entry = (struct imp_entry *) ggc_alloc (sizeof (struct imp_entry));
6143 imp_entry->next = imp_list;
6144 imp_entry->imp_context = class;
6145 imp_entry->imp_template = implementation_template;
6147 synth_forward_declarations ();
6148 imp_entry->class_decl = UOBJC_CLASS_decl;
6149 imp_entry->meta_decl = UOBJC_METACLASS_decl;
6151 /* Append to front and increment count. */
6152 imp_list = imp_entry;
6153 if (TREE_CODE (class) == CLASS_IMPLEMENTATION_TYPE)
6158 return ivar_context;
6161 else if (TREE_CODE (class) == CLASS_INTERFACE_TYPE)
6163 tree record = xref_tag (RECORD_TYPE, CLASS_NAME (class));
6165 if (!TYPE_FIELDS (record))
6167 finish_struct (record, get_class_ivars (class), NULL_TREE);
6168 CLASS_STATIC_TEMPLATE (class) = record;
6170 /* Mark this record as a class template for static typing. */
6171 TREE_STATIC_TEMPLATE (record) = 1;
6178 return error_mark_node;
6181 /* This is called once we see the "@end" in an interface/implementation. */
6184 finish_class (class)
6187 if (TREE_CODE (class) == CLASS_IMPLEMENTATION_TYPE)
6189 /* All code generation is done in finish_objc. */
6191 if (implementation_template != objc_implementation_context)
6193 /* Ensure that all method listed in the interface contain bodies. */
6194 check_methods (CLASS_CLS_METHODS (implementation_template),
6195 CLASS_CLS_METHODS (objc_implementation_context), '+');
6196 check_methods (CLASS_NST_METHODS (implementation_template),
6197 CLASS_NST_METHODS (objc_implementation_context), '-');
6199 if (CLASS_PROTOCOL_LIST (implementation_template))
6200 check_protocols (CLASS_PROTOCOL_LIST (implementation_template),
6202 IDENTIFIER_POINTER (CLASS_NAME (objc_implementation_context)));
6206 else if (TREE_CODE (class) == CATEGORY_IMPLEMENTATION_TYPE)
6208 tree category = CLASS_CATEGORY_LIST (implementation_template);
6210 /* Find the category interface from the class it is associated with. */
6213 if (CLASS_SUPER_NAME (class) == CLASS_SUPER_NAME (category))
6215 category = CLASS_CATEGORY_LIST (category);
6220 /* Ensure all method listed in the interface contain bodies. */
6221 check_methods (CLASS_CLS_METHODS (category),
6222 CLASS_CLS_METHODS (objc_implementation_context), '+');
6223 check_methods (CLASS_NST_METHODS (category),
6224 CLASS_NST_METHODS (objc_implementation_context), '-');
6226 if (CLASS_PROTOCOL_LIST (category))
6227 check_protocols (CLASS_PROTOCOL_LIST (category),
6229 IDENTIFIER_POINTER (CLASS_SUPER_NAME (objc_implementation_context)));
6233 else if (TREE_CODE (class) == CLASS_INTERFACE_TYPE)
6236 const char *class_name = IDENTIFIER_POINTER (CLASS_NAME (class));
6237 char *string = (char *) alloca (strlen (class_name) + 3);
6239 /* extern struct objc_object *_<my_name>; */
6241 sprintf (string, "_%s", class_name);
6243 decl_specs = build_tree_list (NULL_TREE, ridpointers[(int) RID_EXTERN]);
6244 decl_specs = tree_cons (NULL_TREE, objc_object_reference, decl_specs);
6245 define_decl (build1 (INDIRECT_REF, NULL_TREE, get_identifier (string)),
6251 add_protocol (protocol)
6254 /* Put protocol on list in reverse order. */
6255 TREE_CHAIN (protocol) = protocol_chain;
6256 protocol_chain = protocol;
6257 return protocol_chain;
6261 lookup_protocol (ident)
6266 for (chain = protocol_chain; chain; chain = TREE_CHAIN (chain))
6267 if (ident == PROTOCOL_NAME (chain))
6273 /* This function forward declares the protocols named by NAMES. If
6274 they are already declared or defined, the function has no effect. */
6277 objc_declare_protocols (names)
6282 for (list = names; list; list = TREE_CHAIN (list))
6284 tree name = TREE_VALUE (list);
6286 if (lookup_protocol (name) == NULL_TREE)
6288 tree protocol = make_node (PROTOCOL_INTERFACE_TYPE);
6290 TYPE_BINFO (protocol) = make_tree_vec (2);
6291 PROTOCOL_NAME (protocol) = name;
6292 PROTOCOL_LIST (protocol) = NULL_TREE;
6293 add_protocol (protocol);
6294 PROTOCOL_DEFINED (protocol) = 0;
6295 PROTOCOL_FORWARD_DECL (protocol) = NULL_TREE;
6301 start_protocol (code, name, list)
6302 enum tree_code code;
6308 /* This is as good a place as any. Need to invoke
6309 push_tag_toplevel. */
6310 if (!objc_protocol_template)
6311 objc_protocol_template = build_protocol_template ();
6313 protocol = lookup_protocol (name);
6317 protocol = make_node (code);
6318 TYPE_BINFO (protocol) = make_tree_vec (2);
6320 PROTOCOL_NAME (protocol) = name;
6321 PROTOCOL_LIST (protocol) = lookup_and_install_protocols (list);
6322 add_protocol (protocol);
6323 PROTOCOL_DEFINED (protocol) = 1;
6324 PROTOCOL_FORWARD_DECL (protocol) = NULL_TREE;
6326 check_protocol_recursively (protocol, list);
6328 else if (! PROTOCOL_DEFINED (protocol))
6330 PROTOCOL_DEFINED (protocol) = 1;
6331 PROTOCOL_LIST (protocol) = lookup_and_install_protocols (list);
6333 check_protocol_recursively (protocol, list);
6337 warning ("duplicate declaration for protocol `%s'",
6338 IDENTIFIER_POINTER (name));
6344 finish_protocol (protocol)
6345 tree protocol ATTRIBUTE_UNUSED;
6350 /* "Encode" a data type into a string, which grows in util_obstack.
6351 ??? What is the FORMAT? Someone please document this! */
6354 encode_type_qualifiers (declspecs)
6359 for (spec = declspecs; spec; spec = TREE_CHAIN (spec))
6361 if (ridpointers[(int) RID_CONST] == TREE_VALUE (spec))
6362 obstack_1grow (&util_obstack, 'r');
6363 else if (ridpointers[(int) RID_IN] == TREE_VALUE (spec))
6364 obstack_1grow (&util_obstack, 'n');
6365 else if (ridpointers[(int) RID_INOUT] == TREE_VALUE (spec))
6366 obstack_1grow (&util_obstack, 'N');
6367 else if (ridpointers[(int) RID_OUT] == TREE_VALUE (spec))
6368 obstack_1grow (&util_obstack, 'o');
6369 else if (ridpointers[(int) RID_BYCOPY] == TREE_VALUE (spec))
6370 obstack_1grow (&util_obstack, 'O');
6371 else if (ridpointers[(int) RID_BYREF] == TREE_VALUE (spec))
6372 obstack_1grow (&util_obstack, 'R');
6373 else if (ridpointers[(int) RID_ONEWAY] == TREE_VALUE (spec))
6374 obstack_1grow (&util_obstack, 'V');
6378 /* Encode a pointer type. */
6381 encode_pointer (type, curtype, format)
6386 tree pointer_to = TREE_TYPE (type);
6388 if (TREE_CODE (pointer_to) == RECORD_TYPE)
6390 if (TYPE_NAME (pointer_to)
6391 && TREE_CODE (TYPE_NAME (pointer_to)) == IDENTIFIER_NODE)
6393 const char *name = IDENTIFIER_POINTER (TYPE_NAME (pointer_to));
6395 if (strcmp (name, TAG_OBJECT) == 0) /* '@' */
6397 obstack_1grow (&util_obstack, '@');
6400 else if (TREE_STATIC_TEMPLATE (pointer_to))
6402 if (generating_instance_variables)
6404 obstack_1grow (&util_obstack, '@');
6405 obstack_1grow (&util_obstack, '"');
6406 obstack_grow (&util_obstack, name, strlen (name));
6407 obstack_1grow (&util_obstack, '"');
6412 obstack_1grow (&util_obstack, '@');
6416 else if (strcmp (name, TAG_CLASS) == 0) /* '#' */
6418 obstack_1grow (&util_obstack, '#');
6421 else if (strcmp (name, TAG_SELECTOR) == 0) /* ':' */
6423 obstack_1grow (&util_obstack, ':');
6428 else if (TREE_CODE (pointer_to) == INTEGER_TYPE
6429 && TYPE_MODE (pointer_to) == QImode)
6431 obstack_1grow (&util_obstack, '*');
6435 /* We have a type that does not get special treatment. */
6437 /* NeXT extension */
6438 obstack_1grow (&util_obstack, '^');
6439 encode_type (pointer_to, curtype, format);
6443 encode_array (type, curtype, format)
6448 tree an_int_cst = TYPE_SIZE (type);
6449 tree array_of = TREE_TYPE (type);
6452 /* An incomplete array is treated like a pointer. */
6453 if (an_int_cst == NULL)
6455 encode_pointer (type, curtype, format);
6459 sprintf (buffer, "[%ld",
6460 (long) (TREE_INT_CST_LOW (an_int_cst)
6461 / TREE_INT_CST_LOW (TYPE_SIZE (array_of))));
6463 obstack_grow (&util_obstack, buffer, strlen (buffer));
6464 encode_type (array_of, curtype, format);
6465 obstack_1grow (&util_obstack, ']');
6470 encode_aggregate_within (type, curtype, format, left, right)
6477 /* The RECORD_TYPE may in fact be a typedef! For purposes
6478 of encoding, we need the real underlying enchilada. */
6479 if (TYPE_MAIN_VARIANT (type))
6480 type = TYPE_MAIN_VARIANT (type);
6482 if (obstack_object_size (&util_obstack) > 0
6483 && *(obstack_next_free (&util_obstack) - 1) == '^')
6485 tree name = TYPE_NAME (type);
6487 /* we have a reference; this is a NeXT extension. */
6489 if (obstack_object_size (&util_obstack) - curtype == 1
6490 && format == OBJC_ENCODE_INLINE_DEFS)
6492 /* Output format of struct for first level only. */
6493 tree fields = TYPE_FIELDS (type);
6495 if (name && TREE_CODE (name) == IDENTIFIER_NODE)
6497 obstack_1grow (&util_obstack, left);
6498 obstack_grow (&util_obstack,
6499 IDENTIFIER_POINTER (name),
6500 strlen (IDENTIFIER_POINTER (name)));
6501 obstack_1grow (&util_obstack, '=');
6505 obstack_1grow (&util_obstack, left);
6506 obstack_grow (&util_obstack, "?=", 2);
6509 for ( ; fields; fields = TREE_CHAIN (fields))
6510 encode_field_decl (fields, curtype, format);
6512 obstack_1grow (&util_obstack, right);
6515 else if (name && TREE_CODE (name) == IDENTIFIER_NODE)
6517 obstack_1grow (&util_obstack, left);
6518 obstack_grow (&util_obstack,
6519 IDENTIFIER_POINTER (name),
6520 strlen (IDENTIFIER_POINTER (name)));
6521 obstack_1grow (&util_obstack, right);
6526 /* We have an untagged structure or a typedef. */
6527 obstack_1grow (&util_obstack, left);
6528 obstack_1grow (&util_obstack, '?');
6529 obstack_1grow (&util_obstack, right);
6535 tree name = TYPE_NAME (type);
6536 tree fields = TYPE_FIELDS (type);
6538 if (format == OBJC_ENCODE_INLINE_DEFS
6539 || generating_instance_variables)
6541 obstack_1grow (&util_obstack, left);
6542 if (name && TREE_CODE (name) == IDENTIFIER_NODE)
6543 obstack_grow (&util_obstack,
6544 IDENTIFIER_POINTER (name),
6545 strlen (IDENTIFIER_POINTER (name)));
6547 obstack_1grow (&util_obstack, '?');
6549 obstack_1grow (&util_obstack, '=');
6551 for (; fields; fields = TREE_CHAIN (fields))
6553 if (generating_instance_variables)
6555 tree fname = DECL_NAME (fields);
6557 obstack_1grow (&util_obstack, '"');
6558 if (fname && TREE_CODE (fname) == IDENTIFIER_NODE)
6560 obstack_grow (&util_obstack,
6561 IDENTIFIER_POINTER (fname),
6562 strlen (IDENTIFIER_POINTER (fname)));
6565 obstack_1grow (&util_obstack, '"');
6568 encode_field_decl (fields, curtype, format);
6571 obstack_1grow (&util_obstack, right);
6576 obstack_1grow (&util_obstack, left);
6577 if (name && TREE_CODE (name) == IDENTIFIER_NODE)
6578 obstack_grow (&util_obstack,
6579 IDENTIFIER_POINTER (name),
6580 strlen (IDENTIFIER_POINTER (name)));
6582 /* We have an untagged structure or a typedef. */
6583 obstack_1grow (&util_obstack, '?');
6585 obstack_1grow (&util_obstack, right);
6591 encode_aggregate (type, curtype, format)
6596 enum tree_code code = TREE_CODE (type);
6602 encode_aggregate_within(type, curtype, format, '{', '}');
6607 encode_aggregate_within(type, curtype, format, '(', ')');
6612 obstack_1grow (&util_obstack, 'i');
6620 /* Support bitfields. The current version of Objective-C does not support
6621 them. The string will consist of one or more "b:n"'s where n is an
6622 integer describing the width of the bitfield. Currently, classes in
6623 the kit implement a method "-(char *)describeBitfieldStruct:" that
6624 simulates this. If they do not implement this method, the archiver
6625 assumes the bitfield is 16 bits wide (padded if necessary) and packed
6626 according to the GNU compiler. After looking at the "kit", it appears
6627 that all classes currently rely on this default behavior, rather than
6628 hand generating this string (which is tedious). */
6631 encode_bitfield (width)
6635 sprintf (buffer, "b%d", width);
6636 obstack_grow (&util_obstack, buffer, strlen (buffer));
6639 /* FORMAT will be OBJC_ENCODE_INLINE_DEFS or OBJC_ENCODE_DONT_INLINE_DEFS. */
6642 encode_type (type, curtype, format)
6647 enum tree_code code = TREE_CODE (type);
6649 if (code == INTEGER_TYPE)
6651 if (integer_zerop (TYPE_MIN_VALUE (type)))
6653 /* Unsigned integer types. */
6655 if (TYPE_MODE (type) == QImode)
6656 obstack_1grow (&util_obstack, 'C');
6657 else if (TYPE_MODE (type) == HImode)
6658 obstack_1grow (&util_obstack, 'S');
6659 else if (TYPE_MODE (type) == SImode)
6661 if (type == long_unsigned_type_node)
6662 obstack_1grow (&util_obstack, 'L');
6664 obstack_1grow (&util_obstack, 'I');
6666 else if (TYPE_MODE (type) == DImode)
6667 obstack_1grow (&util_obstack, 'Q');
6671 /* Signed integer types. */
6673 if (TYPE_MODE (type) == QImode)
6674 obstack_1grow (&util_obstack, 'c');
6675 else if (TYPE_MODE (type) == HImode)
6676 obstack_1grow (&util_obstack, 's');
6677 else if (TYPE_MODE (type) == SImode)
6679 if (type == long_integer_type_node)
6680 obstack_1grow (&util_obstack, 'l');
6682 obstack_1grow (&util_obstack, 'i');
6685 else if (TYPE_MODE (type) == DImode)
6686 obstack_1grow (&util_obstack, 'q');
6690 else if (code == REAL_TYPE)
6692 /* Floating point types. */
6694 if (TYPE_MODE (type) == SFmode)
6695 obstack_1grow (&util_obstack, 'f');
6696 else if (TYPE_MODE (type) == DFmode
6697 || TYPE_MODE (type) == TFmode)
6698 obstack_1grow (&util_obstack, 'd');
6701 else if (code == VOID_TYPE)
6702 obstack_1grow (&util_obstack, 'v');
6704 else if (code == ARRAY_TYPE)
6705 encode_array (type, curtype, format);
6707 else if (code == POINTER_TYPE)
6708 encode_pointer (type, curtype, format);
6710 else if (code == RECORD_TYPE || code == UNION_TYPE || code == ENUMERAL_TYPE)
6711 encode_aggregate (type, curtype, format);
6713 else if (code == FUNCTION_TYPE) /* '?' */
6714 obstack_1grow (&util_obstack, '?');
6718 encode_complete_bitfield (position, type, size)
6723 enum tree_code code = TREE_CODE (type);
6725 char charType = '?';
6727 if (code == INTEGER_TYPE)
6729 if (integer_zerop (TYPE_MIN_VALUE (type)))
6731 /* Unsigned integer types. */
6733 if (TYPE_MODE (type) == QImode)
6735 else if (TYPE_MODE (type) == HImode)
6737 else if (TYPE_MODE (type) == SImode)
6739 if (type == long_unsigned_type_node)
6744 else if (TYPE_MODE (type) == DImode)
6749 /* Signed integer types. */
6751 if (TYPE_MODE (type) == QImode)
6753 else if (TYPE_MODE (type) == HImode)
6755 else if (TYPE_MODE (type) == SImode)
6757 if (type == long_integer_type_node)
6763 else if (TYPE_MODE (type) == DImode)
6767 else if (code == ENUMERAL_TYPE)
6772 sprintf (buffer, "b%d%c%d", position, charType, size);
6773 obstack_grow (&util_obstack, buffer, strlen (buffer));
6777 encode_field_decl (field_decl, curtype, format)
6784 type = TREE_TYPE (field_decl);
6786 /* If this field is obviously a bitfield, or is a bitfield that has been
6787 clobbered to look like a ordinary integer mode, go ahead and generate
6788 the bitfield typing information. */
6789 if (flag_next_runtime)
6791 if (DECL_BIT_FIELD_TYPE (field_decl))
6792 encode_bitfield (tree_low_cst (DECL_SIZE (field_decl), 1));
6794 encode_type (TREE_TYPE (field_decl), curtype, format);
6798 if (DECL_BIT_FIELD_TYPE (field_decl))
6799 encode_complete_bitfield (int_bit_position (field_decl),
6800 DECL_BIT_FIELD_TYPE (field_decl),
6801 tree_low_cst (DECL_SIZE (field_decl), 1));
6803 encode_type (TREE_TYPE (field_decl), curtype, format);
6808 expr_last (complex_expr)
6814 while ((next = TREE_OPERAND (complex_expr, 0)))
6815 complex_expr = next;
6817 return complex_expr;
6820 /* Transform a method definition into a function definition as follows:
6821 - synthesize the first two arguments, "self" and "_cmd". */
6824 start_method_def (method)
6829 /* Required to implement _msgSuper. */
6830 objc_method_context = method;
6831 UOBJC_SUPER_decl = NULL_TREE;
6833 /* Must be called BEFORE start_function. */
6836 /* Generate prototype declarations for arguments..."new-style". */
6838 if (TREE_CODE (objc_method_context) == INSTANCE_METHOD_DECL)
6839 decl_specs = build_tree_list (NULL_TREE, uprivate_record);
6841 /* Really a `struct objc_class *'. However, we allow people to
6842 assign to self, which changes its type midstream. */
6843 decl_specs = build_tree_list (NULL_TREE, objc_object_reference);
6845 push_parm_decl (build_tree_list
6846 (build_tree_list (decl_specs,
6847 build1 (INDIRECT_REF, NULL_TREE, self_id)),
6850 decl_specs = build_tree_list (NULL_TREE,
6851 xref_tag (RECORD_TYPE,
6852 get_identifier (TAG_SELECTOR)));
6853 push_parm_decl (build_tree_list
6854 (build_tree_list (decl_specs,
6855 build1 (INDIRECT_REF, NULL_TREE, ucmd_id)),
6858 /* Generate argument declarations if a keyword_decl. */
6859 if (METHOD_SEL_ARGS (method))
6861 tree arglist = METHOD_SEL_ARGS (method);
6864 tree arg_spec = TREE_PURPOSE (TREE_TYPE (arglist));
6865 tree arg_decl = TREE_VALUE (TREE_TYPE (arglist));
6869 tree last_expr = expr_last (arg_decl);
6871 /* Unite the abstract decl with its name. */
6872 TREE_OPERAND (last_expr, 0) = KEYWORD_ARG_NAME (arglist);
6873 push_parm_decl (build_tree_list
6874 (build_tree_list (arg_spec, arg_decl),
6877 /* Unhook: restore the abstract declarator. */
6878 TREE_OPERAND (last_expr, 0) = NULL_TREE;
6882 push_parm_decl (build_tree_list
6883 (build_tree_list (arg_spec,
6884 KEYWORD_ARG_NAME (arglist)),
6887 arglist = TREE_CHAIN (arglist);
6892 if (METHOD_ADD_ARGS (method) != NULL_TREE
6893 && METHOD_ADD_ARGS (method) != objc_ellipsis_node)
6895 /* We have a variable length selector - in "prototype" format. */
6896 tree akey = TREE_PURPOSE (METHOD_ADD_ARGS (method));
6899 /* This must be done prior to calling pushdecl. pushdecl is
6900 going to change our chain on us. */
6901 tree nextkey = TREE_CHAIN (akey);
6909 warn_with_method (message, mtype, method)
6910 const char *message;
6914 if (!diagnostic_count_diagnostic (global_dc, DK_WARNING))
6917 diagnostic_report_current_function (global_dc);
6919 /* Add a readable method name to the warning. */
6920 warning_with_file_and_line (DECL_SOURCE_FILE (method),
6921 DECL_SOURCE_LINE (method),
6924 gen_method_decl (method, errbuf));
6927 /* Return 1 if METHOD is consistent with PROTO. */
6930 comp_method_with_proto (method, proto)
6933 /* Create a function template node at most once. */
6934 if (!function1_template)
6935 function1_template = make_node (FUNCTION_TYPE);
6937 /* Install argument types - normally set by build_function_type. */
6938 TYPE_ARG_TYPES (function1_template) = get_arg_type_list (proto, METHOD_DEF, 0);
6940 /* install return type */
6941 TREE_TYPE (function1_template) = groktypename (TREE_TYPE (proto));
6943 return comptypes (TREE_TYPE (METHOD_DEFINITION (method)), function1_template);
6946 /* Return 1 if PROTO1 is consistent with PROTO2. */
6949 comp_proto_with_proto (proto0, proto1)
6950 tree proto0, proto1;
6952 /* Create a couple of function_template nodes at most once. */
6953 if (!function1_template)
6954 function1_template = make_node (FUNCTION_TYPE);
6955 if (!function2_template)
6956 function2_template = make_node (FUNCTION_TYPE);
6958 /* Install argument types; normally set by build_function_type. */
6959 TYPE_ARG_TYPES (function1_template) = get_arg_type_list (proto0, METHOD_REF, 0);
6960 TYPE_ARG_TYPES (function2_template) = get_arg_type_list (proto1, METHOD_REF, 0);
6962 /* Install return type. */
6963 TREE_TYPE (function1_template) = groktypename (TREE_TYPE (proto0));
6964 TREE_TYPE (function2_template) = groktypename (TREE_TYPE (proto1));
6966 return comptypes (function1_template, function2_template);
6969 /* - Generate an identifier for the function. the format is "_n_cls",
6970 where 1 <= n <= nMethods, and cls is the name the implementation we
6972 - Install the return type from the method declaration.
6973 - If we have a prototype, check for type consistency. */
6976 really_start_method (method, parmlist)
6977 tree method, parmlist;
6979 tree sc_spec, ret_spec, ret_decl, decl_specs;
6980 tree method_decl, method_id;
6981 const char *sel_name, *class_name, *cat_name;
6984 /* Synth the storage class & assemble the return type. */
6985 sc_spec = tree_cons (NULL_TREE, ridpointers[(int) RID_STATIC], NULL_TREE);
6986 ret_spec = TREE_PURPOSE (TREE_TYPE (method));
6987 decl_specs = chainon (sc_spec, ret_spec);
6989 sel_name = IDENTIFIER_POINTER (METHOD_SEL_NAME (method));
6990 class_name = IDENTIFIER_POINTER (CLASS_NAME (objc_implementation_context));
6991 cat_name = ((TREE_CODE (objc_implementation_context)
6992 == CLASS_IMPLEMENTATION_TYPE)
6994 : IDENTIFIER_POINTER (CLASS_SUPER_NAME (objc_implementation_context)));
6997 /* Make sure this is big enough for any plausible method label. */
6998 buf = (char *) alloca (50 + strlen (sel_name) + strlen (class_name)
6999 + (cat_name ? strlen (cat_name) : 0));
7001 OBJC_GEN_METHOD_LABEL (buf, TREE_CODE (method) == INSTANCE_METHOD_DECL,
7002 class_name, cat_name, sel_name, method_slot);
7004 method_id = get_identifier (buf);
7006 method_decl = build_nt (CALL_EXPR, method_id, parmlist, NULL_TREE);
7008 /* Check the declarator portion of the return type for the method. */
7009 if ((ret_decl = TREE_VALUE (TREE_TYPE (method))))
7011 /* Unite the complex decl (specified in the abstract decl) with the
7012 function decl just synthesized..(int *), (int (*)()), (int (*)[]). */
7013 tree save_expr = expr_last (ret_decl);
7015 TREE_OPERAND (save_expr, 0) = method_decl;
7016 method_decl = ret_decl;
7018 /* Fool the parser into thinking it is starting a function. */
7019 start_function (decl_specs, method_decl, NULL_TREE);
7021 /* Unhook: this has the effect of restoring the abstract declarator. */
7022 TREE_OPERAND (save_expr, 0) = NULL_TREE;
7027 TREE_VALUE (TREE_TYPE (method)) = method_decl;
7029 /* Fool the parser into thinking it is starting a function. */
7030 start_function (decl_specs, method_decl, NULL_TREE);
7032 /* Unhook: this has the effect of restoring the abstract declarator. */
7033 TREE_VALUE (TREE_TYPE (method)) = NULL_TREE;
7036 METHOD_DEFINITION (method) = current_function_decl;
7038 /* Check consistency...start_function, pushdecl, duplicate_decls. */
7040 if (implementation_template != objc_implementation_context)
7044 if (TREE_CODE (method) == INSTANCE_METHOD_DECL)
7045 proto = lookup_instance_method_static (implementation_template,
7046 METHOD_SEL_NAME (method));
7048 proto = lookup_class_method_static (implementation_template,
7049 METHOD_SEL_NAME (method));
7051 if (proto && ! comp_method_with_proto (method, proto))
7053 char type = (TREE_CODE (method) == INSTANCE_METHOD_DECL ? '-' : '+');
7055 warn_with_method ("conflicting types for", type, method);
7056 warn_with_method ("previous declaration of", type, proto);
7061 /* The following routine is always called...this "architecture" is to
7062 accommodate "old-style" variable length selectors.
7064 - a:a b:b // prototype ; id c; id d; // old-style. */
7067 continue_method_def ()
7071 if (METHOD_ADD_ARGS (objc_method_context) == objc_ellipsis_node)
7072 /* We have a `, ...' immediately following the selector. */
7073 parmlist = get_parm_info (0);
7075 parmlist = get_parm_info (1); /* place a `void_at_end' */
7077 /* Set self_decl from the first argument...this global is used by
7078 build_ivar_reference calling build_indirect_ref. */
7079 self_decl = TREE_PURPOSE (parmlist);
7082 really_start_method (objc_method_context, parmlist);
7083 store_parm_decls ();
7086 /* Called by the parser, from the `pushlevel' production. */
7091 if (!UOBJC_SUPER_decl)
7093 UOBJC_SUPER_decl = start_decl (get_identifier (UTAG_SUPER),
7094 build_tree_list (NULL_TREE,
7095 objc_super_template),
7098 finish_decl (UOBJC_SUPER_decl, NULL_TREE, NULL_TREE);
7100 /* This prevents `unused variable' warnings when compiling with -Wall. */
7101 TREE_USED (UOBJC_SUPER_decl) = 1;
7102 DECL_ARTIFICIAL (UOBJC_SUPER_decl) = 1;
7106 /* _n_Method (id self, SEL sel, ...)
7108 struct objc_super _S;
7109 _msgSuper ((_S.self = self, _S.class = _cls, &_S), ...);
7113 get_super_receiver ()
7115 if (objc_method_context)
7117 tree super_expr, super_expr_list;
7119 /* Set receiver to self. */
7120 super_expr = build_component_ref (UOBJC_SUPER_decl, self_id);
7121 super_expr = build_modify_expr (super_expr, NOP_EXPR, self_decl);
7122 super_expr_list = build_tree_list (NULL_TREE, super_expr);
7124 /* Set class to begin searching. */
7125 super_expr = build_component_ref (UOBJC_SUPER_decl,
7126 get_identifier ("class"));
7128 if (TREE_CODE (objc_implementation_context) == CLASS_IMPLEMENTATION_TYPE)
7130 /* [_cls, __cls]Super are "pre-built" in
7131 synth_forward_declarations. */
7133 super_expr = build_modify_expr (super_expr, NOP_EXPR,
7134 ((TREE_CODE (objc_method_context)
7135 == INSTANCE_METHOD_DECL)
7137 : uucls_super_ref));
7141 /* We have a category. */
7143 tree super_name = CLASS_SUPER_NAME (implementation_template);
7146 /* Barf if super used in a category of Object. */
7149 error ("no super class declared in interface for `%s'",
7150 IDENTIFIER_POINTER (CLASS_NAME (implementation_template)));
7151 return error_mark_node;
7154 if (flag_next_runtime)
7156 super_class = get_class_reference (super_name);
7157 if (TREE_CODE (objc_method_context) == CLASS_METHOD_DECL)
7158 /* Cast the super class to 'id', since the user may not have
7159 included <objc/objc-class.h>, leaving 'struct objc_class'
7160 an incomplete type. */
7162 = build_component_ref (build_indirect_ref
7163 (build_c_cast (id_type, super_class), "->"),
7164 get_identifier ("isa"));
7168 add_class_reference (super_name);
7169 super_class = (TREE_CODE (objc_method_context) == INSTANCE_METHOD_DECL
7170 ? objc_get_class_decl : objc_get_meta_class_decl);
7171 assemble_external (super_class);
7173 = build_function_call
7177 my_build_string (IDENTIFIER_LENGTH (super_name) + 1,
7178 IDENTIFIER_POINTER (super_name))));
7181 TREE_TYPE (super_class) = TREE_TYPE (ucls_super_ref);
7182 super_expr = build_modify_expr (super_expr, NOP_EXPR, super_class);
7185 chainon (super_expr_list, build_tree_list (NULL_TREE, super_expr));
7187 super_expr = build_unary_op (ADDR_EXPR, UOBJC_SUPER_decl, 0);
7188 chainon (super_expr_list, build_tree_list (NULL_TREE, super_expr));
7190 return build_compound_expr (super_expr_list);
7194 error ("[super ...] must appear in a method context");
7195 return error_mark_node;
7200 encode_method_def (func_decl)
7205 HOST_WIDE_INT max_parm_end = 0;
7210 encode_type (TREE_TYPE (TREE_TYPE (func_decl)),
7211 obstack_object_size (&util_obstack),
7212 OBJC_ENCODE_INLINE_DEFS);
7215 for (parms = DECL_ARGUMENTS (func_decl); parms;
7216 parms = TREE_CHAIN (parms))
7218 HOST_WIDE_INT parm_end = (forwarding_offset (parms)
7219 + int_size_in_bytes (TREE_TYPE (parms)));
7221 if (! offset_is_register && parm_end > max_parm_end)
7222 max_parm_end = parm_end;
7225 stack_size = max_parm_end - OBJC_FORWARDING_MIN_OFFSET;
7227 sprintf (buffer, "%d", stack_size);
7228 obstack_grow (&util_obstack, buffer, strlen (buffer));
7230 /* Argument types. */
7231 for (parms = DECL_ARGUMENTS (func_decl); parms;
7232 parms = TREE_CHAIN (parms))
7235 encode_type (TREE_TYPE (parms),
7236 obstack_object_size (&util_obstack),
7237 OBJC_ENCODE_INLINE_DEFS);
7239 /* Compute offset. */
7240 sprintf (buffer, "%d", forwarding_offset (parms));
7242 /* Indicate register. */
7243 if (offset_is_register)
7244 obstack_1grow (&util_obstack, '+');
7246 obstack_grow (&util_obstack, buffer, strlen (buffer));
7249 /* Null terminate string. */
7250 obstack_1grow (&util_obstack, 0);
7251 result = get_identifier (obstack_finish (&util_obstack));
7252 obstack_free (&util_obstack, util_firstobj);
7257 objc_expand_function_end ()
7259 METHOD_ENCODING (objc_method_context) = encode_method_def (current_function_decl);
7263 finish_method_def ()
7265 lang_expand_function_end = objc_expand_function_end;
7266 finish_function (0, 1);
7267 lang_expand_function_end = NULL;
7269 /* Required to implement _msgSuper. This must be done AFTER finish_function,
7270 since the optimizer may find "may be used before set" errors. */
7271 objc_method_context = NULL_TREE;
7276 lang_report_error_function (decl)
7279 if (objc_method_context)
7281 fprintf (stderr, "In method `%s'\n",
7282 IDENTIFIER_POINTER (METHOD_SEL_NAME (objc_method_context)));
7292 is_complex_decl (type)
7295 return (TREE_CODE (type) == ARRAY_TYPE
7296 || TREE_CODE (type) == FUNCTION_TYPE
7297 || (TREE_CODE (type) == POINTER_TYPE && ! IS_ID (type)));
7301 /* Code to convert a decl node into text for a declaration in C. */
7303 static char tmpbuf[256];
7306 adorn_decl (decl, str)
7310 enum tree_code code = TREE_CODE (decl);
7312 if (code == ARRAY_REF)
7314 tree an_int_cst = TREE_OPERAND (decl, 1);
7316 if (an_int_cst && TREE_CODE (an_int_cst) == INTEGER_CST)
7317 sprintf (str + strlen (str), "[%ld]",
7318 (long) TREE_INT_CST_LOW (an_int_cst));
7323 else if (code == ARRAY_TYPE)
7325 tree an_int_cst = TYPE_SIZE (decl);
7326 tree array_of = TREE_TYPE (decl);
7328 if (an_int_cst && TREE_CODE (an_int_cst) == INTEGER_TYPE)
7329 sprintf (str + strlen (str), "[%ld]",
7330 (long) (TREE_INT_CST_LOW (an_int_cst)
7331 / TREE_INT_CST_LOW (TYPE_SIZE (array_of))));
7336 else if (code == CALL_EXPR)
7338 tree chain = TREE_PURPOSE (TREE_OPERAND (decl, 1));
7343 gen_declaration_1 (chain, str);
7344 chain = TREE_CHAIN (chain);
7351 else if (code == FUNCTION_TYPE)
7353 tree chain = TYPE_ARG_TYPES (decl);
7356 while (chain && TREE_VALUE (chain) != void_type_node)
7358 gen_declaration_1 (TREE_VALUE (chain), str);
7359 chain = TREE_CHAIN (chain);
7360 if (chain && TREE_VALUE (chain) != void_type_node)
7366 else if (code == INDIRECT_REF)
7368 strcpy (tmpbuf, "*");
7369 if (TREE_TYPE (decl) && TREE_CODE (TREE_TYPE (decl)) == TREE_LIST)
7373 for (chain = nreverse (copy_list (TREE_TYPE (decl)));
7375 chain = TREE_CHAIN (chain))
7377 if (TREE_CODE (TREE_VALUE (chain)) == IDENTIFIER_NODE)
7379 strcat (tmpbuf, " ");
7380 strcat (tmpbuf, IDENTIFIER_POINTER (TREE_VALUE (chain)));
7384 strcat (tmpbuf, " ");
7386 strcat (tmpbuf, str);
7387 strcpy (str, tmpbuf);
7390 else if (code == POINTER_TYPE)
7392 strcpy (tmpbuf, "*");
7393 if (TREE_READONLY (decl) || TYPE_VOLATILE (decl))
7395 if (TREE_READONLY (decl))
7396 strcat (tmpbuf, " const");
7397 if (TYPE_VOLATILE (decl))
7398 strcat (tmpbuf, " volatile");
7400 strcat (tmpbuf, " ");
7402 strcat (tmpbuf, str);
7403 strcpy (str, tmpbuf);
7408 gen_declarator (decl, buf, name)
7415 enum tree_code code = TREE_CODE (decl);
7425 op = TREE_OPERAND (decl, 0);
7427 /* We have a pointer to a function or array...(*)(), (*)[] */
7428 if ((code == ARRAY_REF || code == CALL_EXPR)
7429 && op && TREE_CODE (op) == INDIRECT_REF)
7432 str = gen_declarator (op, buf, name);
7436 strcpy (tmpbuf, "(");
7437 strcat (tmpbuf, str);
7438 strcat (tmpbuf, ")");
7439 strcpy (str, tmpbuf);
7442 adorn_decl (decl, str);
7451 /* This clause is done iteratively rather than recursively. */
7454 op = (is_complex_decl (TREE_TYPE (decl))
7455 ? TREE_TYPE (decl) : NULL_TREE);
7457 adorn_decl (decl, str);
7459 /* We have a pointer to a function or array...(*)(), (*)[] */
7460 if (code == POINTER_TYPE
7461 && op && (TREE_CODE (op) == FUNCTION_TYPE
7462 || TREE_CODE (op) == ARRAY_TYPE))
7464 strcpy (tmpbuf, "(");
7465 strcat (tmpbuf, str);
7466 strcat (tmpbuf, ")");
7467 strcpy (str, tmpbuf);
7470 decl = (is_complex_decl (TREE_TYPE (decl))
7471 ? TREE_TYPE (decl) : NULL_TREE);
7474 while (decl && (code = TREE_CODE (decl)))
7479 case IDENTIFIER_NODE:
7480 /* Will only happen if we are processing a "raw" expr-decl. */
7481 strcpy (buf, IDENTIFIER_POINTER (decl));
7492 /* We have an abstract declarator or a _DECL node. */
7500 gen_declspecs (declspecs, buf, raw)
7509 for (chain = nreverse (copy_list (declspecs));
7510 chain; chain = TREE_CHAIN (chain))
7512 tree aspec = TREE_VALUE (chain);
7514 if (TREE_CODE (aspec) == IDENTIFIER_NODE)
7515 strcat (buf, IDENTIFIER_POINTER (aspec));
7516 else if (TREE_CODE (aspec) == RECORD_TYPE)
7518 if (TYPE_NAME (aspec))
7520 tree protocol_list = TYPE_PROTOCOL_LIST (aspec);
7522 if (! TREE_STATIC_TEMPLATE (aspec))
7523 strcat (buf, "struct ");
7524 strcat (buf, IDENTIFIER_POINTER (TYPE_NAME (aspec)));
7529 tree chain = protocol_list;
7536 (PROTOCOL_NAME (TREE_VALUE (chain))));
7537 chain = TREE_CHAIN (chain);
7546 strcat (buf, "untagged struct");
7549 else if (TREE_CODE (aspec) == UNION_TYPE)
7551 if (TYPE_NAME (aspec))
7553 if (! TREE_STATIC_TEMPLATE (aspec))
7554 strcat (buf, "union ");
7555 strcat (buf, IDENTIFIER_POINTER (TYPE_NAME (aspec)));
7558 strcat (buf, "untagged union");
7561 else if (TREE_CODE (aspec) == ENUMERAL_TYPE)
7563 if (TYPE_NAME (aspec))
7565 if (! TREE_STATIC_TEMPLATE (aspec))
7566 strcat (buf, "enum ");
7567 strcat (buf, IDENTIFIER_POINTER (TYPE_NAME (aspec)));
7570 strcat (buf, "untagged enum");
7573 else if (TREE_CODE (aspec) == TYPE_DECL && DECL_NAME (aspec))
7574 strcat (buf, IDENTIFIER_POINTER (DECL_NAME (aspec)));
7576 else if (IS_ID (aspec))
7578 tree protocol_list = TYPE_PROTOCOL_LIST (aspec);
7583 tree chain = protocol_list;
7590 (PROTOCOL_NAME (TREE_VALUE (chain))));
7591 chain = TREE_CHAIN (chain);
7598 if (TREE_CHAIN (chain))
7604 /* Type qualifiers. */
7605 if (TREE_READONLY (declspecs))
7606 strcat (buf, "const ");
7607 if (TYPE_VOLATILE (declspecs))
7608 strcat (buf, "volatile ");
7610 switch (TREE_CODE (declspecs))
7612 /* Type specifiers. */
7615 declspecs = TYPE_MAIN_VARIANT (declspecs);
7617 /* Signed integer types. */
7619 if (declspecs == short_integer_type_node)
7620 strcat (buf, "short int ");
7621 else if (declspecs == integer_type_node)
7622 strcat (buf, "int ");
7623 else if (declspecs == long_integer_type_node)
7624 strcat (buf, "long int ");
7625 else if (declspecs == long_long_integer_type_node)
7626 strcat (buf, "long long int ");
7627 else if (declspecs == signed_char_type_node
7628 || declspecs == char_type_node)
7629 strcat (buf, "char ");
7631 /* Unsigned integer types. */
7633 else if (declspecs == short_unsigned_type_node)
7634 strcat (buf, "unsigned short ");
7635 else if (declspecs == unsigned_type_node)
7636 strcat (buf, "unsigned int ");
7637 else if (declspecs == long_unsigned_type_node)
7638 strcat (buf, "unsigned long ");
7639 else if (declspecs == long_long_unsigned_type_node)
7640 strcat (buf, "unsigned long long ");
7641 else if (declspecs == unsigned_char_type_node)
7642 strcat (buf, "unsigned char ");
7646 declspecs = TYPE_MAIN_VARIANT (declspecs);
7648 if (declspecs == float_type_node)
7649 strcat (buf, "float ");
7650 else if (declspecs == double_type_node)
7651 strcat (buf, "double ");
7652 else if (declspecs == long_double_type_node)
7653 strcat (buf, "long double ");
7657 if (TYPE_NAME (declspecs)
7658 && TREE_CODE (TYPE_NAME (declspecs)) == IDENTIFIER_NODE)
7660 tree protocol_list = TYPE_PROTOCOL_LIST (declspecs);
7662 if (! TREE_STATIC_TEMPLATE (declspecs))
7663 strcat (buf, "struct ");
7664 strcat (buf, IDENTIFIER_POINTER (TYPE_NAME (declspecs)));
7668 tree chain = protocol_list;
7675 (PROTOCOL_NAME (TREE_VALUE (chain))));
7676 chain = TREE_CHAIN (chain);
7685 strcat (buf, "untagged struct");
7691 if (TYPE_NAME (declspecs)
7692 && TREE_CODE (TYPE_NAME (declspecs)) == IDENTIFIER_NODE)
7694 strcat (buf, "union ");
7695 strcat (buf, IDENTIFIER_POINTER (TYPE_NAME (declspecs)));
7700 strcat (buf, "untagged union ");
7704 if (TYPE_NAME (declspecs)
7705 && TREE_CODE (TYPE_NAME (declspecs)) == IDENTIFIER_NODE)
7707 strcat (buf, "enum ");
7708 strcat (buf, IDENTIFIER_POINTER (TYPE_NAME (declspecs)));
7713 strcat (buf, "untagged enum ");
7717 strcat (buf, "void ");
7722 tree protocol_list = TYPE_PROTOCOL_LIST (declspecs);
7727 tree chain = protocol_list;
7734 (PROTOCOL_NAME (TREE_VALUE (chain))));
7735 chain = TREE_CHAIN (chain);
7751 /* Given a tree node, produce a printable description of it in the given
7752 buffer, overwriting the buffer. */
7755 gen_declaration (atype_or_adecl, buf)
7756 tree atype_or_adecl;
7760 gen_declaration_1 (atype_or_adecl, buf);
7764 /* Given a tree node, append a printable description to the end of the
7768 gen_declaration_1 (atype_or_adecl, buf)
7769 tree atype_or_adecl;
7774 if (TREE_CODE (atype_or_adecl) == TREE_LIST)
7776 tree declspecs; /* "identifier_node", "record_type" */
7777 tree declarator; /* "array_ref", "indirect_ref", "call_expr"... */
7779 /* We have a "raw", abstract declarator (typename). */
7780 declarator = TREE_VALUE (atype_or_adecl);
7781 declspecs = TREE_PURPOSE (atype_or_adecl);
7783 gen_declspecs (declspecs, buf, 1);
7787 strcat (buf, gen_declarator (declarator, declbuf, ""));
7794 tree declspecs; /* "integer_type", "real_type", "record_type"... */
7795 tree declarator; /* "array_type", "function_type", "pointer_type". */
7797 if (TREE_CODE (atype_or_adecl) == FIELD_DECL
7798 || TREE_CODE (atype_or_adecl) == PARM_DECL
7799 || TREE_CODE (atype_or_adecl) == FUNCTION_DECL)
7800 atype = TREE_TYPE (atype_or_adecl);
7802 /* Assume we have a *_type node. */
7803 atype = atype_or_adecl;
7805 if (is_complex_decl (atype))
7809 /* Get the declaration specifier; it is at the end of the list. */
7810 declarator = chain = atype;
7812 chain = TREE_TYPE (chain); /* not TREE_CHAIN (chain); */
7813 while (is_complex_decl (chain));
7820 declarator = NULL_TREE;
7823 gen_declspecs (declspecs, buf, 0);
7825 if (TREE_CODE (atype_or_adecl) == FIELD_DECL
7826 || TREE_CODE (atype_or_adecl) == PARM_DECL
7827 || TREE_CODE (atype_or_adecl) == FUNCTION_DECL)
7829 const char *const decl_name =
7830 (DECL_NAME (atype_or_adecl)
7831 ? IDENTIFIER_POINTER (DECL_NAME (atype_or_adecl)) : "");
7836 strcat (buf, gen_declarator (declarator, declbuf, decl_name));
7839 else if (decl_name[0])
7842 strcat (buf, decl_name);
7845 else if (declarator)
7848 strcat (buf, gen_declarator (declarator, declbuf, ""));
7853 #define RAW_TYPESPEC(meth) (TREE_VALUE (TREE_PURPOSE (TREE_TYPE (meth))))
7855 /* Given a method tree, put a printable description into the given
7856 buffer (overwriting) and return a pointer to the buffer. */
7859 gen_method_decl (method, buf)
7866 if (RAW_TYPESPEC (method) != objc_object_reference)
7869 gen_declaration_1 (TREE_TYPE (method), buf);
7873 chain = METHOD_SEL_ARGS (method);
7876 /* We have a chain of keyword_decls. */
7879 if (KEYWORD_KEY_NAME (chain))
7880 strcat (buf, IDENTIFIER_POINTER (KEYWORD_KEY_NAME (chain)));
7883 if (RAW_TYPESPEC (chain) != objc_object_reference)
7886 gen_declaration_1 (TREE_TYPE (chain), buf);
7890 strcat (buf, IDENTIFIER_POINTER (KEYWORD_ARG_NAME (chain)));
7891 if ((chain = TREE_CHAIN (chain)))
7896 if (METHOD_ADD_ARGS (method) == objc_ellipsis_node)
7897 strcat (buf, ", ...");
7898 else if (METHOD_ADD_ARGS (method))
7900 /* We have a tree list node as generate by get_parm_info. */
7901 chain = TREE_PURPOSE (METHOD_ADD_ARGS (method));
7903 /* Know we have a chain of parm_decls. */
7907 gen_declaration_1 (chain, buf);
7908 chain = TREE_CHAIN (chain);
7914 /* We have a unary selector. */
7915 strcat (buf, IDENTIFIER_POINTER (METHOD_SEL_NAME (method)));
7923 /* Dump an @interface declaration of the supplied class CHAIN to the
7924 supplied file FP. Used to implement the -gen-decls option (which
7925 prints out an @interface declaration of all classes compiled in
7926 this run); potentially useful for debugging the compiler too. */
7928 dump_interface (fp, chain)
7932 /* FIXME: A heap overflow here whenever a method (or ivar)
7933 declaration is so long that it doesn't fit in the buffer. The
7934 code and all the related functions should be rewritten to avoid
7935 using fixed size buffers. */
7936 char *buf = (char *) xmalloc (1024 * 10);
7937 const char *my_name = IDENTIFIER_POINTER (CLASS_NAME (chain));
7938 tree ivar_decls = CLASS_RAW_IVARS (chain);
7939 tree nst_methods = CLASS_NST_METHODS (chain);
7940 tree cls_methods = CLASS_CLS_METHODS (chain);
7942 fprintf (fp, "\n@interface %s", my_name);
7944 /* CLASS_SUPER_NAME is used to store the superclass name for
7945 classes, and the category name for categories. */
7946 if (CLASS_SUPER_NAME (chain))
7948 const char *name = IDENTIFIER_POINTER (CLASS_SUPER_NAME (chain));
7950 if (TREE_CODE (chain) == CATEGORY_IMPLEMENTATION_TYPE
7951 || TREE_CODE (chain) == CATEGORY_INTERFACE_TYPE)
7953 fprintf (fp, " (%s)\n", name);
7957 fprintf (fp, " : %s\n", name);
7963 /* FIXME - the following doesn't seem to work at the moment. */
7966 fprintf (fp, "{\n");
7969 fprintf (fp, "\t%s;\n", gen_declaration (ivar_decls, buf));
7970 ivar_decls = TREE_CHAIN (ivar_decls);
7973 fprintf (fp, "}\n");
7978 fprintf (fp, "- %s;\n", gen_method_decl (nst_methods, buf));
7979 nst_methods = TREE_CHAIN (nst_methods);
7984 fprintf (fp, "+ %s;\n", gen_method_decl (cls_methods, buf));
7985 cls_methods = TREE_CHAIN (cls_methods);
7988 fprintf (fp, "@end\n");
7991 /* Demangle function for Objective-C */
7993 objc_demangle (mangled)
7994 const char *mangled;
7996 char *demangled, *cp;
7998 if (mangled[0] == '_' &&
7999 (mangled[1] == 'i' || mangled[1] == 'c') &&
8002 cp = demangled = xmalloc(strlen(mangled) + 2);
8003 if (mangled[1] == 'i')
8004 *cp++ = '-'; /* for instance method */
8006 *cp++ = '+'; /* for class method */
8007 *cp++ = '['; /* opening left brace */
8008 strcpy(cp, mangled+3); /* tack on the rest of the mangled name */
8009 while (*cp && *cp == '_')
8010 cp++; /* skip any initial underbars in class name */
8011 cp = strchr(cp, '_'); /* find first non-initial underbar */
8014 free(demangled); /* not mangled name */
8017 if (cp[1] == '_') /* easy case: no category name */
8019 *cp++ = ' '; /* replace two '_' with one ' ' */
8020 strcpy(cp, mangled + (cp - demangled) + 2);
8024 *cp++ = '('; /* less easy case: category name */
8025 cp = strchr(cp, '_');
8028 free(demangled); /* not mangled name */
8032 *cp++ = ' '; /* overwriting 1st char of method name... */
8033 strcpy(cp, mangled + (cp - demangled)); /* get it back */
8035 while (*cp && *cp == '_')
8036 cp++; /* skip any initial underbars in method name */
8039 *cp = ':'; /* replace remaining '_' with ':' */
8040 *cp++ = ']'; /* closing right brace */
8041 *cp++ = 0; /* string terminator */
8045 return mangled; /* not an objc mangled name */
8049 objc_printable_name (decl, kind)
8051 int kind ATTRIBUTE_UNUSED;
8053 return objc_demangle (IDENTIFIER_POINTER (DECL_NAME (decl)));
8059 gcc_obstack_init (&util_obstack);
8060 util_firstobj = (char *) obstack_finish (&util_obstack);
8062 errbuf = (char *) xmalloc (BUFSIZE);
8064 synth_module_prologue ();
8070 struct imp_entry *impent;
8072 /* The internally generated initializers appear to have missing braces.
8073 Don't warn about this. */
8074 int save_warn_missing_braces = warn_missing_braces;
8075 warn_missing_braces = 0;
8077 /* A missing @end may not be detected by the parser. */
8078 if (objc_implementation_context)
8080 warning ("`@end' missing in implementation context");
8081 finish_class (objc_implementation_context);
8082 objc_ivar_chain = NULL_TREE;
8083 objc_implementation_context = NULL_TREE;
8086 generate_forward_declaration_to_string_table ();
8088 #ifdef OBJC_PROLOGUE
8092 /* Process the static instances here because initialization of objc_symtab
8094 if (objc_static_instances)
8095 generate_static_references ();
8097 if (imp_list || class_names_chain
8098 || meth_var_names_chain || meth_var_types_chain || sel_ref_chain)
8099 generate_objc_symtab_decl ();
8101 for (impent = imp_list; impent; impent = impent->next)
8103 objc_implementation_context = impent->imp_context;
8104 implementation_template = impent->imp_template;
8106 UOBJC_CLASS_decl = impent->class_decl;
8107 UOBJC_METACLASS_decl = impent->meta_decl;
8109 /* Dump the @interface of each class as we compile it, if the
8110 -gen-decls option is in use. TODO: Dump the classes in the
8111 order they were found, rather than in reverse order as we
8113 if (flag_gen_declaration)
8115 dump_interface (gen_declaration_file, objc_implementation_context);
8118 if (TREE_CODE (objc_implementation_context) == CLASS_IMPLEMENTATION_TYPE)
8120 /* all of the following reference the string pool... */
8121 generate_ivar_lists ();
8122 generate_dispatch_tables ();
8123 generate_shared_structures ();
8127 generate_dispatch_tables ();
8128 generate_category (objc_implementation_context);
8132 /* If we are using an array of selectors, we must always
8133 finish up the array decl even if no selectors were used. */
8134 if (! flag_next_runtime || sel_ref_chain)
8135 build_selector_translation_table ();
8138 generate_protocols ();
8140 if (objc_implementation_context || class_names_chain || objc_static_instances
8141 || meth_var_names_chain || meth_var_types_chain || sel_ref_chain)
8143 /* Arrange for ObjC data structures to be initialized at run time. */
8144 rtx init_sym = build_module_descriptor ();
8145 if (init_sym && targetm.have_ctors_dtors)
8146 (* targetm.asm_out.constructor) (init_sym, DEFAULT_INIT_PRIORITY);
8149 /* Dump the class references. This forces the appropriate classes
8150 to be linked into the executable image, preserving unix archive
8151 semantics. This can be removed when we move to a more dynamically
8152 linked environment. */
8154 for (chain = cls_ref_chain; chain; chain = TREE_CHAIN (chain))
8156 handle_class_ref (chain);
8157 if (TREE_PURPOSE (chain))
8158 generate_classref_translation_entry (chain);
8161 for (impent = imp_list; impent; impent = impent->next)
8162 handle_impent (impent);
8164 /* Dump the string table last. */
8166 generate_strings ();
8173 /* Run through the selector hash tables and print a warning for any
8174 selector which has multiple methods. */
8176 for (slot = 0; slot < SIZEHASHTABLE; slot++)
8177 for (hsh = cls_method_hash_list[slot]; hsh; hsh = hsh->next)
8180 tree meth = hsh->key;
8181 char type = (TREE_CODE (meth) == INSTANCE_METHOD_DECL
8185 warning ("potential selector conflict for method `%s'",
8186 IDENTIFIER_POINTER (METHOD_SEL_NAME (meth)));
8187 warn_with_method ("found", type, meth);
8188 for (loop = hsh->list; loop; loop = loop->next)
8189 warn_with_method ("found", type, loop->value);
8192 for (slot = 0; slot < SIZEHASHTABLE; slot++)
8193 for (hsh = nst_method_hash_list[slot]; hsh; hsh = hsh->next)
8196 tree meth = hsh->key;
8197 char type = (TREE_CODE (meth) == INSTANCE_METHOD_DECL
8201 warning ("potential selector conflict for method `%s'",
8202 IDENTIFIER_POINTER (METHOD_SEL_NAME (meth)));
8203 warn_with_method ("found", type, meth);
8204 for (loop = hsh->list; loop; loop = loop->next)
8205 warn_with_method ("found", type, loop->value);
8209 warn_missing_braces = save_warn_missing_braces;
8212 /* Subroutines of finish_objc. */
8215 generate_classref_translation_entry (chain)
8218 tree expr, name, decl_specs, decl, sc_spec;
8221 type = TREE_TYPE (TREE_PURPOSE (chain));
8223 expr = add_objc_string (TREE_VALUE (chain), class_names);
8224 expr = build_c_cast (type, expr); /* cast! */
8226 name = DECL_NAME (TREE_PURPOSE (chain));
8228 sc_spec = build_tree_list (NULL_TREE, ridpointers[(int) RID_STATIC]);
8230 /* static struct objc_class * _OBJC_CLASS_REFERENCES_n = ...; */
8231 decl_specs = tree_cons (NULL_TREE, type, sc_spec);
8233 /* The decl that is returned from start_decl is the one that we
8234 forward declared in build_class_reference. */
8235 decl = start_decl (name, decl_specs, 1, NULL_TREE);
8236 DECL_CONTEXT (decl) = NULL_TREE;
8237 finish_decl (decl, expr, NULL_TREE);
8242 handle_class_ref (chain)
8245 const char *name = IDENTIFIER_POINTER (TREE_VALUE (chain));
8246 char *string = (char *) alloca (strlen (name) + 30);
8250 sprintf (string, "%sobjc_class_name_%s",
8251 (flag_next_runtime ? "." : "__"), name);
8253 #ifdef ASM_DECLARE_UNRESOLVED_REFERENCE
8254 if (flag_next_runtime)
8256 ASM_DECLARE_UNRESOLVED_REFERENCE (asm_out_file, string);
8261 /* Make a decl for this name, so we can use its address in a tree. */
8262 decl = build_decl (VAR_DECL, get_identifier (string), char_type_node);
8263 DECL_EXTERNAL (decl) = 1;
8264 TREE_PUBLIC (decl) = 1;
8267 rest_of_decl_compilation (decl, 0, 0, 0);
8269 /* Make a decl for the address. */
8270 sprintf (string, "%sobjc_class_ref_%s",
8271 (flag_next_runtime ? "." : "__"), name);
8272 exp = build1 (ADDR_EXPR, string_type_node, decl);
8273 decl = build_decl (VAR_DECL, get_identifier (string), string_type_node);
8274 DECL_INITIAL (decl) = exp;
8275 TREE_STATIC (decl) = 1;
8276 TREE_USED (decl) = 1;
8279 rest_of_decl_compilation (decl, 0, 0, 0);
8283 handle_impent (impent)
8284 struct imp_entry *impent;
8288 objc_implementation_context = impent->imp_context;
8289 implementation_template = impent->imp_template;
8291 if (TREE_CODE (impent->imp_context) == CLASS_IMPLEMENTATION_TYPE)
8293 const char *const class_name =
8294 IDENTIFIER_POINTER (CLASS_NAME (impent->imp_context));
8296 string = (char *) alloca (strlen (class_name) + 30);
8298 sprintf (string, "%sobjc_class_name_%s",
8299 (flag_next_runtime ? "." : "__"), class_name);
8301 else if (TREE_CODE (impent->imp_context) == CATEGORY_IMPLEMENTATION_TYPE)
8303 const char *const class_name =
8304 IDENTIFIER_POINTER (CLASS_NAME (impent->imp_context));
8305 const char *const class_super_name =
8306 IDENTIFIER_POINTER (CLASS_SUPER_NAME (impent->imp_context));
8308 string = (char *) alloca (strlen (class_name)
8309 + strlen (class_super_name) + 30);
8311 /* Do the same for categories. Even though no references to
8312 these symbols are generated automatically by the compiler, it
8313 gives you a handle to pull them into an archive by hand. */
8314 sprintf (string, "*%sobjc_category_name_%s_%s",
8315 (flag_next_runtime ? "." : "__"), class_name, class_super_name);
8320 #ifdef ASM_DECLARE_CLASS_REFERENCE
8321 if (flag_next_runtime)
8323 ASM_DECLARE_CLASS_REFERENCE (asm_out_file, string);
8331 init = build_int_2 (0, 0);
8332 TREE_TYPE (init) = c_common_type_for_size (BITS_PER_WORD, 1);
8333 decl = build_decl (VAR_DECL, get_identifier (string), TREE_TYPE (init));
8334 TREE_PUBLIC (decl) = 1;
8335 TREE_READONLY (decl) = 1;
8336 TREE_USED (decl) = 1;
8337 TREE_CONSTANT (decl) = 1;
8338 DECL_CONTEXT (decl) = 0;
8339 DECL_ARTIFICIAL (decl) = 1;
8340 DECL_INITIAL (decl) = init;
8341 assemble_variable (decl, 1, 0, 0);
8345 /* Look up ID as an instance variable. */
8347 lookup_objc_ivar (id)
8352 if (objc_method_context && !strcmp (IDENTIFIER_POINTER (id), "super"))
8353 /* We have a message to super. */
8354 return get_super_receiver ();
8355 else if (objc_method_context && (decl = is_ivar (objc_ivar_chain, id)))
8357 if (is_private (decl))
8358 return error_mark_node;
8360 return build_ivar_reference (id);
8366 #include "gtype-objc.h"