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"
60 #include "langhooks.h"
71 #include "diagnostic.h"
73 #include "tree-iterator.h"
76 #include "langhooks-def.h"
78 #define OBJC_VOID_AT_END void_list_node
80 /* When building Objective-C++, we are not linking against the C front-end
81 and so need to replicate the C tree-construction functions in some way. */
83 #define OBJCP_REMAP_FUNCTIONS
84 #include "objcp-decl.h"
87 /* This is the default way of generating a method name. */
88 /* I am not sure it is really correct.
89 Perhaps there's a danger that it will make name conflicts
90 if method names contain underscores. -- rms. */
91 #ifndef OBJC_GEN_METHOD_LABEL
92 #define OBJC_GEN_METHOD_LABEL(BUF, IS_INST, CLASS_NAME, CAT_NAME, SEL_NAME, NUM) \
95 sprintf ((BUF), "_%s_%s_%s_%s", \
96 ((IS_INST) ? "i" : "c"), \
98 ((CAT_NAME)? (CAT_NAME) : ""), \
100 for (temp = (BUF); *temp; temp++) \
101 if (*temp == ':') *temp = '_'; \
105 /* These need specifying. */
106 #ifndef OBJC_FORWARDING_STACK_OFFSET
107 #define OBJC_FORWARDING_STACK_OFFSET 0
110 #ifndef OBJC_FORWARDING_MIN_OFFSET
111 #define OBJC_FORWARDING_MIN_OFFSET 0
114 /* Set up for use of obstacks. */
118 /* This obstack is used to accumulate the encoding of a data type. */
119 static struct obstack util_obstack;
121 /* This points to the beginning of obstack contents, so we can free
122 the whole contents. */
125 /* The version identifies which language generation and runtime
126 the module (file) was compiled for, and is recorded in the
127 module descriptor. */
129 #define OBJC_VERSION (flag_next_runtime ? 5 : 8)
130 #define PROTOCOL_VERSION 2
132 /* (Decide if these can ever be validly changed.) */
133 #define OBJC_ENCODE_INLINE_DEFS 0
134 #define OBJC_ENCODE_DONT_INLINE_DEFS 1
136 /*** Private Interface (procedures) ***/
138 /* Used by compile_file. */
140 static void init_objc (void);
141 static void finish_objc (void);
143 /* Code generation. */
145 static void synth_module_prologue (void);
146 static tree objc_build_constructor (tree, tree);
147 static void build_module_descriptor (void);
148 static void build_module_initializer_routine (void);
149 static tree init_module_descriptor (tree);
150 static tree build_objc_method_call (int, tree, tree, tree, tree);
151 static void generate_strings (void);
152 static tree get_proto_encoding (tree);
153 static void build_selector_translation_table (void);
154 static tree lookup_interface (tree);
155 static tree objc_add_static_instance (tree, tree);
157 static tree start_class (enum tree_code, tree, tree, tree);
158 static tree continue_class (tree);
159 static void finish_class (tree);
160 static void start_method_def (tree);
162 static void objc_start_function (tree, tree, tree, tree);
164 static void objc_start_function (tree, tree, tree, struct c_arg_info *);
166 static tree start_protocol (enum tree_code, tree, tree);
167 static tree build_method_decl (enum tree_code, tree, tree, tree);
168 static tree objc_add_method (tree, tree, int);
169 static tree add_instance_variable (tree, int, tree);
170 static tree build_ivar_reference (tree);
171 static tree is_ivar (tree, tree);
172 static int is_private (tree);
173 static tree get_super_receiver (void);
175 static void build_objc_exception_stuff (void);
176 static void build_next_objc_exception_stuff (void);
178 static tree build_ivar_template (void);
179 static tree build_method_template (void);
180 static void build_private_template (tree);
181 static void build_class_template (void);
182 static void build_selector_template (void);
183 static void build_category_template (void);
184 static tree lookup_method_in_hash_lists (tree, int);
185 static void build_super_template (void);
186 static tree build_category_initializer (tree, tree, tree, tree, tree, tree);
187 static tree build_protocol_initializer (tree, tree, tree, tree, tree);
188 static void synth_forward_declarations (void);
189 static int ivar_list_length (tree);
190 static tree get_class_ivars (tree);
191 static void generate_ivar_lists (void);
192 static void generate_dispatch_tables (void);
193 static void generate_shared_structures (void);
194 static tree generate_protocol_list (tree);
195 static void build_protocol_reference (tree);
197 static tree build_keyword_selector (tree);
198 static const char *synth_id_with_class_suffix (const char *, tree);
200 static void generate_static_references (void);
201 static int check_methods_accessible (tree, tree, int);
202 static void encode_aggregate_within (tree, int, int, int, int);
203 static const char *objc_demangle (const char *);
205 /* Hash tables to manage the global pool of method prototypes. */
207 hash *nst_method_hash_list = 0;
208 hash *cls_method_hash_list = 0;
210 static size_t hash_func (tree);
211 static void hash_init (void);
212 static void hash_enter (hash *, tree);
213 static hash hash_lookup (hash *, tree);
214 static void hash_add_attr (hash, tree);
215 static tree lookup_method (tree, tree);
216 static tree lookup_method_static (tree, tree, int);
217 static void add_method_to_hash_list (hash *, tree);
218 static tree add_class (tree);
219 static void add_category (tree, tree);
220 static inline tree lookup_category (tree, tree);
224 class_names, /* class, category, protocol, module names */
225 meth_var_names, /* method and variable names */
226 meth_var_types /* method and variable type descriptors */
229 static tree add_objc_string (tree, enum string_section);
230 static tree get_objc_string_decl (tree, enum string_section);
231 static tree build_objc_string_decl (enum string_section);
232 static tree build_selector_reference_decl (void);
233 static void build_selector_table_decl (void);
235 /* Protocol additions. */
237 static tree add_protocol (tree);
238 static tree lookup_protocol (tree);
239 static void check_protocol_recursively (tree, tree);
240 static tree lookup_and_install_protocols (tree);
244 static void encode_type_qualifiers (tree);
245 static void encode_pointer (tree, int, int);
246 static void encode_array (tree, int, int);
247 static void encode_aggregate (tree, int, int);
248 static void encode_next_bitfield (int);
249 static void encode_gnu_bitfield (int, tree, int);
250 static void encode_type (tree, int, int);
251 static void encode_field_decl (tree, int, int);
254 static void really_start_method (tree, tree);
256 static void really_start_method (tree, struct c_arg_info *);
258 static int objc_types_are_equivalent (tree, tree);
259 static int comp_proto_with_proto (tree, tree);
260 static tree get_arg_type_list (tree, int, int);
261 static void objc_push_parm (tree);
263 static tree objc_get_parm_info (int);
265 static struct c_arg_info *objc_get_parm_info (int);
267 static void synth_self_and_ucmd_args (void);
269 /* Utilities for debugging and error diagnostics. */
271 static void warn_with_method (const char *, int, tree);
272 static void error_with_ivar (const char *, tree);
273 static char *gen_type_name (tree);
274 static char *gen_type_name_0 (tree);
275 static char *gen_method_decl (tree);
276 static char *gen_declaration (tree);
277 static void dump_interface (FILE *, tree);
279 /* Everything else. */
281 static tree lookup_method_in_protocol_list (tree, tree, int);
282 static tree lookup_protocol_in_reflist (tree, tree);
283 static tree start_var_decl (tree, const char *);
284 static void finish_var_decl (tree, tree);
285 static tree create_field_decl (tree, const char *);
286 static tree setup_string_decl (void);
287 static int check_string_class_template (void);
288 static tree my_build_string (int, const char *);
289 static void build_objc_symtab_template (void);
290 static tree init_def_list (tree);
291 static tree init_objc_symtab (tree);
292 static tree build_metadata_decl (const char *, tree);
293 static void forward_declare_categories (void);
294 static void generate_objc_symtab_decl (void);
295 static tree build_selector (tree);
296 static tree build_typed_selector_reference (tree, tree);
297 static tree build_selector_reference (tree);
298 static tree build_class_reference_decl (void);
299 static void add_class_reference (tree);
300 static void build_protocol_template (void);
301 static tree build_descriptor_table_initializer (tree, tree);
302 static tree build_method_prototype_list_template (tree, int);
303 static tree build_method_prototype_template (void);
304 static tree objc_method_parm_type (tree);
305 static int objc_encoded_type_size (tree);
306 static tree encode_method_prototype (tree);
307 static tree generate_descriptor_table (tree, const char *, int, tree, tree);
308 static void generate_method_descriptors (tree);
309 static void generate_protocol_references (tree);
310 static void generate_protocols (void);
311 static void check_ivars (tree, tree);
312 static tree build_ivar_list_template (tree, int);
313 static tree build_method_list_template (tree, int);
314 static tree build_ivar_list_initializer (tree, tree);
315 static tree generate_ivars_list (tree, const char *, int, tree);
316 static tree build_dispatch_table_initializer (tree, tree);
317 static tree generate_dispatch_table (tree, const char *, int, tree);
318 static tree build_shared_structure_initializer (tree, tree, tree, tree,
319 tree, int, tree, tree, tree);
320 static void generate_category (tree);
321 static tree adjust_type_for_id_default (tree);
322 static tree check_duplicates (hash, int, int);
323 static tree receiver_is_class_object (tree, int, int);
324 static int check_methods (tree, tree, int);
325 static int conforms_to_protocol (tree, tree);
326 static void check_protocol (tree, const char *, const char *);
327 static void check_protocols (tree, const char *, const char *);
328 static void generate_classref_translation_entry (tree);
329 static void handle_class_ref (tree);
330 static void generate_struct_by_value_array (void)
332 static void mark_referenced_methods (void);
333 static void generate_objc_image_info (void);
335 /*** Private Interface (data) ***/
337 /* Reserved tag definitions. */
339 #define OBJECT_TYPEDEF_NAME "id"
340 #define CLASS_TYPEDEF_NAME "Class"
342 #define TAG_OBJECT "objc_object"
343 #define TAG_CLASS "objc_class"
344 #define TAG_SUPER "objc_super"
345 #define TAG_SELECTOR "objc_selector"
347 #define UTAG_CLASS "_objc_class"
348 #define UTAG_IVAR "_objc_ivar"
349 #define UTAG_IVAR_LIST "_objc_ivar_list"
350 #define UTAG_METHOD "_objc_method"
351 #define UTAG_METHOD_LIST "_objc_method_list"
352 #define UTAG_CATEGORY "_objc_category"
353 #define UTAG_MODULE "_objc_module"
354 #define UTAG_SYMTAB "_objc_symtab"
355 #define UTAG_SUPER "_objc_super"
356 #define UTAG_SELECTOR "_objc_selector"
358 #define UTAG_PROTOCOL "_objc_protocol"
359 #define UTAG_METHOD_PROTOTYPE "_objc_method_prototype"
360 #define UTAG_METHOD_PROTOTYPE_LIST "_objc__method_prototype_list"
362 /* Note that the string object global name is only needed for the
364 #define STRING_OBJECT_GLOBAL_FORMAT "_%sClassReference"
366 #define PROTOCOL_OBJECT_CLASS_NAME "Protocol"
368 static const char *TAG_GETCLASS;
369 static const char *TAG_GETMETACLASS;
370 static const char *TAG_MSGSEND;
371 static const char *TAG_MSGSENDSUPER;
372 /* The NeXT Objective-C messenger may have two extra entry points, for use
373 when returning a structure. */
374 static const char *TAG_MSGSEND_STRET;
375 static const char *TAG_MSGSENDSUPER_STRET;
376 static const char *default_constant_string_class_name;
378 /* Runtime metadata flags. */
379 #define CLS_FACTORY 0x0001L
380 #define CLS_META 0x0002L
382 #define OBJC_MODIFIER_STATIC 0x00000001
383 #define OBJC_MODIFIER_FINAL 0x00000002
384 #define OBJC_MODIFIER_PUBLIC 0x00000004
385 #define OBJC_MODIFIER_PRIVATE 0x00000008
386 #define OBJC_MODIFIER_PROTECTED 0x00000010
387 #define OBJC_MODIFIER_NATIVE 0x00000020
388 #define OBJC_MODIFIER_SYNCHRONIZED 0x00000040
389 #define OBJC_MODIFIER_ABSTRACT 0x00000080
390 #define OBJC_MODIFIER_VOLATILE 0x00000100
391 #define OBJC_MODIFIER_TRANSIENT 0x00000200
392 #define OBJC_MODIFIER_NONE_SPECIFIED 0x80000000
394 /* NeXT-specific tags. */
396 #define TAG_MSGSEND_NONNIL "objc_msgSendNonNil"
397 #define TAG_MSGSEND_NONNIL_STRET "objc_msgSendNonNil_stret"
398 #define TAG_EXCEPTIONEXTRACT "objc_exception_extract"
399 #define TAG_EXCEPTIONTRYENTER "objc_exception_try_enter"
400 #define TAG_EXCEPTIONTRYEXIT "objc_exception_try_exit"
401 #define TAG_EXCEPTIONMATCH "objc_exception_match"
402 #define TAG_EXCEPTIONTHROW "objc_exception_throw"
403 #define TAG_SYNCENTER "objc_sync_enter"
404 #define TAG_SYNCEXIT "objc_sync_exit"
405 #define TAG_SETJMP "_setjmp"
406 #define UTAG_EXCDATA "_objc_exception_data"
408 /* GNU-specific tags. */
410 #define TAG_EXECCLASS "__objc_exec_class"
411 #define TAG_GNUINIT "__objc_gnu_init"
413 /* The OCTI_... enumeration itself is in objc/objc-act.h. */
414 tree objc_global_trees[OCTI_MAX];
416 static void handle_impent (struct imp_entry *);
418 struct imp_entry *imp_list = 0;
419 int imp_count = 0; /* `@implementation' */
420 int cat_count = 0; /* `@category' */
422 enum tree_code objc_inherit_code;
423 int objc_public_flag;
425 /* Use to generate method labels. */
426 static int method_slot = 0;
430 static char *errbuf; /* Buffer for error diagnostics */
432 /* Data imported from tree.c. */
434 extern enum debug_info_type write_symbols;
436 /* Data imported from toplev.c. */
438 extern const char *dump_base_name;
440 static int flag_typed_selectors;
442 /* Store all constructed constant strings in a hash table so that
443 they get uniqued properly. */
445 struct string_descriptor GTY(())
447 /* The literal argument . */
450 /* The resulting constant string. */
454 static GTY((param_is (struct string_descriptor))) htab_t string_htab;
456 static hashval_t string_hash (const void *);
457 static int string_eq (const void *, const void *);
459 FILE *gen_declaration_file;
461 /* Tells "encode_pointer/encode_aggregate" whether we are generating
462 type descriptors for instance variables (as opposed to methods).
463 Type descriptors for instance variables contain more information
464 than methods (for static typing and embedded structures). */
466 static int generating_instance_variables = 0;
468 /* Some platforms pass small structures through registers versus
469 through an invisible pointer. Determine at what size structure is
470 the transition point between the two possibilities. */
473 generate_struct_by_value_array (void)
476 tree field_decl, field_decl_chain;
478 int aggregate_in_mem[32];
481 /* Presumably no platform passes 32 byte structures in a register. */
482 for (i = 1; i < 32; i++)
486 /* Create an unnamed struct that has `i' character components */
487 type = start_struct (RECORD_TYPE, NULL_TREE);
489 strcpy (buffer, "c1");
490 field_decl = create_field_decl (char_type_node,
492 field_decl_chain = field_decl;
494 for (j = 1; j < i; j++)
496 sprintf (buffer, "c%d", j + 1);
497 field_decl = create_field_decl (char_type_node,
499 chainon (field_decl_chain, field_decl);
501 finish_struct (type, field_decl_chain, NULL_TREE);
503 aggregate_in_mem[i] = aggregate_value_p (type, 0);
504 if (!aggregate_in_mem[i])
508 /* We found some structures that are returned in registers instead of memory
509 so output the necessary data. */
512 for (i = 31; i >= 0; i--)
513 if (!aggregate_in_mem[i])
515 printf ("#define OBJC_MAX_STRUCT_BY_VALUE %d\n\n", i);
517 /* The first member of the structure is always 0 because we don't handle
518 structures with 0 members */
519 printf ("static int struct_forward_array[] = {\n 0");
521 for (j = 1; j <= i; j++)
522 printf (", %d", aggregate_in_mem[j]);
533 if (cxx_init () == false)
535 if (c_objc_common_init () == false)
539 #ifndef USE_MAPPED_LOCATION
540 /* Force the line number back to 0; check_newline will have
541 raised it to 1, which will make the builtin functions appear
542 not to be built in. */
546 /* If gen_declaration desired, open the output file. */
547 if (flag_gen_declaration)
549 register char * const dumpname = concat (dump_base_name, ".decl", NULL);
550 gen_declaration_file = fopen (dumpname, "w");
551 if (gen_declaration_file == 0)
552 fatal_error ("can't open %s: %m", dumpname);
556 if (flag_next_runtime)
558 TAG_GETCLASS = "objc_getClass";
559 TAG_GETMETACLASS = "objc_getMetaClass";
560 TAG_MSGSEND = "objc_msgSend";
561 TAG_MSGSENDSUPER = "objc_msgSendSuper";
562 TAG_MSGSEND_STRET = "objc_msgSend_stret";
563 TAG_MSGSENDSUPER_STRET = "objc_msgSendSuper_stret";
564 default_constant_string_class_name = "NSConstantString";
568 TAG_GETCLASS = "objc_get_class";
569 TAG_GETMETACLASS = "objc_get_meta_class";
570 TAG_MSGSEND = "objc_msg_lookup";
571 TAG_MSGSENDSUPER = "objc_msg_lookup_super";
572 /* GNU runtime does not provide special functions to support
573 structure-returning methods. */
574 default_constant_string_class_name = "NXConstantString";
575 flag_typed_selectors = 1;
580 if (print_struct_values)
581 generate_struct_by_value_array ();
587 objc_finish_file (void)
589 mark_referenced_methods ();
592 /* We need to instantiate templates _before_ we emit ObjC metadata;
593 if we do not, some metadata (such as selectors) may go missing. */
594 instantiate_pending_templates (0);
597 /* Finalize Objective-C runtime data. No need to generate tables
598 and code if only checking syntax. */
599 if (!flag_syntax_only)
602 if (gen_declaration_file)
603 fclose (gen_declaration_file);
610 /* Return the first occurrence of a method declaration corresponding
611 to sel_name in rproto_list. Search rproto_list recursively.
612 If is_class is 0, search for instance methods, otherwise for class
615 lookup_method_in_protocol_list (tree rproto_list, tree sel_name,
621 for (rproto = rproto_list; rproto; rproto = TREE_CHAIN (rproto))
623 p = TREE_VALUE (rproto);
625 if (TREE_CODE (p) == PROTOCOL_INTERFACE_TYPE)
627 if ((fnd = lookup_method (is_class
628 ? PROTOCOL_CLS_METHODS (p)
629 : PROTOCOL_NST_METHODS (p), sel_name)))
631 else if (PROTOCOL_LIST (p))
632 fnd = lookup_method_in_protocol_list (PROTOCOL_LIST (p),
637 ; /* An identifier...if we could not find a protocol. */
648 lookup_protocol_in_reflist (tree rproto_list, tree lproto)
652 /* Make sure the protocol is supported by the object on the rhs. */
653 if (TREE_CODE (lproto) == PROTOCOL_INTERFACE_TYPE)
656 for (rproto = rproto_list; rproto; rproto = TREE_CHAIN (rproto))
658 p = TREE_VALUE (rproto);
660 if (TREE_CODE (p) == PROTOCOL_INTERFACE_TYPE)
665 else if (PROTOCOL_LIST (p))
666 fnd = lookup_protocol_in_reflist (PROTOCOL_LIST (p), lproto);
675 ; /* An identifier...if we could not find a protocol. */
682 objc_start_class_interface (tree class, tree super_class, tree protos)
684 objc_interface_context
686 = start_class (CLASS_INTERFACE_TYPE, class, super_class, protos);
687 objc_public_flag = 0;
691 objc_start_category_interface (tree class, tree categ, tree protos)
693 objc_interface_context
694 = start_class (CATEGORY_INTERFACE_TYPE, class, categ, protos);
696 = continue_class (objc_interface_context);
700 objc_start_protocol (tree name, tree protos)
702 objc_interface_context
703 = start_protocol (PROTOCOL_INTERFACE_TYPE, name, protos);
707 objc_continue_interface (void)
710 = continue_class (objc_interface_context);
714 objc_finish_interface (void)
716 finish_class (objc_interface_context);
717 objc_interface_context = NULL_TREE;
721 objc_start_class_implementation (tree class, tree super_class)
723 objc_implementation_context
725 = start_class (CLASS_IMPLEMENTATION_TYPE, class, super_class, NULL_TREE);
726 objc_public_flag = 0;
730 objc_start_category_implementation (tree class, tree categ)
732 objc_implementation_context
733 = start_class (CATEGORY_IMPLEMENTATION_TYPE, class, categ, NULL_TREE);
735 = continue_class (objc_implementation_context);
739 objc_continue_implementation (void)
742 = continue_class (objc_implementation_context);
746 objc_finish_implementation (void)
748 if (objc_implementation_context)
750 finish_class (objc_implementation_context);
751 objc_ivar_chain = NULL_TREE;
752 objc_implementation_context = NULL_TREE;
755 warning ("%<@end%> must appear in an @implementation context");
759 objc_set_visibility (int visibility)
761 objc_public_flag = visibility;
765 objc_set_method_type (enum tree_code type)
767 objc_inherit_code = (type == PLUS_EXPR
769 : INSTANCE_METHOD_DECL);
773 objc_build_method_signature (tree rettype, tree selector, tree optparms)
775 return build_method_decl (objc_inherit_code, rettype, selector, optparms);
779 objc_add_method_declaration (tree decl)
781 if (!objc_interface_context)
782 fatal_error ("method declaration not in @interface context");
784 objc_add_method (objc_interface_context,
786 objc_inherit_code == CLASS_METHOD_DECL);
790 objc_start_method_definition (tree decl)
792 if (!objc_implementation_context)
793 fatal_error ("method definition not in @implementation context");
795 objc_add_method (objc_implementation_context,
797 objc_inherit_code == CLASS_METHOD_DECL);
798 start_method_def (decl);
802 objc_add_instance_variable (tree decl)
804 (void) add_instance_variable (objc_ivar_context,
809 /* Return 1 if IDENT is an ObjC/ObjC++ reserved keyword in the context of
813 objc_is_reserved_word (tree ident)
815 unsigned char code = C_RID_CODE (ident);
817 return (OBJC_IS_AT_KEYWORD (code)
819 || code == RID_CLASS || code == RID_PUBLIC
820 || code == RID_PROTECTED || code == RID_PRIVATE
821 || code == RID_TRY || code == RID_THROW || code == RID_CATCH
826 /* Return true if TYPE is 'id'. */
829 objc_is_object_id (tree type)
831 return OBJC_TYPE_NAME (type) == objc_object_id;
835 objc_is_class_id (tree type)
837 return OBJC_TYPE_NAME (type) == objc_class_id;
842 objc_types_compatible_p (tree type1, tree type2)
845 if (objc_is_object_ptr (type1) || objc_is_object_ptr (type2)
846 || objc_is_class_name (type1) || objc_is_class_name (type2))
848 return lhd_types_compatible_p (type1, type2);
853 return cxx_types_compatible_p (type1, type2);
855 return c_types_compatible_p (type1, type2);
861 /* Return 1 if LHS and RHS are compatible types for assignment or
862 various other operations. Return 0 if they are incompatible, and
863 return -1 if we choose to not decide (because the types are really
864 just C types, not ObjC specific ones). When the operation is
865 REFLEXIVE (typically comparisons), check for compatibility in
866 either direction; when it's not (typically assignments), don't.
868 This function is called in two cases: when both lhs and rhs are
869 pointers to records (in which case we check protocols too), and
870 when both lhs and rhs are records (in which case we check class
873 Warnings about classes/protocols not implementing a protocol are
874 emitted here (multiple of those warnings might be emitted for a
875 single line!); generic warnings about incompatible assignments and
876 lacks of casts in comparisons are/must be emitted by the caller if
881 objc_comptypes (tree lhs, tree rhs, int reflexive)
883 /* New clause for protocols. */
885 /* Here we manage the case of a POINTER_TYPE = POINTER_TYPE. We only
886 manage the ObjC ones, and leave the rest to the C code. */
887 if (TREE_CODE (lhs) == POINTER_TYPE
888 && TREE_CODE (TREE_TYPE (lhs)) == RECORD_TYPE
889 && TREE_CODE (rhs) == POINTER_TYPE
890 && TREE_CODE (TREE_TYPE (rhs)) == RECORD_TYPE)
892 int lhs_is_proto = IS_PROTOCOL_QUALIFIED_UNTYPED (lhs);
893 int rhs_is_proto = IS_PROTOCOL_QUALIFIED_UNTYPED (rhs);
897 tree lproto, lproto_list = TYPE_OBJC_PROTOCOL_LIST (TREE_TYPE (lhs));
898 tree rproto, rproto_list;
901 /* <Protocol> = <Protocol> */
904 /* Class <Protocol> != id <Protocol>;
905 id <Protocol> != Class <Protocol> */
906 if (IS_ID (lhs) != IS_ID (rhs))
909 rproto_list = TYPE_OBJC_PROTOCOL_LIST (TREE_TYPE (rhs));
913 /* An assignment between objects of type 'id
914 <Protocol>'; make sure the protocol on the lhs is
915 supported by the object on the rhs. */
916 for (lproto = lproto_list; lproto;
917 lproto = TREE_CHAIN (lproto))
919 p = TREE_VALUE (lproto);
920 rproto = lookup_protocol_in_reflist (rproto_list, p);
924 ("object does not conform to the %qs protocol",
925 IDENTIFIER_POINTER (PROTOCOL_NAME (p)));
931 /* Obscure case - a comparison between two objects
932 of type 'id <Protocol>'. Check that either the
933 protocol on the lhs is supported by the object on
934 the rhs, or viceversa. */
936 /* Check if the protocol on the lhs is supported by the
937 object on the rhs. */
938 for (lproto = lproto_list; lproto;
939 lproto = TREE_CHAIN (lproto))
941 p = TREE_VALUE (lproto);
942 rproto = lookup_protocol_in_reflist (rproto_list, p);
946 /* Check failed - check if the protocol on the rhs
947 is supported by the object on the lhs. */
948 for (rproto = rproto_list; rproto;
949 rproto = TREE_CHAIN (rproto))
951 p = TREE_VALUE (rproto);
952 lproto = lookup_protocol_in_reflist (lproto_list,
957 /* This check failed too: incompatible */
967 /* <Protocol> = <class> * */
968 else if (TYPED_OBJECT (TREE_TYPE (rhs)))
970 tree rname = OBJC_TYPE_NAME (TREE_TYPE (rhs));
973 /* Class <Protocol> != <class> * */
977 /* Make sure the protocol is supported by the object on
979 for (lproto = lproto_list; lproto; lproto = TREE_CHAIN (lproto))
981 p = TREE_VALUE (lproto);
983 rinter = lookup_interface (rname);
985 while (rinter && !rproto)
989 rproto_list = CLASS_PROTOCOL_LIST (rinter);
990 rproto = lookup_protocol_in_reflist (rproto_list, p);
991 /* If the underlying ObjC class does not have
992 the protocol we're looking for, check for "one-off"
993 protocols (e.g., `NSObject<MyProt> *foo;') attached
995 if (!rproto && TYPE_HAS_OBJC_INFO (TREE_TYPE (rhs)))
997 rproto_list = TYPE_OBJC_PROTOCOL_LIST (TREE_TYPE (rhs));
998 rproto = lookup_protocol_in_reflist (rproto_list, p);
1001 /* Check for protocols adopted by categories. */
1002 cat = CLASS_CATEGORY_LIST (rinter);
1003 while (cat && !rproto)
1005 rproto_list = CLASS_PROTOCOL_LIST (cat);
1006 rproto = lookup_protocol_in_reflist (rproto_list, p);
1007 cat = CLASS_CATEGORY_LIST (cat);
1010 rinter = lookup_interface (CLASS_SUPER_NAME (rinter));
1014 warning ("class %qs does not implement the %qs protocol",
1015 IDENTIFIER_POINTER (OBJC_TYPE_NAME (TREE_TYPE (rhs))),
1016 IDENTIFIER_POINTER (PROTOCOL_NAME (p)));
1020 /* id <Protocol> = id; Class <Protocol> = id */
1021 else if (objc_is_object_id (TREE_TYPE (rhs)))
1025 /* id <Protocol> != Class; Class <Protocol> = Class */
1026 else if (objc_is_class_id (TREE_TYPE (rhs)))
1028 return IS_CLASS (lhs);
1030 /* <Protocol> = ?? : let comptypes decide. */
1033 else if (rhs_is_proto)
1035 /* <class> * = <Protocol> */
1036 if (TYPED_OBJECT (TREE_TYPE (lhs)))
1038 /* <class> * != Class <Protocol> */
1044 tree rname = OBJC_TYPE_NAME (TREE_TYPE (lhs));
1046 tree rproto, rproto_list = TYPE_OBJC_PROTOCOL_LIST (TREE_TYPE (rhs));
1048 /* Make sure the protocol is supported by the object on
1050 for (rproto = rproto_list; rproto;
1051 rproto = TREE_CHAIN (rproto))
1053 tree p = TREE_VALUE (rproto);
1055 rinter = lookup_interface (rname);
1057 while (rinter && !lproto)
1061 tree lproto_list = CLASS_PROTOCOL_LIST (rinter);
1062 lproto = lookup_protocol_in_reflist (lproto_list, p);
1063 /* If the underlying ObjC class does not
1064 have the protocol we're looking for,
1065 check for "one-off" protocols (e.g.,
1066 `NSObject<MyProt> *foo;') attached to the
1068 if (!lproto && TYPE_HAS_OBJC_INFO (TREE_TYPE (lhs)))
1070 lproto_list = TYPE_OBJC_PROTOCOL_LIST
1072 lproto = lookup_protocol_in_reflist
1076 /* Check for protocols adopted by categories. */
1077 cat = CLASS_CATEGORY_LIST (rinter);
1078 while (cat && !lproto)
1080 lproto_list = CLASS_PROTOCOL_LIST (cat);
1081 lproto = lookup_protocol_in_reflist (lproto_list,
1083 cat = CLASS_CATEGORY_LIST (cat);
1086 rinter = lookup_interface (CLASS_SUPER_NAME
1091 warning ("class %qs does not implement the %qs protocol",
1092 IDENTIFIER_POINTER (OBJC_TYPE_NAME
1094 IDENTIFIER_POINTER (PROTOCOL_NAME (p)));
1101 /* id = id <Protocol>; id = Class <Protocol> */
1102 else if (objc_is_object_id (TREE_TYPE (lhs)))
1106 /* Class != id <Protocol>; Class = Class <Protocol> */
1107 else if (objc_is_class_id (TREE_TYPE (lhs)))
1109 return IS_CLASS (rhs);
1111 /* ??? = <Protocol> : let comptypes decide */
1119 /* Attention: we shouldn't defer to comptypes here. One bad
1120 side effect would be that we might loose the REFLEXIVE
1123 lhs = TREE_TYPE (lhs);
1124 rhs = TREE_TYPE (rhs);
1128 if (TREE_CODE (lhs) != RECORD_TYPE || TREE_CODE (rhs) != RECORD_TYPE)
1130 /* Nothing to do with ObjC - let immediately comptypes take
1131 responsibility for checking. */
1135 /* `id' = `<class> *' `<class> *' = `id': always allow it.
1137 'Object *o = [[Object alloc] init]; falls
1138 in the case <class> * = `id'.
1140 if ((objc_is_object_id (lhs) && TYPED_OBJECT (rhs))
1141 || (objc_is_object_id (rhs) && TYPED_OBJECT (lhs)))
1144 /* `id' = `Class', `Class' = `id' */
1146 else if ((objc_is_object_id (lhs) && objc_is_class_id (rhs))
1147 || (objc_is_class_id (lhs) && objc_is_object_id (rhs)))
1150 /* `Class' != `<class> *' && `<class> *' != `Class'! */
1151 else if ((OBJC_TYPE_NAME (lhs) == objc_class_id && TYPED_OBJECT (rhs))
1152 || (OBJC_TYPE_NAME (rhs) == objc_class_id && TYPED_OBJECT (lhs)))
1155 /* `<class> *' = `<class> *' */
1157 else if (TYPED_OBJECT (lhs) && TYPED_OBJECT (rhs))
1159 tree lname = OBJC_TYPE_NAME (lhs);
1160 tree rname = OBJC_TYPE_NAME (rhs);
1166 /* If the left hand side is a super class of the right hand side,
1168 for (inter = lookup_interface (rname); inter;
1169 inter = lookup_interface (CLASS_SUPER_NAME (inter)))
1170 if (lname == CLASS_SUPER_NAME (inter))
1173 /* Allow the reverse when reflexive. */
1175 for (inter = lookup_interface (lname); inter;
1176 inter = lookup_interface (CLASS_SUPER_NAME (inter)))
1177 if (rname == CLASS_SUPER_NAME (inter))
1183 /* Not an ObjC type - let comptypes do the check. */
1187 /* Called from finish_decl. */
1190 objc_check_decl (tree decl)
1192 tree type = TREE_TYPE (decl);
1194 if (TREE_CODE (type) != RECORD_TYPE)
1196 if (OBJC_TYPE_NAME (type) && (type = objc_is_class_name (OBJC_TYPE_NAME (type))))
1197 error ("statically allocated instance of Objective-C class %qs",
1198 IDENTIFIER_POINTER (type));
1201 /* Construct a PROTOCOLS-qualified variant of INTERFACE, where INTERFACE may
1202 either name an Objective-C class, or refer to the special 'id' or 'Class'
1203 types. If INTERFACE is not a valid ObjC type, just return it unchanged. */
1206 objc_get_protocol_qualified_type (tree interface, tree protocols)
1208 /* If INTERFACE is not provided, default to 'id'. */
1209 tree type = (interface ? objc_is_id (interface) : objc_object_type);
1210 bool is_ptr = (type != NULL_TREE);
1214 type = objc_is_class_name (interface);
1217 type = xref_tag (RECORD_TYPE, type);
1224 type = build_variant_type_copy (type);
1226 /* For pointers (i.e., 'id' or 'Class'), attach the protocol(s)
1230 TREE_TYPE (type) = build_variant_type_copy (TREE_TYPE (type));
1231 TYPE_POINTER_TO (TREE_TYPE (type)) = type;
1232 type = TREE_TYPE (type);
1235 /* Look up protocols and install in lang specific list. */
1236 DUP_TYPE_OBJC_INFO (type, TYPE_MAIN_VARIANT (type));
1237 TYPE_OBJC_PROTOCOL_LIST (type) = lookup_and_install_protocols (protocols);
1239 /* For RECORD_TYPEs, point to the @interface; for 'id' and 'Class',
1240 return the pointer to the new pointee variant. */
1242 type = TYPE_POINTER_TO (type);
1244 TYPE_OBJC_INTERFACE (type)
1245 = TYPE_OBJC_INTERFACE (TYPE_MAIN_VARIANT (type));
1251 /* Check for circular dependencies in protocols. The arguments are
1252 PROTO, the protocol to check, and LIST, a list of protocol it
1256 check_protocol_recursively (tree proto, tree list)
1260 for (p = list; p; p = TREE_CHAIN (p))
1262 tree pp = TREE_VALUE (p);
1264 if (TREE_CODE (pp) == IDENTIFIER_NODE)
1265 pp = lookup_protocol (pp);
1268 fatal_error ("protocol %qs has circular dependency",
1269 IDENTIFIER_POINTER (PROTOCOL_NAME (pp)));
1271 check_protocol_recursively (proto, PROTOCOL_LIST (pp));
1275 /* Look up PROTOCOLS, and return a list of those that are found.
1276 If none are found, return NULL. */
1279 lookup_and_install_protocols (tree protocols)
1282 tree return_value = NULL_TREE;
1284 for (proto = protocols; proto; proto = TREE_CHAIN (proto))
1286 tree ident = TREE_VALUE (proto);
1287 tree p = lookup_protocol (ident);
1290 error ("cannot find protocol declaration for %qs",
1291 IDENTIFIER_POINTER (ident));
1293 return_value = chainon (return_value,
1294 build_tree_list (NULL_TREE, p));
1297 return return_value;
1300 /* Create a declaration for field NAME of a given TYPE. */
1303 create_field_decl (tree type, const char *name)
1305 return build_decl (FIELD_DECL, get_identifier (name), type);
1308 /* Create a global, static declaration for variable NAME of a given TYPE. The
1309 finish_var_decl() routine will need to be called on it afterwards. */
1312 start_var_decl (tree type, const char *name)
1314 tree var = build_decl (VAR_DECL, get_identifier (name), type);
1316 TREE_STATIC (var) = 1;
1317 DECL_INITIAL (var) = error_mark_node; /* A real initializer is coming... */
1318 DECL_IGNORED_P (var) = 1;
1319 DECL_ARTIFICIAL (var) = 1;
1320 DECL_CONTEXT (var) = NULL_TREE;
1322 DECL_THIS_STATIC (var) = 1; /* squash redeclaration errors */
1328 /* Finish off the variable declaration created by start_var_decl(). */
1331 finish_var_decl (tree var, tree initializer)
1333 finish_decl (var, initializer, NULL_TREE);
1334 /* Ensure that the variable actually gets output. */
1335 mark_decl_referenced (var);
1336 /* Mark the decl to avoid "defined but not used" warning. */
1337 TREE_USED (var) = 1;
1340 /* Find the decl for the constant string class reference. This is only
1341 used for the NeXT runtime. */
1344 setup_string_decl (void)
1349 /* %s in format will provide room for terminating null */
1350 length = strlen (STRING_OBJECT_GLOBAL_FORMAT)
1351 + strlen (constant_string_class_name);
1352 name = xmalloc (length);
1353 sprintf (name, STRING_OBJECT_GLOBAL_FORMAT,
1354 constant_string_class_name);
1355 constant_string_global_id = get_identifier (name);
1356 string_class_decl = lookup_name (constant_string_global_id);
1358 return string_class_decl;
1361 /* Purpose: "play" parser, creating/installing representations
1362 of the declarations that are required by Objective-C.
1366 type_spec--------->sc_spec
1367 (tree_list) (tree_list)
1370 identifier_node identifier_node */
1373 synth_module_prologue (void)
1376 enum debug_info_type save_write_symbols = write_symbols;
1377 const struct gcc_debug_hooks *const save_hooks = debug_hooks;
1379 /* Suppress outputting debug symbols, because
1380 dbxout_init hasn'r been called yet. */
1381 write_symbols = NO_DEBUG;
1382 debug_hooks = &do_nothing_debug_hooks;
1385 push_lang_context (lang_name_c); /* extern "C" */
1388 /* The following are also defined in <objc/objc.h> and friends. */
1390 objc_object_id = get_identifier (TAG_OBJECT);
1391 objc_class_id = get_identifier (TAG_CLASS);
1393 objc_object_reference = xref_tag (RECORD_TYPE, objc_object_id);
1394 objc_class_reference = xref_tag (RECORD_TYPE, objc_class_id);
1396 objc_object_type = build_pointer_type (objc_object_reference);
1397 objc_class_type = build_pointer_type (objc_class_reference);
1399 objc_object_name = get_identifier (OBJECT_TYPEDEF_NAME);
1400 objc_class_name = get_identifier (CLASS_TYPEDEF_NAME);
1402 /* Declare the 'id' and 'Class' typedefs. */
1404 type = lang_hooks.decls.pushdecl (build_decl (TYPE_DECL,
1407 DECL_IN_SYSTEM_HEADER (type) = 1;
1408 type = lang_hooks.decls.pushdecl (build_decl (TYPE_DECL,
1411 DECL_IN_SYSTEM_HEADER (type) = 1;
1413 /* Forward-declare '@interface Protocol'. */
1415 type = get_identifier (PROTOCOL_OBJECT_CLASS_NAME);
1416 objc_declare_class (tree_cons (NULL_TREE, type, NULL_TREE));
1417 objc_protocol_type = build_pointer_type (xref_tag (RECORD_TYPE,
1420 /* Declare type of selector-objects that represent an operation name. */
1422 if (flag_next_runtime)
1423 /* `struct objc_selector *' */
1425 = build_pointer_type (xref_tag (RECORD_TYPE,
1426 get_identifier (TAG_SELECTOR)));
1428 /* `const struct objc_selector *' */
1430 = build_pointer_type
1431 (build_qualified_type (xref_tag (RECORD_TYPE,
1432 get_identifier (TAG_SELECTOR)),
1435 /* Declare receiver type used for dispatching messages to 'super'. */
1437 /* `struct objc_super *' */
1438 objc_super_type = build_pointer_type (xref_tag (RECORD_TYPE,
1439 get_identifier (TAG_SUPER)));
1441 if (flag_next_runtime)
1443 /* NB: In order to call one of the ..._stret (struct-returning)
1444 functions, the function *MUST* first be cast to a signature that
1445 corresponds to the actual ObjC method being invoked. This is
1446 what is done by the build_objc_method_call() routine below. */
1448 /* id objc_msgSend (id, SEL, ...); */
1449 /* id objc_msgSendNonNil (id, SEL, ...); */
1450 /* id objc_msgSend_stret (id, SEL, ...); */
1451 /* id objc_msgSendNonNil_stret (id, SEL, ...); */
1453 = build_function_type (objc_object_type,
1454 tree_cons (NULL_TREE, objc_object_type,
1455 tree_cons (NULL_TREE, objc_selector_type,
1457 umsg_decl = builtin_function (TAG_MSGSEND,
1458 type, 0, NOT_BUILT_IN,
1460 umsg_nonnil_decl = builtin_function (TAG_MSGSEND_NONNIL,
1461 type, 0, NOT_BUILT_IN,
1463 umsg_stret_decl = builtin_function (TAG_MSGSEND_STRET,
1464 type, 0, NOT_BUILT_IN,
1466 umsg_nonnil_stret_decl = builtin_function (TAG_MSGSEND_NONNIL_STRET,
1467 type, 0, NOT_BUILT_IN,
1470 /* id objc_msgSendSuper (struct objc_super *, SEL, ...); */
1471 /* id objc_msgSendSuper_stret (struct objc_super *, SEL, ...); */
1473 = build_function_type (objc_object_type,
1474 tree_cons (NULL_TREE, objc_super_type,
1475 tree_cons (NULL_TREE, objc_selector_type,
1477 umsg_super_decl = builtin_function (TAG_MSGSENDSUPER,
1478 type, 0, NOT_BUILT_IN,
1480 umsg_super_stret_decl = builtin_function (TAG_MSGSENDSUPER_STRET,
1481 type, 0, NOT_BUILT_IN, 0,
1486 /* GNU runtime messenger entry points. */
1488 /* typedef id (*IMP)(id, SEL, ...); */
1490 = build_pointer_type
1491 (build_function_type (objc_object_type,
1492 tree_cons (NULL_TREE, objc_object_type,
1493 tree_cons (NULL_TREE, objc_selector_type,
1496 /* IMP objc_msg_lookup (id, SEL); */
1498 = build_function_type (IMP_type,
1499 tree_cons (NULL_TREE, objc_object_type,
1500 tree_cons (NULL_TREE, objc_selector_type,
1501 OBJC_VOID_AT_END)));
1502 umsg_decl = builtin_function (TAG_MSGSEND,
1503 type, 0, NOT_BUILT_IN,
1506 /* IMP objc_msg_lookup_super (struct objc_super *, SEL); */
1508 = build_function_type (IMP_type,
1509 tree_cons (NULL_TREE, objc_super_type,
1510 tree_cons (NULL_TREE, objc_selector_type,
1511 OBJC_VOID_AT_END)));
1512 umsg_super_decl = builtin_function (TAG_MSGSENDSUPER,
1513 type, 0, NOT_BUILT_IN,
1516 /* The following GNU runtime entry point is called to initialize
1519 __objc_exec_class (void *); */
1521 = build_function_type (void_type_node,
1522 tree_cons (NULL_TREE, ptr_type_node,
1524 execclass_decl = builtin_function (TAG_EXECCLASS,
1525 type, 0, NOT_BUILT_IN,
1529 /* id objc_getClass (const char *); */
1531 type = build_function_type (objc_object_type,
1532 tree_cons (NULL_TREE,
1533 const_string_type_node,
1537 = builtin_function (TAG_GETCLASS, type, 0, NOT_BUILT_IN,
1540 /* id objc_getMetaClass (const char *); */
1542 objc_get_meta_class_decl
1543 = builtin_function (TAG_GETMETACLASS, type, 0, NOT_BUILT_IN, NULL, NULL_TREE);
1545 build_class_template ();
1546 build_super_template ();
1547 build_protocol_template ();
1548 build_category_template ();
1549 build_objc_exception_stuff ();
1551 if (flag_next_runtime)
1552 build_next_objc_exception_stuff ();
1554 /* static SEL _OBJC_SELECTOR_TABLE[]; */
1556 if (! flag_next_runtime)
1557 build_selector_table_decl ();
1559 /* Forward declare constant_string_id and constant_string_type. */
1560 if (!constant_string_class_name)
1561 constant_string_class_name = default_constant_string_class_name;
1563 constant_string_id = get_identifier (constant_string_class_name);
1564 objc_declare_class (tree_cons (NULL_TREE, constant_string_id, NULL_TREE));
1566 /* Pre-build the following entities - for speed/convenience. */
1567 self_id = get_identifier ("self");
1568 ucmd_id = get_identifier ("_cmd");
1570 /* The C++ front-end does not appear to grok __attribute__((__unused__)). */
1571 unused_list = build_tree_list (get_identifier ("__unused__"), NULL_TREE);
1575 pop_lang_context ();
1578 write_symbols = save_write_symbols;
1579 debug_hooks = save_hooks;
1582 /* Ensure that the ivar list for NSConstantString/NXConstantString
1583 (or whatever was specified via `-fconstant-string-class')
1584 contains fields at least as large as the following three, so that
1585 the runtime can stomp on them with confidence:
1587 struct STRING_OBJECT_CLASS_NAME
1591 unsigned int length;
1595 check_string_class_template (void)
1597 tree field_decl = TYPE_FIELDS (constant_string_type);
1599 #define AT_LEAST_AS_LARGE_AS(F, T) \
1600 (F && TREE_CODE (F) == FIELD_DECL \
1601 && (TREE_INT_CST_LOW (DECL_SIZE (F)) \
1602 >= TREE_INT_CST_LOW (TYPE_SIZE (T))))
1604 if (!AT_LEAST_AS_LARGE_AS (field_decl, ptr_type_node))
1607 field_decl = TREE_CHAIN (field_decl);
1608 if (!AT_LEAST_AS_LARGE_AS (field_decl, ptr_type_node))
1611 field_decl = TREE_CHAIN (field_decl);
1612 return AT_LEAST_AS_LARGE_AS (field_decl, unsigned_type_node);
1614 #undef AT_LEAST_AS_LARGE_AS
1617 /* Avoid calling `check_string_class_template ()' more than once. */
1618 static GTY(()) int string_layout_checked;
1620 /* Custom build_string which sets TREE_TYPE! */
1623 my_build_string (int len, const char *str)
1625 return fix_string_type (build_string (len, str));
1630 string_hash (const void *ptr)
1632 tree str = ((struct string_descriptor *)ptr)->literal;
1633 const unsigned char *p = (const unsigned char *) TREE_STRING_POINTER (str);
1634 int i, len = TREE_STRING_LENGTH (str);
1637 for (i = 0; i < len; i++)
1638 h = ((h * 613) + p[i]);
1644 string_eq (const void *ptr1, const void *ptr2)
1646 tree str1 = ((struct string_descriptor *)ptr1)->literal;
1647 tree str2 = ((struct string_descriptor *)ptr2)->literal;
1648 int len1 = TREE_STRING_LENGTH (str1);
1650 return (len1 == TREE_STRING_LENGTH (str2)
1651 && !memcmp (TREE_STRING_POINTER (str1), TREE_STRING_POINTER (str2),
1655 /* Given a chain of STRING_CST's, build a static instance of
1656 NXConstantString which points at the concatenation of those
1657 strings. We place the string object in the __string_objects
1658 section of the __OBJC segment. The Objective-C runtime will
1659 initialize the isa pointers of the string objects to point at the
1660 NXConstantString class object. */
1663 objc_build_string_object (tree string)
1665 tree initlist, constructor, constant_string_class;
1668 struct string_descriptor *desc, key;
1671 /* Prep the string argument. */
1672 string = fix_string_type (string);
1673 TREE_SET_CODE (string, STRING_CST);
1674 length = TREE_STRING_LENGTH (string) - 1;
1676 /* Check whether the string class being used actually exists and has the
1677 correct ivar layout. */
1678 if (!string_layout_checked)
1680 string_layout_checked = -1;
1681 constant_string_class = lookup_interface (constant_string_id);
1683 if (!constant_string_class
1684 || !(constant_string_type
1685 = CLASS_STATIC_TEMPLATE (constant_string_class)))
1686 error ("cannot find interface declaration for %qs",
1687 IDENTIFIER_POINTER (constant_string_id));
1688 /* The NSConstantString/NXConstantString ivar layout is now known. */
1689 else if (!check_string_class_template ())
1690 error ("interface %qs does not have valid constant string layout",
1691 IDENTIFIER_POINTER (constant_string_id));
1692 /* For the NeXT runtime, we can generate a literal reference
1693 to the string class, don't need to run a constructor. */
1694 else if (flag_next_runtime && !setup_string_decl ())
1695 error ("cannot find reference tag for class %qs",
1696 IDENTIFIER_POINTER (constant_string_id));
1699 string_layout_checked = 1; /* Success! */
1700 add_class_reference (constant_string_id);
1704 if (string_layout_checked == -1)
1705 return error_mark_node;
1707 /* Perhaps we already constructed a constant string just like this one? */
1708 key.literal = string;
1709 loc = htab_find_slot (string_htab, &key, INSERT);
1715 *loc = desc = ggc_alloc (sizeof (*desc));
1716 desc->literal = string;
1718 /* GNU: & ((NXConstantString) { NULL, string, length }) */
1719 /* NeXT: & ((NSConstantString) { isa, string, length }) */
1720 fields = TYPE_FIELDS (constant_string_type);
1722 = build_tree_list (fields,
1724 ? build_unary_op (ADDR_EXPR, string_class_decl, 0)
1725 : build_int_cst (NULL_TREE, 0));
1726 fields = TREE_CHAIN (fields);
1727 initlist = tree_cons (fields, build_unary_op (ADDR_EXPR, string, 1),
1729 fields = TREE_CHAIN (fields);
1730 initlist = tree_cons (fields, build_int_cst (NULL_TREE, length),
1732 constructor = objc_build_constructor (constant_string_type,
1733 nreverse (initlist));
1734 TREE_INVARIANT (constructor) = true;
1736 if (!flag_next_runtime)
1738 = objc_add_static_instance (constructor, constant_string_type);
1741 var = build_decl (CONST_DECL, NULL, TREE_TYPE (constructor));
1742 DECL_INITIAL (var) = constructor;
1743 TREE_STATIC (var) = 1;
1744 pushdecl_top_level (var);
1747 desc->constructor = constructor;
1750 addr = build_unary_op (ADDR_EXPR, desc->constructor, 1);
1755 /* Declare a static instance of CLASS_DECL initialized by CONSTRUCTOR. */
1757 static GTY(()) int num_static_inst;
1760 objc_add_static_instance (tree constructor, tree class_decl)
1765 /* Find the list of static instances for the CLASS_DECL. Create one if
1767 for (chain = &objc_static_instances;
1768 *chain && TREE_VALUE (*chain) != class_decl;
1769 chain = &TREE_CHAIN (*chain));
1772 *chain = tree_cons (NULL_TREE, class_decl, NULL_TREE);
1773 add_objc_string (OBJC_TYPE_NAME (class_decl), class_names);
1776 sprintf (buf, "_OBJC_INSTANCE_%d", num_static_inst++);
1777 decl = build_decl (VAR_DECL, get_identifier (buf), class_decl);
1778 DECL_COMMON (decl) = 1;
1779 TREE_STATIC (decl) = 1;
1780 DECL_ARTIFICIAL (decl) = 1;
1781 DECL_INITIAL (decl) = constructor;
1783 /* We may be writing something else just now.
1784 Postpone till end of input. */
1785 DECL_DEFER_OUTPUT (decl) = 1;
1786 pushdecl_top_level (decl);
1787 rest_of_decl_compilation (decl, 1, 0);
1789 /* Add the DECL to the head of this CLASS' list. */
1790 TREE_PURPOSE (*chain) = tree_cons (NULL_TREE, decl, TREE_PURPOSE (*chain));
1795 /* Build a static constant CONSTRUCTOR
1796 with type TYPE and elements ELTS. */
1799 objc_build_constructor (tree type, tree elts)
1801 tree constructor = build_constructor (type, elts);
1803 TREE_CONSTANT (constructor) = 1;
1804 TREE_STATIC (constructor) = 1;
1805 TREE_READONLY (constructor) = 1;
1808 /* Adjust for impedance mismatch. We should figure out how to build
1809 CONSTRUCTORs that consistently please both the C and C++ gods. */
1810 if (!TREE_PURPOSE (elts))
1811 TREE_TYPE (constructor) = NULL_TREE;
1812 TREE_HAS_CONSTRUCTOR (constructor) = 1;
1818 /* Take care of defining and initializing _OBJC_SYMBOLS. */
1820 /* Predefine the following data type:
1828 void *defs[cls_def_cnt + cat_def_cnt];
1832 build_objc_symtab_template (void)
1834 tree field_decl, field_decl_chain;
1836 objc_symtab_template
1837 = start_struct (RECORD_TYPE, get_identifier (UTAG_SYMTAB));
1839 /* long sel_ref_cnt; */
1840 field_decl = create_field_decl (long_integer_type_node, "sel_ref_cnt");
1841 field_decl_chain = field_decl;
1844 field_decl = create_field_decl (build_pointer_type (objc_selector_type),
1846 chainon (field_decl_chain, field_decl);
1848 /* short cls_def_cnt; */
1849 field_decl = create_field_decl (short_integer_type_node, "cls_def_cnt");
1850 chainon (field_decl_chain, field_decl);
1852 /* short cat_def_cnt; */
1853 field_decl = create_field_decl (short_integer_type_node,
1855 chainon (field_decl_chain, field_decl);
1857 if (imp_count || cat_count || !flag_next_runtime)
1859 /* void *defs[imp_count + cat_count (+ 1)]; */
1860 /* NB: The index is one less than the size of the array. */
1861 int index = imp_count + cat_count
1862 + (flag_next_runtime? -1: 0);
1863 field_decl = create_field_decl
1866 build_index_type (build_int_cst (NULL_TREE, index))),
1868 chainon (field_decl_chain, field_decl);
1871 finish_struct (objc_symtab_template, field_decl_chain, NULL_TREE);
1874 /* Create the initial value for the `defs' field of _objc_symtab.
1875 This is a CONSTRUCTOR. */
1878 init_def_list (tree type)
1880 tree expr, initlist = NULL_TREE;
1881 struct imp_entry *impent;
1884 for (impent = imp_list; impent; impent = impent->next)
1886 if (TREE_CODE (impent->imp_context) == CLASS_IMPLEMENTATION_TYPE)
1888 expr = build_unary_op (ADDR_EXPR, impent->class_decl, 0);
1889 initlist = tree_cons (NULL_TREE, expr, initlist);
1894 for (impent = imp_list; impent; impent = impent->next)
1896 if (TREE_CODE (impent->imp_context) == CATEGORY_IMPLEMENTATION_TYPE)
1898 expr = build_unary_op (ADDR_EXPR, impent->class_decl, 0);
1899 initlist = tree_cons (NULL_TREE, expr, initlist);
1903 if (!flag_next_runtime)
1905 /* statics = { ..., _OBJC_STATIC_INSTANCES, ... } */
1908 if (static_instances_decl)
1909 expr = build_unary_op (ADDR_EXPR, static_instances_decl, 0);
1911 expr = build_int_cst (NULL_TREE, 0);
1913 initlist = tree_cons (NULL_TREE, expr, initlist);
1916 return objc_build_constructor (type, nreverse (initlist));
1919 /* Construct the initial value for all of _objc_symtab. */
1922 init_objc_symtab (tree type)
1926 /* sel_ref_cnt = { ..., 5, ... } */
1928 initlist = build_tree_list (NULL_TREE,
1929 build_int_cst (long_integer_type_node, 0));
1931 /* refs = { ..., _OBJC_SELECTOR_TABLE, ... } */
1933 if (flag_next_runtime || ! sel_ref_chain)
1934 initlist = tree_cons (NULL_TREE, build_int_cst (NULL_TREE, 0), initlist);
1937 = tree_cons (NULL_TREE,
1938 convert (build_pointer_type (objc_selector_type),
1939 build_unary_op (ADDR_EXPR,
1940 UOBJC_SELECTOR_TABLE_decl, 1)),
1943 /* cls_def_cnt = { ..., 5, ... } */
1945 initlist = tree_cons (NULL_TREE, build_int_cst (NULL_TREE, imp_count), initlist);
1947 /* cat_def_cnt = { ..., 5, ... } */
1949 initlist = tree_cons (NULL_TREE, build_int_cst (NULL_TREE, cat_count), initlist);
1951 /* cls_def = { ..., { &Foo, &Bar, ...}, ... } */
1953 if (imp_count || cat_count || !flag_next_runtime)
1956 tree field = TYPE_FIELDS (type);
1957 field = TREE_CHAIN (TREE_CHAIN (TREE_CHAIN (TREE_CHAIN (field))));
1959 initlist = tree_cons (NULL_TREE, init_def_list (TREE_TYPE (field)),
1963 return objc_build_constructor (type, nreverse (initlist));
1966 /* Generate forward declarations for metadata such as
1967 'OBJC_CLASS_...'. */
1970 build_metadata_decl (const char *name, tree type)
1974 /* struct TYPE NAME_<name>; */
1975 decl = start_var_decl (type, synth_id_with_class_suffix
1977 objc_implementation_context));
1982 /* Push forward-declarations of all the categories so that
1983 init_def_list can use them in a CONSTRUCTOR. */
1986 forward_declare_categories (void)
1988 struct imp_entry *impent;
1989 tree sav = objc_implementation_context;
1991 for (impent = imp_list; impent; impent = impent->next)
1993 if (TREE_CODE (impent->imp_context) == CATEGORY_IMPLEMENTATION_TYPE)
1995 /* Set an invisible arg to synth_id_with_class_suffix. */
1996 objc_implementation_context = impent->imp_context;
1997 /* extern struct objc_category _OBJC_CATEGORY_<name>; */
1998 impent->class_decl = build_metadata_decl ("_OBJC_CATEGORY",
1999 objc_category_template);
2002 objc_implementation_context = sav;
2005 /* Create the declaration of _OBJC_SYMBOLS, with type `struct _objc_symtab'
2006 and initialized appropriately. */
2009 generate_objc_symtab_decl (void)
2011 /* forward declare categories */
2013 forward_declare_categories ();
2015 build_objc_symtab_template ();
2016 UOBJC_SYMBOLS_decl = start_var_decl (objc_symtab_template, "_OBJC_SYMBOLS");
2017 finish_var_decl (UOBJC_SYMBOLS_decl,
2018 init_objc_symtab (TREE_TYPE (UOBJC_SYMBOLS_decl)));
2022 init_module_descriptor (tree type)
2024 tree initlist, expr;
2026 /* version = { 1, ... } */
2028 expr = build_int_cst (long_integer_type_node, OBJC_VERSION);
2029 initlist = build_tree_list (NULL_TREE, expr);
2031 /* size = { ..., sizeof (struct _objc_module), ... } */
2033 expr = convert (long_integer_type_node,
2034 size_in_bytes (objc_module_template));
2035 initlist = tree_cons (NULL_TREE, expr, initlist);
2037 /* name = { ..., "foo.m", ... } */
2039 expr = add_objc_string (get_identifier (input_filename), class_names);
2040 initlist = tree_cons (NULL_TREE, expr, initlist);
2042 /* symtab = { ..., _OBJC_SYMBOLS, ... } */
2044 if (UOBJC_SYMBOLS_decl)
2045 expr = build_unary_op (ADDR_EXPR, UOBJC_SYMBOLS_decl, 0);
2047 expr = build_int_cst (NULL_TREE, 0);
2048 initlist = tree_cons (NULL_TREE, expr, initlist);
2050 return objc_build_constructor (type, nreverse (initlist));
2053 /* Write out the data structures to describe Objective C classes defined.
2055 struct _objc_module { ... } _OBJC_MODULE = { ... }; */
2058 build_module_descriptor (void)
2060 tree field_decl, field_decl_chain;
2063 push_lang_context (lang_name_c); /* extern "C" */
2066 objc_module_template
2067 = start_struct (RECORD_TYPE, get_identifier (UTAG_MODULE));
2070 field_decl = create_field_decl (long_integer_type_node, "version");
2071 field_decl_chain = field_decl;
2074 field_decl = create_field_decl (long_integer_type_node, "size");
2075 chainon (field_decl_chain, field_decl);
2078 field_decl = create_field_decl (string_type_node, "name");
2079 chainon (field_decl_chain, field_decl);
2081 /* struct _objc_symtab *symtab; */
2083 = create_field_decl (build_pointer_type
2084 (xref_tag (RECORD_TYPE,
2085 get_identifier (UTAG_SYMTAB))),
2087 chainon (field_decl_chain, field_decl);
2089 finish_struct (objc_module_template, field_decl_chain, NULL_TREE);
2091 /* Create an instance of "_objc_module". */
2092 UOBJC_MODULES_decl = start_var_decl (objc_module_template, "_OBJC_MODULES");
2093 finish_var_decl (UOBJC_MODULES_decl,
2094 init_module_descriptor (TREE_TYPE (UOBJC_MODULES_decl)));
2097 pop_lang_context ();
2101 /* The GNU runtime requires us to provide a static initializer function
2104 static void __objc_gnu_init (void) {
2105 __objc_exec_class (&L_OBJC_MODULES);
2109 build_module_initializer_routine (void)
2114 push_lang_context (lang_name_c); /* extern "C" */
2117 objc_push_parm (build_decl (PARM_DECL, NULL_TREE, void_type_node));
2118 objc_start_function (get_identifier (TAG_GNUINIT),
2119 build_function_type (void_type_node,
2121 NULL_TREE, objc_get_parm_info (0));
2123 body = c_begin_compound_stmt (true);
2124 add_stmt (build_function_call
2128 build_unary_op (ADDR_EXPR,
2129 UOBJC_MODULES_decl, 0))));
2130 add_stmt (c_end_compound_stmt (body, true));
2132 TREE_PUBLIC (current_function_decl) = 0;
2135 /* For Objective-C++, we will need to call __objc_gnu_init
2136 from objc_generate_static_init_call() below. */
2137 DECL_STATIC_CONSTRUCTOR (current_function_decl) = 1;
2140 GNU_INIT_decl = current_function_decl;
2144 pop_lang_context ();
2149 /* Return 1 if the __objc_gnu_init function has been synthesized and needs
2150 to be called by the module initializer routine. */
2153 objc_static_init_needed_p (void)
2155 return (GNU_INIT_decl != NULL_TREE);
2158 /* Generate a call to the __objc_gnu_init initializer function. */
2161 objc_generate_static_init_call (tree ctors ATTRIBUTE_UNUSED)
2163 add_stmt (build_stmt (EXPR_STMT,
2164 build_function_call (GNU_INIT_decl, NULL_TREE)));
2168 #endif /* OBJCPLUS */
2170 /* Return the DECL of the string IDENT in the SECTION. */
2173 get_objc_string_decl (tree ident, enum string_section section)
2177 if (section == class_names)
2178 chain = class_names_chain;
2179 else if (section == meth_var_names)
2180 chain = meth_var_names_chain;
2181 else if (section == meth_var_types)
2182 chain = meth_var_types_chain;
2186 for (; chain != 0; chain = TREE_CHAIN (chain))
2187 if (TREE_VALUE (chain) == ident)
2188 return (TREE_PURPOSE (chain));
2194 /* Output references to all statically allocated objects. Return the DECL
2195 for the array built. */
2198 generate_static_references (void)
2200 tree decls = NULL_TREE, expr = NULL_TREE;
2201 tree class_name, class, decl, initlist;
2202 tree cl_chain, in_chain, type
2203 = build_array_type (build_pointer_type (void_type_node), NULL_TREE);
2204 int num_inst, num_class;
2207 if (flag_next_runtime)
2210 for (cl_chain = objc_static_instances, num_class = 0;
2211 cl_chain; cl_chain = TREE_CHAIN (cl_chain), num_class++)
2213 for (num_inst = 0, in_chain = TREE_PURPOSE (cl_chain);
2214 in_chain; num_inst++, in_chain = TREE_CHAIN (in_chain));
2216 sprintf (buf, "_OBJC_STATIC_INSTANCES_%d", num_class);
2217 decl = start_var_decl (type, buf);
2219 /* Output {class_name, ...}. */
2220 class = TREE_VALUE (cl_chain);
2221 class_name = get_objc_string_decl (OBJC_TYPE_NAME (class), class_names);
2222 initlist = build_tree_list (NULL_TREE,
2223 build_unary_op (ADDR_EXPR, class_name, 1));
2225 /* Output {..., instance, ...}. */
2226 for (in_chain = TREE_PURPOSE (cl_chain);
2227 in_chain; in_chain = TREE_CHAIN (in_chain))
2229 expr = build_unary_op (ADDR_EXPR, TREE_VALUE (in_chain), 1);
2230 initlist = tree_cons (NULL_TREE, expr, initlist);
2233 /* Output {..., NULL}. */
2234 initlist = tree_cons (NULL_TREE, build_int_cst (NULL_TREE, 0), initlist);
2236 expr = objc_build_constructor (TREE_TYPE (decl), nreverse (initlist));
2237 finish_var_decl (decl, expr);
2239 = tree_cons (NULL_TREE, build_unary_op (ADDR_EXPR, decl, 1), decls);
2242 decls = tree_cons (NULL_TREE, build_int_cst (NULL_TREE, 0), decls);
2243 expr = objc_build_constructor (type, nreverse (decls));
2244 static_instances_decl = start_var_decl (type, "_OBJC_STATIC_INSTANCES");
2245 finish_var_decl (static_instances_decl, expr);
2248 /* Output all strings. */
2251 generate_strings (void)
2253 tree chain, string_expr;
2254 tree string, decl, type;
2256 for (chain = class_names_chain; chain; chain = TREE_CHAIN (chain))
2258 string = TREE_VALUE (chain);
2259 decl = TREE_PURPOSE (chain);
2260 type = build_array_type
2263 (build_int_cst (NULL_TREE,
2264 IDENTIFIER_LENGTH (string))));
2265 decl = start_var_decl (type, IDENTIFIER_POINTER (DECL_NAME (decl)));
2266 string_expr = my_build_string (IDENTIFIER_LENGTH (string) + 1,
2267 IDENTIFIER_POINTER (string));
2268 finish_var_decl (decl, string_expr);
2271 for (chain = meth_var_names_chain; chain; chain = TREE_CHAIN (chain))
2273 string = TREE_VALUE (chain);
2274 decl = TREE_PURPOSE (chain);
2275 type = build_array_type
2278 (build_int_cst (NULL_TREE,
2279 IDENTIFIER_LENGTH (string))));
2280 decl = start_var_decl (type, IDENTIFIER_POINTER (DECL_NAME (decl)));
2281 string_expr = my_build_string (IDENTIFIER_LENGTH (string) + 1,
2282 IDENTIFIER_POINTER (string));
2283 finish_var_decl (decl, string_expr);
2286 for (chain = meth_var_types_chain; chain; chain = TREE_CHAIN (chain))
2288 string = TREE_VALUE (chain);
2289 decl = TREE_PURPOSE (chain);
2290 type = build_array_type
2293 (build_int_cst (NULL_TREE,
2294 IDENTIFIER_LENGTH (string))));
2295 decl = start_var_decl (type, IDENTIFIER_POINTER (DECL_NAME (decl)));
2296 string_expr = my_build_string (IDENTIFIER_LENGTH (string) + 1,
2297 IDENTIFIER_POINTER (string));
2298 finish_var_decl (decl, string_expr);
2302 static GTY(()) int selector_reference_idx;
2305 build_selector_reference_decl (void)
2310 sprintf (buf, "_OBJC_SELECTOR_REFERENCES_%d", selector_reference_idx++);
2311 decl = start_var_decl (objc_selector_type, buf);
2317 build_selector_table_decl (void)
2321 if (flag_typed_selectors)
2323 build_selector_template ();
2324 temp = build_array_type (objc_selector_template, NULL_TREE);
2327 temp = build_array_type (objc_selector_type, NULL_TREE);
2329 UOBJC_SELECTOR_TABLE_decl = start_var_decl (temp, "_OBJC_SELECTOR_TABLE");
2332 /* Just a handy wrapper for add_objc_string. */
2335 build_selector (tree ident)
2337 return convert (objc_selector_type,
2338 add_objc_string (ident, meth_var_names));
2342 build_selector_translation_table (void)
2344 tree chain, initlist = NULL_TREE;
2346 tree decl = NULL_TREE;
2348 for (chain = sel_ref_chain; chain; chain = TREE_CHAIN (chain))
2352 if (warn_selector && objc_implementation_context)
2356 for (method_chain = meth_var_names_chain;
2358 method_chain = TREE_CHAIN (method_chain))
2360 if (TREE_VALUE (method_chain) == TREE_VALUE (chain))
2369 if (flag_next_runtime && TREE_PURPOSE (chain))
2370 loc = &DECL_SOURCE_LOCATION (TREE_PURPOSE (chain));
2372 loc = &input_location;
2373 warning ("%Hcreating selector for nonexistent method %qE",
2374 loc, TREE_VALUE (chain));
2378 expr = build_selector (TREE_VALUE (chain));
2379 /* add one for the '\0' character */
2380 offset += IDENTIFIER_LENGTH (TREE_VALUE (chain)) + 1;
2382 if (flag_next_runtime)
2384 decl = TREE_PURPOSE (chain);
2385 finish_var_decl (decl, expr);
2389 if (flag_typed_selectors)
2391 tree eltlist = NULL_TREE;
2392 tree encoding = get_proto_encoding (TREE_PURPOSE (chain));
2393 eltlist = tree_cons (NULL_TREE, expr, NULL_TREE);
2394 eltlist = tree_cons (NULL_TREE, encoding, eltlist);
2395 expr = objc_build_constructor (objc_selector_template,
2396 nreverse (eltlist));
2399 initlist = tree_cons (NULL_TREE, expr, initlist);
2403 if (! flag_next_runtime)
2405 /* Cause the selector table (previously forward-declared)
2406 to be actually output. */
2407 initlist = tree_cons (NULL_TREE,
2408 flag_typed_selectors
2409 ? objc_build_constructor
2410 (objc_selector_template,
2411 tree_cons (NULL_TREE,
2412 build_int_cst (NULL_TREE, 0),
2413 tree_cons (NULL_TREE,
2414 build_int_cst (NULL_TREE, 0),
2416 : build_int_cst (NULL_TREE, 0), initlist);
2417 initlist = objc_build_constructor (TREE_TYPE (UOBJC_SELECTOR_TABLE_decl),
2418 nreverse (initlist));
2419 finish_var_decl (UOBJC_SELECTOR_TABLE_decl, initlist);
2424 get_proto_encoding (tree proto)
2429 if (! METHOD_ENCODING (proto))
2431 encoding = encode_method_prototype (proto);
2432 METHOD_ENCODING (proto) = encoding;
2435 encoding = METHOD_ENCODING (proto);
2437 return add_objc_string (encoding, meth_var_types);
2440 return build_int_cst (NULL_TREE, 0);
2443 /* sel_ref_chain is a list whose "value" fields will be instances of
2444 identifier_node that represent the selector. */
2447 build_typed_selector_reference (tree ident, tree prototype)
2449 tree *chain = &sel_ref_chain;
2455 if (TREE_PURPOSE (*chain) == prototype && TREE_VALUE (*chain) == ident)
2456 goto return_at_index;
2459 chain = &TREE_CHAIN (*chain);
2462 *chain = tree_cons (prototype, ident, NULL_TREE);
2465 expr = build_unary_op (ADDR_EXPR,
2466 build_array_ref (UOBJC_SELECTOR_TABLE_decl,
2467 build_int_cst (NULL_TREE, index)),
2469 return convert (objc_selector_type, expr);
2473 build_selector_reference (tree ident)
2475 tree *chain = &sel_ref_chain;
2481 if (TREE_VALUE (*chain) == ident)
2482 return (flag_next_runtime
2483 ? TREE_PURPOSE (*chain)
2484 : build_array_ref (UOBJC_SELECTOR_TABLE_decl,
2485 build_int_cst (NULL_TREE, index)));
2488 chain = &TREE_CHAIN (*chain);
2491 expr = (flag_next_runtime ? build_selector_reference_decl (): NULL_TREE);
2493 *chain = tree_cons (expr, ident, NULL_TREE);
2495 return (flag_next_runtime
2497 : build_array_ref (UOBJC_SELECTOR_TABLE_decl,
2498 build_int_cst (NULL_TREE, index)));
2501 static GTY(()) int class_reference_idx;
2504 build_class_reference_decl (void)
2509 sprintf (buf, "_OBJC_CLASS_REFERENCES_%d", class_reference_idx++);
2510 decl = start_var_decl (objc_class_type, buf);
2515 /* Create a class reference, but don't create a variable to reference
2519 add_class_reference (tree ident)
2523 if ((chain = cls_ref_chain))
2528 if (ident == TREE_VALUE (chain))
2532 chain = TREE_CHAIN (chain);
2536 /* Append to the end of the list */
2537 TREE_CHAIN (tail) = tree_cons (NULL_TREE, ident, NULL_TREE);
2540 cls_ref_chain = tree_cons (NULL_TREE, ident, NULL_TREE);
2543 /* Get a class reference, creating it if necessary. Also create the
2544 reference variable. */
2547 objc_get_class_reference (tree ident)
2552 if (processing_template_decl)
2553 /* Must wait until template instantiation time. */
2554 return build_min_nt (CLASS_REFERENCE_EXPR, ident);
2555 if (TREE_CODE (ident) == TYPE_DECL)
2556 ident = DECL_NAME (ident);
2560 if (!(ident = objc_is_class_name (ident)))
2562 error ("%qs is not an Objective-C class name or alias",
2563 IDENTIFIER_POINTER (orig_ident));
2564 return error_mark_node;
2567 if (flag_next_runtime && !flag_zero_link)
2572 for (chain = &cls_ref_chain; *chain; chain = &TREE_CHAIN (*chain))
2573 if (TREE_VALUE (*chain) == ident)
2575 if (! TREE_PURPOSE (*chain))
2576 TREE_PURPOSE (*chain) = build_class_reference_decl ();
2578 return TREE_PURPOSE (*chain);
2581 decl = build_class_reference_decl ();
2582 *chain = tree_cons (decl, ident, NULL_TREE);
2589 add_class_reference (ident);
2591 params = build_tree_list (NULL_TREE,
2592 my_build_string (IDENTIFIER_LENGTH (ident) + 1,
2593 IDENTIFIER_POINTER (ident)));
2595 assemble_external (objc_get_class_decl);
2596 return build_function_call (objc_get_class_decl, params);
2600 /* For each string section we have a chain which maps identifier nodes
2601 to decls for the strings. */
2604 add_objc_string (tree ident, enum string_section section)
2608 if (section == class_names)
2609 chain = &class_names_chain;
2610 else if (section == meth_var_names)
2611 chain = &meth_var_names_chain;
2612 else if (section == meth_var_types)
2613 chain = &meth_var_types_chain;
2619 if (TREE_VALUE (*chain) == ident)
2620 return convert (string_type_node,
2621 build_unary_op (ADDR_EXPR, TREE_PURPOSE (*chain), 1));
2623 chain = &TREE_CHAIN (*chain);
2626 decl = build_objc_string_decl (section);
2628 *chain = tree_cons (decl, ident, NULL_TREE);
2630 return convert (string_type_node, build_unary_op (ADDR_EXPR, decl, 1));
2633 static GTY(()) int class_names_idx;
2634 static GTY(()) int meth_var_names_idx;
2635 static GTY(()) int meth_var_types_idx;
2638 build_objc_string_decl (enum string_section section)
2643 if (section == class_names)
2644 sprintf (buf, "_OBJC_CLASS_NAME_%d", class_names_idx++);
2645 else if (section == meth_var_names)
2646 sprintf (buf, "_OBJC_METH_VAR_NAME_%d", meth_var_names_idx++);
2647 else if (section == meth_var_types)
2648 sprintf (buf, "_OBJC_METH_VAR_TYPE_%d", meth_var_types_idx++);
2650 ident = get_identifier (buf);
2652 decl = build_decl (VAR_DECL, ident, build_array_type (char_type_node, 0));
2653 DECL_EXTERNAL (decl) = 1;
2654 TREE_PUBLIC (decl) = 0;
2655 TREE_USED (decl) = 1;
2656 TREE_CONSTANT (decl) = 1;
2657 DECL_CONTEXT (decl) = 0;
2658 DECL_ARTIFICIAL (decl) = 1;
2660 DECL_THIS_STATIC (decl) = 1; /* squash redeclaration errors */
2663 make_decl_rtl (decl);
2664 pushdecl_top_level (decl);
2671 objc_declare_alias (tree alias_ident, tree class_ident)
2673 tree underlying_class;
2676 if (current_namespace != global_namespace) {
2677 error ("Objective-C declarations may only appear in global scope");
2679 #endif /* OBJCPLUS */
2681 if (!(underlying_class = objc_is_class_name (class_ident)))
2682 warning ("cannot find class %qs", IDENTIFIER_POINTER (class_ident));
2683 else if (objc_is_class_name (alias_ident))
2684 warning ("class %qs already exists", IDENTIFIER_POINTER (alias_ident));
2686 alias_chain = tree_cons (underlying_class, alias_ident, alias_chain);
2690 objc_declare_class (tree ident_list)
2694 if (current_namespace != global_namespace) {
2695 error ("Objective-C declarations may only appear in global scope");
2697 #endif /* OBJCPLUS */
2699 for (list = ident_list; list; list = TREE_CHAIN (list))
2701 tree ident = TREE_VALUE (list);
2703 if (! objc_is_class_name (ident))
2705 tree record = lookup_name (ident), type = record;
2709 if (TREE_CODE (record) == TYPE_DECL)
2710 type = DECL_ORIGINAL_TYPE (record);
2712 if (!TYPE_HAS_OBJC_INFO (type)
2713 || !TYPE_OBJC_INTERFACE (type))
2715 error ("%qs redeclared as different kind of symbol",
2716 IDENTIFIER_POINTER (ident));
2717 error ("%Jprevious declaration of '%D'",
2722 record = xref_tag (RECORD_TYPE, ident);
2723 INIT_TYPE_OBJC_INFO (record);
2724 TYPE_OBJC_INTERFACE (record) = ident;
2725 class_chain = tree_cons (NULL_TREE, ident, class_chain);
2731 objc_is_class_name (tree ident)
2735 if (ident && TREE_CODE (ident) == IDENTIFIER_NODE
2736 && identifier_global_value (ident))
2737 ident = identifier_global_value (ident);
2738 while (ident && TREE_CODE (ident) == TYPE_DECL && DECL_ORIGINAL_TYPE (ident))
2739 ident = OBJC_TYPE_NAME (DECL_ORIGINAL_TYPE (ident));
2741 if (ident && TREE_CODE (ident) == RECORD_TYPE)
2742 ident = OBJC_TYPE_NAME (ident);
2744 if (ident && TREE_CODE (ident) == TYPE_DECL)
2745 ident = DECL_NAME (ident);
2747 if (!ident || TREE_CODE (ident) != IDENTIFIER_NODE)
2750 if (lookup_interface (ident))
2753 for (chain = class_chain; chain; chain = TREE_CHAIN (chain))
2755 if (ident == TREE_VALUE (chain))
2759 for (chain = alias_chain; chain; chain = TREE_CHAIN (chain))
2761 if (ident == TREE_VALUE (chain))
2762 return TREE_PURPOSE (chain);
2768 /* Check whether TYPE is either 'id' or 'Class'. */
2771 objc_is_id (tree type)
2773 if (type && TREE_CODE (type) == IDENTIFIER_NODE
2774 && identifier_global_value (type))
2775 type = identifier_global_value (type);
2777 if (type && TREE_CODE (type) == TYPE_DECL)
2778 type = TREE_TYPE (type);
2780 /* NB: This function may be called before the ObjC front-end has
2781 been initialized, in which case OBJC_OBJECT_TYPE will (still) be NULL. */
2782 return (objc_object_type && type
2783 && (IS_ID (type) || IS_CLASS (type) || IS_SUPER (type))
2788 /* Check whether TYPE is either 'id', 'Class', or a pointer to an ObjC
2789 class instance. This is needed by other parts of the compiler to
2790 handle ObjC types gracefully. */
2793 objc_is_object_ptr (tree type)
2797 type = TYPE_MAIN_VARIANT (type);
2798 if (!POINTER_TYPE_P (type))
2801 ret = objc_is_id (type);
2803 ret = objc_is_class_name (TREE_TYPE (type));
2809 lookup_interface (tree ident)
2814 if (ident && TREE_CODE (ident) == TYPE_DECL)
2815 ident = DECL_NAME (ident);
2817 for (chain = interface_chain; chain; chain = TREE_CHAIN (chain))
2819 if (ident == CLASS_NAME (chain))
2825 /* Implement @defs (<classname>) within struct bodies. */
2828 objc_get_class_ivars (tree class_name)
2830 tree interface = lookup_interface (class_name);
2833 return get_class_ivars (interface);
2835 error ("cannot find interface declaration for %qs",
2836 IDENTIFIER_POINTER (class_name));
2838 return error_mark_node;
2841 /* Used by: build_private_template, continue_class,
2842 and for @defs constructs. */
2845 get_class_ivars (tree interface)
2847 tree ivar_chain = copy_list (CLASS_RAW_IVARS (interface));
2849 /* Both CLASS_RAW_IVARS and CLASS_IVARS contain a list of ivars declared
2850 by the current class (i.e., they do not include super-class ivars).
2851 However, the CLASS_IVARS list will be side-effected by a call to
2852 finish_struct(), which will fill in field offsets. */
2853 if (!CLASS_IVARS (interface))
2854 CLASS_IVARS (interface) = ivar_chain;
2856 while (CLASS_SUPER_NAME (interface))
2858 /* Prepend super-class ivars. */
2859 interface = lookup_interface (CLASS_SUPER_NAME (interface));
2860 ivar_chain = chainon (copy_list (CLASS_RAW_IVARS (interface)),
2868 objc_create_temporary_var (tree type)
2872 decl = build_decl (VAR_DECL, NULL_TREE, type);
2873 TREE_USED (decl) = 1;
2874 DECL_ARTIFICIAL (decl) = 1;
2875 DECL_IGNORED_P (decl) = 1;
2876 DECL_CONTEXT (decl) = current_function_decl;
2881 /* Exception handling constructs. We begin by having the parser do most
2882 of the work and passing us blocks. What we do next depends on whether
2883 we're doing "native" exception handling or legacy Darwin setjmp exceptions.
2884 We abstract all of this in a handful of appropriately named routines. */
2886 /* Stack of open try blocks. */
2888 struct objc_try_context
2890 struct objc_try_context *outer;
2892 /* Statements (or statement lists) as processed by the parser. */
2896 /* Some file position locations. */
2897 location_t try_locus;
2898 location_t end_try_locus;
2899 location_t end_catch_locus;
2900 location_t finally_locus;
2901 location_t end_finally_locus;
2903 /* A STATEMENT_LIST of CATCH_EXPRs, appropriate for sticking into op1
2904 of a TRY_CATCH_EXPR. Even when doing Darwin setjmp. */
2907 /* The CATCH_EXPR of an open @catch clause. */
2910 /* The VAR_DECL holding the Darwin equivalent of EXC_PTR_EXPR. */
2916 static struct objc_try_context *cur_try_context;
2918 /* This hook, called via lang_eh_runtime_type, generates a runtime object
2919 that represents TYPE. For Objective-C, this is just the class name. */
2920 /* ??? Isn't there a class object or some such? Is it easy to get? */
2924 objc_eh_runtime_type (tree type)
2926 return add_objc_string (OBJC_TYPE_NAME (TREE_TYPE (type)), class_names);
2930 /* Initialize exception handling. */
2933 objc_init_exceptions (void)
2935 static bool done = false;
2940 if (flag_objc_sjlj_exceptions)
2942 /* On Darwin, ObjC exceptions require a sufficiently recent
2943 version of the runtime, so the user must ask for them explicitly. */
2944 if (!flag_objc_exceptions)
2945 warning ("use %<-fobjc-exceptions%> to enable Objective-C "
2946 "exception syntax");
2951 c_eh_initialized_p = true;
2952 eh_personality_libfunc
2953 = init_one_libfunc (USING_SJLJ_EXCEPTIONS
2954 ? "__gnu_objc_personality_sj0"
2955 : "__gnu_objc_personality_v0");
2956 using_eh_for_cleanups ();
2957 lang_eh_runtime_type = objc_eh_runtime_type;
2962 /* Build an EXC_PTR_EXPR, or the moral equivalent. In the case of Darwin,
2963 we'll arrange for it to be initialized (and associated with a binding)
2967 objc_build_exc_ptr (void)
2969 if (flag_objc_sjlj_exceptions)
2971 tree var = cur_try_context->caught_decl;
2974 var = objc_create_temporary_var (objc_object_type);
2975 cur_try_context->caught_decl = var;
2980 return build (EXC_PTR_EXPR, objc_object_type);
2983 /* Build "objc_exception_try_exit(&_stack)". */
2986 next_sjlj_build_try_exit (void)
2989 t = build_fold_addr_expr (cur_try_context->stack_decl);
2990 t = tree_cons (NULL, t, NULL);
2991 t = build_function_call (objc_exception_try_exit_decl, t);
2996 objc_exception_try_enter (&_stack);
2997 if (_setjmp(&_stack.buf))
3001 Return the COND_EXPR. Note that the THEN and ELSE fields are left
3002 empty, ready for the caller to fill them in. */
3005 next_sjlj_build_enter_and_setjmp (void)
3007 tree t, enter, sj, cond;
3009 t = build_fold_addr_expr (cur_try_context->stack_decl);
3010 t = tree_cons (NULL, t, NULL);
3011 enter = build_function_call (objc_exception_try_enter_decl, t);
3013 t = build_component_ref (cur_try_context->stack_decl,
3014 get_identifier ("buf"));
3015 t = build_fold_addr_expr (t);
3016 t = convert (ptr_type_node, t);
3017 t = tree_cons (NULL, t, NULL);
3018 sj = build_function_call (objc_setjmp_decl, t);
3020 cond = build (COMPOUND_EXPR, TREE_TYPE (sj), enter, sj);
3021 cond = lang_hooks.truthvalue_conversion (cond);
3023 return build (COND_EXPR, void_type_node, cond, NULL, NULL);
3027 DECL = objc_exception_extract(&_stack);
3031 next_sjlj_build_exc_extract (tree decl)
3035 t = build_fold_addr_expr (cur_try_context->stack_decl);
3036 t = tree_cons (NULL, t, NULL);
3037 t = build_function_call (objc_exception_extract_decl, t);
3038 t = convert (TREE_TYPE (decl), t);
3039 t = build (MODIFY_EXPR, void_type_node, decl, t);
3045 if (objc_exception_match(obj_get_class(TYPE), _caught)
3052 objc_exception_try_exit(&_stack);
3054 from the sequence of CATCH_EXPRs in the current try context. */
3057 next_sjlj_build_catch_list (void)
3059 tree_stmt_iterator i = tsi_start (cur_try_context->catch_list);
3061 tree *last = &catch_seq;
3062 bool saw_id = false;
3064 for (; !tsi_end_p (i); tsi_next (&i))
3066 tree stmt = tsi_stmt (i);
3067 tree type = CATCH_TYPES (stmt);
3068 tree body = CATCH_BODY (stmt);
3080 if (type == error_mark_node)
3081 cond = error_mark_node;
3084 args = tree_cons (NULL, cur_try_context->caught_decl, NULL);
3085 t = objc_get_class_reference (OBJC_TYPE_NAME (TREE_TYPE (type)));
3086 args = tree_cons (NULL, t, args);
3087 t = build_function_call (objc_exception_match_decl, args);
3088 cond = lang_hooks.truthvalue_conversion (t);
3090 t = build (COND_EXPR, void_type_node, cond, body, NULL);
3091 SET_EXPR_LOCUS (t, EXPR_LOCUS (stmt));
3094 last = &COND_EXPR_ELSE (t);
3100 t = build (MODIFY_EXPR, void_type_node, cur_try_context->rethrow_decl,
3101 cur_try_context->caught_decl);
3102 SET_EXPR_LOCATION (t, cur_try_context->end_catch_locus);
3103 append_to_statement_list (t, last);
3105 t = next_sjlj_build_try_exit ();
3106 SET_EXPR_LOCATION (t, cur_try_context->end_catch_locus);
3107 append_to_statement_list (t, last);
3113 /* Build a complete @try-@catch-@finally block for legacy Darwin setjmp
3114 exception handling. We aim to build:
3117 struct _objc_exception_data _stack;
3118 id volatile _rethrow = 0;
3121 objc_exception_try_enter (&_stack);
3122 if (_setjmp(&_stack.buf))
3124 id _caught = objc_exception_extract(&_stack);
3125 objc_exception_try_enter (&_stack);
3126 if (_setjmp(&_stack.buf))
3127 _rethrow = objc_exception_extract(&_stack);
3137 objc_exception_try_exit(&_stack);
3140 objc_exception_throw(_rethrow);
3144 If CATCH-LIST is empty, we can omit all of the block containing
3145 "_caught" except for the setting of _rethrow. Note the use of
3146 a real TRY_FINALLY_EXPR here, which is not involved in EH per-se,
3147 but handles goto and other exits from the block. */
3150 next_sjlj_build_try_catch_finally (void)
3152 tree rethrow_decl, stack_decl, t;
3153 tree catch_seq, try_fin, bind;
3155 /* Create the declarations involved. */
3156 t = xref_tag (RECORD_TYPE, get_identifier (UTAG_EXCDATA));
3157 stack_decl = objc_create_temporary_var (t);
3158 cur_try_context->stack_decl = stack_decl;
3160 rethrow_decl = objc_create_temporary_var (objc_object_type);
3161 cur_try_context->rethrow_decl = rethrow_decl;
3162 TREE_THIS_VOLATILE (rethrow_decl) = 1;
3163 TREE_CHAIN (rethrow_decl) = stack_decl;
3165 /* Build the outermost variable binding level. */
3166 bind = build (BIND_EXPR, void_type_node, rethrow_decl, NULL, NULL);
3167 SET_EXPR_LOCATION (bind, cur_try_context->try_locus);
3168 TREE_SIDE_EFFECTS (bind) = 1;
3170 /* Initialize rethrow_decl. */
3171 t = build (MODIFY_EXPR, void_type_node, rethrow_decl,
3172 convert (objc_object_type, null_pointer_node));
3173 SET_EXPR_LOCATION (t, cur_try_context->try_locus);
3174 append_to_statement_list (t, &BIND_EXPR_BODY (bind));
3176 /* Build the outermost TRY_FINALLY_EXPR. */
3177 try_fin = build (TRY_FINALLY_EXPR, void_type_node, NULL, NULL);
3178 SET_EXPR_LOCATION (try_fin, cur_try_context->try_locus);
3179 TREE_SIDE_EFFECTS (try_fin) = 1;
3180 append_to_statement_list (try_fin, &BIND_EXPR_BODY (bind));
3182 /* Create the complete catch sequence. */
3183 if (cur_try_context->catch_list)
3185 tree caught_decl = objc_build_exc_ptr ();
3186 catch_seq = build_stmt (BIND_EXPR, caught_decl, NULL, NULL);
3188 t = next_sjlj_build_exc_extract (caught_decl);
3189 append_to_statement_list (t, &BIND_EXPR_BODY (catch_seq));
3191 t = next_sjlj_build_enter_and_setjmp ();
3192 COND_EXPR_THEN (t) = next_sjlj_build_exc_extract (rethrow_decl);
3193 COND_EXPR_ELSE (t) = next_sjlj_build_catch_list ();
3194 append_to_statement_list (t, &BIND_EXPR_BODY (catch_seq));
3197 catch_seq = next_sjlj_build_exc_extract (rethrow_decl);
3198 SET_EXPR_LOCATION (catch_seq, cur_try_context->end_try_locus);
3200 /* Build the main register-and-try if statement. */
3201 t = next_sjlj_build_enter_and_setjmp ();
3202 SET_EXPR_LOCATION (t, cur_try_context->try_locus);
3203 COND_EXPR_THEN (t) = catch_seq;
3204 COND_EXPR_ELSE (t) = cur_try_context->try_body;
3205 TREE_OPERAND (try_fin, 0) = t;
3207 /* Build the complete FINALLY statement list. */
3208 t = next_sjlj_build_try_exit ();
3209 t = build_stmt (COND_EXPR,
3210 lang_hooks.truthvalue_conversion (rethrow_decl),
3212 SET_EXPR_LOCATION (t, cur_try_context->finally_locus);
3213 append_to_statement_list (t, &TREE_OPERAND (try_fin, 1));
3215 append_to_statement_list (cur_try_context->finally_body,
3216 &TREE_OPERAND (try_fin, 1));
3218 t = tree_cons (NULL, rethrow_decl, NULL);
3219 t = build_function_call (objc_exception_throw_decl, t);
3220 t = build_stmt (COND_EXPR,
3221 lang_hooks.truthvalue_conversion (rethrow_decl),
3223 SET_EXPR_LOCATION (t, cur_try_context->end_finally_locus);
3224 append_to_statement_list (t, &TREE_OPERAND (try_fin, 1));
3229 /* Called just after parsing the @try and its associated BODY. We now
3230 must prepare for the tricky bits -- handling the catches and finally. */
3233 objc_begin_try_stmt (location_t try_locus, tree body)
3235 struct objc_try_context *c = xcalloc (1, sizeof (*c));
3236 c->outer = cur_try_context;
3238 c->try_locus = try_locus;
3239 c->end_try_locus = input_location;
3240 cur_try_context = c;
3242 objc_init_exceptions ();
3245 /* Called just after parsing "@catch (parm)". Open a binding level,
3246 enter DECL into the binding level, and initialize it. Leave the
3247 binding level open while the body of the compound statement is parsed. */
3250 objc_begin_catch_clause (tree decl)
3252 tree compound, type, t;
3254 /* Begin a new scope that the entire catch clause will live in. */
3255 compound = c_begin_compound_stmt (true);
3257 /* The parser passed in a PARM_DECL, but what we really want is a VAR_DECL. */
3258 decl = build_decl (VAR_DECL, DECL_NAME (decl), TREE_TYPE (decl));
3259 lang_hooks.decls.pushdecl (decl);
3261 /* Since a decl is required here by syntax, don't warn if its unused. */
3262 /* ??? As opposed to __attribute__((unused))? Anyway, this appears to
3263 be what the previous objc implementation did. */
3264 TREE_USED (decl) = 1;
3266 /* Verify that the type of the catch is valid. It must be a pointer
3267 to an Objective-C class, or "id" (which is catch-all). */
3268 type = TREE_TYPE (decl);
3270 if (POINTER_TYPE_P (type) && objc_is_object_id (TREE_TYPE (type)))
3272 else if (!POINTER_TYPE_P (type) || !TYPED_OBJECT (TREE_TYPE (type)))
3274 error ("@catch parameter is not a known Objective-C class type");
3275 type = error_mark_node;
3277 else if (cur_try_context->catch_list)
3279 /* Examine previous @catch clauses and see if we've already
3280 caught the type in question. */
3281 tree_stmt_iterator i = tsi_start (cur_try_context->catch_list);
3282 for (; !tsi_end_p (i); tsi_next (&i))
3284 tree stmt = tsi_stmt (i);
3285 t = CATCH_TYPES (stmt);
3286 if (t == error_mark_node)
3288 if (!t || objc_comptypes (TREE_TYPE (t), TREE_TYPE (type), 0) == 1)
3290 warning ("exception of type %<%T%> will be caught",
3292 warning ("%H by earlier handler for %<%T%>",
3293 EXPR_LOCUS (stmt), TREE_TYPE (t ? t : objc_object_type));
3299 /* Record the data for the catch in the try context so that we can
3300 finalize it later. */
3301 t = build_stmt (CATCH_EXPR, type, compound);
3302 cur_try_context->current_catch = t;
3304 /* Initialize the decl from the EXC_PTR_EXPR we get from the runtime. */
3305 t = objc_build_exc_ptr ();
3306 t = convert (TREE_TYPE (decl), t);
3307 t = build (MODIFY_EXPR, void_type_node, decl, t);
3311 /* Called just after parsing the closing brace of a @catch clause. Close
3312 the open binding level, and record a CATCH_EXPR for it. */
3315 objc_finish_catch_clause (void)
3317 tree c = cur_try_context->current_catch;
3318 cur_try_context->current_catch = NULL;
3319 cur_try_context->end_catch_locus = input_location;
3321 CATCH_BODY (c) = c_end_compound_stmt (CATCH_BODY (c), 1);
3322 append_to_statement_list (c, &cur_try_context->catch_list);
3325 /* Called after parsing a @finally clause and its associated BODY.
3326 Record the body for later placement. */
3329 objc_build_finally_clause (location_t finally_locus, tree body)
3331 cur_try_context->finally_body = body;
3332 cur_try_context->finally_locus = finally_locus;
3333 cur_try_context->end_finally_locus = input_location;
3336 /* Called to finalize a @try construct. */
3339 objc_finish_try_stmt (void)
3341 struct objc_try_context *c = cur_try_context;
3344 if (c->catch_list == NULL && c->finally_body == NULL)
3345 error ("%<@try%> without %<@catch%> or %<@finally%>");
3347 /* If we're doing Darwin setjmp exceptions, build the big nasty. */
3348 if (flag_objc_sjlj_exceptions)
3350 if (!cur_try_context->finally_body)
3352 cur_try_context->finally_locus = input_location;
3353 cur_try_context->end_finally_locus = input_location;
3355 stmt = next_sjlj_build_try_catch_finally ();
3359 /* Otherwise, nest the CATCH inside a FINALLY. */
3363 stmt = build_stmt (TRY_CATCH_EXPR, stmt, c->catch_list);
3364 SET_EXPR_LOCATION (stmt, cur_try_context->try_locus);
3366 if (c->finally_body)
3368 stmt = build_stmt (TRY_FINALLY_EXPR, stmt, c->finally_body);
3369 SET_EXPR_LOCATION (stmt, cur_try_context->try_locus);
3374 cur_try_context = c->outer;
3379 objc_build_throw_stmt (tree throw_expr)
3383 objc_init_exceptions ();
3385 if (throw_expr == NULL)
3387 /* If we're not inside a @catch block, there is no "current
3388 exception" to be rethrown. */
3389 if (cur_try_context == NULL
3390 || cur_try_context->current_catch == NULL)
3392 error ("%<@throw%> (rethrow) used outside of a @catch block");
3396 /* Otherwise the object is still sitting in the EXC_PTR_EXPR
3397 value that we get from the runtime. */
3398 throw_expr = objc_build_exc_ptr ();
3401 /* A throw is just a call to the runtime throw function with the
3402 object as a parameter. */
3403 args = tree_cons (NULL, throw_expr, NULL);
3404 return add_stmt (build_function_call (objc_exception_throw_decl, args));
3408 objc_build_synchronized (location_t start_locus, tree mutex, tree body)
3412 /* First lock the mutex. */
3413 mutex = save_expr (mutex);
3414 args = tree_cons (NULL, mutex, NULL);
3415 call = build_function_call (objc_sync_enter_decl, args);
3416 SET_EXPR_LOCATION (call, start_locus);
3419 /* Build the mutex unlock. */
3420 args = tree_cons (NULL, mutex, NULL);
3421 call = build_function_call (objc_sync_exit_decl, args);
3422 SET_EXPR_LOCATION (call, input_location);
3424 /* Put the that and the body in a TRY_FINALLY. */
3425 objc_begin_try_stmt (start_locus, body);
3426 objc_build_finally_clause (input_location, call);
3427 objc_finish_try_stmt ();
3431 /* Predefine the following data type:
3433 struct _objc_exception_data
3439 /* The following yuckiness should prevent users from having to #include
3440 <setjmp.h> in their code... */
3442 #ifdef TARGET_POWERPC
3443 /* snarfed from /usr/include/ppc/setjmp.h */
3444 #define _JBLEN (26 + 36 + 129 + 1)
3446 /* snarfed from /usr/include/i386/{setjmp,signal}.h */
3451 build_next_objc_exception_stuff (void)
3453 tree field_decl, field_decl_chain, index, temp_type;
3455 objc_exception_data_template
3456 = start_struct (RECORD_TYPE, get_identifier (UTAG_EXCDATA));
3458 /* int buf[_JBLEN]; */
3460 index = build_index_type (build_int_cst (NULL_TREE, _JBLEN - 1));
3461 field_decl = create_field_decl (build_array_type (integer_type_node, index),
3463 field_decl_chain = field_decl;
3465 /* void *pointers[4]; */
3467 index = build_index_type (build_int_cst (NULL_TREE, 4 - 1));
3468 field_decl = create_field_decl (build_array_type (ptr_type_node, index),
3470 chainon (field_decl_chain, field_decl);
3472 finish_struct (objc_exception_data_template, field_decl_chain, NULL_TREE);
3474 /* int _setjmp(...); */
3475 /* If the user includes <setjmp.h>, this shall be superseded by
3476 'int _setjmp(jmp_buf);' */
3477 temp_type = build_function_type (integer_type_node, NULL_TREE);
3479 = builtin_function (TAG_SETJMP, temp_type, 0, NOT_BUILT_IN, NULL, NULL_TREE);
3481 /* id objc_exception_extract(struct _objc_exception_data *); */
3483 = build_function_type (objc_object_type,
3484 tree_cons (NULL_TREE,
3485 build_pointer_type (objc_exception_data_template),
3487 objc_exception_extract_decl
3488 = builtin_function (TAG_EXCEPTIONEXTRACT, temp_type, 0, NOT_BUILT_IN, NULL, NULL_TREE);
3489 /* void objc_exception_try_enter(struct _objc_exception_data *); */
3490 /* void objc_exception_try_exit(struct _objc_exception_data *); */
3492 = build_function_type (void_type_node,
3493 tree_cons (NULL_TREE,
3494 build_pointer_type (objc_exception_data_template),
3496 objc_exception_try_enter_decl
3497 = builtin_function (TAG_EXCEPTIONTRYENTER, temp_type, 0, NOT_BUILT_IN, NULL, NULL_TREE);
3498 objc_exception_try_exit_decl
3499 = builtin_function (TAG_EXCEPTIONTRYEXIT, temp_type, 0, NOT_BUILT_IN, NULL, NULL_TREE);
3501 /* int objc_exception_match(id, id); */
3503 = build_function_type (integer_type_node,
3504 tree_cons (NULL_TREE, objc_object_type,
3505 tree_cons (NULL_TREE, objc_object_type,
3506 OBJC_VOID_AT_END)));
3507 objc_exception_match_decl
3508 = builtin_function (TAG_EXCEPTIONMATCH, temp_type, 0, NOT_BUILT_IN, NULL, NULL_TREE);
3512 build_objc_exception_stuff (void)
3514 tree noreturn_list, nothrow_list, temp_type;
3516 noreturn_list = tree_cons (get_identifier ("noreturn"), NULL, NULL);
3517 nothrow_list = tree_cons (get_identifier ("nothrow"), NULL, NULL);
3519 /* void objc_exception_throw(id) __attribute__((noreturn)); */
3520 /* void objc_sync_enter(id); */
3521 /* void objc_sync_exit(id); */
3522 temp_type = build_function_type (void_type_node,
3523 tree_cons (NULL_TREE, objc_object_type,
3525 objc_exception_throw_decl
3526 = builtin_function (TAG_EXCEPTIONTHROW, temp_type, 0, NOT_BUILT_IN, NULL,
3528 objc_sync_enter_decl
3529 = builtin_function (TAG_SYNCENTER, temp_type, 0, NOT_BUILT_IN,
3530 NULL, nothrow_list);
3532 = builtin_function (TAG_SYNCEXIT, temp_type, 0, NOT_BUILT_IN,
3533 NULL, nothrow_list);
3536 /* Construct a C struct corresponding to ObjC class CLASS, with the same
3539 struct <classname> {
3540 struct _objc_class *isa;
3545 build_private_template (tree class)
3547 if (!CLASS_STATIC_TEMPLATE (class))
3549 tree record = start_struct (RECORD_TYPE, CLASS_NAME (class));
3551 finish_struct (record, get_class_ivars (class), NULL_TREE);
3552 /* mark this record as class template - for class type checking */
3553 INIT_TYPE_OBJC_INFO (record);
3554 TYPE_OBJC_INTERFACE (record) = class;
3555 CLASS_STATIC_TEMPLATE (class) = record;
3559 /* Begin code generation for protocols... */
3561 /* struct _objc_protocol {
3562 struct _objc_class *isa;
3563 char *protocol_name;
3564 struct _objc_protocol **protocol_list;
3565 struct _objc__method_prototype_list *instance_methods;
3566 struct _objc__method_prototype_list *class_methods;
3570 build_protocol_template (void)
3572 tree field_decl, field_decl_chain;
3574 objc_protocol_template = start_struct (RECORD_TYPE,
3575 get_identifier (UTAG_PROTOCOL));
3577 /* struct _objc_class *isa; */
3578 field_decl = create_field_decl (build_pointer_type
3579 (xref_tag (RECORD_TYPE,
3580 get_identifier (UTAG_CLASS))),
3582 field_decl_chain = field_decl;
3584 /* char *protocol_name; */
3585 field_decl = create_field_decl (string_type_node, "protocol_name");
3586 chainon (field_decl_chain, field_decl);
3588 /* struct _objc_protocol **protocol_list; */
3589 field_decl = create_field_decl (build_pointer_type
3591 (objc_protocol_template)),
3593 chainon (field_decl_chain, field_decl);
3595 /* struct objc_method_list *instance_methods; */
3596 field_decl = create_field_decl (build_pointer_type
3597 (xref_tag (RECORD_TYPE,
3599 (UTAG_METHOD_PROTOTYPE_LIST))),
3600 "instance_methods");
3601 chainon (field_decl_chain, field_decl);
3603 /* struct objc_method_list *class_methods; */
3604 field_decl = create_field_decl (build_pointer_type
3605 (xref_tag (RECORD_TYPE,
3607 (UTAG_METHOD_PROTOTYPE_LIST))),
3609 chainon (field_decl_chain, field_decl);
3611 finish_struct (objc_protocol_template, field_decl_chain, NULL_TREE);
3615 build_descriptor_table_initializer (tree type, tree entries)
3617 tree initlist = NULL_TREE;
3621 tree eltlist = NULL_TREE;
3624 = tree_cons (NULL_TREE,
3625 build_selector (METHOD_SEL_NAME (entries)), NULL_TREE);
3627 = tree_cons (NULL_TREE,
3628 add_objc_string (METHOD_ENCODING (entries),
3633 = tree_cons (NULL_TREE,
3634 objc_build_constructor (type, nreverse (eltlist)),
3637 entries = TREE_CHAIN (entries);
3641 return objc_build_constructor (build_array_type (type, 0),
3642 nreverse (initlist));
3645 /* struct objc_method_prototype_list {
3647 struct objc_method_prototype {
3654 build_method_prototype_list_template (tree list_type, int size)
3656 tree objc_ivar_list_record;
3657 tree field_decl, field_decl_chain;
3659 /* Generate an unnamed struct definition. */
3661 objc_ivar_list_record = start_struct (RECORD_TYPE, NULL_TREE);
3663 /* int method_count; */
3664 field_decl = create_field_decl (integer_type_node, "method_count");
3665 field_decl_chain = field_decl;
3667 /* struct objc_method method_list[]; */
3668 field_decl = create_field_decl (build_array_type
3671 (build_int_cst (NULL_TREE, size - 1))),
3673 chainon (field_decl_chain, field_decl);
3675 finish_struct (objc_ivar_list_record, field_decl_chain, NULL_TREE);
3677 return objc_ivar_list_record;
3681 build_method_prototype_template (void)
3684 tree field_decl, field_decl_chain;
3687 = start_struct (RECORD_TYPE, get_identifier (UTAG_METHOD_PROTOTYPE));
3690 field_decl = create_field_decl (objc_selector_type, "_cmd");
3691 field_decl_chain = field_decl;
3693 /* char *method_types; */
3694 field_decl = create_field_decl (string_type_node, "method_types");
3695 chainon (field_decl_chain, field_decl);
3697 finish_struct (proto_record, field_decl_chain, NULL_TREE);
3699 return proto_record;
3703 objc_method_parm_type (tree type)
3705 type = TREE_VALUE (TREE_TYPE (type));
3706 if (TREE_CODE (type) == TYPE_DECL)
3707 type = TREE_TYPE (type);
3708 return TYPE_MAIN_VARIANT (type);
3712 objc_encoded_type_size (tree type)
3714 int sz = int_size_in_bytes (type);
3716 /* Make all integer and enum types at least as large
3718 if (sz > 0 && INTEGRAL_TYPE_P (type))
3719 sz = MAX (sz, int_size_in_bytes (integer_type_node));
3720 /* Treat arrays as pointers, since that's how they're
3722 else if (TREE_CODE (type) == ARRAY_TYPE)
3723 sz = int_size_in_bytes (ptr_type_node);
3728 encode_method_prototype (tree method_decl)
3735 /* ONEWAY and BYCOPY, for remote object are the only method qualifiers. */
3736 encode_type_qualifiers (TREE_PURPOSE (TREE_TYPE (method_decl)));
3738 /* Encode return type. */
3739 encode_type (objc_method_parm_type (method_decl),
3740 obstack_object_size (&util_obstack),
3741 OBJC_ENCODE_INLINE_DEFS);
3744 /* The first two arguments (self and _cmd) are pointers; account for
3746 i = int_size_in_bytes (ptr_type_node);
3747 parm_offset = 2 * i;
3748 for (parms = METHOD_SEL_ARGS (method_decl); parms;
3749 parms = TREE_CHAIN (parms))
3751 tree type = objc_method_parm_type (parms);
3752 int sz = objc_encoded_type_size (type);
3754 /* If a type size is not known, bail out. */
3757 error ("%Jtype '%D' does not have a known size",
3759 /* Pretend that the encoding succeeded; the compilation will
3760 fail nevertheless. */
3761 goto finish_encoding;
3766 sprintf (buf, "%d@0:%d", parm_offset, i);
3767 obstack_grow (&util_obstack, buf, strlen (buf));
3769 /* Argument types. */
3770 parm_offset = 2 * i;
3771 for (parms = METHOD_SEL_ARGS (method_decl); parms;
3772 parms = TREE_CHAIN (parms))
3774 tree type = objc_method_parm_type (parms);
3776 /* Process argument qualifiers for user supplied arguments. */
3777 encode_type_qualifiers (TREE_PURPOSE (TREE_TYPE (parms)));
3780 encode_type (type, obstack_object_size (&util_obstack),
3781 OBJC_ENCODE_INLINE_DEFS);
3783 /* Compute offset. */
3784 sprintf (buf, "%d", parm_offset);
3785 parm_offset += objc_encoded_type_size (type);
3787 obstack_grow (&util_obstack, buf, strlen (buf));
3791 obstack_1grow (&util_obstack, '\0');
3792 result = get_identifier (obstack_finish (&util_obstack));
3793 obstack_free (&util_obstack, util_firstobj);
3798 generate_descriptor_table (tree type, const char *name, int size, tree list,
3801 tree decl, initlist;
3803 decl = start_var_decl (type, synth_id_with_class_suffix (name, proto));
3805 initlist = build_tree_list (NULL_TREE, build_int_cst (NULL_TREE, size));
3806 initlist = tree_cons (NULL_TREE, list, initlist);
3808 finish_var_decl (decl, objc_build_constructor (type, nreverse (initlist)));
3814 generate_method_descriptors (tree protocol)
3816 tree initlist, chain, method_list_template;
3819 if (!objc_method_prototype_template)
3820 objc_method_prototype_template = build_method_prototype_template ();
3822 chain = PROTOCOL_CLS_METHODS (protocol);
3825 size = list_length (chain);
3827 method_list_template
3828 = build_method_prototype_list_template (objc_method_prototype_template,
3832 = build_descriptor_table_initializer (objc_method_prototype_template,
3835 UOBJC_CLASS_METHODS_decl
3836 = generate_descriptor_table (method_list_template,
3837 "_OBJC_PROTOCOL_CLASS_METHODS",
3838 size, initlist, protocol);
3841 UOBJC_CLASS_METHODS_decl = 0;
3843 chain = PROTOCOL_NST_METHODS (protocol);
3846 size = list_length (chain);
3848 method_list_template
3849 = build_method_prototype_list_template (objc_method_prototype_template,
3852 = build_descriptor_table_initializer (objc_method_prototype_template,
3855 UOBJC_INSTANCE_METHODS_decl
3856 = generate_descriptor_table (method_list_template,
3857 "_OBJC_PROTOCOL_INSTANCE_METHODS",
3858 size, initlist, protocol);
3861 UOBJC_INSTANCE_METHODS_decl = 0;
3865 generate_protocol_references (tree plist)
3869 /* Forward declare protocols referenced. */
3870 for (lproto = plist; lproto; lproto = TREE_CHAIN (lproto))
3872 tree proto = TREE_VALUE (lproto);
3874 if (TREE_CODE (proto) == PROTOCOL_INTERFACE_TYPE
3875 && PROTOCOL_NAME (proto))
3877 if (! PROTOCOL_FORWARD_DECL (proto))
3878 build_protocol_reference (proto);
3880 if (PROTOCOL_LIST (proto))
3881 generate_protocol_references (PROTOCOL_LIST (proto));
3886 /* For each protocol which was referenced either from a @protocol()
3887 expression, or because a class/category implements it (then a
3888 pointer to the protocol is stored in the struct describing the
3889 class/category), we create a statically allocated instance of the
3890 Protocol class. The code is written in such a way as to generate
3891 as few Protocol objects as possible; we generate a unique Protocol
3892 instance for each protocol, and we don't generate a Protocol
3893 instance if the protocol is never referenced (either from a
3894 @protocol() or from a class/category implementation). These
3895 statically allocated objects can be referred to via the static
3896 (that is, private to this module) symbols _OBJC_PROTOCOL_n.
3898 The statically allocated Protocol objects that we generate here
3899 need to be fixed up at runtime in order to be used: the 'isa'
3900 pointer of the objects need to be set up to point to the 'Protocol'
3901 class, as known at runtime.
3903 The NeXT runtime fixes up all protocols at program startup time,
3904 before main() is entered. It uses a low-level trick to look up all
3905 those symbols, then loops on them and fixes them up.
3907 The GNU runtime as well fixes up all protocols before user code
3908 from the module is executed; it requires pointers to those symbols
3909 to be put in the objc_symtab (which is then passed as argument to
3910 the function __objc_exec_class() which the compiler sets up to be
3911 executed automatically when the module is loaded); setup of those
3912 Protocol objects happen in two ways in the GNU runtime: all
3913 Protocol objects referred to by a class or category implementation
3914 are fixed up when the class/category is loaded; all Protocol
3915 objects referred to by a @protocol() expression are added by the
3916 compiler to the list of statically allocated instances to fixup
3917 (the same list holding the statically allocated constant string
3918 objects). Because, as explained above, the compiler generates as
3919 few Protocol objects as possible, some Protocol object might end up
3920 being referenced multiple times when compiled with the GNU runtime,
3921 and end up being fixed up multiple times at runtime initialization.
3922 But that doesn't hurt, it's just a little inefficient. */
3925 generate_protocols (void)
3929 tree initlist, protocol_name_expr, refs_decl, refs_expr;
3931 /* If a protocol was directly referenced, pull in indirect references. */
3932 for (p = protocol_chain; p; p = TREE_CHAIN (p))
3933 if (PROTOCOL_FORWARD_DECL (p) && PROTOCOL_LIST (p))
3934 generate_protocol_references (PROTOCOL_LIST (p));
3936 for (p = protocol_chain; p; p = TREE_CHAIN (p))
3938 tree nst_methods = PROTOCOL_NST_METHODS (p);
3939 tree cls_methods = PROTOCOL_CLS_METHODS (p);
3941 /* If protocol wasn't referenced, don't generate any code. */
3942 decl = PROTOCOL_FORWARD_DECL (p);
3947 /* Make sure we link in the Protocol class. */
3948 add_class_reference (get_identifier (PROTOCOL_OBJECT_CLASS_NAME));
3952 if (! METHOD_ENCODING (nst_methods))
3954 encoding = encode_method_prototype (nst_methods);
3955 METHOD_ENCODING (nst_methods) = encoding;
3957 nst_methods = TREE_CHAIN (nst_methods);
3962 if (! METHOD_ENCODING (cls_methods))
3964 encoding = encode_method_prototype (cls_methods);
3965 METHOD_ENCODING (cls_methods) = encoding;
3968 cls_methods = TREE_CHAIN (cls_methods);
3970 generate_method_descriptors (p);
3972 if (PROTOCOL_LIST (p))
3973 refs_decl = generate_protocol_list (p);
3977 /* static struct objc_protocol _OBJC_PROTOCOL_<mumble>; */
3978 protocol_name_expr = add_objc_string (PROTOCOL_NAME (p), class_names);
3981 refs_expr = convert (build_pointer_type (build_pointer_type
3982 (objc_protocol_template)),
3983 build_unary_op (ADDR_EXPR, refs_decl, 0));
3985 refs_expr = build_int_cst (NULL_TREE, 0);
3987 /* UOBJC_INSTANCE_METHODS_decl/UOBJC_CLASS_METHODS_decl are set
3988 by generate_method_descriptors, which is called above. */
3989 initlist = build_protocol_initializer (TREE_TYPE (decl),
3990 protocol_name_expr, refs_expr,
3991 UOBJC_INSTANCE_METHODS_decl,
3992 UOBJC_CLASS_METHODS_decl);
3993 finish_var_decl (decl, initlist);
3998 build_protocol_initializer (tree type, tree protocol_name,
3999 tree protocol_list, tree instance_methods,
4002 tree initlist = NULL_TREE, expr;
4003 tree cast_type = build_pointer_type
4004 (xref_tag (RECORD_TYPE,
4005 get_identifier (UTAG_CLASS)));
4007 /* Filling the "isa" in with one allows the runtime system to
4008 detect that the version change...should remove before final release. */
4010 expr = build_int_cst (cast_type, PROTOCOL_VERSION);
4011 initlist = tree_cons (NULL_TREE, expr, initlist);
4012 initlist = tree_cons (NULL_TREE, protocol_name, initlist);
4013 initlist = tree_cons (NULL_TREE, protocol_list, initlist);
4015 if (!instance_methods)
4016 initlist = tree_cons (NULL_TREE, build_int_cst (NULL_TREE, 0), initlist);
4019 expr = build_unary_op (ADDR_EXPR, instance_methods, 0);
4020 initlist = tree_cons (NULL_TREE, expr, initlist);
4024 initlist = tree_cons (NULL_TREE, build_int_cst (NULL_TREE, 0), initlist);
4027 expr = build_unary_op (ADDR_EXPR, class_methods, 0);
4028 initlist = tree_cons (NULL_TREE, expr, initlist);
4031 return objc_build_constructor (type, nreverse (initlist));
4034 /* struct _objc_category {
4035 char *category_name;
4037 struct _objc_method_list *instance_methods;
4038 struct _objc_method_list *class_methods;
4039 struct _objc_protocol_list *protocols;
4043 build_category_template (void)
4045 tree field_decl, field_decl_chain;
4047 objc_category_template = start_struct (RECORD_TYPE,
4048 get_identifier (UTAG_CATEGORY));
4050 /* char *category_name; */
4051 field_decl = create_field_decl (string_type_node, "category_name");
4052 field_decl_chain = field_decl;
4054 /* char *class_name; */
4055 field_decl = create_field_decl (string_type_node, "class_name");
4056 chainon (field_decl_chain, field_decl);
4058 /* struct _objc_method_list *instance_methods; */
4059 field_decl = create_field_decl (build_pointer_type
4060 (xref_tag (RECORD_TYPE,
4062 (UTAG_METHOD_LIST))),
4063 "instance_methods");
4064 chainon (field_decl_chain, field_decl);
4066 /* struct _objc_method_list *class_methods; */
4067 field_decl = create_field_decl (build_pointer_type
4068 (xref_tag (RECORD_TYPE,
4070 (UTAG_METHOD_LIST))),
4072 chainon (field_decl_chain, field_decl);
4074 /* struct _objc_protocol **protocol_list; */
4075 field_decl = create_field_decl (build_pointer_type
4077 (objc_protocol_template)),
4079 chainon (field_decl_chain, field_decl);
4081 finish_struct (objc_category_template, field_decl_chain, NULL_TREE);
4084 /* struct _objc_selector {
4090 build_selector_template (void)
4093 tree field_decl, field_decl_chain;
4095 objc_selector_template
4096 = start_struct (RECORD_TYPE, get_identifier (UTAG_SELECTOR));
4099 field_decl = create_field_decl (objc_selector_type, "sel_id");
4100 field_decl_chain = field_decl;
4102 /* char *sel_type; */
4103 field_decl = create_field_decl (string_type_node, "sel_type");
4104 chainon (field_decl_chain, field_decl);
4106 finish_struct (objc_selector_template, field_decl_chain, NULL_TREE);
4109 /* struct _objc_class {
4110 struct _objc_class *isa;
4111 struct _objc_class *super_class;
4116 struct _objc_ivar_list *ivars;
4117 struct _objc_method_list *methods;
4118 #ifdef __NEXT_RUNTIME__
4119 struct objc_cache *cache;
4121 struct sarray *dtable;
4122 struct _objc_class *subclass_list;
4123 struct _objc_class *sibling_class;
4125 struct _objc_protocol_list *protocols;
4126 #ifdef __NEXT_RUNTIME__
4129 void *gc_object_type;
4132 /* NB: The 'sel_id' and 'gc_object_type' fields are not being used by
4133 the NeXT/Apple runtime; still, the compiler must generate them to
4134 maintain backward binary compatibility (and to allow for future
4138 build_class_template (void)
4140 tree field_decl, field_decl_chain;
4143 = start_struct (RECORD_TYPE, get_identifier (UTAG_CLASS));
4145 /* struct _objc_class *isa; */
4146 field_decl = create_field_decl (build_pointer_type (objc_class_template),
4148 field_decl_chain = field_decl;
4150 /* struct _objc_class *super_class; */
4151 field_decl = create_field_decl (build_pointer_type (objc_class_template),
4153 chainon (field_decl_chain, field_decl);
4156 field_decl = create_field_decl (string_type_node, "name");
4157 chainon (field_decl_chain, field_decl);
4160 field_decl = create_field_decl (long_integer_type_node, "version");
4161 chainon (field_decl_chain, field_decl);
4164 field_decl = create_field_decl (long_integer_type_node, "info");
4165 chainon (field_decl_chain, field_decl);
4167 /* long instance_size; */
4168 field_decl = create_field_decl (long_integer_type_node, "instance_size");
4169 chainon (field_decl_chain, field_decl);
4171 /* struct _objc_ivar_list *ivars; */
4172 field_decl = create_field_decl (build_pointer_type
4173 (xref_tag (RECORD_TYPE,
4177 chainon (field_decl_chain, field_decl);
4179 /* struct _objc_method_list *methods; */
4180 field_decl = create_field_decl (build_pointer_type
4181 (xref_tag (RECORD_TYPE,
4183 (UTAG_METHOD_LIST))),
4185 chainon (field_decl_chain, field_decl);
4187 if (flag_next_runtime)
4189 /* struct objc_cache *cache; */
4190 field_decl = create_field_decl (build_pointer_type
4191 (xref_tag (RECORD_TYPE,
4195 chainon (field_decl_chain, field_decl);
4199 /* struct sarray *dtable; */
4200 field_decl = create_field_decl (build_pointer_type
4201 (xref_tag (RECORD_TYPE,
4205 chainon (field_decl_chain, field_decl);
4207 /* struct objc_class *subclass_list; */
4208 field_decl = create_field_decl (build_pointer_type
4209 (objc_class_template),
4211 chainon (field_decl_chain, field_decl);
4213 /* struct objc_class *sibling_class; */
4214 field_decl = create_field_decl (build_pointer_type
4215 (objc_class_template),
4217 chainon (field_decl_chain, field_decl);
4220 /* struct _objc_protocol **protocol_list; */
4221 field_decl = create_field_decl (build_pointer_type
4223 (xref_tag (RECORD_TYPE,
4227 chainon (field_decl_chain, field_decl);
4229 if (flag_next_runtime)
4232 field_decl = create_field_decl (build_pointer_type (void_type_node),
4234 chainon (field_decl_chain, field_decl);
4237 /* void *gc_object_type; */
4238 field_decl = create_field_decl (build_pointer_type (void_type_node),
4240 chainon (field_decl_chain, field_decl);
4242 finish_struct (objc_class_template, field_decl_chain, NULL_TREE);
4245 /* Generate appropriate forward declarations for an implementation. */
4248 synth_forward_declarations (void)
4252 /* static struct objc_class _OBJC_CLASS_<my_name>; */
4253 UOBJC_CLASS_decl = build_metadata_decl ("_OBJC_CLASS",
4254 objc_class_template);
4256 /* static struct objc_class _OBJC_METACLASS_<my_name>; */
4257 UOBJC_METACLASS_decl = build_metadata_decl ("_OBJC_METACLASS",
4258 objc_class_template);
4260 /* Pre-build the following entities - for speed/convenience. */
4262 an_id = get_identifier ("super_class");
4263 ucls_super_ref = build_component_ref (UOBJC_CLASS_decl, an_id);
4264 uucls_super_ref = build_component_ref (UOBJC_METACLASS_decl, an_id);
4268 error_with_ivar (const char *message, tree decl)
4270 error ("%J%s %qs", decl,
4271 message, gen_declaration (decl));
4276 check_ivars (tree inter, tree imp)
4278 tree intdecls = CLASS_RAW_IVARS (inter);
4279 tree impdecls = CLASS_RAW_IVARS (imp);
4286 if (intdecls && TREE_CODE (intdecls) == TYPE_DECL)
4287 intdecls = TREE_CHAIN (intdecls);
4289 if (intdecls == 0 && impdecls == 0)
4291 if (intdecls == 0 || impdecls == 0)
4293 error ("inconsistent instance variable specification");
4297 t1 = TREE_TYPE (intdecls); t2 = TREE_TYPE (impdecls);
4299 if (!comptypes (t1, t2)
4300 || !tree_int_cst_equal (DECL_INITIAL (intdecls),
4301 DECL_INITIAL (impdecls)))
4303 if (DECL_NAME (intdecls) == DECL_NAME (impdecls))
4305 error_with_ivar ("conflicting instance variable type",
4307 error_with_ivar ("previous declaration of",
4310 else /* both the type and the name don't match */
4312 error ("inconsistent instance variable specification");
4317 else if (DECL_NAME (intdecls) != DECL_NAME (impdecls))
4319 error_with_ivar ("conflicting instance variable name",
4321 error_with_ivar ("previous declaration of",
4325 intdecls = TREE_CHAIN (intdecls);
4326 impdecls = TREE_CHAIN (impdecls);
4330 /* Set 'objc_super_template' to the data type node for 'struct _objc_super'.
4331 This needs to be done just once per compilation. */
4333 /* struct _objc_super {
4334 struct _objc_object *self;
4335 struct _objc_class *super_class;
4339 build_super_template (void)
4341 tree field_decl, field_decl_chain;
4343 objc_super_template = start_struct (RECORD_TYPE, get_identifier (UTAG_SUPER));
4345 /* struct _objc_object *self; */
4346 field_decl = create_field_decl (objc_object_type, "self");
4347 field_decl_chain = field_decl;
4349 /* struct _objc_class *super_class; */
4350 field_decl = create_field_decl (build_pointer_type (objc_class_template),
4352 chainon (field_decl_chain, field_decl);
4354 finish_struct (objc_super_template, field_decl_chain, NULL_TREE);
4357 /* struct _objc_ivar {
4364 build_ivar_template (void)
4366 tree objc_ivar_id, objc_ivar_record;
4367 tree field_decl, field_decl_chain;
4369 objc_ivar_id = get_identifier (UTAG_IVAR);
4370 objc_ivar_record = start_struct (RECORD_TYPE, objc_ivar_id);
4372 /* char *ivar_name; */
4373 field_decl = create_field_decl (string_type_node, "ivar_name");
4374 field_decl_chain = field_decl;
4376 /* char *ivar_type; */
4377 field_decl = create_field_decl (string_type_node, "ivar_type");
4378 chainon (field_decl_chain, field_decl);
4380 /* int ivar_offset; */
4381 field_decl = create_field_decl (integer_type_node, "ivar_offset");
4382 chainon (field_decl_chain, field_decl);
4384 finish_struct (objc_ivar_record, field_decl_chain, NULL_TREE);
4386 return objc_ivar_record;
4391 struct objc_ivar ivar_list[ivar_count];
4395 build_ivar_list_template (tree list_type, int size)
4397 tree objc_ivar_list_record;
4398 tree field_decl, field_decl_chain;
4400 objc_ivar_list_record = start_struct (RECORD_TYPE, NULL_TREE);
4402 /* int ivar_count; */
4403 field_decl = create_field_decl (integer_type_node, "ivar_count");
4404 field_decl_chain = field_decl;
4406 /* struct objc_ivar ivar_list[]; */
4407 field_decl = create_field_decl (build_array_type
4410 (build_int_cst (NULL_TREE, size - 1))),
4412 chainon (field_decl_chain, field_decl);
4414 finish_struct (objc_ivar_list_record, field_decl_chain, NULL_TREE);
4416 return objc_ivar_list_record;
4420 struct _objc__method_prototype_list *method_next;
4422 struct objc_method method_list[method_count];
4426 build_method_list_template (tree list_type, int size)
4428 tree objc_ivar_list_record;
4429 tree field_decl, field_decl_chain;
4431 objc_ivar_list_record = start_struct (RECORD_TYPE, NULL_TREE);
4433 /* struct _objc__method_prototype_list *method_next; */
4434 field_decl = create_field_decl (build_pointer_type
4435 (xref_tag (RECORD_TYPE,
4437 (UTAG_METHOD_PROTOTYPE_LIST))),
4439 field_decl_chain = field_decl;
4441 /* int method_count; */
4442 field_decl = create_field_decl (integer_type_node, "method_count");
4443 chainon (field_decl_chain, field_decl);
4445 /* struct objc_method method_list[]; */
4446 field_decl = create_field_decl (build_array_type
4449 (build_int_cst (NULL_TREE, size - 1))),
4451 chainon (field_decl_chain, field_decl);
4453 finish_struct (objc_ivar_list_record, field_decl_chain, NULL_TREE);
4455 return objc_ivar_list_record;
4459 build_ivar_list_initializer (tree type, tree field_decl)
4461 tree initlist = NULL_TREE;
4465 tree ivar = NULL_TREE;
4468 if (DECL_NAME (field_decl))
4469 ivar = tree_cons (NULL_TREE,
4470 add_objc_string (DECL_NAME (field_decl),
4474 /* Unnamed bit-field ivar (yuck). */
4475 ivar = tree_cons (NULL_TREE, build_int_cst (NULL_TREE, 0), ivar);
4478 encode_field_decl (field_decl,
4479 obstack_object_size (&util_obstack),
4480 OBJC_ENCODE_DONT_INLINE_DEFS);
4482 /* Null terminate string. */
4483 obstack_1grow (&util_obstack, 0);
4487 add_objc_string (get_identifier (obstack_finish (&util_obstack)),
4490 obstack_free (&util_obstack, util_firstobj);
4493 ivar = tree_cons (NULL_TREE, byte_position (field_decl), ivar);
4494 initlist = tree_cons (NULL_TREE,
4495 objc_build_constructor (type, nreverse (ivar)),
4498 field_decl = TREE_CHAIN (field_decl);
4499 while (field_decl && TREE_CODE (field_decl) != FIELD_DECL);
4503 return objc_build_constructor (build_array_type (type, 0),
4504 nreverse (initlist));
4508 generate_ivars_list (tree type, const char *name, int size, tree list)
4510 tree decl, initlist;
4512 decl = start_var_decl (type, synth_id_with_class_suffix
4513 (name, objc_implementation_context));
4515 initlist = build_tree_list (NULL_TREE, build_int_cst (NULL_TREE, size));
4516 initlist = tree_cons (NULL_TREE, list, initlist);
4518 finish_var_decl (decl,
4519 objc_build_constructor (TREE_TYPE (decl),
4520 nreverse (initlist)));
4525 /* Count only the fields occurring in T. */
4527 ivar_list_length (tree t)
4531 for (; t; t = TREE_CHAIN (t))
4532 if (TREE_CODE (t) == FIELD_DECL)
4539 generate_ivar_lists (void)
4541 tree initlist, ivar_list_template, chain;
4544 generating_instance_variables = 1;
4546 if (!objc_ivar_template)
4547 objc_ivar_template = build_ivar_template ();
4549 /* Only generate class variables for the root of the inheritance
4550 hierarchy since these will be the same for every class. */
4552 if (CLASS_SUPER_NAME (implementation_template) == NULL_TREE
4553 && (chain = TYPE_FIELDS (objc_class_template)))
4555 size = ivar_list_length (chain);
4557 ivar_list_template = build_ivar_list_template (objc_ivar_template, size);
4558 initlist = build_ivar_list_initializer (objc_ivar_template, chain);
4560 UOBJC_CLASS_VARIABLES_decl
4561 = generate_ivars_list (ivar_list_template, "_OBJC_CLASS_VARIABLES",
4565 UOBJC_CLASS_VARIABLES_decl = 0;
4567 chain = CLASS_IVARS (implementation_template);
4570 size = ivar_list_length (chain);
4571 ivar_list_template = build_ivar_list_template (objc_ivar_template, size);
4572 initlist = build_ivar_list_initializer (objc_ivar_template, chain);
4574 UOBJC_INSTANCE_VARIABLES_decl
4575 = generate_ivars_list (ivar_list_template, "_OBJC_INSTANCE_VARIABLES",
4579 UOBJC_INSTANCE_VARIABLES_decl = 0;
4581 generating_instance_variables = 0;
4585 build_dispatch_table_initializer (tree type, tree entries)
4587 tree initlist = NULL_TREE;
4591 tree elemlist = NULL_TREE;
4593 elemlist = tree_cons (NULL_TREE,
4594 build_selector (METHOD_SEL_NAME (entries)),
4597 /* Generate the method encoding if we don't have one already. */
4598 if (! METHOD_ENCODING (entries))
4599 METHOD_ENCODING (entries) =
4600 encode_method_prototype (entries);
4602 elemlist = tree_cons (NULL_TREE,
4603 add_objc_string (METHOD_ENCODING (entries),
4608 = tree_cons (NULL_TREE,
4609 convert (ptr_type_node,
4610 build_unary_op (ADDR_EXPR,
4611 METHOD_DEFINITION (entries), 1)),
4614 initlist = tree_cons (NULL_TREE,
4615 objc_build_constructor (type, nreverse (elemlist)),
4618 entries = TREE_CHAIN (entries);
4622 return objc_build_constructor (build_array_type (type, 0),
4623 nreverse (initlist));
4626 /* To accomplish method prototyping without generating all kinds of
4627 inane warnings, the definition of the dispatch table entries were
4630 struct objc_method { SEL _cmd; ...; id (*_imp)(); };
4632 struct objc_method { SEL _cmd; ...; void *_imp; }; */
4635 build_method_template (void)
4638 tree field_decl, field_decl_chain;
4640 _SLT_record = start_struct (RECORD_TYPE, get_identifier (UTAG_METHOD));
4643 field_decl = create_field_decl (objc_selector_type, "_cmd");
4644 field_decl_chain = field_decl;
4646 /* char *method_types; */
4647 field_decl = create_field_decl (string_type_node, "method_types");
4648 chainon (field_decl_chain, field_decl);
4651 field_decl = create_field_decl (build_pointer_type (void_type_node),
4653 chainon (field_decl_chain, field_decl);
4655 finish_struct (_SLT_record, field_decl_chain, NULL_TREE);
4662 generate_dispatch_table (tree type, const char *name, int size, tree list)
4664 tree decl, initlist;
4666 decl = start_var_decl (type, synth_id_with_class_suffix
4667 (name, objc_implementation_context));
4669 initlist = build_tree_list (NULL_TREE, build_int_cst (NULL_TREE, 0));
4670 initlist = tree_cons (NULL_TREE, build_int_cst (NULL_TREE, size), initlist);
4671 initlist = tree_cons (NULL_TREE, list, initlist);
4673 finish_var_decl (decl,
4674 objc_build_constructor (TREE_TYPE (decl),
4675 nreverse (initlist)));
4681 mark_referenced_methods (void)
4683 struct imp_entry *impent;
4686 for (impent = imp_list; impent; impent = impent->next)
4688 chain = CLASS_CLS_METHODS (impent->imp_context);
4691 cgraph_mark_needed_node (cgraph_node (METHOD_DEFINITION (chain)));
4692 chain = TREE_CHAIN (chain);
4695 chain = CLASS_NST_METHODS (impent->imp_context);
4698 cgraph_mark_needed_node (cgraph_node (METHOD_DEFINITION (chain)));
4699 chain = TREE_CHAIN (chain);
4705 generate_dispatch_tables (void)
4707 tree initlist, chain, method_list_template;
4710 if (!objc_method_template)
4711 objc_method_template = build_method_template ();
4713 chain = CLASS_CLS_METHODS (objc_implementation_context);
4716 size = list_length (chain);
4718 method_list_template
4719 = build_method_list_template (objc_method_template, size);
4721 = build_dispatch_table_initializer (objc_method_template, chain);
4723 UOBJC_CLASS_METHODS_decl
4724 = generate_dispatch_table (method_list_template,
4725 ((TREE_CODE (objc_implementation_context)
4726 == CLASS_IMPLEMENTATION_TYPE)
4727 ? "_OBJC_CLASS_METHODS"
4728 : "_OBJC_CATEGORY_CLASS_METHODS"),
4732 UOBJC_CLASS_METHODS_decl = 0;
4734 chain = CLASS_NST_METHODS (objc_implementation_context);
4737 size = list_length (chain);
4739 method_list_template
4740 = build_method_list_template (objc_method_template, size);
4742 = build_dispatch_table_initializer (objc_method_template, chain);
4744 if (TREE_CODE (objc_implementation_context) == CLASS_IMPLEMENTATION_TYPE)
4745 UOBJC_INSTANCE_METHODS_decl
4746 = generate_dispatch_table (method_list_template,
4747 "_OBJC_INSTANCE_METHODS",
4750 /* We have a category. */
4751 UOBJC_INSTANCE_METHODS_decl
4752 = generate_dispatch_table (method_list_template,
4753 "_OBJC_CATEGORY_INSTANCE_METHODS",
4757 UOBJC_INSTANCE_METHODS_decl = 0;
4761 generate_protocol_list (tree i_or_p)
4764 tree refs_decl, lproto, e, plist;
4766 const char *ref_name;
4768 if (TREE_CODE (i_or_p) == CLASS_INTERFACE_TYPE
4769 || TREE_CODE (i_or_p) == CATEGORY_INTERFACE_TYPE)
4770 plist = CLASS_PROTOCOL_LIST (i_or_p);
4771 else if (TREE_CODE (i_or_p) == PROTOCOL_INTERFACE_TYPE)
4772 plist = PROTOCOL_LIST (i_or_p);
4777 for (lproto = plist; lproto; lproto = TREE_CHAIN (lproto))
4778 if (TREE_CODE (TREE_VALUE (lproto)) == PROTOCOL_INTERFACE_TYPE
4779 && PROTOCOL_FORWARD_DECL (TREE_VALUE (lproto)))
4782 /* Build initializer. */
4783 initlist = tree_cons (NULL_TREE, build_int_cst (NULL_TREE, 0), NULL_TREE);
4784 e = build_int_cst (build_pointer_type (objc_protocol_template), size);
4785 initlist = tree_cons (NULL_TREE, e, initlist);
4787 for (lproto = plist; lproto; lproto = TREE_CHAIN (lproto))
4789 tree pval = TREE_VALUE (lproto);
4791 if (TREE_CODE (pval) == PROTOCOL_INTERFACE_TYPE
4792 && PROTOCOL_FORWARD_DECL (pval))
4794 e = build_unary_op (ADDR_EXPR, PROTOCOL_FORWARD_DECL (pval), 0);
4795 initlist = tree_cons (NULL_TREE, e, initlist);
4799 /* static struct objc_protocol *refs[n]; */
4801 if (TREE_CODE (i_or_p) == PROTOCOL_INTERFACE_TYPE)
4802 ref_name = synth_id_with_class_suffix ("_OBJC_PROTOCOL_REFS", i_or_p);
4803 else if (TREE_CODE (i_or_p) == CLASS_INTERFACE_TYPE)
4804 ref_name = synth_id_with_class_suffix ("_OBJC_CLASS_PROTOCOLS", i_or_p);
4805 else if (TREE_CODE (i_or_p) == CATEGORY_INTERFACE_TYPE)
4806 ref_name = synth_id_with_class_suffix ("_OBJC_CATEGORY_PROTOCOLS", i_or_p);
4810 refs_decl = start_var_decl
4812 (build_pointer_type (objc_protocol_template),
4813 build_index_type (build_int_cst (NULL_TREE, size + 2))),
4816 finish_var_decl (refs_decl, objc_build_constructor (TREE_TYPE (refs_decl),
4817 nreverse (initlist)));
4823 build_category_initializer (tree type, tree cat_name, tree class_name,
4824 tree instance_methods, tree class_methods,
4827 tree initlist = NULL_TREE, expr;
4829 initlist = tree_cons (NULL_TREE, cat_name, initlist);
4830 initlist = tree_cons (NULL_TREE, class_name, initlist);
4832 if (!instance_methods)
4833 initlist = tree_cons (NULL_TREE, build_int_cst (NULL_TREE, 0), initlist);
4836 expr = build_unary_op (ADDR_EXPR, instance_methods, 0);
4837 initlist = tree_cons (NULL_TREE, expr, initlist);
4840 initlist = tree_cons (NULL_TREE, build_int_cst (NULL_TREE, 0), initlist);
4843 expr = build_unary_op (ADDR_EXPR, class_methods, 0);
4844 initlist = tree_cons (NULL_TREE, expr, initlist);
4847 /* protocol_list = */
4849 initlist = tree_cons (NULL_TREE, build_int_cst (NULL_TREE, 0), initlist);
4852 expr = convert (build_pointer_type
4854 (objc_protocol_template)),
4855 build_unary_op (ADDR_EXPR, protocol_list, 0));
4856 initlist = tree_cons (NULL_TREE, expr, initlist);
4859 return objc_build_constructor (type, nreverse (initlist));
4862 /* struct _objc_class {
4863 struct objc_class *isa;
4864 struct objc_class *super_class;
4869 struct objc_ivar_list *ivars;
4870 struct objc_method_list *methods;
4871 if (flag_next_runtime)
4872 struct objc_cache *cache;
4874 struct sarray *dtable;
4875 struct objc_class *subclass_list;
4876 struct objc_class *sibling_class;
4878 struct objc_protocol_list *protocols;
4879 if (flag_next_runtime)
4881 void *gc_object_type;
4885 build_shared_structure_initializer (tree type, tree isa, tree super,
4886 tree name, tree size, int status,
4887 tree dispatch_table, tree ivar_list,
4890 tree initlist = NULL_TREE, expr;
4893 initlist = tree_cons (NULL_TREE, isa, initlist);
4896 initlist = tree_cons (NULL_TREE, super, initlist);
4899 initlist = tree_cons (NULL_TREE, default_conversion (name), initlist);
4902 initlist = tree_cons (NULL_TREE, build_int_cst (long_integer_type_node, 0),
4906 initlist = tree_cons (NULL_TREE,
4907 build_int_cst (long_integer_type_node, status),
4910 /* instance_size = */
4911 initlist = tree_cons (NULL_TREE, convert (long_integer_type_node, size),
4914 /* objc_ivar_list = */
4916 initlist = tree_cons (NULL_TREE, build_int_cst (NULL_TREE, 0), initlist);
4919 expr = build_unary_op (ADDR_EXPR, ivar_list, 0);
4920 initlist = tree_cons (NULL_TREE, expr, initlist);
4923 /* objc_method_list = */
4924 if (!dispatch_table)
4925 initlist = tree_cons (NULL_TREE, build_int_cst (NULL_TREE, 0), initlist);
4928 expr = build_unary_op (ADDR_EXPR, dispatch_table, 0);
4929 initlist = tree_cons (NULL_TREE, expr, initlist);
4932 if (flag_next_runtime)
4933 /* method_cache = */
4934 initlist = tree_cons (NULL_TREE, build_int_cst (NULL_TREE, 0), initlist);
4938 initlist = tree_cons (NULL_TREE, build_int_cst (NULL_TREE, 0), initlist);
4940 /* subclass_list = */
4941 initlist = tree_cons (NULL_TREE, build_int_cst (NULL_TREE, 0), initlist);
4943 /* sibling_class = */
4944 initlist = tree_cons (NULL_TREE, build_int_cst (NULL_TREE, 0), initlist);
4947 /* protocol_list = */
4948 if (! protocol_list)
4949 initlist = tree_cons (NULL_TREE, build_int_cst (NULL_TREE, 0), initlist);
4952 expr = convert (build_pointer_type
4954 (objc_protocol_template)),
4955 build_unary_op (ADDR_EXPR, protocol_list, 0));
4956 initlist = tree_cons (NULL_TREE, expr, initlist);
4959 if (flag_next_runtime)
4961 initlist = tree_cons (NULL_TREE, build_int_cst (NULL_TREE, 0), initlist);
4963 /* gc_object_type = NULL */
4964 initlist = tree_cons (NULL_TREE, build_int_cst (NULL_TREE, 0), initlist);
4966 return objc_build_constructor (type, nreverse (initlist));
4969 /* Retrieve category interface CAT_NAME (if any) associated with CLASS. */
4972 lookup_category (tree class, tree cat_name)
4974 tree category = CLASS_CATEGORY_LIST (class);
4976 while (category && CLASS_SUPER_NAME (category) != cat_name)
4977 category = CLASS_CATEGORY_LIST (category);
4981 /* static struct objc_category _OBJC_CATEGORY_<name> = { ... }; */
4984 generate_category (tree cat)
4987 tree initlist, cat_name_expr, class_name_expr;
4988 tree protocol_decl, category;
4990 add_class_reference (CLASS_NAME (cat));
4991 cat_name_expr = add_objc_string (CLASS_SUPER_NAME (cat), class_names);
4993 class_name_expr = add_objc_string (CLASS_NAME (cat), class_names);
4995 category = lookup_category (implementation_template,
4996 CLASS_SUPER_NAME (cat));
4998 if (category && CLASS_PROTOCOL_LIST (category))
5000 generate_protocol_references (CLASS_PROTOCOL_LIST (category));
5001 protocol_decl = generate_protocol_list (category);
5006 decl = start_var_decl (objc_category_template,
5007 synth_id_with_class_suffix
5008 ("_OBJC_CATEGORY", objc_implementation_context));
5010 initlist = build_category_initializer (TREE_TYPE (decl),
5011 cat_name_expr, class_name_expr,
5012 UOBJC_INSTANCE_METHODS_decl,
5013 UOBJC_CLASS_METHODS_decl,
5016 finish_var_decl (decl, initlist);
5019 /* static struct objc_class _OBJC_METACLASS_Foo={ ... };
5020 static struct objc_class _OBJC_CLASS_Foo={ ... }; */
5023 generate_shared_structures (void)
5025 tree sc_spec, decl_specs, decl;
5026 tree name_expr, super_expr, root_expr;
5027 tree my_root_id = NULL_TREE, my_super_id = NULL_TREE;
5028 tree cast_type, initlist, protocol_decl;
5030 my_super_id = CLASS_SUPER_NAME (implementation_template);
5033 add_class_reference (my_super_id);
5035 /* Compute "my_root_id" - this is required for code generation.
5036 the "isa" for all meta class structures points to the root of
5037 the inheritance hierarchy (e.g. "__Object")... */
5038 my_root_id = my_super_id;
5041 tree my_root_int = lookup_interface (my_root_id);
5043 if (my_root_int && CLASS_SUPER_NAME (my_root_int))
5044 my_root_id = CLASS_SUPER_NAME (my_root_int);
5051 /* No super class. */
5052 my_root_id = CLASS_NAME (implementation_template);
5054 cast_type = build_pointer_type (objc_class_template);
5055 name_expr = add_objc_string (CLASS_NAME (implementation_template),
5058 /* Install class `isa' and `super' pointers at runtime. */
5061 super_expr = add_objc_string (my_super_id, class_names);
5062 super_expr = build_c_cast (cast_type, super_expr); /* cast! */
5065 super_expr = build_int_cst (NULL_TREE, 0);
5067 root_expr = add_objc_string (my_root_id, class_names);
5068 root_expr = build_c_cast (cast_type, root_expr); /* cast! */
5070 if (CLASS_PROTOCOL_LIST (implementation_template))
5072 generate_protocol_references
5073 (CLASS_PROTOCOL_LIST (implementation_template));
5074 protocol_decl = generate_protocol_list (implementation_template);
5079 /* static struct objc_class _OBJC_METACLASS_Foo = { ... }; */
5081 sc_spec = build_tree_list (NULL_TREE, ridpointers[(int) RID_STATIC]);
5082 decl_specs = tree_cons (NULL_TREE, objc_class_template, sc_spec);
5084 decl = start_var_decl (objc_class_template,
5086 (DECL_NAME (UOBJC_METACLASS_decl)));
5089 = build_shared_structure_initializer
5091 root_expr, super_expr, name_expr,
5092 convert (integer_type_node, TYPE_SIZE_UNIT (objc_class_template)),
5094 UOBJC_CLASS_METHODS_decl,
5095 UOBJC_CLASS_VARIABLES_decl,
5098 finish_var_decl (decl, initlist);
5100 /* static struct objc_class _OBJC_CLASS_Foo={ ... }; */
5102 decl = start_var_decl (objc_class_template,
5104 (DECL_NAME (UOBJC_CLASS_decl)));
5107 = build_shared_structure_initializer
5109 build_unary_op (ADDR_EXPR, UOBJC_METACLASS_decl, 0),
5110 super_expr, name_expr,
5111 convert (integer_type_node,
5112 TYPE_SIZE_UNIT (CLASS_STATIC_TEMPLATE
5113 (implementation_template))),
5115 UOBJC_INSTANCE_METHODS_decl,
5116 UOBJC_INSTANCE_VARIABLES_decl,
5119 finish_var_decl (decl, initlist);
5124 synth_id_with_class_suffix (const char *preamble, tree ctxt)
5126 static char string[BUFSIZE];
5128 if (TREE_CODE (ctxt) == CLASS_IMPLEMENTATION_TYPE
5129 || TREE_CODE (ctxt) == CLASS_INTERFACE_TYPE)
5131 sprintf (string, "%s_%s", preamble,
5132 IDENTIFIER_POINTER (CLASS_NAME (ctxt)));
5134 else if (TREE_CODE (ctxt) == CATEGORY_IMPLEMENTATION_TYPE
5135 || TREE_CODE (ctxt) == CATEGORY_INTERFACE_TYPE)
5137 /* We have a category. */
5138 const char *const class_name
5139 = IDENTIFIER_POINTER (CLASS_NAME (objc_implementation_context));
5140 const char *const class_super_name
5141 = IDENTIFIER_POINTER (CLASS_SUPER_NAME (objc_implementation_context));
5142 sprintf (string, "%s_%s_%s", preamble, class_name, class_super_name);
5144 else if (TREE_CODE (ctxt) == PROTOCOL_INTERFACE_TYPE)
5146 const char *protocol_name = IDENTIFIER_POINTER (PROTOCOL_NAME (ctxt));
5147 sprintf (string, "%s_%s", preamble, protocol_name);
5155 /* If type is empty or only type qualifiers are present, add default
5156 type of id (otherwise grokdeclarator will default to int). */
5159 adjust_type_for_id_default (tree type)
5162 type = make_node (TREE_LIST);
5164 if (!TREE_VALUE (type))
5165 TREE_VALUE (type) = objc_object_type;
5166 else if (TREE_CODE (TREE_VALUE (type)) == RECORD_TYPE
5167 && TYPED_OBJECT (TREE_VALUE (type)))
5168 error ("can not use an object as parameter to a method");
5175 selector ':' '(' typename ')' identifier
5178 Transform an Objective-C keyword argument into
5179 the C equivalent parameter declarator.
5181 In: key_name, an "identifier_node" (optional).
5182 arg_type, a "tree_list" (optional).
5183 arg_name, an "identifier_node".
5185 Note: It would be really nice to strongly type the preceding
5186 arguments in the function prototype; however, then I
5187 could not use the "accessor" macros defined in "tree.h".
5189 Out: an instance of "keyword_decl". */
5192 objc_build_keyword_decl (tree key_name, tree arg_type, tree arg_name)
5196 /* If no type is specified, default to "id". */
5197 arg_type = adjust_type_for_id_default (arg_type);
5199 keyword_decl = make_node (KEYWORD_DECL);
5201 TREE_TYPE (keyword_decl) = arg_type;
5202 KEYWORD_ARG_NAME (keyword_decl) = arg_name;
5203 KEYWORD_KEY_NAME (keyword_decl) = key_name;
5205 return keyword_decl;
5208 /* Given a chain of keyword_decl's, synthesize the full keyword selector. */
5211 build_keyword_selector (tree selector)
5214 tree key_chain, key_name;
5217 /* Scan the selector to see how much space we'll need. */
5218 for (key_chain = selector; key_chain; key_chain = TREE_CHAIN (key_chain))
5220 if (TREE_CODE (selector) == KEYWORD_DECL)
5221 key_name = KEYWORD_KEY_NAME (key_chain);
5222 else if (TREE_CODE (selector) == TREE_LIST)
5223 key_name = TREE_PURPOSE (key_chain);
5228 len += IDENTIFIER_LENGTH (key_name) + 1;
5230 /* Just a ':' arg. */
5234 buf = (char *) alloca (len + 1);
5235 /* Start the buffer out as an empty string. */
5238 for (key_chain = selector; key_chain; key_chain = TREE_CHAIN (key_chain))
5240 if (TREE_CODE (selector) == KEYWORD_DECL)
5241 key_name = KEYWORD_KEY_NAME (key_chain);
5242 else if (TREE_CODE (selector) == TREE_LIST)
5244 key_name = TREE_PURPOSE (key_chain);
5245 /* The keyword decl chain will later be used as a function argument
5246 chain. Unhook the selector itself so as to not confuse other
5247 parts of the compiler. */
5248 TREE_PURPOSE (key_chain) = NULL_TREE;
5254 strcat (buf, IDENTIFIER_POINTER (key_name));
5258 return get_identifier (buf);
5261 /* Used for declarations and definitions. */
5264 build_method_decl (enum tree_code code, tree ret_type, tree selector,
5269 /* If no type is specified, default to "id". */
5270 ret_type = adjust_type_for_id_default (ret_type);
5272 method_decl = make_node (code);
5273 TREE_TYPE (method_decl) = ret_type;
5275 /* If we have a keyword selector, create an identifier_node that
5276 represents the full selector name (`:' included)... */
5277 if (TREE_CODE (selector) == KEYWORD_DECL)
5279 METHOD_SEL_NAME (method_decl) = build_keyword_selector (selector);
5280 METHOD_SEL_ARGS (method_decl) = selector;
5281 METHOD_ADD_ARGS (method_decl) = add_args;
5285 METHOD_SEL_NAME (method_decl) = selector;
5286 METHOD_SEL_ARGS (method_decl) = NULL_TREE;
5287 METHOD_ADD_ARGS (method_decl) = NULL_TREE;
5293 #define METHOD_DEF 0
5294 #define METHOD_REF 1
5296 /* Used by `build_objc_method_call' and `comp_proto_with_proto'. Return
5297 an argument list for method METH. CONTEXT is either METHOD_DEF or
5298 METHOD_REF, saying whether we are trying to define a method or call
5299 one. SUPERFLAG says this is for a send to super; this makes a
5300 difference for the NeXT calling sequence in which the lookup and
5301 the method call are done together. If METH is null, user-defined
5302 arguments (i.e., beyond self and _cmd) shall be represented by `...'. */
5305 get_arg_type_list (tree meth, int context, int superflag)
5309 /* Receiver type. */
5310 if (flag_next_runtime && superflag)
5311 arglist = build_tree_list (NULL_TREE, objc_super_type);
5312 else if (context == METHOD_DEF && TREE_CODE (meth) == INSTANCE_METHOD_DECL)
5313 arglist = build_tree_list (NULL_TREE, objc_instance_type);
5315 arglist = build_tree_list (NULL_TREE, objc_object_type);
5317 /* Selector type - will eventually change to `int'. */
5318 chainon (arglist, build_tree_list (NULL_TREE, objc_selector_type));
5320 /* No actual method prototype given -- assume that remaining arguments
5325 /* Build a list of argument types. */
5326 for (akey = METHOD_SEL_ARGS (meth); akey; akey = TREE_CHAIN (akey))
5328 tree arg_type = TREE_VALUE (TREE_TYPE (akey));
5330 /* Decay arrays and functions into pointers. */
5331 if (TREE_CODE (arg_type) == ARRAY_TYPE)
5332 arg_type = build_pointer_type (TREE_TYPE (arg_type));
5333 else if (TREE_CODE (arg_type) == FUNCTION_TYPE)
5334 arg_type = build_pointer_type (arg_type);
5336 chainon (arglist, build_tree_list (NULL_TREE, arg_type));
5339 if (METHOD_ADD_ARGS (meth))
5341 for (akey = TREE_CHAIN (METHOD_ADD_ARGS (meth));
5342 akey; akey = TREE_CHAIN (akey))
5344 tree arg_type = TREE_TYPE (TREE_VALUE (akey));
5346 chainon (arglist, build_tree_list (NULL_TREE, arg_type));
5349 if (!TREE_OVERFLOW (METHOD_ADD_ARGS (meth)))
5350 goto lack_of_ellipsis;
5355 chainon (arglist, OBJC_VOID_AT_END);
5362 check_duplicates (hash hsh, int methods, int is_class)
5364 tree meth = NULL_TREE;
5372 /* We have two or more methods with the same name but
5376 warning ("multiple %s named %<%c%s%> found",
5377 methods ? "methods" : "selectors",
5378 (is_class ? '+' : '-'),
5379 IDENTIFIER_POINTER (METHOD_SEL_NAME (meth)));
5381 warn_with_method (methods ? "using" : "found",
5382 ((TREE_CODE (meth) == INSTANCE_METHOD_DECL)
5386 for (loop = hsh->list; loop; loop = loop->next)
5387 warn_with_method ("also found",
5388 ((TREE_CODE (loop->value) == INSTANCE_METHOD_DECL)
5397 /* If RECEIVER is a class reference, return the identifier node for
5398 the referenced class. RECEIVER is created by objc_get_class_reference,
5399 so we check the exact form created depending on which runtimes are
5403 receiver_is_class_object (tree receiver, int self, int super)
5405 tree chain, exp, arg;
5407 /* The receiver is 'self' or 'super' in the context of a class method. */
5408 if (objc_method_context
5409 && TREE_CODE (objc_method_context) == CLASS_METHOD_DECL
5412 ? CLASS_SUPER_NAME (implementation_template)
5413 : CLASS_NAME (implementation_template));
5415 if (flag_next_runtime)
5417 /* The receiver is a variable created by
5418 build_class_reference_decl. */
5419 if (TREE_CODE (receiver) == VAR_DECL && IS_CLASS (TREE_TYPE (receiver)))
5420 /* Look up the identifier. */
5421 for (chain = cls_ref_chain; chain; chain = TREE_CHAIN (chain))
5422 if (TREE_PURPOSE (chain) == receiver)
5423 return TREE_VALUE (chain);
5426 /* The receiver is a function call that returns an id. Check if
5427 it is a call to objc_getClass, if so, pick up the class name. */
5428 if (TREE_CODE (receiver) == CALL_EXPR
5429 && (exp = TREE_OPERAND (receiver, 0))
5430 && TREE_CODE (exp) == ADDR_EXPR
5431 && (exp = TREE_OPERAND (exp, 0))
5432 && TREE_CODE (exp) == FUNCTION_DECL
5433 /* For some reason, we sometimes wind up with multiple FUNCTION_DECL
5434 prototypes for objc_get_class(). Thankfully, they seem to share the
5435 same function type. */
5436 && TREE_TYPE (exp) == TREE_TYPE (objc_get_class_decl)
5437 && !strcmp (IDENTIFIER_POINTER (DECL_NAME (exp)), TAG_GETCLASS)
5438 /* We have a call to objc_get_class/objc_getClass! */
5439 && (arg = TREE_OPERAND (receiver, 1))
5440 && TREE_CODE (arg) == TREE_LIST
5441 && (arg = TREE_VALUE (arg)))
5444 if (TREE_CODE (arg) == ADDR_EXPR
5445 && (arg = TREE_OPERAND (arg, 0))
5446 && TREE_CODE (arg) == STRING_CST)
5447 /* Finally, we have the class name. */
5448 return get_identifier (TREE_STRING_POINTER (arg));
5453 /* If we are currently building a message expr, this holds
5454 the identifier of the selector of the message. This is
5455 used when printing warnings about argument mismatches. */
5457 static tree current_objc_message_selector = 0;
5460 objc_message_selector (void)
5462 return current_objc_message_selector;
5465 /* Construct an expression for sending a message.
5466 MESS has the object to send to in TREE_PURPOSE
5467 and the argument list (including selector) in TREE_VALUE.
5469 (*(<abstract_decl>(*)())_msg)(receiver, selTransTbl[n], ...);
5470 (*(<abstract_decl>(*)())_msgSuper)(receiver, selTransTbl[n], ...); */
5473 objc_build_message_expr (tree mess)
5475 tree receiver = TREE_PURPOSE (mess);
5478 tree args = TREE_PURPOSE (TREE_VALUE (mess));
5480 tree args = TREE_VALUE (mess);
5482 tree method_params = NULL_TREE;
5484 if (TREE_CODE (receiver) == ERROR_MARK)
5485 return error_mark_node;
5487 /* Obtain the full selector name. */
5488 if (TREE_CODE (args) == IDENTIFIER_NODE)
5489 /* A unary selector. */
5491 else if (TREE_CODE (args) == TREE_LIST)
5492 sel_name = build_keyword_selector (args);
5496 /* Build the parameter list to give to the method. */
5497 if (TREE_CODE (args) == TREE_LIST)
5499 method_params = chainon (args, TREE_VALUE (TREE_VALUE (mess)));
5502 tree chain = args, prev = NULL_TREE;
5504 /* We have a keyword selector--check for comma expressions. */
5507 tree element = TREE_VALUE (chain);
5509 /* We have a comma expression, must collapse... */
5510 if (TREE_CODE (element) == TREE_LIST)
5513 TREE_CHAIN (prev) = element;
5518 chain = TREE_CHAIN (chain);
5520 method_params = args;
5525 if (processing_template_decl)
5526 /* Must wait until template instantiation time. */
5527 return build_min_nt (MESSAGE_SEND_EXPR, receiver, sel_name,
5531 return objc_finish_message_expr (receiver, sel_name, method_params);
5534 /* Look up method SEL_NAME that would be suitable for receiver
5535 of type 'id' (if IS_CLASS is zero) or 'Class' (if IS_CLASS is
5536 nonzero), and report on any duplicates. */
5539 lookup_method_in_hash_lists (tree sel_name, int is_class)
5541 hash method_prototype = NULL;
5544 method_prototype = hash_lookup (nst_method_hash_list,
5547 if (!method_prototype)
5549 method_prototype = hash_lookup (cls_method_hash_list,
5554 return check_duplicates (method_prototype, 1, is_class);
5557 /* The 'objc_finish_message_expr' routine is called from within
5558 'objc_build_message_expr' for non-template functions. In the case of
5559 C++ template functions, it is called from 'build_expr_from_tree'
5560 (in decl2.c) after RECEIVER and METHOD_PARAMS have been expanded. */
5563 objc_finish_message_expr (tree receiver, tree sel_name, tree method_params)
5565 tree method_prototype = NULL_TREE, rprotos = NULL_TREE, rtype;
5566 tree selector, retval, class_tree;
5567 int self, super, have_cast;
5569 /* Extract the receiver of the message, as well as its type
5570 (where the latter may take the form of a cast or be inferred
5571 from the implementation context). */
5573 while (TREE_CODE (rtype) == COMPOUND_EXPR
5574 || TREE_CODE (rtype) == MODIFY_EXPR
5575 || TREE_CODE (rtype) == NOP_EXPR
5576 || TREE_CODE (rtype) == CONVERT_EXPR
5577 || TREE_CODE (rtype) == COMPONENT_REF)
5578 rtype = TREE_OPERAND (rtype, 0);
5579 self = (rtype == self_decl);
5580 super = (rtype == UOBJC_SUPER_decl);
5581 rtype = TREE_TYPE (receiver);
5582 have_cast = (TREE_CODE (receiver) == NOP_EXPR
5583 || (TREE_CODE (receiver) == COMPOUND_EXPR
5584 && !IS_SUPER (rtype)));
5586 /* If the receiver is a class object, retrieve the corresponding
5587 @interface, if one exists. */
5588 class_tree = receiver_is_class_object (receiver, self, super);
5590 /* Now determine the receiver type (if an explicit cast has not been
5595 rtype = lookup_interface (class_tree);
5596 /* Handle `self' and `super'. */
5599 if (!CLASS_SUPER_NAME (implementation_template))
5601 error ("no super class declared in @interface for %qs",
5602 IDENTIFIER_POINTER (CLASS_NAME (implementation_template)));
5603 return error_mark_node;
5605 rtype = lookup_interface (CLASS_SUPER_NAME (implementation_template));
5608 rtype = lookup_interface (CLASS_NAME (implementation_template));
5611 /* If receiver is of type `id' or `Class' (or if the @interface for a
5612 class is not visible), we shall be satisfied with the existence of
5613 any instance or class method. */
5614 if (!rtype || objc_is_id (rtype))
5617 rtype = xref_tag (RECORD_TYPE, class_tree);
5620 class_tree = (IS_CLASS (rtype) ? objc_class_name : NULL_TREE);
5621 rprotos = (TYPE_HAS_OBJC_INFO (TREE_TYPE (rtype))
5622 ? TYPE_OBJC_PROTOCOL_LIST (TREE_TYPE (rtype))
5629 /* If messaging 'id <Protos>' or 'Class <Proto>', first search
5630 in protocols themselves for the method prototype. */
5632 = lookup_method_in_protocol_list (rprotos, sel_name,
5633 class_tree != NULL_TREE);
5635 /* If messaging 'Class <Proto>' but did not find a class method
5636 prototype, search for an instance method instead, and warn
5637 about having done so. */
5638 if (!method_prototype && !rtype && class_tree != NULL_TREE)
5641 = lookup_method_in_protocol_list (rprotos, sel_name, 0);
5643 if (method_prototype)
5644 warning ("found %<-%s%> instead of %<+%s%> in protocol(s)",
5645 IDENTIFIER_POINTER (sel_name),
5646 IDENTIFIER_POINTER (sel_name));
5652 tree orig_rtype = rtype, saved_rtype;
5654 if (TREE_CODE (rtype) == POINTER_TYPE)
5655 rtype = TREE_TYPE (rtype);
5656 /* Traverse typedef aliases */
5657 while (TREE_CODE (rtype) == RECORD_TYPE && OBJC_TYPE_NAME (rtype)
5658 && TREE_CODE (OBJC_TYPE_NAME (rtype)) == TYPE_DECL
5659 && DECL_ORIGINAL_TYPE (OBJC_TYPE_NAME (rtype)))
5660 rtype = DECL_ORIGINAL_TYPE (OBJC_TYPE_NAME (rtype));
5661 saved_rtype = rtype;
5662 if (TYPED_OBJECT (rtype))
5664 rprotos = TYPE_OBJC_PROTOCOL_LIST (rtype);
5665 rtype = TYPE_OBJC_INTERFACE (rtype);
5667 /* If we could not find an @interface declaration, we must have
5668 only seen a @class declaration; so, we cannot say anything
5669 more intelligent about which methods the receiver will
5671 if (!rtype || TREE_CODE (rtype) == IDENTIFIER_NODE)
5672 rtype = saved_rtype;
5673 else if (TREE_CODE (rtype) == CLASS_INTERFACE_TYPE
5674 || TREE_CODE (rtype) == CLASS_IMPLEMENTATION_TYPE)
5676 /* We have a valid ObjC class name. Look up the method name
5677 in the published @interface for the class (and its
5680 = lookup_method_static (rtype, sel_name, class_tree != NULL_TREE);
5682 /* If the method was not found in the @interface, it may still
5683 exist locally as part of the @implementation. */
5684 if (!method_prototype && objc_implementation_context
5685 && CLASS_NAME (objc_implementation_context)
5686 == OBJC_TYPE_NAME (rtype))
5690 ? CLASS_CLS_METHODS (objc_implementation_context)
5691 : CLASS_NST_METHODS (objc_implementation_context)),
5694 /* If we haven't found a candidate method by now, try looking for
5695 it in the protocol list. */
5696 if (!method_prototype && rprotos)
5698 = lookup_method_in_protocol_list (rprotos, sel_name,
5699 class_tree != NULL_TREE);
5703 warning ("invalid receiver type %qs",
5704 gen_type_name (orig_rtype));
5705 /* After issuing the "invalid receiver" warning, perform method
5706 lookup as if we were messaging 'id'. */
5707 rtype = rprotos = NULL_TREE;
5712 /* For 'id' or 'Class' receivers, search in the global hash table
5713 as a last resort. For all receivers, warn if protocol searches
5715 if (!method_prototype)
5718 warning ("%<%c%s%> not found in protocol(s)",
5719 (class_tree ? '+' : '-'),
5720 IDENTIFIER_POINTER (sel_name));
5724 = lookup_method_in_hash_lists (sel_name, class_tree != NULL_TREE);
5727 if (!method_prototype)
5729 static bool warn_missing_methods = false;
5732 warning ("%qs may not respond to %<%c%s%>",
5733 IDENTIFIER_POINTER (OBJC_TYPE_NAME (rtype)),
5734 (class_tree ? '+' : '-'),
5735 IDENTIFIER_POINTER (sel_name));
5736 /* If we are messaging an 'id' or 'Class' object and made it here,
5737 then we have failed to find _any_ instance or class method,
5740 warning ("no %<%c%s%> method found",
5741 (class_tree ? '+' : '-'),
5742 IDENTIFIER_POINTER (sel_name));
5744 if (!warn_missing_methods)
5746 warning ("(Messages without a matching method signature");
5747 warning ("will be assumed to return %<id%> and accept");
5748 warning ("%<...%> as arguments.)");
5749 warn_missing_methods = true;
5753 /* Save the selector name for printing error messages. */
5754 current_objc_message_selector = sel_name;
5756 /* Build the parameters list for looking up the method.
5757 These are the object itself and the selector. */
5759 if (flag_typed_selectors)
5760 selector = build_typed_selector_reference (sel_name, method_prototype);
5762 selector = build_selector_reference (sel_name);
5764 retval = build_objc_method_call (super, method_prototype,
5766 selector, method_params);
5768 current_objc_message_selector = 0;
5773 /* Build a tree expression to send OBJECT the operation SELECTOR,
5774 looking up the method on object LOOKUP_OBJECT (often same as OBJECT),
5775 assuming the method has prototype METHOD_PROTOTYPE.
5776 (That is an INSTANCE_METHOD_DECL or CLASS_METHOD_DECL.)
5777 Use METHOD_PARAMS as list of args to pass to the method.
5778 If SUPER_FLAG is nonzero, we look up the superclass's method. */
5781 build_objc_method_call (int super_flag, tree method_prototype,
5782 tree lookup_object, tree selector,
5785 tree sender = (super_flag ? umsg_super_decl :
5786 (!flag_next_runtime || flag_nil_receivers
5788 : umsg_nonnil_decl));
5789 tree rcv_p = (super_flag ? objc_super_type : objc_object_type);
5791 /* If a prototype for the method to be called exists, then cast
5792 the sender's return type and arguments to match that of the method.
5793 Otherwise, leave sender as is. */
5796 ? TREE_VALUE (TREE_TYPE (method_prototype))
5797 : objc_object_type);
5799 = build_pointer_type
5800 (build_function_type
5803 (method_prototype, METHOD_REF, super_flag)));
5806 lookup_object = build_c_cast (rcv_p, lookup_object);
5808 /* Use SAVE_EXPR to avoid evaluating the receiver twice. */
5809 lookup_object = save_expr (lookup_object);
5811 if (flag_next_runtime)
5813 /* If we are returning a struct in memory, and the address
5814 of that memory location is passed as a hidden first
5815 argument, then change which messenger entry point this
5816 expr will call. NB: Note that sender_cast remains
5817 unchanged (it already has a struct return type). */
5818 if (!targetm.calls.struct_value_rtx (0, 0)
5819 && (TREE_CODE (ret_type) == RECORD_TYPE
5820 || TREE_CODE (ret_type) == UNION_TYPE)
5821 && targetm.calls.return_in_memory (ret_type, 0))
5822 sender = (super_flag ? umsg_super_stret_decl :
5823 flag_nil_receivers ? umsg_stret_decl : umsg_nonnil_stret_decl);
5825 method_params = tree_cons (NULL_TREE, lookup_object,
5826 tree_cons (NULL_TREE, selector,
5828 method = build_fold_addr_expr (sender);
5832 /* This is the portable (GNU) way. */
5835 /* First, call the lookup function to get a pointer to the method,
5836 then cast the pointer, then call it with the method arguments. */
5838 object = (super_flag ? self_decl : lookup_object);
5840 t = tree_cons (NULL_TREE, selector, NULL_TREE);
5841 t = tree_cons (NULL_TREE, lookup_object, t);
5842 method = build_function_call (sender, t);
5844 /* Pass the object to the method. */
5845 method_params = tree_cons (NULL_TREE, object,
5846 tree_cons (NULL_TREE, selector,
5850 /* ??? Selector is not at this point something we can use inside
5851 the compiler itself. Set it to garbage for the nonce. */
5852 t = build (OBJ_TYPE_REF, sender_cast, method, lookup_object, size_zero_node);
5853 return build_function_call (t, method_params);
5857 build_protocol_reference (tree p)
5860 const char *proto_name;
5862 /* static struct _objc_protocol _OBJC_PROTOCOL_<mumble>; */
5864 proto_name = synth_id_with_class_suffix ("_OBJC_PROTOCOL", p);
5865 decl = start_var_decl (objc_protocol_template, proto_name);
5867 PROTOCOL_FORWARD_DECL (p) = decl;
5870 /* This function is called by the parser when (and only when) a
5871 @protocol() expression is found, in order to compile it. */
5873 objc_build_protocol_expr (tree protoname)
5876 tree p = lookup_protocol (protoname);
5880 error ("cannot find protocol declaration for %qs",
5881 IDENTIFIER_POINTER (protoname));
5882 return error_mark_node;
5885 if (!PROTOCOL_FORWARD_DECL (p))
5886 build_protocol_reference (p);
5888 expr = build_unary_op (ADDR_EXPR, PROTOCOL_FORWARD_DECL (p), 0);
5890 /* ??? Ideally we'd build the reference with objc_protocol_type directly,
5891 if we have it, rather than converting it here. */
5892 expr = convert (objc_protocol_type, expr);
5894 /* The @protocol() expression is being compiled into a pointer to a
5895 statically allocated instance of the Protocol class. To become
5896 usable at runtime, the 'isa' pointer of the instance need to be
5897 fixed up at runtime by the runtime library, to point to the
5898 actual 'Protocol' class. */
5900 /* For the GNU runtime, put the static Protocol instance in the list
5901 of statically allocated instances, so that we make sure that its
5902 'isa' pointer is fixed up at runtime by the GNU runtime library
5903 to point to the Protocol class (at runtime, when loading the
5904 module, the GNU runtime library loops on the statically allocated
5905 instances (as found in the defs field in objc_symtab) and fixups
5906 all the 'isa' pointers of those objects). */
5907 if (! flag_next_runtime)
5909 /* This type is a struct containing the fields of a Protocol
5910 object. (Cfr. objc_protocol_type instead is the type of a pointer
5911 to such a struct). */
5912 tree protocol_struct_type = xref_tag
5913 (RECORD_TYPE, get_identifier (PROTOCOL_OBJECT_CLASS_NAME));
5916 /* Look for the list of Protocol statically allocated instances
5917 to fixup at runtime. Create a new list to hold Protocol
5918 statically allocated instances, if the list is not found. At
5919 present there is only another list, holding NSConstantString
5920 static instances to be fixed up at runtime. */
5921 for (chain = &objc_static_instances;
5922 *chain && TREE_VALUE (*chain) != protocol_struct_type;
5923 chain = &TREE_CHAIN (*chain));
5926 *chain = tree_cons (NULL_TREE, protocol_struct_type, NULL_TREE);
5927 add_objc_string (OBJC_TYPE_NAME (protocol_struct_type),
5931 /* Add this statically allocated instance to the Protocol list. */
5932 TREE_PURPOSE (*chain) = tree_cons (NULL_TREE,
5933 PROTOCOL_FORWARD_DECL (p),
5934 TREE_PURPOSE (*chain));
5941 /* This function is called by the parser when a @selector() expression
5942 is found, in order to compile it. It is only called by the parser
5943 and only to compile a @selector(). */
5945 objc_build_selector_expr (tree selnamelist)
5949 /* Obtain the full selector name. */
5950 if (TREE_CODE (selnamelist) == IDENTIFIER_NODE)
5951 /* A unary selector. */
5952 selname = selnamelist;
5953 else if (TREE_CODE (selnamelist) == TREE_LIST)
5954 selname = build_keyword_selector (selnamelist);
5958 /* If we are required to check @selector() expressions as they
5959 are found, check that the selector has been declared. */
5960 if (warn_undeclared_selector)
5962 /* Look the selector up in the list of all known class and
5963 instance methods (up to this line) to check that the selector
5967 /* First try with instance methods. */
5968 hsh = hash_lookup (nst_method_hash_list, selname);
5970 /* If not found, try with class methods. */
5973 hsh = hash_lookup (cls_method_hash_list, selname);
5976 /* If still not found, print out a warning. */
5979 warning ("undeclared selector %qs", IDENTIFIER_POINTER (selname));
5984 if (flag_typed_selectors)
5985 return build_typed_selector_reference (selname, 0);
5987 return build_selector_reference (selname);
5991 objc_build_encode_expr (tree type)
5996 encode_type (type, obstack_object_size (&util_obstack),
5997 OBJC_ENCODE_INLINE_DEFS);
5998 obstack_1grow (&util_obstack, 0); /* null terminate string */
5999 string = obstack_finish (&util_obstack);
6001 /* Synthesize a string that represents the encoded struct/union. */
6002 result = my_build_string (strlen (string) + 1, string);
6003 obstack_free (&util_obstack, util_firstobj);
6008 build_ivar_reference (tree id)
6010 if (TREE_CODE (objc_method_context) == CLASS_METHOD_DECL)
6012 /* Historically, a class method that produced objects (factory
6013 method) would assign `self' to the instance that it
6014 allocated. This would effectively turn the class method into
6015 an instance method. Following this assignment, the instance
6016 variables could be accessed. That practice, while safe,
6017 violates the simple rule that a class method should not refer
6018 to an instance variable. It's better to catch the cases
6019 where this is done unknowingly than to support the above
6021 warning ("instance variable %qs accessed in class method",
6022 IDENTIFIER_POINTER (id));
6023 self_decl = convert (objc_instance_type, self_decl); /* cast */
6026 return build_component_ref (build_indirect_ref (self_decl, "->"), id);
6029 /* Compute a hash value for a given method SEL_NAME. */
6032 hash_func (tree sel_name)
6034 const unsigned char *s
6035 = (const unsigned char *)IDENTIFIER_POINTER (sel_name);
6039 h = h * 67 + *s++ - 113;
6046 nst_method_hash_list
6047 = (hash *) ggc_alloc_cleared (SIZEHASHTABLE * sizeof (hash));
6048 cls_method_hash_list
6049 = (hash *) ggc_alloc_cleared (SIZEHASHTABLE * sizeof (hash));
6051 /* Initialize the hash table used to hold the constant string objects. */
6052 string_htab = htab_create_ggc (31, string_hash,
6056 /* WARNING!!!! hash_enter is called with a method, and will peek
6057 inside to find its selector! But hash_lookup is given a selector
6058 directly, and looks for the selector that's inside the found
6059 entry's key (method) for comparison. */
6062 hash_enter (hash *hashlist, tree method)
6065 int slot = hash_func (METHOD_SEL_NAME (method)) % SIZEHASHTABLE;
6067 obj = (hash) ggc_alloc (sizeof (struct hashed_entry));
6069 obj->next = hashlist[slot];
6072 hashlist[slot] = obj; /* append to front */
6076 hash_lookup (hash *hashlist, tree sel_name)
6080 target = hashlist[hash_func (sel_name) % SIZEHASHTABLE];
6084 if (sel_name == METHOD_SEL_NAME (target->key))
6087 target = target->next;
6093 hash_add_attr (hash entry, tree value)
6097 obj = (attr) ggc_alloc (sizeof (struct hashed_attribute));
6098 obj->next = entry->list;
6101 entry->list = obj; /* append to front */
6105 lookup_method (tree mchain, tree method)
6109 if (TREE_CODE (method) == IDENTIFIER_NODE)
6112 key = METHOD_SEL_NAME (method);
6116 if (METHOD_SEL_NAME (mchain) == key)
6119 mchain = TREE_CHAIN (mchain);
6125 lookup_method_static (tree interface, tree ident, int is_class)
6127 tree meth = NULL_TREE, root_inter = NULL_TREE;
6128 tree inter = interface;
6132 tree chain = is_class ? CLASS_CLS_METHODS (inter) : CLASS_NST_METHODS (inter);
6133 tree category = inter;
6135 /* First, look up the method in the class itself. */
6136 if ((meth = lookup_method (chain, ident)))
6139 /* Failing that, look for the method in each category of the class. */
6140 while ((category = CLASS_CATEGORY_LIST (category)))
6142 chain = is_class ? CLASS_CLS_METHODS (category) : CLASS_NST_METHODS (category);
6144 /* Check directly in each category. */
6145 if ((meth = lookup_method (chain, ident)))
6148 /* Failing that, check in each category's protocols. */
6149 if (CLASS_PROTOCOL_LIST (category))
6151 if ((meth = (lookup_method_in_protocol_list
6152 (CLASS_PROTOCOL_LIST (category), ident, is_class))))
6157 /* If not found in categories, check in protocols of the main class. */
6158 if (CLASS_PROTOCOL_LIST (inter))
6160 if ((meth = (lookup_method_in_protocol_list
6161 (CLASS_PROTOCOL_LIST (inter), ident, is_class))))
6165 /* Failing that, climb up the inheritance hierarchy. */
6167 inter = lookup_interface (CLASS_SUPER_NAME (inter));
6171 /* If no class (factory) method was found, check if an _instance_
6172 method of the same name exists in the root class. This is what
6173 the Objective-C runtime will do. If an instance method was not
6175 return is_class ? lookup_method_static (root_inter, ident, 0): NULL_TREE;
6178 /* Add the method to the hash list if it doesn't contain an identical
6181 add_method_to_hash_list (hash *hash_list, tree method)
6185 if (!(hsh = hash_lookup (hash_list, METHOD_SEL_NAME (method))))
6187 /* Install on a global chain. */
6188 hash_enter (hash_list, method);
6192 /* Check types against those; if different, add to a list. */
6194 int already_there = comp_proto_with_proto (method, hsh->key);
6195 for (loop = hsh->list; !already_there && loop; loop = loop->next)
6196 already_there |= comp_proto_with_proto (method, loop->value);
6198 hash_add_attr (hsh, method);
6203 objc_add_method (tree class, tree method, int is_class)
6207 if (!(mth = lookup_method (is_class
6208 ? CLASS_CLS_METHODS (class)
6209 : CLASS_NST_METHODS (class), method)))
6211 /* put method on list in reverse order */
6214 TREE_CHAIN (method) = CLASS_CLS_METHODS (class);
6215 CLASS_CLS_METHODS (class) = method;
6219 TREE_CHAIN (method) = CLASS_NST_METHODS (class);
6220 CLASS_NST_METHODS (class) = method;
6225 /* When processing an @interface for a class or category, give hard
6226 errors on methods with identical selectors but differing argument
6227 and/or return types. We do not do this for @implementations, because
6228 C/C++ will do it for us (i.e., there will be duplicate function
6229 definition errors). */
6230 if ((TREE_CODE (class) == CLASS_INTERFACE_TYPE
6231 || TREE_CODE (class) == CATEGORY_INTERFACE_TYPE)
6232 && !comp_proto_with_proto (method, mth))
6233 error ("duplicate declaration of method %<%c%s%>",
6234 is_class ? '+' : '-',
6235 IDENTIFIER_POINTER (METHOD_SEL_NAME (mth)));
6239 add_method_to_hash_list (cls_method_hash_list, method);
6242 add_method_to_hash_list (nst_method_hash_list, method);
6244 /* Instance methods in root classes (and categories thereof)
6245 may act as class methods as a last resort. We also add
6246 instance methods listed in @protocol declarations to
6247 the class hash table, on the assumption that @protocols
6248 may be adopted by root classes or categories. */
6249 if (TREE_CODE (class) == CATEGORY_INTERFACE_TYPE
6250 || TREE_CODE (class) == CATEGORY_IMPLEMENTATION_TYPE)
6251 class = lookup_interface (CLASS_NAME (class));
6253 if (TREE_CODE (class) == PROTOCOL_INTERFACE_TYPE
6254 || !CLASS_SUPER_NAME (class))
6255 add_method_to_hash_list (cls_method_hash_list, method);
6262 add_class (tree class)
6264 /* Put interfaces on list in reverse order. */
6265 TREE_CHAIN (class) = interface_chain;
6266 interface_chain = class;
6267 return interface_chain;
6271 add_category (tree class, tree category)
6273 /* Put categories on list in reverse order. */
6274 tree cat = lookup_category (class, CLASS_SUPER_NAME (category));
6278 warning ("duplicate interface declaration for category %<%s(%s)%>",
6279 IDENTIFIER_POINTER (CLASS_NAME (class)),
6280 IDENTIFIER_POINTER (CLASS_SUPER_NAME (category)));
6284 CLASS_CATEGORY_LIST (category) = CLASS_CATEGORY_LIST (class);
6285 CLASS_CATEGORY_LIST (class) = category;
6289 /* Called after parsing each instance variable declaration. Necessary to
6290 preserve typedefs and implement public/private...
6292 PUBLIC is 1 for public, 0 for protected, and 2 for private. */
6295 add_instance_variable (tree class, int public, tree field_decl)
6297 tree field_type = TREE_TYPE (field_decl);
6298 const char *ivar_name = DECL_NAME (field_decl)
6299 ? IDENTIFIER_POINTER (DECL_NAME (field_decl))
6303 if (TREE_CODE (field_type) == REFERENCE_TYPE)
6305 error ("illegal reference type specified for instance variable %qs",
6307 /* Return class as is without adding this ivar. */
6312 if (field_type == error_mark_node || !TYPE_SIZE (field_type)
6313 || TYPE_SIZE (field_type) == error_mark_node)
6314 /* 'type[0]' is allowed, but 'type[]' is not! */
6316 error ("instance variable %qs has unknown size", ivar_name);
6317 /* Return class as is without adding this ivar. */
6322 /* zlaski 2001-Apr-24: C++ classes with non-trivial constructors and/or destructors
6323 cannot be ivars; ditto for classes with vtables. */
6324 if(IS_AGGR_TYPE (field_type) && (TYPE_NEEDS_CONSTRUCTING (field_type)
6325 || TYPE_HAS_NONTRIVIAL_DESTRUCTOR (field_type) || TYPE_POLYMORPHIC_P (field_type)))
6327 const char *type_name = IDENTIFIER_POINTER (OBJC_TYPE_NAME (field_type));
6328 if(TYPE_POLYMORPHIC_P (field_type)) {
6329 /* vtable pointers are Real Bad(tm), since Obj-C cannot initialize them */
6330 error ("type %qs has virtual member functions", type_name);
6331 error ("illegal aggregate type %qs specified for instance variable %qs",
6332 type_name, ivar_name);
6333 /* Return class as is without adding this ivar. */
6336 /* user-defined constructors and destructors are not known to Obj-C and
6337 hence will not be called. This may or may not be a problem. */
6338 if (TYPE_NEEDS_CONSTRUCTING (field_type))
6339 warning ("type %qs has a user-defined constructor", type_name);
6340 if (TYPE_HAS_NONTRIVIAL_DESTRUCTOR (field_type))
6341 warning ("type %qs has a user-defined destructor", type_name);
6342 warning ("C++ constructors and destructors will not be invoked for Objective-C fields");
6346 /* Overload the public attribute, it is not used for FIELD_DECLs. */
6350 TREE_PUBLIC (field_decl) = 0;
6351 TREE_PRIVATE (field_decl) = 0;
6352 TREE_PROTECTED (field_decl) = 1;
6356 TREE_PUBLIC (field_decl) = 1;
6357 TREE_PRIVATE (field_decl) = 0;
6358 TREE_PROTECTED (field_decl) = 0;
6362 TREE_PUBLIC (field_decl) = 0;
6363 TREE_PRIVATE (field_decl) = 1;
6364 TREE_PROTECTED (field_decl) = 0;
6369 CLASS_RAW_IVARS (class) = chainon (CLASS_RAW_IVARS (class), field_decl);
6375 is_ivar (tree decl_chain, tree ident)
6377 for ( ; decl_chain; decl_chain = TREE_CHAIN (decl_chain))
6378 if (DECL_NAME (decl_chain) == ident)
6383 /* True if the ivar is private and we are not in its implementation. */
6386 is_private (tree decl)
6388 return (TREE_PRIVATE (decl)
6389 && ! is_ivar (CLASS_IVARS (implementation_template),
6393 /* We have an instance variable reference;, check to see if it is public. */
6396 objc_is_public (tree expr, tree identifier)
6398 tree basetype = TREE_TYPE (expr);
6399 enum tree_code code = TREE_CODE (basetype);
6402 if (code == RECORD_TYPE)
6404 if (TYPE_HAS_OBJC_INFO (basetype) && TYPE_OBJC_INTERFACE (basetype))
6406 if (TREE_CODE (TYPE_OBJC_INTERFACE (basetype)) == IDENTIFIER_NODE)
6408 error ("cannot find interface declaration for %qs",
6409 IDENTIFIER_POINTER (OBJC_TYPE_NAME (basetype)));
6413 if ((decl = is_ivar (TYPE_FIELDS (basetype), identifier)))
6415 if (TREE_PUBLIC (decl))
6418 /* Important difference between the Stepstone translator:
6419 all instance variables should be public within the context
6420 of the implementation. */
6421 if (objc_implementation_context
6422 && (((TREE_CODE (objc_implementation_context)
6423 == CLASS_IMPLEMENTATION_TYPE)
6424 || (TREE_CODE (objc_implementation_context)
6425 == CATEGORY_IMPLEMENTATION_TYPE))
6426 && (CLASS_NAME (objc_implementation_context)
6427 == OBJC_TYPE_NAME (basetype))))
6429 int private = is_private (decl);
6432 error ("instance variable %qs is declared private",
6433 IDENTIFIER_POINTER (DECL_NAME (decl)));
6437 /* The 2.95.2 compiler sometimes allowed C functions to access
6438 non-@public ivars. We will let this slide for now... */
6439 if (!objc_method_context)
6441 warning ("instance variable %qs is %s; "
6442 "this will be a hard error in the future",
6443 IDENTIFIER_POINTER (identifier),
6444 TREE_PRIVATE (decl) ? "@private" : "@protected");
6448 error ("instance variable %qs is declared %s",
6449 IDENTIFIER_POINTER (identifier),
6450 TREE_PRIVATE (decl) ? "private" : "protected");
6455 else if (objc_implementation_context && (basetype == objc_object_reference))
6457 expr = convert (uprivate_record, expr);
6458 warning ("static access to object of type %<id%>");
6465 /* Make sure all entries in CHAIN are also in LIST. */
6468 check_methods (tree chain, tree list, int mtype)
6474 if (!lookup_method (list, chain))
6478 if (TREE_CODE (objc_implementation_context)
6479 == CLASS_IMPLEMENTATION_TYPE)
6480 warning ("incomplete implementation of class %qs",
6481 IDENTIFIER_POINTER (CLASS_NAME (objc_implementation_context)));
6482 else if (TREE_CODE (objc_implementation_context)
6483 == CATEGORY_IMPLEMENTATION_TYPE)
6484 warning ("incomplete implementation of category %qs",
6485 IDENTIFIER_POINTER (CLASS_SUPER_NAME (objc_implementation_context)));
6489 warning ("method definition for %<%c%s%> not found",
6490 mtype, IDENTIFIER_POINTER (METHOD_SEL_NAME (chain)));
6493 chain = TREE_CHAIN (chain);
6499 /* Check if CLASS, or its superclasses, explicitly conforms to PROTOCOL. */
6502 conforms_to_protocol (tree class, tree protocol)
6504 if (TREE_CODE (protocol) == PROTOCOL_INTERFACE_TYPE)
6506 tree p = CLASS_PROTOCOL_LIST (class);
6507 while (p && TREE_VALUE (p) != protocol)
6512 tree super = (CLASS_SUPER_NAME (class)
6513 ? lookup_interface (CLASS_SUPER_NAME (class))
6515 int tmp = super ? conforms_to_protocol (super, protocol) : 0;
6524 /* Make sure all methods in CHAIN are accessible as MTYPE methods in
6525 CONTEXT. This is one of two mechanisms to check protocol integrity. */
6528 check_methods_accessible (tree chain, tree context, int mtype)
6532 tree base_context = context;
6536 context = base_context;
6540 list = CLASS_CLS_METHODS (context);
6542 list = CLASS_NST_METHODS (context);
6544 if (lookup_method (list, chain))
6547 else if (TREE_CODE (context) == CLASS_IMPLEMENTATION_TYPE
6548 || TREE_CODE (context) == CLASS_INTERFACE_TYPE)
6549 context = (CLASS_SUPER_NAME (context)
6550 ? lookup_interface (CLASS_SUPER_NAME (context))
6553 else if (TREE_CODE (context) == CATEGORY_IMPLEMENTATION_TYPE
6554 || TREE_CODE (context) == CATEGORY_INTERFACE_TYPE)
6555 context = (CLASS_NAME (context)
6556 ? lookup_interface (CLASS_NAME (context))
6562 if (context == NULL_TREE)
6566 if (TREE_CODE (objc_implementation_context)
6567 == CLASS_IMPLEMENTATION_TYPE)
6568 warning ("incomplete implementation of class %qs",
6570 (CLASS_NAME (objc_implementation_context)));
6571 else if (TREE_CODE (objc_implementation_context)
6572 == CATEGORY_IMPLEMENTATION_TYPE)
6573 warning ("incomplete implementation of category %qs",
6575 (CLASS_SUPER_NAME (objc_implementation_context)));
6578 warning ("method definition for %<%c%s%> not found",
6579 mtype, IDENTIFIER_POINTER (METHOD_SEL_NAME (chain)));
6582 chain = TREE_CHAIN (chain); /* next method... */
6587 /* Check whether the current interface (accessible via
6588 'objc_implementation_context') actually implements protocol P, along
6589 with any protocols that P inherits. */
6592 check_protocol (tree p, const char *type, const char *name)
6594 if (TREE_CODE (p) == PROTOCOL_INTERFACE_TYPE)
6598 /* Ensure that all protocols have bodies! */
6601 f1 = check_methods (PROTOCOL_CLS_METHODS (p),
6602 CLASS_CLS_METHODS (objc_implementation_context),
6604 f2 = check_methods (PROTOCOL_NST_METHODS (p),
6605 CLASS_NST_METHODS (objc_implementation_context),
6610 f1 = check_methods_accessible (PROTOCOL_CLS_METHODS (p),
6611 objc_implementation_context,
6613 f2 = check_methods_accessible (PROTOCOL_NST_METHODS (p),
6614 objc_implementation_context,
6619 warning ("%s %qs does not fully implement the %qs protocol",
6620 type, name, IDENTIFIER_POINTER (PROTOCOL_NAME (p)));
6623 /* Check protocols recursively. */
6624 if (PROTOCOL_LIST (p))
6626 tree subs = PROTOCOL_LIST (p);
6628 lookup_interface (CLASS_SUPER_NAME (implementation_template));
6632 tree sub = TREE_VALUE (subs);
6634 /* If the superclass does not conform to the protocols
6635 inherited by P, then we must! */
6636 if (!super_class || !conforms_to_protocol (super_class, sub))
6637 check_protocol (sub, type, name);
6638 subs = TREE_CHAIN (subs);
6643 /* Check whether the current interface (accessible via
6644 'objc_implementation_context') actually implements the protocols listed
6648 check_protocols (tree proto_list, const char *type, const char *name)
6650 for ( ; proto_list; proto_list = TREE_CHAIN (proto_list))
6652 tree p = TREE_VALUE (proto_list);
6654 check_protocol (p, type, name);
6658 /* Make sure that the class CLASS_NAME is defined
6659 CODE says which kind of thing CLASS_NAME ought to be.
6660 It can be CLASS_INTERFACE_TYPE, CLASS_IMPLEMENTATION_TYPE,
6661 CATEGORY_INTERFACE_TYPE, or CATEGORY_IMPLEMENTATION_TYPE. */
6664 start_class (enum tree_code code, tree class_name, tree super_name,
6670 if (current_namespace != global_namespace) {
6671 error ("Objective-C declarations may only appear in global scope");
6673 #endif /* OBJCPLUS */
6675 if (objc_implementation_context)
6677 warning ("%<@end%> missing in implementation context");
6678 finish_class (objc_implementation_context);
6679 objc_ivar_chain = NULL_TREE;
6680 objc_implementation_context = NULL_TREE;
6683 class = make_node (code);
6684 TYPE_LANG_SLOT_1 (class) = make_tree_vec (CLASS_LANG_SLOT_ELTS);
6686 /* Check for existence of the super class, if one was specified. */
6687 if ((code == CLASS_INTERFACE_TYPE || code == CLASS_IMPLEMENTATION_TYPE)
6688 && super_name && !objc_is_class_name (super_name))
6690 error ("cannot find interface declaration for %qs, superclass of %qs",
6691 IDENTIFIER_POINTER (super_name),
6692 IDENTIFIER_POINTER (class_name));
6693 super_name = NULL_TREE;
6696 CLASS_NAME (class) = class_name;
6697 CLASS_SUPER_NAME (class) = super_name;
6698 CLASS_CLS_METHODS (class) = NULL_TREE;
6700 if (! objc_is_class_name (class_name)
6701 && (decl = lookup_name (class_name)))
6703 error ("%qs redeclared as different kind of symbol",
6704 IDENTIFIER_POINTER (class_name));
6705 error ("%Jprevious declaration of '%D'",
6709 if (code == CLASS_IMPLEMENTATION_TYPE)
6714 for (chain = implemented_classes; chain; chain = TREE_CHAIN (chain))
6715 if (TREE_VALUE (chain) == class_name)
6717 error ("reimplementation of class %qs",
6718 IDENTIFIER_POINTER (class_name));
6719 return error_mark_node;
6721 implemented_classes = tree_cons (NULL_TREE, class_name,
6722 implemented_classes);
6725 /* Reset for multiple classes per file. */
6728 objc_implementation_context = class;
6730 /* Lookup the interface for this implementation. */
6732 if (!(implementation_template = lookup_interface (class_name)))
6734 warning ("cannot find interface declaration for %qs",
6735 IDENTIFIER_POINTER (class_name));
6736 add_class (implementation_template = objc_implementation_context);
6739 /* If a super class has been specified in the implementation,
6740 insure it conforms to the one specified in the interface. */
6743 && (super_name != CLASS_SUPER_NAME (implementation_template)))
6745 tree previous_name = CLASS_SUPER_NAME (implementation_template);
6746 const char *const name =
6747 previous_name ? IDENTIFIER_POINTER (previous_name) : "";
6748 error ("conflicting super class name %qs",
6749 IDENTIFIER_POINTER (super_name));
6750 error ("previous declaration of %qs", name);
6753 else if (! super_name)
6755 CLASS_SUPER_NAME (objc_implementation_context)
6756 = CLASS_SUPER_NAME (implementation_template);
6760 else if (code == CLASS_INTERFACE_TYPE)
6762 if (lookup_interface (class_name))
6764 error ("duplicate interface declaration for class %qs",
6766 warning ("duplicate interface declaration for class %qs",
6768 IDENTIFIER_POINTER (class_name));
6773 CLASS_PROTOCOL_LIST (class)
6774 = lookup_and_install_protocols (protocol_list);
6777 else if (code == CATEGORY_INTERFACE_TYPE)
6779 tree class_category_is_assoc_with;
6781 /* For a category, class_name is really the name of the class that
6782 the following set of methods will be associated with. We must
6783 find the interface so that can derive the objects template. */
6785 if (!(class_category_is_assoc_with = lookup_interface (class_name)))
6787 error ("cannot find interface declaration for %qs",
6788 IDENTIFIER_POINTER (class_name));
6789 exit (FATAL_EXIT_CODE);
6792 add_category (class_category_is_assoc_with, class);
6795 CLASS_PROTOCOL_LIST (class)
6796 = lookup_and_install_protocols (protocol_list);
6799 else if (code == CATEGORY_IMPLEMENTATION_TYPE)
6801 /* Reset for multiple classes per file. */
6804 objc_implementation_context = class;
6806 /* For a category, class_name is really the name of the class that
6807 the following set of methods will be associated with. We must
6808 find the interface so that can derive the objects template. */
6810 if (!(implementation_template = lookup_interface (class_name)))
6812 error ("cannot find interface declaration for %qs",
6813 IDENTIFIER_POINTER (class_name));
6814 exit (FATAL_EXIT_CODE);
6821 continue_class (tree class)
6823 if (TREE_CODE (class) == CLASS_IMPLEMENTATION_TYPE
6824 || TREE_CODE (class) == CATEGORY_IMPLEMENTATION_TYPE)
6826 struct imp_entry *imp_entry;
6829 /* Check consistency of the instance variables. */
6831 if (CLASS_RAW_IVARS (class))
6832 check_ivars (implementation_template, class);
6834 /* code generation */
6837 push_lang_context (lang_name_c);
6840 build_private_template (implementation_template);
6841 uprivate_record = CLASS_STATIC_TEMPLATE (implementation_template);
6842 ivar_context = TYPE_FIELDS (uprivate_record);
6843 objc_instance_type = build_pointer_type (uprivate_record);
6845 imp_entry = (struct imp_entry *) ggc_alloc (sizeof (struct imp_entry));
6847 imp_entry->next = imp_list;
6848 imp_entry->imp_context = class;
6849 imp_entry->imp_template = implementation_template;
6851 synth_forward_declarations ();
6852 imp_entry->class_decl = UOBJC_CLASS_decl;
6853 imp_entry->meta_decl = UOBJC_METACLASS_decl;
6855 /* Append to front and increment count. */
6856 imp_list = imp_entry;
6857 if (TREE_CODE (class) == CLASS_IMPLEMENTATION_TYPE)
6863 pop_lang_context ();
6864 #endif /* OBJCPLUS */
6866 return ivar_context;
6869 else if (TREE_CODE (class) == CLASS_INTERFACE_TYPE)
6872 push_lang_context (lang_name_c);
6873 #endif /* OBJCPLUS */
6875 build_private_template (class);
6878 pop_lang_context ();
6879 #endif /* OBJCPLUS */
6885 return error_mark_node;
6888 /* This is called once we see the "@end" in an interface/implementation. */
6891 finish_class (tree class)
6893 if (TREE_CODE (class) == CLASS_IMPLEMENTATION_TYPE)
6895 /* All code generation is done in finish_objc. */
6897 if (implementation_template != objc_implementation_context)
6899 /* Ensure that all method listed in the interface contain bodies. */
6900 check_methods (CLASS_CLS_METHODS (implementation_template),
6901 CLASS_CLS_METHODS (objc_implementation_context), '+');
6902 check_methods (CLASS_NST_METHODS (implementation_template),
6903 CLASS_NST_METHODS (objc_implementation_context), '-');
6905 if (CLASS_PROTOCOL_LIST (implementation_template))
6906 check_protocols (CLASS_PROTOCOL_LIST (implementation_template),
6908 IDENTIFIER_POINTER (CLASS_NAME (objc_implementation_context)));
6912 else if (TREE_CODE (class) == CATEGORY_IMPLEMENTATION_TYPE)
6914 tree category = lookup_category (implementation_template, CLASS_SUPER_NAME (class));
6918 /* Ensure all method listed in the interface contain bodies. */
6919 check_methods (CLASS_CLS_METHODS (category),
6920 CLASS_CLS_METHODS (objc_implementation_context), '+');
6921 check_methods (CLASS_NST_METHODS (category),
6922 CLASS_NST_METHODS (objc_implementation_context), '-');
6924 if (CLASS_PROTOCOL_LIST (category))
6925 check_protocols (CLASS_PROTOCOL_LIST (category),
6927 IDENTIFIER_POINTER (CLASS_SUPER_NAME (objc_implementation_context)));
6933 add_protocol (tree protocol)
6935 /* Put protocol on list in reverse order. */
6936 TREE_CHAIN (protocol) = protocol_chain;
6937 protocol_chain = protocol;
6938 return protocol_chain;
6942 lookup_protocol (tree ident)
6946 for (chain = protocol_chain; chain; chain = TREE_CHAIN (chain))
6947 if (ident == PROTOCOL_NAME (chain))
6953 /* This function forward declares the protocols named by NAMES. If
6954 they are already declared or defined, the function has no effect. */
6957 objc_declare_protocols (tree names)
6962 if (current_namespace != global_namespace) {
6963 error ("Objective-C declarations may only appear in global scope");
6965 #endif /* OBJCPLUS */
6967 for (list = names; list; list = TREE_CHAIN (list))
6969 tree name = TREE_VALUE (list);
6971 if (lookup_protocol (name) == NULL_TREE)
6973 tree protocol = make_node (PROTOCOL_INTERFACE_TYPE);
6975 TYPE_LANG_SLOT_1 (protocol)
6976 = make_tree_vec (PROTOCOL_LANG_SLOT_ELTS);
6977 PROTOCOL_NAME (protocol) = name;
6978 PROTOCOL_LIST (protocol) = NULL_TREE;
6979 add_protocol (protocol);
6980 PROTOCOL_DEFINED (protocol) = 0;
6981 PROTOCOL_FORWARD_DECL (protocol) = NULL_TREE;
6987 start_protocol (enum tree_code code, tree name, tree list)
6992 if (current_namespace != global_namespace) {
6993 error ("Objective-C declarations may only appear in global scope");
6995 #endif /* OBJCPLUS */
6997 protocol = lookup_protocol (name);
7001 protocol = make_node (code);
7002 TYPE_LANG_SLOT_1 (protocol) = make_tree_vec (PROTOCOL_LANG_SLOT_ELTS);
7004 PROTOCOL_NAME (protocol) = name;
7005 PROTOCOL_LIST (protocol) = lookup_and_install_protocols (list);
7006 add_protocol (protocol);
7007 PROTOCOL_DEFINED (protocol) = 1;
7008 PROTOCOL_FORWARD_DECL (protocol) = NULL_TREE;
7010 check_protocol_recursively (protocol, list);
7012 else if (! PROTOCOL_DEFINED (protocol))
7014 PROTOCOL_DEFINED (protocol) = 1;
7015 PROTOCOL_LIST (protocol) = lookup_and_install_protocols (list);
7017 check_protocol_recursively (protocol, list);
7021 warning ("duplicate declaration for protocol %qs",
7022 IDENTIFIER_POINTER (name));
7028 /* "Encode" a data type into a string, which grows in util_obstack.
7029 ??? What is the FORMAT? Someone please document this! */
7032 encode_type_qualifiers (tree declspecs)
7036 for (spec = declspecs; spec; spec = TREE_CHAIN (spec))
7038 if (ridpointers[(int) RID_IN] == TREE_VALUE (spec))
7039 obstack_1grow (&util_obstack, 'n');
7040 else if (ridpointers[(int) RID_INOUT] == TREE_VALUE (spec))
7041 obstack_1grow (&util_obstack, 'N');
7042 else if (ridpointers[(int) RID_OUT] == TREE_VALUE (spec))
7043 obstack_1grow (&util_obstack, 'o');
7044 else if (ridpointers[(int) RID_BYCOPY] == TREE_VALUE (spec))
7045 obstack_1grow (&util_obstack, 'O');
7046 else if (ridpointers[(int) RID_BYREF] == TREE_VALUE (spec))
7047 obstack_1grow (&util_obstack, 'R');
7048 else if (ridpointers[(int) RID_ONEWAY] == TREE_VALUE (spec))
7049 obstack_1grow (&util_obstack, 'V');
7053 /* Encode a pointer type. */
7056 encode_pointer (tree type, int curtype, int format)
7058 tree pointer_to = TREE_TYPE (type);
7060 if (TREE_CODE (pointer_to) == RECORD_TYPE)
7062 if (OBJC_TYPE_NAME (pointer_to)
7063 && TREE_CODE (OBJC_TYPE_NAME (pointer_to)) == IDENTIFIER_NODE)
7065 const char *name = IDENTIFIER_POINTER (OBJC_TYPE_NAME (pointer_to));
7067 if (strcmp (name, TAG_OBJECT) == 0) /* '@' */
7069 obstack_1grow (&util_obstack, '@');
7072 else if (TYPE_HAS_OBJC_INFO (pointer_to)
7073 && TYPE_OBJC_INTERFACE (pointer_to))
7075 if (generating_instance_variables)
7077 obstack_1grow (&util_obstack, '@');
7078 obstack_1grow (&util_obstack, '"');
7079 obstack_grow (&util_obstack, name, strlen (name));
7080 obstack_1grow (&util_obstack, '"');
7085 obstack_1grow (&util_obstack, '@');
7089 else if (strcmp (name, TAG_CLASS) == 0) /* '#' */
7091 obstack_1grow (&util_obstack, '#');
7094 else if (strcmp (name, TAG_SELECTOR) == 0) /* ':' */
7096 obstack_1grow (&util_obstack, ':');
7101 else if (TREE_CODE (pointer_to) == INTEGER_TYPE
7102 && TYPE_MODE (pointer_to) == QImode)
7104 tree pname = TREE_CODE (OBJC_TYPE_NAME (pointer_to)) == IDENTIFIER_NODE
7105 ? OBJC_TYPE_NAME (pointer_to)
7106 : DECL_NAME (OBJC_TYPE_NAME (pointer_to));
7108 if (!flag_next_runtime || strcmp (IDENTIFIER_POINTER (pname), "BOOL"))
7110 /* It appears that "r*" means "const char *" rather than
7112 if (TYPE_READONLY (pointer_to))
7113 obstack_1grow (&util_obstack, 'r');
7115 obstack_1grow (&util_obstack, '*');
7120 /* We have a type that does not get special treatment. */
7122 /* NeXT extension */
7123 obstack_1grow (&util_obstack, '^');
7124 encode_type (pointer_to, curtype, format);
7128 encode_array (tree type, int curtype, int format)
7130 tree an_int_cst = TYPE_SIZE (type);
7131 tree array_of = TREE_TYPE (type);
7134 /* An incomplete array is treated like a pointer. */
7135 if (an_int_cst == NULL)
7137 encode_pointer (type, curtype, format);
7141 sprintf (buffer, "[" HOST_WIDE_INT_PRINT_DEC,
7142 (TREE_INT_CST_LOW (an_int_cst)
7143 / TREE_INT_CST_LOW (TYPE_SIZE (array_of))));
7145 obstack_grow (&util_obstack, buffer, strlen (buffer));
7146 encode_type (array_of, curtype, format);
7147 obstack_1grow (&util_obstack, ']');
7152 encode_aggregate_within (tree type, int curtype, int format, int left,
7156 /* NB: aggregates that are pointed to have slightly different encoding
7157 rules in that you never encode the names of instance variables. */
7159 = (obstack_object_size (&util_obstack) > 0
7160 && *(obstack_next_free (&util_obstack) - 1) == '^');
7162 = ((format == OBJC_ENCODE_INLINE_DEFS || generating_instance_variables)
7163 && (!pointed_to || obstack_object_size (&util_obstack) - curtype == 1));
7165 /* Traverse struct aliases; it is important to get the
7166 original struct and its tag name (if any). */
7167 type = TYPE_MAIN_VARIANT (type);
7168 name = OBJC_TYPE_NAME (type);
7169 /* Open parenth/bracket. */
7170 obstack_1grow (&util_obstack, left);
7172 /* Encode the struct/union tag name, or '?' if a tag was
7173 not provided. Typedef aliases do not qualify. */
7174 if (name && TREE_CODE (name) == IDENTIFIER_NODE
7176 /* Did this struct have a tag? */
7177 && !TYPE_WAS_ANONYMOUS (type)
7180 obstack_grow (&util_obstack,
7181 IDENTIFIER_POINTER (name),
7182 strlen (IDENTIFIER_POINTER (name)));
7184 obstack_1grow (&util_obstack, '?');
7186 /* Encode the types (and possibly names) of the inner fields,
7188 if (inline_contents)
7190 tree fields = TYPE_FIELDS (type);
7192 obstack_1grow (&util_obstack, '=');
7193 for (; fields; fields = TREE_CHAIN (fields))
7196 /* C++ static members, and things that are not fields at all,
7197 should not appear in the encoding. */
7198 if (TREE_CODE (fields) != FIELD_DECL || TREE_STATIC (fields))
7201 if (generating_instance_variables && !pointed_to)
7203 tree fname = DECL_NAME (fields);
7205 obstack_1grow (&util_obstack, '"');
7206 if (fname && TREE_CODE (fname) == IDENTIFIER_NODE)
7207 obstack_grow (&util_obstack,
7208 IDENTIFIER_POINTER (fname),
7209 strlen (IDENTIFIER_POINTER (fname)));
7210 obstack_1grow (&util_obstack, '"');
7212 encode_field_decl (fields, curtype, format);
7215 /* Close parenth/bracket. */
7216 obstack_1grow (&util_obstack, right);
7220 encode_aggregate (tree type, int curtype, int format)
7222 enum tree_code code = TREE_CODE (type);
7228 encode_aggregate_within (type, curtype, format, '{', '}');
7233 encode_aggregate_within (type, curtype, format, '(', ')');
7238 obstack_1grow (&util_obstack, 'i');
7246 /* Encode a bitfield NeXT-style (i.e., without a bit offset or the underlying
7250 encode_next_bitfield (int width)
7253 sprintf (buffer, "b%d", width);
7254 obstack_grow (&util_obstack, buffer, strlen (buffer));
7257 /* FORMAT will be OBJC_ENCODE_INLINE_DEFS or OBJC_ENCODE_DONT_INLINE_DEFS. */
7259 encode_type (tree type, int curtype, int format)
7261 enum tree_code code = TREE_CODE (type);
7264 if (TYPE_READONLY (type))
7265 obstack_1grow (&util_obstack, 'r');
7267 if (code == INTEGER_TYPE)
7269 switch (GET_MODE_BITSIZE (TYPE_MODE (type)))
7271 case 8: c = TYPE_UNSIGNED (type) ? 'C' : 'c'; break;
7272 case 16: c = TYPE_UNSIGNED (type) ? 'S' : 's'; break;
7274 if (type == long_unsigned_type_node
7275 || type == long_integer_type_node)
7276 c = TYPE_UNSIGNED (type) ? 'L' : 'l';
7278 c = TYPE_UNSIGNED (type) ? 'I' : 'i';
7280 case 64: c = TYPE_UNSIGNED (type) ? 'Q' : 'q'; break;
7283 obstack_1grow (&util_obstack, c);
7286 else if (code == REAL_TYPE)
7288 /* Floating point types. */
7289 switch (GET_MODE_BITSIZE (TYPE_MODE (type)))
7291 case 32: c = 'f'; break;
7294 case 128: c = 'd'; break;
7297 obstack_1grow (&util_obstack, c);
7300 else if (code == VOID_TYPE)
7301 obstack_1grow (&util_obstack, 'v');
7303 else if (code == BOOLEAN_TYPE)
7304 obstack_1grow (&util_obstack, 'B');
7306 else if (code == ARRAY_TYPE)
7307 encode_array (type, curtype, format);
7309 else if (code == POINTER_TYPE)
7310 encode_pointer (type, curtype, format);
7312 else if (code == RECORD_TYPE || code == UNION_TYPE || code == ENUMERAL_TYPE)
7313 encode_aggregate (type, curtype, format);
7315 else if (code == FUNCTION_TYPE) /* '?' */
7316 obstack_1grow (&util_obstack, '?');
7320 encode_gnu_bitfield (int position, tree type, int size)
7322 enum tree_code code = TREE_CODE (type);
7324 char charType = '?';
7326 if (code == INTEGER_TYPE)
7328 if (integer_zerop (TYPE_MIN_VALUE (type)))
7330 /* Unsigned integer types. */
7332 if (TYPE_MODE (type) == QImode)
7334 else if (TYPE_MODE (type) == HImode)
7336 else if (TYPE_MODE (type) == SImode)
7338 if (type == long_unsigned_type_node)
7343 else if (TYPE_MODE (type) == DImode)
7348 /* Signed integer types. */
7350 if (TYPE_MODE (type) == QImode)
7352 else if (TYPE_MODE (type) == HImode)
7354 else if (TYPE_MODE (type) == SImode)
7356 if (type == long_integer_type_node)
7362 else if (TYPE_MODE (type) == DImode)
7366 else if (code == ENUMERAL_TYPE)
7371 sprintf (buffer, "b%d%c%d", position, charType, size);
7372 obstack_grow (&util_obstack, buffer, strlen (buffer));
7376 encode_field_decl (tree field_decl, int curtype, int format)
7381 /* C++ static members, and things that are not fields at all,
7382 should not appear in the encoding. */
7383 if (TREE_CODE (field_decl) != FIELD_DECL || TREE_STATIC (field_decl))
7387 type = TREE_TYPE (field_decl);
7389 /* Generate the bitfield typing information, if needed. Note the difference
7390 between GNU and NeXT runtimes. */
7391 if (DECL_BIT_FIELD_TYPE (field_decl))
7393 int size = tree_low_cst (DECL_SIZE (field_decl), 1);
7395 if (flag_next_runtime)
7396 encode_next_bitfield (size);
7398 encode_gnu_bitfield (int_bit_position (field_decl),
7399 DECL_BIT_FIELD_TYPE (field_decl), size);
7402 encode_type (TREE_TYPE (field_decl), curtype, format);
7405 static GTY(()) tree objc_parmlist = NULL_TREE;
7407 /* Append PARM to a list of formal parameters of a method, making a necessary
7408 array-to-pointer adjustment along the way. */
7411 objc_push_parm (tree parm)
7413 /* Decay arrays and functions into pointers. */
7414 if (TREE_CODE (TREE_TYPE (parm)) == ARRAY_TYPE)
7415 TREE_TYPE (parm) = build_pointer_type (TREE_TYPE (TREE_TYPE (parm)));
7416 else if (TREE_CODE (TREE_TYPE (parm)) == FUNCTION_TYPE)
7417 TREE_TYPE (parm) = build_pointer_type (TREE_TYPE (parm));
7419 DECL_ARG_TYPE_AS_WRITTEN (parm) = TREE_TYPE (parm);
7420 DECL_ARG_TYPE (parm)
7421 = lang_hooks.types.type_promotes_to (TREE_TYPE (parm));
7423 /* Record constancy and volatility. */
7424 c_apply_type_quals_to_decl
7425 ((TYPE_READONLY (TREE_TYPE (parm)) ? TYPE_QUAL_CONST : 0)
7426 | (TYPE_RESTRICT (TREE_TYPE (parm)) ? TYPE_QUAL_RESTRICT : 0)
7427 | (TYPE_VOLATILE (TREE_TYPE (parm)) ? TYPE_QUAL_VOLATILE : 0), parm);
7429 objc_parmlist = chainon (objc_parmlist, parm);
7432 /* Retrieve the formal parameter list constructed via preceding calls to
7433 objc_push_parm(). */
7437 objc_get_parm_info (int have_ellipsis ATTRIBUTE_UNUSED)
7439 static struct c_arg_info *
7440 objc_get_parm_info (int have_ellipsis)
7444 tree parm_info = objc_parmlist;
7445 objc_parmlist = NULL_TREE;
7449 tree parm_info = objc_parmlist;
7450 struct c_arg_info *arg_info;
7451 /* The C front-end requires an elaborate song and dance at
7454 declare_parm_level ();
7457 tree next = TREE_CHAIN (parm_info);
7459 TREE_CHAIN (parm_info) = NULL_TREE;
7460 parm_info = pushdecl (parm_info);
7461 finish_decl (parm_info, NULL_TREE, NULL_TREE);
7464 arg_info = get_parm_info (have_ellipsis);
7466 objc_parmlist = NULL_TREE;
7471 /* Synthesize the formal parameters 'id self' and 'SEL _cmd' needed for ObjC
7472 method definitions. In the case of instance methods, we can be more
7473 specific as to the type of 'self'. */
7476 synth_self_and_ucmd_args (void)
7480 if (objc_method_context
7481 && TREE_CODE (objc_method_context) == INSTANCE_METHOD_DECL)
7482 self_type = objc_instance_type;
7484 /* Really a `struct objc_class *'. However, we allow people to
7485 assign to self, which changes its type midstream. */
7486 self_type = objc_object_type;
7489 objc_push_parm (build_decl (PARM_DECL, self_id, self_type));
7492 objc_push_parm (build_decl (PARM_DECL, ucmd_id, objc_selector_type));
7495 /* Transform an Objective-C method definition into a static C function
7496 definition, synthesizing the first two arguments, "self" and "_cmd",
7500 start_method_def (tree method)
7506 struct c_arg_info *parm_info;
7508 int have_ellipsis = 0;
7510 /* Required to implement _msgSuper. */
7511 objc_method_context = method;
7512 UOBJC_SUPER_decl = NULL_TREE;
7514 /* Generate prototype declarations for arguments..."new-style". */
7515 synth_self_and_ucmd_args ();
7517 /* Generate argument declarations if a keyword_decl. */
7518 parmlist = METHOD_SEL_ARGS (method);
7521 tree type = TREE_VALUE (TREE_TYPE (parmlist)), parm;
7523 parm = build_decl (PARM_DECL, KEYWORD_ARG_NAME (parmlist), type);
7524 objc_push_parm (parm);
7525 parmlist = TREE_CHAIN (parmlist);
7528 if (METHOD_ADD_ARGS (method))
7532 for (akey = TREE_CHAIN (METHOD_ADD_ARGS (method));
7533 akey; akey = TREE_CHAIN (akey))
7535 objc_push_parm (TREE_VALUE (akey));
7538 if (TREE_OVERFLOW (METHOD_ADD_ARGS (method)))
7542 parm_info = objc_get_parm_info (have_ellipsis);
7544 really_start_method (objc_method_context, parm_info);
7548 warn_with_method (const char *message, int mtype, tree method)
7550 /* Add a readable method name to the warning. */
7551 warning ("%J%s %<%c%s%>", method,
7552 message, mtype, gen_method_decl (method));
7555 /* Return 1 if TYPE1 is equivalent to TYPE2
7556 for purposes of method overloading. */
7559 objc_types_are_equivalent (tree type1, tree type2)
7564 /* Strip away indirections. */
7565 while ((TREE_CODE (type1) == ARRAY_TYPE || TREE_CODE (type1) == POINTER_TYPE)
7566 && (TREE_CODE (type1) == TREE_CODE (type2)))
7567 type1 = TREE_TYPE (type1), type2 = TREE_TYPE (type2);
7568 if (TYPE_MAIN_VARIANT (type1) != TYPE_MAIN_VARIANT (type2))
7571 type1 = (TYPE_HAS_OBJC_INFO (type1)
7572 ? TYPE_OBJC_PROTOCOL_LIST (type1)
7574 type2 = (TYPE_HAS_OBJC_INFO (type2)
7575 ? TYPE_OBJC_PROTOCOL_LIST (type2)
7578 if (list_length (type1) == list_length (type2))
7580 for (; type2; type2 = TREE_CHAIN (type2))
7581 if (!lookup_protocol_in_reflist (type1, TREE_VALUE (type2)))
7588 /* Return 1 if PROTO1 is equivalent to PROTO2
7589 for purposes of method overloading. */
7592 comp_proto_with_proto (tree proto1, tree proto2)
7596 /* The following test is needed in case there are hashing
7598 if (METHOD_SEL_NAME (proto1) != METHOD_SEL_NAME (proto2))
7601 /* Compare return types. */
7602 type1 = TREE_VALUE (TREE_TYPE (proto1));
7603 type2 = TREE_VALUE (TREE_TYPE (proto2));
7605 if (!objc_types_are_equivalent (type1, type2))
7608 /* Compare argument types. */
7609 for (type1 = get_arg_type_list (proto1, METHOD_REF, 0),
7610 type2 = get_arg_type_list (proto2, METHOD_REF, 0);
7612 type1 = TREE_CHAIN (type1), type2 = TREE_CHAIN (type2))
7614 if (!objc_types_are_equivalent (TREE_VALUE (type1), TREE_VALUE (type2)))
7618 return (!type1 && !type2);
7621 /* Fold an OBJ_TYPE_REF expression for ObjC method dispatches, where
7622 this occurs. ObjC method dispatches are _not_ like C++ virtual
7623 member function dispatches, and we account for the difference here. */
7626 objc_fold_obj_type_ref (tree ref, tree known_type)
7628 objc_fold_obj_type_ref (tree ref ATTRIBUTE_UNUSED,
7629 tree known_type ATTRIBUTE_UNUSED)
7633 tree v = BINFO_VIRTUALS (TYPE_BINFO (known_type));
7635 /* If the receiver does not have virtual member functions, there
7636 is nothing we can (or need to) do here. */
7640 /* Let C++ handle C++ virtual functions. */
7641 return cp_fold_obj_type_ref (ref, known_type);
7643 /* For plain ObjC, we currently do not need to do anything. */
7649 objc_start_function (tree name, tree type, tree attrs,
7653 struct c_arg_info *params
7657 tree fndecl = build_decl (FUNCTION_DECL, name, type);
7660 DECL_ARGUMENTS (fndecl) = params;
7661 DECL_INITIAL (fndecl) = error_mark_node;
7662 DECL_EXTERNAL (fndecl) = 0;
7663 TREE_STATIC (fndecl) = 1;
7664 retrofit_lang_decl (fndecl);
7665 cplus_decl_attributes (&fndecl, attrs, 0);
7666 start_preparsed_function (fndecl, attrs, /*flags=*/SF_DEFAULT);
7668 decl_attributes (&fndecl, attrs, 0);
7669 announce_function (fndecl);
7670 DECL_INITIAL (fndecl) = error_mark_node;
7671 DECL_EXTERNAL (fndecl) = 0;
7672 TREE_STATIC (fndecl) = 1;
7673 current_function_decl = pushdecl (fndecl);
7675 declare_parm_level ();
7676 DECL_RESULT (current_function_decl)
7677 = build_decl (RESULT_DECL, NULL_TREE,
7678 TREE_TYPE (TREE_TYPE (current_function_decl)));
7679 DECL_ARTIFICIAL (DECL_RESULT (current_function_decl)) = 1;
7680 DECL_IGNORED_P (DECL_RESULT (current_function_decl)) = 1;
7681 start_fname_decls ();
7682 store_parm_decls_from (params);
7685 TREE_USED (current_function_decl) = 1;
7688 /* - Generate an identifier for the function. the format is "_n_cls",
7689 where 1 <= n <= nMethods, and cls is the name the implementation we
7691 - Install the return type from the method declaration.
7692 - If we have a prototype, check for type consistency. */
7695 really_start_method (tree method,
7699 struct c_arg_info *parmlist
7703 tree ret_type, meth_type;
7705 const char *sel_name, *class_name, *cat_name;
7708 /* Synth the storage class & assemble the return type. */
7709 ret_type = TREE_VALUE (TREE_TYPE (method));
7711 sel_name = IDENTIFIER_POINTER (METHOD_SEL_NAME (method));
7712 class_name = IDENTIFIER_POINTER (CLASS_NAME (objc_implementation_context));
7713 cat_name = ((TREE_CODE (objc_implementation_context)
7714 == CLASS_IMPLEMENTATION_TYPE)
7716 : IDENTIFIER_POINTER (CLASS_SUPER_NAME (objc_implementation_context)));
7719 /* Make sure this is big enough for any plausible method label. */
7720 buf = (char *) alloca (50 + strlen (sel_name) + strlen (class_name)
7721 + (cat_name ? strlen (cat_name) : 0));
7723 OBJC_GEN_METHOD_LABEL (buf, TREE_CODE (method) == INSTANCE_METHOD_DECL,
7724 class_name, cat_name, sel_name, method_slot);
7726 method_id = get_identifier (buf);
7729 /* Objective-C methods cannot be overloaded, so we don't need
7730 the type encoding appended. It looks bad anyway... */
7731 push_lang_context (lang_name_c);
7735 = build_function_type (ret_type,
7736 get_arg_type_list (method, METHOD_DEF, 0));
7737 objc_start_function (method_id, meth_type, NULL_TREE, parmlist);
7739 /* Set self_decl from the first argument. */
7740 self_decl = DECL_ARGUMENTS (current_function_decl);
7742 /* Suppress unused warnings. */
7743 TREE_USED (self_decl) = 1;
7744 TREE_USED (TREE_CHAIN (self_decl)) = 1;
7746 pop_lang_context ();
7749 METHOD_DEFINITION (method) = current_function_decl;
7751 /* Check consistency...start_function, pushdecl, duplicate_decls. */
7753 if (implementation_template != objc_implementation_context)
7756 = lookup_method_static (implementation_template,
7757 METHOD_SEL_NAME (method),
7758 TREE_CODE (method) == CLASS_METHOD_DECL);
7762 if (!comp_proto_with_proto (method, proto))
7764 char type = (TREE_CODE (method) == INSTANCE_METHOD_DECL ? '-' : '+');
7766 warn_with_method ("conflicting types for", type, method);
7767 warn_with_method ("previous declaration of", type, proto);
7772 /* We have a method @implementation even though we did not
7773 see a corresponding @interface declaration (which is allowed
7774 by Objective-C rules). Go ahead and place the method in
7775 the @interface anyway, so that message dispatch lookups
7777 tree interface = implementation_template;
7779 if (TREE_CODE (objc_implementation_context)
7780 == CATEGORY_IMPLEMENTATION_TYPE)
7781 interface = lookup_category
7783 CLASS_SUPER_NAME (objc_implementation_context));
7786 objc_add_method (interface, copy_node (method),
7787 TREE_CODE (method) == CLASS_METHOD_DECL);
7792 static void *UOBJC_SUPER_scope = 0;
7794 /* _n_Method (id self, SEL sel, ...)
7796 struct objc_super _S;
7797 _msgSuper ((_S.self = self, _S.class = _cls, &_S), ...);
7801 get_super_receiver (void)
7803 if (objc_method_context)
7805 tree super_expr, super_expr_list;
7807 if (!UOBJC_SUPER_decl)
7809 UOBJC_SUPER_decl = build_decl (VAR_DECL, get_identifier (TAG_SUPER),
7810 objc_super_template);
7811 /* This prevents `unused variable' warnings when compiling with -Wall. */
7812 TREE_USED (UOBJC_SUPER_decl) = 1;
7813 lang_hooks.decls.pushdecl (UOBJC_SUPER_decl);
7814 finish_decl (UOBJC_SUPER_decl, NULL_TREE, NULL_TREE);
7815 UOBJC_SUPER_scope = objc_get_current_scope ();
7818 /* Set receiver to self. */
7819 super_expr = build_component_ref (UOBJC_SUPER_decl, self_id);
7820 super_expr = build_modify_expr (super_expr, NOP_EXPR, self_decl);
7821 super_expr_list = super_expr;
7823 /* Set class to begin searching. */
7824 super_expr = build_component_ref (UOBJC_SUPER_decl,
7825 get_identifier ("super_class"));
7827 if (TREE_CODE (objc_implementation_context) == CLASS_IMPLEMENTATION_TYPE)
7829 /* [_cls, __cls]Super are "pre-built" in
7830 synth_forward_declarations. */
7832 super_expr = build_modify_expr (super_expr, NOP_EXPR,
7833 ((TREE_CODE (objc_method_context)
7834 == INSTANCE_METHOD_DECL)
7836 : uucls_super_ref));
7840 /* We have a category. */
7842 tree super_name = CLASS_SUPER_NAME (implementation_template);
7845 /* Barf if super used in a category of Object. */
7848 error ("no super class declared in interface for %qs",
7849 IDENTIFIER_POINTER (CLASS_NAME (implementation_template)));
7850 return error_mark_node;
7853 if (flag_next_runtime && !flag_zero_link)
7855 super_class = objc_get_class_reference (super_name);
7856 if (TREE_CODE (objc_method_context) == CLASS_METHOD_DECL)
7857 /* If we are in a class method, we must retrieve the
7858 _metaclass_ for the current class, pointed at by
7859 the class's "isa" pointer. The following assumes that
7860 "isa" is the first ivar in a class (which it must be). */
7862 = build_indirect_ref
7863 (build_c_cast (build_pointer_type (objc_class_type),
7864 super_class), "unary *");
7868 add_class_reference (super_name);
7869 super_class = (TREE_CODE (objc_method_context) == INSTANCE_METHOD_DECL
7870 ? objc_get_class_decl : objc_get_meta_class_decl);
7871 assemble_external (super_class);
7873 = build_function_call
7877 my_build_string (IDENTIFIER_LENGTH (super_name) + 1,
7878 IDENTIFIER_POINTER (super_name))));
7882 = build_modify_expr (super_expr, NOP_EXPR,
7883 build_c_cast (TREE_TYPE (super_expr),
7887 super_expr_list = build_compound_expr (super_expr_list, super_expr);
7889 super_expr = build_unary_op (ADDR_EXPR, UOBJC_SUPER_decl, 0);
7890 super_expr_list = build_compound_expr (super_expr_list, super_expr);
7892 return super_expr_list;
7896 error ("[super ...] must appear in a method context");
7897 return error_mark_node;
7901 /* When exiting a scope, sever links to a 'super' declaration (if any)
7902 therein contained. */
7905 objc_clear_super_receiver (void)
7907 if (objc_method_context
7908 && UOBJC_SUPER_scope == objc_get_current_scope ()) {
7909 UOBJC_SUPER_decl = 0;
7910 UOBJC_SUPER_scope = 0;
7915 objc_finish_method_definition (tree fndecl)
7917 /* We cannot validly inline ObjC methods, at least not without a language
7918 extension to declare that a method need not be dynamically
7919 dispatched, so suppress all thoughts of doing so. */
7920 DECL_INLINE (fndecl) = 0;
7921 DECL_UNINLINABLE (fndecl) = 1;
7924 /* The C++ front-end will have called finish_function() for us. */
7928 METHOD_ENCODING (objc_method_context)
7929 = encode_method_prototype (objc_method_context);
7931 /* Required to implement _msgSuper. This must be done AFTER finish_function,
7932 since the optimizer may find "may be used before set" errors. */
7933 objc_method_context = NULL_TREE;
7938 lang_report_error_function (tree decl)
7940 if (objc_method_context)
7942 fprintf (stderr, "In method %qs\n",
7943 IDENTIFIER_POINTER (METHOD_SEL_NAME (objc_method_context)));
7952 /* Given a tree DECL node, produce a printable description of it in the given
7953 buffer, overwriting the buffer. */
7956 gen_declaration (tree decl)
7962 gen_type_name_0 (TREE_TYPE (decl));
7964 if (DECL_NAME (decl))
7966 if (!POINTER_TYPE_P (TREE_TYPE (decl)))
7967 strcat (errbuf, " ");
7969 strcat (errbuf, IDENTIFIER_POINTER (DECL_NAME (decl)));
7972 if (DECL_INITIAL (decl)
7973 && TREE_CODE (DECL_INITIAL (decl)) == INTEGER_CST)
7974 sprintf (errbuf + strlen (errbuf), ": " HOST_WIDE_INT_PRINT_DEC,
7975 TREE_INT_CST_LOW (DECL_INITIAL (decl)));
7981 /* Given a tree TYPE node, produce a printable description of it in the given
7982 buffer, overwriting the buffer. */
7985 gen_type_name_0 (tree type)
7987 tree orig = type, proto;
7989 if (TYPE_P (type) && TYPE_NAME (type))
7990 type = TYPE_NAME (type);
7991 else if (POINTER_TYPE_P (type) || TREE_CODE (type) == ARRAY_TYPE)
7993 tree inner = TREE_TYPE (type);
7995 while (TREE_CODE (inner) == ARRAY_TYPE)
7996 inner = TREE_TYPE (inner);
7998 gen_type_name_0 (inner);
8000 if (!POINTER_TYPE_P (inner))
8001 strcat (errbuf, " ");
8003 if (POINTER_TYPE_P (type))
8004 strcat (errbuf, "*");
8006 while (type != inner)
8008 strcat (errbuf, "[");
8010 if (TYPE_DOMAIN (type))
8014 sprintf (sz, HOST_WIDE_INT_PRINT_DEC,
8016 (TYPE_MAX_VALUE (TYPE_DOMAIN (type))) + 1));
8017 strcat (errbuf, sz);
8020 strcat (errbuf, "]");
8021 type = TREE_TYPE (type);
8027 if (TREE_CODE (type) == TYPE_DECL && DECL_NAME (type))
8028 type = DECL_NAME (type);
8030 strcat (errbuf, IDENTIFIER_POINTER (type));
8032 /* For 'id' and 'Class', adopted protocols are stored in the pointee. */
8033 if (objc_is_id (orig))
8034 orig = TREE_TYPE (orig);
8036 proto = TYPE_HAS_OBJC_INFO (orig) ? TYPE_OBJC_PROTOCOL_LIST (orig) : NULL_TREE;
8040 strcat (errbuf, " <");
8044 IDENTIFIER_POINTER (PROTOCOL_NAME (TREE_VALUE (proto))));
8045 proto = TREE_CHAIN (proto);
8046 strcat (errbuf, proto ? ", " : ">");
8055 gen_type_name (tree type)
8059 return gen_type_name_0 (type);
8062 /* Given a method tree, put a printable description into the given
8063 buffer (overwriting) and return a pointer to the buffer. */
8066 gen_method_decl (tree method)
8070 strcpy (errbuf, "("); /* NB: Do _not_ call strcat() here. */
8071 gen_type_name_0 (TREE_VALUE (TREE_TYPE (method)));
8072 strcat (errbuf, ")");
8073 chain = METHOD_SEL_ARGS (method);
8077 /* We have a chain of keyword_decls. */
8080 if (KEYWORD_KEY_NAME (chain))
8081 strcat (errbuf, IDENTIFIER_POINTER (KEYWORD_KEY_NAME (chain)));
8083 strcat (errbuf, ":(");
8084 gen_type_name_0 (TREE_VALUE (TREE_TYPE (chain)));
8085 strcat (errbuf, ")");
8087 strcat (errbuf, IDENTIFIER_POINTER (KEYWORD_ARG_NAME (chain)));
8088 if ((chain = TREE_CHAIN (chain)))
8089 strcat (errbuf, " ");
8093 if (METHOD_ADD_ARGS (method))
8095 chain = TREE_CHAIN (METHOD_ADD_ARGS (method));
8097 /* Know we have a chain of parm_decls. */
8100 strcat (errbuf, ", ");
8101 gen_type_name_0 (TREE_TYPE (TREE_VALUE (chain)));
8102 chain = TREE_CHAIN (chain);
8105 if (TREE_OVERFLOW (METHOD_ADD_ARGS (method)))
8106 strcat (errbuf, ", ...");
8111 /* We have a unary selector. */
8112 strcat (errbuf, IDENTIFIER_POINTER (METHOD_SEL_NAME (method)));
8120 /* Dump an @interface declaration of the supplied class CHAIN to the
8121 supplied file FP. Used to implement the -gen-decls option (which
8122 prints out an @interface declaration of all classes compiled in
8123 this run); potentially useful for debugging the compiler too. */
8125 dump_interface (FILE *fp, tree chain)
8127 /* FIXME: A heap overflow here whenever a method (or ivar)
8128 declaration is so long that it doesn't fit in the buffer. The
8129 code and all the related functions should be rewritten to avoid
8130 using fixed size buffers. */
8131 const char *my_name = IDENTIFIER_POINTER (CLASS_NAME (chain));
8132 tree ivar_decls = CLASS_RAW_IVARS (chain);
8133 tree nst_methods = CLASS_NST_METHODS (chain);
8134 tree cls_methods = CLASS_CLS_METHODS (chain);
8136 fprintf (fp, "\n@interface %s", my_name);
8138 /* CLASS_SUPER_NAME is used to store the superclass name for
8139 classes, and the category name for categories. */
8140 if (CLASS_SUPER_NAME (chain))
8142 const char *name = IDENTIFIER_POINTER (CLASS_SUPER_NAME (chain));
8144 if (TREE_CODE (chain) == CATEGORY_IMPLEMENTATION_TYPE
8145 || TREE_CODE (chain) == CATEGORY_INTERFACE_TYPE)
8147 fprintf (fp, " (%s)\n", name);
8151 fprintf (fp, " : %s\n", name);
8157 /* FIXME - the following doesn't seem to work at the moment. */
8160 fprintf (fp, "{\n");
8163 fprintf (fp, "\t%s;\n", gen_declaration (ivar_decls));
8164 ivar_decls = TREE_CHAIN (ivar_decls);
8167 fprintf (fp, "}\n");
8172 fprintf (fp, "- %s;\n", gen_method_decl (nst_methods));
8173 nst_methods = TREE_CHAIN (nst_methods);
8178 fprintf (fp, "+ %s;\n", gen_method_decl (cls_methods));
8179 cls_methods = TREE_CHAIN (cls_methods);
8182 fprintf (fp, "@end\n");
8185 /* Demangle function for Objective-C */
8187 objc_demangle (const char *mangled)
8189 char *demangled, *cp;
8191 if (mangled[0] == '_' &&
8192 (mangled[1] == 'i' || mangled[1] == 'c') &&
8195 cp = demangled = xmalloc(strlen(mangled) + 2);
8196 if (mangled[1] == 'i')
8197 *cp++ = '-'; /* for instance method */
8199 *cp++ = '+'; /* for class method */
8200 *cp++ = '['; /* opening left brace */
8201 strcpy(cp, mangled+3); /* tack on the rest of the mangled name */
8202 while (*cp && *cp == '_')
8203 cp++; /* skip any initial underbars in class name */
8204 cp = strchr(cp, '_'); /* find first non-initial underbar */
8207 free(demangled); /* not mangled name */
8210 if (cp[1] == '_') /* easy case: no category name */
8212 *cp++ = ' '; /* replace two '_' with one ' ' */
8213 strcpy(cp, mangled + (cp - demangled) + 2);
8217 *cp++ = '('; /* less easy case: category name */
8218 cp = strchr(cp, '_');
8221 free(demangled); /* not mangled name */
8225 *cp++ = ' '; /* overwriting 1st char of method name... */
8226 strcpy(cp, mangled + (cp - demangled)); /* get it back */
8228 while (*cp && *cp == '_')
8229 cp++; /* skip any initial underbars in method name */
8232 *cp = ':'; /* replace remaining '_' with ':' */
8233 *cp++ = ']'; /* closing right brace */
8234 *cp++ = 0; /* string terminator */
8238 return mangled; /* not an objc mangled name */
8242 objc_printable_name (tree decl, int kind ATTRIBUTE_UNUSED)
8244 return objc_demangle (IDENTIFIER_POINTER (DECL_NAME (decl)));
8250 gcc_obstack_init (&util_obstack);
8251 util_firstobj = (char *) obstack_finish (&util_obstack);
8253 errbuf = (char *) xmalloc (1024 * 10);
8255 synth_module_prologue ();
8261 struct imp_entry *impent;
8263 /* The internally generated initializers appear to have missing braces.
8264 Don't warn about this. */
8265 int save_warn_missing_braces = warn_missing_braces;
8266 warn_missing_braces = 0;
8268 /* A missing @end may not be detected by the parser. */
8269 if (objc_implementation_context)
8271 warning ("%<@end%> missing in implementation context");
8272 finish_class (objc_implementation_context);
8273 objc_ivar_chain = NULL_TREE;
8274 objc_implementation_context = NULL_TREE;
8277 /* Process the static instances here because initialization of objc_symtab
8279 if (objc_static_instances)
8280 generate_static_references ();
8282 if (imp_list || class_names_chain
8283 || meth_var_names_chain || meth_var_types_chain || sel_ref_chain)
8284 generate_objc_symtab_decl ();
8286 for (impent = imp_list; impent; impent = impent->next)
8288 objc_implementation_context = impent->imp_context;
8289 implementation_template = impent->imp_template;
8291 UOBJC_CLASS_decl = impent->class_decl;
8292 UOBJC_METACLASS_decl = impent->meta_decl;
8294 /* Dump the @interface of each class as we compile it, if the
8295 -gen-decls option is in use. TODO: Dump the classes in the
8296 order they were found, rather than in reverse order as we
8298 if (flag_gen_declaration)
8300 dump_interface (gen_declaration_file, objc_implementation_context);
8303 if (TREE_CODE (objc_implementation_context) == CLASS_IMPLEMENTATION_TYPE)
8305 /* all of the following reference the string pool... */
8306 generate_ivar_lists ();
8307 generate_dispatch_tables ();
8308 generate_shared_structures ();
8312 generate_dispatch_tables ();
8313 generate_category (objc_implementation_context);
8317 /* If we are using an array of selectors, we must always
8318 finish up the array decl even if no selectors were used. */
8319 if (! flag_next_runtime || sel_ref_chain)
8320 build_selector_translation_table ();
8323 generate_protocols ();
8325 if (flag_replace_objc_classes && imp_list)
8326 generate_objc_image_info ();
8328 /* Arrange for ObjC data structures to be initialized at run time. */
8329 if (objc_implementation_context || class_names_chain || objc_static_instances
8330 || meth_var_names_chain || meth_var_types_chain || sel_ref_chain)
8332 build_module_descriptor ();
8334 if (!flag_next_runtime)
8335 build_module_initializer_routine ();
8338 /* Dump the class references. This forces the appropriate classes
8339 to be linked into the executable image, preserving unix archive
8340 semantics. This can be removed when we move to a more dynamically
8341 linked environment. */
8343 for (chain = cls_ref_chain; chain; chain = TREE_CHAIN (chain))
8345 handle_class_ref (chain);
8346 if (TREE_PURPOSE (chain))
8347 generate_classref_translation_entry (chain);
8350 for (impent = imp_list; impent; impent = impent->next)
8351 handle_impent (impent);
8353 /* Dump the string table last. */
8355 generate_strings ();
8362 /* Run through the selector hash tables and print a warning for any
8363 selector which has multiple methods. */
8365 for (slot = 0; slot < SIZEHASHTABLE; slot++)
8367 for (hsh = cls_method_hash_list[slot]; hsh; hsh = hsh->next)
8368 check_duplicates (hsh, 0, 1);
8369 for (hsh = nst_method_hash_list[slot]; hsh; hsh = hsh->next)
8370 check_duplicates (hsh, 0, 1);
8374 warn_missing_braces = save_warn_missing_braces;
8377 /* Subroutines of finish_objc. */
8380 generate_classref_translation_entry (tree chain)
8382 tree expr, decl, type;
8384 decl = TREE_PURPOSE (chain);
8385 type = TREE_TYPE (decl);
8387 expr = add_objc_string (TREE_VALUE (chain), class_names);
8388 expr = convert (type, expr); /* cast! */
8390 /* The decl that is the one that we
8391 forward declared in build_class_reference. */
8392 finish_var_decl (decl, expr);
8397 handle_class_ref (tree chain)
8399 const char *name = IDENTIFIER_POINTER (TREE_VALUE (chain));
8400 char *string = (char *) alloca (strlen (name) + 30);
8404 sprintf (string, "%sobjc_class_name_%s",
8405 (flag_next_runtime ? "." : "__"), name);
8407 #ifdef ASM_DECLARE_UNRESOLVED_REFERENCE
8408 if (flag_next_runtime)
8410 ASM_DECLARE_UNRESOLVED_REFERENCE (asm_out_file, string);
8415 /* Make a decl for this name, so we can use its address in a tree. */
8416 decl = build_decl (VAR_DECL, get_identifier (string), char_type_node);
8417 DECL_EXTERNAL (decl) = 1;
8418 TREE_PUBLIC (decl) = 1;
8421 rest_of_decl_compilation (decl, 0, 0);
8423 /* Make a decl for the address. */
8424 sprintf (string, "%sobjc_class_ref_%s",
8425 (flag_next_runtime ? "." : "__"), name);
8426 exp = build1 (ADDR_EXPR, string_type_node, decl);
8427 decl = build_decl (VAR_DECL, get_identifier (string), string_type_node);
8428 DECL_INITIAL (decl) = exp;
8429 TREE_STATIC (decl) = 1;
8430 TREE_USED (decl) = 1;
8433 rest_of_decl_compilation (decl, 0, 0);
8437 handle_impent (struct imp_entry *impent)
8441 objc_implementation_context = impent->imp_context;
8442 implementation_template = impent->imp_template;
8444 if (TREE_CODE (impent->imp_context) == CLASS_IMPLEMENTATION_TYPE)
8446 const char *const class_name =
8447 IDENTIFIER_POINTER (CLASS_NAME (impent->imp_context));
8449 string = (char *) alloca (strlen (class_name) + 30);
8451 sprintf (string, "%sobjc_class_name_%s",
8452 (flag_next_runtime ? "." : "__"), class_name);
8454 else if (TREE_CODE (impent->imp_context) == CATEGORY_IMPLEMENTATION_TYPE)
8456 const char *const class_name =
8457 IDENTIFIER_POINTER (CLASS_NAME (impent->imp_context));
8458 const char *const class_super_name =
8459 IDENTIFIER_POINTER (CLASS_SUPER_NAME (impent->imp_context));
8461 string = (char *) alloca (strlen (class_name)
8462 + strlen (class_super_name) + 30);
8464 /* Do the same for categories. Even though no references to
8465 these symbols are generated automatically by the compiler, it
8466 gives you a handle to pull them into an archive by hand. */
8467 sprintf (string, "*%sobjc_category_name_%s_%s",
8468 (flag_next_runtime ? "." : "__"), class_name, class_super_name);
8473 #ifdef ASM_DECLARE_CLASS_REFERENCE
8474 if (flag_next_runtime)
8476 ASM_DECLARE_CLASS_REFERENCE (asm_out_file, string);
8484 init = build_int_cst (c_common_type_for_size (BITS_PER_WORD, 1), 0);
8485 decl = build_decl (VAR_DECL, get_identifier (string), TREE_TYPE (init));
8486 TREE_PUBLIC (decl) = 1;
8487 TREE_READONLY (decl) = 1;
8488 TREE_USED (decl) = 1;
8489 TREE_CONSTANT (decl) = 1;
8490 DECL_CONTEXT (decl) = 0;
8491 DECL_ARTIFICIAL (decl) = 1;
8492 DECL_INITIAL (decl) = init;
8493 assemble_variable (decl, 1, 0, 0);
8497 /* The Fix-and-Continue functionality available in Mac OS X 10.3 and
8498 later requires that ObjC translation units participating in F&C be
8499 specially marked. The following routine accomplishes this. */
8501 /* static int _OBJC_IMAGE_INFO[2] = { 0, 1 }; */
8504 generate_objc_image_info (void)
8506 tree decl, initlist;
8508 decl = start_var_decl (build_array_type
8510 build_index_type (build_int_cst (NULL_TREE, 2 - 1))),
8511 "_OBJC_IMAGE_INFO");
8513 initlist = build_tree_list (NULL_TREE, build_int_cst (NULL_TREE, 0));
8514 initlist = tree_cons (NULL_TREE, build_int_cst (NULL_TREE, 1), initlist);
8515 initlist = objc_build_constructor (TREE_TYPE (decl), nreverse (initlist));
8517 finish_var_decl (decl, initlist);
8520 /* Look up ID as an instance variable. OTHER contains the result of
8521 the C or C++ lookup, which we may want to use instead. */
8524 objc_lookup_ivar (tree other, tree id)
8528 /* If we are not inside of an ObjC method, ivar lookup makes no sense. */
8529 if (!objc_method_context)
8532 if (!strcmp (IDENTIFIER_POINTER (id), "super"))
8533 /* We have a message to super. */
8534 return get_super_receiver ();
8536 /* In a class method, look up an instance variable only as a last
8538 if (TREE_CODE (objc_method_context) == CLASS_METHOD_DECL
8539 && other && other != error_mark_node)
8542 /* Look up the ivar, but do not use it if it is not accessible. */
8543 ivar = is_ivar (objc_ivar_chain, id);
8545 if (!ivar || is_private (ivar))
8548 /* In an instance method, a local variable (or parameter) may hide the
8549 instance variable. */
8550 if (TREE_CODE (objc_method_context) == INSTANCE_METHOD_DECL
8551 && other && other != error_mark_node && !DECL_FILE_SCOPE_P (other))
8553 warning ("local declaration of %qs hides instance variable",
8554 IDENTIFIER_POINTER (id));
8559 /* At this point, we are either in an instance method with no obscuring
8560 local definitions, or in a class method with no alternate definitions
8562 return build_ivar_reference (id);
8565 #include "gt-objc-objc-act.h"