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 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 = build_constructor (constant_string_type, nreverse (initlist));
1351 if (!flag_next_runtime)
1354 = objc_add_static_instance (constructor, constant_string_type);
1357 return (build_unary_op (ADDR_EXPR, constructor, 1));
1360 /* Declare a static instance of CLASS_DECL initialized by CONSTRUCTOR. */
1362 static GTY(()) int num_static_inst;
1364 objc_add_static_instance (constructor, class_decl)
1365 tree constructor, class_decl;
1370 /* Find the list of static instances for the CLASS_DECL. Create one if
1372 for (chain = &objc_static_instances;
1373 *chain && TREE_VALUE (*chain) != class_decl;
1374 chain = &TREE_CHAIN (*chain));
1377 *chain = tree_cons (NULL_TREE, class_decl, NULL_TREE);
1378 add_objc_string (TYPE_NAME (class_decl), class_names);
1381 sprintf (buf, "_OBJC_INSTANCE_%d", num_static_inst++);
1382 decl = build_decl (VAR_DECL, get_identifier (buf), class_decl);
1383 DECL_COMMON (decl) = 1;
1384 TREE_STATIC (decl) = 1;
1385 DECL_ARTIFICIAL (decl) = 1;
1386 DECL_INITIAL (decl) = constructor;
1388 /* We may be writing something else just now.
1389 Postpone till end of input. */
1390 DECL_DEFER_OUTPUT (decl) = 1;
1391 pushdecl_top_level (decl);
1392 rest_of_decl_compilation (decl, 0, 1, 0);
1394 /* Add the DECL to the head of this CLASS' list. */
1395 TREE_PURPOSE (*chain) = tree_cons (NULL_TREE, decl, TREE_PURPOSE (*chain));
1400 /* Build a static constant CONSTRUCTOR
1401 with type TYPE and elements ELTS. */
1404 build_constructor (type, elts)
1407 tree constructor, f, e;
1409 /* ??? Most of the places that we build constructors, we don't fill in
1410 the type of integers properly. Convert them all en masse. */
1411 if (TREE_CODE (type) == ARRAY_TYPE)
1413 f = TREE_TYPE (type);
1414 if (TREE_CODE (f) == POINTER_TYPE || TREE_CODE (f) == INTEGER_TYPE)
1415 for (e = elts; e ; e = TREE_CHAIN (e))
1416 TREE_VALUE (e) = convert (f, TREE_VALUE (e));
1420 f = TYPE_FIELDS (type);
1421 for (e = elts; e && f; e = TREE_CHAIN (e), f = TREE_CHAIN (f))
1422 if (TREE_CODE (TREE_TYPE (f)) == POINTER_TYPE
1423 || TREE_CODE (TREE_TYPE (f)) == INTEGER_TYPE)
1424 TREE_VALUE (e) = convert (TREE_TYPE (f), TREE_VALUE (e));
1427 constructor = build (CONSTRUCTOR, type, NULL_TREE, elts);
1428 TREE_CONSTANT (constructor) = 1;
1429 TREE_STATIC (constructor) = 1;
1430 TREE_READONLY (constructor) = 1;
1435 /* Take care of defining and initializing _OBJC_SYMBOLS. */
1437 /* Predefine the following data type:
1445 void *defs[cls_def_cnt + cat_def_cnt];
1449 build_objc_symtab_template ()
1451 tree field_decl, field_decl_chain, index;
1453 objc_symtab_template
1454 = start_struct (RECORD_TYPE, get_identifier (UTAG_SYMTAB));
1456 /* long sel_ref_cnt; */
1458 field_decl = create_builtin_decl (FIELD_DECL,
1459 long_integer_type_node,
1461 field_decl_chain = field_decl;
1465 field_decl = create_builtin_decl (FIELD_DECL,
1466 build_pointer_type (selector_type),
1468 chainon (field_decl_chain, field_decl);
1470 /* short cls_def_cnt; */
1472 field_decl = create_builtin_decl (FIELD_DECL,
1473 short_integer_type_node,
1475 chainon (field_decl_chain, field_decl);
1477 /* short cat_def_cnt; */
1479 field_decl = create_builtin_decl (FIELD_DECL,
1480 short_integer_type_node,
1482 chainon (field_decl_chain, field_decl);
1484 /* void *defs[cls_def_cnt + cat_def_cnt]; */
1486 if (!flag_next_runtime)
1487 index = build_index_type (build_int_2 (imp_count + cat_count, 0));
1489 index = build_index_type (build_int_2 (imp_count + cat_count - 1,
1490 imp_count == 0 && cat_count == 0
1492 field_decl = create_builtin_decl (FIELD_DECL,
1493 build_array_type (ptr_type_node, index),
1495 chainon (field_decl_chain, field_decl);
1497 finish_struct (objc_symtab_template, field_decl_chain, NULL_TREE);
1500 /* Create the initial value for the `defs' field of _objc_symtab.
1501 This is a CONSTRUCTOR. */
1504 init_def_list (type)
1507 tree expr, initlist = NULL_TREE;
1508 struct imp_entry *impent;
1511 for (impent = imp_list; impent; impent = impent->next)
1513 if (TREE_CODE (impent->imp_context) == CLASS_IMPLEMENTATION_TYPE)
1515 expr = build_unary_op (ADDR_EXPR, impent->class_decl, 0);
1516 initlist = tree_cons (NULL_TREE, expr, initlist);
1521 for (impent = imp_list; impent; impent = impent->next)
1523 if (TREE_CODE (impent->imp_context) == CATEGORY_IMPLEMENTATION_TYPE)
1525 expr = build_unary_op (ADDR_EXPR, impent->class_decl, 0);
1526 initlist = tree_cons (NULL_TREE, expr, initlist);
1530 if (!flag_next_runtime)
1532 /* statics = { ..., _OBJC_STATIC_INSTANCES, ... } */
1535 if (static_instances_decl)
1536 expr = build_unary_op (ADDR_EXPR, static_instances_decl, 0);
1538 expr = build_int_2 (0, 0);
1540 initlist = tree_cons (NULL_TREE, expr, initlist);
1543 return build_constructor (type, nreverse (initlist));
1546 /* Construct the initial value for all of _objc_symtab. */
1549 init_objc_symtab (type)
1554 /* sel_ref_cnt = { ..., 5, ... } */
1556 initlist = build_tree_list (NULL_TREE, build_int_2 (0, 0));
1558 /* refs = { ..., _OBJC_SELECTOR_TABLE, ... } */
1560 if (flag_next_runtime || ! sel_ref_chain)
1561 initlist = tree_cons (NULL_TREE, build_int_2 (0, 0), initlist);
1563 initlist = tree_cons (NULL_TREE,
1564 build_unary_op (ADDR_EXPR,
1565 UOBJC_SELECTOR_TABLE_decl, 1),
1568 /* cls_def_cnt = { ..., 5, ... } */
1570 initlist = tree_cons (NULL_TREE, build_int_2 (imp_count, 0), initlist);
1572 /* cat_def_cnt = { ..., 5, ... } */
1574 initlist = tree_cons (NULL_TREE, build_int_2 (cat_count, 0), initlist);
1576 /* cls_def = { ..., { &Foo, &Bar, ...}, ... } */
1578 if (imp_count || cat_count || static_instances_decl)
1581 tree field = TYPE_FIELDS (type);
1582 field = TREE_CHAIN (TREE_CHAIN (TREE_CHAIN (TREE_CHAIN (field))));
1584 initlist = tree_cons (NULL_TREE, init_def_list (TREE_TYPE (field)),
1588 return build_constructor (type, nreverse (initlist));
1591 /* Push forward-declarations of all the categories so that
1592 init_def_list can use them in a CONSTRUCTOR. */
1595 forward_declare_categories ()
1597 struct imp_entry *impent;
1598 tree sav = objc_implementation_context;
1600 for (impent = imp_list; impent; impent = impent->next)
1602 if (TREE_CODE (impent->imp_context) == CATEGORY_IMPLEMENTATION_TYPE)
1604 /* Set an invisible arg to synth_id_with_class_suffix. */
1605 objc_implementation_context = impent->imp_context;
1607 = create_builtin_decl (VAR_DECL, objc_category_template,
1608 IDENTIFIER_POINTER (synth_id_with_class_suffix ("_OBJC_CATEGORY", objc_implementation_context)));
1611 objc_implementation_context = sav;
1614 /* Create the declaration of _OBJC_SYMBOLS, with type `strict _objc_symtab'
1615 and initialized appropriately. */
1618 generate_objc_symtab_decl ()
1622 if (!objc_category_template)
1623 build_category_template ();
1625 /* forward declare categories */
1627 forward_declare_categories ();
1629 if (!objc_symtab_template)
1630 build_objc_symtab_template ();
1632 sc_spec = build_tree_list (NULL_TREE, ridpointers[(int) RID_STATIC]);
1634 UOBJC_SYMBOLS_decl = start_decl (get_identifier ("_OBJC_SYMBOLS"),
1635 tree_cons (NULL_TREE,
1636 objc_symtab_template, sc_spec),
1640 TREE_USED (UOBJC_SYMBOLS_decl) = 1;
1641 DECL_IGNORED_P (UOBJC_SYMBOLS_decl) = 1;
1642 DECL_ARTIFICIAL (UOBJC_SYMBOLS_decl) = 1;
1643 finish_decl (UOBJC_SYMBOLS_decl,
1644 init_objc_symtab (TREE_TYPE (UOBJC_SYMBOLS_decl)),
1649 init_module_descriptor (type)
1652 tree initlist, expr;
1654 /* version = { 1, ... } */
1656 expr = build_int_2 (OBJC_VERSION, 0);
1657 initlist = build_tree_list (NULL_TREE, expr);
1659 /* size = { ..., sizeof (struct objc_module), ... } */
1661 expr = size_in_bytes (objc_module_template);
1662 initlist = tree_cons (NULL_TREE, expr, initlist);
1664 /* name = { ..., "foo.m", ... } */
1666 expr = add_objc_string (get_identifier (input_filename), class_names);
1667 initlist = tree_cons (NULL_TREE, expr, initlist);
1669 /* symtab = { ..., _OBJC_SYMBOLS, ... } */
1671 if (UOBJC_SYMBOLS_decl)
1672 expr = build_unary_op (ADDR_EXPR, UOBJC_SYMBOLS_decl, 0);
1674 expr = build_int_2 (0, 0);
1675 initlist = tree_cons (NULL_TREE, expr, initlist);
1677 return build_constructor (type, nreverse (initlist));
1680 /* Write out the data structures to describe Objective C classes defined.
1681 If appropriate, compile and output a setup function to initialize them.
1682 Return a symbol_ref to the function to call to initialize the Objective C
1683 data structures for this file (and perhaps for other files also).
1685 struct objc_module { ... } _OBJC_MODULE = { ... }; */
1688 build_module_descriptor ()
1690 tree decl_specs, field_decl, field_decl_chain;
1692 objc_module_template
1693 = start_struct (RECORD_TYPE, get_identifier (UTAG_MODULE));
1697 decl_specs = build_tree_list (NULL_TREE, ridpointers[(int) RID_LONG]);
1698 field_decl = get_identifier ("version");
1700 = grokfield (input_filename, lineno, field_decl, decl_specs, NULL_TREE);
1701 field_decl_chain = field_decl;
1705 decl_specs = build_tree_list (NULL_TREE, ridpointers[(int) RID_LONG]);
1706 field_decl = get_identifier ("size");
1708 = grokfield (input_filename, lineno, field_decl, decl_specs, NULL_TREE);
1709 chainon (field_decl_chain, field_decl);
1713 decl_specs = build_tree_list (NULL_TREE, ridpointers[(int) RID_CHAR]);
1714 field_decl = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("name"));
1716 = grokfield (input_filename, lineno, field_decl, decl_specs, NULL_TREE);
1717 chainon (field_decl_chain, field_decl);
1719 /* struct objc_symtab *symtab; */
1721 decl_specs = get_identifier (UTAG_SYMTAB);
1722 decl_specs = build_tree_list (NULL_TREE, xref_tag (RECORD_TYPE, decl_specs));
1723 field_decl = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("symtab"));
1725 = grokfield (input_filename, lineno, field_decl, decl_specs, NULL_TREE);
1726 chainon (field_decl_chain, field_decl);
1728 finish_struct (objc_module_template, field_decl_chain, NULL_TREE);
1730 /* Create an instance of "objc_module". */
1732 decl_specs = tree_cons (NULL_TREE, objc_module_template,
1733 build_tree_list (NULL_TREE,
1734 ridpointers[(int) RID_STATIC]));
1736 UOBJC_MODULES_decl = start_decl (get_identifier ("_OBJC_MODULES"),
1737 decl_specs, 1, NULL_TREE);
1739 DECL_ARTIFICIAL (UOBJC_MODULES_decl) = 1;
1740 DECL_IGNORED_P (UOBJC_MODULES_decl) = 1;
1741 DECL_CONTEXT (UOBJC_MODULES_decl) = NULL_TREE;
1743 finish_decl (UOBJC_MODULES_decl,
1744 init_module_descriptor (TREE_TYPE (UOBJC_MODULES_decl)),
1747 /* Mark the decl to avoid "defined but not used" warning. */
1748 DECL_IN_SYSTEM_HEADER (UOBJC_MODULES_decl) = 1;
1750 /* Generate a constructor call for the module descriptor.
1751 This code was generated by reading the grammar rules
1752 of c-parse.in; Therefore, it may not be the most efficient
1753 way of generating the requisite code. */
1755 if (flag_next_runtime)
1759 tree parms, execclass_decl, decelerator, void_list_node_1;
1760 tree init_function_name, init_function_decl;
1762 /* Declare void __objc_execClass (void *); */
1764 void_list_node_1 = build_tree_list (NULL_TREE, void_type_node);
1765 execclass_decl = build_decl (FUNCTION_DECL,
1766 get_identifier (TAG_EXECCLASS),
1767 build_function_type (void_type_node,
1768 tree_cons (NULL_TREE, ptr_type_node,
1769 void_list_node_1)));
1770 DECL_EXTERNAL (execclass_decl) = 1;
1771 DECL_ARTIFICIAL (execclass_decl) = 1;
1772 TREE_PUBLIC (execclass_decl) = 1;
1773 pushdecl (execclass_decl);
1774 rest_of_decl_compilation (execclass_decl, 0, 0, 0);
1775 assemble_external (execclass_decl);
1777 /* void _GLOBAL_$I$<gnyf> () {objc_execClass (&L_OBJC_MODULES);} */
1779 init_function_name = get_file_function_name ('I');
1780 start_function (void_list_node_1,
1781 build_nt (CALL_EXPR, init_function_name,
1782 tree_cons (NULL_TREE, NULL_TREE,
1786 store_parm_decls ();
1788 init_function_decl = current_function_decl;
1789 TREE_PUBLIC (init_function_decl) = ! targetm.have_ctors_dtors;
1790 TREE_USED (init_function_decl) = 1;
1791 /* Don't let this one be deferred. */
1792 DECL_INLINE (init_function_decl) = 0;
1793 DECL_UNINLINABLE (init_function_decl) = 1;
1794 current_function_cannot_inline
1795 = "static constructors and destructors cannot be inlined";
1798 = build_tree_list (NULL_TREE,
1799 build_unary_op (ADDR_EXPR, UOBJC_MODULES_decl, 0));
1800 decelerator = build_function_call (execclass_decl, parms);
1802 c_expand_expr_stmt (decelerator);
1804 finish_function (0, 0);
1806 return XEXP (DECL_RTL (init_function_decl), 0);
1810 /* extern const char _OBJC_STRINGS[]; */
1813 generate_forward_declaration_to_string_table ()
1815 tree sc_spec, decl_specs, expr_decl;
1817 sc_spec = tree_cons (NULL_TREE, ridpointers[(int) RID_EXTERN], NULL_TREE);
1818 decl_specs = tree_cons (NULL_TREE, ridpointers[(int) RID_CHAR], sc_spec);
1821 = build_nt (ARRAY_REF, get_identifier ("_OBJC_STRINGS"), NULL_TREE);
1823 UOBJC_STRINGS_decl = define_decl (expr_decl, decl_specs);
1826 /* Return the DECL of the string IDENT in the SECTION. */
1829 get_objc_string_decl (ident, section)
1831 enum string_section section;
1835 if (section == class_names)
1836 chain = class_names_chain;
1837 else if (section == meth_var_names)
1838 chain = meth_var_names_chain;
1839 else if (section == meth_var_types)
1840 chain = meth_var_types_chain;
1844 for (; chain != 0; chain = TREE_CHAIN (chain))
1845 if (TREE_VALUE (chain) == ident)
1846 return (TREE_PURPOSE (chain));
1852 /* Output references to all statically allocated objects. Return the DECL
1853 for the array built. */
1856 generate_static_references ()
1858 tree decls = NULL_TREE, ident, decl_spec, expr_decl, expr = NULL_TREE;
1859 tree class_name, class, decl, initlist;
1860 tree cl_chain, in_chain, type;
1861 int num_inst, num_class;
1864 if (flag_next_runtime)
1867 for (cl_chain = objc_static_instances, num_class = 0;
1868 cl_chain; cl_chain = TREE_CHAIN (cl_chain), num_class++)
1870 for (num_inst = 0, in_chain = TREE_PURPOSE (cl_chain);
1871 in_chain; num_inst++, in_chain = TREE_CHAIN (in_chain));
1873 sprintf (buf, "_OBJC_STATIC_INSTANCES_%d", num_class);
1874 ident = get_identifier (buf);
1876 expr_decl = build_nt (ARRAY_REF, ident, NULL_TREE);
1877 decl_spec = tree_cons (NULL_TREE, build_pointer_type (void_type_node),
1878 build_tree_list (NULL_TREE,
1879 ridpointers[(int) RID_STATIC]));
1880 decl = start_decl (expr_decl, decl_spec, 1, NULL_TREE);
1881 DECL_CONTEXT (decl) = 0;
1882 DECL_ARTIFICIAL (decl) = 1;
1884 /* Output {class_name, ...}. */
1885 class = TREE_VALUE (cl_chain);
1886 class_name = get_objc_string_decl (TYPE_NAME (class), class_names);
1887 initlist = build_tree_list (NULL_TREE,
1888 build_unary_op (ADDR_EXPR, class_name, 1));
1890 /* Output {..., instance, ...}. */
1891 for (in_chain = TREE_PURPOSE (cl_chain);
1892 in_chain; in_chain = TREE_CHAIN (in_chain))
1894 expr = build_unary_op (ADDR_EXPR, TREE_VALUE (in_chain), 1);
1895 initlist = tree_cons (NULL_TREE, expr, initlist);
1898 /* Output {..., NULL}. */
1899 initlist = tree_cons (NULL_TREE, build_int_2 (0, 0), initlist);
1901 expr = build_constructor (TREE_TYPE (decl), nreverse (initlist));
1902 finish_decl (decl, expr, NULL_TREE);
1903 TREE_USED (decl) = 1;
1905 type = build_array_type (build_pointer_type (void_type_node), 0);
1906 decl = build_decl (VAR_DECL, ident, type);
1907 TREE_USED (decl) = 1;
1908 TREE_STATIC (decl) = 1;
1910 = tree_cons (NULL_TREE, build_unary_op (ADDR_EXPR, decl, 1), decls);
1913 decls = tree_cons (NULL_TREE, build_int_2 (0, 0), decls);
1914 ident = get_identifier ("_OBJC_STATIC_INSTANCES");
1915 expr_decl = build_nt (ARRAY_REF, ident, NULL_TREE);
1916 decl_spec = tree_cons (NULL_TREE, build_pointer_type (void_type_node),
1917 build_tree_list (NULL_TREE,
1918 ridpointers[(int) RID_STATIC]));
1919 static_instances_decl
1920 = start_decl (expr_decl, decl_spec, 1, NULL_TREE);
1921 TREE_USED (static_instances_decl) = 1;
1922 DECL_CONTEXT (static_instances_decl) = 0;
1923 DECL_ARTIFICIAL (static_instances_decl) = 1;
1924 expr = build_constructor (TREE_TYPE (static_instances_decl),
1926 finish_decl (static_instances_decl, expr, NULL_TREE);
1929 /* Output all strings. */
1934 tree sc_spec, decl_specs, expr_decl;
1935 tree chain, string_expr;
1938 for (chain = class_names_chain; chain; chain = TREE_CHAIN (chain))
1940 string = TREE_VALUE (chain);
1941 decl = TREE_PURPOSE (chain);
1943 = tree_cons (NULL_TREE, ridpointers[(int) RID_STATIC], NULL_TREE);
1944 decl_specs = tree_cons (NULL_TREE, ridpointers[(int) RID_CHAR], sc_spec);
1945 expr_decl = build_nt (ARRAY_REF, DECL_NAME (decl), NULL_TREE);
1946 decl = start_decl (expr_decl, decl_specs, 1, NULL_TREE);
1947 DECL_CONTEXT (decl) = NULL_TREE;
1948 string_expr = my_build_string (IDENTIFIER_LENGTH (string) + 1,
1949 IDENTIFIER_POINTER (string));
1950 finish_decl (decl, string_expr, NULL_TREE);
1953 for (chain = meth_var_names_chain; chain; chain = TREE_CHAIN (chain))
1955 string = TREE_VALUE (chain);
1956 decl = TREE_PURPOSE (chain);
1958 = tree_cons (NULL_TREE, ridpointers[(int) RID_STATIC], NULL_TREE);
1959 decl_specs = tree_cons (NULL_TREE, ridpointers[(int) RID_CHAR], sc_spec);
1960 expr_decl = build_nt (ARRAY_REF, DECL_NAME (decl), NULL_TREE);
1961 decl = start_decl (expr_decl, decl_specs, 1, NULL_TREE);
1962 DECL_CONTEXT (decl) = NULL_TREE;
1963 string_expr = my_build_string (IDENTIFIER_LENGTH (string) + 1,
1964 IDENTIFIER_POINTER (string));
1965 finish_decl (decl, string_expr, NULL_TREE);
1968 for (chain = meth_var_types_chain; chain; chain = TREE_CHAIN (chain))
1970 string = TREE_VALUE (chain);
1971 decl = TREE_PURPOSE (chain);
1973 = tree_cons (NULL_TREE, ridpointers[(int) RID_STATIC], NULL_TREE);
1974 decl_specs = tree_cons (NULL_TREE, ridpointers[(int) RID_CHAR], sc_spec);
1975 expr_decl = build_nt (ARRAY_REF, DECL_NAME (decl), NULL_TREE);
1976 decl = start_decl (expr_decl, decl_specs, 1, NULL_TREE);
1977 DECL_CONTEXT (decl) = NULL_TREE;
1978 string_expr = my_build_string (IDENTIFIER_LENGTH (string) + 1,
1979 IDENTIFIER_POINTER (string));
1980 finish_decl (decl, string_expr, NULL_TREE);
1984 static GTY(()) int selector_reference_idx;
1986 build_selector_reference_decl ()
1991 sprintf (buf, "_OBJC_SELECTOR_REFERENCES_%d", selector_reference_idx++);
1993 ident = get_identifier (buf);
1995 decl = build_decl (VAR_DECL, ident, selector_type);
1996 DECL_EXTERNAL (decl) = 1;
1997 TREE_PUBLIC (decl) = 1;
1998 TREE_USED (decl) = 1;
1999 TREE_READONLY (decl) = 1;
2000 DECL_ARTIFICIAL (decl) = 1;
2001 DECL_CONTEXT (decl) = 0;
2003 make_decl_rtl (decl, 0);
2004 pushdecl_top_level (decl);
2009 /* Just a handy wrapper for add_objc_string. */
2012 build_selector (ident)
2015 tree expr = add_objc_string (ident, meth_var_names);
2016 if (flag_typed_selectors)
2019 return build_c_cast (selector_type, expr); /* cast! */
2023 build_selector_translation_table ()
2025 tree sc_spec, decl_specs;
2026 tree chain, initlist = NULL_TREE;
2028 tree decl = NULL_TREE, var_decl, name;
2030 for (chain = sel_ref_chain; chain; chain = TREE_CHAIN (chain))
2034 if (warn_selector && objc_implementation_context)
2038 for (method_chain = meth_var_names_chain;
2040 method_chain = TREE_CHAIN (method_chain))
2042 if (TREE_VALUE (method_chain) == TREE_VALUE (chain))
2050 /* Adjust line number for warning message. */
2051 int save_lineno = lineno;
2052 if (flag_next_runtime && TREE_PURPOSE (chain))
2053 lineno = DECL_SOURCE_LINE (TREE_PURPOSE (chain));
2054 warning ("creating selector for non existant method %s",
2055 IDENTIFIER_POINTER (TREE_VALUE (chain)));
2056 lineno = save_lineno;
2060 expr = build_selector (TREE_VALUE (chain));
2062 if (flag_next_runtime)
2064 name = DECL_NAME (TREE_PURPOSE (chain));
2066 sc_spec = build_tree_list (NULL_TREE, ridpointers[(int) RID_STATIC]);
2068 /* static SEL _OBJC_SELECTOR_REFERENCES_n = ...; */
2069 decl_specs = tree_cons (NULL_TREE, selector_type, sc_spec);
2073 /* The `decl' that is returned from start_decl is the one that we
2074 forward declared in `build_selector_reference' */
2075 decl = start_decl (var_decl, decl_specs, 1, NULL_TREE );
2078 /* add one for the '\0' character */
2079 offset += IDENTIFIER_LENGTH (TREE_VALUE (chain)) + 1;
2081 if (flag_next_runtime)
2082 finish_decl (decl, expr, NULL_TREE);
2085 if (flag_typed_selectors)
2087 tree eltlist = NULL_TREE;
2088 tree encoding = get_proto_encoding (TREE_PURPOSE (chain));
2089 eltlist = tree_cons (NULL_TREE, expr, NULL_TREE);
2090 eltlist = tree_cons (NULL_TREE, encoding, eltlist);
2091 expr = build_constructor (objc_selector_template,
2092 nreverse (eltlist));
2094 initlist = tree_cons (NULL_TREE, expr, initlist);
2099 if (! flag_next_runtime)
2101 /* Cause the variable and its initial value to be actually output. */
2102 DECL_EXTERNAL (UOBJC_SELECTOR_TABLE_decl) = 0;
2103 TREE_STATIC (UOBJC_SELECTOR_TABLE_decl) = 1;
2104 /* NULL terminate the list and fix the decl for output. */
2105 initlist = tree_cons (NULL_TREE, build_int_2 (0, 0), initlist);
2106 DECL_INITIAL (UOBJC_SELECTOR_TABLE_decl) = objc_ellipsis_node;
2107 initlist = build_constructor (TREE_TYPE (UOBJC_SELECTOR_TABLE_decl),
2108 nreverse (initlist));
2109 finish_decl (UOBJC_SELECTOR_TABLE_decl, initlist, NULL_TREE);
2110 current_function_decl = NULL_TREE;
2115 get_proto_encoding (proto)
2123 if (! METHOD_ENCODING (proto))
2125 tmp_decl = build_tmp_function_decl ();
2126 hack_method_prototype (proto, tmp_decl);
2127 encoding = encode_method_prototype (proto, tmp_decl);
2128 METHOD_ENCODING (proto) = encoding;
2131 encoding = METHOD_ENCODING (proto);
2133 return add_objc_string (encoding, meth_var_types);
2136 return build_int_2 (0, 0);
2139 /* sel_ref_chain is a list whose "value" fields will be instances of
2140 identifier_node that represent the selector. */
2143 build_typed_selector_reference (ident, prototype)
2144 tree ident, prototype;
2146 tree *chain = &sel_ref_chain;
2152 if (TREE_PURPOSE (*chain) == prototype && TREE_VALUE (*chain) == ident)
2153 goto return_at_index;
2156 chain = &TREE_CHAIN (*chain);
2159 *chain = tree_cons (prototype, ident, NULL_TREE);
2162 expr = build_unary_op (ADDR_EXPR,
2163 build_array_ref (UOBJC_SELECTOR_TABLE_decl,
2164 build_int_2 (index, 0)),
2166 return build_c_cast (selector_type, expr);
2170 build_selector_reference (ident)
2173 tree *chain = &sel_ref_chain;
2179 if (TREE_VALUE (*chain) == ident)
2180 return (flag_next_runtime
2181 ? TREE_PURPOSE (*chain)
2182 : build_array_ref (UOBJC_SELECTOR_TABLE_decl,
2183 build_int_2 (index, 0)));
2186 chain = &TREE_CHAIN (*chain);
2189 expr = build_selector_reference_decl ();
2191 *chain = tree_cons (expr, ident, NULL_TREE);
2193 return (flag_next_runtime
2195 : build_array_ref (UOBJC_SELECTOR_TABLE_decl,
2196 build_int_2 (index, 0)));
2199 static GTY(()) int class_reference_idx;
2201 build_class_reference_decl ()
2206 sprintf (buf, "_OBJC_CLASS_REFERENCES_%d", class_reference_idx++);
2208 ident = get_identifier (buf);
2210 decl = build_decl (VAR_DECL, ident, objc_class_type);
2211 DECL_EXTERNAL (decl) = 1;
2212 TREE_PUBLIC (decl) = 1;
2213 TREE_USED (decl) = 1;
2214 TREE_READONLY (decl) = 1;
2215 DECL_CONTEXT (decl) = 0;
2216 DECL_ARTIFICIAL (decl) = 1;
2218 make_decl_rtl (decl, 0);
2219 pushdecl_top_level (decl);
2224 /* Create a class reference, but don't create a variable to reference
2228 add_class_reference (ident)
2233 if ((chain = cls_ref_chain))
2238 if (ident == TREE_VALUE (chain))
2242 chain = TREE_CHAIN (chain);
2246 /* Append to the end of the list */
2247 TREE_CHAIN (tail) = tree_cons (NULL_TREE, ident, NULL_TREE);
2250 cls_ref_chain = tree_cons (NULL_TREE, ident, NULL_TREE);
2253 /* Get a class reference, creating it if necessary. Also create the
2254 reference variable. */
2257 get_class_reference (ident)
2260 if (flag_next_runtime)
2265 for (chain = &cls_ref_chain; *chain; chain = &TREE_CHAIN (*chain))
2266 if (TREE_VALUE (*chain) == ident)
2268 if (! TREE_PURPOSE (*chain))
2269 TREE_PURPOSE (*chain) = build_class_reference_decl ();
2271 return TREE_PURPOSE (*chain);
2274 decl = build_class_reference_decl ();
2275 *chain = tree_cons (decl, ident, NULL_TREE);
2282 add_class_reference (ident);
2284 params = build_tree_list (NULL_TREE,
2285 my_build_string (IDENTIFIER_LENGTH (ident) + 1,
2286 IDENTIFIER_POINTER (ident)));
2288 assemble_external (objc_get_class_decl);
2289 return build_function_call (objc_get_class_decl, params);
2293 /* For each string section we have a chain which maps identifier nodes
2294 to decls for the strings. */
2297 add_objc_string (ident, section)
2299 enum string_section section;
2303 if (section == class_names)
2304 chain = &class_names_chain;
2305 else if (section == meth_var_names)
2306 chain = &meth_var_names_chain;
2307 else if (section == meth_var_types)
2308 chain = &meth_var_types_chain;
2314 if (TREE_VALUE (*chain) == ident)
2315 return build_unary_op (ADDR_EXPR, TREE_PURPOSE (*chain), 1);
2317 chain = &TREE_CHAIN (*chain);
2320 decl = build_objc_string_decl (section);
2322 *chain = tree_cons (decl, ident, NULL_TREE);
2324 return build_unary_op (ADDR_EXPR, decl, 1);
2327 static GTY(()) int class_names_idx;
2328 static GTY(()) int meth_var_names_idx;
2329 static GTY(()) int meth_var_types_idx;
2332 build_objc_string_decl (section)
2333 enum string_section section;
2338 if (section == class_names)
2339 sprintf (buf, "_OBJC_CLASS_NAME_%d", class_names_idx++);
2340 else if (section == meth_var_names)
2341 sprintf (buf, "_OBJC_METH_VAR_NAME_%d", meth_var_names_idx++);
2342 else if (section == meth_var_types)
2343 sprintf (buf, "_OBJC_METH_VAR_TYPE_%d", meth_var_types_idx++);
2345 ident = get_identifier (buf);
2347 decl = build_decl (VAR_DECL, ident, build_array_type (char_type_node, 0));
2348 DECL_EXTERNAL (decl) = 1;
2349 TREE_PUBLIC (decl) = 1;
2350 TREE_USED (decl) = 1;
2351 TREE_READONLY (decl) = 1;
2352 TREE_CONSTANT (decl) = 1;
2353 DECL_CONTEXT (decl) = 0;
2354 DECL_ARTIFICIAL (decl) = 1;
2356 make_decl_rtl (decl, 0);
2357 pushdecl_top_level (decl);
2364 objc_declare_alias (alias_ident, class_ident)
2368 if (is_class_name (class_ident) != class_ident)
2369 warning ("cannot find class `%s'", IDENTIFIER_POINTER (class_ident));
2370 else if (is_class_name (alias_ident))
2371 warning ("class `%s' already exists", IDENTIFIER_POINTER (alias_ident));
2373 alias_chain = tree_cons (class_ident, alias_ident, alias_chain);
2377 objc_declare_class (ident_list)
2382 for (list = ident_list; list; list = TREE_CHAIN (list))
2384 tree ident = TREE_VALUE (list);
2387 if ((decl = lookup_name (ident)))
2389 error ("`%s' redeclared as different kind of symbol",
2390 IDENTIFIER_POINTER (ident));
2391 error_with_decl (decl, "previous declaration of `%s'");
2394 if (! is_class_name (ident))
2396 tree record = xref_tag (RECORD_TYPE, ident);
2397 TREE_STATIC_TEMPLATE (record) = 1;
2398 class_chain = tree_cons (NULL_TREE, ident, class_chain);
2404 is_class_name (ident)
2409 if (lookup_interface (ident))
2412 for (chain = class_chain; chain; chain = TREE_CHAIN (chain))
2414 if (ident == TREE_VALUE (chain))
2418 for (chain = alias_chain; chain; chain = TREE_CHAIN (chain))
2420 if (ident == TREE_VALUE (chain))
2421 return TREE_PURPOSE (chain);
2431 /* NB: This function may be called before the ObjC front-end
2432 has been initialized, in which case ID_TYPE will be NULL. */
2433 return (id_type && ident && TYPE_P (ident) && IS_ID (ident))
2439 lookup_interface (ident)
2444 for (chain = interface_chain; chain; chain = TREE_CHAIN (chain))
2446 if (ident == CLASS_NAME (chain))
2452 /* Used by: build_private_template, continue_class,
2453 and for @defs constructs. */
2456 get_class_ivars (interface)
2459 tree my_name, super_name, ivar_chain;
2461 my_name = CLASS_NAME (interface);
2462 super_name = CLASS_SUPER_NAME (interface);
2463 ivar_chain = CLASS_IVARS (interface);
2465 /* Save off a pristine copy of the leaf ivars (i.e, those not
2466 inherited from a super class). */
2467 if (!CLASS_OWN_IVARS (interface))
2468 CLASS_OWN_IVARS (interface) = copy_list (ivar_chain);
2473 tree super_interface = lookup_interface (super_name);
2475 if (!super_interface)
2477 /* fatal did not work with 2 args...should fix */
2478 error ("cannot find interface declaration for `%s', superclass of `%s'",
2479 IDENTIFIER_POINTER (super_name),
2480 IDENTIFIER_POINTER (my_name));
2481 exit (FATAL_EXIT_CODE);
2484 if (super_interface == interface)
2485 fatal_error ("circular inheritance in interface declaration for `%s'",
2486 IDENTIFIER_POINTER (super_name));
2488 interface = super_interface;
2489 my_name = CLASS_NAME (interface);
2490 super_name = CLASS_SUPER_NAME (interface);
2492 op1 = CLASS_OWN_IVARS (interface);
2495 tree head = copy_list (op1);
2497 /* Prepend super class ivars...make a copy of the list, we
2498 do not want to alter the original. */
2499 chainon (head, ivar_chain);
2506 /* struct <classname> {
2507 struct objc_class *isa;
2512 build_private_template (class)
2517 if (CLASS_STATIC_TEMPLATE (class))
2519 uprivate_record = CLASS_STATIC_TEMPLATE (class);
2520 ivar_context = TYPE_FIELDS (CLASS_STATIC_TEMPLATE (class));
2524 uprivate_record = start_struct (RECORD_TYPE, CLASS_NAME (class));
2526 ivar_context = get_class_ivars (class);
2528 finish_struct (uprivate_record, ivar_context, NULL_TREE);
2530 CLASS_STATIC_TEMPLATE (class) = uprivate_record;
2532 /* mark this record as class template - for class type checking */
2533 TREE_STATIC_TEMPLATE (uprivate_record) = 1;
2537 = groktypename (build_tree_list (build_tree_list (NULL_TREE,
2539 build1 (INDIRECT_REF, NULL_TREE,
2542 return ivar_context;
2545 /* Begin code generation for protocols... */
2547 /* struct objc_protocol {
2548 char *protocol_name;
2549 struct objc_protocol **protocol_list;
2550 struct objc_method_desc *instance_methods;
2551 struct objc_method_desc *class_methods;
2555 build_protocol_template ()
2557 tree decl_specs, field_decl, field_decl_chain;
2560 template = start_struct (RECORD_TYPE, get_identifier (UTAG_PROTOCOL));
2562 /* struct objc_class *isa; */
2564 decl_specs = build_tree_list (NULL_TREE, xref_tag (RECORD_TYPE,
2565 get_identifier (UTAG_CLASS)));
2566 field_decl = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("isa"));
2568 = grokfield (input_filename, lineno, field_decl, decl_specs, NULL_TREE);
2569 field_decl_chain = field_decl;
2571 /* char *protocol_name; */
2573 decl_specs = build_tree_list (NULL_TREE, ridpointers[(int) RID_CHAR]);
2575 = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("protocol_name"));
2577 = grokfield (input_filename, lineno, field_decl, decl_specs, NULL_TREE);
2578 chainon (field_decl_chain, field_decl);
2580 /* struct objc_protocol **protocol_list; */
2582 decl_specs = build_tree_list (NULL_TREE, template);
2584 = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("protocol_list"));
2585 field_decl = build1 (INDIRECT_REF, NULL_TREE, field_decl);
2587 = grokfield (input_filename, lineno, field_decl, decl_specs, NULL_TREE);
2588 chainon (field_decl_chain, field_decl);
2590 /* struct objc_method_list *instance_methods; */
2593 = build_tree_list (NULL_TREE,
2594 xref_tag (RECORD_TYPE,
2595 get_identifier (UTAG_METHOD_PROTOTYPE_LIST)));
2597 = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("instance_methods"));
2599 = grokfield (input_filename, lineno, field_decl, decl_specs, NULL_TREE);
2600 chainon (field_decl_chain, field_decl);
2602 /* struct objc_method_list *class_methods; */
2605 = build_tree_list (NULL_TREE,
2606 xref_tag (RECORD_TYPE,
2607 get_identifier (UTAG_METHOD_PROTOTYPE_LIST)));
2609 = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("class_methods"));
2611 = grokfield (input_filename, lineno, field_decl, decl_specs, NULL_TREE);
2612 chainon (field_decl_chain, field_decl);
2614 return finish_struct (template, field_decl_chain, NULL_TREE);
2618 build_descriptor_table_initializer (type, entries)
2622 tree initlist = NULL_TREE;
2626 tree eltlist = NULL_TREE;
2629 = tree_cons (NULL_TREE,
2630 build_selector (METHOD_SEL_NAME (entries)), NULL_TREE);
2632 = tree_cons (NULL_TREE,
2633 add_objc_string (METHOD_ENCODING (entries),
2638 = tree_cons (NULL_TREE,
2639 build_constructor (type, nreverse (eltlist)), initlist);
2641 entries = TREE_CHAIN (entries);
2645 return build_constructor (build_array_type (type, 0), nreverse (initlist));
2648 /* struct objc_method_prototype_list {
2650 struct objc_method_prototype {
2657 build_method_prototype_list_template (list_type, size)
2661 tree objc_ivar_list_record;
2662 tree decl_specs, field_decl, field_decl_chain;
2664 /* Generate an unnamed struct definition. */
2666 objc_ivar_list_record = start_struct (RECORD_TYPE, NULL_TREE);
2668 /* int method_count; */
2670 decl_specs = build_tree_list (NULL_TREE, ridpointers[(int) RID_INT]);
2671 field_decl = get_identifier ("method_count");
2674 = grokfield (input_filename, lineno, field_decl, decl_specs, NULL_TREE);
2675 field_decl_chain = field_decl;
2677 /* struct objc_method method_list[]; */
2679 decl_specs = build_tree_list (NULL_TREE, list_type);
2680 field_decl = build_nt (ARRAY_REF, get_identifier ("method_list"),
2681 build_int_2 (size, 0));
2684 = grokfield (input_filename, lineno, field_decl, decl_specs, NULL_TREE);
2685 chainon (field_decl_chain, field_decl);
2687 finish_struct (objc_ivar_list_record, field_decl_chain, NULL_TREE);
2689 return objc_ivar_list_record;
2693 build_method_prototype_template ()
2696 tree decl_specs, field_decl, field_decl_chain;
2699 = start_struct (RECORD_TYPE, get_identifier (UTAG_METHOD_PROTOTYPE));
2701 /* struct objc_selector *_cmd; */
2702 decl_specs = tree_cons (NULL_TREE, xref_tag (RECORD_TYPE,
2703 get_identifier (TAG_SELECTOR)), NULL_TREE);
2704 field_decl = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("_cmd"));
2707 = grokfield (input_filename, lineno, 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"));
2714 = grokfield (input_filename, lineno, 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, 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 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"));
3250 = grokfield (input_filename, lineno, 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"));
3258 = grokfield (input_filename, lineno, 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"));
3269 = grokfield (input_filename, lineno, 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"));
3280 = grokfield (input_filename, lineno, 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);
3292 = grokfield (input_filename, lineno, 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"));
3317 = grokfield (input_filename, lineno, 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"));
3325 = grokfield (input_filename, lineno, 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"));
3364 = grokfield (input_filename, lineno, 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"));
3373 = grokfield (input_filename, lineno, 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"));
3381 = grokfield (input_filename, lineno, 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");
3389 = grokfield (input_filename, lineno, 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");
3397 = grokfield (input_filename, lineno, 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");
3405 = grokfield (input_filename, lineno, 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"));
3415 = grokfield (input_filename, lineno, 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"));
3425 = grokfield (input_filename, lineno, 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, lineno, 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, lineno, 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, lineno, 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, lineno, 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, lineno, 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"));
3489 = grokfield (input_filename, lineno, 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"));
3497 = grokfield (input_filename, lineno, 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_with_file_and_line (DECL_SOURCE_FILE (decl),
3547 DECL_SOURCE_LINE (decl),
3549 message, gen_declaration (rawdecl, errbuf));
3554 check_ivars (inter, imp)
3558 tree intdecls = CLASS_IVARS (inter);
3559 tree impdecls = CLASS_IVARS (imp);
3560 tree rawintdecls = CLASS_RAW_IVARS (inter);
3561 tree rawimpdecls = CLASS_RAW_IVARS (imp);
3567 if (intdecls == 0 && impdecls == 0)
3569 if (intdecls == 0 || impdecls == 0)
3571 error ("inconsistent instance variable specification");
3575 t1 = TREE_TYPE (intdecls); t2 = TREE_TYPE (impdecls);
3577 if (!comptypes (t1, t2))
3579 if (DECL_NAME (intdecls) == DECL_NAME (impdecls))
3581 error_with_ivar ("conflicting instance variable type",
3582 impdecls, rawimpdecls);
3583 error_with_ivar ("previous declaration of",
3584 intdecls, rawintdecls);
3586 else /* both the type and the name don't match */
3588 error ("inconsistent instance variable specification");
3593 else if (DECL_NAME (intdecls) != DECL_NAME (impdecls))
3595 error_with_ivar ("conflicting instance variable name",
3596 impdecls, rawimpdecls);
3597 error_with_ivar ("previous declaration of",
3598 intdecls, rawintdecls);
3601 intdecls = TREE_CHAIN (intdecls);
3602 impdecls = TREE_CHAIN (impdecls);
3603 rawintdecls = TREE_CHAIN (rawintdecls);
3604 rawimpdecls = TREE_CHAIN (rawimpdecls);
3608 /* Set super_type to the data type node for struct objc_super *,
3609 first defining struct objc_super itself.
3610 This needs to be done just once per compilation. */
3613 build_super_template ()
3615 tree record, decl_specs, field_decl, field_decl_chain;
3617 record = start_struct (RECORD_TYPE, get_identifier (UTAG_SUPER));
3619 /* struct objc_object *self; */
3621 decl_specs = build_tree_list (NULL_TREE, objc_object_reference);
3622 field_decl = get_identifier ("self");
3623 field_decl = build1 (INDIRECT_REF, NULL_TREE, field_decl);
3624 field_decl = grokfield (input_filename, lineno,
3625 field_decl, decl_specs, NULL_TREE);
3626 field_decl_chain = field_decl;
3628 /* struct objc_class *class; */
3630 decl_specs = get_identifier (UTAG_CLASS);
3631 decl_specs = build_tree_list (NULL_TREE, xref_tag (RECORD_TYPE, decl_specs));
3632 field_decl = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("class"));
3634 field_decl = grokfield (input_filename, lineno,
3635 field_decl, decl_specs, NULL_TREE);
3636 chainon (field_decl_chain, field_decl);
3638 finish_struct (record, field_decl_chain, NULL_TREE);
3640 /* `struct objc_super *' */
3641 super_type = groktypename (build_tree_list (build_tree_list (NULL_TREE,
3643 build1 (INDIRECT_REF,
3644 NULL_TREE, NULL_TREE)));
3648 /* struct objc_ivar {
3655 build_ivar_template ()
3657 tree objc_ivar_id, objc_ivar_record;
3658 tree decl_specs, field_decl, field_decl_chain;
3660 objc_ivar_id = get_identifier (UTAG_IVAR);
3661 objc_ivar_record = start_struct (RECORD_TYPE, objc_ivar_id);
3663 /* char *ivar_name; */
3665 decl_specs = build_tree_list (NULL_TREE, ridpointers[(int) RID_CHAR]);
3666 field_decl = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("ivar_name"));
3668 field_decl = grokfield (input_filename, lineno, field_decl,
3669 decl_specs, NULL_TREE);
3670 field_decl_chain = field_decl;
3672 /* char *ivar_type; */
3674 decl_specs = build_tree_list (NULL_TREE, ridpointers[(int) RID_CHAR]);
3675 field_decl = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("ivar_type"));
3677 field_decl = grokfield (input_filename, lineno, field_decl,
3678 decl_specs, NULL_TREE);
3679 chainon (field_decl_chain, field_decl);
3681 /* int ivar_offset; */
3683 decl_specs = build_tree_list (NULL_TREE, ridpointers[(int) RID_INT]);
3684 field_decl = get_identifier ("ivar_offset");
3686 field_decl = grokfield (input_filename, lineno, field_decl,
3687 decl_specs, NULL_TREE);
3688 chainon (field_decl_chain, field_decl);
3690 finish_struct (objc_ivar_record, field_decl_chain, NULL_TREE);
3692 return objc_ivar_record;
3697 struct objc_ivar ivar_list[ivar_count];
3701 build_ivar_list_template (list_type, size)
3705 tree objc_ivar_list_record;
3706 tree decl_specs, field_decl, field_decl_chain;
3708 objc_ivar_list_record = start_struct (RECORD_TYPE, NULL_TREE);
3710 /* int ivar_count; */
3712 decl_specs = build_tree_list (NULL_TREE, ridpointers[(int) RID_INT]);
3713 field_decl = get_identifier ("ivar_count");
3715 field_decl = grokfield (input_filename, lineno, field_decl,
3716 decl_specs, NULL_TREE);
3717 field_decl_chain = field_decl;
3719 /* struct objc_ivar ivar_list[]; */
3721 decl_specs = build_tree_list (NULL_TREE, list_type);
3722 field_decl = build_nt (ARRAY_REF, get_identifier ("ivar_list"),
3723 build_int_2 (size, 0));
3725 field_decl = grokfield (input_filename, lineno,
3726 field_decl, decl_specs, NULL_TREE);
3727 chainon (field_decl_chain, field_decl);
3729 finish_struct (objc_ivar_list_record, field_decl_chain, NULL_TREE);
3731 return objc_ivar_list_record;
3737 struct objc_method method_list[method_count];
3741 build_method_list_template (list_type, size)
3745 tree objc_ivar_list_record;
3746 tree decl_specs, field_decl, field_decl_chain;
3748 objc_ivar_list_record = start_struct (RECORD_TYPE, NULL_TREE);
3750 /* int method_next; */
3755 xref_tag (RECORD_TYPE,
3756 get_identifier (UTAG_METHOD_PROTOTYPE_LIST)));
3758 = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("method_next"));
3759 field_decl = grokfield (input_filename, lineno, field_decl,
3760 decl_specs, NULL_TREE);
3761 field_decl_chain = field_decl;
3763 /* int method_count; */
3765 decl_specs = build_tree_list (NULL_TREE, ridpointers[(int) RID_INT]);
3766 field_decl = get_identifier ("method_count");
3768 field_decl = grokfield (input_filename, lineno,
3769 field_decl, decl_specs, NULL_TREE);
3770 chainon (field_decl_chain, field_decl);
3772 /* struct objc_method method_list[]; */
3774 decl_specs = build_tree_list (NULL_TREE, list_type);
3775 field_decl = build_nt (ARRAY_REF, get_identifier ("method_list"),
3776 build_int_2 (size, 0));
3778 field_decl = grokfield (input_filename, lineno,
3779 field_decl, decl_specs, NULL_TREE);
3780 chainon (field_decl_chain, field_decl);
3782 finish_struct (objc_ivar_list_record, field_decl_chain, NULL_TREE);
3784 return objc_ivar_list_record;
3788 build_ivar_list_initializer (type, field_decl)
3792 tree initlist = NULL_TREE;
3796 tree ivar = NULL_TREE;
3799 if (DECL_NAME (field_decl))
3800 ivar = tree_cons (NULL_TREE,
3801 add_objc_string (DECL_NAME (field_decl),
3805 /* Unnamed bit-field ivar (yuck). */
3806 ivar = tree_cons (NULL_TREE, build_int_2 (0, 0), ivar);
3809 encode_field_decl (field_decl,
3810 obstack_object_size (&util_obstack),
3811 OBJC_ENCODE_DONT_INLINE_DEFS);
3813 /* Null terminate string. */
3814 obstack_1grow (&util_obstack, 0);
3818 add_objc_string (get_identifier (obstack_finish (&util_obstack)),
3821 obstack_free (&util_obstack, util_firstobj);
3824 ivar = tree_cons (NULL_TREE, byte_position (field_decl), ivar);
3825 initlist = tree_cons (NULL_TREE,
3826 build_constructor (type, nreverse (ivar)),
3829 field_decl = TREE_CHAIN (field_decl);
3833 return build_constructor (build_array_type (type, 0), nreverse (initlist));
3837 generate_ivars_list (type, name, size, list)
3843 tree sc_spec, decl_specs, decl, initlist;
3845 sc_spec = tree_cons (NULL_TREE, ridpointers[(int) RID_STATIC], NULL_TREE);
3846 decl_specs = tree_cons (NULL_TREE, type, sc_spec);
3848 decl = start_decl (synth_id_with_class_suffix (name, objc_implementation_context),
3849 decl_specs, 1, NULL_TREE);
3851 initlist = build_tree_list (NULL_TREE, build_int_2 (size, 0));
3852 initlist = tree_cons (NULL_TREE, list, initlist);
3855 build_constructor (TREE_TYPE (decl), nreverse (initlist)),
3862 generate_ivar_lists ()
3864 tree initlist, ivar_list_template, chain;
3865 tree cast, variable_length_type;
3868 generating_instance_variables = 1;
3870 if (!objc_ivar_template)
3871 objc_ivar_template = build_ivar_template ();
3875 (build_tree_list (NULL_TREE, xref_tag (RECORD_TYPE,
3876 get_identifier (UTAG_IVAR_LIST))),
3878 variable_length_type = groktypename (cast);
3880 /* Only generate class variables for the root of the inheritance
3881 hierarchy since these will be the same for every class. */
3883 if (CLASS_SUPER_NAME (implementation_template) == NULL_TREE
3884 && (chain = TYPE_FIELDS (objc_class_template)))
3886 size = list_length (chain);
3888 ivar_list_template = build_ivar_list_template (objc_ivar_template, size);
3889 initlist = build_ivar_list_initializer (objc_ivar_template, chain);
3891 UOBJC_CLASS_VARIABLES_decl
3892 = generate_ivars_list (ivar_list_template, "_OBJC_CLASS_VARIABLES",
3894 TREE_TYPE (UOBJC_CLASS_VARIABLES_decl) = variable_length_type;
3897 UOBJC_CLASS_VARIABLES_decl = 0;
3899 chain = CLASS_IVARS (implementation_template);
3902 size = list_length (chain);
3903 ivar_list_template = build_ivar_list_template (objc_ivar_template, size);
3904 initlist = build_ivar_list_initializer (objc_ivar_template, chain);
3906 UOBJC_INSTANCE_VARIABLES_decl
3907 = generate_ivars_list (ivar_list_template, "_OBJC_INSTANCE_VARIABLES",
3909 TREE_TYPE (UOBJC_INSTANCE_VARIABLES_decl) = variable_length_type;
3912 UOBJC_INSTANCE_VARIABLES_decl = 0;
3914 generating_instance_variables = 0;
3918 build_dispatch_table_initializer (type, entries)
3922 tree initlist = NULL_TREE;
3926 tree elemlist = NULL_TREE;
3928 elemlist = tree_cons (NULL_TREE,
3929 build_selector (METHOD_SEL_NAME (entries)),
3932 /* Generate the method encoding if we don't have one already. */
3933 if (! METHOD_ENCODING (entries))
3934 METHOD_ENCODING (entries) =
3935 encode_method_def (METHOD_DEFINITION (entries));
3937 elemlist = tree_cons (NULL_TREE,
3938 add_objc_string (METHOD_ENCODING (entries),
3942 elemlist = tree_cons (NULL_TREE,
3943 build_unary_op (ADDR_EXPR,
3944 METHOD_DEFINITION (entries), 1),
3947 initlist = tree_cons (NULL_TREE,
3948 build_constructor (type, nreverse (elemlist)),
3951 entries = TREE_CHAIN (entries);
3955 return build_constructor (build_array_type (type, 0), 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, lineno, 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, lineno, 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, lineno, 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 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, 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 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 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, lineno,
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_with_file_and_line (DECL_SOURCE_FILE (method),
7118 DECL_SOURCE_LINE (method),
7121 gen_method_decl (method, errbuf));
7124 /* Return 1 if METHOD is consistent with PROTO. */
7127 comp_method_with_proto (method, proto)
7130 /* Create a function template node at most once. */
7131 if (!function1_template)
7132 function1_template = make_node (FUNCTION_TYPE);
7134 /* Install argument types - normally set by build_function_type. */
7135 TYPE_ARG_TYPES (function1_template) = get_arg_type_list (proto, METHOD_DEF, 0);
7137 /* install return type */
7138 TREE_TYPE (function1_template) = groktypename (TREE_TYPE (proto));
7140 return comptypes (TREE_TYPE (METHOD_DEFINITION (method)), function1_template);
7143 /* Return 1 if PROTO1 is consistent with PROTO2. */
7146 comp_proto_with_proto (proto0, proto1)
7147 tree proto0, proto1;
7149 /* Create a couple of function_template nodes at most once. */
7150 if (!function1_template)
7151 function1_template = make_node (FUNCTION_TYPE);
7152 if (!function2_template)
7153 function2_template = make_node (FUNCTION_TYPE);
7155 /* Install argument types; normally set by build_function_type. */
7156 TYPE_ARG_TYPES (function1_template) = get_arg_type_list (proto0, METHOD_REF, 0);
7157 TYPE_ARG_TYPES (function2_template) = get_arg_type_list (proto1, METHOD_REF, 0);
7159 /* Install return type. */
7160 TREE_TYPE (function1_template) = groktypename (TREE_TYPE (proto0));
7161 TREE_TYPE (function2_template) = groktypename (TREE_TYPE (proto1));
7163 return comptypes (function1_template, function2_template);
7166 /* - Generate an identifier for the function. the format is "_n_cls",
7167 where 1 <= n <= nMethods, and cls is the name the implementation we
7169 - Install the return type from the method declaration.
7170 - If we have a prototype, check for type consistency. */
7173 really_start_method (method, parmlist)
7174 tree method, parmlist;
7176 tree sc_spec, ret_spec, ret_decl, decl_specs;
7177 tree method_decl, method_id;
7178 const char *sel_name, *class_name, *cat_name;
7181 /* Synth the storage class & assemble the return type. */
7182 sc_spec = tree_cons (NULL_TREE, ridpointers[(int) RID_STATIC], NULL_TREE);
7183 ret_spec = TREE_PURPOSE (TREE_TYPE (method));
7184 decl_specs = chainon (sc_spec, ret_spec);
7186 sel_name = IDENTIFIER_POINTER (METHOD_SEL_NAME (method));
7187 class_name = IDENTIFIER_POINTER (CLASS_NAME (objc_implementation_context));
7188 cat_name = ((TREE_CODE (objc_implementation_context)
7189 == CLASS_IMPLEMENTATION_TYPE)
7191 : IDENTIFIER_POINTER (CLASS_SUPER_NAME (objc_implementation_context)));
7194 /* Make sure this is big enough for any plausible method label. */
7195 buf = (char *) alloca (50 + strlen (sel_name) + strlen (class_name)
7196 + (cat_name ? strlen (cat_name) : 0));
7198 OBJC_GEN_METHOD_LABEL (buf, TREE_CODE (method) == INSTANCE_METHOD_DECL,
7199 class_name, cat_name, sel_name, method_slot);
7201 method_id = get_identifier (buf);
7203 method_decl = build_nt (CALL_EXPR, method_id, parmlist, NULL_TREE);
7205 /* Check the declarator portion of the return type for the method. */
7206 if ((ret_decl = TREE_VALUE (TREE_TYPE (method))))
7208 /* Unite the complex decl (specified in the abstract decl) with the
7209 function decl just synthesized..(int *), (int (*)()), (int (*)[]). */
7210 tree save_expr = expr_last (ret_decl);
7212 TREE_OPERAND (save_expr, 0) = method_decl;
7213 method_decl = ret_decl;
7215 /* Fool the parser into thinking it is starting a function. */
7216 start_function (decl_specs, method_decl, NULL_TREE);
7218 /* Unhook: this has the effect of restoring the abstract declarator. */
7219 TREE_OPERAND (save_expr, 0) = NULL_TREE;
7224 TREE_VALUE (TREE_TYPE (method)) = method_decl;
7226 /* Fool the parser into thinking it is starting a function. */
7227 start_function (decl_specs, method_decl, NULL_TREE);
7229 /* Unhook: this has the effect of restoring the abstract declarator. */
7230 TREE_VALUE (TREE_TYPE (method)) = NULL_TREE;
7233 METHOD_DEFINITION (method) = current_function_decl;
7235 /* Check consistency...start_function, pushdecl, duplicate_decls. */
7237 if (implementation_template != objc_implementation_context)
7241 if (TREE_CODE (method) == INSTANCE_METHOD_DECL)
7242 proto = lookup_instance_method_static (implementation_template,
7243 METHOD_SEL_NAME (method));
7245 proto = lookup_class_method_static (implementation_template,
7246 METHOD_SEL_NAME (method));
7248 if (proto && ! comp_method_with_proto (method, proto))
7250 char type = (TREE_CODE (method) == INSTANCE_METHOD_DECL ? '-' : '+');
7252 warn_with_method ("conflicting types for", type, method);
7253 warn_with_method ("previous declaration of", type, proto);
7258 /* The following routine is always called...this "architecture" is to
7259 accommodate "old-style" variable length selectors.
7261 - a:a b:b // prototype ; id c; id d; // old-style. */
7264 continue_method_def ()
7268 if (METHOD_ADD_ARGS (objc_method_context) == objc_ellipsis_node)
7269 /* We have a `, ...' immediately following the selector. */
7270 parmlist = get_parm_info (0);
7272 parmlist = get_parm_info (1); /* place a `void_at_end' */
7274 /* Set self_decl from the first argument...this global is used by
7275 build_ivar_reference calling build_indirect_ref. */
7276 self_decl = TREE_PURPOSE (parmlist);
7279 really_start_method (objc_method_context, parmlist);
7280 store_parm_decls ();
7283 /* Called by the parser, from the `pushlevel' production. */
7288 if (!UOBJC_SUPER_decl)
7290 UOBJC_SUPER_decl = start_decl (get_identifier (UTAG_SUPER),
7291 build_tree_list (NULL_TREE,
7292 objc_super_template),
7295 finish_decl (UOBJC_SUPER_decl, NULL_TREE, NULL_TREE);
7297 /* This prevents `unused variable' warnings when compiling with -Wall. */
7298 TREE_USED (UOBJC_SUPER_decl) = 1;
7299 DECL_ARTIFICIAL (UOBJC_SUPER_decl) = 1;
7303 /* _n_Method (id self, SEL sel, ...)
7305 struct objc_super _S;
7306 _msgSuper ((_S.self = self, _S.class = _cls, &_S), ...);
7310 get_super_receiver ()
7312 if (objc_method_context)
7314 tree super_expr, super_expr_list;
7316 /* Set receiver to self. */
7317 super_expr = build_component_ref (UOBJC_SUPER_decl, self_id);
7318 super_expr = build_modify_expr (super_expr, NOP_EXPR, self_decl);
7319 super_expr_list = build_tree_list (NULL_TREE, super_expr);
7321 /* Set class to begin searching. */
7322 super_expr = build_component_ref (UOBJC_SUPER_decl,
7323 get_identifier ("class"));
7325 if (TREE_CODE (objc_implementation_context) == CLASS_IMPLEMENTATION_TYPE)
7327 /* [_cls, __cls]Super are "pre-built" in
7328 synth_forward_declarations. */
7330 super_expr = build_modify_expr (super_expr, NOP_EXPR,
7331 ((TREE_CODE (objc_method_context)
7332 == INSTANCE_METHOD_DECL)
7334 : uucls_super_ref));
7338 /* We have a category. */
7340 tree super_name = CLASS_SUPER_NAME (implementation_template);
7343 /* Barf if super used in a category of Object. */
7346 error ("no super class declared in interface for `%s'",
7347 IDENTIFIER_POINTER (CLASS_NAME (implementation_template)));
7348 return error_mark_node;
7351 if (flag_next_runtime)
7353 super_class = get_class_reference (super_name);
7354 if (TREE_CODE (objc_method_context) == CLASS_METHOD_DECL)
7355 /* Cast the super class to 'id', since the user may not have
7356 included <objc/objc-class.h>, leaving 'struct objc_class'
7357 an incomplete type. */
7359 = build_component_ref (build_indirect_ref
7360 (build_c_cast (id_type, super_class), "->"),
7361 get_identifier ("isa"));
7365 add_class_reference (super_name);
7366 super_class = (TREE_CODE (objc_method_context) == INSTANCE_METHOD_DECL
7367 ? objc_get_class_decl : objc_get_meta_class_decl);
7368 assemble_external (super_class);
7370 = build_function_call
7374 my_build_string (IDENTIFIER_LENGTH (super_name) + 1,
7375 IDENTIFIER_POINTER (super_name))));
7378 TREE_TYPE (super_class) = TREE_TYPE (ucls_super_ref);
7379 super_expr = build_modify_expr (super_expr, NOP_EXPR, super_class);
7382 chainon (super_expr_list, build_tree_list (NULL_TREE, super_expr));
7384 super_expr = build_unary_op (ADDR_EXPR, UOBJC_SUPER_decl, 0);
7385 chainon (super_expr_list, build_tree_list (NULL_TREE, super_expr));
7387 return build_compound_expr (super_expr_list);
7391 error ("[super ...] must appear in a method context");
7392 return error_mark_node;
7397 encode_method_def (func_decl)
7402 HOST_WIDE_INT max_parm_end = 0;
7407 encode_type (TREE_TYPE (TREE_TYPE (func_decl)),
7408 obstack_object_size (&util_obstack),
7409 OBJC_ENCODE_INLINE_DEFS);
7412 for (parms = DECL_ARGUMENTS (func_decl); parms;
7413 parms = TREE_CHAIN (parms))
7415 HOST_WIDE_INT parm_end = (forwarding_offset (parms)
7416 + int_size_in_bytes (TREE_TYPE (parms)));
7418 if (! offset_is_register && parm_end > max_parm_end)
7419 max_parm_end = parm_end;
7422 stack_size = max_parm_end - OBJC_FORWARDING_MIN_OFFSET;
7424 sprintf (buffer, "%d", stack_size);
7425 obstack_grow (&util_obstack, buffer, strlen (buffer));
7427 /* Argument types. */
7428 for (parms = DECL_ARGUMENTS (func_decl); parms;
7429 parms = TREE_CHAIN (parms))
7432 encode_type (TREE_TYPE (parms),
7433 obstack_object_size (&util_obstack),
7434 OBJC_ENCODE_INLINE_DEFS);
7436 /* Compute offset. */
7437 sprintf (buffer, "%d", forwarding_offset (parms));
7439 /* Indicate register. */
7440 if (offset_is_register)
7441 obstack_1grow (&util_obstack, '+');
7443 obstack_grow (&util_obstack, buffer, strlen (buffer));
7446 /* Null terminate string. */
7447 obstack_1grow (&util_obstack, 0);
7448 result = get_identifier (obstack_finish (&util_obstack));
7449 obstack_free (&util_obstack, util_firstobj);
7454 objc_expand_function_end ()
7456 METHOD_ENCODING (objc_method_context) = encode_method_def (current_function_decl);
7460 finish_method_def ()
7462 lang_expand_function_end = objc_expand_function_end;
7463 finish_function (0, 1);
7464 lang_expand_function_end = NULL;
7466 /* Required to implement _msgSuper. This must be done AFTER finish_function,
7467 since the optimizer may find "may be used before set" errors. */
7468 objc_method_context = NULL_TREE;
7473 lang_report_error_function (decl)
7476 if (objc_method_context)
7478 fprintf (stderr, "In method `%s'\n",
7479 IDENTIFIER_POINTER (METHOD_SEL_NAME (objc_method_context)));
7489 is_complex_decl (type)
7492 return (TREE_CODE (type) == ARRAY_TYPE
7493 || TREE_CODE (type) == FUNCTION_TYPE
7494 || (TREE_CODE (type) == POINTER_TYPE && ! IS_ID (type)));
7498 /* Code to convert a decl node into text for a declaration in C. */
7500 static char tmpbuf[256];
7503 adorn_decl (decl, str)
7507 enum tree_code code = TREE_CODE (decl);
7509 if (code == ARRAY_REF)
7511 tree an_int_cst = TREE_OPERAND (decl, 1);
7513 if (an_int_cst && TREE_CODE (an_int_cst) == INTEGER_CST)
7514 sprintf (str + strlen (str), "[%ld]",
7515 (long) TREE_INT_CST_LOW (an_int_cst));
7520 else if (code == ARRAY_TYPE)
7522 tree an_int_cst = TYPE_SIZE (decl);
7523 tree array_of = TREE_TYPE (decl);
7525 if (an_int_cst && TREE_CODE (an_int_cst) == INTEGER_TYPE)
7526 sprintf (str + strlen (str), "[%ld]",
7527 (long) (TREE_INT_CST_LOW (an_int_cst)
7528 / TREE_INT_CST_LOW (TYPE_SIZE (array_of))));
7533 else if (code == CALL_EXPR)
7535 tree chain = TREE_PURPOSE (TREE_OPERAND (decl, 1));
7540 gen_declaration_1 (chain, str);
7541 chain = TREE_CHAIN (chain);
7548 else if (code == FUNCTION_TYPE)
7550 tree chain = TYPE_ARG_TYPES (decl);
7553 while (chain && TREE_VALUE (chain) != void_type_node)
7555 gen_declaration_1 (TREE_VALUE (chain), str);
7556 chain = TREE_CHAIN (chain);
7557 if (chain && TREE_VALUE (chain) != void_type_node)
7563 else if (code == INDIRECT_REF)
7565 strcpy (tmpbuf, "*");
7566 if (TREE_TYPE (decl) && TREE_CODE (TREE_TYPE (decl)) == TREE_LIST)
7570 for (chain = nreverse (copy_list (TREE_TYPE (decl)));
7572 chain = TREE_CHAIN (chain))
7574 if (TREE_CODE (TREE_VALUE (chain)) == IDENTIFIER_NODE)
7576 strcat (tmpbuf, " ");
7577 strcat (tmpbuf, IDENTIFIER_POINTER (TREE_VALUE (chain)));
7581 strcat (tmpbuf, " ");
7583 strcat (tmpbuf, str);
7584 strcpy (str, tmpbuf);
7587 else if (code == POINTER_TYPE)
7589 strcpy (tmpbuf, "*");
7590 if (TREE_READONLY (decl) || TYPE_VOLATILE (decl))
7592 if (TREE_READONLY (decl))
7593 strcat (tmpbuf, " const");
7594 if (TYPE_VOLATILE (decl))
7595 strcat (tmpbuf, " volatile");
7597 strcat (tmpbuf, " ");
7599 strcat (tmpbuf, str);
7600 strcpy (str, tmpbuf);
7605 gen_declarator (decl, buf, name)
7612 enum tree_code code = TREE_CODE (decl);
7622 op = TREE_OPERAND (decl, 0);
7624 /* We have a pointer to a function or array...(*)(), (*)[] */
7625 if ((code == ARRAY_REF || code == CALL_EXPR)
7626 && op && TREE_CODE (op) == INDIRECT_REF)
7629 str = gen_declarator (op, buf, name);
7633 strcpy (tmpbuf, "(");
7634 strcat (tmpbuf, str);
7635 strcat (tmpbuf, ")");
7636 strcpy (str, tmpbuf);
7639 adorn_decl (decl, str);
7648 /* This clause is done iteratively rather than recursively. */
7651 op = (is_complex_decl (TREE_TYPE (decl))
7652 ? TREE_TYPE (decl) : NULL_TREE);
7654 adorn_decl (decl, str);
7656 /* We have a pointer to a function or array...(*)(), (*)[] */
7657 if (code == POINTER_TYPE
7658 && op && (TREE_CODE (op) == FUNCTION_TYPE
7659 || TREE_CODE (op) == ARRAY_TYPE))
7661 strcpy (tmpbuf, "(");
7662 strcat (tmpbuf, str);
7663 strcat (tmpbuf, ")");
7664 strcpy (str, tmpbuf);
7667 decl = (is_complex_decl (TREE_TYPE (decl))
7668 ? TREE_TYPE (decl) : NULL_TREE);
7671 while (decl && (code = TREE_CODE (decl)))
7676 case IDENTIFIER_NODE:
7677 /* Will only happen if we are processing a "raw" expr-decl. */
7678 strcpy (buf, IDENTIFIER_POINTER (decl));
7689 /* We have an abstract declarator or a _DECL node. */
7697 gen_declspecs (declspecs, buf, raw)
7706 for (chain = nreverse (copy_list (declspecs));
7707 chain; chain = TREE_CHAIN (chain))
7709 tree aspec = TREE_VALUE (chain);
7711 if (TREE_CODE (aspec) == IDENTIFIER_NODE)
7712 strcat (buf, IDENTIFIER_POINTER (aspec));
7713 else if (TREE_CODE (aspec) == RECORD_TYPE)
7715 if (TYPE_NAME (aspec))
7717 tree protocol_list = TYPE_PROTOCOL_LIST (aspec);
7719 if (! TREE_STATIC_TEMPLATE (aspec))
7720 strcat (buf, "struct ");
7721 strcat (buf, IDENTIFIER_POINTER (TYPE_NAME (aspec)));
7726 tree chain = protocol_list;
7733 (PROTOCOL_NAME (TREE_VALUE (chain))));
7734 chain = TREE_CHAIN (chain);
7743 strcat (buf, "untagged struct");
7746 else if (TREE_CODE (aspec) == UNION_TYPE)
7748 if (TYPE_NAME (aspec))
7750 if (! TREE_STATIC_TEMPLATE (aspec))
7751 strcat (buf, "union ");
7752 strcat (buf, IDENTIFIER_POINTER (TYPE_NAME (aspec)));
7755 strcat (buf, "untagged union");
7758 else if (TREE_CODE (aspec) == ENUMERAL_TYPE)
7760 if (TYPE_NAME (aspec))
7762 if (! TREE_STATIC_TEMPLATE (aspec))
7763 strcat (buf, "enum ");
7764 strcat (buf, IDENTIFIER_POINTER (TYPE_NAME (aspec)));
7767 strcat (buf, "untagged enum");
7770 else if (TREE_CODE (aspec) == TYPE_DECL && DECL_NAME (aspec))
7771 strcat (buf, IDENTIFIER_POINTER (DECL_NAME (aspec)));
7773 else if (IS_ID (aspec))
7775 tree protocol_list = TYPE_PROTOCOL_LIST (aspec);
7780 tree chain = protocol_list;
7787 (PROTOCOL_NAME (TREE_VALUE (chain))));
7788 chain = TREE_CHAIN (chain);
7795 if (TREE_CHAIN (chain))
7801 /* Type qualifiers. */
7802 if (TREE_READONLY (declspecs))
7803 strcat (buf, "const ");
7804 if (TYPE_VOLATILE (declspecs))
7805 strcat (buf, "volatile ");
7807 switch (TREE_CODE (declspecs))
7809 /* Type specifiers. */
7812 declspecs = TYPE_MAIN_VARIANT (declspecs);
7814 /* Signed integer types. */
7816 if (declspecs == short_integer_type_node)
7817 strcat (buf, "short int ");
7818 else if (declspecs == integer_type_node)
7819 strcat (buf, "int ");
7820 else if (declspecs == long_integer_type_node)
7821 strcat (buf, "long int ");
7822 else if (declspecs == long_long_integer_type_node)
7823 strcat (buf, "long long int ");
7824 else if (declspecs == signed_char_type_node
7825 || declspecs == char_type_node)
7826 strcat (buf, "char ");
7828 /* Unsigned integer types. */
7830 else if (declspecs == short_unsigned_type_node)
7831 strcat (buf, "unsigned short ");
7832 else if (declspecs == unsigned_type_node)
7833 strcat (buf, "unsigned int ");
7834 else if (declspecs == long_unsigned_type_node)
7835 strcat (buf, "unsigned long ");
7836 else if (declspecs == long_long_unsigned_type_node)
7837 strcat (buf, "unsigned long long ");
7838 else if (declspecs == unsigned_char_type_node)
7839 strcat (buf, "unsigned char ");
7843 declspecs = TYPE_MAIN_VARIANT (declspecs);
7845 if (declspecs == float_type_node)
7846 strcat (buf, "float ");
7847 else if (declspecs == double_type_node)
7848 strcat (buf, "double ");
7849 else if (declspecs == long_double_type_node)
7850 strcat (buf, "long double ");
7854 if (TYPE_NAME (declspecs)
7855 && TREE_CODE (TYPE_NAME (declspecs)) == IDENTIFIER_NODE)
7857 tree protocol_list = TYPE_PROTOCOL_LIST (declspecs);
7859 if (! TREE_STATIC_TEMPLATE (declspecs))
7860 strcat (buf, "struct ");
7861 strcat (buf, IDENTIFIER_POINTER (TYPE_NAME (declspecs)));
7865 tree chain = protocol_list;
7872 (PROTOCOL_NAME (TREE_VALUE (chain))));
7873 chain = TREE_CHAIN (chain);
7882 strcat (buf, "untagged struct");
7888 if (TYPE_NAME (declspecs)
7889 && TREE_CODE (TYPE_NAME (declspecs)) == IDENTIFIER_NODE)
7891 strcat (buf, "union ");
7892 strcat (buf, IDENTIFIER_POINTER (TYPE_NAME (declspecs)));
7897 strcat (buf, "untagged union ");
7901 if (TYPE_NAME (declspecs)
7902 && TREE_CODE (TYPE_NAME (declspecs)) == IDENTIFIER_NODE)
7904 strcat (buf, "enum ");
7905 strcat (buf, IDENTIFIER_POINTER (TYPE_NAME (declspecs)));
7910 strcat (buf, "untagged enum ");
7914 strcat (buf, "void ");
7919 tree protocol_list = TYPE_PROTOCOL_LIST (declspecs);
7924 tree chain = protocol_list;
7931 (PROTOCOL_NAME (TREE_VALUE (chain))));
7932 chain = TREE_CHAIN (chain);
7948 /* Given a tree node, produce a printable description of it in the given
7949 buffer, overwriting the buffer. */
7952 gen_declaration (atype_or_adecl, buf)
7953 tree atype_or_adecl;
7957 gen_declaration_1 (atype_or_adecl, buf);
7961 /* Given a tree node, append a printable description to the end of the
7965 gen_declaration_1 (atype_or_adecl, buf)
7966 tree atype_or_adecl;
7971 if (TREE_CODE (atype_or_adecl) == TREE_LIST)
7973 tree declspecs; /* "identifier_node", "record_type" */
7974 tree declarator; /* "array_ref", "indirect_ref", "call_expr"... */
7976 /* We have a "raw", abstract declarator (typename). */
7977 declarator = TREE_VALUE (atype_or_adecl);
7978 declspecs = TREE_PURPOSE (atype_or_adecl);
7980 gen_declspecs (declspecs, buf, 1);
7984 strcat (buf, gen_declarator (declarator, declbuf, ""));
7991 tree declspecs; /* "integer_type", "real_type", "record_type"... */
7992 tree declarator; /* "array_type", "function_type", "pointer_type". */
7994 if (TREE_CODE (atype_or_adecl) == FIELD_DECL
7995 || TREE_CODE (atype_or_adecl) == PARM_DECL
7996 || TREE_CODE (atype_or_adecl) == FUNCTION_DECL)
7997 atype = TREE_TYPE (atype_or_adecl);
7999 /* Assume we have a *_type node. */
8000 atype = atype_or_adecl;
8002 if (is_complex_decl (atype))
8006 /* Get the declaration specifier; it is at the end of the list. */
8007 declarator = chain = atype;
8009 chain = TREE_TYPE (chain); /* not TREE_CHAIN (chain); */
8010 while (is_complex_decl (chain));
8017 declarator = NULL_TREE;
8020 gen_declspecs (declspecs, buf, 0);
8022 if (TREE_CODE (atype_or_adecl) == FIELD_DECL
8023 || TREE_CODE (atype_or_adecl) == PARM_DECL
8024 || TREE_CODE (atype_or_adecl) == FUNCTION_DECL)
8026 const char *const decl_name =
8027 (DECL_NAME (atype_or_adecl)
8028 ? IDENTIFIER_POINTER (DECL_NAME (atype_or_adecl)) : "");
8033 strcat (buf, gen_declarator (declarator, declbuf, decl_name));
8036 else if (decl_name[0])
8039 strcat (buf, decl_name);
8042 else if (declarator)
8045 strcat (buf, gen_declarator (declarator, declbuf, ""));
8050 #define RAW_TYPESPEC(meth) (TREE_VALUE (TREE_PURPOSE (TREE_TYPE (meth))))
8052 /* Given a method tree, put a printable description into the given
8053 buffer (overwriting) and return a pointer to the buffer. */
8056 gen_method_decl (method, buf)
8063 if (RAW_TYPESPEC (method) != objc_object_reference)
8066 gen_declaration_1 (TREE_TYPE (method), buf);
8070 chain = METHOD_SEL_ARGS (method);
8073 /* We have a chain of keyword_decls. */
8076 if (KEYWORD_KEY_NAME (chain))
8077 strcat (buf, IDENTIFIER_POINTER (KEYWORD_KEY_NAME (chain)));
8080 if (RAW_TYPESPEC (chain) != objc_object_reference)
8083 gen_declaration_1 (TREE_TYPE (chain), buf);
8087 strcat (buf, IDENTIFIER_POINTER (KEYWORD_ARG_NAME (chain)));
8088 if ((chain = TREE_CHAIN (chain)))
8093 if (METHOD_ADD_ARGS (method) == objc_ellipsis_node)
8094 strcat (buf, ", ...");
8095 else if (METHOD_ADD_ARGS (method))
8097 /* We have a tree list node as generate by get_parm_info. */
8098 chain = TREE_PURPOSE (METHOD_ADD_ARGS (method));
8100 /* Know we have a chain of parm_decls. */
8104 gen_declaration_1 (chain, buf);
8105 chain = TREE_CHAIN (chain);
8111 /* We have a unary selector. */
8112 strcat (buf, IDENTIFIER_POINTER (METHOD_SEL_NAME (method)));
8120 /* Dump an @interface declaration of the supplied class CHAIN to the
8121 supplied file FP. Used to implement the -gen-decls option (which
8122 prints out an @interface declaration of all classes compiled in
8123 this run); potentially useful for debugging the compiler too. */
8125 dump_interface (fp, chain)
8129 /* FIXME: A heap overflow here whenever a method (or ivar)
8130 declaration is so long that it doesn't fit in the buffer. The
8131 code and all the related functions should be rewritten to avoid
8132 using fixed size buffers. */
8133 char *buf = (char *) xmalloc (1024 * 10);
8134 const char *my_name = IDENTIFIER_POINTER (CLASS_NAME (chain));
8135 tree ivar_decls = CLASS_RAW_IVARS (chain);
8136 tree nst_methods = CLASS_NST_METHODS (chain);
8137 tree cls_methods = CLASS_CLS_METHODS (chain);
8139 fprintf (fp, "\n@interface %s", my_name);
8141 /* CLASS_SUPER_NAME is used to store the superclass name for
8142 classes, and the category name for categories. */
8143 if (CLASS_SUPER_NAME (chain))
8145 const char *name = IDENTIFIER_POINTER (CLASS_SUPER_NAME (chain));
8147 if (TREE_CODE (chain) == CATEGORY_IMPLEMENTATION_TYPE
8148 || TREE_CODE (chain) == CATEGORY_INTERFACE_TYPE)
8150 fprintf (fp, " (%s)\n", name);
8154 fprintf (fp, " : %s\n", name);
8160 /* FIXME - the following doesn't seem to work at the moment. */
8163 fprintf (fp, "{\n");
8166 fprintf (fp, "\t%s;\n", gen_declaration (ivar_decls, buf));
8167 ivar_decls = TREE_CHAIN (ivar_decls);
8170 fprintf (fp, "}\n");
8175 fprintf (fp, "- %s;\n", gen_method_decl (nst_methods, buf));
8176 nst_methods = TREE_CHAIN (nst_methods);
8181 fprintf (fp, "+ %s;\n", gen_method_decl (cls_methods, buf));
8182 cls_methods = TREE_CHAIN (cls_methods);
8185 fprintf (fp, "@end\n");
8188 /* Demangle function for Objective-C */
8190 objc_demangle (mangled)
8191 const char *mangled;
8193 char *demangled, *cp;
8195 if (mangled[0] == '_' &&
8196 (mangled[1] == 'i' || mangled[1] == 'c') &&
8199 cp = demangled = xmalloc(strlen(mangled) + 2);
8200 if (mangled[1] == 'i')
8201 *cp++ = '-'; /* for instance method */
8203 *cp++ = '+'; /* for class method */
8204 *cp++ = '['; /* opening left brace */
8205 strcpy(cp, mangled+3); /* tack on the rest of the mangled name */
8206 while (*cp && *cp == '_')
8207 cp++; /* skip any initial underbars in class name */
8208 cp = strchr(cp, '_'); /* find first non-initial underbar */
8211 free(demangled); /* not mangled name */
8214 if (cp[1] == '_') /* easy case: no category name */
8216 *cp++ = ' '; /* replace two '_' with one ' ' */
8217 strcpy(cp, mangled + (cp - demangled) + 2);
8221 *cp++ = '('; /* less easy case: category name */
8222 cp = strchr(cp, '_');
8225 free(demangled); /* not mangled name */
8229 *cp++ = ' '; /* overwriting 1st char of method name... */
8230 strcpy(cp, mangled + (cp - demangled)); /* get it back */
8232 while (*cp && *cp == '_')
8233 cp++; /* skip any initial underbars in method name */
8236 *cp = ':'; /* replace remaining '_' with ':' */
8237 *cp++ = ']'; /* closing right brace */
8238 *cp++ = 0; /* string terminator */
8242 return mangled; /* not an objc mangled name */
8246 objc_printable_name (decl, kind)
8248 int kind ATTRIBUTE_UNUSED;
8250 return objc_demangle (IDENTIFIER_POINTER (DECL_NAME (decl)));
8256 gcc_obstack_init (&util_obstack);
8257 util_firstobj = (char *) obstack_finish (&util_obstack);
8259 errbuf = (char *) xmalloc (BUFSIZE);
8261 synth_module_prologue ();
8267 struct imp_entry *impent;
8269 /* The internally generated initializers appear to have missing braces.
8270 Don't warn about this. */
8271 int save_warn_missing_braces = warn_missing_braces;
8272 warn_missing_braces = 0;
8274 /* A missing @end may not be detected by the parser. */
8275 if (objc_implementation_context)
8277 warning ("`@end' missing in implementation context");
8278 finish_class (objc_implementation_context);
8279 objc_ivar_chain = NULL_TREE;
8280 objc_implementation_context = NULL_TREE;
8283 generate_forward_declaration_to_string_table ();
8285 #ifdef OBJC_PROLOGUE
8289 /* Process the static instances here because initialization of objc_symtab
8291 if (objc_static_instances)
8292 generate_static_references ();
8294 if (imp_list || class_names_chain
8295 || meth_var_names_chain || meth_var_types_chain || sel_ref_chain)
8296 generate_objc_symtab_decl ();
8298 for (impent = imp_list; impent; impent = impent->next)
8300 objc_implementation_context = impent->imp_context;
8301 implementation_template = impent->imp_template;
8303 UOBJC_CLASS_decl = impent->class_decl;
8304 UOBJC_METACLASS_decl = impent->meta_decl;
8306 /* Dump the @interface of each class as we compile it, if the
8307 -gen-decls option is in use. TODO: Dump the classes in the
8308 order they were found, rather than in reverse order as we
8310 if (flag_gen_declaration)
8312 dump_interface (gen_declaration_file, objc_implementation_context);
8315 if (TREE_CODE (objc_implementation_context) == CLASS_IMPLEMENTATION_TYPE)
8317 /* all of the following reference the string pool... */
8318 generate_ivar_lists ();
8319 generate_dispatch_tables ();
8320 generate_shared_structures ();
8324 generate_dispatch_tables ();
8325 generate_category (objc_implementation_context);
8329 /* If we are using an array of selectors, we must always
8330 finish up the array decl even if no selectors were used. */
8331 if (! flag_next_runtime || sel_ref_chain)
8332 build_selector_translation_table ();
8335 generate_protocols ();
8337 if (objc_implementation_context || class_names_chain || objc_static_instances
8338 || meth_var_names_chain || meth_var_types_chain || sel_ref_chain)
8340 /* Arrange for ObjC data structures to be initialized at run time. */
8341 rtx init_sym = build_module_descriptor ();
8342 if (init_sym && targetm.have_ctors_dtors)
8343 (* targetm.asm_out.constructor) (init_sym, DEFAULT_INIT_PRIORITY);
8346 /* Dump the class references. This forces the appropriate classes
8347 to be linked into the executable image, preserving unix archive
8348 semantics. This can be removed when we move to a more dynamically
8349 linked environment. */
8351 for (chain = cls_ref_chain; chain; chain = TREE_CHAIN (chain))
8353 handle_class_ref (chain);
8354 if (TREE_PURPOSE (chain))
8355 generate_classref_translation_entry (chain);
8358 for (impent = imp_list; impent; impent = impent->next)
8359 handle_impent (impent);
8361 /* Dump the string table last. */
8363 generate_strings ();
8370 /* Run through the selector hash tables and print a warning for any
8371 selector which has multiple methods. */
8373 for (slot = 0; slot < SIZEHASHTABLE; slot++)
8374 for (hsh = cls_method_hash_list[slot]; hsh; hsh = hsh->next)
8377 tree meth = hsh->key;
8378 char type = (TREE_CODE (meth) == INSTANCE_METHOD_DECL
8382 warning ("potential selector conflict for method `%s'",
8383 IDENTIFIER_POINTER (METHOD_SEL_NAME (meth)));
8384 warn_with_method ("found", type, meth);
8385 for (loop = hsh->list; loop; loop = loop->next)
8386 warn_with_method ("found", type, loop->value);
8389 for (slot = 0; slot < SIZEHASHTABLE; slot++)
8390 for (hsh = nst_method_hash_list[slot]; hsh; hsh = hsh->next)
8393 tree meth = hsh->key;
8394 char type = (TREE_CODE (meth) == INSTANCE_METHOD_DECL
8398 warning ("potential selector conflict for method `%s'",
8399 IDENTIFIER_POINTER (METHOD_SEL_NAME (meth)));
8400 warn_with_method ("found", type, meth);
8401 for (loop = hsh->list; loop; loop = loop->next)
8402 warn_with_method ("found", type, loop->value);
8406 warn_missing_braces = save_warn_missing_braces;
8409 /* Subroutines of finish_objc. */
8412 generate_classref_translation_entry (chain)
8415 tree expr, name, decl_specs, decl, sc_spec;
8418 type = TREE_TYPE (TREE_PURPOSE (chain));
8420 expr = add_objc_string (TREE_VALUE (chain), class_names);
8421 expr = build_c_cast (type, expr); /* cast! */
8423 name = DECL_NAME (TREE_PURPOSE (chain));
8425 sc_spec = build_tree_list (NULL_TREE, ridpointers[(int) RID_STATIC]);
8427 /* static struct objc_class * _OBJC_CLASS_REFERENCES_n = ...; */
8428 decl_specs = tree_cons (NULL_TREE, type, sc_spec);
8430 /* The decl that is returned from start_decl is the one that we
8431 forward declared in build_class_reference. */
8432 decl = start_decl (name, decl_specs, 1, NULL_TREE);
8433 DECL_CONTEXT (decl) = NULL_TREE;
8434 finish_decl (decl, expr, NULL_TREE);
8439 handle_class_ref (chain)
8442 const char *name = IDENTIFIER_POINTER (TREE_VALUE (chain));
8443 char *string = (char *) alloca (strlen (name) + 30);
8447 sprintf (string, "%sobjc_class_name_%s",
8448 (flag_next_runtime ? "." : "__"), name);
8450 #ifdef ASM_DECLARE_UNRESOLVED_REFERENCE
8451 if (flag_next_runtime)
8453 ASM_DECLARE_UNRESOLVED_REFERENCE (asm_out_file, string);
8458 /* Make a decl for this name, so we can use its address in a tree. */
8459 decl = build_decl (VAR_DECL, get_identifier (string), char_type_node);
8460 DECL_EXTERNAL (decl) = 1;
8461 TREE_PUBLIC (decl) = 1;
8464 rest_of_decl_compilation (decl, 0, 0, 0);
8466 /* Make a decl for the address. */
8467 sprintf (string, "%sobjc_class_ref_%s",
8468 (flag_next_runtime ? "." : "__"), name);
8469 exp = build1 (ADDR_EXPR, string_type_node, decl);
8470 decl = build_decl (VAR_DECL, get_identifier (string), string_type_node);
8471 DECL_INITIAL (decl) = exp;
8472 TREE_STATIC (decl) = 1;
8473 TREE_USED (decl) = 1;
8476 rest_of_decl_compilation (decl, 0, 0, 0);
8480 handle_impent (impent)
8481 struct imp_entry *impent;
8485 objc_implementation_context = impent->imp_context;
8486 implementation_template = impent->imp_template;
8488 if (TREE_CODE (impent->imp_context) == CLASS_IMPLEMENTATION_TYPE)
8490 const char *const class_name =
8491 IDENTIFIER_POINTER (CLASS_NAME (impent->imp_context));
8493 string = (char *) alloca (strlen (class_name) + 30);
8495 sprintf (string, "%sobjc_class_name_%s",
8496 (flag_next_runtime ? "." : "__"), class_name);
8498 else if (TREE_CODE (impent->imp_context) == CATEGORY_IMPLEMENTATION_TYPE)
8500 const char *const class_name =
8501 IDENTIFIER_POINTER (CLASS_NAME (impent->imp_context));
8502 const char *const class_super_name =
8503 IDENTIFIER_POINTER (CLASS_SUPER_NAME (impent->imp_context));
8505 string = (char *) alloca (strlen (class_name)
8506 + strlen (class_super_name) + 30);
8508 /* Do the same for categories. Even though no references to
8509 these symbols are generated automatically by the compiler, it
8510 gives you a handle to pull them into an archive by hand. */
8511 sprintf (string, "*%sobjc_category_name_%s_%s",
8512 (flag_next_runtime ? "." : "__"), class_name, class_super_name);
8517 #ifdef ASM_DECLARE_CLASS_REFERENCE
8518 if (flag_next_runtime)
8520 ASM_DECLARE_CLASS_REFERENCE (asm_out_file, string);
8528 init = build_int_2 (0, 0);
8529 TREE_TYPE (init) = c_common_type_for_size (BITS_PER_WORD, 1);
8530 decl = build_decl (VAR_DECL, get_identifier (string), TREE_TYPE (init));
8531 TREE_PUBLIC (decl) = 1;
8532 TREE_READONLY (decl) = 1;
8533 TREE_USED (decl) = 1;
8534 TREE_CONSTANT (decl) = 1;
8535 DECL_CONTEXT (decl) = 0;
8536 DECL_ARTIFICIAL (decl) = 1;
8537 DECL_INITIAL (decl) = init;
8538 assemble_variable (decl, 1, 0, 0);
8542 /* Look up ID as an instance variable. */
8544 lookup_objc_ivar (id)
8549 if (objc_method_context && !strcmp (IDENTIFIER_POINTER (id), "super"))
8550 /* We have a message to super. */
8551 return get_super_receiver ();
8552 else if (objc_method_context && (decl = is_ivar (objc_ivar_chain, id)))
8554 if (is_private (decl))
8555 return error_mark_node;
8557 return build_ivar_reference (id);
8563 #include "gt-objc-objc-act.h"
8564 #include "gtype-objc.h"