1 /* Implement classes and message passing for Objective C.
2 Copyright (C) 1992, 1993, 1994, 1995, 1997, 1998, 1999, 2000,
3 2001, 2002, 2003, 2004 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"
53 #include "langhooks.h"
64 #include "diagnostic.h"
66 #include "tree-iterator.h"
69 /* This is the default way of generating a method name. */
70 /* I am not sure it is really correct.
71 Perhaps there's a danger that it will make name conflicts
72 if method names contain underscores. -- rms. */
73 #ifndef OBJC_GEN_METHOD_LABEL
74 #define OBJC_GEN_METHOD_LABEL(BUF, IS_INST, CLASS_NAME, CAT_NAME, SEL_NAME, NUM) \
77 sprintf ((BUF), "_%s_%s_%s_%s", \
78 ((IS_INST) ? "i" : "c"), \
80 ((CAT_NAME)? (CAT_NAME) : ""), \
82 for (temp = (BUF); *temp; temp++) \
83 if (*temp == ':') *temp = '_'; \
87 /* These need specifying. */
88 #ifndef OBJC_FORWARDING_STACK_OFFSET
89 #define OBJC_FORWARDING_STACK_OFFSET 0
92 #ifndef OBJC_FORWARDING_MIN_OFFSET
93 #define OBJC_FORWARDING_MIN_OFFSET 0
96 /* Set up for use of obstacks. */
100 /* This obstack is used to accumulate the encoding of a data type. */
101 static struct obstack util_obstack;
103 /* This points to the beginning of obstack contents, so we can free
104 the whole contents. */
107 /* The version identifies which language generation and runtime
108 the module (file) was compiled for, and is recorded in the
109 module descriptor. */
111 #define OBJC_VERSION (flag_next_runtime ? 5 : 8)
112 #define PROTOCOL_VERSION 2
114 /* (Decide if these can ever be validly changed.) */
115 #define OBJC_ENCODE_INLINE_DEFS 0
116 #define OBJC_ENCODE_DONT_INLINE_DEFS 1
118 /*** Private Interface (procedures) ***/
120 /* Used by compile_file. */
122 static void init_objc (void);
123 static void finish_objc (void);
125 /* Code generation. */
127 static void synth_module_prologue (void);
128 static tree objc_build_constructor (tree, tree);
129 static rtx build_module_descriptor (void);
130 static tree init_module_descriptor (tree);
131 static tree build_objc_method_call (int, tree, tree, tree, tree);
132 static void generate_strings (void);
133 static tree get_proto_encoding (tree);
134 static void build_selector_translation_table (void);
135 static tree lookup_interface (tree);
136 static tree objc_add_static_instance (tree, tree);
138 static void build_objc_exception_stuff (void);
139 static void build_next_objc_exception_stuff (void);
141 static tree build_ivar_template (void);
142 static tree build_method_template (void);
143 static tree build_private_template (tree);
144 static void build_class_template (void);
145 static void build_selector_template (void);
146 static void build_category_template (void);
147 static tree lookup_method_in_hash_lists (tree, int);
148 static void build_super_template (void);
149 static tree build_category_initializer (tree, tree, tree, tree, tree, tree);
150 static tree build_protocol_initializer (tree, tree, tree, tree, tree);
151 static void synth_forward_declarations (void);
152 static int ivar_list_length (tree);
153 static tree get_class_ivars (tree, int);
154 static void generate_ivar_lists (void);
155 static void generate_dispatch_tables (void);
156 static void generate_shared_structures (void);
157 static tree generate_protocol_list (tree);
158 static void build_protocol_reference (tree);
160 static tree build_keyword_selector (tree);
161 static tree synth_id_with_class_suffix (const char *, tree);
163 static void generate_static_references (void);
164 static int check_methods_accessible (tree, tree, int);
165 static void encode_aggregate_within (tree, int, int, int, int);
166 static const char *objc_demangle (const char *);
167 static void objc_expand_function_end (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 (tree);
175 static void hash_init (void);
176 static void hash_enter (hash *, tree);
177 static hash hash_lookup (hash *, tree);
178 static void hash_add_attr (hash, tree);
179 static tree lookup_method (tree, tree);
180 static tree lookup_method_static (tree, tree, int);
181 static void add_method_to_hash_list (hash *, tree);
182 static tree add_class (tree);
183 static void add_category (tree, tree);
184 static inline tree lookup_category (tree, tree);
188 class_names, /* class, category, protocol, module names */
189 meth_var_names, /* method and variable names */
190 meth_var_types /* method and variable type descriptors */
193 static tree add_objc_string (tree, enum string_section);
194 static tree get_objc_string_decl (tree, enum string_section);
195 static tree build_objc_string_decl (enum string_section);
196 static tree build_selector_reference_decl (void);
198 /* Protocol additions. */
200 static tree add_protocol (tree);
201 static tree lookup_protocol (tree);
202 static void check_protocol_recursively (tree, tree);
203 static tree lookup_and_install_protocols (tree);
207 static void encode_type_qualifiers (tree);
208 static void encode_pointer (tree, int, int);
209 static void encode_array (tree, int, int);
210 static void encode_aggregate (tree, int, int);
211 static void encode_next_bitfield (int);
212 static void encode_gnu_bitfield (int, tree, int);
213 static void encode_type (tree, int, int);
214 static void encode_field_decl (tree, int, int);
216 static void really_start_method (tree, tree);
217 static int comp_method_with_proto (tree, tree);
218 static int objc_types_are_equivalent (tree, tree);
219 static int comp_proto_with_proto (tree, tree);
220 static tree get_arg_type_list (tree, int, int);
221 static tree objc_expr_last (tree);
222 static void synth_self_and_ucmd_args (void);
224 /* Utilities for debugging and error diagnostics. */
226 static void warn_with_method (const char *, int, tree);
227 static void error_with_ivar (const char *, tree, tree);
228 static char *gen_method_decl (tree, char *);
229 static char *gen_declaration (tree, char *);
230 static void gen_declaration_1 (tree, char *);
231 static char *gen_declarator (tree, char *, const char *);
232 static int is_complex_decl (tree);
233 static void adorn_decl (tree, char *);
234 static void dump_interface (FILE *, tree);
236 /* Everything else. */
238 static tree define_decl (tree, tree);
239 static tree lookup_method_in_protocol_list (tree, tree, int);
240 static tree lookup_protocol_in_reflist (tree, tree);
241 static tree create_builtin_decl (enum tree_code, tree, const char *);
242 static void setup_string_decl (void);
243 static int check_string_class_template (void);
244 static tree my_build_string (int, const char *);
245 static void build_objc_symtab_template (void);
246 static tree init_def_list (tree);
247 static tree init_objc_symtab (tree);
248 static tree build_metadata_decl (const char *, tree);
249 static void forward_declare_categories (void);
250 static void generate_objc_symtab_decl (void);
251 static tree build_selector (tree);
252 static tree build_typed_selector_reference (tree, tree);
253 static tree build_selector_reference (tree);
254 static tree build_class_reference_decl (void);
255 static void add_class_reference (tree);
256 static tree build_protocol_template (void);
257 static tree build_descriptor_table_initializer (tree, tree);
258 static tree build_method_prototype_list_template (tree, int);
259 static tree build_method_prototype_template (void);
260 static tree objc_method_parm_type (tree);
261 static int objc_encoded_type_size (tree);
262 static tree encode_method_prototype (tree);
263 static tree generate_descriptor_table (tree, const char *, int, tree, tree);
264 static void generate_method_descriptors (tree);
265 static void generate_protocol_references (tree);
266 static void generate_protocols (void);
267 static void check_ivars (tree, tree);
268 static tree build_ivar_list_template (tree, int);
269 static tree build_method_list_template (tree, int);
270 static tree build_ivar_list_initializer (tree, tree);
271 static tree generate_ivars_list (tree, const char *, int, tree);
272 static tree build_dispatch_table_initializer (tree, tree);
273 static tree generate_dispatch_table (tree, const char *, int, tree);
274 static tree build_shared_structure_initializer (tree, tree, tree, tree,
275 tree, int, tree, tree, tree);
276 static void generate_category (tree);
277 static int is_objc_type_qualifier (tree);
278 static tree adjust_type_for_id_default (tree);
279 static tree check_duplicates (hash, int, int);
280 static tree receiver_is_class_object (tree, int, int);
281 static int check_methods (tree, tree, int);
282 static int conforms_to_protocol (tree, tree);
283 static void check_protocol (tree, const char *, const char *);
284 static void check_protocols (tree, const char *, const char *);
285 static void gen_declspecs (tree, char *, int);
286 static void generate_classref_translation_entry (tree);
287 static void handle_class_ref (tree);
288 static void generate_struct_by_value_array (void)
290 static void mark_referenced_methods (void);
291 static void generate_objc_image_info (void);
293 /*** Private Interface (data) ***/
295 /* Reserved tag definitions. */
298 #define TAG_OBJECT "objc_object"
299 #define TAG_CLASS "objc_class"
300 #define TAG_SUPER "objc_super"
301 #define TAG_SELECTOR "objc_selector"
303 #define UTAG_CLASS "_objc_class"
304 #define UTAG_IVAR "_objc_ivar"
305 #define UTAG_IVAR_LIST "_objc_ivar_list"
306 #define UTAG_METHOD "_objc_method"
307 #define UTAG_METHOD_LIST "_objc_method_list"
308 #define UTAG_CATEGORY "_objc_category"
309 #define UTAG_MODULE "_objc_module"
310 #define UTAG_SYMTAB "_objc_symtab"
311 #define UTAG_SUPER "_objc_super"
312 #define UTAG_SELECTOR "_objc_selector"
314 #define UTAG_PROTOCOL "_objc_protocol"
315 #define UTAG_METHOD_PROTOTYPE "_objc_method_prototype"
316 #define UTAG_METHOD_PROTOTYPE_LIST "_objc__method_prototype_list"
318 /* Note that the string object global name is only needed for the
320 #define STRING_OBJECT_GLOBAL_FORMAT "_%sClassReference"
322 #define PROTOCOL_OBJECT_CLASS_NAME "Protocol"
324 static const char *TAG_GETCLASS;
325 static const char *TAG_GETMETACLASS;
326 static const char *TAG_MSGSEND;
327 static const char *TAG_MSGSENDSUPER;
328 /* The NeXT Objective-C messenger may have two extra entry points, for use
329 when returning a structure. */
330 static const char *TAG_MSGSEND_STRET;
331 static const char *TAG_MSGSENDSUPER_STRET;
332 static const char *TAG_EXECCLASS;
333 static const char *default_constant_string_class_name;
335 /* Runtime metadata flags. */
336 #define CLS_FACTORY 0x0001L
337 #define CLS_META 0x0002L
339 #define OBJC_MODIFIER_STATIC 0x00000001
340 #define OBJC_MODIFIER_FINAL 0x00000002
341 #define OBJC_MODIFIER_PUBLIC 0x00000004
342 #define OBJC_MODIFIER_PRIVATE 0x00000008
343 #define OBJC_MODIFIER_PROTECTED 0x00000010
344 #define OBJC_MODIFIER_NATIVE 0x00000020
345 #define OBJC_MODIFIER_SYNCHRONIZED 0x00000040
346 #define OBJC_MODIFIER_ABSTRACT 0x00000080
347 #define OBJC_MODIFIER_VOLATILE 0x00000100
348 #define OBJC_MODIFIER_TRANSIENT 0x00000200
349 #define OBJC_MODIFIER_NONE_SPECIFIED 0x80000000
351 #define TAG_MSGSEND_NONNIL "objc_msgSendNonNil"
352 #define TAG_MSGSEND_NONNIL_STRET "objc_msgSendNonNil_stret"
353 #define TAG_EXCEPTIONEXTRACT "objc_exception_extract"
354 #define TAG_EXCEPTIONTRYENTER "objc_exception_try_enter"
355 #define TAG_EXCEPTIONTRYEXIT "objc_exception_try_exit"
356 #define TAG_EXCEPTIONMATCH "objc_exception_match"
357 #define TAG_EXCEPTIONTHROW "objc_exception_throw"
358 #define TAG_SYNCENTER "objc_sync_enter"
359 #define TAG_SYNCEXIT "objc_sync_exit"
360 #define TAG_SETJMP "_setjmp"
361 #define TAG_RETURN_STRUCT "objc_return_struct"
363 #define UTAG_EXCDATA "_objc_exception_data"
365 /* The OCTI_... enumeration itself is in objc/objc-act.h. */
366 tree objc_global_trees[OCTI_MAX];
368 static void handle_impent (struct imp_entry *);
370 struct imp_entry *imp_list = 0;
371 int imp_count = 0; /* `@implementation' */
372 int cat_count = 0; /* `@category' */
374 /* Use to generate method labels. */
375 static int method_slot = 0;
379 static char *errbuf; /* Buffer for error diagnostics */
381 /* Data imported from tree.c. */
383 extern enum debug_info_type write_symbols;
385 /* Data imported from toplev.c. */
387 extern const char *dump_base_name;
389 static int flag_typed_selectors;
391 FILE *gen_declaration_file;
393 /* Tells "encode_pointer/encode_aggregate" whether we are generating
394 type descriptors for instance variables (as opposed to methods).
395 Type descriptors for instance variables contain more information
396 than methods (for static typing and embedded structures). */
398 static int generating_instance_variables = 0;
400 /* Some platforms pass small structures through registers versus
401 through an invisible pointer. Determine at what size structure is
402 the transition point between the two possibilities. */
405 generate_struct_by_value_array (void)
408 tree field_decl, field_decl_chain;
410 int aggregate_in_mem[32];
413 /* Presumably no platform passes 32 byte structures in a register. */
414 for (i = 1; i < 32; i++)
418 /* Create an unnamed struct that has `i' character components */
419 type = start_struct (RECORD_TYPE, NULL_TREE);
421 strcpy (buffer, "c1");
422 field_decl = create_builtin_decl (FIELD_DECL,
425 field_decl_chain = field_decl;
427 for (j = 1; j < i; j++)
429 sprintf (buffer, "c%d", j + 1);
430 field_decl = create_builtin_decl (FIELD_DECL,
433 chainon (field_decl_chain, field_decl);
435 finish_struct (type, field_decl_chain, NULL_TREE);
437 aggregate_in_mem[i] = aggregate_value_p (type, 0);
438 if (!aggregate_in_mem[i])
442 /* We found some structures that are returned in registers instead of memory
443 so output the necessary data. */
446 for (i = 31; i >= 0; i--)
447 if (!aggregate_in_mem[i])
449 printf ("#define OBJC_MAX_STRUCT_BY_VALUE %d\n\n", i);
451 /* The first member of the structure is always 0 because we don't handle
452 structures with 0 members */
453 printf ("static int struct_forward_array[] = {\n 0");
455 for (j = 1; j <= i; j++)
456 printf (", %d", aggregate_in_mem[j]);
466 if (c_objc_common_init () == false)
469 /* Force the line number back to 0; check_newline will have
470 raised it to 1, which will make the builtin functions appear
471 not to be built in. */
474 /* If gen_declaration desired, open the output file. */
475 if (flag_gen_declaration)
477 register char * const dumpname = concat (dump_base_name, ".decl", NULL);
478 gen_declaration_file = fopen (dumpname, "w");
479 if (gen_declaration_file == 0)
480 fatal_error ("can't open %s: %m", dumpname);
484 if (flag_next_runtime)
486 TAG_GETCLASS = "objc_getClass";
487 TAG_GETMETACLASS = "objc_getMetaClass";
488 TAG_MSGSEND = "objc_msgSend";
489 TAG_MSGSENDSUPER = "objc_msgSendSuper";
490 TAG_MSGSEND_STRET = "objc_msgSend_stret";
491 TAG_MSGSENDSUPER_STRET = "objc_msgSendSuper_stret";
492 TAG_EXECCLASS = "__objc_execClass";
493 default_constant_string_class_name = "NSConstantString";
497 TAG_GETCLASS = "objc_get_class";
498 TAG_GETMETACLASS = "objc_get_meta_class";
499 TAG_MSGSEND = "objc_msg_lookup";
500 TAG_MSGSENDSUPER = "objc_msg_lookup_super";
501 /* GNU runtime does not provide special functions to support
502 structure-returning methods. */
503 TAG_EXECCLASS = "__objc_exec_class";
504 default_constant_string_class_name = "NXConstantString";
505 flag_typed_selectors = 1;
508 objc_ellipsis_node = make_node (ERROR_MARK);
512 if (print_struct_values)
513 generate_struct_by_value_array ();
519 objc_finish_file (void)
521 mark_referenced_methods ();
523 /* Finalize Objective-C runtime data. No need to generate tables
524 and code if only checking syntax. */
525 if (!flag_syntax_only)
528 if (gen_declaration_file)
529 fclose (gen_declaration_file);
533 define_decl (tree declarator, tree declspecs)
535 tree decl = start_decl (declarator, declspecs, 0, NULL_TREE);
536 finish_decl (decl, NULL_TREE, NULL_TREE);
540 /* Return the first occurrence of a method declaration corresponding
541 to sel_name in rproto_list. Search rproto_list recursively.
542 If is_class is 0, search for instance methods, otherwise for class
545 lookup_method_in_protocol_list (tree rproto_list, tree sel_name,
551 for (rproto = rproto_list; rproto; rproto = TREE_CHAIN (rproto))
553 p = TREE_VALUE (rproto);
555 if (TREE_CODE (p) == PROTOCOL_INTERFACE_TYPE)
557 if ((fnd = lookup_method (is_class
558 ? PROTOCOL_CLS_METHODS (p)
559 : PROTOCOL_NST_METHODS (p), sel_name)))
561 else if (PROTOCOL_LIST (p))
562 fnd = lookup_method_in_protocol_list (PROTOCOL_LIST (p),
567 ; /* An identifier...if we could not find a protocol. */
578 lookup_protocol_in_reflist (tree rproto_list, tree lproto)
582 /* Make sure the protocol is supported by the object on the rhs. */
583 if (TREE_CODE (lproto) == PROTOCOL_INTERFACE_TYPE)
586 for (rproto = rproto_list; rproto; rproto = TREE_CHAIN (rproto))
588 p = TREE_VALUE (rproto);
590 if (TREE_CODE (p) == PROTOCOL_INTERFACE_TYPE)
595 else if (PROTOCOL_LIST (p))
596 fnd = lookup_protocol_in_reflist (PROTOCOL_LIST (p), lproto);
605 ; /* An identifier...if we could not find a protocol. */
611 /* Return 1 if IDENT is an ObjC/ObjC++ reserved keyword in the context of
615 objc_is_reserved_word (tree ident)
617 unsigned char code = C_RID_CODE (ident);
619 return (OBJC_IS_AT_KEYWORD (code)
621 || code == RID_CLASS || code == RID_PUBLIC
622 || code == RID_PROTECTED || code == RID_PRIVATE
623 || code == RID_TRY || code == RID_THROW || code == RID_CATCH
628 /* Return true if TYPE is 'id'. */
631 objc_is_object_id (tree type)
633 return OBJC_TYPE_NAME (type) == objc_object_id;
637 objc_is_class_id (tree type)
639 return OBJC_TYPE_NAME (type) == objc_class_id;
642 /* Return 1 if LHS and RHS are compatible types for assignment or
643 various other operations. Return 0 if they are incompatible, and
644 return -1 if we choose to not decide (because the types are really
645 just C types, not ObjC specific ones). When the operation is
646 REFLEXIVE (typically comparisons), check for compatibility in
647 either direction; when it's not (typically assignments), don't.
649 This function is called in two cases: when both lhs and rhs are
650 pointers to records (in which case we check protocols too), and
651 when both lhs and rhs are records (in which case we check class
654 Warnings about classes/protocols not implementing a protocol are
655 emitted here (multiple of those warnings might be emitted for a
656 single line!); generic warnings about incompatible assignments and
657 lacks of casts in comparisons are/must be emitted by the caller if
662 objc_comptypes (tree lhs, tree rhs, int reflexive)
664 /* New clause for protocols. */
666 /* Here we manage the case of a POINTER_TYPE = POINTER_TYPE. We only
667 manage the ObjC ones, and leave the rest to the C code. */
668 if (TREE_CODE (lhs) == POINTER_TYPE
669 && TREE_CODE (TREE_TYPE (lhs)) == RECORD_TYPE
670 && TREE_CODE (rhs) == POINTER_TYPE
671 && TREE_CODE (TREE_TYPE (rhs)) == RECORD_TYPE)
673 int lhs_is_proto = IS_PROTOCOL_QUALIFIED_ID (lhs);
674 int rhs_is_proto = IS_PROTOCOL_QUALIFIED_ID (rhs);
678 tree lproto, lproto_list = TYPE_PROTOCOL_LIST (lhs);
679 tree rproto, rproto_list;
682 /* <Protocol> = <Protocol> */
685 rproto_list = TYPE_PROTOCOL_LIST (rhs);
689 /* An assignment between objects of type 'id
690 <Protocol>'; make sure the protocol on the lhs is
691 supported by the object on the rhs. */
692 for (lproto = lproto_list; lproto;
693 lproto = TREE_CHAIN (lproto))
695 p = TREE_VALUE (lproto);
696 rproto = lookup_protocol_in_reflist (rproto_list, p);
700 ("object does not conform to the `%s' protocol",
701 IDENTIFIER_POINTER (PROTOCOL_NAME (p)));
707 /* Obscure case - a comparison between two objects
708 of type 'id <Protocol>'. Check that either the
709 protocol on the lhs is supported by the object on
710 the rhs, or viceversa. */
712 /* Check if the protocol on the lhs is supported by the
713 object on the rhs. */
714 for (lproto = lproto_list; lproto;
715 lproto = TREE_CHAIN (lproto))
717 p = TREE_VALUE (lproto);
718 rproto = lookup_protocol_in_reflist (rproto_list, p);
722 /* Check failed - check if the protocol on the rhs
723 is supported by the object on the lhs. */
724 for (rproto = rproto_list; rproto;
725 rproto = TREE_CHAIN (rproto))
727 p = TREE_VALUE (rproto);
728 lproto = lookup_protocol_in_reflist (lproto_list,
733 /* This check failed too: incompatible */
743 /* <Protocol> = <class> * */
744 else if (TYPED_OBJECT (TREE_TYPE (rhs)))
746 tree rname = OBJC_TYPE_NAME (TREE_TYPE (rhs));
749 /* Make sure the protocol is supported by the object on
751 for (lproto = lproto_list; lproto; lproto = TREE_CHAIN (lproto))
753 p = TREE_VALUE (lproto);
755 rinter = lookup_interface (rname);
757 while (rinter && !rproto)
761 rproto_list = CLASS_PROTOCOL_LIST (rinter);
762 rproto = lookup_protocol_in_reflist (rproto_list, p);
763 /* If the underlying ObjC class does not have
764 the protocol we're looking for, check for "one-off"
765 protocols (e.g., `NSObject<MyProt> *foo;') attached
769 rproto_list = TYPE_PROTOCOL_LIST (TREE_TYPE (rhs));
770 rproto = lookup_protocol_in_reflist (rproto_list, p);
773 /* Check for protocols adopted by categories. */
774 cat = CLASS_CATEGORY_LIST (rinter);
775 while (cat && !rproto)
777 rproto_list = CLASS_PROTOCOL_LIST (cat);
778 rproto = lookup_protocol_in_reflist (rproto_list, p);
779 cat = CLASS_CATEGORY_LIST (cat);
782 rinter = lookup_interface (CLASS_SUPER_NAME (rinter));
786 warning ("class `%s' does not implement the `%s' protocol",
787 IDENTIFIER_POINTER (OBJC_TYPE_NAME (TREE_TYPE (rhs))),
788 IDENTIFIER_POINTER (PROTOCOL_NAME (p)));
792 /* <Protocol> = id */
793 else if (objc_is_object_id (TREE_TYPE (rhs)))
797 /* <Protocol> = Class */
798 else if (objc_is_class_id (TREE_TYPE (rhs)))
802 /* <Protocol> = ?? : let comptypes decide. */
805 else if (rhs_is_proto)
807 /* <class> * = <Protocol> */
808 if (TYPED_OBJECT (TREE_TYPE (lhs)))
812 tree rname = OBJC_TYPE_NAME (TREE_TYPE (lhs));
814 tree rproto, rproto_list = TYPE_PROTOCOL_LIST (rhs);
816 /* Make sure the protocol is supported by the object on
818 for (rproto = rproto_list; rproto;
819 rproto = TREE_CHAIN (rproto))
821 tree p = TREE_VALUE (rproto);
823 rinter = lookup_interface (rname);
825 while (rinter && !lproto)
829 tree lproto_list = CLASS_PROTOCOL_LIST (rinter);
830 lproto = lookup_protocol_in_reflist (lproto_list, p);
831 /* If the underlying ObjC class does not
832 have the protocol we're looking for,
833 check for "one-off" protocols (e.g.,
834 `NSObject<MyProt> *foo;') attached to the
838 lproto_list = TYPE_PROTOCOL_LIST
840 lproto = lookup_protocol_in_reflist
844 /* Check for protocols adopted by categories. */
845 cat = CLASS_CATEGORY_LIST (rinter);
846 while (cat && !lproto)
848 lproto_list = CLASS_PROTOCOL_LIST (cat);
849 lproto = lookup_protocol_in_reflist (lproto_list,
851 cat = CLASS_CATEGORY_LIST (cat);
854 rinter = lookup_interface (CLASS_SUPER_NAME
859 warning ("class `%s' does not implement the `%s' protocol",
860 IDENTIFIER_POINTER (OBJC_TYPE_NAME
862 IDENTIFIER_POINTER (PROTOCOL_NAME (p)));
869 /* id = <Protocol> */
870 else if (objc_is_object_id (TREE_TYPE (lhs)))
874 /* Class = <Protocol> */
875 else if (objc_is_class_id (TREE_TYPE (lhs)))
879 /* ??? = <Protocol> : let comptypes decide */
887 /* Attention: we shouldn't defer to comptypes here. One bad
888 side effect would be that we might loose the REFLEXIVE
891 lhs = TREE_TYPE (lhs);
892 rhs = TREE_TYPE (rhs);
896 if (TREE_CODE (lhs) != RECORD_TYPE || TREE_CODE (rhs) != RECORD_TYPE)
898 /* Nothing to do with ObjC - let immediately comptypes take
899 responsibility for checking. */
903 /* `id' = `<class> *' `<class> *' = `id': always allow it.
905 'Object *o = [[Object alloc] init]; falls
906 in the case <class> * = `id'.
908 if ((objc_is_object_id (lhs) && TYPED_OBJECT (rhs))
909 || (objc_is_object_id (rhs) && TYPED_OBJECT (lhs)))
912 /* `id' = `Class', `Class' = `id' */
914 else if ((objc_is_object_id (lhs) && objc_is_class_id (rhs))
915 || (objc_is_class_id (lhs) && objc_is_object_id (rhs)))
918 /* `Class' != `<class> *' && `<class> *' != `Class'! */
919 else if ((OBJC_TYPE_NAME (lhs) == objc_class_id && TYPED_OBJECT (rhs))
920 || (OBJC_TYPE_NAME (rhs) == objc_class_id && TYPED_OBJECT (lhs)))
923 /* `<class> *' = `<class> *' */
925 else if (TYPED_OBJECT (lhs) && TYPED_OBJECT (rhs))
927 tree lname = OBJC_TYPE_NAME (lhs);
928 tree rname = OBJC_TYPE_NAME (rhs);
934 /* If the left hand side is a super class of the right hand side,
936 for (inter = lookup_interface (rname); inter;
937 inter = lookup_interface (CLASS_SUPER_NAME (inter)))
938 if (lname == CLASS_SUPER_NAME (inter))
941 /* Allow the reverse when reflexive. */
943 for (inter = lookup_interface (lname); inter;
944 inter = lookup_interface (CLASS_SUPER_NAME (inter)))
945 if (rname == CLASS_SUPER_NAME (inter))
951 /* Not an ObjC type - let comptypes do the check. */
955 /* Called from finish_decl. */
958 objc_check_decl (tree decl)
960 tree type = TREE_TYPE (decl);
962 if (TREE_CODE (type) != RECORD_TYPE)
964 if (TYPE_NAME (type) && (type = objc_is_class_name (TYPE_NAME (type))))
965 error ("statically allocated instance of Objective-C class `%s'",
966 IDENTIFIER_POINTER (type));
969 /* Implement static typing. At this point, we know we have an interface. */
972 get_static_reference (tree interface, tree protocols)
974 tree type = xref_tag (RECORD_TYPE, interface);
978 type = build_variant_type_copy (type);
980 /* Look up protocols and install in lang specific list. Note
981 that the protocol list can have a different lifetime than T! */
982 SET_TYPE_PROTOCOL_LIST (type, lookup_and_install_protocols (protocols));
988 /* Return a declaration corresponding to a protocol list qualified 'id'. */
990 get_protocol_reference (tree protocols)
992 tree type_decl = lookup_name (objc_id_id);
995 if (type_decl && TREE_CODE (type_decl) == TYPE_DECL)
997 type = TREE_TYPE (type_decl);
998 if (TYPE_MAIN_VARIANT (type) != objc_id_type)
999 warning ("unexpected type for `id' (%s)",
1000 gen_declaration (type, errbuf));
1004 error ("undefined type `id', please import <objc/objc.h>");
1005 return error_mark_node;
1008 /* This clause creates a new pointer type that is qualified with
1009 the protocol specification...this info is used later to do more
1010 elaborate type checking. */
1014 type = build_variant_type_copy (type);
1016 /* Look up protocols...and install in lang specific list */
1017 SET_TYPE_PROTOCOL_LIST (type, lookup_and_install_protocols (protocols));
1022 /* Check for circular dependencies in protocols. The arguments are
1023 PROTO, the protocol to check, and LIST, a list of protocol it
1027 check_protocol_recursively (tree proto, tree list)
1031 for (p = list; p; p = TREE_CHAIN (p))
1033 tree pp = TREE_VALUE (p);
1035 if (TREE_CODE (pp) == IDENTIFIER_NODE)
1036 pp = lookup_protocol (pp);
1039 fatal_error ("protocol `%s' has circular dependency",
1040 IDENTIFIER_POINTER (PROTOCOL_NAME (pp)));
1042 check_protocol_recursively (proto, PROTOCOL_LIST (pp));
1046 /* Look up PROTOCOLS, and return a list of those that are found.
1047 If none are found, return NULL. */
1050 lookup_and_install_protocols (tree protocols)
1053 tree return_value = NULL_TREE;
1055 for (proto = protocols; proto; proto = TREE_CHAIN (proto))
1057 tree ident = TREE_VALUE (proto);
1058 tree p = lookup_protocol (ident);
1061 error ("cannot find protocol declaration for `%s'",
1062 IDENTIFIER_POINTER (ident));
1064 return_value = chainon (return_value,
1065 build_tree_list (NULL_TREE, p));
1068 return return_value;
1071 /* Create and push a decl for a built-in external variable or field NAME.
1073 TYPE is its data type. */
1076 create_builtin_decl (enum tree_code code, tree type, const char *name)
1078 tree decl = build_decl (code, get_identifier (name), type);
1080 if (code == VAR_DECL)
1082 TREE_STATIC (decl) = 1;
1083 make_decl_rtl (decl);
1085 DECL_ARTIFICIAL (decl) = 1;
1091 /* Find the decl for the constant string class. */
1094 setup_string_decl (void)
1096 if (!string_class_decl)
1098 if (!constant_string_global_id)
1102 /* %s in format will provide room for terminating null */
1103 length = strlen (STRING_OBJECT_GLOBAL_FORMAT)
1104 + strlen (constant_string_class_name);
1105 name = xmalloc (length);
1106 sprintf (name, STRING_OBJECT_GLOBAL_FORMAT,
1107 constant_string_class_name);
1108 constant_string_global_id = get_identifier (name);
1110 string_class_decl = lookup_name (constant_string_global_id);
1114 /* Purpose: "play" parser, creating/installing representations
1115 of the declarations that are required by Objective-C.
1119 type_spec--------->sc_spec
1120 (tree_list) (tree_list)
1123 identifier_node identifier_node */
1126 synth_module_prologue (void)
1130 /* Defined in `objc.h' */
1131 objc_object_id = get_identifier (TAG_OBJECT);
1133 objc_object_reference = xref_tag (RECORD_TYPE, objc_object_id);
1135 objc_id_type = build_pointer_type (objc_object_reference);
1137 objc_id_id = get_identifier (TYPE_ID);
1138 objc_class_id = get_identifier (TAG_CLASS);
1140 objc_class_type = build_pointer_type (xref_tag (RECORD_TYPE, objc_class_id));
1141 temp_type = get_identifier (PROTOCOL_OBJECT_CLASS_NAME);
1142 objc_declare_class (tree_cons (NULL_TREE, temp_type, NULL_TREE));
1143 objc_protocol_type = build_pointer_type (xref_tag (RECORD_TYPE, temp_type));
1145 /* Declare type of selector-objects that represent an operation name. */
1147 if (flag_next_runtime)
1148 /* `struct objc_selector *' */
1150 = build_pointer_type (xref_tag (RECORD_TYPE,
1151 get_identifier (TAG_SELECTOR)));
1153 /* `const struct objc_selector *' */
1155 = build_pointer_type
1156 (build_qualified_type (xref_tag (RECORD_TYPE,
1157 get_identifier (TAG_SELECTOR)),
1160 /* Declare receiver type used for dispatching messages to 'super'. */
1162 /* `struct objc_super *' */
1163 objc_super_type = build_pointer_type (xref_tag (RECORD_TYPE,
1164 get_identifier (TAG_SUPER)));
1166 if (flag_next_runtime)
1168 /* NB: In order to call one of the ..._stret (struct-returning)
1169 functions, the function *MUST* first be cast to a signature that
1170 corresponds to the actual ObjC method being invoked. This is
1171 what is done by the build_objc_method_call() routine below. */
1173 /* id objc_msgSend (id, SEL, ...); */
1174 /* id objc_msgSendNonNil (id, SEL, ...); */
1175 /* id objc_msgSend_stret (id, SEL, ...); */
1176 /* id objc_msgSendNonNil_stret (id, SEL, ...); */
1178 = build_function_type (objc_id_type,
1179 tree_cons (NULL_TREE, objc_id_type,
1180 tree_cons (NULL_TREE,
1183 umsg_decl = builtin_function (TAG_MSGSEND,
1184 temp_type, 0, NOT_BUILT_IN,
1186 umsg_nonnil_decl = builtin_function (TAG_MSGSEND_NONNIL,
1187 temp_type, 0, NOT_BUILT_IN,
1189 umsg_stret_decl = builtin_function (TAG_MSGSEND_STRET,
1190 temp_type, 0, NOT_BUILT_IN,
1192 umsg_nonnil_stret_decl = builtin_function (TAG_MSGSEND_NONNIL_STRET,
1193 temp_type, 0, NOT_BUILT_IN,
1196 /* id objc_msgSendSuper (struct objc_super *, SEL, ...); */
1197 /* id objc_msgSendSuper_stret (struct objc_super *, SEL, ...); */
1199 = build_function_type (objc_id_type,
1200 tree_cons (NULL_TREE, objc_super_type,
1201 tree_cons (NULL_TREE,
1204 umsg_super_decl = builtin_function (TAG_MSGSENDSUPER,
1205 temp_type, 0, NOT_BUILT_IN,
1207 umsg_super_stret_decl = builtin_function (TAG_MSGSENDSUPER_STRET,
1208 temp_type, 0, NOT_BUILT_IN, 0,
1213 /* GNU runtime messenger entry points. */
1215 /* typedef id (*IMP)(id, SEL, ...); */
1217 = build_pointer_type
1218 (build_function_type (objc_id_type,
1219 tree_cons (NULL_TREE, objc_id_type,
1220 tree_cons (NULL_TREE,
1224 /* IMP objc_msg_lookup (id, SEL); */
1226 = build_function_type (IMP_type,
1227 tree_cons (NULL_TREE, objc_id_type,
1228 tree_cons (NULL_TREE,
1231 umsg_decl = builtin_function (TAG_MSGSEND,
1232 temp_type, 0, NOT_BUILT_IN,
1235 /* IMP objc_msg_lookup_super (struct objc_super *, SEL); */
1237 = build_function_type (IMP_type,
1238 tree_cons (NULL_TREE, objc_super_type,
1239 tree_cons (NULL_TREE,
1242 umsg_super_decl = builtin_function (TAG_MSGSENDSUPER,
1243 temp_type, 0, NOT_BUILT_IN,
1247 /* id objc_getClass (const char *); */
1249 temp_type = build_function_type (objc_id_type,
1250 tree_cons (NULL_TREE,
1251 const_string_type_node,
1255 = builtin_function (TAG_GETCLASS, temp_type, 0, NOT_BUILT_IN,
1258 /* id objc_getMetaClass (const char *); */
1260 objc_get_meta_class_decl
1261 = builtin_function (TAG_GETMETACLASS, temp_type, 0, NOT_BUILT_IN, NULL, NULL_TREE);
1263 build_super_template ();
1264 build_objc_exception_stuff ();
1265 if (flag_next_runtime)
1266 build_next_objc_exception_stuff ();
1268 /* static SEL _OBJC_SELECTOR_TABLE[]; */
1270 if (! flag_next_runtime)
1272 if (flag_typed_selectors)
1274 /* Suppress outputting debug symbols, because
1275 dbxout_init hasn'r been called yet. */
1276 enum debug_info_type save_write_symbols = write_symbols;
1277 const struct gcc_debug_hooks *const save_hooks = debug_hooks;
1278 write_symbols = NO_DEBUG;
1279 debug_hooks = &do_nothing_debug_hooks;
1281 build_selector_template ();
1282 temp_type = build_array_type (objc_selector_template, NULL_TREE);
1284 write_symbols = save_write_symbols;
1285 debug_hooks = save_hooks;
1288 temp_type = build_array_type (objc_selector_type, NULL_TREE);
1290 layout_type (temp_type);
1291 UOBJC_SELECTOR_TABLE_decl
1292 = create_builtin_decl (VAR_DECL, temp_type,
1293 "_OBJC_SELECTOR_TABLE");
1295 /* Avoid warning when not sending messages. */
1296 TREE_USED (UOBJC_SELECTOR_TABLE_decl) = 1;
1299 /* Forward declare constant_string_id and constant_string_type. */
1300 if (!constant_string_class_name)
1301 constant_string_class_name = default_constant_string_class_name;
1303 constant_string_id = get_identifier (constant_string_class_name);
1304 objc_declare_class (tree_cons (NULL_TREE, constant_string_id, NULL_TREE));
1306 /* Pre-build the following entities - for speed/convenience. */
1307 self_id = get_identifier ("self");
1308 ucmd_id = get_identifier ("_cmd");
1310 /* The C++ front-end does not appear to grok __attribute__((__unused__)). */
1311 unused_list = build_tree_list (get_identifier ("__unused__"), NULL_TREE);
1315 /* Ensure that the ivar list for NSConstantString/NXConstantString
1316 (or whatever was specified via `-fconstant-string-class')
1317 contains fields at least as large as the following three, so that
1318 the runtime can stomp on them with confidence:
1320 struct STRING_OBJECT_CLASS_NAME
1324 unsigned int length;
1328 check_string_class_template (void)
1330 tree field_decl = TYPE_FIELDS (constant_string_type);
1332 #define AT_LEAST_AS_LARGE_AS(F, T) \
1333 (F && TREE_CODE (F) == FIELD_DECL \
1334 && (TREE_INT_CST_LOW (DECL_SIZE (F)) \
1335 >= TREE_INT_CST_LOW (TYPE_SIZE (T))))
1337 if (!AT_LEAST_AS_LARGE_AS (field_decl, ptr_type_node))
1340 field_decl = TREE_CHAIN (field_decl);
1341 if (!AT_LEAST_AS_LARGE_AS (field_decl, ptr_type_node))
1344 field_decl = TREE_CHAIN (field_decl);
1345 return AT_LEAST_AS_LARGE_AS (field_decl, unsigned_type_node);
1347 #undef AT_LEAST_AS_LARGE_AS
1350 /* Avoid calling `check_string_class_template ()' more than once. */
1351 static GTY(()) int string_layout_checked;
1353 /* Custom build_string which sets TREE_TYPE! */
1356 my_build_string (int len, const char *str)
1358 return fix_string_type (build_string (len, str));
1361 /* Given a chain of STRING_CST's, build a static instance of
1362 NXConstantString which points at the concatenation of those
1363 strings. We place the string object in the __string_objects
1364 section of the __OBJC segment. The Objective-C runtime will
1365 initialize the isa pointers of the string objects to point at the
1366 NXConstantString class object. */
1369 build_objc_string_object (tree string)
1371 tree initlist, constructor, constant_string_class;
1375 string = fix_string_type (string);
1377 constant_string_class = lookup_interface (constant_string_id);
1378 if (!constant_string_class
1379 || !(constant_string_type
1380 = CLASS_STATIC_TEMPLATE (constant_string_class)))
1382 error ("cannot find interface declaration for `%s'",
1383 IDENTIFIER_POINTER (constant_string_id));
1384 return error_mark_node;
1387 /* Call to 'combine_strings' has been moved above. */
1388 TREE_SET_CODE (string, STRING_CST);
1389 length = TREE_STRING_LENGTH (string) - 1;
1391 if (!string_layout_checked)
1393 /* The NSConstantString/NXConstantString ivar layout is now
1395 if (!check_string_class_template ())
1397 error ("interface `%s' does not have valid constant string layout",
1398 IDENTIFIER_POINTER (constant_string_id));
1399 return error_mark_node;
1401 add_class_reference (constant_string_id);
1403 fields = TYPE_FIELDS (constant_string_type);
1405 /* & ((NXConstantString) { NULL, string, length }) */
1407 if (flag_next_runtime)
1409 /* For the NeXT runtime, we can generate a literal reference
1410 to the string class, don't need to run a constructor. */
1411 setup_string_decl ();
1412 if (string_class_decl == NULL_TREE)
1414 error ("cannot find reference tag for class `%s'",
1415 IDENTIFIER_POINTER (constant_string_id));
1416 return error_mark_node;
1418 initlist = build_tree_list
1420 copy_node (build_unary_op (ADDR_EXPR, string_class_decl, 0)));
1424 initlist = build_tree_list (fields, build_int_cst (NULL_TREE, 0));
1427 fields = TREE_CHAIN (fields);
1430 = tree_cons (fields, copy_node (build_unary_op (ADDR_EXPR, string, 1)),
1433 fields = TREE_CHAIN (fields);
1435 initlist = tree_cons (fields, build_int_cst (NULL_TREE, length), initlist);
1436 constructor = objc_build_constructor (constant_string_type,
1437 nreverse (initlist));
1439 if (!flag_next_runtime)
1442 = objc_add_static_instance (constructor, constant_string_type);
1445 constructor = build_unary_op (ADDR_EXPR, constructor, 1);
1446 TREE_CONSTANT (constructor) = true;
1450 /* Declare a static instance of CLASS_DECL initialized by CONSTRUCTOR. */
1452 static GTY(()) int num_static_inst;
1455 objc_add_static_instance (tree constructor, tree class_decl)
1460 /* Find the list of static instances for the CLASS_DECL. Create one if
1462 for (chain = &objc_static_instances;
1463 *chain && TREE_VALUE (*chain) != class_decl;
1464 chain = &TREE_CHAIN (*chain));
1467 *chain = tree_cons (NULL_TREE, class_decl, NULL_TREE);
1468 add_objc_string (OBJC_TYPE_NAME (class_decl), class_names);
1471 sprintf (buf, "_OBJC_INSTANCE_%d", num_static_inst++);
1472 decl = build_decl (VAR_DECL, get_identifier (buf), class_decl);
1473 DECL_COMMON (decl) = 1;
1474 TREE_STATIC (decl) = 1;
1475 DECL_ARTIFICIAL (decl) = 1;
1476 DECL_INITIAL (decl) = constructor;
1478 /* We may be writing something else just now.
1479 Postpone till end of input. */
1480 DECL_DEFER_OUTPUT (decl) = 1;
1481 pushdecl_top_level (decl);
1482 rest_of_decl_compilation (decl, 1, 0);
1484 /* Add the DECL to the head of this CLASS' list. */
1485 TREE_PURPOSE (*chain) = tree_cons (NULL_TREE, decl, TREE_PURPOSE (*chain));
1490 /* Build a static constant CONSTRUCTOR
1491 with type TYPE and elements ELTS. */
1494 objc_build_constructor (tree type, tree elts)
1496 tree constructor, f, e;
1498 /* ??? Most of the places that we build constructors, we don't fill in
1499 the type of integers properly. Convert them all en masse. */
1500 if (TREE_CODE (type) == ARRAY_TYPE)
1502 f = TREE_TYPE (type);
1503 if (TREE_CODE (f) == POINTER_TYPE || TREE_CODE (f) == INTEGER_TYPE)
1504 for (e = elts; e ; e = TREE_CHAIN (e))
1505 TREE_VALUE (e) = convert (f, TREE_VALUE (e));
1509 f = TYPE_FIELDS (type);
1510 for (e = elts; e && f; e = TREE_CHAIN (e), f = TREE_CHAIN (f))
1511 if (TREE_CODE (TREE_TYPE (f)) == POINTER_TYPE
1512 || TREE_CODE (TREE_TYPE (f)) == INTEGER_TYPE)
1513 TREE_VALUE (e) = convert (TREE_TYPE (f), TREE_VALUE (e));
1516 constructor = build_constructor (type, elts);
1517 TREE_CONSTANT (constructor) = 1;
1518 TREE_STATIC (constructor) = 1;
1519 TREE_READONLY (constructor) = 1;
1522 /* zlaski 2001-Apr-02: mark this as a call to a constructor, as required by
1523 build_unary_op (wasn't true in 2.7.2.1 days) */
1524 TREE_HAS_CONSTRUCTOR (constructor) = 1;
1529 /* Take care of defining and initializing _OBJC_SYMBOLS. */
1531 /* Predefine the following data type:
1539 void *defs[cls_def_cnt + cat_def_cnt];
1543 build_objc_symtab_template (void)
1545 tree field_decl, field_decl_chain;
1547 objc_symtab_template
1548 = start_struct (RECORD_TYPE, get_identifier (UTAG_SYMTAB));
1550 /* long sel_ref_cnt; */
1552 field_decl = create_builtin_decl (FIELD_DECL,
1553 long_integer_type_node,
1555 field_decl_chain = field_decl;
1559 field_decl = create_builtin_decl (FIELD_DECL,
1560 build_pointer_type (objc_selector_type),
1562 chainon (field_decl_chain, field_decl);
1564 /* short cls_def_cnt; */
1566 field_decl = create_builtin_decl (FIELD_DECL,
1567 short_integer_type_node,
1569 chainon (field_decl_chain, field_decl);
1571 /* short cat_def_cnt; */
1573 field_decl = create_builtin_decl (FIELD_DECL,
1574 short_integer_type_node,
1576 chainon (field_decl_chain, field_decl);
1578 if (imp_count || cat_count || !flag_next_runtime)
1580 /* void *defs[imp_count + cat_count (+ 1)]; */
1581 /* NB: The index is one less than the size of the array. */
1582 int index = imp_count + cat_count
1583 + (flag_next_runtime? -1: 0);
1584 field_decl = create_builtin_decl
1588 build_index_type (build_int_cst (NULL_TREE, index))),
1590 chainon (field_decl_chain, field_decl);
1593 finish_struct (objc_symtab_template, field_decl_chain, NULL_TREE);
1596 /* Create the initial value for the `defs' field of _objc_symtab.
1597 This is a CONSTRUCTOR. */
1600 init_def_list (tree type)
1602 tree expr, initlist = NULL_TREE;
1603 struct imp_entry *impent;
1606 for (impent = imp_list; impent; impent = impent->next)
1608 if (TREE_CODE (impent->imp_context) == CLASS_IMPLEMENTATION_TYPE)
1610 expr = build_unary_op (ADDR_EXPR, impent->class_decl, 0);
1611 initlist = tree_cons (NULL_TREE, expr, initlist);
1616 for (impent = imp_list; impent; impent = impent->next)
1618 if (TREE_CODE (impent->imp_context) == CATEGORY_IMPLEMENTATION_TYPE)
1620 expr = build_unary_op (ADDR_EXPR, impent->class_decl, 0);
1621 initlist = tree_cons (NULL_TREE, expr, initlist);
1625 if (!flag_next_runtime)
1627 /* statics = { ..., _OBJC_STATIC_INSTANCES, ... } */
1630 if (static_instances_decl)
1631 expr = build_unary_op (ADDR_EXPR, static_instances_decl, 0);
1633 expr = build_int_cst (NULL_TREE, 0);
1635 initlist = tree_cons (NULL_TREE, expr, initlist);
1638 return objc_build_constructor (type, nreverse (initlist));
1641 /* Construct the initial value for all of _objc_symtab. */
1644 init_objc_symtab (tree type)
1648 /* sel_ref_cnt = { ..., 5, ... } */
1650 initlist = build_tree_list (NULL_TREE, build_int_cst (NULL_TREE, 0));
1652 /* refs = { ..., _OBJC_SELECTOR_TABLE, ... } */
1654 if (flag_next_runtime || ! sel_ref_chain)
1655 initlist = tree_cons (NULL_TREE, build_int_cst (NULL_TREE, 0), initlist);
1657 initlist = tree_cons (NULL_TREE,
1658 build_unary_op (ADDR_EXPR,
1659 UOBJC_SELECTOR_TABLE_decl, 1),
1662 /* cls_def_cnt = { ..., 5, ... } */
1664 initlist = tree_cons (NULL_TREE, build_int_cst (NULL_TREE, imp_count), initlist);
1666 /* cat_def_cnt = { ..., 5, ... } */
1668 initlist = tree_cons (NULL_TREE, build_int_cst (NULL_TREE, cat_count), initlist);
1670 /* cls_def = { ..., { &Foo, &Bar, ...}, ... } */
1672 if (imp_count || cat_count || !flag_next_runtime)
1675 tree field = TYPE_FIELDS (type);
1676 field = TREE_CHAIN (TREE_CHAIN (TREE_CHAIN (TREE_CHAIN (field))));
1678 initlist = tree_cons (NULL_TREE, init_def_list (TREE_TYPE (field)),
1682 return objc_build_constructor (type, nreverse (initlist));
1685 /* Generate forward declarations for metadata such as
1686 'OBJC_CLASS_...'. */
1689 build_metadata_decl (const char *name, tree type)
1691 tree decl, decl_specs;
1692 /* extern struct TYPE NAME_<name>; */
1693 decl_specs = build_tree_list (NULL_TREE, ridpointers[(int) RID_EXTERN]);
1694 decl_specs = tree_cons (NULL_TREE, type, decl_specs);
1695 decl = define_decl (synth_id_with_class_suffix
1697 objc_implementation_context),
1699 TREE_USED (decl) = 1;
1700 DECL_ARTIFICIAL (decl) = 1;
1701 TREE_PUBLIC (decl) = 0;
1705 /* Push forward-declarations of all the categories so that
1706 init_def_list can use them in a CONSTRUCTOR. */
1709 forward_declare_categories (void)
1711 struct imp_entry *impent;
1712 tree sav = objc_implementation_context;
1714 for (impent = imp_list; impent; impent = impent->next)
1716 if (TREE_CODE (impent->imp_context) == CATEGORY_IMPLEMENTATION_TYPE)
1718 /* Set an invisible arg to synth_id_with_class_suffix. */
1719 objc_implementation_context = impent->imp_context;
1720 /* extern struct objc_category _OBJC_CATEGORY_<name>; */
1721 impent->class_decl = build_metadata_decl ("_OBJC_CATEGORY",
1722 objc_category_template);
1725 objc_implementation_context = sav;
1728 /* Create the declaration of _OBJC_SYMBOLS, with type `struct _objc_symtab'
1729 and initialized appropriately. */
1732 generate_objc_symtab_decl (void)
1736 if (!objc_category_template)
1737 build_category_template ();
1739 /* forward declare categories */
1741 forward_declare_categories ();
1743 if (!objc_symtab_template)
1744 build_objc_symtab_template ();
1746 sc_spec = build_tree_list (NULL_TREE, ridpointers[(int) RID_STATIC]);
1748 UOBJC_SYMBOLS_decl = start_decl (get_identifier ("_OBJC_SYMBOLS"),
1749 tree_cons (NULL_TREE,
1750 objc_symtab_template, sc_spec),
1754 TREE_USED (UOBJC_SYMBOLS_decl) = 1;
1755 DECL_IGNORED_P (UOBJC_SYMBOLS_decl) = 1;
1756 DECL_ARTIFICIAL (UOBJC_SYMBOLS_decl) = 1;
1757 finish_decl (UOBJC_SYMBOLS_decl,
1758 init_objc_symtab (TREE_TYPE (UOBJC_SYMBOLS_decl)),
1763 init_module_descriptor (tree type)
1765 tree initlist, expr;
1767 /* version = { 1, ... } */
1769 expr = build_int_cst (NULL_TREE, OBJC_VERSION);
1770 initlist = build_tree_list (NULL_TREE, expr);
1772 /* size = { ..., sizeof (struct objc_module), ... } */
1774 expr = size_in_bytes (objc_module_template);
1775 initlist = tree_cons (NULL_TREE, expr, initlist);
1777 /* name = { ..., "foo.m", ... } */
1779 expr = add_objc_string (get_identifier (input_filename), class_names);
1780 initlist = tree_cons (NULL_TREE, expr, initlist);
1782 /* symtab = { ..., _OBJC_SYMBOLS, ... } */
1784 if (UOBJC_SYMBOLS_decl)
1785 expr = build_unary_op (ADDR_EXPR, UOBJC_SYMBOLS_decl, 0);
1787 expr = build_int_cst (NULL_TREE, 0);
1788 initlist = tree_cons (NULL_TREE, expr, initlist);
1790 return objc_build_constructor (type, nreverse (initlist));
1793 /* Write out the data structures to describe Objective C classes defined.
1794 If appropriate, compile and output a setup function to initialize them.
1795 Return a symbol_ref to the function to call to initialize the Objective C
1796 data structures for this file (and perhaps for other files also).
1798 struct objc_module { ... } _OBJC_MODULE = { ... }; */
1801 build_module_descriptor (void)
1803 tree decl_specs, field_decl, field_decl_chain;
1805 objc_module_template
1806 = start_struct (RECORD_TYPE, get_identifier (UTAG_MODULE));
1810 decl_specs = build_tree_list (NULL_TREE, ridpointers[(int) RID_LONG]);
1811 field_decl = get_identifier ("version");
1812 field_decl = grokfield (field_decl, decl_specs, NULL_TREE);
1813 field_decl_chain = field_decl;
1817 decl_specs = build_tree_list (NULL_TREE, ridpointers[(int) RID_LONG]);
1818 field_decl = get_identifier ("size");
1819 field_decl = grokfield (field_decl, decl_specs, NULL_TREE);
1820 chainon (field_decl_chain, field_decl);
1824 decl_specs = build_tree_list (NULL_TREE, ridpointers[(int) RID_CHAR]);
1825 field_decl = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("name"));
1826 field_decl = grokfield (field_decl, decl_specs, NULL_TREE);
1827 chainon (field_decl_chain, field_decl);
1829 /* struct objc_symtab *symtab; */
1831 decl_specs = get_identifier (UTAG_SYMTAB);
1832 decl_specs = build_tree_list (NULL_TREE, xref_tag (RECORD_TYPE, decl_specs));
1833 field_decl = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("symtab"));
1834 field_decl = grokfield (field_decl, decl_specs, NULL_TREE);
1835 chainon (field_decl_chain, field_decl);
1837 finish_struct (objc_module_template, field_decl_chain, NULL_TREE);
1839 /* Create an instance of "objc_module". */
1841 decl_specs = tree_cons (NULL_TREE, objc_module_template,
1842 build_tree_list (NULL_TREE,
1843 ridpointers[(int) RID_STATIC]));
1845 UOBJC_MODULES_decl = start_decl (get_identifier ("_OBJC_MODULES"),
1846 decl_specs, 1, NULL_TREE);
1848 DECL_ARTIFICIAL (UOBJC_MODULES_decl) = 1;
1849 DECL_IGNORED_P (UOBJC_MODULES_decl) = 1;
1850 DECL_CONTEXT (UOBJC_MODULES_decl) = NULL_TREE;
1852 finish_decl (UOBJC_MODULES_decl,
1853 init_module_descriptor (TREE_TYPE (UOBJC_MODULES_decl)),
1856 /* Mark the decl to avoid "defined but not used" warning. */
1857 DECL_IN_SYSTEM_HEADER (UOBJC_MODULES_decl) = 1;
1859 mark_decl_referenced (UOBJC_MODULES_decl);
1861 /* Generate a constructor call for the module descriptor.
1862 This code was generated by reading the grammar rules
1863 of c-parse.in; Therefore, it may not be the most efficient
1864 way of generating the requisite code. */
1866 if (flag_next_runtime)
1870 tree parms, execclass_decl, decelerator, void_list_node_1;
1871 tree init_function_name, init_function_decl, compound;
1873 /* Declare void __objc_execClass (void *); */
1875 void_list_node_1 = build_tree_list (NULL_TREE, void_type_node);
1876 execclass_decl = build_decl (FUNCTION_DECL,
1877 get_identifier (TAG_EXECCLASS),
1878 build_function_type (void_type_node,
1879 tree_cons (NULL_TREE, ptr_type_node,
1882 DECL_EXTERNAL (execclass_decl) = 1;
1883 DECL_ARTIFICIAL (execclass_decl) = 1;
1884 TREE_PUBLIC (execclass_decl) = 1;
1885 pushdecl (execclass_decl);
1886 rest_of_decl_compilation (execclass_decl, 0, 0);
1887 assemble_external (execclass_decl);
1889 /* void _GLOBAL_$I$<gnyf> () {objc_execClass (&L_OBJC_MODULES);} */
1891 init_function_name = get_file_function_name ('I');
1892 start_function (void_list_node_1,
1893 build_nt (CALL_EXPR, init_function_name,
1894 tree_cons (NULL_TREE, NULL_TREE,
1898 store_parm_decls ();
1899 compound = c_begin_compound_stmt (true);
1901 init_function_decl = current_function_decl;
1902 TREE_PUBLIC (init_function_decl) = ! targetm.have_ctors_dtors;
1903 TREE_USED (init_function_decl) = 1;
1904 /* Don't let this one be deferred. */
1905 DECL_INLINE (init_function_decl) = 0;
1906 DECL_UNINLINABLE (init_function_decl) = 1;
1909 = build_tree_list (NULL_TREE,
1910 build_unary_op (ADDR_EXPR, UOBJC_MODULES_decl, 0));
1911 decelerator = build_function_call (execclass_decl, parms);
1913 add_stmt (decelerator);
1914 add_stmt (c_end_compound_stmt (compound, true));
1918 return XEXP (DECL_RTL (init_function_decl), 0);
1922 /* Return the DECL of the string IDENT in the SECTION. */
1925 get_objc_string_decl (tree ident, enum string_section section)
1929 if (section == class_names)
1930 chain = class_names_chain;
1931 else if (section == meth_var_names)
1932 chain = meth_var_names_chain;
1933 else if (section == meth_var_types)
1934 chain = meth_var_types_chain;
1938 for (; chain != 0; chain = TREE_CHAIN (chain))
1939 if (TREE_VALUE (chain) == ident)
1940 return (TREE_PURPOSE (chain));
1946 /* Output references to all statically allocated objects. Return the DECL
1947 for the array built. */
1950 generate_static_references (void)
1952 tree decls = NULL_TREE, ident, decl_spec, expr_decl, expr = NULL_TREE;
1953 tree class_name, class, decl, initlist;
1954 tree cl_chain, in_chain;
1955 int num_inst, num_class;
1958 if (flag_next_runtime)
1961 for (cl_chain = objc_static_instances, num_class = 0;
1962 cl_chain; cl_chain = TREE_CHAIN (cl_chain), num_class++)
1964 for (num_inst = 0, in_chain = TREE_PURPOSE (cl_chain);
1965 in_chain; num_inst++, in_chain = TREE_CHAIN (in_chain));
1967 sprintf (buf, "_OBJC_STATIC_INSTANCES_%d", num_class);
1968 ident = get_identifier (buf);
1970 expr_decl = build_nt (ARRAY_REF, ident, NULL_TREE, NULL_TREE, NULL_TREE);
1971 decl_spec = tree_cons (NULL_TREE, build_pointer_type (void_type_node),
1972 build_tree_list (NULL_TREE,
1973 ridpointers[(int) RID_STATIC]));
1974 decl = start_decl (expr_decl, decl_spec, 1, NULL_TREE);
1975 DECL_CONTEXT (decl) = 0;
1976 DECL_ARTIFICIAL (decl) = 1;
1977 TREE_USED (decl) = 1;
1979 /* Output {class_name, ...}. */
1980 class = TREE_VALUE (cl_chain);
1981 class_name = get_objc_string_decl (OBJC_TYPE_NAME (class), class_names);
1982 initlist = build_tree_list (NULL_TREE,
1983 build_unary_op (ADDR_EXPR, class_name, 1));
1985 /* Output {..., instance, ...}. */
1986 for (in_chain = TREE_PURPOSE (cl_chain);
1987 in_chain; in_chain = TREE_CHAIN (in_chain))
1989 expr = build_unary_op (ADDR_EXPR, TREE_VALUE (in_chain), 1);
1990 initlist = tree_cons (NULL_TREE, expr, initlist);
1993 /* Output {..., NULL}. */
1994 initlist = tree_cons (NULL_TREE, build_int_cst (NULL_TREE, 0), initlist);
1996 expr = objc_build_constructor (TREE_TYPE (decl), nreverse (initlist));
1997 finish_decl (decl, expr, NULL_TREE);
1999 = tree_cons (NULL_TREE, build_unary_op (ADDR_EXPR, decl, 1), decls);
2002 decls = tree_cons (NULL_TREE, build_int_cst (NULL_TREE, 0), decls);
2003 ident = get_identifier ("_OBJC_STATIC_INSTANCES");
2004 expr_decl = build_nt (ARRAY_REF, ident, NULL_TREE, NULL_TREE, NULL_TREE);
2005 decl_spec = tree_cons (NULL_TREE, build_pointer_type (void_type_node),
2006 build_tree_list (NULL_TREE,
2007 ridpointers[(int) RID_STATIC]));
2008 static_instances_decl
2009 = start_decl (expr_decl, decl_spec, 1, NULL_TREE);
2010 TREE_USED (static_instances_decl) = 1;
2011 DECL_CONTEXT (static_instances_decl) = 0;
2012 DECL_ARTIFICIAL (static_instances_decl) = 1;
2013 expr = objc_build_constructor (TREE_TYPE (static_instances_decl),
2015 finish_decl (static_instances_decl, expr, NULL_TREE);
2016 rest_of_decl_compilation (static_instances_decl, 0, 0);
2019 /* Output all strings. */
2022 generate_strings (void)
2024 tree sc_spec, decl_specs, expr_decl;
2025 tree chain, string_expr;
2028 for (chain = class_names_chain; chain; chain = TREE_CHAIN (chain))
2030 string = TREE_VALUE (chain);
2031 decl = TREE_PURPOSE (chain);
2033 = tree_cons (NULL_TREE, ridpointers[(int) RID_STATIC], NULL_TREE);
2034 decl_specs = tree_cons (NULL_TREE, ridpointers[(int) RID_CHAR], sc_spec);
2035 expr_decl = build_nt (ARRAY_REF, DECL_NAME (decl), NULL_TREE,
2036 NULL_TREE, NULL_TREE);
2037 decl = start_decl (expr_decl, decl_specs, 1, NULL_TREE);
2038 DECL_CONTEXT (decl) = NULL_TREE;
2039 string_expr = my_build_string (IDENTIFIER_LENGTH (string) + 1,
2040 IDENTIFIER_POINTER (string));
2041 finish_decl (decl, string_expr, NULL_TREE);
2044 for (chain = meth_var_names_chain; chain; chain = TREE_CHAIN (chain))
2046 string = TREE_VALUE (chain);
2047 decl = TREE_PURPOSE (chain);
2049 = tree_cons (NULL_TREE, ridpointers[(int) RID_STATIC], NULL_TREE);
2050 decl_specs = tree_cons (NULL_TREE, ridpointers[(int) RID_CHAR], sc_spec);
2051 expr_decl = build_nt (ARRAY_REF, DECL_NAME (decl), NULL_TREE,
2052 NULL_TREE, NULL_TREE);
2053 decl = start_decl (expr_decl, decl_specs, 1, NULL_TREE);
2054 DECL_CONTEXT (decl) = NULL_TREE;
2055 string_expr = my_build_string (IDENTIFIER_LENGTH (string) + 1,
2056 IDENTIFIER_POINTER (string));
2057 finish_decl (decl, string_expr, NULL_TREE);
2060 for (chain = meth_var_types_chain; chain; chain = TREE_CHAIN (chain))
2062 string = TREE_VALUE (chain);
2063 decl = TREE_PURPOSE (chain);
2065 = tree_cons (NULL_TREE, ridpointers[(int) RID_STATIC], NULL_TREE);
2066 decl_specs = tree_cons (NULL_TREE, ridpointers[(int) RID_CHAR], sc_spec);
2067 expr_decl = build_nt (ARRAY_REF, DECL_NAME (decl), NULL_TREE,
2068 NULL_TREE, NULL_TREE);
2069 decl = start_decl (expr_decl, decl_specs, 1, NULL_TREE);
2070 DECL_CONTEXT (decl) = NULL_TREE;
2071 string_expr = my_build_string (IDENTIFIER_LENGTH (string) + 1,
2072 IDENTIFIER_POINTER (string));
2073 finish_decl (decl, string_expr, NULL_TREE);
2077 static GTY(()) int selector_reference_idx;
2080 build_selector_reference_decl (void)
2085 sprintf (buf, "_OBJC_SELECTOR_REFERENCES_%d", selector_reference_idx++);
2087 ident = get_identifier (buf);
2089 decl = build_decl (VAR_DECL, ident, objc_selector_type);
2090 DECL_EXTERNAL (decl) = 1;
2091 TREE_PUBLIC (decl) = 0;
2092 TREE_USED (decl) = 1;
2093 DECL_ARTIFICIAL (decl) = 1;
2094 DECL_CONTEXT (decl) = 0;
2096 make_decl_rtl (decl);
2097 pushdecl_top_level (decl);
2102 /* Just a handy wrapper for add_objc_string. */
2105 build_selector (tree ident)
2107 tree expr = add_objc_string (ident, meth_var_names);
2108 if (flag_typed_selectors)
2111 return build_c_cast (objc_selector_type, expr); /* cast! */
2115 build_selector_translation_table (void)
2117 tree sc_spec, decl_specs;
2118 tree chain, initlist = NULL_TREE;
2120 tree decl = NULL_TREE, var_decl, name;
2122 for (chain = sel_ref_chain; chain; chain = TREE_CHAIN (chain))
2126 if (warn_selector && objc_implementation_context)
2130 for (method_chain = meth_var_names_chain;
2132 method_chain = TREE_CHAIN (method_chain))
2134 if (TREE_VALUE (method_chain) == TREE_VALUE (chain))
2142 /* Adjust line number for warning message. */
2143 int save_lineno = input_line;
2144 if (flag_next_runtime && TREE_PURPOSE (chain))
2145 input_line = DECL_SOURCE_LINE (TREE_PURPOSE (chain));
2146 warning ("creating selector for non existant method %s",
2147 IDENTIFIER_POINTER (TREE_VALUE (chain)));
2148 input_line = save_lineno;
2152 expr = build_selector (TREE_VALUE (chain));
2154 if (flag_next_runtime)
2156 name = DECL_NAME (TREE_PURPOSE (chain));
2158 sc_spec = build_tree_list (NULL_TREE, ridpointers[(int) RID_STATIC]);
2160 /* static SEL _OBJC_SELECTOR_REFERENCES_n = ...; */
2161 decl_specs = tree_cons (NULL_TREE, objc_selector_type, sc_spec);
2165 /* The `decl' that is returned from start_decl is the one that we
2166 forward declared in `build_selector_reference' */
2167 decl = start_decl (var_decl, decl_specs, 1, NULL_TREE );
2170 /* add one for the '\0' character */
2171 offset += IDENTIFIER_LENGTH (TREE_VALUE (chain)) + 1;
2173 if (flag_next_runtime)
2174 finish_decl (decl, expr, NULL_TREE);
2177 if (flag_typed_selectors)
2179 tree eltlist = NULL_TREE;
2180 tree encoding = get_proto_encoding (TREE_PURPOSE (chain));
2181 eltlist = tree_cons (NULL_TREE, expr, NULL_TREE);
2182 eltlist = tree_cons (NULL_TREE, encoding, eltlist);
2183 expr = objc_build_constructor (objc_selector_template,
2184 nreverse (eltlist));
2186 initlist = tree_cons (NULL_TREE, expr, initlist);
2191 if (! flag_next_runtime)
2193 /* Cause the variable and its initial value to be actually output. */
2194 DECL_EXTERNAL (UOBJC_SELECTOR_TABLE_decl) = 0;
2195 TREE_STATIC (UOBJC_SELECTOR_TABLE_decl) = 1;
2196 /* NULL terminate the list and fix the decl for output. */
2197 initlist = tree_cons (NULL_TREE, build_int_cst (NULL_TREE, 0), initlist);
2198 DECL_INITIAL (UOBJC_SELECTOR_TABLE_decl) = objc_ellipsis_node;
2199 initlist = objc_build_constructor (TREE_TYPE (UOBJC_SELECTOR_TABLE_decl),
2200 nreverse (initlist));
2201 finish_decl (UOBJC_SELECTOR_TABLE_decl, initlist, NULL_TREE);
2202 current_function_decl = NULL_TREE;
2207 get_proto_encoding (tree proto)
2212 if (! METHOD_ENCODING (proto))
2214 encoding = encode_method_prototype (proto);
2215 METHOD_ENCODING (proto) = encoding;
2218 encoding = METHOD_ENCODING (proto);
2220 return add_objc_string (encoding, meth_var_types);
2223 return build_int_cst (NULL_TREE, 0);
2226 /* sel_ref_chain is a list whose "value" fields will be instances of
2227 identifier_node that represent the selector. */
2230 build_typed_selector_reference (tree ident, tree prototype)
2232 tree *chain = &sel_ref_chain;
2238 if (TREE_PURPOSE (*chain) == prototype && TREE_VALUE (*chain) == ident)
2239 goto return_at_index;
2242 chain = &TREE_CHAIN (*chain);
2245 *chain = tree_cons (prototype, ident, NULL_TREE);
2248 expr = build_unary_op (ADDR_EXPR,
2249 build_array_ref (UOBJC_SELECTOR_TABLE_decl,
2250 build_int_cst (NULL_TREE, index)),
2252 return build_c_cast (objc_selector_type, expr);
2256 build_selector_reference (tree ident)
2258 tree *chain = &sel_ref_chain;
2264 if (TREE_VALUE (*chain) == ident)
2265 return (flag_next_runtime
2266 ? TREE_PURPOSE (*chain)
2267 : build_array_ref (UOBJC_SELECTOR_TABLE_decl,
2268 build_int_cst (NULL_TREE, index)));
2271 chain = &TREE_CHAIN (*chain);
2274 expr = build_selector_reference_decl ();
2276 *chain = tree_cons (expr, ident, NULL_TREE);
2278 return (flag_next_runtime
2280 : build_array_ref (UOBJC_SELECTOR_TABLE_decl,
2281 build_int_cst (NULL_TREE, index)));
2284 static GTY(()) int class_reference_idx;
2287 build_class_reference_decl (void)
2292 sprintf (buf, "_OBJC_CLASS_REFERENCES_%d", class_reference_idx++);
2294 ident = get_identifier (buf);
2296 decl = build_decl (VAR_DECL, ident, objc_class_type);
2297 DECL_EXTERNAL (decl) = 1;
2298 TREE_PUBLIC (decl) = 0;
2299 TREE_USED (decl) = 1;
2300 DECL_CONTEXT (decl) = 0;
2301 DECL_ARTIFICIAL (decl) = 1;
2303 make_decl_rtl (decl);
2304 pushdecl_top_level (decl);
2309 /* Create a class reference, but don't create a variable to reference
2313 add_class_reference (tree ident)
2317 if ((chain = cls_ref_chain))
2322 if (ident == TREE_VALUE (chain))
2326 chain = TREE_CHAIN (chain);
2330 /* Append to the end of the list */
2331 TREE_CHAIN (tail) = tree_cons (NULL_TREE, ident, NULL_TREE);
2334 cls_ref_chain = tree_cons (NULL_TREE, ident, NULL_TREE);
2337 /* Get a class reference, creating it if necessary. Also create the
2338 reference variable. */
2341 get_class_reference (tree ident)
2346 if (processing_template_decl)
2347 /* Must wait until template instantiation time. */
2348 return build_min_nt (CLASS_REFERENCE_EXPR, ident);
2349 if (TREE_CODE (ident) == TYPE_DECL)
2350 ident = DECL_NAME (ident);
2354 if (!(ident = objc_is_class_name (ident)))
2356 error ("`%s' is not an Objective-C class name or alias",
2357 IDENTIFIER_POINTER (orig_ident));
2358 return error_mark_node;
2361 if (flag_next_runtime && !flag_zero_link)
2366 for (chain = &cls_ref_chain; *chain; chain = &TREE_CHAIN (*chain))
2367 if (TREE_VALUE (*chain) == ident)
2369 if (! TREE_PURPOSE (*chain))
2370 TREE_PURPOSE (*chain) = build_class_reference_decl ();
2372 return TREE_PURPOSE (*chain);
2375 decl = build_class_reference_decl ();
2376 *chain = tree_cons (decl, ident, NULL_TREE);
2383 add_class_reference (ident);
2385 params = build_tree_list (NULL_TREE,
2386 my_build_string (IDENTIFIER_LENGTH (ident) + 1,
2387 IDENTIFIER_POINTER (ident)));
2389 assemble_external (objc_get_class_decl);
2390 return build_function_call (objc_get_class_decl, params);
2394 /* For each string section we have a chain which maps identifier nodes
2395 to decls for the strings. */
2398 add_objc_string (tree ident, enum string_section section)
2402 if (section == class_names)
2403 chain = &class_names_chain;
2404 else if (section == meth_var_names)
2405 chain = &meth_var_names_chain;
2406 else if (section == meth_var_types)
2407 chain = &meth_var_types_chain;
2413 if (TREE_VALUE (*chain) == ident)
2414 return build_unary_op (ADDR_EXPR, TREE_PURPOSE (*chain), 1);
2416 chain = &TREE_CHAIN (*chain);
2419 decl = build_objc_string_decl (section);
2421 *chain = tree_cons (decl, ident, NULL_TREE);
2423 return build_unary_op (ADDR_EXPR, decl, 1);
2426 static GTY(()) int class_names_idx;
2427 static GTY(()) int meth_var_names_idx;
2428 static GTY(()) int meth_var_types_idx;
2431 build_objc_string_decl (enum string_section section)
2436 if (section == class_names)
2437 sprintf (buf, "_OBJC_CLASS_NAME_%d", class_names_idx++);
2438 else if (section == meth_var_names)
2439 sprintf (buf, "_OBJC_METH_VAR_NAME_%d", meth_var_names_idx++);
2440 else if (section == meth_var_types)
2441 sprintf (buf, "_OBJC_METH_VAR_TYPE_%d", meth_var_types_idx++);
2443 ident = get_identifier (buf);
2445 decl = build_decl (VAR_DECL, ident, build_array_type (char_type_node, 0));
2446 DECL_EXTERNAL (decl) = 1;
2447 TREE_PUBLIC (decl) = 0;
2448 TREE_USED (decl) = 1;
2449 TREE_CONSTANT (decl) = 1;
2450 DECL_CONTEXT (decl) = 0;
2451 DECL_ARTIFICIAL (decl) = 1;
2453 make_decl_rtl (decl);
2454 pushdecl_top_level (decl);
2461 objc_declare_alias (tree alias_ident, tree class_ident)
2463 tree underlying_class;
2466 if (current_namespace != global_namespace) {
2467 error ("Objective-C declarations may only appear in global scope");
2469 #endif /* OBJCPLUS */
2471 if (!(underlying_class = objc_is_class_name (class_ident)))
2472 warning ("cannot find class `%s'", IDENTIFIER_POINTER (class_ident));
2473 else if (objc_is_class_name (alias_ident))
2474 warning ("class `%s' already exists", IDENTIFIER_POINTER (alias_ident));
2476 alias_chain = tree_cons (underlying_class, alias_ident, alias_chain);
2480 objc_declare_class (tree ident_list)
2484 if (current_namespace != global_namespace) {
2485 error ("Objective-C declarations may only appear in global scope");
2487 #endif /* OBJCPLUS */
2489 for (list = ident_list; list; list = TREE_CHAIN (list))
2491 tree ident = TREE_VALUE (list);
2493 if (! objc_is_class_name (ident))
2495 tree record = lookup_name (ident);
2497 if (record && ! TREE_STATIC_TEMPLATE (record))
2499 error ("`%s' redeclared as different kind of symbol",
2500 IDENTIFIER_POINTER (ident));
2501 error ("%Jprevious declaration of '%D'",
2505 record = xref_tag (RECORD_TYPE, ident);
2506 TREE_STATIC_TEMPLATE (record) = 1;
2507 class_chain = tree_cons (NULL_TREE, ident, class_chain);
2513 objc_is_class_name (tree ident)
2517 if (ident && TREE_CODE (ident) == IDENTIFIER_NODE
2518 && identifier_global_value (ident))
2519 ident = identifier_global_value (ident);
2520 while (ident && TREE_CODE (ident) == TYPE_DECL && DECL_ORIGINAL_TYPE (ident))
2521 ident = TYPE_NAME (DECL_ORIGINAL_TYPE (ident));
2524 if (ident && TREE_CODE (ident) == RECORD_TYPE)
2525 ident = TYPE_NAME (ident);
2526 if (ident && TREE_CODE (ident) == TYPE_DECL)
2527 ident = DECL_NAME (ident);
2529 if (!ident || TREE_CODE (ident) != IDENTIFIER_NODE)
2532 if (lookup_interface (ident))
2535 for (chain = class_chain; chain; chain = TREE_CHAIN (chain))
2537 if (ident == TREE_VALUE (chain))
2541 for (chain = alias_chain; chain; chain = TREE_CHAIN (chain))
2543 if (ident == TREE_VALUE (chain))
2544 return TREE_PURPOSE (chain);
2550 /* Check whether TYPE is either 'id', 'Class', or a pointer to an ObjC
2551 class instance. This is needed by other parts of the compiler to
2552 handle ObjC types gracefully. */
2555 objc_is_object_ptr (tree type)
2557 type = TYPE_MAIN_VARIANT (type);
2558 if (!type || TREE_CODE (type) != POINTER_TYPE)
2560 /* NB: This function may be called before the ObjC front-end has
2561 been initialized, in which case OBJC_ID_TYPE will be NULL. */
2562 if (objc_id_type && type && TYPE_P (type)
2564 || TREE_TYPE (type) == TREE_TYPE (objc_class_type)))
2566 return objc_is_class_name (OBJC_TYPE_NAME (TREE_TYPE (type)));
2570 lookup_interface (tree ident)
2575 if (ident && TREE_CODE (ident) == TYPE_DECL)
2576 ident = DECL_NAME (ident);
2578 for (chain = interface_chain; chain; chain = TREE_CHAIN (chain))
2580 if (ident == CLASS_NAME (chain))
2586 /* Implement @defs (<classname>) within struct bodies. */
2589 get_class_ivars_from_name (tree class_name)
2591 tree interface = lookup_interface (class_name);
2592 tree field, fields = NULL_TREE;
2596 tree raw_ivar = get_class_ivars (interface, 1);
2598 /* Regenerate the FIELD_DECLs for the enclosing struct. */
2599 for (; raw_ivar; raw_ivar = TREE_CHAIN (raw_ivar))
2601 field = grokfield (TREE_PURPOSE (TREE_VALUE (raw_ivar)),
2602 TREE_PURPOSE (raw_ivar),
2603 TREE_VALUE (TREE_VALUE (raw_ivar)));
2605 finish_member_declaration (field);
2607 fields = chainon (fields, field);
2612 error ("cannot find interface declaration for `%s'",
2613 IDENTIFIER_POINTER (class_name));
2618 /* Used by: build_private_template, continue_class,
2619 and for @defs constructs. */
2622 get_class_ivars (tree interface, int raw)
2624 tree my_name, super_name, ivar_chain;
2626 my_name = CLASS_NAME (interface);
2627 super_name = CLASS_SUPER_NAME (interface);
2629 ivar_chain = CLASS_RAW_IVARS (interface);
2632 ivar_chain = CLASS_IVARS (interface);
2633 /* Save off a pristine copy of the leaf ivars (i.e, those not
2634 inherited from a super class). */
2635 if (!CLASS_OWN_IVARS (interface))
2636 CLASS_OWN_IVARS (interface) = copy_list (ivar_chain);
2642 tree super_interface = lookup_interface (super_name);
2644 if (!super_interface)
2646 /* fatal did not work with 2 args...should fix */
2647 error ("cannot find interface declaration for `%s', superclass of `%s'",
2648 IDENTIFIER_POINTER (super_name),
2649 IDENTIFIER_POINTER (my_name));
2650 exit (FATAL_EXIT_CODE);
2653 if (super_interface == interface)
2654 fatal_error ("circular inheritance in interface declaration for `%s'",
2655 IDENTIFIER_POINTER (super_name));
2657 interface = super_interface;
2658 my_name = CLASS_NAME (interface);
2659 super_name = CLASS_SUPER_NAME (interface);
2661 op1 = (raw ? CLASS_RAW_IVARS (interface) : CLASS_OWN_IVARS (interface));
2664 tree head = copy_list (op1);
2666 /* Prepend super class ivars...make a copy of the list, we
2667 do not want to alter the original. */
2668 chainon (head, ivar_chain);
2677 objc_create_temporary_var (tree type)
2681 decl = build_decl (VAR_DECL, NULL_TREE, type);
2682 TREE_USED (decl) = 1;
2683 DECL_ARTIFICIAL (decl) = 1;
2684 DECL_IGNORED_P (decl) = 1;
2685 DECL_CONTEXT (decl) = current_function_decl;
2690 /* Exception handling constructs. We begin by having the parser do most
2691 of the work and passing us blocks. What we do next depends on whether
2692 we're doing "native" exception handling or legacy Darwin setjmp exceptions.
2693 We abstract all of this in a handful of appropriately named routines. */
2695 /* Stack of open try blocks. */
2697 struct objc_try_context
2699 struct objc_try_context *outer;
2701 /* Statements (or statement lists) as processed by the parser. */
2705 /* Some file position locations. */
2706 location_t try_locus;
2707 location_t end_try_locus;
2708 location_t end_catch_locus;
2709 location_t finally_locus;
2710 location_t end_finally_locus;
2712 /* A STATEMENT_LIST of CATCH_EXPRs, appropriate for sticking into op1
2713 of a TRY_CATCH_EXPR. Even when doing Darwin setjmp. */
2716 /* The CATCH_EXPR of an open @catch clause. */
2719 /* The VAR_DECL holding the Darwin equivalent of EXC_PTR_EXPR. */
2725 static struct objc_try_context *cur_try_context;
2727 /* This hook, called via lang_eh_runtime_type, generates a runtime object
2728 that represents TYPE. For Objective-C, this is just the class name. */
2729 /* ??? Isn't there a class object or some such? Is it easy to get? */
2732 objc_eh_runtime_type (tree type)
2734 return add_objc_string (OBJC_TYPE_NAME (TREE_TYPE (type)), class_names);
2737 /* Initialize exception handling. */
2740 objc_init_exceptions (void)
2742 static bool done = false;
2748 if (!flag_objc_exceptions)
2749 warning ("use %<-fobjc-exceptions%> to enable Objective-C "
2750 "exception syntax");
2752 if (!flag_objc_sjlj_exceptions)
2754 c_eh_initialized_p = true;
2755 eh_personality_libfunc
2756 = init_one_libfunc (USING_SJLJ_EXCEPTIONS
2757 ? "__gnu_objc_personality_sj0"
2758 : "__gnu_objc_personality_v0");
2759 using_eh_for_cleanups ();
2760 lang_eh_runtime_type = objc_eh_runtime_type;
2764 /* Build an EXC_PTR_EXPR, or the moral equivalent. In the case of Darwin,
2765 we'll arrange for it to be initialized (and associated with a binding)
2769 objc_build_exc_ptr (void)
2771 if (flag_objc_sjlj_exceptions)
2773 tree var = cur_try_context->caught_decl;
2776 var = objc_create_temporary_var (objc_id_type);
2777 cur_try_context->caught_decl = var;
2782 return build (EXC_PTR_EXPR, objc_id_type);
2785 /* Build "objc_exception_try_exit(&_stack)". */
2788 next_sjlj_build_try_exit (void)
2791 t = build_fold_addr_expr (cur_try_context->stack_decl);
2792 t = tree_cons (NULL, t, NULL);
2793 t = build_function_call (objc_exception_try_exit_decl, t);
2798 objc_exception_try_enter (&_stack);
2799 if (_setjmp(&_stack.buf))
2803 Return the COND_EXPR. Note that the THEN and ELSE fields are left
2804 empty, ready for the caller to fill them in. */
2807 next_sjlj_build_enter_and_setjmp (void)
2809 tree t, enter, sj, cond;
2811 t = build_fold_addr_expr (cur_try_context->stack_decl);
2812 t = tree_cons (NULL, t, NULL);
2813 enter = build_function_call (objc_exception_try_enter_decl, t);
2815 t = build_component_ref (cur_try_context->stack_decl,
2816 get_identifier ("buf"));
2817 t = build_fold_addr_expr (t);
2818 t = convert (ptr_type_node, t);
2819 t = tree_cons (NULL, t, NULL);
2820 sj = build_function_call (objc_setjmp_decl, t);
2822 cond = build (COMPOUND_EXPR, TREE_TYPE (sj), enter, sj);
2823 cond = lang_hooks.truthvalue_conversion (cond);
2825 return build (COND_EXPR, void_type_node, cond, NULL, NULL);
2829 DECL = objc_exception_extract(&_stack);
2833 next_sjlj_build_exc_extract (tree decl)
2837 t = build_fold_addr_expr (cur_try_context->stack_decl);
2838 t = tree_cons (NULL, t, NULL);
2839 t = build_function_call (objc_exception_extract_decl, t);
2840 t = convert (TREE_TYPE (decl), t);
2841 t = build (MODIFY_EXPR, void_type_node, decl, t);
2847 if (objc_exception_match(obj_get_class(TYPE), _caught)
2854 objc_exception_try_exit(&_stack);
2856 from the sequence of CATCH_EXPRs in the current try context. */
2859 next_sjlj_build_catch_list (void)
2861 tree_stmt_iterator i = tsi_start (cur_try_context->catch_list);
2863 tree *last = &catch_seq;
2864 bool saw_id = false;
2866 for (; !tsi_end_p (i); tsi_next (&i))
2868 tree stmt = tsi_stmt (i);
2869 tree type = CATCH_TYPES (stmt);
2870 tree body = CATCH_BODY (stmt);
2882 if (type == error_mark_node)
2883 cond = error_mark_node;
2886 args = tree_cons (NULL, cur_try_context->caught_decl, NULL);
2887 t = get_class_reference (OBJC_TYPE_NAME (TREE_TYPE (type)));
2888 args = tree_cons (NULL, t, args);
2889 t = build_function_call (objc_exception_match_decl, args);
2890 cond = lang_hooks.truthvalue_conversion (t);
2892 t = build (COND_EXPR, void_type_node, cond, body, NULL);
2893 SET_EXPR_LOCUS (t, EXPR_LOCUS (stmt));
2896 last = &COND_EXPR_ELSE (t);
2902 t = build (MODIFY_EXPR, void_type_node, cur_try_context->rethrow_decl,
2903 cur_try_context->caught_decl);
2904 annotate_with_locus (t, cur_try_context->end_catch_locus);
2905 append_to_statement_list (t, last);
2907 t = next_sjlj_build_try_exit ();
2908 annotate_with_locus (t, cur_try_context->end_catch_locus);
2909 append_to_statement_list (t, last);
2915 /* Build a complete @try-@catch-@finally block for legacy Darwin setjmp
2916 exception handling. We aim to build:
2919 struct _objc_exception_data _stack;
2920 id volatile _rethrow = 0;
2923 objc_exception_try_enter (&_stack);
2924 if (_setjmp(&_stack.buf))
2926 id _caught = objc_exception_extract(&_stack);
2927 objc_exception_try_enter (&_stack);
2928 if (_setjmp(&_stack.buf))
2929 _rethrow = objc_exception_extract(&_stack);
2939 objc_exception_try_exit(&_stack);
2942 objc_exception_throw(_rethrow);
2946 If CATCH-LIST is empty, we can omit all of the block containing
2947 "_caught" except for the setting of _rethrow. Note the use of
2948 a real TRY_FINALLY_EXPR here, which is not involved in EH per-se,
2949 but handles goto and other exits from the block. */
2952 next_sjlj_build_try_catch_finally (void)
2954 tree rethrow_decl, stack_decl, t;
2955 tree catch_seq, try_fin, bind;
2957 /* Create the declarations involved. */
2958 t = xref_tag (RECORD_TYPE, get_identifier (UTAG_EXCDATA));
2959 stack_decl = objc_create_temporary_var (t);
2960 cur_try_context->stack_decl = stack_decl;
2962 rethrow_decl = objc_create_temporary_var (objc_id_type);
2963 cur_try_context->rethrow_decl = rethrow_decl;
2964 TREE_THIS_VOLATILE (rethrow_decl) = 1;
2965 TREE_CHAIN (rethrow_decl) = stack_decl;
2967 /* Build the outermost varible binding level. */
2968 bind = build (BIND_EXPR, void_type_node, rethrow_decl, NULL, NULL);
2969 annotate_with_locus (bind, cur_try_context->try_locus);
2970 TREE_SIDE_EFFECTS (bind) = 1;
2972 /* Initialize rethrow_decl. */
2973 t = build (MODIFY_EXPR, void_type_node, rethrow_decl,
2974 convert (objc_id_type, null_pointer_node));
2975 annotate_with_locus (t, cur_try_context->try_locus);
2976 append_to_statement_list (t, &BIND_EXPR_BODY (bind));
2978 /* Build the outermost TRY_FINALLY_EXPR. */
2979 try_fin = build (TRY_FINALLY_EXPR, void_type_node, NULL, NULL);
2980 annotate_with_locus (try_fin, cur_try_context->try_locus);
2981 TREE_SIDE_EFFECTS (try_fin) = 1;
2982 append_to_statement_list (try_fin, &BIND_EXPR_BODY (bind));
2984 /* Create the complete catch sequence. */
2985 if (cur_try_context->catch_list)
2987 tree caught_decl = objc_build_exc_ptr ();
2988 catch_seq = build_stmt (BIND_EXPR, caught_decl, NULL, NULL);
2990 t = next_sjlj_build_exc_extract (caught_decl);
2991 append_to_statement_list (t, &BIND_EXPR_BODY (catch_seq));
2993 t = next_sjlj_build_enter_and_setjmp ();
2994 COND_EXPR_THEN (t) = next_sjlj_build_exc_extract (rethrow_decl);
2995 COND_EXPR_ELSE (t) = next_sjlj_build_catch_list ();
2996 append_to_statement_list (t, &BIND_EXPR_BODY (catch_seq));
2999 catch_seq = next_sjlj_build_exc_extract (rethrow_decl);
3000 annotate_with_locus (catch_seq, cur_try_context->end_try_locus);
3002 /* Build the main register-and-try if statement. */
3003 t = next_sjlj_build_enter_and_setjmp ();
3004 annotate_with_locus (t, cur_try_context->try_locus);
3005 COND_EXPR_THEN (t) = catch_seq;
3006 COND_EXPR_ELSE (t) = cur_try_context->try_body;
3007 TREE_OPERAND (try_fin, 0) = t;
3009 /* Build the complete FINALLY statement list. */
3010 t = next_sjlj_build_try_exit ();
3011 t = build_stmt (COND_EXPR,
3012 lang_hooks.truthvalue_conversion (rethrow_decl),
3014 annotate_with_locus (t, cur_try_context->finally_locus);
3015 append_to_statement_list (t, &TREE_OPERAND (try_fin, 1));
3017 append_to_statement_list (cur_try_context->finally_body,
3018 &TREE_OPERAND (try_fin, 1));
3020 t = tree_cons (NULL, rethrow_decl, NULL);
3021 t = build_function_call (objc_exception_throw_decl, t);
3022 t = build_stmt (COND_EXPR,
3023 lang_hooks.truthvalue_conversion (rethrow_decl),
3025 annotate_with_locus (t, cur_try_context->end_finally_locus);
3026 append_to_statement_list (t, &TREE_OPERAND (try_fin, 1));
3031 /* Called just after parsing the @try and its associated BODY. We now
3032 must prepare for the tricky bits -- handling the catches and finally. */
3035 objc_begin_try_stmt (location_t try_locus, tree body)
3037 struct objc_try_context *c = xcalloc (1, sizeof (*c));
3038 c->outer = cur_try_context;
3040 c->try_locus = try_locus;
3041 c->end_try_locus = input_location;
3042 cur_try_context = c;
3044 objc_init_exceptions ();
3047 /* Called just after parsing "@catch (parm)". Open a binding level,
3048 enter PARM into the binding level, and initialize it. Leave the
3049 binding level open while the body of the compound statement is parsed. */
3052 objc_begin_catch_clause (tree parm)
3054 tree compound, decl, type, t;
3056 /* Begin a new scope that the entire catch clause will live in. */
3057 compound = c_begin_compound_stmt (1);
3059 /* Turn the raw declarator/declspecs into a decl in the current scope. */
3060 decl = define_decl (TREE_VALUE (TREE_PURPOSE (parm)),
3061 TREE_PURPOSE (TREE_PURPOSE (parm)));
3063 /* Since a decl is required here by syntax, don't warn if its unused. */
3064 /* ??? As opposed to __attribute__((unused))? Anyway, this appears to
3065 be what the previous objc implementation did. */
3066 TREE_USED (decl) = 1;
3068 /* Verify that the type of the catch is valid. It must be a pointer
3069 to an Objective-C class, or "id" (which is catch-all). */
3070 type = TREE_TYPE (decl);
3071 if (POINTER_TYPE_P (type) && objc_is_object_id (TREE_TYPE (type)))
3073 else if (!POINTER_TYPE_P (type) || !TYPED_OBJECT (TREE_TYPE (type)))
3075 error ("@catch parameter is not a known Objective-C class type");
3076 type = error_mark_node;
3078 else if (cur_try_context->catch_list)
3080 /* Examine previous @catch clauses and see if we've already
3081 caught the type in question. */
3082 tree_stmt_iterator i = tsi_start (cur_try_context->catch_list);
3083 for (; !tsi_end_p (i); tsi_next (&i))
3085 tree stmt = tsi_stmt (i);
3086 t = CATCH_TYPES (stmt);
3087 if (t == error_mark_node)
3089 if (!t || objc_comptypes (TREE_TYPE (t), TREE_TYPE (type), 0) == 1)
3091 warning ("exception of type %<%T%> will be caught",
3093 warning ("%H by earlier handler for %<%T%>",
3094 EXPR_LOCUS (stmt), TREE_TYPE (t ? t : objc_id_type));
3100 /* Record the data for the catch in the try context so that we can
3101 finalize it later. */
3102 t = build_stmt (CATCH_EXPR, type, compound);
3103 cur_try_context->current_catch = t;
3105 /* Initialize the decl from the EXC_PTR_EXPR we get from the runtime. */
3106 t = objc_build_exc_ptr ();
3107 t = convert (TREE_TYPE (decl), t);
3108 t = build (MODIFY_EXPR, void_type_node, decl, t);
3112 /* Called just after parsing the closing brace of a @catch clause. Close
3113 the open binding level, and record a CATCH_EXPR for it. */
3116 objc_finish_catch_clause (void)
3118 tree c = cur_try_context->current_catch;
3119 cur_try_context->current_catch = NULL;
3120 cur_try_context->end_catch_locus = input_location;
3122 CATCH_BODY (c) = c_end_compound_stmt (CATCH_BODY (c), 1);
3123 append_to_statement_list (c, &cur_try_context->catch_list);
3126 /* Called after parsing a @finally clause and its associated BODY.
3127 Record the body for later placement. */
3130 objc_build_finally_clause (location_t finally_locus, tree body)
3132 cur_try_context->finally_body = body;
3133 cur_try_context->finally_locus = finally_locus;
3134 cur_try_context->end_finally_locus = input_location;
3137 /* Called to finalize a @try construct. */
3140 objc_finish_try_stmt (void)
3142 struct objc_try_context *c = cur_try_context;
3145 if (c->catch_list == NULL && c->finally_body == NULL)
3146 error ("`@try' without `@catch' or `@finally'");
3148 /* If we're doing Darwin setjmp exceptions, build the big nasty. */
3149 if (flag_objc_sjlj_exceptions)
3151 if (!cur_try_context->finally_body)
3153 cur_try_context->finally_locus = input_location;
3154 cur_try_context->end_finally_locus = input_location;
3156 stmt = next_sjlj_build_try_catch_finally ();
3160 /* Otherwise, nest the CATCH inside a FINALLY. */
3164 stmt = build_stmt (TRY_CATCH_EXPR, stmt, c->catch_list);
3165 annotate_with_locus (stmt, cur_try_context->try_locus);
3167 if (c->finally_body)
3169 stmt = build_stmt (TRY_FINALLY_EXPR, stmt, c->finally_body);
3170 annotate_with_locus (stmt, cur_try_context->try_locus);
3175 cur_try_context = c->outer;
3180 objc_build_throw_stmt (tree throw_expr)
3184 objc_init_exceptions ();
3186 if (throw_expr == NULL)
3188 /* If we're not inside a @catch block, there is no "current
3189 exception" to be rethrown. */
3190 if (cur_try_context == NULL
3191 || cur_try_context->current_catch == NULL)
3193 error ("%<@throw%> (rethrow) used outside of a @catch block");
3197 /* Otherwise the object is still sitting in the EXC_PTR_EXPR
3198 value that we get from the runtime. */
3199 throw_expr = objc_build_exc_ptr ();
3202 /* A throw is just a call to the runtime throw function with the
3203 object as a parameter. */
3204 args = tree_cons (NULL, throw_expr, NULL);
3205 return add_stmt (build_function_call (objc_exception_throw_decl, args));
3209 objc_build_synchronized (location_t start_locus, tree mutex, tree body)
3213 /* First lock the mutex. */
3214 mutex = save_expr (mutex);
3215 args = tree_cons (NULL, mutex, NULL);
3216 call = build_function_call (objc_sync_enter_decl, args);
3217 annotate_with_locus (call, start_locus);
3220 /* Build the mutex unlock. */
3221 args = tree_cons (NULL, mutex, NULL);
3222 call = build_function_call (objc_sync_exit_decl, args);
3223 annotate_with_locus (call, input_location);
3225 /* Put the that and the body in a TRY_FINALLY. */
3226 objc_begin_try_stmt (start_locus, body);
3227 objc_build_finally_clause (input_location, call);
3228 objc_finish_try_stmt ();
3232 /* Predefine the following data type:
3234 struct _objc_exception_data
3240 /* The following yuckiness should prevent users from having to #include
3241 <setjmp.h> in their code... */
3243 #ifdef TARGET_POWERPC
3244 /* snarfed from /usr/include/ppc/setjmp.h */
3245 #define _JBLEN (26 + 36 + 129 + 1)
3247 /* snarfed from /usr/include/i386/{setjmp,signal}.h */
3252 build_next_objc_exception_stuff (void)
3254 tree field_decl, field_decl_chain, index, temp_type;
3256 /* Suppress outputting debug symbols, because
3257 dbxout_init hasn't been called yet. */
3258 enum debug_info_type save_write_symbols = write_symbols;
3259 const struct gcc_debug_hooks *save_hooks = debug_hooks;
3261 write_symbols = NO_DEBUG;
3262 debug_hooks = &do_nothing_debug_hooks;
3264 objc_exception_data_template
3265 = start_struct (RECORD_TYPE, get_identifier (UTAG_EXCDATA));
3267 /* int buf[_JBLEN]; */
3269 index = build_index_type (build_int_cst (NULL_TREE, _JBLEN - 1));
3270 field_decl = create_builtin_decl (FIELD_DECL,
3271 build_array_type (integer_type_node, index),
3273 field_decl_chain = field_decl;
3275 /* void *pointers[4]; */
3277 index = build_index_type (build_int_cst (NULL_TREE, 4 - 1));
3278 field_decl = create_builtin_decl (FIELD_DECL,
3279 build_array_type (ptr_type_node, index),
3281 chainon (field_decl_chain, field_decl);
3283 finish_struct (objc_exception_data_template, field_decl_chain, NULL_TREE);
3285 /* int _setjmp(...); */
3286 /* If the user includes <setjmp.h>, this shall be superseded by
3287 'int _setjmp(jmp_buf);' */
3288 temp_type = build_function_type (integer_type_node, NULL_TREE);
3290 = builtin_function (TAG_SETJMP, temp_type, 0, NOT_BUILT_IN, NULL, NULL_TREE);
3292 /* id objc_exception_extract(struct _objc_exception_data *); */
3294 = build_function_type (objc_id_type,
3295 tree_cons (NULL_TREE,
3296 build_pointer_type (objc_exception_data_template),
3298 objc_exception_extract_decl
3299 = builtin_function (TAG_EXCEPTIONEXTRACT, temp_type, 0, NOT_BUILT_IN, NULL, NULL_TREE);
3300 /* void objc_exception_try_enter(struct _objc_exception_data *); */
3301 /* void objc_exception_try_exit(struct _objc_exception_data *); */
3303 = build_function_type (void_type_node,
3304 tree_cons (NULL_TREE,
3305 build_pointer_type (objc_exception_data_template),
3307 objc_exception_try_enter_decl
3308 = builtin_function (TAG_EXCEPTIONTRYENTER, temp_type, 0, NOT_BUILT_IN, NULL, NULL_TREE);
3309 objc_exception_try_exit_decl
3310 = builtin_function (TAG_EXCEPTIONTRYEXIT, temp_type, 0, NOT_BUILT_IN, NULL, NULL_TREE);
3312 /* int objc_exception_match(id, id); */
3314 = build_function_type (integer_type_node,
3315 tree_cons (NULL_TREE, objc_id_type,
3316 tree_cons (NULL_TREE, objc_id_type,
3318 objc_exception_match_decl
3319 = builtin_function (TAG_EXCEPTIONMATCH, temp_type, 0, NOT_BUILT_IN, NULL, NULL_TREE);
3321 write_symbols = save_write_symbols;
3322 debug_hooks = save_hooks;
3326 build_objc_exception_stuff (void)
3328 tree noreturn_list, nothrow_list, temp_type;
3330 noreturn_list = tree_cons (get_identifier ("noreturn"), NULL, NULL);
3331 nothrow_list = tree_cons (get_identifier ("nothrow"), NULL, NULL);
3333 /* void objc_exception_throw(id) __attribute__((noreturn)); */
3334 /* void objc_sync_enter(id); */
3335 /* void objc_sync_exit(id); */
3336 temp_type = build_function_type (void_type_node,
3337 tree_cons (NULL_TREE, objc_id_type,
3339 objc_exception_throw_decl
3340 = builtin_function (TAG_EXCEPTIONTHROW, temp_type, 0, NOT_BUILT_IN, NULL,
3342 objc_sync_enter_decl
3343 = builtin_function (TAG_SYNCENTER, temp_type, 0, NOT_BUILT_IN,
3344 NULL, nothrow_list);
3346 = builtin_function (TAG_SYNCEXIT, temp_type, 0, NOT_BUILT_IN,
3347 NULL, nothrow_list);
3351 /* struct <classname> {
3352 struct objc_class *isa;
3357 build_private_template (tree class)
3361 if (CLASS_STATIC_TEMPLATE (class))
3363 uprivate_record = CLASS_STATIC_TEMPLATE (class);
3364 ivar_context = TYPE_FIELDS (CLASS_STATIC_TEMPLATE (class));
3368 uprivate_record = start_struct (RECORD_TYPE, CLASS_NAME (class));
3369 ivar_context = get_class_ivars (class, 0);
3371 finish_struct (uprivate_record, ivar_context, NULL_TREE);
3373 CLASS_STATIC_TEMPLATE (class) = uprivate_record;
3375 /* mark this record as class template - for class type checking */
3376 TREE_STATIC_TEMPLATE (uprivate_record) = 1;
3380 = groktypename (build_tree_list (build_tree_list (NULL_TREE,
3382 build1 (INDIRECT_REF, NULL_TREE,
3385 return ivar_context;
3388 /* Begin code generation for protocols... */
3390 /* struct objc_protocol {
3391 char *protocol_name;
3392 struct objc_protocol **protocol_list;
3393 struct objc_method_desc *instance_methods;
3394 struct objc_method_desc *class_methods;
3398 build_protocol_template (void)
3400 tree decl_specs, field_decl, field_decl_chain;
3403 template = start_struct (RECORD_TYPE, get_identifier (UTAG_PROTOCOL));
3405 /* struct objc_class *isa; */
3407 decl_specs = build_tree_list (NULL_TREE, xref_tag (RECORD_TYPE,
3408 get_identifier (UTAG_CLASS)));
3409 field_decl = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("isa"));
3410 field_decl = grokfield (field_decl, decl_specs, NULL_TREE);
3411 field_decl_chain = field_decl;
3413 /* char *protocol_name; */
3415 decl_specs = build_tree_list (NULL_TREE, ridpointers[(int) RID_CHAR]);
3417 = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("protocol_name"));
3418 field_decl = grokfield (field_decl, decl_specs, NULL_TREE);
3419 chainon (field_decl_chain, field_decl);
3421 /* struct objc_protocol **protocol_list; */
3423 decl_specs = build_tree_list (NULL_TREE, template);
3425 = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("protocol_list"));
3426 field_decl = build1 (INDIRECT_REF, NULL_TREE, field_decl);
3427 field_decl = grokfield (field_decl, decl_specs, NULL_TREE);
3428 chainon (field_decl_chain, field_decl);
3430 /* struct objc_method_list *instance_methods; */
3433 = build_tree_list (NULL_TREE,
3434 xref_tag (RECORD_TYPE,
3435 get_identifier (UTAG_METHOD_PROTOTYPE_LIST)));
3437 = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("instance_methods"));
3438 field_decl = grokfield (field_decl, decl_specs, NULL_TREE);
3439 chainon (field_decl_chain, field_decl);
3441 /* struct objc_method_list *class_methods; */
3444 = build_tree_list (NULL_TREE,
3445 xref_tag (RECORD_TYPE,
3446 get_identifier (UTAG_METHOD_PROTOTYPE_LIST)));
3448 = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("class_methods"));
3449 field_decl = grokfield (field_decl, decl_specs, NULL_TREE);
3450 chainon (field_decl_chain, field_decl);
3452 return finish_struct (template, field_decl_chain, NULL_TREE);
3456 build_descriptor_table_initializer (tree type, tree entries)
3458 tree initlist = NULL_TREE;
3462 tree eltlist = NULL_TREE;
3465 = tree_cons (NULL_TREE,
3466 build_selector (METHOD_SEL_NAME (entries)), NULL_TREE);
3468 = tree_cons (NULL_TREE,
3469 add_objc_string (METHOD_ENCODING (entries),
3474 = tree_cons (NULL_TREE,
3475 objc_build_constructor (type, nreverse (eltlist)),
3478 entries = TREE_CHAIN (entries);
3482 return objc_build_constructor (build_array_type (type, 0),
3483 nreverse (initlist));
3486 /* struct objc_method_prototype_list {
3488 struct objc_method_prototype {
3495 build_method_prototype_list_template (tree list_type, int size)
3497 tree objc_ivar_list_record;
3498 tree decl_specs, field_decl, field_decl_chain;
3500 /* Generate an unnamed struct definition. */
3502 objc_ivar_list_record = start_struct (RECORD_TYPE, NULL_TREE);
3504 /* int method_count; */
3506 decl_specs = build_tree_list (NULL_TREE, ridpointers[(int) RID_INT]);
3507 field_decl = get_identifier ("method_count");
3508 field_decl = grokfield (field_decl, decl_specs, NULL_TREE);
3509 field_decl_chain = field_decl;
3511 /* struct objc_method method_list[]; */
3513 decl_specs = build_tree_list (NULL_TREE, list_type);
3514 field_decl = build_nt (ARRAY_REF, get_identifier ("method_list"),
3515 build_int_cst (NULL_TREE, size), NULL_TREE, NULL_TREE);
3516 field_decl = grokfield (field_decl, decl_specs, NULL_TREE);
3517 chainon (field_decl_chain, field_decl);
3519 finish_struct (objc_ivar_list_record, field_decl_chain, NULL_TREE);
3521 return objc_ivar_list_record;
3525 build_method_prototype_template (void)
3528 tree decl_specs, field_decl, field_decl_chain;
3531 = start_struct (RECORD_TYPE, get_identifier (UTAG_METHOD_PROTOTYPE));
3533 /* struct objc_selector *_cmd; */
3534 decl_specs = tree_cons (NULL_TREE, xref_tag (RECORD_TYPE,
3535 get_identifier (TAG_SELECTOR)), NULL_TREE);
3536 field_decl = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("_cmd"));
3537 field_decl = grokfield (field_decl, decl_specs, NULL_TREE);
3538 field_decl_chain = field_decl;
3540 decl_specs = tree_cons (NULL_TREE, ridpointers[(int) RID_CHAR], NULL_TREE);
3542 = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("method_types"));
3543 field_decl = grokfield (field_decl, decl_specs, NULL_TREE);
3544 chainon (field_decl_chain, field_decl);
3546 finish_struct (proto_record, field_decl_chain, NULL_TREE);
3548 return proto_record;
3552 objc_method_parm_type (tree type)
3554 type = groktypename (TREE_TYPE (type));
3555 if (TREE_CODE (type) == TYPE_DECL)
3556 type = TREE_TYPE (type);
3557 return TYPE_MAIN_VARIANT (type);
3561 objc_encoded_type_size (tree type)
3563 int sz = int_size_in_bytes (type);
3565 /* Make all integer and enum types at least as large
3567 if (sz > 0 && (TREE_CODE (type) == INTEGER_TYPE
3568 || TREE_CODE (type) == BOOLEAN_TYPE
3569 || TREE_CODE (type) == ENUMERAL_TYPE))
3570 sz = MAX (sz, int_size_in_bytes (integer_type_node));
3571 /* Treat arrays as pointers, since that's how they're
3573 else if (TREE_CODE (type) == ARRAY_TYPE)
3574 sz = int_size_in_bytes (ptr_type_node);
3579 encode_method_prototype (tree method_decl)
3586 /* ONEWAY and BYCOPY, for remote object are the only method qualifiers. */
3587 encode_type_qualifiers (TREE_PURPOSE (TREE_TYPE (method_decl)));
3589 /* Encode return type. */
3590 encode_type (objc_method_parm_type (method_decl),
3591 obstack_object_size (&util_obstack),
3592 OBJC_ENCODE_INLINE_DEFS);
3595 /* The first two arguments (self and _cmd) are pointers; account for
3597 i = int_size_in_bytes (ptr_type_node);
3598 parm_offset = 2 * i;
3599 for (parms = METHOD_SEL_ARGS (method_decl); parms;
3600 parms = TREE_CHAIN (parms))
3602 tree type = objc_method_parm_type (parms);
3603 int sz = objc_encoded_type_size (type);
3605 /* If a type size is not known, bail out. */
3608 error ("%Jtype '%D' does not have a known size",
3610 /* Pretend that the encoding succeeded; the compilation will
3611 fail nevertheless. */
3612 goto finish_encoding;
3617 sprintf (buf, "%d@0:%d", parm_offset, i);
3618 obstack_grow (&util_obstack, buf, strlen (buf));
3620 /* Argument types. */
3621 parm_offset = 2 * i;
3622 for (parms = METHOD_SEL_ARGS (method_decl); parms;
3623 parms = TREE_CHAIN (parms))
3625 tree type = objc_method_parm_type (parms);
3627 /* Process argument qualifiers for user supplied arguments. */
3628 encode_type_qualifiers (TREE_PURPOSE (TREE_TYPE (parms)));
3631 encode_type (type, obstack_object_size (&util_obstack),
3632 OBJC_ENCODE_INLINE_DEFS);
3634 /* Compute offset. */
3635 sprintf (buf, "%d", parm_offset);
3636 parm_offset += objc_encoded_type_size (type);
3638 obstack_grow (&util_obstack, buf, strlen (buf));
3642 obstack_1grow (&util_obstack, '\0');
3643 result = get_identifier (obstack_finish (&util_obstack));
3644 obstack_free (&util_obstack, util_firstobj);
3649 generate_descriptor_table (tree type, const char *name, int size, tree list,
3652 tree sc_spec, decl_specs, decl, initlist;
3654 sc_spec = tree_cons (NULL_TREE, ridpointers[(int) RID_STATIC], NULL_TREE);
3655 decl_specs = tree_cons (NULL_TREE, type, sc_spec);
3657 decl = start_decl (synth_id_with_class_suffix (name, proto),
3658 decl_specs, 1, NULL_TREE);
3659 DECL_CONTEXT (decl) = NULL_TREE;
3661 initlist = build_tree_list (NULL_TREE, build_int_cst (NULL_TREE, size));
3662 initlist = tree_cons (NULL_TREE, list, initlist);
3664 finish_decl (decl, objc_build_constructor (type, nreverse (initlist)),
3671 generate_method_descriptors (tree protocol)
3673 tree initlist, chain, method_list_template;
3674 tree cast, variable_length_type;
3677 if (!objc_method_prototype_template)
3678 objc_method_prototype_template = build_method_prototype_template ();
3680 cast = build_tree_list (build_tree_list (NULL_TREE, xref_tag (RECORD_TYPE,
3681 get_identifier (UTAG_METHOD_PROTOTYPE_LIST))),
3683 variable_length_type = groktypename (cast);
3685 chain = PROTOCOL_CLS_METHODS (protocol);
3688 size = list_length (chain);
3690 method_list_template
3691 = build_method_prototype_list_template (objc_method_prototype_template,
3695 = build_descriptor_table_initializer (objc_method_prototype_template,
3698 UOBJC_CLASS_METHODS_decl
3699 = generate_descriptor_table (method_list_template,
3700 "_OBJC_PROTOCOL_CLASS_METHODS",
3701 size, initlist, protocol);
3702 TREE_TYPE (UOBJC_CLASS_METHODS_decl) = variable_length_type;
3705 UOBJC_CLASS_METHODS_decl = 0;
3707 chain = PROTOCOL_NST_METHODS (protocol);
3710 size = list_length (chain);
3712 method_list_template
3713 = build_method_prototype_list_template (objc_method_prototype_template,
3716 = build_descriptor_table_initializer (objc_method_prototype_template,
3719 UOBJC_INSTANCE_METHODS_decl
3720 = generate_descriptor_table (method_list_template,
3721 "_OBJC_PROTOCOL_INSTANCE_METHODS",
3722 size, initlist, protocol);
3723 TREE_TYPE (UOBJC_INSTANCE_METHODS_decl) = variable_length_type;
3726 UOBJC_INSTANCE_METHODS_decl = 0;
3730 generate_protocol_references (tree plist)
3734 /* Forward declare protocols referenced. */
3735 for (lproto = plist; lproto; lproto = TREE_CHAIN (lproto))
3737 tree proto = TREE_VALUE (lproto);
3739 if (TREE_CODE (proto) == PROTOCOL_INTERFACE_TYPE
3740 && PROTOCOL_NAME (proto))
3742 if (! PROTOCOL_FORWARD_DECL (proto))
3743 build_protocol_reference (proto);
3745 if (PROTOCOL_LIST (proto))
3746 generate_protocol_references (PROTOCOL_LIST (proto));
3751 /* For each protocol which was referenced either from a @protocol()
3752 expression, or because a class/category implements it (then a
3753 pointer to the protocol is stored in the struct describing the
3754 class/category), we create a statically allocated instance of the
3755 Protocol class. The code is written in such a way as to generate
3756 as few Protocol objects as possible; we generate a unique Protocol
3757 instance for each protocol, and we don't generate a Protocol
3758 instance if the protocol is never referenced (either from a
3759 @protocol() or from a class/category implementation). These
3760 statically allocated objects can be referred to via the static
3761 (that is, private to this module) symbols _OBJC_PROTOCOL_n.
3763 The statically allocated Protocol objects that we generate here
3764 need to be fixed up at runtime in order to be used: the 'isa'
3765 pointer of the objects need to be set up to point to the 'Protocol'
3766 class, as known at runtime.
3768 The NeXT runtime fixes up all protocols at program startup time,
3769 before main() is entered. It uses a low-level trick to look up all
3770 those symbols, then loops on them and fixes them up.
3772 The GNU runtime as well fixes up all protocols before user code
3773 from the module is executed; it requires pointers to those symbols
3774 to be put in the objc_symtab (which is then passed as argument to
3775 the function __objc_exec_class() which the compiler sets up to be
3776 executed automatically when the module is loaded); setup of those
3777 Protocol objects happen in two ways in the GNU runtime: all
3778 Protocol objects referred to by a class or category implementation
3779 are fixed up when the class/category is loaded; all Protocol
3780 objects referred to by a @protocol() expression are added by the
3781 compiler to the list of statically allocated instances to fixup
3782 (the same list holding the statically allocated constant string
3783 objects). Because, as explained above, the compiler generates as
3784 few Protocol objects as possible, some Protocol object might end up
3785 being referenced multiple times when compiled with the GNU runtime,
3786 and end up being fixed up multiple times at runtime inizialization.
3787 But that doesn't hurt, it's just a little inefficient. */
3790 generate_protocols (void)
3793 tree sc_spec, decl_specs, decl;
3794 tree initlist, protocol_name_expr, refs_decl, refs_expr;
3797 if (! objc_protocol_template)
3798 objc_protocol_template = build_protocol_template ();
3800 /* If a protocol was directly referenced, pull in indirect references. */
3801 for (p = protocol_chain; p; p = TREE_CHAIN (p))
3802 if (PROTOCOL_FORWARD_DECL (p) && PROTOCOL_LIST (p))
3803 generate_protocol_references (PROTOCOL_LIST (p));
3805 for (p = protocol_chain; p; p = TREE_CHAIN (p))
3807 tree nst_methods = PROTOCOL_NST_METHODS (p);
3808 tree cls_methods = PROTOCOL_CLS_METHODS (p);
3810 /* If protocol wasn't referenced, don't generate any code. */
3811 if (! PROTOCOL_FORWARD_DECL (p))
3814 /* Make sure we link in the Protocol class. */
3815 add_class_reference (get_identifier (PROTOCOL_OBJECT_CLASS_NAME));
3819 if (! METHOD_ENCODING (nst_methods))
3821 encoding = encode_method_prototype (nst_methods);
3822 METHOD_ENCODING (nst_methods) = encoding;
3824 nst_methods = TREE_CHAIN (nst_methods);
3829 if (! METHOD_ENCODING (cls_methods))
3831 encoding = encode_method_prototype (cls_methods);
3832 METHOD_ENCODING (cls_methods) = encoding;
3835 cls_methods = TREE_CHAIN (cls_methods);
3837 generate_method_descriptors (p);
3839 if (PROTOCOL_LIST (p))
3840 refs_decl = generate_protocol_list (p);
3844 /* static struct objc_protocol _OBJC_PROTOCOL_<mumble>; */
3846 sc_spec = tree_cons (NULL_TREE, ridpointers[(int) RID_STATIC],
3848 decl_specs = tree_cons (NULL_TREE, objc_protocol_template, sc_spec);
3850 decl = start_decl (synth_id_with_class_suffix ("_OBJC_PROTOCOL", p),
3851 decl_specs, 1, NULL_TREE);
3853 DECL_CONTEXT (decl) = NULL_TREE;
3855 protocol_name_expr = add_objc_string (PROTOCOL_NAME (p), class_names);
3861 (build_tree_list (build_tree_list (NULL_TREE,
3862 objc_protocol_template),
3863 build1 (INDIRECT_REF, NULL_TREE,
3864 build1 (INDIRECT_REF, NULL_TREE,
3867 refs_expr = build_unary_op (ADDR_EXPR, refs_decl, 0);
3868 TREE_TYPE (refs_expr) = cast_type2;
3871 refs_expr = build_int_cst (NULL_TREE, 0);
3873 /* UOBJC_INSTANCE_METHODS_decl/UOBJC_CLASS_METHODS_decl are set
3874 by generate_method_descriptors, which is called above. */
3875 initlist = build_protocol_initializer (TREE_TYPE (decl),
3876 protocol_name_expr, refs_expr,
3877 UOBJC_INSTANCE_METHODS_decl,
3878 UOBJC_CLASS_METHODS_decl);
3879 finish_decl (decl, initlist, NULL_TREE);
3881 /* Mark the decl as used to avoid "defined but not used" warning. */
3882 TREE_USED (decl) = 1;
3887 build_protocol_initializer (tree type, tree protocol_name,
3888 tree protocol_list, tree instance_methods,
3891 tree initlist = NULL_TREE, expr;
3894 cast_type = groktypename
3896 (build_tree_list (NULL_TREE,
3897 xref_tag (RECORD_TYPE,
3898 get_identifier (UTAG_CLASS))),
3899 build1 (INDIRECT_REF, NULL_TREE, NULL_TREE)));
3901 /* Filling the "isa" in with one allows the runtime system to
3902 detect that the version change...should remove before final release. */
3904 expr = build_int_cst (cast_type, PROTOCOL_VERSION);
3905 initlist = tree_cons (NULL_TREE, expr, initlist);
3906 initlist = tree_cons (NULL_TREE, protocol_name, initlist);
3907 initlist = tree_cons (NULL_TREE, protocol_list, initlist);
3909 if (!instance_methods)
3910 initlist = tree_cons (NULL_TREE, build_int_cst (NULL_TREE, 0), initlist);
3913 expr = build_unary_op (ADDR_EXPR, instance_methods, 0);
3914 initlist = tree_cons (NULL_TREE, expr, initlist);
3918 initlist = tree_cons (NULL_TREE, build_int_cst (NULL_TREE, 0), initlist);
3921 expr = build_unary_op (ADDR_EXPR, class_methods, 0);
3922 initlist = tree_cons (NULL_TREE, expr, initlist);
3925 return objc_build_constructor (type, nreverse (initlist));
3928 /* struct objc_category {
3929 char *category_name;
3931 struct objc_method_list *instance_methods;
3932 struct objc_method_list *class_methods;
3933 struct objc_protocol_list *protocols;
3937 build_category_template (void)
3939 tree decl_specs, field_decl, field_decl_chain;
3941 objc_category_template = start_struct (RECORD_TYPE,
3942 get_identifier (UTAG_CATEGORY));
3943 /* char *category_name; */
3945 decl_specs = build_tree_list (NULL_TREE, ridpointers[(int) RID_CHAR]);
3947 = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("category_name"));
3948 field_decl = grokfield (field_decl, decl_specs, NULL_TREE);
3949 field_decl_chain = field_decl;
3951 /* char *class_name; */
3953 decl_specs = build_tree_list (NULL_TREE, ridpointers[(int) RID_CHAR]);
3954 field_decl = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("class_name"));
3955 field_decl = grokfield (field_decl, decl_specs, NULL_TREE);
3956 chainon (field_decl_chain, field_decl);
3958 /* struct objc_method_list *instance_methods; */
3960 decl_specs = build_tree_list (NULL_TREE,
3961 xref_tag (RECORD_TYPE,
3962 get_identifier (UTAG_METHOD_LIST)));
3964 = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("instance_methods"));
3965 field_decl = grokfield (field_decl, decl_specs, NULL_TREE);
3966 chainon (field_decl_chain, field_decl);
3968 /* struct objc_method_list *class_methods; */
3970 decl_specs = build_tree_list (NULL_TREE,
3971 xref_tag (RECORD_TYPE,
3972 get_identifier (UTAG_METHOD_LIST)));
3974 = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("class_methods"));
3975 field_decl = grokfield (field_decl, decl_specs, NULL_TREE);
3976 chainon (field_decl_chain, field_decl);
3978 /* struct objc_protocol **protocol_list; */
3980 decl_specs = build_tree_list (NULL_TREE,
3981 xref_tag (RECORD_TYPE,
3982 get_identifier (UTAG_PROTOCOL)));
3984 = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("protocol_list"));
3985 field_decl = build1 (INDIRECT_REF, NULL_TREE, field_decl);
3986 field_decl = grokfield (field_decl, decl_specs, NULL_TREE);
3987 chainon (field_decl_chain, field_decl);
3989 finish_struct (objc_category_template, field_decl_chain, NULL_TREE);
3992 /* struct objc_selector {
3998 build_selector_template (void)
4001 tree decl_specs, field_decl, field_decl_chain;
4003 objc_selector_template
4004 = start_struct (RECORD_TYPE, get_identifier (UTAG_SELECTOR));
4008 decl_specs = build_tree_list (NULL_TREE, ridpointers[(int) RID_VOID]);
4009 field_decl = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("sel_id"));
4010 field_decl = grokfield (field_decl, decl_specs, NULL_TREE);
4011 field_decl_chain = field_decl;
4013 /* char *sel_type; */
4015 decl_specs = build_tree_list (NULL_TREE, ridpointers[(int) RID_CHAR]);
4016 field_decl = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("sel_type"));
4017 field_decl = grokfield (field_decl, decl_specs, NULL_TREE);
4018 chainon (field_decl_chain, field_decl);
4020 finish_struct (objc_selector_template, field_decl_chain, NULL_TREE);
4023 /* struct objc_class {
4024 struct objc_class *isa;
4025 struct objc_class *super_class;
4030 struct objc_ivar_list *ivars;
4031 struct objc_method_list *methods;
4032 if (flag_next_runtime)
4033 struct objc_cache *cache;
4035 struct sarray *dtable;
4036 struct objc_class *subclass_list;
4037 struct objc_class *sibling_class;
4039 struct objc_protocol_list *protocols;
4040 if (flag_next_runtime)
4042 void *gc_object_type;
4045 /* NB: The 'sel_id' and 'gc_object_type' fields are not being used by
4046 the NeXT/Apple runtime; still, the compiler must generate them to
4047 maintain backward binary compatibility (and to allow for future
4051 build_class_template (void)
4053 tree decl_specs, field_decl, field_decl_chain;
4056 = start_struct (RECORD_TYPE, get_identifier (UTAG_CLASS));
4058 /* struct objc_class *isa; */
4060 decl_specs = build_tree_list (NULL_TREE, objc_class_template);
4061 field_decl = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("isa"));
4062 field_decl = grokfield (field_decl, decl_specs, NULL_TREE);
4063 field_decl_chain = field_decl;
4065 /* struct objc_class *super_class; */
4067 decl_specs = build_tree_list (NULL_TREE, objc_class_template);
4069 = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("super_class"));
4070 field_decl = grokfield (field_decl, decl_specs, NULL_TREE);
4071 chainon (field_decl_chain, field_decl);
4075 decl_specs = build_tree_list (NULL_TREE, ridpointers[(int) RID_CHAR]);
4076 field_decl = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("name"));
4077 field_decl = grokfield (field_decl, decl_specs, NULL_TREE);
4078 chainon (field_decl_chain, field_decl);
4082 decl_specs = build_tree_list (NULL_TREE, ridpointers[(int) RID_LONG]);
4083 field_decl = get_identifier ("version");
4084 field_decl = grokfield (field_decl, decl_specs, NULL_TREE);
4085 chainon (field_decl_chain, field_decl);
4089 decl_specs = build_tree_list (NULL_TREE, ridpointers[(int) RID_LONG]);
4090 field_decl = get_identifier ("info");
4091 field_decl = grokfield (field_decl, decl_specs, NULL_TREE);
4092 chainon (field_decl_chain, field_decl);
4094 /* long instance_size; */
4096 decl_specs = build_tree_list (NULL_TREE, ridpointers[(int) RID_LONG]);
4097 field_decl = get_identifier ("instance_size");
4098 field_decl = grokfield (field_decl, decl_specs, NULL_TREE);
4099 chainon (field_decl_chain, field_decl);
4101 /* struct objc_ivar_list *ivars; */
4103 decl_specs = build_tree_list (NULL_TREE,
4104 xref_tag (RECORD_TYPE,
4105 get_identifier (UTAG_IVAR_LIST)));
4106 field_decl = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("ivars"));
4107 field_decl = grokfield (field_decl, decl_specs, NULL_TREE);
4108 chainon (field_decl_chain, field_decl);
4110 /* struct objc_method_list *methods; */
4112 decl_specs = build_tree_list (NULL_TREE,
4113 xref_tag (RECORD_TYPE,
4114 get_identifier (UTAG_METHOD_LIST)));
4115 field_decl = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("methods"));
4116 field_decl = grokfield (field_decl, decl_specs, NULL_TREE);
4117 chainon (field_decl_chain, field_decl);
4119 if (flag_next_runtime)
4121 /* struct objc_cache *cache; */
4123 decl_specs = build_tree_list (NULL_TREE,
4124 xref_tag (RECORD_TYPE,
4125 get_identifier ("objc_cache")));
4126 field_decl = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("cache"));
4127 field_decl = grokfield (field_decl, decl_specs, NULL_TREE);
4128 chainon (field_decl_chain, field_decl);
4132 /* struct sarray *dtable; */
4134 decl_specs = build_tree_list (NULL_TREE,
4135 xref_tag (RECORD_TYPE,
4136 get_identifier ("sarray")));
4137 field_decl = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("dtable"));
4138 field_decl = grokfield (field_decl, decl_specs, NULL_TREE);
4139 chainon (field_decl_chain, field_decl);
4141 /* struct objc_class *subclass_list; */
4143 decl_specs = build_tree_list (NULL_TREE, objc_class_template);
4145 = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("subclass_list"));
4146 field_decl = grokfield (field_decl, decl_specs, NULL_TREE);
4147 chainon (field_decl_chain, field_decl);
4149 /* struct objc_class *sibling_class; */
4151 decl_specs = build_tree_list (NULL_TREE, objc_class_template);
4153 = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("sibling_class"));
4154 field_decl = grokfield (field_decl, decl_specs, NULL_TREE);
4155 chainon (field_decl_chain, field_decl);
4158 /* struct objc_protocol **protocol_list; */
4160 decl_specs = build_tree_list (NULL_TREE,
4161 xref_tag (RECORD_TYPE,
4162 get_identifier (UTAG_PROTOCOL)));
4164 = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("protocol_list"));
4166 = build1 (INDIRECT_REF, NULL_TREE, field_decl);
4167 field_decl = grokfield (field_decl, decl_specs, NULL_TREE);
4168 chainon (field_decl_chain, field_decl);
4170 if (flag_next_runtime)
4174 decl_specs = build_tree_list (NULL_TREE, ridpointers[(int) RID_VOID]);
4175 field_decl = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("sel_id"));
4177 = grokfield (field_decl, decl_specs, NULL_TREE);
4178 chainon (field_decl_chain, field_decl);
4181 /* void *gc_object_type; */
4183 decl_specs = build_tree_list (NULL_TREE, ridpointers[(int) RID_VOID]);
4184 field_decl = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("gc_object_type"));
4185 field_decl = grokfield (field_decl, decl_specs, NULL_TREE);
4186 chainon (field_decl_chain, field_decl);
4188 finish_struct (objc_class_template, field_decl_chain, NULL_TREE);
4191 /* Generate appropriate forward declarations for an implementation. */
4194 synth_forward_declarations (void)
4198 /* static struct objc_class _OBJC_CLASS_<my_name>; */
4199 UOBJC_CLASS_decl = build_metadata_decl ("_OBJC_CLASS",
4200 objc_class_template);
4202 /* static struct objc_class _OBJC_METACLASS_<my_name>; */
4203 UOBJC_METACLASS_decl = build_metadata_decl ("_OBJC_METACLASS",
4204 objc_class_template);
4206 mark_decl_referenced (UOBJC_CLASS_decl);
4207 mark_decl_referenced (UOBJC_METACLASS_decl);
4209 /* Pre-build the following entities - for speed/convenience. */
4211 an_id = get_identifier ("super_class");
4212 ucls_super_ref = build_component_ref (UOBJC_CLASS_decl, an_id);
4213 uucls_super_ref = build_component_ref (UOBJC_METACLASS_decl, an_id);
4217 error_with_ivar (const char *message, tree decl, tree rawdecl)
4219 error ("%J%s `%s'", decl,
4220 message, gen_declaration (rawdecl, errbuf));
4225 check_ivars (tree inter, tree imp)
4227 tree intdecls = CLASS_IVARS (inter);
4228 tree impdecls = CLASS_IVARS (imp);
4229 tree rawintdecls = CLASS_RAW_IVARS (inter);
4230 tree rawimpdecls = CLASS_RAW_IVARS (imp);
4237 if (intdecls && TREE_CODE (intdecls) == TYPE_DECL)
4238 intdecls = TREE_CHAIN (intdecls);
4240 if (intdecls == 0 && impdecls == 0)
4242 if (intdecls == 0 || impdecls == 0)
4244 error ("inconsistent instance variable specification");
4248 t1 = TREE_TYPE (intdecls); t2 = TREE_TYPE (impdecls);
4250 if (TREE_VALUE (TREE_VALUE (rawimpdecls)))
4252 /* t1 is the bit-field type, so t2 must be converted to the
4253 bit-field type for comparison as well. */
4254 unsigned HOST_WIDE_INT width
4255 = tree_low_cst (TREE_VALUE (TREE_VALUE (rawimpdecls)), 1);
4256 if (width != TYPE_PRECISION (t2))
4257 t2 = build_nonstandard_integer_type (width, TYPE_UNSIGNED (t2));
4260 if (!comptypes (t1, t2)
4261 || !tree_int_cst_equal (TREE_VALUE (TREE_VALUE (rawintdecls)),
4262 TREE_VALUE (TREE_VALUE (rawimpdecls))))
4264 if (DECL_NAME (intdecls) == DECL_NAME (impdecls))
4266 error_with_ivar ("conflicting instance variable type",
4267 impdecls, rawimpdecls);
4268 error_with_ivar ("previous declaration of",
4269 intdecls, rawintdecls);
4271 else /* both the type and the name don't match */
4273 error ("inconsistent instance variable specification");
4278 else if (DECL_NAME (intdecls) != DECL_NAME (impdecls))
4280 error_with_ivar ("conflicting instance variable name",
4281 impdecls, rawimpdecls);
4282 error_with_ivar ("previous declaration of",
4283 intdecls, rawintdecls);
4286 intdecls = TREE_CHAIN (intdecls);
4287 impdecls = TREE_CHAIN (impdecls);
4288 rawintdecls = TREE_CHAIN (rawintdecls);
4289 rawimpdecls = TREE_CHAIN (rawimpdecls);
4293 /* Set 'objc_super_template' to the data type node for 'struct _objc_super'.
4294 This needs to be done just once per compilation. */
4297 build_super_template (void)
4299 tree decl_specs, field_decl, field_decl_chain;
4301 /* Suppress outputting debug symbols, because
4302 dbxout_init hasn't been called yet. */
4303 enum debug_info_type save_write_symbols = write_symbols;
4304 const struct gcc_debug_hooks *save_hooks = debug_hooks;
4306 write_symbols = NO_DEBUG;
4307 debug_hooks = &do_nothing_debug_hooks;
4309 objc_super_template = start_struct (RECORD_TYPE, get_identifier (UTAG_SUPER));
4311 /* struct objc_object *self; */
4313 decl_specs = build_tree_list (NULL_TREE, objc_object_reference);
4314 field_decl = get_identifier ("self");
4315 field_decl = build1 (INDIRECT_REF, NULL_TREE, field_decl);
4316 field_decl = grokfield (field_decl, decl_specs, NULL_TREE);
4317 field_decl_chain = field_decl;
4320 /* struct objc_class *super_class; */
4322 /* struct objc_class *class; */
4325 decl_specs = get_identifier (UTAG_CLASS);
4326 decl_specs = build_tree_list (NULL_TREE, xref_tag (RECORD_TYPE, decl_specs));
4328 field_decl = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("super_class"));
4330 field_decl = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("class"));
4333 field_decl = grokfield (field_decl, decl_specs, NULL_TREE);
4334 chainon (field_decl_chain, field_decl);
4336 finish_struct (objc_super_template, field_decl_chain, NULL_TREE);
4338 write_symbols = save_write_symbols;
4339 debug_hooks = save_hooks;
4342 /* struct objc_ivar {
4349 build_ivar_template (void)
4351 tree objc_ivar_id, objc_ivar_record;
4352 tree decl_specs, field_decl, field_decl_chain;
4354 objc_ivar_id = get_identifier (UTAG_IVAR);
4355 objc_ivar_record = start_struct (RECORD_TYPE, objc_ivar_id);
4357 /* char *ivar_name; */
4359 decl_specs = build_tree_list (NULL_TREE, ridpointers[(int) RID_CHAR]);
4360 field_decl = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("ivar_name"));
4362 field_decl = grokfield (field_decl, decl_specs, NULL_TREE);
4363 field_decl_chain = field_decl;
4365 /* char *ivar_type; */
4367 decl_specs = build_tree_list (NULL_TREE, ridpointers[(int) RID_CHAR]);
4368 field_decl = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("ivar_type"));
4370 field_decl = grokfield (field_decl, decl_specs, NULL_TREE);
4371 chainon (field_decl_chain, field_decl);
4373 /* int ivar_offset; */
4375 decl_specs = build_tree_list (NULL_TREE, ridpointers[(int) RID_INT]);
4376 field_decl = get_identifier ("ivar_offset");
4378 field_decl = grokfield (field_decl, decl_specs, NULL_TREE);
4379 chainon (field_decl_chain, field_decl);
4381 finish_struct (objc_ivar_record, field_decl_chain, NULL_TREE);
4383 return objc_ivar_record;
4388 struct objc_ivar ivar_list[ivar_count];
4392 build_ivar_list_template (tree list_type, int size)
4394 tree objc_ivar_list_record;
4395 tree decl_specs, field_decl, field_decl_chain;
4397 objc_ivar_list_record = start_struct (RECORD_TYPE, NULL_TREE);
4399 /* int ivar_count; */
4401 decl_specs = build_tree_list (NULL_TREE, ridpointers[(int) RID_INT]);
4402 field_decl = get_identifier ("ivar_count");
4404 field_decl = grokfield (field_decl, decl_specs, NULL_TREE);
4405 field_decl_chain = field_decl;
4407 /* struct objc_ivar ivar_list[]; */
4409 decl_specs = build_tree_list (NULL_TREE, list_type);
4410 field_decl = build_nt (ARRAY_REF, get_identifier ("ivar_list"),
4411 build_int_cst (NULL_TREE, size), NULL_TREE, NULL_TREE);
4413 field_decl = grokfield (field_decl, decl_specs, NULL_TREE);
4414 chainon (field_decl_chain, field_decl);
4416 finish_struct (objc_ivar_list_record, field_decl_chain, NULL_TREE);
4418 return objc_ivar_list_record;
4424 struct objc_method method_list[method_count];
4428 build_method_list_template (tree list_type, int size)
4430 tree objc_ivar_list_record;
4431 tree decl_specs, field_decl, field_decl_chain;
4433 objc_ivar_list_record = start_struct (RECORD_TYPE, NULL_TREE);
4435 /* int method_next; */
4440 xref_tag (RECORD_TYPE,
4441 get_identifier (UTAG_METHOD_PROTOTYPE_LIST)));
4443 = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("method_next"));
4444 field_decl = grokfield (field_decl, decl_specs, NULL_TREE);
4445 field_decl_chain = field_decl;
4447 /* int method_count; */
4449 decl_specs = build_tree_list (NULL_TREE, ridpointers[(int) RID_INT]);
4450 field_decl = get_identifier ("method_count");
4452 field_decl = grokfield (field_decl, decl_specs, NULL_TREE);
4453 chainon (field_decl_chain, field_decl);
4455 /* struct objc_method method_list[]; */
4457 decl_specs = build_tree_list (NULL_TREE, list_type);
4458 field_decl = build_nt (ARRAY_REF, get_identifier ("method_list"),
4459 build_int_cst (NULL_TREE, size), NULL_TREE, NULL_TREE);
4461 field_decl = grokfield (field_decl, decl_specs, NULL_TREE);
4462 chainon (field_decl_chain, field_decl);
4464 finish_struct (objc_ivar_list_record, field_decl_chain, NULL_TREE);
4466 return objc_ivar_list_record;
4470 build_ivar_list_initializer (tree type, tree field_decl)
4472 tree initlist = NULL_TREE;
4476 tree ivar = NULL_TREE;
4479 if (DECL_NAME (field_decl))
4480 ivar = tree_cons (NULL_TREE,
4481 add_objc_string (DECL_NAME (field_decl),
4485 /* Unnamed bit-field ivar (yuck). */
4486 ivar = tree_cons (NULL_TREE, build_int_cst (NULL_TREE, 0), ivar);
4489 encode_field_decl (field_decl,
4490 obstack_object_size (&util_obstack),
4491 OBJC_ENCODE_DONT_INLINE_DEFS);
4493 /* Null terminate string. */
4494 obstack_1grow (&util_obstack, 0);
4498 add_objc_string (get_identifier (obstack_finish (&util_obstack)),
4501 obstack_free (&util_obstack, util_firstobj);
4504 ivar = tree_cons (NULL_TREE, byte_position (field_decl), ivar);
4505 initlist = tree_cons (NULL_TREE,
4506 objc_build_constructor (type, nreverse (ivar)),
4509 field_decl = TREE_CHAIN (field_decl);
4510 while (field_decl && TREE_CODE (field_decl) != FIELD_DECL);
4514 return objc_build_constructor (build_array_type (type, 0),
4515 nreverse (initlist));
4519 generate_ivars_list (tree type, const char *name, int size, tree list)
4521 tree sc_spec, decl_specs, decl, initlist;
4523 sc_spec = tree_cons (NULL_TREE, ridpointers[(int) RID_STATIC], NULL_TREE);
4524 decl_specs = tree_cons (NULL_TREE, type, sc_spec);
4526 decl = start_decl (synth_id_with_class_suffix (name, objc_implementation_context),
4527 decl_specs, 1, NULL_TREE);
4529 initlist = build_tree_list (NULL_TREE, build_int_cst (NULL_TREE, size));
4530 initlist = tree_cons (NULL_TREE, list, initlist);
4533 objc_build_constructor (TREE_TYPE (decl), nreverse (initlist)),
4539 /* Count only the fields occurring in T. */
4541 ivar_list_length (tree t)
4545 for (; t; t = TREE_CHAIN (t))
4546 if (TREE_CODE (t) == FIELD_DECL)
4553 generate_ivar_lists (void)
4555 tree initlist, ivar_list_template, chain;
4556 tree cast, variable_length_type;
4559 generating_instance_variables = 1;
4561 if (!objc_ivar_template)
4562 objc_ivar_template = build_ivar_template ();
4566 (build_tree_list (NULL_TREE, xref_tag (RECORD_TYPE,
4567 get_identifier (UTAG_IVAR_LIST))),
4569 variable_length_type = groktypename (cast);
4571 /* Only generate class variables for the root of the inheritance
4572 hierarchy since these will be the same for every class. */
4574 if (CLASS_SUPER_NAME (implementation_template) == NULL_TREE
4575 && (chain = TYPE_FIELDS (objc_class_template)))
4577 size = ivar_list_length (chain);
4579 ivar_list_template = build_ivar_list_template (objc_ivar_template, size);
4580 initlist = build_ivar_list_initializer (objc_ivar_template, chain);
4582 UOBJC_CLASS_VARIABLES_decl
4583 = generate_ivars_list (ivar_list_template, "_OBJC_CLASS_VARIABLES",
4585 TREE_TYPE (UOBJC_CLASS_VARIABLES_decl) = variable_length_type;
4588 UOBJC_CLASS_VARIABLES_decl = 0;
4590 chain = CLASS_IVARS (implementation_template);
4593 size = ivar_list_length (chain);
4594 ivar_list_template = build_ivar_list_template (objc_ivar_template, size);
4595 initlist = build_ivar_list_initializer (objc_ivar_template, chain);
4597 UOBJC_INSTANCE_VARIABLES_decl
4598 = generate_ivars_list (ivar_list_template, "_OBJC_INSTANCE_VARIABLES",
4600 TREE_TYPE (UOBJC_INSTANCE_VARIABLES_decl) = variable_length_type;
4603 UOBJC_INSTANCE_VARIABLES_decl = 0;
4605 generating_instance_variables = 0;
4609 build_dispatch_table_initializer (tree type, tree entries)
4611 tree initlist = NULL_TREE;
4615 tree elemlist = NULL_TREE;
4617 elemlist = tree_cons (NULL_TREE,
4618 build_selector (METHOD_SEL_NAME (entries)),
4621 /* Generate the method encoding if we don't have one already. */
4622 if (! METHOD_ENCODING (entries))
4623 METHOD_ENCODING (entries) =
4624 encode_method_prototype (entries);
4626 elemlist = tree_cons (NULL_TREE,
4627 add_objc_string (METHOD_ENCODING (entries),
4631 elemlist = tree_cons (NULL_TREE,
4632 build_unary_op (ADDR_EXPR,
4633 METHOD_DEFINITION (entries), 1),
4636 initlist = tree_cons (NULL_TREE,
4637 objc_build_constructor (type, nreverse (elemlist)),
4640 entries = TREE_CHAIN (entries);
4644 return objc_build_constructor (build_array_type (type, 0),
4645 nreverse (initlist));
4648 /* To accomplish method prototyping without generating all kinds of
4649 inane warnings, the definition of the dispatch table entries were
4652 struct objc_method { SEL _cmd; ...; id (*_imp)(); };
4654 struct objc_method { SEL _cmd; ...; void *_imp; }; */
4657 build_method_template (void)
4660 tree decl_specs, field_decl, field_decl_chain;
4662 _SLT_record = start_struct (RECORD_TYPE, get_identifier (UTAG_METHOD));
4664 /* struct objc_selector *_cmd; */
4665 decl_specs = tree_cons (NULL_TREE,
4666 xref_tag (RECORD_TYPE,
4667 get_identifier (TAG_SELECTOR)),
4669 field_decl = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("_cmd"));
4671 field_decl = grokfield (field_decl, decl_specs, NULL_TREE);
4672 field_decl_chain = field_decl;
4674 decl_specs = tree_cons (NULL_TREE, ridpointers[(int) RID_CHAR], NULL_TREE);
4675 field_decl = build1 (INDIRECT_REF, NULL_TREE,
4676 get_identifier ("method_types"));
4677 field_decl = grokfield (field_decl, decl_specs, NULL_TREE);
4678 chainon (field_decl_chain, field_decl);
4682 decl_specs = tree_cons (NULL_TREE, ridpointers[(int) RID_VOID], NULL_TREE);
4683 field_decl = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("_imp"));
4684 field_decl = grokfield (field_decl, decl_specs, NULL_TREE);
4685 chainon (field_decl_chain, field_decl);
4687 finish_struct (_SLT_record, field_decl_chain, NULL_TREE);
4694 generate_dispatch_table (tree type, const char *name, int size, tree list)
4696 tree sc_spec, decl_specs, decl, initlist;
4698 sc_spec = tree_cons (NULL_TREE, ridpointers[(int) RID_STATIC], NULL_TREE);
4699 decl_specs = tree_cons (NULL_TREE, type, sc_spec);
4701 decl = start_decl (synth_id_with_class_suffix (name, objc_implementation_context),
4702 decl_specs, 1, NULL_TREE);
4704 initlist = build_tree_list (NULL_TREE, build_int_cst (NULL_TREE, 0));
4705 initlist = tree_cons (NULL_TREE, build_int_cst (NULL_TREE, size), initlist);
4706 initlist = tree_cons (NULL_TREE, list, initlist);
4709 objc_build_constructor (TREE_TYPE (decl), nreverse (initlist)),
4716 mark_referenced_methods (void)
4718 struct imp_entry *impent;
4721 for (impent = imp_list; impent; impent = impent->next)
4723 chain = CLASS_CLS_METHODS (impent->imp_context);
4726 cgraph_mark_needed_node (cgraph_node (METHOD_DEFINITION (chain)));
4727 chain = TREE_CHAIN (chain);
4730 chain = CLASS_NST_METHODS (impent->imp_context);
4733 cgraph_mark_needed_node (cgraph_node (METHOD_DEFINITION (chain)));
4734 chain = TREE_CHAIN (chain);
4740 generate_dispatch_tables (void)
4742 tree initlist, chain, method_list_template;
4743 tree cast, variable_length_type;
4746 if (!objc_method_template)
4747 objc_method_template = build_method_template ();
4751 (build_tree_list (NULL_TREE,
4752 xref_tag (RECORD_TYPE,
4753 get_identifier (UTAG_METHOD_LIST))),
4756 variable_length_type = groktypename (cast);
4758 chain = CLASS_CLS_METHODS (objc_implementation_context);
4761 size = list_length (chain);
4763 method_list_template
4764 = build_method_list_template (objc_method_template, size);
4766 = build_dispatch_table_initializer (objc_method_template, chain);
4768 UOBJC_CLASS_METHODS_decl
4769 = generate_dispatch_table (method_list_template,
4770 ((TREE_CODE (objc_implementation_context)
4771 == CLASS_IMPLEMENTATION_TYPE)
4772 ? "_OBJC_CLASS_METHODS"
4773 : "_OBJC_CATEGORY_CLASS_METHODS"),
4775 TREE_TYPE (UOBJC_CLASS_METHODS_decl) = variable_length_type;
4778 UOBJC_CLASS_METHODS_decl = 0;
4780 chain = CLASS_NST_METHODS (objc_implementation_context);
4783 size = list_length (chain);
4785 method_list_template
4786 = build_method_list_template (objc_method_template, size);
4788 = build_dispatch_table_initializer (objc_method_template, chain);
4790 if (TREE_CODE (objc_implementation_context) == CLASS_IMPLEMENTATION_TYPE)
4791 UOBJC_INSTANCE_METHODS_decl
4792 = generate_dispatch_table (method_list_template,
4793 "_OBJC_INSTANCE_METHODS",
4796 /* We have a category. */
4797 UOBJC_INSTANCE_METHODS_decl
4798 = generate_dispatch_table (method_list_template,
4799 "_OBJC_CATEGORY_INSTANCE_METHODS",
4801 TREE_TYPE (UOBJC_INSTANCE_METHODS_decl) = variable_length_type;
4804 UOBJC_INSTANCE_METHODS_decl = 0;
4808 generate_protocol_list (tree i_or_p)
4810 tree initlist, decl_specs, sc_spec;
4811 tree refs_decl, expr_decl, lproto, e, plist;
4815 if (TREE_CODE (i_or_p) == CLASS_INTERFACE_TYPE
4816 || TREE_CODE (i_or_p) == CATEGORY_INTERFACE_TYPE)
4817 plist = CLASS_PROTOCOL_LIST (i_or_p);
4818 else if (TREE_CODE (i_or_p) == PROTOCOL_INTERFACE_TYPE)
4819 plist = PROTOCOL_LIST (i_or_p);
4823 cast_type = groktypename
4825 (build_tree_list (NULL_TREE,
4826 xref_tag (RECORD_TYPE,
4827 get_identifier (UTAG_PROTOCOL))),
4828 build1 (INDIRECT_REF, NULL_TREE, NULL_TREE)));
4831 for (lproto = plist; lproto; lproto = TREE_CHAIN (lproto))
4832 if (TREE_CODE (TREE_VALUE (lproto)) == PROTOCOL_INTERFACE_TYPE
4833 && PROTOCOL_FORWARD_DECL (TREE_VALUE (lproto)))
4836 /* Build initializer. */
4837 initlist = tree_cons (NULL_TREE, build_int_cst (NULL_TREE, 0), NULL_TREE);
4839 e = build_int_cst (cast_type, size);
4840 initlist = tree_cons (NULL_TREE, e, initlist);
4842 for (lproto = plist; lproto; lproto = TREE_CHAIN (lproto))
4844 tree pval = TREE_VALUE (lproto);
4846 if (TREE_CODE (pval) == PROTOCOL_INTERFACE_TYPE
4847 && PROTOCOL_FORWARD_DECL (pval))
4849 e = build_unary_op (ADDR_EXPR, PROTOCOL_FORWARD_DECL (pval), 0);
4850 initlist = tree_cons (NULL_TREE, e, initlist);
4854 /* static struct objc_protocol *refs[n]; */
4856 sc_spec = tree_cons (NULL_TREE, ridpointers[(int) RID_STATIC], NULL_TREE);
4857 decl_specs = tree_cons (NULL_TREE, xref_tag (RECORD_TYPE,
4858 get_identifier (UTAG_PROTOCOL)),
4861 if (TREE_CODE (i_or_p) == PROTOCOL_INTERFACE_TYPE)
4862 expr_decl = build_nt (ARRAY_REF,
4863 synth_id_with_class_suffix ("_OBJC_PROTOCOL_REFS",
4865 build_int_cst (NULL_TREE, size + 2), NULL_TREE, NULL_TREE);
4866 else if (TREE_CODE (i_or_p) == CLASS_INTERFACE_TYPE)
4867 expr_decl = build_nt (ARRAY_REF,
4868 synth_id_with_class_suffix ("_OBJC_CLASS_PROTOCOLS",
4870 build_int_cst (NULL_TREE, size + 2), NULL_TREE, NULL_TREE);
4871 else if (TREE_CODE (i_or_p) == CATEGORY_INTERFACE_TYPE)
4873 = build_nt (ARRAY_REF,
4874 synth_id_with_class_suffix ("_OBJC_CATEGORY_PROTOCOLS",
4876 build_int_cst (NULL_TREE, size + 2), NULL_TREE, NULL_TREE);
4880 expr_decl = build1 (INDIRECT_REF, NULL_TREE, expr_decl);
4882 refs_decl = start_decl (expr_decl, decl_specs, 1, NULL_TREE);
4883 DECL_CONTEXT (refs_decl) = NULL_TREE;
4885 finish_decl (refs_decl, objc_build_constructor (TREE_TYPE (refs_decl),
4886 nreverse (initlist)),
4893 build_category_initializer (tree type, tree cat_name, tree class_name,
4894 tree instance_methods, tree class_methods,
4897 tree initlist = NULL_TREE, expr;
4899 initlist = tree_cons (NULL_TREE, cat_name, initlist);
4900 initlist = tree_cons (NULL_TREE, class_name, initlist);
4902 if (!instance_methods)
4903 initlist = tree_cons (NULL_TREE, build_int_cst (NULL_TREE, 0), initlist);
4906 expr = build_unary_op (ADDR_EXPR, instance_methods, 0);
4907 initlist = tree_cons (NULL_TREE, expr, initlist);
4910 initlist = tree_cons (NULL_TREE, build_int_cst (NULL_TREE, 0), initlist);
4913 expr = build_unary_op (ADDR_EXPR, class_methods, 0);
4914 initlist = tree_cons (NULL_TREE, expr, initlist);
4917 /* protocol_list = */
4919 initlist = tree_cons (NULL_TREE, build_int_cst (NULL_TREE, 0), initlist);
4922 tree cast_type2 = groktypename
4924 (build_tree_list (NULL_TREE,
4925 xref_tag (RECORD_TYPE,
4926 get_identifier (UTAG_PROTOCOL))),
4927 build1 (INDIRECT_REF, NULL_TREE,
4928 build1 (INDIRECT_REF, NULL_TREE, NULL_TREE))));
4930 expr = build_unary_op (ADDR_EXPR, protocol_list, 0);
4931 TREE_TYPE (expr) = cast_type2;
4932 initlist = tree_cons (NULL_TREE, expr, initlist);
4935 return objc_build_constructor (type, nreverse (initlist));
4938 /* struct objc_class {
4939 struct objc_class *isa;
4940 struct objc_class *super_class;
4945 struct objc_ivar_list *ivars;
4946 struct objc_method_list *methods;
4947 if (flag_next_runtime)
4948 struct objc_cache *cache;
4950 struct sarray *dtable;
4951 struct objc_class *subclass_list;
4952 struct objc_class *sibling_class;
4954 struct objc_protocol_list *protocols;
4955 if (flag_next_runtime)
4957 void *gc_object_type;
4961 build_shared_structure_initializer (tree type, tree isa, tree super,
4962 tree name, tree size, int status,
4963 tree dispatch_table, tree ivar_list,
4966 tree initlist = NULL_TREE, expr;
4969 initlist = tree_cons (NULL_TREE, isa, initlist);
4972 initlist = tree_cons (NULL_TREE, super, initlist);
4975 initlist = tree_cons (NULL_TREE, default_conversion (name), initlist);
4978 initlist = tree_cons (NULL_TREE, build_int_cst (NULL_TREE, 0), initlist);
4981 initlist = tree_cons (NULL_TREE, build_int_cst (NULL_TREE, status), initlist);
4983 /* instance_size = */
4984 initlist = tree_cons (NULL_TREE, size, initlist);
4986 /* objc_ivar_list = */
4988 initlist = tree_cons (NULL_TREE, build_int_cst (NULL_TREE, 0), initlist);
4991 expr = build_unary_op (ADDR_EXPR, ivar_list, 0);
4992 initlist = tree_cons (NULL_TREE, expr, initlist);
4995 /* objc_method_list = */
4996 if (!dispatch_table)
4997 initlist = tree_cons (NULL_TREE, build_int_cst (NULL_TREE, 0), initlist);
5000 expr = build_unary_op (ADDR_EXPR, dispatch_table, 0);
5001 initlist = tree_cons (NULL_TREE, expr, initlist);
5004 if (flag_next_runtime)
5005 /* method_cache = */
5006 initlist = tree_cons (NULL_TREE, build_int_cst (NULL_TREE, 0), initlist);
5010 initlist = tree_cons (NULL_TREE, build_int_cst (NULL_TREE, 0), initlist);
5012 /* subclass_list = */
5013 initlist = tree_cons (NULL_TREE, build_int_cst (NULL_TREE, 0), initlist);
5015 /* sibling_class = */
5016 initlist = tree_cons (NULL_TREE, build_int_cst (NULL_TREE, 0), initlist);
5019 /* protocol_list = */
5020 if (! protocol_list)
5021 initlist = tree_cons (NULL_TREE, build_int_cst (NULL_TREE, 0), initlist);
5027 (build_tree_list (NULL_TREE,
5028 xref_tag (RECORD_TYPE,
5029 get_identifier (UTAG_PROTOCOL))),
5030 build1 (INDIRECT_REF, NULL_TREE,
5031 build1 (INDIRECT_REF, NULL_TREE, NULL_TREE))));
5033 expr = build_unary_op (ADDR_EXPR, protocol_list, 0);
5034 TREE_TYPE (expr) = cast_type2;
5035 initlist = tree_cons (NULL_TREE, expr, initlist);
5038 if (flag_next_runtime)
5040 initlist = tree_cons (NULL_TREE, build_int_cst (NULL_TREE, 0), initlist);
5042 /* gc_object_type = NULL */
5043 initlist = tree_cons (NULL_TREE, build_int_cst (NULL_TREE, 0), initlist);
5045 return objc_build_constructor (type, nreverse (initlist));
5048 /* Retrieve category interface CAT_NAME (if any) associated with CLASS. */
5051 lookup_category (tree class, tree cat_name)
5053 tree category = CLASS_CATEGORY_LIST (class);
5055 while (category && CLASS_SUPER_NAME (category) != cat_name)
5056 category = CLASS_CATEGORY_LIST (category);
5060 /* static struct objc_category _OBJC_CATEGORY_<name> = { ... }; */
5063 generate_category (tree cat)
5065 tree sc_spec, decl_specs, decl;
5066 tree initlist, cat_name_expr, class_name_expr;
5067 tree protocol_decl, category;
5069 add_class_reference (CLASS_NAME (cat));
5070 cat_name_expr = add_objc_string (CLASS_SUPER_NAME (cat), class_names);
5072 class_name_expr = add_objc_string (CLASS_NAME (cat), class_names);
5074 category = lookup_category (implementation_template,
5075 CLASS_SUPER_NAME (cat));
5077 if (category && CLASS_PROTOCOL_LIST (category))
5079 generate_protocol_references (CLASS_PROTOCOL_LIST (category));
5080 protocol_decl = generate_protocol_list (category);
5085 sc_spec = tree_cons (NULL_TREE, ridpointers[(int) RID_STATIC], NULL_TREE);
5086 decl_specs = tree_cons (NULL_TREE, objc_category_template, sc_spec);
5088 decl = start_decl (synth_id_with_class_suffix ("_OBJC_CATEGORY",
5089 objc_implementation_context),
5090 decl_specs, 1, NULL_TREE);
5092 initlist = build_category_initializer (TREE_TYPE (decl),
5093 cat_name_expr, class_name_expr,
5094 UOBJC_INSTANCE_METHODS_decl,
5095 UOBJC_CLASS_METHODS_decl,
5098 finish_decl (decl, initlist, NULL_TREE);
5101 /* static struct objc_class _OBJC_METACLASS_Foo={ ... };
5102 static struct objc_class _OBJC_CLASS_Foo={ ... }; */
5105 generate_shared_structures (void)
5107 tree sc_spec, decl_specs, decl;
5108 tree name_expr, super_expr, root_expr;
5109 tree my_root_id = NULL_TREE, my_super_id = NULL_TREE;
5110 tree cast_type, initlist, protocol_decl;
5112 my_super_id = CLASS_SUPER_NAME (implementation_template);
5115 add_class_reference (my_super_id);
5117 /* Compute "my_root_id" - this is required for code generation.
5118 the "isa" for all meta class structures points to the root of
5119 the inheritance hierarchy (e.g. "__Object")... */
5120 my_root_id = my_super_id;
5123 tree my_root_int = lookup_interface (my_root_id);
5125 if (my_root_int && CLASS_SUPER_NAME (my_root_int))
5126 my_root_id = CLASS_SUPER_NAME (my_root_int);
5133 /* No super class. */
5134 my_root_id = CLASS_NAME (implementation_template);
5137 = groktypename (build_tree_list (build_tree_list (NULL_TREE,
5138 objc_class_template),
5139 build1 (INDIRECT_REF,
5140 NULL_TREE, NULL_TREE)));
5142 name_expr = add_objc_string (CLASS_NAME (implementation_template),
5145 /* Install class `isa' and `super' pointers at runtime. */
5148 super_expr = add_objc_string (my_super_id, class_names);
5149 super_expr = build_c_cast (cast_type, super_expr); /* cast! */
5152 super_expr = build_int_cst (NULL_TREE, 0);
5154 root_expr = add_objc_string (my_root_id, class_names);
5155 root_expr = build_c_cast (cast_type, root_expr); /* cast! */
5157 if (CLASS_PROTOCOL_LIST (implementation_template))
5159 generate_protocol_references
5160 (CLASS_PROTOCOL_LIST (implementation_template));
5161 protocol_decl = generate_protocol_list (implementation_template);
5166 /* static struct objc_class _OBJC_METACLASS_Foo = { ... }; */
5168 sc_spec = build_tree_list (NULL_TREE, ridpointers[(int) RID_STATIC]);
5169 decl_specs = tree_cons (NULL_TREE, objc_class_template, sc_spec);
5171 decl = start_decl (DECL_NAME (UOBJC_METACLASS_decl), decl_specs, 1,
5175 = build_shared_structure_initializer
5177 root_expr, super_expr, name_expr,
5178 convert (integer_type_node, TYPE_SIZE_UNIT (objc_class_template)),
5180 UOBJC_CLASS_METHODS_decl,
5181 UOBJC_CLASS_VARIABLES_decl,
5184 finish_decl (decl, initlist, NULL_TREE);
5186 /* static struct objc_class _OBJC_CLASS_Foo={ ... }; */
5188 decl = start_decl (DECL_NAME (UOBJC_CLASS_decl), decl_specs, 1,
5192 = build_shared_structure_initializer
5194 build_unary_op (ADDR_EXPR, UOBJC_METACLASS_decl, 0),
5195 super_expr, name_expr,
5196 convert (integer_type_node,
5197 TYPE_SIZE_UNIT (CLASS_STATIC_TEMPLATE
5198 (implementation_template))),
5200 UOBJC_INSTANCE_METHODS_decl,
5201 UOBJC_INSTANCE_VARIABLES_decl,
5204 finish_decl (decl, initlist, NULL_TREE);
5208 synth_id_with_class_suffix (const char *preamble, tree ctxt)
5211 if (TREE_CODE (ctxt) == CLASS_IMPLEMENTATION_TYPE
5212 || TREE_CODE (ctxt) == CLASS_INTERFACE_TYPE)
5214 const char *const class_name
5215 = IDENTIFIER_POINTER (CLASS_NAME (objc_implementation_context));
5216 string = (char *) alloca (strlen (preamble) + strlen (class_name) + 3);
5217 sprintf (string, "%s_%s", preamble,
5218 IDENTIFIER_POINTER (CLASS_NAME (ctxt)));
5220 else if (TREE_CODE (ctxt) == CATEGORY_IMPLEMENTATION_TYPE
5221 || TREE_CODE (ctxt) == CATEGORY_INTERFACE_TYPE)
5223 /* We have a category. */
5224 const char *const class_name
5225 = IDENTIFIER_POINTER (CLASS_NAME (objc_implementation_context));
5226 const char *const class_super_name
5227 = IDENTIFIER_POINTER (CLASS_SUPER_NAME (objc_implementation_context));
5228 string = (char *) alloca (strlen (preamble)
5229 + strlen (class_name)
5230 + strlen (class_super_name)
5232 sprintf (string, "%s_%s_%s", preamble, class_name, class_super_name);
5234 else if (TREE_CODE (ctxt) == PROTOCOL_INTERFACE_TYPE)
5236 const char *protocol_name = IDENTIFIER_POINTER (PROTOCOL_NAME (ctxt));
5238 = (char *) alloca (strlen (preamble) + strlen (protocol_name) + 3);
5239 sprintf (string, "%s_%s", preamble, protocol_name);
5244 return get_identifier (string);
5248 is_objc_type_qualifier (tree node)
5250 return (TREE_CODE (node) == IDENTIFIER_NODE
5251 && (node == ridpointers [(int) RID_CONST]
5252 || node == ridpointers [(int) RID_VOLATILE]
5253 || node == ridpointers [(int) RID_IN]
5254 || node == ridpointers [(int) RID_OUT]
5255 || node == ridpointers [(int) RID_INOUT]
5256 || node == ridpointers [(int) RID_BYCOPY]
5257 || node == ridpointers [(int) RID_BYREF]
5258 || node == ridpointers [(int) RID_ONEWAY]));
5261 /* If type is empty or only type qualifiers are present, add default
5262 type of id (otherwise grokdeclarator will default to int). */
5265 adjust_type_for_id_default (tree type)
5267 tree declspecs, chain;
5270 return build_tree_list (build_tree_list (NULL_TREE, objc_object_reference),
5271 build1 (INDIRECT_REF, NULL_TREE, NULL_TREE));
5273 declspecs = TREE_PURPOSE (type);
5275 /* Determine if a typespec is present. */
5276 for (chain = declspecs;
5278 chain = TREE_CHAIN (chain))
5280 if (TYPED_OBJECT (TREE_VALUE (chain))
5281 && !(TREE_VALUE (type)
5282 && TREE_CODE (TREE_VALUE (type)) == INDIRECT_REF))
5283 error ("can not use an object as parameter to a method\n");
5284 if (!is_objc_type_qualifier (TREE_VALUE (chain)))
5288 return build_tree_list (tree_cons (NULL_TREE, objc_object_reference,
5290 build1 (INDIRECT_REF, NULL_TREE, NULL_TREE));
5295 selector ':' '(' typename ')' identifier
5298 Transform an Objective-C keyword argument into
5299 the C equivalent parameter declarator.
5301 In: key_name, an "identifier_node" (optional).
5302 arg_type, a "tree_list" (optional).
5303 arg_name, an "identifier_node".
5305 Note: It would be really nice to strongly type the preceding
5306 arguments in the function prototype; however, then I
5307 could not use the "accessor" macros defined in "tree.h".
5309 Out: an instance of "keyword_decl". */
5312 build_keyword_decl (tree key_name, tree arg_type, tree arg_name)
5316 /* If no type is specified, default to "id". */
5317 arg_type = adjust_type_for_id_default (arg_type);
5319 keyword_decl = make_node (KEYWORD_DECL);
5321 TREE_TYPE (keyword_decl) = arg_type;
5322 KEYWORD_ARG_NAME (keyword_decl) = arg_name;
5323 KEYWORD_KEY_NAME (keyword_decl) = key_name;
5325 return keyword_decl;
5328 /* Given a chain of keyword_decl's, synthesize the full keyword selector. */
5331 build_keyword_selector (tree selector)
5334 tree key_chain, key_name;
5337 /* Scan the selector to see how much space we'll need. */
5338 for (key_chain = selector; key_chain; key_chain = TREE_CHAIN (key_chain))
5340 if (TREE_CODE (selector) == KEYWORD_DECL)
5341 key_name = KEYWORD_KEY_NAME (key_chain);
5342 else if (TREE_CODE (selector) == TREE_LIST)
5343 key_name = TREE_PURPOSE (key_chain);
5348 len += IDENTIFIER_LENGTH (key_name) + 1;
5350 /* Just a ':' arg. */
5354 buf = (char *) alloca (len + 1);
5355 /* Start the buffer out as an empty string. */
5358 for (key_chain = selector; key_chain; key_chain = TREE_CHAIN (key_chain))
5360 if (TREE_CODE (selector) == KEYWORD_DECL)
5361 key_name = KEYWORD_KEY_NAME (key_chain);
5362 else if (TREE_CODE (selector) == TREE_LIST)
5364 key_name = TREE_PURPOSE (key_chain);
5365 /* The keyword decl chain will later be used as a function argument
5366 chain. Unhook the selector itself so as to not confuse other
5367 parts of the compiler. */
5368 TREE_PURPOSE (key_chain) = NULL_TREE;
5374 strcat (buf, IDENTIFIER_POINTER (key_name));
5378 return get_identifier (buf);
5381 /* Used for declarations and definitions. */
5384 build_method_decl (enum tree_code code, tree ret_type, tree selector,
5389 /* If no type is specified, default to "id". */
5390 ret_type = adjust_type_for_id_default (ret_type);
5392 method_decl = make_node (code);
5393 TREE_TYPE (method_decl) = ret_type;
5395 /* If we have a keyword selector, create an identifier_node that
5396 represents the full selector name (`:' included)... */
5397 if (TREE_CODE (selector) == KEYWORD_DECL)
5399 METHOD_SEL_NAME (method_decl) = build_keyword_selector (selector);
5400 METHOD_SEL_ARGS (method_decl) = selector;
5401 METHOD_ADD_ARGS (method_decl) = add_args;
5405 METHOD_SEL_NAME (method_decl) = selector;
5406 METHOD_SEL_ARGS (method_decl) = NULL_TREE;
5407 METHOD_ADD_ARGS (method_decl) = NULL_TREE;
5413 #define METHOD_DEF 0
5414 #define METHOD_REF 1
5416 /* Used by `build_objc_method_call' and `comp_proto_with_proto'. Return
5417 an argument list for method METH. CONTEXT is either METHOD_DEF or
5418 METHOD_REF, saying whether we are trying to define a method or call
5419 one. SUPERFLAG says this is for a send to super; this makes a
5420 difference for the NeXT calling sequence in which the lookup and
5421 the method call are done together. If METH is null, user-defined
5422 arguments (i.e., beyond self and _cmd) shall be represented by `...'. */
5425 get_arg_type_list (tree meth, int context, int superflag)
5429 /* Receiver type. */
5430 if (flag_next_runtime && superflag)
5431 arglist = build_tree_list (NULL_TREE, objc_super_type);
5432 else if (context == METHOD_DEF)
5433 arglist = build_tree_list (NULL_TREE, TREE_TYPE (self_decl));
5435 arglist = build_tree_list (NULL_TREE, objc_id_type);
5437 /* Selector type - will eventually change to `int'. */
5438 chainon (arglist, build_tree_list (NULL_TREE, objc_selector_type));
5440 /* No actual method prototype given -- assume that remaining arguments
5445 /* Build a list of argument types. */
5446 for (akey = METHOD_SEL_ARGS (meth); akey; akey = TREE_CHAIN (akey))
5448 tree arg_decl = groktypename_in_parm_context (TREE_TYPE (akey));
5449 chainon (arglist, build_tree_list (NULL_TREE, TREE_TYPE (arg_decl)));
5452 if (METHOD_ADD_ARGS (meth) == objc_ellipsis_node)
5453 /* We have a `, ...' immediately following the selector,
5454 finalize the arglist...simulate get_parm_info (true). */
5456 else if (METHOD_ADD_ARGS (meth))
5458 /* we have a variable length selector */
5459 tree add_arg_list = TREE_CHAIN (METHOD_ADD_ARGS (meth));
5460 chainon (arglist, add_arg_list);
5463 /* finalize the arglist...simulate get_parm_info (false) */
5464 chainon (arglist, void_list_node);
5470 check_duplicates (hash hsh, int methods, int is_class)
5472 tree meth = NULL_TREE;
5480 /* We have two or more methods with the same name but
5484 warning ("multiple %s named `%c%s' found",
5485 methods ? "methods" : "selectors",
5486 (is_class ? '+' : '-'),
5487 IDENTIFIER_POINTER (METHOD_SEL_NAME (meth)));
5489 warn_with_method (methods ? "using" : "found",
5490 ((TREE_CODE (meth) == INSTANCE_METHOD_DECL)
5494 for (loop = hsh->list; loop; loop = loop->next)
5495 warn_with_method ("also found",
5496 ((TREE_CODE (loop->value) == INSTANCE_METHOD_DECL)
5505 /* If RECEIVER is a class reference, return the identifier node for
5506 the referenced class. RECEIVER is created by get_class_reference,
5507 so we check the exact form created depending on which runtimes are
5511 receiver_is_class_object (tree receiver, int self, int super)
5513 tree chain, exp, arg;
5515 /* The receiver is 'self' or 'super' in the context of a class method. */
5516 if (objc_method_context
5517 && TREE_CODE (objc_method_context) == CLASS_METHOD_DECL
5520 ? CLASS_SUPER_NAME (implementation_template)
5521 : CLASS_NAME (implementation_template));
5523 if (flag_next_runtime)
5525 /* The receiver is a variable created by
5526 build_class_reference_decl. */
5527 if (TREE_CODE (receiver) == VAR_DECL
5528 && TREE_TYPE (TREE_TYPE (receiver)) == TREE_TYPE (objc_class_type))
5529 /* Look up the identifier. */
5530 for (chain = cls_ref_chain; chain; chain = TREE_CHAIN (chain))
5531 if (TREE_PURPOSE (chain) == receiver)
5532 return TREE_VALUE (chain);
5535 /* The receiver is a function call that returns an id. Check if
5536 it is a call to objc_getClass, if so, pick up the class name. */
5537 if (TREE_CODE (receiver) == CALL_EXPR
5538 && (exp = TREE_OPERAND (receiver, 0))
5539 && TREE_CODE (exp) == ADDR_EXPR
5540 && (exp = TREE_OPERAND (exp, 0))
5541 && TREE_CODE (exp) == FUNCTION_DECL
5542 /* For some reason, we sometimes wind up with multiple FUNCTION_DECL
5543 prototypes for objc_get_class(). Thankfully, they seem to share the
5544 same function type. */
5545 && TREE_TYPE (exp) == TREE_TYPE (objc_get_class_decl)
5546 && !strcmp (IDENTIFIER_POINTER (DECL_NAME (exp)), TAG_GETCLASS)
5547 /* We have a call to objc_get_class/objc_getClass! */
5548 && (arg = TREE_OPERAND (receiver, 1))
5549 && TREE_CODE (arg) == TREE_LIST
5550 && (arg = TREE_VALUE (arg)))
5553 if (TREE_CODE (arg) == ADDR_EXPR
5554 && (arg = TREE_OPERAND (arg, 0))
5555 && TREE_CODE (arg) == STRING_CST)
5556 /* Finally, we have the class name. */
5557 return get_identifier (TREE_STRING_POINTER (arg));
5562 /* If we are currently building a message expr, this holds
5563 the identifier of the selector of the message. This is
5564 used when printing warnings about argument mismatches. */
5566 static tree current_objc_message_selector = 0;
5569 objc_message_selector (void)
5571 return current_objc_message_selector;
5574 /* Construct an expression for sending a message.
5575 MESS has the object to send to in TREE_PURPOSE
5576 and the argument list (including selector) in TREE_VALUE.
5578 (*(<abstract_decl>(*)())_msg)(receiver, selTransTbl[n], ...);
5579 (*(<abstract_decl>(*)())_msgSuper)(receiver, selTransTbl[n], ...); */
5582 build_message_expr (tree mess)
5584 tree receiver = TREE_PURPOSE (mess);
5586 tree args = TREE_VALUE (mess);
5587 tree method_params = NULL_TREE;
5589 if (TREE_CODE (receiver) == ERROR_MARK)
5590 return error_mark_node;
5592 /* Obtain the full selector name. */
5593 if (TREE_CODE (args) == IDENTIFIER_NODE)
5594 /* A unary selector. */
5596 else if (TREE_CODE (args) == TREE_LIST)
5597 sel_name = build_keyword_selector (args);
5601 /* Build the parameter list to give to the method. */
5602 if (TREE_CODE (args) == TREE_LIST)
5604 tree chain = args, prev = NULL_TREE;
5606 /* We have a keyword selector--check for comma expressions. */
5609 tree element = TREE_VALUE (chain);
5611 /* We have a comma expression, must collapse... */
5612 if (TREE_CODE (element) == TREE_LIST)
5615 TREE_CHAIN (prev) = element;
5620 chain = TREE_CHAIN (chain);
5622 method_params = args;
5626 if (processing_template_decl)
5627 /* Must wait until template instantiation time. */
5628 return build_min_nt (MESSAGE_SEND_EXPR, receiver, sel_name,
5632 return finish_message_expr (receiver, sel_name, method_params);
5635 /* Look up method SEL_NAME that would be suitable for receiver
5636 of type 'id' (if IS_CLASS is zero) or 'Class' (if IS_CLASS is
5637 nonzero), and report on any duplicates. */
5640 lookup_method_in_hash_lists (tree sel_name, int is_class)
5642 hash method_prototype = NULL;
5645 method_prototype = hash_lookup (nst_method_hash_list,
5648 if (!method_prototype)
5650 method_prototype = hash_lookup (cls_method_hash_list,
5655 return check_duplicates (method_prototype, 1, is_class);
5658 /* The 'finish_message_expr' routine is called from within
5659 'build_message_expr' for non-template functions. In the case of
5660 C++ template functions, it is called from 'build_expr_from_tree'
5661 (in decl2.c) after RECEIVER and METHOD_PARAMS have been expanded. */
5664 finish_message_expr (tree receiver, tree sel_name, tree method_params)
5666 tree method_prototype = NULL_TREE, rprotos = NULL_TREE, rtype;
5667 tree selector, retval, class_tree;
5668 int self, super, have_cast;
5670 /* Extract the receiver of the message, as well as its type
5671 (where the latter may take the form of a cast or be inferred
5672 from the implementation context). */
5674 while (TREE_CODE (rtype) == COMPOUND_EXPR
5675 || TREE_CODE (rtype) == MODIFY_EXPR
5676 || TREE_CODE (rtype) == NOP_EXPR
5677 || TREE_CODE (rtype) == COMPONENT_REF)
5678 rtype = TREE_OPERAND (rtype, 0);
5679 self = (rtype == self_decl);
5680 super = (rtype == UOBJC_SUPER_decl);
5681 rtype = TREE_TYPE (receiver);
5682 have_cast = (TREE_CODE (receiver) == NOP_EXPR
5683 || (TREE_CODE (receiver) == COMPOUND_EXPR
5684 && !IS_SUPER (rtype)));
5686 /* If the receiver is a class object, retrieve the corresponding
5687 @interface, if one exists. */
5688 class_tree = receiver_is_class_object (receiver, self, super);
5690 /* Now determine the receiver type (if an explicit cast has not been
5695 rtype = lookup_interface (class_tree);
5696 /* Handle `self' and `super'. */
5699 if (!CLASS_SUPER_NAME (implementation_template))
5701 error ("no super class declared in @interface for `%s'",
5702 IDENTIFIER_POINTER (CLASS_NAME (implementation_template)));
5703 return error_mark_node;
5705 rtype = lookup_interface (CLASS_SUPER_NAME (implementation_template));
5708 rtype = lookup_interface (CLASS_NAME (implementation_template));
5711 /* If receiver is of type `id' or `Class' (or if the @interface for a
5712 class is not visible), we shall be satisfied with the existence of
5713 any instance or class method. */
5714 if (!rtype || IS_ID (rtype)
5715 || TREE_TYPE (rtype) == TREE_TYPE (objc_class_type))
5718 rtype = xref_tag (RECORD_TYPE, class_tree);
5719 else if (IS_ID (rtype))
5721 rprotos = TYPE_PROTOCOL_LIST (rtype);
5725 class_tree = TYPE_NAME (rtype) = get_identifier ("Class");
5729 = lookup_method_in_protocol_list (rprotos, sel_name,
5730 class_tree != NULL_TREE);
5731 if (!method_prototype && !rprotos)
5733 = lookup_method_in_hash_lists (sel_name,
5734 class_tree != NULL_TREE);
5738 tree orig_rtype = rtype, saved_rtype;
5740 if (TREE_CODE (rtype) == POINTER_TYPE)
5741 rtype = TREE_TYPE (rtype);
5742 /* Traverse typedef aliases */
5743 while (TREE_CODE (rtype) == RECORD_TYPE && TYPE_NAME (rtype)
5744 && TREE_CODE (TYPE_NAME (rtype)) == TYPE_DECL
5745 && DECL_ORIGINAL_TYPE (TYPE_NAME (rtype)))
5746 rtype = DECL_ORIGINAL_TYPE (TYPE_NAME (rtype));
5747 saved_rtype = rtype;
5748 if (TYPED_OBJECT (rtype))
5750 rprotos = TYPE_PROTOCOL_LIST (rtype);
5751 rtype = lookup_interface (OBJC_TYPE_NAME (rtype));
5753 /* If we could not find an @interface declaration, we must have
5754 only seen a @class declaration; so, we cannot say anything
5755 more intelligent about which methods the receiver will
5758 rtype = saved_rtype;
5759 else if (TREE_CODE (rtype) == CLASS_INTERFACE_TYPE
5760 || TREE_CODE (rtype) == CLASS_IMPLEMENTATION_TYPE)
5762 /* We have a valid ObjC class name. Look up the method name
5763 in the published @interface for the class (and its
5766 = lookup_method_static (rtype, sel_name, class_tree != NULL_TREE);
5768 /* If the method was not found in the @interface, it may still
5769 exist locally as part of the @implementation. */
5770 if (!method_prototype && objc_implementation_context
5771 && CLASS_NAME (objc_implementation_context)
5772 == OBJC_TYPE_NAME (rtype))
5776 ? CLASS_CLS_METHODS (objc_implementation_context)
5777 : CLASS_NST_METHODS (objc_implementation_context)),
5780 /* If we haven't found a candidate method by now, try looking for
5781 it in the protocol list. */
5782 if (!method_prototype && rprotos)
5784 = lookup_method_in_protocol_list (rprotos, sel_name,
5785 class_tree != NULL_TREE);
5789 warning ("invalid receiver type `%s'",
5790 gen_declaration (orig_rtype, errbuf));
5791 rtype = rprotos = NULL_TREE;
5795 if (!method_prototype)
5797 static bool warn_missing_methods = false;
5800 warning ("`%s' may not respond to `%c%s'",
5801 IDENTIFIER_POINTER (OBJC_TYPE_NAME (rtype)),
5802 (class_tree ? '+' : '-'),
5803 IDENTIFIER_POINTER (sel_name));
5805 warning ("`%c%s' not implemented by protocol(s)",
5806 (class_tree ? '+' : '-'),
5807 IDENTIFIER_POINTER (sel_name));
5808 if (!warn_missing_methods)
5810 warning ("(Messages without a matching method signature");
5811 warning ("will be assumed to return `id' and accept");
5812 warning ("`...' as arguments.)");
5813 warn_missing_methods = true;
5817 /* Save the selector name for printing error messages. */
5818 current_objc_message_selector = sel_name;
5820 /* Build the parameters list for looking up the method.
5821 These are the object itself and the selector. */
5823 if (flag_typed_selectors)
5824 selector = build_typed_selector_reference (sel_name, method_prototype);
5826 selector = build_selector_reference (sel_name);
5828 retval = build_objc_method_call (super, method_prototype,
5830 selector, method_params);
5832 current_objc_message_selector = 0;
5837 /* Build a tree expression to send OBJECT the operation SELECTOR,
5838 looking up the method on object LOOKUP_OBJECT (often same as OBJECT),
5839 assuming the method has prototype METHOD_PROTOTYPE.
5840 (That is an INSTANCE_METHOD_DECL or CLASS_METHOD_DECL.)
5841 Use METHOD_PARAMS as list of args to pass to the method.
5842 If SUPER_FLAG is nonzero, we look up the superclass's method. */
5845 build_objc_method_call (int super_flag, tree method_prototype,
5846 tree lookup_object, tree selector,
5849 tree sender = (super_flag ? umsg_super_decl :
5850 (!flag_next_runtime || flag_nil_receivers
5852 : umsg_nonnil_decl));
5853 tree rcv_p = (super_flag ? objc_super_type : objc_id_type);
5855 /* If a prototype for the method to be called exists, then cast
5856 the sender's return type and arguments to match that of the method.
5857 Otherwise, leave sender as is. */
5860 ? groktypename (TREE_TYPE (method_prototype))
5863 = build_pointer_type
5864 (build_function_type
5867 (method_prototype, METHOD_REF, super_flag)));
5870 lookup_object = build_c_cast (rcv_p, lookup_object);
5872 /* Use SAVE_EXPR to avoid evaluating the receiver twice. */
5873 lookup_object = save_expr (lookup_object);
5875 if (flag_next_runtime)
5877 /* If we are returning a struct in memory, and the address
5878 of that memory location is passed as a hidden first
5879 argument, then change which messenger entry point this
5880 expr will call. NB: Note that sender_cast remains
5881 unchanged (it already has a struct return type). */
5882 if (!targetm.calls.struct_value_rtx (0, 0)
5883 && (TREE_CODE (ret_type) == RECORD_TYPE
5884 || TREE_CODE (ret_type) == UNION_TYPE)
5885 && targetm.calls.return_in_memory (ret_type, 0))
5886 sender = (super_flag ? umsg_super_stret_decl :
5887 flag_nil_receivers ? umsg_stret_decl : umsg_nonnil_stret_decl);
5889 method_params = tree_cons (NULL_TREE, lookup_object,
5890 tree_cons (NULL_TREE, selector,
5892 method = build_fold_addr_expr (sender);
5896 /* This is the portable (GNU) way. */
5899 /* First, call the lookup function to get a pointer to the method,
5900 then cast the pointer, then call it with the method arguments. */
5902 object = (super_flag ? self_decl : lookup_object);
5904 t = tree_cons (NULL_TREE, selector, NULL_TREE);
5905 t = tree_cons (NULL_TREE, lookup_object, t);
5906 method = build_function_call (sender, t);
5908 /* Pass the object to the method. */
5909 method_params = tree_cons (NULL_TREE, object,
5910 tree_cons (NULL_TREE, selector,
5914 /* ??? Selector is not at this point something we can use inside
5915 the compiler itself. Set it to garbage for the nonce. */
5916 t = build (OBJ_TYPE_REF, sender_cast, method, lookup_object, size_zero_node);
5917 return build_function_call (t, method_params);
5921 build_protocol_reference (tree p)
5923 tree decl, ident, ptype;
5925 /* static struct objc_protocol _OBJC_PROTOCOL_<mumble>; */
5927 ident = synth_id_with_class_suffix ("_OBJC_PROTOCOL", p);
5929 = groktypename (build_tree_list (build_tree_list (NULL_TREE,
5930 objc_protocol_template),
5933 if (identifier_global_value (ident))
5934 decl = identifier_global_value (ident); /* Set by pushdecl. */
5937 decl = build_decl (VAR_DECL, ident, ptype);
5938 DECL_EXTERNAL (decl) = 1;
5939 TREE_PUBLIC (decl) = 0;
5940 TREE_USED (decl) = 1;
5941 DECL_ARTIFICIAL (decl) = 1;
5943 make_decl_rtl (decl);
5944 pushdecl_top_level (decl);
5947 PROTOCOL_FORWARD_DECL (p) = decl;
5950 /* This function is called by the parser when (and only when) a
5951 @protocol() expression is found, in order to compile it. */
5953 build_protocol_expr (tree protoname)
5956 tree p = lookup_protocol (protoname);
5960 error ("cannot find protocol declaration for `%s'",
5961 IDENTIFIER_POINTER (protoname));
5962 return error_mark_node;
5965 if (!PROTOCOL_FORWARD_DECL (p))
5966 build_protocol_reference (p);
5968 expr = build_unary_op (ADDR_EXPR, PROTOCOL_FORWARD_DECL (p), 0);
5970 /* ??? Ideally we'd build the reference with objc_protocol_type directly,
5971 if we have it, rather than converting it here. */
5972 expr = convert (objc_protocol_type, expr);
5974 /* The @protocol() expression is being compiled into a pointer to a
5975 statically allocated instance of the Protocol class. To become
5976 usable at runtime, the 'isa' pointer of the instance need to be
5977 fixed up at runtime by the runtime library, to point to the
5978 actual 'Protocol' class. */
5980 /* For the GNU runtime, put the static Protocol instance in the list
5981 of statically allocated instances, so that we make sure that its
5982 'isa' pointer is fixed up at runtime by the GNU runtime library
5983 to point to the Protocol class (at runtime, when loading the
5984 module, the GNU runtime library loops on the statically allocated
5985 instances (as found in the defs field in objc_symtab) and fixups
5986 all the 'isa' pointers of those objects). */
5987 if (! flag_next_runtime)
5989 /* This type is a struct containing the fields of a Protocol
5990 object. (Cfr. objc_protocol_type instead is the type of a pointer
5991 to such a struct). */
5992 tree protocol_struct_type = xref_tag
5993 (RECORD_TYPE, get_identifier (PROTOCOL_OBJECT_CLASS_NAME));
5996 /* Look for the list of Protocol statically allocated instances
5997 to fixup at runtime. Create a new list to hold Protocol
5998 statically allocated instances, if the list is not found. At
5999 present there is only another list, holding NSConstantString
6000 static instances to be fixed up at runtime. */
6001 for (chain = &objc_static_instances;
6002 *chain && TREE_VALUE (*chain) != protocol_struct_type;
6003 chain = &TREE_CHAIN (*chain));
6006 *chain = tree_cons (NULL_TREE, protocol_struct_type, NULL_TREE);
6007 add_objc_string (OBJC_TYPE_NAME (protocol_struct_type),
6011 /* Add this statically allocated instance to the Protocol list. */
6012 TREE_PURPOSE (*chain) = tree_cons (NULL_TREE,
6013 PROTOCOL_FORWARD_DECL (p),
6014 TREE_PURPOSE (*chain));
6021 /* This function is called by the parser when a @selector() expression
6022 is found, in order to compile it. It is only called by the parser
6023 and only to compile a @selector(). */
6025 build_selector_expr (tree selnamelist)
6029 /* Obtain the full selector name. */
6030 if (TREE_CODE (selnamelist) == IDENTIFIER_NODE)
6031 /* A unary selector. */
6032 selname = selnamelist;
6033 else if (TREE_CODE (selnamelist) == TREE_LIST)
6034 selname = build_keyword_selector (selnamelist);
6038 /* If we are required to check @selector() expressions as they
6039 are found, check that the selector has been declared. */
6040 if (warn_undeclared_selector)
6042 /* Look the selector up in the list of all known class and
6043 instance methods (up to this line) to check that the selector
6047 /* First try with instance methods. */
6048 hsh = hash_lookup (nst_method_hash_list, selname);
6050 /* If not found, try with class methods. */
6053 hsh = hash_lookup (cls_method_hash_list, selname);
6056 /* If still not found, print out a warning. */
6059 warning ("undeclared selector `%s'", IDENTIFIER_POINTER (selname));
6064 if (flag_typed_selectors)
6065 return build_typed_selector_reference (selname, 0);
6067 return build_selector_reference (selname);
6071 build_encode_expr (tree type)
6076 encode_type (type, obstack_object_size (&util_obstack),
6077 OBJC_ENCODE_INLINE_DEFS);
6078 obstack_1grow (&util_obstack, 0); /* null terminate string */
6079 string = obstack_finish (&util_obstack);
6081 /* Synthesize a string that represents the encoded struct/union. */
6082 result = my_build_string (strlen (string) + 1, string);
6083 obstack_free (&util_obstack, util_firstobj);
6088 build_ivar_reference (tree id)
6090 if (TREE_CODE (objc_method_context) == CLASS_METHOD_DECL)
6092 /* Historically, a class method that produced objects (factory
6093 method) would assign `self' to the instance that it
6094 allocated. This would effectively turn the class method into
6095 an instance method. Following this assignment, the instance
6096 variables could be accessed. That practice, while safe,
6097 violates the simple rule that a class method should not refer
6098 to an instance variable. It's better to catch the cases
6099 where this is done unknowingly than to support the above
6101 warning ("instance variable `%s' accessed in class method",
6102 IDENTIFIER_POINTER (id));
6103 TREE_TYPE (self_decl) = objc_instance_type; /* cast */
6106 return build_component_ref (build_indirect_ref (self_decl, "->"), id);
6109 /* Compute a hash value for a given method SEL_NAME. */
6112 hash_func (tree sel_name)
6114 const unsigned char *s
6115 = (const unsigned char *)IDENTIFIER_POINTER (sel_name);
6119 h = h * 67 + *s++ - 113;
6126 nst_method_hash_list
6127 = (hash *) ggc_alloc_cleared (SIZEHASHTABLE * sizeof (hash));
6128 cls_method_hash_list
6129 = (hash *) ggc_alloc_cleared (SIZEHASHTABLE * sizeof (hash));
6132 /* WARNING!!!! hash_enter is called with a method, and will peek
6133 inside to find its selector! But hash_lookup is given a selector
6134 directly, and looks for the selector that's inside the found
6135 entry's key (method) for comparison. */
6138 hash_enter (hash *hashlist, tree method)
6141 int slot = hash_func (METHOD_SEL_NAME (method)) % SIZEHASHTABLE;
6143 obj = (hash) ggc_alloc (sizeof (struct hashed_entry));
6145 obj->next = hashlist[slot];
6148 hashlist[slot] = obj; /* append to front */
6152 hash_lookup (hash *hashlist, tree sel_name)
6156 target = hashlist[hash_func (sel_name) % SIZEHASHTABLE];
6160 if (sel_name == METHOD_SEL_NAME (target->key))
6163 target = target->next;
6169 hash_add_attr (hash entry, tree value)
6173 obj = (attr) ggc_alloc (sizeof (struct hashed_attribute));
6174 obj->next = entry->list;
6177 entry->list = obj; /* append to front */
6181 lookup_method (tree mchain, tree method)
6185 if (TREE_CODE (method) == IDENTIFIER_NODE)
6188 key = METHOD_SEL_NAME (method);
6192 if (METHOD_SEL_NAME (mchain) == key)
6195 mchain = TREE_CHAIN (mchain);
6201 lookup_method_static (tree interface, tree ident, int is_class)
6203 tree meth = NULL_TREE, root_inter = NULL_TREE;
6204 tree inter = interface;
6208 tree chain = is_class ? CLASS_CLS_METHODS (inter) : CLASS_NST_METHODS (inter);
6209 tree category = inter;
6211 /* First, look up the method in the class itself. */
6212 if ((meth = lookup_method (chain, ident)))
6215 /* Failing that, look for the method in each category of the class. */
6216 while ((category = CLASS_CATEGORY_LIST (category)))
6218 chain = is_class ? CLASS_CLS_METHODS (category) : CLASS_NST_METHODS (category);
6220 /* Check directly in each category. */
6221 if ((meth = lookup_method (chain, ident)))
6224 /* Failing that, check in each category's protocols. */
6225 if (CLASS_PROTOCOL_LIST (category))
6227 if ((meth = (lookup_method_in_protocol_list
6228 (CLASS_PROTOCOL_LIST (category), ident, is_class))))
6233 /* If not found in categories, check in protocols of the main class. */
6234 if (CLASS_PROTOCOL_LIST (inter))
6236 if ((meth = (lookup_method_in_protocol_list
6237 (CLASS_PROTOCOL_LIST (inter), ident, is_class))))
6241 /* Failing that, climb up the inheritance hierarchy. */
6243 inter = lookup_interface (CLASS_SUPER_NAME (inter));
6247 /* If no class (factory) method was found, check if an _instance_
6248 method of the same name exists in the root class. This is what
6249 the Objective-C runtime will do. If an instance method was not
6251 return is_class ? lookup_method_static (root_inter, ident, 0): NULL_TREE;
6254 /* Add the method to the hash list if it doesn't contain an identical
6257 add_method_to_hash_list (hash *hash_list, tree method)
6261 if (!(hsh = hash_lookup (hash_list, METHOD_SEL_NAME (method))))
6263 /* Install on a global chain. */
6264 hash_enter (hash_list, method);
6268 /* Check types against those; if different, add to a list. */
6270 int already_there = comp_proto_with_proto (method, hsh->key);
6271 for (loop = hsh->list; !already_there && loop; loop = loop->next)
6272 already_there |= comp_proto_with_proto (method, loop->value);
6274 hash_add_attr (hsh, method);
6279 objc_add_method (tree class, tree method, int is_class)
6283 if (!(mth = lookup_method (is_class ? CLASS_CLS_METHODS (class) : CLASS_NST_METHODS (class), method)))
6285 /* put method on list in reverse order */
6288 TREE_CHAIN (method) = CLASS_CLS_METHODS (class);
6289 CLASS_CLS_METHODS (class) = method;
6293 TREE_CHAIN (method) = CLASS_NST_METHODS (class);
6294 CLASS_NST_METHODS (class) = method;
6299 /* When processing an @interface for a class or category, give hard
6300 errors on methods with identical selectors but differing argument
6301 and/or return types. We do not do this for @implementations, because
6302 C/C++ will do it for us (i.e., there will be duplicate function
6303 definition errors). */
6304 if ((TREE_CODE (class) == CLASS_INTERFACE_TYPE
6305 || TREE_CODE (class) == CATEGORY_INTERFACE_TYPE)
6306 && !comp_proto_with_proto (method, mth))
6307 error ("duplicate declaration of method `%c%s'",
6308 is_class ? '+' : '-', IDENTIFIER_POINTER (METHOD_SEL_NAME (mth)));
6312 add_method_to_hash_list (cls_method_hash_list, method);
6315 add_method_to_hash_list (nst_method_hash_list, method);
6317 /* Instance methods in root classes (and categories thereof)
6318 may acts as class methods as a last resort. */
6319 if (TREE_CODE (class) == CATEGORY_INTERFACE_TYPE
6320 || TREE_CODE (class) == CATEGORY_IMPLEMENTATION_TYPE)
6321 class = lookup_interface (CLASS_NAME (class));
6323 if (TREE_CODE (class) != PROTOCOL_INTERFACE_TYPE
6324 && !CLASS_SUPER_NAME (class))
6325 add_method_to_hash_list (cls_method_hash_list, method);
6332 add_class (tree class)
6334 /* Put interfaces on list in reverse order. */
6335 TREE_CHAIN (class) = interface_chain;
6336 interface_chain = class;
6337 return interface_chain;
6341 add_category (tree class, tree category)
6343 /* Put categories on list in reverse order. */
6344 tree cat = lookup_category (class, CLASS_SUPER_NAME (category));
6348 warning ("duplicate interface declaration for category `%s(%s)'",
6349 IDENTIFIER_POINTER (CLASS_NAME (class)),
6350 IDENTIFIER_POINTER (CLASS_SUPER_NAME (category)));
6354 CLASS_CATEGORY_LIST (category) = CLASS_CATEGORY_LIST (class);
6355 CLASS_CATEGORY_LIST (class) = category;
6359 /* Called after parsing each instance variable declaration. Necessary to
6360 preserve typedefs and implement public/private...
6362 PUBLIC is 1 for public, 0 for protected, and 2 for private. */
6365 add_instance_variable (tree class, int public, tree declarator,
6366 tree declspecs, tree width)
6368 tree field_decl = grokfield (declarator, declspecs, width);
6369 tree field_type = TREE_TYPE (field_decl);
6370 const char *ivar_name = DECL_NAME (field_decl)
6371 ? IDENTIFIER_POINTER (DECL_NAME (field_decl))
6376 if (TREE_CODE (field_type) == REFERENCE_TYPE)
6378 error ("illegal reference type specified for instance variable `%s'",
6380 /* Return class as is without adding this ivar. */
6385 if (field_type == error_mark_node || !TYPE_SIZE (field_type)
6386 || TYPE_SIZE (field_type) == error_mark_node
6387 /* 'type[0]' is allowed, but 'type[]' is not! */
6389 || (TYPE_SIZE (field_type) == bitsize_zero_node
6390 && !TREE_OPERAND (declarator, 1))
6394 error ("instance variable `%s' has unknown size", ivar_name);
6395 /* Return class as is without adding this ivar. */
6400 /* zlaski 2001-Apr-24: C++ classes with non-trivial constructors and/or destructors
6401 cannot be ivars; ditto for classes with vtables. */
6402 if(IS_AGGR_TYPE (field_type) && (TYPE_NEEDS_CONSTRUCTING (field_type)
6403 || TYPE_HAS_NONTRIVIAL_DESTRUCTOR (field_type) || TYPE_POLYMORPHIC_P (field_type)))
6405 const char *type_name = IDENTIFIER_POINTER (OBJC_TYPE_NAME (field_type));
6406 if(TYPE_POLYMORPHIC_P (field_type)) {
6407 /* vtable pointers are Real Bad(tm), since Obj-C cannot initialize them */
6408 error ("type `%s' has virtual member functions", type_name);
6409 error ("illegal aggregate type `%s' specified for instance variable `%s'",
6410 type_name, ivar_name);
6411 /* Return class as is without adding this ivar. */
6414 /* user-defined constructors and destructors are not known to Obj-C and
6415 hence will not be called. This may or may not be a problem. */
6416 if (TYPE_NEEDS_CONSTRUCTING (field_type))
6417 warning ("type `%s' has a user-defined constructor", type_name);
6418 if (TYPE_HAS_NONTRIVIAL_DESTRUCTOR (field_type))
6419 warning ("type `%s' has a user-defined destructor", type_name);
6420 warning ("C++ constructors and destructors will not be invoked for Objective-C fields");
6424 /* Overload the public attribute, it is not used for FIELD_DECLs. */
6428 TREE_PUBLIC (field_decl) = 0;
6429 TREE_PRIVATE (field_decl) = 0;
6430 TREE_PROTECTED (field_decl) = 1;
6434 TREE_PUBLIC (field_decl) = 1;
6435 TREE_PRIVATE (field_decl) = 0;
6436 TREE_PROTECTED (field_decl) = 0;
6440 TREE_PUBLIC (field_decl) = 0;
6441 TREE_PRIVATE (field_decl) = 1;
6442 TREE_PROTECTED (field_decl) = 0;
6447 raw_decl = build_tree_list (declspecs, build_tree_list (declarator, width));
6448 CLASS_RAW_IVARS (class) = chainon (CLASS_RAW_IVARS (class), raw_decl);
6449 CLASS_IVARS (class) = chainon (CLASS_IVARS (class), field_decl);
6454 is_ivar (tree decl_chain, tree ident)
6456 for ( ; decl_chain; decl_chain = TREE_CHAIN (decl_chain))
6457 if (DECL_NAME (decl_chain) == ident)
6462 /* True if the ivar is private and we are not in its implementation. */
6465 is_private (tree decl)
6467 return (TREE_PRIVATE (decl)
6468 && ! is_ivar (CLASS_IVARS (implementation_template),
6472 /* We have an instance variable reference;, check to see if it is public. */
6475 objc_is_public (tree expr, tree identifier)
6477 tree basetype = TREE_TYPE (expr);
6478 enum tree_code code = TREE_CODE (basetype);
6481 if (code == RECORD_TYPE)
6483 if (TREE_STATIC_TEMPLATE (basetype))
6485 if (!lookup_interface (OBJC_TYPE_NAME (basetype)))
6487 error ("cannot find interface declaration for `%s'",
6488 IDENTIFIER_POINTER (OBJC_TYPE_NAME (basetype)));
6492 if ((decl = is_ivar (TYPE_FIELDS (basetype), identifier)))
6494 if (TREE_PUBLIC (decl))
6497 /* Important difference between the Stepstone translator:
6498 all instance variables should be public within the context
6499 of the implementation. */
6500 if (objc_implementation_context
6501 && (((TREE_CODE (objc_implementation_context)
6502 == CLASS_IMPLEMENTATION_TYPE)
6503 || (TREE_CODE (objc_implementation_context)
6504 == CATEGORY_IMPLEMENTATION_TYPE))
6505 && (CLASS_NAME (objc_implementation_context)
6506 == OBJC_TYPE_NAME (basetype))))
6508 int private = is_private (decl);
6511 error ("instance variable `%s' is declared private",
6512 IDENTIFIER_POINTER (DECL_NAME (decl)));
6516 /* The 2.95.2 compiler sometimes allowed C functions to access
6517 non-@public ivars. We will let this slide for now... */
6518 if (!objc_method_context)
6520 warning ("instance variable `%s' is %s; "
6521 "this will be a hard error in the future",
6522 IDENTIFIER_POINTER (identifier),
6523 TREE_PRIVATE (decl) ? "@private" : "@protected");
6527 error ("instance variable `%s' is declared %s",
6528 IDENTIFIER_POINTER (identifier),
6529 TREE_PRIVATE (decl) ? "private" : "protected");
6534 else if (objc_implementation_context && (basetype == objc_object_reference))
6536 TREE_TYPE (expr) = uprivate_record;
6537 warning ("static access to object of type `id'");
6544 /* Make sure all entries in CHAIN are also in LIST. */
6547 check_methods (tree chain, tree list, int mtype)
6553 if (!lookup_method (list, chain))
6557 if (TREE_CODE (objc_implementation_context)
6558 == CLASS_IMPLEMENTATION_TYPE)
6559 warning ("incomplete implementation of class `%s'",
6560 IDENTIFIER_POINTER (CLASS_NAME (objc_implementation_context)));
6561 else if (TREE_CODE (objc_implementation_context)
6562 == CATEGORY_IMPLEMENTATION_TYPE)
6563 warning ("incomplete implementation of category `%s'",
6564 IDENTIFIER_POINTER (CLASS_SUPER_NAME (objc_implementation_context)));
6568 warning ("method definition for `%c%s' not found",
6569 mtype, IDENTIFIER_POINTER (METHOD_SEL_NAME (chain)));
6572 chain = TREE_CHAIN (chain);
6578 /* Check if CLASS, or its superclasses, explicitly conforms to PROTOCOL. */
6581 conforms_to_protocol (tree class, tree protocol)
6583 if (TREE_CODE (protocol) == PROTOCOL_INTERFACE_TYPE)
6585 tree p = CLASS_PROTOCOL_LIST (class);
6586 while (p && TREE_VALUE (p) != protocol)
6591 tree super = (CLASS_SUPER_NAME (class)
6592 ? lookup_interface (CLASS_SUPER_NAME (class))
6594 int tmp = super ? conforms_to_protocol (super, protocol) : 0;
6603 /* Make sure all methods in CHAIN are accessible as MTYPE methods in
6604 CONTEXT. This is one of two mechanisms to check protocol integrity. */
6607 check_methods_accessible (tree chain, tree context, int mtype)
6611 tree base_context = context;
6615 context = base_context;
6619 list = CLASS_CLS_METHODS (context);
6621 list = CLASS_NST_METHODS (context);
6623 if (lookup_method (list, chain))
6626 else if (TREE_CODE (context) == CLASS_IMPLEMENTATION_TYPE
6627 || TREE_CODE (context) == CLASS_INTERFACE_TYPE)
6628 context = (CLASS_SUPER_NAME (context)
6629 ? lookup_interface (CLASS_SUPER_NAME (context))
6632 else if (TREE_CODE (context) == CATEGORY_IMPLEMENTATION_TYPE
6633 || TREE_CODE (context) == CATEGORY_INTERFACE_TYPE)
6634 context = (CLASS_NAME (context)
6635 ? lookup_interface (CLASS_NAME (context))
6641 if (context == NULL_TREE)
6645 if (TREE_CODE (objc_implementation_context)
6646 == CLASS_IMPLEMENTATION_TYPE)
6647 warning ("incomplete implementation of class `%s'",
6649 (CLASS_NAME (objc_implementation_context)));
6650 else if (TREE_CODE (objc_implementation_context)
6651 == CATEGORY_IMPLEMENTATION_TYPE)
6652 warning ("incomplete implementation of category `%s'",
6654 (CLASS_SUPER_NAME (objc_implementation_context)));
6657 warning ("method definition for `%c%s' not found",
6658 mtype, IDENTIFIER_POINTER (METHOD_SEL_NAME (chain)));
6661 chain = TREE_CHAIN (chain); /* next method... */
6666 /* Check whether the current interface (accessible via
6667 'objc_implementation_context') actually implements protocol P, along
6668 with any protocols that P inherits. */
6671 check_protocol (tree p, const char *type, const char *name)
6673 if (TREE_CODE (p) == PROTOCOL_INTERFACE_TYPE)
6677 /* Ensure that all protocols have bodies! */
6680 f1 = check_methods (PROTOCOL_CLS_METHODS (p),
6681 CLASS_CLS_METHODS (objc_implementation_context),
6683 f2 = check_methods (PROTOCOL_NST_METHODS (p),
6684 CLASS_NST_METHODS (objc_implementation_context),
6689 f1 = check_methods_accessible (PROTOCOL_CLS_METHODS (p),
6690 objc_implementation_context,
6692 f2 = check_methods_accessible (PROTOCOL_NST_METHODS (p),
6693 objc_implementation_context,
6698 warning ("%s `%s' does not fully implement the `%s' protocol",
6699 type, name, IDENTIFIER_POINTER (PROTOCOL_NAME (p)));
6702 /* Check protocols recursively. */
6703 if (PROTOCOL_LIST (p))
6705 tree subs = PROTOCOL_LIST (p);
6707 lookup_interface (CLASS_SUPER_NAME (implementation_template));
6711 tree sub = TREE_VALUE (subs);
6713 /* If the superclass does not conform to the protocols
6714 inherited by P, then we must! */
6715 if (!super_class || !conforms_to_protocol (super_class, sub))
6716 check_protocol (sub, type, name);
6717 subs = TREE_CHAIN (subs);
6722 /* Check whether the current interface (accessible via
6723 'objc_implementation_context') actually implements the protocols listed
6727 check_protocols (tree proto_list, const char *type, const char *name)
6729 for ( ; proto_list; proto_list = TREE_CHAIN (proto_list))
6731 tree p = TREE_VALUE (proto_list);
6733 check_protocol (p, type, name);
6737 /* Make sure that the class CLASS_NAME is defined
6738 CODE says which kind of thing CLASS_NAME ought to be.
6739 It can be CLASS_INTERFACE_TYPE, CLASS_IMPLEMENTATION_TYPE,
6740 CATEGORY_INTERFACE_TYPE, or CATEGORY_IMPLEMENTATION_TYPE. */
6743 start_class (enum tree_code code, tree class_name, tree super_name,
6749 if (current_namespace != global_namespace) {
6750 error ("Objective-C declarations may only appear in global scope");
6752 #endif /* OBJCPLUS */
6754 if (objc_implementation_context)
6756 warning ("`@end' missing in implementation context");
6757 finish_class (objc_implementation_context);
6758 objc_ivar_chain = NULL_TREE;
6759 objc_implementation_context = NULL_TREE;
6762 class = make_node (code);
6763 TYPE_LANG_SLOT_1 (class) = make_tree_vec (CLASS_LANG_SLOT_ELTS);
6765 CLASS_NAME (class) = class_name;
6766 CLASS_SUPER_NAME (class) = super_name;
6767 CLASS_CLS_METHODS (class) = NULL_TREE;
6769 if (! objc_is_class_name (class_name)
6770 && (decl = lookup_name (class_name)))
6772 error ("`%s' redeclared as different kind of symbol",
6773 IDENTIFIER_POINTER (class_name));
6774 error ("%Jprevious declaration of '%D'",
6778 if (code == CLASS_IMPLEMENTATION_TYPE)
6783 for (chain = implemented_classes; chain; chain = TREE_CHAIN (chain))
6784 if (TREE_VALUE (chain) == class_name)
6786 error ("reimplementation of class `%s'",
6787 IDENTIFIER_POINTER (class_name));
6788 return error_mark_node;
6790 implemented_classes = tree_cons (NULL_TREE, class_name,
6791 implemented_classes);
6794 /* Reset for multiple classes per file. */
6797 objc_implementation_context = class;
6799 /* Lookup the interface for this implementation. */
6801 if (!(implementation_template = lookup_interface (class_name)))
6803 warning ("cannot find interface declaration for `%s'",
6804 IDENTIFIER_POINTER (class_name));
6805 add_class (implementation_template = objc_implementation_context);
6808 /* If a super class has been specified in the implementation,
6809 insure it conforms to the one specified in the interface. */
6812 && (super_name != CLASS_SUPER_NAME (implementation_template)))
6814 tree previous_name = CLASS_SUPER_NAME (implementation_template);
6815 const char *const name =
6816 previous_name ? IDENTIFIER_POINTER (previous_name) : "";
6817 error ("conflicting super class name `%s'",
6818 IDENTIFIER_POINTER (super_name));
6819 error ("previous declaration of `%s'", name);
6822 else if (! super_name)
6824 CLASS_SUPER_NAME (objc_implementation_context)
6825 = CLASS_SUPER_NAME (implementation_template);
6829 else if (code == CLASS_INTERFACE_TYPE)
6831 if (lookup_interface (class_name))
6833 error ("duplicate interface declaration for class `%s'",
6835 warning ("duplicate interface declaration for class `%s'",
6837 IDENTIFIER_POINTER (class_name));
6842 CLASS_PROTOCOL_LIST (class)
6843 = lookup_and_install_protocols (protocol_list);
6846 else if (code == CATEGORY_INTERFACE_TYPE)
6848 tree class_category_is_assoc_with;
6850 /* For a category, class_name is really the name of the class that
6851 the following set of methods will be associated with. We must
6852 find the interface so that can derive the objects template. */
6854 if (!(class_category_is_assoc_with = lookup_interface (class_name)))
6856 error ("cannot find interface declaration for `%s'",
6857 IDENTIFIER_POINTER (class_name));
6858 exit (FATAL_EXIT_CODE);
6861 add_category (class_category_is_assoc_with, class);
6864 CLASS_PROTOCOL_LIST (class)
6865 = lookup_and_install_protocols (protocol_list);
6868 else if (code == CATEGORY_IMPLEMENTATION_TYPE)
6870 /* Reset for multiple classes per file. */
6873 objc_implementation_context = class;
6875 /* For a category, class_name is really the name of the class that
6876 the following set of methods will be associated with. We must
6877 find the interface so that can derive the objects template. */
6879 if (!(implementation_template = lookup_interface (class_name)))
6881 error ("cannot find interface declaration for `%s'",
6882 IDENTIFIER_POINTER (class_name));
6883 exit (FATAL_EXIT_CODE);
6890 continue_class (tree class)
6892 if (TREE_CODE (class) == CLASS_IMPLEMENTATION_TYPE
6893 || TREE_CODE (class) == CATEGORY_IMPLEMENTATION_TYPE)
6895 struct imp_entry *imp_entry;
6898 /* Check consistency of the instance variables. */
6900 if (CLASS_IVARS (class))
6901 check_ivars (implementation_template, class);
6903 /* code generation */
6905 ivar_context = build_private_template (implementation_template);
6907 if (!objc_class_template)
6908 build_class_template ();
6910 imp_entry = (struct imp_entry *) ggc_alloc (sizeof (struct imp_entry));
6912 imp_entry->next = imp_list;
6913 imp_entry->imp_context = class;
6914 imp_entry->imp_template = implementation_template;
6916 synth_forward_declarations ();
6917 imp_entry->class_decl = UOBJC_CLASS_decl;
6918 imp_entry->meta_decl = UOBJC_METACLASS_decl;
6920 /* Append to front and increment count. */
6921 imp_list = imp_entry;
6922 if (TREE_CODE (class) == CLASS_IMPLEMENTATION_TYPE)
6927 return ivar_context;
6930 else if (TREE_CODE (class) == CLASS_INTERFACE_TYPE)
6932 if (!CLASS_STATIC_TEMPLATE (class))
6934 tree record = start_struct (RECORD_TYPE, CLASS_NAME (class));
6935 finish_struct (record, get_class_ivars (class, 0), NULL_TREE);
6936 CLASS_STATIC_TEMPLATE (class) = record;
6938 /* Mark this record as a class template for static typing. */
6939 TREE_STATIC_TEMPLATE (record) = 1;
6946 return error_mark_node;
6949 /* This is called once we see the "@end" in an interface/implementation. */
6952 finish_class (tree class)
6954 if (TREE_CODE (class) == CLASS_IMPLEMENTATION_TYPE)
6956 /* All code generation is done in finish_objc. */
6958 if (implementation_template != objc_implementation_context)
6960 /* Ensure that all method listed in the interface contain bodies. */
6961 check_methods (CLASS_CLS_METHODS (implementation_template),
6962 CLASS_CLS_METHODS (objc_implementation_context), '+');
6963 check_methods (CLASS_NST_METHODS (implementation_template),
6964 CLASS_NST_METHODS (objc_implementation_context), '-');
6966 if (CLASS_PROTOCOL_LIST (implementation_template))
6967 check_protocols (CLASS_PROTOCOL_LIST (implementation_template),
6969 IDENTIFIER_POINTER (CLASS_NAME (objc_implementation_context)));
6973 else if (TREE_CODE (class) == CATEGORY_IMPLEMENTATION_TYPE)
6975 tree category = lookup_category (implementation_template, CLASS_SUPER_NAME (class));
6979 /* Ensure all method listed in the interface contain bodies. */
6980 check_methods (CLASS_CLS_METHODS (category),
6981 CLASS_CLS_METHODS (objc_implementation_context), '+');
6982 check_methods (CLASS_NST_METHODS (category),
6983 CLASS_NST_METHODS (objc_implementation_context), '-');
6985 if (CLASS_PROTOCOL_LIST (category))
6986 check_protocols (CLASS_PROTOCOL_LIST (category),
6988 IDENTIFIER_POINTER (CLASS_SUPER_NAME (objc_implementation_context)));
6992 else if (TREE_CODE (class) == CLASS_INTERFACE_TYPE)
6995 const char *class_name = IDENTIFIER_POINTER (CLASS_NAME (class));
6996 char *string = (char *) alloca (strlen (class_name) + 3);
6998 /* extern struct objc_object *_<my_name>; */
7000 sprintf (string, "_%s", class_name);
7002 decl_specs = build_tree_list (NULL_TREE, ridpointers[(int) RID_EXTERN]);
7003 decl_specs = tree_cons (NULL_TREE, objc_object_reference, decl_specs);
7004 define_decl (build1 (INDIRECT_REF, NULL_TREE, get_identifier (string)),
7010 add_protocol (tree protocol)
7012 /* Put protocol on list in reverse order. */
7013 TREE_CHAIN (protocol) = protocol_chain;
7014 protocol_chain = protocol;
7015 return protocol_chain;
7019 lookup_protocol (tree ident)
7023 for (chain = protocol_chain; chain; chain = TREE_CHAIN (chain))
7024 if (ident == PROTOCOL_NAME (chain))
7030 /* This function forward declares the protocols named by NAMES. If
7031 they are already declared or defined, the function has no effect. */
7034 objc_declare_protocols (tree names)
7039 if (current_namespace != global_namespace) {
7040 error ("Objective-C declarations may only appear in global scope");
7042 #endif /* OBJCPLUS */
7044 for (list = names; list; list = TREE_CHAIN (list))
7046 tree name = TREE_VALUE (list);
7048 if (lookup_protocol (name) == NULL_TREE)
7050 tree protocol = make_node (PROTOCOL_INTERFACE_TYPE);
7052 TYPE_LANG_SLOT_1 (protocol)
7053 = make_tree_vec (PROTOCOL_LANG_SLOT_ELTS);
7054 PROTOCOL_NAME (protocol) = name;
7055 PROTOCOL_LIST (protocol) = NULL_TREE;
7056 add_protocol (protocol);
7057 PROTOCOL_DEFINED (protocol) = 0;
7058 PROTOCOL_FORWARD_DECL (protocol) = NULL_TREE;
7064 start_protocol (enum tree_code code, tree name, tree list)
7069 if (current_namespace != global_namespace) {
7070 error ("Objective-C declarations may only appear in global scope");
7072 #endif /* OBJCPLUS */
7074 /* This is as good a place as any. Need to invoke
7075 push_tag_toplevel. */
7076 if (!objc_protocol_template)
7077 objc_protocol_template = build_protocol_template ();
7079 protocol = lookup_protocol (name);
7083 protocol = make_node (code);
7084 TYPE_LANG_SLOT_1 (protocol) = make_tree_vec (PROTOCOL_LANG_SLOT_ELTS);
7086 PROTOCOL_NAME (protocol) = name;
7087 PROTOCOL_LIST (protocol) = lookup_and_install_protocols (list);
7088 add_protocol (protocol);
7089 PROTOCOL_DEFINED (protocol) = 1;
7090 PROTOCOL_FORWARD_DECL (protocol) = NULL_TREE;
7092 check_protocol_recursively (protocol, list);
7094 else if (! PROTOCOL_DEFINED (protocol))
7096 PROTOCOL_DEFINED (protocol) = 1;
7097 PROTOCOL_LIST (protocol) = lookup_and_install_protocols (list);
7099 check_protocol_recursively (protocol, list);
7103 warning ("duplicate declaration for protocol `%s'",
7104 IDENTIFIER_POINTER (name));
7110 finish_protocol (tree protocol ATTRIBUTE_UNUSED)
7115 /* "Encode" a data type into a string, which grows in util_obstack.
7116 ??? What is the FORMAT? Someone please document this! */
7119 encode_type_qualifiers (tree declspecs)
7123 for (spec = declspecs; spec; spec = TREE_CHAIN (spec))
7125 if (ridpointers[(int) RID_CONST] == TREE_VALUE (spec))
7126 obstack_1grow (&util_obstack, 'r');
7127 else if (ridpointers[(int) RID_IN] == TREE_VALUE (spec))
7128 obstack_1grow (&util_obstack, 'n');
7129 else if (ridpointers[(int) RID_INOUT] == TREE_VALUE (spec))
7130 obstack_1grow (&util_obstack, 'N');
7131 else if (ridpointers[(int) RID_OUT] == TREE_VALUE (spec))
7132 obstack_1grow (&util_obstack, 'o');
7133 else if (ridpointers[(int) RID_BYCOPY] == TREE_VALUE (spec))
7134 obstack_1grow (&util_obstack, 'O');
7135 else if (ridpointers[(int) RID_BYREF] == TREE_VALUE (spec))
7136 obstack_1grow (&util_obstack, 'R');
7137 else if (ridpointers[(int) RID_ONEWAY] == TREE_VALUE (spec))
7138 obstack_1grow (&util_obstack, 'V');
7142 /* Encode a pointer type. */
7145 encode_pointer (tree type, int curtype, int format)
7147 tree pointer_to = TREE_TYPE (type);
7149 if (TREE_CODE (pointer_to) == RECORD_TYPE)
7151 if (OBJC_TYPE_NAME (pointer_to)
7152 && TREE_CODE (OBJC_TYPE_NAME (pointer_to)) == IDENTIFIER_NODE)
7154 const char *name = IDENTIFIER_POINTER (OBJC_TYPE_NAME (pointer_to));
7156 if (strcmp (name, TAG_OBJECT) == 0) /* '@' */
7158 obstack_1grow (&util_obstack, '@');
7161 else if (TREE_STATIC_TEMPLATE (pointer_to))
7163 if (generating_instance_variables)
7165 obstack_1grow (&util_obstack, '@');
7166 obstack_1grow (&util_obstack, '"');
7167 obstack_grow (&util_obstack, name, strlen (name));
7168 obstack_1grow (&util_obstack, '"');
7173 obstack_1grow (&util_obstack, '@');
7177 else if (strcmp (name, TAG_CLASS) == 0) /* '#' */
7179 obstack_1grow (&util_obstack, '#');
7182 else if (strcmp (name, TAG_SELECTOR) == 0) /* ':' */
7184 obstack_1grow (&util_obstack, ':');
7189 else if (TREE_CODE (pointer_to) == INTEGER_TYPE
7190 && TYPE_MODE (pointer_to) == QImode)
7192 tree pname = TREE_CODE (OBJC_TYPE_NAME (pointer_to)) == IDENTIFIER_NODE
7193 ? OBJC_TYPE_NAME (pointer_to)
7194 : DECL_NAME (OBJC_TYPE_NAME (pointer_to));
7196 if (!flag_next_runtime || strcmp (IDENTIFIER_POINTER (pname), "BOOL"))
7198 obstack_1grow (&util_obstack, '*');
7203 /* We have a type that does not get special treatment. */
7205 /* NeXT extension */
7206 obstack_1grow (&util_obstack, '^');
7207 encode_type (pointer_to, curtype, format);
7211 encode_array (tree type, int curtype, int format)
7213 tree an_int_cst = TYPE_SIZE (type);
7214 tree array_of = TREE_TYPE (type);
7217 /* An incomplete array is treated like a pointer. */
7218 if (an_int_cst == NULL)
7220 encode_pointer (type, curtype, format);
7224 sprintf (buffer, "[%ld",
7225 (long) (TREE_INT_CST_LOW (an_int_cst)
7226 / TREE_INT_CST_LOW (TYPE_SIZE (array_of))));
7228 obstack_grow (&util_obstack, buffer, strlen (buffer));
7229 encode_type (array_of, curtype, format);
7230 obstack_1grow (&util_obstack, ']');
7235 encode_aggregate_within (tree type, int curtype, int format, int left,
7239 /* NB: aggregates that are pointed to have slightly different encoding
7240 rules in that you never encode the names of instance variables. */
7242 = (obstack_object_size (&util_obstack) > 0
7243 && *(obstack_next_free (&util_obstack) - 1) == '^');
7245 = ((format == OBJC_ENCODE_INLINE_DEFS || generating_instance_variables)
7246 && (!pointed_to || obstack_object_size (&util_obstack) - curtype == 1));
7248 /* Traverse struct aliases; it is important to get the
7249 original struct and its tag name (if any). */
7250 type = TYPE_MAIN_VARIANT (type);
7251 name = OBJC_TYPE_NAME (type);
7252 /* Open parenth/bracket. */
7253 obstack_1grow (&util_obstack, left);
7255 /* Encode the struct/union tag name, or '?' if a tag was
7256 not provided. Typedef aliases do not qualify. */
7257 if (name && TREE_CODE (name) == IDENTIFIER_NODE
7259 /* Did this struct have a tag? */
7260 && !TYPE_WAS_ANONYMOUS (type)
7263 obstack_grow (&util_obstack,
7264 IDENTIFIER_POINTER (name),
7265 strlen (IDENTIFIER_POINTER (name)));
7267 obstack_1grow (&util_obstack, '?');
7269 /* Encode the types (and possibly names) of the inner fields,
7271 if (inline_contents)
7273 tree fields = TYPE_FIELDS (type);
7275 obstack_1grow (&util_obstack, '=');
7276 for (; fields; fields = TREE_CHAIN (fields))
7279 /* C++ static members, and things that are not fields at all,
7280 should not appear in the encoding. */
7281 if (TREE_CODE (fields) != FIELD_DECL || TREE_STATIC (fields))
7284 if (generating_instance_variables && !pointed_to)
7286 tree fname = DECL_NAME (fields);
7288 obstack_1grow (&util_obstack, '"');
7289 if (fname && TREE_CODE (fname) == IDENTIFIER_NODE)
7290 obstack_grow (&util_obstack,
7291 IDENTIFIER_POINTER (fname),
7292 strlen (IDENTIFIER_POINTER (fname)));
7293 obstack_1grow (&util_obstack, '"');
7295 encode_field_decl (fields, curtype, format);
7298 /* Close parenth/bracket. */
7299 obstack_1grow (&util_obstack, right);
7303 encode_aggregate (tree type, int curtype, int format)
7305 enum tree_code code = TREE_CODE (type);
7311 encode_aggregate_within (type, curtype, format, '{', '}');
7316 encode_aggregate_within (type, curtype, format, '(', ')');
7321 obstack_1grow (&util_obstack, 'i');
7329 /* Encode a bitfield NeXT-style (i.e., without a bit offset or the underlying
7333 encode_next_bitfield (int width)
7336 sprintf (buffer, "b%d", width);
7337 obstack_grow (&util_obstack, buffer, strlen (buffer));
7340 /* FORMAT will be OBJC_ENCODE_INLINE_DEFS or OBJC_ENCODE_DONT_INLINE_DEFS. */
7342 encode_type (tree type, int curtype, int format)
7344 enum tree_code code = TREE_CODE (type);
7347 if (code == INTEGER_TYPE)
7349 switch (GET_MODE_BITSIZE (TYPE_MODE (type)))
7351 case 8: c = TYPE_UNSIGNED (type) ? 'C' : 'c'; break;
7352 case 16: c = TYPE_UNSIGNED (type) ? 'S' : 's'; break;
7354 if (type == long_unsigned_type_node
7355 || type == long_integer_type_node)
7356 c = TYPE_UNSIGNED (type) ? 'L' : 'l';
7358 c = TYPE_UNSIGNED (type) ? 'I' : 'i';
7360 case 64: c = TYPE_UNSIGNED (type) ? 'Q' : 'q'; break;
7363 obstack_1grow (&util_obstack, c);
7366 else if (code == REAL_TYPE)
7368 /* Floating point types. */
7369 switch (GET_MODE_BITSIZE (TYPE_MODE (type)))
7371 case 32: c = 'f'; break;
7373 case 128: c = 'd'; break;
7376 obstack_1grow (&util_obstack, c);
7379 else if (code == VOID_TYPE)
7380 obstack_1grow (&util_obstack, 'v');
7382 else if (code == BOOLEAN_TYPE)
7383 obstack_1grow (&util_obstack, 'B');
7385 else if (code == ARRAY_TYPE)
7386 encode_array (type, curtype, format);
7388 else if (code == POINTER_TYPE)
7389 encode_pointer (type, curtype, format);
7391 else if (code == RECORD_TYPE || code == UNION_TYPE || code == ENUMERAL_TYPE)
7392 encode_aggregate (type, curtype, format);
7394 else if (code == FUNCTION_TYPE) /* '?' */
7395 obstack_1grow (&util_obstack, '?');
7399 encode_gnu_bitfield (int position, tree type, int size)
7401 enum tree_code code = TREE_CODE (type);
7403 char charType = '?';
7405 if (code == INTEGER_TYPE)
7407 if (integer_zerop (TYPE_MIN_VALUE (type)))
7409 /* Unsigned integer types. */
7411 if (TYPE_MODE (type) == QImode)
7413 else if (TYPE_MODE (type) == HImode)
7415 else if (TYPE_MODE (type) == SImode)
7417 if (type == long_unsigned_type_node)
7422 else if (TYPE_MODE (type) == DImode)
7427 /* Signed integer types. */
7429 if (TYPE_MODE (type) == QImode)
7431 else if (TYPE_MODE (type) == HImode)
7433 else if (TYPE_MODE (type) == SImode)
7435 if (type == long_integer_type_node)
7441 else if (TYPE_MODE (type) == DImode)
7445 else if (code == ENUMERAL_TYPE)
7450 sprintf (buffer, "b%d%c%d", position, charType, size);
7451 obstack_grow (&util_obstack, buffer, strlen (buffer));
7455 encode_field_decl (tree field_decl, int curtype, int format)
7460 /* C++ static members, and things that are not fields at all,
7461 should not appear in the encoding. */
7462 if (TREE_CODE (field_decl) != FIELD_DECL || TREE_STATIC (field_decl))
7466 type = TREE_TYPE (field_decl);
7468 /* Generate the bitfield typing information, if needed. Note the difference
7469 between GNU and NeXT runtimes. */
7470 if (DECL_BIT_FIELD_TYPE (field_decl))
7472 int size = tree_low_cst (DECL_SIZE (field_decl), 1);
7474 if (flag_next_runtime)
7475 encode_next_bitfield (size);
7477 encode_gnu_bitfield (int_bit_position (field_decl),
7478 DECL_BIT_FIELD_TYPE (field_decl), size);
7481 encode_type (TREE_TYPE (field_decl), curtype, format);
7485 objc_expr_last (tree complex_expr)
7490 while ((next = TREE_OPERAND (complex_expr, 0)))
7491 complex_expr = next;
7493 return complex_expr;
7497 synth_self_and_ucmd_args (void)
7501 if (objc_method_context
7502 && TREE_CODE (objc_method_context) == INSTANCE_METHOD_DECL)
7503 decl_specs = build_tree_list (NULL_TREE, uprivate_record);
7505 /* Really a `struct objc_class *'. However, we allow people to
7506 assign to self, which changes its type midstream. */
7507 decl_specs = build_tree_list (NULL_TREE, objc_object_reference);
7509 push_parm_decl (build_tree_list
7510 (build_tree_list (decl_specs,
7511 build1 (INDIRECT_REF, NULL_TREE, self_id)),
7514 decl_specs = build_tree_list (NULL_TREE, TREE_TYPE (objc_selector_type));
7515 push_parm_decl (build_tree_list
7516 (build_tree_list (decl_specs,
7517 build1 (INDIRECT_REF, NULL_TREE, ucmd_id)),
7521 /* Transform a method definition into a function definition as follows:
7522 - synthesize the first two arguments, "self" and "_cmd". */
7525 start_method_def (tree method)
7527 /* Required to implement _msgSuper. */
7528 objc_method_context = method;
7529 UOBJC_SUPER_decl = NULL_TREE;
7531 /* Must be called BEFORE start_function. */
7533 declare_parm_level ();
7535 /* Generate prototype declarations for arguments..."new-style". */
7536 synth_self_and_ucmd_args ();
7538 /* Generate argument declarations if a keyword_decl. */
7539 if (METHOD_SEL_ARGS (method))
7541 tree arglist = METHOD_SEL_ARGS (method);
7544 tree arg_spec = TREE_PURPOSE (TREE_TYPE (arglist));
7545 tree arg_decl = TREE_VALUE (TREE_TYPE (arglist));
7549 tree last_expr = objc_expr_last (arg_decl);
7551 /* Unite the abstract decl with its name. */
7552 TREE_OPERAND (last_expr, 0) = KEYWORD_ARG_NAME (arglist);
7553 push_parm_decl (build_tree_list
7554 (build_tree_list (arg_spec, arg_decl),
7558 /* Unhook: restore the abstract declarator. */
7559 TREE_OPERAND (last_expr, 0) = NULL_TREE;
7564 push_parm_decl (build_tree_list
7565 (build_tree_list (arg_spec,
7566 KEYWORD_ARG_NAME (arglist)),
7569 arglist = TREE_CHAIN (arglist);
7574 if (METHOD_ADD_ARGS (method) != NULL_TREE
7575 && METHOD_ADD_ARGS (method) != objc_ellipsis_node)
7577 /* We have a variable length selector - in "prototype" format. */
7578 tree akey = TREE_PURPOSE (METHOD_ADD_ARGS (method));
7581 /* This must be done prior to calling pushdecl. pushdecl is
7582 going to change our chain on us. */
7583 tree nextkey = TREE_CHAIN (akey);
7591 warn_with_method (const char *message, int mtype, tree method)
7593 /* Add a readable method name to the warning. */
7594 warning ("%J%s `%c%s'", method,
7595 message, mtype, gen_method_decl (method, errbuf));
7598 /* Return 1 if METHOD is consistent with PROTO. */
7601 comp_method_with_proto (tree method, tree proto)
7603 /* Create a function template node at most once. */
7604 if (!function1_template)
7605 function1_template = make_node (FUNCTION_TYPE);
7607 /* Install argument types - normally set by build_function_type. */
7608 TYPE_ARG_TYPES (function1_template)
7609 = get_arg_type_list (proto, METHOD_DEF, 0);
7611 /* install return type */
7612 TREE_TYPE (function1_template) = groktypename (TREE_TYPE (proto));
7614 return comptypes (TREE_TYPE (METHOD_DEFINITION (method)), function1_template);
7617 /* Return 1 if TYPE1 is equivalent to TYPE2. */
7620 objc_types_are_equivalent (tree type1, tree type2)
7624 if (TYPE_MAIN_VARIANT (type1) != TYPE_MAIN_VARIANT (type2))
7626 type1 = TYPE_PROTOCOL_LIST (type1);
7627 type2 = TYPE_PROTOCOL_LIST (type2);
7628 if (list_length (type1) == list_length (type2))
7630 for (; type2; type2 = TREE_CHAIN (type2))
7631 if (!lookup_protocol_in_reflist (type1, TREE_VALUE (type2)))
7638 /* Return 1 if PROTO1 is equivalent to PROTO2. */
7641 comp_proto_with_proto (tree proto1, tree proto2)
7645 /* The following test is needed in case there are hashing
7647 if (METHOD_SEL_NAME (proto1) != METHOD_SEL_NAME (proto2))
7650 /* Compare return types. */
7651 type1 = groktypename (TREE_TYPE (proto1));
7652 type2 = groktypename (TREE_TYPE (proto2));
7654 if (!objc_types_are_equivalent (type1, type2))
7657 /* Compare argument types. */
7658 for (type1 = get_arg_type_list (proto1, METHOD_REF, 0),
7659 type2 = get_arg_type_list (proto2, METHOD_REF, 0);
7661 type1 = TREE_CHAIN (type1), type2 = TREE_CHAIN (type2))
7663 if (!objc_types_are_equivalent (TREE_VALUE (type1), TREE_VALUE (type2)))
7667 return (!type1 && !type2);
7670 /* - Generate an identifier for the function. the format is "_n_cls",
7671 where 1 <= n <= nMethods, and cls is the name the implementation we
7673 - Install the return type from the method declaration.
7674 - If we have a prototype, check for type consistency. */
7677 really_start_method (tree method, tree parmlist)
7679 tree sc_spec, ret_spec, ret_decl, decl_specs;
7680 tree method_decl, method_id;
7681 const char *sel_name, *class_name, *cat_name;
7684 /* Synth the storage class & assemble the return type. */
7685 sc_spec = tree_cons (NULL_TREE, ridpointers[(int) RID_STATIC], NULL_TREE);
7686 ret_spec = TREE_PURPOSE (TREE_TYPE (method));
7687 decl_specs = chainon (sc_spec, ret_spec);
7689 sel_name = IDENTIFIER_POINTER (METHOD_SEL_NAME (method));
7690 class_name = IDENTIFIER_POINTER (CLASS_NAME (objc_implementation_context));
7691 cat_name = ((TREE_CODE (objc_implementation_context)
7692 == CLASS_IMPLEMENTATION_TYPE)
7694 : IDENTIFIER_POINTER (CLASS_SUPER_NAME (objc_implementation_context)));
7697 /* Make sure this is big enough for any plausible method label. */
7698 buf = (char *) alloca (50 + strlen (sel_name) + strlen (class_name)
7699 + (cat_name ? strlen (cat_name) : 0));
7701 OBJC_GEN_METHOD_LABEL (buf, TREE_CODE (method) == INSTANCE_METHOD_DECL,
7702 class_name, cat_name, sel_name, method_slot);
7704 method_id = get_identifier (buf);
7707 /* Objective-C methods cannot be overloaded, so we don't need
7708 the type encoding appended. It looks bad anyway... */
7709 push_lang_context (lang_name_c);
7712 method_decl = build_nt (CALL_EXPR, method_id, parmlist, NULL_TREE);
7714 /* Check the declarator portion of the return type for the method. */
7715 if ((ret_decl = TREE_VALUE (TREE_TYPE (method))))
7717 /* Unite the complex decl (specified in the abstract decl) with the
7718 function decl just synthesized..(int *), (int (*)()), (int (*)[]). */
7719 tree save_expr = objc_expr_last (ret_decl);
7721 TREE_OPERAND (save_expr, 0) = method_decl;
7722 method_decl = ret_decl;
7724 /* Fool the parser into thinking it is starting a function. */
7725 start_function (decl_specs, method_decl, NULL_TREE);
7727 /* Unhook: this has the effect of restoring the abstract declarator. */
7728 TREE_OPERAND (save_expr, 0) = NULL_TREE;
7733 TREE_VALUE (TREE_TYPE (method)) = method_decl;
7735 /* Fool the parser into thinking it is starting a function. */
7736 start_function (decl_specs, method_decl, NULL_TREE);
7738 /* Unhook: this has the effect of restoring the abstract declarator. */
7739 TREE_VALUE (TREE_TYPE (method)) = NULL_TREE;
7743 /* set self_decl from the first argument...this global is used by
7744 * build_ivar_reference().build_indirect_ref().
7746 self_decl = DECL_ARGUMENTS (current_function_decl);
7748 /* snaroff (3/28/96): when compiling with -Wall, this suppresses
7749 * the following: warning:unused parameter `struct objc_selector * _cmd'
7751 TREE_USED (self_decl) = 1;
7752 TREE_USED (TREE_CHAIN (self_decl)) = 1;
7753 /* Ditto for the underlying (static) C function. */
7754 TREE_USED (current_function_decl) = 1;
7755 pop_lang_context ();
7758 METHOD_DEFINITION (method) = current_function_decl;
7760 /* Check consistency...start_function, pushdecl, duplicate_decls. */
7762 if (implementation_template != objc_implementation_context)
7765 = lookup_method_static (implementation_template,
7766 METHOD_SEL_NAME (method),
7767 TREE_CODE (method) == CLASS_METHOD_DECL);
7771 if (!comp_method_with_proto (method, proto))
7773 char type = (TREE_CODE (method) == INSTANCE_METHOD_DECL ? '-' : '+');
7775 warn_with_method ("conflicting types for", type, method);
7776 warn_with_method ("previous declaration of", type, proto);
7781 /* We have a method @implementation even though we did not
7782 see a corresponding @interface declaration (which is allowed
7783 by Objective-C rules). Go ahead and place the method in
7784 the @interface anyway, so that message dispatch lookups
7786 tree interface = implementation_template;
7788 if (TREE_CODE (objc_implementation_context)
7789 == CATEGORY_IMPLEMENTATION_TYPE)
7790 interface = lookup_category
7792 CLASS_SUPER_NAME (objc_implementation_context));
7795 objc_add_method (interface, copy_node (method),
7796 TREE_CODE (method) == CLASS_METHOD_DECL);
7801 /* The following routine is always called...this "architecture" is to
7802 accommodate "old-style" variable length selectors.
7804 - a:a b:b // prototype ; id c; id d; // old-style. */
7807 continue_method_def (void)
7811 if (METHOD_ADD_ARGS (objc_method_context) == objc_ellipsis_node)
7812 /* We have a `, ...' immediately following the selector. */
7813 parmlist = get_parm_info (/*ellipsis=*/true);
7815 parmlist = get_parm_info (/*ellipsis=*/false);
7818 /* Set self_decl from the first argument...this global is used by
7819 build_ivar_reference calling build_indirect_ref. */
7820 self_decl = TREE_PURPOSE (parmlist);
7821 #endif /* !OBJCPLUS */
7824 really_start_method (objc_method_context, parmlist);
7825 store_parm_decls ();
7828 static void *UOBJC_SUPER_scope = 0;
7830 /* _n_Method (id self, SEL sel, ...)
7832 struct objc_super _S;
7833 _msgSuper ((_S.self = self, _S.class = _cls, &_S), ...);
7837 get_super_receiver (void)
7839 if (objc_method_context)
7841 tree super_expr, super_expr_list;
7843 if (!UOBJC_SUPER_decl)
7845 UOBJC_SUPER_decl = start_decl (get_identifier (TAG_SUPER),
7846 build_tree_list (NULL_TREE,
7847 objc_super_template),
7850 finish_decl (UOBJC_SUPER_decl, NULL_TREE, NULL_TREE);
7852 /* This prevents `unused variable' warnings when compiling with -Wall. */
7853 TREE_USED (UOBJC_SUPER_decl) = 1;
7854 DECL_ARTIFICIAL (UOBJC_SUPER_decl) = 1;
7856 UOBJC_SUPER_scope = objc_get_current_scope ();
7859 /* Set receiver to self. */
7860 super_expr = build_component_ref (UOBJC_SUPER_decl, self_id);
7861 super_expr = build_modify_expr (super_expr, NOP_EXPR, self_decl);
7862 super_expr_list = super_expr;
7864 /* Set class to begin searching. */
7866 super_expr = build_component_ref (UOBJC_SUPER_decl,
7867 get_identifier ("super_class"));
7869 super_expr = build_component_ref (UOBJC_SUPER_decl,
7870 get_identifier ("class"));
7873 if (TREE_CODE (objc_implementation_context) == CLASS_IMPLEMENTATION_TYPE)
7875 /* [_cls, __cls]Super are "pre-built" in
7876 synth_forward_declarations. */
7878 super_expr = build_modify_expr (super_expr, NOP_EXPR,
7879 ((TREE_CODE (objc_method_context)
7880 == INSTANCE_METHOD_DECL)
7882 : uucls_super_ref));
7886 /* We have a category. */
7888 tree super_name = CLASS_SUPER_NAME (implementation_template);
7891 /* Barf if super used in a category of Object. */
7894 error ("no super class declared in interface for `%s'",
7895 IDENTIFIER_POINTER (CLASS_NAME (implementation_template)));
7896 return error_mark_node;
7899 if (flag_next_runtime && !flag_zero_link)
7901 super_class = get_class_reference (super_name);
7902 if (TREE_CODE (objc_method_context) == CLASS_METHOD_DECL)
7903 /* If we are in a class method, we must retrieve the
7904 _metaclass_ for the current class, pointed at by
7905 the class's "isa" pointer. The following assumes that
7906 "isa" is the first ivar in a class (which it must be). */
7908 = build_indirect_ref
7909 (build_c_cast (build_pointer_type (objc_class_type),
7910 super_class), "unary *");
7914 add_class_reference (super_name);
7915 super_class = (TREE_CODE (objc_method_context) == INSTANCE_METHOD_DECL
7916 ? objc_get_class_decl : objc_get_meta_class_decl);
7917 assemble_external (super_class);
7919 = build_function_call
7923 my_build_string (IDENTIFIER_LENGTH (super_name) + 1,
7924 IDENTIFIER_POINTER (super_name))));
7928 = build_modify_expr (super_expr, NOP_EXPR,
7929 build_c_cast (TREE_TYPE (super_expr),
7933 super_expr_list = build_compound_expr (super_expr_list, super_expr);
7935 super_expr = build_unary_op (ADDR_EXPR, UOBJC_SUPER_decl, 0);
7936 super_expr_list = build_compound_expr (super_expr_list, super_expr);
7938 return super_expr_list;
7942 error ("[super ...] must appear in a method context");
7943 return error_mark_node;
7947 /* When exiting a scope, sever links to a 'super' declaration (if any)
7948 therein contained. */
7951 objc_clear_super_receiver (void)
7953 if (objc_method_context
7954 && UOBJC_SUPER_scope == objc_get_current_scope ()) {
7955 UOBJC_SUPER_decl = 0;
7956 UOBJC_SUPER_scope = 0;
7961 objc_expand_function_end (void)
7963 /* This routine may also get called for C functions, including those
7964 nested within ObjC methods. In such cases, method encoding is
7966 if (objc_method_context == NULL_TREE
7967 || DECL_INITIAL (objc_method_context) != current_function_decl)
7970 METHOD_ENCODING (objc_method_context)
7971 = encode_method_prototype (objc_method_context);
7975 finish_method_def (void)
7977 lang_expand_function_end = objc_expand_function_end;
7978 /* We cannot validly inline ObjC methods, at least not without a language
7979 extension to declare that a method need not be dynamically
7980 dispatched, so suppress all thoughts of doing so. */
7981 DECL_INLINE (current_function_decl) = 0;
7982 DECL_UNINLINABLE (current_function_decl) = 1;
7985 lang_expand_function_end = NULL;
7987 /* Required to implement _msgSuper. This must be done AFTER finish_function,
7988 since the optimizer may find "may be used before set" errors. */
7989 objc_method_context = NULL_TREE;
7994 lang_report_error_function (tree decl)
7996 if (objc_method_context)
7998 fprintf (stderr, "In method `%s'\n",
7999 IDENTIFIER_POINTER (METHOD_SEL_NAME (objc_method_context)));
8009 is_complex_decl (tree type)
8011 return (TREE_CODE (type) == ARRAY_TYPE
8012 || TREE_CODE (type) == FUNCTION_TYPE
8013 || (TREE_CODE (type) == POINTER_TYPE && ! IS_ID (type)));
8017 /* Code to convert a decl node into text for a declaration in C. */
8019 static char tmpbuf[256];
8022 adorn_decl (tree decl, char *str)
8024 enum tree_code code = TREE_CODE (decl);
8026 if (code == ARRAY_REF)
8028 tree an_int_cst = TREE_OPERAND (decl, 1);
8030 if (an_int_cst && TREE_CODE (an_int_cst) == INTEGER_CST)
8031 sprintf (str + strlen (str), "[%ld]",
8032 (long) TREE_INT_CST_LOW (an_int_cst));
8037 else if (code == ARRAY_TYPE)
8039 tree an_int_cst = TYPE_SIZE (decl);
8040 tree array_of = TREE_TYPE (decl);
8042 if (an_int_cst && TREE_CODE (an_int_cst) == INTEGER_TYPE)
8043 sprintf (str + strlen (str), "[%ld]",
8044 (long) (TREE_INT_CST_LOW (an_int_cst)
8045 / TREE_INT_CST_LOW (TYPE_SIZE (array_of))));
8050 else if (code == CALL_EXPR)
8052 tree chain = TREE_PURPOSE (TREE_OPERAND (decl, 1));
8057 gen_declaration_1 (chain, str);
8058 chain = TREE_CHAIN (chain);
8065 else if (code == FUNCTION_TYPE)
8067 tree chain = TYPE_ARG_TYPES (decl);
8070 while (chain && TREE_VALUE (chain) != void_type_node)
8072 gen_declaration_1 (TREE_VALUE (chain), str);
8073 chain = TREE_CHAIN (chain);
8074 if (chain && TREE_VALUE (chain) != void_type_node)
8080 else if (code == INDIRECT_REF)
8082 strcpy (tmpbuf, "*");
8083 if (TREE_TYPE (decl) && TREE_CODE (TREE_TYPE (decl)) == TREE_LIST)
8087 for (chain = nreverse (copy_list (TREE_TYPE (decl)));
8089 chain = TREE_CHAIN (chain))
8091 if (TREE_CODE (TREE_VALUE (chain)) == IDENTIFIER_NODE)
8093 strcat (tmpbuf, " ");
8094 strcat (tmpbuf, IDENTIFIER_POINTER (TREE_VALUE (chain)));
8098 strcat (tmpbuf, " ");
8100 strcat (tmpbuf, str);
8101 strcpy (str, tmpbuf);
8104 else if (code == POINTER_TYPE)
8106 strcpy (tmpbuf, "*");
8107 if (TYPE_READONLY (decl) || TYPE_VOLATILE (decl))
8109 if (TYPE_READONLY (decl))
8110 strcat (tmpbuf, " const");
8111 if (TYPE_VOLATILE (decl))
8112 strcat (tmpbuf, " volatile");
8114 strcat (tmpbuf, " ");
8116 strcat (tmpbuf, str);
8117 strcpy (str, tmpbuf);
8122 gen_declarator (tree decl, char *buf, const char *name)
8126 enum tree_code code = TREE_CODE (decl);
8136 op = TREE_OPERAND (decl, 0);
8138 /* We have a pointer to a function or array...(*)(), (*)[] */
8139 if ((code == ARRAY_REF || code == CALL_EXPR)
8140 && op && TREE_CODE (op) == INDIRECT_REF)
8143 str = gen_declarator (op, buf, name);
8147 strcpy (tmpbuf, "(");
8148 strcat (tmpbuf, str);
8149 strcat (tmpbuf, ")");
8150 strcpy (str, tmpbuf);
8153 adorn_decl (decl, str);
8162 /* This clause is done iteratively rather than recursively. */
8165 op = (is_complex_decl (TREE_TYPE (decl))
8166 ? TREE_TYPE (decl) : NULL_TREE);
8168 adorn_decl (decl, str);
8170 /* We have a pointer to a function or array...(*)(), (*)[] */
8171 if (code == POINTER_TYPE
8172 && op && (TREE_CODE (op) == FUNCTION_TYPE
8173 || TREE_CODE (op) == ARRAY_TYPE))
8175 strcpy (tmpbuf, "(");
8176 strcat (tmpbuf, str);
8177 strcat (tmpbuf, ")");
8178 strcpy (str, tmpbuf);
8181 decl = (is_complex_decl (TREE_TYPE (decl))
8182 ? TREE_TYPE (decl) : NULL_TREE);
8185 while (decl && (code = TREE_CODE (decl)))
8190 case IDENTIFIER_NODE:
8191 /* Will only happen if we are processing a "raw" expr-decl. */
8192 strcpy (buf, IDENTIFIER_POINTER (decl));
8203 /* We have an abstract declarator or a _DECL node. */
8211 gen_declspecs (tree declspecs, char *buf, int raw)
8217 for (chain = nreverse (copy_list (declspecs));
8218 chain; chain = TREE_CHAIN (chain))
8220 tree aspec = TREE_VALUE (chain);
8222 if (TREE_CODE (aspec) == IDENTIFIER_NODE)
8223 strcat (buf, IDENTIFIER_POINTER (aspec));
8224 else if (TREE_CODE (aspec) == RECORD_TYPE)
8226 if (OBJC_TYPE_NAME (aspec))
8228 tree protocol_list = TYPE_PROTOCOL_LIST (aspec);
8230 if (! TREE_STATIC_TEMPLATE (aspec))
8231 strcat (buf, "struct ");
8232 strcat (buf, IDENTIFIER_POINTER (OBJC_TYPE_NAME (aspec)));
8237 tree chain = protocol_list;
8244 (PROTOCOL_NAME (TREE_VALUE (chain))));
8245 chain = TREE_CHAIN (chain);
8254 strcat (buf, "untagged struct");
8257 else if (TREE_CODE (aspec) == UNION_TYPE)
8259 if (OBJC_TYPE_NAME (aspec))
8261 if (! TREE_STATIC_TEMPLATE (aspec))
8262 strcat (buf, "union ");
8263 strcat (buf, IDENTIFIER_POINTER (OBJC_TYPE_NAME (aspec)));
8266 strcat (buf, "untagged union");
8269 else if (TREE_CODE (aspec) == ENUMERAL_TYPE)
8271 if (OBJC_TYPE_NAME (aspec))
8273 if (! TREE_STATIC_TEMPLATE (aspec))
8274 strcat (buf, "enum ");
8275 strcat (buf, IDENTIFIER_POINTER (OBJC_TYPE_NAME (aspec)));
8278 strcat (buf, "untagged enum");
8281 else if (TREE_CODE (aspec) == TYPE_DECL && DECL_NAME (aspec))
8282 strcat (buf, IDENTIFIER_POINTER (DECL_NAME (aspec)));
8284 else if (IS_ID (aspec))
8286 tree protocol_list = TYPE_PROTOCOL_LIST (aspec);
8291 tree chain = protocol_list;
8298 (PROTOCOL_NAME (TREE_VALUE (chain))));
8299 chain = TREE_CHAIN (chain);
8306 if (TREE_CHAIN (chain))
8312 /* Type qualifiers. */
8313 if (TYPE_READONLY (declspecs))
8314 strcat (buf, "const ");
8315 if (TYPE_VOLATILE (declspecs))
8316 strcat (buf, "volatile ");
8318 switch (TREE_CODE (declspecs))
8320 /* Type specifiers. */
8323 declspecs = TYPE_MAIN_VARIANT (declspecs);
8325 /* Signed integer types. */
8327 if (declspecs == short_integer_type_node)
8328 strcat (buf, "short int ");
8329 else if (declspecs == integer_type_node)
8330 strcat (buf, "int ");
8331 else if (declspecs == long_integer_type_node)
8332 strcat (buf, "long int ");
8333 else if (declspecs == long_long_integer_type_node)
8334 strcat (buf, "long long int ");
8335 else if (declspecs == signed_char_type_node
8336 || declspecs == char_type_node)
8337 strcat (buf, "char ");
8339 /* Unsigned integer types. */
8341 else if (declspecs == short_unsigned_type_node)
8342 strcat (buf, "unsigned short ");
8343 else if (declspecs == unsigned_type_node)
8344 strcat (buf, "unsigned int ");
8345 else if (declspecs == long_unsigned_type_node)
8346 strcat (buf, "unsigned long ");
8347 else if (declspecs == long_long_unsigned_type_node)
8348 strcat (buf, "unsigned long long ");
8349 else if (declspecs == unsigned_char_type_node)
8350 strcat (buf, "unsigned char ");
8354 declspecs = TYPE_MAIN_VARIANT (declspecs);
8356 if (declspecs == float_type_node)
8357 strcat (buf, "float ");
8358 else if (declspecs == double_type_node)
8359 strcat (buf, "double ");
8360 else if (declspecs == long_double_type_node)
8361 strcat (buf, "long double ");
8365 if (OBJC_TYPE_NAME (declspecs)
8366 && TREE_CODE (OBJC_TYPE_NAME (declspecs)) == IDENTIFIER_NODE)
8368 tree protocol_list = TYPE_PROTOCOL_LIST (declspecs);
8370 if (! TREE_STATIC_TEMPLATE (declspecs))
8371 strcat (buf, "struct ");
8372 strcat (buf, IDENTIFIER_POINTER (OBJC_TYPE_NAME (declspecs)));
8376 tree chain = protocol_list;
8383 (PROTOCOL_NAME (TREE_VALUE (chain))));
8384 chain = TREE_CHAIN (chain);
8393 strcat (buf, "untagged struct");
8399 if (OBJC_TYPE_NAME (declspecs)
8400 && TREE_CODE (OBJC_TYPE_NAME (declspecs)) == IDENTIFIER_NODE)
8402 strcat (buf, "union ");
8403 strcat (buf, IDENTIFIER_POINTER (OBJC_TYPE_NAME (declspecs)));
8408 strcat (buf, "untagged union ");
8412 if (OBJC_TYPE_NAME (declspecs)
8413 && TREE_CODE (OBJC_TYPE_NAME (declspecs)) == IDENTIFIER_NODE)
8415 strcat (buf, "enum ");
8416 strcat (buf, IDENTIFIER_POINTER (OBJC_TYPE_NAME (declspecs)));
8421 strcat (buf, "untagged enum ");
8425 strcat (buf, "void ");
8430 tree protocol_list = TYPE_PROTOCOL_LIST (declspecs);
8435 tree chain = protocol_list;
8442 (PROTOCOL_NAME (TREE_VALUE (chain))));
8443 chain = TREE_CHAIN (chain);
8459 /* Given a tree node, produce a printable description of it in the given
8460 buffer, overwriting the buffer. */
8463 gen_declaration (tree atype_or_adecl, char *buf)
8466 gen_declaration_1 (atype_or_adecl, buf);
8470 /* Given a tree node, append a printable description to the end of the
8474 gen_declaration_1 (tree atype_or_adecl, char *buf)
8478 if (TREE_CODE (atype_or_adecl) == TREE_LIST)
8480 tree declspecs; /* "identifier_node", "record_type" */
8481 tree declarator; /* "array_ref", "indirect_ref", "call_expr"... */
8482 tree width = NULL_TREE; /* for bitfields */
8484 /* We have a "raw", abstract declarator (typename). */
8485 declarator = TREE_VALUE (atype_or_adecl);
8486 /* In the case of raw ivars, the declarator itself is a list,
8487 and contains bitfield widths. */
8488 if (declarator && TREE_CODE (declarator) == TREE_LIST)
8490 width = TREE_VALUE (declarator);
8491 declarator = TREE_PURPOSE (declarator);
8493 declspecs = TREE_PURPOSE (atype_or_adecl);
8495 gen_declspecs (declspecs, buf, 1);
8499 strcat (buf, gen_declarator (declarator, declbuf, ""));
8502 sprintf (buf + strlen (buf), ": " HOST_WIDE_INT_PRINT_UNSIGNED,
8503 TREE_INT_CST_LOW (width));
8509 tree declspecs; /* "integer_type", "real_type", "record_type"... */
8510 tree declarator; /* "array_type", "function_type", "pointer_type". */
8512 if (TREE_CODE (atype_or_adecl) == FIELD_DECL
8513 || TREE_CODE (atype_or_adecl) == PARM_DECL
8514 || TREE_CODE (atype_or_adecl) == FUNCTION_DECL)
8515 atype = TREE_TYPE (atype_or_adecl);
8517 /* Assume we have a *_type node. */
8518 atype = atype_or_adecl;
8520 if (is_complex_decl (atype))
8524 /* Get the declaration specifier; it is at the end of the list. */
8525 declarator = chain = atype;
8527 chain = TREE_TYPE (chain); /* not TREE_CHAIN (chain); */
8528 while (is_complex_decl (chain));
8535 declarator = NULL_TREE;
8538 gen_declspecs (declspecs, buf, 0);
8540 if (TREE_CODE (atype_or_adecl) == FIELD_DECL
8541 || TREE_CODE (atype_or_adecl) == PARM_DECL
8542 || TREE_CODE (atype_or_adecl) == FUNCTION_DECL)
8544 const char *const decl_name =
8545 (DECL_NAME (atype_or_adecl)
8546 ? IDENTIFIER_POINTER (DECL_NAME (atype_or_adecl)) : "");
8551 strcat (buf, gen_declarator (declarator, declbuf, decl_name));
8554 else if (decl_name[0])
8557 strcat (buf, decl_name);
8560 else if (declarator)
8563 strcat (buf, gen_declarator (declarator, declbuf, ""));
8568 #define RAW_TYPESPEC(meth) (TREE_VALUE (TREE_PURPOSE (TREE_TYPE (meth))))
8570 /* Given a method tree, put a printable description into the given
8571 buffer (overwriting) and return a pointer to the buffer. */
8574 gen_method_decl (tree method, char *buf)
8579 if (RAW_TYPESPEC (method) != objc_object_reference)
8582 gen_declaration_1 (TREE_TYPE (method), buf);
8586 chain = METHOD_SEL_ARGS (method);
8589 /* We have a chain of keyword_decls. */
8592 if (KEYWORD_KEY_NAME (chain))
8593 strcat (buf, IDENTIFIER_POINTER (KEYWORD_KEY_NAME (chain)));
8596 if (RAW_TYPESPEC (chain) != objc_object_reference)
8599 gen_declaration_1 (TREE_TYPE (chain), buf);
8603 strcat (buf, IDENTIFIER_POINTER (KEYWORD_ARG_NAME (chain)));
8604 if ((chain = TREE_CHAIN (chain)))
8609 if (METHOD_ADD_ARGS (method) == objc_ellipsis_node)
8610 strcat (buf, ", ...");
8611 else if (METHOD_ADD_ARGS (method))
8613 /* We have a tree list node as generate by get_parm_info. */
8614 chain = TREE_PURPOSE (METHOD_ADD_ARGS (method));
8616 /* Know we have a chain of parm_decls. */
8620 gen_declaration_1 (chain, buf);
8621 chain = TREE_CHAIN (chain);
8627 /* We have a unary selector. */
8628 strcat (buf, IDENTIFIER_POINTER (METHOD_SEL_NAME (method)));
8636 /* Dump an @interface declaration of the supplied class CHAIN to the
8637 supplied file FP. Used to implement the -gen-decls option (which
8638 prints out an @interface declaration of all classes compiled in
8639 this run); potentially useful for debugging the compiler too. */
8641 dump_interface (FILE *fp, tree chain)
8643 /* FIXME: A heap overflow here whenever a method (or ivar)
8644 declaration is so long that it doesn't fit in the buffer. The
8645 code and all the related functions should be rewritten to avoid
8646 using fixed size buffers. */
8647 char *buf = (char *) xmalloc (1024 * 10);
8648 const char *my_name = IDENTIFIER_POINTER (CLASS_NAME (chain));
8649 tree ivar_decls = CLASS_RAW_IVARS (chain);
8650 tree nst_methods = CLASS_NST_METHODS (chain);
8651 tree cls_methods = CLASS_CLS_METHODS (chain);
8653 fprintf (fp, "\n@interface %s", my_name);
8655 /* CLASS_SUPER_NAME is used to store the superclass name for
8656 classes, and the category name for categories. */
8657 if (CLASS_SUPER_NAME (chain))
8659 const char *name = IDENTIFIER_POINTER (CLASS_SUPER_NAME (chain));
8661 if (TREE_CODE (chain) == CATEGORY_IMPLEMENTATION_TYPE
8662 || TREE_CODE (chain) == CATEGORY_INTERFACE_TYPE)
8664 fprintf (fp, " (%s)\n", name);
8668 fprintf (fp, " : %s\n", name);
8674 /* FIXME - the following doesn't seem to work at the moment. */
8677 fprintf (fp, "{\n");
8680 fprintf (fp, "\t%s;\n", gen_declaration (ivar_decls, buf));
8681 ivar_decls = TREE_CHAIN (ivar_decls);
8684 fprintf (fp, "}\n");
8689 fprintf (fp, "- %s;\n", gen_method_decl (nst_methods, buf));
8690 nst_methods = TREE_CHAIN (nst_methods);
8695 fprintf (fp, "+ %s;\n", gen_method_decl (cls_methods, buf));
8696 cls_methods = TREE_CHAIN (cls_methods);
8699 fprintf (fp, "@end\n");
8702 /* Demangle function for Objective-C */
8704 objc_demangle (const char *mangled)
8706 char *demangled, *cp;
8708 if (mangled[0] == '_' &&
8709 (mangled[1] == 'i' || mangled[1] == 'c') &&
8712 cp = demangled = xmalloc(strlen(mangled) + 2);
8713 if (mangled[1] == 'i')
8714 *cp++ = '-'; /* for instance method */
8716 *cp++ = '+'; /* for class method */
8717 *cp++ = '['; /* opening left brace */
8718 strcpy(cp, mangled+3); /* tack on the rest of the mangled name */
8719 while (*cp && *cp == '_')
8720 cp++; /* skip any initial underbars in class name */
8721 cp = strchr(cp, '_'); /* find first non-initial underbar */
8724 free(demangled); /* not mangled name */
8727 if (cp[1] == '_') /* easy case: no category name */
8729 *cp++ = ' '; /* replace two '_' with one ' ' */
8730 strcpy(cp, mangled + (cp - demangled) + 2);
8734 *cp++ = '('; /* less easy case: category name */
8735 cp = strchr(cp, '_');
8738 free(demangled); /* not mangled name */
8742 *cp++ = ' '; /* overwriting 1st char of method name... */
8743 strcpy(cp, mangled + (cp - demangled)); /* get it back */
8745 while (*cp && *cp == '_')
8746 cp++; /* skip any initial underbars in method name */
8749 *cp = ':'; /* replace remaining '_' with ':' */
8750 *cp++ = ']'; /* closing right brace */
8751 *cp++ = 0; /* string terminator */
8755 return mangled; /* not an objc mangled name */
8759 objc_printable_name (tree decl, int kind ATTRIBUTE_UNUSED)
8761 return objc_demangle (IDENTIFIER_POINTER (DECL_NAME (decl)));
8767 gcc_obstack_init (&util_obstack);
8768 util_firstobj = (char *) obstack_finish (&util_obstack);
8770 errbuf = (char *) xmalloc (BUFSIZE);
8772 synth_module_prologue ();
8778 struct imp_entry *impent;
8780 /* The internally generated initializers appear to have missing braces.
8781 Don't warn about this. */
8782 int save_warn_missing_braces = warn_missing_braces;
8783 warn_missing_braces = 0;
8785 /* A missing @end may not be detected by the parser. */
8786 if (objc_implementation_context)
8788 warning ("`@end' missing in implementation context");
8789 finish_class (objc_implementation_context);
8790 objc_ivar_chain = NULL_TREE;
8791 objc_implementation_context = NULL_TREE;
8794 /* Process the static instances here because initialization of objc_symtab
8796 if (objc_static_instances)
8797 generate_static_references ();
8799 if (imp_list || class_names_chain
8800 || meth_var_names_chain || meth_var_types_chain || sel_ref_chain)
8801 generate_objc_symtab_decl ();
8803 for (impent = imp_list; impent; impent = impent->next)
8805 objc_implementation_context = impent->imp_context;
8806 implementation_template = impent->imp_template;
8808 UOBJC_CLASS_decl = impent->class_decl;
8809 UOBJC_METACLASS_decl = impent->meta_decl;
8811 /* Dump the @interface of each class as we compile it, if the
8812 -gen-decls option is in use. TODO: Dump the classes in the
8813 order they were found, rather than in reverse order as we
8815 if (flag_gen_declaration)
8817 dump_interface (gen_declaration_file, objc_implementation_context);
8820 if (TREE_CODE (objc_implementation_context) == CLASS_IMPLEMENTATION_TYPE)
8822 /* all of the following reference the string pool... */
8823 generate_ivar_lists ();
8824 generate_dispatch_tables ();
8825 generate_shared_structures ();
8829 generate_dispatch_tables ();
8830 generate_category (objc_implementation_context);
8834 /* If we are using an array of selectors, we must always
8835 finish up the array decl even if no selectors were used. */
8836 if (! flag_next_runtime || sel_ref_chain)
8837 build_selector_translation_table ();
8840 generate_protocols ();
8842 if (flag_replace_objc_classes && imp_list)
8843 generate_objc_image_info ();
8845 if (objc_implementation_context || class_names_chain || objc_static_instances
8846 || meth_var_names_chain || meth_var_types_chain || sel_ref_chain)
8848 /* Arrange for ObjC data structures to be initialized at run time. */
8849 rtx init_sym = build_module_descriptor ();
8850 if (init_sym && targetm.have_ctors_dtors)
8851 (* targetm.asm_out.constructor) (init_sym, DEFAULT_INIT_PRIORITY);
8854 /* Dump the class references. This forces the appropriate classes
8855 to be linked into the executable image, preserving unix archive
8856 semantics. This can be removed when we move to a more dynamically
8857 linked environment. */
8859 for (chain = cls_ref_chain; chain; chain = TREE_CHAIN (chain))
8861 handle_class_ref (chain);
8862 if (TREE_PURPOSE (chain))
8863 generate_classref_translation_entry (chain);
8866 for (impent = imp_list; impent; impent = impent->next)
8867 handle_impent (impent);
8869 /* Dump the string table last. */
8871 generate_strings ();
8878 /* Run through the selector hash tables and print a warning for any
8879 selector which has multiple methods. */
8881 for (slot = 0; slot < SIZEHASHTABLE; slot++)
8883 for (hsh = cls_method_hash_list[slot]; hsh; hsh = hsh->next)
8884 check_duplicates (hsh, 0, 1);
8885 for (hsh = nst_method_hash_list[slot]; hsh; hsh = hsh->next)
8886 check_duplicates (hsh, 0, 1);
8890 warn_missing_braces = save_warn_missing_braces;
8893 /* Subroutines of finish_objc. */
8896 generate_classref_translation_entry (tree chain)
8898 tree expr, name, decl_specs, decl, sc_spec;
8901 type = TREE_TYPE (TREE_PURPOSE (chain));
8903 expr = add_objc_string (TREE_VALUE (chain), class_names);
8904 expr = build_c_cast (type, expr); /* cast! */
8906 name = DECL_NAME (TREE_PURPOSE (chain));
8908 sc_spec = build_tree_list (NULL_TREE, ridpointers[(int) RID_STATIC]);
8910 /* static struct objc_class * _OBJC_CLASS_REFERENCES_n = ...; */
8911 decl_specs = tree_cons (NULL_TREE, type, sc_spec);
8913 /* The decl that is returned from start_decl is the one that we
8914 forward declared in build_class_reference. */
8915 decl = start_decl (name, decl_specs, 1, NULL_TREE);
8916 DECL_CONTEXT (decl) = NULL_TREE;
8917 finish_decl (decl, expr, NULL_TREE);
8922 handle_class_ref (tree chain)
8924 const char *name = IDENTIFIER_POINTER (TREE_VALUE (chain));
8925 char *string = (char *) alloca (strlen (name) + 30);
8929 sprintf (string, "%sobjc_class_name_%s",
8930 (flag_next_runtime ? "." : "__"), name);
8932 #ifdef ASM_DECLARE_UNRESOLVED_REFERENCE
8933 if (flag_next_runtime)
8935 ASM_DECLARE_UNRESOLVED_REFERENCE (asm_out_file, string);
8940 /* Make a decl for this name, so we can use its address in a tree. */
8941 decl = build_decl (VAR_DECL, get_identifier (string), char_type_node);
8942 DECL_EXTERNAL (decl) = 1;
8943 TREE_PUBLIC (decl) = 1;
8946 rest_of_decl_compilation (decl, 0, 0);
8948 /* Make a decl for the address. */
8949 sprintf (string, "%sobjc_class_ref_%s",
8950 (flag_next_runtime ? "." : "__"), name);
8951 exp = build1 (ADDR_EXPR, string_type_node, decl);
8952 decl = build_decl (VAR_DECL, get_identifier (string), string_type_node);
8953 DECL_INITIAL (decl) = exp;
8954 TREE_STATIC (decl) = 1;
8955 TREE_USED (decl) = 1;
8958 rest_of_decl_compilation (decl, 0, 0);
8962 handle_impent (struct imp_entry *impent)
8966 objc_implementation_context = impent->imp_context;
8967 implementation_template = impent->imp_template;
8969 if (TREE_CODE (impent->imp_context) == CLASS_IMPLEMENTATION_TYPE)
8971 const char *const class_name =
8972 IDENTIFIER_POINTER (CLASS_NAME (impent->imp_context));
8974 string = (char *) alloca (strlen (class_name) + 30);
8976 sprintf (string, "%sobjc_class_name_%s",
8977 (flag_next_runtime ? "." : "__"), class_name);
8979 else if (TREE_CODE (impent->imp_context) == CATEGORY_IMPLEMENTATION_TYPE)
8981 const char *const class_name =
8982 IDENTIFIER_POINTER (CLASS_NAME (impent->imp_context));
8983 const char *const class_super_name =
8984 IDENTIFIER_POINTER (CLASS_SUPER_NAME (impent->imp_context));
8986 string = (char *) alloca (strlen (class_name)
8987 + strlen (class_super_name) + 30);
8989 /* Do the same for categories. Even though no references to
8990 these symbols are generated automatically by the compiler, it
8991 gives you a handle to pull them into an archive by hand. */
8992 sprintf (string, "*%sobjc_category_name_%s_%s",
8993 (flag_next_runtime ? "." : "__"), class_name, class_super_name);
8998 #ifdef ASM_DECLARE_CLASS_REFERENCE
8999 if (flag_next_runtime)
9001 ASM_DECLARE_CLASS_REFERENCE (asm_out_file, string);
9009 init = build_int_cst (c_common_type_for_size (BITS_PER_WORD, 1), 0);
9010 decl = build_decl (VAR_DECL, get_identifier (string), TREE_TYPE (init));
9011 TREE_PUBLIC (decl) = 1;
9012 TREE_READONLY (decl) = 1;
9013 TREE_USED (decl) = 1;
9014 TREE_CONSTANT (decl) = 1;
9015 DECL_CONTEXT (decl) = 0;
9016 DECL_ARTIFICIAL (decl) = 1;
9017 DECL_INITIAL (decl) = init;
9018 assemble_variable (decl, 1, 0, 0);
9022 /* The Fix-and-Continue functionality available in Mac OS X 10.3 and
9023 later requires that ObjC translation units participating in F&C be
9024 specially marked. The following routine accomplishes this. */
9026 /* static int _OBJC_IMAGE_INFO[2] = { 0, 1 }; */
9029 generate_objc_image_info (void)
9031 tree sc_spec, decl, initlist;
9033 sc_spec = build_tree_list (NULL_TREE, ridpointers[(int) RID_STATIC]);
9035 = start_decl (get_identifier ("_OBJC_IMAGE_INFO"),
9036 tree_cons (NULL_TREE,
9039 build_index_type (build_int_cst (NULL_TREE, 1))),
9044 initlist = build_tree_list (NULL_TREE, build_int_cst (NULL_TREE, 0));
9045 initlist = tree_cons (NULL_TREE, build_int_cst (NULL_TREE, 1), initlist);
9046 initlist = build_constructor (TREE_TYPE (decl), nreverse (initlist));
9048 TREE_USED (decl) = DECL_IGNORED_P (decl) = DECL_ARTIFICIAL (decl) = 1;
9049 TREE_CONSTANT (initlist) = TREE_STATIC (initlist) = 1;
9050 finish_decl (decl, initlist, NULL_TREE);
9053 /* Look up ID as an instance variable. */
9056 objc_lookup_ivar (tree id)
9060 if (objc_method_context && !strcmp (IDENTIFIER_POINTER (id), "super"))
9061 /* We have a message to super. */
9062 return get_super_receiver ();
9063 else if (objc_method_context && (decl = is_ivar (objc_ivar_chain, id)))
9065 if (is_private (decl))
9068 return build_ivar_reference (id);
9074 #include "gt-objc-objc-act.h"