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");
1700 field_decl = grokfield (input_filename, input_line,
1701 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");
1708 field_decl = grokfield (input_filename, input_line,
1709 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"));
1716 field_decl = grokfield (input_filename, input_line,
1717 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"));
1725 field_decl = grokfield (input_filename, input_line,
1726 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 = input_line;
2053 if (flag_next_runtime && TREE_PURPOSE (chain))
2054 input_line = DECL_SOURCE_LINE (TREE_PURPOSE (chain));
2055 warning ("creating selector for non existant method %s",
2056 IDENTIFIER_POINTER (TREE_VALUE (chain)));
2057 input_line = 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"));
2568 field_decl = grokfield (input_filename, input_line,
2569 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"));
2577 field_decl = grokfield (input_filename, input_line,
2578 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);
2587 field_decl = grokfield (input_filename, input_line,
2588 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"));
2599 field_decl = grokfield (input_filename, input_line,
2600 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"));
2611 field_decl = grokfield (input_filename, input_line,
2612 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");
2675 field_decl = grokfield (input_filename, input_line,
2676 field_decl, decl_specs, NULL_TREE);
2677 field_decl_chain = field_decl;
2679 /* struct objc_method method_list[]; */
2681 decl_specs = build_tree_list (NULL_TREE, list_type);
2682 field_decl = build_nt (ARRAY_REF, get_identifier ("method_list"),
2683 build_int_2 (size, 0));
2684 field_decl = grokfield (input_filename, input_line,
2685 field_decl, decl_specs, NULL_TREE);
2686 chainon (field_decl_chain, field_decl);
2688 finish_struct (objc_ivar_list_record, field_decl_chain, NULL_TREE);
2690 return objc_ivar_list_record;
2694 build_method_prototype_template ()
2697 tree decl_specs, field_decl, field_decl_chain;
2700 = start_struct (RECORD_TYPE, get_identifier (UTAG_METHOD_PROTOTYPE));
2702 /* struct objc_selector *_cmd; */
2703 decl_specs = tree_cons (NULL_TREE, xref_tag (RECORD_TYPE,
2704 get_identifier (TAG_SELECTOR)), NULL_TREE);
2705 field_decl = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("_cmd"));
2706 field_decl = grokfield (input_filename, input_line,
2707 field_decl, decl_specs, NULL_TREE);
2708 field_decl_chain = field_decl;
2710 decl_specs = tree_cons (NULL_TREE, ridpointers[(int) RID_CHAR], NULL_TREE);
2712 = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("method_types"));
2713 field_decl = grokfield (input_filename, input_line,
2714 field_decl, decl_specs, NULL_TREE);
2715 chainon (field_decl_chain, field_decl);
2717 finish_struct (proto_record, field_decl_chain, NULL_TREE);
2719 return proto_record;
2722 /* True if last call to forwarding_offset yielded a register offset. */
2723 static int offset_is_register;
2726 forwarding_offset (parm)
2729 int offset_in_bytes;
2731 if (GET_CODE (DECL_INCOMING_RTL (parm)) == MEM)
2733 rtx addr = XEXP (DECL_INCOMING_RTL (parm), 0);
2735 /* ??? Here we assume that the parm address is indexed
2736 off the frame pointer or arg pointer.
2737 If that is not true, we produce meaningless results,
2738 but do not crash. */
2739 if (GET_CODE (addr) == PLUS
2740 && GET_CODE (XEXP (addr, 1)) == CONST_INT)
2741 offset_in_bytes = INTVAL (XEXP (addr, 1));
2743 offset_in_bytes = 0;
2745 offset_in_bytes += OBJC_FORWARDING_STACK_OFFSET;
2746 offset_is_register = 0;
2748 else if (GET_CODE (DECL_INCOMING_RTL (parm)) == REG)
2750 int regno = REGNO (DECL_INCOMING_RTL (parm));
2751 offset_in_bytes = apply_args_register_offset (regno);
2752 offset_is_register = 1;
2757 /* This is the case where the parm is passed as an int or double
2758 and it is converted to a char, short or float and stored back
2759 in the parmlist. In this case, describe the parm
2760 with the variable's declared type, and adjust the address
2761 if the least significant bytes (which we are using) are not
2763 if (BYTES_BIG_ENDIAN && TREE_TYPE (parm) != DECL_ARG_TYPE (parm))
2764 offset_in_bytes += (GET_MODE_SIZE (TYPE_MODE (DECL_ARG_TYPE (parm)))
2765 - GET_MODE_SIZE (GET_MODE (DECL_RTL (parm))));
2767 return offset_in_bytes;
2771 encode_method_prototype (method_decl, func_decl)
2778 HOST_WIDE_INT max_parm_end = 0;
2782 /* ONEWAY and BYCOPY, for remote object are the only method qualifiers. */
2783 encode_type_qualifiers (TREE_PURPOSE (TREE_TYPE (method_decl)));
2786 encode_type (TREE_TYPE (TREE_TYPE (func_decl)),
2787 obstack_object_size (&util_obstack),
2788 OBJC_ENCODE_INLINE_DEFS);
2791 for (parms = DECL_ARGUMENTS (func_decl); parms;
2792 parms = TREE_CHAIN (parms))
2794 HOST_WIDE_INT parm_end = (forwarding_offset (parms)
2795 + int_size_in_bytes (TREE_TYPE (parms)));
2797 if (!offset_is_register && max_parm_end < parm_end)
2798 max_parm_end = parm_end;
2801 stack_size = max_parm_end - OBJC_FORWARDING_MIN_OFFSET;
2803 sprintf (buf, "%d", stack_size);
2804 obstack_grow (&util_obstack, buf, strlen (buf));
2806 user_args = METHOD_SEL_ARGS (method_decl);
2808 /* Argument types. */
2809 for (parms = DECL_ARGUMENTS (func_decl), i = 0; parms;
2810 parms = TREE_CHAIN (parms), i++)
2812 /* Process argument qualifiers for user supplied arguments. */
2815 encode_type_qualifiers (TREE_PURPOSE (TREE_TYPE (user_args)));
2816 user_args = TREE_CHAIN (user_args);
2820 encode_type (TREE_TYPE (parms),
2821 obstack_object_size (&util_obstack),
2822 OBJC_ENCODE_INLINE_DEFS);
2824 /* Compute offset. */
2825 sprintf (buf, "%d", forwarding_offset (parms));
2827 /* Indicate register. */
2828 if (offset_is_register)
2829 obstack_1grow (&util_obstack, '+');
2831 obstack_grow (&util_obstack, buf, strlen (buf));
2834 obstack_1grow (&util_obstack, '\0');
2835 result = get_identifier (obstack_finish (&util_obstack));
2836 obstack_free (&util_obstack, util_firstobj);
2841 generate_descriptor_table (type, name, size, list, proto)
2848 tree sc_spec, decl_specs, decl, initlist;
2850 sc_spec = tree_cons (NULL_TREE, ridpointers[(int) RID_STATIC], NULL_TREE);
2851 decl_specs = tree_cons (NULL_TREE, type, sc_spec);
2853 decl = start_decl (synth_id_with_class_suffix (name, proto),
2854 decl_specs, 1, NULL_TREE);
2855 DECL_CONTEXT (decl) = NULL_TREE;
2857 initlist = build_tree_list (NULL_TREE, build_int_2 (size, 0));
2858 initlist = tree_cons (NULL_TREE, list, initlist);
2860 finish_decl (decl, objc_build_constructor (type, nreverse (initlist)),
2867 generate_method_descriptors (protocol)
2870 tree initlist, chain, method_list_template;
2871 tree cast, variable_length_type;
2874 if (!objc_method_prototype_template)
2875 objc_method_prototype_template = build_method_prototype_template ();
2877 cast = build_tree_list (build_tree_list (NULL_TREE, xref_tag (RECORD_TYPE,
2878 get_identifier (UTAG_METHOD_PROTOTYPE_LIST))),
2880 variable_length_type = groktypename (cast);
2882 chain = PROTOCOL_CLS_METHODS (protocol);
2885 size = list_length (chain);
2887 method_list_template
2888 = build_method_prototype_list_template (objc_method_prototype_template,
2892 = build_descriptor_table_initializer (objc_method_prototype_template,
2895 UOBJC_CLASS_METHODS_decl
2896 = generate_descriptor_table (method_list_template,
2897 "_OBJC_PROTOCOL_CLASS_METHODS",
2898 size, initlist, protocol);
2899 TREE_TYPE (UOBJC_CLASS_METHODS_decl) = variable_length_type;
2902 UOBJC_CLASS_METHODS_decl = 0;
2904 chain = PROTOCOL_NST_METHODS (protocol);
2907 size = list_length (chain);
2909 method_list_template
2910 = build_method_prototype_list_template (objc_method_prototype_template,
2913 = build_descriptor_table_initializer (objc_method_prototype_template,
2916 UOBJC_INSTANCE_METHODS_decl
2917 = generate_descriptor_table (method_list_template,
2918 "_OBJC_PROTOCOL_INSTANCE_METHODS",
2919 size, initlist, protocol);
2920 TREE_TYPE (UOBJC_INSTANCE_METHODS_decl) = variable_length_type;
2923 UOBJC_INSTANCE_METHODS_decl = 0;
2926 /* Generate a temporary FUNCTION_DECL node to be used in
2927 hack_method_prototype below. */
2929 static GTY(()) int build_tmp_function_decl_xxx;
2931 build_tmp_function_decl ()
2933 tree decl_specs, expr_decl, parms;
2936 /* struct objc_object *objc_xxx (id, SEL, ...); */
2938 decl_specs = build_tree_list (NULL_TREE, objc_object_reference);
2939 push_parm_decl (build_tree_list
2940 (build_tree_list (decl_specs,
2941 build1 (INDIRECT_REF, NULL_TREE,
2945 decl_specs = build_tree_list (NULL_TREE, xref_tag (RECORD_TYPE,
2946 get_identifier (TAG_SELECTOR)));
2947 expr_decl = build1 (INDIRECT_REF, NULL_TREE, NULL_TREE);
2949 push_parm_decl (build_tree_list (build_tree_list (decl_specs, expr_decl),
2951 parms = get_parm_info (0);
2954 decl_specs = build_tree_list (NULL_TREE, objc_object_reference);
2955 sprintf (buffer, "__objc_tmp_%x", build_tmp_function_decl_xxx++);
2956 expr_decl = build_nt (CALL_EXPR, get_identifier (buffer), parms, NULL_TREE);
2957 expr_decl = build1 (INDIRECT_REF, NULL_TREE, expr_decl);
2959 return define_decl (expr_decl, decl_specs);
2962 /* Generate the prototypes for protocol methods. This is used to
2963 generate method encodings for these.
2965 NST_METHODS is the method to generate a _DECL node for TMP_DECL is
2966 a decl node to be used. This is also where the return value is
2970 hack_method_prototype (nst_methods, tmp_decl)
2977 /* Hack to avoid problem with static typing of self arg. */
2978 TREE_SET_CODE (nst_methods, CLASS_METHOD_DECL);
2979 start_method_def (nst_methods);
2980 TREE_SET_CODE (nst_methods, INSTANCE_METHOD_DECL);
2982 if (METHOD_ADD_ARGS (nst_methods) == objc_ellipsis_node)
2983 parms = get_parm_info (0); /* we have a `, ...' */
2985 parms = get_parm_info (1); /* place a `void_at_end' */
2987 poplevel (0, 0, 0); /* Must be called BEFORE start_function. */
2989 /* Usually called from store_parm_decls -> init_function_start. */
2991 DECL_ARGUMENTS (tmp_decl) = TREE_PURPOSE (parms);
2993 if (current_function_decl)
2995 current_function_decl = tmp_decl;
2998 /* Code taken from start_function. */
2999 tree restype = TREE_TYPE (TREE_TYPE (tmp_decl));
3000 /* Promote the value to int before returning it. */
3001 if (TREE_CODE (restype) == INTEGER_TYPE
3002 && TYPE_PRECISION (restype) < TYPE_PRECISION (integer_type_node))
3003 restype = integer_type_node;
3004 DECL_RESULT (tmp_decl) = build_decl (RESULT_DECL, 0, restype);
3007 for (parm = DECL_ARGUMENTS (tmp_decl); parm; parm = TREE_CHAIN (parm))
3008 DECL_CONTEXT (parm) = tmp_decl;
3010 init_function_start (tmp_decl, "objc-act", 0);
3012 /* Typically called from expand_function_start for function definitions. */
3013 assign_parms (tmp_decl);
3015 /* install return type */
3016 TREE_TYPE (TREE_TYPE (tmp_decl)) = groktypename (TREE_TYPE (nst_methods));
3018 current_function_decl = NULL;
3022 generate_protocol_references (plist)
3027 /* Forward declare protocols referenced. */
3028 for (lproto = plist; lproto; lproto = TREE_CHAIN (lproto))
3030 tree proto = TREE_VALUE (lproto);
3032 if (TREE_CODE (proto) == PROTOCOL_INTERFACE_TYPE
3033 && PROTOCOL_NAME (proto))
3035 if (! PROTOCOL_FORWARD_DECL (proto))
3036 build_protocol_reference (proto);
3038 if (PROTOCOL_LIST (proto))
3039 generate_protocol_references (PROTOCOL_LIST (proto));
3044 /* For each protocol which was referenced either from a @protocol()
3045 expression, or because a class/category implements it (then a
3046 pointer to the protocol is stored in the struct describing the
3047 class/category), we create a statically allocated instance of the
3048 Protocol class. The code is written in such a way as to generate
3049 as few Protocol objects as possible; we generate a unique Protocol
3050 instance for each protocol, and we don't generate a Protocol
3051 instance if the protocol is never referenced (either from a
3052 @protocol() or from a class/category implementation). These
3053 statically allocated objects can be referred to via the static
3054 (that is, private to this module) symbols _OBJC_PROTOCOL_n.
3056 The statically allocated Protocol objects that we generate here
3057 need to be fixed up at runtime in order to be used: the 'isa'
3058 pointer of the objects need to be set up to point to the 'Protocol'
3059 class, as known at runtime.
3061 The NeXT runtime fixes up all protocols at program startup time,
3062 before main() is entered. It uses a low-level trick to look up all
3063 those symbols, then loops on them and fixes them up.
3065 The GNU runtime as well fixes up all protocols before user code
3066 from the module is executed; it requires pointers to those symbols
3067 to be put in the objc_symtab (which is then passed as argument to
3068 the function __objc_exec_class() which the compiler sets up to be
3069 executed automatically when the module is loaded); setup of those
3070 Protocol objects happen in two ways in the GNU runtime: all
3071 Protocol objects referred to by a class or category implementation
3072 are fixed up when the class/category is loaded; all Protocol
3073 objects referred to by a @protocol() expression are added by the
3074 compiler to the list of statically allocated instances to fixup
3075 (the same list holding the statically allocated constant string
3076 objects). Because, as explained above, the compiler generates as
3077 few Protocol objects as possible, some Protocol object might end up
3078 being referenced multiple times when compiled with the GNU runtime,
3079 and end up being fixed up multiple times at runtime inizialization.
3080 But that doesn't hurt, it's just a little inefficient. */
3082 generate_protocols ()
3084 tree p, tmp_decl, encoding;
3085 tree sc_spec, decl_specs, decl;
3086 tree initlist, protocol_name_expr, refs_decl, refs_expr;
3089 tmp_decl = build_tmp_function_decl ();
3091 if (! objc_protocol_template)
3092 objc_protocol_template = build_protocol_template ();
3094 /* If a protocol was directly referenced, pull in indirect references. */
3095 for (p = protocol_chain; p; p = TREE_CHAIN (p))
3096 if (PROTOCOL_FORWARD_DECL (p) && PROTOCOL_LIST (p))
3097 generate_protocol_references (PROTOCOL_LIST (p));
3099 for (p = protocol_chain; p; p = TREE_CHAIN (p))
3101 tree nst_methods = PROTOCOL_NST_METHODS (p);
3102 tree cls_methods = PROTOCOL_CLS_METHODS (p);
3104 /* If protocol wasn't referenced, don't generate any code. */
3105 if (! PROTOCOL_FORWARD_DECL (p))
3108 /* Make sure we link in the Protocol class. */
3109 add_class_reference (get_identifier (PROTOCOL_OBJECT_CLASS_NAME));
3113 if (! METHOD_ENCODING (nst_methods))
3115 hack_method_prototype (nst_methods, tmp_decl);
3116 encoding = encode_method_prototype (nst_methods, tmp_decl);
3117 METHOD_ENCODING (nst_methods) = encoding;
3119 nst_methods = TREE_CHAIN (nst_methods);
3124 if (! METHOD_ENCODING (cls_methods))
3126 hack_method_prototype (cls_methods, tmp_decl);
3127 encoding = encode_method_prototype (cls_methods, tmp_decl);
3128 METHOD_ENCODING (cls_methods) = encoding;
3131 cls_methods = TREE_CHAIN (cls_methods);
3133 generate_method_descriptors (p);
3135 if (PROTOCOL_LIST (p))
3136 refs_decl = generate_protocol_list (p);
3140 /* static struct objc_protocol _OBJC_PROTOCOL_<mumble>; */
3142 sc_spec = tree_cons (NULL_TREE, ridpointers[(int) RID_STATIC],
3144 decl_specs = tree_cons (NULL_TREE, objc_protocol_template, sc_spec);
3146 decl = start_decl (synth_id_with_class_suffix ("_OBJC_PROTOCOL", p),
3147 decl_specs, 1, NULL_TREE);
3149 DECL_CONTEXT (decl) = NULL_TREE;
3151 protocol_name_expr = add_objc_string (PROTOCOL_NAME (p), class_names);
3157 (build_tree_list (build_tree_list (NULL_TREE,
3158 objc_protocol_template),
3159 build1 (INDIRECT_REF, NULL_TREE,
3160 build1 (INDIRECT_REF, NULL_TREE,
3163 refs_expr = build_unary_op (ADDR_EXPR, refs_decl, 0);
3164 TREE_TYPE (refs_expr) = cast_type2;
3167 refs_expr = build_int_2 (0, 0);
3169 /* UOBJC_INSTANCE_METHODS_decl/UOBJC_CLASS_METHODS_decl are set
3170 by generate_method_descriptors, which is called above. */
3171 initlist = build_protocol_initializer (TREE_TYPE (decl),
3172 protocol_name_expr, refs_expr,
3173 UOBJC_INSTANCE_METHODS_decl,
3174 UOBJC_CLASS_METHODS_decl);
3175 finish_decl (decl, initlist, NULL_TREE);
3177 /* Mark the decl as used to avoid "defined but not used" warning. */
3178 TREE_USED (decl) = 1;
3183 build_protocol_initializer (type, protocol_name, protocol_list,
3184 instance_methods, class_methods)
3188 tree instance_methods;
3191 tree initlist = NULL_TREE, expr;
3194 cast_type = groktypename
3196 (build_tree_list (NULL_TREE,
3197 xref_tag (RECORD_TYPE,
3198 get_identifier (UTAG_CLASS))),
3199 build1 (INDIRECT_REF, NULL_TREE, NULL_TREE)));
3201 /* Filling the "isa" in with one allows the runtime system to
3202 detect that the version change...should remove before final release. */
3204 expr = build_int_2 (PROTOCOL_VERSION, 0);
3205 TREE_TYPE (expr) = cast_type;
3206 initlist = tree_cons (NULL_TREE, expr, initlist);
3207 initlist = tree_cons (NULL_TREE, protocol_name, initlist);
3208 initlist = tree_cons (NULL_TREE, protocol_list, initlist);
3210 if (!instance_methods)
3211 initlist = tree_cons (NULL_TREE, build_int_2 (0, 0), initlist);
3214 expr = build_unary_op (ADDR_EXPR, instance_methods, 0);
3215 initlist = tree_cons (NULL_TREE, expr, initlist);
3219 initlist = tree_cons (NULL_TREE, build_int_2 (0, 0), initlist);
3222 expr = build_unary_op (ADDR_EXPR, class_methods, 0);
3223 initlist = tree_cons (NULL_TREE, expr, initlist);
3226 return objc_build_constructor (type, nreverse (initlist));
3229 /* struct objc_category {
3230 char *category_name;
3232 struct objc_method_list *instance_methods;
3233 struct objc_method_list *class_methods;
3234 struct objc_protocol_list *protocols;
3238 build_category_template ()
3240 tree decl_specs, field_decl, field_decl_chain;
3242 objc_category_template = start_struct (RECORD_TYPE,
3243 get_identifier (UTAG_CATEGORY));
3244 /* char *category_name; */
3246 decl_specs = build_tree_list (NULL_TREE, ridpointers[(int) RID_CHAR]);
3248 = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("category_name"));
3249 field_decl = grokfield (input_filename, input_line,
3250 field_decl, decl_specs, NULL_TREE);
3251 field_decl_chain = field_decl;
3253 /* char *class_name; */
3255 decl_specs = build_tree_list (NULL_TREE, ridpointers[(int) RID_CHAR]);
3256 field_decl = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("class_name"));
3257 field_decl = grokfield (input_filename, input_line,
3258 field_decl, decl_specs, NULL_TREE);
3259 chainon (field_decl_chain, field_decl);
3261 /* struct objc_method_list *instance_methods; */
3263 decl_specs = build_tree_list (NULL_TREE,
3264 xref_tag (RECORD_TYPE,
3265 get_identifier (UTAG_METHOD_LIST)));
3267 = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("instance_methods"));
3268 field_decl = grokfield (input_filename, input_line,
3269 field_decl, decl_specs, NULL_TREE);
3270 chainon (field_decl_chain, field_decl);
3272 /* struct objc_method_list *class_methods; */
3274 decl_specs = build_tree_list (NULL_TREE,
3275 xref_tag (RECORD_TYPE,
3276 get_identifier (UTAG_METHOD_LIST)));
3278 = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("class_methods"));
3279 field_decl = grokfield (input_filename, input_line,
3280 field_decl, decl_specs, NULL_TREE);
3281 chainon (field_decl_chain, field_decl);
3283 /* struct objc_protocol **protocol_list; */
3285 decl_specs = build_tree_list (NULL_TREE,
3286 xref_tag (RECORD_TYPE,
3287 get_identifier (UTAG_PROTOCOL)));
3289 = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("protocol_list"));
3290 field_decl = build1 (INDIRECT_REF, NULL_TREE, field_decl);
3291 field_decl = grokfield (input_filename, input_line,
3292 field_decl, decl_specs, NULL_TREE);
3293 chainon (field_decl_chain, field_decl);
3295 finish_struct (objc_category_template, field_decl_chain, NULL_TREE);
3298 /* struct objc_selector {
3304 build_selector_template ()
3307 tree decl_specs, field_decl, field_decl_chain;
3309 objc_selector_template
3310 = start_struct (RECORD_TYPE, get_identifier (UTAG_SELECTOR));
3314 decl_specs = build_tree_list (NULL_TREE, ridpointers[(int) RID_VOID]);
3315 field_decl = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("sel_id"));
3316 field_decl = grokfield (input_filename, input_line,
3317 field_decl, decl_specs, NULL_TREE);
3318 field_decl_chain = field_decl;
3320 /* char *sel_type; */
3322 decl_specs = build_tree_list (NULL_TREE, ridpointers[(int) RID_CHAR]);
3323 field_decl = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("sel_type"));
3324 field_decl = grokfield (input_filename, input_line,
3325 field_decl, decl_specs, NULL_TREE);
3326 chainon (field_decl_chain, field_decl);
3328 finish_struct (objc_selector_template, field_decl_chain, NULL_TREE);
3331 /* struct objc_class {
3332 struct objc_class *isa;
3333 struct objc_class *super_class;
3338 struct objc_ivar_list *ivars;
3339 struct objc_method_list *methods;
3340 if (flag_next_runtime)
3341 struct objc_cache *cache;
3343 struct sarray *dtable;
3344 struct objc_class *subclass_list;
3345 struct objc_class *sibling_class;
3347 struct objc_protocol_list *protocols;
3348 void *gc_object_type;
3352 build_class_template ()
3354 tree decl_specs, field_decl, field_decl_chain;
3357 = start_struct (RECORD_TYPE, get_identifier (UTAG_CLASS));
3359 /* struct objc_class *isa; */
3361 decl_specs = build_tree_list (NULL_TREE, objc_class_template);
3362 field_decl = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("isa"));
3363 field_decl = grokfield (input_filename, input_line,
3364 field_decl, decl_specs, NULL_TREE);
3365 field_decl_chain = field_decl;
3367 /* struct objc_class *super_class; */
3369 decl_specs = build_tree_list (NULL_TREE, objc_class_template);
3371 = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("super_class"));
3372 field_decl = grokfield (input_filename, input_line,
3373 field_decl, decl_specs, NULL_TREE);
3374 chainon (field_decl_chain, field_decl);
3378 decl_specs = build_tree_list (NULL_TREE, ridpointers[(int) RID_CHAR]);
3379 field_decl = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("name"));
3380 field_decl = grokfield (input_filename, input_line,
3381 field_decl, decl_specs, NULL_TREE);
3382 chainon (field_decl_chain, field_decl);
3386 decl_specs = build_tree_list (NULL_TREE, ridpointers[(int) RID_LONG]);
3387 field_decl = get_identifier ("version");
3388 field_decl = grokfield (input_filename, input_line,
3389 field_decl, decl_specs, NULL_TREE);
3390 chainon (field_decl_chain, field_decl);
3394 decl_specs = build_tree_list (NULL_TREE, ridpointers[(int) RID_LONG]);
3395 field_decl = get_identifier ("info");
3396 field_decl = grokfield (input_filename, input_line,
3397 field_decl, decl_specs, NULL_TREE);
3398 chainon (field_decl_chain, field_decl);
3400 /* long instance_size; */
3402 decl_specs = build_tree_list (NULL_TREE, ridpointers[(int) RID_LONG]);
3403 field_decl = get_identifier ("instance_size");
3404 field_decl = grokfield (input_filename, input_line,
3405 field_decl, decl_specs, NULL_TREE);
3406 chainon (field_decl_chain, field_decl);
3408 /* struct objc_ivar_list *ivars; */
3410 decl_specs = build_tree_list (NULL_TREE,
3411 xref_tag (RECORD_TYPE,
3412 get_identifier (UTAG_IVAR_LIST)));
3413 field_decl = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("ivars"));
3414 field_decl = grokfield (input_filename, input_line,
3415 field_decl, decl_specs, NULL_TREE);
3416 chainon (field_decl_chain, field_decl);
3418 /* struct objc_method_list *methods; */
3420 decl_specs = build_tree_list (NULL_TREE,
3421 xref_tag (RECORD_TYPE,
3422 get_identifier (UTAG_METHOD_LIST)));
3423 field_decl = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("methods"));
3424 field_decl = grokfield (input_filename, input_line,
3425 field_decl, decl_specs, NULL_TREE);
3426 chainon (field_decl_chain, field_decl);
3428 if (flag_next_runtime)
3430 /* struct objc_cache *cache; */
3432 decl_specs = build_tree_list (NULL_TREE,
3433 xref_tag (RECORD_TYPE,
3434 get_identifier ("objc_cache")));
3435 field_decl = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("cache"));
3436 field_decl = grokfield (input_filename, input_line, field_decl,
3437 decl_specs, NULL_TREE);
3438 chainon (field_decl_chain, field_decl);
3442 /* struct sarray *dtable; */
3444 decl_specs = build_tree_list (NULL_TREE,
3445 xref_tag (RECORD_TYPE,
3446 get_identifier ("sarray")));
3447 field_decl = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("dtable"));
3448 field_decl = grokfield (input_filename, input_line, field_decl,
3449 decl_specs, NULL_TREE);
3450 chainon (field_decl_chain, field_decl);
3452 /* struct objc_class *subclass_list; */
3454 decl_specs = build_tree_list (NULL_TREE, objc_class_template);
3456 = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("subclass_list"));
3457 field_decl = grokfield (input_filename, input_line, field_decl,
3458 decl_specs, NULL_TREE);
3459 chainon (field_decl_chain, field_decl);
3461 /* struct objc_class *sibling_class; */
3463 decl_specs = build_tree_list (NULL_TREE, objc_class_template);
3465 = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("sibling_class"));
3466 field_decl = grokfield (input_filename, input_line, field_decl,
3467 decl_specs, NULL_TREE);
3468 chainon (field_decl_chain, field_decl);
3471 /* struct objc_protocol **protocol_list; */
3473 decl_specs = build_tree_list (NULL_TREE,
3474 xref_tag (RECORD_TYPE,
3475 get_identifier (UTAG_PROTOCOL)));
3477 = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("protocol_list"));
3479 = build1 (INDIRECT_REF, NULL_TREE, field_decl);
3480 field_decl = grokfield (input_filename, input_line, field_decl,
3481 decl_specs, NULL_TREE);
3482 chainon (field_decl_chain, field_decl);
3486 decl_specs = build_tree_list (NULL_TREE, ridpointers[(int) RID_VOID]);
3487 field_decl = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("sel_id"));
3488 field_decl = grokfield (input_filename, input_line,
3489 field_decl, decl_specs, NULL_TREE);
3490 chainon (field_decl_chain, field_decl);
3492 /* void *gc_object_type; */
3494 decl_specs = build_tree_list (NULL_TREE, ridpointers[(int) RID_VOID]);
3495 field_decl = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("gc_object_type"));
3496 field_decl = grokfield (input_filename, input_line,
3497 field_decl, decl_specs, NULL_TREE);
3498 chainon (field_decl_chain, field_decl);
3500 finish_struct (objc_class_template, field_decl_chain, NULL_TREE);
3503 /* Generate appropriate forward declarations for an implementation. */
3506 synth_forward_declarations ()
3508 tree sc_spec, decl_specs, an_id;
3510 /* extern struct objc_class _OBJC_CLASS_<my_name>; */
3512 an_id = synth_id_with_class_suffix ("_OBJC_CLASS", objc_implementation_context);
3514 sc_spec = build_tree_list (NULL_TREE, ridpointers[(int) RID_EXTERN]);
3515 decl_specs = tree_cons (NULL_TREE, objc_class_template, sc_spec);
3516 UOBJC_CLASS_decl = define_decl (an_id, decl_specs);
3517 TREE_USED (UOBJC_CLASS_decl) = 1;
3518 DECL_ARTIFICIAL (UOBJC_CLASS_decl) = 1;
3520 /* extern struct objc_class _OBJC_METACLASS_<my_name>; */
3522 an_id = synth_id_with_class_suffix ("_OBJC_METACLASS",
3523 objc_implementation_context);
3525 UOBJC_METACLASS_decl = define_decl (an_id, decl_specs);
3526 TREE_USED (UOBJC_METACLASS_decl) = 1;
3527 DECL_ARTIFICIAL(UOBJC_METACLASS_decl) = 1;
3529 /* Pre-build the following entities - for speed/convenience. */
3531 an_id = get_identifier ("super_class");
3532 ucls_super_ref = build_component_ref (UOBJC_CLASS_decl, an_id);
3533 uucls_super_ref = build_component_ref (UOBJC_METACLASS_decl, an_id);
3537 error_with_ivar (message, decl, rawdecl)
3538 const char *message;
3542 diagnostic_count_diagnostic (global_dc, DK_ERROR);
3544 diagnostic_report_current_function (global_dc);
3546 error ("%H%s `%s'", &DECL_SOURCE_LOCATION (decl),
3547 message, gen_declaration (rawdecl, errbuf));
3552 check_ivars (inter, imp)
3556 tree intdecls = CLASS_IVARS (inter);
3557 tree impdecls = CLASS_IVARS (imp);
3558 tree rawintdecls = CLASS_RAW_IVARS (inter);
3559 tree rawimpdecls = CLASS_RAW_IVARS (imp);
3565 if (intdecls == 0 && impdecls == 0)
3567 if (intdecls == 0 || impdecls == 0)
3569 error ("inconsistent instance variable specification");
3573 t1 = TREE_TYPE (intdecls); t2 = TREE_TYPE (impdecls);
3575 if (!comptypes (t1, t2))
3577 if (DECL_NAME (intdecls) == DECL_NAME (impdecls))
3579 error_with_ivar ("conflicting instance variable type",
3580 impdecls, rawimpdecls);
3581 error_with_ivar ("previous declaration of",
3582 intdecls, rawintdecls);
3584 else /* both the type and the name don't match */
3586 error ("inconsistent instance variable specification");
3591 else if (DECL_NAME (intdecls) != DECL_NAME (impdecls))
3593 error_with_ivar ("conflicting instance variable name",
3594 impdecls, rawimpdecls);
3595 error_with_ivar ("previous declaration of",
3596 intdecls, rawintdecls);
3599 intdecls = TREE_CHAIN (intdecls);
3600 impdecls = TREE_CHAIN (impdecls);
3601 rawintdecls = TREE_CHAIN (rawintdecls);
3602 rawimpdecls = TREE_CHAIN (rawimpdecls);
3606 /* Set super_type to the data type node for struct objc_super *,
3607 first defining struct objc_super itself.
3608 This needs to be done just once per compilation. */
3611 build_super_template ()
3613 tree record, decl_specs, field_decl, field_decl_chain;
3615 record = start_struct (RECORD_TYPE, get_identifier (UTAG_SUPER));
3617 /* struct objc_object *self; */
3619 decl_specs = build_tree_list (NULL_TREE, objc_object_reference);
3620 field_decl = get_identifier ("self");
3621 field_decl = build1 (INDIRECT_REF, NULL_TREE, field_decl);
3622 field_decl = grokfield (input_filename, input_line,
3623 field_decl, decl_specs, NULL_TREE);
3624 field_decl_chain = field_decl;
3626 /* struct objc_class *class; */
3628 decl_specs = get_identifier (UTAG_CLASS);
3629 decl_specs = build_tree_list (NULL_TREE, xref_tag (RECORD_TYPE, decl_specs));
3630 field_decl = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("class"));
3632 field_decl = grokfield (input_filename, input_line,
3633 field_decl, decl_specs, NULL_TREE);
3634 chainon (field_decl_chain, field_decl);
3636 finish_struct (record, field_decl_chain, NULL_TREE);
3638 /* `struct objc_super *' */
3639 super_type = groktypename (build_tree_list (build_tree_list (NULL_TREE,
3641 build1 (INDIRECT_REF,
3642 NULL_TREE, NULL_TREE)));
3646 /* struct objc_ivar {
3653 build_ivar_template ()
3655 tree objc_ivar_id, objc_ivar_record;
3656 tree decl_specs, field_decl, field_decl_chain;
3658 objc_ivar_id = get_identifier (UTAG_IVAR);
3659 objc_ivar_record = start_struct (RECORD_TYPE, objc_ivar_id);
3661 /* char *ivar_name; */
3663 decl_specs = build_tree_list (NULL_TREE, ridpointers[(int) RID_CHAR]);
3664 field_decl = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("ivar_name"));
3666 field_decl = grokfield (input_filename, input_line, field_decl,
3667 decl_specs, NULL_TREE);
3668 field_decl_chain = field_decl;
3670 /* char *ivar_type; */
3672 decl_specs = build_tree_list (NULL_TREE, ridpointers[(int) RID_CHAR]);
3673 field_decl = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("ivar_type"));
3675 field_decl = grokfield (input_filename, input_line, field_decl,
3676 decl_specs, NULL_TREE);
3677 chainon (field_decl_chain, field_decl);
3679 /* int ivar_offset; */
3681 decl_specs = build_tree_list (NULL_TREE, ridpointers[(int) RID_INT]);
3682 field_decl = get_identifier ("ivar_offset");
3684 field_decl = grokfield (input_filename, input_line, field_decl,
3685 decl_specs, NULL_TREE);
3686 chainon (field_decl_chain, field_decl);
3688 finish_struct (objc_ivar_record, field_decl_chain, NULL_TREE);
3690 return objc_ivar_record;
3695 struct objc_ivar ivar_list[ivar_count];
3699 build_ivar_list_template (list_type, size)
3703 tree objc_ivar_list_record;
3704 tree decl_specs, field_decl, field_decl_chain;
3706 objc_ivar_list_record = start_struct (RECORD_TYPE, NULL_TREE);
3708 /* int ivar_count; */
3710 decl_specs = build_tree_list (NULL_TREE, ridpointers[(int) RID_INT]);
3711 field_decl = get_identifier ("ivar_count");
3713 field_decl = grokfield (input_filename, input_line, field_decl,
3714 decl_specs, NULL_TREE);
3715 field_decl_chain = field_decl;
3717 /* struct objc_ivar ivar_list[]; */
3719 decl_specs = build_tree_list (NULL_TREE, list_type);
3720 field_decl = build_nt (ARRAY_REF, get_identifier ("ivar_list"),
3721 build_int_2 (size, 0));
3723 field_decl = grokfield (input_filename, input_line,
3724 field_decl, decl_specs, NULL_TREE);
3725 chainon (field_decl_chain, field_decl);
3727 finish_struct (objc_ivar_list_record, field_decl_chain, NULL_TREE);
3729 return objc_ivar_list_record;
3735 struct objc_method method_list[method_count];
3739 build_method_list_template (list_type, size)
3743 tree objc_ivar_list_record;
3744 tree decl_specs, field_decl, field_decl_chain;
3746 objc_ivar_list_record = start_struct (RECORD_TYPE, NULL_TREE);
3748 /* int method_next; */
3753 xref_tag (RECORD_TYPE,
3754 get_identifier (UTAG_METHOD_PROTOTYPE_LIST)));
3756 = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("method_next"));
3757 field_decl = grokfield (input_filename, input_line, field_decl,
3758 decl_specs, NULL_TREE);
3759 field_decl_chain = field_decl;
3761 /* int method_count; */
3763 decl_specs = build_tree_list (NULL_TREE, ridpointers[(int) RID_INT]);
3764 field_decl = get_identifier ("method_count");
3766 field_decl = grokfield (input_filename, input_line,
3767 field_decl, decl_specs, NULL_TREE);
3768 chainon (field_decl_chain, field_decl);
3770 /* struct objc_method method_list[]; */
3772 decl_specs = build_tree_list (NULL_TREE, list_type);
3773 field_decl = build_nt (ARRAY_REF, get_identifier ("method_list"),
3774 build_int_2 (size, 0));
3776 field_decl = grokfield (input_filename, input_line,
3777 field_decl, decl_specs, NULL_TREE);
3778 chainon (field_decl_chain, field_decl);
3780 finish_struct (objc_ivar_list_record, field_decl_chain, NULL_TREE);
3782 return objc_ivar_list_record;
3786 build_ivar_list_initializer (type, field_decl)
3790 tree initlist = NULL_TREE;
3794 tree ivar = NULL_TREE;
3797 if (DECL_NAME (field_decl))
3798 ivar = tree_cons (NULL_TREE,
3799 add_objc_string (DECL_NAME (field_decl),
3803 /* Unnamed bit-field ivar (yuck). */
3804 ivar = tree_cons (NULL_TREE, build_int_2 (0, 0), ivar);
3807 encode_field_decl (field_decl,
3808 obstack_object_size (&util_obstack),
3809 OBJC_ENCODE_DONT_INLINE_DEFS);
3811 /* Null terminate string. */
3812 obstack_1grow (&util_obstack, 0);
3816 add_objc_string (get_identifier (obstack_finish (&util_obstack)),
3819 obstack_free (&util_obstack, util_firstobj);
3822 ivar = tree_cons (NULL_TREE, byte_position (field_decl), ivar);
3823 initlist = tree_cons (NULL_TREE,
3824 objc_build_constructor (type, nreverse (ivar)),
3827 field_decl = TREE_CHAIN (field_decl);
3831 return objc_build_constructor (build_array_type (type, 0),
3832 nreverse (initlist));
3836 generate_ivars_list (type, name, size, list)
3842 tree sc_spec, decl_specs, decl, initlist;
3844 sc_spec = tree_cons (NULL_TREE, ridpointers[(int) RID_STATIC], NULL_TREE);
3845 decl_specs = tree_cons (NULL_TREE, type, sc_spec);
3847 decl = start_decl (synth_id_with_class_suffix (name, objc_implementation_context),
3848 decl_specs, 1, NULL_TREE);
3850 initlist = build_tree_list (NULL_TREE, build_int_2 (size, 0));
3851 initlist = tree_cons (NULL_TREE, list, initlist);
3854 objc_build_constructor (TREE_TYPE (decl), nreverse (initlist)),
3861 generate_ivar_lists ()
3863 tree initlist, ivar_list_template, chain;
3864 tree cast, variable_length_type;
3867 generating_instance_variables = 1;
3869 if (!objc_ivar_template)
3870 objc_ivar_template = build_ivar_template ();
3874 (build_tree_list (NULL_TREE, xref_tag (RECORD_TYPE,
3875 get_identifier (UTAG_IVAR_LIST))),
3877 variable_length_type = groktypename (cast);
3879 /* Only generate class variables for the root of the inheritance
3880 hierarchy since these will be the same for every class. */
3882 if (CLASS_SUPER_NAME (implementation_template) == NULL_TREE
3883 && (chain = TYPE_FIELDS (objc_class_template)))
3885 size = list_length (chain);
3887 ivar_list_template = build_ivar_list_template (objc_ivar_template, size);
3888 initlist = build_ivar_list_initializer (objc_ivar_template, chain);
3890 UOBJC_CLASS_VARIABLES_decl
3891 = generate_ivars_list (ivar_list_template, "_OBJC_CLASS_VARIABLES",
3893 TREE_TYPE (UOBJC_CLASS_VARIABLES_decl) = variable_length_type;
3896 UOBJC_CLASS_VARIABLES_decl = 0;
3898 chain = CLASS_IVARS (implementation_template);
3901 size = list_length (chain);
3902 ivar_list_template = build_ivar_list_template (objc_ivar_template, size);
3903 initlist = build_ivar_list_initializer (objc_ivar_template, chain);
3905 UOBJC_INSTANCE_VARIABLES_decl
3906 = generate_ivars_list (ivar_list_template, "_OBJC_INSTANCE_VARIABLES",
3908 TREE_TYPE (UOBJC_INSTANCE_VARIABLES_decl) = variable_length_type;
3911 UOBJC_INSTANCE_VARIABLES_decl = 0;
3913 generating_instance_variables = 0;
3917 build_dispatch_table_initializer (type, entries)
3921 tree initlist = NULL_TREE;
3925 tree elemlist = NULL_TREE;
3927 elemlist = tree_cons (NULL_TREE,
3928 build_selector (METHOD_SEL_NAME (entries)),
3931 /* Generate the method encoding if we don't have one already. */
3932 if (! METHOD_ENCODING (entries))
3933 METHOD_ENCODING (entries) =
3934 encode_method_def (METHOD_DEFINITION (entries));
3936 elemlist = tree_cons (NULL_TREE,
3937 add_objc_string (METHOD_ENCODING (entries),
3941 elemlist = tree_cons (NULL_TREE,
3942 build_unary_op (ADDR_EXPR,
3943 METHOD_DEFINITION (entries), 1),
3946 initlist = tree_cons (NULL_TREE,
3947 objc_build_constructor (type, nreverse (elemlist)),
3950 entries = TREE_CHAIN (entries);
3954 return objc_build_constructor (build_array_type (type, 0),
3955 nreverse (initlist));
3958 /* To accomplish method prototyping without generating all kinds of
3959 inane warnings, the definition of the dispatch table entries were
3962 struct objc_method { SEL _cmd; ...; id (*_imp)(); };
3964 struct objc_method { SEL _cmd; ...; void *_imp; }; */
3967 build_method_template ()
3970 tree decl_specs, field_decl, field_decl_chain;
3972 _SLT_record = start_struct (RECORD_TYPE, get_identifier (UTAG_METHOD));
3974 /* struct objc_selector *_cmd; */
3975 decl_specs = tree_cons (NULL_TREE,
3976 xref_tag (RECORD_TYPE,
3977 get_identifier (TAG_SELECTOR)),
3979 field_decl = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("_cmd"));
3981 field_decl = grokfield (input_filename, input_line, field_decl,
3982 decl_specs, NULL_TREE);
3983 field_decl_chain = field_decl;
3985 decl_specs = tree_cons (NULL_TREE, ridpointers[(int) RID_CHAR], NULL_TREE);
3986 field_decl = build1 (INDIRECT_REF, NULL_TREE,
3987 get_identifier ("method_types"));
3988 field_decl = grokfield (input_filename, input_line, field_decl,
3989 decl_specs, NULL_TREE);
3990 chainon (field_decl_chain, field_decl);
3994 decl_specs = tree_cons (NULL_TREE, ridpointers[(int) RID_VOID], NULL_TREE);
3995 field_decl = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("_imp"));
3996 field_decl = grokfield (input_filename, input_line, field_decl,
3997 decl_specs, NULL_TREE);
3998 chainon (field_decl_chain, field_decl);
4000 finish_struct (_SLT_record, field_decl_chain, NULL_TREE);
4007 generate_dispatch_table (type, name, size, list)
4013 tree sc_spec, decl_specs, decl, initlist;
4015 sc_spec = tree_cons (NULL_TREE, ridpointers[(int) RID_STATIC], NULL_TREE);
4016 decl_specs = tree_cons (NULL_TREE, type, sc_spec);
4018 decl = start_decl (synth_id_with_class_suffix (name, objc_implementation_context),
4019 decl_specs, 1, NULL_TREE);
4021 initlist = build_tree_list (NULL_TREE, build_int_2 (0, 0));
4022 initlist = tree_cons (NULL_TREE, build_int_2 (size, 0), initlist);
4023 initlist = tree_cons (NULL_TREE, list, initlist);
4026 objc_build_constructor (TREE_TYPE (decl), nreverse (initlist)),
4033 mark_referenced_methods ()
4035 struct imp_entry *impent;
4038 for (impent = imp_list; impent; impent = impent->next)
4040 chain = CLASS_CLS_METHODS (impent->imp_context);
4043 cgraph_mark_needed_node (cgraph_node (METHOD_DEFINITION (chain)), 1);
4044 chain = TREE_CHAIN (chain);
4046 chain = CLASS_NST_METHODS (impent->imp_context);
4049 cgraph_mark_needed_node (cgraph_node (METHOD_DEFINITION (chain)), 1);
4050 chain = TREE_CHAIN (chain);
4056 generate_dispatch_tables ()
4058 tree initlist, chain, method_list_template;
4059 tree cast, variable_length_type;
4062 if (!objc_method_template)
4063 objc_method_template = build_method_template ();
4067 (build_tree_list (NULL_TREE,
4068 xref_tag (RECORD_TYPE,
4069 get_identifier (UTAG_METHOD_LIST))),
4072 variable_length_type = groktypename (cast);
4074 chain = CLASS_CLS_METHODS (objc_implementation_context);
4077 size = list_length (chain);
4079 method_list_template
4080 = build_method_list_template (objc_method_template, size);
4082 = build_dispatch_table_initializer (objc_method_template, chain);
4084 UOBJC_CLASS_METHODS_decl
4085 = generate_dispatch_table (method_list_template,
4086 ((TREE_CODE (objc_implementation_context)
4087 == CLASS_IMPLEMENTATION_TYPE)
4088 ? "_OBJC_CLASS_METHODS"
4089 : "_OBJC_CATEGORY_CLASS_METHODS"),
4091 TREE_TYPE (UOBJC_CLASS_METHODS_decl) = variable_length_type;
4094 UOBJC_CLASS_METHODS_decl = 0;
4096 chain = CLASS_NST_METHODS (objc_implementation_context);
4099 size = list_length (chain);
4101 method_list_template
4102 = build_method_list_template (objc_method_template, size);
4104 = build_dispatch_table_initializer (objc_method_template, chain);
4106 if (TREE_CODE (objc_implementation_context) == CLASS_IMPLEMENTATION_TYPE)
4107 UOBJC_INSTANCE_METHODS_decl
4108 = generate_dispatch_table (method_list_template,
4109 "_OBJC_INSTANCE_METHODS",
4112 /* We have a category. */
4113 UOBJC_INSTANCE_METHODS_decl
4114 = generate_dispatch_table (method_list_template,
4115 "_OBJC_CATEGORY_INSTANCE_METHODS",
4117 TREE_TYPE (UOBJC_INSTANCE_METHODS_decl) = variable_length_type;
4120 UOBJC_INSTANCE_METHODS_decl = 0;
4124 generate_protocol_list (i_or_p)
4127 tree initlist, decl_specs, sc_spec;
4128 tree refs_decl, expr_decl, lproto, e, plist;
4132 if (TREE_CODE (i_or_p) == CLASS_INTERFACE_TYPE
4133 || TREE_CODE (i_or_p) == CATEGORY_INTERFACE_TYPE)
4134 plist = CLASS_PROTOCOL_LIST (i_or_p);
4135 else if (TREE_CODE (i_or_p) == PROTOCOL_INTERFACE_TYPE)
4136 plist = PROTOCOL_LIST (i_or_p);
4140 cast_type = groktypename
4142 (build_tree_list (NULL_TREE,
4143 xref_tag (RECORD_TYPE,
4144 get_identifier (UTAG_PROTOCOL))),
4145 build1 (INDIRECT_REF, NULL_TREE, NULL_TREE)));
4148 for (lproto = plist; lproto; lproto = TREE_CHAIN (lproto))
4149 if (TREE_CODE (TREE_VALUE (lproto)) == PROTOCOL_INTERFACE_TYPE
4150 && PROTOCOL_FORWARD_DECL (TREE_VALUE (lproto)))
4153 /* Build initializer. */
4154 initlist = tree_cons (NULL_TREE, build_int_2 (0, 0), NULL_TREE);
4156 e = build_int_2 (size, 0);
4157 TREE_TYPE (e) = cast_type;
4158 initlist = tree_cons (NULL_TREE, e, initlist);
4160 for (lproto = plist; lproto; lproto = TREE_CHAIN (lproto))
4162 tree pval = TREE_VALUE (lproto);
4164 if (TREE_CODE (pval) == PROTOCOL_INTERFACE_TYPE
4165 && PROTOCOL_FORWARD_DECL (pval))
4167 e = build_unary_op (ADDR_EXPR, PROTOCOL_FORWARD_DECL (pval), 0);
4168 initlist = tree_cons (NULL_TREE, e, initlist);
4172 /* static struct objc_protocol *refs[n]; */
4174 sc_spec = tree_cons (NULL_TREE, ridpointers[(int) RID_STATIC], NULL_TREE);
4175 decl_specs = tree_cons (NULL_TREE, xref_tag (RECORD_TYPE,
4176 get_identifier (UTAG_PROTOCOL)),
4179 if (TREE_CODE (i_or_p) == PROTOCOL_INTERFACE_TYPE)
4180 expr_decl = build_nt (ARRAY_REF,
4181 synth_id_with_class_suffix ("_OBJC_PROTOCOL_REFS",
4183 build_int_2 (size + 2, 0));
4184 else if (TREE_CODE (i_or_p) == CLASS_INTERFACE_TYPE)
4185 expr_decl = build_nt (ARRAY_REF,
4186 synth_id_with_class_suffix ("_OBJC_CLASS_PROTOCOLS",
4188 build_int_2 (size + 2, 0));
4189 else if (TREE_CODE (i_or_p) == CATEGORY_INTERFACE_TYPE)
4191 = build_nt (ARRAY_REF,
4192 synth_id_with_class_suffix ("_OBJC_CATEGORY_PROTOCOLS",
4194 build_int_2 (size + 2, 0));
4198 expr_decl = build1 (INDIRECT_REF, NULL_TREE, expr_decl);
4200 refs_decl = start_decl (expr_decl, decl_specs, 1, NULL_TREE);
4201 DECL_CONTEXT (refs_decl) = NULL_TREE;
4203 finish_decl (refs_decl, objc_build_constructor (TREE_TYPE (refs_decl),
4204 nreverse (initlist)),
4211 build_category_initializer (type, cat_name, class_name,
4212 instance_methods, class_methods, protocol_list)
4216 tree instance_methods;
4220 tree initlist = NULL_TREE, expr;
4222 initlist = tree_cons (NULL_TREE, cat_name, initlist);
4223 initlist = tree_cons (NULL_TREE, class_name, initlist);
4225 if (!instance_methods)
4226 initlist = tree_cons (NULL_TREE, build_int_2 (0, 0), initlist);
4229 expr = build_unary_op (ADDR_EXPR, instance_methods, 0);
4230 initlist = tree_cons (NULL_TREE, expr, initlist);
4233 initlist = tree_cons (NULL_TREE, build_int_2 (0, 0), initlist);
4236 expr = build_unary_op (ADDR_EXPR, class_methods, 0);
4237 initlist = tree_cons (NULL_TREE, expr, initlist);
4240 /* protocol_list = */
4242 initlist = tree_cons (NULL_TREE, build_int_2 (0, 0), initlist);
4245 tree cast_type2 = groktypename
4247 (build_tree_list (NULL_TREE,
4248 xref_tag (RECORD_TYPE,
4249 get_identifier (UTAG_PROTOCOL))),
4250 build1 (INDIRECT_REF, NULL_TREE,
4251 build1 (INDIRECT_REF, NULL_TREE, NULL_TREE))));
4253 expr = build_unary_op (ADDR_EXPR, protocol_list, 0);
4254 TREE_TYPE (expr) = cast_type2;
4255 initlist = tree_cons (NULL_TREE, expr, initlist);
4258 return objc_build_constructor (type, nreverse (initlist));
4261 /* struct objc_class {
4262 struct objc_class *isa;
4263 struct objc_class *super_class;
4268 struct objc_ivar_list *ivars;
4269 struct objc_method_list *methods;
4270 if (flag_next_runtime)
4271 struct objc_cache *cache;
4273 struct sarray *dtable;
4274 struct objc_class *subclass_list;
4275 struct objc_class *sibling_class;
4277 struct objc_protocol_list *protocols;
4278 void *gc_object_type;
4282 build_shared_structure_initializer (type, isa, super, name, size, status,
4283 dispatch_table, ivar_list, protocol_list)
4290 tree dispatch_table;
4294 tree initlist = NULL_TREE, expr;
4297 initlist = tree_cons (NULL_TREE, isa, initlist);
4300 initlist = tree_cons (NULL_TREE, super, initlist);
4303 initlist = tree_cons (NULL_TREE, default_conversion (name), initlist);
4306 initlist = tree_cons (NULL_TREE, build_int_2 (0, 0), initlist);
4309 initlist = tree_cons (NULL_TREE, build_int_2 (status, 0), initlist);
4311 /* instance_size = */
4312 initlist = tree_cons (NULL_TREE, size, initlist);
4314 /* objc_ivar_list = */
4316 initlist = tree_cons (NULL_TREE, build_int_2 (0, 0), initlist);
4319 expr = build_unary_op (ADDR_EXPR, ivar_list, 0);
4320 initlist = tree_cons (NULL_TREE, expr, initlist);
4323 /* objc_method_list = */
4324 if (!dispatch_table)
4325 initlist = tree_cons (NULL_TREE, build_int_2 (0, 0), initlist);
4328 expr = build_unary_op (ADDR_EXPR, dispatch_table, 0);
4329 initlist = tree_cons (NULL_TREE, expr, initlist);
4332 if (flag_next_runtime)
4333 /* method_cache = */
4334 initlist = tree_cons (NULL_TREE, build_int_2 (0, 0), initlist);
4338 initlist = tree_cons (NULL_TREE, build_int_2 (0, 0), initlist);
4340 /* subclass_list = */
4341 initlist = tree_cons (NULL_TREE, build_int_2 (0, 0), initlist);
4343 /* sibling_class = */
4344 initlist = tree_cons (NULL_TREE, build_int_2 (0, 0), initlist);
4347 /* protocol_list = */
4348 if (! protocol_list)
4349 initlist = tree_cons (NULL_TREE, build_int_2 (0, 0), initlist);
4355 (build_tree_list (NULL_TREE,
4356 xref_tag (RECORD_TYPE,
4357 get_identifier (UTAG_PROTOCOL))),
4358 build1 (INDIRECT_REF, NULL_TREE,
4359 build1 (INDIRECT_REF, NULL_TREE, NULL_TREE))));
4361 expr = build_unary_op (ADDR_EXPR, protocol_list, 0);
4362 TREE_TYPE (expr) = cast_type2;
4363 initlist = tree_cons (NULL_TREE, expr, initlist);
4366 /* gc_object_type = NULL */
4367 initlist = tree_cons (NULL_TREE, build_int_2 (0, 0), initlist);
4369 return objc_build_constructor (type, nreverse (initlist));
4372 /* static struct objc_category _OBJC_CATEGORY_<name> = { ... }; */
4375 generate_category (cat)
4378 tree sc_spec, decl_specs, decl;
4379 tree initlist, cat_name_expr, class_name_expr;
4380 tree protocol_decl, category;
4382 add_class_reference (CLASS_NAME (cat));
4383 cat_name_expr = add_objc_string (CLASS_SUPER_NAME (cat), class_names);
4385 class_name_expr = add_objc_string (CLASS_NAME (cat), class_names);
4387 category = CLASS_CATEGORY_LIST (implementation_template);
4389 /* find the category interface from the class it is associated with */
4392 if (CLASS_SUPER_NAME (cat) == CLASS_SUPER_NAME (category))
4394 category = CLASS_CATEGORY_LIST (category);
4397 if (category && CLASS_PROTOCOL_LIST (category))
4399 generate_protocol_references (CLASS_PROTOCOL_LIST (category));
4400 protocol_decl = generate_protocol_list (category);
4405 sc_spec = tree_cons (NULL_TREE, ridpointers[(int) RID_STATIC], NULL_TREE);
4406 decl_specs = tree_cons (NULL_TREE, objc_category_template, sc_spec);
4408 decl = start_decl (synth_id_with_class_suffix ("_OBJC_CATEGORY",
4409 objc_implementation_context),
4410 decl_specs, 1, NULL_TREE);
4412 initlist = build_category_initializer (TREE_TYPE (decl),
4413 cat_name_expr, class_name_expr,
4414 UOBJC_INSTANCE_METHODS_decl,
4415 UOBJC_CLASS_METHODS_decl,
4418 TREE_USED (decl) = 1;
4419 finish_decl (decl, initlist, NULL_TREE);
4422 /* static struct objc_class _OBJC_METACLASS_Foo={ ... };
4423 static struct objc_class _OBJC_CLASS_Foo={ ... }; */
4426 generate_shared_structures ()
4428 tree sc_spec, decl_specs, decl;
4429 tree name_expr, super_expr, root_expr;
4430 tree my_root_id = NULL_TREE, my_super_id = NULL_TREE;
4431 tree cast_type, initlist, protocol_decl;
4433 my_super_id = CLASS_SUPER_NAME (implementation_template);
4436 add_class_reference (my_super_id);
4438 /* Compute "my_root_id" - this is required for code generation.
4439 the "isa" for all meta class structures points to the root of
4440 the inheritance hierarchy (e.g. "__Object")... */
4441 my_root_id = my_super_id;
4444 tree my_root_int = lookup_interface (my_root_id);
4446 if (my_root_int && CLASS_SUPER_NAME (my_root_int))
4447 my_root_id = CLASS_SUPER_NAME (my_root_int);
4454 /* No super class. */
4455 my_root_id = CLASS_NAME (implementation_template);
4458 = groktypename (build_tree_list (build_tree_list (NULL_TREE,
4459 objc_class_template),
4460 build1 (INDIRECT_REF,
4461 NULL_TREE, NULL_TREE)));
4463 name_expr = add_objc_string (CLASS_NAME (implementation_template),
4466 /* Install class `isa' and `super' pointers at runtime. */
4469 super_expr = add_objc_string (my_super_id, class_names);
4470 super_expr = build_c_cast (cast_type, super_expr); /* cast! */
4473 super_expr = build_int_2 (0, 0);
4475 root_expr = add_objc_string (my_root_id, class_names);
4476 root_expr = build_c_cast (cast_type, root_expr); /* cast! */
4478 if (CLASS_PROTOCOL_LIST (implementation_template))
4480 generate_protocol_references
4481 (CLASS_PROTOCOL_LIST (implementation_template));
4482 protocol_decl = generate_protocol_list (implementation_template);
4487 /* static struct objc_class _OBJC_METACLASS_Foo = { ... }; */
4489 sc_spec = build_tree_list (NULL_TREE, ridpointers[(int) RID_STATIC]);
4490 decl_specs = tree_cons (NULL_TREE, objc_class_template, sc_spec);
4492 decl = start_decl (DECL_NAME (UOBJC_METACLASS_decl), decl_specs, 1,
4496 = build_shared_structure_initializer
4498 root_expr, super_expr, name_expr,
4499 convert (integer_type_node, TYPE_SIZE_UNIT (objc_class_template)),
4501 UOBJC_CLASS_METHODS_decl,
4502 UOBJC_CLASS_VARIABLES_decl,
4505 finish_decl (decl, initlist, NULL_TREE);
4507 /* static struct objc_class _OBJC_CLASS_Foo={ ... }; */
4509 decl = start_decl (DECL_NAME (UOBJC_CLASS_decl), decl_specs, 1,
4513 = build_shared_structure_initializer
4515 build_unary_op (ADDR_EXPR, UOBJC_METACLASS_decl, 0),
4516 super_expr, name_expr,
4517 convert (integer_type_node,
4518 TYPE_SIZE_UNIT (CLASS_STATIC_TEMPLATE
4519 (implementation_template))),
4521 UOBJC_INSTANCE_METHODS_decl,
4522 UOBJC_INSTANCE_VARIABLES_decl,
4525 finish_decl (decl, initlist, NULL_TREE);
4529 synth_id_with_class_suffix (preamble, ctxt)
4530 const char *preamble;
4534 if (TREE_CODE (ctxt) == CLASS_IMPLEMENTATION_TYPE
4535 || TREE_CODE (ctxt) == CLASS_INTERFACE_TYPE)
4537 const char *const class_name
4538 = IDENTIFIER_POINTER (CLASS_NAME (objc_implementation_context));
4539 string = (char *) alloca (strlen (preamble) + strlen (class_name) + 3);
4540 sprintf (string, "%s_%s", preamble,
4541 IDENTIFIER_POINTER (CLASS_NAME (ctxt)));
4543 else if (TREE_CODE (ctxt) == CATEGORY_IMPLEMENTATION_TYPE
4544 || TREE_CODE (ctxt) == CATEGORY_INTERFACE_TYPE)
4546 /* We have a category. */
4547 const char *const class_name
4548 = IDENTIFIER_POINTER (CLASS_NAME (objc_implementation_context));
4549 const char *const class_super_name
4550 = IDENTIFIER_POINTER (CLASS_SUPER_NAME (objc_implementation_context));
4551 string = (char *) alloca (strlen (preamble)
4552 + strlen (class_name)
4553 + strlen (class_super_name)
4555 sprintf (string, "%s_%s_%s", preamble, class_name, class_super_name);
4557 else if (TREE_CODE (ctxt) == PROTOCOL_INTERFACE_TYPE)
4559 const char *protocol_name = IDENTIFIER_POINTER (PROTOCOL_NAME (ctxt));
4561 = (char *) alloca (strlen (preamble) + strlen (protocol_name) + 3);
4562 sprintf (string, "%s_%s", preamble, protocol_name);
4567 return get_identifier (string);
4571 is_objc_type_qualifier (node)
4574 return (TREE_CODE (node) == IDENTIFIER_NODE
4575 && (node == ridpointers [(int) RID_CONST]
4576 || node == ridpointers [(int) RID_VOLATILE]
4577 || node == ridpointers [(int) RID_IN]
4578 || node == ridpointers [(int) RID_OUT]
4579 || node == ridpointers [(int) RID_INOUT]
4580 || node == ridpointers [(int) RID_BYCOPY]
4581 || node == ridpointers [(int) RID_BYREF]
4582 || node == ridpointers [(int) RID_ONEWAY]));
4585 /* If type is empty or only type qualifiers are present, add default
4586 type of id (otherwise grokdeclarator will default to int). */
4589 adjust_type_for_id_default (type)
4592 tree declspecs, chain;
4595 return build_tree_list (build_tree_list (NULL_TREE, objc_object_reference),
4596 build1 (INDIRECT_REF, NULL_TREE, NULL_TREE));
4598 declspecs = TREE_PURPOSE (type);
4600 /* Determine if a typespec is present. */
4601 for (chain = declspecs;
4603 chain = TREE_CHAIN (chain))
4605 if (TYPED_OBJECT (TREE_VALUE (chain))
4606 && !(TREE_VALUE (type)
4607 && TREE_CODE (TREE_VALUE (type)) == INDIRECT_REF))
4608 error ("can not use an object as parameter to a method\n");
4609 if (!is_objc_type_qualifier (TREE_VALUE (chain)))
4613 return build_tree_list (tree_cons (NULL_TREE, objc_object_reference,
4615 build1 (INDIRECT_REF, NULL_TREE, NULL_TREE));
4620 selector ':' '(' typename ')' identifier
4623 Transform an Objective-C keyword argument into
4624 the C equivalent parameter declarator.
4626 In: key_name, an "identifier_node" (optional).
4627 arg_type, a "tree_list" (optional).
4628 arg_name, an "identifier_node".
4630 Note: It would be really nice to strongly type the preceding
4631 arguments in the function prototype; however, then I
4632 could not use the "accessor" macros defined in "tree.h".
4634 Out: an instance of "keyword_decl". */
4637 build_keyword_decl (key_name, arg_type, arg_name)
4644 /* If no type is specified, default to "id". */
4645 arg_type = adjust_type_for_id_default (arg_type);
4647 keyword_decl = make_node (KEYWORD_DECL);
4649 TREE_TYPE (keyword_decl) = arg_type;
4650 KEYWORD_ARG_NAME (keyword_decl) = arg_name;
4651 KEYWORD_KEY_NAME (keyword_decl) = key_name;
4653 return keyword_decl;
4656 /* Given a chain of keyword_decl's, synthesize the full keyword selector. */
4659 build_keyword_selector (selector)
4663 tree key_chain, key_name;
4666 /* Scan the selector to see how much space we'll need. */
4667 for (key_chain = selector; key_chain; key_chain = TREE_CHAIN (key_chain))
4669 if (TREE_CODE (selector) == KEYWORD_DECL)
4670 key_name = KEYWORD_KEY_NAME (key_chain);
4671 else if (TREE_CODE (selector) == TREE_LIST)
4672 key_name = TREE_PURPOSE (key_chain);
4677 len += IDENTIFIER_LENGTH (key_name) + 1;
4679 /* Just a ':' arg. */
4683 buf = (char *) alloca (len + 1);
4684 /* Start the buffer out as an empty string. */
4687 for (key_chain = selector; key_chain; key_chain = TREE_CHAIN (key_chain))
4689 if (TREE_CODE (selector) == KEYWORD_DECL)
4690 key_name = KEYWORD_KEY_NAME (key_chain);
4691 else if (TREE_CODE (selector) == TREE_LIST)
4692 key_name = TREE_PURPOSE (key_chain);
4697 strcat (buf, IDENTIFIER_POINTER (key_name));
4701 return get_identifier (buf);
4704 /* Used for declarations and definitions. */
4707 build_method_decl (code, ret_type, selector, add_args)
4708 enum tree_code code;
4715 /* If no type is specified, default to "id". */
4716 ret_type = adjust_type_for_id_default (ret_type);
4718 method_decl = make_node (code);
4719 TREE_TYPE (method_decl) = ret_type;
4721 /* If we have a keyword selector, create an identifier_node that
4722 represents the full selector name (`:' included)... */
4723 if (TREE_CODE (selector) == KEYWORD_DECL)
4725 METHOD_SEL_NAME (method_decl) = build_keyword_selector (selector);
4726 METHOD_SEL_ARGS (method_decl) = selector;
4727 METHOD_ADD_ARGS (method_decl) = add_args;
4731 METHOD_SEL_NAME (method_decl) = selector;
4732 METHOD_SEL_ARGS (method_decl) = NULL_TREE;
4733 METHOD_ADD_ARGS (method_decl) = NULL_TREE;
4739 #define METHOD_DEF 0
4740 #define METHOD_REF 1
4742 /* Used by `build_objc_method_call' and `comp_method_types'. Return
4743 an argument list for method METH. CONTEXT is either METHOD_DEF or
4744 METHOD_REF, saying whether we are trying to define a method or call
4745 one. SUPERFLAG says this is for a send to super; this makes a
4746 difference for the NeXT calling sequence in which the lookup and
4747 the method call are done together. */
4750 get_arg_type_list (meth, context, superflag)
4757 /* Receiver type. */
4758 if (flag_next_runtime && superflag)
4759 arglist = build_tree_list (NULL_TREE, super_type);
4760 else if (context == METHOD_DEF)
4761 arglist = build_tree_list (NULL_TREE, TREE_TYPE (self_decl));
4763 arglist = build_tree_list (NULL_TREE, id_type);
4765 /* Selector type - will eventually change to `int'. */
4766 chainon (arglist, build_tree_list (NULL_TREE, selector_type));
4768 /* Build a list of argument types. */
4769 for (akey = METHOD_SEL_ARGS (meth); akey; akey = TREE_CHAIN (akey))
4771 tree arg_decl = groktypename_in_parm_context (TREE_TYPE (akey));
4772 chainon (arglist, build_tree_list (NULL_TREE, TREE_TYPE (arg_decl)));
4775 if (METHOD_ADD_ARGS (meth) == objc_ellipsis_node)
4776 /* We have a `, ...' immediately following the selector,
4777 finalize the arglist...simulate get_parm_info (0). */
4779 else if (METHOD_ADD_ARGS (meth))
4781 /* we have a variable length selector */
4782 tree add_arg_list = TREE_CHAIN (METHOD_ADD_ARGS (meth));
4783 chainon (arglist, add_arg_list);
4786 /* finalize the arglist...simulate get_parm_info (1) */
4787 chainon (arglist, build_tree_list (NULL_TREE, void_type_node));
4793 check_duplicates (hsh)
4796 tree meth = NULL_TREE;
4804 /* We have two methods with the same name and different types. */
4806 char type = (TREE_CODE (meth) == INSTANCE_METHOD_DECL) ? '-' : '+';
4808 warning ("multiple declarations for method `%s'",
4809 IDENTIFIER_POINTER (METHOD_SEL_NAME (meth)));
4811 warn_with_method ("using", type, meth);
4812 for (loop = hsh->list; loop; loop = loop->next)
4813 warn_with_method ("also found", type, loop->value);
4819 /* If RECEIVER is a class reference, return the identifier node for
4820 the referenced class. RECEIVER is created by get_class_reference,
4821 so we check the exact form created depending on which runtimes are
4825 receiver_is_class_object (receiver)
4828 tree chain, exp, arg;
4830 /* The receiver is 'self' in the context of a class method. */
4831 if (objc_method_context
4832 && receiver == self_decl
4833 && TREE_CODE (objc_method_context) == CLASS_METHOD_DECL)
4835 return CLASS_NAME (objc_implementation_context);
4838 if (flag_next_runtime)
4840 /* The receiver is a variable created by
4841 build_class_reference_decl. */
4842 if (TREE_CODE (receiver) == VAR_DECL
4843 && TREE_TYPE (receiver) == objc_class_type)
4844 /* Look up the identifier. */
4845 for (chain = cls_ref_chain; chain; chain = TREE_CHAIN (chain))
4846 if (TREE_PURPOSE (chain) == receiver)
4847 return TREE_VALUE (chain);
4851 /* The receiver is a function call that returns an id. Check if
4852 it is a call to objc_getClass, if so, pick up the class name. */
4853 if (TREE_CODE (receiver) == CALL_EXPR
4854 && (exp = TREE_OPERAND (receiver, 0))
4855 && TREE_CODE (exp) == ADDR_EXPR
4856 && (exp = TREE_OPERAND (exp, 0))
4857 && TREE_CODE (exp) == FUNCTION_DECL
4858 && exp == objc_get_class_decl
4859 /* We have a call to objc_getClass! */
4860 && (arg = TREE_OPERAND (receiver, 1))
4861 && TREE_CODE (arg) == TREE_LIST
4862 && (arg = TREE_VALUE (arg)))
4865 if (TREE_CODE (arg) == ADDR_EXPR
4866 && (arg = TREE_OPERAND (arg, 0))
4867 && TREE_CODE (arg) == STRING_CST)
4868 /* Finally, we have the class name. */
4869 return get_identifier (TREE_STRING_POINTER (arg));
4875 /* If we are currently building a message expr, this holds
4876 the identifier of the selector of the message. This is
4877 used when printing warnings about argument mismatches. */
4879 static tree current_objc_message_selector = 0;
4882 objc_message_selector ()
4884 return current_objc_message_selector;
4887 /* Construct an expression for sending a message.
4888 MESS has the object to send to in TREE_PURPOSE
4889 and the argument list (including selector) in TREE_VALUE.
4891 (*(<abstract_decl>(*)())_msg)(receiver, selTransTbl[n], ...);
4892 (*(<abstract_decl>(*)())_msgSuper)(receiver, selTransTbl[n], ...); */
4895 build_message_expr (mess)
4898 tree receiver = TREE_PURPOSE (mess);
4900 tree args = TREE_VALUE (mess);
4901 tree method_params = NULL_TREE;
4903 if (TREE_CODE (receiver) == ERROR_MARK)
4904 return error_mark_node;
4906 /* Obtain the full selector name. */
4907 if (TREE_CODE (args) == IDENTIFIER_NODE)
4908 /* A unary selector. */
4910 else if (TREE_CODE (args) == TREE_LIST)
4911 sel_name = build_keyword_selector (args);
4915 /* Build the parameter list to give to the method. */
4916 if (TREE_CODE (args) == TREE_LIST)
4918 tree chain = args, prev = NULL_TREE;
4920 /* We have a keyword selector--check for comma expressions. */
4923 tree element = TREE_VALUE (chain);
4925 /* We have a comma expression, must collapse... */
4926 if (TREE_CODE (element) == TREE_LIST)
4929 TREE_CHAIN (prev) = element;
4934 chain = TREE_CHAIN (chain);
4936 method_params = args;
4939 return finish_message_expr (receiver, sel_name, method_params);
4942 /* The 'finish_message_expr' routine is called from within
4943 'build_message_expr' for non-template functions. In the case of
4944 C++ template functions, it is called from 'build_expr_from_tree'
4945 (in decl2.c) after RECEIVER and METHOD_PARAMS have been expanded. */
4948 finish_message_expr (receiver, sel_name, method_params)
4949 tree receiver, sel_name, method_params;
4951 tree method_prototype = NULL_TREE, class_ident = NULL_TREE;
4952 tree selector, self_object, retval;
4953 int statically_typed = 0, statically_allocated = 0;
4955 /* Determine receiver type. */
4956 tree rtype = TREE_TYPE (receiver);
4957 int super = IS_SUPER (rtype);
4961 if (TREE_STATIC_TEMPLATE (rtype))
4962 statically_allocated = 1;
4963 else if (TREE_CODE (rtype) == POINTER_TYPE
4964 && TREE_STATIC_TEMPLATE (TREE_TYPE (rtype)))
4965 statically_typed = 1;
4966 else if ((flag_next_runtime
4968 && (class_ident = receiver_is_class_object (receiver)))
4970 else if (! IS_ID (rtype)
4971 /* Allow any type that matches objc_class_type. */
4972 && ! comptypes (rtype, objc_class_type))
4974 warning ("invalid receiver type `%s'",
4975 gen_declaration (rtype, errbuf));
4977 if (statically_allocated)
4978 receiver = build_unary_op (ADDR_EXPR, receiver, 0);
4980 /* Don't evaluate the receiver twice. */
4981 receiver = save_expr (receiver);
4982 self_object = receiver;
4985 /* If sending to `super', use current self as the object. */
4986 self_object = self_decl;
4988 /* Determine operation return type. */
4994 if (CLASS_SUPER_NAME (implementation_template))
4997 = lookup_interface (CLASS_SUPER_NAME (implementation_template));
4999 if (TREE_CODE (objc_method_context) == INSTANCE_METHOD_DECL)
5000 method_prototype = lookup_instance_method_static (iface, sel_name);
5002 method_prototype = lookup_class_method_static (iface, sel_name);
5004 if (iface && !method_prototype)
5005 warning ("`%s' does not respond to `%s'",
5006 IDENTIFIER_POINTER (CLASS_SUPER_NAME (implementation_template)),
5007 IDENTIFIER_POINTER (sel_name));
5011 error ("no super class declared in interface for `%s'",
5012 IDENTIFIER_POINTER (CLASS_NAME (implementation_template)));
5013 return error_mark_node;
5017 else if (statically_allocated)
5019 tree ctype = TREE_TYPE (rtype);
5020 tree iface = lookup_interface (TYPE_NAME (rtype));
5023 method_prototype = lookup_instance_method_static (iface, sel_name);
5025 if (! method_prototype && ctype && TYPE_PROTOCOL_LIST (ctype))
5027 = lookup_method_in_protocol_list (TYPE_PROTOCOL_LIST (ctype),
5030 if (!method_prototype)
5031 warning ("`%s' does not respond to `%s'",
5032 IDENTIFIER_POINTER (TYPE_NAME (rtype)),
5033 IDENTIFIER_POINTER (sel_name));
5035 else if (statically_typed)
5037 tree ctype = TREE_TYPE (rtype);
5039 /* `self' is now statically_typed. All methods should be visible
5040 within the context of the implementation. */
5041 if (objc_implementation_context
5042 && CLASS_NAME (objc_implementation_context) == TYPE_NAME (ctype))
5045 = lookup_instance_method_static (implementation_template,
5048 if (! method_prototype && TYPE_PROTOCOL_LIST (ctype))
5050 = lookup_method_in_protocol_list (TYPE_PROTOCOL_LIST (ctype),
5053 if (! method_prototype
5054 && implementation_template != objc_implementation_context)
5055 /* The method is not published in the interface. Check
5058 = lookup_method (CLASS_NST_METHODS (objc_implementation_context),
5065 if ((iface = lookup_interface (TYPE_NAME (ctype))))
5066 method_prototype = lookup_instance_method_static (iface, sel_name);
5068 if (! method_prototype)
5070 tree protocol_list = TYPE_PROTOCOL_LIST (ctype);
5073 = lookup_method_in_protocol_list (protocol_list,
5078 if (!method_prototype)
5079 warning ("`%s' does not respond to `%s'",
5080 IDENTIFIER_POINTER (TYPE_NAME (ctype)),
5081 IDENTIFIER_POINTER (sel_name));
5083 else if (class_ident)
5085 if (objc_implementation_context
5086 && CLASS_NAME (objc_implementation_context) == class_ident)
5089 = lookup_class_method_static (implementation_template, sel_name);
5091 if (!method_prototype
5092 && implementation_template != objc_implementation_context)
5093 /* The method is not published in the interface. Check
5096 = lookup_method (CLASS_CLS_METHODS (objc_implementation_context),
5103 if ((iface = lookup_interface (class_ident)))
5104 method_prototype = lookup_class_method_static (iface, sel_name);
5107 if (!method_prototype)
5109 warning ("cannot find class (factory) method");
5110 warning ("return type for `%s' defaults to id",
5111 IDENTIFIER_POINTER (sel_name));
5114 else if (IS_PROTOCOL_QUALIFIED_ID (rtype))
5116 /* An anonymous object that has been qualified with a protocol. */
5118 tree protocol_list = TYPE_PROTOCOL_LIST (rtype);
5120 method_prototype = lookup_method_in_protocol_list (protocol_list,
5123 if (!method_prototype)
5127 warning ("method `%s' not implemented by protocol",
5128 IDENTIFIER_POINTER (sel_name));
5130 /* Try and find the method signature in the global pools. */
5132 if (!(hsh = hash_lookup (nst_method_hash_list, sel_name)))
5133 hsh = hash_lookup (cls_method_hash_list, sel_name);
5135 if (!(method_prototype = check_duplicates (hsh)))
5136 warning ("return type defaults to id");
5143 /* We think we have an instance...loophole: extern id Object; */
5144 hsh = hash_lookup (nst_method_hash_list, sel_name);
5147 /* For various loopholes */
5148 hsh = hash_lookup (cls_method_hash_list, sel_name);
5150 method_prototype = check_duplicates (hsh);
5151 if (!method_prototype)
5153 warning ("cannot find method");
5154 warning ("return type for `%s' defaults to id",
5155 IDENTIFIER_POINTER (sel_name));
5159 /* Save the selector name for printing error messages. */
5160 current_objc_message_selector = sel_name;
5162 /* Build the parameters list for looking up the method.
5163 These are the object itself and the selector. */
5165 if (flag_typed_selectors)
5166 selector = build_typed_selector_reference (sel_name, method_prototype);
5168 selector = build_selector_reference (sel_name);
5170 retval = build_objc_method_call (super, method_prototype,
5171 receiver, self_object,
5172 selector, method_params);
5174 current_objc_message_selector = 0;
5179 /* Build a tree expression to send OBJECT the operation SELECTOR,
5180 looking up the method on object LOOKUP_OBJECT (often same as OBJECT),
5181 assuming the method has prototype METHOD_PROTOTYPE.
5182 (That is an INSTANCE_METHOD_DECL or CLASS_METHOD_DECL.)
5183 Use METHOD_PARAMS as list of args to pass to the method.
5184 If SUPER_FLAG is nonzero, we look up the superclass's method. */
5187 build_objc_method_call (super_flag, method_prototype, lookup_object, object,
5188 selector, method_params)
5190 tree method_prototype, lookup_object, object, selector, method_params;
5192 tree sender = (super_flag ? umsg_super_decl : umsg_decl);
5193 tree rcv_p = (super_flag
5194 ? build_pointer_type (xref_tag (RECORD_TYPE,
5195 get_identifier (TAG_SUPER)))
5198 if (flag_next_runtime)
5200 if (! method_prototype)
5202 method_params = tree_cons (NULL_TREE, lookup_object,
5203 tree_cons (NULL_TREE, selector,
5205 assemble_external (sender);
5206 return build_function_call (sender, method_params);
5210 /* This is a real kludge, but it is used only for the Next.
5211 Clobber the data type of SENDER temporarily to accept
5212 all the arguments for this operation, and to return
5213 whatever this operation returns. */
5214 tree arglist = NULL_TREE, retval, savarg, savret;
5215 tree ret_type = groktypename (TREE_TYPE (method_prototype));
5217 /* Save the proper contents of SENDER's data type. */
5218 savarg = TYPE_ARG_TYPES (TREE_TYPE (sender));
5219 savret = TREE_TYPE (TREE_TYPE (sender));
5221 /* Install this method's argument types. */
5222 arglist = get_arg_type_list (method_prototype, METHOD_REF,
5224 TYPE_ARG_TYPES (TREE_TYPE (sender)) = arglist;
5226 /* Install this method's return type. */
5227 TREE_TYPE (TREE_TYPE (sender)) = ret_type;
5229 /* Call SENDER with all the parameters. This will do type
5230 checking using the arg types for this method. */
5231 method_params = tree_cons (NULL_TREE, lookup_object,
5232 tree_cons (NULL_TREE, selector,
5234 assemble_external (sender);
5235 retval = build_function_call (sender, method_params);
5237 /* Restore SENDER's return/argument types. */
5238 TYPE_ARG_TYPES (TREE_TYPE (sender)) = savarg;
5239 TREE_TYPE (TREE_TYPE (sender)) = savret;
5245 /* This is the portable way.
5246 First call the lookup function to get a pointer to the method,
5247 then cast the pointer, then call it with the method arguments. */
5250 /* Avoid trouble since we may evaluate each of these twice. */
5251 object = save_expr (object);
5252 selector = save_expr (selector);
5254 lookup_object = build_c_cast (rcv_p, lookup_object);
5256 assemble_external (sender);
5258 = build_function_call (sender,
5259 tree_cons (NULL_TREE, lookup_object,
5260 tree_cons (NULL_TREE, selector,
5263 /* If we have a method prototype, construct the data type this
5264 method needs, and cast what we got from SENDER into a pointer
5266 if (method_prototype)
5268 tree arglist = get_arg_type_list (method_prototype, METHOD_REF,
5270 tree valtype = groktypename (TREE_TYPE (method_prototype));
5271 tree fake_function_type = build_function_type (valtype, arglist);
5272 TREE_TYPE (method) = build_pointer_type (fake_function_type);
5276 = build_pointer_type (build_function_type (ptr_type_node, NULL_TREE));
5278 /* Pass the object to the method. */
5279 assemble_external (method);
5280 return build_function_call (method,
5281 tree_cons (NULL_TREE, object,
5282 tree_cons (NULL_TREE, selector,
5288 build_protocol_reference (p)
5291 tree decl, ident, ptype;
5293 /* extern struct objc_protocol _OBJC_PROTOCOL_<mumble>; */
5295 ident = synth_id_with_class_suffix ("_OBJC_PROTOCOL", p);
5297 = groktypename (build_tree_list (build_tree_list (NULL_TREE,
5298 objc_protocol_template),
5301 if (identifier_global_value (ident))
5302 decl = identifier_global_value (ident); /* Set by pushdecl. */
5305 decl = build_decl (VAR_DECL, ident, ptype);
5306 DECL_EXTERNAL (decl) = 1;
5307 TREE_PUBLIC (decl) = 1;
5308 TREE_USED (decl) = 1;
5309 DECL_ARTIFICIAL (decl) = 1;
5311 make_decl_rtl (decl, 0);
5312 pushdecl_top_level (decl);
5315 PROTOCOL_FORWARD_DECL (p) = decl;
5318 /* This function is called by the parser when (and only when) a
5319 @protocol() expression is found, in order to compile it. */
5321 build_protocol_expr (protoname)
5325 tree p = lookup_protocol (protoname);
5329 error ("cannot find protocol declaration for `%s'",
5330 IDENTIFIER_POINTER (protoname));
5331 return error_mark_node;
5334 if (!PROTOCOL_FORWARD_DECL (p))
5335 build_protocol_reference (p);
5337 expr = build_unary_op (ADDR_EXPR, PROTOCOL_FORWARD_DECL (p), 0);
5339 TREE_TYPE (expr) = protocol_type;
5341 /* The @protocol() expression is being compiled into a pointer to a
5342 statically allocated instance of the Protocol class. To become
5343 usable at runtime, the 'isa' pointer of the instance need to be
5344 fixed up at runtime by the runtime library, to point to the
5345 actual 'Protocol' class. */
5347 /* For the GNU runtime, put the static Protocol instance in the list
5348 of statically allocated instances, so that we make sure that its
5349 'isa' pointer is fixed up at runtime by the GNU runtime library
5350 to point to the Protocol class (at runtime, when loading the
5351 module, the GNU runtime library loops on the statically allocated
5352 instances (as found in the defs field in objc_symtab) and fixups
5353 all the 'isa' pointers of those objects). */
5354 if (! flag_next_runtime)
5356 /* This type is a struct containing the fields of a Protocol
5357 object. (Cfr. protocol_type instead is the type of a pointer
5358 to such a struct). */
5359 tree protocol_struct_type = xref_tag
5360 (RECORD_TYPE, get_identifier (PROTOCOL_OBJECT_CLASS_NAME));
5363 /* Look for the list of Protocol statically allocated instances
5364 to fixup at runtime. Create a new list to hold Protocol
5365 statically allocated instances, if the list is not found. At
5366 present there is only another list, holding NSConstantString
5367 static instances to be fixed up at runtime. */
5368 for (chain = &objc_static_instances;
5369 *chain && TREE_VALUE (*chain) != protocol_struct_type;
5370 chain = &TREE_CHAIN (*chain));
5373 *chain = tree_cons (NULL_TREE, protocol_struct_type, NULL_TREE);
5374 add_objc_string (TYPE_NAME (protocol_struct_type),
5378 /* Add this statically allocated instance to the Protocol list. */
5379 TREE_PURPOSE (*chain) = tree_cons (NULL_TREE,
5380 PROTOCOL_FORWARD_DECL (p),
5381 TREE_PURPOSE (*chain));
5388 /* This function is called by the parser when a @selector() expression
5389 is found, in order to compile it. It is only called by the parser
5390 and only to compile a @selector(). */
5392 build_selector_expr (selnamelist)
5397 /* Obtain the full selector name. */
5398 if (TREE_CODE (selnamelist) == IDENTIFIER_NODE)
5399 /* A unary selector. */
5400 selname = selnamelist;
5401 else if (TREE_CODE (selnamelist) == TREE_LIST)
5402 selname = build_keyword_selector (selnamelist);
5406 /* If we are required to check @selector() expressions as they
5407 are found, check that the selector has been declared. */
5408 if (warn_undeclared_selector)
5410 /* Look the selector up in the list of all known class and
5411 instance methods (up to this line) to check that the selector
5415 /* First try with instance methods. */
5416 hsh = hash_lookup (nst_method_hash_list, selname);
5418 /* If not found, try with class methods. */
5421 hsh = hash_lookup (cls_method_hash_list, selname);
5424 /* If still not found, print out a warning. */
5427 warning ("undeclared selector `%s'", IDENTIFIER_POINTER (selname));
5432 if (flag_typed_selectors)
5433 return build_typed_selector_reference (selname, 0);
5435 return build_selector_reference (selname);
5439 build_encode_expr (type)
5445 encode_type (type, obstack_object_size (&util_obstack),
5446 OBJC_ENCODE_INLINE_DEFS);
5447 obstack_1grow (&util_obstack, 0); /* null terminate string */
5448 string = obstack_finish (&util_obstack);
5450 /* Synthesize a string that represents the encoded struct/union. */
5451 result = my_build_string (strlen (string) + 1, string);
5452 obstack_free (&util_obstack, util_firstobj);
5457 build_ivar_reference (id)
5460 if (TREE_CODE (objc_method_context) == CLASS_METHOD_DECL)
5462 /* Historically, a class method that produced objects (factory
5463 method) would assign `self' to the instance that it
5464 allocated. This would effectively turn the class method into
5465 an instance method. Following this assignment, the instance
5466 variables could be accessed. That practice, while safe,
5467 violates the simple rule that a class method should not refer
5468 to an instance variable. It's better to catch the cases
5469 where this is done unknowingly than to support the above
5471 warning ("instance variable `%s' accessed in class method",
5472 IDENTIFIER_POINTER (id));
5473 TREE_TYPE (self_decl) = instance_type; /* cast */
5476 return build_component_ref (build_indirect_ref (self_decl, "->"), id);
5479 /* Compute a hash value for a given method SEL_NAME. */
5482 hash_func (sel_name)
5485 const unsigned char *s
5486 = (const unsigned char *)IDENTIFIER_POINTER (sel_name);
5490 h = h * 67 + *s++ - 113;
5497 nst_method_hash_list = (hash *) ggc_calloc (SIZEHASHTABLE, sizeof (hash));
5498 cls_method_hash_list = (hash *) ggc_calloc (SIZEHASHTABLE, sizeof (hash));
5501 /* WARNING!!!! hash_enter is called with a method, and will peek
5502 inside to find its selector! But hash_lookup is given a selector
5503 directly, and looks for the selector that's inside the found
5504 entry's key (method) for comparison. */
5507 hash_enter (hashlist, method)
5512 int slot = hash_func (METHOD_SEL_NAME (method)) % SIZEHASHTABLE;
5514 obj = (hash) ggc_alloc (sizeof (struct hashed_entry));
5516 obj->next = hashlist[slot];
5519 hashlist[slot] = obj; /* append to front */
5523 hash_lookup (hashlist, sel_name)
5529 target = hashlist[hash_func (sel_name) % SIZEHASHTABLE];
5533 if (sel_name == METHOD_SEL_NAME (target->key))
5536 target = target->next;
5542 hash_add_attr (entry, value)
5548 obj = (attr) ggc_alloc (sizeof (struct hashed_attribute));
5549 obj->next = entry->list;
5552 entry->list = obj; /* append to front */
5556 lookup_method (mchain, method)
5562 if (TREE_CODE (method) == IDENTIFIER_NODE)
5565 key = METHOD_SEL_NAME (method);
5569 if (METHOD_SEL_NAME (mchain) == key)
5572 mchain = TREE_CHAIN (mchain);
5578 lookup_instance_method_static (interface, ident)
5582 tree inter = interface;
5583 tree chain = CLASS_NST_METHODS (inter);
5584 tree meth = NULL_TREE;
5588 if ((meth = lookup_method (chain, ident)))
5591 if (CLASS_CATEGORY_LIST (inter))
5593 tree category = CLASS_CATEGORY_LIST (inter);
5594 chain = CLASS_NST_METHODS (category);
5598 if ((meth = lookup_method (chain, ident)))
5601 /* Check for instance methods in protocols in categories. */
5602 if (CLASS_PROTOCOL_LIST (category))
5604 if ((meth = (lookup_method_in_protocol_list
5605 (CLASS_PROTOCOL_LIST (category), ident, 0))))
5609 if ((category = CLASS_CATEGORY_LIST (category)))
5610 chain = CLASS_NST_METHODS (category);
5615 if (CLASS_PROTOCOL_LIST (inter))
5617 if ((meth = (lookup_method_in_protocol_list
5618 (CLASS_PROTOCOL_LIST (inter), ident, 0))))
5622 if ((inter = lookup_interface (CLASS_SUPER_NAME (inter))))
5623 chain = CLASS_NST_METHODS (inter);
5631 lookup_class_method_static (interface, ident)
5635 tree inter = interface;
5636 tree chain = CLASS_CLS_METHODS (inter);
5637 tree meth = NULL_TREE;
5638 tree root_inter = NULL_TREE;
5642 if ((meth = lookup_method (chain, ident)))
5645 if (CLASS_CATEGORY_LIST (inter))
5647 tree category = CLASS_CATEGORY_LIST (inter);
5648 chain = CLASS_CLS_METHODS (category);
5652 if ((meth = lookup_method (chain, ident)))
5655 /* Check for class methods in protocols in categories. */
5656 if (CLASS_PROTOCOL_LIST (category))
5658 if ((meth = (lookup_method_in_protocol_list
5659 (CLASS_PROTOCOL_LIST (category), ident, 1))))
5663 if ((category = CLASS_CATEGORY_LIST (category)))
5664 chain = CLASS_CLS_METHODS (category);
5669 /* Check for class methods in protocols. */
5670 if (CLASS_PROTOCOL_LIST (inter))
5672 if ((meth = (lookup_method_in_protocol_list
5673 (CLASS_PROTOCOL_LIST (inter), ident, 1))))
5678 if ((inter = lookup_interface (CLASS_SUPER_NAME (inter))))
5679 chain = CLASS_CLS_METHODS (inter);
5683 /* If no class (factory) method was found, check if an _instance_
5684 method of the same name exists in the root class. This is what
5685 the Objective-C runtime will do. */
5686 return lookup_instance_method_static (root_inter, ident);
5690 add_class_method (class, method)
5697 if (!(mth = lookup_method (CLASS_CLS_METHODS (class), method)))
5699 /* put method on list in reverse order */
5700 TREE_CHAIN (method) = CLASS_CLS_METHODS (class);
5701 CLASS_CLS_METHODS (class) = method;
5705 if (TREE_CODE (class) == CLASS_IMPLEMENTATION_TYPE)
5706 error ("duplicate definition of class method `%s'",
5707 IDENTIFIER_POINTER (METHOD_SEL_NAME (mth)));
5710 /* Check types; if different, complain. */
5711 if (!comp_proto_with_proto (method, mth))
5712 error ("duplicate declaration of class method `%s'",
5713 IDENTIFIER_POINTER (METHOD_SEL_NAME (mth)));
5717 if (!(hsh = hash_lookup (cls_method_hash_list, METHOD_SEL_NAME (method))))
5719 /* Install on a global chain. */
5720 hash_enter (cls_method_hash_list, method);
5724 /* Check types; if different, add to a list. */
5725 if (!comp_proto_with_proto (method, hsh->key))
5726 hash_add_attr (hsh, method);
5732 add_instance_method (class, method)
5739 if (!(mth = lookup_method (CLASS_NST_METHODS (class), method)))
5741 /* Put method on list in reverse order. */
5742 TREE_CHAIN (method) = CLASS_NST_METHODS (class);
5743 CLASS_NST_METHODS (class) = method;
5747 if (TREE_CODE (class) == CLASS_IMPLEMENTATION_TYPE)
5748 error ("duplicate definition of instance method `%s'",
5749 IDENTIFIER_POINTER (METHOD_SEL_NAME (mth)));
5752 /* Check types; if different, complain. */
5753 if (!comp_proto_with_proto (method, mth))
5754 error ("duplicate declaration of instance method `%s'",
5755 IDENTIFIER_POINTER (METHOD_SEL_NAME (mth)));
5759 if (!(hsh = hash_lookup (nst_method_hash_list, METHOD_SEL_NAME (method))))
5761 /* Install on a global chain. */
5762 hash_enter (nst_method_hash_list, method);
5766 /* Check types; if different, add to a list. */
5767 if (!comp_proto_with_proto (method, hsh->key))
5768 hash_add_attr (hsh, method);
5777 /* Put interfaces on list in reverse order. */
5778 TREE_CHAIN (class) = interface_chain;
5779 interface_chain = class;
5780 return interface_chain;
5784 add_category (class, category)
5788 /* Put categories on list in reverse order. */
5789 tree cat = CLASS_CATEGORY_LIST (class);
5793 if (CLASS_SUPER_NAME (cat) == CLASS_SUPER_NAME (category))
5794 warning ("duplicate interface declaration for category `%s(%s)'",
5795 IDENTIFIER_POINTER (CLASS_NAME (class)),
5796 IDENTIFIER_POINTER (CLASS_SUPER_NAME (category)));
5797 cat = CLASS_CATEGORY_LIST (cat);
5800 CLASS_CATEGORY_LIST (category) = CLASS_CATEGORY_LIST (class);
5801 CLASS_CATEGORY_LIST (class) = category;
5804 /* Called after parsing each instance variable declaration. Necessary to
5805 preserve typedefs and implement public/private...
5807 PUBLIC is 1 for public, 0 for protected, and 2 for private. */
5810 add_instance_variable (class, public, declarator, declspecs, width)
5817 tree field_decl, raw_decl;
5819 raw_decl = build_tree_list (declspecs, declarator);
5821 if (CLASS_RAW_IVARS (class))
5822 chainon (CLASS_RAW_IVARS (class), raw_decl);
5824 CLASS_RAW_IVARS (class) = raw_decl;
5826 field_decl = grokfield (input_filename, input_line,
5827 declarator, declspecs, width);
5829 /* Overload the public attribute, it is not used for FIELD_DECLs. */
5833 TREE_PUBLIC (field_decl) = 0;
5834 TREE_PRIVATE (field_decl) = 0;
5835 TREE_PROTECTED (field_decl) = 1;
5839 TREE_PUBLIC (field_decl) = 1;
5840 TREE_PRIVATE (field_decl) = 0;
5841 TREE_PROTECTED (field_decl) = 0;
5845 TREE_PUBLIC (field_decl) = 0;
5846 TREE_PRIVATE (field_decl) = 1;
5847 TREE_PROTECTED (field_decl) = 0;
5852 if (CLASS_IVARS (class))
5853 chainon (CLASS_IVARS (class), field_decl);
5855 CLASS_IVARS (class) = field_decl;
5861 is_ivar (decl_chain, ident)
5865 for ( ; decl_chain; decl_chain = TREE_CHAIN (decl_chain))
5866 if (DECL_NAME (decl_chain) == ident)
5871 /* True if the ivar is private and we are not in its implementation. */
5877 if (TREE_PRIVATE (decl)
5878 && ! is_ivar (CLASS_IVARS (implementation_template), DECL_NAME (decl)))
5880 error ("instance variable `%s' is declared private",
5881 IDENTIFIER_POINTER (DECL_NAME (decl)));
5888 /* We have an instance variable reference;, check to see if it is public. */
5891 is_public (expr, identifier)
5895 tree basetype = TREE_TYPE (expr);
5896 enum tree_code code = TREE_CODE (basetype);
5899 if (code == RECORD_TYPE)
5901 if (TREE_STATIC_TEMPLATE (basetype))
5903 if (!lookup_interface (TYPE_NAME (basetype)))
5905 error ("cannot find interface declaration for `%s'",
5906 IDENTIFIER_POINTER (TYPE_NAME (basetype)));
5910 if ((decl = is_ivar (TYPE_FIELDS (basetype), identifier)))
5912 if (TREE_PUBLIC (decl))
5915 /* Important difference between the Stepstone translator:
5916 all instance variables should be public within the context
5917 of the implementation. */
5918 if (objc_implementation_context
5919 && (((TREE_CODE (objc_implementation_context)
5920 == CLASS_IMPLEMENTATION_TYPE)
5921 || (TREE_CODE (objc_implementation_context)
5922 == CATEGORY_IMPLEMENTATION_TYPE))
5923 && (CLASS_NAME (objc_implementation_context)
5924 == TYPE_NAME (basetype))))
5925 return ! is_private (decl);
5927 error ("instance variable `%s' is declared %s",
5928 IDENTIFIER_POINTER (identifier),
5929 TREE_PRIVATE (decl) ? "private" : "protected");
5934 else if (objc_implementation_context && (basetype == objc_object_reference))
5936 TREE_TYPE (expr) = uprivate_record;
5937 warning ("static access to object of type `id'");
5944 /* Make sure all entries in CHAIN are also in LIST. */
5947 check_methods (chain, list, mtype)
5956 if (!lookup_method (list, chain))
5960 if (TREE_CODE (objc_implementation_context)
5961 == CLASS_IMPLEMENTATION_TYPE)
5962 warning ("incomplete implementation of class `%s'",
5963 IDENTIFIER_POINTER (CLASS_NAME (objc_implementation_context)));
5964 else if (TREE_CODE (objc_implementation_context)
5965 == CATEGORY_IMPLEMENTATION_TYPE)
5966 warning ("incomplete implementation of category `%s'",
5967 IDENTIFIER_POINTER (CLASS_SUPER_NAME (objc_implementation_context)));
5971 warning ("method definition for `%c%s' not found",
5972 mtype, IDENTIFIER_POINTER (METHOD_SEL_NAME (chain)));
5975 chain = TREE_CHAIN (chain);
5981 /* Check if CLASS, or its superclasses, explicitly conforms to PROTOCOL. */
5984 conforms_to_protocol (class, protocol)
5988 if (TREE_CODE (protocol) == PROTOCOL_INTERFACE_TYPE)
5990 tree p = CLASS_PROTOCOL_LIST (class);
5991 while (p && TREE_VALUE (p) != protocol)
5996 tree super = (CLASS_SUPER_NAME (class)
5997 ? lookup_interface (CLASS_SUPER_NAME (class))
5999 int tmp = super ? conforms_to_protocol (super, protocol) : 0;
6008 /* Make sure all methods in CHAIN are accessible as MTYPE methods in
6009 CONTEXT. This is one of two mechanisms to check protocol integrity. */
6012 check_methods_accessible (chain, context, mtype)
6019 tree base_context = context;
6023 context = base_context;
6027 list = CLASS_CLS_METHODS (context);
6029 list = CLASS_NST_METHODS (context);
6031 if (lookup_method (list, chain))
6034 else if (TREE_CODE (context) == CLASS_IMPLEMENTATION_TYPE
6035 || TREE_CODE (context) == CLASS_INTERFACE_TYPE)
6036 context = (CLASS_SUPER_NAME (context)
6037 ? lookup_interface (CLASS_SUPER_NAME (context))
6040 else if (TREE_CODE (context) == CATEGORY_IMPLEMENTATION_TYPE
6041 || TREE_CODE (context) == CATEGORY_INTERFACE_TYPE)
6042 context = (CLASS_NAME (context)
6043 ? lookup_interface (CLASS_NAME (context))
6049 if (context == NULL_TREE)
6053 if (TREE_CODE (objc_implementation_context)
6054 == CLASS_IMPLEMENTATION_TYPE)
6055 warning ("incomplete implementation of class `%s'",
6057 (CLASS_NAME (objc_implementation_context)));
6058 else if (TREE_CODE (objc_implementation_context)
6059 == CATEGORY_IMPLEMENTATION_TYPE)
6060 warning ("incomplete implementation of category `%s'",
6062 (CLASS_SUPER_NAME (objc_implementation_context)));
6065 warning ("method definition for `%c%s' not found",
6066 mtype, IDENTIFIER_POINTER (METHOD_SEL_NAME (chain)));
6069 chain = TREE_CHAIN (chain); /* next method... */
6074 /* Check whether the current interface (accessible via
6075 'objc_implementation_context') actually implements protocol P, along
6076 with any protocols that P inherits. */
6079 check_protocol (p, type, name)
6084 if (TREE_CODE (p) == PROTOCOL_INTERFACE_TYPE)
6088 /* Ensure that all protocols have bodies! */
6091 f1 = check_methods (PROTOCOL_CLS_METHODS (p),
6092 CLASS_CLS_METHODS (objc_implementation_context),
6094 f2 = check_methods (PROTOCOL_NST_METHODS (p),
6095 CLASS_NST_METHODS (objc_implementation_context),
6100 f1 = check_methods_accessible (PROTOCOL_CLS_METHODS (p),
6101 objc_implementation_context,
6103 f2 = check_methods_accessible (PROTOCOL_NST_METHODS (p),
6104 objc_implementation_context,
6109 warning ("%s `%s' does not fully implement the `%s' protocol",
6110 type, name, IDENTIFIER_POINTER (PROTOCOL_NAME (p)));
6113 /* Check protocols recursively. */
6114 if (PROTOCOL_LIST (p))
6116 tree subs = PROTOCOL_LIST (p);
6118 lookup_interface (CLASS_SUPER_NAME (implementation_template));
6122 tree sub = TREE_VALUE (subs);
6124 /* If the superclass does not conform to the protocols
6125 inherited by P, then we must! */
6126 if (!super_class || !conforms_to_protocol (super_class, sub))
6127 check_protocol (sub, type, name);
6128 subs = TREE_CHAIN (subs);
6133 /* Check whether the current interface (accessible via
6134 'objc_implementation_context') actually implements the protocols listed
6138 check_protocols (proto_list, type, name)
6143 for ( ; proto_list; proto_list = TREE_CHAIN (proto_list))
6145 tree p = TREE_VALUE (proto_list);
6147 check_protocol (p, type, name);
6151 /* Make sure that the class CLASS_NAME is defined
6152 CODE says which kind of thing CLASS_NAME ought to be.
6153 It can be CLASS_INTERFACE_TYPE, CLASS_IMPLEMENTATION_TYPE,
6154 CATEGORY_INTERFACE_TYPE, or CATEGORY_IMPLEMENTATION_TYPE. */
6157 start_class (code, class_name, super_name, protocol_list)
6158 enum tree_code code;
6165 if (objc_implementation_context)
6167 warning ("`@end' missing in implementation context");
6168 finish_class (objc_implementation_context);
6169 objc_ivar_chain = NULL_TREE;
6170 objc_implementation_context = NULL_TREE;
6173 class = make_node (code);
6174 TYPE_BINFO (class) = make_tree_vec (BINFO_ELTS);
6176 CLASS_NAME (class) = class_name;
6177 CLASS_SUPER_NAME (class) = super_name;
6178 CLASS_CLS_METHODS (class) = NULL_TREE;
6180 if (! is_class_name (class_name) && (decl = lookup_name (class_name)))
6182 error ("`%s' redeclared as different kind of symbol",
6183 IDENTIFIER_POINTER (class_name));
6184 error_with_decl (decl, "previous declaration of `%s'");
6187 if (code == CLASS_IMPLEMENTATION_TYPE)
6192 for (chain = implemented_classes; chain; chain = TREE_CHAIN (chain))
6193 if (TREE_VALUE (chain) == class_name)
6195 error ("reimplementation of class `%s'",
6196 IDENTIFIER_POINTER (class_name));
6197 return error_mark_node;
6199 implemented_classes = tree_cons (NULL_TREE, class_name,
6200 implemented_classes);
6203 /* Pre-build the following entities - for speed/convenience. */
6205 self_id = get_identifier ("self");
6207 ucmd_id = get_identifier ("_cmd");
6210 = build_tree_list (get_identifier ("__unused__"), NULL_TREE);
6211 if (!objc_super_template)
6212 objc_super_template = build_super_template ();
6214 /* Reset for multiple classes per file. */
6217 objc_implementation_context = class;
6219 /* Lookup the interface for this implementation. */
6221 if (!(implementation_template = lookup_interface (class_name)))
6223 warning ("cannot find interface declaration for `%s'",
6224 IDENTIFIER_POINTER (class_name));
6225 add_class (implementation_template = objc_implementation_context);
6228 /* If a super class has been specified in the implementation,
6229 insure it conforms to the one specified in the interface. */
6232 && (super_name != CLASS_SUPER_NAME (implementation_template)))
6234 tree previous_name = CLASS_SUPER_NAME (implementation_template);
6235 const char *const name =
6236 previous_name ? IDENTIFIER_POINTER (previous_name) : "";
6237 error ("conflicting super class name `%s'",
6238 IDENTIFIER_POINTER (super_name));
6239 error ("previous declaration of `%s'", name);
6242 else if (! super_name)
6244 CLASS_SUPER_NAME (objc_implementation_context)
6245 = CLASS_SUPER_NAME (implementation_template);
6249 else if (code == CLASS_INTERFACE_TYPE)
6251 if (lookup_interface (class_name))
6252 warning ("duplicate interface declaration for class `%s'",
6253 IDENTIFIER_POINTER (class_name));
6258 CLASS_PROTOCOL_LIST (class)
6259 = lookup_and_install_protocols (protocol_list);
6262 else if (code == CATEGORY_INTERFACE_TYPE)
6264 tree class_category_is_assoc_with;
6266 /* For a category, class_name is really the name of the class that
6267 the following set of methods will be associated with. We must
6268 find the interface so that can derive the objects template. */
6270 if (!(class_category_is_assoc_with = lookup_interface (class_name)))
6272 error ("cannot find interface declaration for `%s'",
6273 IDENTIFIER_POINTER (class_name));
6274 exit (FATAL_EXIT_CODE);
6277 add_category (class_category_is_assoc_with, class);
6280 CLASS_PROTOCOL_LIST (class)
6281 = lookup_and_install_protocols (protocol_list);
6284 else if (code == CATEGORY_IMPLEMENTATION_TYPE)
6286 /* Pre-build the following entities for speed/convenience. */
6288 self_id = get_identifier ("self");
6290 ucmd_id = get_identifier ("_cmd");
6293 = build_tree_list (get_identifier ("__unused__"), NULL_TREE);
6294 if (!objc_super_template)
6295 objc_super_template = build_super_template ();
6297 /* Reset for multiple classes per file. */
6300 objc_implementation_context = class;
6302 /* For a category, class_name is really the name of the class that
6303 the following set of methods will be associated with. We must
6304 find the interface so that can derive the objects template. */
6306 if (!(implementation_template = lookup_interface (class_name)))
6308 error ("cannot find interface declaration for `%s'",
6309 IDENTIFIER_POINTER (class_name));
6310 exit (FATAL_EXIT_CODE);
6317 continue_class (class)
6320 if (TREE_CODE (class) == CLASS_IMPLEMENTATION_TYPE
6321 || TREE_CODE (class) == CATEGORY_IMPLEMENTATION_TYPE)
6323 struct imp_entry *imp_entry;
6326 /* Check consistency of the instance variables. */
6328 if (CLASS_IVARS (class))
6329 check_ivars (implementation_template, class);
6331 /* code generation */
6333 ivar_context = build_private_template (implementation_template);
6335 if (!objc_class_template)
6336 build_class_template ();
6338 imp_entry = (struct imp_entry *) ggc_alloc (sizeof (struct imp_entry));
6340 imp_entry->next = imp_list;
6341 imp_entry->imp_context = class;
6342 imp_entry->imp_template = implementation_template;
6344 synth_forward_declarations ();
6345 imp_entry->class_decl = UOBJC_CLASS_decl;
6346 imp_entry->meta_decl = UOBJC_METACLASS_decl;
6348 /* Append to front and increment count. */
6349 imp_list = imp_entry;
6350 if (TREE_CODE (class) == CLASS_IMPLEMENTATION_TYPE)
6355 return ivar_context;
6358 else if (TREE_CODE (class) == CLASS_INTERFACE_TYPE)
6360 tree record = xref_tag (RECORD_TYPE, CLASS_NAME (class));
6362 if (!TYPE_FIELDS (record))
6364 finish_struct (record, get_class_ivars (class), NULL_TREE);
6365 CLASS_STATIC_TEMPLATE (class) = record;
6367 /* Mark this record as a class template for static typing. */
6368 TREE_STATIC_TEMPLATE (record) = 1;
6375 return error_mark_node;
6378 /* This is called once we see the "@end" in an interface/implementation. */
6381 finish_class (class)
6384 if (TREE_CODE (class) == CLASS_IMPLEMENTATION_TYPE)
6386 /* All code generation is done in finish_objc. */
6388 if (implementation_template != objc_implementation_context)
6390 /* Ensure that all method listed in the interface contain bodies. */
6391 check_methods (CLASS_CLS_METHODS (implementation_template),
6392 CLASS_CLS_METHODS (objc_implementation_context), '+');
6393 check_methods (CLASS_NST_METHODS (implementation_template),
6394 CLASS_NST_METHODS (objc_implementation_context), '-');
6396 if (CLASS_PROTOCOL_LIST (implementation_template))
6397 check_protocols (CLASS_PROTOCOL_LIST (implementation_template),
6399 IDENTIFIER_POINTER (CLASS_NAME (objc_implementation_context)));
6403 else if (TREE_CODE (class) == CATEGORY_IMPLEMENTATION_TYPE)
6405 tree category = CLASS_CATEGORY_LIST (implementation_template);
6407 /* Find the category interface from the class it is associated with. */
6410 if (CLASS_SUPER_NAME (class) == CLASS_SUPER_NAME (category))
6412 category = CLASS_CATEGORY_LIST (category);
6417 /* Ensure all method listed in the interface contain bodies. */
6418 check_methods (CLASS_CLS_METHODS (category),
6419 CLASS_CLS_METHODS (objc_implementation_context), '+');
6420 check_methods (CLASS_NST_METHODS (category),
6421 CLASS_NST_METHODS (objc_implementation_context), '-');
6423 if (CLASS_PROTOCOL_LIST (category))
6424 check_protocols (CLASS_PROTOCOL_LIST (category),
6426 IDENTIFIER_POINTER (CLASS_SUPER_NAME (objc_implementation_context)));
6430 else if (TREE_CODE (class) == CLASS_INTERFACE_TYPE)
6433 const char *class_name = IDENTIFIER_POINTER (CLASS_NAME (class));
6434 char *string = (char *) alloca (strlen (class_name) + 3);
6436 /* extern struct objc_object *_<my_name>; */
6438 sprintf (string, "_%s", class_name);
6440 decl_specs = build_tree_list (NULL_TREE, ridpointers[(int) RID_EXTERN]);
6441 decl_specs = tree_cons (NULL_TREE, objc_object_reference, decl_specs);
6442 define_decl (build1 (INDIRECT_REF, NULL_TREE, get_identifier (string)),
6448 add_protocol (protocol)
6451 /* Put protocol on list in reverse order. */
6452 TREE_CHAIN (protocol) = protocol_chain;
6453 protocol_chain = protocol;
6454 return protocol_chain;
6458 lookup_protocol (ident)
6463 for (chain = protocol_chain; chain; chain = TREE_CHAIN (chain))
6464 if (ident == PROTOCOL_NAME (chain))
6470 /* This function forward declares the protocols named by NAMES. If
6471 they are already declared or defined, the function has no effect. */
6474 objc_declare_protocols (names)
6479 for (list = names; list; list = TREE_CHAIN (list))
6481 tree name = TREE_VALUE (list);
6483 if (lookup_protocol (name) == NULL_TREE)
6485 tree protocol = make_node (PROTOCOL_INTERFACE_TYPE);
6487 TYPE_BINFO (protocol) = make_tree_vec (2);
6488 PROTOCOL_NAME (protocol) = name;
6489 PROTOCOL_LIST (protocol) = NULL_TREE;
6490 add_protocol (protocol);
6491 PROTOCOL_DEFINED (protocol) = 0;
6492 PROTOCOL_FORWARD_DECL (protocol) = NULL_TREE;
6498 start_protocol (code, name, list)
6499 enum tree_code code;
6505 /* This is as good a place as any. Need to invoke
6506 push_tag_toplevel. */
6507 if (!objc_protocol_template)
6508 objc_protocol_template = build_protocol_template ();
6510 protocol = lookup_protocol (name);
6514 protocol = make_node (code);
6515 TYPE_BINFO (protocol) = make_tree_vec (2);
6517 PROTOCOL_NAME (protocol) = name;
6518 PROTOCOL_LIST (protocol) = lookup_and_install_protocols (list);
6519 add_protocol (protocol);
6520 PROTOCOL_DEFINED (protocol) = 1;
6521 PROTOCOL_FORWARD_DECL (protocol) = NULL_TREE;
6523 check_protocol_recursively (protocol, list);
6525 else if (! PROTOCOL_DEFINED (protocol))
6527 PROTOCOL_DEFINED (protocol) = 1;
6528 PROTOCOL_LIST (protocol) = lookup_and_install_protocols (list);
6530 check_protocol_recursively (protocol, list);
6534 warning ("duplicate declaration for protocol `%s'",
6535 IDENTIFIER_POINTER (name));
6541 finish_protocol (protocol)
6542 tree protocol ATTRIBUTE_UNUSED;
6547 /* "Encode" a data type into a string, which grows in util_obstack.
6548 ??? What is the FORMAT? Someone please document this! */
6551 encode_type_qualifiers (declspecs)
6556 for (spec = declspecs; spec; spec = TREE_CHAIN (spec))
6558 if (ridpointers[(int) RID_CONST] == TREE_VALUE (spec))
6559 obstack_1grow (&util_obstack, 'r');
6560 else if (ridpointers[(int) RID_IN] == TREE_VALUE (spec))
6561 obstack_1grow (&util_obstack, 'n');
6562 else if (ridpointers[(int) RID_INOUT] == TREE_VALUE (spec))
6563 obstack_1grow (&util_obstack, 'N');
6564 else if (ridpointers[(int) RID_OUT] == TREE_VALUE (spec))
6565 obstack_1grow (&util_obstack, 'o');
6566 else if (ridpointers[(int) RID_BYCOPY] == TREE_VALUE (spec))
6567 obstack_1grow (&util_obstack, 'O');
6568 else if (ridpointers[(int) RID_BYREF] == TREE_VALUE (spec))
6569 obstack_1grow (&util_obstack, 'R');
6570 else if (ridpointers[(int) RID_ONEWAY] == TREE_VALUE (spec))
6571 obstack_1grow (&util_obstack, 'V');
6575 /* Encode a pointer type. */
6578 encode_pointer (type, curtype, format)
6583 tree pointer_to = TREE_TYPE (type);
6585 if (TREE_CODE (pointer_to) == RECORD_TYPE)
6587 if (TYPE_NAME (pointer_to)
6588 && TREE_CODE (TYPE_NAME (pointer_to)) == IDENTIFIER_NODE)
6590 const char *name = IDENTIFIER_POINTER (TYPE_NAME (pointer_to));
6592 if (strcmp (name, TAG_OBJECT) == 0) /* '@' */
6594 obstack_1grow (&util_obstack, '@');
6597 else if (TREE_STATIC_TEMPLATE (pointer_to))
6599 if (generating_instance_variables)
6601 obstack_1grow (&util_obstack, '@');
6602 obstack_1grow (&util_obstack, '"');
6603 obstack_grow (&util_obstack, name, strlen (name));
6604 obstack_1grow (&util_obstack, '"');
6609 obstack_1grow (&util_obstack, '@');
6613 else if (strcmp (name, TAG_CLASS) == 0) /* '#' */
6615 obstack_1grow (&util_obstack, '#');
6618 else if (strcmp (name, TAG_SELECTOR) == 0) /* ':' */
6620 obstack_1grow (&util_obstack, ':');
6625 else if (TREE_CODE (pointer_to) == INTEGER_TYPE
6626 && TYPE_MODE (pointer_to) == QImode)
6628 obstack_1grow (&util_obstack, '*');
6632 /* We have a type that does not get special treatment. */
6634 /* NeXT extension */
6635 obstack_1grow (&util_obstack, '^');
6636 encode_type (pointer_to, curtype, format);
6640 encode_array (type, curtype, format)
6645 tree an_int_cst = TYPE_SIZE (type);
6646 tree array_of = TREE_TYPE (type);
6649 /* An incomplete array is treated like a pointer. */
6650 if (an_int_cst == NULL)
6652 encode_pointer (type, curtype, format);
6656 sprintf (buffer, "[%ld",
6657 (long) (TREE_INT_CST_LOW (an_int_cst)
6658 / TREE_INT_CST_LOW (TYPE_SIZE (array_of))));
6660 obstack_grow (&util_obstack, buffer, strlen (buffer));
6661 encode_type (array_of, curtype, format);
6662 obstack_1grow (&util_obstack, ']');
6667 encode_aggregate_within (type, curtype, format, left, right)
6674 /* The RECORD_TYPE may in fact be a typedef! For purposes
6675 of encoding, we need the real underlying enchilada. */
6676 if (TYPE_MAIN_VARIANT (type))
6677 type = TYPE_MAIN_VARIANT (type);
6679 if (obstack_object_size (&util_obstack) > 0
6680 && *(obstack_next_free (&util_obstack) - 1) == '^')
6682 tree name = TYPE_NAME (type);
6684 /* we have a reference; this is a NeXT extension. */
6686 if (obstack_object_size (&util_obstack) - curtype == 1
6687 && format == OBJC_ENCODE_INLINE_DEFS)
6689 /* Output format of struct for first level only. */
6690 tree fields = TYPE_FIELDS (type);
6692 if (name && TREE_CODE (name) == IDENTIFIER_NODE)
6694 obstack_1grow (&util_obstack, left);
6695 obstack_grow (&util_obstack,
6696 IDENTIFIER_POINTER (name),
6697 strlen (IDENTIFIER_POINTER (name)));
6698 obstack_1grow (&util_obstack, '=');
6702 obstack_1grow (&util_obstack, left);
6703 obstack_grow (&util_obstack, "?=", 2);
6706 for ( ; fields; fields = TREE_CHAIN (fields))
6707 encode_field_decl (fields, curtype, format);
6709 obstack_1grow (&util_obstack, right);
6712 else if (name && TREE_CODE (name) == IDENTIFIER_NODE)
6714 obstack_1grow (&util_obstack, left);
6715 obstack_grow (&util_obstack,
6716 IDENTIFIER_POINTER (name),
6717 strlen (IDENTIFIER_POINTER (name)));
6718 obstack_1grow (&util_obstack, right);
6723 /* We have an untagged structure or a typedef. */
6724 obstack_1grow (&util_obstack, left);
6725 obstack_1grow (&util_obstack, '?');
6726 obstack_1grow (&util_obstack, right);
6732 tree name = TYPE_NAME (type);
6733 tree fields = TYPE_FIELDS (type);
6735 if (format == OBJC_ENCODE_INLINE_DEFS
6736 || generating_instance_variables)
6738 obstack_1grow (&util_obstack, left);
6739 if (name && TREE_CODE (name) == IDENTIFIER_NODE)
6740 obstack_grow (&util_obstack,
6741 IDENTIFIER_POINTER (name),
6742 strlen (IDENTIFIER_POINTER (name)));
6744 obstack_1grow (&util_obstack, '?');
6746 obstack_1grow (&util_obstack, '=');
6748 for (; fields; fields = TREE_CHAIN (fields))
6750 if (generating_instance_variables)
6752 tree fname = DECL_NAME (fields);
6754 obstack_1grow (&util_obstack, '"');
6755 if (fname && TREE_CODE (fname) == IDENTIFIER_NODE)
6757 obstack_grow (&util_obstack,
6758 IDENTIFIER_POINTER (fname),
6759 strlen (IDENTIFIER_POINTER (fname)));
6762 obstack_1grow (&util_obstack, '"');
6765 encode_field_decl (fields, curtype, format);
6768 obstack_1grow (&util_obstack, right);
6773 obstack_1grow (&util_obstack, left);
6774 if (name && TREE_CODE (name) == IDENTIFIER_NODE)
6775 obstack_grow (&util_obstack,
6776 IDENTIFIER_POINTER (name),
6777 strlen (IDENTIFIER_POINTER (name)));
6779 /* We have an untagged structure or a typedef. */
6780 obstack_1grow (&util_obstack, '?');
6782 obstack_1grow (&util_obstack, right);
6788 encode_aggregate (type, curtype, format)
6793 enum tree_code code = TREE_CODE (type);
6799 encode_aggregate_within(type, curtype, format, '{', '}');
6804 encode_aggregate_within(type, curtype, format, '(', ')');
6809 obstack_1grow (&util_obstack, 'i');
6817 /* Support bitfields. The current version of Objective-C does not support
6818 them. The string will consist of one or more "b:n"'s where n is an
6819 integer describing the width of the bitfield. Currently, classes in
6820 the kit implement a method "-(char *)describeBitfieldStruct:" that
6821 simulates this. If they do not implement this method, the archiver
6822 assumes the bitfield is 16 bits wide (padded if necessary) and packed
6823 according to the GNU compiler. After looking at the "kit", it appears
6824 that all classes currently rely on this default behavior, rather than
6825 hand generating this string (which is tedious). */
6828 encode_bitfield (width)
6832 sprintf (buffer, "b%d", width);
6833 obstack_grow (&util_obstack, buffer, strlen (buffer));
6836 /* FORMAT will be OBJC_ENCODE_INLINE_DEFS or OBJC_ENCODE_DONT_INLINE_DEFS. */
6839 encode_type (type, curtype, format)
6844 enum tree_code code = TREE_CODE (type);
6846 if (code == INTEGER_TYPE)
6848 if (integer_zerop (TYPE_MIN_VALUE (type)))
6850 /* Unsigned integer types. */
6852 if (TYPE_MODE (type) == QImode)
6853 obstack_1grow (&util_obstack, 'C');
6854 else if (TYPE_MODE (type) == HImode)
6855 obstack_1grow (&util_obstack, 'S');
6856 else if (TYPE_MODE (type) == SImode)
6858 if (type == long_unsigned_type_node)
6859 obstack_1grow (&util_obstack, 'L');
6861 obstack_1grow (&util_obstack, 'I');
6863 else if (TYPE_MODE (type) == DImode)
6864 obstack_1grow (&util_obstack, 'Q');
6868 /* Signed integer types. */
6870 if (TYPE_MODE (type) == QImode)
6871 obstack_1grow (&util_obstack, 'c');
6872 else if (TYPE_MODE (type) == HImode)
6873 obstack_1grow (&util_obstack, 's');
6874 else if (TYPE_MODE (type) == SImode)
6876 if (type == long_integer_type_node)
6877 obstack_1grow (&util_obstack, 'l');
6879 obstack_1grow (&util_obstack, 'i');
6882 else if (TYPE_MODE (type) == DImode)
6883 obstack_1grow (&util_obstack, 'q');
6887 else if (code == REAL_TYPE)
6889 /* Floating point types. */
6891 if (TYPE_MODE (type) == SFmode)
6892 obstack_1grow (&util_obstack, 'f');
6893 else if (TYPE_MODE (type) == DFmode
6894 || TYPE_MODE (type) == TFmode)
6895 obstack_1grow (&util_obstack, 'd');
6898 else if (code == VOID_TYPE)
6899 obstack_1grow (&util_obstack, 'v');
6901 else if (code == ARRAY_TYPE)
6902 encode_array (type, curtype, format);
6904 else if (code == POINTER_TYPE)
6905 encode_pointer (type, curtype, format);
6907 else if (code == RECORD_TYPE || code == UNION_TYPE || code == ENUMERAL_TYPE)
6908 encode_aggregate (type, curtype, format);
6910 else if (code == FUNCTION_TYPE) /* '?' */
6911 obstack_1grow (&util_obstack, '?');
6915 encode_complete_bitfield (position, type, size)
6920 enum tree_code code = TREE_CODE (type);
6922 char charType = '?';
6924 if (code == INTEGER_TYPE)
6926 if (integer_zerop (TYPE_MIN_VALUE (type)))
6928 /* Unsigned integer types. */
6930 if (TYPE_MODE (type) == QImode)
6932 else if (TYPE_MODE (type) == HImode)
6934 else if (TYPE_MODE (type) == SImode)
6936 if (type == long_unsigned_type_node)
6941 else if (TYPE_MODE (type) == DImode)
6946 /* Signed integer types. */
6948 if (TYPE_MODE (type) == QImode)
6950 else if (TYPE_MODE (type) == HImode)
6952 else if (TYPE_MODE (type) == SImode)
6954 if (type == long_integer_type_node)
6960 else if (TYPE_MODE (type) == DImode)
6964 else if (code == ENUMERAL_TYPE)
6969 sprintf (buffer, "b%d%c%d", position, charType, size);
6970 obstack_grow (&util_obstack, buffer, strlen (buffer));
6974 encode_field_decl (field_decl, curtype, format)
6981 type = TREE_TYPE (field_decl);
6983 /* If this field is obviously a bitfield, or is a bitfield that has been
6984 clobbered to look like a ordinary integer mode, go ahead and generate
6985 the bitfield typing information. */
6986 if (flag_next_runtime)
6988 if (DECL_BIT_FIELD_TYPE (field_decl))
6989 encode_bitfield (tree_low_cst (DECL_SIZE (field_decl), 1));
6991 encode_type (TREE_TYPE (field_decl), curtype, format);
6995 if (DECL_BIT_FIELD_TYPE (field_decl))
6996 encode_complete_bitfield (int_bit_position (field_decl),
6997 DECL_BIT_FIELD_TYPE (field_decl),
6998 tree_low_cst (DECL_SIZE (field_decl), 1));
7000 encode_type (TREE_TYPE (field_decl), curtype, format);
7005 expr_last (complex_expr)
7011 while ((next = TREE_OPERAND (complex_expr, 0)))
7012 complex_expr = next;
7014 return complex_expr;
7017 /* Transform a method definition into a function definition as follows:
7018 - synthesize the first two arguments, "self" and "_cmd". */
7021 start_method_def (method)
7026 /* Required to implement _msgSuper. */
7027 objc_method_context = method;
7028 UOBJC_SUPER_decl = NULL_TREE;
7030 /* Must be called BEFORE start_function. */
7033 /* Generate prototype declarations for arguments..."new-style". */
7035 if (TREE_CODE (objc_method_context) == INSTANCE_METHOD_DECL)
7036 decl_specs = build_tree_list (NULL_TREE, uprivate_record);
7038 /* Really a `struct objc_class *'. However, we allow people to
7039 assign to self, which changes its type midstream. */
7040 decl_specs = build_tree_list (NULL_TREE, objc_object_reference);
7042 push_parm_decl (build_tree_list
7043 (build_tree_list (decl_specs,
7044 build1 (INDIRECT_REF, NULL_TREE, self_id)),
7047 decl_specs = build_tree_list (NULL_TREE,
7048 xref_tag (RECORD_TYPE,
7049 get_identifier (TAG_SELECTOR)));
7050 push_parm_decl (build_tree_list
7051 (build_tree_list (decl_specs,
7052 build1 (INDIRECT_REF, NULL_TREE, ucmd_id)),
7055 /* Generate argument declarations if a keyword_decl. */
7056 if (METHOD_SEL_ARGS (method))
7058 tree arglist = METHOD_SEL_ARGS (method);
7061 tree arg_spec = TREE_PURPOSE (TREE_TYPE (arglist));
7062 tree arg_decl = TREE_VALUE (TREE_TYPE (arglist));
7066 tree last_expr = expr_last (arg_decl);
7068 /* Unite the abstract decl with its name. */
7069 TREE_OPERAND (last_expr, 0) = KEYWORD_ARG_NAME (arglist);
7070 push_parm_decl (build_tree_list
7071 (build_tree_list (arg_spec, arg_decl),
7074 /* Unhook: restore the abstract declarator. */
7075 TREE_OPERAND (last_expr, 0) = NULL_TREE;
7079 push_parm_decl (build_tree_list
7080 (build_tree_list (arg_spec,
7081 KEYWORD_ARG_NAME (arglist)),
7084 arglist = TREE_CHAIN (arglist);
7089 if (METHOD_ADD_ARGS (method) != NULL_TREE
7090 && METHOD_ADD_ARGS (method) != objc_ellipsis_node)
7092 /* We have a variable length selector - in "prototype" format. */
7093 tree akey = TREE_PURPOSE (METHOD_ADD_ARGS (method));
7096 /* This must be done prior to calling pushdecl. pushdecl is
7097 going to change our chain on us. */
7098 tree nextkey = TREE_CHAIN (akey);
7106 warn_with_method (message, mtype, method)
7107 const char *message;
7111 if (!diagnostic_count_diagnostic (global_dc, DK_WARNING))
7114 diagnostic_report_current_function (global_dc);
7116 /* Add a readable method name to the warning. */
7117 warning ("%H%s `%c%s'", &DECL_SOURCE_LOCATION (method),
7118 message, mtype, gen_method_decl (method, errbuf));
7121 /* Return 1 if METHOD is consistent with PROTO. */
7124 comp_method_with_proto (method, proto)
7127 /* Create a function template node at most once. */
7128 if (!function1_template)
7129 function1_template = make_node (FUNCTION_TYPE);
7131 /* Install argument types - normally set by build_function_type. */
7132 TYPE_ARG_TYPES (function1_template) = get_arg_type_list (proto, METHOD_DEF, 0);
7134 /* install return type */
7135 TREE_TYPE (function1_template) = groktypename (TREE_TYPE (proto));
7137 return comptypes (TREE_TYPE (METHOD_DEFINITION (method)), function1_template);
7140 /* Return 1 if PROTO1 is consistent with PROTO2. */
7143 comp_proto_with_proto (proto0, proto1)
7144 tree proto0, proto1;
7146 /* Create a couple of function_template nodes at most once. */
7147 if (!function1_template)
7148 function1_template = make_node (FUNCTION_TYPE);
7149 if (!function2_template)
7150 function2_template = make_node (FUNCTION_TYPE);
7152 /* Install argument types; normally set by build_function_type. */
7153 TYPE_ARG_TYPES (function1_template) = get_arg_type_list (proto0, METHOD_REF, 0);
7154 TYPE_ARG_TYPES (function2_template) = get_arg_type_list (proto1, METHOD_REF, 0);
7156 /* Install return type. */
7157 TREE_TYPE (function1_template) = groktypename (TREE_TYPE (proto0));
7158 TREE_TYPE (function2_template) = groktypename (TREE_TYPE (proto1));
7160 return comptypes (function1_template, function2_template);
7163 /* - Generate an identifier for the function. the format is "_n_cls",
7164 where 1 <= n <= nMethods, and cls is the name the implementation we
7166 - Install the return type from the method declaration.
7167 - If we have a prototype, check for type consistency. */
7170 really_start_method (method, parmlist)
7171 tree method, parmlist;
7173 tree sc_spec, ret_spec, ret_decl, decl_specs;
7174 tree method_decl, method_id;
7175 const char *sel_name, *class_name, *cat_name;
7178 /* Synth the storage class & assemble the return type. */
7179 sc_spec = tree_cons (NULL_TREE, ridpointers[(int) RID_STATIC], NULL_TREE);
7180 ret_spec = TREE_PURPOSE (TREE_TYPE (method));
7181 decl_specs = chainon (sc_spec, ret_spec);
7183 sel_name = IDENTIFIER_POINTER (METHOD_SEL_NAME (method));
7184 class_name = IDENTIFIER_POINTER (CLASS_NAME (objc_implementation_context));
7185 cat_name = ((TREE_CODE (objc_implementation_context)
7186 == CLASS_IMPLEMENTATION_TYPE)
7188 : IDENTIFIER_POINTER (CLASS_SUPER_NAME (objc_implementation_context)));
7191 /* Make sure this is big enough for any plausible method label. */
7192 buf = (char *) alloca (50 + strlen (sel_name) + strlen (class_name)
7193 + (cat_name ? strlen (cat_name) : 0));
7195 OBJC_GEN_METHOD_LABEL (buf, TREE_CODE (method) == INSTANCE_METHOD_DECL,
7196 class_name, cat_name, sel_name, method_slot);
7198 method_id = get_identifier (buf);
7200 method_decl = build_nt (CALL_EXPR, method_id, parmlist, NULL_TREE);
7202 /* Check the declarator portion of the return type for the method. */
7203 if ((ret_decl = TREE_VALUE (TREE_TYPE (method))))
7205 /* Unite the complex decl (specified in the abstract decl) with the
7206 function decl just synthesized..(int *), (int (*)()), (int (*)[]). */
7207 tree save_expr = expr_last (ret_decl);
7209 TREE_OPERAND (save_expr, 0) = method_decl;
7210 method_decl = ret_decl;
7212 /* Fool the parser into thinking it is starting a function. */
7213 start_function (decl_specs, method_decl, NULL_TREE);
7215 /* Unhook: this has the effect of restoring the abstract declarator. */
7216 TREE_OPERAND (save_expr, 0) = NULL_TREE;
7221 TREE_VALUE (TREE_TYPE (method)) = method_decl;
7223 /* Fool the parser into thinking it is starting a function. */
7224 start_function (decl_specs, method_decl, NULL_TREE);
7226 /* Unhook: this has the effect of restoring the abstract declarator. */
7227 TREE_VALUE (TREE_TYPE (method)) = NULL_TREE;
7230 METHOD_DEFINITION (method) = current_function_decl;
7232 /* Check consistency...start_function, pushdecl, duplicate_decls. */
7234 if (implementation_template != objc_implementation_context)
7238 if (TREE_CODE (method) == INSTANCE_METHOD_DECL)
7239 proto = lookup_instance_method_static (implementation_template,
7240 METHOD_SEL_NAME (method));
7242 proto = lookup_class_method_static (implementation_template,
7243 METHOD_SEL_NAME (method));
7245 if (proto && ! comp_method_with_proto (method, proto))
7247 char type = (TREE_CODE (method) == INSTANCE_METHOD_DECL ? '-' : '+');
7249 warn_with_method ("conflicting types for", type, method);
7250 warn_with_method ("previous declaration of", type, proto);
7255 /* The following routine is always called...this "architecture" is to
7256 accommodate "old-style" variable length selectors.
7258 - a:a b:b // prototype ; id c; id d; // old-style. */
7261 continue_method_def ()
7265 if (METHOD_ADD_ARGS (objc_method_context) == objc_ellipsis_node)
7266 /* We have a `, ...' immediately following the selector. */
7267 parmlist = get_parm_info (0);
7269 parmlist = get_parm_info (1); /* place a `void_at_end' */
7271 /* Set self_decl from the first argument...this global is used by
7272 build_ivar_reference calling build_indirect_ref. */
7273 self_decl = TREE_PURPOSE (parmlist);
7276 really_start_method (objc_method_context, parmlist);
7277 store_parm_decls ();
7280 /* Called by the parser, from the `pushlevel' production. */
7285 if (!UOBJC_SUPER_decl)
7287 UOBJC_SUPER_decl = start_decl (get_identifier (UTAG_SUPER),
7288 build_tree_list (NULL_TREE,
7289 objc_super_template),
7292 finish_decl (UOBJC_SUPER_decl, NULL_TREE, NULL_TREE);
7294 /* This prevents `unused variable' warnings when compiling with -Wall. */
7295 TREE_USED (UOBJC_SUPER_decl) = 1;
7296 DECL_ARTIFICIAL (UOBJC_SUPER_decl) = 1;
7300 /* _n_Method (id self, SEL sel, ...)
7302 struct objc_super _S;
7303 _msgSuper ((_S.self = self, _S.class = _cls, &_S), ...);
7307 get_super_receiver ()
7309 if (objc_method_context)
7311 tree super_expr, super_expr_list;
7313 /* Set receiver to self. */
7314 super_expr = build_component_ref (UOBJC_SUPER_decl, self_id);
7315 super_expr = build_modify_expr (super_expr, NOP_EXPR, self_decl);
7316 super_expr_list = build_tree_list (NULL_TREE, super_expr);
7318 /* Set class to begin searching. */
7319 super_expr = build_component_ref (UOBJC_SUPER_decl,
7320 get_identifier ("class"));
7322 if (TREE_CODE (objc_implementation_context) == CLASS_IMPLEMENTATION_TYPE)
7324 /* [_cls, __cls]Super are "pre-built" in
7325 synth_forward_declarations. */
7327 super_expr = build_modify_expr (super_expr, NOP_EXPR,
7328 ((TREE_CODE (objc_method_context)
7329 == INSTANCE_METHOD_DECL)
7331 : uucls_super_ref));
7335 /* We have a category. */
7337 tree super_name = CLASS_SUPER_NAME (implementation_template);
7340 /* Barf if super used in a category of Object. */
7343 error ("no super class declared in interface for `%s'",
7344 IDENTIFIER_POINTER (CLASS_NAME (implementation_template)));
7345 return error_mark_node;
7348 if (flag_next_runtime)
7350 super_class = get_class_reference (super_name);
7351 if (TREE_CODE (objc_method_context) == CLASS_METHOD_DECL)
7352 /* Cast the super class to 'id', since the user may not have
7353 included <objc/objc-class.h>, leaving 'struct objc_class'
7354 an incomplete type. */
7356 = build_component_ref (build_indirect_ref
7357 (build_c_cast (id_type, super_class), "->"),
7358 get_identifier ("isa"));
7362 add_class_reference (super_name);
7363 super_class = (TREE_CODE (objc_method_context) == INSTANCE_METHOD_DECL
7364 ? objc_get_class_decl : objc_get_meta_class_decl);
7365 assemble_external (super_class);
7367 = build_function_call
7371 my_build_string (IDENTIFIER_LENGTH (super_name) + 1,
7372 IDENTIFIER_POINTER (super_name))));
7375 TREE_TYPE (super_class) = TREE_TYPE (ucls_super_ref);
7376 super_expr = build_modify_expr (super_expr, NOP_EXPR, super_class);
7379 chainon (super_expr_list, build_tree_list (NULL_TREE, super_expr));
7381 super_expr = build_unary_op (ADDR_EXPR, UOBJC_SUPER_decl, 0);
7382 chainon (super_expr_list, build_tree_list (NULL_TREE, super_expr));
7384 return build_compound_expr (super_expr_list);
7388 error ("[super ...] must appear in a method context");
7389 return error_mark_node;
7394 encode_method_def (func_decl)
7399 HOST_WIDE_INT max_parm_end = 0;
7404 encode_type (TREE_TYPE (TREE_TYPE (func_decl)),
7405 obstack_object_size (&util_obstack),
7406 OBJC_ENCODE_INLINE_DEFS);
7409 for (parms = DECL_ARGUMENTS (func_decl); parms;
7410 parms = TREE_CHAIN (parms))
7412 HOST_WIDE_INT parm_end = (forwarding_offset (parms)
7413 + int_size_in_bytes (TREE_TYPE (parms)));
7415 if (! offset_is_register && parm_end > max_parm_end)
7416 max_parm_end = parm_end;
7419 stack_size = max_parm_end - OBJC_FORWARDING_MIN_OFFSET;
7421 sprintf (buffer, "%d", stack_size);
7422 obstack_grow (&util_obstack, buffer, strlen (buffer));
7424 /* Argument types. */
7425 for (parms = DECL_ARGUMENTS (func_decl); parms;
7426 parms = TREE_CHAIN (parms))
7429 encode_type (TREE_TYPE (parms),
7430 obstack_object_size (&util_obstack),
7431 OBJC_ENCODE_INLINE_DEFS);
7433 /* Compute offset. */
7434 sprintf (buffer, "%d", forwarding_offset (parms));
7436 /* Indicate register. */
7437 if (offset_is_register)
7438 obstack_1grow (&util_obstack, '+');
7440 obstack_grow (&util_obstack, buffer, strlen (buffer));
7443 /* Null terminate string. */
7444 obstack_1grow (&util_obstack, 0);
7445 result = get_identifier (obstack_finish (&util_obstack));
7446 obstack_free (&util_obstack, util_firstobj);
7451 objc_expand_function_end ()
7453 METHOD_ENCODING (objc_method_context) = encode_method_def (current_function_decl);
7457 finish_method_def ()
7459 lang_expand_function_end = objc_expand_function_end;
7460 finish_function (0, 1);
7461 lang_expand_function_end = NULL;
7463 /* Required to implement _msgSuper. This must be done AFTER finish_function,
7464 since the optimizer may find "may be used before set" errors. */
7465 objc_method_context = NULL_TREE;
7470 lang_report_error_function (decl)
7473 if (objc_method_context)
7475 fprintf (stderr, "In method `%s'\n",
7476 IDENTIFIER_POINTER (METHOD_SEL_NAME (objc_method_context)));
7486 is_complex_decl (type)
7489 return (TREE_CODE (type) == ARRAY_TYPE
7490 || TREE_CODE (type) == FUNCTION_TYPE
7491 || (TREE_CODE (type) == POINTER_TYPE && ! IS_ID (type)));
7495 /* Code to convert a decl node into text for a declaration in C. */
7497 static char tmpbuf[256];
7500 adorn_decl (decl, str)
7504 enum tree_code code = TREE_CODE (decl);
7506 if (code == ARRAY_REF)
7508 tree an_int_cst = TREE_OPERAND (decl, 1);
7510 if (an_int_cst && TREE_CODE (an_int_cst) == INTEGER_CST)
7511 sprintf (str + strlen (str), "[%ld]",
7512 (long) TREE_INT_CST_LOW (an_int_cst));
7517 else if (code == ARRAY_TYPE)
7519 tree an_int_cst = TYPE_SIZE (decl);
7520 tree array_of = TREE_TYPE (decl);
7522 if (an_int_cst && TREE_CODE (an_int_cst) == INTEGER_TYPE)
7523 sprintf (str + strlen (str), "[%ld]",
7524 (long) (TREE_INT_CST_LOW (an_int_cst)
7525 / TREE_INT_CST_LOW (TYPE_SIZE (array_of))));
7530 else if (code == CALL_EXPR)
7532 tree chain = TREE_PURPOSE (TREE_OPERAND (decl, 1));
7537 gen_declaration_1 (chain, str);
7538 chain = TREE_CHAIN (chain);
7545 else if (code == FUNCTION_TYPE)
7547 tree chain = TYPE_ARG_TYPES (decl);
7550 while (chain && TREE_VALUE (chain) != void_type_node)
7552 gen_declaration_1 (TREE_VALUE (chain), str);
7553 chain = TREE_CHAIN (chain);
7554 if (chain && TREE_VALUE (chain) != void_type_node)
7560 else if (code == INDIRECT_REF)
7562 strcpy (tmpbuf, "*");
7563 if (TREE_TYPE (decl) && TREE_CODE (TREE_TYPE (decl)) == TREE_LIST)
7567 for (chain = nreverse (copy_list (TREE_TYPE (decl)));
7569 chain = TREE_CHAIN (chain))
7571 if (TREE_CODE (TREE_VALUE (chain)) == IDENTIFIER_NODE)
7573 strcat (tmpbuf, " ");
7574 strcat (tmpbuf, IDENTIFIER_POINTER (TREE_VALUE (chain)));
7578 strcat (tmpbuf, " ");
7580 strcat (tmpbuf, str);
7581 strcpy (str, tmpbuf);
7584 else if (code == POINTER_TYPE)
7586 strcpy (tmpbuf, "*");
7587 if (TREE_READONLY (decl) || TYPE_VOLATILE (decl))
7589 if (TREE_READONLY (decl))
7590 strcat (tmpbuf, " const");
7591 if (TYPE_VOLATILE (decl))
7592 strcat (tmpbuf, " volatile");
7594 strcat (tmpbuf, " ");
7596 strcat (tmpbuf, str);
7597 strcpy (str, tmpbuf);
7602 gen_declarator (decl, buf, name)
7609 enum tree_code code = TREE_CODE (decl);
7619 op = TREE_OPERAND (decl, 0);
7621 /* We have a pointer to a function or array...(*)(), (*)[] */
7622 if ((code == ARRAY_REF || code == CALL_EXPR)
7623 && op && TREE_CODE (op) == INDIRECT_REF)
7626 str = gen_declarator (op, buf, name);
7630 strcpy (tmpbuf, "(");
7631 strcat (tmpbuf, str);
7632 strcat (tmpbuf, ")");
7633 strcpy (str, tmpbuf);
7636 adorn_decl (decl, str);
7645 /* This clause is done iteratively rather than recursively. */
7648 op = (is_complex_decl (TREE_TYPE (decl))
7649 ? TREE_TYPE (decl) : NULL_TREE);
7651 adorn_decl (decl, str);
7653 /* We have a pointer to a function or array...(*)(), (*)[] */
7654 if (code == POINTER_TYPE
7655 && op && (TREE_CODE (op) == FUNCTION_TYPE
7656 || TREE_CODE (op) == ARRAY_TYPE))
7658 strcpy (tmpbuf, "(");
7659 strcat (tmpbuf, str);
7660 strcat (tmpbuf, ")");
7661 strcpy (str, tmpbuf);
7664 decl = (is_complex_decl (TREE_TYPE (decl))
7665 ? TREE_TYPE (decl) : NULL_TREE);
7668 while (decl && (code = TREE_CODE (decl)))
7673 case IDENTIFIER_NODE:
7674 /* Will only happen if we are processing a "raw" expr-decl. */
7675 strcpy (buf, IDENTIFIER_POINTER (decl));
7686 /* We have an abstract declarator or a _DECL node. */
7694 gen_declspecs (declspecs, buf, raw)
7703 for (chain = nreverse (copy_list (declspecs));
7704 chain; chain = TREE_CHAIN (chain))
7706 tree aspec = TREE_VALUE (chain);
7708 if (TREE_CODE (aspec) == IDENTIFIER_NODE)
7709 strcat (buf, IDENTIFIER_POINTER (aspec));
7710 else if (TREE_CODE (aspec) == RECORD_TYPE)
7712 if (TYPE_NAME (aspec))
7714 tree protocol_list = TYPE_PROTOCOL_LIST (aspec);
7716 if (! TREE_STATIC_TEMPLATE (aspec))
7717 strcat (buf, "struct ");
7718 strcat (buf, IDENTIFIER_POINTER (TYPE_NAME (aspec)));
7723 tree chain = protocol_list;
7730 (PROTOCOL_NAME (TREE_VALUE (chain))));
7731 chain = TREE_CHAIN (chain);
7740 strcat (buf, "untagged struct");
7743 else if (TREE_CODE (aspec) == UNION_TYPE)
7745 if (TYPE_NAME (aspec))
7747 if (! TREE_STATIC_TEMPLATE (aspec))
7748 strcat (buf, "union ");
7749 strcat (buf, IDENTIFIER_POINTER (TYPE_NAME (aspec)));
7752 strcat (buf, "untagged union");
7755 else if (TREE_CODE (aspec) == ENUMERAL_TYPE)
7757 if (TYPE_NAME (aspec))
7759 if (! TREE_STATIC_TEMPLATE (aspec))
7760 strcat (buf, "enum ");
7761 strcat (buf, IDENTIFIER_POINTER (TYPE_NAME (aspec)));
7764 strcat (buf, "untagged enum");
7767 else if (TREE_CODE (aspec) == TYPE_DECL && DECL_NAME (aspec))
7768 strcat (buf, IDENTIFIER_POINTER (DECL_NAME (aspec)));
7770 else if (IS_ID (aspec))
7772 tree protocol_list = TYPE_PROTOCOL_LIST (aspec);
7777 tree chain = protocol_list;
7784 (PROTOCOL_NAME (TREE_VALUE (chain))));
7785 chain = TREE_CHAIN (chain);
7792 if (TREE_CHAIN (chain))
7798 /* Type qualifiers. */
7799 if (TREE_READONLY (declspecs))
7800 strcat (buf, "const ");
7801 if (TYPE_VOLATILE (declspecs))
7802 strcat (buf, "volatile ");
7804 switch (TREE_CODE (declspecs))
7806 /* Type specifiers. */
7809 declspecs = TYPE_MAIN_VARIANT (declspecs);
7811 /* Signed integer types. */
7813 if (declspecs == short_integer_type_node)
7814 strcat (buf, "short int ");
7815 else if (declspecs == integer_type_node)
7816 strcat (buf, "int ");
7817 else if (declspecs == long_integer_type_node)
7818 strcat (buf, "long int ");
7819 else if (declspecs == long_long_integer_type_node)
7820 strcat (buf, "long long int ");
7821 else if (declspecs == signed_char_type_node
7822 || declspecs == char_type_node)
7823 strcat (buf, "char ");
7825 /* Unsigned integer types. */
7827 else if (declspecs == short_unsigned_type_node)
7828 strcat (buf, "unsigned short ");
7829 else if (declspecs == unsigned_type_node)
7830 strcat (buf, "unsigned int ");
7831 else if (declspecs == long_unsigned_type_node)
7832 strcat (buf, "unsigned long ");
7833 else if (declspecs == long_long_unsigned_type_node)
7834 strcat (buf, "unsigned long long ");
7835 else if (declspecs == unsigned_char_type_node)
7836 strcat (buf, "unsigned char ");
7840 declspecs = TYPE_MAIN_VARIANT (declspecs);
7842 if (declspecs == float_type_node)
7843 strcat (buf, "float ");
7844 else if (declspecs == double_type_node)
7845 strcat (buf, "double ");
7846 else if (declspecs == long_double_type_node)
7847 strcat (buf, "long double ");
7851 if (TYPE_NAME (declspecs)
7852 && TREE_CODE (TYPE_NAME (declspecs)) == IDENTIFIER_NODE)
7854 tree protocol_list = TYPE_PROTOCOL_LIST (declspecs);
7856 if (! TREE_STATIC_TEMPLATE (declspecs))
7857 strcat (buf, "struct ");
7858 strcat (buf, IDENTIFIER_POINTER (TYPE_NAME (declspecs)));
7862 tree chain = protocol_list;
7869 (PROTOCOL_NAME (TREE_VALUE (chain))));
7870 chain = TREE_CHAIN (chain);
7879 strcat (buf, "untagged struct");
7885 if (TYPE_NAME (declspecs)
7886 && TREE_CODE (TYPE_NAME (declspecs)) == IDENTIFIER_NODE)
7888 strcat (buf, "union ");
7889 strcat (buf, IDENTIFIER_POINTER (TYPE_NAME (declspecs)));
7894 strcat (buf, "untagged union ");
7898 if (TYPE_NAME (declspecs)
7899 && TREE_CODE (TYPE_NAME (declspecs)) == IDENTIFIER_NODE)
7901 strcat (buf, "enum ");
7902 strcat (buf, IDENTIFIER_POINTER (TYPE_NAME (declspecs)));
7907 strcat (buf, "untagged enum ");
7911 strcat (buf, "void ");
7916 tree protocol_list = TYPE_PROTOCOL_LIST (declspecs);
7921 tree chain = protocol_list;
7928 (PROTOCOL_NAME (TREE_VALUE (chain))));
7929 chain = TREE_CHAIN (chain);
7945 /* Given a tree node, produce a printable description of it in the given
7946 buffer, overwriting the buffer. */
7949 gen_declaration (atype_or_adecl, buf)
7950 tree atype_or_adecl;
7954 gen_declaration_1 (atype_or_adecl, buf);
7958 /* Given a tree node, append a printable description to the end of the
7962 gen_declaration_1 (atype_or_adecl, buf)
7963 tree atype_or_adecl;
7968 if (TREE_CODE (atype_or_adecl) == TREE_LIST)
7970 tree declspecs; /* "identifier_node", "record_type" */
7971 tree declarator; /* "array_ref", "indirect_ref", "call_expr"... */
7973 /* We have a "raw", abstract declarator (typename). */
7974 declarator = TREE_VALUE (atype_or_adecl);
7975 declspecs = TREE_PURPOSE (atype_or_adecl);
7977 gen_declspecs (declspecs, buf, 1);
7981 strcat (buf, gen_declarator (declarator, declbuf, ""));
7988 tree declspecs; /* "integer_type", "real_type", "record_type"... */
7989 tree declarator; /* "array_type", "function_type", "pointer_type". */
7991 if (TREE_CODE (atype_or_adecl) == FIELD_DECL
7992 || TREE_CODE (atype_or_adecl) == PARM_DECL
7993 || TREE_CODE (atype_or_adecl) == FUNCTION_DECL)
7994 atype = TREE_TYPE (atype_or_adecl);
7996 /* Assume we have a *_type node. */
7997 atype = atype_or_adecl;
7999 if (is_complex_decl (atype))
8003 /* Get the declaration specifier; it is at the end of the list. */
8004 declarator = chain = atype;
8006 chain = TREE_TYPE (chain); /* not TREE_CHAIN (chain); */
8007 while (is_complex_decl (chain));
8014 declarator = NULL_TREE;
8017 gen_declspecs (declspecs, buf, 0);
8019 if (TREE_CODE (atype_or_adecl) == FIELD_DECL
8020 || TREE_CODE (atype_or_adecl) == PARM_DECL
8021 || TREE_CODE (atype_or_adecl) == FUNCTION_DECL)
8023 const char *const decl_name =
8024 (DECL_NAME (atype_or_adecl)
8025 ? IDENTIFIER_POINTER (DECL_NAME (atype_or_adecl)) : "");
8030 strcat (buf, gen_declarator (declarator, declbuf, decl_name));
8033 else if (decl_name[0])
8036 strcat (buf, decl_name);
8039 else if (declarator)
8042 strcat (buf, gen_declarator (declarator, declbuf, ""));
8047 #define RAW_TYPESPEC(meth) (TREE_VALUE (TREE_PURPOSE (TREE_TYPE (meth))))
8049 /* Given a method tree, put a printable description into the given
8050 buffer (overwriting) and return a pointer to the buffer. */
8053 gen_method_decl (method, buf)
8060 if (RAW_TYPESPEC (method) != objc_object_reference)
8063 gen_declaration_1 (TREE_TYPE (method), buf);
8067 chain = METHOD_SEL_ARGS (method);
8070 /* We have a chain of keyword_decls. */
8073 if (KEYWORD_KEY_NAME (chain))
8074 strcat (buf, IDENTIFIER_POINTER (KEYWORD_KEY_NAME (chain)));
8077 if (RAW_TYPESPEC (chain) != objc_object_reference)
8080 gen_declaration_1 (TREE_TYPE (chain), buf);
8084 strcat (buf, IDENTIFIER_POINTER (KEYWORD_ARG_NAME (chain)));
8085 if ((chain = TREE_CHAIN (chain)))
8090 if (METHOD_ADD_ARGS (method) == objc_ellipsis_node)
8091 strcat (buf, ", ...");
8092 else if (METHOD_ADD_ARGS (method))
8094 /* We have a tree list node as generate by get_parm_info. */
8095 chain = TREE_PURPOSE (METHOD_ADD_ARGS (method));
8097 /* Know we have a chain of parm_decls. */
8101 gen_declaration_1 (chain, buf);
8102 chain = TREE_CHAIN (chain);
8108 /* We have a unary selector. */
8109 strcat (buf, IDENTIFIER_POINTER (METHOD_SEL_NAME (method)));
8117 /* Dump an @interface declaration of the supplied class CHAIN to the
8118 supplied file FP. Used to implement the -gen-decls option (which
8119 prints out an @interface declaration of all classes compiled in
8120 this run); potentially useful for debugging the compiler too. */
8122 dump_interface (fp, chain)
8126 /* FIXME: A heap overflow here whenever a method (or ivar)
8127 declaration is so long that it doesn't fit in the buffer. The
8128 code and all the related functions should be rewritten to avoid
8129 using fixed size buffers. */
8130 char *buf = (char *) xmalloc (1024 * 10);
8131 const char *my_name = IDENTIFIER_POINTER (CLASS_NAME (chain));
8132 tree ivar_decls = CLASS_RAW_IVARS (chain);
8133 tree nst_methods = CLASS_NST_METHODS (chain);
8134 tree cls_methods = CLASS_CLS_METHODS (chain);
8136 fprintf (fp, "\n@interface %s", my_name);
8138 /* CLASS_SUPER_NAME is used to store the superclass name for
8139 classes, and the category name for categories. */
8140 if (CLASS_SUPER_NAME (chain))
8142 const char *name = IDENTIFIER_POINTER (CLASS_SUPER_NAME (chain));
8144 if (TREE_CODE (chain) == CATEGORY_IMPLEMENTATION_TYPE
8145 || TREE_CODE (chain) == CATEGORY_INTERFACE_TYPE)
8147 fprintf (fp, " (%s)\n", name);
8151 fprintf (fp, " : %s\n", name);
8157 /* FIXME - the following doesn't seem to work at the moment. */
8160 fprintf (fp, "{\n");
8163 fprintf (fp, "\t%s;\n", gen_declaration (ivar_decls, buf));
8164 ivar_decls = TREE_CHAIN (ivar_decls);
8167 fprintf (fp, "}\n");
8172 fprintf (fp, "- %s;\n", gen_method_decl (nst_methods, buf));
8173 nst_methods = TREE_CHAIN (nst_methods);
8178 fprintf (fp, "+ %s;\n", gen_method_decl (cls_methods, buf));
8179 cls_methods = TREE_CHAIN (cls_methods);
8182 fprintf (fp, "@end\n");
8185 /* Demangle function for Objective-C */
8187 objc_demangle (mangled)
8188 const char *mangled;
8190 char *demangled, *cp;
8192 if (mangled[0] == '_' &&
8193 (mangled[1] == 'i' || mangled[1] == 'c') &&
8196 cp = demangled = xmalloc(strlen(mangled) + 2);
8197 if (mangled[1] == 'i')
8198 *cp++ = '-'; /* for instance method */
8200 *cp++ = '+'; /* for class method */
8201 *cp++ = '['; /* opening left brace */
8202 strcpy(cp, mangled+3); /* tack on the rest of the mangled name */
8203 while (*cp && *cp == '_')
8204 cp++; /* skip any initial underbars in class name */
8205 cp = strchr(cp, '_'); /* find first non-initial underbar */
8208 free(demangled); /* not mangled name */
8211 if (cp[1] == '_') /* easy case: no category name */
8213 *cp++ = ' '; /* replace two '_' with one ' ' */
8214 strcpy(cp, mangled + (cp - demangled) + 2);
8218 *cp++ = '('; /* less easy case: category name */
8219 cp = strchr(cp, '_');
8222 free(demangled); /* not mangled name */
8226 *cp++ = ' '; /* overwriting 1st char of method name... */
8227 strcpy(cp, mangled + (cp - demangled)); /* get it back */
8229 while (*cp && *cp == '_')
8230 cp++; /* skip any initial underbars in method name */
8233 *cp = ':'; /* replace remaining '_' with ':' */
8234 *cp++ = ']'; /* closing right brace */
8235 *cp++ = 0; /* string terminator */
8239 return mangled; /* not an objc mangled name */
8243 objc_printable_name (decl, kind)
8245 int kind ATTRIBUTE_UNUSED;
8247 return objc_demangle (IDENTIFIER_POINTER (DECL_NAME (decl)));
8253 gcc_obstack_init (&util_obstack);
8254 util_firstobj = (char *) obstack_finish (&util_obstack);
8256 errbuf = (char *) xmalloc (BUFSIZE);
8258 synth_module_prologue ();
8264 struct imp_entry *impent;
8266 /* The internally generated initializers appear to have missing braces.
8267 Don't warn about this. */
8268 int save_warn_missing_braces = warn_missing_braces;
8269 warn_missing_braces = 0;
8271 /* A missing @end may not be detected by the parser. */
8272 if (objc_implementation_context)
8274 warning ("`@end' missing in implementation context");
8275 finish_class (objc_implementation_context);
8276 objc_ivar_chain = NULL_TREE;
8277 objc_implementation_context = NULL_TREE;
8280 generate_forward_declaration_to_string_table ();
8282 #ifdef OBJC_PROLOGUE
8286 /* Process the static instances here because initialization of objc_symtab
8288 if (objc_static_instances)
8289 generate_static_references ();
8291 if (imp_list || class_names_chain
8292 || meth_var_names_chain || meth_var_types_chain || sel_ref_chain)
8293 generate_objc_symtab_decl ();
8295 for (impent = imp_list; impent; impent = impent->next)
8297 objc_implementation_context = impent->imp_context;
8298 implementation_template = impent->imp_template;
8300 UOBJC_CLASS_decl = impent->class_decl;
8301 UOBJC_METACLASS_decl = impent->meta_decl;
8303 /* Dump the @interface of each class as we compile it, if the
8304 -gen-decls option is in use. TODO: Dump the classes in the
8305 order they were found, rather than in reverse order as we
8307 if (flag_gen_declaration)
8309 dump_interface (gen_declaration_file, objc_implementation_context);
8312 if (TREE_CODE (objc_implementation_context) == CLASS_IMPLEMENTATION_TYPE)
8314 /* all of the following reference the string pool... */
8315 generate_ivar_lists ();
8316 generate_dispatch_tables ();
8317 generate_shared_structures ();
8321 generate_dispatch_tables ();
8322 generate_category (objc_implementation_context);
8326 /* If we are using an array of selectors, we must always
8327 finish up the array decl even if no selectors were used. */
8328 if (! flag_next_runtime || sel_ref_chain)
8329 build_selector_translation_table ();
8332 generate_protocols ();
8334 if (objc_implementation_context || class_names_chain || objc_static_instances
8335 || meth_var_names_chain || meth_var_types_chain || sel_ref_chain)
8337 /* Arrange for ObjC data structures to be initialized at run time. */
8338 rtx init_sym = build_module_descriptor ();
8339 if (init_sym && targetm.have_ctors_dtors)
8340 (* targetm.asm_out.constructor) (init_sym, DEFAULT_INIT_PRIORITY);
8343 /* Dump the class references. This forces the appropriate classes
8344 to be linked into the executable image, preserving unix archive
8345 semantics. This can be removed when we move to a more dynamically
8346 linked environment. */
8348 for (chain = cls_ref_chain; chain; chain = TREE_CHAIN (chain))
8350 handle_class_ref (chain);
8351 if (TREE_PURPOSE (chain))
8352 generate_classref_translation_entry (chain);
8355 for (impent = imp_list; impent; impent = impent->next)
8356 handle_impent (impent);
8358 /* Dump the string table last. */
8360 generate_strings ();
8367 /* Run through the selector hash tables and print a warning for any
8368 selector which has multiple methods. */
8370 for (slot = 0; slot < SIZEHASHTABLE; slot++)
8371 for (hsh = cls_method_hash_list[slot]; hsh; hsh = hsh->next)
8374 tree meth = hsh->key;
8375 char type = (TREE_CODE (meth) == INSTANCE_METHOD_DECL
8379 warning ("potential selector conflict for method `%s'",
8380 IDENTIFIER_POINTER (METHOD_SEL_NAME (meth)));
8381 warn_with_method ("found", type, meth);
8382 for (loop = hsh->list; loop; loop = loop->next)
8383 warn_with_method ("found", type, loop->value);
8386 for (slot = 0; slot < SIZEHASHTABLE; slot++)
8387 for (hsh = nst_method_hash_list[slot]; hsh; hsh = hsh->next)
8390 tree meth = hsh->key;
8391 char type = (TREE_CODE (meth) == INSTANCE_METHOD_DECL
8395 warning ("potential selector conflict for method `%s'",
8396 IDENTIFIER_POINTER (METHOD_SEL_NAME (meth)));
8397 warn_with_method ("found", type, meth);
8398 for (loop = hsh->list; loop; loop = loop->next)
8399 warn_with_method ("found", type, loop->value);
8403 warn_missing_braces = save_warn_missing_braces;
8406 /* Subroutines of finish_objc. */
8409 generate_classref_translation_entry (chain)
8412 tree expr, name, decl_specs, decl, sc_spec;
8415 type = TREE_TYPE (TREE_PURPOSE (chain));
8417 expr = add_objc_string (TREE_VALUE (chain), class_names);
8418 expr = build_c_cast (type, expr); /* cast! */
8420 name = DECL_NAME (TREE_PURPOSE (chain));
8422 sc_spec = build_tree_list (NULL_TREE, ridpointers[(int) RID_STATIC]);
8424 /* static struct objc_class * _OBJC_CLASS_REFERENCES_n = ...; */
8425 decl_specs = tree_cons (NULL_TREE, type, sc_spec);
8427 /* The decl that is returned from start_decl is the one that we
8428 forward declared in build_class_reference. */
8429 decl = start_decl (name, decl_specs, 1, NULL_TREE);
8430 DECL_CONTEXT (decl) = NULL_TREE;
8431 finish_decl (decl, expr, NULL_TREE);
8436 handle_class_ref (chain)
8439 const char *name = IDENTIFIER_POINTER (TREE_VALUE (chain));
8440 char *string = (char *) alloca (strlen (name) + 30);
8444 sprintf (string, "%sobjc_class_name_%s",
8445 (flag_next_runtime ? "." : "__"), name);
8447 #ifdef ASM_DECLARE_UNRESOLVED_REFERENCE
8448 if (flag_next_runtime)
8450 ASM_DECLARE_UNRESOLVED_REFERENCE (asm_out_file, string);
8455 /* Make a decl for this name, so we can use its address in a tree. */
8456 decl = build_decl (VAR_DECL, get_identifier (string), char_type_node);
8457 DECL_EXTERNAL (decl) = 1;
8458 TREE_PUBLIC (decl) = 1;
8461 rest_of_decl_compilation (decl, 0, 0, 0);
8463 /* Make a decl for the address. */
8464 sprintf (string, "%sobjc_class_ref_%s",
8465 (flag_next_runtime ? "." : "__"), name);
8466 exp = build1 (ADDR_EXPR, string_type_node, decl);
8467 decl = build_decl (VAR_DECL, get_identifier (string), string_type_node);
8468 DECL_INITIAL (decl) = exp;
8469 TREE_STATIC (decl) = 1;
8470 TREE_USED (decl) = 1;
8473 rest_of_decl_compilation (decl, 0, 0, 0);
8477 handle_impent (impent)
8478 struct imp_entry *impent;
8482 objc_implementation_context = impent->imp_context;
8483 implementation_template = impent->imp_template;
8485 if (TREE_CODE (impent->imp_context) == CLASS_IMPLEMENTATION_TYPE)
8487 const char *const class_name =
8488 IDENTIFIER_POINTER (CLASS_NAME (impent->imp_context));
8490 string = (char *) alloca (strlen (class_name) + 30);
8492 sprintf (string, "%sobjc_class_name_%s",
8493 (flag_next_runtime ? "." : "__"), class_name);
8495 else if (TREE_CODE (impent->imp_context) == CATEGORY_IMPLEMENTATION_TYPE)
8497 const char *const class_name =
8498 IDENTIFIER_POINTER (CLASS_NAME (impent->imp_context));
8499 const char *const class_super_name =
8500 IDENTIFIER_POINTER (CLASS_SUPER_NAME (impent->imp_context));
8502 string = (char *) alloca (strlen (class_name)
8503 + strlen (class_super_name) + 30);
8505 /* Do the same for categories. Even though no references to
8506 these symbols are generated automatically by the compiler, it
8507 gives you a handle to pull them into an archive by hand. */
8508 sprintf (string, "*%sobjc_category_name_%s_%s",
8509 (flag_next_runtime ? "." : "__"), class_name, class_super_name);
8514 #ifdef ASM_DECLARE_CLASS_REFERENCE
8515 if (flag_next_runtime)
8517 ASM_DECLARE_CLASS_REFERENCE (asm_out_file, string);
8525 init = build_int_2 (0, 0);
8526 TREE_TYPE (init) = c_common_type_for_size (BITS_PER_WORD, 1);
8527 decl = build_decl (VAR_DECL, get_identifier (string), TREE_TYPE (init));
8528 TREE_PUBLIC (decl) = 1;
8529 TREE_READONLY (decl) = 1;
8530 TREE_USED (decl) = 1;
8531 TREE_CONSTANT (decl) = 1;
8532 DECL_CONTEXT (decl) = 0;
8533 DECL_ARTIFICIAL (decl) = 1;
8534 DECL_INITIAL (decl) = init;
8535 assemble_variable (decl, 1, 0, 0);
8539 /* Look up ID as an instance variable. */
8541 lookup_objc_ivar (id)
8546 if (objc_method_context && !strcmp (IDENTIFIER_POINTER (id), "super"))
8547 /* We have a message to super. */
8548 return get_super_receiver ();
8549 else if (objc_method_context && (decl = is_ivar (objc_ivar_chain, id)))
8551 if (is_private (decl))
8552 return error_mark_node;
8554 return build_ivar_reference (id);
8560 #include "gt-objc-objc-act.h"
8561 #include "gtype-objc.h"