1 /* Implement classes and message passing for Objective C.
2 Copyright (C) 1992, 1993, 1994, 1995, 1997, 1998, 1999, 2000,
3 2001, 2002, 2003 Free Software Foundation, Inc.
4 Contributed by Steve Naroff.
6 This file is part of GCC.
8 GCC is free software; you can redistribute it and/or modify
9 it under the terms of the GNU General Public License as published by
10 the Free Software Foundation; either version 2, or (at your option)
13 GCC is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 GNU General Public License for more details.
18 You should have received a copy of the GNU General Public License
19 along with GCC; see the file COPYING. If not, write to
20 the Free Software Foundation, 59 Temple Place - Suite 330,
21 Boston, MA 02111-1307, USA. */
23 /* Purpose: This module implements the Objective-C 4.0 language.
25 compatibility issues (with the Stepstone translator):
27 - does not recognize the following 3.3 constructs.
28 @requires, @classes, @messages, = (...)
29 - methods with variable arguments must conform to ANSI standard.
30 - tagged structure definitions that appear in BOTH the interface
31 and implementation are not allowed.
32 - public/private: all instance variables are public within the
33 context of the implementation...I consider this to be a bug in
35 - statically allocated objects are not supported. the user will
36 receive an error if this service is requested.
38 code generation `options':
44 #include "coretypes.h"
62 #include "diagnostic.h"
65 /* This is the default way of generating a method name. */
66 /* I am not sure it is really correct.
67 Perhaps there's a danger that it will make name conflicts
68 if method names contain underscores. -- rms. */
69 #ifndef OBJC_GEN_METHOD_LABEL
70 #define OBJC_GEN_METHOD_LABEL(BUF, IS_INST, CLASS_NAME, CAT_NAME, SEL_NAME, NUM) \
73 sprintf ((BUF), "_%s_%s_%s_%s", \
74 ((IS_INST) ? "i" : "c"), \
76 ((CAT_NAME)? (CAT_NAME) : ""), \
78 for (temp = (BUF); *temp; temp++) \
79 if (*temp == ':') *temp = '_'; \
83 /* These need specifying. */
84 #ifndef OBJC_FORWARDING_STACK_OFFSET
85 #define OBJC_FORWARDING_STACK_OFFSET 0
88 #ifndef OBJC_FORWARDING_MIN_OFFSET
89 #define OBJC_FORWARDING_MIN_OFFSET 0
93 /* Set up for use of obstacks. */
97 /* This obstack is used to accumulate the encoding of a data type. */
98 static struct obstack util_obstack;
99 /* This points to the beginning of obstack contents,
100 so we can free the whole contents. */
103 /* for encode_method_def */
106 /* The version identifies which language generation and runtime
107 the module (file) was compiled for, and is recorded in the
108 module descriptor. */
110 #define OBJC_VERSION (flag_next_runtime ? 5 : 8)
111 #define PROTOCOL_VERSION 2
113 /* (Decide if these can ever be validly changed.) */
114 #define OBJC_ENCODE_INLINE_DEFS 0
115 #define OBJC_ENCODE_DONT_INLINE_DEFS 1
117 /*** Private Interface (procedures) ***/
119 /* Used by compile_file. */
121 static void init_objc PARAMS ((void));
122 static void finish_objc PARAMS ((void));
124 /* Code generation. */
126 static void synth_module_prologue PARAMS ((void));
127 static tree objc_build_constructor PARAMS ((tree, tree));
128 static rtx build_module_descriptor PARAMS ((void));
129 static tree init_module_descriptor PARAMS ((tree));
130 static tree build_objc_method_call PARAMS ((int, tree, tree,
132 static void generate_strings PARAMS ((void));
133 static tree get_proto_encoding PARAMS ((tree));
134 static void build_selector_translation_table PARAMS ((void));
136 static tree objc_add_static_instance PARAMS ((tree, tree));
138 static tree build_ivar_template PARAMS ((void));
139 static tree build_method_template PARAMS ((void));
140 static tree build_private_template PARAMS ((tree));
141 static void build_class_template PARAMS ((void));
142 static void build_selector_template PARAMS ((void));
143 static void build_category_template PARAMS ((void));
144 static tree build_super_template PARAMS ((void));
145 static tree build_category_initializer PARAMS ((tree, tree, tree,
147 static tree build_protocol_initializer PARAMS ((tree, tree, tree,
150 static void synth_forward_declarations PARAMS ((void));
151 static void generate_ivar_lists PARAMS ((void));
152 static void generate_dispatch_tables PARAMS ((void));
153 static void generate_shared_structures PARAMS ((void));
154 static tree generate_protocol_list PARAMS ((tree));
155 static void generate_forward_declaration_to_string_table PARAMS ((void));
156 static void build_protocol_reference PARAMS ((tree));
158 static tree build_keyword_selector PARAMS ((tree));
159 static tree synth_id_with_class_suffix PARAMS ((const char *, tree));
161 static void generate_static_references PARAMS ((void));
162 static int check_methods_accessible PARAMS ((tree, tree,
164 static void encode_aggregate_within PARAMS ((tree, int, int,
166 static const char *objc_demangle PARAMS ((const char *));
167 static void objc_expand_function_end PARAMS ((void));
169 /* Hash tables to manage the global pool of method prototypes. */
171 hash *nst_method_hash_list = 0;
172 hash *cls_method_hash_list = 0;
174 static size_t hash_func PARAMS ((tree));
175 static void hash_init PARAMS ((void));
176 static void hash_enter PARAMS ((hash *, tree));
177 static hash hash_lookup PARAMS ((hash *, tree));
178 static void hash_add_attr PARAMS ((hash, tree));
179 static tree lookup_method PARAMS ((tree, tree));
180 static tree lookup_instance_method_static PARAMS ((tree, tree));
181 static tree lookup_class_method_static PARAMS ((tree, tree));
182 static tree add_class PARAMS ((tree));
183 static void add_category PARAMS ((tree, tree));
187 class_names, /* class, category, protocol, module names */
188 meth_var_names, /* method and variable names */
189 meth_var_types /* method and variable type descriptors */
192 static tree add_objc_string PARAMS ((tree,
193 enum string_section));
194 static tree get_objc_string_decl PARAMS ((tree,
195 enum string_section));
196 static tree build_objc_string_decl PARAMS ((enum string_section));
197 static tree build_selector_reference_decl PARAMS ((void));
199 /* Protocol additions. */
201 static tree add_protocol PARAMS ((tree));
202 static tree lookup_protocol PARAMS ((tree));
203 static void check_protocol_recursively PARAMS ((tree, tree));
204 static tree lookup_and_install_protocols PARAMS ((tree));
208 static void encode_type_qualifiers PARAMS ((tree));
209 static void encode_pointer PARAMS ((tree, int, int));
210 static void encode_array PARAMS ((tree, int, int));
211 static void encode_aggregate PARAMS ((tree, int, int));
212 static void encode_bitfield PARAMS ((int));
213 static void encode_type PARAMS ((tree, int, int));
214 static void encode_field_decl PARAMS ((tree, int, int));
216 static void really_start_method PARAMS ((tree, tree));
217 static int comp_method_with_proto PARAMS ((tree, tree));
218 static int comp_proto_with_proto PARAMS ((tree, tree));
219 static tree get_arg_type_list PARAMS ((tree, int, int));
220 static tree objc_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_error ("can't open %s: %m", 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 ("%H'%D' cannot be statically allocated",
919 &DECL_SOURCE_LOCATION (decl), decl);
922 /* Implement static typing. At this point, we know we have an interface. */
925 get_static_reference (interface, protocols)
929 tree type = xref_tag (RECORD_TYPE, interface);
933 tree t, m = TYPE_MAIN_VARIANT (type);
935 t = copy_node (type);
937 /* Add this type to the chain of variants of TYPE. */
938 TYPE_NEXT_VARIANT (t) = TYPE_NEXT_VARIANT (m);
939 TYPE_NEXT_VARIANT (m) = t;
941 /* Look up protocols and install in lang specific list. Note
942 that the protocol list can have a different lifetime than T! */
943 SET_TYPE_PROTOCOL_LIST (t, lookup_and_install_protocols (protocols));
945 /* This forces a new pointer type to be created later
946 (in build_pointer_type)...so that the new template
947 we just created will actually be used...what a hack! */
948 if (TYPE_POINTER_TO (t))
949 TYPE_POINTER_TO (t) = NULL_TREE;
958 get_object_reference (protocols)
961 tree type_decl = lookup_name (objc_id_id);
964 if (type_decl && TREE_CODE (type_decl) == TYPE_DECL)
966 type = TREE_TYPE (type_decl);
967 if (TYPE_MAIN_VARIANT (type) != id_type)
968 warning ("unexpected type for `id' (%s)",
969 gen_declaration (type, errbuf));
973 error ("undefined type `id', please import <objc/objc.h>");
974 return error_mark_node;
977 /* This clause creates a new pointer type that is qualified with
978 the protocol specification...this info is used later to do more
979 elaborate type checking. */
983 tree t, m = TYPE_MAIN_VARIANT (type);
985 t = copy_node (type);
987 /* Add this type to the chain of variants of TYPE. */
988 TYPE_NEXT_VARIANT (t) = TYPE_NEXT_VARIANT (m);
989 TYPE_NEXT_VARIANT (m) = t;
991 /* Look up protocols...and install in lang specific list */
992 SET_TYPE_PROTOCOL_LIST (t, lookup_and_install_protocols (protocols));
994 /* This forces a new pointer type to be created later
995 (in build_pointer_type)...so that the new template
996 we just created will actually be used...what a hack! */
997 if (TYPE_POINTER_TO (t))
998 TYPE_POINTER_TO (t) = NULL_TREE;
1005 /* Check for circular dependencies in protocols. The arguments are
1006 PROTO, the protocol to check, and LIST, a list of protocol it
1010 check_protocol_recursively (proto, list)
1016 for (p = list; p; p = TREE_CHAIN (p))
1018 tree pp = TREE_VALUE (p);
1020 if (TREE_CODE (pp) == IDENTIFIER_NODE)
1021 pp = lookup_protocol (pp);
1024 fatal_error ("protocol `%s' has circular dependency",
1025 IDENTIFIER_POINTER (PROTOCOL_NAME (pp)));
1027 check_protocol_recursively (proto, PROTOCOL_LIST (pp));
1032 lookup_and_install_protocols (protocols)
1037 tree return_value = protocols;
1039 for (proto = protocols; proto; proto = TREE_CHAIN (proto))
1041 tree ident = TREE_VALUE (proto);
1042 tree p = lookup_protocol (ident);
1046 error ("cannot find protocol declaration for `%s'",
1047 IDENTIFIER_POINTER (ident));
1049 TREE_CHAIN (prev) = TREE_CHAIN (proto);
1051 return_value = TREE_CHAIN (proto);
1055 /* Replace identifier with actual protocol node. */
1056 TREE_VALUE (proto) = p;
1061 return return_value;
1064 /* Create and push a decl for a built-in external variable or field NAME.
1066 TYPE is its data type. */
1069 create_builtin_decl (code, type, name)
1070 enum tree_code code;
1074 tree decl = build_decl (code, get_identifier (name), type);
1076 if (code == VAR_DECL)
1078 TREE_STATIC (decl) = 1;
1079 make_decl_rtl (decl, 0);
1083 DECL_ARTIFICIAL (decl) = 1;
1087 /* Find the decl for the constant string class. */
1090 setup_string_decl ()
1092 if (!string_class_decl)
1094 if (!constant_string_global_id)
1095 constant_string_global_id = get_identifier (STRING_OBJECT_GLOBAL_NAME);
1096 string_class_decl = lookup_name (constant_string_global_id);
1100 /* Purpose: "play" parser, creating/installing representations
1101 of the declarations that are required by Objective-C.
1105 type_spec--------->sc_spec
1106 (tree_list) (tree_list)
1109 identifier_node identifier_node */
1112 synth_module_prologue ()
1117 /* Defined in `objc.h' */
1118 objc_object_id = get_identifier (TAG_OBJECT);
1120 objc_object_reference = xref_tag (RECORD_TYPE, objc_object_id);
1122 id_type = build_pointer_type (objc_object_reference);
1124 objc_id_id = get_identifier (TYPE_ID);
1125 objc_class_id = get_identifier (TAG_CLASS);
1127 objc_class_type = build_pointer_type (xref_tag (RECORD_TYPE, objc_class_id));
1128 protocol_type = build_pointer_type (xref_tag (RECORD_TYPE,
1129 get_identifier (PROTOCOL_OBJECT_CLASS_NAME)));
1131 /* Declare type of selector-objects that represent an operation name. */
1133 /* `struct objc_selector *' */
1135 = build_pointer_type (xref_tag (RECORD_TYPE,
1136 get_identifier (TAG_SELECTOR)));
1138 /* Forward declare type, or else the prototype for msgSendSuper will
1141 super_p = build_pointer_type (xref_tag (RECORD_TYPE,
1142 get_identifier (TAG_SUPER)));
1145 /* id objc_msgSend (id, SEL, ...); */
1148 = build_function_type (id_type,
1149 tree_cons (NULL_TREE, id_type,
1150 tree_cons (NULL_TREE, selector_type,
1153 if (! flag_next_runtime)
1155 umsg_decl = build_decl (FUNCTION_DECL,
1156 get_identifier (TAG_MSGSEND), temp_type);
1157 DECL_EXTERNAL (umsg_decl) = 1;
1158 TREE_PUBLIC (umsg_decl) = 1;
1159 DECL_INLINE (umsg_decl) = 1;
1160 DECL_ARTIFICIAL (umsg_decl) = 1;
1162 make_decl_rtl (umsg_decl, NULL);
1163 pushdecl (umsg_decl);
1166 umsg_decl = builtin_function (TAG_MSGSEND, temp_type, 0, NOT_BUILT_IN,
1169 /* id objc_msgSendSuper (struct objc_super *, SEL, ...); */
1172 = build_function_type (id_type,
1173 tree_cons (NULL_TREE, super_p,
1174 tree_cons (NULL_TREE, selector_type,
1177 umsg_super_decl = builtin_function (TAG_MSGSENDSUPER,
1178 temp_type, 0, NOT_BUILT_IN,
1181 /* id objc_getClass (const char *); */
1183 temp_type = build_function_type (id_type,
1184 tree_cons (NULL_TREE,
1185 const_string_type_node,
1186 tree_cons (NULL_TREE, void_type_node,
1190 = builtin_function (TAG_GETCLASS, temp_type, 0, NOT_BUILT_IN,
1193 /* id objc_getMetaClass (const char *); */
1195 objc_get_meta_class_decl
1196 = builtin_function (TAG_GETMETACLASS, temp_type, 0, NOT_BUILT_IN,
1199 /* static SEL _OBJC_SELECTOR_TABLE[]; */
1201 if (! flag_next_runtime)
1203 if (flag_typed_selectors)
1205 /* Suppress outputting debug symbols, because
1206 dbxout_init hasn'r been called yet. */
1207 enum debug_info_type save_write_symbols = write_symbols;
1208 const struct gcc_debug_hooks *const save_hooks = debug_hooks;
1209 write_symbols = NO_DEBUG;
1210 debug_hooks = &do_nothing_debug_hooks;
1212 build_selector_template ();
1213 temp_type = build_array_type (objc_selector_template, NULL_TREE);
1215 write_symbols = save_write_symbols;
1216 debug_hooks = save_hooks;
1219 temp_type = build_array_type (selector_type, NULL_TREE);
1221 layout_type (temp_type);
1222 UOBJC_SELECTOR_TABLE_decl
1223 = create_builtin_decl (VAR_DECL, temp_type,
1224 "_OBJC_SELECTOR_TABLE");
1226 /* Avoid warning when not sending messages. */
1227 TREE_USED (UOBJC_SELECTOR_TABLE_decl) = 1;
1230 generate_forward_declaration_to_string_table ();
1232 /* Forward declare constant_string_id and constant_string_type. */
1233 if (!constant_string_class_name)
1234 constant_string_class_name = default_constant_string_class_name;
1236 constant_string_id = get_identifier (constant_string_class_name);
1237 constant_string_type = xref_tag (RECORD_TYPE, constant_string_id);
1240 /* Predefine the following data type:
1242 struct STRING_OBJECT_CLASS_NAME
1246 unsigned int length;
1250 build_string_class_template ()
1252 tree field_decl, field_decl_chain;
1254 field_decl = create_builtin_decl (FIELD_DECL, id_type, "isa");
1255 field_decl_chain = field_decl;
1257 field_decl = create_builtin_decl (FIELD_DECL,
1258 build_pointer_type (char_type_node),
1260 chainon (field_decl_chain, field_decl);
1262 field_decl = create_builtin_decl (FIELD_DECL, unsigned_type_node, "length");
1263 chainon (field_decl_chain, field_decl);
1265 finish_struct (constant_string_type, field_decl_chain, NULL_TREE);
1268 /* Custom build_string which sets TREE_TYPE! */
1271 my_build_string (len, str)
1275 return fix_string_type (build_string (len, str));
1278 /* Build a static instance of NXConstantString which points at the
1279 string constant STRING.
1280 We place the string object in the __string_objects section of the
1281 __OBJC segment. The Objective-C runtime will initialize the isa
1282 pointers of the string objects to point at the NXConstantString
1286 build_objc_string_object (string)
1289 tree initlist, constructor;
1292 if (lookup_interface (constant_string_id) == NULL_TREE)
1294 error ("cannot find interface declaration for `%s'",
1295 IDENTIFIER_POINTER (constant_string_id));
1296 return error_mark_node;
1299 add_class_reference (constant_string_id);
1301 length = TREE_STRING_LENGTH (string) - 1;
1303 /* We could not properly create NXConstantString in synth_module_prologue,
1304 because that's called before debugging is initialized. Do it now. */
1305 if (TYPE_FIELDS (constant_string_type) == NULL_TREE)
1306 build_string_class_template ();
1308 /* & ((NXConstantString) { NULL, string, length }) */
1310 if (flag_next_runtime)
1312 /* For the NeXT runtime, we can generate a literal reference
1313 to the string class, don't need to run a constructor. */
1314 setup_string_decl ();
1315 if (string_class_decl == NULL_TREE)
1317 error ("cannot find reference tag for class `%s'",
1318 IDENTIFIER_POINTER (constant_string_id));
1319 return error_mark_node;
1321 initlist = build_tree_list
1323 copy_node (build_unary_op (ADDR_EXPR, string_class_decl, 0)));
1327 initlist = build_tree_list (NULL_TREE, build_int_2 (0, 0));
1331 = tree_cons (NULL_TREE, copy_node (build_unary_op (ADDR_EXPR, string, 1)),
1333 initlist = tree_cons (NULL_TREE, build_int_2 (length, 0), initlist);
1334 constructor = objc_build_constructor (constant_string_type,
1335 nreverse (initlist));
1337 if (!flag_next_runtime)
1340 = objc_add_static_instance (constructor, constant_string_type);
1343 return (build_unary_op (ADDR_EXPR, constructor, 1));
1346 /* Declare a static instance of CLASS_DECL initialized by CONSTRUCTOR. */
1348 static GTY(()) int num_static_inst;
1350 objc_add_static_instance (constructor, class_decl)
1351 tree constructor, class_decl;
1356 /* Find the list of static instances for the CLASS_DECL. Create one if
1358 for (chain = &objc_static_instances;
1359 *chain && TREE_VALUE (*chain) != class_decl;
1360 chain = &TREE_CHAIN (*chain));
1363 *chain = tree_cons (NULL_TREE, class_decl, NULL_TREE);
1364 add_objc_string (TYPE_NAME (class_decl), class_names);
1367 sprintf (buf, "_OBJC_INSTANCE_%d", num_static_inst++);
1368 decl = build_decl (VAR_DECL, get_identifier (buf), class_decl);
1369 DECL_COMMON (decl) = 1;
1370 TREE_STATIC (decl) = 1;
1371 DECL_ARTIFICIAL (decl) = 1;
1372 DECL_INITIAL (decl) = constructor;
1374 /* We may be writing something else just now.
1375 Postpone till end of input. */
1376 DECL_DEFER_OUTPUT (decl) = 1;
1377 pushdecl_top_level (decl);
1378 rest_of_decl_compilation (decl, 0, 1, 0);
1380 /* Add the DECL to the head of this CLASS' list. */
1381 TREE_PURPOSE (*chain) = tree_cons (NULL_TREE, decl, TREE_PURPOSE (*chain));
1386 /* Build a static constant CONSTRUCTOR
1387 with type TYPE and elements ELTS. */
1390 objc_build_constructor (type, elts)
1393 tree constructor, f, e;
1395 /* ??? Most of the places that we build constructors, we don't fill in
1396 the type of integers properly. Convert them all en masse. */
1397 if (TREE_CODE (type) == ARRAY_TYPE)
1399 f = TREE_TYPE (type);
1400 if (TREE_CODE (f) == POINTER_TYPE || TREE_CODE (f) == INTEGER_TYPE)
1401 for (e = elts; e ; e = TREE_CHAIN (e))
1402 TREE_VALUE (e) = convert (f, TREE_VALUE (e));
1406 f = TYPE_FIELDS (type);
1407 for (e = elts; e && f; e = TREE_CHAIN (e), f = TREE_CHAIN (f))
1408 if (TREE_CODE (TREE_TYPE (f)) == POINTER_TYPE
1409 || TREE_CODE (TREE_TYPE (f)) == INTEGER_TYPE)
1410 TREE_VALUE (e) = convert (TREE_TYPE (f), TREE_VALUE (e));
1413 constructor = build_constructor (type, elts);
1414 TREE_CONSTANT (constructor) = 1;
1415 TREE_STATIC (constructor) = 1;
1416 TREE_READONLY (constructor) = 1;
1421 /* Take care of defining and initializing _OBJC_SYMBOLS. */
1423 /* Predefine the following data type:
1431 void *defs[cls_def_cnt + cat_def_cnt];
1435 build_objc_symtab_template ()
1437 tree field_decl, field_decl_chain, index;
1439 objc_symtab_template
1440 = start_struct (RECORD_TYPE, get_identifier (UTAG_SYMTAB));
1442 /* long sel_ref_cnt; */
1444 field_decl = create_builtin_decl (FIELD_DECL,
1445 long_integer_type_node,
1447 field_decl_chain = field_decl;
1451 field_decl = create_builtin_decl (FIELD_DECL,
1452 build_pointer_type (selector_type),
1454 chainon (field_decl_chain, field_decl);
1456 /* short cls_def_cnt; */
1458 field_decl = create_builtin_decl (FIELD_DECL,
1459 short_integer_type_node,
1461 chainon (field_decl_chain, field_decl);
1463 /* short cat_def_cnt; */
1465 field_decl = create_builtin_decl (FIELD_DECL,
1466 short_integer_type_node,
1468 chainon (field_decl_chain, field_decl);
1470 /* void *defs[cls_def_cnt + cat_def_cnt]; */
1472 if (!flag_next_runtime)
1473 index = build_index_type (build_int_2 (imp_count + cat_count, 0));
1475 index = build_index_type (build_int_2 (imp_count + cat_count - 1,
1476 imp_count == 0 && cat_count == 0
1478 field_decl = create_builtin_decl (FIELD_DECL,
1479 build_array_type (ptr_type_node, index),
1481 chainon (field_decl_chain, field_decl);
1483 finish_struct (objc_symtab_template, field_decl_chain, NULL_TREE);
1486 /* Create the initial value for the `defs' field of _objc_symtab.
1487 This is a CONSTRUCTOR. */
1490 init_def_list (type)
1493 tree expr, initlist = NULL_TREE;
1494 struct imp_entry *impent;
1497 for (impent = imp_list; impent; impent = impent->next)
1499 if (TREE_CODE (impent->imp_context) == CLASS_IMPLEMENTATION_TYPE)
1501 expr = build_unary_op (ADDR_EXPR, impent->class_decl, 0);
1502 initlist = tree_cons (NULL_TREE, expr, initlist);
1507 for (impent = imp_list; impent; impent = impent->next)
1509 if (TREE_CODE (impent->imp_context) == CATEGORY_IMPLEMENTATION_TYPE)
1511 expr = build_unary_op (ADDR_EXPR, impent->class_decl, 0);
1512 initlist = tree_cons (NULL_TREE, expr, initlist);
1516 if (!flag_next_runtime)
1518 /* statics = { ..., _OBJC_STATIC_INSTANCES, ... } */
1521 if (static_instances_decl)
1522 expr = build_unary_op (ADDR_EXPR, static_instances_decl, 0);
1524 expr = build_int_2 (0, 0);
1526 initlist = tree_cons (NULL_TREE, expr, initlist);
1529 return objc_build_constructor (type, nreverse (initlist));
1532 /* Construct the initial value for all of _objc_symtab. */
1535 init_objc_symtab (type)
1540 /* sel_ref_cnt = { ..., 5, ... } */
1542 initlist = build_tree_list (NULL_TREE, build_int_2 (0, 0));
1544 /* refs = { ..., _OBJC_SELECTOR_TABLE, ... } */
1546 if (flag_next_runtime || ! sel_ref_chain)
1547 initlist = tree_cons (NULL_TREE, build_int_2 (0, 0), initlist);
1549 initlist = tree_cons (NULL_TREE,
1550 build_unary_op (ADDR_EXPR,
1551 UOBJC_SELECTOR_TABLE_decl, 1),
1554 /* cls_def_cnt = { ..., 5, ... } */
1556 initlist = tree_cons (NULL_TREE, build_int_2 (imp_count, 0), initlist);
1558 /* cat_def_cnt = { ..., 5, ... } */
1560 initlist = tree_cons (NULL_TREE, build_int_2 (cat_count, 0), initlist);
1562 /* cls_def = { ..., { &Foo, &Bar, ...}, ... } */
1564 if (imp_count || cat_count || static_instances_decl)
1567 tree field = TYPE_FIELDS (type);
1568 field = TREE_CHAIN (TREE_CHAIN (TREE_CHAIN (TREE_CHAIN (field))));
1570 initlist = tree_cons (NULL_TREE, init_def_list (TREE_TYPE (field)),
1574 return objc_build_constructor (type, nreverse (initlist));
1577 /* Push forward-declarations of all the categories so that
1578 init_def_list can use them in a CONSTRUCTOR. */
1581 forward_declare_categories ()
1583 struct imp_entry *impent;
1584 tree sav = objc_implementation_context;
1586 for (impent = imp_list; impent; impent = impent->next)
1588 if (TREE_CODE (impent->imp_context) == CATEGORY_IMPLEMENTATION_TYPE)
1590 /* Set an invisible arg to synth_id_with_class_suffix. */
1591 objc_implementation_context = impent->imp_context;
1593 = create_builtin_decl (VAR_DECL, objc_category_template,
1594 IDENTIFIER_POINTER (synth_id_with_class_suffix ("_OBJC_CATEGORY", objc_implementation_context)));
1595 TREE_PUBLIC (impent->class_decl) = 0;
1598 objc_implementation_context = sav;
1601 /* Create the declaration of _OBJC_SYMBOLS, with type `strict _objc_symtab'
1602 and initialized appropriately. */
1605 generate_objc_symtab_decl ()
1609 if (!objc_category_template)
1610 build_category_template ();
1612 /* forward declare categories */
1614 forward_declare_categories ();
1616 if (!objc_symtab_template)
1617 build_objc_symtab_template ();
1619 sc_spec = build_tree_list (NULL_TREE, ridpointers[(int) RID_STATIC]);
1621 UOBJC_SYMBOLS_decl = start_decl (get_identifier ("_OBJC_SYMBOLS"),
1622 tree_cons (NULL_TREE,
1623 objc_symtab_template, sc_spec),
1627 TREE_USED (UOBJC_SYMBOLS_decl) = 1;
1628 DECL_IGNORED_P (UOBJC_SYMBOLS_decl) = 1;
1629 DECL_ARTIFICIAL (UOBJC_SYMBOLS_decl) = 1;
1630 finish_decl (UOBJC_SYMBOLS_decl,
1631 init_objc_symtab (TREE_TYPE (UOBJC_SYMBOLS_decl)),
1636 init_module_descriptor (type)
1639 tree initlist, expr;
1641 /* version = { 1, ... } */
1643 expr = build_int_2 (OBJC_VERSION, 0);
1644 initlist = build_tree_list (NULL_TREE, expr);
1646 /* size = { ..., sizeof (struct objc_module), ... } */
1648 expr = size_in_bytes (objc_module_template);
1649 initlist = tree_cons (NULL_TREE, expr, initlist);
1651 /* name = { ..., "foo.m", ... } */
1653 expr = add_objc_string (get_identifier (input_filename), class_names);
1654 initlist = tree_cons (NULL_TREE, expr, initlist);
1656 /* symtab = { ..., _OBJC_SYMBOLS, ... } */
1658 if (UOBJC_SYMBOLS_decl)
1659 expr = build_unary_op (ADDR_EXPR, UOBJC_SYMBOLS_decl, 0);
1661 expr = build_int_2 (0, 0);
1662 initlist = tree_cons (NULL_TREE, expr, initlist);
1664 return objc_build_constructor (type, nreverse (initlist));
1667 /* Write out the data structures to describe Objective C classes defined.
1668 If appropriate, compile and output a setup function to initialize them.
1669 Return a symbol_ref to the function to call to initialize the Objective C
1670 data structures for this file (and perhaps for other files also).
1672 struct objc_module { ... } _OBJC_MODULE = { ... }; */
1675 build_module_descriptor ()
1677 tree decl_specs, field_decl, field_decl_chain;
1679 objc_module_template
1680 = start_struct (RECORD_TYPE, get_identifier (UTAG_MODULE));
1684 decl_specs = build_tree_list (NULL_TREE, ridpointers[(int) RID_LONG]);
1685 field_decl = get_identifier ("version");
1686 field_decl = grokfield (field_decl, decl_specs, NULL_TREE);
1687 field_decl_chain = field_decl;
1691 decl_specs = build_tree_list (NULL_TREE, ridpointers[(int) RID_LONG]);
1692 field_decl = get_identifier ("size");
1693 field_decl = grokfield (field_decl, decl_specs, NULL_TREE);
1694 chainon (field_decl_chain, field_decl);
1698 decl_specs = build_tree_list (NULL_TREE, ridpointers[(int) RID_CHAR]);
1699 field_decl = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("name"));
1700 field_decl = grokfield (field_decl, decl_specs, NULL_TREE);
1701 chainon (field_decl_chain, field_decl);
1703 /* struct objc_symtab *symtab; */
1705 decl_specs = get_identifier (UTAG_SYMTAB);
1706 decl_specs = build_tree_list (NULL_TREE, xref_tag (RECORD_TYPE, decl_specs));
1707 field_decl = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("symtab"));
1708 field_decl = grokfield (field_decl, decl_specs, NULL_TREE);
1709 chainon (field_decl_chain, field_decl);
1711 finish_struct (objc_module_template, field_decl_chain, NULL_TREE);
1713 /* Create an instance of "objc_module". */
1715 decl_specs = tree_cons (NULL_TREE, objc_module_template,
1716 build_tree_list (NULL_TREE,
1717 ridpointers[(int) RID_STATIC]));
1719 UOBJC_MODULES_decl = start_decl (get_identifier ("_OBJC_MODULES"),
1720 decl_specs, 1, NULL_TREE);
1722 DECL_ARTIFICIAL (UOBJC_MODULES_decl) = 1;
1723 DECL_IGNORED_P (UOBJC_MODULES_decl) = 1;
1724 DECL_CONTEXT (UOBJC_MODULES_decl) = NULL_TREE;
1726 finish_decl (UOBJC_MODULES_decl,
1727 init_module_descriptor (TREE_TYPE (UOBJC_MODULES_decl)),
1730 /* Mark the decl to avoid "defined but not used" warning. */
1731 DECL_IN_SYSTEM_HEADER (UOBJC_MODULES_decl) = 1;
1733 /* Generate a constructor call for the module descriptor.
1734 This code was generated by reading the grammar rules
1735 of c-parse.in; Therefore, it may not be the most efficient
1736 way of generating the requisite code. */
1738 if (flag_next_runtime)
1742 tree parms, execclass_decl, decelerator, void_list_node_1;
1743 tree init_function_name, init_function_decl;
1745 /* Declare void __objc_execClass (void *); */
1747 void_list_node_1 = build_tree_list (NULL_TREE, void_type_node);
1748 execclass_decl = build_decl (FUNCTION_DECL,
1749 get_identifier (TAG_EXECCLASS),
1750 build_function_type (void_type_node,
1751 tree_cons (NULL_TREE, ptr_type_node,
1752 void_list_node_1)));
1753 DECL_EXTERNAL (execclass_decl) = 1;
1754 DECL_ARTIFICIAL (execclass_decl) = 1;
1755 TREE_PUBLIC (execclass_decl) = 1;
1756 pushdecl (execclass_decl);
1757 rest_of_decl_compilation (execclass_decl, 0, 0, 0);
1758 assemble_external (execclass_decl);
1760 /* void _GLOBAL_$I$<gnyf> () {objc_execClass (&L_OBJC_MODULES);} */
1762 init_function_name = get_file_function_name ('I');
1763 start_function (void_list_node_1,
1764 build_nt (CALL_EXPR, init_function_name,
1765 tree_cons (NULL_TREE, NULL_TREE,
1769 store_parm_decls ();
1771 init_function_decl = current_function_decl;
1772 TREE_PUBLIC (init_function_decl) = ! targetm.have_ctors_dtors;
1773 TREE_USED (init_function_decl) = 1;
1774 /* Don't let this one be deferred. */
1775 DECL_INLINE (init_function_decl) = 0;
1776 DECL_UNINLINABLE (init_function_decl) = 1;
1777 current_function_cannot_inline
1778 = "static constructors and destructors cannot be inlined";
1781 = build_tree_list (NULL_TREE,
1782 build_unary_op (ADDR_EXPR, UOBJC_MODULES_decl, 0));
1783 decelerator = build_function_call (execclass_decl, parms);
1785 c_expand_expr_stmt (decelerator);
1789 return XEXP (DECL_RTL (init_function_decl), 0);
1793 /* extern const char _OBJC_STRINGS[]; */
1796 generate_forward_declaration_to_string_table ()
1798 tree sc_spec, decl_specs, expr_decl;
1800 sc_spec = tree_cons (NULL_TREE, ridpointers[(int) RID_EXTERN], NULL_TREE);
1801 decl_specs = tree_cons (NULL_TREE, ridpointers[(int) RID_CHAR], sc_spec);
1804 = build_nt (ARRAY_REF, get_identifier ("_OBJC_STRINGS"), NULL_TREE);
1806 UOBJC_STRINGS_decl = define_decl (expr_decl, decl_specs);
1809 /* Return the DECL of the string IDENT in the SECTION. */
1812 get_objc_string_decl (ident, section)
1814 enum string_section section;
1818 if (section == class_names)
1819 chain = class_names_chain;
1820 else if (section == meth_var_names)
1821 chain = meth_var_names_chain;
1822 else if (section == meth_var_types)
1823 chain = meth_var_types_chain;
1827 for (; chain != 0; chain = TREE_CHAIN (chain))
1828 if (TREE_VALUE (chain) == ident)
1829 return (TREE_PURPOSE (chain));
1835 /* Output references to all statically allocated objects. Return the DECL
1836 for the array built. */
1839 generate_static_references ()
1841 tree decls = NULL_TREE, ident, decl_spec, expr_decl, expr = NULL_TREE;
1842 tree class_name, class, decl, initlist;
1843 tree cl_chain, in_chain, type;
1844 int num_inst, num_class;
1847 if (flag_next_runtime)
1850 for (cl_chain = objc_static_instances, num_class = 0;
1851 cl_chain; cl_chain = TREE_CHAIN (cl_chain), num_class++)
1853 for (num_inst = 0, in_chain = TREE_PURPOSE (cl_chain);
1854 in_chain; num_inst++, in_chain = TREE_CHAIN (in_chain));
1856 sprintf (buf, "_OBJC_STATIC_INSTANCES_%d", num_class);
1857 ident = get_identifier (buf);
1859 expr_decl = build_nt (ARRAY_REF, ident, NULL_TREE);
1860 decl_spec = tree_cons (NULL_TREE, build_pointer_type (void_type_node),
1861 build_tree_list (NULL_TREE,
1862 ridpointers[(int) RID_STATIC]));
1863 decl = start_decl (expr_decl, decl_spec, 1, NULL_TREE);
1864 DECL_CONTEXT (decl) = 0;
1865 DECL_ARTIFICIAL (decl) = 1;
1867 /* Output {class_name, ...}. */
1868 class = TREE_VALUE (cl_chain);
1869 class_name = get_objc_string_decl (TYPE_NAME (class), class_names);
1870 initlist = build_tree_list (NULL_TREE,
1871 build_unary_op (ADDR_EXPR, class_name, 1));
1873 /* Output {..., instance, ...}. */
1874 for (in_chain = TREE_PURPOSE (cl_chain);
1875 in_chain; in_chain = TREE_CHAIN (in_chain))
1877 expr = build_unary_op (ADDR_EXPR, TREE_VALUE (in_chain), 1);
1878 initlist = tree_cons (NULL_TREE, expr, initlist);
1881 /* Output {..., NULL}. */
1882 initlist = tree_cons (NULL_TREE, build_int_2 (0, 0), initlist);
1884 expr = objc_build_constructor (TREE_TYPE (decl), nreverse (initlist));
1885 finish_decl (decl, expr, NULL_TREE);
1886 TREE_USED (decl) = 1;
1888 type = build_array_type (build_pointer_type (void_type_node), 0);
1889 decl = build_decl (VAR_DECL, ident, type);
1890 TREE_USED (decl) = 1;
1891 TREE_STATIC (decl) = 1;
1893 = tree_cons (NULL_TREE, build_unary_op (ADDR_EXPR, decl, 1), decls);
1896 decls = tree_cons (NULL_TREE, build_int_2 (0, 0), decls);
1897 ident = get_identifier ("_OBJC_STATIC_INSTANCES");
1898 expr_decl = build_nt (ARRAY_REF, ident, NULL_TREE);
1899 decl_spec = tree_cons (NULL_TREE, build_pointer_type (void_type_node),
1900 build_tree_list (NULL_TREE,
1901 ridpointers[(int) RID_STATIC]));
1902 static_instances_decl
1903 = start_decl (expr_decl, decl_spec, 1, NULL_TREE);
1904 TREE_USED (static_instances_decl) = 1;
1905 DECL_CONTEXT (static_instances_decl) = 0;
1906 DECL_ARTIFICIAL (static_instances_decl) = 1;
1907 expr = objc_build_constructor (TREE_TYPE (static_instances_decl),
1909 finish_decl (static_instances_decl, expr, NULL_TREE);
1912 /* Output all strings. */
1917 tree sc_spec, decl_specs, expr_decl;
1918 tree chain, string_expr;
1921 for (chain = class_names_chain; chain; chain = TREE_CHAIN (chain))
1923 string = TREE_VALUE (chain);
1924 decl = TREE_PURPOSE (chain);
1926 = tree_cons (NULL_TREE, ridpointers[(int) RID_STATIC], NULL_TREE);
1927 decl_specs = tree_cons (NULL_TREE, ridpointers[(int) RID_CHAR], sc_spec);
1928 expr_decl = build_nt (ARRAY_REF, DECL_NAME (decl), NULL_TREE);
1929 decl = start_decl (expr_decl, decl_specs, 1, NULL_TREE);
1930 DECL_CONTEXT (decl) = NULL_TREE;
1931 string_expr = my_build_string (IDENTIFIER_LENGTH (string) + 1,
1932 IDENTIFIER_POINTER (string));
1933 finish_decl (decl, string_expr, NULL_TREE);
1936 for (chain = meth_var_names_chain; chain; chain = TREE_CHAIN (chain))
1938 string = TREE_VALUE (chain);
1939 decl = TREE_PURPOSE (chain);
1941 = tree_cons (NULL_TREE, ridpointers[(int) RID_STATIC], NULL_TREE);
1942 decl_specs = tree_cons (NULL_TREE, ridpointers[(int) RID_CHAR], sc_spec);
1943 expr_decl = build_nt (ARRAY_REF, DECL_NAME (decl), NULL_TREE);
1944 decl = start_decl (expr_decl, decl_specs, 1, NULL_TREE);
1945 DECL_CONTEXT (decl) = NULL_TREE;
1946 string_expr = my_build_string (IDENTIFIER_LENGTH (string) + 1,
1947 IDENTIFIER_POINTER (string));
1948 finish_decl (decl, string_expr, NULL_TREE);
1951 for (chain = meth_var_types_chain; chain; chain = TREE_CHAIN (chain))
1953 string = TREE_VALUE (chain);
1954 decl = TREE_PURPOSE (chain);
1956 = tree_cons (NULL_TREE, ridpointers[(int) RID_STATIC], NULL_TREE);
1957 decl_specs = tree_cons (NULL_TREE, ridpointers[(int) RID_CHAR], sc_spec);
1958 expr_decl = build_nt (ARRAY_REF, DECL_NAME (decl), NULL_TREE);
1959 decl = start_decl (expr_decl, decl_specs, 1, NULL_TREE);
1960 DECL_CONTEXT (decl) = NULL_TREE;
1961 string_expr = my_build_string (IDENTIFIER_LENGTH (string) + 1,
1962 IDENTIFIER_POINTER (string));
1963 finish_decl (decl, string_expr, NULL_TREE);
1967 static GTY(()) int selector_reference_idx;
1969 build_selector_reference_decl ()
1974 sprintf (buf, "_OBJC_SELECTOR_REFERENCES_%d", selector_reference_idx++);
1976 ident = get_identifier (buf);
1978 decl = build_decl (VAR_DECL, ident, selector_type);
1979 DECL_EXTERNAL (decl) = 1;
1980 TREE_PUBLIC (decl) = 0;
1981 TREE_USED (decl) = 1;
1982 TREE_READONLY (decl) = 1;
1983 DECL_ARTIFICIAL (decl) = 1;
1984 DECL_CONTEXT (decl) = 0;
1986 make_decl_rtl (decl, 0);
1987 pushdecl_top_level (decl);
1992 /* Just a handy wrapper for add_objc_string. */
1995 build_selector (ident)
1998 tree expr = add_objc_string (ident, meth_var_names);
1999 if (flag_typed_selectors)
2002 return build_c_cast (selector_type, expr); /* cast! */
2006 build_selector_translation_table ()
2008 tree sc_spec, decl_specs;
2009 tree chain, initlist = NULL_TREE;
2011 tree decl = NULL_TREE, var_decl, name;
2013 for (chain = sel_ref_chain; chain; chain = TREE_CHAIN (chain))
2017 if (warn_selector && objc_implementation_context)
2021 for (method_chain = meth_var_names_chain;
2023 method_chain = TREE_CHAIN (method_chain))
2025 if (TREE_VALUE (method_chain) == TREE_VALUE (chain))
2033 /* Adjust line number for warning message. */
2034 int save_lineno = input_line;
2035 if (flag_next_runtime && TREE_PURPOSE (chain))
2036 input_line = DECL_SOURCE_LINE (TREE_PURPOSE (chain));
2037 warning ("creating selector for non existant method %s",
2038 IDENTIFIER_POINTER (TREE_VALUE (chain)));
2039 input_line = save_lineno;
2043 expr = build_selector (TREE_VALUE (chain));
2045 if (flag_next_runtime)
2047 name = DECL_NAME (TREE_PURPOSE (chain));
2049 sc_spec = build_tree_list (NULL_TREE, ridpointers[(int) RID_STATIC]);
2051 /* static SEL _OBJC_SELECTOR_REFERENCES_n = ...; */
2052 decl_specs = tree_cons (NULL_TREE, selector_type, sc_spec);
2056 /* The `decl' that is returned from start_decl is the one that we
2057 forward declared in `build_selector_reference' */
2058 decl = start_decl (var_decl, decl_specs, 1, NULL_TREE );
2061 /* add one for the '\0' character */
2062 offset += IDENTIFIER_LENGTH (TREE_VALUE (chain)) + 1;
2064 if (flag_next_runtime)
2065 finish_decl (decl, expr, NULL_TREE);
2068 if (flag_typed_selectors)
2070 tree eltlist = NULL_TREE;
2071 tree encoding = get_proto_encoding (TREE_PURPOSE (chain));
2072 eltlist = tree_cons (NULL_TREE, expr, NULL_TREE);
2073 eltlist = tree_cons (NULL_TREE, encoding, eltlist);
2074 expr = objc_build_constructor (objc_selector_template,
2075 nreverse (eltlist));
2077 initlist = tree_cons (NULL_TREE, expr, initlist);
2082 if (! flag_next_runtime)
2084 /* Cause the variable and its initial value to be actually output. */
2085 DECL_EXTERNAL (UOBJC_SELECTOR_TABLE_decl) = 0;
2086 TREE_STATIC (UOBJC_SELECTOR_TABLE_decl) = 1;
2087 /* NULL terminate the list and fix the decl for output. */
2088 initlist = tree_cons (NULL_TREE, build_int_2 (0, 0), initlist);
2089 DECL_INITIAL (UOBJC_SELECTOR_TABLE_decl) = objc_ellipsis_node;
2090 initlist = objc_build_constructor (TREE_TYPE (UOBJC_SELECTOR_TABLE_decl),
2091 nreverse (initlist));
2092 finish_decl (UOBJC_SELECTOR_TABLE_decl, initlist, NULL_TREE);
2093 current_function_decl = NULL_TREE;
2098 get_proto_encoding (proto)
2106 if (! METHOD_ENCODING (proto))
2108 tmp_decl = build_tmp_function_decl ();
2109 hack_method_prototype (proto, tmp_decl);
2110 encoding = encode_method_prototype (proto, tmp_decl);
2111 METHOD_ENCODING (proto) = encoding;
2114 encoding = METHOD_ENCODING (proto);
2116 return add_objc_string (encoding, meth_var_types);
2119 return build_int_2 (0, 0);
2122 /* sel_ref_chain is a list whose "value" fields will be instances of
2123 identifier_node that represent the selector. */
2126 build_typed_selector_reference (ident, prototype)
2127 tree ident, prototype;
2129 tree *chain = &sel_ref_chain;
2135 if (TREE_PURPOSE (*chain) == prototype && TREE_VALUE (*chain) == ident)
2136 goto return_at_index;
2139 chain = &TREE_CHAIN (*chain);
2142 *chain = tree_cons (prototype, ident, NULL_TREE);
2145 expr = build_unary_op (ADDR_EXPR,
2146 build_array_ref (UOBJC_SELECTOR_TABLE_decl,
2147 build_int_2 (index, 0)),
2149 return build_c_cast (selector_type, expr);
2153 build_selector_reference (ident)
2156 tree *chain = &sel_ref_chain;
2162 if (TREE_VALUE (*chain) == ident)
2163 return (flag_next_runtime
2164 ? TREE_PURPOSE (*chain)
2165 : build_array_ref (UOBJC_SELECTOR_TABLE_decl,
2166 build_int_2 (index, 0)));
2169 chain = &TREE_CHAIN (*chain);
2172 expr = build_selector_reference_decl ();
2174 *chain = tree_cons (expr, ident, NULL_TREE);
2176 return (flag_next_runtime
2178 : build_array_ref (UOBJC_SELECTOR_TABLE_decl,
2179 build_int_2 (index, 0)));
2182 static GTY(()) int class_reference_idx;
2184 build_class_reference_decl ()
2189 sprintf (buf, "_OBJC_CLASS_REFERENCES_%d", class_reference_idx++);
2191 ident = get_identifier (buf);
2193 decl = build_decl (VAR_DECL, ident, objc_class_type);
2194 DECL_EXTERNAL (decl) = 1;
2195 TREE_PUBLIC (decl) = 0;
2196 TREE_USED (decl) = 1;
2197 TREE_READONLY (decl) = 1;
2198 DECL_CONTEXT (decl) = 0;
2199 DECL_ARTIFICIAL (decl) = 1;
2201 make_decl_rtl (decl, 0);
2202 pushdecl_top_level (decl);
2207 /* Create a class reference, but don't create a variable to reference
2211 add_class_reference (ident)
2216 if ((chain = cls_ref_chain))
2221 if (ident == TREE_VALUE (chain))
2225 chain = TREE_CHAIN (chain);
2229 /* Append to the end of the list */
2230 TREE_CHAIN (tail) = tree_cons (NULL_TREE, ident, NULL_TREE);
2233 cls_ref_chain = tree_cons (NULL_TREE, ident, NULL_TREE);
2236 /* Get a class reference, creating it if necessary. Also create the
2237 reference variable. */
2240 get_class_reference (ident)
2243 if (flag_next_runtime)
2248 for (chain = &cls_ref_chain; *chain; chain = &TREE_CHAIN (*chain))
2249 if (TREE_VALUE (*chain) == ident)
2251 if (! TREE_PURPOSE (*chain))
2252 TREE_PURPOSE (*chain) = build_class_reference_decl ();
2254 return TREE_PURPOSE (*chain);
2257 decl = build_class_reference_decl ();
2258 *chain = tree_cons (decl, ident, NULL_TREE);
2265 add_class_reference (ident);
2267 params = build_tree_list (NULL_TREE,
2268 my_build_string (IDENTIFIER_LENGTH (ident) + 1,
2269 IDENTIFIER_POINTER (ident)));
2271 assemble_external (objc_get_class_decl);
2272 return build_function_call (objc_get_class_decl, params);
2276 /* For each string section we have a chain which maps identifier nodes
2277 to decls for the strings. */
2280 add_objc_string (ident, section)
2282 enum string_section section;
2286 if (section == class_names)
2287 chain = &class_names_chain;
2288 else if (section == meth_var_names)
2289 chain = &meth_var_names_chain;
2290 else if (section == meth_var_types)
2291 chain = &meth_var_types_chain;
2297 if (TREE_VALUE (*chain) == ident)
2298 return build_unary_op (ADDR_EXPR, TREE_PURPOSE (*chain), 1);
2300 chain = &TREE_CHAIN (*chain);
2303 decl = build_objc_string_decl (section);
2305 *chain = tree_cons (decl, ident, NULL_TREE);
2307 return build_unary_op (ADDR_EXPR, decl, 1);
2310 static GTY(()) int class_names_idx;
2311 static GTY(()) int meth_var_names_idx;
2312 static GTY(()) int meth_var_types_idx;
2315 build_objc_string_decl (section)
2316 enum string_section section;
2321 if (section == class_names)
2322 sprintf (buf, "_OBJC_CLASS_NAME_%d", class_names_idx++);
2323 else if (section == meth_var_names)
2324 sprintf (buf, "_OBJC_METH_VAR_NAME_%d", meth_var_names_idx++);
2325 else if (section == meth_var_types)
2326 sprintf (buf, "_OBJC_METH_VAR_TYPE_%d", meth_var_types_idx++);
2328 ident = get_identifier (buf);
2330 decl = build_decl (VAR_DECL, ident, build_array_type (char_type_node, 0));
2331 DECL_EXTERNAL (decl) = 1;
2332 TREE_PUBLIC (decl) = 0;
2333 TREE_USED (decl) = 1;
2334 TREE_READONLY (decl) = 1;
2335 TREE_CONSTANT (decl) = 1;
2336 DECL_CONTEXT (decl) = 0;
2337 DECL_ARTIFICIAL (decl) = 1;
2339 make_decl_rtl (decl, 0);
2340 pushdecl_top_level (decl);
2347 objc_declare_alias (alias_ident, class_ident)
2351 if (is_class_name (class_ident) != class_ident)
2352 warning ("cannot find class `%s'", IDENTIFIER_POINTER (class_ident));
2353 else if (is_class_name (alias_ident))
2354 warning ("class `%s' already exists", IDENTIFIER_POINTER (alias_ident));
2356 alias_chain = tree_cons (class_ident, alias_ident, alias_chain);
2360 objc_declare_class (ident_list)
2365 for (list = ident_list; list; list = TREE_CHAIN (list))
2367 tree ident = TREE_VALUE (list);
2370 if ((decl = lookup_name (ident)))
2372 error ("`%s' redeclared as different kind of symbol",
2373 IDENTIFIER_POINTER (ident));
2374 error ("%Hprevious declaration of '%D'",
2375 &DECL_SOURCE_LOCATION (decl), decl);
2378 if (! is_class_name (ident))
2380 tree record = xref_tag (RECORD_TYPE, ident);
2381 TREE_STATIC_TEMPLATE (record) = 1;
2382 class_chain = tree_cons (NULL_TREE, ident, class_chain);
2388 is_class_name (ident)
2393 if (lookup_interface (ident))
2396 for (chain = class_chain; chain; chain = TREE_CHAIN (chain))
2398 if (ident == TREE_VALUE (chain))
2402 for (chain = alias_chain; chain; chain = TREE_CHAIN (chain))
2404 if (ident == TREE_VALUE (chain))
2405 return TREE_PURPOSE (chain);
2415 /* NB: This function may be called before the ObjC front-end
2416 has been initialized, in which case ID_TYPE will be NULL. */
2417 return (id_type && ident && TYPE_P (ident) && IS_ID (ident))
2423 lookup_interface (ident)
2428 for (chain = interface_chain; chain; chain = TREE_CHAIN (chain))
2430 if (ident == CLASS_NAME (chain))
2436 /* Used by: build_private_template, continue_class,
2437 and for @defs constructs. */
2440 get_class_ivars (interface)
2443 tree my_name, super_name, ivar_chain;
2445 my_name = CLASS_NAME (interface);
2446 super_name = CLASS_SUPER_NAME (interface);
2447 ivar_chain = CLASS_IVARS (interface);
2449 /* Save off a pristine copy of the leaf ivars (i.e, those not
2450 inherited from a super class). */
2451 if (!CLASS_OWN_IVARS (interface))
2452 CLASS_OWN_IVARS (interface) = copy_list (ivar_chain);
2457 tree super_interface = lookup_interface (super_name);
2459 if (!super_interface)
2461 /* fatal did not work with 2 args...should fix */
2462 error ("cannot find interface declaration for `%s', superclass of `%s'",
2463 IDENTIFIER_POINTER (super_name),
2464 IDENTIFIER_POINTER (my_name));
2465 exit (FATAL_EXIT_CODE);
2468 if (super_interface == interface)
2469 fatal_error ("circular inheritance in interface declaration for `%s'",
2470 IDENTIFIER_POINTER (super_name));
2472 interface = super_interface;
2473 my_name = CLASS_NAME (interface);
2474 super_name = CLASS_SUPER_NAME (interface);
2476 op1 = CLASS_OWN_IVARS (interface);
2479 tree head = copy_list (op1);
2481 /* Prepend super class ivars...make a copy of the list, we
2482 do not want to alter the original. */
2483 chainon (head, ivar_chain);
2490 /* struct <classname> {
2491 struct objc_class *isa;
2496 build_private_template (class)
2501 if (CLASS_STATIC_TEMPLATE (class))
2503 uprivate_record = CLASS_STATIC_TEMPLATE (class);
2504 ivar_context = TYPE_FIELDS (CLASS_STATIC_TEMPLATE (class));
2508 uprivate_record = start_struct (RECORD_TYPE, CLASS_NAME (class));
2510 ivar_context = get_class_ivars (class);
2512 finish_struct (uprivate_record, ivar_context, NULL_TREE);
2514 CLASS_STATIC_TEMPLATE (class) = uprivate_record;
2516 /* mark this record as class template - for class type checking */
2517 TREE_STATIC_TEMPLATE (uprivate_record) = 1;
2521 = groktypename (build_tree_list (build_tree_list (NULL_TREE,
2523 build1 (INDIRECT_REF, NULL_TREE,
2526 return ivar_context;
2529 /* Begin code generation for protocols... */
2531 /* struct objc_protocol {
2532 char *protocol_name;
2533 struct objc_protocol **protocol_list;
2534 struct objc_method_desc *instance_methods;
2535 struct objc_method_desc *class_methods;
2539 build_protocol_template ()
2541 tree decl_specs, field_decl, field_decl_chain;
2544 template = start_struct (RECORD_TYPE, get_identifier (UTAG_PROTOCOL));
2546 /* struct objc_class *isa; */
2548 decl_specs = build_tree_list (NULL_TREE, xref_tag (RECORD_TYPE,
2549 get_identifier (UTAG_CLASS)));
2550 field_decl = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("isa"));
2551 field_decl = grokfield (field_decl, decl_specs, NULL_TREE);
2552 field_decl_chain = field_decl;
2554 /* char *protocol_name; */
2556 decl_specs = build_tree_list (NULL_TREE, ridpointers[(int) RID_CHAR]);
2558 = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("protocol_name"));
2559 field_decl = grokfield (field_decl, decl_specs, NULL_TREE);
2560 chainon (field_decl_chain, field_decl);
2562 /* struct objc_protocol **protocol_list; */
2564 decl_specs = build_tree_list (NULL_TREE, template);
2566 = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("protocol_list"));
2567 field_decl = build1 (INDIRECT_REF, NULL_TREE, field_decl);
2568 field_decl = grokfield (field_decl, decl_specs, NULL_TREE);
2569 chainon (field_decl_chain, field_decl);
2571 /* struct objc_method_list *instance_methods; */
2574 = build_tree_list (NULL_TREE,
2575 xref_tag (RECORD_TYPE,
2576 get_identifier (UTAG_METHOD_PROTOTYPE_LIST)));
2578 = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("instance_methods"));
2579 field_decl = grokfield (field_decl, decl_specs, NULL_TREE);
2580 chainon (field_decl_chain, field_decl);
2582 /* struct objc_method_list *class_methods; */
2585 = build_tree_list (NULL_TREE,
2586 xref_tag (RECORD_TYPE,
2587 get_identifier (UTAG_METHOD_PROTOTYPE_LIST)));
2589 = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("class_methods"));
2590 field_decl = grokfield (field_decl, decl_specs, NULL_TREE);
2591 chainon (field_decl_chain, field_decl);
2593 return finish_struct (template, field_decl_chain, NULL_TREE);
2597 build_descriptor_table_initializer (type, entries)
2601 tree initlist = NULL_TREE;
2605 tree eltlist = NULL_TREE;
2608 = tree_cons (NULL_TREE,
2609 build_selector (METHOD_SEL_NAME (entries)), NULL_TREE);
2611 = tree_cons (NULL_TREE,
2612 add_objc_string (METHOD_ENCODING (entries),
2617 = tree_cons (NULL_TREE,
2618 objc_build_constructor (type, nreverse (eltlist)),
2621 entries = TREE_CHAIN (entries);
2625 return objc_build_constructor (build_array_type (type, 0),
2626 nreverse (initlist));
2629 /* struct objc_method_prototype_list {
2631 struct objc_method_prototype {
2638 build_method_prototype_list_template (list_type, size)
2642 tree objc_ivar_list_record;
2643 tree decl_specs, field_decl, field_decl_chain;
2645 /* Generate an unnamed struct definition. */
2647 objc_ivar_list_record = start_struct (RECORD_TYPE, NULL_TREE);
2649 /* int method_count; */
2651 decl_specs = build_tree_list (NULL_TREE, ridpointers[(int) RID_INT]);
2652 field_decl = get_identifier ("method_count");
2653 field_decl = grokfield (field_decl, decl_specs, NULL_TREE);
2654 field_decl_chain = field_decl;
2656 /* struct objc_method method_list[]; */
2658 decl_specs = build_tree_list (NULL_TREE, list_type);
2659 field_decl = build_nt (ARRAY_REF, get_identifier ("method_list"),
2660 build_int_2 (size, 0));
2661 field_decl = grokfield (field_decl, decl_specs, NULL_TREE);
2662 chainon (field_decl_chain, field_decl);
2664 finish_struct (objc_ivar_list_record, field_decl_chain, NULL_TREE);
2666 return objc_ivar_list_record;
2670 build_method_prototype_template ()
2673 tree decl_specs, field_decl, field_decl_chain;
2676 = start_struct (RECORD_TYPE, get_identifier (UTAG_METHOD_PROTOTYPE));
2678 /* struct objc_selector *_cmd; */
2679 decl_specs = tree_cons (NULL_TREE, xref_tag (RECORD_TYPE,
2680 get_identifier (TAG_SELECTOR)), NULL_TREE);
2681 field_decl = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("_cmd"));
2682 field_decl = grokfield (field_decl, decl_specs, NULL_TREE);
2683 field_decl_chain = field_decl;
2685 decl_specs = tree_cons (NULL_TREE, ridpointers[(int) RID_CHAR], NULL_TREE);
2687 = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("method_types"));
2688 field_decl = grokfield (field_decl, decl_specs, NULL_TREE);
2689 chainon (field_decl_chain, field_decl);
2691 finish_struct (proto_record, field_decl_chain, NULL_TREE);
2693 return proto_record;
2696 /* True if last call to forwarding_offset yielded a register offset. */
2697 static int offset_is_register;
2700 forwarding_offset (parm)
2703 int offset_in_bytes;
2705 if (GET_CODE (DECL_INCOMING_RTL (parm)) == MEM)
2707 rtx addr = XEXP (DECL_INCOMING_RTL (parm), 0);
2709 /* ??? Here we assume that the parm address is indexed
2710 off the frame pointer or arg pointer.
2711 If that is not true, we produce meaningless results,
2712 but do not crash. */
2713 if (GET_CODE (addr) == PLUS
2714 && GET_CODE (XEXP (addr, 1)) == CONST_INT)
2715 offset_in_bytes = INTVAL (XEXP (addr, 1));
2717 offset_in_bytes = 0;
2719 offset_in_bytes += OBJC_FORWARDING_STACK_OFFSET;
2720 offset_is_register = 0;
2722 else if (GET_CODE (DECL_INCOMING_RTL (parm)) == REG)
2724 int regno = REGNO (DECL_INCOMING_RTL (parm));
2725 offset_in_bytes = apply_args_register_offset (regno);
2726 offset_is_register = 1;
2731 /* This is the case where the parm is passed as an int or double
2732 and it is converted to a char, short or float and stored back
2733 in the parmlist. In this case, describe the parm
2734 with the variable's declared type, and adjust the address
2735 if the least significant bytes (which we are using) are not
2737 if (BYTES_BIG_ENDIAN && TREE_TYPE (parm) != DECL_ARG_TYPE (parm))
2738 offset_in_bytes += (GET_MODE_SIZE (TYPE_MODE (DECL_ARG_TYPE (parm)))
2739 - GET_MODE_SIZE (GET_MODE (DECL_RTL (parm))));
2741 return offset_in_bytes;
2745 encode_method_prototype (method_decl, func_decl)
2752 HOST_WIDE_INT max_parm_end = 0;
2756 /* ONEWAY and BYCOPY, for remote object are the only method qualifiers. */
2757 encode_type_qualifiers (TREE_PURPOSE (TREE_TYPE (method_decl)));
2760 encode_type (TREE_TYPE (TREE_TYPE (func_decl)),
2761 obstack_object_size (&util_obstack),
2762 OBJC_ENCODE_INLINE_DEFS);
2765 for (parms = DECL_ARGUMENTS (func_decl); parms;
2766 parms = TREE_CHAIN (parms))
2768 HOST_WIDE_INT parm_end = (forwarding_offset (parms)
2769 + int_size_in_bytes (TREE_TYPE (parms)));
2771 if (!offset_is_register && max_parm_end < parm_end)
2772 max_parm_end = parm_end;
2775 stack_size = max_parm_end - OBJC_FORWARDING_MIN_OFFSET;
2777 sprintf (buf, "%d", stack_size);
2778 obstack_grow (&util_obstack, buf, strlen (buf));
2780 user_args = METHOD_SEL_ARGS (method_decl);
2782 /* Argument types. */
2783 for (parms = DECL_ARGUMENTS (func_decl), i = 0; parms;
2784 parms = TREE_CHAIN (parms), i++)
2786 /* Process argument qualifiers for user supplied arguments. */
2789 encode_type_qualifiers (TREE_PURPOSE (TREE_TYPE (user_args)));
2790 user_args = TREE_CHAIN (user_args);
2794 encode_type (TREE_TYPE (parms),
2795 obstack_object_size (&util_obstack),
2796 OBJC_ENCODE_INLINE_DEFS);
2798 /* Compute offset. */
2799 sprintf (buf, "%d", forwarding_offset (parms));
2801 /* Indicate register. */
2802 if (offset_is_register)
2803 obstack_1grow (&util_obstack, '+');
2805 obstack_grow (&util_obstack, buf, strlen (buf));
2808 obstack_1grow (&util_obstack, '\0');
2809 result = get_identifier (obstack_finish (&util_obstack));
2810 obstack_free (&util_obstack, util_firstobj);
2815 generate_descriptor_table (type, name, size, list, proto)
2822 tree sc_spec, decl_specs, decl, initlist;
2824 sc_spec = tree_cons (NULL_TREE, ridpointers[(int) RID_STATIC], NULL_TREE);
2825 decl_specs = tree_cons (NULL_TREE, type, sc_spec);
2827 decl = start_decl (synth_id_with_class_suffix (name, proto),
2828 decl_specs, 1, NULL_TREE);
2829 DECL_CONTEXT (decl) = NULL_TREE;
2831 initlist = build_tree_list (NULL_TREE, build_int_2 (size, 0));
2832 initlist = tree_cons (NULL_TREE, list, initlist);
2834 finish_decl (decl, objc_build_constructor (type, nreverse (initlist)),
2841 generate_method_descriptors (protocol)
2844 tree initlist, chain, method_list_template;
2845 tree cast, variable_length_type;
2848 if (!objc_method_prototype_template)
2849 objc_method_prototype_template = build_method_prototype_template ();
2851 cast = build_tree_list (build_tree_list (NULL_TREE, xref_tag (RECORD_TYPE,
2852 get_identifier (UTAG_METHOD_PROTOTYPE_LIST))),
2854 variable_length_type = groktypename (cast);
2856 chain = PROTOCOL_CLS_METHODS (protocol);
2859 size = list_length (chain);
2861 method_list_template
2862 = build_method_prototype_list_template (objc_method_prototype_template,
2866 = build_descriptor_table_initializer (objc_method_prototype_template,
2869 UOBJC_CLASS_METHODS_decl
2870 = generate_descriptor_table (method_list_template,
2871 "_OBJC_PROTOCOL_CLASS_METHODS",
2872 size, initlist, protocol);
2873 TREE_TYPE (UOBJC_CLASS_METHODS_decl) = variable_length_type;
2876 UOBJC_CLASS_METHODS_decl = 0;
2878 chain = PROTOCOL_NST_METHODS (protocol);
2881 size = list_length (chain);
2883 method_list_template
2884 = build_method_prototype_list_template (objc_method_prototype_template,
2887 = build_descriptor_table_initializer (objc_method_prototype_template,
2890 UOBJC_INSTANCE_METHODS_decl
2891 = generate_descriptor_table (method_list_template,
2892 "_OBJC_PROTOCOL_INSTANCE_METHODS",
2893 size, initlist, protocol);
2894 TREE_TYPE (UOBJC_INSTANCE_METHODS_decl) = variable_length_type;
2897 UOBJC_INSTANCE_METHODS_decl = 0;
2900 /* Generate a temporary FUNCTION_DECL node to be used in
2901 hack_method_prototype below. */
2903 static GTY(()) int build_tmp_function_decl_xxx;
2905 build_tmp_function_decl ()
2907 tree decl_specs, expr_decl, parms;
2911 /* struct objc_object *objc_xxx (id, SEL, ...); */
2913 decl_specs = build_tree_list (NULL_TREE, objc_object_reference);
2914 push_parm_decl (build_tree_list
2915 (build_tree_list (decl_specs,
2916 build1 (INDIRECT_REF, NULL_TREE,
2920 decl_specs = build_tree_list (NULL_TREE, xref_tag (RECORD_TYPE,
2921 get_identifier (TAG_SELECTOR)));
2922 expr_decl = build1 (INDIRECT_REF, NULL_TREE, NULL_TREE);
2924 push_parm_decl (build_tree_list (build_tree_list (decl_specs, expr_decl),
2926 parms = get_parm_info (0);
2929 decl_specs = build_tree_list (NULL_TREE, objc_object_reference);
2930 sprintf (buffer, "__objc_tmp_%x", build_tmp_function_decl_xxx++);
2931 expr_decl = build_nt (CALL_EXPR, get_identifier (buffer), parms, NULL_TREE);
2932 expr_decl = build1 (INDIRECT_REF, NULL_TREE, expr_decl);
2934 tmp_decl = define_decl (expr_decl, decl_specs);
2935 DECL_SOURCE_LINE (tmp_decl) = 0;
2940 /* Generate the prototypes for protocol methods. This is used to
2941 generate method encodings for these.
2943 NST_METHODS is the method to generate a _DECL node for TMP_DECL is
2944 a decl node to be used. This is also where the return value is
2948 hack_method_prototype (nst_methods, tmp_decl)
2955 /* Hack to avoid problem with static typing of self arg. */
2956 TREE_SET_CODE (nst_methods, CLASS_METHOD_DECL);
2957 start_method_def (nst_methods);
2958 TREE_SET_CODE (nst_methods, INSTANCE_METHOD_DECL);
2960 if (METHOD_ADD_ARGS (nst_methods) == objc_ellipsis_node)
2961 parms = get_parm_info (0); /* we have a `, ...' */
2963 parms = get_parm_info (1); /* place a `void_at_end' */
2965 poplevel (0, 0, 0); /* Must be called BEFORE start_function. */
2967 /* Usually called from store_parm_decls -> init_function_start. */
2969 DECL_ARGUMENTS (tmp_decl) = TREE_PURPOSE (parms);
2971 if (current_function_decl)
2973 current_function_decl = tmp_decl;
2976 /* Code taken from start_function. */
2977 tree restype = TREE_TYPE (TREE_TYPE (tmp_decl));
2978 /* Promote the value to int before returning it. */
2979 if (TREE_CODE (restype) == INTEGER_TYPE
2980 && TYPE_PRECISION (restype) < TYPE_PRECISION (integer_type_node))
2981 restype = integer_type_node;
2982 DECL_RESULT (tmp_decl) = build_decl (RESULT_DECL, 0, restype);
2985 for (parm = DECL_ARGUMENTS (tmp_decl); parm; parm = TREE_CHAIN (parm))
2986 DECL_CONTEXT (parm) = tmp_decl;
2988 init_function_start (tmp_decl);
2990 /* Typically called from expand_function_start for function definitions. */
2991 assign_parms (tmp_decl);
2993 /* install return type */
2994 TREE_TYPE (TREE_TYPE (tmp_decl)) = groktypename (TREE_TYPE (nst_methods));
2996 current_function_decl = NULL;
3000 generate_protocol_references (plist)
3005 /* Forward declare protocols referenced. */
3006 for (lproto = plist; lproto; lproto = TREE_CHAIN (lproto))
3008 tree proto = TREE_VALUE (lproto);
3010 if (TREE_CODE (proto) == PROTOCOL_INTERFACE_TYPE
3011 && PROTOCOL_NAME (proto))
3013 if (! PROTOCOL_FORWARD_DECL (proto))
3014 build_protocol_reference (proto);
3016 if (PROTOCOL_LIST (proto))
3017 generate_protocol_references (PROTOCOL_LIST (proto));
3022 /* For each protocol which was referenced either from a @protocol()
3023 expression, or because a class/category implements it (then a
3024 pointer to the protocol is stored in the struct describing the
3025 class/category), we create a statically allocated instance of the
3026 Protocol class. The code is written in such a way as to generate
3027 as few Protocol objects as possible; we generate a unique Protocol
3028 instance for each protocol, and we don't generate a Protocol
3029 instance if the protocol is never referenced (either from a
3030 @protocol() or from a class/category implementation). These
3031 statically allocated objects can be referred to via the static
3032 (that is, private to this module) symbols _OBJC_PROTOCOL_n.
3034 The statically allocated Protocol objects that we generate here
3035 need to be fixed up at runtime in order to be used: the 'isa'
3036 pointer of the objects need to be set up to point to the 'Protocol'
3037 class, as known at runtime.
3039 The NeXT runtime fixes up all protocols at program startup time,
3040 before main() is entered. It uses a low-level trick to look up all
3041 those symbols, then loops on them and fixes them up.
3043 The GNU runtime as well fixes up all protocols before user code
3044 from the module is executed; it requires pointers to those symbols
3045 to be put in the objc_symtab (which is then passed as argument to
3046 the function __objc_exec_class() which the compiler sets up to be
3047 executed automatically when the module is loaded); setup of those
3048 Protocol objects happen in two ways in the GNU runtime: all
3049 Protocol objects referred to by a class or category implementation
3050 are fixed up when the class/category is loaded; all Protocol
3051 objects referred to by a @protocol() expression are added by the
3052 compiler to the list of statically allocated instances to fixup
3053 (the same list holding the statically allocated constant string
3054 objects). Because, as explained above, the compiler generates as
3055 few Protocol objects as possible, some Protocol object might end up
3056 being referenced multiple times when compiled with the GNU runtime,
3057 and end up being fixed up multiple times at runtime inizialization.
3058 But that doesn't hurt, it's just a little inefficient. */
3060 generate_protocols ()
3062 tree p, tmp_decl, encoding;
3063 tree sc_spec, decl_specs, decl;
3064 tree initlist, protocol_name_expr, refs_decl, refs_expr;
3067 tmp_decl = build_tmp_function_decl ();
3069 if (! objc_protocol_template)
3070 objc_protocol_template = build_protocol_template ();
3072 /* If a protocol was directly referenced, pull in indirect references. */
3073 for (p = protocol_chain; p; p = TREE_CHAIN (p))
3074 if (PROTOCOL_FORWARD_DECL (p) && PROTOCOL_LIST (p))
3075 generate_protocol_references (PROTOCOL_LIST (p));
3077 for (p = protocol_chain; p; p = TREE_CHAIN (p))
3079 tree nst_methods = PROTOCOL_NST_METHODS (p);
3080 tree cls_methods = PROTOCOL_CLS_METHODS (p);
3082 /* If protocol wasn't referenced, don't generate any code. */
3083 if (! PROTOCOL_FORWARD_DECL (p))
3086 /* Make sure we link in the Protocol class. */
3087 add_class_reference (get_identifier (PROTOCOL_OBJECT_CLASS_NAME));
3091 if (! METHOD_ENCODING (nst_methods))
3093 hack_method_prototype (nst_methods, tmp_decl);
3094 encoding = encode_method_prototype (nst_methods, tmp_decl);
3095 METHOD_ENCODING (nst_methods) = encoding;
3097 nst_methods = TREE_CHAIN (nst_methods);
3102 if (! METHOD_ENCODING (cls_methods))
3104 hack_method_prototype (cls_methods, tmp_decl);
3105 encoding = encode_method_prototype (cls_methods, tmp_decl);
3106 METHOD_ENCODING (cls_methods) = encoding;
3109 cls_methods = TREE_CHAIN (cls_methods);
3111 generate_method_descriptors (p);
3113 if (PROTOCOL_LIST (p))
3114 refs_decl = generate_protocol_list (p);
3118 /* static struct objc_protocol _OBJC_PROTOCOL_<mumble>; */
3120 sc_spec = tree_cons (NULL_TREE, ridpointers[(int) RID_STATIC],
3122 decl_specs = tree_cons (NULL_TREE, objc_protocol_template, sc_spec);
3124 decl = start_decl (synth_id_with_class_suffix ("_OBJC_PROTOCOL", p),
3125 decl_specs, 1, NULL_TREE);
3127 DECL_CONTEXT (decl) = NULL_TREE;
3129 protocol_name_expr = add_objc_string (PROTOCOL_NAME (p), class_names);
3135 (build_tree_list (build_tree_list (NULL_TREE,
3136 objc_protocol_template),
3137 build1 (INDIRECT_REF, NULL_TREE,
3138 build1 (INDIRECT_REF, NULL_TREE,
3141 refs_expr = build_unary_op (ADDR_EXPR, refs_decl, 0);
3142 TREE_TYPE (refs_expr) = cast_type2;
3145 refs_expr = build_int_2 (0, 0);
3147 /* UOBJC_INSTANCE_METHODS_decl/UOBJC_CLASS_METHODS_decl are set
3148 by generate_method_descriptors, which is called above. */
3149 initlist = build_protocol_initializer (TREE_TYPE (decl),
3150 protocol_name_expr, refs_expr,
3151 UOBJC_INSTANCE_METHODS_decl,
3152 UOBJC_CLASS_METHODS_decl);
3153 finish_decl (decl, initlist, NULL_TREE);
3155 /* Mark the decl as used to avoid "defined but not used" warning. */
3156 TREE_USED (decl) = 1;
3161 build_protocol_initializer (type, protocol_name, protocol_list,
3162 instance_methods, class_methods)
3166 tree instance_methods;
3169 tree initlist = NULL_TREE, expr;
3172 cast_type = groktypename
3174 (build_tree_list (NULL_TREE,
3175 xref_tag (RECORD_TYPE,
3176 get_identifier (UTAG_CLASS))),
3177 build1 (INDIRECT_REF, NULL_TREE, NULL_TREE)));
3179 /* Filling the "isa" in with one allows the runtime system to
3180 detect that the version change...should remove before final release. */
3182 expr = build_int_2 (PROTOCOL_VERSION, 0);
3183 TREE_TYPE (expr) = cast_type;
3184 initlist = tree_cons (NULL_TREE, expr, initlist);
3185 initlist = tree_cons (NULL_TREE, protocol_name, initlist);
3186 initlist = tree_cons (NULL_TREE, protocol_list, initlist);
3188 if (!instance_methods)
3189 initlist = tree_cons (NULL_TREE, build_int_2 (0, 0), initlist);
3192 expr = build_unary_op (ADDR_EXPR, instance_methods, 0);
3193 initlist = tree_cons (NULL_TREE, expr, initlist);
3197 initlist = tree_cons (NULL_TREE, build_int_2 (0, 0), initlist);
3200 expr = build_unary_op (ADDR_EXPR, class_methods, 0);
3201 initlist = tree_cons (NULL_TREE, expr, initlist);
3204 return objc_build_constructor (type, nreverse (initlist));
3207 /* struct objc_category {
3208 char *category_name;
3210 struct objc_method_list *instance_methods;
3211 struct objc_method_list *class_methods;
3212 struct objc_protocol_list *protocols;
3216 build_category_template ()
3218 tree decl_specs, field_decl, field_decl_chain;
3220 objc_category_template = start_struct (RECORD_TYPE,
3221 get_identifier (UTAG_CATEGORY));
3222 /* char *category_name; */
3224 decl_specs = build_tree_list (NULL_TREE, ridpointers[(int) RID_CHAR]);
3226 = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("category_name"));
3227 field_decl = grokfield (field_decl, decl_specs, NULL_TREE);
3228 field_decl_chain = field_decl;
3230 /* char *class_name; */
3232 decl_specs = build_tree_list (NULL_TREE, ridpointers[(int) RID_CHAR]);
3233 field_decl = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("class_name"));
3234 field_decl = grokfield (field_decl, decl_specs, NULL_TREE);
3235 chainon (field_decl_chain, field_decl);
3237 /* struct objc_method_list *instance_methods; */
3239 decl_specs = build_tree_list (NULL_TREE,
3240 xref_tag (RECORD_TYPE,
3241 get_identifier (UTAG_METHOD_LIST)));
3243 = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("instance_methods"));
3244 field_decl = grokfield (field_decl, decl_specs, NULL_TREE);
3245 chainon (field_decl_chain, field_decl);
3247 /* struct objc_method_list *class_methods; */
3249 decl_specs = build_tree_list (NULL_TREE,
3250 xref_tag (RECORD_TYPE,
3251 get_identifier (UTAG_METHOD_LIST)));
3253 = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("class_methods"));
3254 field_decl = grokfield (field_decl, decl_specs, NULL_TREE);
3255 chainon (field_decl_chain, field_decl);
3257 /* struct objc_protocol **protocol_list; */
3259 decl_specs = build_tree_list (NULL_TREE,
3260 xref_tag (RECORD_TYPE,
3261 get_identifier (UTAG_PROTOCOL)));
3263 = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("protocol_list"));
3264 field_decl = build1 (INDIRECT_REF, NULL_TREE, field_decl);
3265 field_decl = grokfield (field_decl, decl_specs, NULL_TREE);
3266 chainon (field_decl_chain, field_decl);
3268 finish_struct (objc_category_template, field_decl_chain, NULL_TREE);
3271 /* struct objc_selector {
3277 build_selector_template ()
3280 tree decl_specs, field_decl, field_decl_chain;
3282 objc_selector_template
3283 = start_struct (RECORD_TYPE, get_identifier (UTAG_SELECTOR));
3287 decl_specs = build_tree_list (NULL_TREE, ridpointers[(int) RID_VOID]);
3288 field_decl = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("sel_id"));
3289 field_decl = grokfield (field_decl, decl_specs, NULL_TREE);
3290 field_decl_chain = field_decl;
3292 /* char *sel_type; */
3294 decl_specs = build_tree_list (NULL_TREE, ridpointers[(int) RID_CHAR]);
3295 field_decl = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("sel_type"));
3296 field_decl = grokfield (field_decl, decl_specs, NULL_TREE);
3297 chainon (field_decl_chain, field_decl);
3299 finish_struct (objc_selector_template, field_decl_chain, NULL_TREE);
3302 /* struct objc_class {
3303 struct objc_class *isa;
3304 struct objc_class *super_class;
3309 struct objc_ivar_list *ivars;
3310 struct objc_method_list *methods;
3311 if (flag_next_runtime)
3312 struct objc_cache *cache;
3314 struct sarray *dtable;
3315 struct objc_class *subclass_list;
3316 struct objc_class *sibling_class;
3318 struct objc_protocol_list *protocols;
3319 void *gc_object_type;
3323 build_class_template ()
3325 tree decl_specs, field_decl, field_decl_chain;
3328 = start_struct (RECORD_TYPE, get_identifier (UTAG_CLASS));
3330 /* struct objc_class *isa; */
3332 decl_specs = build_tree_list (NULL_TREE, objc_class_template);
3333 field_decl = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("isa"));
3334 field_decl = grokfield (field_decl, decl_specs, NULL_TREE);
3335 field_decl_chain = field_decl;
3337 /* struct objc_class *super_class; */
3339 decl_specs = build_tree_list (NULL_TREE, objc_class_template);
3341 = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("super_class"));
3342 field_decl = grokfield (field_decl, decl_specs, NULL_TREE);
3343 chainon (field_decl_chain, field_decl);
3347 decl_specs = build_tree_list (NULL_TREE, ridpointers[(int) RID_CHAR]);
3348 field_decl = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("name"));
3349 field_decl = grokfield (field_decl, decl_specs, NULL_TREE);
3350 chainon (field_decl_chain, field_decl);
3354 decl_specs = build_tree_list (NULL_TREE, ridpointers[(int) RID_LONG]);
3355 field_decl = get_identifier ("version");
3356 field_decl = grokfield (field_decl, decl_specs, NULL_TREE);
3357 chainon (field_decl_chain, field_decl);
3361 decl_specs = build_tree_list (NULL_TREE, ridpointers[(int) RID_LONG]);
3362 field_decl = get_identifier ("info");
3363 field_decl = grokfield (field_decl, decl_specs, NULL_TREE);
3364 chainon (field_decl_chain, field_decl);
3366 /* long instance_size; */
3368 decl_specs = build_tree_list (NULL_TREE, ridpointers[(int) RID_LONG]);
3369 field_decl = get_identifier ("instance_size");
3370 field_decl = grokfield (field_decl, decl_specs, NULL_TREE);
3371 chainon (field_decl_chain, field_decl);
3373 /* struct objc_ivar_list *ivars; */
3375 decl_specs = build_tree_list (NULL_TREE,
3376 xref_tag (RECORD_TYPE,
3377 get_identifier (UTAG_IVAR_LIST)));
3378 field_decl = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("ivars"));
3379 field_decl = grokfield (field_decl, decl_specs, NULL_TREE);
3380 chainon (field_decl_chain, field_decl);
3382 /* struct objc_method_list *methods; */
3384 decl_specs = build_tree_list (NULL_TREE,
3385 xref_tag (RECORD_TYPE,
3386 get_identifier (UTAG_METHOD_LIST)));
3387 field_decl = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("methods"));
3388 field_decl = grokfield (field_decl, decl_specs, NULL_TREE);
3389 chainon (field_decl_chain, field_decl);
3391 if (flag_next_runtime)
3393 /* struct objc_cache *cache; */
3395 decl_specs = build_tree_list (NULL_TREE,
3396 xref_tag (RECORD_TYPE,
3397 get_identifier ("objc_cache")));
3398 field_decl = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("cache"));
3399 field_decl = grokfield (field_decl, decl_specs, NULL_TREE);
3400 chainon (field_decl_chain, field_decl);
3404 /* struct sarray *dtable; */
3406 decl_specs = build_tree_list (NULL_TREE,
3407 xref_tag (RECORD_TYPE,
3408 get_identifier ("sarray")));
3409 field_decl = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("dtable"));
3410 field_decl = grokfield (field_decl, decl_specs, NULL_TREE);
3411 chainon (field_decl_chain, field_decl);
3413 /* struct objc_class *subclass_list; */
3415 decl_specs = build_tree_list (NULL_TREE, objc_class_template);
3417 = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("subclass_list"));
3418 field_decl = grokfield (field_decl, decl_specs, NULL_TREE);
3419 chainon (field_decl_chain, field_decl);
3421 /* struct objc_class *sibling_class; */
3423 decl_specs = build_tree_list (NULL_TREE, objc_class_template);
3425 = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("sibling_class"));
3426 field_decl = grokfield (field_decl, decl_specs, NULL_TREE);
3427 chainon (field_decl_chain, field_decl);
3430 /* struct objc_protocol **protocol_list; */
3432 decl_specs = build_tree_list (NULL_TREE,
3433 xref_tag (RECORD_TYPE,
3434 get_identifier (UTAG_PROTOCOL)));
3436 = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("protocol_list"));
3438 = build1 (INDIRECT_REF, NULL_TREE, field_decl);
3439 field_decl = grokfield (field_decl, decl_specs, NULL_TREE);
3440 chainon (field_decl_chain, field_decl);
3444 decl_specs = build_tree_list (NULL_TREE, ridpointers[(int) RID_VOID]);
3445 field_decl = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("sel_id"));
3446 field_decl = grokfield (field_decl, decl_specs, NULL_TREE);
3447 chainon (field_decl_chain, field_decl);
3449 /* void *gc_object_type; */
3451 decl_specs = build_tree_list (NULL_TREE, ridpointers[(int) RID_VOID]);
3452 field_decl = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("gc_object_type"));
3453 field_decl = grokfield (field_decl, decl_specs, NULL_TREE);
3454 chainon (field_decl_chain, field_decl);
3456 finish_struct (objc_class_template, field_decl_chain, NULL_TREE);
3459 /* Generate appropriate forward declarations for an implementation. */
3462 synth_forward_declarations ()
3464 tree sc_spec, decl_specs, an_id;
3466 /* static struct objc_class _OBJC_CLASS_<my_name>; */
3468 an_id = synth_id_with_class_suffix ("_OBJC_CLASS", objc_implementation_context);
3470 sc_spec = build_tree_list (NULL_TREE, ridpointers[(int) RID_EXTERN]);
3471 decl_specs = tree_cons (NULL_TREE, objc_class_template, sc_spec);
3472 UOBJC_CLASS_decl = define_decl (an_id, decl_specs);
3473 TREE_USED (UOBJC_CLASS_decl) = 1;
3474 DECL_ARTIFICIAL (UOBJC_CLASS_decl) = 1;
3475 TREE_PUBLIC (UOBJC_CLASS_decl) = 0;
3477 /* static struct objc_class _OBJC_METACLASS_<my_name>; */
3479 an_id = synth_id_with_class_suffix ("_OBJC_METACLASS",
3480 objc_implementation_context);
3482 UOBJC_METACLASS_decl = define_decl (an_id, decl_specs);
3483 TREE_USED (UOBJC_METACLASS_decl) = 1;
3484 DECL_ARTIFICIAL (UOBJC_METACLASS_decl) = 1;
3485 TREE_PUBLIC (UOBJC_METACLASS_decl) = 0;
3487 /* Pre-build the following entities - for speed/convenience. */
3489 an_id = get_identifier ("super_class");
3490 ucls_super_ref = build_component_ref (UOBJC_CLASS_decl, an_id);
3491 uucls_super_ref = build_component_ref (UOBJC_METACLASS_decl, an_id);
3495 error_with_ivar (message, decl, rawdecl)
3496 const char *message;
3500 error ("%H%s `%s'", &DECL_SOURCE_LOCATION (decl),
3501 message, gen_declaration (rawdecl, errbuf));
3506 check_ivars (inter, imp)
3510 tree intdecls = CLASS_IVARS (inter);
3511 tree impdecls = CLASS_IVARS (imp);
3512 tree rawintdecls = CLASS_RAW_IVARS (inter);
3513 tree rawimpdecls = CLASS_RAW_IVARS (imp);
3519 if (intdecls == 0 && impdecls == 0)
3521 if (intdecls == 0 || impdecls == 0)
3523 error ("inconsistent instance variable specification");
3527 t1 = TREE_TYPE (intdecls); t2 = TREE_TYPE (impdecls);
3529 if (!comptypes (t1, t2, false))
3531 if (DECL_NAME (intdecls) == DECL_NAME (impdecls))
3533 error_with_ivar ("conflicting instance variable type",
3534 impdecls, rawimpdecls);
3535 error_with_ivar ("previous declaration of",
3536 intdecls, rawintdecls);
3538 else /* both the type and the name don't match */
3540 error ("inconsistent instance variable specification");
3545 else if (DECL_NAME (intdecls) != DECL_NAME (impdecls))
3547 error_with_ivar ("conflicting instance variable name",
3548 impdecls, rawimpdecls);
3549 error_with_ivar ("previous declaration of",
3550 intdecls, rawintdecls);
3553 intdecls = TREE_CHAIN (intdecls);
3554 impdecls = TREE_CHAIN (impdecls);
3555 rawintdecls = TREE_CHAIN (rawintdecls);
3556 rawimpdecls = TREE_CHAIN (rawimpdecls);
3560 /* Set super_type to the data type node for struct objc_super *,
3561 first defining struct objc_super itself.
3562 This needs to be done just once per compilation. */
3565 build_super_template ()
3567 tree record, decl_specs, field_decl, field_decl_chain;
3569 record = start_struct (RECORD_TYPE, get_identifier (UTAG_SUPER));
3571 /* struct objc_object *self; */
3573 decl_specs = build_tree_list (NULL_TREE, objc_object_reference);
3574 field_decl = get_identifier ("self");
3575 field_decl = build1 (INDIRECT_REF, NULL_TREE, field_decl);
3576 field_decl = grokfield (field_decl, decl_specs, NULL_TREE);
3577 field_decl_chain = field_decl;
3579 /* struct objc_class *class; */
3581 decl_specs = get_identifier (UTAG_CLASS);
3582 decl_specs = build_tree_list (NULL_TREE, xref_tag (RECORD_TYPE, decl_specs));
3583 field_decl = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("class"));
3585 field_decl = grokfield (field_decl, decl_specs, NULL_TREE);
3586 chainon (field_decl_chain, field_decl);
3588 finish_struct (record, field_decl_chain, NULL_TREE);
3590 /* `struct objc_super *' */
3591 super_type = groktypename (build_tree_list (build_tree_list (NULL_TREE,
3593 build1 (INDIRECT_REF,
3594 NULL_TREE, NULL_TREE)));
3598 /* struct objc_ivar {
3605 build_ivar_template ()
3607 tree objc_ivar_id, objc_ivar_record;
3608 tree decl_specs, field_decl, field_decl_chain;
3610 objc_ivar_id = get_identifier (UTAG_IVAR);
3611 objc_ivar_record = start_struct (RECORD_TYPE, objc_ivar_id);
3613 /* char *ivar_name; */
3615 decl_specs = build_tree_list (NULL_TREE, ridpointers[(int) RID_CHAR]);
3616 field_decl = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("ivar_name"));
3618 field_decl = grokfield (field_decl, decl_specs, NULL_TREE);
3619 field_decl_chain = field_decl;
3621 /* char *ivar_type; */
3623 decl_specs = build_tree_list (NULL_TREE, ridpointers[(int) RID_CHAR]);
3624 field_decl = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("ivar_type"));
3626 field_decl = grokfield (field_decl, decl_specs, NULL_TREE);
3627 chainon (field_decl_chain, field_decl);
3629 /* int ivar_offset; */
3631 decl_specs = build_tree_list (NULL_TREE, ridpointers[(int) RID_INT]);
3632 field_decl = get_identifier ("ivar_offset");
3634 field_decl = grokfield (field_decl, decl_specs, NULL_TREE);
3635 chainon (field_decl_chain, field_decl);
3637 finish_struct (objc_ivar_record, field_decl_chain, NULL_TREE);
3639 return objc_ivar_record;
3644 struct objc_ivar ivar_list[ivar_count];
3648 build_ivar_list_template (list_type, size)
3652 tree objc_ivar_list_record;
3653 tree decl_specs, field_decl, field_decl_chain;
3655 objc_ivar_list_record = start_struct (RECORD_TYPE, NULL_TREE);
3657 /* int ivar_count; */
3659 decl_specs = build_tree_list (NULL_TREE, ridpointers[(int) RID_INT]);
3660 field_decl = get_identifier ("ivar_count");
3662 field_decl = grokfield (field_decl, decl_specs, NULL_TREE);
3663 field_decl_chain = field_decl;
3665 /* struct objc_ivar ivar_list[]; */
3667 decl_specs = build_tree_list (NULL_TREE, list_type);
3668 field_decl = build_nt (ARRAY_REF, get_identifier ("ivar_list"),
3669 build_int_2 (size, 0));
3671 field_decl = grokfield (field_decl, decl_specs, NULL_TREE);
3672 chainon (field_decl_chain, field_decl);
3674 finish_struct (objc_ivar_list_record, field_decl_chain, NULL_TREE);
3676 return objc_ivar_list_record;
3682 struct objc_method method_list[method_count];
3686 build_method_list_template (list_type, size)
3690 tree objc_ivar_list_record;
3691 tree decl_specs, field_decl, field_decl_chain;
3693 objc_ivar_list_record = start_struct (RECORD_TYPE, NULL_TREE);
3695 /* int method_next; */
3700 xref_tag (RECORD_TYPE,
3701 get_identifier (UTAG_METHOD_PROTOTYPE_LIST)));
3703 = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("method_next"));
3704 field_decl = grokfield (field_decl, decl_specs, NULL_TREE);
3705 field_decl_chain = field_decl;
3707 /* int method_count; */
3709 decl_specs = build_tree_list (NULL_TREE, ridpointers[(int) RID_INT]);
3710 field_decl = get_identifier ("method_count");
3712 field_decl = grokfield (field_decl, decl_specs, NULL_TREE);
3713 chainon (field_decl_chain, field_decl);
3715 /* struct objc_method method_list[]; */
3717 decl_specs = build_tree_list (NULL_TREE, list_type);
3718 field_decl = build_nt (ARRAY_REF, get_identifier ("method_list"),
3719 build_int_2 (size, 0));
3721 field_decl = grokfield (field_decl, decl_specs, NULL_TREE);
3722 chainon (field_decl_chain, field_decl);
3724 finish_struct (objc_ivar_list_record, field_decl_chain, NULL_TREE);
3726 return objc_ivar_list_record;
3730 build_ivar_list_initializer (type, field_decl)
3734 tree initlist = NULL_TREE;
3738 tree ivar = NULL_TREE;
3741 if (DECL_NAME (field_decl))
3742 ivar = tree_cons (NULL_TREE,
3743 add_objc_string (DECL_NAME (field_decl),
3747 /* Unnamed bit-field ivar (yuck). */
3748 ivar = tree_cons (NULL_TREE, build_int_2 (0, 0), ivar);
3751 encode_field_decl (field_decl,
3752 obstack_object_size (&util_obstack),
3753 OBJC_ENCODE_DONT_INLINE_DEFS);
3755 /* Null terminate string. */
3756 obstack_1grow (&util_obstack, 0);
3760 add_objc_string (get_identifier (obstack_finish (&util_obstack)),
3763 obstack_free (&util_obstack, util_firstobj);
3766 ivar = tree_cons (NULL_TREE, byte_position (field_decl), ivar);
3767 initlist = tree_cons (NULL_TREE,
3768 objc_build_constructor (type, nreverse (ivar)),
3771 field_decl = TREE_CHAIN (field_decl);
3775 return objc_build_constructor (build_array_type (type, 0),
3776 nreverse (initlist));
3780 generate_ivars_list (type, name, size, list)
3786 tree sc_spec, decl_specs, decl, initlist;
3788 sc_spec = tree_cons (NULL_TREE, ridpointers[(int) RID_STATIC], NULL_TREE);
3789 decl_specs = tree_cons (NULL_TREE, type, sc_spec);
3791 decl = start_decl (synth_id_with_class_suffix (name, objc_implementation_context),
3792 decl_specs, 1, NULL_TREE);
3794 initlist = build_tree_list (NULL_TREE, build_int_2 (size, 0));
3795 initlist = tree_cons (NULL_TREE, list, initlist);
3798 objc_build_constructor (TREE_TYPE (decl), nreverse (initlist)),
3805 generate_ivar_lists ()
3807 tree initlist, ivar_list_template, chain;
3808 tree cast, variable_length_type;
3811 generating_instance_variables = 1;
3813 if (!objc_ivar_template)
3814 objc_ivar_template = build_ivar_template ();
3818 (build_tree_list (NULL_TREE, xref_tag (RECORD_TYPE,
3819 get_identifier (UTAG_IVAR_LIST))),
3821 variable_length_type = groktypename (cast);
3823 /* Only generate class variables for the root of the inheritance
3824 hierarchy since these will be the same for every class. */
3826 if (CLASS_SUPER_NAME (implementation_template) == NULL_TREE
3827 && (chain = TYPE_FIELDS (objc_class_template)))
3829 size = list_length (chain);
3831 ivar_list_template = build_ivar_list_template (objc_ivar_template, size);
3832 initlist = build_ivar_list_initializer (objc_ivar_template, chain);
3834 UOBJC_CLASS_VARIABLES_decl
3835 = generate_ivars_list (ivar_list_template, "_OBJC_CLASS_VARIABLES",
3837 TREE_TYPE (UOBJC_CLASS_VARIABLES_decl) = variable_length_type;
3840 UOBJC_CLASS_VARIABLES_decl = 0;
3842 chain = CLASS_IVARS (implementation_template);
3845 size = list_length (chain);
3846 ivar_list_template = build_ivar_list_template (objc_ivar_template, size);
3847 initlist = build_ivar_list_initializer (objc_ivar_template, chain);
3849 UOBJC_INSTANCE_VARIABLES_decl
3850 = generate_ivars_list (ivar_list_template, "_OBJC_INSTANCE_VARIABLES",
3852 TREE_TYPE (UOBJC_INSTANCE_VARIABLES_decl) = variable_length_type;
3855 UOBJC_INSTANCE_VARIABLES_decl = 0;
3857 generating_instance_variables = 0;
3861 build_dispatch_table_initializer (type, entries)
3865 tree initlist = NULL_TREE;
3869 tree elemlist = NULL_TREE;
3871 elemlist = tree_cons (NULL_TREE,
3872 build_selector (METHOD_SEL_NAME (entries)),
3875 /* Generate the method encoding if we don't have one already. */
3876 if (! METHOD_ENCODING (entries))
3877 METHOD_ENCODING (entries) =
3878 encode_method_def (METHOD_DEFINITION (entries));
3880 elemlist = tree_cons (NULL_TREE,
3881 add_objc_string (METHOD_ENCODING (entries),
3885 elemlist = tree_cons (NULL_TREE,
3886 build_unary_op (ADDR_EXPR,
3887 METHOD_DEFINITION (entries), 1),
3890 initlist = tree_cons (NULL_TREE,
3891 objc_build_constructor (type, nreverse (elemlist)),
3894 entries = TREE_CHAIN (entries);
3898 return objc_build_constructor (build_array_type (type, 0),
3899 nreverse (initlist));
3902 /* To accomplish method prototyping without generating all kinds of
3903 inane warnings, the definition of the dispatch table entries were
3906 struct objc_method { SEL _cmd; ...; id (*_imp)(); };
3908 struct objc_method { SEL _cmd; ...; void *_imp; }; */
3911 build_method_template ()
3914 tree decl_specs, field_decl, field_decl_chain;
3916 _SLT_record = start_struct (RECORD_TYPE, get_identifier (UTAG_METHOD));
3918 /* struct objc_selector *_cmd; */
3919 decl_specs = tree_cons (NULL_TREE,
3920 xref_tag (RECORD_TYPE,
3921 get_identifier (TAG_SELECTOR)),
3923 field_decl = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("_cmd"));
3925 field_decl = grokfield (field_decl, decl_specs, NULL_TREE);
3926 field_decl_chain = field_decl;
3928 decl_specs = tree_cons (NULL_TREE, ridpointers[(int) RID_CHAR], NULL_TREE);
3929 field_decl = build1 (INDIRECT_REF, NULL_TREE,
3930 get_identifier ("method_types"));
3931 field_decl = grokfield (field_decl, decl_specs, NULL_TREE);
3932 chainon (field_decl_chain, field_decl);
3936 decl_specs = tree_cons (NULL_TREE, ridpointers[(int) RID_VOID], NULL_TREE);
3937 field_decl = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("_imp"));
3938 field_decl = grokfield (field_decl, decl_specs, NULL_TREE);
3939 chainon (field_decl_chain, field_decl);
3941 finish_struct (_SLT_record, field_decl_chain, NULL_TREE);
3948 generate_dispatch_table (type, name, size, list)
3954 tree sc_spec, decl_specs, decl, initlist;
3956 sc_spec = tree_cons (NULL_TREE, ridpointers[(int) RID_STATIC], NULL_TREE);
3957 decl_specs = tree_cons (NULL_TREE, type, sc_spec);
3959 decl = start_decl (synth_id_with_class_suffix (name, objc_implementation_context),
3960 decl_specs, 1, NULL_TREE);
3962 initlist = build_tree_list (NULL_TREE, build_int_2 (0, 0));
3963 initlist = tree_cons (NULL_TREE, build_int_2 (size, 0), initlist);
3964 initlist = tree_cons (NULL_TREE, list, initlist);
3967 objc_build_constructor (TREE_TYPE (decl), nreverse (initlist)),
3974 mark_referenced_methods ()
3976 struct imp_entry *impent;
3979 for (impent = imp_list; impent; impent = impent->next)
3981 chain = CLASS_CLS_METHODS (impent->imp_context);
3984 cgraph_mark_needed_node (cgraph_node (METHOD_DEFINITION (chain)), 1);
3985 chain = TREE_CHAIN (chain);
3987 chain = CLASS_NST_METHODS (impent->imp_context);
3990 cgraph_mark_needed_node (cgraph_node (METHOD_DEFINITION (chain)), 1);
3991 chain = TREE_CHAIN (chain);
3997 generate_dispatch_tables ()
3999 tree initlist, chain, method_list_template;
4000 tree cast, variable_length_type;
4003 if (!objc_method_template)
4004 objc_method_template = build_method_template ();
4008 (build_tree_list (NULL_TREE,
4009 xref_tag (RECORD_TYPE,
4010 get_identifier (UTAG_METHOD_LIST))),
4013 variable_length_type = groktypename (cast);
4015 chain = CLASS_CLS_METHODS (objc_implementation_context);
4018 size = list_length (chain);
4020 method_list_template
4021 = build_method_list_template (objc_method_template, size);
4023 = build_dispatch_table_initializer (objc_method_template, chain);
4025 UOBJC_CLASS_METHODS_decl
4026 = generate_dispatch_table (method_list_template,
4027 ((TREE_CODE (objc_implementation_context)
4028 == CLASS_IMPLEMENTATION_TYPE)
4029 ? "_OBJC_CLASS_METHODS"
4030 : "_OBJC_CATEGORY_CLASS_METHODS"),
4032 TREE_TYPE (UOBJC_CLASS_METHODS_decl) = variable_length_type;
4035 UOBJC_CLASS_METHODS_decl = 0;
4037 chain = CLASS_NST_METHODS (objc_implementation_context);
4040 size = list_length (chain);
4042 method_list_template
4043 = build_method_list_template (objc_method_template, size);
4045 = build_dispatch_table_initializer (objc_method_template, chain);
4047 if (TREE_CODE (objc_implementation_context) == CLASS_IMPLEMENTATION_TYPE)
4048 UOBJC_INSTANCE_METHODS_decl
4049 = generate_dispatch_table (method_list_template,
4050 "_OBJC_INSTANCE_METHODS",
4053 /* We have a category. */
4054 UOBJC_INSTANCE_METHODS_decl
4055 = generate_dispatch_table (method_list_template,
4056 "_OBJC_CATEGORY_INSTANCE_METHODS",
4058 TREE_TYPE (UOBJC_INSTANCE_METHODS_decl) = variable_length_type;
4061 UOBJC_INSTANCE_METHODS_decl = 0;
4065 generate_protocol_list (i_or_p)
4068 tree initlist, decl_specs, sc_spec;
4069 tree refs_decl, expr_decl, lproto, e, plist;
4073 if (TREE_CODE (i_or_p) == CLASS_INTERFACE_TYPE
4074 || TREE_CODE (i_or_p) == CATEGORY_INTERFACE_TYPE)
4075 plist = CLASS_PROTOCOL_LIST (i_or_p);
4076 else if (TREE_CODE (i_or_p) == PROTOCOL_INTERFACE_TYPE)
4077 plist = PROTOCOL_LIST (i_or_p);
4081 cast_type = groktypename
4083 (build_tree_list (NULL_TREE,
4084 xref_tag (RECORD_TYPE,
4085 get_identifier (UTAG_PROTOCOL))),
4086 build1 (INDIRECT_REF, NULL_TREE, NULL_TREE)));
4089 for (lproto = plist; lproto; lproto = TREE_CHAIN (lproto))
4090 if (TREE_CODE (TREE_VALUE (lproto)) == PROTOCOL_INTERFACE_TYPE
4091 && PROTOCOL_FORWARD_DECL (TREE_VALUE (lproto)))
4094 /* Build initializer. */
4095 initlist = tree_cons (NULL_TREE, build_int_2 (0, 0), NULL_TREE);
4097 e = build_int_2 (size, 0);
4098 TREE_TYPE (e) = cast_type;
4099 initlist = tree_cons (NULL_TREE, e, initlist);
4101 for (lproto = plist; lproto; lproto = TREE_CHAIN (lproto))
4103 tree pval = TREE_VALUE (lproto);
4105 if (TREE_CODE (pval) == PROTOCOL_INTERFACE_TYPE
4106 && PROTOCOL_FORWARD_DECL (pval))
4108 e = build_unary_op (ADDR_EXPR, PROTOCOL_FORWARD_DECL (pval), 0);
4109 initlist = tree_cons (NULL_TREE, e, initlist);
4113 /* static struct objc_protocol *refs[n]; */
4115 sc_spec = tree_cons (NULL_TREE, ridpointers[(int) RID_STATIC], NULL_TREE);
4116 decl_specs = tree_cons (NULL_TREE, xref_tag (RECORD_TYPE,
4117 get_identifier (UTAG_PROTOCOL)),
4120 if (TREE_CODE (i_or_p) == PROTOCOL_INTERFACE_TYPE)
4121 expr_decl = build_nt (ARRAY_REF,
4122 synth_id_with_class_suffix ("_OBJC_PROTOCOL_REFS",
4124 build_int_2 (size + 2, 0));
4125 else if (TREE_CODE (i_or_p) == CLASS_INTERFACE_TYPE)
4126 expr_decl = build_nt (ARRAY_REF,
4127 synth_id_with_class_suffix ("_OBJC_CLASS_PROTOCOLS",
4129 build_int_2 (size + 2, 0));
4130 else if (TREE_CODE (i_or_p) == CATEGORY_INTERFACE_TYPE)
4132 = build_nt (ARRAY_REF,
4133 synth_id_with_class_suffix ("_OBJC_CATEGORY_PROTOCOLS",
4135 build_int_2 (size + 2, 0));
4139 expr_decl = build1 (INDIRECT_REF, NULL_TREE, expr_decl);
4141 refs_decl = start_decl (expr_decl, decl_specs, 1, NULL_TREE);
4142 DECL_CONTEXT (refs_decl) = NULL_TREE;
4144 finish_decl (refs_decl, objc_build_constructor (TREE_TYPE (refs_decl),
4145 nreverse (initlist)),
4152 build_category_initializer (type, cat_name, class_name,
4153 instance_methods, class_methods, protocol_list)
4157 tree instance_methods;
4161 tree initlist = NULL_TREE, expr;
4163 initlist = tree_cons (NULL_TREE, cat_name, initlist);
4164 initlist = tree_cons (NULL_TREE, class_name, initlist);
4166 if (!instance_methods)
4167 initlist = tree_cons (NULL_TREE, build_int_2 (0, 0), initlist);
4170 expr = build_unary_op (ADDR_EXPR, instance_methods, 0);
4171 initlist = tree_cons (NULL_TREE, expr, initlist);
4174 initlist = tree_cons (NULL_TREE, build_int_2 (0, 0), initlist);
4177 expr = build_unary_op (ADDR_EXPR, class_methods, 0);
4178 initlist = tree_cons (NULL_TREE, expr, initlist);
4181 /* protocol_list = */
4183 initlist = tree_cons (NULL_TREE, build_int_2 (0, 0), initlist);
4186 tree cast_type2 = groktypename
4188 (build_tree_list (NULL_TREE,
4189 xref_tag (RECORD_TYPE,
4190 get_identifier (UTAG_PROTOCOL))),
4191 build1 (INDIRECT_REF, NULL_TREE,
4192 build1 (INDIRECT_REF, NULL_TREE, NULL_TREE))));
4194 expr = build_unary_op (ADDR_EXPR, protocol_list, 0);
4195 TREE_TYPE (expr) = cast_type2;
4196 initlist = tree_cons (NULL_TREE, expr, initlist);
4199 return objc_build_constructor (type, nreverse (initlist));
4202 /* struct objc_class {
4203 struct objc_class *isa;
4204 struct objc_class *super_class;
4209 struct objc_ivar_list *ivars;
4210 struct objc_method_list *methods;
4211 if (flag_next_runtime)
4212 struct objc_cache *cache;
4214 struct sarray *dtable;
4215 struct objc_class *subclass_list;
4216 struct objc_class *sibling_class;
4218 struct objc_protocol_list *protocols;
4219 void *gc_object_type;
4223 build_shared_structure_initializer (type, isa, super, name, size, status,
4224 dispatch_table, ivar_list, protocol_list)
4231 tree dispatch_table;
4235 tree initlist = NULL_TREE, expr;
4238 initlist = tree_cons (NULL_TREE, isa, initlist);
4241 initlist = tree_cons (NULL_TREE, super, initlist);
4244 initlist = tree_cons (NULL_TREE, default_conversion (name), initlist);
4247 initlist = tree_cons (NULL_TREE, build_int_2 (0, 0), initlist);
4250 initlist = tree_cons (NULL_TREE, build_int_2 (status, 0), initlist);
4252 /* instance_size = */
4253 initlist = tree_cons (NULL_TREE, size, initlist);
4255 /* objc_ivar_list = */
4257 initlist = tree_cons (NULL_TREE, build_int_2 (0, 0), initlist);
4260 expr = build_unary_op (ADDR_EXPR, ivar_list, 0);
4261 initlist = tree_cons (NULL_TREE, expr, initlist);
4264 /* objc_method_list = */
4265 if (!dispatch_table)
4266 initlist = tree_cons (NULL_TREE, build_int_2 (0, 0), initlist);
4269 expr = build_unary_op (ADDR_EXPR, dispatch_table, 0);
4270 initlist = tree_cons (NULL_TREE, expr, initlist);
4273 if (flag_next_runtime)
4274 /* method_cache = */
4275 initlist = tree_cons (NULL_TREE, build_int_2 (0, 0), initlist);
4279 initlist = tree_cons (NULL_TREE, build_int_2 (0, 0), initlist);
4281 /* subclass_list = */
4282 initlist = tree_cons (NULL_TREE, build_int_2 (0, 0), initlist);
4284 /* sibling_class = */
4285 initlist = tree_cons (NULL_TREE, build_int_2 (0, 0), initlist);
4288 /* protocol_list = */
4289 if (! protocol_list)
4290 initlist = tree_cons (NULL_TREE, build_int_2 (0, 0), initlist);
4296 (build_tree_list (NULL_TREE,
4297 xref_tag (RECORD_TYPE,
4298 get_identifier (UTAG_PROTOCOL))),
4299 build1 (INDIRECT_REF, NULL_TREE,
4300 build1 (INDIRECT_REF, NULL_TREE, NULL_TREE))));
4302 expr = build_unary_op (ADDR_EXPR, protocol_list, 0);
4303 TREE_TYPE (expr) = cast_type2;
4304 initlist = tree_cons (NULL_TREE, expr, initlist);
4307 /* gc_object_type = NULL */
4308 initlist = tree_cons (NULL_TREE, build_int_2 (0, 0), initlist);
4310 return objc_build_constructor (type, nreverse (initlist));
4313 /* static struct objc_category _OBJC_CATEGORY_<name> = { ... }; */
4316 generate_category (cat)
4319 tree sc_spec, decl_specs, decl;
4320 tree initlist, cat_name_expr, class_name_expr;
4321 tree protocol_decl, category;
4323 add_class_reference (CLASS_NAME (cat));
4324 cat_name_expr = add_objc_string (CLASS_SUPER_NAME (cat), class_names);
4326 class_name_expr = add_objc_string (CLASS_NAME (cat), class_names);
4328 category = CLASS_CATEGORY_LIST (implementation_template);
4330 /* find the category interface from the class it is associated with */
4333 if (CLASS_SUPER_NAME (cat) == CLASS_SUPER_NAME (category))
4335 category = CLASS_CATEGORY_LIST (category);
4338 if (category && CLASS_PROTOCOL_LIST (category))
4340 generate_protocol_references (CLASS_PROTOCOL_LIST (category));
4341 protocol_decl = generate_protocol_list (category);
4346 sc_spec = tree_cons (NULL_TREE, ridpointers[(int) RID_STATIC], NULL_TREE);
4347 decl_specs = tree_cons (NULL_TREE, objc_category_template, sc_spec);
4349 decl = start_decl (synth_id_with_class_suffix ("_OBJC_CATEGORY",
4350 objc_implementation_context),
4351 decl_specs, 1, NULL_TREE);
4353 initlist = build_category_initializer (TREE_TYPE (decl),
4354 cat_name_expr, class_name_expr,
4355 UOBJC_INSTANCE_METHODS_decl,
4356 UOBJC_CLASS_METHODS_decl,
4359 TREE_USED (decl) = 1;
4360 finish_decl (decl, initlist, NULL_TREE);
4363 /* static struct objc_class _OBJC_METACLASS_Foo={ ... };
4364 static struct objc_class _OBJC_CLASS_Foo={ ... }; */
4367 generate_shared_structures ()
4369 tree sc_spec, decl_specs, decl;
4370 tree name_expr, super_expr, root_expr;
4371 tree my_root_id = NULL_TREE, my_super_id = NULL_TREE;
4372 tree cast_type, initlist, protocol_decl;
4374 my_super_id = CLASS_SUPER_NAME (implementation_template);
4377 add_class_reference (my_super_id);
4379 /* Compute "my_root_id" - this is required for code generation.
4380 the "isa" for all meta class structures points to the root of
4381 the inheritance hierarchy (e.g. "__Object")... */
4382 my_root_id = my_super_id;
4385 tree my_root_int = lookup_interface (my_root_id);
4387 if (my_root_int && CLASS_SUPER_NAME (my_root_int))
4388 my_root_id = CLASS_SUPER_NAME (my_root_int);
4395 /* No super class. */
4396 my_root_id = CLASS_NAME (implementation_template);
4399 = groktypename (build_tree_list (build_tree_list (NULL_TREE,
4400 objc_class_template),
4401 build1 (INDIRECT_REF,
4402 NULL_TREE, NULL_TREE)));
4404 name_expr = add_objc_string (CLASS_NAME (implementation_template),
4407 /* Install class `isa' and `super' pointers at runtime. */
4410 super_expr = add_objc_string (my_super_id, class_names);
4411 super_expr = build_c_cast (cast_type, super_expr); /* cast! */
4414 super_expr = build_int_2 (0, 0);
4416 root_expr = add_objc_string (my_root_id, class_names);
4417 root_expr = build_c_cast (cast_type, root_expr); /* cast! */
4419 if (CLASS_PROTOCOL_LIST (implementation_template))
4421 generate_protocol_references
4422 (CLASS_PROTOCOL_LIST (implementation_template));
4423 protocol_decl = generate_protocol_list (implementation_template);
4428 /* static struct objc_class _OBJC_METACLASS_Foo = { ... }; */
4430 sc_spec = build_tree_list (NULL_TREE, ridpointers[(int) RID_STATIC]);
4431 decl_specs = tree_cons (NULL_TREE, objc_class_template, sc_spec);
4433 decl = start_decl (DECL_NAME (UOBJC_METACLASS_decl), decl_specs, 1,
4437 = build_shared_structure_initializer
4439 root_expr, super_expr, name_expr,
4440 convert (integer_type_node, TYPE_SIZE_UNIT (objc_class_template)),
4442 UOBJC_CLASS_METHODS_decl,
4443 UOBJC_CLASS_VARIABLES_decl,
4446 finish_decl (decl, initlist, NULL_TREE);
4448 /* static struct objc_class _OBJC_CLASS_Foo={ ... }; */
4450 decl = start_decl (DECL_NAME (UOBJC_CLASS_decl), decl_specs, 1,
4454 = build_shared_structure_initializer
4456 build_unary_op (ADDR_EXPR, UOBJC_METACLASS_decl, 0),
4457 super_expr, name_expr,
4458 convert (integer_type_node,
4459 TYPE_SIZE_UNIT (CLASS_STATIC_TEMPLATE
4460 (implementation_template))),
4462 UOBJC_INSTANCE_METHODS_decl,
4463 UOBJC_INSTANCE_VARIABLES_decl,
4466 finish_decl (decl, initlist, NULL_TREE);
4470 synth_id_with_class_suffix (preamble, ctxt)
4471 const char *preamble;
4475 if (TREE_CODE (ctxt) == CLASS_IMPLEMENTATION_TYPE
4476 || TREE_CODE (ctxt) == CLASS_INTERFACE_TYPE)
4478 const char *const class_name
4479 = IDENTIFIER_POINTER (CLASS_NAME (objc_implementation_context));
4480 string = alloca (strlen (preamble) + strlen (class_name) + 3);
4481 sprintf (string, "%s_%s", preamble,
4482 IDENTIFIER_POINTER (CLASS_NAME (ctxt)));
4484 else if (TREE_CODE (ctxt) == CATEGORY_IMPLEMENTATION_TYPE
4485 || TREE_CODE (ctxt) == CATEGORY_INTERFACE_TYPE)
4487 /* We have a category. */
4488 const char *const class_name
4489 = IDENTIFIER_POINTER (CLASS_NAME (objc_implementation_context));
4490 const char *const class_super_name
4491 = IDENTIFIER_POINTER (CLASS_SUPER_NAME (objc_implementation_context));
4492 string = alloca (strlen (preamble) + strlen (class_name)
4493 + strlen (class_super_name) + 3);
4494 sprintf (string, "%s_%s_%s", preamble, class_name, class_super_name);
4496 else if (TREE_CODE (ctxt) == PROTOCOL_INTERFACE_TYPE)
4498 const char *protocol_name = IDENTIFIER_POINTER (PROTOCOL_NAME (ctxt));
4499 string = alloca (strlen (preamble) + strlen (protocol_name) + 3);
4500 sprintf (string, "%s_%s", preamble, protocol_name);
4505 return get_identifier (string);
4509 is_objc_type_qualifier (node)
4512 return (TREE_CODE (node) == IDENTIFIER_NODE
4513 && (node == ridpointers [(int) RID_CONST]
4514 || node == ridpointers [(int) RID_VOLATILE]
4515 || node == ridpointers [(int) RID_IN]
4516 || node == ridpointers [(int) RID_OUT]
4517 || node == ridpointers [(int) RID_INOUT]
4518 || node == ridpointers [(int) RID_BYCOPY]
4519 || node == ridpointers [(int) RID_BYREF]
4520 || node == ridpointers [(int) RID_ONEWAY]));
4523 /* If type is empty or only type qualifiers are present, add default
4524 type of id (otherwise grokdeclarator will default to int). */
4527 adjust_type_for_id_default (type)
4530 tree declspecs, chain;
4533 return build_tree_list (build_tree_list (NULL_TREE, objc_object_reference),
4534 build1 (INDIRECT_REF, NULL_TREE, NULL_TREE));
4536 declspecs = TREE_PURPOSE (type);
4538 /* Determine if a typespec is present. */
4539 for (chain = declspecs;
4541 chain = TREE_CHAIN (chain))
4543 if (TYPED_OBJECT (TREE_VALUE (chain))
4544 && !(TREE_VALUE (type)
4545 && TREE_CODE (TREE_VALUE (type)) == INDIRECT_REF))
4546 error ("can not use an object as parameter to a method\n");
4547 if (!is_objc_type_qualifier (TREE_VALUE (chain)))
4551 return build_tree_list (tree_cons (NULL_TREE, objc_object_reference,
4553 build1 (INDIRECT_REF, NULL_TREE, NULL_TREE));
4558 selector ':' '(' typename ')' identifier
4561 Transform an Objective-C keyword argument into
4562 the C equivalent parameter declarator.
4564 In: key_name, an "identifier_node" (optional).
4565 arg_type, a "tree_list" (optional).
4566 arg_name, an "identifier_node".
4568 Note: It would be really nice to strongly type the preceding
4569 arguments in the function prototype; however, then I
4570 could not use the "accessor" macros defined in "tree.h".
4572 Out: an instance of "keyword_decl". */
4575 build_keyword_decl (key_name, arg_type, arg_name)
4582 /* If no type is specified, default to "id". */
4583 arg_type = adjust_type_for_id_default (arg_type);
4585 keyword_decl = make_node (KEYWORD_DECL);
4587 TREE_TYPE (keyword_decl) = arg_type;
4588 KEYWORD_ARG_NAME (keyword_decl) = arg_name;
4589 KEYWORD_KEY_NAME (keyword_decl) = key_name;
4591 return keyword_decl;
4594 /* Given a chain of keyword_decl's, synthesize the full keyword selector. */
4597 build_keyword_selector (selector)
4601 tree key_chain, key_name;
4604 /* Scan the selector to see how much space we'll need. */
4605 for (key_chain = selector; key_chain; key_chain = TREE_CHAIN (key_chain))
4607 if (TREE_CODE (selector) == KEYWORD_DECL)
4608 key_name = KEYWORD_KEY_NAME (key_chain);
4609 else if (TREE_CODE (selector) == TREE_LIST)
4610 key_name = TREE_PURPOSE (key_chain);
4615 len += IDENTIFIER_LENGTH (key_name) + 1;
4617 /* Just a ':' arg. */
4621 buf = alloca (len + 1);
4622 /* Start the buffer out as an empty string. */
4625 for (key_chain = selector; key_chain; key_chain = TREE_CHAIN (key_chain))
4627 if (TREE_CODE (selector) == KEYWORD_DECL)
4628 key_name = KEYWORD_KEY_NAME (key_chain);
4629 else if (TREE_CODE (selector) == TREE_LIST)
4630 key_name = TREE_PURPOSE (key_chain);
4635 strcat (buf, IDENTIFIER_POINTER (key_name));
4639 return get_identifier (buf);
4642 /* Used for declarations and definitions. */
4645 build_method_decl (code, ret_type, selector, add_args)
4646 enum tree_code code;
4653 /* If no type is specified, default to "id". */
4654 ret_type = adjust_type_for_id_default (ret_type);
4656 method_decl = make_node (code);
4657 TREE_TYPE (method_decl) = ret_type;
4659 /* If we have a keyword selector, create an identifier_node that
4660 represents the full selector name (`:' included)... */
4661 if (TREE_CODE (selector) == KEYWORD_DECL)
4663 METHOD_SEL_NAME (method_decl) = build_keyword_selector (selector);
4664 METHOD_SEL_ARGS (method_decl) = selector;
4665 METHOD_ADD_ARGS (method_decl) = add_args;
4669 METHOD_SEL_NAME (method_decl) = selector;
4670 METHOD_SEL_ARGS (method_decl) = NULL_TREE;
4671 METHOD_ADD_ARGS (method_decl) = NULL_TREE;
4677 #define METHOD_DEF 0
4678 #define METHOD_REF 1
4680 /* Used by `build_objc_method_call' and `comp_method_types'. Return
4681 an argument list for method METH. CONTEXT is either METHOD_DEF or
4682 METHOD_REF, saying whether we are trying to define a method or call
4683 one. SUPERFLAG says this is for a send to super; this makes a
4684 difference for the NeXT calling sequence in which the lookup and
4685 the method call are done together. */
4688 get_arg_type_list (meth, context, superflag)
4695 /* Receiver type. */
4696 if (flag_next_runtime && superflag)
4697 arglist = build_tree_list (NULL_TREE, super_type);
4698 else if (context == METHOD_DEF)
4699 arglist = build_tree_list (NULL_TREE, TREE_TYPE (self_decl));
4701 arglist = build_tree_list (NULL_TREE, id_type);
4703 /* Selector type - will eventually change to `int'. */
4704 chainon (arglist, build_tree_list (NULL_TREE, selector_type));
4706 /* Build a list of argument types. */
4707 for (akey = METHOD_SEL_ARGS (meth); akey; akey = TREE_CHAIN (akey))
4709 tree arg_decl = groktypename_in_parm_context (TREE_TYPE (akey));
4710 chainon (arglist, build_tree_list (NULL_TREE, TREE_TYPE (arg_decl)));
4713 if (METHOD_ADD_ARGS (meth) == objc_ellipsis_node)
4714 /* We have a `, ...' immediately following the selector,
4715 finalize the arglist...simulate get_parm_info (0). */
4717 else if (METHOD_ADD_ARGS (meth))
4719 /* we have a variable length selector */
4720 tree add_arg_list = TREE_CHAIN (METHOD_ADD_ARGS (meth));
4721 chainon (arglist, add_arg_list);
4724 /* finalize the arglist...simulate get_parm_info (1) */
4725 chainon (arglist, build_tree_list (NULL_TREE, void_type_node));
4731 check_duplicates (hsh)
4734 tree meth = NULL_TREE;
4742 /* We have two methods with the same name and different types. */
4744 char type = (TREE_CODE (meth) == INSTANCE_METHOD_DECL) ? '-' : '+';
4746 warning ("multiple declarations for method `%s'",
4747 IDENTIFIER_POINTER (METHOD_SEL_NAME (meth)));
4749 warn_with_method ("using", type, meth);
4750 for (loop = hsh->list; loop; loop = loop->next)
4751 warn_with_method ("also found", type, loop->value);
4757 /* If RECEIVER is a class reference, return the identifier node for
4758 the referenced class. RECEIVER is created by get_class_reference,
4759 so we check the exact form created depending on which runtimes are
4763 receiver_is_class_object (receiver)
4766 tree chain, exp, arg;
4768 /* The receiver is 'self' in the context of a class method. */
4769 if (objc_method_context
4770 && receiver == self_decl
4771 && TREE_CODE (objc_method_context) == CLASS_METHOD_DECL)
4773 return CLASS_NAME (objc_implementation_context);
4776 if (flag_next_runtime)
4778 /* The receiver is a variable created by
4779 build_class_reference_decl. */
4780 if (TREE_CODE (receiver) == VAR_DECL
4781 && TREE_TYPE (receiver) == objc_class_type)
4782 /* Look up the identifier. */
4783 for (chain = cls_ref_chain; chain; chain = TREE_CHAIN (chain))
4784 if (TREE_PURPOSE (chain) == receiver)
4785 return TREE_VALUE (chain);
4789 /* The receiver is a function call that returns an id. Check if
4790 it is a call to objc_getClass, if so, pick up the class name. */
4791 if (TREE_CODE (receiver) == CALL_EXPR
4792 && (exp = TREE_OPERAND (receiver, 0))
4793 && TREE_CODE (exp) == ADDR_EXPR
4794 && (exp = TREE_OPERAND (exp, 0))
4795 && TREE_CODE (exp) == FUNCTION_DECL
4796 && exp == objc_get_class_decl
4797 /* We have a call to objc_getClass! */
4798 && (arg = TREE_OPERAND (receiver, 1))
4799 && TREE_CODE (arg) == TREE_LIST
4800 && (arg = TREE_VALUE (arg)))
4803 if (TREE_CODE (arg) == ADDR_EXPR
4804 && (arg = TREE_OPERAND (arg, 0))
4805 && TREE_CODE (arg) == STRING_CST)
4806 /* Finally, we have the class name. */
4807 return get_identifier (TREE_STRING_POINTER (arg));
4813 /* If we are currently building a message expr, this holds
4814 the identifier of the selector of the message. This is
4815 used when printing warnings about argument mismatches. */
4817 static tree current_objc_message_selector = 0;
4820 objc_message_selector ()
4822 return current_objc_message_selector;
4825 /* Construct an expression for sending a message.
4826 MESS has the object to send to in TREE_PURPOSE
4827 and the argument list (including selector) in TREE_VALUE.
4829 (*(<abstract_decl>(*)())_msg)(receiver, selTransTbl[n], ...);
4830 (*(<abstract_decl>(*)())_msgSuper)(receiver, selTransTbl[n], ...); */
4833 build_message_expr (mess)
4836 tree receiver = TREE_PURPOSE (mess);
4838 tree args = TREE_VALUE (mess);
4839 tree method_params = NULL_TREE;
4841 if (TREE_CODE (receiver) == ERROR_MARK)
4842 return error_mark_node;
4844 /* Obtain the full selector name. */
4845 if (TREE_CODE (args) == IDENTIFIER_NODE)
4846 /* A unary selector. */
4848 else if (TREE_CODE (args) == TREE_LIST)
4849 sel_name = build_keyword_selector (args);
4853 /* Build the parameter list to give to the method. */
4854 if (TREE_CODE (args) == TREE_LIST)
4856 tree chain = args, prev = NULL_TREE;
4858 /* We have a keyword selector--check for comma expressions. */
4861 tree element = TREE_VALUE (chain);
4863 /* We have a comma expression, must collapse... */
4864 if (TREE_CODE (element) == TREE_LIST)
4867 TREE_CHAIN (prev) = element;
4872 chain = TREE_CHAIN (chain);
4874 method_params = args;
4877 return finish_message_expr (receiver, sel_name, method_params);
4880 /* The 'finish_message_expr' routine is called from within
4881 'build_message_expr' for non-template functions. In the case of
4882 C++ template functions, it is called from 'build_expr_from_tree'
4883 (in decl2.c) after RECEIVER and METHOD_PARAMS have been expanded. */
4886 finish_message_expr (receiver, sel_name, method_params)
4887 tree receiver, sel_name, method_params;
4889 tree method_prototype = NULL_TREE, class_ident = NULL_TREE;
4890 tree selector, self_object, retval;
4891 int statically_typed = 0, statically_allocated = 0;
4893 /* Determine receiver type. */
4894 tree rtype = TREE_TYPE (receiver);
4895 int super = IS_SUPER (rtype);
4899 if (TREE_STATIC_TEMPLATE (rtype))
4900 statically_allocated = 1;
4901 else if (TREE_CODE (rtype) == POINTER_TYPE
4902 && TREE_STATIC_TEMPLATE (TREE_TYPE (rtype)))
4903 statically_typed = 1;
4904 else if ((flag_next_runtime
4906 && (class_ident = receiver_is_class_object (receiver)))
4908 else if (! IS_ID (rtype)
4909 /* Allow any type that matches objc_class_type. */
4910 && ! comptypes (rtype, objc_class_type, false))
4912 warning ("invalid receiver type `%s'",
4913 gen_declaration (rtype, errbuf));
4915 if (statically_allocated)
4916 receiver = build_unary_op (ADDR_EXPR, receiver, 0);
4918 /* Don't evaluate the receiver twice. */
4919 receiver = save_expr (receiver);
4920 self_object = receiver;
4923 /* If sending to `super', use current self as the object. */
4924 self_object = self_decl;
4926 /* Determine operation return type. */
4932 if (CLASS_SUPER_NAME (implementation_template))
4935 = lookup_interface (CLASS_SUPER_NAME (implementation_template));
4937 if (TREE_CODE (objc_method_context) == INSTANCE_METHOD_DECL)
4938 method_prototype = lookup_instance_method_static (iface, sel_name);
4940 method_prototype = lookup_class_method_static (iface, sel_name);
4942 if (iface && !method_prototype)
4943 warning ("`%s' does not respond to `%s'",
4944 IDENTIFIER_POINTER (CLASS_SUPER_NAME (implementation_template)),
4945 IDENTIFIER_POINTER (sel_name));
4949 error ("no super class declared in interface for `%s'",
4950 IDENTIFIER_POINTER (CLASS_NAME (implementation_template)));
4951 return error_mark_node;
4955 else if (statically_allocated)
4957 tree ctype = TREE_TYPE (rtype);
4958 tree iface = lookup_interface (TYPE_NAME (rtype));
4961 method_prototype = lookup_instance_method_static (iface, sel_name);
4963 if (! method_prototype && ctype && TYPE_PROTOCOL_LIST (ctype))
4965 = lookup_method_in_protocol_list (TYPE_PROTOCOL_LIST (ctype),
4968 if (!method_prototype)
4969 warning ("`%s' does not respond to `%s'",
4970 IDENTIFIER_POINTER (TYPE_NAME (rtype)),
4971 IDENTIFIER_POINTER (sel_name));
4973 else if (statically_typed)
4975 tree ctype = TREE_TYPE (rtype);
4977 /* `self' is now statically_typed. All methods should be visible
4978 within the context of the implementation. */
4979 if (objc_implementation_context
4980 && CLASS_NAME (objc_implementation_context) == TYPE_NAME (ctype))
4983 = lookup_instance_method_static (implementation_template,
4986 if (! method_prototype && TYPE_PROTOCOL_LIST (ctype))
4988 = lookup_method_in_protocol_list (TYPE_PROTOCOL_LIST (ctype),
4991 if (! method_prototype
4992 && implementation_template != objc_implementation_context)
4993 /* The method is not published in the interface. Check
4996 = lookup_method (CLASS_NST_METHODS (objc_implementation_context),
5003 if ((iface = lookup_interface (TYPE_NAME (ctype))))
5004 method_prototype = lookup_instance_method_static (iface, sel_name);
5006 if (! method_prototype)
5008 tree protocol_list = TYPE_PROTOCOL_LIST (ctype);
5011 = lookup_method_in_protocol_list (protocol_list,
5016 if (!method_prototype)
5017 warning ("`%s' does not respond to `%s'",
5018 IDENTIFIER_POINTER (TYPE_NAME (ctype)),
5019 IDENTIFIER_POINTER (sel_name));
5021 else if (class_ident)
5023 if (objc_implementation_context
5024 && CLASS_NAME (objc_implementation_context) == class_ident)
5027 = lookup_class_method_static (implementation_template, sel_name);
5029 if (!method_prototype
5030 && implementation_template != objc_implementation_context)
5031 /* The method is not published in the interface. Check
5034 = lookup_method (CLASS_CLS_METHODS (objc_implementation_context),
5041 if ((iface = lookup_interface (class_ident)))
5042 method_prototype = lookup_class_method_static (iface, sel_name);
5045 if (!method_prototype)
5047 warning ("cannot find class (factory) method");
5048 warning ("return type for `%s' defaults to id",
5049 IDENTIFIER_POINTER (sel_name));
5052 else if (IS_PROTOCOL_QUALIFIED_ID (rtype))
5054 /* An anonymous object that has been qualified with a protocol. */
5056 tree protocol_list = TYPE_PROTOCOL_LIST (rtype);
5058 method_prototype = lookup_method_in_protocol_list (protocol_list,
5061 if (!method_prototype)
5065 warning ("method `%s' not implemented by protocol",
5066 IDENTIFIER_POINTER (sel_name));
5068 /* Try and find the method signature in the global pools. */
5070 if (!(hsh = hash_lookup (nst_method_hash_list, sel_name)))
5071 hsh = hash_lookup (cls_method_hash_list, sel_name);
5073 if (!(method_prototype = check_duplicates (hsh)))
5074 warning ("return type defaults to id");
5081 /* We think we have an instance...loophole: extern id Object; */
5082 hsh = hash_lookup (nst_method_hash_list, sel_name);
5085 /* For various loopholes */
5086 hsh = hash_lookup (cls_method_hash_list, sel_name);
5088 method_prototype = check_duplicates (hsh);
5089 if (!method_prototype)
5091 warning ("cannot find method");
5092 warning ("return type for `%s' defaults to id",
5093 IDENTIFIER_POINTER (sel_name));
5097 /* Save the selector name for printing error messages. */
5098 current_objc_message_selector = sel_name;
5100 /* Build the parameters list for looking up the method.
5101 These are the object itself and the selector. */
5103 if (flag_typed_selectors)
5104 selector = build_typed_selector_reference (sel_name, method_prototype);
5106 selector = build_selector_reference (sel_name);
5108 retval = build_objc_method_call (super, method_prototype,
5109 receiver, self_object,
5110 selector, method_params);
5112 current_objc_message_selector = 0;
5117 /* Build a tree expression to send OBJECT the operation SELECTOR,
5118 looking up the method on object LOOKUP_OBJECT (often same as OBJECT),
5119 assuming the method has prototype METHOD_PROTOTYPE.
5120 (That is an INSTANCE_METHOD_DECL or CLASS_METHOD_DECL.)
5121 Use METHOD_PARAMS as list of args to pass to the method.
5122 If SUPER_FLAG is nonzero, we look up the superclass's method. */
5125 build_objc_method_call (super_flag, method_prototype, lookup_object, object,
5126 selector, method_params)
5128 tree method_prototype, lookup_object, object, selector, method_params;
5130 tree sender = (super_flag ? umsg_super_decl : umsg_decl);
5131 tree rcv_p = (super_flag
5132 ? build_pointer_type (xref_tag (RECORD_TYPE,
5133 get_identifier (TAG_SUPER)))
5136 if (flag_next_runtime)
5138 if (! method_prototype)
5140 method_params = tree_cons (NULL_TREE, lookup_object,
5141 tree_cons (NULL_TREE, selector,
5143 assemble_external (sender);
5144 return build_function_call (sender, method_params);
5148 /* This is a real kludge, but it is used only for the Next.
5149 Clobber the data type of SENDER temporarily to accept
5150 all the arguments for this operation, and to return
5151 whatever this operation returns. */
5152 tree arglist = NULL_TREE, retval, savarg, savret;
5153 tree ret_type = groktypename (TREE_TYPE (method_prototype));
5155 /* Save the proper contents of SENDER's data type. */
5156 savarg = TYPE_ARG_TYPES (TREE_TYPE (sender));
5157 savret = TREE_TYPE (TREE_TYPE (sender));
5159 /* Install this method's argument types. */
5160 arglist = get_arg_type_list (method_prototype, METHOD_REF,
5162 TYPE_ARG_TYPES (TREE_TYPE (sender)) = arglist;
5164 /* Install this method's return type. */
5165 TREE_TYPE (TREE_TYPE (sender)) = ret_type;
5167 /* Call SENDER with all the parameters. This will do type
5168 checking using the arg types for this method. */
5169 method_params = tree_cons (NULL_TREE, lookup_object,
5170 tree_cons (NULL_TREE, selector,
5172 assemble_external (sender);
5173 retval = build_function_call (sender, method_params);
5175 /* Restore SENDER's return/argument types. */
5176 TYPE_ARG_TYPES (TREE_TYPE (sender)) = savarg;
5177 TREE_TYPE (TREE_TYPE (sender)) = savret;
5183 /* This is the portable way.
5184 First call the lookup function to get a pointer to the method,
5185 then cast the pointer, then call it with the method arguments. */
5188 /* Avoid trouble since we may evaluate each of these twice. */
5189 object = save_expr (object);
5190 selector = save_expr (selector);
5192 lookup_object = build_c_cast (rcv_p, lookup_object);
5194 assemble_external (sender);
5196 = build_function_call (sender,
5197 tree_cons (NULL_TREE, lookup_object,
5198 tree_cons (NULL_TREE, selector,
5201 /* If we have a method prototype, construct the data type this
5202 method needs, and cast what we got from SENDER into a pointer
5204 if (method_prototype)
5206 tree arglist = get_arg_type_list (method_prototype, METHOD_REF,
5208 tree valtype = groktypename (TREE_TYPE (method_prototype));
5209 tree fake_function_type = build_function_type (valtype, arglist);
5210 TREE_TYPE (method) = build_pointer_type (fake_function_type);
5214 = build_pointer_type (build_function_type (ptr_type_node, NULL_TREE));
5216 /* Pass the object to the method. */
5217 assemble_external (method);
5218 return build_function_call (method,
5219 tree_cons (NULL_TREE, object,
5220 tree_cons (NULL_TREE, selector,
5226 build_protocol_reference (p)
5229 tree decl, ident, ptype;
5231 /* static struct objc_protocol _OBJC_PROTOCOL_<mumble>; */
5233 ident = synth_id_with_class_suffix ("_OBJC_PROTOCOL", p);
5235 = groktypename (build_tree_list (build_tree_list (NULL_TREE,
5236 objc_protocol_template),
5239 if (identifier_global_value (ident))
5240 decl = identifier_global_value (ident); /* Set by pushdecl. */
5243 decl = build_decl (VAR_DECL, ident, ptype);
5244 DECL_EXTERNAL (decl) = 1;
5245 TREE_PUBLIC (decl) = 0;
5246 TREE_USED (decl) = 1;
5247 DECL_ARTIFICIAL (decl) = 1;
5249 make_decl_rtl (decl, 0);
5250 pushdecl_top_level (decl);
5253 PROTOCOL_FORWARD_DECL (p) = decl;
5256 /* This function is called by the parser when (and only when) a
5257 @protocol() expression is found, in order to compile it. */
5259 build_protocol_expr (protoname)
5263 tree p = lookup_protocol (protoname);
5267 error ("cannot find protocol declaration for `%s'",
5268 IDENTIFIER_POINTER (protoname));
5269 return error_mark_node;
5272 if (!PROTOCOL_FORWARD_DECL (p))
5273 build_protocol_reference (p);
5275 expr = build_unary_op (ADDR_EXPR, PROTOCOL_FORWARD_DECL (p), 0);
5277 TREE_TYPE (expr) = protocol_type;
5279 /* The @protocol() expression is being compiled into a pointer to a
5280 statically allocated instance of the Protocol class. To become
5281 usable at runtime, the 'isa' pointer of the instance need to be
5282 fixed up at runtime by the runtime library, to point to the
5283 actual 'Protocol' class. */
5285 /* For the GNU runtime, put the static Protocol instance in the list
5286 of statically allocated instances, so that we make sure that its
5287 'isa' pointer is fixed up at runtime by the GNU runtime library
5288 to point to the Protocol class (at runtime, when loading the
5289 module, the GNU runtime library loops on the statically allocated
5290 instances (as found in the defs field in objc_symtab) and fixups
5291 all the 'isa' pointers of those objects). */
5292 if (! flag_next_runtime)
5294 /* This type is a struct containing the fields of a Protocol
5295 object. (Cfr. protocol_type instead is the type of a pointer
5296 to such a struct). */
5297 tree protocol_struct_type = xref_tag
5298 (RECORD_TYPE, get_identifier (PROTOCOL_OBJECT_CLASS_NAME));
5301 /* Look for the list of Protocol statically allocated instances
5302 to fixup at runtime. Create a new list to hold Protocol
5303 statically allocated instances, if the list is not found. At
5304 present there is only another list, holding NSConstantString
5305 static instances to be fixed up at runtime. */
5306 for (chain = &objc_static_instances;
5307 *chain && TREE_VALUE (*chain) != protocol_struct_type;
5308 chain = &TREE_CHAIN (*chain));
5311 *chain = tree_cons (NULL_TREE, protocol_struct_type, NULL_TREE);
5312 add_objc_string (TYPE_NAME (protocol_struct_type),
5316 /* Add this statically allocated instance to the Protocol list. */
5317 TREE_PURPOSE (*chain) = tree_cons (NULL_TREE,
5318 PROTOCOL_FORWARD_DECL (p),
5319 TREE_PURPOSE (*chain));
5326 /* This function is called by the parser when a @selector() expression
5327 is found, in order to compile it. It is only called by the parser
5328 and only to compile a @selector(). */
5330 build_selector_expr (selnamelist)
5335 /* Obtain the full selector name. */
5336 if (TREE_CODE (selnamelist) == IDENTIFIER_NODE)
5337 /* A unary selector. */
5338 selname = selnamelist;
5339 else if (TREE_CODE (selnamelist) == TREE_LIST)
5340 selname = build_keyword_selector (selnamelist);
5344 /* If we are required to check @selector() expressions as they
5345 are found, check that the selector has been declared. */
5346 if (warn_undeclared_selector)
5348 /* Look the selector up in the list of all known class and
5349 instance methods (up to this line) to check that the selector
5353 /* First try with instance methods. */
5354 hsh = hash_lookup (nst_method_hash_list, selname);
5356 /* If not found, try with class methods. */
5359 hsh = hash_lookup (cls_method_hash_list, selname);
5362 /* If still not found, print out a warning. */
5365 warning ("undeclared selector `%s'", IDENTIFIER_POINTER (selname));
5370 if (flag_typed_selectors)
5371 return build_typed_selector_reference (selname, 0);
5373 return build_selector_reference (selname);
5377 build_encode_expr (type)
5383 encode_type (type, obstack_object_size (&util_obstack),
5384 OBJC_ENCODE_INLINE_DEFS);
5385 obstack_1grow (&util_obstack, 0); /* null terminate string */
5386 string = obstack_finish (&util_obstack);
5388 /* Synthesize a string that represents the encoded struct/union. */
5389 result = my_build_string (strlen (string) + 1, string);
5390 obstack_free (&util_obstack, util_firstobj);
5395 build_ivar_reference (id)
5398 if (TREE_CODE (objc_method_context) == CLASS_METHOD_DECL)
5400 /* Historically, a class method that produced objects (factory
5401 method) would assign `self' to the instance that it
5402 allocated. This would effectively turn the class method into
5403 an instance method. Following this assignment, the instance
5404 variables could be accessed. That practice, while safe,
5405 violates the simple rule that a class method should not refer
5406 to an instance variable. It's better to catch the cases
5407 where this is done unknowingly than to support the above
5409 warning ("instance variable `%s' accessed in class method",
5410 IDENTIFIER_POINTER (id));
5411 TREE_TYPE (self_decl) = instance_type; /* cast */
5414 return build_component_ref (build_indirect_ref (self_decl, "->"), id);
5417 /* Compute a hash value for a given method SEL_NAME. */
5420 hash_func (sel_name)
5423 const unsigned char *s
5424 = (const unsigned char *)IDENTIFIER_POINTER (sel_name);
5428 h = h * 67 + *s++ - 113;
5435 nst_method_hash_list = ggc_calloc (SIZEHASHTABLE, sizeof (hash));
5436 cls_method_hash_list = ggc_calloc (SIZEHASHTABLE, sizeof (hash));
5439 /* WARNING!!!! hash_enter is called with a method, and will peek
5440 inside to find its selector! But hash_lookup is given a selector
5441 directly, and looks for the selector that's inside the found
5442 entry's key (method) for comparison. */
5445 hash_enter (hashlist, method)
5450 int slot = hash_func (METHOD_SEL_NAME (method)) % SIZEHASHTABLE;
5452 obj = ggc_alloc (sizeof (struct hashed_entry));
5454 obj->next = hashlist[slot];
5457 hashlist[slot] = obj; /* append to front */
5461 hash_lookup (hashlist, sel_name)
5467 target = hashlist[hash_func (sel_name) % SIZEHASHTABLE];
5471 if (sel_name == METHOD_SEL_NAME (target->key))
5474 target = target->next;
5480 hash_add_attr (entry, value)
5486 obj = ggc_alloc (sizeof (struct hashed_attribute));
5487 obj->next = entry->list;
5490 entry->list = obj; /* append to front */
5494 lookup_method (mchain, method)
5500 if (TREE_CODE (method) == IDENTIFIER_NODE)
5503 key = METHOD_SEL_NAME (method);
5507 if (METHOD_SEL_NAME (mchain) == key)
5510 mchain = TREE_CHAIN (mchain);
5516 lookup_instance_method_static (interface, ident)
5520 tree inter = interface;
5521 tree chain = CLASS_NST_METHODS (inter);
5522 tree meth = NULL_TREE;
5526 if ((meth = lookup_method (chain, ident)))
5529 if (CLASS_CATEGORY_LIST (inter))
5531 tree category = CLASS_CATEGORY_LIST (inter);
5532 chain = CLASS_NST_METHODS (category);
5536 if ((meth = lookup_method (chain, ident)))
5539 /* Check for instance methods in protocols in categories. */
5540 if (CLASS_PROTOCOL_LIST (category))
5542 if ((meth = (lookup_method_in_protocol_list
5543 (CLASS_PROTOCOL_LIST (category), ident, 0))))
5547 if ((category = CLASS_CATEGORY_LIST (category)))
5548 chain = CLASS_NST_METHODS (category);
5553 if (CLASS_PROTOCOL_LIST (inter))
5555 if ((meth = (lookup_method_in_protocol_list
5556 (CLASS_PROTOCOL_LIST (inter), ident, 0))))
5560 if ((inter = lookup_interface (CLASS_SUPER_NAME (inter))))
5561 chain = CLASS_NST_METHODS (inter);
5569 lookup_class_method_static (interface, ident)
5573 tree inter = interface;
5574 tree chain = CLASS_CLS_METHODS (inter);
5575 tree meth = NULL_TREE;
5576 tree root_inter = NULL_TREE;
5580 if ((meth = lookup_method (chain, ident)))
5583 if (CLASS_CATEGORY_LIST (inter))
5585 tree category = CLASS_CATEGORY_LIST (inter);
5586 chain = CLASS_CLS_METHODS (category);
5590 if ((meth = lookup_method (chain, ident)))
5593 /* Check for class methods in protocols in categories. */
5594 if (CLASS_PROTOCOL_LIST (category))
5596 if ((meth = (lookup_method_in_protocol_list
5597 (CLASS_PROTOCOL_LIST (category), ident, 1))))
5601 if ((category = CLASS_CATEGORY_LIST (category)))
5602 chain = CLASS_CLS_METHODS (category);
5607 /* Check for class methods in protocols. */
5608 if (CLASS_PROTOCOL_LIST (inter))
5610 if ((meth = (lookup_method_in_protocol_list
5611 (CLASS_PROTOCOL_LIST (inter), ident, 1))))
5616 if ((inter = lookup_interface (CLASS_SUPER_NAME (inter))))
5617 chain = CLASS_CLS_METHODS (inter);
5621 /* If no class (factory) method was found, check if an _instance_
5622 method of the same name exists in the root class. This is what
5623 the Objective-C runtime will do. */
5624 return lookup_instance_method_static (root_inter, ident);
5628 add_class_method (class, method)
5635 if (!(mth = lookup_method (CLASS_CLS_METHODS (class), method)))
5637 /* put method on list in reverse order */
5638 TREE_CHAIN (method) = CLASS_CLS_METHODS (class);
5639 CLASS_CLS_METHODS (class) = method;
5643 if (TREE_CODE (class) == CLASS_IMPLEMENTATION_TYPE)
5644 error ("duplicate definition of class method `%s'",
5645 IDENTIFIER_POINTER (METHOD_SEL_NAME (mth)));
5648 /* Check types; if different, complain. */
5649 if (!comp_proto_with_proto (method, mth))
5650 error ("duplicate declaration of class method `%s'",
5651 IDENTIFIER_POINTER (METHOD_SEL_NAME (mth)));
5655 if (!(hsh = hash_lookup (cls_method_hash_list, METHOD_SEL_NAME (method))))
5657 /* Install on a global chain. */
5658 hash_enter (cls_method_hash_list, method);
5662 /* Check types; if different, add to a list. */
5663 if (!comp_proto_with_proto (method, hsh->key))
5664 hash_add_attr (hsh, method);
5670 add_instance_method (class, method)
5677 if (!(mth = lookup_method (CLASS_NST_METHODS (class), method)))
5679 /* Put method on list in reverse order. */
5680 TREE_CHAIN (method) = CLASS_NST_METHODS (class);
5681 CLASS_NST_METHODS (class) = method;
5685 if (TREE_CODE (class) == CLASS_IMPLEMENTATION_TYPE)
5686 error ("duplicate definition of instance method `%s'",
5687 IDENTIFIER_POINTER (METHOD_SEL_NAME (mth)));
5690 /* Check types; if different, complain. */
5691 if (!comp_proto_with_proto (method, mth))
5692 error ("duplicate declaration of instance method `%s'",
5693 IDENTIFIER_POINTER (METHOD_SEL_NAME (mth)));
5697 if (!(hsh = hash_lookup (nst_method_hash_list, METHOD_SEL_NAME (method))))
5699 /* Install on a global chain. */
5700 hash_enter (nst_method_hash_list, method);
5704 /* Check types; if different, add to a list. */
5705 if (!comp_proto_with_proto (method, hsh->key))
5706 hash_add_attr (hsh, method);
5715 /* Put interfaces on list in reverse order. */
5716 TREE_CHAIN (class) = interface_chain;
5717 interface_chain = class;
5718 return interface_chain;
5722 add_category (class, category)
5726 /* Put categories on list in reverse order. */
5727 tree cat = CLASS_CATEGORY_LIST (class);
5731 if (CLASS_SUPER_NAME (cat) == CLASS_SUPER_NAME (category))
5732 warning ("duplicate interface declaration for category `%s(%s)'",
5733 IDENTIFIER_POINTER (CLASS_NAME (class)),
5734 IDENTIFIER_POINTER (CLASS_SUPER_NAME (category)));
5735 cat = CLASS_CATEGORY_LIST (cat);
5738 CLASS_CATEGORY_LIST (category) = CLASS_CATEGORY_LIST (class);
5739 CLASS_CATEGORY_LIST (class) = category;
5742 /* Called after parsing each instance variable declaration. Necessary to
5743 preserve typedefs and implement public/private...
5745 PUBLIC is 1 for public, 0 for protected, and 2 for private. */
5748 add_instance_variable (class, public, declarator, declspecs, width)
5755 tree field_decl, raw_decl;
5757 raw_decl = build_tree_list (declspecs, declarator);
5759 if (CLASS_RAW_IVARS (class))
5760 chainon (CLASS_RAW_IVARS (class), raw_decl);
5762 CLASS_RAW_IVARS (class) = raw_decl;
5764 field_decl = grokfield (declarator, declspecs, width);
5766 /* Overload the public attribute, it is not used for FIELD_DECLs. */
5770 TREE_PUBLIC (field_decl) = 0;
5771 TREE_PRIVATE (field_decl) = 0;
5772 TREE_PROTECTED (field_decl) = 1;
5776 TREE_PUBLIC (field_decl) = 1;
5777 TREE_PRIVATE (field_decl) = 0;
5778 TREE_PROTECTED (field_decl) = 0;
5782 TREE_PUBLIC (field_decl) = 0;
5783 TREE_PRIVATE (field_decl) = 1;
5784 TREE_PROTECTED (field_decl) = 0;
5789 if (CLASS_IVARS (class))
5790 chainon (CLASS_IVARS (class), field_decl);
5792 CLASS_IVARS (class) = field_decl;
5798 is_ivar (decl_chain, ident)
5802 for ( ; decl_chain; decl_chain = TREE_CHAIN (decl_chain))
5803 if (DECL_NAME (decl_chain) == ident)
5808 /* True if the ivar is private and we are not in its implementation. */
5814 if (TREE_PRIVATE (decl)
5815 && ! is_ivar (CLASS_IVARS (implementation_template), DECL_NAME (decl)))
5817 error ("instance variable `%s' is declared private",
5818 IDENTIFIER_POINTER (DECL_NAME (decl)));
5825 /* We have an instance variable reference;, check to see if it is public. */
5828 is_public (expr, identifier)
5832 tree basetype = TREE_TYPE (expr);
5833 enum tree_code code = TREE_CODE (basetype);
5836 if (code == RECORD_TYPE)
5838 if (TREE_STATIC_TEMPLATE (basetype))
5840 if (!lookup_interface (TYPE_NAME (basetype)))
5842 error ("cannot find interface declaration for `%s'",
5843 IDENTIFIER_POINTER (TYPE_NAME (basetype)));
5847 if ((decl = is_ivar (TYPE_FIELDS (basetype), identifier)))
5849 if (TREE_PUBLIC (decl))
5852 /* Important difference between the Stepstone translator:
5853 all instance variables should be public within the context
5854 of the implementation. */
5855 if (objc_implementation_context
5856 && (((TREE_CODE (objc_implementation_context)
5857 == CLASS_IMPLEMENTATION_TYPE)
5858 || (TREE_CODE (objc_implementation_context)
5859 == CATEGORY_IMPLEMENTATION_TYPE))
5860 && (CLASS_NAME (objc_implementation_context)
5861 == TYPE_NAME (basetype))))
5862 return ! is_private (decl);
5864 error ("instance variable `%s' is declared %s",
5865 IDENTIFIER_POINTER (identifier),
5866 TREE_PRIVATE (decl) ? "private" : "protected");
5871 else if (objc_implementation_context && (basetype == objc_object_reference))
5873 TREE_TYPE (expr) = uprivate_record;
5874 warning ("static access to object of type `id'");
5881 /* Make sure all entries in CHAIN are also in LIST. */
5884 check_methods (chain, list, mtype)
5893 if (!lookup_method (list, chain))
5897 if (TREE_CODE (objc_implementation_context)
5898 == CLASS_IMPLEMENTATION_TYPE)
5899 warning ("incomplete implementation of class `%s'",
5900 IDENTIFIER_POINTER (CLASS_NAME (objc_implementation_context)));
5901 else if (TREE_CODE (objc_implementation_context)
5902 == CATEGORY_IMPLEMENTATION_TYPE)
5903 warning ("incomplete implementation of category `%s'",
5904 IDENTIFIER_POINTER (CLASS_SUPER_NAME (objc_implementation_context)));
5908 warning ("method definition for `%c%s' not found",
5909 mtype, IDENTIFIER_POINTER (METHOD_SEL_NAME (chain)));
5912 chain = TREE_CHAIN (chain);
5918 /* Check if CLASS, or its superclasses, explicitly conforms to PROTOCOL. */
5921 conforms_to_protocol (class, protocol)
5925 if (TREE_CODE (protocol) == PROTOCOL_INTERFACE_TYPE)
5927 tree p = CLASS_PROTOCOL_LIST (class);
5928 while (p && TREE_VALUE (p) != protocol)
5933 tree super = (CLASS_SUPER_NAME (class)
5934 ? lookup_interface (CLASS_SUPER_NAME (class))
5936 int tmp = super ? conforms_to_protocol (super, protocol) : 0;
5945 /* Make sure all methods in CHAIN are accessible as MTYPE methods in
5946 CONTEXT. This is one of two mechanisms to check protocol integrity. */
5949 check_methods_accessible (chain, context, mtype)
5956 tree base_context = context;
5960 context = base_context;
5964 list = CLASS_CLS_METHODS (context);
5966 list = CLASS_NST_METHODS (context);
5968 if (lookup_method (list, chain))
5971 else if (TREE_CODE (context) == CLASS_IMPLEMENTATION_TYPE
5972 || TREE_CODE (context) == CLASS_INTERFACE_TYPE)
5973 context = (CLASS_SUPER_NAME (context)
5974 ? lookup_interface (CLASS_SUPER_NAME (context))
5977 else if (TREE_CODE (context) == CATEGORY_IMPLEMENTATION_TYPE
5978 || TREE_CODE (context) == CATEGORY_INTERFACE_TYPE)
5979 context = (CLASS_NAME (context)
5980 ? lookup_interface (CLASS_NAME (context))
5986 if (context == NULL_TREE)
5990 if (TREE_CODE (objc_implementation_context)
5991 == CLASS_IMPLEMENTATION_TYPE)
5992 warning ("incomplete implementation of class `%s'",
5994 (CLASS_NAME (objc_implementation_context)));
5995 else if (TREE_CODE (objc_implementation_context)
5996 == CATEGORY_IMPLEMENTATION_TYPE)
5997 warning ("incomplete implementation of category `%s'",
5999 (CLASS_SUPER_NAME (objc_implementation_context)));
6002 warning ("method definition for `%c%s' not found",
6003 mtype, IDENTIFIER_POINTER (METHOD_SEL_NAME (chain)));
6006 chain = TREE_CHAIN (chain); /* next method... */
6011 /* Check whether the current interface (accessible via
6012 'objc_implementation_context') actually implements protocol P, along
6013 with any protocols that P inherits. */
6016 check_protocol (p, type, name)
6021 if (TREE_CODE (p) == PROTOCOL_INTERFACE_TYPE)
6025 /* Ensure that all protocols have bodies! */
6028 f1 = check_methods (PROTOCOL_CLS_METHODS (p),
6029 CLASS_CLS_METHODS (objc_implementation_context),
6031 f2 = check_methods (PROTOCOL_NST_METHODS (p),
6032 CLASS_NST_METHODS (objc_implementation_context),
6037 f1 = check_methods_accessible (PROTOCOL_CLS_METHODS (p),
6038 objc_implementation_context,
6040 f2 = check_methods_accessible (PROTOCOL_NST_METHODS (p),
6041 objc_implementation_context,
6046 warning ("%s `%s' does not fully implement the `%s' protocol",
6047 type, name, IDENTIFIER_POINTER (PROTOCOL_NAME (p)));
6050 /* Check protocols recursively. */
6051 if (PROTOCOL_LIST (p))
6053 tree subs = PROTOCOL_LIST (p);
6055 lookup_interface (CLASS_SUPER_NAME (implementation_template));
6059 tree sub = TREE_VALUE (subs);
6061 /* If the superclass does not conform to the protocols
6062 inherited by P, then we must! */
6063 if (!super_class || !conforms_to_protocol (super_class, sub))
6064 check_protocol (sub, type, name);
6065 subs = TREE_CHAIN (subs);
6070 /* Check whether the current interface (accessible via
6071 'objc_implementation_context') actually implements the protocols listed
6075 check_protocols (proto_list, type, name)
6080 for ( ; proto_list; proto_list = TREE_CHAIN (proto_list))
6082 tree p = TREE_VALUE (proto_list);
6084 check_protocol (p, type, name);
6088 /* Make sure that the class CLASS_NAME is defined
6089 CODE says which kind of thing CLASS_NAME ought to be.
6090 It can be CLASS_INTERFACE_TYPE, CLASS_IMPLEMENTATION_TYPE,
6091 CATEGORY_INTERFACE_TYPE, or CATEGORY_IMPLEMENTATION_TYPE. */
6094 start_class (code, class_name, super_name, protocol_list)
6095 enum tree_code code;
6102 if (objc_implementation_context)
6104 warning ("`@end' missing in implementation context");
6105 finish_class (objc_implementation_context);
6106 objc_ivar_chain = NULL_TREE;
6107 objc_implementation_context = NULL_TREE;
6110 class = make_node (code);
6111 TYPE_BINFO (class) = make_tree_vec (BINFO_ELTS);
6113 CLASS_NAME (class) = class_name;
6114 CLASS_SUPER_NAME (class) = super_name;
6115 CLASS_CLS_METHODS (class) = NULL_TREE;
6117 if (! is_class_name (class_name) && (decl = lookup_name (class_name)))
6119 error ("`%s' redeclared as different kind of symbol",
6120 IDENTIFIER_POINTER (class_name));
6121 error ("%Hprevious declaration of '%D'",
6122 &DECL_SOURCE_LOCATION (decl), decl);
6125 if (code == CLASS_IMPLEMENTATION_TYPE)
6130 for (chain = implemented_classes; chain; chain = TREE_CHAIN (chain))
6131 if (TREE_VALUE (chain) == class_name)
6133 error ("reimplementation of class `%s'",
6134 IDENTIFIER_POINTER (class_name));
6135 return error_mark_node;
6137 implemented_classes = tree_cons (NULL_TREE, class_name,
6138 implemented_classes);
6141 /* Pre-build the following entities - for speed/convenience. */
6143 self_id = get_identifier ("self");
6145 ucmd_id = get_identifier ("_cmd");
6148 = build_tree_list (get_identifier ("__unused__"), NULL_TREE);
6149 if (!objc_super_template)
6150 objc_super_template = build_super_template ();
6152 /* Reset for multiple classes per file. */
6155 objc_implementation_context = class;
6157 /* Lookup the interface for this implementation. */
6159 if (!(implementation_template = lookup_interface (class_name)))
6161 warning ("cannot find interface declaration for `%s'",
6162 IDENTIFIER_POINTER (class_name));
6163 add_class (implementation_template = objc_implementation_context);
6166 /* If a super class has been specified in the implementation,
6167 insure it conforms to the one specified in the interface. */
6170 && (super_name != CLASS_SUPER_NAME (implementation_template)))
6172 tree previous_name = CLASS_SUPER_NAME (implementation_template);
6173 const char *const name =
6174 previous_name ? IDENTIFIER_POINTER (previous_name) : "";
6175 error ("conflicting super class name `%s'",
6176 IDENTIFIER_POINTER (super_name));
6177 error ("previous declaration of `%s'", name);
6180 else if (! super_name)
6182 CLASS_SUPER_NAME (objc_implementation_context)
6183 = CLASS_SUPER_NAME (implementation_template);
6187 else if (code == CLASS_INTERFACE_TYPE)
6189 if (lookup_interface (class_name))
6190 warning ("duplicate interface declaration for class `%s'",
6191 IDENTIFIER_POINTER (class_name));
6196 CLASS_PROTOCOL_LIST (class)
6197 = lookup_and_install_protocols (protocol_list);
6200 else if (code == CATEGORY_INTERFACE_TYPE)
6202 tree class_category_is_assoc_with;
6204 /* For a category, class_name is really the name of the class that
6205 the following set of methods will be associated with. We must
6206 find the interface so that can derive the objects template. */
6208 if (!(class_category_is_assoc_with = lookup_interface (class_name)))
6210 error ("cannot find interface declaration for `%s'",
6211 IDENTIFIER_POINTER (class_name));
6212 exit (FATAL_EXIT_CODE);
6215 add_category (class_category_is_assoc_with, class);
6218 CLASS_PROTOCOL_LIST (class)
6219 = lookup_and_install_protocols (protocol_list);
6222 else if (code == CATEGORY_IMPLEMENTATION_TYPE)
6224 /* Pre-build the following entities for speed/convenience. */
6226 self_id = get_identifier ("self");
6228 ucmd_id = get_identifier ("_cmd");
6231 = build_tree_list (get_identifier ("__unused__"), NULL_TREE);
6232 if (!objc_super_template)
6233 objc_super_template = build_super_template ();
6235 /* Reset for multiple classes per file. */
6238 objc_implementation_context = class;
6240 /* For a category, class_name is really the name of the class that
6241 the following set of methods will be associated with. We must
6242 find the interface so that can derive the objects template. */
6244 if (!(implementation_template = lookup_interface (class_name)))
6246 error ("cannot find interface declaration for `%s'",
6247 IDENTIFIER_POINTER (class_name));
6248 exit (FATAL_EXIT_CODE);
6255 continue_class (class)
6258 if (TREE_CODE (class) == CLASS_IMPLEMENTATION_TYPE
6259 || TREE_CODE (class) == CATEGORY_IMPLEMENTATION_TYPE)
6261 struct imp_entry *imp_entry;
6264 /* Check consistency of the instance variables. */
6266 if (CLASS_IVARS (class))
6267 check_ivars (implementation_template, class);
6269 /* code generation */
6271 ivar_context = build_private_template (implementation_template);
6273 if (!objc_class_template)
6274 build_class_template ();
6276 imp_entry = ggc_alloc (sizeof (struct imp_entry));
6278 imp_entry->next = imp_list;
6279 imp_entry->imp_context = class;
6280 imp_entry->imp_template = implementation_template;
6282 synth_forward_declarations ();
6283 imp_entry->class_decl = UOBJC_CLASS_decl;
6284 imp_entry->meta_decl = UOBJC_METACLASS_decl;
6286 /* Append to front and increment count. */
6287 imp_list = imp_entry;
6288 if (TREE_CODE (class) == CLASS_IMPLEMENTATION_TYPE)
6293 return ivar_context;
6296 else if (TREE_CODE (class) == CLASS_INTERFACE_TYPE)
6298 tree record = xref_tag (RECORD_TYPE, CLASS_NAME (class));
6300 if (!TYPE_FIELDS (record))
6302 finish_struct (record, get_class_ivars (class), NULL_TREE);
6303 CLASS_STATIC_TEMPLATE (class) = record;
6305 /* Mark this record as a class template for static typing. */
6306 TREE_STATIC_TEMPLATE (record) = 1;
6313 return error_mark_node;
6316 /* This is called once we see the "@end" in an interface/implementation. */
6319 finish_class (class)
6322 if (TREE_CODE (class) == CLASS_IMPLEMENTATION_TYPE)
6324 /* All code generation is done in finish_objc. */
6326 if (implementation_template != objc_implementation_context)
6328 /* Ensure that all method listed in the interface contain bodies. */
6329 check_methods (CLASS_CLS_METHODS (implementation_template),
6330 CLASS_CLS_METHODS (objc_implementation_context), '+');
6331 check_methods (CLASS_NST_METHODS (implementation_template),
6332 CLASS_NST_METHODS (objc_implementation_context), '-');
6334 if (CLASS_PROTOCOL_LIST (implementation_template))
6335 check_protocols (CLASS_PROTOCOL_LIST (implementation_template),
6337 IDENTIFIER_POINTER (CLASS_NAME (objc_implementation_context)));
6341 else if (TREE_CODE (class) == CATEGORY_IMPLEMENTATION_TYPE)
6343 tree category = CLASS_CATEGORY_LIST (implementation_template);
6345 /* Find the category interface from the class it is associated with. */
6348 if (CLASS_SUPER_NAME (class) == CLASS_SUPER_NAME (category))
6350 category = CLASS_CATEGORY_LIST (category);
6355 /* Ensure all method listed in the interface contain bodies. */
6356 check_methods (CLASS_CLS_METHODS (category),
6357 CLASS_CLS_METHODS (objc_implementation_context), '+');
6358 check_methods (CLASS_NST_METHODS (category),
6359 CLASS_NST_METHODS (objc_implementation_context), '-');
6361 if (CLASS_PROTOCOL_LIST (category))
6362 check_protocols (CLASS_PROTOCOL_LIST (category),
6364 IDENTIFIER_POINTER (CLASS_SUPER_NAME (objc_implementation_context)));
6368 else if (TREE_CODE (class) == CLASS_INTERFACE_TYPE)
6371 const char *class_name = IDENTIFIER_POINTER (CLASS_NAME (class));
6372 char *string = alloca (strlen (class_name) + 3);
6374 /* extern struct objc_object *_<my_name>; */
6376 sprintf (string, "_%s", class_name);
6378 decl_specs = build_tree_list (NULL_TREE, ridpointers[(int) RID_EXTERN]);
6379 decl_specs = tree_cons (NULL_TREE, objc_object_reference, decl_specs);
6380 define_decl (build1 (INDIRECT_REF, NULL_TREE, get_identifier (string)),
6386 add_protocol (protocol)
6389 /* Put protocol on list in reverse order. */
6390 TREE_CHAIN (protocol) = protocol_chain;
6391 protocol_chain = protocol;
6392 return protocol_chain;
6396 lookup_protocol (ident)
6401 for (chain = protocol_chain; chain; chain = TREE_CHAIN (chain))
6402 if (ident == PROTOCOL_NAME (chain))
6408 /* This function forward declares the protocols named by NAMES. If
6409 they are already declared or defined, the function has no effect. */
6412 objc_declare_protocols (names)
6417 for (list = names; list; list = TREE_CHAIN (list))
6419 tree name = TREE_VALUE (list);
6421 if (lookup_protocol (name) == NULL_TREE)
6423 tree protocol = make_node (PROTOCOL_INTERFACE_TYPE);
6425 TYPE_BINFO (protocol) = make_tree_vec (2);
6426 PROTOCOL_NAME (protocol) = name;
6427 PROTOCOL_LIST (protocol) = NULL_TREE;
6428 add_protocol (protocol);
6429 PROTOCOL_DEFINED (protocol) = 0;
6430 PROTOCOL_FORWARD_DECL (protocol) = NULL_TREE;
6436 start_protocol (code, name, list)
6437 enum tree_code code;
6443 /* This is as good a place as any. Need to invoke
6444 push_tag_toplevel. */
6445 if (!objc_protocol_template)
6446 objc_protocol_template = build_protocol_template ();
6448 protocol = lookup_protocol (name);
6452 protocol = make_node (code);
6453 TYPE_BINFO (protocol) = make_tree_vec (2);
6455 PROTOCOL_NAME (protocol) = name;
6456 PROTOCOL_LIST (protocol) = lookup_and_install_protocols (list);
6457 add_protocol (protocol);
6458 PROTOCOL_DEFINED (protocol) = 1;
6459 PROTOCOL_FORWARD_DECL (protocol) = NULL_TREE;
6461 check_protocol_recursively (protocol, list);
6463 else if (! PROTOCOL_DEFINED (protocol))
6465 PROTOCOL_DEFINED (protocol) = 1;
6466 PROTOCOL_LIST (protocol) = lookup_and_install_protocols (list);
6468 check_protocol_recursively (protocol, list);
6472 warning ("duplicate declaration for protocol `%s'",
6473 IDENTIFIER_POINTER (name));
6479 finish_protocol (protocol)
6480 tree protocol ATTRIBUTE_UNUSED;
6485 /* "Encode" a data type into a string, which grows in util_obstack.
6486 ??? What is the FORMAT? Someone please document this! */
6489 encode_type_qualifiers (declspecs)
6494 for (spec = declspecs; spec; spec = TREE_CHAIN (spec))
6496 if (ridpointers[(int) RID_CONST] == TREE_VALUE (spec))
6497 obstack_1grow (&util_obstack, 'r');
6498 else if (ridpointers[(int) RID_IN] == TREE_VALUE (spec))
6499 obstack_1grow (&util_obstack, 'n');
6500 else if (ridpointers[(int) RID_INOUT] == TREE_VALUE (spec))
6501 obstack_1grow (&util_obstack, 'N');
6502 else if (ridpointers[(int) RID_OUT] == TREE_VALUE (spec))
6503 obstack_1grow (&util_obstack, 'o');
6504 else if (ridpointers[(int) RID_BYCOPY] == TREE_VALUE (spec))
6505 obstack_1grow (&util_obstack, 'O');
6506 else if (ridpointers[(int) RID_BYREF] == TREE_VALUE (spec))
6507 obstack_1grow (&util_obstack, 'R');
6508 else if (ridpointers[(int) RID_ONEWAY] == TREE_VALUE (spec))
6509 obstack_1grow (&util_obstack, 'V');
6513 /* Encode a pointer type. */
6516 encode_pointer (type, curtype, format)
6521 tree pointer_to = TREE_TYPE (type);
6523 if (TREE_CODE (pointer_to) == RECORD_TYPE)
6525 if (TYPE_NAME (pointer_to)
6526 && TREE_CODE (TYPE_NAME (pointer_to)) == IDENTIFIER_NODE)
6528 const char *name = IDENTIFIER_POINTER (TYPE_NAME (pointer_to));
6530 if (strcmp (name, TAG_OBJECT) == 0) /* '@' */
6532 obstack_1grow (&util_obstack, '@');
6535 else if (TREE_STATIC_TEMPLATE (pointer_to))
6537 if (generating_instance_variables)
6539 obstack_1grow (&util_obstack, '@');
6540 obstack_1grow (&util_obstack, '"');
6541 obstack_grow (&util_obstack, name, strlen (name));
6542 obstack_1grow (&util_obstack, '"');
6547 obstack_1grow (&util_obstack, '@');
6551 else if (strcmp (name, TAG_CLASS) == 0) /* '#' */
6553 obstack_1grow (&util_obstack, '#');
6556 else if (strcmp (name, TAG_SELECTOR) == 0) /* ':' */
6558 obstack_1grow (&util_obstack, ':');
6563 else if (TREE_CODE (pointer_to) == INTEGER_TYPE
6564 && TYPE_MODE (pointer_to) == QImode)
6566 obstack_1grow (&util_obstack, '*');
6570 /* We have a type that does not get special treatment. */
6572 /* NeXT extension */
6573 obstack_1grow (&util_obstack, '^');
6574 encode_type (pointer_to, curtype, format);
6578 encode_array (type, curtype, format)
6583 tree an_int_cst = TYPE_SIZE (type);
6584 tree array_of = TREE_TYPE (type);
6587 /* An incomplete array is treated like a pointer. */
6588 if (an_int_cst == NULL)
6590 encode_pointer (type, curtype, format);
6594 sprintf (buffer, "[%ld",
6595 (long) (TREE_INT_CST_LOW (an_int_cst)
6596 / TREE_INT_CST_LOW (TYPE_SIZE (array_of))));
6598 obstack_grow (&util_obstack, buffer, strlen (buffer));
6599 encode_type (array_of, curtype, format);
6600 obstack_1grow (&util_obstack, ']');
6605 encode_aggregate_within (type, curtype, format, left, right)
6612 /* The RECORD_TYPE may in fact be a typedef! For purposes
6613 of encoding, we need the real underlying enchilada. */
6614 if (TYPE_MAIN_VARIANT (type))
6615 type = TYPE_MAIN_VARIANT (type);
6617 if (obstack_object_size (&util_obstack) > 0
6618 && *(obstack_next_free (&util_obstack) - 1) == '^')
6620 tree name = TYPE_NAME (type);
6622 /* we have a reference; this is a NeXT extension. */
6624 if (obstack_object_size (&util_obstack) - curtype == 1
6625 && format == OBJC_ENCODE_INLINE_DEFS)
6627 /* Output format of struct for first level only. */
6628 tree fields = TYPE_FIELDS (type);
6630 if (name && TREE_CODE (name) == IDENTIFIER_NODE)
6632 obstack_1grow (&util_obstack, left);
6633 obstack_grow (&util_obstack,
6634 IDENTIFIER_POINTER (name),
6635 strlen (IDENTIFIER_POINTER (name)));
6636 obstack_1grow (&util_obstack, '=');
6640 obstack_1grow (&util_obstack, left);
6641 obstack_grow (&util_obstack, "?=", 2);
6644 for ( ; fields; fields = TREE_CHAIN (fields))
6645 encode_field_decl (fields, curtype, format);
6647 obstack_1grow (&util_obstack, right);
6650 else if (name && TREE_CODE (name) == IDENTIFIER_NODE)
6652 obstack_1grow (&util_obstack, left);
6653 obstack_grow (&util_obstack,
6654 IDENTIFIER_POINTER (name),
6655 strlen (IDENTIFIER_POINTER (name)));
6656 obstack_1grow (&util_obstack, right);
6661 /* We have an untagged structure or a typedef. */
6662 obstack_1grow (&util_obstack, left);
6663 obstack_1grow (&util_obstack, '?');
6664 obstack_1grow (&util_obstack, right);
6670 tree name = TYPE_NAME (type);
6671 tree fields = TYPE_FIELDS (type);
6673 if (format == OBJC_ENCODE_INLINE_DEFS
6674 || generating_instance_variables)
6676 obstack_1grow (&util_obstack, left);
6677 if (name && TREE_CODE (name) == IDENTIFIER_NODE)
6678 obstack_grow (&util_obstack,
6679 IDENTIFIER_POINTER (name),
6680 strlen (IDENTIFIER_POINTER (name)));
6682 obstack_1grow (&util_obstack, '?');
6684 obstack_1grow (&util_obstack, '=');
6686 for (; fields; fields = TREE_CHAIN (fields))
6688 if (generating_instance_variables)
6690 tree fname = DECL_NAME (fields);
6692 obstack_1grow (&util_obstack, '"');
6693 if (fname && TREE_CODE (fname) == IDENTIFIER_NODE)
6695 obstack_grow (&util_obstack,
6696 IDENTIFIER_POINTER (fname),
6697 strlen (IDENTIFIER_POINTER (fname)));
6700 obstack_1grow (&util_obstack, '"');
6703 encode_field_decl (fields, curtype, format);
6706 obstack_1grow (&util_obstack, right);
6711 obstack_1grow (&util_obstack, left);
6712 if (name && TREE_CODE (name) == IDENTIFIER_NODE)
6713 obstack_grow (&util_obstack,
6714 IDENTIFIER_POINTER (name),
6715 strlen (IDENTIFIER_POINTER (name)));
6717 /* We have an untagged structure or a typedef. */
6718 obstack_1grow (&util_obstack, '?');
6720 obstack_1grow (&util_obstack, right);
6726 encode_aggregate (type, curtype, format)
6731 enum tree_code code = TREE_CODE (type);
6737 encode_aggregate_within(type, curtype, format, '{', '}');
6742 encode_aggregate_within(type, curtype, format, '(', ')');
6747 obstack_1grow (&util_obstack, 'i');
6755 /* Support bitfields. The current version of Objective-C does not support
6756 them. The string will consist of one or more "b:n"'s where n is an
6757 integer describing the width of the bitfield. Currently, classes in
6758 the kit implement a method "-(char *)describeBitfieldStruct:" that
6759 simulates this. If they do not implement this method, the archiver
6760 assumes the bitfield is 16 bits wide (padded if necessary) and packed
6761 according to the GNU compiler. After looking at the "kit", it appears
6762 that all classes currently rely on this default behavior, rather than
6763 hand generating this string (which is tedious). */
6766 encode_bitfield (width)
6770 sprintf (buffer, "b%d", width);
6771 obstack_grow (&util_obstack, buffer, strlen (buffer));
6774 /* FORMAT will be OBJC_ENCODE_INLINE_DEFS or OBJC_ENCODE_DONT_INLINE_DEFS. */
6777 encode_type (type, curtype, format)
6782 enum tree_code code = TREE_CODE (type);
6784 if (code == INTEGER_TYPE)
6786 if (integer_zerop (TYPE_MIN_VALUE (type)))
6788 /* Unsigned integer types. */
6790 if (TYPE_MODE (type) == QImode)
6791 obstack_1grow (&util_obstack, 'C');
6792 else if (TYPE_MODE (type) == HImode)
6793 obstack_1grow (&util_obstack, 'S');
6794 else if (TYPE_MODE (type) == SImode)
6796 if (type == long_unsigned_type_node)
6797 obstack_1grow (&util_obstack, 'L');
6799 obstack_1grow (&util_obstack, 'I');
6801 else if (TYPE_MODE (type) == DImode)
6802 obstack_1grow (&util_obstack, 'Q');
6806 /* Signed integer types. */
6808 if (TYPE_MODE (type) == QImode)
6809 obstack_1grow (&util_obstack, 'c');
6810 else if (TYPE_MODE (type) == HImode)
6811 obstack_1grow (&util_obstack, 's');
6812 else if (TYPE_MODE (type) == SImode)
6814 if (type == long_integer_type_node)
6815 obstack_1grow (&util_obstack, 'l');
6817 obstack_1grow (&util_obstack, 'i');
6820 else if (TYPE_MODE (type) == DImode)
6821 obstack_1grow (&util_obstack, 'q');
6825 else if (code == REAL_TYPE)
6827 /* Floating point types. */
6829 if (TYPE_MODE (type) == SFmode)
6830 obstack_1grow (&util_obstack, 'f');
6831 else if (TYPE_MODE (type) == DFmode
6832 || TYPE_MODE (type) == TFmode)
6833 obstack_1grow (&util_obstack, 'd');
6836 else if (code == VOID_TYPE)
6837 obstack_1grow (&util_obstack, 'v');
6839 else if (code == ARRAY_TYPE)
6840 encode_array (type, curtype, format);
6842 else if (code == POINTER_TYPE)
6843 encode_pointer (type, curtype, format);
6845 else if (code == RECORD_TYPE || code == UNION_TYPE || code == ENUMERAL_TYPE)
6846 encode_aggregate (type, curtype, format);
6848 else if (code == FUNCTION_TYPE) /* '?' */
6849 obstack_1grow (&util_obstack, '?');
6853 encode_complete_bitfield (position, type, size)
6858 enum tree_code code = TREE_CODE (type);
6860 char charType = '?';
6862 if (code == INTEGER_TYPE)
6864 if (integer_zerop (TYPE_MIN_VALUE (type)))
6866 /* Unsigned integer types. */
6868 if (TYPE_MODE (type) == QImode)
6870 else if (TYPE_MODE (type) == HImode)
6872 else if (TYPE_MODE (type) == SImode)
6874 if (type == long_unsigned_type_node)
6879 else if (TYPE_MODE (type) == DImode)
6884 /* Signed integer types. */
6886 if (TYPE_MODE (type) == QImode)
6888 else if (TYPE_MODE (type) == HImode)
6890 else if (TYPE_MODE (type) == SImode)
6892 if (type == long_integer_type_node)
6898 else if (TYPE_MODE (type) == DImode)
6902 else if (code == ENUMERAL_TYPE)
6907 sprintf (buffer, "b%d%c%d", position, charType, size);
6908 obstack_grow (&util_obstack, buffer, strlen (buffer));
6912 encode_field_decl (field_decl, curtype, format)
6919 type = TREE_TYPE (field_decl);
6921 /* If this field is obviously a bitfield, or is a bitfield that has been
6922 clobbered to look like a ordinary integer mode, go ahead and generate
6923 the bitfield typing information. */
6924 if (flag_next_runtime)
6926 if (DECL_BIT_FIELD_TYPE (field_decl))
6927 encode_bitfield (tree_low_cst (DECL_SIZE (field_decl), 1));
6929 encode_type (TREE_TYPE (field_decl), curtype, format);
6933 if (DECL_BIT_FIELD_TYPE (field_decl))
6934 encode_complete_bitfield (int_bit_position (field_decl),
6935 DECL_BIT_FIELD_TYPE (field_decl),
6936 tree_low_cst (DECL_SIZE (field_decl), 1));
6938 encode_type (TREE_TYPE (field_decl), curtype, format);
6943 objc_expr_last (complex_expr)
6949 while ((next = TREE_OPERAND (complex_expr, 0)))
6950 complex_expr = next;
6952 return complex_expr;
6955 /* Transform a method definition into a function definition as follows:
6956 - synthesize the first two arguments, "self" and "_cmd". */
6959 start_method_def (method)
6964 /* Required to implement _msgSuper. */
6965 objc_method_context = method;
6966 UOBJC_SUPER_decl = NULL_TREE;
6968 /* Must be called BEFORE start_function. */
6971 /* Generate prototype declarations for arguments..."new-style". */
6973 if (TREE_CODE (objc_method_context) == INSTANCE_METHOD_DECL)
6974 decl_specs = build_tree_list (NULL_TREE, uprivate_record);
6976 /* Really a `struct objc_class *'. However, we allow people to
6977 assign to self, which changes its type midstream. */
6978 decl_specs = build_tree_list (NULL_TREE, objc_object_reference);
6980 push_parm_decl (build_tree_list
6981 (build_tree_list (decl_specs,
6982 build1 (INDIRECT_REF, NULL_TREE, self_id)),
6985 decl_specs = build_tree_list (NULL_TREE,
6986 xref_tag (RECORD_TYPE,
6987 get_identifier (TAG_SELECTOR)));
6988 push_parm_decl (build_tree_list
6989 (build_tree_list (decl_specs,
6990 build1 (INDIRECT_REF, NULL_TREE, ucmd_id)),
6993 /* Generate argument declarations if a keyword_decl. */
6994 if (METHOD_SEL_ARGS (method))
6996 tree arglist = METHOD_SEL_ARGS (method);
6999 tree arg_spec = TREE_PURPOSE (TREE_TYPE (arglist));
7000 tree arg_decl = TREE_VALUE (TREE_TYPE (arglist));
7004 tree last_expr = objc_expr_last (arg_decl);
7006 /* Unite the abstract decl with its name. */
7007 TREE_OPERAND (last_expr, 0) = KEYWORD_ARG_NAME (arglist);
7008 push_parm_decl (build_tree_list
7009 (build_tree_list (arg_spec, arg_decl),
7012 /* Unhook: restore the abstract declarator. */
7013 TREE_OPERAND (last_expr, 0) = NULL_TREE;
7017 push_parm_decl (build_tree_list
7018 (build_tree_list (arg_spec,
7019 KEYWORD_ARG_NAME (arglist)),
7022 arglist = TREE_CHAIN (arglist);
7027 if (METHOD_ADD_ARGS (method) != NULL_TREE
7028 && METHOD_ADD_ARGS (method) != objc_ellipsis_node)
7030 /* We have a variable length selector - in "prototype" format. */
7031 tree akey = TREE_PURPOSE (METHOD_ADD_ARGS (method));
7034 /* This must be done prior to calling pushdecl. pushdecl is
7035 going to change our chain on us. */
7036 tree nextkey = TREE_CHAIN (akey);
7044 warn_with_method (message, mtype, method)
7045 const char *message;
7049 /* Add a readable method name to the warning. */
7050 warning ("%H%s `%c%s'", &DECL_SOURCE_LOCATION (method),
7051 message, mtype, gen_method_decl (method, errbuf));
7054 /* Return 1 if METHOD is consistent with PROTO. */
7057 comp_method_with_proto (method, proto)
7060 /* Create a function template node at most once. */
7061 if (!function1_template)
7062 function1_template = make_node (FUNCTION_TYPE);
7064 /* Install argument types - normally set by build_function_type. */
7065 TYPE_ARG_TYPES (function1_template) = get_arg_type_list (proto, METHOD_DEF, 0);
7067 /* install return type */
7068 TREE_TYPE (function1_template) = groktypename (TREE_TYPE (proto));
7070 return comptypes (TREE_TYPE (METHOD_DEFINITION (method)), function1_template,
7074 /* Return 1 if PROTO1 is consistent with PROTO2. */
7077 comp_proto_with_proto (proto0, proto1)
7078 tree proto0, proto1;
7080 /* Create a couple of function_template nodes at most once. */
7081 if (!function1_template)
7082 function1_template = make_node (FUNCTION_TYPE);
7083 if (!function2_template)
7084 function2_template = make_node (FUNCTION_TYPE);
7086 /* Install argument types; normally set by build_function_type. */
7087 TYPE_ARG_TYPES (function1_template) = get_arg_type_list (proto0, METHOD_REF, 0);
7088 TYPE_ARG_TYPES (function2_template) = get_arg_type_list (proto1, METHOD_REF, 0);
7090 /* Install return type. */
7091 TREE_TYPE (function1_template) = groktypename (TREE_TYPE (proto0));
7092 TREE_TYPE (function2_template) = groktypename (TREE_TYPE (proto1));
7094 return comptypes (function1_template, function2_template, false);
7097 /* - Generate an identifier for the function. the format is "_n_cls",
7098 where 1 <= n <= nMethods, and cls is the name the implementation we
7100 - Install the return type from the method declaration.
7101 - If we have a prototype, check for type consistency. */
7104 really_start_method (method, parmlist)
7105 tree method, parmlist;
7107 tree sc_spec, ret_spec, ret_decl, decl_specs;
7108 tree method_decl, method_id;
7109 const char *sel_name, *class_name, *cat_name;
7112 /* Synth the storage class & assemble the return type. */
7113 sc_spec = tree_cons (NULL_TREE, ridpointers[(int) RID_STATIC], NULL_TREE);
7114 ret_spec = TREE_PURPOSE (TREE_TYPE (method));
7115 decl_specs = chainon (sc_spec, ret_spec);
7117 sel_name = IDENTIFIER_POINTER (METHOD_SEL_NAME (method));
7118 class_name = IDENTIFIER_POINTER (CLASS_NAME (objc_implementation_context));
7119 cat_name = ((TREE_CODE (objc_implementation_context)
7120 == CLASS_IMPLEMENTATION_TYPE)
7122 : IDENTIFIER_POINTER (CLASS_SUPER_NAME (objc_implementation_context)));
7125 /* Make sure this is big enough for any plausible method label. */
7126 buf = alloca (50 + strlen (sel_name) + strlen (class_name)
7127 + (cat_name ? strlen (cat_name) : 0));
7129 OBJC_GEN_METHOD_LABEL (buf, TREE_CODE (method) == INSTANCE_METHOD_DECL,
7130 class_name, cat_name, sel_name, method_slot);
7132 method_id = get_identifier (buf);
7134 method_decl = build_nt (CALL_EXPR, method_id, parmlist, NULL_TREE);
7136 /* Check the declarator portion of the return type for the method. */
7137 if ((ret_decl = TREE_VALUE (TREE_TYPE (method))))
7139 /* Unite the complex decl (specified in the abstract decl) with the
7140 function decl just synthesized..(int *), (int (*)()), (int (*)[]). */
7141 tree save_expr = objc_expr_last (ret_decl);
7143 TREE_OPERAND (save_expr, 0) = method_decl;
7144 method_decl = ret_decl;
7146 /* Fool the parser into thinking it is starting a function. */
7147 start_function (decl_specs, method_decl, NULL_TREE);
7149 /* Unhook: this has the effect of restoring the abstract declarator. */
7150 TREE_OPERAND (save_expr, 0) = NULL_TREE;
7155 TREE_VALUE (TREE_TYPE (method)) = method_decl;
7157 /* Fool the parser into thinking it is starting a function. */
7158 start_function (decl_specs, method_decl, NULL_TREE);
7160 /* Unhook: this has the effect of restoring the abstract declarator. */
7161 TREE_VALUE (TREE_TYPE (method)) = NULL_TREE;
7164 METHOD_DEFINITION (method) = current_function_decl;
7166 /* Check consistency...start_function, pushdecl, duplicate_decls. */
7168 if (implementation_template != objc_implementation_context)
7172 if (TREE_CODE (method) == INSTANCE_METHOD_DECL)
7173 proto = lookup_instance_method_static (implementation_template,
7174 METHOD_SEL_NAME (method));
7176 proto = lookup_class_method_static (implementation_template,
7177 METHOD_SEL_NAME (method));
7179 if (proto && ! comp_method_with_proto (method, proto))
7181 char type = (TREE_CODE (method) == INSTANCE_METHOD_DECL ? '-' : '+');
7183 warn_with_method ("conflicting types for", type, method);
7184 warn_with_method ("previous declaration of", type, proto);
7189 /* The following routine is always called...this "architecture" is to
7190 accommodate "old-style" variable length selectors.
7192 - a:a b:b // prototype ; id c; id d; // old-style. */
7195 continue_method_def ()
7199 if (METHOD_ADD_ARGS (objc_method_context) == objc_ellipsis_node)
7200 /* We have a `, ...' immediately following the selector. */
7201 parmlist = get_parm_info (0);
7203 parmlist = get_parm_info (1); /* place a `void_at_end' */
7205 /* Set self_decl from the first argument...this global is used by
7206 build_ivar_reference calling build_indirect_ref. */
7207 self_decl = TREE_PURPOSE (parmlist);
7210 really_start_method (objc_method_context, parmlist);
7211 store_parm_decls ();
7214 /* Called by the parser, from the `pushlevel' production. */
7219 if (!UOBJC_SUPER_decl)
7221 UOBJC_SUPER_decl = start_decl (get_identifier (UTAG_SUPER),
7222 build_tree_list (NULL_TREE,
7223 objc_super_template),
7226 finish_decl (UOBJC_SUPER_decl, NULL_TREE, NULL_TREE);
7228 /* This prevents `unused variable' warnings when compiling with -Wall. */
7229 TREE_USED (UOBJC_SUPER_decl) = 1;
7230 DECL_ARTIFICIAL (UOBJC_SUPER_decl) = 1;
7234 /* _n_Method (id self, SEL sel, ...)
7236 struct objc_super _S;
7237 _msgSuper ((_S.self = self, _S.class = _cls, &_S), ...);
7241 get_super_receiver ()
7243 if (objc_method_context)
7245 tree super_expr, super_expr_list;
7247 /* Set receiver to self. */
7248 super_expr = build_component_ref (UOBJC_SUPER_decl, self_id);
7249 super_expr = build_modify_expr (super_expr, NOP_EXPR, self_decl);
7250 super_expr_list = build_tree_list (NULL_TREE, super_expr);
7252 /* Set class to begin searching. */
7253 super_expr = build_component_ref (UOBJC_SUPER_decl,
7254 get_identifier ("class"));
7256 if (TREE_CODE (objc_implementation_context) == CLASS_IMPLEMENTATION_TYPE)
7258 /* [_cls, __cls]Super are "pre-built" in
7259 synth_forward_declarations. */
7261 super_expr = build_modify_expr (super_expr, NOP_EXPR,
7262 ((TREE_CODE (objc_method_context)
7263 == INSTANCE_METHOD_DECL)
7265 : uucls_super_ref));
7269 /* We have a category. */
7271 tree super_name = CLASS_SUPER_NAME (implementation_template);
7274 /* Barf if super used in a category of Object. */
7277 error ("no super class declared in interface for `%s'",
7278 IDENTIFIER_POINTER (CLASS_NAME (implementation_template)));
7279 return error_mark_node;
7282 if (flag_next_runtime)
7284 super_class = get_class_reference (super_name);
7285 if (TREE_CODE (objc_method_context) == CLASS_METHOD_DECL)
7286 /* Cast the super class to 'id', since the user may not have
7287 included <objc/objc-class.h>, leaving 'struct objc_class'
7288 an incomplete type. */
7290 = build_component_ref (build_indirect_ref
7291 (build_c_cast (id_type, super_class), "->"),
7292 get_identifier ("isa"));
7296 add_class_reference (super_name);
7297 super_class = (TREE_CODE (objc_method_context) == INSTANCE_METHOD_DECL
7298 ? objc_get_class_decl : objc_get_meta_class_decl);
7299 assemble_external (super_class);
7301 = build_function_call
7305 my_build_string (IDENTIFIER_LENGTH (super_name) + 1,
7306 IDENTIFIER_POINTER (super_name))));
7309 TREE_TYPE (super_class) = TREE_TYPE (ucls_super_ref);
7310 super_expr = build_modify_expr (super_expr, NOP_EXPR, super_class);
7313 chainon (super_expr_list, build_tree_list (NULL_TREE, super_expr));
7315 super_expr = build_unary_op (ADDR_EXPR, UOBJC_SUPER_decl, 0);
7316 chainon (super_expr_list, build_tree_list (NULL_TREE, super_expr));
7318 return build_compound_expr (super_expr_list);
7322 error ("[super ...] must appear in a method context");
7323 return error_mark_node;
7328 encode_method_def (func_decl)
7333 HOST_WIDE_INT max_parm_end = 0;
7338 encode_type (TREE_TYPE (TREE_TYPE (func_decl)),
7339 obstack_object_size (&util_obstack),
7340 OBJC_ENCODE_INLINE_DEFS);
7343 for (parms = DECL_ARGUMENTS (func_decl); parms;
7344 parms = TREE_CHAIN (parms))
7346 HOST_WIDE_INT parm_end = (forwarding_offset (parms)
7347 + int_size_in_bytes (TREE_TYPE (parms)));
7349 if (! offset_is_register && parm_end > max_parm_end)
7350 max_parm_end = parm_end;
7353 stack_size = max_parm_end - OBJC_FORWARDING_MIN_OFFSET;
7355 sprintf (buffer, "%d", stack_size);
7356 obstack_grow (&util_obstack, buffer, strlen (buffer));
7358 /* Argument types. */
7359 for (parms = DECL_ARGUMENTS (func_decl); parms;
7360 parms = TREE_CHAIN (parms))
7363 encode_type (TREE_TYPE (parms),
7364 obstack_object_size (&util_obstack),
7365 OBJC_ENCODE_INLINE_DEFS);
7367 /* Compute offset. */
7368 sprintf (buffer, "%d", forwarding_offset (parms));
7370 /* Indicate register. */
7371 if (offset_is_register)
7372 obstack_1grow (&util_obstack, '+');
7374 obstack_grow (&util_obstack, buffer, strlen (buffer));
7377 /* Null terminate string. */
7378 obstack_1grow (&util_obstack, 0);
7379 result = get_identifier (obstack_finish (&util_obstack));
7380 obstack_free (&util_obstack, util_firstobj);
7385 objc_expand_function_end ()
7387 METHOD_ENCODING (objc_method_context) = encode_method_def (current_function_decl);
7391 finish_method_def ()
7393 lang_expand_function_end = objc_expand_function_end;
7395 lang_expand_function_end = NULL;
7397 /* Required to implement _msgSuper. This must be done AFTER finish_function,
7398 since the optimizer may find "may be used before set" errors. */
7399 objc_method_context = NULL_TREE;
7404 lang_report_error_function (decl)
7407 if (objc_method_context)
7409 fprintf (stderr, "In method `%s'\n",
7410 IDENTIFIER_POINTER (METHOD_SEL_NAME (objc_method_context)));
7420 is_complex_decl (type)
7423 return (TREE_CODE (type) == ARRAY_TYPE
7424 || TREE_CODE (type) == FUNCTION_TYPE
7425 || (TREE_CODE (type) == POINTER_TYPE && ! IS_ID (type)));
7429 /* Code to convert a decl node into text for a declaration in C. */
7431 static char tmpbuf[256];
7434 adorn_decl (decl, str)
7438 enum tree_code code = TREE_CODE (decl);
7440 if (code == ARRAY_REF)
7442 tree an_int_cst = TREE_OPERAND (decl, 1);
7444 if (an_int_cst && TREE_CODE (an_int_cst) == INTEGER_CST)
7445 sprintf (str + strlen (str), "[%ld]",
7446 (long) TREE_INT_CST_LOW (an_int_cst));
7451 else if (code == ARRAY_TYPE)
7453 tree an_int_cst = TYPE_SIZE (decl);
7454 tree array_of = TREE_TYPE (decl);
7456 if (an_int_cst && TREE_CODE (an_int_cst) == INTEGER_TYPE)
7457 sprintf (str + strlen (str), "[%ld]",
7458 (long) (TREE_INT_CST_LOW (an_int_cst)
7459 / TREE_INT_CST_LOW (TYPE_SIZE (array_of))));
7464 else if (code == CALL_EXPR)
7466 tree chain = TREE_PURPOSE (TREE_OPERAND (decl, 1));
7471 gen_declaration_1 (chain, str);
7472 chain = TREE_CHAIN (chain);
7479 else if (code == FUNCTION_TYPE)
7481 tree chain = TYPE_ARG_TYPES (decl);
7484 while (chain && TREE_VALUE (chain) != void_type_node)
7486 gen_declaration_1 (TREE_VALUE (chain), str);
7487 chain = TREE_CHAIN (chain);
7488 if (chain && TREE_VALUE (chain) != void_type_node)
7494 else if (code == INDIRECT_REF)
7496 strcpy (tmpbuf, "*");
7497 if (TREE_TYPE (decl) && TREE_CODE (TREE_TYPE (decl)) == TREE_LIST)
7501 for (chain = nreverse (copy_list (TREE_TYPE (decl)));
7503 chain = TREE_CHAIN (chain))
7505 if (TREE_CODE (TREE_VALUE (chain)) == IDENTIFIER_NODE)
7507 strcat (tmpbuf, " ");
7508 strcat (tmpbuf, IDENTIFIER_POINTER (TREE_VALUE (chain)));
7512 strcat (tmpbuf, " ");
7514 strcat (tmpbuf, str);
7515 strcpy (str, tmpbuf);
7518 else if (code == POINTER_TYPE)
7520 strcpy (tmpbuf, "*");
7521 if (TREE_READONLY (decl) || TYPE_VOLATILE (decl))
7523 if (TREE_READONLY (decl))
7524 strcat (tmpbuf, " const");
7525 if (TYPE_VOLATILE (decl))
7526 strcat (tmpbuf, " volatile");
7528 strcat (tmpbuf, " ");
7530 strcat (tmpbuf, str);
7531 strcpy (str, tmpbuf);
7536 gen_declarator (decl, buf, name)
7543 enum tree_code code = TREE_CODE (decl);
7553 op = TREE_OPERAND (decl, 0);
7555 /* We have a pointer to a function or array...(*)(), (*)[] */
7556 if ((code == ARRAY_REF || code == CALL_EXPR)
7557 && op && TREE_CODE (op) == INDIRECT_REF)
7560 str = gen_declarator (op, buf, name);
7564 strcpy (tmpbuf, "(");
7565 strcat (tmpbuf, str);
7566 strcat (tmpbuf, ")");
7567 strcpy (str, tmpbuf);
7570 adorn_decl (decl, str);
7579 /* This clause is done iteratively rather than recursively. */
7582 op = (is_complex_decl (TREE_TYPE (decl))
7583 ? TREE_TYPE (decl) : NULL_TREE);
7585 adorn_decl (decl, str);
7587 /* We have a pointer to a function or array...(*)(), (*)[] */
7588 if (code == POINTER_TYPE
7589 && op && (TREE_CODE (op) == FUNCTION_TYPE
7590 || TREE_CODE (op) == ARRAY_TYPE))
7592 strcpy (tmpbuf, "(");
7593 strcat (tmpbuf, str);
7594 strcat (tmpbuf, ")");
7595 strcpy (str, tmpbuf);
7598 decl = (is_complex_decl (TREE_TYPE (decl))
7599 ? TREE_TYPE (decl) : NULL_TREE);
7602 while (decl && (code = TREE_CODE (decl)))
7607 case IDENTIFIER_NODE:
7608 /* Will only happen if we are processing a "raw" expr-decl. */
7609 strcpy (buf, IDENTIFIER_POINTER (decl));
7620 /* We have an abstract declarator or a _DECL node. */
7628 gen_declspecs (declspecs, buf, raw)
7637 for (chain = nreverse (copy_list (declspecs));
7638 chain; chain = TREE_CHAIN (chain))
7640 tree aspec = TREE_VALUE (chain);
7642 if (TREE_CODE (aspec) == IDENTIFIER_NODE)
7643 strcat (buf, IDENTIFIER_POINTER (aspec));
7644 else if (TREE_CODE (aspec) == RECORD_TYPE)
7646 if (TYPE_NAME (aspec))
7648 tree protocol_list = TYPE_PROTOCOL_LIST (aspec);
7650 if (! TREE_STATIC_TEMPLATE (aspec))
7651 strcat (buf, "struct ");
7652 strcat (buf, IDENTIFIER_POINTER (TYPE_NAME (aspec)));
7657 tree chain = protocol_list;
7664 (PROTOCOL_NAME (TREE_VALUE (chain))));
7665 chain = TREE_CHAIN (chain);
7674 strcat (buf, "untagged struct");
7677 else if (TREE_CODE (aspec) == UNION_TYPE)
7679 if (TYPE_NAME (aspec))
7681 if (! TREE_STATIC_TEMPLATE (aspec))
7682 strcat (buf, "union ");
7683 strcat (buf, IDENTIFIER_POINTER (TYPE_NAME (aspec)));
7686 strcat (buf, "untagged union");
7689 else if (TREE_CODE (aspec) == ENUMERAL_TYPE)
7691 if (TYPE_NAME (aspec))
7693 if (! TREE_STATIC_TEMPLATE (aspec))
7694 strcat (buf, "enum ");
7695 strcat (buf, IDENTIFIER_POINTER (TYPE_NAME (aspec)));
7698 strcat (buf, "untagged enum");
7701 else if (TREE_CODE (aspec) == TYPE_DECL && DECL_NAME (aspec))
7702 strcat (buf, IDENTIFIER_POINTER (DECL_NAME (aspec)));
7704 else if (IS_ID (aspec))
7706 tree protocol_list = TYPE_PROTOCOL_LIST (aspec);
7711 tree chain = protocol_list;
7718 (PROTOCOL_NAME (TREE_VALUE (chain))));
7719 chain = TREE_CHAIN (chain);
7726 if (TREE_CHAIN (chain))
7732 /* Type qualifiers. */
7733 if (TREE_READONLY (declspecs))
7734 strcat (buf, "const ");
7735 if (TYPE_VOLATILE (declspecs))
7736 strcat (buf, "volatile ");
7738 switch (TREE_CODE (declspecs))
7740 /* Type specifiers. */
7743 declspecs = TYPE_MAIN_VARIANT (declspecs);
7745 /* Signed integer types. */
7747 if (declspecs == short_integer_type_node)
7748 strcat (buf, "short int ");
7749 else if (declspecs == integer_type_node)
7750 strcat (buf, "int ");
7751 else if (declspecs == long_integer_type_node)
7752 strcat (buf, "long int ");
7753 else if (declspecs == long_long_integer_type_node)
7754 strcat (buf, "long long int ");
7755 else if (declspecs == signed_char_type_node
7756 || declspecs == char_type_node)
7757 strcat (buf, "char ");
7759 /* Unsigned integer types. */
7761 else if (declspecs == short_unsigned_type_node)
7762 strcat (buf, "unsigned short ");
7763 else if (declspecs == unsigned_type_node)
7764 strcat (buf, "unsigned int ");
7765 else if (declspecs == long_unsigned_type_node)
7766 strcat (buf, "unsigned long ");
7767 else if (declspecs == long_long_unsigned_type_node)
7768 strcat (buf, "unsigned long long ");
7769 else if (declspecs == unsigned_char_type_node)
7770 strcat (buf, "unsigned char ");
7774 declspecs = TYPE_MAIN_VARIANT (declspecs);
7776 if (declspecs == float_type_node)
7777 strcat (buf, "float ");
7778 else if (declspecs == double_type_node)
7779 strcat (buf, "double ");
7780 else if (declspecs == long_double_type_node)
7781 strcat (buf, "long double ");
7785 if (TYPE_NAME (declspecs)
7786 && TREE_CODE (TYPE_NAME (declspecs)) == IDENTIFIER_NODE)
7788 tree protocol_list = TYPE_PROTOCOL_LIST (declspecs);
7790 if (! TREE_STATIC_TEMPLATE (declspecs))
7791 strcat (buf, "struct ");
7792 strcat (buf, IDENTIFIER_POINTER (TYPE_NAME (declspecs)));
7796 tree chain = protocol_list;
7803 (PROTOCOL_NAME (TREE_VALUE (chain))));
7804 chain = TREE_CHAIN (chain);
7813 strcat (buf, "untagged struct");
7819 if (TYPE_NAME (declspecs)
7820 && TREE_CODE (TYPE_NAME (declspecs)) == IDENTIFIER_NODE)
7822 strcat (buf, "union ");
7823 strcat (buf, IDENTIFIER_POINTER (TYPE_NAME (declspecs)));
7828 strcat (buf, "untagged union ");
7832 if (TYPE_NAME (declspecs)
7833 && TREE_CODE (TYPE_NAME (declspecs)) == IDENTIFIER_NODE)
7835 strcat (buf, "enum ");
7836 strcat (buf, IDENTIFIER_POINTER (TYPE_NAME (declspecs)));
7841 strcat (buf, "untagged enum ");
7845 strcat (buf, "void ");
7850 tree protocol_list = TYPE_PROTOCOL_LIST (declspecs);
7855 tree chain = protocol_list;
7862 (PROTOCOL_NAME (TREE_VALUE (chain))));
7863 chain = TREE_CHAIN (chain);
7879 /* Given a tree node, produce a printable description of it in the given
7880 buffer, overwriting the buffer. */
7883 gen_declaration (atype_or_adecl, buf)
7884 tree atype_or_adecl;
7888 gen_declaration_1 (atype_or_adecl, buf);
7892 /* Given a tree node, append a printable description to the end of the
7896 gen_declaration_1 (atype_or_adecl, buf)
7897 tree atype_or_adecl;
7902 if (TREE_CODE (atype_or_adecl) == TREE_LIST)
7904 tree declspecs; /* "identifier_node", "record_type" */
7905 tree declarator; /* "array_ref", "indirect_ref", "call_expr"... */
7907 /* We have a "raw", abstract declarator (typename). */
7908 declarator = TREE_VALUE (atype_or_adecl);
7909 declspecs = TREE_PURPOSE (atype_or_adecl);
7911 gen_declspecs (declspecs, buf, 1);
7915 strcat (buf, gen_declarator (declarator, declbuf, ""));
7922 tree declspecs; /* "integer_type", "real_type", "record_type"... */
7923 tree declarator; /* "array_type", "function_type", "pointer_type". */
7925 if (TREE_CODE (atype_or_adecl) == FIELD_DECL
7926 || TREE_CODE (atype_or_adecl) == PARM_DECL
7927 || TREE_CODE (atype_or_adecl) == FUNCTION_DECL)
7928 atype = TREE_TYPE (atype_or_adecl);
7930 /* Assume we have a *_type node. */
7931 atype = atype_or_adecl;
7933 if (is_complex_decl (atype))
7937 /* Get the declaration specifier; it is at the end of the list. */
7938 declarator = chain = atype;
7940 chain = TREE_TYPE (chain); /* not TREE_CHAIN (chain); */
7941 while (is_complex_decl (chain));
7948 declarator = NULL_TREE;
7951 gen_declspecs (declspecs, buf, 0);
7953 if (TREE_CODE (atype_or_adecl) == FIELD_DECL
7954 || TREE_CODE (atype_or_adecl) == PARM_DECL
7955 || TREE_CODE (atype_or_adecl) == FUNCTION_DECL)
7957 const char *const decl_name =
7958 (DECL_NAME (atype_or_adecl)
7959 ? IDENTIFIER_POINTER (DECL_NAME (atype_or_adecl)) : "");
7964 strcat (buf, gen_declarator (declarator, declbuf, decl_name));
7967 else if (decl_name[0])
7970 strcat (buf, decl_name);
7973 else if (declarator)
7976 strcat (buf, gen_declarator (declarator, declbuf, ""));
7981 #define RAW_TYPESPEC(meth) (TREE_VALUE (TREE_PURPOSE (TREE_TYPE (meth))))
7983 /* Given a method tree, put a printable description into the given
7984 buffer (overwriting) and return a pointer to the buffer. */
7987 gen_method_decl (method, buf)
7994 if (RAW_TYPESPEC (method) != objc_object_reference)
7997 gen_declaration_1 (TREE_TYPE (method), buf);
8001 chain = METHOD_SEL_ARGS (method);
8004 /* We have a chain of keyword_decls. */
8007 if (KEYWORD_KEY_NAME (chain))
8008 strcat (buf, IDENTIFIER_POINTER (KEYWORD_KEY_NAME (chain)));
8011 if (RAW_TYPESPEC (chain) != objc_object_reference)
8014 gen_declaration_1 (TREE_TYPE (chain), buf);
8018 strcat (buf, IDENTIFIER_POINTER (KEYWORD_ARG_NAME (chain)));
8019 if ((chain = TREE_CHAIN (chain)))
8024 if (METHOD_ADD_ARGS (method) == objc_ellipsis_node)
8025 strcat (buf, ", ...");
8026 else if (METHOD_ADD_ARGS (method))
8028 /* We have a tree list node as generate by get_parm_info. */
8029 chain = TREE_PURPOSE (METHOD_ADD_ARGS (method));
8031 /* Know we have a chain of parm_decls. */
8035 gen_declaration_1 (chain, buf);
8036 chain = TREE_CHAIN (chain);
8042 /* We have a unary selector. */
8043 strcat (buf, IDENTIFIER_POINTER (METHOD_SEL_NAME (method)));
8051 /* Dump an @interface declaration of the supplied class CHAIN to the
8052 supplied file FP. Used to implement the -gen-decls option (which
8053 prints out an @interface declaration of all classes compiled in
8054 this run); potentially useful for debugging the compiler too. */
8056 dump_interface (fp, chain)
8060 /* FIXME: A heap overflow here whenever a method (or ivar)
8061 declaration is so long that it doesn't fit in the buffer. The
8062 code and all the related functions should be rewritten to avoid
8063 using fixed size buffers. */
8064 char *buf = xmalloc (1024 * 10);
8065 const char *my_name = IDENTIFIER_POINTER (CLASS_NAME (chain));
8066 tree ivar_decls = CLASS_RAW_IVARS (chain);
8067 tree nst_methods = CLASS_NST_METHODS (chain);
8068 tree cls_methods = CLASS_CLS_METHODS (chain);
8070 fprintf (fp, "\n@interface %s", my_name);
8072 /* CLASS_SUPER_NAME is used to store the superclass name for
8073 classes, and the category name for categories. */
8074 if (CLASS_SUPER_NAME (chain))
8076 const char *name = IDENTIFIER_POINTER (CLASS_SUPER_NAME (chain));
8078 if (TREE_CODE (chain) == CATEGORY_IMPLEMENTATION_TYPE
8079 || TREE_CODE (chain) == CATEGORY_INTERFACE_TYPE)
8081 fprintf (fp, " (%s)\n", name);
8085 fprintf (fp, " : %s\n", name);
8091 /* FIXME - the following doesn't seem to work at the moment. */
8094 fprintf (fp, "{\n");
8097 fprintf (fp, "\t%s;\n", gen_declaration (ivar_decls, buf));
8098 ivar_decls = TREE_CHAIN (ivar_decls);
8101 fprintf (fp, "}\n");
8106 fprintf (fp, "- %s;\n", gen_method_decl (nst_methods, buf));
8107 nst_methods = TREE_CHAIN (nst_methods);
8112 fprintf (fp, "+ %s;\n", gen_method_decl (cls_methods, buf));
8113 cls_methods = TREE_CHAIN (cls_methods);
8116 fprintf (fp, "@end\n");
8119 /* Demangle function for Objective-C */
8121 objc_demangle (mangled)
8122 const char *mangled;
8124 char *demangled, *cp;
8126 if (mangled[0] == '_' &&
8127 (mangled[1] == 'i' || mangled[1] == 'c') &&
8130 cp = demangled = xmalloc(strlen(mangled) + 2);
8131 if (mangled[1] == 'i')
8132 *cp++ = '-'; /* for instance method */
8134 *cp++ = '+'; /* for class method */
8135 *cp++ = '['; /* opening left brace */
8136 strcpy(cp, mangled+3); /* tack on the rest of the mangled name */
8137 while (*cp && *cp == '_')
8138 cp++; /* skip any initial underbars in class name */
8139 cp = strchr(cp, '_'); /* find first non-initial underbar */
8142 free(demangled); /* not mangled name */
8145 if (cp[1] == '_') /* easy case: no category name */
8147 *cp++ = ' '; /* replace two '_' with one ' ' */
8148 strcpy(cp, mangled + (cp - demangled) + 2);
8152 *cp++ = '('; /* less easy case: category name */
8153 cp = strchr(cp, '_');
8156 free(demangled); /* not mangled name */
8160 *cp++ = ' '; /* overwriting 1st char of method name... */
8161 strcpy(cp, mangled + (cp - demangled)); /* get it back */
8163 while (*cp && *cp == '_')
8164 cp++; /* skip any initial underbars in method name */
8167 *cp = ':'; /* replace remaining '_' with ':' */
8168 *cp++ = ']'; /* closing right brace */
8169 *cp++ = 0; /* string terminator */
8173 return mangled; /* not an objc mangled name */
8177 objc_printable_name (decl, kind)
8179 int kind ATTRIBUTE_UNUSED;
8181 return objc_demangle (IDENTIFIER_POINTER (DECL_NAME (decl)));
8187 gcc_obstack_init (&util_obstack);
8188 util_firstobj = (char *) obstack_finish (&util_obstack);
8190 errbuf = xmalloc (BUFSIZE);
8192 synth_module_prologue ();
8198 struct imp_entry *impent;
8200 /* The internally generated initializers appear to have missing braces.
8201 Don't warn about this. */
8202 int save_warn_missing_braces = warn_missing_braces;
8203 warn_missing_braces = 0;
8205 /* A missing @end may not be detected by the parser. */
8206 if (objc_implementation_context)
8208 warning ("`@end' missing in implementation context");
8209 finish_class (objc_implementation_context);
8210 objc_ivar_chain = NULL_TREE;
8211 objc_implementation_context = NULL_TREE;
8214 generate_forward_declaration_to_string_table ();
8216 /* Process the static instances here because initialization of objc_symtab
8218 if (objc_static_instances)
8219 generate_static_references ();
8221 if (imp_list || class_names_chain
8222 || meth_var_names_chain || meth_var_types_chain || sel_ref_chain)
8223 generate_objc_symtab_decl ();
8225 for (impent = imp_list; impent; impent = impent->next)
8227 objc_implementation_context = impent->imp_context;
8228 implementation_template = impent->imp_template;
8230 UOBJC_CLASS_decl = impent->class_decl;
8231 UOBJC_METACLASS_decl = impent->meta_decl;
8233 /* Dump the @interface of each class as we compile it, if the
8234 -gen-decls option is in use. TODO: Dump the classes in the
8235 order they were found, rather than in reverse order as we
8237 if (flag_gen_declaration)
8239 dump_interface (gen_declaration_file, objc_implementation_context);
8242 if (TREE_CODE (objc_implementation_context) == CLASS_IMPLEMENTATION_TYPE)
8244 /* all of the following reference the string pool... */
8245 generate_ivar_lists ();
8246 generate_dispatch_tables ();
8247 generate_shared_structures ();
8251 generate_dispatch_tables ();
8252 generate_category (objc_implementation_context);
8256 /* If we are using an array of selectors, we must always
8257 finish up the array decl even if no selectors were used. */
8258 if (! flag_next_runtime || sel_ref_chain)
8259 build_selector_translation_table ();
8262 generate_protocols ();
8264 if (objc_implementation_context || class_names_chain || objc_static_instances
8265 || meth_var_names_chain || meth_var_types_chain || sel_ref_chain)
8267 /* Arrange for ObjC data structures to be initialized at run time. */
8268 rtx init_sym = build_module_descriptor ();
8269 if (init_sym && targetm.have_ctors_dtors)
8270 (* targetm.asm_out.constructor) (init_sym, DEFAULT_INIT_PRIORITY);
8273 /* Dump the class references. This forces the appropriate classes
8274 to be linked into the executable image, preserving unix archive
8275 semantics. This can be removed when we move to a more dynamically
8276 linked environment. */
8278 for (chain = cls_ref_chain; chain; chain = TREE_CHAIN (chain))
8280 handle_class_ref (chain);
8281 if (TREE_PURPOSE (chain))
8282 generate_classref_translation_entry (chain);
8285 for (impent = imp_list; impent; impent = impent->next)
8286 handle_impent (impent);
8288 /* Dump the string table last. */
8290 generate_strings ();
8297 /* Run through the selector hash tables and print a warning for any
8298 selector which has multiple methods. */
8300 for (slot = 0; slot < SIZEHASHTABLE; slot++)
8301 for (hsh = cls_method_hash_list[slot]; hsh; hsh = hsh->next)
8304 tree meth = hsh->key;
8305 char type = (TREE_CODE (meth) == INSTANCE_METHOD_DECL
8309 warning ("potential selector conflict for method `%s'",
8310 IDENTIFIER_POINTER (METHOD_SEL_NAME (meth)));
8311 warn_with_method ("found", type, meth);
8312 for (loop = hsh->list; loop; loop = loop->next)
8313 warn_with_method ("found", type, loop->value);
8316 for (slot = 0; slot < SIZEHASHTABLE; slot++)
8317 for (hsh = nst_method_hash_list[slot]; hsh; hsh = hsh->next)
8320 tree meth = hsh->key;
8321 char type = (TREE_CODE (meth) == INSTANCE_METHOD_DECL
8325 warning ("potential selector conflict for method `%s'",
8326 IDENTIFIER_POINTER (METHOD_SEL_NAME (meth)));
8327 warn_with_method ("found", type, meth);
8328 for (loop = hsh->list; loop; loop = loop->next)
8329 warn_with_method ("found", type, loop->value);
8333 warn_missing_braces = save_warn_missing_braces;
8336 /* Subroutines of finish_objc. */
8339 generate_classref_translation_entry (chain)
8342 tree expr, name, decl_specs, decl, sc_spec;
8345 type = TREE_TYPE (TREE_PURPOSE (chain));
8347 expr = add_objc_string (TREE_VALUE (chain), class_names);
8348 expr = build_c_cast (type, expr); /* cast! */
8350 name = DECL_NAME (TREE_PURPOSE (chain));
8352 sc_spec = build_tree_list (NULL_TREE, ridpointers[(int) RID_STATIC]);
8354 /* static struct objc_class * _OBJC_CLASS_REFERENCES_n = ...; */
8355 decl_specs = tree_cons (NULL_TREE, type, sc_spec);
8357 /* The decl that is returned from start_decl is the one that we
8358 forward declared in build_class_reference. */
8359 decl = start_decl (name, decl_specs, 1, NULL_TREE);
8360 DECL_CONTEXT (decl) = NULL_TREE;
8361 finish_decl (decl, expr, NULL_TREE);
8366 handle_class_ref (chain)
8369 const char *name = IDENTIFIER_POINTER (TREE_VALUE (chain));
8370 char *string = alloca (strlen (name) + 30);
8374 sprintf (string, "%sobjc_class_name_%s",
8375 (flag_next_runtime ? "." : "__"), name);
8377 #ifdef ASM_DECLARE_UNRESOLVED_REFERENCE
8378 if (flag_next_runtime)
8380 ASM_DECLARE_UNRESOLVED_REFERENCE (asm_out_file, string);
8385 /* Make a decl for this name, so we can use its address in a tree. */
8386 decl = build_decl (VAR_DECL, get_identifier (string), char_type_node);
8387 DECL_EXTERNAL (decl) = 1;
8388 TREE_PUBLIC (decl) = 1;
8391 rest_of_decl_compilation (decl, 0, 0, 0);
8393 /* Make a decl for the address. */
8394 sprintf (string, "%sobjc_class_ref_%s",
8395 (flag_next_runtime ? "." : "__"), name);
8396 exp = build1 (ADDR_EXPR, string_type_node, decl);
8397 decl = build_decl (VAR_DECL, get_identifier (string), string_type_node);
8398 DECL_INITIAL (decl) = exp;
8399 TREE_STATIC (decl) = 1;
8400 TREE_USED (decl) = 1;
8403 rest_of_decl_compilation (decl, 0, 0, 0);
8407 handle_impent (impent)
8408 struct imp_entry *impent;
8412 objc_implementation_context = impent->imp_context;
8413 implementation_template = impent->imp_template;
8415 if (TREE_CODE (impent->imp_context) == CLASS_IMPLEMENTATION_TYPE)
8417 const char *const class_name =
8418 IDENTIFIER_POINTER (CLASS_NAME (impent->imp_context));
8420 string = alloca (strlen (class_name) + 30);
8422 sprintf (string, "%sobjc_class_name_%s",
8423 (flag_next_runtime ? "." : "__"), class_name);
8425 else if (TREE_CODE (impent->imp_context) == CATEGORY_IMPLEMENTATION_TYPE)
8427 const char *const class_name =
8428 IDENTIFIER_POINTER (CLASS_NAME (impent->imp_context));
8429 const char *const class_super_name =
8430 IDENTIFIER_POINTER (CLASS_SUPER_NAME (impent->imp_context));
8432 string = alloca (strlen (class_name)
8433 + strlen (class_super_name) + 30);
8435 /* Do the same for categories. Even though no references to
8436 these symbols are generated automatically by the compiler, it
8437 gives you a handle to pull them into an archive by hand. */
8438 sprintf (string, "*%sobjc_category_name_%s_%s",
8439 (flag_next_runtime ? "." : "__"), class_name, class_super_name);
8444 #ifdef ASM_DECLARE_CLASS_REFERENCE
8445 if (flag_next_runtime)
8447 ASM_DECLARE_CLASS_REFERENCE (asm_out_file, string);
8455 init = build_int_2 (0, 0);
8456 TREE_TYPE (init) = c_common_type_for_size (BITS_PER_WORD, 1);
8457 decl = build_decl (VAR_DECL, get_identifier (string), TREE_TYPE (init));
8458 TREE_PUBLIC (decl) = 1;
8459 TREE_READONLY (decl) = 1;
8460 TREE_USED (decl) = 1;
8461 TREE_CONSTANT (decl) = 1;
8462 DECL_CONTEXT (decl) = 0;
8463 DECL_ARTIFICIAL (decl) = 1;
8464 DECL_INITIAL (decl) = init;
8465 assemble_variable (decl, 1, 0, 0);
8469 /* Look up ID as an instance variable. */
8471 lookup_objc_ivar (id)
8476 if (objc_method_context && !strcmp (IDENTIFIER_POINTER (id), "super"))
8477 /* We have a message to super. */
8478 return get_super_receiver ();
8479 else if (objc_method_context && (decl = is_ivar (objc_ivar_chain, id)))
8481 if (is_private (decl))
8482 return error_mark_node;
8484 return build_ivar_reference (id);
8490 #include "gt-objc-objc-act.h"
8491 #include "gtype-objc.h"