1 /* Implement classes and message passing for Objective C.
2 Copyright (C) 1992, 1993, 1994, 1995, 1997, 1998, 1999, 2000,
3 2001, 2002, 2003 Free Software Foundation, Inc.
4 Contributed by Steve Naroff.
6 This file is part of GCC.
8 GCC is free software; you can redistribute it and/or modify
9 it under the terms of the GNU General Public License as published by
10 the Free Software Foundation; either version 2, or (at your option)
13 GCC is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 GNU General Public License for more details.
18 You should have received a copy of the GNU General Public License
19 along with GCC; see the file COPYING. If not, write to
20 the Free Software Foundation, 59 Temple Place - Suite 330,
21 Boston, MA 02111-1307, USA. */
23 /* Purpose: This module implements the Objective-C 4.0 language.
25 compatibility issues (with the Stepstone translator):
27 - does not recognize the following 3.3 constructs.
28 @requires, @classes, @messages, = (...)
29 - methods with variable arguments must conform to ANSI standard.
30 - tagged structure definitions that appear in BOTH the interface
31 and implementation are not allowed.
32 - public/private: all instance variables are public within the
33 context of the implementation...I consider this to be a bug in
35 - statically allocated objects are not supported. the user will
36 receive an error if this service is requested.
38 code generation `options':
44 #include "coretypes.h"
62 #include "diagnostic.h"
65 /* This is the default way of generating a method name. */
66 /* I am not sure it is really correct.
67 Perhaps there's a danger that it will make name conflicts
68 if method names contain underscores. -- rms. */
69 #ifndef OBJC_GEN_METHOD_LABEL
70 #define OBJC_GEN_METHOD_LABEL(BUF, IS_INST, CLASS_NAME, CAT_NAME, SEL_NAME, NUM) \
73 sprintf ((BUF), "_%s_%s_%s_%s", \
74 ((IS_INST) ? "i" : "c"), \
76 ((CAT_NAME)? (CAT_NAME) : ""), \
78 for (temp = (BUF); *temp; temp++) \
79 if (*temp == ':') *temp = '_'; \
83 /* These need specifying. */
84 #ifndef OBJC_FORWARDING_STACK_OFFSET
85 #define OBJC_FORWARDING_STACK_OFFSET 0
88 #ifndef OBJC_FORWARDING_MIN_OFFSET
89 #define OBJC_FORWARDING_MIN_OFFSET 0
93 /* Set up for use of obstacks. */
97 /* This obstack is used to accumulate the encoding of a data type. */
98 static struct obstack util_obstack;
99 /* This points to the beginning of obstack contents,
100 so we can free the whole contents. */
103 /* for encode_method_def */
106 /* The version identifies which language generation and runtime
107 the module (file) was compiled for, and is recorded in the
108 module descriptor. */
110 #define OBJC_VERSION (flag_next_runtime ? 5 : 8)
111 #define PROTOCOL_VERSION 2
113 /* (Decide if these can ever be validly changed.) */
114 #define OBJC_ENCODE_INLINE_DEFS 0
115 #define OBJC_ENCODE_DONT_INLINE_DEFS 1
117 /*** Private Interface (procedures) ***/
119 /* Used by compile_file. */
121 static void init_objc PARAMS ((void));
122 static void finish_objc PARAMS ((void));
124 /* Code generation. */
126 static void synth_module_prologue PARAMS ((void));
127 static tree objc_build_constructor PARAMS ((tree, tree));
128 static rtx build_module_descriptor PARAMS ((void));
129 static tree init_module_descriptor PARAMS ((tree));
130 static tree build_objc_method_call PARAMS ((int, tree, tree,
132 static void generate_strings PARAMS ((void));
133 static tree get_proto_encoding PARAMS ((tree));
134 static void build_selector_translation_table PARAMS ((void));
136 static tree objc_add_static_instance PARAMS ((tree, tree));
138 static tree build_ivar_template PARAMS ((void));
139 static tree build_method_template PARAMS ((void));
140 static tree build_private_template PARAMS ((tree));
141 static void build_class_template PARAMS ((void));
142 static void build_selector_template PARAMS ((void));
143 static void build_category_template PARAMS ((void));
144 static tree build_super_template PARAMS ((void));
145 static tree build_category_initializer PARAMS ((tree, tree, tree,
147 static tree build_protocol_initializer PARAMS ((tree, tree, tree,
150 static void synth_forward_declarations PARAMS ((void));
151 static void generate_ivar_lists PARAMS ((void));
152 static void generate_dispatch_tables PARAMS ((void));
153 static void generate_shared_structures PARAMS ((void));
154 static tree generate_protocol_list PARAMS ((tree));
155 static void generate_forward_declaration_to_string_table PARAMS ((void));
156 static void build_protocol_reference PARAMS ((tree));
158 static tree build_keyword_selector PARAMS ((tree));
159 static tree synth_id_with_class_suffix PARAMS ((const char *, tree));
161 static void generate_static_references PARAMS ((void));
162 static int check_methods_accessible PARAMS ((tree, tree,
164 static void encode_aggregate_within PARAMS ((tree, int, int,
166 static const char *objc_demangle PARAMS ((const char *));
167 static void objc_expand_function_end PARAMS ((void));
169 /* Hash tables to manage the global pool of method prototypes. */
171 hash *nst_method_hash_list = 0;
172 hash *cls_method_hash_list = 0;
174 static size_t hash_func PARAMS ((tree));
175 static void hash_init PARAMS ((void));
176 static void hash_enter PARAMS ((hash *, tree));
177 static hash hash_lookup PARAMS ((hash *, tree));
178 static void hash_add_attr PARAMS ((hash, tree));
179 static tree lookup_method PARAMS ((tree, tree));
180 static tree lookup_instance_method_static PARAMS ((tree, tree));
181 static tree lookup_class_method_static PARAMS ((tree, tree));
182 static tree add_class PARAMS ((tree));
183 static void add_category PARAMS ((tree, tree));
187 class_names, /* class, category, protocol, module names */
188 meth_var_names, /* method and variable names */
189 meth_var_types /* method and variable type descriptors */
192 static tree add_objc_string PARAMS ((tree,
193 enum string_section));
194 static tree get_objc_string_decl PARAMS ((tree,
195 enum string_section));
196 static tree build_objc_string_decl PARAMS ((enum string_section));
197 static tree build_selector_reference_decl PARAMS ((void));
199 /* Protocol additions. */
201 static tree add_protocol PARAMS ((tree));
202 static tree lookup_protocol PARAMS ((tree));
203 static void check_protocol_recursively PARAMS ((tree, tree));
204 static tree lookup_and_install_protocols PARAMS ((tree));
208 static void encode_type_qualifiers PARAMS ((tree));
209 static void encode_pointer PARAMS ((tree, int, int));
210 static void encode_array PARAMS ((tree, int, int));
211 static void encode_aggregate PARAMS ((tree, int, int));
212 static void encode_bitfield PARAMS ((int));
213 static void encode_type PARAMS ((tree, int, int));
214 static void encode_field_decl PARAMS ((tree, int, int));
216 static void really_start_method PARAMS ((tree, tree));
217 static int comp_method_with_proto PARAMS ((tree, tree));
218 static int comp_proto_with_proto PARAMS ((tree, tree));
219 static tree get_arg_type_list PARAMS ((tree, int, int));
220 static tree expr_last PARAMS ((tree));
222 /* Utilities for debugging and error diagnostics. */
224 static void warn_with_method PARAMS ((const char *, int, tree));
225 static void error_with_ivar PARAMS ((const char *, tree, tree));
226 static char *gen_method_decl PARAMS ((tree, char *));
227 static char *gen_declaration PARAMS ((tree, char *));
228 static void gen_declaration_1 PARAMS ((tree, char *));
229 static char *gen_declarator PARAMS ((tree, char *,
231 static int is_complex_decl PARAMS ((tree));
232 static void adorn_decl PARAMS ((tree, char *));
233 static void dump_interface PARAMS ((FILE *, tree));
235 /* Everything else. */
237 static tree define_decl PARAMS ((tree, tree));
238 static tree lookup_method_in_protocol_list PARAMS ((tree, tree, int));
239 static tree lookup_protocol_in_reflist PARAMS ((tree, tree));
240 static tree create_builtin_decl PARAMS ((enum tree_code,
241 tree, const char *));
242 static void setup_string_decl PARAMS ((void));
243 static void build_string_class_template PARAMS ((void));
244 static tree my_build_string PARAMS ((int, const char *));
245 static void build_objc_symtab_template PARAMS ((void));
246 static tree init_def_list PARAMS ((tree));
247 static tree init_objc_symtab PARAMS ((tree));
248 static void forward_declare_categories PARAMS ((void));
249 static void generate_objc_symtab_decl PARAMS ((void));
250 static tree build_selector PARAMS ((tree));
251 static tree build_typed_selector_reference PARAMS ((tree, tree));
252 static tree build_selector_reference PARAMS ((tree));
253 static tree build_class_reference_decl PARAMS ((void));
254 static void add_class_reference PARAMS ((tree));
255 static tree build_protocol_template PARAMS ((void));
256 static tree build_descriptor_table_initializer PARAMS ((tree, tree));
257 static tree build_method_prototype_list_template PARAMS ((tree, int));
258 static tree build_method_prototype_template PARAMS ((void));
259 static int forwarding_offset PARAMS ((tree));
260 static tree encode_method_prototype PARAMS ((tree, tree));
261 static tree generate_descriptor_table PARAMS ((tree, const char *,
263 static void generate_method_descriptors PARAMS ((tree));
264 static tree build_tmp_function_decl PARAMS ((void));
265 static void hack_method_prototype PARAMS ((tree, tree));
266 static void generate_protocol_references PARAMS ((tree));
267 static void generate_protocols PARAMS ((void));
268 static void check_ivars PARAMS ((tree, tree));
269 static tree build_ivar_list_template PARAMS ((tree, int));
270 static tree build_method_list_template PARAMS ((tree, int));
271 static tree build_ivar_list_initializer PARAMS ((tree, tree));
272 static tree generate_ivars_list PARAMS ((tree, const char *,
274 static tree build_dispatch_table_initializer PARAMS ((tree, tree));
275 static tree generate_dispatch_table PARAMS ((tree, const char *,
277 static tree build_shared_structure_initializer PARAMS ((tree, tree, tree, tree,
278 tree, int, tree, tree,
280 static void generate_category PARAMS ((tree));
281 static int is_objc_type_qualifier PARAMS ((tree));
282 static tree adjust_type_for_id_default PARAMS ((tree));
283 static tree check_duplicates PARAMS ((hash));
284 static tree receiver_is_class_object PARAMS ((tree));
285 static int check_methods PARAMS ((tree, tree, int));
286 static int conforms_to_protocol PARAMS ((tree, tree));
287 static void check_protocol PARAMS ((tree, const char *,
289 static void check_protocols PARAMS ((tree, const char *,
291 static tree encode_method_def PARAMS ((tree));
292 static void gen_declspecs PARAMS ((tree, char *, int));
293 static void generate_classref_translation_entry PARAMS ((tree));
294 static void handle_class_ref PARAMS ((tree));
295 static void generate_struct_by_value_array PARAMS ((void))
297 static void encode_complete_bitfield PARAMS ((int, tree, int));
298 static void mark_referenced_methods PARAMS ((void));
300 /*** Private Interface (data) ***/
302 /* Reserved tag definitions. */
305 #define TAG_OBJECT "objc_object"
306 #define TAG_CLASS "objc_class"
307 #define TAG_SUPER "objc_super"
308 #define TAG_SELECTOR "objc_selector"
310 #define UTAG_CLASS "_objc_class"
311 #define UTAG_IVAR "_objc_ivar"
312 #define UTAG_IVAR_LIST "_objc_ivar_list"
313 #define UTAG_METHOD "_objc_method"
314 #define UTAG_METHOD_LIST "_objc_method_list"
315 #define UTAG_CATEGORY "_objc_category"
316 #define UTAG_MODULE "_objc_module"
317 #define UTAG_SYMTAB "_objc_symtab"
318 #define UTAG_SUPER "_objc_super"
319 #define UTAG_SELECTOR "_objc_selector"
321 #define UTAG_PROTOCOL "_objc_protocol"
322 #define UTAG_METHOD_PROTOTYPE "_objc_method_prototype"
323 #define UTAG_METHOD_PROTOTYPE_LIST "_objc__method_prototype_list"
325 /* Note that the string object global name is only needed for the
327 #define STRING_OBJECT_GLOBAL_NAME "_NSConstantStringClassReference"
329 #define PROTOCOL_OBJECT_CLASS_NAME "Protocol"
331 static const char *TAG_GETCLASS;
332 static const char *TAG_GETMETACLASS;
333 static const char *TAG_MSGSEND;
334 static const char *TAG_MSGSENDSUPER;
335 static const char *TAG_EXECCLASS;
336 static const char *default_constant_string_class_name;
338 /* The OCTI_... enumeration itself is in objc/objc-act.h. */
339 tree objc_global_trees[OCTI_MAX];
341 static void handle_impent PARAMS ((struct imp_entry *));
343 struct imp_entry *imp_list = 0;
344 int imp_count = 0; /* `@implementation' */
345 int cat_count = 0; /* `@category' */
347 static int method_slot = 0; /* Used by start_method_def, */
351 static char *errbuf; /* Buffer for error diagnostics */
353 /* Data imported from tree.c. */
355 extern enum debug_info_type write_symbols;
357 /* Data imported from toplev.c. */
359 extern const char *dump_base_name;
361 static int flag_typed_selectors;
363 FILE *gen_declaration_file;
365 /* Tells "encode_pointer/encode_aggregate" whether we are generating
366 type descriptors for instance variables (as opposed to methods).
367 Type descriptors for instance variables contain more information
368 than methods (for static typing and embedded structures). */
370 static int generating_instance_variables = 0;
372 /* Some platforms pass small structures through registers versus
373 through an invisible pointer. Determine at what size structure is
374 the transition point between the two possibilities. */
377 generate_struct_by_value_array ()
380 tree field_decl, field_decl_chain;
382 int aggregate_in_mem[32];
385 /* Presumably no platform passes 32 byte structures in a register. */
386 for (i = 1; i < 32; i++)
390 /* Create an unnamed struct that has `i' character components */
391 type = start_struct (RECORD_TYPE, NULL_TREE);
393 strcpy (buffer, "c1");
394 field_decl = create_builtin_decl (FIELD_DECL,
397 field_decl_chain = field_decl;
399 for (j = 1; j < i; j++)
401 sprintf (buffer, "c%d", j + 1);
402 field_decl = create_builtin_decl (FIELD_DECL,
405 chainon (field_decl_chain, field_decl);
407 finish_struct (type, field_decl_chain, NULL_TREE);
409 aggregate_in_mem[i] = aggregate_value_p (type);
410 if (!aggregate_in_mem[i])
414 /* We found some structures that are returned in registers instead of memory
415 so output the necessary data. */
418 for (i = 31; i >= 0; i--)
419 if (!aggregate_in_mem[i])
421 printf ("#define OBJC_MAX_STRUCT_BY_VALUE %d\n\n", i);
423 /* The first member of the structure is always 0 because we don't handle
424 structures with 0 members */
425 printf ("static int struct_forward_array[] = {\n 0");
427 for (j = 1; j <= i; j++)
428 printf (", %d", aggregate_in_mem[j]);
438 if (c_objc_common_init () == false)
441 /* Force the line number back to 0; check_newline will have
442 raised it to 1, which will make the builtin functions appear
443 not to be built in. */
446 /* If gen_declaration desired, open the output file. */
447 if (flag_gen_declaration)
449 register char * const dumpname = concat (dump_base_name, ".decl", NULL);
450 gen_declaration_file = fopen (dumpname, "w");
451 if (gen_declaration_file == 0)
452 fatal_io_error ("can't open %s", dumpname);
456 if (flag_next_runtime)
458 TAG_GETCLASS = "objc_getClass";
459 TAG_GETMETACLASS = "objc_getMetaClass";
460 TAG_MSGSEND = "objc_msgSend";
461 TAG_MSGSENDSUPER = "objc_msgSendSuper";
462 TAG_EXECCLASS = "__objc_execClass";
463 default_constant_string_class_name = "NSConstantString";
467 TAG_GETCLASS = "objc_get_class";
468 TAG_GETMETACLASS = "objc_get_meta_class";
469 TAG_MSGSEND = "objc_msg_lookup";
470 TAG_MSGSENDSUPER = "objc_msg_lookup_super";
471 TAG_EXECCLASS = "__objc_exec_class";
472 default_constant_string_class_name = "NXConstantString";
473 flag_typed_selectors = 1;
476 objc_ellipsis_node = make_node (ERROR_MARK);
480 if (print_struct_values)
481 generate_struct_by_value_array ();
489 mark_referenced_methods ();
490 c_objc_common_finish_file ();
492 /* Finalize Objective-C runtime data. No need to generate tables
493 and code if only checking syntax. */
494 if (!flag_syntax_only)
497 if (gen_declaration_file)
498 fclose (gen_declaration_file);
502 define_decl (declarator, declspecs)
506 tree decl = start_decl (declarator, declspecs, 0, NULL_TREE);
507 finish_decl (decl, NULL_TREE, NULL_TREE);
511 /* Return 1 if LHS and RHS are compatible types for assignment or
512 various other operations. Return 0 if they are incompatible, and
513 return -1 if we choose to not decide. When the operation is
514 REFLEXIVE, check for compatibility in either direction.
516 For statically typed objects, an assignment of the form `a' = `b'
520 `a' and `b' are the same class type, or
521 `a' and `b' are of class types A and B such that B is a descendant of A. */
524 lookup_method_in_protocol_list (rproto_list, sel_name, class_meth)
532 for (rproto = rproto_list; rproto; rproto = TREE_CHAIN (rproto))
534 p = TREE_VALUE (rproto);
536 if (TREE_CODE (p) == PROTOCOL_INTERFACE_TYPE)
538 if ((fnd = lookup_method (class_meth
539 ? PROTOCOL_CLS_METHODS (p)
540 : PROTOCOL_NST_METHODS (p), sel_name)))
542 else if (PROTOCOL_LIST (p))
543 fnd = lookup_method_in_protocol_list (PROTOCOL_LIST (p),
544 sel_name, class_meth);
548 ; /* An identifier...if we could not find a protocol. */
559 lookup_protocol_in_reflist (rproto_list, lproto)
565 /* Make sure the protocol is supported by the object on the rhs. */
566 if (TREE_CODE (lproto) == PROTOCOL_INTERFACE_TYPE)
569 for (rproto = rproto_list; rproto; rproto = TREE_CHAIN (rproto))
571 p = TREE_VALUE (rproto);
573 if (TREE_CODE (p) == PROTOCOL_INTERFACE_TYPE)
578 else if (PROTOCOL_LIST (p))
579 fnd = lookup_protocol_in_reflist (PROTOCOL_LIST (p), lproto);
588 ; /* An identifier...if we could not find a protocol. */
594 /* Return 1 if LHS and RHS are compatible types for assignment or
595 various other operations. Return 0 if they are incompatible, and
596 return -1 if we choose to not decide (because the types are really
597 just C types, not ObjC specific ones). When the operation is
598 REFLEXIVE (typically comparisons), check for compatibility in
599 either direction; when it's not (typically assignments), don't.
601 This function is called in two cases: when both lhs and rhs are
602 pointers to records (in which case we check protocols too), and
603 when both lhs and rhs are records (in which case we check class
606 Warnings about classes/protocols not implementing a protocol are
607 emitted here (multiple of those warnings might be emitted for a
608 single line!); generic warnings about incompatible assignments and
609 lacks of casts in comparisons are/must be emitted by the caller if
614 objc_comptypes (lhs, rhs, reflexive)
619 /* New clause for protocols. */
621 /* Here we manage the case of a POINTER_TYPE = POINTER_TYPE. We only
622 manage the ObjC ones, and leave the rest to the C code. */
623 if (TREE_CODE (lhs) == POINTER_TYPE
624 && TREE_CODE (TREE_TYPE (lhs)) == RECORD_TYPE
625 && TREE_CODE (rhs) == POINTER_TYPE
626 && TREE_CODE (TREE_TYPE (rhs)) == RECORD_TYPE)
628 int lhs_is_proto = IS_PROTOCOL_QUALIFIED_ID (lhs);
629 int rhs_is_proto = IS_PROTOCOL_QUALIFIED_ID (rhs);
633 tree lproto, lproto_list = TYPE_PROTOCOL_LIST (lhs);
634 tree rproto, rproto_list;
637 /* <Protocol> = <Protocol> */
640 rproto_list = TYPE_PROTOCOL_LIST (rhs);
644 /* An assignment between objects of type 'id
645 <Protocol>'; make sure the protocol on the lhs is
646 supported by the object on the rhs. */
647 for (lproto = lproto_list; lproto;
648 lproto = TREE_CHAIN (lproto))
650 p = TREE_VALUE (lproto);
651 rproto = lookup_protocol_in_reflist (rproto_list, p);
655 ("object does not conform to the `%s' protocol",
656 IDENTIFIER_POINTER (PROTOCOL_NAME (p)));
662 /* Obscure case - a comparison between two objects
663 of type 'id <Protocol>'. Check that either the
664 protocol on the lhs is supported by the object on
665 the rhs, or viceversa. */
667 /* Check if the protocol on the lhs is supported by the
668 object on the rhs. */
669 for (lproto = lproto_list; lproto;
670 lproto = TREE_CHAIN (lproto))
672 p = TREE_VALUE (lproto);
673 rproto = lookup_protocol_in_reflist (rproto_list, p);
677 /* Check failed - check if the protocol on the rhs
678 is supported by the object on the lhs. */
679 for (rproto = rproto_list; rproto;
680 rproto = TREE_CHAIN (rproto))
682 p = TREE_VALUE (rproto);
683 lproto = lookup_protocol_in_reflist (lproto_list,
688 /* This check failed too: incompatible */
698 /* <Protocol> = <class> * */
699 else if (TYPED_OBJECT (TREE_TYPE (rhs)))
701 tree rname = TYPE_NAME (TREE_TYPE (rhs));
704 /* Make sure the protocol is supported by the object on
706 for (lproto = lproto_list; lproto; lproto = TREE_CHAIN (lproto))
708 p = TREE_VALUE (lproto);
710 rinter = lookup_interface (rname);
712 while (rinter && !rproto)
716 rproto_list = CLASS_PROTOCOL_LIST (rinter);
717 rproto = lookup_protocol_in_reflist (rproto_list, p);
718 /* If the underlying ObjC class does not have
719 the protocol we're looking for, check for "one-off"
720 protocols (e.g., `NSObject<MyProt> *foo;') attached
724 rproto_list = TYPE_PROTOCOL_LIST (TREE_TYPE (rhs));
725 rproto = lookup_protocol_in_reflist (rproto_list, p);
728 /* Check for protocols adopted by categories. */
729 cat = CLASS_CATEGORY_LIST (rinter);
730 while (cat && !rproto)
732 rproto_list = CLASS_PROTOCOL_LIST (cat);
733 rproto = lookup_protocol_in_reflist (rproto_list, p);
734 cat = CLASS_CATEGORY_LIST (cat);
737 rinter = lookup_interface (CLASS_SUPER_NAME (rinter));
741 warning ("class `%s' does not implement the `%s' protocol",
742 IDENTIFIER_POINTER (TYPE_NAME (TREE_TYPE (rhs))),
743 IDENTIFIER_POINTER (PROTOCOL_NAME (p)));
747 /* <Protocol> = id */
748 else if (TYPE_NAME (TREE_TYPE (rhs)) == objc_object_id)
752 /* <Protocol> = Class */
753 else if (TYPE_NAME (TREE_TYPE (rhs)) == objc_class_id)
757 /* <Protocol> = ?? : let comptypes decide. */
760 else if (rhs_is_proto)
762 /* <class> * = <Protocol> */
763 if (TYPED_OBJECT (TREE_TYPE (lhs)))
767 tree rname = TYPE_NAME (TREE_TYPE (lhs));
769 tree rproto, rproto_list = TYPE_PROTOCOL_LIST (rhs);
771 /* Make sure the protocol is supported by the object on
773 for (rproto = rproto_list; rproto;
774 rproto = TREE_CHAIN (rproto))
776 tree p = TREE_VALUE (rproto);
778 rinter = lookup_interface (rname);
780 while (rinter && !lproto)
784 tree lproto_list = CLASS_PROTOCOL_LIST (rinter);
785 lproto = lookup_protocol_in_reflist (lproto_list, p);
786 /* If the underlying ObjC class does not
787 have the protocol we're looking for,
788 check for "one-off" protocols (e.g.,
789 `NSObject<MyProt> *foo;') attached to the
793 lproto_list = TYPE_PROTOCOL_LIST
795 lproto = lookup_protocol_in_reflist
799 /* Check for protocols adopted by categories. */
800 cat = CLASS_CATEGORY_LIST (rinter);
801 while (cat && !lproto)
803 lproto_list = CLASS_PROTOCOL_LIST (cat);
804 lproto = lookup_protocol_in_reflist (lproto_list,
806 cat = CLASS_CATEGORY_LIST (cat);
809 rinter = lookup_interface (CLASS_SUPER_NAME
814 warning ("class `%s' does not implement the `%s' protocol",
815 IDENTIFIER_POINTER (TYPE_NAME
817 IDENTIFIER_POINTER (PROTOCOL_NAME (p)));
824 /* id = <Protocol> */
825 else if (TYPE_NAME (TREE_TYPE (lhs)) == objc_object_id)
829 /* Class = <Protocol> */
830 else if (TYPE_NAME (TREE_TYPE (lhs)) == objc_class_id)
834 /* ??? = <Protocol> : let comptypes decide */
842 /* Attention: we shouldn't defer to comptypes here. One bad
843 side effect would be that we might loose the REFLEXIVE
846 lhs = TREE_TYPE (lhs);
847 rhs = TREE_TYPE (rhs);
851 if (TREE_CODE (lhs) != RECORD_TYPE || TREE_CODE (rhs) != RECORD_TYPE)
853 /* Nothing to do with ObjC - let immediately comptypes take
854 responsibility for checking. */
858 /* `id' = `<class> *' `<class> *' = `id': always allow it.
860 'Object *o = [[Object alloc] init]; falls
861 in the case <class> * = `id'.
863 if ((TYPE_NAME (lhs) == objc_object_id && TYPED_OBJECT (rhs))
864 || (TYPE_NAME (rhs) == objc_object_id && TYPED_OBJECT (lhs)))
867 /* `id' = `Class', `Class' = `id' */
869 else if ((TYPE_NAME (lhs) == objc_object_id
870 && TYPE_NAME (rhs) == objc_class_id)
871 || (TYPE_NAME (lhs) == objc_class_id
872 && TYPE_NAME (rhs) == objc_object_id))
875 /* `<class> *' = `<class> *' */
877 else if (TYPED_OBJECT (lhs) && TYPED_OBJECT (rhs))
879 tree lname = TYPE_NAME (lhs);
880 tree rname = TYPE_NAME (rhs);
886 /* If the left hand side is a super class of the right hand side,
888 for (inter = lookup_interface (rname); inter;
889 inter = lookup_interface (CLASS_SUPER_NAME (inter)))
890 if (lname == CLASS_SUPER_NAME (inter))
893 /* Allow the reverse when reflexive. */
895 for (inter = lookup_interface (lname); inter;
896 inter = lookup_interface (CLASS_SUPER_NAME (inter)))
897 if (rname == CLASS_SUPER_NAME (inter))
903 /* Not an ObjC type - let comptypes do the check. */
907 /* Called from c-decl.c before all calls to rest_of_decl_compilation. */
910 objc_check_decl (decl)
913 tree type = TREE_TYPE (decl);
915 if (TREE_CODE (type) == RECORD_TYPE
916 && TREE_STATIC_TEMPLATE (type)
917 && type != constant_string_type)
918 error_with_decl (decl, "`%s' cannot be statically allocated");
921 /* Implement static typing. At this point, we know we have an interface. */
924 get_static_reference (interface, protocols)
928 tree type = xref_tag (RECORD_TYPE, interface);
932 tree t, m = TYPE_MAIN_VARIANT (type);
934 t = copy_node (type);
936 /* Add this type to the chain of variants of TYPE. */
937 TYPE_NEXT_VARIANT (t) = TYPE_NEXT_VARIANT (m);
938 TYPE_NEXT_VARIANT (m) = t;
940 /* Look up protocols and install in lang specific list. Note
941 that the protocol list can have a different lifetime than T! */
942 TYPE_PROTOCOL_LIST (t) = lookup_and_install_protocols (protocols);
944 /* This forces a new pointer type to be created later
945 (in build_pointer_type)...so that the new template
946 we just created will actually be used...what a hack! */
947 if (TYPE_POINTER_TO (t))
948 TYPE_POINTER_TO (t) = NULL_TREE;
957 get_object_reference (protocols)
960 tree type_decl = lookup_name (objc_id_id);
963 if (type_decl && TREE_CODE (type_decl) == TYPE_DECL)
965 type = TREE_TYPE (type_decl);
966 if (TYPE_MAIN_VARIANT (type) != id_type)
967 warning ("unexpected type for `id' (%s)",
968 gen_declaration (type, errbuf));
972 error ("undefined type `id', please import <objc/objc.h>");
973 return error_mark_node;
976 /* This clause creates a new pointer type that is qualified with
977 the protocol specification...this info is used later to do more
978 elaborate type checking. */
982 tree t, m = TYPE_MAIN_VARIANT (type);
984 t = copy_node (type);
986 /* Add this type to the chain of variants of TYPE. */
987 TYPE_NEXT_VARIANT (t) = TYPE_NEXT_VARIANT (m);
988 TYPE_NEXT_VARIANT (m) = t;
990 /* Look up protocols...and install in lang specific list */
991 TYPE_PROTOCOL_LIST (t) = lookup_and_install_protocols (protocols);
993 /* This forces a new pointer type to be created later
994 (in build_pointer_type)...so that the new template
995 we just created will actually be used...what a hack! */
996 if (TYPE_POINTER_TO (t))
997 TYPE_POINTER_TO (t) = NULL_TREE;
1004 /* Check for circular dependencies in protocols. The arguments are
1005 PROTO, the protocol to check, and LIST, a list of protocol it
1009 check_protocol_recursively (proto, list)
1015 for (p = list; p; p = TREE_CHAIN (p))
1017 tree pp = TREE_VALUE (p);
1019 if (TREE_CODE (pp) == IDENTIFIER_NODE)
1020 pp = lookup_protocol (pp);
1023 fatal_error ("protocol `%s' has circular dependency",
1024 IDENTIFIER_POINTER (PROTOCOL_NAME (pp)));
1026 check_protocol_recursively (proto, PROTOCOL_LIST (pp));
1031 lookup_and_install_protocols (protocols)
1036 tree return_value = protocols;
1038 for (proto = protocols; proto; proto = TREE_CHAIN (proto))
1040 tree ident = TREE_VALUE (proto);
1041 tree p = lookup_protocol (ident);
1045 error ("cannot find protocol declaration for `%s'",
1046 IDENTIFIER_POINTER (ident));
1048 TREE_CHAIN (prev) = TREE_CHAIN (proto);
1050 return_value = TREE_CHAIN (proto);
1054 /* Replace identifier with actual protocol node. */
1055 TREE_VALUE (proto) = p;
1060 return return_value;
1063 /* Create and push a decl for a built-in external variable or field NAME.
1065 TYPE is its data type. */
1068 create_builtin_decl (code, type, name)
1069 enum tree_code code;
1073 tree decl = build_decl (code, get_identifier (name), type);
1075 if (code == VAR_DECL)
1077 TREE_STATIC (decl) = 1;
1078 make_decl_rtl (decl, 0);
1082 DECL_ARTIFICIAL (decl) = 1;
1086 /* Find the decl for the constant string class. */
1089 setup_string_decl ()
1091 if (!string_class_decl)
1093 if (!constant_string_global_id)
1094 constant_string_global_id = get_identifier (STRING_OBJECT_GLOBAL_NAME);
1095 string_class_decl = lookup_name (constant_string_global_id);
1099 /* Purpose: "play" parser, creating/installing representations
1100 of the declarations that are required by Objective-C.
1104 type_spec--------->sc_spec
1105 (tree_list) (tree_list)
1108 identifier_node identifier_node */
1111 synth_module_prologue ()
1116 /* Defined in `objc.h' */
1117 objc_object_id = get_identifier (TAG_OBJECT);
1119 objc_object_reference = xref_tag (RECORD_TYPE, objc_object_id);
1121 id_type = build_pointer_type (objc_object_reference);
1123 objc_id_id = get_identifier (TYPE_ID);
1124 objc_class_id = get_identifier (TAG_CLASS);
1126 objc_class_type = build_pointer_type (xref_tag (RECORD_TYPE, objc_class_id));
1127 protocol_type = build_pointer_type (xref_tag (RECORD_TYPE,
1128 get_identifier (PROTOCOL_OBJECT_CLASS_NAME)));
1130 /* Declare type of selector-objects that represent an operation name. */
1132 /* `struct objc_selector *' */
1134 = build_pointer_type (xref_tag (RECORD_TYPE,
1135 get_identifier (TAG_SELECTOR)));
1137 /* Forward declare type, or else the prototype for msgSendSuper will
1140 super_p = build_pointer_type (xref_tag (RECORD_TYPE,
1141 get_identifier (TAG_SUPER)));
1144 /* id objc_msgSend (id, SEL, ...); */
1147 = build_function_type (id_type,
1148 tree_cons (NULL_TREE, id_type,
1149 tree_cons (NULL_TREE, selector_type,
1152 if (! flag_next_runtime)
1154 umsg_decl = build_decl (FUNCTION_DECL,
1155 get_identifier (TAG_MSGSEND), temp_type);
1156 DECL_EXTERNAL (umsg_decl) = 1;
1157 TREE_PUBLIC (umsg_decl) = 1;
1158 DECL_INLINE (umsg_decl) = 1;
1159 DECL_ARTIFICIAL (umsg_decl) = 1;
1161 make_decl_rtl (umsg_decl, NULL);
1162 pushdecl (umsg_decl);
1165 umsg_decl = builtin_function (TAG_MSGSEND, temp_type, 0, NOT_BUILT_IN,
1168 /* id objc_msgSendSuper (struct objc_super *, SEL, ...); */
1171 = build_function_type (id_type,
1172 tree_cons (NULL_TREE, super_p,
1173 tree_cons (NULL_TREE, selector_type,
1176 umsg_super_decl = builtin_function (TAG_MSGSENDSUPER,
1177 temp_type, 0, NOT_BUILT_IN,
1180 /* id objc_getClass (const char *); */
1182 temp_type = build_function_type (id_type,
1183 tree_cons (NULL_TREE,
1184 const_string_type_node,
1185 tree_cons (NULL_TREE, void_type_node,
1189 = builtin_function (TAG_GETCLASS, temp_type, 0, NOT_BUILT_IN,
1192 /* id objc_getMetaClass (const char *); */
1194 objc_get_meta_class_decl
1195 = builtin_function (TAG_GETMETACLASS, temp_type, 0, NOT_BUILT_IN,
1198 /* static SEL _OBJC_SELECTOR_TABLE[]; */
1200 if (! flag_next_runtime)
1202 if (flag_typed_selectors)
1204 /* Suppress outputting debug symbols, because
1205 dbxout_init hasn'r been called yet. */
1206 enum debug_info_type save_write_symbols = write_symbols;
1207 const struct gcc_debug_hooks *const save_hooks = debug_hooks;
1208 write_symbols = NO_DEBUG;
1209 debug_hooks = &do_nothing_debug_hooks;
1211 build_selector_template ();
1212 temp_type = build_array_type (objc_selector_template, NULL_TREE);
1214 write_symbols = save_write_symbols;
1215 debug_hooks = save_hooks;
1218 temp_type = build_array_type (selector_type, NULL_TREE);
1220 layout_type (temp_type);
1221 UOBJC_SELECTOR_TABLE_decl
1222 = create_builtin_decl (VAR_DECL, temp_type,
1223 "_OBJC_SELECTOR_TABLE");
1225 /* Avoid warning when not sending messages. */
1226 TREE_USED (UOBJC_SELECTOR_TABLE_decl) = 1;
1229 generate_forward_declaration_to_string_table ();
1231 /* Forward declare constant_string_id and constant_string_type. */
1232 if (!constant_string_class_name)
1233 constant_string_class_name = default_constant_string_class_name;
1235 constant_string_id = get_identifier (constant_string_class_name);
1236 constant_string_type = xref_tag (RECORD_TYPE, constant_string_id);
1239 /* Predefine the following data type:
1241 struct STRING_OBJECT_CLASS_NAME
1245 unsigned int length;
1249 build_string_class_template ()
1251 tree field_decl, field_decl_chain;
1253 field_decl = create_builtin_decl (FIELD_DECL, id_type, "isa");
1254 field_decl_chain = field_decl;
1256 field_decl = create_builtin_decl (FIELD_DECL,
1257 build_pointer_type (char_type_node),
1259 chainon (field_decl_chain, field_decl);
1261 field_decl = create_builtin_decl (FIELD_DECL, unsigned_type_node, "length");
1262 chainon (field_decl_chain, field_decl);
1264 finish_struct (constant_string_type, field_decl_chain, NULL_TREE);
1267 /* Custom build_string which sets TREE_TYPE! */
1270 my_build_string (len, str)
1274 return fix_string_type (build_string (len, str));
1277 /* Given a chain of STRING_CST's, build a static instance of
1278 NXConstantString which points at the concatenation of those strings.
1279 We place the string object in the __string_objects section of the
1280 __OBJC segment. The Objective-C runtime will initialize the isa
1281 pointers of the string objects to point at the NXConstantString
1285 build_objc_string_object (strings)
1288 tree string, initlist, constructor;
1291 if (lookup_interface (constant_string_id) == NULL_TREE)
1293 error ("cannot find interface declaration for `%s'",
1294 IDENTIFIER_POINTER (constant_string_id));
1295 return error_mark_node;
1298 add_class_reference (constant_string_id);
1300 if (TREE_CHAIN (strings))
1302 varray_type vstrings;
1303 VARRAY_TREE_INIT (vstrings, 32, "strings");
1305 for (; strings ; strings = TREE_CHAIN (strings))
1306 VARRAY_PUSH_TREE (vstrings, strings);
1308 string = combine_strings (vstrings);
1313 string = fix_string_type (string);
1315 TREE_SET_CODE (string, STRING_CST);
1316 length = TREE_STRING_LENGTH (string) - 1;
1318 /* We could not properly create NXConstantString in synth_module_prologue,
1319 because that's called before debugging is initialized. Do it now. */
1320 if (TYPE_FIELDS (constant_string_type) == NULL_TREE)
1321 build_string_class_template ();
1323 /* & ((NXConstantString) { NULL, string, length }) */
1325 if (flag_next_runtime)
1327 /* For the NeXT runtime, we can generate a literal reference
1328 to the string class, don't need to run a constructor. */
1329 setup_string_decl ();
1330 if (string_class_decl == NULL_TREE)
1332 error ("cannot find reference tag for class `%s'",
1333 IDENTIFIER_POINTER (constant_string_id));
1334 return error_mark_node;
1336 initlist = build_tree_list
1338 copy_node (build_unary_op (ADDR_EXPR, string_class_decl, 0)));
1342 initlist = build_tree_list (NULL_TREE, build_int_2 (0, 0));
1346 = tree_cons (NULL_TREE, copy_node (build_unary_op (ADDR_EXPR, string, 1)),
1348 initlist = tree_cons (NULL_TREE, build_int_2 (length, 0), initlist);
1349 constructor = objc_build_constructor (constant_string_type,
1350 nreverse (initlist));
1352 if (!flag_next_runtime)
1355 = objc_add_static_instance (constructor, constant_string_type);
1358 return (build_unary_op (ADDR_EXPR, constructor, 1));
1361 /* Declare a static instance of CLASS_DECL initialized by CONSTRUCTOR. */
1363 static GTY(()) int num_static_inst;
1365 objc_add_static_instance (constructor, class_decl)
1366 tree constructor, class_decl;
1371 /* Find the list of static instances for the CLASS_DECL. Create one if
1373 for (chain = &objc_static_instances;
1374 *chain && TREE_VALUE (*chain) != class_decl;
1375 chain = &TREE_CHAIN (*chain));
1378 *chain = tree_cons (NULL_TREE, class_decl, NULL_TREE);
1379 add_objc_string (TYPE_NAME (class_decl), class_names);
1382 sprintf (buf, "_OBJC_INSTANCE_%d", num_static_inst++);
1383 decl = build_decl (VAR_DECL, get_identifier (buf), class_decl);
1384 DECL_COMMON (decl) = 1;
1385 TREE_STATIC (decl) = 1;
1386 DECL_ARTIFICIAL (decl) = 1;
1387 DECL_INITIAL (decl) = constructor;
1389 /* We may be writing something else just now.
1390 Postpone till end of input. */
1391 DECL_DEFER_OUTPUT (decl) = 1;
1392 pushdecl_top_level (decl);
1393 rest_of_decl_compilation (decl, 0, 1, 0);
1395 /* Add the DECL to the head of this CLASS' list. */
1396 TREE_PURPOSE (*chain) = tree_cons (NULL_TREE, decl, TREE_PURPOSE (*chain));
1401 /* Build a static constant CONSTRUCTOR
1402 with type TYPE and elements ELTS. */
1405 objc_build_constructor (type, elts)
1408 tree constructor, f, e;
1410 /* ??? Most of the places that we build constructors, we don't fill in
1411 the type of integers properly. Convert them all en masse. */
1412 if (TREE_CODE (type) == ARRAY_TYPE)
1414 f = TREE_TYPE (type);
1415 if (TREE_CODE (f) == POINTER_TYPE || TREE_CODE (f) == INTEGER_TYPE)
1416 for (e = elts; e ; e = TREE_CHAIN (e))
1417 TREE_VALUE (e) = convert (f, TREE_VALUE (e));
1421 f = TYPE_FIELDS (type);
1422 for (e = elts; e && f; e = TREE_CHAIN (e), f = TREE_CHAIN (f))
1423 if (TREE_CODE (TREE_TYPE (f)) == POINTER_TYPE
1424 || TREE_CODE (TREE_TYPE (f)) == INTEGER_TYPE)
1425 TREE_VALUE (e) = convert (TREE_TYPE (f), TREE_VALUE (e));
1428 constructor = build_constructor (type, elts);
1429 TREE_CONSTANT (constructor) = 1;
1430 TREE_STATIC (constructor) = 1;
1431 TREE_READONLY (constructor) = 1;
1436 /* Take care of defining and initializing _OBJC_SYMBOLS. */
1438 /* Predefine the following data type:
1446 void *defs[cls_def_cnt + cat_def_cnt];
1450 build_objc_symtab_template ()
1452 tree field_decl, field_decl_chain, index;
1454 objc_symtab_template
1455 = start_struct (RECORD_TYPE, get_identifier (UTAG_SYMTAB));
1457 /* long sel_ref_cnt; */
1459 field_decl = create_builtin_decl (FIELD_DECL,
1460 long_integer_type_node,
1462 field_decl_chain = field_decl;
1466 field_decl = create_builtin_decl (FIELD_DECL,
1467 build_pointer_type (selector_type),
1469 chainon (field_decl_chain, field_decl);
1471 /* short cls_def_cnt; */
1473 field_decl = create_builtin_decl (FIELD_DECL,
1474 short_integer_type_node,
1476 chainon (field_decl_chain, field_decl);
1478 /* short cat_def_cnt; */
1480 field_decl = create_builtin_decl (FIELD_DECL,
1481 short_integer_type_node,
1483 chainon (field_decl_chain, field_decl);
1485 /* void *defs[cls_def_cnt + cat_def_cnt]; */
1487 if (!flag_next_runtime)
1488 index = build_index_type (build_int_2 (imp_count + cat_count, 0));
1490 index = build_index_type (build_int_2 (imp_count + cat_count - 1,
1491 imp_count == 0 && cat_count == 0
1493 field_decl = create_builtin_decl (FIELD_DECL,
1494 build_array_type (ptr_type_node, index),
1496 chainon (field_decl_chain, field_decl);
1498 finish_struct (objc_symtab_template, field_decl_chain, NULL_TREE);
1501 /* Create the initial value for the `defs' field of _objc_symtab.
1502 This is a CONSTRUCTOR. */
1505 init_def_list (type)
1508 tree expr, initlist = NULL_TREE;
1509 struct imp_entry *impent;
1512 for (impent = imp_list; impent; impent = impent->next)
1514 if (TREE_CODE (impent->imp_context) == CLASS_IMPLEMENTATION_TYPE)
1516 expr = build_unary_op (ADDR_EXPR, impent->class_decl, 0);
1517 initlist = tree_cons (NULL_TREE, expr, initlist);
1522 for (impent = imp_list; impent; impent = impent->next)
1524 if (TREE_CODE (impent->imp_context) == CATEGORY_IMPLEMENTATION_TYPE)
1526 expr = build_unary_op (ADDR_EXPR, impent->class_decl, 0);
1527 initlist = tree_cons (NULL_TREE, expr, initlist);
1531 if (!flag_next_runtime)
1533 /* statics = { ..., _OBJC_STATIC_INSTANCES, ... } */
1536 if (static_instances_decl)
1537 expr = build_unary_op (ADDR_EXPR, static_instances_decl, 0);
1539 expr = build_int_2 (0, 0);
1541 initlist = tree_cons (NULL_TREE, expr, initlist);
1544 return objc_build_constructor (type, nreverse (initlist));
1547 /* Construct the initial value for all of _objc_symtab. */
1550 init_objc_symtab (type)
1555 /* sel_ref_cnt = { ..., 5, ... } */
1557 initlist = build_tree_list (NULL_TREE, build_int_2 (0, 0));
1559 /* refs = { ..., _OBJC_SELECTOR_TABLE, ... } */
1561 if (flag_next_runtime || ! sel_ref_chain)
1562 initlist = tree_cons (NULL_TREE, build_int_2 (0, 0), initlist);
1564 initlist = tree_cons (NULL_TREE,
1565 build_unary_op (ADDR_EXPR,
1566 UOBJC_SELECTOR_TABLE_decl, 1),
1569 /* cls_def_cnt = { ..., 5, ... } */
1571 initlist = tree_cons (NULL_TREE, build_int_2 (imp_count, 0), initlist);
1573 /* cat_def_cnt = { ..., 5, ... } */
1575 initlist = tree_cons (NULL_TREE, build_int_2 (cat_count, 0), initlist);
1577 /* cls_def = { ..., { &Foo, &Bar, ...}, ... } */
1579 if (imp_count || cat_count || static_instances_decl)
1582 tree field = TYPE_FIELDS (type);
1583 field = TREE_CHAIN (TREE_CHAIN (TREE_CHAIN (TREE_CHAIN (field))));
1585 initlist = tree_cons (NULL_TREE, init_def_list (TREE_TYPE (field)),
1589 return objc_build_constructor (type, nreverse (initlist));
1592 /* Push forward-declarations of all the categories so that
1593 init_def_list can use them in a CONSTRUCTOR. */
1596 forward_declare_categories ()
1598 struct imp_entry *impent;
1599 tree sav = objc_implementation_context;
1601 for (impent = imp_list; impent; impent = impent->next)
1603 if (TREE_CODE (impent->imp_context) == CATEGORY_IMPLEMENTATION_TYPE)
1605 /* Set an invisible arg to synth_id_with_class_suffix. */
1606 objc_implementation_context = impent->imp_context;
1608 = create_builtin_decl (VAR_DECL, objc_category_template,
1609 IDENTIFIER_POINTER (synth_id_with_class_suffix ("_OBJC_CATEGORY", objc_implementation_context)));
1612 objc_implementation_context = sav;
1615 /* Create the declaration of _OBJC_SYMBOLS, with type `strict _objc_symtab'
1616 and initialized appropriately. */
1619 generate_objc_symtab_decl ()
1623 if (!objc_category_template)
1624 build_category_template ();
1626 /* forward declare categories */
1628 forward_declare_categories ();
1630 if (!objc_symtab_template)
1631 build_objc_symtab_template ();
1633 sc_spec = build_tree_list (NULL_TREE, ridpointers[(int) RID_STATIC]);
1635 UOBJC_SYMBOLS_decl = start_decl (get_identifier ("_OBJC_SYMBOLS"),
1636 tree_cons (NULL_TREE,
1637 objc_symtab_template, sc_spec),
1641 TREE_USED (UOBJC_SYMBOLS_decl) = 1;
1642 DECL_IGNORED_P (UOBJC_SYMBOLS_decl) = 1;
1643 DECL_ARTIFICIAL (UOBJC_SYMBOLS_decl) = 1;
1644 finish_decl (UOBJC_SYMBOLS_decl,
1645 init_objc_symtab (TREE_TYPE (UOBJC_SYMBOLS_decl)),
1650 init_module_descriptor (type)
1653 tree initlist, expr;
1655 /* version = { 1, ... } */
1657 expr = build_int_2 (OBJC_VERSION, 0);
1658 initlist = build_tree_list (NULL_TREE, expr);
1660 /* size = { ..., sizeof (struct objc_module), ... } */
1662 expr = size_in_bytes (objc_module_template);
1663 initlist = tree_cons (NULL_TREE, expr, initlist);
1665 /* name = { ..., "foo.m", ... } */
1667 expr = add_objc_string (get_identifier (input_filename), class_names);
1668 initlist = tree_cons (NULL_TREE, expr, initlist);
1670 /* symtab = { ..., _OBJC_SYMBOLS, ... } */
1672 if (UOBJC_SYMBOLS_decl)
1673 expr = build_unary_op (ADDR_EXPR, UOBJC_SYMBOLS_decl, 0);
1675 expr = build_int_2 (0, 0);
1676 initlist = tree_cons (NULL_TREE, expr, initlist);
1678 return objc_build_constructor (type, nreverse (initlist));
1681 /* Write out the data structures to describe Objective C classes defined.
1682 If appropriate, compile and output a setup function to initialize them.
1683 Return a symbol_ref to the function to call to initialize the Objective C
1684 data structures for this file (and perhaps for other files also).
1686 struct objc_module { ... } _OBJC_MODULE = { ... }; */
1689 build_module_descriptor ()
1691 tree decl_specs, field_decl, field_decl_chain;
1693 objc_module_template
1694 = start_struct (RECORD_TYPE, get_identifier (UTAG_MODULE));
1698 decl_specs = build_tree_list (NULL_TREE, ridpointers[(int) RID_LONG]);
1699 field_decl = get_identifier ("version");
1701 = grokfield (input_filename, lineno, field_decl, decl_specs, NULL_TREE);
1702 field_decl_chain = field_decl;
1706 decl_specs = build_tree_list (NULL_TREE, ridpointers[(int) RID_LONG]);
1707 field_decl = get_identifier ("size");
1709 = grokfield (input_filename, lineno, field_decl, decl_specs, NULL_TREE);
1710 chainon (field_decl_chain, field_decl);
1714 decl_specs = build_tree_list (NULL_TREE, ridpointers[(int) RID_CHAR]);
1715 field_decl = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("name"));
1717 = grokfield (input_filename, lineno, field_decl, decl_specs, NULL_TREE);
1718 chainon (field_decl_chain, field_decl);
1720 /* struct objc_symtab *symtab; */
1722 decl_specs = get_identifier (UTAG_SYMTAB);
1723 decl_specs = build_tree_list (NULL_TREE, xref_tag (RECORD_TYPE, decl_specs));
1724 field_decl = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("symtab"));
1726 = grokfield (input_filename, lineno, field_decl, decl_specs, NULL_TREE);
1727 chainon (field_decl_chain, field_decl);
1729 finish_struct (objc_module_template, field_decl_chain, NULL_TREE);
1731 /* Create an instance of "objc_module". */
1733 decl_specs = tree_cons (NULL_TREE, objc_module_template,
1734 build_tree_list (NULL_TREE,
1735 ridpointers[(int) RID_STATIC]));
1737 UOBJC_MODULES_decl = start_decl (get_identifier ("_OBJC_MODULES"),
1738 decl_specs, 1, NULL_TREE);
1740 DECL_ARTIFICIAL (UOBJC_MODULES_decl) = 1;
1741 DECL_IGNORED_P (UOBJC_MODULES_decl) = 1;
1742 DECL_CONTEXT (UOBJC_MODULES_decl) = NULL_TREE;
1744 finish_decl (UOBJC_MODULES_decl,
1745 init_module_descriptor (TREE_TYPE (UOBJC_MODULES_decl)),
1748 /* Mark the decl to avoid "defined but not used" warning. */
1749 DECL_IN_SYSTEM_HEADER (UOBJC_MODULES_decl) = 1;
1751 /* Generate a constructor call for the module descriptor.
1752 This code was generated by reading the grammar rules
1753 of c-parse.in; Therefore, it may not be the most efficient
1754 way of generating the requisite code. */
1756 if (flag_next_runtime)
1760 tree parms, execclass_decl, decelerator, void_list_node_1;
1761 tree init_function_name, init_function_decl;
1763 /* Declare void __objc_execClass (void *); */
1765 void_list_node_1 = build_tree_list (NULL_TREE, void_type_node);
1766 execclass_decl = build_decl (FUNCTION_DECL,
1767 get_identifier (TAG_EXECCLASS),
1768 build_function_type (void_type_node,
1769 tree_cons (NULL_TREE, ptr_type_node,
1770 void_list_node_1)));
1771 DECL_EXTERNAL (execclass_decl) = 1;
1772 DECL_ARTIFICIAL (execclass_decl) = 1;
1773 TREE_PUBLIC (execclass_decl) = 1;
1774 pushdecl (execclass_decl);
1775 rest_of_decl_compilation (execclass_decl, 0, 0, 0);
1776 assemble_external (execclass_decl);
1778 /* void _GLOBAL_$I$<gnyf> () {objc_execClass (&L_OBJC_MODULES);} */
1780 init_function_name = get_file_function_name ('I');
1781 start_function (void_list_node_1,
1782 build_nt (CALL_EXPR, init_function_name,
1783 tree_cons (NULL_TREE, NULL_TREE,
1787 store_parm_decls ();
1789 init_function_decl = current_function_decl;
1790 TREE_PUBLIC (init_function_decl) = ! targetm.have_ctors_dtors;
1791 TREE_USED (init_function_decl) = 1;
1792 /* Don't let this one be deferred. */
1793 DECL_INLINE (init_function_decl) = 0;
1794 DECL_UNINLINABLE (init_function_decl) = 1;
1795 current_function_cannot_inline
1796 = "static constructors and destructors cannot be inlined";
1799 = build_tree_list (NULL_TREE,
1800 build_unary_op (ADDR_EXPR, UOBJC_MODULES_decl, 0));
1801 decelerator = build_function_call (execclass_decl, parms);
1803 c_expand_expr_stmt (decelerator);
1805 finish_function (0, 0);
1807 return XEXP (DECL_RTL (init_function_decl), 0);
1811 /* extern const char _OBJC_STRINGS[]; */
1814 generate_forward_declaration_to_string_table ()
1816 tree sc_spec, decl_specs, expr_decl;
1818 sc_spec = tree_cons (NULL_TREE, ridpointers[(int) RID_EXTERN], NULL_TREE);
1819 decl_specs = tree_cons (NULL_TREE, ridpointers[(int) RID_CHAR], sc_spec);
1822 = build_nt (ARRAY_REF, get_identifier ("_OBJC_STRINGS"), NULL_TREE);
1824 UOBJC_STRINGS_decl = define_decl (expr_decl, decl_specs);
1827 /* Return the DECL of the string IDENT in the SECTION. */
1830 get_objc_string_decl (ident, section)
1832 enum string_section section;
1836 if (section == class_names)
1837 chain = class_names_chain;
1838 else if (section == meth_var_names)
1839 chain = meth_var_names_chain;
1840 else if (section == meth_var_types)
1841 chain = meth_var_types_chain;
1845 for (; chain != 0; chain = TREE_CHAIN (chain))
1846 if (TREE_VALUE (chain) == ident)
1847 return (TREE_PURPOSE (chain));
1853 /* Output references to all statically allocated objects. Return the DECL
1854 for the array built. */
1857 generate_static_references ()
1859 tree decls = NULL_TREE, ident, decl_spec, expr_decl, expr = NULL_TREE;
1860 tree class_name, class, decl, initlist;
1861 tree cl_chain, in_chain, type;
1862 int num_inst, num_class;
1865 if (flag_next_runtime)
1868 for (cl_chain = objc_static_instances, num_class = 0;
1869 cl_chain; cl_chain = TREE_CHAIN (cl_chain), num_class++)
1871 for (num_inst = 0, in_chain = TREE_PURPOSE (cl_chain);
1872 in_chain; num_inst++, in_chain = TREE_CHAIN (in_chain));
1874 sprintf (buf, "_OBJC_STATIC_INSTANCES_%d", num_class);
1875 ident = get_identifier (buf);
1877 expr_decl = build_nt (ARRAY_REF, ident, NULL_TREE);
1878 decl_spec = tree_cons (NULL_TREE, build_pointer_type (void_type_node),
1879 build_tree_list (NULL_TREE,
1880 ridpointers[(int) RID_STATIC]));
1881 decl = start_decl (expr_decl, decl_spec, 1, NULL_TREE);
1882 DECL_CONTEXT (decl) = 0;
1883 DECL_ARTIFICIAL (decl) = 1;
1885 /* Output {class_name, ...}. */
1886 class = TREE_VALUE (cl_chain);
1887 class_name = get_objc_string_decl (TYPE_NAME (class), class_names);
1888 initlist = build_tree_list (NULL_TREE,
1889 build_unary_op (ADDR_EXPR, class_name, 1));
1891 /* Output {..., instance, ...}. */
1892 for (in_chain = TREE_PURPOSE (cl_chain);
1893 in_chain; in_chain = TREE_CHAIN (in_chain))
1895 expr = build_unary_op (ADDR_EXPR, TREE_VALUE (in_chain), 1);
1896 initlist = tree_cons (NULL_TREE, expr, initlist);
1899 /* Output {..., NULL}. */
1900 initlist = tree_cons (NULL_TREE, build_int_2 (0, 0), initlist);
1902 expr = objc_build_constructor (TREE_TYPE (decl), nreverse (initlist));
1903 finish_decl (decl, expr, NULL_TREE);
1904 TREE_USED (decl) = 1;
1906 type = build_array_type (build_pointer_type (void_type_node), 0);
1907 decl = build_decl (VAR_DECL, ident, type);
1908 TREE_USED (decl) = 1;
1909 TREE_STATIC (decl) = 1;
1911 = tree_cons (NULL_TREE, build_unary_op (ADDR_EXPR, decl, 1), decls);
1914 decls = tree_cons (NULL_TREE, build_int_2 (0, 0), decls);
1915 ident = get_identifier ("_OBJC_STATIC_INSTANCES");
1916 expr_decl = build_nt (ARRAY_REF, ident, NULL_TREE);
1917 decl_spec = tree_cons (NULL_TREE, build_pointer_type (void_type_node),
1918 build_tree_list (NULL_TREE,
1919 ridpointers[(int) RID_STATIC]));
1920 static_instances_decl
1921 = start_decl (expr_decl, decl_spec, 1, NULL_TREE);
1922 TREE_USED (static_instances_decl) = 1;
1923 DECL_CONTEXT (static_instances_decl) = 0;
1924 DECL_ARTIFICIAL (static_instances_decl) = 1;
1925 expr = objc_build_constructor (TREE_TYPE (static_instances_decl),
1927 finish_decl (static_instances_decl, expr, NULL_TREE);
1930 /* Output all strings. */
1935 tree sc_spec, decl_specs, expr_decl;
1936 tree chain, string_expr;
1939 for (chain = class_names_chain; chain; chain = TREE_CHAIN (chain))
1941 string = TREE_VALUE (chain);
1942 decl = TREE_PURPOSE (chain);
1944 = tree_cons (NULL_TREE, ridpointers[(int) RID_STATIC], NULL_TREE);
1945 decl_specs = tree_cons (NULL_TREE, ridpointers[(int) RID_CHAR], sc_spec);
1946 expr_decl = build_nt (ARRAY_REF, DECL_NAME (decl), NULL_TREE);
1947 decl = start_decl (expr_decl, decl_specs, 1, NULL_TREE);
1948 DECL_CONTEXT (decl) = NULL_TREE;
1949 string_expr = my_build_string (IDENTIFIER_LENGTH (string) + 1,
1950 IDENTIFIER_POINTER (string));
1951 finish_decl (decl, string_expr, NULL_TREE);
1954 for (chain = meth_var_names_chain; chain; chain = TREE_CHAIN (chain))
1956 string = TREE_VALUE (chain);
1957 decl = TREE_PURPOSE (chain);
1959 = tree_cons (NULL_TREE, ridpointers[(int) RID_STATIC], NULL_TREE);
1960 decl_specs = tree_cons (NULL_TREE, ridpointers[(int) RID_CHAR], sc_spec);
1961 expr_decl = build_nt (ARRAY_REF, DECL_NAME (decl), NULL_TREE);
1962 decl = start_decl (expr_decl, decl_specs, 1, NULL_TREE);
1963 DECL_CONTEXT (decl) = NULL_TREE;
1964 string_expr = my_build_string (IDENTIFIER_LENGTH (string) + 1,
1965 IDENTIFIER_POINTER (string));
1966 finish_decl (decl, string_expr, NULL_TREE);
1969 for (chain = meth_var_types_chain; chain; chain = TREE_CHAIN (chain))
1971 string = TREE_VALUE (chain);
1972 decl = TREE_PURPOSE (chain);
1974 = tree_cons (NULL_TREE, ridpointers[(int) RID_STATIC], NULL_TREE);
1975 decl_specs = tree_cons (NULL_TREE, ridpointers[(int) RID_CHAR], sc_spec);
1976 expr_decl = build_nt (ARRAY_REF, DECL_NAME (decl), NULL_TREE);
1977 decl = start_decl (expr_decl, decl_specs, 1, NULL_TREE);
1978 DECL_CONTEXT (decl) = NULL_TREE;
1979 string_expr = my_build_string (IDENTIFIER_LENGTH (string) + 1,
1980 IDENTIFIER_POINTER (string));
1981 finish_decl (decl, string_expr, NULL_TREE);
1985 static GTY(()) int selector_reference_idx;
1987 build_selector_reference_decl ()
1992 sprintf (buf, "_OBJC_SELECTOR_REFERENCES_%d", selector_reference_idx++);
1994 ident = get_identifier (buf);
1996 decl = build_decl (VAR_DECL, ident, selector_type);
1997 DECL_EXTERNAL (decl) = 1;
1998 TREE_PUBLIC (decl) = 1;
1999 TREE_USED (decl) = 1;
2000 TREE_READONLY (decl) = 1;
2001 DECL_ARTIFICIAL (decl) = 1;
2002 DECL_CONTEXT (decl) = 0;
2004 make_decl_rtl (decl, 0);
2005 pushdecl_top_level (decl);
2010 /* Just a handy wrapper for add_objc_string. */
2013 build_selector (ident)
2016 tree expr = add_objc_string (ident, meth_var_names);
2017 if (flag_typed_selectors)
2020 return build_c_cast (selector_type, expr); /* cast! */
2024 build_selector_translation_table ()
2026 tree sc_spec, decl_specs;
2027 tree chain, initlist = NULL_TREE;
2029 tree decl = NULL_TREE, var_decl, name;
2031 for (chain = sel_ref_chain; chain; chain = TREE_CHAIN (chain))
2035 if (warn_selector && objc_implementation_context)
2039 for (method_chain = meth_var_names_chain;
2041 method_chain = TREE_CHAIN (method_chain))
2043 if (TREE_VALUE (method_chain) == TREE_VALUE (chain))
2051 /* Adjust line number for warning message. */
2052 int save_lineno = lineno;
2053 if (flag_next_runtime && TREE_PURPOSE (chain))
2054 lineno = DECL_SOURCE_LINE (TREE_PURPOSE (chain));
2055 warning ("creating selector for non existant method %s",
2056 IDENTIFIER_POINTER (TREE_VALUE (chain)));
2057 lineno = save_lineno;
2061 expr = build_selector (TREE_VALUE (chain));
2063 if (flag_next_runtime)
2065 name = DECL_NAME (TREE_PURPOSE (chain));
2067 sc_spec = build_tree_list (NULL_TREE, ridpointers[(int) RID_STATIC]);
2069 /* static SEL _OBJC_SELECTOR_REFERENCES_n = ...; */
2070 decl_specs = tree_cons (NULL_TREE, selector_type, sc_spec);
2074 /* The `decl' that is returned from start_decl is the one that we
2075 forward declared in `build_selector_reference' */
2076 decl = start_decl (var_decl, decl_specs, 1, NULL_TREE );
2079 /* add one for the '\0' character */
2080 offset += IDENTIFIER_LENGTH (TREE_VALUE (chain)) + 1;
2082 if (flag_next_runtime)
2083 finish_decl (decl, expr, NULL_TREE);
2086 if (flag_typed_selectors)
2088 tree eltlist = NULL_TREE;
2089 tree encoding = get_proto_encoding (TREE_PURPOSE (chain));
2090 eltlist = tree_cons (NULL_TREE, expr, NULL_TREE);
2091 eltlist = tree_cons (NULL_TREE, encoding, eltlist);
2092 expr = objc_build_constructor (objc_selector_template,
2093 nreverse (eltlist));
2095 initlist = tree_cons (NULL_TREE, expr, initlist);
2100 if (! flag_next_runtime)
2102 /* Cause the variable and its initial value to be actually output. */
2103 DECL_EXTERNAL (UOBJC_SELECTOR_TABLE_decl) = 0;
2104 TREE_STATIC (UOBJC_SELECTOR_TABLE_decl) = 1;
2105 /* NULL terminate the list and fix the decl for output. */
2106 initlist = tree_cons (NULL_TREE, build_int_2 (0, 0), initlist);
2107 DECL_INITIAL (UOBJC_SELECTOR_TABLE_decl) = objc_ellipsis_node;
2108 initlist = objc_build_constructor (TREE_TYPE (UOBJC_SELECTOR_TABLE_decl),
2109 nreverse (initlist));
2110 finish_decl (UOBJC_SELECTOR_TABLE_decl, initlist, NULL_TREE);
2111 current_function_decl = NULL_TREE;
2116 get_proto_encoding (proto)
2124 if (! METHOD_ENCODING (proto))
2126 tmp_decl = build_tmp_function_decl ();
2127 hack_method_prototype (proto, tmp_decl);
2128 encoding = encode_method_prototype (proto, tmp_decl);
2129 METHOD_ENCODING (proto) = encoding;
2132 encoding = METHOD_ENCODING (proto);
2134 return add_objc_string (encoding, meth_var_types);
2137 return build_int_2 (0, 0);
2140 /* sel_ref_chain is a list whose "value" fields will be instances of
2141 identifier_node that represent the selector. */
2144 build_typed_selector_reference (ident, prototype)
2145 tree ident, prototype;
2147 tree *chain = &sel_ref_chain;
2153 if (TREE_PURPOSE (*chain) == prototype && TREE_VALUE (*chain) == ident)
2154 goto return_at_index;
2157 chain = &TREE_CHAIN (*chain);
2160 *chain = tree_cons (prototype, ident, NULL_TREE);
2163 expr = build_unary_op (ADDR_EXPR,
2164 build_array_ref (UOBJC_SELECTOR_TABLE_decl,
2165 build_int_2 (index, 0)),
2167 return build_c_cast (selector_type, expr);
2171 build_selector_reference (ident)
2174 tree *chain = &sel_ref_chain;
2180 if (TREE_VALUE (*chain) == ident)
2181 return (flag_next_runtime
2182 ? TREE_PURPOSE (*chain)
2183 : build_array_ref (UOBJC_SELECTOR_TABLE_decl,
2184 build_int_2 (index, 0)));
2187 chain = &TREE_CHAIN (*chain);
2190 expr = build_selector_reference_decl ();
2192 *chain = tree_cons (expr, ident, NULL_TREE);
2194 return (flag_next_runtime
2196 : build_array_ref (UOBJC_SELECTOR_TABLE_decl,
2197 build_int_2 (index, 0)));
2200 static GTY(()) int class_reference_idx;
2202 build_class_reference_decl ()
2207 sprintf (buf, "_OBJC_CLASS_REFERENCES_%d", class_reference_idx++);
2209 ident = get_identifier (buf);
2211 decl = build_decl (VAR_DECL, ident, objc_class_type);
2212 DECL_EXTERNAL (decl) = 1;
2213 TREE_PUBLIC (decl) = 1;
2214 TREE_USED (decl) = 1;
2215 TREE_READONLY (decl) = 1;
2216 DECL_CONTEXT (decl) = 0;
2217 DECL_ARTIFICIAL (decl) = 1;
2219 make_decl_rtl (decl, 0);
2220 pushdecl_top_level (decl);
2225 /* Create a class reference, but don't create a variable to reference
2229 add_class_reference (ident)
2234 if ((chain = cls_ref_chain))
2239 if (ident == TREE_VALUE (chain))
2243 chain = TREE_CHAIN (chain);
2247 /* Append to the end of the list */
2248 TREE_CHAIN (tail) = tree_cons (NULL_TREE, ident, NULL_TREE);
2251 cls_ref_chain = tree_cons (NULL_TREE, ident, NULL_TREE);
2254 /* Get a class reference, creating it if necessary. Also create the
2255 reference variable. */
2258 get_class_reference (ident)
2261 if (flag_next_runtime)
2266 for (chain = &cls_ref_chain; *chain; chain = &TREE_CHAIN (*chain))
2267 if (TREE_VALUE (*chain) == ident)
2269 if (! TREE_PURPOSE (*chain))
2270 TREE_PURPOSE (*chain) = build_class_reference_decl ();
2272 return TREE_PURPOSE (*chain);
2275 decl = build_class_reference_decl ();
2276 *chain = tree_cons (decl, ident, NULL_TREE);
2283 add_class_reference (ident);
2285 params = build_tree_list (NULL_TREE,
2286 my_build_string (IDENTIFIER_LENGTH (ident) + 1,
2287 IDENTIFIER_POINTER (ident)));
2289 assemble_external (objc_get_class_decl);
2290 return build_function_call (objc_get_class_decl, params);
2294 /* For each string section we have a chain which maps identifier nodes
2295 to decls for the strings. */
2298 add_objc_string (ident, section)
2300 enum string_section section;
2304 if (section == class_names)
2305 chain = &class_names_chain;
2306 else if (section == meth_var_names)
2307 chain = &meth_var_names_chain;
2308 else if (section == meth_var_types)
2309 chain = &meth_var_types_chain;
2315 if (TREE_VALUE (*chain) == ident)
2316 return build_unary_op (ADDR_EXPR, TREE_PURPOSE (*chain), 1);
2318 chain = &TREE_CHAIN (*chain);
2321 decl = build_objc_string_decl (section);
2323 *chain = tree_cons (decl, ident, NULL_TREE);
2325 return build_unary_op (ADDR_EXPR, decl, 1);
2328 static GTY(()) int class_names_idx;
2329 static GTY(()) int meth_var_names_idx;
2330 static GTY(()) int meth_var_types_idx;
2333 build_objc_string_decl (section)
2334 enum string_section section;
2339 if (section == class_names)
2340 sprintf (buf, "_OBJC_CLASS_NAME_%d", class_names_idx++);
2341 else if (section == meth_var_names)
2342 sprintf (buf, "_OBJC_METH_VAR_NAME_%d", meth_var_names_idx++);
2343 else if (section == meth_var_types)
2344 sprintf (buf, "_OBJC_METH_VAR_TYPE_%d", meth_var_types_idx++);
2346 ident = get_identifier (buf);
2348 decl = build_decl (VAR_DECL, ident, build_array_type (char_type_node, 0));
2349 DECL_EXTERNAL (decl) = 1;
2350 TREE_PUBLIC (decl) = 1;
2351 TREE_USED (decl) = 1;
2352 TREE_READONLY (decl) = 1;
2353 TREE_CONSTANT (decl) = 1;
2354 DECL_CONTEXT (decl) = 0;
2355 DECL_ARTIFICIAL (decl) = 1;
2357 make_decl_rtl (decl, 0);
2358 pushdecl_top_level (decl);
2365 objc_declare_alias (alias_ident, class_ident)
2369 if (is_class_name (class_ident) != class_ident)
2370 warning ("cannot find class `%s'", IDENTIFIER_POINTER (class_ident));
2371 else if (is_class_name (alias_ident))
2372 warning ("class `%s' already exists", IDENTIFIER_POINTER (alias_ident));
2374 alias_chain = tree_cons (class_ident, alias_ident, alias_chain);
2378 objc_declare_class (ident_list)
2383 for (list = ident_list; list; list = TREE_CHAIN (list))
2385 tree ident = TREE_VALUE (list);
2388 if ((decl = lookup_name (ident)))
2390 error ("`%s' redeclared as different kind of symbol",
2391 IDENTIFIER_POINTER (ident));
2392 error_with_decl (decl, "previous declaration of `%s'");
2395 if (! is_class_name (ident))
2397 tree record = xref_tag (RECORD_TYPE, ident);
2398 TREE_STATIC_TEMPLATE (record) = 1;
2399 class_chain = tree_cons (NULL_TREE, ident, class_chain);
2405 is_class_name (ident)
2410 if (lookup_interface (ident))
2413 for (chain = class_chain; chain; chain = TREE_CHAIN (chain))
2415 if (ident == TREE_VALUE (chain))
2419 for (chain = alias_chain; chain; chain = TREE_CHAIN (chain))
2421 if (ident == TREE_VALUE (chain))
2422 return TREE_PURPOSE (chain);
2432 /* NB: This function may be called before the ObjC front-end
2433 has been initialized, in which case ID_TYPE will be NULL. */
2434 return (id_type && ident && TYPE_P (ident) && IS_ID (ident))
2440 lookup_interface (ident)
2445 for (chain = interface_chain; chain; chain = TREE_CHAIN (chain))
2447 if (ident == CLASS_NAME (chain))
2453 /* Used by: build_private_template, continue_class,
2454 and for @defs constructs. */
2457 get_class_ivars (interface)
2460 tree my_name, super_name, ivar_chain;
2462 my_name = CLASS_NAME (interface);
2463 super_name = CLASS_SUPER_NAME (interface);
2464 ivar_chain = CLASS_IVARS (interface);
2466 /* Save off a pristine copy of the leaf ivars (i.e, those not
2467 inherited from a super class). */
2468 if (!CLASS_OWN_IVARS (interface))
2469 CLASS_OWN_IVARS (interface) = copy_list (ivar_chain);
2474 tree super_interface = lookup_interface (super_name);
2476 if (!super_interface)
2478 /* fatal did not work with 2 args...should fix */
2479 error ("cannot find interface declaration for `%s', superclass of `%s'",
2480 IDENTIFIER_POINTER (super_name),
2481 IDENTIFIER_POINTER (my_name));
2482 exit (FATAL_EXIT_CODE);
2485 if (super_interface == interface)
2486 fatal_error ("circular inheritance in interface declaration for `%s'",
2487 IDENTIFIER_POINTER (super_name));
2489 interface = super_interface;
2490 my_name = CLASS_NAME (interface);
2491 super_name = CLASS_SUPER_NAME (interface);
2493 op1 = CLASS_OWN_IVARS (interface);
2496 tree head = copy_list (op1);
2498 /* Prepend super class ivars...make a copy of the list, we
2499 do not want to alter the original. */
2500 chainon (head, ivar_chain);
2507 /* struct <classname> {
2508 struct objc_class *isa;
2513 build_private_template (class)
2518 if (CLASS_STATIC_TEMPLATE (class))
2520 uprivate_record = CLASS_STATIC_TEMPLATE (class);
2521 ivar_context = TYPE_FIELDS (CLASS_STATIC_TEMPLATE (class));
2525 uprivate_record = start_struct (RECORD_TYPE, CLASS_NAME (class));
2527 ivar_context = get_class_ivars (class);
2529 finish_struct (uprivate_record, ivar_context, NULL_TREE);
2531 CLASS_STATIC_TEMPLATE (class) = uprivate_record;
2533 /* mark this record as class template - for class type checking */
2534 TREE_STATIC_TEMPLATE (uprivate_record) = 1;
2538 = groktypename (build_tree_list (build_tree_list (NULL_TREE,
2540 build1 (INDIRECT_REF, NULL_TREE,
2543 return ivar_context;
2546 /* Begin code generation for protocols... */
2548 /* struct objc_protocol {
2549 char *protocol_name;
2550 struct objc_protocol **protocol_list;
2551 struct objc_method_desc *instance_methods;
2552 struct objc_method_desc *class_methods;
2556 build_protocol_template ()
2558 tree decl_specs, field_decl, field_decl_chain;
2561 template = start_struct (RECORD_TYPE, get_identifier (UTAG_PROTOCOL));
2563 /* struct objc_class *isa; */
2565 decl_specs = build_tree_list (NULL_TREE, xref_tag (RECORD_TYPE,
2566 get_identifier (UTAG_CLASS)));
2567 field_decl = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("isa"));
2569 = grokfield (input_filename, lineno, field_decl, decl_specs, NULL_TREE);
2570 field_decl_chain = field_decl;
2572 /* char *protocol_name; */
2574 decl_specs = build_tree_list (NULL_TREE, ridpointers[(int) RID_CHAR]);
2576 = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("protocol_name"));
2578 = grokfield (input_filename, lineno, field_decl, decl_specs, NULL_TREE);
2579 chainon (field_decl_chain, field_decl);
2581 /* struct objc_protocol **protocol_list; */
2583 decl_specs = build_tree_list (NULL_TREE, template);
2585 = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("protocol_list"));
2586 field_decl = build1 (INDIRECT_REF, NULL_TREE, field_decl);
2588 = grokfield (input_filename, lineno, field_decl, decl_specs, NULL_TREE);
2589 chainon (field_decl_chain, field_decl);
2591 /* struct objc_method_list *instance_methods; */
2594 = build_tree_list (NULL_TREE,
2595 xref_tag (RECORD_TYPE,
2596 get_identifier (UTAG_METHOD_PROTOTYPE_LIST)));
2598 = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("instance_methods"));
2600 = grokfield (input_filename, lineno, field_decl, decl_specs, NULL_TREE);
2601 chainon (field_decl_chain, field_decl);
2603 /* struct objc_method_list *class_methods; */
2606 = build_tree_list (NULL_TREE,
2607 xref_tag (RECORD_TYPE,
2608 get_identifier (UTAG_METHOD_PROTOTYPE_LIST)));
2610 = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("class_methods"));
2612 = grokfield (input_filename, lineno, field_decl, decl_specs, NULL_TREE);
2613 chainon (field_decl_chain, field_decl);
2615 return finish_struct (template, field_decl_chain, NULL_TREE);
2619 build_descriptor_table_initializer (type, entries)
2623 tree initlist = NULL_TREE;
2627 tree eltlist = NULL_TREE;
2630 = tree_cons (NULL_TREE,
2631 build_selector (METHOD_SEL_NAME (entries)), NULL_TREE);
2633 = tree_cons (NULL_TREE,
2634 add_objc_string (METHOD_ENCODING (entries),
2639 = tree_cons (NULL_TREE,
2640 objc_build_constructor (type, nreverse (eltlist)),
2643 entries = TREE_CHAIN (entries);
2647 return objc_build_constructor (build_array_type (type, 0),
2648 nreverse (initlist));
2651 /* struct objc_method_prototype_list {
2653 struct objc_method_prototype {
2660 build_method_prototype_list_template (list_type, size)
2664 tree objc_ivar_list_record;
2665 tree decl_specs, field_decl, field_decl_chain;
2667 /* Generate an unnamed struct definition. */
2669 objc_ivar_list_record = start_struct (RECORD_TYPE, NULL_TREE);
2671 /* int method_count; */
2673 decl_specs = build_tree_list (NULL_TREE, ridpointers[(int) RID_INT]);
2674 field_decl = get_identifier ("method_count");
2677 = grokfield (input_filename, lineno, field_decl, decl_specs, NULL_TREE);
2678 field_decl_chain = field_decl;
2680 /* struct objc_method method_list[]; */
2682 decl_specs = build_tree_list (NULL_TREE, list_type);
2683 field_decl = build_nt (ARRAY_REF, get_identifier ("method_list"),
2684 build_int_2 (size, 0));
2687 = grokfield (input_filename, lineno, field_decl, decl_specs, NULL_TREE);
2688 chainon (field_decl_chain, field_decl);
2690 finish_struct (objc_ivar_list_record, field_decl_chain, NULL_TREE);
2692 return objc_ivar_list_record;
2696 build_method_prototype_template ()
2699 tree decl_specs, field_decl, field_decl_chain;
2702 = start_struct (RECORD_TYPE, get_identifier (UTAG_METHOD_PROTOTYPE));
2704 /* struct objc_selector *_cmd; */
2705 decl_specs = tree_cons (NULL_TREE, xref_tag (RECORD_TYPE,
2706 get_identifier (TAG_SELECTOR)), NULL_TREE);
2707 field_decl = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("_cmd"));
2710 = grokfield (input_filename, lineno, field_decl, decl_specs, NULL_TREE);
2711 field_decl_chain = field_decl;
2713 decl_specs = tree_cons (NULL_TREE, ridpointers[(int) RID_CHAR], NULL_TREE);
2715 = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("method_types"));
2717 = grokfield (input_filename, lineno, field_decl, decl_specs, NULL_TREE);
2718 chainon (field_decl_chain, field_decl);
2720 finish_struct (proto_record, field_decl_chain, NULL_TREE);
2722 return proto_record;
2725 /* True if last call to forwarding_offset yielded a register offset. */
2726 static int offset_is_register;
2729 forwarding_offset (parm)
2732 int offset_in_bytes;
2734 if (GET_CODE (DECL_INCOMING_RTL (parm)) == MEM)
2736 rtx addr = XEXP (DECL_INCOMING_RTL (parm), 0);
2738 /* ??? Here we assume that the parm address is indexed
2739 off the frame pointer or arg pointer.
2740 If that is not true, we produce meaningless results,
2741 but do not crash. */
2742 if (GET_CODE (addr) == PLUS
2743 && GET_CODE (XEXP (addr, 1)) == CONST_INT)
2744 offset_in_bytes = INTVAL (XEXP (addr, 1));
2746 offset_in_bytes = 0;
2748 offset_in_bytes += OBJC_FORWARDING_STACK_OFFSET;
2749 offset_is_register = 0;
2751 else if (GET_CODE (DECL_INCOMING_RTL (parm)) == REG)
2753 int regno = REGNO (DECL_INCOMING_RTL (parm));
2754 offset_in_bytes = apply_args_register_offset (regno);
2755 offset_is_register = 1;
2760 /* This is the case where the parm is passed as an int or double
2761 and it is converted to a char, short or float and stored back
2762 in the parmlist. In this case, describe the parm
2763 with the variable's declared type, and adjust the address
2764 if the least significant bytes (which we are using) are not
2766 if (BYTES_BIG_ENDIAN && TREE_TYPE (parm) != DECL_ARG_TYPE (parm))
2767 offset_in_bytes += (GET_MODE_SIZE (TYPE_MODE (DECL_ARG_TYPE (parm)))
2768 - GET_MODE_SIZE (GET_MODE (DECL_RTL (parm))));
2770 return offset_in_bytes;
2774 encode_method_prototype (method_decl, func_decl)
2781 HOST_WIDE_INT max_parm_end = 0;
2785 /* ONEWAY and BYCOPY, for remote object are the only method qualifiers. */
2786 encode_type_qualifiers (TREE_PURPOSE (TREE_TYPE (method_decl)));
2789 encode_type (TREE_TYPE (TREE_TYPE (func_decl)),
2790 obstack_object_size (&util_obstack),
2791 OBJC_ENCODE_INLINE_DEFS);
2794 for (parms = DECL_ARGUMENTS (func_decl); parms;
2795 parms = TREE_CHAIN (parms))
2797 HOST_WIDE_INT parm_end = (forwarding_offset (parms)
2798 + int_size_in_bytes (TREE_TYPE (parms)));
2800 if (!offset_is_register && max_parm_end < parm_end)
2801 max_parm_end = parm_end;
2804 stack_size = max_parm_end - OBJC_FORWARDING_MIN_OFFSET;
2806 sprintf (buf, "%d", stack_size);
2807 obstack_grow (&util_obstack, buf, strlen (buf));
2809 user_args = METHOD_SEL_ARGS (method_decl);
2811 /* Argument types. */
2812 for (parms = DECL_ARGUMENTS (func_decl), i = 0; parms;
2813 parms = TREE_CHAIN (parms), i++)
2815 /* Process argument qualifiers for user supplied arguments. */
2818 encode_type_qualifiers (TREE_PURPOSE (TREE_TYPE (user_args)));
2819 user_args = TREE_CHAIN (user_args);
2823 encode_type (TREE_TYPE (parms),
2824 obstack_object_size (&util_obstack),
2825 OBJC_ENCODE_INLINE_DEFS);
2827 /* Compute offset. */
2828 sprintf (buf, "%d", forwarding_offset (parms));
2830 /* Indicate register. */
2831 if (offset_is_register)
2832 obstack_1grow (&util_obstack, '+');
2834 obstack_grow (&util_obstack, buf, strlen (buf));
2837 obstack_1grow (&util_obstack, '\0');
2838 result = get_identifier (obstack_finish (&util_obstack));
2839 obstack_free (&util_obstack, util_firstobj);
2844 generate_descriptor_table (type, name, size, list, proto)
2851 tree sc_spec, decl_specs, decl, initlist;
2853 sc_spec = tree_cons (NULL_TREE, ridpointers[(int) RID_STATIC], NULL_TREE);
2854 decl_specs = tree_cons (NULL_TREE, type, sc_spec);
2856 decl = start_decl (synth_id_with_class_suffix (name, proto),
2857 decl_specs, 1, NULL_TREE);
2858 DECL_CONTEXT (decl) = NULL_TREE;
2860 initlist = build_tree_list (NULL_TREE, build_int_2 (size, 0));
2861 initlist = tree_cons (NULL_TREE, list, initlist);
2863 finish_decl (decl, objc_build_constructor (type, nreverse (initlist)),
2870 generate_method_descriptors (protocol)
2873 tree initlist, chain, method_list_template;
2874 tree cast, variable_length_type;
2877 if (!objc_method_prototype_template)
2878 objc_method_prototype_template = build_method_prototype_template ();
2880 cast = build_tree_list (build_tree_list (NULL_TREE, xref_tag (RECORD_TYPE,
2881 get_identifier (UTAG_METHOD_PROTOTYPE_LIST))),
2883 variable_length_type = groktypename (cast);
2885 chain = PROTOCOL_CLS_METHODS (protocol);
2888 size = list_length (chain);
2890 method_list_template
2891 = build_method_prototype_list_template (objc_method_prototype_template,
2895 = build_descriptor_table_initializer (objc_method_prototype_template,
2898 UOBJC_CLASS_METHODS_decl
2899 = generate_descriptor_table (method_list_template,
2900 "_OBJC_PROTOCOL_CLASS_METHODS",
2901 size, initlist, protocol);
2902 TREE_TYPE (UOBJC_CLASS_METHODS_decl) = variable_length_type;
2905 UOBJC_CLASS_METHODS_decl = 0;
2907 chain = PROTOCOL_NST_METHODS (protocol);
2910 size = list_length (chain);
2912 method_list_template
2913 = build_method_prototype_list_template (objc_method_prototype_template,
2916 = build_descriptor_table_initializer (objc_method_prototype_template,
2919 UOBJC_INSTANCE_METHODS_decl
2920 = generate_descriptor_table (method_list_template,
2921 "_OBJC_PROTOCOL_INSTANCE_METHODS",
2922 size, initlist, protocol);
2923 TREE_TYPE (UOBJC_INSTANCE_METHODS_decl) = variable_length_type;
2926 UOBJC_INSTANCE_METHODS_decl = 0;
2929 /* Generate a temporary FUNCTION_DECL node to be used in
2930 hack_method_prototype below. */
2932 static GTY(()) int build_tmp_function_decl_xxx;
2934 build_tmp_function_decl ()
2936 tree decl_specs, expr_decl, parms;
2939 /* struct objc_object *objc_xxx (id, SEL, ...); */
2941 decl_specs = build_tree_list (NULL_TREE, objc_object_reference);
2942 push_parm_decl (build_tree_list
2943 (build_tree_list (decl_specs,
2944 build1 (INDIRECT_REF, NULL_TREE,
2948 decl_specs = build_tree_list (NULL_TREE, xref_tag (RECORD_TYPE,
2949 get_identifier (TAG_SELECTOR)));
2950 expr_decl = build1 (INDIRECT_REF, NULL_TREE, NULL_TREE);
2952 push_parm_decl (build_tree_list (build_tree_list (decl_specs, expr_decl),
2954 parms = get_parm_info (0);
2957 decl_specs = build_tree_list (NULL_TREE, objc_object_reference);
2958 sprintf (buffer, "__objc_tmp_%x", build_tmp_function_decl_xxx++);
2959 expr_decl = build_nt (CALL_EXPR, get_identifier (buffer), parms, NULL_TREE);
2960 expr_decl = build1 (INDIRECT_REF, NULL_TREE, expr_decl);
2962 return define_decl (expr_decl, decl_specs);
2965 /* Generate the prototypes for protocol methods. This is used to
2966 generate method encodings for these.
2968 NST_METHODS is the method to generate a _DECL node for TMP_DECL is
2969 a decl node to be used. This is also where the return value is
2973 hack_method_prototype (nst_methods, tmp_decl)
2980 /* Hack to avoid problem with static typing of self arg. */
2981 TREE_SET_CODE (nst_methods, CLASS_METHOD_DECL);
2982 start_method_def (nst_methods);
2983 TREE_SET_CODE (nst_methods, INSTANCE_METHOD_DECL);
2985 if (METHOD_ADD_ARGS (nst_methods) == objc_ellipsis_node)
2986 parms = get_parm_info (0); /* we have a `, ...' */
2988 parms = get_parm_info (1); /* place a `void_at_end' */
2990 poplevel (0, 0, 0); /* Must be called BEFORE start_function. */
2992 /* Usually called from store_parm_decls -> init_function_start. */
2994 DECL_ARGUMENTS (tmp_decl) = TREE_PURPOSE (parms);
2996 if (current_function_decl)
2998 current_function_decl = tmp_decl;
3001 /* Code taken from start_function. */
3002 tree restype = TREE_TYPE (TREE_TYPE (tmp_decl));
3003 /* Promote the value to int before returning it. */
3004 if (TREE_CODE (restype) == INTEGER_TYPE
3005 && TYPE_PRECISION (restype) < TYPE_PRECISION (integer_type_node))
3006 restype = integer_type_node;
3007 DECL_RESULT (tmp_decl) = build_decl (RESULT_DECL, 0, restype);
3010 for (parm = DECL_ARGUMENTS (tmp_decl); parm; parm = TREE_CHAIN (parm))
3011 DECL_CONTEXT (parm) = tmp_decl;
3013 init_function_start (tmp_decl, "objc-act", 0);
3015 /* Typically called from expand_function_start for function definitions. */
3016 assign_parms (tmp_decl);
3018 /* install return type */
3019 TREE_TYPE (TREE_TYPE (tmp_decl)) = groktypename (TREE_TYPE (nst_methods));
3021 current_function_decl = NULL;
3025 generate_protocol_references (plist)
3030 /* Forward declare protocols referenced. */
3031 for (lproto = plist; lproto; lproto = TREE_CHAIN (lproto))
3033 tree proto = TREE_VALUE (lproto);
3035 if (TREE_CODE (proto) == PROTOCOL_INTERFACE_TYPE
3036 && PROTOCOL_NAME (proto))
3038 if (! PROTOCOL_FORWARD_DECL (proto))
3039 build_protocol_reference (proto);
3041 if (PROTOCOL_LIST (proto))
3042 generate_protocol_references (PROTOCOL_LIST (proto));
3047 /* For each protocol which was referenced either from a @protocol()
3048 expression, or because a class/category implements it (then a
3049 pointer to the protocol is stored in the struct describing the
3050 class/category), we create a statically allocated instance of the
3051 Protocol class. The code is written in such a way as to generate
3052 as few Protocol objects as possible; we generate a unique Protocol
3053 instance for each protocol, and we don't generate a Protocol
3054 instance if the protocol is never referenced (either from a
3055 @protocol() or from a class/category implementation). These
3056 statically allocated objects can be referred to via the static
3057 (that is, private to this module) symbols _OBJC_PROTOCOL_n.
3059 The statically allocated Protocol objects that we generate here
3060 need to be fixed up at runtime in order to be used: the 'isa'
3061 pointer of the objects need to be set up to point to the 'Protocol'
3062 class, as known at runtime.
3064 The NeXT runtime fixes up all protocols at program startup time,
3065 before main() is entered. It uses a low-level trick to look up all
3066 those symbols, then loops on them and fixes them up.
3068 The GNU runtime as well fixes up all protocols before user code
3069 from the module is executed; it requires pointers to those symbols
3070 to be put in the objc_symtab (which is then passed as argument to
3071 the function __objc_exec_class() which the compiler sets up to be
3072 executed automatically when the module is loaded); setup of those
3073 Protocol objects happen in two ways in the GNU runtime: all
3074 Protocol objects referred to by a class or category implementation
3075 are fixed up when the class/category is loaded; all Protocol
3076 objects referred to by a @protocol() expression are added by the
3077 compiler to the list of statically allocated instances to fixup
3078 (the same list holding the statically allocated constant string
3079 objects). Because, as explained above, the compiler generates as
3080 few Protocol objects as possible, some Protocol object might end up
3081 being referenced multiple times when compiled with the GNU runtime,
3082 and end up being fixed up multiple times at runtime inizialization.
3083 But that doesn't hurt, it's just a little inefficient. */
3085 generate_protocols ()
3087 tree p, tmp_decl, encoding;
3088 tree sc_spec, decl_specs, decl;
3089 tree initlist, protocol_name_expr, refs_decl, refs_expr;
3092 tmp_decl = build_tmp_function_decl ();
3094 if (! objc_protocol_template)
3095 objc_protocol_template = build_protocol_template ();
3097 /* If a protocol was directly referenced, pull in indirect references. */
3098 for (p = protocol_chain; p; p = TREE_CHAIN (p))
3099 if (PROTOCOL_FORWARD_DECL (p) && PROTOCOL_LIST (p))
3100 generate_protocol_references (PROTOCOL_LIST (p));
3102 for (p = protocol_chain; p; p = TREE_CHAIN (p))
3104 tree nst_methods = PROTOCOL_NST_METHODS (p);
3105 tree cls_methods = PROTOCOL_CLS_METHODS (p);
3107 /* If protocol wasn't referenced, don't generate any code. */
3108 if (! PROTOCOL_FORWARD_DECL (p))
3111 /* Make sure we link in the Protocol class. */
3112 add_class_reference (get_identifier (PROTOCOL_OBJECT_CLASS_NAME));
3116 if (! METHOD_ENCODING (nst_methods))
3118 hack_method_prototype (nst_methods, tmp_decl);
3119 encoding = encode_method_prototype (nst_methods, tmp_decl);
3120 METHOD_ENCODING (nst_methods) = encoding;
3122 nst_methods = TREE_CHAIN (nst_methods);
3127 if (! METHOD_ENCODING (cls_methods))
3129 hack_method_prototype (cls_methods, tmp_decl);
3130 encoding = encode_method_prototype (cls_methods, tmp_decl);
3131 METHOD_ENCODING (cls_methods) = encoding;
3134 cls_methods = TREE_CHAIN (cls_methods);
3136 generate_method_descriptors (p);
3138 if (PROTOCOL_LIST (p))
3139 refs_decl = generate_protocol_list (p);
3143 /* static struct objc_protocol _OBJC_PROTOCOL_<mumble>; */
3145 sc_spec = tree_cons (NULL_TREE, ridpointers[(int) RID_STATIC],
3147 decl_specs = tree_cons (NULL_TREE, objc_protocol_template, sc_spec);
3149 decl = start_decl (synth_id_with_class_suffix ("_OBJC_PROTOCOL", p),
3150 decl_specs, 1, NULL_TREE);
3152 DECL_CONTEXT (decl) = NULL_TREE;
3154 protocol_name_expr = add_objc_string (PROTOCOL_NAME (p), class_names);
3160 (build_tree_list (build_tree_list (NULL_TREE,
3161 objc_protocol_template),
3162 build1 (INDIRECT_REF, NULL_TREE,
3163 build1 (INDIRECT_REF, NULL_TREE,
3166 refs_expr = build_unary_op (ADDR_EXPR, refs_decl, 0);
3167 TREE_TYPE (refs_expr) = cast_type2;
3170 refs_expr = build_int_2 (0, 0);
3172 /* UOBJC_INSTANCE_METHODS_decl/UOBJC_CLASS_METHODS_decl are set
3173 by generate_method_descriptors, which is called above. */
3174 initlist = build_protocol_initializer (TREE_TYPE (decl),
3175 protocol_name_expr, refs_expr,
3176 UOBJC_INSTANCE_METHODS_decl,
3177 UOBJC_CLASS_METHODS_decl);
3178 finish_decl (decl, initlist, NULL_TREE);
3180 /* Mark the decl as used to avoid "defined but not used" warning. */
3181 TREE_USED (decl) = 1;
3186 build_protocol_initializer (type, protocol_name, protocol_list,
3187 instance_methods, class_methods)
3191 tree instance_methods;
3194 tree initlist = NULL_TREE, expr;
3197 cast_type = groktypename
3199 (build_tree_list (NULL_TREE,
3200 xref_tag (RECORD_TYPE,
3201 get_identifier (UTAG_CLASS))),
3202 build1 (INDIRECT_REF, NULL_TREE, NULL_TREE)));
3204 /* Filling the "isa" in with one allows the runtime system to
3205 detect that the version change...should remove before final release. */
3207 expr = build_int_2 (PROTOCOL_VERSION, 0);
3208 TREE_TYPE (expr) = cast_type;
3209 initlist = tree_cons (NULL_TREE, expr, initlist);
3210 initlist = tree_cons (NULL_TREE, protocol_name, initlist);
3211 initlist = tree_cons (NULL_TREE, protocol_list, initlist);
3213 if (!instance_methods)
3214 initlist = tree_cons (NULL_TREE, build_int_2 (0, 0), initlist);
3217 expr = build_unary_op (ADDR_EXPR, instance_methods, 0);
3218 initlist = tree_cons (NULL_TREE, expr, initlist);
3222 initlist = tree_cons (NULL_TREE, build_int_2 (0, 0), initlist);
3225 expr = build_unary_op (ADDR_EXPR, class_methods, 0);
3226 initlist = tree_cons (NULL_TREE, expr, initlist);
3229 return objc_build_constructor (type, nreverse (initlist));
3232 /* struct objc_category {
3233 char *category_name;
3235 struct objc_method_list *instance_methods;
3236 struct objc_method_list *class_methods;
3237 struct objc_protocol_list *protocols;
3241 build_category_template ()
3243 tree decl_specs, field_decl, field_decl_chain;
3245 objc_category_template = start_struct (RECORD_TYPE,
3246 get_identifier (UTAG_CATEGORY));
3247 /* char *category_name; */
3249 decl_specs = build_tree_list (NULL_TREE, ridpointers[(int) RID_CHAR]);
3251 = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("category_name"));
3253 = grokfield (input_filename, lineno, field_decl, decl_specs, NULL_TREE);
3254 field_decl_chain = field_decl;
3256 /* char *class_name; */
3258 decl_specs = build_tree_list (NULL_TREE, ridpointers[(int) RID_CHAR]);
3259 field_decl = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("class_name"));
3261 = grokfield (input_filename, lineno, field_decl, decl_specs, NULL_TREE);
3262 chainon (field_decl_chain, field_decl);
3264 /* struct objc_method_list *instance_methods; */
3266 decl_specs = build_tree_list (NULL_TREE,
3267 xref_tag (RECORD_TYPE,
3268 get_identifier (UTAG_METHOD_LIST)));
3270 = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("instance_methods"));
3272 = grokfield (input_filename, lineno, field_decl, decl_specs, NULL_TREE);
3273 chainon (field_decl_chain, field_decl);
3275 /* struct objc_method_list *class_methods; */
3277 decl_specs = build_tree_list (NULL_TREE,
3278 xref_tag (RECORD_TYPE,
3279 get_identifier (UTAG_METHOD_LIST)));
3281 = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("class_methods"));
3283 = grokfield (input_filename, lineno, field_decl, decl_specs, NULL_TREE);
3284 chainon (field_decl_chain, field_decl);
3286 /* struct objc_protocol **protocol_list; */
3288 decl_specs = build_tree_list (NULL_TREE,
3289 xref_tag (RECORD_TYPE,
3290 get_identifier (UTAG_PROTOCOL)));
3292 = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("protocol_list"));
3293 field_decl = build1 (INDIRECT_REF, NULL_TREE, field_decl);
3295 = grokfield (input_filename, lineno, field_decl, decl_specs, NULL_TREE);
3296 chainon (field_decl_chain, field_decl);
3298 finish_struct (objc_category_template, field_decl_chain, NULL_TREE);
3301 /* struct objc_selector {
3307 build_selector_template ()
3310 tree decl_specs, field_decl, field_decl_chain;
3312 objc_selector_template
3313 = start_struct (RECORD_TYPE, get_identifier (UTAG_SELECTOR));
3317 decl_specs = build_tree_list (NULL_TREE, ridpointers[(int) RID_VOID]);
3318 field_decl = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("sel_id"));
3320 = grokfield (input_filename, lineno, field_decl, decl_specs, NULL_TREE);
3321 field_decl_chain = field_decl;
3323 /* char *sel_type; */
3325 decl_specs = build_tree_list (NULL_TREE, ridpointers[(int) RID_CHAR]);
3326 field_decl = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("sel_type"));
3328 = grokfield (input_filename, lineno, field_decl, decl_specs, NULL_TREE);
3329 chainon (field_decl_chain, field_decl);
3331 finish_struct (objc_selector_template, field_decl_chain, NULL_TREE);
3334 /* struct objc_class {
3335 struct objc_class *isa;
3336 struct objc_class *super_class;
3341 struct objc_ivar_list *ivars;
3342 struct objc_method_list *methods;
3343 if (flag_next_runtime)
3344 struct objc_cache *cache;
3346 struct sarray *dtable;
3347 struct objc_class *subclass_list;
3348 struct objc_class *sibling_class;
3350 struct objc_protocol_list *protocols;
3351 void *gc_object_type;
3355 build_class_template ()
3357 tree decl_specs, field_decl, field_decl_chain;
3360 = start_struct (RECORD_TYPE, get_identifier (UTAG_CLASS));
3362 /* struct objc_class *isa; */
3364 decl_specs = build_tree_list (NULL_TREE, objc_class_template);
3365 field_decl = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("isa"));
3367 = grokfield (input_filename, lineno, field_decl, decl_specs, NULL_TREE);
3368 field_decl_chain = field_decl;
3370 /* struct objc_class *super_class; */
3372 decl_specs = build_tree_list (NULL_TREE, objc_class_template);
3374 = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("super_class"));
3376 = grokfield (input_filename, lineno, field_decl, decl_specs, NULL_TREE);
3377 chainon (field_decl_chain, field_decl);
3381 decl_specs = build_tree_list (NULL_TREE, ridpointers[(int) RID_CHAR]);
3382 field_decl = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("name"));
3384 = grokfield (input_filename, lineno, field_decl, decl_specs, NULL_TREE);
3385 chainon (field_decl_chain, field_decl);
3389 decl_specs = build_tree_list (NULL_TREE, ridpointers[(int) RID_LONG]);
3390 field_decl = get_identifier ("version");
3392 = grokfield (input_filename, lineno, field_decl, decl_specs, NULL_TREE);
3393 chainon (field_decl_chain, field_decl);
3397 decl_specs = build_tree_list (NULL_TREE, ridpointers[(int) RID_LONG]);
3398 field_decl = get_identifier ("info");
3400 = grokfield (input_filename, lineno, field_decl, decl_specs, NULL_TREE);
3401 chainon (field_decl_chain, field_decl);
3403 /* long instance_size; */
3405 decl_specs = build_tree_list (NULL_TREE, ridpointers[(int) RID_LONG]);
3406 field_decl = get_identifier ("instance_size");
3408 = grokfield (input_filename, lineno, field_decl, decl_specs, NULL_TREE);
3409 chainon (field_decl_chain, field_decl);
3411 /* struct objc_ivar_list *ivars; */
3413 decl_specs = build_tree_list (NULL_TREE,
3414 xref_tag (RECORD_TYPE,
3415 get_identifier (UTAG_IVAR_LIST)));
3416 field_decl = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("ivars"));
3418 = grokfield (input_filename, lineno, field_decl, decl_specs, NULL_TREE);
3419 chainon (field_decl_chain, field_decl);
3421 /* struct objc_method_list *methods; */
3423 decl_specs = build_tree_list (NULL_TREE,
3424 xref_tag (RECORD_TYPE,
3425 get_identifier (UTAG_METHOD_LIST)));
3426 field_decl = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("methods"));
3428 = grokfield (input_filename, lineno, field_decl, decl_specs, NULL_TREE);
3429 chainon (field_decl_chain, field_decl);
3431 if (flag_next_runtime)
3433 /* struct objc_cache *cache; */
3435 decl_specs = build_tree_list (NULL_TREE,
3436 xref_tag (RECORD_TYPE,
3437 get_identifier ("objc_cache")));
3438 field_decl = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("cache"));
3439 field_decl = grokfield (input_filename, lineno, field_decl,
3440 decl_specs, NULL_TREE);
3441 chainon (field_decl_chain, field_decl);
3445 /* struct sarray *dtable; */
3447 decl_specs = build_tree_list (NULL_TREE,
3448 xref_tag (RECORD_TYPE,
3449 get_identifier ("sarray")));
3450 field_decl = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("dtable"));
3451 field_decl = grokfield (input_filename, lineno, field_decl,
3452 decl_specs, NULL_TREE);
3453 chainon (field_decl_chain, field_decl);
3455 /* struct objc_class *subclass_list; */
3457 decl_specs = build_tree_list (NULL_TREE, objc_class_template);
3459 = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("subclass_list"));
3460 field_decl = grokfield (input_filename, lineno, field_decl,
3461 decl_specs, NULL_TREE);
3462 chainon (field_decl_chain, field_decl);
3464 /* struct objc_class *sibling_class; */
3466 decl_specs = build_tree_list (NULL_TREE, objc_class_template);
3468 = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("sibling_class"));
3469 field_decl = grokfield (input_filename, lineno, field_decl,
3470 decl_specs, NULL_TREE);
3471 chainon (field_decl_chain, field_decl);
3474 /* struct objc_protocol **protocol_list; */
3476 decl_specs = build_tree_list (NULL_TREE,
3477 xref_tag (RECORD_TYPE,
3478 get_identifier (UTAG_PROTOCOL)));
3480 = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("protocol_list"));
3482 = build1 (INDIRECT_REF, NULL_TREE, field_decl);
3483 field_decl = grokfield (input_filename, lineno, field_decl,
3484 decl_specs, NULL_TREE);
3485 chainon (field_decl_chain, field_decl);
3489 decl_specs = build_tree_list (NULL_TREE, ridpointers[(int) RID_VOID]);
3490 field_decl = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("sel_id"));
3492 = grokfield (input_filename, lineno, field_decl, decl_specs, NULL_TREE);
3493 chainon (field_decl_chain, field_decl);
3495 /* void *gc_object_type; */
3497 decl_specs = build_tree_list (NULL_TREE, ridpointers[(int) RID_VOID]);
3498 field_decl = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("gc_object_type"));
3500 = grokfield (input_filename, lineno, field_decl, decl_specs, NULL_TREE);
3501 chainon (field_decl_chain, field_decl);
3503 finish_struct (objc_class_template, field_decl_chain, NULL_TREE);
3506 /* Generate appropriate forward declarations for an implementation. */
3509 synth_forward_declarations ()
3511 tree sc_spec, decl_specs, an_id;
3513 /* extern struct objc_class _OBJC_CLASS_<my_name>; */
3515 an_id = synth_id_with_class_suffix ("_OBJC_CLASS", objc_implementation_context);
3517 sc_spec = build_tree_list (NULL_TREE, ridpointers[(int) RID_EXTERN]);
3518 decl_specs = tree_cons (NULL_TREE, objc_class_template, sc_spec);
3519 UOBJC_CLASS_decl = define_decl (an_id, decl_specs);
3520 TREE_USED (UOBJC_CLASS_decl) = 1;
3521 DECL_ARTIFICIAL (UOBJC_CLASS_decl) = 1;
3523 /* extern struct objc_class _OBJC_METACLASS_<my_name>; */
3525 an_id = synth_id_with_class_suffix ("_OBJC_METACLASS",
3526 objc_implementation_context);
3528 UOBJC_METACLASS_decl = define_decl (an_id, decl_specs);
3529 TREE_USED (UOBJC_METACLASS_decl) = 1;
3530 DECL_ARTIFICIAL(UOBJC_METACLASS_decl) = 1;
3532 /* Pre-build the following entities - for speed/convenience. */
3534 an_id = get_identifier ("super_class");
3535 ucls_super_ref = build_component_ref (UOBJC_CLASS_decl, an_id);
3536 uucls_super_ref = build_component_ref (UOBJC_METACLASS_decl, an_id);
3540 error_with_ivar (message, decl, rawdecl)
3541 const char *message;
3545 diagnostic_count_diagnostic (global_dc, DK_ERROR);
3547 diagnostic_report_current_function (global_dc);
3549 error_with_file_and_line (DECL_SOURCE_FILE (decl),
3550 DECL_SOURCE_LINE (decl),
3552 message, gen_declaration (rawdecl, errbuf));
3557 check_ivars (inter, imp)
3561 tree intdecls = CLASS_IVARS (inter);
3562 tree impdecls = CLASS_IVARS (imp);
3563 tree rawintdecls = CLASS_RAW_IVARS (inter);
3564 tree rawimpdecls = CLASS_RAW_IVARS (imp);
3570 if (intdecls == 0 && impdecls == 0)
3572 if (intdecls == 0 || impdecls == 0)
3574 error ("inconsistent instance variable specification");
3578 t1 = TREE_TYPE (intdecls); t2 = TREE_TYPE (impdecls);
3580 if (!comptypes (t1, t2))
3582 if (DECL_NAME (intdecls) == DECL_NAME (impdecls))
3584 error_with_ivar ("conflicting instance variable type",
3585 impdecls, rawimpdecls);
3586 error_with_ivar ("previous declaration of",
3587 intdecls, rawintdecls);
3589 else /* both the type and the name don't match */
3591 error ("inconsistent instance variable specification");
3596 else if (DECL_NAME (intdecls) != DECL_NAME (impdecls))
3598 error_with_ivar ("conflicting instance variable name",
3599 impdecls, rawimpdecls);
3600 error_with_ivar ("previous declaration of",
3601 intdecls, rawintdecls);
3604 intdecls = TREE_CHAIN (intdecls);
3605 impdecls = TREE_CHAIN (impdecls);
3606 rawintdecls = TREE_CHAIN (rawintdecls);
3607 rawimpdecls = TREE_CHAIN (rawimpdecls);
3611 /* Set super_type to the data type node for struct objc_super *,
3612 first defining struct objc_super itself.
3613 This needs to be done just once per compilation. */
3616 build_super_template ()
3618 tree record, decl_specs, field_decl, field_decl_chain;
3620 record = start_struct (RECORD_TYPE, get_identifier (UTAG_SUPER));
3622 /* struct objc_object *self; */
3624 decl_specs = build_tree_list (NULL_TREE, objc_object_reference);
3625 field_decl = get_identifier ("self");
3626 field_decl = build1 (INDIRECT_REF, NULL_TREE, field_decl);
3627 field_decl = grokfield (input_filename, lineno,
3628 field_decl, decl_specs, NULL_TREE);
3629 field_decl_chain = field_decl;
3631 /* struct objc_class *class; */
3633 decl_specs = get_identifier (UTAG_CLASS);
3634 decl_specs = build_tree_list (NULL_TREE, xref_tag (RECORD_TYPE, decl_specs));
3635 field_decl = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("class"));
3637 field_decl = grokfield (input_filename, lineno,
3638 field_decl, decl_specs, NULL_TREE);
3639 chainon (field_decl_chain, field_decl);
3641 finish_struct (record, field_decl_chain, NULL_TREE);
3643 /* `struct objc_super *' */
3644 super_type = groktypename (build_tree_list (build_tree_list (NULL_TREE,
3646 build1 (INDIRECT_REF,
3647 NULL_TREE, NULL_TREE)));
3651 /* struct objc_ivar {
3658 build_ivar_template ()
3660 tree objc_ivar_id, objc_ivar_record;
3661 tree decl_specs, field_decl, field_decl_chain;
3663 objc_ivar_id = get_identifier (UTAG_IVAR);
3664 objc_ivar_record = start_struct (RECORD_TYPE, objc_ivar_id);
3666 /* char *ivar_name; */
3668 decl_specs = build_tree_list (NULL_TREE, ridpointers[(int) RID_CHAR]);
3669 field_decl = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("ivar_name"));
3671 field_decl = grokfield (input_filename, lineno, field_decl,
3672 decl_specs, NULL_TREE);
3673 field_decl_chain = field_decl;
3675 /* char *ivar_type; */
3677 decl_specs = build_tree_list (NULL_TREE, ridpointers[(int) RID_CHAR]);
3678 field_decl = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("ivar_type"));
3680 field_decl = grokfield (input_filename, lineno, field_decl,
3681 decl_specs, NULL_TREE);
3682 chainon (field_decl_chain, field_decl);
3684 /* int ivar_offset; */
3686 decl_specs = build_tree_list (NULL_TREE, ridpointers[(int) RID_INT]);
3687 field_decl = get_identifier ("ivar_offset");
3689 field_decl = grokfield (input_filename, lineno, field_decl,
3690 decl_specs, NULL_TREE);
3691 chainon (field_decl_chain, field_decl);
3693 finish_struct (objc_ivar_record, field_decl_chain, NULL_TREE);
3695 return objc_ivar_record;
3700 struct objc_ivar ivar_list[ivar_count];
3704 build_ivar_list_template (list_type, size)
3708 tree objc_ivar_list_record;
3709 tree decl_specs, field_decl, field_decl_chain;
3711 objc_ivar_list_record = start_struct (RECORD_TYPE, NULL_TREE);
3713 /* int ivar_count; */
3715 decl_specs = build_tree_list (NULL_TREE, ridpointers[(int) RID_INT]);
3716 field_decl = get_identifier ("ivar_count");
3718 field_decl = grokfield (input_filename, lineno, field_decl,
3719 decl_specs, NULL_TREE);
3720 field_decl_chain = field_decl;
3722 /* struct objc_ivar ivar_list[]; */
3724 decl_specs = build_tree_list (NULL_TREE, list_type);
3725 field_decl = build_nt (ARRAY_REF, get_identifier ("ivar_list"),
3726 build_int_2 (size, 0));
3728 field_decl = grokfield (input_filename, lineno,
3729 field_decl, decl_specs, NULL_TREE);
3730 chainon (field_decl_chain, field_decl);
3732 finish_struct (objc_ivar_list_record, field_decl_chain, NULL_TREE);
3734 return objc_ivar_list_record;
3740 struct objc_method method_list[method_count];
3744 build_method_list_template (list_type, size)
3748 tree objc_ivar_list_record;
3749 tree decl_specs, field_decl, field_decl_chain;
3751 objc_ivar_list_record = start_struct (RECORD_TYPE, NULL_TREE);
3753 /* int method_next; */
3758 xref_tag (RECORD_TYPE,
3759 get_identifier (UTAG_METHOD_PROTOTYPE_LIST)));
3761 = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("method_next"));
3762 field_decl = grokfield (input_filename, lineno, field_decl,
3763 decl_specs, NULL_TREE);
3764 field_decl_chain = field_decl;
3766 /* int method_count; */
3768 decl_specs = build_tree_list (NULL_TREE, ridpointers[(int) RID_INT]);
3769 field_decl = get_identifier ("method_count");
3771 field_decl = grokfield (input_filename, lineno,
3772 field_decl, decl_specs, NULL_TREE);
3773 chainon (field_decl_chain, field_decl);
3775 /* struct objc_method method_list[]; */
3777 decl_specs = build_tree_list (NULL_TREE, list_type);
3778 field_decl = build_nt (ARRAY_REF, get_identifier ("method_list"),
3779 build_int_2 (size, 0));
3781 field_decl = grokfield (input_filename, lineno,
3782 field_decl, decl_specs, NULL_TREE);
3783 chainon (field_decl_chain, field_decl);
3785 finish_struct (objc_ivar_list_record, field_decl_chain, NULL_TREE);
3787 return objc_ivar_list_record;
3791 build_ivar_list_initializer (type, field_decl)
3795 tree initlist = NULL_TREE;
3799 tree ivar = NULL_TREE;
3802 if (DECL_NAME (field_decl))
3803 ivar = tree_cons (NULL_TREE,
3804 add_objc_string (DECL_NAME (field_decl),
3808 /* Unnamed bit-field ivar (yuck). */
3809 ivar = tree_cons (NULL_TREE, build_int_2 (0, 0), ivar);
3812 encode_field_decl (field_decl,
3813 obstack_object_size (&util_obstack),
3814 OBJC_ENCODE_DONT_INLINE_DEFS);
3816 /* Null terminate string. */
3817 obstack_1grow (&util_obstack, 0);
3821 add_objc_string (get_identifier (obstack_finish (&util_obstack)),
3824 obstack_free (&util_obstack, util_firstobj);
3827 ivar = tree_cons (NULL_TREE, byte_position (field_decl), ivar);
3828 initlist = tree_cons (NULL_TREE,
3829 objc_build_constructor (type, nreverse (ivar)),
3832 field_decl = TREE_CHAIN (field_decl);
3836 return objc_build_constructor (build_array_type (type, 0),
3837 nreverse (initlist));
3841 generate_ivars_list (type, name, size, list)
3847 tree sc_spec, decl_specs, decl, initlist;
3849 sc_spec = tree_cons (NULL_TREE, ridpointers[(int) RID_STATIC], NULL_TREE);
3850 decl_specs = tree_cons (NULL_TREE, type, sc_spec);
3852 decl = start_decl (synth_id_with_class_suffix (name, objc_implementation_context),
3853 decl_specs, 1, NULL_TREE);
3855 initlist = build_tree_list (NULL_TREE, build_int_2 (size, 0));
3856 initlist = tree_cons (NULL_TREE, list, initlist);
3859 objc_build_constructor (TREE_TYPE (decl), nreverse (initlist)),
3866 generate_ivar_lists ()
3868 tree initlist, ivar_list_template, chain;
3869 tree cast, variable_length_type;
3872 generating_instance_variables = 1;
3874 if (!objc_ivar_template)
3875 objc_ivar_template = build_ivar_template ();
3879 (build_tree_list (NULL_TREE, xref_tag (RECORD_TYPE,
3880 get_identifier (UTAG_IVAR_LIST))),
3882 variable_length_type = groktypename (cast);
3884 /* Only generate class variables for the root of the inheritance
3885 hierarchy since these will be the same for every class. */
3887 if (CLASS_SUPER_NAME (implementation_template) == NULL_TREE
3888 && (chain = TYPE_FIELDS (objc_class_template)))
3890 size = list_length (chain);
3892 ivar_list_template = build_ivar_list_template (objc_ivar_template, size);
3893 initlist = build_ivar_list_initializer (objc_ivar_template, chain);
3895 UOBJC_CLASS_VARIABLES_decl
3896 = generate_ivars_list (ivar_list_template, "_OBJC_CLASS_VARIABLES",
3898 TREE_TYPE (UOBJC_CLASS_VARIABLES_decl) = variable_length_type;
3901 UOBJC_CLASS_VARIABLES_decl = 0;
3903 chain = CLASS_IVARS (implementation_template);
3906 size = list_length (chain);
3907 ivar_list_template = build_ivar_list_template (objc_ivar_template, size);
3908 initlist = build_ivar_list_initializer (objc_ivar_template, chain);
3910 UOBJC_INSTANCE_VARIABLES_decl
3911 = generate_ivars_list (ivar_list_template, "_OBJC_INSTANCE_VARIABLES",
3913 TREE_TYPE (UOBJC_INSTANCE_VARIABLES_decl) = variable_length_type;
3916 UOBJC_INSTANCE_VARIABLES_decl = 0;
3918 generating_instance_variables = 0;
3922 build_dispatch_table_initializer (type, entries)
3926 tree initlist = NULL_TREE;
3930 tree elemlist = NULL_TREE;
3932 elemlist = tree_cons (NULL_TREE,
3933 build_selector (METHOD_SEL_NAME (entries)),
3936 /* Generate the method encoding if we don't have one already. */
3937 if (! METHOD_ENCODING (entries))
3938 METHOD_ENCODING (entries) =
3939 encode_method_def (METHOD_DEFINITION (entries));
3941 elemlist = tree_cons (NULL_TREE,
3942 add_objc_string (METHOD_ENCODING (entries),
3946 elemlist = tree_cons (NULL_TREE,
3947 build_unary_op (ADDR_EXPR,
3948 METHOD_DEFINITION (entries), 1),
3951 initlist = tree_cons (NULL_TREE,
3952 objc_build_constructor (type, nreverse (elemlist)),
3955 entries = TREE_CHAIN (entries);
3959 return objc_build_constructor (build_array_type (type, 0),
3960 nreverse (initlist));
3963 /* To accomplish method prototyping without generating all kinds of
3964 inane warnings, the definition of the dispatch table entries were
3967 struct objc_method { SEL _cmd; ...; id (*_imp)(); };
3969 struct objc_method { SEL _cmd; ...; void *_imp; }; */
3972 build_method_template ()
3975 tree decl_specs, field_decl, field_decl_chain;
3977 _SLT_record = start_struct (RECORD_TYPE, get_identifier (UTAG_METHOD));
3979 /* struct objc_selector *_cmd; */
3980 decl_specs = tree_cons (NULL_TREE,
3981 xref_tag (RECORD_TYPE,
3982 get_identifier (TAG_SELECTOR)),
3984 field_decl = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("_cmd"));
3986 field_decl = grokfield (input_filename, lineno, field_decl,
3987 decl_specs, NULL_TREE);
3988 field_decl_chain = field_decl;
3990 decl_specs = tree_cons (NULL_TREE, ridpointers[(int) RID_CHAR], NULL_TREE);
3991 field_decl = build1 (INDIRECT_REF, NULL_TREE,
3992 get_identifier ("method_types"));
3993 field_decl = grokfield (input_filename, lineno, field_decl,
3994 decl_specs, NULL_TREE);
3995 chainon (field_decl_chain, field_decl);
3999 decl_specs = tree_cons (NULL_TREE, ridpointers[(int) RID_VOID], NULL_TREE);
4000 field_decl = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("_imp"));
4001 field_decl = grokfield (input_filename, lineno, field_decl,
4002 decl_specs, NULL_TREE);
4003 chainon (field_decl_chain, field_decl);
4005 finish_struct (_SLT_record, field_decl_chain, NULL_TREE);
4012 generate_dispatch_table (type, name, size, list)
4018 tree sc_spec, decl_specs, decl, initlist;
4020 sc_spec = tree_cons (NULL_TREE, ridpointers[(int) RID_STATIC], NULL_TREE);
4021 decl_specs = tree_cons (NULL_TREE, type, sc_spec);
4023 decl = start_decl (synth_id_with_class_suffix (name, objc_implementation_context),
4024 decl_specs, 1, NULL_TREE);
4026 initlist = build_tree_list (NULL_TREE, build_int_2 (0, 0));
4027 initlist = tree_cons (NULL_TREE, build_int_2 (size, 0), initlist);
4028 initlist = tree_cons (NULL_TREE, list, initlist);
4031 objc_build_constructor (TREE_TYPE (decl), nreverse (initlist)),
4038 mark_referenced_methods ()
4040 struct imp_entry *impent;
4043 for (impent = imp_list; impent; impent = impent->next)
4045 chain = CLASS_CLS_METHODS (impent->imp_context);
4048 cgraph_mark_needed_node (cgraph_node (METHOD_DEFINITION (chain)), 1);
4049 chain = TREE_CHAIN (chain);
4051 chain = CLASS_NST_METHODS (impent->imp_context);
4054 cgraph_mark_needed_node (cgraph_node (METHOD_DEFINITION (chain)), 1);
4055 chain = TREE_CHAIN (chain);
4061 generate_dispatch_tables ()
4063 tree initlist, chain, method_list_template;
4064 tree cast, variable_length_type;
4067 if (!objc_method_template)
4068 objc_method_template = build_method_template ();
4072 (build_tree_list (NULL_TREE,
4073 xref_tag (RECORD_TYPE,
4074 get_identifier (UTAG_METHOD_LIST))),
4077 variable_length_type = groktypename (cast);
4079 chain = CLASS_CLS_METHODS (objc_implementation_context);
4082 size = list_length (chain);
4084 method_list_template
4085 = build_method_list_template (objc_method_template, size);
4087 = build_dispatch_table_initializer (objc_method_template, chain);
4089 UOBJC_CLASS_METHODS_decl
4090 = generate_dispatch_table (method_list_template,
4091 ((TREE_CODE (objc_implementation_context)
4092 == CLASS_IMPLEMENTATION_TYPE)
4093 ? "_OBJC_CLASS_METHODS"
4094 : "_OBJC_CATEGORY_CLASS_METHODS"),
4096 TREE_TYPE (UOBJC_CLASS_METHODS_decl) = variable_length_type;
4099 UOBJC_CLASS_METHODS_decl = 0;
4101 chain = CLASS_NST_METHODS (objc_implementation_context);
4104 size = list_length (chain);
4106 method_list_template
4107 = build_method_list_template (objc_method_template, size);
4109 = build_dispatch_table_initializer (objc_method_template, chain);
4111 if (TREE_CODE (objc_implementation_context) == CLASS_IMPLEMENTATION_TYPE)
4112 UOBJC_INSTANCE_METHODS_decl
4113 = generate_dispatch_table (method_list_template,
4114 "_OBJC_INSTANCE_METHODS",
4117 /* We have a category. */
4118 UOBJC_INSTANCE_METHODS_decl
4119 = generate_dispatch_table (method_list_template,
4120 "_OBJC_CATEGORY_INSTANCE_METHODS",
4122 TREE_TYPE (UOBJC_INSTANCE_METHODS_decl) = variable_length_type;
4125 UOBJC_INSTANCE_METHODS_decl = 0;
4129 generate_protocol_list (i_or_p)
4132 tree initlist, decl_specs, sc_spec;
4133 tree refs_decl, expr_decl, lproto, e, plist;
4137 if (TREE_CODE (i_or_p) == CLASS_INTERFACE_TYPE
4138 || TREE_CODE (i_or_p) == CATEGORY_INTERFACE_TYPE)
4139 plist = CLASS_PROTOCOL_LIST (i_or_p);
4140 else if (TREE_CODE (i_or_p) == PROTOCOL_INTERFACE_TYPE)
4141 plist = PROTOCOL_LIST (i_or_p);
4145 cast_type = groktypename
4147 (build_tree_list (NULL_TREE,
4148 xref_tag (RECORD_TYPE,
4149 get_identifier (UTAG_PROTOCOL))),
4150 build1 (INDIRECT_REF, NULL_TREE, NULL_TREE)));
4153 for (lproto = plist; lproto; lproto = TREE_CHAIN (lproto))
4154 if (TREE_CODE (TREE_VALUE (lproto)) == PROTOCOL_INTERFACE_TYPE
4155 && PROTOCOL_FORWARD_DECL (TREE_VALUE (lproto)))
4158 /* Build initializer. */
4159 initlist = tree_cons (NULL_TREE, build_int_2 (0, 0), NULL_TREE);
4161 e = build_int_2 (size, 0);
4162 TREE_TYPE (e) = cast_type;
4163 initlist = tree_cons (NULL_TREE, e, initlist);
4165 for (lproto = plist; lproto; lproto = TREE_CHAIN (lproto))
4167 tree pval = TREE_VALUE (lproto);
4169 if (TREE_CODE (pval) == PROTOCOL_INTERFACE_TYPE
4170 && PROTOCOL_FORWARD_DECL (pval))
4172 e = build_unary_op (ADDR_EXPR, PROTOCOL_FORWARD_DECL (pval), 0);
4173 initlist = tree_cons (NULL_TREE, e, initlist);
4177 /* static struct objc_protocol *refs[n]; */
4179 sc_spec = tree_cons (NULL_TREE, ridpointers[(int) RID_STATIC], NULL_TREE);
4180 decl_specs = tree_cons (NULL_TREE, xref_tag (RECORD_TYPE,
4181 get_identifier (UTAG_PROTOCOL)),
4184 if (TREE_CODE (i_or_p) == PROTOCOL_INTERFACE_TYPE)
4185 expr_decl = build_nt (ARRAY_REF,
4186 synth_id_with_class_suffix ("_OBJC_PROTOCOL_REFS",
4188 build_int_2 (size + 2, 0));
4189 else if (TREE_CODE (i_or_p) == CLASS_INTERFACE_TYPE)
4190 expr_decl = build_nt (ARRAY_REF,
4191 synth_id_with_class_suffix ("_OBJC_CLASS_PROTOCOLS",
4193 build_int_2 (size + 2, 0));
4194 else if (TREE_CODE (i_or_p) == CATEGORY_INTERFACE_TYPE)
4196 = build_nt (ARRAY_REF,
4197 synth_id_with_class_suffix ("_OBJC_CATEGORY_PROTOCOLS",
4199 build_int_2 (size + 2, 0));
4203 expr_decl = build1 (INDIRECT_REF, NULL_TREE, expr_decl);
4205 refs_decl = start_decl (expr_decl, decl_specs, 1, NULL_TREE);
4206 DECL_CONTEXT (refs_decl) = NULL_TREE;
4208 finish_decl (refs_decl, objc_build_constructor (TREE_TYPE (refs_decl),
4209 nreverse (initlist)),
4216 build_category_initializer (type, cat_name, class_name,
4217 instance_methods, class_methods, protocol_list)
4221 tree instance_methods;
4225 tree initlist = NULL_TREE, expr;
4227 initlist = tree_cons (NULL_TREE, cat_name, initlist);
4228 initlist = tree_cons (NULL_TREE, class_name, initlist);
4230 if (!instance_methods)
4231 initlist = tree_cons (NULL_TREE, build_int_2 (0, 0), initlist);
4234 expr = build_unary_op (ADDR_EXPR, instance_methods, 0);
4235 initlist = tree_cons (NULL_TREE, expr, initlist);
4238 initlist = tree_cons (NULL_TREE, build_int_2 (0, 0), initlist);
4241 expr = build_unary_op (ADDR_EXPR, class_methods, 0);
4242 initlist = tree_cons (NULL_TREE, expr, initlist);
4245 /* protocol_list = */
4247 initlist = tree_cons (NULL_TREE, build_int_2 (0, 0), initlist);
4250 tree cast_type2 = groktypename
4252 (build_tree_list (NULL_TREE,
4253 xref_tag (RECORD_TYPE,
4254 get_identifier (UTAG_PROTOCOL))),
4255 build1 (INDIRECT_REF, NULL_TREE,
4256 build1 (INDIRECT_REF, NULL_TREE, NULL_TREE))));
4258 expr = build_unary_op (ADDR_EXPR, protocol_list, 0);
4259 TREE_TYPE (expr) = cast_type2;
4260 initlist = tree_cons (NULL_TREE, expr, initlist);
4263 return objc_build_constructor (type, nreverse (initlist));
4266 /* struct objc_class {
4267 struct objc_class *isa;
4268 struct objc_class *super_class;
4273 struct objc_ivar_list *ivars;
4274 struct objc_method_list *methods;
4275 if (flag_next_runtime)
4276 struct objc_cache *cache;
4278 struct sarray *dtable;
4279 struct objc_class *subclass_list;
4280 struct objc_class *sibling_class;
4282 struct objc_protocol_list *protocols;
4283 void *gc_object_type;
4287 build_shared_structure_initializer (type, isa, super, name, size, status,
4288 dispatch_table, ivar_list, protocol_list)
4295 tree dispatch_table;
4299 tree initlist = NULL_TREE, expr;
4302 initlist = tree_cons (NULL_TREE, isa, initlist);
4305 initlist = tree_cons (NULL_TREE, super, initlist);
4308 initlist = tree_cons (NULL_TREE, default_conversion (name), initlist);
4311 initlist = tree_cons (NULL_TREE, build_int_2 (0, 0), initlist);
4314 initlist = tree_cons (NULL_TREE, build_int_2 (status, 0), initlist);
4316 /* instance_size = */
4317 initlist = tree_cons (NULL_TREE, size, initlist);
4319 /* objc_ivar_list = */
4321 initlist = tree_cons (NULL_TREE, build_int_2 (0, 0), initlist);
4324 expr = build_unary_op (ADDR_EXPR, ivar_list, 0);
4325 initlist = tree_cons (NULL_TREE, expr, initlist);
4328 /* objc_method_list = */
4329 if (!dispatch_table)
4330 initlist = tree_cons (NULL_TREE, build_int_2 (0, 0), initlist);
4333 expr = build_unary_op (ADDR_EXPR, dispatch_table, 0);
4334 initlist = tree_cons (NULL_TREE, expr, initlist);
4337 if (flag_next_runtime)
4338 /* method_cache = */
4339 initlist = tree_cons (NULL_TREE, build_int_2 (0, 0), initlist);
4343 initlist = tree_cons (NULL_TREE, build_int_2 (0, 0), initlist);
4345 /* subclass_list = */
4346 initlist = tree_cons (NULL_TREE, build_int_2 (0, 0), initlist);
4348 /* sibling_class = */
4349 initlist = tree_cons (NULL_TREE, build_int_2 (0, 0), initlist);
4352 /* protocol_list = */
4353 if (! protocol_list)
4354 initlist = tree_cons (NULL_TREE, build_int_2 (0, 0), initlist);
4360 (build_tree_list (NULL_TREE,
4361 xref_tag (RECORD_TYPE,
4362 get_identifier (UTAG_PROTOCOL))),
4363 build1 (INDIRECT_REF, NULL_TREE,
4364 build1 (INDIRECT_REF, NULL_TREE, NULL_TREE))));
4366 expr = build_unary_op (ADDR_EXPR, protocol_list, 0);
4367 TREE_TYPE (expr) = cast_type2;
4368 initlist = tree_cons (NULL_TREE, expr, initlist);
4371 /* gc_object_type = NULL */
4372 initlist = tree_cons (NULL_TREE, build_int_2 (0, 0), initlist);
4374 return objc_build_constructor (type, nreverse (initlist));
4377 /* static struct objc_category _OBJC_CATEGORY_<name> = { ... }; */
4380 generate_category (cat)
4383 tree sc_spec, decl_specs, decl;
4384 tree initlist, cat_name_expr, class_name_expr;
4385 tree protocol_decl, category;
4387 add_class_reference (CLASS_NAME (cat));
4388 cat_name_expr = add_objc_string (CLASS_SUPER_NAME (cat), class_names);
4390 class_name_expr = add_objc_string (CLASS_NAME (cat), class_names);
4392 category = CLASS_CATEGORY_LIST (implementation_template);
4394 /* find the category interface from the class it is associated with */
4397 if (CLASS_SUPER_NAME (cat) == CLASS_SUPER_NAME (category))
4399 category = CLASS_CATEGORY_LIST (category);
4402 if (category && CLASS_PROTOCOL_LIST (category))
4404 generate_protocol_references (CLASS_PROTOCOL_LIST (category));
4405 protocol_decl = generate_protocol_list (category);
4410 sc_spec = tree_cons (NULL_TREE, ridpointers[(int) RID_STATIC], NULL_TREE);
4411 decl_specs = tree_cons (NULL_TREE, objc_category_template, sc_spec);
4413 decl = start_decl (synth_id_with_class_suffix ("_OBJC_CATEGORY",
4414 objc_implementation_context),
4415 decl_specs, 1, NULL_TREE);
4417 initlist = build_category_initializer (TREE_TYPE (decl),
4418 cat_name_expr, class_name_expr,
4419 UOBJC_INSTANCE_METHODS_decl,
4420 UOBJC_CLASS_METHODS_decl,
4423 TREE_USED (decl) = 1;
4424 finish_decl (decl, initlist, NULL_TREE);
4427 /* static struct objc_class _OBJC_METACLASS_Foo={ ... };
4428 static struct objc_class _OBJC_CLASS_Foo={ ... }; */
4431 generate_shared_structures ()
4433 tree sc_spec, decl_specs, decl;
4434 tree name_expr, super_expr, root_expr;
4435 tree my_root_id = NULL_TREE, my_super_id = NULL_TREE;
4436 tree cast_type, initlist, protocol_decl;
4438 my_super_id = CLASS_SUPER_NAME (implementation_template);
4441 add_class_reference (my_super_id);
4443 /* Compute "my_root_id" - this is required for code generation.
4444 the "isa" for all meta class structures points to the root of
4445 the inheritance hierarchy (e.g. "__Object")... */
4446 my_root_id = my_super_id;
4449 tree my_root_int = lookup_interface (my_root_id);
4451 if (my_root_int && CLASS_SUPER_NAME (my_root_int))
4452 my_root_id = CLASS_SUPER_NAME (my_root_int);
4459 /* No super class. */
4460 my_root_id = CLASS_NAME (implementation_template);
4463 = groktypename (build_tree_list (build_tree_list (NULL_TREE,
4464 objc_class_template),
4465 build1 (INDIRECT_REF,
4466 NULL_TREE, NULL_TREE)));
4468 name_expr = add_objc_string (CLASS_NAME (implementation_template),
4471 /* Install class `isa' and `super' pointers at runtime. */
4474 super_expr = add_objc_string (my_super_id, class_names);
4475 super_expr = build_c_cast (cast_type, super_expr); /* cast! */
4478 super_expr = build_int_2 (0, 0);
4480 root_expr = add_objc_string (my_root_id, class_names);
4481 root_expr = build_c_cast (cast_type, root_expr); /* cast! */
4483 if (CLASS_PROTOCOL_LIST (implementation_template))
4485 generate_protocol_references
4486 (CLASS_PROTOCOL_LIST (implementation_template));
4487 protocol_decl = generate_protocol_list (implementation_template);
4492 /* static struct objc_class _OBJC_METACLASS_Foo = { ... }; */
4494 sc_spec = build_tree_list (NULL_TREE, ridpointers[(int) RID_STATIC]);
4495 decl_specs = tree_cons (NULL_TREE, objc_class_template, sc_spec);
4497 decl = start_decl (DECL_NAME (UOBJC_METACLASS_decl), decl_specs, 1,
4501 = build_shared_structure_initializer
4503 root_expr, super_expr, name_expr,
4504 convert (integer_type_node, TYPE_SIZE_UNIT (objc_class_template)),
4506 UOBJC_CLASS_METHODS_decl,
4507 UOBJC_CLASS_VARIABLES_decl,
4510 finish_decl (decl, initlist, NULL_TREE);
4512 /* static struct objc_class _OBJC_CLASS_Foo={ ... }; */
4514 decl = start_decl (DECL_NAME (UOBJC_CLASS_decl), decl_specs, 1,
4518 = build_shared_structure_initializer
4520 build_unary_op (ADDR_EXPR, UOBJC_METACLASS_decl, 0),
4521 super_expr, name_expr,
4522 convert (integer_type_node,
4523 TYPE_SIZE_UNIT (CLASS_STATIC_TEMPLATE
4524 (implementation_template))),
4526 UOBJC_INSTANCE_METHODS_decl,
4527 UOBJC_INSTANCE_VARIABLES_decl,
4530 finish_decl (decl, initlist, NULL_TREE);
4534 synth_id_with_class_suffix (preamble, ctxt)
4535 const char *preamble;
4539 if (TREE_CODE (ctxt) == CLASS_IMPLEMENTATION_TYPE
4540 || TREE_CODE (ctxt) == CLASS_INTERFACE_TYPE)
4542 const char *const class_name
4543 = IDENTIFIER_POINTER (CLASS_NAME (objc_implementation_context));
4544 string = (char *) alloca (strlen (preamble) + strlen (class_name) + 3);
4545 sprintf (string, "%s_%s", preamble,
4546 IDENTIFIER_POINTER (CLASS_NAME (ctxt)));
4548 else if (TREE_CODE (ctxt) == CATEGORY_IMPLEMENTATION_TYPE
4549 || TREE_CODE (ctxt) == CATEGORY_INTERFACE_TYPE)
4551 /* We have a category. */
4552 const char *const class_name
4553 = IDENTIFIER_POINTER (CLASS_NAME (objc_implementation_context));
4554 const char *const class_super_name
4555 = IDENTIFIER_POINTER (CLASS_SUPER_NAME (objc_implementation_context));
4556 string = (char *) alloca (strlen (preamble)
4557 + strlen (class_name)
4558 + strlen (class_super_name)
4560 sprintf (string, "%s_%s_%s", preamble, class_name, class_super_name);
4562 else if (TREE_CODE (ctxt) == PROTOCOL_INTERFACE_TYPE)
4564 const char *protocol_name = IDENTIFIER_POINTER (PROTOCOL_NAME (ctxt));
4566 = (char *) alloca (strlen (preamble) + strlen (protocol_name) + 3);
4567 sprintf (string, "%s_%s", preamble, protocol_name);
4572 return get_identifier (string);
4576 is_objc_type_qualifier (node)
4579 return (TREE_CODE (node) == IDENTIFIER_NODE
4580 && (node == ridpointers [(int) RID_CONST]
4581 || node == ridpointers [(int) RID_VOLATILE]
4582 || node == ridpointers [(int) RID_IN]
4583 || node == ridpointers [(int) RID_OUT]
4584 || node == ridpointers [(int) RID_INOUT]
4585 || node == ridpointers [(int) RID_BYCOPY]
4586 || node == ridpointers [(int) RID_BYREF]
4587 || node == ridpointers [(int) RID_ONEWAY]));
4590 /* If type is empty or only type qualifiers are present, add default
4591 type of id (otherwise grokdeclarator will default to int). */
4594 adjust_type_for_id_default (type)
4597 tree declspecs, chain;
4600 return build_tree_list (build_tree_list (NULL_TREE, objc_object_reference),
4601 build1 (INDIRECT_REF, NULL_TREE, NULL_TREE));
4603 declspecs = TREE_PURPOSE (type);
4605 /* Determine if a typespec is present. */
4606 for (chain = declspecs;
4608 chain = TREE_CHAIN (chain))
4610 if (TYPED_OBJECT (TREE_VALUE (chain))
4611 && !(TREE_VALUE (type)
4612 && TREE_CODE (TREE_VALUE (type)) == INDIRECT_REF))
4613 error ("can not use an object as parameter to a method\n");
4614 if (!is_objc_type_qualifier (TREE_VALUE (chain)))
4618 return build_tree_list (tree_cons (NULL_TREE, objc_object_reference,
4620 build1 (INDIRECT_REF, NULL_TREE, NULL_TREE));
4625 selector ':' '(' typename ')' identifier
4628 Transform an Objective-C keyword argument into
4629 the C equivalent parameter declarator.
4631 In: key_name, an "identifier_node" (optional).
4632 arg_type, a "tree_list" (optional).
4633 arg_name, an "identifier_node".
4635 Note: It would be really nice to strongly type the preceding
4636 arguments in the function prototype; however, then I
4637 could not use the "accessor" macros defined in "tree.h".
4639 Out: an instance of "keyword_decl". */
4642 build_keyword_decl (key_name, arg_type, arg_name)
4649 /* If no type is specified, default to "id". */
4650 arg_type = adjust_type_for_id_default (arg_type);
4652 keyword_decl = make_node (KEYWORD_DECL);
4654 TREE_TYPE (keyword_decl) = arg_type;
4655 KEYWORD_ARG_NAME (keyword_decl) = arg_name;
4656 KEYWORD_KEY_NAME (keyword_decl) = key_name;
4658 return keyword_decl;
4661 /* Given a chain of keyword_decl's, synthesize the full keyword selector. */
4664 build_keyword_selector (selector)
4668 tree key_chain, key_name;
4671 /* Scan the selector to see how much space we'll need. */
4672 for (key_chain = selector; key_chain; key_chain = TREE_CHAIN (key_chain))
4674 if (TREE_CODE (selector) == KEYWORD_DECL)
4675 key_name = KEYWORD_KEY_NAME (key_chain);
4676 else if (TREE_CODE (selector) == TREE_LIST)
4677 key_name = TREE_PURPOSE (key_chain);
4682 len += IDENTIFIER_LENGTH (key_name) + 1;
4684 /* Just a ':' arg. */
4688 buf = (char *) alloca (len + 1);
4689 /* Start the buffer out as an empty string. */
4692 for (key_chain = selector; key_chain; key_chain = TREE_CHAIN (key_chain))
4694 if (TREE_CODE (selector) == KEYWORD_DECL)
4695 key_name = KEYWORD_KEY_NAME (key_chain);
4696 else if (TREE_CODE (selector) == TREE_LIST)
4697 key_name = TREE_PURPOSE (key_chain);
4702 strcat (buf, IDENTIFIER_POINTER (key_name));
4706 return get_identifier (buf);
4709 /* Used for declarations and definitions. */
4712 build_method_decl (code, ret_type, selector, add_args)
4713 enum tree_code code;
4720 /* If no type is specified, default to "id". */
4721 ret_type = adjust_type_for_id_default (ret_type);
4723 method_decl = make_node (code);
4724 TREE_TYPE (method_decl) = ret_type;
4726 /* If we have a keyword selector, create an identifier_node that
4727 represents the full selector name (`:' included)... */
4728 if (TREE_CODE (selector) == KEYWORD_DECL)
4730 METHOD_SEL_NAME (method_decl) = build_keyword_selector (selector);
4731 METHOD_SEL_ARGS (method_decl) = selector;
4732 METHOD_ADD_ARGS (method_decl) = add_args;
4736 METHOD_SEL_NAME (method_decl) = selector;
4737 METHOD_SEL_ARGS (method_decl) = NULL_TREE;
4738 METHOD_ADD_ARGS (method_decl) = NULL_TREE;
4744 #define METHOD_DEF 0
4745 #define METHOD_REF 1
4747 /* Used by `build_objc_method_call' and `comp_method_types'. Return
4748 an argument list for method METH. CONTEXT is either METHOD_DEF or
4749 METHOD_REF, saying whether we are trying to define a method or call
4750 one. SUPERFLAG says this is for a send to super; this makes a
4751 difference for the NeXT calling sequence in which the lookup and
4752 the method call are done together. */
4755 get_arg_type_list (meth, context, superflag)
4762 /* Receiver type. */
4763 if (flag_next_runtime && superflag)
4764 arglist = build_tree_list (NULL_TREE, super_type);
4765 else if (context == METHOD_DEF)
4766 arglist = build_tree_list (NULL_TREE, TREE_TYPE (self_decl));
4768 arglist = build_tree_list (NULL_TREE, id_type);
4770 /* Selector type - will eventually change to `int'. */
4771 chainon (arglist, build_tree_list (NULL_TREE, selector_type));
4773 /* Build a list of argument types. */
4774 for (akey = METHOD_SEL_ARGS (meth); akey; akey = TREE_CHAIN (akey))
4776 tree arg_decl = groktypename_in_parm_context (TREE_TYPE (akey));
4777 chainon (arglist, build_tree_list (NULL_TREE, TREE_TYPE (arg_decl)));
4780 if (METHOD_ADD_ARGS (meth) == objc_ellipsis_node)
4781 /* We have a `, ...' immediately following the selector,
4782 finalize the arglist...simulate get_parm_info (0). */
4784 else if (METHOD_ADD_ARGS (meth))
4786 /* we have a variable length selector */
4787 tree add_arg_list = TREE_CHAIN (METHOD_ADD_ARGS (meth));
4788 chainon (arglist, add_arg_list);
4791 /* finalize the arglist...simulate get_parm_info (1) */
4792 chainon (arglist, build_tree_list (NULL_TREE, void_type_node));
4798 check_duplicates (hsh)
4801 tree meth = NULL_TREE;
4809 /* We have two methods with the same name and different types. */
4811 char type = (TREE_CODE (meth) == INSTANCE_METHOD_DECL) ? '-' : '+';
4813 warning ("multiple declarations for method `%s'",
4814 IDENTIFIER_POINTER (METHOD_SEL_NAME (meth)));
4816 warn_with_method ("using", type, meth);
4817 for (loop = hsh->list; loop; loop = loop->next)
4818 warn_with_method ("also found", type, loop->value);
4824 /* If RECEIVER is a class reference, return the identifier node for
4825 the referenced class. RECEIVER is created by get_class_reference,
4826 so we check the exact form created depending on which runtimes are
4830 receiver_is_class_object (receiver)
4833 tree chain, exp, arg;
4835 /* The receiver is 'self' in the context of a class method. */
4836 if (objc_method_context
4837 && receiver == self_decl
4838 && TREE_CODE (objc_method_context) == CLASS_METHOD_DECL)
4840 return CLASS_NAME (objc_implementation_context);
4843 if (flag_next_runtime)
4845 /* The receiver is a variable created by
4846 build_class_reference_decl. */
4847 if (TREE_CODE (receiver) == VAR_DECL
4848 && TREE_TYPE (receiver) == objc_class_type)
4849 /* Look up the identifier. */
4850 for (chain = cls_ref_chain; chain; chain = TREE_CHAIN (chain))
4851 if (TREE_PURPOSE (chain) == receiver)
4852 return TREE_VALUE (chain);
4856 /* The receiver is a function call that returns an id. Check if
4857 it is a call to objc_getClass, if so, pick up the class name. */
4858 if (TREE_CODE (receiver) == CALL_EXPR
4859 && (exp = TREE_OPERAND (receiver, 0))
4860 && TREE_CODE (exp) == ADDR_EXPR
4861 && (exp = TREE_OPERAND (exp, 0))
4862 && TREE_CODE (exp) == FUNCTION_DECL
4863 && exp == objc_get_class_decl
4864 /* We have a call to objc_getClass! */
4865 && (arg = TREE_OPERAND (receiver, 1))
4866 && TREE_CODE (arg) == TREE_LIST
4867 && (arg = TREE_VALUE (arg)))
4870 if (TREE_CODE (arg) == ADDR_EXPR
4871 && (arg = TREE_OPERAND (arg, 0))
4872 && TREE_CODE (arg) == STRING_CST)
4873 /* Finally, we have the class name. */
4874 return get_identifier (TREE_STRING_POINTER (arg));
4880 /* If we are currently building a message expr, this holds
4881 the identifier of the selector of the message. This is
4882 used when printing warnings about argument mismatches. */
4884 static tree current_objc_message_selector = 0;
4887 objc_message_selector ()
4889 return current_objc_message_selector;
4892 /* Construct an expression for sending a message.
4893 MESS has the object to send to in TREE_PURPOSE
4894 and the argument list (including selector) in TREE_VALUE.
4896 (*(<abstract_decl>(*)())_msg)(receiver, selTransTbl[n], ...);
4897 (*(<abstract_decl>(*)())_msgSuper)(receiver, selTransTbl[n], ...); */
4900 build_message_expr (mess)
4903 tree receiver = TREE_PURPOSE (mess);
4905 tree args = TREE_VALUE (mess);
4906 tree method_params = NULL_TREE;
4908 if (TREE_CODE (receiver) == ERROR_MARK)
4909 return error_mark_node;
4911 /* Obtain the full selector name. */
4912 if (TREE_CODE (args) == IDENTIFIER_NODE)
4913 /* A unary selector. */
4915 else if (TREE_CODE (args) == TREE_LIST)
4916 sel_name = build_keyword_selector (args);
4920 /* Build the parameter list to give to the method. */
4921 if (TREE_CODE (args) == TREE_LIST)
4923 tree chain = args, prev = NULL_TREE;
4925 /* We have a keyword selector--check for comma expressions. */
4928 tree element = TREE_VALUE (chain);
4930 /* We have a comma expression, must collapse... */
4931 if (TREE_CODE (element) == TREE_LIST)
4934 TREE_CHAIN (prev) = element;
4939 chain = TREE_CHAIN (chain);
4941 method_params = args;
4944 return finish_message_expr (receiver, sel_name, method_params);
4947 /* The 'finish_message_expr' routine is called from within
4948 'build_message_expr' for non-template functions. In the case of
4949 C++ template functions, it is called from 'build_expr_from_tree'
4950 (in decl2.c) after RECEIVER and METHOD_PARAMS have been expanded. */
4953 finish_message_expr (receiver, sel_name, method_params)
4954 tree receiver, sel_name, method_params;
4956 tree method_prototype = NULL_TREE, class_ident = NULL_TREE;
4957 tree selector, self_object, retval;
4958 int statically_typed = 0, statically_allocated = 0;
4960 /* Determine receiver type. */
4961 tree rtype = TREE_TYPE (receiver);
4962 int super = IS_SUPER (rtype);
4966 if (TREE_STATIC_TEMPLATE (rtype))
4967 statically_allocated = 1;
4968 else if (TREE_CODE (rtype) == POINTER_TYPE
4969 && TREE_STATIC_TEMPLATE (TREE_TYPE (rtype)))
4970 statically_typed = 1;
4971 else if ((flag_next_runtime
4973 && (class_ident = receiver_is_class_object (receiver)))
4975 else if (! IS_ID (rtype)
4976 /* Allow any type that matches objc_class_type. */
4977 && ! comptypes (rtype, objc_class_type))
4979 warning ("invalid receiver type `%s'",
4980 gen_declaration (rtype, errbuf));
4982 if (statically_allocated)
4983 receiver = build_unary_op (ADDR_EXPR, receiver, 0);
4985 /* Don't evaluate the receiver twice. */
4986 receiver = save_expr (receiver);
4987 self_object = receiver;
4990 /* If sending to `super', use current self as the object. */
4991 self_object = self_decl;
4993 /* Determine operation return type. */
4999 if (CLASS_SUPER_NAME (implementation_template))
5002 = lookup_interface (CLASS_SUPER_NAME (implementation_template));
5004 if (TREE_CODE (objc_method_context) == INSTANCE_METHOD_DECL)
5005 method_prototype = lookup_instance_method_static (iface, sel_name);
5007 method_prototype = lookup_class_method_static (iface, sel_name);
5009 if (iface && !method_prototype)
5010 warning ("`%s' does not respond to `%s'",
5011 IDENTIFIER_POINTER (CLASS_SUPER_NAME (implementation_template)),
5012 IDENTIFIER_POINTER (sel_name));
5016 error ("no super class declared in interface for `%s'",
5017 IDENTIFIER_POINTER (CLASS_NAME (implementation_template)));
5018 return error_mark_node;
5022 else if (statically_allocated)
5024 tree ctype = TREE_TYPE (rtype);
5025 tree iface = lookup_interface (TYPE_NAME (rtype));
5028 method_prototype = lookup_instance_method_static (iface, sel_name);
5030 if (! method_prototype && ctype && TYPE_PROTOCOL_LIST (ctype))
5032 = lookup_method_in_protocol_list (TYPE_PROTOCOL_LIST (ctype),
5035 if (!method_prototype)
5036 warning ("`%s' does not respond to `%s'",
5037 IDENTIFIER_POINTER (TYPE_NAME (rtype)),
5038 IDENTIFIER_POINTER (sel_name));
5040 else if (statically_typed)
5042 tree ctype = TREE_TYPE (rtype);
5044 /* `self' is now statically_typed. All methods should be visible
5045 within the context of the implementation. */
5046 if (objc_implementation_context
5047 && CLASS_NAME (objc_implementation_context) == TYPE_NAME (ctype))
5050 = lookup_instance_method_static (implementation_template,
5053 if (! method_prototype && TYPE_PROTOCOL_LIST (ctype))
5055 = lookup_method_in_protocol_list (TYPE_PROTOCOL_LIST (ctype),
5058 if (! method_prototype
5059 && implementation_template != objc_implementation_context)
5060 /* The method is not published in the interface. Check
5063 = lookup_method (CLASS_NST_METHODS (objc_implementation_context),
5070 if ((iface = lookup_interface (TYPE_NAME (ctype))))
5071 method_prototype = lookup_instance_method_static (iface, sel_name);
5073 if (! method_prototype)
5075 tree protocol_list = TYPE_PROTOCOL_LIST (ctype);
5078 = lookup_method_in_protocol_list (protocol_list,
5083 if (!method_prototype)
5084 warning ("`%s' does not respond to `%s'",
5085 IDENTIFIER_POINTER (TYPE_NAME (ctype)),
5086 IDENTIFIER_POINTER (sel_name));
5088 else if (class_ident)
5090 if (objc_implementation_context
5091 && CLASS_NAME (objc_implementation_context) == class_ident)
5094 = lookup_class_method_static (implementation_template, sel_name);
5096 if (!method_prototype
5097 && implementation_template != objc_implementation_context)
5098 /* The method is not published in the interface. Check
5101 = lookup_method (CLASS_CLS_METHODS (objc_implementation_context),
5108 if ((iface = lookup_interface (class_ident)))
5109 method_prototype = lookup_class_method_static (iface, sel_name);
5112 if (!method_prototype)
5114 warning ("cannot find class (factory) method");
5115 warning ("return type for `%s' defaults to id",
5116 IDENTIFIER_POINTER (sel_name));
5119 else if (IS_PROTOCOL_QUALIFIED_ID (rtype))
5121 /* An anonymous object that has been qualified with a protocol. */
5123 tree protocol_list = TYPE_PROTOCOL_LIST (rtype);
5125 method_prototype = lookup_method_in_protocol_list (protocol_list,
5128 if (!method_prototype)
5132 warning ("method `%s' not implemented by protocol",
5133 IDENTIFIER_POINTER (sel_name));
5135 /* Try and find the method signature in the global pools. */
5137 if (!(hsh = hash_lookup (nst_method_hash_list, sel_name)))
5138 hsh = hash_lookup (cls_method_hash_list, sel_name);
5140 if (!(method_prototype = check_duplicates (hsh)))
5141 warning ("return type defaults to id");
5148 /* We think we have an instance...loophole: extern id Object; */
5149 hsh = hash_lookup (nst_method_hash_list, sel_name);
5152 /* For various loopholes */
5153 hsh = hash_lookup (cls_method_hash_list, sel_name);
5155 method_prototype = check_duplicates (hsh);
5156 if (!method_prototype)
5158 warning ("cannot find method");
5159 warning ("return type for `%s' defaults to id",
5160 IDENTIFIER_POINTER (sel_name));
5164 /* Save the selector name for printing error messages. */
5165 current_objc_message_selector = sel_name;
5167 /* Build the parameters list for looking up the method.
5168 These are the object itself and the selector. */
5170 if (flag_typed_selectors)
5171 selector = build_typed_selector_reference (sel_name, method_prototype);
5173 selector = build_selector_reference (sel_name);
5175 retval = build_objc_method_call (super, method_prototype,
5176 receiver, self_object,
5177 selector, method_params);
5179 current_objc_message_selector = 0;
5184 /* Build a tree expression to send OBJECT the operation SELECTOR,
5185 looking up the method on object LOOKUP_OBJECT (often same as OBJECT),
5186 assuming the method has prototype METHOD_PROTOTYPE.
5187 (That is an INSTANCE_METHOD_DECL or CLASS_METHOD_DECL.)
5188 Use METHOD_PARAMS as list of args to pass to the method.
5189 If SUPER_FLAG is nonzero, we look up the superclass's method. */
5192 build_objc_method_call (super_flag, method_prototype, lookup_object, object,
5193 selector, method_params)
5195 tree method_prototype, lookup_object, object, selector, method_params;
5197 tree sender = (super_flag ? umsg_super_decl : umsg_decl);
5198 tree rcv_p = (super_flag
5199 ? build_pointer_type (xref_tag (RECORD_TYPE,
5200 get_identifier (TAG_SUPER)))
5203 if (flag_next_runtime)
5205 if (! method_prototype)
5207 method_params = tree_cons (NULL_TREE, lookup_object,
5208 tree_cons (NULL_TREE, selector,
5210 assemble_external (sender);
5211 return build_function_call (sender, method_params);
5215 /* This is a real kludge, but it is used only for the Next.
5216 Clobber the data type of SENDER temporarily to accept
5217 all the arguments for this operation, and to return
5218 whatever this operation returns. */
5219 tree arglist = NULL_TREE, retval, savarg, savret;
5220 tree ret_type = groktypename (TREE_TYPE (method_prototype));
5222 /* Save the proper contents of SENDER's data type. */
5223 savarg = TYPE_ARG_TYPES (TREE_TYPE (sender));
5224 savret = TREE_TYPE (TREE_TYPE (sender));
5226 /* Install this method's argument types. */
5227 arglist = get_arg_type_list (method_prototype, METHOD_REF,
5229 TYPE_ARG_TYPES (TREE_TYPE (sender)) = arglist;
5231 /* Install this method's return type. */
5232 TREE_TYPE (TREE_TYPE (sender)) = ret_type;
5234 /* Call SENDER with all the parameters. This will do type
5235 checking using the arg types for this method. */
5236 method_params = tree_cons (NULL_TREE, lookup_object,
5237 tree_cons (NULL_TREE, selector,
5239 assemble_external (sender);
5240 retval = build_function_call (sender, method_params);
5242 /* Restore SENDER's return/argument types. */
5243 TYPE_ARG_TYPES (TREE_TYPE (sender)) = savarg;
5244 TREE_TYPE (TREE_TYPE (sender)) = savret;
5250 /* This is the portable way.
5251 First call the lookup function to get a pointer to the method,
5252 then cast the pointer, then call it with the method arguments. */
5255 /* Avoid trouble since we may evaluate each of these twice. */
5256 object = save_expr (object);
5257 selector = save_expr (selector);
5259 lookup_object = build_c_cast (rcv_p, lookup_object);
5261 assemble_external (sender);
5263 = build_function_call (sender,
5264 tree_cons (NULL_TREE, lookup_object,
5265 tree_cons (NULL_TREE, selector,
5268 /* If we have a method prototype, construct the data type this
5269 method needs, and cast what we got from SENDER into a pointer
5271 if (method_prototype)
5273 tree arglist = get_arg_type_list (method_prototype, METHOD_REF,
5275 tree valtype = groktypename (TREE_TYPE (method_prototype));
5276 tree fake_function_type = build_function_type (valtype, arglist);
5277 TREE_TYPE (method) = build_pointer_type (fake_function_type);
5281 = build_pointer_type (build_function_type (ptr_type_node, NULL_TREE));
5283 /* Pass the object to the method. */
5284 assemble_external (method);
5285 return build_function_call (method,
5286 tree_cons (NULL_TREE, object,
5287 tree_cons (NULL_TREE, selector,
5293 build_protocol_reference (p)
5296 tree decl, ident, ptype;
5298 /* extern struct objc_protocol _OBJC_PROTOCOL_<mumble>; */
5300 ident = synth_id_with_class_suffix ("_OBJC_PROTOCOL", p);
5302 = groktypename (build_tree_list (build_tree_list (NULL_TREE,
5303 objc_protocol_template),
5306 if (identifier_global_value (ident))
5307 decl = identifier_global_value (ident); /* Set by pushdecl. */
5310 decl = build_decl (VAR_DECL, ident, ptype);
5311 DECL_EXTERNAL (decl) = 1;
5312 TREE_PUBLIC (decl) = 1;
5313 TREE_USED (decl) = 1;
5314 DECL_ARTIFICIAL (decl) = 1;
5316 make_decl_rtl (decl, 0);
5317 pushdecl_top_level (decl);
5320 PROTOCOL_FORWARD_DECL (p) = decl;
5323 /* This function is called by the parser when (and only when) a
5324 @protocol() expression is found, in order to compile it. */
5326 build_protocol_expr (protoname)
5330 tree p = lookup_protocol (protoname);
5334 error ("cannot find protocol declaration for `%s'",
5335 IDENTIFIER_POINTER (protoname));
5336 return error_mark_node;
5339 if (!PROTOCOL_FORWARD_DECL (p))
5340 build_protocol_reference (p);
5342 expr = build_unary_op (ADDR_EXPR, PROTOCOL_FORWARD_DECL (p), 0);
5344 TREE_TYPE (expr) = protocol_type;
5346 /* The @protocol() expression is being compiled into a pointer to a
5347 statically allocated instance of the Protocol class. To become
5348 usable at runtime, the 'isa' pointer of the instance need to be
5349 fixed up at runtime by the runtime library, to point to the
5350 actual 'Protocol' class. */
5352 /* For the GNU runtime, put the static Protocol instance in the list
5353 of statically allocated instances, so that we make sure that its
5354 'isa' pointer is fixed up at runtime by the GNU runtime library
5355 to point to the Protocol class (at runtime, when loading the
5356 module, the GNU runtime library loops on the statically allocated
5357 instances (as found in the defs field in objc_symtab) and fixups
5358 all the 'isa' pointers of those objects). */
5359 if (! flag_next_runtime)
5361 /* This type is a struct containing the fields of a Protocol
5362 object. (Cfr. protocol_type instead is the type of a pointer
5363 to such a struct). */
5364 tree protocol_struct_type = xref_tag
5365 (RECORD_TYPE, get_identifier (PROTOCOL_OBJECT_CLASS_NAME));
5368 /* Look for the list of Protocol statically allocated instances
5369 to fixup at runtime. Create a new list to hold Protocol
5370 statically allocated instances, if the list is not found. At
5371 present there is only another list, holding NSConstantString
5372 static instances to be fixed up at runtime. */
5373 for (chain = &objc_static_instances;
5374 *chain && TREE_VALUE (*chain) != protocol_struct_type;
5375 chain = &TREE_CHAIN (*chain));
5378 *chain = tree_cons (NULL_TREE, protocol_struct_type, NULL_TREE);
5379 add_objc_string (TYPE_NAME (protocol_struct_type),
5383 /* Add this statically allocated instance to the Protocol list. */
5384 TREE_PURPOSE (*chain) = tree_cons (NULL_TREE,
5385 PROTOCOL_FORWARD_DECL (p),
5386 TREE_PURPOSE (*chain));
5393 /* This function is called by the parser when a @selector() expression
5394 is found, in order to compile it. It is only called by the parser
5395 and only to compile a @selector(). */
5397 build_selector_expr (selnamelist)
5402 /* Obtain the full selector name. */
5403 if (TREE_CODE (selnamelist) == IDENTIFIER_NODE)
5404 /* A unary selector. */
5405 selname = selnamelist;
5406 else if (TREE_CODE (selnamelist) == TREE_LIST)
5407 selname = build_keyword_selector (selnamelist);
5411 /* If we are required to check @selector() expressions as they
5412 are found, check that the selector has been declared. */
5413 if (warn_undeclared_selector)
5415 /* Look the selector up in the list of all known class and
5416 instance methods (up to this line) to check that the selector
5420 /* First try with instance methods. */
5421 hsh = hash_lookup (nst_method_hash_list, selname);
5423 /* If not found, try with class methods. */
5426 hsh = hash_lookup (cls_method_hash_list, selname);
5429 /* If still not found, print out a warning. */
5432 warning ("undeclared selector `%s'", IDENTIFIER_POINTER (selname));
5437 if (flag_typed_selectors)
5438 return build_typed_selector_reference (selname, 0);
5440 return build_selector_reference (selname);
5444 build_encode_expr (type)
5450 encode_type (type, obstack_object_size (&util_obstack),
5451 OBJC_ENCODE_INLINE_DEFS);
5452 obstack_1grow (&util_obstack, 0); /* null terminate string */
5453 string = obstack_finish (&util_obstack);
5455 /* Synthesize a string that represents the encoded struct/union. */
5456 result = my_build_string (strlen (string) + 1, string);
5457 obstack_free (&util_obstack, util_firstobj);
5462 build_ivar_reference (id)
5465 if (TREE_CODE (objc_method_context) == CLASS_METHOD_DECL)
5467 /* Historically, a class method that produced objects (factory
5468 method) would assign `self' to the instance that it
5469 allocated. This would effectively turn the class method into
5470 an instance method. Following this assignment, the instance
5471 variables could be accessed. That practice, while safe,
5472 violates the simple rule that a class method should not refer
5473 to an instance variable. It's better to catch the cases
5474 where this is done unknowingly than to support the above
5476 warning ("instance variable `%s' accessed in class method",
5477 IDENTIFIER_POINTER (id));
5478 TREE_TYPE (self_decl) = instance_type; /* cast */
5481 return build_component_ref (build_indirect_ref (self_decl, "->"), id);
5484 /* Compute a hash value for a given method SEL_NAME. */
5487 hash_func (sel_name)
5490 const unsigned char *s
5491 = (const unsigned char *)IDENTIFIER_POINTER (sel_name);
5495 h = h * 67 + *s++ - 113;
5502 nst_method_hash_list = (hash *) ggc_calloc (SIZEHASHTABLE, sizeof (hash));
5503 cls_method_hash_list = (hash *) ggc_calloc (SIZEHASHTABLE, sizeof (hash));
5506 /* WARNING!!!! hash_enter is called with a method, and will peek
5507 inside to find its selector! But hash_lookup is given a selector
5508 directly, and looks for the selector that's inside the found
5509 entry's key (method) for comparison. */
5512 hash_enter (hashlist, method)
5517 int slot = hash_func (METHOD_SEL_NAME (method)) % SIZEHASHTABLE;
5519 obj = (hash) ggc_alloc (sizeof (struct hashed_entry));
5521 obj->next = hashlist[slot];
5524 hashlist[slot] = obj; /* append to front */
5528 hash_lookup (hashlist, sel_name)
5534 target = hashlist[hash_func (sel_name) % SIZEHASHTABLE];
5538 if (sel_name == METHOD_SEL_NAME (target->key))
5541 target = target->next;
5547 hash_add_attr (entry, value)
5553 obj = (attr) ggc_alloc (sizeof (struct hashed_attribute));
5554 obj->next = entry->list;
5557 entry->list = obj; /* append to front */
5561 lookup_method (mchain, method)
5567 if (TREE_CODE (method) == IDENTIFIER_NODE)
5570 key = METHOD_SEL_NAME (method);
5574 if (METHOD_SEL_NAME (mchain) == key)
5577 mchain = TREE_CHAIN (mchain);
5583 lookup_instance_method_static (interface, ident)
5587 tree inter = interface;
5588 tree chain = CLASS_NST_METHODS (inter);
5589 tree meth = NULL_TREE;
5593 if ((meth = lookup_method (chain, ident)))
5596 if (CLASS_CATEGORY_LIST (inter))
5598 tree category = CLASS_CATEGORY_LIST (inter);
5599 chain = CLASS_NST_METHODS (category);
5603 if ((meth = lookup_method (chain, ident)))
5606 /* Check for instance methods in protocols in categories. */
5607 if (CLASS_PROTOCOL_LIST (category))
5609 if ((meth = (lookup_method_in_protocol_list
5610 (CLASS_PROTOCOL_LIST (category), ident, 0))))
5614 if ((category = CLASS_CATEGORY_LIST (category)))
5615 chain = CLASS_NST_METHODS (category);
5620 if (CLASS_PROTOCOL_LIST (inter))
5622 if ((meth = (lookup_method_in_protocol_list
5623 (CLASS_PROTOCOL_LIST (inter), ident, 0))))
5627 if ((inter = lookup_interface (CLASS_SUPER_NAME (inter))))
5628 chain = CLASS_NST_METHODS (inter);
5636 lookup_class_method_static (interface, ident)
5640 tree inter = interface;
5641 tree chain = CLASS_CLS_METHODS (inter);
5642 tree meth = NULL_TREE;
5643 tree root_inter = NULL_TREE;
5647 if ((meth = lookup_method (chain, ident)))
5650 if (CLASS_CATEGORY_LIST (inter))
5652 tree category = CLASS_CATEGORY_LIST (inter);
5653 chain = CLASS_CLS_METHODS (category);
5657 if ((meth = lookup_method (chain, ident)))
5660 /* Check for class methods in protocols in categories. */
5661 if (CLASS_PROTOCOL_LIST (category))
5663 if ((meth = (lookup_method_in_protocol_list
5664 (CLASS_PROTOCOL_LIST (category), ident, 1))))
5668 if ((category = CLASS_CATEGORY_LIST (category)))
5669 chain = CLASS_CLS_METHODS (category);
5674 /* Check for class methods in protocols. */
5675 if (CLASS_PROTOCOL_LIST (inter))
5677 if ((meth = (lookup_method_in_protocol_list
5678 (CLASS_PROTOCOL_LIST (inter), ident, 1))))
5683 if ((inter = lookup_interface (CLASS_SUPER_NAME (inter))))
5684 chain = CLASS_CLS_METHODS (inter);
5688 /* If no class (factory) method was found, check if an _instance_
5689 method of the same name exists in the root class. This is what
5690 the Objective-C runtime will do. */
5691 return lookup_instance_method_static (root_inter, ident);
5695 add_class_method (class, method)
5702 if (!(mth = lookup_method (CLASS_CLS_METHODS (class), method)))
5704 /* put method on list in reverse order */
5705 TREE_CHAIN (method) = CLASS_CLS_METHODS (class);
5706 CLASS_CLS_METHODS (class) = method;
5710 if (TREE_CODE (class) == CLASS_IMPLEMENTATION_TYPE)
5711 error ("duplicate definition of class method `%s'",
5712 IDENTIFIER_POINTER (METHOD_SEL_NAME (mth)));
5715 /* Check types; if different, complain. */
5716 if (!comp_proto_with_proto (method, mth))
5717 error ("duplicate declaration of class method `%s'",
5718 IDENTIFIER_POINTER (METHOD_SEL_NAME (mth)));
5722 if (!(hsh = hash_lookup (cls_method_hash_list, METHOD_SEL_NAME (method))))
5724 /* Install on a global chain. */
5725 hash_enter (cls_method_hash_list, method);
5729 /* Check types; if different, add to a list. */
5730 if (!comp_proto_with_proto (method, hsh->key))
5731 hash_add_attr (hsh, method);
5737 add_instance_method (class, method)
5744 if (!(mth = lookup_method (CLASS_NST_METHODS (class), method)))
5746 /* Put method on list in reverse order. */
5747 TREE_CHAIN (method) = CLASS_NST_METHODS (class);
5748 CLASS_NST_METHODS (class) = method;
5752 if (TREE_CODE (class) == CLASS_IMPLEMENTATION_TYPE)
5753 error ("duplicate definition of instance method `%s'",
5754 IDENTIFIER_POINTER (METHOD_SEL_NAME (mth)));
5757 /* Check types; if different, complain. */
5758 if (!comp_proto_with_proto (method, mth))
5759 error ("duplicate declaration of instance method `%s'",
5760 IDENTIFIER_POINTER (METHOD_SEL_NAME (mth)));
5764 if (!(hsh = hash_lookup (nst_method_hash_list, METHOD_SEL_NAME (method))))
5766 /* Install on a global chain. */
5767 hash_enter (nst_method_hash_list, method);
5771 /* Check types; if different, add to a list. */
5772 if (!comp_proto_with_proto (method, hsh->key))
5773 hash_add_attr (hsh, method);
5782 /* Put interfaces on list in reverse order. */
5783 TREE_CHAIN (class) = interface_chain;
5784 interface_chain = class;
5785 return interface_chain;
5789 add_category (class, category)
5793 /* Put categories on list in reverse order. */
5794 tree cat = CLASS_CATEGORY_LIST (class);
5798 if (CLASS_SUPER_NAME (cat) == CLASS_SUPER_NAME (category))
5799 warning ("duplicate interface declaration for category `%s(%s)'",
5800 IDENTIFIER_POINTER (CLASS_NAME (class)),
5801 IDENTIFIER_POINTER (CLASS_SUPER_NAME (category)));
5802 cat = CLASS_CATEGORY_LIST (cat);
5805 CLASS_CATEGORY_LIST (category) = CLASS_CATEGORY_LIST (class);
5806 CLASS_CATEGORY_LIST (class) = category;
5809 /* Called after parsing each instance variable declaration. Necessary to
5810 preserve typedefs and implement public/private...
5812 PUBLIC is 1 for public, 0 for protected, and 2 for private. */
5815 add_instance_variable (class, public, declarator, declspecs, width)
5822 tree field_decl, raw_decl;
5824 raw_decl = build_tree_list (declspecs, declarator);
5826 if (CLASS_RAW_IVARS (class))
5827 chainon (CLASS_RAW_IVARS (class), raw_decl);
5829 CLASS_RAW_IVARS (class) = raw_decl;
5831 field_decl = grokfield (input_filename, lineno,
5832 declarator, declspecs, width);
5834 /* Overload the public attribute, it is not used for FIELD_DECLs. */
5838 TREE_PUBLIC (field_decl) = 0;
5839 TREE_PRIVATE (field_decl) = 0;
5840 TREE_PROTECTED (field_decl) = 1;
5844 TREE_PUBLIC (field_decl) = 1;
5845 TREE_PRIVATE (field_decl) = 0;
5846 TREE_PROTECTED (field_decl) = 0;
5850 TREE_PUBLIC (field_decl) = 0;
5851 TREE_PRIVATE (field_decl) = 1;
5852 TREE_PROTECTED (field_decl) = 0;
5857 if (CLASS_IVARS (class))
5858 chainon (CLASS_IVARS (class), field_decl);
5860 CLASS_IVARS (class) = field_decl;
5866 is_ivar (decl_chain, ident)
5870 for ( ; decl_chain; decl_chain = TREE_CHAIN (decl_chain))
5871 if (DECL_NAME (decl_chain) == ident)
5876 /* True if the ivar is private and we are not in its implementation. */
5882 if (TREE_PRIVATE (decl)
5883 && ! is_ivar (CLASS_IVARS (implementation_template), DECL_NAME (decl)))
5885 error ("instance variable `%s' is declared private",
5886 IDENTIFIER_POINTER (DECL_NAME (decl)));
5893 /* We have an instance variable reference;, check to see if it is public. */
5896 is_public (expr, identifier)
5900 tree basetype = TREE_TYPE (expr);
5901 enum tree_code code = TREE_CODE (basetype);
5904 if (code == RECORD_TYPE)
5906 if (TREE_STATIC_TEMPLATE (basetype))
5908 if (!lookup_interface (TYPE_NAME (basetype)))
5910 error ("cannot find interface declaration for `%s'",
5911 IDENTIFIER_POINTER (TYPE_NAME (basetype)));
5915 if ((decl = is_ivar (TYPE_FIELDS (basetype), identifier)))
5917 if (TREE_PUBLIC (decl))
5920 /* Important difference between the Stepstone translator:
5921 all instance variables should be public within the context
5922 of the implementation. */
5923 if (objc_implementation_context
5924 && (((TREE_CODE (objc_implementation_context)
5925 == CLASS_IMPLEMENTATION_TYPE)
5926 || (TREE_CODE (objc_implementation_context)
5927 == CATEGORY_IMPLEMENTATION_TYPE))
5928 && (CLASS_NAME (objc_implementation_context)
5929 == TYPE_NAME (basetype))))
5930 return ! is_private (decl);
5932 error ("instance variable `%s' is declared %s",
5933 IDENTIFIER_POINTER (identifier),
5934 TREE_PRIVATE (decl) ? "private" : "protected");
5939 else if (objc_implementation_context && (basetype == objc_object_reference))
5941 TREE_TYPE (expr) = uprivate_record;
5942 warning ("static access to object of type `id'");
5949 /* Make sure all entries in CHAIN are also in LIST. */
5952 check_methods (chain, list, mtype)
5961 if (!lookup_method (list, chain))
5965 if (TREE_CODE (objc_implementation_context)
5966 == CLASS_IMPLEMENTATION_TYPE)
5967 warning ("incomplete implementation of class `%s'",
5968 IDENTIFIER_POINTER (CLASS_NAME (objc_implementation_context)));
5969 else if (TREE_CODE (objc_implementation_context)
5970 == CATEGORY_IMPLEMENTATION_TYPE)
5971 warning ("incomplete implementation of category `%s'",
5972 IDENTIFIER_POINTER (CLASS_SUPER_NAME (objc_implementation_context)));
5976 warning ("method definition for `%c%s' not found",
5977 mtype, IDENTIFIER_POINTER (METHOD_SEL_NAME (chain)));
5980 chain = TREE_CHAIN (chain);
5986 /* Check if CLASS, or its superclasses, explicitly conforms to PROTOCOL. */
5989 conforms_to_protocol (class, protocol)
5993 if (TREE_CODE (protocol) == PROTOCOL_INTERFACE_TYPE)
5995 tree p = CLASS_PROTOCOL_LIST (class);
5996 while (p && TREE_VALUE (p) != protocol)
6001 tree super = (CLASS_SUPER_NAME (class)
6002 ? lookup_interface (CLASS_SUPER_NAME (class))
6004 int tmp = super ? conforms_to_protocol (super, protocol) : 0;
6013 /* Make sure all methods in CHAIN are accessible as MTYPE methods in
6014 CONTEXT. This is one of two mechanisms to check protocol integrity. */
6017 check_methods_accessible (chain, context, mtype)
6024 tree base_context = context;
6028 context = base_context;
6032 list = CLASS_CLS_METHODS (context);
6034 list = CLASS_NST_METHODS (context);
6036 if (lookup_method (list, chain))
6039 else if (TREE_CODE (context) == CLASS_IMPLEMENTATION_TYPE
6040 || TREE_CODE (context) == CLASS_INTERFACE_TYPE)
6041 context = (CLASS_SUPER_NAME (context)
6042 ? lookup_interface (CLASS_SUPER_NAME (context))
6045 else if (TREE_CODE (context) == CATEGORY_IMPLEMENTATION_TYPE
6046 || TREE_CODE (context) == CATEGORY_INTERFACE_TYPE)
6047 context = (CLASS_NAME (context)
6048 ? lookup_interface (CLASS_NAME (context))
6054 if (context == NULL_TREE)
6058 if (TREE_CODE (objc_implementation_context)
6059 == CLASS_IMPLEMENTATION_TYPE)
6060 warning ("incomplete implementation of class `%s'",
6062 (CLASS_NAME (objc_implementation_context)));
6063 else if (TREE_CODE (objc_implementation_context)
6064 == CATEGORY_IMPLEMENTATION_TYPE)
6065 warning ("incomplete implementation of category `%s'",
6067 (CLASS_SUPER_NAME (objc_implementation_context)));
6070 warning ("method definition for `%c%s' not found",
6071 mtype, IDENTIFIER_POINTER (METHOD_SEL_NAME (chain)));
6074 chain = TREE_CHAIN (chain); /* next method... */
6079 /* Check whether the current interface (accessible via
6080 'objc_implementation_context') actually implements protocol P, along
6081 with any protocols that P inherits. */
6084 check_protocol (p, type, name)
6089 if (TREE_CODE (p) == PROTOCOL_INTERFACE_TYPE)
6093 /* Ensure that all protocols have bodies! */
6096 f1 = check_methods (PROTOCOL_CLS_METHODS (p),
6097 CLASS_CLS_METHODS (objc_implementation_context),
6099 f2 = check_methods (PROTOCOL_NST_METHODS (p),
6100 CLASS_NST_METHODS (objc_implementation_context),
6105 f1 = check_methods_accessible (PROTOCOL_CLS_METHODS (p),
6106 objc_implementation_context,
6108 f2 = check_methods_accessible (PROTOCOL_NST_METHODS (p),
6109 objc_implementation_context,
6114 warning ("%s `%s' does not fully implement the `%s' protocol",
6115 type, name, IDENTIFIER_POINTER (PROTOCOL_NAME (p)));
6118 /* Check protocols recursively. */
6119 if (PROTOCOL_LIST (p))
6121 tree subs = PROTOCOL_LIST (p);
6123 lookup_interface (CLASS_SUPER_NAME (implementation_template));
6127 tree sub = TREE_VALUE (subs);
6129 /* If the superclass does not conform to the protocols
6130 inherited by P, then we must! */
6131 if (!super_class || !conforms_to_protocol (super_class, sub))
6132 check_protocol (sub, type, name);
6133 subs = TREE_CHAIN (subs);
6138 /* Check whether the current interface (accessible via
6139 'objc_implementation_context') actually implements the protocols listed
6143 check_protocols (proto_list, type, name)
6148 for ( ; proto_list; proto_list = TREE_CHAIN (proto_list))
6150 tree p = TREE_VALUE (proto_list);
6152 check_protocol (p, type, name);
6156 /* Make sure that the class CLASS_NAME is defined
6157 CODE says which kind of thing CLASS_NAME ought to be.
6158 It can be CLASS_INTERFACE_TYPE, CLASS_IMPLEMENTATION_TYPE,
6159 CATEGORY_INTERFACE_TYPE, or CATEGORY_IMPLEMENTATION_TYPE. */
6162 start_class (code, class_name, super_name, protocol_list)
6163 enum tree_code code;
6170 if (objc_implementation_context)
6172 warning ("`@end' missing in implementation context");
6173 finish_class (objc_implementation_context);
6174 objc_ivar_chain = NULL_TREE;
6175 objc_implementation_context = NULL_TREE;
6178 class = make_node (code);
6179 TYPE_BINFO (class) = make_tree_vec (BINFO_ELTS);
6181 CLASS_NAME (class) = class_name;
6182 CLASS_SUPER_NAME (class) = super_name;
6183 CLASS_CLS_METHODS (class) = NULL_TREE;
6185 if (! is_class_name (class_name) && (decl = lookup_name (class_name)))
6187 error ("`%s' redeclared as different kind of symbol",
6188 IDENTIFIER_POINTER (class_name));
6189 error_with_decl (decl, "previous declaration of `%s'");
6192 if (code == CLASS_IMPLEMENTATION_TYPE)
6197 for (chain = implemented_classes; chain; chain = TREE_CHAIN (chain))
6198 if (TREE_VALUE (chain) == class_name)
6200 error ("reimplementation of class `%s'",
6201 IDENTIFIER_POINTER (class_name));
6202 return error_mark_node;
6204 implemented_classes = tree_cons (NULL_TREE, class_name,
6205 implemented_classes);
6208 /* Pre-build the following entities - for speed/convenience. */
6210 self_id = get_identifier ("self");
6212 ucmd_id = get_identifier ("_cmd");
6215 = build_tree_list (get_identifier ("__unused__"), NULL_TREE);
6216 if (!objc_super_template)
6217 objc_super_template = build_super_template ();
6219 /* Reset for multiple classes per file. */
6222 objc_implementation_context = class;
6224 /* Lookup the interface for this implementation. */
6226 if (!(implementation_template = lookup_interface (class_name)))
6228 warning ("cannot find interface declaration for `%s'",
6229 IDENTIFIER_POINTER (class_name));
6230 add_class (implementation_template = objc_implementation_context);
6233 /* If a super class has been specified in the implementation,
6234 insure it conforms to the one specified in the interface. */
6237 && (super_name != CLASS_SUPER_NAME (implementation_template)))
6239 tree previous_name = CLASS_SUPER_NAME (implementation_template);
6240 const char *const name =
6241 previous_name ? IDENTIFIER_POINTER (previous_name) : "";
6242 error ("conflicting super class name `%s'",
6243 IDENTIFIER_POINTER (super_name));
6244 error ("previous declaration of `%s'", name);
6247 else if (! super_name)
6249 CLASS_SUPER_NAME (objc_implementation_context)
6250 = CLASS_SUPER_NAME (implementation_template);
6254 else if (code == CLASS_INTERFACE_TYPE)
6256 if (lookup_interface (class_name))
6257 warning ("duplicate interface declaration for class `%s'",
6258 IDENTIFIER_POINTER (class_name));
6263 CLASS_PROTOCOL_LIST (class)
6264 = lookup_and_install_protocols (protocol_list);
6267 else if (code == CATEGORY_INTERFACE_TYPE)
6269 tree class_category_is_assoc_with;
6271 /* For a category, class_name is really the name of the class that
6272 the following set of methods will be associated with. We must
6273 find the interface so that can derive the objects template. */
6275 if (!(class_category_is_assoc_with = lookup_interface (class_name)))
6277 error ("cannot find interface declaration for `%s'",
6278 IDENTIFIER_POINTER (class_name));
6279 exit (FATAL_EXIT_CODE);
6282 add_category (class_category_is_assoc_with, class);
6285 CLASS_PROTOCOL_LIST (class)
6286 = lookup_and_install_protocols (protocol_list);
6289 else if (code == CATEGORY_IMPLEMENTATION_TYPE)
6291 /* Pre-build the following entities for speed/convenience. */
6293 self_id = get_identifier ("self");
6295 ucmd_id = get_identifier ("_cmd");
6298 = build_tree_list (get_identifier ("__unused__"), NULL_TREE);
6299 if (!objc_super_template)
6300 objc_super_template = build_super_template ();
6302 /* Reset for multiple classes per file. */
6305 objc_implementation_context = class;
6307 /* For a category, class_name is really the name of the class that
6308 the following set of methods will be associated with. We must
6309 find the interface so that can derive the objects template. */
6311 if (!(implementation_template = lookup_interface (class_name)))
6313 error ("cannot find interface declaration for `%s'",
6314 IDENTIFIER_POINTER (class_name));
6315 exit (FATAL_EXIT_CODE);
6322 continue_class (class)
6325 if (TREE_CODE (class) == CLASS_IMPLEMENTATION_TYPE
6326 || TREE_CODE (class) == CATEGORY_IMPLEMENTATION_TYPE)
6328 struct imp_entry *imp_entry;
6331 /* Check consistency of the instance variables. */
6333 if (CLASS_IVARS (class))
6334 check_ivars (implementation_template, class);
6336 /* code generation */
6338 ivar_context = build_private_template (implementation_template);
6340 if (!objc_class_template)
6341 build_class_template ();
6343 imp_entry = (struct imp_entry *) ggc_alloc (sizeof (struct imp_entry));
6345 imp_entry->next = imp_list;
6346 imp_entry->imp_context = class;
6347 imp_entry->imp_template = implementation_template;
6349 synth_forward_declarations ();
6350 imp_entry->class_decl = UOBJC_CLASS_decl;
6351 imp_entry->meta_decl = UOBJC_METACLASS_decl;
6353 /* Append to front and increment count. */
6354 imp_list = imp_entry;
6355 if (TREE_CODE (class) == CLASS_IMPLEMENTATION_TYPE)
6360 return ivar_context;
6363 else if (TREE_CODE (class) == CLASS_INTERFACE_TYPE)
6365 tree record = xref_tag (RECORD_TYPE, CLASS_NAME (class));
6367 if (!TYPE_FIELDS (record))
6369 finish_struct (record, get_class_ivars (class), NULL_TREE);
6370 CLASS_STATIC_TEMPLATE (class) = record;
6372 /* Mark this record as a class template for static typing. */
6373 TREE_STATIC_TEMPLATE (record) = 1;
6380 return error_mark_node;
6383 /* This is called once we see the "@end" in an interface/implementation. */
6386 finish_class (class)
6389 if (TREE_CODE (class) == CLASS_IMPLEMENTATION_TYPE)
6391 /* All code generation is done in finish_objc. */
6393 if (implementation_template != objc_implementation_context)
6395 /* Ensure that all method listed in the interface contain bodies. */
6396 check_methods (CLASS_CLS_METHODS (implementation_template),
6397 CLASS_CLS_METHODS (objc_implementation_context), '+');
6398 check_methods (CLASS_NST_METHODS (implementation_template),
6399 CLASS_NST_METHODS (objc_implementation_context), '-');
6401 if (CLASS_PROTOCOL_LIST (implementation_template))
6402 check_protocols (CLASS_PROTOCOL_LIST (implementation_template),
6404 IDENTIFIER_POINTER (CLASS_NAME (objc_implementation_context)));
6408 else if (TREE_CODE (class) == CATEGORY_IMPLEMENTATION_TYPE)
6410 tree category = CLASS_CATEGORY_LIST (implementation_template);
6412 /* Find the category interface from the class it is associated with. */
6415 if (CLASS_SUPER_NAME (class) == CLASS_SUPER_NAME (category))
6417 category = CLASS_CATEGORY_LIST (category);
6422 /* Ensure all method listed in the interface contain bodies. */
6423 check_methods (CLASS_CLS_METHODS (category),
6424 CLASS_CLS_METHODS (objc_implementation_context), '+');
6425 check_methods (CLASS_NST_METHODS (category),
6426 CLASS_NST_METHODS (objc_implementation_context), '-');
6428 if (CLASS_PROTOCOL_LIST (category))
6429 check_protocols (CLASS_PROTOCOL_LIST (category),
6431 IDENTIFIER_POINTER (CLASS_SUPER_NAME (objc_implementation_context)));
6435 else if (TREE_CODE (class) == CLASS_INTERFACE_TYPE)
6438 const char *class_name = IDENTIFIER_POINTER (CLASS_NAME (class));
6439 char *string = (char *) alloca (strlen (class_name) + 3);
6441 /* extern struct objc_object *_<my_name>; */
6443 sprintf (string, "_%s", class_name);
6445 decl_specs = build_tree_list (NULL_TREE, ridpointers[(int) RID_EXTERN]);
6446 decl_specs = tree_cons (NULL_TREE, objc_object_reference, decl_specs);
6447 define_decl (build1 (INDIRECT_REF, NULL_TREE, get_identifier (string)),
6453 add_protocol (protocol)
6456 /* Put protocol on list in reverse order. */
6457 TREE_CHAIN (protocol) = protocol_chain;
6458 protocol_chain = protocol;
6459 return protocol_chain;
6463 lookup_protocol (ident)
6468 for (chain = protocol_chain; chain; chain = TREE_CHAIN (chain))
6469 if (ident == PROTOCOL_NAME (chain))
6475 /* This function forward declares the protocols named by NAMES. If
6476 they are already declared or defined, the function has no effect. */
6479 objc_declare_protocols (names)
6484 for (list = names; list; list = TREE_CHAIN (list))
6486 tree name = TREE_VALUE (list);
6488 if (lookup_protocol (name) == NULL_TREE)
6490 tree protocol = make_node (PROTOCOL_INTERFACE_TYPE);
6492 TYPE_BINFO (protocol) = make_tree_vec (2);
6493 PROTOCOL_NAME (protocol) = name;
6494 PROTOCOL_LIST (protocol) = NULL_TREE;
6495 add_protocol (protocol);
6496 PROTOCOL_DEFINED (protocol) = 0;
6497 PROTOCOL_FORWARD_DECL (protocol) = NULL_TREE;
6503 start_protocol (code, name, list)
6504 enum tree_code code;
6510 /* This is as good a place as any. Need to invoke
6511 push_tag_toplevel. */
6512 if (!objc_protocol_template)
6513 objc_protocol_template = build_protocol_template ();
6515 protocol = lookup_protocol (name);
6519 protocol = make_node (code);
6520 TYPE_BINFO (protocol) = make_tree_vec (2);
6522 PROTOCOL_NAME (protocol) = name;
6523 PROTOCOL_LIST (protocol) = lookup_and_install_protocols (list);
6524 add_protocol (protocol);
6525 PROTOCOL_DEFINED (protocol) = 1;
6526 PROTOCOL_FORWARD_DECL (protocol) = NULL_TREE;
6528 check_protocol_recursively (protocol, list);
6530 else if (! PROTOCOL_DEFINED (protocol))
6532 PROTOCOL_DEFINED (protocol) = 1;
6533 PROTOCOL_LIST (protocol) = lookup_and_install_protocols (list);
6535 check_protocol_recursively (protocol, list);
6539 warning ("duplicate declaration for protocol `%s'",
6540 IDENTIFIER_POINTER (name));
6546 finish_protocol (protocol)
6547 tree protocol ATTRIBUTE_UNUSED;
6552 /* "Encode" a data type into a string, which grows in util_obstack.
6553 ??? What is the FORMAT? Someone please document this! */
6556 encode_type_qualifiers (declspecs)
6561 for (spec = declspecs; spec; spec = TREE_CHAIN (spec))
6563 if (ridpointers[(int) RID_CONST] == TREE_VALUE (spec))
6564 obstack_1grow (&util_obstack, 'r');
6565 else if (ridpointers[(int) RID_IN] == TREE_VALUE (spec))
6566 obstack_1grow (&util_obstack, 'n');
6567 else if (ridpointers[(int) RID_INOUT] == TREE_VALUE (spec))
6568 obstack_1grow (&util_obstack, 'N');
6569 else if (ridpointers[(int) RID_OUT] == TREE_VALUE (spec))
6570 obstack_1grow (&util_obstack, 'o');
6571 else if (ridpointers[(int) RID_BYCOPY] == TREE_VALUE (spec))
6572 obstack_1grow (&util_obstack, 'O');
6573 else if (ridpointers[(int) RID_BYREF] == TREE_VALUE (spec))
6574 obstack_1grow (&util_obstack, 'R');
6575 else if (ridpointers[(int) RID_ONEWAY] == TREE_VALUE (spec))
6576 obstack_1grow (&util_obstack, 'V');
6580 /* Encode a pointer type. */
6583 encode_pointer (type, curtype, format)
6588 tree pointer_to = TREE_TYPE (type);
6590 if (TREE_CODE (pointer_to) == RECORD_TYPE)
6592 if (TYPE_NAME (pointer_to)
6593 && TREE_CODE (TYPE_NAME (pointer_to)) == IDENTIFIER_NODE)
6595 const char *name = IDENTIFIER_POINTER (TYPE_NAME (pointer_to));
6597 if (strcmp (name, TAG_OBJECT) == 0) /* '@' */
6599 obstack_1grow (&util_obstack, '@');
6602 else if (TREE_STATIC_TEMPLATE (pointer_to))
6604 if (generating_instance_variables)
6606 obstack_1grow (&util_obstack, '@');
6607 obstack_1grow (&util_obstack, '"');
6608 obstack_grow (&util_obstack, name, strlen (name));
6609 obstack_1grow (&util_obstack, '"');
6614 obstack_1grow (&util_obstack, '@');
6618 else if (strcmp (name, TAG_CLASS) == 0) /* '#' */
6620 obstack_1grow (&util_obstack, '#');
6623 else if (strcmp (name, TAG_SELECTOR) == 0) /* ':' */
6625 obstack_1grow (&util_obstack, ':');
6630 else if (TREE_CODE (pointer_to) == INTEGER_TYPE
6631 && TYPE_MODE (pointer_to) == QImode)
6633 obstack_1grow (&util_obstack, '*');
6637 /* We have a type that does not get special treatment. */
6639 /* NeXT extension */
6640 obstack_1grow (&util_obstack, '^');
6641 encode_type (pointer_to, curtype, format);
6645 encode_array (type, curtype, format)
6650 tree an_int_cst = TYPE_SIZE (type);
6651 tree array_of = TREE_TYPE (type);
6654 /* An incomplete array is treated like a pointer. */
6655 if (an_int_cst == NULL)
6657 encode_pointer (type, curtype, format);
6661 sprintf (buffer, "[%ld",
6662 (long) (TREE_INT_CST_LOW (an_int_cst)
6663 / TREE_INT_CST_LOW (TYPE_SIZE (array_of))));
6665 obstack_grow (&util_obstack, buffer, strlen (buffer));
6666 encode_type (array_of, curtype, format);
6667 obstack_1grow (&util_obstack, ']');
6672 encode_aggregate_within (type, curtype, format, left, right)
6679 /* The RECORD_TYPE may in fact be a typedef! For purposes
6680 of encoding, we need the real underlying enchilada. */
6681 if (TYPE_MAIN_VARIANT (type))
6682 type = TYPE_MAIN_VARIANT (type);
6684 if (obstack_object_size (&util_obstack) > 0
6685 && *(obstack_next_free (&util_obstack) - 1) == '^')
6687 tree name = TYPE_NAME (type);
6689 /* we have a reference; this is a NeXT extension. */
6691 if (obstack_object_size (&util_obstack) - curtype == 1
6692 && format == OBJC_ENCODE_INLINE_DEFS)
6694 /* Output format of struct for first level only. */
6695 tree fields = TYPE_FIELDS (type);
6697 if (name && TREE_CODE (name) == IDENTIFIER_NODE)
6699 obstack_1grow (&util_obstack, left);
6700 obstack_grow (&util_obstack,
6701 IDENTIFIER_POINTER (name),
6702 strlen (IDENTIFIER_POINTER (name)));
6703 obstack_1grow (&util_obstack, '=');
6707 obstack_1grow (&util_obstack, left);
6708 obstack_grow (&util_obstack, "?=", 2);
6711 for ( ; fields; fields = TREE_CHAIN (fields))
6712 encode_field_decl (fields, curtype, format);
6714 obstack_1grow (&util_obstack, right);
6717 else if (name && TREE_CODE (name) == IDENTIFIER_NODE)
6719 obstack_1grow (&util_obstack, left);
6720 obstack_grow (&util_obstack,
6721 IDENTIFIER_POINTER (name),
6722 strlen (IDENTIFIER_POINTER (name)));
6723 obstack_1grow (&util_obstack, right);
6728 /* We have an untagged structure or a typedef. */
6729 obstack_1grow (&util_obstack, left);
6730 obstack_1grow (&util_obstack, '?');
6731 obstack_1grow (&util_obstack, right);
6737 tree name = TYPE_NAME (type);
6738 tree fields = TYPE_FIELDS (type);
6740 if (format == OBJC_ENCODE_INLINE_DEFS
6741 || generating_instance_variables)
6743 obstack_1grow (&util_obstack, left);
6744 if (name && TREE_CODE (name) == IDENTIFIER_NODE)
6745 obstack_grow (&util_obstack,
6746 IDENTIFIER_POINTER (name),
6747 strlen (IDENTIFIER_POINTER (name)));
6749 obstack_1grow (&util_obstack, '?');
6751 obstack_1grow (&util_obstack, '=');
6753 for (; fields; fields = TREE_CHAIN (fields))
6755 if (generating_instance_variables)
6757 tree fname = DECL_NAME (fields);
6759 obstack_1grow (&util_obstack, '"');
6760 if (fname && TREE_CODE (fname) == IDENTIFIER_NODE)
6762 obstack_grow (&util_obstack,
6763 IDENTIFIER_POINTER (fname),
6764 strlen (IDENTIFIER_POINTER (fname)));
6767 obstack_1grow (&util_obstack, '"');
6770 encode_field_decl (fields, curtype, format);
6773 obstack_1grow (&util_obstack, right);
6778 obstack_1grow (&util_obstack, left);
6779 if (name && TREE_CODE (name) == IDENTIFIER_NODE)
6780 obstack_grow (&util_obstack,
6781 IDENTIFIER_POINTER (name),
6782 strlen (IDENTIFIER_POINTER (name)));
6784 /* We have an untagged structure or a typedef. */
6785 obstack_1grow (&util_obstack, '?');
6787 obstack_1grow (&util_obstack, right);
6793 encode_aggregate (type, curtype, format)
6798 enum tree_code code = TREE_CODE (type);
6804 encode_aggregate_within(type, curtype, format, '{', '}');
6809 encode_aggregate_within(type, curtype, format, '(', ')');
6814 obstack_1grow (&util_obstack, 'i');
6822 /* Support bitfields. The current version of Objective-C does not support
6823 them. The string will consist of one or more "b:n"'s where n is an
6824 integer describing the width of the bitfield. Currently, classes in
6825 the kit implement a method "-(char *)describeBitfieldStruct:" that
6826 simulates this. If they do not implement this method, the archiver
6827 assumes the bitfield is 16 bits wide (padded if necessary) and packed
6828 according to the GNU compiler. After looking at the "kit", it appears
6829 that all classes currently rely on this default behavior, rather than
6830 hand generating this string (which is tedious). */
6833 encode_bitfield (width)
6837 sprintf (buffer, "b%d", width);
6838 obstack_grow (&util_obstack, buffer, strlen (buffer));
6841 /* FORMAT will be OBJC_ENCODE_INLINE_DEFS or OBJC_ENCODE_DONT_INLINE_DEFS. */
6844 encode_type (type, curtype, format)
6849 enum tree_code code = TREE_CODE (type);
6851 if (code == INTEGER_TYPE)
6853 if (integer_zerop (TYPE_MIN_VALUE (type)))
6855 /* Unsigned integer types. */
6857 if (TYPE_MODE (type) == QImode)
6858 obstack_1grow (&util_obstack, 'C');
6859 else if (TYPE_MODE (type) == HImode)
6860 obstack_1grow (&util_obstack, 'S');
6861 else if (TYPE_MODE (type) == SImode)
6863 if (type == long_unsigned_type_node)
6864 obstack_1grow (&util_obstack, 'L');
6866 obstack_1grow (&util_obstack, 'I');
6868 else if (TYPE_MODE (type) == DImode)
6869 obstack_1grow (&util_obstack, 'Q');
6873 /* Signed integer types. */
6875 if (TYPE_MODE (type) == QImode)
6876 obstack_1grow (&util_obstack, 'c');
6877 else if (TYPE_MODE (type) == HImode)
6878 obstack_1grow (&util_obstack, 's');
6879 else if (TYPE_MODE (type) == SImode)
6881 if (type == long_integer_type_node)
6882 obstack_1grow (&util_obstack, 'l');
6884 obstack_1grow (&util_obstack, 'i');
6887 else if (TYPE_MODE (type) == DImode)
6888 obstack_1grow (&util_obstack, 'q');
6892 else if (code == REAL_TYPE)
6894 /* Floating point types. */
6896 if (TYPE_MODE (type) == SFmode)
6897 obstack_1grow (&util_obstack, 'f');
6898 else if (TYPE_MODE (type) == DFmode
6899 || TYPE_MODE (type) == TFmode)
6900 obstack_1grow (&util_obstack, 'd');
6903 else if (code == VOID_TYPE)
6904 obstack_1grow (&util_obstack, 'v');
6906 else if (code == ARRAY_TYPE)
6907 encode_array (type, curtype, format);
6909 else if (code == POINTER_TYPE)
6910 encode_pointer (type, curtype, format);
6912 else if (code == RECORD_TYPE || code == UNION_TYPE || code == ENUMERAL_TYPE)
6913 encode_aggregate (type, curtype, format);
6915 else if (code == FUNCTION_TYPE) /* '?' */
6916 obstack_1grow (&util_obstack, '?');
6920 encode_complete_bitfield (position, type, size)
6925 enum tree_code code = TREE_CODE (type);
6927 char charType = '?';
6929 if (code == INTEGER_TYPE)
6931 if (integer_zerop (TYPE_MIN_VALUE (type)))
6933 /* Unsigned integer types. */
6935 if (TYPE_MODE (type) == QImode)
6937 else if (TYPE_MODE (type) == HImode)
6939 else if (TYPE_MODE (type) == SImode)
6941 if (type == long_unsigned_type_node)
6946 else if (TYPE_MODE (type) == DImode)
6951 /* Signed integer types. */
6953 if (TYPE_MODE (type) == QImode)
6955 else if (TYPE_MODE (type) == HImode)
6957 else if (TYPE_MODE (type) == SImode)
6959 if (type == long_integer_type_node)
6965 else if (TYPE_MODE (type) == DImode)
6969 else if (code == ENUMERAL_TYPE)
6974 sprintf (buffer, "b%d%c%d", position, charType, size);
6975 obstack_grow (&util_obstack, buffer, strlen (buffer));
6979 encode_field_decl (field_decl, curtype, format)
6986 type = TREE_TYPE (field_decl);
6988 /* If this field is obviously a bitfield, or is a bitfield that has been
6989 clobbered to look like a ordinary integer mode, go ahead and generate
6990 the bitfield typing information. */
6991 if (flag_next_runtime)
6993 if (DECL_BIT_FIELD_TYPE (field_decl))
6994 encode_bitfield (tree_low_cst (DECL_SIZE (field_decl), 1));
6996 encode_type (TREE_TYPE (field_decl), curtype, format);
7000 if (DECL_BIT_FIELD_TYPE (field_decl))
7001 encode_complete_bitfield (int_bit_position (field_decl),
7002 DECL_BIT_FIELD_TYPE (field_decl),
7003 tree_low_cst (DECL_SIZE (field_decl), 1));
7005 encode_type (TREE_TYPE (field_decl), curtype, format);
7010 expr_last (complex_expr)
7016 while ((next = TREE_OPERAND (complex_expr, 0)))
7017 complex_expr = next;
7019 return complex_expr;
7022 /* Transform a method definition into a function definition as follows:
7023 - synthesize the first two arguments, "self" and "_cmd". */
7026 start_method_def (method)
7031 /* Required to implement _msgSuper. */
7032 objc_method_context = method;
7033 UOBJC_SUPER_decl = NULL_TREE;
7035 /* Must be called BEFORE start_function. */
7038 /* Generate prototype declarations for arguments..."new-style". */
7040 if (TREE_CODE (objc_method_context) == INSTANCE_METHOD_DECL)
7041 decl_specs = build_tree_list (NULL_TREE, uprivate_record);
7043 /* Really a `struct objc_class *'. However, we allow people to
7044 assign to self, which changes its type midstream. */
7045 decl_specs = build_tree_list (NULL_TREE, objc_object_reference);
7047 push_parm_decl (build_tree_list
7048 (build_tree_list (decl_specs,
7049 build1 (INDIRECT_REF, NULL_TREE, self_id)),
7052 decl_specs = build_tree_list (NULL_TREE,
7053 xref_tag (RECORD_TYPE,
7054 get_identifier (TAG_SELECTOR)));
7055 push_parm_decl (build_tree_list
7056 (build_tree_list (decl_specs,
7057 build1 (INDIRECT_REF, NULL_TREE, ucmd_id)),
7060 /* Generate argument declarations if a keyword_decl. */
7061 if (METHOD_SEL_ARGS (method))
7063 tree arglist = METHOD_SEL_ARGS (method);
7066 tree arg_spec = TREE_PURPOSE (TREE_TYPE (arglist));
7067 tree arg_decl = TREE_VALUE (TREE_TYPE (arglist));
7071 tree last_expr = expr_last (arg_decl);
7073 /* Unite the abstract decl with its name. */
7074 TREE_OPERAND (last_expr, 0) = KEYWORD_ARG_NAME (arglist);
7075 push_parm_decl (build_tree_list
7076 (build_tree_list (arg_spec, arg_decl),
7079 /* Unhook: restore the abstract declarator. */
7080 TREE_OPERAND (last_expr, 0) = NULL_TREE;
7084 push_parm_decl (build_tree_list
7085 (build_tree_list (arg_spec,
7086 KEYWORD_ARG_NAME (arglist)),
7089 arglist = TREE_CHAIN (arglist);
7094 if (METHOD_ADD_ARGS (method) != NULL_TREE
7095 && METHOD_ADD_ARGS (method) != objc_ellipsis_node)
7097 /* We have a variable length selector - in "prototype" format. */
7098 tree akey = TREE_PURPOSE (METHOD_ADD_ARGS (method));
7101 /* This must be done prior to calling pushdecl. pushdecl is
7102 going to change our chain on us. */
7103 tree nextkey = TREE_CHAIN (akey);
7111 warn_with_method (message, mtype, method)
7112 const char *message;
7116 if (!diagnostic_count_diagnostic (global_dc, DK_WARNING))
7119 diagnostic_report_current_function (global_dc);
7121 /* Add a readable method name to the warning. */
7122 warning_with_file_and_line (DECL_SOURCE_FILE (method),
7123 DECL_SOURCE_LINE (method),
7126 gen_method_decl (method, errbuf));
7129 /* Return 1 if METHOD is consistent with PROTO. */
7132 comp_method_with_proto (method, proto)
7135 /* Create a function template node at most once. */
7136 if (!function1_template)
7137 function1_template = make_node (FUNCTION_TYPE);
7139 /* Install argument types - normally set by build_function_type. */
7140 TYPE_ARG_TYPES (function1_template) = get_arg_type_list (proto, METHOD_DEF, 0);
7142 /* install return type */
7143 TREE_TYPE (function1_template) = groktypename (TREE_TYPE (proto));
7145 return comptypes (TREE_TYPE (METHOD_DEFINITION (method)), function1_template);
7148 /* Return 1 if PROTO1 is consistent with PROTO2. */
7151 comp_proto_with_proto (proto0, proto1)
7152 tree proto0, proto1;
7154 /* Create a couple of function_template nodes at most once. */
7155 if (!function1_template)
7156 function1_template = make_node (FUNCTION_TYPE);
7157 if (!function2_template)
7158 function2_template = make_node (FUNCTION_TYPE);
7160 /* Install argument types; normally set by build_function_type. */
7161 TYPE_ARG_TYPES (function1_template) = get_arg_type_list (proto0, METHOD_REF, 0);
7162 TYPE_ARG_TYPES (function2_template) = get_arg_type_list (proto1, METHOD_REF, 0);
7164 /* Install return type. */
7165 TREE_TYPE (function1_template) = groktypename (TREE_TYPE (proto0));
7166 TREE_TYPE (function2_template) = groktypename (TREE_TYPE (proto1));
7168 return comptypes (function1_template, function2_template);
7171 /* - Generate an identifier for the function. the format is "_n_cls",
7172 where 1 <= n <= nMethods, and cls is the name the implementation we
7174 - Install the return type from the method declaration.
7175 - If we have a prototype, check for type consistency. */
7178 really_start_method (method, parmlist)
7179 tree method, parmlist;
7181 tree sc_spec, ret_spec, ret_decl, decl_specs;
7182 tree method_decl, method_id;
7183 const char *sel_name, *class_name, *cat_name;
7186 /* Synth the storage class & assemble the return type. */
7187 sc_spec = tree_cons (NULL_TREE, ridpointers[(int) RID_STATIC], NULL_TREE);
7188 ret_spec = TREE_PURPOSE (TREE_TYPE (method));
7189 decl_specs = chainon (sc_spec, ret_spec);
7191 sel_name = IDENTIFIER_POINTER (METHOD_SEL_NAME (method));
7192 class_name = IDENTIFIER_POINTER (CLASS_NAME (objc_implementation_context));
7193 cat_name = ((TREE_CODE (objc_implementation_context)
7194 == CLASS_IMPLEMENTATION_TYPE)
7196 : IDENTIFIER_POINTER (CLASS_SUPER_NAME (objc_implementation_context)));
7199 /* Make sure this is big enough for any plausible method label. */
7200 buf = (char *) alloca (50 + strlen (sel_name) + strlen (class_name)
7201 + (cat_name ? strlen (cat_name) : 0));
7203 OBJC_GEN_METHOD_LABEL (buf, TREE_CODE (method) == INSTANCE_METHOD_DECL,
7204 class_name, cat_name, sel_name, method_slot);
7206 method_id = get_identifier (buf);
7208 method_decl = build_nt (CALL_EXPR, method_id, parmlist, NULL_TREE);
7210 /* Check the declarator portion of the return type for the method. */
7211 if ((ret_decl = TREE_VALUE (TREE_TYPE (method))))
7213 /* Unite the complex decl (specified in the abstract decl) with the
7214 function decl just synthesized..(int *), (int (*)()), (int (*)[]). */
7215 tree save_expr = expr_last (ret_decl);
7217 TREE_OPERAND (save_expr, 0) = method_decl;
7218 method_decl = ret_decl;
7220 /* Fool the parser into thinking it is starting a function. */
7221 start_function (decl_specs, method_decl, NULL_TREE);
7223 /* Unhook: this has the effect of restoring the abstract declarator. */
7224 TREE_OPERAND (save_expr, 0) = NULL_TREE;
7229 TREE_VALUE (TREE_TYPE (method)) = method_decl;
7231 /* Fool the parser into thinking it is starting a function. */
7232 start_function (decl_specs, method_decl, NULL_TREE);
7234 /* Unhook: this has the effect of restoring the abstract declarator. */
7235 TREE_VALUE (TREE_TYPE (method)) = NULL_TREE;
7238 METHOD_DEFINITION (method) = current_function_decl;
7240 /* Check consistency...start_function, pushdecl, duplicate_decls. */
7242 if (implementation_template != objc_implementation_context)
7246 if (TREE_CODE (method) == INSTANCE_METHOD_DECL)
7247 proto = lookup_instance_method_static (implementation_template,
7248 METHOD_SEL_NAME (method));
7250 proto = lookup_class_method_static (implementation_template,
7251 METHOD_SEL_NAME (method));
7253 if (proto && ! comp_method_with_proto (method, proto))
7255 char type = (TREE_CODE (method) == INSTANCE_METHOD_DECL ? '-' : '+');
7257 warn_with_method ("conflicting types for", type, method);
7258 warn_with_method ("previous declaration of", type, proto);
7263 /* The following routine is always called...this "architecture" is to
7264 accommodate "old-style" variable length selectors.
7266 - a:a b:b // prototype ; id c; id d; // old-style. */
7269 continue_method_def ()
7273 if (METHOD_ADD_ARGS (objc_method_context) == objc_ellipsis_node)
7274 /* We have a `, ...' immediately following the selector. */
7275 parmlist = get_parm_info (0);
7277 parmlist = get_parm_info (1); /* place a `void_at_end' */
7279 /* Set self_decl from the first argument...this global is used by
7280 build_ivar_reference calling build_indirect_ref. */
7281 self_decl = TREE_PURPOSE (parmlist);
7284 really_start_method (objc_method_context, parmlist);
7285 store_parm_decls ();
7288 /* Called by the parser, from the `pushlevel' production. */
7293 if (!UOBJC_SUPER_decl)
7295 UOBJC_SUPER_decl = start_decl (get_identifier (UTAG_SUPER),
7296 build_tree_list (NULL_TREE,
7297 objc_super_template),
7300 finish_decl (UOBJC_SUPER_decl, NULL_TREE, NULL_TREE);
7302 /* This prevents `unused variable' warnings when compiling with -Wall. */
7303 TREE_USED (UOBJC_SUPER_decl) = 1;
7304 DECL_ARTIFICIAL (UOBJC_SUPER_decl) = 1;
7308 /* _n_Method (id self, SEL sel, ...)
7310 struct objc_super _S;
7311 _msgSuper ((_S.self = self, _S.class = _cls, &_S), ...);
7315 get_super_receiver ()
7317 if (objc_method_context)
7319 tree super_expr, super_expr_list;
7321 /* Set receiver to self. */
7322 super_expr = build_component_ref (UOBJC_SUPER_decl, self_id);
7323 super_expr = build_modify_expr (super_expr, NOP_EXPR, self_decl);
7324 super_expr_list = build_tree_list (NULL_TREE, super_expr);
7326 /* Set class to begin searching. */
7327 super_expr = build_component_ref (UOBJC_SUPER_decl,
7328 get_identifier ("class"));
7330 if (TREE_CODE (objc_implementation_context) == CLASS_IMPLEMENTATION_TYPE)
7332 /* [_cls, __cls]Super are "pre-built" in
7333 synth_forward_declarations. */
7335 super_expr = build_modify_expr (super_expr, NOP_EXPR,
7336 ((TREE_CODE (objc_method_context)
7337 == INSTANCE_METHOD_DECL)
7339 : uucls_super_ref));
7343 /* We have a category. */
7345 tree super_name = CLASS_SUPER_NAME (implementation_template);
7348 /* Barf if super used in a category of Object. */
7351 error ("no super class declared in interface for `%s'",
7352 IDENTIFIER_POINTER (CLASS_NAME (implementation_template)));
7353 return error_mark_node;
7356 if (flag_next_runtime)
7358 super_class = get_class_reference (super_name);
7359 if (TREE_CODE (objc_method_context) == CLASS_METHOD_DECL)
7360 /* Cast the super class to 'id', since the user may not have
7361 included <objc/objc-class.h>, leaving 'struct objc_class'
7362 an incomplete type. */
7364 = build_component_ref (build_indirect_ref
7365 (build_c_cast (id_type, super_class), "->"),
7366 get_identifier ("isa"));
7370 add_class_reference (super_name);
7371 super_class = (TREE_CODE (objc_method_context) == INSTANCE_METHOD_DECL
7372 ? objc_get_class_decl : objc_get_meta_class_decl);
7373 assemble_external (super_class);
7375 = build_function_call
7379 my_build_string (IDENTIFIER_LENGTH (super_name) + 1,
7380 IDENTIFIER_POINTER (super_name))));
7383 TREE_TYPE (super_class) = TREE_TYPE (ucls_super_ref);
7384 super_expr = build_modify_expr (super_expr, NOP_EXPR, super_class);
7387 chainon (super_expr_list, build_tree_list (NULL_TREE, super_expr));
7389 super_expr = build_unary_op (ADDR_EXPR, UOBJC_SUPER_decl, 0);
7390 chainon (super_expr_list, build_tree_list (NULL_TREE, super_expr));
7392 return build_compound_expr (super_expr_list);
7396 error ("[super ...] must appear in a method context");
7397 return error_mark_node;
7402 encode_method_def (func_decl)
7407 HOST_WIDE_INT max_parm_end = 0;
7412 encode_type (TREE_TYPE (TREE_TYPE (func_decl)),
7413 obstack_object_size (&util_obstack),
7414 OBJC_ENCODE_INLINE_DEFS);
7417 for (parms = DECL_ARGUMENTS (func_decl); parms;
7418 parms = TREE_CHAIN (parms))
7420 HOST_WIDE_INT parm_end = (forwarding_offset (parms)
7421 + int_size_in_bytes (TREE_TYPE (parms)));
7423 if (! offset_is_register && parm_end > max_parm_end)
7424 max_parm_end = parm_end;
7427 stack_size = max_parm_end - OBJC_FORWARDING_MIN_OFFSET;
7429 sprintf (buffer, "%d", stack_size);
7430 obstack_grow (&util_obstack, buffer, strlen (buffer));
7432 /* Argument types. */
7433 for (parms = DECL_ARGUMENTS (func_decl); parms;
7434 parms = TREE_CHAIN (parms))
7437 encode_type (TREE_TYPE (parms),
7438 obstack_object_size (&util_obstack),
7439 OBJC_ENCODE_INLINE_DEFS);
7441 /* Compute offset. */
7442 sprintf (buffer, "%d", forwarding_offset (parms));
7444 /* Indicate register. */
7445 if (offset_is_register)
7446 obstack_1grow (&util_obstack, '+');
7448 obstack_grow (&util_obstack, buffer, strlen (buffer));
7451 /* Null terminate string. */
7452 obstack_1grow (&util_obstack, 0);
7453 result = get_identifier (obstack_finish (&util_obstack));
7454 obstack_free (&util_obstack, util_firstobj);
7459 objc_expand_function_end ()
7461 METHOD_ENCODING (objc_method_context) = encode_method_def (current_function_decl);
7465 finish_method_def ()
7467 lang_expand_function_end = objc_expand_function_end;
7468 finish_function (0, 1);
7469 lang_expand_function_end = NULL;
7471 /* Required to implement _msgSuper. This must be done AFTER finish_function,
7472 since the optimizer may find "may be used before set" errors. */
7473 objc_method_context = NULL_TREE;
7478 lang_report_error_function (decl)
7481 if (objc_method_context)
7483 fprintf (stderr, "In method `%s'\n",
7484 IDENTIFIER_POINTER (METHOD_SEL_NAME (objc_method_context)));
7494 is_complex_decl (type)
7497 return (TREE_CODE (type) == ARRAY_TYPE
7498 || TREE_CODE (type) == FUNCTION_TYPE
7499 || (TREE_CODE (type) == POINTER_TYPE && ! IS_ID (type)));
7503 /* Code to convert a decl node into text for a declaration in C. */
7505 static char tmpbuf[256];
7508 adorn_decl (decl, str)
7512 enum tree_code code = TREE_CODE (decl);
7514 if (code == ARRAY_REF)
7516 tree an_int_cst = TREE_OPERAND (decl, 1);
7518 if (an_int_cst && TREE_CODE (an_int_cst) == INTEGER_CST)
7519 sprintf (str + strlen (str), "[%ld]",
7520 (long) TREE_INT_CST_LOW (an_int_cst));
7525 else if (code == ARRAY_TYPE)
7527 tree an_int_cst = TYPE_SIZE (decl);
7528 tree array_of = TREE_TYPE (decl);
7530 if (an_int_cst && TREE_CODE (an_int_cst) == INTEGER_TYPE)
7531 sprintf (str + strlen (str), "[%ld]",
7532 (long) (TREE_INT_CST_LOW (an_int_cst)
7533 / TREE_INT_CST_LOW (TYPE_SIZE (array_of))));
7538 else if (code == CALL_EXPR)
7540 tree chain = TREE_PURPOSE (TREE_OPERAND (decl, 1));
7545 gen_declaration_1 (chain, str);
7546 chain = TREE_CHAIN (chain);
7553 else if (code == FUNCTION_TYPE)
7555 tree chain = TYPE_ARG_TYPES (decl);
7558 while (chain && TREE_VALUE (chain) != void_type_node)
7560 gen_declaration_1 (TREE_VALUE (chain), str);
7561 chain = TREE_CHAIN (chain);
7562 if (chain && TREE_VALUE (chain) != void_type_node)
7568 else if (code == INDIRECT_REF)
7570 strcpy (tmpbuf, "*");
7571 if (TREE_TYPE (decl) && TREE_CODE (TREE_TYPE (decl)) == TREE_LIST)
7575 for (chain = nreverse (copy_list (TREE_TYPE (decl)));
7577 chain = TREE_CHAIN (chain))
7579 if (TREE_CODE (TREE_VALUE (chain)) == IDENTIFIER_NODE)
7581 strcat (tmpbuf, " ");
7582 strcat (tmpbuf, IDENTIFIER_POINTER (TREE_VALUE (chain)));
7586 strcat (tmpbuf, " ");
7588 strcat (tmpbuf, str);
7589 strcpy (str, tmpbuf);
7592 else if (code == POINTER_TYPE)
7594 strcpy (tmpbuf, "*");
7595 if (TREE_READONLY (decl) || TYPE_VOLATILE (decl))
7597 if (TREE_READONLY (decl))
7598 strcat (tmpbuf, " const");
7599 if (TYPE_VOLATILE (decl))
7600 strcat (tmpbuf, " volatile");
7602 strcat (tmpbuf, " ");
7604 strcat (tmpbuf, str);
7605 strcpy (str, tmpbuf);
7610 gen_declarator (decl, buf, name)
7617 enum tree_code code = TREE_CODE (decl);
7627 op = TREE_OPERAND (decl, 0);
7629 /* We have a pointer to a function or array...(*)(), (*)[] */
7630 if ((code == ARRAY_REF || code == CALL_EXPR)
7631 && op && TREE_CODE (op) == INDIRECT_REF)
7634 str = gen_declarator (op, buf, name);
7638 strcpy (tmpbuf, "(");
7639 strcat (tmpbuf, str);
7640 strcat (tmpbuf, ")");
7641 strcpy (str, tmpbuf);
7644 adorn_decl (decl, str);
7653 /* This clause is done iteratively rather than recursively. */
7656 op = (is_complex_decl (TREE_TYPE (decl))
7657 ? TREE_TYPE (decl) : NULL_TREE);
7659 adorn_decl (decl, str);
7661 /* We have a pointer to a function or array...(*)(), (*)[] */
7662 if (code == POINTER_TYPE
7663 && op && (TREE_CODE (op) == FUNCTION_TYPE
7664 || TREE_CODE (op) == ARRAY_TYPE))
7666 strcpy (tmpbuf, "(");
7667 strcat (tmpbuf, str);
7668 strcat (tmpbuf, ")");
7669 strcpy (str, tmpbuf);
7672 decl = (is_complex_decl (TREE_TYPE (decl))
7673 ? TREE_TYPE (decl) : NULL_TREE);
7676 while (decl && (code = TREE_CODE (decl)))
7681 case IDENTIFIER_NODE:
7682 /* Will only happen if we are processing a "raw" expr-decl. */
7683 strcpy (buf, IDENTIFIER_POINTER (decl));
7694 /* We have an abstract declarator or a _DECL node. */
7702 gen_declspecs (declspecs, buf, raw)
7711 for (chain = nreverse (copy_list (declspecs));
7712 chain; chain = TREE_CHAIN (chain))
7714 tree aspec = TREE_VALUE (chain);
7716 if (TREE_CODE (aspec) == IDENTIFIER_NODE)
7717 strcat (buf, IDENTIFIER_POINTER (aspec));
7718 else if (TREE_CODE (aspec) == RECORD_TYPE)
7720 if (TYPE_NAME (aspec))
7722 tree protocol_list = TYPE_PROTOCOL_LIST (aspec);
7724 if (! TREE_STATIC_TEMPLATE (aspec))
7725 strcat (buf, "struct ");
7726 strcat (buf, IDENTIFIER_POINTER (TYPE_NAME (aspec)));
7731 tree chain = protocol_list;
7738 (PROTOCOL_NAME (TREE_VALUE (chain))));
7739 chain = TREE_CHAIN (chain);
7748 strcat (buf, "untagged struct");
7751 else if (TREE_CODE (aspec) == UNION_TYPE)
7753 if (TYPE_NAME (aspec))
7755 if (! TREE_STATIC_TEMPLATE (aspec))
7756 strcat (buf, "union ");
7757 strcat (buf, IDENTIFIER_POINTER (TYPE_NAME (aspec)));
7760 strcat (buf, "untagged union");
7763 else if (TREE_CODE (aspec) == ENUMERAL_TYPE)
7765 if (TYPE_NAME (aspec))
7767 if (! TREE_STATIC_TEMPLATE (aspec))
7768 strcat (buf, "enum ");
7769 strcat (buf, IDENTIFIER_POINTER (TYPE_NAME (aspec)));
7772 strcat (buf, "untagged enum");
7775 else if (TREE_CODE (aspec) == TYPE_DECL && DECL_NAME (aspec))
7776 strcat (buf, IDENTIFIER_POINTER (DECL_NAME (aspec)));
7778 else if (IS_ID (aspec))
7780 tree protocol_list = TYPE_PROTOCOL_LIST (aspec);
7785 tree chain = protocol_list;
7792 (PROTOCOL_NAME (TREE_VALUE (chain))));
7793 chain = TREE_CHAIN (chain);
7800 if (TREE_CHAIN (chain))
7806 /* Type qualifiers. */
7807 if (TREE_READONLY (declspecs))
7808 strcat (buf, "const ");
7809 if (TYPE_VOLATILE (declspecs))
7810 strcat (buf, "volatile ");
7812 switch (TREE_CODE (declspecs))
7814 /* Type specifiers. */
7817 declspecs = TYPE_MAIN_VARIANT (declspecs);
7819 /* Signed integer types. */
7821 if (declspecs == short_integer_type_node)
7822 strcat (buf, "short int ");
7823 else if (declspecs == integer_type_node)
7824 strcat (buf, "int ");
7825 else if (declspecs == long_integer_type_node)
7826 strcat (buf, "long int ");
7827 else if (declspecs == long_long_integer_type_node)
7828 strcat (buf, "long long int ");
7829 else if (declspecs == signed_char_type_node
7830 || declspecs == char_type_node)
7831 strcat (buf, "char ");
7833 /* Unsigned integer types. */
7835 else if (declspecs == short_unsigned_type_node)
7836 strcat (buf, "unsigned short ");
7837 else if (declspecs == unsigned_type_node)
7838 strcat (buf, "unsigned int ");
7839 else if (declspecs == long_unsigned_type_node)
7840 strcat (buf, "unsigned long ");
7841 else if (declspecs == long_long_unsigned_type_node)
7842 strcat (buf, "unsigned long long ");
7843 else if (declspecs == unsigned_char_type_node)
7844 strcat (buf, "unsigned char ");
7848 declspecs = TYPE_MAIN_VARIANT (declspecs);
7850 if (declspecs == float_type_node)
7851 strcat (buf, "float ");
7852 else if (declspecs == double_type_node)
7853 strcat (buf, "double ");
7854 else if (declspecs == long_double_type_node)
7855 strcat (buf, "long double ");
7859 if (TYPE_NAME (declspecs)
7860 && TREE_CODE (TYPE_NAME (declspecs)) == IDENTIFIER_NODE)
7862 tree protocol_list = TYPE_PROTOCOL_LIST (declspecs);
7864 if (! TREE_STATIC_TEMPLATE (declspecs))
7865 strcat (buf, "struct ");
7866 strcat (buf, IDENTIFIER_POINTER (TYPE_NAME (declspecs)));
7870 tree chain = protocol_list;
7877 (PROTOCOL_NAME (TREE_VALUE (chain))));
7878 chain = TREE_CHAIN (chain);
7887 strcat (buf, "untagged struct");
7893 if (TYPE_NAME (declspecs)
7894 && TREE_CODE (TYPE_NAME (declspecs)) == IDENTIFIER_NODE)
7896 strcat (buf, "union ");
7897 strcat (buf, IDENTIFIER_POINTER (TYPE_NAME (declspecs)));
7902 strcat (buf, "untagged union ");
7906 if (TYPE_NAME (declspecs)
7907 && TREE_CODE (TYPE_NAME (declspecs)) == IDENTIFIER_NODE)
7909 strcat (buf, "enum ");
7910 strcat (buf, IDENTIFIER_POINTER (TYPE_NAME (declspecs)));
7915 strcat (buf, "untagged enum ");
7919 strcat (buf, "void ");
7924 tree protocol_list = TYPE_PROTOCOL_LIST (declspecs);
7929 tree chain = protocol_list;
7936 (PROTOCOL_NAME (TREE_VALUE (chain))));
7937 chain = TREE_CHAIN (chain);
7953 /* Given a tree node, produce a printable description of it in the given
7954 buffer, overwriting the buffer. */
7957 gen_declaration (atype_or_adecl, buf)
7958 tree atype_or_adecl;
7962 gen_declaration_1 (atype_or_adecl, buf);
7966 /* Given a tree node, append a printable description to the end of the
7970 gen_declaration_1 (atype_or_adecl, buf)
7971 tree atype_or_adecl;
7976 if (TREE_CODE (atype_or_adecl) == TREE_LIST)
7978 tree declspecs; /* "identifier_node", "record_type" */
7979 tree declarator; /* "array_ref", "indirect_ref", "call_expr"... */
7981 /* We have a "raw", abstract declarator (typename). */
7982 declarator = TREE_VALUE (atype_or_adecl);
7983 declspecs = TREE_PURPOSE (atype_or_adecl);
7985 gen_declspecs (declspecs, buf, 1);
7989 strcat (buf, gen_declarator (declarator, declbuf, ""));
7996 tree declspecs; /* "integer_type", "real_type", "record_type"... */
7997 tree declarator; /* "array_type", "function_type", "pointer_type". */
7999 if (TREE_CODE (atype_or_adecl) == FIELD_DECL
8000 || TREE_CODE (atype_or_adecl) == PARM_DECL
8001 || TREE_CODE (atype_or_adecl) == FUNCTION_DECL)
8002 atype = TREE_TYPE (atype_or_adecl);
8004 /* Assume we have a *_type node. */
8005 atype = atype_or_adecl;
8007 if (is_complex_decl (atype))
8011 /* Get the declaration specifier; it is at the end of the list. */
8012 declarator = chain = atype;
8014 chain = TREE_TYPE (chain); /* not TREE_CHAIN (chain); */
8015 while (is_complex_decl (chain));
8022 declarator = NULL_TREE;
8025 gen_declspecs (declspecs, buf, 0);
8027 if (TREE_CODE (atype_or_adecl) == FIELD_DECL
8028 || TREE_CODE (atype_or_adecl) == PARM_DECL
8029 || TREE_CODE (atype_or_adecl) == FUNCTION_DECL)
8031 const char *const decl_name =
8032 (DECL_NAME (atype_or_adecl)
8033 ? IDENTIFIER_POINTER (DECL_NAME (atype_or_adecl)) : "");
8038 strcat (buf, gen_declarator (declarator, declbuf, decl_name));
8041 else if (decl_name[0])
8044 strcat (buf, decl_name);
8047 else if (declarator)
8050 strcat (buf, gen_declarator (declarator, declbuf, ""));
8055 #define RAW_TYPESPEC(meth) (TREE_VALUE (TREE_PURPOSE (TREE_TYPE (meth))))
8057 /* Given a method tree, put a printable description into the given
8058 buffer (overwriting) and return a pointer to the buffer. */
8061 gen_method_decl (method, buf)
8068 if (RAW_TYPESPEC (method) != objc_object_reference)
8071 gen_declaration_1 (TREE_TYPE (method), buf);
8075 chain = METHOD_SEL_ARGS (method);
8078 /* We have a chain of keyword_decls. */
8081 if (KEYWORD_KEY_NAME (chain))
8082 strcat (buf, IDENTIFIER_POINTER (KEYWORD_KEY_NAME (chain)));
8085 if (RAW_TYPESPEC (chain) != objc_object_reference)
8088 gen_declaration_1 (TREE_TYPE (chain), buf);
8092 strcat (buf, IDENTIFIER_POINTER (KEYWORD_ARG_NAME (chain)));
8093 if ((chain = TREE_CHAIN (chain)))
8098 if (METHOD_ADD_ARGS (method) == objc_ellipsis_node)
8099 strcat (buf, ", ...");
8100 else if (METHOD_ADD_ARGS (method))
8102 /* We have a tree list node as generate by get_parm_info. */
8103 chain = TREE_PURPOSE (METHOD_ADD_ARGS (method));
8105 /* Know we have a chain of parm_decls. */
8109 gen_declaration_1 (chain, buf);
8110 chain = TREE_CHAIN (chain);
8116 /* We have a unary selector. */
8117 strcat (buf, IDENTIFIER_POINTER (METHOD_SEL_NAME (method)));
8125 /* Dump an @interface declaration of the supplied class CHAIN to the
8126 supplied file FP. Used to implement the -gen-decls option (which
8127 prints out an @interface declaration of all classes compiled in
8128 this run); potentially useful for debugging the compiler too. */
8130 dump_interface (fp, chain)
8134 /* FIXME: A heap overflow here whenever a method (or ivar)
8135 declaration is so long that it doesn't fit in the buffer. The
8136 code and all the related functions should be rewritten to avoid
8137 using fixed size buffers. */
8138 char *buf = (char *) xmalloc (1024 * 10);
8139 const char *my_name = IDENTIFIER_POINTER (CLASS_NAME (chain));
8140 tree ivar_decls = CLASS_RAW_IVARS (chain);
8141 tree nst_methods = CLASS_NST_METHODS (chain);
8142 tree cls_methods = CLASS_CLS_METHODS (chain);
8144 fprintf (fp, "\n@interface %s", my_name);
8146 /* CLASS_SUPER_NAME is used to store the superclass name for
8147 classes, and the category name for categories. */
8148 if (CLASS_SUPER_NAME (chain))
8150 const char *name = IDENTIFIER_POINTER (CLASS_SUPER_NAME (chain));
8152 if (TREE_CODE (chain) == CATEGORY_IMPLEMENTATION_TYPE
8153 || TREE_CODE (chain) == CATEGORY_INTERFACE_TYPE)
8155 fprintf (fp, " (%s)\n", name);
8159 fprintf (fp, " : %s\n", name);
8165 /* FIXME - the following doesn't seem to work at the moment. */
8168 fprintf (fp, "{\n");
8171 fprintf (fp, "\t%s;\n", gen_declaration (ivar_decls, buf));
8172 ivar_decls = TREE_CHAIN (ivar_decls);
8175 fprintf (fp, "}\n");
8180 fprintf (fp, "- %s;\n", gen_method_decl (nst_methods, buf));
8181 nst_methods = TREE_CHAIN (nst_methods);
8186 fprintf (fp, "+ %s;\n", gen_method_decl (cls_methods, buf));
8187 cls_methods = TREE_CHAIN (cls_methods);
8190 fprintf (fp, "@end\n");
8193 /* Demangle function for Objective-C */
8195 objc_demangle (mangled)
8196 const char *mangled;
8198 char *demangled, *cp;
8200 if (mangled[0] == '_' &&
8201 (mangled[1] == 'i' || mangled[1] == 'c') &&
8204 cp = demangled = xmalloc(strlen(mangled) + 2);
8205 if (mangled[1] == 'i')
8206 *cp++ = '-'; /* for instance method */
8208 *cp++ = '+'; /* for class method */
8209 *cp++ = '['; /* opening left brace */
8210 strcpy(cp, mangled+3); /* tack on the rest of the mangled name */
8211 while (*cp && *cp == '_')
8212 cp++; /* skip any initial underbars in class name */
8213 cp = strchr(cp, '_'); /* find first non-initial underbar */
8216 free(demangled); /* not mangled name */
8219 if (cp[1] == '_') /* easy case: no category name */
8221 *cp++ = ' '; /* replace two '_' with one ' ' */
8222 strcpy(cp, mangled + (cp - demangled) + 2);
8226 *cp++ = '('; /* less easy case: category name */
8227 cp = strchr(cp, '_');
8230 free(demangled); /* not mangled name */
8234 *cp++ = ' '; /* overwriting 1st char of method name... */
8235 strcpy(cp, mangled + (cp - demangled)); /* get it back */
8237 while (*cp && *cp == '_')
8238 cp++; /* skip any initial underbars in method name */
8241 *cp = ':'; /* replace remaining '_' with ':' */
8242 *cp++ = ']'; /* closing right brace */
8243 *cp++ = 0; /* string terminator */
8247 return mangled; /* not an objc mangled name */
8251 objc_printable_name (decl, kind)
8253 int kind ATTRIBUTE_UNUSED;
8255 return objc_demangle (IDENTIFIER_POINTER (DECL_NAME (decl)));
8261 gcc_obstack_init (&util_obstack);
8262 util_firstobj = (char *) obstack_finish (&util_obstack);
8264 errbuf = (char *) xmalloc (BUFSIZE);
8266 synth_module_prologue ();
8272 struct imp_entry *impent;
8274 /* The internally generated initializers appear to have missing braces.
8275 Don't warn about this. */
8276 int save_warn_missing_braces = warn_missing_braces;
8277 warn_missing_braces = 0;
8279 /* A missing @end may not be detected by the parser. */
8280 if (objc_implementation_context)
8282 warning ("`@end' missing in implementation context");
8283 finish_class (objc_implementation_context);
8284 objc_ivar_chain = NULL_TREE;
8285 objc_implementation_context = NULL_TREE;
8288 generate_forward_declaration_to_string_table ();
8290 #ifdef OBJC_PROLOGUE
8294 /* Process the static instances here because initialization of objc_symtab
8296 if (objc_static_instances)
8297 generate_static_references ();
8299 if (imp_list || class_names_chain
8300 || meth_var_names_chain || meth_var_types_chain || sel_ref_chain)
8301 generate_objc_symtab_decl ();
8303 for (impent = imp_list; impent; impent = impent->next)
8305 objc_implementation_context = impent->imp_context;
8306 implementation_template = impent->imp_template;
8308 UOBJC_CLASS_decl = impent->class_decl;
8309 UOBJC_METACLASS_decl = impent->meta_decl;
8311 /* Dump the @interface of each class as we compile it, if the
8312 -gen-decls option is in use. TODO: Dump the classes in the
8313 order they were found, rather than in reverse order as we
8315 if (flag_gen_declaration)
8317 dump_interface (gen_declaration_file, objc_implementation_context);
8320 if (TREE_CODE (objc_implementation_context) == CLASS_IMPLEMENTATION_TYPE)
8322 /* all of the following reference the string pool... */
8323 generate_ivar_lists ();
8324 generate_dispatch_tables ();
8325 generate_shared_structures ();
8329 generate_dispatch_tables ();
8330 generate_category (objc_implementation_context);
8334 /* If we are using an array of selectors, we must always
8335 finish up the array decl even if no selectors were used. */
8336 if (! flag_next_runtime || sel_ref_chain)
8337 build_selector_translation_table ();
8340 generate_protocols ();
8342 if (objc_implementation_context || class_names_chain || objc_static_instances
8343 || meth_var_names_chain || meth_var_types_chain || sel_ref_chain)
8345 /* Arrange for ObjC data structures to be initialized at run time. */
8346 rtx init_sym = build_module_descriptor ();
8347 if (init_sym && targetm.have_ctors_dtors)
8348 (* targetm.asm_out.constructor) (init_sym, DEFAULT_INIT_PRIORITY);
8351 /* Dump the class references. This forces the appropriate classes
8352 to be linked into the executable image, preserving unix archive
8353 semantics. This can be removed when we move to a more dynamically
8354 linked environment. */
8356 for (chain = cls_ref_chain; chain; chain = TREE_CHAIN (chain))
8358 handle_class_ref (chain);
8359 if (TREE_PURPOSE (chain))
8360 generate_classref_translation_entry (chain);
8363 for (impent = imp_list; impent; impent = impent->next)
8364 handle_impent (impent);
8366 /* Dump the string table last. */
8368 generate_strings ();
8375 /* Run through the selector hash tables and print a warning for any
8376 selector which has multiple methods. */
8378 for (slot = 0; slot < SIZEHASHTABLE; slot++)
8379 for (hsh = cls_method_hash_list[slot]; hsh; hsh = hsh->next)
8382 tree meth = hsh->key;
8383 char type = (TREE_CODE (meth) == INSTANCE_METHOD_DECL
8387 warning ("potential selector conflict for method `%s'",
8388 IDENTIFIER_POINTER (METHOD_SEL_NAME (meth)));
8389 warn_with_method ("found", type, meth);
8390 for (loop = hsh->list; loop; loop = loop->next)
8391 warn_with_method ("found", type, loop->value);
8394 for (slot = 0; slot < SIZEHASHTABLE; slot++)
8395 for (hsh = nst_method_hash_list[slot]; hsh; hsh = hsh->next)
8398 tree meth = hsh->key;
8399 char type = (TREE_CODE (meth) == INSTANCE_METHOD_DECL
8403 warning ("potential selector conflict for method `%s'",
8404 IDENTIFIER_POINTER (METHOD_SEL_NAME (meth)));
8405 warn_with_method ("found", type, meth);
8406 for (loop = hsh->list; loop; loop = loop->next)
8407 warn_with_method ("found", type, loop->value);
8411 warn_missing_braces = save_warn_missing_braces;
8414 /* Subroutines of finish_objc. */
8417 generate_classref_translation_entry (chain)
8420 tree expr, name, decl_specs, decl, sc_spec;
8423 type = TREE_TYPE (TREE_PURPOSE (chain));
8425 expr = add_objc_string (TREE_VALUE (chain), class_names);
8426 expr = build_c_cast (type, expr); /* cast! */
8428 name = DECL_NAME (TREE_PURPOSE (chain));
8430 sc_spec = build_tree_list (NULL_TREE, ridpointers[(int) RID_STATIC]);
8432 /* static struct objc_class * _OBJC_CLASS_REFERENCES_n = ...; */
8433 decl_specs = tree_cons (NULL_TREE, type, sc_spec);
8435 /* The decl that is returned from start_decl is the one that we
8436 forward declared in build_class_reference. */
8437 decl = start_decl (name, decl_specs, 1, NULL_TREE);
8438 DECL_CONTEXT (decl) = NULL_TREE;
8439 finish_decl (decl, expr, NULL_TREE);
8444 handle_class_ref (chain)
8447 const char *name = IDENTIFIER_POINTER (TREE_VALUE (chain));
8448 char *string = (char *) alloca (strlen (name) + 30);
8452 sprintf (string, "%sobjc_class_name_%s",
8453 (flag_next_runtime ? "." : "__"), name);
8455 #ifdef ASM_DECLARE_UNRESOLVED_REFERENCE
8456 if (flag_next_runtime)
8458 ASM_DECLARE_UNRESOLVED_REFERENCE (asm_out_file, string);
8463 /* Make a decl for this name, so we can use its address in a tree. */
8464 decl = build_decl (VAR_DECL, get_identifier (string), char_type_node);
8465 DECL_EXTERNAL (decl) = 1;
8466 TREE_PUBLIC (decl) = 1;
8469 rest_of_decl_compilation (decl, 0, 0, 0);
8471 /* Make a decl for the address. */
8472 sprintf (string, "%sobjc_class_ref_%s",
8473 (flag_next_runtime ? "." : "__"), name);
8474 exp = build1 (ADDR_EXPR, string_type_node, decl);
8475 decl = build_decl (VAR_DECL, get_identifier (string), string_type_node);
8476 DECL_INITIAL (decl) = exp;
8477 TREE_STATIC (decl) = 1;
8478 TREE_USED (decl) = 1;
8481 rest_of_decl_compilation (decl, 0, 0, 0);
8485 handle_impent (impent)
8486 struct imp_entry *impent;
8490 objc_implementation_context = impent->imp_context;
8491 implementation_template = impent->imp_template;
8493 if (TREE_CODE (impent->imp_context) == CLASS_IMPLEMENTATION_TYPE)
8495 const char *const class_name =
8496 IDENTIFIER_POINTER (CLASS_NAME (impent->imp_context));
8498 string = (char *) alloca (strlen (class_name) + 30);
8500 sprintf (string, "%sobjc_class_name_%s",
8501 (flag_next_runtime ? "." : "__"), class_name);
8503 else if (TREE_CODE (impent->imp_context) == CATEGORY_IMPLEMENTATION_TYPE)
8505 const char *const class_name =
8506 IDENTIFIER_POINTER (CLASS_NAME (impent->imp_context));
8507 const char *const class_super_name =
8508 IDENTIFIER_POINTER (CLASS_SUPER_NAME (impent->imp_context));
8510 string = (char *) alloca (strlen (class_name)
8511 + strlen (class_super_name) + 30);
8513 /* Do the same for categories. Even though no references to
8514 these symbols are generated automatically by the compiler, it
8515 gives you a handle to pull them into an archive by hand. */
8516 sprintf (string, "*%sobjc_category_name_%s_%s",
8517 (flag_next_runtime ? "." : "__"), class_name, class_super_name);
8522 #ifdef ASM_DECLARE_CLASS_REFERENCE
8523 if (flag_next_runtime)
8525 ASM_DECLARE_CLASS_REFERENCE (asm_out_file, string);
8533 init = build_int_2 (0, 0);
8534 TREE_TYPE (init) = c_common_type_for_size (BITS_PER_WORD, 1);
8535 decl = build_decl (VAR_DECL, get_identifier (string), TREE_TYPE (init));
8536 TREE_PUBLIC (decl) = 1;
8537 TREE_READONLY (decl) = 1;
8538 TREE_USED (decl) = 1;
8539 TREE_CONSTANT (decl) = 1;
8540 DECL_CONTEXT (decl) = 0;
8541 DECL_ARTIFICIAL (decl) = 1;
8542 DECL_INITIAL (decl) = init;
8543 assemble_variable (decl, 1, 0, 0);
8547 /* Look up ID as an instance variable. */
8549 lookup_objc_ivar (id)
8554 if (objc_method_context && !strcmp (IDENTIFIER_POINTER (id), "super"))
8555 /* We have a message to super. */
8556 return get_super_receiver ();
8557 else if (objc_method_context && (decl = is_ivar (objc_ivar_chain, id)))
8559 if (is_private (decl))
8560 return error_mark_node;
8562 return build_ivar_reference (id);
8568 #include "gt-objc-objc-act.h"
8569 #include "gtype-objc.h"