1 /* Implement classes and message passing for Objective C.
2 Copyright (C) 1992, 1993, 1994, 1995, 1997, 1998, 1999, 2000, 2001,
3 2002, 2003, 2004, 2005, 2007, 2008, 2009, 2010
4 Free Software Foundation, Inc.
5 Contributed by Steve Naroff.
7 This file is part of GCC.
9 GCC is free software; you can redistribute it and/or modify
10 it under the terms of the GNU General Public License as published by
11 the Free Software Foundation; either version 3, or (at your option)
14 GCC is distributed in the hope that it will be useful,
15 but WITHOUT ANY WARRANTY; without even the implied warranty of
16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 GNU General Public License for more details.
19 You should have received a copy of the GNU General Public License
20 along with GCC; see the file COPYING3. If not see
21 <http://www.gnu.org/licenses/>. */
25 #include "coretypes.h"
36 #include "c-family/c-common.h"
37 #include "c-family/c-pragma.h"
39 #include "langhooks.h"
48 #include "diagnostic-core.h"
51 #include "tree-iterator.h"
53 #include "langhooks-def.h"
55 /* For default_tree_printer (). */
56 #include "tree-pretty-print.h"
58 /* For enum gimplify_status */
61 #define OBJC_VOID_AT_END void_list_node
63 static unsigned int should_call_super_dealloc = 0;
65 /* When building Objective-C++, we need in_late_binary_op. */
67 bool in_late_binary_op = false;
70 /* When building Objective-C++, we are not linking against the C front-end
71 and so need to replicate the C tree-construction functions in some way. */
73 #define OBJCP_REMAP_FUNCTIONS
74 #include "objcp-decl.h"
77 /* This is the default way of generating a method name. */
78 /* I am not sure it is really correct.
79 Perhaps there's a danger that it will make name conflicts
80 if method names contain underscores. -- rms. */
81 #ifndef OBJC_GEN_METHOD_LABEL
82 #define OBJC_GEN_METHOD_LABEL(BUF, IS_INST, CLASS_NAME, CAT_NAME, SEL_NAME, NUM) \
85 sprintf ((BUF), "_%s_%s_%s_%s", \
86 ((IS_INST) ? "i" : "c"), \
88 ((CAT_NAME)? (CAT_NAME) : ""), \
90 for (temp = (BUF); *temp; temp++) \
91 if (*temp == ':') *temp = '_'; \
95 /* These need specifying. */
96 #ifndef OBJC_FORWARDING_STACK_OFFSET
97 #define OBJC_FORWARDING_STACK_OFFSET 0
100 #ifndef OBJC_FORWARDING_MIN_OFFSET
101 #define OBJC_FORWARDING_MIN_OFFSET 0
104 /* Set up for use of obstacks. */
108 /* This obstack is used to accumulate the encoding of a data type. */
109 static struct obstack util_obstack;
111 /* This points to the beginning of obstack contents, so we can free
112 the whole contents. */
115 /* The version identifies which language generation and runtime
116 the module (file) was compiled for, and is recorded in the
117 module descriptor. */
119 #define OBJC_VERSION (flag_next_runtime ? 6 : 8)
120 #define PROTOCOL_VERSION 2
122 /* (Decide if these can ever be validly changed.) */
123 #define OBJC_ENCODE_INLINE_DEFS 0
124 #define OBJC_ENCODE_DONT_INLINE_DEFS 1
126 /*** Private Interface (procedures) ***/
128 /* Used by compile_file. */
130 static void init_objc (void);
131 static void finish_objc (void);
133 /* Code generation. */
135 static tree objc_build_constructor (tree, VEC(constructor_elt,gc) *);
136 static tree build_objc_method_call (location_t, int, tree, tree, tree, tree);
137 static tree get_proto_encoding (tree);
138 static tree lookup_interface (tree);
139 static tree objc_add_static_instance (tree, tree);
141 static tree start_class (enum tree_code, tree, tree, tree);
142 static tree continue_class (tree);
143 static void finish_class (tree);
144 static void start_method_def (tree);
146 static void objc_start_function (tree, tree, tree, tree);
148 static void objc_start_function (tree, tree, tree, struct c_arg_info *);
150 static tree start_protocol (enum tree_code, tree, tree);
151 static tree build_method_decl (enum tree_code, tree, tree, tree, bool);
152 static tree objc_add_method (tree, tree, int, bool);
153 static tree add_instance_variable (tree, objc_ivar_visibility_kind, tree);
154 static tree build_ivar_reference (tree);
155 static tree is_ivar (tree, tree);
157 static void build_objc_exception_stuff (void);
158 static void build_next_objc_exception_stuff (void);
160 /* We only need the following for ObjC; ObjC++ will use C++'s definition
161 of DERIVED_FROM_P. */
163 static bool objc_derived_from_p (tree, tree);
164 #define DERIVED_FROM_P(PARENT, CHILD) objc_derived_from_p (PARENT, CHILD)
168 static void objc_gen_one_property_datum (tree, tree, tree, bool*);
169 static void objc_gen_property_data (tree, tree);
170 static void objc_synthesize_getter (tree, tree, tree);
171 static void objc_process_getter_setter (tree, tree, bool);
172 static void objc_synthesize_setter (tree, tree, tree);
173 static char *objc_build_property_ivar_name (tree);
174 static char *objc_build_property_setter_name (tree, bool);
175 static int match_proto_with_proto (tree, tree, int);
176 static tree lookup_property (tree, tree);
177 static tree lookup_property_in_list (tree, tree);
178 static tree lookup_property_in_protocol_list (tree, tree);
179 static tree objc_setter_func_call (tree, tree, tree);
180 static tree build_property_reference (tree, tree);
181 static tree is_property (tree, tree);
182 /* Set on a CALL_EXPR if it is for call to a getter function represented by an
183 objective-c property declaration. */
184 #define CALL_EXPR_OBJC_PROPERTY_GETTER(NODE) \
185 (CALL_EXPR_CHECK(NODE)->base.deprecated_flag)
187 static void objc_xref_basetypes (tree, tree);
189 static void build_class_template (void);
190 static void build_selector_template (void);
191 static void build_category_template (void);
192 static void build_super_template (void);
193 static tree build_protocol_initializer (tree, tree, tree, tree, tree);
194 static tree get_class_ivars (tree, bool);
195 static tree generate_protocol_list (tree);
196 static void build_protocol_reference (tree);
198 static void build_fast_enumeration_state_template (void);
201 static void objc_generate_cxx_cdtors (void);
205 static void objc_decl_method_attributes (tree*, tree, int);
206 static tree build_keyword_selector (tree);
207 static const char *synth_id_with_class_suffix (const char *, tree);
209 /* Hash tables to manage the global pool of method prototypes. */
211 hash *nst_method_hash_list = 0;
212 hash *cls_method_hash_list = 0;
214 /* Hash tables to manage the global pool of class names. */
216 hash *cls_name_hash_list = 0;
217 hash *als_name_hash_list = 0;
219 static void hash_class_name_enter (hash *, tree, tree);
220 static hash hash_class_name_lookup (hash *, tree);
222 static hash hash_lookup (hash *, tree);
223 static tree lookup_method (tree, tree);
224 static tree lookup_method_static (tree, tree, int);
226 static tree add_class (tree, tree);
227 static void add_category (tree, tree);
228 static inline tree lookup_category (tree, tree);
232 class_names, /* class, category, protocol, module names */
233 meth_var_names, /* method and variable names */
234 meth_var_types /* method and variable type descriptors */
237 static tree add_objc_string (tree, enum string_section);
238 static void build_selector_table_decl (void);
240 /* Protocol additions. */
242 static tree lookup_protocol (tree);
243 static tree lookup_and_install_protocols (tree);
247 static void encode_type_qualifiers (tree);
248 static void encode_type (tree, int, int);
249 static void encode_field_decl (tree, int, int);
252 static void really_start_method (tree, tree);
254 static void really_start_method (tree, struct c_arg_info *);
256 static int comp_proto_with_proto (tree, tree, int);
257 static tree get_arg_type_list (tree, int, int);
258 static tree objc_decay_parm_type (tree);
259 static void objc_push_parm (tree);
261 static tree objc_get_parm_info (int);
263 static struct c_arg_info *objc_get_parm_info (int);
266 /* Utilities for debugging and error diagnostics. */
268 static char *gen_type_name (tree);
269 static char *gen_type_name_0 (tree);
270 static char *gen_method_decl (tree);
271 static char *gen_declaration (tree);
273 /* Everything else. */
275 static tree create_field_decl (tree, const char *);
276 static void add_class_reference (tree);
277 static void build_protocol_template (void);
278 static tree encode_method_prototype (tree);
279 static void generate_classref_translation_entry (tree);
280 static void handle_class_ref (tree);
281 static void generate_struct_by_value_array (void)
283 static void mark_referenced_methods (void);
284 static void generate_objc_image_info (void);
285 static bool objc_type_valid_for_messaging (tree typ);
287 /*** Private Interface (data) ***/
289 /* Reserved tag definitions. */
291 #define OBJECT_TYPEDEF_NAME "id"
292 #define CLASS_TYPEDEF_NAME "Class"
294 #define TAG_OBJECT "objc_object"
295 #define TAG_CLASS "objc_class"
296 #define TAG_SUPER "objc_super"
297 #define TAG_SELECTOR "objc_selector"
299 #define UTAG_CLASS "_objc_class"
300 #define UTAG_IVAR "_objc_ivar"
301 #define UTAG_IVAR_LIST "_objc_ivar_list"
302 #define UTAG_METHOD "_objc_method"
303 #define UTAG_METHOD_LIST "_objc_method_list"
304 #define UTAG_CATEGORY "_objc_category"
305 #define UTAG_MODULE "_objc_module"
306 #define UTAG_SYMTAB "_objc_symtab"
307 #define UTAG_SUPER "_objc_super"
308 #define UTAG_SELECTOR "_objc_selector"
310 #define UTAG_PROTOCOL "_objc_protocol"
311 #define UTAG_METHOD_PROTOTYPE "_objc_method_prototype"
312 #define UTAG_METHOD_PROTOTYPE_LIST "_objc__method_prototype_list"
314 /* Note that the string object global name is only needed for the
316 #define STRING_OBJECT_GLOBAL_FORMAT "_%sClassReference"
318 #define PROTOCOL_OBJECT_CLASS_NAME "Protocol"
320 #define TAG_ENUMERATION_MUTATION "objc_enumerationMutation"
321 #define TAG_FAST_ENUMERATION_STATE "__objcFastEnumerationState"
323 static const char *TAG_GETCLASS;
324 static const char *TAG_GETMETACLASS;
325 static const char *TAG_MSGSEND;
326 static const char *TAG_MSGSENDSUPER;
327 /* The NeXT Objective-C messenger may have two extra entry points, for use
328 when returning a structure. */
329 static const char *TAG_MSGSEND_STRET;
330 static const char *TAG_MSGSENDSUPER_STRET;
331 static const char *default_constant_string_class_name;
333 /* Runtime metadata flags. */
334 #define CLS_FACTORY 0x0001L
335 #define CLS_META 0x0002L
336 #define CLS_HAS_CXX_STRUCTORS 0x2000L
338 #define OBJC_MODIFIER_STATIC 0x00000001
339 #define OBJC_MODIFIER_FINAL 0x00000002
340 #define OBJC_MODIFIER_PUBLIC 0x00000004
341 #define OBJC_MODIFIER_PRIVATE 0x00000008
342 #define OBJC_MODIFIER_PROTECTED 0x00000010
343 #define OBJC_MODIFIER_NATIVE 0x00000020
344 #define OBJC_MODIFIER_SYNCHRONIZED 0x00000040
345 #define OBJC_MODIFIER_ABSTRACT 0x00000080
346 #define OBJC_MODIFIER_VOLATILE 0x00000100
347 #define OBJC_MODIFIER_TRANSIENT 0x00000200
348 #define OBJC_MODIFIER_NONE_SPECIFIED 0x80000000
350 /* NeXT-specific tags. */
352 #define TAG_MSGSEND_NONNIL "objc_msgSendNonNil"
353 #define TAG_MSGSEND_NONNIL_STRET "objc_msgSendNonNil_stret"
354 #define TAG_EXCEPTIONEXTRACT "objc_exception_extract"
355 #define TAG_EXCEPTIONTRYENTER "objc_exception_try_enter"
356 #define TAG_EXCEPTIONTRYEXIT "objc_exception_try_exit"
357 #define TAG_EXCEPTIONMATCH "objc_exception_match"
358 #define TAG_EXCEPTIONTHROW "objc_exception_throw"
359 #define TAG_SYNCENTER "objc_sync_enter"
360 #define TAG_SYNCEXIT "objc_sync_exit"
361 #define TAG_SETJMP "_setjmp"
362 #define UTAG_EXCDATA "_objc_exception_data"
364 #define TAG_ASSIGNIVAR "objc_assign_ivar"
365 #define TAG_ASSIGNGLOBAL "objc_assign_global"
366 #define TAG_ASSIGNSTRONGCAST "objc_assign_strongCast"
368 /* Branch entry points. All that matters here are the addresses;
369 functions with these names do not really exist in libobjc. */
371 #define TAG_MSGSEND_FAST "objc_msgSend_Fast"
372 #define TAG_ASSIGNIVAR_FAST "objc_assign_ivar_Fast"
374 #define TAG_CXX_CONSTRUCT ".cxx_construct"
375 #define TAG_CXX_DESTRUCT ".cxx_destruct"
377 /* GNU-specific tags. */
379 #define TAG_EXECCLASS "__objc_exec_class"
380 #define TAG_GNUINIT "__objc_gnu_init"
382 /* Flags for lookup_method_static(). */
383 #define OBJC_LOOKUP_CLASS 1 /* Look for class methods. */
384 #define OBJC_LOOKUP_NO_SUPER 2 /* Do not examine superclasses. */
386 /* The OCTI_... enumeration itself is in objc/objc-act.h. */
387 tree objc_global_trees[OCTI_MAX];
389 static void handle_impent (struct imp_entry *);
391 struct imp_entry *imp_list = 0;
392 int imp_count = 0; /* `@implementation' */
393 int cat_count = 0; /* `@category' */
395 objc_ivar_visibility_kind objc_ivar_visibility;
397 /* Use to generate method labels. */
398 static int method_slot = 0;
400 /* Flag to say whether methods in a protocol are optional or
402 static bool objc_method_optional_flag = false;
404 static bool property_readonly;
405 static tree property_getter;
406 static tree property_setter;
407 static tree property_ivar;
408 static bool property_copies;
409 static bool in_objc_property_setter_name_context = false;
411 static int objc_collecting_ivars = 0;
415 static char *errbuf; /* Buffer for error diagnostics */
417 /* Data imported from tree.c. */
419 extern enum debug_info_type write_symbols;
421 /* Data imported from toplev.c. */
423 extern const char *dump_base_name;
425 static int flag_typed_selectors;
427 /* Store all constructed constant strings in a hash table so that
428 they get uniqued properly. */
430 struct GTY(()) string_descriptor {
431 /* The literal argument . */
434 /* The resulting constant string. */
438 static GTY((param_is (struct string_descriptor))) htab_t string_htab;
440 FILE *gen_declaration_file;
442 /* Tells "encode_pointer/encode_aggregate" whether we are generating
443 type descriptors for instance variables (as opposed to methods).
444 Type descriptors for instance variables contain more information
445 than methods (for static typing and embedded structures). */
447 static int generating_instance_variables = 0;
449 /* For building an objc struct. These may not be used when this file
450 is compiled as part of obj-c++. */
452 static bool objc_building_struct;
453 static struct c_struct_parse_info *objc_struct_info ATTRIBUTE_UNUSED;
455 /* Start building a struct for objc. */
458 objc_start_struct (tree name)
460 gcc_assert (!objc_building_struct);
461 objc_building_struct = true;
462 return start_struct (input_location, RECORD_TYPE, name, &objc_struct_info);
465 /* Finish building a struct for objc. */
468 objc_finish_struct (tree type, tree fieldlist)
470 gcc_assert (objc_building_struct);
471 objc_building_struct = false;
472 return finish_struct (input_location, type, fieldlist, NULL_TREE,
477 build_sized_array_type (tree base_type, int size)
479 tree index_type = build_index_type (build_int_cst (NULL_TREE, size - 1));
480 return build_array_type (base_type, index_type);
484 add_field_decl (tree type, const char *name, tree **chain)
486 tree field = create_field_decl (type, name);
490 *chain = &DECL_CHAIN (field);
495 /* Some platforms pass small structures through registers versus
496 through an invisible pointer. Determine at what size structure is
497 the transition point between the two possibilities. */
500 generate_struct_by_value_array (void)
505 int aggregate_in_mem[32];
508 /* Presumably no platform passes 32 byte structures in a register. */
509 for (i = 1; i < 32; i++)
514 /* Create an unnamed struct that has `i' character components */
515 type = objc_start_struct (NULL_TREE);
517 strcpy (buffer, "c1");
518 decls = add_field_decl (char_type_node, buffer, &chain);
520 for (j = 1; j < i; j++)
522 sprintf (buffer, "c%d", j + 1);
523 add_field_decl (char_type_node, buffer, &chain);
525 objc_finish_struct (type, decls);
527 aggregate_in_mem[i] = aggregate_value_p (type, 0);
528 if (!aggregate_in_mem[i])
532 /* We found some structures that are returned in registers instead of memory
533 so output the necessary data. */
536 for (i = 31; i >= 0; i--)
537 if (!aggregate_in_mem[i])
539 printf ("#define OBJC_MAX_STRUCT_BY_VALUE %d\n\n", i);
541 /* The first member of the structure is always 0 because we don't handle
542 structures with 0 members */
543 printf ("static int struct_forward_array[] = {\n 0");
545 for (j = 1; j <= i; j++)
546 printf (", %d", aggregate_in_mem[j]);
553 /* FIXME: We need to intercept calls to warn_deprecated_use, since that
554 ultimately calls warning () with a "qD" formatter for decls. The 'D'
555 formatter does not handle ObjC-specific decls (in ObjC++). For now, we
556 interpose a switch to the default handler which simply prints the decl
558 Eventually, we should handle this within the objc{,p}/ code. */
561 objc_warn_deprecated_use (tree depitem, tree attr)
563 if (DECL_P (depitem))
565 static bool (*sav_printer) (pretty_printer *, text_info *, const char *,
566 int, bool, bool, bool) = NULL ;
567 if (sav_printer == NULL)
568 sav_printer = diagnostic_format_decoder (global_dc) ;
569 diagnostic_format_decoder (global_dc) = &default_tree_printer;
570 warn_deprecated_use (depitem, attr);
571 diagnostic_format_decoder (global_dc) = sav_printer;
574 warn_deprecated_use (depitem, attr);
581 if (cxx_init () == false)
583 if (c_objc_common_init () == false)
587 /* If gen_declaration desired, open the output file. */
588 if (flag_gen_declaration)
590 register char * const dumpname = concat (dump_base_name, ".decl", NULL);
591 gen_declaration_file = fopen (dumpname, "w");
592 if (gen_declaration_file == 0)
593 fatal_error ("can't open %s: %m", dumpname);
597 if (flag_next_runtime)
599 TAG_GETCLASS = "objc_getClass";
600 TAG_GETMETACLASS = "objc_getMetaClass";
601 TAG_MSGSEND = "objc_msgSend";
602 TAG_MSGSENDSUPER = "objc_msgSendSuper";
603 TAG_MSGSEND_STRET = "objc_msgSend_stret";
604 TAG_MSGSENDSUPER_STRET = "objc_msgSendSuper_stret";
605 default_constant_string_class_name = "NSConstantString";
609 TAG_GETCLASS = "objc_get_class";
610 TAG_GETMETACLASS = "objc_get_meta_class";
611 TAG_MSGSEND = "objc_msg_lookup";
612 TAG_MSGSENDSUPER = "objc_msg_lookup_super";
613 /* GNU runtime does not provide special functions to support
614 structure-returning methods. */
615 default_constant_string_class_name = "NXConstantString";
616 flag_typed_selectors = 1;
617 /* GNU runtime does not need the compiler to change code
618 in order to do GC. */
621 warning_at (0, 0, "%<-fobjc-gc%> is ignored for %<-fgnu-runtime%>");
628 if (print_struct_values && !flag_compare_debug)
629 generate_struct_by_value_array ();
634 /* This is called automatically (at the very end of compilation) by
635 c_write_global_declarations and cp_write_global_declarations. */
637 objc_write_global_declarations (void)
639 mark_referenced_methods ();
641 /* Finalize Objective-C runtime data. */
644 if (gen_declaration_file)
645 fclose (gen_declaration_file);
648 /* Return the first occurrence of a method declaration corresponding
649 to sel_name in rproto_list. Search rproto_list recursively.
650 If is_class is 0, search for instance methods, otherwise for class
653 lookup_method_in_protocol_list (tree rproto_list, tree sel_name,
659 for (rproto = rproto_list; rproto; rproto = TREE_CHAIN (rproto))
661 p = TREE_VALUE (rproto);
663 if (TREE_CODE (p) == PROTOCOL_INTERFACE_TYPE)
665 if ((fnd = lookup_method (is_class
666 ? PROTOCOL_CLS_METHODS (p)
667 : PROTOCOL_NST_METHODS (p), sel_name)))
669 else if (PROTOCOL_LIST (p))
670 fnd = lookup_method_in_protocol_list (PROTOCOL_LIST (p),
675 ; /* An identifier...if we could not find a protocol. */
686 lookup_protocol_in_reflist (tree rproto_list, tree lproto)
690 /* Make sure the protocol is supported by the object on the rhs. */
691 if (TREE_CODE (lproto) == PROTOCOL_INTERFACE_TYPE)
694 for (rproto = rproto_list; rproto; rproto = TREE_CHAIN (rproto))
696 p = TREE_VALUE (rproto);
698 if (TREE_CODE (p) == PROTOCOL_INTERFACE_TYPE)
703 else if (PROTOCOL_LIST (p))
704 fnd = lookup_protocol_in_reflist (PROTOCOL_LIST (p), lproto);
713 ; /* An identifier...if we could not find a protocol. */
720 objc_start_class_interface (tree klass, tree super_class,
721 tree protos, tree attributes)
724 warning_at (input_location, OPT_Wattributes,
725 "class attributes are not available in this version"
726 " of the compiler, (ignored)");
727 objc_interface_context
729 = start_class (CLASS_INTERFACE_TYPE, klass, super_class, protos);
730 objc_ivar_visibility = OBJC_IVAR_VIS_PROTECTED;
734 objc_start_category_interface (tree klass, tree categ,
735 tree protos, tree attributes)
738 warning_at (input_location, OPT_Wattributes,
739 "category attributes are not available in this version"
740 " of the compiler, (ignored)");
741 objc_interface_context
742 = start_class (CATEGORY_INTERFACE_TYPE, klass, categ, protos);
744 = continue_class (objc_interface_context);
748 objc_start_protocol (tree name, tree protos, tree attributes)
751 warning_at (input_location, OPT_Wattributes,
752 "protocol attributes are not available in this version"
753 " of the compiler, (ignored)");
754 objc_interface_context
755 = start_protocol (PROTOCOL_INTERFACE_TYPE, name, protos);
756 objc_method_optional_flag = false;
760 objc_continue_interface (void)
763 = continue_class (objc_interface_context);
767 objc_finish_interface (void)
769 finish_class (objc_interface_context);
770 objc_interface_context = NULL_TREE;
771 objc_method_optional_flag = false;
775 objc_start_class_implementation (tree klass, tree super_class)
777 objc_implementation_context
779 = start_class (CLASS_IMPLEMENTATION_TYPE, klass, super_class, NULL_TREE);
780 objc_ivar_visibility = OBJC_IVAR_VIS_PROTECTED;
784 objc_start_category_implementation (tree klass, tree categ)
786 objc_implementation_context
787 = start_class (CATEGORY_IMPLEMENTATION_TYPE, klass, categ, NULL_TREE);
789 = continue_class (objc_implementation_context);
793 objc_continue_implementation (void)
796 = continue_class (objc_implementation_context);
800 objc_finish_implementation (void)
803 if (flag_objc_call_cxx_cdtors)
804 objc_generate_cxx_cdtors ();
807 if (objc_implementation_context)
809 finish_class (objc_implementation_context);
810 objc_ivar_chain = NULL_TREE;
811 objc_implementation_context = NULL_TREE;
814 warning (0, "%<@end%> must appear in an @implementation context");
818 objc_set_visibility (objc_ivar_visibility_kind visibility)
820 if (visibility == OBJC_IVAR_VIS_PACKAGE)
821 warning (0, "%<@package%> presently has the same effect as %<@public%>");
822 objc_ivar_visibility = visibility;
826 objc_set_method_opt (bool optional)
828 objc_method_optional_flag = optional;
829 if (!objc_interface_context
830 || TREE_CODE (objc_interface_context) != PROTOCOL_INTERFACE_TYPE)
832 error ("@optional/@required is allowed in @protocol context only.");
833 objc_method_optional_flag = false;
837 /* This routine gathers property attribute information from the attribute
838 portion of a property declaration. */
841 objc_set_property_attr (location_t loc, objc_property_attribute_kind attr,
844 static char string[BUFSIZE];
847 case OBJC_PATTR_INIT: /* init */
848 property_readonly = property_copies = false;
849 property_setter = property_getter = property_ivar = NULL_TREE;
851 case OBJC_PATTR_READONLY: /* readonly */
852 property_readonly = true;
854 case OBJC_PATTR_GETTER: /* getter = ident */
855 if (property_getter != NULL_TREE)
856 error_at (loc, "the %<getter%> attribute may only be specified once");
857 property_getter = ident;
859 case OBJC_PATTR_SETTER: /* setter = ident */
860 if (property_setter != NULL_TREE)
861 error_at (loc, "the %<setter%> attribute may only be specified once");
862 /* setters always have a trailing ':' in their name. In fact, this is the
863 only syntax that parser recognizes for a setter name. Must add a trailing
864 ':' here so name matches that of the declaration of user instance method
866 sprintf (string, "%s:", IDENTIFIER_POINTER (ident));
867 property_setter = get_identifier (string);;
869 case OBJC_PATTR_IVAR: /* ivar = ident */
870 if (property_ivar != NULL_TREE)
871 error_at (loc, "the %<ivar%> attribute may only be specified once");
872 else if (objc_interface_context)
874 warning_at (loc, 0, "the %<ivar%> attribute is ignored in an @interface");
875 property_ivar = NULL_TREE;
878 property_ivar = ident;
880 case OBJC_PATTR_COPIES: /* copies */
881 property_copies = true;
888 /* This routine builds a 'property_decl' tree node and adds it to the list
889 of such properties in the current class. It also checks for duplicates.
893 objc_add_property_variable (tree decl)
897 tree interface = NULL_TREE;
899 if (objc_implementation_context)
901 interface = lookup_interface (CLASS_NAME (objc_implementation_context));
904 error ("no class property can be implemented without an interface");
907 if (TREE_CODE (objc_implementation_context) == CATEGORY_IMPLEMENTATION_TYPE)
909 interface = lookup_category (interface,
910 CLASS_SUPER_NAME (objc_implementation_context));
913 error ("no category property can be implemented without an interface");
918 else if (!objc_interface_context)
920 fatal_error ("property declaration not in @interface or @implementation context");
924 property_decl = make_node (PROPERTY_DECL);
925 TREE_TYPE (property_decl) = TREE_TYPE (decl);
927 PROPERTY_NAME (property_decl) = DECL_NAME (decl);
928 PROPERTY_GETTER_NAME (property_decl) = property_getter;
929 PROPERTY_SETTER_NAME (property_decl) = property_setter;
930 PROPERTY_IVAR_NAME (property_decl) = property_ivar;
931 PROPERTY_READONLY (property_decl) = property_readonly
933 : boolean_false_node;
934 PROPERTY_COPIES (property_decl) = property_copies
936 : boolean_false_node;
938 if (objc_interface_context)
940 /* Doing the property in interface declaration. */
942 /* Issue error if property and an ivar name match. */
943 if (TREE_CODE (objc_interface_context) == CLASS_INTERFACE_TYPE
944 && is_ivar (CLASS_IVARS (objc_interface_context), DECL_NAME (decl)))
945 error ("property %qD may not have the same name as an ivar in the class", decl);
946 /* must check for duplicate property declarations. */
947 for (x = CLASS_PROPERTY_DECL (objc_interface_context); x; x = TREE_CHAIN (x))
949 if (PROPERTY_NAME (x) == DECL_NAME (decl))
951 error ("duplicate property declaration %qD", decl);
955 TREE_CHAIN (property_decl) = CLASS_PROPERTY_DECL (objc_interface_context);
956 CLASS_PROPERTY_DECL (objc_interface_context) = property_decl;
960 /* Doing the property in implementation context. */
961 /* If property is not declared in the interface issue error. */
962 for (x = CLASS_PROPERTY_DECL (interface); x; x = TREE_CHAIN (x))
963 if (PROPERTY_NAME (x) == DECL_NAME (decl))
967 error ("no declaration of property %qD found in the interface", decl);
970 /* readonlys must also match. */
971 if (PROPERTY_READONLY (x) != PROPERTY_READONLY (property_decl))
973 error ("property %qD %<readonly%> attribute conflicts with its"
974 " interface version", decl);
976 /* copies must also match. */
977 if (PROPERTY_COPIES (x) != PROPERTY_COPIES (property_decl))
979 error ("property %qD %<copies%> attribute conflicts with its"
980 " interface version", decl);
982 /* Cannot have readonly and setter attribute for the same property. */
983 if (PROPERTY_READONLY (property_decl) == boolean_true_node &&
984 PROPERTY_SETTER_NAME (property_decl))
986 warning (0, "a %<readonly%> property cannot have a setter (ignored)");
987 PROPERTY_SETTER_NAME (property_decl) = NULL_TREE;
989 /* Add the property to the list of properties for current implementation. */
990 TREE_CHAIN (property_decl) = IMPL_PROPERTY_DECL (objc_implementation_context);
991 IMPL_PROPERTY_DECL (objc_implementation_context) = property_decl;
995 /* This routine looks for a given PROPERTY in a list of CLASS, CATEGORY, or
999 lookup_property_in_list (tree chain, tree property)
1002 for (x = CLASS_PROPERTY_DECL (chain); x; x = TREE_CHAIN (x))
1003 if (PROPERTY_NAME (x) == property)
1008 /* This routine looks for a given PROPERTY in the tree chain of RPROTO_LIST. */
1010 static tree lookup_property_in_protocol_list (tree rproto_list, tree property)
1013 for (rproto = rproto_list; rproto; rproto = TREE_CHAIN (rproto))
1015 tree p = TREE_VALUE (rproto);
1016 if (TREE_CODE (p) == PROTOCOL_INTERFACE_TYPE)
1018 if ((x = lookup_property_in_list (p, property)))
1020 if (PROTOCOL_LIST (p))
1021 return lookup_property_in_protocol_list (PROTOCOL_LIST (p), property);
1025 ; /* An identifier...if we could not find a protocol. */
1031 /* This routine looks up the PROPERTY in current INTERFACE, its categories and up the
1032 chain of interface hierarchy.
1035 lookup_property (tree interface_type, tree property)
1037 tree inter = interface_type;
1041 if ((x = lookup_property_in_list (inter, property)))
1043 /* Failing that, look for the property in each category of the class. */
1045 while ((category = CLASS_CATEGORY_LIST (category)))
1046 if ((x = lookup_property_in_list (category, property)))
1049 /* Failing to find in categories, look for property in protocol list. */
1050 if (CLASS_PROTOCOL_LIST (inter)
1051 && (x = lookup_property_in_protocol_list (
1052 CLASS_PROTOCOL_LIST (inter), property)))
1055 /* Failing that, climb up the inheritance hierarchy. */
1056 inter = lookup_interface (CLASS_SUPER_NAME (inter));
1061 /* This routine recognizes a dot-notation for a propery reference and generates a call to
1062 the getter function for this property. In all other cases, it returns a NULL_TREE.
1066 objc_build_getter_call (tree receiver, tree component)
1071 if (receiver == NULL_TREE
1072 || receiver == error_mark_node
1073 || (rtype = TREE_TYPE (receiver)) == NULL_TREE)
1076 if (component == NULL_TREE
1077 || component == error_mark_node
1078 || TREE_CODE (component) != IDENTIFIER_NODE)
1081 if (objc_is_id (rtype))
1083 tree rprotos = (TYPE_HAS_OBJC_INFO (TREE_TYPE (rtype))
1084 ? TYPE_OBJC_PROTOCOL_LIST (TREE_TYPE (rtype))
1087 x = lookup_property_in_protocol_list (rprotos, component);
1091 tree basetype = TYPE_MAIN_VARIANT (rtype);
1093 if (basetype != NULL_TREE && TREE_CODE (basetype) == POINTER_TYPE)
1094 basetype = TREE_TYPE (basetype);
1098 while (basetype != NULL_TREE
1099 && TREE_CODE (basetype) == RECORD_TYPE
1100 && OBJC_TYPE_NAME (basetype)
1101 && TREE_CODE (OBJC_TYPE_NAME (basetype)) == TYPE_DECL
1102 && DECL_ORIGINAL_TYPE (OBJC_TYPE_NAME (basetype)))
1103 basetype = DECL_ORIGINAL_TYPE (OBJC_TYPE_NAME (basetype));
1105 if (basetype != NULL_TREE && TYPED_OBJECT (basetype))
1107 tree interface_type = TYPE_OBJC_INTERFACE (basetype);
1108 if (!interface_type)
1110 x = lookup_property (interface_type, component);
1116 tree call_exp, getter;
1117 /* Get the getter name. */
1118 gcc_assert (PROPERTY_NAME (x));
1119 getter = objc_finish_message_expr (receiver, PROPERTY_NAME (x),
1123 /* In C++, a getter which returns an aggregate value results in a
1124 target_expr which initializes a temporary to the call expression. */
1125 if (TREE_CODE (getter) == TARGET_EXPR)
1127 gcc_assert (MAYBE_CLASS_TYPE_P (TREE_TYPE (getter)));
1128 gcc_assert (TREE_CODE (TREE_OPERAND (getter,0)) == VAR_DECL);
1129 call_exp = TREE_OPERAND (getter,1);
1132 gcc_assert (TREE_CODE (call_exp) == CALL_EXPR);
1134 CALL_EXPR_OBJC_PROPERTY_GETTER (call_exp) = 1;
1140 /* This routine builds a call to property's 'setter' function. RECEIVER is the
1141 receiving object for 'setter'. PROPERTY_IDENT is name of the property and
1142 RHS is the argument passed to the 'setter' function. */
1145 objc_setter_func_call (tree receiver, tree property_ident, tree rhs)
1147 tree setter_argument = build_tree_list (NULL_TREE, rhs);
1148 char *setter_name = objc_build_property_setter_name (property_ident, true);
1150 in_objc_property_setter_name_context = true;
1151 setter = objc_finish_message_expr (receiver, get_identifier (setter_name),
1153 in_objc_property_setter_name_context = false;
1157 /* Find the selector identifier from a reference. A somewhat tortuous way of
1158 obtaining the information to allow a setter to be written, given an
1162 get_selector_from_reference (tree selref)
1166 if (flag_next_runtime)
1168 /* Run through the selectors until we find the one we're looking for. */
1169 for (chain = sel_ref_chain; chain; chain = TREE_CHAIN (chain))
1170 if (TREE_PURPOSE (chain) == selref)
1171 return TREE_VALUE (chain);
1175 /* To find our way back to the selector for the GNU runtime is harder
1176 work, we need to decompose the representation of SELECTOR_TABLE[n]
1177 to find 'n'. This representation is in several forms. */
1178 if (TREE_CODE (selref) == POINTER_PLUS_EXPR)
1180 /* We need the element size to decode the array offset expression
1182 unsigned size = (unsigned) TREE_INT_CST_LOW
1188 (TREE_OPERAND (selref, 0), 0), 0)))));
1190 (unsigned) TREE_INT_CST_LOW (TREE_OPERAND (selref, 1))
1192 for (chain = sel_ref_chain; chain; chain = TREE_CHAIN (chain))
1194 return TREE_VALUE (chain);
1196 else if (TREE_CODE (selref) == NOP_EXPR)
1198 /* Either we have a base an index, or we have just a base (when the
1200 if (TREE_CODE (TREE_OPERAND (selref, 0)) == ADDR_EXPR
1203 (TREE_OPERAND (selref, 0), 0)) == ARRAY_REF)
1206 unsigned index = (unsigned) TREE_INT_CST_LOW
1209 (TREE_OPERAND (selref, 0), 0), 1));
1210 for (chain = sel_ref_chain; chain; chain = TREE_CHAIN (chain))
1212 return TREE_VALUE (chain);
1215 return TREE_VALUE (sel_ref_chain);
1216 } /* Else we don't know how to figure this out - which will produce a
1217 parse error - saying that the LHS is not writeable. */
1222 /* This routine converts a previously synthesized 'getter' function call for
1223 a property and converts it to a 'setter' function call for the same
1227 objc_build_setter_call (tree lhs, tree rhs)
1230 && TREE_CODE (lhs) == CALL_EXPR
1231 && CALL_EXPR_OBJC_PROPERTY_GETTER (lhs))
1234 /* Get the Object. */
1235 tree receiver = TREE_OPERAND (lhs, 3);
1236 /* Get the selector reference. */
1237 tree selector_reference = TREE_OPERAND (lhs, 4);
1238 gcc_assert (receiver && selector_reference);
1239 /* The style of the selector reference is different for GNU & NeXT. */
1240 selector = get_selector_from_reference (selector_reference);
1242 return objc_setter_func_call (receiver, selector, rhs);
1247 /* This routine checks to see if ID is a property name. If so, it
1248 returns property declaration. */
1251 is_property (tree klass, tree id)
1255 for (x = CLASS_PROPERTY_DECL (klass); x; x = TREE_CHAIN (x))
1256 if (PROPERTY_NAME (x) == id)
1261 /* This routine returns call to property's getter when a property is
1262 used stand-alone (without self. notation). */
1265 build_property_reference (tree property, tree id)
1268 if (TREE_CODE (objc_method_context) == CLASS_METHOD_DECL)
1270 error ("property %qs accessed in class method",
1271 IDENTIFIER_POINTER (id));
1272 return error_mark_node;
1275 getter = objc_finish_message_expr (self_decl, PROPERTY_NAME (property), NULL_TREE);
1276 CALL_EXPR_OBJC_PROPERTY_GETTER (getter) = 1;
1281 objc_build_method_signature (bool is_class_method, tree rettype, tree selector,
1282 tree optparms, bool ellipsis)
1284 if (is_class_method)
1285 return build_method_decl (CLASS_METHOD_DECL, rettype, selector,
1286 optparms, ellipsis);
1288 return build_method_decl (INSTANCE_METHOD_DECL, rettype, selector,
1289 optparms, ellipsis);
1293 objc_add_method_declaration (bool is_class_method, tree decl, tree attributes)
1295 if (!objc_interface_context)
1297 /* PS: At the moment, due to how the parser works, it should be
1298 impossible to get here. But it's good to have the check in
1299 case the parser changes.
1301 fatal_error ("method declaration not in @interface context");
1304 objc_decl_method_attributes (&decl, attributes, 0);
1305 objc_add_method (objc_interface_context,
1308 objc_method_optional_flag);
1311 /* Return 'true' if the method definition could be started, and
1312 'false' if not (because we are outside an @implementation context).
1315 objc_start_method_definition (bool is_class_method, tree decl, tree attributes)
1317 if (!objc_implementation_context)
1319 error ("method definition not in @implementation context");
1323 if (decl != NULL_TREE && METHOD_SEL_NAME (decl) == error_mark_node)
1327 /* Indicate no valid break/continue context by setting these variables
1328 to some non-null, non-label value. We'll notice and emit the proper
1329 error message in c_finish_bc_stmt. */
1330 c_break_label = c_cont_label = size_zero_node;
1333 objc_decl_method_attributes (&decl, attributes, 0);
1334 objc_add_method (objc_implementation_context,
1337 /* is optional */ false);
1338 start_method_def (decl);
1343 objc_add_instance_variable (tree decl)
1345 (void) add_instance_variable (objc_ivar_context,
1346 objc_ivar_visibility,
1350 /* Return true if TYPE is 'id'. */
1353 objc_is_object_id (tree type)
1355 return OBJC_TYPE_NAME (type) == objc_object_id;
1359 objc_is_class_id (tree type)
1361 return OBJC_TYPE_NAME (type) == objc_class_id;
1364 /* Construct a C struct with same name as KLASS, a base struct with tag
1365 SUPER_NAME (if any), and FIELDS indicated. */
1368 objc_build_struct (tree klass, tree fields, tree super_name)
1370 tree name = CLASS_NAME (klass);
1371 tree s = objc_start_struct (name);
1372 tree super = (super_name ? xref_tag (RECORD_TYPE, super_name) : NULL_TREE);
1374 VEC(tree,heap) *objc_info = NULL;
1379 /* Prepend a packed variant of the base class into the layout. This
1380 is necessary to preserve ObjC ABI compatibility. */
1381 tree base = build_decl (input_location,
1382 FIELD_DECL, NULL_TREE, super);
1383 tree field = TYPE_FIELDS (super);
1385 while (field && DECL_CHAIN (field)
1386 && TREE_CODE (DECL_CHAIN (field)) == FIELD_DECL)
1387 field = DECL_CHAIN (field);
1389 /* For ObjC ABI purposes, the "packed" size of a base class is
1390 the sum of the offset and the size (in bits) of the last field
1393 = (field && TREE_CODE (field) == FIELD_DECL
1394 ? size_binop (PLUS_EXPR,
1395 size_binop (PLUS_EXPR,
1398 convert (bitsizetype,
1399 DECL_FIELD_OFFSET (field)),
1400 bitsize_int (BITS_PER_UNIT)),
1401 DECL_FIELD_BIT_OFFSET (field)),
1403 : bitsize_zero_node);
1404 DECL_SIZE_UNIT (base)
1405 = size_binop (FLOOR_DIV_EXPR, convert (sizetype, DECL_SIZE (base)),
1406 size_int (BITS_PER_UNIT));
1407 DECL_ARTIFICIAL (base) = 1;
1408 DECL_ALIGN (base) = 1;
1409 DECL_FIELD_CONTEXT (base) = s;
1411 DECL_FIELD_IS_BASE (base) = 1;
1414 TREE_NO_WARNING (fields) = 1; /* Suppress C++ ABI warnings -- we */
1415 #endif /* are following the ObjC ABI here. */
1416 DECL_CHAIN (base) = fields;
1420 /* NB: Calling finish_struct() may cause type TYPE_LANG_SPECIFIC fields
1421 in all variants of this RECORD_TYPE to be clobbered, but it is therein
1422 that we store protocol conformance info (e.g., 'NSObject <MyProtocol>').
1423 Hence, we must squirrel away the ObjC-specific information before calling
1424 finish_struct(), and then reinstate it afterwards. */
1426 for (t = TYPE_NEXT_VARIANT (s); t; t = TYPE_NEXT_VARIANT (t))
1428 if (!TYPE_HAS_OBJC_INFO (t))
1430 INIT_TYPE_OBJC_INFO (t);
1431 TYPE_OBJC_INTERFACE (t) = klass;
1433 VEC_safe_push (tree, heap, objc_info, TYPE_OBJC_INFO (t));
1436 /* Point the struct at its related Objective-C class. */
1437 INIT_TYPE_OBJC_INFO (s);
1438 TYPE_OBJC_INTERFACE (s) = klass;
1440 s = objc_finish_struct (s, fields);
1442 for (i = 0, t = TYPE_NEXT_VARIANT (s); t; t = TYPE_NEXT_VARIANT (t), i++)
1444 TYPE_OBJC_INFO (t) = VEC_index (tree, objc_info, i);
1445 /* Replace the IDENTIFIER_NODE with an actual @interface. */
1446 TYPE_OBJC_INTERFACE (t) = klass;
1448 VEC_free (tree, heap, objc_info);
1450 /* Use TYPE_BINFO structures to point at the super class, if any. */
1451 objc_xref_basetypes (s, super);
1453 /* Mark this struct as a class template. */
1454 CLASS_STATIC_TEMPLATE (klass) = s;
1459 /* Build a type differing from TYPE only in that TYPE_VOLATILE is set.
1460 Unlike tree.c:build_qualified_type(), preserve TYPE_LANG_SPECIFIC in the
1463 objc_build_volatilized_type (tree type)
1467 /* Check if we have not constructed the desired variant already. */
1468 for (t = TYPE_MAIN_VARIANT (type); t; t = TYPE_NEXT_VARIANT (t))
1470 /* The type qualifiers must (obviously) match up. */
1471 if (!TYPE_VOLATILE (t)
1472 || (TYPE_READONLY (t) != TYPE_READONLY (type))
1473 || (TYPE_RESTRICT (t) != TYPE_RESTRICT (type)))
1476 /* For pointer types, the pointees (and hence their TYPE_LANG_SPECIFIC
1477 info, if any) must match up. */
1478 if (POINTER_TYPE_P (t)
1479 && (TREE_TYPE (t) != TREE_TYPE (type)))
1482 /* Only match up the types which were previously volatilized in similar fashion and not
1483 because they were declared as such. */
1484 if (!lookup_attribute ("objc_volatilized", TYPE_ATTRIBUTES (t)))
1487 /* Everything matches up! */
1491 /* Ok, we could not re-use any of the pre-existing variants. Create
1493 t = build_variant_type_copy (type);
1494 TYPE_VOLATILE (t) = 1;
1496 TYPE_ATTRIBUTES (t) = merge_attributes (TYPE_ATTRIBUTES (type),
1497 tree_cons (get_identifier ("objc_volatilized"),
1500 if (TREE_CODE (t) == ARRAY_TYPE)
1501 TREE_TYPE (t) = objc_build_volatilized_type (TREE_TYPE (t));
1503 /* Set up the canonical type information. */
1504 if (TYPE_STRUCTURAL_EQUALITY_P (type))
1505 SET_TYPE_STRUCTURAL_EQUALITY (t);
1506 else if (TYPE_CANONICAL (type) != type)
1507 TYPE_CANONICAL (t) = objc_build_volatilized_type (TYPE_CANONICAL (type));
1509 TYPE_CANONICAL (t) = t;
1514 /* Mark DECL as being 'volatile' for purposes of Darwin
1515 _setjmp()/_longjmp() exception handling. Called from
1516 objc_mark_locals_volatile(). */
1518 objc_volatilize_decl (tree decl)
1520 /* Do not mess with variables that are 'static' or (already)
1522 if (!TREE_THIS_VOLATILE (decl) && !TREE_STATIC (decl)
1523 && (TREE_CODE (decl) == VAR_DECL
1524 || TREE_CODE (decl) == PARM_DECL))
1526 tree t = TREE_TYPE (decl);
1528 t = objc_build_volatilized_type (t);
1530 TREE_TYPE (decl) = t;
1531 TREE_THIS_VOLATILE (decl) = 1;
1532 TREE_SIDE_EFFECTS (decl) = 1;
1533 DECL_REGISTER (decl) = 0;
1535 C_DECL_REGISTER (decl) = 0;
1540 /* Check if protocol PROTO is adopted (directly or indirectly) by class CLS
1541 (including its categories and superclasses) or by object type TYP.
1542 Issue a warning if PROTO is not adopted anywhere and WARN is set. */
1545 objc_lookup_protocol (tree proto, tree cls, tree typ, bool warn)
1547 bool class_type = (cls != NULL_TREE);
1553 /* Check protocols adopted by the class and its categories. */
1554 for (c = cls; c; c = CLASS_CATEGORY_LIST (c))
1556 if (lookup_protocol_in_reflist (CLASS_PROTOCOL_LIST (c), proto))
1560 /* Repeat for superclasses. */
1561 cls = lookup_interface (CLASS_SUPER_NAME (cls));
1564 /* Check for any protocols attached directly to the object type. */
1565 if (TYPE_HAS_OBJC_INFO (typ))
1567 if (lookup_protocol_in_reflist (TYPE_OBJC_PROTOCOL_LIST (typ), proto))
1574 gen_type_name_0 (class_type ? typ : TYPE_POINTER_TO (typ));
1575 /* NB: Types 'id' and 'Class' cannot reasonably be described as
1576 "implementing" a given protocol, since they do not have an
1579 warning (0, "class %qs does not implement the %qE protocol",
1580 identifier_to_locale (errbuf), PROTOCOL_NAME (proto));
1582 warning (0, "type %qs does not conform to the %qE protocol",
1583 identifier_to_locale (errbuf), PROTOCOL_NAME (proto));
1589 /* Check if class RCLS and instance struct type RTYP conform to at least the
1590 same protocols that LCLS and LTYP conform to. */
1593 objc_compare_protocols (tree lcls, tree ltyp, tree rcls, tree rtyp, bool warn)
1596 bool have_lproto = false;
1600 /* NB: We do _not_ look at categories defined for LCLS; these may or
1601 may not get loaded in, and therefore it is unreasonable to require
1602 that RCLS/RTYP must implement any of their protocols. */
1603 for (p = CLASS_PROTOCOL_LIST (lcls); p; p = TREE_CHAIN (p))
1607 if (!objc_lookup_protocol (TREE_VALUE (p), rcls, rtyp, warn))
1611 /* Repeat for superclasses. */
1612 lcls = lookup_interface (CLASS_SUPER_NAME (lcls));
1615 /* Check for any protocols attached directly to the object type. */
1616 if (TYPE_HAS_OBJC_INFO (ltyp))
1618 for (p = TYPE_OBJC_PROTOCOL_LIST (ltyp); p; p = TREE_CHAIN (p))
1622 if (!objc_lookup_protocol (TREE_VALUE (p), rcls, rtyp, warn))
1627 /* NB: If LTYP and LCLS have no protocols to search for, return 'true'
1628 vacuously, _unless_ RTYP is a protocol-qualified 'id'. We can get
1629 away with simply checking for 'id' or 'Class' (!RCLS), since this
1630 routine will not get called in other cases. */
1631 return have_lproto || (rcls != NULL_TREE);
1634 /* Given two types TYPE1 and TYPE2, return their least common ancestor.
1635 Both TYPE1 and TYPE2 must be pointers, and already determined to be
1636 compatible by objc_compare_types() below. */
1639 objc_common_type (tree type1, tree type2)
1641 tree inner1 = TREE_TYPE (type1), inner2 = TREE_TYPE (type2);
1643 while (POINTER_TYPE_P (inner1))
1645 inner1 = TREE_TYPE (inner1);
1646 inner2 = TREE_TYPE (inner2);
1649 /* If one type is derived from another, return the base type. */
1650 if (DERIVED_FROM_P (inner1, inner2))
1652 else if (DERIVED_FROM_P (inner2, inner1))
1655 /* If both types are 'Class', return 'Class'. */
1656 if (objc_is_class_id (inner1) && objc_is_class_id (inner2))
1657 return objc_class_type;
1659 /* Otherwise, return 'id'. */
1660 return objc_object_type;
1663 /* Determine if it is permissible to assign (if ARGNO is greater than -3)
1664 an instance of RTYP to an instance of LTYP or to compare the two
1665 (if ARGNO is equal to -3), per ObjC type system rules. Before
1666 returning 'true', this routine may issue warnings related to, e.g.,
1667 protocol conformance. When returning 'false', the routine must
1668 produce absolutely no warnings; the C or C++ front-end will do so
1669 instead, if needed. If either LTYP or RTYP is not an Objective-C type,
1670 the routine must return 'false'.
1672 The ARGNO parameter is encoded as follows:
1673 >= 1 Parameter number (CALLEE contains function being called);
1677 -3 Comparison (LTYP and RTYP may match in either direction);
1678 -4 Silent comparison (for C++ overload resolution).
1682 objc_compare_types (tree ltyp, tree rtyp, int argno, tree callee)
1684 tree lcls, rcls, lproto, rproto;
1685 bool pointers_compatible;
1687 /* We must be dealing with pointer types */
1688 if (!POINTER_TYPE_P (ltyp) || !POINTER_TYPE_P (rtyp))
1693 ltyp = TREE_TYPE (ltyp); /* Remove indirections. */
1694 rtyp = TREE_TYPE (rtyp);
1696 while (POINTER_TYPE_P (ltyp) && POINTER_TYPE_P (rtyp));
1698 /* We must also handle function pointers, since ObjC is a bit more
1699 lenient than C or C++ on this. */
1700 if (TREE_CODE (ltyp) == FUNCTION_TYPE && TREE_CODE (rtyp) == FUNCTION_TYPE)
1702 /* Return types must be covariant. */
1703 if (!comptypes (TREE_TYPE (ltyp), TREE_TYPE (rtyp))
1704 && !objc_compare_types (TREE_TYPE (ltyp), TREE_TYPE (rtyp),
1708 /* Argument types must be contravariant. */
1709 for (ltyp = TYPE_ARG_TYPES (ltyp), rtyp = TYPE_ARG_TYPES (rtyp);
1710 ltyp && rtyp; ltyp = TREE_CHAIN (ltyp), rtyp = TREE_CHAIN (rtyp))
1712 if (!comptypes (TREE_VALUE (rtyp), TREE_VALUE (ltyp))
1713 && !objc_compare_types (TREE_VALUE (rtyp), TREE_VALUE (ltyp),
1718 return (ltyp == rtyp);
1721 /* Past this point, we are only interested in ObjC class instances,
1722 or 'id' or 'Class'. */
1723 if (TREE_CODE (ltyp) != RECORD_TYPE || TREE_CODE (rtyp) != RECORD_TYPE)
1726 if (!objc_is_object_id (ltyp) && !objc_is_class_id (ltyp)
1727 && !TYPE_HAS_OBJC_INFO (ltyp))
1730 if (!objc_is_object_id (rtyp) && !objc_is_class_id (rtyp)
1731 && !TYPE_HAS_OBJC_INFO (rtyp))
1734 /* Past this point, we are committed to returning 'true' to the caller
1735 (unless performing a silent comparison; see below). However, we can
1736 still warn about type and/or protocol mismatches. */
1738 if (TYPE_HAS_OBJC_INFO (ltyp))
1740 lcls = TYPE_OBJC_INTERFACE (ltyp);
1741 lproto = TYPE_OBJC_PROTOCOL_LIST (ltyp);
1744 lcls = lproto = NULL_TREE;
1746 if (TYPE_HAS_OBJC_INFO (rtyp))
1748 rcls = TYPE_OBJC_INTERFACE (rtyp);
1749 rproto = TYPE_OBJC_PROTOCOL_LIST (rtyp);
1752 rcls = rproto = NULL_TREE;
1754 /* If we could not find an @interface declaration, we must have
1755 only seen a @class declaration; for purposes of type comparison,
1756 treat it as a stand-alone (root) class. */
1758 if (lcls && TREE_CODE (lcls) == IDENTIFIER_NODE)
1761 if (rcls && TREE_CODE (rcls) == IDENTIFIER_NODE)
1764 /* If either type is an unqualified 'id', we're done. */
1765 if ((!lproto && objc_is_object_id (ltyp))
1766 || (!rproto && objc_is_object_id (rtyp)))
1769 pointers_compatible = (TYPE_MAIN_VARIANT (ltyp) == TYPE_MAIN_VARIANT (rtyp));
1771 /* If the underlying types are the same, and at most one of them has
1772 a protocol list, we do not need to issue any diagnostics. */
1773 if (pointers_compatible && (!lproto || !rproto))
1776 /* If exactly one of the types is 'Class', issue a diagnostic; any
1777 exceptions of this rule have already been handled. */
1778 if (objc_is_class_id (ltyp) ^ objc_is_class_id (rtyp))
1779 pointers_compatible = false;
1780 /* Otherwise, check for inheritance relations. */
1783 if (!pointers_compatible)
1785 = (objc_is_object_id (ltyp) || objc_is_object_id (rtyp));
1787 if (!pointers_compatible)
1788 pointers_compatible = DERIVED_FROM_P (ltyp, rtyp);
1790 if (!pointers_compatible && argno <= -3)
1791 pointers_compatible = DERIVED_FROM_P (rtyp, ltyp);
1794 /* If the pointers match modulo protocols, check for protocol conformance
1796 if (pointers_compatible)
1798 pointers_compatible = objc_compare_protocols (lcls, ltyp, rcls, rtyp,
1801 if (!pointers_compatible && argno == -3)
1802 pointers_compatible = objc_compare_protocols (rcls, rtyp, lcls, ltyp,
1806 if (!pointers_compatible)
1808 /* The two pointers are not exactly compatible. Issue a warning, unless
1809 we are performing a silent comparison, in which case return 'false'
1811 /* NB: For the time being, we shall make our warnings look like their
1812 C counterparts. In the future, we may wish to make them more
1820 warning (0, "comparison of distinct Objective-C types lacks a cast");
1824 warning (0, "initialization from distinct Objective-C type");
1828 warning (0, "assignment from distinct Objective-C type");
1832 warning (0, "distinct Objective-C type in return");
1836 warning (0, "passing argument %d of %qE from distinct "
1837 "Objective-C type", argno, callee);
1845 /* This routine is similar to objc_compare_types except that function-pointers are
1846 excluded. This is because, caller assumes that common types are of (id, Object*)
1847 variety and calls objc_common_type to obtain a common type. There is no commonolty
1848 between two function-pointers in this regard. */
1851 objc_have_common_type (tree ltyp, tree rtyp, int argno, tree callee)
1853 if (objc_compare_types (ltyp, rtyp, argno, callee))
1855 /* exclude function-pointer types. */
1858 ltyp = TREE_TYPE (ltyp); /* Remove indirections. */
1859 rtyp = TREE_TYPE (rtyp);
1861 while (POINTER_TYPE_P (ltyp) && POINTER_TYPE_P (rtyp));
1862 return !(TREE_CODE (ltyp) == FUNCTION_TYPE && TREE_CODE (rtyp) == FUNCTION_TYPE);
1867 /* Check if LTYP and RTYP have the same type qualifiers. If either type
1868 lives in the volatilized hash table, ignore the 'volatile' bit when
1869 making the comparison. */
1872 objc_type_quals_match (tree ltyp, tree rtyp)
1874 int lquals = TYPE_QUALS (ltyp), rquals = TYPE_QUALS (rtyp);
1876 if (lookup_attribute ("objc_volatilized", TYPE_ATTRIBUTES (ltyp)))
1877 lquals &= ~TYPE_QUAL_VOLATILE;
1879 if (lookup_attribute ("objc_volatilized", TYPE_ATTRIBUTES (rtyp)))
1880 rquals &= ~TYPE_QUAL_VOLATILE;
1882 return (lquals == rquals);
1886 /* Determine if CHILD is derived from PARENT. The routine assumes that
1887 both parameters are RECORD_TYPEs, and is non-reflexive. */
1890 objc_derived_from_p (tree parent, tree child)
1892 parent = TYPE_MAIN_VARIANT (parent);
1894 for (child = TYPE_MAIN_VARIANT (child);
1895 TYPE_BINFO (child) && BINFO_N_BASE_BINFOS (TYPE_BINFO (child));)
1897 child = TYPE_MAIN_VARIANT (BINFO_TYPE (BINFO_BASE_BINFO
1898 (TYPE_BINFO (child),
1901 if (child == parent)
1910 objc_build_component_ref (tree datum, tree component)
1912 /* If COMPONENT is NULL, the caller is referring to the anonymous
1913 base class field. */
1916 tree base = TYPE_FIELDS (TREE_TYPE (datum));
1918 return build3 (COMPONENT_REF, TREE_TYPE (base), datum, base, NULL_TREE);
1921 /* The 'build_component_ref' routine has been removed from the C++
1922 front-end, but 'finish_class_member_access_expr' seems to be
1923 a worthy substitute. */
1925 return finish_class_member_access_expr (datum, component, false,
1926 tf_warning_or_error);
1928 return build_component_ref (input_location, datum, component);
1932 /* Recursively copy inheritance information rooted at BINFO. To do this,
1933 we emulate the song and dance performed by cp/tree.c:copy_binfo(). */
1936 objc_copy_binfo (tree binfo)
1938 tree btype = BINFO_TYPE (binfo);
1939 tree binfo2 = make_tree_binfo (BINFO_N_BASE_BINFOS (binfo));
1943 BINFO_TYPE (binfo2) = btype;
1944 BINFO_OFFSET (binfo2) = BINFO_OFFSET (binfo);
1945 BINFO_BASE_ACCESSES (binfo2) = BINFO_BASE_ACCESSES (binfo);
1947 /* Recursively copy base binfos of BINFO. */
1948 for (ix = 0; BINFO_BASE_ITERATE (binfo, ix, base_binfo); ix++)
1950 tree base_binfo2 = objc_copy_binfo (base_binfo);
1952 BINFO_INHERITANCE_CHAIN (base_binfo2) = binfo2;
1953 BINFO_BASE_APPEND (binfo2, base_binfo2);
1959 /* Record superclass information provided in BASETYPE for ObjC class REF.
1960 This is loosely based on cp/decl.c:xref_basetypes(). */
1963 objc_xref_basetypes (tree ref, tree basetype)
1965 tree binfo = make_tree_binfo (basetype ? 1 : 0);
1967 TYPE_BINFO (ref) = binfo;
1968 BINFO_OFFSET (binfo) = size_zero_node;
1969 BINFO_TYPE (binfo) = ref;
1973 tree base_binfo = objc_copy_binfo (TYPE_BINFO (basetype));
1975 BINFO_INHERITANCE_CHAIN (base_binfo) = binfo;
1976 BINFO_BASE_ACCESSES (binfo) = VEC_alloc (tree, gc, 1);
1977 BINFO_BASE_APPEND (binfo, base_binfo);
1978 BINFO_BASE_ACCESS_APPEND (binfo, access_public_node);
1982 /* Called from finish_decl. */
1985 objc_check_decl (tree decl)
1987 tree type = TREE_TYPE (decl);
1989 if (TREE_CODE (type) != RECORD_TYPE)
1991 if (OBJC_TYPE_NAME (type) && (type = objc_is_class_name (OBJC_TYPE_NAME (type))))
1992 error ("statically allocated instance of Objective-C class %qE",
1997 objc_check_global_decl (tree decl)
1999 tree id = DECL_NAME (decl);
2000 if (objc_is_class_name (id) && global_bindings_p())
2001 error ("redeclaration of Objective-C class %qs", IDENTIFIER_POINTER (id));
2004 /* Return a non-volatalized version of TYPE. */
2007 objc_non_volatilized_type (tree type)
2009 if (lookup_attribute ("objc_volatilized", TYPE_ATTRIBUTES (type)))
2010 type = build_qualified_type (type, (TYPE_QUALS (type) & ~TYPE_QUAL_VOLATILE));
2014 /* Construct a PROTOCOLS-qualified variant of INTERFACE, where INTERFACE may
2015 either name an Objective-C class, or refer to the special 'id' or 'Class'
2016 types. If INTERFACE is not a valid ObjC type, just return it unchanged. */
2019 objc_get_protocol_qualified_type (tree interface, tree protocols)
2021 /* If INTERFACE is not provided, default to 'id'. */
2022 tree type = (interface ? objc_is_id (interface) : objc_object_type);
2023 bool is_ptr = (type != NULL_TREE);
2027 type = objc_is_class_name (interface);
2031 /* If looking at a typedef, retrieve the precise type it
2033 if (TREE_CODE (interface) == IDENTIFIER_NODE)
2034 interface = identifier_global_value (interface);
2036 type = ((interface && TREE_CODE (interface) == TYPE_DECL
2037 && DECL_ORIGINAL_TYPE (interface))
2038 ? DECL_ORIGINAL_TYPE (interface)
2039 : xref_tag (RECORD_TYPE, type));
2047 type = build_variant_type_copy (type);
2049 /* For pointers (i.e., 'id' or 'Class'), attach the protocol(s)
2053 tree orig_pointee_type = TREE_TYPE (type);
2054 TREE_TYPE (type) = build_variant_type_copy (orig_pointee_type);
2056 /* Set up the canonical type information. */
2057 TYPE_CANONICAL (type)
2058 = TYPE_CANONICAL (TYPE_POINTER_TO (orig_pointee_type));
2060 TYPE_POINTER_TO (TREE_TYPE (type)) = type;
2061 type = TREE_TYPE (type);
2064 /* Look up protocols and install in lang specific list. */
2065 DUP_TYPE_OBJC_INFO (type, TYPE_MAIN_VARIANT (type));
2066 TYPE_OBJC_PROTOCOL_LIST (type) = lookup_and_install_protocols (protocols);
2068 /* For RECORD_TYPEs, point to the @interface; for 'id' and 'Class',
2069 return the pointer to the new pointee variant. */
2071 type = TYPE_POINTER_TO (type);
2073 TYPE_OBJC_INTERFACE (type)
2074 = TYPE_OBJC_INTERFACE (TYPE_MAIN_VARIANT (type));
2080 /* Check for circular dependencies in protocols. The arguments are
2081 PROTO, the protocol to check, and LIST, a list of protocol it
2085 check_protocol_recursively (tree proto, tree list)
2089 for (p = list; p; p = TREE_CHAIN (p))
2091 tree pp = TREE_VALUE (p);
2093 if (TREE_CODE (pp) == IDENTIFIER_NODE)
2094 pp = lookup_protocol (pp);
2097 fatal_error ("protocol %qE has circular dependency",
2098 PROTOCOL_NAME (pp));
2100 check_protocol_recursively (proto, PROTOCOL_LIST (pp));
2104 /* Look up PROTOCOLS, and return a list of those that are found.
2105 If none are found, return NULL. */
2108 lookup_and_install_protocols (tree protocols)
2111 tree return_value = NULL_TREE;
2113 if (protocols == error_mark_node)
2116 for (proto = protocols; proto; proto = TREE_CHAIN (proto))
2118 tree ident = TREE_VALUE (proto);
2119 tree p = lookup_protocol (ident);
2122 return_value = chainon (return_value,
2123 build_tree_list (NULL_TREE, p));
2124 else if (ident != error_mark_node)
2125 error ("cannot find protocol declaration for %qE",
2129 return return_value;
2132 /* Create a declaration for field NAME of a given TYPE. */
2135 create_field_decl (tree type, const char *name)
2137 return build_decl (input_location,
2138 FIELD_DECL, get_identifier (name), type);
2141 /* Create a global, static declaration for variable NAME of a given TYPE. The
2142 finish_var_decl() routine will need to be called on it afterwards. */
2145 start_var_decl (tree type, const char *name)
2147 tree var = build_decl (input_location,
2148 VAR_DECL, get_identifier (name), type);
2150 TREE_STATIC (var) = 1;
2151 DECL_INITIAL (var) = error_mark_node; /* A real initializer is coming... */
2152 DECL_IGNORED_P (var) = 1;
2153 DECL_ARTIFICIAL (var) = 1;
2154 DECL_CONTEXT (var) = NULL_TREE;
2156 DECL_THIS_STATIC (var) = 1; /* squash redeclaration errors */
2162 /* Finish off the variable declaration created by start_var_decl(). */
2165 finish_var_decl (tree var, tree initializer)
2167 finish_decl (var, input_location, initializer, NULL_TREE, NULL_TREE);
2170 /* Find the decl for the constant string class reference. This is only
2171 used for the NeXT runtime. */
2174 setup_string_decl (void)
2179 /* %s in format will provide room for terminating null */
2180 length = strlen (STRING_OBJECT_GLOBAL_FORMAT)
2181 + strlen (constant_string_class_name);
2182 name = XNEWVEC (char, length);
2183 sprintf (name, STRING_OBJECT_GLOBAL_FORMAT,
2184 constant_string_class_name);
2185 constant_string_global_id = get_identifier (name);
2186 string_class_decl = lookup_name (constant_string_global_id);
2188 return string_class_decl;
2191 /* Purpose: "play" parser, creating/installing representations
2192 of the declarations that are required by Objective-C.
2196 type_spec--------->sc_spec
2197 (tree_list) (tree_list)
2200 identifier_node identifier_node */
2203 synth_module_prologue (void)
2206 enum debug_info_type save_write_symbols = write_symbols;
2207 const struct gcc_debug_hooks *const save_hooks = debug_hooks;
2209 /* Suppress outputting debug symbols, because
2210 dbxout_init hasn't been called yet. */
2211 write_symbols = NO_DEBUG;
2212 debug_hooks = &do_nothing_debug_hooks;
2215 push_lang_context (lang_name_c); /* extern "C" */
2218 /* The following are also defined in <objc/objc.h> and friends. */
2220 objc_object_id = get_identifier (TAG_OBJECT);
2221 objc_class_id = get_identifier (TAG_CLASS);
2223 objc_object_reference = xref_tag (RECORD_TYPE, objc_object_id);
2224 objc_class_reference = xref_tag (RECORD_TYPE, objc_class_id);
2226 objc_object_type = build_pointer_type (objc_object_reference);
2227 objc_class_type = build_pointer_type (objc_class_reference);
2229 objc_object_name = get_identifier (OBJECT_TYPEDEF_NAME);
2230 objc_class_name = get_identifier (CLASS_TYPEDEF_NAME);
2232 /* Declare the 'id' and 'Class' typedefs. */
2234 type = lang_hooks.decls.pushdecl (build_decl (input_location,
2238 TREE_NO_WARNING (type) = 1;
2239 type = lang_hooks.decls.pushdecl (build_decl (input_location,
2243 TREE_NO_WARNING (type) = 1;
2245 /* Forward-declare '@interface Protocol'. */
2247 type = get_identifier (PROTOCOL_OBJECT_CLASS_NAME);
2248 objc_declare_class (tree_cons (NULL_TREE, type, NULL_TREE));
2249 objc_protocol_type = build_pointer_type (xref_tag (RECORD_TYPE,
2252 /* Declare type of selector-objects that represent an operation name. */
2254 if (flag_next_runtime)
2255 /* `struct objc_selector *' */
2257 = build_pointer_type (xref_tag (RECORD_TYPE,
2258 get_identifier (TAG_SELECTOR)));
2260 /* `const struct objc_selector *' */
2262 = build_pointer_type
2263 (build_qualified_type (xref_tag (RECORD_TYPE,
2264 get_identifier (TAG_SELECTOR)),
2267 /* Declare receiver type used for dispatching messages to 'super'. */
2269 /* `struct objc_super *' */
2270 objc_super_type = build_pointer_type (xref_tag (RECORD_TYPE,
2271 get_identifier (TAG_SUPER)));
2273 /* Declare pointers to method and ivar lists. */
2274 objc_method_list_ptr = build_pointer_type
2275 (xref_tag (RECORD_TYPE,
2276 get_identifier (UTAG_METHOD_LIST)));
2277 objc_method_proto_list_ptr
2278 = build_pointer_type (xref_tag (RECORD_TYPE,
2279 get_identifier (UTAG_METHOD_PROTOTYPE_LIST)));
2280 objc_ivar_list_ptr = build_pointer_type
2281 (xref_tag (RECORD_TYPE,
2282 get_identifier (UTAG_IVAR_LIST)));
2284 /* TREE_NOTHROW is cleared for the message-sending functions,
2285 because the function that gets called can throw in Obj-C++, or
2286 could itself call something that can throw even in Obj-C. */
2288 if (flag_next_runtime)
2290 /* NB: In order to call one of the ..._stret (struct-returning)
2291 functions, the function *MUST* first be cast to a signature that
2292 corresponds to the actual ObjC method being invoked. This is
2293 what is done by the build_objc_method_call() routine below. */
2295 /* id objc_msgSend (id, SEL, ...); */
2296 /* id objc_msgSendNonNil (id, SEL, ...); */
2297 /* id objc_msgSend_stret (id, SEL, ...); */
2298 /* id objc_msgSendNonNil_stret (id, SEL, ...); */
2300 = build_varargs_function_type_list (objc_object_type,
2304 umsg_decl = add_builtin_function (TAG_MSGSEND,
2305 type, 0, NOT_BUILT_IN,
2307 umsg_nonnil_decl = add_builtin_function (TAG_MSGSEND_NONNIL,
2308 type, 0, NOT_BUILT_IN,
2310 umsg_stret_decl = add_builtin_function (TAG_MSGSEND_STRET,
2311 type, 0, NOT_BUILT_IN,
2313 umsg_nonnil_stret_decl = add_builtin_function (TAG_MSGSEND_NONNIL_STRET,
2314 type, 0, NOT_BUILT_IN,
2317 /* These can throw, because the function that gets called can throw
2318 in Obj-C++, or could itself call something that can throw even
2320 TREE_NOTHROW (umsg_decl) = 0;
2321 TREE_NOTHROW (umsg_nonnil_decl) = 0;
2322 TREE_NOTHROW (umsg_stret_decl) = 0;
2323 TREE_NOTHROW (umsg_nonnil_stret_decl) = 0;
2325 /* id objc_msgSend_Fast (id, SEL, ...)
2326 __attribute__ ((hard_coded_address (OFFS_MSGSEND_FAST))); */
2327 #ifdef OFFS_MSGSEND_FAST
2328 umsg_fast_decl = add_builtin_function (TAG_MSGSEND_FAST,
2329 type, 0, NOT_BUILT_IN,
2331 TREE_NOTHROW (umsg_fast_decl) = 0;
2332 DECL_ATTRIBUTES (umsg_fast_decl)
2333 = tree_cons (get_identifier ("hard_coded_address"),
2334 build_int_cst (NULL_TREE, OFFS_MSGSEND_FAST),
2337 /* No direct dispatch available. */
2338 umsg_fast_decl = umsg_decl;
2341 /* id objc_msgSendSuper (struct objc_super *, SEL, ...); */
2342 /* id objc_msgSendSuper_stret (struct objc_super *, SEL, ...); */
2344 = build_varargs_function_type_list (objc_object_type,
2348 umsg_super_decl = add_builtin_function (TAG_MSGSENDSUPER,
2349 type, 0, NOT_BUILT_IN,
2351 umsg_super_stret_decl = add_builtin_function (TAG_MSGSENDSUPER_STRET,
2352 type, 0, NOT_BUILT_IN, 0,
2354 TREE_NOTHROW (umsg_super_decl) = 0;
2355 TREE_NOTHROW (umsg_super_stret_decl) = 0;
2359 /* GNU runtime messenger entry points. */
2361 /* typedef id (*IMP)(id, SEL, ...); */
2363 build_varargs_function_type_list (objc_object_type,
2367 tree IMP_type = build_pointer_type (ftype);
2369 /* IMP objc_msg_lookup (id, SEL); */
2370 type = build_function_type_list (IMP_type,
2374 umsg_decl = add_builtin_function (TAG_MSGSEND,
2375 type, 0, NOT_BUILT_IN,
2377 TREE_NOTHROW (umsg_decl) = 0;
2379 /* IMP objc_msg_lookup_super (struct objc_super *, SEL); */
2381 = build_function_type_list (IMP_type,
2385 umsg_super_decl = add_builtin_function (TAG_MSGSENDSUPER,
2386 type, 0, NOT_BUILT_IN,
2388 TREE_NOTHROW (umsg_super_decl) = 0;
2390 /* The following GNU runtime entry point is called to initialize
2393 __objc_exec_class (void *); */
2395 = build_function_type_list (void_type_node,
2398 execclass_decl = add_builtin_function (TAG_EXECCLASS,
2399 type, 0, NOT_BUILT_IN,
2403 /* id objc_getClass (const char *); */
2405 type = build_function_type_list (objc_object_type,
2406 const_string_type_node,
2410 = add_builtin_function (TAG_GETCLASS, type, 0, NOT_BUILT_IN,
2413 /* id objc_getMetaClass (const char *); */
2415 objc_get_meta_class_decl
2416 = add_builtin_function (TAG_GETMETACLASS, type, 0, NOT_BUILT_IN, NULL, NULL_TREE);
2418 build_class_template ();
2419 build_super_template ();
2420 build_protocol_template ();
2421 build_category_template ();
2422 build_objc_exception_stuff ();
2424 if (flag_next_runtime)
2425 build_next_objc_exception_stuff ();
2427 /* static SEL _OBJC_SELECTOR_TABLE[]; */
2429 if (! flag_next_runtime)
2430 build_selector_table_decl ();
2432 /* Forward declare constant_string_id and constant_string_type. */
2433 if (!constant_string_class_name)
2434 constant_string_class_name = default_constant_string_class_name;
2436 constant_string_id = get_identifier (constant_string_class_name);
2437 objc_declare_class (tree_cons (NULL_TREE, constant_string_id, NULL_TREE));
2439 /* Pre-build the following entities - for speed/convenience. */
2440 self_id = get_identifier ("self");
2441 ucmd_id = get_identifier ("_cmd");
2443 /* Declare struct _objc_fast_enumeration_state { ... }; */
2444 build_fast_enumeration_state_template ();
2446 /* void objc_enumeration_mutation (id) */
2447 type = build_function_type (void_type_node,
2448 tree_cons (NULL_TREE, objc_object_type, NULL_TREE));
2449 objc_enumeration_mutation_decl
2450 = add_builtin_function (TAG_ENUMERATION_MUTATION, type, 0, NOT_BUILT_IN,
2452 TREE_NOTHROW (objc_enumeration_mutation_decl) = 0;
2455 pop_lang_context ();
2458 write_symbols = save_write_symbols;
2459 debug_hooks = save_hooks;
2462 /* Ensure that the ivar list for NSConstantString/NXConstantString
2463 (or whatever was specified via `-fconstant-string-class')
2464 contains fields at least as large as the following three, so that
2465 the runtime can stomp on them with confidence:
2467 struct STRING_OBJECT_CLASS_NAME
2471 unsigned int length;
2475 check_string_class_template (void)
2477 tree field_decl = objc_get_class_ivars (constant_string_id);
2479 #define AT_LEAST_AS_LARGE_AS(F, T) \
2480 (F && TREE_CODE (F) == FIELD_DECL \
2481 && (TREE_INT_CST_LOW (TYPE_SIZE (TREE_TYPE (F))) \
2482 >= TREE_INT_CST_LOW (TYPE_SIZE (T))))
2484 if (!AT_LEAST_AS_LARGE_AS (field_decl, ptr_type_node))
2487 field_decl = DECL_CHAIN (field_decl);
2488 if (!AT_LEAST_AS_LARGE_AS (field_decl, ptr_type_node))
2491 field_decl = DECL_CHAIN (field_decl);
2492 return AT_LEAST_AS_LARGE_AS (field_decl, unsigned_type_node);
2494 #undef AT_LEAST_AS_LARGE_AS
2497 /* Avoid calling `check_string_class_template ()' more than once. */
2498 static GTY(()) int string_layout_checked;
2500 /* Construct an internal string layout to be used as a template for
2501 creating NSConstantString/NXConstantString instances. */
2504 objc_build_internal_const_str_type (void)
2506 tree type = (*lang_hooks.types.make_type) (RECORD_TYPE);
2507 tree fields = build_decl (input_location,
2508 FIELD_DECL, NULL_TREE, ptr_type_node);
2509 tree field = build_decl (input_location,
2510 FIELD_DECL, NULL_TREE, ptr_type_node);
2512 DECL_CHAIN (field) = fields; fields = field;
2513 field = build_decl (input_location,
2514 FIELD_DECL, NULL_TREE, unsigned_type_node);
2515 DECL_CHAIN (field) = fields; fields = field;
2516 /* NB: The finish_builtin_struct() routine expects FIELD_DECLs in
2518 finish_builtin_struct (type, "__builtin_ObjCString",
2524 /* Custom build_string which sets TREE_TYPE! */
2527 my_build_string (int len, const char *str)
2529 return fix_string_type (build_string (len, str));
2532 /* Build a string with contents STR and length LEN and convert it to a
2536 my_build_string_pointer (int len, const char *str)
2538 tree string = my_build_string (len, str);
2539 tree ptrtype = build_pointer_type (TREE_TYPE (TREE_TYPE (string)));
2540 return build1 (ADDR_EXPR, ptrtype, string);
2544 string_hash (const void *ptr)
2546 const_tree const str = ((const struct string_descriptor *)ptr)->literal;
2547 const unsigned char *p = (const unsigned char *) TREE_STRING_POINTER (str);
2548 int i, len = TREE_STRING_LENGTH (str);
2551 for (i = 0; i < len; i++)
2552 h = ((h * 613) + p[i]);
2558 string_eq (const void *ptr1, const void *ptr2)
2560 const_tree const str1 = ((const struct string_descriptor *)ptr1)->literal;
2561 const_tree const str2 = ((const struct string_descriptor *)ptr2)->literal;
2562 int len1 = TREE_STRING_LENGTH (str1);
2564 return (len1 == TREE_STRING_LENGTH (str2)
2565 && !memcmp (TREE_STRING_POINTER (str1), TREE_STRING_POINTER (str2),
2569 /* Given a chain of STRING_CST's, build a static instance of
2570 NXConstantString which points at the concatenation of those
2571 strings. We place the string object in the __string_objects
2572 section of the __OBJC segment. The Objective-C runtime will
2573 initialize the isa pointers of the string objects to point at the
2574 NXConstantString class object. */
2577 objc_build_string_object (tree string)
2579 tree constant_string_class;
2582 struct string_descriptor *desc, key;
2585 /* Prep the string argument. */
2586 string = fix_string_type (string);
2587 TREE_SET_CODE (string, STRING_CST);
2588 length = TREE_STRING_LENGTH (string) - 1;
2590 /* The target may have different ideas on how to construct an ObjC string
2591 literal. On Darwin (Mac OS X), for example, we may wish to obtain a
2592 constant CFString reference instead.
2593 At present, this is only supported for the NeXT runtime. */
2594 if (flag_next_runtime && targetcm.objc_construct_string)
2596 tree constructor = (*targetcm.objc_construct_string) (string);
2598 return build1 (NOP_EXPR, objc_object_type, constructor);
2601 /* Check whether the string class being used actually exists and has the
2602 correct ivar layout. */
2603 if (!string_layout_checked)
2605 string_layout_checked = -1;
2606 constant_string_class = lookup_interface (constant_string_id);
2607 internal_const_str_type = objc_build_internal_const_str_type ();
2609 if (!constant_string_class
2610 || !(constant_string_type
2611 = CLASS_STATIC_TEMPLATE (constant_string_class)))
2612 error ("cannot find interface declaration for %qE",
2613 constant_string_id);
2614 /* The NSConstantString/NXConstantString ivar layout is now known. */
2615 else if (!check_string_class_template ())
2616 error ("interface %qE does not have valid constant string layout",
2617 constant_string_id);
2618 /* For the NeXT runtime, we can generate a literal reference
2619 to the string class, don't need to run a constructor. */
2620 else if (flag_next_runtime && !setup_string_decl ())
2621 error ("cannot find reference tag for class %qE",
2622 constant_string_id);
2625 string_layout_checked = 1; /* Success! */
2626 add_class_reference (constant_string_id);
2630 if (string_layout_checked == -1)
2631 return error_mark_node;
2633 /* Perhaps we already constructed a constant string just like this one? */
2634 key.literal = string;
2635 loc = htab_find_slot (string_htab, &key, INSERT);
2636 desc = (struct string_descriptor *) *loc;
2640 tree var, constructor;
2641 VEC(constructor_elt,gc) *v = NULL;
2642 *loc = desc = ggc_alloc_string_descriptor ();
2643 desc->literal = string;
2645 /* GNU: (NXConstantString *) & ((__builtin_ObjCString) { NULL, string, length }) */
2646 /* NeXT: (NSConstantString *) & ((__builtin_ObjCString) { isa, string, length }) */
2647 fields = TYPE_FIELDS (internal_const_str_type);
2648 CONSTRUCTOR_APPEND_ELT (v, fields,
2650 ? build_unary_op (input_location,
2651 ADDR_EXPR, string_class_decl, 0)
2652 : build_int_cst (NULL_TREE, 0));
2653 fields = DECL_CHAIN (fields);
2654 CONSTRUCTOR_APPEND_ELT (v, fields,
2655 build_unary_op (input_location,
2656 ADDR_EXPR, string, 1));
2657 fields = DECL_CHAIN (fields);
2658 CONSTRUCTOR_APPEND_ELT (v, fields, build_int_cst (NULL_TREE, length));
2659 constructor = objc_build_constructor (internal_const_str_type, v);
2661 if (!flag_next_runtime)
2663 = objc_add_static_instance (constructor, constant_string_type);
2666 var = build_decl (input_location,
2667 CONST_DECL, NULL, TREE_TYPE (constructor));
2668 DECL_INITIAL (var) = constructor;
2669 TREE_STATIC (var) = 1;
2670 pushdecl_top_level (var);
2673 desc->constructor = constructor;
2676 addr = convert (build_pointer_type (constant_string_type),
2677 build_unary_op (input_location,
2678 ADDR_EXPR, desc->constructor, 1));
2683 /* Declare a static instance of CLASS_DECL initialized by CONSTRUCTOR. */
2685 static GTY(()) int num_static_inst;
2688 objc_add_static_instance (tree constructor, tree class_decl)
2693 /* Find the list of static instances for the CLASS_DECL. Create one if
2695 for (chain = &objc_static_instances;
2696 *chain && TREE_VALUE (*chain) != class_decl;
2697 chain = &TREE_CHAIN (*chain));
2700 *chain = tree_cons (NULL_TREE, class_decl, NULL_TREE);
2701 add_objc_string (OBJC_TYPE_NAME (class_decl), class_names);
2704 sprintf (buf, "_OBJC_INSTANCE_%d", num_static_inst++);
2705 decl = build_decl (input_location,
2706 VAR_DECL, get_identifier (buf), class_decl);
2707 TREE_STATIC (decl) = 1;
2708 DECL_ARTIFICIAL (decl) = 1;
2709 TREE_USED (decl) = 1;
2710 DECL_INITIAL (decl) = constructor;
2712 /* We may be writing something else just now.
2713 Postpone till end of input. */
2714 DECL_DEFER_OUTPUT (decl) = 1;
2715 pushdecl_top_level (decl);
2716 rest_of_decl_compilation (decl, 1, 0);
2718 /* Add the DECL to the head of this CLASS' list. */
2719 TREE_PURPOSE (*chain) = tree_cons (NULL_TREE, decl, TREE_PURPOSE (*chain));
2724 /* Build a static constant CONSTRUCTOR
2725 with type TYPE and elements ELTS. */
2728 objc_build_constructor (tree type, VEC(constructor_elt,gc) *elts)
2730 tree constructor = build_constructor (type, elts);
2732 TREE_CONSTANT (constructor) = 1;
2733 TREE_STATIC (constructor) = 1;
2734 TREE_READONLY (constructor) = 1;
2737 /* Adjust for impedance mismatch. We should figure out how to build
2738 CONSTRUCTORs that consistently please both the C and C++ gods. */
2739 if (!VEC_index (constructor_elt, elts, 0)->index)
2740 TREE_TYPE (constructor) = init_list_type_node;
2746 /* Take care of defining and initializing _OBJC_SYMBOLS. */
2748 /* Predefine the following data type:
2756 void *defs[cls_def_cnt + cat_def_cnt];
2760 build_objc_symtab_template (void)
2762 tree fields, *chain = NULL;
2764 objc_symtab_template = objc_start_struct (get_identifier (UTAG_SYMTAB));
2766 /* long sel_ref_cnt; */
2767 fields = add_field_decl (long_integer_type_node, "sel_ref_cnt", &chain);
2770 add_field_decl (build_pointer_type (objc_selector_type), "refs", &chain);
2772 /* short cls_def_cnt; */
2773 add_field_decl (short_integer_type_node, "cls_def_cnt", &chain);
2775 /* short cat_def_cnt; */
2776 add_field_decl (short_integer_type_node, "cat_def_cnt", &chain);
2778 if (imp_count || cat_count || !flag_next_runtime)
2780 /* void *defs[imp_count + cat_count (+ 1)]; */
2781 /* NB: The index is one less than the size of the array. */
2782 int index = imp_count + cat_count + (flag_next_runtime ? -1: 0);
2783 tree array_type = build_sized_array_type (ptr_type_node, index + 1);
2784 add_field_decl (array_type, "defs", &chain);
2787 objc_finish_struct (objc_symtab_template, fields);
2790 /* Create the initial value for the `defs' field of _objc_symtab.
2791 This is a CONSTRUCTOR. */
2794 init_def_list (tree type)
2797 struct imp_entry *impent;
2798 VEC(constructor_elt,gc) *v = NULL;
2801 for (impent = imp_list; impent; impent = impent->next)
2803 if (TREE_CODE (impent->imp_context) == CLASS_IMPLEMENTATION_TYPE)
2805 expr = build_unary_op (input_location,
2806 ADDR_EXPR, impent->class_decl, 0);
2807 CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, expr);
2812 for (impent = imp_list; impent; impent = impent->next)
2814 if (TREE_CODE (impent->imp_context) == CATEGORY_IMPLEMENTATION_TYPE)
2816 expr = build_unary_op (input_location,
2817 ADDR_EXPR, impent->class_decl, 0);
2818 CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, expr);
2822 if (!flag_next_runtime)
2824 /* statics = { ..., _OBJC_STATIC_INSTANCES, ... } */
2825 if (static_instances_decl)
2826 expr = build_unary_op (input_location,
2827 ADDR_EXPR, static_instances_decl, 0);
2829 expr = integer_zero_node;
2831 CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, expr);
2834 return objc_build_constructor (type, v);
2837 /* Construct the initial value for all of _objc_symtab. */
2840 init_objc_symtab (tree type)
2842 VEC(constructor_elt,gc) *v = NULL;
2844 /* sel_ref_cnt = { ..., 5, ... } */
2846 CONSTRUCTOR_APPEND_ELT (v, NULL_TREE,
2847 build_int_cst (long_integer_type_node, 0));
2849 /* refs = { ..., _OBJC_SELECTOR_TABLE, ... } */
2851 if (flag_next_runtime || ! sel_ref_chain)
2852 CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, convert (
2853 build_pointer_type (objc_selector_type),
2854 integer_zero_node));
2857 tree expr = build_unary_op (input_location, ADDR_EXPR,
2858 UOBJC_SELECTOR_TABLE_decl, 1);
2860 CONSTRUCTOR_APPEND_ELT (v, NULL_TREE,
2861 convert (build_pointer_type (objc_selector_type),
2865 /* cls_def_cnt = { ..., 5, ... } */
2867 CONSTRUCTOR_APPEND_ELT (v, NULL_TREE,
2868 build_int_cst (short_integer_type_node, imp_count));
2870 /* cat_def_cnt = { ..., 5, ... } */
2872 CONSTRUCTOR_APPEND_ELT (v, NULL_TREE,
2873 build_int_cst (short_integer_type_node, cat_count));
2875 /* cls_def = { ..., { &Foo, &Bar, ...}, ... } */
2877 if (imp_count || cat_count || !flag_next_runtime)
2880 tree field = TYPE_FIELDS (type);
2881 field = DECL_CHAIN (DECL_CHAIN (DECL_CHAIN (DECL_CHAIN (field))));
2883 CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, init_def_list (TREE_TYPE (field)));
2886 return objc_build_constructor (type, v);
2889 /* Generate forward declarations for metadata such as
2890 'OBJC_CLASS_...'. */
2893 build_metadata_decl (const char *name, tree type)
2897 /* struct TYPE NAME_<name>; */
2898 decl = start_var_decl (type, synth_id_with_class_suffix
2900 objc_implementation_context));
2905 /* Push forward-declarations of all the categories so that
2906 init_def_list can use them in a CONSTRUCTOR. */
2909 forward_declare_categories (void)
2911 struct imp_entry *impent;
2912 tree sav = objc_implementation_context;
2914 for (impent = imp_list; impent; impent = impent->next)
2916 if (TREE_CODE (impent->imp_context) == CATEGORY_IMPLEMENTATION_TYPE)
2918 /* Set an invisible arg to synth_id_with_class_suffix. */
2919 objc_implementation_context = impent->imp_context;
2920 /* extern struct objc_category _OBJC_CATEGORY_<name>; */
2921 impent->class_decl = build_metadata_decl ("_OBJC_CATEGORY",
2922 objc_category_template);
2925 objc_implementation_context = sav;
2928 /* Create the declaration of _OBJC_SYMBOLS, with type `struct _objc_symtab'
2929 and initialized appropriately. */
2932 generate_objc_symtab_decl (void)
2935 build_objc_symtab_template ();
2936 UOBJC_SYMBOLS_decl = start_var_decl (objc_symtab_template, "_OBJC_SYMBOLS");
2937 finish_var_decl (UOBJC_SYMBOLS_decl,
2938 init_objc_symtab (TREE_TYPE (UOBJC_SYMBOLS_decl)));
2942 init_module_descriptor (tree type)
2945 VEC(constructor_elt,gc) *v = NULL;
2947 /* version = { 1, ... } */
2949 expr = build_int_cst (long_integer_type_node, OBJC_VERSION);
2950 CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, expr);
2952 /* size = { ..., sizeof (struct _objc_module), ... } */
2954 expr = convert (long_integer_type_node,
2955 size_in_bytes (objc_module_template));
2956 CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, expr);
2958 /* Don't provide any file name for security reasons. */
2959 /* name = { ..., "", ... } */
2961 expr = add_objc_string (get_identifier (""), class_names);
2962 CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, expr);
2964 /* symtab = { ..., _OBJC_SYMBOLS, ... } */
2966 if (UOBJC_SYMBOLS_decl)
2967 expr = build_unary_op (input_location,
2968 ADDR_EXPR, UOBJC_SYMBOLS_decl, 0);
2970 expr = null_pointer_node;
2971 CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, expr);
2973 return objc_build_constructor (type, v);
2976 /* Write out the data structures to describe Objective C classes defined.
2978 struct _objc_module { ... } _OBJC_MODULE = { ... }; */
2981 build_module_descriptor (void)
2983 tree decls, *chain = NULL;
2986 push_lang_context (lang_name_c); /* extern "C" */
2989 objc_module_template = objc_start_struct (get_identifier (UTAG_MODULE));
2992 decls = add_field_decl (long_integer_type_node, "version", &chain);
2995 add_field_decl (long_integer_type_node, "size", &chain);
2998 add_field_decl (string_type_node, "name", &chain);
3000 /* struct _objc_symtab *symtab; */
3001 add_field_decl (build_pointer_type (xref_tag (RECORD_TYPE,
3002 get_identifier (UTAG_SYMTAB))),
3005 objc_finish_struct (objc_module_template, decls);
3007 /* Create an instance of "_objc_module". */
3008 UOBJC_MODULES_decl = start_var_decl (objc_module_template, "_OBJC_MODULES");
3009 /* This is the root of the metadata for defined classes and categories, it
3010 is referenced by the runtime and, therefore, needed. */
3011 DECL_PRESERVE_P (UOBJC_MODULES_decl) = 1;
3012 finish_var_decl (UOBJC_MODULES_decl,
3013 init_module_descriptor (TREE_TYPE (UOBJC_MODULES_decl)));
3016 pop_lang_context ();
3020 /* The GNU runtime requires us to provide a static initializer function
3023 static void __objc_gnu_init (void) {
3024 __objc_exec_class (&L_OBJC_MODULES);
3028 build_module_initializer_routine (void)
3033 push_lang_context (lang_name_c); /* extern "C" */
3036 objc_push_parm (build_decl (input_location,
3037 PARM_DECL, NULL_TREE, void_type_node));
3039 objc_start_function (get_identifier (TAG_GNUINIT),
3040 build_function_type_list (void_type_node, NULL_TREE),
3041 NULL_TREE, NULL_TREE);
3043 objc_start_function (get_identifier (TAG_GNUINIT),
3044 build_function_type_list (void_type_node, NULL_TREE),
3045 NULL_TREE, objc_get_parm_info (0));
3047 body = c_begin_compound_stmt (true);
3048 add_stmt (build_function_call
3053 build_unary_op (input_location, ADDR_EXPR,
3054 UOBJC_MODULES_decl, 0))));
3055 add_stmt (c_end_compound_stmt (input_location, body, true));
3057 TREE_PUBLIC (current_function_decl) = 0;
3060 /* For Objective-C++, we will need to call __objc_gnu_init
3061 from objc_generate_static_init_call() below. */
3062 DECL_STATIC_CONSTRUCTOR (current_function_decl) = 1;
3065 GNU_INIT_decl = current_function_decl;
3069 pop_lang_context ();
3074 /* Return 1 if the __objc_gnu_init function has been synthesized and needs
3075 to be called by the module initializer routine. */
3078 objc_static_init_needed_p (void)
3080 return (GNU_INIT_decl != NULL_TREE);
3083 /* Generate a call to the __objc_gnu_init initializer function. */
3086 objc_generate_static_init_call (tree ctors ATTRIBUTE_UNUSED)
3088 add_stmt (build_stmt (input_location, EXPR_STMT,
3089 build_function_call (input_location,
3090 GNU_INIT_decl, NULL_TREE)));
3094 #endif /* OBJCPLUS */
3096 /* Return the DECL of the string IDENT in the SECTION. */
3099 get_objc_string_decl (tree ident, enum string_section section)
3106 chain = class_names_chain;
3108 case meth_var_names:
3109 chain = meth_var_names_chain;
3111 case meth_var_types:
3112 chain = meth_var_types_chain;
3118 for (; chain != 0; chain = TREE_CHAIN (chain))
3119 if (TREE_VALUE (chain) == ident)
3120 return (TREE_PURPOSE (chain));
3126 /* Output references to all statically allocated objects. Return the DECL
3127 for the array built. */
3130 generate_static_references (void)
3132 tree expr = NULL_TREE;
3133 tree class_name, klass, decl;
3134 tree cl_chain, in_chain, type
3135 = build_array_type (build_pointer_type (void_type_node), NULL_TREE);
3136 int num_inst, num_class;
3138 VEC(constructor_elt,gc) *decls = NULL;
3140 if (flag_next_runtime)
3143 for (cl_chain = objc_static_instances, num_class = 0;
3144 cl_chain; cl_chain = TREE_CHAIN (cl_chain), num_class++)
3146 VEC(constructor_elt,gc) *v = NULL;
3148 for (num_inst = 0, in_chain = TREE_PURPOSE (cl_chain);
3149 in_chain; num_inst++, in_chain = TREE_CHAIN (in_chain));
3151 sprintf (buf, "_OBJC_STATIC_INSTANCES_%d", num_class);
3152 decl = start_var_decl (type, buf);
3154 /* Output {class_name, ...}. */
3155 klass = TREE_VALUE (cl_chain);
3156 class_name = get_objc_string_decl (OBJC_TYPE_NAME (klass), class_names);
3157 CONSTRUCTOR_APPEND_ELT (v, NULL_TREE,
3158 build_unary_op (input_location,
3159 ADDR_EXPR, class_name, 1));
3161 /* Output {..., instance, ...}. */
3162 for (in_chain = TREE_PURPOSE (cl_chain);
3163 in_chain; in_chain = TREE_CHAIN (in_chain))
3165 expr = build_unary_op (input_location,
3166 ADDR_EXPR, TREE_VALUE (in_chain), 1);
3167 CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, expr);
3170 /* Output {..., NULL}. */
3171 CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, build_int_cst (NULL_TREE, 0));
3173 expr = objc_build_constructor (TREE_TYPE (decl), v);
3174 finish_var_decl (decl, expr);
3175 CONSTRUCTOR_APPEND_ELT (decls, NULL_TREE,
3176 build_unary_op (input_location,
3177 ADDR_EXPR, decl, 1));
3180 CONSTRUCTOR_APPEND_ELT (decls, NULL_TREE, build_int_cst (NULL_TREE, 0));
3181 expr = objc_build_constructor (type, decls);
3182 static_instances_decl = start_var_decl (type, "_OBJC_STATIC_INSTANCES");
3183 finish_var_decl (static_instances_decl, expr);
3186 static GTY(()) int selector_reference_idx;
3189 build_selector_reference_decl (void)
3194 sprintf (buf, "_OBJC_SELECTOR_REFERENCES_%d", selector_reference_idx++);
3195 decl = start_var_decl (objc_selector_type, buf);
3201 build_selector_table_decl (void)
3205 if (flag_typed_selectors)
3207 build_selector_template ();
3208 temp = build_array_type (objc_selector_template, NULL_TREE);
3211 temp = build_array_type (objc_selector_type, NULL_TREE);
3213 UOBJC_SELECTOR_TABLE_decl = start_var_decl (temp, "_OBJC_SELECTOR_TABLE");
3216 /* Just a handy wrapper for add_objc_string. */
3219 build_selector (tree ident)
3221 return convert (objc_selector_type,
3222 add_objc_string (ident, meth_var_names));
3225 /* Used only by build_*_selector_translation_table (). */
3227 diagnose_missing_method (tree meth, location_t here)
3231 for (method_chain = meth_var_names_chain;
3233 method_chain = TREE_CHAIN (method_chain))
3235 if (TREE_VALUE (method_chain) == meth)
3243 warning_at (here, 0, "creating selector for nonexistent method %qE",
3248 build_next_selector_translation_table (void)
3251 for (chain = sel_ref_chain; chain; chain = TREE_CHAIN (chain))
3254 tree decl = TREE_PURPOSE (chain);
3255 if (warn_selector && objc_implementation_context)
3259 loc = DECL_SOURCE_LOCATION (decl);
3261 loc = input_location;
3262 diagnose_missing_method (TREE_VALUE (chain), loc);
3265 expr = build_selector (TREE_VALUE (chain));
3269 /* Entries of this form are used for references to methods.
3270 The runtime re-writes these on start-up, but the compiler can't see
3271 that and optimizes it away unless we force it. */
3272 DECL_PRESERVE_P (decl) = 1;
3273 finish_var_decl (decl, expr);
3279 build_gnu_selector_translation_table (void)
3283 tree decl = NULL_TREE;*/
3284 VEC(constructor_elt,gc) *inits = NULL;
3286 for (chain = sel_ref_chain; chain; chain = TREE_CHAIN (chain))
3290 if (warn_selector && objc_implementation_context)
3291 diagnose_missing_method (TREE_VALUE (chain), input_location);
3293 expr = build_selector (TREE_VALUE (chain));
3294 /* add one for the '\0' character
3295 offset += IDENTIFIER_LENGTH (TREE_VALUE (chain)) + 1;*/
3298 if (flag_typed_selectors)
3300 VEC(constructor_elt,gc) *v = NULL;
3301 tree encoding = get_proto_encoding (TREE_PURPOSE (chain));
3302 CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, expr);
3303 CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, encoding);
3304 expr = objc_build_constructor (objc_selector_template, v);
3307 CONSTRUCTOR_APPEND_ELT (inits, NULL_TREE, expr);
3309 } /* each element in the chain */
3312 /* Cause the selector table (previously forward-declared)
3313 to be actually output. */
3316 if (flag_typed_selectors)
3318 VEC(constructor_elt,gc) *v = NULL;
3319 CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, integer_zero_node);
3320 CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, integer_zero_node);
3321 expr = objc_build_constructor (objc_selector_template, v);
3324 expr = integer_zero_node;
3326 CONSTRUCTOR_APPEND_ELT (inits, NULL_TREE, expr);
3327 expr = objc_build_constructor (TREE_TYPE (UOBJC_SELECTOR_TABLE_decl),
3329 finish_var_decl (UOBJC_SELECTOR_TABLE_decl, expr);
3334 get_proto_encoding (tree proto)
3339 if (! METHOD_ENCODING (proto))
3341 encoding = encode_method_prototype (proto);
3342 METHOD_ENCODING (proto) = encoding;
3345 encoding = METHOD_ENCODING (proto);
3347 return add_objc_string (encoding, meth_var_types);
3350 return build_int_cst (NULL_TREE, 0);
3353 /* sel_ref_chain is a list whose "value" fields will be instances of
3354 identifier_node that represent the selector. LOC is the location of
3358 build_typed_selector_reference (location_t loc, tree ident, tree prototype)
3360 tree *chain = &sel_ref_chain;
3366 if (TREE_PURPOSE (*chain) == prototype && TREE_VALUE (*chain) == ident)
3367 goto return_at_index;
3370 chain = &TREE_CHAIN (*chain);
3373 *chain = tree_cons (prototype, ident, NULL_TREE);
3376 expr = build_unary_op (loc, ADDR_EXPR,
3377 build_array_ref (loc, UOBJC_SELECTOR_TABLE_decl,
3378 build_int_cst (NULL_TREE, index)),
3380 return convert (objc_selector_type, expr);
3384 build_selector_reference (location_t loc, tree ident)
3386 tree *chain = &sel_ref_chain;
3392 if (TREE_VALUE (*chain) == ident)
3393 return (flag_next_runtime
3394 ? TREE_PURPOSE (*chain)
3395 : build_array_ref (loc, UOBJC_SELECTOR_TABLE_decl,
3396 build_int_cst (NULL_TREE, index)));
3399 chain = &TREE_CHAIN (*chain);
3402 expr = (flag_next_runtime ? build_selector_reference_decl (): NULL_TREE);
3404 *chain = tree_cons (expr, ident, NULL_TREE);
3406 return (flag_next_runtime
3408 : build_array_ref (loc, UOBJC_SELECTOR_TABLE_decl,
3409 build_int_cst (NULL_TREE, index)));
3412 static GTY(()) int class_reference_idx;
3415 build_class_reference_decl (void)
3420 sprintf (buf, "_OBJC_CLASS_REFERENCES_%d", class_reference_idx++);
3421 decl = start_var_decl (objc_class_type, buf);
3426 /* Create a class reference, but don't create a variable to reference
3430 add_class_reference (tree ident)
3434 if ((chain = cls_ref_chain))
3439 if (ident == TREE_VALUE (chain))
3443 chain = TREE_CHAIN (chain);
3447 /* Append to the end of the list */
3448 TREE_CHAIN (tail) = tree_cons (NULL_TREE, ident, NULL_TREE);
3451 cls_ref_chain = tree_cons (NULL_TREE, ident, NULL_TREE);
3454 /* Get a class reference, creating it if necessary. Also create the
3455 reference variable. */
3458 objc_get_class_reference (tree ident)
3460 tree orig_ident = (DECL_P (ident)
3463 ? OBJC_TYPE_NAME (ident)
3465 bool local_scope = false;
3468 if (processing_template_decl)
3469 /* Must wait until template instantiation time. */
3470 return build_min_nt (CLASS_REFERENCE_EXPR, ident);
3473 if (TREE_CODE (ident) == TYPE_DECL)
3474 ident = (DECL_ORIGINAL_TYPE (ident)
3475 ? DECL_ORIGINAL_TYPE (ident)
3476 : TREE_TYPE (ident));
3480 && CP_TYPE_CONTEXT (ident) != global_namespace)
3484 if (local_scope || !(ident = objc_is_class_name (ident)))
3486 error ("%qE is not an Objective-C class name or alias",
3488 return error_mark_node;
3491 if (flag_next_runtime && !flag_zero_link)
3496 for (chain = &cls_ref_chain; *chain; chain = &TREE_CHAIN (*chain))
3497 if (TREE_VALUE (*chain) == ident)
3499 if (! TREE_PURPOSE (*chain))
3500 TREE_PURPOSE (*chain) = build_class_reference_decl ();
3502 return TREE_PURPOSE (*chain);
3505 decl = build_class_reference_decl ();
3506 *chain = tree_cons (decl, ident, NULL_TREE);
3513 add_class_reference (ident);
3515 params = build_tree_list (NULL_TREE,
3516 my_build_string_pointer
3517 (IDENTIFIER_LENGTH (ident) + 1,
3518 IDENTIFIER_POINTER (ident)));
3520 assemble_external (objc_get_class_decl);
3521 return build_function_call (input_location, objc_get_class_decl, params);
3525 /* For each string section we have a chain which maps identifier nodes
3526 to decls for the strings. */
3528 static GTY(()) int class_names_idx;
3529 static GTY(()) int meth_var_names_idx;
3530 static GTY(()) int meth_var_types_idx;
3533 add_objc_string (tree ident, enum string_section section)
3535 tree *chain, decl, type, string_expr;
3542 chain = &class_names_chain;
3543 sprintf (buf, "_OBJC_CLASS_NAME_%d", class_names_idx++);
3545 case meth_var_names:
3546 chain = &meth_var_names_chain;
3547 sprintf (buf, "_OBJC_METH_VAR_NAME_%d", meth_var_names_idx++);
3549 case meth_var_types:
3550 chain = &meth_var_types_chain;
3551 sprintf (buf, "_OBJC_METH_VAR_TYPE_%d", meth_var_types_idx++);
3559 if (TREE_VALUE (*chain) == ident)
3560 return convert (string_type_node,
3561 build_unary_op (input_location,
3562 ADDR_EXPR, TREE_PURPOSE (*chain), 1));
3564 chain = &TREE_CHAIN (*chain);
3567 type = build_sized_array_type (char_type_node, IDENTIFIER_LENGTH (ident) + 1);
3568 decl = start_var_decl (type, buf);
3569 string_expr = my_build_string (IDENTIFIER_LENGTH (ident) + 1,
3570 IDENTIFIER_POINTER (ident));
3571 TREE_CONSTANT (decl) = 1;
3572 finish_var_decl (decl, string_expr);
3574 *chain = tree_cons (decl, ident, NULL_TREE);
3576 return convert (string_type_node, build_unary_op (input_location,
3577 ADDR_EXPR, decl, 1));
3581 objc_declare_alias (tree alias_ident, tree class_ident)
3583 tree underlying_class;
3586 if (current_namespace != global_namespace) {
3587 error ("Objective-C declarations may only appear in global scope");
3589 #endif /* OBJCPLUS */
3591 if (!(underlying_class = objc_is_class_name (class_ident)))
3592 warning (0, "cannot find class %qE", class_ident);
3593 else if (objc_is_class_name (alias_ident))
3594 warning (0, "class %qE already exists", alias_ident);
3597 /* Implement @compatibility_alias as a typedef. */
3599 push_lang_context (lang_name_c); /* extern "C" */
3601 lang_hooks.decls.pushdecl (build_decl
3605 xref_tag (RECORD_TYPE, underlying_class)));
3607 pop_lang_context ();
3609 hash_class_name_enter (als_name_hash_list, alias_ident,
3615 objc_declare_class (tree ident_list)
3619 if (current_namespace != global_namespace) {
3620 error ("Objective-C declarations may only appear in global scope");
3622 #endif /* OBJCPLUS */
3624 for (list = ident_list; list; list = TREE_CHAIN (list))
3626 tree ident = TREE_VALUE (list);
3628 if (! objc_is_class_name (ident))
3630 tree record = lookup_name (ident), type = record;
3634 if (TREE_CODE (record) == TYPE_DECL)
3635 type = DECL_ORIGINAL_TYPE (record) ?
3636 DECL_ORIGINAL_TYPE (record) :
3639 if (!TYPE_HAS_OBJC_INFO (type)
3640 || !TYPE_OBJC_INTERFACE (type))
3642 error ("%qE redeclared as different kind of symbol",
3644 error ("previous declaration of %q+D",
3649 record = xref_tag (RECORD_TYPE, ident);
3650 INIT_TYPE_OBJC_INFO (record);
3651 TYPE_OBJC_INTERFACE (record) = ident;
3652 hash_class_name_enter (cls_name_hash_list, ident, NULL_TREE);
3658 objc_is_class_name (tree ident)
3662 if (ident && TREE_CODE (ident) == IDENTIFIER_NODE
3663 && identifier_global_value (ident))
3664 ident = identifier_global_value (ident);
3665 while (ident && TREE_CODE (ident) == TYPE_DECL && DECL_ORIGINAL_TYPE (ident))
3666 ident = OBJC_TYPE_NAME (DECL_ORIGINAL_TYPE (ident));
3668 if (ident && TREE_CODE (ident) == RECORD_TYPE)
3669 ident = OBJC_TYPE_NAME (ident);
3671 if (ident && TREE_CODE (ident) == TYPE_DECL)
3673 tree type = TREE_TYPE (ident);
3674 if (type && TREE_CODE (type) == TEMPLATE_TYPE_PARM)
3676 ident = DECL_NAME (ident);
3679 if (!ident || TREE_CODE (ident) != IDENTIFIER_NODE)
3682 if (lookup_interface (ident))
3685 target = hash_class_name_lookup (cls_name_hash_list, ident);
3689 target = hash_class_name_lookup (als_name_hash_list, ident);
3692 gcc_assert (target->list && target->list->value);
3693 return target->list->value;
3699 /* Check whether TYPE is either 'id' or 'Class'. */
3702 objc_is_id (tree type)
3704 if (type && TREE_CODE (type) == IDENTIFIER_NODE
3705 && identifier_global_value (type))
3706 type = identifier_global_value (type);
3708 if (type && TREE_CODE (type) == TYPE_DECL)
3709 type = TREE_TYPE (type);
3711 /* NB: This function may be called before the ObjC front-end has
3712 been initialized, in which case OBJC_OBJECT_TYPE will (still) be NULL. */
3713 return (objc_object_type && type
3714 && (IS_ID (type) || IS_CLASS (type) || IS_SUPER (type))
3719 /* Check whether TYPE is either 'id', 'Class', or a pointer to an ObjC
3720 class instance. This is needed by other parts of the compiler to
3721 handle ObjC types gracefully. */
3724 objc_is_object_ptr (tree type)
3728 type = TYPE_MAIN_VARIANT (type);
3729 if (!POINTER_TYPE_P (type))
3732 ret = objc_is_id (type);
3734 ret = objc_is_class_name (TREE_TYPE (type));
3740 objc_is_gcable_type (tree type, int or_strong_p)
3746 if (objc_is_id (TYPE_MAIN_VARIANT (type)))
3748 if (or_strong_p && lookup_attribute ("objc_gc", TYPE_ATTRIBUTES (type)))
3750 if (TREE_CODE (type) != POINTER_TYPE && TREE_CODE (type) != INDIRECT_REF)
3752 type = TREE_TYPE (type);
3753 if (TREE_CODE (type) != RECORD_TYPE)
3755 name = TYPE_NAME (type);
3756 return (objc_is_class_name (name) != NULL_TREE);
3760 objc_substitute_decl (tree expr, tree oldexpr, tree newexpr)
3762 if (expr == oldexpr)
3765 switch (TREE_CODE (expr))
3768 return objc_build_component_ref
3769 (objc_substitute_decl (TREE_OPERAND (expr, 0),
3772 DECL_NAME (TREE_OPERAND (expr, 1)));
3774 return build_array_ref (input_location,
3775 objc_substitute_decl (TREE_OPERAND (expr, 0),
3778 TREE_OPERAND (expr, 1));
3780 return build_indirect_ref (input_location,
3781 objc_substitute_decl (TREE_OPERAND (expr, 0),
3783 newexpr), RO_ARROW);
3790 objc_build_ivar_assignment (tree outervar, tree lhs, tree rhs)
3793 /* The LHS parameter contains the expression 'outervar->memberspec';
3794 we need to transform it into '&((typeof(outervar) *) 0)->memberspec',
3795 where memberspec may be arbitrarily complex (e.g., 'g->f.d[2].g[3]').
3798 = objc_substitute_decl
3799 (lhs, outervar, convert (TREE_TYPE (outervar), integer_zero_node));
3801 = (flag_objc_direct_dispatch
3802 ? objc_assign_ivar_fast_decl
3803 : objc_assign_ivar_decl);
3805 offs = convert (integer_type_node, build_unary_op (input_location,
3806 ADDR_EXPR, offs, 0));
3808 func_params = tree_cons (NULL_TREE,
3809 convert (objc_object_type, rhs),
3810 tree_cons (NULL_TREE, convert (objc_object_type, outervar),
3811 tree_cons (NULL_TREE, offs,
3814 assemble_external (func);
3815 return build_function_call (input_location, func, func_params);
3819 objc_build_global_assignment (tree lhs, tree rhs)
3821 tree func_params = tree_cons (NULL_TREE,
3822 convert (objc_object_type, rhs),
3823 tree_cons (NULL_TREE, convert (build_pointer_type (objc_object_type),
3824 build_unary_op (input_location, ADDR_EXPR, lhs, 0)),
3827 assemble_external (objc_assign_global_decl);
3828 return build_function_call (input_location,
3829 objc_assign_global_decl, func_params);
3833 objc_build_strong_cast_assignment (tree lhs, tree rhs)
3835 tree func_params = tree_cons (NULL_TREE,
3836 convert (objc_object_type, rhs),
3837 tree_cons (NULL_TREE, convert (build_pointer_type (objc_object_type),
3838 build_unary_op (input_location, ADDR_EXPR, lhs, 0)),
3841 assemble_external (objc_assign_strong_cast_decl);
3842 return build_function_call (input_location,
3843 objc_assign_strong_cast_decl, func_params);
3847 objc_is_gcable_p (tree expr)
3849 return (TREE_CODE (expr) == COMPONENT_REF
3850 ? objc_is_gcable_p (TREE_OPERAND (expr, 1))
3851 : TREE_CODE (expr) == ARRAY_REF
3852 ? (objc_is_gcable_p (TREE_TYPE (expr))
3853 || objc_is_gcable_p (TREE_OPERAND (expr, 0)))
3854 : TREE_CODE (expr) == ARRAY_TYPE
3855 ? objc_is_gcable_p (TREE_TYPE (expr))
3857 ? objc_is_gcable_type (expr, 1)
3858 : (objc_is_gcable_p (TREE_TYPE (expr))
3860 && lookup_attribute ("objc_gc", DECL_ATTRIBUTES (expr)))));
3864 objc_is_ivar_reference_p (tree expr)
3866 return (TREE_CODE (expr) == ARRAY_REF
3867 ? objc_is_ivar_reference_p (TREE_OPERAND (expr, 0))
3868 : TREE_CODE (expr) == COMPONENT_REF
3869 ? TREE_CODE (TREE_OPERAND (expr, 1)) == FIELD_DECL
3874 objc_is_global_reference_p (tree expr)
3876 return (TREE_CODE (expr) == INDIRECT_REF || TREE_CODE (expr) == PLUS_EXPR
3877 ? objc_is_global_reference_p (TREE_OPERAND (expr, 0))
3879 ? (DECL_FILE_SCOPE_P (expr) || TREE_STATIC (expr))
3884 objc_generate_write_barrier (tree lhs, enum tree_code modifycode, tree rhs)
3886 tree result = NULL_TREE, outer;
3887 int strong_cast_p = 0, outer_gc_p = 0, indirect_p = 0;
3889 /* See if we have any lhs casts, and strip them out. NB: The lvalue casts
3890 will have been transformed to the form '*(type *)&expr'. */
3891 if (TREE_CODE (lhs) == INDIRECT_REF)
3893 outer = TREE_OPERAND (lhs, 0);
3895 while (!strong_cast_p
3896 && (CONVERT_EXPR_P (outer)
3897 || TREE_CODE (outer) == NON_LVALUE_EXPR))
3899 tree lhstype = TREE_TYPE (outer);
3901 /* Descend down the cast chain, and record the first objc_gc
3903 if (POINTER_TYPE_P (lhstype))
3906 = lookup_attribute ("objc_gc",
3907 TYPE_ATTRIBUTES (TREE_TYPE (lhstype)));
3913 outer = TREE_OPERAND (outer, 0);
3917 /* If we have a __strong cast, it trumps all else. */
3920 if (modifycode != NOP_EXPR)
3921 goto invalid_pointer_arithmetic;
3923 if (warn_assign_intercept)
3924 warning (0, "strong-cast assignment has been intercepted");
3926 result = objc_build_strong_cast_assignment (lhs, rhs);
3931 /* the lhs must be of a suitable type, regardless of its underlying
3933 if (!objc_is_gcable_p (lhs))
3939 && (TREE_CODE (outer) == COMPONENT_REF
3940 || TREE_CODE (outer) == ARRAY_REF))
3941 outer = TREE_OPERAND (outer, 0);
3943 if (TREE_CODE (outer) == INDIRECT_REF)
3945 outer = TREE_OPERAND (outer, 0);
3949 outer_gc_p = objc_is_gcable_p (outer);
3951 /* Handle ivar assignments. */
3952 if (objc_is_ivar_reference_p (lhs))
3954 /* if the struct to the left of the ivar is not an Objective-C object (__strong
3955 doesn't cut it here), the best we can do here is suggest a cast. */
3956 if (!objc_is_gcable_type (TREE_TYPE (outer), 0))
3958 /* We may still be able to use the global write barrier... */
3959 if (!indirect_p && objc_is_global_reference_p (outer))
3960 goto global_reference;
3963 if (modifycode == NOP_EXPR)
3965 if (warn_assign_intercept)
3966 warning (0, "strong-cast may possibly be needed");
3972 if (modifycode != NOP_EXPR)
3973 goto invalid_pointer_arithmetic;
3975 if (warn_assign_intercept)
3976 warning (0, "instance variable assignment has been intercepted");
3978 result = objc_build_ivar_assignment (outer, lhs, rhs);
3983 /* Likewise, intercept assignment to global/static variables if their type is
3985 if (objc_is_global_reference_p (outer))
3991 if (modifycode != NOP_EXPR)
3993 invalid_pointer_arithmetic:
3995 warning (0, "pointer arithmetic for garbage-collected objects not allowed");
4000 if (warn_assign_intercept)
4001 warning (0, "global/static variable assignment has been intercepted");
4003 result = objc_build_global_assignment (lhs, rhs);
4006 /* In all other cases, fall back to the normal mechanism. */
4011 struct GTY(()) interface_tuple {
4016 static GTY ((param_is (struct interface_tuple))) htab_t interface_htab;
4019 hash_interface (const void *p)
4021 const struct interface_tuple *d = (const struct interface_tuple *) p;
4022 return IDENTIFIER_HASH_VALUE (d->id);
4026 eq_interface (const void *p1, const void *p2)
4028 const struct interface_tuple *d = (const struct interface_tuple *) p1;
4033 lookup_interface (tree ident)
4036 if (ident && TREE_CODE (ident) == TYPE_DECL)
4037 ident = DECL_NAME (ident);
4040 if (ident == NULL_TREE || TREE_CODE (ident) != IDENTIFIER_NODE)
4044 struct interface_tuple **slot;
4049 slot = (struct interface_tuple **)
4050 htab_find_slot_with_hash (interface_htab, ident,
4051 IDENTIFIER_HASH_VALUE (ident),
4054 i = (*slot)->class_name;
4060 /* Implement @defs (<classname>) within struct bodies. */
4063 objc_get_class_ivars (tree class_name)
4065 tree interface = lookup_interface (class_name);
4068 return get_class_ivars (interface, true);
4070 error ("cannot find interface declaration for %qE",
4073 return error_mark_node;
4076 /* Called when checking the variables in a struct. If we are not
4077 doing the ivars list inside an @interface context, then returns
4078 fieldlist unchanged. Else, returns the list of class ivars.
4081 objc_get_interface_ivars (tree fieldlist)
4083 if (!objc_collecting_ivars || !objc_interface_context
4084 || TREE_CODE (objc_interface_context) != CLASS_INTERFACE_TYPE
4085 || CLASS_SUPER_NAME (objc_interface_context) == NULL_TREE)
4088 return get_class_ivars (objc_interface_context, true);
4091 /* Used by: build_private_template, continue_class,
4092 and for @defs constructs. */
4095 get_class_ivars (tree interface, bool inherited)
4097 tree ivar_chain = copy_list (CLASS_RAW_IVARS (interface));
4099 /* Both CLASS_RAW_IVARS and CLASS_IVARS contain a list of ivars declared
4100 by the current class (i.e., they do not include super-class ivars).
4101 However, the CLASS_IVARS list will be side-effected by a call to
4102 finish_struct(), which will fill in field offsets. */
4103 if (!CLASS_IVARS (interface))
4104 CLASS_IVARS (interface) = ivar_chain;
4109 while (CLASS_SUPER_NAME (interface))
4111 /* Prepend super-class ivars. */
4112 interface = lookup_interface (CLASS_SUPER_NAME (interface));
4113 ivar_chain = chainon (copy_list (CLASS_RAW_IVARS (interface)),
4120 /* Create a temporary variable of type 'type'. If 'name' is set, uses
4121 the specified name, else use no name. Returns the declaration of
4122 the type. The 'name' is mostly useful for debugging.
4125 objc_create_temporary_var (tree type, const char *name)
4131 decl = build_decl (input_location,
4132 VAR_DECL, get_identifier (name), type);
4136 decl = build_decl (input_location,
4137 VAR_DECL, NULL_TREE, type);
4139 TREE_USED (decl) = 1;
4140 DECL_ARTIFICIAL (decl) = 1;
4141 DECL_IGNORED_P (decl) = 1;
4142 DECL_CONTEXT (decl) = current_function_decl;
4147 /* Exception handling constructs. We begin by having the parser do most
4148 of the work and passing us blocks. What we do next depends on whether
4149 we're doing "native" exception handling or legacy Darwin setjmp exceptions.
4150 We abstract all of this in a handful of appropriately named routines. */
4152 /* Stack of open try blocks. */
4154 struct objc_try_context
4156 struct objc_try_context *outer;
4158 /* Statements (or statement lists) as processed by the parser. */
4162 /* Some file position locations. */
4163 location_t try_locus;
4164 location_t end_try_locus;
4165 location_t end_catch_locus;
4166 location_t finally_locus;
4167 location_t end_finally_locus;
4169 /* A STATEMENT_LIST of CATCH_EXPRs, appropriate for sticking into op1
4170 of a TRY_CATCH_EXPR. Even when doing Darwin setjmp. */
4173 /* The CATCH_EXPR of an open @catch clause. */
4176 /* The VAR_DECL holding the Darwin equivalent of __builtin_eh_pointer. */
4182 static struct objc_try_context *cur_try_context;
4184 static GTY(()) tree objc_eh_personality_decl;
4186 /* This hook, called via lang_eh_runtime_type, generates a runtime object
4187 that represents TYPE. For Objective-C, this is just the class name. */
4188 /* ??? Isn't there a class object or some such? Is it easy to get? */
4192 objc_eh_runtime_type (tree type)
4194 return add_objc_string (OBJC_TYPE_NAME (TREE_TYPE (type)), class_names);
4198 objc_eh_personality (void)
4200 if (!flag_objc_sjlj_exceptions && !objc_eh_personality_decl)
4201 objc_eh_personality_decl = build_personality_function ("gnu_objc");
4202 return objc_eh_personality_decl;
4206 /* Build __builtin_eh_pointer, or the moral equivalent. In the case
4207 of Darwin, we'll arrange for it to be initialized (and associated
4208 with a binding) later. */
4211 objc_build_exc_ptr (void)
4213 if (flag_objc_sjlj_exceptions)
4215 tree var = cur_try_context->caught_decl;
4218 var = objc_create_temporary_var (objc_object_type, NULL);
4219 cur_try_context->caught_decl = var;
4226 t = built_in_decls[BUILT_IN_EH_POINTER];
4227 t = build_call_expr (t, 1, integer_zero_node);
4228 return fold_convert (objc_object_type, t);
4232 /* Build "objc_exception_try_exit(&_stack)". */
4235 next_sjlj_build_try_exit (void)
4238 t = build_fold_addr_expr_loc (input_location, cur_try_context->stack_decl);
4239 t = tree_cons (NULL, t, NULL);
4240 t = build_function_call (input_location,
4241 objc_exception_try_exit_decl, t);
4246 objc_exception_try_enter (&_stack);
4247 if (_setjmp(&_stack.buf))
4251 Return the COND_EXPR. Note that the THEN and ELSE fields are left
4252 empty, ready for the caller to fill them in. */
4255 next_sjlj_build_enter_and_setjmp (void)
4257 tree t, enter, sj, cond;
4259 t = build_fold_addr_expr_loc (input_location, cur_try_context->stack_decl);
4260 t = tree_cons (NULL, t, NULL);
4261 enter = build_function_call (input_location,
4262 objc_exception_try_enter_decl, t);
4264 t = objc_build_component_ref (cur_try_context->stack_decl,
4265 get_identifier ("buf"));
4266 t = build_fold_addr_expr_loc (input_location, t);
4268 /* Convert _setjmp argument to type that is expected. */
4269 if (TYPE_ARG_TYPES (TREE_TYPE (objc_setjmp_decl)))
4270 t = convert (TREE_VALUE (TYPE_ARG_TYPES (TREE_TYPE (objc_setjmp_decl))), t);
4272 t = convert (ptr_type_node, t);
4274 t = convert (ptr_type_node, t);
4276 t = tree_cons (NULL, t, NULL);
4277 sj = build_function_call (input_location,
4278 objc_setjmp_decl, t);
4280 cond = build2 (COMPOUND_EXPR, TREE_TYPE (sj), enter, sj);
4281 cond = c_common_truthvalue_conversion (input_location, cond);
4283 return build3 (COND_EXPR, void_type_node, cond, NULL, NULL);
4288 DECL = objc_exception_extract(&_stack); */
4291 next_sjlj_build_exc_extract (tree decl)
4295 t = build_fold_addr_expr_loc (input_location, cur_try_context->stack_decl);
4296 t = tree_cons (NULL, t, NULL);
4297 t = build_function_call (input_location,
4298 objc_exception_extract_decl, t);
4299 t = convert (TREE_TYPE (decl), t);
4300 t = build2 (MODIFY_EXPR, void_type_node, decl, t);
4306 if (objc_exception_match(obj_get_class(TYPE), _caught)
4313 objc_exception_try_exit(&_stack);
4315 from the sequence of CATCH_EXPRs in the current try context. */
4318 next_sjlj_build_catch_list (void)
4320 tree_stmt_iterator i = tsi_start (cur_try_context->catch_list);
4322 tree *last = &catch_seq;
4323 bool saw_id = false;
4325 for (; !tsi_end_p (i); tsi_next (&i))
4327 tree stmt = tsi_stmt (i);
4328 tree type = CATCH_TYPES (stmt);
4329 tree body = CATCH_BODY (stmt);
4341 if (type == error_mark_node)
4342 cond = error_mark_node;
4345 args = tree_cons (NULL, cur_try_context->caught_decl, NULL);
4346 t = objc_get_class_reference (OBJC_TYPE_NAME (TREE_TYPE (type)));
4347 args = tree_cons (NULL, t, args);
4348 t = build_function_call (input_location,
4349 objc_exception_match_decl, args);
4350 cond = c_common_truthvalue_conversion (input_location, t);
4352 t = build3 (COND_EXPR, void_type_node, cond, body, NULL);
4353 SET_EXPR_LOCATION (t, EXPR_LOCATION (stmt));
4356 last = &COND_EXPR_ELSE (t);
4362 t = build2 (MODIFY_EXPR, void_type_node, cur_try_context->rethrow_decl,
4363 cur_try_context->caught_decl);
4364 SET_EXPR_LOCATION (t, cur_try_context->end_catch_locus);
4365 append_to_statement_list (t, last);
4367 t = next_sjlj_build_try_exit ();
4368 SET_EXPR_LOCATION (t, cur_try_context->end_catch_locus);
4369 append_to_statement_list (t, last);
4375 /* Build a complete @try-@catch-@finally block for legacy Darwin setjmp
4376 exception handling. We aim to build:
4379 struct _objc_exception_data _stack;
4383 objc_exception_try_enter (&_stack);
4384 if (_setjmp(&_stack.buf))
4386 id _caught = objc_exception_extract(&_stack);
4387 objc_exception_try_enter (&_stack);
4388 if (_setjmp(&_stack.buf))
4389 _rethrow = objc_exception_extract(&_stack);
4399 objc_exception_try_exit(&_stack);
4402 objc_exception_throw(_rethrow);
4406 If CATCH-LIST is empty, we can omit all of the block containing
4407 "_caught" except for the setting of _rethrow. Note the use of
4408 a real TRY_FINALLY_EXPR here, which is not involved in EH per-se,
4409 but handles goto and other exits from the block. */
4412 next_sjlj_build_try_catch_finally (void)
4414 tree rethrow_decl, stack_decl, t;
4415 tree catch_seq, try_fin, bind;
4417 /* Create the declarations involved. */
4418 t = xref_tag (RECORD_TYPE, get_identifier (UTAG_EXCDATA));
4419 stack_decl = objc_create_temporary_var (t, NULL);
4420 cur_try_context->stack_decl = stack_decl;
4422 rethrow_decl = objc_create_temporary_var (objc_object_type, NULL);
4423 cur_try_context->rethrow_decl = rethrow_decl;
4424 TREE_CHAIN (rethrow_decl) = stack_decl;
4426 /* Build the outermost variable binding level. */
4427 bind = build3 (BIND_EXPR, void_type_node, rethrow_decl, NULL, NULL);
4428 SET_EXPR_LOCATION (bind, cur_try_context->try_locus);
4429 TREE_SIDE_EFFECTS (bind) = 1;
4431 /* Initialize rethrow_decl. */
4432 t = build2 (MODIFY_EXPR, void_type_node, rethrow_decl,
4433 convert (objc_object_type, null_pointer_node));
4434 SET_EXPR_LOCATION (t, cur_try_context->try_locus);
4435 append_to_statement_list (t, &BIND_EXPR_BODY (bind));
4437 /* Build the outermost TRY_FINALLY_EXPR. */
4438 try_fin = build2 (TRY_FINALLY_EXPR, void_type_node, NULL, NULL);
4439 SET_EXPR_LOCATION (try_fin, cur_try_context->try_locus);
4440 TREE_SIDE_EFFECTS (try_fin) = 1;
4441 append_to_statement_list (try_fin, &BIND_EXPR_BODY (bind));
4443 /* Create the complete catch sequence. */
4444 if (cur_try_context->catch_list)
4446 tree caught_decl = objc_build_exc_ptr ();
4447 catch_seq = build_stmt (input_location, BIND_EXPR, caught_decl, NULL, NULL);
4448 TREE_SIDE_EFFECTS (catch_seq) = 1;
4450 t = next_sjlj_build_exc_extract (caught_decl);
4451 append_to_statement_list (t, &BIND_EXPR_BODY (catch_seq));
4453 t = next_sjlj_build_enter_and_setjmp ();
4454 COND_EXPR_THEN (t) = next_sjlj_build_exc_extract (rethrow_decl);
4455 COND_EXPR_ELSE (t) = next_sjlj_build_catch_list ();
4456 append_to_statement_list (t, &BIND_EXPR_BODY (catch_seq));
4459 catch_seq = next_sjlj_build_exc_extract (rethrow_decl);
4460 SET_EXPR_LOCATION (catch_seq, cur_try_context->end_try_locus);
4462 /* Build the main register-and-try if statement. */
4463 t = next_sjlj_build_enter_and_setjmp ();
4464 SET_EXPR_LOCATION (t, cur_try_context->try_locus);
4465 COND_EXPR_THEN (t) = catch_seq;
4466 COND_EXPR_ELSE (t) = cur_try_context->try_body;
4467 TREE_OPERAND (try_fin, 0) = t;
4469 /* Build the complete FINALLY statement list. */
4470 t = next_sjlj_build_try_exit ();
4471 t = build_stmt (input_location, COND_EXPR,
4472 c_common_truthvalue_conversion
4473 (input_location, rethrow_decl),
4475 SET_EXPR_LOCATION (t, cur_try_context->finally_locus);
4476 append_to_statement_list (t, &TREE_OPERAND (try_fin, 1));
4478 append_to_statement_list (cur_try_context->finally_body,
4479 &TREE_OPERAND (try_fin, 1));
4481 t = tree_cons (NULL, rethrow_decl, NULL);
4482 t = build_function_call (input_location,
4483 objc_exception_throw_decl, t);
4484 t = build_stmt (input_location, COND_EXPR,
4485 c_common_truthvalue_conversion (input_location,
4488 SET_EXPR_LOCATION (t, cur_try_context->end_finally_locus);
4489 append_to_statement_list (t, &TREE_OPERAND (try_fin, 1));
4494 /* Called just after parsing the @try and its associated BODY. We now
4495 must prepare for the tricky bits -- handling the catches and finally. */
4498 objc_begin_try_stmt (location_t try_locus, tree body)
4500 struct objc_try_context *c = XCNEW (struct objc_try_context);
4501 c->outer = cur_try_context;
4503 c->try_locus = try_locus;
4504 c->end_try_locus = input_location;
4505 cur_try_context = c;
4507 /* -fobjc-exceptions is required to enable Objective-C exceptions.
4508 For example, on Darwin, ObjC exceptions require a sufficiently
4509 recent version of the runtime, so the user must ask for them
4510 explicitly. On other platforms, at the moment -fobjc-exceptions
4511 triggers -fexceptions which again is required for exceptions to
4514 if (!flag_objc_exceptions)
4516 error_at (try_locus, "%<-fobjc-exceptions%> is required to enable Objective-C exception syntax");
4519 if (flag_objc_sjlj_exceptions)
4520 objc_mark_locals_volatile (NULL);
4523 /* Called just after parsing "@catch (parm)". Open a binding level,
4524 enter DECL into the binding level, and initialize it. Leave the
4525 binding level open while the body of the compound statement is parsed. */
4528 objc_begin_catch_clause (tree decl)
4530 tree compound, type, t;
4532 /* Begin a new scope that the entire catch clause will live in. */
4533 compound = c_begin_compound_stmt (true);
4535 /* The parser passed in a PARM_DECL, but what we really want is a VAR_DECL. */
4536 decl = build_decl (input_location,
4537 VAR_DECL, DECL_NAME (decl), TREE_TYPE (decl));
4538 lang_hooks.decls.pushdecl (decl);
4540 /* Since a decl is required here by syntax, don't warn if its unused. */
4541 /* ??? As opposed to __attribute__((unused))? Anyway, this appears to
4542 be what the previous objc implementation did. */
4543 TREE_USED (decl) = 1;
4544 DECL_READ_P (decl) = 1;
4546 /* Verify that the type of the catch is valid. It must be a pointer
4547 to an Objective-C class, or "id" (which is catch-all). */
4548 type = TREE_TYPE (decl);
4550 if (POINTER_TYPE_P (type) && objc_is_object_id (TREE_TYPE (type)))
4552 else if (!POINTER_TYPE_P (type) || !TYPED_OBJECT (TREE_TYPE (type)))
4554 error ("@catch parameter is not a known Objective-C class type");
4555 type = error_mark_node;
4557 else if (cur_try_context->catch_list)
4559 /* Examine previous @catch clauses and see if we've already
4560 caught the type in question. */
4561 tree_stmt_iterator i = tsi_start (cur_try_context->catch_list);
4562 for (; !tsi_end_p (i); tsi_next (&i))
4564 tree stmt = tsi_stmt (i);
4565 t = CATCH_TYPES (stmt);
4566 if (t == error_mark_node)
4568 if (!t || DERIVED_FROM_P (TREE_TYPE (t), TREE_TYPE (type)))
4570 warning (0, "exception of type %<%T%> will be caught",
4572 warning_at (EXPR_LOCATION (stmt), 0, " by earlier handler for %<%T%>",
4573 TREE_TYPE (t ? t : objc_object_type));
4579 /* Record the data for the catch in the try context so that we can
4580 finalize it later. */
4581 t = build_stmt (input_location, CATCH_EXPR, type, compound);
4582 cur_try_context->current_catch = t;
4584 /* Initialize the decl from the EXC_PTR_EXPR we get from the runtime. */
4585 t = objc_build_exc_ptr ();
4586 t = convert (TREE_TYPE (decl), t);
4587 t = build2 (MODIFY_EXPR, void_type_node, decl, t);
4591 /* Called just after parsing the closing brace of a @catch clause. Close
4592 the open binding level, and record a CATCH_EXPR for it. */
4595 objc_finish_catch_clause (void)
4597 tree c = cur_try_context->current_catch;
4598 cur_try_context->current_catch = NULL;
4599 cur_try_context->end_catch_locus = input_location;
4601 CATCH_BODY (c) = c_end_compound_stmt (input_location, CATCH_BODY (c), 1);
4602 append_to_statement_list (c, &cur_try_context->catch_list);
4605 /* Called after parsing a @finally clause and its associated BODY.
4606 Record the body for later placement. */
4609 objc_build_finally_clause (location_t finally_locus, tree body)
4611 cur_try_context->finally_body = body;
4612 cur_try_context->finally_locus = finally_locus;
4613 cur_try_context->end_finally_locus = input_location;
4616 /* Called to finalize a @try construct. */
4619 objc_finish_try_stmt (void)
4621 struct objc_try_context *c = cur_try_context;
4624 if (c->catch_list == NULL && c->finally_body == NULL)
4625 error ("%<@try%> without %<@catch%> or %<@finally%>");
4627 /* If we're doing Darwin setjmp exceptions, build the big nasty. */
4628 if (flag_objc_sjlj_exceptions)
4630 bool save = in_late_binary_op;
4631 in_late_binary_op = true;
4632 if (!cur_try_context->finally_body)
4634 cur_try_context->finally_locus = input_location;
4635 cur_try_context->end_finally_locus = input_location;
4637 stmt = next_sjlj_build_try_catch_finally ();
4638 in_late_binary_op = save;
4642 /* Otherwise, nest the CATCH inside a FINALLY. */
4646 stmt = build_stmt (input_location, TRY_CATCH_EXPR, stmt, c->catch_list);
4647 SET_EXPR_LOCATION (stmt, cur_try_context->try_locus);
4649 if (c->finally_body)
4651 stmt = build_stmt (input_location, TRY_FINALLY_EXPR, stmt, c->finally_body);
4652 SET_EXPR_LOCATION (stmt, cur_try_context->try_locus);
4657 cur_try_context = c->outer;
4663 objc_build_throw_stmt (location_t loc, tree throw_expr)
4667 if (!flag_objc_exceptions)
4669 error_at (loc, "%<-fobjc-exceptions%> is required to enable Objective-C exception syntax");
4672 if (throw_expr == NULL)
4674 /* If we're not inside a @catch block, there is no "current
4675 exception" to be rethrown. */
4676 if (cur_try_context == NULL
4677 || cur_try_context->current_catch == NULL)
4679 error_at (loc, "%<@throw%> (rethrow) used outside of a @catch block");
4683 /* Otherwise the object is still sitting in the EXC_PTR_EXPR
4684 value that we get from the runtime. */
4685 throw_expr = objc_build_exc_ptr ();
4688 /* A throw is just a call to the runtime throw function with the
4689 object as a parameter. */
4690 args = tree_cons (NULL, throw_expr, NULL);
4691 return add_stmt (build_function_call (loc,
4692 objc_exception_throw_decl, args));
4696 objc_build_synchronized (location_t start_locus, tree mutex, tree body)
4700 /* First lock the mutex. */
4701 mutex = save_expr (mutex);
4702 args = tree_cons (NULL, mutex, NULL);
4703 call = build_function_call (input_location,
4704 objc_sync_enter_decl, args);
4705 SET_EXPR_LOCATION (call, start_locus);
4708 /* Build the mutex unlock. */
4709 args = tree_cons (NULL, mutex, NULL);
4710 call = build_function_call (input_location,
4711 objc_sync_exit_decl, args);
4712 SET_EXPR_LOCATION (call, input_location);
4714 /* Put the that and the body in a TRY_FINALLY. */
4715 objc_begin_try_stmt (start_locus, body);
4716 objc_build_finally_clause (input_location, call);
4717 return objc_finish_try_stmt ();
4721 /* Predefine the following data type:
4723 struct _objc_exception_data
4725 int buf[OBJC_JBLEN];
4729 /* The following yuckiness should prevent users from having to #include
4730 <setjmp.h> in their code... */
4732 /* Define to a harmless positive value so the below code doesn't die. */
4734 #define OBJC_JBLEN 18
4738 build_next_objc_exception_stuff (void)
4740 tree decls, temp_type, *chain = NULL;
4742 objc_exception_data_template
4743 = objc_start_struct (get_identifier (UTAG_EXCDATA));
4745 /* int buf[OBJC_JBLEN]; */
4747 temp_type = build_sized_array_type (integer_type_node, OBJC_JBLEN);
4748 decls = add_field_decl (temp_type, "buf", &chain);
4750 /* void *pointers[4]; */
4752 temp_type = build_sized_array_type (ptr_type_node, 4);
4753 add_field_decl (temp_type, "pointers", &chain);
4755 objc_finish_struct (objc_exception_data_template, decls);
4757 /* int _setjmp(...); */
4758 /* If the user includes <setjmp.h>, this shall be superseded by
4759 'int _setjmp(jmp_buf);' */
4760 temp_type = build_varargs_function_type_list (integer_type_node, NULL_TREE);
4762 = add_builtin_function (TAG_SETJMP, temp_type, 0, NOT_BUILT_IN, NULL, NULL_TREE);
4764 /* id objc_exception_extract(struct _objc_exception_data *); */
4766 = build_function_type_list (objc_object_type,
4767 build_pointer_type (objc_exception_data_template),
4769 objc_exception_extract_decl
4770 = add_builtin_function (TAG_EXCEPTIONEXTRACT, temp_type, 0, NOT_BUILT_IN, NULL,
4772 /* void objc_exception_try_enter(struct _objc_exception_data *); */
4773 /* void objc_exception_try_exit(struct _objc_exception_data *); */
4775 = build_function_type_list (void_type_node,
4776 build_pointer_type (objc_exception_data_template),
4778 objc_exception_try_enter_decl
4779 = add_builtin_function (TAG_EXCEPTIONTRYENTER, temp_type, 0, NOT_BUILT_IN, NULL,
4781 objc_exception_try_exit_decl
4782 = add_builtin_function (TAG_EXCEPTIONTRYEXIT, temp_type, 0, NOT_BUILT_IN, NULL,
4785 /* int objc_exception_match(id, id); */
4787 = build_function_type_list (integer_type_node,
4788 objc_object_type, objc_object_type, NULL_TREE);
4789 objc_exception_match_decl
4790 = add_builtin_function (TAG_EXCEPTIONMATCH, temp_type, 0, NOT_BUILT_IN, NULL,
4793 /* id objc_assign_ivar (id, id, unsigned int); */
4794 /* id objc_assign_ivar_Fast (id, id, unsigned int)
4795 __attribute__ ((hard_coded_address (OFFS_ASSIGNIVAR_FAST))); */
4797 = build_function_type_list (objc_object_type,
4802 objc_assign_ivar_decl
4803 = add_builtin_function (TAG_ASSIGNIVAR, temp_type, 0, NOT_BUILT_IN,
4805 #ifdef OFFS_ASSIGNIVAR_FAST
4806 objc_assign_ivar_fast_decl
4807 = add_builtin_function (TAG_ASSIGNIVAR_FAST, temp_type, 0,
4808 NOT_BUILT_IN, NULL, NULL_TREE);
4809 DECL_ATTRIBUTES (objc_assign_ivar_fast_decl)
4810 = tree_cons (get_identifier ("hard_coded_address"),
4811 build_int_cst (NULL_TREE, OFFS_ASSIGNIVAR_FAST),
4814 /* Default to slower ivar method. */
4815 objc_assign_ivar_fast_decl = objc_assign_ivar_decl;
4818 /* id objc_assign_global (id, id *); */
4819 /* id objc_assign_strongCast (id, id *); */
4820 temp_type = build_function_type_list (objc_object_type,
4822 build_pointer_type (objc_object_type),
4824 objc_assign_global_decl
4825 = add_builtin_function (TAG_ASSIGNGLOBAL, temp_type, 0, NOT_BUILT_IN, NULL,
4827 objc_assign_strong_cast_decl
4828 = add_builtin_function (TAG_ASSIGNSTRONGCAST, temp_type, 0, NOT_BUILT_IN, NULL,
4833 build_objc_exception_stuff (void)
4835 tree noreturn_list, nothrow_list, temp_type;
4837 noreturn_list = tree_cons (get_identifier ("noreturn"), NULL, NULL);
4838 nothrow_list = tree_cons (get_identifier ("nothrow"), NULL, NULL);
4840 /* void objc_exception_throw(id) __attribute__((noreturn)); */
4841 /* void objc_sync_enter(id); */
4842 /* void objc_sync_exit(id); */
4843 temp_type = build_function_type_list (void_type_node,
4846 objc_exception_throw_decl
4847 = add_builtin_function (TAG_EXCEPTIONTHROW, temp_type, 0, NOT_BUILT_IN, NULL,
4849 objc_sync_enter_decl
4850 = add_builtin_function (TAG_SYNCENTER, temp_type, 0, NOT_BUILT_IN,
4851 NULL, nothrow_list);
4853 = add_builtin_function (TAG_SYNCEXIT, temp_type, 0, NOT_BUILT_IN,
4854 NULL, nothrow_list);
4857 /* Construct a C struct corresponding to ObjC class CLASS, with the same
4860 struct <classname> {
4861 struct _objc_class *isa;
4866 build_private_template (tree klass)
4868 if (!CLASS_STATIC_TEMPLATE (klass))
4870 tree record = objc_build_struct (klass,
4871 get_class_ivars (klass, false),
4872 CLASS_SUPER_NAME (klass));
4874 /* Set the TREE_USED bit for this struct, so that stab generator
4875 can emit stabs for this struct type. */
4876 if (flag_debug_only_used_symbols && TYPE_STUB_DECL (record))
4877 TREE_USED (TYPE_STUB_DECL (record)) = 1;
4881 /* Begin code generation for protocols... */
4883 /* struct _objc_protocol {
4884 struct _objc_class *isa;
4885 char *protocol_name;
4886 struct _objc_protocol **protocol_list;
4887 struct _objc__method_prototype_list *instance_methods;
4888 struct _objc__method_prototype_list *class_methods;
4892 build_protocol_template (void)
4894 tree ptype, decls, *chain = NULL;
4896 objc_protocol_template = objc_start_struct (get_identifier (UTAG_PROTOCOL));
4898 /* struct _objc_class *isa; */
4899 ptype = build_pointer_type (xref_tag (RECORD_TYPE,
4900 get_identifier (UTAG_CLASS)));
4901 decls = add_field_decl (ptype, "isa", &chain);
4903 /* char *protocol_name; */
4904 add_field_decl (string_type_node, "protocol_name", &chain);
4906 /* struct _objc_protocol **protocol_list; */
4907 ptype = build_pointer_type (build_pointer_type (objc_protocol_template));
4908 add_field_decl (ptype, "protocol_list", &chain);
4910 /* struct _objc__method_prototype_list *instance_methods; */
4911 add_field_decl (objc_method_proto_list_ptr, "instance_methods", &chain);
4913 /* struct _objc__method_prototype_list *class_methods; */
4914 add_field_decl (objc_method_proto_list_ptr, "class_methods", &chain);
4916 objc_finish_struct (objc_protocol_template, decls);
4920 build_descriptor_table_initializer (tree type, tree entries)
4922 VEC(constructor_elt,gc) *inits = NULL;
4926 VEC(constructor_elt,gc) *elts = NULL;
4928 CONSTRUCTOR_APPEND_ELT (elts, NULL_TREE,
4929 build_selector (METHOD_SEL_NAME (entries)));
4930 CONSTRUCTOR_APPEND_ELT (elts, NULL_TREE,
4931 add_objc_string (METHOD_ENCODING (entries),
4934 CONSTRUCTOR_APPEND_ELT (inits, NULL_TREE,
4935 objc_build_constructor (type, elts));
4937 entries = DECL_CHAIN (entries);
4941 return objc_build_constructor (build_array_type (type, 0), inits);
4944 /* struct objc_method_prototype_list {
4946 struct objc_method_prototype {
4953 build_method_prototype_list_template (tree list_type, int size)
4955 tree objc_ivar_list_record;
4956 tree array_type, decls, *chain = NULL;
4958 /* Generate an unnamed struct definition. */
4960 objc_ivar_list_record = objc_start_struct (NULL_TREE);
4962 /* int method_count; */
4963 decls = add_field_decl (integer_type_node, "method_count", &chain);
4965 /* struct objc_method method_list[]; */
4966 array_type = build_sized_array_type (list_type, size);
4967 add_field_decl (array_type, "method_list", &chain);
4969 objc_finish_struct (objc_ivar_list_record, decls);
4971 return objc_ivar_list_record;
4975 build_method_prototype_template (void)
4978 tree decls, *chain = NULL;
4980 proto_record = objc_start_struct (get_identifier (UTAG_METHOD_PROTOTYPE));
4983 decls = add_field_decl (objc_selector_type, "_cmd", &chain);
4985 /* char *method_types; */
4986 add_field_decl (string_type_node, "method_types", &chain);
4988 objc_finish_struct (proto_record, decls);
4990 return proto_record;
4994 objc_method_parm_type (tree type)
4996 type = TREE_VALUE (TREE_TYPE (type));
4997 if (TREE_CODE (type) == TYPE_DECL)
4998 type = TREE_TYPE (type);
5003 objc_encoded_type_size (tree type)
5005 int sz = int_size_in_bytes (type);
5007 /* Make all integer and enum types at least as large
5009 if (sz > 0 && INTEGRAL_TYPE_P (type))
5010 sz = MAX (sz, int_size_in_bytes (integer_type_node));
5011 /* Treat arrays as pointers, since that's how they're
5013 else if (TREE_CODE (type) == ARRAY_TYPE)
5014 sz = int_size_in_bytes (ptr_type_node);
5018 /* Encode a method prototype.
5020 The format is described in gcc/doc/objc.texi, section 'Method
5024 encode_method_prototype (tree method_decl)
5031 /* ONEWAY and BYCOPY, for remote object are the only method qualifiers. */
5032 encode_type_qualifiers (TREE_PURPOSE (TREE_TYPE (method_decl)));
5034 /* Encode return type. */
5035 encode_type (objc_method_parm_type (method_decl),
5036 obstack_object_size (&util_obstack),
5037 OBJC_ENCODE_INLINE_DEFS);
5040 /* The first two arguments (self and _cmd) are pointers; account for
5042 i = int_size_in_bytes (ptr_type_node);
5043 parm_offset = 2 * i;
5044 for (parms = METHOD_SEL_ARGS (method_decl); parms;
5045 parms = DECL_CHAIN (parms))
5047 tree type = objc_method_parm_type (parms);
5048 int sz = objc_encoded_type_size (type);
5050 /* If a type size is not known, bail out. */
5053 error ("type %q+D does not have a known size",
5055 /* Pretend that the encoding succeeded; the compilation will
5056 fail nevertheless. */
5057 goto finish_encoding;
5062 sprintf (buf, "%d@0:%d", parm_offset, i);
5063 obstack_grow (&util_obstack, buf, strlen (buf));
5065 /* Argument types. */
5066 parm_offset = 2 * i;
5067 for (parms = METHOD_SEL_ARGS (method_decl); parms;
5068 parms = DECL_CHAIN (parms))
5070 tree type = objc_method_parm_type (parms);
5072 /* Process argument qualifiers for user supplied arguments. */
5073 encode_type_qualifiers (TREE_PURPOSE (TREE_TYPE (parms)));
5076 encode_type (type, obstack_object_size (&util_obstack),
5077 OBJC_ENCODE_INLINE_DEFS);
5079 /* Compute offset. */
5080 sprintf (buf, "%d", parm_offset);
5081 parm_offset += objc_encoded_type_size (type);
5083 obstack_grow (&util_obstack, buf, strlen (buf));
5087 obstack_1grow (&util_obstack, '\0');
5088 result = get_identifier (XOBFINISH (&util_obstack, char *));
5089 obstack_free (&util_obstack, util_firstobj);
5094 generate_descriptor_table (tree type, const char *name, int size, tree list,
5098 VEC(constructor_elt,gc) *v = NULL;
5100 decl = start_var_decl (type, synth_id_with_class_suffix (name, proto));
5102 CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, build_int_cst (NULL_TREE, size));
5103 CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, list);
5105 finish_var_decl (decl, objc_build_constructor (type, v));
5111 generate_method_descriptors (tree protocol)
5113 tree initlist, chain, method_list_template;
5116 if (!objc_method_prototype_template)
5117 objc_method_prototype_template = build_method_prototype_template ();
5119 chain = PROTOCOL_CLS_METHODS (protocol);
5122 size = list_length (chain);
5124 method_list_template
5125 = build_method_prototype_list_template (objc_method_prototype_template,
5129 = build_descriptor_table_initializer (objc_method_prototype_template,
5132 UOBJC_CLASS_METHODS_decl
5133 = generate_descriptor_table (method_list_template,
5134 "_OBJC_PROTOCOL_CLASS_METHODS",
5135 size, initlist, protocol);
5138 UOBJC_CLASS_METHODS_decl = 0;
5140 chain = PROTOCOL_NST_METHODS (protocol);
5143 size = list_length (chain);
5145 method_list_template
5146 = build_method_prototype_list_template (objc_method_prototype_template,
5149 = build_descriptor_table_initializer (objc_method_prototype_template,
5152 UOBJC_INSTANCE_METHODS_decl
5153 = generate_descriptor_table (method_list_template,
5154 "_OBJC_PROTOCOL_INSTANCE_METHODS",
5155 size, initlist, protocol);
5158 UOBJC_INSTANCE_METHODS_decl = 0;
5162 generate_protocol_references (tree plist)
5166 /* Forward declare protocols referenced. */
5167 for (lproto = plist; lproto; lproto = TREE_CHAIN (lproto))
5169 tree proto = TREE_VALUE (lproto);
5171 if (TREE_CODE (proto) == PROTOCOL_INTERFACE_TYPE
5172 && PROTOCOL_NAME (proto))
5174 if (! PROTOCOL_FORWARD_DECL (proto))
5175 build_protocol_reference (proto);
5177 if (PROTOCOL_LIST (proto))
5178 generate_protocol_references (PROTOCOL_LIST (proto));
5183 /* Generate either '- .cxx_construct' or '- .cxx_destruct' for the
5187 objc_generate_cxx_ctor_or_dtor (bool dtor)
5189 tree fn, body, compound_stmt, ivar;
5191 /* - (id) .cxx_construct { ... return self; } */
5192 /* - (void) .cxx_construct { ... } */
5194 objc_start_method_definition
5195 (false /* is_class_method */,
5196 objc_build_method_signature (false /* is_class_method */,
5197 build_tree_list (NULL_TREE,
5200 : objc_object_type),
5201 get_identifier (dtor
5203 : TAG_CXX_CONSTRUCT),
5204 make_node (TREE_LIST),
5206 body = begin_function_body ();
5207 compound_stmt = begin_compound_stmt (0);
5209 ivar = CLASS_IVARS (implementation_template);
5210 /* Destroy ivars in reverse order. */
5212 ivar = nreverse (copy_list (ivar));
5214 for (; ivar; ivar = TREE_CHAIN (ivar))
5216 if (TREE_CODE (ivar) == FIELD_DECL)
5218 tree type = TREE_TYPE (ivar);
5220 /* Call the ivar's default constructor or destructor. Do not
5221 call the destructor unless a corresponding constructor call
5222 has also been made (or is not needed). */
5223 if (MAYBE_CLASS_TYPE_P (type)
5225 ? (TYPE_HAS_NONTRIVIAL_DESTRUCTOR (type)
5226 && (!TYPE_NEEDS_CONSTRUCTING (type)
5227 || TYPE_HAS_DEFAULT_CONSTRUCTOR (type)))
5228 : (TYPE_NEEDS_CONSTRUCTING (type)
5229 && TYPE_HAS_DEFAULT_CONSTRUCTOR (type))))
5231 (build_special_member_call
5232 (build_ivar_reference (DECL_NAME (ivar)),
5233 dtor ? complete_dtor_identifier : complete_ctor_identifier,
5234 NULL, type, LOOKUP_NORMAL, tf_warning_or_error));
5238 /* The constructor returns 'self'. */
5240 finish_return_stmt (self_decl);
5242 finish_compound_stmt (compound_stmt);
5243 finish_function_body (body);
5244 fn = current_function_decl;
5246 objc_finish_method_definition (fn);
5249 /* The following routine will examine the current @interface for any
5250 non-POD C++ ivars requiring non-trivial construction and/or
5251 destruction, and then synthesize special '- .cxx_construct' and/or
5252 '- .cxx_destruct' methods which will run the appropriate
5253 construction or destruction code. Note that ivars inherited from
5254 super-classes are _not_ considered. */
5256 objc_generate_cxx_cdtors (void)
5258 bool need_ctor = false, need_dtor = false;
5261 /* Error case, due to possibly an extra @end. */
5262 if (!objc_implementation_context)
5265 /* We do not want to do this for categories, since they do not have
5268 if (TREE_CODE (objc_implementation_context) != CLASS_IMPLEMENTATION_TYPE)
5271 /* First, determine if we even need a constructor and/or destructor. */
5273 for (ivar = CLASS_IVARS (implementation_template); ivar;
5274 ivar = TREE_CHAIN (ivar))
5276 if (TREE_CODE (ivar) == FIELD_DECL)
5278 tree type = TREE_TYPE (ivar);
5280 if (MAYBE_CLASS_TYPE_P (type))
5282 if (TYPE_NEEDS_CONSTRUCTING (type)
5283 && TYPE_HAS_DEFAULT_CONSTRUCTOR (type))
5284 /* NB: If a default constructor is not available, we will not
5285 be able to initialize this ivar; the add_instance_variable()
5286 routine will already have warned about this. */
5289 if (TYPE_HAS_NONTRIVIAL_DESTRUCTOR (type)
5290 && (!TYPE_NEEDS_CONSTRUCTING (type)
5291 || TYPE_HAS_DEFAULT_CONSTRUCTOR (type)))
5292 /* NB: If a default constructor is not available, we will not
5293 call the destructor either, for symmetry. */
5299 /* Generate '- .cxx_construct' if needed. */
5302 objc_generate_cxx_ctor_or_dtor (false);
5304 /* Generate '- .cxx_destruct' if needed. */
5307 objc_generate_cxx_ctor_or_dtor (true);
5309 /* The 'imp_list' variable points at an imp_entry record for the current
5310 @implementation. Record the existence of '- .cxx_construct' and/or
5311 '- .cxx_destruct' methods therein; it will be included in the
5312 metadata for the class. */
5313 if (flag_next_runtime)
5314 imp_list->has_cxx_cdtors = (need_ctor || need_dtor);
5318 /* For each protocol which was referenced either from a @protocol()
5319 expression, or because a class/category implements it (then a
5320 pointer to the protocol is stored in the struct describing the
5321 class/category), we create a statically allocated instance of the
5322 Protocol class. The code is written in such a way as to generate
5323 as few Protocol objects as possible; we generate a unique Protocol
5324 instance for each protocol, and we don't generate a Protocol
5325 instance if the protocol is never referenced (either from a
5326 @protocol() or from a class/category implementation). These
5327 statically allocated objects can be referred to via the static
5328 (that is, private to this module) symbols _OBJC_PROTOCOL_n.
5330 The statically allocated Protocol objects that we generate here
5331 need to be fixed up at runtime in order to be used: the 'isa'
5332 pointer of the objects need to be set up to point to the 'Protocol'
5333 class, as known at runtime.
5335 The NeXT runtime fixes up all protocols at program startup time,
5336 before main() is entered. It uses a low-level trick to look up all
5337 those symbols, then loops on them and fixes them up.
5339 The GNU runtime as well fixes up all protocols before user code
5340 from the module is executed; it requires pointers to those symbols
5341 to be put in the objc_symtab (which is then passed as argument to
5342 the function __objc_exec_class() which the compiler sets up to be
5343 executed automatically when the module is loaded); setup of those
5344 Protocol objects happen in two ways in the GNU runtime: all
5345 Protocol objects referred to by a class or category implementation
5346 are fixed up when the class/category is loaded; all Protocol
5347 objects referred to by a @protocol() expression are added by the
5348 compiler to the list of statically allocated instances to fixup
5349 (the same list holding the statically allocated constant string
5350 objects). Because, as explained above, the compiler generates as
5351 few Protocol objects as possible, some Protocol object might end up
5352 being referenced multiple times when compiled with the GNU runtime,
5353 and end up being fixed up multiple times at runtime initialization.
5354 But that doesn't hurt, it's just a little inefficient. */
5357 generate_protocols (void)
5361 tree initlist, protocol_name_expr, refs_decl, refs_expr;
5363 /* If a protocol was directly referenced, pull in indirect references. */
5364 for (p = protocol_chain; p; p = TREE_CHAIN (p))
5365 if (PROTOCOL_FORWARD_DECL (p) && PROTOCOL_LIST (p))
5366 generate_protocol_references (PROTOCOL_LIST (p));
5368 for (p = protocol_chain; p; p = TREE_CHAIN (p))
5370 tree nst_methods = PROTOCOL_NST_METHODS (p);
5371 tree cls_methods = PROTOCOL_CLS_METHODS (p);
5373 /* If protocol wasn't referenced, don't generate any code. */
5374 decl = PROTOCOL_FORWARD_DECL (p);
5379 /* Make sure we link in the Protocol class. */
5380 add_class_reference (get_identifier (PROTOCOL_OBJECT_CLASS_NAME));
5384 if (! METHOD_ENCODING (nst_methods))
5386 encoding = encode_method_prototype (nst_methods);
5387 METHOD_ENCODING (nst_methods) = encoding;
5389 nst_methods = DECL_CHAIN (nst_methods);
5394 if (! METHOD_ENCODING (cls_methods))
5396 encoding = encode_method_prototype (cls_methods);
5397 METHOD_ENCODING (cls_methods) = encoding;
5400 cls_methods = DECL_CHAIN (cls_methods);
5402 generate_method_descriptors (p);
5404 if (PROTOCOL_LIST (p))
5405 refs_decl = generate_protocol_list (p);
5409 /* static struct objc_protocol _OBJC_PROTOCOL_<mumble>; */
5410 protocol_name_expr = add_objc_string (PROTOCOL_NAME (p), class_names);
5413 refs_expr = convert (build_pointer_type (build_pointer_type
5414 (objc_protocol_template)),
5415 build_unary_op (input_location,
5416 ADDR_EXPR, refs_decl, 0));
5418 refs_expr = build_int_cst (NULL_TREE, 0);
5420 /* UOBJC_INSTANCE_METHODS_decl/UOBJC_CLASS_METHODS_decl are set
5421 by generate_method_descriptors, which is called above. */
5422 initlist = build_protocol_initializer (TREE_TYPE (decl),
5423 protocol_name_expr, refs_expr,
5424 UOBJC_INSTANCE_METHODS_decl,
5425 UOBJC_CLASS_METHODS_decl);
5426 finish_var_decl (decl, initlist);
5431 build_protocol_initializer (tree type, tree protocol_name,
5432 tree protocol_list, tree instance_methods,
5436 tree cast_type = build_pointer_type
5437 (xref_tag (RECORD_TYPE,
5438 get_identifier (UTAG_CLASS)));
5439 VEC(constructor_elt,gc) *inits = NULL;
5441 /* Filling the "isa" in with one allows the runtime system to
5442 detect that the version change...should remove before final release. */
5444 expr = build_int_cst (cast_type, PROTOCOL_VERSION);
5445 CONSTRUCTOR_APPEND_ELT (inits, NULL_TREE, expr);
5446 CONSTRUCTOR_APPEND_ELT (inits, NULL_TREE, protocol_name);
5447 CONSTRUCTOR_APPEND_ELT (inits, NULL_TREE, protocol_list);
5449 if (!instance_methods)
5450 CONSTRUCTOR_APPEND_ELT (inits, NULL_TREE, build_int_cst (NULL_TREE, 0));
5453 expr = convert (objc_method_proto_list_ptr,
5454 build_unary_op (input_location,
5455 ADDR_EXPR, instance_methods, 0));
5456 CONSTRUCTOR_APPEND_ELT (inits, NULL_TREE, expr);
5460 CONSTRUCTOR_APPEND_ELT (inits, NULL_TREE, build_int_cst (NULL_TREE, 0));
5463 expr = convert (objc_method_proto_list_ptr,
5464 build_unary_op (input_location,
5465 ADDR_EXPR, class_methods, 0));
5466 CONSTRUCTOR_APPEND_ELT (inits, NULL_TREE, expr);
5469 return objc_build_constructor (type, inits);
5472 /* struct _objc_category {
5473 char *category_name;
5475 struct _objc_method_list *instance_methods;
5476 struct _objc_method_list *class_methods;
5477 struct _objc_protocol_list *protocols;
5481 build_category_template (void)
5483 tree ptype, decls, *chain = NULL;
5485 objc_category_template = objc_start_struct (get_identifier (UTAG_CATEGORY));
5487 /* char *category_name; */
5488 decls = add_field_decl (string_type_node, "category_name", &chain);
5490 /* char *class_name; */
5491 add_field_decl (string_type_node, "class_name", &chain);
5493 /* struct _objc_method_list *instance_methods; */
5494 add_field_decl (objc_method_list_ptr, "instance_methods", &chain);
5496 /* struct _objc_method_list *class_methods; */
5497 add_field_decl (objc_method_list_ptr, "class_methods", &chain);
5499 /* struct _objc_protocol **protocol_list; */
5500 ptype = build_pointer_type (build_pointer_type (objc_protocol_template));
5501 add_field_decl (ptype, "protocol_list", &chain);
5503 objc_finish_struct (objc_category_template, decls);
5506 /* struct _objc_selector {
5512 build_selector_template (void)
5514 tree decls, *chain = NULL;
5516 objc_selector_template = objc_start_struct (get_identifier (UTAG_SELECTOR));
5519 decls = add_field_decl (objc_selector_type, "sel_id", &chain);
5521 /* char *sel_type; */
5522 add_field_decl (string_type_node, "sel_type", &chain);
5524 objc_finish_struct (objc_selector_template, decls);
5527 /* struct _objc_class {
5528 struct _objc_class *isa;
5529 struct _objc_class *super_class;
5534 struct _objc_ivar_list *ivars;
5535 struct _objc_method_list *methods;
5536 #ifdef __NEXT_RUNTIME__
5537 struct objc_cache *cache;
5539 struct sarray *dtable;
5540 struct _objc_class *subclass_list;
5541 struct _objc_class *sibling_class;
5543 struct _objc_protocol_list *protocols;
5544 #ifdef __NEXT_RUNTIME__
5547 void *gc_object_type;
5550 /* NB: The 'sel_id' and 'gc_object_type' fields are not being used by
5551 the NeXT/Apple runtime; still, the compiler must generate them to
5552 maintain backward binary compatibility (and to allow for future
5556 build_class_template (void)
5558 tree ptype, decls, *chain = NULL;
5560 objc_class_template = objc_start_struct (get_identifier (UTAG_CLASS));
5562 /* struct _objc_class *isa; */
5563 decls = add_field_decl (build_pointer_type (objc_class_template),
5566 /* struct _objc_class *super_class; */
5567 add_field_decl (build_pointer_type (objc_class_template),
5568 "super_class", &chain);
5571 add_field_decl (string_type_node, "name", &chain);
5574 add_field_decl (long_integer_type_node, "version", &chain);
5577 add_field_decl (long_integer_type_node, "info", &chain);
5579 /* long instance_size; */
5580 add_field_decl (long_integer_type_node, "instance_size", &chain);
5582 /* struct _objc_ivar_list *ivars; */
5583 add_field_decl (objc_ivar_list_ptr,"ivars", &chain);
5585 /* struct _objc_method_list *methods; */
5586 add_field_decl (objc_method_list_ptr, "methods", &chain);
5588 if (flag_next_runtime)
5590 /* struct objc_cache *cache; */
5591 ptype = build_pointer_type (xref_tag (RECORD_TYPE,
5592 get_identifier ("objc_cache")));
5593 add_field_decl (ptype, "cache", &chain);
5597 /* struct sarray *dtable; */
5598 ptype = build_pointer_type(xref_tag (RECORD_TYPE,
5599 get_identifier ("sarray")));
5600 add_field_decl (ptype, "dtable", &chain);
5602 /* struct objc_class *subclass_list; */
5603 ptype = build_pointer_type (objc_class_template);
5604 add_field_decl (ptype, "subclass_list", &chain);
5606 /* struct objc_class *sibling_class; */
5607 ptype = build_pointer_type (objc_class_template);
5608 add_field_decl (ptype, "sibling_class", &chain);
5611 /* struct _objc_protocol **protocol_list; */
5612 ptype = build_pointer_type (build_pointer_type
5613 (xref_tag (RECORD_TYPE,
5614 get_identifier (UTAG_PROTOCOL))));
5615 add_field_decl (ptype, "protocol_list", &chain);
5617 if (flag_next_runtime)
5620 add_field_decl (build_pointer_type (void_type_node), "sel_id", &chain);
5623 /* void *gc_object_type; */
5624 add_field_decl (build_pointer_type (void_type_node),
5625 "gc_object_type", &chain);
5627 objc_finish_struct (objc_class_template, decls);
5630 /* Generate appropriate forward declarations for an implementation. */
5633 synth_forward_declarations (void)
5637 /* static struct objc_class _OBJC_CLASS_<my_name>; */
5638 UOBJC_CLASS_decl = build_metadata_decl ("_OBJC_CLASS",
5639 objc_class_template);
5641 /* static struct objc_class _OBJC_METACLASS_<my_name>; */
5642 UOBJC_METACLASS_decl = build_metadata_decl ("_OBJC_METACLASS",
5643 objc_class_template);
5645 /* Pre-build the following entities - for speed/convenience. */
5647 an_id = get_identifier ("super_class");
5648 ucls_super_ref = objc_build_component_ref (UOBJC_CLASS_decl, an_id);
5649 uucls_super_ref = objc_build_component_ref (UOBJC_METACLASS_decl, an_id);
5653 error_with_ivar (const char *message, tree decl)
5655 error_at (DECL_SOURCE_LOCATION (decl), "%s %qs",
5656 message, identifier_to_locale (gen_declaration (decl)));
5661 check_ivars (tree inter, tree imp)
5663 tree intdecls = CLASS_RAW_IVARS (inter);
5664 tree impdecls = CLASS_RAW_IVARS (imp);
5671 if (intdecls && TREE_CODE (intdecls) == TYPE_DECL)
5672 intdecls = TREE_CHAIN (intdecls);
5674 if (intdecls == 0 && impdecls == 0)
5676 if (intdecls == 0 || impdecls == 0)
5678 error ("inconsistent instance variable specification");
5682 t1 = TREE_TYPE (intdecls); t2 = TREE_TYPE (impdecls);
5684 if (!comptypes (t1, t2)
5685 || !tree_int_cst_equal (DECL_INITIAL (intdecls),
5686 DECL_INITIAL (impdecls)))
5688 if (DECL_NAME (intdecls) == DECL_NAME (impdecls))
5690 error_with_ivar ("conflicting instance variable type",
5692 error_with_ivar ("previous declaration of",
5695 else /* both the type and the name don't match */
5697 error ("inconsistent instance variable specification");
5702 else if (DECL_NAME (intdecls) != DECL_NAME (impdecls))
5704 error_with_ivar ("conflicting instance variable name",
5706 error_with_ivar ("previous declaration of",
5710 intdecls = DECL_CHAIN (intdecls);
5711 impdecls = DECL_CHAIN (impdecls);
5715 /* Set 'objc_super_template' to the data type node for 'struct _objc_super'.
5716 This needs to be done just once per compilation. */
5718 /* struct _objc_super {
5719 struct _objc_object *self;
5720 struct _objc_class *super_class;
5724 build_super_template (void)
5726 tree decls, *chain = NULL;
5728 objc_super_template = objc_start_struct (get_identifier (UTAG_SUPER));
5730 /* struct _objc_object *self; */
5731 decls = add_field_decl (objc_object_type, "self", &chain);
5733 /* struct _objc_class *super_class; */
5734 add_field_decl (build_pointer_type (objc_class_template),
5735 "super_class", &chain);
5737 objc_finish_struct (objc_super_template, decls);
5740 /* struct _objc_ivar {
5747 build_ivar_template (void)
5749 tree objc_ivar_id, objc_ivar_record;
5750 tree decls, *chain = NULL;
5752 objc_ivar_id = get_identifier (UTAG_IVAR);
5753 objc_ivar_record = objc_start_struct (objc_ivar_id);
5755 /* char *ivar_name; */
5756 decls = add_field_decl (string_type_node, "ivar_name", &chain);
5758 /* char *ivar_type; */
5759 add_field_decl (string_type_node, "ivar_type", &chain);
5761 /* int ivar_offset; */
5762 add_field_decl (integer_type_node, "ivar_offset", &chain);
5764 objc_finish_struct (objc_ivar_record, decls);
5766 return objc_ivar_record;
5771 struct objc_ivar ivar_list[ivar_count];
5775 build_ivar_list_template (tree list_type, int size)
5777 tree objc_ivar_list_record;
5778 tree array_type, decls, *chain = NULL;
5780 objc_ivar_list_record = objc_start_struct (NULL_TREE);
5782 /* int ivar_count; */
5783 decls = add_field_decl (integer_type_node, "ivar_count", &chain);
5785 /* struct objc_ivar ivar_list[]; */
5786 array_type = build_sized_array_type (list_type, size);
5787 add_field_decl (array_type, "ivar_list", &chain);
5789 objc_finish_struct (objc_ivar_list_record, decls);
5791 return objc_ivar_list_record;
5795 struct _objc__method_prototype_list *method_next;
5797 struct objc_method method_list[method_count];
5801 build_method_list_template (tree list_type, int size)
5803 tree objc_ivar_list_record;
5804 tree array_type, decls, *chain = NULL;
5806 objc_ivar_list_record = objc_start_struct (NULL_TREE);
5808 /* struct _objc__method_prototype_list *method_next; */
5809 decls = add_field_decl (objc_method_proto_list_ptr, "method_next", &chain);
5811 /* int method_count; */
5812 add_field_decl (integer_type_node, "method_count", &chain);
5814 /* struct objc_method method_list[]; */
5815 array_type = build_sized_array_type (list_type, size);
5816 add_field_decl (array_type, "method_list", &chain);
5818 objc_finish_struct (objc_ivar_list_record, decls);
5820 return objc_ivar_list_record;
5824 build_ivar_list_initializer (tree type, tree field_decl)
5826 VEC(constructor_elt,gc) *inits = NULL;
5830 VEC(constructor_elt,gc) *ivar = NULL;
5834 if (DECL_NAME (field_decl))
5835 CONSTRUCTOR_APPEND_ELT (ivar, NULL_TREE,
5836 add_objc_string (DECL_NAME (field_decl),
5839 /* Unnamed bit-field ivar (yuck). */
5840 CONSTRUCTOR_APPEND_ELT (ivar, NULL_TREE, build_int_cst (NULL_TREE, 0));
5843 encode_field_decl (field_decl,
5844 obstack_object_size (&util_obstack),
5845 OBJC_ENCODE_DONT_INLINE_DEFS);
5847 /* Null terminate string. */
5848 obstack_1grow (&util_obstack, 0);
5849 id = add_objc_string (get_identifier (XOBFINISH (&util_obstack, char *)),
5851 CONSTRUCTOR_APPEND_ELT (ivar, NULL_TREE, id);
5852 obstack_free (&util_obstack, util_firstobj);
5855 CONSTRUCTOR_APPEND_ELT (ivar, NULL_TREE, byte_position (field_decl));
5856 CONSTRUCTOR_APPEND_ELT (inits, NULL_TREE,
5857 objc_build_constructor (type, ivar));
5859 field_decl = DECL_CHAIN (field_decl);
5860 while (field_decl && TREE_CODE (field_decl) != FIELD_DECL);
5864 return objc_build_constructor (build_array_type (type, 0), inits);
5868 generate_ivars_list (tree type, const char *name, int size, tree list)
5871 VEC(constructor_elt,gc) *inits = NULL;
5873 decl = start_var_decl (type, synth_id_with_class_suffix
5874 (name, objc_implementation_context));
5876 CONSTRUCTOR_APPEND_ELT (inits, NULL_TREE, build_int_cst (NULL_TREE, size));
5877 CONSTRUCTOR_APPEND_ELT (inits, NULL_TREE, list);
5879 finish_var_decl (decl,
5880 objc_build_constructor (TREE_TYPE (decl), inits));
5885 /* Count only the fields occurring in T. */
5888 ivar_list_length (tree t)
5892 for (; t; t = DECL_CHAIN (t))
5893 if (TREE_CODE (t) == FIELD_DECL)
5900 generate_ivar_lists (void)
5902 tree initlist, ivar_list_template, chain;
5905 generating_instance_variables = 1;
5907 if (!objc_ivar_template)
5908 objc_ivar_template = build_ivar_template ();
5910 /* Only generate class variables for the root of the inheritance
5911 hierarchy since these will be the same for every class. */
5913 if (CLASS_SUPER_NAME (implementation_template) == NULL_TREE
5914 && (chain = TYPE_FIELDS (objc_class_template)))
5916 size = ivar_list_length (chain);
5918 ivar_list_template = build_ivar_list_template (objc_ivar_template, size);
5919 initlist = build_ivar_list_initializer (objc_ivar_template, chain);
5921 UOBJC_CLASS_VARIABLES_decl
5922 = generate_ivars_list (ivar_list_template, "_OBJC_CLASS_VARIABLES",
5926 UOBJC_CLASS_VARIABLES_decl = 0;
5928 chain = CLASS_IVARS (implementation_template);
5931 size = ivar_list_length (chain);
5932 ivar_list_template = build_ivar_list_template (objc_ivar_template, size);
5933 initlist = build_ivar_list_initializer (objc_ivar_template, chain);
5935 UOBJC_INSTANCE_VARIABLES_decl
5936 = generate_ivars_list (ivar_list_template, "_OBJC_INSTANCE_VARIABLES",
5940 UOBJC_INSTANCE_VARIABLES_decl = 0;
5942 generating_instance_variables = 0;
5946 build_dispatch_table_initializer (tree type, tree entries)
5948 VEC(constructor_elt,gc) *inits = NULL;
5952 VEC(constructor_elt,gc) *elems = NULL;
5955 CONSTRUCTOR_APPEND_ELT (elems, NULL_TREE,
5956 build_selector (METHOD_SEL_NAME (entries)));
5958 /* Generate the method encoding if we don't have one already. */
5959 if (! METHOD_ENCODING (entries))
5960 METHOD_ENCODING (entries) =
5961 encode_method_prototype (entries);
5963 CONSTRUCTOR_APPEND_ELT (elems, NULL_TREE,
5964 add_objc_string (METHOD_ENCODING (entries),
5967 expr = convert (ptr_type_node,
5968 build_unary_op (input_location, ADDR_EXPR,
5969 METHOD_DEFINITION (entries), 1));
5970 CONSTRUCTOR_APPEND_ELT (elems, NULL_TREE, expr);
5972 CONSTRUCTOR_APPEND_ELT (inits, NULL_TREE,
5973 objc_build_constructor (type, elems));
5975 entries = DECL_CHAIN (entries);
5979 return objc_build_constructor (build_array_type (type, 0), inits);
5982 /* To accomplish method prototyping without generating all kinds of
5983 inane warnings, the definition of the dispatch table entries were
5986 struct objc_method { SEL _cmd; ...; id (*_imp)(); };
5988 struct objc_method { SEL _cmd; ...; void *_imp; }; */
5991 build_method_template (void)
5994 tree decls, *chain = NULL;
5996 _SLT_record = objc_start_struct (get_identifier (UTAG_METHOD));
5999 decls = add_field_decl (objc_selector_type, "_cmd", &chain);
6001 /* char *method_types; */
6002 add_field_decl (string_type_node, "method_types", &chain);
6005 add_field_decl (build_pointer_type (void_type_node), "_imp", &chain);
6007 objc_finish_struct (_SLT_record, decls);
6014 generate_dispatch_table (tree type, const char *name, int size, tree list)
6017 VEC(constructor_elt,gc) *v = NULL;
6019 decl = start_var_decl (type, synth_id_with_class_suffix
6020 (name, objc_implementation_context));
6022 CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, integer_zero_node);
6023 CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, build_int_cst (integer_type_node, size));
6024 CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, list);
6026 finish_var_decl (decl,
6027 objc_build_constructor (TREE_TYPE (decl), v));
6033 mark_referenced_methods (void)
6035 struct imp_entry *impent;
6038 for (impent = imp_list; impent; impent = impent->next)
6040 chain = CLASS_CLS_METHODS (impent->imp_context);
6043 cgraph_mark_needed_node (cgraph_node (METHOD_DEFINITION (chain)));
6044 chain = DECL_CHAIN (chain);
6047 chain = CLASS_NST_METHODS (impent->imp_context);
6050 cgraph_mark_needed_node (cgraph_node (METHOD_DEFINITION (chain)));
6051 chain = DECL_CHAIN (chain);
6057 generate_dispatch_tables (void)
6059 tree initlist, chain, method_list_template;
6062 if (!objc_method_template)
6063 objc_method_template = build_method_template ();
6065 chain = CLASS_CLS_METHODS (objc_implementation_context);
6068 size = list_length (chain);
6070 method_list_template
6071 = build_method_list_template (objc_method_template, size);
6073 = build_dispatch_table_initializer (objc_method_template, chain);
6075 UOBJC_CLASS_METHODS_decl
6076 = generate_dispatch_table (method_list_template,
6077 ((TREE_CODE (objc_implementation_context)
6078 == CLASS_IMPLEMENTATION_TYPE)
6079 ? "_OBJC_CLASS_METHODS"
6080 : "_OBJC_CATEGORY_CLASS_METHODS"),
6084 UOBJC_CLASS_METHODS_decl = 0;
6086 chain = CLASS_NST_METHODS (objc_implementation_context);
6089 size = list_length (chain);
6091 method_list_template
6092 = build_method_list_template (objc_method_template, size);
6094 = build_dispatch_table_initializer (objc_method_template, chain);
6096 if (TREE_CODE (objc_implementation_context) == CLASS_IMPLEMENTATION_TYPE)
6097 UOBJC_INSTANCE_METHODS_decl
6098 = generate_dispatch_table (method_list_template,
6099 "_OBJC_INSTANCE_METHODS",
6102 /* We have a category. */
6103 UOBJC_INSTANCE_METHODS_decl
6104 = generate_dispatch_table (method_list_template,
6105 "_OBJC_CATEGORY_INSTANCE_METHODS",
6109 UOBJC_INSTANCE_METHODS_decl = 0;
6113 generate_protocol_list (tree i_or_p)
6115 tree array_type, ptype, refs_decl, lproto, e, plist;
6117 const char *ref_name;
6118 VEC(constructor_elt,gc) *v = NULL;
6120 switch (TREE_CODE (i_or_p))
6122 case CLASS_INTERFACE_TYPE:
6123 case CATEGORY_INTERFACE_TYPE:
6124 plist = CLASS_PROTOCOL_LIST (i_or_p);
6126 case PROTOCOL_INTERFACE_TYPE:
6127 plist = PROTOCOL_LIST (i_or_p);
6134 for (lproto = plist; lproto; lproto = TREE_CHAIN (lproto))
6135 if (TREE_CODE (TREE_VALUE (lproto)) == PROTOCOL_INTERFACE_TYPE
6136 && PROTOCOL_FORWARD_DECL (TREE_VALUE (lproto)))
6139 /* Build initializer. */
6140 CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, build_int_cst (NULL_TREE, 0));
6141 e = build_int_cst (build_pointer_type (objc_protocol_template), size);
6142 CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, e);
6144 for (lproto = plist; lproto; lproto = TREE_CHAIN (lproto))
6146 tree pval = TREE_VALUE (lproto);
6148 if (TREE_CODE (pval) == PROTOCOL_INTERFACE_TYPE
6149 && PROTOCOL_FORWARD_DECL (pval))
6151 e = build_unary_op (input_location, ADDR_EXPR,
6152 PROTOCOL_FORWARD_DECL (pval), 0);
6153 CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, e);
6157 /* static struct objc_protocol *refs[n]; */
6159 switch (TREE_CODE (i_or_p))
6161 case PROTOCOL_INTERFACE_TYPE:
6162 ref_name = synth_id_with_class_suffix ("_OBJC_PROTOCOL_REFS", i_or_p);
6164 case CLASS_INTERFACE_TYPE:
6165 ref_name = synth_id_with_class_suffix ("_OBJC_CLASS_PROTOCOLS", i_or_p);
6167 case CATEGORY_INTERFACE_TYPE:
6168 ref_name = synth_id_with_class_suffix ("_OBJC_CATEGORY_PROTOCOLS", i_or_p);
6174 ptype = build_pointer_type (objc_protocol_template);
6175 array_type = build_sized_array_type (ptype, size + 3);
6176 refs_decl = start_var_decl (array_type, ref_name);
6178 finish_var_decl (refs_decl,
6179 objc_build_constructor (TREE_TYPE (refs_decl), v));
6185 build_category_initializer (tree type, tree cat_name, tree class_name,
6186 tree instance_methods, tree class_methods,
6190 VEC(constructor_elt,gc) *v = NULL;
6192 CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, cat_name);
6193 CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, class_name);
6195 if (!instance_methods)
6196 CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, build_int_cst (NULL_TREE, 0));
6199 expr = convert (objc_method_list_ptr,
6200 build_unary_op (input_location, ADDR_EXPR,
6201 instance_methods, 0));
6202 CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, expr);
6205 CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, build_int_cst (NULL_TREE, 0));
6208 expr = convert (objc_method_list_ptr,
6209 build_unary_op (input_location, ADDR_EXPR,
6211 CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, expr);
6214 /* protocol_list = */
6216 CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, build_int_cst (NULL_TREE, 0));
6219 expr = convert (build_pointer_type
6221 (objc_protocol_template)),
6222 build_unary_op (input_location, ADDR_EXPR,
6224 CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, expr);
6227 return objc_build_constructor (type, v);
6230 /* struct _objc_class {
6231 struct objc_class *isa;
6232 struct objc_class *super_class;
6237 struct objc_ivar_list *ivars;
6238 struct objc_method_list *methods;
6239 if (flag_next_runtime)
6240 struct objc_cache *cache;
6242 struct sarray *dtable;
6243 struct objc_class *subclass_list;
6244 struct objc_class *sibling_class;
6246 struct objc_protocol_list *protocols;
6247 if (flag_next_runtime)
6249 void *gc_object_type;
6253 build_shared_structure_initializer (tree type, tree isa, tree super,
6254 tree name, tree size, int status,
6255 tree dispatch_table, tree ivar_list,
6259 VEC(constructor_elt,gc) *v = NULL;
6262 CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, isa);
6265 CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, super);
6268 CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, default_conversion (name));
6271 CONSTRUCTOR_APPEND_ELT (v, NULL_TREE,
6272 build_int_cst (long_integer_type_node, 0));
6275 CONSTRUCTOR_APPEND_ELT (v, NULL_TREE,
6276 build_int_cst (long_integer_type_node, status));
6278 /* instance_size = */
6279 CONSTRUCTOR_APPEND_ELT (v, NULL_TREE,
6280 convert (long_integer_type_node, size));
6282 /* objc_ivar_list = */
6284 CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, build_int_cst (NULL_TREE, 0));
6287 expr = convert (objc_ivar_list_ptr,
6288 build_unary_op (input_location, ADDR_EXPR,
6290 CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, expr);
6293 /* objc_method_list = */
6294 if (!dispatch_table)
6295 CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, build_int_cst (NULL_TREE, 0));
6298 expr = convert (objc_method_list_ptr,
6299 build_unary_op (input_location, ADDR_EXPR,
6300 dispatch_table, 0));
6301 CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, expr);
6304 if (flag_next_runtime)
6305 /* method_cache = */
6306 CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, build_int_cst (NULL_TREE, 0));
6310 CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, build_int_cst (NULL_TREE, 0));
6312 /* subclass_list = */
6313 CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, build_int_cst (NULL_TREE, 0));
6315 /* sibling_class = */
6316 CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, build_int_cst (NULL_TREE, 0));
6319 /* protocol_list = */
6320 if (! protocol_list)
6321 CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, build_int_cst (NULL_TREE, 0));
6324 expr = convert (build_pointer_type
6326 (objc_protocol_template)),
6327 build_unary_op (input_location, ADDR_EXPR,
6329 CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, expr);
6332 if (flag_next_runtime)
6334 CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, build_int_cst (NULL_TREE, 0));
6336 /* gc_object_type = NULL */
6337 CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, build_int_cst (NULL_TREE, 0));
6339 return objc_build_constructor (type, v);
6342 /* Retrieve category interface CAT_NAME (if any) associated with CLASS. */
6345 lookup_category (tree klass, tree cat_name)
6347 tree category = CLASS_CATEGORY_LIST (klass);
6349 while (category && CLASS_SUPER_NAME (category) != cat_name)
6350 category = CLASS_CATEGORY_LIST (category);
6354 /* static struct objc_category _OBJC_CATEGORY_<name> = { ... }; */
6357 generate_category (struct imp_entry *impent)
6359 tree initlist, cat_name_expr, class_name_expr;
6360 tree protocol_decl, category;
6361 tree cat = impent->imp_context;
6363 implementation_template = impent->imp_template;
6364 UOBJC_CLASS_decl = impent->class_decl;
6365 UOBJC_METACLASS_decl = impent->meta_decl;
6367 add_class_reference (CLASS_NAME (cat));
6368 cat_name_expr = add_objc_string (CLASS_SUPER_NAME (cat), class_names);
6370 class_name_expr = add_objc_string (CLASS_NAME (cat), class_names);
6372 category = lookup_category (implementation_template,
6373 CLASS_SUPER_NAME (cat));
6375 if (category && CLASS_PROTOCOL_LIST (category))
6377 generate_protocol_references (CLASS_PROTOCOL_LIST (category));
6378 protocol_decl = generate_protocol_list (category);
6383 initlist = build_category_initializer (TREE_TYPE (UOBJC_CLASS_decl),
6384 cat_name_expr, class_name_expr,
6385 UOBJC_INSTANCE_METHODS_decl,
6386 UOBJC_CLASS_METHODS_decl,
6388 /* Finish and initialize the forward decl. */
6389 finish_var_decl (UOBJC_CLASS_decl, initlist);
6392 /* static struct objc_class _OBJC_METACLASS_Foo={ ... };
6393 static struct objc_class _OBJC_CLASS_Foo={ ... }; */
6396 generate_shared_structures (struct imp_entry *impent)
6398 tree name_expr, super_expr, root_expr;
6399 tree my_root_id, my_super_id;
6400 tree cast_type, initlist, protocol_decl;
6403 objc_implementation_context = impent->imp_context;
6404 implementation_template = impent->imp_template;
6405 UOBJC_CLASS_decl = impent->class_decl;
6406 UOBJC_METACLASS_decl = impent->meta_decl;
6407 cls_flags = impent->has_cxx_cdtors ? CLS_HAS_CXX_STRUCTORS : 0 ;
6409 my_super_id = CLASS_SUPER_NAME (implementation_template);
6412 add_class_reference (my_super_id);
6414 /* Compute "my_root_id" - this is required for code generation.
6415 the "isa" for all meta class structures points to the root of
6416 the inheritance hierarchy (e.g. "__Object")... */
6417 my_root_id = my_super_id;
6420 tree my_root_int = lookup_interface (my_root_id);
6422 if (my_root_int && CLASS_SUPER_NAME (my_root_int))
6423 my_root_id = CLASS_SUPER_NAME (my_root_int);
6430 /* No super class. */
6431 my_root_id = CLASS_NAME (implementation_template);
6433 cast_type = build_pointer_type (objc_class_template);
6434 name_expr = add_objc_string (CLASS_NAME (implementation_template),
6437 /* Install class `isa' and `super' pointers at runtime. */
6439 super_expr = add_objc_string (my_super_id, class_names);
6441 super_expr = integer_zero_node;
6443 super_expr = build_c_cast (input_location,
6444 cast_type, super_expr); /* cast! */
6446 root_expr = add_objc_string (my_root_id, class_names);
6447 root_expr = build_c_cast (input_location, cast_type, root_expr); /* cast! */
6449 if (CLASS_PROTOCOL_LIST (implementation_template))
6451 generate_protocol_references
6452 (CLASS_PROTOCOL_LIST (implementation_template));
6453 protocol_decl = generate_protocol_list (implementation_template);
6458 /* static struct objc_class _OBJC_METACLASS_Foo = { ... }; */
6461 = build_shared_structure_initializer
6462 (TREE_TYPE (UOBJC_METACLASS_decl),
6463 root_expr, super_expr, name_expr,
6464 convert (integer_type_node, TYPE_SIZE_UNIT (objc_class_template)),
6466 UOBJC_CLASS_METHODS_decl,
6467 UOBJC_CLASS_VARIABLES_decl,
6470 finish_var_decl (UOBJC_METACLASS_decl, initlist);
6472 /* static struct objc_class _OBJC_CLASS_Foo={ ... }; */
6475 = build_shared_structure_initializer
6476 (TREE_TYPE (UOBJC_CLASS_decl),
6477 build_unary_op (input_location, ADDR_EXPR, UOBJC_METACLASS_decl, 0),
6478 super_expr, name_expr,
6479 convert (integer_type_node,
6480 TYPE_SIZE_UNIT (CLASS_STATIC_TEMPLATE
6481 (implementation_template))),
6482 1 /*CLS_FACTORY*/ | cls_flags,
6483 UOBJC_INSTANCE_METHODS_decl,
6484 UOBJC_INSTANCE_VARIABLES_decl,
6487 finish_var_decl (UOBJC_CLASS_decl, initlist);
6492 synth_id_with_class_suffix (const char *preamble, tree ctxt)
6494 static char string[BUFSIZE];
6496 switch (TREE_CODE (ctxt))
6498 case CLASS_IMPLEMENTATION_TYPE:
6499 case CLASS_INTERFACE_TYPE:
6500 sprintf (string, "%s_%s", preamble,
6501 IDENTIFIER_POINTER (CLASS_NAME (ctxt)));
6503 case CATEGORY_IMPLEMENTATION_TYPE:
6504 case CATEGORY_INTERFACE_TYPE:
6506 /* We have a category. */
6507 const char *const class_name
6508 = IDENTIFIER_POINTER (CLASS_NAME (objc_implementation_context));
6509 const char *const class_super_name
6510 = IDENTIFIER_POINTER (CLASS_SUPER_NAME (objc_implementation_context));
6511 sprintf (string, "%s_%s_%s", preamble, class_name, class_super_name);
6514 case PROTOCOL_INTERFACE_TYPE:
6516 const char *protocol_name = IDENTIFIER_POINTER (PROTOCOL_NAME (ctxt));
6517 sprintf (string, "%s_%s", preamble, protocol_name);
6527 /* If type is empty or only type qualifiers are present, add default
6528 type of id (otherwise grokdeclarator will default to int). */
6530 adjust_type_for_id_default (tree type)
6533 type = make_node (TREE_LIST);
6535 if (!TREE_VALUE (type))
6536 TREE_VALUE (type) = objc_object_type;
6537 else if (TREE_CODE (TREE_VALUE (type)) == RECORD_TYPE
6538 && TYPED_OBJECT (TREE_VALUE (type)))
6539 error ("can not use an object as parameter to a method");
6546 selector ':' '(' typename ')' identifier
6549 Transform an Objective-C keyword argument into
6550 the C equivalent parameter declarator.
6552 In: key_name, an "identifier_node" (optional).
6553 arg_type, a "tree_list" (optional).
6554 arg_name, an "identifier_node".
6555 attributes, a optional tree containing param attributes.
6557 Note: It would be really nice to strongly type the preceding
6558 arguments in the function prototype; however, then I
6559 could not use the "accessor" macros defined in "tree.h".
6561 Out: an instance of "keyword_decl". */
6564 objc_build_keyword_decl (tree key_name, tree arg_type,
6565 tree arg_name, tree attributes)
6570 warning_at (input_location, OPT_Wattributes,
6571 "method parameter attributes are not available in this "
6572 "version of the compiler, (ignored)");
6574 /* If no type is specified, default to "id". */
6575 arg_type = adjust_type_for_id_default (arg_type);
6577 keyword_decl = make_node (KEYWORD_DECL);
6579 TREE_TYPE (keyword_decl) = arg_type;
6580 KEYWORD_ARG_NAME (keyword_decl) = arg_name;
6581 KEYWORD_KEY_NAME (keyword_decl) = key_name;
6583 return keyword_decl;
6586 /* Given a chain of keyword_decl's, synthesize the full keyword selector. */
6588 build_keyword_selector (tree selector)
6591 tree key_chain, key_name;
6594 /* Scan the selector to see how much space we'll need. */
6595 for (key_chain = selector; key_chain; key_chain = TREE_CHAIN (key_chain))
6597 switch (TREE_CODE (selector))
6600 key_name = KEYWORD_KEY_NAME (key_chain);
6603 key_name = TREE_PURPOSE (key_chain);
6610 len += IDENTIFIER_LENGTH (key_name) + 1;
6612 /* Just a ':' arg. */
6616 buf = (char *) alloca (len + 1);
6617 /* Start the buffer out as an empty string. */
6620 for (key_chain = selector; key_chain; key_chain = TREE_CHAIN (key_chain))
6622 switch (TREE_CODE (selector))
6625 key_name = KEYWORD_KEY_NAME (key_chain);
6628 key_name = TREE_PURPOSE (key_chain);
6629 /* The keyword decl chain will later be used as a function
6630 argument chain. Unhook the selector itself so as to not
6631 confuse other parts of the compiler. */
6632 TREE_PURPOSE (key_chain) = NULL_TREE;
6639 strcat (buf, IDENTIFIER_POINTER (key_name));
6643 return get_identifier (buf);
6646 /* Used for declarations and definitions. */
6649 build_method_decl (enum tree_code code, tree ret_type, tree selector,
6650 tree add_args, bool ellipsis)
6654 /* If no type is specified, default to "id". */
6655 ret_type = adjust_type_for_id_default (ret_type);
6657 method_decl = make_node (code);
6658 TREE_TYPE (method_decl) = ret_type;
6660 /* If we have a keyword selector, create an identifier_node that
6661 represents the full selector name (`:' included)... */
6662 if (TREE_CODE (selector) == KEYWORD_DECL)
6664 METHOD_SEL_NAME (method_decl) = build_keyword_selector (selector);
6665 METHOD_SEL_ARGS (method_decl) = selector;
6666 METHOD_ADD_ARGS (method_decl) = add_args;
6667 METHOD_ADD_ARGS_ELLIPSIS_P (method_decl) = ellipsis;
6671 METHOD_SEL_NAME (method_decl) = selector;
6672 METHOD_SEL_ARGS (method_decl) = NULL_TREE;
6673 METHOD_ADD_ARGS (method_decl) = NULL_TREE;
6679 #define METHOD_DEF 0
6680 #define METHOD_REF 1
6682 /* This routine processes objective-c method attributes. */
6685 objc_decl_method_attributes (tree *node, tree attributes, int flags)
6687 tree sentinel_attr = lookup_attribute ("sentinel", attributes);
6690 /* hackery to make an obj method look like a function type. */
6691 tree rettype = TREE_TYPE (*node);
6692 TREE_TYPE (*node) = build_function_type (TREE_VALUE (rettype),
6693 get_arg_type_list (*node, METHOD_REF, 0));
6694 decl_attributes (node, attributes, flags);
6695 METHOD_TYPE_ATTRIBUTES (*node) = TYPE_ATTRIBUTES (TREE_TYPE (*node));
6696 TREE_TYPE (*node) = rettype;
6699 decl_attributes (node, attributes, flags);
6703 objc_method_decl (enum tree_code opcode)
6705 return opcode == INSTANCE_METHOD_DECL || opcode == CLASS_METHOD_DECL;
6708 /* Used by `build_objc_method_call' and `comp_proto_with_proto'. Return
6709 an argument list for method METH. CONTEXT is either METHOD_DEF or
6710 METHOD_REF, saying whether we are trying to define a method or call
6711 one. SUPERFLAG says this is for a send to super; this makes a
6712 difference for the NeXT calling sequence in which the lookup and
6713 the method call are done together. If METH is null, user-defined
6714 arguments (i.e., beyond self and _cmd) shall be represented by `...'. */
6717 get_arg_type_list (tree meth, int context, int superflag)
6721 /* Receiver type. */
6722 if (flag_next_runtime && superflag)
6723 arglist = build_tree_list (NULL_TREE, objc_super_type);
6724 else if (context == METHOD_DEF && TREE_CODE (meth) == INSTANCE_METHOD_DECL)
6725 arglist = build_tree_list (NULL_TREE, objc_instance_type);
6727 arglist = build_tree_list (NULL_TREE, objc_object_type);
6729 /* Selector type - will eventually change to `int'. */
6730 chainon (arglist, build_tree_list (NULL_TREE, objc_selector_type));
6732 /* No actual method prototype given -- assume that remaining arguments
6737 /* Build a list of argument types. */
6738 for (akey = METHOD_SEL_ARGS (meth); akey; akey = DECL_CHAIN (akey))
6740 tree arg_type = TREE_VALUE (TREE_TYPE (akey));
6742 /* Decay argument types for the underlying C function as appropriate. */
6743 arg_type = objc_decay_parm_type (arg_type);
6745 chainon (arglist, build_tree_list (NULL_TREE, arg_type));
6748 if (METHOD_ADD_ARGS (meth))
6750 for (akey = TREE_CHAIN (METHOD_ADD_ARGS (meth));
6751 akey; akey = TREE_CHAIN (akey))
6753 tree arg_type = TREE_TYPE (TREE_VALUE (akey));
6755 arg_type = objc_decay_parm_type (arg_type);
6757 chainon (arglist, build_tree_list (NULL_TREE, arg_type));
6760 if (!METHOD_ADD_ARGS_ELLIPSIS_P (meth))
6761 goto lack_of_ellipsis;
6766 chainon (arglist, OBJC_VOID_AT_END);
6773 check_duplicates (hash hsh, int methods, int is_class)
6775 tree meth = NULL_TREE;
6783 /* We have two or more methods with the same name but
6787 /* But just how different are those types? If
6788 -Wno-strict-selector-match is specified, we shall not
6789 complain if the differences are solely among types with
6790 identical size and alignment. */
6791 if (!warn_strict_selector_match)
6793 for (loop = hsh->list; loop; loop = loop->next)
6794 if (!comp_proto_with_proto (meth, loop->value, 0))
6803 bool type = TREE_CODE (meth) == INSTANCE_METHOD_DECL;
6805 warning_at (input_location, 0,
6806 "multiple methods named %<%c%E%> found",
6807 (is_class ? '+' : '-'),
6808 METHOD_SEL_NAME (meth));
6809 inform (DECL_SOURCE_LOCATION (meth), "using %<%c%s%>",
6811 identifier_to_locale (gen_method_decl (meth)));
6815 bool type = TREE_CODE (meth) == INSTANCE_METHOD_DECL;
6817 warning_at (input_location, 0,
6818 "multiple selectors named %<%c%E%> found",
6819 (is_class ? '+' : '-'),
6820 METHOD_SEL_NAME (meth));
6821 inform (DECL_SOURCE_LOCATION (meth), "found %<%c%s%>",
6823 identifier_to_locale (gen_method_decl (meth)));
6826 for (loop = hsh->list; loop; loop = loop->next)
6828 bool type = TREE_CODE (loop->value) == INSTANCE_METHOD_DECL;
6830 inform (DECL_SOURCE_LOCATION (loop->value), "also found %<%c%s%>",
6832 identifier_to_locale (gen_method_decl (loop->value)));
6839 /* If RECEIVER is a class reference, return the identifier node for
6840 the referenced class. RECEIVER is created by objc_get_class_reference,
6841 so we check the exact form created depending on which runtimes are
6845 receiver_is_class_object (tree receiver, int self, int super)
6847 tree chain, exp, arg;
6849 /* The receiver is 'self' or 'super' in the context of a class method. */
6850 if (objc_method_context
6851 && TREE_CODE (objc_method_context) == CLASS_METHOD_DECL
6854 ? CLASS_SUPER_NAME (implementation_template)
6855 : CLASS_NAME (implementation_template));
6857 if (flag_next_runtime)
6859 /* The receiver is a variable created by
6860 build_class_reference_decl. */
6861 if (TREE_CODE (receiver) == VAR_DECL && IS_CLASS (TREE_TYPE (receiver)))
6862 /* Look up the identifier. */
6863 for (chain = cls_ref_chain; chain; chain = TREE_CHAIN (chain))
6864 if (TREE_PURPOSE (chain) == receiver)
6865 return TREE_VALUE (chain);
6868 /* The receiver is a function call that returns an id. Check if
6869 it is a call to objc_getClass, if so, pick up the class name. */
6870 if (TREE_CODE (receiver) == CALL_EXPR
6871 && (exp = CALL_EXPR_FN (receiver))
6872 && TREE_CODE (exp) == ADDR_EXPR
6873 && (exp = TREE_OPERAND (exp, 0))
6874 && TREE_CODE (exp) == FUNCTION_DECL
6875 /* For some reason, we sometimes wind up with multiple FUNCTION_DECL
6876 prototypes for objc_get_class(). Thankfully, they seem to share the
6877 same function type. */
6878 && TREE_TYPE (exp) == TREE_TYPE (objc_get_class_decl)
6879 && !strcmp (IDENTIFIER_POINTER (DECL_NAME (exp)), TAG_GETCLASS)
6880 /* We have a call to objc_get_class/objc_getClass! */
6881 && (arg = CALL_EXPR_ARG (receiver, 0)))
6884 if (TREE_CODE (arg) == ADDR_EXPR
6885 && (arg = TREE_OPERAND (arg, 0))
6886 && TREE_CODE (arg) == STRING_CST)
6887 /* Finally, we have the class name. */
6888 return get_identifier (TREE_STRING_POINTER (arg));
6893 /* If we are currently building a message expr, this holds
6894 the identifier of the selector of the message. This is
6895 used when printing warnings about argument mismatches. */
6897 static tree current_objc_message_selector = 0;
6900 objc_message_selector (void)
6902 return current_objc_message_selector;
6905 /* Construct an expression for sending a message.
6906 MESS has the object to send to in TREE_PURPOSE
6907 and the argument list (including selector) in TREE_VALUE.
6909 (*(<abstract_decl>(*)())_msg)(receiver, selTransTbl[n], ...);
6910 (*(<abstract_decl>(*)())_msgSuper)(receiver, selTransTbl[n], ...); */
6913 objc_build_message_expr (tree mess)
6915 tree receiver = TREE_PURPOSE (mess);
6918 tree args = TREE_PURPOSE (TREE_VALUE (mess));
6920 tree args = TREE_VALUE (mess);
6922 tree method_params = NULL_TREE;
6924 if (TREE_CODE (receiver) == ERROR_MARK || TREE_CODE (args) == ERROR_MARK)
6925 return error_mark_node;
6927 /* Obtain the full selector name. */
6928 switch (TREE_CODE (args))
6930 case IDENTIFIER_NODE:
6931 /* A unary selector. */
6935 sel_name = build_keyword_selector (args);
6941 /* Build the parameter list to give to the method. */
6942 if (TREE_CODE (args) == TREE_LIST)
6944 method_params = chainon (args, TREE_VALUE (TREE_VALUE (mess)));
6947 tree chain = args, prev = NULL_TREE;
6949 /* We have a keyword selector--check for comma expressions. */
6952 tree element = TREE_VALUE (chain);
6954 /* We have a comma expression, must collapse... */
6955 if (TREE_CODE (element) == TREE_LIST)
6958 TREE_CHAIN (prev) = element;
6963 chain = TREE_CHAIN (chain);
6965 method_params = args;
6970 if (processing_template_decl)
6971 /* Must wait until template instantiation time. */
6972 return build_min_nt (MESSAGE_SEND_EXPR, receiver, sel_name,
6976 return objc_finish_message_expr (receiver, sel_name, method_params);
6979 /* Look up method SEL_NAME that would be suitable for receiver
6980 of type 'id' (if IS_CLASS is zero) or 'Class' (if IS_CLASS is
6981 nonzero), and report on any duplicates. */
6984 lookup_method_in_hash_lists (tree sel_name, int is_class)
6986 hash method_prototype = NULL;
6989 method_prototype = hash_lookup (nst_method_hash_list,
6992 if (!method_prototype)
6994 method_prototype = hash_lookup (cls_method_hash_list,
6999 return check_duplicates (method_prototype, 1, is_class);
7002 /* The 'objc_finish_message_expr' routine is called from within
7003 'objc_build_message_expr' for non-template functions. In the case of
7004 C++ template functions, it is called from 'build_expr_from_tree'
7005 (in decl2.c) after RECEIVER and METHOD_PARAMS have been expanded. */
7008 objc_finish_message_expr (tree receiver, tree sel_name, tree method_params)
7010 tree method_prototype = NULL_TREE, rprotos = NULL_TREE, rtype;
7011 tree selector, retval, class_tree;
7012 int self, super, have_cast;
7014 /* We have used the receiver, so mark it as read. */
7015 mark_exp_read (receiver);
7017 /* Extract the receiver of the message, as well as its type
7018 (where the latter may take the form of a cast or be inferred
7019 from the implementation context). */
7021 while (TREE_CODE (rtype) == COMPOUND_EXPR
7022 || TREE_CODE (rtype) == MODIFY_EXPR
7023 || CONVERT_EXPR_P (rtype)
7024 || TREE_CODE (rtype) == COMPONENT_REF)
7025 rtype = TREE_OPERAND (rtype, 0);
7027 self = (rtype == self_decl);
7028 super = (rtype == UOBJC_SUPER_decl);
7029 rtype = TREE_TYPE (receiver);
7031 have_cast = (TREE_CODE (receiver) == NOP_EXPR
7032 || (TREE_CODE (receiver) == COMPOUND_EXPR
7033 && !IS_SUPER (rtype)));
7035 /* If we are calling [super dealloc], reset our warning flag. */
7036 if (super && !strcmp ("dealloc", IDENTIFIER_POINTER (sel_name)))
7037 should_call_super_dealloc = 0;
7039 /* If the receiver is a class object, retrieve the corresponding
7040 @interface, if one exists. */
7041 class_tree = receiver_is_class_object (receiver, self, super);
7043 /* Now determine the receiver type (if an explicit cast has not been
7048 rtype = lookup_interface (class_tree);
7049 /* Handle `self' and `super'. */
7052 if (!CLASS_SUPER_NAME (implementation_template))
7054 error ("no super class declared in @interface for %qE",
7055 CLASS_NAME (implementation_template));
7056 return error_mark_node;
7058 rtype = lookup_interface (CLASS_SUPER_NAME (implementation_template));
7061 rtype = lookup_interface (CLASS_NAME (implementation_template));
7064 /* If receiver is of type `id' or `Class' (or if the @interface for a
7065 class is not visible), we shall be satisfied with the existence of
7066 any instance or class method. */
7067 if (objc_is_id (rtype))
7069 class_tree = (IS_CLASS (rtype) ? objc_class_name : NULL_TREE);
7070 rprotos = (TYPE_HAS_OBJC_INFO (TREE_TYPE (rtype))
7071 ? TYPE_OBJC_PROTOCOL_LIST (TREE_TYPE (rtype))
7077 /* If messaging 'id <Protos>' or 'Class <Proto>', first search
7078 in protocols themselves for the method prototype. */
7080 = lookup_method_in_protocol_list (rprotos, sel_name,
7081 class_tree != NULL_TREE);
7083 /* If messaging 'Class <Proto>' but did not find a class method
7084 prototype, search for an instance method instead, and warn
7085 about having done so. */
7086 if (!method_prototype && !rtype && class_tree != NULL_TREE)
7089 = lookup_method_in_protocol_list (rprotos, sel_name, 0);
7091 if (method_prototype)
7092 warning (0, "found %<-%E%> instead of %<+%E%> in protocol(s)",
7093 sel_name, sel_name);
7099 tree orig_rtype = rtype;
7101 if (TREE_CODE (rtype) == POINTER_TYPE)
7102 rtype = TREE_TYPE (rtype);
7103 /* Traverse typedef aliases */
7104 while (TREE_CODE (rtype) == RECORD_TYPE && OBJC_TYPE_NAME (rtype)
7105 && TREE_CODE (OBJC_TYPE_NAME (rtype)) == TYPE_DECL
7106 && DECL_ORIGINAL_TYPE (OBJC_TYPE_NAME (rtype)))
7107 rtype = DECL_ORIGINAL_TYPE (OBJC_TYPE_NAME (rtype));
7108 if (TYPED_OBJECT (rtype))
7110 rprotos = TYPE_OBJC_PROTOCOL_LIST (rtype);
7111 rtype = TYPE_OBJC_INTERFACE (rtype);
7113 /* If we could not find an @interface declaration, we must have
7114 only seen a @class declaration; so, we cannot say anything
7115 more intelligent about which methods the receiver will
7117 if (!rtype || TREE_CODE (rtype) == IDENTIFIER_NODE)
7120 /* We could not find an @interface declaration, yet Message maybe in a
7121 @class's protocol. */
7122 if (!method_prototype && rprotos)
7124 = lookup_method_in_protocol_list (rprotos, sel_name, 0);
7126 else if (TREE_CODE (rtype) == CLASS_INTERFACE_TYPE
7127 || TREE_CODE (rtype) == CLASS_IMPLEMENTATION_TYPE)
7129 /* We have a valid ObjC class name. Look up the method name
7130 in the published @interface for the class (and its
7133 = lookup_method_static (rtype, sel_name, class_tree != NULL_TREE);
7135 /* If the method was not found in the @interface, it may still
7136 exist locally as part of the @implementation. */
7137 if (!method_prototype && objc_implementation_context
7138 && CLASS_NAME (objc_implementation_context)
7139 == OBJC_TYPE_NAME (rtype))
7143 ? CLASS_CLS_METHODS (objc_implementation_context)
7144 : CLASS_NST_METHODS (objc_implementation_context)),
7147 /* If we haven't found a candidate method by now, try looking for
7148 it in the protocol list. */
7149 if (!method_prototype && rprotos)
7151 = lookup_method_in_protocol_list (rprotos, sel_name,
7152 class_tree != NULL_TREE);
7156 warning (0, "invalid receiver type %qs",
7157 identifier_to_locale (gen_type_name (orig_rtype)));
7158 /* After issuing the "invalid receiver" warning, perform method
7159 lookup as if we were messaging 'id'. */
7160 rtype = rprotos = NULL_TREE;
7165 /* For 'id' or 'Class' receivers, search in the global hash table
7166 as a last resort. For all receivers, warn if protocol searches
7168 if (!method_prototype)
7171 warning (0, "%<%c%E%> not found in protocol(s)",
7172 (class_tree ? '+' : '-'),
7177 = lookup_method_in_hash_lists (sel_name, class_tree != NULL_TREE);
7180 if (!method_prototype && in_objc_property_setter_name_context)
7181 error ("readonly property can not be set");
7182 else if (!method_prototype)
7184 static bool warn_missing_methods = false;
7187 warning (0, "%qE may not respond to %<%c%E%>",
7188 OBJC_TYPE_NAME (rtype),
7189 (class_tree ? '+' : '-'),
7191 /* If we are messaging an 'id' or 'Class' object and made it here,
7192 then we have failed to find _any_ instance or class method,
7195 warning (0, "no %<%c%E%> method found",
7196 (class_tree ? '+' : '-'),
7199 if (!warn_missing_methods)
7201 warning_at (input_location,
7202 0, "(Messages without a matching method signature");
7203 warning_at (input_location,
7204 0, "will be assumed to return %<id%> and accept");
7205 warning_at (input_location,
7206 0, "%<...%> as arguments.)");
7207 warn_missing_methods = true;
7211 /* Save the selector name for printing error messages. */
7212 current_objc_message_selector = sel_name;
7214 /* Build the parameters list for looking up the method.
7215 These are the object itself and the selector. */
7217 if (flag_typed_selectors)
7218 selector = build_typed_selector_reference (input_location,
7219 sel_name, method_prototype);
7221 selector = build_selector_reference (input_location, sel_name);
7223 retval = build_objc_method_call (input_location, super, method_prototype,
7225 selector, method_params);
7227 current_objc_message_selector = 0;
7232 /* Build a tree expression to send OBJECT the operation SELECTOR,
7233 looking up the method on object LOOKUP_OBJECT (often same as OBJECT),
7234 assuming the method has prototype METHOD_PROTOTYPE.
7235 (That is an INSTANCE_METHOD_DECL or CLASS_METHOD_DECL.)
7236 LOC is the location of the expression to build.
7237 Use METHOD_PARAMS as list of args to pass to the method.
7238 If SUPER_FLAG is nonzero, we look up the superclass's method. */
7241 build_objc_method_call (location_t loc, int super_flag, tree method_prototype,
7242 tree lookup_object, tree selector,
7245 tree sender = (super_flag ? umsg_super_decl :
7246 (!flag_next_runtime || flag_nil_receivers
7247 ? (flag_objc_direct_dispatch
7250 : umsg_nonnil_decl));
7251 tree rcv_p = (super_flag ? objc_super_type : objc_object_type);
7252 VEC(tree, gc) *parms = NULL;
7253 unsigned nparm = (method_params ? list_length (method_params) : 0);
7255 /* If a prototype for the method to be called exists, then cast
7256 the sender's return type and arguments to match that of the method.
7257 Otherwise, leave sender as is. */
7260 ? TREE_VALUE (TREE_TYPE (method_prototype))
7261 : objc_object_type);
7263 tree method_param_types =
7264 get_arg_type_list (method_prototype, METHOD_REF, super_flag);
7265 tree ftype = build_function_type (ret_type, method_param_types);
7269 if (method_prototype && METHOD_TYPE_ATTRIBUTES (method_prototype))
7270 ftype = build_type_attribute_variant (
7271 ftype, METHOD_TYPE_ATTRIBUTES (method_prototype));
7273 sender_cast = build_pointer_type (ftype);
7275 if (method_prototype && TREE_DEPRECATED (method_prototype))
7276 objc_warn_deprecated_use (method_prototype, NULL_TREE);
7278 lookup_object = build_c_cast (loc, rcv_p, lookup_object);
7280 /* Use SAVE_EXPR to avoid evaluating the receiver twice. */
7281 lookup_object = save_expr (lookup_object);
7283 /* Param list + 2 slots for object and selector. */
7284 parms = VEC_alloc (tree, gc, nparm + 2);
7286 if (flag_next_runtime)
7288 /* If we are returning a struct in memory, and the address
7289 of that memory location is passed as a hidden first
7290 argument, then change which messenger entry point this
7291 expr will call. NB: Note that sender_cast remains
7292 unchanged (it already has a struct return type). */
7293 if (!targetm.calls.struct_value_rtx (0, 0)
7294 && (TREE_CODE (ret_type) == RECORD_TYPE
7295 || TREE_CODE (ret_type) == UNION_TYPE)
7296 && targetm.calls.return_in_memory (ret_type, 0))
7297 sender = (super_flag ? umsg_super_stret_decl :
7298 flag_nil_receivers ? umsg_stret_decl : umsg_nonnil_stret_decl);
7300 method = build_fold_addr_expr_loc (input_location, sender);
7301 /* Pass the object to the method. */
7302 VEC_quick_push (tree, parms, lookup_object);
7306 /* This is the portable (GNU) way. */
7307 /* First, call the lookup function to get a pointer to the method,
7308 then cast the pointer, then call it with the method arguments. */
7309 VEC(tree, gc) *tv = VEC_alloc (tree, gc, 2);
7310 VEC_quick_push (tree, tv, lookup_object);
7311 VEC_quick_push (tree, tv, selector);
7312 method = build_function_call_vec (loc, sender, tv, NULL);
7313 VEC_free (tree, gc, tv);
7315 /* Pass the appropriate object to the method. */
7316 VEC_quick_push (tree, parms, (super_flag ? self_decl : lookup_object));
7319 /* Pass the selector to the method. */
7320 VEC_quick_push (tree, parms, selector);
7321 /* Now append the remainder of the parms. */
7323 for (; method_params; method_params = TREE_CHAIN (method_params))
7324 VEC_quick_push (tree, parms, TREE_VALUE (method_params));
7326 /* Build an obj_type_ref, with the correct cast for the method call. */
7327 t = build3 (OBJ_TYPE_REF, sender_cast, method,
7328 lookup_object, size_zero_node);
7329 t = build_function_call_vec (loc, t, parms, NULL);\
7330 VEC_free (tree, gc, parms);
7335 build_protocol_reference (tree p)
7338 const char *proto_name;
7340 /* static struct _objc_protocol _OBJC_PROTOCOL_<mumble>; */
7342 proto_name = synth_id_with_class_suffix ("_OBJC_PROTOCOL", p);
7343 decl = start_var_decl (objc_protocol_template, proto_name);
7345 PROTOCOL_FORWARD_DECL (p) = decl;
7348 /* This function is called by the parser when (and only when) a
7349 @protocol() expression is found, in order to compile it. */
7351 objc_build_protocol_expr (tree protoname)
7354 tree p = lookup_protocol (protoname);
7358 error ("cannot find protocol declaration for %qE",
7360 return error_mark_node;
7363 if (!PROTOCOL_FORWARD_DECL (p))
7364 build_protocol_reference (p);
7366 expr = build_unary_op (input_location,
7367 ADDR_EXPR, PROTOCOL_FORWARD_DECL (p), 0);
7369 /* ??? Ideally we'd build the reference with objc_protocol_type directly,
7370 if we have it, rather than converting it here. */
7371 expr = convert (objc_protocol_type, expr);
7373 /* The @protocol() expression is being compiled into a pointer to a
7374 statically allocated instance of the Protocol class. To become
7375 usable at runtime, the 'isa' pointer of the instance need to be
7376 fixed up at runtime by the runtime library, to point to the
7377 actual 'Protocol' class. */
7379 /* For the GNU runtime, put the static Protocol instance in the list
7380 of statically allocated instances, so that we make sure that its
7381 'isa' pointer is fixed up at runtime by the GNU runtime library
7382 to point to the Protocol class (at runtime, when loading the
7383 module, the GNU runtime library loops on the statically allocated
7384 instances (as found in the defs field in objc_symtab) and fixups
7385 all the 'isa' pointers of those objects). */
7386 if (! flag_next_runtime)
7388 /* This type is a struct containing the fields of a Protocol
7389 object. (Cfr. objc_protocol_type instead is the type of a pointer
7390 to such a struct). */
7391 tree protocol_struct_type = xref_tag
7392 (RECORD_TYPE, get_identifier (PROTOCOL_OBJECT_CLASS_NAME));
7395 /* Look for the list of Protocol statically allocated instances
7396 to fixup at runtime. Create a new list to hold Protocol
7397 statically allocated instances, if the list is not found. At
7398 present there is only another list, holding NSConstantString
7399 static instances to be fixed up at runtime. */
7400 for (chain = &objc_static_instances;
7401 *chain && TREE_VALUE (*chain) != protocol_struct_type;
7402 chain = &TREE_CHAIN (*chain));
7405 *chain = tree_cons (NULL_TREE, protocol_struct_type, NULL_TREE);
7406 add_objc_string (OBJC_TYPE_NAME (protocol_struct_type),
7410 /* Add this statically allocated instance to the Protocol list. */
7411 TREE_PURPOSE (*chain) = tree_cons (NULL_TREE,
7412 PROTOCOL_FORWARD_DECL (p),
7413 TREE_PURPOSE (*chain));
7420 /* This function is called by the parser when a @selector() expression
7421 is found, in order to compile it. It is only called by the parser
7422 and only to compile a @selector(). LOC is the location of the
7425 objc_build_selector_expr (location_t loc, tree selnamelist)
7429 /* Obtain the full selector name. */
7430 switch (TREE_CODE (selnamelist))
7432 case IDENTIFIER_NODE:
7433 /* A unary selector. */
7434 selname = selnamelist;
7437 selname = build_keyword_selector (selnamelist);
7443 /* If we are required to check @selector() expressions as they
7444 are found, check that the selector has been declared. */
7445 if (warn_undeclared_selector)
7447 /* Look the selector up in the list of all known class and
7448 instance methods (up to this line) to check that the selector
7452 /* First try with instance methods. */
7453 hsh = hash_lookup (nst_method_hash_list, selname);
7455 /* If not found, try with class methods. */
7458 hsh = hash_lookup (cls_method_hash_list, selname);
7461 /* If still not found, print out a warning. */
7464 warning (0, "undeclared selector %qE", selname);
7469 if (flag_typed_selectors)
7470 return build_typed_selector_reference (loc, selname, 0);
7472 return build_selector_reference (loc, selname);
7475 /* This is used to implement @encode(). See gcc/doc/objc.texi,
7476 section '@encode'. */
7478 objc_build_encode_expr (tree type)
7483 encode_type (type, obstack_object_size (&util_obstack),
7484 OBJC_ENCODE_INLINE_DEFS);
7485 obstack_1grow (&util_obstack, 0); /* null terminate string */
7486 string = XOBFINISH (&util_obstack, const char *);
7488 /* Synthesize a string that represents the encoded struct/union. */
7489 result = my_build_string (strlen (string) + 1, string);
7490 obstack_free (&util_obstack, util_firstobj);
7495 build_ivar_reference (tree id)
7497 if (TREE_CODE (objc_method_context) == CLASS_METHOD_DECL)
7499 /* Historically, a class method that produced objects (factory
7500 method) would assign `self' to the instance that it
7501 allocated. This would effectively turn the class method into
7502 an instance method. Following this assignment, the instance
7503 variables could be accessed. That practice, while safe,
7504 violates the simple rule that a class method should not refer
7505 to an instance variable. It's better to catch the cases
7506 where this is done unknowingly than to support the above
7508 warning (0, "instance variable %qE accessed in class method",
7510 self_decl = convert (objc_instance_type, self_decl); /* cast */
7513 return objc_build_component_ref (build_indirect_ref (input_location,
7514 self_decl, RO_ARROW),
7518 /* Compute a hash value for a given method SEL_NAME. */
7521 hash_func (tree sel_name)
7523 const unsigned char *s
7524 = (const unsigned char *)IDENTIFIER_POINTER (sel_name);
7528 h = h * 67 + *s++ - 113;
7535 nst_method_hash_list = ggc_alloc_cleared_vec_hash (SIZEHASHTABLE);
7536 cls_method_hash_list = ggc_alloc_cleared_vec_hash (SIZEHASHTABLE);
7538 cls_name_hash_list = ggc_alloc_cleared_vec_hash (SIZEHASHTABLE);
7539 als_name_hash_list = ggc_alloc_cleared_vec_hash (SIZEHASHTABLE);
7541 /* Initialize the hash table used to hold the constant string objects. */
7542 string_htab = htab_create_ggc (31, string_hash,
7546 /* This routine adds sel_name to the hash list. sel_name is a class or alias
7547 name for the class. If alias name, then value is its underlying class.
7548 If class, the value is NULL_TREE. */
7551 hash_class_name_enter (hash *hashlist, tree sel_name, tree value)
7554 int slot = hash_func (sel_name) % SIZEHASHTABLE;
7556 obj = ggc_alloc_hashed_entry ();
7557 if (value != NULL_TREE)
7559 /* Save the underlying class for the 'alias' in the hash table */
7560 attr obj_attr = ggc_alloc_hashed_attribute ();
7561 obj_attr->value = value;
7562 obj->list = obj_attr;
7566 obj->next = hashlist[slot];
7567 obj->key = sel_name;
7569 hashlist[slot] = obj; /* append to front */
7574 Searches in the hash table looking for a match for class or alias name.
7578 hash_class_name_lookup (hash *hashlist, tree sel_name)
7582 target = hashlist[hash_func (sel_name) % SIZEHASHTABLE];
7586 if (sel_name == target->key)
7589 target = target->next;
7594 /* WARNING!!!! hash_enter is called with a method, and will peek
7595 inside to find its selector! But hash_lookup is given a selector
7596 directly, and looks for the selector that's inside the found
7597 entry's key (method) for comparison. */
7600 hash_enter (hash *hashlist, tree method)
7603 int slot = hash_func (METHOD_SEL_NAME (method)) % SIZEHASHTABLE;
7605 obj = ggc_alloc_hashed_entry ();
7607 obj->next = hashlist[slot];
7610 hashlist[slot] = obj; /* append to front */
7614 hash_lookup (hash *hashlist, tree sel_name)
7618 target = hashlist[hash_func (sel_name) % SIZEHASHTABLE];
7622 if (sel_name == METHOD_SEL_NAME (target->key))
7625 target = target->next;
7631 hash_add_attr (hash entry, tree value)
7635 obj = ggc_alloc_hashed_attribute ();
7636 obj->next = entry->list;
7639 entry->list = obj; /* append to front */
7643 lookup_method (tree mchain, tree method)
7647 if (TREE_CODE (method) == IDENTIFIER_NODE)
7650 key = METHOD_SEL_NAME (method);
7654 if (METHOD_SEL_NAME (mchain) == key)
7657 mchain = DECL_CHAIN (mchain);
7662 /* Look up a class (if OBJC_LOOKUP_CLASS is set in FLAGS) or instance method
7663 in INTERFACE, along with any categories and protocols attached thereto.
7664 If method is not found, and the OBJC_LOOKUP_NO_SUPER is _not_ set in FLAGS,
7665 recursively examine the INTERFACE's superclass. If OBJC_LOOKUP_CLASS is
7666 set, OBJC_LOOKUP_NO_SUPER is cleared, and no suitable class method could
7667 be found in INTERFACE or any of its superclasses, look for an _instance_
7668 method of the same name in the root class as a last resort.
7670 If a suitable method cannot be found, return NULL_TREE. */
7673 lookup_method_static (tree interface, tree ident, int flags)
7675 tree meth = NULL_TREE, root_inter = NULL_TREE;
7676 tree inter = interface;
7677 int is_class = (flags & OBJC_LOOKUP_CLASS);
7678 int no_superclasses = (flags & OBJC_LOOKUP_NO_SUPER);
7682 tree chain = is_class ? CLASS_CLS_METHODS (inter) : CLASS_NST_METHODS (inter);
7683 tree category = inter;
7685 /* First, look up the method in the class itself. */
7686 if ((meth = lookup_method (chain, ident)))
7689 /* Failing that, look for the method in each category of the class. */
7690 while ((category = CLASS_CATEGORY_LIST (category)))
7692 chain = is_class ? CLASS_CLS_METHODS (category) : CLASS_NST_METHODS (category);
7694 /* Check directly in each category. */
7695 if ((meth = lookup_method (chain, ident)))
7698 /* Failing that, check in each category's protocols. */
7699 if (CLASS_PROTOCOL_LIST (category))
7701 if ((meth = (lookup_method_in_protocol_list
7702 (CLASS_PROTOCOL_LIST (category), ident, is_class))))
7707 /* If not found in categories, check in protocols of the main class. */
7708 if (CLASS_PROTOCOL_LIST (inter))
7710 if ((meth = (lookup_method_in_protocol_list
7711 (CLASS_PROTOCOL_LIST (inter), ident, is_class))))
7715 /* If we were instructed not to look in superclasses, don't. */
7716 if (no_superclasses)
7719 /* Failing that, climb up the inheritance hierarchy. */
7721 inter = lookup_interface (CLASS_SUPER_NAME (inter));
7725 /* If no class (factory) method was found, check if an _instance_
7726 method of the same name exists in the root class. This is what
7727 the Objective-C runtime will do. If an instance method was not
7729 return is_class ? lookup_method_static (root_inter, ident, 0): NULL_TREE;
7732 /* Add the method to the hash list if it doesn't contain an identical
7736 add_method_to_hash_list (hash *hash_list, tree method)
7740 if (!(hsh = hash_lookup (hash_list, METHOD_SEL_NAME (method))))
7742 /* Install on a global chain. */
7743 hash_enter (hash_list, method);
7747 /* Check types against those; if different, add to a list. */
7749 int already_there = comp_proto_with_proto (method, hsh->key, 1);
7750 for (loop = hsh->list; !already_there && loop; loop = loop->next)
7751 already_there |= comp_proto_with_proto (method, loop->value, 1);
7753 hash_add_attr (hsh, method);
7758 objc_add_method (tree klass, tree method, int is_class, bool is_optional)
7762 /* @optional methods are added to protocol's OPTIONAL list */
7765 gcc_assert (TREE_CODE (klass) == PROTOCOL_INTERFACE_TYPE);
7766 if (!(mth = lookup_method (is_class
7767 ? PROTOCOL_OPTIONAL_CLS_METHODS (klass)
7768 : PROTOCOL_OPTIONAL_NST_METHODS (klass),
7773 TREE_CHAIN (method) = PROTOCOL_OPTIONAL_CLS_METHODS (klass);
7774 PROTOCOL_OPTIONAL_CLS_METHODS (klass) = method;
7778 TREE_CHAIN (method) = PROTOCOL_OPTIONAL_NST_METHODS (klass);
7779 PROTOCOL_OPTIONAL_NST_METHODS (klass) = method;
7783 else if (!(mth = lookup_method (is_class
7784 ? CLASS_CLS_METHODS (klass)
7785 : CLASS_NST_METHODS (klass), method)))
7787 /* put method on list in reverse order */
7790 DECL_CHAIN (method) = CLASS_CLS_METHODS (klass);
7791 CLASS_CLS_METHODS (klass) = method;
7795 DECL_CHAIN (method) = CLASS_NST_METHODS (klass);
7796 CLASS_NST_METHODS (klass) = method;
7801 /* When processing an @interface for a class or category, give hard
7802 errors on methods with identical selectors but differing argument
7803 and/or return types. We do not do this for @implementations, because
7804 C/C++ will do it for us (i.e., there will be duplicate function
7805 definition errors). */
7806 if ((TREE_CODE (klass) == CLASS_INTERFACE_TYPE
7807 || TREE_CODE (klass) == CATEGORY_INTERFACE_TYPE)
7808 && !comp_proto_with_proto (method, mth, 1))
7809 error ("duplicate declaration of method %<%c%E%>",
7810 is_class ? '+' : '-',
7811 METHOD_SEL_NAME (mth));
7815 add_method_to_hash_list (cls_method_hash_list, method);
7818 add_method_to_hash_list (nst_method_hash_list, method);
7820 /* Instance methods in root classes (and categories thereof)
7821 may act as class methods as a last resort. We also add
7822 instance methods listed in @protocol declarations to
7823 the class hash table, on the assumption that @protocols
7824 may be adopted by root classes or categories. */
7825 if (TREE_CODE (klass) == CATEGORY_INTERFACE_TYPE
7826 || TREE_CODE (klass) == CATEGORY_IMPLEMENTATION_TYPE)
7827 klass = lookup_interface (CLASS_NAME (klass));
7829 if (TREE_CODE (klass) == PROTOCOL_INTERFACE_TYPE
7830 || !CLASS_SUPER_NAME (klass))
7831 add_method_to_hash_list (cls_method_hash_list, method);
7838 add_class (tree class_name, tree name)
7840 struct interface_tuple **slot;
7842 /* Put interfaces on list in reverse order. */
7843 TREE_CHAIN (class_name) = interface_chain;
7844 interface_chain = class_name;
7846 if (interface_htab == NULL)
7847 interface_htab = htab_create_ggc (31, hash_interface, eq_interface, NULL);
7848 slot = (struct interface_tuple **)
7849 htab_find_slot_with_hash (interface_htab, name,
7850 IDENTIFIER_HASH_VALUE (name),
7854 *slot = ggc_alloc_cleared_interface_tuple ();
7857 (*slot)->class_name = class_name;
7859 return interface_chain;
7863 add_category (tree klass, tree category)
7865 /* Put categories on list in reverse order. */
7866 tree cat = lookup_category (klass, CLASS_SUPER_NAME (category));
7870 warning (0, "duplicate interface declaration for category %<%E(%E)%>",
7872 CLASS_SUPER_NAME (category));
7876 CLASS_CATEGORY_LIST (category) = CLASS_CATEGORY_LIST (klass);
7877 CLASS_CATEGORY_LIST (klass) = category;
7881 /* Called after parsing each instance variable declaration. Necessary to
7882 preserve typedefs and implement public/private...
7884 VISIBILITY is 1 for public, 0 for protected, and 2 for private. */
7887 add_instance_variable (tree klass, objc_ivar_visibility_kind visibility,
7890 tree field_type = TREE_TYPE (field_decl);
7891 const char *ivar_name = DECL_NAME (field_decl)
7892 ? identifier_to_locale (IDENTIFIER_POINTER (DECL_NAME (field_decl)))
7896 if (TREE_CODE (field_type) == REFERENCE_TYPE)
7898 error ("illegal reference type specified for instance variable %qs",
7900 /* Return class as is without adding this ivar. */
7905 if (field_type == error_mark_node || !TYPE_SIZE (field_type)
7906 || TYPE_SIZE (field_type) == error_mark_node)
7907 /* 'type[0]' is allowed, but 'type[]' is not! */
7909 error ("instance variable %qs has unknown size", ivar_name);
7910 /* Return class as is without adding this ivar. */
7915 /* Check if the ivar being added has a non-POD C++ type. If so, we will
7916 need to either (1) warn the user about it or (2) generate suitable
7917 constructor/destructor call from '- .cxx_construct' or '- .cxx_destruct'
7918 methods (if '-fobjc-call-cxx-cdtors' was specified). */
7919 if (MAYBE_CLASS_TYPE_P (field_type)
7920 && (TYPE_NEEDS_CONSTRUCTING (field_type)
7921 || TYPE_HAS_NONTRIVIAL_DESTRUCTOR (field_type)
7922 || TYPE_POLYMORPHIC_P (field_type)))
7924 tree type_name = OBJC_TYPE_NAME (field_type);
7926 if (flag_objc_call_cxx_cdtors)
7928 /* Since the ObjC runtime will be calling the constructors and
7929 destructors for us, the only thing we can't handle is the lack
7930 of a default constructor. */
7931 if (TYPE_NEEDS_CONSTRUCTING (field_type)
7932 && !TYPE_HAS_DEFAULT_CONSTRUCTOR (field_type))
7934 warning (0, "type %qE has no default constructor to call",
7937 /* If we cannot call a constructor, we should also avoid
7938 calling the destructor, for symmetry. */
7939 if (TYPE_HAS_NONTRIVIAL_DESTRUCTOR (field_type))
7940 warning (0, "destructor for %qE shall not be run either",
7946 static bool warn_cxx_ivars = false;
7948 if (TYPE_POLYMORPHIC_P (field_type))
7950 /* Vtable pointers are Real Bad(tm), since Obj-C cannot
7952 error ("type %qE has virtual member functions", type_name);
7953 error ("illegal aggregate type %qE specified "
7954 "for instance variable %qs",
7955 type_name, ivar_name);
7956 /* Return class as is without adding this ivar. */
7960 /* User-defined constructors and destructors are not known to Obj-C
7961 and hence will not be called. This may or may not be a problem. */
7962 if (TYPE_NEEDS_CONSTRUCTING (field_type))
7963 warning (0, "type %qE has a user-defined constructor", type_name);
7964 if (TYPE_HAS_NONTRIVIAL_DESTRUCTOR (field_type))
7965 warning (0, "type %qE has a user-defined destructor", type_name);
7967 if (!warn_cxx_ivars)
7969 warning (0, "C++ constructors and destructors will not "
7970 "be invoked for Objective-C fields");
7971 warn_cxx_ivars = true;
7977 /* Overload the public attribute, it is not used for FIELD_DECLs. */
7980 case OBJC_IVAR_VIS_PROTECTED:
7981 TREE_PUBLIC (field_decl) = 0;
7982 TREE_PRIVATE (field_decl) = 0;
7983 TREE_PROTECTED (field_decl) = 1;
7986 case OBJC_IVAR_VIS_PACKAGE:
7987 /* TODO: Implement the package variant. */
7988 case OBJC_IVAR_VIS_PUBLIC:
7989 TREE_PUBLIC (field_decl) = 1;
7990 TREE_PRIVATE (field_decl) = 0;
7991 TREE_PROTECTED (field_decl) = 0;
7994 case OBJC_IVAR_VIS_PRIVATE:
7995 TREE_PUBLIC (field_decl) = 0;
7996 TREE_PRIVATE (field_decl) = 1;
7997 TREE_PROTECTED (field_decl) = 0;
8002 CLASS_RAW_IVARS (klass) = chainon (CLASS_RAW_IVARS (klass), field_decl);
8008 is_ivar (tree decl_chain, tree ident)
8010 for ( ; decl_chain; decl_chain = DECL_CHAIN (decl_chain))
8011 if (DECL_NAME (decl_chain) == ident)
8016 /* True if the ivar is private and we are not in its implementation. */
8019 is_private (tree decl)
8021 return (TREE_PRIVATE (decl)
8022 && ! is_ivar (CLASS_IVARS (implementation_template),
8026 /* We have an instance variable reference;, check to see if it is public. */
8029 objc_is_public (tree expr, tree identifier)
8031 tree basetype, decl;
8034 if (processing_template_decl)
8038 if (TREE_TYPE (expr) == error_mark_node)
8041 basetype = TYPE_MAIN_VARIANT (TREE_TYPE (expr));
8043 if (basetype && TREE_CODE (basetype) == RECORD_TYPE)
8045 if (TYPE_HAS_OBJC_INFO (basetype) && TYPE_OBJC_INTERFACE (basetype))
8047 tree klass = lookup_interface (OBJC_TYPE_NAME (basetype));
8051 error ("cannot find interface declaration for %qE",
8052 OBJC_TYPE_NAME (basetype));
8056 if ((decl = is_ivar (get_class_ivars (klass, true), identifier)))
8058 if (TREE_PUBLIC (decl))
8061 /* Important difference between the Stepstone translator:
8062 all instance variables should be public within the context
8063 of the implementation. */
8064 if (objc_implementation_context
8065 && ((TREE_CODE (objc_implementation_context)
8066 == CLASS_IMPLEMENTATION_TYPE)
8067 || (TREE_CODE (objc_implementation_context)
8068 == CATEGORY_IMPLEMENTATION_TYPE)))
8070 tree curtype = TYPE_MAIN_VARIANT
8071 (CLASS_STATIC_TEMPLATE
8072 (implementation_template));
8074 if (basetype == curtype
8075 || DERIVED_FROM_P (basetype, curtype))
8077 int priv = is_private (decl);
8080 error ("instance variable %qE is declared private",
8087 /* The 2.95.2 compiler sometimes allowed C functions to access
8088 non-@public ivars. We will let this slide for now... */
8089 if (!objc_method_context)
8091 warning (0, "instance variable %qE is %s; "
8092 "this will be a hard error in the future",
8094 TREE_PRIVATE (decl) ? "@private" : "@protected");
8098 error ("instance variable %qE is declared %s",
8100 TREE_PRIVATE (decl) ? "private" : "protected");
8109 /* Make sure all entries in CHAIN are also in LIST. */
8112 check_methods (tree chain, tree list, int mtype)
8118 if (!lookup_method (list, chain))
8122 switch (TREE_CODE (objc_implementation_context))
8124 case CLASS_IMPLEMENTATION_TYPE:
8125 warning (0, "incomplete implementation of class %qE",
8126 CLASS_NAME (objc_implementation_context));
8128 case CATEGORY_IMPLEMENTATION_TYPE:
8129 warning (0, "incomplete implementation of category %qE",
8130 CLASS_SUPER_NAME (objc_implementation_context));
8138 warning (0, "method definition for %<%c%E%> not found",
8139 mtype, METHOD_SEL_NAME (chain));
8142 chain = DECL_CHAIN (chain);
8148 /* Check if KLASS, or its superclasses, explicitly conforms to PROTOCOL. */
8151 conforms_to_protocol (tree klass, tree protocol)
8153 if (TREE_CODE (protocol) == PROTOCOL_INTERFACE_TYPE)
8155 tree p = CLASS_PROTOCOL_LIST (klass);
8156 while (p && TREE_VALUE (p) != protocol)
8161 tree super = (CLASS_SUPER_NAME (klass)
8162 ? lookup_interface (CLASS_SUPER_NAME (klass))
8164 int tmp = super ? conforms_to_protocol (super, protocol) : 0;
8173 /* Make sure all methods in CHAIN are accessible as MTYPE methods in
8174 CONTEXT. This is one of two mechanisms to check protocol integrity. */
8177 check_methods_accessible (tree chain, tree context, int mtype)
8181 tree base_context = context;
8185 context = base_context;
8189 list = CLASS_CLS_METHODS (context);
8191 list = CLASS_NST_METHODS (context);
8193 if (lookup_method (list, chain))
8196 switch (TREE_CODE (context))
8198 case CLASS_IMPLEMENTATION_TYPE:
8199 case CLASS_INTERFACE_TYPE:
8200 context = (CLASS_SUPER_NAME (context)
8201 ? lookup_interface (CLASS_SUPER_NAME (context))
8204 case CATEGORY_IMPLEMENTATION_TYPE:
8205 case CATEGORY_INTERFACE_TYPE:
8206 context = (CLASS_NAME (context)
8207 ? lookup_interface (CLASS_NAME (context))
8215 if (context == NULL_TREE)
8219 switch (TREE_CODE (objc_implementation_context))
8221 case CLASS_IMPLEMENTATION_TYPE:
8222 warning (0, "incomplete implementation of class %qE",
8223 CLASS_NAME (objc_implementation_context));
8225 case CATEGORY_IMPLEMENTATION_TYPE:
8226 warning (0, "incomplete implementation of category %qE",
8227 CLASS_SUPER_NAME (objc_implementation_context));
8234 warning (0, "method definition for %<%c%E%> not found",
8235 mtype, METHOD_SEL_NAME (chain));
8238 chain = TREE_CHAIN (chain); /* next method... */
8243 /* Check whether the current interface (accessible via
8244 'objc_implementation_context') actually implements protocol P, along
8245 with any protocols that P inherits. */
8248 check_protocol (tree p, const char *type, tree name)
8250 if (TREE_CODE (p) == PROTOCOL_INTERFACE_TYPE)
8254 /* Ensure that all protocols have bodies! */
8257 f1 = check_methods (PROTOCOL_CLS_METHODS (p),
8258 CLASS_CLS_METHODS (objc_implementation_context),
8260 f2 = check_methods (PROTOCOL_NST_METHODS (p),
8261 CLASS_NST_METHODS (objc_implementation_context),
8266 f1 = check_methods_accessible (PROTOCOL_CLS_METHODS (p),
8267 objc_implementation_context,
8269 f2 = check_methods_accessible (PROTOCOL_NST_METHODS (p),
8270 objc_implementation_context,
8275 warning (0, "%s %qE does not fully implement the %qE protocol",
8276 type, name, PROTOCOL_NAME (p));
8279 /* Check protocols recursively. */
8280 if (PROTOCOL_LIST (p))
8282 tree subs = PROTOCOL_LIST (p);
8284 lookup_interface (CLASS_SUPER_NAME (implementation_template));
8288 tree sub = TREE_VALUE (subs);
8290 /* If the superclass does not conform to the protocols
8291 inherited by P, then we must! */
8292 if (!super_class || !conforms_to_protocol (super_class, sub))
8293 check_protocol (sub, type, name);
8294 subs = TREE_CHAIN (subs);
8299 /* Check whether the current interface (accessible via
8300 'objc_implementation_context') actually implements the protocols listed
8304 check_protocols (tree proto_list, const char *type, tree name)
8306 for ( ; proto_list; proto_list = TREE_CHAIN (proto_list))
8308 tree p = TREE_VALUE (proto_list);
8310 check_protocol (p, type, name);
8314 /* Make sure that the class CLASS_NAME is defined
8315 CODE says which kind of thing CLASS_NAME ought to be.
8316 It can be CLASS_INTERFACE_TYPE, CLASS_IMPLEMENTATION_TYPE,
8317 CATEGORY_INTERFACE_TYPE, or CATEGORY_IMPLEMENTATION_TYPE. */
8320 start_class (enum tree_code code, tree class_name, tree super_name,
8326 if (current_namespace != global_namespace) {
8327 error ("Objective-C declarations may only appear in global scope");
8329 #endif /* OBJCPLUS */
8331 if (objc_implementation_context)
8333 warning (0, "%<@end%> missing in implementation context");
8334 finish_class (objc_implementation_context);
8335 objc_ivar_chain = NULL_TREE;
8336 objc_implementation_context = NULL_TREE;
8339 klass = make_node (code);
8340 TYPE_LANG_SLOT_1 (klass) = make_tree_vec (CLASS_LANG_SLOT_ELTS);
8342 /* Check for existence of the super class, if one was specified. Note
8343 that we must have seen an @interface, not just a @class. If we
8344 are looking at a @compatibility_alias, traverse it first. */
8345 if ((code == CLASS_INTERFACE_TYPE || code == CLASS_IMPLEMENTATION_TYPE)
8348 tree super = objc_is_class_name (super_name);
8350 if (!super || !lookup_interface (super))
8352 error ("cannot find interface declaration for %qE, superclass of %qE",
8353 super ? super : super_name,
8355 super_name = NULL_TREE;
8361 CLASS_NAME (klass) = class_name;
8362 CLASS_SUPER_NAME (klass) = super_name;
8363 CLASS_CLS_METHODS (klass) = NULL_TREE;
8365 if (! objc_is_class_name (class_name)
8366 && (decl = lookup_name (class_name)))
8368 error ("%qE redeclared as different kind of symbol",
8370 error ("previous declaration of %q+D",
8376 case CLASS_IMPLEMENTATION_TYPE:
8380 for (chain = implemented_classes; chain; chain = TREE_CHAIN (chain))
8381 if (TREE_VALUE (chain) == class_name)
8383 error ("reimplementation of class %qE",
8385 return error_mark_node;
8387 implemented_classes = tree_cons (NULL_TREE, class_name,
8388 implemented_classes);
8391 /* Reset for multiple classes per file. */
8394 objc_implementation_context = klass;
8396 /* Lookup the interface for this implementation. */
8398 if (!(implementation_template = lookup_interface (class_name)))
8400 warning (0, "cannot find interface declaration for %qE",
8402 add_class (implementation_template = objc_implementation_context,
8406 /* If a super class has been specified in the implementation,
8407 insure it conforms to the one specified in the interface. */
8410 && (super_name != CLASS_SUPER_NAME (implementation_template)))
8412 tree previous_name = CLASS_SUPER_NAME (implementation_template);
8413 error ("conflicting super class name %qE",
8416 error ("previous declaration of %qE", previous_name);
8418 error ("previous declaration");
8421 else if (! super_name)
8423 CLASS_SUPER_NAME (objc_implementation_context)
8424 = CLASS_SUPER_NAME (implementation_template);
8428 case CLASS_INTERFACE_TYPE:
8429 if (lookup_interface (class_name))
8431 error ("duplicate interface declaration for class %qE", class_name);
8433 warning (0, "duplicate interface declaration for class %qE", class_name);
8436 add_class (klass, class_name);
8439 CLASS_PROTOCOL_LIST (klass)
8440 = lookup_and_install_protocols (protocol_list);
8443 case CATEGORY_INTERFACE_TYPE:
8445 tree class_category_is_assoc_with;
8447 /* For a category, class_name is really the name of the class that
8448 the following set of methods will be associated with. We must
8449 find the interface so that can derive the objects template. */
8450 if (!(class_category_is_assoc_with = lookup_interface (class_name)))
8452 error ("cannot find interface declaration for %qE",
8454 exit (FATAL_EXIT_CODE);
8457 add_category (class_category_is_assoc_with, klass);
8460 CLASS_PROTOCOL_LIST (klass)
8461 = lookup_and_install_protocols (protocol_list);
8465 case CATEGORY_IMPLEMENTATION_TYPE:
8466 /* Reset for multiple classes per file. */
8469 objc_implementation_context = klass;
8471 /* For a category, class_name is really the name of the class that
8472 the following set of methods will be associated with. We must
8473 find the interface so that can derive the objects template. */
8475 if (!(implementation_template = lookup_interface (class_name)))
8477 error ("cannot find interface declaration for %qE",
8479 exit (FATAL_EXIT_CODE);
8489 continue_class (tree klass)
8491 switch (TREE_CODE (klass))
8493 case CLASS_IMPLEMENTATION_TYPE:
8494 case CATEGORY_IMPLEMENTATION_TYPE:
8496 struct imp_entry *imp_entry;
8498 /* Check consistency of the instance variables. */
8500 if (CLASS_RAW_IVARS (klass))
8501 check_ivars (implementation_template, klass);
8503 /* code generation */
8505 push_lang_context (lang_name_c);
8507 build_private_template (implementation_template);
8508 uprivate_record = CLASS_STATIC_TEMPLATE (implementation_template);
8509 objc_instance_type = build_pointer_type (uprivate_record);
8511 imp_entry = ggc_alloc_imp_entry ();
8513 imp_entry->next = imp_list;
8514 imp_entry->imp_context = klass;
8515 imp_entry->imp_template = implementation_template;
8517 synth_forward_declarations ();
8518 imp_entry->class_decl = UOBJC_CLASS_decl;
8519 imp_entry->meta_decl = UOBJC_METACLASS_decl;
8520 imp_entry->has_cxx_cdtors = 0;
8522 /* Append to front and increment count. */
8523 imp_list = imp_entry;
8524 if (TREE_CODE (klass) == CLASS_IMPLEMENTATION_TYPE)
8529 pop_lang_context ();
8530 #endif /* OBJCPLUS */
8532 return get_class_ivars (implementation_template, true);
8535 case CLASS_INTERFACE_TYPE:
8538 push_lang_context (lang_name_c);
8539 #endif /* OBJCPLUS */
8540 objc_collecting_ivars = 1;
8541 build_private_template (klass);
8542 objc_collecting_ivars = 0;
8544 pop_lang_context ();
8545 #endif /* OBJCPLUS */
8550 return error_mark_node;
8554 /* This routine builds a property ivar name. */
8557 objc_build_property_ivar_name (tree property_decl)
8559 static char string[BUFSIZE];
8560 sprintf (string, "_%s", IDENTIFIER_POINTER (PROPERTY_NAME (property_decl)));
8564 /* This routine builds name of the setter synthesized function. */
8567 objc_build_property_setter_name (tree ident, bool delimit_colon)
8569 static char string[BUFSIZE];
8571 sprintf (string, "set%s:", IDENTIFIER_POINTER (ident));
8573 sprintf (string, "set%s", IDENTIFIER_POINTER (ident));
8574 string[3] = TOUPPER (string[3]);
8578 /* This routine does all the work for generating data and code per each
8579 property declared in current implementation. */
8582 objc_gen_one_property_datum (tree klass, tree property, tree class_methods, bool *ivar_added)
8586 /* If getter, check that it is already declared in user code. */
8587 if (PROPERTY_GETTER_NAME (property))
8589 mth = lookup_method (CLASS_NST_METHODS (class_methods),
8590 PROPERTY_GETTER_NAME (property));
8592 error ("property getter %qs not declared in class %qs",
8593 IDENTIFIER_POINTER (PROPERTY_GETTER_NAME (property)),
8594 IDENTIFIER_POINTER (CLASS_NAME (class_methods)));
8596 /* If setter, check that it is already declared in user code. */
8597 if (PROPERTY_SETTER_NAME (property))
8599 mth = lookup_method (CLASS_NST_METHODS (class_methods),
8600 PROPERTY_SETTER_NAME (property));
8602 error ("property setter %qs not declared in class %qs",
8603 IDENTIFIER_POINTER (PROPERTY_SETTER_NAME (property)),
8604 IDENTIFIER_POINTER (CLASS_NAME (class_methods)));
8606 /* If ivar attribute specified, check that it is already declared. */
8607 if (PROPERTY_IVAR_NAME (property))
8609 if (!is_ivar (CLASS_IVARS (klass),
8610 PROPERTY_IVAR_NAME (property)))
8611 error ("ivar %qs in property declaration must be an existing ivar",
8612 IDENTIFIER_POINTER (PROPERTY_IVAR_NAME (property)));
8614 else if (!PROPERTY_GETTER_NAME (property)
8615 || (PROPERTY_READONLY (property) == boolean_false_node
8616 && !PROPERTY_SETTER_NAME (property)))
8618 /* Setter and/or getter must be synthesize and there was no user-specified
8619 ivar. Must create an ivar and add to to current class's ivar list. */
8620 tree record = CLASS_STATIC_TEMPLATE (klass);
8621 tree type = TREE_TYPE (property);
8622 tree field_decl, field;
8623 field_decl = create_field_decl (type,
8624 objc_build_property_ivar_name (property));
8625 DECL_CONTEXT (field_decl) = record;
8626 (void) add_instance_variable (klass,
8627 OBJC_IVAR_VIS_PUBLIC, field_decl);
8628 /* Unfortunately, CLASS_IVARS is completed when interface is completed.
8629 Must add the new ivar by hand to its list here. */
8631 CLASS_IVARS (klass) =
8632 chainon (CLASS_IVARS (klass),
8633 copy_node (field_decl));
8634 gcc_assert (record);
8635 /* Must also add this ivar to the end of list of fields for this class. */
8636 field = TYPE_FIELDS (record);
8637 if (field && field != CLASS_IVARS (klass))
8638 /* class has a hidden field, attach ivar list after the hiddent field. */
8639 TREE_CHAIN (field) = CLASS_IVARS (klass);
8641 TYPE_FIELDS (record) = CLASS_IVARS (klass);
8646 /* This routine processes an existing getter or setter attribute.
8647 It aliases internal property getter or setter to the user implemented
8652 objc_process_getter_setter (tree klass, tree property, bool getter)
8655 tree prop_getter_mth_decl;
8659 /* getter name is same as property name. */
8660 name_ident = PROPERTY_NAME (property);
8662 /* Must synthesize setter name from property name. */
8663 name_ident = get_identifier (objc_build_property_setter_name (
8664 PROPERTY_NAME (property), true));
8666 /* Find declaration of instance method for the property in its class. */
8667 prop_mth_decl = lookup_method (CLASS_NST_METHODS (klass), name_ident);
8672 prop_getter_mth_decl = lookup_method (CLASS_NST_METHODS (objc_implementation_context),
8673 getter ? PROPERTY_GETTER_NAME (property)
8674 : PROPERTY_SETTER_NAME (property));
8676 if (!prop_getter_mth_decl)
8679 if (!match_proto_with_proto (prop_getter_mth_decl, prop_mth_decl, 1))
8681 error ("User %s %qs does not match property %qs type",
8682 getter ? "getter" : "setter",
8683 IDENTIFIER_POINTER (DECL_NAME (prop_getter_mth_decl)),
8684 IDENTIFIER_POINTER (PROPERTY_NAME (property)));
8687 /* We alias internal property getter to the user implemented getter by copying relevant
8688 entries from user's implementation to the internal one. */
8689 prop_mth_decl = copy_node (prop_mth_decl);
8690 METHOD_ENCODING (prop_mth_decl) = METHOD_ENCODING (prop_getter_mth_decl);
8691 METHOD_DEFINITION (prop_mth_decl) = METHOD_DEFINITION (prop_getter_mth_decl);
8692 objc_add_method (objc_implementation_context, prop_mth_decl, 0, 0);
8695 /* This routine synthesizes a 'getter' method. */
8698 objc_synthesize_getter (tree klass, tree class_method, tree property)
8705 /* If user has implemented a getter with same name then do nothing. */
8706 if (lookup_method (CLASS_NST_METHODS (objc_implementation_context),
8707 PROPERTY_NAME (property)))
8710 /* Find declaration of the property in the interface. There must be one. */
8711 decl = lookup_method (CLASS_NST_METHODS (class_method),
8712 PROPERTY_NAME (property));
8714 /* If one not declared in the interface, this condition has already been reported
8715 as user error (because property was not declared in the interface). */
8719 /* For now no attributes. */
8720 objc_start_method_definition (false /* is_class_method */, copy_node (decl), NULL_TREE);
8722 body = c_begin_compound_stmt (true);
8723 /* return self->_property_name; */
8724 /* If user specified an ivar, use it in generation of the getter. */
8725 ivar_ident = PROPERTY_IVAR_NAME (property)
8726 ? PROPERTY_IVAR_NAME (property)
8727 : get_identifier (objc_build_property_ivar_name (property));
8729 /* objc_ivar_chain might not be up to date in the case that property 'ivar'
8730 is added *after* user ivar is parsed and objc_continue_implementation
8731 has already been called. */
8732 objc_ivar_chain = CLASS_IVARS (klass);
8733 ret_val = objc_lookup_ivar (NULL_TREE, ivar_ident);
8734 /* If ivar attribute is not a user declared attribute, this condition has
8735 already been repored as error. */
8736 gcc_assert (ret_val || PROPERTY_IVAR_NAME (property));
8741 finish_return_stmt (ret_val);
8743 (void)c_finish_return (input_location, ret_val, NULL);
8746 add_stmt (c_end_compound_stmt (input_location, body, true));
8747 fn = current_function_decl;
8751 objc_finish_method_definition (fn);
8754 /* This routine synthesizes a 'setter' method. */
8757 objc_synthesize_setter (tree klass, tree class_method, tree property)
8759 tree fn, decl, ivar_ident, lhs, rhs;
8761 char *setter_name = objc_build_property_setter_name (
8762 PROPERTY_NAME (property), true);
8763 tree setter_ident = get_identifier (setter_name);
8765 /* If user has implemented a setter with same name then do nothing. */
8766 if (lookup_method (CLASS_NST_METHODS (objc_implementation_context),
8770 /* Find declaration of the property in the interface. There must be one. */
8771 decl = lookup_method (CLASS_NST_METHODS (class_method), setter_ident);
8773 /* If one not declared in the inerface, this condition has already been reported
8774 as user error (because property was not declared in the interface. */
8778 /* For now, no attributes. */
8779 objc_start_method_definition (false /* is_class_method */, copy_node (decl), NULL_TREE);
8781 body = c_begin_compound_stmt (true);
8782 /* _property_name = _value; */
8783 /* If user specified an ivar, use it in generation of the setter. */
8784 ivar_ident = PROPERTY_IVAR_NAME (property)
8785 ? PROPERTY_IVAR_NAME (property)
8786 : get_identifier (objc_build_property_ivar_name (property));
8788 /* objc_ivar_chain might not be up to date in the case that property 'ivar'
8789 is added *after* user ivar is parsed and objc_continue_implementation
8790 has already been called. */
8791 objc_ivar_chain = CLASS_IVARS (klass);
8792 lhs = objc_lookup_ivar (NULL_TREE, ivar_ident);
8793 /* If ivar attribute is not a user declared attribute, this condition has
8794 already been repored as error. */
8795 gcc_assert (lhs || PROPERTY_IVAR_NAME (property));
8798 rhs = lookup_name (get_identifier ("_value"));
8800 /* FIXME: NULL types to get compile. */
8801 add_stmt (build_modify_expr (input_location,
8802 lhs, NULL_TREE, NOP_EXPR,
8803 input_location, rhs, NULL_TREE));
8805 add_stmt (c_end_compound_stmt (input_location, body, true));
8806 fn = current_function_decl;
8810 objc_finish_method_definition (fn);
8813 /* This function is called by the parser after a @synthesize
8814 expression is parsed. 'start_locus' is the location of the
8815 @synthesize expression, and 'property_and_ivar_list' is a chained
8816 list of the property and ivar names.
8819 objc_add_synthesize_declaration (location_t start_locus ATTRIBUTE_UNUSED, tree property_and_ivar_list ATTRIBUTE_UNUSED)
8821 if (property_and_ivar_list == error_mark_node)
8824 if (!objc_implementation_context)
8826 /* We can get here only in Objective-C; the Objective-C++ parser
8827 detects the problem while parsing, outputs the error
8828 "misplaced '@synthesize' Objective-C++ construct" and skips
8830 error ("%<@synthesize%> not in @implementation context");
8835 error ("%<@synthesize%> is not supported in this version of the compiler");
8838 /* This function is called by the parser after a @dynamic expression
8839 is parsed. 'start_locus' is the location of the @dynamic
8840 expression, and 'property_list' is a chained list of all the
8843 objc_add_dynamic_declaration (location_t start_locus ATTRIBUTE_UNUSED, tree property_list ATTRIBUTE_UNUSED)
8845 if (property_list == error_mark_node)
8848 if (!objc_implementation_context)
8850 /* We can get here only in Objective-C; the Objective-C++ parser
8851 detects the problem while parsing, outputs the error
8852 "misplaced '@dynamic' Objective-C++ construct" and skips the
8854 error ("%<@dynamic%> not in @implementation context");
8859 error ("%<@dynamic%> is not supported in this version of the compiler");
8862 /* Main routine to generate code/data for all the property information for
8863 current implementation (class or category). CLASS is the interface where
8864 ivars are declared. CLASS_METHODS is where methods are found which
8865 could be a class or a category depending on whether we are implementing
8866 property of a class or a category. */
8869 objc_gen_property_data (tree klass, tree class_methods)
8872 bool ivar_added = false;
8873 for (x = IMPL_PROPERTY_DECL (objc_implementation_context); x; x = TREE_CHAIN (x))
8874 objc_gen_one_property_datum (klass, x, class_methods, &ivar_added);
8878 tree record = CLASS_STATIC_TEMPLATE (klass);
8879 /* Ugh, must recalculate struct layout since at least one ivar was added. */
8880 TYPE_SIZE (record) = 0;
8881 layout_type (record);
8884 /* Synthesize all getters for properties. */
8885 for (x = IMPL_PROPERTY_DECL (objc_implementation_context); x; x = TREE_CHAIN (x))
8887 /* Property has a getter attribute, no need to synthesize one. */
8888 if (PROPERTY_GETTER_NAME (x) == NULL_TREE)
8889 objc_synthesize_getter (klass, class_methods, x);
8891 objc_process_getter_setter (class_methods, x, true);
8893 if (PROPERTY_READONLY (x) == boolean_false_node)
8895 /* not a readonly property. */
8896 if (PROPERTY_SETTER_NAME (x) == NULL_TREE)
8897 objc_synthesize_setter (klass, class_methods, x);
8899 objc_process_getter_setter (class_methods, x, false);
8904 /* This is called once we see the "@end" in an interface/implementation. */
8907 finish_class (tree klass)
8909 switch (TREE_CODE (klass))
8911 case CLASS_IMPLEMENTATION_TYPE:
8913 /* All code generation is done in finish_objc. */
8915 /* Generate what needed for property; setters, getters, etc. */
8916 objc_gen_property_data (implementation_template, implementation_template);
8918 if (implementation_template != objc_implementation_context)
8920 /* Ensure that all method listed in the interface contain bodies. */
8921 check_methods (CLASS_CLS_METHODS (implementation_template),
8922 CLASS_CLS_METHODS (objc_implementation_context), '+');
8923 check_methods (CLASS_NST_METHODS (implementation_template),
8924 CLASS_NST_METHODS (objc_implementation_context), '-');
8926 if (CLASS_PROTOCOL_LIST (implementation_template))
8927 check_protocols (CLASS_PROTOCOL_LIST (implementation_template),
8929 CLASS_NAME (objc_implementation_context));
8933 case CATEGORY_IMPLEMENTATION_TYPE:
8935 tree category = lookup_category (implementation_template, CLASS_SUPER_NAME (klass));
8939 /* Generate what needed for property; setters, getters, etc. */
8940 objc_gen_property_data (implementation_template, category);
8942 /* Ensure all method listed in the interface contain bodies. */
8943 check_methods (CLASS_CLS_METHODS (category),
8944 CLASS_CLS_METHODS (objc_implementation_context), '+');
8945 check_methods (CLASS_NST_METHODS (category),
8946 CLASS_NST_METHODS (objc_implementation_context), '-');
8948 if (CLASS_PROTOCOL_LIST (category))
8949 check_protocols (CLASS_PROTOCOL_LIST (category),
8951 CLASS_SUPER_NAME (objc_implementation_context));
8957 /* Process properties of the class. */
8959 for (x = CLASS_PROPERTY_DECL (objc_interface_context); x; x = TREE_CHAIN (x))
8961 tree type = TREE_TYPE (x);
8962 tree prop_name = PROPERTY_NAME (x);
8963 /* Build an instance method declaration: - (type) prop_name; */
8964 if (PROPERTY_GETTER_NAME (x) == NULL_TREE)
8966 /* No getter attribute specified. Generate an instance method for the
8968 tree rettype = build_tree_list (NULL_TREE, type);
8969 tree getter_decl = build_method_decl (INSTANCE_METHOD_DECL,
8972 objc_add_method (objc_interface_context, getter_decl, false, false);
8973 METHOD_PROPERTY_CONTEXT (getter_decl) = x;
8976 warning (0, "getter = %qs may not be specified in an interface",
8977 IDENTIFIER_POINTER (PROPERTY_GETTER_NAME (x)));
8979 /* Build an instance method declaration: - (void) setName: (type)value; */
8980 if (PROPERTY_SETTER_NAME (x) == NULL_TREE
8981 && PROPERTY_READONLY (x) == boolean_false_node)
8983 /* Declare a setter instance method in the interface. */
8984 tree key_name, arg_type, arg_name;
8985 tree setter_decl, selector;
8986 tree ret_type = build_tree_list (NULL_TREE, void_type_node);
8988 key_name = get_identifier (objc_build_property_setter_name
8989 (PROPERTY_NAME (x), false));
8990 arg_type = build_tree_list (NULL_TREE, type);
8991 arg_name = get_identifier ("_value");
8992 /* For now, no attributes. */
8993 selector = objc_build_keyword_decl (key_name, arg_type, arg_name, NULL);
8994 setter_decl = build_method_decl (INSTANCE_METHOD_DECL,
8996 build_tree_list (NULL_TREE, NULL_TREE),
8998 objc_add_method (objc_interface_context, setter_decl, false, false);
8999 METHOD_PROPERTY_CONTEXT (setter_decl) = x;
9001 else if (PROPERTY_SETTER_NAME (x))
9002 warning (0, "setter = %qs may not be specified in an interface",
9003 IDENTIFIER_POINTER (PROPERTY_SETTER_NAME (x)));
9004 if (PROPERTY_IVAR_NAME (x))
9005 warning (0, "ivar = %qs attribute may not be specified in an interface",
9006 IDENTIFIER_POINTER (PROPERTY_IVAR_NAME (x)));
9013 add_protocol (tree protocol)
9015 /* Put protocol on list in reverse order. */
9016 TREE_CHAIN (protocol) = protocol_chain;
9017 protocol_chain = protocol;
9018 return protocol_chain;
9022 lookup_protocol (tree ident)
9026 for (chain = protocol_chain; chain; chain = TREE_CHAIN (chain))
9027 if (ident == PROTOCOL_NAME (chain))
9033 /* This function forward declares the protocols named by NAMES. If
9034 they are already declared or defined, the function has no effect. */
9037 objc_declare_protocols (tree names)
9042 if (current_namespace != global_namespace) {
9043 error ("Objective-C declarations may only appear in global scope");
9045 #endif /* OBJCPLUS */
9047 for (list = names; list; list = TREE_CHAIN (list))
9049 tree name = TREE_VALUE (list);
9051 if (lookup_protocol (name) == NULL_TREE)
9053 tree protocol = make_node (PROTOCOL_INTERFACE_TYPE);
9055 TYPE_LANG_SLOT_1 (protocol)
9056 = make_tree_vec (PROTOCOL_LANG_SLOT_ELTS);
9057 PROTOCOL_NAME (protocol) = name;
9058 PROTOCOL_LIST (protocol) = NULL_TREE;
9059 add_protocol (protocol);
9060 PROTOCOL_DEFINED (protocol) = 0;
9061 PROTOCOL_FORWARD_DECL (protocol) = NULL_TREE;
9067 start_protocol (enum tree_code code, tree name, tree list)
9072 if (current_namespace != global_namespace) {
9073 error ("Objective-C declarations may only appear in global scope");
9075 #endif /* OBJCPLUS */
9077 protocol = lookup_protocol (name);
9081 protocol = make_node (code);
9082 TYPE_LANG_SLOT_1 (protocol) = make_tree_vec (PROTOCOL_LANG_SLOT_ELTS);
9084 PROTOCOL_NAME (protocol) = name;
9085 PROTOCOL_LIST (protocol) = lookup_and_install_protocols (list);
9086 add_protocol (protocol);
9087 PROTOCOL_DEFINED (protocol) = 1;
9088 PROTOCOL_FORWARD_DECL (protocol) = NULL_TREE;
9090 check_protocol_recursively (protocol, list);
9092 else if (! PROTOCOL_DEFINED (protocol))
9094 PROTOCOL_DEFINED (protocol) = 1;
9095 PROTOCOL_LIST (protocol) = lookup_and_install_protocols (list);
9097 check_protocol_recursively (protocol, list);
9101 warning (0, "duplicate declaration for protocol %qE",
9108 /* "Encode" a data type into a string, which grows in util_obstack.
9110 The format is described in gcc/doc/objc.texi, section 'Type
9113 Most of the encode_xxx functions have a 'type' argument, which is
9114 the type to encode, and an integer 'curtype' argument, which is the
9115 index in the encoding string of the beginning of the encoding of
9116 the current type, and allows you to find what characters have
9117 already been written for the current type (they are the ones in the
9118 current encoding string starting from 'curtype').
9120 For example, if we are encoding a method which returns 'int' and
9121 takes a 'char **' argument, then when we get to the point of
9122 encoding the 'char **' argument, the encoded string already
9123 contains 'i12@0:4' (assuming a pointer size of 4 bytes). So,
9124 'curtype' will be set to 7 when starting to encode 'char **'.
9125 During the whole of the encoding of 'char **', 'curtype' will be
9126 fixed at 7, so the routine encoding the second pointer can find out
9127 that it's actually encoding a pointer to a pointer by looking
9128 backwards at what has already been encoded for the current type,
9129 and seeing there is a "^" (meaning a pointer) in there.
9133 /* Encode type qualifiers encodes one of the "PQ" Objective-C
9134 keywords, ie 'in', 'out', 'inout', 'bycopy', 'byref', 'oneway'.
9135 'const', instead, is encoded directly as part of the type.
9139 encode_type_qualifiers (tree declspecs)
9143 for (spec = declspecs; spec; spec = TREE_CHAIN (spec))
9145 /* FIXME: Shouldn't we use token->keyword here ? */
9146 if (ridpointers[(int) RID_IN] == TREE_VALUE (spec))
9147 obstack_1grow (&util_obstack, 'n');
9148 else if (ridpointers[(int) RID_INOUT] == TREE_VALUE (spec))
9149 obstack_1grow (&util_obstack, 'N');
9150 else if (ridpointers[(int) RID_OUT] == TREE_VALUE (spec))
9151 obstack_1grow (&util_obstack, 'o');
9152 else if (ridpointers[(int) RID_BYCOPY] == TREE_VALUE (spec))
9153 obstack_1grow (&util_obstack, 'O');
9154 else if (ridpointers[(int) RID_BYREF] == TREE_VALUE (spec))
9155 obstack_1grow (&util_obstack, 'R');
9156 else if (ridpointers[(int) RID_ONEWAY] == TREE_VALUE (spec))
9157 obstack_1grow (&util_obstack, 'V');
9163 /* Determine if a pointee is marked read-only. Only used by the NeXT
9164 runtime to be compatible with gcc-3.3. */
9167 pointee_is_readonly (tree pointee)
9169 while (POINTER_TYPE_P (pointee))
9170 pointee = TREE_TYPE (pointee);
9172 return TYPE_READONLY (pointee);
9175 /* Encode a pointer type. */
9178 encode_pointer (tree type, int curtype, int format)
9180 tree pointer_to = TREE_TYPE (type);
9182 if (flag_next_runtime)
9184 /* This code is used to be compatible with gcc-3.3. */
9185 /* For historical/compatibility reasons, the read-only qualifier
9186 of the pointee gets emitted _before_ the '^'. The read-only
9187 qualifier of the pointer itself gets ignored, _unless_ we are
9188 looking at a typedef! Also, do not emit the 'r' for anything
9189 but the outermost type! */
9190 if (!generating_instance_variables
9191 && (obstack_object_size (&util_obstack) - curtype <= 1)
9192 && (TYPE_NAME (type) && TREE_CODE (TYPE_NAME (type)) == TYPE_DECL
9193 ? TYPE_READONLY (type)
9194 : pointee_is_readonly (pointer_to)))
9195 obstack_1grow (&util_obstack, 'r');
9198 if (TREE_CODE (pointer_to) == RECORD_TYPE)
9200 if (OBJC_TYPE_NAME (pointer_to)
9201 && TREE_CODE (OBJC_TYPE_NAME (pointer_to)) == IDENTIFIER_NODE)
9203 const char *name = IDENTIFIER_POINTER (OBJC_TYPE_NAME (pointer_to));
9205 if (strcmp (name, TAG_OBJECT) == 0) /* '@' */
9207 obstack_1grow (&util_obstack, '@');
9210 else if (TYPE_HAS_OBJC_INFO (pointer_to)
9211 && TYPE_OBJC_INTERFACE (pointer_to))
9213 if (generating_instance_variables)
9215 obstack_1grow (&util_obstack, '@');
9216 obstack_1grow (&util_obstack, '"');
9217 obstack_grow (&util_obstack, name, strlen (name));
9218 obstack_1grow (&util_obstack, '"');
9223 obstack_1grow (&util_obstack, '@');
9227 else if (strcmp (name, TAG_CLASS) == 0) /* '#' */
9229 obstack_1grow (&util_obstack, '#');
9232 else if (strcmp (name, TAG_SELECTOR) == 0) /* ':' */
9234 obstack_1grow (&util_obstack, ':');
9239 else if (TREE_CODE (pointer_to) == INTEGER_TYPE
9240 && TYPE_MODE (pointer_to) == QImode)
9242 tree pname = TREE_CODE (OBJC_TYPE_NAME (pointer_to)) == IDENTIFIER_NODE
9243 ? OBJC_TYPE_NAME (pointer_to)
9244 : DECL_NAME (OBJC_TYPE_NAME (pointer_to));
9246 /* (BOOL *) are an exception and are encoded as ^c, while all
9247 other pointers to char are encoded as *. */
9248 if (strcmp (IDENTIFIER_POINTER (pname), "BOOL"))
9250 if (!flag_next_runtime)
9252 /* The NeXT runtime adds the 'r' before getting here. */
9254 /* It appears that "r*" means "const char *" rather than
9255 "char *const". "char *const" is encoded as "*",
9256 which is identical to "char *", so the "const" is
9257 unfortunately lost. */
9258 if (TYPE_READONLY (pointer_to))
9259 obstack_1grow (&util_obstack, 'r');
9262 obstack_1grow (&util_obstack, '*');
9267 /* We have a normal pointer type that does not get special treatment. */
9268 obstack_1grow (&util_obstack, '^');
9269 encode_type (pointer_to, curtype, format);
9273 encode_array (tree type, int curtype, int format)
9275 tree an_int_cst = TYPE_SIZE (type);
9276 tree array_of = TREE_TYPE (type);
9279 if (an_int_cst == NULL)
9281 /* We are trying to encode an incomplete array. An incomplete
9282 array is forbidden as part of an instance variable. */
9283 if (generating_instance_variables)
9285 /* TODO: Detect this error earlier. */
9286 error ("instance variable has unknown size");
9290 /* So the only case in which an incomplete array could occur is
9291 if we are encoding the arguments or return value of a method.
9292 In that case, an incomplete array argument or return value
9293 (eg, -(void)display: (char[])string) is treated like a
9294 pointer because that is how the compiler does the function
9295 call. A special, more complicated case, is when the
9296 incomplete array is the last member of a struct (eg, if we
9297 are encoding "struct { unsigned long int a;double b[];}"),
9298 which is again part of a method argument/return value. In
9299 that case, we really need to communicate to the runtime that
9300 there is an incomplete array (not a pointer!) there. So, we
9301 detect that special case and encode it as a zero-length
9304 Try to detect that we are part of a struct. We do this by
9305 searching for '=' in the type encoding for the current type.
9306 NB: This hack assumes that you can't use '=' as part of a C
9310 char *enc = obstack_base (&util_obstack) + curtype;
9311 if (memchr (enc, '=',
9312 obstack_object_size (&util_obstack) - curtype) == NULL)
9314 /* We are not inside a struct. Encode the array as a
9316 encode_pointer (type, curtype, format);
9321 /* Else, we are in a struct, and we encode it as a zero-length
9323 sprintf (buffer, "[" HOST_WIDE_INT_PRINT_DEC, (HOST_WIDE_INT)0);
9325 else if (TREE_INT_CST_LOW (TYPE_SIZE (array_of)) == 0)
9326 sprintf (buffer, "[" HOST_WIDE_INT_PRINT_DEC, (HOST_WIDE_INT)0);
9328 sprintf (buffer, "[" HOST_WIDE_INT_PRINT_DEC,
9329 TREE_INT_CST_LOW (an_int_cst)
9330 / TREE_INT_CST_LOW (TYPE_SIZE (array_of)));
9332 obstack_grow (&util_obstack, buffer, strlen (buffer));
9333 encode_type (array_of, curtype, format);
9334 obstack_1grow (&util_obstack, ']');
9338 /* Encode a vector. The vector type is a GCC extension to C. */
9340 encode_vector (tree type, int curtype, int format)
9342 tree vector_of = TREE_TYPE (type);
9345 /* Vectors are like simple fixed-size arrays. */
9347 /* Output ![xx,yy,<code>] where xx is the vector_size, yy is the
9348 alignment of the vector, and <code> is the base type. Eg, int
9349 __attribute__ ((vector_size (16))) gets encoded as ![16,32,i]
9350 assuming that the alignment is 32 bytes. We include size and
9351 alignment in bytes so that the runtime does not have to have any
9352 knowledge of the actual types.
9354 sprintf (buffer, "![" HOST_WIDE_INT_PRINT_DEC ",%d",
9355 /* We want to compute the equivalent of sizeof (<vector>).
9356 Code inspired by c_sizeof_or_alignof_type. */
9357 ((TREE_INT_CST_LOW (TYPE_SIZE_UNIT (type))
9358 / (TYPE_PRECISION (char_type_node) / BITS_PER_UNIT))),
9359 /* We want to compute the equivalent of __alignof__
9360 (<vector>). Code inspired by
9361 c_sizeof_or_alignof_type. */
9362 TYPE_ALIGN_UNIT (type));
9363 obstack_grow (&util_obstack, buffer, strlen (buffer));
9364 encode_type (vector_of, curtype, format);
9365 obstack_1grow (&util_obstack, ']');
9370 encode_aggregate_fields (tree type, bool pointed_to, int curtype, int format)
9372 tree field = TYPE_FIELDS (type);
9374 for (; field; field = DECL_CHAIN (field))
9377 /* C++ static members, and things that are not field at all,
9378 should not appear in the encoding. */
9379 if (TREE_CODE (field) != FIELD_DECL || TREE_STATIC (field))
9383 /* Recursively encode fields of embedded base classes. */
9384 if (DECL_ARTIFICIAL (field) && !DECL_NAME (field)
9385 && TREE_CODE (TREE_TYPE (field)) == RECORD_TYPE)
9387 encode_aggregate_fields (TREE_TYPE (field),
9388 pointed_to, curtype, format);
9392 if (generating_instance_variables && !pointed_to)
9394 tree fname = DECL_NAME (field);
9396 obstack_1grow (&util_obstack, '"');
9398 if (fname && TREE_CODE (fname) == IDENTIFIER_NODE)
9399 obstack_grow (&util_obstack,
9400 IDENTIFIER_POINTER (fname),
9401 strlen (IDENTIFIER_POINTER (fname)));
9403 obstack_1grow (&util_obstack, '"');
9406 encode_field_decl (field, curtype, format);
9411 encode_aggregate_within (tree type, int curtype, int format, int left,
9415 /* NB: aggregates that are pointed to have slightly different encoding
9416 rules in that you never encode the names of instance variables. */
9417 int ob_size = obstack_object_size (&util_obstack);
9418 bool inline_contents = false;
9419 bool pointed_to = false;
9421 if (flag_next_runtime)
9423 if (ob_size > 0 && *(obstack_next_free (&util_obstack) - 1) == '^')
9426 if ((format == OBJC_ENCODE_INLINE_DEFS || generating_instance_variables)
9427 && (!pointed_to || ob_size - curtype == 1
9428 || (ob_size - curtype == 2
9429 && *(obstack_next_free (&util_obstack) - 2) == 'r')))
9430 inline_contents = true;
9434 /* c0 and c1 are the last two characters in the encoding of the
9435 current type; if the last two characters were '^' or '^r',
9436 then we are encoding an aggregate that is "pointed to". The
9437 comment above applies: in that case we should avoid encoding
9438 the names of instance variables.
9440 char c1 = ob_size > 1 ? *(obstack_next_free (&util_obstack) - 2) : 0;
9441 char c0 = ob_size > 0 ? *(obstack_next_free (&util_obstack) - 1) : 0;
9443 if (c0 == '^' || (c1 == '^' && c0 == 'r'))
9446 if (format == OBJC_ENCODE_INLINE_DEFS || generating_instance_variables)
9449 inline_contents = true;
9452 /* Note that the check (ob_size - curtype < 2) prevents
9453 infinite recursion when encoding a structure which is
9454 a linked list (eg, struct node { struct node *next;
9455 }). Each time we follow a pointer, we add one
9456 character to ob_size, and curtype is fixed, so after
9457 at most two pointers we stop inlining contents and
9460 The other case where we don't inline is "^r", which
9461 is a pointer to a constant struct.
9463 if ((ob_size - curtype <= 2) && !(c0 == 'r'))
9464 inline_contents = true;
9469 /* Traverse struct aliases; it is important to get the
9470 original struct and its tag name (if any). */
9471 type = TYPE_MAIN_VARIANT (type);
9472 name = OBJC_TYPE_NAME (type);
9473 /* Open parenth/bracket. */
9474 obstack_1grow (&util_obstack, left);
9476 /* Encode the struct/union tag name, or '?' if a tag was
9477 not provided. Typedef aliases do not qualify. */
9479 /* For compatibility with the NeXT runtime, ObjC++ encodes template
9480 args as a composite struct tag name. */
9481 if (name && TREE_CODE (name) == IDENTIFIER_NODE
9482 /* Did this struct have a tag? */
9483 && !TYPE_WAS_ANONYMOUS (type))
9484 obstack_grow (&util_obstack,
9485 decl_as_string (type, TFF_DECL_SPECIFIERS | TFF_UNQUALIFIED_NAME),
9486 strlen (decl_as_string (type, TFF_DECL_SPECIFIERS | TFF_UNQUALIFIED_NAME)));
9488 if (name && TREE_CODE (name) == IDENTIFIER_NODE)
9489 obstack_grow (&util_obstack,
9490 IDENTIFIER_POINTER (name),
9491 strlen (IDENTIFIER_POINTER (name)));
9494 obstack_1grow (&util_obstack, '?');
9496 /* Encode the types (and possibly names) of the inner fields,
9498 if (inline_contents)
9500 obstack_1grow (&util_obstack, '=');
9501 encode_aggregate_fields (type, pointed_to, curtype, format);
9503 /* Close parenth/bracket. */
9504 obstack_1grow (&util_obstack, right);
9507 /* Encode a bitfield NeXT-style (i.e., without a bit offset or the underlying
9511 encode_next_bitfield (int width)
9514 sprintf (buffer, "b%d", width);
9515 obstack_grow (&util_obstack, buffer, strlen (buffer));
9519 /* Encodes 'type', ignoring type qualifiers (which you should encode
9520 beforehand if needed) with the exception of 'const', which is
9521 encoded by encode_type. See above for the explanation of
9522 'curtype'. 'format' can be OBJC_ENCODE_INLINE_DEFS or
9523 OBJC_ENCODE_DONT_INLINE_DEFS.
9526 encode_type (tree type, int curtype, int format)
9528 enum tree_code code = TREE_CODE (type);
9530 /* Ignore type qualifiers other than 'const' when encoding a
9533 if (type == error_mark_node)
9536 if (!flag_next_runtime)
9538 if (TYPE_READONLY (type))
9539 obstack_1grow (&util_obstack, 'r');
9545 if (flag_next_runtime)
9547 /* Kludge for backwards-compatibility with gcc-3.3: enums
9548 are always encoded as 'i' no matter what type they
9549 actually are (!). */
9550 obstack_1grow (&util_obstack, 'i');
9553 /* Else, they are encoded exactly like the integer type that is
9554 used by the compiler to store them. */
9558 switch (GET_MODE_BITSIZE (TYPE_MODE (type)))
9560 case 8: c = TYPE_UNSIGNED (type) ? 'C' : 'c'; break;
9561 case 16: c = TYPE_UNSIGNED (type) ? 'S' : 's'; break;
9564 tree int_type = type;
9565 if (flag_next_runtime)
9567 /* Another legacy kludge for compatiblity with
9568 gcc-3.3: 32-bit longs are encoded as 'l' or 'L',
9569 but not always. For typedefs, we need to use 'i'
9570 or 'I' instead if encoding a struct field, or a
9572 int_type = ((!generating_instance_variables
9573 && (obstack_object_size (&util_obstack)
9574 == (unsigned) curtype))
9575 ? TYPE_MAIN_VARIANT (type)
9578 if (int_type == long_unsigned_type_node
9579 || int_type == long_integer_type_node)
9580 c = TYPE_UNSIGNED (type) ? 'L' : 'l';
9582 c = TYPE_UNSIGNED (type) ? 'I' : 'i';
9585 case 64: c = TYPE_UNSIGNED (type) ? 'Q' : 'q'; break;
9586 case 128: c = TYPE_UNSIGNED (type) ? 'T' : 't'; break;
9587 default: gcc_unreachable ();
9589 obstack_1grow (&util_obstack, c);
9595 /* Floating point types. */
9596 switch (GET_MODE_BITSIZE (TYPE_MODE (type)))
9598 case 32: c = 'f'; break;
9599 case 64: c = 'd'; break;
9601 case 128: c = 'D'; break;
9602 default: gcc_unreachable ();
9604 obstack_1grow (&util_obstack, c);
9608 obstack_1grow (&util_obstack, 'v');
9612 obstack_1grow (&util_obstack, 'B');
9616 encode_array (type, curtype, format);
9621 case REFERENCE_TYPE:
9623 encode_pointer (type, curtype, format);
9627 encode_aggregate_within (type, curtype, format, '{', '}');
9631 encode_aggregate_within (type, curtype, format, '(', ')');
9634 case FUNCTION_TYPE: /* '?' means an unknown type. */
9635 obstack_1grow (&util_obstack, '?');
9639 /* A complex is encoded as 'j' followed by the inner type (eg,
9640 "_Complex int" is encoded as 'ji'). */
9641 obstack_1grow (&util_obstack, 'j');
9642 encode_type (TREE_TYPE (type), curtype, format);
9646 encode_vector (type, curtype, format);
9650 warning (0, "unknown type %s found during Objective-C encoding",
9651 gen_type_name (type));
9652 obstack_1grow (&util_obstack, '?');
9656 if (flag_next_runtime)
9658 /* Super-kludge. Some ObjC qualifier and type combinations need
9659 to be rearranged for compatibility with gcc-3.3. */
9660 if (code == POINTER_TYPE && obstack_object_size (&util_obstack) >= 3)
9662 char *enc = obstack_base (&util_obstack) + curtype;
9664 /* Rewrite "in const" from "nr" to "rn". */
9665 if (curtype >= 1 && !strncmp (enc - 1, "nr", 2))
9666 strncpy (enc - 1, "rn", 2);
9672 encode_gnu_bitfield (int position, tree type, int size)
9674 enum tree_code code = TREE_CODE (type);
9676 char charType = '?';
9678 /* This code is only executed for the GNU runtime, so we can ignore
9679 the NeXT runtime kludge of always encoding enums as 'i' no matter
9680 what integers they actually are. */
9681 if (code == INTEGER_TYPE || code == ENUMERAL_TYPE)
9683 if (integer_zerop (TYPE_MIN_VALUE (type)))
9684 /* Unsigned integer types. */
9686 switch (TYPE_MODE (type))
9689 charType = 'C'; break;
9691 charType = 'S'; break;
9694 if (type == long_unsigned_type_node)
9701 charType = 'Q'; break;
9707 /* Signed integer types. */
9709 switch (TYPE_MODE (type))
9712 charType = 'c'; break;
9714 charType = 's'; break;
9717 if (type == long_integer_type_node)
9724 charType = 'q'; break;
9732 /* Do not do any encoding, produce an error and keep going. */
9733 error ("trying to encode non-integer type as a bitfield");
9737 sprintf (buffer, "b%d%c%d", position, charType, size);
9738 obstack_grow (&util_obstack, buffer, strlen (buffer));
9742 encode_field_decl (tree field_decl, int curtype, int format)
9745 /* C++ static members, and things that are not fields at all,
9746 should not appear in the encoding. */
9747 if (TREE_CODE (field_decl) != FIELD_DECL || TREE_STATIC (field_decl))
9751 /* Generate the bitfield typing information, if needed. Note the difference
9752 between GNU and NeXT runtimes. */
9753 if (DECL_BIT_FIELD_TYPE (field_decl))
9755 int size = tree_low_cst (DECL_SIZE (field_decl), 1);
9757 if (flag_next_runtime)
9758 encode_next_bitfield (size);
9760 encode_gnu_bitfield (int_bit_position (field_decl),
9761 DECL_BIT_FIELD_TYPE (field_decl), size);
9764 encode_type (TREE_TYPE (field_decl), curtype, format);
9767 /* Decay array and function parameters into pointers. */
9770 objc_decay_parm_type (tree type)
9772 if (TREE_CODE (type) == ARRAY_TYPE || TREE_CODE (type) == FUNCTION_TYPE)
9773 type = build_pointer_type (TREE_CODE (type) == ARRAY_TYPE
9780 static GTY(()) tree objc_parmlist = NULL_TREE;
9782 /* Append PARM to a list of formal parameters of a method, making a necessary
9783 array-to-pointer adjustment along the way. */
9786 objc_push_parm (tree parm)
9790 if (TREE_TYPE (parm) == error_mark_node)
9792 objc_parmlist = chainon (objc_parmlist, parm);
9796 /* Decay arrays and functions into pointers. */
9797 type = objc_decay_parm_type (TREE_TYPE (parm));
9799 /* If the parameter type has been decayed, a new PARM_DECL needs to be
9801 if (type != TREE_TYPE (parm))
9802 parm = build_decl (input_location, PARM_DECL, DECL_NAME (parm), type);
9804 DECL_ARG_TYPE (parm)
9805 = lang_hooks.types.type_promotes_to (TREE_TYPE (parm));
9807 /* Record constancy and volatility. */
9808 c_apply_type_quals_to_decl
9809 ((TYPE_READONLY (TREE_TYPE (parm)) ? TYPE_QUAL_CONST : 0)
9810 | (TYPE_RESTRICT (TREE_TYPE (parm)) ? TYPE_QUAL_RESTRICT : 0)
9811 | (TYPE_VOLATILE (TREE_TYPE (parm)) ? TYPE_QUAL_VOLATILE : 0), parm);
9813 objc_parmlist = chainon (objc_parmlist, parm);
9816 /* Retrieve the formal parameter list constructed via preceding calls to
9817 objc_push_parm(). */
9821 objc_get_parm_info (int have_ellipsis ATTRIBUTE_UNUSED)
9823 static struct c_arg_info *
9824 objc_get_parm_info (int have_ellipsis)
9828 tree parm_info = objc_parmlist;
9829 objc_parmlist = NULL_TREE;
9833 tree parm_info = objc_parmlist;
9834 struct c_arg_info *arg_info;
9835 /* The C front-end requires an elaborate song and dance at
9838 declare_parm_level ();
9841 tree next = DECL_CHAIN (parm_info);
9843 DECL_CHAIN (parm_info) = NULL_TREE;
9844 parm_info = pushdecl (parm_info);
9845 finish_decl (parm_info, input_location, NULL_TREE, NULL_TREE, NULL_TREE);
9848 arg_info = get_parm_info (have_ellipsis);
9850 objc_parmlist = NULL_TREE;
9855 /* Synthesize the formal parameters 'id self' and 'SEL _cmd' needed for ObjC
9856 method definitions. In the case of instance methods, we can be more
9857 specific as to the type of 'self'. */
9860 synth_self_and_ucmd_args (void)
9864 if (objc_method_context
9865 && TREE_CODE (objc_method_context) == INSTANCE_METHOD_DECL)
9866 self_type = objc_instance_type;
9868 /* Really a `struct objc_class *'. However, we allow people to
9869 assign to self, which changes its type midstream. */
9870 self_type = objc_object_type;
9873 objc_push_parm (build_decl (input_location,
9874 PARM_DECL, self_id, self_type));
9877 objc_push_parm (build_decl (input_location,
9878 PARM_DECL, ucmd_id, objc_selector_type));
9881 /* Transform an Objective-C method definition into a static C function
9882 definition, synthesizing the first two arguments, "self" and "_cmd",
9886 start_method_def (tree method)
9892 struct c_arg_info *parm_info;
9894 int have_ellipsis = 0;
9896 /* If we are defining a "dealloc" method in a non-root class, we
9897 will need to check if a [super dealloc] is missing, and warn if
9899 if(CLASS_SUPER_NAME (objc_implementation_context)
9900 && !strcmp ("dealloc", IDENTIFIER_POINTER (METHOD_SEL_NAME (method))))
9901 should_call_super_dealloc = 1;
9903 should_call_super_dealloc = 0;
9905 /* Required to implement _msgSuper. */
9906 objc_method_context = method;
9907 UOBJC_SUPER_decl = NULL_TREE;
9909 /* Generate prototype declarations for arguments..."new-style". */
9910 synth_self_and_ucmd_args ();
9912 /* Generate argument declarations if a keyword_decl. */
9913 parmlist = METHOD_SEL_ARGS (method);
9916 tree type = TREE_VALUE (TREE_TYPE (parmlist)), parm;
9918 parm = build_decl (input_location,
9919 PARM_DECL, KEYWORD_ARG_NAME (parmlist), type);
9920 objc_push_parm (parm);
9921 parmlist = DECL_CHAIN (parmlist);
9924 if (METHOD_ADD_ARGS (method))
9928 for (akey = TREE_CHAIN (METHOD_ADD_ARGS (method));
9929 akey; akey = TREE_CHAIN (akey))
9931 objc_push_parm (TREE_VALUE (akey));
9934 if (METHOD_ADD_ARGS_ELLIPSIS_P (method))
9938 parm_info = objc_get_parm_info (have_ellipsis);
9940 really_start_method (objc_method_context, parm_info);
9943 /* Return 1 if TYPE1 is equivalent to TYPE2
9944 for purposes of method overloading. */
9947 objc_types_are_equivalent (tree type1, tree type2)
9952 /* Strip away indirections. */
9953 while ((TREE_CODE (type1) == ARRAY_TYPE || TREE_CODE (type1) == POINTER_TYPE)
9954 && (TREE_CODE (type1) == TREE_CODE (type2)))
9955 type1 = TREE_TYPE (type1), type2 = TREE_TYPE (type2);
9956 if (TYPE_MAIN_VARIANT (type1) != TYPE_MAIN_VARIANT (type2))
9959 type1 = (TYPE_HAS_OBJC_INFO (type1)
9960 ? TYPE_OBJC_PROTOCOL_LIST (type1)
9962 type2 = (TYPE_HAS_OBJC_INFO (type2)
9963 ? TYPE_OBJC_PROTOCOL_LIST (type2)
9966 if (list_length (type1) == list_length (type2))
9968 for (; type2; type2 = TREE_CHAIN (type2))
9969 if (!lookup_protocol_in_reflist (type1, TREE_VALUE (type2)))
9976 /* Return 1 if TYPE1 has the same size and alignment as TYPE2. */
9979 objc_types_share_size_and_alignment (tree type1, tree type2)
9981 return (simple_cst_equal (TYPE_SIZE (type1), TYPE_SIZE (type2))
9982 && TYPE_ALIGN (type1) == TYPE_ALIGN (type2));
9985 /* Return 1 if PROTO1 is equivalent to PROTO2
9986 for purposes of method overloading. Ordinarily, the type signatures
9987 should match up exactly, unless STRICT is zero, in which case we
9988 shall allow differences in which the size and alignment of a type
9992 comp_proto_with_proto (tree proto1, tree proto2, int strict)
9994 /* The following test is needed in case there are hashing
9996 if (METHOD_SEL_NAME (proto1) != METHOD_SEL_NAME (proto2))
9999 return match_proto_with_proto (proto1, proto2, strict);
10003 match_proto_with_proto (tree proto1, tree proto2, int strict)
10007 /* Compare return types. */
10008 type1 = TREE_VALUE (TREE_TYPE (proto1));
10009 type2 = TREE_VALUE (TREE_TYPE (proto2));
10011 if (!objc_types_are_equivalent (type1, type2)
10012 && (strict || !objc_types_share_size_and_alignment (type1, type2)))
10015 /* Compare argument types. */
10016 for (type1 = get_arg_type_list (proto1, METHOD_REF, 0),
10017 type2 = get_arg_type_list (proto2, METHOD_REF, 0);
10019 type1 = TREE_CHAIN (type1), type2 = TREE_CHAIN (type2))
10021 if (!objc_types_are_equivalent (TREE_VALUE (type1), TREE_VALUE (type2))
10023 || !objc_types_share_size_and_alignment (TREE_VALUE (type1),
10024 TREE_VALUE (type2))))
10028 return (!type1 && !type2);
10031 /* Fold an OBJ_TYPE_REF expression for ObjC method dispatches, where
10032 this occurs. ObjC method dispatches are _not_ like C++ virtual
10033 member function dispatches, and we account for the difference here. */
10036 objc_fold_obj_type_ref (tree ref, tree known_type)
10038 objc_fold_obj_type_ref (tree ref ATTRIBUTE_UNUSED,
10039 tree known_type ATTRIBUTE_UNUSED)
10043 tree v = BINFO_VIRTUALS (TYPE_BINFO (known_type));
10045 /* If the receiver does not have virtual member functions, there
10046 is nothing we can (or need to) do here. */
10050 /* Let C++ handle C++ virtual functions. */
10051 return cp_fold_obj_type_ref (ref, known_type);
10053 /* For plain ObjC, we currently do not need to do anything. */
10059 objc_start_function (tree name, tree type, tree attrs,
10063 struct c_arg_info *params
10067 tree fndecl = build_decl (input_location,
10068 FUNCTION_DECL, name, type);
10071 DECL_ARGUMENTS (fndecl) = params;
10072 DECL_INITIAL (fndecl) = error_mark_node;
10073 DECL_EXTERNAL (fndecl) = 0;
10074 TREE_STATIC (fndecl) = 1;
10075 retrofit_lang_decl (fndecl);
10076 cplus_decl_attributes (&fndecl, attrs, 0);
10077 start_preparsed_function (fndecl, attrs, /*flags=*/SF_DEFAULT);
10079 current_function_returns_value = 0; /* Assume, until we see it does. */
10080 current_function_returns_null = 0;
10082 decl_attributes (&fndecl, attrs, 0);
10083 announce_function (fndecl);
10084 DECL_INITIAL (fndecl) = error_mark_node;
10085 DECL_EXTERNAL (fndecl) = 0;
10086 TREE_STATIC (fndecl) = 1;
10087 current_function_decl = pushdecl (fndecl);
10089 declare_parm_level ();
10090 DECL_RESULT (current_function_decl)
10091 = build_decl (input_location,
10092 RESULT_DECL, NULL_TREE,
10093 TREE_TYPE (TREE_TYPE (current_function_decl)));
10094 DECL_ARTIFICIAL (DECL_RESULT (current_function_decl)) = 1;
10095 DECL_IGNORED_P (DECL_RESULT (current_function_decl)) = 1;
10096 start_fname_decls ();
10097 store_parm_decls_from (params);
10100 TREE_USED (current_function_decl) = 1;
10103 /* - Generate an identifier for the function. the format is "_n_cls",
10104 where 1 <= n <= nMethods, and cls is the name the implementation we
10106 - Install the return type from the method declaration.
10107 - If we have a prototype, check for type consistency. */
10110 really_start_method (tree method,
10114 struct c_arg_info *parmlist
10118 tree ret_type, meth_type;
10120 const char *sel_name, *class_name, *cat_name;
10123 /* Synth the storage class & assemble the return type. */
10124 ret_type = TREE_VALUE (TREE_TYPE (method));
10126 sel_name = IDENTIFIER_POINTER (METHOD_SEL_NAME (method));
10127 class_name = IDENTIFIER_POINTER (CLASS_NAME (objc_implementation_context));
10128 cat_name = ((TREE_CODE (objc_implementation_context)
10129 == CLASS_IMPLEMENTATION_TYPE)
10131 : IDENTIFIER_POINTER (CLASS_SUPER_NAME (objc_implementation_context)));
10134 /* Make sure this is big enough for any plausible method label. */
10135 buf = (char *) alloca (50 + strlen (sel_name) + strlen (class_name)
10136 + (cat_name ? strlen (cat_name) : 0));
10138 OBJC_GEN_METHOD_LABEL (buf, TREE_CODE (method) == INSTANCE_METHOD_DECL,
10139 class_name, cat_name, sel_name, method_slot);
10141 method_id = get_identifier (buf);
10144 /* Objective-C methods cannot be overloaded, so we don't need
10145 the type encoding appended. It looks bad anyway... */
10146 push_lang_context (lang_name_c);
10150 = build_function_type (ret_type,
10151 get_arg_type_list (method, METHOD_DEF, 0));
10152 objc_start_function (method_id, meth_type, NULL_TREE, parmlist);
10154 /* Set self_decl from the first argument. */
10155 self_decl = DECL_ARGUMENTS (current_function_decl);
10157 /* Suppress unused warnings. */
10158 TREE_USED (self_decl) = 1;
10159 DECL_READ_P (self_decl) = 1;
10160 TREE_USED (DECL_CHAIN (self_decl)) = 1;
10161 DECL_READ_P (DECL_CHAIN (self_decl)) = 1;
10163 pop_lang_context ();
10166 METHOD_DEFINITION (method) = current_function_decl;
10168 /* Check consistency...start_function, pushdecl, duplicate_decls. */
10170 if (implementation_template != objc_implementation_context)
10173 = lookup_method_static (implementation_template,
10174 METHOD_SEL_NAME (method),
10175 ((TREE_CODE (method) == CLASS_METHOD_DECL)
10176 | OBJC_LOOKUP_NO_SUPER));
10180 if (!comp_proto_with_proto (method, proto, 1))
10182 bool type = TREE_CODE (method) == INSTANCE_METHOD_DECL;
10184 warning_at (DECL_SOURCE_LOCATION (method), 0,
10185 "conflicting types for %<%c%s%>",
10186 (type ? '-' : '+'),
10187 identifier_to_locale (gen_method_decl (method)));
10188 inform (DECL_SOURCE_LOCATION (proto),
10189 "previous declaration of %<%c%s%>",
10190 (type ? '-' : '+'),
10191 identifier_to_locale (gen_method_decl (proto)));
10196 /* We have a method @implementation even though we did not
10197 see a corresponding @interface declaration (which is allowed
10198 by Objective-C rules). Go ahead and place the method in
10199 the @interface anyway, so that message dispatch lookups
10201 tree interface = implementation_template;
10203 if (TREE_CODE (objc_implementation_context)
10204 == CATEGORY_IMPLEMENTATION_TYPE)
10205 interface = lookup_category
10207 CLASS_SUPER_NAME (objc_implementation_context));
10210 objc_add_method (interface, copy_node (method),
10211 TREE_CODE (method) == CLASS_METHOD_DECL,
10212 /* is_optional= */ false);
10217 static void *UOBJC_SUPER_scope = 0;
10219 /* _n_Method (id self, SEL sel, ...)
10221 struct objc_super _S;
10222 _msgSuper ((_S.self = self, _S.class = _cls, &_S), ...);
10226 get_super_receiver (void)
10228 if (objc_method_context)
10230 tree super_expr, super_expr_list;
10232 if (!UOBJC_SUPER_decl)
10234 UOBJC_SUPER_decl = build_decl (input_location,
10235 VAR_DECL, get_identifier (TAG_SUPER),
10236 objc_super_template);
10237 /* This prevents `unused variable' warnings when compiling with -Wall. */
10238 TREE_USED (UOBJC_SUPER_decl) = 1;
10239 DECL_READ_P (UOBJC_SUPER_decl) = 1;
10240 lang_hooks.decls.pushdecl (UOBJC_SUPER_decl);
10241 finish_decl (UOBJC_SUPER_decl, input_location, NULL_TREE, NULL_TREE,
10243 UOBJC_SUPER_scope = objc_get_current_scope ();
10246 /* Set receiver to self. */
10247 super_expr = objc_build_component_ref (UOBJC_SUPER_decl, self_id);
10248 super_expr = build_modify_expr (input_location, super_expr, NULL_TREE,
10249 NOP_EXPR, input_location, self_decl,
10251 super_expr_list = super_expr;
10253 /* Set class to begin searching. */
10254 super_expr = objc_build_component_ref (UOBJC_SUPER_decl,
10255 get_identifier ("super_class"));
10257 if (TREE_CODE (objc_implementation_context) == CLASS_IMPLEMENTATION_TYPE)
10259 /* [_cls, __cls]Super are "pre-built" in
10260 synth_forward_declarations. */
10262 super_expr = build_modify_expr (input_location, super_expr,
10263 NULL_TREE, NOP_EXPR,
10265 ((TREE_CODE (objc_method_context)
10266 == INSTANCE_METHOD_DECL)
10268 : uucls_super_ref),
10273 /* We have a category. */
10275 tree super_name = CLASS_SUPER_NAME (implementation_template);
10278 /* Barf if super used in a category of Object. */
10281 error ("no super class declared in interface for %qE",
10282 CLASS_NAME (implementation_template));
10283 return error_mark_node;
10286 if (flag_next_runtime && !flag_zero_link)
10288 super_class = objc_get_class_reference (super_name);
10289 if (TREE_CODE (objc_method_context) == CLASS_METHOD_DECL)
10290 /* If we are in a class method, we must retrieve the
10291 _metaclass_ for the current class, pointed at by
10292 the class's "isa" pointer. The following assumes that
10293 "isa" is the first ivar in a class (which it must be). */
10295 = build_indirect_ref
10297 build_c_cast (input_location,
10298 build_pointer_type (objc_class_type),
10299 super_class), RO_UNARY_STAR);
10303 add_class_reference (super_name);
10304 super_class = (TREE_CODE (objc_method_context) == INSTANCE_METHOD_DECL
10305 ? objc_get_class_decl : objc_get_meta_class_decl);
10306 assemble_external (super_class);
10308 = build_function_call
10313 my_build_string_pointer
10314 (IDENTIFIER_LENGTH (super_name) + 1,
10315 IDENTIFIER_POINTER (super_name))));
10319 = build_modify_expr (input_location, super_expr, NULL_TREE,
10322 build_c_cast (input_location,
10323 TREE_TYPE (super_expr),
10328 super_expr_list = build_compound_expr (input_location,
10329 super_expr_list, super_expr);
10331 super_expr = build_unary_op (input_location,
10332 ADDR_EXPR, UOBJC_SUPER_decl, 0);
10333 super_expr_list = build_compound_expr (input_location,
10334 super_expr_list, super_expr);
10336 return super_expr_list;
10340 error ("[super ...] must appear in a method context");
10341 return error_mark_node;
10345 /* When exiting a scope, sever links to a 'super' declaration (if any)
10346 therein contained. */
10349 objc_clear_super_receiver (void)
10351 if (objc_method_context
10352 && UOBJC_SUPER_scope == objc_get_current_scope ()) {
10353 UOBJC_SUPER_decl = 0;
10354 UOBJC_SUPER_scope = 0;
10359 objc_finish_method_definition (tree fndecl)
10361 /* We cannot validly inline ObjC methods, at least not without a language
10362 extension to declare that a method need not be dynamically
10363 dispatched, so suppress all thoughts of doing so. */
10364 DECL_UNINLINABLE (fndecl) = 1;
10367 /* The C++ front-end will have called finish_function() for us. */
10368 finish_function ();
10371 METHOD_ENCODING (objc_method_context)
10372 = encode_method_prototype (objc_method_context);
10374 /* Required to implement _msgSuper. This must be done AFTER finish_function,
10375 since the optimizer may find "may be used before set" errors. */
10376 objc_method_context = NULL_TREE;
10378 if (should_call_super_dealloc)
10379 warning (0, "method possibly missing a [super dealloc] call");
10382 /* Given a tree DECL node, produce a printable description of it in the given
10383 buffer, overwriting the buffer. */
10386 gen_declaration (tree decl)
10392 gen_type_name_0 (TREE_TYPE (decl));
10394 if (DECL_NAME (decl))
10396 if (!POINTER_TYPE_P (TREE_TYPE (decl)))
10397 strcat (errbuf, " ");
10399 strcat (errbuf, IDENTIFIER_POINTER (DECL_NAME (decl)));
10402 if (DECL_INITIAL (decl)
10403 && TREE_CODE (DECL_INITIAL (decl)) == INTEGER_CST)
10404 sprintf (errbuf + strlen (errbuf), ": " HOST_WIDE_INT_PRINT_DEC,
10405 TREE_INT_CST_LOW (DECL_INITIAL (decl)));
10411 /* Given a tree TYPE node, produce a printable description of it in the given
10412 buffer, overwriting the buffer. */
10415 gen_type_name_0 (tree type)
10417 tree orig = type, proto;
10419 if (TYPE_P (type) && TYPE_NAME (type))
10420 type = TYPE_NAME (type);
10421 else if (POINTER_TYPE_P (type) || TREE_CODE (type) == ARRAY_TYPE)
10423 tree inner = TREE_TYPE (type);
10425 while (TREE_CODE (inner) == ARRAY_TYPE)
10426 inner = TREE_TYPE (inner);
10428 gen_type_name_0 (inner);
10430 if (!POINTER_TYPE_P (inner))
10431 strcat (errbuf, " ");
10433 if (POINTER_TYPE_P (type))
10434 strcat (errbuf, "*");
10436 while (type != inner)
10438 strcat (errbuf, "[");
10440 if (TYPE_DOMAIN (type))
10444 sprintf (sz, HOST_WIDE_INT_PRINT_DEC,
10446 (TYPE_MAX_VALUE (TYPE_DOMAIN (type))) + 1));
10447 strcat (errbuf, sz);
10450 strcat (errbuf, "]");
10451 type = TREE_TYPE (type);
10454 goto exit_function;
10457 if (TREE_CODE (type) == TYPE_DECL && DECL_NAME (type))
10458 type = DECL_NAME (type);
10460 strcat (errbuf, TREE_CODE (type) == IDENTIFIER_NODE
10461 ? IDENTIFIER_POINTER (type)
10464 /* For 'id' and 'Class', adopted protocols are stored in the pointee. */
10465 if (objc_is_id (orig))
10466 orig = TREE_TYPE (orig);
10468 proto = TYPE_HAS_OBJC_INFO (orig) ? TYPE_OBJC_PROTOCOL_LIST (orig) : NULL_TREE;
10472 strcat (errbuf, " <");
10476 IDENTIFIER_POINTER (PROTOCOL_NAME (TREE_VALUE (proto))));
10477 proto = TREE_CHAIN (proto);
10478 strcat (errbuf, proto ? ", " : ">");
10487 gen_type_name (tree type)
10491 return gen_type_name_0 (type);
10494 /* Given a method tree, put a printable description into the given
10495 buffer (overwriting) and return a pointer to the buffer. */
10498 gen_method_decl (tree method)
10502 strcpy (errbuf, "("); /* NB: Do _not_ call strcat() here. */
10503 gen_type_name_0 (TREE_VALUE (TREE_TYPE (method)));
10504 strcat (errbuf, ")");
10505 chain = METHOD_SEL_ARGS (method);
10509 /* We have a chain of keyword_decls. */
10512 if (KEYWORD_KEY_NAME (chain))
10513 strcat (errbuf, IDENTIFIER_POINTER (KEYWORD_KEY_NAME (chain)));
10515 strcat (errbuf, ":(");
10516 gen_type_name_0 (TREE_VALUE (TREE_TYPE (chain)));
10517 strcat (errbuf, ")");
10519 strcat (errbuf, IDENTIFIER_POINTER (KEYWORD_ARG_NAME (chain)));
10520 if ((chain = DECL_CHAIN (chain)))
10521 strcat (errbuf, " ");
10525 if (METHOD_ADD_ARGS (method))
10527 chain = TREE_CHAIN (METHOD_ADD_ARGS (method));
10529 /* Know we have a chain of parm_decls. */
10532 strcat (errbuf, ", ");
10533 gen_type_name_0 (TREE_TYPE (TREE_VALUE (chain)));
10534 chain = TREE_CHAIN (chain);
10537 if (METHOD_ADD_ARGS_ELLIPSIS_P (method))
10538 strcat (errbuf, ", ...");
10543 /* We have a unary selector. */
10544 strcat (errbuf, IDENTIFIER_POINTER (METHOD_SEL_NAME (method)));
10552 /* Dump an @interface declaration of the supplied class CHAIN to the
10553 supplied file FP. Used to implement the -gen-decls option (which
10554 prints out an @interface declaration of all classes compiled in
10555 this run); potentially useful for debugging the compiler too. */
10557 dump_interface (FILE *fp, tree chain)
10559 /* FIXME: A heap overflow here whenever a method (or ivar)
10560 declaration is so long that it doesn't fit in the buffer. The
10561 code and all the related functions should be rewritten to avoid
10562 using fixed size buffers. */
10563 const char *my_name = IDENTIFIER_POINTER (CLASS_NAME (chain));
10564 tree ivar_decls = CLASS_RAW_IVARS (chain);
10565 tree nst_methods = CLASS_NST_METHODS (chain);
10566 tree cls_methods = CLASS_CLS_METHODS (chain);
10568 fprintf (fp, "\n@interface %s", my_name);
10570 /* CLASS_SUPER_NAME is used to store the superclass name for
10571 classes, and the category name for categories. */
10572 if (CLASS_SUPER_NAME (chain))
10574 const char *name = IDENTIFIER_POINTER (CLASS_SUPER_NAME (chain));
10576 switch (TREE_CODE (chain))
10578 case CATEGORY_IMPLEMENTATION_TYPE:
10579 case CATEGORY_INTERFACE_TYPE:
10580 fprintf (fp, " (%s)\n", name);
10583 fprintf (fp, " : %s\n", name);
10588 fprintf (fp, "\n");
10590 /* FIXME - the following doesn't seem to work at the moment. */
10593 fprintf (fp, "{\n");
10596 fprintf (fp, "\t%s;\n", gen_declaration (ivar_decls));
10597 ivar_decls = TREE_CHAIN (ivar_decls);
10599 while (ivar_decls);
10600 fprintf (fp, "}\n");
10603 while (nst_methods)
10605 fprintf (fp, "- %s;\n", gen_method_decl (nst_methods));
10606 nst_methods = TREE_CHAIN (nst_methods);
10609 while (cls_methods)
10611 fprintf (fp, "+ %s;\n", gen_method_decl (cls_methods));
10612 cls_methods = TREE_CHAIN (cls_methods);
10615 fprintf (fp, "@end\n");
10618 /* Demangle function for Objective-C */
10619 static const char *
10620 objc_demangle (const char *mangled)
10622 char *demangled, *cp;
10624 if (mangled[0] == '_' &&
10625 (mangled[1] == 'i' || mangled[1] == 'c') &&
10628 cp = demangled = XNEWVEC (char, strlen(mangled) + 2);
10629 if (mangled[1] == 'i')
10630 *cp++ = '-'; /* for instance method */
10632 *cp++ = '+'; /* for class method */
10633 *cp++ = '['; /* opening left brace */
10634 strcpy(cp, mangled+3); /* tack on the rest of the mangled name */
10635 while (*cp && *cp == '_')
10636 cp++; /* skip any initial underbars in class name */
10637 cp = strchr(cp, '_'); /* find first non-initial underbar */
10640 free(demangled); /* not mangled name */
10643 if (cp[1] == '_') /* easy case: no category name */
10645 *cp++ = ' '; /* replace two '_' with one ' ' */
10646 strcpy(cp, mangled + (cp - demangled) + 2);
10650 *cp++ = '('; /* less easy case: category name */
10651 cp = strchr(cp, '_');
10654 free(demangled); /* not mangled name */
10658 *cp++ = ' '; /* overwriting 1st char of method name... */
10659 strcpy(cp, mangled + (cp - demangled)); /* get it back */
10661 while (*cp && *cp == '_')
10662 cp++; /* skip any initial underbars in method name */
10665 *cp = ':'; /* replace remaining '_' with ':' */
10666 *cp++ = ']'; /* closing right brace */
10667 *cp++ = 0; /* string terminator */
10671 return mangled; /* not an objc mangled name */
10675 objc_printable_name (tree decl, int kind ATTRIBUTE_UNUSED)
10677 return objc_demangle (IDENTIFIER_POINTER (DECL_NAME (decl)));
10683 gcc_obstack_init (&util_obstack);
10684 util_firstobj = (char *) obstack_finish (&util_obstack);
10686 errbuf = XNEWVEC (char, 1024 * 10);
10688 synth_module_prologue ();
10694 struct imp_entry *impent;
10696 /* The internally generated initializers appear to have missing braces.
10697 Don't warn about this. */
10698 int save_warn_missing_braces = warn_missing_braces;
10699 warn_missing_braces = 0;
10701 /* A missing @end may not be detected by the parser. */
10702 if (objc_implementation_context)
10704 warning (0, "%<@end%> missing in implementation context");
10705 finish_class (objc_implementation_context);
10706 objc_ivar_chain = NULL_TREE;
10707 objc_implementation_context = NULL_TREE;
10710 /* Process the static instances here because initialization of objc_symtab
10711 depends on them. */
10712 if (objc_static_instances)
10713 generate_static_references ();
10715 /* forward declare categories */
10717 forward_declare_categories ();
10719 for (impent = imp_list; impent; impent = impent->next)
10721 objc_implementation_context = impent->imp_context;
10722 implementation_template = impent->imp_template;
10724 /* FIXME: This needs reworking to be more obvious. */
10726 UOBJC_CLASS_decl = impent->class_decl;
10727 UOBJC_METACLASS_decl = impent->meta_decl;
10729 /* Dump the @interface of each class as we compile it, if the
10730 -gen-decls option is in use. TODO: Dump the classes in the
10731 order they were found, rather than in reverse order as we
10733 if (flag_gen_declaration)
10735 dump_interface (gen_declaration_file, objc_implementation_context);
10738 if (TREE_CODE (objc_implementation_context) == CLASS_IMPLEMENTATION_TYPE)
10740 /* all of the following reference the string pool... */
10741 generate_ivar_lists ();
10742 generate_dispatch_tables ();
10743 generate_shared_structures (impent);
10747 generate_dispatch_tables ();
10748 generate_category (impent);
10751 impent->class_decl = UOBJC_CLASS_decl;
10752 impent->meta_decl = UOBJC_METACLASS_decl;
10755 /* If we are using an array of selectors, we must always
10756 finish up the array decl even if no selectors were used. */
10757 if (flag_next_runtime)
10758 build_next_selector_translation_table ();
10760 build_gnu_selector_translation_table ();
10762 if (protocol_chain)
10763 generate_protocols ();
10765 if (flag_next_runtime)
10766 generate_objc_image_info ();
10768 if (imp_list || class_names_chain
10769 || meth_var_names_chain || meth_var_types_chain || sel_ref_chain)
10770 generate_objc_symtab_decl ();
10772 /* Arrange for ObjC data structures to be initialized at run time. */
10773 if (objc_implementation_context || class_names_chain || objc_static_instances
10774 || meth_var_names_chain || meth_var_types_chain || sel_ref_chain)
10776 build_module_descriptor ();
10778 if (!flag_next_runtime)
10779 build_module_initializer_routine ();
10782 /* Dump the class references. This forces the appropriate classes
10783 to be linked into the executable image, preserving unix archive
10784 semantics. This can be removed when we move to a more dynamically
10785 linked environment. */
10787 for (chain = cls_ref_chain; chain; chain = TREE_CHAIN (chain))
10789 handle_class_ref (chain);
10790 if (TREE_PURPOSE (chain))
10791 generate_classref_translation_entry (chain);
10794 for (impent = imp_list; impent; impent = impent->next)
10795 handle_impent (impent);
10802 /* Run through the selector hash tables and print a warning for any
10803 selector which has multiple methods. */
10805 for (slot = 0; slot < SIZEHASHTABLE; slot++)
10807 for (hsh = cls_method_hash_list[slot]; hsh; hsh = hsh->next)
10808 check_duplicates (hsh, 0, 1);
10809 for (hsh = nst_method_hash_list[slot]; hsh; hsh = hsh->next)
10810 check_duplicates (hsh, 0, 1);
10814 warn_missing_braces = save_warn_missing_braces;
10817 /* Subroutines of finish_objc. */
10820 generate_classref_translation_entry (tree chain)
10822 tree expr, decl, type;
10824 decl = TREE_PURPOSE (chain);
10825 type = TREE_TYPE (decl);
10827 expr = add_objc_string (TREE_VALUE (chain), class_names);
10828 expr = convert (type, expr); /* cast! */
10830 /* This is a class reference. It is re-written by the runtime,
10831 but will be optimized away unless we force it. */
10832 DECL_PRESERVE_P (decl) = 1;
10833 finish_var_decl (decl, expr);
10838 handle_class_ref (tree chain)
10840 const char *name = IDENTIFIER_POINTER (TREE_VALUE (chain));
10841 char *string = (char *) alloca (strlen (name) + 30);
10845 sprintf (string, "%sobjc_class_name_%s",
10846 (flag_next_runtime ? "." : "__"), name);
10848 #ifdef ASM_DECLARE_UNRESOLVED_REFERENCE
10849 if (flag_next_runtime)
10851 ASM_DECLARE_UNRESOLVED_REFERENCE (asm_out_file, string);
10856 /* Make a decl for this name, so we can use its address in a tree. */
10857 decl = build_decl (input_location,
10858 VAR_DECL, get_identifier (string), TREE_TYPE (integer_zero_node));
10859 DECL_EXTERNAL (decl) = 1;
10860 TREE_PUBLIC (decl) = 1;
10862 finish_var_decl (decl, 0);
10864 /* Make a decl for the address. */
10865 sprintf (string, "%sobjc_class_ref_%s",
10866 (flag_next_runtime ? "." : "__"), name);
10867 exp = build1 (ADDR_EXPR, string_type_node, decl);
10868 decl = build_decl (input_location,
10869 VAR_DECL, get_identifier (string), string_type_node);
10870 TREE_STATIC (decl) = 1;
10871 TREE_USED (decl) = 1;
10872 DECL_READ_P (decl) = 1;
10873 DECL_ARTIFICIAL (decl) = 1;
10874 DECL_INITIAL (decl) = error_mark_node;
10876 /* We must force the reference. */
10877 DECL_PRESERVE_P (decl) = 1;
10880 finish_var_decl (decl, exp);
10884 handle_impent (struct imp_entry *impent)
10888 objc_implementation_context = impent->imp_context;
10889 implementation_template = impent->imp_template;
10891 switch (TREE_CODE (impent->imp_context))
10893 case CLASS_IMPLEMENTATION_TYPE:
10895 const char *const class_name =
10896 IDENTIFIER_POINTER (CLASS_NAME (impent->imp_context));
10898 string = (char *) alloca (strlen (class_name) + 30);
10900 sprintf (string, "%sobjc_class_name_%s",
10901 (flag_next_runtime ? "." : "__"), class_name);
10904 case CATEGORY_IMPLEMENTATION_TYPE:
10906 const char *const class_name =
10907 IDENTIFIER_POINTER (CLASS_NAME (impent->imp_context));
10908 const char *const class_super_name =
10909 IDENTIFIER_POINTER (CLASS_SUPER_NAME (impent->imp_context));
10911 string = (char *) alloca (strlen (class_name)
10912 + strlen (class_super_name) + 30);
10914 /* Do the same for categories. Even though no references to
10915 these symbols are generated automatically by the compiler,
10916 it gives you a handle to pull them into an archive by
10918 sprintf (string, "*%sobjc_category_name_%s_%s",
10919 (flag_next_runtime ? "." : "__"), class_name, class_super_name);
10926 #ifdef ASM_DECLARE_CLASS_REFERENCE
10927 if (flag_next_runtime)
10929 ASM_DECLARE_CLASS_REFERENCE (asm_out_file, string);
10937 init = integer_zero_node;
10938 decl = build_decl (input_location,
10939 VAR_DECL, get_identifier (string), TREE_TYPE (init));
10940 TREE_PUBLIC (decl) = 1;
10941 TREE_READONLY (decl) = 1;
10942 TREE_USED (decl) = 1;
10943 TREE_CONSTANT (decl) = 1;
10944 DECL_CONTEXT (decl) = NULL_TREE;
10945 DECL_ARTIFICIAL (decl) = 1;
10946 TREE_STATIC (decl) = 1;
10947 DECL_INITIAL (decl) = error_mark_node; /* A real initializer is coming... */
10948 /* We must force the reference. */
10949 DECL_PRESERVE_P (decl) = 1;
10951 finish_var_decl(decl, init) ;
10955 /* The Fix-and-Continue functionality available in Mac OS X 10.3 and
10956 later requires that ObjC translation units participating in F&C be
10957 specially marked. The following routine accomplishes this. */
10959 /* static int _OBJC_IMAGE_INFO[2] = { 0, 1 }; */
10962 generate_objc_image_info (void)
10966 = ((flag_replace_objc_classes && imp_count ? 1 : 0)
10967 | (flag_objc_gc ? 2 : 0));
10968 VEC(constructor_elt,gc) *v = NULL;
10972 return; /* No need for an image_info entry. */
10974 array_type = build_sized_array_type (integer_type_node, 2);
10976 decl = start_var_decl (array_type, "_OBJC_IMAGE_INFO");
10978 CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, integer_zero_node);
10979 CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, build_int_cst (integer_type_node, flags));
10980 /* If we need this (determined above) it is because the runtime wants to
10981 refer to it in a manner hidden from the compiler. So we must force the
10983 DECL_PRESERVE_P (decl) = 1;
10984 finish_var_decl (decl, objc_build_constructor (TREE_TYPE (decl), v));
10987 /* Routine is called to issue diagnostic when reference to a private
10988 ivar is made and no other variable with same name is found in
10991 objc_diagnose_private_ivar (tree id)
10994 if (!objc_method_context)
10996 ivar = is_ivar (objc_ivar_chain, id);
10997 if (ivar && is_private (ivar))
10999 error ("instance variable %qs is declared private",
11000 IDENTIFIER_POINTER (id));
11006 /* Look up ID as an instance variable. OTHER contains the result of
11007 the C or C++ lookup, which we may want to use instead. */
11008 /* Also handle use of property as setter/getter. */
11010 objc_lookup_ivar (tree other, tree id)
11012 tree ivar, property;
11014 /* If we are not inside of an ObjC method, ivar lookup makes no sense. */
11015 if (!objc_method_context)
11018 if (!strcmp (IDENTIFIER_POINTER (id), "super"))
11019 /* We have a message to super. */
11020 return get_super_receiver ();
11022 /* In a class method, look up an instance variable only as a last
11024 if (TREE_CODE (objc_method_context) == CLASS_METHOD_DECL
11025 && other && other != error_mark_node)
11028 property = NULL_TREE;
11029 if (objc_implementation_context)
11030 property = is_property (objc_implementation_context, id);
11034 /* Look up the ivar, but do not use it if it is not accessible. */
11035 ivar = is_ivar (objc_ivar_chain, id);
11037 if (!ivar || is_private (ivar))
11041 /* In an instance method, a local variable (or parameter) may hide the
11042 instance variable. */
11043 if (TREE_CODE (objc_method_context) == INSTANCE_METHOD_DECL
11044 && other && other != error_mark_node
11046 && CP_DECL_CONTEXT (other) != global_namespace)
11048 && !DECL_FILE_SCOPE_P (other))
11052 warning (0, "local declaration of %qE hides property", id);
11054 warning (0, "local declaration of %qE hides instance variable", id);
11060 return build_property_reference (property, id);
11062 /* At this point, we are either in an instance method with no obscuring
11063 local definitions, or in a class method with no alternate definitions
11065 return build_ivar_reference (id);
11068 /* Possibly rewrite a function CALL into an OBJ_TYPE_REF expression. This
11069 needs to be done if we are calling a function through a cast. */
11072 objc_rewrite_function_call (tree function, tree first_param)
11074 if (TREE_CODE (function) == NOP_EXPR
11075 && TREE_CODE (TREE_OPERAND (function, 0)) == ADDR_EXPR
11076 && TREE_CODE (TREE_OPERAND (TREE_OPERAND (function, 0), 0))
11079 function = build3 (OBJ_TYPE_REF, TREE_TYPE (function),
11080 TREE_OPERAND (function, 0),
11081 first_param, size_zero_node);
11087 /* Look for the special case of OBJC_TYPE_REF with the address of
11088 a function in OBJ_TYPE_REF_EXPR (presumably objc_msgSend or one
11089 of its cousins). */
11092 objc_gimplify_expr (tree *expr_p, gimple_seq *pre_p, gimple_seq *post_p)
11094 enum gimplify_status r0, r1;
11095 if (TREE_CODE (*expr_p) == OBJ_TYPE_REF
11096 && TREE_CODE (OBJ_TYPE_REF_EXPR (*expr_p)) == ADDR_EXPR
11097 && TREE_CODE (TREE_OPERAND (OBJ_TYPE_REF_EXPR (*expr_p), 0))
11100 /* Postincrements in OBJ_TYPE_REF_OBJECT don't affect the
11101 value of the OBJ_TYPE_REF, so force them to be emitted
11102 during subexpression evaluation rather than after the
11103 OBJ_TYPE_REF. This permits objc_msgSend calls in Objective
11104 C to use direct rather than indirect calls when the
11105 object expression has a postincrement. */
11106 r0 = gimplify_expr (&OBJ_TYPE_REF_OBJECT (*expr_p), pre_p, NULL,
11107 is_gimple_val, fb_rvalue);
11108 r1 = gimplify_expr (&OBJ_TYPE_REF_EXPR (*expr_p), pre_p, post_p,
11109 is_gimple_val, fb_rvalue);
11111 return MIN (r0, r1);
11115 return (enum gimplify_status) cp_gimplify_expr (expr_p, pre_p, post_p);
11117 return (enum gimplify_status) c_gimplify_expr (expr_p, pre_p, post_p);
11121 /* This routine returns true if TYP is a valid objc object type,
11122 suitable for messaging; false otherwise.
11126 objc_type_valid_for_messaging (tree typ)
11128 if (!POINTER_TYPE_P (typ))
11132 typ = TREE_TYPE (typ); /* Remove indirections. */
11133 while (POINTER_TYPE_P (typ));
11135 if (TREE_CODE (typ) != RECORD_TYPE)
11138 return objc_is_object_id (typ) || TYPE_HAS_OBJC_INFO (typ);
11141 /* Begin code generation for fast enumeration (foreach) ... */
11145 struct __objcFastEnumerationState
11147 unsigned long state;
11149 unsigned long *mutationsPtr;
11150 unsigned long extra[5];
11153 Confusingly enough, NSFastEnumeration is then defined by libraries
11154 to be the same structure.
11158 build_fast_enumeration_state_template (void)
11160 tree decls, *chain = NULL;
11163 objc_fast_enumeration_state_template = objc_start_struct (get_identifier
11164 (TAG_FAST_ENUMERATION_STATE));
11166 /* unsigned long state; */
11167 decls = add_field_decl (long_unsigned_type_node, "state", &chain);
11169 /* id *itemsPtr; */
11170 add_field_decl (build_pointer_type (objc_object_type),
11171 "itemsPtr", &chain);
11173 /* unsigned long *mutationsPtr; */
11174 add_field_decl (build_pointer_type (long_unsigned_type_node),
11175 "mutationsPtr", &chain);
11177 /* unsigned long extra[5]; */
11178 add_field_decl (build_sized_array_type (long_unsigned_type_node, 5),
11182 objc_finish_struct (objc_fast_enumeration_state_template, decls);
11186 'objc_finish_foreach_loop()' generates the code for an Objective-C
11187 foreach loop. The 'location' argument is the location of the 'for'
11188 that starts the loop. The 'object_expression' is the expression of
11189 the 'object' that iterates; the 'collection_expression' is the
11190 expression of the collection that we iterate over (we need to make
11191 sure we evaluate this only once); the 'for_body' is the set of
11192 statements to be executed in each iteration; 'break_label' and
11193 'continue_label' are the break and continue labels which we need to
11194 emit since the <statements> may be jumping to 'break_label' (if they
11195 contain 'break') or to 'continue_label' (if they contain
11200 for (<object expression> in <collection expression>)
11203 which is compiled into the following blurb:
11206 id __objc_foreach_collection;
11207 __objc_fast_enumeration_state __objc_foreach_enum_state;
11208 unsigned long __objc_foreach_batchsize;
11209 id __objc_foreach_items[16];
11210 __objc_foreach_collection = <collection expression>;
11211 __objc_foreach_enum_state = { 0 };
11212 __objc_foreach_batchsize = [__objc_foreach_collection countByEnumeratingWithState: &__objc_foreach_enum_state objects: __objc_foreach_items count: 16];
11214 if (__objc_foreach_batchsize == 0)
11215 <object expression> = nil;
11218 unsigned long __objc_foreach_mutations_pointer = *__objc_foreach_enum_state.mutationsPtr;
11221 unsigned long __objc_foreach_index;
11222 __objc_foreach_index = 0;
11225 if (__objc_foreach_mutation_pointer != *__objc_foreach_enum_state.mutationsPtr) objc_enumeration_mutation (<collection expression>);
11226 <object expression> = enumState.itemsPtr[__objc_foreach_index];
11227 <statements> [PS: inside <statments>, 'break' jumps to break_label and 'continue' jumps to continue_label]
11230 __objc_foreach_index++;
11231 if (__objc_foreach_index < __objc_foreach_batchsize) goto next_object;
11232 __objc_foreach_batchsize = [__objc_foreach_collection countByEnumeratingWithState: &__objc_foreach_enum_state objects: __objc_foreach_items count: 16];
11234 if (__objc_foreach_batchsize != 0) goto next_batch;
11235 <object expression> = nil;
11240 'statements' may contain a 'continue' or 'break' instruction, which
11241 the user expects to 'continue' or 'break' the entire foreach loop.
11242 We are provided the labels that 'break' and 'continue' jump to, so
11243 we place them where we want them to jump to when they pick them.
11245 Optimization TODO: we could cache the IMP of
11246 countByEnumeratingWithState:objects:count:.
11249 /* If you need to debug objc_finish_foreach_loop(), uncomment the following line. */
11250 /* #define DEBUG_OBJC_FINISH_FOREACH_LOOP 1 */
11252 #ifdef DEBUG_OBJC_FINISH_FOREACH_LOOP
11253 #include "tree-pretty-print.h"
11257 objc_finish_foreach_loop (location_t location, tree object_expression, tree collection_expression, tree for_body,
11258 tree break_label, tree continue_label)
11260 /* A tree representing the __objcFastEnumerationState struct type,
11261 or NSFastEnumerationState struct, whatever we are using. */
11262 tree objc_fast_enumeration_state_type;
11264 /* The trees representing the declarations of each of the local variables. */
11265 tree objc_foreach_collection_decl;
11266 tree objc_foreach_enum_state_decl;
11267 tree objc_foreach_items_decl;
11268 tree objc_foreach_batchsize_decl;
11269 tree objc_foreach_mutations_pointer_decl;
11270 tree objc_foreach_index_decl;
11272 /* A tree representing the selector countByEnumeratingWithState:objects:count:. */
11273 tree selector_name;
11275 /* A tree representing the local bind. */
11278 /* A tree representing the external 'if (__objc_foreach_batchsize)' */
11281 /* A tree representing the 'else' part of 'first_if' */
11284 /* A tree representing the 'next_batch' label. */
11285 tree next_batch_label_decl;
11287 /* A tree representing the binding after the 'next_batch' label. */
11288 tree next_batch_bind;
11290 /* A tree representing the 'next_object' label. */
11291 tree next_object_label_decl;
11293 /* Temporary variables. */
11297 if (object_expression == error_mark_node)
11300 if (collection_expression == error_mark_node)
11303 if (!objc_type_valid_for_messaging (TREE_TYPE (object_expression)))
11305 error ("iterating variable in fast enumeration is not an object");
11309 if (!objc_type_valid_for_messaging (TREE_TYPE (collection_expression)))
11311 error ("collection in fast enumeration is not an object");
11315 /* TODO: Check that object_expression is either a variable
11316 declaration, or an lvalue. */
11318 /* This kludge is an idea from apple. We use the
11319 __objcFastEnumerationState struct implicitly defined by the
11320 compiler, unless a NSFastEnumerationState struct has been defined
11321 (by a Foundation library such as GNUstep Base) in which case, we
11324 objc_fast_enumeration_state_type = objc_fast_enumeration_state_template;
11326 tree objc_NSFastEnumeration_type = lookup_name (get_identifier ("NSFastEnumerationState"));
11328 if (objc_NSFastEnumeration_type)
11330 /* TODO: We really need to check that
11331 objc_NSFastEnumeration_type is the same as ours! */
11332 if (TREE_CODE (objc_NSFastEnumeration_type) == TYPE_DECL)
11334 /* If it's a typedef, use the original type. */
11335 if (DECL_ORIGINAL_TYPE (objc_NSFastEnumeration_type))
11336 objc_fast_enumeration_state_type = DECL_ORIGINAL_TYPE (objc_NSFastEnumeration_type);
11338 objc_fast_enumeration_state_type = TREE_TYPE (objc_NSFastEnumeration_type);
11344 /* Done by c-parser.c. */
11347 /* Done by c-parser.c. */
11349 /* id __objc_foreach_collection */
11350 objc_foreach_collection_decl = objc_create_temporary_var (objc_object_type, "__objc_foreach_collection");
11352 /* __objcFastEnumerationState __objc_foreach_enum_state; */
11353 objc_foreach_enum_state_decl = objc_create_temporary_var (objc_fast_enumeration_state_type, "__objc_foreach_enum_state");
11354 TREE_CHAIN (objc_foreach_enum_state_decl) = objc_foreach_collection_decl;
11356 /* id __objc_foreach_items[16]; */
11357 objc_foreach_items_decl = objc_create_temporary_var (build_sized_array_type (objc_object_type, 16), "__objc_foreach_items");
11358 TREE_CHAIN (objc_foreach_items_decl) = objc_foreach_enum_state_decl;
11360 /* unsigned long __objc_foreach_batchsize; */
11361 objc_foreach_batchsize_decl = objc_create_temporary_var (long_unsigned_type_node, "__objc_foreach_batchsize");
11362 TREE_CHAIN (objc_foreach_batchsize_decl) = objc_foreach_items_decl;
11364 /* Generate the local variable binding. */
11365 bind = build3 (BIND_EXPR, void_type_node, objc_foreach_batchsize_decl, NULL, NULL);
11366 SET_EXPR_LOCATION (bind, location);
11367 TREE_SIDE_EFFECTS (bind) = 1;
11369 /* __objc_foreach_collection = <collection expression>; */
11370 t = build2 (MODIFY_EXPR, void_type_node, objc_foreach_collection_decl, collection_expression);
11371 SET_EXPR_LOCATION (t, location);
11372 append_to_statement_list (t, &BIND_EXPR_BODY (bind));
11374 /* __objc_foreach_enum_state.state = 0; */
11375 t = build2 (MODIFY_EXPR, void_type_node, objc_build_component_ref (objc_foreach_enum_state_decl,
11376 get_identifier ("state")),
11377 build_int_cst (long_unsigned_type_node, 0));
11378 SET_EXPR_LOCATION (t, location);
11379 append_to_statement_list (t, &BIND_EXPR_BODY (bind));
11381 /* __objc_foreach_enum_state.itemsPtr = NULL; */
11382 t = build2 (MODIFY_EXPR, void_type_node, objc_build_component_ref (objc_foreach_enum_state_decl,
11383 get_identifier ("itemsPtr")),
11384 null_pointer_node);
11385 SET_EXPR_LOCATION (t, location);
11386 append_to_statement_list (t, &BIND_EXPR_BODY (bind));
11388 /* __objc_foreach_enum_state.mutationsPtr = NULL; */
11389 t = build2 (MODIFY_EXPR, void_type_node, objc_build_component_ref (objc_foreach_enum_state_decl,
11390 get_identifier ("mutationsPtr")),
11391 null_pointer_node);
11392 SET_EXPR_LOCATION (t, location);
11393 append_to_statement_list (t, &BIND_EXPR_BODY (bind));
11395 /* __objc_foreach_enum_state.extra[0] = 0; */
11396 /* __objc_foreach_enum_state.extra[1] = 0; */
11397 /* __objc_foreach_enum_state.extra[2] = 0; */
11398 /* __objc_foreach_enum_state.extra[3] = 0; */
11399 /* __objc_foreach_enum_state.extra[4] = 0; */
11400 for (i = 0; i < 5 ; i++)
11402 t = build2 (MODIFY_EXPR, void_type_node,
11403 build_array_ref (location, objc_build_component_ref (objc_foreach_enum_state_decl,
11404 get_identifier ("extra")),
11405 build_int_cst (NULL_TREE, i)),
11406 build_int_cst (long_unsigned_type_node, 0));
11407 SET_EXPR_LOCATION (t, location);
11408 append_to_statement_list (t, &BIND_EXPR_BODY (bind));
11411 /* __objc_foreach_batchsize = [__objc_foreach_collection countByEnumeratingWithState: &__objc_foreach_enum_state objects: __objc_foreach_items count: 16]; */
11412 selector_name = get_identifier ("countByEnumeratingWithState:objects:count:");
11414 t = objc_finish_message_expr (objc_foreach_collection_decl, selector_name,
11416 tree_cons /* &__objc_foreach_enum_state */
11417 (NULL_TREE, build_fold_addr_expr_loc (location, objc_foreach_enum_state_decl),
11418 tree_cons /* __objc_foreach_items */
11419 (NULL_TREE, objc_foreach_items_decl,
11421 (NULL_TREE, build_int_cst (NULL_TREE, 16), NULL_TREE))));
11423 /* In C, we need to decay the __objc_foreach_items array that we are passing. */
11425 struct c_expr array;
11426 array.value = objc_foreach_items_decl;
11427 t = objc_finish_message_expr (objc_foreach_collection_decl, selector_name,
11429 tree_cons /* &__objc_foreach_enum_state */
11430 (NULL_TREE, build_fold_addr_expr_loc (location, objc_foreach_enum_state_decl),
11431 tree_cons /* __objc_foreach_items */
11432 (NULL_TREE, default_function_array_conversion (location, array).value,
11434 (NULL_TREE, build_int_cst (NULL_TREE, 16), NULL_TREE))));
11437 t = build2 (MODIFY_EXPR, void_type_node, objc_foreach_batchsize_decl,
11438 convert (long_unsigned_type_node, t));
11439 SET_EXPR_LOCATION (t, location);
11440 append_to_statement_list (t, &BIND_EXPR_BODY (bind));
11442 /* if (__objc_foreach_batchsize == 0) */
11443 first_if = build3 (COND_EXPR, void_type_node,
11446 (c_common_truthvalue_conversion
11448 build_binary_op (location,
11450 objc_foreach_batchsize_decl,
11451 build_int_cst (long_unsigned_type_node, 0), 1)),
11453 /* Then block (we fill it in later). */
11455 /* Else block (we fill it in later). */
11457 SET_EXPR_LOCATION (first_if, location);
11458 append_to_statement_list (first_if, &BIND_EXPR_BODY (bind));
11460 /* then <object expression> = nil; */
11461 t = build2 (MODIFY_EXPR, void_type_node, object_expression, convert (objc_object_type, null_pointer_node));
11462 SET_EXPR_LOCATION (t, location);
11463 COND_EXPR_THEN (first_if) = t;
11465 /* Now we build the 'else' part of the if; once we finish building
11466 it, we attach it to first_if as the 'else' part. */
11471 /* unsigned long __objc_foreach_mutations_pointer; */
11472 objc_foreach_mutations_pointer_decl = objc_create_temporary_var (long_unsigned_type_node, "__objc_foreach_mutations_pointer");
11474 /* Generate the local variable binding. */
11475 first_else = build3 (BIND_EXPR, void_type_node, objc_foreach_mutations_pointer_decl, NULL, NULL);
11476 SET_EXPR_LOCATION (first_else, location);
11477 TREE_SIDE_EFFECTS (first_else) = 1;
11479 /* __objc_foreach_mutations_pointer = *__objc_foreach_enum_state.mutationsPtr; */
11480 t = build2 (MODIFY_EXPR, void_type_node, objc_foreach_mutations_pointer_decl,
11481 build_indirect_ref (location, objc_build_component_ref (objc_foreach_enum_state_decl,
11482 get_identifier ("mutationsPtr")),
11484 SET_EXPR_LOCATION (t, location);
11485 append_to_statement_list (t, &BIND_EXPR_BODY (first_else));
11488 next_batch_label_decl = create_artificial_label (location);
11489 t = build1 (LABEL_EXPR, void_type_node, next_batch_label_decl);
11490 SET_EXPR_LOCATION (t, location);
11491 append_to_statement_list (t, &BIND_EXPR_BODY (first_else));
11495 /* unsigned long __objc_foreach_index; */
11496 objc_foreach_index_decl = objc_create_temporary_var (long_unsigned_type_node, "__objc_foreach_index");
11498 /* Generate the local variable binding. */
11499 next_batch_bind = build3 (BIND_EXPR, void_type_node, objc_foreach_index_decl, NULL, NULL);
11500 SET_EXPR_LOCATION (next_batch_bind, location);
11501 TREE_SIDE_EFFECTS (next_batch_bind) = 1;
11502 append_to_statement_list (next_batch_bind, &BIND_EXPR_BODY (first_else));
11504 /* __objc_foreach_index = 0; */
11505 t = build2 (MODIFY_EXPR, void_type_node, objc_foreach_index_decl,
11506 build_int_cst (long_unsigned_type_node, 0));
11507 SET_EXPR_LOCATION (t, location);
11508 append_to_statement_list (t, &BIND_EXPR_BODY (next_batch_bind));
11511 next_object_label_decl = create_artificial_label (location);
11512 t = build1 (LABEL_EXPR, void_type_node, next_object_label_decl);
11513 SET_EXPR_LOCATION (t, location);
11514 append_to_statement_list (t, &BIND_EXPR_BODY (next_batch_bind));
11516 /* if (__objc_foreach_mutation_pointer != *__objc_foreach_enum_state.mutationsPtr) objc_enumeration_mutation (<collection expression>); */
11517 t = build3 (COND_EXPR, void_type_node,
11520 (c_common_truthvalue_conversion
11525 objc_foreach_mutations_pointer_decl,
11526 build_indirect_ref (location,
11527 objc_build_component_ref (objc_foreach_enum_state_decl,
11528 get_identifier ("mutationsPtr")),
11529 RO_UNARY_STAR), 1)),
11532 build_function_call (input_location,
11533 objc_enumeration_mutation_decl,
11534 tree_cons (NULL, collection_expression, NULL)),
11537 SET_EXPR_LOCATION (t, location);
11538 append_to_statement_list (t, &BIND_EXPR_BODY (next_batch_bind));
11540 /* <object expression> = enumState.itemsPtr[__objc_foreach_index]; */
11541 t = build2 (MODIFY_EXPR, void_type_node, object_expression,
11542 build_array_ref (location, objc_build_component_ref (objc_foreach_enum_state_decl,
11543 get_identifier ("itemsPtr")),
11544 objc_foreach_index_decl));
11545 SET_EXPR_LOCATION (t, location);
11546 append_to_statement_list (t, &BIND_EXPR_BODY (next_batch_bind));
11548 /* <statements> [PS: in <statments>, 'break' jumps to break_label and 'continue' jumps to continue_label] */
11549 append_to_statement_list (for_body, &BIND_EXPR_BODY (next_batch_bind));
11551 /* continue_label: */
11552 if (continue_label)
11554 t = build1 (LABEL_EXPR, void_type_node, continue_label);
11555 SET_EXPR_LOCATION (t, location);
11556 append_to_statement_list (t, &BIND_EXPR_BODY (next_batch_bind));
11559 /* __objc_foreach_index++; */
11560 t = build2 (MODIFY_EXPR, void_type_node, objc_foreach_index_decl,
11561 build_binary_op (location,
11563 objc_foreach_index_decl,
11564 build_int_cst (long_unsigned_type_node, 1), 1));
11565 SET_EXPR_LOCATION (t, location);
11566 append_to_statement_list (t, &BIND_EXPR_BODY (next_batch_bind));
11568 /* if (__objc_foreach_index < __objc_foreach_batchsize) goto next_object; */
11569 t = build3 (COND_EXPR, void_type_node,
11572 (c_common_truthvalue_conversion
11574 build_binary_op (location,
11576 objc_foreach_index_decl,
11577 objc_foreach_batchsize_decl, 1)),
11580 build1 (GOTO_EXPR, void_type_node, next_object_label_decl),
11583 SET_EXPR_LOCATION (t, location);
11584 append_to_statement_list (t, &BIND_EXPR_BODY (next_batch_bind));
11586 /* __objc_foreach_batchsize = [__objc_foreach_collection countByEnumeratingWithState: &__objc_foreach_enum_state objects: __objc_foreach_items count: 16]; */
11588 t = objc_finish_message_expr (objc_foreach_collection_decl, selector_name,
11590 tree_cons /* &__objc_foreach_enum_state */
11591 (NULL_TREE, build_fold_addr_expr_loc (location, objc_foreach_enum_state_decl),
11592 tree_cons /* __objc_foreach_items */
11593 (NULL_TREE, objc_foreach_items_decl,
11595 (NULL_TREE, build_int_cst (NULL_TREE, 16), NULL_TREE))));
11597 /* In C, we need to decay the __objc_foreach_items array that we are passing. */
11599 struct c_expr array;
11600 array.value = objc_foreach_items_decl;
11601 t = objc_finish_message_expr (objc_foreach_collection_decl, selector_name,
11603 tree_cons /* &__objc_foreach_enum_state */
11604 (NULL_TREE, build_fold_addr_expr_loc (location, objc_foreach_enum_state_decl),
11605 tree_cons /* __objc_foreach_items */
11606 (NULL_TREE, default_function_array_conversion (location, array).value,
11608 (NULL_TREE, build_int_cst (NULL_TREE, 16), NULL_TREE))));
11611 t = build2 (MODIFY_EXPR, void_type_node, objc_foreach_batchsize_decl,
11612 convert (long_unsigned_type_node, t));
11613 SET_EXPR_LOCATION (t, location);
11614 append_to_statement_list (t, &BIND_EXPR_BODY (next_batch_bind));
11618 /* if (__objc_foreach_batchsize != 0) goto next_batch; */
11619 t = build3 (COND_EXPR, void_type_node,
11622 (c_common_truthvalue_conversion
11624 build_binary_op (location,
11626 objc_foreach_batchsize_decl,
11627 build_int_cst (long_unsigned_type_node, 0), 1)),
11630 build1 (GOTO_EXPR, void_type_node, next_batch_label_decl),
11633 SET_EXPR_LOCATION (t, location);
11634 append_to_statement_list (t, &BIND_EXPR_BODY (first_else));
11636 /* <object expression> = nil; */
11637 t = build2 (MODIFY_EXPR, void_type_node, object_expression, convert (objc_object_type, null_pointer_node));
11638 SET_EXPR_LOCATION (t, location);
11639 append_to_statement_list (t, &BIND_EXPR_BODY (first_else));
11644 t = build1 (LABEL_EXPR, void_type_node, break_label);
11645 SET_EXPR_LOCATION (t, location);
11646 append_to_statement_list (t, &BIND_EXPR_BODY (first_else));
11650 COND_EXPR_ELSE (first_if) = first_else;
11652 /* Do the whole thing. */
11655 #ifdef DEBUG_OBJC_FINISH_FOREACH_LOOP
11656 /* This will print to stderr the whole blurb generated by the
11657 compiler while compiling (assuming the compiler doesn't crash
11658 before getting here).
11660 debug_generic_stmt (bind);
11664 /* Done by c-parser.c */
11667 #include "gt-objc-objc-act.h"